From dae6fc93f754d1221497352ff9ccb92b9aa0b281 Mon Sep 17 00:00:00 2001 From: zhangsz Date: Mon, 3 Mar 2025 11:01:26 +0800 Subject: [PATCH] ocs init --- mss/log/pps_trace.log | 33 + mss/log/snmp_log.txt | 36 + mss/log/wxc2_log.txt | 3 + mss/log/wxc2_startup.log | 249 + mss/log/wxc2exit.txt | 4 + mss/main/Makefile | 98 + mss/main/conf/.copyarea.db | 48 + mss/main/conf/.ussd.conf.swp | Bin 0 -> 12288 bytes mss/main/conf/AucSysPara | Bin 0 -> 3064 bytes mss/main/conf/EirSysPara | Bin 0 -> 17476 bytes mss/main/conf/EvrcFlt | Bin 0 -> 94301 bytes mss/main/conf/HlrSysPara | Bin 0 -> 7248 bytes mss/main/conf/MIB_files/IWV-SMI.txt | 40 + mss/main/conf/MIB_files/Special_App-SMI.txt | 43 + mss/main/conf/MIB_files/System_IP_List.txt | 26 + mss/main/conf/MIB_files/WXC2-AUC-MIB.txt | 437 + mss/main/conf/MIB_files/WXC2-HLR-MIB.txt | 2431 ++ mss/main/conf/MIB_files/WXC2-MSC-MIB.txt | 4084 +++ mss/main/conf/MIB_files/WXC2-MSS-MIB.txt | 54 + mss/main/conf/MIB_files/WXC2-PPS-MIB.txt | 13090 ++++++++ mss/main/conf/MIB_files/WXC2-SMI.txt | 57 + mss/main/conf/MIB_files/WXC2-SMSC-MIB.txt | 259 + mss/main/conf/MIB_files/WXC2-SS7-MIB.txt | 3729 +++ mss/main/conf/MIB_files/menu_page | 13 + mss/main/conf/MIB_files/menu_tree.txt | 908 + mss/main/conf/MIB_files/mib_list_file.txt | 14 + mss/main/conf/MIB_files/mib_write_tree.txt | 25779 +++++++++++++++ mss/main/conf/aas_codec_table.conf | 17 + mss/main/conf/aas_langVG_Conf | 1285 + mss/main/conf/aas_publicVG_Conf | 32 + mss/main/conf/alaw2intel | Bin 0 -> 34398 bytes mss/main/conf/cap_acn.conf | 8 + mss/main/conf/cap_acn.confV1 | 8 + mss/main/conf/cap_acn.confV2 | 8 + mss/main/conf/cap_acn.confV3 | 8 + mss/main/conf/cap_operation.conf | 34 + mss/main/conf/cc_table.conf | 215 + mss/main/conf/celp13k | Bin 0 -> 120466 bytes mss/main/conf/conv_prefix.conf | Bin 0 -> 26048 bytes mss/main/conf/debug.conf | 6 + mss/main/conf/evrc2pcm | Bin 0 -> 95409 bytes mss/main/conf/ews.conf | 2 + mss/main/conf/ewsAdmin.conf | 1 + mss/main/conf/ewsDetailLeftMenu.conf | 215 + mss/main/conf/ewsHtml/add.gif | Bin 0 -> 106 bytes mss/main/conf/ewsHtml/alarmList_header.html | 28 + mss/main/conf/ewsHtml/alarmNumList.html | 62 + mss/main/conf/ewsHtml/alvr_125.gif | Bin 0 -> 2152 bytes mss/main/conf/ewsHtml/alvr_150.gif | Bin 0 -> 2561 bytes mss/main/conf/ewsHtml/blank.gif | Bin 0 -> 66 bytes mss/main/conf/ewsHtml/default.html | 16 + mss/main/conf/ewsHtml/delete.gif | Bin 0 -> 82 bytes mss/main/conf/ewsHtml/detailTopMenu.html | 1 + mss/main/conf/ewsHtml/inDeveloping.html | 11 + mss/main/conf/ewsHtml/index.html | 20 + mss/main/conf/ewsHtml/lastblk.gif | Bin 0 -> 85 bytes mss/main/conf/ewsHtml/line.gif | Bin 0 -> 83 bytes mss/main/conf/ewsHtml/listDetailContent.html | 23 + mss/main/conf/ewsHtml/midblk.gif | Bin 0 -> 87 bytes mss/main/conf/ewsHtml/midminus.gif | Bin 0 -> 192 bytes mss/main/conf/ewsHtml/midplus.gif | Bin 0 -> 301 bytes .../ewsHtml/singleDetailContent_header.html | 25 + mss/main/conf/ewsHtml/status_header.html | 32 + mss/main/conf/ewsHtml/topMenu_header.html | 101 + mss/main/conf/ewsHtml/userConf_header.html | 93 + mss/main/conf/ewsHtml/userList_header.html | 38 + mss/main/conf/ewsIndex.conf | 17 + mss/main/conf/ewsLeftMenu.conf | 272 + mss/main/conf/ewsSysAlarmConf.conf | 1 + mss/main/conf/ewsSysConf.conf | 6 + mss/main/conf/fd_server.conf | 25 + mss/main/conf/help_page | 20 + mss/main/conf/hlr_parambit.conf | Bin 0 -> 20741 bytes mss/main/conf/iptrans.conf | 33 + mss/main/conf/is41_operation.conf | 60 + mss/main/conf/manager_engine.conf | Bin 0 -> 244 bytes mss/main/conf/map_acn.conf | 42 + mss/main/conf/map_acn_ver1.conf | 42 + mss/main/conf/map_acn_ver2.conf | 42 + mss/main/conf/map_acn_ver3.conf | 42 + mss/main/conf/map_operation.conf | 71 + mss/main/conf/mcms_conf.txt | 2 + mss/main/conf/menu_page | 17 + mss/main/conf/menu_page2 | 17 + mss/main/conf/mhc_adjacentNodes.txt | 3 + mss/main/conf/mhc_sysParma.conf | Bin 0 -> 2540 bytes mss/main/conf/mnpf.conf | Bin 0 -> 6344 bytes mss/main/conf/mrfc_mrfp.conf | 29 + mss/main/conf/msc_art.conf | 133 + mss/main/conf/msc_conf | Bin 0 -> 875156 bytes mss/main/conf/msc_conf.tgz | Bin 0 -> 15875 bytes mss/main/conf/msc_cua.conf | 390 + mss/main/conf/msc_dps.conf | 739 + mss/main/conf/msc_la.conf | 263 + mss/main/conf/msc_mg.conf | 353 + mss/main/conf/msc_rzs.conf | 202 + mss/main/conf/msc_system.conf | 13 + mss/main/conf/msc_tg.conf | 3546 +++ mss/main/conf/mtp3.conf | 52 + mss/main/conf/oprConf.txt | Bin 0 -> 6188 bytes mss/main/conf/palim_lac.config | 36 + mss/main/conf/palim_mg.config | 37 + mss/main/conf/palim_sys.config | 34 + mss/main/conf/palim_tg.config | 0 mss/main/conf/palim_user.config | 44 + mss/main/conf/ppsConf.txt | Bin 0 -> 430769 bytes mss/main/conf/ppsCrdConf.txt | Bin 0 -> 10290 bytes mss/main/conf/profile | 37 + mss/main/conf/rls_mg.conf | 1 + mss/main/conf/rls_rz.conf | 33 + mss/main/conf/rls_sys.conf | 2 + mss/main/conf/sccp.conf | 43 + mss/main/conf/shm.conf | 57 + mss/main/conf/smpp.conf | 35 + mss/main/conf/smsc_csta.conf | 21 + mss/main/conf/smsc_parambit.conf | Bin 0 -> 4456 bytes mss/main/conf/smsc_sys.conf | 5 + mss/main/conf/snmp.conf | 24 + mss/main/conf/srf.conf | Bin 0 -> 96324 bytes mss/main/conf/syntax_lang0 | 318 + mss/main/conf/syntax_lang1 | 344 + mss/main/conf/system.ini | Bin 0 -> 3724 bytes mss/main/conf/ussd.conf | 16 + mss/main/conf/vlr.conf | Bin 0 -> 140 bytes mss/main/conf/vlr_conf | Bin 0 -> 76 bytes mss/main/conf/vlr_err | 4 + mss/main/conf/vlr_index | 3 + mss/main/conf/wxc2_sys.conf | 3 + mss/main/conf/wxc2exit.txt | 4 + mss/main/conf/xap_mscid.conf | Bin 0 -> 3072 bytes mss/main/conf/xap_sysparam.conf | Bin 0 -> 20 bytes mss/main/makeclean | 32 + mss/main/makedebug | 32 + mss/main/makerelease_16cos | 34 + mss/main/makerelease_64cos_cook | 34 + mss/main/makerelease_rdb_tariff | 34 + mss/main/makerelease_zed_mobile | 34 + mss/main/myipcrm | 33 + mss/main/pkg.tgz | Bin 0 -> 70192 bytes mss/main/release_note | 37 + mss/main/src/include/wxc2ver.h | 33 + mss/main/src/wxc2main.c | 2299 ++ mss/main/wxc2d | 83 + mss/pps/Makefile | 31 + mss/pps/build_redis.txt | 16 + mss/pps/src/include/Makefile.am | 18 + mss/pps/src/include/Makefile.in | 236 + mss/pps/src/include/acconfig.h | 98 + mss/pps/src/include/callingCard.h | 81 + mss/pps/src/include/cdrme.h | 144 + mss/pps/src/include/config.h | 126 + mss/pps/src/include/crd.h | 34 + mss/pps/src/include/debug.h | 110 + mss/pps/src/include/errlog.h | 40 + mss/pps/src/include/function.h | 235 + mss/pps/src/include/gprs.h | 79 + mss/pps/src/include/includes.h | 43 + mss/pps/src/include/iofunc.h | 23 + mss/pps/src/include/logfunc.h | 37 + mss/pps/src/include/message.h | 192 + mss/pps/src/include/mfunc.h | 296 + mss/pps/src/include/param.h | 331 + mss/pps/src/include/plat_inc.h | 17 + mss/pps/src/include/ppsMibTable.h | 830 + mss/pps/src/include/pps_public.h | 8 + mss/pps/src/include/pps_redis.h | 8 + mss/pps/src/include/ppsinf.h | 31 + mss/pps/src/include/ppsm.h | 1093 + mss/pps/src/include/ppsoid.h | 59 + mss/pps/src/include/precard.h | 82 + mss/pps/src/include/public.h | 102 + mss/pps/src/include/ramdata.h | 555 + mss/pps/src/include/report.h | 153 + mss/pps/src/include/restapi.h | 829 + mss/pps/src/include/stamp-h | 1 + mss/pps/src/include/stamp-h.in | 1 + mss/pps/src/include/tariff.h | 54 + mss/pps/src/include/version.h | 21 + mss/pps/src/include/voiceID.h | 169 + mss/pps/src/lib/Makefile | 91 + mss/pps/src/lib/Makefile.am | 22 + mss/pps/src/lib/Makefile.in | 278 + mss/pps/src/lib/comfunc.c | 127 + mss/pps/src/lib/crypt.c | 473 + mss/pps/src/lib/daemon.c | 62 + mss/pps/src/lib/debug.c | 175 + mss/pps/src/lib/error.c | 113 + mss/pps/src/lib/errorlog.c | 128 + mss/pps/src/lib/function.c | 391 + mss/pps/src/lib/iofunc.c | 111 + mss/pps/src/lib/ipcfunc.c | 81 + mss/pps/src/lib/logfunc.c | 196 + mss/pps/src/lib/ppsfun.c | 372 + mss/pps/src/lib/ppsfunc.c | 372 + mss/pps/src/lib/queuefunc.c | 53 + mss/pps/src/lib/signal.c | 44 + mss/pps/src/lib/time.c | 377 + mss/pps/src/lib/version.c | 15 + mss/pps/src/log/dailyreport.bak | Bin 0 -> 476 bytes mss/pps/src/log/pps_trace.log | 33 + mss/pps/src/log/snmp_log.txt | 36 + mss/pps/src/main/.Makefile.swp | Bin 0 -> 16384 bytes mss/pps/src/main/Cook_Makefile | 160 + mss/pps/src/main/Makefile | 163 + mss/pps/src/main/Rdb_Makefile | 163 + mss/pps/src/main/Zed_Makefile | 163 + mss/pps/src/main/callMeBack.c | 508 + mss/pps/src/main/callingCardMsg.c | 849 + mss/pps/src/main/callingCardState.c | 1206 + mss/pps/src/main/calling_card.c | 8 + mss/pps/src/main/capmsg.c | 1389 + mss/pps/src/main/comfunc.c | 660 + mss/pps/src/main/conf/.svn/all-wcprops | 95 + mss/pps/src/main/conf/.svn/entries | 538 + .../conf/.svn/prop-base/cap_acn.conf.svn-base | 5 + .../prop-base/cap_operation.conf.svn-base | 5 + .../.svn/prop-base/conv_prefix.conf.svn-base | 9 + .../conf/.svn/prop-base/help_page.svn-base | 5 + .../conf/.svn/prop-base/iptrans.conf.svn-base | 5 + .../conf/.svn/prop-base/map_acn.conf.svn-base | 5 + .../prop-base/map_operation.conf.svn-base | 5 + .../conf/.svn/prop-base/menu_page.svn-base | 5 + .../conf/.svn/prop-base/mtp3.conf.svn-base | 5 + .../conf/.svn/prop-base/ppsConf.txt.svn-base | 9 + .../.svn/prop-base/ppsCrdConf.txt.svn-base | 9 + .../conf/.svn/prop-base/sccp.conf.svn-base | 5 + .../.svn/prop-base/sccp.conf_omt.svn-base | 5 + .../.svn/prop-base/wxc2_sys.conf.svn-base | 5 + .../.svn/prop-base/xap_sysparam.conf.svn-base | 9 + .../conf/.svn/text-base/cap_acn.conf.svn-base | 7 + .../text-base/cap_operation.conf.svn-base | 34 + .../.svn/text-base/conv_prefix.conf.svn-base | Bin 0 -> 6976 bytes .../conf/.svn/text-base/help_page.svn-base | 16 + .../conf/.svn/text-base/iptrans.conf.svn-base | 30 + .../conf/.svn/text-base/map_acn.conf.svn-base | 40 + .../text-base/map_operation.conf.svn-base | 66 + .../conf/.svn/text-base/menu_page.svn-base | 23 + .../conf/.svn/text-base/mtp3.conf.svn-base | 1408 + .../conf/.svn/text-base/ppsConf.txt.svn-base | Bin 0 -> 5040 bytes .../.svn/text-base/ppsCrdConf.txt.svn-base | Bin 0 -> 10289 bytes .../conf/.svn/text-base/sccp.conf.svn-base | 27 + .../.svn/text-base/sccp.conf_omt.svn-base | 87 + .../.svn/text-base/wxc2_sys.conf.svn-base | 5 + .../.svn/text-base/xap_sysparam.conf.svn-base | Bin 0 -> 16 bytes mss/pps/src/main/conf/cap_acn.conf | 7 + mss/pps/src/main/conf/cap_operation.conf | 34 + mss/pps/src/main/conf/conv_prefix.conf | Bin 0 -> 6976 bytes mss/pps/src/main/conf/help_page | 16 + mss/pps/src/main/conf/iptrans.conf | 30 + mss/pps/src/main/conf/map_acn.conf | 40 + mss/pps/src/main/conf/map_operation.conf | 66 + mss/pps/src/main/conf/menu_page | 23 + mss/pps/src/main/conf/mtp3.conf | 1408 + mss/pps/src/main/conf/ppsConf.txt | Bin 0 -> 5041 bytes mss/pps/src/main/conf/ppsCrdConf.txt | Bin 0 -> 10289 bytes mss/pps/src/main/conf/sccp.conf | 27 + mss/pps/src/main/conf/sccp.conf_omt | 87 + mss/pps/src/main/conf/wxc2_sys.conf | 5 + mss/pps/src/main/conf/xap_sysparam.conf | Bin 0 -> 16 bytes mss/pps/src/main/crd.c | 216 + mss/pps/src/main/dailyreport.c | 1822 ++ mss/pps/src/main/feeTransfer.c | 2350 ++ mss/pps/src/main/freeSMS.c | 507 + mss/pps/src/main/gprs.c | 2244 ++ mss/pps/src/main/loadtl.c | 1147 + mss/pps/src/main/masterSlaveCard.c | 3055 ++ mss/pps/src/main/message.c | 4686 +++ mss/pps/src/main/mfunc.c | 6430 ++++ mss/pps/src/main/myipcrm | 33 + mss/pps/src/main/ocs_user_table.c | 189 + mss/pps/src/main/ppsMibTable.c | 6417 ++++ mss/pps/src/main/pps_redis.c | 1867 ++ mss/pps/src/main/ppsfunc.c | 223 + mss/pps/src/main/ppsm.c | 12964 ++++++++ mss/pps/src/main/ppsmain.c | 271 + mss/pps/src/main/ppsmap.c | 412 + mss/pps/src/main/ppsmib.c | 8211 +++++ mss/pps/src/main/ppsopr.c | 1360 + mss/pps/src/main/ppsussd.c | 7861 +++++ mss/pps/src/main/precard.c | 2184 ++ mss/pps/src/main/radius.c | 735 + mss/pps/src/main/rammng.c | 1872 ++ mss/pps/src/main/restapi.c | 2860 ++ mss/pps/src/main/smppapi.c | 2199 ++ mss/pps/src/main/tariffApplication.c | 624 + mss/pps/src/main/vas.c | 1080 + mss/pps/src/object/makefile | 9 + plat/debug/Makefile | 98 + plat/debug/src/debug.c | 15652 ++++++++++ plat/debug/src/include/debug.h | 60 + plat/debug/src/include/debug_struct.h | 374 + plat/debug/ut/debug_test.c | 926 + plat/diameter/daemon/daemon.c | 10 + plat/diameter/doc/acl_wl.conf.sample | 19 + plat/diameter/doc/app_acct.conf.sample | 82 + plat/diameter/doc/app_diameap.conf.sample | 44 + plat/diameter/doc/app_radgw.conf.sample | 105 + plat/diameter/doc/app_redirect.conf.sample | 97 + plat/diameter/doc/app_sip.conf.sample | 28 + plat/diameter/doc/app_sip.sql | 117 + plat/diameter/doc/app_sip_SL.sql | 21 + plat/diameter/doc/dbg_interactive.py.sample | 783 + plat/diameter/doc/dict_legacy_xml.conf.sample | 15 + .../doc/eap_tls_plugin.diameap.conf.sample | 13 + plat/diameter/doc/echodrop.rgwx.conf.sample | 33 + plat/diameter/doc/freediameter.conf.sample | 252 + plat/diameter/doc/rt_busypeers.conf.sample | 47 + plat/diameter/doc/rt_default.conf.sample | 91 + plat/diameter/doc/rt_ereg.conf.sample | 21 + .../doc/single_host/CAGenerate/ca.chain.crt | 87 + .../doc/single_host/CAGenerate/ca.crl | Bin 0 -> 404 bytes .../doc/single_host/CAGenerate/ca.crt | 87 + .../doc/single_host/CAGenerate/ca.csr | 16 + .../diameter/doc/single_host/CAGenerate/ca.db | 2 + .../doc/single_host/CAGenerate/ca.db.attr | 1 + .../doc/single_host/CAGenerate/ca.db.attr.old | 1 + .../doc/single_host/CAGenerate/ca.db.old | 1 + .../doc/single_host/CAGenerate/ca.srl | 1 + .../doc/single_host/CAGenerate/ca.srl.old | 1 + .../doc/single_host/CAGenerate/fdTestExt | Bin 0 -> 1984180 bytes .../CAGenerate/freeDiameter-1.conf | 16 + .../doc/single_host/CAGenerate/localhost.crt | 152 + .../doc/single_host/CAGenerate/localhost.csr | 17 + .../doc/single_host/CAGenerate/ocsp.crt | 159 + .../doc/single_host/CAGenerate/ocsp.csr | 17 + .../single_host/CAGenerate/ssl_make_certs.sh | 545 + .../doc/single_host/demoCA/index.txt.attr | 1 + .../doc/single_host/demoCA/index.txt.attr.old | 1 + .../doc/single_host/demoCA/index.txt.old | 1 + plat/diameter/doc/single_host/demoCA/serial | 1 + .../doc/single_host/demoCA/serial.old | 1 + plat/diameter/doc/single_host/fdTestExt | Bin 0 -> 1984180 bytes .../doc/single_host/freeDiameter-1.conf | 16 + .../doc/single_host/freeDiameter-2.conf | 15 + plat/diameter/doc/single_host/make_certs.sh | 20 + plat/diameter/doc/single_host/test_app1.conf | 0 plat/diameter/doc/single_host/test_app2.conf | 0 plat/diameter/doc/test_app.conf.sample | 74 + plat/diameter/doc/test_netemul.conf.sample | 59 + plat/diameter/doc/test_sip.conf.sample | 8 + plat/diameter/extensions/sh_app/dict_dcca.c | 1559 + .../extensions/sh_app/dict_dcca_3gpp.c | 859 + plat/diameter/extensions/sh_app/gx_app.c | 3789 +++ plat/diameter/extensions/sh_app/sh_app.c | 965 + plat/diameter/extensions/sh_app/sh_app.h | 538 + plat/diameter/extensions/sh_app/sh_bench.c | 344 + plat/diameter/extensions/sh_app/sh_cli.c | 997 + plat/diameter/extensions/sh_app/sh_conf.c | 371 + plat/diameter/extensions/sh_app/sh_conf.h | 48 + plat/diameter/extensions/sh_app/sh_dict.c | 4723 +++ plat/diameter/extensions/sh_app/sh_serv.c | 753 + plat/diameter/extensions/sh_app/ta_conf.l | 177 + plat/diameter/extensions/sh_app/ta_conf.y | 239 + plat/diameter/freeDiameter-1.conf | 26 + plat/diameter/freeDiameter-2.conf | 25 + .../freeDiameterd/freeDiameter-host.h | 108 + plat/diameter/freeDiameterd/main.c | 312 + .../diameter/include/freeDiameter/extension.h | 72 + .../freeDiameter/freeDiameter-host.h.in | 106 + .../diameter/include/freeDiameter/libfdcore.h | 1216 + .../include/freeDiameter/libfdproto.h | 3254 ++ .../include/freeDiameter/version.h.in | 3 + plat/diameter/include/gy_message.h | 159 + plat/diameter/libfdcore/apps.c | 152 + plat/diameter/libfdcore/cnxctx.c | 2045 ++ plat/diameter/libfdcore/cnxctx.h | 153 + plat/diameter/libfdcore/config.c | 643 + plat/diameter/libfdcore/core.c | 403 + plat/diameter/libfdcore/dict_base_proto.c | 3355 ++ plat/diameter/libfdcore/endpoints.c | 271 + plat/diameter/libfdcore/events.c | 231 + plat/diameter/libfdcore/extensions.c | 293 + plat/diameter/libfdcore/fdcore-internal.h | 375 + plat/diameter/libfdcore/fdd.l | 285 + plat/diameter/libfdcore/fdd.y | 667 + plat/diameter/libfdcore/fifo_stats.c | 79 + plat/diameter/libfdcore/freeDiameter-host.h | 106 + plat/diameter/libfdcore/hooks.c | 454 + plat/diameter/libfdcore/messages.c | 452 + plat/diameter/libfdcore/p_ce.c | 1112 + plat/diameter/libfdcore/p_cnx.c | 357 + plat/diameter/libfdcore/p_dp.c | 207 + plat/diameter/libfdcore/p_dw.c | 177 + plat/diameter/libfdcore/p_expiry.c | 205 + plat/diameter/libfdcore/p_out.c | 237 + plat/diameter/libfdcore/p_psm.c | 958 + plat/diameter/libfdcore/p_sr.c | 350 + plat/diameter/libfdcore/peers.c | 700 + plat/diameter/libfdcore/queues.c | 86 + plat/diameter/libfdcore/routing_dispatch.c | 1337 + plat/diameter/libfdcore/sctp.c | 1355 + plat/diameter/libfdcore/sctp3436.c | 793 + plat/diameter/libfdcore/server.c | 509 + plat/diameter/libfdcore/tcp.c | 168 + plat/diameter/libfdcore/version.c | 47 + plat/diameter/libfdcore/version.h | 3 + plat/diameter/libfdproto/dictionary.c | 2347 ++ .../libfdproto/dictionary_functions.c | 405 + plat/diameter/libfdproto/dispatch.c | 228 + plat/diameter/libfdproto/fdproto-internal.h | 65 + plat/diameter/libfdproto/fifo.c | 700 + plat/diameter/libfdproto/init.c | 71 + plat/diameter/libfdproto/lists.c | 169 + plat/diameter/libfdproto/log.c | 325 + plat/diameter/libfdproto/messages.c | 2869 ++ plat/diameter/libfdproto/ostr.c | 563 + plat/diameter/libfdproto/portability.c | 70 + plat/diameter/libfdproto/rt_data.c | 338 + plat/diameter/libfdproto/sessions.c | 940 + plat/diameter/libfdproto/utils.c | 84 + plat/diameter/libfdproto/version.c | 47 + plat/diameter/makefile | 29 + plat/diameter/makefile.new | 26 + plat/iptrans/Makefile | 98 + plat/iptrans/src/comfunc.c | 81 + plat/iptrans/src/daemon.c | 65 + plat/iptrans/src/error.c | 114 + plat/iptrans/src/errorlog.c | 131 + plat/iptrans/src/include/config.h | 23 + plat/iptrans/src/include/dbsync.h | 37 + plat/iptrans/src/include/debug.h | 53 + plat/iptrans/src/include/errlog.h | 39 + plat/iptrans/src/include/function.h | 127 + plat/iptrans/src/include/includes.h | 47 + plat/iptrans/src/include/iptrans.h | 206 + plat/iptrans/src/include/iptrfunc.h | 9 + plat/iptrans/src/ipcfunc.c | 87 + plat/iptrans/src/ipmsgfun.c | 52 + plat/iptrans/src/iptrans.c | 1913 ++ plat/iptrans/src/iptrans.c.bak | 1913 ++ plat/iptrans/src/iptrmain.c | 101 + plat/iptrans/src/mcast_join.c | 59 + plat/iptrans/src/queuefunc.c | 133 + plat/iptrans/src/readmsg.c | 190 + plat/iptrans/src/signal.c | 33 + plat/iptrans/src/simu_debug.c | 28 + plat/m2ua/Makefile | 98 + plat/m2ua/src/include/m2ua.h | 151 + plat/m2ua/src/include/m2ua_const.h | 383 + plat/m2ua/src/include/m2ua_debug.h | 10 + plat/m2ua/src/include/m2ua_def.h | 69 + plat/m2ua/src/include/m2ua_ext.h | 67 + plat/m2ua/src/include/m2ua_fsm.h | 9 + plat/m2ua/src/include/m2ua_msg.h | 59 + plat/m2ua/src/include/m2ua_pub.h | 63 + plat/m2ua/src/include/m2ua_pub.h.bak | 63 + plat/m2ua/src/include/m2ua_struct.h | 260 + plat/m2ua/src/include/sctp.h | 655 + plat/m2ua/src/m2ua.c | 486 + plat/m2ua/src/m2ua_debug.c | 537 + plat/m2ua/src/m2ua_fsm.c | 1631 + plat/m2ua/src/m2ua_msg.c | 4008 +++ plat/m2ua/ut/testcate/MGC(IUA)_Client.txt | 32 + plat/m2ua/ut/testcate/MGC(IUA)_Server.txt | 52 + plat/m2ua/ut/testcate/MGC(M2UA)_Client.txt | 33 + plat/m2ua/ut/testcate/MGC(M2UA)_Server.txt | 61 + plat/m2ua/ut/testcate/SG(IUA)_Client.txt | 80 + plat/m2ua/ut/testcate/SG(IUA)_Server.txt | 16 + plat/m2ua/ut/testcate/SG(M2UA)_Client.txt | 79 + plat/m2ua/ut/testcate/SG(M2UA)_Server.txt | 15 + plat/m2ua/ut/testcate/headfile.txt | 6 + plat/m2ua/ut/xua_test/Makefile | 21 + plat/m2ua/ut/xua_test/conf/.svn/all-wcprops | 185 + plat/m2ua/ut/xua_test/conf/.svn/entries | 1048 + .../conf/.svn/prop-base/AucSysPara.svn-base | 9 + .../conf/.svn/prop-base/EirSysPara.svn-base | 9 + .../conf/.svn/prop-base/HlrSysPara.svn-base | 9 + .../conf/.svn/prop-base/cap_acn.conf.svn-base | 5 + .../prop-base/cap_operation.conf.svn-base | 5 + .../.svn/prop-base/cc_table.conf.svn-base | 5 + .../.svn/prop-base/conv_prefix.conf.svn-base | 9 + .../conf/.svn/prop-base/help_page.svn-base | 5 + .../.svn/prop-base/hlr_parambit.conf.svn-base | 9 + .../conf/.svn/prop-base/iptrans.conf.svn-base | 5 + .../conf/.svn/prop-base/map_acn.conf.svn-base | 5 + .../prop-base/map_operation.conf.svn-base | 5 + .../conf/.svn/prop-base/menu_page.svn-base | 5 + .../conf/.svn/prop-base/mnpf.conf.svn-base | 9 + .../conf/.svn/prop-base/msc_conf.svn-base | 9 + .../conf/.svn/prop-base/mtp3.conf.svn-base | 5 + .../conf/.svn/prop-base/ppsConf.txt.svn-base | 9 + .../.svn/prop-base/ppsCrdConf.txt.svn-base | 9 + .../conf/.svn/prop-base/profile.svn-base | 5 + .../conf/.svn/prop-base/sccp.conf.svn-base | 5 + .../.svn/prop-base/sccp_omt.conf.svn-base | 5 + .../.svn/prop-base/sccp_sts.conf.svn-base | 5 + .../.svn/prop-base/smsc_csta.conf.svn-base | 5 + .../prop-base/smsc_parambit.conf.svn-base | 9 + .../.svn/prop-base/smsc_sys.conf.svn-base | 5 + .../conf/.svn/prop-base/system.ini.svn-base | 9 + .../conf/.svn/prop-base/vlr.conf.svn-base | 9 + .../.svn/prop-base/wxc2_sys.conf.svn-base | 5 + .../conf/.svn/prop-base/wxc2exit.txt.svn-base | 5 + .../.svn/prop-base/xap_sysparam.conf.svn-base | 9 + .../conf/.svn/text-base/AucSysPara.svn-base | Bin 0 -> 56 bytes .../conf/.svn/text-base/EirSysPara.svn-base | Bin 0 -> 17476 bytes .../conf/.svn/text-base/HlrSysPara.svn-base | Bin 0 -> 7244 bytes .../conf/.svn/text-base/cap_acn.conf.svn-base | 7 + .../text-base/cap_operation.conf.svn-base | 34 + .../.svn/text-base/cc_table.conf.svn-base | 215 + .../.svn/text-base/conv_prefix.conf.svn-base | Bin 0 -> 4096 bytes .../conf/.svn/text-base/help_page.svn-base | 20 + .../.svn/text-base/hlr_parambit.conf.svn-base | Bin 0 -> 20740 bytes .../conf/.svn/text-base/iptrans.conf.svn-base | 16 + .../conf/.svn/text-base/map_acn.conf.svn-base | 40 + .../text-base/map_operation.conf.svn-base | 67 + .../conf/.svn/text-base/menu_page.svn-base | 13 + .../conf/.svn/text-base/mnpf.conf.svn-base | Bin 0 -> 718 bytes .../conf/.svn/text-base/msc_conf.svn-base | Bin 0 -> 220944 bytes .../conf/.svn/text-base/mtp3.conf.svn-base | 1408 + .../conf/.svn/text-base/ppsConf.txt.svn-base | Bin 0 -> 4524 bytes .../.svn/text-base/ppsCrdConf.txt.svn-base | Bin 0 -> 10289 bytes .../conf/.svn/text-base/profile.svn-base | 37 + .../conf/.svn/text-base/sccp.conf.svn-base | 85 + .../.svn/text-base/sccp_omt.conf.svn-base | 87 + .../.svn/text-base/sccp_sts.conf.svn-base | 74 + .../.svn/text-base/smsc_csta.conf.svn-base | 21 + .../text-base/smsc_parambit.conf.svn-base | Bin 0 -> 5812 bytes .../.svn/text-base/smsc_sys.conf.svn-base | 5 + .../conf/.svn/text-base/system.ini.svn-base | Bin 0 -> 212 bytes .../conf/.svn/text-base/vlr.conf.svn-base | Bin 0 -> 128 bytes .../.svn/text-base/wxc2_sys.conf.svn-base | 3 + .../conf/.svn/text-base/wxc2exit.txt.svn-base | 4 + .../.svn/text-base/xap_sysparam.conf.svn-base | Bin 0 -> 13 bytes plat/m2ua/ut/xua_test/conf/AucSysPara | Bin 0 -> 56 bytes plat/m2ua/ut/xua_test/conf/EirSysPara | Bin 0 -> 17476 bytes plat/m2ua/ut/xua_test/conf/HlrSysPara | Bin 0 -> 7244 bytes plat/m2ua/ut/xua_test/conf/cap_acn.conf | 7 + plat/m2ua/ut/xua_test/conf/cap_operation.conf | 34 + plat/m2ua/ut/xua_test/conf/cc_table.conf | 215 + plat/m2ua/ut/xua_test/conf/conv_prefix.conf | Bin 0 -> 4096 bytes plat/m2ua/ut/xua_test/conf/help_page | 20 + plat/m2ua/ut/xua_test/conf/hlr_parambit.conf | Bin 0 -> 20740 bytes plat/m2ua/ut/xua_test/conf/iptrans.conf | 16 + plat/m2ua/ut/xua_test/conf/map_acn.conf | 40 + plat/m2ua/ut/xua_test/conf/map_operation.conf | 67 + plat/m2ua/ut/xua_test/conf/menu_page | 13 + plat/m2ua/ut/xua_test/conf/mnpf.conf | Bin 0 -> 718 bytes plat/m2ua/ut/xua_test/conf/msc_conf | Bin 0 -> 220944 bytes plat/m2ua/ut/xua_test/conf/mtp3.conf | 1408 + plat/m2ua/ut/xua_test/conf/ppsConf.txt | Bin 0 -> 4524 bytes plat/m2ua/ut/xua_test/conf/ppsCrdConf.txt | Bin 0 -> 10289 bytes plat/m2ua/ut/xua_test/conf/profile | 37 + plat/m2ua/ut/xua_test/conf/sccp.conf | 85 + plat/m2ua/ut/xua_test/conf/sccp_omt.conf | 87 + plat/m2ua/ut/xua_test/conf/sccp_sts.conf | 74 + plat/m2ua/ut/xua_test/conf/smsc_csta.conf | 21 + plat/m2ua/ut/xua_test/conf/smsc_parambit.conf | Bin 0 -> 5812 bytes plat/m2ua/ut/xua_test/conf/smsc_sys.conf | 5 + plat/m2ua/ut/xua_test/conf/system.ini | Bin 0 -> 212 bytes plat/m2ua/ut/xua_test/conf/vlr.conf | Bin 0 -> 128 bytes plat/m2ua/ut/xua_test/conf/wxc2_sys.conf | 3 + plat/m2ua/ut/xua_test/conf/wxc2exit.txt | 4 + plat/m2ua/ut/xua_test/conf/xap_sysparam.conf | Bin 0 -> 13 bytes plat/m2ua/ut/xua_test/xuatest.c | 293 + plat/mtp3/Makefile | 98 + plat/mtp3/src/include/mtp3.h | 172 + plat/mtp3/src/include/mtp3lite.h | 28 + plat/mtp3/src/include/mtp3lite_pub.h | 53 + plat/mtp3/src/include/mtpconst.h | 579 + plat/mtp3/src/include/mtpdef.h | 159 + plat/mtp3/src/include/mtpext.h | 140 + plat/mtp3/src/include/mtpfunc.h | 102 + plat/mtp3/src/include/mtpstm.h | 296 + plat/mtp3/src/mtp3lite.c | 791 + plat/mtp3/src/mtpinit.c | 2223 ++ plat/mtp3/src/mtpm.c | 2502 ++ plat/mtp3/src/mtpmib.c | 4537 +++ plat/mtp3/src/mtpslm.c | 405 + plat/mtp3/src/mtpsmh.c | 5375 ++++ plat/mtp3/src/mtpsrm.c | 336 + plat/mtp3/src/mtpstm.c | 2205 ++ plat/public/Makefile | 98 + plat/public/src/asn1.c | 943 + plat/public/src/asn1per.c | 444 + plat/public/src/bisearch.c | 199 + plat/public/src/cdr.c | 453 + plat/public/src/crypt.c | 493 + plat/public/src/include/asn1.h | 76 + plat/public/src/include/asn1per.h | 64 + plat/public/src/include/bisearch.h | 123 + plat/public/src/include/cdr.h | 60 + plat/public/src/include/crypt.h | 28 + plat/public/src/include/includes.h | 47 + plat/public/src/include/includes.h.bak | 47 + plat/public/src/include/license_id.h | 37 + plat/public/src/include/memwatch.h | 707 + plat/public/src/include/omc_public.h | 643 + plat/public/src/include/pub_base.h | 127 + plat/public/src/include/pub_debug.h | 43 + plat/public/src/include/pub_file.h | 22 + plat/public/src/include/pub_fmt.h | 132 + plat/public/src/include/pub_include.h | 39 + plat/public/src/include/pub_inet.h | 77 + plat/public/src/include/pub_list.h | 501 + plat/public/src/include/pub_log.h | 68 + plat/public/src/include/pub_malloc.h | 26 + plat/public/src/include/pub_netcap.h | 35 + plat/public/src/include/pub_sdp.h | 205 + plat/public/src/include/pub_str.h | 26 + plat/public/src/include/pub_sys.h | 53 + plat/public/src/include/pub_time.h | 29 + plat/public/src/include/pub_timer.h | 96 + plat/public/src/include/pub_wnet.h | 41 + plat/public/src/include/public.h | 102 + plat/public/src/include/svrstat.h | 100 + plat/public/src/memwatch.c | 2669 ++ plat/public/src/pub_conf.c | 12 + plat/public/src/pub_debug.c | 52 + plat/public/src/pub_file.c | 44 + plat/public/src/pub_fmt.c | 1264 + plat/public/src/pub_inet.c | 409 + plat/public/src/pub_license.c | 152 + plat/public/src/pub_log.c | 135 + plat/public/src/pub_malloc.c | 23 + plat/public/src/pub_netcap.c | 371 + plat/public/src/pub_sdp.c | 3560 +++ plat/public/src/pub_str.c | 999 + plat/public/src/pub_sys.c | 555 + plat/public/src/pub_time.c | 152 + plat/public/src/pub_timer.c | 182 + plat/public/src/pub_wnet.c | 425 + plat/public/src/shm.c | 69 + plat/public/src/uwav/number.c | 483 + plat/public/src/uwav/number.h | 82 + plat/public/src/uwav/numgrp.c | 176 + plat/public/src/uwav/numgrp.h | 29 + plat/public/ut/asn.1/asntest.c | 429 + plat/public/ut/bisearch/bisearch_test.c | 149 + plat/public/ut/debug_api/debug | Bin 0 -> 11872 bytes plat/public/ut/debug_api/wxc_debug_test.c | 125 + plat/public/ut/function.c | 87 + plat/public/ut/inet/pub_inet_test.c | 648 + plat/public/ut/main/Makefile | 98 + plat/public/ut/main/bin/.svn/all-wcprops | 5 + plat/public/ut/main/bin/.svn/entries | 28 + plat/public/ut/main/obj/.svn/all-wcprops | 5 + plat/public/ut/main/obj/.svn/entries | 28 + plat/public/ut/main/src/.svn/all-wcprops | 11 + plat/public/ut/main/src/.svn/entries | 62 + .../main/src/.svn/prop-base/main.c.svn-base | 5 + .../main/src/.svn/text-base/main.c.svn-base | 19 + plat/public/ut/main/src/main.c | 19 + plat/public/ut/public_test/public_test.c | 15 + plat/public/ut/timer/Makefile | 72 + plat/public/ut/timer/bin/.svn/all-wcprops | 5 + plat/public/ut/timer/bin/.svn/entries | 28 + plat/public/ut/timer/ut/.svn/all-wcprops | 5 + plat/public/ut/timer/ut/.svn/entries | 28 + plat/public/ut/timer/wxc_tmtest.c | 155 + plat/radius/Makefile | 95 + plat/radius/src/include/radius.h | 11 + plat/radius/src/include/radius_const.h | 346 + plat/radius/src/include/radius_debug.h | 14 + plat/radius/src/include/radius_def.h | 42 + plat/radius/src/include/radius_ext.h | 41 + plat/radius/src/include/radius_fsm.h | 8 + plat/radius/src/include/radius_function.h | 33 + plat/radius/src/include/radius_if.h | 26 + plat/radius/src/include/radius_inc.h | 6 + plat/radius/src/include/radius_md5.h | 85 + plat/radius/src/include/radius_pub.h | 66 + plat/radius/src/include/radius_struct.h | 1433 + plat/radius/src/include/radius_transport.h | 8 + plat/radius/src/radius.c | 121 + plat/radius/src/radius_debug.c | 495 + plat/radius/src/radius_fsm.c | 340 + plat/radius/src/radius_function.c | 9794 ++++++ plat/radius/src/radius_if.c | 277 + plat/radius/src/radius_md5.c | 848 + plat/radius/src/radius_transport.c | 126 + plat/radius/ut/Makefile | 101 + plat/radius/ut/radius_test_main.c | 49 + plat/radius/ut/radius_unit_test.c | 157 + plat/radius/ut/radius_unit_test.h | 7 + plat/sccp/Makefile | 98 + plat/sccp/src/include/sccp.h | 399 + plat/sccp/src/include/sccp_func.h | 166 + plat/sccp/src/include/sccp_pub.h | 52 + plat/sccp/src/include/sccpconst.h | 503 + plat/sccp/src/include/sccpconst.h.bak | 503 + plat/sccp/src/include/scoc.h | 274 + plat/sccp/src/include/scoc_if.h | 560 + plat/sccp/src/sccp.c | 399 + plat/sccp/src/sccp_debug.c | 683 + plat/sccp/src/sccp_func.c | 113 + plat/sccp/src/sccp_gtt.c | 441 + plat/sccp/src/sccp_log.c | 432 + plat/sccp/src/sccp_mib.c | 1188 + plat/sccp/src/sccp_msg.c | 820 + plat/sccp/src/sccp_param.c | 775 + plat/sccp/src/sclc.c | 638 + plat/sccp/src/scmg.c | 556 + plat/sccp/src/scoc.c | 126 + plat/sccp/src/scoc_fsm.c | 1109 + plat/sccp/src/scoc_func.c | 974 + plat/sccp/src/scoc_if.c | 292 + plat/sccp/src/scoc_pool.c | 231 + plat/sccp/src/scoc_pri.c | 283 + plat/sccp/src/scrc.c | 1974 ++ plat/sccp/ut/fsmtest/Makefile | 98 + plat/sccp/ut/fsmtest/bin/.svn/all-wcprops | 5 + plat/sccp/ut/fsmtest/bin/.svn/entries | 31 + .../sccp/ut/fsmtest/bin/conf/.svn/all-wcprops | 149 + plat/sccp/ut/fsmtest/bin/conf/.svn/entries | 844 + .../conf/.svn/prop-base/HlrSysPara.svn-base | 9 + .../conf/.svn/prop-base/cap_acn.conf.svn-base | 5 + .../prop-base/cap_operation.conf.svn-base | 5 + .../.svn/prop-base/cc_table.conf.svn-base | 5 + .../.svn/prop-base/conv_prefix.conf.svn-base | 9 + .../conf/.svn/prop-base/hae_sys.conf.svn-base | 5 + .../conf/.svn/prop-base/help_page.svn-base | 5 + .../.svn/prop-base/hlr_parambit.conf.svn-base | 9 + .../conf/.svn/prop-base/iptrans.conf.svn-base | 5 + .../conf/.svn/prop-base/map_acn.conf.svn-base | 5 + .../prop-base/map_operation.conf.svn-base | 5 + .../conf/.svn/prop-base/menu_page.svn-base | 5 + .../conf/.svn/prop-base/mtp3.conf.svn-base | 5 + .../conf/.svn/prop-base/ppsConf.txt.svn-base | 9 + .../bin/conf/.svn/prop-base/profile.svn-base | 5 + .../conf/.svn/prop-base/sccp.conf.svn-base | 5 + .../.svn/prop-base/sccp_test.conf.svn-base | 5 + .../.svn/prop-base/smsc_csta.conf.svn-base | 5 + .../prop-base/smsc_parambit.conf.svn-base | 9 + .../.svn/prop-base/smsc_sys.conf.svn-base | 5 + .../conf/.svn/prop-base/system.ini.svn-base | 9 + .../.svn/prop-base/wxc2_sys.conf.svn-base | 5 + .../conf/.svn/prop-base/wxc2exit.txt.svn-base | 5 + .../.svn/prop-base/xap_sysparam.conf.svn-base | 9 + .../conf/.svn/text-base/HlrSysPara.svn-base | Bin 0 -> 7244 bytes .../conf/.svn/text-base/cap_acn.conf.svn-base | 8 + .../text-base/cap_operation.conf.svn-base | 36 + .../.svn/text-base/cc_table.conf.svn-base | 215 + .../.svn/text-base/conv_prefix.conf.svn-base | Bin 0 -> 4608 bytes .../conf/.svn/text-base/hae_sys.conf.svn-base | 6 + .../conf/.svn/text-base/help_page.svn-base | 20 + .../.svn/text-base/hlr_parambit.conf.svn-base | Bin 0 -> 20740 bytes .../conf/.svn/text-base/iptrans.conf.svn-base | 25 + .../conf/.svn/text-base/map_acn.conf.svn-base | 42 + .../text-base/map_operation.conf.svn-base | 76 + .../conf/.svn/text-base/menu_page.svn-base | 17 + .../conf/.svn/text-base/mtp3.conf.svn-base | 1408 + .../conf/.svn/text-base/ppsConf.txt.svn-base | Bin 0 -> 28340 bytes .../bin/conf/.svn/text-base/profile.svn-base | 37 + .../conf/.svn/text-base/sccp.conf.svn-base | 26 + .../.svn/text-base/sccp_test.conf.svn-base | 2 + .../.svn/text-base/smsc_csta.conf.svn-base | 21 + .../text-base/smsc_parambit.conf.svn-base | Bin 0 -> 2836 bytes .../.svn/text-base/smsc_sys.conf.svn-base | 5 + .../conf/.svn/text-base/system.ini.svn-base | Bin 0 -> 212 bytes .../.svn/text-base/wxc2_sys.conf.svn-base | 1 + .../conf/.svn/text-base/wxc2exit.txt.svn-base | 4 + .../.svn/text-base/xap_sysparam.conf.svn-base | Bin 0 -> 13 bytes plat/sccp/ut/fsmtest/bin/conf/HlrSysPara | Bin 0 -> 7244 bytes plat/sccp/ut/fsmtest/bin/conf/cap_acn.conf | 8 + .../ut/fsmtest/bin/conf/cap_operation.conf | 36 + plat/sccp/ut/fsmtest/bin/conf/cc_table.conf | 215 + .../sccp/ut/fsmtest/bin/conf/conv_prefix.conf | Bin 0 -> 4608 bytes plat/sccp/ut/fsmtest/bin/conf/hae_sys.conf | 6 + plat/sccp/ut/fsmtest/bin/conf/help_page | 20 + .../ut/fsmtest/bin/conf/hlr_parambit.conf | Bin 0 -> 20740 bytes plat/sccp/ut/fsmtest/bin/conf/iptrans.conf | 25 + plat/sccp/ut/fsmtest/bin/conf/map_acn.conf | 42 + .../ut/fsmtest/bin/conf/map_operation.conf | 76 + plat/sccp/ut/fsmtest/bin/conf/menu_page | 17 + plat/sccp/ut/fsmtest/bin/conf/mtp3.conf | 1408 + plat/sccp/ut/fsmtest/bin/conf/ppsConf.txt | Bin 0 -> 28340 bytes plat/sccp/ut/fsmtest/bin/conf/profile | 37 + plat/sccp/ut/fsmtest/bin/conf/sccp.conf | 26 + plat/sccp/ut/fsmtest/bin/conf/sccp_test.conf | 2 + plat/sccp/ut/fsmtest/bin/conf/smsc_csta.conf | 21 + .../ut/fsmtest/bin/conf/smsc_parambit.conf | Bin 0 -> 2836 bytes plat/sccp/ut/fsmtest/bin/conf/smsc_sys.conf | 5 + plat/sccp/ut/fsmtest/bin/conf/system.ini | Bin 0 -> 212 bytes plat/sccp/ut/fsmtest/bin/conf/wxc2_sys.conf | 1 + plat/sccp/ut/fsmtest/bin/conf/wxc2exit.txt | 4 + .../ut/fsmtest/bin/conf/xap_sysparam.conf | Bin 0 -> 13 bytes plat/sccp/ut/fsmtest/obj/.svn/all-wcprops | 17 + plat/sccp/ut/fsmtest/obj/.svn/entries | 96 + .../.svn/prop-base/sccp_test.gcno.svn-base | 9 + .../.svn/prop-base/scoc_test.gcno.svn-base | 9 + .../.svn/text-base/sccp_test.gcno.svn-base | Bin 0 -> 5000 bytes .../.svn/text-base/scoc_test.gcno.svn-base | Bin 0 -> 13992 bytes plat/sccp/ut/fsmtest/obj/sccp_test.gcno | Bin 0 -> 5000 bytes plat/sccp/ut/fsmtest/obj/scoc_test.gcno | Bin 0 -> 13992 bytes plat/sccp/ut/fsmtest/sccp_test.c | 192 + plat/sccp/ut/fsmtest/scoc_test.c | 616 + plat/scf/Makefile | 92 + plat/scf/src/include/scfdef.h | 12 + plat/scf/src/include/scfmsg.h | 105 + plat/scf/src/include/scfpub.h | 5 + plat/scf/src/scfmsg.c | 170 + plat/scf/src/scsm.c | 976 + plat/smpp/Makefile | 98 + plat/smpp/src/include/smpp.h | 187 + plat/smpp/src/include/smpp_const.h | 240 + plat/smpp/src/include/smpp_def.h | 39 + plat/smpp/src/include/smpp_ext.h | 38 + plat/smpp/src/include/smpp_msg.h | 465 + plat/smpp/src/include/smpp_public.h | 62 + plat/smpp/src/smpp_debug.c | 471 + plat/smpp/src/smpp_fsm.c | 676 + plat/smpp/src/smpp_func.c | 1204 + plat/smpp/src/smpp_mib.c | 819 + plat/smpp/src/smpp_msg.c | 5897 ++++ plat/smpp/ut/conf/MIB_files/.svn/all-wcprops | 95 + plat/smpp/ut/conf/MIB_files/.svn/entries | 538 + .../.svn/prop-base/IWV-SMI.txt.svn-base | 5 + .../prop-base/Special_App-SMI.txt.svn-base | 5 + .../prop-base/System_IP_List.txt.svn-base | 5 + .../.svn/prop-base/WXC2-AUC-MIB.txt.svn-base | 5 + .../.svn/prop-base/WXC2-HLR-MIB.txt.svn-base | 5 + .../.svn/prop-base/WXC2-MSC-MIB.txt.svn-base | 5 + .../.svn/prop-base/WXC2-MSS-MIB.txt.svn-base | 5 + .../.svn/prop-base/WXC2-PPS-MIB.txt.svn-base | 5 + .../.svn/prop-base/WXC2-SMI.txt.svn-base | 5 + .../.svn/prop-base/WXC2-SMSC-MIB.txt.svn-base | 5 + .../.svn/prop-base/WXC2-SS7-MIB.txt.svn-base | 5 + .../.svn/prop-base/menu_page.svn-base | 5 + .../.svn/prop-base/menu_tree.txt.svn-base | 5 + .../.svn/prop-base/mib_list_file.txt.svn-base | 5 + .../prop-base/mib_write_tree.txt.svn-base | 5 + .../.svn/text-base/IWV-SMI.txt.svn-base | 40 + .../text-base/Special_App-SMI.txt.svn-base | 43 + .../text-base/System_IP_List.txt.svn-base | 26 + .../.svn/text-base/WXC2-AUC-MIB.txt.svn-base | 437 + .../.svn/text-base/WXC2-HLR-MIB.txt.svn-base | 2431 ++ .../.svn/text-base/WXC2-MSC-MIB.txt.svn-base | 4084 +++ .../.svn/text-base/WXC2-MSS-MIB.txt.svn-base | 54 + .../.svn/text-base/WXC2-PPS-MIB.txt.svn-base | 13090 ++++++++ .../.svn/text-base/WXC2-SMI.txt.svn-base | 57 + .../.svn/text-base/WXC2-SMSC-MIB.txt.svn-base | 259 + .../.svn/text-base/WXC2-SS7-MIB.txt.svn-base | 3729 +++ .../.svn/text-base/menu_page.svn-base | 13 + .../.svn/text-base/menu_tree.txt.svn-base | 908 + .../.svn/text-base/mib_list_file.txt.svn-base | 14 + .../text-base/mib_write_tree.txt.svn-base | 25897 ++++++++++++++++ plat/smpp/ut/conf/MIB_files/IWV-SMI.txt | 40 + .../ut/conf/MIB_files/Special_App-SMI.txt | 43 + .../smpp/ut/conf/MIB_files/System_IP_List.txt | 26 + plat/smpp/ut/conf/MIB_files/WXC2-AUC-MIB.txt | 437 + plat/smpp/ut/conf/MIB_files/WXC2-HLR-MIB.txt | 2431 ++ plat/smpp/ut/conf/MIB_files/WXC2-MSC-MIB.txt | 4084 +++ plat/smpp/ut/conf/MIB_files/WXC2-MSS-MIB.txt | 54 + plat/smpp/ut/conf/MIB_files/WXC2-PPS-MIB.txt | 13090 ++++++++ plat/smpp/ut/conf/MIB_files/WXC2-SMI.txt | 57 + plat/smpp/ut/conf/MIB_files/WXC2-SMSC-MIB.txt | 259 + plat/smpp/ut/conf/MIB_files/WXC2-SS7-MIB.txt | 3729 +++ plat/smpp/ut/conf/MIB_files/menu_page | 13 + plat/smpp/ut/conf/MIB_files/menu_tree.txt | 908 + plat/smpp/ut/conf/MIB_files/mib_list_file.txt | 14 + .../smpp/ut/conf/MIB_files/mib_write_tree.txt | 25897 ++++++++++++++++ plat/smpp/ut/conf/guess_number_test.conf | 1 + plat/smpp/ut/conf/help_page | 16 + plat/smpp/ut/conf/iptrans.conf | 25 + plat/smpp/ut/conf/menu_page | 22 + plat/smpp/ut/conf/mtp3.conf | 1408 + plat/smpp/ut/conf/sccp.conf | 22 + plat/smpp/ut/conf/smpp.conf | 35 + plat/smpp/ut/smpp_test/smpp_test.c | 688 + plat/smpp/ut/smpp_ussd_test/guess_number.c | 948 + plat/smpp/ut/smpp_ussd_test/pppchat.c | 704 + plat/snmp/Makefile | 98 + plat/snmp/src/heartbeat.c | 315 + plat/snmp/src/include/heartbeat.h | 88 + plat/snmp/src/include/macro.h | 100 + plat/snmp/src/include/snmp.h | 415 + plat/snmp/src/include/snmpv3AuthCry.h | 77 + plat/snmp/src/include/sysctrl.h | 57 + plat/snmp/src/include/table.h | 42 + plat/snmp/src/md5.c | 301 + plat/snmp/src/md5.h | 21 + plat/snmp/src/mib_parser/snmp_mib.c | 4152 +++ plat/snmp/src/mib_parser/snmp_mib.h | 171 + plat/snmp/src/mib_parser/snmp_mib_api.c | 122 + plat/snmp/src/mib_parser/snmp_mib_api.h | 49 + plat/snmp/src/snmp.c | 3319 ++ plat/snmp/src/snmpdebug.c | 503 + plat/snmp/src/snmpmib.c | 224 + plat/snmp/src/snmptable.c | 269 + plat/snmp/src/snmptest.c | 254 + plat/snmp/src/snmpv3AuthCry.c | 278 + plat/snmp/src/sysctrl.c | 329 + plat/tcap/Makefile | 98 + plat/tcap/src/idmanage.c | 292 + plat/tcap/src/include/idmanage.h | 16 + plat/tcap/src/include/itcap.h | 18 + plat/tcap/src/include/tcap_head.h | 256 + plat/tcap/src/include/tcap_m.h | 21 + plat/tcap/src/include/tcap_proc.h | 3 + plat/tcap/src/include/tcap_public.h | 68 + plat/tcap/src/include/tcap_struct.h | 396 + plat/tcap/src/itcap.c | 759 + plat/tcap/src/tcap_coding.c | 2272 ++ plat/tcap/src/tcap_fsm.c | 3102 ++ plat/tcap/src/tcap_m.c | 603 + plat/tcp/Makefile | 98 + plat/tcp/src/include/tcp_debug.h | 20 + plat/tcp/src/include/tcp_if.h | 32 + plat/tcp/src/include/tcp_inc.h | 134 + plat/tcp/src/include/tcp_port.h | 59 + plat/tcp/src/tcp_debug.c | 429 + plat/tcp/src/tcp_if.c | 99 + plat/tcp/src/tcp_port.c | 1063 + plat/xapp/Makefile | 95 + plat/xapp/conf/cap_acn.conf | 8 + plat/xapp/conf/cap_operation.conf | 36 + plat/xapp/conf/map_acn.conf | 42 + plat/xapp/conf/map_operation.conf | 76 + plat/xapp/src/capp/cap_coding.h | 39 + plat/xapp/src/capp/cap_head.h | 151 + plat/xapp/src/capp/cap_msg.c | 1520 + plat/xapp/src/capp/cap_msg.h | 876 + plat/xapp/src/capp/cap_msgtype.c | 1073 + plat/xapp/src/capp/cap_public.c | 497 + plat/xapp/src/capp/cap_public.h | 14 + plat/xapp/src/capp/icap.h | 20 + plat/xapp/src/conv_prefix.c | 1323 + plat/xapp/src/conv_prefix.h | 91 + plat/xapp/src/ixap.h | 77 + plat/xapp/src/mapp/Map_opr.c | 918 + plat/xapp/src/mapp/imap.h | 28 + plat/xapp/src/mapp/is41_code.h | 110 + plat/xapp/src/mapp/is41_code_auc.c | 1345 + plat/xapp/src/mapp/is41_code_ms.c | 3968 +++ plat/xapp/src/mapp/is41_code_sms.c | 1134 + plat/xapp/src/mapp/is41_code_win.c | 1871 ++ plat/xapp/src/mapp/is41_coding.c | 490 + plat/xapp/src/mapp/is41_debug.c | 3650 +++ plat/xapp/src/mapp/is41_init.c | 23 + plat/xapp/src/mapp/map_LCSCode.c | 430 + plat/xapp/src/mapp/map_LCSCode.h | 260 + plat/xapp/src/mapp/map_acn.h | 75 + plat/xapp/src/mapp/map_code.h | 343 + plat/xapp/src/mapp/map_code_auc.c | 436 + plat/xapp/src/mapp/map_code_ch.c | 1937 ++ plat/xapp/src/mapp/map_code_dlgpdu.c | 210 + plat/xapp/src/mapp/map_code_ms.c | 5305 ++++ plat/xapp/src/mapp/map_code_om.c | 231 + plat/xapp/src/mapp/map_code_sms.c | 1322 + plat/xapp/src/mapp/map_code_ss.c | 1647 + plat/xapp/src/mapp/map_coding.c | 2345 ++ plat/xapp/src/mapp/map_coding.h | 546 + plat/xapp/src/mapp/map_const.h | 1353 + plat/xapp/src/mapp/map_dlgpdu.h | 104 + plat/xapp/src/mapp/map_includes.h | 24 + plat/xapp/src/mapp/map_opr_func.h | 34 + plat/xapp/src/mapp/map_public.c | 1112 + plat/xapp/src/mapp/map_public.h | 26 + plat/xapp/src/mapp/map_struct.h | 4585 +++ plat/xapp/src/mapp/win_struct.h | 477 + plat/xapp/src/roaming_rule.c | 427 + plat/xapp/src/roaming_rule.h | 44 + plat/xapp/src/xap_cdmacdr.c | 1760 ++ plat/xapp/src/xap_cdmacdr.h | 898 + plat/xapp/src/xap_interface.c | 1063 + plat/xapp/src/xap_interfunc.h | 11 + plat/xapp/src/xap_monitor.c | 1340 + plat/xapp/src/xap_monitor.h | 19 + plat/xapp/src/xap_provider.c | 3496 +++ plat/xapp/src/xap_provider.h | 185 + plat/xapp/ut/xapp_test/Makefile | 42 + plat/xapp/ut/xapp_test/conf/.sccp.conf.swo | Bin 0 -> 12288 bytes plat/xapp/ut/xapp_test/conf/.svn/all-wcprops | 179 + plat/xapp/ut/xapp_test/conf/.svn/entries | 1014 + .../.svn/prop-base/.sccp.conf.swo.svn-base | 9 + .../conf/.svn/prop-base/HlrSysPara.svn-base | 9 + .../conf/.svn/prop-base/cap_acn.conf.svn-base | 5 + .../prop-base/cap_operation.conf.svn-base | 5 + .../.svn/prop-base/cc_table.conf.svn-base | 5 + .../conf/.svn/prop-base/conf.rar.svn-base | 9 + .../.svn/prop-base/conv_prefix.conf.svn-base | 9 + .../conf/.svn/prop-base/hae_sys.conf.svn-base | 5 + .../conf/.svn/prop-base/help_page.svn-base | 5 + .../.svn/prop-base/hlr_parambit.conf.svn-base | 9 + .../conf/.svn/prop-base/iptrans.conf.svn-base | 5 + .../conf/.svn/prop-base/map_acn.conf.svn-base | 5 + .../prop-base/map_operation.conf.svn-base | 5 + .../conf/.svn/prop-base/menu_page.svn-base | 5 + .../conf/.svn/prop-base/mtp3.conf.svn-base | 5 + .../conf/.svn/prop-base/ppsConf.txt.svn-base | 9 + .../conf/.svn/prop-base/profile.svn-base | 5 + .../conf/.svn/prop-base/sccp.conf.svn-base | 5 + .../.svn/prop-base/smsc_csta.conf.svn-base | 5 + .../prop-base/smsc_parambit.conf.svn-base | 9 + .../.svn/prop-base/smsc_sys.conf.svn-base | 5 + .../.svn/prop-base/system.ini.100k.svn-base | 9 + .../.svn/prop-base/system.ini.30K.svn-base | 9 + .../conf/.svn/prop-base/system.ini.svn-base | 9 + .../prop-base/system.inimscvlrhlr.svn-base | 9 + .../.svn/prop-base/wxc2_sys.conf.svn-base | 5 + .../conf/.svn/prop-base/wxc2exit.txt.svn-base | 5 + .../.svn/prop-base/xap_sysparam.conf.svn-base | 9 + .../.svn/prop-base/xapp_test.conf.svn-base | 5 + .../.svn/text-base/.sccp.conf.swo.svn-base | Bin 0 -> 12288 bytes .../conf/.svn/text-base/HlrSysPara.svn-base | Bin 0 -> 7244 bytes .../conf/.svn/text-base/cap_acn.conf.svn-base | 8 + .../text-base/cap_operation.conf.svn-base | 36 + .../.svn/text-base/cc_table.conf.svn-base | 215 + .../conf/.svn/text-base/conf.rar.svn-base | Bin 0 -> 2638 bytes .../.svn/text-base/conv_prefix.conf.svn-base | Bin 0 -> 4608 bytes .../conf/.svn/text-base/hae_sys.conf.svn-base | 6 + .../conf/.svn/text-base/help_page.svn-base | 20 + .../.svn/text-base/hlr_parambit.conf.svn-base | Bin 0 -> 20740 bytes .../conf/.svn/text-base/iptrans.conf.svn-base | 17 + .../conf/.svn/text-base/map_acn.conf.svn-base | 42 + .../text-base/map_operation.conf.svn-base | 76 + .../conf/.svn/text-base/menu_page.svn-base | 13 + .../conf/.svn/text-base/mtp3.conf.svn-base | 1408 + .../conf/.svn/text-base/ppsConf.txt.svn-base | Bin 0 -> 28340 bytes .../conf/.svn/text-base/profile.svn-base | 37 + .../conf/.svn/text-base/sccp.conf.svn-base | 26 + .../.svn/text-base/smsc_csta.conf.svn-base | 21 + .../text-base/smsc_parambit.conf.svn-base | Bin 0 -> 2836 bytes .../.svn/text-base/smsc_sys.conf.svn-base | 5 + .../.svn/text-base/system.ini.100k.svn-base | Bin 0 -> 212 bytes .../.svn/text-base/system.ini.30K.svn-base | Bin 0 -> 212 bytes .../conf/.svn/text-base/system.ini.svn-base | Bin 0 -> 212 bytes .../text-base/system.inimscvlrhlr.svn-base | Bin 0 -> 212 bytes .../.svn/text-base/wxc2_sys.conf.svn-base | 1 + .../conf/.svn/text-base/wxc2exit.txt.svn-base | 4 + .../.svn/text-base/xap_sysparam.conf.svn-base | Bin 0 -> 13 bytes .../.svn/text-base/xapp_test.conf.svn-base | 2 + plat/xapp/ut/xapp_test/conf/HlrSysPara | Bin 0 -> 7244 bytes plat/xapp/ut/xapp_test/conf/cap_acn.conf | 8 + .../xapp/ut/xapp_test/conf/cap_operation.conf | 36 + plat/xapp/ut/xapp_test/conf/cc_table.conf | 215 + plat/xapp/ut/xapp_test/conf/conf.rar | Bin 0 -> 2638 bytes plat/xapp/ut/xapp_test/conf/conv_prefix.conf | Bin 0 -> 4608 bytes plat/xapp/ut/xapp_test/conf/hae_sys.conf | 6 + plat/xapp/ut/xapp_test/conf/help_page | 20 + plat/xapp/ut/xapp_test/conf/hlr_parambit.conf | Bin 0 -> 20740 bytes plat/xapp/ut/xapp_test/conf/iptrans.conf | 17 + plat/xapp/ut/xapp_test/conf/map_acn.conf | 42 + .../xapp/ut/xapp_test/conf/map_operation.conf | 76 + plat/xapp/ut/xapp_test/conf/menu_page | 13 + plat/xapp/ut/xapp_test/conf/mtp3.conf | 1408 + plat/xapp/ut/xapp_test/conf/ppsConf.txt | Bin 0 -> 28340 bytes plat/xapp/ut/xapp_test/conf/profile | 37 + plat/xapp/ut/xapp_test/conf/sccp.conf | 26 + plat/xapp/ut/xapp_test/conf/smsc_csta.conf | 21 + .../xapp/ut/xapp_test/conf/smsc_parambit.conf | Bin 0 -> 2836 bytes plat/xapp/ut/xapp_test/conf/smsc_sys.conf | 5 + plat/xapp/ut/xapp_test/conf/system.ini | Bin 0 -> 212 bytes plat/xapp/ut/xapp_test/conf/system.ini.100k | Bin 0 -> 212 bytes plat/xapp/ut/xapp_test/conf/system.ini.30K | Bin 0 -> 212 bytes .../ut/xapp_test/conf/system.inimscvlrhlr | Bin 0 -> 212 bytes plat/xapp/ut/xapp_test/conf/wxc2_sys.conf | 1 + plat/xapp/ut/xapp_test/conf/wxc2exit.txt | 4 + plat/xapp/ut/xapp_test/conf/xap_sysparam.conf | Bin 0 -> 13 bytes plat/xapp/ut/xapp_test/conf/xapp_test.conf | 2 + plat/xapp/ut/xapp_test/xapp_coding_test.c | 652 + plat/xapp/ut/xapp_test/xapp_coding_test.h | 105 + plat/xapp/ut/xapp_test/xapp_main.c | 372 + plat/xapp/ut/xapp_test/xapp_main.h | 32 + plat/xapp/ut/xapp_test/xapp_op_test.c | 2067 ++ plat/xapp/ut/xapp_test/xapp_op_test.h | 39 + 1057 files changed, 519829 insertions(+) create mode 100644 mss/log/pps_trace.log create mode 100644 mss/log/snmp_log.txt create mode 100644 mss/log/wxc2_log.txt create mode 100644 mss/log/wxc2_startup.log create mode 100644 mss/log/wxc2exit.txt create mode 100644 mss/main/Makefile create mode 100644 mss/main/conf/.copyarea.db create mode 100644 mss/main/conf/.ussd.conf.swp create mode 100644 mss/main/conf/AucSysPara create mode 100644 mss/main/conf/EirSysPara create mode 100644 mss/main/conf/EvrcFlt create mode 100644 mss/main/conf/HlrSysPara create mode 100644 mss/main/conf/MIB_files/IWV-SMI.txt create mode 100644 mss/main/conf/MIB_files/Special_App-SMI.txt create mode 100644 mss/main/conf/MIB_files/System_IP_List.txt create mode 100644 mss/main/conf/MIB_files/WXC2-AUC-MIB.txt create mode 100644 mss/main/conf/MIB_files/WXC2-HLR-MIB.txt create mode 100644 mss/main/conf/MIB_files/WXC2-MSC-MIB.txt create mode 100644 mss/main/conf/MIB_files/WXC2-MSS-MIB.txt create mode 100644 mss/main/conf/MIB_files/WXC2-PPS-MIB.txt create mode 100644 mss/main/conf/MIB_files/WXC2-SMI.txt create mode 100644 mss/main/conf/MIB_files/WXC2-SMSC-MIB.txt create mode 100644 mss/main/conf/MIB_files/WXC2-SS7-MIB.txt create mode 100644 mss/main/conf/MIB_files/menu_page create mode 100644 mss/main/conf/MIB_files/menu_tree.txt create mode 100644 mss/main/conf/MIB_files/mib_list_file.txt create mode 100644 mss/main/conf/MIB_files/mib_write_tree.txt create mode 100644 mss/main/conf/aas_codec_table.conf create mode 100644 mss/main/conf/aas_langVG_Conf create mode 100644 mss/main/conf/aas_publicVG_Conf create mode 100644 mss/main/conf/alaw2intel create mode 100644 mss/main/conf/cap_acn.conf create mode 100644 mss/main/conf/cap_acn.confV1 create mode 100644 mss/main/conf/cap_acn.confV2 create mode 100644 mss/main/conf/cap_acn.confV3 create mode 100644 mss/main/conf/cap_operation.conf create mode 100644 mss/main/conf/cc_table.conf create mode 100644 mss/main/conf/celp13k create mode 100644 mss/main/conf/conv_prefix.conf create mode 100644 mss/main/conf/debug.conf create mode 100644 mss/main/conf/evrc2pcm create mode 100644 mss/main/conf/ews.conf create mode 100644 mss/main/conf/ewsAdmin.conf create mode 100644 mss/main/conf/ewsDetailLeftMenu.conf create mode 100644 mss/main/conf/ewsHtml/add.gif create mode 100644 mss/main/conf/ewsHtml/alarmList_header.html create mode 100644 mss/main/conf/ewsHtml/alarmNumList.html create mode 100644 mss/main/conf/ewsHtml/alvr_125.gif create mode 100644 mss/main/conf/ewsHtml/alvr_150.gif create mode 100644 mss/main/conf/ewsHtml/blank.gif create mode 100644 mss/main/conf/ewsHtml/default.html create mode 100644 mss/main/conf/ewsHtml/delete.gif create mode 100644 mss/main/conf/ewsHtml/detailTopMenu.html create mode 100644 mss/main/conf/ewsHtml/inDeveloping.html create mode 100644 mss/main/conf/ewsHtml/index.html create mode 100644 mss/main/conf/ewsHtml/lastblk.gif create mode 100644 mss/main/conf/ewsHtml/line.gif create mode 100644 mss/main/conf/ewsHtml/listDetailContent.html create mode 100644 mss/main/conf/ewsHtml/midblk.gif create mode 100644 mss/main/conf/ewsHtml/midminus.gif create mode 100644 mss/main/conf/ewsHtml/midplus.gif create mode 100644 mss/main/conf/ewsHtml/singleDetailContent_header.html create mode 100644 mss/main/conf/ewsHtml/status_header.html create mode 100644 mss/main/conf/ewsHtml/topMenu_header.html create mode 100644 mss/main/conf/ewsHtml/userConf_header.html create mode 100644 mss/main/conf/ewsHtml/userList_header.html create mode 100644 mss/main/conf/ewsIndex.conf create mode 100644 mss/main/conf/ewsLeftMenu.conf create mode 100644 mss/main/conf/ewsSysAlarmConf.conf create mode 100644 mss/main/conf/ewsSysConf.conf create mode 100644 mss/main/conf/fd_server.conf create mode 100644 mss/main/conf/help_page create mode 100644 mss/main/conf/hlr_parambit.conf create mode 100644 mss/main/conf/iptrans.conf create mode 100644 mss/main/conf/is41_operation.conf create mode 100644 mss/main/conf/manager_engine.conf create mode 100644 mss/main/conf/map_acn.conf create mode 100644 mss/main/conf/map_acn_ver1.conf create mode 100644 mss/main/conf/map_acn_ver2.conf create mode 100644 mss/main/conf/map_acn_ver3.conf create mode 100644 mss/main/conf/map_operation.conf create mode 100644 mss/main/conf/mcms_conf.txt create mode 100644 mss/main/conf/menu_page create mode 100644 mss/main/conf/menu_page2 create mode 100644 mss/main/conf/mhc_adjacentNodes.txt create mode 100644 mss/main/conf/mhc_sysParma.conf create mode 100644 mss/main/conf/mnpf.conf create mode 100644 mss/main/conf/mrfc_mrfp.conf create mode 100644 mss/main/conf/msc_art.conf create mode 100644 mss/main/conf/msc_conf create mode 100644 mss/main/conf/msc_conf.tgz create mode 100644 mss/main/conf/msc_cua.conf create mode 100644 mss/main/conf/msc_dps.conf create mode 100644 mss/main/conf/msc_la.conf create mode 100644 mss/main/conf/msc_mg.conf create mode 100644 mss/main/conf/msc_rzs.conf create mode 100644 mss/main/conf/msc_system.conf create mode 100644 mss/main/conf/msc_tg.conf create mode 100644 mss/main/conf/mtp3.conf create mode 100644 mss/main/conf/oprConf.txt create mode 100644 mss/main/conf/palim_lac.config create mode 100644 mss/main/conf/palim_mg.config create mode 100644 mss/main/conf/palim_sys.config create mode 100644 mss/main/conf/palim_tg.config create mode 100644 mss/main/conf/palim_user.config create mode 100644 mss/main/conf/ppsConf.txt create mode 100644 mss/main/conf/ppsCrdConf.txt create mode 100644 mss/main/conf/profile create mode 100644 mss/main/conf/rls_mg.conf create mode 100644 mss/main/conf/rls_rz.conf create mode 100644 mss/main/conf/rls_sys.conf create mode 100644 mss/main/conf/sccp.conf create mode 100644 mss/main/conf/shm.conf create mode 100644 mss/main/conf/smpp.conf create mode 100644 mss/main/conf/smsc_csta.conf create mode 100644 mss/main/conf/smsc_parambit.conf create mode 100644 mss/main/conf/smsc_sys.conf create mode 100644 mss/main/conf/snmp.conf create mode 100644 mss/main/conf/srf.conf create mode 100644 mss/main/conf/syntax_lang0 create mode 100644 mss/main/conf/syntax_lang1 create mode 100644 mss/main/conf/system.ini create mode 100644 mss/main/conf/ussd.conf create mode 100644 mss/main/conf/vlr.conf create mode 100644 mss/main/conf/vlr_conf create mode 100644 mss/main/conf/vlr_err create mode 100644 mss/main/conf/vlr_index create mode 100644 mss/main/conf/wxc2_sys.conf create mode 100644 mss/main/conf/wxc2exit.txt create mode 100644 mss/main/conf/xap_mscid.conf create mode 100644 mss/main/conf/xap_sysparam.conf create mode 100644 mss/main/makeclean create mode 100644 mss/main/makedebug create mode 100644 mss/main/makerelease_16cos create mode 100644 mss/main/makerelease_64cos_cook create mode 100644 mss/main/makerelease_rdb_tariff create mode 100644 mss/main/makerelease_zed_mobile create mode 100644 mss/main/myipcrm create mode 100644 mss/main/pkg.tgz create mode 100644 mss/main/release_note create mode 100644 mss/main/src/include/wxc2ver.h create mode 100644 mss/main/src/wxc2main.c create mode 100644 mss/main/wxc2d create mode 100644 mss/pps/Makefile create mode 100644 mss/pps/build_redis.txt create mode 100644 mss/pps/src/include/Makefile.am create mode 100644 mss/pps/src/include/Makefile.in create mode 100644 mss/pps/src/include/acconfig.h create mode 100644 mss/pps/src/include/callingCard.h create mode 100644 mss/pps/src/include/cdrme.h create mode 100644 mss/pps/src/include/config.h create mode 100644 mss/pps/src/include/crd.h create mode 100644 mss/pps/src/include/debug.h create mode 100644 mss/pps/src/include/errlog.h create mode 100644 mss/pps/src/include/function.h create mode 100644 mss/pps/src/include/gprs.h create mode 100644 mss/pps/src/include/includes.h create mode 100644 mss/pps/src/include/iofunc.h create mode 100644 mss/pps/src/include/logfunc.h create mode 100644 mss/pps/src/include/message.h create mode 100644 mss/pps/src/include/mfunc.h create mode 100644 mss/pps/src/include/param.h create mode 100644 mss/pps/src/include/plat_inc.h create mode 100644 mss/pps/src/include/ppsMibTable.h create mode 100644 mss/pps/src/include/pps_public.h create mode 100644 mss/pps/src/include/pps_redis.h create mode 100644 mss/pps/src/include/ppsinf.h create mode 100644 mss/pps/src/include/ppsm.h create mode 100644 mss/pps/src/include/ppsoid.h create mode 100644 mss/pps/src/include/precard.h create mode 100644 mss/pps/src/include/public.h create mode 100644 mss/pps/src/include/ramdata.h create mode 100644 mss/pps/src/include/report.h create mode 100644 mss/pps/src/include/restapi.h create mode 100644 mss/pps/src/include/stamp-h create mode 100644 mss/pps/src/include/stamp-h.in create mode 100644 mss/pps/src/include/tariff.h create mode 100644 mss/pps/src/include/version.h create mode 100644 mss/pps/src/include/voiceID.h create mode 100644 mss/pps/src/lib/Makefile create mode 100644 mss/pps/src/lib/Makefile.am create mode 100644 mss/pps/src/lib/Makefile.in create mode 100644 mss/pps/src/lib/comfunc.c create mode 100644 mss/pps/src/lib/crypt.c create mode 100644 mss/pps/src/lib/daemon.c create mode 100644 mss/pps/src/lib/debug.c create mode 100644 mss/pps/src/lib/error.c create mode 100644 mss/pps/src/lib/errorlog.c create mode 100644 mss/pps/src/lib/function.c create mode 100644 mss/pps/src/lib/iofunc.c create mode 100644 mss/pps/src/lib/ipcfunc.c create mode 100644 mss/pps/src/lib/logfunc.c create mode 100644 mss/pps/src/lib/ppsfun.c create mode 100644 mss/pps/src/lib/ppsfunc.c create mode 100644 mss/pps/src/lib/queuefunc.c create mode 100644 mss/pps/src/lib/signal.c create mode 100644 mss/pps/src/lib/time.c create mode 100644 mss/pps/src/lib/version.c create mode 100644 mss/pps/src/log/dailyreport.bak create mode 100644 mss/pps/src/log/pps_trace.log create mode 100644 mss/pps/src/log/snmp_log.txt create mode 100644 mss/pps/src/main/.Makefile.swp create mode 100644 mss/pps/src/main/Cook_Makefile create mode 100644 mss/pps/src/main/Makefile create mode 100644 mss/pps/src/main/Rdb_Makefile create mode 100644 mss/pps/src/main/Zed_Makefile create mode 100644 mss/pps/src/main/callMeBack.c create mode 100644 mss/pps/src/main/callingCardMsg.c create mode 100644 mss/pps/src/main/callingCardState.c create mode 100644 mss/pps/src/main/calling_card.c create mode 100644 mss/pps/src/main/capmsg.c create mode 100644 mss/pps/src/main/comfunc.c create mode 100644 mss/pps/src/main/conf/.svn/all-wcprops create mode 100644 mss/pps/src/main/conf/.svn/entries create mode 100644 mss/pps/src/main/conf/.svn/prop-base/cap_acn.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/cap_operation.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/conv_prefix.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/help_page.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/iptrans.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/map_acn.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/map_operation.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/menu_page.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/mtp3.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/ppsConf.txt.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/ppsCrdConf.txt.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/sccp.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/sccp.conf_omt.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/wxc2_sys.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/prop-base/xap_sysparam.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/cap_acn.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/cap_operation.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/conv_prefix.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/help_page.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/iptrans.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/map_acn.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/map_operation.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/menu_page.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/mtp3.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/ppsConf.txt.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/ppsCrdConf.txt.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/sccp.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/sccp.conf_omt.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/wxc2_sys.conf.svn-base create mode 100644 mss/pps/src/main/conf/.svn/text-base/xap_sysparam.conf.svn-base create mode 100644 mss/pps/src/main/conf/cap_acn.conf create mode 100644 mss/pps/src/main/conf/cap_operation.conf create mode 100644 mss/pps/src/main/conf/conv_prefix.conf create mode 100644 mss/pps/src/main/conf/help_page create mode 100644 mss/pps/src/main/conf/iptrans.conf create mode 100644 mss/pps/src/main/conf/map_acn.conf create mode 100644 mss/pps/src/main/conf/map_operation.conf create mode 100644 mss/pps/src/main/conf/menu_page create mode 100644 mss/pps/src/main/conf/mtp3.conf create mode 100644 mss/pps/src/main/conf/ppsConf.txt create mode 100644 mss/pps/src/main/conf/ppsCrdConf.txt create mode 100644 mss/pps/src/main/conf/sccp.conf create mode 100644 mss/pps/src/main/conf/sccp.conf_omt create mode 100644 mss/pps/src/main/conf/wxc2_sys.conf create mode 100644 mss/pps/src/main/conf/xap_sysparam.conf create mode 100644 mss/pps/src/main/crd.c create mode 100644 mss/pps/src/main/dailyreport.c create mode 100644 mss/pps/src/main/feeTransfer.c create mode 100644 mss/pps/src/main/freeSMS.c create mode 100644 mss/pps/src/main/gprs.c create mode 100644 mss/pps/src/main/loadtl.c create mode 100644 mss/pps/src/main/masterSlaveCard.c create mode 100644 mss/pps/src/main/message.c create mode 100644 mss/pps/src/main/mfunc.c create mode 100644 mss/pps/src/main/myipcrm create mode 100644 mss/pps/src/main/ocs_user_table.c create mode 100644 mss/pps/src/main/ppsMibTable.c create mode 100644 mss/pps/src/main/pps_redis.c create mode 100644 mss/pps/src/main/ppsfunc.c create mode 100644 mss/pps/src/main/ppsm.c create mode 100644 mss/pps/src/main/ppsmain.c create mode 100644 mss/pps/src/main/ppsmap.c create mode 100644 mss/pps/src/main/ppsmib.c create mode 100644 mss/pps/src/main/ppsopr.c create mode 100644 mss/pps/src/main/ppsussd.c create mode 100644 mss/pps/src/main/precard.c create mode 100644 mss/pps/src/main/radius.c create mode 100644 mss/pps/src/main/rammng.c create mode 100644 mss/pps/src/main/restapi.c create mode 100644 mss/pps/src/main/smppapi.c create mode 100644 mss/pps/src/main/tariffApplication.c create mode 100644 mss/pps/src/main/vas.c create mode 100644 mss/pps/src/object/makefile create mode 100644 plat/debug/Makefile create mode 100644 plat/debug/src/debug.c create mode 100644 plat/debug/src/include/debug.h create mode 100644 plat/debug/src/include/debug_struct.h create mode 100644 plat/debug/ut/debug_test.c create mode 100644 plat/diameter/daemon/daemon.c create mode 100644 plat/diameter/doc/acl_wl.conf.sample create mode 100644 plat/diameter/doc/app_acct.conf.sample create mode 100644 plat/diameter/doc/app_diameap.conf.sample create mode 100644 plat/diameter/doc/app_radgw.conf.sample create mode 100644 plat/diameter/doc/app_redirect.conf.sample create mode 100644 plat/diameter/doc/app_sip.conf.sample create mode 100644 plat/diameter/doc/app_sip.sql create mode 100644 plat/diameter/doc/app_sip_SL.sql create mode 100644 plat/diameter/doc/dbg_interactive.py.sample create mode 100644 plat/diameter/doc/dict_legacy_xml.conf.sample create mode 100644 plat/diameter/doc/eap_tls_plugin.diameap.conf.sample create mode 100644 plat/diameter/doc/echodrop.rgwx.conf.sample create mode 100644 plat/diameter/doc/freediameter.conf.sample create mode 100644 plat/diameter/doc/rt_busypeers.conf.sample create mode 100644 plat/diameter/doc/rt_default.conf.sample create mode 100644 plat/diameter/doc/rt_ereg.conf.sample create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.chain.crt create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.crl create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.crt create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.csr create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.db create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.db.attr create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.db.attr.old create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.db.old create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.srl create mode 100644 plat/diameter/doc/single_host/CAGenerate/ca.srl.old create mode 100644 plat/diameter/doc/single_host/CAGenerate/fdTestExt create mode 100644 plat/diameter/doc/single_host/CAGenerate/freeDiameter-1.conf create mode 100644 plat/diameter/doc/single_host/CAGenerate/localhost.crt create mode 100644 plat/diameter/doc/single_host/CAGenerate/localhost.csr create mode 100644 plat/diameter/doc/single_host/CAGenerate/ocsp.crt create mode 100644 plat/diameter/doc/single_host/CAGenerate/ocsp.csr create mode 100644 plat/diameter/doc/single_host/CAGenerate/ssl_make_certs.sh create mode 100644 plat/diameter/doc/single_host/demoCA/index.txt.attr create mode 100644 plat/diameter/doc/single_host/demoCA/index.txt.attr.old create mode 100644 plat/diameter/doc/single_host/demoCA/index.txt.old create mode 100644 plat/diameter/doc/single_host/demoCA/serial create mode 100644 plat/diameter/doc/single_host/demoCA/serial.old create mode 100644 plat/diameter/doc/single_host/fdTestExt create mode 100644 plat/diameter/doc/single_host/freeDiameter-1.conf create mode 100644 plat/diameter/doc/single_host/freeDiameter-2.conf create mode 100644 plat/diameter/doc/single_host/make_certs.sh create mode 100644 plat/diameter/doc/single_host/test_app1.conf create mode 100644 plat/diameter/doc/single_host/test_app2.conf create mode 100644 plat/diameter/doc/test_app.conf.sample create mode 100644 plat/diameter/doc/test_netemul.conf.sample create mode 100644 plat/diameter/doc/test_sip.conf.sample create mode 100644 plat/diameter/extensions/sh_app/dict_dcca.c create mode 100644 plat/diameter/extensions/sh_app/dict_dcca_3gpp.c create mode 100644 plat/diameter/extensions/sh_app/gx_app.c create mode 100644 plat/diameter/extensions/sh_app/sh_app.c create mode 100644 plat/diameter/extensions/sh_app/sh_app.h create mode 100644 plat/diameter/extensions/sh_app/sh_bench.c create mode 100644 plat/diameter/extensions/sh_app/sh_cli.c create mode 100644 plat/diameter/extensions/sh_app/sh_conf.c create mode 100644 plat/diameter/extensions/sh_app/sh_conf.h create mode 100644 plat/diameter/extensions/sh_app/sh_dict.c create mode 100644 plat/diameter/extensions/sh_app/sh_serv.c create mode 100644 plat/diameter/extensions/sh_app/ta_conf.l create mode 100644 plat/diameter/extensions/sh_app/ta_conf.y create mode 100644 plat/diameter/freeDiameter-1.conf create mode 100644 plat/diameter/freeDiameter-2.conf create mode 100644 plat/diameter/freeDiameterd/freeDiameter-host.h create mode 100644 plat/diameter/freeDiameterd/main.c create mode 100644 plat/diameter/include/freeDiameter/extension.h create mode 100644 plat/diameter/include/freeDiameter/freeDiameter-host.h.in create mode 100644 plat/diameter/include/freeDiameter/libfdcore.h create mode 100644 plat/diameter/include/freeDiameter/libfdproto.h create mode 100644 plat/diameter/include/freeDiameter/version.h.in create mode 100644 plat/diameter/include/gy_message.h create mode 100644 plat/diameter/libfdcore/apps.c create mode 100644 plat/diameter/libfdcore/cnxctx.c create mode 100644 plat/diameter/libfdcore/cnxctx.h create mode 100644 plat/diameter/libfdcore/config.c create mode 100644 plat/diameter/libfdcore/core.c create mode 100644 plat/diameter/libfdcore/dict_base_proto.c create mode 100644 plat/diameter/libfdcore/endpoints.c create mode 100644 plat/diameter/libfdcore/events.c create mode 100644 plat/diameter/libfdcore/extensions.c create mode 100644 plat/diameter/libfdcore/fdcore-internal.h create mode 100644 plat/diameter/libfdcore/fdd.l create mode 100644 plat/diameter/libfdcore/fdd.y create mode 100644 plat/diameter/libfdcore/fifo_stats.c create mode 100644 plat/diameter/libfdcore/freeDiameter-host.h create mode 100644 plat/diameter/libfdcore/hooks.c create mode 100644 plat/diameter/libfdcore/messages.c create mode 100644 plat/diameter/libfdcore/p_ce.c create mode 100644 plat/diameter/libfdcore/p_cnx.c create mode 100644 plat/diameter/libfdcore/p_dp.c create mode 100644 plat/diameter/libfdcore/p_dw.c create mode 100644 plat/diameter/libfdcore/p_expiry.c create mode 100644 plat/diameter/libfdcore/p_out.c create mode 100644 plat/diameter/libfdcore/p_psm.c create mode 100644 plat/diameter/libfdcore/p_sr.c create mode 100644 plat/diameter/libfdcore/peers.c create mode 100644 plat/diameter/libfdcore/queues.c create mode 100644 plat/diameter/libfdcore/routing_dispatch.c create mode 100644 plat/diameter/libfdcore/sctp.c create mode 100644 plat/diameter/libfdcore/sctp3436.c create mode 100644 plat/diameter/libfdcore/server.c create mode 100644 plat/diameter/libfdcore/tcp.c create mode 100644 plat/diameter/libfdcore/version.c create mode 100644 plat/diameter/libfdcore/version.h create mode 100644 plat/diameter/libfdproto/dictionary.c create mode 100644 plat/diameter/libfdproto/dictionary_functions.c create mode 100644 plat/diameter/libfdproto/dispatch.c create mode 100644 plat/diameter/libfdproto/fdproto-internal.h create mode 100644 plat/diameter/libfdproto/fifo.c create mode 100644 plat/diameter/libfdproto/init.c create mode 100644 plat/diameter/libfdproto/lists.c create mode 100644 plat/diameter/libfdproto/log.c create mode 100644 plat/diameter/libfdproto/messages.c create mode 100644 plat/diameter/libfdproto/ostr.c create mode 100644 plat/diameter/libfdproto/portability.c create mode 100644 plat/diameter/libfdproto/rt_data.c create mode 100644 plat/diameter/libfdproto/sessions.c create mode 100644 plat/diameter/libfdproto/utils.c create mode 100644 plat/diameter/libfdproto/version.c create mode 100644 plat/diameter/makefile create mode 100644 plat/diameter/makefile.new create mode 100644 plat/iptrans/Makefile create mode 100644 plat/iptrans/src/comfunc.c create mode 100644 plat/iptrans/src/daemon.c create mode 100644 plat/iptrans/src/error.c create mode 100644 plat/iptrans/src/errorlog.c create mode 100644 plat/iptrans/src/include/config.h create mode 100644 plat/iptrans/src/include/dbsync.h create mode 100644 plat/iptrans/src/include/debug.h create mode 100644 plat/iptrans/src/include/errlog.h create mode 100644 plat/iptrans/src/include/function.h create mode 100644 plat/iptrans/src/include/includes.h create mode 100644 plat/iptrans/src/include/iptrans.h create mode 100644 plat/iptrans/src/include/iptrfunc.h create mode 100644 plat/iptrans/src/ipcfunc.c create mode 100644 plat/iptrans/src/ipmsgfun.c create mode 100644 plat/iptrans/src/iptrans.c create mode 100644 plat/iptrans/src/iptrans.c.bak create mode 100644 plat/iptrans/src/iptrmain.c create mode 100644 plat/iptrans/src/mcast_join.c create mode 100644 plat/iptrans/src/queuefunc.c create mode 100644 plat/iptrans/src/readmsg.c create mode 100644 plat/iptrans/src/signal.c create mode 100644 plat/iptrans/src/simu_debug.c create mode 100644 plat/m2ua/Makefile create mode 100644 plat/m2ua/src/include/m2ua.h create mode 100644 plat/m2ua/src/include/m2ua_const.h create mode 100644 plat/m2ua/src/include/m2ua_debug.h create mode 100644 plat/m2ua/src/include/m2ua_def.h create mode 100644 plat/m2ua/src/include/m2ua_ext.h create mode 100644 plat/m2ua/src/include/m2ua_fsm.h create mode 100644 plat/m2ua/src/include/m2ua_msg.h create mode 100644 plat/m2ua/src/include/m2ua_pub.h create mode 100644 plat/m2ua/src/include/m2ua_pub.h.bak create mode 100644 plat/m2ua/src/include/m2ua_struct.h create mode 100644 plat/m2ua/src/include/sctp.h create mode 100644 plat/m2ua/src/m2ua.c create mode 100644 plat/m2ua/src/m2ua_debug.c create mode 100644 plat/m2ua/src/m2ua_fsm.c create mode 100644 plat/m2ua/src/m2ua_msg.c create mode 100644 plat/m2ua/ut/testcate/MGC(IUA)_Client.txt create mode 100644 plat/m2ua/ut/testcate/MGC(IUA)_Server.txt create mode 100644 plat/m2ua/ut/testcate/MGC(M2UA)_Client.txt create mode 100644 plat/m2ua/ut/testcate/MGC(M2UA)_Server.txt create mode 100644 plat/m2ua/ut/testcate/SG(IUA)_Client.txt create mode 100644 plat/m2ua/ut/testcate/SG(IUA)_Server.txt create mode 100644 plat/m2ua/ut/testcate/SG(M2UA)_Client.txt create mode 100644 plat/m2ua/ut/testcate/SG(M2UA)_Server.txt create mode 100644 plat/m2ua/ut/testcate/headfile.txt create mode 100644 plat/m2ua/ut/xua_test/Makefile create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/all-wcprops create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/entries create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/AucSysPara.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/EirSysPara.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/HlrSysPara.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_acn.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_operation.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/cc_table.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/conv_prefix.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/help_page.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/iptrans.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_acn.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_operation.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/menu_page.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/mnpf.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/msc_conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/mtp3.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsConf.txt.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsCrdConf.txt.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/profile.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_omt.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_sts.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_csta.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_sys.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/system.ini.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/vlr.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2exit.txt.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/AucSysPara.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/EirSysPara.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/HlrSysPara.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_acn.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_operation.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/cc_table.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/conv_prefix.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/help_page.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/hlr_parambit.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/iptrans.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/map_acn.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/map_operation.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/menu_page.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/mnpf.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/msc_conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/mtp3.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/ppsConf.txt.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/ppsCrdConf.txt.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/profile.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_omt.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_sts.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_csta.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_parambit.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_sys.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/system.ini.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/vlr.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2_sys.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2exit.txt.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/.svn/text-base/xap_sysparam.conf.svn-base create mode 100644 plat/m2ua/ut/xua_test/conf/AucSysPara create mode 100644 plat/m2ua/ut/xua_test/conf/EirSysPara create mode 100644 plat/m2ua/ut/xua_test/conf/HlrSysPara create mode 100644 plat/m2ua/ut/xua_test/conf/cap_acn.conf create mode 100644 plat/m2ua/ut/xua_test/conf/cap_operation.conf create mode 100644 plat/m2ua/ut/xua_test/conf/cc_table.conf create mode 100644 plat/m2ua/ut/xua_test/conf/conv_prefix.conf create mode 100644 plat/m2ua/ut/xua_test/conf/help_page create mode 100644 plat/m2ua/ut/xua_test/conf/hlr_parambit.conf create mode 100644 plat/m2ua/ut/xua_test/conf/iptrans.conf create mode 100644 plat/m2ua/ut/xua_test/conf/map_acn.conf create mode 100644 plat/m2ua/ut/xua_test/conf/map_operation.conf create mode 100644 plat/m2ua/ut/xua_test/conf/menu_page create mode 100644 plat/m2ua/ut/xua_test/conf/mnpf.conf create mode 100644 plat/m2ua/ut/xua_test/conf/msc_conf create mode 100644 plat/m2ua/ut/xua_test/conf/mtp3.conf create mode 100644 plat/m2ua/ut/xua_test/conf/ppsConf.txt create mode 100644 plat/m2ua/ut/xua_test/conf/ppsCrdConf.txt create mode 100644 plat/m2ua/ut/xua_test/conf/profile create mode 100644 plat/m2ua/ut/xua_test/conf/sccp.conf create mode 100644 plat/m2ua/ut/xua_test/conf/sccp_omt.conf create mode 100644 plat/m2ua/ut/xua_test/conf/sccp_sts.conf create mode 100644 plat/m2ua/ut/xua_test/conf/smsc_csta.conf create mode 100644 plat/m2ua/ut/xua_test/conf/smsc_parambit.conf create mode 100644 plat/m2ua/ut/xua_test/conf/smsc_sys.conf create mode 100644 plat/m2ua/ut/xua_test/conf/system.ini create mode 100644 plat/m2ua/ut/xua_test/conf/vlr.conf create mode 100644 plat/m2ua/ut/xua_test/conf/wxc2_sys.conf create mode 100644 plat/m2ua/ut/xua_test/conf/wxc2exit.txt create mode 100644 plat/m2ua/ut/xua_test/conf/xap_sysparam.conf create mode 100644 plat/m2ua/ut/xua_test/xuatest.c create mode 100644 plat/mtp3/Makefile create mode 100644 plat/mtp3/src/include/mtp3.h create mode 100644 plat/mtp3/src/include/mtp3lite.h create mode 100644 plat/mtp3/src/include/mtp3lite_pub.h create mode 100644 plat/mtp3/src/include/mtpconst.h create mode 100644 plat/mtp3/src/include/mtpdef.h create mode 100644 plat/mtp3/src/include/mtpext.h create mode 100644 plat/mtp3/src/include/mtpfunc.h create mode 100644 plat/mtp3/src/include/mtpstm.h create mode 100644 plat/mtp3/src/mtp3lite.c create mode 100644 plat/mtp3/src/mtpinit.c create mode 100644 plat/mtp3/src/mtpm.c create mode 100644 plat/mtp3/src/mtpmib.c create mode 100644 plat/mtp3/src/mtpslm.c create mode 100644 plat/mtp3/src/mtpsmh.c create mode 100644 plat/mtp3/src/mtpsrm.c create mode 100644 plat/mtp3/src/mtpstm.c create mode 100644 plat/public/Makefile create mode 100644 plat/public/src/asn1.c create mode 100644 plat/public/src/asn1per.c create mode 100644 plat/public/src/bisearch.c create mode 100644 plat/public/src/cdr.c create mode 100644 plat/public/src/crypt.c create mode 100644 plat/public/src/include/asn1.h create mode 100644 plat/public/src/include/asn1per.h create mode 100644 plat/public/src/include/bisearch.h create mode 100644 plat/public/src/include/cdr.h create mode 100644 plat/public/src/include/crypt.h create mode 100644 plat/public/src/include/includes.h create mode 100644 plat/public/src/include/includes.h.bak create mode 100644 plat/public/src/include/license_id.h create mode 100644 plat/public/src/include/memwatch.h create mode 100644 plat/public/src/include/omc_public.h create mode 100644 plat/public/src/include/pub_base.h create mode 100644 plat/public/src/include/pub_debug.h create mode 100644 plat/public/src/include/pub_file.h create mode 100644 plat/public/src/include/pub_fmt.h create mode 100644 plat/public/src/include/pub_include.h create mode 100644 plat/public/src/include/pub_inet.h create mode 100644 plat/public/src/include/pub_list.h create mode 100644 plat/public/src/include/pub_log.h create mode 100644 plat/public/src/include/pub_malloc.h create mode 100644 plat/public/src/include/pub_netcap.h create mode 100644 plat/public/src/include/pub_sdp.h create mode 100644 plat/public/src/include/pub_str.h create mode 100644 plat/public/src/include/pub_sys.h create mode 100644 plat/public/src/include/pub_time.h create mode 100644 plat/public/src/include/pub_timer.h create mode 100644 plat/public/src/include/pub_wnet.h create mode 100644 plat/public/src/include/public.h create mode 100644 plat/public/src/include/svrstat.h create mode 100644 plat/public/src/memwatch.c create mode 100644 plat/public/src/pub_conf.c create mode 100644 plat/public/src/pub_debug.c create mode 100644 plat/public/src/pub_file.c create mode 100644 plat/public/src/pub_fmt.c create mode 100644 plat/public/src/pub_inet.c create mode 100644 plat/public/src/pub_license.c create mode 100644 plat/public/src/pub_log.c create mode 100644 plat/public/src/pub_malloc.c create mode 100644 plat/public/src/pub_netcap.c create mode 100644 plat/public/src/pub_sdp.c create mode 100644 plat/public/src/pub_str.c create mode 100644 plat/public/src/pub_sys.c create mode 100644 plat/public/src/pub_time.c create mode 100644 plat/public/src/pub_timer.c create mode 100644 plat/public/src/pub_wnet.c create mode 100644 plat/public/src/shm.c create mode 100644 plat/public/src/uwav/number.c create mode 100644 plat/public/src/uwav/number.h create mode 100644 plat/public/src/uwav/numgrp.c create mode 100644 plat/public/src/uwav/numgrp.h create mode 100644 plat/public/ut/asn.1/asntest.c create mode 100644 plat/public/ut/bisearch/bisearch_test.c create mode 100644 plat/public/ut/debug_api/debug create mode 100644 plat/public/ut/debug_api/wxc_debug_test.c create mode 100644 plat/public/ut/function.c create mode 100644 plat/public/ut/inet/pub_inet_test.c create mode 100644 plat/public/ut/main/Makefile create mode 100644 plat/public/ut/main/bin/.svn/all-wcprops create mode 100644 plat/public/ut/main/bin/.svn/entries create mode 100644 plat/public/ut/main/obj/.svn/all-wcprops create mode 100644 plat/public/ut/main/obj/.svn/entries create mode 100644 plat/public/ut/main/src/.svn/all-wcprops create mode 100644 plat/public/ut/main/src/.svn/entries create mode 100644 plat/public/ut/main/src/.svn/prop-base/main.c.svn-base create mode 100644 plat/public/ut/main/src/.svn/text-base/main.c.svn-base create mode 100644 plat/public/ut/main/src/main.c create mode 100644 plat/public/ut/public_test/public_test.c create mode 100644 plat/public/ut/timer/Makefile create mode 100644 plat/public/ut/timer/bin/.svn/all-wcprops create mode 100644 plat/public/ut/timer/bin/.svn/entries create mode 100644 plat/public/ut/timer/ut/.svn/all-wcprops create mode 100644 plat/public/ut/timer/ut/.svn/entries create mode 100644 plat/public/ut/timer/wxc_tmtest.c create mode 100644 plat/radius/Makefile create mode 100644 plat/radius/src/include/radius.h create mode 100644 plat/radius/src/include/radius_const.h create mode 100644 plat/radius/src/include/radius_debug.h create mode 100644 plat/radius/src/include/radius_def.h create mode 100644 plat/radius/src/include/radius_ext.h create mode 100644 plat/radius/src/include/radius_fsm.h create mode 100644 plat/radius/src/include/radius_function.h create mode 100644 plat/radius/src/include/radius_if.h create mode 100644 plat/radius/src/include/radius_inc.h create mode 100644 plat/radius/src/include/radius_md5.h create mode 100644 plat/radius/src/include/radius_pub.h create mode 100644 plat/radius/src/include/radius_struct.h create mode 100644 plat/radius/src/include/radius_transport.h create mode 100644 plat/radius/src/radius.c create mode 100644 plat/radius/src/radius_debug.c create mode 100644 plat/radius/src/radius_fsm.c create mode 100644 plat/radius/src/radius_function.c create mode 100644 plat/radius/src/radius_if.c create mode 100644 plat/radius/src/radius_md5.c create mode 100644 plat/radius/src/radius_transport.c create mode 100644 plat/radius/ut/Makefile create mode 100644 plat/radius/ut/radius_test_main.c create mode 100644 plat/radius/ut/radius_unit_test.c create mode 100644 plat/radius/ut/radius_unit_test.h create mode 100644 plat/sccp/Makefile create mode 100644 plat/sccp/src/include/sccp.h create mode 100644 plat/sccp/src/include/sccp_func.h create mode 100644 plat/sccp/src/include/sccp_pub.h create mode 100644 plat/sccp/src/include/sccpconst.h create mode 100644 plat/sccp/src/include/sccpconst.h.bak create mode 100644 plat/sccp/src/include/scoc.h create mode 100644 plat/sccp/src/include/scoc_if.h create mode 100644 plat/sccp/src/sccp.c create mode 100644 plat/sccp/src/sccp_debug.c create mode 100644 plat/sccp/src/sccp_func.c create mode 100644 plat/sccp/src/sccp_gtt.c create mode 100644 plat/sccp/src/sccp_log.c create mode 100644 plat/sccp/src/sccp_mib.c create mode 100644 plat/sccp/src/sccp_msg.c create mode 100644 plat/sccp/src/sccp_param.c create mode 100644 plat/sccp/src/sclc.c create mode 100644 plat/sccp/src/scmg.c create mode 100644 plat/sccp/src/scoc.c create mode 100644 plat/sccp/src/scoc_fsm.c create mode 100644 plat/sccp/src/scoc_func.c create mode 100644 plat/sccp/src/scoc_if.c create mode 100644 plat/sccp/src/scoc_pool.c create mode 100644 plat/sccp/src/scoc_pri.c create mode 100644 plat/sccp/src/scrc.c create mode 100644 plat/sccp/ut/fsmtest/Makefile create mode 100644 plat/sccp/ut/fsmtest/bin/.svn/all-wcprops create mode 100644 plat/sccp/ut/fsmtest/bin/.svn/entries create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/all-wcprops create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/entries create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/HlrSysPara.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_acn.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_operation.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cc_table.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/conv_prefix.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hae_sys.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/help_page.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hlr_parambit.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/iptrans.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_acn.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_operation.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/menu_page.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/mtp3.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/ppsConf.txt.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/profile.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp_test.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_csta.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_parambit.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_sys.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/system.ini.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2_sys.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2exit.txt.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/xap_sysparam.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/HlrSysPara.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/cap_acn.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/cap_operation.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/cc_table.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/conv_prefix.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/hae_sys.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/help_page.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/hlr_parambit.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/iptrans.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_acn.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_operation.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/menu_page.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/mtp3.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/ppsConf.txt.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/profile.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp_test.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_csta.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_parambit.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_sys.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/system.ini.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/wxc2_sys.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/wxc2exit.txt.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/xap_sysparam.conf.svn-base create mode 100644 plat/sccp/ut/fsmtest/bin/conf/HlrSysPara create mode 100644 plat/sccp/ut/fsmtest/bin/conf/cap_acn.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/cap_operation.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/cc_table.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/conv_prefix.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/hae_sys.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/help_page create mode 100644 plat/sccp/ut/fsmtest/bin/conf/hlr_parambit.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/iptrans.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/map_acn.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/map_operation.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/menu_page create mode 100644 plat/sccp/ut/fsmtest/bin/conf/mtp3.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/ppsConf.txt create mode 100644 plat/sccp/ut/fsmtest/bin/conf/profile create mode 100644 plat/sccp/ut/fsmtest/bin/conf/sccp.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/sccp_test.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/smsc_csta.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/smsc_parambit.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/smsc_sys.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/system.ini create mode 100644 plat/sccp/ut/fsmtest/bin/conf/wxc2_sys.conf create mode 100644 plat/sccp/ut/fsmtest/bin/conf/wxc2exit.txt create mode 100644 plat/sccp/ut/fsmtest/bin/conf/xap_sysparam.conf create mode 100644 plat/sccp/ut/fsmtest/obj/.svn/all-wcprops create mode 100644 plat/sccp/ut/fsmtest/obj/.svn/entries create mode 100644 plat/sccp/ut/fsmtest/obj/.svn/prop-base/sccp_test.gcno.svn-base create mode 100644 plat/sccp/ut/fsmtest/obj/.svn/prop-base/scoc_test.gcno.svn-base create mode 100644 plat/sccp/ut/fsmtest/obj/.svn/text-base/sccp_test.gcno.svn-base create mode 100644 plat/sccp/ut/fsmtest/obj/.svn/text-base/scoc_test.gcno.svn-base create mode 100644 plat/sccp/ut/fsmtest/obj/sccp_test.gcno create mode 100644 plat/sccp/ut/fsmtest/obj/scoc_test.gcno create mode 100644 plat/sccp/ut/fsmtest/sccp_test.c create mode 100644 plat/sccp/ut/fsmtest/scoc_test.c create mode 100644 plat/scf/Makefile create mode 100644 plat/scf/src/include/scfdef.h create mode 100644 plat/scf/src/include/scfmsg.h create mode 100644 plat/scf/src/include/scfpub.h create mode 100644 plat/scf/src/scfmsg.c create mode 100644 plat/scf/src/scsm.c create mode 100644 plat/smpp/Makefile create mode 100644 plat/smpp/src/include/smpp.h create mode 100644 plat/smpp/src/include/smpp_const.h create mode 100644 plat/smpp/src/include/smpp_def.h create mode 100644 plat/smpp/src/include/smpp_ext.h create mode 100644 plat/smpp/src/include/smpp_msg.h create mode 100644 plat/smpp/src/include/smpp_public.h create mode 100644 plat/smpp/src/smpp_debug.c create mode 100644 plat/smpp/src/smpp_fsm.c create mode 100644 plat/smpp/src/smpp_func.c create mode 100644 plat/smpp/src/smpp_mib.c create mode 100644 plat/smpp/src/smpp_msg.c create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/all-wcprops create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/entries create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/IWV-SMI.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/Special_App-SMI.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/System_IP_List.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-AUC-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-HLR-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSC-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSS-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-PPS-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMI.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMSC-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SS7-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_page.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_tree.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_list_file.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_write_tree.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/IWV-SMI.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/Special_App-SMI.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/System_IP_List.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-AUC-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-HLR-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSC-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSS-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-PPS-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMI.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMSC-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SS7-MIB.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_page.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_tree.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_list_file.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_write_tree.txt.svn-base create mode 100644 plat/smpp/ut/conf/MIB_files/IWV-SMI.txt create mode 100644 plat/smpp/ut/conf/MIB_files/Special_App-SMI.txt create mode 100644 plat/smpp/ut/conf/MIB_files/System_IP_List.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-AUC-MIB.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-HLR-MIB.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-MSC-MIB.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-MSS-MIB.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-PPS-MIB.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-SMI.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-SMSC-MIB.txt create mode 100644 plat/smpp/ut/conf/MIB_files/WXC2-SS7-MIB.txt create mode 100644 plat/smpp/ut/conf/MIB_files/menu_page create mode 100644 plat/smpp/ut/conf/MIB_files/menu_tree.txt create mode 100644 plat/smpp/ut/conf/MIB_files/mib_list_file.txt create mode 100644 plat/smpp/ut/conf/MIB_files/mib_write_tree.txt create mode 100644 plat/smpp/ut/conf/guess_number_test.conf create mode 100644 plat/smpp/ut/conf/help_page create mode 100644 plat/smpp/ut/conf/iptrans.conf create mode 100644 plat/smpp/ut/conf/menu_page create mode 100644 plat/smpp/ut/conf/mtp3.conf create mode 100644 plat/smpp/ut/conf/sccp.conf create mode 100644 plat/smpp/ut/conf/smpp.conf create mode 100644 plat/smpp/ut/smpp_test/smpp_test.c create mode 100644 plat/smpp/ut/smpp_ussd_test/guess_number.c create mode 100644 plat/smpp/ut/smpp_ussd_test/pppchat.c create mode 100644 plat/snmp/Makefile create mode 100644 plat/snmp/src/heartbeat.c create mode 100644 plat/snmp/src/include/heartbeat.h create mode 100644 plat/snmp/src/include/macro.h create mode 100644 plat/snmp/src/include/snmp.h create mode 100644 plat/snmp/src/include/snmpv3AuthCry.h create mode 100644 plat/snmp/src/include/sysctrl.h create mode 100644 plat/snmp/src/include/table.h create mode 100644 plat/snmp/src/md5.c create mode 100644 plat/snmp/src/md5.h create mode 100644 plat/snmp/src/mib_parser/snmp_mib.c create mode 100644 plat/snmp/src/mib_parser/snmp_mib.h create mode 100644 plat/snmp/src/mib_parser/snmp_mib_api.c create mode 100644 plat/snmp/src/mib_parser/snmp_mib_api.h create mode 100644 plat/snmp/src/snmp.c create mode 100644 plat/snmp/src/snmpdebug.c create mode 100644 plat/snmp/src/snmpmib.c create mode 100644 plat/snmp/src/snmptable.c create mode 100644 plat/snmp/src/snmptest.c create mode 100644 plat/snmp/src/snmpv3AuthCry.c create mode 100644 plat/snmp/src/sysctrl.c create mode 100644 plat/tcap/Makefile create mode 100644 plat/tcap/src/idmanage.c create mode 100644 plat/tcap/src/include/idmanage.h create mode 100644 plat/tcap/src/include/itcap.h create mode 100644 plat/tcap/src/include/tcap_head.h create mode 100644 plat/tcap/src/include/tcap_m.h create mode 100644 plat/tcap/src/include/tcap_proc.h create mode 100644 plat/tcap/src/include/tcap_public.h create mode 100644 plat/tcap/src/include/tcap_struct.h create mode 100644 plat/tcap/src/itcap.c create mode 100644 plat/tcap/src/tcap_coding.c create mode 100644 plat/tcap/src/tcap_fsm.c create mode 100644 plat/tcap/src/tcap_m.c create mode 100644 plat/tcp/Makefile create mode 100644 plat/tcp/src/include/tcp_debug.h create mode 100644 plat/tcp/src/include/tcp_if.h create mode 100644 plat/tcp/src/include/tcp_inc.h create mode 100644 plat/tcp/src/include/tcp_port.h create mode 100644 plat/tcp/src/tcp_debug.c create mode 100644 plat/tcp/src/tcp_if.c create mode 100644 plat/tcp/src/tcp_port.c create mode 100644 plat/xapp/Makefile create mode 100644 plat/xapp/conf/cap_acn.conf create mode 100644 plat/xapp/conf/cap_operation.conf create mode 100644 plat/xapp/conf/map_acn.conf create mode 100644 plat/xapp/conf/map_operation.conf create mode 100644 plat/xapp/src/capp/cap_coding.h create mode 100644 plat/xapp/src/capp/cap_head.h create mode 100644 plat/xapp/src/capp/cap_msg.c create mode 100644 plat/xapp/src/capp/cap_msg.h create mode 100644 plat/xapp/src/capp/cap_msgtype.c create mode 100644 plat/xapp/src/capp/cap_public.c create mode 100644 plat/xapp/src/capp/cap_public.h create mode 100644 plat/xapp/src/capp/icap.h create mode 100644 plat/xapp/src/conv_prefix.c create mode 100644 plat/xapp/src/conv_prefix.h create mode 100644 plat/xapp/src/ixap.h create mode 100644 plat/xapp/src/mapp/Map_opr.c create mode 100644 plat/xapp/src/mapp/imap.h create mode 100644 plat/xapp/src/mapp/is41_code.h create mode 100644 plat/xapp/src/mapp/is41_code_auc.c create mode 100644 plat/xapp/src/mapp/is41_code_ms.c create mode 100644 plat/xapp/src/mapp/is41_code_sms.c create mode 100644 plat/xapp/src/mapp/is41_code_win.c create mode 100644 plat/xapp/src/mapp/is41_coding.c create mode 100644 plat/xapp/src/mapp/is41_debug.c create mode 100644 plat/xapp/src/mapp/is41_init.c create mode 100644 plat/xapp/src/mapp/map_LCSCode.c create mode 100644 plat/xapp/src/mapp/map_LCSCode.h create mode 100644 plat/xapp/src/mapp/map_acn.h create mode 100644 plat/xapp/src/mapp/map_code.h create mode 100644 plat/xapp/src/mapp/map_code_auc.c create mode 100644 plat/xapp/src/mapp/map_code_ch.c create mode 100644 plat/xapp/src/mapp/map_code_dlgpdu.c create mode 100644 plat/xapp/src/mapp/map_code_ms.c create mode 100644 plat/xapp/src/mapp/map_code_om.c create mode 100644 plat/xapp/src/mapp/map_code_sms.c create mode 100644 plat/xapp/src/mapp/map_code_ss.c create mode 100644 plat/xapp/src/mapp/map_coding.c create mode 100644 plat/xapp/src/mapp/map_coding.h create mode 100644 plat/xapp/src/mapp/map_const.h create mode 100644 plat/xapp/src/mapp/map_dlgpdu.h create mode 100644 plat/xapp/src/mapp/map_includes.h create mode 100644 plat/xapp/src/mapp/map_opr_func.h create mode 100644 plat/xapp/src/mapp/map_public.c create mode 100644 plat/xapp/src/mapp/map_public.h create mode 100644 plat/xapp/src/mapp/map_struct.h create mode 100644 plat/xapp/src/mapp/win_struct.h create mode 100644 plat/xapp/src/roaming_rule.c create mode 100644 plat/xapp/src/roaming_rule.h create mode 100644 plat/xapp/src/xap_cdmacdr.c create mode 100644 plat/xapp/src/xap_cdmacdr.h create mode 100644 plat/xapp/src/xap_interface.c create mode 100644 plat/xapp/src/xap_interfunc.h create mode 100644 plat/xapp/src/xap_monitor.c create mode 100644 plat/xapp/src/xap_monitor.h create mode 100644 plat/xapp/src/xap_provider.c create mode 100644 plat/xapp/src/xap_provider.h create mode 100644 plat/xapp/ut/xapp_test/Makefile create mode 100644 plat/xapp/ut/xapp_test/conf/.sccp.conf.swo create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/all-wcprops create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/entries create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/.sccp.conf.swo.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/HlrSysPara.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_acn.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_operation.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/cc_table.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/conf.rar.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/conv_prefix.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/hae_sys.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/help_page.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/iptrans.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_acn.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_operation.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/menu_page.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/mtp3.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/ppsConf.txt.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/profile.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/sccp.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_csta.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_sys.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.100k.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.30K.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.inimscvlrhlr.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2exit.txt.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/prop-base/xapp_test.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/.sccp.conf.swo.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/HlrSysPara.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/cap_acn.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/cap_operation.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/cc_table.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/conf.rar.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/conv_prefix.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/hae_sys.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/help_page.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/hlr_parambit.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/iptrans.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/map_acn.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/map_operation.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/menu_page.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/mtp3.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/ppsConf.txt.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/profile.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/sccp.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_csta.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_parambit.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_sys.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.100k.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.30K.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/system.inimscvlrhlr.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2_sys.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2exit.txt.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/xap_sysparam.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/.svn/text-base/xapp_test.conf.svn-base create mode 100644 plat/xapp/ut/xapp_test/conf/HlrSysPara create mode 100644 plat/xapp/ut/xapp_test/conf/cap_acn.conf create mode 100644 plat/xapp/ut/xapp_test/conf/cap_operation.conf create mode 100644 plat/xapp/ut/xapp_test/conf/cc_table.conf create mode 100644 plat/xapp/ut/xapp_test/conf/conf.rar create mode 100644 plat/xapp/ut/xapp_test/conf/conv_prefix.conf create mode 100644 plat/xapp/ut/xapp_test/conf/hae_sys.conf create mode 100644 plat/xapp/ut/xapp_test/conf/help_page create mode 100644 plat/xapp/ut/xapp_test/conf/hlr_parambit.conf create mode 100644 plat/xapp/ut/xapp_test/conf/iptrans.conf create mode 100644 plat/xapp/ut/xapp_test/conf/map_acn.conf create mode 100644 plat/xapp/ut/xapp_test/conf/map_operation.conf create mode 100644 plat/xapp/ut/xapp_test/conf/menu_page create mode 100644 plat/xapp/ut/xapp_test/conf/mtp3.conf create mode 100644 plat/xapp/ut/xapp_test/conf/ppsConf.txt create mode 100644 plat/xapp/ut/xapp_test/conf/profile create mode 100644 plat/xapp/ut/xapp_test/conf/sccp.conf create mode 100644 plat/xapp/ut/xapp_test/conf/smsc_csta.conf create mode 100644 plat/xapp/ut/xapp_test/conf/smsc_parambit.conf create mode 100644 plat/xapp/ut/xapp_test/conf/smsc_sys.conf create mode 100644 plat/xapp/ut/xapp_test/conf/system.ini create mode 100644 plat/xapp/ut/xapp_test/conf/system.ini.100k create mode 100644 plat/xapp/ut/xapp_test/conf/system.ini.30K create mode 100644 plat/xapp/ut/xapp_test/conf/system.inimscvlrhlr create mode 100644 plat/xapp/ut/xapp_test/conf/wxc2_sys.conf create mode 100644 plat/xapp/ut/xapp_test/conf/wxc2exit.txt create mode 100644 plat/xapp/ut/xapp_test/conf/xap_sysparam.conf create mode 100644 plat/xapp/ut/xapp_test/conf/xapp_test.conf create mode 100644 plat/xapp/ut/xapp_test/xapp_coding_test.c create mode 100644 plat/xapp/ut/xapp_test/xapp_coding_test.h create mode 100644 plat/xapp/ut/xapp_test/xapp_main.c create mode 100644 plat/xapp/ut/xapp_test/xapp_main.h create mode 100644 plat/xapp/ut/xapp_test/xapp_op_test.c create mode 100644 plat/xapp/ut/xapp_test/xapp_op_test.h diff --git a/mss/log/pps_trace.log b/mss/log/pps_trace.log new file mode 100644 index 0000000..d47fb9c --- /dev/null +++ b/mss/log/pps_trace.log @@ -0,0 +1,33 @@ +Last function : 02 : capMessageProc(2) +-> 00 : AccountExpiredDateCheck +-> 01 : SyncMessageProc +-> 02 : capMessageProc +-> 03 : SyncMessageProc +-> 04 : capMessageProc +-> 05 : cstaInstanceCheck +-> 06 : TariffPlanProc +-> 07 : CheckLoadFile +-> 08 : ppsDebugRt +-> 09 : PeriodicChargeProc +-> 10 : smppMonitor +-> 11 : reportCreatedDaily +-> 12 : AccountExpiredDateCheck +-> 13 : SyncMessageProc +-> 14 : capMessageProc +-> 15 : cstaInstanceCheck +-> 16 : TariffPlanProc +-> 17 : CheckLoadFile +-> 18 : ppsDebugRt +-> 19 : PeriodicChargeProc +-> 20 : smppMonitor +-> 21 : reportCreatedDaily +-> 22 : AccountExpiredDateCheck +-> 23 : SyncMessageProc +-> 24 : capMessageProc +-> 25 : cstaInstanceCheck +-> 26 : TariffPlanProc +-> 27 : CheckLoadFile +-> 28 : ppsDebugRt +-> 29 : PeriodicChargeProc +-> 30 : smppMonitor +-> 31 : reportCreatedDaily diff --git a/mss/log/snmp_log.txt b/mss/log/snmp_log.txt new file mode 100644 index 0000000..96a8f3c --- /dev/null +++ b/mss/log/snmp_log.txt @@ -0,0 +1,36 @@ +-------- SNMP log info ------- +---------------------------------- +---> Lastest log No. = 31 <----- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +------------- End -------------- diff --git a/mss/log/wxc2_log.txt b/mss/log/wxc2_log.txt new file mode 100644 index 0000000..a117ad0 --- /dev/null +++ b/mss/log/wxc2_log.txt @@ -0,0 +1,3 @@ +time: 1474702518 +app_state: 0 +sub_state: 50 diff --git a/mss/log/wxc2_startup.log b/mss/log/wxc2_startup.log new file mode 100644 index 0000000..21e7b67 --- /dev/null +++ b/mss/log/wxc2_startup.log @@ -0,0 +1,249 @@ +wxc2main startup --->Tue Jan 15 14:32:54 2013 + wxc2main startup --->Fri Feb 15 12:03:32 2013 + wxc2main startup --->Fri Feb 15 13:02:46 2013 + wxc2main startup --->Sat Feb 16 09:45:14 2013 + wxc2main startup --->Sat Feb 16 14:47:13 2013 + wxc2main startup --->Sat Feb 16 15:05:02 2013 + wxc2main startup --->Sat Feb 16 15:20:40 2013 + wxc2main startup --->Sat Feb 16 15:45:26 2013 + wxc2main startup --->Sat Feb 16 16:19:19 2013 + wxc2main startup --->Sat Feb 16 17:18:58 2013 + wxc2main startup --->Sun Feb 17 22:21:51 2013 + wxc2main startup --->Sun Feb 17 22:36:13 2013 + wxc2main startup --->Sun Feb 17 22:43:15 2013 + wxc2main startup --->Sun Feb 17 23:12:52 2013 + wxc2main startup --->Fri Jan 18 02:00:58 2013 + wxc2main startup --->Sat Jan 19 04:02:28 2013 + wxc2main startup --->Sat Jan 19 05:18:05 2013 + wxc2main startup --->Sat Jan 19 05:39:43 2013 + wxc2main startup --->Sat Jan 19 08:38:41 2013 + wxc2main startup --->Thu Jan 24 01:19:46 2013 + wxc2main startup --->Fri Jan 25 10:22:51 2013 + wxc2main startup --->Fri Jan 25 10:59:36 2013 + wxc2main startup --->Fri Jan 25 12:56:12 2013 + wxc2main startup --->Sat Jan 26 15:42:27 2013 + wxc2main startup --->Sat Jan 26 21:16:33 2013 + wxc2main startup --->Sat Jan 26 21:31:40 2013 + wxc2main startup --->Sat Jan 26 22:12:32 2013 + wxc2main startup --->Sat Jan 26 23:21:55 2013 + wxc2main startup --->Sun Jan 27 00:02:13 2013 + wxc2main startup --->Mon Jan 28 09:49:47 2013 + wxc2main startup --->Mon Jan 28 10:51:00 2013 + wxc2main startup --->Tue Jan 29 14:29:11 2013 + wxc2main startup --->Tue Jan 29 17:41:59 2013 + wxc2main startup --->Tue Jan 29 21:28:38 2013 + wxc2main startup --->Tue Jan 29 21:36:24 2013 + wxc2main startup --->Tue Jan 29 22:59:35 2013 + wxc2main startup --->Sun Feb 3 14:30:28 2013 + wxc2main startup --->Sun Feb 3 14:36:42 2013 + wxc2main startup --->Sun Feb 3 14:52:35 2013 + wxc2main startup --->Sun Feb 3 15:06:01 2013 + wxc2main startup --->Sun Feb 3 15:50:05 2013 + wxc2main startup --->Sun Feb 3 16:01:19 2013 + wxc2main startup --->Sun Feb 3 16:01:43 2013 + wxc2main startup --->Mon Feb 4 17:50:13 2013 + wxc2main startup --->Tue Feb 5 01:06:02 2013 + wxc2main startup --->Tue Feb 5 01:24:51 2013 + wxc2main startup --->Tue Feb 5 03:40:43 2013 + wxc2main startup --->Wed Feb 6 11:34:10 2013 + wxc2main startup --->Fri Feb 8 01:50:30 2013 + wxc2main startup --->Sat Feb 9 14:02:59 2013 + wxc2main startup --->Sat Feb 9 14:11:38 2013 + wxc2main startup --->Sat Feb 9 14:53:44 2013 + wxc2main startup --->Sat Feb 9 15:12:24 2013 + wxc2main startup --->Sat Feb 9 15:39:19 2013 + wxc2main startup --->Sat Feb 9 15:47:52 2013 + wxc2main startup --->Sat Feb 9 15:48:38 2013 + wxc2main startup --->Sat Feb 9 16:18:58 2013 + wxc2main startup --->Wed Feb 13 15:10:15 2013 + wxc2main startup --->Mon Mar 11 05:16:42 2013 + wxc2main startup --->Mon Mar 11 06:56:24 2013 + wxc2main startup --->Mon Mar 11 09:09:07 2013 + wxc2main startup --->Mon Mar 11 09:27:30 2013 + wxc2main startup --->Mon Mar 11 09:43:31 2013 + wxc2main startup --->Mon Mar 11 10:39:56 2013 + wxc2main startup --->Mon Mar 11 11:04:52 2013 + wxc2main startup --->Mon Mar 11 11:17:09 2013 + wxc2main startup --->Thu Mar 21 17:02:29 2013 + wxc2main startup --->Thu Mar 21 17:04:04 2013 + wxc2main startup --->Fri Mar 22 02:06:03 2013 + wxc2main startup --->Sun Mar 31 04:27:04 2013 + wxc2main startup --->Sun Mar 31 04:27:34 2013 + wxc2main startup --->Sun Mar 31 04:37:37 2013 + wxc2main startup --->Sun Mar 31 04:44:40 2013 + wxc2main startup --->Mon Apr 1 04:24:17 2013 + wxc2main startup --->Mon Apr 1 04:30:51 2013 + wxc2main startup --->Mon Apr 1 06:02:27 2013 + wxc2main startup --->Mon Apr 1 06:46:11 2013 + wxc2main startup --->Mon Apr 1 11:29:16 2013 + wxc2main startup --->Wed Apr 3 03:44:39 2013 + wxc2main startup --->Mon Apr 8 22:04:37 2013 + wxc2main startup --->Mon Apr 8 22:14:02 2013 + wxc2main startup --->Mon Mar 18 10:46:51 2013 + wxc2main startup --->Mon Apr 1 13:21:35 2013 + wxc2main startup --->Thu Apr 4 13:46:36 2013 + wxc2main startup --->Thu Apr 4 17:08:10 2013 + wxc2main startup --->Thu Apr 4 17:21:01 2013 + wxc2main startup --->Thu Apr 4 17:28:54 2013 + wxc2main startup --->Thu Apr 4 17:48:19 2013 + wxc2main startup --->Thu Apr 4 17:50:40 2013 + wxc2main startup --->Thu Apr 4 18:47:06 2013 + wxc2main startup --->Sun Apr 7 15:04:59 2013 + wxc2main startup --->Tue Apr 2 05:46:53 2013 + wxc2main startup --->Tue Apr 2 06:15:26 2013 + wxc2main startup --->Tue Apr 2 08:02:55 2013 + wxc2main startup --->Tue Apr 2 09:44:04 2013 + wxc2main startup --->Tue Apr 2 11:12:25 2013 + wxc2main startup --->Fri Apr 12 07:25:34 2013 + wxc2main startup --->Fri May 3 09:17:27 2013 + wxc2main startup --->Tue May 14 06:33:54 2013 + wxc2main startup --->Tue May 14 07:12:28 2013 + wxc2main startup --->Sat May 25 00:09:59 2013 + wxc2main startup --->Fri May 31 04:03:27 2013 + wxc2main startup --->Fri May 31 04:44:23 2013 + wxc2main startup --->Fri May 31 05:03:52 2013 + wxc2main startup --->Fri May 31 07:22:09 2013 + wxc2main startup --->Fri May 31 07:40:47 2013 + wxc2main startup --->Fri May 31 08:03:24 2013 + wxc2main startup --->Fri May 31 08:15:36 2013 + wxc2main startup --->Fri May 31 08:26:34 2013 + wxc2main startup --->Fri May 31 23:59:56 2013 + wxc2main startup --->Tue Jun 4 08:46:19 2013 + wxc2main startup --->Wed Jun 5 01:08:46 2013 + wxc2main startup --->Thu Jun 20 00:49:06 2013 + wxc2main startup --->Thu Jun 20 01:00:03 2013 + wxc2main startup --->Thu Jun 20 01:42:30 2013 + wxc2main startup --->Fri Jun 21 01:37:36 2013 + wxc2main startup --->Sat Jun 29 04:23:13 2013 + wxc2main startup --->Wed Aug 21 02:22:11 2013 + wxc2main startup --->Tue Sep 10 17:59:36 2013 + wxc2main startup --->Fri Oct 11 01:47:27 2013 + wxc2main startup --->Tue Oct 22 07:29:18 2013 + wxc2main startup --->Tue Oct 22 07:49:19 2013 + wxc2main startup --->Wed Oct 23 07:55:26 2013 + wxc2main startup --->Wed Oct 23 08:00:37 2013 + wxc2main startup --->Wed Oct 23 08:00:43 2013 + wxc2main startup --->Wed Oct 23 08:09:41 2013 + wxc2main startup --->Wed Oct 23 08:33:11 2013 + wxc2main startup --->Wed Oct 23 08:42:35 2013 + wxc2main startup --->Thu Oct 24 02:00:06 2013 + wxc2main startup --->Thu Nov 21 03:11:21 2013 + wxc2main startup --->Thu Nov 21 03:42:41 2013 + wxc2main startup --->Thu Nov 21 03:43:06 2013 + wxc2main startup --->Thu Nov 21 03:43:50 2013 + wxc2main startup --->Thu Nov 21 03:44:11 2013 + wxc2main startup --->Thu Nov 21 03:44:39 2013 + wxc2main startup --->Tue Feb 25 11:12:31 2014 + wxc2main startup --->Fri May 1 12:46:21 2015 + wxc2main startup --->Fri May 1 12:46:55 2015 + wxc2main startup --->Fri May 1 12:54:40 2015 + wxc2main startup --->Fri May 1 12:56:52 2015 + wxc2main startup --->Fri May 1 12:58:22 2015 + wxc2main startup --->Fri May 1 13:04:03 2015 + wxc2main startup --->Fri May 1 13:11:56 2015 + wxc2main startup --->Fri May 1 13:18:06 2015 + wxc2main startup --->Fri May 1 13:23:22 2015 + wxc2main startup --->Fri May 1 13:32:39 2015 + wxc2main startup --->Fri May 1 13:33:24 2015 + wxc2main startup --->Fri May 1 14:21:04 2015 + wxc2main startup --->Fri May 1 14:50:58 2015 + wxc2main startup --->Fri May 1 15:01:26 2015 + wxc2main startup --->Fri May 1 15:04:44 2015 + wxc2main startup --->Fri May 1 15:32:11 2015 + wxc2main startup --->Fri May 1 15:35:56 2015 + wxc2main startup --->Sat May 2 01:42:38 2015 + wxc2main startup --->Sat May 2 01:54:12 2015 + wxc2main startup --->Sat May 2 02:13:46 2015 + wxc2main startup --->Sat May 2 02:47:45 2015 + wxc2main startup --->Sat May 2 03:13:05 2015 + wxc2main startup --->Sat May 2 03:19:09 2015 + wxc2main startup --->Sat May 2 03:27:54 2015 + wxc2main startup --->Sat May 2 03:48:52 2015 + wxc2main startup --->Sat May 2 03:56:35 2015 + wxc2main startup --->Sat May 2 04:04:53 2015 + wxc2main startup --->Sat May 2 04:05:00 2015 + wxc2main startup --->Sat May 2 04:13:59 2015 + wxc2main startup --->Sat May 2 04:14:06 2015 + wxc2main startup --->Sat May 2 04:25:34 2015 + wxc2main startup --->Sat May 2 04:37:04 2015 + wxc2main startup --->Sat May 2 05:39:46 2015 + wxc2main startup --->Sat May 2 11:48:45 2015 + wxc2main startup --->Sat May 2 12:04:37 2015 + wxc2main startup --->Sat May 2 12:17:25 2015 + wxc2main startup --->Sat May 2 12:45:05 2015 + wxc2main startup --->Sat May 2 12:59:45 2015 + wxc2main startup --->Sat May 2 14:04:15 2015 + wxc2main startup --->Sun May 3 01:53:04 2015 + wxc2main startup --->Sun May 3 03:04:18 2015 + wxc2main startup --->Sun May 3 03:32:17 2015 + wxc2main startup --->Wed May 6 11:49:54 2015 + wxc2main startup --->Sat May 9 07:31:37 2015 + wxc2main startup --->Sun May 10 07:25:40 2015 + wxc2main startup --->Mon May 11 12:09:35 2015 + wxc2main startup --->Tue May 12 08:45:11 2015 + wxc2main startup --->Wed May 13 12:47:39 2015 + wxc2main startup --->Thu May 14 12:33:27 2015 + wxc2main startup --->Thu May 14 13:12:25 2015 + wxc2main startup --->Thu May 14 13:37:23 2015 + wxc2main startup --->Thu May 14 14:33:10 2015 + wxc2main startup --->Thu May 14 14:46:59 2015 + wxc2main startup --->Thu May 14 15:01:35 2015 + wxc2main startup --->Thu May 14 15:09:35 2015 + wxc2main startup --->Thu May 14 15:16:26 2015 + wxc2main startup --->Thu May 14 15:34:19 2015 + wxc2main startup --->Thu May 14 15:41:30 2015 + wxc2main startup --->Fri May 15 14:56:53 2015 + wxc2main startup --->Sat May 16 03:08:22 2015 + wxc2main startup --->Sat May 16 08:44:41 2015 + wxc2main startup --->Sat May 16 09:14:54 2015 + wxc2main startup --->Sat May 16 13:11:47 2015 + wxc2main startup --->Sat May 16 13:11:58 2015 + wxc2main startup --->Sat May 16 13:21:33 2015 + wxc2main startup --->Sun May 17 02:34:21 2015 + wxc2main startup --->Sun May 17 03:25:37 2015 + wxc2main startup --->Sun May 17 03:57:11 2015 + wxc2main startup --->Sun May 17 07:07:46 2015 + wxc2main startup --->Sun May 17 07:14:55 2015 + wxc2main startup --->Sun May 17 07:31:28 2015 + wxc2main startup --->Sun May 17 07:35:39 2015 + wxc2main startup --->Sun May 17 08:19:30 2015 + wxc2main startup --->Sun May 17 09:02:35 2015 + wxc2main startup --->Sun May 17 09:05:38 2015 + wxc2main startup --->Sun May 17 09:11:36 2015 + wxc2main startup --->Sun May 17 09:15:03 2015 + wxc2main startup --->Tue May 19 12:02:09 2015 + wxc2main startup --->Wed May 20 12:01:58 2015 + wxc2main startup --->Thu May 21 13:20:01 2015 + wxc2main startup --->Sat May 23 02:49:53 2015 + wxc2main startup --->Sat May 23 03:43:44 2015 + wxc2main startup --->Sat May 23 05:49:31 2015 + wxc2main startup --->Sat May 23 05:51:29 2015 + wxc2main startup --->Sat May 23 06:20:58 2015 + wxc2main startup --->Sat May 23 06:36:07 2015 + wxc2main startup --->Sat May 23 06:45:19 2015 + wxc2main startup --->Sat May 23 07:04:42 2015 + wxc2main startup --->Sat May 23 11:48:02 2015 + wxc2main startup --->Sat May 23 11:49:56 2015 + wxc2main startup --->Sat May 23 12:02:52 2015 + wxc2main startup --->Sun May 24 11:42:55 2015 + wxc2main startup --->Mon May 25 11:49:40 2015 + wxc2main startup --->Mon May 25 13:07:19 2015 + wxc2main startup --->Mon May 25 13:31:06 2015 + wxc2main startup --->Tue May 26 13:32:04 2015 + wxc2main startup --->Wed May 27 12:25:36 2015 + wxc2main startup --->Sat Sep 24 03:49:36 2016 + wxc2main startup --->Sat Sep 24 03:50:04 2016 + wxc2main startup --->Sat Sep 24 03:50:42 2016 + wxc2main startup --->Sat Sep 24 03:51:09 2016 + wxc2main startup --->Sat Sep 24 03:51:28 2016 + wxc2main startup --->Sat Sep 24 03:55:58 2016 + wxc2main startup --->Sat Sep 24 03:58:05 2016 + wxc2main startup --->Sat Sep 24 04:00:18 2016 + wxc2main startup --->Sat Sep 24 06:26:59 2016 + wxc2main startup --->Sat Sep 24 07:39:46 2016 + wxc2main startup --->Sat Sep 24 07:40:22 2016 + wxc2main startup --->Sat Sep 24 07:41:05 2016 + wxc2main startup --->Sat Sep 24 07:41:34 2016 + wxc2main startup --->Sat Sep 24 07:42:23 2016 + wxc2main startup --->Sat Sep 24 07:43:47 2016 + \ No newline at end of file diff --git a/mss/log/wxc2exit.txt b/mss/log/wxc2exit.txt new file mode 100644 index 0000000..ee1ece8 --- /dev/null +++ b/mss/log/wxc2exit.txt @@ -0,0 +1,4 @@ +WXC2 procedure exit log + Time: Sat Sep 24 06:26:51 2016 + +Now module: MSC diff --git a/mss/main/Makefile b/mss/main/Makefile new file mode 100644 index 0000000..f2f8d30 --- /dev/null +++ b/mss/main/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public pal isdn +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas palim rls ues +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + + +MODULE = agtocs +TYPE = app + +DBUG_FLAGS_ADD = -D_LKSCTP +RELS_FLAGS_ADD = -D_LKSCTP + +##Default commonly as below + +BUILD = exef +CFG = debug + +PLT_LIB = scf smpp xapp tcap mtp3 m2ua snmp iptrans debug sccp public radius tcp diameter + +APP_LIB = pps +LIB_ADD = -ldl -lpthread -ldl -lcrypt -lnsl -lm -lrt -lsctp -lgcrypt -lgnutls /usr/lib/x86_64-linux-gnu/libidn.a -L/usr/local/lib -lglib-2.0 -lhiredis + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = on +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/mss/main/conf/.copyarea.db b/mss/main/conf/.copyarea.db new file mode 100644 index 0000000..98d44ab --- /dev/null +++ b/mss/main/conf/.copyarea.db @@ -0,0 +1,48 @@ +ClearCase CopyAreaDB|4 +vobs\r9\mss\main\conf +2 +2c +9:help_page|1|11ab98fac5b|21f|d62d8a1f|2d495c7ebfa311dc832b001c23e19543|0 +c:msc_rzs.conf|1|11ab98fb3ec|29c|48ecc3c0|7869699ebfa311dc832b001c23e19543|0 +f:msc_system.conf|1|11ab98fb2d3|59|e97d1aaa|7609692ebfa311dc832b001c23e19543|0 +12:cap_operation.conf|1|11ab98fb0fe|4b0|9c725776|70196816bfa311dc832b001c23e19543|0 +c:cap_acn.conf|1|11ab98fae20|f1|ba0a4b11|33495d7abfa311dc832b001c23e19543|0 +10:conv_prefix.conf|1|11ab98fadc2|3940|d52c0a58|31795d42bfa311dc832b001c23e19543|0 +e:smsc_csta.conf|1|11ab98fb227|16b|27e474c8|73a968bebfa311dc832b001c23e19543|0 +c:map_acn.conf|1|11ab98fad74|5e5|45d6ce17|30495d0abfa311dc832b001c23e19543|0 +d:wxc2_sys.conf|1|11ab98faca9|42|438e1272|2e795cb6bfa311dc832b001c23e19543|0 +c:iptrans.conf|1|11ab98fb41b|227|b33f8c12|790969babfa311dc832b001c23e19543|0 +9:menu_page|1|11ab98fabce|2ce|7a7341|2b895c2abfa311dc832b001c23e19543|0 +a:system.ini|1|11ab98fb3bd|e8c|69e55b25|77d96982bfa311dc832b001c23e19543|0 +a:HlrSysPara|1|11ab98fb13d|1c50|326a8f75|70a96832bfa311dc832b001c23e19543|0 +d:smsc_sys.conf|1|11ab98fb1f8|54|50a31776|730968a2bfa311dc832b001c23e19543|0 +4:conf|2|0|0|0|3b995f02bfa311dc832b001c23e19543|0 +c:systemhh.ini|1|11ab98fae7e|4a8|153f5a60|34795db2bfa311dc832b001c23e19543|0 +c:msc_cua.conf|1|11ab98faf68|15e7|d014cac6|37795e3ebfa311dc832b001c23e19543|0 +9:ussd.conf|1|11ab98fb2a4|124|e2154d2c|75696912bfa311dc832b001c23e19543|0 +d:ussd_bak.conf|1|11ab98fadf1|e7|a8564408|32a95d5ebfa311dc832b001c23e19543|0 +12:map_operation.conf|1|11ab98fb081|a57|cf9ff375|3b095ee6bfa311dc832b001c23e19543|0 +a:debug.conf|1|11ab98fb16c|67|af3f196c|7149684ebfa311dc832b001c23e19543|0 +9:vlr_index|1|11ab98faf97|88|af192153|38095e5abfa311dc832b001c23e19543|0 +13:is41_operation.conf|1|11ab98fb052|886|d103743d|3a695ecabfa311dc832b001c23e19543|0 +a:AucSysPara|1|11ab98fb275|38|a03e055a|74d968f6bfa311dc832b001c23e19543|0 +7:vlr_err|1|11ab98fb311|c4|d24e2f78|7699694abfa311dc832b001c23e19543|0 +a:EirSysPara|1|11ab98fafc6|4444|47900a1d|38a95e76bfa311dc832b001c23e19543|0 +9:sccp.conf|1|11ab98fabfd|fa31|cbce0f2|2c195c46bfa311dc832b001c23e19543|0 +e:system.ini.old|1|11ab98fb39e|4a8|dc5068df|77396966bfa311dc832b001c23e19543|0 +b:ppsConf.txt|1|11ab98fac2c|1bf0|7736b2e4|2cb95c62bfa311dc832b001c23e19543|0 +9:mtp3.conf|1|11ab98fad35|1c03d|9a278bd3|2fb95ceebfa311dc832b001c23e19543|0 +b:msc_mg.conf|1|11ab98fad93|30d|52a3e524|30e95d26bfa311dc832b001c23e19543|0 +4:stop|1|11ab98fad07|11000|160383d4|2f195cd2bfa311dc832b001c23e19543|0 +e:ppsCrdConf.txt|1|11ab98fb1c9|2832|28320001|72796886bfa311dc832b001c23e19543|0 +12:smsc_parambit.conf|1|11ab98fb0b0|968|3c4a89a2|6f7967fabfa311dc832b001c23e19543|0 +8:vlr.conf|1|11ab98fac7a|80|5d091aab|2de95c9abfa311dc832b001c23e19543|0 +d:cc_table.conf|1|11ab98fae4f|1156|31d07a59|33d95d96bfa311dc832b001c23e19543|0 +c:wxc2exit.txt|1|11ab98faf0a|4a|539c1559|36395e06bfa311dc832b001c23e19543|0 +11:xap_sysparam.conf|1|11ab98faff5|10|3b390840|39395e92bfa311dc832b001c23e19543|0 +8:srf.conf|1|11ab98fb023|1782c|11d18f04|39d95eaebfa311dc832b001c23e19543|0 +b:msc_tg.conf|1|11ab98faedb|22b0|6de108a2|35a95deabfa311dc832b001c23e19543|0 +e:xap_mscid.conf|1|11ab98fb246|c00|c000001|743968dabfa311dc832b001c23e19543|0 +9:smpp.conf|1|11ab98faf39|c1a|20460689|36d95e22bfa311dc832b001c23e19543|0 +b:msc_la.conf|1|11ab98fb19a|17d|78566e3f|71d9686abfa311dc832b001c23e19543|0 +c:msc_dps.conf|1|11ab98faeac|112a|8d7ba7b5|35095dcebfa311dc832b001c23e19543|0 diff --git a/mss/main/conf/.ussd.conf.swp b/mss/main/conf/.ussd.conf.swp new file mode 100644 index 0000000000000000000000000000000000000000..acaca1da531d957a317b96f1e89e4d1f00e74f80 GIT binary patch literal 12288 zcmeI&zi-n(6bJAZRwSVGA9y5NB>a;QFCAJpQ6n`dibi#00bZa0SG_<0uX=z1pYmNa@nAt^4Rwz?n^YbArl4!AOHafKmY;|fB*y_ z009U<00RGsKs+M~9}vBfFz^4(e*oVf5`B~SD)Cw3lf*}f_Y%Iu7s-9Qt$A(gFdzT{ z2tWV=5P$##AOHafKmY=NA>cA|@VwjUIF2VvcDtVC2A1bPvs}+N8?H&IhwC`?BG~Q7 zT$P#Y-RbanL?&i73ucbU;}G@`*Nb2Pqqv0Bur zgV7%)W*I4clT1~Z&lC^i^|{JqQ?8P19+jI^@kx@VxmhZ@oJ7$n z_l|p4MEzVZ;*z6MOC=w1v)!I}t`7Z^cGPMz+qPEoRT^tn>!nsjk>uH~sGr7jx$6q+0>&+Ti2wiq literal 0 HcmV?d00001 diff --git a/mss/main/conf/AucSysPara b/mss/main/conf/AucSysPara new file mode 100644 index 0000000000000000000000000000000000000000..c214082d994b5bb8c09559590d29492eac6b72db GIT binary patch literal 3064 zcmZQzfC28d(g+5IxOeYh0t^CBR={Dn5W|8tMg|5KPX@-@M`zvH_H)7e;*j#~zwS4e zI4~$UBp}pbWdXIK045Y30|N^hpM!zn-~a#rfuf8ct#r4O3EhEc?xPWxQOG2$0vXdG zY-!|`QDa9#U^E0qLtr!n&_aOGjdKDc10#bxgcjguU<_#x0M@v{{7`y6BUFt5OpQD< gOhg~7i*x3DG*gEx7g)=qfFbLVQHPI)z)%PQ0Kn2pvH$=8 literal 0 HcmV?d00001 diff --git a/mss/main/conf/EirSysPara b/mss/main/conf/EirSysPara new file mode 100644 index 0000000000000000000000000000000000000000..242ca1773ec1d45baf146846964f14fb70e09ebf GIT binary patch literal 17476 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�a{ej6zkvLv2s-9Zz#skz|A#=Bz6N+I z+A9E^+uIC0>aLG(9aSEOfM3(mPXb?{v!@Hd`F&Uebv}C&xF7Os_VYdPx7GRAOPGKC z2ArSI_{>CZ|2h0iB()>tivfYYxG9I<8`Xp&{C@PY%Krf1 z#i(zGTHko!`-{B%%?F+e{cHZY3V0ZvFEo4H27Ca<2krS}2XG1VK}~*p8CNeqzVj*q zUO0erqW*I1Q@SZT+nAYSxAD$;r(5Jiu5_o{<<8B>0O;@!#Addr9RWQTun29}b5g3wf2cdOOORdhGzyG%VeKfs;>G(aupV51=rbUUz*b%CzvR7z4}IienE@T_)cQQWCbTp}wTt9MmF^5P^hBiB3z8))uHv zl+H8>o>31Ub_Dl;Df8W$QD!elDEq01yV7jyA;2AZ0t!O*RvfVN^ltJ;&4? z3FZvs%2BH3jxmyN!Jcr?a?BY$aq2}TKocw4gfrPBQ!v=Xu0SN(aDYNn+|#p+?zC(a z?SYeP0Kgn_K)B}BUq!^1^3k9IN zA|hhq<61`=gHU54TXQ>Mzfn?je!3M$hw$>RNcbQ7U7TWU9Z-F?si#5us14diz`^-$ zaKWVHR>{%A6O8a9u_sY60pVS2d@wp3N+RqK3%i2CB&-Uv=^4njXWID8kRWK#<&ca~ zAGdGSE-uoe8_l651QqNXP7_uF(b@tf#jU|AcywD@MYcwKby_lU&>8c>tIiO^GVJ=+ z+C;XFf$b-uK`BZRnAwq|dcBm?)24``9nOKvGz98PCL%I12 zzI0K&lFO2fO|?e04JkvYB12yp`oV0#p}6N^n$bzny9n4hQXIydXdy+X zO2h-xJ%0Tdd+;yfpIo(mq)p_0w(g1VBz z2us=I!hw21&TMyzV>l&@=qzt7Ag93tGMzYo#;gs+(nlg>1tGXdX(k)apkemm=V7e# z^fYz~m)p}pWl+lQ>4J4D4;?v`LCiHYT@f9UqNpGd94honysnHh@6GlQ2Hw4#&H( z%X@r3if5mBiWO!`9J?*%kL);|if4M+V))f+36oMVyLR-HVy%fLm*!m=INwTV0S2DV zsiP^oy)ldjRVXAZFfh&G5<{Fw4^cv3kfa0-F$xKv{>uh!47};xlI^W9v*1BQaT|<* zi0MN5`r1{hs9DMoCm?zC$WK5zJ99m2x0q3?;XEnV!6*5++Vjjyoogtwc9y5UK7+QWq*%vCk(Kk=E9a-@c@t1*bTNxL%;PGCSjGyj z;|6Zx7H;DX?&2O+k>dd#;t?L>37%pN&+!85c!^hdjV)|r7khY*5BP{r_>3Ow@t*1# zpZL^gKKF$$edTN4_%99$VN4KDyFjCq7#jU#iewi4X?8|*(|yq0}c~@kgNtX^8wDSwdZ70 z!UMrUvg>&OrqgLV9{aqu=E4a$0Vm)DoPZN>0#3jQH~}Z%1e|~qZ~~`E;Mo0#D>wls z-~^n&e;_co**3X-sdHi0^EyZR-Jg%{KRbV Configuration -> Call Routing +-- + +Call_Routing OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Call Routing . + " + ::= { CCF_Config 1 } + +Prefix_Assignment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 8 + Default : EEEEEEEEEEEEEEEE + Field : [1]Prefix + { + [u]0.0-7.7 + [u]input + [v]keepHex-low-E + } + Remark: 4 bytes are used to set a 8-digit prefix for dialed number. + Prefix is the first layer for dialed number based call routing. If the dialed number of a call matches a pre-programmed prefix in this table, this call will be routed to a certain trunk group, subsequently that trunk group will route this call via a dedicated E1 port.This system has totally 256 prefixes. + Dialed number without matching a pre-programmed prefix will be routed to the default trunk group 0. + Prefix 252 is for default international call, all internation calls unable to be routed out will be routed from the trunk group assigned to prefix 252, keep default EEEEEEEE. + Prefix 253 is for default national call, all national calls unable to be routed out will be routed from the trunk group assigned to prefix 253, keep default EEEEEEEE. + Prefix 254 is for default subscriber call, all dialed MSISDN unable to be routed out will be routed from the trunk group assigned to prefix 254, keep default EEEEEEEE. + Prefix 255 is for unknown call, all unknown calls unable to be routed out will be routed from the trunk group assigned to prefix 255, keep default EEEEEEEE. + E=End tag, C='#', B='*'. + Default=0xEEEEEEEE. + [End] + " + ::= { Call_Routing 1 } + +Prefix_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 18 + Default : 2200EEEEEEEEEEEEEEEE010800EEEEEEEE03 + Flag : E10 + Field : [1]TON incoming call + { + [u]0.0-0.3 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [2]TON outgoing call + { + [u]0.4-0.7 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [3]Out trunk deletion count + { + [u]1.0-1.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [4]Out trunk insertion count + { + [u]1.4-1.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [5]Out trunk inserted digits + { + [u]2.0-9.7 + [u]input + [v]keepHex-low-E + } + [6]CDR on/off + { + [u]10.0-10.0 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [7]Reserved + { + [u]10.1-10.1 + [u]select + } + [8]Properties + { + [u]10.2-10.3 + [u]select + [v]0[opt]Trunk + [v]1[opt]MSISDN + [v]2[opt]MSRN + [v]3[opt]MSC + } + [9]Call type + { + [u]10.4-10.6 + [u]select + [v]0[opt]Normal Call + [v]1[opt]Emergency + [v]2[opt]MCT + [v]3[opt]VMS + [v]4[opt]IN + } + [10]Enable + { + [u]10.7-10.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } + [11]Length of dialed number + { + [u]11.0-11.7 + [u]input + [v]toDec-high-0 + } + [12]E.164 International deletion count + { + [u]12.0-12.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]Delete first one + [v]2[opt]Delete first two + [v]3[opt]Delete first three + [v]4[opt]Delete first four + [v]5[opt]Delete first five + [v]6[opt]Delete first six + [v]7[opt]Delete first seven + [v]8[opt]Delete first eight + } + [13]E.164 International insertion count + { + [u]12.4-12.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]Insert first one + [v]2[opt]Insert first two + [v]3[opt]Insert first three + [v]4[opt]Insert first four + [v]5[opt]Insert first five + [v]6[opt]Insert first six + [v]7[opt]Insert first seven + [v]8[opt]Insert first eight + } + [14]E.164 international inserted digits + { + [u]13.0-16.7 + [u]input + [v]keepHex-low-E + } + [15]Cli-type + { + [u]17.0-17.7 + [u]select + [v]0[opt]Sub + [v]1[opt]NDD + [v]2[opt]IDD + [v]3[opt]Unknown(local) + [v]4[opt]Unknown(NDD) + [v]5[opt]Unknown(IDD) + } + Remark: Enable: Y=prefix enable, N=prefix disable. + TON incoming call: Type of number for incoming call, include unknown, MSISDN, NDD and IDD. It is specified by originating node for terminating node to route this call with proper dialed number manipulation. + For system subscriber dialed prefix, always use unknown for In-TON except the prefix of international prefix beginning with a . For this kind of prefix (such as 86755832) we should set the In-TON as IDD to support dialing. + TON outgoing call: Type of number for outgoing call, include unknown, MSISDN, NDD and IDD. It specifies the type of an outgoing call for terminating node to route this call with proper dialed number manipulation. Generally the MSC uses IDD for outgoing call. + Out trunk deletion count: Quantity of deleted digit of a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no deletion, 1-8=delete first 1-8 digits. + Out trunk insertion count: Quantity of inserted digit for a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no insertion, 1-8=insert 1-8 digits from the beginning of this number. + Out trunk inserted digits: 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number. + CDR on/off: Turn on/off the CDR of dialed numbers beginning with this prefix. + Properties: Specify the properties of a prefix. Trunk=to PSTN, MSISDN=to A interface, MSRN=MS roaming number, MSC=to peer MSC. + Call type: Normal=no verification for MT, Emergency call=no verification for MO (free call), MCT=Malicious Call Trace, VMS call=send signaling carried DTMF to VMS. + Length of dialed number: Length of dialed number (1-32). + E.164 international deletion count: Quantity of deleted digit of E164 international number, always use IDD for outgoing call for PPS debiting. + E.164 international insertion count: Quantity of inserted digit of E164 international number, always use IDD for outgoing call for PPS debiting. + E.164 international inserted digits: Inserted digit to the E164 international number, 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number, always use IDD for outgoing call for PPS debiting. + [End] + " + ::= { Call_Routing 2 } + +Prefix_TG OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field: + [1]Assign TG to prefix + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a trunk group for each prefix for call routing, a single prefix points to only one trunk group, multiple prefix can be assigned the same trunk group, default is the no. of the prefix. + [End] + " + ::= { Call_Routing 3 } + +TG_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 10 + Default : 00000000000000000000000000 + Flag : E2 + Field: [1]DPC + { + [u]0.0-3.7 + [u]input + [v]keepHex-high-0 + } + [2]TG flag + { + [u]4.0-4.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]CDR on/off + { + [u]4.1-4.1 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [4]Announcement + { + [u]4.2-4.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [5]TG category + { + [u]4.3-4.5 + [u]select + [v]0[opt]PSTN + [v]1[opt]HPLMN + [v]2[opt]VHLMN + [v]3[opt]SUB + [v]4[opt]IP + [v]5[opt]Intercept + } + [6]Alternative TG flag + { + [u]4.6-4.6 + [u]select + [v]0[opt]Disable + [v]1[opt]enable + } + [7]Loopback + { + [u]4.7-4.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [8]Network indicator + { + [u]5.0-5.7 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [9]Circuit selection + { + [u]6.0-6.1 + [u]select + [v]0[opt]Clockwise + [v]1[opt]Anti-clockwise + [v]2[opt]Odd + [v]3[opt]Even + } + [10]Back off + { + [u]6.2-6.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [11]Reserved + { + [u]6.3-6.4 + [u]select + } + [12]MPTY + { + [u]6.5-6.5 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [13]Location + { + [u]6.6-6.7 + [u]select + [v]0[opt]MSC-0 + [v]1[opt]MSC-1 + [v]2[opt]Both + [v]3[opt]Spare + } + [14]Alternative TG + { + [u]7.0-7.7 + [u]input + [v]toDec-high-0 + } + [15]Tandem restriction + { + [u]8.0-8.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [16]Incoming Call type + { + [u]9.0-9.7 + [u]select + [v]0[opt]Normal + [v]1[opt]IN + } + Remark: DPC: Destination point code of this trunk group. + TG flag: enable or disable this trunk group. + CDR on/off: CDR on or off option for this trunk group. + Announcement: Voice announcement enable or disable for this trunk group. + TG category: PSTN=to PSTN, IP=to VMS and VPS, HPLMN=to HPLMN, VPLMN=to VPLMN, SUB=to BSC, Intercept=to intercept LEA + Alternative TG flag: Alternative trunk group enable or disable option. + Alternative TG: Alternative trunk group for backup purpose. + Loop back: Incoming call loop back enable or disable, used for MSC loop back. + Network indicator: Specify network type, International, International spare , National, National spare. + Circuit selection: Preferred circuit selection mode, include clockwise, anti-clockwise, odd and even. + Back off: Back off on or off when simultaneously select the same channel with the opposite side. + Location: For normal trunk group, select Both. For a trunk group to a VPS, configure this trunk group as MSC0 or MSC1. + MPTY: Multi-party call enable or disable. For all trunk groups to BSC, select Enable. + Tandem restriction:Y: Tandem disabled. Not support transit call from PSTN to PSTN via this trunk group. + N: Tandem enabled. Support transit call from PSTN to PSTN via this trunk group. + [End] + " + ::= { Call_Routing 4 } + +Call_Routing_CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 2 + Default : 03FF + Field : [1]Reserved + { + [u]0.3-0.7 + [u]select + } + [2]Redirection + { + [u]0.3-0.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [3]Feature Request + { + [u]0.2-0.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [4]Sorm + { + [u]0.1-0.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [5]MCT + { + [u]0.0-0.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [6]MT SM + { + [u]1.7-1.7 + [u]select + [v]0[opt]off + [v]1[opt]on + + } + [7]MO SM + { + [u]1.6-1.6 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [8]Transit call + { + [u]1.5-1.5 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [9]Gateway outgoing call + { + [u]1.4-1.4 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [10]Gateway incoming call + { + [u]1.3-1.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [11]Roaming call + { + [u]1.2-1.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [12]MT call + { + [u]1.1-1.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [13]MO call + { + [u]1.0-1.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + Remark: Sorm: call intercept MCT: malicious call trace + Default=CDR of MO call and MT call is enabled, CDR of roaming call, gateway incoming call, gateway outgoing call, transit call, MO SMS and MT SMS is disabled. + [End] + " + ::= { Call_Routing 5 } + +Voice_Prompt_Announcement_option OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 16 + Default : 00000000000000000000000000000000 + Field : [1]Announcement 0 + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [2]Announcement 1 + { + [u]1.0-1.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [3]Announcement 2 + { + [u]2.0-2.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [4]Announcement 3 + { + [u]3.0-3.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + + [5]Announcement 4 + { + [u]4.0-4.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [6]Announcement 5 + { + [u]5.0-5.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [7]Announcement 6 + { + [u]6.0-6.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [8]Announcement 7 + { + [u]7.0-7.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [9]Announcement 8 + { + [u]8.0-8.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [10]Announcement 9 + { + [u]9.0-9.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [11]Announcement 10 + { + [u]10.0-10.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [12]Announcement 11 + { + [u]11.0-11.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [13]Announcement 12 + { + [u]12.0-12.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [14]Announcement 13 + { + [u]13.0-13.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [15]Announcement 14 + { + [u]14.0-14.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [16]Announcement 15 + { + [u]15.0-15.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + Remark : Set to play either announcement or tone indicating call unattainable reason for subscribers. System has total 8 announcements and tones that can be independently set. + Announcement 0: The dialed number is invalid. + Announcement 1: The subscriber dialed is not activated. + Announcement 2: The subscriber is busy. + Announcement 3: The network is busy. + Announcement 4: Caller's account was deactivated. + Announcement 5: The subscriber dialed was deactivated. + Announcement 6: Feature not available to caller. + Announcement 7: The subscriber dialed is not available. + [End] + " + ::= { Call_Routing 6 } + +Call_Routing_Warning OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 32 + Field : [1]Remanent time for warning tone + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark :Set time to play prompt tone for reaching zero balance prepaid subscriber when a call is in progress, unit is second. e.g. if set as 60, the system will play prompt tone one minute before a subscriber uses up his balance. + [End] + " + ::= { Call_Routing 7 } + + + +-- +-- CCF -> Configuration -> MSC +-- + + +CCF_MSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CCF Configuration MSC ." + ::= { CCF_Config 2 } + +Emergency_Call OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 21 + Default : 0000000000EEEEEEEEEEEEEEEE112EEEEEEEEEEEEE + Flag : E1 + Field : [1]Enable flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]LAC + { + [u]01.0-02.7 + [u]input + [v]toDec-high-0 + } + [3]CI + { + [u]03.0-04.7 + [u]input + [v]toDec-high-0 + } + [4]Dial number + { + [u]05.0-12.7 + [u]input + [v]keepHex-low-E + } + [5]Local emergency number + { + [u]13.0-20.7 + [u]input + [v]keepHex-low-E + } + Remark: Emergency call number. Default=112. + [End] + " + ::= { CCF_MSC 5 } + +Location_Management OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 8 + Default : 0000000000000000 + Flag : E1 + Field : [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } + [2]TG + { + [u]01.0-01.7 + [u]input + [v]toDec-high-0 + } + [3]LAC + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [4]CI + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + [5]Zone Code + { + [u]06.0-07.7 + [u]input + [v]toDec-high-0 + } + Remark :Manage the MS location by correlate TG (trunk group), LAC (location area code, cell ID and zone code, totally 256 location management. + [End] + " + ::= { CCF_MSC 8 } + + + +-- +-- CCF -> Configuration -> CPC Management +-- + + +CPC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CPC Management." + ::= { CCF_Config 3 } + +SRF_Address OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 8 + Default : 8675500000000009 + Field : [1]EIR number + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-E + } + Remark: E.164 number of HLR server:HLR MSISDN used for SCCP addressing, F=end tag. + Default=91867555950502FFFF=91867555950502. + [End] + " + ::= { CPC 3 } + +Max_Call_Duration OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 3C + Field : [1]Max. call duration + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark : Define the permitted maximum call duration. Any ongoing call reaching this duration threshold will be compulsively cut off. byte value: 0=disable this function, 1-255=max. call duration, unit=minute. Default=0. + [End] + " + ::= { CPC 7 } + +-- +-- CCF -> Configuration -> E1 Port +-- + + +E1_Port OBJECT-IDENTITY + STATUS current + DESCRIPTION + "E1 Port." + ::= { CCF_Config 4 } + +E1_Interface OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]E1 interface + { + [u]0.0-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF CDMA2K + [v]4[opt]BICC + [v]5[opt]CI-CNF + [v]6[opt]CI-loopback + } + Remark: Set the type of E1 interface for 256 E1 ports. + [End] + " + ::= { E1_Port 1 } + +E1_TG OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : EE + Field : [1]Assign TG + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark :Assign a trunk group to each E1 port for call routing. A single E1 port points to only one trunk group, multiple E1 port can be assigned the same trunk group. Default=number of the E1 port. + [End] + " + ::= { E1_Port 2 } + +E1_CIC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 4 + Default : 00000000 + Field : [1]E1 CIC + { + [u]0.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark :Circuit identity code, uniquely identify each circuit within a trunk group. CIC of both ends of a circuit must be identical. 256 CIC for dual MSC platform 256 E1 ports. + [End] + " + ::= { E1_Port 3 } + +E1_Media_Control_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 4 + Default : 00000000 + Field : [1]E1 Control Protocol Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Internal + [v]1[opt]MGCP + } + [2]E1 Enable + { + [u]1.0-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]MG Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + [4]Trunk Number + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark :E1 Media Control Attributes + [End] + " + ::= { E1_Port 4 } + +-- +-- CCF -> Configuration -> Channel attributes +-- + + +Channel_Attributes OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Channel attributes." + ::= { CCF_Config 5 } + +Card0_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 1 } + +Card1_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 2 } + +Card2_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 3 } + +Card3_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 4 } + +Card4_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 5 } + +Card5_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 6 } + +Card6_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 7 } + +Card7_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 8 } + +Card8_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 9 } + +Card9_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 10 } + +Card10_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 11 } + +Card11_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 12 } + +Card12_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 13 } + +Card13_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 14 } + +Card14_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 15 } + +Card15_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 16 } + +Card16_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 17 } + +Card17_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 18 } + +Card18_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 19 } + +Card19_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 20 } + +Card20_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 21 } + +Card21_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 22 } + +Card22_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 23 } + +Card23_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 24 } + +Card24_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 25 } + +Card25_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 26 } + +Card26_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 27 } + +Card27_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 28 } + +Card28_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 29 } + +Card29_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 30 } + +Card30_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 31 } + +Card31_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 32 } +-- +--CCF -> CPC_attributes +-- + +CPC_attributes OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CPC attributes." + ::= { CCF_Config 6 } +MSCID OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : [1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + [2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: MSCID + [End] + " + ::= { CPC_attributes 3 } + +-- +-- CCF -> Media_gateway +-- + +Media_gateway OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Media_gateway ." + ::= { CCF_Config 7 } + +MG_Attribute OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 53 + Default : 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field : [1]MG Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]MG IP Address + { + [u]1.0-4.7 + [u]input + [v]keepHex-high-0 + } + [3]MG Name + { + [u]5.0-52.7 + [u]input + [v]toAscii-low-0 + } + Remark: MG Attributes + [End] + " + ::= { Media_gateway 1 } + +-- +-- CCF -> CCF_Status +-- + +CCF_Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Status for CCF ." + ::= { CCF(MSC) 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : + Remark : Version of MSC software (Read only).
+ Byte0: System release version number, based on basic function and structure.
+ Byte1: Software module version number, based on software module.
+ Byte2: Test version, 0=Release version number, 1=Test version number.. + [End] + " + ::= { CCF_Status 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : EE + Flag : S1.3 + Field : [1]Command + { + [u]0.0-0.7 + [u]select + [v]90[opt]Reset + [v]165[opt]Initialize + [v]181[opt]Save parameter + [v]238[opt]No command + } + Remark: Control command for MSC-CPC. + Reset: Used for CPC status initialization. + Initialize: Restore the parameter setup to the default factory setting. + Save parameter: Save the parameters residing in CPC's memory into CPC's harddisk. + [End] + " + ::= { CCF_Status 2 } + +E1_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length : 1 + Default : EE + Field : [1]Quantity of occupied timeslot + { + [u]0.0-0.4 + [u]input + [v]toDec-high-0 + } + + [2]E1 type + { + [u]0.5-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF_CDMA2K + [v]4[opt]BICC + } + Remark : E1 status (read only). + [End] + " + ::= { CCF_Status 4 } + +Channel_Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Channel status (read only)." + ::= { CCF_Status 5 } + +Card0_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 1 } + +Card1_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 2 } + +Card2_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 3 } + +Card3_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 4 } + +Card4_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 5 } + +Card5_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 6 } + +Card6_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 7 } + +Card7_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 8 } + +Card8_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 9 } + +Card9_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 10 } + +Card10_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 11 } + +Card11_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 12 } + +Card12_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 13 } + +Card13_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 14 } + +Card14_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 15 } + +Card15_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 16 } + +-- +-- sub system VLR +-- + +VLR OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]sub for VLR . + " + ::= { MSC 5 } + +-- +-- VLR -> Configuration +-- + +VLR_Config OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for VLR . + " + ::= { VLR 2 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Public parameters . " + ::= { VLR_Config 1 } + +OptAuthReq OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 1 + Default : 00 + Field : [1]Update Location + { + [u]00.0-00.0 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [2]MO + { + [u]00.1-00.1 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [3]MT + { + [u]00.2-00.2 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [4]Spare + { + [u]00.3-00.7 + [u]input + [v]toDec-high-0 + } + Remark :Flag of SIM authentication on MS poweron and MO/MT call. + [End] + " + ::= { Public_Param 1 } + +OptReuseTriplets OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptReuseTriplets + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]double authentication + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Spare + { + [u]00.2-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Flag of reusing authentication triplets in VLR in the case that authentication to HLR is not available. Default=disable. + [End] + " + ::= { Public_Param 2 } + +OptCipReq OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptCipReq + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark : Flag of voice ciphering over air interface by MS. Default=Disable. + [End] + " + ::= { Public_Param 3 } + +OptCiphAlgo OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 4 + Default : 00000000 + Field : [1]OptCiphAlgo + { + [u]00.0-00.7 + [u]select + [v]0[opt]None + [v]1[opt]A5_1 + [v]2[opt]A5_2 + [v]3[opt]A5_3 + [v]4[opt]A5_4 + [v]5[opt]A5_5 + [v]6[opt]A5_6 + [v]7[opt]A5_7 + } + Remark : Voice ciphering algorithm selection. Default=no ciphering. + [End] + " + ::= { Public_Param 4 } + +OptTmsiAlloc OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]TMSI Allocation Option + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Allocate TMSI + [v]2[opt]Reallocate TMSI + } + Remark :Flag of allocating a new TMSI every time a call management service is requested. Default=Disable. + [End] + " + ::= { Public_Param 5 } + +OptEcSetUpAllow OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]OptEcSetUpAllow + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark : Flag of making emergency call for non-registered MS or MS without SIM. Default=Enable. + [End] + " + ::= { Public_Param 7 } + +OptCheckIMEI OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]Update Location + { + [u]00.0-00.0 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [2]MO + { + [u]00.1-00.1 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [3]MT + { + [u]00.2-00.2 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [4]Spare + { + [u]00.3-00.7 + [u]input + [v]toDec-high-0 + } + Remark : Flag of IMEI verification via EIR. Default=no IMEI verification. + [End] + " + ::= { Public_Param 8 } + +OptVlrPurge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptVlrPurge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + Remark : Flag of VLR purge. Default=Off. + [End] + " + ::= { Public_Param 9 } + +IdlePeriod2Purge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 3C + Field : [1]IdlePeriod2Purge + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark : Set the threshold of idle time to purge. If a mobile's idle time reaches this threshold, VLR will purge all records of this MS, unit=6 minute. Default=60minutes. + [End] + " + ::= { Public_Param 10 } + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]CDR on/off + { + [u]00.0-00.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + Remark : VLR CDR flag. Default=On. + [End] + " + ::= { Public_Param 11 } + +MSRN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 16 + Default : 8675531240000FFF8675531241000FFF + Field : [3]Start number + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-F + } + [4]End number + { + [u]08.0-15.7 + [u]input + [v]keepHex-low-F + } + Remark : Mobile station roaming number, use 16 bytes (32 digits) to define a range of MSRN. The length of start MSRN and end MSRN must be identical. F=end tag. + [End] + " + ::= { Public_Param 13 } + +-- +-- VLR -> Management +-- + +VLR_Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management for VLR . + " + ::= { VLR 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : + Remark : Version of VLR software (Read only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { VLR_Management 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : EE + Flag : S1.2 + Field : [1]Management + { + [u]00.0-00.7 + [u]select + [v]0[opt]Reset VLR + [v]1[opt]Save parameters + } + Remark : Control command for VLR. + Reset: Used to initialize the status of VLR. + Save parameters: Save the parameters residing in memory into harddisk. + [End] + " + ::= { VLR_Management 3 } + +Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : + Remark :Basic status of VLR. + [End] + " + ::= { VLR_Management 4 } + +END diff --git a/mss/main/conf/MIB_files/WXC2-MSS-MIB.txt b/mss/main/conf/MIB_files/WXC2-MSS-MIB.txt new file mode 100644 index 0000000..ddb4465 --- /dev/null +++ b/mss/main/conf/MIB_files/WXC2-MSS-MIB.txt @@ -0,0 +1,54 @@ +WXC2-MSS-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +MSS OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Subsystems for MSS . " + ::= { App 16 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for MSS . " + ::= { MSS 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Management for MSS . " + ::= { Configuration 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 1 + Default : 00 + Field : [1]Command + { + [u]00.0-00.7 + [u]select + [v]4[opt]Shutdown + [v]5[opt]Undefine value + } + Remark : Safely shut down MSS server by stoping MSS process, saving subscriber data to harddisk and shut down the server. + Operation procedures: + 1. Select -Shutdown- at above pulldown menu. + 2. Click -Set- button in this set window. + 3. Click -SET- button on operation page. + [End] + " + ::= { Management 1 } + +END diff --git a/mss/main/conf/MIB_files/WXC2-PPS-MIB.txt b/mss/main/conf/MIB_files/WXC2-PPS-MIB.txt new file mode 100644 index 0000000..b566b21 --- /dev/null +++ b/mss/main/conf/MIB_files/WXC2-PPS-MIB.txt @@ -0,0 +1,13090 @@ +WXC2-PPS-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +PPS OBJECT-IDENTITY + STATUS current + DESCRIPTION + "[SubSystem_Module]Subsystems for PPS . " + ::= { App 6 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " public parameters for MSS . " + ::= { PPS 2 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for PPS . " + ::= { Public_Param 1 } + +Service_Control OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service Control . " + ::= { Configuration 1 } + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]CDR flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark: PPS CDR generation enable or disable. Default=PPS generate CDR. + [End] + " + ::= { Service_Control 1 } + +Blacklist_Threshold OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 05 + Field: [1]Blacklist threshold + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Legal recharge failure, subsciber who breaks the threshold will be marked in black list and suspended from service provisioning. Default=5. + [End] + " + ::= { Service_Control 2 } + +Maximum_Balance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00100000 + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This value is for overflow prevention. Normally operator doesn't need to change this value. e.g. 5000, and the smallest unit is cent then the maximum allowed balance is 5000 cents. + [End] + " + ::= { Service_Control 3 } + +License_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]License + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-E + } + Remark: 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of PPS subscribers for service provider. The new license can not support less PPS subscribers than what the old license supports. + [End] + " + ::= { Service_Control 4 } + +Prompt_Resolution OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Currency resolution + { + [u]00.0-00.1 + [u]select + [v]0[opt]1 + [v]1[opt]10 + [v]2[opt]100 + } + [2]Date format + { + [u]00.2-00.3 + [u]select + [v]0[opt]YYYY-MM-DD + [v]1[opt]DD-MM-YYYY + [v]2[opt]MM-DD-YYYY + } + [3]Currency symbol position + { + [u]00.4-00.4[u]select + [v]0[opt]Front + [v]1[opt]Rear + } + [4]Reserved + { + [u]00.5-00.7 + [u]select + } + Remark: Currency style: Set the number of decimals in account balance SM display format. If account balance=55555 in smallest currency unit: + 1=account balance display in SM is 55555. + 10=account balance display in SM is 5555.5. + 100=account balance display in SM is 555.55. + Default=100. + Date style: Set the date format displayed in SM or announcement. Default=YYYY-MM-DD. + Currency symbol position: Set the position of the currency symbol. + There are two types: at the front of the amount (e.g. $5) or at the rear of the amount (e.g. 5Fr). Default=at the front. + [End] + " + ::= { Service_Control 5 } + +SMS_Sentence OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 5 + Length: 112 + Default: 00596F7572206163636F756E742062616C616E63652069733A000000000000004578706972656420696E3A000000000000000000000000000000000000000000506C6561736520726563686172676520796F7572206163636F756E740000000000000000000000000000000000000000 + Field: [1]SM encode type + { + [u]00.0-00.7 + [u]select + [v]0[opt]7 bit + [v]4[opt]octet + [v]8[opt]unicode + } + [2]Account balance + { + [u]01.0-31.7 + [u]input + [v]toAscii-low-0 + } + [3]expired in + { + [u]32.0-63.7 + [u]input + [v]toAscii-low-0 + } + [4]recharge in time + { + [u]64.0-111.7 + [u]input + [v]toAscii-low-0 + } + Remark: The # of sentence(0-4) refers to differenct language type; + [End] + " + ::= { Service_Control 6 } + +Last_Call_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 5 + Length: 88 + Default: 4C6173742063616C6C2073656E74206F6E3A00000000000000000000000000004C6173742063616C6C207265636569766564206F6E3A200000000000000000004174000000000000546F00000000000046726F6D00000000 + Field: [1]Last call sent on + { + [u]00.0-31.7 + [u]input + [v]toAscii-low-0 + } + [2]Last call received on + { + [u]32.0-63.7 + [u]input + [v]toAscii-low-0 + } + [3]At + { + [u]64.0-71.7 + [u]input + [v]toAscii-low-0 + } + [4]To + { + [u]72.0-79.7 + [u]input + [v]toAscii-low-0 + } + [5]From + { + [u]80.0-87.7 + [u]input + [v]toAscii-low-0 + } + Remark: The # of sentence(0-4) refers to differenct language type. + [End] + " + ::= { Service_Control 7 } + +Currency_Symbol OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 2400000000000000 + Field: [1]Currency symbol + { + [u]00.0-07.7 + [u]input + [v]toAscii-low-0 + } + Remark: Set the symbol of the local currency in SMS amount display. e.g. $, RMB, EUR, US$, FR$. default=$. In the set window, type the currency symbol. The input symbol will be converted to ASCII code. + Do not input any symbol that not listed on the ASCII code table. ASCII table: 'A'=0x41, 'B'=0x42 ... 'I'=0x49, 'J'=0x4a, 'K'=0x4b ... 'Z'=0x5A, '$'=0x24 + e.g. RMB=0x52 0x4d 0x42, US$=0x55 0x53 0x24 + [End] + " + ::= { Service_Control 8 } + +Third_Party_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Service ID + { + [u]00.0-07.7 + [u]input + [v]toAscii-low-0 + } + [2]Service password + { + [u]08.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: This parameter is a verification for third party ESME when the third party ESME sends a billing request to PPS server. For example, if a subscriber sends a short message via a ESME (e.g. website), the ESME will send a billing request to PPS to debit this subscriber. This billing request must contains a service ID and password to pass the verification. After verification, the subscriber will be debited by the PPS. PPS supports 8 ESME connections. + [End] + " + ::= { Service_Control 9 } + +Basic_Tariff_Zone OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 64 + Length: 9 + Default: 000000000000000000 + Field: [1]MCC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-F + } + [2]MNC + { + [u]02.0-02.7 + [u]input + [v]keepHex-low-F + } + [3]LAC + { + [u]03.0-04.7 + [u]input + [v]toDec-high-0 + } + [4]Cell ID + { + [u]05.0-06.7 + [u]input + [v]toDec-high-0 + } + [5]MO tariff ID + { + [u]07.0-07.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [6]MT tariff ID + { + [u]08.0-08.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: The basic tariff is applied for each calling or called number prefix. The WXC2 System supports 16 MO and MT tariffs (0-15) and 256 billing zones. This parameter defines basic tariff for each billing zone. Each parameter is a combination of MCC, MNC, cell ID, LAC and MO/MT tariff ID. The billing zone may be set as a cell, a LAC or a zone. Normally a single billing zone deploys only one basic tariff. + Each PPS subscriber profile also contains its tariff setup specifying which tariff should be applied for this subscriber. Using either basic tariff zone (location dependent) or tariff in subscriber profile (subscriber dependent) is determined by a parameter -Tariff subscription-. + LAC: If LAC=65536, all LACs in the MCC and MNC use the same basic tariff. + Cell ID: If cell ID=65536, all cells in the LAC use the same basic tariff. + [End] + " + ::= { Service_Control 10 } + +SRF_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SRF parameters . " + ::= { Configuration 2 } + +SRF_Number OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SRF Number. " + ::= { SRF_Param 1 } + +SRF_0_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]SRF 0 number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: E.164 number of SRF 0 (Special Resource Function) entity. + [End] + " + ::= { SRF_Number 1 } + +SRF_1_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]SRF 1 number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: E.164 number of SRF 1 (Special Resource Function) entity. + [End] + " + ::= { SRF_Number 2 } + +Service_Number OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service number . " + ::= { SRF_Param 2 } + +Hotline OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Hotline + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: PPS service center number. Subscriber dials this number to recharge, enquire their account and modify favorite numbers. + [End] + " + ::= { Service_Number 1 } + +Inquiry OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Inquiry number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated PPS number for account (balance and validity) inquiry. + [End] + " + ::= { Service_Number 2 } + +Scratch_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge via scratch card + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via scratch card. + [End] + " + ::= { Service_Number 3 } + +Credit_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge via credit card + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via credit card. + [End] + " + ::= { Service_Number 4 } + +Third_Party_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge other account + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharging other account from MS or PSTN. + [End] + " + ::= { Service_Number 5 } + +Customer_Care_Center OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Customer care center number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number to connect customer care center. + [End] + " + ::= { Service_Number 6 } + +Rechareg_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via scratch card or credit card. + [End] + " + ::= { Service_Number 7 } + +Service_Key OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service key . " + ::= { SRF_Param 3 } + +Inquiry OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Key for inquiry + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the function key to enquire account balance after entering the PPS service center. + [End] + " + ::= { Service_Key 2 } + +Scratch_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Field: [1]Key for recharging via scratch card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to recharge account via scratch card after entering the PPS service center. + [End] + " + ::= { Service_Key 3 } + +Credit_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Key for recharging via credit card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key for recharging account via credit card after entering the PPS service center. + [End] + " + ::= { Service_Key 4 } + +Set_Favorite_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 04 + Field: [1]Key to set favorite number + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to set favorite number after entering the PPS service center. + [End] + " + ::= { Service_Key 5 } + +Language_Selection OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 05 + Field: [1]Key for language selection + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to select system language (from 5 available candidates) after entering the PPS service center. All announcements in the PPS service center is played in the system language. + [End] + " + ::= { Service_Key 6 } + +SetPasswd OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 06 + Field: [1]PPS account password + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to set account password after entering the PPS service center. When recharging account] selecting language] modifying favorite number or seting password] subscriber is asked to pass the password verification. + [End] + " + ::= { Service_Key 7 } + +File_Operation OBJECT-IDENTITY + STATUS current + DESCRIPTION + " File operation . " + ::= { Configuration 3 } + +Import_User_Data OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Command status + { + [u]00.0-00.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading failed + } + [2]Total number sent + { + [u]01.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]Records loaded + { + [u]04.0-06.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. Progress and result of PPS subscriber import. + Total number sent: Total quantity of PPS subscribers requesting import. + Records loaded: Quantity of successfully imported PPS subscribers. + [End] + " + ::= { File_Operation 1 } + +Import_Recharge_Card OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Import recharge card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. Result of uploading recharge card to PPS. 0=unsuccessful. 1=successful. + [End] + " + ::= { File_Operation 2 } + +New_Tariff_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { File_Operation 3 } + +New_Tariff_Start_Time OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 20050101000000 + Field: [1]Year + { + [u]00.0-01.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]03.0-03.7 + [u]input + [v]keepHex-high-0 + } + [4]Hour + { + [u]04.0-04.7 + [u]input + [v]keepHex-high-0 + } + [5]Minute + { + [u]05.0-05.7 + [u]input + [v]keepHex-high-0 + } + [6]Second + { + [u]06.0-06.7 + [u]input + [v]keepHex-high-0 + } + Remark: Read only. Set start time for new tariff plan. + [End] + " + ::= { File_Operation 4 } + +COS_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS parameters . " + ::= { Configuration 4 } + +COS_0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 0 Parameters. " + ::= { COS_Param 1 } + +Recharge_Promotion_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_0 1 } + +Start_Date_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS0 1 } + +End_Date_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS0 2 } + +Promotion_Bonus_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS0 3 } + +Tariff_Resolution_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_0 2 } + +MO_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS0 1 } + +MT_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS0 2 } + +Tariff_Subscription_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS0 3 } + +Recharge_Card_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS0 4 } + +Account_Control_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_0 3 } + +Min_balance_MO_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS0 1 } + +Maximum_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS0 2 } + +Release_Day_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS0 3 } + +MT_Control_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_0 4 } + +Charge_Flag_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS0 1 } + +Zero_Balance_Control_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS0 2 } + +Validity_Solution_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_0 5 } + +Clear_Balance_Option_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS0 1 } + +Validity_Recharge_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS0 2 } + +Validity_Zero_Balance_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS0 3 } + +Activated_Account_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS0 4 } + +FF_Number_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS0 5 } + +Support_Credit_Card_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS0 + [End] + " + ::= { Validity_Solution_COS0 6 } + +Credit_Vault_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS0 7 } + +SM_Inquiry_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_0 6 } + +Feedback_SM_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS0 1 } + +Inquiry_SM_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS0 2 } + +SM_Expiry_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS0 3 } + +SM_Low_Balance_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS0 4 } + +COS_1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 1 Parameters. " + ::= { COS_Param 2 } + +Recharge_Promotion_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_1 1 } + +Start_Date_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS1 1 } + +End_Date_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS1 2 } + +Promotion_Bonus_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS1 3 } + +Tariff_Resolution_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_1 2 } + +MO_Tariff_ID_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS1 1 } + +MT_Tariff_ID_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS1 2 } + +Tariff_Subscription_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS1 3 } + +Recharge_Card_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS1 4 } + +Account_Control_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_1 3 } + +Min_balance_MO_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS1 1 } + +Maximum_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS1 2 } + +Release_Day_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS1 3 } + +MT_Control_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_1 4 } + +Charge_Flag_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS1 1 } + +Zero_Balance_Control_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS1 2 } + +Validity_Solution_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_1 5 } + +Clear_Balance_Option_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS1 1 } + +Validity_Recharge_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS1 2 } + +Validity_Zero_Balance_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS1 3 } + +Activated_Account_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS1 4 } + +FF_Number_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS1 5 } + +Support_Credit_Card_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS1 6 } + +Credit_Vault_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS1 7 } + +SM_Inquiry_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_1 6 } + +Feedback_SM_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS1 1 } + +Inquiry_SM_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS1 2 } + +SM_Expiry_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS1 3 } + +SM_Low_Balance_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS1 4 } + +COS_2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 2 Parameters. " + ::= { COS_Param 3 } + +Recharge_Promotion_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_2 1 } + +Start_Date_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS2 1 } + +End_Date_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS2 2 } + +Promotion_Bonus_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS2 3 } + +Tariff_Resolution_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_2 2 } + +MO_Tariff_ID_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS2 1 } + +MT_Tariff_ID_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS2 2 } + +Tariff_Subscription_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS2 3 } + +Recharge_Card_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS2 4 } + +Account_Control_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_2 3 } + +Min_balance_MO_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS2 1 } + +Maximum_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS2 2 } + +Release_Day_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS2 3 } + +MT_Control_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_2 4 } + +Charge_Flag_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS2 1 } + +Zero_Balance_Control_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS2 2 } + +Validity_Solution_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_2 5 } + +Clear_Balance_Option_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS2 1 } + +Validity_Recharge_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS2 2 } + +Validity_Zero_Balance_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS2 3 } + +Activated_Account_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS2 4 } + +FF_Number_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Free times of changing: set total times of free change for family number if charge is enabled. Maximum is 15. + [End] + " + ::= { Validity_Solution_COS2 5 } + +Support_Credit_Card_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS2 6 } + +Credit_Vault_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS2 7 } + +SM_Inquiry_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_2 6 } + +Feedback_SM_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS2 1 } + +Inquiry_SM_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS2 2 } + +SM_Expiry_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS2 3 } + +SM_Low_Balance_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS2 4 } + +COS_3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 3 Parameters. " + ::= { COS_Param 4 } + +Recharge_Promotion_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_3 1 } + +Start_Date_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS3 1 } + +End_Date_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS3 2 } + +Promotion_Bonus_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS3 3 } + +Tariff_Resolution_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_3 2 } + +MO_Tariff_ID_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS3 1 } + +MT_Tariff_ID_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS3 2 } + +Tariff_Subscription_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS3 3 } + +Recharge_Card_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS3 4 } + +Account_Control_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_3 3 } + +Min_balance_MO_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS3 1 } + +Maximum_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS3 2 } + +Release_Day_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS3 3 } + +MT_Control_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_3 4 } + +Charge_Flag_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS3 1 } + +Zero_Balance_Control_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS3 2 } + +Validity_Solution_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_3 5 } + +Clear_Balance_Option_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS3 1 } + +Validity_Recharge_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS3 2 } + +Validity_Zero_Balance_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS3 3 } + +Activated_Account_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS3 4 } + +FF_Number_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS3 5 } + +Support_Credit_Card_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS3 6 } + +Credit_Vault_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS3 7 } + +SM_Inquiry_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_3 6 } + +Feedback_SM_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS3 1 } + +Inquiry_SM_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS3 2 } + +SM_Expiry_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS3 3 } + +SM_Low_Balance_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS3 4 } + +COS_4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 4 Parameters. " + ::= { COS_Param 5 } + +Recharge_Promotion_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_4 1 } + +Start_Date_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS4 1 } + +End_Date_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS4 2 } + +Promotion_Bonus_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS4 3 } + +Tariff_Resolution_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_4 2 } + +MO_Tariff_ID_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS4 1 } + +MT_Tariff_ID_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS4 2 } + +Tariff_Subscription_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS4 3 } + +Recharge_Card_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS4 4 } + +Account_Control_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_4 3 } + +Min_balance_MO_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS4 1 } + +Maximum_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS4 2 } + +Release_Day_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS4 3 } + +MT_Control_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_4 4 } + +Charge_Flag_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS4 1 } + +Zero_Balance_Control_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS4 2 } + +Validity_Solution_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_4 5 } + +Clear_Balance_Option_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS4 1 } + +Validity_Recharge_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS4 2 } + +Validity_Zero_Balance_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS4 3 } + +Activated_Account_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS4 4 } + +FF_Number_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS4 5 } + +Support_Credit_Card_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS4 6 } + +Credit_Vault_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS4 7 } + +SM_Inquiry_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_4 6 } + +Feedback_SM_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS4 1 } + +Inquiry_SM_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS4 2 } + +SM_Expiry_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS4 3 } + +SM_Low_Balance_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS4 4 } + +COS_5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 5 Parameters. " + ::= { COS_Param 6 } + +Recharge_Promotion_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_5 1 } + +Start_Date_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS5 1 } + +End_Date_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS5 2 } + +Promotion_Bonus_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS5 3 } + +Tariff_Resolution_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_5 2 } + +MO_Tariff_ID_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS5 1 } + +MT_Tariff_ID_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] Select a MT tariff for this COS. The COS ID is included in subscriber profile for MT call charge. Total 16 MT tariffs available. + " + ::= { Tariff_Resolution_COS5 2 } + +Tariff_Subscription_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS5 3 } + +Recharge_Card_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS5 4 } + +Account_Control_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_5 3 } + +Min_balance_MO_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS5 1 } + +Maximum_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS5 2 } + +Release_Day_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS5 3 } + +MT_Control_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_5 4 } + +Charge_Flag_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS5 1 } + +Zero_Balance_Control_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS5 2 } + +Validity_Solution_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_5 5 } + +Clear_Balance_Option_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS5 1 } + +Validity_Recharge_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS5 2 } + +Validity_Zero_Balance_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS5 3 } + +Activated_Account_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS5 4 } + +FF_Number_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS5 5 } + +Support_Credit_Card_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS5 6 } + +Credit_Vault_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS5 7 } + +SM_Inquiry_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_5 6 } + +Feedback_SM_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS5 1 } + +Inquiry_SM_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS5 2 } + +SM_Expiry_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS5 3 } + +SM_Low_Balance_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS5 4 } + +COS_6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 6 Parameters. " + ::= { COS_Param 7 } + +Recharge_Promotion_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_6 1 } + +Start_Date_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS6 1 } + +End_Date_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS6 2 } + +Promotion_Bonus_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS6 3 } + +Tariff_Resolution_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_6 2 } + +MO_Tariff_ID_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS6 1 } + +MT_Tariff_ID_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS6 2 } + +Tariff_Subscription_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS6 3 } + +Recharge_Card_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS6 4 } + +Account_Control_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_6 3 } + +Min_balance_MO_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS6 1 } + +Maximum_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS6 2 } + +Release_Day_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS6 3 } + +MT_Control_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_6 4 } + +Charge_Flag_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS6 1 } + +Zero_Balance_Control_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS6 2 } + +Validity_Solution_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_6 5 } + +Clear_Balance_Option_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS6 1 } + +Validity_Recharge_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS6 2 } + +Validity_Zero_Balance_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS6 3 } + +Activated_Account_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS6 4 } + +FF_Number_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS6 5 } + +Support_Credit_Card_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS6 6 } + +Credit_Vault_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS6 7 } + +SM_Inquiry_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_6 6 } + +Feedback_SM_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS6 1 } + +Inquiry_SM_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS6 2 } + +SM_Expiry_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS6 3 } + +SM_Low_Balance_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS6 4 } + +COS_7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 7 Parameters. " + ::= { COS_Param 8 } + +Recharge_Promotion_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_7 1 } + +Start_Date_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS7 1 } + +End_Date_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS7 2 } + +Promotion_Bonus_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS7 3 } + +Tariff_Resolution_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_7 2 } + +MO_Tariff_ID_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS7 1 } + +MT_Tariff_ID_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS7 2 } + +Tariff_Subscription_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS7 3 } + +Recharge_Card_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS7 4 } + +Account_Control_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_7 3 } + +Min_balance_MO_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS7 1 } + +Maximum_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS7 2 } + +Release_Day_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS7 3 } + +MT_Control_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_7 4 } + +Charge_Flag_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS7 1 } + +Zero_Balance_Control_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS7 2 } + +Validity_Solution_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_7 5 } + +Clear_Balance_Option_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS7 1 } + +Validity_Recharge_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS7 2 } + +Validity_Zero_Balance_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS7 3 } + +Activated_Account_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS7 4 } + +FF_Number_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS7 5 } + +Support_Credit_Card_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS7 6 } + +Credit_Vault_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS7 7 } + +SM_Inquiry_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_7 6 } + +Feedback_SM_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS7 1 } + +Inquiry_SM_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS7 2 } + +SM_Expiry_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS7 3 } + +SM_Low_Balance_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS7 4 } + +COS_8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 8 Parameters. " + ::= { COS_Param 9 } + +Recharge_Promotion_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_8 1 } + +Start_Date_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS8 1 } + +End_Date_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS8 2 } + +Promotion_Bonus_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS8 3 } + +Tariff_Resolution_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_8 2 } + +MO_Tariff_ID_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS8 1 } + +MT_Tariff_ID_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS8 2 } + +Tariff_Subscription_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS8 3 } + +Recharge_Card_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS8 4 } + +Account_Control_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_8 3 } + +Min_balance_MO_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS8 1 } + +Maximum_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS8 2 } + +Release_Day_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS8 3 } + +MT_Control_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_8 4 } + +Charge_Flag_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS8 1 } + +Zero_Balance_Control_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS8 2 } + +Validity_Solution_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_8 5 } + +Clear_Balance_Option_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS8 1 } + +Validity_Recharge_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS8 2 } + +Validity_Zero_Balance_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS8 3 } + +Activated_Account_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS8 4 } + +FF_Number_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS8 5 } + +Support_Credit_Card_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS8 6 } + +Credit_Vault_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS8 7 } + +SM_Inquiry_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_8 6 } + +Feedback_SM_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS8 1 } + +Inquiry_SM_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS8 2 } + +SM_Expiry_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS8 3 } + +SM_Low_Balance_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS8 4 } + +COS_9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 9 Parameters. " + ::= { COS_Param 10 } + +Recharge_Promotion_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_9 1 } + +Start_Date_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS9 1 } + +End_Date_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS9 2 } + +Promotion_Bonus_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS9 3 } + +Tariff_Resolution_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_9 2 } + +MO_Tariff_ID_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS9 1 } + +MT_Tariff_ID_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS9 2 } + +Tariff_Subscription_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS9 3 } + +Recharge_Card_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS9 4 } + +Account_Control_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_9 3 } + +Min_balance_MO_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS9 1 } + +Maximum_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS9 2 } + +Release_Day_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS9 3 } + +MT_Control_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_9 4 } + +Charge_Flag_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS9 1 } + +Zero_Balance_Control_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS9 2 } + +Validity_Solution_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_9 5 } + +Clear_Balance_Option_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS9 1 } + +Validity_Recharge_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS9 2 } + +Validity_Zero_Balance_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS9 3 } + +Activated_Account_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS9 4 } + +FF_Number_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS9 5 } + +Support_Credit_Card_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS9 6 } + +Credit_Vault_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS9 7 } + +SM_Inquiry_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_9 6 } + +Feedback_SM_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS9 1 } + +Inquiry_SM_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS9 2 } + +SM_Expiry_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS9 3 } + +SM_Low_Balance_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS9 4 } + +COS_10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 10 Parameters. " + ::= { COS_Param 11 } + +Recharge_Promotion_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_10 1 } + +Start_Date_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS10 1 } + +End_Date_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS10 2 } + +Promotion_Bonus_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS10 3 } + +Tariff_Resolution_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_10 2 } + +MO_Tariff_ID_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS10 1 } + +MT_Tariff_ID_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS10 2 } + +Tariff_Subscription_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS10 3 } + +Recharge_Card_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS10 4 } + +Account_Control_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_10 3 } + +Min_balance_MO_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS10 1 } + +Maximum_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS10 2 } + +Release_Day_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS10 3 } + +MT_Control_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_10 4 } + +Charge_Flag_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS10 1 } + +Zero_Balance_Control_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS10 2 } + +Validity_Solution_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_10 5 } + +Clear_Balance_Option_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS10 1 } + +Validity_Recharge_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS10 2 } + +Validity_Zero_Balance_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS10 3 } + +Activated_Account_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS10 4 } + +FF_Number_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS10 5 } + +Support_Credit_Card_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS10 6 } + +Credit_Vault_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS10 7 } + +SM_Inquiry_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_10 6 } + +Feedback_SM_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS10 1 } + +Inquiry_SM_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS10 2 } + +SM_Expiry_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS10 3 } + +SM_Low_Balance_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS10 4 } + +COS_11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 11 Parameters. " + ::= { COS_Param 12 } + +Recharge_Promotion_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_11 1 } + +Start_Date_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS11 1 } + +End_Date_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS11 2 } + +Promotion_Bonus_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS11 3 } + +Tariff_Resolution_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_11 2 } + +MO_Tariff_ID_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS11 1 } + +MT_Tariff_ID_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS11 2 } + +Tariff_Subscription_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS11 3 } + +Recharge_Card_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS11 4 } + +Account_Control_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_11 3 } + +Min_balance_MO_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS11 1 } + +Maximum_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS11 2 } + +Release_Day_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS11 3 } + +MT_Control_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_11 4 } + +Charge_Flag_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS11 1 } + +Zero_Balance_Control_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS11 2 } + +Validity_Solution_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_11 5 } + +Clear_Balance_Option_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS11 1 } + +Validity_Recharge_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS11 2 } + +Validity_Zero_Balance_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS11 3 } + +Activated_Account_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS11 4 } + +FF_Number_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS11 5 } + +Support_Credit_Card_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS11 6 } + +Credit_Vault_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS11 7 } + +SM_Inquiry_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_11 6 } + +Feedback_SM_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS11 1 } + +Inquiry_SM_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS11 2 } + +SM_Expiry_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS11 3 } + +SM_Low_Balance_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS11 4 } + +COS_12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 12 Parameters. " + ::= { COS_Param 13 } + +Recharge_Promotion_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_12 1 } + +Start_Date_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS12 1 } + +End_Date_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS12 2 } + +Promotion_Bonus_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS12 3 } + +Tariff_Resolution_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_12 2 } + +MO_Tariff_ID_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS12 1 } + +MT_Tariff_ID_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS12 2 } + +Tariff_Subscription_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS12 3 } + +Recharge_Card_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS12 4 } + +Account_Control_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_12 3 } + +Min_balance_MO_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS12 1 } + +Maximum_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS12 2 } + +Release_Day_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS12 3 } + +MT_Control_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_12 4 } + +Charge_Flag_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS12 1 } + +Zero_Balance_Control_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS12 2 } + +Validity_Solution_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_12 5 } + +Clear_Balance_Option_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS12 1 } + +Validity_Recharge_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS12 2 } + +Validity_Zero_Balance_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS12 3 } + +Activated_Account_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS12 4 } + +FF_Number_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS12 5 } + +Support_Credit_Card_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS12 6 } + +Credit_Vault_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS12 7 } + +SM_Inquiry_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_12 6 } + +Feedback_SM_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS12 1 } + +Inquiry_SM_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS12 2 } + +SM_Expiry_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS12 3 } + +SM_Low_Balance_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS12 4 } + +COS_13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 13 Parameters. " + ::= { COS_Param 14 } + +Recharge_Promotion_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_13 1 } + +Start_Date_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS13 1 } + +End_Date_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS13 2 } + +Promotion_Bonus_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS13 3 } + +Tariff_Resolution_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_13 2 } + +MO_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS13 1 } + +MT_Tariff_ID_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS13 2 } + +Tariff_Subscription_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS13 3 } + +Recharge_Card_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS13 4 } + +Account_Control_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_13 3 } + +Min_balance_MO_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS13 1 } + +Maximum_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS13 2 } + +Release_Day_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS13 3 } + +MT_Control_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_13 4 } + +Charge_Flag_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS13 1 } + +Zero_Balance_Control_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS13 2 } + +Validity_Solution_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_13 5 } + +Clear_Balance_Option_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS13 1 } + +Validity_Recharge_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS13 2 } + +Validity_Zero_Balance_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS13 3 } + +Activated_Account_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS13 4 } + +FF_Number_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS13 5 } + +Support_Credit_Card_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS13 6 } + +Credit_Vault_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS13 7 } + +SM_Inquiry_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_13 6 } + +Feedback_SM_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS13 1 } + +Inquiry_SM_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS13 2 } + +SM_Expiry_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS13 3 } + +SM_Low_Balance_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS13 4 } + +COS_14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 14 Parameters. " + ::= { COS_Param 15 } + +Recharge_Promotion_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_14 1 } + +Start_Date_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS14 1 } + +End_Date_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS14 2 } + +Promotion_Bonus_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS14 3 } + +Tariff_Resolution_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_14 2 } + +MO_Tariff_ID_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS14 1 } + +MT_Tariff_ID_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS14 2 } + +Tariff_Subscription_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS14 3 } + +Recharge_Card_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS14 4 } + +Account_Control_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_14 3 } + +Min_balance_MO_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS14 1 } + +Maximum_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS14 2 } + +Release_Day_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS14 3 } + +MT_Control_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_14 4 } + +Charge_Flag_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS14 1 } + +Zero_Balance_Control_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS14 2 } + +Validity_Solution_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_14 5 } + +Clear_Balance_Option_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS14 1 } + +Validity_Recharge_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS14 2 } + +Validity_Zero_Balance_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS14 3 } + +Activated_Account_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS14 4 } + +FF_Number_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS14 5 } + +Support_Credit_Card_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS14 6 } + +Credit_Vault_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS14 7 } + +SM_Inquiry_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_14 6 } + +Feedback_SM_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS14 1 } + +Inquiry_SM_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS14 2 } + +SM_Expiry_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS14 3 } + +SM_Low_Balance_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS14 4 } + +COS_15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 15 Parameters. " + ::= { COS_Param 16 } + +Recharge_Promotion_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_15 1 } + +Start_Date_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS15 1 } + +End_Date_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS15 2 } + +Promotion_Bonus_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS15 3 } + +Tariff_Resolution_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_15 2 } + +MO_Tariff_ID_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS15 1 } + +MT_Tariff_ID_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS15 2 } + +Tariff_Subscription_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS15 3 } + +Recharge_Card_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS15 4 } + +Account_Control_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_15 3 } + +Min_balance_MO_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS15 1 } + +Maximum_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS15 2 } + +Release_Day_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS15 3 } + +MT_Control_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_15 4 } + +Charge_Flag_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS15 1 } + +Zero_Balance_Control_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS15 2 } + +Validity_Solution_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_15 5 } + +Clear_Balance_Option_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS15 1 } + +Validity_Recharge_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS15 2 } + +Validity_Zero_Balance_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS15 3 } + +Activated_Account_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS15 4 } + +FF_Number_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS15 5 } + +Support_Credit_Card_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS15 6 } + +Credit_Vault_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS15 7 } + +SM_Inquiry_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_15 6 } + +Feedback_SM_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS15 1 } + +Inquiry_SM_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS15 2 } + +SM_Expiry_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS15 3 } + +SM_Low_Balance_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS15 4 } + +Call_Routing_VMS OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Call routing to VMS . " + ::= { Configuration 5 } + +VMS_PLMN_Maintenance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS service number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 1 } + +VMS_PSTN_Maintenance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS service number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 2 } + +--VMS_Deposit_Number OBJECT-TYPE +-- SYNTAX OCTET STRING +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- " Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. +-- " +-- ::= { Call_Routing_VMS 3 } + +VMS_leave_msg_No OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS deposit number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 3 } + +--Access_VoiceBox OBJECT-TYPE +-- SYNTAX OCTET STRING +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- " Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. +-- " +-- ::= { Call_Routing_VMS 4 } + +Rule OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Route by + { + [u]00.0-00.0 + [u]select + [v]0[opt]Prefix + [v]1[opt]Whole number + } + [2]Route + { + [u]00.1-00.1 + [u]select + [v]0[opt]Caller number + [v]1[opt]Called number + } + [3]Reserved + { + [u]00.2-00.7 + [u]input + [v]toDec-high-0 + } + Remark: rule + [End] + " + ::= { Call_Routing_VMS 4 } + +VMS_User_Segments OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 80 + Default: 3836373535393030303030000000000038363735353939393939390000000000383637353539393830300000000000003836373535393938303100000000000038363735353939383032000000000000 + Field: [1]Start MSISDN + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + [2]End MSISDN + { + [u]16.0-31.7 + [u]input + [v]toAscii-low-0 + } + [3]VMS service number - PLMN + { + [u]32.0-47.7 + [u]input + [v]toAscii-low-0 + } + [4]VMS service number - PSTN + { + [u]48.0-63.7 + [u]input + [v]toAscii-low-0 + } + [5]Leave message deposit number + { + [u]64.0-79.7 + [u]input + [v]toAscii-low-0 + } + Remark: VMS user segments + [End] + " + ::= { Call_Routing_VMS 5 } + +Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Status. " + ::= { Configuration 6 } + +Activation OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]System status + { + [u]00.0-00.7 + [u]select + [v]0[opt]Normal + } + Remark: Set PPS system status. 0=normal. After initial PPS installation, if the PPS system doesn't has subscriber profiles, its status is suspended. In this case operator may set this parameter (normal) to activate the PPS server. + [End] + " + ::= { Status 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag : S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]1[opt]Save parameters + [v]2[opt]Save user data + } + Remark: PPS management command. + Save parameters: Save PPS parameters in PPS memory to PPS hard disk. + Save user data: Save PPS subscriber data in PPS memory to PPS hard disk. + [End] + " + ::= { Status 2 } + +END \ No newline at end of file diff --git a/mss/main/conf/MIB_files/WXC2-SMI.txt b/mss/main/conf/MIB_files/WXC2-SMI.txt new file mode 100644 index 0000000..4841a50 --- /dev/null +++ b/mss/main/conf/MIB_files/WXC2-SMI.txt @@ -0,0 +1,57 @@ +-- ***************************************************************** +-- WXC2-SMI: WXC2 Structure of Management Information +-- +-- draft November 2000, Huang qilong +-- 1st November 2004, Sheng Xueqiang +-- +-- Copyright (c) 2004 by interWAVE, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- + +WXC2-SMI DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, + OBJECT-IDENTITY, + FROM SNMPv2-SMI + IWV_Products + FROM IWV-SMI; + +WXC2 MODULE-IDENTITY + LAST-UPDATED "200506050000Z" + ORGANIZATION "interWAVE, Inc." + CONTACT-INFO + "http://www.iwv.com" + DESCRIPTION + "The Structure of Management Information for the WXC2 of interWAVE enterprise." + REVISION "200506050000Z" + DESCRIPTION + "1st version of this MIB module." + ::= { IWV_Products 3 } + +-- WXC2_PCM +PCM OBJECT-IDENTITY + STATUS current + DESCRIPTION + "PCM " + ::= { WXC2 1 } + + +-- WXC2_platform +Platform OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Platform " + ::= { WXC2 2 } + +-- WXC2_App + +App OBJECT-IDENTITY + STATUS current + DESCRIPTION + "App platform" + ::= { WXC2 3 } + +END diff --git a/mss/main/conf/MIB_files/WXC2-SMSC-MIB.txt b/mss/main/conf/MIB_files/WXC2-SMSC-MIB.txt new file mode 100644 index 0000000..d6a5a82 --- /dev/null +++ b/mss/main/conf/MIB_files/WXC2-SMSC-MIB.txt @@ -0,0 +1,259 @@ +WXC2-SMSC-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +SMSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "[SubSystem_Module]Subsystems for SMSC . " + ::= { App 5 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for SMSC . " + ::= { SMSC 2 } + +System_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " system parameter . " + ::= { Configuration 1 } + + + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]SMSC CDR + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [2]SMSC LOG + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [3]Reserved + { + [u]0.2-0.7 + [u]select + } + + Remark: SMSC CDR generation enable or disable. + [End] + " + ::= { System_Param 1 } + +SM_Validity OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 0000A8C0 + Field: [1]SM validity + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Period of validity of short message, define a threshold how long an awaiting sending message should be kept in sending array till sent to MS, unit is second, default=0c0a8h seconds=12 hours. + [End] + " + ::= { System_Param 2 } + +MSISDN_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 16 + Length: 19 + Default: 8675557127000EEEEE8675557127999EEEEE00 + Field: [1]Start MSISDN + { + [u]00.0-08.7 + [u]input + [v]keepHex-low-E + } + [2]End MSISDN + { + [u]09.0-17.7 + [u]input + [v]keepHex-low-E + } + [3]Number Type + { + [u]18.0-18.7 + [u]select + [v]0[opt]GSM + [v]1[opt]CDMA + } + Remark: Specify the beginning MSISDN for the range of provisioned subscriber. F=end tag. + [End] + " + ::= { System_Param 3 } + +SMPP_parameters OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 32 + Length: 12 + Default: 000000000000000000000000 + Field: [1]Enable flag + { + [u]00.0-00.7 + [u]select + [v]00[opt]Disable + [v]01[opt]Enable + } + [2]Session type + { + [u]01.0-01.7 + [u]select + [v]00[opt]BIND_TX + [v]01[opt]BIND_RX + [v]02[opt]BIND_TRX + } + [3]Service number + { + [u]02.0-9.7 + [u]input + [v]toAscii-low-0 + } + [4]Message mode + { + [u]10.0-10.7 + [u]select + [v]00[opt]Store and forward + [v]01[opt]Datagram + [v]02[opt]Transaction + } + [5]Data Coding Scheme + { + [u]11.0-11.7 + [u]select + [v]00[opt]To smpp=7bit,default=7bit + [v]01[opt]To smpp=8bit,default=7bit + [v]16[opt]To smpp=7bit,default=8bit + [v]17[opt]To smpp=8bit,default=8bit + } + Remark: Name: Can be any name, generally use the name of the connected device. + Service number: SMPP connected party MSISDN used for display on MT MS, + e.g. for a SMPP to PPS, set the service number as MSISDN of PPS. + Data coding scheme: + 00:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 7bit + 01:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 7bit + 10:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 8bit + 11:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 8bit + Default=0. + [End] + " + ::= { Configuration 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management for SMSC . + " + ::= { SMSC 3 } + +SMSC_ID OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]SMSC ID + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-E + } + Remark: SMSC ID + [End] + " + ::= { Management 1 } + +Software_Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Version + { + [u]00.0-02.7 + [u]input + [v]keepHex-low-E + } + Remark: Software version + [End] + " + ::= { Management 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Flag: S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]01[opt]Save parameters + [v]04[opt]Reset system + [v]05[opt]Delete pending SM + } + Remark: SMSC system command. + Save parameters: Save the SMSC parameters in memory to SMSC harddisk. + Delete pending SM: Delete the pending SM in awaiting array. + [End] + " + ::= { Management 3 } + + + +END diff --git a/mss/main/conf/MIB_files/WXC2-SS7-MIB.txt b/mss/main/conf/MIB_files/WXC2-SS7-MIB.txt new file mode 100644 index 0000000..a642454 --- /dev/null +++ b/mss/main/conf/MIB_files/WXC2-SS7-MIB.txt @@ -0,0 +1,3729 @@ +WXC2-SS7-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + Platform + FROM WXC2-SMI; + +SS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for SS7 . + " + ::= { Platform 2 } + + +-- +-- sub system MTP3 +-- + +MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for MTP3 . + " + ::= { SS7 2 } + +Config_MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MTP3 Configuration. " + ::= { MTP3 2 } + +Network_Indicator OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]International network + { + [u]0.0-0.0 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [2]International network spare + { + [u]0.1-0.1 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [3]National network + { + [u]0.2-0.2 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [4]National network spare + { + [u]0.3-0.3 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [5]International network + { + [u]0.4-0.4 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [6]International network spare + { + [u]0.5-0.5 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [7]National network + { + [u]0.6-0.6 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [8]National network spare + { + [u]0.7-0.7 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + Remark: MTP3 network indicator. + [End] + " + ::= { Config_MTP3 2 } + + + + +OPC OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Originating point code. " + ::= { Config_MTP3 3 } + +International_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 1 } + +International_Spare_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 2 } + +National_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 3 } + +National_Spare_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 4 } + +International_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 5 } + +International_Spare_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 6} + +National_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 7 } + +National_Spare_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 8 } + +Linkset OBJECT-IDENTITY + STATUS current + DESCRIPTION + " linkset. " + ::= { Config_MTP3 4 } + +Linkset_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 4 + Default: 00000000 + Field: [1]Linkset DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Network indicator + { + [u]3.0-3.1 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [3]Reserved + { + [u]3.2-3.2 + [u]select + } + [4]Linkset loopback + { + [u]3.3-3.3 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [5]Reserved + { + [u]3.4-3.7 + [u]select + } + Remark: Opposite point code: The opposite point code of the linkset. + Network indicator: The network type of the opposite point code. + Loop back: Loop back enable or disable, used for MSC loop back link. + [End] + " + ::= { Linkset 1 } + +Link OBJECT-IDENTITY + STATUS current + DESCRIPTION + " link. " + ::= { Config_MTP3 5 } + +Link_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 15 + Default: 8010FFFFFFFF000000000000000000 + Field: [1]Linkset no. + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + [2]SLC no. + { + [u]01.0-01.7 + [u]input + [v]toDec-high-0 + } + [3]CPC IP + { + [u]02.0-05.7 + [u]input + [v]keepHex-high-0 + } + [4]Link Type + { + [u]06.0-06.0 + [u]select + [v]0[opt]Non-sigtran + [v]1[opt]Sigtran + } + [5]Link Enable + { + [u]06.1-06.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [6]MTP3-Lite Enable + { + [u]06.2-06.2 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [7]Reserved + { + [u]06.3-06.7 + [u]select + } + [8]SG no. + { + [u]07.0-07.7 + [u]input + [v]toDec-high-0 + } + [9]M2UA Interface ID + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + [10]MTP3-Lite Remote IP + { + [u]09.0-12.7 + [u]input + [v]keepHex-high-0 + } + [11]MTP3-Lite Inactivity Timeout + { + [u]13.0-13.7 + [u]input + [v]toDec-high-0 + } + [12]MTP3-Lite Allowed Inactivity Timeouts + { + [u]14.0-14.7 + [u]input + [v]toDec-high-0 + } + Remark: E1 link attributes. + Linkset no.: Assign linkset to E1 link, MSC has up to 128 linksets (0-127). 128=TCH E1. + SLC no.: Assign SLC to each E1 link of a linkset, each linkset has up to 13 E1 links (0-15). + IP: E1 link management IP. The third byte of CPC IP: + 98=E1 link 0-127, 99=E1 link 128-255. + Default=0x000032. + [End] + " + ::= { Link 1 } + +Link_Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 01 + Field: [1]E1 link + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + [v]2[opt]Inhibit + [v]3[opt]Uninhibit + } + Remark: Used for E1 link control, not affect call traffic. + Disable=Disable E1 link MTP2 layer. + Enable=Enable a disabled E1 link MTP2 layer. + Inhibit=Inhibit E1 link MTP3 layer. + Uninhibit=Uninhibit a inhibited E1 link MTP3 layer. + Default=Enable a disabled E1 link MTP2 layer. + [End] + " + ::= { Link 2 } + +TCP_Port OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-writed + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1388 + Field: [1]TCP Port + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + Remark: TCP server port for SCCP-Lite. + [End] + " + ::= { Link 3 } + +Routing OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Routing. " + ::= { Config_MTP3 6 } + +International OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 1 } + +International_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 2 } + +National OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 3 } + +National_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 4 } + +SPC_to_ACN OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SPC to ACN. " + ::= { Config_MTP3 7 } + +Local_ACN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 1 } + +International OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 2 } + +International_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 3 } + +National OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 4 } + +National_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 5 } + +Signaling_Gateway OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 7 + Default: 00000000000000 + Field: [1]Enable + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Server + { + [u]01.0-01.7 + [u]select + [v]0[opt]Client + [v]1[opt]Server + } + [3]ACK + { + [u]02.0-02.7 + [u]select + [v]0[opt]no ACK + [v]1[opt]ACK + } + [4]IP + { + [u]03.0-06.7 + [u]input + [v]keepHex-high-0 + } + Remark: SG attributes + [End] + " + ::= { Config_MTP3 9 } + +Status_MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MTP3 Status. " + ::= { MTP3 3 } + +Link_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 01 + Field: [1]Link status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Inhibited + } + Remark: E1 link MTP3 status (Read Only). + [End] + " + ::= { Status_MTP3 1 } + +Linkset_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 1 + Default: 01 + Field: [1]Linkset status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Reserved + } + Remark: Linkset status (Read only). + [End] + " + ::= { Status_MTP3 2 } + +International_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8A + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 3 } + +International_Spare_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 4 } + +National_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 5 } + +National_Spare_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 6 } + + + +Command_MTP3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag :S1.3 + Field: [1]command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No command + [v]1[opt]Reset + [v]2[opt]Save parameter + } + Remark: Control command for MTP3 platform. + Reset=status initialization. + Save parameter=save parameters residing in memory into harddisk. + [End] + " + ::= { Status_MTP3 7 } + +-- +-- sub system SCCP +-- + +SCCP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for SCCP . + " + ::= { SS7 3 } + +Config_SCCP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SCCP Configuration. " + ::= { SCCP 2 } + +Local_Node OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Local Node. " + ::= { Config_SCCP 1 } + +OMC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: OMC E.134 number. + IP0: OMC0 IP, 172.18.128.1. + IP1: OMC1 IP, 172.18.129.1. + [End] + " + ::= { Local_Node 4 } + +HLR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: HLR E.134 number. + IP0: HLR0 IP, 172.18.98.1. + IP1: HLR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 6 } + +VLR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VLR E.134 number. + IP0: VLR0 IP, 172.18.98.1. + IP1: VLR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 7 } + +MSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: MSC E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 8 } + +EIR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: EIR E.134 number. + IP0: EIR0 IP, 172.18.98.1. + IP1: EIR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 9 } + +AUC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: AUC E.134 number. + IP0: AUC0 IP, 172.18.98.1. + IP1: AUC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 10 } + +SMSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: SMSC E.134 number. + IP0: OMC0 IP, 172.18.98.1. + IP1: OMC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 11 } + +SMPP_EMSE OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VMS-SMPP E.134 number. + IP0: VMS0 IP, 172.18.147.1. + IP1: VMS1 IP, 172.18.148.1. + [End] + " + ::= { Local_Node 19 } + +SMPP_SMSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: SMSC-SMPP E.134 number. + IP0: SMSC0 IP, 172.18.98.1. + IP1: SMSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 20 } + +SMPP_OMC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: OMC-SMPP E.134 number. + IP0: OMC0 IP, 172.18.128.1. + IP1: OMC1 IP, 172.18.129.1. + [End] + " + ::= { Local_Node 21 } + +SRF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VMS SRF E.134 number. + IP0: VMS0 IP, 172.18.147.1. + IP1: VMS1 IP, 172.18.148.1. + [End] + " + ::= { Local_Node 22 } + +SSF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: MSC SSF E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 143 } + +SCF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: PPS SCF E.134 number. + IP0: PPS0 IP, 172.18.98.1. + IP1: PPS1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 147 } + +AIF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: AIF E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 254 } + +GTT_Table OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 43 + Default: 000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000007000000FFFFFFFFFFFFFFFFFFFF + Field: [1]On/off + { + [u]00.0-00.7 + [u]select + [v]1[opt]On + [v]0[opt]Off + } + [2]Numbering plan + { + [u]01.0-01.7 + [u]select + [v]0[opt]0 + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } + [3]TT + { + [u]02.0-02.7 + [u]input + [v]keepHex-low-F + } + [4]Start GT number + { + [u]03.0-12.7 + [u]input + [v]keepHex-low-F + } + [4]End GT number + { + [u]13.0-22.7 + [u]input + [v]keepHex-low-F + } + [5]Network indicator + { + [u]23.0-23.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + } + [6]DPC + { + [u]24.0-26.7 + [u]input + [v]toDec-high-0 + } + [7]SSN + { + [u]27.0-27.7 + [u]input + [v]toDec-high-0 + } + [8]Route indicator + { + [u]28.0-28.7 + [u]select + [v]0[opt]Route on GT + [v]1[opt]Route on SSN + } + [9]Address indicator + { + [u]29.0-29.7 + [u]select + [v]0[opt]NULL + [v]3[opt]DPC+SSN + [v]6[opt]GT+SSN + [v]7[opt]GT+DPC+SSN + } + [10]Replaced start digit + { + [u]30.0-30.7 + [u]input + [v]keepHex-high-0 + } + [11]Replaced end digit + { + [u]31.0-31.7 + [u]input + [v]keepHex-high-0 + } + [12]Outgoing number plan + { + [u]32.0-32.7 + [u]select + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } + [13]Replacing digits + { + [u]33.0-42.7 + [u]input + [v]keepHex-low-F + } + Remark: On/off: GTT flag, off=disable, on=enable. + Numbering plan: 1=MSISDN, 3=IMSI, 7=GT. + Specify the beginning number of a group of consecutive numbers routed by GTT, for single-number GTT route, the start number is same as the end number. + End GT number: Specify the end number of a group of consecutive number routed by GT. If there are some inconsecutive numbers for a same destination, a different GTT record should be set. + Network indicator (NI): 0=International network, 1=International network spare, 2=National network, 3=National network spare, + DPC: Destination point code. + SSN: Subsystem number. + 2=Reserved for ITU-T allocation. + 3=ISDN user part. + 4=OMC. + 5=MAP. + 3=HLR. + 7=VLR. + 8=MSC. + 9=EIR. + 10=AUC. + 11=SMSC. + 147=PPS. + 254=BSSMAP. + Route indicator: For IMSI and MSISDN, select Route on SSN. For the record of the connected network, select Route on GT. + Address indicator: select the contribution of SCCP Address. + Replaced start digit: Specify the beginning digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. + Replaced end digit: Specify the end digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. + Outgoing number plan: Outgoing number plan, include MSISDN, IMSI and GT. + Replacing digits: Replacing digits, the length of replacing digits and replaced digits may be different. + [End] + " + ::= { Config_SCCP 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Management. " + ::= { SCCP 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: + Remark: Version of SCCP platform software (Read Only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { Management 1 } + +Command_SCCP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag : S1.2 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]0[opt]Reset + [v]2[opt]Save parameters + } + Remark: Control command for SCCP. + Reset: Used for SCCP status initialization. + Load parameter: Load the parameters from device's harddisk to device's memory. + Save parameter: Save the parameters residing in device's memory into device's harddisk. + [End] + " + ::= { Management 2 } + +-- +-- sub system XAPP +-- + +XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for XAPP . + " + ::= { SS7 5 } + +Config_XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Configuration. " + ::= { XAPP 2 } + +MCC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 460E + Field: [1]MCC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + + Remark: Mobile country code. + [End] + " + ::= { Config_XAPP 1 } + +MNC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Field: [1]MNC + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-E + } + Remark: Mobile network code. + [End] + " + ::= { Config_XAPP 2 } + +CC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 86EE + Field: [1]CC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + Remark: Country code. + [End] + " + ::= { Config_XAPP 3 } + +NDC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 755EEE + Field: [1]NDC + { + [u]00.0-02.7 + [u]input + [v]keepHex-low-E + } + Remark: National destination code. + [End] + " + ::= { Config_XAPP 4 } + +International_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 00ee + Field: [1]International prefix + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + Remark: International call prefix. + [End] + " + ::= { Config_XAPP 5 } + +National_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0EEE + Field: [1]National prefix + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + + Remark: National call prefix. + [End] + " + ::= { Config_XAPP 6 } + +Local_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: EEEE + Field: + Remark: Local prefix. + [End] + " + ::= { Config_XAPP 7 } + +Conv_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 35 + Default: 0000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]Prefix + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + [2]Delete length + { + [u]16.0-16.7[u]input + [v]toDec-high-0 + } + [3]Add length + { + [u]17.0-17.7 + [u]input + [v]toDec-high-0 + } + [4]Add digits + { + [u]18.0-33.7 + [u]input + [v]toAscii-low-0 + } + [5]Valid length + { + [u]34.0-34.7 + [u]input + [v]toDec-high-0 + } + Remark: Conv prefix . + [End] + " + ::= { Config_XAPP 8 } + +CLI_Conv_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 37 + Default: 0000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]In property + { + [u]00.0-00.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } + [2]Prefix + { + [u]01.0-16.7 + [u]input + [v]toAscii-low-0 + } + [3]Delete length + { + [u]17.0-17.7 + [u]input + [v]toDec-high-0 + } + [4]Out property + { + [u]18.0-18.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } + [5]Add length + { + [u]19.0-19.7 + [u]input + [v]toDec-high-0 + } + [6]Add digits + { + [u]20.0-35.7 + [u]input + [v]toAscii-low-0 + + } + [7]Valid length + { + [u]36.0-36.7 + [u]input + [v]toDec-high-0 + } + Remark: CLI_Conv prefix . + [End] + " + ::= { Config_XAPP 9 } + +mscid_to_number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 12 + Default: 00000000EEEEEEEEEEEEEEEE + Field: + + [1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + [2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + [3]SSN + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [4]Number + { + [u]04.0-11.7 + [u]input + [v]keepHex-low-E + } + Remark: Conv prefix . + [End] + " + ::= { Config_XAPP 10 } + +Status_XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Status. " + ::= { XAPP 3 } + +Version_XAPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: + Remark: Version of XAPP module (Read Only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { Status_XAPP 1 } + +Command_XAPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag: S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]01[opt]Save parameters + } + Remark: Control command for XAPP. + Save parameter: Save the parameters in memory into local harddisk. + [End] + " + ::= { Status_XAPP 2 } + +Maplat OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for Maplat . + " + ::= { Platform 3 } +-- +-- sub system SMPP +-- + +SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for SMPP . + " + ::= { Maplat 4 } + +Config_SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SMPP Configuration. " + ::= { SMPP 2 } +SMPP_Link_Parameter OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 32 + Length: 106 + Default: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field:[1]Link enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Link type + { + [u]1.0-1.7 + [u]select + [v]0[opt]UDP + [v]1[opt]TCP + } + [3]Server type + { + [u]2.0-2.7 + [u]select + [v]0[opt]SMPP_CLIENT + [v]1[opt]SMPP_SERVER + } + [4]Session type + { + [u]3.0-3.7 + [u]select + [v]00[opt]BIND_TX + [v]01[opt]BIND_RX + [v]02[opt]BIND_TRX + } + [5]System ID + { + [u]4.0-19.7 + [u]input + [v]toAscii-low-0 + } + [6]Password + { + [u]20.0-28.7 + [u]input + [v]toAscii-low-0 + } + [7]System type + { + [u]29.0-41.7 + [u]input + [v]toAscii-low-0 + } + [8]Local GTT + { + [u]42.0-57.7 + [u]input + [v]toAscii-low-0 + } + [9]Remote GTT + { + [u]58.0-73.7 + [u]input + [v]toAscii-low-0 + } + [10]Local IP + { + [u]74.0-77.7 + [u]input + [v]keepHex-low-F + } + [11]Remote IP + { + [u]78.0-81.7 + [u]input + [v]keepHex-low-F + } + [12]Session init timer + { + [u]82.0-85.7 + [u]input + [v]toDec-high-0 + } + [13]Enquire link timer + { + [u]86.0-89.7 + [u]input + [v]toDec-high-0 + } + [14]Inactivity timer + { + [u]90.0-93.7 + [u]input + [v]toDec-high-0 + } + [15]Response timer + { + [u]94.0-97.7 + [u]input + [v]toDec-high-0 + } + [16]Remote service number + { + [u]98.0-105.7 + [u]input + [v]toAscii-low-0 + } + + Remark: Session type: BIND_TX-bind as transmitter, BIND_RX-bind as receiver, BIND_TRX-bind as transceiver. + System ID: using in BIND and OUTBIND. + Password: The password parameter is used by the SMSC to authenticate the identity of the binding ESME. The Service Provider may require ESME¡¯s to provide a password when binding to the SMSC. This password is normally issued by the SMSC system administrator. + The password parameter may also be used by the ESME to authenticate the identity of the binding SMSC (e.g. in the case of the outbind operation). + System type: The system_type may be used to categorise the system, e.g., ¡°EMAIL¡±, ¡°WWW¡±, etc. + The system_type parameter is used to categorize the type of ESME that is binding to the SMSC. Examples include ¡°VMS¡± (voice mail system) and ¡°OTA¡± (over-the-air activation system). + Specification of the system_type is optional - some SMSC¡¯s may not require ESME¡¯s to provide this detail. In this case, the ESME can set the system_type to NULL. + IP: Specify the IP addresses of 16 SMPP connected devices.
e.g. 0xAC127001=172.18.112.1.
+ Session init timer: This timer specifies the time lapse allowed between a network connection being established and a bind_transmitter or bind_receiver request being sent to SMSC. This timer should be active on the SMSC. + Enquire link timer: This timer specifies the time lapse allowed between operations after which an SMPP entity should interrogate whether it's peer still has an active session. + The scale is second. + Inactivity timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) + Response timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) + Local service number: compare with application's service number while bind as TX or TRX. + remote service number: compare with application's service number while bind as RX + [End] + " + ::= { Config_SMPP 1 } + + +Status_SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Status. " + ::= { SMPP 3 } + +Command_SMPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Flag :S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]2[opt]save parameter + } + Remark: Control command for SMPP. + [End] + " + ::= { Status_SMPP 2 } + + +END diff --git a/mss/main/conf/MIB_files/menu_page b/mss/main/conf/MIB_files/menu_page new file mode 100644 index 0000000..f7d1b26 --- /dev/null +++ b/mss/main/conf/MIB_files/menu_page @@ -0,0 +1,13 @@ + + ******************* + * Module Page * + ******************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- PPS + d -- TCAP l -- SNMP + e -- XAPP m -- M2UA + f -- MSC n -- DEBUG + g -- VLR o -- AUC + h -- SSF p -- EIR diff --git a/mss/main/conf/MIB_files/menu_tree.txt b/mss/main/conf/MIB_files/menu_tree.txt new file mode 100644 index 0000000..2f52696 --- /dev/null +++ b/mss/main/conf/MIB_files/menu_tree.txt @@ -0,0 +1,908 @@ +############## The debug menu tree config file root=wxc2 root_oid={1.3.6.1.4.1.1373.1.3} +#(0)(1)(2)(9) ip group +#/ the layer +#.1.1.3. menu_id +#{3.2.2.1.2} the last oid from the root +#[name] menu name +#M:8 the id of the menu in the current object +############## all the line must end for ';',and menu id and last oid must do not contain space + +##WXC2 +/. (9); + +M:1 [MSC] {3.2}; +M:2 [VLR] {3.2.5}; +M:3 [HLR] {3.3}; +M:4 [PPS] {3.6}; +M:5 [SMSC] {3.5}; +M:6 [AUC] {3.4}; +##M:7 [EIR] {3.8}; + +##MSC +/ /.1. (9); + +M:1 [Prefix Assignment] {3.2.2.2.1.1}; +M:2 [Prefix Attributes] {3.2.2.2.1.2}; +M:3 [Assign TG to Prefix] {3.2.2.2.1.3}; +M:4 [TG attributes] {3.2.2.2.1.4}; +M:5 [CDR Flag] {3.2.2.2.1.5}; +M:6 [Announcement Option] {3.2.2.2.1.6}; +M:7 [Warning tone] {3.2.2.2.1.7}; +M:8 [Emergency call] {3.2.2.2.2.5}; +M:9 [Location management] {3.2.2.2.2.8}; +M:10 [Max. call duration] {3.2.2.2.3.7}; +M:11 [E1 Port] {3.2.2.2.4}; +M:12 [channel attributes] {3.2.2.2.5}; +M:13 [Platform] {2}; +M:14 [MSC0] (1) {3.2}; +M:15 [MSC1] (2) {3.2}; + +##MSC->E1 Port +/ / /.1.11. (9); + +M:1 [E1 interface] {3.2.2.2.4.1}; +M:2 [Assign TG to E1] {3.2.2.2.4.2}; +M:3 [CIC of E1] {3.2.2.2.4.3}; + +##MSC->channel attributes->8K card 0-31 +/ / /.1.12. (9); + +M:1 [Card 0 channel attributes] {3.2.2.2.5.1}; +M:2 [Card 1 channel attributes] {3.2.2.2.5.2}; +M:3 [Card 2 channel attributes] {3.2.2.2.5.3}; +M:4 [Card 3 channel attributes] {3.2.2.2.5.4}; +M:5 [Card 4 channel attributes] {3.2.2.2.5.5}; +M:6 [Card 5 channel attributes] {3.2.2.2.5.6}; +M:7 [Card 6 channel attributes] {3.2.2.2.5.7}; +M:8 [Card 7 channel attributes] {3.2.2.2.5.8}; +M:9 [Card 8 channel attributes] {3.2.2.2.5.9}; +M:10 [Card 9 channel attributes] {3.2.2.2.5.10}; +M:11 [Card 10 channel attributes] {3.2.2.2.5.11}; +M:12 [Card 11 channel attributes] {3.2.2.2.5.12}; +M:13 [Card 12 channel attributes] {3.2.2.2.5.13}; +M:14 [Card 13 channel attributes] {3.2.2.2.5.14}; +M:15 [Card 14 channel attributes] {3.2.2.2.5.15}; +M:16 [Card 15 channel attributes] {3.2.2.2.5.16}; +M:17 [Card 16 channel attributes] {3.2.2.2.5.17}; +M:18 [Card 17 channel attributes] {3.2.2.2.5.18}; +M:19 [Card 18 channel attributes] {3.2.2.2.5.19}; +M:20 [Card 19 channel attributes] {3.2.2.2.5.20}; +M:21 [Card 20 channel attributes] {3.2.2.2.5.21}; +M:22 [Card 21 channel attributes] {3.2.2.2.5.22}; +M:23 [Card 22 channel attributes] {3.2.2.2.5.23}; +M:24 [Card 23 channel attributes] {3.2.2.2.5.24}; +M:25 [Card 24 channel attributes] {3.2.2.2.5.25}; +M:26 [Card 25 channel attributes] {3.2.2.2.5.26}; +M:27 [Card 26 channel attributes] {3.2.2.2.5.27}; +M:28 [Card 27 channel attributes] {3.2.2.2.5.28}; +M:29 [Card 28 channel attributes] {3.2.2.2.5.29}; +M:30 [Card 29 channel attributes] {3.2.2.2.5.30}; +M:31 [Card 30 channel attributes] {3.2.2.2.5.31}; +M:32 [Card 31 channel attributes] {3.2.2.2.5.32}; + + +##MSC->Platform +/ / /.1.13. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##MSC->Platform->MTP3 +/ / /.1.13.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [ACN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##MSC->Platform->MTP3->Status +/ / /.1.13.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##MSC->Platform->SCCP +/ / /.1.13.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##MSC->Platform->XAPP +/ / /.1.13.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + + +##MSC->MSC0->E1 status +/ / /.1.14. (1); + +M:1 [E1 Status] {3.2.2.3.4}; +M:2 [Channel Status] {3.2.2.3.5}; +##M:3 [CSU0] {1.1}; + + +##MSC->MSC1->E1 status +/ / /.1.15. (2); + +M:1 [E1 Status] {3.2.2.3.4}; +M:2 [Channel Status] {3.2.2.3.5}; +##M:3 [CSU1] {1.1}; + + +##MSC->MSC0->Channel Status +/ / / /.1.14.2. (1); + +M:1 [8K Card 0] {3.2.2.3.5.1}; +M:2 [8K Card 1] {3.2.2.3.5.2}; +M:3 [8K Card 2] {3.2.2.3.5.3}; +M:4 [8K Card 3] {3.2.2.3.5.4}; +M:5 [8K Card 4] {3.2.2.3.5.5}; +M:6 [8K Card 5] {3.2.2.3.5.6}; +M:7 [8K Card 6] {3.2.2.3.5.7}; +M:8 [8K Card 7] {3.2.2.3.5.8}; +M:9 [8K Card 8] {3.2.2.3.5.9}; +M:10 [8K Card 9] {3.2.2.3.5.10}; +M:11 [8K Card 10] {3.2.2.3.5.11}; +M:12 [8K Card 11] {3.2.2.3.5.12}; +M:13 [8K Card 12] {3.2.2.3.5.13}; +M:14 [8K Card 13] {3.2.2.3.5.14}; +M:15 [8K Card 14] {3.2.2.3.5.15}; +M:16 [8K Card 15] {3.2.2.3.5.16}; + + +##MSC->MSC1->channel status +/ / / /.1.15.2. (2); + +M:1 [8K Card 0] {3.2.2.3.5.1}; +M:2 [8K Card 1] {3.2.2.3.5.2}; +M:3 [8K Card 2] {3.2.2.3.5.3}; +M:4 [8K Card 3] {3.2.2.3.5.4}; +M:5 [8K Card 4] {3.2.2.3.5.5}; +M:6 [8K Card 5] {3.2.2.3.5.6}; +M:7 [8K Card 6] {3.2.2.3.5.7}; +M:8 [8K Card 7] {3.2.2.3.5.8}; +M:9 [8K Card 8] {3.2.2.3.5.9}; +M:10 [8K Card 9] {3.2.2.3.5.10}; +M:11 [8K Card 10] {3.2.2.3.5.11}; +M:12 [8K Card 11] {3.2.2.3.5.12}; +M:13 [8K Card 12] {3.2.2.3.5.13}; +M:14 [8K Card 13] {3.2.2.3.5.14}; +M:15 [8K Card 14] {3.2.2.3.5.15}; +M:16 [8K Card 15] {3.2.2.3.5.16}; + + +##MSC->MSC0->CSU0 +##/ / / / /.1.14.3. (1); + +##M:1 [E1 enable] {1.1.1.2.1}; +##M:2 [MTP alarm on/off] {1.1.1.2.2}; +##M:3 [Link type] {1.1.1.2.3}; +##M:4 [NT/LT] {1.1.1.2.4}; +##M:5 [DPLL priority] {1.1.1.2.5}; +##M:6 [CRC4 flag] {1.1.1.2.6}; +##M:7 [Ringback Tone] {1.1.1.2.7.1}; +##M:8 [Busy Tone] {1.1.1.2.7.2}; +##M:9 [Unavailable Tone] {1.1.1.2.7.3}; +##M:10 [Congestion Tone] {1.1.1.2.7.4}; +##M:11 [Proceeding Tone] {1.1.1.2.7.5}; +##M:12 [Warning tone] {1.1.1.2.7.6}; +##M:13 [Tone assignment] {1.1.1.2.7.9}; +##M:14 [DTMF mark&space] {1.1.1.2.7.10}; +##M:15 [8KE1_0] (0) {1.1.1.3}; +##M:16 [8KE1_1] (0) {1.1.1.3}; +##M:17 [8KE1_2] (0) {1.1.1.3}; +##M:18 [8KE1_3] (0) {1.1.1.3}; +##M:19 [8KE1_4] (0) {1.1.1.3}; +##M:20 [8KE1_5] (0) {1.1.1.3}; +##M:21 [8KE1_6] (0) {1.1.1.3}; +##M:22 [8KE1_7] (0) {1.1.1.3}; +##M:23 [8KE1_8] (0) {1.1.1.3}; +##M:24 [8KE1_9] (0) {1.1.1.3}; +##M:25 [8KE1_10] (0) {1.1.1.3}; +##M:26 [8KE1_11] (0) {1.1.1.3}; +##M:27 [8KE1_12] (0) {1.1.1.3}; +##M:28 [8KE1_13] (0) {1.1.1.3}; +##M:29 [8KE1_14] (0) {1.1.1.3}; +##M:30 [8KE1_15] (0) {1.1.1.3}; + + +##MSC->MSC1->CSU1 +##/ / / / /.1.15.3. (2); + +##M:1 [E1 enable] {1.1.1.2.1}; +##M:2 [MTP alarm on/off] {1.1.1.2.2}; +##M:3 [Link type] {1.1.1.2.3}; +##M:4 [NT/LT] {1.1.1.2.4}; +##M:5 [DPLL priority] {1.1.1.2.5}; +##M:6 [CRC4 flag] {1.1.1.2.6}; +##M:7 [Ringback Tone] {1.1.1.2.7.1}; +##M:8 [Busy Tone] {1.1.1.2.7.2}; +##M:9 [Unavailable Tone] {1.1.1.2.7.3}; +##M:10 [Congestion Tone] {1.1.1.2.7.4}; +##M:11 [Proceeding Tone] {1.1.1.2.7.5}; +##M:12 [Warning tone] {1.1.1.2.7.6}; +##M:13 [Tone assignment] {1.1.1.2.7.9}; +##M:14 [DTMF mark&space] {1.1.1.2.7.10}; +##M:15 [8KE1_0] (0) {1.1.1.3}; +##M:16 [8KE1_1] (0) {1.1.1.3}; +##M:17 [8KE1_2] (0) {1.1.1.3}; +##M:18 [8KE1_3] (0) {1.1.1.3}; +##M:19 [8KE1_4] (0) {1.1.1.3}; +##M:20 [8KE1_5] (0) {1.1.1.3}; +##M:21 [8KE1_6] (0) {1.1.1.3}; +##M:22 [8KE1_7] (0) {1.1.1.3}; +##M:23 [8KE1_8] (0) {1.1.1.3}; +##M:24 [8KE1_9] (0) {1.1.1.3}; +##M:25 [8KE1_10] (0) {1.1.1.3}; +##M:26 [8KE1_11] (0) {1.1.1.3}; +##M:27 [8KE1_12] (0) {1.1.1.3}; +##M:28 [8KE1_13] (0) {1.1.1.3}; +##M:29 [8KE1_14] (0) {1.1.1.3}; +##M:30 [8KE1_15] (0) {1.1.1.3}; + +##VLR +/ / /.2. (9); + +M:1 [OptAuthReq] {3.2.5.2.1.1}; +M:2 [OpReuseTriplets] {3.2.5.2.1.2}; +M:3 [OptCipReq] {3.2.5.2.1.3}; +M:4 [OptCiphAlgo] {3.2.5.2.1.4}; +M:5 [OptTmsiAlloc] {3.2.5.2.1.5}; +M:6 [OptEcsSetUpAllow] {3.2.5.2.1.7}; +M:7 [OptCheckIMEI] {3.2.5.2.1.8}; +M:8 [OptVlrPurge] {3.2.5.2.1.9}; +M:9 [idlePeriod2Purge] {3.2.5.2.1.10}; +M:10 [CDR flag] {3.2.5.2.1.11}; +M:11 [MSRN] {3.2.5.2.1.13}; +M:12 [VLR0] {3.2.5}; +M:13 [VLR1] {3.2.5}; + +##VLR->VLR0 + +/ / /.2.12. (1); + +M:1 [Version] {3.2.5.3.2}; +M:2 [Command] {3.2.5.3.3}; +M:3 [Status] {3.2.5.3.4}; + +##VLR->VLR0 + +/ / /.2.13. (2); + +M:1 [Version] {3.2.5.3.2}; +M:2 [Command] {3.2.5.3.3}; +M:3 [Status] {3.2.5.3.4}; + + +##HLR +/ / /.3. (9); + +M:1 [HPLMN] {3.3.2.1.11}; +M:2 [VPLMNs] {3.3.2.1.12}; +M:3 [CSRR list] {3.3.2.1.13}; +M:4 [Regional Subscription] {3.3.2.1.14}; +M:5 [License control] {3.3.2.1.15}; +M:6 [CDR control] {3.3.2.1.16}; +M:7 [Feature Code] {3.3.2.1.27}; +M:8 [Platform] {2}; +M:9 [HLR0] {3.3}; +M:10 [HLR1] {3.3}; + +##HLR->Platform +/ / /.3.8. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##HLR->Platform->MTP3 +/ / /.3.8.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [ACN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##HLR->Platform->MTP3->Status +/ / /.3.8.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##HLR->Platform->SCCP +/ / /.3.8.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##HLR->Platform->XAPP +/ / /.3.8.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##HLR->HLR0 + +/ / /.3.9. (1); + +M:1 [Command] {3.3.2.2.2}; +M:2 [Subscriber import] {3.3.2.2.3}; +M:3 [Max Licenses] {3.3.2.2.11}; +M:4 [Used Licenses] {3.3.2.2.12}; +M:5 [Subscriber information] {3.3.2.2.13}; +M:6 [Version] {3.3.2.2.14}; +M:7 [IMSI segment] {3.3.2.2.15}; +M:8 [MSISDN segment] {3.3.2.2.16}; +M:9 [CNF applicant info] {3.3.2.2.27}; +##M:10 [Contry code] {3.3.2.2.10}; + +##HLR->HLR0->Subscriber information + +/ / /.3.9.5. (1); + +M:1 [Provisioned subscribers] {3.3.2.2.13.1}; +M:2 [Registered subscribers] {3.3.2.2.13.2}; +M:3 [Roaming subscribers] {3.3.2.2.13.3}; + +##HLR->HLR0->Version +/ / /.3.9.6. (1); + +M:1 [Software] {3.3.2.2.14.1}; +M:2 [User data] {3.3.2.2.14.2}; + + +##HLR->HLR1 + +/ / /.3.10. (2); + +M:1 [Command] {3.3.2.2.2}; +M:2 [Subscriber import] {3.3.2.2.3}; +M:3 [Max Licenses] {3.3.2.2.11}; +M:4 [Used Licenses] {3.3.2.2.12}; +M:5 [Subscriber information] {3.3.2.2.13}; +M:6 [Version] {3.3.2.2.14}; +M:7 [IMSI segment] {3.3.2.2.15}; +M:8 [MSISDN segment] {3.3.2.2.16}; +M:9 [CNF applicant info] {3.3.2.2.27}; +##M:10 [Contry code] {3.3.2.2.10}; + +##HLR->HLR1->Subscriber information +/ / /.3.10.5. (2); + +M:1 [Provisioned subscribers] {3.3.2.2.13.1}; +M:2 [Registered subscribers] {3.3.2.2.13.2}; +M:3 [Roaming subscribers] {3.3.2.2.13.3}; + +##HLR->HLR1->Version +/ / /.3.10.6. (2); + +M:1 [Software] {3.3.2.2.14.1}; +M:2 [User data] {3.3.2.2.14.2}; + +##PPS +/ / /.4. (9); + +M:1 [Service control] {3.6.2.1.1}; +M:2 [SRF Number] {3.6.2.1.2.1}; +M:3 [Service number] {3.6.2.1.2.2}; +M:4 [Service key] {3.6.2.1.2.3}; +M:5 [COS Parameter] {3.6.2.1.4}; +M:6 [Call routing to VMS] {3.6.2.1.5}; +M:7 [Status] {3.6.2.1.6}; +M:8 [Platform] {2}; + +##PPS->Service control +/ / /.4.1. (9); + +M:1 [CDR flag] {3.6.2.1.1.1}; +M:2 [Blacklist threshhold] {3.6.2.1.1.2}; +M:3 [Maximun balance] {3.6.2.1.1.3}; +M:4 [license control] {3.6.2.1.1.4}; +M:5 [Prompt resolution] {3.6.2.1.1.5}; +M:6 [SMS Sentence] {3.6.2.1.1.6}; +M:7 [Last call info] {3.6.2.1.1.7}; +M:8 [Currency Symbol] {3.6.2.1.1.8}; +M:9 [Third party info] {3.6.2.1.1.9}; +M:10 [Basic Tariff Zone] {3.6.2.1.1.10}; + +##PPS->Service number +/ / /.4.3. (9); + +M:1 [Hotline] {3.6.2.1.2.2.1}; +M:2 [Inquiry] {3.6.2.1.2.2.2}; +M:3 [Scratch card rechagne] {3.6.2.1.2.2.3}; +M:4 [Credit card recharge] {3.6.2.1.2.2.4}; +M:5 [Third party recharge] {3.6.2.1.2.2.5}; +M:6 [Customer care center] {3.6.2.1.2.2.6}; +M:7 [Recharge] {3.6.2.1.2.2.7}; + +##PPS->Service key +/ / /.4.4. (9); + +M:1 [Inquiry] {3.6.2.1.2.3.2}; +M:2 [Scratch card rechagne] {3.6.2.1.2.3.3}; +M:3 [Credit card recharge] {3.6.2.1.2.3.4}; +M:4 [Set favorite number] {3.6.2.1.2.3.5}; +M:5 [Set password] {3.6.2.1.2.3.6}; + + +##PPS->COS Parameter +/ / /.4.5. (9); + +M:1 [COS0] {3.6.2.1.4.1}; +M:2 [COS1] {3.6.2.1.4.2}; +M:3 [COS2] {3.6.2.1.4.3}; +M:4 [COS3] {3.6.2.1.4.4}; +M:5 [COS4] {3.6.2.1.4.5}; +M:6 [COS5] {3.6.2.1.4.6}; +M:7 [COS6] {3.6.2.1.4.7}; +M:8 [COS7] {3.6.2.1.4.8}; +M:9 [COS8] {3.6.2.1.4.9}; +M:10 [COS9] {3.6.2.1.4.10}; +M:11 [COS10] {3.6.2.1.4.11}; +M:12 [COS11] {3.6.2.1.4.12}; +M:13 [COS12] {3.6.2.1.4.13}; +M:14 [COS13] {3.6.2.1.4.14}; +M:15 [COS14] {3.6.2.1.4.15}; +M:16 [COS15] {3.6.2.1.4.16}; + + +##PPS->COS Parameter->COS 0-15 +/ / /.4.5.1. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.1.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.1.2}; +M:3 [Account control] {3.6.2.1.4.1.3}; +M:4 [MT Call control] {3.6.2.1.4.1.4}; +M:5 [Validity control] {3.6.2.1.4.1.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.1.6}; + +/ / /.4.5.2. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.2.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.2.2}; +M:3 [Account control] {3.6.2.1.4.2.3}; +M:4 [MT Call control] {3.6.2.1.4.2.4}; +M:5 [Validity control] {3.6.2.1.4.2.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.2.6}; + +/ / /.4.5.3. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.3.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.3.2}; +M:3 [Account control] {3.6.2.1.4.3.3}; +M:4 [MT Call control] {3.6.2.1.4.3.4}; +M:5 [Validity control] {3.6.2.1.4.3.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.3.6}; + +/ / /.4.5.4. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.4.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.4.2}; +M:3 [Account control] {3.6.2.1.4.4.3}; +M:4 [MT Call control] {3.6.2.1.4.4.4}; +M:5 [Validity control] {3.6.2.1.4.4.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.4.6}; + +/ / /.4.5.5. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.5.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.5.2}; +M:3 [Account control] {3.6.2.1.4.5.3}; +M:4 [MT Call control] {3.6.2.1.4.5.4}; +M:5 [Validity control] {3.6.2.1.4.5.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.5.6}; + +/ / /.4.5.6. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.6.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.6.2}; +M:3 [Account control] {3.6.2.1.4.6.3}; +M:4 [MT Call control] {3.6.2.1.4.6.4}; +M:5 [Validity control] {3.6.2.1.4.6.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.6.6}; + +/ / /.4.5.7. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.7.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.7.2}; +M:3 [Account control] {3.6.2.1.4.7.3}; +M:4 [MT Call control] {3.6.2.1.4.7.4}; +M:5 [Validity control] {3.6.2.1.4.7.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.7.6}; + +/ / /.4.5.8. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.8.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.8.2}; +M:3 [Account control] {3.6.2.1.4.8.3}; +M:4 [MT Call control] {3.6.2.1.4.8.4}; +M:5 [Validity control] {3.6.2.1.4.8.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.8.6}; + +/ / /.4.5.9. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.9.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.9.2}; +M:3 [Account control] {3.6.2.1.4.9.3}; +M:4 [MT Call control] {3.6.2.1.4.9.4}; +M:5 [Validity control] {3.6.2.1.4.9.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.9.6}; + +/ / /.4.5.10. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.10.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.10.2}; +M:3 [Account control] {3.6.2.1.4.10.3}; +M:4 [MT Call control] {3.6.2.1.4.10.4}; +M:5 [Validity control] {3.6.2.1.4.10.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.10.6}; + +/ / /.4.5.11. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.11.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.11.2}; +M:3 [Account control] {3.6.2.1.4.11.3}; +M:4 [MT Call control] {3.6.2.1.4.11.4}; +M:5 [Validity control] {3.6.2.1.4.11.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.11.6}; + +/ / /.4.5.12. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.12.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.12.2}; +M:3 [Account control] {3.6.2.1.4.12.3}; +M:4 [MT Call control] {3.6.2.1.4.12.4}; +M:5 [Validity control] {3.6.2.1.4.12.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.12.6}; + +/ / /.4.5.13. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.13.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.13.2}; +M:3 [Account control] {3.6.2.1.4.13.3}; +M:4 [MT Call control] {3.6.2.1.4.13.4}; +M:5 [Validity control] {3.6.2.1.4.13.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.13.6}; + +/ / /.4.5.14. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.14.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.14.2}; +M:3 [Account control] {3.6.2.1.4.14.3}; +M:4 [MT Call control] {3.6.2.1.4.14.4}; +M:5 [Validity control] {3.6.2.1.4.14.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.14.6}; + +/ / /.4.5.15. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.15.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.15.2}; +M:3 [Account control] {3.6.2.1.4.15.3}; +M:4 [MT Call control] {3.6.2.1.4.15.4}; +M:5 [Validity control] {3.6.2.1.4.15.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.15.6}; + +/ / /.4.5.16. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.16.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.16.2}; +M:3 [Account control] {3.6.2.1.4.16.3}; +M:4 [MT Call control] {3.6.2.1.4.16.4}; +M:5 [Validity control] {3.6.2.1.4.16.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.16.6}; + + +##PPS->call routing to VMS +/ / /.4.6. (9); + +M:1 [VMS service number-PLMN] {3.6.2.1.5.1}; +M:2 [VMS service number-PSTN] {3.6.2.1.5.2}; +M:3 [VMS leave message number] {3.6.2.1.5.3}; +M:4 [Routing rule] {3.6.2.1.5.4}; +M:5 [VMS user segments] {3.6.2.1.5.5}; + +##PPS->Status +/ / /.4.7. (9); + +M:1 [Activaion] {3.6.2.1.6.1}; +M:2 [Command] {3.6.2.1.6.2}; + + +##PPS->Platform +/ / /.4.8. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; +M:4 [SMPP] {2.3.4} + +##PPS->Platform->MTP3 +/ / /.4.8.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##PPS->Platform->MTP3->Status +/ / /.4.8.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##PPS->Platform->SCCP +/ / /.4.8.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##PPS->Platform->XAPP +/ / /.4.8.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##PPS-->Platform->SMPP +/ / /.4.8.4. (9); + +M:1 [SMPP_Link_Param] {2.3.4.2.1}; +M:2 [Command] {2.3.4.3.2}; + + +## SMSC +/ / /.5. (9); + +M:1 [CDR flag] {3.5.2.1.1}; +M:2 [SM Validity] {3.5.2.1.2}; +M:3 [MSISDN Segment] {3.5.2.1.3}; +M:4 [SMPP parameters] {3.5.2.2}; +M:5 [Command] {3.5.3.3}; +M:6 [Platform] {2}; +M:7 [SMSC0] {3.5}; +M:8 [SMSC1] {3.5}; + + +##SMSC->Platform +/ / /.5.6. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; +M:4 [SMPP] {2.3.4}; + +##SMSC->Platform->MTP3 +/ / /.5.6.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##SMSC->Platform->MTP3->Status +/ / /.5.6.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##SMSC->Platform->SCCP +/ / /.5.6.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##SMSC->Platform->XAPP +/ / /.5.6.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##SMSC->Platform->SMPP +/ / /.5.6.4. (9); + +M:1 [SMPP_Link_Param] {2.3.4.2.1}; +M:2 [Command] {2.3.4.3.2}; + + +##SMSC->SMSC0 +/ / /.5.7. (1); + +M:1 [SMSC ID] {3.5.3.1}; +M:2 [Software version] {3.5.3.2}; + +##SMSC->SMSC1 +/ / /.5.8. (2); + +M:1 [SMSC ID] {3.5.3.1}; +M:2 [Software version] {3.5.3.2}; + +##AUC +/ / /.6. (9); + +M:1 [Platform] {2}; +M:2 [AUC0] (1) {3.4}; +M:3 [AUC1] (2) {3.4}; + + +##AUC->Platform +/ / /.6.1. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##AUC->Platform->MTP3 +/ / /.6.1.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##AUC->Platform->MTP3->Status +/ / /.6.1.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##AUC->Platform->SCCP +/ / /.6.1.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##AUC->Platform->XAPP +/ / /.6.1.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + + +##EIR +##/ / /.7. (9); + +##M:1 [Platform] {2}; +##M:2 [EIR0] (1) {3.8}; +##M:3 [EIR1] (2) {3.8}; + +##EIR->Platform +##/ / /.7.1. (9); + +##M:1 [MTP3] {2.2.2}; +##M:2 [SCCP] {2.2.3}; +##M:3 [XAPP] {2.2.5}; + +##EIR->Platform->MTP3 +##/ / /.7.1.1. (9); + +##M:1 [Network Indicator] {2.2.2.2.2}; +##M:2 [Originating Point code] {2.2.2.2.3}; +##M:3 [Link Set] {2.2.2.2.4}; +##M:4 [Link] {2.2.2.2.5}; +##M:5 [Routing] {2.2.2.2.6}; +##M:6 [CAN] {2.2.2.2.7}; +##M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##EIR->Platform->MTP3->Status +##/ / /.7.1.1.7. (9); + +####M:1 [Link status] {2.2.2.3.1}; +##M:2 [Link set status] {2.2.2.3.2}; +##M:3 [International routing] {2.2.2.3.3}; +##M:4 [International spare] {2.2.2.3.4}; +##M:5 [National routing] {2.2.2.3.5}; +##M:6 [National spare routing] {2.2.2.3.6}; +##M:7 [Command] {2.2.2.3.7}; + +##EIR->Platform->SCCP +##/ / /.7.1.2. (9); + +##M:1 [Local node] {2.2.3.2.1}; +##M:2 [GTT] {2.2.3.2.2}; +##M:3 [Command] {2.2.3.3.2}; + +##EIR->Platform->XAPP +##/ / /.7.1.3. (9); + +##M:1 [MCC] {2.2.5.2.1}; +##M:2 [MNC] {2.2.5.2.2}; +##M:3 [CC] {2.2.5.2.3}; +##M:5 [International prefix] {2.2.5.2.5}; +##M:6 [National Prefix] {2.2.5.2.6}; +##M:7 [Local Prefix] {2.2.5.2.7}; +##M:8 [Convert Prefix] {2.2.5.2.8}; +##M:9 [Command] {2.2.5.3.2}; diff --git a/mss/main/conf/MIB_files/mib_list_file.txt b/mss/main/conf/MIB_files/mib_list_file.txt new file mode 100644 index 0000000..c51c1d3 --- /dev/null +++ b/mss/main/conf/MIB_files/mib_list_file.txt @@ -0,0 +1,14 @@ +// "//" is the annotation characters; +IWV-SMI.txt +Special_App-SMI.txt +//PPPRT-MIB.txt +WXC2-SMI.txt +//WXC2-CSU-MIB.txt +WXC2-SS7-MIB.txt +WXC2-MSC-MIB.txt +WXC2-HLR-MIB.txt +WXC2-AUC-MIB.txt +//WXC2-EIR-MIB.txt +WXC2-SMSC-MIB.txt +WXC2-PPS-MIB.txt +WXC2-MSS-MIB.txt diff --git a/mss/main/conf/MIB_files/mib_write_tree.txt b/mss/main/conf/MIB_files/mib_write_tree.txt new file mode 100644 index 0000000..eab2129 --- /dev/null +++ b/mss/main/conf/MIB_files/mib_write_tree.txt @@ -0,0 +1,25779 @@ +Create node: IWV(OID: 1.3.6.1.4.1.1373) +-> father_name = [enterprises] +-> -> IWV(0) + + +Create node: IWV_Products(OID: 1.3.6.1.4.1.1373.1) +-> father_name = [IWV] +-> -> IWV_Products(0) + + +Remark: iwvProducts is the root OBJECT IDENTIFIER from which sysObjectID values are assigned. Actual values are defined in IWV-PRODUCTS-MIB. + + +Create node: Special_App(OID: 1.3.6.1.4.1.1373.1.2) +-> father_name = [IWV_Products] +-> -> Special_App(0) + + +Create node: IWF(OID: 1.3.6.1.4.1.1373.1.2.8) +-> father_name = [Special_App] +-> -> IWF(0) + + +Remark: IWF + + +Create node: WXC2(OID: 1.3.6.1.4.1.1373.1.3) +-> father_name = [IWV_Products] +-> -> Special_App(0) +-> -> WXC2(1) + + +Create node: PCM(OID: 1.3.6.1.4.1.1373.1.3.1) +-> father_name = [WXC2] +-> -> PCM(0) + + +Remark: PCM + + +Create node: Platform(OID: 1.3.6.1.4.1.1373.1.3.2) +-> father_name = [WXC2] +-> -> PCM(0) +-> -> Platform(1) + + +Remark: Platform + + +Create node: App(OID: 1.3.6.1.4.1.1373.1.3.3) +-> father_name = [WXC2] +-> -> PCM(0) +-> -> Platform(1) +-> -> App(2) + + +Remark: App platform + + +Create node: SS7(OID: 1.3.6.1.4.1.1373.1.3.2.2) +-> father_name = [Platform] +-> -> SS7(0) + + +Remark: + Subsystems for SS7 . + + +Create node: MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2) +-> father_name = [SS7] +-> -> MTP3(0) + + +Remark: Subsystems for MTP3 . + + +Create node: Config_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2) +-> father_name = [MTP3] +-> -> Config_MTP3(0) + + +Remark: MTP3 Configuration. + + +Create node: Network_Indicator(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.2) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) + + +Register leaf node: Network_Indicator. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : MTP3 network indicator. + +Field : total(8) +Access : read-write [1]International network + { + [u]0.0-0.0 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [2]International network spare + { + [u]0.1-0.1 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [3]National network + { + [u]0.2-0.2 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [4]National network spare + { + [u]0.3-0.3 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [5]International network + { + [u]0.4-0.4 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [6]International network spare + { + [u]0.5-0.5 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [7]National network + { + [u]0.6-0.6 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [8]National network spare + { + [u]0.7-0.7 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + + +Create node: OPC(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) + + +Remark: Originating point code. + + +Create node: International_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.1) +-> father_name = [OPC] +-> -> International_14bit(0) + + +Register leaf node: International_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.2) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) + + +Register leaf node: International_Spare_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.3) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) + + +Register leaf node: National_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.4) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) + + +Register leaf node: National_Spare_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.5) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) + + +Register leaf node: International_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.6) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) + + +Register leaf node: International_Spare_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.7) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) +-> -> National_24bit(6) + + +Register leaf node: National_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.8) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) +-> -> National_24bit(6) +-> -> National_Spare_24bit(7) + + +Register leaf node: National_Spare_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Linkset(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.4) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) + + +Remark: linkset. + + +Create node: Linkset_Attributes(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.4.1) +-> father_name = [Linkset] +-> -> Linkset_Attributes(0) + + +Register leaf node: Linkset_Attributes. +Instance: 128 +Length : 4 +Flag : 255 +Default : +Remark : Opposite point code: The opposite point code of the linkset. +Network indicator: The network type of the opposite point code. +Loop back: Loop back enable or disable, used for MSC loop back link. + +Field : total(5) +Access : read-write[1]Linkset DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + [2]Network indicator + { + [u]3.0-3.1 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [4]Linkset loopback + { + [u]3.3-3.3 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Link(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) + + +Remark: link. + + +Create node: Link_Attributes(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.1) +-> father_name = [Link] +-> -> Link_Attributes(0) + + +Register leaf node: Link_Attributes. +Instance: 256 +Length : 15 +Flag : 255 +Default : €ÿÿÿÿ +Remark : E1 link attributes. +Linkset no.: Assign linkset to E1 link, MSC has up to 128 linksets (0-127). 128=TCH E1. +SLC no.: Assign SLC to each E1 link of a linkset, each linkset has up to 13 E1 links (0-15). +IP: E1 link management IP. The third byte of CPC IP: +98=E1 link 0-127, 99=E1 link 128-255. +Default=0x000032. + +Field : total(12) +Access : read-write[1]Linkset no. + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } +[2]SLC no. + { + [u]1.0-1.7 + [u]input + [v]toDec high 0 + } +[3]CPC IP + { + [u]2.0-5.7 + [u]input + [v]KeepHex high 0 + } + [4]Link Type + { + [u]6.0-6.0 + [u]select + [v]0[opt]Non-sigtran + [v]1[opt]Sigtran + } + [5]Link Enable + { + [u]6.1-6.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [6]MTP3-Lite Enable + { + [u]6.2-6.2 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[8]SG no. + { + [u]7.0-7.7 + [u]input + [v]toDec high 0 + } +[9]M2UA Interface ID + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } +[10]MTP3-Lite Remote IP + { + [u]9.0-12.7 + [u]input + [v]KeepHex high 0 + } +[11]MTP3-Lite Inactivity Timeout + { + [u]13.0-13.7 + [u]input + [v]toDec high 0 + } +[12]MTP3-Lite Allowed Inactivity Timeouts + { + [u]14.0-14.7 + [u]input + [v]toDec high 0 + } + + +Create node: Link_Command(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.2) +-> father_name = [Link] +-> -> Link_Attributes(0) +-> -> Link_Command(1) + + +Register leaf node: Link_Command. +Instance: 256 +Length : 1 +Flag : 255 +Default :  +Remark : Used for E1 link control, not affect call traffic. +Disable=Disable E1 link MTP2 layer. +Enable=Enable a disabled E1 link MTP2 layer. +Inhibit=Inhibit E1 link MTP3 layer. +Uninhibit=Uninhibit a inhibited E1 link MTP3 layer. +Default=Enable a disabled E1 link MTP2 layer. + +Field : total(1) +Access : write-only [1]E1 link + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + [v]2[opt]Inhibit + [v]3[opt]Uninhibit + } + + +Create node: TCP_Port(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.3) +-> father_name = [Link] +-> -> Link_Attributes(0) +-> -> Link_Command(1) +-> -> TCP_Port(2) + + +Register leaf node: TCP_Port. +Instance: 1 +Length : 2 +Flag : 255 +Default : ˆ +Remark : TCP server port for SCCP-Lite. + +Field : total(1) +Access : read-write[1]TCP Port + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) + + +Remark: Routing. + + +Create node: International(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.1) +-> father_name = [Routing] +-> -> International(0) + + +Register leaf node: International. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.2) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) + + +Register leaf node: International_Spare. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: National(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.3) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) +-> -> National(2) + + +Register leaf node: National. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.4) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) +-> -> National(2) +-> -> National_Spare(3) + + +Register leaf node: National_Spare. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: SPC_to_ACN(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) +-> -> SPC_to_ACN(5) + + +Remark: SPC to ACN. + + +Create node: Local_ACN(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.1) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) + + +Register leaf node: Local_ACN. +Instance: 1 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: International(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.2) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) + + +Register leaf node: International. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: International_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.3) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) + + +Register leaf node: International_Spare. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: National(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.4) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) +-> -> National(3) + + +Register leaf node: National. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: National_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.5) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) +-> -> National(3) +-> -> National_Spare(4) + + +Register leaf node: National_Spare. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: Signaling_Gateway(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.9) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) +-> -> SPC_to_ACN(5) +-> -> Signaling_Gateway(6) + + +Register leaf node: Signaling_Gateway. +Instance: 256 +Length : 7 +Flag : 255 +Default : +Remark : SG attributes + +Field : total(4) +Access : read-write [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Server + { + [u]1.0-1.7 + [u]select + [v]0[opt]Client + [v]1[opt]Server + } + [3]ACK + { + [u]2.0-2.7 + [u]select + [v]0[opt]no ACK + [v]1[opt]ACK + } +[4]IP + { + [u]3.0-6.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Status_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3) +-> father_name = [MTP3] +-> -> Config_MTP3(0) +-> -> Status_MTP3(1) + + +Remark: MTP3 Status. + + +Create node: Link_Status(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.1) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) + + +Register leaf node: Link_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default :  +Remark : E1 link MTP3 status (Read Only). + +Field : total(1) +Access : read-only [1]Link status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Inhibited + } + + +Create node: Linkset_Status(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.2) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) + + +Register leaf node: Linkset_Status. +Instance: 128 +Length : 1 +Flag : 255 +Default :  +Remark : Linkset status (Read only). + +Field : total(1) +Access : read-only [1]Linkset status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Reserved + } + + +Create node: International_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.3) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) + + +Register leaf node: International_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: International_Spare_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.4) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) + + +Register leaf node: International_Spare_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: National_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.5) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) + + +Register leaf node: National_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: National_Spare_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.6) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) +-> -> National_Spare_Routing(5) + + +Register leaf node: National_Spare_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: Command_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.7) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) +-> -> National_Spare_Routing(5) +-> -> Command_MTP3(6) + + +Register leaf node: Command_MTP3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for MTP3 platform. +Reset=status initialization. +Save parameter=save parameters residing in memory into harddisk. + +Field : total(1) +Access : read-write [1]command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No command + [v]1[opt]Reset + [v]2[opt]Save parameter + } + + +Create node: SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3) +-> father_name = [SS7] +-> -> MTP3(0) +-> -> SCCP(1) + + +Remark: Subsystems for SCCP . + + +Create node: Config_SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2) +-> father_name = [SCCP] +-> -> Config_SCCP(0) + + +Remark: SCCP Configuration. + + +Create node: Local_Node(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1) +-> father_name = [Config_SCCP] +-> -> Local_Node(0) + + +Remark: Local Node. + + +Create node: OMC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.4) +-> father_name = [Local_Node] +-> -> OMC(0) + + +Register leaf node: OMC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: OMC E.134 number. +IP0: OMC0 IP, 172.18.128.1. +IP1: OMC1 IP, 172.18.129.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: HLR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.6) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) + + +Register leaf node: HLR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: HLR E.134 number. +IP0: HLR0 IP, 172.18.98.1. +IP1: HLR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: VLR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.7) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) + + +Register leaf node: VLR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VLR E.134 number. +IP0: VLR0 IP, 172.18.98.1. +IP1: VLR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: MSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.8) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) + + +Register leaf node: MSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: MSC E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: EIR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.9) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) + + +Register leaf node: EIR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: EIR E.134 number. +IP0: EIR0 IP, 172.18.98.1. +IP1: EIR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: AUC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.10) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) + + +Register leaf node: AUC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: AUC E.134 number. +IP0: AUC0 IP, 172.18.98.1. +IP1: AUC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.11) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) + + +Register leaf node: SMSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: SMSC E.134 number. +IP0: OMC0 IP, 172.18.98.1. +IP1: OMC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_EMSE(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.19) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) + + +Register leaf node: SMPP_EMSE. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VMS-SMPP E.134 number. +IP0: VMS0 IP, 172.18.147.1. +IP1: VMS1 IP, 172.18.148.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_SMSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.20) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) + + +Register leaf node: SMPP_SMSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: SMSC-SMPP E.134 number. +IP0: SMSC0 IP, 172.18.98.1. +IP1: SMSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_OMC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.21) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) + + +Register leaf node: SMPP_OMC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: OMC-SMPP E.134 number. +IP0: OMC0 IP, 172.18.128.1. +IP1: OMC1 IP, 172.18.129.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SRF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.22) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) + + +Register leaf node: SRF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VMS SRF E.134 number. +IP0: VMS0 IP, 172.18.147.1. +IP1: VMS1 IP, 172.18.148.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SSF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.143) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) + + +Register leaf node: SSF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: MSC SSF E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SCF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.147) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) +-> -> SCF(12) + + +Register leaf node: SCF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: PPS SCF E.134 number. +IP0: PPS0 IP, 172.18.98.1. +IP1: PPS1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: AIF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.254) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) +-> -> SCF(12) +-> -> AIF(13) + + +Register leaf node: AIF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: AIF E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: GTT_Table(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.2) +-> father_name = [Config_SCCP] +-> -> Local_Node(0) +-> -> GTT_Table(1) + + +Register leaf node: GTT_Table. +Instance: 256 +Length : 43 +Flag : 255 +Default : +Remark : On/off: GTT flag, off=disable, on=enable. +Numbering plan: 1=MSISDN, 3=IMSI, 7=GT. +Specify the beginning number of a group of consecutive numbers routed by GTT, for single-number GTT route, the start number is same as the end number. +End GT number: Specify the end number of a group of consecutive number routed by GT. If there are some inconsecutive numbers for a same destination, a different GTT record should be set. +Network indicator (NI): 0=International network, 1=International network spare, 2=National network, 3=National network spare, +DPC: Destination point code. +SSN: Subsystem number. +2=Reserved for ITU-T allocation. +3=ISDN user part. +4=OMC. +5=MAP. +3=HLR. +7=VLR. +8=MSC. +9=EIR. +10=AUC. +11=SMSC. +147=PPS. +254=BSSMAP. +Route indicator: For IMSI and MSISDN, select Route on SSN. For the record of the connected network, select Route on GT. +Address indicator: select the contribution of SCCP Address. +Replaced start digit: Specify the beginning digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. +Replaced end digit: Specify the end digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. +Outgoing number plan: Outgoing number plan, include MSISDN, IMSI and GT. +Replacing digits: Replacing digits, the length of replacing digits and replaced digits may be different. + +Field : total(14) +Access : read-write [1]On/off + { + [u]0.0-0.7 + [u]select + [v]1[opt]On + [v]0[opt]Off + } + [2]Numbering plan + { + [u]1.0-1.7 + [u]select + [v]0[opt]0 + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } +[3]TT + { + [u]2.0-2.7 + [u]input + [v]KeepHex Low F + } +[4]Start GT number + { + [u]3.0-12.7 + [u]input + [v]KeepHex Low F + } +[4]End GT number + { + [u]13.0-22.7 + [u]input + [v]KeepHex Low F + } + [5]Network indicator + { + [u]23.0-23.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + } +[6]DPC + { + [u]24.0-26.7 + [u]input + [v]toDec high 0 + } +[7]SSN + { + [u]27.0-27.7 + [u]input + [v]toDec high 0 + } + [8]Route indicator + { + [u]28.0-28.7 + [u]select + [v]0[opt]Route on GT + [v]1[opt]Route on SSN + } + [9]Address indicator + { + [u]29.0-29.7 + [u]select + [v]0[opt]NULL + [v]3[opt]DPC+SSN + [v]6[opt]GT+SSN + [v]7[opt]GT+DPC+SSN + } +[10]Replaced start digit + { + [u]30.0-30.7 + [u]input + [v]KeepHex high 0 + } +[11]Replaced end digit + { + [u]31.0-31.7 + [u]input + [v]KeepHex high 0 + } + [12]Outgoing number plan + { + [u]32.0-32.7 + [u]select + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } +[13]Replacing digits + { + [u]33.0-42.7 + [u]input + [v]KeepHex Low F + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3) +-> father_name = [SCCP] +-> -> Config_SCCP(0) +-> -> Management(1) + + +Remark: Management. + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.1) +-> father_name = [Management] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of SCCP platform software (Read Only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-write + +Create node: Command_SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.2) +-> father_name = [Management] +-> -> Version(0) +-> -> Command_SCCP(1) + + +Register leaf node: Command_SCCP. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for SCCP. +Reset: Used for SCCP status initialization. +Load parameter: Load the parameters from device's harddisk to device's memory. +Save parameter: Save the parameters residing in device's memory into device's harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]0[opt]Reset + [v]2[opt]Save parameters + } + + +Create node: XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5) +-> father_name = [SS7] +-> -> MTP3(0) +-> -> SCCP(1) +-> -> XAPP(2) + + +Remark: Subsystems for XAPP . + + +Create node: Config_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2) +-> father_name = [XAPP] +-> -> Config_XAPP(0) + + +Remark: XAPP Configuration. + + +Create node: MCC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.1) +-> father_name = [Config_XAPP] +-> -> MCC(0) + + +Register leaf node: MCC. +Instance: 1 +Length : 2 +Flag : 255 +Default : F +Remark : Mobile country code. + +Field : total(1) +Access : read-write[1]MCC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: MNC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.2) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) + + +Register leaf node: MNC. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Mobile network code. + +Field : total(1) +Access : read-write[1]MNC + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low E + } + + +Create node: CC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.3) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) + + +Register leaf node: CC. +Instance: 1 +Length : 2 +Flag : 255 +Default : †î +Remark : Country code. + +Field : total(1) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: NDC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.4) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) + + +Register leaf node: NDC. +Instance: 1 +Length : 3 +Flag : 255 +Default : u^î +Remark : National destination code. + +Field : total(1) +Access : read-write[1]NDC + { + [u]0.0-2.7 + [u]input + [v]KeepHex Low E + } + + +Create node: International_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.5) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) + + +Register leaf node: International_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : International call prefix. + +Field : total(1) +Access : read-write[1]International prefix + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: National_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.6) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) + + +Register leaf node: National_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : î +Remark : National call prefix. + +Field : total(1) +Access : read-write[1]National prefix + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Local_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.7) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) + + +Register leaf node: Local_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : îî +Remark : Local prefix. + +Field : total(0) +Access : read-write + +Create node: Conv_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.8) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) + + +Register leaf node: Conv_Prefix. +Instance: 128 +Length : 35 +Flag : 255 +Default : +Remark : Conv prefix . + +Field : total(5) +Access : read-write[1]Prefix + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } +[2]Delete length + { + [u]0.0-0.0 + [u]input + [v]toDec high 0 + } +[3]Add length + { + [u]17.0-17.7 + [u]input + [v]toDec high 0 + } +[4]Add digits + { + [u]18.0-33.7 + [u]input + [v]ToAscii Low 0 + } +[5]Valid length + { + [u]34.0-34.7 + [u]input + [v]toDec high 0 + } + + +Create node: CLI_Conv_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.9) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) +-> -> CLI_Conv_Prefix(8) + + +Register leaf node: CLI_Conv_Prefix. +Instance: 8 +Length : 37 +Flag : 255 +Default : +Remark : CLI_Conv prefix . + +Field : total(7) +Access : read-write [1]In property + { + [u]0.0-0.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } +[2]Prefix + { + [u]1.0-16.7 + [u]input + [v]ToAscii Low 0 + } +[3]Delete length + { + [u]17.0-17.7 + [u]input + [v]toDec high 0 + } + [4]Out property + { + [u]18.0-18.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } +[5]Add length + { + [u]19.0-19.7 + [u]input + [v]toDec high 0 + } +[6]Add digits + { + [u]20.0-35.7 + [u]input + [v]ToAscii Low 0 + } +[7]Valid length + { + [u]36.0-36.7 + [u]input + [v]toDec high 0 + } + + +Create node: mscid_to_number(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.10) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) +-> -> CLI_Conv_Prefix(8) +-> -> mscid_to_number(9) + + +Register leaf node: mscid_to_number. +Instance: 256 +Length : 12 +Flag : 255 +Default : +Remark : Conv prefix . + +Field : total(4) +Access : read-write[1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } +[3]SSN + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[4]Number + { + [u]4.0-11.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Status_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3) +-> father_name = [XAPP] +-> -> Config_XAPP(0) +-> -> Status_XAPP(1) + + +Remark: XAPP Status. + + +Create node: Version_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.1) +-> father_name = [Status_XAPP] +-> -> Version_XAPP(0) + + +Register leaf node: Version_XAPP. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of XAPP module (Read Only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-only + +Create node: Command_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.2) +-> father_name = [Status_XAPP] +-> -> Version_XAPP(0) +-> -> Command_XAPP(1) + + +Register leaf node: Command_XAPP. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for XAPP. +Save parameter: Save the parameters in memory into local harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + } + + +Create node: Maplat(OID: 1.3.6.1.4.1.1373.1.3.2.3) +-> father_name = [Platform] +-> -> SS7(0) +-> -> Maplat(1) + + +Remark: + Subsystems for Maplat . + + +Create node: SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4) +-> father_name = [Maplat] +-> -> SMPP(0) + + +Remark: Subsystems for SMPP . + + +Create node: Config_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.2) +-> father_name = [SMPP] +-> -> Config_SMPP(0) + + +Remark: SMPP Configuration. + + +Create node: SMPP_Link_Parameter(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.2.1) +-> father_name = [Config_SMPP] +-> -> SMPP_Link_Parameter(0) + + +Register leaf node: SMPP_Link_Parameter. +Instance: 32 +Length : 106 +Flag : 255 +Default : +Remark : Session type: BIND_TX-bind as transmitter, BIND_RX-bind as receiver, BIND_TRX-bind as transceiver. +System ID: using in BIND and OUTBIND. +Password: The password parameter is used by the SMSC to authenticate the identity of the binding ESME. The Service Provider may require ESME¡¯s to provide a password when binding to the SMSC. This password is normally issued by the SMSC system administrator. +The password parameter may also be used by the ESME to authenticate the identity of the binding SMSC (e.g. in the case of the outbind operation). +System type: The system_type may be used to categorise the system, e.g., ¡°EMAIL¡±, ¡°WWW¡±, etc. +The system_type parameter is used to categorize the type of ESME that is binding to the SMSC. Examples include ¡°VMS¡± (voice mail system) and ¡°OTA¡± (over-the-air activation system). +Specification of the system_type is optional - some SMSC¡¯s may not require ESME¡¯s to provide this detail. In this case, the ESME can set the system_type to NULL. +IP: Specify the IP addresses of 16 SMPP connected devices.
e.g. 0xAC127001=172.18.112.1.
+Session init timer: This timer specifies the time lapse allowed between a network connection being established and a bind_transmitter or bind_receiver request being sent to SMSC. This timer should be active on the SMSC. +Enquire link timer: This timer specifies the time lapse allowed between operations after which an SMPP entity should interrogate whether it's peer still has an active session. +The scale is second. +Inactivity timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) +Response timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) +Local service number: compare with application's service number while bind as TX or TRX. +remote service number: compare with application's service number while bind as RX + +Field : total(16) +Access : read-write [1]Link enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Link type + { + [u]1.0-1.7 + [u]select + [v]0[opt]UDP + [v]1[opt]TCP + } + [3]Server type + { + [u]2.0-2.7 + [u]select + [v]0[opt]SMPP_CLIENT + [v]1[opt]SMPP_SERVER + } + [4]Session type + { + [u]3.0-3.7 + [u]select + [v]0[opt]BIND_TX + [v]1[opt]BIND_RX + [v]2[opt]BIND_TRX + } +[5]System ID + { + [u]4.0-19.7 + [u]input + [v]ToAscii Low 0 + } +[6]Password + { + [u]20.0-28.7 + [u]input + [v]ToAscii Low 0 + } +[7]System type + { + [u]29.0-41.7 + [u]input + [v]ToAscii Low 0 + } +[8]Local GTT + { + [u]42.0-57.7 + [u]input + [v]ToAscii Low 0 + } +[9]Remote GTT + { + [u]58.0-73.7 + [u]input + [v]ToAscii Low 0 + } +[10]Local IP + { + [u]74.0-77.7 + [u]input + [v]KeepHex Low F + } +[11]Remote IP + { + [u]78.0-81.7 + [u]input + [v]KeepHex Low F + } +[12]Session init timer + { + [u]82.0-85.7 + [u]input + [v]toDec high 0 + } +[13]Enquire link timer + { + [u]86.0-89.7 + [u]input + [v]toDec high 0 + } +[14]Inactivity timer + { + [u]90.0-93.7 + [u]input + [v]toDec high 0 + } +[15]Response timer + { + [u]94.0-97.7 + [u]input + [v]toDec high 0 + } +[16]Remote service number + { + [u]98.0-105.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Status_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3) +-> father_name = [SMPP] +-> -> Config_SMPP(0) +-> -> Status_SMPP(1) + + +Remark: XAPP Status. + + +Create node: Command_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3.2) +-> father_name = [Status_SMPP] +-> -> Command_SMPP(0) + + +Register leaf node: Command_SMPP. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Control command for SMPP. + +Field : total(1) +Access : write-only [1]Command + { + [u]0.0-0.7 + [u]select + [v]2[opt]save parameter + } + + +Create node: MSC(OID: 1.3.6.1.4.1.1373.1.3.3.2) +-> father_name = [App] +-> -> MSC(0) + + +Remark: + Subsystems for msc . + + +Create node: CCF(MSC)(OID: 1.3.6.1.4.1.1373.1.3.3.2.2) +-> father_name = [MSC] +-> -> CCF(MSC)(0) + + +Remark: Subsystems for msc . + + +Create node: CCF_Config(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2) +-> father_name = [CCF(MSC)] +-> -> CCF_Config(0) + + +Remark: + Configuration for CCF . + + +Create node: Call_Routing(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) + + +Remark: + Call Routing . + + +Create node: Prefix_Assignment(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.1) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) + + +Register leaf node: Prefix_Assignment. +Instance: 256 +Length : 8 +Flag : 255 +Default : îîîîîîîî +Remark : 4 bytes are used to set a 8-digit prefix for dialed number. +Prefix is the first layer for dialed number based call routing. If the dialed number of a call matches a pre-programmed prefix in this table, this call will be routed to a certain trunk group, subsequently that trunk group will route this call via a dedicated E1 port.This system has totally 256 prefixes. +Dialed number without matching a pre-programmed prefix will be routed to the default trunk group 0. +Prefix 252 is for default international call, all internation calls unable to be routed out will be routed from the trunk group assigned to prefix 252, keep default EEEEEEEE. +Prefix 253 is for default national call, all national calls unable to be routed out will be routed from the trunk group assigned to prefix 253, keep default EEEEEEEE. +Prefix 254 is for default subscriber call, all dialed MSISDN unable to be routed out will be routed from the trunk group assigned to prefix 254, keep default EEEEEEEE. +Prefix 255 is for unknown call, all unknown calls unable to be routed out will be routed from the trunk group assigned to prefix 255, keep default EEEEEEEE. +E=End tag, C='#', B='*'. +Default=0xEEEEEEEE. + +Field : total(1) +Access : read-write[1]Prefix + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Prefix_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.2) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) + + +Register leaf node: Prefix_Attributes. +Instance: 256 +Length : 18 +Flag : 9 +Default : " +Remark : Enable: Y=prefix enable, N=prefix disable. +TON incoming call: Type of number for incoming call, include unknown, MSISDN, NDD and IDD. It is specified by originating node for terminating node to route this call with proper dialed number manipulation. +For system subscriber dialed prefix, always use unknown for In-TON except the prefix of international prefix beginning with a . For this kind of prefix (such as 86755832) we should set the In-TON as IDD to support dialing. +TON outgoing call: Type of number for outgoing call, include unknown, MSISDN, NDD and IDD. It specifies the type of an outgoing call for terminating node to route this call with proper dialed number manipulation. Generally the MSC uses IDD for outgoing call. +Out trunk deletion count: Quantity of deleted digit of a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no deletion, 1-8=delete first 1-8 digits. +Out trunk insertion count: Quantity of inserted digit for a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no insertion, 1-8=insert 1-8 digits from the beginning of this number. +Out trunk inserted digits: 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number. +CDR on/off: Turn on/off the CDR of dialed numbers beginning with this prefix. +Properties: Specify the properties of a prefix. Trunk=to PSTN, MSISDN=to A interface, MSRN=MS roaming number, MSC=to peer MSC. +Call type: Normal=no verification for MT, Emergency call=no verification for MO (free call), MCT=Malicious Call Trace, VMS call=send signaling carried DTMF to VMS. +Length of dialed number: Length of dialed number (1-32). +E.164 international deletion count: Quantity of deleted digit of E164 international number, always use IDD for outgoing call for PPS debiting. +E.164 international insertion count: Quantity of inserted digit of E164 international number, always use IDD for outgoing call for PPS debiting. +E.164 international inserted digits: Inserted digit to the E164 international number, 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number, always use IDD for outgoing call for PPS debiting. + +Field : total(15) +Access : read-write [1]TON incoming call + { + [u]0.0-0.3 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [2]TON outgoing call + { + [u]0.4-0.7 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [3]Out trunk deletion count + { + [u]1.0-1.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [4]Out trunk insertion count + { + [u]1.4-1.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } +[5]Out trunk inserted digits + { + [u]2.0-9.7 + [u]input + [v]KeepHex Low E + } + [6]CDR on/off + { + [u]10.0-10.0 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [8]Properties + { + [u]10.2-10.3 + [u]select + [v]0[opt]Trunk + [v]1[opt]MSISDN + [v]2[opt]MSRN + [v]3[opt]MSC + } + [9]Call type + { + [u]10.4-10.6 + [u]select + [v]0[opt]Normal Call + [v]1[opt]Emergency + [v]2[opt]MCT + [v]3[opt]VMS + [v]4[opt]IN + } + [10]Enable + { + [u]10.7-10.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } +[11]Length of dialed number + { + [u]11.0-11.7 + [u]input + [v]toDec high 0 + } + [12]E.164 International deletion count + { + [u]12.0-12.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]Delete first one + [v]2[opt]Delete first two + [v]3[opt]Delete first three + [v]4[opt]Delete first four + [v]5[opt]Delete first five + [v]6[opt]Delete first six + [v]7[opt]Delete first seven + [v]8[opt]Delete first eight + } + [13]E.164 International insertion count + { + [u]12.4-12.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]Insert first one + [v]2[opt]Insert first two + [v]3[opt]Insert first three + [v]4[opt]Insert first four + [v]5[opt]Insert first five + [v]6[opt]Insert first six + [v]7[opt]Insert first seven + [v]8[opt]Insert first eight + } +[14]E.164 international inserted digits + { + [u]13.0-16.7 + [u]input + [v]KeepHex Low E + } + [15]Cli-type + { + [u]17.0-17.7 + [u]select + [v]0[opt]Sub + [v]1[opt]NDD + [v]2[opt]IDD + [v]3[opt]Unknown(local) + [v]4[opt]Unknown(NDD) + [v]5[opt]Unknown(IDD) + } + + +Create node: Prefix_TG(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.3) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) + + +Register leaf node: Prefix_TG. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Assign a trunk group for each prefix for call routing, a single prefix points to only one trunk group, multiple prefix can be assigned the same trunk group, default is the no. of the prefix. + +Field : total(1) +Access : read-write[1]Assign TG to prefix + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: TG_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.4) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) + + +Register leaf node: TG_Attributes. +Instance: 256 +Length : 10 +Flag : 1 +Default : +Remark : DPC: Destination point code of this trunk group. +TG flag: enable or disable this trunk group. +CDR on/off: CDR on or off option for this trunk group. +Announcement: Voice announcement enable or disable for this trunk group. +TG category: PSTN=to PSTN, IP=to VMS and VPS, HPLMN=to HPLMN, VPLMN=to VPLMN, SUB=to BSC, Intercept=to intercept LEA +Alternative TG flag: Alternative trunk group enable or disable option. +Alternative TG: Alternative trunk group for backup purpose. +Loop back: Incoming call loop back enable or disable, used for MSC loop back. +Network indicator: Specify network type, International, International spare , National, National spare. +Circuit selection: Preferred circuit selection mode, include clockwise, anti-clockwise, odd and even. +Back off: Back off on or off when simultaneously select the same channel with the opposite side. +Location: For normal trunk group, select Both. For a trunk group to a VPS, configure this trunk group as MSC0 or MSC1. +MPTY: Multi-party call enable or disable. For all trunk groups to BSC, select Enable. +Tandem restriction:Y: Tandem disabled. Not support transit call from PSTN to PSTN via this trunk group. +N: Tandem enabled. Support transit call from PSTN to PSTN via this trunk group. + +Field : total(16) +Access : read-write[1]DPC + { + [u]0.0-3.7 + [u]input + [v]KeepHex high 0 + } + [2]TG flag + { + [u]4.0-4.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]CDR on/off + { + [u]4.1-4.1 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [4]Announcement + { + [u]4.2-4.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [5]TG category + { + [u]4.3-4.5 + [u]select + [v]0[opt]PSTN + [v]1[opt]HPLMN + [v]2[opt]VHLMN + [v]3[opt]SUB + [v]4[opt]IP + [v]5[opt]Intercept + } + [6]Alternative TG flag + { + [u]4.6-4.6 + [u]select + [v]0[opt]Disable + [v]1[opt]enable + } + [7]Loopback + { + [u]4.7-4.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [8]Network indicator + { + [u]5.0-5.7 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [9]Circuit selection + { + [u]6.0-6.1 + [u]select + [v]0[opt]Clockwise + [v]1[opt]Anti-clockwise + [v]2[opt]Odd + [v]3[opt]Even + } + [10]Back off + { + [u]6.2-6.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [12]MPTY + { + [u]6.5-6.5 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [13]Location + { + [u]6.6-6.7 + [u]select + [v]0[opt]MSC-0 + [v]1[opt]MSC-1 + [v]2[opt]Both + [v]3[opt]Spare + } +[14]Alternative TG + { + [u]7.0-7.7 + [u]input + [v]toDec high 0 + } + [15]Tandem restriction + { + [u]8.0-8.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [16]Incoming Call type + { + [u]9.0-9.7 + [u]select + [v]0[opt]Normal + [v]1[opt]IN + } + + +Create node: Call_Routing_CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.5) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) + + +Register leaf node: Call_Routing_CDR_Flag. +Instance: 1 +Length : 2 +Flag : 255 +Default : ÿ +Remark : Sorm: call intercept MCT: malicious call trace +Default=CDR of MO call and MT call is enabled, CDR of roaming call, gateway incoming call, gateway outgoing call, transit call, MO SMS and MT SMS is disabled. + +Field : total(13) +Access : read-write [2]Redirection + { + [u]0.3-0.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [3]Feature Request + { + [u]0.2-0.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [4]Sorm + { + [u]0.1-0.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [5]MCT + { + [u]0.0-0.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [6]MT SM + { + [u]1.7-1.7 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [7]MO SM + { + [u]1.6-1.6 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [8]Transit call + { + [u]1.5-1.5 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [9]Gateway outgoing call + { + [u]1.4-1.4 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [10]Gateway incoming call + { + [u]1.3-1.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [11]Roaming call + { + [u]1.2-1.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [12]MT call + { + [u]1.1-1.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [13]MO call + { + [u]1.0-1.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + + +Create node: Voice_Prompt_Announcement_option(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.6) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) +-> -> Voice_Prompt_Announcement_option(5) + + +Register leaf node: Voice_Prompt_Announcement_option. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Set to play either announcement or tone indicating call unattainable reason for subscribers. System has total 8 announcements and tones that can be independently set. +Announcement 0: The dialed number is invalid. +Announcement 1: The subscriber dialed is not activated. +Announcement 2: The subscriber is busy. +Announcement 3: The network is busy. +Announcement 4: Caller's account was deactivated. +Announcement 5: The subscriber dialed was deactivated. +Announcement 6: Feature not available to caller. +Announcement 7: The subscriber dialed is not available. + +Field : total(16) +Access : read-write [1]Announcement 0 + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [2]Announcement 1 + { + [u]1.0-1.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [3]Announcement 2 + { + [u]2.0-2.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [4]Announcement 3 + { + [u]3.0-3.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [5]Announcement 4 + { + [u]4.0-4.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [6]Announcement 5 + { + [u]5.0-5.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [7]Announcement 6 + { + [u]6.0-6.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [8]Announcement 7 + { + [u]7.0-7.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [9]Announcement 8 + { + [u]8.0-8.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [10]Announcement 9 + { + [u]9.0-9.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [11]Announcement 10 + { + [u]10.0-10.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [12]Announcement 11 + { + [u]11.0-11.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [13]Announcement 12 + { + [u]12.0-12.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [14]Announcement 13 + { + [u]13.0-13.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [15]Announcement 14 + { + [u]14.0-14.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [16]Announcement 15 + { + [u]15.0-15.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + +Create node: Call_Routing_Warning(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.7) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) +-> -> Voice_Prompt_Announcement_option(5) +-> -> Call_Routing_Warning(6) + + +Register leaf node: Call_Routing_Warning. +Instance: 1 +Length : 1 +Flag : 255 +Default : 2 +Remark : Set time to play prompt tone for reaching zero balance prepaid subscriber when a call is in progress, unit is second. e.g. if set as 60, the system will play prompt tone one minute before a subscriber uses up his balance. + +Field : total(1) +Access : read-write[1]Remanent time for warning tone + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: CCF_MSC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) + + +Remark: CCF Configuration MSC . + + +Create node: Emergency_Call(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2.5) +-> father_name = [CCF_MSC] +-> -> Emergency_Call(0) + + +Register leaf node: Emergency_Call. +Instance: 256 +Length : 21 +Flag : 0 +Default : +Remark : Emergency call number. Default=112. + +Field : total(5) +Access : read-write [1]Enable flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]LAC + { + [u]1.0-2.7 + [u]input + [v]toDec high 0 + } +[3]CI + { + [u]3.0-4.7 + [u]input + [v]toDec high 0 + } +[4]Dial number + { + [u]5.0-12.7 + [u]input + [v]KeepHex Low E + } +[5]Local emergency number + { + [u]13.0-20.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Location_Management(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2.8) +-> father_name = [CCF_MSC] +-> -> Emergency_Call(0) +-> -> Location_Management(1) + + +Register leaf node: Location_Management. +Instance: 256 +Length : 8 +Flag : 0 +Default : +Remark : Manage the MS location by correlate TG (trunk group), LAC (location area code, cell ID and zone code, totally 256 location management. + +Field : total(5) +Access : read-write [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } +[2]TG + { + [u]1.0-1.7 + [u]input + [v]toDec high 0 + } +[3]LAC + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[4]CI + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } +[5]Zone Code + { + [u]6.0-7.7 + [u]input + [v]toDec high 0 + } + + +Create node: CPC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) + + +Remark: CPC Management. + + +Create node: SRF_Address(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3.3) +-> father_name = [CPC] +-> -> SRF_Address(0) + + +Register leaf node: SRF_Address. +Instance: 1 +Length : 8 +Flag : 255 +Default : †uP +Remark : E.164 number of HLR server:HLR MSISDN used for SCCP addressing, F=end tag. +Default=91867555950502FFFF=91867555950502. + +Field : total(1) +Access : read-write[1]EIR number + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Max_Call_Duration(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3.7) +-> father_name = [CPC] +-> -> SRF_Address(0) +-> -> Max_Call_Duration(1) + + +Register leaf node: Max_Call_Duration. +Instance: 1 +Length : 1 +Flag : 255 +Default : < +Remark : Define the permitted maximum call duration. Any ongoing call reaching this duration threshold will be compulsively cut off. byte value: 0=disable this function, 1-255=max. call duration, unit=minute. Default=0. + +Field : total(1) +Access : read-write[1]Max. call duration + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_Port(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) + + +Remark: E1 Port. + + +Create node: E1_Interface(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.1) +-> father_name = [E1_Port] +-> -> E1_Interface(0) + + +Register leaf node: E1_Interface. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Set the type of E1 interface for 256 E1 ports. + +Field : total(1) +Access : read-write [1]E1 interface + { + [u]0.0-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF CDMA2K + [v]4[opt]BICC + [v]5[opt]CI-CNF + [v]6[opt]CI-loopback + } + + +Create node: E1_TG(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.2) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) + + +Register leaf node: E1_TG. +Instance: 256 +Length : 1 +Flag : 255 +Default : î +Remark : Assign a trunk group to each E1 port for call routing. A single E1 port points to only one trunk group, multiple E1 port can be assigned the same trunk group. Default=number of the E1 port. + +Field : total(1) +Access : read-write[1]Assign TG + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_CIC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.3) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) +-> -> E1_CIC(2) + + +Register leaf node: E1_CIC. +Instance: 256 +Length : 4 +Flag : 255 +Default : +Remark : Circuit identity code, uniquely identify each circuit within a trunk group. CIC of both ends of a circuit must be identical. 256 CIC for dual MSC platform 256 E1 ports. + +Field : total(1) +Access : read-write[1]E1 CIC + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_Media_Control_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.4) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) +-> -> E1_CIC(2) +-> -> E1_Media_Control_Attributes(3) + + +Register leaf node: E1_Media_Control_Attributes. +Instance: 256 +Length : 4 +Flag : 255 +Default : +Remark : E1 Media Control Attributes + +Field : total(4) +Access : read-write [1]E1 Control Protocol Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Internal + [v]1[opt]MGCP + } + [2]E1 Enable + { + [u]1.0-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[3]MG Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } +[4]Trunk Number + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Channel_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) + + +Remark: Channel attributes. + + +Create node: Card0_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.1) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) + + +Register leaf node: Card0_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card1_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.2) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) + + +Register leaf node: Card1_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card2_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.3) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) + + +Register leaf node: Card2_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card3_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.4) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) + + +Register leaf node: Card3_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card4_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.5) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) + + +Register leaf node: Card4_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card5_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.6) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) + + +Register leaf node: Card5_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card6_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.7) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) + + +Register leaf node: Card6_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card7_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.8) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) + + +Register leaf node: Card7_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card8_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.9) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) + + +Register leaf node: Card8_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card9_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.10) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) + + +Register leaf node: Card9_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card10_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.11) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) + + +Register leaf node: Card10_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card11_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.12) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) + + +Register leaf node: Card11_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card12_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.13) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) + + +Register leaf node: Card12_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card13_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.14) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) + + +Register leaf node: Card13_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card14_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.15) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) + + +Register leaf node: Card14_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card15_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.16) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) + + +Register leaf node: Card15_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card16_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.17) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) + + +Register leaf node: Card16_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card17_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.18) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) + + +Register leaf node: Card17_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card18_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.19) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) + + +Register leaf node: Card18_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card19_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.20) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) + + +Register leaf node: Card19_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card20_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.21) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) + + +Register leaf node: Card20_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card21_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.22) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) + + +Register leaf node: Card21_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card22_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.23) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) + + +Register leaf node: Card22_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card23_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.24) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) + + +Register leaf node: Card23_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card24_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.25) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) + + +Register leaf node: Card24_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card25_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.26) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) + + +Register leaf node: Card25_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card26_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.27) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) + + +Register leaf node: Card26_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card27_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.28) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) + + +Register leaf node: Card27_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card28_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.29) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) + + +Register leaf node: Card28_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card29_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.30) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) + + +Register leaf node: Card29_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card30_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.31) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) +-> -> Card30_Channel(30) + + +Register leaf node: Card30_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card31_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.32) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) +-> -> Card30_Channel(30) +-> -> Card31_Channel(31) + + +Register leaf node: Card31_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: CPC_attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.6) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) +-> -> CPC_attributes(5) + + +Remark: CPC attributes. + + +Create node: MSCID(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.6.3) +-> father_name = [CPC_attributes] +-> -> MSCID(0) + + +Register leaf node: MSCID. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : MSCID + +Field : total(2) +Access : read-write[1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Media_gateway(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.7) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) +-> -> CPC_attributes(5) +-> -> Media_gateway(6) + + +Remark: Media_gateway . + + +Create node: MG_Attribute(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.7.1) +-> father_name = [Media_gateway] +-> -> MG_Attribute(0) + + +Register leaf node: MG_Attribute. +Instance: 256 +Length : 53 +Flag : 255 +Default : +Remark : MG Attributes + +Field : total(3) +Access : read-only [1]MG Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]MG IP Address + { + [u]1.0-4.7 + [u]input + [v]KeepHex high 0 + } +[3]MG Name + { + [u]5.0-52.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: CCF_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3) +-> father_name = [CCF(MSC)] +-> -> CCF_Config(0) +-> -> CCF_Status(1) + + +Remark: Status for CCF . + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.1) +-> father_name = [CCF_Status] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of MSC software (Read only).
+Byte0: System release version number, based on basic function and structure.
+Byte1: Software module version number, based on software module.
+Byte2: Test version, 0=Release version number, 1=Test version number.. + +Field : total(0) +Access : read-only + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.2) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : î +Remark : Control command for MSC-CPC. +Reset: Used for CPC status initialization. +Initialize: Restore the parameter setup to the default factory setting. +Save parameter: Save the parameters residing in CPC's memory into CPC's harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]90[opt]Reset + [v]165[opt]Initialize + [v]181[opt]Save parameter + [v]238[opt]No command + } + + +Create node: E1_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.4) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) +-> -> E1_Status(2) + + +Register leaf node: E1_Status. +Instance: 128 +Length : 1 +Flag : 255 +Default : î +Remark : E1 status (read only). + +Field : total(2) +Access : read-only[1]Quantity of occupied timeslot + { + [u]0.0-0.4 + [u]input + [v]toDec high 0 + } + [2]E1 type + { + [u]0.5-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF_CDMA2K + [v]4[opt]BICC + } + + +Create node: Channel_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) +-> -> E1_Status(2) +-> -> Channel_Status(3) + + +Remark: Channel status (read only). + + +Create node: Card0_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.1) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) + + +Register leaf node: Card0_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card1_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.2) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) + + +Register leaf node: Card1_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card2_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.3) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) + + +Register leaf node: Card2_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card3_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.4) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) + + +Register leaf node: Card3_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card4_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.5) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) + + +Register leaf node: Card4_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card5_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.6) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) + + +Register leaf node: Card5_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card6_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.7) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) + + +Register leaf node: Card6_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card7_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.8) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) + + +Register leaf node: Card7_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card8_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.9) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) + + +Register leaf node: Card8_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card9_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.10) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) + + +Register leaf node: Card9_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card10_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.11) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) + + +Register leaf node: Card10_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card11_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.12) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) + + +Register leaf node: Card11_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card12_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.13) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) + + +Register leaf node: Card12_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card13_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.14) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) + + +Register leaf node: Card13_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card14_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.15) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) +-> -> Card14_Status(14) + + +Register leaf node: Card14_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card15_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.16) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) +-> -> Card14_Status(14) +-> -> Card15_Status(15) + + +Register leaf node: Card15_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: VLR(OID: 1.3.6.1.4.1.1373.1.3.3.2.5) +-> father_name = [MSC] +-> -> CCF(MSC)(0) +-> -> VLR(1) + + +Remark: sub for VLR . + + +Create node: VLR_Config(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2) +-> father_name = [VLR] +-> -> VLR_Config(0) + + +Remark: + Configuration for VLR . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1) +-> father_name = [VLR_Config] +-> -> Public_Param(0) + + +Remark: Public parameters . + + +Create node: OptAuthReq(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.1) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) + + +Register leaf node: OptAuthReq. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of SIM authentication on MS poweron and MO/MT call. + +Field : total(4) +Access : read-write [1]Update Location + { + [u]0.0-0.0 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [2]MO + { + [u]0.1-0.1 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [3]MT + { + [u]0.2-0.2 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } +[4]Spare + { + [u]0.3-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptReuseTriplets(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.2) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) + + +Register leaf node: OptReuseTriplets. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of reusing authentication triplets in VLR in the case that authentication to HLR is not available. Default=disable. + +Field : total(3) +Access : read-write [1]OptReuseTriplets + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]double authentication + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[3]Spare + { + [u]0.2-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptCipReq(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.3) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) + + +Register leaf node: OptCipReq. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of voice ciphering over air interface by MS. Default=Disable. + +Field : total(1) +Access : read-write [1]OptCipReq + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: OptCiphAlgo(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.4) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) + + +Register leaf node: OptCiphAlgo. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Voice ciphering algorithm selection. Default=no ciphering. + +Field : total(1) +Access : read-write [1]OptCiphAlgo + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]A5_1 + [v]2[opt]A5_2 + [v]3[opt]A5_3 + [v]4[opt]A5_4 + [v]5[opt]A5_5 + [v]6[opt]A5_6 + [v]7[opt]A5_7 + } + + +Create node: OptTmsiAlloc(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.5) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) + + +Register leaf node: OptTmsiAlloc. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Flag of allocating a new TMSI every time a call management service is requested. Default=Disable. + +Field : total(1) +Access : read-write [1]TMSI Allocation Option + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Allocate TMSI + [v]2[opt]Reallocate TMSI + } + + +Create node: OptEcSetUpAllow(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.7) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) + + +Register leaf node: OptEcSetUpAllow. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Flag of making emergency call for non-registered MS or MS without SIM. Default=Enable. + +Field : total(1) +Access : read-write [1]OptEcSetUpAllow + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: OptCheckIMEI(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.8) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) + + +Register leaf node: OptCheckIMEI. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of IMEI verification via EIR. Default=no IMEI verification. + +Field : total(4) +Access : read-write [1]Update Location + { + [u]0.0-0.0 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [2]MO + { + [u]0.1-0.1 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [3]MT + { + [u]0.2-0.2 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } +[4]Spare + { + [u]0.3-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptVlrPurge(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.9) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) + + +Register leaf node: OptVlrPurge. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of VLR purge. Default=Off. + +Field : total(1) +Access : read-write [1]OptVlrPurge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: IdlePeriod2Purge(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.10) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) + + +Register leaf node: IdlePeriod2Purge. +Instance: 1 +Length : 1 +Flag : 255 +Default : < +Remark : Set the threshold of idle time to purge. If a mobile's idle time reaches this threshold, VLR will purge all records of this MS, unit=6 minute. Default=60minutes. + +Field : total(1) +Access : read-write[1]IdlePeriod2Purge + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.11) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) +-> -> CDR_Flag(9) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : VLR CDR flag. Default=On. + +Field : total(1) +Access : read-write [1]CDR on/off + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: MSRN(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.13) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) +-> -> CDR_Flag(9) +-> -> MSRN(10) + + +Register leaf node: MSRN. +Instance: 1 +Length : 16 +Flag : 255 +Default : †uS@ +Remark : Mobile station roaming number, use 16 bytes (32 digits) to define a range of MSRN. The length of start MSRN and end MSRN must be identical. F=end tag. + +Field : total(2) +Access : read-write[3]Start number + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low F + } +[4]End number + { + [u]8.0-15.7 + [u]input + [v]KeepHex Low F + } + + +Create node: VLR_Management(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3) +-> father_name = [VLR] +-> -> VLR_Config(0) +-> -> VLR_Management(1) + + +Remark: + Management for VLR . + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.2) +-> father_name = [VLR_Management] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of VLR software (Read only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-only + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.3) +-> father_name = [VLR_Management] +-> -> Version(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : î +Remark : Control command for VLR. +Reset: Used to initialize the status of VLR. +Save parameters: Save the parameters residing in memory into harddisk. + +Field : total(1) +Access : write-only [1]Management + { + [u]0.0-0.7 + [u]select + [v]0[opt]Reset VLR + [v]1[opt]Save parameters + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.4) +-> father_name = [VLR_Management] +-> -> Version(0) +-> -> Command(1) +-> -> Status(2) + + +Register leaf node: Status. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Basic status of VLR. + +Field : total(0) +Access : read-only + +Create node: HLR(OID: 1.3.6.1.4.1.1373.1.3.3.3) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) + + +Remark: Subsystems for HLR . + + +Create node: Config(OID: 1.3.6.1.4.1.1373.1.3.3.3.2) +-> father_name = [HLR] +-> -> Config(0) + + +Remark: + Configuration for HLR . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1) +-> father_name = [Config] +-> -> Public_Param(0) + + +Remark: + Public parameter . + + +Create node: HPLMN(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.11) +-> father_name = [Public_Param] +-> -> HPLMN(0) + + +Register leaf node: HPLMN. +Instance: 1 +Length : 17 +Flag : 255 +Default : îîîîîîîîîîîîîîîîî +Remark : Define the SN (VLR phone number) range of the VLR in the HPLMN (home PLMN) by specifying the start and end phone number of the range. +MSISDN=CC(country code)+NDC(National Destination Code)+SN. +All VLRs within a HPLMN have the same CC and NDC but the different SN. The SN of all VLR in a HPLMN must lie within the defined SN range. +Byte0-1=Country code. +Byte2-3=National destination code. +Byte4-9=Start SN of the VLR SN. +Byte10-15=End SN of the VLR SN. +e.g. For China country code=86, Shanghai national destination code=21, VLR SN=26060888: +Byte0-1=86EE, +Byte2-3=21EE, +SN=26060888, +Else=E. + +Field : total(4) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]NDC + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Start SN + { + [u]5.0-10.7 + [u]input + [v]KeepHex Low E + } +[4]End SN + { + [u]11.0-16.7 + [u]input + [v]KeepHex Low E + } + + +Create node: VPLMNs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.12) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) + + +Register leaf node: VPLMNs. +Instance: 256 +Length : 17 +Flag : 255 +Default : îîîîîîîîîîîîîîîîî +Remark : Define all connected VPLMNs (up tp 256) by specifying all VLR zones included in these VPLMNs. Each VLR zone is defined by its VLR MSISDN. MSISDN=CC+NDC+SN. All VLRs within a same VPLMN have the CC and NDC but the different SN. A VPLMN contains a group of VLRs whose SN is included in the defined SN range, E=random digit. +This parameter also define two ranges of VLR CSRR (Country specific roaming restrictionszones) zones for each VPLMN. In these defined VLR CSRR zones all HPLMN subscribers may be subjected to country specific roaming restrictions. +For each VPLMN setup, the format is: +byte0=ISDN numbering plan, default=91. +byte1-2=country code, EEEE. +byte3-4=national destination code, EEEE. +byte5-10=start SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. +byte11-16=end SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. +byte17-22=start SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte23-28=end SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte29-34=start SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte35-40=end SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +E=random digit. + +Field : total(4) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]NDC + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Start SN + { + [u]5.0-10.7 + [u]input + [v]KeepHex Low E + } +[4]End SN + { + [u]11.0-16.7 + [u]input + [v]KeepHex Low E + } + + +Create node: CSRR_List(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.13) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) + + +Register leaf node: CSRR_List. +Instance: 8 +Length : 32 +Flag : 255 +Default : +Remark : Define 8 CSRR (country specific roaming restriction) lists to confine the roaming range of a subscriber. +Each CSRR list defines the roaming restriction for 256 VPLMN ranges. + +Field : total(256) +Access : read-write [1]VPLMN0 Roaming allowed + { + [u]31.0-31.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [2]VPLMN1 Roaming allowed + { + [u]31.1-31.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [3]VPLMN2 Roaming allowed + { + [u]31.2-31.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [4]VPLMN3 Roaming allowed + { + [u]31.3-31.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [5]VPLMN4 Roaming allowed + { + [u]31.4-31.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [6]VPLMN5 Roaming allowed + { + [u]31.5-31.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [7]VPLMN6 Roaming allowed + { + [u]31.6-31.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [8]VPLMN7 Roaming allowed + { + [u]31.7-31.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [9]VPLMN8 Roaming allowed + { + [u]30.0-30.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [10]VPLMN9 Roaming allowed + { + [u]30.1-30.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [11]VPLMN10 Roaming allowed + { + [u]30.2-30.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [12]VPLMN11 Roaming allowed + { + [u]30.3-30.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [13]VPLMN12 Roaming allowed + { + [u]30.4-30.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [14]VPLMN13 Roaming allowed + { + [u]30.5-30.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [15]VPLMN14 Roaming allowed + { + [u]30.6-30.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [16]VPLMN15 Roaming allowed + { + [u]30.7-30.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [17]VPLMN16 Roaming allowed + { + [u]29.0-29.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [18]VPLMN17 Roaming allowed + { + [u]29.1-29.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [19]VPLMN18 Roaming allowed + { + [u]29.2-29.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [20]VPLMN19 Roaming allowed + { + [u]29.3-29.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [21]VPLMN20 Roaming allowed + { + [u]29.4-29.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [22]VPLMN21 Roaming allowed + { + [u]29.5-29.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [23]VPLMN22 Roaming allowed + { + [u]29.6-29.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [24]VPLMN23 Roaming allowed + { + [u]29.7-29.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [25]VPLMN24 Roaming allowed + { + [u]28.0-28.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [26]VPLMN25 Roaming allowed + { + [u]28.1-28.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [27]VPLMN26 Roaming allowed + { + [u]28.2-28.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [28]VPLMN27 Roaming allowed + { + [u]28.3-28.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [29]VPLMN28 Roaming allowed + { + [u]28.4-28.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [30]VPLMN29 Roaming allowed + { + [u]28.5-28.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [31]VPLMN30 Roaming allowed + { + [u]28.6-28.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [32]VPLMN31 Roaming allowed + { + [u]28.7-28.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [33]VPLMN32 Roaming allowed + { + [u]27.0-27.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [34]VPLMN33 Roaming allowed + { + [u]27.1-27.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [35]VPLMN34 Roaming allowed + { + [u]27.2-27.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [36]VPLMN35 Roaming allowed + { + [u]27.3-27.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [37]VPLMN36 Roaming allowed + { + [u]27.4-27.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [38]VPLMN37 Roaming allowed + { + [u]27.5-27.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [39]VPLMN38 Roaming allowed + { + [u]27.6-27.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [40]VPLMN39 Roaming allowed + { + [u]27.7-27.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [41]VPLMN40 Roaming allowed + { + [u]26.0-26.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [42]VPLMN41 Roaming allowed + { + [u]26.1-26.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [43]VPLMN42 Roaming allowed + { + [u]26.2-26.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [44]VPLMN43 Roaming allowed + { + [u]26.3-26.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [45]VPLMN44 Roaming allowed + { + [u]26.4-26.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [46]VPLMN45 Roaming allowed + { + [u]26.5-26.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [47]VPLMN46 Roaming allowed + { + [u]26.6-26.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [48]VPLMN47 Roaming allowed + { + [u]26.7-26.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [49]VPLMN48 Roaming allowed + { + [u]25.0-25.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [50]VPLMN49 Roaming allowed + { + [u]25.1-25.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [51]VPLMN50 Roaming allowed + { + [u]25.2-25.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [52]VPLMN51 Roaming allowed + { + [u]25.3-25.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [53]VPLMN52 Roaming allowed + { + [u]25.4-25.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [54]VPLMN53 Roaming allowed + { + [u]25.5-25.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [55]VPLMN54 Roaming allowed + { + [u]25.6-25.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [56]VPLMN55 Roaming allowed + { + [u]25.7-25.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [57]VPLMN56 Roaming allowed + { + [u]24.0-24.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [58]VPLMN57 Roaming allowed + { + [u]24.1-24.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [59]VPLMN58 Roaming allowed + { + [u]24.2-24.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [60]VPLMN59 Roaming allowed + { + [u]24.3-24.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [61]VPLMN60 Roaming allowed + { + [u]24.4-24.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [62]VPLMN61 Roaming allowed + { + [u]24.5-24.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [63]VPLMN62 Roaming allowed + { + [u]24.6-24.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [64]VPLMN63 Roaming allowed + { + [u]24.7-24.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [65]VPLMN64 Roaming allowed + { + [u]23.0-23.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [66]VPLMN65 Roaming allowed + { + [u]23.1-23.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [67]VPLMN66 Roaming allowed + { + [u]23.2-23.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [68]VPLMN67 Roaming allowed + { + [u]23.3-23.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [69]VPLMN68 Roaming allowed + { + [u]23.4-23.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [70]VPLMN69 Roaming allowed + { + [u]23.5-23.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [71]VPLMN70 Roaming allowed + { + [u]23.6-23.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [72]VPLMN71 Roaming allowed + { + [u]23.7-23.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [73]VPLMN72 Roaming allowed + { + [u]22.0-22.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [74]VPLMN73 Roaming allowed + { + [u]22.1-22.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [75]VPLMN74 Roaming allowed + { + [u]22.2-22.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [76]VPLMN75 Roaming allowed + { + [u]22.3-22.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [77]VPLMN76 Roaming allowed + { + [u]22.4-22.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [78]VPLMN77 Roaming allowed + { + [u]22.5-22.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [79]VPLMN78 Roaming allowed + { + [u]22.6-22.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [80]VPLMN79 Roaming allowed + { + [u]22.7-22.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [81]VPLMN80 Roaming allowed + { + [u]21.0-21.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [82]VPLMN81 Roaming allowed + { + [u]21.1-21.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [83]VPLMN82 Roaming allowed + { + [u]21.2-21.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [84]VPLMN83 Roaming allowed + { + [u]21.3-21.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [85]VPLMN84 Roaming allowed + { + [u]21.4-21.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [86]VPLMN85 Roaming allowed + { + [u]21.5-21.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [87]VPLMN86 Roaming allowed + { + [u]21.6-21.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [88]VPLMN87 Roaming allowed + { + [u]21.7-21.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [89]VPLMN88 Roaming allowed + { + [u]20.0-20.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [90]VPLMN89 Roaming allowed + { + [u]20.1-20.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [91]VPLMN90 Roaming allowed + { + [u]20.2-20.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [92]VPLMN91 Roaming allowed + { + [u]20.3-20.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [93]VPLMN92 Roaming allowed + { + [u]20.4-20.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [94]VPLMN93 Roaming allowed + { + [u]20.5-20.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [95]VPLMN94 Roaming allowed + { + [u]20.6-20.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [96]VPLMN95 Roaming allowed + { + [u]20.7-20.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [97]VPLMN96 Roaming allowed + { + [u]19.0-19.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [98]VPLMN97 Roaming allowed + { + [u]19.1-19.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [99]VPLMN98 Roaming allowed + { + [u]19.2-19.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [100]VPLMN99 Roaming allowed + { + [u]19.3-19.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [101]VPLMN100 Roaming allowed + { + [u]19.4-19.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [102]VPLMN101 Roaming allowed + { + [u]19.5-19.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [103]VPLMN102 Roaming allowed + { + [u]19.6-19.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [104]VPLMN103 Roaming allowed + { + [u]19.7-19.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [105]VPLMN104 Roaming allowed + { + [u]18.0-18.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [106]VPLMN105 Roaming allowed + { + [u]18.1-18.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [107]VPLMN106 Roaming allowed + { + [u]18.2-18.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [108]VPLMN107 Roaming allowed + { + [u]18.3-18.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [109]VPLMN108 Roaming allowed + { + [u]18.4-18.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [110]VPLMN109 Roaming allowed + { + [u]18.5-18.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [111]VPLMN110 Roaming allowed + { + [u]18.6-18.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [112]VPLMN111 Roaming allowed + { + [u]18.7-18.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [113]VPLMN112 Roaming allowed + { + [u]17.0-17.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [114]VPLMN113 Roaming allowed + { + [u]17.1-17.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [115]VPLMN114 Roaming allowed + { + [u]17.2-17.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [116]VPLMN115 Roaming allowed + { + [u]17.3-17.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [117]VPLMN116 Roaming allowed + { + [u]17.4-17.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [118]VPLMN117 Roaming allowed + { + [u]17.5-17.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [119]VPLMN118 Roaming allowed + { + [u]17.6-17.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [120]VPLMN119 Roaming allowed + { + [u]17.7-17.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [121]VPLMN120 Roaming allowed + { + [u]16.0-16.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [122]VPLMN121 Roaming allowed + { + [u]16.1-16.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [123]VPLMN122 Roaming allowed + { + [u]16.2-16.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [124]VPLMN123 Roaming allowed + { + [u]16.3-16.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [125]VPLMN124 Roaming allowed + { + [u]16.4-16.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [126]VPLMN125 Roaming allowed + { + [u]16.5-16.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [127]VPLMN126 Roaming allowed + { + [u]16.6-16.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [128]VPLMN127 Roaming allowed + { + [u]16.7-16.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [129]VPLMN128 Roaming allowed + { + [u]15.0-15.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [130]VPLMN129 Roaming allowed + { + [u]15.1-15.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [131]VPLMN130 Roaming allowed + { + [u]15.2-15.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [132]VPLMN131 Roaming allowed + { + [u]15.3-15.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [133]VPLMN132 Roaming allowed + { + [u]15.4-15.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [134]VPLMN133 Roaming allowed + { + [u]15.5-15.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [135]VPLMN134 Roaming allowed + { + [u]15.6-15.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [136]VPLMN135 Roaming allowed + { + [u]15.7-15.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [137]VPLMN136 Roaming allowed + { + [u]14.0-14.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [138]VPLMN137 Roaming allowed + { + [u]14.1-14.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [139]VPLMN138 Roaming allowed + { + [u]14.2-14.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [140]VPLMN139 Roaming allowed + { + [u]14.3-14.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [141]VPLMN140 Roaming allowed + { + [u]14.4-14.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [142]VPLMN141 Roaming allowed + { + [u]14.5-14.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [143]VPLMN142 Roaming allowed + { + [u]14.6-14.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [144]VPLMN143 Roaming allowed + { + [u]14.7-14.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [145]VPLMN144 Roaming allowed + { + [u]13.0-13.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [146]VPLMN145 Roaming allowed + { + [u]13.1-13.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [147]VPLMN146 Roaming allowed + { + [u]13.2-13.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [148]VPLMN147 Roaming allowed + { + [u]13.3-13.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [149]VPLMN148 Roaming allowed + { + [u]13.4-13.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [150]VPLMN149 Roaming allowed + { + [u]13.5-13.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [151]VPLMN150 Roaming allowed + { + [u]13.6-13.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [152]VPLMN151 Roaming allowed + { + [u]13.7-13.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [153]VPLMN152 Roaming allowed + { + [u]12.0-12.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [154]VPLMN153 Roaming allowed + { + [u]12.1-12.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [155]VPLMN154 Roaming allowed + { + [u]12.2-12.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [156]VPLMN155 Roaming allowed + { + [u]12.3-12.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [157]VPLMN156 Roaming allowed + { + [u]12.4-12.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [158]VPLMN157 Roaming allowed + { + [u]12.5-12.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [159]VPLMN158 Roaming allowed + { + [u]12.6-12.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [160]VPLMN159 Roaming allowed + { + [u]12.7-12.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [161]VPLMN160 Roaming allowed + { + [u]11.0-11.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [162]VPLMN161 Roaming allowed + { + [u]11.1-11.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [163]VPLMN162 Roaming allowed + { + [u]11.2-11.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [164]VPLMN163 Roaming allowed + { + [u]11.3-11.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [165]VPLMN164 Roaming allowed + { + [u]11.4-11.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [166]VPLMN165 Roaming allowed + { + [u]11.5-11.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [167]VPLMN166 Roaming allowed + { + [u]11.6-11.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [168]VPLMN167 Roaming allowed + { + [u]11.7-11.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [169]VPLMN168 Roaming allowed + { + [u]10.0-10.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [170]VPLMN169 Roaming allowed + { + [u]10.1-10.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [171]VPLMN170 Roaming allowed + { + [u]10.2-10.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [172]VPLMN171 Roaming allowed + { + [u]10.3-10.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [173]VPLMN172 Roaming allowed + { + [u]10.4-10.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [174]VPLMN173 Roaming allowed + { + [u]10.5-10.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [175]VPLMN174 Roaming allowed + { + [u]10.6-10.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [176]VPLMN175 Roaming allowed + { + [u]10.7-10.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [177]VPLMN176 Roaming allowed + { + [u]9.0-9.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [178]VPLMN177 Roaming allowed + { + [u]9.1-9.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [179]VPLMN178 Roaming allowed + { + [u]9.2-9.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [180]VPLMN179 Roaming allowed + { + [u]9.3-9.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [181]VPLMN180 Roaming allowed + { + [u]9.4-9.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [182]VPLMN181 Roaming allowed + { + [u]9.5-9.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [183]VPLMN182 Roaming allowed + { + [u]9.6-9.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [184]VPLMN183 Roaming allowed + { + [u]9.7-9.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [185]VPLMN184 Roaming allowed] + { + [u]8.0-8.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [186]VPLMN185 Roaming allowed + { + [u]8.1-8.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [187]VPLMN186 Roaming allowed + { + [u]8.2-8.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [188]VPLMN187 Roaming allowed + { + [u]8.3-8.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [189]VPLMN188 Roaming allowed + { + [u]8.4-8.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [190]VPLMN189 Roaming allowed + { + [u]8.5-8.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [191]VPLMN190 Roaming allowed + { + [u]8.6-8.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [192]VPLMN191 Roaming allowed + { + [u]8.7-8.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [193]VPLMN192 Roaming allowed + { + [u]7.0-7.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [194]VPLMN193 Roaming allowed + { + [u]7.1-7.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [195]VPLMN194 Roaming allowed + { + [u]7.2-7.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [196]VPLMN195 Roaming allowed + { + [u]7.3-7.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [197]VPLMN196 Roaming allowed + { + [u]7.4-7.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [198]VPLMN197 Roaming allowed + { + [u]7.5-7.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [199]VPLMN198 Roaming allowed + { + [u]7.6-7.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [200]VPLMN199 Roaming allowed + { + [u]7.7-7.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [201]VPLMN200 Roaming allowed + { + [u]6.0-6.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [202]VPLMN201 Roaming allowed + { + [u]6.1-6.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [203]VPLMN202 Roaming allowed + { + [u]6.2-6.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [204]VPLMN203 Roaming allowed + { + [u]6.3-6.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [205]VPLMN204 Roaming allowed + { + [u]6.4-6.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [206]VPLMN205 Roaming allowed + { + [u]6.5-6.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [207]VPLMN206 Roaming allowed + { + [u]6.6-6.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [208]VPLMN207 Roaming allowed + { + [u]6.7-6.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [209]VPLMN208 Roaming allowed + { + [u]5.0-5.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [210]VPLMN209 Roaming allowed + { + [u]5.1-5.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [211]VPLMN210 Roaming allowed + { + [u]5.2-5.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [212]VPLMN211 Roaming allowed + { + [u]5.3-5.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [213]VPLMN212 Roaming allowed + { + [u]5.4-5.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [214]VPLMN213 Roaming allowed + { + [u]5.5-5.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [215]VPLMN214 Roaming allowed + { + [u]5.6-5.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [216]VPLMN215 Roaming allowed + { + [u]5.7-5.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [217]VPLMN216 Roaming allowed + { + [u]4.0-4.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [218]VPLMN217 Roaming allowed + { + [u]4.1-4.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [219]VPLMN218 Roaming allowed + { + [u]4.2-4.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [220]VPLMN219 Roaming allowed + { + [u]4.3-4.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [221]VPLMN220 Roaming allowed + { + [u]4.4-4.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [222]VPLMN221 Roaming allowed + { + [u]4.5-4.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [223]VPLMN222 Roaming allowed + { + [u]4.6-4.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [224]VPLMN223 Roaming allowed + { + [u]4.7-4.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [225]VPLMN224 Roaming allowed + { + [u]3.0-3.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [226]VPLMN225 Roaming allowed + { + [u]3.1-3.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [227]VPLMN226 Roaming allowed + { + [u]3.2-3.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [228]VPLMN227 Roaming allowed + { + [u]3.3-3.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [229]VPLMN228 Roaming allowed + { + [u]3.4-3.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [230]VPLMN229 Roaming allowed + { + [u]3.5-3.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [231]VPLMN230 Roaming allowed + { + [u]3.6-3.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [232]VPLMN231 Roaming allowed + { + [u]3.7-3.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [233]VPLMN232 Roaming allowed + { + [u]2.0-2.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [234]VPLMN233 Roaming allowed + { + [u]2.1-2.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [235]VPLMN234 Roaming allowed + { + [u]2.2-2.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [236]VPLMN235 Roaming allowed + { + [u]2.3-2.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [237]VPLMN236 Roaming allowed + { + [u]2.4-2.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [238]VPLMN237 Roaming allowed + { + [u]2.5-2.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [239]VPLMN238 Roaming allowed + { + [u]2.6-2.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [240]VPLMN239 Roaming allowed + { + [u]2.7-2.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [241]VPLMN240 Roaming allowed + { + [u]1.0-1.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [242]VPLMN241 Roaming allowed + { + [u]1.1-1.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [243]VPLMN242 Roaming allowed + { + [u]1.2-1.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [244]VPLMN243 Roaming allowed + { + [u]1.3-1.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [245]VPLMN244 Roaming allowed + { + [u]1.4-1.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [246]VPLMN245 Roaming allowed + { + [u]1.5-1.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [247]VPLMN246 Roaming allowed + { + [u]1.6-1.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [248]VPLMN247 Roaming allowed + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [249]VPLMN248 Roaming allowed + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [250]VPLMN249 Roaming allowed + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [251]VPLMN250 Roaming allowed + { + [u]0.2-0.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [252]VPLMN251 Roaming allowed + { + [u]0.3-0.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [253]VPLMN252 Roaming allowed + { + [u]0.4-0.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [254]VPLMN253 Roaming allowed + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [255]VPLMN254 Roaming allowed + { + [u]0.6-0.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [256]VPLMN255 Roaming allowed + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Regional_Subs_List(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.14) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) + + +Register leaf node: Regional_Subs_List. +Instance: 255 +Length : 7 +Flag : 255 +Default : îîîîîîî +Remark : Define the regional subscription zone code list. HLR supports up to 256 regional subscription zone code. +Regional subscription code = CC+NDC+zone code + +Field : total(3) +Access : read-write[1]Country Code + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]National Destination Code + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Zone Code + { + [u]5.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Licenses_Control(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.15) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) + + +Register leaf node: Licenses_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of HLR subscribers for service provider: +The new license can not support less HLR subscribers than what the old license supports. + +Field : total(1) +Access : write-only[1]Licenses + { + [u]0.0-7.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: CDR_Control(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.16) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) +-> -> CDR_Control(5) + + +Register leaf node: CDR_Control. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : HLR CDR generation flag: +Off=Not generate HLR CDR. +On=Generate HLR CDR. + +Field : total(1) +Access : read-write [1]CDR control + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: Feature_Code(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.27) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) +-> -> CDR_Control(5) +-> -> Feature_Code(6) + + +Register leaf node: Feature_Code. +Instance: 1 +Length : 64 +Flag : 255 +Default : �îhîrî’îpî +Remark : None. + +Field : total(6) +Access : read-write[1]CFB + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]CFD + { + [u]2.0-3.7 + [u]input + [v]KeepHex Low E + } +[3]CFNA + { + [u]4.0-5.7 + [u]input + [v]KeepHex Low E + } +[4]CFU + { + [u]6.0-7.7 + [u]input + [v]KeepHex Low E + } +[5]Call waiting + { + [u]8.0-9.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2) +-> father_name = [Config] +-> -> Public_Param(0) +-> -> Management(1) + + +Remark: + Management . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.2) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Bit0-2: HLR paramter save control: +Idle=no operation. +Save=Save parameters from HLR memory to HLR hard disk. +Bit3-5: HLR subscriber data save control: +Idle=no operation. +Save=Save HLR subscriber data from HLR memory to both HLR hard disk and OMC database. +Bit6-7: Reserved. + +Field : total(3) +Access : read-write [1]Save parameter to HD + { + [u]0.0-0.2 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + } + [2]Save subscriber data to HD&OMC + { + [u]0.3-0.5 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + } + + +Create node: Subscriber_Import(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.3) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) + + +Register leaf node: Subscriber_Import. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Progress and result of HLR subscriber import. +Byte0: Progress of HLR subscriber import. +Byte1-3: Total quantity of HLR subscribers requesting import. +Byte4-7: Quantity of successfully imported HLR subscribers. + +Field : total(3) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading Failed + } +[2]Total subscriber requested + { + [u]1.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Total imported subscribers + { + [u]4.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Max_Licenses(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.11) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) + + +Register leaf node: Max_Licenses. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The maximum quantity of approved HLR subscribers determined by License control (Read Only). + +Field : total(1) +Access : read-only[1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Used_Licenses(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.12) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) + + +Register leaf node: Used_Licenses. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of currently registered HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Used Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Subscriber_Info(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) + + +Remark: + Subscriber information . + + +Create node: Provisioned_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.1) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) + + +Register leaf node: Provisioned_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of service provisioned and active HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Provisioned Subs + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Registered_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.2) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) +-> -> Registered_Subs(1) + + +Register leaf node: Registered_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of registered (both active and inactive) HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Registered Subs + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Roaming_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.3) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) +-> -> Registered_Subs(1) +-> -> Roaming_Subs(2) + + +Register leaf node: Roaming_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of provisioned HLR subscribers currently roaming to VPLMNs (Read Only). + +Field : total(1) +Access : read-only[1]Roaming Subs + { + [u]0.0-0.0 + [u]input + [v]toDec high 0 + } + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) + + +Remark: + Version . + + +Create node: Software(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14.1) +-> father_name = [Version] +-> -> Software(0) + + +Register leaf node: Software. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of HLR software (Read Only): +Byte0: System release version number: +- Based on basic function and structure. +Byte1: Software module version number: +- Based on software module. +Byte2: Test version: +- 0=Release version number. +- 1=Test version number. + +Field : total(3) +Access : read-only[1]Release + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Version + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Slice + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: User_Data(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14.2) +-> father_name = [Version] +-> -> Software(0) +-> -> User_Data(1) + + +Register leaf node: User_Data. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC subscriber data (Read Only): +System release version: Based on basic function and structure. +Subscriber data version: Based on software module. +Test version: 0=Release version 1=Test version + +Field : total(3) +Access : read-only[1]Release + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Version + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Slice + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: IMSI_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.15) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) + + +Register leaf node: IMSI_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : MSISDN segment table (Read Only): +Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + +Field : total(1) +Access : read-only[1]IMSI segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: MSISDN_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.16) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) +-> -> MSISDN_Segment(7) + + +Register leaf node: MSISDN_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : MSISDN segment table (Read Only): +Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + +Field : total(1) +Access : read-only[1]MSISDN segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: CNF_Applicant_Info(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.27) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) +-> -> MSISDN_Segment(7) +-> -> CNF_Applicant_Info(8) + + +Register leaf node: CNF_Applicant_Info. +Instance: 1 +Length : 9 +Flag : 255 +Default : +Remark : Display the IMSI and charge type of the latest conference applicant (Read Only). + +Field : total(2) +Access : read-only [1]Charge Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Invalid user + [v]1[opt]Post-pay user + [v]2[opt]Prepaid user + } +[2]IMSI + { + [u]1.0-8.7 + [u]input + [v]KeepHex Low E + } + + +Create node: AUC(OID: 1.3.6.1.4.1.1373.1.3.3.4) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) + + +Remark: Subsystems for AUC . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.4.2) +-> father_name = [AUC] +-> -> Configuration(0) + + +Remark: + Configuration for AUC . + + +Create node: Public_parameter(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1) +-> father_name = [Configuration] +-> -> Public_parameter(0) + + +Remark: + Public_parameter for AUC . + + +Create node: SSD(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.2) +-> father_name = [Public_parameter] +-> -> SSD(0) + + +Register leaf node: SSD. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : SSD + +Field : total(3) +Access : read-write [1]share SSD + { + [u]0.0-0.7 + [u]select + [v]0[opt]not share + [v]1[opt]share + } +[2]Update SSD timer + { + [u]1.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Count(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.3) +-> father_name = [Public_parameter] +-> -> SSD(0) +-> -> Count(1) + + +Register leaf node: Count. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : Count. + +Field : total(2) +Access : read-write[1]Count Match Range + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Failures(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.4) +-> father_name = [Public_parameter] +-> -> SSD(0) +-> -> Count(1) +-> -> Failures(2) + + +Register leaf node: Failures. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : Count. + +Field : total(7) +Access : read-write [1]AUTHR Mismatch + { + [u]0.0-0.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + [2]Count Mismatch + { + [u]1.0-1.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [3]Unique Challenge Failure + { + [u]2.0-2.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [4]SSD Update Failure + { + [u]3.0-3.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [5]Count Update Failure + { + [u]4.0-4.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [6]Missing AUTH Parameters + { + [u]5.0-5.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2) +-> father_name = [Configuration] +-> -> Public_parameter(0) +-> -> Management(1) + + +Remark: + Management . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.2) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Command for AUC paramters and user data operation, and the result of command. + +Field : total(3) +Access : read-write [1]Save parameters to HD + { + [u]0.0-0.2 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + [v]1[opt]Saving + [v]2[opt]Save succeeds + [v]3[opt]Save fails + } + [2]Save user data to HD&OMC + { + [u]0.3-0.5 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + [v]1[opt]Saving + [v]2[opt]Save succeeds + [v]3[opt]Save fails + } + + +Create node: License_Control(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.3) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) + + +Register leaf node: License_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of AUC subscribers for service provider. The new license can not support less AUC subscribers than what the old license supports. + +Field : total(1) +Access : write-only[1]Licenses + { + [u]0.0-15.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: MAX_License(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.11) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) + + +Register leaf node: MAX_License. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The maximum quantity of approved AUC subscribers determined by License control Read only. + +Field : total(1) +Access : write-only[1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Used_License(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.12) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) + + +Register leaf node: Used_License. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of currently registered EIR subscribers (Read only). + +Field : total(1) +Access : read-only[1]Used Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: User_information(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.13) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) + + +Remark: + User Information . + + +Create node: Provisioned_Users(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.13.1) +-> father_name = [User_information] +-> -> Provisioned_Users(0) + + +Register leaf node: Provisioned_Users. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of service enabled AUC subscribers (Read only). + +Field : total(1) +Access : read-only[1]Provisioned users + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) +-> -> Version(5) + + +Remark: + Version . + + +Create node: Software(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14.1) +-> father_name = [Version] +-> -> Software(0) + + +Register leaf node: Software. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC software (Read only). +System: System release version, based on basic function and structure. +Module: Software module version, based on software module. +Test: Test version, 0=Release version. 1=Test version. + +Field : total(3) +Access : read-only[1]System + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Module + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Test + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: User_data(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14.2) +-> father_name = [Version] +-> -> Software(0) +-> -> User_data(1) + + +Register leaf node: User_data. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC subscriber data (Read only). +System: System release version, based on basic function and structure. +User data: Subscriber profile version, based on software module. +Test: Test version, 0=Release version. 1=Test version. + +Field : total(3) +Access : read-only[1]System + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]User data + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Test + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: IMSI_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.15) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) +-> -> Version(5) +-> -> IMSI_Segment(6) + + +Register leaf node: IMSI_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : IMSI segment table (Read only): +100,000 IMSIs are subdivided into 1000 segments, each IMSI segment use the 8 most significant digits (from the 6th digit to 13th digit of 15-digit of IMSI) as the segment number. +IMSI=MCC(3)+MNC(2)+MSIN(10) +Segment number=the 8 most significant digits of the MSIN, each segment has 100 subscribers (00-99). +e.g. If IMSI=460002356090098 then it belongs to IMSI segemt 23560900 and its account number in that segment=98. 0=empty segment. + +Field : total(1) +Access : read-only[1]IMSI segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.4.3) +-> father_name = [AUC] +-> -> Configuration(0) +-> -> Status(1) + + +Remark: + Status for AUC . + + +Create node: Import_status(OID: 1.3.6.1.4.1.1373.1.3.3.4.3.2) +-> father_name = [Status] +-> -> Import_status(0) + + +Register leaf node: Import_status. +Instance: 1 +Length : 12 +Flag : 255 +Default : +Remark : Import status. + +Field : total(0) +Access : read-write + +Create node: SMSC(OID: 1.3.6.1.4.1.1373.1.3.3.5) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) + + +Remark: Subsystems for SMSC . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.5.2) +-> father_name = [SMSC] +-> -> Configuration(0) + + +Remark: Configuration for SMSC . + + +Create node: System_Param(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1) +-> father_name = [Configuration] +-> -> System_Param(0) + + +Remark: system parameter . + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.1) +-> father_name = [System_Param] +-> -> CDR_Flag(0) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : SMSC CDR generation enable or disable. + +Field : total(3) +Access : read-write [1]SMSC CDR + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [2]SMSC LOG + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + + +Create node: SM_Validity(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.2) +-> father_name = [System_Param] +-> -> CDR_Flag(0) +-> -> SM_Validity(1) + + +Register leaf node: SM_Validity. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Period of validity of short message, define a threshold how long an awaiting sending message should be kept in sending array till sent to MS, unit is second, default=0c0a8h seconds=12 hours. + +Field : total(1) +Access : read-write[1]SM validity + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: MSISDN_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.3) +-> father_name = [System_Param] +-> -> CDR_Flag(0) +-> -> SM_Validity(1) +-> -> MSISDN_Segment(2) + + +Register leaf node: MSISDN_Segment. +Instance: 16 +Length : 19 +Flag : 255 +Default : †uUq' +Remark : Specify the beginning MSISDN for the range of provisioned subscriber. F=end tag. + +Field : total(3) +Access : read-write[1]Start MSISDN + { + [u]0.0-8.7 + [u]input + [v]KeepHex Low E + } +[2]End MSISDN + { + [u]9.0-17.7 + [u]input + [v]KeepHex Low E + } + [3]Number Type + { + [u]18.0-18.7 + [u]select + [v]0[opt]GSM + [v]1[opt]CDMA + } + + +Create node: SMPP_parameters(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.2) +-> father_name = [Configuration] +-> -> System_Param(0) +-> -> SMPP_parameters(1) + + +Register leaf node: SMPP_parameters. +Instance: 32 +Length : 12 +Flag : 255 +Default : +Remark : Name: Can be any name, generally use the name of the connected device. +Service number: SMPP connected party MSISDN used for display on MT MS, +e.g. for a SMPP to PPS, set the service number as MSISDN of PPS. +Data coding scheme: +00:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 7bit +01:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 7bit +10:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 8bit +11:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 8bit +Default=0. + +Field : total(5) +Access : read-write [1]Enable flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Session type + { + [u]1.0-1.7 + [u]select + [v]0[opt]BIND_TX + [v]1[opt]BIND_RX + [v]2[opt]BIND_TRX + } +[3]Service number + { + [u]2.0-9.7 + [u]input + [v]ToAscii Low 0 + } + [4]Message mode + { + [u]10.0-10.7 + [u]select + [v]0[opt]Store and forward + [v]1[opt]Datagram + [v]2[opt]Transaction + } + [5]Data Coding Scheme + { + [u]11.0-11.7 + [u]select + [v]0[opt]To smpp=7bit,default=7bit + [v]1[opt]To smpp=8bit,default=7bit + [v]16[opt]To smpp=7bit,default=8bit + [v]17[opt]To smpp=8bit,default=8bit + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.5.3) +-> father_name = [SMSC] +-> -> Configuration(0) +-> -> Management(1) + + +Remark: + Management for SMSC . + + +Create node: SMSC_ID(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.1) +-> father_name = [Management] +-> -> SMSC_ID(0) + + +Register leaf node: SMSC_ID. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : SMSC ID + +Field : total(1) +Access : read-write[1]SMSC ID + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Software_Version(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.2) +-> father_name = [Management] +-> -> SMSC_ID(0) +-> -> Software_Version(1) + + +Register leaf node: Software_Version. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Software version + +Field : total(1) +Access : write-only[1]Version + { + [u]0.0-2.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.3) +-> father_name = [Management] +-> -> SMSC_ID(0) +-> -> Software_Version(1) +-> -> Command(2) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : SMSC system command. +Save parameters: Save the SMSC parameters in memory to SMSC harddisk. +Delete pending SM: Delete the pending SM in awaiting array. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + [v]4[opt]Reset system + [v]5[opt]Delete pending SM + } + + +Create node: PPS(OID: 1.3.6.1.4.1.1373.1.3.3.6) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) +-> -> PPS(4) + + +Remark: Subsystems for PPS . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2) +-> father_name = [PPS] +-> -> Public_Param(0) + + +Remark: public parameters for MSS . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1) +-> father_name = [Public_Param] +-> -> Configuration(0) + + +Remark: Configuration for PPS . + + +Create node: Service_Control(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1) +-> father_name = [Configuration] +-> -> Service_Control(0) + + +Remark: Service Control . + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.1) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : PPS CDR generation enable or disable. Default=PPS generate CDR. + +Field : total(1) +Access : read-write [1]CDR flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Blacklist_Threshold(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.2) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) + + +Register leaf node: Blacklist_Threshold. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Legal recharge failure, subsciber who breaks the threshold will be marked in black list and suspended from service provisioning. Default=5. + +Field : total(1) +Access : read-write[1]Blacklist threshold + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Balance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.3) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) + + +Register leaf node: Maximum_Balance. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This value is for overflow prevention. Normally operator doesn't need to change this value. e.g. 5000, and the smallest unit is cent then the maximum allowed balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: License_Control(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.4) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) + + +Register leaf node: License_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of PPS subscribers for service provider. The new license can not support less PPS subscribers than what the old license supports. + +Field : total(1) +Access : read-write[1]License + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Prompt_Resolution(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.5) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) + + +Register leaf node: Prompt_Resolution. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Currency style: Set the number of decimals in account balance SM display format. If account balance=55555 in smallest currency unit: +1=account balance display in SM is 55555. +10=account balance display in SM is 5555.5. +100=account balance display in SM is 555.55. +Default=100. +Date style: Set the date format displayed in SM or announcement. Default=YYYY-MM-DD. +Currency symbol position: Set the position of the currency symbol. +There are two types: at the front of the amount (e.g. $5) or at the rear of the amount (e.g. 5Fr). Default=at the front. + +Field : total(4) +Access : read-write [1]Currency resolution + { + [u]0.0-0.1 + [u]select + [v]0[opt]1 + [v]1[opt]10 + [v]2[opt]100 + } + [2]Date format + { + [u]0.2-0.3 + [u]select + [v]0[opt]YYYY-MM-DD + [v]1[opt]DD-MM-YYYY + [v]2[opt]MM-DD-YYYY + } + [3]Currency symbol position + { + [u]0.0-0.0 + [u]select + [v]0[opt]Front + [v]1[opt]Rear + } + + +Create node: SMS_Sentence(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.6) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) + + +Register leaf node: SMS_Sentence. +Instance: 5 +Length : 112 +Flag : 255 +Default : +Remark : The # of sentence(0-4) refers to differenct language type; + +Field : total(4) +Access : read-write [1]SM encode type + { + [u]0.0-0.7 + [u]select + [v]0[opt]7 bit + [v]4[opt]octet + [v]8[opt]unicode + } +[2]Account balance + { + [u]1.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[3]expired in + { + [u]32.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[4]recharge in time + { + [u]64.0-111.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Last_Call_Info(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.7) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) + + +Register leaf node: Last_Call_Info. +Instance: 5 +Length : 88 +Flag : 255 +Default : Last call sent on: +Remark : The # of sentence(0-4) refers to differenct language type. + +Field : total(5) +Access : read-write[1]Last call sent on + { + [u]0.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[2]Last call received on + { + [u]32.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[3]At + { + [u]64.0-71.7 + [u]input + [v]ToAscii Low 0 + } +[4]To + { + [u]72.0-79.7 + [u]input + [v]ToAscii Low 0 + } +[5]From + { + [u]80.0-87.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Currency_Symbol(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.8) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) + + +Register leaf node: Currency_Symbol. +Instance: 1 +Length : 8 +Flag : 255 +Default : $ +Remark : Set the symbol of the local currency in SMS amount display. e.g. $, RMB, EUR, US$, FR$. default=$. In the set window, type the currency symbol. The input symbol will be converted to ASCII code. +Do not input any symbol that not listed on the ASCII code table. ASCII table: 'A'=0x41, 'B'=0x42 ... 'I'=0x49, 'J'=0x4a, 'K'=0x4b ... 'Z'=0x5A, '$'=0x24 +e.g. RMB=0x52 0x4d 0x42, US$=0x55 0x53 0x24 + +Field : total(1) +Access : read-write[1]Currency symbol + { + [u]0.0-7.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Third_Party_Info(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.9) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) +-> -> Third_Party_Info(8) + + +Register leaf node: Third_Party_Info. +Instance: 8 +Length : 16 +Flag : 255 +Default : +Remark : This parameter is a verification for third party ESME when the third party ESME sends a billing request to PPS server. For example, if a subscriber sends a short message via a ESME (e.g. website), the ESME will send a billing request to PPS to debit this subscriber. This billing request must contains a service ID and password to pass the verification. After verification, the subscriber will be debited by the PPS. PPS supports 8 ESME connections. + +Field : total(2) +Access : read-write[1]Service ID + { + [u]0.0-7.7 + [u]input + [v]ToAscii Low 0 + } +[2]Service password + { + [u]8.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Basic_Tariff_Zone(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.10) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) +-> -> Third_Party_Info(8) +-> -> Basic_Tariff_Zone(9) + + +Register leaf node: Basic_Tariff_Zone. +Instance: 64 +Length : 9 +Flag : 255 +Default : +Remark : The basic tariff is applied for each calling or called number prefix. The WXC2 System supports 16 MO and MT tariffs (0-15) and 256 billing zones. This parameter defines basic tariff for each billing zone. Each parameter is a combination of MCC, MNC, cell ID, LAC and MO/MT tariff ID. The billing zone may be set as a cell, a LAC or a zone. Normally a single billing zone deploys only one basic tariff. +Each PPS subscriber profile also contains its tariff setup specifying which tariff should be applied for this subscriber. Using either basic tariff zone (location dependent) or tariff in subscriber profile (subscriber dependent) is determined by a parameter -Tariff subscription-. +LAC: If LAC=65536, all LACs in the MCC and MNC use the same basic tariff. +Cell ID: If cell ID=65536, all cells in the LAC use the same basic tariff. + +Field : total(6) +Access : read-write[1]MCC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low F + } +[2]MNC + { + [u]2.0-2.7 + [u]input + [v]KeepHex Low F + } +[3]LAC + { + [u]3.0-4.7 + [u]input + [v]toDec high 0 + } +[4]Cell ID + { + [u]5.0-6.7 + [u]input + [v]toDec high 0 + } + [5]MO tariff ID + { + [u]7.0-7.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [6]MT tariff ID + { + [u]8.0-8.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: SRF_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) + + +Remark: SRF parameters . + + +Create node: SRF_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) + + +Remark: SRF Number. + + +Create node: SRF_0_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1.1) +-> father_name = [SRF_Number] +-> -> SRF_0_Number(0) + + +Register leaf node: SRF_0_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : E.164 number of SRF 0 (Special Resource Function) entity. + +Field : total(1) +Access : read-write[1]SRF 0 number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: SRF_1_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1.2) +-> father_name = [SRF_Number] +-> -> SRF_0_Number(0) +-> -> SRF_1_Number(1) + + +Register leaf node: SRF_1_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : E.164 number of SRF 1 (Special Resource Function) entity. + +Field : total(1) +Access : read-write[1]SRF 1 number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Service_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) +-> -> Service_Number(1) + + +Remark: Service number . + + +Create node: Hotline(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.1) +-> father_name = [Service_Number] +-> -> Hotline(0) + + +Register leaf node: Hotline. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : PPS service center number. Subscriber dials this number to recharge, enquire their account and modify favorite numbers. + +Field : total(1) +Access : read-write[1]Hotline + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Inquiry(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.2) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) + + +Register leaf node: Inquiry. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated PPS number for account (balance and validity) inquiry. + +Field : total(1) +Access : read-write[1]Inquiry number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Scratch_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.3) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) + + +Register leaf node: Scratch_Card_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via scratch card. + +Field : total(1) +Access : read-write[1]Recharge via scratch card + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Credit_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.4) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) + + +Register leaf node: Credit_Card_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via credit card. + +Field : total(1) +Access : read-write[1]Recharge via credit card + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Third_Party_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.5) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) + + +Register leaf node: Third_Party_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharging other account from MS or PSTN. + +Field : total(1) +Access : read-write[1]Recharge other account + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Customer_Care_Center(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.6) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) +-> -> Customer_Care_Center(5) + + +Register leaf node: Customer_Care_Center. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number to connect customer care center. + +Field : total(1) +Access : read-write[1]Customer care center number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Rechareg_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.7) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) +-> -> Customer_Care_Center(5) +-> -> Rechareg_Number(6) + + +Register leaf node: Rechareg_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via scratch card or credit card. + +Field : total(1) +Access : read-write[1]Recharge number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Service_Key(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) +-> -> Service_Number(1) +-> -> Service_Key(2) + + +Remark: Service key . + + +Create node: Inquiry(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.2) +-> father_name = [Service_Key] +-> -> Inquiry(0) + + +Register leaf node: Inquiry. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the function key to enquire account balance after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for inquiry + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Scratch_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.3) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) + + +Register leaf node: Scratch_Card_Recharge. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to recharge account via scratch card after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for recharging via scratch card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Credit_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.4) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) + + +Register leaf node: Credit_Card_Recharge. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key for recharging account via credit card after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for recharging via credit card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Set_Favorite_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.5) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) + + +Register leaf node: Set_Favorite_Number. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to set favorite number after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key to set favorite number + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Language_Selection(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.6) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) +-> -> Language_Selection(4) + + +Register leaf node: Language_Selection. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to select system language (from 5 available candidates) after entering the PPS service center. All announcements in the PPS service center is played in the system language. + +Field : total(1) +Access : read-write[1]Key for language selection + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: SetPasswd(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.7) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) +-> -> Language_Selection(4) +-> -> SetPasswd(5) + + +Register leaf node: SetPasswd. +Instance: 1 +Length : 3 +Flag : 255 +Default :  +Remark : Define the key to set account password after entering the PPS service center. When recharging account] selecting language] modifying favorite number or seting password] subscriber is asked to pass the password verification. + +Field : total(1) +Access : read-write[1]PPS account password + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: File_Operation(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) + + +Remark: File operation . + + +Create node: Import_User_Data(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.1) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) + + +Register leaf node: Import_User_Data. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Read only. Progress and result of PPS subscriber import. +Total number sent: Total quantity of PPS subscribers requesting import. +Records loaded: Quantity of successfully imported PPS subscribers. + +Field : total(3) +Access : read-only [1]Command status + { + [u]0.0-0.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading failed + } +[2]Total number sent + { + [u]1.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Records loaded + { + [u]4.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Import_Recharge_Card(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.2) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) + + +Register leaf node: Import_Recharge_Card. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Read only. Result of uploading recharge card to PPS. 0=unsuccessful. 1=successful. + +Field : total(1) +Access : read-only[1]Import recharge card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: New_Tariff_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.3) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) +-> -> New_Tariff_Flag(2) + + +Register leaf node: New_Tariff_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-only [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: New_Tariff_Start_Time(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.4) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) +-> -> New_Tariff_Flag(2) +-> -> New_Tariff_Start_Time(3) + + +Register leaf node: New_Tariff_Start_Time. +Instance: 1 +Length : 7 +Flag : 255 +Default :  +Remark : Read only. Set start time for new tariff plan. + +Field : total(6) +Access : read-only[1]Year + { + [u]0.0-1.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]3.0-3.7 + [u]input + [v]KeepHex high 0 + } +[4]Hour + { + [u]4.0-4.7 + [u]input + [v]KeepHex high 0 + } +[5]Minute + { + [u]5.0-5.7 + [u]input + [v]KeepHex high 0 + } +[6]Second + { + [u]6.0-6.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: COS_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) + + +Remark: COS parameters . + + +Create node: COS_0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1) +-> father_name = [COS_Param] +-> -> COS_0(0) + + +Remark: COS 0 Parameters. + + +Create node: Recharge_Promotion_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.1) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) + + +Register leaf node: Start_Date_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.2) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) +-> -> End_Date_COS0(1) + + +Register leaf node: End_Date_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.3) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) +-> -> End_Date_COS0(1) +-> -> Promotion_Bonus_COS0(2) + + +Register leaf node: Promotion_Bonus_COS0. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.1) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) + + +Register leaf node: MO_Tariff_ID_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.2) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) + + +Register leaf node: MT_Tariff_ID_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.3) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) +-> -> Tariff_Subscription_COS0(2) + + +Register leaf node: Tariff_Subscription_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.4) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) +-> -> Tariff_Subscription_COS0(2) +-> -> Recharge_Card_Validity_COS0(3) + + +Register leaf node: Recharge_Card_Validity_COS0. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.1) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) + + +Register leaf node: Min_balance_MO_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.2) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) +-> -> Maximum_Validity_COS0(1) + + +Register leaf node: Maximum_Validity_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.3) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) +-> -> Maximum_Validity_COS0(1) +-> -> Release_Day_COS0(2) + + +Register leaf node: Release_Day_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4.1) +-> father_name = [MT_Control_COS0] +-> -> Charge_Flag_COS0(0) + + +Register leaf node: Charge_Flag_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4.2) +-> father_name = [MT_Control_COS0] +-> -> Charge_Flag_COS0(0) +-> -> Zero_Balance_Control_COS0(1) + + +Register leaf node: Zero_Balance_Control_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) +-> -> Validity_Solution_COS0(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.1) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) + + +Register leaf node: Clear_Balance_Option_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.2) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) + + +Register leaf node: Validity_Recharge_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.3) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) + + +Register leaf node: Validity_Zero_Balance_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.4) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) + + +Register leaf node: Activated_Account_Validity_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.5) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) + + +Register leaf node: FF_Number_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.6) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) +-> -> Support_Credit_Card_COS0(5) + + +Register leaf node: Support_Credit_Card_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS0 + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.7) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) +-> -> Support_Credit_Card_COS0(5) +-> -> Credit_Vault_COS0(6) + + +Register leaf node: Credit_Vault_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) +-> -> Validity_Solution_COS0(4) +-> -> SM_Inquiry_COS0(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.1) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) + + +Register leaf node: Feedback_SM_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.2) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) + + +Register leaf node: Inquiry_SM_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.3) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) +-> -> SM_Expiry_COS0(2) + + +Register leaf node: SM_Expiry_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.4) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) +-> -> SM_Expiry_COS0(2) +-> -> SM_Low_Balance_COS0(3) + + +Register leaf node: SM_Low_Balance_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) + + +Remark: COS 1 Parameters. + + +Create node: Recharge_Promotion_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.1) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) + + +Register leaf node: Start_Date_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.2) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) +-> -> End_Date_COS1(1) + + +Register leaf node: End_Date_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.3) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) +-> -> End_Date_COS1(1) +-> -> Promotion_Bonus_COS1(2) + + +Register leaf node: Promotion_Bonus_COS1. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.1) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) + + +Register leaf node: MO_Tariff_ID_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.2) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) + + +Register leaf node: MT_Tariff_ID_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.3) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) +-> -> Tariff_Subscription_COS1(2) + + +Register leaf node: Tariff_Subscription_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.4) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) +-> -> Tariff_Subscription_COS1(2) +-> -> Recharge_Card_Validity_COS1(3) + + +Register leaf node: Recharge_Card_Validity_COS1. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.1) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) + + +Register leaf node: Min_balance_MO_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.2) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) +-> -> Maximum_Validity_COS1(1) + + +Register leaf node: Maximum_Validity_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.3) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) +-> -> Maximum_Validity_COS1(1) +-> -> Release_Day_COS1(2) + + +Register leaf node: Release_Day_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4.1) +-> father_name = [MT_Control_COS1] +-> -> Charge_Flag_COS1(0) + + +Register leaf node: Charge_Flag_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4.2) +-> father_name = [MT_Control_COS1] +-> -> Charge_Flag_COS1(0) +-> -> Zero_Balance_Control_COS1(1) + + +Register leaf node: Zero_Balance_Control_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) +-> -> Validity_Solution_COS1(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.1) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) + + +Register leaf node: Clear_Balance_Option_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.2) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) + + +Register leaf node: Validity_Recharge_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.3) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) + + +Register leaf node: Validity_Zero_Balance_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.4) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) + + +Register leaf node: Activated_Account_Validity_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.5) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) + + +Register leaf node: FF_Number_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.6) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) +-> -> Support_Credit_Card_COS1(5) + + +Register leaf node: Support_Credit_Card_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.7) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) +-> -> Support_Credit_Card_COS1(5) +-> -> Credit_Vault_COS1(6) + + +Register leaf node: Credit_Vault_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) +-> -> Validity_Solution_COS1(4) +-> -> SM_Inquiry_COS1(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.1) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) + + +Register leaf node: Feedback_SM_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.2) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) + + +Register leaf node: Inquiry_SM_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.3) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) +-> -> SM_Expiry_COS1(2) + + +Register leaf node: SM_Expiry_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.4) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) +-> -> SM_Expiry_COS1(2) +-> -> SM_Low_Balance_COS1(3) + + +Register leaf node: SM_Low_Balance_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) + + +Remark: COS 2 Parameters. + + +Create node: Recharge_Promotion_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.1) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) + + +Register leaf node: Start_Date_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.2) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) +-> -> End_Date_COS2(1) + + +Register leaf node: End_Date_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.3) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) +-> -> End_Date_COS2(1) +-> -> Promotion_Bonus_COS2(2) + + +Register leaf node: Promotion_Bonus_COS2. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.1) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) + + +Register leaf node: MO_Tariff_ID_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.2) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) + + +Register leaf node: MT_Tariff_ID_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.3) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) +-> -> Tariff_Subscription_COS2(2) + + +Register leaf node: Tariff_Subscription_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.4) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) +-> -> Tariff_Subscription_COS2(2) +-> -> Recharge_Card_Validity_COS2(3) + + +Register leaf node: Recharge_Card_Validity_COS2. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.1) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) + + +Register leaf node: Min_balance_MO_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.2) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) +-> -> Maximum_Validity_COS2(1) + + +Register leaf node: Maximum_Validity_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.3) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) +-> -> Maximum_Validity_COS2(1) +-> -> Release_Day_COS2(2) + + +Register leaf node: Release_Day_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4.1) +-> father_name = [MT_Control_COS2] +-> -> Charge_Flag_COS2(0) + + +Register leaf node: Charge_Flag_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4.2) +-> father_name = [MT_Control_COS2] +-> -> Charge_Flag_COS2(0) +-> -> Zero_Balance_Control_COS2(1) + + +Register leaf node: Zero_Balance_Control_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) +-> -> Validity_Solution_COS2(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.1) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) + + +Register leaf node: Clear_Balance_Option_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.2) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) + + +Register leaf node: Validity_Recharge_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.3) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) + + +Register leaf node: Validity_Zero_Balance_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.4) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) + + +Register leaf node: Activated_Account_Validity_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.5) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) + + +Register leaf node: FF_Number_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Free times of changing: set total times of free change for family number if charge is enabled. Maximum is 15. + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.6) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) +-> -> Support_Credit_Card_COS2(5) + + +Register leaf node: Support_Credit_Card_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.7) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) +-> -> Support_Credit_Card_COS2(5) +-> -> Credit_Vault_COS2(6) + + +Register leaf node: Credit_Vault_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) +-> -> Validity_Solution_COS2(4) +-> -> SM_Inquiry_COS2(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.1) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) + + +Register leaf node: Feedback_SM_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.2) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) + + +Register leaf node: Inquiry_SM_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.3) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) +-> -> SM_Expiry_COS2(2) + + +Register leaf node: SM_Expiry_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.4) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) +-> -> SM_Expiry_COS2(2) +-> -> SM_Low_Balance_COS2(3) + + +Register leaf node: SM_Low_Balance_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) + + +Remark: COS 3 Parameters. + + +Create node: Recharge_Promotion_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.1) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) + + +Register leaf node: Start_Date_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.2) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) +-> -> End_Date_COS3(1) + + +Register leaf node: End_Date_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.3) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) +-> -> End_Date_COS3(1) +-> -> Promotion_Bonus_COS3(2) + + +Register leaf node: Promotion_Bonus_COS3. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.1) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) + + +Register leaf node: MO_Tariff_ID_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.2) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) + + +Register leaf node: MT_Tariff_ID_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.3) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) +-> -> Tariff_Subscription_COS3(2) + + +Register leaf node: Tariff_Subscription_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.4) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) +-> -> Tariff_Subscription_COS3(2) +-> -> Recharge_Card_Validity_COS3(3) + + +Register leaf node: Recharge_Card_Validity_COS3. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.1) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) + + +Register leaf node: Min_balance_MO_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.2) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) +-> -> Maximum_Validity_COS3(1) + + +Register leaf node: Maximum_Validity_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.3) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) +-> -> Maximum_Validity_COS3(1) +-> -> Release_Day_COS3(2) + + +Register leaf node: Release_Day_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4.1) +-> father_name = [MT_Control_COS3] +-> -> Charge_Flag_COS3(0) + + +Register leaf node: Charge_Flag_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4.2) +-> father_name = [MT_Control_COS3] +-> -> Charge_Flag_COS3(0) +-> -> Zero_Balance_Control_COS3(1) + + +Register leaf node: Zero_Balance_Control_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) +-> -> Validity_Solution_COS3(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.1) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) + + +Register leaf node: Clear_Balance_Option_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.2) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) + + +Register leaf node: Validity_Recharge_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.3) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) + + +Register leaf node: Validity_Zero_Balance_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.4) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) + + +Register leaf node: Activated_Account_Validity_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.5) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) + + +Register leaf node: FF_Number_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.6) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) +-> -> Support_Credit_Card_COS3(5) + + +Register leaf node: Support_Credit_Card_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.7) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) +-> -> Support_Credit_Card_COS3(5) +-> -> Credit_Vault_COS3(6) + + +Register leaf node: Credit_Vault_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) +-> -> Validity_Solution_COS3(4) +-> -> SM_Inquiry_COS3(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.1) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) + + +Register leaf node: Feedback_SM_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.2) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) + + +Register leaf node: Inquiry_SM_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.3) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) +-> -> SM_Expiry_COS3(2) + + +Register leaf node: SM_Expiry_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.4) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) +-> -> SM_Expiry_COS3(2) +-> -> SM_Low_Balance_COS3(3) + + +Register leaf node: SM_Low_Balance_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) + + +Remark: COS 4 Parameters. + + +Create node: Recharge_Promotion_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.1) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) + + +Register leaf node: Start_Date_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.2) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) +-> -> End_Date_COS4(1) + + +Register leaf node: End_Date_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.3) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) +-> -> End_Date_COS4(1) +-> -> Promotion_Bonus_COS4(2) + + +Register leaf node: Promotion_Bonus_COS4. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.1) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) + + +Register leaf node: MO_Tariff_ID_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.2) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) + + +Register leaf node: MT_Tariff_ID_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.3) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) +-> -> Tariff_Subscription_COS4(2) + + +Register leaf node: Tariff_Subscription_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.4) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) +-> -> Tariff_Subscription_COS4(2) +-> -> Recharge_Card_Validity_COS4(3) + + +Register leaf node: Recharge_Card_Validity_COS4. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.1) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) + + +Register leaf node: Min_balance_MO_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.2) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) +-> -> Maximum_Validity_COS4(1) + + +Register leaf node: Maximum_Validity_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.3) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) +-> -> Maximum_Validity_COS4(1) +-> -> Release_Day_COS4(2) + + +Register leaf node: Release_Day_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4.1) +-> father_name = [MT_Control_COS4] +-> -> Charge_Flag_COS4(0) + + +Register leaf node: Charge_Flag_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4.2) +-> father_name = [MT_Control_COS4] +-> -> Charge_Flag_COS4(0) +-> -> Zero_Balance_Control_COS4(1) + + +Register leaf node: Zero_Balance_Control_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) +-> -> Validity_Solution_COS4(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.1) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) + + +Register leaf node: Clear_Balance_Option_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.2) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) + + +Register leaf node: Validity_Recharge_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.3) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) + + +Register leaf node: Validity_Zero_Balance_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.4) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) + + +Register leaf node: Activated_Account_Validity_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.5) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) + + +Register leaf node: FF_Number_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.6) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) +-> -> Support_Credit_Card_COS4(5) + + +Register leaf node: Support_Credit_Card_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.7) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) +-> -> Support_Credit_Card_COS4(5) +-> -> Credit_Vault_COS4(6) + + +Register leaf node: Credit_Vault_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) +-> -> Validity_Solution_COS4(4) +-> -> SM_Inquiry_COS4(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.1) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) + + +Register leaf node: Feedback_SM_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.2) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) + + +Register leaf node: Inquiry_SM_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.3) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) +-> -> SM_Expiry_COS4(2) + + +Register leaf node: SM_Expiry_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.4) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) +-> -> SM_Expiry_COS4(2) +-> -> SM_Low_Balance_COS4(3) + + +Register leaf node: SM_Low_Balance_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) + + +Remark: COS 5 Parameters. + + +Create node: Recharge_Promotion_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.1) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) + + +Register leaf node: Start_Date_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.2) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) +-> -> End_Date_COS5(1) + + +Register leaf node: End_Date_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.3) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) +-> -> End_Date_COS5(1) +-> -> Promotion_Bonus_COS5(2) + + +Register leaf node: Promotion_Bonus_COS5. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.1) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) + + +Register leaf node: MO_Tariff_ID_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.2) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) + + +Register leaf node: MT_Tariff_ID_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.3) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) +-> -> Tariff_Subscription_COS5(2) + + +Register leaf node: Tariff_Subscription_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.4) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) +-> -> Tariff_Subscription_COS5(2) +-> -> Recharge_Card_Validity_COS5(3) + + +Register leaf node: Recharge_Card_Validity_COS5. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.1) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) + + +Register leaf node: Min_balance_MO_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.2) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) +-> -> Maximum_Validity_COS5(1) + + +Register leaf node: Maximum_Validity_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.3) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) +-> -> Maximum_Validity_COS5(1) +-> -> Release_Day_COS5(2) + + +Register leaf node: Release_Day_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4.1) +-> father_name = [MT_Control_COS5] +-> -> Charge_Flag_COS5(0) + + +Register leaf node: Charge_Flag_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4.2) +-> father_name = [MT_Control_COS5] +-> -> Charge_Flag_COS5(0) +-> -> Zero_Balance_Control_COS5(1) + + +Register leaf node: Zero_Balance_Control_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) +-> -> Validity_Solution_COS5(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.1) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) + + +Register leaf node: Clear_Balance_Option_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.2) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) + + +Register leaf node: Validity_Recharge_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.3) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) + + +Register leaf node: Validity_Zero_Balance_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.4) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) + + +Register leaf node: Activated_Account_Validity_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.5) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) + + +Register leaf node: FF_Number_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.6) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) +-> -> Support_Credit_Card_COS5(5) + + +Register leaf node: Support_Credit_Card_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.7) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) +-> -> Support_Credit_Card_COS5(5) +-> -> Credit_Vault_COS5(6) + + +Register leaf node: Credit_Vault_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) +-> -> Validity_Solution_COS5(4) +-> -> SM_Inquiry_COS5(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.1) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) + + +Register leaf node: Feedback_SM_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.2) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) + + +Register leaf node: Inquiry_SM_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.3) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) +-> -> SM_Expiry_COS5(2) + + +Register leaf node: SM_Expiry_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.4) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) +-> -> SM_Expiry_COS5(2) +-> -> SM_Low_Balance_COS5(3) + + +Register leaf node: SM_Low_Balance_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) + + +Remark: COS 6 Parameters. + + +Create node: Recharge_Promotion_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.1) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) + + +Register leaf node: Start_Date_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.2) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) +-> -> End_Date_COS6(1) + + +Register leaf node: End_Date_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.3) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) +-> -> End_Date_COS6(1) +-> -> Promotion_Bonus_COS6(2) + + +Register leaf node: Promotion_Bonus_COS6. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.1) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) + + +Register leaf node: MO_Tariff_ID_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.2) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) + + +Register leaf node: MT_Tariff_ID_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.3) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) +-> -> Tariff_Subscription_COS6(2) + + +Register leaf node: Tariff_Subscription_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.4) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) +-> -> Tariff_Subscription_COS6(2) +-> -> Recharge_Card_Validity_COS6(3) + + +Register leaf node: Recharge_Card_Validity_COS6. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.1) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) + + +Register leaf node: Min_balance_MO_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.2) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) +-> -> Maximum_Validity_COS6(1) + + +Register leaf node: Maximum_Validity_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.3) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) +-> -> Maximum_Validity_COS6(1) +-> -> Release_Day_COS6(2) + + +Register leaf node: Release_Day_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4.1) +-> father_name = [MT_Control_COS6] +-> -> Charge_Flag_COS6(0) + + +Register leaf node: Charge_Flag_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4.2) +-> father_name = [MT_Control_COS6] +-> -> Charge_Flag_COS6(0) +-> -> Zero_Balance_Control_COS6(1) + + +Register leaf node: Zero_Balance_Control_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) +-> -> Validity_Solution_COS6(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.1) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) + + +Register leaf node: Clear_Balance_Option_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.2) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) + + +Register leaf node: Validity_Recharge_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.3) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) + + +Register leaf node: Validity_Zero_Balance_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.4) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) + + +Register leaf node: Activated_Account_Validity_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.5) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) + + +Register leaf node: FF_Number_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.6) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) +-> -> Support_Credit_Card_COS6(5) + + +Register leaf node: Support_Credit_Card_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.7) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) +-> -> Support_Credit_Card_COS6(5) +-> -> Credit_Vault_COS6(6) + + +Register leaf node: Credit_Vault_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) +-> -> Validity_Solution_COS6(4) +-> -> SM_Inquiry_COS6(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.1) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) + + +Register leaf node: Feedback_SM_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.2) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) + + +Register leaf node: Inquiry_SM_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.3) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) +-> -> SM_Expiry_COS6(2) + + +Register leaf node: SM_Expiry_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.4) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) +-> -> SM_Expiry_COS6(2) +-> -> SM_Low_Balance_COS6(3) + + +Register leaf node: SM_Low_Balance_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) + + +Remark: COS 7 Parameters. + + +Create node: Recharge_Promotion_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.1) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) + + +Register leaf node: Start_Date_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.2) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) +-> -> End_Date_COS7(1) + + +Register leaf node: End_Date_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.3) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) +-> -> End_Date_COS7(1) +-> -> Promotion_Bonus_COS7(2) + + +Register leaf node: Promotion_Bonus_COS7. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.1) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) + + +Register leaf node: MO_Tariff_ID_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.2) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) + + +Register leaf node: MT_Tariff_ID_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.3) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) +-> -> Tariff_Subscription_COS7(2) + + +Register leaf node: Tariff_Subscription_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.4) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) +-> -> Tariff_Subscription_COS7(2) +-> -> Recharge_Card_Validity_COS7(3) + + +Register leaf node: Recharge_Card_Validity_COS7. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.1) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) + + +Register leaf node: Min_balance_MO_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.2) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) +-> -> Maximum_Validity_COS7(1) + + +Register leaf node: Maximum_Validity_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.3) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) +-> -> Maximum_Validity_COS7(1) +-> -> Release_Day_COS7(2) + + +Register leaf node: Release_Day_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4.1) +-> father_name = [MT_Control_COS7] +-> -> Charge_Flag_COS7(0) + + +Register leaf node: Charge_Flag_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4.2) +-> father_name = [MT_Control_COS7] +-> -> Charge_Flag_COS7(0) +-> -> Zero_Balance_Control_COS7(1) + + +Register leaf node: Zero_Balance_Control_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) +-> -> Validity_Solution_COS7(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.1) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) + + +Register leaf node: Clear_Balance_Option_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.2) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) + + +Register leaf node: Validity_Recharge_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.3) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) + + +Register leaf node: Validity_Zero_Balance_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.4) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) + + +Register leaf node: Activated_Account_Validity_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.5) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) + + +Register leaf node: FF_Number_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.6) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) +-> -> Support_Credit_Card_COS7(5) + + +Register leaf node: Support_Credit_Card_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.7) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) +-> -> Support_Credit_Card_COS7(5) +-> -> Credit_Vault_COS7(6) + + +Register leaf node: Credit_Vault_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) +-> -> Validity_Solution_COS7(4) +-> -> SM_Inquiry_COS7(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.1) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) + + +Register leaf node: Feedback_SM_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.2) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) + + +Register leaf node: Inquiry_SM_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.3) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) +-> -> SM_Expiry_COS7(2) + + +Register leaf node: SM_Expiry_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.4) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) +-> -> SM_Expiry_COS7(2) +-> -> SM_Low_Balance_COS7(3) + + +Register leaf node: SM_Low_Balance_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) + + +Remark: COS 8 Parameters. + + +Create node: Recharge_Promotion_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.1) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) + + +Register leaf node: Start_Date_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.2) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) +-> -> End_Date_COS8(1) + + +Register leaf node: End_Date_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.3) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) +-> -> End_Date_COS8(1) +-> -> Promotion_Bonus_COS8(2) + + +Register leaf node: Promotion_Bonus_COS8. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.1) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) + + +Register leaf node: MO_Tariff_ID_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.2) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) + + +Register leaf node: MT_Tariff_ID_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.3) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) +-> -> Tariff_Subscription_COS8(2) + + +Register leaf node: Tariff_Subscription_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.4) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) +-> -> Tariff_Subscription_COS8(2) +-> -> Recharge_Card_Validity_COS8(3) + + +Register leaf node: Recharge_Card_Validity_COS8. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.1) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) + + +Register leaf node: Min_balance_MO_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.2) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) +-> -> Maximum_Validity_COS8(1) + + +Register leaf node: Maximum_Validity_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.3) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) +-> -> Maximum_Validity_COS8(1) +-> -> Release_Day_COS8(2) + + +Register leaf node: Release_Day_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4.1) +-> father_name = [MT_Control_COS8] +-> -> Charge_Flag_COS8(0) + + +Register leaf node: Charge_Flag_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4.2) +-> father_name = [MT_Control_COS8] +-> -> Charge_Flag_COS8(0) +-> -> Zero_Balance_Control_COS8(1) + + +Register leaf node: Zero_Balance_Control_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) +-> -> Validity_Solution_COS8(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.1) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) + + +Register leaf node: Clear_Balance_Option_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.2) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) + + +Register leaf node: Validity_Recharge_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.3) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) + + +Register leaf node: Validity_Zero_Balance_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.4) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) + + +Register leaf node: Activated_Account_Validity_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.5) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) + + +Register leaf node: FF_Number_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.6) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) +-> -> Support_Credit_Card_COS8(5) + + +Register leaf node: Support_Credit_Card_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.7) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) +-> -> Support_Credit_Card_COS8(5) +-> -> Credit_Vault_COS8(6) + + +Register leaf node: Credit_Vault_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) +-> -> Validity_Solution_COS8(4) +-> -> SM_Inquiry_COS8(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.1) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) + + +Register leaf node: Feedback_SM_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.2) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) + + +Register leaf node: Inquiry_SM_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.3) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) +-> -> SM_Expiry_COS8(2) + + +Register leaf node: SM_Expiry_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.4) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) +-> -> SM_Expiry_COS8(2) +-> -> SM_Low_Balance_COS8(3) + + +Register leaf node: SM_Low_Balance_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) + + +Remark: COS 9 Parameters. + + +Create node: Recharge_Promotion_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.1) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) + + +Register leaf node: Start_Date_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.2) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) +-> -> End_Date_COS9(1) + + +Register leaf node: End_Date_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.3) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) +-> -> End_Date_COS9(1) +-> -> Promotion_Bonus_COS9(2) + + +Register leaf node: Promotion_Bonus_COS9. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.1) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) + + +Register leaf node: MO_Tariff_ID_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.2) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) + + +Register leaf node: MT_Tariff_ID_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.3) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) +-> -> Tariff_Subscription_COS9(2) + + +Register leaf node: Tariff_Subscription_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.4) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) +-> -> Tariff_Subscription_COS9(2) +-> -> Recharge_Card_Validity_COS9(3) + + +Register leaf node: Recharge_Card_Validity_COS9. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.1) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) + + +Register leaf node: Min_balance_MO_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.2) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) +-> -> Maximum_Validity_COS9(1) + + +Register leaf node: Maximum_Validity_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.3) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) +-> -> Maximum_Validity_COS9(1) +-> -> Release_Day_COS9(2) + + +Register leaf node: Release_Day_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4.1) +-> father_name = [MT_Control_COS9] +-> -> Charge_Flag_COS9(0) + + +Register leaf node: Charge_Flag_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4.2) +-> father_name = [MT_Control_COS9] +-> -> Charge_Flag_COS9(0) +-> -> Zero_Balance_Control_COS9(1) + + +Register leaf node: Zero_Balance_Control_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) +-> -> Validity_Solution_COS9(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.1) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) + + +Register leaf node: Clear_Balance_Option_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.2) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) + + +Register leaf node: Validity_Recharge_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.3) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) + + +Register leaf node: Validity_Zero_Balance_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.4) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) + + +Register leaf node: Activated_Account_Validity_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.5) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) + + +Register leaf node: FF_Number_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.6) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) +-> -> Support_Credit_Card_COS9(5) + + +Register leaf node: Support_Credit_Card_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.7) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) +-> -> Support_Credit_Card_COS9(5) +-> -> Credit_Vault_COS9(6) + + +Register leaf node: Credit_Vault_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) +-> -> Validity_Solution_COS9(4) +-> -> SM_Inquiry_COS9(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.1) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) + + +Register leaf node: Feedback_SM_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.2) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) + + +Register leaf node: Inquiry_SM_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.3) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) +-> -> SM_Expiry_COS9(2) + + +Register leaf node: SM_Expiry_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.4) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) +-> -> SM_Expiry_COS9(2) +-> -> SM_Low_Balance_COS9(3) + + +Register leaf node: SM_Low_Balance_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) + + +Remark: COS 10 Parameters. + + +Create node: Recharge_Promotion_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.1) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) + + +Register leaf node: Start_Date_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.2) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) +-> -> End_Date_COS10(1) + + +Register leaf node: End_Date_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.3) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) +-> -> End_Date_COS10(1) +-> -> Promotion_Bonus_COS10(2) + + +Register leaf node: Promotion_Bonus_COS10. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.1) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) + + +Register leaf node: MO_Tariff_ID_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.2) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) + + +Register leaf node: MT_Tariff_ID_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.3) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) +-> -> Tariff_Subscription_COS10(2) + + +Register leaf node: Tariff_Subscription_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.4) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) +-> -> Tariff_Subscription_COS10(2) +-> -> Recharge_Card_Validity_COS10(3) + + +Register leaf node: Recharge_Card_Validity_COS10. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.1) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) + + +Register leaf node: Min_balance_MO_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.2) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) +-> -> Maximum_Validity_COS10(1) + + +Register leaf node: Maximum_Validity_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.3) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) +-> -> Maximum_Validity_COS10(1) +-> -> Release_Day_COS10(2) + + +Register leaf node: Release_Day_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4.1) +-> father_name = [MT_Control_COS10] +-> -> Charge_Flag_COS10(0) + + +Register leaf node: Charge_Flag_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4.2) +-> father_name = [MT_Control_COS10] +-> -> Charge_Flag_COS10(0) +-> -> Zero_Balance_Control_COS10(1) + + +Register leaf node: Zero_Balance_Control_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) +-> -> Validity_Solution_COS10(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.1) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) + + +Register leaf node: Clear_Balance_Option_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.2) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) + + +Register leaf node: Validity_Recharge_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.3) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) + + +Register leaf node: Validity_Zero_Balance_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.4) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) + + +Register leaf node: Activated_Account_Validity_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.5) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) + + +Register leaf node: FF_Number_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.6) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) +-> -> Support_Credit_Card_COS10(5) + + +Register leaf node: Support_Credit_Card_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.7) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) +-> -> Support_Credit_Card_COS10(5) +-> -> Credit_Vault_COS10(6) + + +Register leaf node: Credit_Vault_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) +-> -> Validity_Solution_COS10(4) +-> -> SM_Inquiry_COS10(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.1) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) + + +Register leaf node: Feedback_SM_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.2) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) + + +Register leaf node: Inquiry_SM_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.3) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) +-> -> SM_Expiry_COS10(2) + + +Register leaf node: SM_Expiry_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.4) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) +-> -> SM_Expiry_COS10(2) +-> -> SM_Low_Balance_COS10(3) + + +Register leaf node: SM_Low_Balance_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) + + +Remark: COS 11 Parameters. + + +Create node: Recharge_Promotion_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.1) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) + + +Register leaf node: Start_Date_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.2) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) +-> -> End_Date_COS11(1) + + +Register leaf node: End_Date_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.3) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) +-> -> End_Date_COS11(1) +-> -> Promotion_Bonus_COS11(2) + + +Register leaf node: Promotion_Bonus_COS11. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.1) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) + + +Register leaf node: MO_Tariff_ID_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.2) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) + + +Register leaf node: MT_Tariff_ID_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.3) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) +-> -> Tariff_Subscription_COS11(2) + + +Register leaf node: Tariff_Subscription_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.4) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) +-> -> Tariff_Subscription_COS11(2) +-> -> Recharge_Card_Validity_COS11(3) + + +Register leaf node: Recharge_Card_Validity_COS11. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.1) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) + + +Register leaf node: Min_balance_MO_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.2) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) +-> -> Maximum_Validity_COS11(1) + + +Register leaf node: Maximum_Validity_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.3) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) +-> -> Maximum_Validity_COS11(1) +-> -> Release_Day_COS11(2) + + +Register leaf node: Release_Day_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4.1) +-> father_name = [MT_Control_COS11] +-> -> Charge_Flag_COS11(0) + + +Register leaf node: Charge_Flag_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4.2) +-> father_name = [MT_Control_COS11] +-> -> Charge_Flag_COS11(0) +-> -> Zero_Balance_Control_COS11(1) + + +Register leaf node: Zero_Balance_Control_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) +-> -> Validity_Solution_COS11(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.1) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) + + +Register leaf node: Clear_Balance_Option_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.2) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) + + +Register leaf node: Validity_Recharge_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.3) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) + + +Register leaf node: Validity_Zero_Balance_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.4) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) + + +Register leaf node: Activated_Account_Validity_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.5) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) + + +Register leaf node: FF_Number_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.6) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) +-> -> Support_Credit_Card_COS11(5) + + +Register leaf node: Support_Credit_Card_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.7) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) +-> -> Support_Credit_Card_COS11(5) +-> -> Credit_Vault_COS11(6) + + +Register leaf node: Credit_Vault_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) +-> -> Validity_Solution_COS11(4) +-> -> SM_Inquiry_COS11(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.1) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) + + +Register leaf node: Feedback_SM_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.2) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) + + +Register leaf node: Inquiry_SM_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.3) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) +-> -> SM_Expiry_COS11(2) + + +Register leaf node: SM_Expiry_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.4) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) +-> -> SM_Expiry_COS11(2) +-> -> SM_Low_Balance_COS11(3) + + +Register leaf node: SM_Low_Balance_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) + + +Remark: COS 12 Parameters. + + +Create node: Recharge_Promotion_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.1) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) + + +Register leaf node: Start_Date_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.2) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) +-> -> End_Date_COS12(1) + + +Register leaf node: End_Date_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.3) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) +-> -> End_Date_COS12(1) +-> -> Promotion_Bonus_COS12(2) + + +Register leaf node: Promotion_Bonus_COS12. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.1) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) + + +Register leaf node: MO_Tariff_ID_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.2) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) + + +Register leaf node: MT_Tariff_ID_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.3) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) +-> -> Tariff_Subscription_COS12(2) + + +Register leaf node: Tariff_Subscription_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.4) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) +-> -> Tariff_Subscription_COS12(2) +-> -> Recharge_Card_Validity_COS12(3) + + +Register leaf node: Recharge_Card_Validity_COS12. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.1) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) + + +Register leaf node: Min_balance_MO_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.2) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) +-> -> Maximum_Validity_COS12(1) + + +Register leaf node: Maximum_Validity_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.3) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) +-> -> Maximum_Validity_COS12(1) +-> -> Release_Day_COS12(2) + + +Register leaf node: Release_Day_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4.1) +-> father_name = [MT_Control_COS12] +-> -> Charge_Flag_COS12(0) + + +Register leaf node: Charge_Flag_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4.2) +-> father_name = [MT_Control_COS12] +-> -> Charge_Flag_COS12(0) +-> -> Zero_Balance_Control_COS12(1) + + +Register leaf node: Zero_Balance_Control_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) +-> -> Validity_Solution_COS12(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.1) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) + + +Register leaf node: Clear_Balance_Option_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.2) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) + + +Register leaf node: Validity_Recharge_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.3) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) + + +Register leaf node: Validity_Zero_Balance_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.4) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) + + +Register leaf node: Activated_Account_Validity_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.5) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) + + +Register leaf node: FF_Number_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.6) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) +-> -> Support_Credit_Card_COS12(5) + + +Register leaf node: Support_Credit_Card_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.7) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) +-> -> Support_Credit_Card_COS12(5) +-> -> Credit_Vault_COS12(6) + + +Register leaf node: Credit_Vault_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) +-> -> Validity_Solution_COS12(4) +-> -> SM_Inquiry_COS12(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.1) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) + + +Register leaf node: Feedback_SM_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.2) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) + + +Register leaf node: Inquiry_SM_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.3) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) +-> -> SM_Expiry_COS12(2) + + +Register leaf node: SM_Expiry_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.4) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) +-> -> SM_Expiry_COS12(2) +-> -> SM_Low_Balance_COS12(3) + + +Register leaf node: SM_Low_Balance_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) + + +Remark: COS 13 Parameters. + + +Create node: Recharge_Promotion_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.1) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) + + +Register leaf node: Start_Date_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.2) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) +-> -> End_Date_COS13(1) + + +Register leaf node: End_Date_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.3) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) +-> -> End_Date_COS13(1) +-> -> Promotion_Bonus_COS13(2) + + +Register leaf node: Promotion_Bonus_COS13. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.1) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) + + +Register leaf node: MO_Tariff_ID_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.2) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) + + +Register leaf node: MT_Tariff_ID_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.3) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) +-> -> Tariff_Subscription_COS13(2) + + +Register leaf node: Tariff_Subscription_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.4) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) +-> -> Tariff_Subscription_COS13(2) +-> -> Recharge_Card_Validity_COS13(3) + + +Register leaf node: Recharge_Card_Validity_COS13. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.1) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) + + +Register leaf node: Min_balance_MO_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.2) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) +-> -> Maximum_Validity_COS13(1) + + +Register leaf node: Maximum_Validity_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.3) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) +-> -> Maximum_Validity_COS13(1) +-> -> Release_Day_COS13(2) + + +Register leaf node: Release_Day_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4.1) +-> father_name = [MT_Control_COS13] +-> -> Charge_Flag_COS13(0) + + +Register leaf node: Charge_Flag_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4.2) +-> father_name = [MT_Control_COS13] +-> -> Charge_Flag_COS13(0) +-> -> Zero_Balance_Control_COS13(1) + + +Register leaf node: Zero_Balance_Control_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) +-> -> Validity_Solution_COS13(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.1) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) + + +Register leaf node: Clear_Balance_Option_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.2) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) + + +Register leaf node: Validity_Recharge_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.3) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) + + +Register leaf node: Validity_Zero_Balance_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.4) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) + + +Register leaf node: Activated_Account_Validity_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.5) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) + + +Register leaf node: FF_Number_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.6) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) +-> -> Support_Credit_Card_COS13(5) + + +Register leaf node: Support_Credit_Card_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.7) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) +-> -> Support_Credit_Card_COS13(5) +-> -> Credit_Vault_COS13(6) + + +Register leaf node: Credit_Vault_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) +-> -> Validity_Solution_COS13(4) +-> -> SM_Inquiry_COS13(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.1) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) + + +Register leaf node: Feedback_SM_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.2) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) + + +Register leaf node: Inquiry_SM_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.3) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) +-> -> SM_Expiry_COS13(2) + + +Register leaf node: SM_Expiry_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.4) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) +-> -> SM_Expiry_COS13(2) +-> -> SM_Low_Balance_COS13(3) + + +Register leaf node: SM_Low_Balance_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) +-> -> COS_14(14) + + +Remark: COS 14 Parameters. + + +Create node: Recharge_Promotion_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.1) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) + + +Register leaf node: Start_Date_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.2) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) +-> -> End_Date_COS14(1) + + +Register leaf node: End_Date_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.3) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) +-> -> End_Date_COS14(1) +-> -> Promotion_Bonus_COS14(2) + + +Register leaf node: Promotion_Bonus_COS14. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.1) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) + + +Register leaf node: MO_Tariff_ID_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.2) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) + + +Register leaf node: MT_Tariff_ID_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.3) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) +-> -> Tariff_Subscription_COS14(2) + + +Register leaf node: Tariff_Subscription_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.4) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) +-> -> Tariff_Subscription_COS14(2) +-> -> Recharge_Card_Validity_COS14(3) + + +Register leaf node: Recharge_Card_Validity_COS14. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.1) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) + + +Register leaf node: Min_balance_MO_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.2) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) +-> -> Maximum_Validity_COS14(1) + + +Register leaf node: Maximum_Validity_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.3) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) +-> -> Maximum_Validity_COS14(1) +-> -> Release_Day_COS14(2) + + +Register leaf node: Release_Day_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4.1) +-> father_name = [MT_Control_COS14] +-> -> Charge_Flag_COS14(0) + + +Register leaf node: Charge_Flag_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4.2) +-> father_name = [MT_Control_COS14] +-> -> Charge_Flag_COS14(0) +-> -> Zero_Balance_Control_COS14(1) + + +Register leaf node: Zero_Balance_Control_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) +-> -> Validity_Solution_COS14(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.1) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) + + +Register leaf node: Clear_Balance_Option_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.2) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) + + +Register leaf node: Validity_Recharge_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.3) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) + + +Register leaf node: Validity_Zero_Balance_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.4) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) + + +Register leaf node: Activated_Account_Validity_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.5) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) + + +Register leaf node: FF_Number_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.6) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) +-> -> Support_Credit_Card_COS14(5) + + +Register leaf node: Support_Credit_Card_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.7) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) +-> -> Support_Credit_Card_COS14(5) +-> -> Credit_Vault_COS14(6) + + +Register leaf node: Credit_Vault_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) +-> -> Validity_Solution_COS14(4) +-> -> SM_Inquiry_COS14(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.1) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) + + +Register leaf node: Feedback_SM_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.2) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) + + +Register leaf node: Inquiry_SM_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.3) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) +-> -> SM_Expiry_COS14(2) + + +Register leaf node: SM_Expiry_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.4) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) +-> -> SM_Expiry_COS14(2) +-> -> SM_Low_Balance_COS14(3) + + +Register leaf node: SM_Low_Balance_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) +-> -> COS_14(14) +-> -> COS_15(15) + + +Remark: COS 15 Parameters. + + +Create node: Recharge_Promotion_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.1) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) + + +Register leaf node: Start_Date_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.2) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) +-> -> End_Date_COS15(1) + + +Register leaf node: End_Date_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.3) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) +-> -> End_Date_COS15(1) +-> -> Promotion_Bonus_COS15(2) + + +Register leaf node: Promotion_Bonus_COS15. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.1) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) + + +Register leaf node: MO_Tariff_ID_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.2) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) + + +Register leaf node: MT_Tariff_ID_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.3) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) +-> -> Tariff_Subscription_COS15(2) + + +Register leaf node: Tariff_Subscription_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.4) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) +-> -> Tariff_Subscription_COS15(2) +-> -> Recharge_Card_Validity_COS15(3) + + +Register leaf node: Recharge_Card_Validity_COS15. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.1) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) + + +Register leaf node: Min_balance_MO_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.2) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) +-> -> Maximum_Validity_COS15(1) + + +Register leaf node: Maximum_Validity_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.3) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) +-> -> Maximum_Validity_COS15(1) +-> -> Release_Day_COS15(2) + + +Register leaf node: Release_Day_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4.1) +-> father_name = [MT_Control_COS15] +-> -> Charge_Flag_COS15(0) + + +Register leaf node: Charge_Flag_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4.2) +-> father_name = [MT_Control_COS15] +-> -> Charge_Flag_COS15(0) +-> -> Zero_Balance_Control_COS15(1) + + +Register leaf node: Zero_Balance_Control_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) +-> -> Validity_Solution_COS15(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.1) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) + + +Register leaf node: Clear_Balance_Option_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.2) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) + + +Register leaf node: Validity_Recharge_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.3) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) + + +Register leaf node: Validity_Zero_Balance_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.4) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) + + +Register leaf node: Activated_Account_Validity_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.5) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) + + +Register leaf node: FF_Number_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.6) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) +-> -> Support_Credit_Card_COS15(5) + + +Register leaf node: Support_Credit_Card_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.7) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) +-> -> Support_Credit_Card_COS15(5) +-> -> Credit_Vault_COS15(6) + + +Register leaf node: Credit_Vault_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) +-> -> Validity_Solution_COS15(4) +-> -> SM_Inquiry_COS15(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.1) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) + + +Register leaf node: Feedback_SM_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.2) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) + + +Register leaf node: Inquiry_SM_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.3) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) +-> -> SM_Expiry_COS15(2) + + +Register leaf node: SM_Expiry_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.4) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) +-> -> SM_Expiry_COS15(2) +-> -> SM_Low_Balance_COS15(3) + + +Register leaf node: SM_Low_Balance_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Call_Routing_VMS(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) +-> -> Call_Routing_VMS(4) + + +Remark: Call routing to VMS . + + +Create node: VMS_PLMN_Maintenance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.1) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) + + +Register leaf node: VMS_PLMN_Maintenance. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS service number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: VMS_PSTN_Maintenance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.2) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) + + +Register leaf node: VMS_PSTN_Maintenance. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS service number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: VMS_leave_msg_No(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.3) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) + + +Register leaf node: VMS_leave_msg_No. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS deposit number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Rule(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.4) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) +-> -> Rule(3) + + +Register leaf node: Rule. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : rule + +Field : total(3) +Access : read-only [1]Route by + { + [u]0.0-0.0 + [u]select + [v]0[opt]Prefix + [v]1[opt]Whole number + } + [2]Route + { + [u]0.1-0.1 + [u]select + [v]0[opt]Caller number + [v]1[opt]Called number + } + + +Create node: VMS_User_Segments(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.5) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) +-> -> Rule(3) +-> -> VMS_User_Segments(4) + + +Register leaf node: VMS_User_Segments. +Instance: 128 +Length : 80 +Flag : 255 +Default : 86755900000 +Remark : VMS user segments + +Field : total(5) +Access : read-only[1]Start MSISDN + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } +[2]End MSISDN + { + [u]16.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[3]VMS service number - PLMN + { + [u]32.0-47.7 + [u]input + [v]ToAscii Low 0 + } +[4]VMS service number - PSTN + { + [u]48.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[5]Leave message deposit number + { + [u]64.0-79.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) +-> -> Call_Routing_VMS(4) +-> -> Status(5) + + +Remark: Status. + + +Create node: Activation(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.1) +-> father_name = [Status] +-> -> Activation(0) + + +Register leaf node: Activation. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set PPS system status. 0=normal. After initial PPS installation, if the PPS system doesn't has subscriber profiles, its status is suspended. In this case operator may set this parameter (normal) to activate the PPS server. + +Field : total(1) +Access : read-only [1]System status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Normal + } + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.2) +-> father_name = [Status] +-> -> Activation(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS management command. +Save parameters: Save PPS parameters in PPS memory to PPS hard disk. +Save user data: Save PPS subscriber data in PPS memory to PPS hard disk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + [v]2[opt]Save user data + } + + +Create node: MSS(OID: 1.3.6.1.4.1.1373.1.3.3.16) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) +-> -> PPS(4) +-> -> MSS(5) + + +Remark: Subsystems for MSS . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.16.2) +-> father_name = [MSS] +-> -> Configuration(0) + + +Remark: Configuration for MSS . + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.16.2.1) +-> father_name = [Configuration] +-> -> Management(0) + + +Remark: Management for MSS . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.16.2.1.1) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Safely shut down MSS server by stoping MSS process, saving subscriber data to harddisk and shut down the server. +Operation procedures: +1. Select -Shutdown- at above pulldown menu. +2. Click -Set- button in this set window. +3. Click -SET- button on operation page. + +Field : total(1) +Access : write-only [1]Command + { + [u]0.0-0.7 + [u]select + [v]4[opt]Shutdown + [v]5[opt]Undefine value + } + + diff --git a/mss/main/conf/aas_codec_table.conf b/mss/main/conf/aas_codec_table.conf new file mode 100644 index 0000000..d02617f --- /dev/null +++ b/mss/main/conf/aas_codec_table.conf @@ -0,0 +1,17 @@ +#[Coder name] [Txpayload] [RxPayload] [Ptime] +PCMA 8 8 20; +PCMU 0 0 20; +EVRC 60 60 20; +QC 62 62 20; +G729 18 18 20; +G729B 118 118 20; +GSM 3 3 20; +GSM-EFR 97 97 20; +AMR_4_75 98 98 20; +AMR_5_15 98 98 20; +AMR_5_9 98 98 20; +AMR_6_7 98 98 20; +AMR_7_4 98 98 20; +AMR_7_95 98 98 20; +AMR_10_2 98 98 20; +AMR_12_2 98 98 20; diff --git a/mss/main/conf/aas_langVG_Conf b/mss/main/conf/aas_langVG_Conf new file mode 100644 index 0000000..a035a92 --- /dev/null +++ b/mss/main/conf/aas_langVG_Conf @@ -0,0 +1,1285 @@ +#LANGUAGE00: +VoiceGroup000=121,130; +VoiceGroup001=122; +VoiceGroup002=123; +VoiceGroup003=124; +VoiceGroup004=125; +VoiceGroup005=126; +VoiceGroup006=127; +VoiceGroup007=128; +VoiceGroup008=106; +VoiceGroup009=129; +VoiceGroup010=120; +VoiceGroup011=161; +VoiceGroup012=133,9999,9999,134,9999; +VoiceGroup013=163; +VoiceGroup014=137; +VoiceGroup015=138; +VoiceGroup016=139; +VoiceGroup017=140,133,9999,9999,134,9999; +VoiceGroup018=141; +VoiceGroup019=142; +VoiceGroup020=170; +VoiceGroup021=143,142; +VoiceGroup022=144,142; +VoiceGroup023=145,142; +VoiceGroup024=146; +VoiceGroup025=147; +VoiceGroup026=148; +VoiceGroup027=146; +VoiceGroup028=171,9999,142; +VoiceGroup029=153; +VoiceGroup030=154,9999,150; +VoiceGroup031=150; +VoiceGroup032=149,9999,150; +VoiceGroup033=172,131; +VoiceGroup034=158,159,160,161,162; +VoiceGroup035=163,150; +VoiceGroup036=173,158,159,160,161,162; +VoiceGroup037=156; +VoiceGroup038=157; +VoiceGroup039=166; +VoiceGroup040=168; +VoiceGroup041=167; +VoiceGroup042=253,120; +VoiceGroup043=169,120; +VoiceGroup044=136; +VoiceGroup045=135; +VoiceGroup046=133,9999,9999; +VoiceGroup047=174,175; +VoiceGroup048=176; +VoiceGroup049=176,177; +VoiceGroup050=178; +VoiceGroup051=133,9999,9999,134,9999; +VoiceGroup052=; +VoiceGroup053=; +VoiceGroup054=179; +VoiceGroup055=; +VoiceGroup056=; +VoiceGroup057=; +VoiceGroup058=; +VoiceGroup059=133,9999,9999,134,9999,360,9999,134,9999; +VoiceGroup060=180; +VoiceGroup061=181,182; +VoiceGroup062=181,182; +VoiceGroup063=183; +VoiceGroup064=; +VoiceGroup065=; +VoiceGroup066=; +VoiceGroup067=; +VoiceGroup068=; +VoiceGroup069=; +VoiceGroup070=; +VoiceGroup071=; +VoiceGroup072=; +VoiceGroup073=; +VoiceGroup074=; +VoiceGroup075=; +VoiceGroup076=; +VoiceGroup077=; +VoiceGroup078=; +VoiceGroup079=; +VoiceGroup080=; +VoiceGroup081=; +VoiceGroup082=; +VoiceGroup083=; +VoiceGroup084=; +VoiceGroup085=; +VoiceGroup086=; +VoiceGroup087=; +VoiceGroup088=; +VoiceGroup089=; +VoiceGroup090=; +VoiceGroup091=; +VoiceGroup092=; +VoiceGroup093=; +VoiceGroup094=; +VoiceGroup095=; +VoiceGroup096=; +VoiceGroup097=; +VoiceGroup098=; +VoiceGroup099=; +VoiceGroup100=256; +VoiceGroup101=257,291; +VoiceGroup102=258; +VoiceGroup103=259; +VoiceGroup104=260; +VoiceGroup105=261; +VoiceGroup106=262,291; +VoiceGroup107=263,291; +VoiceGroup108=264; +VoiceGroup109=265; +VoiceGroup110=266; +VoiceGroup111=169; +VoiceGroup112=; +VoiceGroup113=; +VoiceGroup114=; +VoiceGroup115=; +VoiceGroup116=; +VoiceGroup117=; +VoiceGroup118=; +VoiceGroup119=; +VoiceGroup120=271; +VoiceGroup121=272; +VoiceGroup122=273; +VoiceGroup123=274,291; +VoiceGroup124=275,291; +VoiceGroup125=276; +VoiceGroup126=277,275,291; +VoiceGroup127=278,291; +VoiceGroup128=279; +VoiceGroup129=280; +VoiceGroup130=281; +VoiceGroup131=282; +VoiceGroup132=283; +VoiceGroup133=284; +VoiceGroup134=285; +VoiceGroup135=286; +VoiceGroup136=287; +VoiceGroup137=288; +VoiceGroup138=289; +VoiceGroup139=171,9999; +VoiceGroup140=273,290; +VoiceGroup141=; +VoiceGroup142=; +VoiceGroup143=; +VoiceGroup144=; +VoiceGroup145=; +VoiceGroup146=; +VoiceGroup147=; +VoiceGroup148=; +VoiceGroup149=; +VoiceGroup150=300,291; +VoiceGroup151=301; +VoiceGroup152=302; +VoiceGroup153=303,291; +VoiceGroup154=304; +VoiceGroup155=305; +VoiceGroup156=306; +VoiceGroup157=307,9999,43,9999; +VoiceGroup158=308; +VoiceGroup159=309; +VoiceGroup160=; +VoiceGroup161=310; +VoiceGroup162=314; +VoiceGroup163=333; +VoiceGroup164=151,9999,86,85,311,9999,341; +VoiceGroup165=86,84,39,9999,311,9999,341; +VoiceGroup166=313,311,341; +VoiceGroup167=312; +VoiceGroup168=315,9999; +VoiceGroup169=316,9999,318,319,334,9999,336,319,317,9999,319; +VoiceGroup170=320,9999,318,322,335,9999,336,322,321,9999,322; +VoiceGroup171=323,291; +VoiceGroup172=324,291; +VoiceGroup173=337,327,323,291; +VoiceGroup174=328,324,291; +VoiceGroup175=337,332; +VoiceGroup176=337,153; +VoiceGroup177=333; +VoiceGroup178=329; +VoiceGroup179=325,9999,338,9999; +VoiceGroup180=326,9999,150; +VoiceGroup181=330; +VoiceGroup182=331; +VoiceGroup183=339; +VoiceGroup184=340; +VoiceGroup185=; +VoiceGroup186=; +VoiceGroup187=; +VoiceGroup188=; +VoiceGroup189=; +VoiceGroup190=; +VoiceGroup191=; +VoiceGroup192=; +VoiceGroup193=; +VoiceGroup194=; +VoiceGroup195=; +VoiceGroup196=; +VoiceGroup197=; +VoiceGroup198=; +VoiceGroup199=; +VoiceGroup200=; +VoiceGroup201=; +VoiceGroup202=; +VoiceGroup203=; +VoiceGroup204=; +VoiceGroup205=; +VoiceGroup206=; +VoiceGroup207=; +VoiceGroup208=; +VoiceGroup209=; +VoiceGroup210=; +VoiceGroup211=; +VoiceGroup212=; +VoiceGroup213=; +VoiceGroup214=; +VoiceGroup215=; +VoiceGroup216=; +VoiceGroup217=; +VoiceGroup218=; +VoiceGroup219=; +VoiceGroup220=; +VoiceGroup221=; +VoiceGroup222=; +VoiceGroup223=; +VoiceGroup224=; +VoiceGroup225=; +VoiceGroup226=; +VoiceGroup227=; +VoiceGroup228=; +VoiceGroup229=; +VoiceGroup230=; +VoiceGroup231=; +VoiceGroup232=; +VoiceGroup233=; +VoiceGroup234=; +VoiceGroup235=; +VoiceGroup236=; +VoiceGroup237=; +VoiceGroup238=; +VoiceGroup239=; +VoiceGroup240=; +VoiceGroup241=; +VoiceGroup242=; +VoiceGroup243=; +VoiceGroup244=; +VoiceGroup245=; +VoiceGroup246=; +VoiceGroup247=; +VoiceGroup248=; +VoiceGroup249=; +VoiceGroup250=; +VoiceGroup251=; +VoiceGroup252=; +VoiceGroup253=; +VoiceGroup254=; +VoiceGroup255=; +#LANGUAGE01: +VoiceGroup000=121,130; +VoiceGroup001=122; +VoiceGroup002=123; +VoiceGroup003=124; +VoiceGroup004=125; +VoiceGroup005=126; +VoiceGroup006=127; +VoiceGroup007=128; +VoiceGroup008=106; +VoiceGroup009=129; +VoiceGroup010=120; +VoiceGroup011=161; +VoiceGroup012=133,9999,134,99999; +VoiceGroup013=163; +VoiceGroup014=137; +VoiceGroup015=138; +VoiceGroup016=139; +VoiceGroup017=140,133,9999,134,9999; +VoiceGroup018=141; +VoiceGroup019=142; +VoiceGroup020=170; +VoiceGroup021=143,142; +VoiceGroup022=144,142; +VoiceGroup023=145,142; +VoiceGroup024=146; +VoiceGroup025=147; +VoiceGroup026=148; +VoiceGroup027=146; +VoiceGroup028=171,9999,142; +VoiceGroup029=153; +VoiceGroup030=154,9999,150; +VoiceGroup031=150; +VoiceGroup032=149,9999,150; +VoiceGroup033=172,131; +VoiceGroup034=158,159,160,161,162; +VoiceGroup035=163,150; +VoiceGroup036=173,158,159,160,161,162; +VoiceGroup037=156; +VoiceGroup038=157; +VoiceGroup039=166; +VoiceGroup040=168; +VoiceGroup041=167; +VoiceGroup042=253,120; +VoiceGroup043=169,120; +VoiceGroup044=136; +VoiceGroup045=135; +VoiceGroup046=133,9999; +VoiceGroup047=174,175; +VoiceGroup048=176; +VoiceGroup049=176,177; +VoiceGroup050=178; +VoiceGroup051=133,9999,134,9999; +VoiceGroup052=; +VoiceGroup053=; +VoiceGroup054=179; +VoiceGroup055=; +VoiceGroup056=; +VoiceGroup057=; +VoiceGroup058=; +VoiceGroup059=133,9999,134,9999,360,9999,134,9999; +VoiceGroup060=180; +VoiceGroup061=181,182; +VoiceGroup062=181,182; +VoiceGroup063=183; +VoiceGroup064=; +VoiceGroup065=; +VoiceGroup066=; +VoiceGroup067=; +VoiceGroup068=; +VoiceGroup069=; +VoiceGroup070=; +VoiceGroup071=; +VoiceGroup072=; +VoiceGroup073=; +VoiceGroup074=; +VoiceGroup075=; +VoiceGroup076=; +VoiceGroup077=; +VoiceGroup078=; +VoiceGroup079=; +VoiceGroup080=; +VoiceGroup081=; +VoiceGroup082=; +VoiceGroup083=; +VoiceGroup084=; +VoiceGroup085=; +VoiceGroup086=; +VoiceGroup087=; +VoiceGroup088=; +VoiceGroup089=; +VoiceGroup090=; +VoiceGroup091=; +VoiceGroup092=; +VoiceGroup093=; +VoiceGroup094=; +VoiceGroup095=; +VoiceGroup096=; +VoiceGroup097=; +VoiceGroup098=; +VoiceGroup099=; +VoiceGroup100=256; +VoiceGroup101=257; +VoiceGroup102=258; +VoiceGroup103=259; +VoiceGroup104=260; +VoiceGroup105=261; +VoiceGroup106=262; +VoiceGroup107=263; +VoiceGroup108=264; +VoiceGroup109=265; +VoiceGroup110=266; +VoiceGroup111=169; +VoiceGroup112=; +VoiceGroup113=; +VoiceGroup114=; +VoiceGroup115=; +VoiceGroup116=; +VoiceGroup117=; +VoiceGroup118=; +VoiceGroup119=; +VoiceGroup120=271; +VoiceGroup121=272; +VoiceGroup122=273; +VoiceGroup123=274; +VoiceGroup124=275; +VoiceGroup125=276; +VoiceGroup126=277,275; +VoiceGroup127=278; +VoiceGroup128=279; +VoiceGroup129=280; +VoiceGroup130=281; +VoiceGroup131=282; +VoiceGroup132=283; +VoiceGroup133=284; +VoiceGroup134=285; +VoiceGroup135=286; +VoiceGroup136=287; +VoiceGroup137=288; +VoiceGroup138=289; +VoiceGroup139=171,9999; +VoiceGroup140=273,290; +VoiceGroup141=; +VoiceGroup142=; +VoiceGroup143=; +VoiceGroup144=; +VoiceGroup145=; +VoiceGroup146=; +VoiceGroup147=; +VoiceGroup148=; +VoiceGroup149=; +VoiceGroup150=; +VoiceGroup151=; +VoiceGroup152=; +VoiceGroup153=; +VoiceGroup154=; +VoiceGroup155=; +VoiceGroup156=; +VoiceGroup157=; +VoiceGroup158=; +VoiceGroup159=; +VoiceGroup160=; +VoiceGroup161=; +VoiceGroup162=; +VoiceGroup163=; +VoiceGroup164=; +VoiceGroup165=; +VoiceGroup166=; +VoiceGroup167=; +VoiceGroup168=; +VoiceGroup169=; +VoiceGroup170=; +VoiceGroup171=; +VoiceGroup172=; +VoiceGroup173=; +VoiceGroup174=; +VoiceGroup175=; +VoiceGroup176=; +VoiceGroup177=; +VoiceGroup178=; +VoiceGroup179=; +VoiceGroup180=; +VoiceGroup181=; +VoiceGroup182=; +VoiceGroup183=; +VoiceGroup184=; +VoiceGroup185=; +VoiceGroup186=; +VoiceGroup187=; +VoiceGroup188=; +VoiceGroup189=; +VoiceGroup190=; +VoiceGroup191=; +VoiceGroup192=; +VoiceGroup193=; +VoiceGroup194=; +VoiceGroup195=; +VoiceGroup196=; +VoiceGroup197=; +VoiceGroup198=; +VoiceGroup199=; +VoiceGroup200=; +VoiceGroup201=; +VoiceGroup202=; +VoiceGroup203=; +VoiceGroup204=; +VoiceGroup205=; +VoiceGroup206=; +VoiceGroup207=; +VoiceGroup208=; +VoiceGroup209=; +VoiceGroup210=; +VoiceGroup211=; +VoiceGroup212=; +VoiceGroup213=; +VoiceGroup214=; +VoiceGroup215=; +VoiceGroup216=; +VoiceGroup217=; +VoiceGroup218=; +VoiceGroup219=; +VoiceGroup220=; +VoiceGroup221=; +VoiceGroup222=; +VoiceGroup223=; +VoiceGroup224=; +VoiceGroup225=; +VoiceGroup226=; +VoiceGroup227=; +VoiceGroup228=; +VoiceGroup229=; +VoiceGroup230=; +VoiceGroup231=; +VoiceGroup232=; +VoiceGroup233=; +VoiceGroup234=; +VoiceGroup235=; +VoiceGroup236=; +VoiceGroup237=; +VoiceGroup238=; +VoiceGroup239=; +VoiceGroup240=; +VoiceGroup241=; +VoiceGroup242=; +VoiceGroup243=; +VoiceGroup244=; +VoiceGroup245=; +VoiceGroup246=; +VoiceGroup247=; +VoiceGroup248=; +VoiceGroup249=; +VoiceGroup250=; +VoiceGroup251=; +VoiceGroup252=; +VoiceGroup253=; +VoiceGroup254=; +VoiceGroup255=; +#LANGUAGE02: +VoiceGroup000=121,130; +VoiceGroup001=122; +VoiceGroup002=123; +VoiceGroup003=124; +VoiceGroup004=125; +VoiceGroup005=126; +VoiceGroup006=127; +VoiceGroup007=128; +VoiceGroup008=106; +VoiceGroup009=129; +VoiceGroup010=120; +VoiceGroup011=161; +VoiceGroup012=133,9999,134,9999; +VoiceGroup013=163; +VoiceGroup014=137; +VoiceGroup015=138; +VoiceGroup016=139; +VoiceGroup017=140,133,9999,134,9999; +VoiceGroup018=141; +VoiceGroup019=142; +VoiceGroup020=170; +VoiceGroup021=143,142; +VoiceGroup022=144,142; +VoiceGroup023=145,142; +VoiceGroup024=146; +VoiceGroup025=147; +VoiceGroup026=148; +VoiceGroup027=146; +VoiceGroup028=171,9999,142; +VoiceGroup029=153; +VoiceGroup030=154,9999,150; +VoiceGroup031=150; +VoiceGroup032=149,9999,150; +VoiceGroup033=172,131; +VoiceGroup034=158,159,160,161,162; +VoiceGroup035=163,150; +VoiceGroup036=173,158,159,160,161,162; +VoiceGroup037=156; +VoiceGroup038=157; +VoiceGroup039=166; +VoiceGroup040=168; +VoiceGroup041=167; +VoiceGroup042=253; +VoiceGroup043=169,120; +VoiceGroup044=136; +VoiceGroup045=135; +VoiceGroup046=133,9999; +VoiceGroup047=174,175; +VoiceGroup048=176; +VoiceGroup049=176,177; +VoiceGroup050=178; +VoiceGroup051=133,9999,134,9999; +VoiceGroup052=; +VoiceGroup053=; +VoiceGroup054=179; +VoiceGroup055=; +VoiceGroup056=; +VoiceGroup057=; +VoiceGroup058=; +VoiceGroup059=; +VoiceGroup060=180; +VoiceGroup061=181,182; +VoiceGroup062=181,182; +VoiceGroup063=183; +VoiceGroup064=; +VoiceGroup065=; +VoiceGroup066=; +VoiceGroup067=; +VoiceGroup068=; +VoiceGroup069=; +VoiceGroup070=; +VoiceGroup071=; +VoiceGroup072=; +VoiceGroup073=; +VoiceGroup074=; +VoiceGroup075=; +VoiceGroup076=; +VoiceGroup077=; +VoiceGroup078=; +VoiceGroup079=; +VoiceGroup080=; +VoiceGroup081=; +VoiceGroup082=; +VoiceGroup083=; +VoiceGroup084=; +VoiceGroup085=; +VoiceGroup086=; +VoiceGroup087=; +VoiceGroup088=; +VoiceGroup089=; +VoiceGroup090=; +VoiceGroup091=; +VoiceGroup092=; +VoiceGroup093=; +VoiceGroup094=; +VoiceGroup095=; +VoiceGroup096=; +VoiceGroup097=; +VoiceGroup098=; +VoiceGroup099=; +VoiceGroup100=256; +VoiceGroup101=257; +VoiceGroup102=258; +VoiceGroup103=259; +VoiceGroup104=260; +VoiceGroup105=261; +VoiceGroup106=262; +VoiceGroup107=263; +VoiceGroup108=264; +VoiceGroup109=265; +VoiceGroup110=266; +VoiceGroup111=169; +VoiceGroup112=; +VoiceGroup113=; +VoiceGroup114=; +VoiceGroup115=; +VoiceGroup116=; +VoiceGroup117=; +VoiceGroup118=; +VoiceGroup119=; +VoiceGroup120=271; +VoiceGroup121=272; +VoiceGroup122=273; +VoiceGroup123=274; +VoiceGroup124=275; +VoiceGroup125=276; +VoiceGroup126=277,275; +VoiceGroup127=278; +VoiceGroup128=279; +VoiceGroup129=280; +VoiceGroup130=281; +VoiceGroup131=282; +VoiceGroup132=283; +VoiceGroup133=284; +VoiceGroup134=285; +VoiceGroup135=286; +VoiceGroup136=287; +VoiceGroup137=288; +VoiceGroup138=289; +VoiceGroup139=171,9999; +VoiceGroup140=273,290; +VoiceGroup141=; +VoiceGroup142=; +VoiceGroup143=; +VoiceGroup144=; +VoiceGroup145=; +VoiceGroup146=; +VoiceGroup147=; +VoiceGroup148=; +VoiceGroup149=; +VoiceGroup150=; +VoiceGroup151=; +VoiceGroup152=; +VoiceGroup153=; +VoiceGroup154=; +VoiceGroup155=; +VoiceGroup156=; +VoiceGroup157=; +VoiceGroup158=; +VoiceGroup159=; +VoiceGroup160=; +VoiceGroup161=; +VoiceGroup162=; +VoiceGroup163=; +VoiceGroup164=; +VoiceGroup165=; +VoiceGroup166=; +VoiceGroup167=; +VoiceGroup168=; +VoiceGroup169=; +VoiceGroup170=; +VoiceGroup171=; +VoiceGroup172=; +VoiceGroup173=; +VoiceGroup174=; +VoiceGroup175=; +VoiceGroup176=; +VoiceGroup177=; +VoiceGroup178=; +VoiceGroup179=; +VoiceGroup180=; +VoiceGroup181=; +VoiceGroup182=; +VoiceGroup183=; +VoiceGroup184=; +VoiceGroup185=; +VoiceGroup186=; +VoiceGroup187=; +VoiceGroup188=; +VoiceGroup189=; +VoiceGroup190=; +VoiceGroup191=; +VoiceGroup192=; +VoiceGroup193=; +VoiceGroup194=; +VoiceGroup195=; +VoiceGroup196=; +VoiceGroup197=; +VoiceGroup198=; +VoiceGroup199=; +VoiceGroup200=; +VoiceGroup201=; +VoiceGroup202=; +VoiceGroup203=; +VoiceGroup204=; +VoiceGroup205=; +VoiceGroup206=; +VoiceGroup207=; +VoiceGroup208=; +VoiceGroup209=; +VoiceGroup210=; +VoiceGroup211=; +VoiceGroup212=; +VoiceGroup213=; +VoiceGroup214=; +VoiceGroup215=; +VoiceGroup216=; +VoiceGroup217=; +VoiceGroup218=; +VoiceGroup219=; +VoiceGroup220=; +VoiceGroup221=; +VoiceGroup222=; +VoiceGroup223=; +VoiceGroup224=; +VoiceGroup225=; +VoiceGroup226=; +VoiceGroup227=; +VoiceGroup228=; +VoiceGroup229=; +VoiceGroup230=; +VoiceGroup231=; +VoiceGroup232=; +VoiceGroup233=; +VoiceGroup234=; +VoiceGroup235=; +VoiceGroup236=; +VoiceGroup237=; +VoiceGroup238=; +VoiceGroup239=; +VoiceGroup240=; +VoiceGroup241=; +VoiceGroup242=; +VoiceGroup243=; +VoiceGroup244=; +VoiceGroup245=; +VoiceGroup246=; +VoiceGroup247=; +VoiceGroup248=; +VoiceGroup249=; +VoiceGroup250=; +VoiceGroup251=; +VoiceGroup252=; +VoiceGroup253=; +VoiceGroup254=; +VoiceGroup255=; +#LANGUAGE03: +VoiceGroup000=121,130; +VoiceGroup001=122; +VoiceGroup002=123; +VoiceGroup003=124; +VoiceGroup004=125; +VoiceGroup005=126; +VoiceGroup006=127; +VoiceGroup007=128; +VoiceGroup008=106; +VoiceGroup009=129; +VoiceGroup010=120; +VoiceGroup011=161; +VoiceGroup012=133,9999,134,9999; +VoiceGroup013=163; +VoiceGroup014=137; +VoiceGroup015=138; +VoiceGroup016=139; +VoiceGroup017=140,133,9999,134,9999; +VoiceGroup018=141; +VoiceGroup019=142; +VoiceGroup020=170; +VoiceGroup021=143,142; +VoiceGroup022=144,142; +VoiceGroup023=145,142; +VoiceGroup024=146; +VoiceGroup025=147; +VoiceGroup026=148; +VoiceGroup027=146; +VoiceGroup028=171,9999,142; +VoiceGroup029=153; +VoiceGroup030=154,9999,150; +VoiceGroup031=150; +VoiceGroup032=149,9999,150; +VoiceGroup033=172,131; +VoiceGroup034=158,159,160,161,162; +VoiceGroup035=163,150; +VoiceGroup036=173,158,159,160,161,162; +VoiceGroup037=156; +VoiceGroup038=157; +VoiceGroup039=166; +VoiceGroup040=168; +VoiceGroup041=167; +VoiceGroup042=253; +VoiceGroup043=169,120; +VoiceGroup044=136; +VoiceGroup045=135; +VoiceGroup046=133,9999; +VoiceGroup047=174,175; +VoiceGroup048=176; +VoiceGroup049=176,177; +VoiceGroup050=178; +VoiceGroup051=133,9999,134,9999; +VoiceGroup052=; +VoiceGroup053=; +VoiceGroup054=179; +VoiceGroup055=; +VoiceGroup056=; +VoiceGroup057=; +VoiceGroup058=; +VoiceGroup059=; +VoiceGroup060=180; +VoiceGroup061=181,182; +VoiceGroup062=181,182; +VoiceGroup063=183; +VoiceGroup064=; +VoiceGroup065=; +VoiceGroup066=; +VoiceGroup067=; +VoiceGroup068=; +VoiceGroup069=; +VoiceGroup070=; +VoiceGroup071=; +VoiceGroup072=; +VoiceGroup073=; +VoiceGroup074=; +VoiceGroup075=; +VoiceGroup076=; +VoiceGroup077=; +VoiceGroup078=; +VoiceGroup079=; +VoiceGroup080=; +VoiceGroup081=; +VoiceGroup082=; +VoiceGroup083=; +VoiceGroup084=; +VoiceGroup085=; +VoiceGroup086=; +VoiceGroup087=; +VoiceGroup088=; +VoiceGroup089=; +VoiceGroup090=; +VoiceGroup091=; +VoiceGroup092=; +VoiceGroup093=; +VoiceGroup094=; +VoiceGroup095=; +VoiceGroup096=; +VoiceGroup097=; +VoiceGroup098=; +VoiceGroup099=; +VoiceGroup100=256; +VoiceGroup101=257; +VoiceGroup102=258; +VoiceGroup103=259; +VoiceGroup104=260; +VoiceGroup105=261; +VoiceGroup106=262; +VoiceGroup107=263; +VoiceGroup108=264; +VoiceGroup109=265; +VoiceGroup110=266; +VoiceGroup111=169; +VoiceGroup112=; +VoiceGroup113=; +VoiceGroup114=; +VoiceGroup115=; +VoiceGroup116=; +VoiceGroup117=; +VoiceGroup118=; +VoiceGroup119=; +VoiceGroup120=271; +VoiceGroup121=272; +VoiceGroup122=273; +VoiceGroup123=274; +VoiceGroup124=275; +VoiceGroup125=276; +VoiceGroup126=277,275; +VoiceGroup127=278; +VoiceGroup128=279; +VoiceGroup129=280; +VoiceGroup130=281; +VoiceGroup131=282; +VoiceGroup132=283; +VoiceGroup133=284; +VoiceGroup134=285; +VoiceGroup135=286; +VoiceGroup136=287; +VoiceGroup137=288; +VoiceGroup138=289; +VoiceGroup139=171,9999; +VoiceGroup140=273,290; +VoiceGroup141=; +VoiceGroup142=; +VoiceGroup143=; +VoiceGroup144=; +VoiceGroup145=; +VoiceGroup146=; +VoiceGroup147=; +VoiceGroup148=; +VoiceGroup149=; +VoiceGroup150=; +VoiceGroup151=; +VoiceGroup152=; +VoiceGroup153=; +VoiceGroup154=; +VoiceGroup155=; +VoiceGroup156=; +VoiceGroup157=; +VoiceGroup158=; +VoiceGroup159=; +VoiceGroup160=; +VoiceGroup161=; +VoiceGroup162=; +VoiceGroup163=; +VoiceGroup164=; +VoiceGroup165=; +VoiceGroup166=; +VoiceGroup167=; +VoiceGroup168=; +VoiceGroup169=; +VoiceGroup170=; +VoiceGroup171=; +VoiceGroup172=; +VoiceGroup173=; +VoiceGroup174=; +VoiceGroup175=; +VoiceGroup176=; +VoiceGroup177=; +VoiceGroup178=; +VoiceGroup179=; +VoiceGroup180=; +VoiceGroup181=; +VoiceGroup182=; +VoiceGroup183=; +VoiceGroup184=; +VoiceGroup185=; +VoiceGroup186=; +VoiceGroup187=; +VoiceGroup188=; +VoiceGroup189=; +VoiceGroup190=; +VoiceGroup191=; +VoiceGroup192=; +VoiceGroup193=; +VoiceGroup194=; +VoiceGroup195=; +VoiceGroup196=; +VoiceGroup197=; +VoiceGroup198=; +VoiceGroup199=; +VoiceGroup200=; +VoiceGroup201=; +VoiceGroup202=; +VoiceGroup203=; +VoiceGroup204=; +VoiceGroup205=; +VoiceGroup206=; +VoiceGroup207=; +VoiceGroup208=; +VoiceGroup209=; +VoiceGroup210=; +VoiceGroup211=; +VoiceGroup212=; +VoiceGroup213=; +VoiceGroup214=; +VoiceGroup215=; +VoiceGroup216=; +VoiceGroup217=; +VoiceGroup218=; +VoiceGroup219=; +VoiceGroup220=; +VoiceGroup221=; +VoiceGroup222=; +VoiceGroup223=; +VoiceGroup224=; +VoiceGroup225=; +VoiceGroup226=; +VoiceGroup227=; +VoiceGroup228=; +VoiceGroup229=; +VoiceGroup230=; +VoiceGroup231=; +VoiceGroup232=; +VoiceGroup233=; +VoiceGroup234=; +VoiceGroup235=; +VoiceGroup236=; +VoiceGroup237=; +VoiceGroup238=; +VoiceGroup239=; +VoiceGroup240=; +VoiceGroup241=; +VoiceGroup242=; +VoiceGroup243=; +VoiceGroup244=; +VoiceGroup245=; +VoiceGroup246=; +VoiceGroup247=; +VoiceGroup248=; +VoiceGroup249=; +VoiceGroup250=; +VoiceGroup251=; +VoiceGroup252=; +VoiceGroup253=; +VoiceGroup254=; +VoiceGroup255=; +#LANGUAGE04: +VoiceGroup000=121,130; +VoiceGroup001=122; +VoiceGroup002=123; +VoiceGroup003=124; +VoiceGroup004=125; +VoiceGroup005=126; +VoiceGroup006=127; +VoiceGroup007=128; +VoiceGroup008=106; +VoiceGroup009=129; +VoiceGroup010=120; +VoiceGroup011=161; +VoiceGroup012=133,9999,134,9999; +VoiceGroup013=163; +VoiceGroup014=137; +VoiceGroup015=138; +VoiceGroup016=139; +VoiceGroup017=140,133,9999,134,9999; +VoiceGroup018=141; +VoiceGroup019=142; +VoiceGroup020=170; +VoiceGroup021=143,142; +VoiceGroup022=144,142; +VoiceGroup023=145,142; +VoiceGroup024=146; +VoiceGroup025=147; +VoiceGroup026=148; +VoiceGroup027=146; +VoiceGroup028=171,9999,142; +VoiceGroup029=153; +VoiceGroup030=154,9999,150; +VoiceGroup031=150; +VoiceGroup032=149,9999,150; +VoiceGroup033=172,131; +VoiceGroup034=158,159,160,161,162; +VoiceGroup035=163,150; +VoiceGroup036=173,158,159,160,161,162; +VoiceGroup037=156; +VoiceGroup038=157; +VoiceGroup039=166; +VoiceGroup040=168; +VoiceGroup041=167; +VoiceGroup042=253; +VoiceGroup043=169,120; +VoiceGroup044=136; +VoiceGroup045=135; +VoiceGroup046=133,9999; +VoiceGroup047=174,175; +VoiceGroup048=176; +VoiceGroup049=176,177; +VoiceGroup050=178; +VoiceGroup051=133,9999,134,9999; +VoiceGroup052=; +VoiceGroup053=; +VoiceGroup054=179; +VoiceGroup055=; +VoiceGroup056=; +VoiceGroup057=; +VoiceGroup058=; +VoiceGroup059=; +VoiceGroup060=180; +VoiceGroup061=181,182; +VoiceGroup062=181,182; +VoiceGroup063=183; +VoiceGroup064=; +VoiceGroup065=; +VoiceGroup066=; +VoiceGroup067=; +VoiceGroup068=; +VoiceGroup069=; +VoiceGroup070=; +VoiceGroup071=; +VoiceGroup072=; +VoiceGroup073=; +VoiceGroup074=; +VoiceGroup075=; +VoiceGroup076=; +VoiceGroup077=; +VoiceGroup078=; +VoiceGroup079=; +VoiceGroup080=; +VoiceGroup081=; +VoiceGroup082=; +VoiceGroup083=; +VoiceGroup084=; +VoiceGroup085=; +VoiceGroup086=; +VoiceGroup087=; +VoiceGroup088=; +VoiceGroup089=; +VoiceGroup090=; +VoiceGroup091=; +VoiceGroup092=; +VoiceGroup093=; +VoiceGroup094=; +VoiceGroup095=; +VoiceGroup096=; +VoiceGroup097=; +VoiceGroup098=; +VoiceGroup099=; +VoiceGroup100=256; +VoiceGroup101=257; +VoiceGroup102=258; +VoiceGroup103=259; +VoiceGroup104=260; +VoiceGroup105=261; +VoiceGroup106=262; +VoiceGroup107=263; +VoiceGroup108=264; +VoiceGroup109=265; +VoiceGroup110=266; +VoiceGroup111=169; +VoiceGroup112=; +VoiceGroup113=; +VoiceGroup114=; +VoiceGroup115=; +VoiceGroup116=; +VoiceGroup117=; +VoiceGroup118=; +VoiceGroup119=; +VoiceGroup120=271; +VoiceGroup121=272; +VoiceGroup122=273; +VoiceGroup123=274; +VoiceGroup124=275; +VoiceGroup125=276; +VoiceGroup126=277,275; +VoiceGroup127=278; +VoiceGroup128=279; +VoiceGroup129=280; +VoiceGroup130=281; +VoiceGroup131=282; +VoiceGroup132=283; +VoiceGroup133=284; +VoiceGroup134=285; +VoiceGroup135=286; +VoiceGroup136=287; +VoiceGroup137=288; +VoiceGroup138=289; +VoiceGroup139=171,9999; +VoiceGroup140=273,290; +VoiceGroup141=; +VoiceGroup142=; +VoiceGroup143=; +VoiceGroup144=; +VoiceGroup145=; +VoiceGroup146=; +VoiceGroup147=; +VoiceGroup148=; +VoiceGroup149=; +VoiceGroup150=; +VoiceGroup151=; +VoiceGroup152=; +VoiceGroup153=; +VoiceGroup154=; +VoiceGroup155=; +VoiceGroup156=; +VoiceGroup157=; +VoiceGroup158=; +VoiceGroup159=; +VoiceGroup160=; +VoiceGroup161=; +VoiceGroup162=; +VoiceGroup163=; +VoiceGroup164=; +VoiceGroup165=; +VoiceGroup166=; +VoiceGroup167=; +VoiceGroup168=; +VoiceGroup169=; +VoiceGroup170=; +VoiceGroup171=; +VoiceGroup172=; +VoiceGroup173=; +VoiceGroup174=; +VoiceGroup175=; +VoiceGroup176=; +VoiceGroup177=; +VoiceGroup178=; +VoiceGroup179=; +VoiceGroup180=; +VoiceGroup181=; +VoiceGroup182=; +VoiceGroup183=; +VoiceGroup184=; +VoiceGroup185=; +VoiceGroup186=; +VoiceGroup187=; +VoiceGroup188=; +VoiceGroup189=; +VoiceGroup190=; +VoiceGroup191=; +VoiceGroup192=; +VoiceGroup193=; +VoiceGroup194=; +VoiceGroup195=; +VoiceGroup196=; +VoiceGroup197=; +VoiceGroup198=; +VoiceGroup199=; +VoiceGroup200=; +VoiceGroup201=; +VoiceGroup202=; +VoiceGroup203=; +VoiceGroup204=; +VoiceGroup205=; +VoiceGroup206=; +VoiceGroup207=; +VoiceGroup208=; +VoiceGroup209=; +VoiceGroup210=; +VoiceGroup211=; +VoiceGroup212=; +VoiceGroup213=; +VoiceGroup214=; +VoiceGroup215=; +VoiceGroup216=; +VoiceGroup217=; +VoiceGroup218=; +VoiceGroup219=; +VoiceGroup220=; +VoiceGroup221=; +VoiceGroup222=; +VoiceGroup223=; +VoiceGroup224=; +VoiceGroup225=; +VoiceGroup226=; +VoiceGroup227=; +VoiceGroup228=; +VoiceGroup229=; +VoiceGroup230=; +VoiceGroup231=; +VoiceGroup232=; +VoiceGroup233=; +VoiceGroup234=; +VoiceGroup235=; +VoiceGroup236=; +VoiceGroup237=; +VoiceGroup238=; +VoiceGroup239=; +VoiceGroup240=; +VoiceGroup241=; +VoiceGroup242=; +VoiceGroup243=; +VoiceGroup244=; +VoiceGroup245=; +VoiceGroup246=; +VoiceGroup247=; +VoiceGroup248=; +VoiceGroup249=; +VoiceGroup250=; +VoiceGroup251=; +VoiceGroup252=; +VoiceGroup253=; +VoiceGroup254=; +VoiceGroup255=; diff --git a/mss/main/conf/aas_publicVG_Conf b/mss/main/conf/aas_publicVG_Conf new file mode 100644 index 0000000..1446cce --- /dev/null +++ b/mss/main/conf/aas_publicVG_Conf @@ -0,0 +1,32 @@ +VoiceGroup000=BB00,100; +VoiceGroup001=BB00,101; +VoiceGroup002=BB00,102; +VoiceGroup003=BB00,103; +VoiceGroup004=BB00,104; +VoiceGroup005=BB00,105; +VoiceGroup006=BB00,106; +VoiceGroup007=BB00,107; +VoiceGroup008=BB00,108; +VoiceGroup009=BB00,109; +VoiceGroup010=BB00,110; +VoiceGroup011=BB00,111; +VoiceGroup012=BB00,112; +VoiceGroup013=; +VoiceGroup014=; +VoiceGroup015=; +VoiceGroup016=; +VoiceGroup017=; +VoiceGroup018=; +VoiceGroup019=; +VoiceGroup020=; +VoiceGroup021=; +VoiceGroup022=; +VoiceGroup023=; +VoiceGroup024=; +VoiceGroup025=; +VoiceGroup026=; +VoiceGroup027=; +VoiceGroup028=; +VoiceGroup029=; +VoiceGroup030=; +VoiceGroup031=; diff --git a/mss/main/conf/alaw2intel b/mss/main/conf/alaw2intel new file mode 100644 index 0000000000000000000000000000000000000000..6b6955721530b6857318e86b9e93cb3a3bf0c7cf GIT binary patch literal 34398 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 literal 0 HcmV?d00001 diff --git a/mss/main/conf/cap_acn.conf b/mss/main/conf/cap_acn.conf new file mode 100644 index 0000000..bc61171 --- /dev/null +++ b/mss/main/conf/cap_acn.conf @@ -0,0 +1,8 @@ +#application context name configure file for CAP +total data length=4 + +#application context name data +No.1:50 02 // gsmSSF to gsmSCF +No.2:51 02 // assist handoff gsmSSF to gsmSCF +No.3:52 02 // gsmSRF to gsmSCF +No.4:128 02 // gsmSRF to gsmSCF diff --git a/mss/main/conf/cap_acn.confV1 b/mss/main/conf/cap_acn.confV1 new file mode 100644 index 0000000..9b4f796 --- /dev/null +++ b/mss/main/conf/cap_acn.confV1 @@ -0,0 +1,8 @@ +#application context name configure file for CAP +total data length=4 + +#application context name data +No.1:50 00 // gsmSSF to gsmSCF +No.2:51 00 // assist handoff gsmSSF to gsmSCF +No.3:52 00 // gsmSRF to gsmSCF +No.4:128 00 // gsmSRF to gsmSCF diff --git a/mss/main/conf/cap_acn.confV2 b/mss/main/conf/cap_acn.confV2 new file mode 100644 index 0000000..4bd81c1 --- /dev/null +++ b/mss/main/conf/cap_acn.confV2 @@ -0,0 +1,8 @@ +#application context name configure file for CAP +total data length=4 + +#application context name data +No.1:50 01 // gsmSSF to gsmSCF +No.2:51 01 // assist handoff gsmSSF to gsmSCF +No.3:52 01 // gsmSRF to gsmSCF +No.4:128 01 // gsmSRF to gsmSCF diff --git a/mss/main/conf/cap_acn.confV3 b/mss/main/conf/cap_acn.confV3 new file mode 100644 index 0000000..ba8f855 --- /dev/null +++ b/mss/main/conf/cap_acn.confV3 @@ -0,0 +1,8 @@ +#application context name configure file for CAP +total data length=4 + +#application context name data +No.1:50 02 // gsmSSF to gsmSCF +No.2:51 02 // assist handoff gsmSSF to gsmSCF +No.3:52 02 // gsmSRF to gsmSCF +No.4:128 02 // gsmSRF to gsmSCF diff --git a/mss/main/conf/cap_operation.conf b/mss/main/conf/cap_operation.conf new file mode 100644 index 0000000..764ce6a --- /dev/null +++ b/mss/main/conf/cap_operation.conf @@ -0,0 +1,34 @@ +# operation code configure file for CAP +total data length=30 + +#operation code +No.1:00 02 5 // initial DP +No.2:16 02 5 // assist request instructions +No.3:17 02 20 // establish temporary connection +No.4:18 04 5 // disconnect forward connection +No.5:19 02 5 // connect to resource +No.6:20 02 5 // connect +No.7:22 04 5 // release call +No.8:23 02 5 // request report BCSM event +No.9:24 02 5 // event report BCSM +No.10:31 04 5 // continue +No.11:33 02 5 // reset timer +No.12:34 02 5 // furnish charging information +No.13:35 02 5 // apply charging +No.14:36 02 5 // apply charging report +No.15:44 02 5 // call information report +No.16:45 02 5 // call information request +No.17:46 02 5 // send charging information +No.18:47 02 60 // play announcement +No.19:48 03 60 // prompt and collect user information +No.20:49 04 5 // specialized resource report +No.21:53 02 5 // cancel +No.22:55 03 5 // activity test +No.23:60 02 5 // initial DPSMS +No.24:61 02 5 // Furnishing charging info.SMS +No.25:62 02 5 // connect DPSMS +No.26:63 02 5 // request SMS event +No.27:64 02 5 // event report SMS +No.28:65 04 5 // continue SMS +No.29:66 04 5 // release DPSMS +No.30:67 02 5 // reset timer DPSMS diff --git a/mss/main/conf/cc_table.conf b/mss/main/conf/cc_table.conf new file mode 100644 index 0000000..72da771 --- /dev/null +++ b/mss/main/conf/cc_table.conf @@ -0,0 +1,215 @@ +# Country code table configure file + +#List the country code +0086; // China +0001; // Canada & USA +0007; // Kazakhstan & Kirighzia & Kyrgyzstan & Russia & Sakhalin & Tajikistan & Uzbekistan +0020; // Egypt +0027; // South Africa +0030; // Greece +0031; // Netherlands +0036; // Hungary +0039; // Italy +0040; // Bomania +0041; // Switzerland +0042; // Czech Republic & Slovakia +0043; // Austria +0044; // United Kingdom +0045; // Denmark +0046; // Sweden +0047; // Norway +0048; // Poland +0049; // Germany +0051; // Peru +0052; // South Korea +0053; // Cuba +0054; // Argentina +0055; // Brazil +0056; // Chile +0057; // Colombia +0058; // Venezuela +0060; // Malaysia +0061; // Australia +0062; // Indonesia +0063; // Philippines +0064; // New Zealand +0065; // Singapore +0066; // Thailand +0081; // Japan +0084; // Vietnam +0090; // Turkey +0091; // India +0092; // Pakistan +0093; // Afghanistan +0094; // Sri Lanka +0095; // Myanmar (Burma) +0098; // Iran +0212; // Morocco +0213; // Algeria +0216; // Tunisia +0218; // Libya +0220; // Gambia +0221; // Senegal Republic +0222; // Mauritania +0223; // Mali Republic +0224; // Guinea +0225; // Ivory Coast +0226; // Burkina Faso +0227; // Niger +0228; // Togo +0229; // Benin +0230; // Mauritius +0231; // Liberia +0232; // Sierra Leone +0233; // Ghana +0234; // Nigeria +0235; // Chad Republic +0236; // Central Africa Republic +0237; // Cameroon +0239; // Sao Tome +0240; // Equatorial Guinea +0241; // Gabon +0242; // Congo +0243; // Zaire +0244; // Angola +0245; // Guinea Bissau +0246; // Diego Garcia +0247; // Ascension Islands +0248; // Seychelles +0249; // Sudan +0250; // Rwanda +0251; // Ethiopia +0252; // Somalia +0253; // Djibouti +0254; // Kenya +0255; // Tanzania +0256; // Uganda +0257; // Burundi +0258; // Mozambigue +0259; // Zanzibar +0260; // Zambia +0261; // Madagascar +0262; // Reunion Island +0263; // Zimbabwe +0264; // Namibia +0265; // Malawi +0266; // Lesotho +0267; // Botswana +0268; // Swaziland +0269; // Comoros +0290; // St.Helena +0291; // Eritrea +0297; // Aruba +0298; // Faeroe Islands +0299; // Greenland +#2696 // Mayotte Island +0321; // Belgium +0331; // France +0339; // Monaco +0349; // Spain +0350; // Gibraltar +0351; // Portugal +0352; // Luxembourg +0353; // Ireland +0354; // Iceland +0355; // Albania +0356; // Malta +0357; // Cyprus +0358; // Finland +0359; // Bulgaria +0370; // Lithuania +0371; // Latvia +0372; // Estonia +0373; // Moldova +0374; // Armenia +0375; // Belarus +0376; // Andorra +0380; // Ukraine +0381; // Yugoslavia +0385; // Croatia +0386; // Slovenia +0387; // Bosnia Herzegovina +0389; // Macedonia +0395; // San Marino +0396; // Vatican City +0417; // Liechtenstein +0500; // Falkland Islands +0501; // Belize +0502; // Guatemala +0503; // EI Salvador +0504; // Honduras +0505; // Nicaragua +0506; // Costa Rica +0507; // Panama +0508; // St.Pierre +0509; // Haiti +0521; // Mexico Band 1 +0522; // Mexico Band 2 +0523; // Mexico Band 3 +0524; // Mexico Band 4 +0525; // Mexico Band 5 +0526; // Mexico Band 6 +0527; // Mexico Band 7 +0528; // Mexico Band 8 +0590; // Guadeloupe +0591; // Bolivia +0592; // Ecuador & Guyana +0594; // French Guiana +0595; // Paraguay +0596; // French Antilles +0597; // Suriname +0598; // Uruguay +0599; // Netherlands Antilles +#5399 // Guantanamo Bay +0670; // Saipan +0671; // Guam +0672; // Antarctica(Casey) & Antarctica(Scott) & Christmas/Cocos +0673; // Brunei +0674; // Nauru +0675; // Papau New Guinea +0676; // Tonga +0677; // Solomon Islands +0678; // Vanuatu +0679; // Fiji Islands +0680; // Palau +0681; // Wallis/Futuna +0682; // Cook Island +0683; // Niue Island +0684; // American Samoa +0685; // West Samoa +0686; // Kiribati +0687; // New Caledonia +0688; // Tuvalu Islands +0689; // French Polynesia +0691; // Micronesia +0692; // Marshall Islands +#6723 // Norfolk Island +0787; // Puerto Rico +0809; // Anguilla & Antigua & Bahamas & Barbados & Bermuda...... +0850; // North Korea +0852; // Hong Kong +0853; // Macao +0855; // Cambodia +0856; // Laos +0868; // Trinidad/Tobago +0880; // Bangladesh +0886; // Taiwan +0960; // Maldives +0961; // Lebanon +0962; // Jordan +0963; // Syria +0964; // Iraq +0965; // Kuwait +0966; // Saudi Arabia +0967; // Yemen Arab Rep. +0968; // Oman +0971; // United Arab Emirates +0972; // Israel +0973; // Bahrain +0974; // Qatar +0975; // Bhutan +0976; // Mongolia +0977; // Nepal +0994; // Azerbaijan +0995; // Georgia + diff --git a/mss/main/conf/celp13k b/mss/main/conf/celp13k new file mode 100644 index 0000000000000000000000000000000000000000..803c71e73f7d71042c490821ae0271e8dca9ee92 GIT binary patch literal 120466 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 literal 0 HcmV?d00001 diff --git a/mss/main/conf/conv_prefix.conf b/mss/main/conf/conv_prefix.conf new file mode 100644 index 0000000000000000000000000000000000000000..94caae159559c5d4e036a512e56440070ef0b4e8 GIT binary patch literal 26048 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 literal 0 HcmV?d00001 diff --git a/mss/main/conf/ews.conf b/mss/main/conf/ews.conf new file mode 100644 index 0000000..ffb9f0c --- /dev/null +++ b/mss/main/conf/ews.conf @@ -0,0 +1,2 @@ +serverName:Embedded web server for MSS +version:10.00.00 diff --git a/mss/main/conf/ewsAdmin.conf b/mss/main/conf/ewsAdmin.conf new file mode 100644 index 0000000..b57b59a --- /dev/null +++ b/mss/main/conf/ewsAdmin.conf @@ -0,0 +1 @@ +accountmanager:YWNjb3VudG1hbmFnZXI6YWNjb3VudG1hbmFnZXI=;4;accountmanager; diff --git a/mss/main/conf/ewsDetailLeftMenu.conf b/mss/main/conf/ewsDetailLeftMenu.conf new file mode 100644 index 0000000..0763ae2 --- /dev/null +++ b/mss/main/conf/ewsDetailLeftMenu.conf @@ -0,0 +1,215 @@ + + + + + + + + + + + + + diff --git a/mss/main/conf/ewsHtml/add.gif b/mss/main/conf/ewsHtml/add.gif new file mode 100644 index 0000000000000000000000000000000000000000..6398783ca3c7660528b731f54434f35294ab7e41 GIT binary patch literal 106 zcmZ?wbhEHb6krfwSj5JludhFU{`~s-dV72O{rmSbFfjc8{~t&y{$ycfU|?g=0kVNA z1sEKd^)q(ei846#;)=%NU9(LeODT3aF!n5BtMXQ0$@zUu%uRZ=@!JbcLQ93cQWrnX Jo65pq4FJ<$BcA{O literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/alarmList_header.html b/mss/main/conf/ewsHtml/alarmList_header.html new file mode 100644 index 0000000..0af1a05 --- /dev/null +++ b/mss/main/conf/ewsHtml/alarmList_header.html @@ -0,0 +1,28 @@ + + + +

+ +  +  +
+ \ No newline at end of file diff --git a/mss/main/conf/ewsHtml/alarmNumList.html b/mss/main/conf/ewsHtml/alarmNumList.html new file mode 100644 index 0000000..07a8478 --- /dev/null +++ b/mss/main/conf/ewsHtml/alarmNumList.html @@ -0,0 +1,62 @@ + + + + + + + + +
+ + + + + + + + +
+ + + + + + + + +
+
+ + + + +
Version:
+
+
+ + diff --git a/mss/main/conf/ewsHtml/alvr_125.gif b/mss/main/conf/ewsHtml/alvr_125.gif new file mode 100644 index 0000000000000000000000000000000000000000..84e85c68c2903d5d8b210f0854646845e5ed8e6c GIT binary patch literal 2152 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 I0s%<-KR`)EO#lD@ literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/alvr_150.gif b/mss/main/conf/ewsHtml/alvr_150.gif new file mode 100644 index 0000000000000000000000000000000000000000..d261bbb10cd61da2c4a48ccaa61a9e2215f179bd GIT binary patch literal 2561 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 M6(={|69Gj39}tTHl>h($ literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/blank.gif b/mss/main/conf/ewsHtml/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..c14614406ae44d92646f85f7e0709465d3885531 GIT binary patch literal 66 zcmZ?wbhEHb6krfwSj51<#=;^bAn^C!KW0Wo7A7Vx4vzo-|1&T!=m0TLg#ZHsGk?ae UJO2z$d9L1T@%rrUcuodu0QwXX8vp + + + + + + + + +
+ Welcome enter into +
+ +
+ + diff --git a/mss/main/conf/ewsHtml/delete.gif b/mss/main/conf/ewsHtml/delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..3d5b9e2afcf8927fe6504230fd2e358af9f6028a GIT binary patch literal 82 zcmZ?wbhEHb6krfwXkcUjg8%>jEB<5wG8q|kKzxvl1CwS;f9AoSw+>U@9!XG)^Su7O g@w$uOlytonJLf+9wr##z-^$f#sqI?(;u#pM0qg1=XaE2J literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/detailTopMenu.html b/mss/main/conf/ewsHtml/detailTopMenu.html new file mode 100644 index 0000000..16c990d --- /dev/null +++ b/mss/main/conf/ewsHtml/detailTopMenu.html @@ -0,0 +1 @@ + diff --git a/mss/main/conf/ewsHtml/inDeveloping.html b/mss/main/conf/ewsHtml/inDeveloping.html new file mode 100644 index 0000000..9ae0710 --- /dev/null +++ b/mss/main/conf/ewsHtml/inDeveloping.html @@ -0,0 +1,11 @@ + + + + + + +
+ In developing +
+ + diff --git a/mss/main/conf/ewsHtml/index.html b/mss/main/conf/ewsHtml/index.html new file mode 100644 index 0000000..213f68b --- /dev/null +++ b/mss/main/conf/ewsHtml/index.html @@ -0,0 +1,20 @@ + + + +<DATA serverName> + + + + + + + + + <body> + + <p>´ËÍøÒ³Ê¹ÓÃÁË¿ò¼Ü£¬µ«ÄúµÄä¯ÀÀÆ÷²»Ö§³Ö¿ò¼Ü¡£</p> + + </body> + + + diff --git a/mss/main/conf/ewsHtml/lastblk.gif b/mss/main/conf/ewsHtml/lastblk.gif new file mode 100644 index 0000000000000000000000000000000000000000..c53326074cb100b629676512a451636cc450d913 GIT binary patch literal 85 zcmZ?wbhEHb6krfwP-0+E{K>+|z`)9&!vF*zu_hqx=-?nFAt59npsB775(fijsfblu f{uvxnSY7(%)r{@oPKF{Oo^=_k*5yoLV6X-NL{$>C literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/line.gif b/mss/main/conf/ewsHtml/line.gif new file mode 100644 index 0000000000000000000000000000000000000000..85ada3dced19ab90057a971210641865b64028ea GIT binary patch literal 83 zcmZ?wbhEHb6krfwP-0+E{K>+|z`(|!!vF*zu_hqR#=^qP$jHUPAtWHc!o&oUVqjpF g$XK=IpTQxe)uoTJB)63xRxexRKJ8Yg9Vde|0O8OOt^fc4 literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/listDetailContent.html b/mss/main/conf/ewsHtml/listDetailContent.html new file mode 100644 index 0000000..009cbfd --- /dev/null +++ b/mss/main/conf/ewsHtml/listDetailContent.html @@ -0,0 +1,23 @@ + + + + diff --git a/mss/main/conf/ewsHtml/midblk.gif b/mss/main/conf/ewsHtml/midblk.gif new file mode 100644 index 0000000000000000000000000000000000000000..2716bb39cdc524816b7512e5d193351dd1fccd68 GIT binary patch literal 87 zcmZ?wbhEHb6krfwP-0+E{K>+|z`(|!!vF*zu_hqx=-{BFpr9x(FC-wq#lZoRVqjpF k$yl}VpTQxu)v=GVW^RvfooKqmutxY-;3~H*K}-zR0CV3H)Bpeg literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/midminus.gif b/mss/main/conf/ewsHtml/midminus.gif new file mode 100644 index 0000000000000000000000000000000000000000..95469459b02a699c25c3f9548f307b4096906421 GIT binary patch literal 192 zcmZ?wbhEHb6krfwaA9Cj{K>+|z#zk*!vF*zu@)fB!o`tgNf8tspPY&&w+$ARsI#C@CQ!CL*G)swyKTrKF%BDK5^##U(B#CL}0m zY-A)YDXFZe2r?W7SZx*5yKZL8%jjaudacyFEjGe6LUStL%ZXZhuP9A@z`?}i+~WLT g!#o*}RR*fdSawfIRLT^P=x9Ie>Xvx=g#d#!092SI8UO$Q literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/midplus.gif b/mss/main/conf/ewsHtml/midplus.gif new file mode 100644 index 0000000000000000000000000000000000000000..57afafb910fca231e312beeddf26fe65369056c7 GIT binary patch literal 301 zcmZ?wbhEHb6krfw2xVYU{K>)yBpGxVfB+=c3Z$7B7#tlOq$DIngoI?JrIi#E*jQMk zrKB{})%kgOHPzMSWn~rQh2#j13LBIXR^zB_+kh%}h*~85zaJ z#MD$&bhWh&^z?MJw6rudIN8~S1Oz~K(G0M89heZ1AtBX&LM3QHjurDPUiIXi34AC0 zgu1`*a31y-`XZ|}=>co<1c??dMYYWx5@v0am!!N9J2X+$Q^b?8wUwVwP{6OpySHD_ Hk--`O(t|0l literal 0 HcmV?d00001 diff --git a/mss/main/conf/ewsHtml/singleDetailContent_header.html b/mss/main/conf/ewsHtml/singleDetailContent_header.html new file mode 100644 index 0000000..319fa12 --- /dev/null +++ b/mss/main/conf/ewsHtml/singleDetailContent_header.html @@ -0,0 +1,25 @@ + + + + + + diff --git a/mss/main/conf/ewsHtml/status_header.html b/mss/main/conf/ewsHtml/status_header.html new file mode 100644 index 0000000..d321296 --- /dev/null +++ b/mss/main/conf/ewsHtml/status_header.html @@ -0,0 +1,32 @@ + + + + + +  +  +
+ + +

Server summary information

+ + diff --git a/mss/main/conf/ewsHtml/topMenu_header.html b/mss/main/conf/ewsHtml/topMenu_header.html new file mode 100644 index 0000000..b4c51c2 --- /dev/null +++ b/mss/main/conf/ewsHtml/topMenu_header.html @@ -0,0 +1,101 @@ + + + + + +
SystemStatusAlarm descriptionRefresh time
+ + +
  + + + diff --git a/mss/main/conf/ewsHtml/userConf_header.html b/mss/main/conf/ewsHtml/userConf_header.html new file mode 100644 index 0000000..cf92eaf --- /dev/null +++ b/mss/main/conf/ewsHtml/userConf_header.html @@ -0,0 +1,93 @@ + + + + diff --git a/mss/main/conf/ewsHtml/userList_header.html b/mss/main/conf/ewsHtml/userList_header.html new file mode 100644 index 0000000..bbb4c71 --- /dev/null +++ b/mss/main/conf/ewsHtml/userList_header.html @@ -0,0 +1,38 @@ + + + + + + +
+ +Add + +
+ + + + + + + + diff --git a/mss/main/conf/ewsIndex.conf b/mss/main/conf/ewsIndex.conf new file mode 100644 index 0000000..0b70777 --- /dev/null +++ b/mss/main/conf/ewsIndex.conf @@ -0,0 +1,17 @@ +1:Status;status;1; +1.1:status;./status.html; +1.2:alarm;./alarmList.html; + +2:Configuration;param;2; +2.1:MSC;detailIndex; +2.2:VLR;detailIndex; +2.3:HLR;detailIndex; +2.4:PPS;detailIndex; +2.5:SMSC;detailIndex; +2.6:AUC;detailIndex; + +4:Peripheral;peripheral;2; +4.1:OMC-0;http://172.18.128.1;OMC-0; + +5:Template;template;4; +5.1:Admin;./userList.html; diff --git a/mss/main/conf/ewsLeftMenu.conf b/mss/main/conf/ewsLeftMenu.conf new file mode 100644 index 0000000..8e53bf5 --- /dev/null +++ b/mss/main/conf/ewsLeftMenu.conf @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + +
Account namePrivilegeReal name  
+ + +
+ +
+ + + + + + + + diff --git a/mss/main/conf/ewsSysAlarmConf.conf b/mss/main/conf/ewsSysAlarmConf.conf new file mode 100644 index 0000000..7d1766e --- /dev/null +++ b/mss/main/conf/ewsSysAlarmConf.conf @@ -0,0 +1 @@ +200;0;1;3;running time overflow; 200;0;2;3;incoming message buffer overflow for port0; 200;0;3;3;incoming message buffer overflow for port1; 200;0;4;3;incoming message buffer overflow for port2; 200;0;5;3;incoming message buffer overflow for port3; 200;0;6;3;incoming message buffer overflow for port4; 200;0;7;3;incoming message buffer overflow for port5; 200;0;8;3;incoming message buffer overflow for port6; 200;0;9;3;incoming message buffer overflow for port7; 200;0;10;3;incoming message buffer overflow for port8; 200;0;11;3;incoming message buffer overflow for port9; 200;0;12;3;incoming message buffer overflow for port10; 200;0;13;3;incoming message buffer overflow for port11; 200;0;14;3;incoming message buffer overflow for port12; 200;0;15;3;incoming message buffer overflow for port13; 200;0;16;3;incoming message buffer overflow for port14; 200;0;17;3;incoming message buffer overflow for port15; 200;0;18;3;incoming message buffer overflow for port16; 200;0;19;3;incoming message buffer overflow for port17; 200;0;20;3;incoming message buffer overflow for port18; 200;0;21;3;incoming message buffer overflow for port19; 200;0;22;3;incoming message buffer overflow for port20; 200;0;23;3;incoming message buffer overflow for port21; 200;0;24;3;incoming message buffer overflow for port22; 200;0;25;3;incoming message buffer overflow for port23; 200;0;26;3;incoming message buffer overflow for port24; 200;0;27;3;incoming message buffer overflow for port25; 200;0;28;3;incoming message buffer overflow for port26; 200;0;29;3;incoming message buffer overflow for port27; 200;0;30;3;incoming message buffer overflow for port28; 200;0;31;3;incoming message buffer overflow for port29; 200;0;32;3;incoming message buffer overflow for port30; 200;0;33;3;incoming message buffer overflow for port31; 200;0;34;3;outgoing message buffer overflow for port0; 200;0;35;3;outgoing message buffer overflow for port1; 200;0;36;3;outgoing message buffer overflow for port2; 200;0;37;3;outgoing message buffer overflow for port3; 200;0;38;3;outgoing message buffer overflow for port4; 200;0;39;3;outgoing message buffer overflow for port5; 200;0;40;3;outgoing message buffer overflow for port6; 200;0;41;3;outgoing message buffer overflow for port7; 200;0;42;3;outgoing message buffer overflow for port8; 200;0;43;3;outgoing message buffer overflow for port9; 200;0;44;3;outgoing message buffer overflow for port10; 200;0;45;3;outgoing message buffer overflow for port11; 200;0;46;3;outgoing message buffer overflow for port12; 200;0;47;3;outgoing message buffer overflow for port13; 200;0;48;3;outgoing message buffer overflow for port14; 200;0;49;3;outgoing message buffer overflow for port15; 200;0;50;3;outgoing message buffer overflow for port16; 200;0;51;3;outgoing message buffer overflow for port17; 200;0;52;3;outgoing message buffer overflow for port18; 200;0;53;3;outgoing message buffer overflow for port19; 200;0;54;3;outgoing message buffer overflow for port20; 200;0;55;3;outgoing message buffer overflow for port21; 200;0;56;3;outgoing message buffer overflow for port22; 200;0;57;3;outgoing message buffer overflow for port23; 200;0;58;3;outgoing message buffer overflow for port24; 200;0;59;3;outgoing message buffer overflow for port25; 200;0;60;3;outgoing message buffer overflow for port26; 200;0;61;3;outgoing message buffer overflow for port27; 200;0;62;3;outgoing message buffer overflow for port28; 200;0;63;3;outgoing message buffer overflow for port29; 200;0;64;3;outgoing message buffer overflow for port30; 200;0;65;3;outgoing message buffer overflow for port31; 200;0;66;3;port0 out of service; 200;0;67;3;port1 out of service; 200;0;68;3;port2 out of service; 200;0;69;3;port3 out of service; 200;0;70;3;port4 out of service; 200;0;71;3;port5 out of service; 200;0;72;3;port6 out of service; 200;0;73;3;port7 out of service; 200;0;74;3;port8 out of service; 200;0;75;3;port9 out of service; 200;0;76;3;port10 out of service; 200;0;77;3;port11 out of service; 200;0;78;3;port12 out of service; 200;0;79;3;port13 out of service; 200;0;80;3;port14 out of service; 200;0;81;3;port15 out of service; 200;0;82;3;port16 out of service; 200;0;83;3;port17 out of service; 200;0;84;3;port18 out of service; 200;0;85;3;port19 out of service; 200;0;86;3;port20 out of service; 200;0;87;3;port21 out of service; 200;0;88;3;port22 out of service; 200;0;89;3;port23 out of service; 200;0;90;3;port24 out of service; 200;0;91;3;port25 out of service; 200;0;92;3;port26 out of service; 200;0;93;3;port27 out of service; 200;0;94;3;port28 out of service; 200;0;95;3;port29 out of service; 200;0;96;3;port30 out of service; 200;0;97;3;port31 out of service; 200;0;254;1; Can not receive heartbeat; 200;1;1;3;running time overflow; 200;1;2;3;buffer for message to SCCP overflow; 200;1;3;3;buffer(for message from SCCP) overflow; 200;1;4;3;buffer(for message to TUP)overflow; 200;1;5;3;buffer(for message from TUP)overflow; 200;1;6;3;buffer(for message to ISUP)overflow; 200;1;7;3;buffer(for message from ISUP)overflow; 200;1;8;3;LinkSet0 alarm; 200;1;9;3;LinkSet1 alarm; 200;1;10;3;LinkSet2 alarm; 200;1;11;3;LinkSet3 alarm; 200;1;12;3;LinkSet4 alarm; 200;1;13;3;LinkSet5 alarm; 200;1;14;3;LinkSet6 alarm; 200;1;15;3;LinkSet7 alarm; 200;1;16;3;LinkSet8 alarm; 200;1;17;3;LinkSet9 alarm; 200;1;18;3;LinkSet10 alarm; 200;1;19;3;LinkSet11 alarm; 200;1;20;3;LinkSet12 alarm; 200;1;21;3;LinkSet13 alarm; 200;1;22;3;LinkSet14 alarm; 200;1;23;3;LinkSet15 alarm; 200;1;24;3;LinkSet16 alarm; 200;1;25;3;LinkSet17 alarm; 200;1;26;3;LinkSet18 alarm; 200;1;27;3;LinkSet19 alarm; 200;1;28;3;LinkSet20 alarm; 200;1;29;3;LinkSet21 alarm; 200;1;30;3;LinkSet22 alarm; 200;1;31;3;LinkSet23 alarm; 200;1;32;3;LinkSet24 alarm; 200;1;33;3;LinkSet25 alarm; 200;1;34;3;LinkSet26 alarm; 200;1;35;3;LinkSet27 alarm; 200;1;36;3;LinkSet28 alarm; 200;1;37;3;LinkSet29 alarm; 200;1;38;3;LinkSet30 alarm; 200;1;39;3;LinkSet31 alarm; 200;1;40;3;LinkSet32 alarm; 200;1;41;3;LinkSet33 alarm; 200;1;42;3;LinkSet34 alarm; 200;1;43;3;LinkSet35 alarm; 200;1;44;3;LinkSet36 alarm; 200;1;45;3;LinkSet37 alarm; 200;1;46;3;LinkSet38 alarm; 200;1;47;3;LinkSet39 alarm; 200;1;48;3;LinkSet40 alarm; 200;1;49;3;LinkSet41 alarm; 200;1;50;3;LinkSet42 alarm; 200;1;51;3;LinkSet43 alarm; 200;1;52;3;LinkSet44 alarm; 200;1;53;3;LinkSet45 alarm; 200;1;54;3;LinkSet46 alarm; 200;1;55;3;LinkSet47 alarm; 200;1;56;3;LinkSet48 alarm; 200;1;57;3;LinkSet49 alarm; 200;1;58;3;LinkSet50 alarm; 200;1;59;3;LinkSet51 alarm; 200;1;60;3;LinkSet52 alarm; 200;1;61;3;LinkSet53 alarm; 200;1;62;3;LinkSet54 alarm; 200;1;63;3;LinkSet55 alarm; 200;1;64;3;LinkSet56 alarm; 200;1;65;3;LinkSet57 alarm; 200;1;66;3;LinkSet58 alarm; 200;1;67;3;LinkSet59 alarm; 200;1;68;3;LinkSet60 alarm; 200;1;69;3;LinkSet61 alarm; 200;1;70;3;LinkSet62 alarm; 200;1;71;3;LinkSet63 alarm; 200;1;72;3;LinkSet64 alarm; 200;1;73;3;LinkSet65 alarm; 200;1;74;3;LinkSet66 alarm; 200;1;75;3;LinkSet67 alarm; 200;1;76;3;LinkSet68 alarm; 200;1;77;3;LinkSet69 alarm; 200;1;78;3;LinkSet70 alarm; 200;1;79;3;LinkSet71 alarm; 200;1;80;3;LinkSet72 alarm; 200;1;81;3;LinkSet73 alarm; 200;1;82;3;LinkSet74 alarm; 200;1;83;3;LinkSet75 alarm; 200;1;84;3;LinkSet76 alarm; 200;1;85;3;LinkSet77 alarm; 200;1;86;3;LinkSet78 alarm; 200;1;87;3;LinkSet79 alarm; 200;1;88;3;LinkSet80 alarm; 200;1;89;3;LinkSet81 alarm; 200;1;90;3;LinkSet82 alarm; 200;1;91;3;LinkSet83 alarm; 200;1;92;3;LinkSet84 alarm; 200;1;93;3;LinkSet85 alarm; 200;1;94;3;LinkSet86 alarm; 200;1;95;3;LinkSet87 alarm; 200;1;96;3;LinkSet88 alarm; 200;1;97;3;LinkSet89 alarm; 200;1;98;3;LinkSet90 alarm; 200;1;99;3;LinkSet91 alarm; 200;1;100;3;LinkSet92 alarm; 200;1;101;3;LinkSet93 alarm; 200;1;102;3;LinkSet94 alarm; 200;1;103;3;LinkSet95 alarm; 200;1;104;3;LinkSet96 alarm; 200;1;105;3;LinkSet97 alarm; 200;1;106;3;LinkSet98 alarm; 200;1;107;3;LinkSet99 alarm; 200;1;108;3;LinkSet100 alarm; 200;1;109;3;LinkSet101 alarm; 200;1;110;3;LinkSet102 alarm; 200;1;111;3;LinkSet103 alarm; 200;1;112;3;LinkSet104 alarm; 200;1;113;3;LinkSet105 alarm; 200;1;114;3;LinkSet106 alarm; 200;1;115;3;LinkSet107 alarm; 200;1;116;3;LinkSet108 alarm; 200;1;117;3;LinkSet109 alarm; 200;1;118;3;LinkSet110 alarm; 200;1;119;3;LinkSet111 alarm; 200;1;120;3;LinkSet112 alarm; 200;1;121;3;LinkSet113 alarm; 200;1;122;3;LinkSet114 alarm; 200;1;123;3;LinkSet115 alarm; 200;1;124;3;LinkSet116 alarm; 200;1;125;3;LinkSet117 alarm; 200;1;126;3;LinkSet118 alarm; 200;1;127;3;LinkSet119 alarm; 200;1;128;3;LinkSet120 alarm; 200;1;129;3;LinkSet121 alarm; 200;1;130;3;LinkSet122 alarm; 200;1;131;3;LinkSet123 alarm; 200;1;132;3;LinkSet124 alarm; 200;1;133;3;LinkSet125 alarm; 200;1;134;3;LinkSet126 alarm; 200;1;135;3;LinkSet127 alarm; 200;2;1;3;running time overflow; 200;2;2;3;buffer(for message to Connection UP)overflow; 200;2;3;3;buffer(for message from Connection UP)overflow; 200;2;4;3;buffer(for message to Connectness UP)overflow; 200;2;5;3;buffer(for message from Connectness UP)overflow; 200;2;6;3;failed to transfer a message; 200;3;1;3;running time overflow; 200;3;2;3;buffer(for message to Provider)overflow; 200;3;3;3;buffer(for message from Provider)overflow; 200;3;4;3;no idle dialogue ID; 200;3;5;3;no idle Transaction ID; 200;4;1;3;running time overflow; 200;5;1;3;running time overflow; 200;6;1;3;running time overflow; 200;6;2;3;no valide data source; 200;6;3;3;lost master data source; 200;8;1;3;CPU overload; 200;8;2;3;memory overload; 200;8;3;3;lack of disk space; 320;0;254;1; Can not receive heartbeat; 330;0;1;4;No ilde port id; 330;0;2;4;Not supported MAP service; 330;0;3;3;Database error; 330;0;254;1; Can not receive heartbeat; 340;0;1;1;system initialization; 340;0;2;1;Locking system service; 340;0;254;1; Can not receive heartbeat; 340;1;1;1;Loading Sims Fail; 340;1;2;5;Loading SIMs success; \ No newline at end of file diff --git a/mss/main/conf/ewsSysConf.conf b/mss/main/conf/ewsSysConf.conf new file mode 100644 index 0000000..8a5feac --- /dev/null +++ b/mss/main/conf/ewsSysConf.conf @@ -0,0 +1,6 @@ +200;PLAT;1.3.6.1.4.1.1373.1.3.2; +320;MSC;1.3.6.1.4.1.1373.1.3.3.2; +330;HLR;1.3.6.1.4.1.1373.1.3.3.3; +340;AUC;1.3.6.1.4.1.1373.1.3.3.4; +325;VLR;1.3.6.1.4.1.1373.1.3.3.2.5; +388;MSS;1.3.6.1.4.1.1373.1.3.3.16; diff --git a/mss/main/conf/fd_server.conf b/mss/main/conf/fd_server.conf new file mode 100644 index 0000000..cb58179 --- /dev/null +++ b/mss/main/conf/fd_server.conf @@ -0,0 +1,25 @@ +#Service mode 1:Server 2:Client 3:Server&Client +ServiceMod = 3; + +Identity = "test.aio-0.iwv"; + +Realm = "aio-0.iwv"; + +Port = 3868; + +SecPort = 0; + +SCTPStr = 10; + +#TLS_Cred = "./cacert.pem", +# "./cakey.pem"; +#TLS_CA = "./cacert.pem"; + +#Connect to peer. e.g ConnectPeer = "peer1.localdomain" { No_TLS; No_FWD; No_IP4; No_IP6; No_TCP; No_SCTP; Prefer_TCP; }; +#SCTP +#ConnectPeer = "a.client.com" { Realm = "client.com"; No_TLS; No_FWD; No_TCP; }; +#TCP +ConnectPeer = "a.client.com" { Realm = "client.com"; No_FWD; No_TLS; No_SCTP; Prefer_TCP; }; + +#Log levels 0:anything 1:debug 3:notice 5:error 6:fatal +LogLevel = 3; diff --git a/mss/main/conf/help_page b/mss/main/conf/help_page new file mode 100644 index 0000000..0aca6fd --- /dev/null +++ b/mss/main/conf/help_page @@ -0,0 +1,20 @@ + + ****************** + * Module PAGE * + ****************** + + Welcome to DEBUG MONITOR. + + Press 's' or 'S' to enter "SUB MODULE SELECTION PAGE". + + In "SUB MODULE SELECTION PAGE", + Press 'x' or 'X' to return "HELP PAGE", + Press 'a-p' or 'A-P' to select sub module. + + In each sub module, Press '0-9' and 'a-f' to select pages. + + There are two methods to use Debug, + 1. Serial Port, use PC-to-PC serial line. + 2. Telnet, use "telnet dst_host_ip 4965". + +$ diff --git a/mss/main/conf/hlr_parambit.conf b/mss/main/conf/hlr_parambit.conf new file mode 100644 index 0000000000000000000000000000000000000000..bef2086d49b436ff1006e9e0f1c043a6527f70c8 GIT binary patch literal 20741 zcmeI)xo+J?6vpu@Ayo<@u=+v7&A81VvBTV}hOiUci5r4pRu&#)HR%*nyBb)wt}J<> zb+wR^7kc02?M?C|CyyY1upS{0km5VQ4>%RU`A@}${|p9$Wl`efQ#mZ3$>;K=EXXlA zE?>#lazakZDfvdemDBQ_6!N|NAV11a^0WLRzshg&yZj-4%3pF;7G+7+WGd^jA)B%# z+cK}`(|J4J_@1wP?Wca`8{hiQZ~Q*+0u|^W4YI%lHgG{7dZ7w+n1)$sLL0iU3H!*4 zRHUOc$|4il$VE-m$6l;r9j9>?o7l!KZsLCE4b{*Mn_+)M9aTsBFZ#qwRHBnK$r6*; z#3fDAkGzo@=}|h$MrLHk-dK&z*pA(}UoZ>yxXZm<#R1ltzF&J{W*0`pLZAf zi8s-cbYdoUxmod6Z0ohE)ot2lt!ZuR+NM*T?$R#nOlLc{lkFH>(SgqHp}oC-_hx5y z53SCenfrV0%-mq+ls6k`BLned8bw=!S&{waBP@8EBXA);J+lZG;Swyt1eW14tiUQ< zfva#0u0sPiU=60Q4jZruThKxW+pq&S;TGJ6JJ7>jxCi&)0X&39@ED%JQ+Ni?;RU>e zU3dkr;SIcncW|I_`EV9s0Ty5Z7GMDuU;!3j0Ty5Z7C7JnAHLC}!C(iF;)SyxojMAnha>P}M)ef{zG(zr literal 0 HcmV?d00001 diff --git a/mss/main/conf/map_acn.conf b/mss/main/conf/map_acn.conf new file mode 100644 index 0000000..7e01f9f --- /dev/null +++ b/mss/main/conf/map_acn.conf @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 03 // equipment management +No.8:14 03 // info retrieval +No.9:15 03 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 03 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 03 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 03 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 03 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 03 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 03 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 03 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/mss/main/conf/map_acn_ver1.conf b/mss/main/conf/map_acn_ver1.conf new file mode 100644 index 0000000..c3949a2 --- /dev/null +++ b/mss/main/conf/map_acn_ver1.conf @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 01 // network location update +No.2:02 01 // location cancel +No.3:03 01 // roaming number enquiry +No.4:05 01 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 01 // equipment management +No.8:14 01 // info retrieval +No.9:15 01 // inter VLR info retrieval +No.10:16 01 // subscriber data management +No.11:17 03 // tracing +No.12:18 01 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 01 // short message gateway +No.15:21 01 // short message MO relay +No.16:23 01 // short message alert +No.17:24 01 // short message waiting data management +No.18:25 01 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 01 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/mss/main/conf/map_acn_ver2.conf b/mss/main/conf/map_acn_ver2.conf new file mode 100644 index 0000000..8de7612 --- /dev/null +++ b/mss/main/conf/map_acn_ver2.conf @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 02 // network location update +No.2:02 03 // location cancel +No.3:03 02 // roaming number enquiry +No.4:05 02 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 02 // subscriber data management +No.11:17 02 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 02 // short message gateway +No.15:21 02 // short message MO relay +No.16:23 02 // short message alert +No.17:24 02 // short message waiting data management +No.18:25 02 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 02 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 02 // GPRS notify +No.31:07 02 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/mss/main/conf/map_acn_ver3.conf b/mss/main/conf/map_acn_ver3.conf new file mode 100644 index 0000000..7e01f9f --- /dev/null +++ b/mss/main/conf/map_acn_ver3.conf @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 03 // equipment management +No.8:14 03 // info retrieval +No.9:15 03 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 03 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 03 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 03 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 03 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 03 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 03 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 03 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/mss/main/conf/map_operation.conf b/mss/main/conf/map_operation.conf new file mode 100644 index 0000000..58a820b --- /dev/null +++ b/mss/main/conf/map_operation.conf @@ -0,0 +1,71 @@ +# operation code configure file +total data length=67 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:128 01 20 // OPR:DetermineOprUser +No.64:129 01 20 // OPR:VlrLocationUpdate +No.65:130 01 20 // OPR:CreateUserWithMsisdnImei +No.66:131 01 20 // OPR:DeleteOprUser +No.67:132 01 20 // IMDM:VlrEnquiryIMDMStatus diff --git a/mss/main/conf/mcms_conf.txt b/mss/main/conf/mcms_conf.txt new file mode 100644 index 0000000..8d82592 --- /dev/null +++ b/mss/main/conf/mcms_conf.txt @@ -0,0 +1,2 @@ +bind ip=192.168.1.169 +shm key shift=8 diff --git a/mss/main/conf/menu_page b/mss/main/conf/menu_page new file mode 100644 index 0000000..20f0c41 --- /dev/null +++ b/mss/main/conf/menu_page @@ -0,0 +1,17 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- IPTR m -- MNP + b -- MTP3 n -- DEBUG + c -- SCCP o -- AUC + d -- TCAP p -- SMPP + e -- XAPP r -- XUA + f -- MSC s -- BICC + g -- VLR t -- MGC + h -- EIR u -- GCP + i -- HLR v -- 8ECP + j -- SMSC w -- AIF + k -- PPS y -- ISUP + l -- SNMP z -- AAS diff --git a/mss/main/conf/menu_page2 b/mss/main/conf/menu_page2 new file mode 100644 index 0000000..73f4433 --- /dev/null +++ b/mss/main/conf/menu_page2 @@ -0,0 +1,17 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- ISDN m -- TCP + b -- IIF n -- + c -- UES o -- + d -- SSF p -- + e -- MRFC r -- + f -- SIP s -- + g -- PALIM t -- + h -- RADIUS u -- + i -- RANAP v -- MEGACO + j -- OPR w -- + k -- RLS y -- + l -- MC z -- diff --git a/mss/main/conf/mhc_adjacentNodes.txt b/mss/main/conf/mhc_adjacentNodes.txt new file mode 100644 index 0000000..6ac17fa --- /dev/null +++ b/mss/main/conf/mhc_adjacentNodes.txt @@ -0,0 +1,3 @@ +Name Ip0 Ip1 +MESH0 155.226.202.78 155.226.202.79 +MESH2 155.226.202.30 155.226.202.31 diff --git a/mss/main/conf/mhc_sysParma.conf b/mss/main/conf/mhc_sysParma.conf new file mode 100644 index 0000000000000000000000000000000000000000..4bd9daf715c3dadea99a71cdfa55340aeaf098a2 GIT binary patch literal 2540 zcmZP+WMn?Ukiu{R2>(L?h?fF{zOKO@x)ufuPziR1K?4{EjY|f?A+sNy3It&WU@$=9 z$PB|75OHG+acTB4yLqAZ@=TS QZ!m?+s9W&G)PTzY0CXE87ytkO literal 0 HcmV?d00001 diff --git a/mss/main/conf/mnpf.conf b/mss/main/conf/mnpf.conf new file mode 100644 index 0000000000000000000000000000000000000000..b4149be6d00fd1ef56cbee1d36d70ccdb58af198 GIT binary patch literal 6344 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 z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$YP#Q`@X($b)p){0+(oh;oLun`trJ*#GhSE?PN<(QV4W*$pl!nq! z8cIWHC=I2dG?a$7NgA#_2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N r0t5&UAn+~~XgmlIAV7cs0RjXF5FkK+009C72oNAZfB=DapTPeEQO%(g literal 0 HcmV?d00001 diff --git a/mss/main/conf/msc_conf.tgz b/mss/main/conf/msc_conf.tgz new file mode 100644 index 0000000000000000000000000000000000000000..1d2600fba688fff8f719e405f5b969ac65ba069a GIT binary patch literal 15875 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 literal 0 HcmV?d00001 diff --git a/mss/main/conf/msc_cua.conf b/mss/main/conf/msc_cua.conf new file mode 100644 index 0000000..538cbf9 --- /dev/null +++ b/mss/main/conf/msc_cua.conf @@ -0,0 +1,390 @@ +#MSC CUA Config File +[CUA-1] +id=1 +timestamp=946829620 +title=CUA-1 +aas_prefix=***8 +ann_cause-0=0 +ann_type-0=0 +#ann_code-0=0 +ann_cause-1=0 +ann_type-1=0 +ann_code-1=0 +ann_cause-2=0 +ann_type-2=0 +#ann_code-2=03 +ann_cause-3=0 +ann_type-3=0 +ann_code-3=03 +ann_cause-4=0 +ann_type-4=0 +#ann_code-4=0 +ann_cause-5=0 +ann_type-5=0 +#ann_code-5=5 +ann_cause-6=0 +ann_type-6=0 +ann_code-6=03 +ann_cause-7=0 +ann_type-7=0 +#ann_code-7=0 +ann_cause-8=0 +ann_type-8=0 +ann_code-8=06 +ann_cause-9=0 +ann_type-9=0 +#ann_code-9=0 +ann_cause-10=0 +ann_type-10=0 +#ann_code-10=0 +ann_cause-11=0 +ann_type-11=0 +#ann_code-11=0 +ann_cause-12=0 +ann_type-12=0 +#ann_code-12=0 +ann_cause-13=0 +ann_type-13=0 +#ann_code-13=0 +ann_cause-14=0 +ann_type-14=0 +#ann_code-14=0 +ann_cause-15=0 +ann_type-15=0 +#ann_code-15=0 +ann_cause-16=0 +ann_type-16=0 +#ann_code-16=0 +ann_cause-17=0 +ann_type-17=0 +ann_code-17=02 +ann_cause-18=0 +ann_type-18=0 +ann_code-18=07 +ann_cause-19=0 +ann_type-19=0 +ann_code-19=12 +ann_cause-20=0 +ann_type-20=0 +ann_code-20=07 +ann_cause-21=0 +ann_type-21=0 +ann_code-21=05 +ann_cause-22=0 +ann_type-22=0 +#ann_code-22=0 +ann_cause-23=0 +ann_type-23=0 +#ann_code-23=0 +ann_cause-24=0 +ann_type-24=0 +#ann_code-24=0 +ann_cause-25=0 +ann_type-25=0 +#ann_code-25=0 +ann_cause-26=0 +ann_type-26=0 +#ann_code-26=0 +ann_cause-27=0 +ann_type-27=0 +ann_code-27=03 +ann_cause-28=0 +ann_type-28=0 +ann_code-28=0 +ann_cause-29=0 +ann_type-29=0 +#ann_code-29=0 +ann_cause-30=0 +ann_type-30=0 +#ann_code-30=0 +ann_cause-31=0 +ann_type-31=0 +#ann_code-31=0 +ann_cause-32=0 +ann_type-32=0 +#ann_code-32=0 +ann_cause-33=0 +ann_type-33=0 +#ann_code-33=0 +ann_cause-34=0 +ann_type-34=0 +ann_code-34=03 +ann_cause-35=0 +ann_type-35=0 +#ann_code-35=0 +ann_cause-36=0 +ann_type-36=0 +#ann_code-36=0 +ann_cause-37=0 +ann_type-37=0 +#ann_code-37=0 +ann_cause-38=0 +ann_type-38=0 +ann_code-38=03 +ann_cause-39=0 +ann_type-39=0 +#ann_code-39=0 +ann_cause-40=0 +ann_type-40=0 +#ann_code-40=0 +ann_cause-41=0 +ann_type-41=0 +ann_code-41=03 +ann_cause-42=0 +ann_type-42=0 +ann_code-42=03 +ann_cause-43=0 +ann_type-43=0 +#ann_code-43=0 +ann_cause-44=0 +ann_type-44=0 +ann_code-44=03 +ann_cause-45=0 +ann_type-45=0 +#ann_code-45=0 +ann_cause-46=0 +ann_type-46=0 +#ann_code-46=0 +ann_cause-47=0 +ann_type-47=0 +#ann_code-47=0 +ann_cause-48=0 +ann_type-48=0 +#ann_code-48=0 +ann_cause-49=0 +ann_type-49=0 +#ann_code-49=0 +ann_cause-50=0 +ann_type-50=0 +#ann_code-50=0 +ann_cause-51=0 +ann_type-51=0 +#ann_code-51=0 +ann_cause-52=0 +ann_type-52=0 +#ann_code-52=0 +ann_cause-53=0 +ann_type-53=0 +#ann_code-53=0 +ann_cause-54=0 +ann_type-54=0 +#ann_code-54=0 +ann_cause-55=0 +ann_type-55=0 +#ann_code-55=0 +ann_cause-56=0 +ann_type-56=0 +#ann_code-56=0 +ann_cause-57=0 +ann_type-57=0 +#ann_code-57=0 +ann_cause-58=0 +ann_type-58=0 +ann_code-58=8 +ann_cause-59=0 +ann_type-59=0 +#ann_code-59=0 +ann_cause-60=0 +ann_type-60=0 +#ann_code-60=0 +ann_cause-61=0 +ann_type-61=0 +#ann_code-61=0 +ann_cause-62=0 +ann_type-62=0 +#ann_code-62=0 +ann_cause-63=0 +ann_type-63=0 +#ann_code-63=0 +ann_cause-64=0 +ann_type-64=0 +#ann_code-64=0 +ann_cause-65=0 +ann_type-65=0 +#ann_code-65=0 +ann_cause-66=0 +ann_type-66=0 +#ann_code-66=0 +ann_cause-67=0 +ann_type-67=0 +#ann_code-67=0 +ann_cause-68=0 +ann_type-68=0 +#ann_code-68=0 +ann_cause-69=0 +ann_type-69=0 +#ann_code-69=0 +ann_cause-70=0 +ann_type-70=0 +#ann_code-70=0 +ann_cause-71=0 +ann_type-71=0 +#ann_code-71=0 +ann_cause-72=0 +ann_type-72=0 +#ann_code-72=0 +ann_cause-73=0 +ann_type-73=0 +#ann_code-73=0 +ann_cause-74=0 +ann_type-74=0 +#ann_code-74=0 +ann_cause-75=0 +ann_type-75=0 +#ann_code-75=0 +ann_cause-76=0 +ann_type-76=0 +#ann_code-76=0 +ann_cause-77=0 +ann_type-77=0 +#ann_code-77=0 +ann_cause-78=0 +ann_type-78=0 +#ann_code-78=0 +ann_cause-79=0 +ann_type-79=0 +#ann_code-79=0 +ann_cause-80=0 +ann_type-80=0 +#ann_code-80=0 +ann_cause-81=0 +ann_type-81=0 +#ann_code-81=0 +ann_cause-82=0 +ann_type-82=0 +#ann_code-82=0 +ann_cause-83=0 +ann_type-83=0 +#ann_code-83=0 +ann_cause-84=0 +ann_type-84=0 +#ann_code-84=0 +ann_cause-85=0 +ann_type-85=0 +#ann_code-85=0 +ann_cause-86=0 +ann_type-86=0 +#ann_code-86=0 +ann_cause-87=0 +ann_type-87=0 +#ann_code-87=0 +ann_cause-88=0 +ann_type-88=0 +#ann_code-88=0 +ann_cause-89=0 +ann_type-89=0 +#ann_code-89=0 +ann_cause-90=0 +ann_type-90=0 +#ann_code-90=0 +ann_cause-91=0 +ann_type-91=0 +#ann_code-91=0 +ann_cause-92=0 +ann_type-92=0 +#ann_code-92=0 +ann_cause-93=0 +ann_type-93=0 +#ann_code-93=0 +ann_cause-94=0 +ann_type-94=0 +#ann_code-94=0 +ann_cause-95=0 +ann_type-95=0 +#ann_code-95=0 +ann_cause-96=0 +ann_type-96=0 +#ann_code-96=0 +ann_cause-97=0 +ann_type-97=0 +#ann_code-97=0 +ann_cause-98=0 +ann_type-98=0 +#ann_code-98=0 +ann_cause-99=0 +ann_type-99=0 +#ann_code-99=0 +ann_cause-100=0 +ann_type-100=0 +#ann_code-100=0 +ann_cause-101=0 +ann_type-101=0 +#ann_code-101=0 +ann_cause-102=0 +ann_type-102=0 +#ann_code-102=0 +ann_cause-103=0 +ann_type-103=0 +#ann_code-103=0 +ann_cause-104=0 +ann_type-104=0 +#ann_code-104=0 +ann_cause-105=0 +ann_type-105=0 +#ann_code-105=0 +ann_cause-106=0 +ann_type-106=0 +#ann_code-106=0 +ann_cause-107=0 +ann_type-107=0 +#ann_code-107=0 +ann_cause-108=0 +ann_type-108=0 +#ann_code-108=0 +ann_cause-109=0 +ann_type-109=0 +#ann_code-109=0 +ann_cause-110=0 +ann_type-110=0 +#ann_code-110=0 +ann_cause-111=0 +ann_type-111=0 +#ann_code-111=0 +ann_cause-112=0 +ann_type-112=0 +#ann_code-112=0 +ann_cause-113=0 +ann_type-113=0 +#ann_code-113=0 +ann_cause-114=0 +ann_type-114=0 +#ann_code-114=0 +ann_cause-115=0 +ann_type-115=0 +#ann_code-115=0 +ann_cause-116=0 +ann_type-116=0 +#ann_code-116=0 +ann_cause-117=0 +ann_type-117=0 +#ann_code-117=0 +ann_cause-118=0 +ann_type-118=0 +#ann_code-118=0 +ann_cause-119=0 +ann_type-119=0 +#ann_code-119=0 +ann_cause-120=0 +ann_type-120=0 +#ann_code-120=0 +ann_cause-121=0 +ann_type-121=0 +#ann_code-121=0 +ann_cause-122=0 +ann_type-122=0 +#ann_code-122=0 +ann_cause-123=0 +ann_type-123=0 +#ann_code-123=0 +ann_cause-124=0 +ann_type-124=0 +#ann_code-124=0 +ann_cause-125=0 +ann_type-125=0 +#ann_code-125=0 +ann_cause-126=0 +ann_type-126=0 +#ann_code-126=0 +ann_cause-127=0 +ann_type-127=0 +#ann_code-127=0 diff --git a/mss/main/conf/msc_dps.conf b/mss/main/conf/msc_dps.conf new file mode 100644 index 0000000..15f9e13 --- /dev/null +++ b/mss/main/conf/msc_dps.conf @@ -0,0 +1,739 @@ +#MSC DPS Config File +[HS-1] +id=1 +timestamp=1184323661 +title=HS-1 +cc=86 +ndc=755 +int_prefix=00 +nat_prefix=0 +hplmn_cc-0= +hplmn_cc-1= +hplmn_cc-2= +hplmn_cc-3= +hplmn_cc-4= +hplmn_cc-5= +hplmn_cc-6= +hplmn_cc-7= +npa_nxx= +total_nap=24 +[NA-1] +id=1 +timestamp=1184323661 +title=2G_Local +method=0 +prefix=86755 +start= +end= +attrib=4 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=0 +rsc=0 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=32 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=105 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-2] +id=2 +timestamp=1184500781 +title=zoiper +method=0 +prefix=697559 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=17 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-3] +id=3 +timestamp=1188328309 +title=msrn +method=0 +prefix=8675572 +start= +end= +attrib=4 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=1 +rsc=12 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-4] +id=4 +timestamp=1099347878 +title=3G_local +method=0 +prefix=667559 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=0 +rsc=0 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-5] +id=5 +timestamp=1330564354 +title=emergency_call +method=0 +prefix=596696 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=14 +cli_type=0 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-6] +id=6 +timestamp=1099348110 +title=isdn-isdn +method=0 +prefix=01867559 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=10 +cli_type=0 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=4 +pstn_insert=66 +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-7] +id=7 +timestamp=1240998683 +title=roam +method=0 +prefix=863778 +start= +end= +attrib=4 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=7 +cli_type=5 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-8] +id=8 +timestamp=1192716878 +title=aas +method=0 +prefix=** +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=2 +cli_type=2 +cdr_enable=0 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=2 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-9] +id=9 +timestamp=1276273042 +title=local_ndd +method=0 +prefix=8675590 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=0 +rsc=12 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-10] +id=10 +timestamp=1276795208 +title=VMS-79 +method=0 +prefix=8675592002 +start= +end= +attrib=4 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=13 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-11] +id=11 +timestamp=1276794523 +title=PPS +method=0 +prefix=555 +start= +end= +attrib=2 +called_len=0 +serv_type=2 +emergency_type=0 +service_key=0 +num_type=0 +rsc=2 +cli_type=0 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=2 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-12] +id=12 +timestamp=1276799450 +title=SRF-0 +method=0 +prefix=86755920013 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=2 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-13] +id=13 +timestamp=1276879395 +title=SRF-1 +method=0 +prefix=86755920014 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=3 +cli_type=0 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-14] +id=14 +timestamp=1277202768 +title=PPS +method=0 +prefix=333 +start= +end= +attrib=2 +called_len=0 +serv_type=2 +emergency_type=0 +service_key=0 +num_type=0 +rsc=2 +cli_type=0 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=2 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-15] +id=15 +timestamp=1331240106 +title=x100_pstn +method=0 +prefix=00596696 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=14 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=2 +pstn_insert= +e164_nai=0 +e164_delete=2 +e164_insert= +admin_state=1 +[NA-16] +id=16 +timestamp=1278608532 +title=emergence +method=0 +prefix=112 +start= +end= +attrib=2 +called_len=0 +serv_type=1 +emergency_type=0 +service_key=1 +num_type=0 +rsc=0 +cli_type=0 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert=0 +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-17] +id=17 +timestamp=1278608618 +title=emergence +method=0 +prefix=123 +start= +end= +attrib=2 +called_len=0 +serv_type=1 +emergency_type=1 +service_key=0 +num_type=0 +rsc=0 +cli_type=0 +cdr_enable=0 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=2 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-18] +id=18 +timestamp=1204900204 +title=3G_sip_sip +method=0 +prefix=186755 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=12 +cli_type=2 +cdr_enable=0 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=1 +pstn_insert= +e164_nai=0 +e164_delete=1 +e164_insert= +admin_state=1 +[NA-19] +id=19 +timestamp=1288195867 +title=wxc1_isdn +method=0 +prefix=336 +start= +end= +attrib=4 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=8 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-20] +id=20 +timestamp=1205754550 +title=3G_Local +method=0 +prefix=667559 +start= +end= +attrib=4 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=0 +rsc=0 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-21] +id=21 +timestamp=1329327845 +title=2G_sip_sip +method=0 +prefix=286755 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=12 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=1 +pstn_insert= +e164_nai=0 +e164_delete=1 +e164_insert= +admin_state=1 +[NA-22] +id=22 +timestamp=1206722492 +title=isup_out +method=0 +prefix=596696 +start= +end= +attrib=4 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=14 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 +[NA-26] +id=26 +timestamp=1214837414 +title=Local +method=0 +prefix=90 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=0 +rsc=1 +cli_type=2 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=0 +pstn_insert= +e164_nai=0 +e164_delete=0 +e164_insert=86755 +admin_state=1 +[NA-28] +id=28 +timestamp=1216742366 +title=bicc-bicc +method=0 +prefix=0867559 +start= +end= +attrib=2 +called_len=0 +serv_type=0 +emergency_type=0 +service_key=0 +num_type=2 +rsc=11 +cli_type=0 +cdr_enable=1 +mnp_flag=0 +mnp_mo_option=0 +mnp_mt_option=0 +premium_call=0 +osb1=0 +osb2=0 +pstn_nai=4 +pstn_delete=3 +pstn_insert=69 +e164_nai=0 +e164_delete=0 +e164_insert= +admin_state=1 diff --git a/mss/main/conf/msc_la.conf b/mss/main/conf/msc_la.conf new file mode 100644 index 0000000..00c8fd9 --- /dev/null +++ b/mss/main/conf/msc_la.conf @@ -0,0 +1,263 @@ +#MSC LA Config File +[LA-1] +id=1 +timestamp=1240233332 +title=IPBSS-70 +lac=136 +tg_id=55 +page_type=0 +page_again=3 +nitz=068643A4B365B301000000000000000000000000000000000000000000000000000000FF +em_num-0= +em_num-1=86755900112 +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +total_cell=1 +[Cell-1] +timestamp=1332198100 +title=No title +ci=0 +rz_id=0 +rszi=65535 +latitude=0 +longitude=0 +tg_id=0 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[LA-2] +id=2 +timestamp=1275998984 +title=IPAccess +lac=4 +tg_id=10 +page_type=0 +page_again=0 +nitz=0080000000000000000000000000000000000000000000000000000000000000000000FF +em_num-0=596696000086 +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +total_cell=1 +[Cell-1] +timestamp=1325870242 +title=No title +ci=4 +rz_id=1 +rszi=65535 +latitude=0 +longitude=0 +tg_id=0 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[LA-3] +id=3 +timestamp=1275999055 +title=IPAccess +lac=3 +tg_id=10 +page_type=0 +page_again=0 +nitz=0080000000000000000000000000000000000000000000000000000000000000000000FF +em_num-0=596696000086 +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +total_cell=1 +[Cell-1] +timestamp=1275999078 +title=cell1 +ci=3 +rz_id=1 +rszi=65535 +latitude=0 +longitude=0 +tg_id=0 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[LA-4] +id=4 +timestamp=1325599433 +title=HNBGW-17 +lac=4386 +tg_id=4 +page_type=0 +page_again=3 +nitz=0686341BAC95CB0100000000000000000000000000000000000000000000000000020000 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +total_cell=1 +[Cell-1] +timestamp=1325599452 +title=HNBGW +ci=100 +rz_id=1 +rszi=65535 +latitude=0 +longitude=0 +tg_id=0 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[LA-5] +id=5 +timestamp=1293209780 +title=VBSC-57 +lac=2 +tg_id=0 +page_type=0 +page_again=1 +nitz=0000000000000000000000000000000000000000000000000000000000000000000000FF +em_num-0=596696000086 +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +total_cell=3 +[Cell-1] +timestamp=1294925511 +title=cell2 +ci=2 +rz_id=1 +rszi=65535 +latitude=0 +longitude=0 +tg_id=0 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[Cell-2] +timestamp=1294925521 +title=cell3 +ci=3 +rz_id=1 +rszi=65535 +latitude=0 +longitude=0 +tg_id=0 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[Cell-3] +timestamp=1294925549 +title=cell4 +ci=4 +rz_id=1 +rszi=65535 +latitude=0 +longitude=0 +tg_id=0 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[LA-6] +id=6 +timestamp=1325613024 +title=3G_CN_test +lac=1 +tg_id=15 +page_type=0 +page_again=1 +nitz=008000000000000000000000000000000000000000000000000000000000000000022000 +em_num-0=596696000086 +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +total_cell=1 +[Cell-2] +timestamp=1332198999 +title=HNBGW-31 +ci=1 +rz_id=1 +rszi=65535 +latitude=0 +longitude=0 +tg_id=15 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +[LA-7] +id=7 +timestamp=1332887274 +title=WXBSPlus +lac=9911 +tg_id=6 +page_type=0 +page_again=1 +nitz=000000000000000000000000000000000000000000000000000000000000000000000000 +em_num-0= +em_num-1= +em_num-2= +em_num-3= +em_num-4= +em_num-5= +em_num-6= +em_num-7= +total_cell=0 diff --git a/mss/main/conf/msc_mg.conf b/mss/main/conf/msc_mg.conf new file mode 100644 index 0000000..5947bcc --- /dev/null +++ b/mss/main/conf/msc_mg.conf @@ -0,0 +1,353 @@ +#MSC MG Config File +[MG-1] +id=1 +timestamp=1290613788 +title=AAS-0 +ip=172.25.197.88 +domain=AAS-0 +switch_mode=0 +endpoint_descrip=1 +tone_gen=1 +mg_type=21 +max_port=1 +max_chan=32 +packetization=20 +priority=0 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-2] +id=2 +timestamp=1295520730 +title=UPE-85 +ip=172.25.201.168 +domain=172.25.201.168 +switch_mode=0 +endpoint_descrip=1 +tone_gen=0 +mg_type=3 +max_port=32 +max_chan=32 +packetization=20 +priority=0 +codec-0=3 +codec-1=2 +codec-2=12 +codec-3=0 +codec-4=1 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-3] +id=3 +timestamp=1325612754 +title=UBTS +ip=172.25.192.27 +domain=172.25.192.27 +switch_mode=0 +endpoint_descrip=1 +tone_gen=0 +mg_type=1 +max_port=4 +max_chan=32 +packetization=20 +priority=0 +codec-0=4 +codec-1=10 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-4] +id=4 +timestamp=1310810342 +title=AC_85 +ip=172.25.196.85 +domain=172.25.196.85 +switch_mode=0 +endpoint_descrip=1 +tone_gen=0 +mg_type=1 +max_port=2 +max_chan=32 +packetization=20 +priority=0 +codec-0=4 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-5] +id=5 +timestamp=1282355652 +title=IPBSS-70 +ip=172.25.196.70 +domain=172.25.196.70 +switch_mode=0 +endpoint_descrip=1 +tone_gen=0 +mg_type=4 +max_port=1 +max_chan=32 +packetization=20 +priority=0 +codec-0=3 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-6] +id=6 +timestamp=1275998847 +title=IPAccess-48 +ip=172.25.192.48 +domain=mgw +switch_mode=0 +endpoint_descrip=3 +tone_gen=0 +mg_type=4 +max_port=2 +max_chan=32 +packetization=20 +priority=0 +codec-0=12 +codec-1=4 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=10 +admin_state=1 +[MG-7] +id=7 +timestamp=1299167227 +title=Tandem-87 +ip=172.25.196.87 +domain=rtpproxy-1 +switch_mode=0 +endpoint_descrip=2 +tone_gen=0 +mg_type=20 +max_port=8 +max_chan=32 +packetization=20 +priority=0 +codec-0=4 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-8] +id=8 +timestamp=1330987777 +title=AAS-1 +ip=172.25.197.89 +domain=AAS-1 +switch_mode=0 +endpoint_descrip=1 +tone_gen=1 +mg_type=21 +max_port=1 +max_chan=32 +packetization=20 +priority=0 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-12] +id=12 +timestamp=1192030207 +title=iuupGW-86 +ip=192.168.1.124 +domain=192.168.1.124 +switch_mode=2 +endpoint_descrip=1 +tone_gen=0 +mg_type=23 +max_port=2 +max_chan=32 +packetization=20 +priority=0 +codec-0=4 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-22] +id=22 +timestamp=1245422842 +title=CSS +ip=172.25.196.72 +domain=172.25.196.72 +switch_mode=0 +endpoint_descrip=1 +tone_gen=0 +mg_type=3 +max_port=8 +max_chan=32 +packetization=20 +priority=0 +codec-0=3 +codec-1=2 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 +[MG-80] +id=80 +timestamp=1329792167 +title=AC-UBSC +ip=172.25.192.85 +domain=172.25.192.85 +switch_mode=0 +endpoint_descrip=1 +tone_gen=0 +mg_type=1 +max_port=2 +max_chan=32 +packetization=20 +priority=0 +codec-0=4 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +audit_timer=0 +admin_state=1 diff --git a/mss/main/conf/msc_rzs.conf b/mss/main/conf/msc_rzs.conf new file mode 100644 index 0000000..fd763fb --- /dev/null +++ b/mss/main/conf/msc_rzs.conf @@ -0,0 +1,202 @@ +#MSC RZS Config File +[RZ-1] +id=1 +timestamp=1184323487 +title=RZ-1 +hs_id=1 +cua_id=1 +msrn_start= +msrn_end= +srf_num_1= +srf_num_2= +total_route=19 +[RS-1] +id=1 +timestamp=1184323570 +title=Route-1 +tg_id=1 +atg_id=0 +atg_option=0 +nai=4 +delete=0 +insert= +[RS-2] +id=2 +timestamp=1192716709 +title=Route-2 +tg_id=122 +atg_id=123 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-3] +id=3 +timestamp=1192716782 +title=Route-3 +tg_id=123 +atg_id=122 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-4] +id=4 +timestamp=1194222707 +title=Route-4 +tg_id=24 +atg_id=0 +atg_option=0 +nai=2 +delete=0 +insert= +[RS-5] +id=5 +timestamp=1195169923 +title=Route-5 +tg_id=3 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-6] +id=6 +timestamp=1204900087 +title=Route-6 +tg_id=28 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-7] +id=7 +timestamp=1206553746 +title=Route-7 +tg_id=29 +atg_id=0 +atg_option=0 +nai=4 +delete=0 +insert= +[RS-8] +id=8 +timestamp=1207134337 +title=Route-8 +tg_id=13 +atg_id=0 +atg_option=0 +nai=2 +delete=0 +insert= +[RS-9] +id=9 +timestamp=1228469019 +title=Route-9 +tg_id=12 +atg_id=0 +atg_option=0 +nai=2 +delete=0 +insert= +[RS-10] +id=10 +timestamp=1228469113 +title=Route-10 +tg_id=7 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-11] +id=11 +timestamp=1229694100 +title=Route-11 +tg_id=8 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-12] +id=12 +timestamp=1276274526 +title=Route-12 +tg_id=12 +atg_id=0 +atg_option=0 +nai=3 +delete=0 +insert= +[RS-13] +id=13 +timestamp=1276794568 +title=VMS-79 +tg_id=11 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-14] +id=14 +timestamp=1288194599 +title=Route-14 +tg_id=14 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-15] +id=15 +timestamp=1288194611 +title=Route-15 +tg_id=51 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-16] +id=16 +timestamp=1305299432 +title=Route-16 +tg_id=55 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-17] +id=17 +timestamp=1329401538 +title=Route-17 +tg_id=16 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-30] +id=30 +timestamp=1334898812 +title=Route-30 +tg_id=30 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= +[RS-31] +id=31 +timestamp=1334898830 +title=Route-31 +tg_id=31 +atg_id=0 +atg_option=0 +nai=0 +delete=0 +insert= diff --git a/mss/main/conf/msc_system.conf b/mss/main/conf/msc_system.conf new file mode 100644 index 0000000..2d89802 --- /dev/null +++ b/mss/main/conf/msc_system.conf @@ -0,0 +1,13 @@ +#MSC System Config File +cdr_option=65535 +mo_tick=0 +mt_tick=0 +loc_num= +bw_call_ind=0 +sus_timer=0 +emlpp_pci_option=0 +emlpp_pvi_option=0 +conn_tone=0 +etc_split_num_ind=0 +page_timer=15 +assign_timer=99 diff --git a/mss/main/conf/msc_tg.conf b/mss/main/conf/msc_tg.conf new file mode 100644 index 0000000..ac02176 --- /dev/null +++ b/mss/main/conf/msc_tg.conf @@ -0,0 +1,3546 @@ +#MSC TG Config File +[TG-1] +id=1 +timestamp=1237828323 +title=Intercept +opc=0 +dpc=0 +nw_ind=2 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1332199771 +title=Trunk-1 +mg_id=0 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-2] +id=2 +timestamp=1295520628 +title=UPE-85 +opc=512 +dpc=272 +nw_ind=1 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=0 +[Trk-1] +id=1 +timestamp=1295520665 +title=Trunk-1 +mg_id=2 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-3] +id=3 +timestamp=1268208383 +title=es51_182 +opc=12 +dpc=11 +nw_ind=0 +proto=1 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=0 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=0 +[Trk-1] +id=1 +timestamp=1268208486 +title=Trunk-1 +mg_id=28 +port_id=1 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-4] +id=4 +timestamp=1325096620 +title=HNBGW-17 +opc=1000 +dpc=17 +nw_ind=2 +proto=8 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=0 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=2 +codec-0=12 +codec-1=4 +codec-2=11 +codec-3=2 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=0 +[Trk-1] +id=1 +timestamp=1325597551 +title=Trunk-1 +mg_id=12 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[Trk-2] +id=2 +timestamp=1325787751 +title=Trunk-2 +mg_id=9 +port_id=0 +port_type=0 +supervision=0 +group=1 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-5] +id=5 +timestamp=1098543425 +title=CCS +opc=1000 +dpc=2001 +nw_ind=2 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=1 +tandem_restrict=1 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=8 +codec-0=3 +codec-1=2 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=0 +[Trk-1] +id=1 +timestamp=1098543491 +title=Trunk-1 +mg_id=22 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[Trk-2] +id=2 +timestamp=1247830708 +title=Trunk-2 +mg_id=22 +port_id=1 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=32 +admin_state=1 +ts_type-0=0 +ts_value-0=32 +ts_type-1=3 +ts_value-1=33 +ts_type-2=3 +ts_value-2=34 +ts_type-3=3 +ts_value-3=35 +ts_type-4=3 +ts_value-4=36 +ts_type-5=3 +ts_value-5=37 +ts_type-6=3 +ts_value-6=38 +ts_type-7=3 +ts_value-7=39 +ts_type-8=3 +ts_value-8=40 +ts_type-9=3 +ts_value-9=41 +ts_type-10=3 +ts_value-10=42 +ts_type-11=3 +ts_value-11=43 +ts_type-12=3 +ts_value-12=44 +ts_type-13=3 +ts_value-13=45 +ts_type-14=3 +ts_value-14=46 +ts_type-15=3 +ts_value-15=47 +ts_type-16=5 +ts_value-16=48 +ts_type-17=3 +ts_value-17=49 +ts_type-18=3 +ts_value-18=50 +ts_type-19=3 +ts_value-19=51 +ts_type-20=3 +ts_value-20=52 +ts_type-21=3 +ts_value-21=53 +ts_type-22=3 +ts_value-22=54 +ts_type-23=3 +ts_value-23=55 +ts_type-24=3 +ts_value-24=56 +ts_type-25=3 +ts_value-25=57 +ts_type-26=3 +ts_value-26=58 +ts_type-27=3 +ts_value-27=59 +ts_type-28=3 +ts_value-28=60 +ts_type-29=3 +ts_value-29=61 +ts_type-30=3 +ts_value-30=62 +ts_type-31=3 +ts_value-31=63 +[Trk-3] +id=3 +timestamp=1247830759 +title=Trunk-3 +mg_id=22 +port_id=2 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=64 +admin_state=1 +ts_type-0=0 +ts_value-0=64 +ts_type-1=3 +ts_value-1=65 +ts_type-2=3 +ts_value-2=66 +ts_type-3=3 +ts_value-3=67 +ts_type-4=3 +ts_value-4=68 +ts_type-5=3 +ts_value-5=69 +ts_type-6=3 +ts_value-6=70 +ts_type-7=3 +ts_value-7=71 +ts_type-8=3 +ts_value-8=72 +ts_type-9=3 +ts_value-9=73 +ts_type-10=3 +ts_value-10=74 +ts_type-11=3 +ts_value-11=75 +ts_type-12=3 +ts_value-12=76 +ts_type-13=3 +ts_value-13=77 +ts_type-14=3 +ts_value-14=78 +ts_type-15=3 +ts_value-15=79 +ts_type-16=5 +ts_value-16=80 +ts_type-17=3 +ts_value-17=81 +ts_type-18=3 +ts_value-18=82 +ts_type-19=3 +ts_value-19=83 +ts_type-20=3 +ts_value-20=84 +ts_type-21=3 +ts_value-21=85 +ts_type-22=3 +ts_value-22=86 +ts_type-23=3 +ts_value-23=87 +ts_type-24=3 +ts_value-24=88 +ts_type-25=3 +ts_value-25=89 +ts_type-26=3 +ts_value-26=90 +ts_type-27=3 +ts_value-27=91 +ts_type-28=3 +ts_value-28=92 +ts_type-29=3 +ts_value-29=93 +ts_type-30=3 +ts_value-30=94 +ts_type-31=3 +ts_value-31=95 +[Trk-4] +id=4 +timestamp=1247830787 +title=Trunk-4 +mg_id=22 +port_id=3 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=96 +admin_state=1 +ts_type-0=0 +ts_value-0=96 +ts_type-1=3 +ts_value-1=97 +ts_type-2=3 +ts_value-2=98 +ts_type-3=3 +ts_value-3=99 +ts_type-4=3 +ts_value-4=100 +ts_type-5=3 +ts_value-5=101 +ts_type-6=3 +ts_value-6=102 +ts_type-7=3 +ts_value-7=103 +ts_type-8=3 +ts_value-8=104 +ts_type-9=3 +ts_value-9=105 +ts_type-10=3 +ts_value-10=106 +ts_type-11=3 +ts_value-11=107 +ts_type-12=3 +ts_value-12=108 +ts_type-13=3 +ts_value-13=109 +ts_type-14=3 +ts_value-14=110 +ts_type-15=3 +ts_value-15=111 +ts_type-16=5 +ts_value-16=112 +ts_type-17=3 +ts_value-17=113 +ts_type-18=3 +ts_value-18=114 +ts_type-19=3 +ts_value-19=115 +ts_type-20=3 +ts_value-20=116 +ts_type-21=3 +ts_value-21=117 +ts_type-22=3 +ts_value-22=118 +ts_type-23=3 +ts_value-23=119 +ts_type-24=3 +ts_value-24=120 +ts_type-25=3 +ts_value-25=121 +ts_type-26=3 +ts_value-26=122 +ts_type-27=3 +ts_value-27=123 +ts_type-28=3 +ts_value-28=124 +ts_type-29=3 +ts_value-29=125 +ts_type-30=3 +ts_value-30=126 +ts_type-31=3 +ts_value-31=127 +[Trk-5] +id=5 +timestamp=1247830817 +title=Trunk-5 +mg_id=22 +port_id=4 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=128 +admin_state=1 +ts_type-0=0 +ts_value-0=128 +ts_type-1=3 +ts_value-1=129 +ts_type-2=3 +ts_value-2=130 +ts_type-3=3 +ts_value-3=131 +ts_type-4=3 +ts_value-4=132 +ts_type-5=3 +ts_value-5=133 +ts_type-6=3 +ts_value-6=134 +ts_type-7=3 +ts_value-7=135 +ts_type-8=3 +ts_value-8=136 +ts_type-9=3 +ts_value-9=137 +ts_type-10=3 +ts_value-10=138 +ts_type-11=3 +ts_value-11=139 +ts_type-12=3 +ts_value-12=140 +ts_type-13=3 +ts_value-13=141 +ts_type-14=3 +ts_value-14=142 +ts_type-15=3 +ts_value-15=143 +ts_type-16=5 +ts_value-16=144 +ts_type-17=3 +ts_value-17=145 +ts_type-18=3 +ts_value-18=146 +ts_type-19=3 +ts_value-19=147 +ts_type-20=3 +ts_value-20=148 +ts_type-21=3 +ts_value-21=149 +ts_type-22=3 +ts_value-22=150 +ts_type-23=3 +ts_value-23=151 +ts_type-24=3 +ts_value-24=152 +ts_type-25=3 +ts_value-25=153 +ts_type-26=3 +ts_value-26=154 +ts_type-27=3 +ts_value-27=155 +ts_type-28=3 +ts_value-28=156 +ts_type-29=3 +ts_value-29=157 +ts_type-30=3 +ts_value-30=158 +ts_type-31=3 +ts_value-31=159 +[Trk-6] +id=6 +timestamp=1247830863 +title=Trunk-6 +mg_id=22 +port_id=5 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=160 +admin_state=1 +ts_type-0=0 +ts_value-0=160 +ts_type-1=3 +ts_value-1=161 +ts_type-2=3 +ts_value-2=162 +ts_type-3=3 +ts_value-3=163 +ts_type-4=3 +ts_value-4=164 +ts_type-5=3 +ts_value-5=165 +ts_type-6=3 +ts_value-6=166 +ts_type-7=3 +ts_value-7=167 +ts_type-8=3 +ts_value-8=168 +ts_type-9=3 +ts_value-9=169 +ts_type-10=3 +ts_value-10=170 +ts_type-11=3 +ts_value-11=171 +ts_type-12=3 +ts_value-12=172 +ts_type-13=3 +ts_value-13=173 +ts_type-14=3 +ts_value-14=174 +ts_type-15=3 +ts_value-15=175 +ts_type-16=5 +ts_value-16=176 +ts_type-17=3 +ts_value-17=177 +ts_type-18=3 +ts_value-18=178 +ts_type-19=3 +ts_value-19=179 +ts_type-20=3 +ts_value-20=180 +ts_type-21=3 +ts_value-21=181 +ts_type-22=3 +ts_value-22=182 +ts_type-23=3 +ts_value-23=183 +ts_type-24=3 +ts_value-24=184 +ts_type-25=3 +ts_value-25=185 +ts_type-26=3 +ts_value-26=186 +ts_type-27=3 +ts_value-27=187 +ts_type-28=3 +ts_value-28=188 +ts_type-29=3 +ts_value-29=189 +ts_type-30=3 +ts_value-30=190 +ts_type-31=3 +ts_value-31=191 +[Trk-7] +id=7 +timestamp=1247830909 +title=Trunk-7 +mg_id=22 +port_id=6 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=192 +admin_state=1 +ts_type-0=0 +ts_value-0=192 +ts_type-1=3 +ts_value-1=193 +ts_type-2=3 +ts_value-2=194 +ts_type-3=3 +ts_value-3=195 +ts_type-4=3 +ts_value-4=196 +ts_type-5=3 +ts_value-5=197 +ts_type-6=3 +ts_value-6=198 +ts_type-7=3 +ts_value-7=199 +ts_type-8=3 +ts_value-8=200 +ts_type-9=3 +ts_value-9=201 +ts_type-10=3 +ts_value-10=202 +ts_type-11=3 +ts_value-11=203 +ts_type-12=3 +ts_value-12=204 +ts_type-13=3 +ts_value-13=205 +ts_type-14=3 +ts_value-14=206 +ts_type-15=3 +ts_value-15=207 +ts_type-16=5 +ts_value-16=208 +ts_type-17=3 +ts_value-17=209 +ts_type-18=3 +ts_value-18=210 +ts_type-19=3 +ts_value-19=211 +ts_type-20=3 +ts_value-20=212 +ts_type-21=3 +ts_value-21=213 +ts_type-22=3 +ts_value-22=214 +ts_type-23=3 +ts_value-23=215 +ts_type-24=3 +ts_value-24=216 +ts_type-25=3 +ts_value-25=217 +ts_type-26=3 +ts_value-26=218 +ts_type-27=3 +ts_value-27=219 +ts_type-28=3 +ts_value-28=220 +ts_type-29=3 +ts_value-29=221 +ts_type-30=3 +ts_value-30=222 +ts_type-31=3 +ts_value-31=223 +[Trk-8] +id=8 +timestamp=1247830953 +title=Trunk-8 +mg_id=22 +port_id=7 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=224 +admin_state=1 +ts_type-0=0 +ts_value-0=224 +ts_type-1=3 +ts_value-1=225 +ts_type-2=3 +ts_value-2=226 +ts_type-3=3 +ts_value-3=227 +ts_type-4=3 +ts_value-4=228 +ts_type-5=3 +ts_value-5=229 +ts_type-6=3 +ts_value-6=230 +ts_type-7=3 +ts_value-7=231 +ts_type-8=3 +ts_value-8=232 +ts_type-9=3 +ts_value-9=233 +ts_type-10=3 +ts_value-10=234 +ts_type-11=3 +ts_value-11=235 +ts_type-12=3 +ts_value-12=236 +ts_type-13=3 +ts_value-13=237 +ts_type-14=3 +ts_value-14=238 +ts_type-15=3 +ts_value-15=239 +ts_type-16=5 +ts_value-16=240 +ts_type-17=3 +ts_value-17=241 +ts_type-18=3 +ts_value-18=242 +ts_type-19=3 +ts_value-19=243 +ts_type-20=3 +ts_value-20=244 +ts_type-21=3 +ts_value-21=245 +ts_type-22=3 +ts_value-22=246 +ts_type-23=3 +ts_value-23=247 +ts_type-24=3 +ts_value-24=248 +ts_type-25=3 +ts_value-25=249 +ts_type-26=3 +ts_value-26=250 +ts_type-27=3 +ts_value-27=251 +ts_type-28=3 +ts_value-28=252 +ts_type-29=3 +ts_value-29=253 +ts_type-30=3 +ts_value-30=254 +ts_type-31=3 +ts_value-31=255 +[TG-6] +id=6 +timestamp=1325612874 +title=WXBTS +opc=1000 +dpc=4000 +nw_ind=2 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=3 +codec-1=2 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1325612975 +title=Trunk-1 +mg_id=3 +port_id=2 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-7] +id=7 +timestamp=1227194887 +title=TG_ISDN +opc=0 +dpc=0 +nw_ind=1 +proto=3 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=129 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=0 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=0 +[TG-8] +id=8 +timestamp=1228466591 +title=TG-BICC +opc=80 +dpc=64 +nw_ind=3 +proto=2 +extend_proto=0 +variant=0 +local_domain=0 +dest_domain=0 +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=0 +[Trk-1] +id=1 +timestamp=1228466598 +title=Trunk-1 +mg_id=0 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-9] +id=9 +timestamp=1272322304 +title=VBSC-57 +opc=1000 +dpc=1 +nw_ind=2 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=2 +codec-0=2 +codec-1=12 +codec-2=3 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1272322343 +title=Trunk-1 +mg_id=4 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[Trk-2] +id=2 +timestamp=1325604831 +title=Trunk-2 +mg_id=4 +port_id=1 +port_type=0 +supervision=0 +group=1 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=32 +admin_state=1 +ts_type-0=0 +ts_value-0=32 +ts_type-1=3 +ts_value-1=33 +ts_type-2=3 +ts_value-2=34 +ts_type-3=3 +ts_value-3=35 +ts_type-4=3 +ts_value-4=36 +ts_type-5=3 +ts_value-5=37 +ts_type-6=3 +ts_value-6=38 +ts_type-7=3 +ts_value-7=39 +ts_type-8=3 +ts_value-8=40 +ts_type-9=3 +ts_value-9=41 +ts_type-10=3 +ts_value-10=42 +ts_type-11=3 +ts_value-11=43 +ts_type-12=3 +ts_value-12=44 +ts_type-13=3 +ts_value-13=45 +ts_type-14=3 +ts_value-14=46 +ts_type-15=3 +ts_value-15=47 +ts_type-16=5 +ts_value-16=48 +ts_type-17=3 +ts_value-17=49 +ts_type-18=3 +ts_value-18=50 +ts_type-19=3 +ts_value-19=51 +ts_type-20=3 +ts_value-20=52 +ts_type-21=3 +ts_value-21=53 +ts_type-22=3 +ts_value-22=54 +ts_type-23=3 +ts_value-23=55 +ts_type-24=3 +ts_value-24=56 +ts_type-25=3 +ts_value-25=57 +ts_type-26=3 +ts_value-26=58 +ts_type-27=3 +ts_value-27=59 +ts_type-28=3 +ts_value-28=60 +ts_type-29=3 +ts_value-29=61 +ts_type-30=3 +ts_value-30=62 +ts_type-31=3 +ts_value-31=63 +[TG-10] +id=10 +timestamp=1284551008 +title=ipaccess_48 +opc=1000 +dpc=2000 +nw_ind=2 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=12 +codec-1=4 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1284551072 +title=Trunk-1 +mg_id=6 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-11] +id=11 +timestamp=1276793315 +title=VMS-79 +opc=1000 +dpc=48 +nw_ind=2 +proto=2 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=2 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1276794314 +title=Trunk-1 +mg_id=0 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=3 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=3 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[Trk-2] +id=2 +timestamp=1325761450 +title=Trunk-2 +mg_id=0 +port_id=1 +port_type=0 +supervision=0 +group=1 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=32 +admin_state=1 +ts_type-0=3 +ts_value-0=32 +ts_type-1=3 +ts_value-1=33 +ts_type-2=3 +ts_value-2=34 +ts_type-3=3 +ts_value-3=35 +ts_type-4=3 +ts_value-4=36 +ts_type-5=3 +ts_value-5=37 +ts_type-6=3 +ts_value-6=38 +ts_type-7=3 +ts_value-7=39 +ts_type-8=3 +ts_value-8=40 +ts_type-9=3 +ts_value-9=41 +ts_type-10=3 +ts_value-10=42 +ts_type-11=3 +ts_value-11=43 +ts_type-12=3 +ts_value-12=44 +ts_type-13=3 +ts_value-13=45 +ts_type-14=3 +ts_value-14=46 +ts_type-15=3 +ts_value-15=47 +ts_type-16=3 +ts_value-16=48 +ts_type-17=3 +ts_value-17=49 +ts_type-18=3 +ts_value-18=50 +ts_type-19=3 +ts_value-19=51 +ts_type-20=3 +ts_value-20=52 +ts_type-21=3 +ts_value-21=53 +ts_type-22=3 +ts_value-22=54 +ts_type-23=3 +ts_value-23=55 +ts_type-24=3 +ts_value-24=56 +ts_type-25=3 +ts_value-25=57 +ts_type-26=3 +ts_value-26=58 +ts_type-27=3 +ts_value-27=59 +ts_type-28=3 +ts_value-28=60 +ts_type-29=3 +ts_value-29=61 +ts_type-30=3 +ts_value-30=62 +ts_type-31=3 +ts_value-31=63 +[TG-12] +id=12 +timestamp=1325698611 +title=TG-SIP +opc=0 +dpc=0 +nw_ind=2 +proto=5 +extend_proto=0 +variant=0 +local_domain=172.25.196.78 +dest_domain=172.25.196.88 +dest_ip=172.25.196.88 +dest_ip_1=0.0.0.0 +dest_port=5060 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=0 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[TG-13] +id=13 +timestamp=1325760011 +title=wxc1 +opc=842 +dpc=32 +nw_ind=3 +proto=1 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=1 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1325760074 +title=Trunk-1 +mg_id=3 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=0 +ts_value-0=0 +ts_type-1=5 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=3 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-14] +id=14 +timestamp=1325774950 +title=R8.2 +opc=1000 +dpc=8148 +nw_ind=2 +proto=1 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=2 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1325775021 +title=Trunk-1 +mg_id=3 +port_id=1 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[Trk-2] +id=2 +timestamp=1325776277 +title=Trunk-2 +mg_id=3 +port_id=3 +port_type=0 +supervision=0 +group=1 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=32 +admin_state=1 +ts_type-0=0 +ts_value-0=32 +ts_type-1=3 +ts_value-1=33 +ts_type-2=3 +ts_value-2=34 +ts_type-3=3 +ts_value-3=35 +ts_type-4=3 +ts_value-4=36 +ts_type-5=3 +ts_value-5=37 +ts_type-6=3 +ts_value-6=38 +ts_type-7=3 +ts_value-7=39 +ts_type-8=3 +ts_value-8=40 +ts_type-9=3 +ts_value-9=41 +ts_type-10=3 +ts_value-10=42 +ts_type-11=3 +ts_value-11=43 +ts_type-12=3 +ts_value-12=44 +ts_type-13=3 +ts_value-13=45 +ts_type-14=3 +ts_value-14=46 +ts_type-15=3 +ts_value-15=47 +ts_type-16=5 +ts_value-16=48 +ts_type-17=3 +ts_value-17=49 +ts_type-18=3 +ts_value-18=50 +ts_type-19=3 +ts_value-19=51 +ts_type-20=3 +ts_value-20=52 +ts_type-21=3 +ts_value-21=53 +ts_type-22=3 +ts_value-22=54 +ts_type-23=3 +ts_value-23=55 +ts_type-24=3 +ts_value-24=56 +ts_type-25=3 +ts_value-25=57 +ts_type-26=3 +ts_value-26=58 +ts_type-27=3 +ts_value-27=59 +ts_type-28=3 +ts_value-28=60 +ts_type-29=3 +ts_value-29=61 +ts_type-30=3 +ts_value-30=62 +ts_type-31=3 +ts_value-31=63 +[TG-15] +id=15 +timestamp=1326104479 +title=HNBGW-31 +opc=1000 +dpc=5000 +nw_ind=2 +proto=8 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1326104520 +title=Trunk-1 +mg_id=12 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-16] +id=16 +timestamp=1329400164 +title=TG-sip-zoiper +opc=0 +dpc=0 +nw_ind=0 +proto=5 +extend_proto=0 +variant=0 +local_domain=172.25.196.78 +dest_domain=172.25.201.132 +dest_ip=172.25.201.132 +dest_ip_1=0.0.0.0 +dest_port=5060 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=0 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[TG-29] +id=29 +timestamp=1206547308 +title=es51_182 +opc=12 +dpc=11 +nw_ind=0 +proto=1 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=129 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=0 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=0 +[TG-30] +id=30 +timestamp=1214407970 +title=Loop-MSS-0 +opc=126 +dpc=127 +nw_ind=2 +proto=2 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=16 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1325698419 +title=Trunk-1 +mg_id=0 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=3 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=3 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-31] +id=31 +timestamp=1214408396 +title=Loop-MSS-1 +opc=127 +dpc=126 +nw_ind=2 +proto=2 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=17 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1325698483 +title=Trunk-1 +mg_id=0 +port_id=0 +port_type=0 +supervision=0 +group=1 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=3 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=3 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-55] +id=55 +timestamp=1213374537 +title=IPBSS-70 +opc=1000 +dpc=77 +nw_ind=2 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=3 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1305298728 +title=Trunk-1 +mg_id=5 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-80] +id=80 +timestamp=1329792240 +title=UBSC +opc=1000 +dpc=1515 +nw_ind=2 +proto=0 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=1 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=2 +codec-0=3 +codec-1=2 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1329792291 +title=Trunk-1 +mg_id=80 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=0 +ts_type-0=0 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=5 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[Trk-2] +id=2 +timestamp=1329792308 +title=Trunk-2 +mg_id=80 +port_id=1 +port_type=0 +supervision=0 +group=1 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=32 +admin_state=0 +ts_type-0=0 +ts_value-0=32 +ts_type-1=3 +ts_value-1=33 +ts_type-2=3 +ts_value-2=34 +ts_type-3=3 +ts_value-3=35 +ts_type-4=3 +ts_value-4=36 +ts_type-5=3 +ts_value-5=37 +ts_type-6=3 +ts_value-6=38 +ts_type-7=3 +ts_value-7=39 +ts_type-8=3 +ts_value-8=40 +ts_type-9=3 +ts_value-9=41 +ts_type-10=3 +ts_value-10=42 +ts_type-11=3 +ts_value-11=43 +ts_type-12=3 +ts_value-12=44 +ts_type-13=3 +ts_value-13=45 +ts_type-14=3 +ts_value-14=46 +ts_type-15=3 +ts_value-15=47 +ts_type-16=5 +ts_value-16=48 +ts_type-17=3 +ts_value-17=49 +ts_type-18=3 +ts_value-18=50 +ts_type-19=3 +ts_value-19=51 +ts_type-20=3 +ts_value-20=52 +ts_type-21=3 +ts_value-21=53 +ts_type-22=3 +ts_value-22=54 +ts_type-23=3 +ts_value-23=55 +ts_type-24=3 +ts_value-24=56 +ts_type-25=3 +ts_value-25=57 +ts_type-26=3 +ts_value-26=58 +ts_type-27=3 +ts_value-27=59 +ts_type-28=3 +ts_value-28=60 +ts_type-29=3 +ts_value-29=61 +ts_type-30=3 +ts_value-30=62 +ts_type-31=3 +ts_value-31=63 +[TG-122] +id=122 +timestamp=1210251074 +title=AAS-0 +opc=122 +dpc=123 +nw_ind=2 +proto=2 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=0 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1326115364 +title=Trunk-1 +mg_id=0 +port_id=0 +port_type=0 +supervision=0 +group=0 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=3 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=3 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 +[TG-123] +id=123 +timestamp=1216310309 +title=AAS-1 +opc=124 +dpc=125 +nw_ind=2 +proto=2 +extend_proto=0 +variant=0 +local_domain= +dest_domain= +dest_ip=0.0.0.0 +dest_ip_1=0.0.0.0 +dest_port=0 +remote_proc_isup=0 +assume_incoming_sip_nai=0 +cs_mode=0 +backoff=0 +tandem_restrict=0 +cdr_enable=1 +tg_type=0 +rz_id=1 +arz_id=0 +ignore_np=0 +signal_ported=0 +nfas=0 +primary_chnl=0 +backup_chnl=0 +total_trk=1 +codec-0=255 +codec-1=255 +codec-2=255 +codec-3=255 +codec-4=255 +codec-5=255 +codec-6=255 +codec-7=255 +codec-8=255 +codec-9=255 +codec-10=255 +codec-11=255 +codec-12=255 +codec-13=255 +codec-14=255 +codec-15=255 +ec_ind=0 +sat_ind=0 +admin_state=1 +[Trk-1] +id=1 +timestamp=1326115387 +title=Trunk-1 +mg_id=0 +port_id=0 +port_type=0 +supervision=0 +group=1 +link_id=0 +usr_net_if=0 +cic_plan=0 +min_cicval=0 +admin_state=1 +ts_type-0=3 +ts_value-0=0 +ts_type-1=3 +ts_value-1=1 +ts_type-2=3 +ts_value-2=2 +ts_type-3=3 +ts_value-3=3 +ts_type-4=3 +ts_value-4=4 +ts_type-5=3 +ts_value-5=5 +ts_type-6=3 +ts_value-6=6 +ts_type-7=3 +ts_value-7=7 +ts_type-8=3 +ts_value-8=8 +ts_type-9=3 +ts_value-9=9 +ts_type-10=3 +ts_value-10=10 +ts_type-11=3 +ts_value-11=11 +ts_type-12=3 +ts_value-12=12 +ts_type-13=3 +ts_value-13=13 +ts_type-14=3 +ts_value-14=14 +ts_type-15=3 +ts_value-15=15 +ts_type-16=3 +ts_value-16=16 +ts_type-17=3 +ts_value-17=17 +ts_type-18=3 +ts_value-18=18 +ts_type-19=3 +ts_value-19=19 +ts_type-20=3 +ts_value-20=20 +ts_type-21=3 +ts_value-21=21 +ts_type-22=3 +ts_value-22=22 +ts_type-23=3 +ts_value-23=23 +ts_type-24=3 +ts_value-24=24 +ts_type-25=3 +ts_value-25=25 +ts_type-26=3 +ts_value-26=26 +ts_type-27=3 +ts_value-27=27 +ts_type-28=3 +ts_value-28=28 +ts_type-29=3 +ts_value-29=29 +ts_type-30=3 +ts_value-30=30 +ts_type-31=3 +ts_value-31=31 diff --git a/mss/main/conf/mtp3.conf b/mss/main/conf/mtp3.conf new file mode 100644 index 0000000..ac4bbe1 --- /dev/null +++ b/mss/main/conf/mtp3.conf @@ -0,0 +1,52 @@ +#MTP3 CONFIGURE FILE + +[system] +mtp3litePort=8813 + +[internationalNetworkRouting] +opc=00000c +pclen=1 +pctype=1 +localACN=030303030202020202030302020303020303020303030303030303030303030302020202 +#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn] + +[internationalSpareNetworkRouting] +opc=000200 +pclen=0 +pctype=0 +localACN=030303030202020202030302020303020303020303030303030303030303030302020202 +#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn] +[ 0.UPE_85.000110.000000.0002.0200.00000000.030303030202020202030302020303020303020303030303030303030303030302020202] + +[nationalNetworkRouting] +opc=0003E8 +pclen=0 +pctype=0 +localACN=030303030202020202030302020303020303020303030303030303030303030302020202 +#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn] +[ 1.SGSN.0000CC.000000.0001.0200.00000000.000000000202020202030302020303020303020303030303030303030303030302020202] +[ 2.HNBGW.001388.000000.0002.0200.00000000.030303030202020202030302020303020303020303030303030303030303030302020202] + +[nationalSpareNetworkRouting] +opc=00034a +pclen=0 +pctype=0 +localACN=030303030202020202030302020303020303020303030303030303030303030302020202 +#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn] +[ 0.wxc1.000020.000000.0007.0200.00000000.030303030202020202030302020303020303020303030303030303030303030302020202] + +[linkset] +#[index.title.admin.nw.dpc.loop_flag.opc] +[ 1.SGSN.01.02.0000CC.00.000000] +[ 2.HNBGW.01.02.001388.00.000000] + +[link] +#[index.title.admin.type.linkset.slc.hostIP.alterIP.sg.iid.mtp3lite_mode.mtp3lite_remoteIP.inactive.inactive_times] +[ 1.SGSN.01.04.0001.00.7E01A8C0.00000000.0001.00.00.00000000.ff.ff] +[ 2.HNBGW.01.04.0002.00.7E01A8C0.00000000.0002.00.00.00000000.ff.ff] + +[signalingGateway] +#[index.admin.server.data_ack.sgIP.clientSourceIP.clientSourcePort] +[ 1.01.01.04.8201A8C0.00000000.0000] +[ 2.01.01.04.8001A8C0.00000000.0000] + diff --git a/mss/main/conf/oprConf.txt b/mss/main/conf/oprConf.txt new file mode 100644 index 0000000000000000000000000000000000000000..d884b33ab738734caa286d60902ff0d480bed36d GIT binary patch literal 6188 zcmeI#K?=e!5CzbQC&>|#Kx_-HyA-cbG>f7&QiAO*ypx`(dxr`p(t_Z!{((RyKMCaR zlCLvs3!{{>RB~me)Ra{I&drxx&*sThL_&;1ZsV#Li+j#)_hGYp5Owaf_l=Xm%d-oe zZ;x^R0%weZf&c^{009U<00Izz00bZaf#nJmnqHsl + 1 + 88 + PALIM_LAC_OUT + 4.6.0 + 8.8.15 + 0 + + 9 + 1 + + + + 2 + 134 + PALIM_LAC_OUT + 4.6.0 + 6.6.15 + 0 + + 2 + 1 + + + + 3 + 9208 + PALIM_LAC_OUT + 6.3.7 + 1.9.15 + 0 + + 6000 + 1 + + diff --git a/mss/main/conf/palim_mg.config b/mss/main/conf/palim_mg.config new file mode 100644 index 0000000..5dcc72a --- /dev/null +++ b/mss/main/conf/palim_mg.config @@ -0,0 +1,37 @@ + + 1 + MG-1 + MGC_USER_TYPE_MGC + MG_CTL_PALIM + locked + + 0 + MGC_MG_TYPE_INTERNAL + MGC_MG_CTRL_TYPE_MGCP + 0 + 0 + 0 + 0 + 255.255.255.255 + Error:NoSuchInstance + 0 + 0 + 16 + UNSUPPORT + PCMA + PCMA + PCMA + PCMA + UNSUPPORT + PCMA + PCMA + UNSUPPORT + UNSUPPORT + UNSUPPORT + AMR_7_95 + UNSUPPORT + UNSUPPORT + UNSUPPORT + UNSUPPORT + + diff --git a/mss/main/conf/palim_sys.config b/mss/main/conf/palim_sys.config new file mode 100644 index 0000000..2710f76 --- /dev/null +++ b/mss/main/conf/palim_sys.config @@ -0,0 +1,34 @@ + + 4.6.0 + 8.8.15 + 10000 + 10000 + PALIM_ROUTE_REMOTE + PALIM_ROUTE_REMOTE + ENABLE + DISABLE + DISABLE + DISABLE + DISABLE + 1234 + + + + + + + + 86377800384 + + + 86377800073 + + + + + 86377820005 + 50000 + 65535 + useless + plmn_not_allowed + diff --git a/mss/main/conf/palim_tg.config b/mss/main/conf/palim_tg.config new file mode 100644 index 0000000..e69de29 diff --git a/mss/main/conf/palim_user.config b/mss/main/conf/palim_user.config new file mode 100644 index 0000000..cbda255 --- /dev/null +++ b/mss/main/conf/palim_user.config @@ -0,0 +1,44 @@ + + 460029000000384 + + 86377800384 + + 4.6.0 + 8.8.15 + 88 + 9 + hybrid + + + 460029000000001 + + + 8675590001 + 0.0.0 + 0.0.0 + 65535 + 65535 + private + + + 460029000000063 + + + 86755900063 + 0.0.0 + 0.0.0 + 65535 + 65535 + private + + + 111111111111111 + + + 000000000000000 + 0.0.0 + 0.0.0 + 65535 + 65535 + private + diff --git a/mss/main/conf/ppsConf.txt b/mss/main/conf/ppsConf.txt new file mode 100644 index 0000000000000000000000000000000000000000..3ff0239720ac958860cd0e2541735219977c6569 GIT binary patch literal 430769 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 P0|pEjFkrxdf&YO4C^7&6 literal 0 HcmV?d00001 diff --git a/mss/main/conf/profile b/mss/main/conf/profile new file mode 100644 index 0000000..de17bc9 --- /dev/null +++ b/mss/main/conf/profile @@ -0,0 +1,37 @@ +# /etc/profile + +# System wide environment and startup programs +# Functions and aliases go in /etc/bashrc + +PATH=".:$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/etc/rc.d/init.d:/usr/local/wxc2/bin" +PATH=/usr/java/jdk1.3/bin:$PATH + +ulimit -c 80000 +if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then + umask 002 +else + umask 022 +fi + +USER=`id -un` +LOGNAME=$USER +MAIL="/var/spool/mail/$USER" + +HOSTNAME=`/bin/hostname` +HISTSIZE=1000 + +if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then + INPUTRC=/etc/inputrc +fi +JAVA_COMPILER=javacomp ; export JAVA_COMPILER +LD_LIBRARY_PATH=/usr/local/mysql/lib ; export LD_LIBRARY_PATH +export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC + +for i in /etc/profile.d/*.sh ; do + if [ -x $i ]; then + . $i + fi +done + +unset i +PATH=/usr/local/wxc2/bin:$PATH diff --git a/mss/main/conf/rls_mg.conf b/mss/main/conf/rls_mg.conf new file mode 100644 index 0000000..0a0617b --- /dev/null +++ b/mss/main/conf/rls_mg.conf @@ -0,0 +1 @@ +#RLS MG Config File diff --git a/mss/main/conf/rls_rz.conf b/mss/main/conf/rls_rz.conf new file mode 100644 index 0000000..633125f --- /dev/null +++ b/mss/main/conf/rls_rz.conf @@ -0,0 +1,33 @@ +#RLS RZ Config File +#index site(1:remote, 0:local) +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 0 diff --git a/mss/main/conf/rls_sys.conf b/mss/main/conf/rls_sys.conf new file mode 100644 index 0000000..d5d4574 --- /dev/null +++ b/mss/main/conf/rls_sys.conf @@ -0,0 +1,2 @@ +#RLS System Config File +rls_flag=0 diff --git a/mss/main/conf/sccp.conf b/mss/main/conf/sccp.conf new file mode 100644 index 0000000..611b640 --- /dev/null +++ b/mss/main/conf/sccp.conf @@ -0,0 +1,43 @@ +#SCCP Config file (R1V0_01) + +[Local Node] +#ssn NetID msisdn ip0 ip1 acn_index +4 2 - 192.168.1.126 10.0.0.0 0 +6 2 86755800001 192.168.1.126 10.0.0.0 0 +7 2 86755800002 192.168.1.126 10.0.0.0 0 +8 2 86755800003 192.168.1.126 10.0.0.0 0 +9 2 86755800004 192.168.1.126 10.0.0.0 0 +10 2 86755800005 192.168.1.126 10.0.0.0 0 +11 2 86755800000 192.168.1.126 10.0.0.0 0 +19 2 86755800007 192.168.1.126 10.0.0.0 0 +20 2 86755800008 192.168.1.126 10.0.0.0 0 +22 2 86755800009 192.168.1.126 10.0.0.0 0 +23 2 86755800010 192.168.1.126 10.0.0.0 0 +32 2 86755800011 192.168.1.126 10.0.0.0 0 +33 2 86755800012 192.168.1.126 10.0.0.0 0 +142 2 86755800013 192.168.1.126 10.0.0.0 0 +146 2 86755800014 192.168.1.126 10.0.0.0 0 +147 2 86755800015 192.168.1.126 10.0.0.0 0 +149 2 86755800016 192.168.1.126 0.0.0.0 0 +153 2 86755800017 192.168.1.126 10.0.0.0 0 +254 2 - 192.168.1.126 10.0.0.0 0 + +[GTT_Table] +#No EN NP TT StartDigits EndDigits NI SPC SSN RI AI S E N Rep ACN_index +0 1 6 - 460990010001001 460990010009999 2 0003E8 6 0 6 0 +1 1 1 - 86755900000 86755909999 2 0003E8 6 0 6 0 +2 1 1 - 66755920067 66755920067 2 0000cc 0 0 6 0 + +[RL_SSN] +#NetID DPC SSN + +[GTT_ATTRIBUTE] +Idx + 0 0000000000000000000000000000000000000000000000000000000000000000 +1 0000000000000000000000000000000000000000000000000000000000000000 +2 0000000000000000000000000000000000000000000000000000000000000000 + +[ACN_VERSION] + #No avail 37bytes +0 1 03030303020203030303030202030303030303030303030303030303030303030303030307 +1 1 03030303020202020203030202020202020202030303030303030303030303030202020207 diff --git a/mss/main/conf/shm.conf b/mss/main/conf/shm.conf new file mode 100644 index 0000000..b15b4bb --- /dev/null +++ b/mss/main/conf/shm.conf @@ -0,0 +1,57 @@ +#------------------------------Server paramter----------------------------# + + +#Server Type (0=OMC 1=FUNCTION SERVER) +ServerType=1 + + +#Server ID ( 0=master 1=slave) +ServerID=0 + +#IP Info (OMC0 OMC1 for omc server, SERVER0 and SERVER1 for function server) +OMC0=172.18.128.1 +OMC1=172.18.129.1 +SERVER0=172.18.98.1 +SERVER1=172.18.99.1 + +#------------------------------Share Memory List(MAX=10)-------------------# + +# ID KEY PERM SIZE USR INTTLP INITRP REALP PERIODP REALIP PERIODICIP +* 11 12000000 436 16384 AUC 4957 4957 4972 4972 239.255.4.1 239.255.4.1 +* 12 12040000 436 16384 EIR 4957 4957 4974 4974 239.255.6.1 239.255.6.1 +* 13 45000001 436 33985 HLR 4957 4957 4970 4970 239.255.2.1 239.255.2.1 +* 24 90000000 436 32768 VLR 4957 4957 4973 4973 239.255.5.1 239.255.5.1 +* 5 05020000 436 22528 PPS 4957 4957 4971 4971 239.255.3.1 239.255.3.1 + +#------------------------DataBase info (only used for OMC MAX=10)- ---------# +# HOSTNAME PASSWORD USER DBNAME +<1> localhost rootaa root HlrDb +<2> localhost rootaa root parameter_db +<3> localhost rootaa root account_db +<4> localhost rootaa root tariff_db +<5> localhost rootaa root refresh_card +<6> localhost rootaa root AUC_Para +<7> localhost rootaa root VlrDb +<8> localhost rootaa root EIR_Para + +#-------------------------MIBS Config Files---------------------------------# +PATH:./conf/mibs/ + + +#MIB List +[1] IWV-SMI.txt +[2] WAVEII-SMI.txt +[3] WAVEII-DATASYNC-MIB.txt +[4] WAVEII-AUC-MIB.txt +[5] WAVEII-EIR-MIB.txt +[6] WAVEII-HLR-MIB.txt +[7] WAVEII-MSC-MIB.txt +[8] WAVEII-PPS-MIB.txt + +#ProcedureID(>=0) +#ProID=1 +#Timeout value <256(Minute) (the Max waiting time for the OMC startup) +WaitTime=1 + + + diff --git a/mss/main/conf/smpp.conf b/mss/main/conf/smpp.conf new file mode 100644 index 0000000..65d2f98 --- /dev/null +++ b/mss/main/conf/smpp.conf @@ -0,0 +1,35 @@ +#SMPP Config file (V1.0.01) +#Copy this file to ./conf/smpp.conf to set global options +#No lkEn lkType serverType sessionType sysID pwd sysType LGTT RGTT LIP RIP sessionTimer enqTimer inactTimer rspTimer ServiceNum localSSN remoteSSN +0 129 1 1 0 WSMS 123456 GSM - - 172.25.196.78 172.25.196.80 5 10 5 5 98765 0 0 +1 129 1 1 0 SMEG 123456 GSM - - 172.25.196.78 172.25.196.80 5 10 5 5 88888 0 0 +2 129 1 1 1 SMEG 123456 GSM -- -- 172.25.196.78 172.25.196.80 5 10 5 5 88888 0 0 +3 129 0 0 2 PPS 123456 GSM 86755920016 86755920017 0.0.0.0 0.0.0.0 5 10 5 5 333 0 0 +4 129 0 1 2 PPS 123456 GSM 86755920017 86755920016 0.0.0.0 0.0.0.0 5 10 5 5 333 0 0 +5 129 1 1 2 MMS 123456 GSM -- -- 172.25.196.78 172.25.201.132 5 10 5 5 1111 0 0 +6 129 1 1 0 upe 123456 -- -- -- 172.25.196.78 172.25.201.131 10 10 5 5 78787 0 0 +7 129 1 1 2 SME_SND 123456 GSM -- -- 172.25.196.78 172.25.201.216 5 10 5 5 1010 0 0 +8 129 1 1 2 ESME 123456 GSM -- -- 172.25.196.78 172.25.196.100 5 10 5 5 99999 0 0 +9 129 1 1 0 VMS-0 123456 UTRAN -- -- 172.25.196.78 172.25.196.79 5 10 5 5 9200 0 0 +10 0 1 1 2 3gr4s 123456 GSM -- -- 172.25.196.78 172.25.201.216 5 10 5 5 77999 0 0 +11 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 10 10 5 5 -- 0 0 +12 0 0 0 0 -- -- -- -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +13 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +14 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +15 0 0 0 0 11 11 11 11 11 1.1.1.1 1.1.1.1 11 10 11 11 11 11 11 +16 0 0 1 2 PPS 123456 GSM 86755920017 86755920016 0.0.0.0 0.0.0.0 5 10 5 5 12 0 0 +17 0 0 0 2 PPS 123456 GSM 86755920016 86755920017 0.0.0.0 0.0.0.0 5 10 5 5 12 0 0 +18 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +19 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +20 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +21 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +22 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +23 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +24 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +25 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +26 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +27 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +28 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +29 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +30 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 +31 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- 0 0 diff --git a/mss/main/conf/smsc_csta.conf b/mss/main/conf/smsc_csta.conf new file mode 100644 index 0000000..b38d7f7 --- /dev/null +++ b/mss/main/conf/smsc_csta.conf @@ -0,0 +1,21 @@ +# This file defines the SMSC CSTA row +# The max number of row is 20 +# Attention: When you want to define the Entity name, the name of "MS" "All" and "Other" is reserved + +# define the entity who send short message to SMSC +Receive from: +MS +PPS +VMS +#VMS+PPS +Other +#All + +# define the entity who receive short message from SMSC +Send to: +MS +PPS +VMS +#VMS+PPS +Other +#All diff --git a/mss/main/conf/smsc_parambit.conf b/mss/main/conf/smsc_parambit.conf new file mode 100644 index 0000000000000000000000000000000000000000..6053de50da7bdb322f07d31c0576792ba38a0400 GIT binary patch literal 4456 zcmeI0u};G<5QfizrAtNG*m#7brcJ}tC+Gmpz=D`~17Jf;s1qVgbYbpebmt{_0F;Rx zY+vl8%{7h{sSCcLzS#Hq&VOtxDgy?LvF!Qo>NJ?;`R58?y<(40F*yj(&-3h7J9%N5 zaddpP2S?O%vi!h$dde|n7-tV<=oBoO#N&~EqT2WSYgHHoa&-EwVt#cbn@H17RJ&Nb zAg>13;vETV&oc|pIaf38`U!Z1x*n|eI9TxI z`mOoX%f|e6e%_H!yYYP3jZZHc`6!G+N_X8Cy!MgDj<4B)bR6{Oqk>oar}qA>`t!3! zK9Q!2CE8#qF9~5dR@*{JjAhO z{SO=KFL?9*Al$ZHr;(||+xL&>y?&bt{ImT-TsbYe%JbJEmYx52=)3AqBwMU{T#$1LXCbu;HJXn6`ocY<4492f%Qq%m>G|fue-db6jX_|l9HX`=Nu@-#A z1PGUC9DwoA(WvfuVy-UNrDC#sRJV*X zb-6ATXS+vr%a{rz7~j>6+oj@M_o!|e59)GVD$cVR#08lD9_BB0ucU4nm+Ep|DlT`A z>Xt$0|FFFK!7&umb@T30ajlGhwfocXCCRRi7FXc-3vqn-tluYMCT_;*$m?PklFUPjT`-SL)OIIAzSyijr;v|L)OH-AzSyiP1Aus0mMAapYG3T$eK7c zWb6L6?|yss*ROX?Jc_0DZu_C_V);XB*S{{7rV?XzX;QN0G=HdCX^f;jz zq$hCx@cdJP=TFj8xc|}Fm-71)o6Fe+u&_SU!Fz z`){Rrk#~>a}eey^N|eZkdJ0GgFKnPUcXj<%RI@h zV9N0Qm*MrJ`A|7t&eR{n`7pcwDIe>b4q21Y)l=pDcXr5V{cZD9f1PU-P(T3%6i`3` z1r$&~0R)*U3xqAH&*#qof&&v4r|Ly;SBiR1``1k+8?r-h?*R;Ng_{L`K|1;0-(`Q}#zx@7% z*RSLLKD~bcyndbOn^r&p1r$&~0R_fSfcO8|YqtLn{ows~ll_0T15A&#!1(w78Gk}| z&n*4%4e0-qSCHWSGn4&)!r$8eM|^Fv|IYwTE1-Y^3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC6g*_W#+TVE-Tb?SuIZ>HpWZ*Gqp0UVj*q@b#a8d3gWWnCco>b@Q=(Kl}gC?7>3Mim} z0tzUgfC37v3E2N!u)-hzsK@vn&s{P2l^k(?EkalkEZSaQ$d!u|IhqPE1-Y^3Mim}0^=rN|DWwK z`~T37p1+xA7> z3Mim}0tzUgfC36Apnw7jD4>7>3akm(|7VAS{eS3Z{~rO`|3`dn*#Ad>aS6rSxD4|b zVg6z1zn`mrj-dVJYp{QRwSMla$+!Z?Ux?#m1~Eh0_htTbfdpca&A|RY+52s4|9>&(0tzUgfCA$tVE>=(G5i0}&;CCHG>ru8|0BNE z{y+4y|BnFe|Fd(yX)(P7>3Mim}0tzUgfC36A z@E;L)vo??Xriq5kspJFZ6U=9r-vaYnVSXFTZ-@CEFuxP#cftH_nBPP4W))CCfpHaR z{8B&x1r$&~0R`%mdMZ+ibi{F2x1>y?wzGS{4#dJ&u6VIUST(*5swVSz-ig6@$W zn>NTTXnqmx?0D;S2QQc9{x|o|%;SEw>Gr8VmzFZ`&P{0fvOn_pO@=FVH@`M0Z|jqP z$aZY@4fpmSSR(iz{CfSVPhP_3PyVi3@G(X+aEZaXDW1L`VDh-=SiuA8S&B?*hx`ss zIXvOK?j+WK-5G~A7ER8rFnc%U(|ZRc-3?or>t-HVpS|u^fNRE?P_1J#r#{)7wt9bS zmHMu!&)EyhtbUotieAWA@LN1zRW)Y0#ZQA5E$y?s6M|2P;j(sAd^7|`Ltr!nMnhmU o1V&^C02`kHhp}T~!h@K0E3z75%p6rS8UmvsK>H9#=8!+!?0i6D7}FKiRr QN<$0P8TkLhXhjAF0D(0c761SM literal 0 HcmV?d00001 diff --git a/mss/main/conf/vlr_err b/mss/main/conf/vlr_err new file mode 100644 index 0000000..5c5905f --- /dev/null +++ b/mss/main/conf/vlr_err @@ -0,0 +1,4 @@ +2-13-1-15: VLR START init OK +2-13-1-15: start_time=3e8adf1b +2-13-1-41: ------VLR start up OK!,Local_plan=81,subscirber num=0 +2-13-1-41: *********************************************************** diff --git a/mss/main/conf/vlr_index b/mss/main/conf/vlr_index new file mode 100644 index 0000000..3fb25a6 --- /dev/null +++ b/mss/main/conf/vlr_index @@ -0,0 +1,3 @@ + plan=81,userNum=0 +------------------------------------------------ + 0: key=0,store_index= 0,store_imsi=0,isdn=000000000000000000 diff --git a/mss/main/conf/wxc2_sys.conf b/mss/main/conf/wxc2_sys.conf new file mode 100644 index 0000000..24ec4bb --- /dev/null +++ b/mss/main/conf/wxc2_sys.conf @@ -0,0 +1,3 @@ +aio-0=192.168.1.169; +heartbeat no=9 +noTimeSync=0 diff --git a/mss/main/conf/wxc2exit.txt b/mss/main/conf/wxc2exit.txt new file mode 100644 index 0000000..d511853 --- /dev/null +++ b/mss/main/conf/wxc2exit.txt @@ -0,0 +1,4 @@ +WXC2 procedure exit log + Time: Tue Nov 2 16:34:48 2004 + +Now module: MSC diff --git a/mss/main/conf/xap_mscid.conf b/mss/main/conf/xap_mscid.conf new file mode 100644 index 0000000000000000000000000000000000000000..decc0c3fc74626346f7b843bc456593454ee2680 GIT binary patch literal 3072 jcmeIufdBvi0K=g9Qy=7oP+`D;0RsjM7%*VKz{|h@3;+ND literal 0 HcmV?d00001 diff --git a/mss/main/conf/xap_sysparam.conf b/mss/main/conf/xap_sysparam.conf new file mode 100644 index 0000000000000000000000000000000000000000..ecc41ff361919b9ddedb20b5246b7a9276e946e7 GIT binary patch literal 20 ccmZ?cV`zI<8uyOj9pAfm@0i|gVPIeY0AC3R^Z)<= literal 0 HcmV?d00001 diff --git a/mss/main/makeclean b/mss/main/makeclean new file mode 100644 index 0000000..ea661e3 --- /dev/null +++ b/mss/main/makeclean @@ -0,0 +1,32 @@ +#!/bin/sh + +echo "" +echo "==========================================" +echo "==== Cleaning WXC2 R9 Platform Modules====" +echo "==========================================" +echo "" +cd ../../plat +cd public ; make clean ; cd .. ; +cd debug ; make clean ; cd .. ; +cd snmp ; make clean ; cd .. ; +cd iptrans; make clean ; cd .. ; +cd mtp3 ; make clean ; cd .. ; +cd sccp ; make clean ; cd .. ; +cd tcap ; make clean ; cd .. ; +cd xapp ; make clean ; cd .. ; +cd m2ua ; make clean ; cd .. ; +cd smpp ; make clean ; cd .. ; +cd scf ; make clean ; cd .. ; +cd radius ; make clean ; cd .. ; +cd tcp ; make clean ; cd .. ; +cd diameter ; make clean ; cd .. ; +cd .. + +echo "" +echo "=============================================" +echo "==== Cleaning WXC2 R9 Application Modules====" +echo "=============================================" +echo "" +cd mss +cd pps ; make clean ; cd .. ; +cd main ; make clean ; diff --git a/mss/main/makedebug b/mss/main/makedebug new file mode 100644 index 0000000..fa16bd2 --- /dev/null +++ b/mss/main/makedebug @@ -0,0 +1,32 @@ +#!/bin/sh + +echo "" +echo "==========================================" +echo "==== Building WXC2 R9 Platform Modules====" +echo "==========================================" +echo "" +cd ../../plat +cd public ; make rebuild ; cd .. ; +cd debug ; make rebuild ; cd .. ; +cd snmp ; make rebuild ; cd .. ; +cd iptrans; make rebuild ; cd .. ; +cd mtp3 ; make rebuild ; cd .. ; +cd sccp ; make rebuild ; cd .. ; +cd tcap ; make rebuild ; cd .. ; +cd xapp ; make rebuild ; cd .. ; +cd m2ua ; make rebuild ; cd .. ; +cd smpp ; make rebuild ; cd .. ; +cd scf ; make rebuild ; cd .. ; +cd radius ; make rebulid ; cd .. ; +cd tcp ; make rebulid ; cd .. ; +cd diameter ; make rebulid ; cd .. ; +cd .. + +echo "" +echo "=============================================" +echo "==== Building WXC2 R9 Application Modules====" +echo "=============================================" +echo "" +cd mss +cd pps ; make rebuild ; cd .. ; +cd main ; make rebuild ; diff --git a/mss/main/makerelease_16cos b/mss/main/makerelease_16cos new file mode 100644 index 0000000..7046a9a --- /dev/null +++ b/mss/main/makerelease_16cos @@ -0,0 +1,34 @@ +#!/bin/sh + +./makeclean + +echo "" +echo "==========================================" +echo "==== Building AGT OCS Platform Modules====" +echo "==========================================" +echo "" +cd ../../plat +cd public ; make release ; cd .. ; +cd debug ; make release ; cd .. ; +cd snmp ; make release ; cd .. ; +cd iptrans; make release ; cd .. ; +cd mtp3 ; make release ; cd .. ; +cd sccp ; make release ; cd .. ; +cd tcap ; make release ; cd .. ; +cd xapp ; make release ; cd .. ; +cd m2ua ; make release ; cd .. ; +cd smpp ; make release ; cd .. ; +cd scf ; make release ; cd .. ; +cd radius ; make release ; cd .. ; +cd tcp ; make release ; cd .. ; +cd diameter ; make clean; make ; cd .. ; +cd .. + +echo "" +echo "=============================================" +echo "==== Building AGT OCS Application Modules====" +echo "=============================================" +echo "" +cd mss +cd pps ; make all ; cd .. ; +cd main ; make release ; diff --git a/mss/main/makerelease_64cos_cook b/mss/main/makerelease_64cos_cook new file mode 100644 index 0000000..3389b26 --- /dev/null +++ b/mss/main/makerelease_64cos_cook @@ -0,0 +1,34 @@ +#!/bin/sh + +./makeclean + +echo "" +echo "==========================================" +echo "==== Building AGT OCS Platform Modules====" +echo "==========================================" +echo "" +cd ../../plat +cd public ; make release ; cd .. ; +cd debug ; make release ; cd .. ; +cd snmp ; make release ; cd .. ; +cd iptrans; make release ; cd .. ; +cd mtp3 ; make release ; cd .. ; +cd sccp ; make release ; cd .. ; +cd tcap ; make release ; cd .. ; +cd xapp ; make release ; cd .. ; +cd m2ua ; make release ; cd .. ; +cd smpp ; make release ; cd .. ; +cd scf ; make release ; cd .. ; +cd radius ; make release ; cd .. ; +cd tcp ; make release ; cd .. ; +cd diameter ; make clean; make ; cd .. ; +cd .. + +echo "" +echo "=============================================" +echo "==== Building AGT OCS Application Modules====" +echo "=============================================" +echo "" +cd mss +cd pps ; make cook_island ; cd .. ; +cd main ; make release ; diff --git a/mss/main/makerelease_rdb_tariff b/mss/main/makerelease_rdb_tariff new file mode 100644 index 0000000..9808de5 --- /dev/null +++ b/mss/main/makerelease_rdb_tariff @@ -0,0 +1,34 @@ +#!/bin/sh + +./makeclean + +echo "" +echo "==========================================" +echo "==== Building AGT OCS Platform Modules====" +echo "==========================================" +echo "" +cd ../../plat +cd public ; make release ; cd .. ; +cd debug ; make release ; cd .. ; +cd snmp ; make release ; cd .. ; +cd iptrans; make release ; cd .. ; +cd mtp3 ; make release ; cd .. ; +cd sccp ; make release ; cd .. ; +cd tcap ; make release ; cd .. ; +cd xapp ; make release ; cd .. ; +cd m2ua ; make release ; cd .. ; +cd smpp ; make release ; cd .. ; +cd scf ; make release ; cd .. ; +cd radius ; make release ; cd .. ; +cd tcp ; make release ; cd .. ; +cd diameter ; make clean; make ; cd .. ; +cd .. + +echo "" +echo "=============================================" +echo "==== Building AGT OCS Application Modules====" +echo "=============================================" +echo "" +cd mss +cd pps ; make rdb_tariff ; cd .. ; +cd main ; make release ; diff --git a/mss/main/makerelease_zed_mobile b/mss/main/makerelease_zed_mobile new file mode 100644 index 0000000..f06118e --- /dev/null +++ b/mss/main/makerelease_zed_mobile @@ -0,0 +1,34 @@ +#!/bin/sh + +./makeclean + +echo "" +echo "==========================================" +echo "==== Building AGT OCS Platform Modules====" +echo "==========================================" +echo "" +cd ../../plat +cd public ; make release ; cd .. ; +cd debug ; make release ; cd .. ; +cd snmp ; make release ; cd .. ; +cd iptrans; make release ; cd .. ; +cd mtp3 ; make release ; cd .. ; +cd sccp ; make release ; cd .. ; +cd tcap ; make release ; cd .. ; +cd xapp ; make release ; cd .. ; +cd m2ua ; make release ; cd .. ; +cd smpp ; make release ; cd .. ; +cd scf ; make release ; cd .. ; +cd radius ; make release ; cd .. ; +cd tcp ; make release ; cd .. ; +cd diameter ; make clean; make ; cd .. ; +cd .. + +echo "" +echo "=============================================" +echo "==== Building AGT OCS Application Modules====" +echo "=============================================" +echo "" +cd mss +cd pps ; make zed_mobile ; cd .. ; +cd main ; make release ; diff --git a/mss/main/myipcrm b/mss/main/myipcrm new file mode 100644 index 0000000..80534ab --- /dev/null +++ b/mss/main/myipcrm @@ -0,0 +1,33 @@ +#!/bin/sh + +ipcrm='To delete ipcrm shm' + +#program name +if [ `whoami` != "root" ] ; then + echo "Permission denied!" + exit +fi + +ipcsm=`ipcs -m` +echo "$ipcsm" + +ipcsm=`ipcs -m|grep '0x'|awk '{print $2}'` +for FILE in $ipcsm; do + ipcrm shm $FILE +done + +ipcsm=`ipcs -s` +echo "$ipcsm" + +ipcsm=`ipcs -s|grep '0x'|awk '{print $2}'` +for FILE in $ipcsm; do + ipcrm sem $FILE +done + +ipcsm=`ipcs -q` +echo "$ipcsm" + +ipcsm=`ipcs -q|grep '0x'|awk '{print $2}'` +for FILE in $ipcsm; do + ipcrm msg $FILE +done diff --git a/mss/main/pkg.tgz b/mss/main/pkg.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f8307ba57bfdfd722a68ff59261c343752724d8b GIT binary patch literal 70192 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 literal 0 HcmV?d00001 diff --git a/mss/main/release_note b/mss/main/release_note new file mode 100644 index 0000000..7337372 --- /dev/null +++ b/mss/main/release_note @@ -0,0 +1,37 @@ +ACRD Software Release Notes + +Project: WXC2 R9 MSS + +#---------------------------------------------- +[Version] + 9.0.13 +[Date] + 2007-12-14 +[Builder] + Yingmin +[Module version] + 1.8ECP R9V0_01 + 2.AIFG R9V0_03 + 3.BICC R9V0_04 + 4.DEBUG R9V0_01 + 5.HAEPUB R9V0_01 + 6.IPTRANS R9V0_01 + 7.ISUP R9V0_04 + 8.M2UA R9V0_02 + 9.MGC R9V0_02 + 10.MGCP R9V0_02 + 11.MTP3 R9V0_02 + 12.PUBLIC R9V0_01 + 13.RTP R9V0_01 + 14.SCCP R9V0_06 + 15.SCF R9V0_02 + 16.SMPP R9V0_03 + 17.SNMP R9V0_02 + 18.TCAP R9V0_02 + 19.XAPP R9V0_01 +[Updated Module] + 1.N/A + +[Remark] + 1.Initial Clearcase release +#---------------------------------------------- diff --git a/mss/main/src/include/wxc2ver.h b/mss/main/src/include/wxc2ver.h new file mode 100644 index 0000000..933b623 --- /dev/null +++ b/mss/main/src/include/wxc2ver.h @@ -0,0 +1,33 @@ +//This file contains the version code of every R9 module + +//WXC2 R9 version +const char *r9_ver = "V9.0.12"; + +//platform module version +const char *iptrans_ver = "R9V0_01"; +const char *aifg_ver = "R9V0_03P6"; +const char *mtp3_ver = "R9V0_001"; +const char *sccp_ver = "R9V0_03"; +const char *tcap_ver = "R9V0_05"; +const char *xapp_ver = "R9V0_01"; +const char *snmp_ver = "R9V0_01"; +const char *debug_ver = "R9V0_02"; +const char *smpp_ver = "R9V0_01"; +//const char *m2ua_ver = "R9V0_03b"; +const char *bicc_ver = "R9V0_02"; +const char *mgc_ver = "R9V0_05"; +const char *mgcp_ver = "R9V0_01"; +const char *_8ecp_ver = "R9V0_01p1"; +const char *isup_ver = "R9V0_02"; + +//applicationi module version +const char *msc_ver = "R9V0_06"; +const char *vlr_ver = "R9V0_01"; +const char *hlr_ver = "R9V0_02B1"; +const char *smsc_ver = "R9V0_01"; +const char *ssf_ver = "R9V0_01"; +const char *pps_ver = "R9V0_01"; +const char *aas_ver = "R9V0_01"; +const char *mnp_ver = ""; +const char *auc_ver = "R9V0_01"; + diff --git a/mss/main/src/wxc2main.c b/mss/main/src/wxc2main.c new file mode 100644 index 0000000..adfc648 --- /dev/null +++ b/mss/main/src/wxc2main.c @@ -0,0 +1,2299 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "include/wxc2ver.h" +#include "../../plat/snmp/src/include/snmp.h" +#include "../../plat/public/src/include/license_id.h" +#include "../../plat/tcap/src/include/tcap_public.h" +#include "../../plat/radius/src/include/radius.h" +#include "../../plat/tcp/src/include/tcp_if.h" + + +#define MAX_FUNCTION_ID 16 +#define MAX_APP_FUNC_ID 16 +#define MAX_License_ID (MAX_FUNCTION_ID+MAX_APP_FUNC_ID) + +extern unsigned int wxc2_get_shm_offset(); + +typedef enum _WXC2_LICENSE_DIR +{ + BOTH_IN_DE_CREASABLE, + ONLY_INCREASABLE, + ONLY_DECREASABLE, +}WXC2_LICENSE_DIR; + +typedef struct _wxc2_license_vadility +{ + char name[16]; /* name of the module or function */ + int maxValue; /* max value of the license, the minimum is 0 */ + int step; /* step of license, each modification should be X*step */ + int dir; /* how to modify the license, 0=can increase or decrease, + 1=only increase, 2=only decrease */ +}wxc2_license_vadility; + +wxc2_license_vadility wxc2_license_rule[MAX_License_ID]= +{ + {"MSC TRUNKS",1024,1,ONLY_INCREASABLE}, + {"HLR USERS",100000,100,ONLY_INCREASABLE}, + {"VLR USERS",100000,100,ONLY_INCREASABLE}, + {"AUC USERS",100000,100,ONLY_INCREASABLE}, + {"EIR USERS",100000,100,ONLY_INCREASABLE}, + {"PPS USERS",100000,100,ONLY_INCREASABLE}, + {"SMSC USERS",100000,100,ONLY_INCREASABLE}, + {"MNP USERS",100000,100,ONLY_INCREASABLE}, + {"SMEG USERS",100000,100,ONLY_INCREASABLE}, + {"OPPS USERS",100000,100,ONLY_INCREASABLE}, + {"PALIM USERS",100000,100,ONLY_INCREASABLE}, + {"Mesh HLR",100000,100,ONLY_INCREASABLE}, + {"RMC",100000,100,ONLY_INCREASABLE}, + {"",100000,100,ONLY_INCREASABLE}, + {"",100000,100,ONLY_INCREASABLE}, + {"",100000,100,ONLY_INCREASABLE}, + + {"GPRS",1,1,BOTH_IN_DE_CREASABLE}, + {"USSD",1,1,BOTH_IN_DE_CREASABLE}, + {"ISUP",1,1,BOTH_IN_DE_CREASABLE}, + {"BICC",1,1,BOTH_IN_DE_CREASABLE}, + {"AIF",1,1,BOTH_IN_DE_CREASABLE}, + {"MGC",1,1,BOTH_IN_DE_CREASABLE}, + {"CAP",1,1,BOTH_IN_DE_CREASABLE}, + {"OPPS_OPR",1,1,BOTH_IN_DE_CREASABLE}, + {"OPPS_IMDM",1,1,BOTH_IN_DE_CREASABLE}, + {"ISDN",1,1,BOTH_IN_DE_CREASABLE}, + {"SIP",1,1,BOTH_IN_DE_CREASABLE}, + {"RLS",1,1,BOTH_IN_DE_CREASABLE}, + {"",1,1,BOTH_IN_DE_CREASABLE}, + {"",1,1,BOTH_IN_DE_CREASABLE}, + {"",1,1,BOTH_IN_DE_CREASABLE}, + {"",1,1,BOTH_IN_DE_CREASABLE} +}; + +//extern int mnpf_exit(int flag); +//extern int mnpf_timer(); +//extern int mnpf_init(int capability, int sysID, u_long local_ip,u_long peer_ip,char *sn); +extern void debug_change_title1(); + +u32 WXC2_OID_PREFIX[]={1,3,6,1,4,1,1373,2,3,3,99}; + +static BYTE app_state = 0, sub_state=0; + +#define SYS_IT_INTERVAL_SEC 0 + +#define ES4_IT_INTERVAL_USEC (9*1000) +#define CENTOS_IT_INTERVAL_USEC (10*1000) // actually it's 10 ms interval, but should set timer to 9 ms on ES4 +#define APP_CYCLE 10 + +#define DEFAULT_USERS (100000+1) + +#define MAX_APP_NUM 16 +#define MAX_LICENSE_TYPE 255 + +#define WXC2_SHM_KEY 0x90010000 +#define WXC2_SHM_PERM 0777 + +#define MAX_DELAY_TIME 2000 + +char app_name[MAX_APP_NUM][8]={ + "MSC", + "HLR", + "VLR", + "AUC", + "EIR", + "PPS", + "SMSC", + "MNP", + "SMEG" + "OPPS", + "PALIM", + "MC", + "RMC", + "", + "", + "", +}; + + +enum _SYS_LIST{ + MSC_, + HLR_, + VLR_, + AUC_, + EIR_, + PPS_, + SMSC_, + MNPF_, + SMEG_, + OPPS_, + PALIM_, + MC_, + RMC_ +}; + +enum _WXC2_STATE{ + WXC2_STARTUP, + WXC2_INITRAM, + WXC2_PRIV, + WXC2_NORMAL, +}; + +enum _WXC2_SYSTTYPE{ + WXC2_SYSTYPE_UNIB, + WXC2_SYSTYPE_X40, + WXC2_SYSTYPE_X100, +}; + +char systemTypeName[3][8]={ + "NIB", + "X40", + "X100"}; + +/* index=MSC,HLR,PPS,AUC,EIR , from 0 */ +/* old one +struct _wxc2_param +{ + int systemType; + char segmentFaultCommand[128]; + int register_flag[MAX_APP_NUM]; + int max_users[MAX_APP_NUM]; + char serialNumber[16]; + unsigned char HDSerialNumber[256]; + char license_flag[MAX_APP_NUM]; + u_char license_date[3]; // year(0-99),month,day + unsigned char userBcdLicense[MAX_LICENSE_TYPE][8]; + unsigned int userIntLicense[MAX_LICENSE_TYPE]; + unsigned char HDSerialNumber1[256]; +}wxc2_param,tmpParam; +*/ + +/* new one */ +struct _wxc2_param +{ + char serialNumber[16]; + int systemType; + u_char license_date[3]; /* year(0-99),month,day */ + int register_flag[MAX_APP_NUM]; + int max_users[MAX_APP_NUM]; + unsigned char HDSerialNumber[2][256]; + unsigned char userBcdLicense[MAX_LICENSE_TYPE][8]; + unsigned int userIntLicense[MAX_LICENSE_TYPE]; +}wxc2_param,tmpParam; + +static int sys_timer10ms=0; +static int systemID=0,systemInited=0; +static int shutDownCommand = 0,endflag=0; +static int wxc2_main_state = WXC2_STARTUP; +static int wxc2_startup_state = VLR_; +//static int HzFlag=0; +static u_long wxc_localip,wxc_peerip; +static char wxc_localip_str[32],wxc_peerip_str[32]; +static int nowModule=MSC_; +static u_char heartbeat_no = 0x09,hb_sub_no=0x00; +static u_short hb_no=0x0901; +static u_short plat_work_port = 4096; +static char wxc2HDInfo[256]; /* array[0] is length */ +struct timeval tmstart,tmend; +static char serialNumber[18]=""; +//static int updateFromLowVersion=0; +u_char noTimeSyncFlag = 0; + +struct timeval main_now; + +typedef enum _OS_VERSION +{ + OS_ES4, + OS_CENTOS, +}OS_VERSION; +static int Linux_OS_Release=OS_CENTOS; /* 0=ES4, 1=CentOS */ + +typedef struct segLog{ + u_long tmnow; + u_char app_state; + u_char sub_state; +}segLog; +segLog *segmentLog; +/*----------------------------------------------------*/ +static void wxc2SetTermSignal(struct termio *ptermio, void (*handler)(int)); +static void wxc2Terminate(int sig); +static void moduleProc(); +static int GetHDInfo(); +static void SaveWxc2SystemConf(); +static int CheckHDLicense(unsigned char *HDSerialNumber); +static void CheckLicenseExpire(); +static void UpdateWXC2License(); +/*----------------------------------------------------*/ +extern int iptrMainInit(); +extern void iptrans_timer(); + +extern void debug_init(); +extern void debug_rt(); + +extern void heartbeat_init( unsigned short sysID); +extern void heartbeat_timer(); + +extern void snmp_init(unsigned short port ); +extern void snmp_timer(); + +extern int smpp_timer(); +extern int smpp_init_new(u8 sysid); +extern int smpp_fsm_new(); + +extern void mtp_shm_init(WORD moduleid_systemid, DWORD local_ip, DWORD peer_ip); +extern void mtp3_proc(); +extern void sccp_init(int sysid, u_long localip, u_long peerip); +extern void sccp_timer(); +extern int ReadHDInfoList(); +extern int CheckIfHDInfoBackup(unsigned char *license_info); +extern int SaveHDInfoList(unsigned char *new_hd_info); +extern void tcap_init(u_short maxPorts,u_long localip,u_long peerip); +extern void tcap_msgprc(); +extern void tcap_fsm(); + +extern void xap_init(u_short maxPorts); +extern void xap_fsm(); + +extern void scsm_init(); +extern void scsm(); + +extern int pps_init(); +extern int pps_proc(); +extern int pps_exit(); + +extern void DesCrypt( +unsigned char *Output /*8 bytes*/, +unsigned char *Input /*8 bytes*/, +unsigned char *DesKey/*default=NULL.While using for user licenses control,can keep the default value*/, +unsigned char DesMode/*encrpt or decrypt,refer to enum _DesMode*/); + +extern void ppsRecordLog(); +extern void debug_init_wxc2_ver(char *info); + +//extern void gx_handle_msg_cb(); + +extern void m2ua_init(BYTE); +extern void mtp3_init_serial(char *Serial); +extern void sccp_init_serial_number(BYTE *Serial); +extern int cdr_init(char plane_id, char memset_flag); +extern void m2ua_timer(void); +extern void ReadMCMSParam(void); +extern int fd_main(int argc, char * argv[]); +extern int gx_fsm(long sec, int msec); + +/*----------------------------------------------------*/ + +static u8 wxc2_version[4] = {1, 0, 1, 46}; +//static char wxc2_mini_version[4]={""}; + +static int wxc2_update_version(char *state_str) +{ + char ver_string[64]; + + /*if(wxc2_version[3] == 0) + { + sprintf(ver_string, "WXC2 MSS R%d.%d.%d%s - %s", \ + wxc2_version[0], wxc2_version[1], wxc2_version[2], wxc2_mini_version,state_str); + } + else*/ + { + //sprintf(ver_string, "WXC2 MSS R%d.%d.%d.%03d%s - %s", + sprintf(ver_string, "AGT OCS %d.%d.%d.%03d - %s", \ + wxc2_version[0], wxc2_version[1], wxc2_version[2], wxc2_version[3],state_str); + } + debug_init_wxc2_ver(ver_string); + return 1; +} + +static int +snmpSetWXC2(u_char oidLen, DWORD *oid,u_char *pdata, u_short dataLen) +{ + u_char ocode=0; + DWORD oidtype=0; +// int ssn; +// u_char bufdecrypt[128]=""; +// char buf[128]; + //16.2.1.1:configuration + if(oidLen<14) return 0; + + oidtype = oid[11]; + if(oidtype !=2) return 0; //only configuration supported + oidtype = oid[12]; + if(oidtype !=1) return 0; //parameter + oidtype = oid[13]; + + if(oidtype !=1 && oidtype !=2) return 0; //status, license + switch(oidtype) + { + case 1: /* status */ + ocode = pdata[0]; + switch(ocode) + { + case 1: //init + break; + case 2: //suspend + break; + case 3: //normal + break; + case 4: //shutdown + shutDownCommand = 1; + break; + case 5: //Save subs. data + endflag=1; + return dataLen; + if(wxc2_param.register_flag[PPS_]) pps_exit(1); + endflag =0; + break; + case 6: //backup configuration file, it should work with the script,MSS generates a log file, a script do the acutal backuping... + { + FILE *fpLog; + + fpLog = fopen("/usr/local/wxc2/log/mss_backup_conf.txt","w"); + fprintf(fpLog,"This is a log file to backup mss conf\n"); + fclose(fpLog); + } + //system("tar cf /usr/local/subsManage/conf.bk.tar conf"); + //system("chmod 666 /usr/local/subsManage/conf.bk.tar"); + break; + case 7: + //system("tar xf /usr/local/subsManage/conf.bk.tar"); + wxc2Terminate(128); + break; + default: + return 0; + break; + } + break; + case 2: /* license */ + UpdateWXC2License(); + break; + break; + } + return dataLen; +} + +static int snmpGetWXC2(u_char oidLen, DWORD *oid,u_char *pdata, u_char *vartype) +{ + DWORD oidtype=0; + int len=0; + int i; + unsigned int intLicense; + + //16.2.1.3: license status + if(oidLen<14) return 0; + + oidtype = oid[11]; + if(oidtype !=2) return 0; //only configuration supported + oidtype = oid[12]; + if(oidtype !=1) return 0; //parameter + oidtype = oid[13]; + + if (oidtype != 3) return 0; //license status + + switch (oidtype) + { + case 3: /* license status */ + len = MAX_License_ID * sizeof(int); + for (i = 0; i < MAX_License_ID; i++) + { + intLicense = htonl(wxc2_param.userIntLicense[i]); + memcpy(pdata + i * sizeof(unsigned int), (u_char *) &intLicense, sizeof(unsigned int)); + } + break; + default: + break; + } + + *vartype = 4; + + return len; +} + +static +void wxc2SetTermSignal(struct termio *ptermio, void (*handler)(int)) +{ + ioctl(0,TCGETA, ptermio); + ptermio->c_cc[VINTR] = '\x03'; + ioctl(0,TCSETA, ptermio); + + signal(SIGINT, handler); +// signal(SIGPIPE,handler); + signal(SIGKILL,handler); + signal(SIGSTOP,handler); + signal(SIGTERM,handler); +} + +static +void wxc2Terminate(int sig) +{ + char exitlog[128]="../log/wxc2exit.txt"; + FILE *fpExit; + struct tm *tp, tb; + long ltime; + //char *argv[2]; + int loop=0; + static int wxc2TermFlag=0; + + if(wxc2TermFlag) return; + wxc2TermFlag = 1; + + endflag=1; + printf("backup file for normal stop...\n"); + fpExit=fopen(exitlog,"w"); + if(fpExit!=NULL) + { + tp = &tb; + ltime = time((long *)0); + tp = localtime(<ime); + fprintf(fpExit,"WXC2 procedure exit log\n"); + fprintf(fpExit," Time: %s\n",asctime(tp)); + fprintf(fpExit,"Now module: %s\n",app_name[nowModule]); + fclose(fpExit); + }else{ + printf("fopen file failed\n"); + } + + if(wxc2_param.register_flag[PPS_]) pps_exit(1); + + loop = 0; + while(loop++it_interval.tv_sec = SYS_IT_INTERVAL_SEC; + ptv->it_value. tv_sec = SYS_IT_INTERVAL_SEC; + if(Linux_OS_Release == OS_ES4) + { + ptv->it_interval.tv_usec = ES4_IT_INTERVAL_USEC; + ptv->it_value.tv_usec = ES4_IT_INTERVAL_USEC; + } + else + { + ptv->it_interval.tv_usec = CENTOS_IT_INTERVAL_USEC; + ptv->it_value.tv_usec = CENTOS_IT_INTERVAL_USEC; + } + setitimer(ITIMER_REAL, ptv, NULL); + +} + +void wxc2StartLog(int flag) +{ + FILE *fpLog=NULL; + char logFile[]="../log/wxc2_startup.log"; + time_t *p,tnow; + + p=&tnow; + *p = time(NULL); + fpLog = fopen(logFile,"a+"); + if(fpLog !=NULL) + { + if(!flag) + fprintf(fpLog,"wxc2main startup --->%s ",ctime(p)); + else + fprintf(fpLog,"wxc2main shutdown --->%s ",ctime(p)); + fclose(fpLog); + } +} + +int wxc2_system(char *command) +{ + int pid, status; + char *argv[3]; + + pid = fork(); + if(pid == -1) + return -1; + if(pid == 0) + { + argv[0] = "wxc2d"; + argv[1] = "restart"; + argv[2] = 0; + execvp("/usr/local/wxc2/bin/wxc2d",argv); + exit(127); + } + do{ + if(waitpid(pid,&status,0) == -1){ + if(errno != EINTR) + return -1; + }else{ + return status; + } + }while(1); +} + +#if 0 +static void SysGuard(int sig) +{ + struct timeval tm; + char fname[64]={"../log/logout.txt"}; + FILE *fp; + struct tm *tp, tb; + long ltime; + + tp = &tb; + ltime = time((long *)0); + tp = localtime(<ime); + sprintf(fname,"../log/wxc2_logout.log"); + + fp = fopen(fname,"w"); + + if(fp != NULL) + { + gettimeofday(&tm,NULL); + fprintf(fp,"====================================\n"); + fprintf(fp,"system restart for segementation fault!\n"); + fprintf(fp,"log time : %s\n",ctime(&tm.tv_sec)); + fprintf(fp,"Now module: %d\n",segmentLog->sub_state); + fclose(fp); + } + + printf("wxc2 exit for SEGMENT FAULT!\n"); + + pps_exit(0); + + ppsRecordLog(); + exit(1); +} +#endif + +static void sysTimer_IRQ() +{ + gettimeofday(&main_now,NULL); + sys_timer10ms = 1; +} + +static void +SigactionSystem() +{ + struct sigaction action;//,actsegv; + + action.sa_handler = sysTimer_IRQ; + sigemptyset(&action.sa_mask); + action.sa_flags = SA_RESTART; + if(sigaction(SIGALRM, &action, NULL)<0) + { + printf("sigactin sigalarm failed\n"); + } + +/* if(!wxc2_param.segmentFaultAction) + { + actsegv.sa_handler = SysGuard; + sigemptyset(&actsegv.sa_mask); + actsegv.sa_flags = SA_RESTART; + sigaction(SIGSEGV,&actsegv,NULL); + } +*/ +} + +static void CheckLicenseExpire() +{ + struct tm *tp, tb; + long ltime; + int error_flag = 0; + /* max license is 2099-12-31 */ + tp = &tb; + ltime = time((long *)0); + tp = localtime(<ime); + + //printf("Check license date..."); may cause system crash + + if((tp->tm_year+1900)>wxc2_param.license_date[0]+2000) + { + error_flag = 1; + } + else if((tp->tm_year+1900)==wxc2_param.license_date[0]+2000) + { + if((tp->tm_mon+1)>wxc2_param.license_date[1]) + { + error_flag = 1; + } + else if((tp->tm_mon+1)==wxc2_param.license_date[1]) + { + if(tp->tm_mday>wxc2_param.license_date[2]) + { + error_flag = 1; + } + } + } + + if(error_flag) + { + printf("Failed!\n"); + /*printf("License is expired (20%02d-%02d-%02d),today:(%04d-%02d-%02d)\n", + wxc2_param.license_date[0], + wxc2_param.license_date[1], + wxc2_param.license_date[2], + tp->tm_year+1900, + tp->tm_mon+1, + tp->tm_mday);*/ + exit(4); + } + //printf("pass!\n"); may cause system crash +} + +static int CheckHDLicense(unsigned char *HDSerailNumber) +{ +#if 0// old CheckHDLicense + int length; + length = wxc2HDInfo[0]; + + printf("Check HD License...\n"); + if (memcmp(&wxc2HDInfo[1],HDSerailNumber,length) !=0) + { + char ascii_buf[256]; + BcdToAscii(ascii_buf,&wxc2HDInfo[1],length*2); + printf("Check HD license...FAILED!\n"); + //printf("Activation request code: %s\n", ascii_buf); + printf("Please send ./log/Activation_request_code.txt to get the license\n"); + return 0; + } + printf("Check HD License...PASS!\n"); + return 1; +#endif + int length; + length = wxc2HDInfo[0]; + + printf("Check HD License...\n"); + + ReadHDInfoList(); + + if (memcmp(&wxc2HDInfo[1],HDSerailNumber,length) !=0) + { + if(CheckIfHDInfoBackup(HDSerailNumber) == 0) + { + char ascii_buf[256]; + BcdToAscii(ascii_buf, (BYTE *)&wxc2HDInfo[1],length*2); + printf("Check HD license...FAILED!\n"); + //printf("Activation request code: %s\n", ascii_buf); + printf("Please send ../log/Activation_request_code.txt to get the license\n"); + return 0; + } + } + + SaveHDInfoList((unsigned char *)wxc2HDInfo); + + printf("Check HD License...PASS!\n"); + return 1; +} + +#if 1//def Kylin_and_2204_lic +static int GetHDInfo() +{ + FILE *fpConf=NULL; + int i,j=0,k; + char ethmac[64]="",meminfo[64]="",hwinfo[128]="",*start,*offset,*offset_0,buf[8192]="",tmp[2048]="";//,cpuinfo[64]="" + char ascii_buf[128] = {0}; + unsigned char TmpStr[64] = {0}, act_req_code[128] = {0}, act_req_code_des[128] = {0}; + int ret, offset_len; + + printf("Get HD info ...\n"); + + memset(ethmac, 0, 64); + sprintf(buf,"ip a > ../log/hwinfo"); + ret = system(buf); + fpConf = fopen("../log/hwinfo","r"); + if (fpConf == NULL) { + printf("Log directory may be missing!\n"); + return 0; + } + ret = fread(buf,2048,1,fpConf); + start = buf; + for (;;) { + offset = strstr(start,"ether "); + if (offset == NULL) { + offset = strstr(start,"HWaddr "); + offset_len = 7; + } else { + offset_len = 6; + } + if (offset != NULL) { + strncpy(tmp, start, offset-start); + tmp[offset-start] = 0; + if (strstr(tmp, "docker") != NULL) { + start = offset + offset_len; + continue; + } + offset += offset_len; + for(i=0,j=0;i<64;i++) { + if ((*(offset+i)=='\n') || + (*(offset+i)==' ')) { + ethmac[j] = 0; + break; + } else if (*(offset+i)==':') { + continue; + } else { + ethmac[j] = tolower(*(offset+i)); + j++; + } + } + ethmac[j] = 0; + } + fclose(fpConf); + remove("../log/hwinfo"); + break; + } + + int uuid_or_cpuid=0; //0=CPUID, 1=UUID + memset(meminfo, 0, 64); + sprintf(buf,"dmidecode | grep UUID > ../log/hwinfo"); + ret = system(buf); + fpConf = fopen("../log/hwinfo","r"); + if(fpConf != NULL) { + ret = fread(buf,2048,1,fpConf); + offset_0=offset = strstr(buf,"UUID: "); + if (offset != NULL) { + uuid_or_cpuid = 1; + for(i=6,j=0;i<64;i++) { + if (*(offset+i)=='\n') { + meminfo[j] = 0; + break; + } else if (isdigit(*(offset+i))) { + meminfo[j] = *(offset+i); + j++; + } + } + } + fclose(fpConf); + remove("../log/hwinfo"); + } + + if( uuid_or_cpuid == 0) {//UUID not found + // CPUID + memset(meminfo, 0, 64); + sprintf(buf,"dmidecode -t 4 | grep ID >../log/hwinfo"); + ret = system(buf); + fpConf = fopen("../log/hwinfo","r"); + if(fpConf != NULL) { + ret = fread(buf,2048,1,fpConf); + offset_0=offset = strstr(buf,"ID: "); + if (offset != NULL) { + for(i=4,j=0;i<64;i++) { + if (*(offset+i)=='\n') { + meminfo[j] = 0; + break; + } else if (isdigit(*(offset+i))) { + meminfo[j] = *(offset+i); + j++; + } + } + offset = strstr(offset_0+4,"ID: "); + if (offset != NULL) { + for(i=4;i<64;i++) { + if (*(offset+i)=='\n') { + meminfo[j] = 0; + break; + } else if (isdigit(*(offset+i))) { + meminfo[j] = *(offset+i); + j++; + } + } + } + } + fclose(fpConf); + remove("../log/hwinfo"); + } + } + + strcpy(hwinfo, ""); + strcat(hwinfo, ethmac); + i = j = strlen(ethmac); + hwinfo[i++] = ethmac[0]; + hwinfo[i++] = ethmac[1]; + hwinfo[i++] = ethmac[2]; + hwinfo[i++] = ethmac[3]; + hwinfo[i] = 0; + strcat(hwinfo, meminfo); + j = strlen(meminfo); + i += j; + hwinfo[i++] = ethmac[4]; + hwinfo[i++] = ethmac[5]; + hwinfo[i++] = ethmac[6]; + hwinfo[i++] = ethmac[7]; + hwinfo[i] = 0; + //strcat(hwinfo, cpuinfo); + //j = strlen(cpuinfo); + //i += j; + hwinfo[i++] = ethmac[8]; + hwinfo[i++] = ethmac[9]; + hwinfo[i++] = ethmac[10]; + hwinfo[i++] = ethmac[11]; + hwinfo[i] = 0; + + j = strlen(hwinfo); + if (j == 0) { + printf("Missing Activation Request Info!\n"); + return 0; + } + + k = (j + 7) / 8; + memset(hwinfo + j, '0', 128 - j); + + memset(act_req_code, 0, 128); + for (i = 0; i < k; i++) { + memset(TmpStr, 0, 64); + DesCrypt(TmpStr, (unsigned char *)hwinfo + 8 * i, NULL, 0); + memcpy(act_req_code + 8 * i, TmpStr, 8); + } + memset(ascii_buf, 0, 128); + BcdToAscii(ascii_buf, act_req_code, k * 16); + + fpConf = fopen("../log/Activation_request_code.txt","w"); + if (fpConf != NULL) { + fprintf(fpConf, "%s\n", ascii_buf); + fclose(fpConf); + } else { + printf("Missing Activation_request_code file!\n"); + return 0; + } + + memset(act_req_code_des, 0, 128); + for (i = 0; i < k; i++) { + memset(TmpStr, 0, 64); + DesCrypt(TmpStr, act_req_code + 8 * i, NULL, 0); + memcpy(act_req_code_des + 8 * i, TmpStr, 8); + } + wxc2HDInfo[0] = k*8; + memcpy(&wxc2HDInfo[1],act_req_code_des,k*8); + printf("Get HD info... OK!\n"); + return 1; +} +#else +static int GetHDInfo() +{ + FILE *fpConf=NULL; + int i,j=0,k; + char ethmac[64]="",meminfo[64]="",cpuinfo[64]="",hwinfo[128]="",*offset,*offset_0, buf[8192]; + char ascii_buf[128] = {0}; + unsigned char TmpStr[64] = {0}, act_req_code[128] = {0}, act_req_code_des[128] = {0}; + int lic_mem_cpu = 0;// 0, new lic; 1, old lic; + //struct stat fileinfo; + + // Ethernet Hardware Address + printf("Get HD info ...\n\n"); + + memset(ethmac, 0, 64); + sprintf(buf,"ip a >../log/ethlog.txt"); + system(buf); + fpConf = fopen("../log/ethlog.txt","r"); + if(fpConf != NULL) + { + fread(buf,2048,1,fpConf); + offset = strstr(buf,"ether "); + if (offset == NULL) + { + offset = strstr(buf,"HWaddr "); + if (offset != NULL) + { + offset += 7; + } + } else { + offset += 6; + } + if (offset != NULL) + { + //offset += 7; + for(i=0,j=0;i<64;i++) + { + if ((*(offset+i)=='\n') || + (*(offset+i)==' ')) + { + ethmac[j] = 0; + break; + } + else if (*(offset+i)==':') + continue; + else + { + ethmac[j] = *(offset+i); + //printf("ethmac[%d] = %c\n", j, ethmac[j]); + j++; + } + } + ethmac[j] = 0; + } + fclose(fpConf); + remove("../log/ethlog.txt"); + } + else + { + printf("Log directory may be missing!\n"); + return 0; + } + + if(lic_mem_cpu) + { + // Memory + memset(meminfo, 0, 64); + sprintf(buf,"cat /proc/meminfo >../log/memlog.txt"); + system(buf); + fpConf = fopen("../log/memlog.txt","r"); + if(fpConf != NULL) + { + fread(buf,2048,1,fpConf); + offset = strstr(buf,"MemTotal:"); + if (offset != NULL) + { + for(i=0,j=0;i<64;i++) + { + if ((*(offset+i)=='\n') ||(*(offset+i)=='k')) + { + meminfo[j] = 0; + break; + } + else if (isdigit(*(offset+i))) + { + meminfo[j] = *(offset+i); + //printf("meminfo[%d] = %c\n", j, meminfo[j]); + j++; + } + } + meminfo[j] = 0; + } + fclose(fpConf); + remove("../log/memlog.txt"); + + } + else + { + printf("Log directory may be missing!\n"); + return 0; + } + } + else + { + int uuid_or_cpuid=0; //0=CPUID, 1=UUID + memset(meminfo, 0, 64); + sprintf(buf,"sudo dmidecode | grep UUID >../log/cpuIDlog.txt"); + system(buf); + fpConf = fopen("../log/cpuIDlog.txt","r"); + + if(fpConf != NULL) + { + fread(buf,2048,1,fpConf); + offset_0=offset = strstr(buf,"UUID: "); + if (offset != NULL) + { + uuid_or_cpuid = 1; + for(i=6,j=0;i<64;i++) + { + if (*(offset+i)=='\n') + { + meminfo[j] = 0; + break; + } + else if (isdigit(*(offset+i))) + { + meminfo[j] = *(offset+i); + printf("cpuinfo[%d] = %c\n", j, meminfo[j]); + j++; + } + } + } + fclose(fpConf); + remove("../log/cpuIDlog.txt"); + + } + + if(uuid_or_cpuid == 0)//UUID not found + { + sprintf(buf,"sudo dmidecode -t 4 | grep ID >../log/cpuIDlog.txt"); + system(buf); + fpConf = fopen("../log/cpuIDlog.txt","r"); + if(fpConf != NULL) + { + fread(buf,2048,1,fpConf); + offset_0=offset = strstr(buf,"ID: "); + if (offset != NULL) + { + for(i=4,j=0;i<64;i++) + { + if (*(offset+i)=='\n') + { + meminfo[j] = 0; + break; + } + else if (isdigit(*(offset+i))) + { + meminfo[j] = *(offset+i); + printf("cpuinfo[%d] = %c\n", j, meminfo[j]); + j++; + } + } + } + offset = strstr(offset_0+4,"ID: "); + if (offset != NULL) + { + for(i=4;i<64;i++) + { + if (*(offset+i)=='\n') + { + meminfo[j] = 0; + break; + } + else if (isdigit(*(offset+i))) + { + meminfo[j] = *(offset+i); + printf("cpuinfo[%d] = %c\n", j, meminfo[j]); + j++; + } + } + } + fclose(fpConf); + remove("../log/cpuIDlog.txt"); + + } + } + } + +if(lic_mem_cpu) +{ + // CPUInfo + memset(cpuinfo, 0, 64); + sprintf(buf,"cat /proc/cpuinfo >../log/cpuModlog.txt"); + system(buf); + fpConf = fopen("../log/cpuModlog.txt","r"); + if(fpConf != NULL) + { + fread(buf,2048,1,fpConf); + offset = strstr(buf,"cpu family"); + if (offset != NULL) + { + for(i=0,j=0;i<64;i++) + { + if (*(offset+i)=='\n') + { + cpuinfo[j] = 0; + break; + } + else if (isdigit(*(offset+i))) + { + cpuinfo[j] = *(offset+i); + //printf("cpuinfo[%d] = %c\n", j, cpuinfo[j]); + j++; + } + } + } + offset = strstr(buf,"model"); + if (offset != NULL) + { + for(i=0;i<64;i++) + { + if (*(offset+i)=='\n') + { + cpuinfo[j] = 0; + break; + } + else if (isdigit(*(offset+i))) + { + cpuinfo[j] = *(offset+i); + //printf("cpuinfo[%d] = %c\n", j, cpuinfo[j]); + j++; + } + } + } + offset = strstr(buf,"cache size"); + //offset = strstr(buf,"cpu MHz"); + //offset = strstr(buf,"bogomips"); + if (offset != NULL) + { + for(i=0;i<64;i++) + { + if (*(offset+i)=='\n') + { + cpuinfo[j] = 0; + break; + } + else if (*(offset+i) == 'K') + { + //continue; + break; + } + else if (isdigit(*(offset+i))) + { + cpuinfo[j] = *(offset+i); + //printf("cpuinfo[%d] = %c\n", j, cpuinfo[j]); + j++; + } + } + cpuinfo[j] = 0; + } + fclose(fpConf); + remove("../log/cpuModlog.txt"); + + } + else + { + printf("Log directory may be missing!\n"); + return 0; + } +} + + strcpy(hwinfo, ""); + strcat(hwinfo, ethmac); + i = j = strlen(ethmac); + hwinfo[i++] = ethmac[0]; + hwinfo[i++] = ethmac[1]; + hwinfo[i++] = ethmac[2]; + hwinfo[i++] = ethmac[3]; + hwinfo[i] = 0; + strcat(hwinfo, meminfo); + j = strlen(meminfo); + i += j; + hwinfo[i++] = ethmac[4]; + hwinfo[i++] = ethmac[5]; + hwinfo[i++] = ethmac[6]; + hwinfo[i++] = ethmac[7]; + hwinfo[i] = 0; + if (lic_mem_cpu) + { + strcat(hwinfo, cpuinfo); + j = strlen(cpuinfo); + i += j; + } + hwinfo[i++] = ethmac[8]; + hwinfo[i++] = ethmac[9]; + hwinfo[i++] = ethmac[10]; + hwinfo[i++] = ethmac[11]; + hwinfo[i] = 0; + + j = strlen(hwinfo); + if (j == 0) + { + printf("Missing Activation Request Info!\n"); + return 0; + } + + k = (j + 7) / 8; + //printf("hwinfo: %s, len: %d, segment: %d\n", hwinfo, j, k); + memset(hwinfo + j, '0', 128 - j); + + memset(act_req_code, 0, 128); + for (i = 0; i < k; i++) + { + memset(TmpStr, 0, 64); + DesCrypt(TmpStr, (unsigned char *)hwinfo + 8 * i, NULL, 0); + memcpy(act_req_code + 8 * i, TmpStr, 8); + } + memset(ascii_buf, 0, 128); + BcdToAscii(ascii_buf, act_req_code, k * 16); + + fpConf = fopen("../log/Activation_request_code.txt","w"); + if (fpConf != NULL) + { + fprintf(fpConf, "%s\n", ascii_buf); + fclose(fpConf); + } + else + { + printf("Missing Activation_request_code file!\n"); + return 0; + } + + memset(act_req_code_des, 0, 128); + for (i = 0; i < k; i++) + { + memset(TmpStr, 0, 64); + DesCrypt(TmpStr, act_req_code + 8 * i, NULL, 0); + memcpy(act_req_code_des + 8 * i, TmpStr, 8); + } + //memset(ascii_buf, 0, 128); + //BcdToAscii(ascii_buf, act_req_code_des, k * 16); + //printf("Activation request code DES: %s\n", ascii_buf); + wxc2HDInfo[0] = k*8; + memcpy(&wxc2HDInfo[1],act_req_code_des,k*8); + printf("Get HD info... OK!\n"); + return 1; +} +#endif + +static void SaveWxc2SystemConf() +{ + FILE *fpConf=NULL; + char filename[]="./conf/system.ini"; + + fpConf = fopen(filename,"w"); + if(fpConf==NULL){ + return; + } + fwrite(&wxc2_param,sizeof(wxc2_param),1,fpConf); + fclose(fpConf); +} + +static void UpdateWXC2License() +{ + FILE *fpConf=NULL; + FILE *fpFIB=NULL; + char buf[512],output[256]; + u_char data[8]; + int i,len,newLicense,dif; + + char filename[]="/usr/local/subsManage/system.ini"; + struct stat fileinfo; + + memset(&tmpParam,0,sizeof(tmpParam)); + + fpFIB = fopen("/usr/local/subsManage/fib.txt","w"); + + fpConf = fopen(filename,"r"); + if(fpConf==NULL){ + fprintf(fpFIB,"Cann't open config file:system.ini\n"); + fclose(fpFIB); + return; + } + + stat(filename,&fileinfo); + if(fileinfo.st_size < sizeof(wxc2_param)) + { + fprintf(fpFIB,"Error file length: %d, should be: %lu\n", + (int)fileinfo.st_size, sizeof(wxc2_param)); + fclose(fpFIB); + fclose(fpConf); + remove(filename); + return; + } + + fread(&tmpParam,sizeof(wxc2_param),1,fpConf); + fclose(fpConf); + + rename(filename,"/usr/local/subsManage/system.ini.OLD"); + + if(tmpParam.systemType != wxc2_param.systemType) + { + fprintf(fpFIB,"Wrong FIB file: system type (%s) is not the same as the current one (%s)\n", + systemTypeName[tmpParam.systemType], + systemTypeName[wxc2_param.systemType]); + fclose(fpFIB); + return; + } + if(memcmp(tmpParam.serialNumber,wxc2_param.serialNumber,8)) + { + fprintf(fpFIB,"Wrong FIB file: serial number is not correct.\n"); + fclose(fpFIB); + return; + } +/* + if(!systemID) + { + if(!CheckHDLicense(tmpParam.HDSerialNumber[0])) + { + fprintf(fpFIB,"Wrong FIB file: Hardware codeis not correct.\n"); + fclose(fpFIB); + return; + } + } + else + { + if(!CheckHDLicense(tmpParam.HDSerialNumber[1])) + { + fprintf(fpFIB,"Wrong FIB file: Hardware codeis not correct.\n"); + fclose(fpFIB); + return; + } + } +*/ + for(i=0;i wxc2_license_rule[i].maxValue) + { + fprintf(fpFIB,"Wrong license value: %s license can't be greater than maxValue %d\n", + wxc2_license_rule[i].name, wxc2_license_rule[i].maxValue); + fclose(fpFIB); + return; + } + if (wxc2_license_rule[i].dir == ONLY_INCREASABLE) + { + if (newLicense < wxc2_param.userIntLicense[i]) + { + fprintf(fpFIB,"Wrong license value: %s license can't be less than before,old=%d,now=%d\n", + wxc2_license_rule[i].name,wxc2_param.userIntLicense[i],newLicense); + fclose(fpFIB); + return; + } + } + else if (wxc2_license_rule[i].dir == ONLY_DECREASABLE) + { + if (newLicense > wxc2_param.userIntLicense[i]) + { + fprintf(fpFIB,"Wrong license value: %s license can't be greater than before\n", + wxc2_license_rule[i].name); + fclose(fpFIB); + return; + } + } + + if (newLicense >= wxc2_param.userIntLicense[i]) + dif = newLicense - wxc2_param.userIntLicense[i]; + else + dif = wxc2_param.userIntLicense[i] - newLicense; + + if (dif > 0) + { // if dif equals 0, means no change at all + if (dif % wxc2_license_rule[i].step) + { + fprintf(fpFIB,"Wrong license value: %s license should change by step %d\n", + wxc2_license_rule[i].name, wxc2_license_rule[i].step); + fclose(fpFIB); + return; + } + } + } + + + if(tmpParam.license_date[0] == 0 && + tmpParam.license_date[1] == 0 && + tmpParam.license_date[2] == 0) + { + tmpParam.license_date[0] = 99; + tmpParam.license_date[1] = 12; + tmpParam.license_date[2] = 31; + } + memcpy(&wxc2_param,&tmpParam,sizeof(wxc2_param)); + rename("./conf/system.ini","./conf/system.ini.OLD"); + SaveWxc2SystemConf(); + + /* set FIB file */ + fprintf(fpFIB,"[ system info ]\n"); + fprintf(fpFIB,"software version=R9.0\n"); + switch(wxc2_param.systemType) + { + case 0: + fprintf(fpFIB,"system type=NIB\n"); + break; + case 1: + fprintf(fpFIB,"system type=X40\n"); + break; + case 2: + fprintf(fpFIB,"system type=X100\n"); + break; + } + fprintf(fpFIB,"\n"); + + fprintf(fpFIB,"[ deployment info ]\n"); + fprintf(fpFIB,"serial number=%s\n",serialNumber); + + len = wxc2_param.HDSerialNumber[0][255]; + for(i=0;i> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7 + else + crc = (crc >> 1); + } + } + return ~crc; +} + +static int check_license_file_validity(struct _wxc2_param *param_ptr) +{ + unsigned int check_sum = 0; + unsigned int licensed_check_sum = 0; + char license_date[128], e_license_date[128]; + + if(param_ptr == NULL) + { + goto invalid_license; + } + + check_sum = crc32((unsigned char *)param_ptr, sizeof(struct _wxc2_param)-4); + memcpy(&licensed_check_sum, ¶m_ptr->userIntLicense[MAX_LICENSE_TYPE-1], 4); + + if(check_sum != licensed_check_sum) + goto invalid_license; + + if(1) + { + char year[5], month[3], day[3]; + memcpy(e_license_date, ¶m_ptr->userIntLicense[250], 8); + DesCrypt(license_date,e_license_date, NULL,1); + memcpy(year, license_date, 4); + year[4] = 0; + memcpy(month, &license_date[4], 2); + month[2] = 0; + memcpy(day, &license_date[6], 2); + day[2] = 0; + + param_ptr->license_date[0] = atoi(year) - 2000; + param_ptr->license_date[1] = atoi(month); + param_ptr->license_date[2] = atoi(day); + } + + return 1; + +invalid_license: + printf("invalid license\r\n"); + exit(110); + + return 0; +} + +static +void ReadSystemConf() +{ + FILE *fpConf=NULL; + int i,flag=0; + // char hostname[128]; + char filename[]="./conf/system.ini"; + struct stat fileinfo; + u_char data[8]; + + fpConf = fopen(filename,"r"); + if(fpConf==NULL){ + printf("Cann't open config file\n"); + printf("Please check directory and conf file\n"); + printf("Failed to continue!\n"); + exit(1); + } + stat(filename,&fileinfo); + /* + if(fileinfo.st_size != sizeof(wxc2_param)) + { + // don't set license when initialized + //updateFromLowVersion = 1; + } + */ + fread(&wxc2_param,sizeof(wxc2_param),1,fpConf); + fclose(fpConf); + + // add descrypt and crc check========================= + char buf[128]; + AsciiToBcd(buf,wxc2_param.serialNumber,16); + DesCrypt((unsigned char *)serialNumber,buf,NULL,1); + check_license_file_validity(&wxc2_param); + // =================================================== + + /* + if(updateFromLowVersion) + { + memcpy(wxc2_param.HDSerialNumber[1],wxc2_param.HDSerialNumber,256); + } + */ + + for(i=0;ih_addr_list)),ch_ptr) != 0) + //{ + // printf("Error ip address\n"); + // return 0; + //} + systemID = temp_info[strlen(temp_info)-1] - '0'; + if (systemID > 5) + { + printf("Error system id\n"); + return 0; + } + wxc_localip = inet_addr(ch_ptr); //((struct in_addr *)(*pcn->h_addr_list))->s_addr; + strcpy(wxc_localip_str, ch_ptr); + } + else + { + if (!inet_aton(ch_ptr,&temp_addr)) + { + printf("Can not get peer ip address\n"); + return 0; + } + wxc_peerip = temp_addr.s_addr; + strcpy(wxc_peerip_str, ch_ptr); + } + } //for + }//while + + } + hb_no = heartbeat_no; + hb_no <<=8; + if(hb_sub_no) + hb_no |= hb_sub_no; + else + hb_no |= systemID; + fclose(fp); + return 1; +} + +static void +wxc2HBinit() +{ +// hb_no = heartbeat_no; +// hb_no <<=8; +// hb_no |= systemID; + + heartbeat_init(hb_no); +} + +void LogModuleStartState( int nType , char *Module , int nResult ) +{ + char sType[32]; + char sResult[32]; + char sModule[32]; + + if( strlen(Module) > 10 ) + { + printf("LogModuleStartState:too long module name!\n"); + return; + } + strcpy(sModule, Module ); + TxtColor(BRIGHT,WHITE,BLACK,sModule); + if( nType ) + { + strcpy(sType , "Application"); + } + else + { + strcpy(sType , "Platform"); + } + + if( nResult ) + { + strcpy(sResult , " OK "); + TxtColor(BRIGHT,GREEN,BLACK,sResult); + } + else + { + strcpy(sResult , "Fail"); + TxtColor(BRIGHT,RED,BLACK,sResult); + } + printf("Initialing %s %s Module: \t\t\t\t[ %s ]\n",sType,sModule,sResult); +} + +static +void moduleInit() +{ + int ret = 0; + printf("\n\n[R9 Platform Init]\n\n"); + + debug_init(); + LogModuleStartState( 0, "DEBUG" , 1); + + ret = iptrMainInit(); + LogModuleStartState( 0, "IPTR" , ret); + + snmp_init(4957); + LogModuleStartState( 0, "SNMP" , ret); + snmp_init_serial_number(serialNumber); + if(noTimeSyncFlag == 1) + snmp_set_timenosync(); + + if( !wxc2_param.register_flag[RMC_]) + { + + m2ua_init(systemID); + LogModuleStartState( 0, "M2UA" , ret); + +// mtp_shm_init(0x900|systemID); + mtp_shm_init(hb_no, wxc_localip, wxc_peerip); + LogModuleStartState( 0, "MTP3" , 1); + mtp3_init_serial(serialNumber); + + sccp_init(systemID, wxc_localip, wxc_peerip); + LogModuleStartState( 0, "SCCP" , 1); + sccp_init_serial_number((BYTE *)serialNumber); + + ret = smpp_init_new(systemID); + LogModuleStartState( 0, "SMPP" , ret); + + tcap_init(plat_work_port,wxc_localip,wxc_peerip); + LogModuleStartState( 0, "TCAP" , 1); + + xap_init(plat_work_port); + LogModuleStartState( 0, "XAPP" , 1); + + radius_init(); + LogModuleStartState( 0, "RADIUS" , 1); + + tcp_init(); + LogModuleStartState( 0, "TCP" , 1); + } + + if (wxc2_param.register_flag[PPS_]) + { + scsm_init(); + LogModuleStartState( 0, "SCF" , 1); + } + + wxc2HBinit(); + LogModuleStartState( 0, "HB" , 1); + + cdr_init(systemID, 0); + + + printf("\n\n[R9 Platform Init completed]\n\n"); + inquire_setmsg(11,WXC2_OID_PREFIX, (setcall)snmpSetWXC2); + inquire_getmsg(11,WXC2_OID_PREFIX, (getcall)snmpGetWXC2); +} + +static void moduleProc() +{ + //static int wait_sccp_normal_count = 0; + //static BYTE t20ms = 0; + + segmentLog->tmnow = time(NULL); + + segmentLog->sub_state = 0; + sub_state = 0; + iptrans_timer(); + + segmentLog->sub_state ++; + sub_state ++; + snmp_timer(); + + segmentLog->sub_state ++; + sub_state ++; + heartbeat_timer(); + + + segmentLog->sub_state ++; + sub_state ++; + debug_rt(); + + if (wxc2_main_state == WXC2_NORMAL) + //if(wait_sccp_normal_count++>30)/*wait for 30secs */ + { + //wait_sccp_normal_count=6001; + + segmentLog->sub_state ++; + sub_state ++; + m2ua_timer(); + + + segmentLog->sub_state ++; + sub_state ++; + mtp3_proc(); + + + segmentLog->sub_state ++; + sub_state ++; + sccp_timer(); + + segmentLog->sub_state ++; + sub_state ++; + tcap_fsm(); + + segmentLog->sub_state ++; + sub_state ++; + smpp_fsm_new(); + + segmentLog->sub_state ++; + sub_state ++; + xap_fsm(); + + segmentLog->sub_state ++; + sub_state ++; + radius_timer(); + + segmentLog->sub_state ++; + sub_state ++; + tcp_timer(); + } + + if (wxc2_param.register_flag[PPS_]) + { + segmentLog->sub_state ++; + sub_state ++; + scsm(); + } + +} + +void RecordLogInfo() +{ + int shm_id; + FILE *fpTmp=NULL; + + shm_id = shmget(WXC2_SHM_KEY+wxc2_get_shm_offset(),1024,WXC2_SHM_PERM | IPC_CREAT); + if(shm_id == -1) + return; + segmentLog = (segLog *)shmat(shm_id,(char *)0,0); + if(segmentLog == (void *) -1) + { + printf("get shm failed\n"); + exit(127); + } + fpTmp = fopen("../log/wxc2_log.txt","w"); + if(fpTmp == NULL) return ; + fprintf(fpTmp,"time: %ld\n",segmentLog->tmnow); + fprintf(fpTmp,"app_state: %d\n",segmentLog->app_state); + fprintf(fpTmp,"sub_state: %d\n",segmentLog->sub_state); + fclose(fpTmp); +} + +int wxc2_get_license(int functionID) +{ + if (functionID >= MAX_License_ID) + return -1; + + return wxc2_param.userIntLicense[functionID]; +} + +u_long wxc2_get_localip(char *ip_str) +{ + if(ip_str != NULL) + strcpy(ip_str,wxc_localip_str); + return wxc_localip; +} + +u_long wxc2_get_peerip(char *ip_str) +{ + if(ip_str != NULL) + strcpy(ip_str,wxc_peerip_str); + return wxc_peerip; +} + + +#define WXC2_STARTUP_COMPLETED 1 + +int wxc2_startup(u8 no_sync) +{ + struct termio prev_termio; + + switch(wxc2_startup_state) + { + case 0: + if(wxc2_param.register_flag[PPS_]) + { + if(pps_init((wxc2_param.max_users[PPS_])%DEFAULT_USERS, + systemID,wxc_localip,wxc_peerip,serialNumber,no_sync)) + { + LogModuleStartState( 1 , "PPS" , 1); + wxc2SetTermSignal(&prev_termio,wxc2Terminate); + printf("wxc2 initram ...\n"); + + systemInited = 1; + wxc2HBinit(); + + wxc2_update_version("Normal"); + debug_change_title1(); + return WXC2_STARTUP_COMPLETED; + } + } + else + { + wxc2_startup_state = 0; + + wxc2SetTermSignal(&prev_termio,wxc2Terminate); + + systemInited = 1; + outb(0x05,0x37a); + wxc2HBinit(); + + wxc2_update_version("Normal"); + debug_change_title1(); + return WXC2_STARTUP_COMPLETED; + } + break; + default: + wxc2_startup_state = 0; + break; + } + return 0; +} + +void wxc2_normal_running() +{ + static int license_check_timer=0; + + if(license_check_timer++ == 360000) /* every hour */ + { + license_check_timer = 0; + //CheckLicenseExpire(); + } + switch (app_state) + { + case 0: + app_state = 0; + segmentLog->app_state = app_state; + segmentLog->sub_state =50; + sub_state =50; + if (wxc2_param.register_flag[PPS_]) + { + pps_proc(); + } + break; + default: + app_state = 0; + break; + } +} + +int isWxc2mainNormal() +{ + if(wxc2_main_state == WXC2_NORMAL) + return TRUE; + return FALSE; +} + +int main(int argc, char **argv) +{ + int retval, err_flag=0, daemon_flag=0, no_sync=0; + char buf[32]=""; + struct itimerval tv; + char checkPidFile[32]="./pidofwxc2.txt"; + char checkPidCommand[128]="pidof agtocs 2>./pidofwxc2.txt 1>&2"; + FILE *fpPid=NULL; + //BYTE in; + + system(checkPidCommand); + fpPid = fopen(checkPidFile,"r"); + if(fpPid !=NULL) + { + int len,i; + char record[32]; + memset(record,0,32); + fread(record,32,1,fpPid); + len = strlen(record); + if(len>2) + for(i=0;isub_state =20; + segmentLog->app_state = 20; + + //gx_handle_msg_cb(); + gx_fsm(main_now.tv_sec, main_now.tv_usec%1000); + + + } + if (sys_timer10ms == 0) + { + if(Linux_OS_Release == OS_ES4) + usleep(1); + else + usleep(1000); + + } + } + return 1; +} + + diff --git a/mss/main/wxc2d b/mss/main/wxc2d new file mode 100644 index 0000000..2e2b808 --- /dev/null +++ b/mss/main/wxc2d @@ -0,0 +1,83 @@ +#!/bin/sh +# chkconfig: 2345 99 19 +# description: as following +# CVS $Id: wxc2d,v 1.1 2002/11/16 12:00:00 LiangHB Exp $ +# Startup processes relative with app function + +if [ `whoami` != "root" ] ; then + echo "Permission denied! Only user root supported!" + exit +fi +PATH=/usr/sbin:/usr/local/bin:/bin:/usr/bin ; export PATH +basedir=/usr/local/wxc2 +bindir=$basedir/bin +WXC2_BIN_DIR=/usr/local/wxc2/bin ; export WXC2_BIN_DIR +LOG_FILE_PATH=$basedir/log ; export LOG_FILE_PATH + +KILL_LEVEL=15 + +SERVICE_ALL="wxc2main" + +. /etc/rc.d/init.d/functions + + +case "$1" in + 'start') + # Start daemon + backupMB=`du -m /usr/local/backup |awk '{print $1}'` + if [ $backupMB -gt 90 ] ; then + backupMB=90 + fi + freeDiskMB=`df -m /usr|grep dev|awk '{print $4}'` + MinMB=`expr 150 "-" $backupMB` + echo "There are $freeDiskMB M available in /usr" + if [ $freeDiskMB -lt $MinMB ] ; then + echo "mss need $MinMB m disk space at least,No enough space in /usr !!" + df -h + exit + fi + + + + crontab -u root /usr/local/wxc2/tools/cronset + cd $bindir + + SERVICE_NAME=wxc2main + echo -n "Starting $SERVICE_NAME service:" + ./$SERVICE_NAME -d 2>/dev/null + echo + ;; + 'stop') + # Stop daemon + backupMB=`du -m /usr/local/backup |awk '{print $1}'` + if [ $backupMB -gt 90 ] ; then + backupMB=90 + fi + freeDiskMB=`df -m /usr|grep dev|awk '{print $4}'` + MinMB=`expr 150 "-" $backupMB` + echo "There are $freeDiskMB M available in /usr" + if [ $freeDiskMB -lt $MinMB ] ; then + echo "mss need $MinMB m disk space at least,No enough space in /usr !!" + df -h + exit + fi + + crontab -r + SERVICE_NAME=wxc2main + echo -n "Shutting down $SERVICE_NAME service:" + killproc $SERVICE_NAME -$KILL_LEVEL + echo + sleep 2 + ;; + 'status') + # get status of daemon + + SERVICE_NAME=wxc2main + status $SERVICE_NAME + ;; + *) + # usage + echo "usage: $0 start|stop|status" + exit 1 + ;; +esac diff --git a/mss/pps/Makefile b/mss/pps/Makefile new file mode 100644 index 0000000..4a78642 --- /dev/null +++ b/mss/pps/Makefile @@ -0,0 +1,31 @@ +all: + @cd ./src/lib; make; cd ..; cd .. + @cd ./src/main; make; cd ..; cd .. + @cd ./src/object; make; cp libpps.a ../../lib; cd ..; cd .. + +cook_island: + @cd ./src/lib; make; cd ..; cd .. + @cd ./src/main; make -f Cook_Makefile; cd ..; cd .. + @cd ./src/object; make; cp libpps.a ../../lib; cd ..; cd .. + +zed_mobile: + @cd ./src/lib; make; cd ..; cd .. + @cd ./src/main; make -f Zed_Makefile; cd ..; cd .. + @cd ./src/object; make; cp libpps.a ../../lib; cd ..; cd .. + +rdb_tariff: + @cd ./src/lib; make; cd ..; cd .. + @cd ./src/main; make -f Rdb_Makefile; cd ..; cd .. + @cd ./src/object; make; cp libpps.a ../../lib; cd ..; cd .. + +clean: + @cd ./src/lib; make clean; cd ..; cd .. + @cd ./src/main; make clean; cd ..; cd .. + @cd ./src/object; make clean; cd ..; cd .. + @cd ./lib; rm -f libpps.a; cd .. + +touch: + @cd ./src/lib; touch *.c; cd ..; cd .. + @cd ./src/main; touch *.c; cd ..; cd .. + +rebuild: clean all diff --git a/mss/pps/build_redis.txt b/mss/pps/build_redis.txt new file mode 100644 index 0000000..e3b46b1 --- /dev/null +++ b/mss/pps/build_redis.txt @@ -0,0 +1,16 @@ +1)ppsm.h: #define OCS_USE_REDIS_DB 1 +2)pps/src/main/Makefile + pps_OBJ = ... pps_redis.o + pps_redis.o:pps_redis.c + $(COMPILE.c) -c pps_redis.c $(INCLUDES) +3)pps/src/object/makefile + ar r ... pps_redis.o +4)mss/main/Makefile + -lhiredis + +5)gnutls版本ä¸�兼容,因为diameter没有用到tls,所以注释掉这几行tls代ç �ï¼› +../../plat/diameter/lib//libdiameter.a(config.o): In function `fd_conf_parse': +/root/build/OCS_CRM/plat/diameter/libfdcore/config.c:473: undefined reference to `gnutls_certificate_get_x509_cas' +/root/build/OCS_CRM/plat/diameter/libfdcore/config.c:474: undefined reference to `gnutls_certificate_get_x509_crls' +../../plat/diameter/lib//libdiameter.a(sctp3436.o): In function `set_sess_transport': +/root/build/OCS_CRM/plat/diameter/libfdcore/sctp3436.c:284: undefined reference to `gnutls_transport_set_lowat' diff --git a/mss/pps/src/include/Makefile.am b/mss/pps/src/include/Makefile.am new file mode 100644 index 0000000..f3dbd73 --- /dev/null +++ b/mss/pps/src/include/Makefile.am @@ -0,0 +1,18 @@ +## +## PACS-WLL 2000 project, Prepaid System. +## +## module Copyright (C) 2000-2001 interWAVE Inc. +## Written completely by Zhang Shuzhong at iCRD February, 2001 +## +## file name: Makefile.am +## CVS $Id: Makefile.am,v 1.1 2001/06/28 07:21:15 zhangsz Exp $ +## +## Process this file with automake to create Makefile.in +## + +noinst_HEADERS = cdrme.h beat.h ppsm.h ppsinf.h \ + includes.h public.h function.h \ + iptrans.h sqlfunc.h debug.h \ + errlog.h config.h logfunc.h crypt.h version.h mfunc.h \ + ramdata.h message.h tariff.h ppsoid.h ppcron.h \ + iofunc.h ppscsta.h diff --git a/mss/pps/src/include/Makefile.in b/mss/pps/src/include/Makefile.in new file mode 100644 index 0000000..8ef528d --- /dev/null +++ b/mss/pps/src/include/Makefile.in @@ -0,0 +1,236 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +CC = @CC@ +CHMOD = @CHMOD@ +MAKEINFO = @MAKEINFO@ +MV = @MV@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +RM = @RM@ +SED = @SED@ +VERSION = @VERSION@ + +noinst_HEADERS = cdrme.h beat.h ppsm.h ppsinf.h includes.h public.h function.h iptrans.h sqlfunc.h debug.h errlog.h config.h logfunc.h crypt.h version.h mfunc.h ramdata.h message.h tariff.h ppsoid.h ppcron.h iofunc.h ppscsta.h + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = ./stamp-h.in Makefile.am Makefile.in acconfig.h \ +config.h.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps include/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=include/config.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.h.in: $(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = include + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(HEADERS) config.h +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-hdr clean-tags clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-hdr distclean-tags distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +tags mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \ +distdir info-am info dvi-am dvi check check-am installcheck-am \ +installcheck all-recursive-am install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/mss/pps/src/include/acconfig.h b/mss/pps/src/include/acconfig.h new file mode 100644 index 0000000..5b1d440 --- /dev/null +++ b/mss/pps/src/include/acconfig.h @@ -0,0 +1,98 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you don't have vprintf but do have _doprnt. */ +#undef HAVE_DOPRNT + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define if you have the vprintf function. */ +#undef HAVE_VPRINTF + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if your declares struct tm. */ +#undef TM_IN_SYS_TIME + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you don't have vprintf but do have _doprnt. */ +#undef HAVE_DOPRNT + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define if you have the vprintf function. */ +#undef HAVE_VPRINTF + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if your declares struct tm. */ +#undef TM_IN_SYS_TIME + +/* Define if you have __FILE__ macro */ +#undef HAVE_FILE_MACRO + +/* Define if you have __FUNCTION__ macro */ +#undef HAVE_FUNCTION_MACRO + +/* Define if you have __LINE__ macro */ +#undef HAVE_LINE_MACRO + +/* Define if you have __DATE__ macro */ +#undef HAVE_DATE_MACRO + +/* Define if you have __TIME__ macro */ +#undef HAVE_TIME_MACRO + +/* Define if you have the socket function. */ +#undef HAVE_SOCKET + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + diff --git a/mss/pps/src/include/callingCard.h b/mss/pps/src/include/callingCard.h new file mode 100644 index 0000000..08a31c3 --- /dev/null +++ b/mss/pps/src/include/callingCard.h @@ -0,0 +1,81 @@ +#ifndef _CALLINGCARD_H + +#define _CALLINGCARD_H + +#include "voiceID.h" + +enum _CALLING_CARD_OPERATION +{ + ExitCallingCard = 0, + MakeCall = 1, + InquiryBlance, + RechargeAccout, + ChangePassword, + TransferAccount +}; + + +#ifndef pin_mng_keep_state_value +#define pin_mng_keep_state_value +typedef enum pin_mng_retval +{ + pin_mng_keep_state = 0, + pin_mng_exit, + pin_mng_exit_to_main_menu, +}_pin_mng_retval; +#endif + +enum callingCardMainState +{ + entryCallingCard = 0, + sendMainMenu, + chooseFunction, + runFunction, + exitCallingCardSys +}; + +enum entryCallingCardState +{ + callingCardIdle = 0, + returnMainMenu, + inputCallingCardAccount = 2, + waitForCallingCardAccount, + inputCallingCardAccountPassword, + checkCallingCardAccountPassword, + entrySuccess +}; + +enum makeCallState +{ + requireInputCalledNumber = 2, + waitForCalledNumber, + requireRouteCalled, + waitSpecialResourceReport, + waitForRouteResult, +}; + +enum rechargeAccountState +{ + rechargeAccount = 2 +}; + +enum inquiryAccountSate +{ + inquiryAccount = 2 +}; + +enum transferAccountState +{ + inputTransferOutAccount = 2, + waitForInputTransferOutAccount, + inputTransferOutAccountPassword, + waitForInputTransferOutAccountPassword, + checkTransferOutAccountPassword, + transferToCurrentAccount, + transferSuccess, + transferFail +}; + + +#endif + diff --git a/mss/pps/src/include/cdrme.h b/mss/pps/src/include/cdrme.h new file mode 100644 index 0000000..53d22b3 --- /dev/null +++ b/mss/pps/src/include/cdrme.h @@ -0,0 +1,144 @@ +/* +** +** +** file name: cdrme.h +** +** Defination for CDR(call detail record) management entity (cdrme.c). +*/ + +#ifndef CDRME__H +#define CDRME__H + +#include "report.h" + +#define MO_CDR_TYPE 0x00 +#define MT_CDR_TYPE 0x01 +#define SC_CDR_TYPE 0x02// selfcare cdr +#define MAX_CDR_LEN 8192 +#define MAX_CSTA_LEN 96 + +typedef struct _tocdr_record { + char mtype[2]; + char type[4]; + char imsi[16]; + char msisdn[18]; + char msrn[18]; + char caller[18]; + char called[24]; + char re[16]; + char intkgp[6]; + char outkgp[6]; + char lac[10]; + char bs[4]; + char ss[4]; + char mobclassmark[16]; + char seizuretime[18]; + char answertime[18]; + char releasetime[18]; + char duration[8]; + char tcos[4]; + char ssa[4]; + char ssparam[16]; + char ssr[4]; + char cr[4]; + char rcu[2]; + char charge[8]; + char balance[8]; +} _tocdr_record; + +typedef struct _tocdr_report { + u_long squence; + BYTE mtype; + BYTE type[2]; + BYTE imsi[8]; + BYTE msisdn[9]; + BYTE msrn[9]; + BYTE caller[9]; + BYTE called[12]; + BYTE re[8]; + BYTE intkgp[3]; + BYTE outkgp[3]; + BYTE lac[5]; + BYTE bs[2]; + BYTE ss[2]; + BYTE mobclassmark[8]; + BYTE seizuretime[9]; + BYTE answertime[9]; + BYTE releasetime[9]; + BYTE duration[4]; + BYTE tcos[2]; + BYTE ssa[2]; + BYTE ssparam[8]; + BYTE ssr[2]; + BYTE cr[2]; + BYTE rcu; + BYTE charge[4]; + BYTE balance[4]; + BYTE cos_id; + BYTE gprsSgsnIP[64]; + BYTE gprsGgsnIP[64]; + BYTE gprsDestIP[64]; + BYTE gprsVolume[4]; + BYTE peerAddress[128]; + BYTE plan_id[4]; +} _tocdr_report; + +/* +typedef struct _pps_cdr_buffer{ + u_short pReadSub; + u_short pWriteSub; + _tocdr_report cdr_record[MAX_CDR_LEN]; + u_char flag[MAX_CDR_LEN]; +}_pps_cdr_buffer; +*/ +typedef struct _pps_cdr_buffer{ + u_short pReadSub; + u_short pWriteSub; + u_char flag[MAX_CDR_LEN]; + u_char cdrMsg[MAX_CDR_LEN][256]; /* byte0=len; byte1-255=msg */ +}_pps_cdr_buffer; + + +#define PPS_CSTA_TYPES MAX_SERVICE_TYPE //MAX_CALL_TYPE +#define PPS_CSTA_TYPE_BASE 100 +typedef struct _pps_csta_items +{ + long number; + long charge; + long duration; + long gprsVolume; +}_pps_csta_items; + +typedef struct _pps_vas_csta_items +{ + u_long smsNumber; + long smsCharge; + u_long mmsSendNumber; + long mmsSendCharge; + u_long mmsRetrieveNumber; + long mmsRetrieveCharge; + u_long mmsEmailNumber; + long mmsEmailCharge; +}_pps_vas_csta_items; + +typedef struct _pps_csta_record +{ + u_long timestamp; + _pps_csta_items csta_type[PPS_CSTA_TYPES]; + _pps_csta_items gprsCsta; + _pps_vas_csta_items vasCsta; +}_pps_csta_record; + +typedef struct _pps_csta_buffer +{ + _pps_csta_record csta_record[MAX_CSTA_LEN]; +}_pps_csta_buffer; + +// fix multiple definition==================================== +extern _pps_cdr_buffer pps_cdr_buffer; +extern _pps_csta_buffer pps_csta_buffer; +// + +int encodePPS_MO_CDR(_tocdr_report *pcdr,u_char *pdata); +int encodePPS_MT_CDR(_tocdr_report *pcdr,u_char *pdata); +#endif /* CDRME__H */ diff --git a/mss/pps/src/include/config.h b/mss/pps/src/include/config.h new file mode 100644 index 0000000..a066b7b --- /dev/null +++ b/mss/pps/src/include/config.h @@ -0,0 +1,126 @@ +/* include/config.h. Generated automatically by configure. */ +/* include/config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if your declares struct tm. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if your declares struct tm. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if your declares struct tm. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define if you have __FILE__ macro */ +#define HAVE_FILE_MACRO 1 + +/* Define if you have __FUNCTION__ macro */ +#define HAVE_FUNCTION_MACRO 1 + +/* Define if you have __LINE__ macro */ +#define HAVE_LINE_MACRO 1 + +/* Define if you have __DATE__ macro */ +#define HAVE_DATE_MACRO 1 + +/* Define if you have __TIME__ macro */ +#define HAVE_TIME_MACRO 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "prepaid" + +/* Version number of package */ +#define VERSION "1.0.04" + diff --git a/mss/pps/src/include/crd.h b/mss/pps/src/include/crd.h new file mode 100644 index 0000000..b4e3749 --- /dev/null +++ b/mss/pps/src/include/crd.h @@ -0,0 +1,34 @@ +#ifndef _CRD_H +#define _CRD_H + +#include + + +typedef enum _routeMethod +{ + ByPrefix = 0, + ByWholeNumber +}routeMethod; + +typedef enum _NumberMethod +{ + ByCaller = 0, + ByCalled +}NumberMethod; + +/* call re-direct */ + +#define MAX_DIGITS_LEN 16 + + +int IsCRDServiceNumber(char *number); +/* retval=0/1, no/yes */ + +int IsPostpaidAllowed(); +/* retval=0/1, no/yes */ + +int GetCRDDestination(char *src_number, char *dst_number,u_char type); +int CheckCRDRingBackServiceKey(int serviceKey); +/* retval=0/1, not find/find match destination */ + +#endif diff --git a/mss/pps/src/include/debug.h b/mss/pps/src/include/debug.h new file mode 100644 index 0000000..c316af5 --- /dev/null +++ b/mss/pps/src/include/debug.h @@ -0,0 +1,110 @@ +/* +** +** file name: debug.h +** +** The debug information defination. +** +*/ + +#ifndef DEBUG__H +#define DEBUG__H +#include "config.h" + +void +DebugMsg(void *ptr, const char *fmt, ...); +void +DebugRet(void *ptr, const char *fmt, ...); +void +DebugMsgDelimiter(); +BOOL +WriteDebugMsg(void *dest, const void *src); +#define DebugFlag(shmp) \ + DebugMsg(shmp, "%s: %s: %d", FILE_MACRO, FUNCTION_MACRO, LINE_MACRO) + +#define WriteContentToDebugBuffer(shmp, buf, bcd_buf, nbytes) \ + BcdToAscii(buf, bcd_buf, 2 * nbytes); \ + DebugMsg(shmp, "packets contains (%s):\n%s", FUNCTION_MACRO, buf); + +#define WriteSendMessageToDebugBuffer(shmp, pbuf) \ + DebugMsg(shmp, "=================================================="); \ + DebugMsg(shmp,"Send packet to %s %d Length=%d", \ + Inet_ntoa(pbuf->msgDstIP), pbuf->msgDstPort, \ + pbuf->msgLength); \ + gettimeofday(&tv, NULL); \ + DebugMsg(shmp,"Current time: %s (%ld.%06ld)", \ + CharTime(buf, &tv.tv_sec), tv.tv_sec, tv.tv_usec); \ + DebugMsg(shmp, "packets contains (%s):", FUNCTION_MACRO); \ + BcdToAscii(buf, pbuf->msgContent, 2*pbuf->msgLength); \ + FormatOutput(buf, 2*pbuf->msgLength, 2, ' '); \ + DebugMsg(shmp, "%s", buf); \ + DebugMsg(shmp,"=========04==========08==========12==========16==========20==========24========="); \ + +#define WriteRecvMessageToDebugBuffer(shmp, pbuf) \ + DebugMsg(shmp,"=================================================="); \ + DebugMsg(shmp,"Got packet from %s %d Length=%d", \ + Inet_ntoa(pbuf->msgSrcIP), pbuf->msgSrcPort, \ + pbuf->msgLength); \ + gettimeofday(&tv, NULL); \ + DebugMsg(shmp,"Current time: %s (%ld.%06ld)", \ + CharTime(buf, &tv.tv_sec), tv.tv_sec, tv.tv_usec); \ + DebugMsg(shmp, "packets contains (%s):", FUNCTION_MACRO); \ + BcdToAscii(buf, pbuf->msgContent, 2*pbuf->msgLength); \ + FormatOutput(buf, 2*pbuf->msgLength, 2, ' '); \ + DebugMsg(shmp, "%s", buf); \ + DebugMsg(shmp,"=========04==========08==========12==========16==========20==========24========="); \ + +#define UNDER_DEVELOP 0 +#define DEBUG 1 + +#define D_NO_DEBUG 0 +#define D_CONSOLE_ONLY 1 +#define D_LOG_ONLY 2 +#define D_CONSOLE_LOG 3 +#define D_SYSLOG_MODE 4 + +#define SCAN_IT_INTERVAL_SEC 0 +#define SCAN_IT_INTERVAL_USEC (20*1000) +#define SCAN_IT_VALUE_SEC 0 +#define SCAN_IT_VALUE_USEC (20*1000) + +/* If we have these macros, we can add additional info to the header. */ +#ifdef HAVE_FILE_MACRO +#define FILE_MACRO (__FILE__) +#else +#define FILE_MACRO ("") +#endif + +#ifdef HAVE_FUNCTION_MACRO +#define FUNCTION_MACRO (__FUNCTION__) +#else +#define FUNCTION_MACRO ("") +#endif + +#ifdef HAVE_DATE_MACRO +#define DATE_MACRO (__DATE__) +#else +#define DATE_MACRO ("") +#endif + +#ifdef HAVE_TIME_MACRO +#define TIME_MACRO (__TIME__) +#else +#define TIME_MACRO ("") +#endif + +#ifdef HAVE_LINE_MACRO +#define LINE_MACRO (__LINE__) +#else +#define LINE_MACRO ("") +#endif + +// Buffer stored by debug information +#define DEBUG_BUFFER_LINE (25*16) +#define DEBUG_LINE_LEN (80) +typedef struct { + u_short subRead; + u_short subWrite; + u_char infoDebug[DEBUG_BUFFER_LINE][DEBUG_LINE_LEN]; +} _debug_info; + +#endif /* DEBUG__H */ diff --git a/mss/pps/src/include/errlog.h b/mss/pps/src/include/errlog.h new file mode 100644 index 0000000..cd876b7 --- /dev/null +++ b/mss/pps/src/include/errlog.h @@ -0,0 +1,40 @@ +/* +** Error and log proccess functions header file, +** to be included *after* all standard system headers +** +** CVS: $Id: errlog.h,v 1.1 2001/06/28 07:21:15 zhangsz Exp $ +*/ + +#ifndef ERRLOG__H +#define ERRLOG__H + +#include /* required for some of our prototypes */ +#include /* for convenience */ +#include /* for convenience */ +#include /* for convenience */ +#include /* for convenience */ + + + /* default file access permissions for new files */ +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + + /* default permissions for new directories */ +#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH) + +#define log_flag() \ + log_debug("%s: %s: %d", FILE_MACRO, FUNCTION_MACRO, LINE_MACRO) + +void err_dump(const char *, ...); /* {App misc_source} */ +void err_msg(const char *, ...); +void err_quit(const char *, ...); +void err_ret(const char *, ...); +void err_sys(const char *, ...); + +void log_debug(const char *, ...); /* {App misc_source} */ +void log_msg(const char *, ...); /* {App misc_source} */ +void log_open(const char *, int, int); +void log_quit(const char *, ...); +void log_sys(const char *, ...); +void log_ret(const char *, ...); + +#endif /* ERRLOG__H */ diff --git a/mss/pps/src/include/function.h b/mss/pps/src/include/function.h new file mode 100644 index 0000000..3284392 --- /dev/null +++ b/mss/pps/src/include/function.h @@ -0,0 +1,235 @@ +/* +** +** function.h +** +** Description: Header file of function definations. +*/ + +#ifndef _PPS_FUNCTION__H +#define _PPS_FUNCTION__H + +#define GetAsciiTime GetASCTime + +char * +NstrCrypt(char *sp); + +#define LogContent(fp, buf, bcd_buf, nbytes) \ + BcdToAscii(buf, bcd_buf, 2 * nbytes); \ + FormatOutput(buf, 2*nbytes, 2, ' '); \ + LogMsg(fp, "packets contains (%s):\n%s", FUNCTION_MACRO, buf); + +#define DisplayContent(buf, bcd_buf, nbytes) \ + BcdToAscii(buf, bcd_buf, 2 * nbytes); \ + FormatOutput(buf, 2*nbytes, 2, ' '); \ + log_debug("packets contains (%s):\n%s", FUNCTION_MACRO, buf); + +#define BzeroContent(content, length) \ + bzero(content+length, MAX_CONTENT_LEN-length); + +int InitDaemon(void); /* Initialize a daemon process */ + +void +SetTermSignal(struct termio *ptermio, void (*handler)(int)); + +void +SetFaultSignal(void (*handler)(int)); + +void +SetRefreshSignal(struct termio *ptermio, void (*handler)(int)); + +/* Initialize a daemon process */ +void DaemonInit(const char *pname, int); + +/* passive a socket handler, from comfunc.c */ +int passivesock( const char * transport, u_short portbase, int qlen); + +/* passive a UDP socket handler, from comfunc.c */ +int passiveUDP(u_short portbase); + +/* Fill string 'c' into last area of 'str'. */ +void StringCat(char *str, char *c, int slen); + +int ByteLength(BYTE *bcd, int c); + +/* Cut string while match character c. */ +void StringCut(char *str, int c); + +void Bstr2Hstr(char *cptr); + +void bitstring(char *str, long byze, int biz, int strwid); + +/* Binary string convert to int. */ +unsigned int Bstr2Int(char *cptr); + +/* Hex string convert to int. */ +unsigned int Hstr2Int(char *cptr); + +/* Get current hour */ +int gethour(char *hour_buf); +int getweek(char *week_buf); +void getdate(char *date_buf); +int getmon(char *mon_buf); +int getday(char *day_buf); +int getyear(char *year_buf); +int getmin(char *min_buf); +int getsec(char *sec_buf); + +/* Get current hour */ +int getmin(char * min_buf); + +/* Convert data from ASCII form to left-aligned compact BCD form. */ +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len); + +/* Convert data from left-aligned compact BCD form to ASCII form. */ +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len); + +/* Convert data from ASCII form to right-aligned compact BCD form. */ +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len); + +const char * +ppsgetdaytime(char *daytime_buf); + +//char *GetASCTime(char *timep); +char *CharTime(char *ptr, const time_t *timep); + +void * +ShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg); + +int +SemInit(char *prog_name, key_t key, int sem_num, int sem_flg); + +BOOL +SemLock(char *prog_name, int sem_id, int sem_num, + unsigned nsops, int sem_flg); + +BOOL +SemUnlock(char *prog_name, int sem_id, int sem_num, + unsigned nsops, int sem_flg); + +BOOL +ReadQueueMsg(void *dest, const void *src, int max_num); + +BOOL +WriteQueueMsg(void *dest, const void *src, int max_num); + +BOOL +ReadMsg(void *dest, void *src, int max_num); + +BOOL +WriteMsg(void *src, void *dest, int max_num); + +BOOL +WriteErrorLog(void *pbuf, void *perr, int max_num); + +const char * +Inet_ntoa(const long addr); + +const long +ppsInet_pton(const char *sp); + +//const long +//GetLocalIP(void); + +char * +FormatOutput(char *sp, size_t, int, int); + +void +ByteReverse(BYTE *p1, BYTE *p2, size_t size); + +void +SafeFree(void *pmem); + +/* n is BYTE length */ +void +GetAsciiField(char *dest, BYTE *src, size_t n); + +#define SetAsciiField SetBcdField +void +SetBcdField(BYTE *dest, char *src, size_t n); + +void +SetIntField(BYTE *dest, int src, size_t n); + +int +GetIntField(int *i, BYTE *src, size_t n, int flag); + +void +StringRev(char *sp); + +u_char * +ByteRev(u_char *ptr, size_t size,int flag); + +time_t +MakeTime(struct tm *timep, char *ptr); + +const char * +AsciiTime(char *ptr, time_t); + +void +SetIntToNBO(u_char *dest, const long src); + +void +SetShortToNBO(u_char *dest, const short src); + +const long +GetIntFromNBO(u_char *src); + +const short +GetShortFromNBO(u_char *src); + +const long +ByteToInt(u_char *src, int n); + +u_short +GetHour(time_t); + +u_short +GetMinute(time_t); + +u_short +GetTmHour(); + +u_short +GetTmMinute(); + +u_short +GetTmSecond(); + +u_short +GetTmDay(); + +u_short +GetTmMonth(); + +u_short +GetTmYear(); + +char * +GetTmDate(char *ptr); + +int +AsciiToMsisdn(char *cptr,u_char *bptr,int len); + +void +string2ltime(time_t *nowtime, char *timestr); + +void +ppsAsciiToBcdR(u_char *bcd_buf, const char *asc_buf, int len); + +void +ppsBcdToAsciiR(char *asc_buf, const u_char *bcd_buf, int len); + +void +CharToTimeStamp(u_char *btime,char *atime); + +void gettime(char *time_buf); +const int getnowtime(int *timebuf); +void GetVersionID(char *cbuf, u_char *bbuf); +unsigned int HstrToInt(char *cptr); + +int CutUnknownPrefix(char *number); +extern int msisdnUnkToInt(char *strIn, char *strOut); +//extern int EncryptPIN(); +extern int PutLogFunID(); + +#endif diff --git a/mss/pps/src/include/gprs.h b/mss/pps/src/include/gprs.h new file mode 100644 index 0000000..92abc13 --- /dev/null +++ b/mss/pps/src/include/gprs.h @@ -0,0 +1,79 @@ +#ifndef _GPRS__H +#define _GPRS__H + +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + + +#include "../include/ppsMibTable.h" +#include "../include/mfunc.h" + +#include "../../../../plat/radius/src/include/radius_if.h" + +extern char logMsisdn[18]; +extern int logMsgFlag; + + +#define INIT_QID 1 +#define QID_DUAL_PLAT_POIND 30000 +#define MAX_PPAQ_EACH_ACCESS_REQUEST 1 + +#define GPRS_O_OPEN 0x88 +#define VAS_O_OPEN 0x89 + +#define BYTES_PER_KB 1024 + + +enum{ + PPS_RADIUS_NO_CMD, + PPS_RADIUS_NEW_SERVICE, + PPS_RADIUS_THRESHOLD_REACHED, + PPS_RADIUS_QUOTA_REACHED, + PPS_RADIUS_REMOTE_DISC, + PPS_RADIUS_CLIENT_SERVICE_TER, + PPS_RADIUS_ACCESS_SERVICE_TER, + PPS_RADIUS_SERVICE_NOT_EST, + PPS_RADIUS_DISCONNECT_ACK, + PPS_RADIUS_DISCONNECT_NAK, +}; + +enum{ + PPS_POSTPAID_USER, + PPS_PREPAID_USER, +}; + +enum pps_gprs_process_state{ + pps_gprs_idle, + pps_gprs_postpaid, + pps_gprs_prepaid, + + pps_gprs_wait_request, + pps_gprs_wait_quota_reached, + pps_gprs_inactive_timeout, + pps_gprs_access_timeout, + pps_gprs_wait_terminate, + pps_gprs_service_terminate, + +}; + +enum _VAS_STATE{ + VAS_STATE_IDLE, + VAS_STATE_AUTH, + VAS_STATE_CHARGE, + VAS_STATE_ACCEPT, + VAS_STATE_REJECT, + VAS_STATE_TERMINATE, +};//VAS_STATE; + + +#endif + + diff --git a/mss/pps/src/include/includes.h b/mss/pps/src/include/includes.h new file mode 100644 index 0000000..afe349d --- /dev/null +++ b/mss/pps/src/include/includes.h @@ -0,0 +1,43 @@ +/* +** includes.h +*/ + +#ifndef _PPS_INCLUDES__H +#define _PPS_INCLUDES__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "public.h" +#include "function.h" +#include "errlog.h" +#include "logfunc.h" +#include "debug.h" + +#endif /* INCLUDES__H */ + diff --git a/mss/pps/src/include/iofunc.h b/mss/pps/src/include/iofunc.h new file mode 100644 index 0000000..c154c36 --- /dev/null +++ b/mss/pps/src/include/iofunc.h @@ -0,0 +1,23 @@ +/* +** +** file name: iofunc.h +** +** Parameter of IVR/VPS +** +*/ + +#ifndef IOFUNC__H +#define IOFUNC__H + +void InitParport(char *prog_name, u_short parport_range); + +void SetParport(u_short parport_range, u_char flag); + +void SetParportOn(char ledbit,u_short parport_range); + +void SetParportOff(char ledbit,u_short parport_range); + +void SetNonblock(int); + +void SetParalPort(unsigned char flag, unsigned char data); +#endif /* IOFUNC__H */ diff --git a/mss/pps/src/include/logfunc.h b/mss/pps/src/include/logfunc.h new file mode 100644 index 0000000..6cecafc --- /dev/null +++ b/mss/pps/src/include/logfunc.h @@ -0,0 +1,37 @@ +/* +** +** file name: logfunc.h +** +** Header file include by logfunc.c +** +*/ + +#ifndef LOGFUNC__H +#define LOGFUNC__H + +#define LogFlag(fp) \ + LogMsg(fp, "%s: %s: %d", FILE_MACRO, FUNCTION_MACRO, LINE_MACRO) + +void * +OpenLog (const char *prog_name, const char *ident, + int option, int priority); + +void +LogRet(void *fp, const char *fmt, ...); + +void +LogSys(void *fp, const char *fmt, ...); + +void +LogMsg(void *fp, const char *fmt, ...); + +void +LogQuit(void *fp, const char *fmt, ...); + +void +GetErrnoMsg(char *sp, const char *fmt, ...); + +void +CloseLog(void *fp); + +#endif diff --git a/mss/pps/src/include/message.h b/mss/pps/src/include/message.h new file mode 100644 index 0000000..cb5dc52 --- /dev/null +++ b/mss/pps/src/include/message.h @@ -0,0 +1,192 @@ +/* +** file name: message.h +** +** Message type defination. +** +*/ + +#ifndef MESSAGE__H +#define MESSAGE__H +#include "ramdata.h" + +void SendContinue(u_short); +void SendReleaseCall(u_short); +void SendActivityTest(u_short); +void SendCDR(int); +void SendPlayAnnouncement(int proc_id, int balance, + int expiration, int code_id, int oper_result ); +void SendAccountRealSync(DWORD instance,double balance,double promotion,int ocode); + +void SendPeriodicChargeCDR(int, int, int,int); +void SendRechargeCDR(int, int, int); +void SendOperatorRechargeCDR(int, int, int); +void SendPPSGeneralCDR(int, int, int,char); +void SendRequestBCSMEvent(u_short portid); +void SendApplyCharging(u_short portid); +int GetRamData(u_char oidLen,DWORD *oid,u_char *pdata, u_short dataLen); +int SetCDRParam(u_char oidLen,DWORD *oid,u_char *pdata, u_short dataLen); +int GetCDRParam(DWORD oid,u_char *pdata); +int SetDatabase(u_char oidLen,DWORD *oid,u_char *pdata, u_short dataLen); +int GetDatabase(u_char oidLen,DWORD *oid,u_char *pdata, BYTE *vartype); + +int ImportUserData(char *record); +int ImportCommTariffData(FILE *fp); +int ImportRentTariffData(FILE *fp); +int ImportCallType(FILE *fp); +int ImportHolidayTariffData(FILE *fp); +int ImportDiscountTariffData(FILE *fp); +int ImportBasicTariffData(FILE *fp); +int ImportMTTariff(FILE *fp); +int ImportCalltypeToDiscount(FILE *fp); + +int ppsSendHeartBeating(); + +void SendContinueSMS(u_short portid); +void SendRequestSMSEvents(u_short portid); +void SendReleaseCall(u_short portid); +void SendReleaseSMS(u_short portid); + +int AssignProcID(int gy_flag); + +int DeleteSubscriberDataHead(int head); +int SetUserDataByOMC(u_char oidlen, DWORD *oid, + u_char *pdata, u_short datalen); + +void SendConnectToResource(u_short portid); +void SendSrfPlayAnnouncement(u_short portid); +void SendDisconnectForwardConnection(u_short portid); +void SendPromptAndCollectUserInfo(u_short portid); +int SendAccountInfoPromptToSrf(u_short portid,u_char isOnlyBalance,u_char isLastCallAttatched); +int SendRechargeInfoPromptToSrf(u_short portid); +void SendAccountInfoForLowCredit(char *caller, + long balance,long expired_date, + long promo,long promo_expired_date); +void SendDisconnectForwardConnection(u_short portid); +void SendFmnPromptAndCollectUserInfo(u_short portid); +void SendPromptCollectedRechargedUserInfo(u_short portid); + +/* defination of message type */ + + +#define MAX_MSISDN_LEN 11 +#define MIN_MSISDN_LEN 3 + + +#define _CID_ _cap_initial_dp +typedef struct { + BYTE callType; /* 0/1/2:=MO/MT/MF */ + BYTE servieKey; + BYTE eventTypeBCSM; + BYTE callingPartyNumber[11]; + BYTE IMSI[9]; + BYTE locationInfo[11]; + BYTE callReference[9]; + BYTE calledPartyBCDNumber[20]; + BYTE calledPartyNumber[13]; +}_cap_initial_dp; + +#define _CC_ _cap_continue +typedef struct { + BYTE msgLength; + BYTE msgReserved; + BYTE msgSrvType; + BYTE msgDstID[3]; + BYTE msgSrcID[3]; + BYTE msgOperaCode; + BYTE EndFlag; +}_cap_continue; + +#define _CRC_ _cap_release_call +typedef struct { + BYTE Cause[3]; +}_cap_release_call; + +#define _CER_ _cap_event_report +typedef struct { + BYTE type; + BYTE invoke_id; + BYTE event_type; + BYTE dp_type; +} _cap_event_report; + +#define _CAT_ _cap_activity_test +typedef struct { + BYTE msgLength; + BYTE msgReserved; + BYTE msgSrvType; + BYTE msgDstID[3]; + BYTE msgSrcID[3]; + BYTE msgOperaCode; + BYTE EndFlag; +}_cap_activity_test; + +#define MAX_CALL_NUM_BLEN 10 +#define MAX_CALL_NUM_ALEN 20 + +#define _IER_ _ivr_establish_req +typedef struct { + u_char DDO0; + u_char DDO1; + u_char port; + u_char type; + u_char invoke_id; + u_char caller[MAX_CALL_NUM_BLEN]; + u_char called[MAX_CALL_NUM_BLEN+2]; +} _ivr_establish_req; + +#define _AIS_ _account_info_sm + +typedef struct { + u_char msgLength; + u_char msgReserved; + u_char msgServiceType; + u_char msgDstID[3]; + u_char msgSrcID[3]; + u_char msgOperaCode; + u_char msisdn[8]; + u_char balance[4]; + u_char expired_date[4]; + u_char endFlag; +} _account_info_sm; + +/* +typedef struct { + u_char systemID; + u_char subSystemID; + u_char timeStamp[4]; + u_char ledStatus[8]; + u_char alarm[2]; + u_char reserved0; + u_char extLength; + u_char version[3]; + u_char status; + u_char sumOfParameter; + u_char systemCapability[4]; + u_char licensedUser[4]; + u_char realUserNumber[4]; + char serialNumber[8]; +}_pps_heartbeat; + +*/ +typedef struct { + u_char systemID; + u_char subSystemID; + u_char timeStamp[4]; + u_char ledStatus[8]; + u_char reserved0; + u_char alarm[2]; + u_char extLength_h; + u_char extLength_l; + u_char component_id_h; + u_char component_id_l; + u_char component_len_h; + u_char component_len_l; + u_char version[3]; + u_char status; + u_char sumOfParameter[4]; + u_char licensedUser[4]; + u_char realUserNumber[4]; + u_char serialNumber[4]; + u_char systemCapability[4]; +}_pps_heartbeat; +#endif /* MESSAGE__H */ diff --git a/mss/pps/src/include/mfunc.h b/mss/pps/src/include/mfunc.h new file mode 100644 index 0000000..6606d18 --- /dev/null +++ b/mss/pps/src/include/mfunc.h @@ -0,0 +1,296 @@ +/* +** +** file name: smfunc.h +** +** +*/ + +#ifndef SMFUNC__H +#define SMFUNC__H + +#include "cdrme.h" +#include "ramdata.h" + +/* deal with balance to a nature voice prompt */ +void ProcAmountVoice(char *sp); +int MergeVoiceStream(BYTE *dest, int balance, int expire, int code_id, int oper_result); +u_char GetAccountZoneID(int head, int tail); +int IsSpanCall(void *shmp); +int GetServiceCode(void *shmp, char *sptr); +int GetServiceAction(void *shmp, int code_id); +int GetAccountPos(void *ptr); +float GetBalance(_account_info *ptr); +long GetExpiration(_account_info *ptr); +int GetOverdraft(_account_info *ptr); +int GetCMBTimes(_account_info *ptr); +int UpdateCMBTimes(_account_info *ptr,int times); +int resetCMBTimes(_account_info *ptr); + +void UpdateBalance(_state_data *stateProc,_account_info *ptr, float charge,CHARGED_FEE *chargeFee); +void UpdateExpiration(void *ptr); +void UpdateExpirationFirstCharge(void *ptr); +void UpdateExpirationFirstInquiry(void *ptr, long valid_time); +int IsNormalAccount(void *ptr); +int GetAccountStatus(void *ptr); +int GetDiscount(int timestamp,u_char discount_id); + float BillingFormula(_state_data *shmp,_bill_tariff *ptar,int startTime); +float TimeToCharge(_state_data *shmp,_bill_tariff *ptar, int duration,int begin_time, int init_bill); +int preLeftTime(_state_data *shmp,float balance,_bill_tariff *ptar); +int GetValidTime(int begin_time, void *ptar, float balance, int init_bill, int overdraft); +float caculateMiniCharge(_state_data *shmp,_bill_tariff *ptar); +void EncryptCardHRN(char *card_hrn,u_char *card_pwd); +int BillingProc(void *shmp, int); +void SetCallType(void *shmp, int); +float ChargeGprsAccountBalance(_state_data *shmp,int real_duration); +int IsNormalRechargeCard(void *ptr); +u_short GetRechargeCardFaceValue(void *ptr); +u_short GetRechargeCardValidTime(void *ptr); + +u_char GetTariffLacInfo(u_char *cgi); +void SetLocationInfo(u_char *cgi,u_short portid); +u_long GetTimeFunnel(u_short, u_short, u_short); +int IsEnablePeriodicCharge(int head, int tail); +int IsEnablePeriodicAction(int head, int tail); + +float GetAccountBalance(int head, int tail); +int GetUserType(int head, int tail); +int GetPeriodicTariffFee(int tariff_id,int id); +short GetPeriodicTariffDate(int tariff_id,int id); +short GetPeriodicTariffType(int tariff_id,int id); +short GetPeriodicTariffPeriod(int tariff_id,int id); +void UpdateAccountBalance(int head, int tail, float charge); +u_long GetAccountFirstUsedDate(int head, int tail); +int GetAccountMsisdn(int head, int tail,u_char *msisdn); +short IsPeriodicChargeDate(int id, int first_used_date); +int UpdateTariffTable(int zone_id); +void UpdateOtherTable(void); +void UpdateAccountFirstUsedDate(int, int); +void UpdateAccountStatus(int, int, int); +void UpdateAccountRechargeFail(int, int); +int GetParamRechargeAttemptLimit(); +u_short GetAccountRechargeFail(int, int); +void ResetAccountRechargeFail(int, int); +int IsEnableToCall(int proc_id); +u_short TStringToID(char *time_buf); +u_short TStampToID(time_t); +int CDRStatistics(_tocdr_report *pbuf, float charge, ulong gprsVolume); +int GprsCDRStatistics(_tocdr_report* pbuf,float f_charge,ulong gprsVolume); +int MsisdnToLong(u_long *ulmsisdn, char *cmsisdn); +void cstaInstanceCheck(); +int CheckWetherLocalNumber(char *number); +int GetPeriodicChargeDate(int tariff_id,int id); +int GetUserInstance(long long head, int *instance); +int GetUserPos(int *head,long long head1); +int ConferenceCallBillingProc(void *ptr, int duration); +void SetRoamingFlag(void *shmp); +int GetAccountCUG(_account_info *ptr); +int CheckWetherFamilyNumber(_account_info *caller, _account_info *called); +int GetAccountFamilyNumberCounter(_account_info *ptr); +int StoreAccountFamilyNumber(_account_info *ptr,char *msisdn,int index); +int BillingFamilyNumberChange(_state_data *shmp); +int IncreaseFamilyNumberChangeCounter(int head, int tail); +int GetServiceType(_state_data *shmp); +int GetServiceType_0(_state_data *shmp); +int GetAccountCosID(_account_info *ptr); +int SaveDailyReport(); +int GetRechargeCardByIndex(int index,char *card_no); +void SendManualRechargeCDR(_recharge_card_info *shmp); +int GetAccountLastCallInfo(_account_info *ptr, _last_call_info *pInfo); +int GetSubsCapTariffID(_state_data *shmp, int call_type); +void UpdateSubsCapInfo(_account_info *ptr, int cap_type,float charge, int amount, _state_data *shmp); +void GetSubsCapInfo(_account_info *ptr,int cap_type, float *balance, int *counter, int type); +BOOL isPromotionCanBeUsedAtThisPoint(_state_data *shmp); +BOOL isPromotionCanBeUsedForRoDebit(_account_info *shmp); +double GetBalanceWithPromotionControl(_state_data *stateProc,_account_info *ptr); +int GetAccountBundlePlanInfo(_account_info *ptr, long ret_value[]); +int UpdateAccountBundlePlanInfo(_account_info *shmp, long set_value[]); +int subscribe_bundle_plan_send_used_up_info(char *caller_number, SMS_SENTENCE id); + +int GetAccountVoiceID(int head,int tail); + +int cliManipulationFunction(char *caller, char *called); + +void playPromptAndCollectVoice(u_short portid,u_short voiceID,u8 inputLen); +void playPromptVoice(u_short portid,u_short voiceID); +int CallingCardWaitingForSpecialResourceReport(_state_data *shmp); +int CallingCardSendReleaseCall(u_short portid); +int isTransferAllowed(u_short portid); +int isRechargeAllowed(u_short portid); +int transferIddBillingPrefix(char *number); +int poolTransferAccount(_account_info *callerInfo,_account_info *destInfo,float transferedFee); +extern void resetPoolSlaveDaily(u_short head,u_short tail); + +extern void increPoolChildCharged(_account_info *ptr,double charged); +extern void increPoolChildSMS(_account_info *ptr); +extern void increPoolChildCalls(_account_info *ptr); +extern BOOL isPromotionCanBeUsedAtThisPoint(_state_data *shmp); +extern float BillingFormula(_state_data *shmp,_bill_tariff *ptar,int startTime); +extern float TimeToCharge(_state_data *shmp,_bill_tariff *ptar, int duration,int begin_time, int init_bill); +extern double GetBalanceWithPromotionControl(_state_data *stateProc,_account_info *ptr); +extern float caculateMiniCharge(_state_data *shmp,_bill_tariff *ptar); +extern int preLeftTime(_state_data *shmp,float balance,_bill_tariff *ptar); +extern void PPSSendUserSMSNotification(int head, int tail,char *msgSend); +extern u_char getCurrentTier(_state_data *shmp,_bill_tariff *ptar); +extern void ChangeTariffToPoolCallTariff(_state_data *shmp,_bill_tariff *ptar); +extern float getCurrentFee(_state_data *shmp); +extern int isPoolChildReachSMSLimit(_state_data *shmp); +extern int isPoolChildReachFeeLimit(_account_info *ptr); +extern int decMasterChildren(_prepaid_info *prepaidInfo); +extern int IncreasePoolAccountChangeCounter(int head, int tail); +extern int increMasterChangeCounter(_prepaid_info *prepaidInfo); +extern int getHowManyChildren(_prepaid_info *prepaidInfo); +extern int BillingChildNumberChange(_state_data *shmp); +extern int increMasterChildren(_prepaid_info *prepaidInfo); + +extern int getPoolAccountRole(u_short portid); +extern int CheckWetherPoolNumber(_account_info *caller, _account_info *called); +extern int isPoolChildReachCallLimit(_state_data *shmp); +extern void clearTransferInfo(u_short portid); +extern void clearMasterSlaveInfo(u_short portid); +extern int isRechargeAllowed(u_short portid); +extern int chargeOrTransfer(u_short portid); +extern int getInputtedChoice(_state_data *shmp); +extern int transferAccountIVRProc(u_short portid); +extern int masterSlaveIVRProc(u_short portid); +extern void clearCMBInfo(u_short portid); +extern int callMebackUSSDProc(u_short portid); +extern int transferAccountIVRProc(u_short portid); +extern int smppSendMOSM(char *caller, char *called, u_char *msg,int msgLen,u_char dataCoding); +extern void SendAccountRealSync_2(_account_info *accountInfo,double balance,double promotion ,int ocode); +extern void SendAccountRealSync(DWORD instance,double balance,double promotion, int ocode); +extern void PPSSendUserSMSNotification(int head, int tail,char *msgSend); +extern int WaitingForInput(_state_data *shmp,u8 *inputMsg); +extern float GetPromotion(_account_info *ptr); +extern int GetBalanceWithOutPromotion(int head, int tail); +extern u_char *getSmsSentenceNative(SMS_SENTENCE id,u8 languageType); +extern int fillMoneyToContent(float balance,char *sms); +extern float GetAccountBalance(int head, int tail); +extern int GetLocalCosID(_account_info *ptr); +extern void pps_print_error(u_char logMsisdnFlag,const char *fmt, ...); +extern void pps_print_event(u_char logMsisdnFlag,const char *fmt, ...); +extern void saveCommand(); +extern int GetMOTariffIDWithFreeServiceControl(u_short head,u_short tail); +extern void SendTransferCDR(_account_info *caller_info,_account_info *called_info,float charge); +extern void SendDirectDebitAndRefundCDR(_account_info *caller_info, float charge); +extern void SendSmsDirectDebitAndRefundCDR(_state_data *shmp, int sent_num, int bIsRefund); +extern int SendServiceNotApplied(u_short portid,u8 ussdSmsFlag,u8 serviceNumberPosition); +extern u_long PPS_SET_INTEGER(u_char *pdata, u_char dataLen); +extern float pps_billing_ro_voice(_state_data *shmp, u32 *need_assigned_duration, u32 *new_assigned_bundle); +extern float pps_billing_ro_voice_with_crm(_state_data *shmp, u32 *need_assigned_duration, u32 *new_assigned_bundle); +extern float pps_refund_ro_voice_with_crm(_state_data *shmp, u32 refund_duration, u32 *refund_bundle); +extern float pps_refund_ro_voice(_state_data *shmp, u32 refund_duration, u32 *refund_bundle); +extern int pps_get_ro_voice_quota(_state_data *shmp); +extern int pps_get_account_bundle_mo_voice(_state_data * shmp); +extern int pps_get_account_bundle_mt_voice(_state_data * shmp); +extern int pps_get_account_bundle_mo_sms(_state_data * shmp); +extern void UpdateExpirationForRechargeCard(_account_info *ptr, u_short valid_time, u_short faceValue); +extern int GetCardSystemParamByNearestValue(u_char cos_id, u_short faceValue); +extern void SendSelfcareRechargeCDR(_account_info *user_info, char *pwd, int type, int charge); +extern void SendSelfcareBundleSubCDR(_account_info *user_info, int charge, u32 data_volume, u32 voice_sec); +extern void SendSelfcareTransferCDR(_account_info *caller_info,_account_info *called_info, float charge); +extern int get_transfer_status_normal_flag(); +extern int get_not_change_transfer_expiry_date(); +extern void UpdateAccountOverdraft(int head, int tail, long overdraft); +extern void ppsgetdaytime_readFormat(char *daytime_buf); +extern int GetAccountPromptInfo(); +extern int StoreCDR(_tocdr_report *pcdr); +extern int pps_send_map_close(); +extern int pps_debug_map_msg(); +extern int smppDecodeSM(char *strIn, char *strOut,int length); +extern int SendUSSDNotify(u_short portid, char *ussd_info); +extern int PutLogFunID(char *func_name); +extern const char * AsciiTime(char *ptr, time_t time); +extern int fillMoneyAndDate(long balance, char *expire_date, int calltype0, u_char flag, u_char *smMsgBuf); +extern int pps_get_adaptor_flag(); +extern int smppSendActivicationInfo(_account_info *caller_info, char *called); +extern int MsisdnToAscii(char *ascii_in, BYTE *cmsisdn); +extern char* ppsParseSentence(char *sentence,int varNum, char *varStr[]); +extern char *sendPPSNotificationMessage(int head, int tail, int sms_id); +extern void SendPPSGeneralCDR(int head, int tail, int charge, char cdr_type); +extern const char * AsciiTimeYMD(char *ptr, time_t time); +extern int isAccountExpired(_account_info *ptr); +extern int GetCosIDByAccount(_account_info *ptr); +extern void notifyUserTransferResult_1(_account_info *srcUsr, _account_info *dstUsr, int amount, u8 callerOrCalled); +extern int GetCardSystemParam(u_char cos_id,u_short faceValue); +extern int IsPromotionTime(COSTable *cosTableItem, struct timeval tvn); +extern int GetPromotionAmount(COSTable *cosTableItem, int charge); +extern void UpdateAccountPromotionBalance(int head, int tail, float charge); +extern void UpdateAccountPromotionExpiryDay(int head, int tail, int days); +extern int GetPromotionDay(COSTable *cosTableItem, int charge); +extern int subscribe_bundle_plan(_state_data *shmp, char *sms, int method, char *ret_prompt); +extern int getUssdACK(u_short portid,u_char *ussd_data); +extern int ocs_bundle_plan_query(_state_data *shmp, char *sms, int method, char *ret_prompt); +extern int subscribe_bundle_plan_query_info(_state_data *shmp, int operation, int method, char *ret_prompt); +extern int GetUssdServiceType(_state_data *shmp); +extern int get_cos_bundle_control(int cos_id); +extern int GetUssdServiceKey(u_char serviceKey); +extern int UseExternalVC(); +extern int send_scf_update_card_data(u_short portid); +extern int RechargeFailedUpdateAccountData(u_short portid); +extern int AssignProcID(int gy_flag); +extern int CheckClearFriendFamilyNumber(int head, int tail, int rent_charge,int rent_id); +extern int pps_update_account_bundle_mt_voice(_state_data *shmp, int seconds); +extern int pps_update_account_bundle_mo_voice(_state_data *shmp, int seconds); +extern int IncreaseFriendFamilyFreeCallDuration(int head, int tail, int duration); +extern int sendPPSTestShortMessage(char *message); +extern int pps_update_account_bundle_mo_sms(_state_data *shmp, int count); +extern int IncreaseFriendFamilyFreeSMSCounter(int head, int tail); +extern int IsEnableToAddEditFavoriteNumber(_state_data *shmp, int flag); +extern int IsFavoriteNumberTypeOk(_state_data *shmp); +extern int AddInterPrefix(char *number); +extern int GetMOTariffData(_state_data *shmp,_bill_tariff *ptar, char *call_no, int zone_id); +extern int GetMTTariffData(_state_data *shmp, u_char tariffID, _bill_tariff *ptar, _account_info *pinfo, _account_info *pcaller); +extern int pps_real_update_file_init(); +extern int pps_real_update_file_close(); +extern int pps_get_ucbc_number(char *ucbc_number); +extern long GetPromotionExpiration(_account_info *ptr); +extern ulong getSystemCurrencyResolution(); +extern int pps_real_update_user_file(int head, int tail); +extern int CountUsedCardForDailyReport(int charge); +extern int GetAccountMsisdnStr(int head, int tail,u_char *msisdn); +extern void ppsListAllSubsMSISDN(); +extern int gx_print_all_port_status(); +extern int gx_print_stat(); +extern int gx_stat_clean_all(); +extern int smppSendMsg(u_char *peerNumber,u_char *msg,u_char serviceNumPosition); +extern int UpdateAccountBundlePlanInfoWarningFlag(_state_data *shmp, int flag); +extern void ChangeTariffToCfCugFavTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToCfCugTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToCfFavTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToCfTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToCugFavTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToCugTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToFavoriteCallTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToMTRoamingTariff(_state_data *shmp, _bill_tariff *ptar); +extern void ChangeTariffToMORoamingTariff(_state_data *shmp, _bill_tariff *ptar); +extern int IsPromotionExpired(_account_info *ptr); +extern int pps_rest_query_process(u_short portid); +extern int SendRestAccountInfoPromptToSrf(u_short portid); +extern int pps_rest_topup_process(u_short portid); +extern int SendRestRechargeInfoPromptToSrf(u_short portid); +extern int pps_rest_query_process(u_short portid); +extern int pps_rest_topup_process(u_short portid); +extern int pps_smpp_state(u_short portid); +extern int pps_rest_transfer_process(u_short portid); +extern int SendTransferSuccessRequest(u_short portid,u8 ussdSmsFlag); +extern int SendPSSREnd(u_short portid,char *ussd_info); +extern int ocs_get_calling_card_cos_id(); +extern float ocs_get_calling_card_left_balance(int head, int tail); +extern int ocs_get_calling_card_method(); +extern int WaitingForEventsReport_ccc(u_short portid); +extern int WaitingforAnsweredProc_ccc(u_short portid); +extern int CheckCallValidity_ccc(u_short portid); +extern int WaitingForInputCallingCardAccountResponse_ccc(_state_data *shmp); +extern int BillingProc_ccc(_state_data *shmp, int sub_flag0); +extern int IsEnableToCall_ccc(int proc_id); +extern int pps_get_answer_timer_out(); +extern void ChargeAccountByRealCallDuration(u_short portid); +extern char *pps_get_service_number(unsigned int num_pos); +extern int OCS_with_external_CRM(); +extern void pps_send_rent_charge_to_crm(int head, int tail); +extern void ocs_get_crm_prefix_definition(); + + +#endif + + diff --git a/mss/pps/src/include/param.h b/mss/pps/src/include/param.h new file mode 100644 index 0000000..a8d24cf --- /dev/null +++ b/mss/pps/src/include/param.h @@ -0,0 +1,331 @@ +#ifndef ppsParam_H +#define ppsParam_H +#include + +#include "crd.h" +#include "ppsMibTable.h" +#include "voiceID.h" + +#define MSISDN_LENGTH 11 + + + + +typedef enum _SERVICE_KEY +{ + HELP=0, + INQUIRY_SERVICE, + SCRATCH_CARD_RECHARGE, + CREDIT_CARD_RECHARGE, + FAVORITE_NUMBER_SERVICE, + LANGUAGE_MANAGEMENT, + PIN_MANAGEMENT, + SERVICE_9, + SERVICE_10, + SERVICE_11, +}SERVICE_KEY; + + +typedef struct _file_operation +{ + u_char uploadUserData; + u_char uploadPrepaidCard; + u_char uploadTariffPlan; + u_long nextTariffStartTime; +}PPSFileOperation; + +enum _statistics_enum{ + MIBPPS_CAPOPEN = 0, + MIBPPS_INITIALDP , + MIBPPS_REQUESTBCSM, + MIBPPS_APPLYCHARGING, + MIBPPS_CONTINUE, + MIBPPS_ACTIVITYS, + MIBPPS_ACTIVITYR, + MIBPPS_REPORTBCSM, + MIBPPS_CHARGINGREPORT, + MIBPPS_ANSWERED, + MIBPPS_DISCONNECT, + MIBPPS_RELEASECALL, + MIBPPS_INQUIRE, + MIBPPS_RECHARGE, + MIBPPS_READCARD, + MIBPPS_READCARDRSP, + MIBPPS_WRITECARD, + MIBPPS_WRITECARDRSP, + MIBPPS_PLAYANNOUNCE, + MIBPPS_ACCOUNTINFO, + MIBPPS_ACCINFOACK, + MIBPPS_CDRNUMBER, + MIBPPS_CSTANUMBER, + MIBPPS_CDROVERFLOW, + MIBPPS_BLACKLIST, + MIBPPS_SUSPEND, + MIBPPS_INITIALDP_SMS, + MIBPPS_REQUEST_SMS, + MIBPPS_CONTINUE_SMS, + MIBPPS_REPORT_SMS, + MIBPPS_RELEASE_SMS, + MIBPPS_CONFERENCE, + MIBPPS_THIRD_PARTY, + MIBPPS_CONNECT_TO_RESOURCE, + MIBPPS_PLAY_ANNOUNCEMENT, + MIBPPS_EST_TMP_CNT, + MIBPPS_AST_INS, + MIBPPS_PCUI, + MIBPPS_PCUI_RES, + MIBPPS_SPE_RUS_RPT, + MIBPPS_DISCNT_FWD_CNT, + MIBPPS_SM_INQUIRY, + MIBPPS_SM_RECHARGE, +}; + +typedef struct _msg_statistics_ +{ + u_long CapOpen; + u_long Initialdp[2]; + u_long RequestBCSM[2]; + u_long ApplyCharging[2]; + u_long Continue[2]; + u_long ActivityS; + u_long ActivityR; + u_long ReportBCSM[2]; + u_long ChargingReport[2]; + u_long Answered[2]; + u_long Disconnect[2]; + u_long Releasecall[2]; + u_long Inquire; + u_long Recharge; + u_long ReadCard; + u_long ReadCardRsp; + u_long WriteCard; + u_long WriteCardRsp; + u_long Playannounce; + u_long Accountinfo; + u_long Accinfoack; + u_long InitialDP_SMS; + u_long Request_SMS; + u_long Continue_SMS; + u_long Report_SMS; + u_long Release_SMS; + u_long Conference; + u_long ThirdParty; + u_long ConnectToResource; + u_long PlayAnnouncement; + u_long EstablishTemporaryConnection; + u_long AssistInstructions; + u_long PCUI; + u_long PCUI_rsp; + u_long SpecialResourceReport; + u_long DisconnectForwardConnection; + u_long smInquiry; + u_long smRecharge; + u_long send_sync[4]; + u_long recv_sync[4]; + u_long update_card_request; + u_long update_card_error_msg; + u_long update_card_ok; + u_long update_card_no_card; + u_long update_card_used; + u_long update_card_expired; + u_long update_card_sys_failure; + char ussd_operation_date[7][16]; + u_long ussd_operation[7][3*4]; /* 7*3 */ +}_msg_statistics; + +typedef struct _measurement +{ + u_long cdrnumber; + u_long balance; + u_long duration; + u_long cstanumber; + u_long cdroverflow; + u_long blacklist; + u_long suspend; + u_long usernumber; +// u_long headnumber; + u_char user_number[8]; + u_long peer_usernumber; +// u_char head_prefix[1000][4]; + u_int free_index; + u_long cardnumber; + u_long cardheadnumber; + u_char card_number[8]; + u_char card_prefix[2000][4]; + u_long sysCapability; + u_char sys_capability[4]; + u_char licensed_user[4]; + u_char index_alarm; + u_int search_table_result[4]; + u_char mt_release_flag; +}_measurement; + +typedef struct _display +{ + char sysState; + char peer_state; + char peer_state_counter; + char dataSrc; + char initProgress; + char control_state; + u_long masterIP; + char rechargeDigitals[8]; + char inquiryDigitals[8]; + u_short proc_used; + u_short proc_begin[7]; + u_short ro_used; + u_short gy_used; + u_long totalCharge; + u_long control_state_ts; + char asciiIn[128]; + char asciiOut[8192]; + char reserved0[8192]; + int reserved1[8192]; + long reserved2[8192]; +}_display; + +typedef struct _debug_mib +{ + _msg_statistics msgstatistics; + _measurement measurement; + u_char watch_dog[4*16]; + int report_sum[7][4]; + _display display; +}_debug_mib; + +// fix multiple definition==================================== +extern _debug_mib debugmib; +// + +typedef struct _PpsParam +{ + u_char ppsNumber[MSISDN_LENGTH]; /* byte0 = length */ + u_char smscNumber[MSISDN_LENGTH]; + u_char esmeNumber[MSISDN_LENGTH]; + + u8 param_ver; + u8 reserve[127]; + + PpsServiceConrol serviceControl; + VmsRouteParam routeParam; + PPSFileOperation fileOperation; + PpsTable ppsTables; + u_long rcm_ip; + int max_call_duration; + long max_quota_per_request; + int scf_work_as_adaptor; + int scf_work_as_adaptor_with_vcs; + int data_quota_as_postpaid; + int new_flags[31]; + _ocsCRMConrol ocs_crm_control; +}PPSParamStruct; + + +int SetDefaultParam(); +int DecodePPSAsciiIn(int pageno, char *cmd); +int GetCDR_Record(); + +void SetLoadFileFlag(int dataID); +void AddPPSStatistics(int index,int dir); + +int pps_debug_set(); +int GetCSTA_Record(); +int GetMO_CDR(); +int GetMT_CDR(); +int ppsDeubgRt(); +int pps_smppInit(); +int PeerServerRamInitRequest(u_char oidLen, DWORD *oid, + u_char *pdata,BYTE *vartype); +int reportCDRIncrement(int calltype,int duration, float charge,ulong gprsVolume); +int SetCSTASyncFlag(int instance); + +void PrepaidAction(); +int MessageProc(); +void CallProc(); +int SystemInit(); +int WaitingforAnsweredProc(u_short); +int BeatTrans(); +void SetServerFlag(int flag); +int SetServerID(); +void SetActiveDataServer(int flag); +void TariffPlanProc(); +void PeriodicChargeProc(); +void CheckLoadFile(); +void SysGuard(int sig); +void ReleaseAll(u_short portid); +int RequestBCSMEvent(u_short portid); +int WaitingForInitialDP(u_short portid); +int WaitingForEventsReport(u_short portid); +int ppsBackupRamDataToFile(); +int ppsBackupRamDataToOMCServer(); +void PeriodicSyncRamData(); +int smppMonitor(); +void capMessageProc(); +int SyncDailyReport(); +int ReadDataFromOMCServer(); +int LoadDataFromBackfile(); +int ReadDataFromPeerSever(); +int ReadPeroidicSyncData(); +int LoadPPSParam(); +int ppsInitCSTA(); +void DisplayVoiceOperationCode(); +int UserHeadIncrement(); +int UserNumberIncrement(); +int UserHeadDecrement(); +int UserNumberDecrement(); +int ReadTariffDataFromFile(int tbindex); +int ReadIvrSyntaxDataFromFile(FILE *fp); +int ReadDigitalSyntaxDataFromFile(FILE *fp); +int WaitingforAnsweredProc(u_short portid); +int WaitingForEventsReport(u_short portid); +int ReleasePortStatus(u_short invoke_id); +int ConferenceRequest(u_char oidLen, DWORD *oid, + u_char *pdata,u_short dataLen); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#endif diff --git a/mss/pps/src/include/plat_inc.h b/mss/pps/src/include/plat_inc.h new file mode 100644 index 0000000..2b2cb0a --- /dev/null +++ b/mss/pps/src/include/plat_inc.h @@ -0,0 +1,17 @@ +/* including all platform h files */ + +#ifndef _PPS_PLAT_INC +#define _PPS_PLAT_INC + +#include "../../../../plat/public/src/include/pub_include.h" +#include "../../../../plat/snmp/src/include/snmp.h" +#include "../../../../plat/sccp/src/include/sccp.h" +#include "../../../../plat/tcap/src/include/tcap_public.h" +#include "../../../../plat/tcap/src/include/tcap_proc.h" +#include "../../../../plat/xapp/src/mapp/map_code.h" +#include "../../../../plat/xapp/src/mapp/map_acn.h" +#include "../../../../plat/xapp/src/ixap.h" +#include "../../../../plat/xapp/src/mapp/map_public.h" +#include "../../../../plat/xapp/src/conv_prefix.h" + +#endif diff --git a/mss/pps/src/include/ppsMibTable.h b/mss/pps/src/include/ppsMibTable.h new file mode 100644 index 0000000..6138759 --- /dev/null +++ b/mss/pps/src/include/ppsMibTable.h @@ -0,0 +1,830 @@ +#ifndef PPSMIBTABLE_H +#define PPSMIBTABLE_H + +#include "../../../../plat/snmp/src/include/snmp.h" +#include "../../../../plat/snmp/src/include/macro.h" +#include "../../../../plat/radius/src/include/radius_if.h" + +#include "ramdata.h" + +#define EndLength 2 /* EOF,protect overflow */ +#define MAX_LANGUAGE_TYPES 5 + +#define MAX_INPUT_SMS 128 +#define MAX_TEXT_PROMPT 128 + +#define MAX_CHILD_COS_PER_PARENT 2 + +typedef enum _valueType +{ + INTEGER = 2, + OctetString = 4 +}valueType; + + +typedef enum _PPS_oid { + PPS_HEARTBEAT = 1, + PPS_PARAMETER, + PPS_CSTA, + PPS_CDR, + PPS_USERDATA +}PPS_oid; + +typedef enum _PPS_TYPE_DEF +{ + CAP_TYPE_DISABLE, + CAP_TYPE_CALL, + CAP_TYPE_SMS, + CAP_TYPE_BOTH +}PPS_TYPE_DEF; + +#define PPSOID 6 + +typedef enum _ppsParameter_oid{ + ServiceControl = 1, + COSID , + SrfParameter, + RouteVMS, + PPSOID_FileOperation, + Status, + PPSOID_InitRequest, + SMCLIRegisterOPR, + PPSOID_COMMAND = 10 +}ppsParameter_oid; + + +#define PpsMaxTitleLen 65 +#define MAX_SMS_LEN 100 +#define TABLE_ACTIVE_COMMAND 1 +#define TABLE_DESTROY_COMMAND 6 + +typedef struct _MnpPrefix +{ + u_char title[PpsMaxTitleLen]; + u_char prefix[16+EndLength]; + u8 reserve[32]; + u8 existFlag; +}MnpPrefix; + +typedef enum +{ + SMS_ACCOUNT_BALANCE=0, + SMS_ACCOUNT_PROMOTION=1, + SMS_EXPIRED_ON=2, + SMS_RECHARGE_ON=3, + SMS_LAST_CALL_ON=4, + SMS_LAST_RECEIVE_ON=5, + SMS_AT=6, + SMS_TO=7, + SMS_FROM=8, + SMS_ON=9, + SMS_CMB_PROMPT=10, + SMS_CMB_NOTIFY=11, + + SMS_FREE_SERVICE_ACTIVE=12, + SMS_FREE_SERVICE_DEACTIVE=13, + SMS_FREE_SERVICE_ENQUIRY=14, + SMS_FREE_SERVICE_ACTIVED_NOTIFY=15, + SMS_FREE_SERVICE_DEACTIVED_NOTIFY=16, + SMS_FREE_SERVICE_ACTIVE_ALREADY=17, + SMS_FREE_SERVICE_DEACTIVE_ALREADY=18, + SMS_FREE_SERVICE_DEACTIVED_EXPIRED=19, + SMS_FREE_SERVICE_VALID_DAYS_LEFT=20, + + SMS_WILL_TRANSFER_OUT=21, + SMS_TRANSFERED_OUT=22, + SMS_TRANSFERED_IN=23, + SMS_SERVICE_NOT_APPLIED=24, + SMS_TRANSFER_PROMPT=25, + SMS_FORMAT_ERROR=26, + SMS_INVALID_NUMBER=27, + SMS_INSUFFICIENT_FEE=28, + SMS_EXPIRED_ACCOUNT=29, + SMS_YES_OR_NO=30, + SMS_TRANSFER_SUCCESS=31, + + SMS_POOL_CHILD_LOW_FEE=32, + SMS_POOL_ADDED_CHILD=33, + SMS_POOL_DELED_CHILD=34, + SMS_POOL_BEEN_ADDED_CHILD=35, + SMS_POOL_BEEN_DELED_CHILD=36, + + SMS_CLEAR_FEE_NOTIFY=37, + SMS_CAPGRPS_NOTIFY=38, + SMS_NOT_REGISTER_PREPAID_USER=39, + SMS_USSD_MENU=40, + SMS_USSD_ERROR_INPUT=41, + SMS_RECHARGE_INPUT_PIN=42, + SMS_RECHARGE_INPUT_PIN_AGAIN=43, + SMS_LOW_BALANCE_NOTIFY=44, + SMS_USSD_COMPLETED=45, + + SMS_OVERDRAFT_NOTIFICATION =46, + SMS_GPRS_VOLUME_THIS_MONTH=47, + SMS_GPRS_VOLUME_CONSUMED=48, + SMS_GPRS_DURATION=49, + SMS_GPRS_CHARGED=50, + + SMS_GPRS_RECHARGE_SUCCESS =51, + + SMS_PROMOTION_NEWS=52, + SMS_FREE_SMS_NOTIFICATION=53, + + SMS_RECHARGE_FAILED_NO_CARD=54, + SMS_RECHARGE_FAILED_CARD_USED=55, + SMS_RECHARGE_FAILED_CARD_EXPIRED=56, + SMS_RECHARGE_FAILED_SYS_FAILURE=57, + + SMS_CMB_REACH_MAX_LIMIT=58, + SMS_CMB_AD=59, + + SMS_ACTIVATION_NOTIFY=60, + SMS_CAPSMS_NOTIFY=61, + SMS_CAPSMS_1_NOTIFY=62, + SMS_CAPSMS_2_NOTIFY=63, + + SMS_TELL_ME_NUMBER=64, + SMS_RENT_CHARGE=65, + SMS_FRIEND_FAMILY_REG=66, + SMS_FRIEND_FAMILY_REG_FAILED=67, + SMS_FRIEND_FAMILY_SERVICE_SUSPEND=68, + SMS_FRIEND_FAMILY_PLAN_EXHAUST=69, + SMS_FRIEND_FAMILY_QUERY=70, + SMS_FRIEND_FAMILY_SERIVCE_REACTIVATE=71, + SMS_FRIEND_FAMILY_REMOVE=72, + SMS_FRIEND_FAMILY_QUERY_NOT_REGISTERED=73, + SMS_FRIEND_FAMILY_QUERY_NOT_PLAN=74, + SMS_FRIEND_FAMILY_QUERY_SUSPENDT=75, + SMS_FRIEND_FAMILY_QUERY_SUSPEND_REAC=76, + SMS_FRIEND_FAMILY_QUERY_NO_LIMIT=77, + SMS_BUNDLE_PLAN = 78, + SMS_BUNDLE_PLAN_SUBSCRIBE_CMD = 79, + SMS_BUNDLE_PLAN_SUBSCRIBE_PLEASE = 80, + SMS_BUNDLE_PLAN_SUBSCRIBE_OK = 81, + SMS_BUNDLE_PLAN_SUBSCRIBE_NOK = 82, + SMS_BUNDLE_PLAN_QUERY = 83, + SMS_BUNDLE_PLAN_DATA_WARN = 84, + SMS_BUNDLE_PLAN_DATA_USEDUP = 85, + SMS_BUNDLE_PLAN_DATA = 86, + SMS_BUNDLE_PLAN_QUERY_DATA = 87, + SMS_USSD_MENU1 = 88, + SMS_BUNDLE_PLAN_USSD_SUB_CHOICE = 89,// has voice or sms, or have both + SMS_BUNDLE_PLAN_USSD_DATA = 90,// no voice and sms + SMS_BUNDLE_PLAN_NO_REFUND = 91, + SMS_BUNDLE_PLAN_USSD_MENU = 92, + SMS_BUNDLE_PLAN_NOT_APPLIED = 93, + SMS_BUNDLE_PLAN_USSD_SUB_DATA_CHOICE=94,// no voice and sms + SMS_BUNDLE_PLAN_USSD_SUB_MENU=95,// has voice or sms, or have both + SMS_BUNDLE_PLAN_DATA_WARN_HAS_V = 96, + SMS_BUNDLE_PLAN_VOICE_USEDUP = 97, + SMS_BUNDLE_PLAN_SMS_USEDUP = 98, + SMS_BUNDLE_PLAN_USSD_MENU1 = 99, + + SMS_MAX_ITEM = 100 , + SMS_LAST_CALL_INFO = 101, + SMS_LAST_SMS_INFO = 102, +}SMS_SENTENCE; + +typedef enum _PPS_USSD_OPERATON +{ + USSD_OC_HOTLINE, + USSD_OC_INQUIRY, + USSD_OC_RECHARGE, + USSD_OC_FEE_TRANSFER, + USSD_OC_CALL_ME_BACK, + USSD_OC_TELL_ME_NUMBER, + USSD_OC_FRIEND_FAMILY_QUERY, + USSD_OC_BUNDLE_PLAN, + USSD_OC_BUNDLE_QUERY, + USSD_OC_BUNDLE_PLAN_ALL, + USSD_OC_EXIT, + USSD_OC_MAX, +}PPS_USSD_OPERATION; + +typedef enum _ppsTableType +{ + PromptResolutionTable = 20, + MnpPrefixTable = 21, + SmsSentenceTable = 22, + Resered = 23, + ThirdPartyInfoTable = 24, + BasicTariffZoneTable = 25, + IvrSourceTable = 26, + SrfNumberTable = 27, + ServiceNumberTable = 28, + ServiceKeyTable = 29, + VmsUserSegmentTable = 30, + RadiusGsnTable = 31, + RadiusSgsnTable = 32, + BundlePlanTable = 33, + /****************** cos tables ********************/ + CosTable = 50, + TariffTable = 51, + ServiceControlTable = 52, + AccountValidityTable = 53, + SmsNotificationInquiryTable = 54, + RechargeCardValidityTable = 55, + RechargePromotionTable = 56, + CapPlanTable = 57, + PoolAccountTable = 58, + CosGprsTable = 59, + FriendFamilyTable = 60, + UssdServiceNumberTable = 61, + UssdServiceKeyTable = 62, + /****************** cos tables ********************/ +}ppsTableType; + +typedef enum _ppsTableMaxItem +{ + MaxPromptResolutionItem = 1, + MaxMnpPrefixItem = 32, + MaxSmsSentenceItem = SMS_MAX_ITEM, + MaxThirdPartyInfoItem = 8, + MaxBasicTariffZoneItem = 64, + MaxIvrSourceItem = 1, + MaxSrfNumberItem = 2, + MaxServiceNumberItem = 16, + MaxServiceKeyItem = 7, + MaxVmsUserSegmentItem = 128, + MaxRadiusGsnItem = RADIUS_MAX_NUM_OF_NAS, + MaxRadiusSgsnItem = RADIUS_MAX_NUM_OF_NAS, + /****************** cos tables ********************/ + MaxCosTableItem = 64, + MaxTariffTableItem = 1, + MaxServiceControlTableItem = 1, + MaxAccountValidityTableItem = 1, + MaxSmsNotificationInquiryTableItem = 1, + MaxRechargeCardType = MAX_VALUE_TYPE, + MaxcapPlanTableItem = 4, + MaxPoolAccountTableItem = 1, + MaxGprsTableItem = 1, + MaxGprsCapPlan = 1, + MaxFriendFamilyTableItem = 1, + /****************** cos tables ********************/ + + /*** if you add items in any table,notify these value ***/ + MaxPromptResolutionReservedItem = 1, + MaxMnpPrefixReservedItem = 1, + MaxSmsSentenceReservedItem = 1, + MaxThirdPartyInfoReservedItem = 1, + MaxBasicTariffZoneReservedItem = 1, + MaxIvrSourceReservedItem = 1, + MaxSrfNumberReservedItem = 5, + MaxServiceNumberReservedItem = 8, + MaxServiceKeyReservedItem = 5, + MaxVmsUserSegmentReservedItem = 1, + MaxRadiusGsnReservedItem = 0, + MaxCosTableReservedItem = 1, + MaxTariffTableReservedItem = 1, + MaxServiceControlReservedItem = 0, + MaxAccountValidityReservedItem = 1, + MaxSmsNotificationInquiryReservedItem = 1, + MaxRechargeCardValidityReservedItem = 1, + MaxRechargePromotionReservedItem = 1, + MaxCapPlanReservedItem = 1, + MaxPoolAccountReservedItem = 0, + MaxGprsTableTableReservedItem = 1, + /*** if you add items in any table,notify these value ***/ +}ppsTableMaxItem; + +typedef enum _srfNumberPosition +{ + SRF0Position = 0, + SRF1Postion +}srfNumberPosition; + +typedef enum _serviceNumberPosition +{ + HotLineNumberPosition = 0, + InquiryNumberPosition, + ScratchCardRechargeNumberPosition, + CreditCardRechargeNumberPosition, + ThirdPartyRechargeNumberPosition, + CustomerCareCenterNumberPosition, + RechargeNumberPosition, + OPRNumberPosition, + VirtualCallingCardNumberPosition, + PalimRegisterNumberPosition, //2010-03-08 + PoolAccountPosition, + FeeTransferPosition, + FreeServicePosition, + CallMeBackPosition, + GPRSPrepaidPostion, + TellMeNumber, + FriendFamilyPosition, + MAXServicePostion, + +}serviceNumberPosition; + +typedef struct _PromptResolution +{ + u_char title[PpsMaxTitleLen]; + u8 currencyResolution; + u8 dataFormat; + u8 currencySymbolPosition; + u8 reserve[32]; + u8 existFlag; +}PromptResolution; + + +typedef struct +{ + u8 language[MAX_SMS_LEN+EndLength]; +}LANGUAGE_INFO; + +typedef struct _SmsSentence +{ + u_char title[PpsMaxTitleLen]; + u8 english[MAX_SMS_LEN+EndLength]; + LANGUAGE_INFO language[MAX_LANGUAGE_TYPES]; + u8 existFlag; +}SmsSentence; + +typedef struct _LastCallInfo +{ + u_char title[PpsMaxTitleLen]; + u8 lastCallSentOn[32+EndLength]; + u8 lastCallReceiveOn[32+EndLength]; + u8 at[8+EndLength]; + u8 to[8+EndLength]; + u8 from[8+EndLength]; + u8 reserve[32]; + u8 existFlag; +}LastCallInfo; + +typedef struct _ThirdPartyInfo +{ + u_char title[PpsMaxTitleLen]; + u_char serviceID[8+EndLength]; + u_char servicePassword[8+EndLength]; + u8 reserve[32]; + u8 existFlag; +}ThirdPartyInfo; + +typedef struct _BasicTariffZone +{ + u_char title[PpsMaxTitleLen]; + u8 mcc[3+EndLength]; + u8 mnc[3+EndLength]; + u16 lac; + u16 cellId; + u32 moTariffId; + u32 mtTariffId; + u8 reserve[32]; + u8 existFlag; +}BasicTariffZone; + +typedef struct _IvrSource +{ + u_char title[PpsMaxTitleLen]; + u8 inquiry; + u8 recharge; + u8 reserve[32]; + u8 existFlag; +}IvrSource; + +typedef struct _SrfNumber +{ + u_char title[PpsMaxTitleLen]; + u8 number[16+EndLength]; + u8 reachable; + u8 reserve[32]; + u8 existFlag; +}SrfNumber; + +typedef struct _ServiceNumber +{ + u_char title[PpsMaxTitleLen]; + u8 number[16+EndLength]; + u8 reserve[32]; + u8 existFlag; +}ServiceNumber; + +typedef struct _ServiceKey +{ + u_char title[PpsMaxTitleLen]; + u8 key; + u8 reserve[32]; + u8 existFlag; +}ServiceKey; + +typedef struct _VmsUserSegment +{ + u_char title[PpsMaxTitleLen]; + u8 startMsisdn[16+EndLength]; + u8 endMsisdn[16+EndLength]; + u8 vmsPLMNserviceNumber[16+EndLength]; + u8 vmsPSTNserviceNumber[16+EndLength]; + u8 leaveMessageNumber[16+EndLength]; + u8 reserve[32]; + u8 existFlag; +}VmsUserSegment; + +typedef struct _PPS_RADIUS_NAS_INFO{ + u_char title[PpsMaxTitleLen]; + ulong volumeMeterUnit;/*byte */ + ulong durationMeterUnit;/*s */ + u8 tariffID; + RADIUS_NAS_INFORMATION nasInfo; + u8 existFlag; +}PPS_RADIUS_NAS_INFO; + +typedef struct _PPS_RADIUS_SGSN_INFO{ + u_char title[PpsMaxTitleLen]; + DWORD sgsnIP; + u8 cosID; + u8 apnName[16]; + u8 tariffID; + u8 reserved[15]; + u8 existFlag; +}PPS_RADIUS_SGSN_INFO; + + +/********************** COS tables ***********************/ +typedef struct _promotion_plan_control +{ + u_long rechargePromotionStartDate; + u_long rechargePromotionEndDate; + + struct{ + BOOL IDD; + BOOL NDD; + BOOL LOCAL; + }usedForCall; + + struct{ + BOOL IDD; + BOOL NDD; + BOOL LOCAL; + }usedForSMS; + + struct{ + BOOL allowed; + }usedForGPRS; + + struct{ + BOOL transfer; + u_char transferPrioriy; + }transfer; +}promotion_plan_control; + +typedef struct _CosTariff +{ + u_char title[PpsMaxTitleLen]; + u8 moTariffID; + u8 mtTariffID; + u8 chargeBy; + u8 capPlanResetDay; + promotion_plan_control promotionUseControl; + u8 promotionUsedForRoDebit; + u8 reserve[31]; + u8 existFlag; +}CosTariff; + +typedef struct _CosServiceControl +{ + u_char title[PpsMaxTitleLen]; + u8 moThresholdSet; + int moMinimumBalance; + u8 mtChargeFlag; + u8 mtBalanceControl; + int mtBalanceThreshold; + u8 poolAccountFlag; + u8 poolAccountChangeChargeFlag; + u8 poolAccountFreeChangeTimes; + u8 closeUserGroupService; + u8 rechargeViaCreditCard; + u8 creditVault; + u16 creditVaultAmount; + u8 relatedCosID; + u8 freeSMSActiveDays; + u8 freeSMSRentType; + u8 callMeBackThreshold; + u8 callMeBackMaxTimes; + u8 mtSMSCharge; + u8 validiDaysActivatedByInquiringAccountWithZeroBalance0; + u8 actionWhenMOorMTExpired; /*0=mo,1=MT */ +// u16 validiDaysActivatedByInquiringAccountWithZeroBalance; +// u16 sReserved[2]; + u16 serviceNumberFlag; + u16 smsServiceFlag; + u16 ussdServiceFlag; + + u8 bundle_data_warning_threashold; /*in 5 MB */ + u8 bundle_data_warning_threashold_low; /*in 5 MB */ + u8 event_charging_flag;// 0, disable; 1, enable; + u8 cap_or_bundle_in_tariff;// Cap or Bundle used in Tariff Table: 0, cap; 1, bundle; + u8 bundle_plan_contorl; //0=bundle plan with data/voice/sms, 1=data plan only + u8 reserve[11]; + u8 existFlag; + +}CosServiceControl; + +typedef struct _CosAccountValidity +{ + u_char title[PpsMaxTitleLen]; + u16 maxAccountValidityDays; + u8 actionWhenAccountExpires; + u16 daysKeepingAnExpiredAccount; + u8 actionAfterDaysKeepingAnExpiredAccount; + u8 actionAfterRecharge; + u8 actionAfterBalanceDepleted; + u8 validDaysChangeTo; + u8 activiationByInquiryIs; + u8 validiDaysActivatedByInquiringAccountWithZeroBalance0; + u8 actionWhenMOorMTExpired; /*0=mo,1=MT */ + u16 validiDaysActivatedByInquiringAccountWithZeroBalance; + u8 reserve[27]; + u8 bundlePlanIDWhenActivated; + u8 existFlag; +}CosAccountValidity; + + +typedef struct _CosSmsNotificationInquiry +{ + u_char title[PpsMaxTitleLen]; + u8 smsNotificationWhenRecharge; + u8 smsNotificationWhenInquiry; + u8 smsNotificationWhenExpired; + u8 theDaysSendingSMSBeforeExpiredDay; + u8 smsNotificationWhenBalanceInsufficient; + u16 insufficientBalanceThreshold; + u8 chargeWhenInquiryBySMS; + u8 freeInquiryPerDay; + u8 smsNotificationWhenCleanBalance; //2010-03-08 + u8 smsNotificationWhenCapPlanChanged; //2010-03-08 + u8 smsNotificationWhenApplyOverdraft; + u8 smsNotificationWhenRentCharge; + u8 smsNotificationWhenFriendFamilyServiceReg; + u8 smsNotificationWhenFriendFamilyServiceSuspend; + u8 smsNotificationWhenFriendFamilyPlanExhaust; + u8 smsNotificationWhenFriendFamilyServiceRemoved; + u8 reserve[26]; + u8 existFlag; +}CosSmsNotificationInquiry; + +typedef struct _CosRechargeCardValidity +{ + u_char title[PpsMaxTitleLen]; + u16 cardCredit; + u16 moValidity; + u16 mtValidity; + u8 reserve[32]; + u8 existFlag; +}CosRechargeCardValidity; + + +typedef struct _CosRechargePromotion +{ + u_char title[PpsMaxTitleLen]; + int rechargeCardCredit; + int promotionBonus; + int promotionValidity; + u8 reserve[32]; + u8 existFlag; +}CosRechargePromotion; + +typedef struct _CosCapPlan +{ + u_char title[PpsMaxTitleLen]; + u8 flag; + u8 type; + u32 threshold0; + u32 threshold1; + u32 threshold2; + u8 tariffID0; + u8 tariffID1; + u8 tariffID2; + u8 tariffID3; + u8 reserve[32]; + u8 existFlag; +}CosCapPlan; + +typedef struct{ + u_char title[PpsMaxTitleLen]; + u_char role; + struct{ + struct + { + u_char cosIDForChild[MAX_CHILD_COS_PER_PARENT]; + }parent; + struct + { + u_char isRechargeAllowed; + u_char isTransferAllowed; + u_char periodicTransferOrAutoByParent; + u_short maxCallsPerDay; + u_short maxSMSPerDay; + u_long maxFeePerDay; + }child; + }roleParty; + u8 existFlag; +}COS_Pool_Account; + +typedef struct _GPRS_VOLUME_CAP_PLAN{ + u8 type;/* 0:cap by volume;1:cap by charge */ + u32 threshold0;/* 0-1024*1024*1024KB */ + u32 threshold1;/* 0-1024*1024*1024KB */ + u32 threshold2;/* 0-1024*1024*1024KB */ + u8 tariffID0; + u8 tariffID1; + u8 tariffID2; + u8 tariffID3; +}GPRS_VOLUME_CAP_PLAN; + +typedef struct _PPS_COS_RADIUS_ITEM +{ + u_char title[PpsMaxTitleLen]; + u8 gprsChargeFlag;/*0:disable;1:enable */ + u32 miniBalanceForGprs;/*<=0:unlimited;other:limited */ + ulong inactiveSessionLimit;/*0:unlimit;others:limited */ + u8 notificationWhenSessionTerminate; + u_short maxSmsForGprsNotificationPerDay; + ulong maxVolumeQuotaEachTime;/* byte */ + ulong volumeThresholdDiff;/* byte */ + ulong maxDurationQuotaEachTime;/* s */ + ulong durationThresholdDiff;/* s */ + u8 gprsChargedBy;/*0:define by cos;1:defined by incoming GSN IP */ + GPRS_VOLUME_CAP_PLAN capPlan[MaxGprsCapPlan]; + u8 reserved[64]; + u8 existFlag; +}PPS_COS_RADIUS_ITEM; + +#define MAX_FAVORITE_PALN 6 + +typedef struct CosFriendFamilyPlan +{ + u16 rentCharge; + u8 maxNumbers; + u16 freeSMS; /* 0 means no limitation */ + u32 freeCallDuration; /* 0 means no limitation */ + u8 rentID; /*1-8 index of rent tariff */ + u8 cReserved[4]; + u16 sReserved[2]; + u32 iReserved[2]; +}CosFriendFamilyPlan; + +typedef struct CosFriendFamilyControl +{ + u_char title[PpsMaxTitleLen]; + u8 friendFamilyFlag; + u8 friendFamilyChangeChargeFlag; + u8 friendFamilyFreeChangeTimes; + u8 friendFamilyNumberTypeLocal; + u8 friendFamilyNumberTypeNDD; + u8 friendFamilyNumberTypeIDD; + u16 balanceThresholdForFriendFamilyCall; + u8 keepOrRemoveFriendFamilyNumber; + u16 balanceThresholdToKeepFriendFamilyNumber; + u8 cReserved[32]; + u16 sReserved[8]; + u32 lReserved[4]; + CosFriendFamilyPlan friendFamilyPlan[MAX_FAVORITE_PALN]; + u8 existFlag; +}CosFriendFamilyControl; + +typedef struct _COSTable +{ + u_char title[PpsMaxTitleLen]; + CosTariff tariff[MaxTariffTableItem+MaxTariffTableReservedItem]; + CosServiceControl serviceControl[MaxServiceControlTableItem+MaxServiceControlReservedItem]; + CosAccountValidity accountValidity[MaxAccountValidityTableItem+MaxAccountValidityReservedItem]; + CosSmsNotificationInquiry smsNotificationInquiry[MaxSmsNotificationInquiryTableItem+MaxSmsNotificationInquiryReservedItem]; + CosRechargeCardValidity rechargeCardValidity[MaxRechargeCardType+MaxRechargeCardValidityReservedItem]; + CosRechargePromotion rechargePromotion[MaxRechargeCardType+MaxRechargePromotionReservedItem]; + CosCapPlan capPlan[MaxcapPlanTableItem+MaxCapPlanReservedItem]; + COS_Pool_Account poolAccount[MaxPoolAccountTableItem+MaxPoolAccountReservedItem]; + PPS_COS_RADIUS_ITEM gprs[MaxGprsTableItem+MaxGprsTableTableReservedItem]; + CosFriendFamilyControl friendFamilyControl[MaxFriendFamilyTableItem+MaxServiceControlReservedItem]; + u8 existFlag; +}COSTable; +/********************** COS tables ***********************/ +#define MAX_BUNDLE_PLANS 16 +typedef struct serviceBundlePlan +{ + u_char title[PpsMaxTitleLen]; + u32 charge; + u32 data; + u16 mo_voice; + u16 mt_voice; + u16 sms; + u16 validity; + u8 apply_flag; + u8 apply_code; + u8 cRes[3]; + u16 sRes[4]; + u8 existFlag; +}serviceBundlePlan; + +typedef struct _PpsTable +{ + PromptResolution promptResolution[MaxPromptResolutionItem+MaxPromptResolutionReservedItem]; + MnpPrefix mnpPrefix[MaxMnpPrefixItem+MaxMnpPrefixReservedItem]; + SmsSentence smsSentence[MaxSmsSentenceItem+MaxSmsSentenceReservedItem]; + ThirdPartyInfo thirdPartyInfo[MaxThirdPartyInfoItem+MaxThirdPartyInfoReservedItem]; + BasicTariffZone basicTariffZone[MaxBasicTariffZoneItem+MaxBasicTariffZoneReservedItem]; + IvrSource ivrSource[MaxIvrSourceItem+MaxIvrSourceReservedItem]; + SrfNumber srfNumber[MaxSrfNumberItem+MaxSrfNumberReservedItem]; + ServiceNumber serviceNumber[MaxServiceNumberItem+MaxServiceNumberReservedItem]; + ServiceKey serviceKey[MaxServiceKeyItem+MaxServiceKeyReservedItem]; + VmsUserSegment vmsUserSegment[MaxVmsUserSegmentItem+MaxVmsUserSegmentReservedItem]; + PPS_RADIUS_NAS_INFO gsn[MaxRadiusGsnItem]; + PPS_RADIUS_SGSN_INFO sgsn[MaxRadiusSgsnItem]; + COSTable cosTable[MaxCosTableItem+MaxCosTableReservedItem]; + COSTable reserveTable[MaxCosTableReservedItem]; + ServiceNumber ussdServiceNumber[MaxServiceNumberItem+MaxServiceNumberReservedItem]; + ServiceKey ussdServiceKey[10+3]; + + serviceBundlePlan bundlePlans[MAX_BUNDLE_PLANS]; + + SmsSentence smsExtSentence[MaxSmsSentenceItem+MaxSmsSentenceReservedItem]; + + +}PpsTable; + + +typedef struct _PpsServiceConrol{ + u32 licenseduser; + u8 cdrFlag; + u8 maxRechargeFailedNum; + int maxBalance;// for balance overflow prevention + u_char currencyName[8+EndLength]; + u8 cos_group_flag; + u8 support_mnp_flag; + u8 callingCardVadilityDays; //2010-03-08 + u8 truncation_flag; + u8 mt_release_for_no_charge; + u8 mo_release_for_no_charge; + u8 delay_timer_for_roaming; + u8 vms_allways_go; + u8 languageSmEncodeType[MAX_LANGUAGE_TYPES]; + u8 transfer_idd_prefix; + u8 external_vc; + u8 charge_by_lac_flag; /* 0=by lac+ci, 1=by ci */ + u8 not_change_expiry_date_when_transfer; + u8 only_normal_can_transfer_balance; + u8 max_call_duration; /* in second*/ + u8 gy_delay_timer0; + u8 gy_delay_timer1; + char smsc_addr[12]; + u8 ussd_callback_service_key; /*service key for USSD_CALLBACK feature */ + u8 ucbc_number[16]; /* the GT number of UCBC entity */ + u8 answer_timer; /* in seconds */ + u8 gy_not_support_threshold; + u8 gy_report_data_method; /* 0=segment, 1=accumulated */ + u8 balance_transfer_resolution; /*0=minimum , 1= currency resolution */ + u8 nai_for_diameter_proxy; + u8 mt_play_voice_flag; + u8 tcp_sync_flag; + u8 smpp_over_tcp_flag; + u8 gy_postpaid_flag; + u8 log_func_flag; + u8 calling_card_method; + u8 calling_card_cos_id; + u8 work_with_crm; + u8 mt_not_charged_for_cdr; + u8 crm_free_seconds; + u8 crm_status_validity; + u8 crm_days_before_validity; + u8 crm_notification_for_event; + u8 cellid_present_in_ccr; + u8 reserved[8]; + /******* below is table ********/ + }PpsServiceConrol; + + +/* + CT_LOCAL_CALL_OUT=100, + CT_TRUNK_CALL_OUT, // Local city call out + CT_NDD_CALL_OUT, // Nation l.d.tel + CT_HMT_CALL_OUT, // Hong Kong, Macao, TaiWan + CT_IDD_CALL_OUT, // International L.D.Tel + CT_LOCAL_CALL_IN, + CT_TRUNK_CALL_IN, + +*/ +#define MAX_CALL_TYPE_DES 10 +typedef struct ocsCRMCallTypeDes{ + char equal_or_contain; //0=equal, 1=contain + char description[MAX_CALL_TYPE_DES][128]; //0=LOCAL CALL OUT... + }_ocsCRMCallTypeDes; + +typedef struct ocsCRMConrol{ + char base_prefix_file_name[128]; + _ocsCRMCallTypeDes crm_call_type; + }_ocsCRMConrol; + + +typedef struct _VmsRouteParam +{ + u_char plmnServiceNumber[16+EndLength]; + u_char pstnServiceNumber[16+EndLength]; + u_char leaveMessageNumber[16+EndLength]; + u8 routeMethodOption; + u8 routeNumberOption; + u8 isPostpaidAllowed; + u_char ring_back_service_key; + u8 reserved[64]; +}VmsRouteParam; + +#endif diff --git a/mss/pps/src/include/pps_public.h b/mss/pps/src/include/pps_public.h new file mode 100644 index 0000000..150b71e --- /dev/null +++ b/mss/pps/src/include/pps_public.h @@ -0,0 +1,8 @@ +#ifndef PPS_PULIC_H +#define PPS_PULIC_H + +int pps_init(int sysCap, int sysID,u_long localip,u_long peerip,char *sn,int sync_flag); +void pps_proc(); +int pps_exit(int flag); + +#endif diff --git a/mss/pps/src/include/pps_redis.h b/mss/pps/src/include/pps_redis.h new file mode 100644 index 0000000..bdc77f6 --- /dev/null +++ b/mss/pps/src/include/pps_redis.h @@ -0,0 +1,8 @@ +#ifndef _PPS_REDIS__H_ +#define _PPS_REDIS__H_ +#include "ppsm.h" + + +#endif + + diff --git a/mss/pps/src/include/ppsinf.h b/mss/pps/src/include/ppsinf.h new file mode 100644 index 0000000..3fc090d --- /dev/null +++ b/mss/pps/src/include/ppsinf.h @@ -0,0 +1,31 @@ +/* +** +** file name: ppsinf.h +** +** Interface defined include shared memory key and permission, +** IP address and port. +** +*/ + +#ifndef PPSINF__H +#define PPSINF__H + +//#define DEBUG_SHM_KEY 0x05010000 +//#define DEBUG_SHM_PERM 0664 + +#define RAMDATA_SHM_KEY 0x05020000 /* key of shared memory about + state machine RAM data, + it will provide fast real time + update of the date. */ +#define RAMDATA_SHM_PERM 0664 /* Permission flag of the shared memory */ + +#define SMMP_SHM_KEY 0x05030000 /* key of shared memory about + state machine RAM data, + it will provide fast real time + update of the date. */ +#define SMMP_SHM_PERM 0664 /* Permission flag of the shared memory */ + +#define TARIFF_SHM_KEY 0x05040000 +#define TARIFF_SHM_PERM 0664 + +#endif diff --git a/mss/pps/src/include/ppsm.h b/mss/pps/src/include/ppsm.h new file mode 100644 index 0000000..72e4c31 --- /dev/null +++ b/mss/pps/src/include/ppsm.h @@ -0,0 +1,1093 @@ +/* +** Written completely by Liang Hongbin + +** Header file include by state machine +** +*/ + +#ifndef SMMP__H +#define SMMP__H +#include +#include "ppsMibTable.h" +#include "ramdata.h" +#include "tariff.h" +#include "cdrme.h" +#include "../../../../plat/diameter/include/gy_message.h" + +//#define OCS_USE_REDIS_DB 1 +//#ifdef OCS_USE_REDIS_DB +//#include "pps_redis.h" +//#endif + +#define SMMP_IT_INTERVAL_SEC 0 +#define SMMP_IT_INTERVAL_USEC 10000 +#define SMMP_IT_VALUE_SEC 0 +#define SMMP_IT_VALUE_USEC 10000 +#define TIMER_ACTION_STATE 1 +#define CYCLE_STATE_INTERVAL (1000000/(SMMP_IT_INTERVAL_USEC*TIMER_ACTION_STATE)) + +#define WAITINGFOR_ANSWERED_DELAY (2*60*CYCLE_STATE_INTERVAL) +#define SEND_ACTIVITYTEST_PERIODIC (17*CYCLE_STATE_INTERVAL) +#define ACTIVITY_TEST_DELAY (4*SEND_ACTIVITYTEST_PERIODIC) +#define ONE_MINUTE_STATE_TIME (1*60*CYCLE_STATE_INTERVAL) + +#define PERIODIC_ACTIONS (CYCLE_STATE_INTERVAL) + +#define NORMAL_DELAY_TIMER (10*CYCLE_STATE_INTERVAL) +#define SSHORT_DELAY_TIMER (5*CYCLE_STATE_INTERVAL) +#define PROMPT_AND_COLLECT_TIMER (5*ONE_MINUTE_STATE_TIME) +#define SPECIAL_RESOURCE_REPORT_TIMER (5*ONE_MINUTE_STATE_TIME) + +#define USSD_DELAY_TIMER (3*ONE_MINUTE_STATE_TIME) + +#define PPS_FSM_TIMEROUT (1200*CYCLE_STATE_INTERVAL) +#define PC_LOOP_NUM 16 +// IP address and port defination + +#define PPS_REALSYNC_PORT (4971) +#define PPS_REALSYNC_PORT_ID (PPS_REALSYNC_PORT-4950) +#define HEART_BEATING_PORT (4957) +#define PPS_SERVICE_PORT (4955) + +#define MAX_READ_PACKET_NUM 16 //8 +#define MAX_RAM_INIT_RETRY 5 +#define CONTEXT_BLOCK_SIZE (256) + +#define MAX_RO_FSM_PROCESS 2048 //2K Ro +#define MAX_GY_FSM_PROCESS 16384 // 16K Gy //8192 //8K Gy +#define MAX_FSM_PROCESS (MAX_RO_FSM_PROCESS + MAX_GY_FSM_PROCESS) //(1024+128), (2K Ro + 16K Gy) + +#define TYPE_MO_CALL 0x10 //added by lhb , 07/17 +#define TYPE_MO_SM 0x04 + +#define IVR_END_FLAG 0xCC +#define IVR_CODE_LEN 4 + +#define ACCOUNT_SERIES_LEN 2 + +#define SSN_SCF 0x93 + +#define SERVICE_INPUT_NUM 3 + +#define MAX_PREPAID_CALL_DURATION 3600 + +#define MAX_CALL_DURATION 961 //seconds +#define PAN_KEY "21436587123456" // pan key to encrypt recharge card hrn + +typedef enum _pps_service{ + SRV_IDLE = 0, + SRV_UNKNOWN, + SRV_NORMAL_MO_CALL, + SRV_NORMAL_MT_CALL, + SRV_NORMAL_MF_CALL, + SRV_MO_SMS, + SRV_CALL_HOTLINE, + SRV_INQUIRY, + SRV_SCRATCH_CARD_RECHARGE, + SRV_CREDIT_CARD_RECHARGE, + SRV_THIRD_PARTY_RECHARGE, + SRV_RECHARGE_ONE_INPUT, + SRV_RECHARGE_2TYPES, + SRV_CRD, + SRV_OTHER_VMS_MAITENANCE, + SRV_VMS_DEPOSIT, + SRV_DIRECT_ACCESS, + SRV_OPR_MANAGE, + SRV_CALLINGCARD_MANAGE,/*calling card */ + SRV_FEE_TRANSFER, + SRV_POOL_ACCOUNT, + SRV_FREE_SMS, + SRV_CALL_ME_BACK, + SRV_TELL_ME_NUMBER, + SRV_FAVORITE_NUMBER, + SRV_RESERVED_FUN, + SRV_BUNDLE_PLAN, + SRV_BUNDLE_QUERY, +}_pps_service; + +typedef enum _pps_retval{ + KEEP_STATE = 0, +}_pps_retval; + +typedef enum _call_retval{ + RELEASE_CALL = 1, +}_call_retval; + +typedef enum _sms_retval{ + RELEASE_SMS = 1, +}_sms_retval; + +typedef enum _srf_retval{ + RELEASE_SRF = 1, +}_srf_retval; + +typedef enum _call_state { + S_IDLE, + S_WAITINGFOR_ANSWERED, + S_WAITINGFOR_RELEASED, + S_ESTABLISH_IVR, + S_WAITING_INITIALDP, + S_SEND_MNP_ATI, + S_WAIT_MNP_ATI_RES, + S_CHECK_CALL_VALIDITY, + S_SEND_CONTINUE, + S_APPLY_CHARGING, + S_APPLY_CHARGING_REAL, + S_REQUEST_EVENTS, + S_WAITINGFOR_EVENTS, + S_SEND_RELEASE_CALL, + S_RELEASE_ALL, + S_SEND_SMS_MNP_ATI, + S_SMS_WAIT_MNP_ATI_RES, + S_SMS_CHECK_VALIDITY, + S_REQUEST_SMS_EVENTS, + S_RELEASE_SMS_CONTINUE, + S_WAITINGFOR_SMS_EVENTS, + S_RECHARGE_OVER, +// S_CONNECT_TO_RESOURCE, + S_ESTABLISH_TEMPORARY_CONNECTION, +// S_WAITING_ASSIST_REQUEST, + S_SEND_PLAY_ANNOUNCEMENT, + S_WAITING_SPECIAL_RESOURCE_REPORT, + S_WAITING_RR_PCUI, + S_DISCONNECT_FORWARD_CONNECTION, + //RR = Return result, + //PCUI = PromptAndCollecrUserInformation + S_INQUIRY_MANAGE, + S_RECHARGE_MANAGE, + S_CREDIT_CARD_RECHARGE, + S_FAVORITE_NUMBER_MANAGE, + S_LANGUAGE_MANAGEMENT, + S_PIN_MANAGEMENT, + S_RELEASE_SRF, + S_CRD_SERVICE, + S_MAP_STATE, + S_GPRS_STATE, + S_VAS_STATE, + + S_OPR_MANAGE, + S_CALLING_CARD,/*calling card */ + S_CHARGE_OR_TRANSFER, + S_FEE_TRANSFER, + S_POOL_ACCOUNT, + + S_SMMP_RECHAGE_ACCOUNT, + + S_RO_EVENT_COMMON_INIT = 110, + S_RO_EVENT_COMMON_PROCESS, + S_RO_EVENT_SMS_INIT, + S_RO_EVENT_SMS_PROCESS, + + S_RO_VOC_INIT=120, + S_RO_VOC_CONNECTED, + S_RO_VOC_RELEASE, + S_GY_PS_INIT, + S_GY_PS_CONNECTED, + S_GY_PS_WAIT_TERM, + S_GY_PS_RELEASE, + S_GY_PS_POSTPAID, + S_RO_VOC_GET_TARIFF_FROM_CRM,//S_GY_PS_GET_TARIFF_FROM_CRM, + S_GY_PS_GET_TARIFF_FROM_CRM_RES, + + S_RO_ADAPTOR_CALL_INIT = 130, + S_RO_CALL_WAIT_FIRST_CCA, + S_RO_CALL_TERMIATED, + S_RO_ADAPTOR_SMS_INIT, + S_RO_SMS_WAIT_RESULT, + S_RO_SMS_REFUND, + + S_ROUTING_HOME_PRN, + S_SMPP_MAIN, + + S_CC_CHECK_CALL_VALIDITY, + + S_CRM_QUERY_TARIFF_TEST, + +} _call_state; + +typedef enum _pps_map_state { + S_MAP_SEND_OPENRSP, + S_MAP_GET_PUSSDR, + S_MAP_GET_USSDACK, + S_MAP_RECHARGE_WAIT_PIN, + S_MAP_SEND_PUSSR_ACK, + S_MAP_CHECK_USSD_INPUT_CARD_VALIDITY, + S_MAP_USSD_CHECK_CARD_DATA_RCM, + S_MAP_USSD_CHECK_CARD_DATA_CRM, + S_MAP_USSD_INPUT_CARD_PWD_AGAIN, + S_MAP_SEND_PUSSR_ACK_SEND_USSN, + S_MAP_SEND_USSN_LOWBALANCE_PROMPT, + S_MAP_WAIT_USSN_ACK, + S_MAP_FEE_TRANSFER, + S_MAP_CALL_ME_BACK, + S_MAP_TELL_ME_NUMBER, + S_MAP_FAVORITE_NUMBER, + S_MAP_REST_QUERY, + S_MAP_BUNDLE_PLAN, + S_MAP_BUNDLE_QUERY, + S_MAP_REST_TOPUP, + S_MAP_THIRD_PARTY_HOTLINE, + S_MAP_THIRD_PARTY_CHANNEL, +}_pps_map_state; + +typedef enum _pps_smpp_state { + S_SMPP_IDLE, + S_SMPP_REST_QUERY, + S_SMPP_REST_TOPUP, + S_SMPP_REST_TRANSFER, +}_pps_smpp_state; + +/* +typedef enum ivr_state +{ + +}_ivr_state; + +typedef enum ivr_mng_retval +{ + +}_ivr_mng_retval; +*/ + +typedef enum friend_family_call_type +{ + NONE_FRIEND_FAMILY_CALL = 0, + FRIEND_FAMILY_CALL, + FRIEND_FAMILY_FREE_CALL, + FRIEND_FAMILY_FREE_SMS, +}_friend_family_call_type; + +typedef enum inquiry_state +{ + S_INQ_SEND_PROMPT = 1, + S_INQ_SRR0, + S_INQ_SRR, + S_INQ_PLAY_CREDIT_VAULT, + S_INQ_WAIT_CREDIT_VAULT, + S_INQ_PLAY_OPERATION_DONE, + S_INQ_SRR_OPERATION_DONE, + S_INQ_TO_RECHARGE, + S_INQ_TO_RECHARGE_CONFIRM, + S_INQ_REST_GET, +}_inquiry_state; + +typedef enum inq_mng_retval +{ + inq_mng_keep_state = 0, + inq_mng_to_recharge, + inq_mng_exit, +}_inq_mng_retval; + +typedef enum recharge_state +{ + S_REC_CHECK_ACCOUNT_STATUS = 1, + S_REC_INPUT_ACCOUNT , + S_REC_WAIT_ACCOUNT, + S_REC_INPUT_PIN, + S_REC_WAIT_PIN, + S_REC_ACCOUNT_READ, + S_REC_ACCOUNT_CONFRIM, + S_REC_PLAY_BALANCE, + S_REC_WAIT_SRR0, + S_REC_INQ_CHECK_MENU, + S_REC_INPUT_RECHARGE_TYPE, + S_REC_WAIT_TYPE, + S_REC_INPUT_PWD, + S_REC_CHECK_PWD, + S_REC_WAIT_SRR, + S_REC_CHECK_CARD_VALIDITY, + S_REC_INPUT_PWD_AGAIN, + S_REC_CHECK_CARD_WITH_RCM, + S_REC_CHECK_CARD_WITH_REST, + S_REC_CHECK_CARD_WITH_REST_GET, + S_REC_CHECK_CARD_WITH_CRM, +}_recharge_state; + +typedef enum rec_mng_retval +{ + rec_mng_keep_state = 0, + rec_mng_turn_to_ivr_scratch_card, + rec_mng_turn_to_credit_recharge, + rec_mng_exit, +}_rec_mng_retval; + +typedef enum credit_recharge_state +{ + S_CCR_PLAY_INFO, + S_CCR_SSR, + S_CCR_CONNECT_TO_IVR_SCRATCH_CARD, + S_CCR_CONNECT_TO_CREDIT_CENTER, +}_credit_recharge_state; + +typedef enum ccr_mng_retval +{ + ccr_mng_keep_state = 0, + ccr_mng_connect_to_credit_center, + ccr_mng_exit, +}_ccr_mng_retval; + +typedef enum fav_management{ + S_FAV_PLAY_MENU, + S_FAV_SET_TYPE, + S_FAV_INPUT_NEW_NUMBER, + S_FAV_WAIT_NEW_NUMBER, + S_FAV_SET_CONFIRM, + S_FAV_WAIT_CONFIRM, + S_FAV_INPUT_EDIT_NO, + S_FAV_WAIT_EDIT_NO, + S_FAV_INQUIRY, + S_FAV_INQUIRY_READ, +}_fav_management; + +typedef enum fav_mng_retval +{ + fav_mng_keep_state = 0, + fav_mng_exit, + fav_mng_exit_to_main_menu, +}_fav_mng_retval; + +typedef enum language_management{ + S_LANGUAGE_MANAGE_MENU = 1, + S_LANGUAGE_SET, + S_LANGUAGE_SET_CONFIRM, +}_language_management; + +typedef enum _language_mng_retval +{ + language_mng_keep_state = 0, + language_mng_exit , + language_mng_exit_to_main_menu, +}_languange_mng_retval; + +typedef enum pin_management{ + S_PIN_INPUT_OLD_PIN = 1, + S_PIN_CHECK_OLD_PIN, + S_PIN_MANAGE_MENU , + S_PIN_NEW_SET, + S_PIN_SET_AGAIN, + S_PIN_SET_OK, + S_PIN_SET_OK_1, +}_pin_management; + +#ifndef pin_mng_keep_state_value +#define pin_mng_keep_state_value +typedef enum pin_mng_retval +{ + pin_mng_keep_state = 0, + pin_mng_exit, + pin_mng_exit_to_main_menu, +}_pin_mng_retval; +#endif + +typedef enum call_distribution{ + S_CRD_CHECK_CALLER_INFO = 1, + S_CRD_INPUT_VOICEBOX, + S_CRD_SET_DESTINATION, + S_CRD_SET_DEPOSIT, + S_CRD_CONNECT, + S_CRD_SRR, +}_call_distribution; + +typedef enum crd_retval{ + crd_keep_state = 0, + crd_release_call, + crd_wait_answer, +}_crd_retval; + +enum _call_type { + CT_LOCAL_CALL_OUT=PPS_CSTA_TYPE_BASE, + CT_TRUNK_CALL_OUT, // Local city call out + CT_NDD_CALL_OUT, // Nation l.d.tel + CT_HMT_CALL_OUT, // Hong Kong, Macao, TaiWan + CT_IDD_CALL_OUT, // International L.D.Tel + CT_LOCAL_CALL_IN, + CT_TRUNK_CALL_IN, + CT_PERIODIC_CHARGE, + CT_ASSISTED_UP, + CT_ASSISTED_DOWN, + CT_RECHARGE_SUCCESS, + CT_RECHARGE_FAIL, + CT_MO_SM, + CT_MT_SM, + CT_CONFERENCE_CALL, + CT_THIRD_PARTY_CHARGE, + CT_IDD_CALL_IN, + CT_SERVICE, + CT_FREE_SERVICE_CALL, + CT_INVALID_CALL, + CT_MO_CALL, + CT_MT_CALL, + CT_MF_CALL, + CT_INVALID_MO_SMS,// 123 + CT_EMERGENCY_CALL, + + CT_DIRECT_DEBITING = 138, + CT_REFUND_ACCOUNT = 139, + CT_TRANFER_OUT=140, + CT_TRANFER_IN, + CT_GPRS, + CT_VAS_SMS, + CT_VAS_MMS_SEND, + CT_VAS_MMS_RETRIEVE, + CT_VAS_MMS_EMAIL, + CT_BUNDLE_PLAN_CHARGE, + CT_GPRS_REFUND,// 148 + CT_MO_CALLING_CARD_CALL, //149 + CT_RENT_CHARGE_TYPE0=150, + CT_RENT_CHARGE_TYPE1=151, + CT_RENT_CHARGE_TYPE2=152, + CT_RENT_CHARGE_TYPE3=153, + CT_RENT_CHARGE_TYPE4=154, + CT_RENT_CHARGE_TYPE5=155, + CT_RENT_CHARGE_TYPE6=156, + CT_RENT_CHARGE_TYPE7=157, + CT_FF_ACTIVATION, + CT_FF_NUMBER_EDIT, + CT_USSD, + CT_RO_DEBIT, + + CT_MO_CC_CALL, + CT_MAX_CALL_TYPE, +}; + +#define MAX_ASCII_NUMBER_LEN 24 +typedef struct { + u_char nai; + u_char number[MAX_ASCII_NUMBER_LEN]; + u_char IMSI[8]; + char location; + u_char free_flag; + unsigned int valid_time; + float fee; + float charge; + u_short head; + u_short tail; + u_char status; + u_short cug_id; + u_char cos_id; + u_char idd_flag; + u_char expired_flag; +} _account_info; + + +typedef struct { + u_char state; + u_char transferMode; + _account_info account; + int fee; + float promotion; + float validTime; + u_char smsTrigger; + u_char inputSMS[MAX_INPUT_SMS+1]; +}TRANSFER_FEE; + +typedef struct { + u_char state; + u_char destNumber[MAX_ASCII_NUMBER_LEN]; + u_char smsTrigger; + u_char inputSMS[MAX_INPUT_SMS+1]; +}CMB; + +typedef struct{ + u_char state; + u_char choice; + u_char childNum; +}MASTER_SLAVE_ENQUIRY; + +typedef struct{ + u_char state; + u_char choice; + u_char cosID; + _account_info slaveInfo; +}MASTER_SLAVE_ADD; + +typedef struct{ + u_char state; + u_char choice; + _account_info slaveInfo; +}MASTER_SLAVE_DEL; + + +typedef struct { + u_char state; + u_char choice; + _prepaid_info *prepaidInfo; + struct{ + MASTER_SLAVE_ENQUIRY enquiry; + MASTER_SLAVE_ADD add; + MASTER_SLAVE_DEL del; + }masterSlaveFunc; +}MASTER_SLAVE_CARD; + +typedef struct RADIUS_REPORTED_INFO{ + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQ vq; + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VT vt; + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DQ dq; + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DT dt; + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS nasIP; + RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR sgsnIP; +}_RADIUS_REPORTED_INFO; + + +typedef struct _CHARGED_FEE{ + double balance; + double promotion; +}CHARGED_FEE; + +typedef struct gprs_process{ + u_char state; + u_char postpaidState; + u_char prepaidState; + + u_short qid; + float discount; + u_char radiusCommand; + RADIUS_TLV_DECIMAL vqAllocated;// Allocated Quota during the whole session + RADIUS_TLV_DECIMAL vthAllocated; + RADIUS_TLV_DECIMAL vqConsumed;// Pre-charged Quota between each CDR + ulong vqAllocatedThisTime; + ulong dqAllocated; + ulong dqConsumed;// Comsumed Quota during the whole session + ulong dqRefund; + ulong dthAllocated; + ulong inactiveTimer; + ulong accessRequestTimer; + DWORD gsnIP; + DWORD sgsnIP; + DWORD destIP; + u_char location; + CHARGED_FEE chargedFee; + + WORD radiusPid; + u_char userType;/* 1:prepaid user;0:postpaid user */ + ulong volumeMeterUnit; + _gprs_tariff *gprsTariff; + _RADIUS_REPORTED_INFO radiusReportedInfo; + RADIUS_TLV_TS calling_station_id; + RADIUS_TLV_TS acct_session_id; + u_char calculateCount; + u_char calledType; + int update_quote_counter; + RADIUS_ATTRIBUTE_CALLED_STATION_ID *calledList; +}_gprs_process; + +typedef struct _ussd_chnl_info{ + char scUrl[256]; + char prompt[256]; + char input[24]; + char sessId[64]; + u_char sess_state; +}ussd_chnl_info; + +typedef struct { + u_short portid;// handle port + u_char state; /* state of the process */ + u_char sub_state; + u_char sub_state_2; + u_char serviceType; + u_char serviceKey; + u_short correlationID; + unsigned int funnel; /* valid time to talk */ + u_short down; + u_short Tassist; + unsigned int count; /* count down value of process */ + unsigned int duration; + unsigned int charged_duration; + unsigned int fsm_timer; + unsigned int wait_timer; + unsigned int maxCallDuration; + u_char call_type; + u_char answerWanted; + u_short tcos; /* terminate cause */ + u_char oc; /* operation code */ + u_char u_error; + u_char tcend; /* tcend sent when release port */ + u_char tariff_flag; + u_char roamingFlag; /* 0=home, 1=roaming */ + u_char logMsisdn; + u_char dir; /* 0=mo, 1= mt*/ + u_char favoriteCall; + u_char cugCall; + u_char poolCall; + u_short voiceID; + u_char srfRelease; + u_char playAnnouncement; + u_char promptAndCollectUserInfo; + u_char maxPCUInfoLen; + u_char endOfReplyDigit[3]; + u_char serviceInput; + u_char chargeFrom; /* 0=VPS,1=SRF,2=SM */ + u_char chargeOther; + u_char rechargeByOther; + char choice_sn; + u_char connFlag; /* 0=no connectID, 1=connectID need, 2=correlation connected*/ + u_char disconnectForwardConnection; + u_char pre_warning; + u_char editFavNumber; + u_char callConnected; + u_char tmpNumber[12]; + char tmpDigits[MAX_ASCII_NUMBER_LEN]; + u_short chargedTime; /* initial tariff or not */ + u_int realCallDuration; + u_char mnp_status; + char routing_number[MAX_ASCII_NUMBER_LEN]; + u_char palim_auto_register; + u_char all_in_one_input_flag; + u_char cap_flag; + u_char bundle_flag; + u_char cap_plan; + u_char cap_seg; + u_char cap_notify_flag; + u_char currentTier; + _bill_tariff tariff; + _bill_tariff *tariffMtReadOnly;/* readonly,don't modify the content */ + _bill_tariff *tariffMoReadOnly;/* readonly,don't modify the content */ + _bill_sms smsTariff; + u_char callingCardFunction; + u_char callingCardState; + u_char routing_home_flag; + u_char ussd_transfer_one_input_flag; + u_char ccc_flag; + union + { + TRANSFER_FEE feeTransfer; + CMB callMeBack; + MASTER_SLAVE_CARD masterSlaveCard; + _gprs_process gprs_process; + ussd_chnl_info chnl_info; + char areaName[32]; + }ppsService; + u_char update_card_ack; + u_char update_card_result; + u_char send_warning_sms_flag; + int fd_port; + struct + { + u_char gy_ro_enable;// Ro or Gy session + u_char adaptor_enabled; + u_short fd_port; + u_char request_type; + u_char request_action; + u_char recv_cmd; + u_short result; + char apn[64]; + long granted_value; + unsigned int last_updated_duration; + u_char is_final; + u_char no_more_ccr; + //int service_identifier; + u_char post_charge; + u_char last_ro_quota_type;// 0: bundle; 1: cap; for Ro refund + unsigned int last_bundle_duration;// for Ro refund + unsigned int last_cap_duration;// for Ro refund + _gy_msg gy_ccr_info; + }ro_if; + struct + { + u_short src_ref; + u_short dst_ref; + u_short timer; + u_char rest_src; /* 0/1/2=USSD, SMS, VOICE */ + u_char rest_oc; /* 0/1 = query, recharge */ + u_char recv_cmd; + u_char result; + u_char error_code; + long balance; + long mo_expiry_date; + long mt_expiry_date; + u_char query_tariff_status; + int unit; + float unit_charge; + int tariff_discount; + int plan_id; + int bundle_plan_id; + unsigned long long total_plan_value; + unsigned long long used_plan_value; + int sess_update_times; + int busicode; + unsigned long long plan_value_add_this_time; + }rest_if; + +} _process_info; + + + + +typedef struct { + u_char new_flag; + u_char callType; + u_short invoke_id; + u_char mtype;// operation type of session: Ro and Gy are CAP_O_OPEN + u_short dialogue_id; + u_short map_did; /* dialogue id for ATI */ + u_short map_iid; /* invoke id for ATI */ + u_char acn; + u_char acn_ver; + u_char map_acn; + u_char map_acn_ver; + u_char context[CONTEXT_BLOCK_SIZE]; +} _context_info; + +typedef struct _port_info{ + u_char status; /* 0=IDLE, 1=used */ + u_char state; +}_port_info; + + +typedef struct _cdr_info +{ + u_char msisdn[12]; + u_char caller[12]; + u_char called[12]; + u_char cgi[7]; + char locationNumber[24]; + char msc_addr[24]; + char smsc_addr[24]; + unsigned int seizuretime; /* Time that system seizure the request */ + unsigned int answertime; /* Time that system answer the request */ + unsigned int releasetime; /* Time that system release the call */ +}_cdr_info; + +typedef struct +{ + int cardhead; + int cardtail; + float balance; + float cc_call_charge; +}_card_info; + +typedef struct { + _process_info process_info; + _account_info caller_info; + _account_info called_info; + _account_info charge_info; + _account_info recharge_info; + _account_info origin_info; + _context_info context_info; + _cdr_info cdr_info; + _card_info card_info; +} _state_data; + + +/* + * Primary PPS will send periodic Ram sync message, + * and process periodic charging. + * Server will be set non-primary server as initiating, + * server upgrade to primary server + * if it can't receive RAM sync message from another PPS in 5 seconds. + */ +#define PROC_FUNCTION_NUM 16 + +enum _PPS_CAUSE{ + NORMAL_RELEASE, + /* + NO_SUCH_SUBSCRIBER, + ERROR_SUBSCRIBER_STATE, + SUBSCRIBER_EXPIRED, + LOW_BALALNCE, + NO_TARIFF, + TIMER_OUT, + MISSING_HANDSHAKE, + */ + CALLER_STATUS_ERROR=1, + CALLER_CREDIT_OUT, + CALLER_EXPIRIED, + CALLED_STATUS_ERROR, + CALLED_CREDIT_OUT, + CALLED_EXPIRIED, + ACTIVITY_MISSED, + TARIFF_NOT_SET, + BOTH_USER_NOT_PREPAID, + TIMER_OUT, + CALLER_REACH_SMS_LIMIT, + CALLER_REACH_CALL_LIMIT, + CALLER_REACH_CHARGE_LIMIT, + SRVICE_NOT_SUBSCRIBERED, +}; + +enum _PPS_SELF_ERROR{ + _PPS_ERR_SERVICE_NOT_APPLIED=129, + _PPS_ERR_MAX_ERROR, +}; + +enum _function_state{ + STATE_UPDATE_TARIFF, + STATE_PERIODIC_TARIFF, +};//function_state; + +typedef struct { + u_long state_i; + u_long count; + u_long timestamp; +} _proc_data; + +typedef struct { + u_long total_recv_initdp; + u_long total_send_continue; + u_long total_send_release; + u_long total_recv_answer; + u_long total_recv_clear; + u_long total_recv_handshake; + u_long total_send_handshake; + u_long total_send_cdr; + u_long total_recv_other; + u_long total_send_other; +} _statistics; + +#define PPS_FSM_RAMSIZE (80*1024*1024) +#define MAX_LOG_FUNC 32 + +typedef struct func_log{ + u_char funcID; + char func_name[MAX_LOG_FUNC][64]; +}_func_log; + +typedef struct { + _func_log func_log; + _statistics statistics; + _proc_data proc_data[PROC_FUNCTION_NUM]; + _port_info port_info[MAX_FSM_PROCESS]; + _state_data state_data[MAX_FSM_PROCESS]; +} _state_machine; + +typedef struct _date_struct { + int year; + int month; + int day; + int hour; + int minute; + int second; +} _date_struct; + +#define MAX_LOADFILE_NUM 16 +#define MAX_READFILE_NUM 10 + +#define PPS_USER_DATA_DB_OID (0x02) +#define PPS_PREPAID_CARD_DB_OID (0x03) + +#define MAX_DEBUG_MESSAGES 8 + +#define USER_FILE_NAME \ +"/usr/local/subsManage/ppsSubsCreate.csv" +#define COMM_TARIFF_FILE_NAME \ +"/tmp/pre_comm_tariff.csv" +#define RENT_FILE_NAME \ +"/tmp/pre_rent.csv" +#define DISCOUNT_FILE_NAME \ +"/tmp/pre_bill_discount.csv" +#define HOLIDAY_FILE_NAME \ +"/tmp/pre_bill_holiday.csv" +#define TARIFF_FILE_NAME \ +"/tmp/pre_mo_tariff.csv" +#define MT_TARIFF_FILE_NAME \ +"/tmp/pre_mt_tariff.csv" +#define BILL_SMS_FILE_NAME \ +"/tmp/pre_bill_sms.csv" +#define BILL_GPRS_FILE_NAME \ +"/tmp/pre_gprs_tariff.csv" +#define BILL_VAS_MMS_SEND_FILE_NAME \ +"/tmp/pre_vas_mms_send_tariff.csv" +#define BILL_VAS_MMS_RETRIEVE_FILE_NAME \ +"/tmp/pre_vas_mms_retrieve_tariff.csv" +#define BILL_VAS_MMS_EMAIL_FILE_NAME \ +"/tmp/pre_vas_mms_email_tariff.csv" + + +#define USER_LOG_FILE \ +"/usr/local/subsManage/ppsSubsCreate.log" +#define PREPAID_CARD_FILE \ +"/usr/local/subsManage/ppsCardCreate.csv" +#define PREPAID_CARD_LOG_FILE \ +"/usr/local/subsManage/ppsCardCreate.log" + +typedef enum LOAD_FILE_ID +{ + _FILE_ID_USER_DATA, + _FILE_ID_PREPAID_CARD, + _FILE_ID_COMM_TARIFF, + _FILE_ID_RENT_TARIFF, + _FILE_ID_BILL_TARIFF, + _FILE_ID_MT_TARIFF, + _FILE_ID_DISCOUNT, + _FILE_ID_HOLIDY, + _FILE_ID_BILL_SMS, + _FILE_ID_GPRS_TARIFF, + _FILE_ID_VAS_MMS_SEND_TARIFF, + _FILE_ID_VAS_MMS_RETRIEVE_TARIFF, + _FILE_ID_VAS_MMS_EMAIL_TARIFF, +}_LOAD_FILE_ID; + +typedef struct _load_file +{ + u_char flag[MAX_LOADFILE_NUM]; + FILE *fp[MAX_LOADFILE_NUM]; + FILE *log_fp[MAX_LOADFILE_NUM]; +/* index=0/1/2/3/4 file=USER/TPARAM/TARIFF/DSICOUNT/HOLIDAY +*/ +}_load_file; + +#define PARAM_CSV \ +"/usr/local/subsManage/rent.csv" +#define BASICTARIFF_CSV \ +"/usr/local/subsManage/mo_tariff.csv" +#define BASICMTTARIFF_CSV \ +"/usr/local/subsManage/mt_tariff.csv" +#define DISCOUNT_CSV \ +"/usr/local/subsManage/bill_discount.csv" +#define HOLIDAY_CSV \ +"/usr/local/subsManage/bill_holiday.csv" +#define COMM_TARIFF \ +"/usr/local/subsManage/comm_tariff.csv" +#define BILL_SMS_CSV \ +"/usr/local/subsManage/bill_sms.csv" +#define GPRS_TARIFF_CSV \ +"/usr/local/subsManage/gprs_tariff.csv" + +#define VAS_MMS_SEND_CSV \ +"/usr/local/subsManage/vas_mms_send_tariff.csv" +#define VAS_MMS_RETRIEVE_CSV \ +"/usr/local/subsManage/vas_mms_retrieve_tariff.csv" +#define VAS_MMS_EMAIL_CSV \ +"/usr/local/subsManage/vas_mms_email_tariff.csv" + + +typedef enum OMC_OPERATION_CODE{ + OMC_OCODE_NULL, + OMC_OCODE_READ, + OMC_OCODE_EDIT, + OMC_OCODE_ADD, + OMC_OCODE_DEL, + MAX_OMC_OCODE +}_OMC_OPERATION_CODE; + +#define PPS_BACKUP_NAME \ +"/usr/local/backup/ppsMemBak.dat" + +#define PPS_BACKUP_TEMP \ +"/usr/local/backup/ppsMemBak.tmp" + +#define PPS_USER_BACKUP_NAME \ +"/usr/local/backup/ppsSubsBak.dat" +#define PPS_USER_BACKUP_TEMP \ +"/usr/local/backup/ppsSubsBak.tmp" + +#define PPS_RECHARGE_CARD_BACKUP_NAME \ +"/usr/local/backup/ppsRechargeCardBak.dat" +#define PPS_RECAHRGE_CARD_BACKUP_TEMP \ +"/usr/local/backup/ppsRechargeCardBak.tmp" + +#define PPS_TARIFF_DATA_NAME \ +"/usr/local/backup/ppsTariffBak.dat" +#define PPS_TARIFF_DATA_TEMP \ +"/usr/local/backup/ppsTariffBak.tmp" + +typedef enum DATA_SOURCE +{ + _SRC_NO_SRC, + _SRC_PEER_SRV, + _SRC_LOCAL_HD, + _SRC_OMC_HD, +}_DATA_SOURCE; + +typedef enum SYS_STATE +{ + _SYS_STATE_NORMAL, + _SYS_STATE_START, + _SYS_STATE_INIT, + _SYS_STATE_SUSPEND, + _SYS_STATE_SHUTDOWN, +}_SYS_STATE; + +typedef enum INIT_STATE +{ + _INIT_CHECK_VERSION, + _INIT_CHECK_SYNC, + _INIT_READ_FROM_PEER, + _INIT_READ_FROM_LOCAL_HD, + _INIT_READ_FROM_OMC_HD, + _INIT_OVER, + _INIT_UNNORMAL, +}_INIT_STATE; + +typedef enum RAM_OPER +{ + _RAM_OPER_READ=1, + _RAM_OPER_SEND, + _RAM_PERIODIC_SYNC, + _RAM_REAL_SYNC, +}_RAM_OPER; + +enum USSD_SMS{ + USSD_TRANSFER, + SMS_TRANSFER, +}; + +enum SERVICE_RETAL{ + SERVICE_KEEP_STATE, + SERVICE_RETURN_TO_PARENT, + SERVICE_EXIT_PPS, +}; + +enum WAIT_INPUT_RESULT{ + NO_INPUT, + INPUT_SUCCESS, + INPUT_ERROR_REINPUT, + INPUT_ERROR_EXIT, +}; + +enum confirm_command{ + CONFIRM_CANCEL, + CONFIRM_OK, + CONFIRM_ENTER_AGAIN, + CONFIRM_LISTEN_RE, +}; + +enum ChildOrParent{ + MASTER_SLAVE_NONE, + MASTER_SLAVE_PARENT, + MASTER_SLAVE_CHILD, +}; + +enum _TIER_RATING_NUMBER{ + BILL_TIERS_ONE = 0, + BILL_TIERS_TWO, + BILL_TIERS_TRREE, +}; + +enum CHECK_TRANSFERED_FEE_RESULT{ + CHECK_TRANSFERED_FEE_OK, + CHECK_TRANSFERED_FEE_INSUFFIENT, + CHECK_TRANSFERED_FEE_EXPIERED, +}; + +enum NOTIFY_CALLER_OR_CALLED{ + NOTIFY_CALLER, + NOTIFY_CALLED, +}; + + +enum CAP_TYPE{ + CAP_CALL, + CAP_SMS, + CAP_GPRS, +}; +#define MAX_IVR_INPUT_LEN 32 + +int BillingSMSProc(_state_data *shmp, int sms_num); +int load_tariff_main(); +int IdleProc(u_short); +int EstablishProc(int invokeid); +int realSyncTcpSend(DWORD db_type, DWORD instance, DWORD ocode, BYTE *payload, WORD len); +int OCS_with_external_CRM(); +void pps_send_rent_charge_to_crm(int head, int tail); +extern int pps_send_query_tariff_req(u_short portid); +extern int BillingProc_crm(_state_data *shmp, int sub_flag0); +extern int pps_send_update_plan_value_req(u_short portid); +int pps_send_selfcare_topup_req(u_short portid); +int RechargeSucceedwithCRM(u_short portid); +unsigned int ocs_get_ue_index(long long msisdn); +long long ocs_get_ue_by_index(int store_index); +void pps_send_update_subs_status_to_crm(_prepaid_info *user_ptr, int update_flag); + + +#endif /* SMMP__H */ diff --git a/mss/pps/src/include/ppsoid.h b/mss/pps/src/include/ppsoid.h new file mode 100644 index 0000000..415be87 --- /dev/null +++ b/mss/pps/src/include/ppsoid.h @@ -0,0 +1,59 @@ +/* +** +** +** file name: ppsoid.h +** +** Prepaid server object id defination tree, +** +*/ + +#ifndef PPSOID__H +#define PPSOID__H +#include +#include "../../../../plat/snmp/src/include/snmp.h" + +typedef enum { + WAVELOOP_SYSTEM=1, + WAVELOOP_OMC, + WAVELOOP_HLR, + WAVELOOP_VLR, + WAVELOOP_CDR, + WAVELOOP_LAN, + WAVELOOP_CSU, + WAVELOOP_VPS, + WAVELOOP_PCR, + WAVELOOP_BSC, + WAVELOOP_BTS, + WAVELOOP_PPS=0x92, +} _WAVEloop_oid; + +typedef enum { + ppsParam_DB=2, + PPS_ACCOUNT_DB, + PPS_RECHARGE_DB, + PPS_TARIFF_DB, +} _pps_database_id; + +typedef enum { + PARAM_GLOBAL=1, + PARAM_ZONE, + PARAM_IVR_COMMON, + PARAM_IVR_SYNTAX, + PARAM_IVR_DIGIT, +} _ppsParam_db; + +typedef enum { + CDR_STATISTICS=1, + CDR_CHARGESUM, + CDR_DURATIONSUM, +} _pps_csta_oid; + + +#define PPS_CONFIGURE 0x02 + +int initSNMP(); +int snmpSetPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, u_short dataLen); +int snmpGetPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, BYTE *vartype); +void snmpTrapPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, u_short dataLen,snmp_addr *addr); + +#endif /* PPSOID__H */ diff --git a/mss/pps/src/include/precard.h b/mss/pps/src/include/precard.h new file mode 100644 index 0000000..a48f067 --- /dev/null +++ b/mss/pps/src/include/precard.h @@ -0,0 +1,82 @@ +#ifndef _PRECARD_H +#define _PRECARD_H + +#include "ramdata.h" + +#define MAX_USED_CARD_STORED 8192 +#define MAX_CLIMAX_CARD_SEGMENT 50 /* 5000 cards stored */ +#define MAX_PREPAID_CARD_NUM (MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG) + +typedef struct USED_PREPAID_CARD_BUFFER{ + int ptrHead; + int ptrTail; + _recharge_card_info used_precard[MAX_USED_CARD_STORED]; +}_USED_REPAID_CARD_BUFFER; + +typedef struct free_mem_quence +{ +// int front_ptr; +// int rear_ptr; + int pWriteSub; + int free_pos[MAX_PREPAID_CARD_NUM+1]; +}_free_mem_quence; + +typedef struct climax_quence +{ + int counter; + int store_pos[MAX_PREPAID_CARD_NUM]; + int store_pos_card_no[MAX_PREPAID_CARD_NUM]; + u_char card_pwd[MAX_PREPAID_CARD_NUM][MAX_CARD_HRN_BLEN]; + long long card_no[MAX_PREPAID_CARD_NUM]; +}_climax_quence; + +typedef struct card_index +{ + _free_mem_quence free_quence; + _climax_quence card_quence; +}_card_index; + +typedef enum SCF_RCM_OC +{ + OC_NULL, + OC_UPDATE_CARD, + OC_UPDATE_CARD_ACK, +}_SCF_RCM_OC; + +typedef enum SCF_RCM_RESULT +{ + OC_RESULT_OK, + OC_RESULT_NO_CARD, + OC_RESULT_CARD_USED, + OC_RESULT_CARD_EXPIRED, + OC_RESULT_SYSTEM_FAILURE, +}_SCF_RCM_RESULT; + +typedef struct scf_rcm_msg{ + u_short invoke_id; + u_char ocode; + u_char result; + u_char card_pwd[MAX_CARD_HRN_BLEN]; + char msisdn[32]; + _recharge_card_info card_data; +}_scf_rcm_msg; + +int StorePrepaidCard(int *head_no, int head); +int InquiryPrepaidCardStorePos(long long head); +void CardHeadInDecrement(int flag); +void CardNumberInDecrement(int flag); +int ImportPrepaidCardData(char *carddata); +int RechargeCardRequest(u_short proc_id,char *card_hrn,int *result); +int SendPrepaidCardRealSync(int instance,int ocode); +int UpdateRechargeCard(u_short proc_id, int status); +int SetPrepaidCardByOMC(u_char oidlen, DWORD *oid, u_char *pdata, u_short datalen); +int GetUsedPrepaidCard(u_char oidlen, DWORD *oid, u_char *pdata, BYTE *vartype); +int SetPrepaidCardFaceValue(long face_value); +void MoveUsedCardToBuffer(int instance); +void DeletePrepaidCardHead(int cardhead); + +float ocs_get_calling_card_left_balance(int head, int tail); +int UpdateRechargeCardBalance(_card_info *cardshmp, float charge); + +#endif + diff --git a/mss/pps/src/include/public.h b/mss/pps/src/include/public.h new file mode 100644 index 0000000..f811ce6 --- /dev/null +++ b/mss/pps/src/include/public.h @@ -0,0 +1,102 @@ +/* +** +** File name: public.h +** +** +*/ + +#ifndef _PPS_PUBLIC__H +#define _PPS_PUBLIC__H + +#include + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned int DWORD; +#endif + +#ifndef _T_BOOL +#define _T_BOOL +typedef int BOOL; +#endif + +#ifndef NORMAL +#define NORMAL (1) +#endif + +#ifndef ABNORMAL +#define ABNORMAL (-1) +#endif + +#ifndef STANDBY +#define STANDBY (0) +#endif + +#ifndef SUCCESS +#define SUCCESS (0) +#endif + +#ifndef FAILURE +#define FAILURE (-1) +#endif + +//#ifndef OVERFLOW +//#define OVERFLOW (-1) +//#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef YES +#define YES (1) +#endif + +#ifndef NO +#define NO (0) +#endif + +#ifndef LED_ON +#define LED_ON (1) +#endif + +#ifndef LED_OFF +#define LED_OFF (0) +#endif + +#ifndef ERROR +#define ERROR (-1) +#endif + +#ifndef EMPTY +#define EMPTY (0) +#endif + +//#define BUFSIZE 8196 + +//#define MAXBUFLEN 8196 +//#define MAXLINE 4096 + +typedef enum _number_type { + T_BIN, T_OCT, T_DEC, T_HEX +} _number_type; + + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#endif /* PUBLIC__H */ diff --git a/mss/pps/src/include/ramdata.h b/mss/pps/src/include/ramdata.h new file mode 100644 index 0000000..86559eb --- /dev/null +++ b/mss/pps/src/include/ramdata.h @@ -0,0 +1,555 @@ +/* +** The module Copyright (C) 2000-2008 interWAVE Inc. +** Written completely by Liang Hongbin +*/ + +#ifndef RAMDATA__H +#define RAMDATA__H +#include + +#define RAMDATA_PACK_SIZE 1024 +#define RAMDATA_PACK_NUM (60*1024) +#define RAMDATA_BLOCK_SIZE (RAMDATA_PACK_SIZE*RAMDATA_PACK_NUM) /* Ram block size is 24MB */ + +#define T_LOW_BALANCE 1 +#define T_EXPIRED 1 + +#define POOL_MAX_CHILD 5 + +#define OCS_WITH_CRM 1 + +typedef enum account_status { + T_FRESH, /* fresh account, can't dial in or out, + but can recharge. */ + T_NORMAL, /* normal account */ + T_SUSPEND, + T_BLACKLIST, + T_RELEASED, + T_OPRTRIAL, + T_DISABLE, + MAX_USER_TYPE, + + T_EXTERNAL=10, +} _account_status; + +typedef struct data_info +{ + u_char version[3]; + u_long dataSize; +}_data_info; + +typedef enum favorite_number{ + NOT_FAVORITE_NUMBER, + FAVORITE_NUMBER, +}_favorite_number; + +typedef enum last_call{ + LST_MO_CALL, + LST_MT_CALL, + LST_MF_CALL, + LST_MO_SMS, +}_last_call; + +#define MAX_FAVORITE_NUMBERS 5 +#define MAX_MSISDN_BLEN 10 +#define MIN_MSISDN_ALEN 6 +#define MAX_MSISDN_ALEN 16 +#define MAX_PIN_LEN 6 +#define MAX_HOME_LOCATION 4 +#define MAX_PPS_USER_FIELD_NUMS 68 + +typedef struct prepaid_info_old { + u_char msisdn[MAX_MSISDN_BLEN]; + char pin[MAX_PIN_LEN]; + u_char status; + double balance; + double promo_balance; + long overdraft; + u_long first_used_date; + u_long mo_expiration_date; /* outgoing */ + u_long mt_expiration_date; /* incoming */ + u_long promo_date; + u_char cos_id; + u_char rent_type; + u_char home_location[MAX_HOME_LOCATION]; + u_short cug_id; + u_char language_type; + u_char recharge_fail; + u_char free_sm_counter; + u_char latch_flag; + u_char favorite_numbers; + /* favorite number set flag + 0=no favorite number set, + otherwise = favorite number sets */ + u_char fav_change_counter; /* favorite number edit counter */ + u_char favorite_number[MAX_FAVORITE_NUMBERS][MAX_MSISDN_BLEN]; + u_char last_call_type; + u_long last_call_date; + u_char last_call_number[MAX_MSISDN_BLEN]; + double in_net_cap_sms_balance; + u_short in_net_cap_sms_counter; + double out_net_cap_sms_balance; + u_short out_net_cap_sms_counter; + double in_net_cap_balance; + double out_net_cap_balance; + double in_net_cap_call_balance; + u_long in_net_cap_call_duration; + double out_net_cap_call_balance; + u_long out_net_cap_call_duration; + +} _prepaid_info_old; + +typedef struct last_call_info +{ + u_char last_call_type; + u_long last_call_date; + u_char last_call_number[MAX_MSISDN_BLEN]; +}_last_call_info; + +typedef struct{ + u_char childNumber; + u_char changeTimes; + u_char childMsisdn[POOL_MAX_CHILD][MAX_MSISDN_BLEN]; +}PoolParent; + +typedef struct{ + u_char parentMsisdn[MAX_MSISDN_BLEN]; + u_short callsToday; + u_short smsToday; + double chargedToday; +}PoolChild; + +typedef struct{ + u_char role; + struct{ + PoolParent parent; + PoolChild child; + }roleParty; +}UserData_Pool_Account; + +typedef struct bundle_info +{ + long long data; /*left in, in B */ + int mo_voice; /* in seconds */ + int mt_voice; + u_short sms; + u_long validity_date; + int warning_sms_flag;// If has already sent sms notification for bundle insufficent, will not send notification again + char cRes[4]; + int iRes[2]; +}_bundle_info; + +typedef struct crm_info +{ + int customer_id; + int account_id; + int product_id; + u_long birthday; + int base_plan_id; + int rent_charge; + int new_plan_id; + int new_rent_charge; + u_char vas_cug_state; /*0=not used, 1=normal, 2=suspended */ + u_long ulRes[4]; + int iRes[4]; + u_char user_class; + u_char ucRes[3]; +}_crm_info; + + +typedef struct prepaid_info { + u_char msisdn[MAX_MSISDN_BLEN]; + char pin[MAX_PIN_LEN]; + u_char status; + double balance; + double promo_balance; + long overdraft;// amount that can overdraft + u_long first_used_date; + u_long mo_expiration_date; /* outgoing */ + u_long mt_expiration_date; /* incoming */ + u_long promo_date; + u_char cos_id; + u_char rent_type; + u_char home_location[MAX_HOME_LOCATION]; + u_short cug_id; + u_char language_type; + u_char recharge_fail; + u_char free_sm_counter; + u_char latch_flag; + u_char favorite_numbers; + /* favorite number set flag + 0=no favorite number set, + otherwise = favorite number sets */ + u_char fav_change_counter; /* favorite number edit counter */ + u_char favorite_number[MAX_FAVORITE_NUMBERS][MAX_MSISDN_BLEN]; + u_char last_call_type; + u_long last_call_date; + u_char last_call_number[MAX_MSISDN_BLEN]; + + /*following fields are designed for cap CALL/SMS,Pierre, 2007-07-13 */ + + double in_net_cap_sms_balance; + u_short in_net_cap_sms_counter; + double out_net_cap_sms_balance; + u_short out_net_cap_sms_counter; + + double in_net_cap_call_balance; + u_long in_net_cap_call_duration; + double out_net_cap_call_balance; + u_long out_net_cap_call_duration; + + double call_in_cap_balance; + u_long call_in_cap_duration; + + double in_net_cap_balance; + double out_net_cap_balance; + + long long gprsVolume; + long long gprsVolumeThisMonth; + double gprsBalance; + u_short gprsNotificationTimes; + + u_char freeSMSActiveDays; + + UserData_Pool_Account poolAccount; + + u_char callMeBackRequestTimes; + u_char favorite_plan_id; /* 0=default, not plan user, 1-6=index0-5*/ + u_char favorite_plan_state; /* 0=ok, 1=suspended */ + u_char cap_sms_notify_counter; + u_char cReseverd[3]; + u_long free_favorite_call; /* in seconds */ + u_long free_favorite_sms; + double dReserved[2]; + + _bundle_info bundle_info; +#ifdef OCS_WITH_CRM + _crm_info crm_info; +#endif +} _prepaid_info; + +#define INVALID_UE_INDEX 0xFFFFFFFF + + +#define UNIT_STORE_ACCOUNT 100 +#define MSISDN_HEAD_NUM 600 //1000 +#define MAX_SUBS_RECORD (MSISDN_HEAD_NUM*UNIT_STORE_ACCOUNT) + +typedef struct prepaid_data_old{ + long long msisdn_head[MSISDN_HEAD_NUM]; + _prepaid_info_old prepaid_info[MSISDN_HEAD_NUM][UNIT_STORE_ACCOUNT]; +} _prepaid_data_old; + +typedef struct prepaid_data { + long long msisdn_head[MSISDN_HEAD_NUM]; + _prepaid_info prepaid_info[MSISDN_HEAD_NUM][UNIT_STORE_ACCOUNT]; +} _prepaid_data; + + +#define MAX_CARD_HRN_BLEN 8 +#define MAX_CARD_HRN_ALEN 16 +#define MAX_CARD_SEGMENT 2000 +#define MAX_CARD_NUM_PSEG 100 +#define MAX_CARD_RECORD (MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG) +#define MAX_CARD_LENGTH 10 +#define MAX_CUG_ID 10000 +#define NOT_CUG_ACCOUNT 0 + +#define CARD_TAIL_LEN 2 + +#define MAX_VALUE_TYPE 8 + +#define _RCI_ _recharge_card_info +#define _recharge_card _recharge_card_info + +typedef enum CARD_STATUS{ + CARD_FRESH, + CARD_USED, + CARD_SUSPEND, + CARD_LONG_TIME_NOT_USED, + CARD_AS_CC_USED, +}_CARD_STATUS; + +typedef struct { + u_char card_no[MAX_CARD_LENGTH+1]; /* 'E' fill at the end */ + u_char card_pwd[MAX_CARD_HRN_BLEN+1]; + long face_value; + u_char card_status; + u_long expiry_date; + u_short valid_time; + char msisdn_used[18]; + u_long updated_date; +} _recharge_card_info; + +typedef struct card_data{ + long face_value[MAX_VALUE_TYPE]; + u_char segment_used_flag[MAX_CARD_SEGMENT]; + long long prepaid_card_head[MAX_CARD_SEGMENT]; + _recharge_card_info prepaid_card[MAX_CARD_SEGMENT][MAX_CARD_NUM_PSEG]; +}_card_data; + +#define BILLING_BASE_NUM 1024 /* number used by billing */ +#define MAX_DISCOUNT_ID 32 +#define MAX_ZONE_NUM_OLD 16 +#ifdef _MAX_64COS_COOK_ +#define MAX_ZONE_NUM 64// used in Cook island, Diego +#else +#define MAX_ZONE_NUM 16// used for PNCC etc +#endif +#define MAX_RENT_TARIFF 8 +#define CALLED_BASE_NUM 50 +#define MAX_MO_CALLTYPE 5 +#define MAX_MT_CALLTYPE 4 +#define MAX_SMS_PREFIX 50 +#define TARIFF_PREFIX_LEN 16 + +#define MAX_GPRS_PREFIX 1 + +#define MAX_VAS_MMS_SEND_TARIFF 64 +#define MAX_VAS_MMS_RETRIEVE_TARIFF 1 +#define MAX_VAS_MMSEMAIL_DELIVER_TARIFF 1 + + +#define COS_GROUP_NUM 16 +#define MAX_ZONE_NUM_NEW (MAX_ZONE_NUM/COS_GROUP_NUM) + +/* +Charge on receiving call is not defined , 2003-10-10 +*/ + +typedef struct comm_tariff +{ + u_short cfChargeUnit; /* call forward */ + float cfChargeAmount; + u_short roamingChargeUnit; /* roaming within province */ + float roamingChargeAmount; /* roaming within province */ + u_short cugChargeUnit; + float cugChargeAmount; + u_short ccChargeUnit; /*conference call */ + float ccChargeAmount; + float favEditChargeAmount; + u_short favChargeUnit; /* favorite number call */ + float favChargeAmount; + u_short cf_cugChargeUnit; /* call forward + cug */ + float cf_cugChargeAmount; + u_short cf_favChargeUnit; /* call forward + favorite number */ + float cf_favChargeAmount; + u_short cug_favChargeUnit; /* cug + favorite number */ + float cug_favChargeAmount; + u_short cf_cug_favChargeUnit; /* call forward + cug + favorite number */ + float cf_cug_favChargeAmount; + + float childChangeChargeAmount; + u_short poolAccountChargeUnit; + float poolAccountChargeAmount; + float activeFreeSMSCharegeAmount; + float deactiveFreeSMSCharegeAmount; +}_comm_tariff; + + +typedef struct _TIER_INFO{ + u_long units; + float base_fee; + float long_distance_fee; +}TIER_INFO; + +#define MAX_TIER 3 +#define TARIFF_AREA_LEN 31 + +typedef struct{ + u_char tierNumber; + TIER_INFO rating[MAX_TIER]; +}TIER_RATING; + +typedef struct bill_tariff { + char bill_id[TARIFF_PREFIX_LEN+1]; + char area[TARIFF_AREA_LEN]; + char cap_flag; + u_char call_type; + u_char tariffID; + u_char discountID; + u_char free_time; /*0-240 seconds*/ + u_short unit_time; + u_char mini_unit; + float adjustment; + TIER_RATING tierRating; +} _bill_tariff; + +typedef struct rent_tariff { + u_char id; /* from 0-15 */ + char description[16]; + u_char rent_type; /*0: daily, 1: monthly */ + u_char charge_date; /* monthly day : 1-28*/ + float rent_amount; +} _rent_tariff; + +typedef struct bill_discount +{ + u_char discount_id; + u_char hours; + u_char days[8]; +} _bill_discount; + +typedef struct bill_holiday +{ + u_char month; + u_char day; + u_char mflag; +} _bill_holiday; + +#define DEFAULT_MT_BILLING 0 +#define DEFAULT_SMS_BILLING 0 + +typedef struct bill_sms +{ + u_char id; + char bill_id[TARIFF_PREFIX_LEN+1]; + u_char call_type; + char area[31]; + char cap_flag; + u_char tariffID; + u_char discountID; + float base_fee; +}_bill_sms; + +typedef struct gprs_tariff { + u_char tariffID; + u_char gprsID; + ulong destIp; + u_short chargeUnit; /* KB */ + float basicFee; + u_short miniChargeUnit;/* KB */ + u_short initialAdjustment; + char cap_flag; + u_char discountID; + u_char reserved[32]; +} _gprs_tariff; + + +typedef struct _VAS_MMS_SEND_TARIFF{ + u_char tariffID; + u_char mmsSendID; + u_char mmsType; + u_char prefix[128]; + u_char callType; + u_char destName[128]; + u_char discountID; + float chargeFee; + u_char capFlag; + u_char reserved[32]; +}VAS_MMS_TARIFF; + + +typedef struct _VAS_MMS_RETRIEVE_TARIFF{ + u_char tariffID; + u_char mmsRetrieveID; + u_char prefix[128]; + u_char callType; + u_char destName[128]; + u_char discountID; + float chargeFee; + u_char capFlag; + u_char reserved[32]; +}VAS_MMS_RETRIEVE_TARIFF; + + +typedef struct _VAS_MMSEMAIL_RETRIEVE_TARIFF{ + u_char tariffID; + u_char emailID; + u_char prefix[128]; + u_char callType; + u_char destName[128]; + u_char discountID; + float chargeFee; + u_char capFlag; + u_char reserved[32]; +}VAS_MMSEMAIL_DELIVER_TARIFF; + + +typedef struct _VAS_TARIFF{ + VAS_MMS_TARIFF vasMmsSendTariff[MAX_VAS_MMS_SEND_TARIFF]; + VAS_MMS_RETRIEVE_TARIFF vasMmsRetrieveTariff[MAX_VAS_MMS_RETRIEVE_TARIFF]; + VAS_MMSEMAIL_DELIVER_TARIFF vasMmsEmailDeliverTariff[MAX_VAS_MMSEMAIL_DELIVER_TARIFF]; +}VAS_TARIFF; + +typedef struct base_tariff { + char bill_id[TARIFF_PREFIX_LEN+1]; + char area[TARIFF_AREA_LEN]; + u_char call_type; +} _base_tariff; + + +typedef struct tariff_data_old { + _comm_tariff comm_tariff[MAX_ZONE_NUM_OLD]; + _rent_tariff rent_tariff[MAX_ZONE_NUM_OLD][MAX_RENT_TARIFF]; + _bill_tariff bill_tariff[MAX_ZONE_NUM_OLD][BILLING_BASE_NUM]; + _bill_tariff called_tariff[MAX_ZONE_NUM_OLD][CALLED_BASE_NUM]; + _bill_discount bill_discount[MAX_DISCOUNT_ID][24]; /* id=9 for sms */ + _bill_holiday holiday_flag[12][31]; + _bill_sms bill_sms[MAX_ZONE_NUM_OLD][MAX_SMS_PREFIX]; +} _tariff_data_old; + +typedef struct tariff_data { + _comm_tariff comm_tariff[MAX_ZONE_NUM]; + _rent_tariff rent_tariff[MAX_ZONE_NUM][MAX_RENT_TARIFF]; + _bill_tariff bill_tariff[MAX_ZONE_NUM][BILLING_BASE_NUM]; + _bill_tariff called_tariff[MAX_ZONE_NUM][CALLED_BASE_NUM]; + _bill_discount bill_discount[MAX_DISCOUNT_ID][24]; /* id=9 for sms */ + _bill_holiday holiday_flag[12][31]; + _bill_sms bill_sms[MAX_ZONE_NUM][MAX_SMS_PREFIX]; + _gprs_tariff gprs_tariff[MAX_ZONE_NUM][MAX_GPRS_PREFIX]; + VAS_TARIFF vas_tariff[MAX_ZONE_NUM]; + _base_tariff base_tariff[BILLING_BASE_NUM]; +} _tariff_data; +/*---------*/ + +typedef struct pps_free_index +{ + int user_counter; /* account counter */ + int pWriteSub; + u_char status[MAX_SUBS_RECORD]; + int free_memory[MAX_SUBS_RECORD]; +}_pps_free_index; + +typedef struct pps_index_node +{ + long long key; + int store_index; +}_pps_index_node; + +typedef struct pps_index_table +{ + _pps_index_node prim_index[MAX_SUBS_RECORD]; +}_pps_index_table; +/* index table is part of shm memory , and sync. between 2 plans */ + +typedef struct pps_index_db +{ + _pps_free_index free_index; + _pps_index_table index_table; +}_pps_index_db; + +typedef struct _ram_data_old{ + _tariff_data_old tariff_data; + _card_data card_data; + _prepaid_data prepaid_data; + _pps_index_db index_data; +} _ram_data_old; + +typedef struct _ram_data{ + _tariff_data tariff_data; + _card_data card_data; + _prepaid_data prepaid_data; + _pps_index_db index_data; +} _ram_data; + +/* all data should be divided into 3 files: +tariff +recharge_card +account +*/ + + + +#endif /* RAMDATA__H */ + diff --git a/mss/pps/src/include/report.h b/mss/pps/src/include/report.h new file mode 100644 index 0000000..9fc176c --- /dev/null +++ b/mss/pps/src/include/report.h @@ -0,0 +1,153 @@ +#ifndef _REPORT_H +#define _REPORT_H + +#include "ramdata.h" + +#define MAX_RECORDS_SAVED 7 +#define MAX_CALL_TYPE 16 + +typedef struct account_report +{ + u_long user_num[MAX_USER_TYPE]; + u_long total_num; + double total_balance; +}_account_report; + + +typedef struct prepaid_card_report +{ + float face_value[MAX_VALUE_TYPE]; + u_long used_today[MAX_VALUE_TYPE]; + u_long total_used[MAX_VALUE_TYPE]; + u_long unused[MAX_VALUE_TYPE]; +}_prepaid_card_report; + + + +typedef enum call_type +{ + INCOMING_CALL = 0, + LOCAL_CALL_OUT, + IDD_CALL, + NDD_CALL, + RENT_CHARGE, + AST_RECHARGE, + AST_CHARGE, + RECHARGE_SUC, + RECHARGE_FAIL, + SHORT_MESSAGE, + CONFERENCE_CALL, + SERVICE_CHARGE, + SERVICE_GPRS = 16, + SERVICE_CCC, + MAX_SERVICE_TYPE, +}_call_type; + +typedef struct call_record +{ + int call_type; + u_long call_times; + u_long call_duration; + double call_charge; +}_call_record; + +typedef struct gprsRecord +{ + long long gprsVolume; + long long gprsDuration; + double gprsCharge; +}_gprs_record; + +typedef struct _pps_vas_record +{ + u_long smsNumber; + double smsCharge; + u_long mmsSendNumber; + double mmsSendCharge; + u_long mmsRetrieveNumber; + double mmsRetrieveCharge; + u_long mmsEmailNumber; + double mmsEmailCharge; +}_pps_vas_record; + +typedef struct call_report +{ + u_long total_call_num; + u_long total_call_duration; + double total_call_charge; + _call_record call_record[MAX_CALL_TYPE]; + _gprs_record gprs_record; + _pps_vas_record vas_record; +}_call_report; + +typedef struct balance_summary +{ + double yesterday_balance; + double today_recharge; + double today_charge; + double today_balance; +}_balance_summary; + +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report +#define USSDCODE_QUERY_CODE_STR "114" +#define USSDCODE_TOPUP_CODE_STR "113" +#define USSDCODE_HOTLINE_CODE_STR "117" + +#define USSDCODE_TYPE_QUERY 0 +#define USSDCODE_TYPE_TOPUP 1 +#define USSDCODE_TYPE_HOTLINE 2 +#define USSDCODE_TYPE_CHANNEL 3 +#define USSDCODE_MAX_CODE_NUM 8 + +#define USSDCODE_STAT_REQ 0 +#define USSDCODE_STAT_DUR 1 +#define USSDCODE_STAT_ERR_TIMEOUT 2 +#define USSDCODE_STAT_ERR_SYSTEM 3 +#define USSDCODE_STAT_ERR_MSG 4 + +typedef struct ussdcode_report +{ + char code[8];// 114,113,117,101/707 + //char type[12];// query,topup,hotline,channel + unsigned int req_count; + unsigned int req_duration;// Sec + + unsigned int err_timeout_count; + //unsigned int err_network_count; + unsigned int err_system_count; + unsigned int err_msg_count; +}_ussdcode_report; + +int pps_update_ussd_code_state(char *code, int type, int result, int dur); +#endif + +typedef struct daily_report +{ + int year_month_day[3]; + _account_report account_report; + _prepaid_card_report prepaid_card_report; + _call_report call_report; + _balance_summary balance_summary; +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + _ussdcode_report ussdcode_report[USSDCODE_MAX_CODE_NUM]; +#endif +}_daily_report; + +typedef struct _pps_report +{ + int ptrTail; + int saveHead; + int saveTail; + _daily_report daily_report[MAX_RECORDS_SAVED]; + _daily_report peer_daily_report[MAX_RECORDS_SAVED]; +}_pps_report; + + +void reportInit(); +int reportCreatedDaily(); +int reportCDRIncrement(int calltype, int duration, float charge,ulong gprsVolume); +int reportAccount(int segmentno); +int reportPrepaidCard(int segmentno); +int GetDailyReport(u_char oidLen, DWORD *oid, u_char *pdata, BYTE *vartype); + +#endif diff --git a/mss/pps/src/include/restapi.h b/mss/pps/src/include/restapi.h new file mode 100644 index 0000000..b9b0ab8 --- /dev/null +++ b/mss/pps/src/include/restapi.h @@ -0,0 +1,829 @@ +#ifndef _RESTAPI_H +#define _RESTAPI_H + +#include "../../../../plat/public/src/include/public.h" + +#define MAX_BODY_LEN 1024 + +#define REST_PROXY_PORT 4951 + +enum RESULT_TYPE +{ + RES_SUCCEED = 0, + RES_FAILED = 1, +}; + +enum ERROR_CODE +{ + ERR_REST_SUCCESS = 2001, + ERR_REST_COMMAND_UNSUPPORTED=3001, + ERR_REST_UNKNOWN_PEER = 3010, + ERR_REST_INVALID_USER_STATUS = 4001, + ERR_REST_DEST_USER_NOT_ALLOWED = 4008, + ERR_REST_CREDIT_LIMIT = 4012, + ERR_REST_INVALID_PARAMETER_VALUE=5004, + ERR_REST_MISSING_PARAMETER = 5005, + ERR_REST_INVALID_RECHARGE_PWD = 5006, + ERR_REST_UNABLE_TO_COMPLY=5012, + ERR_REST_USER_UNKNOWN = 5030, + ERR_REST_NO_LICENSE = 5040, +}; + +enum REST_PROXY_MSG_TYPE +{ + REST_QUERY=1, + REST_TOPUP=2, + REST_TRANSFER=3, + + REST_ORDER=0x84, + REST_FREE_RESOURCE=0x85, + REST_DOWNLOAD_APP=0x86, + REST_CHANNEL=0x87, + REST_OFFER_CHANGE=0x88, + REST_POINT_QUERY=0x89, + REST_POINT_TRANSFER=0x8a, + + // for selfcare + REST_SEND_AUTHCODE_REQ=5, + REST_SEND_AUTHCODE_RSP=6, + REST_QUERY_USERDATA_REQ=7, + REST_QUERY_USERDATA_RSP=8, + REST_BUNDLE_SUBS_REQ=9, + REST_BUNDLE_SUBS_RSP=10, + REST_BUNDLE_USAGE_REQ=11, + REST_BUNDLE_USAGE_RSP=12, + REST_RECHARGE_REQ=13, + REST_RECHARGE_RSP=14, + REST_TRANSFER_REQ=15, + REST_TRANSFER_RSP=16, + REST_RECHARGE_CARD_REQ=17, + REST_RECHARGE_CARD_RSP=18, + REST_CHECK_BALANCE_REQ=19, + REST_CHECK_BALANCE_RSP=20, + REST_QUERY_BALANCE_REQ=21, + REST_QUERY_BALANCE_RSP=22, + + REST_QUERY_RECHARGE_CARD_REQ=23, // query recharge card interface from CRM + REST_QUERY_RECHARGE_CARD_RSP=24, + REST_UPDATE_RECHARGE_CARD_REQ=25, // update recharge card interface with CRM + REST_UPDATE_RECHARGE_CARD_RSP=26, + + REST_CRM_PAYMENT_REQ=27, + REST_CRM_PAYMENT_RES=28, + + REST_CRM_SMS_DELIVER_REQ=29, + REST_CRM_SMS_DELIVER_RES=30, + + REST_CRM_CREATE_ACCT_REQ=31, + REST_CRM_CREATE_ACCT_RES=32, + + REST_CRM_QUERY_TARIFF_REQ=33, + REST_CRM_QUERY_TARIFF_RES=34, + + REST_CRM_UPDATE_SUBS_REQ=35, + REST_CRM_UPDATE_SUBS_RES=36, + + REST_CRM_DELETE_SUBS_REQ=37, + REST_CRM_DELETE_SUBS_RES=38, + + REST_CRM_UPDATE_SESS_INFO_REQ=39, + REST_CRM_UPDATE_SESS_INFO_RES=40, + + REST_CRM_UPDATE_PLAN_INFO_REQ=41, + REST_CRM_UPDATE_PLAN_INFO_RES=42, + + REST_CRM_RENT_CHARGE=43, + REST_CRM_RENT_CHARGE_RES=44, + + +}; + +#if 0 +enum PAY_TYPE +{ + PAY_TYPE_BALANCE = 1, + PAY_TYPE_PAYPAL = 2, + PAY_TYPE_VISA = 3, + PAY_TYPE_MASTER = 4, +}; + +enum ACCT_STATUS +{ + AS_FRESH, /* fresh account, can't dial in or out, + but can recharge. */ + AS_NORMAL, /* normal account */ + AS_SUSPEND, + AS_BLACKLIST, + AS_RELEASED, + AS_OPRTRIAL, + //AS_MAX_USER_TYPE, + + AS_EXTERNAL=10, +}; +#endif + +enum REST_IE_TAG +{ + IE_SRC_REF=1, + IE_DST_REF, + IE_MSISDN, + IE_RESULT, + IE_ERROR_CODE, + IE_BALANCE, + IE_MO_EXPIRY, + IE_MT_EXPIRY, + IE_USERNAME, + IE_PASSWORD, + IE_MSG_CONTENT, //value=11 + IE_STATUS, + IE_REMARK, + IE_GROUP_NAME, + IE_MO_VOICE_MIN,// in minute + IE_REMAIN_MO_VOICE_SEC,// in second + IE_REMAIN_MO_VOICE_MIN,// in minute + IE_MT_VOICE_MIN,// in minute + IE_REMAIN_MT_VOICE_SEC,// in second + IE_REMAIN_MT_VOICE_MIN,// in minute + IE_SMS_NUM, //value=21 + IE_REMAIN_SMS_NUM, + IE_DATA_VOL_MB,// in MB + IE_REMAIN_DATA_VOL_KB,// in KB + IE_REMAIN_DATA_VOL_MB,// in MB + IE_PAY_TYPE, + IE_AMOUNT, + IE_VALID_DAYS, + IE_EXPIRY_TIME, + IE_MSISDN_TRANS_OUT, + IE_MSISDN_TRANS_IN, //value=31 + IE_BALANCE_AVAILABLE, + IE_RECHARGE_AMOUNT, + IE_RECHARGE_TYPE, + IE_RECHARGE_CARD_STATUS, + IE_RECHARGE_CARD_FACE_VALUE, + IE_RECHARGE_CARD_EXPIRED_TS, + IE_RECHARGE_CARD_UPDATED_TS, + IE_CUSTOMER_ID, + IE_ACCOUNT_ID, + IE_PRODUCT_ID, //value=41 + IE_PLAN_ID, + IE_RENT_CHARGE, + IE_BIRTHDAY, + IE_SMS_CONTENT, + IE_SERVICE_TYPE, + IE_TARIIFF_PREFIX, + IE_TARIFF_UNIT, + IE_TARIFF_CHARGE, + IE_TARIFF_DISCOUNT, + IE_PLAN_VALUE,//value=51 + IE_PLAN_USED_VALUE, + IE_BUNDLE_ID, + IE_CAUSE, + IE_SESS_FLAG, + IE_TIMESTAMP, + IE_CONSUME_VALUE, + IE_CALLED_NUMBER, + IE_UE_IP, + IE_GW_IP, + IE_CUG_ID, + IE_VAS_CUG_STATUS, + IE_SESS_UPDATE_TIME, + IE_PLAN_VALUE_ADD_THIS_TIME, + IE_USER_CLASS, + IE_PINCODE, + IE_CALLER_NUMBER, + IE_MAX_NUM, + +}; + +typedef struct rest_header +{ + u16 src_ref; + u16 dst_ref; +}_rest_header; + +typedef struct rest_query +{ + char msisdn[24]; +}_rest_query; + +typedef struct rest_query_res +{ + u8 optional_flag; + u8 result; + u8 error_code; + u32 balance; + u32 mo_expiry; + u32 mt_expiry; +}_rest_query_res; + +typedef struct rest_topup +{ + u8 optional_flag; /* optional=1 ,account_id is presented */ + char msisdn[24]; + + char username[24]; + char password[24]; + char pincode[24]; + u32 balance; + long account_id; +}_rest_topup; + +typedef struct rest_topup_res +{ + u8 optional_flag; + u8 result; + u8 error_code; + u32 balance; + u32 mo_expiry; + u32 mt_expiry; +}_rest_topup_res; + +typedef struct rest_channel +{ + u8 optional_flag; /* optional=1 ,account_id is presented */ + char msisdn[24]; + + char sess_id[64]; + char sc_url[128]; + char input[24]; +}_rest_channel; + +typedef struct rest_channel_res +{ + u8 optional_flag; + u8 result; + u8 error_code; + + u8 sess_state; + char prompt[256]; +}_rest_channel_res; + +typedef struct rest_order +{ + u8 optional_flag; /* optional=1 ,account_id is presented */ + char msisdn[24]; + char callerMsisdn[24]; + char payMsisdn[24]; + + u32 busicode;// 1000: recharge; 1001: order; 1002: cancel; + u32 offer_id; + u32 balance;// when busicode=1000 + u32 paymethod;// byte0: 4: balance; 10: mobile money; null: default balance // byte1: thirdPartyPayMethod + char pincode[64];// when paymethod 10 + //char thirdPartyPayMethod[32];// Airtel, MTN + //char thirdPartyPayPhone[64];// use payMsisdn +}_rest_order; + + +typedef struct rest_order_res +{ + u8 optional_flag; + u8 result; + u8 error_code; +}_rest_order_res; + +typedef struct rest_freeresource +{ + char msisdn[24]; +}_rest_freeresource; + + +typedef struct rest_freeresource_res +{ + u8 optional_flag; + u8 result; + u8 error_code; +}_rest_freeresource_res; + +typedef struct rest_downloadApp +{ + char msisdn[24]; +}_rest_downloadApp; + + +typedef struct rest_downloadApp_res +{ + u8 optional_flag; + u8 result; + u8 error_code; +}_rest_downloadApp_res; + +typedef struct rest_offerChange +{ + char msisdn[24]; + u8 opt_out; +}_rest_offerChange; + + +typedef struct rest_offerChange_res +{ + u8 optional_flag; + u8 result; + u8 error_code; +}_rest_offerChange_res; + +typedef struct rest_queryPoint +{ + char msisdn[24]; +}_rest_queryPoint; + + +typedef struct rest_queryPoint_res +{ + u8 optional_flag; + u8 result; + u8 error_code; + + u32 amount; + u32 airtime_amount; +}_rest_queryPoint_res; + +typedef struct rest_transferPoint +{ + char msisdn[24]; + char target_msisdn[24]; + + u32 amount; + u32 busicode; +}_rest_transferPoint; + + +typedef struct rest_transferPoint_res +{ + u8 optional_flag; + u8 result; + u8 error_code; +}_rest_transferPoint_res; + +// for selfcare ============================= +typedef struct rest_send_authcode_req +{ + char msisdn[24]; + char sms_content[MAX_BODY_LEN]; +}_rest_send_authcode_req; + +typedef struct rest_send_authcode_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; +}_rest_send_authcode_rsp; + +typedef struct rest_query_user_data_req +{ + char msisdn[24]; +}_rest_query_user_data_req; + +typedef struct rest_query_user_data_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; + + char msisdn[24]; + u8 status;// use ACCT_STATUS + char remark[64]; + char usrGrpName[64];// usr data==>cos id==>cos title + u32 balance; + u64 mo_expiry; + u32 mo_voc_min;// in Min + u32 remain_mo_voc_min; + u32 mt_voc_min;// in Min + u32 remain_mt_voc_min; + u32 total_sms_num;// reserved, set to 0 or do not send + u32 remain_sms_num; + u32 total_data_vol;// reserved, set to 0 or do not send + u32 remain_data_vol;// MB +}_rest_query_user_data_rsp; + +typedef struct rest_bundle_subs_req +{ + char msisdn[24]; + u8 payType;// 1: balance; 2: paypal; 3: visa; 4: master, use PAY_TYPE + u32 charge;// Conditional, mandatory if balance + u32 moVoiceMinute; + u32 mtVoiceMinute; + u32 dataVolume;// MB + u32 smsNum; + u32 validDays; +}_rest_bundle_subs_req; + + +typedef struct rest_bundle_subs_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; +}_rest_bundle_subs_rsp; + + +typedef struct rest_bundle_usage_req +{ + char msisdn[24]; +}_rest_bundle_usage_req; + + +typedef struct rest_bundle_usage_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; + u32 moVoiceInSec;// remained mo voice in second + u32 mtVoiceInSec;// remained mt voice in second + u32 dataVolInKB;// remained data volume in KB + u32 smsNum;// remained sms + u64 expiredTime;// expired time +}_rest_bundle_usage_rsp; + + +typedef struct rest_recharge_req +{ + char msisdn[24]; + + u32 amount;// mandatory, add to balance + u8 op_type; + u16 valid_days; +}_rest_recharge_req; + + +typedef struct rest_recharge_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; + u8 status;// current status + u32 balance;// current balance + u64 expiredTime;// expired time +}_rest_recharge_rsp; + + +typedef struct rest_transfer_req +{ + char transferOutMsisdn[24]; + char transferInMsisdn[24]; + + u32 amount;// mandatory +}_rest_transfer_req; + + +typedef struct rest_transfer_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; + u32 balance; +}_rest_transfer_rsp; + + +typedef struct rest_recharge_card_req +{ + char msisdn[24]; + + char cardPwd[32];// rechare card password + //u32 amount;// mandatory, add to balance +}_rest_recharge_card_req; + + +typedef struct rest_recharge_card_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; + u32 rechargeAmount;// mandatory, add to balance + u32 balance;// current balance + u64 expiredTime;// expired time +}_rest_recharge_card_rsp; + + +typedef struct rest_check_balance_req +{ + char msisdn[24]; + + u32 amount;// mandatory +}_rest_check_balance_req; + + +typedef struct rest_check_balance_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; + u8 available;// 0: enough balance; 1: else +}_rest_check_balance_rsp; + + +typedef struct rest_query_balance_req +{ + char msisdn[24]; +}_rest_query_balance_req; + + +typedef struct rest_query_balance_rsp +{ + u8 optional_flag; + u8 result; + u32 error_code; + u8 status;// use ACCT_STATUS + u32 balance;// current balance + u32 mo_expiry; +}_rest_query_balance_rsp; + +typedef struct rest_sms_deliver_req +{ + char msisdn[24]; + u16 sms_len; + char sms_content[MAX_BODY_LEN]; +}_rest_sms_deliver_req; + +typedef struct rest_sms_deliver_res +{ + u8 optional_flag; + u8 result; + u32 error_code; +}_rest_sms_deliver_res; + +typedef struct rest_create_acct_req +{ + char msisdn[24]; + u32 customer_id; + u32 account_id; + u32 product_id; + u32 plan_id; /* basic plan */ + u8 user_class; + u32 balance; + u32 expiry_date; + u32 rent_charge; + u32 birthday; + u32 cug_id; +}_rest_create_acct_req; + +typedef struct rest_create_acct_res +{ + u8 optional_flag; + u8 result; + u32 error_code; +}_rest_create_acct_res; + +typedef struct rest_query_tariff_req +{ + char msisdn[24]; + u8 service_type; /*0=mo call, 1=mt call, 2=sms, 3=data */ + char called_number[24]; +}_rest_query_tariff_req; + +typedef struct rest_query_tariff_res +{ + u8 optional_flag; + u8 result; + u32 error_code; + char prefix[24]; + u32 unit_time; + u32 unit_charge; + u32 discount; + u32 plan_id; + u32 bundle_plan_id; + u64 total_plan_value; + u64 used_plan_value; +}_rest_query_tariff_res; + +typedef struct rest_update_subs_req +{ + u32 optional_flag; + char msisdn[24]; + u32 account_id; + u8 status; /*falg=1*/ + u32 balance; + u32 balance_expiry_date; + u32 basic_plan_id; + u32 basic_plan_rent; + u8 vas_cug_status; +}_rest_update_subs_req; + +typedef struct rest_update_subs_res +{ + u8 optional_flag; + u8 result; + u32 error_code; +}_rest_update_subs_res; + +typedef struct rest_delete_subs_req +{ + char msisdn[24]; + u8 cause; +}_rest_delete_subs_req; + +typedef struct rest_delete_subs_res +{ + u8 optional_flag; + u8 result; + u32 error_code; +}_rest_delete_subs_res; + +typedef struct rest_update_sess_info_req +{ + u32 optional_flag; /*bit 0=called, 1= ue_ip, 2=pgw ip */ + char msisdn[24]; + u8 first_sess; /*if 1 then clear all session in database */ + u8 service_type; /*0=mo call, 1=mt call, 2=mo sms, 3= data*/ + u32 start_time; + u32 consumed_value; /*duration of call, bytes of data */ + char called[24]; /*for call/sms */ + u32 ue_ip; + u32 gw_ip; +}_rest_update_sess_info_req; + +typedef struct rest_update_plan_info_req +{ + u32 optional_flag; /*bit 0=called, 1= ue_ip, 2=pgw ip */ + char msisdn[24]; + u8 service_type; /*0=mo call, 1=mt call, 2=mo sms, 3= data*/ + u32 account_id; + u32 plan_id; + u32 bundle_id; + u64 plan_total_value; + u64 plan_used_value; + u32 sess_update_times; + u64 this_time_add_value; +}_rest_update_plan_info_req; + +typedef struct rest_rent_charge_req +{ + u32 optional_flag; + char msisdn[24]; + u32 balance; + u32 rent_charge; +}_rest_rent_charge_req; + + + +//====================================== + +typedef struct rest_msg_s +{ + u8 msg_type; + _rest_header header; + union + { + _rest_query query; + _rest_query_res query_res; + _rest_topup topup; + _rest_topup_res topup_res; + + _rest_order order; + _rest_order_res order_res; + _rest_freeresource free_resource; + _rest_freeresource_res free_resource_res; + _rest_downloadApp downloadApp; + _rest_downloadApp_res downloadApp_res; + _rest_channel chnl; + _rest_channel_res chnl_res; + _rest_offerChange offerChange; + _rest_offerChange_res offerChange_res; + _rest_queryPoint queryPoint; + _rest_queryPoint_res queryPoint_res; + _rest_transferPoint transferPoint; + _rest_transferPoint_res transferPoint_res; + + // for selfcare + _rest_send_authcode_req send_authcode_req; + _rest_send_authcode_rsp send_authcode_rsp; + _rest_query_user_data_req query_user_data_req; + _rest_query_user_data_rsp query_user_data_rsp; + _rest_bundle_subs_req bundle_subs_req; + _rest_bundle_subs_rsp bundle_subs_rsp; + _rest_bundle_usage_req bundle_usage_req; + _rest_bundle_usage_rsp bundle_usage_rsp; + _rest_recharge_req recharge_req; + _rest_recharge_rsp recharge_rsp; + _rest_transfer_req transfer_req; + _rest_transfer_rsp transfer_rsp; + _rest_recharge_card_req recharge_card_req; + _rest_recharge_card_rsp recharge_card_rsp; + _rest_check_balance_req check_balance_req; + _rest_check_balance_rsp check_balance_rsp; + _rest_query_balance_req query_balance_req; + _rest_query_balance_rsp query_balance_rsp; + // + _rest_sms_deliver_req sms_deliver; + _rest_sms_deliver_res sms_deliver_res; + + _rest_create_acct_req create_acct; + _rest_create_acct_res create_acct_res; + + _rest_query_tariff_req query_tariff; + _rest_query_tariff_res query_tariff_res; + + _rest_update_subs_req update_subs; + _rest_update_subs_res update_subs_res; + + _rest_delete_subs_req delete_subs; + _rest_delete_subs_res delete_subs_res; + + _rest_update_sess_info_req update_sess_info; + + _rest_update_plan_info_req update_plan_info; + + _rest_rent_charge_req rent_charge; + + + }msg; +}_rest_msg_s; + +int encode_rest_query(_rest_msg_s *ptr, u8 *buf); + +int encode_rest_query_res(_rest_msg_s *ptr, u8 *buf); + +int encode_rest_topup(_rest_msg_s *ptr, u8 *buf); + +int encode_rest_topup_res(_rest_msg_s *ptr, u8 *buf); + +int decode_rest_api_msg(u8 *buf, int len, _rest_msg_s *ptr); + +// for selfcare====================================== +int encode_rest_send_authcode_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_send_authcode_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_query_user_data_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_query_user_data_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_bundle_subs_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_bundle_subs_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_bundle_usage_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_bundle_usage_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_recharge_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_recharge_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_transfer_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_transfer_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_recharge_card_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_recharge_card_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_check_balance_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_check_balance_rsp(_rest_msg_s *ptr, u8 *buf); +int encode_rest_query_balance_req(_rest_msg_s *ptr, u8 *buf); +int encode_rest_query_balance_rsp(_rest_msg_s *ptr, u8 *buf); +// + +// for restproxy===================================== +#define YX_USSD_MENU_MAIN 0 +#define YX_USSD_MENU_UNLIMITED_ONCE_RECUR 1 +#define YX_USSD_MENU_PRESS_ZED_DATA 2 +#define YX_USSD_MENU_PRESS_ZED_VOICE 3 +#define YX_USSD_MENU_PRESS_MIFI_AND_ROUTER 4 +#define YX_USSD_MENU_PRESS_INPUT_NO 5 +#define YX_USSD_MENU_PRESS_BALANCE_CHECK 6 +#define YX_USSD_MENU_PRESS_AMA 7 +#define YX_USSD_MENU_PRESS_UNLIMITED_BUNDLES 8 +#define YX_USSD_MENU_PRESS_PURCHASE_AIRTIME 9 +#define YX_USSD_MENU_DATA_24HRS 10 +#define YX_USSD_MENU_DATA_7DAYS 11 +#define YX_USSD_MENU_DATA_30DAYS 12 +#define YX_USSD_MENU_VOICE_DAILY 13 +#define YX_USSD_MENU_VOICE_WEEKLY 14 +#define YX_USSD_MENU_VOICE_MONTHLY 15 +#define YX_USSD_MENU_MIFI_SUB 16 +#define YX_USSD_MENU_BUY_FOR_OTHER 17 +#define YX_USSD_MENU_SELECT_PROVIDER 18 +#define YX_USSD_MENU_ENTER_PAY_NUMBER 19 +#define YX_USSD_MENU_SELECT_MONEY 20 +#define YX_USSD_MENU_PAID_MONEY 21 +#define YX_USSD_MENU_SELECT_MOBIL_MONEY 22 +#define YX_USSD_MENU_SUBSCRIB_COMPLETE 23 +#define YX_USSD_MENU_CANCEL_RENEWAL 24 +#define YX_USSD_MENU_AIRTIME_AMOUNT 25 +#define YX_USSD_MENU_AIRTIME_NO 26 +#define YX_USSD_MENU_DIBAAMA 27 +#define YX_USSD_MENU_DIBA 28 +#define YX_USSD_MENU_MOMO_PIN 29 +#define YX_USSD_MENU_PROMO 30 +#define YX_USSD_MENU_QUERY_POINT 31 +#define YX_USSD_MENU_CUR_POINT 32 +#define YX_USSD_MENU_POINT2NUM 33 +#define YX_USSD_MENU_OFFER_CHANGED 34 +#define YX_USSD_MENU_POINT_TRANSFERED 35 +#define YX_USSD_MENU_POINT_LOW 36 +#define YX_USSD_MENU_OFFER_OUT 37 +#define YX_USSD_MENU_POINT_TRANS_FAIL 38 +#define YX_USSD_MENU_SHARE_NBR 39 +#define YX_USSD_MENU_NUM_MAX 64 +extern char yx_ussd_menu[YX_USSD_MENU_NUM_MAX][512]; +#define YX_USSD_CHNL_NUM_MAX 16 +extern char yx_chnl_info[YX_USSD_CHNL_NUM_MAX][128]; + +#define YX_MOBILE_MONEY_MAX 8 +#define YX_OFFER_TYPE_MAX 10 +#define YX_OFFER_TYPE_BUNDLE 0 +#define YX_OFFER_TYPE_DATA_1 1 +#define YX_OFFER_TYPE_DATA_2 2 +#define YX_OFFER_TYPE_DATA_3 3 +#define YX_OFFER_TYPE_VOICE_1 4 +#define YX_OFFER_TYPE_VOICE_2 5 +#define YX_OFFER_TYPE_VOICE_3 6 +#define YX_OFFER_TYPE_MIFI_1 7 +#define YX_OFFER_TYPE_AMA_1 8 +#define YX_OFFER_TYPE_DIBA_1 9 +#define YX_OFFER_PER_TYPE 12 + +int pps_third_party_plan_process(u_short portid); +int pps_third_party_channel_process(u_short portid); +int match_channel_info(char *sc, char *url); + +// + +#endif diff --git a/mss/pps/src/include/stamp-h b/mss/pps/src/include/stamp-h new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/mss/pps/src/include/stamp-h @@ -0,0 +1 @@ +timestamp diff --git a/mss/pps/src/include/stamp-h.in b/mss/pps/src/include/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/mss/pps/src/include/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/mss/pps/src/include/tariff.h b/mss/pps/src/include/tariff.h new file mode 100644 index 0000000..ff8af97 --- /dev/null +++ b/mss/pps/src/include/tariff.h @@ -0,0 +1,54 @@ +/* +** Written completely by Liang Hongbin +** +*/ + +#ifndef TARIFF__H +#define TARIFF__H +#include "ramdata.h" + +#define PERIODIC_CHARGE_HOUR 9 +#define PERIODIC_CHARGE_MINUTE 0 +#define PERIODIC_CHARGE_SECOND 0 +#define PERIODIC_OF_DAY 24 +#define MAX_MEGA_SIZE 34 +#define PRIVATE_TARIFF_SIZE (MAX_MEGA_SIZE*1024*1024) + +typedef struct { + _comm_tariff comm_tariff[MAX_ZONE_NUM]; + _rent_tariff rent_tariff[MAX_ZONE_NUM][MAX_RENT_TARIFF]; + _bill_tariff bill_tariff[MAX_ZONE_NUM][BILLING_BASE_NUM]; + _bill_tariff called_tariff[MAX_ZONE_NUM][CALLED_BASE_NUM]; + u_char bill_discount[MAX_DISCOUNT_ID][PERIODIC_OF_DAY][8]; + u_char holiday_flag[12][31]; + _bill_sms bill_sms[MAX_ZONE_NUM][MAX_SMS_PREFIX]; + _gprs_tariff gprs_tariff[MAX_ZONE_NUM][MAX_GPRS_PREFIX]; + VAS_TARIFF vas_tariff[MAX_ZONE_NUM]; +} _tariff_private; + + + +#define PPS_PREFIX_NODE_NUM (MAX_ZONE_NUM_NEW*4096) +typedef struct +{ + u_short sub[14]; + u_char flag; //bit0=0/1: prefix not exist/exist;bit1=0/1:prefix not exist in sub node/exist + u_short prefix_index; +}_pps_prefix_node; + +//_pps_prefix_node pps_prefix_table[MAX_ZONE_NUM_NEW][PPS_PREFIX_NODE_NUM]; +//_pps_prefix_node pps_prefix_table[PPS_PREFIX_NODE_NUM]; +/* the ZONE NUM is as a prefix or a separate table is for further study, +if the ZONE NUM is as prefix , then should not be larger than 16 */ + + +int ListCurrentTariff(int zone_id); +void ListTariffPlan(); +void ListCurrentTariffWithMsisdn(char *number); + + +int pps_create_tariff_table(); +int pps_add_charge_prefix(u_short iroot, char *prefix_digits, u_char len, u_short table_index); +int pps_get_charge_prefix(u_char cosID,char *dialing_number); + +#endif /* TARIFF__H */ diff --git a/mss/pps/src/include/version.h b/mss/pps/src/include/version.h new file mode 100644 index 0000000..7e16f7d --- /dev/null +++ b/mss/pps/src/include/version.h @@ -0,0 +1,21 @@ +/* +** +** +** file name: version.h +** CVS $Id: $ +** +** +*/ + +#ifndef VERSION__H +#define VERSION__H +void PutVersionID(char *prog_name, char *distrib_date); +void SetVersionID(u_char *ptr); // Set version id to shared memory + +#define VER_MAJOR 2 +#define VER_MINOR 1 +#define VER_FIX 16 +#define DISTRIB_DATE DATE_MACRO +#define PROJECT_INFO "WAVEprepaid" + +#endif /* VERSION__H */ diff --git a/mss/pps/src/include/voiceID.h b/mss/pps/src/include/voiceID.h new file mode 100644 index 0000000..2ac85f8 --- /dev/null +++ b/mss/pps/src/include/voiceID.h @@ -0,0 +1,169 @@ + +#ifndef ppsVoiceID_H +#define ppsVoiceID_H + +typedef enum _VOICE_GROUP +{ + ERROR_ACCOUNT_STATUS =0, + LOW_ACCOUNT_BALANCE, + EXPIRIED_ACCOUNT, + EMPTY_NUMBER, + MT_ERROR_ACCOUNT_STATUS, + MT_LOW_ACCOUNT_BALANCE, + MT_EXPIRIED_ACCOUNT, + MT_EMPTY_NUMBER, + SERIVCE_NOT_APPLIED, + CALLED_TARIFF_NOT_SET, /* called number is not set in the tariff table */ + SERVICE_SELECT_PROMPT, /* service center greeting */ + ERROR_SERVICE_KEY, /* error service key */ + ACCOUNT_BALANCE_IS, /* account balance is */ + EXPIRY_IN, + INPUT_RECHARGE_ACCOUNT, /* please input account recharged */ + ERROR_RECHARGE_ACCOUNT, /* error recharge account, please input again */ + INPUT_PRECARD_PWD, /* please input prepaid card password */ + RECHARGE_SUCCESS, /* recharge successfully, and recharge amount is:xxx */ + RECHARGE_FAILED, /* recharge failed , error card, please input again */ + FAVORITE_NUMBER_FUNC, + ERROR_FAVUMBER_INPUT_AND_INPUT_AGAIN, + FULL_FAVORITE_NUMBER, + NO_FAVORITE_NUMBER, + ADD_FAVORITE_NUMBER_SUC, + INPUT_EDIT_FAVORITE_NUMBER_SN, + NO_SUCH_SN_FAVORITE_NUMBER, + INPUT_NEW_FAVORITE_NUMBER, + INPUT_INQUIRY_FAVORITE_NUMBER_SN, + SN_X_FAVORITE_NUMBER_IS, + PRE_WARNING_LOW_BALANCE, + TO_BE_RECHARGED_NUMBER, + YES_OR_NO=31, + TO_BE_ADDED_NUMBER_IS, + PRE_WARNING_EXPIRATION_DAY, + LANGUAGE_MANAGEMENT_MENU, + YOUR_DEFAULT_LANGUAGE_SET_IS, + INVALID_LANGUAGE_SELECTION_KEY, + INPUT_OLD_PIN, + ERROR_PIN, + INPUT_NEW_PIN, + INPUT_NEW_PIN_AGAIN, + ERROR_PIN_LENGTH, + TWO_PINS_NOT_MATCH, + PIN_SET_OK, + INQUIRY_RECHARGE_KEY, + LAST_CALL_AT, + ONLY_BALANCE_IS, + RECHARGE_TYPE_SELECTION, + PRESS_1_TO_RECHARGE, + PRESS_2_TO_USE_CREDIT_VAULT, + OPERATION_SUCESSFULLY_DONE=50, + INQUIRY_MESSAGE_FROM, + TO_, + FROM_, + INQUIRY_WITH_PROMOTION=59, + HPLMN_VMS_PROMPT = 60, + PSTN_VMS_PROMPT, + INPUT_VOICEBOX, + NO_SUCH_VOICEBOX, + ERROR_CALLER_STATUS_SUSPEND=66, + ERROR_CALLER_STATUS_BLACKLISTED, + ERROR_CALLER_STATUS_RELEASED, + ERROR_CALLER_STATUS_EXTERNAL, + ERROR_CALLED_STATUS_SUSPEND, + ERROR_CALLED_STATUS_BLACKLISTED, + ERROR_CALLED_STATUS_RELEASED, + ERROR_CALLED_STATUS_EXTERNAL, + + /** for calling card ****/ + PleaseInputCallingCardAccount = 100, + InvalidAccountIputAgain, + MakingCall, + CallingCardMainMenu, + PleaseInputCalledNumber, + InvalidCalledNumberInputAgain, + PleaseInputTransferInAccount, + PleaseInputTransferOutPassword, + TransferSuccess, + TransferFail, + ThankYouUseByeBye, + CallingCardPasswordSetSuccess, + /** for calling card ****/ + + /** for opr ****/ + OPR_SERVICE_SELECT_PROMPT = 120, + IMEI_REGISTER_FAIL, + MS_REGISTER_SUCCESS, + INPUT_MOBILE_IMEI, + INPUT_MOBILE_IMEI_AGAIN, + IMEI_REGISTERING, + REGISTER_OPR_IMEI_ERROR, + REGISTER_OPR_FAIL_PWD_ERROR, + IMEI_REGISTER_FAIL_IMEI_NOT_SAME, + + INPUT_SWITCH_KEY, + INPUT_SWITCH_TO_OPR_SUCCESS, + INPUT_SWITCH_TO_OPR_FAIL, + INPUT_SWITCH_TO_ROAMING_SUCCESS, + INPUT_SWITCH_TO_ROAMING_FAIL, + + INPUT_INQUERY_KEY, + INPUT_REPLAY_OR_BACK, + + NOT_REGISTER_STATUS, + OPR_STATUS, + ROAMING_STATUS, + YOUR_NUMBER_IS, + FIX_REGISTER_SUCCESS, + /** for opr ****/ + + /** for fee transfer ****/ + PleaseInputTransferInAccountAgain = 150, + NotMatchedTransferOutAccount, + FULL_PARTIAL_TRANSFER_CHOICE, + INPUT_FEE_TRANSFERED, + INPUT_FEE_TRANSFERED_FORMAT_ERROR, + TRANSFERED_FEE_INSUFFIENT, + TRANSFERED_FEE_EXPIERED, + INPUT_TRANSFER_CONFIRM, + CHARGE_OR_TRANSFER, + CONFIRM_LISTEN_AGAIN, + /** for fee transfer ****/ + + /** for masterSlaveCard ****/ + MASTER_CARD_PROMPT = 161, + SLAVE_CARD_PROMPT, + ENQUIRY_EMPTY, + MASTER_CARD_HOW_MANY_CHILDREN, + MASTER_CARD_CHILD_NUMBER, + NO_CHILD_NUMBER_RELATED, + SLAVE_ENQUIRY_MENU=167, + SLAVE_ENQUIRY_PARENT_NUMBER, + SLAVE_ENQUIRY_LIMITS, + SLAVE_ENQUIRY_TODAY, + + MASTER_INPUT_CHILD_ADD=171, + MASTER_INPUT_CHILD_DEL, + ADD_FAIL_ALREADY_EXIST, + DEL_FAIL_NOT_YOUR_CHILD, + ADD_FAIL_FULL=175, + ADD_FAIL_INSUFFICIENT_FEE, + DEL_FAIL_EMPTY, + MASTER_SELECT_COS, + MASTER_CONFIRM_ADD, + MASTER_CONFIRM_DEL, + MASTER_ADD_SUCCESS, + MASTER_DEL_SUCCESS, + CHILD_REACH_CALL_LIMIT, + CHILD_REACH_CHARGE_LIMIT=184, + + /** for masterSlaveCard ****/ + + FAVORITE_NUMBER_FUNC_EDIT_QUERY=190, + FAVORITE_NUMBER_FUNC_QUERY, + FAVUMBER_EXIST_INPUT_AGAIN, + FAVORITE_READ_NUMBER_DIDT_QUERY, + FAVORITE_READ_NUMBER_QUERY, + +}VOICE_GROUP; + + +#endif + diff --git a/mss/pps/src/lib/Makefile b/mss/pps/src/lib/Makefile new file mode 100644 index 0000000..2d117d7 --- /dev/null +++ b/mss/pps/src/lib/Makefile @@ -0,0 +1,91 @@ +#!/bin/sh +# $id: $ + +# Makefile for SCSM. +# Created by Liang Hongbin, 2003-09-25 + +CC = gcc +CFLAGS=-D_REENTRANT -g -Wall +oldincludedir = /usr/include +M_COMPILE.c=$(CC) $(CFLAGS) +M_LINK.c=$(CC) $(CFLAGS) +COMPILE.c=$(CC) $(CFLAGS) +LINK.c=$(CC) $(CFLAGS) + + +LIB_OBJ = comfunc.o daemon.o debug.o error.o errorlog.o ppsfun.o iofunc.o ipcfunc.o logfunc.o queuefunc.o signal.o time.o version.o + + +all : CHECK $(LIB_OBJ) + ar r libppsfuns.a $(LIB_OBJ) + +comfunc.o:comfunc.c + $(M_COMPILE.c) -c comfunc.c + +daemon.o:daemon.c + $(M_COMPILE.c) -c daemon.c + +debug.o:debug.c + $(M_COMPILE.c) -c debug.c + +error.o:error.c + $(M_COMPILE.c) -c error.c + +errorlog.o:errorlog.c + $(M_COMPILE.c) -c errorlog.c + +ppsfun.o:ppsfun.c + $(M_COMPILE.c) -c ppsfun.c + +iofunc.o:iofunc.c + $(M_COMPILE.c) -c iofunc.c + +ipcufnc.o:ipcfunc.c + $(M_COMPILE.c) -c ipcfunc.c + +logfunc.o:logfunc.c + $(M_COMPILE.c) -c logfunc.c + +queuefunc.o:queuefunc.c + $(M_COMPILE.c) -c queuefunc.c + +signal.o:signal.c + $(M_COMPILE.c) -c signal.c + +time.o:time.c + $(M_COMPILE.c) -c time.c + +version.o:version.c + $(M_COMPILE.c) -c version.c + +.SUFFIXES: +.SUFFIXES: .c .o + +CHECK: + @echo "Using FLAGS = $(CFLAGS)" + @echo "Using LIBS = $(LIB_FLAGS)" + + +MAKEDIR = || exec false; \ + if test -d "$$dir"; then :; else \ + echo mkdir "$$dir"; \ + mkdir -p "$$dir" >/dev/null 2>&1 || \ + test -d "$$dir" || \ + mkdir "$$dir" || \ + exec false; fi || exec false + +.c.o: # .deps/.dummy + @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ + dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi +# @if (: >> .deps/$@ || : > .deps/$@) >/dev/null 2>&1; then :; \ +# else dir=.deps/`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` \ +# $(MAKEDIR); fi; rm -f .deps/$@ .deps/$@d + @echo Compiling $*.c + @$(CC) -I. $(CFLAGS) $(INCLUDE_FLAGS) -c $< \ + -o $@ # -Wp,-MD,.deps/$@ +clean: + -rm -f core *.o *.c~ *.h~ *.a + +# cd mapp;make clean;cd .. +# cd capp;make clean;cd .. + diff --git a/mss/pps/src/lib/Makefile.am b/mss/pps/src/lib/Makefile.am new file mode 100644 index 0000000..f5a611f --- /dev/null +++ b/mss/pps/src/lib/Makefile.am @@ -0,0 +1,22 @@ +## +## +## +## file name: Makefile +## +## Process this file with automake to produce Makefile.in -*-Makefile-*- +## + +AUTOMAKE_OPTIONS = foreign + +include $(top_srcdir)/Rules.make + +noinst_LIBRARIES = libppfuncs.a +INCLUDES = -I../include + +libppfuncs_a_SOURCES = \ + daemon.c error.c errorlog.c function.c ipcfunc.c \ + comfunc.c signal.c msgfunc.c queuefunc.c logfunc.c crypt.c \ + time.c version.c iofunc.c debug.c + +#libppfuncs_a_LIBADD = @LIBOBJS@ +libppfuncs_a_DEPENDENCIES = $(libppfuncs_a_SOURCES) diff --git a/mss/pps/src/lib/Makefile.in b/mss/pps/src/lib/Makefile.in new file mode 100644 index 0000000..bb4c38f --- /dev/null +++ b/mss/pps/src/lib/Makefile.in @@ -0,0 +1,278 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +#CFLAGS = -O6 -Wall +#CFLAGS = -g -O6 -Wall + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +CC = @CC@ +CHMOD = @CHMOD@ +MAKEINFO = @MAKEINFO@ +MV = @MV@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +RM = @RM@ +SED = @SED@ +VERSION = @VERSION@ + +AUTOMAKE_OPTIONS = foreign + +LDFLAGS = -L$(MYSQLdir)/lib -lm +PPLIBdir = $(top_srcdir)/lib + +noinst_LIBRARIES = libppfuncs.a +INCLUDES = -I../include + +libppfuncs_a_SOURCES = \ + daemon.c error.c errorlog.c function.c ipcfunc.c \ + comfunc.c signal.c msgfunc.c queuefunc.c logfunc.c crypt.c \ + time.c version.c iofunc.c debug.c + + +#libppfuncs_a_LIBADD = @LIBOBJS@ +libppfuncs_a_DEPENDENCIES = $(libppfuncs_a_SOURCES) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../include/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../include +CPPFLAGS = @CPPFLAGS@ +LIBS = @LIBS@ +libppfuncs_a_LIBADD = +libppfuncs_a_OBJECTS = daemon.o error.o errorlog.o function.o ipcfunc.o \ +comfunc.o signal.o msgfunc.o queuefunc.o logfunc.o crypt.o time.o \ +version.o iofunc.o debug.o +AR = ar +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libppfuncs_a_SOURCES) +OBJECTS = $(libppfuncs_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Rules.make + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps lib/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +libppfuncs.a: $(libppfuncs_a_OBJECTS) $(libppfuncs_a_DEPENDENCIES) + -rm -f libppfuncs.a + $(AR) cru libppfuncs.a $(libppfuncs_a_OBJECTS) $(libppfuncs_a_LIBADD) + $(RANLIB) libppfuncs.a + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = lib + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-tags distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/mss/pps/src/lib/comfunc.c b/mss/pps/src/lib/comfunc.c new file mode 100644 index 0000000..bf29277 --- /dev/null +++ b/mss/pps/src/lib/comfunc.c @@ -0,0 +1,127 @@ +/* +** +** Title: comfunc.c +** +** Description: Functions of comunication for WXC2. +** +*/ + +#include "../include/includes.h" + +/* +** passivesock - allocate & bind a server socket using TCP or UDP +*/ + +int +passivesock( const char * transport, u_short portbase, int qlen) +{ + struct sockaddr_in sin; + int s, type; + + memset(& sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(portbase); + sin.sin_addr.s_addr = INADDR_ANY; + bzero(&(sin.sin_zero), 8); + + if ( strcmp(transport, "UDP") == 0) + type = SOCK_DGRAM; + else + type = SOCK_STREAM; + s = socket(AF_INET, type, 0); + if (s < 0) { + perror("socket"); + return -3; + } + if (bind(s, (struct sockaddr *) & sin, sizeof(sin)) < 0) { + perror("bind"); + close(s); + return -4; + } + + if (type == SOCK_STREAM && listen(s, qlen) < 0) { + perror("listen"); + close(s); + return -5; + } + return s; +} + +/* +** passiveUDP - create a passive socket for use in a UDP server +*/ + +int +passiveUDP(u_short portbase) +{ + return (passivesock("UDP", portbase, 0) ); +} + +const char * +Inet_ntoa(const long addr) +{ + struct sockaddr_in sin; + + sin.sin_addr.s_addr = addr; + return ((char *) inet_ntoa(sin.sin_addr) ); +} + + +const long +ppsInet_pton(const char *sp) +{ + struct in_addr i_addr; + + inet_pton(AF_INET, sp, &i_addr); + return i_addr.s_addr; +} + +/* +const long +GetLocalIP(void) +{ + struct hostent *hptr; + char hostname[40]="\0"; + struct in_addr *inaddr; + + if ((gethostname(hostname, -1)) != 0){ + return -1; + } + if ((hptr = gethostbyname(hostname)) == NULL){ + return -1; + } + inaddr = (struct in_addr *)(*hptr->h_addr_list); + return inaddr->s_addr; +} +*/ +int +RecvMsg (int sockfd, u_char *buf, int len, + int src_ip, int src_port) +{ + struct sockaddr_in sin; + int nbytes; + + socklen_t size = sizeof(sin); + nbytes = recvfrom(sockfd, &buf, 1024, + 0, (struct sockaddr *) &sin, &size); + src_ip = sin.sin_addr.s_addr; + src_port = sin.sin_port; + len = nbytes; + return nbytes; +} + +int +SendMsg (int sockfd, u_char *buf, int len, + int dest_ip, int dest_port) +{ + struct sockaddr_in sin; + int retval=0; + + bzero(&sin.sin_zero, sizeof(sin.sin_zero)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = dest_ip; + sin.sin_port = htons(dest_port); + retval = sendto(sockfd, &buf, len, 0, + (struct sockaddr *)&sin, sizeof(sin)); + return retval; +} diff --git a/mss/pps/src/lib/crypt.c b/mss/pps/src/lib/crypt.c new file mode 100644 index 0000000..06e95fa --- /dev/null +++ b/mss/pps/src/lib/crypt.c @@ -0,0 +1,473 @@ +/* +** +** +** file name: crypt.c +** +** Crypt functions +** +*/ + +#include +#include +#include +#include + +static unsigned char T1[] = +{ + 57,49,41,33,25,17, 9, 1, + 59,51,43,35,27,19,11, 3, + 61,53,45,37,29,21,13, 5, + 63,55,47,39,31,23,15, 7, + 56,48,40,32,24,16, 8, 0, + 58,50,42,34,26,18,10, 2, + 60,52,44,36,28,20,12, 4, + 62,54,46,38,30,22,14, 6 +}; + +static unsigned char T2[] = +{ + 39, 7,47,15,55,23,63,31, + 38, 6,46,14,54,22,62,30, + 37, 5,45,13,53,21,61,29, + 36, 4,44,12,52,20,60,28, + 35, 3,43,11,51,19,59,27, + 34, 2,42,10,50,18,58,26, + 33, 1,41, 9,49,17,57,25, + 32, 0,40, 8,48,16,56,24 +}; + +static unsigned char T3[] = +{ + 31, 0, 1, 2, 3, 4, + 3, 4, 5, 6, 7, 8, + 7, 8, 9,10,11,12, + 11,12,13,14,15,16, + 15,16,17,18,19,20, + 19,20,21,22,23,24, + 23,24,25,26,27,28, + 27,28,29,30,31, 0 +}; + +static unsigned char T5[] = +{ + 15, 6,19,20, + 28,11,27,16, + 0,14,22,25, + 4,17,30, 9, + 1, 7,23,13, + 31,26, 2, 8, + 18,12,29, 5, + 21,10, 3,24 +}; + +static unsigned char T7_1_2[] = +{ + 56,48,40,32,24,16, 8, + 0,57,49,41,33,25,17, + 9, 1,58,50,42,34,26, + 18,10, 2,59,51,43,35, + 62,54,46,38,30,22,14, + 6,61,53,45,37,29,21, + 13, 5,60,52,44,36,28, + 20,12, 4,27,19,11, 3 +}; + +static unsigned char T8[] = +{ + 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 +}; + +static unsigned char T9[] = +{ + 13,16,10,23, 0, 4, + 2,27,14, 5,20, 9, + 22,18,11, 3,25, 7, + 15, 6,26,19,12, 1, + 40,51,30,36,46,54, + 29,39,50,44,32,47, + 43,48,38,55,33,52, + 45,41,49,35,28,31 +}; + +static unsigned char T6[][64] = +{ + {/* S1 */ + 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, + 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, + 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, + 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13 + }, + {/* S2 */ + 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, + 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, + 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, + 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9 + }, + {/* S3 */ + 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, + 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, + 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12 + }, + {/* S4 */ + 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, + 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, + 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, + 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14 + }, + {/* S5 */ + 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9, + 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, + 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, + 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3 + }, + {/* S6 */ + 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, + 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, + 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, + 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13 + }, + {/* S7 */ + 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, + 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, + 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, + 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12 + }, + {/* S8 */ + 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, + 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, + 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, + 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11 + } +}; + +unsigned char TE[][4] = +{ + {0,0,0,0}, + {0,0,0,1}, + {0,0,1,0}, + {0,0,1,1}, + {0,1,0,0}, + {0,1,0,1}, + {0,1,1,0}, + {0,1,1,1}, + {1,0,0,0}, + {1,0,0,1}, + {1,0,1,0}, + {1,0,1,1}, + {1,1,0,0}, + {1,1,0,1}, + {1,1,1,0}, + {1,1,1,1} +}; + +void Ks (unsigned char *Key, unsigned char Kn[16][48]) +{ + unsigned char cd[56]; + unsigned char zt[60]; + int n, i; + unsigned char tmp11, tmp12, tmp21, tmp22; + unsigned char *Knn; + + /* choix 1 */ + for (i = 0; i < 56; i++) + { + cd[i] = Key[T7_1_2[i]]; + } + + for (n = 0; n < 16; n++) + { + if (T8[n] == 0) + { + tmp11 = cd[0]; + tmp21 = cd[28]; + memcpy( zt , &cd[1] , 55 ); + memcpy( cd , zt , 55 ); + cd[27] = tmp11; + cd[55] = tmp21; + } + else + { + tmp11 = cd[0]; + tmp12 = cd[1]; + tmp21= cd[28]; + tmp22 = cd[29]; + + memcpy( zt , &cd[2] , 54 ); + memcpy( cd , zt , 54 ); + + cd[26] = tmp11; + cd[27] = tmp12; + cd[54] = tmp21; + cd[55] = tmp22; + } + Knn = Kn[n]; + for (i = 0; i < 48; i++) + { + Knn[i] = cd[T9[i]]; + } + } +} + +void fonction(unsigned char *Knn, unsigned char *r, unsigned char *s) +{ + + unsigned char x[32]; + unsigned long *px; + int i, l; + unsigned char c; + unsigned char t; + + for (i = 0, l = 0, px = (unsigned long *) x; i < 8;) + { + c = 32 * (r[T3[l]] ^ Knn[l]); + l++; + c += 8 * (r[T3[l]] ^ Knn[l]); + l++; + c += 4 * (r[T3[l]] ^ Knn[l]); + l++; + c += 2 * (r[T3[l]] ^ Knn[l]); + l++; + c += 1 * (r[T3[l]] ^ Knn[l]); + l++; + c += 16 * (r[T3[l]] ^ Knn[l]); + l++; + t = T6[i][c]; + i++; + *px = *(long *)TE[t]; + px++; + } + for (i = 0; i < 32; i++) + { + s[i] = x[T5[i]]; + } +} + +void permutation(unsigned char *org, unsigned char *tab) +{ + unsigned char tmp[64]; + int i; + + + memcpy(tmp, org, 64); + for (i = 0; i < 64; i++) + { + org[i] = tmp[tab[i]]; + } +} + +void chiffrement(unsigned char *xi, unsigned char *xo, unsigned char Kn[16][48]) +{ + unsigned char r[32], l[32]; + unsigned char rp[32], lp[32]; + + int i; + int n; + + memcpy(l, &xi[0], 32); + memcpy(r, &xi[32], 32); + + for (n = 0; n < 16; n++) + { + memcpy(lp, r, 32); + + fonction(Kn[n], r, rp); + for (i = 0; i < 32; i++) + { + r[i] =( ( l[i]) ^ (rp[i] ) ) ; + } + memcpy(l, lp, 32); + } + memcpy(&xo[0], r, 32); + memcpy(&xo[32], l, 32); + +} + +void dechiffrement(unsigned char *xi, unsigned char *xo, unsigned char Kn[16][48]) +{ + unsigned char r[32], l[32], rp[32], lp[32]; + + int i; + int n; + + memcpy(l, &xi[0], 32); + memcpy(r, &xi[32], 32); + + for (n = 0; n < 16; n++) + { + memcpy(lp, r, 32); + fonction(Kn[15 - n], r, rp); + for (i = 0; i < 32; i++) + { + r[i] =( ( l[i] ) ^ ( rp[i] )) ; + } + memcpy(l, lp, 32); + } + + memcpy(&xo[0], r, 32); + memcpy(&xo[32], l, 32); +} + +void eclater(const unsigned char *buf_bit, unsigned char *byte) +{ + int i; + unsigned char m; + + for (i = 0; i < 8; i++) + { + for (m = 0x80; m != 0; ) + { + if ((buf_bit[i] & m) != 0) + *byte = 1; + else + *byte = 0; + byte++; + m=m/2 ; + } + } + +} + +void compacter(unsigned char *byte, unsigned char *buf_bit) +{ + int i; + unsigned char m, n; + + for (i = 0; i < 8; i++) + { + n = 0; + for (m = 0x80; m != 0; ) + { + if (*byte++) + n = n | m; + m=m/2 ; + + } + buf_bit[i] = n; + } +} + + +void des(unsigned char *boutput, const unsigned char *binput, const unsigned char *bkey, int direction) +{ + unsigned char input[64]; /* data input */ + unsigned char output[64]; /* data output */ + unsigned char Key[64]; + unsigned char Kn[16][48]; + + eclater(binput, input); + eclater(bkey, Key); + Ks(Key, Kn); + permutation(input, T1); + + if (direction) dechiffrement(input, output, Kn); + else chiffrement(input, output, Kn); + + permutation(output, T2); + compacter(output, boutput); +} + +void atob (unsigned char *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if (i & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} + +void btoa (char *ascii_buf, const unsigned char *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} + +void EncryptPIN (unsigned char cipher[], const char plain[], const char pan[], const unsigned char pin_key[]) +{ + char pin[20]; + unsigned char buf1[8], buf2[8]; + int i; + + i = strlen(plain); + buf1[0] = i; + strcpy(pin, plain); + for (; i<14; ++i) pin[i] = 'F'; + atob(buf1+1, pin, 14); + buf2[0] = buf2[1] = 0x00; + atob(buf2+2, pan+strlen(pan)-13, 12); + for (i=0; i<8; ++i) buf1[i] ^= buf2[i]; + des(cipher, buf1, pin_key, 0); +} + +/* length of pan more than 13, and length of pin key more than 8 */ +void DecryptPIN (char plain[], const unsigned char cipher[], const char pan[], const unsigned char pin_key[]) +{ + unsigned char buf1[8], buf2[8]; + int i; + + des(buf1, cipher, pin_key, 1); + buf2[0] = buf2[1] = 0x00; + atob(buf2+2, pan+strlen(pan)-13, 12); + for (i=0; i<8; i++) buf1[i] ^= buf2[i]; + i = buf1[0]; + if (i <= 14) btoa(plain, buf1+1, i); + else plain[0] = '\0'; +} + +void CalcMAC (char mac[], const char data[], const unsigned char mac_key[]) +{ + int i; + unsigned char m[8]; + + memset(m, 0, 8); + for (i=0; data[i];) + { + m[i&7] ^= data[i]; + ++i; + if (!((i&7) && data[i])) des(m, m, mac_key, 0); + } + btoa(mac, m, 8); +} + +void CalcMAC1 (unsigned char mac[], const unsigned char data[], int len, const unsigned char mac_key[]) +{ + int i; + + memset(mac, 0, 8); + for (i=0; i +#include + +#define MAXFD 4 + +int +InitDaemon(void) +{ + pid_t pid; + + if ( (pid = fork()) < 0) + return FAILURE; + else if (pid != 0) + exit(0); /* parent goes bye-bye */ + /* child continues */ + setsid(); /* become session leader */ + // chdir("/"); /* change working direactory */ + umask(0); /* clear our file mode creation mask */ + return SUCCESS; +} + + +void +DaemonInit(const char *pname, int facility) +{ + int i; + pid_t pid; + + if ( (pid = fork()) < 0) /* parent terminates */ + err_sys("%s: %s: fork (%d)", + FILE_MACRO, FUNCTION_MACRO, LINE_MACRO); + else if (pid != 0) + { + exit(0); + } /* parent goes bye-bye */ + + /* 41st child continues */ + setsid(); /* become session leader */ + + signal(SIGHUP, SIG_IGN); + + if ( (pid = fork()) < 0) /* 1st child terminates */ + err_sys("%s: %s: fork (%d)", + FILE_MACRO, FUNCTION_MACRO, LINE_MACRO); + else if (pid != 0) + exit(0); /* 1st child goes bye-bye */ + + +// chdir("/"); /* change working directory */ + + umask(0); /* clear our file mode creation mask */ + + for (i = 0; i < MAXFD; i++) + close(i); + +} diff --git a/mss/pps/src/lib/debug.c b/mss/pps/src/lib/debug.c new file mode 100644 index 0000000..13d7c51 --- /dev/null +++ b/mss/pps/src/lib/debug.c @@ -0,0 +1,175 @@ +/* +** +** file name: logfunc.c +** +** The module performs log functions. +** +*/ + +#include "../include/includes.h" +#include /* ANSI C header file */ +#include + + +static void DebugDoIt(int, void *ptr, const char *, va_list ap); + + +/* +** Nonfatal error related to a system call. +** Print a message with the system's errno value and return. +*/ + +void +DebugRet(void *ptr, const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + DebugDoIt(1, ptr, fmt, apa); + va_end(apa); + return; +} + +/* +** Fatal error related to a system call. +** Print a message and terminate. +*/ + +void +DebugSys(void *ptr, const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + DebugDoIt(1, ptr, fmt, apa); + va_end(apa); + exit(2); +} + +/* +** Nonfatal error unrelated to a system call. +** Print a message and return. +*/ + +void +DebugMsg(void *ptr, const char *fmt, ...) +{ + + //if(get_debug_log_flag() == 0) + // return ; + + va_list apa; + va_start(apa, fmt); + DebugDoIt(0, ptr, fmt, apa); + va_end(apa); + return; +} + +/* +** Fatal error unrelated to a system call. +** Print a message and terminate. +*/ + +void +DebugQuit(void *ptr, const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + DebugDoIt(0, ptr, fmt, apa); + va_end(apa); + exit(2); +} + +/* +** Print a message and return to caller. +** Caller specifies "errnoflag" and "priority". +*/ + +static void +DebugDoIt(int errnoflag, void *ptr, const char *fmt, va_list apa) +{ + int errno_save; + char buf[8192]; + int len, old_len; + + errno_save = errno; /* value caller might want printed */ + vsprintf(buf, fmt, apa); + + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + + strcat(buf, "\r\n"); + len = strlen(buf); + if(len >= 4096) + return; + + old_len = strlen(ptr); + if((len+old_len) < 4096) + strcat(ptr,buf); + else + strcpy(ptr,buf); + + return; +} + +/* Write a message to loop queue. */ +BOOL +WriteDebugMsg(void *dest, const void *src) +{ + _debug_info *p; + + p = (_debug_info *) dest; + memcpy(&p->infoDebug[p->subWrite], src, DEBUG_LINE_LEN); + p->subWrite ++; + + /* + ** if write subscript more than max_num, + ** write subscript equal 0. + */ + if (p->subWrite == DEBUG_BUFFER_LINE) + p->subWrite = 0; + + /* + ** if message written successful, + ** Read subscript is same as Write subscript, + ** then Read subsrcipt add 1. + */ + if (p->subWrite == p->subRead) { + (p->subRead == DEBUG_BUFFER_LINE-1) ? + (p->subRead = 0) : (p->subRead ++); + return FAILURE; + } + + return SUCCESS; +} + +/* Read a message from loop queue. */ +BOOL +ReadDebugMsg(void *dest, const void *src) +{ + _debug_info *p; + + p = (_debug_info *) src; + /* + ** these are some messages not to be read + ** while subscript of read isn't equal to subscipt of write. + */ + if (p->subRead == p->subWrite) + return FAILURE; + + memcpy(dest, &p->infoDebug[p->subRead], DEBUG_LINE_LEN); + /* + ** increase READ SUBSCRIPT after got a message, + ** set READ SUBSCRIPT to 0 while it equal to max_num. + */ + p->subRead ++; + if (p->subRead == DEBUG_BUFFER_LINE) + { + p->subRead = 0; + } + + return SUCCESS; +} + + diff --git a/mss/pps/src/lib/error.c b/mss/pps/src/lib/error.c new file mode 100644 index 0000000..b074402 --- /dev/null +++ b/mss/pps/src/lib/error.c @@ -0,0 +1,113 @@ +#include +#include /* for definition of errno */ +#include /* ANSI C header file */ +#include +#include "../include/public.h" +#include "../include/errlog.h" + +static void err_doit(int, const char *, va_list); + +char *pname = NULL; /* caller can set this from argv[0] */ + +/* +** Nonfatal error related to a system call. +** Print a message and return. +*/ + +void +err_ret(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error related to a system call. +** Print a message and terminate. +*/ + +void +err_sys(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + exit(1); +} + +/* +** Fatal error related to a system call. +** Print a message, dump core, and terminate. +*/ + +void +err_dump(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + abort(); /* dump core and terminate */ + exit(1); /* shouldn't get here */ +} + +/* +** Nonfatal error unrelated to a system call. +** Print a message and return. +*/ + +void +err_msg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error unrelated to a system call. +** Print a message and terminate. +*/ + +void +err_quit(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, fmt, ap); + va_end(ap); + exit(1); +} + +/* +** Print a message and return to caller. +** Caller specifies "errnoflag". +*/ + +static void +err_doit(int errnoflag, const char *fmt, va_list ap) +{ + int errno_save; + char buf[4096]; + + errno_save = errno; /* value caller might want printed */ + vsprintf(buf, fmt, ap); + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcat(buf, "\n"); + fflush(stdout); /* in case stdout and stderr are the same */ + fputs(buf, stderr); + fflush(NULL); /* flushes all stdio output streams */ + return; +} diff --git a/mss/pps/src/lib/errorlog.c b/mss/pps/src/lib/errorlog.c new file mode 100644 index 0000000..811c5a4 --- /dev/null +++ b/mss/pps/src/lib/errorlog.c @@ -0,0 +1,128 @@ +/* Error routines for programs that can run as a daemon. */ + +#include /* for definition of errno */ +#include /* ANSI C header file */ +#include +#include "../include/errlog.h" + +static void log_doit(int, int, const char *, va_list ap); + +int debug=1; /* caller must define and set this: + nonzero if interactive, zero if daemon */ +int under_develop=1; + + + + +/* Initialize syslog(), if running as daemon. */ +void +log_open(const char *ident, int option, int facility) +{ + if (debug == 0) + openlog(ident, option, facility); +} + +/* +** Nonfatal error related to a system call. +** Print a message with the system's errno value and return. +*/ + +void +log_ret(const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + log_doit(1, LOG_ERR, fmt, apa); + va_end(apa); + return; +} + +/* +** Fatal error related to a system call. +** Print a message and terminate. +*/ + +void +log_sys(const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + log_doit(1, LOG_ERR, fmt, apa); + va_end(apa); + exit(2); +} + +/* +** Nonfatal error unrelated to a system call. +** Print a message and return. +*/ + +void +log_msg(const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + log_doit(0, LOG_ERR, fmt, apa); + va_end(apa); + return; +} + +/* +** Debug message unrelated to a system call. +** Print a message and return while . +*/ + +void +log_debug(const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + log_doit(0, LOG_ERR, fmt, apa); + va_end(apa); + return; +} + +/* +** Fatal error unrelated to a system call. +** Print a message and terminate. +*/ + +void +log_quit(const char *fmt, ...) +{ + va_list apa; + + va_start(apa, fmt); + log_doit(0, LOG_ERR, fmt, apa); + va_end(apa); + exit(2); +} + +/* +** Print a message and return to caller. +** Caller specifies "errnoflag" and "priority". +*/ + +static void +log_doit(int errnoflag, int priority, const char *fmt, va_list apa) +{ + int errno_save; + char buf[4096]; + + errno_save = errno; /* value caller might want printed */ + vsprintf(buf, fmt, apa); + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcat(buf, "\n"); + if (debug) { + fflush(stdout); + fputs(buf, stderr); + fflush(stderr); + } else + syslog(priority, "%s", buf); + return; +} diff --git a/mss/pps/src/lib/function.c b/mss/pps/src/lib/function.c new file mode 100644 index 0000000..9305070 --- /dev/null +++ b/mss/pps/src/lib/function.c @@ -0,0 +1,391 @@ +/* +** +** function.c +** +** Functions for data conversion, tools. +** +*/ + +#include "../include/includes.h" + +void +SafeFree(void *pmem) +{ + if (pmem != NULL) + free(pmem); +} + +/* +** Exchange between a and b +*/ +void +Exchange(long a, long b) +{ +long c; + + c = a; + a = b; + b = c; +} + +int +ByteLength(BYTE *bcd, int c) +{ + int length=0; + + while (*bcd++ != c) + { + length ++; +// if(length>64) break; + } + return length+1; +} + +/* +** Fill string 'c' into last area of 'str'. +*/ +/* +void +StringCat(char *str, char *c, int slen) +{ + if (strlen(str) >= slen) return; + while (strlen(str) < slen) + strcat(str, c); + str[slen] = 0; +} +*/ +/* +** Cut string while match character c. +*/ + +void +StringCut(char *str, int c) +{ + if (toupper(*str) == toupper(c)) *str=0; + while (str && *str++) + if (toupper(*str) == toupper(c)) { + *str = 0; + break; + } +} + +/* +void Bstr2Hstr(char *cptr) +{ + char s[] = ""; + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + sprintf(s, "%x", j); + cptr = (char *) s; +} + +void bitstring(char *str, long byze, int biz, int strwid) +{ + int i, j; + + j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1)); + for (i = 0; i < j; i++) + *str++ = ' '; + while (--biz >= 0) { + *str++ = ((byze >> biz) & 1) + '0'; +// +// if (!(biz % 4) && biz) +// *str++ = ' '; +// + } + *str = '\0'; +} +*/ +/* +** Binary string convert to int. +*/ +/* +unsigned int Bstr2Int(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + return(j); +} +*/ +/* +** Hex string convert to int. +*/ +/* +unsigned int Hstr2Int(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && isxdigit(*cptr)) { + i = *cptr++ - '0'; + if (9 < i) + i -= 7; + j <<= 4; + j |= (i & 0x0f); + } + return(j); +} +*/ +/* Convert data from ASCII form to left-aligned compact BCD form. */ +/* +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if (i & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from left-aligned compact BCD form to ASCII form. */ +/* +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ +/* Convert data from ASCII form to right-aligned compact BCD form. */ +/* +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + if (len > 0) memset(bcd_buf ,0,len/2); + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if ((len - i) & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from right-aligned compact BCD form to ASCII form. */ +/* +void RbcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ +/* Convert number to compact BCD, the number must in the range from 0 to 99. */ +/* +BYTE IntToBcd (int n) +{ + return ((n / 10) << 4) | (n % 10); +} +*/ +/* Convert number from compact BCD. */ +/* +int BcdToInt (BYTE n) +{ + return (n >> 4) * 10 + (n & 0x0f); +} +*/ +/* Copy charaters, then append a null character to array pointed by dst. */ +/* +void CopyToString (char *dst, const char *src, int len) +{ + if (len) memcpy(dst, src, len); + dst[len] = '\0'; +} +*/ +char * +FormatOutput(char *sp, size_t size, int len, int c) +{ + char buf[1024]; + int i, j=0; + + strcpy(buf, sp); + for(i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if(i%2==0) + { + *bcd_buf = ch & 0x0f; ; + } + else + { + *(bcd_buf) |= ((ch&0x0f) <<4 ) ; + bcd_buf ++; + } + } +} + + +/* Convert data from right-aligned compact BCD form to ASCII form. */ + +void ppsBcdToAsciiR (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i 9)? 'A'-10 : '0'); + ch = bcd_buf[i]>> 4; + ascii_buf[i*2+1] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[len] = '\0'; +} + +int AsciiToMsisdn(char *charin, u_char *msgout, int len) +{ + u_char tmpbuf[64]; + char msgin[64]; + int msglen; + if(len>18) return 0; + memcpy(msgin,charin,len); + msglen = len; + if(len%2!=0){ + msgin[len] = 'f'; + msgin[len+1] = 0x00; + msglen = len+1; + } + ppsAsciiToBcdR(tmpbuf,msgin,msglen); + msgout[0] = msglen/2; + msgout[1] = 0x91; + if(tmpbuf[0] !=0x19 && tmpbuf[0] != 0x18) + { + msgout[0] ++; + memcpy(msgout+2,tmpbuf,msglen/2); + } + else + { + memcpy(msgout+2,tmpbuf+1,msglen/2); + } + return 1; +} + +void GetVersionID(char *cversion, BYTE *version) +{ + int i,start,len,index; + char buf[3][32]={"","",""}; + + start = 0,index = 0; + len = strlen(cversion); + for(i=0;i /* ANSI C header file */ +#include +#include "../include/iofunc.h" + +/* +void +InitParport(char *prog_name, u_short partport_range) +{ + if (iopl(3) ) { + log_sys("%s: %s", prog_name, FUNCTION_MACRO); + } +} +*/ + +void +InitParport(char *prog_name, u_short parport_range) +{ + if (ioperm(parport_range, 3, 1) ) { + log_sys("%s: %s: ioperm", prog_name, FUNCTION_MACRO); + } +} + +void +SetParport(u_short parport_range, u_char flag) +{ + outb(flag, parport_range); +} + +void +SetParportOn(char ledbit,u_short parport_range) +{ + BYTE inbyte,outbyte; + BYTE ledstatus = 0x01; + ledstatus >>= ledbit; + inbyte = inb(parport_range); + outbyte = inbyte | ledstatus; + outb(outbyte, parport_range); +} + +void +SetParportOff(char ledbit, u_short parport_range) +{ + BYTE inbyte,outbyte; + inbyte = inb(parport_range); + outbyte = inbyte & 0xbf; + outb(outbyte, parport_range); +} + +void +SetNonblock(int id) +{ + fcntl(id, F_SETFL, O_NONBLOCK); +} + + +/* +++++++++++++++++++++++++++++ */ +/* Write parallel port data */ +/* +++++++++++++++++++++++++++++ */ +void SetParalPort(BYTE flag,BYTE data) +{ // Parallel port address: flag=0,address=0x37a B1;flag=1,address=0x37a B2 + // flag=2--9,address=0x378 B0--B7 + BYTE ii,jj; + + if (flag > 9) + return; + if (data != 0 && data != 1) + return; + if (flag == 0 || flag == 1) // read or write 0x37a + { + ii = inb(0x37a); +/* + jj = 1 << (flag + 1); + ii = ii & (~jj); + if (flag == 0) + jj = (~data & 0x01) << (flag + 1); + else + jj = data << (flag + 1); +*/ + jj = 1< /* ANSI C header file */ +#include + +static void LogDoIt(int, void *fp, int, const char *, va_list ap); + +int debug; /* caller must define and set this: + nonzero if interactive, zero if daemon */ + + + + +/* Initialize syslog(), if running as daemon. */ +void * +OpenLog (const char *prog_name, const char *ident, + int option, int facility) +{ + char *logpath=NULL, filename[100]; + void *fp = NULL; + + switch(debug) { + case D_CONSOLE_ONLY: + fp = stderr; + break; + case D_LOG_ONLY: + case D_CONSOLE_LOG: + if ((logpath = (char *)getenv("LOG_FILE_PATH")) == NULL) { + log_ret("%s: %s: getenv", prog_name, FUNCTION_MACRO); + fp = stderr; + break; + } + sprintf(filename, "%s/%s.log", logpath, prog_name); + if ((fp = fopen(filename, "w")) == NULL) { + log_sys("%s: %s: fopen", prog_name, FUNCTION_MACRO); + fp = stderr; + } + break; + case D_SYSLOG_MODE: + openlog(ident, option, facility); + break; + case D_NO_DEBUG: + default: + break; + } + + return fp; +} + +/* +** Nonfatal error related to a system call. +** Print a message with the system's errno value and return. +*/ + +void +LogRet(void *fp, const char *fmt, ...) +{ + va_list ap; + int priority = LOG_ERR; + + va_start(ap, fmt); + LogDoIt(1, fp, priority, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error related to a system call. +** Print a message and terminate. +*/ + +void +LogSys(void *fp, const char *fmt, ...) +{ + va_list ap; + int priority = LOG_ERR; + + va_start(ap, fmt); + LogDoIt(1, fp, priority, fmt, ap); + va_end(ap); + exit(2); +} + +/* +** Nonfatal error unrelated to a system call. +** Print a message and return. +*/ + +void +LogMsg(void *fp, const char *fmt, ...) +{ + va_list ap; + int priority = LOG_ERR; + + if (fp == NULL) return; + va_start(ap, fmt); + LogDoIt(0, fp, priority, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error unrelated to a system call. +** Print a message and terminate. +*/ + +void +LogQuit(void *fp, const char *fmt, ...) +{ + va_list ap; + int priority = LOG_ERR; + + va_start(ap, fmt); + LogDoIt(0, fp, priority, fmt, ap); + va_end(ap); + exit(2); +} + +/* +** Print a message and return to caller. +** Caller specifies "errnoflag" and "priority". +*/ + +static void +LogDoIt(int errnoflag, void *fp, int priority, + const char *fmt, va_list ap) +{ + int errno_save; + char buf[4096]; + + errno_save = errno; /* value caller might want printed */ + vsprintf(buf, fmt, ap); + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcat(buf, "\n"); + switch (debug) { + case D_CONSOLE_ONLY: + fflush(stdout); + fputs(buf, stderr); + fflush(stderr); + break; + case D_CONSOLE_LOG: + fflush(stdout); + fputs(buf, stderr); + fflush(stderr); + if (fp != stderr) { + fputs(buf, fp); + fflush(fp); + } + break; + case D_LOG_ONLY: + fflush(stdout); + fputs(buf, fp); + fflush(fp); + break; + case D_SYSLOG_MODE: + syslog(priority, "%s", buf); break; + case D_NO_DEBUG: + default: + break; + } + + return; +} + +void +GetErrnoMsg(char *sp, const char *fmt, ...) +{ + va_list ap; + int errno_save; + char buf[4096*2]; + + errno_save = errno; /* value caller might want printed */ + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcpy(sp, buf); + + return; +} + +/* +** Close log file point. +** Return 0 on success, -1 on failure. +*/ +void +CloseLog (void *fp) +{ + fclose(fp); + fp = stdout; +} + diff --git a/mss/pps/src/lib/ppsfun.c b/mss/pps/src/lib/ppsfun.c new file mode 100644 index 0000000..b3d8dff --- /dev/null +++ b/mss/pps/src/lib/ppsfun.c @@ -0,0 +1,372 @@ +/* +** +** function.c +** +** Functions for data conversion, tools. +** +*/ + +#include "../include/includes.h" + +void +SafeFree(void *pmem) +{ + if (pmem != NULL) + free(pmem); +} + +/* +** Exchange between a and b +*/ +void +Exchange(long a, long b) +{ +long c; + + c = a; + a = b; + b = c; +} + +int +ByteLength(BYTE *bcd, int c) +{ + int length=0; + + while (*bcd++ != c) + { + length ++; +// if(length>64) break; + } + return length+1; +} + +/* +** Fill string 'c' into last area of 'str'. +*/ +/* +void +StringCat(char *str, char *c, int slen) +{ + if (strlen(str) >= slen) return; + while (strlen(str) < slen) + strcat(str, c); + str[slen] = 0; +} +*/ +/* +** Cut string while match character c. +*/ + +void +StringCut(char *str, int c) +{ + if (toupper(*str) == toupper(c)) *str=0; + while (str && *str++) + if (toupper(*str) == toupper(c)) { + *str = 0; + break; + } +} + +/* +void Bstr2Hstr(char *cptr) +{ + char s[] = ""; + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + sprintf(s, "%x", j); + cptr = (char *) s; +} + +void bitstring(char *str, long byze, int biz, int strwid) +{ + int i, j; + + j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1)); + for (i = 0; i < j; i++) + *str++ = ' '; + while (--biz >= 0) { + *str++ = ((byze >> biz) & 1) + '0'; +// +// if (!(biz % 4) && biz) +// *str++ = ' '; +// + } + *str = '\0'; +} +*/ +/* +** Binary string convert to int. +*/ +/* +unsigned int Bstr2Int(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + return(j); +} +*/ +/* +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if (i & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from left-aligned compact BCD form to ASCII form. */ +/* +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ +/* Convert data from ASCII form to right-aligned compact BCD form. */ +/* +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + if (len > 0) memset(bcd_buf ,0,len/2); + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if ((len - i) & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from right-aligned compact BCD form to ASCII form. */ +/* +void RbcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ +/* Convert number to compact BCD, the number must in the range from 0 to 99. */ +/* +BYTE IntToBcd (int n) +{ + return ((n / 10) << 4) | (n % 10); +} +*/ +/* Convert number from compact BCD. */ +/* +int BcdToInt (BYTE n) +{ + return (n >> 4) * 10 + (n & 0x0f); +} +*/ +/* Copy charaters, then append a null character to array pointed by dst. */ +/* +void CopyToString (char *dst, const char *src, int len) +{ + if (len) memcpy(dst, src, len); + dst[len] = '\0'; +} +*/ +char * +FormatOutput(char *sp, size_t size, int len, int c) +{ + char buf[1024]; + int i, j=0; + + strcpy(buf, sp); + for(i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if(i%2==0) + { + *bcd_buf = ch & 0x0f; ; + } + else + { + *(bcd_buf) |= ((ch&0x0f) <<4 ) ; + bcd_buf ++; + } + } +} + + +/* Convert data from right-aligned compact BCD form to ASCII form. */ + +void ppsBcdToAsciiR (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i 9)? 'A'-10 : '0'); + ch = bcd_buf[i]>> 4; + ascii_buf[i*2+1] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[len] = '\0'; +} + +int AsciiToMsisdn(char *charin, u_char *msgout, int len) +{ + u_char tmpbuf[64]; + char msgin[64]; + int msglen; + if(len>18) return 0; + memcpy(msgin,charin,len); + msglen = len; + if(len%2!=0){ + msgin[len] = 'f'; + msgin[len+1] = 0x00; + msglen = len+1; + } + ppsAsciiToBcdR(tmpbuf,msgin,msglen); + msgout[0] = msglen/2; + msgout[1] = 0x91; + if(tmpbuf[0] !=0x19 && tmpbuf[0] != 0x18) + { + msgout[0] ++; + memcpy(msgout+2,tmpbuf,msglen/2); + } + else + { + memcpy(msgout+2,tmpbuf+1,msglen/2); + } + return 1; +} + +void GetVersionID(char *cversion, BYTE *version) +{ + int i,start,len,index; + char buf[3][32]={"","",""}; + + start = 0,index = 0; + len = strlen(cversion); + for(i=0;i64) break; + } + return length+1; +} + +/* +** Fill string 'c' into last area of 'str'. +*/ +/* +void +StringCat(char *str, char *c, int slen) +{ + if (strlen(str) >= slen) return; + while (strlen(str) < slen) + strcat(str, c); + str[slen] = 0; +} +*/ +/* +** Cut string while match character c. +*/ + +void +StringCut(char *str, int c) +{ + if (toupper(*str) == toupper(c)) *str=0; + while (str && *str++) + if (toupper(*str) == toupper(c)) { + *str = 0; + break; + } +} + +/* +void Bstr2Hstr(char *cptr) +{ + char s[] = ""; + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + sprintf(s, "%x", j); + cptr = (char *) s; +} + +void bitstring(char *str, long byze, int biz, int strwid) +{ + int i, j; + + j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1)); + for (i = 0; i < j; i++) + *str++ = ' '; + while (--biz >= 0) { + *str++ = ((byze >> biz) & 1) + '0'; +// +// if (!(biz % 4) && biz) +// *str++ = ' '; +// + } + *str = '\0'; +} +*/ +/* +** Binary string convert to int. +*/ +/* +unsigned int Bstr2Int(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + return(j); +} +*/ +/* +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if (i & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from left-aligned compact BCD form to ASCII form. */ +/* +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ +/* Convert data from ASCII form to right-aligned compact BCD form. */ +/* +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + if (len > 0) memset(bcd_buf ,0,len/2); + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if ((len - i) & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from right-aligned compact BCD form to ASCII form. */ +/* +void RbcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ +/* Convert number to compact BCD, the number must in the range from 0 to 99. */ +/* +BYTE IntToBcd (int n) +{ + return ((n / 10) << 4) | (n % 10); +} +*/ +/* Convert number from compact BCD. */ +/* +int BcdToInt (BYTE n) +{ + return (n >> 4) * 10 + (n & 0x0f); +} +*/ +/* Copy charaters, then append a null character to array pointed by dst. */ +/* +void CopyToString (char *dst, const char *src, int len) +{ + if (len) memcpy(dst, src, len); + dst[len] = '\0'; +} +*/ +char * +FormatOutput(char *sp, size_t size, int len, int c) +{ + char buf[BUFSIZE]; + int i, j=0; + + strcpy(buf, sp); + for(i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if(i%2==0) + { + *bcd_buf = ch & 0x0f; ; + } + else + { + *(bcd_buf) |= ((ch&0x0f) <<4 ) ; + bcd_buf ++; + } + } +} + + +/* Convert data from right-aligned compact BCD form to ASCII form. */ + +void ppsBcdToAsciiR (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i 9)? 'A'-10 : '0'); + ch = bcd_buf[i]>> 4; + ascii_buf[i*2+1] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[len] = '\0'; +} + +int AsciiToMsisdn(char *charin, u_char *msgout, int len) +{ + u_char tmpbuf[64]; + char msgin[64]; + int msglen; + if(len>18) return 0; + memcpy(msgin,charin,len); + msglen = len; + if(len%2!=0){ + msgin[len] = 'f'; + msgin[len+1] = 0x00; + msglen = len+1; + } + ppsAsciiToBcdR(tmpbuf,msgin,msglen); + msgout[0] = msglen/2; + msgout[1] = 0x91; + if(tmpbuf[0] !=0x19 && tmpbuf[0] != 0x18) + { + msgout[0] ++; + memcpy(msgout+2,tmpbuf,msglen/2); + } + else + { + memcpy(msgout+2,tmpbuf+1,msglen/2); + } + return 1; +} + +void GetVersionID(char *cversion, BYTE *version) +{ + int i,start,len,index; + char buf[3][32]={"","",""}; + + start = 0,index = 0; + len = strlen(cversion); + for(i=0;i> 4) | (*ptr << 4); + ptr ++; + } + return ptr; +} + +void +Strrev(char *sp) +{ + char ch; + ch = sp[0]; + sp[0] = sp[1]; + sp[1] = ch; +} + +void +ByteReverse(BYTE *pbuf, BYTE *p, size_t size) +{ + + int i; + char *sp=NULL, tmpbuf[3]; + + sp = (char *) malloc(4*size + 1); + bzero(p, size); + + for (i=0; i<2*size; i+=2) { + sprintf(tmpbuf, "%02x", *(pbuf++)); + tmpbuf[2]=0; + Strrev(tmpbuf); + strncpy(sp+i, tmpbuf, 2); + } + AsciiToBcd(pbuf, sp, 4*size); + memcpy(p, pbuf, 2*size); + free(sp); +} diff --git a/mss/pps/src/lib/signal.c b/mss/pps/src/lib/signal.c new file mode 100644 index 0000000..a6426a7 --- /dev/null +++ b/mss/pps/src/lib/signal.c @@ -0,0 +1,44 @@ +/* +** +** Signal functions +** +*/ + +#include "../include/includes.h" + +/* +** Set termination signal in a loop program, +** handler of function mostly deal with something, +** e.g. closing file handler, socket handler or free allocatied memory. +*/ +void +SetTermSignal(struct termio *ptermio, void (*handler)(int)) +{ + ioctl(0, TCGETA, ptermio); + ptermio->c_cc[VINTR] = '\x03'; + ioctl(0, TCSETA, ptermio); + + signal(SIGINT, handler); + signal(SIGTERM, handler); + signal(SIGSTOP, handler); + signal(SIGKILL, handler); + signal(SIGQUIT, handler); + signal(SIGABRT, handler); + signal(SIGHUP, handler); +} + +void +SetFaultSignal(void (*handler)(int) ) +{ + signal(SIGSEGV, handler); +} + +void +SetRefreshSignal(struct termio *ptermio, void (*handler)(int)) +{ + ioctl(0, TCGETA, ptermio); + ptermio->c_cc[VQUIT] = '\x12'; /* QUIT: Ctrl+R */ + ioctl(0, TCSETA, ptermio); + + signal(SIGQUIT, handler); +} diff --git a/mss/pps/src/lib/time.c b/mss/pps/src/lib/time.c new file mode 100644 index 0000000..ebcfc94 --- /dev/null +++ b/mss/pps/src/lib/time.c @@ -0,0 +1,377 @@ +/* +** +** file name: tim.c +** +** time functions +** +*/ + +#include "../include/includes.h" + + +char * GetASCTime(char *timep) +{ + struct tm *tp, tb; + long ltime; + + tp = &tb; + ltime = time((long *)0); + tp = localtime(<ime); + timep = asctime(tp); + timep[24] = 0; + return timep; +} + +char * CharTime(char *ptr, const time_t *timep) +{ + strncpy(ptr, ctime(timep), 24); + ptr[24] = 0; + return ptr; +} + +/* Get current hour */ +/* +int gethour(char * hour_buf) +{ + struct tm *t, tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(hour_buf, "%d", t -> tm_hour); + hour_buf[2]=0; + return t -> tm_hour; +} +*/ +u_short +GetHour(time_t t) +{ + struct tm tmb; + + memcpy(&tmb, localtime(&t), sizeof(struct tm)); + return tmb.tm_hour; +} + +u_short +GetTmHour() +{ + struct tm tmb; + time_t curr_time; + + curr_time = time(NULL); + memcpy(&tmb, localtime(&curr_time), sizeof(struct tm)); + return tmb.tm_hour; +} + +/* Get current hour */ +/* +int getmin(char * min_buf) +{ + struct tm *t, tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(min_buf, "%d", t -> tm_min); + min_buf[2]=0; + return t -> tm_min; +} +*/ +u_short +GetMinute(time_t t) +{ + struct tm tmb; + memcpy(&tmb, localtime(&t), sizeof(struct tm)); + return tmb.tm_min; +} + +u_short +GetTmMinute() +{ + struct tm tmb; + time_t curr_time; + + curr_time = time(NULL); + memcpy(&tmb, localtime(&curr_time), sizeof(struct tm)); + return tmb.tm_min; +} + +/* Get current time */ +/* +int getsec(char * sec_buf) +{ + struct tm *t, tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(sec_buf, "%d", t -> tm_sec); + sec_buf[2]=0; + return t -> tm_sec; +} +*/ +u_short +GetTmSecond() +{ + struct tm tmb; + time_t curr_time; + + curr_time = time(NULL); + memcpy(&tmb, localtime(&curr_time), sizeof(struct tm)); + return tmb.tm_sec; +} + +/* Get current time */ +/* +void gettime(time_buf) +char *time_buf; +{ + struct tm *t,tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(time_buf,"%02d:%02d:%02d",t->tm_hour,t->tm_min,t->tm_sec); + time_buf[8]=0; +} +*/ + +const char * ppsgetdaytime(char *daytime_buf) +{ + struct tm *t,tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(daytime_buf,"%04d%02d%02d%02d%02d%02d", + t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, + t->tm_min, t->tm_sec); + daytime_buf[14] = 0; + return daytime_buf; +} + +const int getnowtime(int *time_buf) +{ + struct tm *t,tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + time_buf[0] = t->tm_year+1900; + time_buf[1] = t->tm_mon+1; + time_buf[2] = t->tm_mday; + time_buf[3] = t->tm_hour; + time_buf[4] = t->tm_min; + time_buf[5] = t->tm_sec; + time_buf[6] = t->tm_wday; + return 1; +} + +const char * AsciiTime(char *ptr, time_t time) +{ + struct tm *t,tt; + + t=&tt; + t=localtime(&time); + sprintf(ptr,"%04d%02d%02d%02d%02d%02d", + t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, + t->tm_min, t->tm_sec); + ptr[14] = 0; + return ptr; +} + + +const char * AsciiTimeYMD(char *ptr, time_t time) +{ + struct tm *t,tt; + + t=&tt; + t=localtime(&time); + + sprintf(ptr,"%04d-%02d-%02d", + t->tm_year+1900, t->tm_mon+1, t->tm_mday); + + return ptr; +} + +const char * AsciiTimeYMDHMS(char *ptr, time_t time) +{ + struct tm *t,tt; + + t=&tt; + t=localtime(&time); + sprintf(ptr,"%02d-%02d-%04d %02d:%02d:%02d", + t->tm_mday, t->tm_mon+1,t->tm_year+1900, t->tm_hour, + t->tm_min, t->tm_sec); + ptr[19] = 0; + return ptr; +} + +u_short +GetTmDay() +{ + struct tm tmb; + time_t curr_time; + + curr_time = time(NULL); + memcpy(&tmb, localtime(&curr_time), sizeof(struct tm)); + return tmb.tm_mday; +} + +u_short +GetTmMonth() +{ + struct tm tmb; + time_t curr_time; + + curr_time = time(NULL); + memcpy(&tmb, localtime(&curr_time), sizeof(struct tm)); + return tmb.tm_mon+1; +} +/* +int getday(day_buf) +char *day_buf; +{ + struct tm *t,tt; + long curr_date; + + t=&tt; + curr_date=time((long *)0); + t=localtime(&curr_date); + sprintf(day_buf,"%02d", t->tm_mday); + day_buf[2]=0; + return t->tm_mday; +} +*/ +u_short +GetTmYear() +{ + struct tm tmb; + time_t curr_time; + + curr_time = time(NULL); + memcpy(&tmb, localtime(&curr_time), sizeof(struct tm)); + return tmb.tm_year+1900; +} + +int getweek(week_buf) +char *week_buf; +{ + struct tm *t,tt; + long curr_date; + + t=&tt; + curr_date=time((long *)0); + t=localtime(&curr_date); + sprintf(week_buf,"%02d", t->tm_wday); + week_buf[2]=0; + return t->tm_wday; +} +/* +int getmon(mon_buf) +char *mon_buf; +{ + struct tm *t,tt; + long curr_date; + + t=&tt; + curr_date=time((long *)0); + t=localtime(&curr_date); + sprintf(mon_buf,"%02d", t->tm_mon+1); + mon_buf[2]=0; + return t->tm_mon; +} + +int getyear(year_buf) +char *year_buf; +{ + struct tm *t,tt; + long curr_date; + + t=&tt; + curr_date=time((long *)0); + t=localtime(&curr_date); + sprintf(year_buf,"%04d", t->tm_year+1900); + year_buf[4]=0; + return t->tm_year; +} +*/ +/* Get current date */ +/* +void getdate(date_buf) +char *date_buf; +{ + struct tm *t,tt; + long curr_date; + + t=&tt; + curr_date=time((long *)0); + t=localtime(&curr_date); + sprintf(date_buf,"%04d-%02d-%02d",t->tm_year+1900,t->tm_mon+1,t->tm_mday); + date_buf[10]=0; +} +*/ +time_t +MakeTime(struct tm *timep, char *ptr) +{ + char tempbuf[5]; + struct tm tm, *timeptr; + time_t retval; + memset(&tm, 0, sizeof(struct tm)); + timeptr = &tm; + strncpy(tempbuf, ptr, 4); + tempbuf[4] = 0; + timeptr->tm_year = atoi(tempbuf) - 1900; + strncpy(tempbuf, ptr+4, 2); + tempbuf[2] = 0; + timeptr->tm_mon = atoi(tempbuf) - 1; + strncpy(tempbuf, ptr+6, 2); + tempbuf[2] = 0; + timeptr->tm_mday = atoi(tempbuf); + strncpy(tempbuf, ptr+8, 2); + tempbuf[2] = 0; + timeptr->tm_hour = atoi(tempbuf); + strncpy(tempbuf, ptr+10, 2); + tempbuf[2] = 0; + timeptr->tm_min = atoi(tempbuf); + strncpy(tempbuf, ptr+12, 2); + tempbuf[2] = 0; + timeptr->tm_sec = atoi(tempbuf); + retval = mktime(timeptr); + if (NULL != timep) + timep = timeptr; + return (retval); +} + +char * +GetTmDate(char *date_buf) +{ + struct tm tmb; + time_t curr_time; + + curr_time = time(NULL); + memcpy(&tmb, localtime(&curr_time), sizeof(struct tm)); + sprintf(date_buf, "%04d%02d%02d", + tmb.tm_year+1900, tmb.tm_mon+1, tmb.tm_mday); + date_buf[9] = 0; + return (char *)date_buf; +} + +void +CharToTimeStamp(u_char *btime, char *atime) +{ + char timestamp[128]={""}; + char buf[128]; + BcdToAscii(buf, (BYTE *)atime, 14); + memcpy(timestamp,&buf[2],12); + + sprintf(×tamp[12],"%02d",0); + sprintf(×tamp[14],"%02d",8); + AsciiToBcd(btime,timestamp,16); +} diff --git a/mss/pps/src/lib/version.c b/mss/pps/src/lib/version.c new file mode 100644 index 0000000..0085e81 --- /dev/null +++ b/mss/pps/src/lib/version.c @@ -0,0 +1,15 @@ +/* +** module name: version.c +** +*/ + +#include "../include/includes.h" +#include "../include/version.h" + +void +SetVersionID(u_char *ptr) +{ + *ptr++ = VER_MAJOR; + *ptr++ = VER_MINOR; + *ptr = VER_FIX; +} diff --git a/mss/pps/src/log/dailyreport.bak b/mss/pps/src/log/dailyreport.bak new file mode 100644 index 0000000000000000000000000000000000000000..0159667892f1df5a747a455a18675ba5ef1cb265 GIT binary patch literal 476 Wcmcb{&cMLIz`!5?#G_z%g#ZA^&;a%T literal 0 HcmV?d00001 diff --git a/mss/pps/src/log/pps_trace.log b/mss/pps/src/log/pps_trace.log new file mode 100644 index 0000000..2d4476d --- /dev/null +++ b/mss/pps/src/log/pps_trace.log @@ -0,0 +1,33 @@ +Last function : (31) +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> +-> diff --git a/mss/pps/src/log/snmp_log.txt b/mss/pps/src/log/snmp_log.txt new file mode 100644 index 0000000..8138a4e --- /dev/null +++ b/mss/pps/src/log/snmp_log.txt @@ -0,0 +1,36 @@ +-------- SNMP log info ------- +---------------------------------- +---> Lastest log No. = 31 <----- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +------------- End -------------- diff --git a/mss/pps/src/main/.Makefile.swp b/mss/pps/src/main/.Makefile.swp new file mode 100644 index 0000000000000000000000000000000000000000..7d19fdee585c2c270d617bcf0ee54402203f38fe GIT binary patch literal 16384 zcmeI2OKc=Z8OMu&Lrlo>2q+u^s$eVFE68*!#s!)i$*;?J>$mx zQa{$-mB>bfMTiR*!~p@>1BZx50)hh)2qC29z~hFrIYdDSgcKeZM506-!vCx88c#oV zA-6@Uk$;}<@6}&_T~*Uv)uZ)KHrxDcd4u8ePR1U7Zbkd!jRiLN0Aqn^yAH|!%SYH< z-PfFHaP>~6PYA<`s|V$&8CC*cuh>CQ@w_13)=a0;)((t`X&HBlqjahQsseAY0#P_A zojox)y>V)tJeNNB2!HV1gEtsNnX3w@3aARG3aARG3aARG3aARG3j9A;AoT8G*Kh*& zBqu@J^m$YKHT!-&`79^$Co}qFSAD4ps0yeGs0yeGs0yeGs0yeGs0yeGs0yeGs0!SL z70||voj_iX(gXn3|K;=l%kN<9ci_9g1QoCh-Ul86C%_AEd=gv(SAhlE;0$;e{QCjM z{s4XjZh~)u>)0p1T5!0+GA*iXS%KmeMc0v5pE?q}>5;2H2apn=E0N$>!8?QM*` z3SI#(gMWa(gPY*{;CtYU;5snDIq(qp=OWGzJOiErm%vBByTHHhW9)fw3;Y)R2E6iC z#0Ssb%h(O@RqzxDfCestKQA!$CvXe=5_}ze359 zr8AcE4Q$WTJTv1frEXPj75Vy_Z9CJ9Ya(>3Qd@9P&o^|<&n28lk+9Sk`Feq!IV8@{ zE{oHIrr2c?IeOkpNQGmpXN&m)QE+pV_a$L`Ow!)Qvu%$0+Q>5U?lX;uG26RM`nKlf zLy$1efV2hYZ5Nz%EOV=guE@&>0&SX2*-oVJl==c+%hkrAl}R-bx>czya2#u!EtrXvx96CPK5AEv}`HYZ>U+|9jQ#ROH!O%7cyW= z+#P+E(~DFA-t|~Kx4hD7?pzdo*F}%*bayZGRxKAo^vDkk(%2l$_?)5dQ}p>rQra?|1JjxE<#RMh*wy1h zBUj_d(4)}2Y>156(wtJWEZ8Rbk}IXlYn;o1@%hW+a(UsoY%(rSnjZ~Wq65*!tns_F z7xzhFP=-K`30#gVT#iUC7nfF8Qcs`_F$_Y1OmTvBj4^Fo-ISmgYM}v9sQKn(vgvu2 zscWI>I*D1^*wXX^>`Z*a=(T&aWf*;5bApNCW6#!t(C~YfcG;iY;do#(&_Yu+pW#GozqUMxz*k5ergrEUVZymM>|q?3Cd=t-`(7qbCv>W z#L24H?sOoS3qykQvq-||d}C{HA!QXyGG^_5=XA!dOdSM5@d|}_06=A5M+$@ zHZ!RULB^=J(>{(gY|;oJL^CszQ6V~mtyZ(1NOaG0HmBb)l*!msh$Ms9-9LhRvN-#^R_o#yA?waf`rkQnJv_giM%| zq{T4=;%~RprIC=$H51_w=o2A3cEGS@X(1}n={9H-t&mBk@d#Jb3#o6c95qLCe-*FIVmUF0}=N+rEwQ>ZFY;IpOD zE?zpHbrzg4CP!z_49|SHgao6b($tA&M$#*Z zoeBIney4fqamOu14t^lVCHnEF-(p^xvU(laO?BMmiNbBRdX3t;*zR`+joK-;WaYq(FU`vz_##(Z>ze=Nf5_WTpAHNLUFzFs-CQQ0^H z3;FsypCHkFL-RvEf)Cw!dA_UTHX3r+JyIFrW&2>C(ewWeJV&?itWD4V%gJ-!i+H|& z4$$-ebua)u&;=*KYk0nY6}$+341NTj21no!d>X8S3b-GMofEIW;y z4v^Ji*(EdWT(tTzKT(~IH?MK4^LvGHlBw@Z3^^fQl~dzIzL=)4k~#FW`<#MSR*tO- zmSysj^XXW5y<5%8D82jzqeCZ)1MylwI&@AQC!6+Qi?qgqIfwK@?3^#HJKQ#~Sd literal 0 HcmV?d00001 diff --git a/mss/pps/src/main/Cook_Makefile b/mss/pps/src/main/Cook_Makefile new file mode 100644 index 0000000..23b4132 --- /dev/null +++ b/mss/pps/src/main/Cook_Makefile @@ -0,0 +1,160 @@ +# !/bin/sh +# Makefile for heart beating processor +# Created by Huang QL, 2000/12/26 +#If you want to include which Module,Set the INC_XXX=$(INC_TRUE), +#or set it to $(INC_FALSE),then run the command: make alt +INC_TRUE=1 +INC_FALSE=0 + +CC = gcc +CFLAGS=-D_REENTRANT -D_MAX_64COS_COOK_ -Wall -Wno-unused-function -g -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -I/usr/local/lib/glib-2.0/include -L/usr/local/lib -lglib-2.0 +#-O2 +prefix = /usr +includedir = $(prefix)/include +libdir = $(prefix)/lib +localinclude = ../include +platLIBPREFIX =../../../wxc2plat +INC_FLAGS = -I$(includedir) +INCLUDES = -I../include + +XAPPLIB_FLAGS = -L$(platLIBPREFIX)/xapp +XAPPLD_LIBRARY = -lxapp +TCAPLIB_FLAGS = -L$(platLIBPREFIX)/tcap +TCAPLD_LIBRARY = -ltcap +SCCPLIB_FLAGS = -L$(platLIBPREFIX)/sccp +SCCPLD_LIBRARY = -lsccp +MTP3LIB_FLAGS = -L$(platLIBPREFIX)/mtp3 -lcurses +MTP3LD_LIBRARY = -lmtp3 +PUBLICLIB_FLAGS = -L$(platLIBPREFIX)/public +PUBLICLD_LIBRARY = -lpublic +DEBUGLIB_FLAGS = -L$(platLIBPREFIX)/debug +DEBUGLD_LIBRARY = -ldebug +SNMPLIB_FLAGS_I = -L$(platLIBPREFIX)/snmp +SNMPLD_LIBRARY_I = -lsnmp +SMPPLIB_FLAGS = -L$(platLIBPREFIX)/smppold +SMPPLD_LIBRARY = -lsmpp +IPTRANS_FLAGS = -L$(platLIBPREFIX)/iptrans +IPTRANS_LIBRARY = -liptrans +SCF_FLAGS = -L$(platLIBPREFIX)/scf +SCF_LIBRARY = -lscf +PPS_FLAGS = -L ../../OPR/lib +PPS_LIBRARY = -lopr + + + +STATIC= + +COMPILE.c=$(CC) $(CFLAGS) +LINK.c=$(CC) $(CFLAGS) + +COMPILE_SUFFIX=$(STATIC) $(INC_FLAGS) + +LINK_SUFFIX= $(INC_FLAGS) \ +$(PUBLICLIB_FLAGS) $(PUBLICLD_LIBRARY) \ +$(SNMPLIB_FLAGS_I) $(SNMPLD_LIBRARY_I) \ +$(XAPPLIB_FLAGS) $(XAPPLD_LIBRARY) \ +$(TCAPLIB_FLAGS) $(TCAPLD_LIBRARY) \ +$(SCCPLIB_FLAGS) $(SCCPLD_LIBRARY) \ +$(MTP3LIB_FLAGS) $(MTP3LD_LIBRARY) \ +$(DEBUGLIB_FLAGS) $(DEBUGLD_LIBRARY) \ +$(SMPPLIB_FLAGS) $(SMPPLD_LIBRARY) \ +$(IPTRANS_FLAGS) $(IPTRANS_LIBRARY) \ +$(SCF_FLAGS) $(SCF_LIBRARY)\ +$(PPS_FLAGS) $(PPS_LIBRARY) + +PROGS=ppsm + +#pps_OBJ = ppsmain.o capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o ppsopr.o callingCardMsg.o callingCardState.o + +pps_OBJ = capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o callingCardMsg.o callingCardState.o tariffApplication.o callMeBack.o freeSMS.o feeTransfer.o masterSlaveCard.o radius.o gprs.o vas.o restapi.o ocs_user_table.o pps_redis.o +all:$(PROGS) +#$(pps_OBJ) +# executive file +ppsm:$(pps_OBJ) + @echo Linking $@ + @echo $(LINK_SUFFIX) +# @$(LINK.c) -o $(PROGS) $(pps_OBJ) $(LINK_SUFFIX) -L../lib/ -lppsfuns -ldl -lz -lpopt -lncurses -lm + +# obj files +#ppsmain.o:ppsmain.c +# $(COMPILE.c) -c ppsmain.c $(INCLUDES) +capmsg.o:capmsg.c + $(COMPILE.c) -c capmsg.c $(INCLUDES) + +crd.o:crd.c + $(COMPILE.c) -c crd.c $(INCLUDES) + +dailyreport.o:dailyreport.c + $(COMPILE.c) -c dailyreport.c $(INCLUDES) + +loadtl.o:loadtl.c + $(COMPILE.c) -c loadtl.c $(INCLUDES) + +message.o:message.c + $(COMPILE.c) -c message.c $(INCLUDES) + +mfunc.o:mfunc.c + $(COMPILE.c) -c mfunc.c $(INCLUDES) + +ppsmap.o:ppsmap.c + $(COMPILE.c) -c ppsmap.c $(INCLUDES) + +ppsMibTable.o:ppsMibTable.c + $(COMPILE.c) -c ppsMibTable.c $(INCLUDES) + +ppsmib.o:ppsmib.c + $(COMPILE.c) -c ppsmib.c $(INCLUDES) + +ppsfunc.o:ppsfunc.c + $(COMPILE.c) -c ppsfunc.c $(INCLUDES) + +ppsm.o:ppsm.c + $(COMPILE.c) -c ppsm.c $(INCLUDES) + +precard.o:precard.c + $(COMPILE.c) -c precard.c $(INCLUDES) + +rammng.o:rammng.c + $(COMPILE.c) -c rammng.c $(INCLUDES) + +smppapi.o:smppapi.c + $(COMPILE.c) -c smppapi.c $(INCLUDES) + +ppsussd.o:ppsussd.c + $(COMPILE.c) -c ppsussd.c $(INCLUDES) + +callingCardMsg.o:callingCardMsg.c + $(COMPILE.c) -c callingCardMsg.c $(INCLUDES) + +callingCardState.o:callingCardState.c + $(COMPILE.c) -c callingCardState.c $(INCLUDES) + + +tariffApplication.o:tariffApplication.c + $(COMPILE.c) -c tariffApplication.c $(INCLUDES) + +callMeBack.o:callMeBack.c + $(COMPILE.c) -c callMeBack.c $(INCLUDES) + +freeSMS.o:freeSMS.c + $(COMPILE.c) -c freeSMS.c $(INCLUDES) + +feeTransfer.o:feeTransfer.c + $(COMPILE.c) -c feeTransfer.c $(INCLUDES) + +masterSlaveCard.o:masterSlaveCard.c + $(COMPILE.c) -c masterSlaveCard.c $(INCLUDES) +radius.o:radius.c + $(COMPILE.c) -c radius.c $(INCLUDES) +gprs.o:gprs.c + $(COMPILE.c) -c gprs.c $(INCLUDES) +vas.o:vas.c + $(COMPILE.c) -c vas.c $(INCLUDES) +restapi.o:restapi.c + $(COMPILE.c) -c restapi.c $(INCLUDES) +ocs_user_table.o:ocs_user_table.c + $(COMPILE.c) -c ocs_user_table.c $(INCLUDES) +pps_redis.o:pps_redis.c + $(COMPILE.c) -c pps_redis.c $(INCLUDES) +clean: + rm -f *.c~ *.o core ppsm *.c.bak diff --git a/mss/pps/src/main/Makefile b/mss/pps/src/main/Makefile new file mode 100644 index 0000000..7f3dd69 --- /dev/null +++ b/mss/pps/src/main/Makefile @@ -0,0 +1,163 @@ +# !/bin/sh +# Makefile for heart beating processor +# Created by Huang QL, 2000/12/26 +#If you want to include which Module,Set the INC_XXX=$(INC_TRUE), +#or set it to $(INC_FALSE),then run the command: make alt +INC_TRUE=1 +INC_FALSE=0 + +CC = gcc +CFLAGS=-D_REENTRANT -Wall -Wno-unused-function -g +CFLAGS_IN=-D_REENTRANT -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include + +#-O2 +prefix = /usr +includedir = $(prefix)/include +libdir = $(prefix)/lib +localinclude = ../include +platLIBPREFIX =../../../wxc2plat +INC_FLAGS = -I$(includedir) +INCLUDES = -I../include + +XAPPLIB_FLAGS = -L$(platLIBPREFIX)/xapp +XAPPLD_LIBRARY = -lxapp +TCAPLIB_FLAGS = -L$(platLIBPREFIX)/tcap +TCAPLD_LIBRARY = -ltcap +SCCPLIB_FLAGS = -L$(platLIBPREFIX)/sccp +SCCPLD_LIBRARY = -lsccp +MTP3LIB_FLAGS = -L$(platLIBPREFIX)/mtp3 -lcurses +MTP3LD_LIBRARY = -lmtp3 +PUBLICLIB_FLAGS = -L$(platLIBPREFIX)/public +PUBLICLD_LIBRARY = -lpublic +DEBUGLIB_FLAGS = -L$(platLIBPREFIX)/debug +DEBUGLD_LIBRARY = -ldebug +SNMPLIB_FLAGS_I = -L$(platLIBPREFIX)/snmp +SNMPLD_LIBRARY_I = -lsnmp +SMPPLIB_FLAGS = -L$(platLIBPREFIX)/smppold +SMPPLD_LIBRARY = -lsmpp +IPTRANS_FLAGS = -L$(platLIBPREFIX)/iptrans +IPTRANS_LIBRARY = -liptrans +SCF_FLAGS = -L$(platLIBPREFIX)/scf +SCF_LIBRARY = -lscf +PPS_FLAGS = -L ../../OPR/lib +PPS_LIBRARY = -lopr + + + +STATIC= + +COMPILE.c=$(CC) $(CFLAGS) $(CFLAGS_IN) +LINK.c=$(CC) $(CFLAGS) + +COMPILE_SUFFIX=$(STATIC) $(INC_FLAGS) + +LINK_SUFFIX= $(INC_FLAGS) \ +$(PUBLICLIB_FLAGS) $(PUBLICLD_LIBRARY) \ +$(SNMPLIB_FLAGS_I) $(SNMPLD_LIBRARY_I) \ +$(XAPPLIB_FLAGS) $(XAPPLD_LIBRARY) \ +$(TCAPLIB_FLAGS) $(TCAPLD_LIBRARY) \ +$(SCCPLIB_FLAGS) $(SCCPLD_LIBRARY) \ +$(MTP3LIB_FLAGS) $(MTP3LD_LIBRARY) \ +$(DEBUGLIB_FLAGS) $(DEBUGLD_LIBRARY) \ +$(SMPPLIB_FLAGS) $(SMPPLD_LIBRARY) \ +$(IPTRANS_FLAGS) $(IPTRANS_LIBRARY) \ +$(SCF_FLAGS) $(SCF_LIBRARY)\ +$(PPS_FLAGS) $(PPS_LIBRARY) + +PROGS=ppsm + +#pps_OBJ = ppsmain.o capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o ppsopr.o callingCardMsg.o callingCardState.o + +pps_OBJ = capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o callingCardMsg.o callingCardState.o tariffApplication.o callMeBack.o freeSMS.o feeTransfer.o masterSlaveCard.o radius.o gprs.o vas.o restapi.o ocs_user_table.o pps_redis.o +all:$(PROGS) +#$(pps_OBJ) +# executive file +ppsm:$(pps_OBJ) + @echo Linking $@ + @echo $(LINK_SUFFIX) +# @$(LINK.c) -o $(PROGS) $(pps_OBJ) $(LINK_SUFFIX) -L../lib/ -lppsfuns -ldl -lz -lpopt -lncurses -lm + +# obj files +#ppsmain.o:ppsmain.c +# $(COMPILE.c) -c ppsmain.c $(INCLUDES) +capmsg.o:capmsg.c + $(COMPILE.c) -c capmsg.c $(INCLUDES) + +crd.o:crd.c + $(COMPILE.c) -c crd.c $(INCLUDES) + +dailyreport.o:dailyreport.c + $(COMPILE.c) -c dailyreport.c $(INCLUDES) + +loadtl.o:loadtl.c + $(COMPILE.c) -c loadtl.c $(INCLUDES) + +message.o:message.c + $(COMPILE.c) -c message.c $(INCLUDES) + +mfunc.o:mfunc.c + $(COMPILE.c) -c mfunc.c $(INCLUDES) + +ppsmap.o:ppsmap.c + $(COMPILE.c) -c ppsmap.c $(INCLUDES) + +ppsMibTable.o:ppsMibTable.c + $(COMPILE.c) -c ppsMibTable.c $(INCLUDES) + +ppsmib.o:ppsmib.c + $(COMPILE.c) -c ppsmib.c $(INCLUDES) + +ppsfunc.o:ppsfunc.c + $(COMPILE.c) -c ppsfunc.c $(INCLUDES) + +ppsm.o:ppsm.c + $(COMPILE.c) -c ppsm.c $(INCLUDES) + +precard.o:precard.c + $(COMPILE.c) -c precard.c $(INCLUDES) + +rammng.o:rammng.c + $(COMPILE.c) -c rammng.c $(INCLUDES) + +smppapi.o:smppapi.c + $(COMPILE.c) -c smppapi.c $(INCLUDES) + +ppsussd.o:ppsussd.c + $(COMPILE.c) -c ppsussd.c $(INCLUDES) + +callingCardMsg.o:callingCardMsg.c + $(COMPILE.c) -c callingCardMsg.c $(INCLUDES) + +callingCardState.o:callingCardState.c + $(COMPILE.c) -c callingCardState.c $(INCLUDES) + + +tariffApplication.o:tariffApplication.c + $(COMPILE.c) -c tariffApplication.c $(INCLUDES) + +callMeBack.o:callMeBack.c + $(COMPILE.c) -c callMeBack.c $(INCLUDES) + +freeSMS.o:freeSMS.c + $(COMPILE.c) -c freeSMS.c $(INCLUDES) + +feeTransfer.o:feeTransfer.c + $(COMPILE.c) -c feeTransfer.c $(INCLUDES) + +masterSlaveCard.o:masterSlaveCard.c + $(COMPILE.c) -c masterSlaveCard.c $(INCLUDES) +radius.o:radius.c + $(COMPILE.c) -c radius.c $(INCLUDES) +gprs.o:gprs.c + $(COMPILE.c) -c gprs.c $(INCLUDES) +vas.o:vas.c + $(COMPILE.c) -c vas.c $(INCLUDES) +restapi.o:restapi.c + $(COMPILE.c) -c restapi.c $(INCLUDES) +ocs_user_table.o:ocs_user_table.c + $(COMPILE.c) -c ocs_user_table.c $(INCLUDES) +pps_redis.o:pps_redis.c + $(COMPILE.c) -c pps_redis.c $(INCLUDES) +clean: + rm -f *.c~ *.o core ppsm *.c.bak + diff --git a/mss/pps/src/main/Rdb_Makefile b/mss/pps/src/main/Rdb_Makefile new file mode 100644 index 0000000..a29b1b8 --- /dev/null +++ b/mss/pps/src/main/Rdb_Makefile @@ -0,0 +1,163 @@ +# !/bin/sh +# Makefile for heart beating processor +# Created by Huang QL, 2000/12/26 +#If you want to include which Module,Set the INC_XXX=$(INC_TRUE), +#or set it to $(INC_FALSE),then run the command: make alt +INC_TRUE=1 +INC_FALSE=0 + +CC = gcc +CFLAGS=-D_REENTRANT -DOCS_USE_REDIS_DB -Wall -Wno-unused-function -g +CFLAGS_IN=-D_REENTRANT -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include + +#-O2 +prefix = /usr +includedir = $(prefix)/include +libdir = $(prefix)/lib +localinclude = ../include +platLIBPREFIX =../../../wxc2plat +INC_FLAGS = -I$(includedir) +INCLUDES = -I../include + +XAPPLIB_FLAGS = -L$(platLIBPREFIX)/xapp +XAPPLD_LIBRARY = -lxapp +TCAPLIB_FLAGS = -L$(platLIBPREFIX)/tcap +TCAPLD_LIBRARY = -ltcap +SCCPLIB_FLAGS = -L$(platLIBPREFIX)/sccp +SCCPLD_LIBRARY = -lsccp +MTP3LIB_FLAGS = -L$(platLIBPREFIX)/mtp3 -lcurses +MTP3LD_LIBRARY = -lmtp3 +PUBLICLIB_FLAGS = -L$(platLIBPREFIX)/public +PUBLICLD_LIBRARY = -lpublic +DEBUGLIB_FLAGS = -L$(platLIBPREFIX)/debug +DEBUGLD_LIBRARY = -ldebug +SNMPLIB_FLAGS_I = -L$(platLIBPREFIX)/snmp +SNMPLD_LIBRARY_I = -lsnmp +SMPPLIB_FLAGS = -L$(platLIBPREFIX)/smppold +SMPPLD_LIBRARY = -lsmpp +IPTRANS_FLAGS = -L$(platLIBPREFIX)/iptrans +IPTRANS_LIBRARY = -liptrans +SCF_FLAGS = -L$(platLIBPREFIX)/scf +SCF_LIBRARY = -lscf +PPS_FLAGS = -L ../../OPR/lib +PPS_LIBRARY = -lopr + + + +STATIC= + +COMPILE.c=$(CC) $(CFLAGS) $(CFLAGS_IN) +LINK.c=$(CC) $(CFLAGS) + +COMPILE_SUFFIX=$(STATIC) $(INC_FLAGS) + +LINK_SUFFIX= $(INC_FLAGS) \ +$(PUBLICLIB_FLAGS) $(PUBLICLD_LIBRARY) \ +$(SNMPLIB_FLAGS_I) $(SNMPLD_LIBRARY_I) \ +$(XAPPLIB_FLAGS) $(XAPPLD_LIBRARY) \ +$(TCAPLIB_FLAGS) $(TCAPLD_LIBRARY) \ +$(SCCPLIB_FLAGS) $(SCCPLD_LIBRARY) \ +$(MTP3LIB_FLAGS) $(MTP3LD_LIBRARY) \ +$(DEBUGLIB_FLAGS) $(DEBUGLD_LIBRARY) \ +$(SMPPLIB_FLAGS) $(SMPPLD_LIBRARY) \ +$(IPTRANS_FLAGS) $(IPTRANS_LIBRARY) \ +$(SCF_FLAGS) $(SCF_LIBRARY)\ +$(PPS_FLAGS) $(PPS_LIBRARY) + +PROGS=ppsm + +#pps_OBJ = ppsmain.o capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o ppsopr.o callingCardMsg.o callingCardState.o + +pps_OBJ = capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o callingCardMsg.o callingCardState.o tariffApplication.o callMeBack.o freeSMS.o feeTransfer.o masterSlaveCard.o radius.o gprs.o vas.o restapi.o ocs_user_table.o pps_redis.o +all:$(PROGS) +#$(pps_OBJ) +# executive file +ppsm:$(pps_OBJ) + @echo Linking $@ + @echo $(LINK_SUFFIX) +# @$(LINK.c) -o $(PROGS) $(pps_OBJ) $(LINK_SUFFIX) -L../lib/ -lppsfuns -ldl -lz -lpopt -lncurses -lm + +# obj files +#ppsmain.o:ppsmain.c +# $(COMPILE.c) -c ppsmain.c $(INCLUDES) +capmsg.o:capmsg.c + $(COMPILE.c) -c capmsg.c $(INCLUDES) + +crd.o:crd.c + $(COMPILE.c) -c crd.c $(INCLUDES) + +dailyreport.o:dailyreport.c + $(COMPILE.c) -c dailyreport.c $(INCLUDES) + +loadtl.o:loadtl.c + $(COMPILE.c) -c loadtl.c $(INCLUDES) + +message.o:message.c + $(COMPILE.c) -c message.c $(INCLUDES) + +mfunc.o:mfunc.c + $(COMPILE.c) -c mfunc.c $(INCLUDES) + +ppsmap.o:ppsmap.c + $(COMPILE.c) -c ppsmap.c $(INCLUDES) + +ppsMibTable.o:ppsMibTable.c + $(COMPILE.c) -c ppsMibTable.c $(INCLUDES) + +ppsmib.o:ppsmib.c + $(COMPILE.c) -c ppsmib.c $(INCLUDES) + +ppsfunc.o:ppsfunc.c + $(COMPILE.c) -c ppsfunc.c $(INCLUDES) + +ppsm.o:ppsm.c + $(COMPILE.c) -c ppsm.c $(INCLUDES) + +precard.o:precard.c + $(COMPILE.c) -c precard.c $(INCLUDES) + +rammng.o:rammng.c + $(COMPILE.c) -c rammng.c $(INCLUDES) + +smppapi.o:smppapi.c + $(COMPILE.c) -c smppapi.c $(INCLUDES) + +ppsussd.o:ppsussd.c + $(COMPILE.c) -c ppsussd.c $(INCLUDES) + +callingCardMsg.o:callingCardMsg.c + $(COMPILE.c) -c callingCardMsg.c $(INCLUDES) + +callingCardState.o:callingCardState.c + $(COMPILE.c) -c callingCardState.c $(INCLUDES) + + +tariffApplication.o:tariffApplication.c + $(COMPILE.c) -c tariffApplication.c $(INCLUDES) + +callMeBack.o:callMeBack.c + $(COMPILE.c) -c callMeBack.c $(INCLUDES) + +freeSMS.o:freeSMS.c + $(COMPILE.c) -c freeSMS.c $(INCLUDES) + +feeTransfer.o:feeTransfer.c + $(COMPILE.c) -c feeTransfer.c $(INCLUDES) + +masterSlaveCard.o:masterSlaveCard.c + $(COMPILE.c) -c masterSlaveCard.c $(INCLUDES) +radius.o:radius.c + $(COMPILE.c) -c radius.c $(INCLUDES) +gprs.o:gprs.c + $(COMPILE.c) -c gprs.c $(INCLUDES) +vas.o:vas.c + $(COMPILE.c) -c vas.c $(INCLUDES) +restapi.o:restapi.c + $(COMPILE.c) -c restapi.c $(INCLUDES) +ocs_user_table.o:ocs_user_table.c + $(COMPILE.c) -c ocs_user_table.c $(INCLUDES) +pps_redis.o:pps_redis.c + $(COMPILE.c) -c pps_redis.c $(INCLUDES) +clean: + rm -f *.c~ *.o core ppsm *.c.bak + diff --git a/mss/pps/src/main/Zed_Makefile b/mss/pps/src/main/Zed_Makefile new file mode 100644 index 0000000..3abaecd --- /dev/null +++ b/mss/pps/src/main/Zed_Makefile @@ -0,0 +1,163 @@ +# !/bin/sh +# Makefile for heart beating processor +# Created by Huang QL, 2000/12/26 +#If you want to include which Module,Set the INC_XXX=$(INC_TRUE), +#or set it to $(INC_FALSE),then run the command: make alt +INC_TRUE=1 +INC_FALSE=0 + +CC = gcc +CFLAGS=-D_REENTRANT -D_ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ -Wall -Wno-unused-function -g +CFLAGS_IN=-D_REENTRANT -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include + +#-O2 +prefix = /usr +includedir = $(prefix)/include +libdir = $(prefix)/lib +localinclude = ../include +platLIBPREFIX =../../../wxc2plat +INC_FLAGS = -I$(includedir) +INCLUDES = -I../include + +XAPPLIB_FLAGS = -L$(platLIBPREFIX)/xapp +XAPPLD_LIBRARY = -lxapp +TCAPLIB_FLAGS = -L$(platLIBPREFIX)/tcap +TCAPLD_LIBRARY = -ltcap +SCCPLIB_FLAGS = -L$(platLIBPREFIX)/sccp +SCCPLD_LIBRARY = -lsccp +MTP3LIB_FLAGS = -L$(platLIBPREFIX)/mtp3 -lcurses +MTP3LD_LIBRARY = -lmtp3 +PUBLICLIB_FLAGS = -L$(platLIBPREFIX)/public +PUBLICLD_LIBRARY = -lpublic +DEBUGLIB_FLAGS = -L$(platLIBPREFIX)/debug +DEBUGLD_LIBRARY = -ldebug +SNMPLIB_FLAGS_I = -L$(platLIBPREFIX)/snmp +SNMPLD_LIBRARY_I = -lsnmp +SMPPLIB_FLAGS = -L$(platLIBPREFIX)/smppold +SMPPLD_LIBRARY = -lsmpp +IPTRANS_FLAGS = -L$(platLIBPREFIX)/iptrans +IPTRANS_LIBRARY = -liptrans +SCF_FLAGS = -L$(platLIBPREFIX)/scf +SCF_LIBRARY = -lscf +PPS_FLAGS = -L ../../OPR/lib +PPS_LIBRARY = -lopr + + + +STATIC= + +COMPILE.c=$(CC) $(CFLAGS) $(CFLAGS_IN) +LINK.c=$(CC) $(CFLAGS) + +COMPILE_SUFFIX=$(STATIC) $(INC_FLAGS) + +LINK_SUFFIX= $(INC_FLAGS) \ +$(PUBLICLIB_FLAGS) $(PUBLICLD_LIBRARY) \ +$(SNMPLIB_FLAGS_I) $(SNMPLD_LIBRARY_I) \ +$(XAPPLIB_FLAGS) $(XAPPLD_LIBRARY) \ +$(TCAPLIB_FLAGS) $(TCAPLD_LIBRARY) \ +$(SCCPLIB_FLAGS) $(SCCPLD_LIBRARY) \ +$(MTP3LIB_FLAGS) $(MTP3LD_LIBRARY) \ +$(DEBUGLIB_FLAGS) $(DEBUGLD_LIBRARY) \ +$(SMPPLIB_FLAGS) $(SMPPLD_LIBRARY) \ +$(IPTRANS_FLAGS) $(IPTRANS_LIBRARY) \ +$(SCF_FLAGS) $(SCF_LIBRARY)\ +$(PPS_FLAGS) $(PPS_LIBRARY) + +PROGS=ppsm + +#pps_OBJ = ppsmain.o capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o ppsopr.o callingCardMsg.o callingCardState.o + +pps_OBJ = capmsg.o dailyreport.o loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o ppsfunc.o ppsm.o precard.o rammng.o smppapi.o crd.o ppsmap.o ppsussd.o callingCardMsg.o callingCardState.o tariffApplication.o callMeBack.o freeSMS.o feeTransfer.o masterSlaveCard.o radius.o gprs.o vas.o restapi.o ocs_user_table.o pps_redis.o +all:$(PROGS) +#$(pps_OBJ) +# executive file +ppsm:$(pps_OBJ) + @echo Linking $@ + @echo $(LINK_SUFFIX) +# @$(LINK.c) -o $(PROGS) $(pps_OBJ) $(LINK_SUFFIX) -L../lib/ -lppsfuns -ldl -lz -lpopt -lncurses -lm + +# obj files +#ppsmain.o:ppsmain.c +# $(COMPILE.c) -c ppsmain.c $(INCLUDES) +capmsg.o:capmsg.c + $(COMPILE.c) -c capmsg.c $(INCLUDES) + +crd.o:crd.c + $(COMPILE.c) -c crd.c $(INCLUDES) + +dailyreport.o:dailyreport.c + $(COMPILE.c) -c dailyreport.c $(INCLUDES) + +loadtl.o:loadtl.c + $(COMPILE.c) -c loadtl.c $(INCLUDES) + +message.o:message.c + $(COMPILE.c) -c message.c $(INCLUDES) + +mfunc.o:mfunc.c + $(COMPILE.c) -c mfunc.c $(INCLUDES) + +ppsmap.o:ppsmap.c + $(COMPILE.c) -c ppsmap.c $(INCLUDES) + +ppsMibTable.o:ppsMibTable.c + $(COMPILE.c) -c ppsMibTable.c $(INCLUDES) + +ppsmib.o:ppsmib.c + $(COMPILE.c) -c ppsmib.c $(INCLUDES) + +ppsfunc.o:ppsfunc.c + $(COMPILE.c) -c ppsfunc.c $(INCLUDES) + +ppsm.o:ppsm.c + $(COMPILE.c) -c ppsm.c $(INCLUDES) + +precard.o:precard.c + $(COMPILE.c) -c precard.c $(INCLUDES) + +rammng.o:rammng.c + $(COMPILE.c) -c rammng.c $(INCLUDES) + +smppapi.o:smppapi.c + $(COMPILE.c) -c smppapi.c $(INCLUDES) + +ppsussd.o:ppsussd.c + $(COMPILE.c) -c ppsussd.c $(INCLUDES) + +callingCardMsg.o:callingCardMsg.c + $(COMPILE.c) -c callingCardMsg.c $(INCLUDES) + +callingCardState.o:callingCardState.c + $(COMPILE.c) -c callingCardState.c $(INCLUDES) + + +tariffApplication.o:tariffApplication.c + $(COMPILE.c) -c tariffApplication.c $(INCLUDES) + +callMeBack.o:callMeBack.c + $(COMPILE.c) -c callMeBack.c $(INCLUDES) + +freeSMS.o:freeSMS.c + $(COMPILE.c) -c freeSMS.c $(INCLUDES) + +feeTransfer.o:feeTransfer.c + $(COMPILE.c) -c feeTransfer.c $(INCLUDES) + +masterSlaveCard.o:masterSlaveCard.c + $(COMPILE.c) -c masterSlaveCard.c $(INCLUDES) +radius.o:radius.c + $(COMPILE.c) -c radius.c $(INCLUDES) +gprs.o:gprs.c + $(COMPILE.c) -c gprs.c $(INCLUDES) +vas.o:vas.c + $(COMPILE.c) -c vas.c $(INCLUDES) +restapi.o:restapi.c + $(COMPILE.c) -c restapi.c $(INCLUDES) +ocs_user_table.o:ocs_user_table.c + $(COMPILE.c) -c ocs_user_table.c $(INCLUDES) +pps_redis.o:pps_redis.c + $(COMPILE.c) -c pps_redis.c $(INCLUDES) +clean: + rm -f *.c~ *.o core ppsm *.c.bak + diff --git a/mss/pps/src/main/callMeBack.c b/mss/pps/src/main/callMeBack.c new file mode 100644 index 0000000..492b973 --- /dev/null +++ b/mss/pps/src/main/callMeBack.c @@ -0,0 +1,508 @@ + +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + +#include "../include/plat_inc.h" + +#include "../include/ppsMibTable.h" +#include "../include/mfunc.h" + +extern int xappCheckIfLocalMSISDN(char *msisdn); + +extern PPSParamStruct ppsParam; +extern struct timeval tvnow; +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr;; + +extern int SendUSSDRequest(u_short portid, char *ussd_info); +extern int smppSendMsg(u_char *peerNumber,u_char *msg,u_char serviceNumPosition); +extern int SendPSSREnd(u_short portid, char *ussd_info); + + +static int SendCMBRequest(u_short portid,u8 ussdSmsFlag) +{ + char tmp[MAX_SMS_LEN*4]; + _state_data *shmp; + + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy(tmp, (char *)getSmsSentenceNative(0,SMS_CMB_PROMPT)); + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid,tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number, (u_char *)tmp,CallMeBackPosition); + break; + } + return 1; +} + + +static int SendCMBNotifyDestRequest(u_short portid,u8 ussdSmsFlag) +{ + //u_char tmpMsisdn[32],tmpMsisdn1[32]; + _state_data *shmp; + char dayTimeReadable[32]={0}, tmp[MAX_SMS_LEN*4]; + + if(portid>=MAX_FSM_PROCESS) return 0; + + ppsgetdaytime_readFormat(dayTimeReadable); + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + cliManipulationFunction((char *)shmp->caller_info.number, (char *)shmp->process_info.ppsService.callMeBack.destNumber); + strcpy(tmp, (char *)shmp->caller_info.number); + + strcat(tmp, (char *)getSmsSentenceNative(0,SMS_CMB_NOTIFY)); + sprintf(tmp+strlen(tmp)," %s %s ", (char *)getSmsSentenceNative(0,SMS_ON), dayTimeReadable); + strcat(tmp, (char *)getSmsSentenceNative(0,SMS_CMB_AD)); + smppSendMOSM((char *)shmp->process_info.ppsService.callMeBack.destNumber, + (char *)shmp->caller_info.number, + (u_char *)tmp, + strlen(tmp), + 0 + ); + return 1; +} + +static int SendReinputCMBRequest(u_short portid,u8 ussdSmsFlag) +{ + char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy(tmp, (char *)getSmsSentenceNative(0,SMS_FORMAT_ERROR)); + strcat(tmp, (char *)getSmsSentenceNative(0,SMS_CMB_PROMPT)); + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid,tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number, (u_char *)tmp,CallMeBackPosition); + break; + } + return 1; +} + +static int SendCMBDstNumberErrorRequest(u_short portid,u8 ussdSmsFlag) +{ + char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy(tmp, (char *)getSmsSentenceNative(0,SMS_INVALID_NUMBER)); + strcat(tmp, (char *)getSmsSentenceNative(0,SMS_CMB_PROMPT)); + + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid,tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number, (u_char *)tmp,CallMeBackPosition); + break; + } + return 1; +} + +static int SendCMBLimited(u_short portid,u8 ussdSmsFlag) +{ + char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy(tmp, (char *)getSmsSentenceNative(0,SMS_CMB_REACH_MAX_LIMIT)); + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendPSSREnd(portid,tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number, (u_char *)tmp,CallMeBackPosition); + break; + } + return 1; +} + +static int getCMBInfo(u_short portid,u_char *ussd_data) +{/* format:number*amount */ + _state_data *shmp; + u8 i,len; + + PutLogFunID("getTransferInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + len = strlen((char *)ussd_data); + if(len <= 0) + return -1; + for(i = 0;i < len;i++) + {/* only '0' - '9' are allowed */ + if(ussd_data[i] < '0' || ussd_data[i] > '9') + return -1; + } + + CutUnknownPrefix((char *)ussd_data); + if(strlen((char *)ussd_data)>MAX_ASCII_NUMBER_LEN) + return -1; + + if(!strcmp((char *)shmp->caller_info.number, (char *)ussd_data)) + { + return -2; + } + strcpy((char *)shmp->process_info.ppsService.callMeBack.destNumber, (char *)ussd_data); + return 1; +} + +#define changeCMBState(portid,val) do { \ + callMeBack = &shmp->process_info.ppsService.callMeBack;\ + callMeBack->state = val; \ + shmp->process_info.serviceInput = 0;\ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + +static u8 getCMBState(u_short portid) +{ + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + return shmp->process_info.ppsService.callMeBack.state; +} + +void clearCMBInfo(u_short portid) +{ + _state_data *shmp; + + PutLogFunID("clearTransferInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + memset(&shmp->process_info.ppsService.callMeBack,0,sizeof(CMB)); +} + +static BOOL checkIfLocalNumber(u_char *number) +{ + if(xappCheckIfLocalMSISDN((char *)number) == 1) + return TRUE; + return FALSE; +} + +static BOOL checkCMBDestNumber(u_short portid) +{ + _state_data *shmp; + _account_info account; + + PutLogFunID("clearTransferInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)account.number, (char *)shmp->process_info.ppsService.callMeBack.destNumber); + return checkIfLocalNumber(account.number); +} + + +int saveCMBSMSACK(u_short portid,u_char *sms) +{ + _state_data *shmp; + u8 len; + + PutLogFunID("saveSMSACK"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + len = strlen((char *)sms) % MAX_INPUT_SMS; + + memcpy(shmp->process_info.ppsService.callMeBack.inputSMS,sms,len); + shmp->process_info.ppsService.callMeBack.inputSMS[len] = 0; + shmp->process_info.ppsService.callMeBack.smsTrigger = TRUE; + return len; +} + + +static int getCMBSMSACK(u_short portid,u_char *sms) +{ + _state_data *shmp; + + PutLogFunID("getSMSACK"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.ppsService.callMeBack.smsTrigger == FALSE) + return 0; + + shmp->process_info.ppsService.callMeBack.smsTrigger = FALSE; + strcpy((char *)sms, (char *)shmp->process_info.ppsService.callMeBack.inputSMS); + return strlen((char *)sms); +} + +extern BOOL isPrepaidUser(_account_info *ptr); +static int isCMBAllowed(u_short portid) +{ + _state_data *shmp; + COSTable *cosTableItem; + int cosID=0,cmbTimes; + BOOL balanceExpired=FALSE,promotionExpired=FALSE; + float balance = 0; + + PutLogFunID("isCMBAllowed"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(isPrepaidUser(&shmp->caller_info) == TRUE) + cosID = GetLocalCosID(&shmp->caller_info); + else + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]postpaid user %s ,cmb fail",portid,shmp->caller_info.number); + return 1; + } + + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + + if(cosTableItem->serviceControl[0].callMeBackMaxTimes > 0) + { + cmbTimes = GetCMBTimes(&shmp->caller_info); + if(cmbTimes >= cosTableItem->serviceControl[0].callMeBackMaxTimes) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]user %s reach max call me back times",portid,shmp->caller_info.number); + return 2; + } + } + + if(GetExpiration(&shmp->caller_info) <= tvnow.tv_sec) + { + balanceExpired = TRUE; + } + else + balance += GetBalanceWithOutPromotion(shmp->caller_info.head,shmp->caller_info.tail); + if(GetPromotionExpiration(&shmp->caller_info) <= tvnow.tv_sec) + promotionExpired = TRUE; + else + balance += GetPromotion(&shmp->caller_info); + + if(balanceExpired && promotionExpired) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]user %s account expired",portid,shmp->caller_info.number); + return 3; + } + balance += GetOverdraft(&shmp->caller_info); + + if(cosTableItem->serviceControl[0].callMeBackThreshold>0 && + balance > cosTableItem->serviceControl[0].callMeBackThreshold) + return 4; + return 0; +} + +enum CMB_STATE{ + S_CMB_IDLE = 0, + S_WART_INPUT_DESTNUMBER, + S_CMB_CHECK_DSTNUMBER, + S_CMB_PROCESSING, + S_CMB_EXIT, +}; + +int callMebackUSSDProc(u_short portid) +{ + _state_data *shmp; + u_char ussd_data[256]={0}; + int result = 0; + CMB *callMeBack; + + PutLogFunID("callMebackUSSDProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(getCMBState(portid)) + { + case S_CMB_IDLE: + result = isCMBAllowed(portid); + if(result != 0) + { + switch(result) + { + case 2: + SendCMBLimited(portid,USSD_TRANSFER); + break; + default: + //SendServiceNotApplied(portid,USSD_TRANSFER,CallMeBackPosition); + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + break; + } + changeCMBState(portid,S_CMB_EXIT); + break; + } + clearCMBInfo(portid); + SendCMBRequest(portid,USSD_TRANSFER); + changeCMBState(portid,S_WART_INPUT_DESTNUMBER); + break; + case S_WART_INPUT_DESTNUMBER: + result = getUssdACK(portid,ussd_data); + switch(result) + { + case 0: + break; + case -1: + return SERVICE_EXIT_PPS; + break; + default: + ussd_data[result] = 0; + result = getCMBInfo(portid,ussd_data); + switch(result) + { + case -1: + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + return SERVICE_EXIT_PPS; + SendReinputCMBRequest(portid,USSD_TRANSFER); + break; + case -2: + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + return SERVICE_EXIT_PPS; + SendCMBDstNumberErrorRequest(portid,USSD_TRANSFER); + break; + default: + changeCMBState(portid,S_CMB_CHECK_DSTNUMBER); + break; + } + break; + } + break; + case S_CMB_CHECK_DSTNUMBER: + if(checkCMBDestNumber(portid) == FALSE) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return SERVICE_EXIT_PPS; + } + SendCMBDstNumberErrorRequest(portid,USSD_TRANSFER); + changeCMBState(portid,S_WART_INPUT_DESTNUMBER); + } + else + changeCMBState(portid,S_CMB_PROCESSING); + break; + case S_CMB_PROCESSING: + UpdateCMBTimes(&shmp->caller_info,1); + SendCMBNotifyDestRequest(portid,SMS_TRANSFER); + changeCMBState(portid,S_CMB_EXIT); + break; + case S_CMB_EXIT: + clearCMBInfo(portid); + return SERVICE_EXIT_PPS; + break; + } + return SERVICE_KEEP_STATE; +} + +int callMebackSMSProc(u_short portid) +{ + _state_data *shmp; + u_char short_message[256]; + int result = 0; + CMB *callMeBack; + + PutLogFunID("callMebackSMSProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(getCMBState(portid)) + { + case S_CMB_IDLE: + result = isCMBAllowed(portid); + if(result != 0) + { + switch(result) + { + case 2: + SendCMBLimited(portid,SMS_TRANSFER); + break; + default: + SendServiceNotApplied(portid,SMS_TRANSFER,CallMeBackPosition); + break; + } + clearCMBInfo(portid); + return SERVICE_RETURN_TO_PARENT; + } + changeCMBState(portid,S_WART_INPUT_DESTNUMBER); + case S_WART_INPUT_DESTNUMBER: + result = getCMBSMSACK(portid,short_message); + switch(result) + { + case 0: + break; + case -1: + return SERVICE_EXIT_PPS; + break; + default: + short_message[result] = 0; + result = getCMBInfo(portid,short_message); + switch(result) + { + case -1: + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + return SERVICE_EXIT_PPS; + SendReinputCMBRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + case -2: + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + return SERVICE_EXIT_PPS; + SendCMBDstNumberErrorRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + default: + changeCMBState(portid,S_CMB_CHECK_DSTNUMBER); + break; + } + break; + } + case S_CMB_CHECK_DSTNUMBER: + if(checkCMBDestNumber(portid) == FALSE) + { + SendCMBDstNumberErrorRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + } + else + changeCMBState(portid,S_CMB_PROCESSING); + case S_CMB_PROCESSING: + UpdateCMBTimes(&shmp->caller_info,1); + SendCMBNotifyDestRequest(portid,SMS_TRANSFER); + changeCMBState(portid,S_CMB_EXIT); + case S_CMB_EXIT: + clearCMBInfo(portid); + return SERVICE_RETURN_TO_PARENT; + break; + } + return SERVICE_KEEP_STATE; +} + + + diff --git a/mss/pps/src/main/callingCardMsg.c b/mss/pps/src/main/callingCardMsg.c new file mode 100644 index 0000000..031f845 --- /dev/null +++ b/mss/pps/src/main/callingCardMsg.c @@ -0,0 +1,849 @@ + +#include "../include/includes.h" +#include "../include/message.h" +#include "../include/ppsm.h" +#include "../include/cdrme.h" +#include "../include/ramdata.h" +#include "../include/mfunc.h" +#include "../include/config.h" +#include "../include/param.h" +#include "../include/precard.h" +#include "../include/callingCard.h" + +#include "../include/plat_inc.h" +#include "../../../../plat/scf/src/include/scfpub.h" +#include "../../../../plat/scf/src/include/scfmsg.h" + +extern u_short debug_messages; +extern int logMsgFlag; +extern int ppsDebugCapMsg(); +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr; +extern int SendAccountInfoBySMPP(); + +extern PPSParamStruct ppsParam; + + +extern int CheckPINValidity(_account_info *ptr, char *pin); +extern void SendAccountBalanceBySrf(u_short portid); +extern int WaitingForRechargeCardPasswordResponse(u_short portid); +extern int RechargeRequestProc(u_short portid); + +int CallingCardSendReleaseCall(u_short portid); + +/* need change _crd_param struct*/ +int IsCallingCardNumber(u_char *dstNumber) +{ + int retval=0; + int len; + u_char *callingNumber; + + callingNumber = ppsParam.ppsTables.serviceNumber[VirtualCallingCardNumberPosition].number; + + if(callingNumber[0] == 0) return 0; + len = strlen((char *)callingNumber); + if(!strncasecmp((char *)dstNumber, (char *)callingNumber, len)) + retval = 1; + + return retval; +} + +int WaitForMainMenu(_state_data *shmp,u_short portid) +{ + int key = -1,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + PutLogFunID("WaitForMainMenu"); + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + shmp->process_info.tcos = CALLER_EXPIRIED; + CallingCardSendReleaseCall(portid); + return pin_mng_exit; + } + + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + { + return key; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return key; + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return -1; + + key = pPCUI->digitsResponse[2]; + /* + key = pPCUI->digitsResponse[2]&0x0F; + + if((key < ExitCallingCard) ||(key > TransferAccount)) + { + return -1; + } + */ + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + break; + } + return key; +} + +int WaitingForPin(_state_data *shmp,u8 type) +{ + /* + type 0:caller + 1:called + */ + int retval=pin_mng_keep_state,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + _account_info *call_type; + + PutLogFunID("WaitingForInputCallingCardAccountResponse"); + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = pin_mng_exit); //timeout ,exit + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = pin_mng_exit); //timeout ,exit + len --; + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len+1] |= 0xF0; + len =len * 2-1; + } + else + len *=2; + if( len != MAX_PIN_LEN) //max language types = 5 + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = pin_mng_exit); + } + return retval = 2; + } + ppsBcdToAsciiR(shmp->process_info.tmpDigits, + &pPCUI->digitsResponse[2], + len); + shmp->process_info.tmpDigits[MAX_PIN_LEN] = 0; + if(type == 0) + call_type = &shmp->caller_info; + else + call_type = &shmp->called_info; + + if(!CheckPINValidity(call_type,shmp->process_info.tmpDigits)) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = pin_mng_exit); + } + return retval = 2; + } + retval = 1; + break; + } + return retval; +} + +int WaitingForInputCallingCardAccountResponse(_state_data *shmp) +{ + int retval=pin_mng_keep_state,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + PutLogFunID("WaitingForInputCallingCardAccountResponse"); + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len>11) len = 11; + if(len<=2) // + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + memset(shmp->cdr_info.msisdn,0xFF,10); + memcpy(shmp->cdr_info.msisdn, + &pPCUI->digitsResponse[2], + len-1); + ppsBcdToAsciiR((char *)shmp->caller_info.number,&pPCUI->digitsResponse[2],2*(len-1)); + StringCut((char *)shmp->caller_info.number,'F'); + if(GetAccountPos(&shmp->caller_info) == FALSE) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + shmp->caller_info.status = GetAccountStatus(&shmp->caller_info); + GetAccountCosID(&shmp->caller_info); + retval = 1; + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 3; + break; + } + return retval; +} + +int WaitingForInputCallingCardAccountResponse_ccc(_state_data *shmp) +{ + int retval=pin_mng_keep_state,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + char card_hrn[32]; + + PutLogFunID("WaitingForInputCallingCardAccountResponse_ccc"); + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len>11) len = 11; + if(len<=2) // + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + + + len --; + + if(pPCUI->digitsResponse[1] & 0x80) + pPCUI->digitsResponse[len] |= 0xF0; + + memset(shmp->cdr_info.caller, 0xFF, 10); + memcpy(shmp->cdr_info.caller, &pPCUI->digitsResponse[2], len); + ppsBcdToAsciiR(card_hrn, &pPCUI->digitsResponse[2], len*2); + + strcpy((char *)shmp->caller_info.number, card_hrn); + + if(1) + { + int result; + if(RechargeCardRequest(shmp->process_info.portid, card_hrn, &result) != 1) + retval = 2; + else + { + UpdateRechargeCard(shmp->process_info.portid, CARD_AS_CC_USED); + retval = 1; + } + } + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 3; + break; + } + return retval; +} + +int WaitingForInputCalledNumber(_state_data *shmp) +{ + int retval=pin_mng_keep_state,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + _state_data *callOutShmp; + + PutLogFunID("WaitingForInputCalledNumber"); + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len>11) len = 11; + if(len<=2) // + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + + dlgid = shmp->process_info.correlationID; + callOutShmp = (_state_data *)&smshm_ptr->state_data; + callOutShmp += dlgid; + callOutShmp->context_info.callType = CT_MO_CALL; + memset(callOutShmp->cdr_info.msisdn,0xFF,10); + memcpy(callOutShmp->cdr_info.msisdn, + &pPCUI->digitsResponse[2], + len-1); + ppsBcdToAsciiR((char *)callOutShmp->charge_info.number,&pPCUI->digitsResponse[2],2*(len-1)); + StringCut((char *)callOutShmp->charge_info.number,'F'); + retval = 1; + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 3; + break; + } + return retval; +} + + +int WaitingForInputTransferOutAccount_LIMITED(_state_data *shmp) +{ + int retval=pin_mng_keep_state,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + PutLogFunID("WaitingForInputTransferOutAccount"); + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len>11) len = 11; + if(len<=2) // + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + memset(shmp->cdr_info.msisdn,0xFF,10); + memcpy(shmp->cdr_info.msisdn, + &pPCUI->digitsResponse[2], + len-1); + ppsBcdToAsciiR((char *)shmp->called_info.number,&pPCUI->digitsResponse[2],2*(len-1)); + StringCut((char *)shmp->called_info.number,'F'); + if(GetAccountPos(&shmp->called_info) == FALSE) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + shmp->called_info.status = GetAccountStatus(&shmp->called_info); + GetAccountCosID(&shmp->called_info); + retval = 1; + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 3; + break; + } + return retval; +} + +int CallingCardWaitingForSpecialResourceReport(_state_data *shmp) +{ + int retval=pin_mng_keep_state,dlgid; + CAP_Message capmsg; + + PutLogFunID("WaitingForSpecialResourceReport"); + + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_SpecializedResourceReport: + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + retval = 1; + break; + default: + retval = 2; + } + return retval; +} + +int CallingCardInquiryManageProc(u_short portid) +{ + int retval,dlgid; + int caller_status,instance; + CAP_Message capmsg; + COSTable *cosTableItem; + _state_data *shmp; + + PutLogFunID("CallingCardInquiryManageProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = pin_mng_keep_state; + + switch(shmp->process_info.sub_state) + { + case S_INQ_SEND_PROMPT: + caller_status = GetAccountStatus(&shmp->caller_info); + if(caller_status == T_NORMAL) + { + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP( + &shmp->caller_info, + shmp->called_info.number); + } + + SendAccountInfoPromptToSrf(portid,FALSE,TRUE); + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0x01; + shmp->process_info.sub_state = S_INQ_SRR; + } + else + { + if((caller_status == T_FRESH || caller_status == T_OPRTRIAL) + && shmp->caller_info.headcaller_info.cos_id]; + if(cosTableItem->accountValidity[0].activiationByInquiryIs) + { + UpdateAccountStatus(shmp->caller_info.head, + shmp->caller_info.tail, + T_NORMAL); + UpdateAccountFirstUsedDate( + shmp->caller_info.head, + shmp->caller_info.tail); + UpdateExpirationFirstInquiry( + &shmp->caller_info, + cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance + ); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP( + &shmp->caller_info, + shmp->called_info.number); + } + + SendAccountInfoPromptToSrf(portid,FALSE,TRUE); + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0x01; + shmp->process_info.sub_state = S_INQ_SRR; + return retval; + } + } + else + { + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_INQ_SRR0; + } + } + break; + case S_INQ_SRR0: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + retval = pin_mng_exit_to_main_menu; + break; + case S_INQ_SRR: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + return (retval=pin_mng_exit_to_main_menu); + } + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + retval = pin_mng_exit_to_main_menu; + break; + default: + retval = pin_mng_exit_to_main_menu; + break; + } + + return retval; +} + +int CallingCardSendReleaseCall(u_short portid) +{ + _state_data *shmp,*shnmp; + + PutLogFunID("CallingCardSendReleaseCall"); + shmp = (_state_data *)&smshm_ptr->state_data; + shnmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + shnmp += shmp->process_info.correlationID; + shnmp->process_info.tcos = shmp->process_info.tcos; + shnmp->process_info.disconnectForwardConnection = 1; + return pin_mng_exit; +} + + +int CallingCardRechargeManageProc(u_short portid) +{ + int retval,retval1,dlgid; + int caller_status; + CAP_Message capmsg; + _state_data *shmp; + + PutLogFunID("CallingCardRechargeManageProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = pin_mng_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + CallingCardSendReleaseCall(portid); + return (retval = pin_mng_exit_to_main_menu); + } + + switch(shmp->process_info.sub_state) + { + case S_REC_CHECK_ACCOUNT_STATUS: + caller_status = GetAccountStatus(&shmp->caller_info); + if( caller_status != T_NORMAL && + caller_status != T_FRESH && + caller_status != T_SUSPEND && + caller_status != T_OPRTRIAL ) + { + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.srfRelease = 1; + SendSrfPlayAnnouncement(portid); + shmp->process_info.tcos = NORMAL_CLEARING; + shmp->process_info.sub_state = S_REC_WAIT_SRR; + return retval; + } + shmp->process_info.sub_state = S_REC_PLAY_BALANCE; + break; + break; + case S_REC_PLAY_BALANCE: + shmp->process_info.funnel = 0; + SendAccountInfoPromptToSrf(portid,TRUE,FALSE); + shmp->process_info.sub_state = S_REC_WAIT_SRR0; + break; + case S_REC_WAIT_SRR0: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + } + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + shmp->process_info.sub_state = S_REC_INPUT_PWD; + break; + case S_REC_INPUT_PWD: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = INPUT_PRECARD_PWD; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + shmp->process_info.maxPCUInfoLen = 20; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state = S_REC_CHECK_PWD; + break; + case S_REC_CHECK_PWD: + retval1 = WaitingForRechargeCardPasswordResponse(portid); + switch(retval1) + { + case 0: + break; + case 1: + RechargeRequestProc(portid); + shmp->process_info.srfRelease = 0; + shmp->process_info.maxPCUInfoLen = 1; + SendRechargeInfoPromptToSrf(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_REC_WAIT_SRR; + break; + case 2: + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = RECHARGE_FAILED; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_REC_CHECK_PWD; + break; + case 3: + retval = pin_mng_exit_to_main_menu; + break; + } + break; + case S_REC_WAIT_SRR: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + } + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + retval = pin_mng_exit_to_main_menu; + break; + } + return retval; +} diff --git a/mss/pps/src/main/callingCardState.c b/mss/pps/src/main/callingCardState.c new file mode 100644 index 0000000..a246940 --- /dev/null +++ b/mss/pps/src/main/callingCardState.c @@ -0,0 +1,1206 @@ + +#include "../include/includes.h" +#include "../include/message.h" +#include "../include/ppsm.h" +#include "../include/cdrme.h" +#include "../include/ramdata.h" +#include "../include/mfunc.h" +#include "../include/config.h" +#include "../include/param.h" +#include "../include/precard.h" +#include "../include/callingCard.h" +#include "../include/plat_inc.h" +#include "../../../../plat/scf/src/include/scfpub.h" +#include "../../../../plat/scf/src/include/scfmsg.h" + +extern _state_machine *smshm_ptr; + +/*------------------------------------------------*/ +extern int ppsDebugCapMsg(); +extern int decode_initialDP(); +extern int decode_initialDPSMS(); +extern int IsMNPCalledNumber(char *number); +extern char* GetCapError(); +extern void PpsHanldeOprProc(); +extern int ImportBillSMS(); +extern int SendScfTcEND(); +extern int UpdateBalanceForRecharge(); + + + + + +extern int SendAccountInfoBySMPP(); +extern int log_warning(); +extern int SendScfUError(); +extern int CheckPromotionLatchFlag(); +extern int sendConnectForCRDService(); +extern int CheckWetherRoamingUser(); +extern int GetAccountZoneIDByLocationInfo(); +extern int CheckWetherFavoriteNumber(); +extern int GetAccountMTZoneID(); +extern int CheckWetherRoamingMTUser(); +extern int GetAccountMTZoneIDByLocationInfo(); +extern int pps_send_map_open(); +extern int pps_send_mnp_ati(); +extern int pps_send_map_close(); +extern int pps_debug_map_msg(); +extern int SendConnectForVMSService(); +extern int SendPreWarningRequestBCSMEvent(); +extern int CheckSeriveIdentification(); +extern int CheckSRFResource(); +extern int SendEstablishTemporaryConnection(); + + +extern int SendAccountBalanceBySrf(); +extern int CheckPINValidity(); +extern int GetAccountFavoriteNumberCounter(); +extern int StoreAccountFavoriteNumber(); +extern int IncreaseFavoriteNumberChangeCounter(); +extern int BillingFavoriteNumberChange(); +extern int GetAccountFavoriteNumber(); +extern int SendFavPromptAndCollectUserInfo(); +extern int UpdateAccountDefaultLanguageType(); +extern int UpdateAccountPIN(); +extern int ppsMapState(); +extern int CreatePPSSubsIndexTable(); +extern int CreateQuenceList(); +extern int ReadSyncMessageForInit(); +extern int ppsDebugRt(); +extern int srfActivityMonitor(); +extern int CheckCRDRingBackServiceKey(int serviceKey); +/********************************************************/ +extern u_short debug_messages; +extern int logMsgFlag; +extern struct timeval tvnow; +extern unsigned short send_activitytest_timer; +extern PPSParamStruct ppsParam; +/******** from ppsm.c ******************/ +extern int InquiryManageProc(u_short portid); +extern int RechargeManageProc(u_short portid); +extern int PINManagementProc(u_short portid,u_char callingCardFlag); +extern int WaitingForRechargePIN(u_short portid); +/******** from ppsm.c ******************/ + +/******** from callingCardMsg.c ******************/ +int WaitForMainMenu(_state_data *shmp,u_short portid); +extern int WaitingForInputCallingCardAccountResponse(_state_data *shmp); +extern int WaitingForInputCalledNumber(_state_data *shmp); +extern int WaitingForInputTransferOutAccount(_state_data *shmp); +extern int WaitingForPin(_state_data *shmp,u8 type); +extern int CallingCardWaitingForSpecialResourceReport(_state_data *shmp); +extern int CallingCardInquiryManageProc(u_short portid); +extern int CallingCardSendReleaseCall(u_short portid); +extern int CallingCardRechargeManageProc(u_short portid); +/******** from callingCardMsg.c ******************/ + + + +static int entryCallingCardProc(u_short portid,_state_data *shmp) +{ + int result = pin_mng_keep_state,rst; + + PutLogFunID("entryCallingCardProc"); + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + shmp->process_info.tcos = CALLER_EXPIRIED; + CallingCardSendReleaseCall(portid); + return pin_mng_exit; + } + switch(shmp->process_info.sub_state_2) + { + case callingCardIdle: + shmp->process_info.sub_state_2 = inputCallingCardAccount; + //break; + case inputCallingCardAccount: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = PleaseInputCallingCardAccount; + shmp->process_info.endOfReplyDigit[0] = 1;/* length */ + shmp->process_info.endOfReplyDigit[1] = 12;/* # */ + shmp->process_info.maxPCUInfoLen = 20; /* max length */ + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = waitForCallingCardAccount; + break; + case waitForCallingCardAccount: + rst = WaitingForInputCallingCardAccountResponse(shmp); + switch(rst) + { + case 0: + break; + case 2: + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = InvalidAccountIputAgain; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + break; + case 1: + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state_2 = inputCallingCardAccountPassword; + break; + case 3: + result = pin_mng_exit; + break; + } + break; + case inputCallingCardAccountPassword: + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = INPUT_OLD_PIN; + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = checkCallingCardAccountPassword; + break; + case checkCallingCardAccountPassword: + rst = WaitingForPin(shmp,0); + switch(rst) + { + case 0: + break; + case 2: + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = ERROR_PIN; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + break; + case 1: + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state_2 = entrySuccess; + break; + case 3: + result = pin_mng_exit; + break; + } + break; + case entrySuccess: + result = entrySuccess; + shmp->process_info.sub_state_2 = callingCardIdle; + break; + default: + result = pin_mng_exit; + shmp->process_info.sub_state_2 = callingCardIdle; + break; + } + return result; +} + + +static int entryCallingCardProc_ccc(u_short portid,_state_data *shmp) +{ + int result = pin_mng_keep_state,rst; + + PutLogFunID("entryCallingCardProccc"); + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + shmp->process_info.tcos = CALLER_EXPIRIED; + CallingCardSendReleaseCall(portid); + return pin_mng_exit; + } + switch(shmp->process_info.sub_state_2) + { + case callingCardIdle: + shmp->process_info.sub_state_2 = inputCallingCardAccount; + shmp->process_info.ccc_flag = 1; + //break; + case inputCallingCardAccount: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = PleaseInputCallingCardAccount; + shmp->process_info.endOfReplyDigit[0] = 1;/* length */ + shmp->process_info.endOfReplyDigit[1] = 12;/* # */ + shmp->process_info.maxPCUInfoLen = 20; /* max length */ + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = waitForCallingCardAccount; + break; + case waitForCallingCardAccount: + rst = WaitingForInputCallingCardAccountResponse_ccc(shmp); + switch(rst) + { + case 0: + break; + case 2: + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = InvalidAccountIputAgain; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + break; + case 1: + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state_2 = entrySuccess; + break; + case 3: + result = pin_mng_exit; + break; + } + break; + break; + case entrySuccess: + result = entrySuccess; + shmp->process_info.sub_state_2 = callingCardIdle; + break; + default: + result = pin_mng_exit; + shmp->process_info.sub_state_2 = callingCardIdle; + break; + } + return result; +} + +static int makeCallProc(u_short portid,_state_data *shmp) +{ + int result = pin_mng_keep_state,rst,len; + _state_data *callOutShmp; + + PutLogFunID("makeCallProc"); + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + shmp->process_info.tcos = CALLER_EXPIRIED; + CallingCardSendReleaseCall(portid); + return pin_mng_exit; + } + switch(shmp->process_info.sub_state_2) + { + case callingCardIdle:/* here need to check :is balance enough to iniate a call? */ + shmp->process_info.sub_state_2 = requireInputCalledNumber; + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + break; + case requireInputCalledNumber: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = PleaseInputCalledNumber; + shmp->process_info.endOfReplyDigit[0] = 1;/* length */ + shmp->process_info.endOfReplyDigit[1] = 12;/* # */ + shmp->process_info.maxPCUInfoLen = 20; /* max length */ + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = waitForCalledNumber; + break; + case waitForCalledNumber: + rst = WaitingForInputCalledNumber(shmp); + switch(rst) + { + case 0: + break; + case 2: + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = InvalidCalledNumberInputAgain; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + break; + case 1: + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state_2 = requireRouteCalled; + break; + case 3: + result = pin_mng_exit; + break; + } + break; + case requireRouteCalled: + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = MakingCall; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = waitSpecialResourceReport; + break; + case waitSpecialResourceReport: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == pin_mng_keep_state) + break; + else if(rst == 1) + { + callOutShmp = (_state_data *)&smshm_ptr->state_data; + callOutShmp += shmp->process_info.correlationID; + callOutShmp->process_info.disconnectForwardConnection = 1; + callOutShmp->process_info.callingCardState = sendMainMenu; + callOutShmp->process_info.callingCardFunction = MakeCall; + len = strlen((char *)callOutShmp->charge_info.number); + memcpy(callOutShmp->process_info.tmpDigits,callOutShmp->charge_info.number,len); + len = sizeof(_account_info); + memcpy(&callOutShmp->called_info,&callOutShmp->charge_info,len); + memcpy(&callOutShmp->caller_info,&shmp->caller_info,len); + result = pin_mng_exit; + } + else + shmp->process_info.sub_state_2 = returnMainMenu; + break; + case returnMainMenu: + shmp->process_info.callingCardState = sendMainMenu; + break; + default: + result = pin_mng_exit; + break; + } + return result; +} + +static int inquiryBlanceProc(u_short portid,_state_data *shmp) +{ + int result= pin_mng_keep_state,rst; + + PutLogFunID("inquiryBlanceProc"); + switch(shmp->process_info.sub_state_2) + { + case callingCardIdle: + shmp->process_info.sub_state_2 = inquiryAccount; + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_INQ_SEND_PROMPT; + break; + case inquiryAccount: + rst = CallingCardInquiryManageProc(portid); + if(rst == pin_mng_exit_to_main_menu) + shmp->process_info.sub_state_2 = returnMainMenu; + break; + case returnMainMenu: + shmp->process_info.callingCardState = sendMainMenu; + break; + default: + result = pin_mng_exit; + break; + } + return result; +} + +static int rechargeAccoutProc(u_short portid,_state_data *shmp) +{ + int result = pin_mng_keep_state,rst; + + PutLogFunID("rechargeAccoutProc"); + switch(shmp->process_info.sub_state_2) + { + case callingCardIdle: + shmp->process_info.sub_state_2 = rechargeAccount; + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_REC_CHECK_ACCOUNT_STATUS; + break; + case rechargeAccount:/* use pps's function to recharge */ + rst = CallingCardRechargeManageProc(portid); + if(rst == pin_mng_exit_to_main_menu) + shmp->process_info.sub_state_2 = returnMainMenu; + break; + case returnMainMenu: + shmp->process_info.callingCardState = sendMainMenu; + break; + default: + result = pin_mng_exit; + break; + } + return result; +} + +enum changePasswordState +{ + passwordChange = 2 +}; +static int changePasswordProc(u_short portid,_state_data *shmp) +{ + int result = pin_mng_keep_state,rst; + + PutLogFunID("changePasswordProc"); + switch(shmp->process_info.sub_state_2) + { + case callingCardIdle: + shmp->process_info.sub_state_2 = passwordChange; + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_INPUT_OLD_PIN; + break; + case passwordChange: + rst = PINManagementProc(portid,1);/* use pps's password changing function */ + if(rst == pin_mng_exit_to_main_menu) + shmp->process_info.sub_state_2 = returnMainMenu; + break; + case returnMainMenu: + shmp->process_info.callingCardState = sendMainMenu; + break; + default: + result = pin_mng_exit; + break; + } + return result; +} + + +enum exitCallingCardState +{ + sendThankYou = 2, + waitPlayBye, + releaseResource +}; + +static int exitCallingCardProc(u_short portid,_state_data *shmp) +{ + int result = pin_mng_keep_state,dlgid; + CAP_Message capmsg; + + PutLogFunID("exitCallingCardProc"); + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + shmp->process_info.tcos = CALLER_EXPIRIED; + CallingCardSendReleaseCall(portid); + return pin_mng_exit; + } + switch(shmp->process_info.sub_state_2) + { + case callingCardIdle: + shmp->process_info.sub_state_2 = sendThankYou; + break; + case sendThankYou: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = ThankYouUseByeBye; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = waitPlayBye; + break; + case waitPlayBye: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return result; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + result = pin_mng_exit; + } + shmp->process_info.sub_state_2 = releaseResource; + break; + case releaseResource: + shmp->process_info.tcos = NORMAL_CLEARING; + CallingCardSendReleaseCall(portid); + result = pin_mng_exit; + break; + } + return result; +} + +int callingCardProc(u_short portid) +{ + int result,retval1 = pin_mng_keep_state,retval; + _state_data *shmp; + + + PutLogFunID("callingCardProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return pin_mng_exit; + } + + switch(shmp->process_info.callingCardState) + { + case entryCallingCard: + if(ocs_get_calling_card_method() == 0) + result = entryCallingCardProc(portid,shmp); + else + result = entryCallingCardProc_ccc(portid, shmp); + if(result > pin_mng_exit) + shmp->process_info.callingCardState = sendMainMenu; + else + retval1 = result; + break; + case sendMainMenu:/* send main menu */ + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = CallingCardMainMenu; + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.callingCardState = chooseFunction; + SendPromptAndCollectUserInfo(portid); + break; + case chooseFunction:/* choose function */ + result = WaitForMainMenu(shmp,portid); + if(result < 0) + break; + shmp->process_info.callingCardFunction = result; + shmp->process_info.callingCardState = runFunction; + shmp->process_info.sub_state_2 = callingCardIdle; + break; + case runFunction:/* run funcion */ + switch(shmp->process_info.callingCardFunction) + { + case ExitCallingCard: + shmp->process_info.callingCardState = exitCallingCardSys; + break; + case MakeCall: + retval1 = makeCallProc(portid,shmp); + break; + case InquiryBlance: + retval1 = inquiryBlanceProc(portid,shmp); + break; + case RechargeAccout: + retval1 = rechargeAccoutProc(portid,shmp); + break; + case ChangePassword: + retval1 = changePasswordProc(portid,shmp); + break; + case TransferAccount: + retval = transferAccountIVRProc(portid); + switch(retval) + { + case SERVICE_KEEP_STATE: + retval1 = pin_mng_keep_state; + break; + case SERVICE_RETURN_TO_PARENT: + retval1 = pin_mng_exit_to_main_menu; + break; + case SERVICE_EXIT_PPS: + default: + retval1 = pin_mng_exit; + break; + } + break; + default: + shmp->process_info.callingCardState = sendMainMenu; + break; + } + break; + case exitCallingCardSys: + retval1 = exitCallingCardProc(portid,shmp); + break; + default: + break; + } + return retval1; +} + + int CheckCallValidity_ccc(u_short portid) +{ + int retval;//,rst; + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("CheckCallValidity_ccc"); + + shmp += portid; + retval = shmp->process_info.state; + + shmp->caller_info.cos_id = ocs_get_calling_card_cos_id(); + shmp->context_info.callType = CT_MO_CC_CALL; + SetCallType(shmp, CT_MO_CC_CALL); + + BillingProc_ccc(shmp, TRUE); +#if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut," \n============== number info =============="); + + DebugMsg(debugmib.display.asciiOut," Call type:Calling Card call "); + + DebugMsg(debugmib.display.asciiOut,"Caller valid_time: %d calltype: %d fee: %.04f", + shmp->caller_info.valid_time, + shmp->process_info.call_type, + shmp->caller_info.fee); + DebugMsg(debugmib.display.asciiOut,"Caller info : %s (%d %d) status:%d,cosid:%d,balance: %.04f", + shmp->caller_info.number, + shmp->caller_info.cos_id, + ocs_get_calling_card_left_balance(shmp->card_info.cardhead, shmp->card_info.cardtail)); + DebugMsg(debugmib.display.asciiOut,"Called valid_time: %d calltype: %d fee: %.04f ", + shmp->called_info.valid_time, + shmp->process_info.call_type, + shmp->called_info.fee); + DebugMsg(debugmib.display.asciiOut,"Called info: %s (%d %d) status: %d,cosid:%d, balance: %.04f", + shmp->called_info.number, + shmp->called_info.head, + shmp->called_info.tail, + shmp->called_info.status, + shmp->called_info.cos_id, + GetBalance(&shmp->called_info)); + + DebugMsg(debugmib.display.asciiOut, + "Tariff :(%s) %s CT:%d DI:%d FreeTime:%d unit_time:%d Miniunit:%d Adj:%.04f ,CapFlag%d, Discount: %d", + shmp->charge_info.number, + shmp->process_info.tariff.bill_id, + shmp->process_info.tariff.call_type, + shmp->process_info.tariff.discountID, + shmp->process_info.tariff.free_time, + shmp->process_info.tariff.unit_time, + shmp->process_info.tariff.mini_unit, + shmp->process_info.tariff.adjustment, + shmp->process_info.tariff.cap_flag, + GetDiscount(tvnow.tv_sec,shmp->process_info.tariff.discountID)); + DebugMsg(debugmib.display.asciiOut, + "tierInfo:L-%d,A-(units:%d,bf:%.04f,lf:%.04f),B-(units:%d,bf:%.04f,lf:%.04f),C-(units:%d,bf:%.04f,lf:%.04f)", + shmp->process_info.tariff.tierRating.tierNumber, + shmp->process_info.tariff.tierRating.rating[0].units, + shmp->process_info.tariff.tierRating.rating[0].base_fee, + shmp->process_info.tariff.tierRating.rating[0].long_distance_fee, + shmp->process_info.tariff.tierRating.rating[1].units, + shmp->process_info.tariff.tierRating.rating[1].base_fee, + shmp->process_info.tariff.tierRating.rating[1].long_distance_fee, + shmp->process_info.tariff.tierRating.rating[2].units, + shmp->process_info.tariff.tierRating.rating[2].base_fee, + shmp->process_info.tariff.tierRating.rating[2].long_distance_fee); + } +#endif + + shmp->process_info.playAnnouncement = 0; + shmp->process_info.promptAndCollectUserInfo = 0; + + if (!IsEnableToCall_ccc(portid) ) + { + /* no voice for CAP V1 */ + if(shmp->context_info.acn_ver<1) + { + shmp->process_info.tcos = SERVICE_NOT_AVAILABLE; + SendReleaseCall(portid); + return (retval= S_RELEASE_ALL); + + } + + { + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 0; + shmp->process_info.promptAndCollectUserInfo = 0; + + return (retval = S_REQUEST_EVENTS); + } + + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 1; + } + + retval = S_REQUEST_EVENTS; + return retval; +} + +int WaitingforAnsweredProc_ccc(u_short portid) +{ + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + //DWORD instance = 0; + int retval, release_flag = 0x00,tcend_flag=0; + int dlgid,msglen,edpr; + CAP_Message capmsg; + struct CapArg capArg; + //CHARGED_FEE chargedFee; + char error[32]; + + PutLogFunID("WaitingforAnsweredProc_ccc"); + + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + + retval = shmp->process_info.state; + if (shmp->process_info.funnel >= pps_get_answer_timer_out()) //WAITINGFOR_ANSWERED_DELAY ) + { + shmp->process_info.tcos = NO_ANSWER; + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x01 || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"P/DID: Wait for answer timeout!" + ,portid,dlgid); + } + + SendReleaseCall(portid); + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + { + retval = S_RELEASE_ALL; + } + + return retval; + } + + shmp->process_info.funnel ++; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + + if(capmsg.msgOperaCode != CAP_OC_EventReportBCSM) + { + if(capmsg.msgOperaCode != CAP_OC_ApplyChargingReport) + { + shmp->process_info.tcos = NETWORK_OUT_OF_ORDER; +#if DEBUG + if(logMsgFlag & 0x04 || logMsgFlag & 0x01 || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Warning: pid=%d did=%d '%s' received (Waiting for ANSWER)", + portid,dlgid,GetCapError(error,capmsg.msgOperaCode)); + ppsDebugCapMsg(&capmsg,0); + } +#endif + + SendReleaseCall(portid); + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + { + retval = S_RELEASE_ALL; + } + return retval; + } + else + { + AddPPSStatistics(MIBPPS_CHARGINGREPORT,shmp->process_info.dir); + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"[%04d] EventReportBCSM Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + if((logMsgFlag & 0x02 )|| shmp->process_info.logMsisdn ) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + return retval; + } + } +#if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"portid=%d, dlgid=%d EventReportBCSM Received! (%ld.%ld)", + portid,shmp->context_info.dialogue_id,tvnow.tv_sec,tvnow.tv_usec); + } + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn ) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + + capArg.version = shmp->context_info.acn_ver; + + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + return retval; + edpr = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM; + switch(edpr) + { + case capp_routeSelectFailure: + release_flag = 0x01; + //tcend_flag = 0x01; + shmp->process_info.tcos = NO_ROUTE; + break; + case capp_oCalledPartyBusy: + case capp_tBusy: + release_flag = 0x01; + shmp->process_info.tcos = USER_BUSY; + break; + case capp_oNoAnswer: + case capp_tNoAnswer: + release_flag = 0x01; + shmp->process_info.tcos = NO_ANSWER; + break; + case capp_oAbandon: + case capp_tAbandon: + release_flag = 0x01; + //tcend_flag = 0x01; + shmp->process_info.tcos = CALL_REJECTED; + break; + case capp_oAnswer: + case capp_tAnswer: + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"portid=%d EventReportBCSM (Answered)!",portid); + } + #endif + + shmp->cdr_info.answertime = tvnow.tv_sec; + shmp->process_info.duration = 0; + shmp->process_info.down = 0; + shmp->process_info.funnel = 0; + + AddPPSStatistics(MIBPPS_ANSWERED,shmp->process_info.dir); + retval = S_WAITINGFOR_EVENTS; + + if(shmp->process_info.serviceKey != 1) + { + shmp->caller_info.charge += shmp->caller_info.fee; + shmp->called_info.charge += shmp->called_info.fee; + shmp->card_info.cc_call_charge += shmp->caller_info.fee; + } + break; + case capp_oDisconnect: + case capp_tDisconnect: + release_flag = 0x01; + shmp->process_info.tcos = edpr; + break; + default: + release_flag = 0x01; + shmp->process_info.tcos = NETWORK_OUT_OF_ORDER; + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x04 || logMsgFlag & 0x01 ) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Warning: pid=%d did=%d Error Message %d,edpr:%d (Waiting for ANSWER)", + dlgid,shmp->context_info.dialogue_id,capmsg.msgOperaCode,edpr); + ppsDebugCapMsg(&capmsg,0); + } + #endif + break; + }/* switch */ + + if(release_flag) + { + if(tcend_flag) + { + SendScfTcEND(portid); + retval = S_RELEASE_ALL; + } + else + { + SendReleaseCall(portid); + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + { + retval = S_RELEASE_ALL; + } + } + return retval; + } + + return retval; +} + +int WaitingForEventsReport_ccc(u_short portid) +{ + int retval, release_flag = 0x00,tcend_flag=0x00; + int dlgid,msglen, /*instance = 0,*/edpr;//,update_flag=0; + CAP_Message capmsg; + struct CapArg capArg; + //CHARGED_FEE chargedFee; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("WaitingForEventsReport_ccc"); + + shmp += portid; + retval = shmp->process_info.state; + + + dlgid = shmp->context_info.dialogue_id; + + if (shmp->process_info.funnel >= ACTIVITY_TEST_DELAY ) + { +#if DEBUG + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn ) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"portid=%d ActivityTest missed! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } +#endif + shmp->process_info.tcos = ACTIVITY_MISSED; + shmp->cdr_info.releasetime = tvnow.tv_sec; + + if(shmp->process_info.serviceKey == 1) + { + ChargeAccountByRealCallDuration(portid); + } + else + { + UpdateRechargeCardBalance(&shmp->card_info, -shmp->card_info.cc_call_charge); + SendCDR(portid); + } + + SendReleaseCall(portid); + + retval = S_RELEASE_ALL; + + return (retval); + } + + if(ReadScfMsg(&capmsg,dlgid)) + { +#if DEBUG + if((logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } +#endif + if(capmsg.msgOperaCode == CAP_OC_ActivityTest ) + { + if(capmsg.msgContent[2] != 0x03) + { + shmp->process_info.funnel = 0; + AddPPSStatistics(MIBPPS_ACTIVITYR,shmp->process_info.dir); + #if DEBUG + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d ActivityTest Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + } + } + else if(capmsg.msgOperaCode == 251) //notice + { + shmp->process_info.funnel = 0; + #if DEBUG + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d Notice Received while waiting for ACT! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + } + else if(capmsg.msgOperaCode == CAP_OC_ApplyChargingReport + /* charging report */ + || capmsg.msgOperaCode == CAP_OC_EventReportBCSM) + /* bcsm event report */ + { + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + #if DEBUG + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d Decode failed OC=%d", + portid,capmsg.msgOperaCode); + } + #endif + return retval; + } + + if(capmsg.msgOperaCode == CAP_OC_ApplyChargingReport) + { + #if DEBUG + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d ApplyChargingReport Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + /* charging time control */ + if(capArg.msg_list.applyChargingReportArg.callActive) + { + if( shmp->process_info.ro_if.adaptor_enabled == 1) + { + if(shmp->process_info.ro_if.granted_value>0) + SendApplyCharging(portid); + } + else + SendApplyCharging(portid); + + } + if(shmp->process_info.serviceKey ==1) + { + shmp->process_info.realCallDuration += + capArg.msg_list.applyChargingReportArg.timeInformation.timeIfNoTariffSwitch; + } + + AddPPSStatistics(MIBPPS_CHARGINGREPORT,shmp->process_info.dir); + } + + if(capmsg.msgOperaCode == CAP_OC_EventReportBCSM) + { + #if DEBUG + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d EventReportBCSM Received (disconnect)! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + + edpr = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM; + switch(edpr) + { + case capp_oDisconnect: + case capp_tDisconnect: + default: + release_flag = 0x01; + shmp->process_info.tcos = edpr; + AddPPSStatistics(MIBPPS_DISCONNECT,shmp->process_info.dir); + shmp->cdr_info.releasetime = tvnow.tv_sec; + break; + }/* switch */ + + if(release_flag) + { + if(tcend_flag) + SendScfTcEND(portid); + else + SendReleaseCall(portid); + shmp->cdr_info.releasetime = tvnow.tv_sec; + { + UpdateRechargeCardBalance(&shmp->card_info, -shmp->card_info.cc_call_charge); + + SendCDR(portid); + } + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + retval = S_RELEASE_ALL; + return retval; + } + } + } + else + { + shmp->process_info.tcos = INVALID_MESSAGE; + shmp->cdr_info.releasetime = tvnow.tv_sec; + { + UpdateRechargeCardBalance(&shmp->card_info, -shmp->card_info.cc_call_charge); + + SendCDR(portid); + } + + SendReleaseCall(portid); + retval = S_RELEASE_ALL; + + return retval; + } + }/* ReadScfMsg */ + + if(shmp->process_info.serviceKey != 1 && shmp->process_info.ro_if.adaptor_enabled == 0) + { + + if (shmp->caller_info.valid_time <= 0 /* Acquire next call period */ + || shmp->called_info.valid_time <= 0) + { + BillingProc_ccc(shmp, FALSE); + shmp->caller_info.charge += shmp->caller_info.fee; + shmp->called_info.charge += shmp->called_info.fee; + shmp->card_info.cc_call_charge += shmp->caller_info.fee; + } + + if (shmp->caller_info.valid_time <= 0 + || shmp->called_info.valid_time <= 0) + { + shmp->cdr_info.releasetime = tvnow.tv_sec; + if(shmp->process_info.tcos != CALLER_REACH_CHARGE_LIMIT) + { + shmp->process_info.tcos = CALLER_CREDIT_OUT; + } + + UpdateRechargeCardBalance(&shmp->card_info, -shmp->card_info.cc_call_charge); + + SendCDR(portid); + SendReleaseCall(portid); + + return (retval = S_RELEASE_ALL); + } + + shmp->caller_info.valid_time --; + shmp->called_info.valid_time --; + + } + + + shmp->process_info.down ++ ; + if(shmp->process_info.down >=send_activitytest_timer) //SEND_ACTIVITYTEST_PERIODIC) + { + shmp->process_info.down = 0; + SendActivityTest(portid); + } + shmp->process_info.funnel ++; + + shmp->process_info.duration ++; + if(shmp->process_info.duration>ppsParam.max_call_duration*50) + { + if(shmp->process_info.send_warning_sms_flag == 0) + { + char warning_message[256]; + + shmp->process_info.send_warning_sms_flag = 1; + + sprintf(warning_message, "call duration exceed MAX call duration %d minutes, caller=%s, called=%s, port id=%d", + ppsParam.max_call_duration, shmp->caller_info.number, shmp->called_info.number, portid); + + sendPPSTestShortMessage(warning_message); + } + } + + return retval; +} + diff --git a/mss/pps/src/main/calling_card.c b/mss/pps/src/main/calling_card.c new file mode 100644 index 0000000..8fe509a --- /dev/null +++ b/mss/pps/src/main/calling_card.c @@ -0,0 +1,8 @@ +#include + + +void function_abc() +{ + printf("abc\n"); + printf("add new printf\n"); +} diff --git a/mss/pps/src/main/capmsg.c b/mss/pps/src/main/capmsg.c new file mode 100644 index 0000000..8d4e81e --- /dev/null +++ b/mss/pps/src/main/capmsg.c @@ -0,0 +1,1389 @@ +#include +#include + +#include "../include/public.h" +#include "../include/ppsm.h" +#include "../include/message.h" +#include "../include/param.h" + +#include "../include/plat_inc.h" + +/* +#include "../../../../plat/public/src/include/includes.h" +#include "../../../../plat/public/src/include/function.h" +#include "../../../../plat/xapp/src/mapp/map_code.h" +#include "../../../../plat/xapp/src/ixap.h" +*/ +#include "../../../../plat/scf/src/include/scfmsg.h" +#include "../../../../plat/scf/src/include/scfdef.h" +//#include "../../../../plat/xapp/src/capp/cap_head.h" +//#include "../../../../plat/xapp/src/capp/cap_public.h" + + +/*----------------------------------------- */ +extern int SetLocationInfo(u_char *cgi,u_short portid); +extern void DebugMsgDelimiter(); +extern void DebugMsg(); +extern void ppsBcdToAsciiR(); +extern void SetRoamingFlag(); +/*------------------------------------------------*/ +int transferIddBillingPrefix(char *number); +void capMessageProc(); +int decode_initialDP(_state_data *shmp, u_short portid,CapArg capArg); +void tcap_change_local_ssn(u32 proc,u8 src_ssn,u8 dst_ssn); +int StuffCapMessage(CapArg capArg,PCAP_Message pcapmsg); +/*----------------------------------------- */ +extern _state_machine *smshm_ptr; +extern _ram_data *ramshm_ptr; +extern int logMsgFlag; +extern struct timeval tvnow; +/*----------------------------------------- */ +extern int AssignProcID(int gy_flag); +extern int CutUnknownPrefix(char *number); +extern int AddInterPrefix(char *number); +extern int AddCC(char *number); +extern int AddNationalPrefix(char *number); +extern void PutLogFunID(char *funName); +extern void StringCut(char *str, int c); +/*----------------------------------------- */ +void capMessageProc() +{ + int loop, portid,dlgid; + CAP_Message capmsg; + u_char msg_flow[256]; + _state_data *shmp=NULL; + + PutLogFunID("capMessageProc"); + for(loop=0;loop<64;loop++) + { + if(!GetScfOpen(&capmsg)) // ´ÓOpen¶ÓÁÐÖжÁÈ¡ÏûÏ¢£¬¶¨ÆÚµ÷Óà + break; + if(capmsg.msgLength[0]==0 && capmsg.msgLength[1]==0) {// ¼ì²é³¤¶ÈÓòÊÇ·ñ> 0 + debugmib.display.proc_begin[6] ++; + continue; + } + portid = AssignProcID(0);// ·ÖÅä´¦Àí¶Ë¿Ú + if( portid< MAX_FSM_PROCESS && portid>=0 ) + { + AddPPSStatistics(MIBPPS_CAPOPEN,0); + shmp=(_state_data *) &smshm_ptr->state_data; + shmp += portid; + + shmp->process_info.portid = portid; + + dlgid = capmsg.dialogue_id[0]*256 + capmsg.dialogue_id[1]; + shmp->context_info.mtype = CAP_O_OPEN; + shmp->context_info.dialogue_id = dlgid; + shmp->context_info.new_flag = YES; + shmp->context_info.acn = capmsg.msgContent[0]; + shmp->context_info.acn_ver = capmsg.msgContent[1]; + + tcap_change_local_ssn(dlgid, SSN_SCF, 0x92); + + if(0) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"[%04d] did=%d cap open received! ACN=[%d.%d] @(%ld.%ld)", + portid,dlgid, + shmp->context_info.acn, + shmp->context_info.acn_ver, + tvnow.tv_sec,tvnow.tv_usec); + } + } + } + for(loop=0;loop<10;loop++) + { + if(!map_get_open(msg_flow,0x99)) + break; + + portid = AssignProcID(0); + if( portid< MAX_FSM_PROCESS && portid>=0 ) + { + //AddPPSStatistics(MIBPPS_CAPOPEN,0); + shmp=(_state_data *) &smshm_ptr->state_data; + shmp += portid; + + shmp->process_info.portid = portid; + dlgid = msg_flow[6]*256 + msg_flow[7]; + shmp->context_info.mtype = 0x80; + shmp->context_info.map_did = dlgid; + shmp->context_info.new_flag = YES; + shmp->context_info.map_acn = msg_flow[11]; + shmp->context_info.map_acn_ver = msg_flow[12]; + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"[%04d] did=%d map open received! (%ld.%ld)", + portid,dlgid,tvnow.tv_sec,tvnow.tv_usec); + } + } + } +} + + +int +StuffCapMessage(CapArg capArg, PCAP_Message pcap_message) +{ + int msglen, offset=0, len; + + PutLogFunID("StuffCapMessage"); + +// memset(pcap_message,0,sizeof(CAP_Message)); + pcap_message->msgServiceCode = CAP_MSG_TYPE; + pcap_message->dialogue_id[0] = capArg.dialogue_id>>8; + pcap_message->dialogue_id[1] = capArg.dialogue_id; + pcap_message->dialogue_id[2] = 0x00; + pcap_message->port_id[0] = capArg.port_id>>8; + pcap_message->port_id[1] = capArg.port_id; + pcap_message->port_id[2] = 0x00; + pcap_message->msgOperaCode = capArg.ocode; + pcap_message->msgOperaType = 0x01; + pcap_message->msgContent[offset++] = capArg.invoke_id; + pcap_message->msgContent[offset++] = 0x01; //optional point + pcap_message->msgContent[offset++] = 0x01; //cap msg tag + len = encode_capmsg(capArg, + &pcap_message->msgContent[offset+2], + 234); + if(len<0 || len>240) return 0; + pcap_message->msgContent[offset++] = len>>8; + pcap_message->msgContent[offset++] = len; //cap msg length + offset += len; + + if(capArg.ocode != CAP_OC_ReleaseCall && capArg.ocode !=CAP_OC_ReleaseSMS) + { + pcap_message->msgContent[offset++] = 0x10; //delimiter + pcap_message->msgContent[offset++] = 0x00; + } + + pcap_message->msgContent[offset++] = 0x00; //end tag + msglen = 9; + msglen += offset; + pcap_message->msgLength[0] = msglen>>8; + pcap_message->msgLength[1] = msglen; + return msglen; +} + +int decode_initialDP_v1(_state_data *shmp,u_short portid,CapArg capArg) +{ + int flag,len,cause,unknwon_flag=0; + int err_flag = 0x00; + //int mf_call_flag = 0; + + CapInitialDP *pInitialDP; + + PutLogFunID("decode_initialDP"); + + cause = INVALID_MESSAGE; + + pInitialDP = &capArg.msg_list.initialDPArg; + + flag = pInitialDP->optional_flag; + + shmp->process_info.serviceKey = pInitialDP->serviceKey; + + + if(flag & 0x0400) + { //EventTypeBCSM + if(pInitialDP->eventTypeBCSM == capp_termAttemptAuthorized ) + shmp->context_info.callType = CT_MT_CALL; + else + shmp->context_info.callType = CT_MO_CALL; + } + else + { + DebugMsg(debugmib.display.asciiOut,"Error Msg: EventTypeBCSM missed"); + err_flag = 0x01; + } + + if(flag & 0x2000) + { //IMSI + len = pInitialDP->iMSI[0]%9; + memcpy(shmp->caller_info.IMSI, + &pInitialDP->iMSI[1], + len); + } + else + { + DebugMsg(debugmib.display.asciiOut,"Error Msg: IMSI missed!"); + //err_flag = 0x01; + } + + if(flag & 0x040000) + { //MSC Address + len = pInitialDP->mscAddress[0]; + if(len>11 || len<2) + { + DebugMsg(debugmib.display.asciiOut,"Wrong MSC Address!"); + return 0; + } + ppsBcdToAsciiR(shmp->cdr_info.msc_addr, + &pInitialDP->mscAddress[2], + (len-1)*2); + StringCut(shmp->cdr_info.msc_addr,'F'); + + } + + if(flag & 0x01) + { //callled party number,mandatory + len = pInitialDP->calledPartyNumber[0]; + if(len>11 || len<3) + { + DebugMsg(debugmib.display.asciiOut,"Wrong called party number!"); + return 0; + } + unknwon_flag = 0; + switch(pInitialDP->calledPartyNumber[1]) + { + case 0x81: //subscriber + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //unknown + unknwon_flag = 1; + + break; + case 0x01: + unknwon_flag = 1; + + break; + case 0x82: + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //unknown + unknwon_flag = 1; + break; + case 0x02: + unknwon_flag = 1; + break; + case 0x83: + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //national + case 0x03: + unknwon_flag = 2; + break; + case 0x84: + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //international + case 0x04: + break; + } + + if(unknwon_flag == 0) + shmp->called_info.nai = 0x91; + else if(unknwon_flag == 1) + shmp->called_info.nai = 0x81; + else + shmp->called_info.nai = 0xa1; + + memcpy(shmp->cdr_info.called, + &pInitialDP->calledPartyNumber[3], + len-2); + shmp->cdr_info.called[len-2]=0xFF; + ppsBcdToAsciiR(shmp->called_info.number, + &pInitialDP->calledPartyNumber[3], + (len-2)*2); + + StringCut((char *)shmp->called_info.number, 'F'); + + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + + if(unknwon_flag == 0) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 1) + { + // CutUnknownPrefix(shmp->called_info.number); + if(transferIddBillingPrefix((char *)shmp->charge_info.number)) + CutUnknownPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 2) + { + AddNationalPrefix((char *)shmp->charge_info.number); + AddCC((char *)shmp->called_info.number); + } + + CutUnknownPrefix((char *)shmp->called_info.number); + } + else + { + //DebugMsg(debugmib.display.asciiOut,"Called party number missed!"); + //err_flag = 0x01; + if(1)//flag & 0x100000) + { //callled partyBCD number + len = pInitialDP->calledPartyBCDNumber[0]; + if(len>13 || len<1) + { + DebugMsg(debugmib.display.asciiOut,"Wrong called partyBCD number!"); + return 0; + } + //81 or 91 + unknwon_flag = 0; + switch(pInitialDP->calledPartyBCDNumber[1]) + { + case 0x80: + case 0xc0: + unknwon_flag = 1; + break; + case 0x81: + case 0xc1: + //check prefix , here + unknwon_flag = 1; + break; + case 0x90: /*international */ + break; + case 0x91: + break; + case 0xa0: /*national */ + unknwon_flag = 2; + break; + case 0xa1: + unknwon_flag = 2; + break; + default: + break; + } + if(unknwon_flag == 0) + shmp->called_info.nai = 0x91; + else if(unknwon_flag == 1) + shmp->called_info.nai = 0x81; + else + shmp->called_info.nai = 0xa1; + + memcpy(shmp->cdr_info.called, + &pInitialDP->calledPartyBCDNumber[2], + len-1); + shmp->cdr_info.called[len-1]=0xFF; + ppsBcdToAsciiR(shmp->called_info.number, + &pInitialDP->calledPartyBCDNumber[2], + (len-1)*2); + StringCut((char *)shmp->called_info.number, 'F'); + + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + + if(unknwon_flag == 0) + { + AddInterPrefix((char *)shmp->charge_info.number); + // AddInterPrefix(shmp->called_info.number); + // CutUnknownPrefix(shmp->called_info.number); + } + else if(unknwon_flag == 1) + { + //CutUnknownPrefix(shmp->called_info.number); + if(transferIddBillingPrefix((char *)shmp->charge_info.number)) + CutUnknownPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 2) + { + AddNationalPrefix((char *)shmp->charge_info.number); + AddCC((char *)shmp->called_info.number); + } + CutUnknownPrefix((char *)shmp->called_info.number); + } + else + { + DebugMsg(debugmib.display.asciiOut,"Warning: Neigther 'Called party number' nor 'Called Party BCD Number' is presented..."); + err_flag = 0x01; + } + + } + + if((flag & 0x400000)||(flag & 0x800)) + { //MF + shmp->context_info.callType = CT_MF_CALL; + //mf_call_flag = 1; + + len = pInitialDP->redirectingPartyID[0]; + if(len>11 || len<3) { + DebugMsg(debugmib.display.asciiOut,"Wrong redirectingPartyID!"); + return 0; + } + unknwon_flag = 0; + switch(pInitialDP->redirectingPartyID[1] & 0x0F) + { + case 1: + case 2: + unknwon_flag = 1; + break; + case 3: + unknwon_flag = 2; + break; + case 4: + unknwon_flag = 0; + break; + } + if(pInitialDP->redirectingPartyID[1] & 0x80){ + //odd number digits, last digit is filler + pInitialDP->redirectingPartyID[len] = + pInitialDP->redirectingPartyID[len] | 0xF0 ; + } + + if(unknwon_flag == 0) + shmp->caller_info.nai = 0x91; + else if(unknwon_flag == 1) + shmp->caller_info.nai = 0x81; + else + shmp->caller_info.nai = 0xa1; + + memcpy(shmp->cdr_info.caller, + &pInitialDP->redirectingPartyID[3], + len-2); + shmp->cdr_info.caller[len-2]=0xFF; + + ppsBcdToAsciiR(shmp->caller_info.number, + &pInitialDP->redirectingPartyID[3], + (len-2)*2); + StringCut((char *)shmp->caller_info.number, 'F'); + + if(unknwon_flag == 2) + { + AddCC((char *)shmp->caller_info.number); + } + CutUnknownPrefix((char *)shmp->caller_info.number); + } + + if(flag & 0x02 ) + { /* calling party number */ + len = pInitialDP->callingPartyNumber[0]; + if(len>11 || len<3) + { + DebugMsg(debugmib.display.asciiOut,"Wrong calling party number!"); + return 0; + } + unknwon_flag = 0; + switch(pInitialDP->callingPartyNumber[1]) + { + case 0x02: + case 0x82: + unknwon_flag = 1; + break; + case 0x03: + case 0x83: + unknwon_flag = 2; + break; + } + + if(pInitialDP->callingPartyNumber[1] & 0x80) + { + /* odd number digits, last digit is filler */ + pInitialDP->callingPartyNumber[len] = + pInitialDP->callingPartyNumber[len] | 0xF0 ; + } + + if(shmp->context_info.callType != CT_MF_CALL) + { + memcpy(shmp->cdr_info.caller, + &pInitialDP->callingPartyNumber[3], + len-2); + shmp->cdr_info.caller[len-2]=0xFF; + + if(unknwon_flag == 0) + shmp->caller_info.nai = 0x91; + else if(unknwon_flag == 1) + shmp->caller_info.nai = 0x81; + else + shmp->caller_info.nai = 0xa1; + + + ppsBcdToAsciiR(shmp->caller_info.number, + &pInitialDP->callingPartyNumber[3], + (len-2)*2); + + StringCut((char *)shmp->caller_info.number, 'F'); + + + if(unknwon_flag == 0) + { + //AddInterPrefix(shmp->charge_info.number); + } + else if(unknwon_flag == 1) //unknown + { + CutUnknownPrefix((char *)shmp->caller_info.number); + // if(transferIddBillingPrefix(shmp->charge_info.number)) + // CutUnknownPrefix(shmp->charge_info.number); + } + else if(unknwon_flag == 2)//national + { + // AddNationalPrefix(shmp->charge_info.number); + AddCC((char *)shmp->caller_info.number); + } + + if(shmp->context_info.callType == CT_MT_CALL) + strcpy((char *)shmp->charge_info.number, (char *)shmp->caller_info.number); + } + else + { + if(unknwon_flag == 0) + shmp->origin_info.nai = 0x91; + else if(unknwon_flag == 1) + shmp->origin_info.nai = 0x81; + else + shmp->origin_info.nai = 0xa1; + + + ppsBcdToAsciiR(shmp->origin_info.number, + &pInitialDP->callingPartyNumber[3], + (len-2)*2); + + StringCut((char *)shmp->origin_info.number, 'F'); + + if(unknwon_flag == 0) + { + } + else if(unknwon_flag == 1) //unknown + { + CutUnknownPrefix((char *)shmp->origin_info.number); + } + else if(unknwon_flag == 2)//national + { + AddCC((char *)shmp->origin_info.number); + } + + } + } + else + { + DebugMsg(debugmib.display.asciiOut,"Error Msg: calling party number missed!"); + err_flag = 0x01; + } + + if(flag & 0x8000) + {//location information + if(shmp->context_info.callType == CT_MO_CALL) + { + if(pInitialDP->locationInformation.cellIdOrLAI_ch==0) + { + SetLocationInfo( + &pInitialDP->locationInformation.cellIdOrLAI.cellIdFixedLength[1], + portid); + } + else + { + DebugMsg(debugmib.display.asciiOut,"Location Info. missed for MO Call!"); + return 0; + } + } + // else if(shmp->context_info.callType == CT_MT_CALL) + { + len = pInitialDP->locationInformation.vlr_number[0]; + if(len<2 || len>11) + { + DebugMsg(debugmib.display.asciiOut,"Wrong vlr number!"); + return 1; /* roaming not */ + } + ppsBcdToAsciiR(shmp->cdr_info.locationNumber, + &pInitialDP->locationInformation.vlr_number[2], + (len-1)*2); + StringCut(shmp->cdr_info.locationNumber,'F'); + SetRoamingFlag(shmp); + } + } + else + { + if(shmp->context_info.callType == CT_MO_CALL) + { + DebugMsg(debugmib.display.asciiOut,"Location Info. missed for MO Call!"); + return 0; + } + } + + if(err_flag){ + cause = INVALID_MESSAGE; + memcpy(&shmp->process_info.tcos ,&cause,2) ; + return 0; + } + return 1; +} + + +int +decode_initialDP(_state_data *shmp,u_short portid,CapArg capArg) +{ + int flag,len,cause,unknwon_flag=0; + int err_flag = 0x00; + + CapInitialDP *pInitialDP; + + PutLogFunID("decode_initialDP"); + + pInitialDP = &capArg.msg_list.initialDPArg; + + flag = pInitialDP->optional_flag; + + shmp->process_info.serviceKey = pInitialDP->serviceKey; + + if(shmp->context_info.acn_ver == 0) + return decode_initialDP_v1(shmp,portid,capArg); + + if(pInitialDP->eventTypeBCSM == capp_termAttemptAuthorized) + shmp->context_info.callType = CT_MT_CALL; + + if(flag & 0x040000){ //MSC Address + len = pInitialDP->mscAddress[0]; + if(len>11 || len<2) + { + DebugMsg(debugmib.display.asciiOut,"Wrong MSC Address!"); + return 0; + } + ppsBcdToAsciiR(shmp->cdr_info.msc_addr, + &pInitialDP->mscAddress[2], + (len-1)*2); + StringCut(shmp->cdr_info.msc_addr,'F'); + + }else{ + DebugMsg(debugmib.display.asciiOut,"\nError Msg: MSC Address missed"); + err_flag = 0x01; + } + + if(flag & 0x0400){ //EventTypeBCSM + }else{ + DebugMsg(debugmib.display.asciiOut,"Error Msg: EventTypeBCSM missed"); + err_flag = 0x01; + } + + if(flag & 0x100000){ //Time and timezone + }else{ + DebugMsg(debugmib.display.asciiOut,"Error Msg: Time&timezone missed"); + err_flag = 0x01; + } + + /* + if(flag & 0x02 ) + { // calling party number + len = pInitialDP->callingPartyNumber[0]; + if(len>11 || len<3) + { + DebugMsg(debugmib.display.asciiOut,"Wrong calling party number!"); + return 0; + } + unknwon_flag = 0; + switch(pInitialDP->callingPartyNumber[1]) + { + case 0x02: + case 0x82: + unknwon_flag = 1; + break; + case 0x03: + case 0x83: + unknwon_flag = 2; + break; + } + if(pInitialDP->callingPartyNumber[1] & 0x80) + { + // odd number digits, last digit is filler + pInitialDP->callingPartyNumber[len] = + pInitialDP->callingPartyNumber[len] | 0xF0 ; + } + } + */ + + if(!(flag & 0x01)) + { + shmp->context_info.callType = CT_MO_CALL; + if(flag & 0x2000){ //IMSI + len = pInitialDP->iMSI[0]%9; + memcpy(shmp->caller_info.IMSI, + &pInitialDP->iMSI[1], + len); + } + else{ + DebugMsg(debugmib.display.asciiOut,"Error Msg: IMSI missed!"); + //err_flag = 0x01; + } + + if(flag & 0x02 ) + { /* calling party number */ + len = pInitialDP->callingPartyNumber[0]; + if(len>11 || len<3) + { + DebugMsg(debugmib.display.asciiOut,"Wrong calling party number!"); + return 0; + } + unknwon_flag = 0; + shmp->caller_info.nai = 0x91; + + switch(pInitialDP->callingPartyNumber[1]) + { + case 0x02: + case 0x82: + unknwon_flag = 1; + shmp->caller_info.nai = 0x81; + + break; + case 0x03: + case 0x83: + unknwon_flag = 2; + shmp->caller_info.nai = 0xa1; + + break; + } + if(pInitialDP->callingPartyNumber[1] & 0x80) + { + /* odd number digits, last digit is filler */ + pInitialDP->callingPartyNumber[len] = + pInitialDP->callingPartyNumber[len] | 0xF0 ; + } + memcpy(shmp->cdr_info.caller, + &pInitialDP->callingPartyNumber[3], + len-2); + shmp->cdr_info.caller[len-2]=0xFF; + ppsBcdToAsciiR(shmp->caller_info.number, + &pInitialDP->callingPartyNumber[3], + (len-2)*2); + StringCut((char *)shmp->caller_info.number, 'F'); + + strcpy((char *)shmp->charge_info.number, (char *)shmp->caller_info.number); + if(unknwon_flag == 0) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 1) //unknown + { + CutUnknownPrefix((char *)shmp->caller_info.number); + } + else if(unknwon_flag == 2)//national + { + AddNationalPrefix((char *)shmp->charge_info.number); + AddCC((char *)shmp->caller_info.number); + } + } + else + { + DebugMsg(debugmib.display.asciiOut,"Error Msg: calling party number missed!"); + err_flag = 0x01; + } + + if(flag & 0x100000) + { //callled partyBCD number + len = pInitialDP->calledPartyBCDNumber[0]; + if(len>13 || len<1) + { + DebugMsg(debugmib.display.asciiOut,"Wrong called partyBCD number!"); + return 0; + } + //81 or 91 + unknwon_flag = 0; + switch(pInitialDP->calledPartyBCDNumber[1]) + { + case 0x80: + case 0xc0: + unknwon_flag = 1; + shmp->called_info.nai = 0x81; + + break; + case 0x81: + case 0xc1: + //check prefix , here + unknwon_flag = 1; + shmp->called_info.nai = 0x81; + + break; + case 0x90: /*international */ + case 0x91: + shmp->called_info.nai = 0x91; + + break; + case 0xa0: /*national */ + case 0xa1: + unknwon_flag = 2; + shmp->called_info.nai = 0xa1; + + break; + default: + break; + } + memcpy(shmp->cdr_info.called, + &pInitialDP->calledPartyBCDNumber[2], + len-1); + shmp->cdr_info.called[len-1]=0xFF; + ppsBcdToAsciiR(shmp->called_info.number, + &pInitialDP->calledPartyBCDNumber[2], + (len-1)*2); + + StringCut((char *)shmp->called_info.number, 'F'); + shmp->called_info.nai = pInitialDP->calledPartyBCDNumber[1]; + + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + + if(unknwon_flag == 0) + { + AddInterPrefix((char *)shmp->charge_info.number); + // AddInterPrefix(shmp->called_info.number); + // CutUnknownPrefix(shmp->called_info.number); + /* if(transferIddBillingPrefix(shmp->charge_info.number)) + CutUnknownPrefix(shmp->charge_info.number); + */ + } + else if(unknwon_flag == 1) + { + //CutUnknownPrefix(shmp->called_info.number); + if(transferIddBillingPrefix((char *)shmp->charge_info.number)) + CutUnknownPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 2) + { + AddNationalPrefix((char *)shmp->charge_info.number); + AddCC((char *)shmp->called_info.number); + } + CutUnknownPrefix((char *)shmp->called_info.number); + } + else + { + DebugMsg(debugmib.display.asciiOut,"Error Msg: called party bcd number missed!"); + err_flag = 0x01; + } + + if(flag & 0x8000) + {/* location information */ + if(pInitialDP->locationInformation.cellIdOrLAI_ch==0) + { + /*both cellid and lac are known */ + SetLocationInfo( + &pInitialDP->locationInformation.cellIdOrLAI.cellIdFixedLength[1],portid); + }else + {/*only lac is known*/ + } + + len = pInitialDP->locationInformation.vlr_number[0]; + if(len<2 || len>11 ) return 0; + ppsBcdToAsciiR(shmp->cdr_info.locationNumber, + &pInitialDP->locationInformation.vlr_number[2], + (len-1)*2); + StringCut(shmp->cdr_info.locationNumber,'F'); + } + else{ + err_flag = 0x01; + } + } + else + { // MT/MF CALL + shmp->process_info.dir = 1; + unknwon_flag = 0; + if(flag & 0x2000){ //IMSI + len = pInitialDP->iMSI[0]%9; + memcpy(shmp->called_info.IMSI, + &pInitialDP->iMSI[1], + len); + } + else{ + DebugMsg(debugmib.display.asciiOut,"Error Msg: IMSI missed!"); + //err_flag = 0x01; + } + + if(flag & 0x01){ //callled party number,mandatory + len = pInitialDP->calledPartyNumber[0]; + if(len>11 || len<3) + { + DebugMsg(debugmib.display.asciiOut,"Wrong called party number!"); + return 0; + } + unknwon_flag = 0; + shmp->called_info.nai = 0x81; + + switch(pInitialDP->calledPartyNumber[1]) + { + case 0x81: //subscriber + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //unknown + unknwon_flag = 1; + break; + case 0x01: + unknwon_flag = 1; + break; + case 0x82: + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //unknown + unknwon_flag = 1; + break; + case 0x02: + unknwon_flag = 1; + break; + case 0x83: + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //national + case 0x03: + unknwon_flag = 2; + shmp->called_info.nai = 0xa1; + + break; + case 0x84: + pInitialDP->calledPartyNumber[len] = + pInitialDP->calledPartyNumber[len] | 0xF0 ; //international + + case 0x04: + shmp->called_info.nai = 0x91; + break; + } + + memcpy(shmp->cdr_info.called, + &pInitialDP->calledPartyNumber[3], + len-2); + shmp->cdr_info.called[len-2]=0xFF; + ppsBcdToAsciiR(shmp->called_info.number, + &pInitialDP->calledPartyNumber[3], + (len-2)*2); + StringCut((char *)shmp->called_info.number, 'F'); + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + + if(unknwon_flag == 0) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 1) + { + // CutUnknownPrefix(shmp->called_info.number); + if(transferIddBillingPrefix((char *)shmp->charge_info.number)) + CutUnknownPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 2) + { + AddNationalPrefix((char *)shmp->charge_info.number); + AddCC((char *)shmp->called_info.number); + } + CutUnknownPrefix((char *)shmp->called_info.number); + } + else + { + err_flag = 0x01; + } + + if(shmp->context_info.callType != CT_MT_CALL) + { + if((flag & 0x400000)||(flag & 0x800)) + { //MF + + shmp->context_info.callType = CT_MF_CALL; + if(flag & 0x2000){ //IMSI + len = pInitialDP->iMSI[0]%9; + memcpy(shmp->caller_info.IMSI, + &pInitialDP->iMSI[1], + len); + } + else{ + DebugMsg(debugmib.display.asciiOut,"Error Msg: IMSI missed!"); + err_flag = 0x01; + } + + len = pInitialDP->redirectingPartyID[0]; + if(len>11 || len<3) { + DebugMsg(debugmib.display.asciiOut,"Wrong redirectingPartyID!"); + return 0; + } + unknwon_flag = 0; + switch(pInitialDP->redirectingPartyID[1] & 0x0F) + { + case 1: + case 2: + unknwon_flag = 1; + shmp->caller_info.nai = 0x81; + break; + case 3: + unknwon_flag = 2; + shmp->caller_info.nai = 0xa1; + break; + case 4: + unknwon_flag = 0; + shmp->caller_info.nai = 0x91; + break; + } + if(pInitialDP->redirectingPartyID[1] & 0x80){ + //odd number digits, last digit is filler + pInitialDP->redirectingPartyID[len] = + pInitialDP->redirectingPartyID[len] | 0xF0 ; + } + memcpy(shmp->cdr_info.caller, + &pInitialDP->redirectingPartyID[3], + len-2); + shmp->cdr_info.caller[len-2]=0xFF; + + + ppsBcdToAsciiR(shmp->caller_info.number, + &pInitialDP->redirectingPartyID[3], + (len-2)*2); + StringCut((char *)shmp->caller_info.number, 'F'); + + if(unknwon_flag == 2) + { + AddCC((char *)shmp->caller_info.number); + } + CutUnknownPrefix((char *)shmp->caller_info.number); + } + else + { //MT + //shmp->context_info.callType = CT_MT_CALL; + } + } + + { + if(flag & 0x02) + { + len = pInitialDP->callingPartyNumber[0]; + if(len>11 || len<2) + { + DebugMsg(debugmib.display.asciiOut,"Wrong calling party number!"); + return 0; + } + unknwon_flag = 0; + + switch(pInitialDP->callingPartyNumber[1]) + { + case 0x02: + case 0x82: + unknwon_flag = 1; + shmp->caller_info.nai = 0x81; + + break; + case 0x03: + case 0x83: + unknwon_flag = 2; + shmp->caller_info.nai = 0xa1; + + break; + } + + if(pInitialDP->callingPartyNumber[1] & 0x80) + { + //odd number digits, last digit is filler + pInitialDP->callingPartyNumber[len] = + pInitialDP->callingPartyNumber[len] | 0xF0 ; + } + if(shmp->context_info.callType == CT_MT_CALL) + { + if(unknwon_flag == 0) + shmp->caller_info.nai = 0x91; + else if(unknwon_flag == 1) + shmp->caller_info.nai = 0x81; + else + shmp->caller_info.nai = 0xa1; + + memcpy(shmp->cdr_info.caller, + &pInitialDP->callingPartyNumber[3], + len-2); + shmp->cdr_info.caller[len-2]=0xFF; + ppsBcdToAsciiR(shmp->caller_info.number, + &pInitialDP->callingPartyNumber[3], + (len-2)*2); + StringCut((char *)shmp->caller_info.number, 'F'); + + strcpy((char *)shmp->charge_info.number, (char *)shmp->caller_info.number); + if(unknwon_flag == 0) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 1) //unknown + { + CutUnknownPrefix((char *)shmp->caller_info.number); + } + else if(unknwon_flag == 2)//national + { + AddNationalPrefix((char *)shmp->charge_info.number); + AddCC((char *)shmp->caller_info.number); + } + } + else if(shmp->context_info.callType == CT_MF_CALL) + { + if(unknwon_flag == 0) + shmp->origin_info.nai = 0x91; + else if(unknwon_flag == 1) + shmp->origin_info.nai = 0x81; + else + shmp->origin_info.nai = 0xa1; + + ppsBcdToAsciiR(shmp->origin_info.number, + &pInitialDP->callingPartyNumber[3], + (len-2)*2); + StringCut((char *)shmp->origin_info.number, 'F'); + + } + } + } + + if(flag & 0x8000){//location information + len = pInitialDP->locationInformation.vlr_number[0]; + if(len<2 || len>11) + { + DebugMsg(debugmib.display.asciiOut,"Wrong vlr number!"); + return 0; + } + ppsBcdToAsciiR(shmp->cdr_info.locationNumber, + &pInitialDP->locationInformation.vlr_number[2], + (len-1)*2); + StringCut(shmp->cdr_info.locationNumber,'F'); + + if(pInitialDP->locationInformation.cellIdOrLAI_ch==0) + { + SetLocationInfo( + &pInitialDP->locationInformation.cellIdOrLAI.cellIdFixedLength[1], + portid); + } + else + { + SetRoamingFlag(shmp); + } + } + } + + if(err_flag){ + cause = INVALID_MESSAGE; + memcpy(&shmp->process_info.tcos ,&cause,2) ; + return 0; + } + return 1; +} + +int +decode_initialDPSMS(_state_data *shmp,u_short portid,CapArg capArg) +{ + int flag,len,cause,unknwon_flag=0; + int err_flag = 0x00; + + CapInitialDPSMS *pInitialDPSMS; + + PutLogFunID("decode_initialDPSMS"); + + pInitialDPSMS = &capArg.msg_list.initialDPSMSArg; + + flag = pInitialDPSMS->optional_flag; + + shmp->context_info.callType = CT_MO_SM; + + shmp->process_info.serviceKey = pInitialDPSMS->serviceKey; + + if(flag & 0x01){ //calledPartyBCDNumber + len = pInitialDPSMS->destinationSubscriberNumber[0]; + if(len>11 || len<2){ + return 0; + } + shmp->called_info.nai = 0x91; + switch(pInitialDPSMS->destinationSubscriberNumber[1]) + { + case 0x81: + case 0x80: + unknwon_flag = 1; + shmp->called_info.nai = 0x81; + break; + case 0x91: + case 0x90: //international number + break; + case 0xA1: + case 0xA0: //national number + unknwon_flag = 2; + shmp->called_info.nai = 0xa1; + break; + default: + break; + } + memcpy(shmp->cdr_info.called, + &pInitialDPSMS->destinationSubscriberNumber[2], + len-1); + shmp->cdr_info.called[len-1]=0xFF; + + ppsBcdToAsciiR(shmp->called_info.number, + &pInitialDPSMS->destinationSubscriberNumber[2], + (len-1)*2); + StringCut((char *)shmp->called_info.number, 'F'); + StringCut((char *)shmp->called_info.number, 'E'); + + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + + if(unknwon_flag == 0) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 1) + { + if(CutUnknownPrefix((char *)shmp->called_info.number) !=1) + { + cause = NO_ROUTE; + memcpy(&shmp->process_info.tcos ,&cause,2) ; + return 0; + } + if(transferIddBillingPrefix((char *)shmp->charge_info.number)) + CutUnknownPrefix((char *)shmp->charge_info.number); + } + else if(unknwon_flag == 2) + { + AddNationalPrefix((char *)shmp->charge_info.number); + AddCC((char *)shmp->called_info.number); + } + } + + if(flag & 0x02) + { //calling + len = pInitialDPSMS->callingPartyNumber[0]; + if(len>11 || len<3) return 0; + memcpy(shmp->cdr_info.caller, + &pInitialDPSMS->callingPartyNumber[2], + len-1); + shmp->cdr_info.caller[len-1]=0xFF; + ppsBcdToAsciiR(shmp->caller_info.number, + &pInitialDPSMS->callingPartyNumber[2], + (len-1)*2); + StringCut((char *)shmp->caller_info.number, 'F'); + StringCut((char *)shmp->caller_info.number, 'E'); + + } + if(flag & 0x08) + { //imsi + len = pInitialDPSMS->iMSI[0]%9; + memcpy(shmp->caller_info.IMSI, + &pInitialDPSMS->iMSI[1], + len); + + } + if(flag & 0x10) + {/* location information */ + if(pInitialDPSMS->locationInformation.cellIdOrLAI_ch==0) + { + /*both cellid and lac are known */ + SetLocationInfo( + &pInitialDPSMS->locationInformation.cellIdOrLAI.cellIdFixedLength[1],portid); + } + len = pInitialDPSMS->locationInformation.vlr_number[0]; + if(len<2 || len>11 ) return 0; + ppsBcdToAsciiR(shmp->cdr_info.locationNumber, + &pInitialDPSMS->locationInformation.vlr_number[2], + (len-1)*2); + StringCut(shmp->cdr_info.locationNumber,'F'); + } + + + if(flag & 0x40) + { + len = pInitialDPSMS->sMSCAddress[0]; + if(len<2 || len>11 ) return 0; + ppsBcdToAsciiR(shmp->cdr_info.smsc_addr, + &pInitialDPSMS->sMSCAddress[2], + (len-1)*2); + StringCut(shmp->cdr_info.smsc_addr,'F'); + + } + + + if(err_flag){ + cause = INVALID_MESSAGE; + memcpy(&shmp->process_info.tcos ,&cause,2) ; + return 0; + } + return 1; + +} + +int +ppsDebugCapMsg(CAP_Message *cap_message,int flag) +{ + int loop; + char buf[1024]={""},buf1[256]={""}; + char capOC[256][40] = + { + " InitialDP", + "", "", "", "","", "", "", "","", "", "", "","", "", "", + " AssistRequestInstructions", + " EstablishTemporaryConnection", + " DisconnectForwardConnection", + " ConnectToResource", + " Connect", + "", + " ReleaseCall", + " RequestReportBCSMEvent", + " EventReportBCSM", + "", "", "", "", "", "", + " Continue", + "", + " ResetTimer", + " FurnishChargingInformation", + " ApplyCharging", + " ApplyChargingReport", + "", "", "", "", "", "", "", + " CallInformationReport", + " CallInformationRequest", + " SendChargingInformation", + " PlayAnnouncement", + " PromptAndCollectUserInformation", + " SpecializedResourceReport", + "", "", "", + " Cancel", + "", + " ActivityTest", + "", "", "", "", + " InitialDPSMS", + " FurnishChargingInformationSMS", + " ConnectSMS", + " RequestReportSMSEvent", + " EventReportSMS", + " ContinueSMS", + " ReleaseSMS", + " ResetTimerSMS", + }; + + PutLogFunID("ppsDebugCapMsg"); + DebugMsg(debugmib.display.asciiOut,""); + if(!flag) + { + DebugMsg(debugmib.display.asciiOut, + " \33[32m--

Rec. MSG @%ld.%ld\33[0m", + cap_message->port_id[0]*256+cap_message->port_id[1], + cap_message->dialogue_id[0]*256+cap_message->dialogue_id[1], + tvnow.tv_sec,tvnow.tv_usec); + } + else + { + DebugMsg(debugmib.display.asciiOut, + " \33[32m--

Snd. MSG @%ld.%ld\33[0m", + cap_message->port_id[0]*256+cap_message->port_id[1], + cap_message->dialogue_id[0]*256+cap_message->dialogue_id[1], + tvnow.tv_sec,tvnow.tv_usec); + } + DebugMsg(debugmib.display.asciiOut,"\33[32m %s \33[0m", + cap_message->msgOperaCode, + capOC[cap_message->msgOperaCode]); + + DebugMsg(debugmib.display.asciiOut," ----------------- Message Flow -----------------"); + sprintf(buf,"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n", + cap_message->msgLength[0], + cap_message->msgLength[1], + cap_message->msgServiceCode, + cap_message->port_id[0], + cap_message->port_id[1], + cap_message->port_id[2], + cap_message->dialogue_id[0], + cap_message->dialogue_id[1], + cap_message->dialogue_id[2], + cap_message->msgOperaCode, + cap_message->msgOperaType); + + for(loop=0;loopmsgLength[1]-9;loop++) + { + sprintf(buf1,"%02X ",cap_message->msgContent[loop]); + strcat(buf,buf1); + if((loop+1)%16==0){ + sprintf(buf1,"\r\n"); + strcat(buf,buf1); + } + } + DebugMsg(debugmib.display.asciiOut,"%s",buf); + + return 1; +} + +char *GetCapError(char *error,int ocode) +{ + PutLogFunID("GetCapError"); + + sprintf(error,"Unknown operation"); + switch(ocode){ + case CAP_O_END: + sprintf(error,"cap end"); + break; + case CAP_O_UABORT: + sprintf(error,"cap uabort"); + break; + case CAP_O_PABORT: + sprintf(error,"cap pabort"); + break; + case CAP_O_ERROR: + sprintf(error,"cap error"); + break; + default: + break; + } + return error; +} diff --git a/mss/pps/src/main/comfunc.c b/mss/pps/src/main/comfunc.c new file mode 100644 index 0000000..2a5e3e4 --- /dev/null +++ b/mss/pps/src/main/comfunc.c @@ -0,0 +1,660 @@ +#include "../include/includes.h" +#include "../include/sms_msgtype.h" +#include "../include/iptrans.h" + +extern long timezone; +extern iconv_t iconv_p,iconv_v; + +void Terminate(int sign) +{ + int retv; + + usleep(10*1000); + printf("Program unormally shutdown.\n"); + exit(1); +} + +void SetTerminate() +{ + struct termio ptermio; + ioctl(0,TCGETA, &ptermio); + ptermio.c_cc[VINTR]='\x03'; + ioctl(0,TCSETA, &ptermio); + signal(SIGINT , Terminate); + signal(SIGTERM, Terminate); +} + +void *ShmInit(int shm_id, key_t key, int size, int shmflg) +{ + void *retp; + + shm_id=shmget(key,size,shmflg); + + if(shm_id==-1){ + fprintf(stderr,"shmget(key %x) %s\n",key,strerror(errno)); + exit(1); + } + retp=shmat(shm_id,(char *)0,0); + if(retp==(void *)-1){ + fprintf(stderr,"shmmat %s\n",strerror(errno)); + exit(1); + } + return retp; +} + +int SemInit( key_t key, int sem_num, int sem_flg) +{ +int initarray[sem_num]; +int sem_id, retval, i; + + sem_id = semget(key, sem_num, sem_flg); + if (sem_id == -1) + { + fprintf(stderr,"Error in semget()\n"); + exit(1); + } + for (i=0; i160) return 0; + for(i=0;i>n) |((mid2<<(7-n))&0xff); + } + else + { + mid1=strIn[i]; + cur=(mid1>>n)&0xff; + } +// sprintf(tmpStr,"%2.2X", cur); +// strcat(strOut,tmpStr); + bcd_Out[index++]=cur; + n=(n+1)%7; + if(n==0) i++; + } +// AsciiToBcd(bcd_Out,strOut,strlen(strOut)); +// bcd_Out[strlen(strOut)/2]='\0'; + bcd_Out[index]='\0'; + return 1; +} + +int DecodeEnglish(char *strIn,char *strOut,int len0) +{ + int i,n,j; + int len; + unsigned char mid1,mid2,cur; + char tmpStr[2]; + BYTE strHex[1024]; + +// len=strlen(strIn); +// sprintf(strOut,""); +// + + n=0;j=0; + len = len0 - len0/8; + memcpy(strHex,strIn,len); + + fprintf(stderr,"len0 :%d len: %d\n",len0,len); + + for(i=0;i0) + { + mid1=strHex[i]; + mid2=strHex[i-1]; + cur=((mid1<>(8-n)); + } + else + { + mid1=strHex[i]&0x7f; + cur=mid1; + } + strOut[j++] = cur; + n =(n+1)%8; + if(n==0) i--; + } + + for(i=0;i>8; + strOut[i*2+1] = code; + } + + strOut[len]=0; + return len; +} + +int DecodeChinese( unsigned char *strIn, char *strOut,int len) +{ + int i,code,count=0; +// size_t size_in=8,size_out=0; +// len = iconv(iconv_p,&strIn,&size_in,&strOut,&size_out); + for(i=0;i>8; + strOut[count++] = code; + } + } + strOut[count]=0; + return len/2; +} + +int StrToChar(char *strIn,char *strOut) +{ + int i,len; + len=strlen(strIn); + + for(i=0;i=87) strIn[i] =strIn[i]-87; + else if(strIn[i]>=65) strIn[i] =strIn[i]-55; + else if(strIn[i]>=48) strIn[i] -=48; + } + for(i=0;i0) + { + if(endc==0) endc=j; + else if(endu==0) endu=j; + } + } + if(xcount>1){ + memcpy(ccode,&strRead[startc],endc-startc); + memcpy(ucode,&strRead[startu],endu-startu); + ccode[endc-startc]=0; + ucode[endu-startu]=0; + indexc=StrToInt(ccode); + indexu=StrToInt(ucode); + CP936_Array[indexc]=indexu; + Unicode_Array[indexu]=indexc; + } + } + return 1; +} + +int StrToInt(char *strHex) +{ + int i,len; + unsigned short intOut; + len=strlen(strHex); + for(i=0;i='a') strHex[i] =strHex[i]-'a'+10; + else if(strHex[i]>='A') strHex[i] =strHex[i]-'A'+10; + else if(strHex[i]>='0') strHex[i] =strHex[i]-'0'; + } + + if(len==2) intOut=(unsigned short)(strHex[0]*16+strHex[1]); + else if(len==4) intOut=(unsigned short)(strHex[0]*16+strHex[1])*256+(strHex[2]*16+strHex[3]); + + return intOut; +} + +const char * Inet_ntoa(const long addr) +{ + struct sockaddr_in addr_in; + addr_in.sin_addr.s_addr=addr; + return ((char *)inet_ntoa(addr_in.sin_addr)); +} + +int msisdn_conv(BYTE* dst_buf,const char *src_buf,int req_len) +{ + BYTE tmp_buf[256]; + int i,len; + len = strlen(src_buf); + memcpy(tmp_buf,src_buf,len); + if(len%2) + { + tmp_buf[len] = 0x0F; + len +=1; + } + AsciiToBcd_v(dst_buf,tmp_buf,len); /* exchange position of the char */ + return 0; +} + +int Datetime2SCTS(BYTE* scts, char* time_in) +{ + struct tm *tmnow=NULL; + time_t timep; + char tmpbuf[1024]; + + timep = time(NULL); + tmnow = localtime(&timep); + + tmpbuf[0] = time_in[2]; + tmpbuf[1] = time_in[3]; + tmpbuf[2] = time_in[5]; + tmpbuf[3] = time_in[6]; + tmpbuf[4] = time_in[8]; + tmpbuf[5] = time_in[9]; + tmpbuf[6] = time_in[11]; + tmpbuf[7] = time_in[12]; + tmpbuf[8] = time_in[14]; + tmpbuf[9] = time_in[15]; + tmpbuf[10] = time_in[17]; + tmpbuf[11] = time_in[18]; + if(timezone>0) + tmpbuf[12] = 0; + else + tmpbuf[12] = 1; + tmpbuf[13] = timezone/3600; + AsciiToBcd(scts,tmpbuf,14); + return 0; +} + + +int AsciiToBcd(BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + for(i=0;i='a') ch -='a' -10; + else if(ch>='A') ch -='A'-10; + else ch -='0'; + if(i &1) *(bcd_buf++) |=ch & 0x0f; + else *(bcd_buf) =ch<<4; + } + + return 0; +} + +int AsciiToBcd_v(BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch,tmp_buf[256]; + for(i=0;i='a') ch -= 'a' -10; + else if(ch>='A') ch -= 'A'-10; + else ch -= '0'; + tmp_buf[i] = ch; + } + for(i=0;i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} + +void DecodeAddress(char *addr_in,char *addrout) +{ + int i,len; + char addrin[22]; + + len = strlen(addr_in); + BcdToAscii(addrin,addr_in,len*2); + len = strlen(addrin); + for(i=0;isms_addr_type = 0x81; + for(i=0;i<8;i++) + { + if(addrin[i*2] !='E' && addrin[i*2] !='e') + { + sms_addr->sms_addr[i] = msisdn[i]; + len = len+2; + } + else if(addrin[i*2+1] == 'E' || addrin[i*2+1] =='e') + { + break; + } + else + { + sms_addr->sms_addr[i] = 0xf0 | (msisdn[i] &0x0f); + len = len+1; + break; + } + } + sms_addr->sms_addr_len = len; + + return 1; +} + +int addr2msisdn(SMS_ADDRESS sms_addr, unsigned char *msisdn) +{ + int i, len; + char addrin[22]; + + len = sms_addr.sms_addr_len; + BcdToAscii(addrin,sms_addr.sms_addr,len%2 ==0 ? len:len+1); + for(i=0;i<(len+1)/2;i++) + { + if(addrin[i*2] !='F' && addrin[i*2] !='f') + { + msisdn[i] = sms_addr.sms_addr[i]; + } + else + { + msisdn[i] = 0xE0 | (sms_addr.sms_addr[i] &0x0f); + } + } + for(i=(len+1)/2;i<8;i++) + msisdn[i]=0xEE; + return 1; +} + +int GetSCTS(long ltime, char *ch_time) +{ + struct tm *t ,tt; + char c_time[7]; + char work[2]={""}; + char tmp[20]={""}; + int i; + + t = &tt; + t = localtime(<ime); + + c_time[0] = t->tm_year-100; + c_time[1] = t->tm_mday; + c_time[2] = t->tm_mon+1; + c_time[3] = t->tm_hour; + c_time[4] = t->tm_min; + c_time[5] = t->tm_sec; + c_time[6] = timezone/3600; + + for(i=0;i<7;i++) + { + sprintf(work,"%02d",c_time[i]); + strcat(tmp,work); + } + + AsciiToBcd_v(ch_time,tmp,14); + + return 1; +} + +int str2msisdn(char *str_In, unsigned char *msisdn) +{ + int i,len; + char strIn[22]; + strcpy(strIn,str_In); + len = strlen(strIn); + for(i=len;i<16;i++) + strIn[i] = 'E'; + AsciiToBcd_v(msisdn,strIn,16); + return 1; +} + +int str2address(char *str_In, PSMS_ADDRESS addrout) +{ + int i,len; + char strIn[22]; + + strcpy(strIn,str_In); + len = strlen(strIn); + + addrout->sms_addr_len = len; + addrout->sms_addr_type = 0x81; + if(len%2 ==1) + { + strIn[len] ='F'; + len = len+1; + } + AsciiToBcd_v(addrout->sms_addr,strIn,len ); + return 1; +} + +int sms2str(char *strIn, char *strOut,int len) +{ + BcdToAscii( strOut,strIn,len*2); + return 1; +} + +int str2sms(char *strIn, char *strOut) +{ + int len; + len = strlen(strIn); + AsciiToBcd(strOut,strIn,len); + return 1; +} + +int GetDate(long ltime,char *ctime) +{ + struct tm *t ,tt; + + t = &tt; + t = localtime(<ime); + + ctime[0] = t->tm_year-100; + ctime[1] = t->tm_mon+1; + ctime[2] = t->tm_mday; + return 1; +} diff --git a/mss/pps/src/main/conf/.svn/all-wcprops b/mss/pps/src/main/conf/.svn/all-wcprops new file mode 100644 index 0000000..5cf3d06 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/all-wcprops @@ -0,0 +1,95 @@ +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf +END +ppsCrdConf.txt +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/ppsCrdConf.txt +END +map_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/map_operation.conf +END +map_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/map_acn.conf +END +help_page +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/help_page +END +ppsConf.txt +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/ppsConf.txt +END +xap_sysparam.conf +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/xap_sysparam.conf +END +sccp.conf_omt +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/sccp.conf_omt +END +menu_page +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/menu_page +END +iptrans.conf +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/iptrans.conf +END +wxc2_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/wxc2_sys.conf +END +conv_prefix.conf +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/conv_prefix.conf +END +mtp3.conf +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/mtp3.conf +END +cap_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/cap_operation.conf +END +cap_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/cap_acn.conf +END +sccp.conf +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/wxc2/!svn/ver/1/trunk/R4S/mss/pps/src/main/conf/sccp.conf +END diff --git a/mss/pps/src/main/conf/.svn/entries b/mss/pps/src/main/conf/.svn/entries new file mode 100644 index 0000000..981f5d9 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/entries @@ -0,0 +1,538 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/mss/pps/src/main/conf +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +ppsCrdConf.txt +file + + + + +2012-12-28T03:06:58.093750Z +33217000814fb308373097dd6d015d55 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +10289 + +map_operation.conf +file + + + + +2012-12-28T03:06:58.109375Z +bc4f58d51ae8fdff18b7ec71c18bfdd7 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +2647 + +map_acn.conf +file + + + + +2012-12-28T03:06:58.109375Z +c2eeff43e897f1191ff6dda1e51c31da +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1509 + +help_page +file + + + + +2012-12-28T03:06:58.109375Z +487a2b3a13e1b0077495bc54ad5d8df1 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +386 + +ppsConf.txt +file + + + + +2012-12-28T03:06:58.140625Z +8add96d879bffb4071178c299efd21f1 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +5040 + +xap_sysparam.conf +file + + + + +2012-12-28T03:06:58.187500Z +07db917a0a4b0ccba0a5543d2c64f904 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +16 + +sccp.conf_omt +file + + + + +2012-12-28T03:06:58.171875Z +535e4352e3f516c242faa58bc866eb30 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +5361 + +menu_page +file + + + + +2012-12-28T03:06:58.093750Z +fed7c4dea77026a9421bd72171df6002 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +583 + +iptrans.conf +file + + + + +2012-12-28T03:06:58.125000Z +b0b3666a5a447b7d63550fae7e1934f4 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +516 + +wxc2_sys.conf +file + + + + +2012-12-28T03:06:58.125000Z +85ad7cc8ef48e2afa8eaeeeab97855ec +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +86 + +conv_prefix.conf +file + + + + +2012-12-28T03:06:58.140625Z +789b365e94dc068bb5090f254a6bbd73 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +6976 + +mtp3.conf +file + + + + +2012-12-28T03:06:58.156250Z +937821b810444c6fbd6a1365cb8330a0 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +95312 + +cap_operation.conf +file + + + + +2012-12-28T03:06:58.156250Z +15cd724ea91b96d8c6ff14aee06b7bcf +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1200 + +cap_acn.conf +file + + + + +2012-12-28T03:06:58.171875Z +6eb5596aab256989a2e072f0858b47c0 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +209 + +sccp.conf +file + + + + +2012-12-28T03:06:58.187500Z +ae0e3a6cac430bf387542d641941deda +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1228 + diff --git a/mss/pps/src/main/conf/.svn/prop-base/cap_acn.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/cap_acn.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/cap_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/cap_operation.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/cap_operation.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/cap_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/conv_prefix.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/conv_prefix.conf.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/conv_prefix.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/help_page.svn-base b/mss/pps/src/main/conf/.svn/prop-base/help_page.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/help_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/iptrans.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/iptrans.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/iptrans.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/map_acn.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/map_acn.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/map_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/map_operation.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/map_operation.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/map_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/menu_page.svn-base b/mss/pps/src/main/conf/.svn/prop-base/menu_page.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/menu_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/mtp3.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/mtp3.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/mtp3.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/ppsConf.txt.svn-base b/mss/pps/src/main/conf/.svn/prop-base/ppsConf.txt.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/ppsConf.txt.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/ppsCrdConf.txt.svn-base b/mss/pps/src/main/conf/.svn/prop-base/ppsCrdConf.txt.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/ppsCrdConf.txt.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/sccp.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/sccp.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/sccp.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/sccp.conf_omt.svn-base b/mss/pps/src/main/conf/.svn/prop-base/sccp.conf_omt.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/sccp.conf_omt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/wxc2_sys.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/wxc2_sys.conf.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/wxc2_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/mss/pps/src/main/conf/.svn/prop-base/xap_sysparam.conf.svn-base b/mss/pps/src/main/conf/.svn/prop-base/xap_sysparam.conf.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/mss/pps/src/main/conf/.svn/prop-base/xap_sysparam.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/mss/pps/src/main/conf/.svn/text-base/cap_acn.conf.svn-base b/mss/pps/src/main/conf/.svn/text-base/cap_acn.conf.svn-base new file mode 100644 index 0000000..6a18ef5 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/text-base/cap_acn.conf.svn-base @@ -0,0 +1,7 @@ +#application context name configure file for CAP +total data length=3 + +#application context name data +No.1:50 02 // gsmSSF to gsmSCF +No.2:51 02 // assist handoff gsmSSF to gsmSCF +No.3:52 02 // gsmSRF to gsmSCF diff --git a/mss/pps/src/main/conf/.svn/text-base/cap_operation.conf.svn-base b/mss/pps/src/main/conf/.svn/text-base/cap_operation.conf.svn-base new file mode 100644 index 0000000..aab4687 --- /dev/null +++ b/mss/pps/src/main/conf/.svn/text-base/cap_operation.conf.svn-base @@ -0,0 +1,34 @@ +# operation code configure file for CAP +total data length=30 + +#operation code +No.1:00 02 5 // initial DP +No.2:16 02 5 // assist request instructions +No.3:17 02 20 // establish temporary connection +No.4:18 04 5 // disconnect forward connection +No.5:19 04 5 // connect to resource +No.6:20 04 5 // connect +No.7:22 04 5 // release call +No.8:23 02 5 // request report BCSM event +No.9:24 02 5 // event report BCSM +No.10:31 04 5 // continue +No.11:33 04 5 // reset timer +No.12:34 04 5 // furnish charging information +No.13:35 02 5 // apply charging +No.14:36 04 5 // apply charging report +No.15:44 04 5 // call information report +No.16:45 04 5 // call information request +No.17:46 04 5 // send charging information +No.18:47 04 60 // play announcement +No.19:48 01 60 // prompt and collect user information +No.20:49 04 5 // specialized resource report +No.21:53 02 5 // cancel +No.22:55 01 5 // activity test +No.23:60 02 5 // initial DPSMS +No.24:61 02 5 // Furnishing charging info.SMS +No.25:62 02 5 // connect DPSMS +No.26:63 02 5 // request SMS event +No.27:64 02 5 // event report SMS +No.28:65 04 5 // continue SMS +No.29:66 04 5 // release DPSMS +No.30:67 02 5 // reset timer DPSMS diff --git a/mss/pps/src/main/conf/.svn/text-base/conv_prefix.conf.svn-base b/mss/pps/src/main/conf/.svn/text-base/conv_prefix.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..356419088365f7cd6716fcb00824f348d35b9c39 GIT binary patch literal 6976 zcmeIyOAde_3`J3@abVmGen8y+#{3S7=DC9FNJ^>6$rIbc>*-2fQ}RWN(Jw=2>gBnz z>(pnMZyfA3CRkIl?>Ofi->#>8dU}g_Tl_g|Q(ZXb_-gZK x1jvSx;ol(}WJ3v%4JE_9K{m*S5+EB&hI^wOr}ljA6n+;ct;E8B1OpO!Lr0b-acC;GijAQvDyU2x_Jde*Z0l@Cz~lw?E(kI4 zBcMNq6|u2`y1}!Z1lw|h4LDL%pLFl;-Fx@>%lF=JIXyZ$fhRxXaXNW)d_%#H-`nrJ z1pr|He0U?^d`H0bd!gbZfWyNF$-3Jg4D}Jfh(~;|@RML`S_Lk%0=ll}ety5dTkwYk zznGto4+eumem)MOqjh^*oTJ6Ft3mYs+d*>Wp&KYdLy>6(NPd7O?PC&2&50W-l!oDk zPJmCPEggf<^7k_-jc$=%cos91VUE`FoAbDdma{fa%a8L0J#u_{g%TAR6RDn)!da@R zJM{v}=9cZzvq}22yp1ojf?Ey-*7T1cWxyM9HY4T7R0DT4VKYqQ&y+h|m1&Z4EUtm{ zJhG9dmX9`NI^(|N9yg?Iqfgw??z+1s&yRa1yoevi$eNM4UXF4ut_)VG{O>UVR~8`A zwS&EQF8se=KfxIY&;-EO1ms;5KVaff1yk_d3rF<1GZAT=pFKS4VRstD)*8g_R>b}? z*Q8D@dlj+MS^}h%tX9jdir5KlHg&MK8^m7lDPQ9r%tz|*&fhG0O=IVYZw~LgPM3jq z{7&q_RrtvB7TcR}m+ftM%oboG*m5z?6JcJ%TVBm5acZ0PUb$rJ)}@?9d%7VC=;PsN VocYJMH@c(i;|(F-()=F^`~tbc9n$~+ literal 0 HcmV?d00001 diff --git a/mss/pps/src/main/conf/.svn/text-base/ppsCrdConf.txt.svn-base b/mss/pps/src/main/conf/.svn/text-base/ppsCrdConf.txt.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..7632e1c034e67f21bde6d2e29b9d41047e076a50 GIT binary patch literal 10289 zcmeI$!41P85JXXz6$rIbc>*-2fQ}RWN(Jw=2>gBnz z>(pnMZyfA3CRkIl?>Ofi->#>8dU}g_Tl_g|Q(ZXb_-gZK x1jvSx;ol(}WJ3v%4JE_9K{m*S5+EB&hI^wOr}$|7IYnq?IhTiFW7)1Mdy`vc4uey`Q^4{s>=@q7E7 zw*VjvfcI|%oZS*|{a&c}2;ku0L9*`j2Sa@XFyav(Ec_(cnpS~}tbnfTxu4(f?-cxD z!7t|L}n9b`?jB4dE^F)&`@Mr0g@k}Nqd+?Qgh^n3Z-GV zp%dUUX-mf-wEVqHN~2q(m!8E8WtgM2{N_AvqUEfO)AHlIL601tj!~i_VR>Q zo<}y))bi1$OlRDe+~bC{ZS;vd+Ff_ohR9rEP732=ZS9)@4QYI zfp`2+?7>y|z;m1JO}NYUHauYqFcECIm}iMFui=zeGfJG=roC4#*}8QpXVIQ+hywa} XI2vdE^6if9==yj=$hS2AhXTI<#kd{d literal 0 HcmV?d00001 diff --git a/mss/pps/src/main/conf/ppsCrdConf.txt b/mss/pps/src/main/conf/ppsCrdConf.txt new file mode 100644 index 0000000000000000000000000000000000000000..7632e1c034e67f21bde6d2e29b9d41047e076a50 GIT binary patch literal 10289 zcmeI$!41P85JXXzplmnServiceNumber,0,16); + memcpy(pcrd->plmnServiceNumber,pdata,dataLen); + break; + case 2: + memset(pcrd->pstnServiceNumber,0,16); + memcpy(pcrd->pstnServiceNumber,pdata,dataLen); + + break; + case 3: + memset(pcrd->leaveMessageNumber,0,16); + memcpy(pcrd->leaveMessageNumber,pdata,dataLen); + break; + case 4: + pcrd->routeMethodOption = pdata[0]; + break; + case 5: + pcrd->routeNumberOption = pdata[0]; + break; + case 6: + pcrd->isPostpaidAllowed = pdata[0]; + break; + case 7: + pcrd->ring_back_service_key = pdata[0]; + break; + } + return dataLen; +} + +int GetCRDParam(u_char oidLen, DWORD *oid, + u_char *pdata, BYTE *vartype) +{ + int oid3; + int vallen = 1; + VmsRouteParam *pcrd; + + pcrd = &ppsParam.routeParam; + oid3 = oid[13]; + *vartype = 0x04; + switch(oid3) + { + case 1: + vallen = strlen((char *)pcrd->plmnServiceNumber); + memcpy(pdata,pcrd->plmnServiceNumber,vallen); + break; + case 2: + vallen = strlen((char *)pcrd->pstnServiceNumber); + memcpy(pdata,pcrd->pstnServiceNumber,vallen); + break; + case 3: + vallen = strlen((char *)pcrd->leaveMessageNumber); + memcpy(pdata,pcrd->leaveMessageNumber,vallen); + break; + case 4: + *vartype = INTEGER; + pdata[0] = pcrd->routeMethodOption; + break; + case 5: + *vartype = INTEGER; + pdata[0] = pcrd->routeNumberOption; + break; + case 6: + *vartype = INTEGER; + pdata[0] = pcrd->isPostpaidAllowed; + break; + case 7: + *vartype = INTEGER; + vallen = 1; + pdata[0] = pcrd->ring_back_service_key; + break; + } + + return vallen; +} + +int IsCRDServiceNumber(char *number) +{ + int retval=0; + int len; + VmsRouteParam *pcrd; + + pcrd = &ppsParam.routeParam; + + if(pcrd->routeMethodOption == ByWholeNumber) + { + if(strcmp((char *)pcrd->plmnServiceNumber,number)==0) + retval = 1; + } + else + { + if(pcrd->plmnServiceNumber[0] == 0) return 0; + len = strlen((char *)pcrd->plmnServiceNumber); + if(!strncasecmp(number, (char *)pcrd->plmnServiceNumber,len)) + retval = 1; + } + return retval; +} + +int IsPSTNMaitenance(char *number) +{ + int retval=0; + int len; + VmsRouteParam *pcrd; + + pcrd = &ppsParam.routeParam; + + if(pcrd->routeMethodOption == ByWholeNumber) + { + if(strcmp((char *)pcrd->pstnServiceNumber,number)==0) + retval = 1; + } + else + { + if(pcrd->pstnServiceNumber[0] == 0) return 0; + len = strlen((char *)pcrd->pstnServiceNumber); + if(!strncasecmp(number, (char *)pcrd->pstnServiceNumber,len)) + retval = 1; + } + return retval; +} + +int IsVMSDeposit(char *number) +{ + int retval=0; + int len; + VmsRouteParam *pcrd; + + pcrd = &ppsParam.routeParam; + + if(pcrd->routeMethodOption == ByWholeNumber) + { + if(strcmp((char *)pcrd->leaveMessageNumber,number)==0) + retval = 1; + } + else + { + if(pcrd->leaveMessageNumber[0] == 0) return 0; + len = strlen((char *)pcrd->leaveMessageNumber); + if(!strncasecmp(number, (char *)pcrd->leaveMessageNumber,len)) + retval = 1; + } + return retval; +} + +int GetCRDDestination(char *src_number, char *dst_number,u_char type) +{ + int retval=0; + int loop=0; + VmsUserSegment *crd_ptr; + + for(loop=0;loopexistFlag == FALSE) + continue; + if(strcmp(src_number, (char *)crd_ptr->startMsisdn)>=0) + if(strcmp(src_number, (char *)crd_ptr->endMsisdn)<=0) + { + switch(type) + { + case 0: /* PLMN maintenance */ + strcpy(dst_number, (char *)crd_ptr->vmsPLMNserviceNumber); + break; + case 1: /* PSTN maintenance */ + strcpy(dst_number, (char *)crd_ptr->vmsPSTNserviceNumber); + break; + case 2: /* deposit message */ + strcpy(dst_number, (char *)crd_ptr->leaveMessageNumber); + break; + } + retval = 1; + break; + } + } + return retval; +} + +int IsPostpaidAllowed() +{ + VmsRouteParam *pcrd; + + pcrd = &ppsParam.routeParam; + + return pcrd->isPostpaidAllowed; +} + +int CheckCRDRingBackSericeKey(int serviceKey) +{ + VmsRouteParam *pcrd; + + pcrd = &ppsParam.routeParam; + + if(pcrd->ring_back_service_key<2) + return 0; + if(pcrd->ring_back_service_key == serviceKey) + return 1; + return 0; +} + diff --git a/mss/pps/src/main/dailyreport.c b/mss/pps/src/main/dailyreport.c new file mode 100644 index 0000000..2725d51 --- /dev/null +++ b/mss/pps/src/main/dailyreport.c @@ -0,0 +1,1822 @@ +/* for daily report + * includes: cdr , account, repaid card +*/ + +#include "../include/includes.h" +#include "../include/report.h" +#include "../include/ramdata.h" +#include "../include/ppsm.h" +#include "../include/cdrme.h" +#include "../include/param.h" +#include "../include/precard.h" +#include "../include/message.h" +#include "../include/plat_inc.h" + +_pps_report pps_report; + +extern u_long PPS_OID_PREFIX[]; +extern u_long peer_server_ip; +extern char masterFlag; +/*------------------------------------------------*/ + +extern int time_now[7]; +extern _ram_data *ramshm_ptr; +extern struct timeval tvnow; +extern _state_machine *smshm_ptr; +extern PPSParamStruct ppsParam; +/*------------------------------------------------*/ +char call_type_name[16][32]={ +"LOCAL_CALL_OUT", +"IDD_CALL", +"NDD_CALL", +"INCOMING_CALL", +"RENT_CHARGE", +"AST_RECHARGE", +"AST_CHARGE", +"RECHARGE_SUC", +"RECHARGE_FAIL", +"SHORT_MESSAGE" +}; + +extern int GetCardIndex(); +int GetDailyReportByIndex(u_char oidLen, DWORD *oid, + u_char *pdata, BYTE *vartype); +int printfDailyLog(int index); +extern u_long LOCAL_IP; +static int waittime = 0, retrytime = 0, getDailyReportResponseFlag = 0; +/*------------------------------------------------*/ +int ClearCleanUsedCardForDailyReport(int index); +int GetPrecardSumData(int index, int type); +int LoadDailyReport(); +int ReadDailyReportFromPeerServer(); +int AccountExpiredDateCheck(); +int SendDailyReportToPeerServerForStop(); +extern void SendOperatorRechargeCDR(); +extern int IsPromotionTime(COSTable *cosTableItem, struct timeval tvn); +extern int smppSendAccountInfo(); +extern int smppSendMOSM(char *called, char *caller, u_char *msg,int msgLen,u_char dataCoding); +extern int CleanPPSUSSDStatisticsByDay(); +extern void resetPoolSlaveDaily(u_short head,u_short tail); +extern int UseExternalVC(); +extern u_char *getSmsSentenceNative(u8 languageType,SMS_SENTENCE id); +extern int subscribe_bundle_plan_send_used_up_info(char *caller_number, SMS_SENTENCE id); +extern char* ppsParseSentence(char *sentence, int varNum, char *varStr[]); +/*----------------------------------------------*/ +void reportInit() +{ + PutLogFunID("reportInit"); + + pps_report.ptrTail = 0; + memset(&pps_report,0,sizeof(_pps_report)); + + getnowtime(time_now); + pps_report.ptrTail = time_now[6]; /* week day */ + pps_report.saveHead = pps_report.ptrTail; + pps_report.saveTail = pps_report.ptrTail; + + pps_report.daily_report[pps_report.ptrTail].year_month_day[0]=time_now[0]; + pps_report.daily_report[pps_report.ptrTail].year_month_day[1]=time_now[1]; + pps_report.daily_report[pps_report.ptrTail].year_month_day[2]=time_now[2]; + + LoadDailyReport(); +} + +void DisplayDailyReportIndex(char *ptr) +{ + ptr = (char *)&pps_report.ptrTail; +} + +int reportCreatedDaily() +{ + static int dailyState=0; + static int segmentno=0; + int balance; + + PutLogFunID("reportCreatedDaily"); + + switch(dailyState){ + case 0: + if(time_now[3]==0 && time_now[4]==0 && time_now[5]<5) //00:00:00 + if(time_now[5]>3) + { + dailyState = 1; + segmentno = 0; + CleanPPSUSSDStatisticsByDay(); + } + break; + case 1: + //if(segmentno<1) + { + reportAccount(segmentno); + reportPrepaidCard(segmentno); + segmentno++; + } + //else + { + segmentno = 0; + dailyState = 2; + waittime = 0; + retrytime = 0; + } + break; + case 2: + dailyState = 3; + waittime = 0; + getDailyReportResponseFlag = 0; + ReadDailyReportFromPeerServer(); + break; + case 3: + if(!getDailyReportResponseFlag) + { + if(waittime++>10) + { + if(retrytime++<2) + { + waittime = 0; + dailyState = 2; + } + else + { + waittime = 0; + retrytime = 0; + dailyState = 4; + } + } + } + else + dailyState = 4; + break; + case 4: + balance = + (int)pps_report.daily_report[pps_report.ptrTail].balance_summary.today_recharge; + debugmib.report_sum[pps_report.ptrTail][1] = balance; + balance = + (int)pps_report.daily_report[pps_report.ptrTail].balance_summary.today_charge; + debugmib.report_sum[pps_report.ptrTail][3] = balance; + + pps_report.ptrTail = time_now[6]; + pps_report.ptrTail %=MAX_RECORDS_SAVED; + memset(&pps_report.daily_report[pps_report.ptrTail],0,sizeof(_daily_report)); + pps_report.daily_report[pps_report.ptrTail].year_month_day[0]=time_now[0]; + pps_report.daily_report[pps_report.ptrTail].year_month_day[1]=time_now[1]; + pps_report.daily_report[pps_report.ptrTail].year_month_day[2]=time_now[2]; + + pps_report.saveTail ++; + + if(pps_report.saveTail ==0x80000000){ + pps_report.saveTail = 0; + } + if(pps_report.saveTail == pps_report.saveHead){ + pps_report.saveHead ++; + pps_report.saveHead %=0x80000000; + } + dailyState = 5; + segmentno = 0; + break; + case 5: + if(segmentno ++>(20*CYCLE_STATE_INTERVAL)) + { + dailyState = 0; + segmentno = 0; + } + break; + default: + dailyState = 0; + segmentno = 0; + break; + } + AccountExpiredDateCheck(); + return 1; +} + +int reportCDRIncrement(int calltype, int duration, float charge,ulong gprsVolume) +{ + int type=0,index=0; + + PutLogFunID("reportCDRIncrement"); + + switch(calltype){ + case CT_LOCAL_CALL_OUT: + case CT_TRUNK_CALL_OUT: + type = LOCAL_CALL_OUT; + break; + case CT_LOCAL_CALL_IN: + case CT_TRUNK_CALL_IN: + type = INCOMING_CALL; + break; + case CT_NDD_CALL_OUT: + type = NDD_CALL; + break; + case CT_IDD_CALL_OUT: + type = IDD_CALL; + break; + case CT_PERIODIC_CHARGE: + type = RENT_CHARGE; + break; + case CT_ASSISTED_UP: + type = AST_RECHARGE; + break; + case CT_ASSISTED_DOWN: + type = AST_CHARGE; + break; + case CT_RECHARGE_SUCCESS: + type = RECHARGE_SUC; + // return 0; + break; + case CT_RECHARGE_FAIL: + type = RECHARGE_FAIL; + return 0; + break; + case CT_MO_SM: + type = SHORT_MESSAGE; + break; + case CT_CONFERENCE_CALL: + type = CONFERENCE_CALL; + break; + case CT_THIRD_PARTY_CHARGE: + type = SERVICE_CHARGE; + break; + case CT_BUNDLE_PLAN_CHARGE: + type = RENT_CHARGE; + break; + default: + return 0; + break; + } + index = pps_report.ptrTail; + + pps_report.daily_report[index].call_report.call_record[type].call_type = type; + if(type !=RECHARGE_SUC) + { + pps_report.daily_report[index].call_report.call_record[type].call_times ++; + pps_report.daily_report[index].call_report.call_record[type].call_duration += duration; + pps_report.daily_report[index].call_report.call_record[type].call_charge += charge; + pps_report.daily_report[index].call_report.total_call_num ++; + pps_report.daily_report[index].call_report.total_call_duration +=duration; + } + + if(type == RECHARGE_SUC || type== AST_RECHARGE){ + pps_report.daily_report[index].balance_summary.today_recharge = + pps_report.daily_report[index].balance_summary.today_recharge + charge; + } + else + { + pps_report.daily_report[index].balance_summary.today_charge += charge; + pps_report.daily_report[index].call_report.total_call_charge += charge; + } + + return 1; +} + +int reportAccount(int segmentno) +{ + int i,j,index,for_index,cos_id=0; + int balance; + double totalBalance=0; + + u_short status=0; + _prepaid_info *shmp=NULL; + COSTable *cosTableItem; + + PutLogFunID("reportAccount"); + + index = pps_report.ptrTail; + +// for(i=segmentno*100;i<(segmentno+1)*100;i++) + for(i=0;iprepaid_data.prepaid_info[i][j]; + if(shmp->msisdn[9]>2) + { + status = shmp->status; + shmp->free_sm_counter = 0; + shmp->gprsNotificationTimes = 0; + + if(OCS_with_external_CRM()) + { + //rent chage for CUG service + if(shmp->cug_id != NOT_CUG_ACCOUNT && shmp->crm_info.vas_cug_state == 0) + { + pps_send_rent_charge_to_crm(i, j); + } + } + + pps_report.daily_report[index].account_report.total_num ++; + pps_report.daily_report[index].account_report.total_balance = + totalBalance = totalBalance + + shmp->balance + + shmp->promo_balance; + pps_report.daily_report[index].account_report.user_num[status]++; + + cos_id = shmp->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(cosTableItem->tariff[0].capPlanResetDay == time_now[2] || cosTableItem->tariff[0].capPlanResetDay==0) + /*reset day=0 means CAP is daily based*/ + { + + shmp->in_net_cap_sms_balance = 0; + shmp->in_net_cap_sms_counter = 0; + shmp->out_net_cap_sms_balance = 0; + shmp->out_net_cap_sms_counter = 0; + + shmp->in_net_cap_balance = 0; + shmp->out_net_cap_balance = 0; + + shmp->in_net_cap_call_balance = 0; + shmp->in_net_cap_call_duration = 0; + shmp->out_net_cap_call_balance = 0; + shmp->out_net_cap_call_duration = 0; + + shmp->gprsBalance = 0; + shmp->gprsVolume = 0; + shmp->gprsVolumeThisMonth = 0; + + shmp->cap_sms_notify_counter = 0; + } + /* + if(shmp->bundle_info.validity_date < tvnow.tv_sec) + { + memset(&shmp->bundle_info, 0x00, sizeof(_bundle_info)); + } + */ + } + } + } + pps_report.daily_report[index].account_report.total_balance = + totalBalance; + balance = + (int)pps_report.daily_report[index].account_report.total_balance; + debugmib.report_sum[index][2] = balance; + + for_index = (index+6)%7; + balance = + (int)pps_report.daily_report[for_index].account_report.total_balance; + debugmib.report_sum[index][0] = balance; + + return 1; +} + +int reportPrepaidCard(int segmentno) +{ + int i,j; + int index=0,update_day=0,now_day=0; + long face_value; + + _prepaid_card_report *shmp=NULL; + + PutLogFunID("reportPrepaidCard"); + + if(UseExternalVC()) + return 1; + + if(OCS_with_external_CRM()) + return 1; + + now_day = (tvnow.tv_sec - timezone)/(24*3600); + + for(i=0;icard_data.segment_used_flag[i] == 0) + //{ + // continue; + //} + for(j=0;jcard_data.prepaid_card[i][j].card_no[MAX_CARD_LENGTH]>0) + { + face_value = ramshm_ptr->card_data.prepaid_card[i][j].face_value; + index = GetCardIndex(face_value); + if(index<0) continue; + + shmp = &pps_report.daily_report[pps_report.ptrTail].prepaid_card_report; + shmp->face_value[index] = face_value; + + + if(ramshm_ptr->card_data.prepaid_card[i][j].card_status == CARD_FRESH || + ramshm_ptr->card_data.prepaid_card[i][j].card_status == CARD_SUSPEND) + { + shmp->unused[index]++; + if(ramshm_ptr->card_data.prepaid_card[i][j].expiry_dateunused[index]--; + shmp->used_today[index]++; + MoveUsedCardToBuffer(i*MAX_CARD_NUM_PSEG+j); + } + } + else if(ramshm_ptr->card_data.prepaid_card[i][j].card_status == CARD_USED) + { + shmp->total_used[index]++; + update_day = (ramshm_ptr->card_data.prepaid_card[i][j].updated_date - timezone)/(24*3600); + if(now_day==(update_day+1)) + { + shmp->used_today[index]++; + } + else + { + MoveUsedCardToBuffer(i*MAX_CARD_NUM_PSEG+j); + } + }/* else */ + }/* if */ + }/* for j */ + }/* for i */ + return 1; +} + +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report +extern int yx_ussd_daily_report; +int GetUssdCodeDailyReportByIndex(u_char oidLen,DWORD *oid, + u_char *pdata, BYTE *vartype) +{ + int totalLen; + int index,saveIndex;//,yesterdayIndex; + int value=0,tag; + char buf[256]="",tagbuf[16]=""; + _daily_report *shmp=NULL, *shmp_peer = NULL; + ASN_BUF *asnbuf, asnbuf1; + + PutLogFunID("GetUssdCodeDailyReportByIndex"); + asnbuf = &asnbuf1; + AsnEncode(pdata,512,asnbuf); + + index = oid[14]; + saveIndex = index %7; + //yesterdayIndex = (saveIndex+7-1)%7; + + shmp = &pps_report.daily_report[saveIndex]; + shmp_peer = &pps_report.peer_daily_report[saveIndex]; + + sprintf(buf,"%04d-%02d-%02d", + shmp->year_month_day[0], + shmp->year_month_day[1], + shmp->year_month_day[2]); + totalLen = add_tlv("1", 10, (u_char *)buf, 0x80, asnbuf); + + PutLogFunID("GetDailyReportByIndex0"); + + strcpy(shmp->ussdcode_report[USSDCODE_TYPE_QUERY].code, USSDCODE_QUERY_CODE_STR); + strcpy(shmp->ussdcode_report[USSDCODE_TYPE_TOPUP].code, USSDCODE_TOPUP_CODE_STR); + strcpy(shmp->ussdcode_report[USSDCODE_TYPE_HOTLINE].code, USSDCODE_HOTLINE_CODE_STR); + + int i=0, offset=2, tagPerCode=8, codeLen=0; + for (i=0; iussdcode_report[i].code); + if (codeLen <= 0) + { + continue; + } + + tag = offset + tagPerCode*i; + sprintf(tagbuf,"%d",tag); + totalLen = add_tlv(tagbuf, codeLen, (u_char *)shmp->ussdcode_report[i].code,0x80,asnbuf); + + tag = offset + tagPerCode*i + 1; + value = shmp->ussdcode_report[i].req_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 2; + value = shmp->ussdcode_report[i].req_duration; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 3; + value = shmp->ussdcode_report[i].err_timeout_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 4; + value = shmp->ussdcode_report[i].err_system_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 5; + value = shmp->ussdcode_report[i].err_msg_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + } + + PutLogFunID("GetUssdCodeDailyReportByIndex1"); + + //printfDailyLog(saveIndex); + return totalLen; +} +#endif + +int GetDailyReport(u_char oidLen, DWORD *oid, u_char *pdata, BYTE *vartype) +{ + int ptrHead; + if(oidLen<14) return -1; + + PutLogFunID("GetDailyReport"); + + switch(oid[13]){ + case 0x01: + *vartype = 0x02; + ptrHead = pps_report.saveHead; + pdata[0] = ptrHead>>24; + pdata[1] = ptrHead>>16; + pdata[2] = ptrHead>>8; + pdata[3] = ptrHead; + return 4; + break; + case 0x02: + *vartype = 0x02; + ptrHead = pps_report.saveTail; + pdata[0] = ptrHead>>24; + pdata[1] = ptrHead>>16; + pdata[2] = ptrHead>>8; + pdata[3] = ptrHead; + return 4; + break; + case 0x03: + if(oidLen<15){ + printf("error oid len: %d\n",oidLen); + return -1; + } + + // if(!masterFlag) return -1; + if(oid[14]>=pps_report.saveTail) return -1; + return GetDailyReportByIndex(oidLen,oid,pdata,vartype); + break; +#if 0//def _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + case 0x04: + if(oidLen<15){ + printf("error oid len: %d\n",oidLen); + return -1; + } + + // if(!masterFlag) return -1; + if(oid[14]>=pps_report.saveTail) return -1; + return GetUssdCodeDailyReportByIndex(oidLen,oid,pdata,vartype); + break; +#endif + default: + return -1; + break; + } + + return 0; +} + +int GetPrepaidCardReport(int index, int valueIndex, int type) +{ + int value=0; + _daily_report *shmp=NULL; + + PutLogFunID("GetPrepaidCardReport"); + + if(index<0 || index>=7) return 0; + if(valueIndex<0 || valueIndex>=MAX_VALUE_TYPE) return 0; + if(type<0 || type>=3) return 0; + + shmp = &pps_report.daily_report[index]; + + if(UseExternalVC()) + { + ClearCleanUsedCardForDailyReport(index); + value = GetPrecardSumData(valueIndex,type); + } + else + { + switch(type) + { + case 0: + value = shmp->prepaid_card_report.face_value[valueIndex]; + break; + case 1: + value = shmp->prepaid_card_report.used_today[valueIndex]; + break; + case 2: + default: + value = shmp->prepaid_card_report.unused[valueIndex]; + break; + } + } + return value; +} + +int CountUsedCardForDailyReport(int charge) +{ + int i; + + _prepaid_card_report *ptr; + + ptr = &pps_report.daily_report[pps_report.ptrTail].prepaid_card_report; + for(i=0;iface_value[i] == charge) + { + ptr->used_today[i] ++; + return 1; + } + } + for(i=0;iface_value[i] == 0) + { + ptr->used_today[i] ++; + ptr->face_value[i] = charge; + return 1; + } + } + return 0; +} + +int GetDailyReportByIndex(u_char oidLen,DWORD *oid, + u_char *pdata, BYTE *vartype) +{ + int totalLen; + int index,saveIndex,i,yesterdayIndex; + int value=0,tag,start; + char buf[256]="",tagbuf[16]=""; + char balancebuf[32]="";// gprsBuf[256]={0}; + _daily_report *shmp=NULL, *shmp_peer = NULL; + long long gprsVal; + u_long vasVaule; + ASN_BUF *asnbuf, asnbuf1; + + PutLogFunID("GetDailyReportByIndex"); + asnbuf = &asnbuf1; + AsnEncode(pdata,512,asnbuf); + + index = oid[14]; + saveIndex = index %7; + yesterdayIndex = (saveIndex+7-1)%7; + + shmp = &pps_report.daily_report[saveIndex]; + shmp_peer = &pps_report.peer_daily_report[saveIndex]; + + sprintf(buf,"%04d-%02d-%02d", + shmp->year_month_day[0], + shmp->year_month_day[1], + shmp->year_month_day[2]); + totalLen = add_tlv("1", 10, (u_char *)buf, 0x80, asnbuf); + + PutLogFunID("GetDailyReportByIndex0"); + + gprsVal = shmp->call_report.gprs_record.gprsCharge + shmp_peer->call_report.gprs_record.gprsCharge+0.5; + + for(tag=2;tag<=30;tag++) + { + switch(tag){ + case 2: + if(pps_report.daily_report[yesterdayIndex].account_report.total_balance == 0){ + shmp->balance_summary.yesterday_balance = + shmp->account_report.total_balance+ + shmp->balance_summary.today_charge- + shmp->balance_summary.today_recharge+ + shmp_peer->balance_summary.today_charge- + shmp_peer->balance_summary.today_recharge; + + }else{ + shmp->balance_summary.yesterday_balance = + pps_report.daily_report[yesterdayIndex].account_report.total_balance; + } + sprintf(balancebuf,"%.0f", + shmp->balance_summary.yesterday_balance); + break; + case 3: + sprintf(balancebuf,"%.0f", + shmp->balance_summary.today_recharge+ + shmp_peer->balance_summary.today_recharge); + break; + case 4: + value = shmp->call_report.total_call_charge + + shmp_peer->call_report.total_call_charge+ + gprsVal; + sprintf(balancebuf,"%d",value); + /* + sprintf(balancebuf,"%.0f", + shmp->balance_summary.today_charge+ + shmp_peer->balance_summary.today_charge); + */ + break; + case 5: + shmp->balance_summary.today_balance = + shmp->account_report.total_balance; + /* + shmp->account_report.total_balance = + shmp->balance_summary.today_recharge + + shmp->balance_summary.yesterday_balance - + shmp->balance_summary.today_charge; + */ + + sprintf(balancebuf,"%.0f",shmp->account_report.total_balance); + break; + case 6: + value = shmp->account_report.user_num[0]; + break; + case 7: + value = shmp->account_report.user_num[1]; + break; + case 8: + value = shmp->account_report.user_num[2]; + break; + case 9: + value = shmp->account_report.user_num[3]; + break; + case 10: + value = shmp->account_report.user_num[4]; + break; + case 11: + value = shmp->account_report.user_num[5]; + break; + case 12: + value = shmp->account_report.total_num; + break; + case 13: + value = GetPrepaidCardReport(saveIndex, 0, 0); + break; + case 14: + value = GetPrepaidCardReport(saveIndex, 0, 1); + break; + case 15: + value = GetPrepaidCardReport(saveIndex, 0, 2); + break; + case 16: + value = GetPrepaidCardReport(saveIndex, 1, 0); + break; + case 17: + value = GetPrepaidCardReport(saveIndex, 1, 1); + break; + case 18: + value = GetPrepaidCardReport(saveIndex, 1, 2); + break; + case 19: + value = GetPrepaidCardReport(saveIndex, 2, 0); + break; + case 20: + value = GetPrepaidCardReport(saveIndex, 2, 1); + break; + case 21: + value = GetPrepaidCardReport(saveIndex, 2, 2); + break; + case 22: + value = GetPrepaidCardReport(saveIndex, 3, 0); + break; + case 23: + value = GetPrepaidCardReport(saveIndex, 3, 1); + break; + case 24: + value = GetPrepaidCardReport(saveIndex, 3, 2); + break; + case 25: + value = GetPrepaidCardReport(saveIndex, 4, 0); + break; + case 26: + value = GetPrepaidCardReport(saveIndex, 4, 1); + break; + case 27: + value = GetPrepaidCardReport(saveIndex, 4, 2); + break; + case 28: + value = GetPrepaidCardReport(saveIndex, 5, 0); + break; + case 29: + value = GetPrepaidCardReport(saveIndex, 5, 1); + break; + case 30: + value = GetPrepaidCardReport(saveIndex, 5, 2); + break; + default: + break; + } + sprintf(tagbuf,"%d",tag); + if(tag<6){ + totalLen = add_tlv(tagbuf, strlen(balancebuf), (u_char *)balancebuf, 0x80, asnbuf); + }else{ + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + } + } + i=0; + start = 31; + for(tag=start;tag<(start+12*3);) /* 60 ,2003-10-21 */ + { + value = shmp->call_report.call_record[i].call_times + + shmp_peer->call_report.call_record[i].call_times; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + value = shmp->call_report.call_record[i].call_duration + + shmp_peer->call_report.call_record[i].call_duration; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + value = shmp->call_report.call_record[i].call_charge + + shmp_peer->call_report.call_record[i].call_charge; + i++; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + } + start += 12*3; + tag = start; /*tag = 67 */ + value = shmp->call_report.total_call_num + + shmp_peer->call_report.total_call_num; + sprintf(tagbuf,"%d",tag); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag ++; + value = shmp->call_report.total_call_duration + + shmp_peer->call_report.total_call_duration; + sprintf(tagbuf,"%d",tag); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + tag ++; + value = shmp->call_report.total_call_charge + + shmp_peer->call_report.total_call_charge + 0.5; + sprintf(tagbuf,"%d",tag); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = 70; + sprintf(tagbuf,"%d",tag); + gprsVal = shmp->call_report.gprs_record.gprsVolume + shmp_peer->call_report.gprs_record.gprsVolume; + sprintf(balancebuf,"%lld",gprsVal); + totalLen = add_tlv(tagbuf, strlen(balancebuf), (u_char *)balancebuf, 0x80, asnbuf); + + tag = 71; + sprintf(tagbuf,"%d",tag); + gprsVal = shmp->call_report.gprs_record.gprsDuration + shmp_peer->call_report.gprs_record.gprsDuration; + sprintf(balancebuf,"%lld",gprsVal); + totalLen = add_tlv(tagbuf, strlen(balancebuf), (u_char *)balancebuf, 0x80, asnbuf); + + tag = 72; + sprintf(tagbuf,"%d",tag); + gprsVal = shmp->call_report.gprs_record.gprsCharge + shmp_peer->call_report.gprs_record.gprsCharge+0.5; + sprintf(balancebuf,"%lld",gprsVal); + totalLen = add_tlv(tagbuf, strlen(balancebuf), (u_char *)balancebuf, 0x80, asnbuf); + + /*********************** VAS daily report **************************/ + tag = 78; + sprintf(tagbuf,"%d",tag); + vasVaule = shmp->call_report.vas_record.smsNumber + shmp_peer->call_report.vas_record.smsNumber; + sprintf(balancebuf,"%ld",vasVaule); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + + tag = 79; + sprintf(tagbuf,"%d",tag); + gprsVal = shmp->call_report.vas_record.smsCharge + shmp_peer->call_report.vas_record.smsCharge; + sprintf(balancebuf,"%lld",gprsVal); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + + tag = 80; + sprintf(tagbuf,"%d",tag); + vasVaule = shmp->call_report.vas_record.mmsSendNumber + shmp_peer->call_report.vas_record.mmsSendNumber; + sprintf(balancebuf,"%ld",vasVaule); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + + tag = 81; + sprintf(tagbuf,"%d",tag); + gprsVal = shmp->call_report.vas_record.mmsSendCharge + shmp_peer->call_report.vas_record.mmsSendCharge; + sprintf(balancebuf,"%lld",gprsVal); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + + tag = 82; + sprintf(tagbuf,"%d",tag); + vasVaule = shmp->call_report.vas_record.mmsRetrieveNumber + shmp_peer->call_report.vas_record.mmsRetrieveNumber; + sprintf(balancebuf,"%ld",vasVaule); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + + tag = 83; + sprintf(tagbuf,"%d",tag); + gprsVal = shmp->call_report.vas_record.mmsRetrieveCharge + shmp_peer->call_report.vas_record.mmsRetrieveCharge; + sprintf(balancebuf,"%lld",gprsVal); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + + tag = 84; + sprintf(tagbuf,"%d",tag); + vasVaule = shmp->call_report.vas_record.mmsEmailNumber + shmp_peer->call_report.vas_record.mmsEmailNumber; + sprintf(balancebuf,"%ld",vasVaule); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + + tag = 85; + sprintf(tagbuf,"%d",tag); + gprsVal = shmp->call_report.vas_record.mmsEmailCharge + shmp_peer->call_report.vas_record.mmsEmailCharge; + sprintf(balancebuf,"%lld",gprsVal); + totalLen = add_tlv(tagbuf,strlen(balancebuf), (u_char *)balancebuf,0x80,asnbuf); + /*********************** VAS daily report **************************/ + +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + if (yx_ussd_daily_report == 0) + { + return totalLen; + } + int offset=86, tagPerCode=8, codeLen=0; + for (i=0; iussdcode_report[i].code); + if (codeLen <= 0) + { + //continue; + } + + tag = offset + tagPerCode*i; + sprintf(tagbuf,"%d",tag); + totalLen = add_tlv(tagbuf, codeLen, (u_char *)shmp->ussdcode_report[i].code,0x80,asnbuf); + + tag = offset + tagPerCode*i + 1; + value = shmp->ussdcode_report[i].req_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 2; + value = shmp->ussdcode_report[i].req_duration; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 3; + value = shmp->ussdcode_report[i].err_timeout_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 4; + value = shmp->ussdcode_report[i].err_system_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 5; + value = shmp->ussdcode_report[i].err_msg_count; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 6; + value = 0; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + + tag = offset + tagPerCode*i + 7; + value = 0; + sprintf(tagbuf,"%d",tag++); + totalLen = AddInteger(tagbuf,value,0x80,asnbuf); + } +#endif + PutLogFunID("GetDailyReportByIndex2"); + + //printfDailyLog(saveIndex); + return totalLen; +} + +int printfDailyLog(int index) +{ + _daily_report *shmp=NULL, *shmp_peer=NULL; + + int i; + + PutLogFunID("printfDailyLog"); + + shmp = &pps_report.daily_report[index]; + shmp_peer = &pps_report.peer_daily_report[index]; + printf("------------------------------------------\n"); + printf("Time: %04d-%02d-%02d\n", + shmp->year_month_day[0], + shmp->year_month_day[1], + shmp->year_month_day[2]); + + printf("account report\n"); + printf(" Fresh: %05ld\n",shmp->account_report.user_num[0]); + printf(" Normal: %05ld\n",shmp->account_report.user_num[1]); + printf(" Suspend: %05ld\n",shmp->account_report.user_num[2]); + printf(" Blacklisted: %05ld\n",shmp->account_report.user_num[3]); + printf(" Released: %05ld\n",shmp->account_report.user_num[4]); + printf(" Total: %05ld\n",shmp->account_report.total_num); + printf(" Total balance: %.0f\n",shmp->account_report.total_balance); + printf(" Yesterday balance: %.0f\n",shmp->balance_summary.yesterday_balance); + printf(" today recharge: %.0f\n",shmp->balance_summary.today_recharge+ + shmp_peer->balance_summary.today_recharge); + printf(" today charge: %.0f\n",shmp->balance_summary.today_charge+ + shmp_peer->balance_summary.today_charge); + + printf("prepaid card report\n"); + for(i=0;iprepaid_card_report.face_value[i]); + printf("used today: %05ld\n",shmp->prepaid_card_report.used_today[i]); + printf("total used: %05ld\n",shmp->prepaid_card_report.total_used[i]); + printf("unused: %05ld\n",shmp->prepaid_card_report.unused[i]); + } + + printf("call statistics\n"); + for(i=0;i<11;i++) + { + printf("call type:%s\n",call_type_name[i]); + printf("call times: %03ld\n",shmp->call_report.call_record[i].call_times+shmp_peer->call_report.call_record[i].call_times); + printf("call duration: %03ld\n",shmp->call_report.call_record[i].call_duration+shmp_peer->call_report.call_record[i].call_duration); + printf("call charge: %.0f\n",shmp->call_report.call_record[i].call_charge+shmp_peer->call_report.call_record[i].call_charge); + } + printf("------------------------------------------\n"); + return 1; +} + +/* --- couple of functions --- */ +void SaveDailyReport() +{ + char fileName[]="../log/dailyreport.bak"; + FILE *fpBak = NULL; + int index; + + fpBak = fopen(fileName,"w"); + if(fpBak == NULL) return; + index = pps_report.ptrTail; + + fwrite(&pps_report.daily_report[index],sizeof(_daily_report),1,fpBak); + fclose(fpBak); + SendDailyReportToPeerServerForStop(); +} + +int LoadDailyReport() +{ + char fileName[]="../log/dailyreport.bak"; + FILE *fpBak = NULL; + int index; + + fpBak = fopen(fileName,"r"); + if(fpBak == NULL) return 0; + index = pps_report.ptrTail; + + fread(&pps_report.daily_report[index],sizeof(_daily_report),1,fpBak); + fclose(fpBak); + if(pps_report.daily_report[index].year_month_day[0] !=time_now[0] || + pps_report.daily_report[index].year_month_day[1] !=time_now[1] || + pps_report.daily_report[index].year_month_day[2] !=time_now[2] ) + { + memset(&pps_report.daily_report[index],0,sizeof(_daily_report)); + pps_report.daily_report[pps_report.ptrTail].year_month_day[0]=time_now[0]; + pps_report.daily_report[pps_report.ptrTail].year_month_day[1]=time_now[1]; + pps_report.daily_report[pps_report.ptrTail].year_month_day[2]=time_now[2]; + } + + + return 1; +} + +/* --- end of couple of functions --- */ + +/* --- couple of functions --- */ +_prepaid_card_report tmpCardReport; +int ClearCleanUsedCardForDailyReport(int index) +{ + int i, j; + int flag[MAX_VALUE_TYPE]; + + PutLogFunID("ClearCleanUsedCardForDailyReport"); + + if(index<0 || index>=MAX_RECORDS_SAVED) + return -1; + + memset(flag,0x00,sizeof(int)* MAX_VALUE_TYPE); + memcpy(&tmpCardReport, + &pps_report.daily_report[index].prepaid_card_report, + sizeof(_prepaid_card_report)); + + for(i=0;i=MAX_VALUE_TYPE) return 0; + if(type<0 || type>=3) return 0; + + switch(type) + { + case 0: + value = tmpCardReport.face_value[index]; + break; + case 1: + value = tmpCardReport.used_today[index]; + break; + default: + value = tmpCardReport.unused[index]; + break; + } + return value; +} + +int ReadDailyReportFromPeerServer() +{ + int index; + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + PutLogFunID("ReadDailyReportFromPeerServer"); + + + index = pps_report.ptrTail; + + snmpbuf.pdu_type = PDU_GET; //trap + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; + snmpaddr.remote_port = HEART_BEATING_PORT; + snmpaddr.local_port = HEART_BEATING_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 14; + varlist->vartype = 0x04; + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x01; + varlist->oid[12] = 0x04; + varlist->oid[13] = index;// + + varlist->msglen = 0; + snmp_send(&snmpbuf,&snmpaddr); + + return 1; +} + +int ReadDailyReportRequest(u_char oidLen,DWORD *oid,u_char *pdata,BYTE *vartype) +{ + int index; + + PutLogFunID("ReadDailyReportRequest"); + if(oidLen<14) return -1; + index = oid[13]; + if(index<0 || index>=MAX_RECORDS_SAVED) return -1; + + memcpy(pdata, + &pps_report.daily_report[index], + sizeof(_daily_report)); + return sizeof(_daily_report); +} + +#if _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report +int pps_update_ussd_code_state(char *code, int type, int result, int dur) +{ + _ussdcode_report *shmp = NULL; + int index = pps_report.ptrTail % MAX_RECORDS_SAVED, i; + switch (type) + { + case USSDCODE_TYPE_QUERY: + shmp = &pps_report.daily_report[index].ussdcode_report[USSDCODE_TYPE_QUERY]; + break; + case USSDCODE_TYPE_TOPUP: + shmp = &pps_report.daily_report[index].ussdcode_report[USSDCODE_TYPE_TOPUP]; + break; + case USSDCODE_TYPE_HOTLINE: + shmp = &pps_report.daily_report[index].ussdcode_report[USSDCODE_TYPE_HOTLINE]; + break; + case USSDCODE_TYPE_CHANNEL: + for (i=USSDCODE_TYPE_CHANNEL; ireq_count++; + break; + case USSDCODE_STAT_DUR: + shmp->req_duration += (dur / CYCLE_STATE_INTERVAL); + break; + case USSDCODE_STAT_ERR_TIMEOUT: + if (dur > 0) + { + shmp->req_duration += (dur / CYCLE_STATE_INTERVAL); + } + shmp->err_timeout_count ++; + break; + case USSDCODE_STAT_ERR_SYSTEM: + if (dur > 0) + { + shmp->req_duration += (dur / CYCLE_STATE_INTERVAL); + } + shmp->err_system_count ++; + break; + case USSDCODE_STAT_ERR_MSG: + if (dur > 0) + { + shmp->req_duration += (dur / CYCLE_STATE_INTERVAL); + } + shmp->err_msg_count ++; + break; + default: + return 0; + } + + return 1; +} +#endif + +int GetDailyReportResponse(snmp_pdu *pdu, snmp_addr *addr) +{ + + int readDailyReportResponseIndex = pdu->var[0].oid[13]; + + PutLogFunID("GetDailyReportResponse"); + + getDailyReportResponseFlag = 1; + + if(readDailyReportResponseIndex>=MAX_RECORDS_SAVED) return 0; + if(pdu->var[0].msglen != sizeof(_daily_report)) return 0; + + memcpy(&pps_report.peer_daily_report[readDailyReportResponseIndex], + pdu->var[0].msg, + sizeof(_daily_report)); + + if(UseExternalVC()) + { + // ClearCleanUsedCardForDailyReport(readDailyReportResponseIndex); + } + //printfDailyLog(readDailyReportResponseIndex); + return 1; +} +/* --- end of couple of functions --- */ + +/* --- couple of functions --- */ +int SendDailyReportToPeerServerForStop() +{ + int index; + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + PutLogFunID("SendDailyReportToPeerServerForStop"); + + index = pps_report.ptrTail; + + snmpbuf.pdu_type = 0x07; //trap + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; + snmpaddr.remote_port = HEART_BEATING_PORT; + snmpaddr.local_port = HEART_BEATING_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 13; + varlist->vartype = 0x04; + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x08; + //varlist->oid[12] = 0x04; + varlist->oid[12] = index;// + + varlist->msglen = sizeof(_daily_report); + memcpy(varlist->msg, + (u_char *)&pps_report.daily_report[index], + sizeof(_daily_report)); + snmp_send(&snmpbuf,&snmpaddr); + + return 1; +} + +int GotSyncDailyReport(DWORD *oid,u_char *pdata,u_short dataLen) +{ + + int index = oid[12]; + + PutLogFunID("GotSyncDailyReport"); + + + if(index>=MAX_RECORDS_SAVED) return 0; + if(dataLen != sizeof(_daily_report)) return 0; + + memcpy(&pps_report.peer_daily_report[index], + pdata, + sizeof(_daily_report)); + + //printfDailyLog(index); + return 1; +} + +/* --- end of couple functions --- */ + + +void PPSSendUserSMSNotification(int head, int tail,char *msgSend) +/* head, tail is the account store index, msgSend is the notfication content */ +{ + char calledMSISDN[32]=""; + int len,msglen=0; + _prepaid_info *shmp=NULL; + + if (head >= MSISDN_HEAD_NUM || tail >= UNIT_STORE_ACCOUNT) + return; + msglen = strlen(msgSend); + if(msglen<=0) + return; + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + BcdToAscii(calledMSISDN,shmp->msisdn,(MAX_MSISDN_BLEN-1)*2); + calledMSISDN[len] = 0; + + + smppSendMOSM(calledMSISDN, + (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, + (u_char *)msgSend, + msglen, + 0); +} + +extern int pps_crm_get_notify_days(); +extern int pps_crm_get_status_vd(); +extern void pps_send_update_subs_status_to_crm(_prepaid_info *user_ptr, int update_flag); +int AccountExpiredDateCheck_crm(_prepaid_info *user_ptr, int instance) +{ + int send_notify_days = pps_crm_get_notify_days(); + int status = user_ptr->status; + int crm_update_user_status=0, crm_send_expired_notification=0; + u_long expired_secs = user_ptr->mo_expiration_date; + long status_changed_seconds = (30*24*3600); + + if(user_ptr->crm_info.user_class == 0x02)//tourist + { + status_changed_seconds = (1*24*3600 ); + } + else + { + int status_vd = pps_crm_get_status_vd(); + + if(status_vd>0) + { + status_changed_seconds = (status_vd * 24 * 3600); + } + } + + switch(status) + { + case T_NORMAL: + status_changed_seconds = 0;//status_changed_seconds; + break; + case T_SUSPEND: + status_changed_seconds *= 1; + break; + case T_DISABLE: + status_changed_seconds *= 2; + break; + } + + if((expired_secs + status_changed_seconds )< tvnow.tv_sec) + { + crm_update_user_status = 1; + } + + if(status == T_NORMAL) + { + if( crm_update_user_status == 1) + { + user_ptr->status = T_SUSPEND; + } + else + { + if(send_notify_days>=1) + { + if ((expired_secs > ( (send_notify_days-1)*24*3600 + tvnow.tv_sec)) && (expired_secs < ( send_notify_days*24*3600 + tvnow.tv_sec))) + { + crm_send_expired_notification = 1; + } + } + } + } + else if(status == T_SUSPEND) + { + if( crm_update_user_status == 1) + { + user_ptr->status = T_DISABLE; + } + } + else if(status == T_DISABLE) + { + if( crm_update_user_status == 1) + { + user_ptr->status = T_RELEASED; + } + } + +// if(crm_update_user_status ) +// user_ptr->mo_expiration_date = tvnow.tv_sec; + + if(!masterFlag) return 0; + + if(crm_update_user_status ) + { + pps_send_update_subs_status_to_crm(user_ptr, 1); + } + else + { + if(crm_send_expired_notification) + { + pps_send_update_subs_status_to_crm(user_ptr, 2); + } + } + + if(user_ptr->status == T_RELEASED) + //if(status == T_DISABLE) + { + char msisdn[32]; + int len = user_ptr->msisdn[MAX_MSISDN_BLEN-1]; + BcdToAscii(msisdn, user_ptr->msisdn,(MAX_MSISDN_BLEN-1)*2); + msisdn[len] = 0; + + DebugMsg(debugmib.display.asciiOut,"%s.%d try to delete RELEASED account: msisdn=%s, instance=%d", + __FUNCTION__, __LINE__, msisdn, instance); + + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_DEL); + } + + return 1; +} + +int AccountExpiredDateCheck() +{ + static u_long LatchIndex=0; + int i, j, balance, cos_id, storeIndex; + u_short status=0, expiredFlag = 0; + int len; + char caller_number[32]; + int crm_update_user_status=0; + COSTable *cosTableItem; + PutLogFunID("AccountExpiredDateCheck"); + + + + if(time_now[3](PERIODIC_CHARGE_HOUR+1)) { + LatchIndex = 0; + return 0; + } + + i=LatchIndex/UNIT_STORE_ACCOUNT; + j=LatchIndex%UNIT_STORE_ACCOUNT; + storeIndex = LatchIndex; + if(LatchIndex ++>=MSISDN_HEAD_NUM*UNIT_STORE_ACCOUNT) + { + return 0;// LatchIndex = 0; + } + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn[9]prepaid_data.prepaid_info[i][j].status; + if(status == T_FRESH) return 1; + + if(OCS_with_external_CRM()) + return AccountExpiredDateCheck_crm(&ramshm_ptr->prepaid_data.prepaid_info[i][j], storeIndex); + + cos_id = ramshm_ptr->prepaid_data.prepaid_info[i][j].cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + if(cosTableItem->accountValidity[0].actionWhenMOorMTExpired == 0) /* MO */ + { + if((ramshm_ptr->prepaid_data.prepaid_info[i][j].mo_expiration_date+ + cosTableItem->accountValidity[0].daysKeepingAnExpiredAccount*24*3600)prepaid_data.prepaid_info[i][j].mt_expiration_date+ + cosTableItem->accountValidity[0].daysKeepingAnExpiredAccount*24*3600)prepaid_data.prepaid_info[i][j].status = T_RELEASED; + crm_update_user_status = 1; + + if(cosTableItem->accountValidity[0].actionAfterDaysKeepingAnExpiredAccount) + { + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].balance>0) + { + balance = ramshm_ptr->prepaid_data.prepaid_info[i][j].balance; + ramshm_ptr->prepaid_data.prepaid_info[i][j].balance = 0; + if(masterFlag) + { + SendOperatorRechargeCDR(i,j,-balance); + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenCleanBalance) + { + PPSSendUserSMSNotification(i, j, (char *)getSmsSentenceNative(0,SMS_CLEAR_FEE_NOTIFY)); + } + } + } + } + } + else if(ramshm_ptr->prepaid_data.prepaid_info[i][j].mt_expiration_dateprepaid_data.prepaid_info[i][j].status = T_SUSPEND; + crm_update_user_status = 1; + + } + if(cosTableItem->accountValidity[0].actionWhenAccountExpires) + { + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].balance>0) + { + balance = ramshm_ptr->prepaid_data.prepaid_info[i][j].balance; + ramshm_ptr->prepaid_data.prepaid_info[i][j].balance = 0; + if(masterFlag) + { + SendOperatorRechargeCDR(i,j,-balance); + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenCleanBalance) + { + PPSSendUserSMSNotification(i, j, (char *)getSmsSentenceNative(0,SMS_CLEAR_FEE_NOTIFY)); + } + } + } + } + } + + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_date< + tvnow.tv_sec) + { + + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance >0) + { + balance = ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance; + ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance = 0; + if(masterFlag) + SendOperatorRechargeCDR(i,j,-balance); + } + } + + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].bundle_info.validity_date > 10) + { + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].bundle_info.validity_date < tvnow.tv_sec) + { + len = ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn[MAX_MSISDN_BLEN-1]; + + BcdToAscii(caller_number, ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn, (MAX_MSISDN_BLEN-1)*2); + caller_number[len ] = '\0'; + + if (ramshm_ptr->prepaid_data.prepaid_info[i][j].bundle_info.data > 0) + { + subscribe_bundle_plan_send_used_up_info(caller_number, SMS_BUNDLE_PLAN_DATA_USEDUP); + } + + memset(&ramshm_ptr->prepaid_data.prepaid_info[i][j].bundle_info, 0x00, sizeof(_bundle_info)); + } + } + + if(crm_update_user_status ) + { + if(OCS_with_external_CRM()) + pps_send_update_subs_status_to_crm(&ramshm_ptr->prepaid_data.prepaid_info[i][j], 1); + } + status = ramshm_ptr->prepaid_data.prepaid_info[i][j].status; + if(status != T_NORMAL) return 1; + + if(!IsPromotionTime(cosTableItem,tvnow)) + { + ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag &=0xFB; + } + + + return 1; +} + +int AccountLatchFlagCheck(int head, int tail) +{ + int i,j ,len,cos_id; + u_short smPromptFlag=0; + char expire_date[128]="",promotion_expire_date[128]="",msisdn[128]=""; + COSTable *cosTableItem; + + PutLogFunID("AccountLatchFlagCheck"); + + i = head; + j = tail; + + smPromptFlag = 0; + + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn[9]prepaid_data.prepaid_info[i][j].cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].balance< + cosTableItem->smsNotificationInquiry[0].insufficientBalanceThreshold) + { + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenBalanceInsufficient) + if(!(ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag & 0x01)) + { + ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag |=0x01; + smPromptFlag = 1; + } + } + else + { + ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag &=0xFE; + } + + + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].mo_expiration_date< + (cosTableItem->smsNotificationInquiry[0].theDaysSendingSMSBeforeExpiredDay) + *24*3600+tvnow.tv_sec) + { + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenExpired) + if(!(ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag & 0x02)) + { + ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag |=0x02; + smPromptFlag = 1; + } + } + else + { + ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag &=0xFD; + } + + + if(smPromptFlag ) + { + len = ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn[9]; + if(len % 2==1) + { + len ++; + BcdToAscii(msisdn, + ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn, + len); + msisdn[len-1] = 0; + } + else + { + BcdToAscii(msisdn, + ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn, + len); + msisdn[len] = 0; + } + + AsciiTime(expire_date, + ramshm_ptr->prepaid_data.prepaid_info[i][j].mo_expiration_date); + + AsciiTime(promotion_expire_date, + ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_date); + + smppSendAccountInfo(msisdn, + ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, + (long)ramshm_ptr->prepaid_data.prepaid_info[i][j].balance,expire_date, + (long)ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance,promotion_expire_date, + 0,"","", + (0x80 | ramshm_ptr->prepaid_data.prepaid_info[i][j].language_type )); + return 1; + } + + return 0; +} + +int CheckPromotionLatchFlag(_account_info *pInfo) +{ + int i,j ,len,cos_id,loop; + char msisdn[32]=""; + char promo_msg[256] = "", newsSMS[512] = ""; + char *bufPtr[3],buf[3][32]; + //float fValue=0; + COSTable *cosTableItem; + + PutLogFunID("CheckPromotionLatchFlag"); + + i = pInfo->head; + j=pInfo->tail; + if(ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn[MAX_MSISDN_BLEN-1]prepaid_data.prepaid_info[i][j].msisdn[MAX_MSISDN_BLEN-1]>MAX_MSISDN_ALEN) + return 1; + + cos_id = ramshm_ptr->prepaid_data.prepaid_info[i][j].cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + sprintf(promo_msg, "%s", (char *)getSmsSentenceNative(0,SMS_PROMOTION_NEWS)); + if(strlen(promo_msg)==0 || strcasecmp(promo_msg,"NULL")==0) + return 1; + + if(IsPromotionTime(cosTableItem,tvnow)) + { + if((ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag & 0x04)) + { + return 0; + } + else + { + ramshm_ptr->prepaid_data.prepaid_info[i][j].latch_flag |=0x04; + } + } + else + return 0; + + SendAccountRealSync(i*UNIT_STORE_ACCOUNT+j,0.0,0.0,OMC_OCODE_EDIT); + len = ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn[MAX_MSISDN_BLEN-1]; + + if(len % 2==1) + { + len ++; + BcdToAscii(msisdn, + ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn, + len); + msisdn[len-1] = 0; + } + else + { + BcdToAscii(msisdn, + ramshm_ptr->prepaid_data.prepaid_info[i][j].msisdn, + len); + msisdn[len] = 0; + } + + bufPtr[0] = buf[0]; + bufPtr[1] = buf[1]; + bufPtr[2] = buf[2]; + + for(loop=0;looprechargePromotion[loop].rechargeCardCredit>0 && + cosTableItem->rechargePromotion[loop].promotionBonus>0) + { + sprintf(promo_msg, "%s", (char *)getSmsSentenceNative(0,SMS_PROMOTION_NEWS)); + /* + fValue = (float)cosTableItem->rechargePromotion[loop].rechargeCardCredit; + fillMoneyToContentWithoutCurrency(fValue,buf[0]); + fValue = (float)cosTableItem->rechargePromotion[loop].promotionBonus; + fillMoneyToContentWithoutCurrency(fValue,buf[1]); + */ + switch(ppsParam.ppsTables.promptResolution[0].currencyResolution) + { + case 0: + sprintf(buf[0],"%d",cosTableItem->rechargePromotion[loop].rechargeCardCredit); + sprintf(buf[1],"%d",cosTableItem->rechargePromotion[loop].promotionBonus); + break; + case 1: + sprintf(buf[0],"%.1f",cosTableItem->rechargePromotion[loop].rechargeCardCredit/10.0); + sprintf(buf[1],"%.1f",cosTableItem->rechargePromotion[loop].promotionBonus/10.0); + break; + case 2: + default: + sprintf(buf[0],"%.2f",cosTableItem->rechargePromotion[loop].rechargeCardCredit/100.0); + sprintf(buf[1],"%.2f",cosTableItem->rechargePromotion[loop].promotionBonus/100.0); + break; + } + if(cosTableItem->rechargePromotion[loop].promotionValidity>0) + { + sprintf(buf[2],"%d",cosTableItem->rechargePromotion[loop].promotionValidity); + sprintf(newsSMS,"%s",ppsParseSentence(promo_msg,3,bufPtr)); + } + else + { + sprintf(newsSMS,"%s",ppsParseSentence(promo_msg,2,bufPtr)); + } + smppSendMOSM(msisdn, + (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, + (u_char *)newsSMS, + strlen(newsSMS), + 0); + } + } + + + return 1; +} + diff --git a/mss/pps/src/main/feeTransfer.c b/mss/pps/src/main/feeTransfer.c new file mode 100644 index 0000000..a829ce5 --- /dev/null +++ b/mss/pps/src/main/feeTransfer.c @@ -0,0 +1,2350 @@ +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + +#include "../include/plat_inc.h" +#include "../../../../plat/scf/src/include/scfmsg.h" +#include "../../../../plat/scf/src/include/scfdef.h" + + +#include "../include/ppsMibTable.h" +#include "../include/mfunc.h" +#include + +extern PPSParamStruct ppsParam; +extern struct timeval tvnow; +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr;; + +extern int SendUSSDRequest(u_short portid, char *ussd_info); +extern int smppSendMsg(u_char *peerNumber,u_char *msg,u_char serviceNumPosition); + + +extern int StuffCapMessage(CapArg capArg, PCAP_Message pcap_message); +extern int ppsDebugCapMsg(CAP_Message *cap_message,int flag); +extern BOOL isPromotionCanBeTransfered(_account_info *accountInfo); +extern BOOL isPromotionFirstTransfered(_account_info *accountInfo); + +extern void SendManualOperationCDR(_account_info *caller_info,_account_info *called_info,int charge); +extern int get_transfer_resolution(); + +extern u_short debug_messages; +extern int logMsgFlag; + + +static double feeAsciiToFloat(u_char *fee); + +ulong getSystemCurrencyResolution(); + +#define MAX_FEE_LENGTH 7 + +enum transfeeAccountState +{ + S_TRANSFER_IDLE, + S_INPUT_DESTNUMBER, + S_WART_INPUT_DESTNUMBER, + S_INPUT_DESTNUMBER_AGAIN, + S_WART_INPUT_DESTNUMBER_AGAIN, + S_MATCH_DESTNUMBER, + S_DESTNUMBER_NOT_MATCHED, + S_TRANSFER_CHECK_DSTNUMBER, + S_TRANSFER_CHECK_TRANSFERED_FEE, + S_FULL_PARTIAL_TRANSFER_CHOICE, + S_WAIT_FULL_PARTIAL_TRANSFER_CHOICE, + S_INPUT_FEE_TRANSFERED, + S_WAIT_INPUT_FEE_TRANSFERED, + S_PLAY_TRANSFERED_FEE_ERROR, + S_WRONG_INPUT_FEE, + S_TRANSFER_CONFIRM, + S_PLAY_TRANSFER_CONFIRM_SUCCESS, + S_WAIT_TRANSFER_CONFIRM, + S_TRANSFER_PROCESSING, + S_PLAY_TRANSFERED_FEE_SUCCESS, + S_CHECK_USSD_INPUT, + S_USSD_FT_ALL_IN_ONE_INPUT, + S_USSD_FT_REST_START, + S_TRANSFER_EXIT, +}; + + +enum transfer_mode{ + FULL_TRANSFER_MODE, + PARTIAL_TRANSFER_MODE, +}; + + +#define changeTransferState(portid,val) do { \ + feeTransfer = &shmp->process_info.ppsService.feeTransfer;\ + feeTransfer->state = val;\ + shmp->process_info.serviceInput = 0;\ + shmp->process_info.funnel = 0;\ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + +u8 getTransferState(u_short portid) +{ + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + return shmp->process_info.ppsService.feeTransfer.state; +} + +void playPromptAndCollectVoice(u_short portid,u_short voiceID,u8 inputLen) +{ + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = voiceID; + shmp->process_info.maxPCUInfoLen = inputLen; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); +} + + void playPromptVoice(u_short portid,u_short voiceID) +{ + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = voiceID; + SendSrfPlayAnnouncement(portid); +} + +void clearTransferInfo(u_short portid) +{ + _state_data *shmp; + + PutLogFunID("clearTransferInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + memset(&shmp->process_info.ppsService.feeTransfer,0,sizeof(TRANSFER_FEE)); +} + + +int WaitingForInput(_state_data *shmp,u8 *inputMsg) +{ + int retval = NO_INPUT,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + PutLogFunID("WaitingForInputTransferOutAccount"); + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = INPUT_ERROR_EXIT); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len > MAX_IVR_INPUT_LEN) + len = MAX_IVR_INPUT_LEN; + + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + ppsBcdToAsciiR((char *)inputMsg,&pPCUI->digitsResponse[2],2*(len-1)); + StringCut((char *)inputMsg,'F'); + retval = INPUT_SUCCESS; + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = INPUT_ERROR_EXIT; + break; + } + return retval; +} + +static double asciiFeeToFloat(u_char *feeChar) +{ + u_char *pFloat; + double value; + u8 i,len,Btimes = 0; + + len = strlen((char *)feeChar); + if(strlen((char *)feeChar) > MAX_FEE_LENGTH) + return -1; + for(i = 0;i < len;i++) + {/* only '0' - '9' and 'B' are allowed */ + if(feeChar[i] == 'B') + Btimes++; + if(feeChar[i] < '0' && feeChar[i] > '9' && feeChar[i] != 'B') + return -1; + } + + if(Btimes > 1)/* 'B' only one time */ + return -1; + + if(feeChar[0] == 'B') + return -1; + + pFloat = (u_char *)strchr((char *)feeChar,'B'); + if(pFloat != NULL) + *pFloat = '.'; + + value = feeAsciiToFloat(feeChar); + if(value <= 0) + return -1; + return value; +} + +ulong getSystemCurrencyResolution() +{ + long resolution; + + switch(ppsParam.ppsTables.promptResolution[0].currencyResolution) + { + case 0: + resolution = 1; + break; + case 1: + resolution = 10; + break; + case 2: + default: + resolution = 100; + break; + + } + return resolution; +} + +static int WaitingForInputTransferOutFee(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + double fee; + ulong resolution = 1; + int result; + + PutLogFunID("WaitingForInputTransferOutFee"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + fee = asciiFeeToFloat(input_msg); + if(fee <= 0 ) + return 2;/* format error */ + if(get_transfer_resolution()) + resolution = getSystemCurrencyResolution(); + + shmp->process_info.ppsService.feeTransfer.fee = (int)(fee*resolution); + + return result; +} + +int WaitingForInputTransferOutAccount(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + + PutLogFunID("WaitingForInputTransferOutFee"); + + memset(input_msg,0,64); + if(shmp->process_info.ussd_transfer_one_input_flag ==1 ) + { + result = INPUT_SUCCESS; + strcpy((char *)input_msg, shmp->process_info.tmpDigits); + } + else + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + CutUnknownPrefix((char *)input_msg); + if((strlen((char *)input_msg) > MAX_ASCII_NUMBER_LEN) + ||!strcmp((char *)shmp->caller_info.number, (char *)input_msg)) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + return (result = INPUT_ERROR_REINPUT); + } + + memset(&shmp->called_info,0,sizeof(_account_info)); + strcpy((char *)shmp->called_info.number, (char *)input_msg); + if(GetAccountPos(&shmp->called_info) == FALSE) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + return (result = INPUT_ERROR_REINPUT); + } + if(get_transfer_status_normal_flag()) + { + int status = GetAccountStatus(&shmp->called_info); + if(status != T_NORMAL && + status != T_FRESH && + status != T_SUSPEND) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + return (result=INPUT_ERROR_REINPUT); + } + } + + return result; +} + + + +void saveFirstInputtedTransferOutAccount(_state_data *shmp) +{ + memcpy(&shmp->process_info.ppsService.feeTransfer.account,&shmp->called_info,sizeof(_account_info)); +} + +int matchTwoInpuutedTransferOutAccount(_state_data *shmp) +{ + if(!strcmp((char *)shmp->process_info.ppsService.feeTransfer.account.number, (char *)shmp->called_info.number)) + return 1; + return 0; +} + +static int WaitForTransferMode(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + + PutLogFunID("WaitForTransferMode"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + if(input_msg[0] < '0' || input_msg[0] > '1') + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return INPUT_ERROR_EXIT; + } + return INPUT_ERROR_REINPUT; + } + shmp->process_info.ppsService.feeTransfer.transferMode = input_msg[0]; + return result; +} + +static int WaitForChoice(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + + PutLogFunID("WaitForChoice"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + if(input_msg[0] < '0' || input_msg[0] > '3') + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return INPUT_ERROR_EXIT; + } + return INPUT_ERROR_REINPUT; + } + shmp->process_info.ppsService.feeTransfer.transferMode = input_msg[0]; + return result; +} + +static int WaitForChoice_chargeOrTransfer(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + + PutLogFunID("WaitForChoice"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + if(input_msg[0] < '1' || input_msg[0] > '2') + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return INPUT_ERROR_EXIT; + } + return INPUT_ERROR_REINPUT; + } + shmp->process_info.ppsService.feeTransfer.transferMode = input_msg[0]; + return result; +} + +int getInputtedChoice(_state_data *shmp) +{ + return shmp->process_info.ppsService.feeTransfer.transferMode - '0'; +} + + +long GetPromotionExpiration(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetIncomingExpiration"); + + return (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) ? + shmp->prepaid_info[ptr->head][ptr->tail].promo_date + : (tvnow.tv_sec+1); +} +float GetPromotion(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetIncomingExpiration"); + + return (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) ? + shmp->prepaid_info[ptr->head][ptr->tail].promo_balance : 0; +} + +int checkTransferedPartialFee(_account_info *callerInfo,float feeTransfered) +{ + float balance=0; + BOOL balanceExpired=FALSE,promotionExpired=FALSE; + + if(isPromotionCanBeTransfered(callerInfo)) + { + if(GetExpiration(callerInfo) <= tvnow.tv_sec) + balanceExpired = TRUE; + if(GetPromotionExpiration(callerInfo) <= tvnow.tv_sec) + promotionExpired = TRUE; + if(balanceExpired && promotionExpired) + return CHECK_TRANSFERED_FEE_EXPIERED; + if(!balanceExpired) + balance += GetBalanceWithOutPromotion(callerInfo->head,callerInfo->tail); + if(!promotionExpired) + balance += GetPromotion(callerInfo); + } + else + { + if(GetExpiration(callerInfo) <= tvnow.tv_sec) + return CHECK_TRANSFERED_FEE_EXPIERED; + balance = GetBalanceWithOutPromotion(callerInfo->head,callerInfo->tail); + } + + if(balance < feeTransfered || feeTransfered<= 0) + return CHECK_TRANSFERED_FEE_INSUFFIENT; + + return CHECK_TRANSFERED_FEE_OK; +} + +int GetBalanceWithOutPromotion(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("getBalanceWithOutPromotion"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + return shmp->prepaid_info[head][tail].balance; + return FALSE; + +} + +int checkTransferedFullFee(_state_data *shmp) +{ + float balance; + + if(GetBalance(&shmp->caller_info) <= 0) + return CHECK_TRANSFERED_FEE_INSUFFIENT; + if(GetExpiration(&shmp->caller_info) < (tvnow.tv_sec+1) + && GetPromotionExpiration(&shmp->caller_info) < (tvnow.tv_sec+1)) + return CHECK_TRANSFERED_FEE_EXPIERED; + if(isPromotionCanBeTransfered(&shmp->caller_info)) + { + balance = GetAccountBalance(shmp->caller_info.head,shmp->caller_info.tail); + } + else + { + balance = GetBalanceWithOutPromotion(shmp->caller_info.head,shmp->caller_info.tail); + } + if(balance<=0) + return CHECK_TRANSFERED_FEE_INSUFFIENT; + shmp->process_info.ppsService.feeTransfer.fee = balance; + return CHECK_TRANSFERED_FEE_OK; +} + +static int expieredDaysTransfer_not_used(_account_info *callerInfo,_account_info *destInfo,float transferedFee,float promotion) +{ + _prepaid_data *prepaidPoint=&ramshm_ptr->prepaid_data; + _prepaid_info *pcalled,*pcaller; + float balance,daysPerBalance,valid_time; + long diff; + COSTable *cosTableItem; + + + pcalled = &prepaidPoint->prepaid_info[destInfo->head][destInfo->tail]; + pcaller = &prepaidPoint->prepaid_info[callerInfo->head][callerInfo->tail]; + cosTableItem = &ppsParam.ppsTables.cosTable[pcalled->cos_id%MaxCosTableItem]; + + if(transferedFee > 0) + { + balance = pcaller->balance; + diff = GetExpiration(callerInfo) - tvnow.tv_sec; + if(balance == 0) + daysPerBalance = 0; + else + daysPerBalance = diff/balance; + valid_time = transferedFee*daysPerBalance; + pcalled->mo_expiration_date = valid_time + pcalled->mo_expiration_date; + + if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) + cosTableItem->accountValidity[0].maxAccountValidityDays = 730; + if(pcalled->mo_expiration_date > tvnow.tv_sec+ cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + pcalled->mo_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + } + + if(promotion > 0) + { + balance = pcaller->promo_balance; + diff = GetPromotionExpiration(callerInfo) - tvnow.tv_sec; + if(balance == 0) + daysPerBalance = 0; + else + daysPerBalance = diff/balance; + valid_time = promotion*daysPerBalance; + pcalled->promo_date = valid_time + pcalled->promo_date; + if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) + cosTableItem->accountValidity[0].maxAccountValidityDays = 730; + if(pcalled->promo_date > tvnow.tv_sec+ cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + pcalled->promo_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + } + return 1; +} + +static int expieredDaysTransfer(_account_info *callerInfo,_account_info *destInfo,float transferedFee,float promotion) +{ + _prepaid_data *prepaidPoint=&ramshm_ptr->prepaid_data; + _prepaid_info *pcalled,*pcaller; + + if(get_not_change_transfer_expiry_date()) + {return 1;} + + pcalled = &prepaidPoint->prepaid_info[destInfo->head][destInfo->tail]; + pcaller = &prepaidPoint->prepaid_info[callerInfo->head][callerInfo->tail]; + + if(transferedFee > 0) + { + if(pcalled->mo_expiration_date < pcaller->mo_expiration_date) + pcalled->mo_expiration_date = pcaller->mo_expiration_date; + if(pcalled->mt_expiration_date < pcaller->mt_expiration_date) + pcalled->mt_expiration_date = pcaller->mt_expiration_date; + } + + if(promotion > 0) + { + if(pcalled->promo_date < pcaller->promo_date) + pcalled->promo_date = pcaller->promo_date; + } + + return 1; + +} + + +int poolTransferAccount(_account_info *callerInfo,_account_info *destInfo,float transferedFee) +{ /*Notice: Be sure to call checkTransferedPartialFee() first to check */ + u_long instance; + int retval=0; + _prepaid_data *prepaidPoint=&ramshm_ptr->prepaid_data; + _prepaid_info *pcaller,*pcalled; + float diff=0; + double oldCallerBalance,oldCallerPromo,oldCalledBalance,oldCalledPromo; + BOOL balanceExpired=FALSE,promotionExpired=FALSE; + + if(transferedFee == 0) + { + //pps_print_error(0,"%s no need to transfer fee:%0.4f to %s",callerInfo->number,transferedFee,destInfo->number); + return -1; + } + + pcalled = &prepaidPoint->prepaid_info[destInfo->head][destInfo->tail]; + oldCalledBalance = pcalled->balance; + oldCalledPromo = pcalled->promo_balance; + pcaller = &prepaidPoint->prepaid_info[callerInfo->head][callerInfo->tail]; + oldCallerBalance = pcaller->balance; + oldCallerPromo = pcaller->promo_balance; + + if(isPromotionCanBeTransfered(callerInfo) == FALSE) + { + expieredDaysTransfer(callerInfo,destInfo,transferedFee,0); + pcalled->balance += transferedFee; + pcaller->balance -= transferedFee; + } + else + { + if(GetExpiration(callerInfo) <= tvnow.tv_sec) + balanceExpired = TRUE; + if(GetPromotionExpiration(callerInfo) <= tvnow.tv_sec) + promotionExpired = TRUE; + + if(balanceExpired == TRUE) + { + expieredDaysTransfer(callerInfo,destInfo,0,transferedFee); + pcalled->promo_balance += transferedFee; + pcaller->promo_balance -= transferedFee; + } + else if(promotionExpired == TRUE) + { + expieredDaysTransfer(callerInfo,destInfo,transferedFee,0); + pcalled->balance += transferedFee; + pcaller->balance -= transferedFee; + } + else + { + if(isPromotionFirstTransfered(callerInfo) == FALSE) + { + if(transferedFee > pcaller->balance) + { + diff = transferedFee - pcaller->balance; + expieredDaysTransfer(callerInfo,destInfo,transferedFee - diff,diff); + pcalled->balance += transferedFee - diff; + pcaller->balance = 0; + pcalled->promo_balance += diff; + pcaller->promo_balance -= diff; + + } + else + { + expieredDaysTransfer(callerInfo,destInfo,transferedFee,0); + pcalled->balance += transferedFee; + pcaller->balance -= transferedFee; + + } + } + else if(isPromotionFirstTransfered(callerInfo) == TRUE) + { + if(transferedFee > pcaller->promo_balance) + { + diff = transferedFee - pcaller->promo_balance; + expieredDaysTransfer(callerInfo,destInfo,diff,transferedFee - diff); + pcalled->promo_balance += transferedFee - diff; + pcaller->promo_balance = 0; + pcalled->balance += diff; + pcaller->balance -= diff; + + } + else + { + expieredDaysTransfer(callerInfo,destInfo,0,transferedFee); + pcalled->promo_balance += transferedFee; + pcaller->promo_balance -= transferedFee; + } + } + } + } + UpdateAccountStatus(destInfo->head, destInfo->tail, T_NORMAL); + instance = destInfo->head * UNIT_STORE_ACCOUNT + destInfo->tail; + if(pcalled->balance >= 0) + { + UpdateAccountOverdraft(destInfo->head, destInfo->tail, 0); + } + resetCMBTimes(destInfo); + SendAccountRealSync(instance, + (pcalled->balance-oldCalledBalance), + (pcalled->promo_balance-oldCalledPromo), + OMC_OCODE_EDIT); + instance = callerInfo->head * UNIT_STORE_ACCOUNT + callerInfo->tail; + SendAccountRealSync(instance, + (pcaller->balance-oldCallerBalance), + (pcaller->promo_balance-oldCallerPromo), + OMC_OCODE_EDIT); + return (retval = 1); +} + + +void notifyUserTransferResult(_state_data *shmp,u8 callerOrCalled) +{ + u_char msgSend[MAX_SMS_LEN*4] = {0}, /*tmpbuf[64]={0},*/ buf[MAX_SMS_LEN*2]={0}; + float balance; + //u_char expire_date[128]={0},promotion_expire_date[128]={0}; + //int i,j; + u_char dayTimeReadable[32]={0}; + char tmpCaller[32],tmpCalled[32]; + + balance = shmp->process_info.ppsService.feeTransfer.fee; + if(balance == 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]No need to notify transfer result,fee:%0.4f",shmp->process_info.portid,balance); + return; + } + + ppsgetdaytime_readFormat((char *)dayTimeReadable); + + switch(callerOrCalled) + { + case NOTIFY_CALLER: + strcpy((char *)msgSend, (char *)getSmsSentenceNative(0, SMS_TRANSFERED_OUT)); + break; + case NOTIFY_CALLED: + default: + strcpy((char *)msgSend, (char *)getSmsSentenceNative(0,SMS_TRANSFERED_IN)); + break; + } + + fillMoneyToContent(balance, (char *)buf); + strcat((char *)msgSend, (char *)buf); + switch(callerOrCalled) + { + case NOTIFY_CALLER: + strcpy(tmpCaller, (char *)shmp->process_info.ppsService.feeTransfer.account.number); + strcpy(tmpCalled, (char *)shmp->caller_info.number); + cliManipulationFunction(tmpCaller,tmpCalled); + + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_TO), tmpCaller); + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_ON), dayTimeReadable); + { + char tmp_info[256]; + + GetAccountPromptInfo(&shmp->caller_info, tmp_info); + strcat((char *)msgSend, tmp_info); + + smppSendMsg(shmp->caller_info.number,msgSend,FeeTransferPosition); + + } + /* + smppSendMsg(shmp->caller_info.number,msgSend,FeeTransferPosition); + + i = shmp->caller_info.head%MSISDN_HEAD_NUM; + j = shmp->caller_info.tail%UNIT_STORE_ACCOUNT; + AsciiTime(expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].mo_expiration_date); + + AsciiTime(promotion_expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_date); + + smppSendAccountInfo(shmp->caller_info.number, + ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number, + (long)ramshm_ptr->prepaid_data.prepaid_info[i][j].balance,expire_date, + (long)ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance,promotion_expire_date, + 0,"","", + ramshm_ptr->prepaid_data.prepaid_info[i][j].language_type ); + */ + break; + case NOTIFY_CALLED: + default: + strcpy(tmpCaller, (char *)shmp->caller_info.number); + strcpy(tmpCalled, (char *)shmp->process_info.ppsService.feeTransfer.account.number); + cliManipulationFunction(tmpCaller,tmpCalled); + + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_FROM), tmpCaller); + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_ON), dayTimeReadable); + { + char tmp_info[256]; + + GetAccountPromptInfo(&shmp->process_info.ppsService.feeTransfer.account, tmp_info); + strcat((char *)msgSend, tmp_info); + + smppSendMsg(shmp->process_info.ppsService.feeTransfer.account.number,msgSend,FeeTransferPosition); + } + /* + smppSendMsg(shmp->process_info.ppsService.feeTransfer.account.number,msgSend,FeeTransferPosition); + + i = shmp->process_info.ppsService.feeTransfer.account.head; + j = shmp->process_info.ppsService.feeTransfer.account.tail; + AsciiTime(expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].mo_expiration_date); + AsciiTime(promotion_expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_date); + smppSendAccountInfo(shmp->process_info.ppsService.feeTransfer.account.number, + ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number, + (long)ramshm_ptr->prepaid_data.prepaid_info[i][j].balance,expire_date, + (long)ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance,promotion_expire_date, + 0,"","", + ramshm_ptr->prepaid_data.prepaid_info[i][j].language_type); + */ + break; + } +} + +void notifyUserTransferResult_1(_account_info *srcUsr, _account_info *dstUsr, int amount, u8 callerOrCalled) +{ + u_char msgSend[MAX_SMS_LEN*4] = {0}, /*tmpbuf[64]={0}, */buf[MAX_SMS_LEN*2]={0}; + float balance; + //u_char expire_date[128]={0},promotion_expire_date[128]={0}; + //int i,j; + u_char dayTimeReadable[32]={0}; + char tmpCaller[32],tmpCalled[32]; + + balance = amount; + if(balance == 0.0) + { + return; + } + + ppsgetdaytime_readFormat((char *)dayTimeReadable); + + switch(callerOrCalled) + { + case NOTIFY_CALLER: + strcpy((char *)msgSend, (char *)getSmsSentenceNative(0,SMS_TRANSFERED_OUT)); + break; + case NOTIFY_CALLED: + default: + strcpy((char *)msgSend, (char *)getSmsSentenceNative(0,SMS_TRANSFERED_IN)); + break; + } + + fillMoneyToContent(balance, (char *)buf); + strcat((char *)msgSend, (char *)buf); + switch(callerOrCalled) + { + case NOTIFY_CALLER: + strcpy(tmpCaller, (char *)dstUsr->number); + strcpy(tmpCalled, (char *)srcUsr->number); + cliManipulationFunction(tmpCaller, tmpCalled); + + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_TO), tmpCaller); + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_ON), dayTimeReadable); + { + char tmp_info[256]; + + GetAccountPromptInfo(srcUsr, tmp_info); + strcat((char *)msgSend, tmp_info); + + smppSendMsg(srcUsr->number, msgSend, FeeTransferPosition); + + } + break; + case NOTIFY_CALLED: + default: + strcpy(tmpCaller, (char *)srcUsr->number); + strcpy(tmpCalled, (char *)dstUsr->number); + cliManipulationFunction(tmpCaller, tmpCalled); + + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_FROM), tmpCaller); + sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_ON), dayTimeReadable); + { + char tmp_info[256]; + + GetAccountPromptInfo(dstUsr, tmp_info); + strcat((char *)msgSend, tmp_info); + + smppSendMsg(dstUsr->number, msgSend, FeeTransferPosition); + } + break; + } +} + +void SendTransferCDR(_account_info *caller_info,_account_info *called_info,float charge) +{ + _tocdr_report pcdr; + char buf[BUFSIZE]={""}; + int fee,balance,len; + int head, tail; + + PutLogFunID("SendManualOperationCDR"); + + head = caller_info->head; + tail = caller_info->tail; + + memset(&pcdr, 0, sizeof(_tocdr_report)); + if (charge > 0) + { + pcdr.type[0] = CT_TRANFER_IN; + pcdr.type[1] = CT_TRANFER_IN>>8; + } + else if (charge < 0) + { + pcdr.type[0] = CT_TRANFER_OUT; + pcdr.type[1] = CT_TRANFER_OUT>>8; + } + else + { + //pps_print_error(0,"transfee fee is %d,%s no need to send cdr at %s", + // charge,caller_info->number,__FUNCTION__); + return ; + } + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + fee = (int)charge; + fee = abs(fee); + memcpy(pcdr.charge,&fee,4); + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance,&balance,4); + + GetAccountMsisdn(head,tail,&pcdr.msisdn[1]); + ByteRev(pcdr.msisdn,9,0); + + pcdr.msisdn[0]=0x91; + memcpy(pcdr.caller,pcdr.msisdn,9); + buf[0] = 0; + + pcdr.called[0] = 0x91; + len = strlen((char *)called_info->number)%20; + ppsAsciiToBcdR(&pcdr.called[1], (char *)called_info->number,(len+1)/2*2); + if(len %2) + { + pcdr.called[(len+1)/2] |= 0xF0; + } + if(len<21) + { + pcdr.called[(len+1)/2+1] = 0xFF; + } + + sprintf(buf,"FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.imsi,buf,16); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + CDRStatistics(&pcdr,charge, 0); + StoreCDR(&pcdr); + pps_real_update_user_file(head, tail); + +#if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut, "SendTransferCDR"); +#endif +} + + +static void sendTransferInCDR(_state_data *shmp) +{ + float charge; + + + charge = shmp->process_info.ppsService.feeTransfer.fee; + SendTransferCDR(&shmp->process_info.ppsService.feeTransfer.account,&shmp->caller_info,charge); +} + +static void sendTransferOutCDR(_state_data *shmp) +{ + float charge; + + charge = shmp->process_info.ppsService.feeTransfer.fee; + SendTransferCDR(&shmp->caller_info,&shmp->process_info.ppsService.feeTransfer.account,-charge); +} + +void FeeTransferTransaction(_state_data *shmp) +{ + poolTransferAccount(&shmp->caller_info, + &shmp->process_info.ppsService.feeTransfer.account, + shmp->process_info.ppsService.feeTransfer.fee); + + notifyUserTransferResult(shmp,NOTIFY_CALLER); + notifyUserTransferResult(shmp,NOTIFY_CALLED); + + sendTransferInCDR(shmp); + sendTransferOutCDR(shmp); +} + +int SendTransferInfoPromptToSrf(u_short portid) +{ + int balance,centbalance,hth_b,th_b,h_b,b_b; + char expire_date[20]="",buf[BUFSIZE]=""; + int resolution=100; + int len; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + u8 transferNumber[MAX_MSISDN_BLEN]; + u8 varIndex = 0; + + PutLogFunID("SendTransferInfoPromptToSrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + balance = shmp->process_info.ppsService.feeTransfer.fee; + + if(balance < 0) + balance = 0; + + AsciiTime(expire_date,GetExpiration(&shmp->caller_info)); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + resolution = getSystemCurrencyResolution(); + + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + INPUT_TRANSFER_CONFIRM; + + + pMID->variableMessage.variableParts.num = 2; + + + pMID->variableMessage.variableParts.variablePart[varIndex].choice_id = 4; + sprintf(buf,"%02d",hth_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[3], + buf,2); + + varIndex++; + + len = strlen((char *)shmp->process_info.ppsService.feeTransfer.account.number); + ppsAsciiToBcdR(transferNumber, (char *)shmp->process_info.ppsService.feeTransfer.account.number, len); + if(len>(MAX_MSISDN_BLEN-1)*2) + len = (MAX_MSISDN_BLEN - 1 )*2; + + pMID->variableMessage.variableParts.variablePart[varIndex].choice_id = 1; + pMID->variableMessage.variableParts.variablePart[varIndex].number[0] = (len+1)/2+1; + if(len%2==0) + { + pMID->variableMessage.variableParts.variablePart[varIndex].number[1] = 0x04; + memcpy(&pMID->variableMessage.variableParts.variablePart[varIndex].number[2], + transferNumber, + (len+1)/2); + + } + else + { + pMID->variableMessage.variableParts.variablePart[varIndex].number[1] = 0x24; + memcpy(&pMID->variableMessage.variableParts.variablePart[varIndex].number[2], + transferNumber, + (len+1)/2); + pMID->variableMessage.variableParts.variablePart[varIndex].number[2+(len+1)/2] &=0x0F; + } + + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x00; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; +} + +int getUssdACK_old(u_short portid,u_char *ussd_data) +{ + MapOprSrv_struct opr_srv; + u8 data_flow[256]; + + struct MapPUSSR_Arg *pussr_arg; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + return 0; + } + if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + pps_send_map_close(portid); + return -1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, PUSSR ", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = shmp->context_info.acn_ver; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", + portid,shmp->context_info.map_did); + } + return -1; + } + //shmp->context_info.invoke_id = data_flow[11]; + + pussr_arg = &opr_srv.msg_list.pussr_arg; + if(pussr_arg->param_flag != 0x01) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode ussd failed,no content,param flag:%d \33[0m", + portid,shmp->context_info.map_did,pussr_arg->param_flag); + } + return -1; + } + + switch(pussr_arg->ussd_arg.ussd_scheme & 0x0f) + { + case 0x00: + case 0x0f: /* 7bit */ + smppDecodeSM((char *)pussr_arg->ussd_arg.ussd_string.ussd_data, + (char *)ussd_data, + pussr_arg->ussd_arg.ussd_string.string_len); + break; + case 0x04: /* 8bit */ + default: + memcpy(ussd_data, + pussr_arg->ussd_arg.ussd_string.ussd_data, + pussr_arg->ussd_arg.ussd_string.string_len); + break; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, USSD data: \r\n\%s ", + portid,shmp->context_info.map_did, + ussd_data); + } + + return strlen((char *)ussd_data); +} + + + +int getUssdACK(u_short portid,u_char *ussd_data) +{ + MapOprSrv_struct opr_srv; + u8 data_flow[256]; + + struct MapUSSR_Res *ussr_ack; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + return 0; + } + if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + pps_send_map_close(portid); + return -1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = shmp->context_info.acn_ver; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m", + portid,shmp->context_info.map_did); + } + return -1; + } + + ussr_ack = &opr_srv.msg_list.ussr_res; + + if(ussr_ack->param_flag != 0x01) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, USSR error received,no content,param flag is:%d \33[0m", + portid,shmp->context_info.map_did,ussr_ack->param_flag); + } + return -1; + } + + switch(ussr_ack->ussd_res.ussd_scheme & 0x0f) + { + case 0x00: + case 0x0f: /* 7bit */ + smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data, + (char *)ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + if(ussr_ack->ussd_res.ussd_string.string_len %7 == 0) + { + int tmplen; + tmplen = ussr_ack->ussd_res.ussd_string.string_len*8/7; + if(ussd_data[tmplen-1] == 0x0d) /* ussd padding byte: 0x0d */ + { + ussd_data[tmplen-1] = '\0'; + } + } + break; + case 0x04: /* 8bit */ + default: + memcpy(ussd_data, + ussr_ack->ussd_res.ussd_string.ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + break; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, USSD data: \r\n\%s ", + portid,shmp->context_info.map_did, + ussd_data); + } + return strlen((char *)ussd_data); +} + +int SendServiceNotApplied(u_short portid,u8 ussdSmsFlag,u8 serviceNumberPosition) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_SERVICE_NOT_APPLIED)); + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + //SendUSSDRequest(portid,tmp); + SendUSSDNotify(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,serviceNumberPosition); + break; + } + return 1; +} + +static int SendTransferRequest(u_short portid,u8 ussdSmsFlag) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT)); + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + + +static int SendReinputTransferRequest(u_short portid,u8 ussdSmsFlag) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_FORMAT_ERROR)); + strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT)); + + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + +static int SendTransferDstNumberErrorRequest(u_short portid,u8 ussdSmsFlag) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_INVALID_NUMBER)); + if(shmp->process_info.ussd_transfer_one_input_flag != 1) + { + strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT)); + } + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + if(shmp->process_info.ussd_transfer_one_input_flag == 1) + SendUSSDNotify(portid, (char *)tmp); + else + SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + +static int SendTransferInsufficientFeeRequest(u_short portid,u8 ussdSmsFlag) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_INSUFFICIENT_FEE)); + if(shmp->process_info.ussd_transfer_one_input_flag != 1) + { + strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT)); + } + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + if(shmp->process_info.ussd_transfer_one_input_flag == 1) + SendUSSDNotify(portid, (char *)tmp); + else + SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + +static int SendTransferExpiredAccountRequest(u_short portid,u8 ussdSmsFlag) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_EXPIRED_ACCOUNT)); + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + +static int SendTransferInfoConfirmRequest(u_short portid,u8 ussdSmsFlag) +{ + _state_data *shmp; + //TRANSFER_FEE *transferInfo; + float balance; + u_char tmp[MAX_SMS_LEN*4] = {0}, /*tmpbuf[64]={0}, */buf[MAX_SMS_LEN*2]={0}; + char tmpCaller[32],tmpCalled[32]; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + //transferInfo = &shmp->process_info.ppsService.feeTransfer; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_WILL_TRANSFER_OUT)); + + balance = shmp->process_info.ppsService.feeTransfer.fee; + fillMoneyToContent(balance, (char *)buf); + strcat((char *)tmp, (char *)buf); + + strcpy(tmpCaller, (char *)shmp->process_info.ppsService.feeTransfer.account.number); + strcpy(tmpCalled, (char *)shmp->caller_info.number); + cliManipulationFunction(tmpCaller,tmpCalled); + + sprintf((char *)tmp+strlen((char *)tmp), " %s %s.", getSmsSentenceNative(0,SMS_TO), tmpCaller); + + strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_YES_OR_NO)); + + + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + +static int SendReinputTransferConfrimRequest(u_short portid,u8 ussdSmsFlag) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_FORMAT_ERROR)); + strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_YES_OR_NO)); + + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + +int SendTransferSuccessRequest(u_short portid,u8 ussdSmsFlag) +{ + u_char tmp[MAX_SMS_LEN*4] = {0}; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_SUCCESS)); + + switch(ussdSmsFlag) + { + case USSD_TRANSFER: + SendPSSREnd(portid, (char *)tmp); + //SendUSSDRequest(portid, (char *)tmp); + break; + case SMS_TRANSFER: + default: + smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition); + break; + } + return 1; +} + +static double feeAsciiToFloat(u_char *fee) +{ + u_char *p; + float factor=0.1001; + double value=0; + + if(fee == NULL) + return 0; + p = fee; + while(isdigit(*p)) + { + value = value*10+(*p-'0'); + p++; + } + if(*p == '.') + { + p++; + while(isdigit(*p)) + { + value += factor*(*p-'0'); + p++; + factor *= 0.1001; + } + } + return value; +} + +int getTransferInfo(u_short portid,u_char *ussd_data) +{/* format:number#amount */ + _state_data *shmp; + TRANSFER_FEE *transferInfo; + u8 i,len,Btimes = 0,Atimes = 0,Bposition,Aposition,resolution = 1; + u8 *p,feeAscii[64]={0}; + double fee; + + PutLogFunID("getTransferInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + len = strlen((char *)ussd_data); + for(i = 0;i < len;i++) + { + if(!isdigit(ussd_data[i]) + && ussd_data[i] != '#' + && ussd_data[i] != '*' + && ussd_data[i] != '.') + return -1; + if(ussd_data[i] == '#') + { + Btimes++; + Bposition = i; + } + if(ussd_data[i] == '*' || ussd_data[i] == '.') + { + Atimes++; + Aposition = i; + } + } + + if(Btimes != 1 || Atimes > 1) + return -1; + + if(!isdigit(ussd_data[0]) || !isdigit(ussd_data[len - 1])) + return -1; + + if(Atimes >= 1) + { + if(Bposition >= Aposition) + return -1; + } + + p = (u8 *)strchr((char *)ussd_data+1, '#'); + if(p == NULL) + return -1; + if(!isdigit(*(p+1))) + return -1; + + transferInfo = &shmp->process_info.ppsService.feeTransfer; + + *p = 0; + + memset(feeAscii,0,64); + strcpy((char *)feeAscii, (char *)p+1); + + p = (u8 *)strchr((char *)feeAscii, '*'); + if(p != NULL) + { + *p = '.'; + } + if(strlen((char *)feeAscii) > MAX_FEE_LENGTH) + return -1; + if(get_transfer_resolution()) + resolution = getSystemCurrencyResolution(); + fee = feeAsciiToFloat(feeAscii); + transferInfo->fee = (int)(fee*resolution); + if(transferInfo->fee <= 0) + return -1; + + CutUnknownPrefix((char *)ussd_data); + if(strlen((char *)ussd_data) > MAX_ASCII_NUMBER_LEN) + return -1; + memset(transferInfo->account.number,0,MAX_ASCII_NUMBER_LEN); + strcpy((char *)transferInfo->account.number, (char *)ussd_data); + + return 1; +} + +int smppSendMsg(u_char *peerNumber,u_char *msg,u_char serviceNumPosition) +{ + //u_char buf[256]={0}; + //int result = 0; + + PutLogFunID("smppSendMsg"); + + + return smppSendMOSM((char *)peerNumber, (char *)ppsParam.ppsTables.serviceNumber[serviceNumPosition].number + , msg, strlen((char *)msg), 0); +} + + +int saveTransferSMSACK(u_short portid,u_char *sms) +{ + _state_data *shmp; + u8 len; + + PutLogFunID("saveSMSACK"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + len = strlen((char *)sms) % MAX_INPUT_SMS; + + memcpy(shmp->process_info.ppsService.feeTransfer.inputSMS,sms,len); + shmp->process_info.ppsService.feeTransfer.inputSMS[len] = 0; + shmp->process_info.ppsService.feeTransfer.smsTrigger = TRUE; + return len; +} + + +static int getTransferSMSACK(u_short portid,u_char *sms) +{ + _state_data *shmp; + + PutLogFunID("getSMSACK"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.ppsService.feeTransfer.smsTrigger == FALSE) + return 0; + + shmp->process_info.ppsService.feeTransfer.smsTrigger = FALSE; + strcpy((char *)sms, (char *)shmp->process_info.ppsService.feeTransfer.inputSMS); + return strlen((char *)sms); +} + +static BOOL checkTransferDestNumber(u_short portid) +{ + _state_data *shmp; + + PutLogFunID("checkTransferDestNumber"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + CutUnknownPrefix((char *)shmp->process_info.ppsService.feeTransfer.account.number); + if(!strcmp((char *)shmp->caller_info.number, (char *)shmp->process_info.ppsService.feeTransfer.account.number)) + { + return FALSE; + } + if(GetAccountPos(&shmp->process_info.ppsService.feeTransfer.account)==FALSE) + return FALSE; + if(get_transfer_status_normal_flag()) + { + int status = GetAccountStatus(&shmp->process_info.ppsService.feeTransfer.account); + if(status == T_NORMAL || + status == T_FRESH || + status == T_SUSPEND) + return TRUE; + else + return FALSE; + } + return TRUE; +} + + +int transferAccountSMSProc(u_short portid) +{ + _state_data *shmp; + u_char short_message[256]; + int result = 0; + TRANSFER_FEE *feeTransfer; + + PutLogFunID("transferAccountSMSProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(getTransferState(portid)) + { + case S_TRANSFER_IDLE: + if(isTransferAllowed(portid) == FALSE) + { + SendServiceNotApplied(portid,SMS_TRANSFER,FeeTransferPosition); + changeTransferState(portid,S_TRANSFER_EXIT); + return SERVICE_RETURN_TO_PARENT; + } + result = checkTransferedPartialFee(&shmp->caller_info,1.0); + if(result == CHECK_TRANSFERED_FEE_INSUFFIENT ) + { + SendTransferInsufficientFeeRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + } + + changeTransferState(portid,S_WART_INPUT_DESTNUMBER); + case S_WART_INPUT_DESTNUMBER: + result = getTransferSMSACK(portid,short_message); + switch(result) + { + case 0: + break; + case -1: + return SERVICE_EXIT_PPS; + break; + default: + short_message[result] = 0; + result = getTransferInfo(portid,short_message); + if(result < 0) + { + SendReinputTransferRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + } + else + changeTransferState(portid,S_TRANSFER_CHECK_TRANSFERED_FEE); + break; + } + case S_TRANSFER_CHECK_TRANSFERED_FEE: + result = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee); + switch(result) + { + case CHECK_TRANSFERED_FEE_INSUFFIENT: + SendTransferInsufficientFeeRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + SendTransferExpiredAccountRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + break; + case CHECK_TRANSFERED_FEE_OK: + default: + changeTransferState(portid,S_TRANSFER_CHECK_DSTNUMBER); + break; + } + case S_TRANSFER_CHECK_DSTNUMBER: + if(checkTransferDestNumber(portid) == FALSE) + { + SendTransferDstNumberErrorRequest(portid,SMS_TRANSFER); + return SERVICE_EXIT_PPS; + } + else + changeTransferState(portid,S_TRANSFER_PROCESSING);/* skip confirm */ + case S_TRANSFER_PROCESSING: + FeeTransferTransaction(shmp); + + changeTransferState(portid,S_TRANSFER_EXIT); + case S_TRANSFER_EXIT: + clearTransferInfo(portid); + return SERVICE_RETURN_TO_PARENT; + break; + } + return SERVICE_KEEP_STATE; +} + + +int transferAccountUSSDProc(u_short portid) +{ + _state_data *shmp; + u_char ussd_data[256]={0}; + int result = 0; + TRANSFER_FEE *feeTransfer; + + PutLogFunID("transferAccountUSSDProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(getTransferState(portid)) + { + case S_TRANSFER_IDLE: + if(pps_get_adaptor_flag()) + { + changeTransferState(portid,S_USSD_FT_REST_START); + break; + } + if(isTransferAllowed(portid) == FALSE) + { + SendServiceNotApplied(portid,USSD_TRANSFER,FeeTransferPosition); + changeTransferState(portid,S_TRANSFER_EXIT); + break; + } + result = checkTransferedPartialFee(&shmp->caller_info,1.0); + if(result == CHECK_TRANSFERED_FEE_INSUFFIENT) + { + SendTransferInsufficientFeeRequest(portid,USSD_TRANSFER); + return SERVICE_EXIT_PPS; + } + + if(shmp->process_info.ussd_transfer_one_input_flag == 1) + { + changeTransferState(portid,S_USSD_FT_ALL_IN_ONE_INPUT); + break; + } + clearTransferInfo(portid); + + SendTransferRequest(portid,USSD_TRANSFER); + changeTransferState(portid,S_WART_INPUT_DESTNUMBER); + break; + case S_WART_INPUT_DESTNUMBER: + result = getUssdACK(portid,ussd_data); + switch(result) + { + case 0: + break; + case -1: + return SERVICE_EXIT_PPS; + break; + default: + result = getTransferInfo(portid,ussd_data); + if(result < 0) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + return SERVICE_EXIT_PPS; + SendReinputTransferRequest(portid,USSD_TRANSFER); + } + else + changeTransferState(portid,S_TRANSFER_CHECK_TRANSFERED_FEE); + break; + } + break; + case S_TRANSFER_CHECK_TRANSFERED_FEE: + result = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee); + switch(result) + { + case CHECK_TRANSFERED_FEE_INSUFFIENT: + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return SERVICE_EXIT_PPS; + } + SendTransferInsufficientFeeRequest(portid,USSD_TRANSFER); + changeTransferState(portid,S_WART_INPUT_DESTNUMBER); + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + SendTransferExpiredAccountRequest(portid,USSD_TRANSFER); + return SERVICE_EXIT_PPS; + break; + case CHECK_TRANSFERED_FEE_OK: + default: + changeTransferState(portid,S_TRANSFER_CHECK_DSTNUMBER); + break; + } + break; + case S_TRANSFER_CHECK_DSTNUMBER: + if(checkTransferDestNumber(portid) == FALSE) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return SERVICE_EXIT_PPS; + } + SendTransferDstNumberErrorRequest(portid,USSD_TRANSFER); + changeTransferState(portid,S_WART_INPUT_DESTNUMBER); + } + else + changeTransferState(portid,S_TRANSFER_CONFIRM); + break; + case S_TRANSFER_CONFIRM: + SendTransferInfoConfirmRequest(portid,USSD_TRANSFER); + changeTransferState(portid,S_WAIT_TRANSFER_CONFIRM); + break; + case S_WAIT_TRANSFER_CONFIRM: + result = getUssdACK(portid,ussd_data); + switch(result) + { + case 0: + break; + case -1: + return SERVICE_EXIT_PPS; + break; + default: + if(result != 1) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + return SERVICE_EXIT_PPS; + else + SendReinputTransferConfrimRequest(portid,USSD_TRANSFER); + } + result = ussd_data[0] - '0'; + switch(result) + { + case CONFIRM_OK: + changeTransferState(portid,S_TRANSFER_PROCESSING); + break; + case CONFIRM_ENTER_AGAIN: + changeTransferState(portid,S_TRANSFER_IDLE); + break; + case CONFIRM_CANCEL: + changeTransferState(portid,S_TRANSFER_EXIT); + break; + default: + return SERVICE_EXIT_PPS; + break; + } + break; + } + break; + case S_TRANSFER_PROCESSING: + FeeTransferTransaction(shmp); + + changeTransferState(portid,S_TRANSFER_EXIT); + break; + case S_USSD_FT_ALL_IN_ONE_INPUT: + strcpy((char *)shmp->process_info.ppsService.feeTransfer.account.number, shmp->process_info.tmpDigits); + result = WaitingForInputTransferOutAccount(shmp); + if(result != INPUT_SUCCESS) + { + SendTransferDstNumberErrorRequest(portid,USSD_TRANSFER); + changeTransferState(portid,S_TRANSFER_EXIT); + break; + } + if(checkTransferDestNumber(portid) == FALSE) + { + SendTransferDstNumberErrorRequest(portid,USSD_TRANSFER); + return SERVICE_EXIT_PPS; + } + + result = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee); + switch(result) + { + case CHECK_TRANSFERED_FEE_INSUFFIENT: + SendTransferInsufficientFeeRequest(portid,USSD_TRANSFER); + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + SendTransferExpiredAccountRequest(portid,USSD_TRANSFER); + break; + case CHECK_TRANSFERED_FEE_OK: + FeeTransferTransaction(shmp); + default: + break; + } + + + changeTransferState(portid,S_TRANSFER_EXIT); + + break; + case S_USSD_FT_REST_START: + result = pps_rest_transfer_process(portid); + if(result != 0) + { + changeTransferState(portid,S_TRANSFER_EXIT); + } + break; + case S_TRANSFER_EXIT: + clearTransferInfo(portid); + return SERVICE_EXIT_PPS; + break; + } + return SERVICE_KEEP_STATE; +} + + +int chargeOrTransfer(u_short portid) +{ + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst; + TRANSFER_FEE *feeTransfer; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + return SERVICE_EXIT_PPS; + } + switch(getTransferState(portid)) + { + case S_TRANSFER_IDLE: + clearTransferInfo(portid); + changeTransferState(portid,S_WAIT_TRANSFER_CONFIRM); + playPromptAndCollectVoice(portid,CHARGE_OR_TRANSFER,1); + break; + case S_WAIT_TRANSFER_CONFIRM: + rst = WaitForChoice_chargeOrTransfer(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = getInputtedChoice(shmp); + switch(rst) + { + case CONFIRM_OK: + changeTransferState(portid,S_TRANSFER_EXIT); + break; + case CONFIRM_ENTER_AGAIN: + changeTransferState(portid,S_TRANSFER_EXIT); + break; + default: + result = SERVICE_EXIT_PPS; + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,CHARGE_OR_TRANSFER,1); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_TRANSFER_EXIT: + result = SERVICE_RETURN_TO_PARENT; + break; + default: + result = SERVICE_EXIT_PPS; + break; + } + return result; +} + + +int transferAccountIVRProc(u_short portid) +{ + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst; + TRANSFER_FEE *feeTransfer; + + PutLogFunID("transferPPSAccountProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + clearTransferInfo(portid); + return SERVICE_EXIT_PPS; + } + switch(getTransferState(portid)) + { + case S_TRANSFER_IDLE: + if(isTransferAllowed(portid) == FALSE) + { + playPromptVoice(portid,SERIVCE_NOT_APPLIED); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR); + break; + } + rst = checkTransferedPartialFee(&shmp->caller_info,1.0); + if(rst == CHECK_TRANSFERED_FEE_INSUFFIENT) + { + playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR); + return result; + } + + clearTransferInfo(portid); + changeTransferState(portid,S_INPUT_DESTNUMBER); + break; + case S_INPUT_DESTNUMBER: + playPromptAndCollectVoice(portid,PleaseInputTransferInAccount,MAX_IVR_INPUT_LEN); + changeTransferState(portid,S_WART_INPUT_DESTNUMBER); + break; + case S_WART_INPUT_DESTNUMBER: + rst = WaitingForInputTransferOutAccount(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + saveFirstInputtedTransferOutAccount(shmp); + changeTransferState(portid,S_INPUT_DESTNUMBER_AGAIN); + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_INPUT_DESTNUMBER_AGAIN: + playPromptAndCollectVoice(portid,PleaseInputTransferInAccountAgain,MAX_IVR_INPUT_LEN); + changeTransferState(portid,S_WART_INPUT_DESTNUMBER_AGAIN); + break; + case S_WART_INPUT_DESTNUMBER_AGAIN: + rst = WaitingForInputTransferOutAccount(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + changeTransferState(portid,S_MATCH_DESTNUMBER); + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN); + changeTransferState(portid,S_WART_INPUT_DESTNUMBER); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_MATCH_DESTNUMBER: + if(matchTwoInpuutedTransferOutAccount(shmp)) + changeTransferState(portid,S_FULL_PARTIAL_TRANSFER_CHOICE); + else + changeTransferState(portid,S_DESTNUMBER_NOT_MATCHED); + break; + case S_DESTNUMBER_NOT_MATCHED: + playPromptVoice(portid,NotMatchedTransferOutAccount); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR); + break; + case S_FULL_PARTIAL_TRANSFER_CHOICE: + playPromptAndCollectVoice(portid,FULL_PARTIAL_TRANSFER_CHOICE,1); + changeTransferState(portid,S_WAIT_FULL_PARTIAL_TRANSFER_CHOICE); + break; + case S_WAIT_FULL_PARTIAL_TRANSFER_CHOICE: + rst = WaitForTransferMode(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = getInputtedChoice(shmp); + if( rst == FULL_TRANSFER_MODE) + { + rst = checkTransferedFullFee(shmp); + switch(rst) + { + case CHECK_TRANSFERED_FEE_OK: + changeTransferState(portid,S_TRANSFER_CONFIRM); + break; + case CHECK_TRANSFERED_FEE_INSUFFIENT: + playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR); + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + default: + playPromptVoice(portid,TRANSFERED_FEE_EXPIERED); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR); + break; + } + } + else if( rst == PARTIAL_TRANSFER_MODE) + changeTransferState(portid,S_INPUT_FEE_TRANSFERED); + else + changeTransferState(portid,S_FULL_PARTIAL_TRANSFER_CHOICE); + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,FULL_PARTIAL_TRANSFER_CHOICE,1); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_INPUT_FEE_TRANSFERED: + playPromptAndCollectVoice(portid,INPUT_FEE_TRANSFERED,MAX_FEE_LENGTH); + changeTransferState(portid,S_WAIT_INPUT_FEE_TRANSFERED); + break; + case S_WAIT_INPUT_FEE_TRANSFERED: + rst = WaitingForInputTransferOutFee(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee); + switch(rst) + { + case CHECK_TRANSFERED_FEE_OK: + changeTransferState(portid,S_TRANSFER_CONFIRM); + break; + case CHECK_TRANSFERED_FEE_INSUFFIENT: + playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR); + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + default: + playPromptVoice(portid,TRANSFERED_FEE_EXPIERED); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,INPUT_FEE_TRANSFERED_FORMAT_ERROR,MAX_IVR_INPUT_LEN); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_TRANSFER_CONFIRM: + SendTransferInfoPromptToSrf(portid); + changeTransferState(portid,S_PLAY_TRANSFER_CONFIRM_SUCCESS); + break; + case S_PLAY_TRANSFER_CONFIRM_SUCCESS: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + playPromptAndCollectVoice(portid,CONFIRM_LISTEN_AGAIN,1); + changeTransferState(portid,S_WAIT_TRANSFER_CONFIRM); + } + else + result = SERVICE_EXIT_PPS; + break; + case S_WAIT_TRANSFER_CONFIRM: + rst = WaitForChoice(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = getInputtedChoice(shmp); + switch(rst) + { + case CONFIRM_OK: + changeTransferState(portid,S_TRANSFER_PROCESSING); + break; + case CONFIRM_ENTER_AGAIN: + changeTransferState(portid,S_FULL_PARTIAL_TRANSFER_CHOICE); + break; + case CONFIRM_LISTEN_RE: + changeTransferState(portid,S_TRANSFER_CONFIRM); + break; + case CONFIRM_CANCEL: + default: + changeTransferState(portid,S_TRANSFER_EXIT); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,CONFIRM_LISTEN_AGAIN,1); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_TRANSFER_PROCESSING: + FeeTransferTransaction(shmp); + + playPromptVoice(portid,TransferSuccess); + changeTransferState(portid,S_PLAY_TRANSFERED_FEE_SUCCESS); + break; + case S_PLAY_TRANSFERED_FEE_SUCCESS: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + changeTransferState(portid,S_TRANSFER_EXIT); + } + else + result = SERVICE_EXIT_PPS; + break; + case S_PLAY_TRANSFERED_FEE_ERROR: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + changeTransferState(portid,S_TRANSFER_EXIT); + } + else + result = SERVICE_EXIT_PPS; + break; + case S_TRANSFER_EXIT: + clearTransferInfo(portid); + result = SERVICE_RETURN_TO_PARENT; + break; + default: + clearTransferInfo(portid); + result = SERVICE_EXIT_PPS; + break; + } + return result; +} + + diff --git a/mss/pps/src/main/freeSMS.c b/mss/pps/src/main/freeSMS.c new file mode 100644 index 0000000..5b51dd8 --- /dev/null +++ b/mss/pps/src/main/freeSMS.c @@ -0,0 +1,507 @@ +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + +#include "../include/plat_inc.h" + +#include "../include/ppsMibTable.h" +#include "../include/mfunc.h" + +extern int logMsgFlag; +extern PPSParamStruct ppsParam; +extern struct timeval tvnow; +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr;; +extern _tariff_private *blf_shmp; + +extern _prepaid_info *getPrepaidInfo(_account_info *account); + +#define FREE_SMS_ACTIVE 0x01 +#define FREE_SMS_DEACTIVE 0xFE +static int isFreeServiceActived(_prepaid_info *prepaidInfo) +{ + if(prepaidInfo->freeSMSActiveDays > 0) + return TRUE; + return FALSE; +} +static void setFreeServiceActived(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + u_char cosID,activeDays; + + cosID = prepaidInfo->cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + activeDays = cosTableItem->serviceControl[0].freeSMSActiveDays; + + if(prepaidInfo->mo_expiration_date < tvnow.tv_sec + activeDays * 24 *3600) + prepaidInfo->mo_expiration_date = tvnow.tv_sec + activeDays * 24 *3600; + if(prepaidInfo->mt_expiration_date < tvnow.tv_sec + activeDays * 24 *3600) + prepaidInfo->mt_expiration_date = tvnow.tv_sec + activeDays * 24 *3600; + + prepaidInfo->freeSMSActiveDays = (activeDays <= 0?15:activeDays); + +} + +static void setFreeServiceDeactived(_prepaid_info *prepaidInfo) +{ + prepaidInfo->freeSMSActiveDays = 0; +} + + +static int sendFreeServiceAlreadyActived(_state_data *shmp,_prepaid_info *prepaidInfo) +{ + char msg[MAX_SMS_LEN*4] = {0}; + + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_FREE_SERVICE_ACTIVE_ALREADY)); + if(prepaidInfo->freeSMSActiveDays != 255) + sprintf(msg+strlen(msg),".%s %d.",getSmsSentenceNative(0,SMS_FREE_SERVICE_VALID_DAYS_LEFT),prepaidInfo->freeSMSActiveDays); + + return smppSendMOSM((char *)shmp->caller_info.number, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + , (u_char *)msg,strlen(msg),0); +} + +static int sendFreeServiceAlreadyDeactived(_state_data *shmp) +{ + char msg[MAX_SMS_LEN*4] = {0}; + + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_FREE_SERVICE_DEACTIVE_ALREADY)); + return smppSendMOSM((char *)shmp->caller_info.number, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + , (u_char *)msg, strlen(msg), 0); +} + +static int sendFreeServiceActived(_state_data *shmp,_prepaid_info *prepaidInfo) +{ + char msg[MAX_SMS_LEN*4] = {0}; + char dayTimeReadable[32]={0}; + + + ppsgetdaytime_readFormat(dayTimeReadable); + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_FREE_SERVICE_ACTIVED_NOTIFY)); + sprintf(msg+strlen(msg)," %s %s.", (char *)getSmsSentenceNative(0,SMS_ON),dayTimeReadable); + if(prepaidInfo->freeSMSActiveDays != 255) + sprintf(msg+strlen(msg),"%s %d.", (char *)getSmsSentenceNative(0,SMS_FREE_SERVICE_VALID_DAYS_LEFT),prepaidInfo->freeSMSActiveDays); + return smppSendMOSM((char *)shmp->caller_info.number, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + , (u_char *)msg, strlen(msg), 0); +} + +static int sendFreeServiceDeactived(u_char *destNumber) +{ + char msg[MAX_SMS_LEN*4] = {0}; + char dayTimeReadable[32]={0}; + + + ppsgetdaytime_readFormat(dayTimeReadable); + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_FREE_SERVICE_DEACTIVED_NOTIFY)); + sprintf(msg+strlen(msg)," %s %s.", (char *)getSmsSentenceNative(0,SMS_ON),dayTimeReadable); + return smppSendMOSM((char *)destNumber, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + ,(u_char *)msg,strlen(msg),0); +} + +static int sendFreeServiceExpired(u_char *destNumber) +{ + char msg[MAX_SMS_LEN*4] = {0}; + char dayTimeReadable[32]={0}; + + ppsgetdaytime_readFormat(dayTimeReadable); + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_FREE_SERVICE_DEACTIVED_EXPIRED)); + sprintf(msg+strlen(msg)," %s %s.", (char *)getSmsSentenceNative(0,SMS_ON),dayTimeReadable); + return smppSendMOSM((char *)destNumber, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + , (u_char *)msg, strlen(msg), 0); +} + +static int sendFreeServiceInsufficientFee(u_char *destNumber) +{ + char msg[MAX_SMS_LEN*4] = {0}; + //char dayTimeReadable[32]={0}; + + sprintf(msg, " %s.", (char *)getSmsSentenceNative(0,SMS_INSUFFICIENT_FEE)); + return smppSendMOSM((char *)destNumber, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + , (u_char *)msg, strlen(msg), 0); +} + +static int sendFreeServiceMoExpired(u_char *destNumber) +{ + char msg[MAX_SMS_LEN*4] = {0}; + //char dayTimeReadable[32]={0}; + + sprintf(msg," %s.", (char *)getSmsSentenceNative(0,SMS_EXPIRED_ACCOUNT)); + return smppSendMOSM((char *)destNumber, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + , (u_char *)msg, strlen(msg), 0); +} + +static int sendFreeServiceErroCode(_state_data *shmp) +{ + char msg[MAX_SMS_LEN*4] = {0}; + + sprintf(msg, " %s.", (char *)getSmsSentenceNative(0,SMS_FREE_SMS_NOTIFICATION)); + + return smppSendMOSM((char *)shmp->caller_info.number, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number + , (u_char *)msg, strlen(msg), 0); + //return ; +} + +static void enableUserRentFlag(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + u8 rentType; + + cosTableItem = &ppsParam.ppsTables.cosTable[prepaidInfo->cos_id]; + + rentType = cosTableItem->serviceControl[0].freeSMSRentType; + if(rentType <= 0) + return; + rentType = (rentType - 1) & 0x07; + prepaidInfo->rent_type |= (0x01 << rentType); +} + +static void disableUserRentFlag(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + u8 rentType,mask = 0xFE; + + cosTableItem = &ppsParam.ppsTables.cosTable[prepaidInfo->cos_id]; + rentType = cosTableItem->serviceControl[0].freeSMSRentType; + if(rentType <= 0) + return; + rentType = (rentType - 1) & 0x07; + mask = (mask >> (8-rentType)) | (mask << rentType); + prepaidInfo->rent_type &= mask; +} + +static int isFreeServiceDaysDeductable(_prepaid_info *prepaidInfo) +{ + if(prepaidInfo->freeSMSActiveDays == 0xFF) + return FALSE; + return TRUE; +} + +void freeServiceDaysDeduct(u_short head,u_short tail) +{ + u8 len;//cosID=0, + //COSTable *cosTableItem; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *userData; + u_char destNumber[32]={0}; + + userData = &shmp->prepaid_info[head][tail]; + //cosID = userData->cos_id; + if(isFreeServiceActived(userData)== TRUE && isFreeServiceDaysDeductable(userData) == TRUE) + { + //cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + userData->freeSMSActiveDays--; + if(userData->freeSMSActiveDays <= 0) + { + disableUserRentFlag(userData); + len = userData->msisdn[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)destNumber,userData->msisdn,(MAX_MSISDN_BLEN-1)*2); + destNumber[len] = 0; + sendFreeServiceExpired(destNumber); + } + } +} + +int GetCosIDByUserData(u_short head,u_short tail) +{ + u8 cosID=0; + COSTable *cosTableItem; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *userData; + + userData = &shmp->prepaid_info[head][tail]; + cosID = userData->cos_id; + if(isFreeServiceActived(userData)== TRUE) + { + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + cosID = cosTableItem->serviceControl[0].relatedCosID; + } + return cosID%MaxCosTableItem; +} + +int GetCosIDByAccount(_account_info *ptr) +{ + //_prepaid_data *shmp=&ramshm_ptr->prepaid_data; + u8 cosID=0; + + PutLogFunID("GetCosIDByAccount"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + cosID = GetCosIDByUserData(ptr->head,ptr->tail); + } + return cosID%MaxCosTableItem; +} + +int GetLocalCosID(_account_info *ptr) +{ + u8 cosID=0; + //COSTable *cosTableItem; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *userData; + + userData = &shmp->prepaid_info[ptr->head][ptr->tail]; + cosID = userData->cos_id%MaxCosTableItem; + return cosID; +} + +int GetMOTariffIDWithFreeServiceControl(u_short head,u_short tail) +{ + //_prepaid_data *shmp=&ramshm_ptr->prepaid_data; + u8 cosID=0; + COSTable *cosTableItem; + + PutLogFunID("GetMOTariffDWithFreeServiceControl"); + + cosID = GetCosIDByUserData(head,tail); + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + + return cosTableItem->tariff[0].moTariffID%MAX_ZONE_NUM; +} + + +int GetMTTariffIDWithFreeServiceControl(_account_info *ptr) +{ + //_prepaid_data *shmp=&ramshm_ptr->prepaid_data; + u8 cosID=0; + COSTable *cosTableItem; + + PutLogFunID("GetMOTariffDWithFreeServiceControl"); + + cosID = GetCosIDByAccount(ptr); + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + + return cosTableItem->tariff[0].mtTariffID%MAX_ZONE_NUM; +} + +void SendManualOperationCDR(_account_info *caller_info,_account_info *called_info,int charge) +{ + _tocdr_report pcdr; + char buf[BUFSIZE]={""}; + int balance,len; + int head, tail; + + PutLogFunID("SendManualOperationCDR"); + + head = caller_info->head; + tail = caller_info->tail; + + memset(&pcdr, 0, sizeof(_tocdr_report)); + if (charge >= 0) + { + pcdr.type[0] = CT_ASSISTED_UP; + pcdr.type[1] = CT_ASSISTED_UP>>8; + } + else + { + pcdr.type[0] = CT_ASSISTED_DOWN; + pcdr.type[1] = CT_ASSISTED_DOWN>>8; + } + + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + charge = abs(charge); + memcpy(pcdr.charge,&charge,4); + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance,&balance,4); + + GetAccountMsisdn(head,tail,&pcdr.msisdn[1]); + ByteRev(pcdr.msisdn,9,0); + + pcdr.msisdn[0]=0x91; + memcpy(pcdr.caller,pcdr.msisdn,9); + buf[0] = 0; + + pcdr.called[0] = 0x91; + len = strlen((char *)called_info->number)%20; + ppsAsciiToBcdR(&pcdr.called[1], (char *)called_info->number,(len+1)/2*2); + if(len %2) + { + pcdr.called[(len+1)/2] |= 0xF0; + } + if(len<21) + { + pcdr.called[(len+1)/2+1] = 0xFF; + } + + sprintf(buf,"FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.imsi,buf,16); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + CDRStatistics(&pcdr,charge, 0); + StoreCDR(&pcdr); + pps_real_update_user_file(head, tail); + +#if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut, "SendManualOperationCDR"); +#endif +} + +static int activteCharge(_state_data *shmp) +{ + int head,tail; + int amount,tariff_id=0; + _prepaid_info *ptr; + + PutLogFunID("activteCharge"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if(head>=MSISDN_HEAD_NUM) + return 0; + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(isFreeServiceActived(ptr) == TRUE) + return 0; + if(GetExpiration(&shmp->caller_info) <= tvnow.tv_sec) + return -1; + tariff_id = GetAccountZoneID(head,tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) + tariff_id = 0; + amount = blf_shmp->comm_tariff[tariff_id].activeFreeSMSCharegeAmount; + if((ptr->balance + ptr->overdraft) - amount < 0) + return -2; + enableUserRentFlag(ptr); + + ptr->balance -= amount; + SendManualOperationCDR(&shmp->caller_info,&shmp->called_info,-amount); + return amount; +} + +static int deactivteCharge(_state_data *shmp) +{ + int head,tail; + int amount,tariff_id=0; + _prepaid_info *ptr; + + PutLogFunID("deactivteCharge"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if(head>=MSISDN_HEAD_NUM) + return 0; + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(isFreeServiceActived(ptr) == FALSE) + return 0; + if(GetExpiration(&shmp->caller_info) <= tvnow.tv_sec) + return -1; + tariff_id = GetAccountZoneID(head,tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) + tariff_id = 0; + amount = blf_shmp->comm_tariff[tariff_id].deactiveFreeSMSCharegeAmount; + if((ptr->balance + ptr->overdraft) - amount < 0) + return -2; + disableUserRentFlag(ptr); + + + ptr->balance -= amount; + SendManualOperationCDR(&shmp->caller_info,&shmp->called_info,-amount); + return amount; +} + + +int switchServiceProc(u_short portid,u_char *shortMsg) +{ + _prepaid_info *prepaidInfo; + u8 len; + int charge; + u_char *sms; + _state_data *shmp; + + PutLogFunID("switchServiceProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return -1; + sms = getSmsSentenceNative(0,SMS_FREE_SERVICE_ACTIVE); + len = strlen((char *)sms); + if(!strncasecmp((char *)shortMsg, (char *)sms, len)) + { + if(isFreeServiceActived(prepaidInfo) == FALSE) + { + charge = activteCharge(shmp); + if(charge < 0) + { switch(charge) + { + case -1: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]switch service,activate fail ,insufficient fee",portid); + sendFreeServiceMoExpired(shmp->caller_info.number); + break; + case -2: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]switch service,activate fail ,MO expired",portid); + sendFreeServiceInsufficientFee(shmp->caller_info.number); + break; + } + return -1; + } + setFreeServiceActived(prepaidInfo); + sendFreeServiceActived(shmp,prepaidInfo); + SendAccountRealSync_2(&shmp->caller_info,-charge,0.0,OMC_OCODE_EDIT); + } + else + sendFreeServiceAlreadyActived(shmp,prepaidInfo); + return 1; + } + + sms = getSmsSentenceNative(0,SMS_FREE_SERVICE_DEACTIVE); + len = strlen((char *)sms); + if(!strncasecmp((char *)shortMsg, (char *)sms, len)) + { + if(isFreeServiceActived(prepaidInfo) == TRUE) + { + charge = deactivteCharge(shmp); + if(charge < 0) + { + switch(charge) + { + case -1: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]switch service,deactivate fail ,insufficient fee",portid); + sendFreeServiceMoExpired(shmp->caller_info.number); + break; + case -2: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]switch service,deactivate fail ,MO expired",portid); + sendFreeServiceInsufficientFee(shmp->caller_info.number); + break; + } + return -1; + } + setFreeServiceDeactived(prepaidInfo); + sendFreeServiceDeactived(shmp->caller_info.number); + SendAccountRealSync_2(&shmp->caller_info,-charge,0.0,OMC_OCODE_EDIT); + } + else + sendFreeServiceAlreadyDeactived(shmp); + return 1; + } + + sms = getSmsSentenceNative(0,SMS_FREE_SERVICE_ENQUIRY); + len = strlen((char *)sms); + if(!strncasecmp((char *)shortMsg, (char *)sms, len)) + { + if(isFreeServiceActived(prepaidInfo)) + sendFreeServiceAlreadyActived(shmp,prepaidInfo); + else + sendFreeServiceAlreadyDeactived(shmp); + return 1; + } + + sendFreeServiceErroCode(shmp); + + return 1; +} + + + + diff --git a/mss/pps/src/main/gprs.c b/mss/pps/src/main/gprs.c new file mode 100644 index 0000000..1874745 --- /dev/null +++ b/mss/pps/src/main/gprs.c @@ -0,0 +1,2244 @@ + +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + +#include "../include/gprs.h" +#include +#include "../include/plat_inc.h" +#include "../../../../plat/diameter/include/gy_message.h" + +/*------------------------------------------------*/ +#define BYTES_PER_BASIC_FEE (BYTES_PER_KB*(tariff->chargeUnit>1?tariff->chargeUnit:1)) +#define MINI_CHARGED_BYTES (tariff->miniChargeUnit*BYTES_PER_BASIC_FEE) +#define MINI_CHARGED_FEE (tariff->miniChargeUnit*tariff->basicFee + tariff->initialAdjustment) + +#define MIN_VOLUME_QUOTA_BYTES 1024 +#define MIN_DURATION_QUOTA_SECOND (60*15) + +#define MAX_VOLUME_BYTES_EACH_TIME (radiusItem->maxVolumeQuotaEachTime > MIN_VOLUME_QUOTA_BYTES?radiusItem->maxVolumeQuotaEachTime:MIN_VOLUME_QUOTA_BYTES) +#define MAX_DURATION_SEC_EACH_TIME (radiusItem->maxDurationQuotaEachTime > MIN_DURATION_QUOTA_SECOND?radiusItem->maxVolumeQuotaEachTime:MIN_DURATION_QUOTA_SECOND) + +#define MAX_VQ_BYTES_EACH_TIME_POST (1024*1024*5)/* 5MB */ +#define MAX_VTH_BYTES_DIFF_POST (1024*1024*1)/*1MB */ + +#define MAX_BYTES_PER_SESSION (((long long)100)*1024*1024*1024)/* 10G */ + +#define pps_set_gprs_state(val) do { \ + gprsProc->state = val; \ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + + +#define pps_set_postpaid_state(val) do { \ + gprsProc->postpaidState = val; \ + gprsProc->accessRequestTimer = 0;\ + gprsProc->radiusCommand = PPS_RADIUS_NO_CMD;\ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + +#define pps_set_prepaid_state(val) do { \ + gprsProc->prepaidState = val;\ + gprsProc->accessRequestTimer = 0;\ + gprsProc->radiusCommand = PPS_RADIUS_NO_CMD;\ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + +extern int subSystemID; +extern _state_machine *smshm_ptr; +extern PPSParamStruct ppsParam; +extern _ram_data *ramshm_ptr; +extern _tariff_private *blf_shmp; +extern _pps_report pps_report; + +extern struct timeval tvnow; + +/*--------------------------------------------------------------------*/ + +extern int StoreCDR(_tocdr_report *pcdr); + +extern int sendRadiusAccessReject(u_short portid,u_char *reason); +extern int sendRadiusAccessAccept(u_short portid,BOOL volumeFlag,BOOL durationFlag); +extern int sendRadiusDisconnectReq(u_short portid); + +void SendGprsCDR(_account_info *caller_info,_state_data *shmp); +static BOOL isGprsRoaming(_state_data *shmp); +static void updateVolumeThisMonth(_account_info *ptr,long long amount); +static void UpdateGprsCapInfo(_account_info *ptr,float charge, long long amount, _state_data *sta_ptr); +static BOOL isFirstAccessAccept(_state_data *shmp); +static long long getRefundBytes(_state_data *shmp); +static long long getReportedBytes(_state_data *shmp); +static int inactiveGsnRefundVolume(_state_data *shmp); +static int inactiveGsntRefund(_state_data *shmp); +extern long pps_get_quota_per_request(); +extern long long pps_get_account_bundle_data(_state_data *shmp); +extern _prepaid_info *getPrepaidInfo(_account_info *account); +extern long pps_get_postpaid_quota_for_first_request(); +extern int subscribe_bundle_plan_send_warning_info(_state_data *shmp); +/*--------------------------------------------------------------------*/ + +BOOL isPrepaidUser(_account_info *ptr) +{ + if(ptr->head >= MSISDN_HEAD_NUM ||ptr->tail > UNIT_STORE_ACCOUNT) + return FALSE; + return TRUE; +} + +PPS_COS_RADIUS_ITEM *getCosRadiusItem(_account_info *ptr)// user profile ==> cos ID ==> Radius Item +{ + COSTable *cosTableItem; + int cosID=0; + + //PutLogFunID("getCosRadiusItem");// too many? + + if(isPrepaidUser(ptr) == TRUE) + cosID = GetLocalCosID(ptr); + else + cosID = 0; + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + + return &cosTableItem->gprs[0]; +} + +static ulong allocatePostpaidVolumeQuota(_state_data *shmp) +{ + //PPS_COS_RADIUS_ITEM *radiusItem; + _gprs_process *gprsProc; + long long volumeQuota; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + //radiusItem = getCosRadiusItem(&shmp->caller_info); + volumeQuota = MAX_VQ_BYTES_EACH_TIME_POST; + + if(gprsProc->vqAllocated.integer >= MAX_BYTES_PER_SESSION) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Max volume(10G) per session reached",shmp->process_info.portid); + return 0; + } + + if(isPrepaidUser(&shmp->caller_info) == TRUE) + { + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,0,volumeQuota,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,volumeQuota); + } + + gprsProc->vqAllocated.integer += volumeQuota ; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = gprsProc->vqAllocated.integer-MAX_VTH_BYTES_DIFF_POST; + gprsProc->vthAllocated.exponent = 0; + gprsProc->vqConsumed.integer += volumeQuota; + gprsProc->vqAllocatedThisTime = volumeQuota; + pps_print_event(shmp->process_info.logMsisdn,"[%05d]allocate %lld bytes,vq is %lld,vth is %lld at %s", + shmp->process_info.portid,volumeQuota,gprsProc->vqAllocated.integer,gprsProc->vthAllocated.integer,__FUNCTION__); + return volumeQuota; +} + +static ulong allocateDurationQuota(_state_data *shmp) +{ + PPS_COS_RADIUS_ITEM *radiusItem; + _gprs_process *gprsProc; + ulong durationQuota; + + + return 0; + gprsProc = &shmp->process_info.ppsService.gprs_process; + radiusItem = getCosRadiusItem(&shmp->caller_info); + + durationQuota = MAX_DURATION_SEC_EACH_TIME; + + gprsProc->dqAllocated += durationQuota; + gprsProc->dthAllocated = gprsProc->dqAllocated - radiusItem->durationThresholdDiff; + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]allocate %ld seconds,dq is %ld,dth is %ld at %s", + shmp->process_info.portid ,durationQuota,gprsProc->dqAllocated,gprsProc->dthAllocated,__FUNCTION__); + return radiusItem->maxDurationQuotaEachTime; +} + +static long long calculateVolume(RADIUS_TLV_DECIMAL *volume) +{ + long long eResult=1; + int i,exponent; + + if(volume->exponent < 0) + { + pps_print_error(0,"Not support float in Volume Quota"); + return -1; + } + exponent = abs(volume->exponent); + for(i=0;iinteger*eResult; +} + +int pps_get_gprs_inactive_timer(_state_data *shmp) +{ + PPS_COS_RADIUS_ITEM *radiusItem; + + radiusItem = getCosRadiusItem(&shmp->caller_info); + if(radiusItem->inactiveSessionLimit <= 0) + return 900; + return radiusItem->inactiveSessionLimit; + +} + + +BOOL isAccessTimeout(_state_data *shmp) +{ + PPS_COS_RADIUS_ITEM *radiusItem; + _gprs_process *gprsProc; + //ulong durationQuota; + + radiusItem = getCosRadiusItem(&shmp->caller_info); + if(radiusItem->inactiveSessionLimit <= 0)// COS->GPRS Service Control->Inactive Session Limit + return FALSE; + //durationQuota = MAX_DURATION_SEC_EACH_TIME; + gprsProc = &shmp->process_info.ppsService.gprs_process; + if(gprsProc->accessRequestTimer/CYCLE_STATE_INTERVAL > radiusItem->inactiveSessionLimit) + return TRUE; + gprsProc->accessRequestTimer++; + return FALSE; +} + + +int resetAccessTimeout(_state_data *shmp) +{ + _gprs_process *gprsProc; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + gprsProc->accessRequestTimer = 0; + + return 1; +} + +static BOOL isWaitTerTimeOut(_state_data *shmp,int time) +{ + _gprs_process *gprsProc; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + if(gprsProc->accessRequestTimer/CYCLE_STATE_INTERVAL > time) + return TRUE; + gprsProc->accessRequestTimer++; + return FALSE; +} + +static BOOL isReachGprsNotificationLimit(_account_info *ptr) +{ + PPS_COS_RADIUS_ITEM *radiusItem; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + //COSTable *cosTableItem; + //double promo_balance,balance; + //float chargedBalance = 0,chargedPromotion = 0; + + + radiusItem = getCosRadiusItem(ptr); + if(!radiusItem->notificationWhenSessionTerminate) + return TRUE; + if(radiusItem->maxSmsForGprsNotificationPerDay <= 0) + return TRUE; + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + if(shmp->prepaid_info[ptr->head][ptr->tail].gprsNotificationTimes < radiusItem->maxSmsForGprsNotificationPerDay) + { + shmp->prepaid_info[ptr->head][ptr->tail].gprsNotificationTimes++; + return FALSE; + } + } + return TRUE; +} + +static BOOL isVolumeThresholdReached(_state_data *shmp) +{ + long long vthAllocated,vthReported; + _RADIUS_REPORTED_INFO *radiusReportedInfo; + + return TRUE; + radiusReportedInfo = &shmp->process_info.ppsService.gprs_process.radiusReportedInfo; + vthAllocated = calculateVolume(&shmp->process_info.ppsService.gprs_process.vthAllocated); + if(vthAllocated <= 0) + return FALSE; + vthReported = calculateVolume(&radiusReportedInfo->vq.vq); + if(vthReported <= 0) + return FALSE; + if(vthAllocated <= vthReported) + return TRUE; + return FALSE; +} + + +static BOOL isDurationThresholdReached(_state_data *shmp) +{ + DWORD dthAllocated,dthReported; + _RADIUS_REPORTED_INFO *radiusReportedInfo; + + radiusReportedInfo = &shmp->process_info.ppsService.gprs_process.radiusReportedInfo; + dthAllocated = shmp->process_info.ppsService.gprs_process.dthAllocated; + dthReported = radiusReportedInfo->dq.dq.value; + if(dthAllocated <= dthReported) + return TRUE; + return FALSE; +} + +int intiateGprsReportedInfo(_state_data *shmp) +{ + _gprs_process *gprsProc; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + memset(&gprsProc->radiusReportedInfo,0,sizeof(_RADIUS_REPORTED_INFO)); + return 1; +} + + +static int volumeRefund(_state_data *shmp) +{ + _gprs_process *gprsProc; + //_gprs_tariff *tariff; + long long refundBytes; + int instance; + //PPS_COS_RADIUS_ITEM *radiusItem; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + + + refundBytes = getRefundBytes(shmp); + + //radiusItem = getCosRadiusItem(&shmp->caller_info); + if(refundBytes > gprsProc->vqAllocatedThisTime + MAX_VTH_BYTES_DIFF_POST) + refundBytes = gprsProc->vqAllocatedThisTime + MAX_VTH_BYTES_DIFF_POST; + + gprsProc->vqConsumed.integer -= refundBytes; + shmp->caller_info.charge = 0; + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,0,-refundBytes,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,-refundBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Consumed(%lld bytes);refund %lld bytes at %s", + shmp->process_info.portid ,gprsProc->vqConsumed.integer,refundBytes,__FUNCTION__); + return 1; +} + +static int inactiveGsnRefundVolume(_state_data *shmp) +{ + _gprs_process *gprsProc; + //_gprs_tariff *tariff; + long long refundBytes; + int instance; + //PPS_COS_RADIUS_ITEM *radiusItem; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + + refundBytes = gprsProc->vqAllocatedThisTime; + gprsProc->vqConsumed.integer -= refundBytes; + shmp->caller_info.charge = 0; + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,0,-refundBytes,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,-refundBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Inactive timeout,Consumed(%lld bytes);refund %lld bytes at %s", + shmp->process_info.portid ,gprsProc->vqConsumed.integer,refundBytes,__FUNCTION__); + return 0; +} + + +static int pps_gprs_postpaid_process(u_short portid) +{ + _gprs_process *gprsProc; + _state_data *shmp; + int result = SERVICE_KEEP_STATE; + BOOL volumeFlag=FALSE,durationFlag=FALSE; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + gprsProc = &shmp->process_info.ppsService.gprs_process; + + switch(gprsProc->postpaidState) + { + case pps_gprs_idle: + if(gprsProc->radiusCommand == PPS_RADIUS_NEW_SERVICE) + { + gprsProc->radiusCommand = PPS_RADIUS_NO_CMD; + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + if(allocatePostpaidVolumeQuota(shmp) > 0) + { + volumeFlag = TRUE; + sendRadiusAccessAccept(portid,volumeFlag,durationFlag); + pps_set_postpaid_state(pps_gprs_wait_request); + } + else + { + sendRadiusAccessReject(portid,(u_char *)"Max volume(3.8G) per session reached"); + pps_set_postpaid_state(pps_gprs_service_terminate); + } + } + else + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Unsupported update result:%d at state:%d",portid, gprsProc->radiusCommand,gprsProc->state); + result = SERVICE_EXIT_PPS; + } + break; + case pps_gprs_wait_request: + if(isAccessTimeout(shmp) == TRUE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]GSN access timeout at state:%d",portid,gprsProc->state); + pps_set_postpaid_state(pps_gprs_access_timeout); + break; + } + + switch(gprsProc->radiusCommand) + { + case PPS_RADIUS_NO_CMD: + break; + case PPS_RADIUS_THRESHOLD_REACHED: + gprsProc->radiusCommand = PPS_RADIUS_NO_CMD; + if(isVolumeThresholdReached(shmp) == TRUE) + { + if(allocatePostpaidVolumeQuota(shmp) > 0) + volumeFlag = TRUE; + } + sendRadiusAccessAccept(portid,volumeFlag,durationFlag); + break; + case PPS_RADIUS_QUOTA_REACHED: + case PPS_RADIUS_REMOTE_DISC: + case PPS_RADIUS_CLIENT_SERVICE_TER: + case PPS_RADIUS_ACCESS_SERVICE_TER: + case PPS_RADIUS_SERVICE_NOT_EST: + if(isPrepaidUser(&shmp->caller_info) == TRUE) + { + volumeRefund(shmp); + } + sendRadiusAccessAccept(portid,0,0); + pps_set_postpaid_state(pps_gprs_service_terminate); + break; + default: + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Ignore unsupported update result:%d at state:%d" + ,portid, gprsProc->radiusCommand,gprsProc->state); + break; + } + break; + case pps_gprs_access_timeout: + /*if(isPrepaidUser(&shmp->caller_info) == TRUE) + { + inactiveGsnRefundVolume(shmp); + }*/ + sendRadiusDisconnectReq(portid); + pps_set_postpaid_state(pps_gprs_wait_terminate); + break; + case pps_gprs_wait_terminate: + if(isWaitTerTimeOut(shmp,10) == TRUE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]GSN access timeout at state:pps_gprs_wait_terminate",portid); + pps_set_postpaid_state(pps_gprs_service_terminate); + break; + } + switch(gprsProc->radiusCommand) + { + case PPS_RADIUS_NO_CMD: + break; + case PPS_RADIUS_QUOTA_REACHED: + case PPS_RADIUS_REMOTE_DISC: + case PPS_RADIUS_CLIENT_SERVICE_TER: + case PPS_RADIUS_ACCESS_SERVICE_TER: + case PPS_RADIUS_SERVICE_NOT_EST: + if(isPrepaidUser(&shmp->caller_info) == TRUE) + { + volumeRefund(shmp); + } + sendRadiusAccessAccept(portid,0,0); + pps_set_postpaid_state(pps_gprs_service_terminate); + break; + default:/* not going to handle disconnect ack or nak */ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]ignore command:%d at pps_gprs_wait_terminate" + ,portid,gprsProc->radiusCommand); + break; + } + break; + case pps_gprs_service_terminate: + shmp->cdr_info.releasetime = tvnow.tv_sec; + if(isPrepaidUser(&shmp->caller_info) == TRUE) + { + SendGprsCDR(&shmp->caller_info,shmp); + } + result = SERVICE_EXIT_PPS; + break; + } + return result; +} + +BOOL isUseLegal(_account_info *userInfo,u_char *reason) +{ + _prepaid_info *prepaidInfo; + + if((prepaidInfo = getPrepaidInfo(userInfo)) == NULL) + return FALSE; + + if(prepaidInfo->status != T_NORMAL) + { + sprintf((char *)reason,"Unacceptable user status:%d",prepaidInfo->status); + return FALSE; + } + return TRUE; +} + +BOOL checkMiniBalanceForGprs(_state_data *shmp) +{ + PPS_COS_RADIUS_ITEM *radiusItem; + //_gprs_process *gprsProc; + double balance; + + //gprsProc = &shmp->process_info.ppsService.gprs_process; + radiusItem = getCosRadiusItem(&shmp->caller_info); + if(radiusItem->miniBalanceForGprs <= 0) + return TRUE; + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info); + if(balance < radiusItem->miniBalanceForGprs) + return FALSE; + return TRUE; +} + +static int findCOSIDBySgsn(DWORD sgsnIP) +{ + int i; + PPS_RADIUS_SGSN_INFO *gsnItem; + struct in_addr ip_addr; + u_char ipAsc[64]; + + ip_addr.s_addr = sgsnIP; + sprintf((char *)ipAsc, "%s",inet_ntoa(ip_addr)); + for(i=0;isgsnIP == sgsnIP) + { + pps_print_event(0,"%s related cos ID:%d",ipAsc,gsnItem->cosID); + return gsnItem->cosID; + } + } + pps_print_error(0,"%s not matched in SGSN talbe",ipAsc); + return -1; +} + +static int findIndexBySgsn(DWORD sgsnIP) +{ + int i; + PPS_RADIUS_SGSN_INFO *gsnItem; + struct in_addr ip_addr; + u_char ipAsc[64]; + + ip_addr.s_addr = sgsnIP; + sprintf((char *)ipAsc, "%s",inet_ntoa(ip_addr)); + for(i=0;isgsnIP== sgsnIP) + { + pps_print_event(0,"%s related sgsn table index:%d",ipAsc,i); + return i; + } + } + pps_print_event(0,"%s not matched in SGSN table",ipAsc); + return -1; +} + +int findTariffIDByAPNName(char *apn_name) +{ + int i, len; + PPS_RADIUS_SGSN_INFO *gsnItem; + + len = strlen(apn_name); + + for(i=0;iapnName , apn_name, len) == 0) + { + pps_print_event(0,"%s related tariff ID:%d", apn_name ,gsnItem->tariffID); + return gsnItem->tariffID; + } + } + + pps_print_error(0,"%s not matched in SGSN talbe", apn_name); + return -1; +} + + +static BOOL isGprsRoaming(_state_data *shmp) +{ + if(shmp->process_info.roamingFlag == 1) + return TRUE; + return FALSE; +} + +void getGprsCapInfo(_account_info *ptr,long long *gprsVolume,double *gprsCharged) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetGprssCapInfo"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + *gprsVolume = shmp->prepaid_info[ptr->head][ptr->tail].gprsVolume; + *gprsCharged = shmp->prepaid_info[ptr->head][ptr->tail].gprsBalance; + } + else + { + *gprsVolume = 0; + *gprsCharged = 0; + } +} + +int GetGprsCapTariffID(_state_data *shmp) +{ /* threshold volume unit is KB */ + int tariff_id = -1;//,cos_id=0,i; + long long gprsVolume; + double gprsCharged; + long long threholdPoint; + u32 c_threshold0=0,c_threshold1=0,c_threshold2=0; + + GPRS_VOLUME_CAP_PLAN *capPlanPtr; + PPS_COS_RADIUS_ITEM *radiusItem; + //_gprs_process *gprsProc; + + + PutLogFunID("GetGprsCapTariffID"); + + radiusItem = getCosRadiusItem(&shmp->caller_info); + + capPlanPtr = &radiusItem->capPlan[0]; + + getGprsCapInfo(&shmp->caller_info,&gprsVolume,&gprsCharged);// Get CAP GPRS volume & balance from user profile + if(gprsVolume<0 || gprsVolume>4000000000000LL) gprsVolume = 0; + if(gprsCharged<0) gprsCharged = 0; + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Get Cap GPRS info, volume=%lld, charge=%lld", + shmp->process_info.portid, gprsVolume, gprsCharged); + + + c_threshold0 = capPlanPtr->threshold0; + c_threshold1 = capPlanPtr->threshold1; + c_threshold2 = capPlanPtr->threshold2; + + if(capPlanPtr->type == 0) + { + threholdPoint = gprsVolume >> 10; + } + else + threholdPoint = (long long )(gprsCharged); + + if(c_threshold0>0) + { + if(threholdPointtariffID0; + shmp->process_info.cap_seg = 0; + } + else if(c_threshold1>0) + { + if(threholdPointtariffID1; + shmp->process_info.cap_seg = 1; + } + else if(c_threshold2>0) + { + if(threholdPointtariffID2; + shmp->process_info.cap_seg = 2; + } + else + { + tariff_id = capPlanPtr->tariffID3; + shmp->process_info.cap_seg = 3; + } + } + else + { + tariff_id = capPlanPtr->tariffID2; + shmp->process_info.cap_seg = 2; + } + } + else + { + tariff_id = capPlanPtr->tariffID1; + shmp->process_info.cap_seg = 1; + } + } + else + pps_print_error(shmp->process_info.logMsisdn,"[%05d]threshold 0 is 0,error!"); + + return tariff_id; +} + + +static _gprs_tariff *getGprsVolumeTariffWithRoamAndCap(_state_data *shmp) +{ + _gprs_process *gprsProc; + _gprs_tariff *tariff; + int tariffID; + PPS_COS_RADIUS_ITEM *radiusItem; + COSTable *cosTableItem; + int cosID; + + shmp->process_info.cap_flag = 0; + + radiusItem = getCosRadiusItem(&shmp->caller_info); // user profile ==> cos ID ==> Radius Item + gprsProc = &shmp->process_info.ppsService.gprs_process; + + if(radiusItem->gprsChargedBy == 1)/* 0:define by cos; 1:defined by incoming GSN IP(by gy avp: Origin-Host ==> apn, charged by access location) */ + { + if(shmp->process_info.ro_if.gy_ro_enable) + cosID = findTariffIDByAPNName(shmp->process_info.ro_if.apn);// Search Radius sgsn table by apn, get tariff ID==>cosID + else + cosID = findCOSIDBySgsn(gprsProc->sgsnIP);// Search Radius sgsn table by sgsn IP(fixed to 0x1234a8c0), get cosID + if(cosID < 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]charged by location,can not find cosID by IP",shmp->process_info.portid); + return NULL; + } + else + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Normal,charged by location,cos id:%d",shmp->process_info.portid,cosID); + } + else + { + cosID = GetLocalCosID(&shmp->caller_info);// user profile ==> cos ID, get cos ID by user data again!!! + } + + /*if(shmp->process_info.ro_if.gy_ro_enable)//for GY billing, APN->tariffID mapping is defined + { + tariffID = cosID;// confusing, cosID is actually sgsnItem->tariffID!!!!!! + } + else + {*/ + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + tariffID = cosTableItem->tariff[0].moTariffID%MAX_ZONE_NUM; + //} + + tariff = &blf_shmp->gprs_tariff[tariffID][0]; + if(tariff->destIp == 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]invalid gprs tariff:%d",shmp->process_info.portid,tariff->tariffID); + return NULL; + } + if(tariff->cap_flag) + { + tariffID = GetGprsCapTariffID(shmp); + if(tariffID >= 0) + { + tariff = &blf_shmp->gprs_tariff[tariffID][0]; + if(tariff->destIp == 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]invalid gprs tariff:%d",shmp->process_info.portid,tariff->tariffID); + return NULL; + } + shmp->process_info.cap_flag = tariff->cap_flag; + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Cap plan,charged by tariff id:%d",shmp->process_info.portid,tariff->tariffID); + } + else + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]charged by cap plan error,no releated cap point",shmp->process_info.portid); + return NULL; + } + return tariff; + } + else + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Normal,charged by tariff id:%d",shmp->process_info.portid,tariff->tariffID); + return tariff; + } + return NULL; +} + + +static void CheckGprsCAPSMSNotification(_state_data *staPtr, _account_info *accountPtr, u_char cos_id, + float charge, int amount ) /* cap_type: 0=volume, 1=charged */ +{ + int cap_seg, notifyFlag=0;//cap_plan, + float c_threshold=0; + _prepaid_info *subPtr=NULL; + + COSTable *cosTableItem; + GPRS_VOLUME_CAP_PLAN *capPlanPtr; + long long c_threshold_v = 0, gprsVolume; + + PutLogFunID("CheckGprsCAPSMSNotification"); + + if(staPtr->process_info.cap_notify_flag) /* already send notification SM in this call */ + return; + + //cap_plan = staPtr->process_info.cap_plan; + cap_seg = staPtr->process_info.cap_seg; + if(cap_seg>=3) return; /* reach the last CAP segment */ + + subPtr = &ramshm_ptr->prepaid_data.prepaid_info[accountPtr->head][accountPtr->tail]; + + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + capPlanPtr = &cosTableItem->gprs[0].capPlan[0]; + + gprsVolume = subPtr->gprsVolume; + if(gprsVolume<0 || gprsVolume>4000000000000LL) + gprsVolume = 0; + + switch(capPlanPtr->type) + { + case 0: /* volume */ + if(cap_seg == 0) + { + c_threshold_v = (capPlanPtr->threshold0 << 10); + } + else if(cap_seg == 1) + { + c_threshold_v = (capPlanPtr->threshold1 << 10); + } + else if(cap_seg == 2) + { + c_threshold_v = (capPlanPtr->threshold2 << 10); + } + if((subPtr->gprsVolume + amount)>=c_threshold_v) + { + if( gprsVolume < c_threshold_v) + { + + notifyFlag = 1; + pps_print_event(staPtr->process_info.logMsisdn,"[%05d]gprs volume reach cap plan threshold point:%d,threshold:%ld KB", + staPtr->process_info.portid,cap_seg,c_threshold_v); + } + } + break; + case 1: + if(cap_seg == 0) + c_threshold = (float)(capPlanPtr->threshold0); + else if(cap_seg == 1) + c_threshold = (float)(capPlanPtr->threshold1); + else if(cap_seg == 2) + c_threshold = (float)(capPlanPtr->threshold2); + if((subPtr->gprsBalance+ charge)>=c_threshold) + { + if(subPtr->gprsBalance < c_threshold) + { + + notifyFlag = 1; + pps_print_event(staPtr->process_info.logMsisdn,"[%05d]gprs charge Fee reach cap plan threshold point:%d,threshold:%0.4f", + staPtr->process_info.portid,cap_seg,c_threshold); + } + } + break; + } + + if(notifyFlag && (subPtr->cap_sms_notify_counter<=cap_seg)) + { + subPtr->cap_sms_notify_counter = cap_seg+1; + PPSSendUserSMSNotification(accountPtr->head, accountPtr->tail, (char *)getSmsSentenceNative(0,SMS_CAPGRPS_NOTIFY)); + staPtr->process_info.cap_notify_flag = 1; + } + +} + + +static void UpdateGprsBundleInfo(_account_info *ptr,float charge, long long amount, _state_data *sta_ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *subPtr; + //u_char cos_id; + //COSTable *cosTableItem; + //int cap_type; + + PutLogFunID("UpdateGprsCapInfo"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + subPtr = &shmp->prepaid_info[ptr->head][ptr->tail]; + + /* + cos_id = subPtr->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenCapPlanChanged) + { + CheckGprsCAPSMSNotification(sta_ptr,ptr,cos_id,charge, amount); + } + cap_type = cosTableItem->gprs[0].capPlan[0].type; + if(cap_type==0)// + { + subPtr->gprsVolume += amount; + } + else + { + subPtr->gprsBalance += charge; + } + */ + subPtr->bundle_info.data += amount; + if (subPtr->bundle_info.data <=0) + { + subPtr->bundle_info.data = 0; + } + + if (subPtr->bundle_info.validity_date < tvnow.tv_sec) + { + subPtr->bundle_info.data = 0; + } + } +} + + +static void UpdateGprsCapInfo(_account_info *ptr,float charge, long long amount, _state_data *sta_ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *subPtr; + u_char cos_id; + COSTable *cosTableItem; + int cap_type; + + PutLogFunID("UpdateGprsCapInfo"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + subPtr = &shmp->prepaid_info[ptr->head][ptr->tail]; + + cos_id = subPtr->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenCapPlanChanged) + {// If reach next cap, send notification or not. + CheckGprsCAPSMSNotification(sta_ptr,ptr,cos_id,charge, amount); + } + cap_type = cosTableItem->gprs[0].capPlan[0].type; + if(cap_type==0)/* volume */ + { + subPtr->gprsVolume += amount; + } + else + { + subPtr->gprsBalance += charge; + } + } +} + +static void updateVolumeThisMonth(_account_info *ptr,long long amount) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *subPtr; + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + subPtr = &shmp->prepaid_info[ptr->head][ptr->tail]; + subPtr->gprsVolumeThisMonth += amount; + + if (subPtr->gprsVolumeThisMonth < 0) + { + subPtr->gprsVolumeThisMonth = 0; + } + } +} + +static long long allocateFirstPrepaidVolumeQuota(_state_data *shmp,u_char *failReason) +{ + PPS_COS_RADIUS_ITEM *radiusItem; + _gprs_process *gprsProc; + _gprs_tariff *tariff; + double balance; + float discount,chargedMiniRequested,chargedThisTime; + int instance; + long long miniChargedBytes,quotaBytes=0,max_quota_bytes; + CHARGED_FEE *chargedFee; + + + gprsProc = &shmp->process_info.ppsService.gprs_process; + if(gprsProc->userType != PPS_PREPAID_USER) + return -1; + tariff = getGprsVolumeTariffWithRoamAndCap(shmp); + if(tariff == NULL) + { + strcpy((char *)failReason,"no gprs tariff assigned"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]no gprs tariff assigned",shmp->process_info.portid); + return -1; + } + else + { + gprsProc->gprsTariff = tariff; + gprsProc->destIP = tariff->destIp; + } + chargedFee = &gprsProc->chargedFee; + memset(chargedFee,0,sizeof(CHARGED_FEE)); + chargedMiniRequested = 0; + chargedThisTime = 0; + radiusItem = getCosRadiusItem(&shmp->caller_info); + max_quota_bytes = MAX_VOLUME_BYTES_EACH_TIME; + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info); + discount = (float)GetDiscount(tvnow.tv_sec,tariff->discountID)/100; + chargedMiniRequested = MINI_CHARGED_FEE*discount; + pps_print_event(shmp->process_info.logMsisdn,"[%05d]tariff:need allocate:%lld bytes,mini charge: %lld bytes(units:%d),mini charged fee:%0.4f(adj:%d),bascic fee:%0.4f,discount:%0.4f", + shmp->process_info.portid ,(long long)MAX_VOLUME_BYTES_EACH_TIME,(long long)MINI_CHARGED_BYTES,tariff->miniChargeUnit, + MINI_CHARGED_FEE,tariff->initialAdjustment,tariff->basicFee,discount); + + if(balance < chargedMiniRequested) + { + strcpy((char *)failReason,"low fee,can't afford mini requested fee"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]low fee,can't afford mini requested fee",shmp->process_info.portid ); + return -1; + } + gprsProc->vqAllocated.integer = 0; + miniChargedBytes = MINI_CHARGED_BYTES; + if(miniChargedBytes > max_quota_bytes) + { + gprsProc->vqAllocated.integer = miniChargedBytes; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = gprsProc->vqAllocated.integer - radiusItem->volumeThresholdDiff; + gprsProc->vthAllocated.exponent = 0; + chargedThisTime = chargedMiniRequested; + quotaBytes = miniChargedBytes; + } + else + { + long long extraBytes; + float extraCharged; + + chargedThisTime = chargedMiniRequested; + extraBytes = max_quota_bytes - miniChargedBytes; + extraCharged = ((extraBytes+BYTES_PER_BASIC_FEE-1)/BYTES_PER_BASIC_FEE)*tariff->basicFee*discount; + if(balance >= chargedThisTime+extraCharged) + { + gprsProc->vqAllocated.integer = max_quota_bytes; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = gprsProc->vqAllocated.integer - radiusItem->volumeThresholdDiff; + gprsProc->vthAllocated.exponent = 0; + chargedThisTime += extraCharged; + quotaBytes = max_quota_bytes; + } + else + { + extraCharged = (balance - chargedMiniRequested)/discount; + extraBytes = (extraCharged/tariff->basicFee)*BYTES_PER_BASIC_FEE; + gprsProc->vqAllocated.integer = miniChargedBytes + extraBytes; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = 0; + gprsProc->vthAllocated.exponent = 0; + chargedThisTime = balance; + quotaBytes = miniChargedBytes + extraBytes; + } + } + gprsProc->discount = discount; + shmp->caller_info.charge += chargedThisTime; + gprsProc->vqConsumed.integer = quotaBytes; + gprsProc->vqAllocatedThisTime = quotaBytes; + UpdateBalance(shmp,&shmp->caller_info, -chargedThisTime,chargedFee); + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,chargedThisTime,quotaBytes,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,quotaBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]allocate %lld bytes,charged %0.4f(balance:%0.4f,promotion:%0.4f),vq is %lld,vth is %lld at %s", + shmp->process_info.portid ,quotaBytes,chargedThisTime,chargedFee->balance,chargedFee->promotion, + gprsProc->vqAllocated.integer,gprsProc->vthAllocated.integer,__FUNCTION__); + return quotaBytes; +} + + +static long long allocateOtherPrepaidVolumeQuota(_state_data *shmp,u_char *failReason) +{ + PPS_COS_RADIUS_ITEM *radiusItem; + _gprs_process *gprsProc; + _gprs_tariff *tariff; + double balance; + float discount,chargedThisTime,quotaCharged; + int instance; + CHARGED_FEE *chargedFee; + long long quotaBytes,max_quota_bytes; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + + if(gprsProc->vqAllocated.integer >= MAX_BYTES_PER_SESSION) + { + strcpy((char *)failReason,"Max volume(10G) per session reached"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Max volume(10G) per session reached",shmp->process_info.portid); + return -2; + } + if(gprsProc->userType != PPS_PREPAID_USER) + return -1; + tariff = getGprsVolumeTariffWithRoamAndCap(shmp); + if(tariff == NULL) + { + strcpy((char *)failReason,"no gprs tariff assigned"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]no gprs tariff assigned",shmp->process_info.portid); + return -1; + } + else + { + gprsProc->gprsTariff = tariff; + gprsProc->destIP = tariff->destIp; + } + + radiusItem = getCosRadiusItem(&shmp->caller_info); + max_quota_bytes = MAX_VOLUME_BYTES_EACH_TIME; + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info); + if(balance <= 0) + { + strcpy((char *)failReason,"low fee"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]low fee",shmp->process_info.portid ); + return -1; + } + if(isPoolChildReachFeeLimit(&shmp->caller_info) == 2) + { + strcpy((char *)failReason,"Child account,reach limited fee"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s child account,reach limited fee",shmp->process_info.portid ,shmp->caller_info.number); + return -1; + } + chargedFee = &gprsProc->chargedFee; + memset(chargedFee,0,sizeof(CHARGED_FEE)); + chargedThisTime = 0; + quotaCharged = 0; + discount = (float)GetDiscount(tvnow.tv_sec,tariff->discountID)/100; + + quotaCharged = ((max_quota_bytes+BYTES_PER_BASIC_FEE-1)/BYTES_PER_BASIC_FEE)*tariff->basicFee*discount; + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]tariff:need allocate:%lld bytes,bascic fee:%0.4f,discount:%0.4f", + shmp->process_info.portid ,max_quota_bytes,tariff->basicFee,discount); + + if(balance >= quotaCharged) + { + gprsProc->vqAllocated.integer += max_quota_bytes; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = gprsProc->vqAllocated.integer - radiusItem->volumeThresholdDiff; + gprsProc->vthAllocated.exponent = 0; + chargedThisTime += quotaCharged; + quotaBytes = max_quota_bytes; + } + else + { + long long extraBytes; + float extraCharged; + + extraCharged = balance/discount; + extraBytes = (extraCharged/tariff->basicFee)*BYTES_PER_BASIC_FEE; + gprsProc->vqAllocated.integer += extraBytes; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = 0; + gprsProc->vthAllocated.exponent = 0; + chargedThisTime = balance; + quotaBytes = extraBytes; + } + gprsProc->discount = discount; + shmp->caller_info.charge += chargedThisTime; + gprsProc->vqConsumed.integer += quotaBytes; + gprsProc->vqAllocatedThisTime = quotaBytes; + UpdateBalance(shmp,&shmp->caller_info, -chargedThisTime,chargedFee); + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,chargedThisTime,quotaBytes,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,quotaBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]allocate %lld bytes,charged %0.4f(balance:%0.4f,promotion:%0.4f),vq is %lld,vth is %lld at %s", + shmp->process_info.portid ,quotaBytes,chargedThisTime,chargedFee->balance,chargedFee->promotion, + gprsProc->vqAllocated.integer,gprsProc->vthAllocated.integer,__FUNCTION__); + return quotaBytes; +} + +static long long getRefundBytes(_state_data *shmp) +{ + _gprs_process *gprsProc; + long long allocatedBytes,consumedBytes; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + allocatedBytes = calculateVolume(&gprsProc->vqAllocated); + if(allocatedBytes < 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]get allocated volume quota when Refund",shmp->process_info.portid ); + return 0; + } + consumedBytes = calculateVolume(&gprsProc->radiusReportedInfo.vq.vq); + if(consumedBytes < 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]get reported volume quota when Refund",shmp->process_info.portid ); + return 0; + } + if(allocatedBytes > consumedBytes) + return allocatedBytes - consumedBytes; + return 0; +} + +static long long getReportedBytes(_state_data *shmp) +{ + _gprs_process *gprsProc; + long long consumedBytes; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + consumedBytes = calculateVolume(&gprsProc->radiusReportedInfo.vq.vq); + if(consumedBytes < 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]get reported volume quota when Refund",shmp->process_info.portid ); + return 0; + } + + return consumedBytes; +} + + +static void refund(_account_info *ptr, float refundFee,CHARGED_FEE *chargeFee) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + //double promo_balance,balance; + float refundPromotioin = 0,refundBalance = 0,absPromotion; + + PutLogFunID("refund"); + + if(refundFee<=0) + { + chargeFee->balance = 0; + chargeFee->promotion= 0; + return; + } + absPromotion = abs(chargeFee->promotion); + if(absPromotion > 0) + { + if(refundFee > absPromotion) + { + refundPromotioin = absPromotion; + refundBalance = refundFee - absPromotion; + } + else + refundPromotioin = refundFee; + } + else + { + refundPromotioin = 0; + refundBalance = refundFee; + } + chargeFee->balance = refundBalance; + chargeFee->promotion= refundPromotioin; + shmp->prepaid_info[ptr->head][ptr->tail].promo_balance += refundPromotioin; + if(refundBalance <= ppsParam.serviceControl.maxBalance) + shmp->prepaid_info[ptr->head][ptr->tail].balance += refundBalance; + if(shmp->prepaid_info[ptr->head][ptr->tail].balance < 0) + shmp->prepaid_info[ptr->head][ptr->tail].balance = 0; + + increPoolChildCharged(ptr,-(refundBalance+refundPromotioin)); + debugmib.display.totalCharge -= refundBalance+refundPromotioin; +} + +static int firstAccessAcceptRefund(_state_data *shmp) +{ + _gprs_process *gprsProc; + _gprs_tariff *tariff; + //PPS_COS_RADIUS_ITEM *radiusItem; + long long refundBytes; + float refundFee;//,basicFee; + float discount; + int instance; + CHARGED_FEE *chargedFee; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + + //radiusItem = getCosRadiusItem(&shmp->caller_info); + tariff = gprsProc->gprsTariff; + discount = gprsProc->discount; + + if(tariff->basicFee == 0 || (discount == 0 && shmp->process_info.cap_flag==0)) + return 0; + + if(getReportedBytes(shmp) <= MINI_CHARGED_BYTES) + { + refundBytes = gprsProc->vqConsumed.integer - MINI_CHARGED_BYTES; + refundFee = shmp->caller_info.charge - MINI_CHARGED_FEE*discount; + gprsProc->vqConsumed.integer = MINI_CHARGED_BYTES; + shmp->caller_info.charge = MINI_CHARGED_FEE*discount; + } + else + { + refundBytes = getRefundBytes(shmp); + gprsProc->vqConsumed.integer -= refundBytes; + refundFee = (refundBytes/BYTES_PER_BASIC_FEE)*tariff->basicFee*discount; + shmp->caller_info.charge -= refundFee; + } + + chargedFee = &gprsProc->chargedFee; + + refund(&shmp->caller_info, refundFee,chargedFee); + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,-refundFee,-refundBytes,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,-refundBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Consumed(%lld bytes,%0.4f fee);refund %lld bytes,fee(balance:%0.4f,promotion:%0.4f) at %s", + shmp->process_info.portid ,gprsProc->vqConsumed.integer,shmp->caller_info.charge, + refundBytes,chargedFee->balance,chargedFee->promotion,__FUNCTION__); + return 1; +} + +static int otherAccessAcceptRefund(_state_data *shmp) +{ + _gprs_process *gprsProc; + _gprs_tariff *tariff; + long long refundBytes; + float refundFee; + float discount; + int instance; + CHARGED_FEE *chargedFee; + PPS_COS_RADIUS_ITEM *radiusItem; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + + + refundBytes = getRefundBytes(shmp); + + radiusItem = getCosRadiusItem(&shmp->caller_info); + if(refundBytes > gprsProc->vqAllocatedThisTime + radiusItem->volumeThresholdDiff) + refundBytes = gprsProc->vqAllocatedThisTime + radiusItem->volumeThresholdDiff; + + gprsProc->vqConsumed.integer -= refundBytes; + tariff = gprsProc->gprsTariff; + discount = gprsProc->discount; + + if(tariff->basicFee == 0 || (discount == 0 && shmp->process_info.cap_flag==0)) + return 0; + + refundFee = (refundBytes/BYTES_PER_BASIC_FEE)*tariff->basicFee*discount; + + chargedFee = &gprsProc->chargedFee; + shmp->caller_info.charge -= refundFee; + refund(&shmp->caller_info, refundFee,chargedFee); + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,-refundFee,-refundBytes,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,-refundBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Consumed(%lld bytes,%0.4f fee);refund %lld bytes,fee(balance:%0.4f promotion:%0.4f) at %s", + shmp->process_info.portid ,gprsProc->vqConsumed.integer,shmp->caller_info.charge, + refundBytes,chargedFee->balance,chargedFee->promotion,__FUNCTION__); + return 1; +} + +static int inactiveGsntRefund(_state_data *shmp) +{ + _gprs_process *gprsProc; + long long refundBytes; + float refundFee; + int instance; + CHARGED_FEE *chargedFee; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + chargedFee = &gprsProc->chargedFee; + + refundBytes = gprsProc->vqAllocatedThisTime; + refundFee = abs(chargedFee->balance+chargedFee->promotion); + + gprsProc->vqConsumed.integer -= refundBytes; + refund(&shmp->caller_info, refundFee,chargedFee); + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,-refundFee,-refundBytes,shmp); + } + updateVolumeThisMonth(&shmp->caller_info,-refundBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]inactive timeout,Consumed(%lld bytes,%0.4f fee);refund %lld bytes,fee(balance:%0.4f promotion:%0.4f) at %s", + shmp->process_info.portid ,gprsProc->vqConsumed.integer,shmp->caller_info.charge, + refundBytes,chargedFee->balance,chargedFee->promotion,__FUNCTION__); + return 1; +} + +static BOOL isFirstAccessAccept(_state_data *shmp) +{ + _gprs_process *gprsProc; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + if(gprsProc->qid - 1 == INIT_QID) + return TRUE; + return FALSE; +} + +static int pps_gprs_prepaidVolume_process(u_short portid) +{ + _gprs_process *gprsProc; + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst; + BOOL volumeFlag=FALSE,durationFlag=FALSE; + u_char failReason[128]={0}; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + gprsProc = &shmp->process_info.ppsService.gprs_process; + + switch(gprsProc->prepaidState) + { + case pps_gprs_idle: + if(gprsProc->radiusCommand == PPS_RADIUS_NEW_SERVICE) + { + gprsProc->radiusCommand = PPS_RADIUS_NO_CMD; + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + + if(checkMiniBalanceForGprs(shmp) == FALSE) + { + sendRadiusAccessReject(portid, (u_char *)"Low Balance for GPRS service"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s Low Balance for GPRS service",portid,shmp->caller_info.number); + pps_set_prepaid_state(pps_gprs_service_terminate); + break; + } + rst = allocateFirstPrepaidVolumeQuota(shmp,failReason); + if(rst > 0) + { + volumeFlag = TRUE;; + sendRadiusAccessAccept(portid,volumeFlag,durationFlag); + pps_set_prepaid_state(pps_gprs_wait_request); + } + else + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s %s",portid,shmp->caller_info.number,failReason); + sendRadiusAccessReject(portid,failReason); + pps_set_prepaid_state(pps_gprs_service_terminate); + } + } + break; + case pps_gprs_wait_request: + if(isAccessTimeout(shmp) == TRUE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]GSN access timeout at state:pps_gprs_wait_request",portid); + pps_set_prepaid_state(pps_gprs_access_timeout); + break; + } + switch(gprsProc->radiusCommand) + { + case PPS_RADIUS_NO_CMD: + break; + case PPS_RADIUS_THRESHOLD_REACHED: + gprsProc->radiusCommand = PPS_RADIUS_NO_CMD; + if(isVolumeThresholdReached(shmp) == TRUE) + { + if(allocateOtherPrepaidVolumeQuota(shmp,failReason) > 0) + { + volumeFlag = TRUE; + sendRadiusAccessAccept(portid,volumeFlag,durationFlag); + } + else + { + sendRadiusAccessReject(portid,failReason); + //pps_set_prepaid_state(pps_gprs_wait_quota_reached); + pps_set_prepaid_state(pps_gprs_access_timeout); + break; + } + } + break; + case PPS_RADIUS_QUOTA_REACHED: + case PPS_RADIUS_REMOTE_DISC: + case PPS_RADIUS_CLIENT_SERVICE_TER: + case PPS_RADIUS_ACCESS_SERVICE_TER: + case PPS_RADIUS_SERVICE_NOT_EST: + if(isFirstAccessAccept(shmp)==TRUE) + firstAccessAcceptRefund(shmp); + else + otherAccessAcceptRefund(shmp); + sendRadiusAccessAccept(portid,0,0); + pps_set_prepaid_state(pps_gprs_service_terminate); + break; + default: + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Ignore unsupported update result:%d at state:%d" + , portid,gprsProc->radiusCommand,gprsProc->state); + break; + } + break; + case pps_gprs_wait_quota_reached: + if(isAccessTimeout(shmp) == TRUE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]GSN access timeout at state:pps_gprs_wait_quota_reached",portid); + pps_set_prepaid_state(pps_gprs_access_timeout); + break; + } + switch(gprsProc->radiusCommand) + { + case PPS_RADIUS_NO_CMD: + break; + case PPS_RADIUS_QUOTA_REACHED: + case PPS_RADIUS_REMOTE_DISC: + case PPS_RADIUS_CLIENT_SERVICE_TER: + case PPS_RADIUS_ACCESS_SERVICE_TER: + case PPS_RADIUS_SERVICE_NOT_EST: + if(isFirstAccessAccept(shmp)==TRUE) + firstAccessAcceptRefund(shmp); + else + otherAccessAcceptRefund(shmp); + sendRadiusAccessAccept(portid,0,0); + pps_set_prepaid_state(pps_gprs_service_terminate); + break; + default: + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Ignore unsupported update result:%d at state:%d" + , portid,gprsProc->radiusCommand,gprsProc->state); + break; + } + break; + case pps_gprs_access_timeout: + //inactiveGsntRefund(shmp); + sendRadiusDisconnectReq(portid); + pps_set_prepaid_state(pps_gprs_wait_terminate); + break; + case pps_gprs_wait_terminate: + if(isWaitTerTimeOut(shmp,10) == TRUE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]GSN access timeout at state:pps_gprs_wait_terminate",portid); + pps_set_prepaid_state(pps_gprs_service_terminate); + break; + } + switch(gprsProc->radiusCommand) + { + case PPS_RADIUS_NO_CMD: + break; + case PPS_RADIUS_QUOTA_REACHED: + case PPS_RADIUS_REMOTE_DISC: + case PPS_RADIUS_CLIENT_SERVICE_TER: + case PPS_RADIUS_ACCESS_SERVICE_TER: + case PPS_RADIUS_SERVICE_NOT_EST: + if(isFirstAccessAccept(shmp)==TRUE) + firstAccessAcceptRefund(shmp); + else + otherAccessAcceptRefund(shmp); + sendRadiusAccessAccept(portid,0,0); + pps_set_prepaid_state(pps_gprs_service_terminate); + break; + default:/* not going to handle disconnect ack or nak */ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Ignore command:%d at pps_gprs_wait_terminate" + ,portid,gprsProc->radiusCommand); + break; + } + break; + case pps_gprs_service_terminate: + shmp->cdr_info.releasetime = tvnow.tv_sec; + SendGprsCDR(&shmp->caller_info,shmp); + result = SERVICE_EXIT_PPS; + break; + } + return result; +} + +int pps_gprs_process(u_short portid) +{ + _gprs_process *gprsProc; + _state_data *shmp; + int result = SERVICE_KEEP_STATE; + u_char failReason[128]={0}; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + gprsProc = &shmp->process_info.ppsService.gprs_process; + + switch(gprsProc->state) + { + case pps_gprs_idle: + switch(gprsProc->radiusCommand) + { + case PPS_RADIUS_NO_CMD: + break; + case PPS_RADIUS_NEW_SERVICE: + if(GetAccountPos(&shmp->caller_info) == TRUE) + { + PPS_COS_RADIUS_ITEM *radiusItem; + if(isUseLegal(&shmp->caller_info,failReason) == FALSE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s",shmp->process_info.portid ,failReason); + sendRadiusAccessReject(portid,failReason); + memset(gprsProc,0,sizeof(_gprs_process)); + pps_set_gprs_state(pps_gprs_idle); + result = SERVICE_EXIT_PPS; + break; + } + radiusItem = getCosRadiusItem(&shmp->caller_info); + if(radiusItem->gprsChargeFlag == 0) + { + gprsProc->userType = PPS_POSTPAID_USER; + pps_set_gprs_state(pps_gprs_postpaid); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Prepaid user:%s ask for gprs service,but no need to charge it",portid,shmp->caller_info.number); + break; + } + gprsProc->userType = PPS_PREPAID_USER; + shmp->context_info.callType = CT_GPRS; + pps_set_gprs_state(pps_gprs_prepaid); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Prepaid user:%s ask for gprs service",portid,shmp->caller_info.number); + } + else + { + gprsProc->userType = PPS_POSTPAID_USER; + pps_set_gprs_state(pps_gprs_postpaid); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Postpaid user:%s ask for gprs service",portid,shmp->caller_info.number); + } + break; + default: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Unsupported update result:%d at state:%d",portid, gprsProc->radiusCommand,gprsProc->state); + result = SERVICE_EXIT_PPS; + break; + } + break; + case pps_gprs_postpaid: + return pps_gprs_postpaid_process(portid); + break; + case pps_gprs_prepaid: + return pps_gprs_prepaidVolume_process(portid); + break; + } + return result; +} + +static long long GetAccountVolume(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountMsisdn"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + return shmp->prepaid_info[head][tail].gprsVolumeThisMonth; + } + return 0; +} + +static int sendGprsSessionInfo(_state_data *shmp,long long volume,ulong duration,float charge) +{ + u_char msg[MAX_SMS_LEN*4] = {0}; + long long volumeThisMonth; + + if(isReachGprsNotificationLimit(&shmp->caller_info)) + return 1; + strcpy((char *)msg, (char *)getSmsSentenceNative(0,SMS_GPRS_VOLUME_CONSUMED)); + sprintf((char *)msg+strlen((char *)msg),"%lldKB,",(volume+BYTES_PER_KB-1)>>10); + strcat((char *)msg, (char *)getSmsSentenceNative(0,SMS_GPRS_DURATION)); + sprintf((char *)msg+strlen((char *)msg),"%ldS,",duration); + strcat((char *)msg, (char *)getSmsSentenceNative(0,SMS_GPRS_CHARGED)); + + fillMoneyToContent(charge, (char *)msg+strlen((char *)msg)); + + volumeThisMonth = GetAccountVolume(shmp->caller_info.head,shmp->caller_info.tail); + msg[strlen((char *)msg)] = '.'; + strcat((char *)msg+strlen((char *)msg), (char *)getSmsSentenceNative(0,SMS_GPRS_VOLUME_THIS_MONTH)); + sprintf((char *)msg+strlen((char *)msg),"%lldKB.",(volumeThisMonth+BYTES_PER_KB-1)>>10); + + return smppSendMOSM((char *)shmp->caller_info.number, (char *)ppsParam.ppsTables.serviceNumber[GPRSPrepaidPostion].number + , msg, strlen((char *)msg),0); +} + +int reportGprsCDRIncrement(int duration, float charge, long gprsVolume) +{ + int index=0; + + PutLogFunID("reportGprsCDRIncrement"); + + index = pps_report.ptrTail; + pps_report.daily_report[index].call_report.gprs_record.gprsVolume += gprsVolume; + pps_report.daily_report[index].call_report.gprs_record.gprsDuration += duration; + pps_report.daily_report[index].call_report.gprs_record.gprsCharge += charge; + + pps_report.daily_report[index].balance_summary.today_charge += charge; + return 1; +} + + +void SendGprsCDR(_account_info *caller_info,_state_data *shmp) +{ + _tocdr_report pcdr; + char buf[BUFSIZE]={""}; + int balance; + int head, tail; + long charge; + ulong duration,volume; + _gprs_process *gprsProc; + struct in_addr nas_addr; + long long consumed_data_value=0; + + PutLogFunID("SendGprsCDR"); + + if(shmp == NULL) + return; + + if(caller_info->charge < 0.0) + return; + if(caller_info->charge > 1000000.00) + return; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + + if(0) + { + consumed_data_value = gprsProc->vqConsumed.integer; + } + if(1) + { + consumed_data_value = gprsProc->dqConsumed; + } + + if( consumed_data_value == 0) + return; + + memset(&pcdr,0,sizeof(_tocdr_report)); + + head = caller_info->head; + tail = caller_info->tail; + + pcdr.mtype = MO_CDR_TYPE; + + if (consumed_data_value < 0) + { + pcdr.type[0] = CT_GPRS_REFUND;// add a new cdr type for GPRS refund + pcdr.type[1] = CT_GPRS_REFUND>>8; + consumed_data_value = -consumed_data_value; + } + else + { + pcdr.type[0] = CT_GPRS; + pcdr.type[1] = CT_GPRS>>8; + } + + duration = shmp->cdr_info.releasetime - shmp->cdr_info.answertime; + + AsciiTime(buf, shmp->cdr_info.seizuretime); + AsciiToBcd(pcdr.seizuretime,buf,14); + AsciiTime(buf, shmp->cdr_info.answertime); + AsciiToBcd(pcdr.answertime,buf,14); + AsciiTime(buf, shmp->cdr_info.releasetime); + AsciiToBcd(pcdr.releasetime,buf,14); + + memcpy(pcdr.duration,&duration,4); + + charge = caller_info->charge; + charge = (int)(charge + 0.5);// ceil ==> int + memcpy(pcdr.charge,&charge,4); + balance = (int) (GetAccountBalance(head, tail) + 0.5); + memcpy(pcdr.balance,&balance,4); + + GetAccountMsisdn(head,tail,&pcdr.msisdn[1]); + ByteRev(pcdr.msisdn,9,0); + pcdr.msisdn[0]=0x91; + memcpy(pcdr.caller,pcdr.msisdn,9); + buf[0] = 0; + + //gprsProc = &shmp->process_info.ppsService.gprs_process; + + nas_addr.s_addr = gprsProc->sgsnIP; + sprintf((char *)pcdr.gprsSgsnIP, "%s",inet_ntoa(nas_addr)); + + nas_addr.s_addr = gprsProc->gsnIP; + sprintf((char *)pcdr.gprsGgsnIP, "%s",inet_ntoa(nas_addr)); + + nas_addr.s_addr = gprsProc->destIP; + sprintf((char *)pcdr.gprsDestIP, "%s",inet_ntoa(nas_addr)); + + volume = (consumed_data_value+BYTES_PER_KB-1) >> 10; + pcdr.gprsVolume[0] = volume >> 24; + pcdr.gprsVolume[1] = volume >> 16; + pcdr.gprsVolume[2] = volume >> 8; + pcdr.gprsVolume[3] = volume; + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + memcpy(pcdr.plan_id, &shmp->process_info.rest_if.plan_id, 4); + + GprsCDRStatistics(&pcdr,charge,volume); + StoreCDR(&pcdr); + pps_real_update_user_file(head, tail); + sendGprsSessionInfo(shmp,consumed_data_value,duration,charge); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]%s send gprs cdr",shmp->process_info.portid ,caller_info->number); +} + +int allocate_ps_data_volume_quota(_state_data *shmp, char *failReason) +{ + _gprs_process *gprsProc; + _gprs_tariff *tariff, gprsTariff; + float balance,chargedThisTime,quotaCharged; + float basicFee = 0.0; + float discount; + int instance; + CHARGED_FEE *chargedFee; + u_long quotaBytes,max_quota_bytes; + long long left_bundle_volume = 0; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + gprsProc->vqAllocatedThisTime = 0; + + if(shmp->caller_info.status == T_BLACKLIST || + shmp->caller_info.status == T_RELEASED || shmp->caller_info.status == T_EXTERNAL)// user status by user profile + { + strcpy(failReason,"Invalid account status0"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d] Invalid account status",shmp->process_info.portid); + return -1; + } + + if(shmp->caller_info.status != T_NORMAL || + shmp->caller_info.expired_flag == 1)// user status (read from user data) + { + strcpy(failReason,"Invalid account status"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d] Invalid account status",shmp->process_info.portid); + return -2; + } + + if(gprsProc->vqAllocated.integer >= MAX_BYTES_PER_SESSION)// Max 10G during the session + { + strcpy(failReason,"Max volume(10G) per session reached"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d] Max volume(10G) per session reached",shmp->process_info.portid); + return -3; + } + + if(OCS_with_external_CRM()) + { +#ifdef OCS_USE_REDIS_DB// get tariff and bundle + pps_send_query_tariff_req(shmp->process_info.portid); +#endif + if(shmp->process_info.rest_if.query_tariff_status == 3) + { + strcpy(failReason,"no gprs tariff assigned"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]no gprs tariff assigned",shmp->process_info.portid); + +#ifndef OCS_USE_REDIS_DB + pps_send_query_tariff_req(shmp->process_info.portid); +#endif + return -4; + } + memset(&gprsTariff, 0x00, sizeof(_gprs_tariff)); + tariff = gprsProc->gprsTariff = &gprsTariff; + gprsProc->gprsTariff->chargeUnit = shmp->process_info.rest_if.unit/1024; + gprsProc->gprsTariff->basicFee = shmp->process_info.rest_if.unit_charge; + discount = shmp->process_info.rest_if.tariff_discount; + gprsProc->discount = discount; + + } + else + { + tariff = getGprsVolumeTariffWithRoamAndCap(shmp);// read Gprs tariff + if(tariff == NULL) + { + strcpy(failReason,"no gprs tariff assigned"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]no gprs tariff assigned",shmp->process_info.portid); + return -4; + } + else + { + gprsProc->gprsTariff = tariff; + gprsProc->destIP = tariff->destIp; + } + } + + max_quota_bytes = pps_get_quota_per_request(); //MAX_VQ_BYTES_EACH_TIME_POST;// Quota for every CCR request + + if(OCS_with_external_CRM()) + { + if(shmp->process_info.rest_if.total_plan_value > 0) + left_bundle_volume = shmp->process_info.rest_if.total_plan_value - shmp->process_info.rest_if.used_plan_value; + if(left_bundle_volume<=0) + { + left_bundle_volume = 0; + shmp->process_info.bundle_flag = 0; + } + else + { + shmp->process_info.bundle_flag = 1; + if(left_bundle_volume>max_quota_bytes) + left_bundle_volume = max_quota_bytes ; + shmp->process_info.rest_if.used_plan_value += left_bundle_volume; + shmp->process_info.rest_if.plan_value_add_this_time = left_bundle_volume; + pps_send_update_plan_value_req(shmp->process_info.portid); + } +#ifndef OCS_USE_REDIS_DB + pps_send_query_tariff_req(shmp->process_info.portid);//get next tariff +#endif + } + else + left_bundle_volume = pps_get_account_bundle_data(shmp);// remain volume in bundle of user + + if(left_bundle_volume > 0) + { + if(left_bundle_volume < max_quota_bytes)// left bundle less than quota for each quest, allocate all left quota + { + max_quota_bytes = left_bundle_volume; + } + + basicFee = 0;// use bundle, do not charge other way + shmp->process_info.bundle_flag = 1;// bundle identifier + + subscribe_bundle_plan_send_warning_info(shmp);// low bundle reach threshold(<2048K), send SMS notification + } + else + { + if(shmp->process_info.bundle_flag )// bundle exaust, send SMS notification + { + long not_consumed_volume = shmp->process_info.ppsService.gprs_process.vqAllocated.integer - + shmp->process_info.ppsService.gprs_process.dqConsumed; + if( not_consumed_volume > 0) + { + gprsProc->vqAllocatedThisTime = not_consumed_volume; + return 1; + } + + gprsProc->vqAllocatedThisTime = 0; + shmp->process_info.bundle_flag = 0; + + subscribe_bundle_plan_send_used_up_info((char *)shmp->caller_info.number, SMS_BUNDLE_PLAN_DATA_USEDUP); + + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Bundle data is used up!",shmp->process_info.portid ); + + return 0; + } + + if(1)//no need to allocate non-charged small quote + { + if(shmp->process_info.ro_if.request_type == RT_INITIAL_REQUEST) + { + max_quota_bytes = pps_get_postpaid_quota_for_first_request(); + shmp->process_info.ro_if.post_charge = 1; + } + else + shmp->process_info.ro_if.post_charge = 0; + } + + basicFee = tariff->basicFee; + + shmp->process_info.bundle_flag = 0; + } + + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info); + if(balance <= 0.001 && shmp->process_info.bundle_flag == 0) + { + strcpy(failReason,"low fee"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]low fee with bundle flag=%d", + shmp->process_info.portid, shmp->process_info.bundle_flag ); + return -5; + } + + + chargedFee = &gprsProc->chargedFee; + memset(chargedFee,0,sizeof(CHARGED_FEE)); + chargedThisTime = 0; + quotaCharged = 0; + if(OCS_with_external_CRM()) + discount = shmp->process_info.rest_if.tariff_discount/100; + else + discount = (float)GetDiscount(tvnow.tv_sec,tariff->discountID)/100; + + //quotaCharged = ((max_quota_bytes+BYTES_PER_BASIC_FEE-1)/BYTES_PER_BASIC_FEE)*basicFee*discount; + quotaCharged = (max_quota_bytes*basicFee*discount)/BYTES_PER_BASIC_FEE; + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]tariff:need allocate:%lld bytes,bascic fee:%0.4f,discount:%0.4f,bundle data=%lld,quotaCharged:%.4f", + shmp->process_info.portid ,max_quota_bytes, basicFee,discount, left_bundle_volume,quotaCharged); + + if(balance >= quotaCharged) + { + gprsProc->vqAllocated.integer += max_quota_bytes; + chargedThisTime += quotaCharged; + quotaBytes = max_quota_bytes; + } + else + { + + if(0) + { + long long extraBytes; + float extraCharged; + + extraCharged = balance/discount; + extraBytes = (extraCharged/tariff->basicFee)*BYTES_PER_BASIC_FEE; + gprsProc->vqAllocated.integer += extraBytes; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = 0; + gprsProc->vthAllocated.exponent = 0; + chargedThisTime = balance; + quotaBytes = extraBytes; + + shmp->process_info.ro_if.post_charge = 0; + } + else + { + strcpy(failReason,"low fee"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]low fee for a minu charge", + shmp->process_info.portid); + return -5; + } + } + + gprsProc->discount = discount; + shmp->caller_info.charge += chargedThisTime; + gprsProc->vqConsumed.integer += quotaBytes; + gprsProc->vqAllocatedThisTime = quotaBytes; + + if( shmp->process_info.ro_if.post_charge == 0 ) + { + UpdateBalance(shmp,&shmp->caller_info, -chargedThisTime,chargedFee); + + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info,chargedThisTime,quotaBytes,shmp); + } + + if(shmp->process_info.bundle_flag) + {// pre-charge bundle first, refund when session stop + UpdateGprsBundleInfo(&shmp->caller_info,chargedThisTime, -quotaBytes, shmp); + } + + updateVolumeThisMonth(&shmp->caller_info,quotaBytes); + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT);// dual platform sync + } + + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]allocate %lld bytes,charged %0.4f(balance:%0.4f,promotion:%0.4f),vq is %lld,vth is %lld at %s", + shmp->process_info.portid ,quotaBytes,chargedThisTime,chargedFee->balance,chargedFee->promotion, + gprsProc->vqAllocated.integer,gprsProc->vthAllocated.integer,__FUNCTION__); + + return 1; +} + +int pps_refund_data_volume(_state_data *shmp) +{ + _gprs_process *gprsProc; + _gprs_tariff *tariff, gprsTariff; + long long refundBytes; + CHARGED_FEE *chargedFee; + float discount, refundFee; + int instance; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + + refundBytes = gprsProc->dqRefund; + + if(gprsProc->vqConsumed.integer > refundBytes) + { + gprsProc->vqConsumed.integer -= refundBytes; + } + else + { + //gprsProc->vqConsumed.integer = 0; + gprsProc->vqConsumed.integer -= refundBytes;// negative for cdr of GPRS refund + } + + if(OCS_with_external_CRM()) + { + memset(&gprsTariff, 0x00, sizeof(_gprs_tariff)); + tariff = gprsProc->gprsTariff = &gprsTariff; + gprsProc->gprsTariff->chargeUnit = shmp->process_info.rest_if.unit/1024; + gprsProc->gprsTariff->basicFee = shmp->process_info.rest_if.unit_charge; + discount = shmp->process_info.rest_if.tariff_discount/100.00; + gprsProc->discount = discount; + + + pps_print_event(shmp->process_info.logMsisdn,"[%05d] Refund %lld bytes, basicFee:%.4f, unit:%d, discount:%.f, at %s", + shmp->process_info.portid , + refundBytes, + tariff->basicFee, + tariff->chargeUnit, + discount, + __FUNCTION__); + + } + else + { + tariff = gprsProc->gprsTariff; + discount = gprsProc->discount; + } + + chargedFee = &gprsProc->chargedFee; + + if(shmp->process_info.bundle_flag == 1) + { + refundFee = 0; + } + else + { + if(tariff->basicFee == 0 || (discount == 0 && shmp->process_info.cap_flag==0)) + return 0; + + refundFee = (refundBytes/BYTES_PER_BASIC_FEE)*tariff->basicFee*discount; + shmp->caller_info.charge = shmp->caller_info.charge - refundFee; + refund(&shmp->caller_info, refundFee,chargedFee); + } + + + + if(shmp->process_info.cap_flag) + { + UpdateGprsCapInfo(&shmp->caller_info, refundFee, refundBytes,shmp); + } + if(shmp->process_info.bundle_flag) + { + if(OCS_with_external_CRM()) + { + if(shmp->process_info.rest_if.used_plan_value>=refundBytes) + { + shmp->process_info.rest_if.used_plan_value -= refundBytes; + shmp->process_info.rest_if.plan_value_add_this_time = (0x8000000000000000) | refundBytes; + pps_send_update_plan_value_req(shmp->process_info.portid); + } + } + else + { + UpdateGprsBundleInfo(&shmp->caller_info,refundFee, refundBytes,shmp); + } + } + + + updateVolumeThisMonth(&shmp->caller_info,-refundBytes); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Consumed(%lld bytes,%0.4f fee);refund %lld bytes,fee(balance:%0.4f promotion:%0.4f) at %s", + shmp->process_info.portid ,gprsProc->vqConsumed.integer,shmp->caller_info.charge, + refundBytes,chargedFee->balance,chargedFee->promotion,__FUNCTION__); + return 1; +} + +int pps_charge_postpaid_data(_state_data *shmp, long consumed_volume, long *uncharged_volume) +{ + _gprs_process *gprsProc; + _gprs_tariff *tariff, gprsTariff; + float balance,chargedThisTime,quotaCharged; + float basicFee = 0.0; + float discount; + int instance; + CHARGED_FEE *chargedFee; + u_long quotaBytes,max_quota_bytes; + long long left_bundle_volume = 0; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + gprsProc->vqAllocatedThisTime = 0; + + if(OCS_with_external_CRM()) + { + memset(&gprsTariff, 0x00, sizeof(_gprs_tariff)); + tariff = gprsProc->gprsTariff = &gprsTariff; + gprsProc->gprsTariff->chargeUnit = shmp->process_info.rest_if.unit/1024; + gprsProc->gprsTariff->basicFee = shmp->process_info.rest_if.unit_charge; + discount = shmp->process_info.rest_if.tariff_discount/100.00; + gprsProc->discount = discount; + + + pps_print_event(shmp->process_info.logMsisdn,"[%05d] Consumed %lld bytes, basicFee:%.4f, unit:%d, discount:%.f, at %s", + shmp->process_info.portid , + consumed_volume, + tariff->basicFee, + tariff->chargeUnit, + discount, + __FUNCTION__); + } + else + { + tariff = getGprsVolumeTariffWithRoamAndCap(shmp);// read Gprs tariff + + if(tariff == NULL) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]no gprs tariff assigned",shmp->process_info.portid); + return -4; + } + else + { + gprsProc->gprsTariff = tariff; + gprsProc->destIP = tariff->destIp; + discount = (float)GetDiscount(tvnow.tv_sec,tariff->discountID)/100.00; + + } + } + + left_bundle_volume = pps_get_account_bundle_data(shmp);// remain volume in bundle of user + + if(left_bundle_volume > 0) + { + if(left_bundle_volume > consumed_volume)// left bundle less than quota for each quest, allocate all left quota + { + UpdateGprsBundleInfo(&shmp->caller_info, 0.0, -consumed_volume, shmp); + basicFee = 0;// use bundle, do not charge other way + max_quota_bytes = 0; + } + else + { + UpdateGprsBundleInfo(&shmp->caller_info, 0.0, -left_bundle_volume, shmp); + //max_quota_bytes = consumed_volume - left_bundle_volume; + //basicFee = tariff->basicFee; + *uncharged_volume = consumed_volume - left_bundle_volume; + max_quota_bytes = 0; + basicFee = 0.0; + } + } + else + { + //max_quota_bytes = consumed_volume; + //basicFee = tariff->basicFee; + *uncharged_volume = consumed_volume; + //max_quota_bytes = 0; + //basicFee = 0.0; + max_quota_bytes = consumed_volume; + basicFee = tariff->basicFee; + + } + + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info); + if(balance <= 0.001) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]low fee to charge postpaid %.02ff", + shmp->process_info.portid, balance); + return -5; + } + + chargedFee = &gprsProc->chargedFee; + memset(chargedFee,0,sizeof(CHARGED_FEE)); + chargedThisTime = 0; + quotaCharged = 0; + + quotaCharged = ((max_quota_bytes+BYTES_PER_BASIC_FEE-1)/BYTES_PER_BASIC_FEE)*basicFee*discount; + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]tariff:need allocate:%lld bytes,bascic fee:%0.4f,discount:%0.4f @%s", + shmp->process_info.portid, max_quota_bytes, basicFee, discount, __FUNCTION__); + + if(balance >= quotaCharged) + { + gprsProc->vqAllocated.integer = max_quota_bytes; + chargedThisTime = quotaCharged; + quotaBytes = max_quota_bytes; + } + else + { + long long extraBytes; + float extraCharged; + + extraCharged = balance/discount; + extraBytes = (extraCharged/tariff->basicFee)*BYTES_PER_BASIC_FEE; + gprsProc->vqAllocated.integer = extraBytes; + gprsProc->vqAllocated.exponent = 0; + gprsProc->vthAllocated.integer = 0; + gprsProc->vthAllocated.exponent = 0; + chargedThisTime = balance; + quotaBytes = extraBytes; + } + + gprsProc->discount = discount; + shmp->caller_info.charge = chargedThisTime; + //gprsProc->vqConsumed.integer = quotaBytes; + gprsProc->vqConsumed.integer = consumed_volume; + gprsProc->vqAllocatedThisTime = quotaBytes; + + UpdateBalance(shmp,&shmp->caller_info, -chargedThisTime,chargedFee); + updateVolumeThisMonth(&shmp->caller_info,quotaBytes); + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee->balance,chargedFee->promotion,OMC_OCODE_EDIT);// dual platform sync + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Consumed(%lld bytes,%0.4f fee);uncharged %lld bytes,fee(balance:%0.4f promotion:%0.4f) at %s", + shmp->process_info.portid,consumed_volume,shmp->caller_info.charge, + *uncharged_volume,chargedFee->balance,chargedFee->promotion,__FUNCTION__); + + return 1; +} diff --git a/mss/pps/src/main/loadtl.c b/mss/pps/src/main/loadtl.c new file mode 100644 index 0000000..1709cb3 --- /dev/null +++ b/mss/pps/src/main/loadtl.c @@ -0,0 +1,1147 @@ +/* +** file name: loadtl.c +** +** Restructure tariff buffer to private shared memory. +** +*/ + +#include "../include/includes.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/ppsm.h" +#include "../include/param.h" + +_pps_prefix_node pps_prefix_table[PPS_PREFIX_NODE_NUM]; + +char HolidayDes[12][31][32]; +extern _tariff_private *blf_shmp; +extern _ram_data *ramshm_ptr; +static char prog_name[16]; + +extern PPSParamStruct ppsParam; +extern _state_machine *smshm_ptr; + +extern int GetMOTariffData(); + +#ifdef OCS_WITH_CRM +int ocs_create_crm_base_tariff_tree(); +#endif +int load_tariff_main() +{ + int i,j,len,tariffID; + FILE *fp=NULL,*fp1=NULL; + char bill_str[32]; + + _bill_tariff *shmp = NULL; + + + PutLogFunID("load_tariff_main"); + + sprintf(prog_name,"load tariff"); + +/* +#ifdef OCS_WITH_CRM + ocs_create_crm_base_tariff_tree(); + return 1; +#endif +*/ + if(OCS_with_external_CRM()==1) + { + ocs_create_crm_base_tariff_tree(); + return 1; + } + + + memcpy(&blf_shmp->comm_tariff, + &ramshm_ptr->tariff_data.comm_tariff, + sizeof(_comm_tariff)*MAX_ZONE_NUM); + fp = fopen(COMM_TARIFF,"w"); + if(fp !=NULL) + { + for(i=0;itariff_data.comm_tariff[i].cfChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].cfChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].roamingChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].roamingChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].ccChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].ccChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].cugChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].cugChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].favEditChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].favChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].favChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].cf_cugChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].cf_cugChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].cf_favChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].cf_favChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].cug_favChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].cug_favChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].cf_cug_favChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].cf_cug_favChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].childChangeChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].poolAccountChargeUnit, + ramshm_ptr->tariff_data.comm_tariff[i].poolAccountChargeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].activeFreeSMSCharegeAmount, + ramshm_ptr->tariff_data.comm_tariff[i].deactiveFreeSMSCharegeAmount + ); + } + fclose(fp); + } + + memcpy(blf_shmp->rent_tariff, ramshm_ptr->tariff_data.rent_tariff, + MAX_RENT_TARIFF * sizeof(_rent_tariff)*MAX_ZONE_NUM); + + fp = fopen(PARAM_CSV,"w"); + if(fp !=NULL) + { + for(i=0;itariff_data.rent_tariff[i][j].id !=0) + { + fprintf(fp,"%d,%d,%s,%d,%d,%f\n",i, + ramshm_ptr->tariff_data.rent_tariff[i][j].id, + ramshm_ptr->tariff_data.rent_tariff[i][j].description, + ramshm_ptr->tariff_data.rent_tariff[i][j].rent_type, + ramshm_ptr->tariff_data.rent_tariff[i][j].charge_date, + ramshm_ptr->tariff_data.rent_tariff[i][j].rent_amount); + } + } + fclose(fp); + } + + + memcpy(&blf_shmp->bill_tariff, + &ramshm_ptr->tariff_data.bill_tariff, + sizeof(_bill_tariff)*MAX_ZONE_NUM*BILLING_BASE_NUM); + fp = fopen(BASICTARIFF_CSV,"w"); + + for(i=0;itariff_data.bill_tariff[i][j]; + len = strlen(shmp->bill_id); + if(len == 0 ) break; + if(ppsParam.serviceControl.cos_group_flag) + tariffID = shmp->tariffID/COS_GROUP_NUM; + else + tariffID = shmp->tariffID; + if(fp !=NULL) + { + fprintf(fp,"%s,%s,%d,%d,%d,%d,%d,%d,%f,%d,%d,%ld,%f,%f,%ld,%f,%f,%ld,%f,%f\n", + shmp->bill_id, + shmp->area, + tariffID, //shmp->tariffID, + shmp->call_type, + shmp->discountID, + shmp->free_time, + shmp->unit_time, + shmp->mini_unit, + shmp->adjustment, + shmp->cap_flag, + shmp->tierRating.tierNumber, + shmp->tierRating.rating[0].units, + shmp->tierRating.rating[0].base_fee, + shmp->tierRating.rating[0].long_distance_fee, + shmp->tierRating.rating[1].units, + shmp->tierRating.rating[1].base_fee, + shmp->tierRating.rating[1].long_distance_fee, + shmp->tierRating.rating[2].units, + shmp->tierRating.rating[2].base_fee, + shmp->tierRating.rating[2].long_distance_fee + ); + } + } + if(fp !=NULL) fclose(fp); + + fp = fopen(DISCOUNT_CSV,"w"); + + for(i=0;ibill_discount[i][j], + ramshm_ptr->tariff_data.bill_discount[i][j].days,8); + if(fp !=NULL && ramshm_ptr->tariff_data.bill_discount[i][j].discount_id ==i){ + fprintf(fp,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + ramshm_ptr->tariff_data.bill_discount[i][j].discount_id, + j, + ramshm_ptr->tariff_data.bill_discount[i][j].days[1], + ramshm_ptr->tariff_data.bill_discount[i][j].days[2], + ramshm_ptr->tariff_data.bill_discount[i][j].days[3], + ramshm_ptr->tariff_data.bill_discount[i][j].days[4], + ramshm_ptr->tariff_data.bill_discount[i][j].days[5], + ramshm_ptr->tariff_data.bill_discount[i][j].days[6], + ramshm_ptr->tariff_data.bill_discount[i][j].days[0], + ramshm_ptr->tariff_data.bill_discount[i][j].days[7]); + } + } + if(fp !=NULL) fclose(fp); + + for(i=0;i<12;i++) + for(j=0;j<31;j++) + { + blf_shmp->holiday_flag[i][j] = ramshm_ptr->tariff_data.holiday_flag[i][j].mflag; + } + + memcpy(&blf_shmp->called_tariff, + &ramshm_ptr->tariff_data.called_tariff, + MAX_ZONE_NUM*CALLED_BASE_NUM*sizeof(_bill_tariff)); + + fp1 = fopen(BASICMTTARIFF_CSV,"w"); + + if(fp1 !=NULL) + { + for(i=0;itariff_data.called_tariff[i]; + shmp += j; + sprintf(bill_str, "%s",shmp->bill_id); + bill_str[16]=0; + len = strlen(bill_str); + if (len == 0 && j!=0) continue; + fprintf(fp1, + "%s,%s,%d,%d,%d,%d,%d,%d,%f,%d,%ld,%f,%f,%ld,%f,%f,%ld,%f,%f,%d\n", + shmp->bill_id, + shmp->area, + shmp->tariffID, + shmp->call_type, + shmp->discountID, + shmp->free_time, + shmp->unit_time, + shmp->mini_unit, + shmp->adjustment, + shmp->tierRating.tierNumber, + shmp->tierRating.rating[0].units, + shmp->tierRating.rating[0].base_fee, + shmp->tierRating.rating[0].long_distance_fee, + shmp->tierRating.rating[1].units, + shmp->tierRating.rating[1].base_fee, + shmp->tierRating.rating[1].long_distance_fee, + shmp->tierRating.rating[2].units, + shmp->tierRating.rating[2].base_fee, + shmp->tierRating.rating[2].long_distance_fee, + shmp->cap_flag); + } + } + if(fp1 !=NULL) fclose(fp1); + + memcpy(&blf_shmp->bill_sms, + &ramshm_ptr->tariff_data.bill_sms, + sizeof(_bill_sms)*MAX_ZONE_NUM*MAX_SMS_PREFIX); + + fp = fopen(BILL_SMS_CSV,"w"); + if(fp !=NULL) + { + for(i=0;itariff_data.bill_sms[i][j].id == j+1) + { + fprintf(fp,"%d,%s,%d,%s,%d,%d,%f,%d\n", + ramshm_ptr->tariff_data.bill_sms[i][j].id, + ramshm_ptr->tariff_data.bill_sms[i][j].bill_id, + ramshm_ptr->tariff_data.bill_sms[i][j].call_type, + ramshm_ptr->tariff_data.bill_sms[i][j].area, + ramshm_ptr->tariff_data.bill_sms[i][j].tariffID, + ramshm_ptr->tariff_data.bill_sms[i][j].discountID, + ramshm_ptr->tariff_data.bill_sms[i][j].base_fee, + ramshm_ptr->tariff_data.bill_sms[i][j].cap_flag); + } + } + } + if(fp !=NULL) fclose(fp); + + memcpy(&blf_shmp->gprs_tariff, + &ramshm_ptr->tariff_data.gprs_tariff, + sizeof(_gprs_tariff)*MAX_ZONE_NUM*MAX_GPRS_PREFIX); + + fp1 = fopen(GPRS_TARIFF_CSV,"w"); + if(fp1 !=NULL) + { + struct in_addr ip_addr; + u_char ipAsc[64]; + + for(i=0;itariff_data.gprs_tariff[i][j].destIp; + sprintf((char *)ipAsc, "%s", inet_ntoa(ip_addr)); + fprintf(fp1,"%d,%d,%s,%d,%f,%d,%d,%d,%d\n", + ramshm_ptr->tariff_data.gprs_tariff[i][j].tariffID, + ramshm_ptr->tariff_data.gprs_tariff[i][j].gprsID, + ipAsc, + ramshm_ptr->tariff_data.gprs_tariff[i][j].chargeUnit, + ramshm_ptr->tariff_data.gprs_tariff[i][j].basicFee, + ramshm_ptr->tariff_data.gprs_tariff[i][j].miniChargeUnit, + ramshm_ptr->tariff_data.gprs_tariff[i][j].initialAdjustment, + ramshm_ptr->tariff_data.gprs_tariff[i][j].cap_flag, + ramshm_ptr->tariff_data.gprs_tariff[i][j].discountID); + } + } + if(fp1 !=NULL) fclose(fp1); + + + memcpy(&blf_shmp->vas_tariff, + &ramshm_ptr->tariff_data.vas_tariff, + sizeof(VAS_TARIFF)*MAX_ZONE_NUM); + + fp = fopen(VAS_MMS_SEND_CSV,"w"); + if(fp !=NULL) + { + for(i=0;itariff_data.vas_tariff[i].vasMmsSendTariff[j].tariffID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].mmsSendID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].mmsType, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].prefix, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].callType, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].destName, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].discountID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].chargeFee, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsSendTariff[j].capFlag); + } + } + if(fp !=NULL) fclose(fp); + + fp1 = fopen(VAS_MMS_RETRIEVE_CSV,"w"); + if(fp1 !=NULL) + { + for(i=0;itariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].tariffID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].mmsRetrieveID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].prefix, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].callType, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].destName, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].discountID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].chargeFee, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsRetrieveTariff[j].capFlag); + } + } + if(fp1 !=NULL) fclose(fp1); + + fp = fopen(VAS_MMS_EMAIL_CSV,"w"); + if(fp !=NULL) + { + for(i=0;itariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].tariffID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].emailID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].prefix, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].callType, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].destName, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].discountID, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].chargeFee, + ramshm_ptr->tariff_data.vas_tariff[i].vasMmsEmailDeliverTariff[j].capFlag); + } + } + if(fp !=NULL) fclose(fp); + + if(ppsParam.serviceControl.cos_group_flag) + pps_create_tariff_table(); + + return 1; +} + +void ListTariffPlan(int tariff_id) +{ + char buf[1024],bill_str[20],area[32]; + _bill_tariff *shmp = NULL; + int num,i=0,j=0,len=0; + + PutLogFunID("ListTariffPlan"); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) + { + DebugMsg(debugmib.display.asciiOut,"Error tariff ID: %d, should be 0-%d", + tariff_id,MAX_ZONE_NUM-1); + return ; + } + AsciiTime(buf,ppsParam.fileOperation.nextTariffStartTime); + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"New tariff start time: %s!",buf); + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Comm tariff:"); + DebugMsg(debugmib.display.asciiOut,"Call forwarded unit: %02d", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].cfChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Call forwarded charge: %f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].cfChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Roaming charge unit: %02d", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].roamingChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Roaming charge charge: %f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].roamingChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Conference call unit: %02d", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].ccChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Conference call charge: %f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].ccChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Closed User Group unit: %02d", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].cugChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Closed User Group charge: %f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].cugChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Favortie edit charge: %f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].favEditChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Favorite call unit: %02d", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].favChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Favorite call charge: %f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].favChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Pool account change charge: %.04f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].childChangeChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Pool call unit: %.02d", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].poolAccountChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Pool call charge: %.04f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].poolAccountChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Activate Free SMS charge: %.04f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].activeFreeSMSCharegeAmount); + DebugMsg(debugmib.display.asciiOut,"Deactivate Free SMS charge: %.04f", + ramshm_ptr->tariff_data.comm_tariff[tariff_id].deactiveFreeSMSCharegeAmount); + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Rent:"); + for(num=0;numtariff_data.rent_tariff[tariff_id][num].id !=0){ + DebugMsg(debugmib.display.asciiOut,"%d,%s,%d,%d,%f", + ramshm_ptr->tariff_data.rent_tariff[tariff_id][num].id, + ramshm_ptr->tariff_data.rent_tariff[tariff_id][num].description, + ramshm_ptr->tariff_data.rent_tariff[tariff_id][num].rent_type, + ramshm_ptr->tariff_data.rent_tariff[tariff_id][num].charge_date, + ramshm_ptr->tariff_data.rent_tariff[tariff_id][num].rent_amount); + } + } + + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"MO Basic tariff"); + + //for(i=0;i<1;i++) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Tariff ID : %02d",tariff_id); + for (num=0; numtariff_data.bill_tariff[tariff_id]; + shmp += num; + sprintf(bill_str, "%s",shmp->bill_id); + bill_str[16]=0; + + len = strlen(bill_str); + + if (len == 0 ) continue; + sprintf(buf,"Prefix CT Area DID Free CUnit miniCU Adj."); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + + StringCat(bill_str," ",7); + strcpy(area,shmp->area); + StringCat(area," ",8); + DebugMsg(debugmib.display.asciiOut, + "%s %d %s %d %d %02d %d %f %d", + bill_str, + shmp->call_type, + area, + shmp->discountID, + shmp->free_time, + shmp->unit_time, + shmp->mini_unit, + shmp->adjustment, + shmp->cap_flag + ); + + DebugMsg(debugmib.display.asciiOut, + "tierInfo:%d,%d,%.04f,%.04f,%d,%.04f,%.04f,%d,%.04f,%.04f", + shmp->tierRating.tierNumber, + shmp->tierRating.rating[0].units, + shmp->tierRating.rating[0].base_fee, + shmp->tierRating.rating[0].long_distance_fee, + shmp->tierRating.rating[1].units, + shmp->tierRating.rating[1].base_fee, + shmp->tierRating.rating[1].long_distance_fee, + shmp->tierRating.rating[2].units, + shmp->tierRating.rating[2].base_fee, + shmp->tierRating.rating[2].long_distance_fee); + } + } + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"SMS Basic tariff"); + DebugMsg(debugmib.display.asciiOut,"ID Prefix CT Area Discount BaseFee"); + for(i=0;itariff_data.bill_sms[tariff_id][i].id == i+1) + { + DebugMsg(debugmib.display.asciiOut,"%d %d %s %d %s %d %f %d", + ramshm_ptr->tariff_data.bill_sms[tariff_id][i].id, + ramshm_ptr->tariff_data.bill_sms[tariff_id][i].call_type, + ramshm_ptr->tariff_data.bill_sms[tariff_id][i].bill_id, + ramshm_ptr->tariff_data.bill_sms[i][j].call_type, + ramshm_ptr->tariff_data.bill_sms[tariff_id][i].area, + ramshm_ptr->tariff_data.bill_sms[tariff_id][i].discountID, + ramshm_ptr->tariff_data.bill_sms[tariff_id][i].base_fee, + ramshm_ptr->tariff_data.bill_sms[tariff_id][i].cap_flag); + } + } + + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"MT Basic tariff"); + + for(i=0;i<1;i++) + { + DebugMsg(debugmib.display.asciiOut,"Tariff ID : %02d",tariff_id); + DebugMsg(debugmib.display.asciiOut, + "Prefix Area DID FreeT UnitT MiniU BaseF LongF Adjust"); + for (num=0; numtariff_data.called_tariff[tariff_id]; + shmp += num; + sprintf(bill_str, "%s",shmp->bill_id); + bill_str[16]=0; + + len = strlen(bill_str); + + if (len == 0 && num !=0) continue; + + StringCat(bill_str," ",7); + strcpy(area,shmp->area); + StringCat(area," ",8); + sprintf(buf,"Prefix CT Area DID Free CUnit miniCU Adj."); + DebugMsg(debugmib.display.asciiOut, + "%s %d %s %d %d %02d %d %f %d", + bill_str, + shmp->call_type, + area, + shmp->discountID, + shmp->free_time, + shmp->unit_time, + shmp->mini_unit, + shmp->adjustment, + shmp->cap_flag); + } + + DebugMsg(debugmib.display.asciiOut, + "Tier info:%d,%.04f,%.04f,%d,%.04f,%.04f,%d,%.04f,%.04f", + shmp->tierRating.rating[0].units, + shmp->tierRating.rating[0].base_fee, + shmp->tierRating.rating[0].long_distance_fee, + shmp->tierRating.rating[1].units, + shmp->tierRating.rating[1].base_fee, + shmp->tierRating.rating[1].long_distance_fee, + shmp->tierRating.rating[2].units, + shmp->tierRating.rating[2].base_fee, + shmp->tierRating.rating[2].long_distance_fee); + } + + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Discount: %d",tariff_id); + for(j=0;jtariff_data.bill_discount[tariff_id][j].days[1], + ramshm_ptr->tariff_data.bill_discount[tariff_id][j].days[2], + ramshm_ptr->tariff_data.bill_discount[tariff_id][j].days[3], + ramshm_ptr->tariff_data.bill_discount[tariff_id][j].days[4], + ramshm_ptr->tariff_data.bill_discount[tariff_id][j].days[5], + ramshm_ptr->tariff_data.bill_discount[tariff_id][j].days[6], + ramshm_ptr->tariff_data.bill_discount[tariff_id][j].days[0], + ramshm_ptr->tariff_data.bill_discount[tariff_id][j].days[7]); + + } + + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Holiday:"); + for(i=0;i<12;i++) + for(j=0;j<31;j++) + { + if(ramshm_ptr->tariff_data.holiday_flag[i][j].mflag ){ + DebugMsg(debugmib.display.asciiOut,"%d ,%d", + i+1, + j+1); + } + } + +} + +int ListCurrentTariff(int zone_id) +{ + int i,j,len; + char buf[4096]; + _bill_tariff *shmp; + static int debug_state = 0,num=0,listNum=0; + + PutLogFunID("ListCurrentTariff"); + if(debug_state == 0) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Comm tariff:"); + DebugMsg(debugmib.display.asciiOut,"Call forwarded unit: %02d", + blf_shmp->comm_tariff[zone_id].cfChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Call forwarded charge: %.04f", + blf_shmp->comm_tariff[zone_id].cfChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Roaming unit: %02d", + blf_shmp->comm_tariff[zone_id].roamingChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Roaming charge: %.04f", + blf_shmp->comm_tariff[zone_id].roamingChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Conference call unit: %02d", + blf_shmp->comm_tariff[zone_id].ccChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Conference call charge: %.04f", + blf_shmp->comm_tariff[zone_id].ccChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Closed User Group unit: %02d", + blf_shmp->comm_tariff[zone_id].cugChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Closed User Group charge: %.04f", + blf_shmp->comm_tariff[zone_id].cugChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Favorite change charge: %.04f", + blf_shmp->comm_tariff[zone_id].favEditChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Favorite call unit: %02d", + blf_shmp->comm_tariff[zone_id].favChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Favorite call charge: %.04f", + blf_shmp->comm_tariff[zone_id].favChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Pool account change charge: %.04f", + blf_shmp->comm_tariff[zone_id].childChangeChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Pool call unit: %.02d", + blf_shmp->comm_tariff[zone_id].poolAccountChargeUnit); + DebugMsg(debugmib.display.asciiOut,"Pool call charge: %.04f", + blf_shmp->comm_tariff[zone_id].poolAccountChargeAmount); + DebugMsg(debugmib.display.asciiOut,"Activate Free SMS charge: %.04f", + blf_shmp->comm_tariff[zone_id].activeFreeSMSCharegeAmount); + DebugMsg(debugmib.display.asciiOut,"Deactivate Free SMS charge: %.04f", + blf_shmp->comm_tariff[zone_id].deactiveFreeSMSCharegeAmount); + debug_state = 1; + return 0; + } + else if(debug_state == 1) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Rent:"); + DebugMsg(debugmib.display.asciiOut,"ID Desc. Type Date Rent"); + for(num=0;numtariff_data.rent_tariff[zone_id][num].id !=0) + { + DebugMsg(debugmib.display.asciiOut,"%d %s %d %d %f", + blf_shmp->rent_tariff[zone_id][num].id, + blf_shmp->rent_tariff[zone_id][num].description, + blf_shmp->rent_tariff[zone_id][num].rent_type, + blf_shmp->rent_tariff[zone_id][num].charge_date, + blf_shmp->rent_tariff[zone_id][num].rent_amount); + } + } + num = 0; + debug_state = 2; + DebugMsg(debugmib.display.asciiOut,"********************************************************************************"); + DebugMsg(debugmib.display.asciiOut,"********************************************************************************"); + return 0; + } + else if(debug_state == 2) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Baisc MO tariff:"); + listNum = 0; + for (;num= 10) + return 0; + + shmp = (_bill_tariff *) &blf_shmp->bill_tariff[zone_id]; + shmp += num; + + len = strlen(shmp->bill_id); + + if (len == 0 ) continue; + sprintf(buf,"Prefix CT Area DID Free CUnit miniCU Adj."); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + + DebugMsg(debugmib.display.asciiOut, + "%s %d %16s %d %d %02d %d %.04f", + shmp->bill_id, + shmp->call_type, + shmp->area, + shmp->discountID, + shmp->free_time, + shmp->unit_time, + shmp->mini_unit, + shmp->adjustment); + DebugMsg(debugmib.display.asciiOut, + "tierInfo:L-%d,A-(units:%d,bf:%.04f,lf:%.04f),B-(units:%d,bf:%.04f,lf:%.04f),C-(units:%d,bf:%.04f,lf:%.04f)", + shmp->tierRating.tierNumber, + shmp->tierRating.rating[0].units, + shmp->tierRating.rating[0].base_fee, + shmp->tierRating.rating[0].long_distance_fee, + shmp->tierRating.rating[1].units, + shmp->tierRating.rating[1].base_fee, + shmp->tierRating.rating[1].long_distance_fee, + shmp->tierRating.rating[2].units, + shmp->tierRating.rating[2].base_fee, + shmp->tierRating.rating[2].long_distance_fee); + listNum++; + } + debug_state = 3; + num = 0; + DebugMsg(debugmib.display.asciiOut,"********************************************************************************"); + DebugMsg(debugmib.display.asciiOut,"********************************************************************************"); + return 0; + } + else if(debug_state == 3) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"MT tariff:"); + listNum = 0; + for(;num= 10) + return 0; + if(blf_shmp->called_tariff[zone_id][num].bill_id[0] ==0/* && i!=0*/) + continue; + { + sprintf(buf,"Prefix CT Area DID Free CUnit miniCU Adj."); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + + sprintf(buf,"%s %d %16s %d %d %02d %d %.04f", + blf_shmp->called_tariff[zone_id][num].bill_id, + blf_shmp->called_tariff[zone_id][num].call_type, + blf_shmp->called_tariff[zone_id][num].area, + blf_shmp->called_tariff[zone_id][num].discountID, + blf_shmp->called_tariff[zone_id][num].free_time, + blf_shmp->called_tariff[zone_id][num].unit_time, + blf_shmp->called_tariff[zone_id][num].mini_unit, + blf_shmp->called_tariff[zone_id][num].adjustment + ); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + DebugMsg(debugmib.display.asciiOut, + "tierInfo:L-%d,A-(units:%d,bf:%.04f,lf:%.04f),B-(units:%d,bf:%.04f,lf:%.04f),C-(units:%d,bf:%.04f,lf:%.04f)", + blf_shmp->called_tariff[zone_id][num].tierRating.tierNumber, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[0].units, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[0].base_fee, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[0].long_distance_fee, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[1].units, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[1].base_fee, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[1].long_distance_fee, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[2].units, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[2].base_fee, + blf_shmp->called_tariff[zone_id][num].tierRating.rating[2].long_distance_fee); + } + listNum++; + } + debug_state = 4; + num = 0; + DebugMsg(debugmib.display.asciiOut,"********************************************************************************"); + DebugMsg(debugmib.display.asciiOut,"********************************************************************************"); + return 0; + } + else if(debug_state == 4) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Discount:"); + DebugMsg(debugmib.display.asciiOut, + "Period Mon. Tue. Wed. Thu. Fri. Sat. Sun. Hol."); + for(j=0;jbill_discount[zone_id][j][1], + blf_shmp->bill_discount[zone_id][j][2], + blf_shmp->bill_discount[zone_id][j][3], + blf_shmp->bill_discount[zone_id][j][4], + blf_shmp->bill_discount[zone_id][j][5], + blf_shmp->bill_discount[zone_id][j][6], + blf_shmp->bill_discount[zone_id][j][0], + blf_shmp->bill_discount[zone_id][j][7]); + } + debug_state = 5; + return 0; + } + else if(debug_state == 5) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"SMS Basic tariff:"); + DebugMsg(debugmib.display.asciiOut,"ID Prefix CT Area Discount BaseFee"); + for(i=0;ibill_sms[zone_id][i].id == i+1) + { + DebugMsg(debugmib.display.asciiOut,"%d %8s %d %16s %d %.04f", + blf_shmp->bill_sms[zone_id][i].id, + blf_shmp->bill_sms[zone_id][i].bill_id, + blf_shmp->bill_sms[zone_id][i].call_type, + blf_shmp->bill_sms[zone_id][i].area, + blf_shmp->bill_sms[zone_id][i].discountID, + blf_shmp->bill_sms[zone_id][i].base_fee); + } + } + debug_state = 6; + return 0; + } + else if(debug_state == 6) + { + struct in_addr ip_addr; + u_char ipAsc[64]; + + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Gprs tariff:"); + DebugMsg(debugmib.display.asciiOut,"ID destIP Cunit BaseFee miniCUnits adj capFlag Discount"); + for(i=0;igprs_tariff[zone_id][i].destIp; + sprintf((char *)ipAsc, "%s", inet_ntoa(ip_addr)); + DebugMsg(debugmib.display.asciiOut,"%d %s %d %.04f %d %d %d %d", + blf_shmp->gprs_tariff[zone_id][i].gprsID, + ipAsc, + blf_shmp->gprs_tariff[zone_id][i].chargeUnit, + blf_shmp->gprs_tariff[zone_id][i].basicFee, + blf_shmp->gprs_tariff[zone_id][i].miniChargeUnit, + blf_shmp->gprs_tariff[zone_id][i].initialAdjustment, + blf_shmp->gprs_tariff[zone_id][i].cap_flag, + blf_shmp->gprs_tariff[zone_id][i].discountID + ); + } + debug_state = 7; + num = 0; + return 0; + } + else if(debug_state == 7) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"VAS MMS Send Tariff"); + listNum = 0; + for(;num= 10) + return 0; + if(strlen((char *)blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].prefix) == 0) + continue; + { + sprintf(buf,"mmsType prefix calltype destName dsID fee capFlag"); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + + sprintf(buf,"%d %s %d %s %d %0.4f %d", + blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].mmsType, + blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].prefix, + blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].callType, + blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].destName, + blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].discountID, + blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].chargeFee, + blf_shmp->vas_tariff[zone_id].vasMmsSendTariff[num].capFlag + ); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + } + listNum++; + } + debug_state = 8; + num = 0; + DebugMsg(debugmib.display.asciiOut,"********************************************************************************"); + return 0; + } + else if(debug_state == 8) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"MMS retrieve tariff:"); + for(;numvas_tariff[zone_id].vasMmsRetrieveTariff[num].prefix, + blf_shmp->vas_tariff[zone_id].vasMmsRetrieveTariff[num].callType, + blf_shmp->vas_tariff[zone_id].vasMmsRetrieveTariff[num].destName, + blf_shmp->vas_tariff[zone_id].vasMmsRetrieveTariff[num].discountID, + blf_shmp->vas_tariff[zone_id].vasMmsRetrieveTariff[num].chargeFee, + blf_shmp->vas_tariff[zone_id].vasMmsRetrieveTariff[num].capFlag + ); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + } + debug_state = 9; + num = 0; + return 0; + } + else if(debug_state == 9) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"MMS Email tariff:"); + for(;numvas_tariff[zone_id].vasMmsEmailDeliverTariff[num].prefix, + blf_shmp->vas_tariff[zone_id].vasMmsEmailDeliverTariff[num].callType, + blf_shmp->vas_tariff[zone_id].vasMmsEmailDeliverTariff[num].destName, + blf_shmp->vas_tariff[zone_id].vasMmsEmailDeliverTariff[num].discountID, + blf_shmp->vas_tariff[zone_id].vasMmsEmailDeliverTariff[num].chargeFee, + blf_shmp->vas_tariff[zone_id].vasMmsEmailDeliverTariff[num].capFlag + ); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + } + debug_state = 10; + num = 0; + return 0; + } + else if(debug_state == 10) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Holiday:"); + DebugMsg(debugmib.display.asciiOut,"Month - Day"); + for(i=0;i<12;i++) + for(j=0;j<31;j++) + { + if(blf_shmp->holiday_flag[i][j]){ + DebugMsg(debugmib.display.asciiOut,"%02d - %02d", + i+1, + j+1); + } + } + debug_state = 0; + return 1; + } + return 1; +} + +void ListCurrentTariffWithMsisdn(char *number) +{ + char buf[4096]; + + _bill_tariff ptar; + + int zone_id; + + PutLogFunID("ListCurrentTariffWithMsisdn"); + + for(zone_id=0;zone_id=0x41 && prefix_digits[0]<=0x45) + { + digit = prefix_digits[0]-0x41+0x0a; + } + + if(len == 0 || digit >= 0x0E) + { + return 0; + } + else + { + if(pps_prefix_table[iroot].sub[digit] == 0) + { + if(pps_prefix_node_ptr < PPS_PREFIX_NODE_NUM - 1) + pps_prefix_table[iroot].sub[digit] = pps_prefix_node_ptr++; + else + { + printf("Fail to build prefix table, resource limit\n"); + return 0; //resource limit + } + } + + isub = pps_prefix_table[iroot].sub[digit]; + pps_prefix_table[iroot].flag |= 0x02; + + if(len == 1 )// || (prefix_digits[1]-0x30) >= 0x0E) + { + if((pps_prefix_table[isub].flag & 0x01) == 0x01) + { + DebugMsg(debugmib.display.asciiOut,"duplicated prefix found: table index: %d", + table_index); + } + pps_prefix_table[isub].flag |= 0x01; + pps_prefix_table[isub].prefix_index = table_index; + return 1; + } + else + { + return pps_add_charge_prefix(isub, &prefix_digits[1], len - 1, table_index); + } + } + return 0; +} + +int pps_create_tariff_table() +{ + int iroot=0,len=0; + int index=0; + char tmpBuf[128]; + + + pps_prefix_node_ptr = MAX_ZONE_NUM_NEW+1; + memset(&pps_prefix_table,0,sizeof(_pps_prefix_node)*PPS_PREFIX_NODE_NUM); + + for(iroot=0;iroottariff_data.bill_tariff[iroot][index].bill_id); + + len = strlen(tmpBuf); + + if(len==0 ) + continue; + if(len>TARIFF_PREFIX_LEN) + len = TARIFF_PREFIX_LEN; + pps_add_charge_prefix(iroot/COS_GROUP_NUM, + tmpBuf, + //ramshm_ptr->tariff_data.bill_tariff[iroot][index].bill_id, + len, + iroot*BILLING_BASE_NUM+index); + } + } + DebugMsg(debugmib.display.asciiOut,"prefix ptr=%d",pps_prefix_node_ptr); + return 1; +} + +int pps_search_charge_prefix(u_short iroot, char *digits, u_char len) +{ + short prefix_index=-1; + unsigned short iNode=0; + u_char digit=digits[0]-0x30; + + + if(digits[0]>=0x41 && digits[0]<=0x45) + { + digit = digits[0]-0x41+0x0a; + } + + iNode = pps_prefix_table[iroot].sub[digit]; + + if(len == 0 || digit>13 || iNode>= PPS_PREFIX_NODE_NUM) + return prefix_index; + + if(len == 1) + { + if((pps_prefix_table[iNode].flag & 0x01) != 0x00) + prefix_index = pps_prefix_table[iNode].prefix_index; + return prefix_index; + } + else + { + if((pps_prefix_table[iNode].flag & 0x02) == 0x00) + { + if((pps_prefix_table[iNode].flag & 0x01) != 0x00) + { + prefix_index = pps_prefix_table[iNode].prefix_index; + } + return prefix_index; + } + if(iNode < iroot) + return prefix_index; + + prefix_index = pps_search_charge_prefix(iNode, &digits[1],len - 1); + if(prefix_index<0 && (pps_prefix_table[iNode].flag & 0x01) == 0x01) + { + prefix_index = pps_prefix_table[iNode].prefix_index; + } + return prefix_index; + } + return prefix_index; +} + +int pps_get_charge_prefix(u_char cosID,char *dialing_number) +{ + int len; + + len = strlen(dialing_number); + if(len==0) + return -1; + /* + if(len>TARIFF_PREFIX_LEN) + len = TARIFF_PREFIX_LEN; + */ + return pps_search_charge_prefix(cosID, dialing_number, len); +} + +#ifdef OCS_WITH_CRM +int ocs_create_crm_base_tariff_tree() +{ + int iroot=0,len=0; + int index=0; + char tmpBuf[128]; + + + pps_prefix_node_ptr = 1; + memset(&pps_prefix_table,0,sizeof(_pps_prefix_node)*PPS_PREFIX_NODE_NUM); + + for(index=0;indextariff_data.base_tariff[index].bill_id); + + len = strlen(tmpBuf); + if(len==0 ) + continue; + if(len>TARIFF_PREFIX_LEN) + len = TARIFF_PREFIX_LEN; + + pps_add_charge_prefix(iroot, tmpBuf, len, index); + } + + DebugMsg(debugmib.display.asciiOut,"prefix ptr=%d",pps_prefix_node_ptr); + + return 1; + +} + + +int ocs_get_charge_prefix(char *dialed_number, char *prefix, char *area_name, int *call_type) +{ + int len; + int index = -1; + + len = strlen(dialed_number); + if(len==0) + return 0; + + index = pps_search_charge_prefix(0, dialed_number, len); + if(index == -1) + return 0; + + strcpy(prefix, ramshm_ptr->tariff_data.base_tariff[index].bill_id); + strcpy(area_name, ramshm_ptr->tariff_data.base_tariff[index].area); + *call_type = ramshm_ptr->tariff_data.base_tariff[index].call_type; + + return 1; + +} + +#endif diff --git a/mss/pps/src/main/masterSlaveCard.c b/mss/pps/src/main/masterSlaveCard.c new file mode 100644 index 0000000..9a7a259 --- /dev/null +++ b/mss/pps/src/main/masterSlaveCard.c @@ -0,0 +1,3055 @@ + +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + +#include "../include/plat_inc.h" +#include "../../../../plat/scf/src/include/scfmsg.h" +#include "../../../../plat/scf/src/include/scfdef.h" + + +#include "../include/ppsMibTable.h" +#include "../include/mfunc.h" + +extern PPSParamStruct ppsParam; +extern struct timeval tvnow; +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr;; + +extern u_short debug_messages; +extern int logMsgFlag; + + +extern int checkTransferedPartialFee(_account_info *callerInfo,float feeTransfered); + +extern int StuffCapMessage(CapArg capArg, PCAP_Message pcap_message); +extern int ppsDebugCapMsg(CAP_Message *cap_message,int flag); +extern void FeeTransferTransaction(_state_data *shmp); +static int getParentNumber(_prepaid_info *prepaidInfo,u8 *parentNumber); +static int getMaxCalls(_prepaid_info *prepaidInfo); +static int getMaxSMS(_prepaid_info *prepaidInfo); +static int getMaxConsume(_prepaid_info *prepaidInfo); +static int getCallsMadeToday(_prepaid_info *prepaidInfo); +static int getSMSToday(_prepaid_info *prepaidInfo); +static int getConsumeFee(_prepaid_info *prepaidInfo); +static int checkMasterFee(u_short portid); +static int RealTransferToSlave(_state_data *shmp); +static int smppNotifyMasterADD(u_char *masterNumber,u_char *slaveNumber); +static int smppNotifyMasterDEL(u_char *masterNumber,u_char *slaveNumber); +static int smppNotifySlaveADD(u_char *masterNumber,u_char *slaveNumber); +static int smppNotifySlaveDEL(u_char *masterNumber,u_char *slaveNumber); +static int getAddSlaveCharge(_account_info *accountInfo); +static int getAddingSlaveCosId(_state_data *shmp,MASTER_SLAVE_ADD *add); +static u_char getChildNum(u_short portid); +static void setChildNum(u_short portid,u_char childNum); +extern BOOL isPromotionCanBeTransfered(_account_info *accountInfo); + +int masterChangeSlaveCharge(_state_data *shmp,_account_info *slaveInfo); +int IncreasePoolAccountChangeCounter(int head, int tail); + +void ppsgetdaytime_readFormat(char *daytime_buf); + + +enum{ + S_MASTER_ADD_IDLE, + S_MASTER_ADD_WAIT_SLAVE, + S_MASTER_ADD_WAIT_COS, + S_MASTER_ADD_PLAY_CONFIRM, + S_MASTER_ADD_WAIT_PLAY_CONFIRM, + S_MASTER_ADD_WAIT_CONFIRM, + S_MASTER_ADD_PROCESSING, + S_MASTER_ADD_WAIT_PLAY_DONE, + S_MASTER_ADD_EXIT, +}; + + +/****************************** enquiry ***********************************************/ + _prepaid_info *getPrepaidInfo(_account_info *account) +{ + int head,tail; + + if(account == NULL) + return NULL; + head = account->head; + tail = account->tail; + if (account->head < MSISDN_HEAD_NUM && account->tail < UNIT_STORE_ACCOUNT) + { + return &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + //return 1; + } + return NULL; +} + +int getHowManyChildren(_prepaid_info *prepaidInfo) +{ + if(prepaidInfo == NULL) + return -1; + return prepaidInfo->poolAccount.roleParty.parent.childNumber; +} + +int increMasterChildren(_prepaid_info *prepaidInfo) +{ + if(prepaidInfo == NULL) + return 0; + prepaidInfo->poolAccount.roleParty.parent.childNumber++; + if(prepaidInfo->poolAccount.roleParty.parent.childNumber > POOL_MAX_CHILD) + prepaidInfo->poolAccount.roleParty.parent.childNumber = POOL_MAX_CHILD; + return prepaidInfo->poolAccount.roleParty.parent.childNumber; +} + +int decMasterChildren(_prepaid_info *prepaidInfo) +{ + if(prepaidInfo == NULL) + return 0; + if(prepaidInfo->poolAccount.roleParty.parent.childNumber <= 0) + prepaidInfo->poolAccount.roleParty.parent.childNumber = 0; + else + prepaidInfo->poolAccount.roleParty.parent.childNumber--; + return prepaidInfo->poolAccount.roleParty.parent.childNumber; +} + +static int getChildNumber(_prepaid_info *prepaidInfo,u8 childIndex,u_char *childNumber) +{ + u8 *bcdNumber,len; + + if(prepaidInfo == NULL) + return -1; + if(childIndex <= 0 || childIndex > POOL_MAX_CHILD) + return -1; + bcdNumber = prepaidInfo->poolAccount.roleParty.parent.childMsisdn[childIndex - 1]; + len = bcdNumber[MAX_MSISDN_BLEN-1]; + /* + if(len > MAX_MSISDN_ALEN || len < 3) + return -1; + */ + BcdToAscii((char *)childNumber,bcdNumber,(MAX_MSISDN_BLEN-1)*2); + childNumber[len] = 0; + return len; +} + + +static void SendDesignatedVoiceAndCollectInfo(u_short portid) +{ + int dlgid,invokeid=0,len; + u_char u_msisdn[12]; + char buf[32]; + CAP_Message cap_message; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + CapMessageID *pMID; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendFavPromptAndCollectUserInfo"); + + shmp += portid; + AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PromptAndCollectUserInformation; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + + pPCUI->collectedInfo.choice_id = 0x00; + pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1; + pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = + shmp->process_info.maxPCUInfoLen; + pPCUI->collectedInfo.collectedDigits.optional_flag = 0x79; + memcpy(pPCUI->collectedInfo.collectedDigits.endOfReplyDigit, + shmp->process_info.endOfReplyDigit,3); + pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt; + pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1; + + pPCUI->optional_flag = 0x03; + pPCUI->disconnectFromIPForbidden = 0x01; + pPCUI->informationToSend.choice_id = 0x00; + pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPCUI->informationToSend.inbandInfo.messageID; + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + +shmp->process_info.voiceID; + pMID->variableMessage.variableParts.num = 2; + + + pMID->variableMessage.variableParts.variablePart[0].choice_id = 1; + strcpy(buf,shmp->process_info.tmpDigits); + len = strlen(buf); + if(len>18) + len = 18; + ppsAsciiToBcdR(u_msisdn,buf,((len+1)/2)*2); + pMID->variableMessage.variableParts.variablePart[0].number[0] = (len+1)/2+1; + if(len%2==0) + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x04; + else + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x24; + memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2], + u_msisdn, + (len+1)/2); + + pMID->variableMessage.variableParts.variablePart[1].choice_id = 0; + pMID->variableMessage.variableParts.variablePart[1].integer = getChildNum(portid); + + pPCUI->informationToSend.inbandInfo.optional_flag = 0x07; + pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPCUI->informationToSend.inbandInfo.duration = 0x00; + pPCUI->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +static void SendSlaveParentNumber(u_short portid) +{ + u8 parentNumber[MAX_MSISDN_BLEN]={0},parentNumberAscci[MAX_MSISDN_BLEN*2]={0},u_msisdn[32]={0}; + _prepaid_info *prepaidInfo; + int len; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + CapVariablePart *pV; + u8 index=0; + + PutLogFunID("SendSlaveParentNumber"); + + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return; + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + SLAVE_ENQUIRY_PARENT_NUMBER; + pMID->variableMessage.variableParts.num = 1; + + getParentNumber(prepaidInfo,parentNumber); + /********************************* parent number ************************************/ + index = 0; + len = parentNumber[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)parentNumberAscci,parentNumber,18); + StringCut((char *)parentNumberAscci,'F'); + parentNumberAscci[len] = 0; + ppsAsciiToBcdR(u_msisdn, (char *)parentNumberAscci,len); + if(len>(MAX_MSISDN_BLEN-1)*2) + len = (MAX_MSISDN_BLEN - 1 )*2; + + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 1; + + pV->number[0] = (len+1)/2+1; + if(len%2==0) + { + pV->number[1] = 0x04; + memcpy(&pV->number[2],u_msisdn,(len+1)/2); + } + else + { + pV->number[1] = 0x24; + memcpy(&pV->number[2],u_msisdn,(len+1)/2); + pV->number[2+(len+1)/2] &=0x0F; + } + /********************************* parent number ************************************/ + + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return; +} + +static void SendSlaveLimits(u_short portid) +{ + int maxConsumePerDay,maxCallsPerDay,maxSMSPerDay,balance,centbalance,hth_b,th_b,h_b,b_b;; + u8 buf[256]={0}; + _prepaid_info *prepaidInfo; + int resolution=100; + //int len; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + CapVariablePart *pV; + u8 index=0; + + PutLogFunID("SendSlaveLimits"); + + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return; + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + SLAVE_ENQUIRY_LIMITS; + pMID->variableMessage.variableParts.num = 3; + + maxCallsPerDay = getMaxCalls(prepaidInfo); + maxSMSPerDay = getMaxSMS(prepaidInfo); + maxConsumePerDay = getMaxConsume(prepaidInfo); + resolution = getSystemCurrencyResolution(); + + /********************************* max calls per day ************************************/ + index = 0; + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 0; + pV->integer = maxCallsPerDay; + /********************************* max calls per day ************************************/ + + + /********************************* max SMS per day ************************************/ + index = 1; + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 0; + pV->integer = maxSMSPerDay; + /********************************* max SMS per day ************************************/ + + /********************************* max consumption per day ************************************/ + index = 2; + balance = maxConsumePerDay; + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 4; + sprintf((char *)buf,"%02d",hth_b); + + ppsAsciiToBcdR(&pV->price[0], (char *)buf,2); + sprintf((char *)buf,"%d%d",th_b,h_b); + + ppsAsciiToBcdR(&pV->price[1], (char *)buf,2); + sprintf((char *)buf,"%02d",b_b); + + ppsAsciiToBcdR(&pV->price[2], (char *)buf,2); + sprintf((char *)buf,"%02d",centbalance); + + ppsAsciiToBcdR(&pV->price[3], (char *)buf,2); + /********************************* max consumption per day ************************************/ + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return; +} + +static void SendSlaveToday(u_short portid) +{ + int chargedToday,balance,centbalance,hth_b,th_b,h_b,b_b; + int dailedToday,smsToday; + u8 buf[256]={0}; + _prepaid_info *prepaidInfo; + int resolution=100; + //int len; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + CapVariablePart *pV; + u8 index=0; + + PutLogFunID("SendSlaveEnquiryResult"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return; + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + /* account balance */ + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + SLAVE_ENQUIRY_TODAY; + pMID->variableMessage.variableParts.num = 3; + + dailedToday = getCallsMadeToday(prepaidInfo); + smsToday = getSMSToday(prepaidInfo); + chargedToday = getConsumeFee(prepaidInfo); + resolution = getSystemCurrencyResolution(); + + /********************************* calls today ************************************/ + index = 0; + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 0; + pV->integer = dailedToday; + /********************************* calls today ************************************/ + + + /********************************* SMS today ************************************/ + index = 1; + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 0; + pV->integer = smsToday; + /********************************* SMS today ************************************/ + + + /********************************* consumption today ************************************/ + index = 2; + balance = chargedToday; + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 4; + sprintf((char *)buf,"%02d",hth_b); + + ppsAsciiToBcdR(&pV->price[0], (char *)buf,2); + sprintf((char *)buf,"%d%d",th_b,h_b); + + ppsAsciiToBcdR(&pV->price[1], (char *)buf,2); + sprintf((char *)buf,"%02d",b_b); + + ppsAsciiToBcdR(&pV->price[2], (char *)buf,2); + sprintf((char *)buf,"%02d",centbalance); + + ppsAsciiToBcdR(&pV->price[3], (char *)buf,2); + /********************************* consumption today ************************************/ + + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return; +} + + + +static void SendSlaveInfo(u_short portid) +{ + int dlgid,invokeid=0; + //u_char u_msisdn[12]; + //char buf[32]; + CAP_Message cap_message; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + CapMessageID *pMID; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendFavPromptAndCollectUserInfo"); + + shmp += portid; + AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PromptAndCollectUserInformation; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + + pPCUI->collectedInfo.choice_id = 0x00; + pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1; + pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = 1; + pPCUI->collectedInfo.collectedDigits.optional_flag = 0x78; + pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt; + pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1; + + pPCUI->optional_flag = 0x03; + pPCUI->disconnectFromIPForbidden = 0x01; + pPCUI->informationToSend.choice_id = 0x00; + pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPCUI->informationToSend.inbandInfo.messageID; + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + MASTER_CARD_HOW_MANY_CHILDREN; + pMID->variableMessage.variableParts.num = 2; + + + pMID->variableMessage.variableParts.variablePart[0].choice_id = 0; + pMID->variableMessage.variableParts.variablePart[0].integer = getChildNum(portid); + + pMID->variableMessage.variableParts.variablePart[1].choice_id = 0; + pMID->variableMessage.variableParts.variablePart[1].integer = getChildNum(portid); + + pPCUI->informationToSend.inbandInfo.optional_flag = 0x07; + pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPCUI->informationToSend.inbandInfo.duration = 0x00; + pPCUI->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +static void playChildNumber(u_short portid,u_char *childNumber) +{ + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + shmp->process_info.voiceID = MASTER_CARD_CHILD_NUMBER; + strcpy(shmp->process_info.tmpDigits, (char *)childNumber); + SendDesignatedVoiceAndCollectInfo(portid); +} + +#define changeEnquirySlaveState(portid,val) do { \ + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;\ + enquiry->state = val;\ + shmp->process_info.serviceInput = 0;\ + shmp->process_info.funnel = 0; \ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + + +static u8 getEnquirySlaveState(u_short portid) +{ + _state_data *shmp; + MASTER_SLAVE_ENQUIRY *enquiry; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + return enquiry->state; +} + + +static int WaitForEnquirySalveSelect(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + MASTER_SLAVE_ENQUIRY *enquiry; + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > enquiry->childNum +'0')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + + enquiry->choice = input_msg[0] - '0'; + return result; +} + + +static int WaitForSlaveEnquiryFunc(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + MASTER_SLAVE_ENQUIRY *enquiry; + + PutLogFunID("WaitForChoice"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > '3')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + enquiry->choice = input_msg[0] - '0'; + return result; +} + +static int WaitForMasterEnquiryFunc(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + MASTER_SLAVE_ENQUIRY *enquiry; + + PutLogFunID("WaitForChoice"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > '3')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + enquiry->choice = input_msg[0] - '0'; + return result; +} + + +static int getEnquiryChoice(_state_data *shmp) +{ + MASTER_SLAVE_ENQUIRY *enquiry; + + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + return enquiry->choice; +} + +static void clearEnquirySlaveInfo(u_short portid) +{ + _state_data *shmp; + MASTER_SLAVE_ENQUIRY *enquiry; + PutLogFunID("clearEnquirySlaveInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + memset(enquiry,0,sizeof(MASTER_SLAVE_ENQUIRY)); +} + +static void setChildNum(u_short portid,u_char childNum) +{ + _state_data *shmp; + MASTER_SLAVE_ENQUIRY *enquiry; + PutLogFunID("clearEnquirySlaveInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + enquiry->childNum = childNum; +} + +static u_char getChildNum(u_short portid) +{ + _state_data *shmp; + MASTER_SLAVE_ENQUIRY *enquiry; + PutLogFunID("clearEnquirySlaveInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry; + return enquiry->childNum; +} + +static int getParentNumber(_prepaid_info *prepaidInfo,u8 *parentNumber) +{ + u8 *bcdNumber; + + if(prepaidInfo == NULL) + return -1; + bcdNumber = prepaidInfo->poolAccount.roleParty.child.parentMsisdn; + memcpy(parentNumber,bcdNumber,MAX_MSISDN_BLEN); + return 1; +} + +static int getMaxCalls(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + u8 cos_id; + COS_Pool_Account *pA; + + cos_id = prepaidInfo->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = &cosTableItem->poolAccount[0]; + return pA->roleParty.child.maxCallsPerDay; +} + +static int getMaxSMS(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + u8 cos_id; + COS_Pool_Account *pA; + + cos_id = prepaidInfo->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = &cosTableItem->poolAccount[0]; + return pA->roleParty.child.maxSMSPerDay; +} + +static int getMaxConsume(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + u8 cos_id; + COS_Pool_Account *pA; + + cos_id = prepaidInfo->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = &cosTableItem->poolAccount[0]; + return pA->roleParty.child.maxFeePerDay; +} + +static int getCallsMadeToday(_prepaid_info *prepaidInfo) +{ + return prepaidInfo->poolAccount.roleParty.child.callsToday; +} +static int getSMSToday(_prepaid_info *prepaidInfo) +{ + return prepaidInfo->poolAccount.roleParty.child.smsToday; +} + +static int getConsumeFee(_prepaid_info *prepaidInfo) +{ + return abs(prepaidInfo->poolAccount.roleParty.child.chargedToday); +} + + +enum SLAVE_ENQUIRY_STATE +{ + S_SLAVE_ENQUIRY_IDLE = 0, + S_SLAVE_ENQUIRY_PARENT, + S_SLAVE_ENQUIRY_LIMITS, + S_SLAVE_ENQUIRY_TODAY, + S_SLAVE_PLAY_INFO, + S_SLAVE_PLAY_DONE, +}; + +static int slaveEnquiryProc(u_short portid) +{ + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst,choice; + //u_char childNumber[MAX_MSISDN_BLEN*2] = {0}; + _prepaid_info *prepaidInfo; + MASTER_SLAVE_ENQUIRY *enquiry; + + PutLogFunID("slaveEnquiryProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(getEnquirySlaveState(portid)) + { + case S_SLAVE_ENQUIRY_IDLE: + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return (result = SERVICE_EXIT_PPS); + clearEnquirySlaveInfo(portid); + playPromptAndCollectVoice(portid,SLAVE_ENQUIRY_MENU,1); + changeEnquirySlaveState(portid,S_SLAVE_PLAY_DONE); + break; + case S_SLAVE_ENQUIRY_PARENT: + SendSlaveParentNumber(portid); + changeEnquirySlaveState(portid,S_SLAVE_PLAY_INFO); + break; + case S_SLAVE_ENQUIRY_LIMITS: + SendSlaveLimits(portid); + changeEnquirySlaveState(portid,S_SLAVE_PLAY_INFO); + break; + case S_SLAVE_ENQUIRY_TODAY: + SendSlaveToday(portid); + changeEnquirySlaveState(portid,S_SLAVE_PLAY_INFO); + break; + case S_SLAVE_PLAY_INFO: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + playPromptAndCollectVoice(portid,SLAVE_ENQUIRY_MENU,1); + changeEnquirySlaveState(portid,S_SLAVE_PLAY_DONE); + } + else + result = SERVICE_EXIT_PPS; + break; + case S_SLAVE_PLAY_DONE: + rst = WaitForSlaveEnquiryFunc(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + choice = getEnquiryChoice(shmp); + switch(choice) + { + case 0: + result = SERVICE_RETURN_TO_PARENT; + break; + case 1: + changeEnquirySlaveState(portid,S_SLAVE_ENQUIRY_PARENT); + break; + case 2: + changeEnquirySlaveState(portid,S_SLAVE_ENQUIRY_LIMITS); + break; + case 3: + default: + changeEnquirySlaveState(portid,S_SLAVE_ENQUIRY_TODAY); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,SLAVE_ENQUIRY_MENU,1); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + } + return result; +} + +enum MASTER_ENQUIRY_STATE +{ + S_MASTER_ENQUIRY_IDLE = 0, + S_MASTER_ENQUIRY_SELECT_INDEX, + S_MASTER_ENQUIRY_SELECT_FUNC, + S_MASTER_ENQUIRY_WAIT_PLAY_DONE, +}; + +static int masterEnquiryProc(u_short portid) +{ + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst,choice; + u_char childNumber[MAX_MSISDN_BLEN*2] = {0}; + _prepaid_info *prepaidInfo; + MASTER_SLAVE_ENQUIRY *enquiry; + + PutLogFunID("masterEnquiryProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(getEnquirySlaveState(portid)) + { + case S_MASTER_ENQUIRY_IDLE: + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return (result = SERVICE_EXIT_PPS); + clearEnquirySlaveInfo(portid); + rst = getHowManyChildren(prepaidInfo); + if(rst <= 0) + { + playPromptVoice(portid,ENQUIRY_EMPTY); + changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_WAIT_PLAY_DONE); + } + else + { + setChildNum(portid,rst); + SendSlaveInfo(portid); + changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_SELECT_INDEX); + } + break; + case S_MASTER_ENQUIRY_SELECT_INDEX: + rst = WaitForEnquirySalveSelect(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return (result = SERVICE_EXIT_PPS); + choice = getEnquiryChoice(shmp); + switch(choice) + { + case 0: + result = SERVICE_RETURN_TO_PARENT; + break; + default: + rst = getChildNumber(prepaidInfo,choice,childNumber); + if(rst > 0) + { + playChildNumber(portid,childNumber); + changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_SELECT_INDEX); + } + else + { + playPromptAndCollectVoice(portid,NO_CHILD_NUMBER_RELATED,1); + changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_SELECT_INDEX); + } + break; + } + break; + case INPUT_ERROR_REINPUT: + changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_IDLE); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_ENQUIRY_WAIT_PLAY_DONE: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + result = SERVICE_RETURN_TO_PARENT; + } + else + result = SERVICE_EXIT_PPS; + break; + } + return result; +} +/****************************** enquiry ***********************************************/ + + + +/****************************** add ***********************************************/ +#define changeMasterAddState(portid,val) do { \ + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;\ + add->state = val;\ + shmp->process_info.serviceInput = 0;\ + shmp->process_info.funnel = 0;\ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + + +static u8 getMasterAddState(u_short portid) +{ + _state_data *shmp; + MASTER_SLAVE_ADD *add; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + return add->state; +} + +static void clearMasterAddInfo(u_short portid) +{ + _state_data *shmp; + MASTER_SLAVE_ADD *add; + + PutLogFunID("clearAddSlaveInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + memset(add,0,sizeof(MASTER_SLAVE_ADD)); +} + +static int isMasterFullSlave(u_short portid) +{ + _prepaid_info *prepaidInfo; + u8 result; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return TRUE; + result = getHowManyChildren(prepaidInfo); + if(result >= POOL_MAX_CHILD) + return TRUE; + return FALSE; +} + +static int WaitingForMasterAddInputSlave(_state_data *shmp) +{ + u8 input_msg[64] = {0},len,i; + //float fee; + int result; + MASTER_SLAVE_ADD *add; + + PutLogFunID("WaitingForMasterInputSlave"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + len = strlen((char *)input_msg) % (2*MAX_MSISDN_BLEN); + + if(len > MAX_MSISDN_ALEN || len < 3) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + + for(i=0;i '9') + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + } + CutUnknownPrefix((char *)input_msg); + if(!strcmp((char *)shmp->caller_info.number, (char *)input_msg)) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + return (result = INPUT_ERROR_REINPUT); + } + + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + strcpy((char *)add->slaveInfo.number, (char *)input_msg); + return result; +} + +static int SendMasterAddConfirmToSrf(u_short portid) +{ + u8 slaveNumber[MAX_MSISDN_BLEN]; + int len; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + CapVariablePart *pV; + u8 index=0; + MASTER_SLAVE_ADD *add; + + PutLogFunID("SendMasterAddConfirmToSrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + MASTER_CONFIRM_ADD; + pMID->variableMessage.variableParts.num = 2; + + + /********************************* slave number ************************************/ + index = 0; + len = strlen((char *)add->slaveInfo.number); + ppsAsciiToBcdR(slaveNumber, (char *)add->slaveInfo.number,len); + if(len>(MAX_MSISDN_BLEN-1)*2) + len = (MAX_MSISDN_BLEN - 1 )*2; + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 1; + + pV->number[0] = (len+1)/2+1; + if(len%2==0) + { + pV->number[1] = 0x04; + memcpy(&pV->number[2],slaveNumber,(len+1)/2); + } + else + { + pV->number[1] = 0x24; + memcpy(&pV->number[2],slaveNumber,(len+1)/2); + pV->number[2+(len+1)/2] &=0x0F; + } + /********************************* slave number ************************************/ + + + index = 1; + pV = &pMID->variableMessage.variableParts.variablePart[index]; + pV->choice_id = 0; + pV->integer = add->cosID; + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; + +} + +static int checkAddSlaveNumber(_state_data *shmp) +{ + //MASTER_SLAVE_ADD *add; + u_char slaveBCD[MAX_MSISDN_BLEN]; + _account_info *slave_info; + _prepaid_info *prepaidInfo; + int i,len; + + PutLogFunID("checkAddSlaveNumber"); + + slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.slaveInfo; + if(GetAccountPos(slave_info) == FALSE) + { + return 2; + } + + if((prepaidInfo = getPrepaidInfo(slave_info)) == NULL) + return 2; + + if(prepaidInfo->poolAccount.role != MASTER_SLAVE_NONE) + return 1; + memset(slaveBCD,0,MAX_MSISDN_BLEN); + len = strlen((char *)slave_info->number); + AsciiToBcd(slaveBCD, (char *)slave_info->number,(len+1)/2*2); + slaveBCD[MAX_MSISDN_BLEN-1] = len; + if(len %2 ==0) + slaveBCD[len/2] = 0xFF; + else + slaveBCD[len/2] |= 0x0F; + + for(i=0;ipoolAccount.roleParty.parent.childMsisdn[i][MAX_MSISDN_BLEN-1] < 3) + continue; + if(!memcmp(slaveBCD,prepaidInfo->poolAccount.roleParty.parent.childMsisdn[i],(len+1)/2*2)) + return 1; + } + + return 0; +} + +static int WaitingForMasterAddInputCos(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + MASTER_SLAVE_ADD *add; + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > '1')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + add->cosID = input_msg[0] - '0'; + return result; +} + +static int masterAddWaitForChoice(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + MASTER_SLAVE_ADD *add; + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > '3')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + add->choice= input_msg[0] - '0'; + + return result; +} + +static int getMasterAddChoice(_state_data *shmp) +{ + MASTER_SLAVE_ADD *add; + + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + return add->choice; +} + +static void addProcessSetMaster(_state_data *shmp) +{ + _account_info *slave_info; + _prepaid_info *prepaidInfo; + UserData_Pool_Account *poolAccount; + u8 len,index,*childMsisdnBCD; + u_char *childMsisdnASCCI; + int charge; + + slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.slaveInfo; + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return; + + poolAccount = &prepaidInfo->poolAccount; + poolAccount->role = MASTER_SLAVE_PARENT; + + for(index=0;indexroleParty.parent.childMsisdn[index][MAX_MSISDN_BLEN-1] < 3) + break; + } + if(index >= POOL_MAX_CHILD) + return; + childMsisdnBCD = poolAccount->roleParty.parent.childMsisdn[index]; + memset(childMsisdnBCD,0,MAX_MSISDN_BLEN); + childMsisdnASCCI = slave_info->number; + len = strlen((char *)childMsisdnASCCI); + AsciiToBcd(childMsisdnBCD, (char *)childMsisdnASCCI,(len+1)/2*2); + childMsisdnBCD[MAX_MSISDN_BLEN-1] = len; + if(len %2 ==0) + childMsisdnBCD[len/2] = 0xFF; + else + childMsisdnBCD[len/2] |= 0x0F; + + increMasterChildren(prepaidInfo); + charge = masterChangeSlaveCharge(shmp,slave_info); + smppNotifyMasterADD(shmp->caller_info.number,slave_info->number); + SendAccountRealSync_2(&shmp->caller_info,-charge,0.0,OMC_OCODE_EDIT); +} + +static void addProcessSetSlave(_state_data *shmp) +{ + _account_info *slave_info; + _prepaid_info *prepaidInfo,*master; + UserData_Pool_Account *poolAccount; + COSTable *cosTableItem; + u8 len,tmp; + + slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.slaveInfo; + if((master = getPrepaidInfo(&shmp->caller_info)) == NULL) + return; + if((prepaidInfo = getPrepaidInfo(slave_info)) == NULL) + return ; + poolAccount = &prepaidInfo->poolAccount; + poolAccount->role = MASTER_SLAVE_CHILD; + + memset(poolAccount->roleParty.child.parentMsisdn,0xff,MAX_MSISDN_BLEN); + len = strlen((char *)shmp->caller_info.number); + + AsciiToBcd(poolAccount->roleParty.child.parentMsisdn, (char *)shmp->caller_info.number,(len+1)/2*2); + poolAccount->roleParty.child.parentMsisdn[MAX_MSISDN_BLEN-1] = len; + if(len %2 ==0) + poolAccount->roleParty.child.parentMsisdn[len/2] = 0xFF; + else + poolAccount->roleParty.child.parentMsisdn[len/2] |= 0x0F; + + poolAccount->roleParty.child.callsToday = 0; + poolAccount->roleParty.child.chargedToday = 0; + + cosTableItem = &ppsParam.ppsTables.cosTable[master->cos_id]; + + tmp = shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.cosID%MAX_CHILD_COS_PER_PARENT; + prepaidInfo->cos_id = cosTableItem->poolAccount[0].roleParty.parent.cosIDForChild[tmp]; + smppNotifySlaveADD(shmp->caller_info.number,slave_info->number); + SendAccountRealSync_2(slave_info,0.0,0.0,OMC_OCODE_EDIT); +} + +static int masterAddProc(u_short portid) +{ + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst; + MASTER_SLAVE_ADD *add; + + PutLogFunID("addProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + + switch(getMasterAddState(portid)) + { + case S_MASTER_ADD_IDLE: + clearMasterAddInfo(portid); + if(isMasterFullSlave(portid) == TRUE) + { + playPromptVoice(portid,ADD_FAIL_FULL); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE); + } + else + { + playPromptAndCollectVoice(portid,MASTER_INPUT_CHILD_ADD,MAX_IVR_INPUT_LEN); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_SLAVE); + } + break; + case S_MASTER_ADD_WAIT_SLAVE: + rst = WaitingForMasterAddInputSlave(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = checkAddSlaveNumber(shmp); + switch(rst) + { + case 0: + playPromptAndCollectVoice(portid,MASTER_SELECT_COS,1); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_COS); + break; + case 1:/* is already a master or slave number */ + playPromptAndCollectVoice(portid,ADD_FAIL_ALREADY_EXIST,MAX_IVR_INPUT_LEN); + changeMasterAddState(portid,S_MASTER_ADD_IDLE); + break; + case 2:/* not exist in pps */ + playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_ADD_WAIT_COS: + rst = WaitingForMasterAddInputCos(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = checkMasterFee(portid); + switch(rst) + { + case CHECK_TRANSFERED_FEE_OK: + changeMasterAddState(portid,S_MASTER_ADD_PLAY_CONFIRM); + break; + case CHECK_TRANSFERED_FEE_INSUFFIENT: + playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE); + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + default: + playPromptVoice(portid,TRANSFERED_FEE_EXPIERED); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,MASTER_SELECT_COS,1); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_ADD_PLAY_CONFIRM: + SendMasterAddConfirmToSrf(portid); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_CONFIRM); + break; + case S_MASTER_ADD_WAIT_PLAY_CONFIRM: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + playPromptAndCollectVoice(portid,CONFIRM_LISTEN_AGAIN,1); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_CONFIRM); + } + else + result = SERVICE_EXIT_PPS; + break; + case S_MASTER_ADD_WAIT_CONFIRM: + rst = masterAddWaitForChoice(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = getMasterAddChoice(shmp); + switch(rst) + { + case CONFIRM_OK: + changeMasterAddState(portid,S_MASTER_ADD_PROCESSING); + break; + case CONFIRM_ENTER_AGAIN: + changeMasterAddState(portid,S_MASTER_ADD_IDLE); + break; + case CONFIRM_LISTEN_RE: + changeMasterAddState(portid,S_MASTER_ADD_PLAY_CONFIRM); + break; + case CONFIRM_CANCEL: + changeMasterAddState(portid,S_MASTER_ADD_EXIT); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,YES_OR_NO,1); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_ADD_PROCESSING: + addProcessSetMaster(shmp); + addProcessSetSlave(shmp); + RealTransferToSlave(shmp); + playPromptVoice(portid,MASTER_ADD_SUCCESS); + changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE); + break; + case S_MASTER_ADD_WAIT_PLAY_DONE: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + changeMasterAddState(portid,S_MASTER_ADD_EXIT); + } + else + result = SERVICE_EXIT_PPS; + break; + case S_MASTER_ADD_EXIT: + result = SERVICE_RETURN_TO_PARENT; + break; + default: + result = SERVICE_EXIT_PPS; + break; + } + return result; +} +/****************************** add ***********************************************/ + + + +/****************************** delete ***********************************************/ +#define changeMasterDelState(portid,val) do { \ + del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;\ + del->state = val;\ + shmp->process_info.serviceInput = 0;\ + shmp->process_info.funnel = 0;\ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + +static u8 getMasterDelState(u_short portid) +{ + _state_data *shmp; + MASTER_SLAVE_DEL *del; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del; + return del->state; +} + +static void clearMasterDelInfo(u_short portid) +{ + _state_data *shmp; + MASTER_SLAVE_DEL *del; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del; + memset(del,0,sizeof(MASTER_SLAVE_DEL)); +} + +static int isMasterEmptySlave(u_short portid) +{ + _prepaid_info *prepaidInfo; + u8 result; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return TRUE; + result = getHowManyChildren(prepaidInfo); + if(result <= 0) + return TRUE; + return FALSE; +} + +static int WaitingForMasterDelInputSlave(_state_data *shmp) +{ + u8 input_msg[64] = {0},len,i; + int result; + MASTER_SLAVE_DEL *del; + + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + len = strlen((char *)input_msg) % (2*MAX_MSISDN_BLEN); + + for(i=0;i '9') + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + } + CutUnknownPrefix((char *)input_msg); + del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del; + strcpy((char *)del->slaveInfo.number, (char *)input_msg); + return result; +} + + +static void SendMasterDelConfirmToSrf(u_short portid) +{ + int dlgid,invokeid=0,len; + u_char u_msisdn[12]; + //char buf[32]; + CAP_Message cap_message; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + CapMessageID *pMID; + MASTER_SLAVE_DEL *del; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + PutLogFunID("SendFavPromptAndCollectUserInfo"); + + AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir); + + del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del; + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PromptAndCollectUserInformation; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + + pPCUI->collectedInfo.choice_id = 0x00; + pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1; + pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = 1; + pPCUI->collectedInfo.collectedDigits.optional_flag = 0x78; + pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt; + pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 0; + + pPCUI->optional_flag = 0x03; + pPCUI->disconnectFromIPForbidden = 0x01; + + pPCUI->informationToSend.choice_id = 0x00; + pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPCUI->informationToSend.inbandInfo.messageID; + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + MASTER_CONFIRM_DEL; + pMID->variableMessage.variableParts.num = 1; + + pMID->variableMessage.variableParts.variablePart[0].choice_id = 1; + len = strlen((char *)del->slaveInfo.number); + ppsAsciiToBcdR(u_msisdn, (char *)del->slaveInfo.number,len); + if(len>(MAX_MSISDN_BLEN-1)*2) + len = (MAX_MSISDN_BLEN - 1 )*2; + + pMID->variableMessage.variableParts.variablePart[0].number[0] = (len+1)/2+1; + if(len%2==0) + { + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x04; + memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2], + u_msisdn, + (len+1)/2); + } + else + { + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x24; + memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2], + u_msisdn, + (len+1)/2); + pMID->variableMessage.variableParts.variablePart[0].number[2+(len+1)/2] &=0x0F; + } + + pPCUI->informationToSend.inbandInfo.optional_flag = 0x07; + pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPCUI->informationToSend.inbandInfo.duration = 0x00; + pPCUI->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +static int checkDelSlaveNumber(_state_data *shmp) +{ + u_char *slaveNumber,slaveStoredNumber[2*MAX_MSISDN_BLEN]; + _account_info *slave_info; + _prepaid_info *prepaidInfo; + u8 len,i,totalChild,*pChild; + + PutLogFunID("checkDelSlaveNumber"); + + slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del.slaveInfo; + slaveNumber = slave_info->number; + + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return 1; + + if(GetAccountPos(slave_info) == FALSE) + { + return 2; + } + + totalChild = prepaidInfo->poolAccount.roleParty.parent.childNumber%(POOL_MAX_CHILD+1); + for(i=0;ipoolAccount.roleParty.parent.childMsisdn[i]; + len = pChild[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)slaveStoredNumber,pChild,18); + StringCut((char *)slaveStoredNumber,'F'); + slaveStoredNumber[len] = 0; + if(!strcmp((char *)slaveNumber, (char *)slaveStoredNumber)) + return 0; + } + return 1; +} + +static int masterDelWaitForChoice(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + MASTER_SLAVE_DEL *del; + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > '2')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del; + del->choice = input_msg[0] - '0'; + + return result; +} + +static int getMasterDelChoice(_state_data *shmp) +{ + MASTER_SLAVE_DEL *del; + + del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del; + return del->choice; +} + +static void delProcessSetMaster(_state_data *shmp) +{ + _account_info *slave_info; + _prepaid_info *prepaidInfo; + UserData_Pool_Account *poolAccount; + u8 len,i,totalChild,*pChild; + u_char *slaveNumber,slaveStoredNumber[2*MAX_MSISDN_BLEN]; + + slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del.slaveInfo; + slaveNumber = slave_info->number; + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return; + poolAccount = &prepaidInfo->poolAccount; + totalChild = poolAccount->roleParty.parent.childNumber%(POOL_MAX_CHILD+1); + if(totalChild == 0) + { + poolAccount->role = MASTER_SLAVE_NONE; + return; + } + for(i=0;iroleParty.parent.childMsisdn[i]; + len = pChild[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)slaveStoredNumber,pChild,18); + StringCut((char *)slaveStoredNumber,'F'); + slaveStoredNumber[len] = 0; + if(!strcmp((char *)slaveNumber, (char *)slaveStoredNumber)) + break; + } + if(i >= totalChild) + return; + if(i >= totalChild-1) + memset(&poolAccount->roleParty.parent.childMsisdn[i],0,MAX_MSISDN_BLEN); + else + { + memmove(&poolAccount->roleParty.parent.childMsisdn[i], + &poolAccount->roleParty.parent.childMsisdn[i+1], + (totalChild-i-1)*MAX_MSISDN_BLEN); + memset(&poolAccount->roleParty.parent.childMsisdn[totalChild-1],0,MAX_MSISDN_BLEN); + } + + totalChild = decMasterChildren(prepaidInfo); + if(totalChild <= 0) + poolAccount->role = MASTER_SLAVE_NONE; + smppNotifyMasterDEL(shmp->caller_info.number,slave_info->number); + SendAccountRealSync_2(&shmp->caller_info,0.0,0.0,OMC_OCODE_EDIT); +} + +static void delProcessSetSlave(_state_data *shmp) +{ + _account_info *slave_info; + _prepaid_info *prepaidInfo; + UserData_Pool_Account *poolAccount; + + slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del.slaveInfo; + if((prepaidInfo = getPrepaidInfo(slave_info)) == NULL) + return ; + + poolAccount = &prepaidInfo->poolAccount; + memset(poolAccount,0,sizeof(UserData_Pool_Account)); + poolAccount->role = MASTER_SLAVE_NONE; + smppNotifySlaveDEL(shmp->caller_info.number,slave_info->number); + SendAccountRealSync_2(slave_info,0.0,0.0,OMC_OCODE_EDIT); +} + + +enum{ + S_MASTER_DEL_IDLE, + S_MASTER_DEL_WAIT_SLAVE, + S_MASTER_DEL_WAIT_CONFIRM, + S_MASTER_DEL_PROCESSING, + S_MASTER_DEL_WAIT_PLAY_DONE, + S_MASTER_DEL_EXIT, +}; + +static int masterDelProc(u_short portid) +{ + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst; + MASTER_SLAVE_DEL *del; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + + switch(getMasterDelState(portid)) + { + case S_MASTER_DEL_IDLE: + clearMasterDelInfo(portid); + if(isMasterEmptySlave(portid) == TRUE) + { + playPromptVoice(portid,DEL_FAIL_EMPTY); + changeMasterDelState(portid,S_MASTER_DEL_WAIT_PLAY_DONE); + } + else + { + playPromptAndCollectVoice(portid,MASTER_INPUT_CHILD_DEL,MAX_IVR_INPUT_LEN); + changeMasterDelState(portid,S_MASTER_DEL_WAIT_SLAVE); + } + break; + case S_MASTER_DEL_WAIT_SLAVE: + rst = WaitingForMasterDelInputSlave(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = checkDelSlaveNumber(shmp); + switch(rst) + { + case 0: + SendMasterDelConfirmToSrf(portid); + changeMasterDelState(portid,S_MASTER_DEL_WAIT_CONFIRM); + break; + case 1:/* not your child */ + playPromptAndCollectVoice(portid,DEL_FAIL_NOT_YOUR_CHILD,MAX_IVR_INPUT_LEN); + break; + case 2:/* not exist in pps */ + playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,MASTER_INPUT_CHILD_DEL,MAX_IVR_INPUT_LEN); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_DEL_WAIT_CONFIRM: + rst = masterDelWaitForChoice(shmp); + switch(rst) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + rst = getMasterDelChoice(shmp); + switch(rst) + { + case CONFIRM_OK: + changeMasterDelState(portid,S_MASTER_DEL_PROCESSING); + break; + case CONFIRM_ENTER_AGAIN: + changeMasterDelState(portid,S_MASTER_DEL_IDLE); + break; + case CONFIRM_CANCEL: + changeMasterDelState(portid,S_MASTER_DEL_EXIT); + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,YES_OR_NO,1); + break; + case INPUT_ERROR_EXIT: + result = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_DEL_PROCESSING: + delProcessSetMaster(shmp); + delProcessSetSlave(shmp); + playPromptVoice(portid,MASTER_DEL_SUCCESS); + changeMasterDelState(portid,S_MASTER_DEL_WAIT_PLAY_DONE); + break; + case S_MASTER_DEL_WAIT_PLAY_DONE: + rst = CallingCardWaitingForSpecialResourceReport(shmp); + if(rst == SERVICE_KEEP_STATE) + break; + else if(rst == 1) + { + changeMasterDelState(portid,S_MASTER_DEL_EXIT); + } + else + result = SERVICE_EXIT_PPS; + break; + case S_MASTER_DEL_EXIT: + result = SERVICE_RETURN_TO_PARENT; + break; + default: + result = SERVICE_EXIT_PPS; + break; + } + return result; +} + +/****************************** delete ***********************************************/ +#define changeMasterSlaveState(portid,val) do { \ + masterSlaveCard = &shmp->process_info.ppsService.masterSlaveCard;\ + masterSlaveCard->state = val;\ + shmp->process_info.serviceInput = 0;\ + shmp->process_info.funnel = 0;\ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + + +static u8 getMasterSlaveState(u_short portid) +{ + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + return shmp->process_info.ppsService.masterSlaveCard.state; +} + +static int WaitForMasterChoice(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + + PutLogFunID("WaitForChoice"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > '3')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + + shmp->process_info.ppsService.masterSlaveCard.choice = input_msg[0] - '0'; + return result; +} + +static int WaitForSalveChoice(_state_data *shmp) +{ + u_char input_msg[64] = {0}; + int result; + + PutLogFunID("WaitForChoice"); + + memset(input_msg,0,64); + result = WaitingForInput(shmp,input_msg); + if(result != INPUT_SUCCESS) + return result; + + if(strlen((char *)input_msg) != 1 + || (input_msg[0] < '0' || input_msg[0] > '1')) + { + if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM) + { + return (result = INPUT_ERROR_EXIT); + } + else + return (result = INPUT_ERROR_REINPUT); + } + + shmp->process_info.ppsService.masterSlaveCard.choice = input_msg[0] - '0'; + return result; +} + +static int getMasterSalveFunc(_state_data *shmp) +{ + return shmp->process_info.ppsService.masterSlaveCard.choice; +} + + +enum MASTER_SLAVE_CARD_STATE{ + S_MASTER_SLAVE_IDLE, + S_MASTER_CHOICE, + S_SLAVE_CHOICE, + S_MASTER_INQUIRY, + S_SLAVE_INQUIRY, + S_MASTER_ADD_SLAVE, + S_MASTER_DEL_SLAVE, + S_MASTER_PLAY, +}; + +void clearMasterSlaveInfo(u_short portid) +{ + _state_data *shmp; + + PutLogFunID("clearTransferInfo"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + memset(&shmp->process_info.ppsService.masterSlaveCard,0,sizeof(MASTER_SLAVE_CARD)); +} + + +int getPoolAccountRole(u_short portid) +{ + _prepaid_info *prepaidInfo = NULL; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if (shmp->caller_info.head < MSISDN_HEAD_NUM && shmp->caller_info.tail < UNIT_STORE_ACCOUNT) + { + prepaidInfo = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail]; + } + if(prepaidInfo == NULL) + return MASTER_SLAVE_NONE; + return prepaidInfo->poolAccount.role; +} + +static int getCosPoolRole(u_short portid) +{ + //_prepaid_info *prepaidInfo = NULL; + _state_data *shmp; + u8 cosID=0; + COSTable *cosTableItem; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + cosID = GetLocalCosID(&shmp->caller_info); + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + return cosTableItem->poolAccount[0].role; +} + +int masterSlaveIVRProc(u_short portid) +{ + _state_data *shmp; + int result_sub = SERVICE_KEEP_STATE,result_main = SERVICE_KEEP_STATE; + MASTER_SLAVE_CARD *masterSlaveCard; + + PutLogFunID("masterSlaveIVRProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + return SERVICE_EXIT_PPS; + } + switch(getMasterSlaveState(portid)) + { + case S_MASTER_SLAVE_IDLE: + clearMasterSlaveInfo(portid); + switch(getCosPoolRole(portid)) + { + case MASTER_SLAVE_NONE: + playPromptVoice(portid,SERIVCE_NOT_APPLIED); + changeMasterSlaveState(portid,S_MASTER_PLAY); + break; + default: + if(getPoolAccountRole(portid) == MASTER_SLAVE_CHILD) + { + playPromptAndCollectVoice(portid,SLAVE_CARD_PROMPT,1); + changeMasterSlaveState(portid,S_SLAVE_CHOICE); + } + else + { + playPromptAndCollectVoice(portid,MASTER_CARD_PROMPT,1); + changeMasterSlaveState(portid,S_MASTER_CHOICE); + } + break; + } + break; + case S_MASTER_CHOICE: + result_sub = WaitForMasterChoice(shmp); + switch(result_sub) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + switch(getMasterSalveFunc(shmp)) + { + case 0: + result_main = SERVICE_RETURN_TO_PARENT; + break; + case 1: + changeMasterSlaveState(portid,S_MASTER_INQUIRY); + break; + case 2: + if(getCosPoolRole(portid) != MASTER_SLAVE_PARENT) + { + playPromptVoice(portid,SERIVCE_NOT_APPLIED); + changeMasterSlaveState(portid,S_MASTER_PLAY); + } + else + changeMasterSlaveState(portid,S_MASTER_ADD_SLAVE); + break; + case 3: + changeMasterSlaveState(portid,S_MASTER_DEL_SLAVE); + break; + default: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,MASTER_CARD_PROMPT,1); + break; + case INPUT_ERROR_EXIT: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case S_SLAVE_CHOICE: + result_sub = WaitForSalveChoice(shmp); + switch(result_sub) + { + case NO_INPUT: + break; + case INPUT_SUCCESS: + switch(getMasterSalveFunc((shmp))) + { + case 0: + result_main = SERVICE_RETURN_TO_PARENT; + break; + case 1: + changeMasterSlaveState(portid,S_SLAVE_INQUIRY); + break; + default: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case INPUT_ERROR_REINPUT: + playPromptAndCollectVoice(portid,SLAVE_CARD_PROMPT,1); + break; + case INPUT_ERROR_EXIT: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_INQUIRY: + result_sub = masterEnquiryProc(portid); + switch(result_sub) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE); + break; + case SERVICE_EXIT_PPS: + default: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case S_SLAVE_INQUIRY: + result_sub = slaveEnquiryProc(portid); + switch(result_sub) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE); + break; + case SERVICE_EXIT_PPS: + default: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_ADD_SLAVE: + result_sub = masterAddProc(portid); + switch(result_sub) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE); + break; + case SERVICE_EXIT_PPS: + default: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_DEL_SLAVE: + result_sub = masterDelProc(portid); + switch(result_sub) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE); + break; + case SERVICE_EXIT_PPS: + default: + result_main = SERVICE_EXIT_PPS; + break; + } + break; + case S_MASTER_PLAY: + result_sub = CallingCardWaitingForSpecialResourceReport(shmp); + if(result_sub == SERVICE_KEEP_STATE) + break; + else if(result_sub == 1) + { + result_main = SERVICE_RETURN_TO_PARENT; + } + else + result_main = SERVICE_EXIT_PPS; + break; + } + return result_main; +} + +static int fillTransferStateData(_state_data *shmp,_account_info *masterAccount,_account_info *childAccount,float fee) +{ + shmp->process_info.ppsService.feeTransfer.fee = fee; + memcpy(&shmp->caller_info,masterAccount,sizeof(_account_info)); + if(GetAccountPos(&shmp->caller_info) == FALSE) + return -1; + memcpy(&shmp->process_info.ppsService.feeTransfer.account,childAccount,sizeof(_account_info)); + if(GetAccountPos(&shmp->process_info.ppsService.feeTransfer.account) == FALSE) + return -1; + return 1; +} + +static int childAutoTransferInFromMaster(_prepaid_info *slave) +{ + int cos_id=0,rst; + COSTable *cosTableItem; + _prepaid_info *master; + _account_info masterAccount,childAccount; + u8 *msisdnBCD,len; + float transferFee,diff; + COS_Pool_Account *pA; + + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return 0; + memset(&masterAccount,0,sizeof(_account_info)); + msisdnBCD = slave->poolAccount.roleParty.child.parentMsisdn; + len = msisdnBCD[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)masterAccount.number,msisdnBCD,18); + StringCut((char *)masterAccount.number,'F'); + masterAccount.number[len] = 0; + + if(GetAccountPos(&masterAccount) == FALSE) + return -1; + + memset(&childAccount,0,sizeof(_account_info)); + msisdnBCD = slave->msisdn; + + len = msisdnBCD[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)childAccount.number,msisdnBCD,18); + StringCut((char *)childAccount.number,'F'); + childAccount.number[len] = 0; + + if((master = getPrepaidInfo(&masterAccount)) == NULL) + return -1; + + cos_id = slave->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = &cosTableItem->poolAccount[0]; + + transferFee = pA->roleParty.child.maxFeePerDay; + + if(isPromotionCanBeTransfered(&masterAccount) == TRUE) + diff = transferFee - (slave->balance+slave->promo_balance); + else + diff = transferFee - slave->balance; + + rst = checkTransferedPartialFee(&masterAccount,diff); + switch(rst) + { + case CHECK_TRANSFERED_FEE_OK: + + break; + case CHECK_TRANSFERED_FEE_INSUFFIENT: + pps_print_error(0,"%s insufficient fee",masterAccount.number); + return -1; + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + pps_print_error(0,"%s expired",masterAccount.number); + return -1; + break; + } + if(GetAccountPos(&childAccount) == FALSE) + return -1; + poolTransferAccount(&masterAccount,&childAccount,diff); + SendTransferCDR(&masterAccount,&childAccount,-diff); + SendTransferCDR(&childAccount,&masterAccount,diff); + + return 2; +} + +static int checkMasterFee(u_short portid) +{ + //_prepaid_info *prepaidInfo; + _state_data *shmp; + MASTER_SLAVE_ADD *add; + u8 cosID; + COSTable *cosTableItem; + COS_Pool_Account *pA; + float transferFee,slaveAddFee; + int rst; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + cosID = getAddingSlaveCosId(shmp,add); + cosTableItem = &ppsParam.ppsTables.cosTable[cosID]; + + pA = &cosTableItem->poolAccount[0]; + transferFee = pA->roleParty.child.maxFeePerDay; + + slaveAddFee = getAddSlaveCharge(&shmp->caller_info); + rst = checkTransferedPartialFee(&shmp->caller_info,transferFee+slaveAddFee); + return rst; +} + +static int getAddingSlaveCosId(_state_data *shmp,MASTER_SLAVE_ADD *add) +{ + int cos_id; + COSTable *cosTableItem; + + cos_id = GetLocalCosID(&shmp->caller_info); + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + cos_id = cosTableItem->poolAccount[0].roleParty.parent.cosIDForChild[add->cosID%MaxCosTableItem]; + return cos_id; +} + +static int RealTransferToSlave(_state_data *shmp) +{ + int cos_id=0,rst; + COSTable *cosTableItem; + double transferFee; + COS_Pool_Account *pA; + _prepaid_info *master,*slave; + MASTER_SLAVE_ADD *add; + _state_data newShmp; + + add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add; + if((master = getPrepaidInfo(&shmp->caller_info)) == NULL) + return -1; + if((slave = getPrepaidInfo(&add->slaveInfo)) == NULL) + return -1; + cos_id = getAddingSlaveCosId(shmp,add); + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + pA = &cosTableItem->poolAccount[0]; + transferFee = pA->roleParty.child.maxFeePerDay; + + rst = fillTransferStateData(&newShmp,&shmp->caller_info,&add->slaveInfo,transferFee); + if(rst < 0) + return -1; + + FeeTransferTransaction(&newShmp); + return 2; +} + +static int smppNotifyParentTransfer(_prepaid_info *slave) +{ + u8 *msisdnBCD,len; + u8 masterNumber[2*MAX_MSISDN_BLEN],slaveNumber[2*MAX_MSISDN_BLEN]; + u_char msg[MAX_SMS_LEN*4]={0}; + + + memset(masterNumber,0,2*MAX_MSISDN_BLEN); + msisdnBCD = slave->poolAccount.roleParty.child.parentMsisdn; + len = msisdnBCD[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)masterNumber,msisdnBCD,18); + StringCut((char *)masterNumber,'F'); + masterNumber[len] = 0; + + memset(slaveNumber,0,2*MAX_MSISDN_BLEN); + msisdnBCD = slave->msisdn; + len = msisdnBCD[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)slaveNumber,msisdnBCD,18); + StringCut((char *)slaveNumber,'F'); + slaveNumber[len] = 0; + + strcpy((char *)msg, (char *)slaveNumber); + strcat((char *)msg," "); + strcat((char *)msg, (char *)getSmsSentenceNative(0,SMS_POOL_CHILD_LOW_FEE)); + return smppSendMOSM((char *)masterNumber, (char *)ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number + ,msg,strlen((char *)msg),0); +} + +static int getSlaveRechargeType(int cos_id) +{ + COSTable *cosTableItem; + COS_Pool_Account *pA; + + cos_id = cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = & cosTableItem->poolAccount[0]; + + return pA->roleParty.child.periodicTransferOrAutoByParent; +} + + +static BOOL isSlaveNeedTransferFee(_prepaid_info *slave) +{ + int cos_id=0; + COSTable *cosTableItem; + COS_Pool_Account *pA; + double transferFee; + + cos_id = slave->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = &cosTableItem->poolAccount[0]; + + transferFee = pA->roleParty.child.maxFeePerDay; + + if(slave->balance + slave->promo_balance >= transferFee) + return FALSE; + return TRUE; +} + +void resetPoolSlaveDaily(u_short head,u_short tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *slave; + + slave = &shmp->prepaid_info[head][tail]; + + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return; + + slave->poolAccount.roleParty.child.callsToday = 0; + slave->poolAccount.roleParty.child.smsToday = 0; + slave->poolAccount.roleParty.child.chargedToday = 0; + if(isSlaveNeedTransferFee(slave) == FALSE) + return; + switch(getSlaveRechargeType(slave->cos_id)) + { + case 0: + childAutoTransferInFromMaster(slave); + break; + case 1: + default: + smppNotifyParentTransfer(slave); + break; + } +} + +int isPoolChildReachCallLimit(_state_data *shmp) +{ + int cos_id=0; + COSTable *cosTableItem; + COS_Pool_Account *pA; + _prepaid_info *slave=NULL; + + if(shmp->caller_info.fee == 0) + return 0; + if (shmp->caller_info.head < MSISDN_HEAD_NUM + && shmp->caller_info.tail < UNIT_STORE_ACCOUNT) + { + slave = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail]; + } + if(slave == NULL) + return 0; + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return 0; + cos_id = slave->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + pA = & cosTableItem->poolAccount[0]; + if(slave->poolAccount.roleParty.child.callsToday >= pA->roleParty.child.maxCallsPerDay) + return 1; + if(getConsumeFee(slave) >= pA->roleParty.child.maxFeePerDay) + return 2; + return 0; +} + +int isPoolChildReachSMSLimit(_state_data *shmp) +{ + int cos_id=0; + COSTable *cosTableItem; + COS_Pool_Account *pA; + _prepaid_info *slave=NULL; + + if(shmp->caller_info.fee == 0) + return 0; + if (shmp->caller_info.head < MSISDN_HEAD_NUM + && shmp->caller_info.tail < UNIT_STORE_ACCOUNT) + { + slave = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail]; + } + if(slave == NULL) + return 0; + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return 0; + cos_id = slave->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + pA = & cosTableItem->poolAccount[0]; + if(slave->poolAccount.roleParty.child.smsToday >= pA->roleParty.child.maxSMSPerDay) + return 1; + if(getConsumeFee(slave) >= pA->roleParty.child.maxFeePerDay) + return 2; + return 0; +} + +int isPoolChildReachFeeLimit(_account_info *ptr) +{ + int cos_id=0; + COSTable *cosTableItem; + COS_Pool_Account *pA; + _prepaid_info *slave=NULL; + + if(ptr->fee == 0) + return 0; + if (ptr->head < MSISDN_HEAD_NUM + && ptr->tail < UNIT_STORE_ACCOUNT) + { + slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail]; + } + if(slave == NULL) + return 0; + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return 0; + cos_id = slave->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + pA = & cosTableItem->poolAccount[0]; + + if(getConsumeFee(slave) >= pA->roleParty.child.maxFeePerDay) + return 2; + return 0; +} + + + +void increPoolChildCalls(_account_info *ptr) +{ + _prepaid_info *slave=NULL; + DWORD instance; + + if (ptr->head < MSISDN_HEAD_NUM + && ptr->tail < UNIT_STORE_ACCOUNT) + { + slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail]; + } + if(slave == NULL) + return; + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return; + slave->poolAccount.roleParty.child.callsToday++; + instance = ptr->head * UNIT_STORE_ACCOUNT + ptr->tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); +} + +void increPoolChildSMS(_account_info *ptr) +{ + _prepaid_info *slave=NULL; + DWORD instance; + + if (ptr->head < MSISDN_HEAD_NUM + && ptr->tail < UNIT_STORE_ACCOUNT) + { + slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail]; + } + if(slave == NULL) + return; + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return; + slave->poolAccount.roleParty.child.smsToday++; + instance = ptr->head * UNIT_STORE_ACCOUNT + ptr->tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); +} + +void increPoolChildCharged(_account_info *ptr,double charged) +{ + _prepaid_info *slave=NULL; + + if (ptr->head < MSISDN_HEAD_NUM + && ptr->tail < UNIT_STORE_ACCOUNT) + { + slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail]; + } + if(slave == NULL) + return; + if(slave->poolAccount.role != MASTER_SLAVE_CHILD) + return; + slave->poolAccount.roleParty.child.chargedToday += charged; +} + +static int isChildRechargeAllowed(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + COS_Pool_Account *pA; + int cos_id; + + cos_id = prepaidInfo->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = &cosTableItem->poolAccount[0]; + if(pA->roleParty.child.isRechargeAllowed) + return TRUE; + + return FALSE; +} + +int isChildTransferAllowed(_prepaid_info *prepaidInfo) +{ + COSTable *cosTableItem; + COS_Pool_Account *pA; + int cos_id; + + cos_id = prepaidInfo->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pA = &cosTableItem->poolAccount[0]; + if(pA->roleParty.child.isTransferAllowed) + return TRUE; + return FALSE; +} + +int isTransferAllowed(u_short portid) +{ + _prepaid_info *prepaidInfo; + _state_data *shmp; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return FALSE; + + if(prepaidInfo->poolAccount.role == MASTER_SLAVE_CHILD) + return isChildTransferAllowed(prepaidInfo); + + GetAccountPos(&shmp->caller_info); + if(GetAccountStatus(&shmp->caller_info) != T_NORMAL) + return FALSE; + + return TRUE; +} + +int isRechargeAllowed(u_short portid) +{ + _prepaid_info *prepaidInfo; + _state_data *shmp; + int rst; + + return TRUE; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL) + return FALSE; + if(prepaidInfo->poolAccount.role == MASTER_SLAVE_CHILD) + { + rst = isChildRechargeAllowed(prepaidInfo); + if(rst == FALSE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]slave card ,recharge not allowed",portid); + } + return rst; + } + + return TRUE; +} + + +static int smppNotifyMasterADD(u_char *masterNumber,u_char *slaveNumber) +{ + char msg[MAX_SMS_LEN*4]={0}; + char dayTimeReadable[32]={0}; + + ppsgetdaytime_readFormat(dayTimeReadable); + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_ADDED_CHILD)); + + cliManipulationFunction((char *)slaveNumber, (char *)masterNumber ); + strcat(msg, (char *)slaveNumber); + strcat(msg," "); + strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON)); + strcat(msg," "); + strcat(msg, dayTimeReadable); + return smppSendMOSM((char *)masterNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0); +} + +static int smppNotifyMasterDEL(u_char *masterNumber,u_char *slaveNumber) +{ + char msg[MAX_SMS_LEN*4]={0}; + char dayTimeReadable[32]={0}; + + ppsgetdaytime_readFormat(dayTimeReadable); + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_DELED_CHILD)); + + cliManipulationFunction((char *)slaveNumber, (char *)masterNumber ); + + strcat(msg, (char *)slaveNumber); + strcat(msg," "); + strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON)); + strcat(msg," "); + strcat(msg, dayTimeReadable); + return smppSendMOSM((char *)masterNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0); +} + +static int smppNotifySlaveADD(u_char *masterNumber,u_char *slaveNumber) +{ + char msg[MAX_SMS_LEN*4]={0}; + char dayTimeReadable[32]={0}; + + ppsgetdaytime_readFormat(dayTimeReadable); + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_BEEN_ADDED_CHILD)); + + cliManipulationFunction((char *)masterNumber, (char *)slaveNumber ); + + strcat(msg, (char *)masterNumber); + strcat(msg," "); + strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON)); + strcat(msg," "); + strcat(msg, dayTimeReadable); + return smppSendMOSM((char *)slaveNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0); +} + +static int smppNotifySlaveDEL(u_char *masterNumber,u_char *slaveNumber) +{ + char msg[MAX_SMS_LEN*4]={0}; + char dayTimeReadable[32]={0}; + + ppsgetdaytime_readFormat(dayTimeReadable); + strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_BEEN_DELED_CHILD)); + + cliManipulationFunction((char *)masterNumber, (char *)slaveNumber ); + + strcat(msg, (char *)masterNumber); + strcat(msg," "); + strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON)); + strcat(msg," "); + strcat(msg, dayTimeReadable); + return smppSendMOSM((char *)slaveNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0); +} + + +void ppsgetdaytime_readFormat(char *daytime_buf) +{ + struct tm *t,tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(daytime_buf,"%04d-%02d-%02d %02d:%02d:%02d", + t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, + t->tm_min, t->tm_sec); + daytime_buf[19] = 0; +} + + +static int getAddSlaveCharge(_account_info *accountInfo) +{ + int head,tail; + int tariff_id=0; + + head = accountInfo->head; + tail = accountInfo->tail; + + if(head>=MSISDN_HEAD_NUM) + return 0; + tariff_id = GetAccountZoneID(head,tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + return ramshm_ptr->tariff_data.comm_tariff[tariff_id].childChangeChargeAmount; +} + +int increMasterChangeCounter(_prepaid_info *prepaidInfo) +{ + u_char *times; + + if(prepaidInfo == NULL) + return 0; + + PutLogFunID("increMasterChangeCounter"); + + + times = &prepaidInfo->poolAccount.roleParty.parent.changeTimes; + if(*times<0x7F) + return (++(*times)); + return *times; +} + + +int IncreasePoolAccountChangeCounter(int head, int tail) +{ + PutLogFunID("IncreasePoolAccountChangeCounter"); + + if(headprepaid_data.prepaid_info[head][tail]); + } + return 0; +} + +extern void SendManualOperationCDR(_account_info *caller_info, _account_info *called_info, int charge); +int masterChangeSlaveCharge(_state_data *shmp,_account_info *slaveInfo) +{ + int head,tail; + int amount,times; + _prepaid_info *ptr; + COSTable *cosTableItem; + int cos_id; + + PutLogFunID("masterChangeSlaveCharge"); + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + if(head>=MSISDN_HEAD_NUM) + return 0; + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + cos_id = ptr->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(!cosTableItem->serviceControl[0].poolAccountChangeChargeFlag) + return 0; + IncreasePoolAccountChangeCounter(head,tail); + times = cosTableItem->serviceControl[0].poolAccountFreeChangeTimes; + if(ptr->poolAccount.roleParty.parent.changeTimes <= times) + return 0; + + amount = getAddSlaveCharge(&shmp->caller_info); + + ptr->balance -= amount; + + SendManualOperationCDR(&shmp->caller_info,&shmp->called_info,-amount); + return amount; +} + +int BillingChildNumberChange(_state_data *shmp) +{ + int head,tail; + int amount,tariff_id=0; + _prepaid_info *ptr; + + PutLogFunID("BillingChildNumberChange"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if(head>=MSISDN_HEAD_NUM) + return 0; + tariff_id = GetAccountZoneID(head,tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + amount = ramshm_ptr->tariff_data.comm_tariff[tariff_id].childChangeChargeAmount; + ptr->balance = ptr->balance - amount; + shmp->caller_info.charge = amount; + return 1; +} + +int CheckWetherPoolNumber(_account_info *caller, _account_info *called) +{ + int i,len; + char msisdn[32]; + UserData_Pool_Account *poolAccount; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("CheckWetherPoolNumber"); + poolAccount = &shmp->prepaid_info[caller->head][caller->tail].poolAccount; + if(caller->head < MSISDN_HEAD_NUM && caller->tail role == MASTER_SLAVE_CHILD) + { + len = poolAccount->roleParty.child.parentMsisdn[MAX_MSISDN_BLEN-1]; + if(len>MAX_MSISDN_ALEN || len<2) + return FALSE; + BcdToAscii(msisdn,poolAccount->roleParty.child.parentMsisdn,MAX_MSISDN_ALEN); + msisdn[len] = 0; + CutUnknownPrefix(msisdn); + if(strcmp(msisdn, (char *)called->number)==0) + return TRUE; + } + else if(poolAccount->role == MASTER_SLAVE_PARENT) + { + if(!poolAccount->roleParty.parent.childNumber) + return NOT_FAVORITE_NUMBER; + for(i=0;iroleParty.parent.childMsisdn[i][MAX_MSISDN_BLEN-1]; + if(len>MAX_MSISDN_ALEN || len<2) + continue; + BcdToAscii(msisdn,poolAccount->roleParty.parent.childMsisdn[i],MAX_MSISDN_ALEN); + msisdn[len] = 0; + CutUnknownPrefix(msisdn); + if(strcmp(msisdn, (char *)called->number)==0) + return TRUE; + } + } + else + return FALSE; + } + return FALSE; +} + + +void ChangeTariffToPoolCallTariff(_state_data *shmp,_bill_tariff *ptar) +{ + u_short rUnit=60; + float rAmount=0; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToPoolCallTariff"); + + tariff_id = shmp->caller_info.location; + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + rUnit = ramshm_ptr->tariff_data.comm_tariff[tariff_id].poolAccountChargeUnit; + rAmount = ramshm_ptr->tariff_data.comm_tariff[tariff_id].poolAccountChargeAmount; + + if(rUnit ==0) rUnit = 60; + + tier = getCurrentTier(shmp,ptar); + ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit; +} + + + + + diff --git a/mss/pps/src/main/message.c b/mss/pps/src/main/message.c new file mode 100644 index 0000000..7753853 --- /dev/null +++ b/mss/pps/src/main/message.c @@ -0,0 +1,4686 @@ +/* +** +** Message send control entity. +** +*/ +#include +#include +#include "../include/includes.h" +#include "../include/message.h" +#include "../include/ppsm.h" +#include "../include/cdrme.h" +#include "../include/ramdata.h" +#include "../include/mfunc.h" +#include "../include/config.h" +#include "../include/param.h" +#include "../include/precard.h" +#include "../include/mfunc.h" + +#include "../include/plat_inc.h" + +#include "../../../../plat/scf/src/include/scfmsg.h" +/*------------------------------------------------*/ + +extern _state_machine *smshm_ptr; +extern _ram_data *ramshm_ptr; +extern char prog_name[12]; +extern char alarm_code[2]; +extern u_char version_id[3]; +extern int subSystemID; +extern _pps_cdr_buffer pps_cdr_buffer; + +extern PPSParamStruct ppsParam; + +extern int cdr_head_ptr , cdr_tail_ptr ; +extern u_long primary_data_server, + second_data_server; +extern struct timeval tvnow; + +extern DWORD PPS_OID_PREFIX[]; +extern int logMsgFlag; +extern int systemCapability; +extern u_char sumOfParameter; +extern u_long peer_server_ip; +extern u_long LOCAL_IP; + +extern u_short debug_messages; +extern char serialNumber[8]; +extern char masterFlag; +/*------------------------------------------------*/ + +int GetSrfAddress(char *msisdn); + +/*------------------------------------------------*/ +extern int smppSendAccountInfo(char *caller, char *called, + long balance, char *expire_date, + long promotion,char *promotionExpireDate, + int calltype0, + char *call_date, + char *msisdn, + u_char flag); +extern int StuffCapMessage(); +extern int ppsDebugCapMsg(); +extern int GetMaxCallDuration(); +extern int GetAccountLastCallInfo(_account_info *ptr, _last_call_info *pInfo); +extern int UpdateAccountLastCDR(); +extern int FindPPSTableIndex(); +extern int UpdateAccountExpiration(); +extern int ListAllPortStatus(); +extern int sccp_GetSSNType ( BYTE ssn ); +extern int CheckPromotionLatchFlag(); +extern int cdr_submit(unsigned char ssn, unsigned short length, char *data); +extern const char * AsciiTimeYMDHMS(char *ptr, time_t time); +extern int ReplaceStr(char *sSrc, char *sMatchStr, char *sReplaceStr); +/*------------------------------------------------*/ +void PutWarningMessage(u_short portid) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + char causebuf[128]; + int cause; + + PutLogFunID("PutWarningMessage"); + shmp += portid; + cause = shmp->process_info.tcos; + switch(cause){ + case CALLER_CREDIT_OUT: + sprintf(causebuf,"Warning: Caller is out of balance"); + break; + case ACTIVITY_MISSED: + sprintf(causebuf,"Warning: Activity message missed"); + break; + case CALLED_CREDIT_OUT: + sprintf(causebuf,"Warning: Called is out of balance"); + break; + case CALLER_STATUS_ERROR: + sprintf(causebuf,"Warning: Caller status is error"); + break; + case CALLED_STATUS_ERROR: + sprintf(causebuf,"Warning: Called status is error"); + break; + case CALLER_EXPIRIED: + sprintf(causebuf,"Warning: Caller is expiry"); + break; + case CALLED_EXPIRIED: + sprintf(causebuf,"Warning: Called is expiry"); + break; + case TARIFF_NOT_SET: + sprintf(causebuf,"Warning: Tariff not set for destination %s", + shmp->charge_info.number); + break; + case capp_oDisconnect: + sprintf(causebuf,"Caller disconnect"); + break; + case capp_tDisconnect: + sprintf(causebuf,"Called disconnect"); + break; + case USER_BUSY: + sprintf(causebuf,"Called busy"); + break; + case NO_ANSWER: + sprintf(causebuf,"No answer"); + break; + case CALL_REJECTED: + sprintf(causebuf,"Call rejected"); + break; + case NO_ROUTE: + sprintf(causebuf,"No route "); + break; + case UNALLOCATED_NUMBER: + sprintf(causebuf,"Caller is unallocated"); + break; + case DESTINATION_OUT_OF_ORDER: + sprintf(causebuf,"Called is unallocated"); + break; + case INVALID_MESSAGE: + sprintf(causebuf,"Invalid message Received"); + break; + case NETWORK_OUT_OF_ORDER: + sprintf(causebuf,"Unexpected message receive"); + break; + case TIMER_OUT: + sprintf(causebuf,"Waiting message time out"); + break; + case SERVICE_NOT_AVAILABLE: + sprintf(causebuf,"Called party is not OK!"); + break; + default: + sprintf(causebuf,"Normal release: %d",cause); + break; + } + if(shmp->process_info.pre_warning) + { + if(shmp->process_info.voiceID == PRE_WARNING_LOW_BALANCE) + { + sprintf(causebuf," Pre-warning for low balance "); + } + else + { + sprintf(causebuf," Pre-warning for near expiry "); + } + } + DebugMsg(debugmib.display.asciiOut,"\33[31m< %s > \33[0m",causebuf); +} + +void ConvertTcosToCause(u_short portid) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + int cause; + + PutLogFunID("ConvertTcosToCause"); + shmp += portid; + cause = shmp->process_info.tcos; + + switch(cause) + { + case ACTIVITY_MISSED: + case NETWORK_OUT_OF_ORDER: + case TIMER_OUT: + shmp->process_info.tcos = NETWORK_OUT_OF_ORDER; + break; + case CALLED_CREDIT_OUT: + case CALLED_STATUS_ERROR: + case CALLED_EXPIRIED: + shmp->process_info.tcos = CALL_REJECTED; //INCOMING_CALLS_BARRED; + break; + case CALLER_EXPIRIED: + if(shmp->process_info.duration>1) + shmp->process_info.tcos = NORMAL_CLEARING; + else + shmp->process_info.tcos = CALL_REJECTED; + break; + case CALLER_STATUS_ERROR: + case CALLER_CREDIT_OUT: //ODB + case CALL_REJECTED: //UDB + shmp->process_info.tcos = CALL_REJECTED; + break; + case TARIFF_NOT_SET: + case SERVICE_NOT_AVAILABLE: + shmp->process_info.tcos = SERVICE_NOT_AVAILABLE; + break; + case capp_oDisconnect: + case capp_tDisconnect: + shmp->process_info.tcos = NORMAL_CLEARING; + break; + case USER_BUSY: + shmp->process_info.tcos = USER_BUSY; + break; + case NO_ANSWER: + shmp->process_info.tcos = NO_ANSWER; + break; + case NO_ROUTE: + shmp->process_info.tcos = NO_ROUTE; + break; + case UNALLOCATED_NUMBER: + case DESTINATION_OUT_OF_ORDER: + shmp->process_info.tcos = UNALLOCATED_NUMBER; + break; + case INVALID_MESSAGE: + shmp->process_info.tcos = INVALID_MESSAGE; + break; + default: + shmp->process_info.tcos = NORMAL_CLEARING; + break; + } +} + +void +SendReleaseCall(u_short portid) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + u_short dlgid,invokeid=0;//,errflag=1; + + CAP_Message cap_message; + CapArg capArg; + + PutLogFunID("SendReleaseCall"); + + shmp += portid; + AddPPSStatistics(MIBPPS_RELEASECALL,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + +// shmp->process_info.tcos = NORMAL_CLEARING; +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + PutWarningMessage(portid); + } +#endif + + capArg.ocode = CAP_OC_ReleaseCall; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + capArg.msg_list.releaseCallArg.cause[0] = 0x02; //length + + ConvertTcosToCause(portid); + + capArg.msg_list.releaseCallArg.cause[1] = shmp->process_info.tcos>>8; + capArg.msg_list.releaseCallArg.cause[2] = shmp->process_info.tcos; + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +void SendPreWarningRequestBCSMEvent(u_short portid) +{ + int invokeid=0,dlgid; + CAP_Message capmsg; + CapArg capArg; + struct CapRequestReportBCSMEvent *pStr; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendPreWarningRequestBCSMEvent"); + + shmp += portid; + shmp->process_info.answerWanted = 0x01; + + AddPPSStatistics(MIBPPS_REQUESTBCSM,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_RequestReportBCSMEvent; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + pStr = &capArg.msg_list.requestReportBCSMEventArg; + + pStr->bcsmEvents_num = 2; + pStr->bcsmEvents[0].eventTypeBCSM = capp_oDisconnect; + pStr->bcsmEvents[0].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[0].optional_flag = 0x01; + pStr->bcsmEvents[0].legID_ch = 0x00; + pStr->bcsmEvents[0].legID.sendingSideID = 0x01; + + pStr->bcsmEvents[1].eventTypeBCSM = capp_oAbandon; + pStr->bcsmEvents[1].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[1].optional_flag = 0x01; + pStr->bcsmEvents[1].legID_ch = 0x00; + pStr->bcsmEvents[1].legID.sendingSideID = 0x01; + + switch(shmp->context_info.callType){ + case CT_MO_CALL: + case CT_MF_CALL: + break; + case CT_MT_CALL: + pStr->bcsmEvents[0].eventTypeBCSM = capp_tDisconnect;; + pStr->bcsmEvents[1].eventTypeBCSM = capp_tAbandon; + break; + default: + break; + } + + StuffCapMessage(capArg, &capmsg); + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif + +} + +void SendRequestBCSMEvent_MO_Call(u_short portid) +{ + int invokeid=0,dlgid, event_counter=0; + CAP_Message capmsg; + CapArg capArg; + struct CapRequestReportBCSMEvent *pStr; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendRequestBCSMEvent_MO_Call"); + + shmp += portid; + shmp->process_info.answerWanted = 0x01; + + AddPPSStatistics(MIBPPS_REQUESTBCSM,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_RequestReportBCSMEvent; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + pStr = &capArg.msg_list.requestReportBCSMEventArg; + /*if shmp->context_info.callType == CT_MO_CALL, + or all oEvents should be tEvents + */ + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oDisconnect; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x01; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oDisconnect; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x02; + event_counter ++; + + if(shmp->context_info.acn_ver>0) + { + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_routeSelectFailure; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oCalledPartyBusy; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oAbandon; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x01; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oNoAnswer; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x02; + pStr->bcsmEvents[event_counter].dPSpecificCriteria.applicationTimer = 40; + event_counter ++; + } + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oAnswer; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter ++; + + pStr->bcsmEvents_num = event_counter; + + StuffCapMessage(capArg, &capmsg); + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif +} + +void +SendRequestBCSMEvent_MF_Call(u_short portid) +{ + int invokeid=0,dlgid, event_counter=0; + CAP_Message capmsg; + CapArg capArg; + struct CapRequestReportBCSMEvent *pStr; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendRequestBCSMEvent_MF_Call"); + + shmp += portid; + shmp->process_info.answerWanted = 0x01; + + AddPPSStatistics(MIBPPS_REQUESTBCSM,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); + + capArg.ocode = CAP_OC_RequestReportBCSMEvent; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + pStr = &capArg.msg_list.requestReportBCSMEventArg; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oDisconnect; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x01; + event_counter ++; + + if(1) + { + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oDisconnect; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x02; + event_counter ++; + } + + if(1) + { + if(shmp->context_info.acn_ver>0) + { + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_routeSelectFailure; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oCalledPartyBusy; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oAbandon; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x01; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oNoAnswer; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x02; + pStr->bcsmEvents[event_counter].dPSpecificCriteria.applicationTimer = 30; + event_counter ++; + } + } + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_oAnswer; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter ++; + + pStr->bcsmEvents_num = event_counter; + + StuffCapMessage(capArg, &capmsg); + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif +} + +void +SendRequestBCSMEvent_MT_Call(u_short portid) +{ + int invokeid=0,dlgid, event_counter=0; + CAP_Message capmsg; + CapArg capArg; + struct CapRequestReportBCSMEvent *pStr; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendRequestBCSMEvent_MT_Call"); + + shmp += portid; + shmp->process_info.answerWanted = 0x01; + + AddPPSStatistics(MIBPPS_REQUESTBCSM,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); + + capArg.ocode = CAP_OC_RequestReportBCSMEvent; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + pStr = &capArg.msg_list.requestReportBCSMEventArg; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_tDisconnect; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x01; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_tDisconnect; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x02; + event_counter ++; + + if(shmp->context_info.acn_ver>0) + { + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_tBusy; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_tAbandon; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x01; + pStr->bcsmEvents[event_counter].legID_ch = 0x00; + pStr->bcsmEvents[event_counter].legID.sendingSideID = 0x01; + event_counter ++; + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_tNoAnswer; + pStr->bcsmEvents[event_counter].monitorMode = capp_interrupted; + pStr->bcsmEvents[event_counter].optional_flag = 0x02; + pStr->bcsmEvents[event_counter].dPSpecificCriteria.applicationTimer = 40; + event_counter ++; + /* Tnoanswer; */ + } + + pStr->bcsmEvents[event_counter].eventTypeBCSM = capp_tAnswer; + pStr->bcsmEvents[event_counter].monitorMode = capp_notifyAndContinue; + pStr->bcsmEvents[event_counter].optional_flag = 0x00; + event_counter ++; + + pStr->bcsmEvents_num = event_counter; + + StuffCapMessage(capArg, &capmsg); + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif +} + +void +SendRequestBCSMEvent(u_short portid) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + +// PutLogFunID("SendRequestBCSMEvent"); + + shmp += portid; + + switch(shmp->context_info.callType){ + case CT_MO_CALL: + case CT_MO_CC_CALL: + SendRequestBCSMEvent_MO_Call(portid); + break; + case CT_MF_CALL: + SendRequestBCSMEvent_MF_Call(portid); + break; + case CT_MT_CALL: + SendRequestBCSMEvent_MT_Call(portid); + break; + default: + break; + } +} + + +void +SendApplyCharging(u_short portid) +{ + int dlgid, invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapApplyCharging *pApplyCharging; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendApplyCharging"); + + shmp += portid; + AddPPSStatistics(MIBPPS_APPLYCHARGING,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_ApplyCharging; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + pApplyCharging = &capArg.msg_list.applyChargingArg; + pApplyCharging->partyToCharge = 0x01; //sendingSideID + + if(shmp->process_info.ro_if.adaptor_enabled == 0 ) + { + int left_voice_bundle = 0; + if (shmp->process_info.bundle_flag) + { + switch(shmp->context_info.callType) + { + case CT_MT_CALL: + left_voice_bundle = pps_get_account_bundle_mt_voice(shmp);// MT left voice bundle + break; + case CT_MO_CALL: + case CT_MF_CALL: + left_voice_bundle = pps_get_account_bundle_mo_voice(shmp);// MO left voice bundle + default: + break; + } + } + + GetMaxCallDuration(shmp); + + shmp->process_info.maxCallDuration += left_voice_bundle; + } + else + shmp->process_info.maxCallDuration = shmp->process_info.ro_if.granted_value; + + pApplyCharging->ACBCC.optional_flag = 0x00; + + if(shmp->process_info.maxCallDuration>=MAX_CALL_DURATION) // 16min.s + { + pApplyCharging->ACBCC.maxCallPeriodDuration = 9000; + } + else + { + pApplyCharging->ACBCC.maxCallPeriodDuration = shmp->process_info.maxCallDuration * 10; + + if(shmp->process_info.ro_if.adaptor_enabled == 0 ) + { + pApplyCharging->ACBCC.optional_flag = 0x01; + //pApplyCharging->ACBCC.releaseIfdurationExceeded.tone = 0xff; + if(shmp->process_info.maxCallDuration<60 && shmp->process_info.duration<1200) + pApplyCharging->ACBCC.releaseIfdurationExceeded.tone = 0x00; + else + pApplyCharging->ACBCC.releaseIfdurationExceeded.tone = 0xff; + + if(shmp->process_info.maxCallDuration<60 && shmp->process_info.duration<1200) + pApplyCharging->ACBCC.releaseIfdurationExceeded.tone = 0x00; + else + pApplyCharging->ACBCC.releaseIfdurationExceeded.tone = 0xff; + } + } + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + +} + +void +SendContinue(u_short portid) +{ + int dlgid, invokeid=0; + CAP_Message cap_message; + CapArg capArg; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendContinue"); + + shmp += portid; + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); + AddPPSStatistics(MIBPPS_CONTINUE,shmp->process_info.dir); + + capArg.ocode = CAP_OC_Continue; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + +} + +void +SendActivityTest(u_short portid) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + u_short dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + + PutLogFunID("SendActivityTest"); + + shmp += portid; + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); + AddPPSStatistics(MIBPPS_ACTIVITYS,shmp->process_info.dir); + + capArg.ocode = CAP_OC_ActivityTest; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} +/***********************************************************/ +void SendConnectToResource(u_short portid) +{ + int dlgid,invokeid=0,len; + char buf[128],msisdn[32]; + CAP_Message cap_message; + CapArg capArg; + CapEstablishTemporaryConnection *pTemporaryConnection; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendConnectToResource"); + + shmp += portid; + AddPPSStatistics(MIBPPS_CONNECT_TO_RESOURCE,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); //??? + + capArg.ocode = CAP_OC_EstablishTemporaryConnection; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pTemporaryConnection = &capArg.msg_list.establishTemporaryConnectionArg; + + pTemporaryConnection->optional_flag = 0x03; + + GetSrfAddress(msisdn); + len = strlen(msisdn); + pTemporaryConnection->assistingSSPIPRoutingAddress[0] = (len+1)/2 + 1; + if(len%2==1) //odd + { + pTemporaryConnection->assistingSSPIPRoutingAddress[1] = 0x20; + len ++; + } + else //even + { + pTemporaryConnection->assistingSSPIPRoutingAddress[1] = 0x00; + } + + ppsAsciiToBcdR(&pTemporaryConnection->assistingSSPIPRoutingAddress[2], + msisdn, + len); + + pTemporaryConnection->correlationID[0] = 3; + pTemporaryConnection->correlationID[1] = 0x00; + /* added 01-06 to identify plan 0/1 */ + if(subSystemID) + sprintf(buf,"%04d",4000+portid); + else + sprintf(buf,"%04d",portid); + + ppsAsciiToBcdR(&pTemporaryConnection->correlationID[2], + buf, + 4); + + ppsBcdToAsciiR(msisdn,&ppsParam.ppsNumber[1],20); + StringCut(msisdn,'F'); + len = (strlen(msisdn)+1)/2; + if(len>10) len = 10; + pTemporaryConnection->scfID[0] = len + 1; + if((ppsParam.ppsNumber[len] & 0xF0) == 0xF0) //odd + { + pTemporaryConnection->scfID[1] = 0x20; + } + else + { + pTemporaryConnection->scfID[1] = 0x00; + } + + memcpy(&pTemporaryConnection->scfID[2], + &ppsParam.ppsNumber[1], + len); + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + +} + +int sendConnectForCRDService(u_short portid) +{ + int dlgid,len; + char msisdn[32]; + CAP_Message cap_message; + CapArg capArg; + CapConnect *pConnect; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("sendConnectForCRDService"); + + shmp += portid; + AddPPSStatistics(MIBPPS_CONNECT_TO_RESOURCE,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_Connect; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = 0; + capArg.version = shmp->context_info.acn_ver; + + pConnect = &capArg.msg_list.connectArg; + + + len = strlen(shmp->process_info.tmpDigits); + pConnect->destinationRoutingAddress[0] = (len+1)/2 + 2; + if(len%2==1) //odd + { + pConnect->destinationRoutingAddress[1] = 0x84; + len ++; + shmp->process_info.tmpDigits[len] = '0'; + } + else //even + { + pConnect->destinationRoutingAddress[1] = 0x04; + } + len %= 60; + pConnect->destinationRoutingAddress[2] = 0x10; + ppsAsciiToBcdR(&pConnect->destinationRoutingAddress[3], + shmp->process_info.tmpDigits, + len); + pConnect->optional_flag = 0x02; + + if(shmp->process_info.callConnected == 1) //credit card recharge + { + len = strlen((char *)shmp->called_info.number); + strcpy(msisdn, (char *)shmp->called_info.number); + } + else + { + // DebugMsg(debugmib.display.asciiOut,"type:%d", + // shmp->process_info.chargeOther); + + if(shmp->process_info.chargeOther == 0) + { + len = 0; + msisdn[0] = 0; + pConnect->optional_flag = 0x00; + } + else if(shmp->process_info.chargeOther == 1) + { + len = shmp->process_info.tmpNumber[MAX_MSISDN_BLEN-1]%20; + ppsBcdToAsciiR(msisdn,shmp->process_info.tmpNumber,(len+1)/2*2); + msisdn[len] = 0; + } + else //call forwarded + { + len = strlen((char *)shmp->caller_info.number); + strcpy(msisdn, (char *)shmp->caller_info.number); + } + } + + pConnect->originalCalledPartyID[0] = (len+1)/2 + 2; + if(len % 2 ==1) + { + pConnect->originalCalledPartyID[1] = 0x84; + len ++; + } + else + { + pConnect->originalCalledPartyID[1] = 0x04; + } + if(len>16) len = 16; + pConnect->originalCalledPartyID[2] = 0x10; + ppsAsciiToBcdR(&pConnect->originalCalledPartyID[3], + msisdn, + len); +/* + len = strlen(shmp->caller_info.number); + pConnect->redirectingPartyID[0] = (len+1)/2 + 2; + if(len % 2 ==1) + { + pConnect->redirectingPartyID[1] = 0x84; + len ++; + } + else + { + pConnect->redirectingPartyID[1] = 0x04; + } + pConnect->redirectingPartyID[2] = 0x00; + ppsAsciiToBcdR(&pConnect->redirectingPartyID[3], + shmp->caller_info.number, + len); +*/ + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"SendConnectForVMSService..."); + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; +} + +int SendConnectForVMSService(u_short portid) +{ + int dlgid,len; + char msisdn[32]; + CAP_Message cap_message; + CapArg capArg; + CapConnect *pConnect; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendConnectForVMSService"); + + shmp += portid; +// AddPPSStatistics(MIBPPS_CONNECT_TO_RESOURCE,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_Connect; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = 0; + capArg.version = shmp->context_info.acn_ver; + + pConnect = &capArg.msg_list.connectArg; + + + len = strlen(shmp->process_info.tmpDigits)%MAX_ASCII_NUMBER_LEN; + pConnect->destinationRoutingAddress[0] = (len+1)/2 + 2; + if(len%2==1) //odd + { + pConnect->destinationRoutingAddress[1] = 0x84; + len ++; + shmp->process_info.tmpDigits[len] = '0'; + } + else //even + { + pConnect->destinationRoutingAddress[1] = 0x04; + } + + pConnect->destinationRoutingAddress[2] = 0x10; + ppsAsciiToBcdR(&pConnect->destinationRoutingAddress[3], + shmp->process_info.tmpDigits, + len); + pConnect->optional_flag = 0x02; + + if(shmp->context_info.callType == CT_MF_CALL) + { + len = strlen((char *)shmp->caller_info.number)%MAX_ASCII_NUMBER_LEN; + strcpy(msisdn, (char *)shmp->caller_info.number); + } + else + { + len = 0; + msisdn[0] = 0; + pConnect->optional_flag = 0x00; + } + + pConnect->originalCalledPartyID[0] = (len+1)/2 + 2; + if(len % 2 ==1) + { + pConnect->originalCalledPartyID[1] = 0x84; + len ++; + } + else + { + pConnect->originalCalledPartyID[1] = 0x04; + } + + pConnect->originalCalledPartyID[2] = 0x10; + ppsAsciiToBcdR(&pConnect->originalCalledPartyID[3], + msisdn, + len); + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"\nSendConnectForVMSService"); + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; +} + + + +void SendEstablishTemporaryConnection(u_short portid) +{ + int dlgid,invokeid=0,len; + char buf[128],msisdn[128]; + CAP_Message cap_message; + CapArg capArg; + CapEstablishTemporaryConnection *pTemporaryConnection; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendEstablishTemporaryConnection"); + + shmp += portid; + AddPPSStatistics(MIBPPS_EST_TMP_CNT,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + // invokeid = ApplyForInvokeID(dlgid); //??? + + capArg.ocode = CAP_OC_EstablishTemporaryConnection; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pTemporaryConnection = &capArg.msg_list.establishTemporaryConnectionArg; + + if((ppsParam.serviceControl.cdrFlag & 0x10 )== 0) + { + pTemporaryConnection->optional_flag = 0x03; + GetSrfAddress(msisdn); + len = strlen(msisdn); + pTemporaryConnection->assistingSSPIPRoutingAddress[0] = (len+1)/2 + 3; + pTemporaryConnection->assistingSSPIPRoutingAddress[1] = 0x05; + //number qualifier + if(len%2==1) //odd + { + pTemporaryConnection->assistingSSPIPRoutingAddress[2] = 0x84; + len ++; + } + else //even + { + pTemporaryConnection->assistingSSPIPRoutingAddress[2] = 0x04; + } + pTemporaryConnection->assistingSSPIPRoutingAddress[3] = 0x13; + + ppsAsciiToBcdR(&pTemporaryConnection->assistingSSPIPRoutingAddress[4], + msisdn, + len); + + pTemporaryConnection->correlationID[0] = 3; + pTemporaryConnection->correlationID[1] = 0x00; + if(subSystemID) + sprintf(buf,"%04d",4000+portid); + else + sprintf(buf,"%04d",portid); + ppsAsciiToBcdR(&pTemporaryConnection->correlationID[2], + buf, + 4); + if(subSystemID == 0) + { + ppsBcdToAsciiR(msisdn,&ppsParam.ppsNumber[1],20); + StringCut(msisdn,'F'); + len = (strlen(msisdn)+1)/2; + if(len>18) len = 18; + // len = ppsParam.ppsNumber[0]; + } + else //only for local SRF + { + pps_get_ucbc_number(msisdn); + len = (strlen(msisdn)+1)/2; + if(len>18) len = 18; + strcat(msisdn,"FF"); + + } + + pTemporaryConnection->scfID[0] = len + 1; + + if((ppsParam.ppsNumber[len] & 0xF0) == 0xF0) //odd + { + pTemporaryConnection->scfID[1] = 0x20; + } + else + { + pTemporaryConnection->scfID[1] = 0x00; + } + if(subSystemID == 0) + { + memcpy(&pTemporaryConnection->scfID[2], + &ppsParam.ppsNumber[1], + len); + } + else + { + ppsAsciiToBcdR(&pTemporaryConnection->scfID[2],msisdn, len*2); + } + } + else + { + pTemporaryConnection->optional_flag = 0x00; + GetSrfAddress(msisdn); + + if(subSystemID) + sprintf(buf,"B%04dB",4000+portid); + else + sprintf(buf,"B%04dB",portid); + + strcat(msisdn,buf); + + ppsBcdToAsciiR(buf,&ppsParam.ppsNumber[1],20); + StringCut(buf,'F'); + StringCut(buf,'E'); + len = strlen(buf); + if(len>18) buf[18]=0; + strcat(msisdn,buf); + len = strlen(msisdn); + + pTemporaryConnection->assistingSSPIPRoutingAddress[0] = (len+1)/2 + 3; + pTemporaryConnection->assistingSSPIPRoutingAddress[1] = 0x05; + //number qualifier + if(len%2==1) //odd + { + pTemporaryConnection->assistingSSPIPRoutingAddress[2] = 0x84; + len ++; + } + else //even + { + pTemporaryConnection->assistingSSPIPRoutingAddress[2] = 0x04; + } + pTemporaryConnection->assistingSSPIPRoutingAddress[3] = 0x13; + + ppsAsciiToBcdR(&pTemporaryConnection->assistingSSPIPRoutingAddress[4], + msisdn, + len); + + + } + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +void SendSrfPlayAnnouncement(u_short portid) +{ + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + int voiceID; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendSrfPlayAnnouncement"); + + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); //??? + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x00; + /* review need 2003-10-08,user prefered language type not taken account */ + + if(pps_get_adaptor_flag()) + voiceID = shmp->process_info.voiceID; + else + voiceID = GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + shmp->process_info.voiceID; + + pPlayAnnouncement->informationToSend.inbandInfo.messageID.elementaryMessageID = voiceID; +/* + if(shmp->process_info.srfRelease) + { + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 1; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; //1seconds + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0; + //if disconnectFromIPForbidden=1 then DisconnectForwardConnect need, + else no DisconnectForwardConnect need + // + pPlayAnnouncement->requestAnnouncementComplete = 0; + }else + */ + { + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 3; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; /* 1seconds */ + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 1; + /* if disconnectFromIPForbidden=1 then DisconnectForwardConnect need, + lse no DisconnectForwardConnect need + */ + pPlayAnnouncement->requestAnnouncementComplete = 1; + + } + + StuffCapMessage(capArg,&cap_message); + PutLogFunID("end of SendSrfPlayAnnouncement"); + + WriteScfMsg(cap_message); + PutLogFunID("end of 1 SendSrfPlayAnnouncement"); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +void SendDisconnectForwardConnection(u_short portid) +{ + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendDisconnectForwardConnection"); + + shmp += portid; + AddPPSStatistics(MIBPPS_DISCNT_FWD_CNT,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); //??? + + capArg.ocode = CAP_OC_DisconnectForwardConnection; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +void SendPromptAndCollectUserInfo(u_short portid) +{ + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendPromptAndCollectUserInfo"); + + if(portid>=MAX_FSM_PROCESS) + return; + + shmp += portid; + AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); //??? + + capArg.ocode = CAP_OC_PromptAndCollectUserInformation; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + + pPCUI->collectedInfo.choice_id = 0x00; + pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 0; + pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = + shmp->process_info.maxPCUInfoLen; + pPCUI->collectedInfo.collectedDigits.optional_flag = 0x79; + memcpy(pPCUI->collectedInfo.collectedDigits.endOfReplyDigit, + shmp->process_info.endOfReplyDigit,3); + pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt; + //pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1; + + if(shmp->process_info.voiceID == INPUT_MOBILE_IMEI + || shmp->process_info.voiceID == INPUT_MOBILE_IMEI_AGAIN) + { + pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 0; + } + else + { + pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1; + } + + pPCUI->optional_flag = 0x03; + pPCUI->disconnectFromIPForbidden = 0x01; + pPCUI->informationToSend.choice_id = 0x00; + pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x00; + /* review need 2003-10-08,user prefered language type not taken account + */ + if(pps_get_adaptor_flag()) + pPCUI->informationToSend.inbandInfo.messageID.elementaryMessageID = shmp->process_info.voiceID; + else + pPCUI->informationToSend.inbandInfo.messageID.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + shmp->process_info.voiceID; + + pPCUI->informationToSend.inbandInfo.optional_flag = 0x07; + pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x03; + pPCUI->informationToSend.inbandInfo.duration = 0x00; + pPCUI->informationToSend.inbandInfo.interval = 0x08; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +int SendAccountInfoPromptToSrf(u_short portid,u_char isOnlyBalance,u_char isLastCallAttatched) +{ + int balance,centbalance,promotion=0,hth_b,th_b,h_b,b_b; + char expire_date[20]="",promo_expire_date[20]="",buf[BUFSIZE]=""; + int resolution=100,last_call_flag=0; + int len; + _last_call_info callInfo; + _state_data *shmp; + long expiry_date = 0; + int voice_id = 0; + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + int index=0; + u8 minusFlag=0; + + PutLogFunID("SendAccountInfoPromptToSrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + if(pps_get_adaptor_flag()) + { + balance = shmp->process_info.rest_if.balance; + expiry_date = shmp->process_info.rest_if.mo_expiry_date; + promotion = 0; + voice_id = 0; + } + else + { + balance = GetBalanceWithOutPromotion(shmp->caller_info.head,shmp->caller_info.tail); + promotion = GetPromotion(&shmp->caller_info); + expiry_date = GetExpiration(&shmp->caller_info); + AsciiTime(promo_expire_date,GetPromotionExpiration(&shmp->caller_info)); + + voice_id = GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail); + } + + + if(balance < 0) + { + minusFlag = 1; + balance = abs(balance); + } + + AsciiTime(expire_date, expiry_date); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + resolution = getSystemCurrencyResolution(); + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + index=0; + + /******************balance sign symbol ********************* */ + pMID->variableMessage.variableParts.variablePart[index].choice_id = 5; + pMID->variableMessage.variableParts.variablePart[index].signSymbol = minusFlag; + /****************** balance sign symbol ********************* */ + + /****************** account balance********************* */ + index++; + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + pMID->variableMessage.variableParts.variablePart[index].choice_id = 4; + sprintf(buf,"%02d",hth_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[3], + buf,2); + + if(isOnlyBalance == TRUE) + { + pMID->variableMessage.variableParts.num = 2; + pMID->variableMessage.elementaryMessageID = voice_id*65536 + + ONLY_BALANCE_IS; + } + else + { + /* account expiry day */ + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 3; + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[0], + expire_date,4); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[2], + &expire_date[4],2); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[3], + &expire_date[6],2); + /****************** account balance********************* */ + + /****************** promotion ********************* */ + if(promotion > 0) + { + index++; + centbalance = (promotion % resolution); + promotion = (promotion / resolution); + hth_b = (promotion / 10000)%100; + th_b = (promotion / 1000)%10; + h_b = (promotion / 100)%10; + b_b = (promotion % 100); + pMID->variableMessage.variableParts.variablePart[index].choice_id = 4; + sprintf(buf,"%02d",hth_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[3], + buf,2); + + /* account expiry day */ + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 3; + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[0], + promo_expire_date,4); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[2], + &promo_expire_date[4],2); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[3], + &promo_expire_date[6],2); + pMID->variableMessage.elementaryMessageID = voice_id*65536 + + INQUIRY_WITH_PROMOTION; + pMID->variableMessage.variableParts.num = 5; + } + /****************** promotion********************* */ + else + { + pMID->variableMessage.elementaryMessageID = voice_id*65536 + + ACCOUNT_BALANCE_IS; + + if(isLastCallAttatched == TRUE && GetAccountLastCallInfo(&shmp->caller_info,&callInfo)) + { + pMID->variableMessage.variableParts.num = 6; + last_call_flag = 1; + } + else + { + pMID->variableMessage.variableParts.num = 3; + } + + if(last_call_flag) + { + index++; + if(callInfo.last_call_type == LST_MT_CALL) + pMID->variableMessage.elementaryMessageID = voice_id*65536 + + INQUIRY_MESSAGE_FROM; + + AsciiTime(expire_date,callInfo.last_call_date); + pMID->variableMessage.variableParts.variablePart[index].choice_id = 3; + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[0], + expire_date,4); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[2], + &expire_date[4],2); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[3], + &expire_date[6],2); + + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 2; + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].time[0], + &expire_date[8],2); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].time[1], + &expire_date[10],2); + + + len = callInfo.last_call_number[MAX_MSISDN_BLEN-1]; + if(len>(MAX_MSISDN_BLEN-1)*2) + len = (MAX_MSISDN_BLEN - 1 )*2; + + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 1; + + pMID->variableMessage.variableParts.variablePart[index].number[0] = (len+1)/2+1; + if(len%2==0) + { + pMID->variableMessage.variableParts.variablePart[index].number[1] = 0x04; + memcpy(&pMID->variableMessage.variableParts.variablePart[index].number[2], + callInfo.last_call_number, + (len+1)/2); + + } + else + { + pMID->variableMessage.variableParts.variablePart[index].number[1] = 0x24; + memcpy(&pMID->variableMessage.variableParts.variablePart[index].number[2], + callInfo.last_call_number, + (len+1)/2); + pMID->variableMessage.variableParts.variablePart[index].number[2+(len+1)/2] &=0x0F; + } + + } + } + } + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x03; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; +} + +int SendRestAccountInfoPromptToSrf(u_short portid) +{ + int balance,centbalance,/*promotion=0,*/hth_b,th_b,h_b,b_b; + char expire_date[20]="",buf[BUFSIZE]=""; + int resolution=100; + long expiry_date; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + int index=0; + u8 minusFlag=0; + + PutLogFunID("SendRestAccountInfoPromptToSrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + balance = shmp->process_info.rest_if.balance; + expiry_date = shmp->process_info.rest_if.mo_expiry_date; + + if(balance < 0) + { + minusFlag = 1; + balance = abs(balance); + } + + AsciiTime(expire_date,expiry_date); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + resolution = getSystemCurrencyResolution(); + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + index=0; + + /******************balance sign symbol ********************* */ + pMID->variableMessage.variableParts.variablePart[index].choice_id = 5; + pMID->variableMessage.variableParts.variablePart[index].signSymbol = minusFlag; + /****************** balance sign symbol ********************* */ + + /****************** account balance********************* */ + index++; + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + pMID->variableMessage.variableParts.variablePart[index].choice_id = 4; + sprintf(buf,"%02d",hth_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[3], + buf,2); + + { + /* account expiry day */ + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 3; + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[0], + expire_date,4); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[2], + &expire_date[4],2); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[3], + &expire_date[6],2); + /****************** account balance********************* */ + + pMID->variableMessage.elementaryMessageID = ACCOUNT_BALANCE_IS; + + pMID->variableMessage.variableParts.num = index+1; + } + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; +} + +void SendAccountBalanceBySrf(u_short portid) +{ + int balance,centbalance,hth_b,th_b,h_b,b_b; + char buf[BUFSIZE]=""; + int resolution=1000; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + + + PutLogFunID("SendAccountBalanceBySrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + balance = GetAccountBalance(shmp->caller_info.head, + shmp->caller_info.tail); + + if(balance<0) balance = 0; + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + resolution = getSystemCurrencyResolution(); + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + /* account balance */ + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + ONLY_BALANCE_IS; + + pMID->variableMessage.variableParts.num = 1; + + pMID->variableMessage.variableParts.variablePart[0].choice_id = 4; + sprintf(buf,"%02d",hth_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[0].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[0].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[0].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[0].price[3], + buf,2); + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +int SendRechargeInfoPromptToSrf(u_short portid) +{ + int balance,centbalance,hth_b,th_b,h_b,b_b; + char expire_date[20]="",buf[BUFSIZE]=""; + int resolution = 100; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + u_char minusFlag=0,index=0; + + _account_info tmpInfo; + + PutLogFunID("SendRechargeInfoPromptToSrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + resolution = getSystemCurrencyResolution(); + if(shmp->process_info.rechargeByOther) + { + memcpy(&tmpInfo,&shmp->caller_info,sizeof(_account_info)); + memcpy(&shmp->caller_info,&shmp->recharge_info,sizeof(_account_info)); + } + + balance = GetAccountBalance(shmp->caller_info.head, + shmp->caller_info.tail); + if(balance < 0) + { + minusFlag = 1; + balance = abs(balance); + } + + AsciiTime(expire_date,GetExpiration(&shmp->caller_info)); + + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + //recharge face value + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + RECHARGE_SUCCESS; + + pMID->variableMessage.variableParts.num = 3; + /******************balance sign symbol ********************* */ + pMID->variableMessage.variableParts.variablePart[index].choice_id = 5; + pMID->variableMessage.variableParts.variablePart[index].signSymbol = minusFlag; + /****************** balance sign symbol ********************* */ + + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 4; + sprintf(buf,"%02d",hth_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[3], + buf,2); + + /* account balance */ + /* + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + + pMID->variableMessage.variableParts.variablePart[1].choice_id = 4; + sprintf(buf,"%02d",hth_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[1].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[1].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[1].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[1].price[3], + buf,2); + */ + /* account expiry day */ + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 3; + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[0], + expire_date,4); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[2], + &expire_date[4],2); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[3], + &expire_date[6],2); + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + if(shmp->process_info.rechargeByOther) + { + memcpy(&shmp->caller_info,&tmpInfo,sizeof(_account_info)); + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; +} + +int SendRestRechargeInfoPromptToSrf(u_short portid) +{ + int balance,centbalance,hth_b,th_b,h_b,b_b; + char expire_date[20]="",buf[BUFSIZE]=""; + int resolution = 100; + _state_data *shmp; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + CapPlayAnnouncement *pPlayAnnouncement; + CapMessageID *pMID; + u_char minusFlag=0,index=0; + + _account_info tmpInfo; + + PutLogFunID("SendRestRechargeInfoPromptToSrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + + resolution = getSystemCurrencyResolution(); + if(shmp->process_info.rechargeByOther) + { + memcpy(&tmpInfo,&shmp->caller_info,sizeof(_account_info)); + memcpy(&shmp->caller_info,&shmp->recharge_info,sizeof(_account_info)); + } + + balance = shmp->process_info.rest_if.balance; + if(balance < 0) + { + minusFlag = 1; + balance = abs(balance); + } + + AsciiTime(expire_date,shmp->process_info.rest_if.mo_expiry_date ); + + centbalance = (balance % resolution); + balance = (balance / resolution); + hth_b = (balance / 10000)%100; + th_b = (balance / 1000)%10; + h_b = (balance / 100)%10; + b_b = (balance % 100); + + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + //recharge face value + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + pMID->variableMessage.elementaryMessageID = RECHARGE_SUCCESS; + + pMID->variableMessage.variableParts.num = 3; + /******************balance sign symbol ********************* */ + pMID->variableMessage.variableParts.variablePart[index].choice_id = 5; + pMID->variableMessage.variableParts.variablePart[index].signSymbol = minusFlag; + /****************** balance sign symbol ********************* */ + + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 4; + sprintf(buf,"%02d",hth_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[0], + buf,2); + sprintf(buf,"%d%d",th_b,h_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[1], + buf,2); + sprintf(buf,"%02d",b_b); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[2], + buf,2); + sprintf(buf,"%02d",centbalance); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].price[3], + buf,2); + + /* account expiry day */ + index++; + pMID->variableMessage.variableParts.variablePart[index].choice_id = 3; + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[0], + expire_date,4); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[2], + &expire_date[4],2); + ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[index].date[3], + &expire_date[6],2); + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + if(shmp->process_info.rechargeByOther) + { + memcpy(&shmp->caller_info,&tmpInfo,sizeof(_account_info)); + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + return 1; +} + + +void SendPromptCollectedRechargedUserInfo(u_short portid) +{ + int dlgid,invokeid=0,len; + char buf[BUFSIZE]; + CAP_Message cap_message; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + CapMessageID *pMID; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendPromptCollectedRechargedUserInfo"); + + shmp += portid; + AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PromptAndCollectUserInformation; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + + pPCUI->collectedInfo.choice_id = 0x00; + pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1; + pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = + shmp->process_info.maxPCUInfoLen; + pPCUI->collectedInfo.collectedDigits.optional_flag = 0x79; + memcpy(pPCUI->collectedInfo.collectedDigits.endOfReplyDigit, + shmp->process_info.endOfReplyDigit,3); + pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt; + pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1; + + pPCUI->optional_flag = 0x03; + pPCUI->disconnectFromIPForbidden = 0x01; + pPCUI->informationToSend.choice_id = 0x00; + pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPCUI->informationToSend.inbandInfo.messageID; + if(pps_get_adaptor_flag()) + pMID->variableMessage.elementaryMessageID = shmp->process_info.voiceID; + else + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + +shmp->process_info.voiceID; + pMID->variableMessage.variableParts.num = 1; + pMID->variableMessage.variableParts.variablePart[0].choice_id = 1; + + ppsBcdToAsciiR(buf,shmp->cdr_info.msisdn,16); + StringCut(buf,'F'); + len = strlen(buf); + if(len>20) len = 20; + + pMID->variableMessage.variableParts.variablePart[0].number[0] = (len+1)/2+1; + if(len%2==0) + { + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x04; + memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2], + shmp->cdr_info.msisdn, + (len+1)/2); + + } + else + { + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x24; + memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2], + shmp->cdr_info.msisdn, + (len+1)/2); + pMID->variableMessage.variableParts.variablePart[0].number[2+(len+1)/2] &=0x0F; + } + + pPCUI->informationToSend.inbandInfo.optional_flag = 0x07; + pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x02; + pPCUI->informationToSend.inbandInfo.duration = 0x00; + pPCUI->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif + +} + +void SendFavPromptAndCollectUserInfo(u_short portid) +{ + int dlgid,invokeid=0,len; + u_char u_msisdn[32]; + char buf[BUFSIZE]; + CAP_Message cap_message; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + CapMessageID *pMID; + + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendFavPromptAndCollectUserInfo"); + + shmp += portid; + AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PromptAndCollectUserInformation; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + + pPCUI->collectedInfo.choice_id = 0x00; + pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1; + pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = + shmp->process_info.maxPCUInfoLen; + pPCUI->collectedInfo.collectedDigits.optional_flag = 0x79; + memcpy(pPCUI->collectedInfo.collectedDigits.endOfReplyDigit, + shmp->process_info.endOfReplyDigit,3); + pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10; + pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt; + pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1; + + pPCUI->optional_flag = 0x03; + pPCUI->disconnectFromIPForbidden = 0x01; + pPCUI->informationToSend.choice_id = 0x00; + pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03; + + pMID = &pPCUI->informationToSend.inbandInfo.messageID; + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + +shmp->process_info.voiceID; + pMID->variableMessage.variableParts.num = 1; + + + pMID->variableMessage.variableParts.variablePart[0].choice_id = 1; + strcpy(buf,shmp->process_info.tmpDigits); + len = strlen(buf); + if(len>18) len = 18; + ppsAsciiToBcdR(u_msisdn,buf,((len+1)/2)*2); + pMID->variableMessage.variableParts.variablePart[0].number[0] = (len+1)/2+1; + if(len%2==0) + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x04; + else + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x24; + memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2], + u_msisdn, + (len+1)/2); + + /* + else + { + pMID->variableMessage.variableParts.variablePart[0].choice_id = 0; + pMID->variableMessage.variableParts.variablePart[0].integer = counter; + } + */ + pPCUI->informationToSend.inbandInfo.optional_flag = 0x07; + pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x01; + pPCUI->informationToSend.inbandInfo.duration = 0x00; + pPCUI->informationToSend.inbandInfo.interval = 0x01; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +int SendScfUAbort(u_short portid) +{ + int /*dlgid,*/msglen; + CAP_Message capmsg, *pcap_message; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendUAbort"); + + shmp += portid; + //dlgid = shmp->context_info.dialogue_id; + + pcap_message = &capmsg; + memset(pcap_message,0,sizeof(CAP_Message)); + pcap_message->msgServiceCode = CAP_MSG_TYPE; + pcap_message->dialogue_id[0] = shmp->context_info.dialogue_id>>8; + pcap_message->dialogue_id[1] = shmp->context_info.dialogue_id; + pcap_message->dialogue_id[2] = 0x00; + pcap_message->port_id[0] = portid>>8; + pcap_message->port_id[1] = portid; + pcap_message->port_id[2] = 0x00; + pcap_message->msgOperaCode = CAP_O_UABORT; + pcap_message->msgOperaType = 0x01; //REQUEST; + pcap_message->msgContent[0] = shmp->process_info.u_error; + pcap_message->msgContent[1] = 0x00; + pcap_message->msgContent[2] = 0x00; + msglen = 12; + + pcap_message->msgLength[0] = msglen>>8; + pcap_message->msgLength[1] = msglen; + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif + return 1; +} + +int SendScfUError(u_short portid) +{ + int /*dlgid,*/msglen; + CAP_Message capmsg, *pcap_message; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendUError"); + + shmp += portid; + //dlgid = shmp->context_info.dialogue_id; + + pcap_message = &capmsg; + memset(pcap_message,0,sizeof(CAP_Message)); + pcap_message->msgServiceCode = CAP_MSG_TYPE; + pcap_message->dialogue_id[0] = shmp->context_info.dialogue_id>>8; + pcap_message->dialogue_id[1] = shmp->context_info.dialogue_id; + pcap_message->dialogue_id[2] = 0x00; + pcap_message->port_id[0] = portid>>8; + pcap_message->port_id[1] = portid; + pcap_message->port_id[2] = 0x00; + pcap_message->msgOperaCode = shmp->process_info.oc; + pcap_message->msgOperaType = 0x03; //RESPONSE; + pcap_message->msgContent[0] = 0; //invokeid + pcap_message->msgContent[1] = 0x01; //optional tag + pcap_message->msgContent[2] = 0x02; //u_error tag + pcap_message->msgContent[3] = 0x01; + pcap_message->msgContent[4] = shmp->process_info.u_error; + pcap_message->msgContent[5] = 0x10; + pcap_message->msgContent[6] = 0x00; + pcap_message->msgContent[7] = 0x00; + msglen = 17; + + pcap_message->msgLength[0] = msglen>>8; + pcap_message->msgLength[1] = msglen; + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif + return 1; +} + +int SendScfTcEND(u_short portid) +{ + int /*dlgid,*/msglen; + CAP_Message capmsg, *pcap_message; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendScfTcEND"); + + shmp += portid; + shmp->process_info.answerWanted = 0x01; + + + //dlgid = shmp->context_info.dialogue_id; + + pcap_message = &capmsg; + memset(pcap_message,0,sizeof(CAP_Message)); + pcap_message->msgServiceCode = CAP_MSG_TYPE; + pcap_message->dialogue_id[0] = shmp->context_info.dialogue_id>>8; + pcap_message->dialogue_id[1] = shmp->context_info.dialogue_id; + pcap_message->dialogue_id[2] = 0x00; + pcap_message->port_id[0] = portid>>8; + pcap_message->port_id[1] = portid; + pcap_message->port_id[2] = 0x00; + pcap_message->msgOperaCode = CAP_O_END; + pcap_message->msgOperaType = 0x01; //REQUEST; + pcap_message->msgContent[0] = 0x01; //release method + pcap_message->msgContent[1] = 0x00; //optional tag + pcap_message->msgContent[2] = 0x00; //end tag + + msglen = 12; + + pcap_message->msgLength[0] = msglen>>8; + pcap_message->msgLength[1] = msglen; + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif + return 1; +} + +/***********************************************************/ +void +SendRequestSMSEvents(u_short portid) +{ + int invokeid=0,dlgid; + CAP_Message capmsg; + CapArg capArg; + struct CapRequestReportSMSEvent *pStr; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendRequestSMSEvents"); + + shmp += portid; + shmp->process_info.answerWanted = 0x01; + + AddPPSStatistics(MIBPPS_REQUEST_SMS,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); + + capArg.ocode = CAP_OC_RequestReportSMSEvent; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + pStr = &capArg.msg_list.requestReportSMSEventArg; + pStr->sMSEvents_num = 2; + pStr->sMSEvents[0].eventTypeSMS = capp_osmsFailure; + pStr->sMSEvents[0].monitorMode = capp_interrupted; + + pStr->sMSEvents[1].eventTypeSMS = capp_osmsSubmitted; + pStr->sMSEvents[1].monitorMode = capp_interrupted; + + StuffCapMessage(capArg, &capmsg); + + WriteScfMsg(capmsg); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif +} + +void +SendContinueSMS(u_short portid) +{ + int dlgid, invokeid=0; + CAP_Message cap_message; + CapArg capArg; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendContinueSMS"); + + AddPPSStatistics(MIBPPS_CONTINUE_SMS,shmp->process_info.dir); + + shmp += portid; + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); + + capArg.ocode = CAP_OC_ContinueSMS; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +void +SendReleaseSMS(u_short portid) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + int dlgid,invokeid=0; + CAP_Message cap_message; + CapArg capArg; + u_char cause=111; + + PutLogFunID("SendReleaseSMS"); + + shmp += portid; + AddPPSStatistics(MIBPPS_RELEASE_SMS,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; +// invokeid = ApplyForInvokeID(dlgid); + + capArg.ocode = CAP_OC_ReleaseSMS; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.msg_list.releaseSMSArg.cause = cause; + capArg.version = shmp->context_info.acn_ver; + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + +/***************************************************/ +void stuff_sccp_address(SCCP_ADDR *pAddr,char *msisdn, u_char ssn,u_char translate_type) +{ + int len; + u_char tt=0; + char gtt[32]; + + pAddr->ip = 0; + pAddr->DPC = 0; + pAddr->RI = 0; + pAddr->NetID = 4; + pAddr->SSN = ssn; + pAddr->GTI = 4; + + tt = sccp_GetSSNType(ssn); + + pAddr->NAI = 4; + if(tt == 0) + { + pAddr->TT = translate_type; + pAddr->NP = 1; + } + else + { + pAddr->TT = 14; + pAddr->NP = 0; + pAddr->GTI= 2; + } + + len = strlen(msisdn); + if(len>20) len= 20; + pAddr->len = len; + if(len %2==1) + { + strcpy(gtt,msisdn); + strcat(gtt,"F"); + len ++; + ppsAsciiToBcdR(pAddr->GTAI,gtt,len); + }else + ppsAsciiToBcdR(pAddr->GTAI,msisdn,len); +} + +void srfActivityMonitor() +{ + static u_char srf_state[MaxSrfNumberItem]={0,0}; + static u_long srf_dlgid[MaxSrfNumberItem]={0,0}; + static u_long srf_timer[MaxSrfNumberItem]={0,0}; + CAP_Message capmsg; + SCCP_ADDR sccpAddr; + char msisdn[32]=""; + int i,sendEnd = 0, test_timer=10; + + for(i=0;i>8; + capmsg.dialogue_id[1] = srf_dlgid[i]; + capmsg.dialogue_id[2] = 0x00; + capmsg.port_id[0] = 0x00; + capmsg.port_id[1] = 0x00; + capmsg.port_id[2] = 0x00; + capmsg.msgOperaCode = CAP_O_OPEN; + capmsg.msgOperaType = 0x01; //REQUEST; + capmsg.msgContent[0] = 0x32; //ACN + capmsg.msgContent[1] = 0x02; //ACN Version = 2 + + stuff_sccp_address(&sccpAddr, + (char *)ppsParam.ppsTables.srfNumber[i].number, + 8,0); + memcpy(&capmsg.msgContent[2], + &sccpAddr, + sizeof(SCCP_ADDR)); + + ppsBcdToAsciiR(msisdn,&ppsParam.ppsNumber[1],20); + StringCut(msisdn,'F'); + stuff_sccp_address(&sccpAddr,msisdn,147,0); + memcpy(&capmsg.msgContent[2+sizeof(SCCP_ADDR)], + &sccpAddr, + sizeof(SCCP_ADDR)); + + cap_send_comdata((u8 *)&capmsg); + + capmsg.msgLength[0] = 0; + capmsg.msgLength[1] = 14; + capmsg.msgServiceCode = CAP_MSG_TYPE; + capmsg.dialogue_id[0] = srf_dlgid[i]>>8; + capmsg.dialogue_id[1] = srf_dlgid[i]; + capmsg.dialogue_id[2] = 0x00; + capmsg.port_id[0] = 0x00; + capmsg.port_id[1] = 0x00; + capmsg.port_id[2] = 0x00; + capmsg.msgOperaCode = CAP_OC_ActivityTest; + capmsg.msgOperaType = 0x01; //REQUEST; + capmsg.msgContent[0] = cap_get_invokeid(srf_dlgid[i]); + capmsg.msgContent[1] = 0x01; + capmsg.msgContent[2] = 0x10; + capmsg.msgContent[3] = 0x00; + capmsg.msgContent[4] = 0x00; + + cap_send_oprdata((u8 *)&capmsg); + srf_timer[i] = 0; + srf_state[i] = 2; +#if DEBUG1 + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x02) + { + ppsDebugCapMsg(&capmsg,1); + debug_messages ++; + } +#endif + + break; + case 2: + sendEnd = 0; + if(srf_timer[i] ++> 5*CYCLE_STATE_INTERVAL) + { + ppsParam.ppsTables.srfNumber[i].reachable = 0; + srf_state[i] = 3; + sendEnd = 1; + } + if(cap_get_comdata((u8 *)&capmsg,srf_dlgid[i])) + { + if(capmsg.msgOperaCode == CAP_O_END) + { + ppsParam.ppsTables.srfNumber[i].reachable = 1; + srf_state[i] = 3; + //sendEnd = 1; + } + } + else if(cap_get_oprdata((u8 *)&capmsg,srf_dlgid[i])) + { + if(capmsg.msgOperaCode == CAP_OC_ActivityTest) + ppsParam.ppsTables.srfNumber[i].reachable = 1; + srf_state[i] = 3; + sendEnd = 1; + } + + if(sendEnd) + { + capmsg.msgLength[0] = 0; + capmsg.msgLength[1] = 12; + capmsg.msgServiceCode = CAP_MSG_TYPE; + capmsg.dialogue_id[0] = srf_dlgid[i]>>8; + capmsg.dialogue_id[1] = srf_dlgid[i]; + capmsg.dialogue_id[2] = 0x00; + capmsg.port_id[0] = 0x00; + capmsg.port_id[1] = 0x00; + capmsg.port_id[2] = 0x00; + capmsg.msgOperaCode = CAP_O_END; + capmsg.msgOperaType = 0x01; //REQUEST; + capmsg.msgContent[0] = BASIC_END; + capmsg.msgContent[1] = 0x00; + capmsg.msgContent[2] = 0x00; + cap_send_comdata((u8 *)&capmsg); + } + break; + case 3: + if(ppsParam.ppsTables.srfNumber[i].reachable) + test_timer = 30*ONE_MINUTE_STATE_TIME; + else + test_timer = 1*ONE_MINUTE_STATE_TIME; + if(srf_timer[i] ++> test_timer) + srf_state[i] = 0; + break; + default: + break; + }//switch + }//for +} + +int CheckSRFResource() +{ + int srfNum=0; + + if(ppsParam.ppsTables.srfNumber[0].reachable) + srfNum ++; + if(ppsParam.ppsTables.srfNumber[1].reachable) + srfNum ++; + return srfNum; + +} + +int GetSrfAddress(char *msisdn) +{ + static u_char referenceNo=0; + int srfNum=0; + + if(ppsParam.ppsTables.srfNumber[0].reachable) + srfNum ++; + if(ppsParam.ppsTables.srfNumber[1].reachable) + srfNum ++; + + if(srfNum == 0) + { + strcpy(msisdn, (char *)ppsParam.ppsTables.srfNumber[0].number); + return 0; + } + if(srfNum == 1) + { + if(ppsParam.ppsTables.srfNumber[0].reachable) + strcpy(msisdn, (char *)ppsParam.ppsTables.srfNumber[0].number); + else if(ppsParam.ppsTables.srfNumber[1].reachable) + strcpy(msisdn, (char *)ppsParam.ppsTables.srfNumber[1].number); + } + else + { + + if(ppsParam.ppsTables.srfNumber[0].reachable && referenceNo%2==0) + { + strcpy(msisdn, (char *)ppsParam.ppsTables.srfNumber[0].number); + } + else if(ppsParam.ppsTables.srfNumber[1].reachable && referenceNo%2==1) + { + strcpy(msisdn, (char *)ppsParam.ppsTables.srfNumber[1].number); + } + referenceNo ++; + } + return 1; +} +/***************************************************/ + +int encodePPS_MO_CDR(_tocdr_report *pcdr,u_char *pdata) +{ + int len = 0, recordType=0; + ASN_BUF *asnbuf, asnbuf1; + u_char buf[BUFSIZE]={""},charge[8],balance[8],duration[8]; + + PutLogFunID("encodePPS_MO_CDR"); + + asnbuf = &asnbuf1; + asn_encode(pdata,asnbuf); + + recordType = pcdr->mtype; + len = add_int("2-1",pcdr->squence,0x00,asnbuf); + len = add_tlv("0-2.0",1, (u_char *)&recordType,0x80,asnbuf); /* record type */ + + len = add_tlv("0-2.3",9,pcdr->msisdn,0x80,asnbuf); /* served MSISDN */ + + len = add_tlv("0-2.9",10,ppsParam.ppsNumber,0x80,asnbuf); /* Recording Entity */ + + CharToTimeStamp(buf, (char *)pcdr->seizuretime); + len = add_tlv("0-2.22",8,buf,0x80,asnbuf); /* seizure timestamp */ + CharToTimeStamp(buf, (char *)pcdr->answertime); + len = add_tlv("0-2.23",8,buf,0x80,asnbuf); /* answer timestamp*/ + CharToTimeStamp(buf, (char *)pcdr->releasetime); + len = add_tlv("0-2.24",8,buf,0x80,asnbuf); /* release timestamp*/ + duration[0] = pcdr->duration[3]; + duration[1] = pcdr->duration[2]; + duration[2] = pcdr->duration[1]; + duration[3] = pcdr->duration[0]; + len = add_tlv("0-2.25",4,duration,0x80,asnbuf);/*call duration*/ + len = add_tlv("0-2.30",1,pcdr->tcos,0x80,asnbuf); /* cause for term*/ + + switch(pcdr->type[0]) + { + case CT_GPRS: + case CT_GPRS_REFUND: + len = add_tlv("0-2.4",9,pcdr->caller,0x80,asnbuf); /* calling number */ + len = add_tlv("0-2.35",strlen((char *)pcdr->gprsSgsnIP),pcdr->gprsSgsnIP,0x80,asnbuf); /* sgsn ip*/ + len = add_tlv("0-2.36",strlen((char *)pcdr->gprsGgsnIP),pcdr->gprsGgsnIP,0x80,asnbuf); /* gsn ip*/ + len = add_tlv("0-2.37",strlen((char *)pcdr->gprsDestIP),pcdr->gprsDestIP,0x80,asnbuf); /* dest ip*/ + len = add_tlv("0-2.38",4,pcdr->gprsVolume,0x80,asnbuf); /* volume*/ + break; + case CT_VAS_SMS: + case CT_VAS_MMS_SEND: + len = add_tlv("0-2.39",strlen((char *)pcdr->peerAddress),pcdr->peerAddress,0x80,asnbuf); /* peer address*/ + break; + default: + len = add_tlv("0-2.1",8,pcdr->imsi,0x80,asnbuf); /* served IMSI */ + len = add_tlv("0-2.4",9,pcdr->caller,0x80,asnbuf); /* calling number */ + len = add_tlv("0-2.5",12,pcdr->called,0x80,asnbuf); /* called number */ + if(OCS_with_external_CRM()) + { + if (strlen(pcdr->peerAddress) > 0) + { + len = add_tlv("0-2.39",strlen((char *)pcdr->peerAddress),pcdr->peerAddress,0x80,asnbuf);/* area name */ + } + } + break; + } + + len = add_tlv("0-2.128",1,pcdr->type,0x80,asnbuf); /* call type */ + charge[0] = pcdr->charge[3]; + charge[1] = pcdr->charge[2]; + charge[2] = pcdr->charge[1]; + charge[3] = pcdr->charge[0]; + len = add_tlv("0-2.129",4,charge,0x80,asnbuf); /* charge */ + balance[0] = pcdr->balance[3]; + balance[1] = pcdr->balance[2]; + balance[2] = pcdr->balance[1]; + balance[3] = pcdr->balance[0]; + len = add_tlv("0-2.130",4,balance,0x80,asnbuf); /* balance */ + if(OCS_with_external_CRM()) + { + char plan_id[4]; + plan_id[0] = pcdr->plan_id[3]; + plan_id[1] = pcdr->plan_id[2]; + plan_id[2] = pcdr->plan_id[1]; + plan_id[3] = pcdr->plan_id[0]; + len = add_tlv("0-2.131",4,(u_char *)plan_id,0x80,asnbuf); /* balance */ + } + else + { + len = add_int("0-2.131",pcdr->cos_id,0x80,asnbuf); + } + return len; +} + + +int encodePPS_MT_CDR(_tocdr_report *pcdr,u_char *pdata) +{ + int len = 0, recordType=0; + ASN_BUF *asnbuf, asnbuf1; + + u_char buf[BUFSIZE]={""},charge[8],balance[8],duration[8]; + + PutLogFunID("encdoePPS_MT_CDR"); + + asnbuf = &asnbuf1; + asn_encode(pdata,asnbuf); + + recordType = pcdr->mtype; + len = add_int("2-1",pcdr->squence,0x00,asnbuf); + len = add_tlv("1-2.0",1, (u_char *)&recordType,0x80,asnbuf); /* record type */ + + len = add_tlv("1-2.6",10,ppsParam.ppsNumber,0x80,asnbuf); /* Recording Entity */ + + CharToTimeStamp(buf, (char *)pcdr->seizuretime); + len = add_tlv("1-2.19",8,buf,0x80,asnbuf); /* seizure timestamp */ + CharToTimeStamp(buf, (char *)pcdr->answertime); + len = add_tlv("1-2.20",8,buf,0x80,asnbuf); /* answer timestamp*/ + CharToTimeStamp(buf, (char *)pcdr->releasetime); + len = add_tlv("1-2.21",8,buf,0x80,asnbuf); /* release timestamp*/ + duration[0] = pcdr->duration[3]; + duration[1] = pcdr->duration[2]; + duration[2] = pcdr->duration[1]; + duration[3] = pcdr->duration[0]; + len = add_tlv("1-2.22",4,duration,0x80,asnbuf);/*call duration*/ + len = add_tlv("1-2.27",1,pcdr->tcos,0x80,asnbuf); /* cause for term*/ + len = add_tlv("1-2.128",1,pcdr->type,0x80,asnbuf); /* call type */ + charge[0] = pcdr->charge[3]; + charge[1] = pcdr->charge[2]; + charge[2] = pcdr->charge[1]; + charge[3] = pcdr->charge[0]; + len = add_tlv("1-2.129",4,charge,0x80,asnbuf); /* charge */ + balance[0] = pcdr->balance[3]; + balance[1] = pcdr->balance[2]; + balance[2] = pcdr->balance[1]; + balance[3] = pcdr->balance[0]; + len = add_tlv("1-2.130",4,balance,0x80,asnbuf); /* balance */ + if(OCS_with_external_CRM()) + { + char plan_id[4]; + plan_id[0] = pcdr->plan_id[3]; + plan_id[1] = pcdr->plan_id[2]; + plan_id[2] = pcdr->plan_id[1]; + plan_id[3] = pcdr->plan_id[0]; + len = add_tlv("0-2.131",4,(u_char *)plan_id,0x80,asnbuf); /* balance */ + } + else + len = add_int("0-2.131",pcdr->cos_id,0x80,asnbuf); + + switch(pcdr->type[0]) + { + case CT_VAS_MMS_RETRIEVE: + case CT_VAS_MMS_EMAIL: + len = add_tlv("1-2.39",strlen((char *)pcdr->peerAddress),pcdr->peerAddress,0x80,asnbuf); /* peer address*/ + len = add_tlv("1-2.3",9,pcdr->msisdn,0x80,asnbuf); /* served number */ + break; + default: + len = add_tlv("1-2.1",8,pcdr->imsi,0x80,asnbuf); /* served IMSI */ + len = add_tlv("1-2.3",9,pcdr->called,0x80,asnbuf); /* called number */ + len = add_tlv("1-2.4",9,pcdr->caller,0x80,asnbuf); /* calling number */ + len = add_tlv("1-2.5",9,pcdr->called,0x80,asnbuf); /* connected number */ + if(OCS_with_external_CRM()) + { + if (strlen(pcdr->peerAddress) > 0) + { + len = add_tlv("0-2.39",strlen((char *)pcdr->peerAddress),pcdr->peerAddress,0x80,asnbuf);/* area name */ + } + } + break; + } + return len; +} + +static pthread_mutex_t store_cdr_mutx = PTHREAD_MUTEX_INITIALIZER; + +int StoreCDR(_tocdr_report *pcdr) +{ + int pWriteSub ,pReadSub; + int tmpLen=0; + + pthread_mutex_lock(&store_cdr_mutx); + + PutLogFunID("StoreCDR"); + + if((ppsParam.serviceControl.cdrFlag & 0x0f)== 0) return 0; + + pWriteSub = pps_cdr_buffer.pWriteSub; + pReadSub = pps_cdr_buffer.pReadSub; + + pcdr->squence = cdr_head_ptr++; + cdr_head_ptr &= 0x7fffffff; + + pps_cdr_buffer.flag[pWriteSub] = 0x01; + //memcpy(&pps_cdr_buffer.cdr_record[pWriteSub],pcdr,sizeof(_tocdr_report)); + + switch(pcdr->mtype) + { + case MO_CDR_TYPE: + default: + tmpLen = encodePPS_MO_CDR(pcdr,&pps_cdr_buffer.cdrMsg[pWriteSub][1]); + break; + case MT_CDR_TYPE: + tmpLen = encodePPS_MT_CDR(pcdr,&pps_cdr_buffer.cdrMsg[pWriteSub][1]); + break; + } + + cdr_submit(SSN_SCF, tmpLen, (char *)&pps_cdr_buffer.cdrMsg[pWriteSub][1]); + + pps_cdr_buffer.cdrMsg[pWriteSub][0] = tmpLen%254; + + pWriteSub ++; + + if(pReadSub == pWriteSub) + { + alarm_code[0] = 0x01; /* cdr */ + alarm_code[1] = 0x01; /* overflow */ + ppsSendHeartBeating(); + AddPPSStatistics(MIBPPS_CDROVERFLOW,0); + } + + if(pWriteSub>=MAX_CDR_LEN) pWriteSub = 0; + pps_cdr_buffer.pWriteSub = pWriteSub; + AddPPSStatistics(MIBPPS_CDRNUMBER,0); + + pthread_mutex_unlock(&store_cdr_mutx); + + return 1; +} + +extern int pps_crm_get_sms_notification_for_event_flag(); +extern void pps_send_last_call_info(_account_info *user_ptr, int call_type, int charge, int duration); +void SendCDR(int proc_id) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + _tocdr_report *pcdr,cdrreport; + char buf[BUFSIZE]={""}; + int len=0; + int duration=0, balance,charge; + + PutLogFunID("SendCDR"); + + shmp += proc_id; + + UpdateAccountLastCDR(shmp); + + pcdr = &cdrreport; + + duration = ceil( (double) shmp->process_info.duration / + CYCLE_STATE_INTERVAL); + + AsciiTime(buf, shmp->cdr_info.seizuretime); + AsciiToBcd(pcdr->seizuretime,buf,14); + AsciiTime(buf, shmp->cdr_info.answertime); + AsciiToBcd(pcdr->answertime,buf,14); + + if(shmp->cdr_info.releasetime==0) + shmp->cdr_info.releasetime = shmp->cdr_info.answertime + duration; + + AsciiTime(buf, shmp->cdr_info.releasetime); + AsciiToBcd(pcdr->releasetime,buf,14); + + memcpy(pcdr->duration,&duration,4); + if(shmp->caller_info.charge<0) + charge = (int) shmp->caller_info.charge; + else + charge = (int)(shmp->caller_info.charge+0.5);// ceil ==> int + + switch(shmp->process_info.call_type) + { + case CT_SERVICE: + case CT_LOCAL_CALL_OUT: + case CT_TRUNK_CALL_OUT: + case CT_NDD_CALL_OUT: + case CT_IDD_CALL_OUT: + case CT_MO_SM: + case CT_MF_CALL: + case CT_CONFERENCE_CALL: + case CT_THIRD_PARTY_CHARGE: + case CT_BUNDLE_PLAN_CHARGE: + if(shmp->caller_info.charge > 0) + { + if(shmp->process_info.call_type == CT_MO_SM) + increPoolChildSMS(&shmp->caller_info); + else + { + increPoolChildCalls(&shmp->caller_info); + } + } + pcdr->mtype = MO_CDR_TYPE; + + pcdr->type[0] = shmp->process_info.call_type; + pcdr->type[1] = 0; + + memcpy(pcdr->charge, &charge,4); // + balance = ceil (GetBalance(&shmp->caller_info)) ; + + memcpy(pcdr->balance,&balance,4); + memcpy(pcdr->imsi,shmp->caller_info.IMSI,8); + + pcdr->msisdn[0] = 0x91; + if(shmp->process_info.chargeOther) + memcpy(&pcdr->msisdn[1],shmp->cdr_info.msisdn,8); + else + memcpy(&pcdr->msisdn[1],shmp->cdr_info.caller,8); + pcdr->caller[0] = 0x91; + memcpy(&pcdr->caller[1],shmp->cdr_info.caller,8); + pcdr->called[0] = 0x91; + memcpy(&pcdr->called[1],shmp->cdr_info.called,10); + + pcdr->tcos[0] = 0; // shmp->process_info.tcos>>8; + pcdr->tcos[1] = 0;//shmp->process_info.tcos; + if (shmp->process_info.call_type == CT_BUNDLE_PLAN_CHARGE) + { + pcdr->tcos[0] = shmp->process_info.tcos & 0xFF; + } + + pcdr->cos_id = GetAccountCosID(&shmp->caller_info); + + memcpy(pcdr->plan_id, &shmp->process_info.rest_if.plan_id, 4); + + if(OCS_with_external_CRM()) + { + if ((shmp->process_info.call_type != CT_BUNDLE_PLAN_CHARGE) + && (shmp->process_info.call_type != CT_SERVICE)) + { + strncpy(pcdr->peerAddress, shmp->process_info.ppsService.areaName, 31); + } + } + CDRStatistics(pcdr,shmp->caller_info.charge, 0); + StoreCDR(pcdr); + + CheckPromotionLatchFlag(&shmp->caller_info); + pps_real_update_user_file(shmp->caller_info.head, shmp->caller_info.tail); + +#if DEBUG + if( logMsgFlag & 0x04 || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"[%05d] Send MO CDR, type = %d", proc_id, shmp->process_info.call_type); + } +#endif + break; + case CT_LOCAL_CALL_IN: + case CT_TRUNK_CALL_IN: + case CT_IDD_CALL_IN: + case CT_MT_SM: + pcdr->mtype = MT_CDR_TYPE; + pcdr->type[0] = shmp->process_info.call_type; + pcdr->type[1] = 0; + + charge = (int)(shmp->called_info.charge+0.5);// ceil ==> int + memcpy(pcdr->charge, &charge,4); /* called_info.charge */ + balance = ceil(GetBalance(&shmp->called_info) ); /* called_info */ + memcpy(pcdr->balance,&balance,4); + memcpy(pcdr->imsi,shmp->called_info.IMSI,8); + + pcdr->msisdn[0] = 0x91; + /* maybe fault, if realnumber=81xxxx ?? */ + memcpy(&pcdr->msisdn[1],shmp->cdr_info.caller,8); + pcdr->caller[0] = 0x91; + memcpy(&pcdr->caller[1],shmp->cdr_info.caller,8); + pcdr->called[0] = 0x91; + len = strlen((char *)shmp->called_info.number)%20; + ppsAsciiToBcdR(&pcdr->called[1], (char *)shmp->called_info.number, (len+1)/2*2); + if(len %2) + { + pcdr->called[(len+1)/2] |= 0xF0; + } + if(len<21) + { + pcdr->called[(len+1)/2+1] = 0xFF; + } + + pcdr->tcos[0] = 0; + pcdr->cos_id = GetAccountCosID(&shmp->called_info); + memcpy(pcdr->plan_id, &shmp->process_info.rest_if.plan_id, 4); + + if(OCS_with_external_CRM()) + { + strncpy(pcdr->peerAddress, shmp->process_info.ppsService.areaName, 31); + } + CDRStatistics(pcdr,shmp->called_info.charge, 0); + StoreCDR(pcdr); + CheckPromotionLatchFlag(&shmp->called_info); + pps_real_update_user_file(shmp->called_info.head, shmp->called_info.tail); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if( logMsgFlag & 0x04 || shmp->process_info.logMsisdn){ + DebugMsg(debugmib.display.asciiOut,"[%05d] Send MT CDR, type = %d", proc_id, shmp->process_info.call_type); + debug_messages ++; + } +#endif + break; + case CT_MO_CC_CALL: + + pcdr->mtype = MO_CDR_TYPE; + + pcdr->type[0] = shmp->process_info.call_type; + pcdr->type[1] = 0; + + memcpy(pcdr->charge, &charge,4); // + balance = (int) (ocs_get_calling_card_left_balance(shmp->card_info.cardhead, shmp->card_info.cardtail)+0.5) ; + + memcpy(pcdr->balance,&balance,4); + memcpy(pcdr->imsi,shmp->caller_info.IMSI,8); + + pcdr->msisdn[0] = 0x91; + memcpy(&pcdr->msisdn[1],shmp->cdr_info.caller,8); + pcdr->caller[0] = 0x91; + memcpy(&pcdr->caller[1],shmp->cdr_info.caller,8); + pcdr->called[0] = 0x91; + memcpy(&pcdr->called[1],shmp->cdr_info.called,10); + + pcdr->tcos[0] = 0; // shmp->process_info.tcos>>8; + pcdr->tcos[1] = 0;//shmp->process_info.tcos; + + pcdr->cos_id = ocs_get_calling_card_cos_id(); + + CDRStatistics(pcdr,shmp->caller_info.charge, 0); + StoreCDR(pcdr); + +#if DEBUG + if( logMsgFlag & 0x04 || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"[%05d] Send MO CC CDR, type = %d", proc_id, shmp->process_info.call_type); + } +#endif + break; + } + + if(OCS_with_external_CRM()) + { + if(charge>0 && pps_crm_get_sms_notification_for_event_flag()) + { + pps_send_last_call_info(&shmp->caller_info, shmp->process_info.call_type, charge, duration); + } + } +} + + +void SendAccountRealSync(DWORD instance, double balance, double promotion, int ocode) +{ + _prepaid_data *ptr = &ramshm_ptr->prepaid_data; + int head=0, tail=0; + + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + PutLogFunID("SendAccountRealSync"); + + if(instance>=UNIT_STORE_ACCOUNT*MSISDN_HEAD_NUM) + return ; + if(ocode>=MAX_OMC_OCODE || ocodeoidlen = 16 + 1; + varlist->vartype = 0x04; + + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x02; /* configuration */ + varlist->oid[12] = 0x02; /* database */ + varlist->oid[13] = 0x02; /* account_db */ + varlist->oid[14] = 0x01; /* user_info */ + + head = (int) (instance / UNIT_STORE_ACCOUNT); + tail = instance % UNIT_STORE_ACCOUNT; + if(ptr->prepaid_info[head][tail].msisdn[9] < MIN_MSISDN_ALEN || + ptr->prepaid_info[head][tail].msisdn[9]>MAX_MSISDN_ALEN) + { + debugmib.watch_dog[48]++; + return ; /* length error */ + } + + varlist->oid[15] = instance; + varlist->oid[16] = ocode; /* update */ + varlist->msglen = sizeof(_prepaid_info)+sizeof(double)*2; + memcpy(varlist->msg, (u_char *) &ptr->prepaid_info[head][tail], sizeof(_prepaid_info)); + memcpy(&varlist->msg[sizeof(_prepaid_info)],&balance,sizeof(double)); + memcpy(&varlist->msg[sizeof(_prepaid_info)+sizeof(double)],&promotion,sizeof(double)); + + if(peer_server_ip != 0x100007f) + { + if (realSyncTcpSend(PPS_USER_DATA_DB_OID, instance, ocode, varlist->msg, varlist->msglen) < 0) + { + snmp_send(&snmpbuf,&snmpaddr); + } + } + + if(ocode == 4) + { + snmpaddr.remote_ip = LOCAL_IP; + snmp_send(&snmpbuf,&snmpaddr); + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + { + //char buf[BUFSIZE]={""}, bufwork[BUFSIZE]; + //int loop; + + debug_messages ++; + if(logMsgFlag == 0x40) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"SendAccountRealSync (%08X,%d), instance:%d", + peer_server_ip,PPS_REALSYNC_PORT,instance); + } + } +#endif +} + +void SendAccountRealSync_2(_account_info *accountInfo,double balance,double promotion ,int ocode) +{ + DWORD instance; + + instance = accountInfo->head * UNIT_STORE_ACCOUNT + accountInfo->tail; + SendAccountRealSync(instance,balance,promotion,ocode); +} + +static _pps_heartbeat hb_default = +{ + 0x00, //system id + 0x00, //subsystem id + {0x00,0x00,0x00,0x00}, //timestamp + {0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //led + 0x00,{0x00,0x00}, //alarm + 0x00, //length, h + 0x1c, //length, l + 0x00,0x00, // component id + 0x00,0x18, //component len + {0x00,0x00,0x00}, //version + 0x00, //state + {0x00,0x00,0x00,0x00}, //check sum + {0x00,0x00,0x00,0x00}, //licensed user + {0x00,0x00,0x00,0x01}, //real user + {0x00,0x00,0x00,0x00}, //serial number + {0x00,0x00,0x00,0x01}, //system capability +}; + +int +ppsSendHeartBeating() +{ + u_long nowSeconds; + _pps_heartbeat ppsHeartBeat; + + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; +// struct timeval tm; +// gettimeofday(&tm,NULL); +// DebugMsg(debugmib.display.asciiOut,"Now send PPS hb: %ld",tm.tv_sec); + PutLogFunID("ppsSendHeartBeating"); + + snmpbuf.pdu_type = 0x07; //trap + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; +// snmpaddr.local_ip = GetLocalIP(); + snmpaddr.remote_port = HEART_BEATING_PORT; + snmpaddr.local_port = HEART_BEATING_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 12; + varlist->vartype = 0x04; + + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x01; /* configuration */ + varlist->msglen = sizeof(_pps_heartbeat); + memcpy(&ppsHeartBeat,&hb_default,sizeof(_pps_heartbeat)); + nowSeconds = tvnow.tv_sec; + + memcpy(ppsHeartBeat.timeStamp ,&nowSeconds,4); + ppsHeartBeat.systemID = subSystemID; + ppsHeartBeat.subSystemID = 0x00; + /* allways be 0x00 for function server subSystemID; */ + memcpy(ppsHeartBeat.alarm,alarm_code,2); + if(alarm_code[0] !=0 || alarm_code[1] !=0){ + ppsHeartBeat.ledStatus[0]=0x29; + } + + //ppsHeartBeat.reserved0 = debugmib.display.initProgress; + ppsHeartBeat.reserved0 = 0; + memcpy(ppsHeartBeat.version,version_id,3); + ppsHeartBeat.status = debugmib.display.sysState; + memcpy(&ppsHeartBeat.sumOfParameter,&sumOfParameter,1); + ppsHeartBeat.systemCapability[0] = systemCapability>>24; + ppsHeartBeat.systemCapability[1] = systemCapability>>16; + ppsHeartBeat.systemCapability[2] = systemCapability>>8; + ppsHeartBeat.systemCapability[3] = systemCapability; + ppsHeartBeat.licensedUser[0]= ppsParam.serviceControl.licenseduser>>24; + ppsHeartBeat.licensedUser[1]= ppsParam.serviceControl.licenseduser>>16; + ppsHeartBeat.licensedUser[2]= ppsParam.serviceControl.licenseduser>>8; + ppsHeartBeat.licensedUser[3]= ppsParam.serviceControl.licenseduser; + ppsHeartBeat.realUserNumber[0] = debugmib.measurement.usernumber>>24; + ppsHeartBeat.realUserNumber[1] = debugmib.measurement.usernumber>>16; + ppsHeartBeat.realUserNumber[2] = debugmib.measurement.usernumber>>8; + ppsHeartBeat.realUserNumber[3] = debugmib.measurement.usernumber; + AsciiToBcd(ppsHeartBeat.serialNumber,serialNumber,8); + memcpy(varlist->msg, (u_char *)&ppsHeartBeat, + sizeof(_pps_heartbeat)); + if(peer_server_ip != 0x100007f) + snmp_send(&snmpbuf,&snmpaddr); + + //primary_data_server = inet_addr("172.18.128.1"); + // if(primary_data_server) + { + snmpaddr.remote_ip = primary_data_server; + if(snmp_send(&snmpbuf,&snmpaddr)==0) + { + DebugMsg(debugmib.display.asciiOut, + "PPS send hb to OMC0 fialed!"); + } + } + //second_data_server = inet_addr("172.18.129.1"); + if(second_data_server) + { + snmpaddr.remote_ip = second_data_server; + if(snmp_send(&snmpbuf,&snmpaddr)==0) + { + DebugMsg(debugmib.display.asciiOut, + "PPS send hb to OMC1 fialed!"); + } + } + alarm_code[0]=0;alarm_code[1] = 0; + return 1; +} + +void +SendPeriodicChargeCDR( int head, int tail, int charge, int rent_type) +{ + _tocdr_report pcdr; + char buf[BUFSIZE]; + int balance; + + PutLogFunID("SendPeriodicChargeCDR"); + + memset(&pcdr,0, sizeof(_tocdr_report)); + pcdr.mtype = MO_CDR_TYPE; + pcdr.type[0] = rent_type; + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + memcpy(pcdr.charge,&charge, 4); + + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance, &balance, 4); + + GetAccountMsisdn(head,tail,&pcdr.msisdn[1]); + ByteRev(pcdr.msisdn,9,0); + pcdr.msisdn[0]=0x91; + memcpy(pcdr.caller,pcdr.msisdn,9); + buf[0] = 0; + sprintf(buf,"FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.called,buf,18); + AsciiToBcd(pcdr.imsi,buf,16); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + pcdr.tcos[1] = NORMAL_CLEARING>>8; + + CDRStatistics(&pcdr,charge, 0); + StoreCDR(&pcdr); + pps_real_update_user_file(head, tail); + +#if DEBUG + if(debug_messages++<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut,"SendPeriodicChargeCDR:%d",charge); +#endif +} + +void +SendRechargeCDR(int proc_id, int type, int charge) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + _tocdr_report pcdr; + + char buf[BUFSIZE]={""}; + int balance; + + + PutLogFunID("SendRechargeCDR"); + + shmp += proc_id; + memset(&pcdr, 0x00, sizeof(_tocdr_report)); + + pcdr.mtype = MO_CDR_TYPE; + pcdr.type[0] = type; + pcdr.type[1] = type>>8; + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + pcdr.charge[0] = charge; + pcdr.charge[1] = charge>>8; + pcdr.charge[2] = charge>>16; + pcdr.charge[3] = charge>>24; + + balance = GetAccountBalance(shmp->caller_info.head, + shmp->caller_info.tail); + pcdr.balance[0] = balance; + pcdr.balance[1] = balance>>8; + pcdr.balance[2] = balance>>16; + pcdr.balance[3] = balance>>24; + + pcdr.msisdn[0] = 0x91; + memset(pcdr.imsi,0xFF,8); + if(shmp->process_info.rechargeByOther) + { + memcpy(&pcdr.msisdn[1],shmp->cdr_info.msisdn,8); + //memset(pcdr.imsi,0xFF,8); + } + else + { + memcpy(&pcdr.msisdn[1],shmp->cdr_info.caller,8); + //memcpy(pcdr.imsi,shmp->caller_info.IMSI,8); + } + pcdr.caller[0] = 0x91; + memcpy(&pcdr.caller[1],shmp->cdr_info.caller,8); + pcdr.called[0] = 0x91; + memcpy(&pcdr.called[1],shmp->cdr_info.called,10); + if(shmp->cdr_info.caller[1] == 0 ) + { + debugmib.watch_dog[0] ++; + debugmib.watch_dog[1] = proc_id; + debugmib.watch_dog[2] = proc_id>>2; + return; + } + //if(shmp->cdr_info.called[1] == 0) return; + //pcdr.tcos[0] = NORMAL_CLEARING%256; + pcdr.tcos[0] = shmp->process_info.rechargeByOther; + + StoreCDR(&pcdr); + + CDRStatistics(&pcdr,charge, 0); + if(UseExternalVC() && type == CT_RECHARGE_SUCCESS) + { + CountUsedCardForDailyReport(charge); + } + pps_real_update_user_file(shmp->caller_info.head, shmp->caller_info.tail); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut,"SendRechargeCDR"); + debug_messages ++; + } +#endif +} + +void SendSelfcareRechargeCDR(_account_info *user_info, char *pwd, int type, int charge) +{ + _tocdr_report pcdr; + char buf[64]={""}; + u_char bcd_buf[12] = {0}; + int balance; + + PutLogFunID("SendSelfcareRechargeCDR"); + + memset(&pcdr, 0x00, sizeof(_tocdr_report)); + + pcdr.mtype = SC_CDR_TYPE; + pcdr.type[0] = type; + pcdr.type[1] = type>>8; + + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + memcpy(pcdr.answertime, pcdr.seizuretime, 9); + memcpy(pcdr.releasetime, pcdr.seizuretime, 9); + + pcdr.duration[0] = 0; + pcdr.charge[0] = charge; + pcdr.charge[1] = charge>>8; + pcdr.charge[2] = charge>>16; + pcdr.charge[3] = charge>>24; + + balance = (int)(GetAccountBalance(user_info->head, user_info->tail) + 0.5); + pcdr.balance[0] = balance; + pcdr.balance[1] = balance>>8; + pcdr.balance[2] = balance>>16; + pcdr.balance[3] = balance>>24; + + memset(pcdr.imsi, 0xFF, 8); + + sprintf(buf, "%sE", user_info->number); + int len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(bcd_buf, buf, len); + pcdr.msisdn[0] = 0x91; + memcpy(&pcdr.msisdn[1], bcd_buf, 8); + + memcpy(pcdr.caller, pcdr.msisdn, 9); + + if (CT_ASSISTED_UP == type) + { + sprintf(buf,"FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.called, buf, 18); + } + else + { + // called num, recharge card num + sprintf(buf, "%sE", pwd); + len = (strlen(buf)+1)/2 * 2; + if (len > 18) + { + len = 18; + } + ppsAsciiToBcdR(bcd_buf, buf, len); + pcdr.called[0] = 0x91; + memcpy(&pcdr.called[1], bcd_buf, 8); + } + + StoreCDR(&pcdr); + + CDRStatistics(&pcdr,charge, 0); + if(UseExternalVC() && type == CT_RECHARGE_SUCCESS) + { + CountUsedCardForDailyReport(charge); + } + pps_real_update_user_file(user_info->head, user_info->tail); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut,"SendSelfcareRechargeCDR"); + debug_messages ++; + } +#endif +} + +void SendSelfcareBundleSubCDR(_account_info *user_info, int charge, u32 data_volume, u32 voice_sec) +{ + _tocdr_report pcdr; + char buf[32]={""}; + u_char bcd_buf[12] = {0}; + int balance; + + PutLogFunID("SendSelfcareBundleSubCDR"); + + memset(&pcdr, 0x00, sizeof(_tocdr_report)); + + pcdr.mtype = SC_CDR_TYPE; + pcdr.type[0] = CT_BUNDLE_PLAN_CHARGE; + pcdr.type[1] = CT_BUNDLE_PLAN_CHARGE>>8; + + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + memcpy(pcdr.answertime, pcdr.seizuretime, 9); + memcpy(pcdr.releasetime, pcdr.seizuretime, 9); + + if (voice_sec > 0) + { + pcdr.tcos[0] = 0x01;// bundle plan + /* + pcdr.duration[0] = voice_sec; + pcdr.duration[1] = voice_sec>>8; + pcdr.duration[2] = voice_sec>>16; + pcdr.duration[3] = voice_sec>>24;*/ + } + + if (data_volume > 0) + { + pcdr.gprsVolume[0] = data_volume; + pcdr.gprsVolume[1] = data_volume>>8; + pcdr.gprsVolume[2] = data_volume>>16; + pcdr.gprsVolume[3] = data_volume>>24; + } + + pcdr.charge[0] = charge; + pcdr.charge[1] = charge>>8; + pcdr.charge[2] = charge>>16; + pcdr.charge[3] = charge>>24; + + balance = (int)(GetAccountBalance(user_info->head, user_info->tail) + 0.5); + pcdr.balance[0] = balance; + pcdr.balance[1] = balance>>8; + pcdr.balance[2] = balance>>16; + pcdr.balance[3] = balance>>24; + + memset(pcdr.imsi, 0xFF, 8); + + sprintf(buf, "%sE", user_info->number); + int len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(bcd_buf, buf, len); + pcdr.msisdn[0] = 0x91; + memcpy(&pcdr.msisdn[1], bcd_buf, 8); + memcpy(pcdr.caller, pcdr.msisdn, 9); + + sprintf(buf,"FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.called, buf, 18); + + StoreCDR(&pcdr); + + CDRStatistics(&pcdr, charge, 0); + pps_real_update_user_file(user_info->head, user_info->tail); +#if DEBUG + if(debug_messages <= MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, "SendSelfcareBundleSubCDR"); + debug_messages ++; + } +#endif +} + +void SendSelfcareTransferCDR(_account_info *caller_info,_account_info *called_info, float charge) +{ + _tocdr_report pcdr; + char buf[32] = {""}; + int fee, balance, len; + int head, tail; + u_char bcd_buf[12] = {0}; + + PutLogFunID("SendSelfcareTransferCDR"); + + head = caller_info->head; + tail = caller_info->tail; + + memset(&pcdr, 0, sizeof(_tocdr_report)); + pcdr.mtype = SC_CDR_TYPE; + if (charge > 0.0) + { + pcdr.type[0] = CT_TRANFER_IN; + pcdr.type[1] = CT_TRANFER_IN>>8; + } + else + { + pcdr.type[0] = CT_TRANFER_OUT; + pcdr.type[1] = CT_TRANFER_OUT>>8; + } + + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + memcpy(pcdr.answertime, pcdr.seizuretime, 9); + memcpy(pcdr.releasetime, pcdr.seizuretime, 9); + + pcdr.duration[0] = 0; + fee = (int)charge; + fee = abs(fee); + memcpy(pcdr.charge, &fee, 4); + balance = (int)(GetAccountBalance(head, tail) + 0.5); + memcpy(pcdr.balance, &balance, 4); + + sprintf(buf, "%sE", caller_info->number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(bcd_buf, buf, len); + pcdr.msisdn[0] = 0x91; + memcpy(&pcdr.msisdn[1], bcd_buf, 8); + + memcpy(pcdr.caller, pcdr.msisdn, 9); + + sprintf(buf, "%sE", called_info->number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(bcd_buf, buf, len); + pcdr.called[0] = 0x91; + memcpy(&pcdr.called[1], bcd_buf, 8); + + memset(pcdr.imsi, 0xFF, 8); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + CDRStatistics(&pcdr, charge, 0); + StoreCDR(&pcdr); + pps_real_update_user_file(head, tail); + +#if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut, "SendSelfcareTransferCDR"); +#endif +} + +void SendDirectDebitAndRefundCDR(_account_info *caller_info, float charge) +{ + _tocdr_report pcdr; + char buf[BUFSIZE] = {""}; + int fee, balance;//, len; + int head, tail; + + PutLogFunID("SendDirectDebitAndRefundCDR"); + + head = caller_info->head; + tail = caller_info->tail; + + memset(&pcdr, 0, sizeof(_tocdr_report)); + if (charge > 0) + { + pcdr.type[0] = CT_REFUND_ACCOUNT; + pcdr.type[1] = CT_REFUND_ACCOUNT>>8; + } + else if (charge < 0) + { + pcdr.type[0] = CT_DIRECT_DEBITING; + pcdr.type[1] = CT_DIRECT_DEBITING>>8; + } + else + { + return ; + } + + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + fee = (int)charge; + fee = abs(fee); + memcpy(pcdr.charge, &fee, 4); + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance, &balance, 4); + + GetAccountMsisdn(head, tail, &pcdr.msisdn[1]); + ByteRev(pcdr.msisdn, 9, 0); + + pcdr.msisdn[0] = 0x91; + memcpy(pcdr.caller, pcdr.msisdn, 9); + buf[0] = 0; + + pcdr.called[0] = 0x91; + /*len = 0;*//* strlen(called_info->number)%20; + ppsAsciiToBcdR(&pcdr.called[1], called_info->number, (len+1)/2*2); + if(len %2) + { + pcdr.called[(len+1)/2] |= 0xF0; + } + if(len<21) + {*/ + //pcdr.called[(len+1)/2+1] = 0xFF; + pcdr.called[1] = 0xFF; + //} + + sprintf(buf, "FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.imsi, buf, 16); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + CDRStatistics(&pcdr, (int)charge, 0); + StoreCDR(&pcdr); + + pps_real_update_user_file(head, tail); + +#if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut, "SendDirectDebitAndRefundCDR"); +#endif +} + +void SendSmsDirectDebitAndRefundCDR(_state_data *shmp, int sent_num, int bIsRefund) +{ + _tocdr_report pcdr; + char buf[BUFSIZE] = {""}; + int fee, balance, len; + int head, tail; + _account_info *caller_info = &shmp->caller_info; + float charge = caller_info->charge; + + PutLogFunID("SendSmsDirectDebitAndRefundCDR"); + + head = caller_info->head; + tail = caller_info->tail; + + memset(&pcdr, 0, sizeof(_tocdr_report)); + if (bIsRefund) + { + pcdr.type[0] = CT_REFUND_ACCOUNT; + pcdr.type[1] = CT_REFUND_ACCOUNT>>8; + } + else + { + pcdr.type[0] = CT_MO_SM; + pcdr.type[1] = CT_MO_SM>>8; + } + + increPoolChildSMS(&shmp->caller_info); + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + fee = (int)charge; + fee = abs(fee); + memcpy(pcdr.charge, &fee, 4); + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance, &balance, 4); + + GetAccountMsisdn(head, tail, &pcdr.msisdn[1]); + ByteRev(pcdr.msisdn, 9, 0); + + pcdr.msisdn[0] = 0x91; + memcpy(pcdr.caller, pcdr.msisdn, 9); + buf[0] = 0; + + len = strlen((char *)shmp->called_info.number); + AsciiToRbcd(&pcdr.called[1], (char *)shmp->called_info.number, len); + if (len & 0x01) + { + pcdr.called[1 + len/2] |= 0xF0; + } + else + { + pcdr.called[1 + len/2] = 0xFF; + } + pcdr.called[0] = 0x91; + + sprintf(buf, "FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.imsi, buf, 16); + + pcdr.cos_id = GetAccountCosID(&shmp->caller_info); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + CDRStatistics(&pcdr, (int)charge, 0); + StoreCDR(&pcdr); + + CheckPromotionLatchFlag(&shmp->caller_info); + pps_real_update_user_file(shmp->caller_info.head, shmp->caller_info.tail); + +#if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut, "SendDirectDebitAndRefundCDR"); +#endif +} + +void +SendOperatorRechargeCDR(int head, int tail, int charge) +{ + _tocdr_report pcdr; + char buf[BUFSIZE]={""}; + int balance; + + PutLogFunID("SendOperatorRechargeCDR"); + + memset(&pcdr, 0, sizeof(_tocdr_report)); + if (charge >= 0) + { + pcdr.type[0] = CT_ASSISTED_UP; + pcdr.type[1] = CT_ASSISTED_UP>>8; + } + else + { + pcdr.type[0] = CT_ASSISTED_DOWN; + pcdr.type[1] = CT_ASSISTED_DOWN>>8; + } + + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + charge = abs(charge); + memcpy(pcdr.charge,&charge,4); + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance,&balance,4); + + GetAccountMsisdn(head,tail,&pcdr.msisdn[1]); + ByteRev(pcdr.msisdn,9,0); + + pcdr.msisdn[0]=0x91; + memcpy(pcdr.caller,pcdr.msisdn,9); + buf[0] = 0; + sprintf(buf,"FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.called,buf,18); + AsciiToBcd(pcdr.imsi,buf,16); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + CDRStatistics(&pcdr,charge, 0); + StoreCDR(&pcdr); + + pps_real_update_user_file(head, tail); + +#if DEBUG + if(debug_messages++<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut, "SendOperatorRechargeCDR"); +#endif +} + + +void SendManualRechargeCDR(_recharge_card_info *shmp) +{ + _tocdr_report pcdr; + + char buf[BUFSIZE]={""}, + msisdn[32]=""; + int balance,head,tail,instance,len; + int charge; + + PutLogFunID("SendManualRechargeCDR"); + + memset(&pcdr, 0, sizeof(_tocdr_report)); + + strcpy(msisdn,shmp->msisdn_used); + len = strlen(msisdn); + if(len>MAX_MSISDN_ALEN || lenmsisdn_used,len); + + return; + } + instance = FindPPSTableIndex(atoll(msisdn)); + if(instance<0) + { + DebugMsg(debugmib.display.asciiOut, + "SendManualRechargeCDR to %s failed: not exist", + shmp->msisdn_used); + return; + } + head = instance / UNIT_STORE_ACCOUNT; + tail = instance % UNIT_STORE_ACCOUNT; + + pcdr.mtype = MO_CDR_TYPE; + pcdr.type[0] = CT_RECHARGE_SUCCESS; + pcdr.type[1] = CT_RECHARGE_SUCCESS>>8; + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + + charge = (int)shmp->face_value; + pcdr.charge[0] = charge; + pcdr.charge[1] = charge>>8; + pcdr.charge[2] = charge>>16; + pcdr.charge[3] = charge>>24; + UpdateAccountBalance(head, tail,charge); + UpdateAccountStatus(head, tail,T_NORMAL); + UpdateAccountExpiration(head,tail,shmp->face_value,shmp->valid_time); + + balance = GetAccountBalance(head, tail); + pcdr.balance[0] = balance; + pcdr.balance[1] = balance>>8; + pcdr.balance[2] = balance>>16; + pcdr.balance[3] = balance>>24; + len = strlen(msisdn); + if(len%2==1) + { + msisdn[len]='F'; + len ++; + } + + memset(pcdr.imsi,0xFF,8); + pcdr.msisdn[0] = 0x91; + ppsAsciiToBcdR(&pcdr.msisdn[1],msisdn,len); + pcdr.msisdn[1+len/2]=0xFF; + memcpy(pcdr.caller,pcdr.msisdn,2+len/2); + + len = shmp->card_no[MAX_CARD_LENGTH]; + BcdToAscii(buf,shmp->card_no,len*2); + + pcdr.called[0] = 0x91; + ppsAsciiToBcdR(&pcdr.called[1],buf,len); + pcdr.called[1+len/2] = 0xFF; + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + StoreCDR(&pcdr); + + CDRStatistics(&pcdr,charge, 0); + + pps_real_update_user_file(head, tail); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut,"SendManualRechargeCDR to %s",shmp->msisdn_used); + debug_messages ++; + } +#endif + +} + + +void +SendPPSGeneralCDR(int head, int tail, int charge, char cdr_type) +{ + _tocdr_report pcdr; + char buf[BUFSIZE]={""}; + int balance; + + PutLogFunID("SendPPSGeneralCDR"); + + memset(&pcdr, 0, sizeof(_tocdr_report)); + + pcdr.type[0] = cdr_type; + pcdr.type[1] = cdr_type>>8; + + AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14); + AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14); + pcdr.duration[0] = 0; + charge = abs(charge); + memcpy(pcdr.charge,&charge,4); + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance,&balance,4); + + GetAccountMsisdn(head,tail,&pcdr.msisdn[1]); + ByteRev(pcdr.msisdn,9,0); + + pcdr.msisdn[0]=0x91; + memcpy(pcdr.caller,pcdr.msisdn,9); + buf[0] = 0; + sprintf(buf,"FFFFFFFFFFFFFFFFFF"); + AsciiToBcd(pcdr.called,buf,18); + AsciiToBcd(pcdr.imsi,buf,16); + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + CDRStatistics(&pcdr,charge, 0); + StoreCDR(&pcdr); + + pps_real_update_user_file(head, tail); + +#if DEBUG + if(debug_messages++<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + DebugMsg(debugmib.display.asciiOut, "SendPPSGeneralCDR"); +#endif +} + +void SendAccountInfoForLowCredit(char *caller, + long balance,long expired_date, + long promo,long promo_expired_date) +{ + char expire_date[64]; + char promo_expire_date[64]; + char serviceNumber[BUFSIZE]=""; + + PutLogFunID("SendAccountInfoForLowCredit"); + + strcpy(serviceNumber, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number); + + AsciiTime(expire_date,expired_date); + AsciiTime(promo_expire_date, promo_expired_date); + smppSendAccountInfo(caller, + serviceNumber, + balance, + expire_date, + promo, + promo_expire_date, + 0,"","",0); + AddPPSStatistics(MIBPPS_ACCOUNTINFO,0); +} + +void SendAccountInfoBySMPP(_account_info *ptr,char *called) +{ + long balance,promotion, expired_date,promo_expired_date; + _last_call_info callInfo; + int len; + char msisdn[32]; + + char expire_date[64],promotion_expire_date[64]={0}; + char expire_date1[64]; + + PutLogFunID("SendAccountInfoBySMPP"); + + balance = (int)GetBalanceWithOutPromotion(ptr->head,ptr->tail); + promotion = (int)GetPromotion(ptr); + expired_date = GetExpiration(ptr); + promo_expired_date = GetPromotionExpiration(ptr); + AsciiTime(expire_date,expired_date); + AsciiTime(promotion_expire_date,promo_expired_date); + + if(GetAccountLastCallInfo(ptr,&callInfo)) + { + + AsciiTime(expire_date1,callInfo.last_call_date); + len = callInfo.last_call_number[MAX_MSISDN_BLEN-1]; + ppsBcdToAsciiR(msisdn,callInfo.last_call_number,18); + msisdn[len] = 0; + + smppSendAccountInfo((char *)ptr->number, + called, + balance, + expire_date, + promotion, + promotion_expire_date, + callInfo.last_call_type+1, + expire_date1, + msisdn, + ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail].language_type); + } + else + smppSendAccountInfo((char *)ptr->number, + called, + balance, + expire_date, + promotion, + promotion_expire_date, + 0, + "", + "", + ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail].language_type); + AddPPSStatistics(MIBPPS_ACCOUNTINFO,0); +} + +void pps_send_last_call_info(_account_info *user_ptr, int call_type, int charge, int duration) +{ + char sms_content[256]; +// char to_be_replace_str[16][32]={"[Charge]","[Charged Units]","[ACCOUNT BALANCE]","[EXPIRY DATE]"}; + char to_be_replace_str[16][32]={"$C","$D","$B","$E"}; + char charge_str[32],duration_str[32],balance_str[32],expire_str[32]; + int balance; + long expired_day; + + //SendAccountInfoBySMPP(ptr, ppsParam.ppsTables.serviceNumber[HotLineNumberPosition].number); + + if(call_type == CT_MO_SM ) + strcpy(sms_content, (char *)getSmsSentenceNative(0,SMS_LAST_SMS_INFO)); + else + strcpy(sms_content, (char *)getSmsSentenceNative(0,SMS_LAST_CALL_INFO)); + + balance = GetAccountBalance(user_ptr->head, user_ptr->tail); + expired_day = GetExpiration(user_ptr); + AsciiTimeYMDHMS(expire_str,expired_day); + + sprintf(charge_str, "%.2f", charge/100.00); + sprintf(duration_str, "%d", duration); + sprintf(balance_str, "%.2f", balance/100.00); + + ReplaceStr(sms_content, to_be_replace_str[0], charge_str); + ReplaceStr(sms_content, to_be_replace_str[1], duration_str); + ReplaceStr(sms_content, to_be_replace_str[2], balance_str); + ReplaceStr(sms_content, to_be_replace_str[3], expire_str); + + smppSendMOSM((char *)user_ptr->number, + (char *)ppsParam.ppsTables.serviceNumber[HotLineNumberPosition].number, + (u_char *)sms_content, strlen(sms_content), 0); + +} + +void SendAccountInfoBySMPPtoThirdParty(_account_info *ptr,char *called, char *third_party_number) +{ + long balance,promotion, expired_date,promo_expired_date; + //_last_call_info callInfo; + //int len; + //char msisdn[32]; + char caller[32]; + + char expire_date[64],promotion_expire_date[64]={0}; + //char expire_date1[64]; + + PutLogFunID("SendAccountInfoBySMPP"); + + balance = (int)GetBalanceWithOutPromotion(ptr->head,ptr->tail); + promotion = (int)GetPromotion(ptr); + expired_date = GetExpiration(ptr); + promo_expired_date = GetPromotionExpiration(ptr); + AsciiTime(expire_date,expired_date); + AsciiTime(promotion_expire_date,promo_expired_date); + + if(third_party_number != NULL) + strcpy(caller, third_party_number); + else + strcpy(caller, (char *)ptr->number); + /* + if(GetAccountLastCallInfo(ptr,&callInfo)) + { + AsciiTime(expire_date1,callInfo.last_call_date); + len = callInfo.last_call_number[MAX_MSISDN_BLEN-1]; + ppsBcdToAsciiR(msisdn,callInfo.last_call_number,18); + msisdn[len] = 0; + smppSendAccountInfo(caller, + called, + balance, + expire_date, + promotion, + promotion_expire_date, + callInfo.last_call_type+1, + expire_date1, + msisdn, + (0x40 | ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail].language_type)); + } + else + */ + smppSendAccountInfo(caller, + called, + balance, + expire_date, + promotion, + promotion_expire_date, + 0, + "", + (char *)ptr->number, + (0x40 | ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail].language_type)); + AddPPSStatistics(MIBPPS_ACCOUNTINFO,0); + +} + + char notificationSMS[256]=""; + +char *sendPPSNotificationMessage(int head, int tail, int sms_id) +{ + char buf[32], configuredSMS[256]; + char caller_number[32], called_number[32]; + int i,counter; + float currency_rate = 100.0; + char *buf_ptr[8],tmp_buf[8][32]; + int cos_id, plan_id, tariff_id, rent_id; + unsigned char bValue=0x01; + _prepaid_info *shmp=NULL; + + if(!GetAccountMsisdnStr(head, tail, (u_char *)caller_number)) + return 0; + strcpy(called_number, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].number); + + sprintf(configuredSMS,"%s ", getSmsSentenceNative(0,sms_id)); + + for(i=0;i<8;i++) + buf_ptr[i] = tmp_buf[i]; + + switch(ppsParam.ppsTables.promptResolution[0].currencyResolution) + { + case 0: + currency_rate = 1.0; + break; + case 1: + currency_rate = 10.0; + break; + case 2: + default: + currency_rate = 100.0; + break; + } + + switch(sms_id) + { + case SMS_RENT_CHARGE: + strcpy(called_number, (char *)ppsParam.ppsTables.serviceNumber[HotLineNumberPosition].number); + if(1) + { + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + cos_id = shmp->cos_id; + tariff_id = ppsParam.ppsTables.cosTable[cos_id].tariff[0].moTariffID; + rent_id = shmp->rent_type; + + for(i=0;itariff_data.rent_tariff[tariff_id][i].description); + sprintf(tmp_buf[1], "%.2f", ramshm_ptr->tariff_data.rent_tariff[tariff_id][i].rent_amount/currency_rate); + sprintf(notificationSMS, "%s",ppsParseSentence(configuredSMS, 2, buf_ptr)); + smppSendMOSM(caller_number, + called_number, + (u_char *)notificationSMS, + strlen(notificationSMS), 0); + } + } + } + + break; + case SMS_FRIEND_FAMILY_REG: + if(1) + { + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + cos_id = shmp->cos_id; + plan_id = shmp->favorite_plan_id - 1; + tariff_id = ppsParam.ppsTables.cosTable[cos_id].tariff[0].moTariffID; + rent_id = ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0].friendFamilyPlan[plan_id].rentID - 1; + + sprintf(tmp_buf[0], "%.2f", ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0].friendFamilyPlan[plan_id].rentCharge/currency_rate); + sprintf(tmp_buf[1], "%.2f", ramshm_ptr->tariff_data.rent_tariff[tariff_id][rent_id].rent_amount/currency_rate); + if( ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0].friendFamilyPlan[plan_id].freeCallDuration>0) + sprintf(tmp_buf[2], "%d", ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0].friendFamilyPlan[plan_id].freeCallDuration); + else + sprintf(tmp_buf[2], "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NO_LIMIT)); + if(ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0].friendFamilyPlan[plan_id].freeSMS>0) + sprintf(tmp_buf[3], "%d", ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0].friendFamilyPlan[plan_id].freeSMS); + else + sprintf(tmp_buf[3], "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NO_LIMIT)); + } + sprintf(notificationSMS, "%s",ppsParseSentence(configuredSMS, 4, buf_ptr)); + break; + case SMS_FRIEND_FAMILY_REG_FAILED: + strcpy(notificationSMS, configuredSMS); + break; + case SMS_FRIEND_FAMILY_SERVICE_SUSPEND: + strcpy(notificationSMS, configuredSMS); + break; + case SMS_FRIEND_FAMILY_PLAN_EXHAUST: + strcpy(notificationSMS, configuredSMS); + break; + case SMS_FRIEND_FAMILY_QUERY: + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + sprintf(tmp_buf[0], "%d", shmp->favorite_numbers); + counter = 1; + for(i=0;ifavorite_number[i][MAX_MSISDN_BLEN-1]>3) + { + sprintf(tmp_buf[counter], "#%d: ", i); + MsisdnToAscii(buf, shmp->favorite_number[i]); + strcat(tmp_buf[counter++], buf); + } + } + sprintf(notificationSMS,"%s", ppsParseSentence((char *)getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NOT_PLAN), counter, buf_ptr)); + break; + case SMS_FRIEND_FAMILY_SERIVCE_REACTIVATE: + strcpy(notificationSMS, configuredSMS); + break; + case SMS_FRIEND_FAMILY_REMOVE: + strcpy(notificationSMS, configuredSMS); + break; + } + + if(sms_id != SMS_RENT_CHARGE) + smppSendMOSM(caller_number, + called_number, + (u_char *)notificationSMS, + strlen(notificationSMS), 0); + + return notificationSMS; +} + +int pps_get_subid() +{ + return subSystemID; +} + +/*----------------------- supplementary functions -------------------*/ +extern pthread_mutex_t pps_mtx; +int AssignProcID(int gy_flag) +{ + static u_short roIdlePort = 0;// Ro handle port [0, 2K) + static u_short gyIdlePort = MAX_RO_FSM_PROCESS;// Gy Handle port [2K, 10K) + _state_data *shmp = NULL; + int i, retPort = -1; + + PutLogFunID("AssignProcID"); + + pthread_mutex_lock( &pps_mtx );// mutex lock================= + if (gy_flag) + { + for (i=0; i= MAX_FSM_PROCESS) + { + gyIdlePort = MAX_RO_FSM_PROCESS;// the first handle port of Gy + } + + if(smshm_ptr->port_info[gyIdlePort].status == 0x00) + { + smshm_ptr->port_info[gyIdlePort].status = 0x01; + debugmib.display.proc_used ++; + debugmib.display.gy_used ++; + + shmp =(_state_data *)&smshm_ptr->state_data; + shmp += gyIdlePort; + + memset(shmp,0,sizeof(_state_data)); + + retPort = gyIdlePort; + break; + } + } + } + else + { + for (i=0; i= MAX_RO_FSM_PROCESS) + { + roIdlePort = 0; + } + + if(smshm_ptr->port_info[roIdlePort].status == 0x00) + { + smshm_ptr->port_info[roIdlePort].status = 0x01; + debugmib.display.proc_used ++; + debugmib.display.ro_used ++; + + shmp =(_state_data *)&smshm_ptr->state_data; + shmp += roIdlePort; + + memset(shmp,0,sizeof(_state_data)); + + retPort = roIdlePort; + break; + } + } + } + + pthread_mutex_unlock( &pps_mtx );// mutex unlock================= + + if (retPort >= 0) + { + return retPort; + } + + ListAllPortStatus(1); + return -1; +} + +int ReleasePortStatus(u_short invoke_id) +{ + pthread_mutex_lock( &pps_mtx );// mutex lock================= + if(invoke_idport_info[invoke_id].status == 0x01) + { + smshm_ptr->port_info[invoke_id].status = 0x00; + debugmib.display.proc_used --; + + if (invoke_id < MAX_RO_FSM_PROCESS) + { + debugmib.display.ro_used--; + } + else + { + debugmib.display.gy_used--; + } + } + else + { + smshm_ptr->port_info[invoke_id].status = 0x00; + debugmib.display.proc_begin[0]++; + } + } + if(debugmib.display.proc_used>=MAX_FSM_PROCESS) + debugmib.display.proc_used = 0; + pthread_mutex_unlock( &pps_mtx );// mutex unlock================= + + return 1; +} + +int ByteToAscii(char *ascii, BYTE *byte, int len) +{ + int i; + for(i=0;ifunc_log.funcID % MAX_LOG_FUNC; + + snprintf(smshm_ptr->func_log.func_name[ptr], 63, "%02d : %s", ptr, func_name); + smshm_ptr->func_log.funcID = (ptr+1)%(MAX_LOG_FUNC); + return 1; +} + + +int log_warning(char *warning, u_short portid) +{ + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + int dlgid; + + shmp += portid; + dlgid = shmp->context_info.dialogue_id; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x01)) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Warning: p[%04d].d[%04d] <%s>@<%ld.%06ld>", + portid,dlgid,warning,tvnow.tv_sec,tvnow.tv_usec); + } + + return 1; +} + +int log_recv_message(void *ptr, u_char *msg_name,u_short portid,u_char first_message) +{ + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + int dlgid; + + shmp += portid; + dlgid = shmp->context_info.dialogue_id; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + if(first_message) + DebugMsg(debugmib.display.asciiOut, + "p[%04d].d[%04d] --> cap message <%s>@<%ld.%06ld>", + portid,shmp->context_info.dialogue_id,msg_name,tvnow.tv_sec,tvnow.tv_usec); + else + DebugMsg(debugmib.display.asciiOut, + "p[%04d].d[%04d] --> cap message <%s>@<%ld.%06ld>", + portid,dlgid,msg_name,tvnow.tv_sec,tvnow.tv_usec); + ppsDebugCapMsg((CAP_Message *)ptr,0); + } + + return 1; +} + +int log_send_message(void *ptr, u_char *msg_name,u_short portid,u_char first_message) +{ + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + int dlgid; + + shmp += portid; + dlgid = shmp->context_info.dialogue_id; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + if(first_message) + DebugMsg(debugmib.display.asciiOut, + "p[%04d].d[%04d] <-- cap message <%s>@<%ld.%06ld>", + portid,shmp->context_info.dialogue_id,msg_name,tvnow.tv_sec,tvnow.tv_usec); + else + DebugMsg(debugmib.display.asciiOut, + "p[%04d].d[%04d] <-- cap message <%s>@<%ld.%06ld>", + portid,dlgid,msg_name,tvnow.tv_sec,tvnow.tv_usec); + ppsDebugCapMsg((CAP_Message *)ptr,0); + } + + return 1; +} diff --git a/mss/pps/src/main/mfunc.c b/mss/pps/src/main/mfunc.c new file mode 100644 index 0000000..3bb50ab --- /dev/null +++ b/mss/pps/src/main/mfunc.c @@ -0,0 +1,6430 @@ + +#include "../include/includes.h" +#include "../include/ramdata.h" +#include "../include/message.h" +#include "../include/ppsm.h" +#include "../include/crypt.h" +#include "../include/ppsoid.h" +#include "../include/cdrme.h" +#include "../include/param.h" +//#include "../include/mfunc.h" + +#include "../include/plat_inc.h" + +#include "../../../../plat/scf/src/include/scfmsg.h" +/*------------------------------------------------*/ + +extern _state_machine *smshm_ptr; +extern _tariff_private *blf_shmp; +extern _ram_data *ramshm_ptr; +extern _debug_info *debug_shmp; +extern int csta_now_instance,csta_old_instance; +extern int logMsgFlag; +extern struct timeval tvnow; +/*------------------------------------------------*/ +extern PPSParamStruct ppsParam; +/*------------------------------------------------*/ +extern int FindPPSSubsStoreIndex(); +extern int AccountLatchFlagCheck(); +extern int GetRechargeCardValidTime(); +extern int GetRechargeCardFaceValue(); +extern int IsPSTNMaitenance(); +extern int IsVMSDeposit(); +extern int IsCallingCardNumber(char *number); +//extern int des(); +extern void SendAccountRealSync_2(_account_info *accountInfo, double balance, double promotion, int ocode); +extern void increPoolChildCharged(_account_info *ptr,double charged); +extern void increPoolChildSMS(_account_info *ptr); +extern void increPoolChildCalls(_account_info *ptr); +extern BOOL isPromotionCanBeUsedAtThisPoint(_state_data *shmp); +extern float BillingFormula(_state_data *shmp,_bill_tariff *ptar,int startTime); +extern float TimeToCharge(_state_data *shmp,_bill_tariff *ptar, int duration,int begin_time, int init_bill); +extern double GetBalanceWithPromotionControl(_state_data *stateProc,_account_info *ptr); +extern float caculateMiniCharge(_state_data *shmp,_bill_tariff *ptar); +extern int preLeftTime(_state_data *shmp,float balance,_bill_tariff *ptar); +extern void PPSSendUserSMSNotification(int head, int tail,char *msgSend); +extern u_char getCurrentTier(_state_data *shmp,_bill_tariff *ptar); +extern void ChangeTariffToPoolCallTariff(_state_data *shmp,_bill_tariff *ptar); +extern float getCurrentFee(_state_data *shmp); +extern int isPoolChildReachSMSLimit(_state_data *shmp); +extern char *sendPPSNotificationMessage(int head, int tail, int sms_id); +extern u_char *getSmsSentenceNative(SMS_SENTENCE id,u8 languageType); +extern BYTE ChangeUserCategory(BYTE *msisdn,BYTE type); +extern int subscribe_bundle_plan_send_used_up_info(char *caller_number, SMS_SENTENCE id); +extern void pps_print_error(u_char logMsisdnFlag,const char *fmt, ...); +extern int reportGprsCDRIncrement(int duration, float charge, long gprsVolume); +float GetAccountBalance(int head, int tail); +int isPoolChildReachFeeLimit(_account_info *ptr); +/*------------------------------------------------*/ + +int GetMOTariffData(_state_data *shmp,_bill_tariff *ptar, char *call_no, int zone_id) +{ + int len=0,maxlen=0,msisdn_len; + int loop,index=-1; + _bill_tariff *ptr; + + PutLogFunID("GetMOTariffData"); + + msisdn_len = strlen(call_no); + if (zone_id >= MAX_ZONE_NUM || zone_id <0) zone_id = 0; + if(ppsParam.serviceControl.cos_group_flag)// only use one type of tariff table in specify system + {// search by tree in this kind of tariff table + if(zone_id>=MAX_ZONE_NUM_NEW) + { + DebugMsg(debugmib.display.asciiOut, "search prefix failed: zone id = %d, called_no=%s", + zone_id,call_no); + + return 0; + } + index = pps_get_charge_prefix(zone_id, call_no);// search tariff table by prefix of called number + + if(index>=0) + { + ptr = &blf_shmp->bill_tariff[index/BILLING_BASE_NUM][index%BILLING_BASE_NUM]; + memcpy(ptar,ptr,sizeof(_bill_tariff));// cpy content of tariff table + if(shmp != NULL)// save address of table + { + shmp->process_info.tariffMoReadOnly = &blf_shmp->bill_tariff[index/BILLING_BASE_NUM][index%BILLING_BASE_NUM]; + } + return 1; + } + else + return 0; + /* + for(loop0=0;loop0bill_tariff[zone_id][loop]; + len = strlen(ptr->bill_id); + if(len == 0) break; + if(len>maxlen && len<=msisdn_len) + { + if(!strncasecmp(call_no,ptr->bill_id,len)) + { + maxlen = len; + index = loop; + } + } + } + } + */ + } + else + {// for this kind of tariff table, has 16 sub items; each has 1024 records + for(loop=0;loopbill_tariff[zone_id][loop]; + len = strlen(ptr->bill_id); + if(len == 0) break; + if(len>maxlen && len<=msisdn_len) + { + if(!strncasecmp(call_no,ptr->bill_id,len)) + { + maxlen = len; + index = loop; + } + } + } + } + if(index>=0) + { + ptr = &blf_shmp->bill_tariff[zone_id][index]; + memcpy(ptar,ptr,sizeof(_bill_tariff)); + if(shmp != NULL) + { + shmp->process_info.tariffMoReadOnly = &blf_shmp->bill_tariff[zone_id][index]; + } + return 1; + } + return FALSE; +} + +int +IsNormalAccount(_account_info *ptr) +{ + if(ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + return TRUE; + } + return FALSE; +} + +int GetAccountFavoriteNumberCounter(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + if(ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + return shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers; + }else + { + return -1; + } +} + +int StoreAccountFavoriteNumber(_account_info *ptr,char *msisdn,int index) +{ + int i,len; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("StoreAccountFavoriteNumber"); + + if(index>0 && index<=MAX_FAVORITE_NUMBERS) + { + len = strlen(msisdn); + shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1][MAX_MSISDN_BLEN-1] = len; + if(len%2==1) + len ++; + AsciiToBcd(shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1],msisdn,len); + return index; + } + + if(ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + for(i=0;iprepaid_info[ptr->head][ptr->tail].favorite_number[i][MAX_MSISDN_BLEN-1]<3) + { + len = strlen(msisdn); + shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[i][MAX_MSISDN_BLEN-1] = len; + if(len%2==1) + len ++; + AsciiToBcd(shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[i],msisdn,len); + shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers++; + if(shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers>MAX_FAVORITE_NUMBERS) + shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers=MAX_FAVORITE_NUMBERS; + return (i+1); + } + } + return (i+1); + }else + { + return -1; + } +} + +int GetAccountFavoriteNumber(_account_info *ptr,char *msisdn,u_char index) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + int len; + + PutLogFunID("GetAccountFavoriteNumber"); + + if(index<=MAX_FAVORITE_NUMBERS && index>0) + { + len = shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1][MAX_MSISDN_BLEN-1]; + if(len<3 || len>16) + { + return 0; + } + memcpy(msisdn, + shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1], + MAX_MSISDN_BLEN); + return index; + } + return 0; +} + + +int +GetAccountPos(_account_info *ptr) +{ + int len=0,store_index; + char msisdn[32]; + + PutLogFunID("GetAccountPos"); + + + len = strlen((char *)ptr->number); + strcpy(msisdn, (char *)ptr->number); + + + if(lenMAX_MSISDN_ALEN) + { + ptr->head = MSISDN_HEAD_NUM + 1; + ptr->tail = UNIT_STORE_ACCOUNT + 1; + return FALSE; + } + + store_index = FindPPSSubsStoreIndex(atoll((char *)ptr->number)); + + if(store_index<0) + { + ptr->head = MSISDN_HEAD_NUM + 1; + ptr->tail = UNIT_STORE_ACCOUNT + 1; + return FALSE; + } + + ptr->head = store_index / UNIT_STORE_ACCOUNT; + ptr->tail = store_index % UNIT_STORE_ACCOUNT; + + return TRUE; +} + + +int +GetUserInstance(long long head,int *instance) +{ + int loop; + + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetUserInstance"); + + for(loop=0;loopmsisdn_head[loop]) + { + *instance = loop ; + return 1; + } + } + return 0; +} + +int +GetUserPos(int *head,long long head1) +{ + int loop; + + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetUserPos"); + + for(loop=0;loopmsisdn_head[loop] !=0) + if(head1 == shmp->msisdn_head[loop]) + { + *head = loop; + return 1; + } + } + for(loop=0;loopmsisdn_head[loop] == 0) + { + *head = loop; + return 2; + } + } + return 0; +} + + +float +GetBalance(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetBalance"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT){ + if(shmp->prepaid_info[ptr->head][ptr->tail].balance>=ppsParam.serviceControl.maxBalance) + shmp->prepaid_info[ptr->head][ptr->tail].status = T_SUSPEND; + if(shmp->prepaid_info[ptr->head][ptr->tail].msisdn[MAX_MSISDN_BLEN-1]<=2) + return 0; + return (shmp->prepaid_info[ptr->head][ptr->tail].balance + + shmp->prepaid_info[ptr->head][ptr->tail].promo_balance); + } + return 0; +} + +long +GetExpiration(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetExpiration"); + + return (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) ? + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date + : (tvnow.tv_sec+1); +} + +long +GetIncomingExpiration(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetIncomingExpiration"); + + return (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) ? + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date + : (tvnow.tv_sec+1); +} + +int +GetOverdraft(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetOverdraft"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { + return shmp->prepaid_info[ptr->head][ptr->tail].overdraft; + } + return 0; +} + +int IsPromotionExpired(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("IsPromotionExpired"); + + if(ptr == NULL) return 0; + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + if(shmp->prepaid_info[ptr->head][ptr->tail].promo_date > tvnow.tv_sec) + return 0; + } + + return 1; +} + +int +GetCMBTimes(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetCMBTimes"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { + return shmp->prepaid_info[ptr->head][ptr->tail].callMeBackRequestTimes; + } + return 0; +} + +int +UpdateCMBTimes(_account_info *ptr,int times) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateCMBTimes"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + shmp->prepaid_info[ptr->head][ptr->tail].callMeBackRequestTimes += times; + SendAccountRealSync_2(ptr,0.0,0.0,OMC_OCODE_EDIT); + return 1; + } + return -1; +} + +int +resetCMBTimes(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("resetCMBTimes"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + shmp->prepaid_info[ptr->head][ptr->tail].callMeBackRequestTimes = 0; + return 1; + } + return -1; +} + + +void UpdateBalanceForRecharge(_account_info *ptr, int charge) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateBalanceForRecharge"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + shmp->prepaid_info[ptr->head][ptr->tail].balance = + shmp->prepaid_info[ptr->head][ptr->tail].balance + charge; + if(shmp->prepaid_info[ptr->head][ptr->tail].balance >= 0) + shmp->prepaid_info[ptr->head][ptr->tail].overdraft = 0; + /* clear overdraft for each recharge */ + } +} + +void UpdateBalance(_state_data *stateProc,_account_info *ptr, float charge,CHARGED_FEE *chargeFee) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + u_char cos_id; + COSTable *cosTableItem; + double promo_balance,balance; + double chargedBalance = 0,chargedPromotion = 0; + + PutLogFunID("UpdateBalance"); + + + cos_id = ptr->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + if(charge < 0 + && shmp->prepaid_info[ptr->head][ptr->tail].promo_balance > 0 + && isPromotionCanBeUsedAtThisPoint(stateProc)) + { + promo_balance = shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; + promo_balance = promo_balance + charge; + shmp->prepaid_info[ptr->head][ptr->tail].promo_balance = promo_balance; + chargedPromotion = charge; + } + else + { + balance = shmp->prepaid_info[ptr->head][ptr->tail].balance; + balance = balance + charge; + shmp->prepaid_info[ptr->head][ptr->tail].balance = balance; + chargedBalance = charge; + } + + if(shmp->prepaid_info[ptr->head][ptr->tail].promo_balance<0) + { + chargedPromotion += shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; + chargedBalance -= shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; + + shmp->prepaid_info[ptr->head][ptr->tail].balance += + shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; + shmp->prepaid_info[ptr->head][ptr->tail].promo_balance = 0; + } + + if((shmp->prepaid_info[ptr->head][ptr->tail].balance + + shmp->prepaid_info[ptr->head][ptr->tail].overdraft)<=0) + { + if(cosTableItem->accountValidity[0].actionAfterBalanceDepleted) + { + if(shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date> + (tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600)) + { + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600; + } + if(shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date> + (tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600)) + { + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600; + } + } + } + chargeFee->balance = chargedBalance; + chargeFee->promotion = chargedPromotion; + increPoolChildCharged(ptr,-charge); + debugmib.display.totalCharge +=charge; + + if(shmp->prepaid_info[ptr->head][ptr->tail].balance < 0) + { + if(shmp->prepaid_info[ptr->head][ptr->tail].overdraft <= 0) + { + shmp->prepaid_info[ptr->head][ptr->tail].balance = 0; + + } + } + + + } + +} + +void UpdateAccountDefaultLanguageType(_account_info *ptr, u_char type) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountDefaultLanguageType"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + shmp->prepaid_info[ptr->head][ptr->tail].language_type = type; + } +} + +void UpdateAccountPIN(_account_info *ptr, char *pin) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountPIN"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + memcpy(shmp->prepaid_info[ptr->head][ptr->tail].pin,pin,6); + } +} + +int GetAccountPINByMsisdn(u_char *msisdn,u_char *pin) +{ + _account_info info; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountPINByMsisdn"); + + memcpy(info.number,msisdn,strlen((char *)msisdn)); + info.number[strlen((char *)msisdn)] = 0; + if(GetAccountPos(&info) == FALSE) + return -1; + + if (info.head < MSISDN_HEAD_NUM && info.tail < UNIT_STORE_ACCOUNT) + { + memcpy(pin,shmp->prepaid_info[info.head][info.tail].pin,6); + + } + return 1; +} + +int CheckPINValidity(_account_info *ptr, char *pin) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("CheckPINValidity"); + + if(ptr->headtail< UNIT_STORE_ACCOUNT) + { + if(!(strncmp(shmp->prepaid_info[ptr->head][ptr->tail].pin, + pin, + MAX_PIN_LEN))) + return 1; + else + return 0; + } + return 0; +} + +int GetCardSystemParam(u_char cos_id,u_short faceValue) +{ + int i; + COSTable *cosTableItem; + + PutLogFunID("GetCardSystemParam"); + + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(faceValue == 0) return -1; + for(i=0;irechargeCardValidity[i].cardCredit == faceValue) + return i; + } + return -1; +} + +int GetCardSystemParamByNearestValue(u_char cos_id, u_short faceValue) +{ + int i, ret = -1; + COSTable *cosTableItem; + u16 maxCredit = 0; + + PutLogFunID("GetCardSystemParamByNearestValue"); + + if (faceValue == 0) + { + return -1; + } + + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + for (i=0; irechargeCardValidity[i].cardCredit) + { + continue; + } + + if (maxCredit >= cosTableItem->rechargeCardValidity[i].cardCredit) + { + continue; + } + + maxCredit = cosTableItem->rechargeCardValidity[i].cardCredit; + ret = i; + } + + return ret; +} + +void UpdateAccountCallCDR(_account_info *ptr, + char *msisdn,u_long timestamp,int calltype) +{ + int len; + char buf[32]; + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountCallCDR"); + + if(ptr->headtailprepaid_info[ptr->head][ptr->tail].last_call_type = calltype; + shmp->prepaid_info[ptr->head][ptr->tail].last_call_date = timestamp; + len = strlen(msisdn); + if(len % 2 == 1) + { + strcpy(buf,msisdn); + strcat(buf,"F"); + ppsAsciiToBcdR(shmp->prepaid_info[ptr->head][ptr->tail].last_call_number,buf,len+1); + } + else + { + ppsAsciiToBcdR(shmp->prepaid_info[ptr->head][ptr->tail].last_call_number,msisdn,len); + } + shmp->prepaid_info[ptr->head][ptr->tail].last_call_number[MAX_MSISDN_BLEN-1] = len; + } +} + +void UpdateAccountLastCDR(_state_data *shmp) +{ + int instance; + + PutLogFunID("UpdateAccountLastCallCDR"); + + switch(shmp->context_info.callType) + { + case CT_MO_CALL: + UpdateAccountCallCDR(&shmp->caller_info, + (char *)shmp->charge_info.number, + shmp->cdr_info.seizuretime, + LST_MO_CALL); + AccountLatchFlagCheck(shmp->caller_info.head,shmp->caller_info.tail); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + break; + case CT_MT_CALL: + UpdateAccountCallCDR(&shmp->called_info, + (char *)shmp->charge_info.number, + shmp->cdr_info.seizuretime, + LST_MT_CALL); + AccountLatchFlagCheck(shmp->called_info.head,shmp->called_info.tail); + instance = shmp->called_info.head * UNIT_STORE_ACCOUNT + + shmp->called_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + break; + case CT_MF_CALL: + UpdateAccountCallCDR(&shmp->caller_info, + (char *)shmp->charge_info.number, + shmp->cdr_info.seizuretime, + LST_MF_CALL); + AccountLatchFlagCheck(shmp->caller_info.head,shmp->caller_info.tail); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + break; + case CT_MO_SM: + UpdateAccountCallCDR(&shmp->caller_info, + (char *)shmp->charge_info.number, + shmp->cdr_info.seizuretime, + LST_MO_SMS); + AccountLatchFlagCheck(shmp->caller_info.head,shmp->caller_info.tail); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + break; + } +} + +void +UpdateExpiration(_state_data *stashmp) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + long expiration = 0,i_expiration = 0; + u_short valid_time, /* outgoing call */ + i_valid_time, /* incoming call */ + faceValue; + int index,cos_id; + _account_info *ptr; + COSTable *cosTableItem; + + PutLogFunID("UpdateExpiration"); + + ptr = &stashmp->caller_info; + + if(ptr->head>=MSISDN_HEAD_NUM || ptr->tail>=UNIT_STORE_ACCOUNT) + return; + cos_id = shmp->prepaid_info[ptr->head][ptr->tail].cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + valid_time = GetRechargeCardValidTime(stashmp); + if(valid_time<=0) valid_time = 30; + i_valid_time = valid_time; + + faceValue = GetRechargeCardFaceValue(stashmp); + expiration = shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date; + i_expiration = shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date; + + if((index=GetCardSystemParam(cos_id,faceValue))>=0){ + valid_time = cosTableItem->rechargeCardValidity[index].moValidity; + i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; + + } + + if(cosTableItem->accountValidity[0].actionAfterRecharge) + { + if(expiration<(valid_time*24*3600+tvnow.tv_sec)) + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + if(i_expiration<(i_valid_time*24*3600+tvnow.tv_sec)) + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + i_valid_time*24*60*60 + tvnow.tv_sec; + } + else + { + if(tvnow.tv_sec > expiration) + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + else{ + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date += + valid_time*24*60*60; + } + if(tvnow.tv_sec > i_expiration) + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + i_valid_time*24*60*60 + tvnow.tv_sec; + else{ + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date += + i_valid_time*24*60*60; + } + } + if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) + cosTableItem->accountValidity[0].maxAccountValidityDays = 730; + if(shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date> tvnow.tv_sec + + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + if(shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date> tvnow.tv_sec + +cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + +} + +void UpdateExpirationForRechargeCard(_account_info *ptr, u_short valid_time, u_short faceValue) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + long expiration = 0,i_expiration = 0; + u_short i_valid_time; /* incoming call */ + int index, cos_id; + COSTable *cosTableItem; + + PutLogFunID("UpdateExpirationForRechargeCard"); + + if(ptr->head>=MSISDN_HEAD_NUM || ptr->tail>=UNIT_STORE_ACCOUNT) + { + return; + } + + if(OCS_with_external_CRM()) + { + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + return; + } + + cos_id = shmp->prepaid_info[ptr->head][ptr->tail].cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + if(valid_time<=0) valid_time = 30; + i_valid_time = valid_time; + + expiration = shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date; + i_expiration = shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date; + + if((index=GetCardSystemParamByNearestValue(cos_id, faceValue))>=0){ + valid_time = cosTableItem->rechargeCardValidity[index].moValidity; + i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; + } + + if(cosTableItem->accountValidity[0].actionAfterRecharge) + { + if(expiration<(valid_time*24*3600+tvnow.tv_sec)) + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + if(i_expiration<(i_valid_time*24*3600+tvnow.tv_sec)) + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + i_valid_time*24*60*60 + tvnow.tv_sec; + } + else + { + if(tvnow.tv_sec > expiration) + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + else{ + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date += + valid_time*24*60*60; + } + if(tvnow.tv_sec > i_expiration) + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + i_valid_time*24*60*60 + tvnow.tv_sec; + else{ + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date += + i_valid_time*24*60*60; + } + } + + if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) + { + cosTableItem->accountValidity[0].maxAccountValidityDays = 730; + } + + if(shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date> tvnow.tv_sec + + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + { + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + } + + if(shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date> tvnow.tv_sec + +cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + { + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + } +} + +void +UpdateExpirationFirstCharge(_state_data *stashmp) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + u_short valid_time, /* outgoing call */ + i_valid_time; /* incoming call */ + int index,cos_id; + u_short faceValue; + _account_info *ptr; + COSTable *cosTableItem; + + PutLogFunID("UpdateExpirationFirstCharge"); + + ptr = &stashmp->caller_info; + if(ptr->head>=MSISDN_HEAD_NUM) { + return; + } + + cos_id = shmp->prepaid_info[ptr->head][ptr->tail].cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + valid_time = GetRechargeCardValidTime(stashmp); + i_valid_time = valid_time; + faceValue = GetRechargeCardFaceValue(stashmp); + + if((index=GetCardSystemParam(cos_id,faceValue))>=0){ + valid_time = cosTableItem->rechargeCardValidity[index].moValidity; + i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; + } + + shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec ; + shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = + i_valid_time*24*60*60 + tvnow.tv_sec ; +} + +void +UpdateExpirationFirstInquiry(_account_info *ptr, u_short valid_time) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *user_ptr = NULL; + COSTable *cosTableItem; + int cos_id= 0, bundle_plan_id=0; + + PutLogFunID("UpdateExpirationFirstInquiry"); + + if(ptr->head>=MSISDN_HEAD_NUM || ptr->tail>=UNIT_STORE_ACCOUNT) + return; + + cos_id = ptr->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + user_ptr = &shmp->prepaid_info[ptr->head][ptr->tail]; + user_ptr->mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec ; + user_ptr->mt_expiration_date = valid_time*24*60*60 + tvnow.tv_sec ; + + bundle_plan_id = cosTableItem->accountValidity[0].bundlePlanIDWhenActivated; + if( bundle_plan_id > 0 && bundle_plan_id < MAX_BUNDLE_PLANS) + { + user_ptr->bundle_info.validity_date = user_ptr->mo_expiration_date; + user_ptr->bundle_info.data = ppsParam.ppsTables.bundlePlans[bundle_plan_id].data * 1024 * 1024LL; + user_ptr->bundle_info.mo_voice = ppsParam.ppsTables.bundlePlans[bundle_plan_id].mo_voice * 60; + user_ptr->bundle_info.mt_voice = ppsParam.ppsTables.bundlePlans[bundle_plan_id].mt_voice * 60; + user_ptr->bundle_info.sms = ppsParam.ppsTables.bundlePlans[bundle_plan_id].sms; + } + +} + +void +UpdateAccountExpiration(int head, int tail, u_short faceValue,u_short valid_time) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + u_long expiration=0,i_expiration=0; + short index, i_valid_time; + int cos_id; + COSTable *cosTableItem; + + PutLogFunID("UpdateAccountExpiration"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + expiration = shmp->prepaid_info[head][tail].mo_expiration_date; + i_expiration = shmp->prepaid_info[head][tail].mt_expiration_date; + i_valid_time = valid_time; + cos_id = shmp->prepaid_info[head][tail].cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if((index=GetCardSystemParam(cos_id,faceValue))>=0){ + valid_time = cosTableItem->rechargeCardValidity[index].moValidity; + i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; + } + + if(cosTableItem->accountValidity[0].actionAfterRecharge) + { + if(expiration<(valid_time*24*3600+tvnow.tv_sec)) + shmp->prepaid_info[head][tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + if(i_expiration<(i_valid_time*24*3600+tvnow.tv_sec)) + shmp->prepaid_info[head][tail].mt_expiration_date = + i_valid_time*24*60*60 + tvnow.tv_sec; + } + else + { + if(tvnow.tv_sec > expiration) + shmp->prepaid_info[head][tail].mo_expiration_date = + valid_time*24*60*60 + tvnow.tv_sec; + else{ + shmp->prepaid_info[head][tail].mo_expiration_date += + valid_time*24*60*60; + } + if(tvnow.tv_sec > i_expiration) + shmp->prepaid_info[head][tail].mt_expiration_date = + i_valid_time*24*60*60 + tvnow.tv_sec; + else{ + shmp->prepaid_info[head][tail].mt_expiration_date += + i_valid_time*24*60*60; + } + } + + if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) + { + cosTableItem->accountValidity[0].maxAccountValidityDays = 730; + } + + if(shmp->prepaid_info[head][tail].mo_expiration_date> tvnow.tv_sec + + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + { + shmp->prepaid_info[head][tail].mo_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + } + + if(shmp->prepaid_info[head][tail].mt_expiration_date> tvnow.tv_sec + +cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) + { + shmp->prepaid_info[head][tail].mt_expiration_date = + tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; + } + } +} + +int +UpdateAccountStatusFromNormalToSuspendedforExpiration(_prepaid_info *pUsrInfo, int head, int tail) +{ + + if(pUsrInfo == NULL) + return 0; + if(pUsrInfo->mo_expiration_date < tvnow.tv_sec) + { + if(pUsrInfo->status == T_NORMAL) + { + pUsrInfo->status = T_SUSPEND; + SendAccountRealSync(head*UNIT_STORE_ACCOUNT+tail, 0.00, 0.00, OMC_OCODE_EDIT ); + } + } + + return 0; +} + + +int +GetAccountStatus(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountStatus"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + if(shmp->prepaid_info[ptr->head][ptr->tail].balance>=ppsParam.serviceControl.maxBalance) + shmp->prepaid_info[ptr->head][ptr->tail].status = T_SUSPEND; + if(shmp->prepaid_info[ptr->head][ptr->tail].msisdn[MAX_MSISDN_BLEN-1]<=2) + { + shmp->prepaid_info[ptr->head][ptr->tail].status = T_FRESH; + return T_EXTERNAL; + } + return shmp->prepaid_info[ptr->head][ptr->tail].status; + } + return T_EXTERNAL; +} + +int GetAccountCosID(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountCosID"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + return shmp->prepaid_info[ptr->head][ptr->tail].cos_id; + } + return 0; +} + +int GetSerivceNumberFlagPerCos(u8 cos_id, u8 service_type, u8 call_type); +int GetServiceNumberFlag(_state_data *shmp, u8 service_pos) +{ + int match_flag = 0; + + if(shmp->context_info.callType == CT_MO_CALL) + { + match_flag = GetSerivceNumberFlagPerCos(shmp->caller_info.cos_id, service_pos, 0); + } + else if(shmp->context_info.callType == CT_MO_SM ) + { + match_flag = GetSerivceNumberFlagPerCos(shmp->caller_info.cos_id, service_pos, 1); + } + else if(shmp->context_info.callType == CT_USSD) + match_flag = GetSerivceNumberFlagPerCos(shmp->caller_info.cos_id, service_pos, 2); + + return match_flag; +} + + +int GetServiceType_0(_state_data *shmp) +{ + int len0,len1; + char buf[32]; + char destination[32]; + + strcpy(destination, (char *)shmp->called_info.number); + + if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[HotLineNumberPosition].number)==0) + { + return SRV_CALL_HOTLINE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number)==0) + { + return SRV_INQUIRY; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number)==0) + { + return SRV_SCRATCH_CARD_RECHARGE; + //return SRV_RECHARGE_2TYPES; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number)==0) + { + return SRV_BUNDLE_PLAN; //SRV_CREDIT_CARD_RECHARGE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ThirdPartyRechargeNumberPosition].number)==0) + { + return SRV_THIRD_PARTY_RECHARGE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[RechargeNumberPosition].number)==0) + { + return SRV_RECHARGE_2TYPES; + //return SRV_SCRATCH_CARD_RECHARGE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number) == 0) + { + shmp->process_info.palim_auto_register = 1; + return SRV_SCRATCH_CARD_RECHARGE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number)==0) + { + return SRV_POOL_ACCOUNT; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number)==0) + { + return SRV_FEE_TRANSFER; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number)==0) + { + return SRV_FREE_SMS; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number)==0) + { + return SRV_CALL_ME_BACK; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[TellMeNumber].number)==0) + { + return SRV_TELL_ME_NUMBER; + } + /* + else if(IsCRDServiceNumber(destination)) + { + return SRV_CRD; + } + else if(IsPSTNMaitenance(destination)) + { + return SRV_OTHER_VMS_MAITENANCE; + } + else if(IsVMSDeposit(destination)) + { + return SRV_VMS_DEPOSIT; + } + */ + else if(IsCallingCardNumber(destination)) + {/*calling card */ + return SRV_CALLINGCARD_MANAGE; + } + /* + else if(IsDirectAccess(destination)) + { + return SRV_DIRECT_ACCESS; + } + else if(IsVMSReservedFunc(destination)) + { + return SRV_RESERVED_FUN; + }*/ + else + { + len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, + (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number, destination); + shmp->process_info.all_in_one_input_flag = 1; + return SRV_CALL_ME_BACK; + } + } + + len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number, destination); + return SRV_RECHARGE_ONE_INPUT; + } + } + + len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, + (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number,destination); + shmp->process_info.palim_auto_register = 1; + return SRV_RECHARGE_ONE_INPUT; + } + } + return SRV_NORMAL_MO_CALL; + } + return SRV_NORMAL_MO_CALL; +} + +int GetServiceType(_state_data *shmp) +{ + int len0,len1; + char buf[32]; + char destination[32]; + + strcpy(destination, (char *)shmp->called_info.number); + shmp->process_info.tcos= NORMAL_RELEASE; + + if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[HotLineNumberPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, HotLineNumberPosition)) + return SRV_CALL_HOTLINE; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, InquiryNumberPosition)) + return SRV_INQUIRY; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) + return SRV_SCRATCH_CARD_RECHARGE; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + //return SRV_RECHARGE_2TYPES; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, CreditCardRechargeNumberPosition)) + return SRV_CREDIT_CARD_RECHARGE; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ThirdPartyRechargeNumberPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, ThirdPartyRechargeNumberPosition)) + return SRV_THIRD_PARTY_RECHARGE; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[RechargeNumberPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, RechargeNumberPosition)) + return SRV_RECHARGE_2TYPES; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + //return SRV_SCRATCH_CARD_RECHARGE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number) == 0) + { + if(GetServiceNumberFlag(shmp, PalimRegisterNumberPosition)) + { + shmp->process_info.palim_auto_register = 1; + return SRV_SCRATCH_CARD_RECHARGE; + } + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, PoolAccountPosition)) + return SRV_POOL_ACCOUNT; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, FeeTransferPosition)) + return SRV_FEE_TRANSFER; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number)==0) + { + if(GetServiceNumberFlag(shmp, FreeServicePosition)) + return SRV_FREE_SMS; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number)==0) + { + if(GetServiceNumberFlag(shmp, CallMeBackPosition)) + return SRV_CALL_ME_BACK; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[TellMeNumber].number)==0) + { + if(GetServiceNumberFlag(shmp, TellMeNumber)) + return SRV_TELL_ME_NUMBER; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + }/* + else if(IsCRDServiceNumber(destination)) + { + return SRV_CRD; + } + else if(IsPSTNMaitenance(destination)) + { + return SRV_OTHER_VMS_MAITENANCE; + } + else if(IsVMSDeposit(destination)) + { + return SRV_VMS_DEPOSIT; + } + else if(IsOprNumber(destination)) + { + if(GetServiceNumberFlag(shmp, OPRNumberPosition)) + return SRV_OPR_MANAGE; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + }*/ + else if(IsCallingCardNumber(destination)) + {/*calling card */ + if(GetServiceNumberFlag(shmp, VirtualCallingCardNumberPosition)) + return SRV_CALLINGCARD_MANAGE; + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + /* + else if(IsDirectAccess(destination)) + { + return SRV_DIRECT_ACCESS; + } + else if(IsVMSReservedFunc(destination)) + { + return SRV_RESERVED_FUN; + }*/ + else + { + len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, + (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number,destination); + if(GetServiceNumberFlag(shmp, CallMeBackPosition)) + { + shmp->process_info.all_in_one_input_flag = 1; + return SRV_CALL_ME_BACK; + } + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + } + + len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number, destination); + if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) + { + return SRV_RECHARGE_ONE_INPUT; + } + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + } + + len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, + (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number,destination); + if(GetServiceNumberFlag(shmp, PalimRegisterNumberPosition)) + { + shmp->process_info.palim_auto_register = 1; + return SRV_RECHARGE_ONE_INPUT; + } + else + { + shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + } + } + } + return SRV_NORMAL_MO_CALL; + } + return SRV_NORMAL_MO_CALL; +} + +int GetUssdServiceType(_state_data *shmp) +{ + int len0,len1; + char buf[128]; + char destination[128]; + + strcpy(destination, (char *)shmp->called_info.number); + + if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_HOTLINE].number)==0) + { + return SRV_CALL_HOTLINE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_INQUIRY].number)==0) + { + return SRV_INQUIRY; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number)==0) + { + return SRV_SCRATCH_CARD_RECHARGE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FEE_TRANSFER].number)==0) + { + return SRV_FEE_TRANSFER; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number)==0) + { + return SRV_CALL_ME_BACK; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_TELL_ME_NUMBER].number)==0) + { + return SRV_TELL_ME_NUMBER; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].number)==0) + { + return SRV_FAVORITE_NUMBER; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_PLAN].number)==0) + { + return SRV_BUNDLE_PLAN; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_QUERY].number)==0) + { + return SRV_BUNDLE_QUERY; + } + else + { + len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, + (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number,destination); + shmp->process_info.all_in_one_input_flag = 1; + return SRV_CALL_ME_BACK; + } + } + + len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number, destination); + return SRV_RECHARGE_ONE_INPUT; + } + } + } + return SRV_NORMAL_MO_CALL; +} + +int GetUssdServiceType_1(_state_data *shmp) +{ + int len0,len1; + char buf[32]; + char destination[32]; + + strcpy(destination, (char *)shmp->called_info.number); + + if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_HOTLINE].number)==0) + { + if(GetServiceNumberFlag(shmp, HotLineNumberPosition)) + return SRV_CALL_HOTLINE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_INQUIRY].number)==0) + { + if(GetServiceNumberFlag(shmp, InquiryNumberPosition)) + return SRV_INQUIRY; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number)==0) + { + if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) + return SRV_SCRATCH_CARD_RECHARGE; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FEE_TRANSFER].number)==0) + { + if(GetServiceNumberFlag(shmp, FeeTransferPosition)) + return SRV_FEE_TRANSFER; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number)==0) + { + if(GetServiceNumberFlag(shmp, CallMeBackPosition)) + return SRV_CALL_ME_BACK; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_TELL_ME_NUMBER].number)==0) + { + if(GetServiceNumberFlag(shmp, TellMeNumber)) + return SRV_TELL_ME_NUMBER; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].number)==0) + { + if(GetServiceNumberFlag(shmp, FriendFamilyPosition)) + return SRV_FAVORITE_NUMBER; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_PLAN].number)==0) + { + return SRV_BUNDLE_PLAN; + } + else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_QUERY].number)==0) + { + return SRV_BUNDLE_QUERY; + } + else + { + len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, + (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number,destination); + if(GetServiceNumberFlag(shmp, CallMeBackPosition)) + { + shmp->process_info.all_in_one_input_flag = 1; + return SRV_CALL_ME_BACK; + } + } + } + + len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number); + if(len0 !=0) + { + len1 = strlen(destination); + if(len1>= 6 +len0) + if(strncmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number,len0)==0) + { + strcpy(buf,&destination[len0]); + strcpy(destination,buf); + destination[len1-len0] = 0; + strcpy((char *)shmp->called_info.number, destination); + if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) + return SRV_RECHARGE_ONE_INPUT; + } + } + } + return SRV_NORMAL_MO_CALL; +} + +int GetUssdServiceKey(u_char serviceKey) +{ + int i; + + PutLogFunID("GetUssdServiceKey"); + + for(i=USSD_OC_HOTLINE;iprepaid_data; + + PutLogFunID("CheckWetherFavoriteNumber"); + + if(caller->head < MSISDN_HEAD_NUM && caller->tail prepaid_info[caller->head][caller->tail].favorite_numbers) + return NOT_FAVORITE_NUMBER; + + cos_id = shmp->prepaid_info[caller->head][caller->tail].cos_id; + serviceControlItem = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; + if(serviceControlItem->balanceThresholdForFriendFamilyCall>GetAccountBalance(caller->head, caller->tail)) + return NOT_FAVORITE_NUMBER; + //if F*F PLAN, check total F&F call duraiton here + + for(i=0;iprepaid_info[caller->head][caller->tail].favorite_number[i][MAX_MSISDN_BLEN-1]; + if(len>MAX_MSISDN_ALEN || len<2) + continue; + BcdToAscii(msisdn, + shmp->prepaid_info[caller->head][caller->tail].favorite_number[i], + MAX_MSISDN_ALEN); + msisdn[len] = 0; + CutUnknownPrefix(msisdn); + //CheckWetherLocalNumber(msisdn); + if(strcmp(msisdn,called_number)==0) + return FAVORITE_NUMBER; + } + } + return NOT_FAVORITE_NUMBER; +} + +int +GetAccountID(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *user_info=NULL; + + PutLogFunID("GetAccountID"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + user_info = &shmp->prepaid_info[ptr->head][ptr->tail]; + + if(user_info->msisdn[MAX_MSISDN_BLEN-1]>=MIN_MSISDN_ALEN && user_info->msisdn[MAX_MSISDN_BLEN-1]<=MAX_MSISDN_ALEN) + { + return user_info->crm_info.account_id; + } + else + return 0; + } + + return 0; +} + +int +GetAccountCUG(_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *user_info=NULL; + + PutLogFunID("GetAccountCUG"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + user_info = &shmp->prepaid_info[ptr->head][ptr->tail]; + + if(user_info->msisdn[MAX_MSISDN_BLEN-1]>=MIN_MSISDN_ALEN && user_info->msisdn[MAX_MSISDN_BLEN-1]<=MAX_MSISDN_ALEN) + { + if(user_info->crm_info.vas_cug_state != 0)//cug service is blocked for rent charge failed + return NOT_CUG_ACCOUNT; + + return user_info->cug_id; + } + else + return NOT_CUG_ACCOUNT; + } + + return NOT_CUG_ACCOUNT; +} + + + + +int GetDiscount(long timestamp,u_char discount_id) +{ + int holiday_flag; + _tariff_private *shmp; + struct tm tm, *timep; + int discount=0; + int wday=0; + + PutLogFunID("GetDiscount"); + + shmp = blf_shmp; + timep = (struct tm *) &tm; + timep = (struct tm *) localtime( (time_t *)×tamp ); + if(timep == NULL) + { + DebugMsg(debugmib.display.asciiOut, "Get Discount time error: %d", timestamp); + + return 100; + } + + holiday_flag = shmp->holiday_flag[timep->tm_mon][timep->tm_mday-1];// advanced->Tariff plan->Holiday + wday = (holiday_flag ? 7 : timep->tm_wday); + +#if DEBUG1 + DebugMsg(debugmib.display.asciiOut, "Tm month: %d Tm mday: %d Holiday flag: %d", + timep->tm_mon, timep->tm_mday, holiday_flag); +#endif + discount = shmp->bill_discount[discount_id][timep->tm_hour][wday];// advanced->Tariff plan->Discount +#if DEBUG1 + DebugMsg(debugmib.display.asciiOut, "Type: %d Hour: %d Week day: %d Discount: %d", + id, timep->tm_hour, wday, discount); +#endif + if(discount < 0) + discount = 0; + return discount; +} + + +void set_truncation_flag(int flag) +{ + ppsParam.serviceControl.truncation_flag = flag; +} + +int get_truncation_flag() +{ + return ppsParam.serviceControl.truncation_flag; +} + + +int SetTcpSyncFlag(int flag) +{ + DebugMsg(debugmib.display.asciiOut,"Current tcp sync flag: %d", ppsParam.serviceControl.tcp_sync_flag); + + if(flag) + ppsParam.serviceControl.tcp_sync_flag = 1; + else + ppsParam.serviceControl.tcp_sync_flag = 0; + + DebugMsg(debugmib.display.asciiOut,"New tcp sync flag: %d", ppsParam.serviceControl.tcp_sync_flag); + return 1; +} + +float ChargeGprsAccountBalance(_state_data *shmp,int real_duration) +{ + int i=0,j; + int discount=0; + float charge=0; + int itimes=0, unit_time=60; + int duration, begin_time; + _bill_tariff *ptar; + + PutLogFunID("ChargeAccountBalance"); + + begin_time = shmp->cdr_info.answertime, + ptar = &shmp->process_info.tariff; + + duration = real_duration; + duration -= ptar->free_time; + if(duration<=0) return (charge = 0); + if ((unit_time = ptar->unit_time) <= 0) + unit_time = 60; + + itimes = (ceil)((double) duration / unit_time); + + discount = GetDiscount(begin_time,ptar->discountID); + + for (i=1; i<=itimes; i++) + { + if (i <= ptar->mini_unit ) + { + for(j=0;j < ptar->mini_unit;j++) + { + charge += BillingFormula(shmp,ptar,begin_time); + begin_time += unit_time; + } + charge = (charge + ptar->adjustment); + i = ptar->mini_unit; + } + else + { + charge = charge + BillingFormula(shmp,ptar,begin_time); + begin_time += unit_time; + } + } + + charge = (charge * discount)/100; + + return charge; +} + +int GetValidTime(_state_data *shmp,int begin_time, _bill_tariff *ptar, + float balance, int init_bill, int overdraft) +{ + int valid_time = 0; + float charge=0, amount=0; + int cos_id; + COSTable *cosTableItem; + + PutLogFunID("GetValidTime"); + + cos_id = shmp->called_info.cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + if (init_bill == 0) + valid_time = ptar->unit_time * ptar->mini_unit; + else + valid_time = ptar->unit_time; + if (valid_time <= 0) + valid_time = 60; + + charge = TimeToCharge(shmp,ptar, valid_time, begin_time,init_bill); + amount = balance - charge + overdraft; + +#if DEBUG1 + DebugMsg(debugmib.display.asciiOut, + "GetValid time: balance: %.0f charge: %.0f draft: %d amount: %.0f", + balance, charge, overdraft, amount); +#endif +/*How to get left seconds of account??? + 2003-10-07 + */ + + if(charge==0) + { + /* mo call */ + if(shmp->context_info.callType != CT_MT_CALL) + { + //if(amount<=0) /* zero balance can't make free mo call */ + if(amount<0) + valid_time = 0; + } + else + { + + if(cosTableItem->serviceControl[0].mtChargeFlag !=0 ) + { // mt call, charged ,no balance + if(cosTableItem->serviceControl[0].mtBalanceControl == 1) + if(balance+overdraftserviceControl[0].mtBalanceThreshold) + valid_time = 0; + } + else + {// mt is free + if(cosTableItem->serviceControl[0].mtChargeFlag == 1) + { // mt balance threshold used + if(balance+overdraftserviceControl[0].mtBalanceThreshold) + valid_time = 0; + } + } + } + } + else + { + if(amount<0) + valid_time = 0; + + if(shmp->context_info.callType == CT_MT_CALL) + if(cosTableItem->serviceControl[0].mtChargeFlag == 1) + { + if(balance+overdraftserviceControl[0].mtBalanceThreshold) + valid_time = 0; + } + } + /* + if (amount < 0 && charge >= 0) + valid_time = 0; + */ + return (valid_time*CYCLE_STATE_INTERVAL); +} + +int GetMaxCallDuration(_state_data *shmp) +{ + int /*init_flag=0 , */discount, maxDuration=0,free_time=0; + float balance; + _bill_tariff *ptar, tariff; + //int j; + //float charge; + u32 calTime; + int init_charge_cycle = 0; + + PutLogFunID("GetMaxCallDuration"); + + if(shmp->process_info.serviceType == SRV_CRD + || + (shmp->process_info.serviceType == SRV_NORMAL_MO_CALL + && + shmp->process_info.callConnected == 1 + && + !ppsParam.serviceControl.vms_allways_go)) + { + maxDuration = 12 * ONE_MINUTE_STATE_TIME ; + shmp->process_info.maxCallDuration = maxDuration; + return maxDuration; + } + + ptar = &tariff; + + memcpy(ptar, &shmp->process_info.tariff, sizeof(_bill_tariff)); + if(ptar->unit_time<=0) + ptar->unit_time = 60; + if(0) + DebugMsg(debugmib.display.asciiOut, " %s:%d , tariff: %.2f+%.2f vs %.2f+%.2f", + __FUNCTION__, __LINE__, + shmp->process_info.tariff.tierRating.rating[0].base_fee, + shmp->process_info.tariff.tierRating.rating[0].long_distance_fee, + ptar->tierRating.rating[0].base_fee, + ptar->tierRating.rating[0].long_distance_fee); + + if (shmp->process_info.ro_if.gy_ro_enable) + { + init_charge_cycle = ptar->free_time;// Ro: shmp->process_info.duration is in second. + } + else + { + init_charge_cycle = ptar->free_time*CYCLE_STATE_INTERVAL; + } + + if(shmp->process_info.duration < init_charge_cycle) + { + free_time = ptar->free_time; + maxDuration = free_time; + //init_flag = 1; + } + else + { + /* + init_charge_cycle = (ptar->free_time+ptar->mini_unit*ptar->unit_time)*CYCLE_STATE_INTERVAL; + + if(shmp->process_info.duration < init_charge_cycle) + { + init_flag = 1; + } + */ + } + + discount = GetDiscount(tvnow.tv_sec, ptar->discountID); + if(discount <= 0)// free call + { + maxDuration = MAX_CALL_DURATION; + } + else + { + if(shmp->context_info.callType == CT_MT_CALL) + balance = (int)GetBalanceWithPromotionControl(shmp,&shmp->called_info) + GetOverdraft(&shmp->called_info); + else + balance = (int)GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info); + + if(balance<0) + return 0; + + calTime = preLeftTime(shmp,balance,ptar); + + maxDuration += calTime; // free_time + pre left + } + + shmp->process_info.maxCallDuration = maxDuration; + + return maxDuration; +} + +void +EncryptCardHRN(char *card_hrn,u_char *card_pwd) +{ + char pinkey[32],tmp_hrn[32]; + u_char u_buf[32]; + int len; + + //PutLogFunID("EncryptCardHRN"); + + len = strlen(card_hrn); + /* + if(len == 10) // add for PNCC + { + StringCat(card_hrn,"00",12); + memcpy(pinkey, card_hrn, 6); + pinkey[6] = 0; + StringCat(pinkey, "0", 8); + EncryptPIN(card_pwd, card_hrn, PAN_KEY, pinkey); + } + else if(len == 11) // for Solomon, 2006-11-15 + { + StringCat(card_hrn,"0",12); + memcpy(pinkey, card_hrn, 6); + pinkey[6] = 0; + StringCat(pinkey, "0", 8); + EncryptPIN(card_pwd, card_hrn, PAN_KEY, pinkey); + } + */ + if(len<10 || len>16) return; + if(len<12) + { + strcpy(tmp_hrn,card_hrn); + StringCat(tmp_hrn,"0",16); + AsciiToBcd(u_buf,tmp_hrn,16); + des(card_pwd,u_buf, (unsigned char *)PAN_KEY,0); + } + else if(len==12) + { + memcpy(pinkey, card_hrn, 6); + pinkey[6] = 0; + StringCat(pinkey, "0", 8); + EncryptPIN(card_pwd, card_hrn, PAN_KEY, (unsigned char *)pinkey); + } + else if(len == 14) + { + memcpy(pinkey, card_hrn, 7); + pinkey[7] = 0; + StringCat(pinkey, "0", 8); + EncryptPIN(card_pwd, card_hrn, PAN_KEY, (unsigned char *)pinkey); + } + else if(len==16) + { + AsciiToBcd(u_buf,card_hrn,16); + des(card_pwd,u_buf, (unsigned char *)PAN_KEY,0); + } + else + { + if(0) + DebugMsg(debugmib.display.asciiOut,"\33[31mPwd len:%d error!Must be 12,14,16 \33[0m",len); + } + +#if DEBUG1 + DebugMsg(debugmib.display.asciiOut, "card hrn: %s pinkey: %s", + card_hrn, pinkey); +#endif +} + +u_char +GetAccountZoneID(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + int cos_id; + COSTable *cosTableItem; + + PutLogFunID("GetAccountZoneID"); + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + cos_id = shmp->prepaid_info[head][tail].cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + return cosTableItem->tariff[0].moTariffID%MAX_ZONE_NUM; + + } + return 0; +} + +u_char GetAccountMTZoneID(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + int cos_id; + COSTable *cosTableItem; + + PutLogFunID("GetAccountMTZoneID"); + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + cos_id = shmp->prepaid_info[head][tail].cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + return cosTableItem->tariff[0].mtTariffID%MAX_ZONE_NUM; + } + return 0; +} + +int GetAccountLastCallInfo(_account_info *ptr, _last_call_info *pInfo) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountLastCallInfo"); + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + if(shmp->prepaid_info[ptr->head][ptr->tail].last_call_date>tvnow.tv_sec/2) + { + pInfo->last_call_type = + shmp->prepaid_info[ptr->head][ptr->tail].last_call_type; + pInfo->last_call_date = + shmp->prepaid_info[ptr->head][ptr->tail].last_call_date; + memcpy(pInfo->last_call_number, + shmp->prepaid_info[ptr->head][ptr->tail].last_call_number, + MAX_MSISDN_BLEN); + return 1; + } + } + return 0; +} + +int IsSpanCall(_state_data *shmp) +{ + PutLogFunID("IsSpanCall"); + + if (shmp->caller_info.location != + GetAccountZoneID(shmp->caller_info.head, + shmp->caller_info.tail) ) + return TRUE; + else + return FALSE; +} + +int IncreaseServiceSM(int head, int tail) +{ + _prepaid_info *ptr; + + PutLogFunID("IncreaseServiceSM"); + + if(headprepaid_data.prepaid_info[head][tail]; + if(ptr->free_sm_counter<0x7F) + return (++ptr->free_sm_counter); + return ptr->free_sm_counter; + } + return 0; +} + +int IncreaseFavoriteNumberChangeCounterByOmc(_prepaid_info *ptr) +{ + PutLogFunID("IncreaseFavoriteNumberChangeCounterByOmc"); + if(ptr == NULL) + return 0; + + if(ptr->fav_change_counter<0x7F) + return (++ptr->fav_change_counter); + return ptr->fav_change_counter; +} + +int IncreaseFavoriteNumberChangeCounter(int head, int tail) +{ + _prepaid_info *ptr; + + PutLogFunID("IncreaseFavoriteNumberChangeCounter"); + + if(headprepaid_data.prepaid_info[head][tail]; + if(ptr->fav_change_counter<0x7F) + return (++ptr->fav_change_counter); + return ptr->fav_change_counter; + } + return 0; +} + +int GetFriendFamilyChangeCounter(int head, int tail) +{ + _prepaid_info *ptr; + + PutLogFunID("IncreaseFavoriteNumberChangeCounter"); + + if(headprepaid_data.prepaid_info[head][tail]; + return ptr->fav_change_counter; + } + return 0; +} + +int GetFriendFamilyCounter(int head, int tail) +{ + _prepaid_info *ptr; + + PutLogFunID("IncreaseFavoriteNumberChangeCounter"); + + if(headprepaid_data.prepaid_info[head][tail]; + return ptr->favorite_numbers; + } + return 0; +} + +int GetAccountFriendFamilyPlanID(int head, int tail) +{ + _prepaid_info *ptr; + + PutLogFunID("GetAccountFriendFamilyPlanID"); + + if(headprepaid_data.prepaid_info[head][tail]; + return ptr->favorite_plan_id-1; + } + return -1; + +} + +int GetFavoriteNumberChangeCharge(_state_data *shmp) +{ + int head,tail; + int amount,tariff_id=0; + //_prepaid_info *ptr; + + PutLogFunID("BillingFavoriteNumberChange"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if(head>=MSISDN_HEAD_NUM) + return 0; + tariff_id = GetAccountZoneID(head,tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + //ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + amount = ramshm_ptr->tariff_data.comm_tariff[tariff_id].favEditChargeAmount; + return amount; +} + +int BillingFavoriteNumberChange(_state_data *shmp) +{ + int head,tail; + int amount,tariff_id=0; + _prepaid_info *ptr; + + PutLogFunID("BillingFavoriteNumberChange"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if(head>=MSISDN_HEAD_NUM) + return 0; + tariff_id = GetAccountZoneID(head,tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + amount = ramshm_ptr->tariff_data.comm_tariff[tariff_id].favEditChargeAmount; + ptr->balance = ptr->balance - amount; + shmp->caller_info.charge = amount; + return amount; +} + +int IsEnableToAddEditFavoriteNumber(_state_data *shmp, int flag) +{/*flag = 0/1, add, edit */ + + CosFriendFamilyControl *friendFamilyControl; + int cos_id,plan_id=0; + + cos_id = shmp->caller_info.cos_id; + + friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; + + plan_id = GetAccountFriendFamilyPlanID(shmp->caller_info.head,shmp->caller_info.tail); + if(plan_id>MAX_FAVORITE_PALN) + return 0; + + if(plan_id>=0 && flag == 0) + { + if(GetFriendFamilyCounter(shmp->caller_info.head,shmp->caller_info.tail)>= + friendFamilyControl->friendFamilyPlan[plan_id].maxNumbers) + return 0; + } + if(flag == 0) + return 1; + + if(friendFamilyControl->friendFamilyChangeChargeFlag) + { + if(GetFriendFamilyChangeCounter(shmp->caller_info.head,shmp->caller_info.tail)<= + friendFamilyControl->friendFamilyFreeChangeTimes) + return 1; + + if(GetFavoriteNumberChangeCharge(shmp) > GetAccountBalance(shmp->caller_info.head,shmp->caller_info.tail)) + { + return 0; + } + } + + return 1; +} + +int IsFavoriteNumberTypeOk(_state_data *shmp) +{ + CosFriendFamilyControl *friendFamilyControl; + int cos_id; + char tmpChargeNumber[32]; + + cos_id = shmp->caller_info.cos_id; + + friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; + + strcpy(tmpChargeNumber,shmp->process_info.tmpDigits); + + CutUnknownPrefix(tmpChargeNumber); //tariff prefix always be E.164 + + if(!GetMOTariffData(shmp,&shmp->process_info.tariff, tmpChargeNumber, shmp->caller_info.location)) + return 0; //no tariff + switch(shmp->process_info.tariff.call_type) + { + case 0: //local + if(friendFamilyControl->friendFamilyNumberTypeLocal) + return 1; + break; + case 1: //NDD + if(friendFamilyControl->friendFamilyNumberTypeNDD) + return 1; + break; + case 2: //IDD + if(friendFamilyControl->friendFamilyNumberTypeIDD) + return 1; + break; + } + + return 0; +} + +int CheckClearFriendFamilyNumber(int head, int tail, int rent_charge,int rent_id) +{ + int cos_id; + _prepaid_info *ptr; + CosFriendFamilyControl *friendFamilyControl; + + PutLogFunID("CheckClearFriendFamilyNumber"); + + if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) + { + return 0; + } + + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + //if(ptr->fav_change_counter==0) + // return 0; + ptr->free_favorite_call = 0; + ptr->free_favorite_sms = 0; + + cos_id = ptr->cos_id; + friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; + if(friendFamilyControl->keepOrRemoveFriendFamilyNumber==0) //remove + { + ptr->rent_type ^= (0x01<favorite_plan_id = 0; + ptr->favorite_numbers = 0; + ptr->favorite_plan_state = 0; + ptr->fav_change_counter = 0; + memset(ptr->favorite_number,0x00,MAX_FAVORITE_NUMBERS*MAX_MSISDN_BLEN); + if(ppsParam.ppsTables.cosTable[cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceRemoved ) + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_REMOVE); + return 1; + } + if(friendFamilyControl->balanceThresholdToKeepFriendFamilyNumber!=0 && + friendFamilyControl->balanceThresholdToKeepFriendFamilyNumber>GetAccountBalance( head, tail)) + { + ptr->favorite_plan_state = 1; + if(ppsParam.ppsTables.cosTable[cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceSuspend) + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_SERVICE_SUSPEND); + return 1; + } + if(rent_charge>GetAccountBalance( head, tail)) + { + ptr->favorite_plan_state = 1; + + if(ppsParam.ppsTables.cosTable[cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceSuspend) + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_SERVICE_SUSPEND); + + return 1; + } + return 0; +} + +int CheckFriendFamilyPlanFreeCallOrSMS(int head, int tail, int type, int duration) /* type0=call, 1=sms */ +{ + /* when type0=call, check if call duration + existing free call duration exceeds threshold */ + int cos_id, plan_id=0; + _prepaid_info *ptr; + CosFriendFamilyControl *friendFamilyControl; + + PutLogFunID("CheckFriendFamilyPlanFreeSMS"); + + if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) + { + return 0; + } + + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(ptr->favorite_numbers ==0) + return 0; + if(ptr->favorite_plan_id<=0 || ptr->favorite_plan_id>MAX_FAVORITE_PALN || ptr->favorite_plan_state !=0) + return 0; + + plan_id = ptr->favorite_plan_id-1; + cos_id = ptr->cos_id; + friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; + switch(type) + { + case 0: + if(friendFamilyControl->friendFamilyPlan[plan_id].freeCallDuration == 0) + return 1; + if((ptr->free_favorite_call+duration) >= friendFamilyControl->friendFamilyPlan[plan_id].freeCallDuration*60) //keep + return 0; + break; + case 1: + default: + if(friendFamilyControl->friendFamilyPlan[plan_id].freeSMS == 0) + return 1; + if(ptr->free_favorite_sms >= friendFamilyControl->friendFamilyPlan[plan_id].freeSMS) //keep + return 0; + break; + } + + return 1; +} + + +int IncreaseFriendFamilyFreeCallDuration(int head, int tail, int duration) +{ + _prepaid_info *ptr; + + PutLogFunID("IncreaseFriendFamilyFreeCallDuration"); + + if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) + { + return 0; + } + + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + + if(1) + { + int cos_id, max_free_duration, plan_id; + cos_id = ptr->cos_id; + plan_id = ptr->favorite_plan_id - 1; + if(plan_id>0 && plan_id0) + if((ptr->free_favorite_call + duration/CYCLE_STATE_INTERVAL)>max_free_duration) + { + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_PLAN_EXHAUST); + } + } + } + ptr->free_favorite_call += ceil( (double) duration / CYCLE_STATE_INTERVAL); + + return 1; +} + + +int IncreaseFriendFamilyFreeSMSCounter(int head, int tail) +{ + _prepaid_info *ptr; + + PutLogFunID("IncreaseFriendFamilyFreeSMSCounter"); + + if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) + { + return 0; + } + + ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + + if(1) + { + int cos_id, max_free_sms, plan_id; + cos_id = ptr->cos_id; + plan_id = ptr->favorite_plan_id - 1; + if(plan_id>0 && plan_id0) + if((ptr->free_favorite_sms +1 )>max_free_sms) + { + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_PLAN_EXHAUST); + } + } + } + ptr->free_favorite_sms++; + + return 1; +} + + +float GetSMSTariff(_state_data *shmp,u_char tariff_id) +{ + int i,flag=0,len=0,maxlen=0,index=0; + float sms_fee = 0; + int discount=100; + _bill_sms *ptr; + char bill_no[64]; + + //tariff_id = shmp->caller_info.location; + //GetAccountZoneID(shmp->caller_info.head,shmp->caller_info.tail); + if(tariff_id>=MAX_ZONE_NUM ) tariff_id = 0; + + if(shmp->process_info.mnp_status ) + sprintf(bill_no,"%s%s",shmp->process_info.routing_number, + shmp->called_info.number); + else + strcpy(bill_no, (char *)shmp->charge_info.number); + + for(i=1;ibill_sms[tariff_id][i]; + if(ptr->id !=0) + { + len = strlen(ptr->bill_id); + if(!strncasecmp(bill_no,ptr->bill_id,len)) + if(len>maxlen) + { + maxlen = len; + flag = 1; + index = i; + } + } + } + + if(flag == 0) + { + if(shmp->process_info.mnp_status ) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\33[33m SMS to ported number, but no RN+MSISDN(%s) billing prefix\33[0m", + bill_no); + DebugMsg(debugmib.display.asciiOut, + "\33[33m Use dialing prefix %s as billing prefix\33[0m", + shmp->charge_info.number); + } + strcpy(bill_no, (char *)shmp->charge_info.number); + for(i=1;ibill_sms[tariff_id][i]; + if(ptr->id !=0) + { + len = strlen(ptr->bill_id); + if(!strncasecmp(bill_no,ptr->bill_id,len)) + if(len>maxlen) + { + maxlen = len; + flag = 1; + index = i; + } + } + } + } + if(flag == 0) + ptr = &blf_shmp->bill_sms[tariff_id][DEFAULT_SMS_BILLING]; + else + ptr = &blf_shmp->bill_sms[tariff_id][index]; + } + else + { + ptr = &blf_shmp->bill_sms[tariff_id][index]; + } + memcpy(&shmp->process_info.smsTariff,ptr,sizeof(_bill_sms)); + sms_fee = ptr->base_fee; + discount = GetDiscount(tvnow.tv_sec,ptr->discountID); + // DebugMsg(debugmib.display.asciiOut, + // "sms tariff : fee:%0.4f discountID:%d discount: %d ", + // sms_fee,ptr->discountID,discount); + sms_fee = sms_fee * discount /100; +// if(!shmp->process_info.cap_flag) + shmp->process_info.cap_flag = ptr->cap_flag; + + if(shmp->process_info.favoriteCall) + { + //COSTable *cosTableItem; + + //cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(CheckFriendFamilyPlanFreeCallOrSMS(shmp->caller_info.head, shmp->caller_info.tail, 1,0)) + { + sms_fee = 0; /* free friend family SMS */ + shmp->process_info.cap_flag = 0; + shmp->process_info.favoriteCall = FRIEND_FAMILY_FREE_SMS; /* free friend family call */ + } + } + return sms_fee; +} + + +static void CheckCAPSMSNotification(_state_data *staPtr, _account_info *accountPtr, u_char cos_id, + int cap_type, float charge, int amount ) /* cap_type: 0=call, 1=sms */ +{ + int cap_plan,cap_seg, type,notifyFlag=0; + float c_threshold=0; + _prepaid_info *subPtr=NULL; + + COSTable *cosTableItem; + CosCapPlan *capPlanPtr; + + + PutLogFunID("CheckCAPSMSNotification"); + + if(staPtr->process_info.cap_notify_flag) /* already send notification SM in this call */ + return; + + cap_plan = staPtr->process_info.cap_plan; + cap_seg = staPtr->process_info.cap_seg; + type = staPtr->process_info.cap_flag; + if(cap_seg>=3) return; /* reach the last CAP segment */ + + subPtr = &ramshm_ptr->prepaid_data.prepaid_info[accountPtr->head][accountPtr->tail]; + + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + capPlanPtr = &cosTableItem->capPlan[cap_plan]; + if(cap_seg == 0) + c_threshold = (float)capPlanPtr->threshold0; + else if(cap_seg == 1) + c_threshold = (float)capPlanPtr->threshold1; + else if(cap_seg == 2) + c_threshold = (float)capPlanPtr->threshold2; + + switch(cap_type) + { + case 0: + if(capPlanPtr->type == 0) //counter + { + if(type == 1) /* in net call */ + { + if((subPtr->in_net_cap_call_duration + amount)>=c_threshold) + notifyFlag = 1; + } + else if(type == 2) /* out net call */ + { + if((subPtr->out_net_cap_call_duration + amount)>=c_threshold) + notifyFlag = 1; + + } + } + else if(charge>0) //balance + { + if(type == 1) + { + if((subPtr->in_net_cap_call_balance + charge)>=c_threshold) + notifyFlag = 1; + } + else if(type == 2) + { + if((subPtr->out_net_cap_call_balance + charge)>=c_threshold) + notifyFlag = 1; + + } + } + break; + case 1: + if(capPlanPtr->type == 0) //counter + { + if(type == 1) + { + if((subPtr->in_net_cap_sms_counter + 1)==c_threshold) + notifyFlag = 1; + } + else if(type == 2) + { + if((subPtr->out_net_cap_sms_counter + 1)==c_threshold) + notifyFlag = 1; + + } + } + else if(charge>0) //balance + { + if(type == 1) + { + if((subPtr->in_net_cap_sms_balance + charge)>=c_threshold) + notifyFlag = 1; + } + else if(type == 2) + { + if((subPtr->out_net_cap_sms_balance + charge)>=c_threshold) + notifyFlag = 1; + + } + } + break; + } + + if(notifyFlag) + { + if(cap_seg == 0) + PPSSendUserSMSNotification(accountPtr->head, accountPtr->tail, (char *)getSmsSentenceNative(0,SMS_CAPSMS_NOTIFY)); + else if(cap_seg == 1) + PPSSendUserSMSNotification(accountPtr->head, accountPtr->tail, (char *)getSmsSentenceNative(0,SMS_CAPSMS_1_NOTIFY)); + else + {PPSSendUserSMSNotification(accountPtr->head, accountPtr->tail, (char *)getSmsSentenceNative(0,SMS_CAPSMS_2_NOTIFY));} + + staPtr->process_info.cap_notify_flag = 1; + } + +} + +void UpdateSubsCapInfo(_account_info *ptr, int cap_type,float charge, int amount, _state_data *sta_ptr) +{ +/* cap type: 0=call, 1=sm */ + + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *subPtr; + u_char cos_id; + int type=sta_ptr->process_info.cap_flag; + COSTable *cosTableItem; + + + PutLogFunID("UpdateSubsCapBalance"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + subPtr = &shmp->prepaid_info[ptr->head][ptr->tail]; + + cos_id = subPtr->cos_id%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenCapPlanChanged) + { + CheckCAPSMSNotification(sta_ptr,ptr,cos_id,cap_type,charge, amount); + } + + if(cap_type==0) + { + if(type == 1) + { + subPtr->in_net_cap_call_balance = + subPtr->in_net_cap_call_balance + charge; + subPtr->in_net_cap_call_duration += amount; + subPtr->in_net_cap_balance = + subPtr->in_net_cap_balance + charge; + } + else if(type == 2) + { + subPtr->out_net_cap_call_balance = + subPtr->out_net_cap_call_balance + charge; + subPtr->out_net_cap_call_duration += amount; + subPtr->out_net_cap_balance = + subPtr->out_net_cap_balance + charge; + } + } + else + { + if(type == 1) + { + subPtr->in_net_cap_sms_balance = + subPtr->in_net_cap_sms_balance + charge; + subPtr->in_net_cap_sms_counter ++; + subPtr->in_net_cap_balance = + subPtr->in_net_cap_balance + charge; + } + else if(type == 2) + { + subPtr->out_net_cap_sms_balance = + subPtr->out_net_cap_sms_balance + charge; + subPtr->out_net_cap_sms_counter ++; + subPtr->out_net_cap_balance = + subPtr->out_net_cap_balance + charge; + } + } + + } +} + +void GetSubsCapInfo(_account_info *ptr,int cap_type, float *balance, int *counter, int type, int cap_flag) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetSubsCapInfo"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + if(cap_flag == CAP_TYPE_BOTH) + { + if(type == 0) + { + *balance = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_balance; + *counter = 0; + } + else + { + *balance = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_balance; + *counter = 0; + } + return; + } + + if(cap_type==0) + { + if(type==0) /* int net */ + { + *balance = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_call_balance; + *counter = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_call_duration; + } + else /* out net */ + { + *balance = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_call_balance; + *counter = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_call_duration; + } + } + else + { + if(type==0) /* int net */ + { + *balance = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_sms_balance; + *counter = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_sms_counter; + } + else /* out net */ + { + *balance = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_sms_balance; + *counter = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_sms_counter; + } + } + } + else + { + *balance = 0; + *counter = 0; + } +} + +int GetSubsCapTariffID(_state_data *shmp, int call_type) +{ + int cos_id=0,tariff_id=-1,cap_plan=0,loop=0; + float cap_balance; + int cap_counter; + float c_threshold0=0,c_threshold1=0,c_threshold2=0; + int cap_flag,cap_type; + COSTable *cosTableItem; + CosCapPlan *capPlanPtr; + + PutLogFunID("GetSubsCapTariffID"); + + cos_id = shmp->caller_info.cos_id%MaxCosTableItem; + + if(call_type == 0) /* call */ + { + cap_type = 1; /* call */ + cap_flag = 1; + } + else /* sm , please refer param.h cap_plan for the assignment*/ + { + cap_type = 2; + cap_flag = 2; + } + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + for(loop=0;loopcapPlan[loop].flag & cap_flag )== cap_type && //call + shmp->process_info.cap_flag == (loop%2+1) ) + { + cap_flag = cosTableItem->capPlan[loop].flag; /* 0=disable, 1/2/3=cap by SM/CALL/BOTH */ + cap_plan = loop; + break; + } + + } + + shmp->process_info.cap_plan = cap_plan; + GetSubsCapInfo(&shmp->caller_info, + call_type, // call=0 or sm=1 + &cap_balance, + &cap_counter, + shmp->process_info.cap_flag-1, //innet=0, outnet=1 + cap_flag + ); + + + capPlanPtr = &cosTableItem->capPlan[cap_plan]; + c_threshold0 = (float)capPlanPtr->threshold0; + c_threshold1 = (float)capPlanPtr->threshold1; + c_threshold2 = (float)capPlanPtr->threshold2; + + if(capPlanPtr->type == 0) + { + if(c_threshold0>0) + { + if(cap_countertariffID0; + shmp->process_info.cap_seg = 0; + } + else if(c_threshold1>0) + { + if(cap_countertariffID1; + shmp->process_info.cap_seg = 1; + } + else if(c_threshold2>0) + { + if(cap_countertariffID2; + shmp->process_info.cap_seg = 2; + } + else + { + tariff_id = capPlanPtr->tariffID3; + shmp->process_info.cap_seg = 3; + } + } + else + { + tariff_id = capPlanPtr->tariffID2; + shmp->process_info.cap_seg = 2; + } + } + else + { + tariff_id = capPlanPtr->tariffID1; + shmp->process_info.cap_seg = 1; + } + } + } + else + { + if(c_threshold0>0) + { + if(cap_balancetariffID0; + shmp->process_info.cap_seg = 0; + } + else if(c_threshold1>0) + { + if(cap_balancetariffID1; + shmp->process_info.cap_seg = 1; + } + else if(c_threshold2>0) + { + if(cap_balancetariffID2; + shmp->process_info.cap_seg = 2; + } + else + { + tariff_id = capPlanPtr->tariffID3; + shmp->process_info.cap_seg = 3; + } + } + else + { + tariff_id = capPlanPtr->tariffID2; + shmp->process_info.cap_seg = 2; + } + } + else + { + tariff_id = capPlanPtr->tariffID1; + shmp->process_info.cap_seg = 1; + } + } + + } + return tariff_id; +} + + +int UpdateAccountBundlePlanInfoWarningFlag(_state_data *shmp, int flag) +{ + _prepaid_data *ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("UpdateAccountBundlePlanInfoWarningFlag"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &ptr->prepaid_info[head][tail]; + sub_ptr->bundle_info.warning_sms_flag = flag; + } + + return 1; +} + +int UpdateAccountBundlePlanInfo(_account_info *shmp, long set_value[7]) +{ + _prepaid_data *ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("UpdateAccountBundlePlanInfo"); + + head = shmp->head; + tail = shmp->tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &ptr->prepaid_info[head][tail]; + + if(sub_ptr->bundle_info.data == 0)// set voice/sms to 0, if data==0 when subscribe bundle + { + sub_ptr->bundle_info.validity_date = tvnow.tv_sec - 1000; + sub_ptr->bundle_info.mo_voice = 0; + sub_ptr->bundle_info.mt_voice = 0; + sub_ptr->bundle_info.sms = 0; + } + + //sub_ptr->balance = sub_ptr->balance + set_value[0]; + sub_ptr->bundle_info.data += ( set_value[1] * 1024 * 1024); + sub_ptr->bundle_info.mo_voice += ( set_value[2] * 60 ); + sub_ptr->bundle_info.mt_voice += ( set_value[3] * 60 ); + sub_ptr->bundle_info.sms += set_value[4]; + sub_ptr->bundle_info.warning_sms_flag = set_value[6]; + + if(sub_ptr->bundle_info.validity_date < tvnow.tv_sec) + { + sub_ptr->bundle_info.validity_date = tvnow.tv_sec + set_value[5] * 24 * 3600; + } + else + { + sub_ptr->bundle_info.validity_date += set_value[5] * 24 * 3600; + } + } + + return 1; +} + +int GetAccountBundlePlanInfo(_account_info *ptr, long ret_value[6]) +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + int retval = 0; + int bundle_info_updated_flag = 1; + + PutLogFunID("GetAccountBundlePlanInfo"); + + head = ptr->head; + tail = ptr->tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + + // see if we have to set bundle to 0=================================== + if ((sub_ptr->bundle_info.validity_date > 0) && (sub_ptr->bundle_info.validity_date < tvnow.tv_sec))// 1) set bundle to 0, if expired when querying. + { + memset(&sub_ptr->bundle_info, 0x00, sizeof(_bundle_info)); + } + else if (((sub_ptr->bundle_info.validity_date >= tvnow.tv_sec) && (sub_ptr->bundle_info.data <= 0))\ + || ((sub_ptr->bundle_info.validity_date == 0) && (sub_ptr->bundle_info.data > 0)))// 2) set bundle to 0, if data == 0 and not expired + // && sub_ptr->bundle_info.mo_voice == 0 + // && sub_ptr->bundle_info.mt_voice == 0 + // && sub_ptr->bundle_info.sms == 0) + { + memset(&sub_ptr->bundle_info, 0x00, sizeof(_bundle_info)); + } + else + { + bundle_info_updated_flag = 0;// no change, so do not have to sync. + } + //===================================================== + + // return bundle when data > 0 and not expired. + if ((sub_ptr->bundle_info.data > 0) && (sub_ptr->bundle_info.validity_date >= tvnow.tv_sec)) + { + retval = 1; + } + // + + ret_value[0] = (sub_ptr->bundle_info.data /( 1024*1024)); + ret_value[1] = (sub_ptr->bundle_info.mo_voice / 60 ); + ret_value[2] = (sub_ptr->bundle_info.mt_voice / 60 ); + ret_value[3] = ( sub_ptr->bundle_info.sms ); + ret_value[4] = sub_ptr->bundle_info.validity_date; + ret_value[5] = sub_ptr->bundle_info.warning_sms_flag; + } + + if(bundle_info_updated_flag ) + { + SendAccountRealSync_2(ptr,0.0,0.0,OMC_OCODE_EDIT); + } + + return retval; +} + +extern void pps_print_event(u_char logMsisdnFlag,const char *fmt, ...); +long long pps_get_account_bundle_data(_state_data *shmp)// get remained Bytes from user bundle info +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("pps_get_account_bundle_data"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + /* + pps_print_event(shmp->process_info.logMsisdn,"[%04d] %s, bundle data=%lld, validity=%ld, now time=%ld", + shmp->process_info.portid, + __FUNCTION__, + sub_ptr->bundle_info.data, + sub_ptr->bundle_info.validity_date, + tvnow.tv_sec); + */ + if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) + { + return sub_ptr->bundle_info.data; + } + else + { + return 0; + } + } + + return 0; +} + +int pps_get_account_bundle_mo_voice(_state_data *shmp)// get remained Bytes from user bundle info +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("pps_get_account_bundle_mo_voice"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + + if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) + { + return sub_ptr->bundle_info.mo_voice; + } + else + { + return 0; + } + } + + return 0; +} + +int pps_update_account_bundle_mo_voice(_state_data *shmp, int seconds)// +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("pps_update_account_bundle_mo_voice"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + + if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) + { + sub_ptr->bundle_info.mo_voice += seconds; + if(sub_ptr->bundle_info.mo_voice <= 0) + { + sub_ptr->bundle_info.mo_voice = 0; + subscribe_bundle_plan_send_used_up_info((char *)shmp->caller_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); /* should only send MO voice is used up */ + } + } + else + { + return 0; + } + } + + return 1; +} + +int pps_get_account_bundle_mt_voice(_state_data *shmp)// +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("pps_get_account_bundle_mt_voice"); + + head = shmp->called_info.head; + tail = shmp->called_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + + if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) + { + return sub_ptr->bundle_info.mo_voice;// mt use the same bundle as mo + } + else + { + return 0; + } + } + + return 0; +} + +int pps_update_account_bundle_mt_voice(_state_data *shmp, int seconds)// +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("pps_update_account_bundle_mt_voice"); + + head = shmp->called_info.head; + tail = shmp->called_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + + if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) + { + sub_ptr->bundle_info.mo_voice += seconds;// mt use the same bundle as mo + if(sub_ptr->bundle_info.mo_voice <= 0) + { + sub_ptr->bundle_info.mo_voice = 0; + subscribe_bundle_plan_send_used_up_info((char *)shmp->called_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); /* should only send MT voice is used up */ + } + } + else + { + return 0; + } + } + + return 1; +} + + +int pps_get_account_bundle_mo_sms(_state_data *shmp)// get remained Bytes from user bundle info +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("pps_get_account_bundle_mo_sms"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + + if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) + { + return sub_ptr->bundle_info.sms; + } + else + { + return 0; + } + } + + return 0; +} + +int pps_update_account_bundle_mo_sms(_state_data *shmp, int count)// get remained Bytes from user bundle info +{ + _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + int head, tail; + + PutLogFunID("pps_get_account_bundle_mo_voice"); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + sub_ptr = &data_ptr->prepaid_info[head][tail]; + + // if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) + { + sub_ptr->bundle_info.sms += count; + if(sub_ptr->bundle_info.sms <= 0) + { + sub_ptr->bundle_info.sms = 0; + subscribe_bundle_plan_send_used_up_info((char *)shmp->caller_info.number, SMS_BUNDLE_PLAN_SMS_USEDUP); /* should only send MO SMS is used up */ + } + } + /* + else + { + return 0; + } + */ + } + + return 1; +} + +extern int ocs_get_charge_prefix(char *dialed_number, char *prefix, char *area_name, int *call_type); +extern int crm_check_if_cug_call(_account_info *caller, _account_info *called); +int BillingSMSProc(_state_data *shmp, int sms_num) +{ + float balance = 0, discount=100.0; + float mosms_unit_charge ; + int cos_id,tariff_id; + COSTable *cosTableItem = NULL; + int charge_num = sms_num, bundle_used_num = 0; + CosServiceControl *serviceControlItem = NULL; + + PutLogFunID("BillingSMSProc"); + + if(OCS_with_external_CRM()) + { + if(crm_check_if_cug_call(&shmp->caller_info, &shmp->called_info)) + { + mosms_unit_charge = 0; + shmp->process_info.rest_if.total_plan_value = 0; + shmp->process_info.rest_if.used_plan_value = 0; + } + else + mosms_unit_charge = shmp->process_info.rest_if.unit_charge * shmp->process_info.rest_if.tariff_discount / discount; + } + else + mosms_unit_charge = GetSMSTariff(shmp,shmp->caller_info.location); + + // Check Cap or Bundle is used================================ + cos_id = shmp->caller_info.cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + serviceControlItem = &cosTableItem->serviceControl[0]; + if(serviceControlItem->cap_or_bundle_in_tariff)// bundle is used, so we can set bundle flag and clear cap flag + { + shmp->process_info.bundle_flag = shmp->process_info.cap_flag; + shmp->process_info.cap_flag = 0; + } + //================================================== + + if(shmp->process_info.bundle_flag) + { + int left_mo_sms = 0; + + left_mo_sms = pps_get_account_bundle_mo_sms(shmp); + if(left_mo_sms > 0) + { + if (left_mo_sms >= charge_num) + { + shmp->caller_info.fee = 0; + shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + bundle_used_num = charge_num; + return bundle_used_num;// bundle charge num + } + else + { + charge_num -= left_mo_sms; + bundle_used_num = left_mo_sms; + } + } + else + { + shmp->process_info.bundle_flag = 0; + } + } + + if(shmp->process_info.cap_flag) + { + tariff_id=GetSubsCapTariffID(shmp,CAP_SMS); + if(tariff_id>=0) + { + mosms_unit_charge = GetSMSTariff(shmp,tariff_id); + /* there should always be DEFAULT tariff prefix */ + shmp->caller_info.location = tariff_id; + } + } + //no roaming fee charged for ROAMING SMS, 2005-05-09 + + switch(shmp->process_info.call_type) + { + case CT_MO_SM: + if(shmp->process_info.serviceType == SRV_SCRATCH_CARD_RECHARGE || + shmp->process_info.serviceType == SRV_RECHARGE_2TYPES || + shmp->process_info.serviceType == SRV_FEE_TRANSFER || + shmp->process_info.serviceType == SRV_FREE_SMS || + shmp->process_info.serviceType == SRV_CALL_ME_BACK || + shmp->process_info.serviceType == SRV_BUNDLE_PLAN || + shmp->process_info.serviceType == USSD_OC_BUNDLE_QUERY) + { + shmp->process_info.cap_flag = 0; + shmp->caller_info.fee = 0; + shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + return bundle_used_num; + } + + if(cosTableItem->serviceControl[0].moThresholdSet) + { + balance = (int)GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + + GetOverdraft(&shmp->caller_info) + - (cosTableItem->serviceControl[0].moMinimumBalance); + + if(balance<0) + { + shmp->caller_info.fee = 0; + shmp->caller_info.valid_time = 0; + shmp->called_info.fee = 0; + shmp->called_info.valid_time = 0; + return bundle_used_num; + } + } + + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info); + + if(shmp->process_info.serviceType == SRV_INQUIRY ) + { + shmp->process_info.cap_flag = 0; + if(!(cosTableItem->smsNotificationInquiry[0].chargeWhenInquiryBySMS)) + { /* not charging on SM inquring */ + shmp->caller_info.fee = 0; + shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; + /* should be a parameter */ + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + return bundle_used_num; + } + else + { + /* inquiry charged, recharge should be always free,not yet,2004-01-06 */ + if(IncreaseServiceSM(shmp->caller_info.head, + shmp->caller_info.tail)<= + (cosTableItem->smsNotificationInquiry[0].freeInquiryPerDay)) + { + shmp->caller_info.fee = 0; + shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + return bundle_used_num; + } + } + } + /* zero balance can't send free sms,06-02-27 */ + /* + if(balance == 0 && mosms_unit_charge==0) + { + shmp->caller_info.valid_time = 0; // should be a parameter + shmp->called_info.valid_time = 0; + shmp->process_info.tcos = CALLER_CREDIT_OUT; // no enough balance + } + else if(balance>=mosms_unit_charge) + */ + if(balance>=(mosms_unit_charge * charge_num)) + { + shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; /* should be a parameter */ + shmp->called_info.valid_time = 10*ONE_MINUTE_STATE_TIME; + shmp->caller_info.fee = mosms_unit_charge * charge_num; + shmp->called_info.fee = 0x00; + } + else + { + shmp->caller_info.valid_time = 0; /* should be a parameter */ + shmp->called_info.valid_time = 0; + shmp->process_info.tcos = CALLER_CREDIT_OUT; /* no enough balance */ + } + break; + default: + shmp->caller_info.valid_time = 0; + shmp->called_info.valid_time = 0; + shmp->process_info.tcos = CALLER_CREDIT_OUT; + break; + } + return bundle_used_num; +} + +int +ConferenceCallBillingProc(_state_data *shmp,int duration) +{ + float charge,balance; + int unit_time=60,unit_amount,tariff_id=0; + int cos_id; + COSTable *cosTableItem; + + PutLogFunID("ConferenceCallBillingProc"); + tariff_id = GetAccountZoneID(shmp->caller_info.head,shmp->caller_info.tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + if(shmp->caller_info.status != T_NORMAL || + tvnow.tv_sec>= GetExpiration(&shmp->caller_info)) + return FALSE; + cos_id = shmp->caller_info.cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + unit_time = blf_shmp->comm_tariff[tariff_id].ccChargeUnit; + if(unit_time<=0) unit_time = 60; + unit_amount = blf_shmp->comm_tariff[tariff_id].ccChargeAmount; + if(unit_amount<=0) unit_amount = 20; + + if(cosTableItem->serviceControl[0].moThresholdSet) + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info) + - cosTableItem->serviceControl[0].moMinimumBalance; + if(balance<0) + { + return FALSE; + } + + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info); + + charge = (duration * unit_amount*1.0) / unit_time; + + shmp->caller_info.charge = charge; + shmp->caller_info.fee = charge; + if(balance>=charge) return TRUE; + return FALSE; +} + +void ChangeTariffToCugTariff(_state_data *shmp,_bill_tariff *ptar){ + u_short rUnit=60; + float rAmount=0; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToCugTariff"); + tariff_id = shmp->caller_info.location; + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + rUnit = blf_shmp->comm_tariff[tariff_id].cugChargeUnit; + rAmount = blf_shmp->comm_tariff[tariff_id].cugChargeAmount; + + if(rUnit == 0) rUnit = 60; + tier = getCurrentTier(shmp,ptar); + ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit; +} + +void ChangeTariffToFavoriteCallTariff(_state_data *shmp,_bill_tariff *ptar) +{ + u_short rUnit=60; + float rAmount=0; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToFavoriteCallTariff"); + + if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL) + return; + tariff_id = shmp->caller_info.location; + + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + rUnit = blf_shmp->comm_tariff[tariff_id].favChargeUnit; + rAmount = blf_shmp->comm_tariff[tariff_id].favChargeAmount; + + if(rUnit ==0) rUnit = 60; + tier = getCurrentTier(shmp,ptar); + + ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit; +} + + +void ChangeTariffToMORoamingTariff(_state_data *shmp,_bill_tariff *ptar){ + u_short rUnit,Unit=0; + float rAmount,Amount=0; + u_char tier; + int tariff_id; + _bill_tariff const *moPtr; + + PutLogFunID("ChangeTariffToMORoamingTariff"); + moPtr = shmp->process_info.tariffMoReadOnly; + if(moPtr == NULL) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]ChangeTariffToMORoamingTariff,no mo tariff", + shmp->process_info.portid); + return; + } + tariff_id = shmp->caller_info.location; + Unit = moPtr->unit_time; + if(Unit == 0) Unit = 60; + + tier = getCurrentTier(shmp, (_bill_tariff *)moPtr); + Amount = moPtr->tierRating.rating[tier].base_fee; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + rUnit = blf_shmp->comm_tariff[tariff_id].roamingChargeUnit; + rAmount = blf_shmp->comm_tariff[tariff_id].roamingChargeAmount; + if(rUnit ==0) rUnit = 60; + + ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit + Amount; +} + +void ChangeTariffToMTRoamingTariff(_state_data *shmp,_bill_tariff *ptar) +{ + u_short rUnit,Unit; + float rAmount,base_fee; + int location; + char destination[128],inter_prefix[32]; + u_char tier,tierDest; + + _bill_tariff *ptrTemp,btar; + _bill_tariff const *mtPtr; + + PutLogFunID("ChangeTariffToMTRoamingTariff"); + + memset(&btar,0,sizeof(_bill_tariff)); + ptrTemp = &btar; + mtPtr = shmp->process_info.tariffMtReadOnly; + if(mtPtr == NULL) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]ChangeTariffToMTRoamingTariff,no mt tariff", + shmp->process_info.portid); + return; + } + + location = GetAccountZoneID(shmp->called_info.head, + shmp->called_info.tail); + + xap_get_interprefix((u8 *)inter_prefix); + + BcdToAscii(destination, (BYTE *)inter_prefix, 4); + StringCut(destination,'E'); + strcat(destination,shmp->cdr_info.locationNumber); + + shmp->process_info.tariff_flag = GetMOTariffData(shmp,ptrTemp, destination, location); + + if(shmp->process_info.tariff_flag <= 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]ChangeTariffToMTRoamingTariff,can't find prefix by:%s,assume basic fee and long fee as 0", + shmp->process_info.portid,destination); + } + + location = shmp->called_info.location; + rUnit = blf_shmp->comm_tariff[location].roamingChargeUnit; + rAmount = blf_shmp->comm_tariff[location].roamingChargeAmount; + if(rUnit ==0) rUnit = 60; + + Unit = mtPtr->unit_time; + if(Unit == 0) Unit = 60; + + tier = getCurrentTier(shmp, (_bill_tariff *)mtPtr); + tierDest = getCurrentTier(shmp,ptrTemp); + + base_fee = mtPtr->tierRating.rating[tier].base_fee; + + ptar->tierRating.rating[tier].base_fee = base_fee + Unit * rAmount /rUnit; + + Unit = ptrTemp->unit_time; + if(Unit == 0) Unit = 60; + rUnit = mtPtr->unit_time; + if(rUnit == 0) rUnit = 60; + + if(UnittierRating.rating[tier].long_distance_fee = + mtPtr->tierRating.rating[tier].long_distance_fee + ptrTemp->tierRating.rating[tierDest].long_distance_fee*rUnit/Unit; + } + else + { + ptar->tierRating.rating[tier].long_distance_fee = + ptrTemp->tierRating.rating[tierDest].long_distance_fee + mtPtr->tierRating.rating[tier].long_distance_fee * Unit / rUnit; + ptar->tierRating.rating[tier].base_fee = ptar->tierRating.rating[tier].base_fee * Unit / rUnit; + ptar->adjustment = mtPtr->adjustment * Unit / rUnit; + ptar->unit_time = mtPtr->unit_time * Unit / rUnit; + ptar->mini_unit = ptrTemp->mini_unit; + } +} + +void ChangeTariffToCfTariff(_state_data *shmp,_bill_tariff *ptar){ + u_short cfUnit; + float cfAmount; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToCfTariff"); + tariff_id = shmp->caller_info.location; + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + cfUnit = blf_shmp->comm_tariff[tariff_id].cfChargeUnit; + cfAmount = blf_shmp->comm_tariff[tariff_id].cfChargeAmount; + + if(cfUnit ==0) cfUnit = 60; + tier = getCurrentTier(shmp,ptar); + ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; +} + +void ChangeTariffToCfCugTariff(_state_data *shmp,_bill_tariff *ptar){ + u_short cfUnit; + float cfAmount; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToCfCugTariff"); + tariff_id = shmp->caller_info.location; + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + cfUnit = blf_shmp->comm_tariff[tariff_id].cf_cugChargeUnit; + cfAmount = blf_shmp->comm_tariff[tariff_id].cf_cugChargeAmount; + + if(cfUnit ==0) cfUnit = 60; + tier = getCurrentTier(shmp,ptar); + ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; +} + +void ChangeTariffToCfFavTariff(_state_data *shmp,_bill_tariff *ptar){ + u_short cfUnit; + float cfAmount; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToCfFavTariff"); + tariff_id = shmp->caller_info.location; + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + cfUnit = blf_shmp->comm_tariff[tariff_id].cf_favChargeUnit; + cfAmount = blf_shmp->comm_tariff[tariff_id].cf_favChargeAmount; + + if(cfUnit ==0) cfUnit = 60; + tier = getCurrentTier(shmp,ptar); + ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; +} + +void ChangeTariffToCugFavTariff(_state_data *shmp,_bill_tariff *ptar){ + u_short cfUnit; + float cfAmount; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToCugFavTariff"); + tariff_id = shmp->caller_info.location; + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + cfUnit = blf_shmp->comm_tariff[tariff_id].cug_favChargeUnit; + cfAmount = blf_shmp->comm_tariff[tariff_id].cug_favChargeAmount; + + if(cfUnit ==0) cfUnit = 60; + tier = getCurrentTier(shmp,ptar); + ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; +} + +void ChangeTariffToCfCugFavTariff(_state_data *shmp,_bill_tariff *ptar){ + u_short cfUnit; + float cfAmount; + u_short Unit=0; + u_char tier; + int tariff_id; + + PutLogFunID("ChangeTariffToCfCugFavTariff"); + tariff_id = shmp->caller_info.location; + Unit = ptar->unit_time; + if(Unit == 0) Unit = 60; + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + + cfUnit = blf_shmp->comm_tariff[tariff_id].cf_cug_favChargeUnit; + cfAmount = blf_shmp->comm_tariff[tariff_id].cf_cug_favChargeAmount; + + if(cfUnit ==0) cfUnit = 60; + tier = getCurrentTier(shmp,ptar); + ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; +} + +int GetMTTariffData(_state_data *shmp, + u_char tariffID, + _bill_tariff *ptar, + _account_info *pinfo, + _account_info *pcaller) +{ + int prefixIndex = DEFAULT_MT_BILLING,i; + int len=0,maxlen=0; + _bill_tariff *ptr; + int cos_id; + COSTable *cosTableItem; + + PutLogFunID("GetMTTariffData"); + + + cos_id = pinfo->cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(cosTableItem->serviceControl[0].mtChargeFlag==0) + { + ptar->call_type = 4; + ptar->free_time = 0; + ptar->unit_time = 60; + ptar->mini_unit = 1; + ptar->adjustment = 0; + memset(&ptar->tierRating,0,sizeof(TIER_RATING)); + return 1; + } + + if(tariffID>=MAX_ZONE_NUM ) + tariffID = 0; + + memset(ptar,0,sizeof(_bill_tariff)); + + for(i=1;icalled_tariff[tariffID][i]; + if(ptr->bill_id[0] == 0) continue; + len = strlen(ptr->bill_id); + + if(len>maxlen) + if(!strncasecmp((char *)pcaller->number,ptr->bill_id,len)) + { + maxlen = len; + prefixIndex = i; + } + } + memcpy(ptar,&blf_shmp->called_tariff[tariffID][prefixIndex],sizeof(_bill_tariff)); + shmp->process_info.tariffMtReadOnly = &blf_shmp->called_tariff[tariffID][prefixIndex]; + return 1; +} + +int cfLargeThancug(int tariff_id) +{ + _comm_tariff *commTariff; + + PutLogFunID("cfLargeThancug"); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; + commTariff = &ramshm_ptr->tariff_data.comm_tariff[tariff_id]; + if((commTariff->cfChargeAmount*commTariff->cugChargeUnit)> + (commTariff->cugChargeAmount*commTariff->cfChargeUnit)) + return 1; + else + return 0; +} + +int BillingProc(_state_data *shmp, int sub_flag0) +{ + int duration=0,overdraft=0,sub_flag; + int cos_id; + COSTable *cosTableItem; + CosServiceControl *serviceControlItem = NULL, *mtServiceCtrItem = NULL; + + PutLogFunID("BillingProc"); + + sub_flag = sub_flag0; + cos_id = shmp->caller_info.cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + serviceControlItem = &cosTableItem->serviceControl[0]; + + if (sub_flag || shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL) + { + if(shmp->context_info.callType == CT_MT_CALL) + { + shmp->process_info.tariff_flag = + GetMTTariffData(shmp, + shmp->called_info.location, + &shmp->process_info.tariff, + &shmp->called_info, + &shmp->charge_info); + } + else + { + if(shmp->process_info.serviceType == SRV_CRD + || + (shmp->process_info.serviceType == SRV_NORMAL_MO_CALL + && + shmp->process_info.callConnected == 1 + && + !ppsParam.serviceControl.vms_allways_go)) + { + GetMOTariffData(shmp, &shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); + shmp->process_info.tariff_flag = 1; + shmp->caller_info.valid_time = 12*ONE_MINUTE_STATE_TIME; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 12*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + return 1; + } + if(shmp->context_info.callType == CT_MO_CALL && + cosTableItem->smsNotificationInquiry[0].smsNotificationWhenBalanceInsufficient) + if(GetBalanceWithPromotionControl(shmp,&shmp->caller_info)< + cosTableItem->smsNotificationInquiry[0].insufficientBalanceThreshold) + { + shmp->process_info.pre_warning = 1; + shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; + } + if(shmp->process_info.mnp_status) + { + char billing_prefix[64]; + sprintf(billing_prefix,"%s%s",shmp->process_info.routing_number, + shmp->called_info.number); + + shmp->process_info.tariff_flag = + GetMOTariffData(shmp,&shmp->process_info.tariff, billing_prefix, shmp->caller_info.location); + /* parameter: continue or release the call */ + if(shmp->process_info.tariff_flag==0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\33[33m Calling ported number, but no RN+MSISDN(%s) billing prefix\33[0m", + billing_prefix); + DebugMsg(debugmib.display.asciiOut, + "\33[33m Use dialing prefix %s as billing prefix\33[0m", + shmp->charge_info.number); + } + shmp->process_info.tariff_flag = + GetMOTariffData(shmp, &shmp->process_info.tariff, + (char *)shmp->charge_info.number, + shmp->caller_info.location); + } + else + { + strcpy((char *)shmp->charge_info.number, billing_prefix); + } + } + else + { + shmp->process_info.tariff_flag = + GetMOTariffData(shmp,&shmp->process_info.tariff, + (char *)shmp->charge_info.number, + shmp->caller_info.location); + + } + /* check MO tariff cap flag here */ + /* added for cap call, 2007-10-25 */ + shmp->process_info.cap_flag = shmp->process_info.tariff.cap_flag; + // Check Cap or Bundle is used================================ + if(serviceControlItem->cap_or_bundle_in_tariff)// bundle is used, so we can set bundle flag and clear cap flag + { + shmp->process_info.bundle_flag = shmp->process_info.cap_flag; /* cap flag is reused as bundle call */ + shmp->process_info.cap_flag = 0; + } + //================================================== + + if(shmp->process_info.cap_flag>0) + { +// DebugMsg(debugmib.display.asciiOut,"CAP call, flag: %d", + // shmp->process_info.cap_flag); + shmp->caller_info.location = GetSubsCapTariffID(shmp,CAP_CALL); + GetMOTariffData(shmp,&shmp->process_info.tariff, + (char *)shmp->charge_info.number, + shmp->caller_info.location); + + } + + if(shmp->process_info.favoriteCall) + { + if(CheckFriendFamilyPlanFreeCallOrSMS(shmp->caller_info.head, shmp->caller_info.tail, 0, shmp->process_info.duration/CYCLE_STATE_INTERVAL)) + { + shmp->process_info.favoriteCall = FRIEND_FAMILY_FREE_CALL; + + memset(&shmp->process_info.tariff.tierRating, 0x00, sizeof(TIER_RATING)); + shmp->process_info.tariff.adjustment = 0; + shmp->process_info.tariff.cap_flag = 0; + } + else + { + IncreaseFriendFamilyFreeCallDuration(shmp->caller_info.head, + shmp->caller_info.tail, + shmp->process_info.duration); + shmp->process_info.favoriteCall = FRIEND_FAMILY_CALL; + } + } + if(serviceControlItem->moThresholdSet && shmp->process_info.favoriteCall != FRIEND_FAMILY_FREE_CALL) + { + if((GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info)) + < (serviceControlItem->moMinimumBalance)) + { + shmp->caller_info.valid_time = 0; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 0; + shmp->called_info.fee = 0; + return 0; + } + } + + } + }// if sub_flag + + switch(shmp->context_info.callType){ + case CT_MT_CALL: + switch(shmp->called_info.status) + { + case T_FRESH: + case T_SUSPEND: + case T_BLACKLIST: + case T_EXTERNAL: + case T_RELEASED: + shmp->caller_info.valid_time = 0; + shmp->called_info.valid_time = 0; + shmp->process_info.tcos = CALLED_STATUS_ERROR; + shmp->process_info.voiceID = MT_ERROR_ACCOUNT_STATUS; + return FALSE; + break; + default: + break; + } + + // Check Cap or Bundle is used================================ + mtServiceCtrItem = &ppsParam.ppsTables.cosTable[shmp->called_info.cos_id].serviceControl[0]; + if(mtServiceCtrItem->cap_or_bundle_in_tariff)// bundle is used, so we can set bundle flag + { + shmp->process_info.bundle_flag = shmp->process_info.tariff.cap_flag; + } + //================================================== + + if(shmp->process_info.bundle_flag) + { + int left_mt_voice_seconds = 0; + + left_mt_voice_seconds = pps_get_account_bundle_mt_voice(shmp); + if(left_mt_voice_seconds > 0) + { + if(left_mt_voice_seconds > shmp->process_info.tariff.unit_time) + left_mt_voice_seconds = shmp->process_info.tariff.unit_time; + shmp->caller_info.valid_time = left_mt_voice_seconds*CYCLE_STATE_INTERVAL; + + shmp->caller_info.fee = 0; + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + //DebugMsg(debugmib.display.asciiOut, "BillingProc()->%s allocate bundle mt voice[%d]", + // shmp->caller_info.number, left_mt_voice_seconds); + + return 1; + } + else + { + /* + if(shmp->process_info.duration > 1) + { + subscribe_bundle_plan_send_used_up_info(shmp->caller_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); + } + */ + + shmp->process_info.bundle_flag = 0; + } + } + + if(shmp->process_info.chargedTime==0 && shmp->process_info.tariff.free_time) + { + shmp->called_info.valid_time = + shmp->process_info.tariff.free_time*CYCLE_STATE_INTERVAL; + shmp->called_info.fee = 0; + + } + else + { + + sub_flag = shmp->process_info.chargedTime; + if(shmp->process_info.tariff.free_time) + sub_flag = shmp->process_info.chargedTime - 1; + + overdraft = GetOverdraft(&shmp->called_info); + if(!sub_flag && overdraft<0){ + overdraft = 0; + } + shmp->called_info.valid_time = + GetValidTime( shmp, + tvnow.tv_sec, + //shmp->cdr_info.answertime, + &shmp->process_info.tariff, + GetBalanceWithPromotionControl(shmp,&shmp->called_info), + sub_flag, + overdraft); + + duration = (int)( shmp->called_info.valid_time / CYCLE_STATE_INTERVAL); + shmp->called_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration, tvnow.tv_sec,sub_flag); + if(isPoolChildReachFeeLimit(&shmp->called_info) == 2) + { + pps_print_error(shmp->process_info.logMsisdn,"%s child account,reach limited fee",shmp->called_info.number); + shmp->caller_info.valid_time = 0; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 0; + shmp->called_info.fee = 0; + shmp->process_info.tcos = CALLER_REACH_CHARGE_LIMIT; + shmp->process_info.pre_warning = 1; + shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; + return -1; + } + } + shmp->caller_info.fee = 0; + shmp->caller_info.valid_time = shmp->called_info.valid_time; + break; + case CT_MF_CALL: + case CT_MO_CALL: + if(shmp->process_info.serviceType == SRV_CRD + || + (shmp->process_info.serviceType == SRV_NORMAL_MO_CALL + && + shmp->process_info.callConnected == 1 + && + !ppsParam.serviceControl.vms_allways_go)) + { + shmp->process_info.tariff_flag = 1; + shmp->caller_info.valid_time = 6*ONE_MINUTE_STATE_TIME; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 6*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + return 1; + } + switch(shmp->caller_info.status) + { + case T_FRESH: + case T_SUSPEND: + case T_BLACKLIST: + case T_EXTERNAL: + case T_RELEASED: + shmp->caller_info.valid_time = 0; + shmp->called_info.valid_time = 0; + shmp->process_info.tcos = CALLER_STATUS_ERROR; + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + return FALSE; + break; + default: + break; + } + overdraft = GetOverdraft(&shmp->caller_info); + if(shmp->process_info.bundle_flag )/* bundle mo call charging */ + { + int left_mo_voice_seconds = 0; + + left_mo_voice_seconds = pps_get_account_bundle_mo_voice(shmp); + if(left_mo_voice_seconds > 0) + { + if(left_mo_voice_seconds > shmp->process_info.tariff.unit_time) + left_mo_voice_seconds = shmp->process_info.tariff.unit_time; + shmp->caller_info.valid_time = left_mo_voice_seconds*CYCLE_STATE_INTERVAL; + + shmp->caller_info.fee = 0; + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + //DebugMsg(debugmib.display.asciiOut, "BillingProc()->%s allocate bundle mo voice[%d]", + // shmp->caller_info.number, left_mo_voice_seconds); + + return 1; + } + else + { + /* + if(shmp->process_info.duration > 1) + { + subscribe_bundle_plan_send_used_up_info(shmp->caller_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); + } + */ + + shmp->process_info.bundle_flag = 0; + } + } + + if(shmp->process_info.chargedTime==0 && shmp->process_info.tariff.free_time) + { + shmp->caller_info.valid_time = + shmp->process_info.tariff.free_time*CYCLE_STATE_INTERVAL; + shmp->caller_info.fee = 0; + if(GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+overdraft< getCurrentFee(shmp)) + { + shmp->caller_info.valid_time = 0; + } + } + else + { + if(shmp->process_info.cap_flag>0 && sub_flag0 == 0) /* re-get tariff for cap call during the call */ + { + shmp->caller_info.location = GetSubsCapTariffID(shmp,CAP_CALL); + GetMOTariffData(shmp,&shmp->process_info.tariff, + (char *)shmp->charge_info.number, + shmp->caller_info.location); + + } + + sub_flag = shmp->process_info.chargedTime; + if(shmp->process_info.tariff.free_time) + sub_flag = shmp->process_info.chargedTime - 1; + + if(!sub_flag && overdraft<0){ + overdraft = 0; + } + shmp->caller_info.valid_time = + GetValidTime( shmp, + tvnow.tv_sec, + //shmp->cdr_info.answertime, + &shmp->process_info.tariff, + GetBalanceWithPromotionControl(shmp,&shmp->caller_info), + sub_flag, + overdraft); + + duration = (int)( shmp->caller_info.valid_time + / CYCLE_STATE_INTERVAL); + shmp->caller_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration,tvnow.tv_sec,sub_flag); + if(isPoolChildReachFeeLimit(&shmp->caller_info) == 2) + { + pps_print_error(shmp->process_info.logMsisdn,"%s child account,reach limited fee",shmp->caller_info.number); + shmp->caller_info.valid_time = 0; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 0; + shmp->called_info.fee = 0; + shmp->process_info.tcos = CALLER_REACH_CHARGE_LIMIT; + shmp->process_info.pre_warning = 1; + shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; + return -1; + } + } + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + break; + default: + shmp->caller_info.valid_time = 0; + shmp->called_info.valid_time = 0; + break; + } + shmp->process_info.chargedTime ++; + return SUCCESS; +} + +int crm_check_if_cug_call(_account_info *caller, _account_info *called) +{ + if(caller == NULL || called == NULL) + return 0; + if(caller->cug_id == 0 || called->cug_id == 0) + return 0; + if(caller->cug_id != called->cug_id) + return 0; + + return 1; +} + +extern int ocs_get_crm_free_seconds(); +int BillingProc_crm(_state_data *shmp, int sub_flag0) +{ + int duration=0,overdraft=0,sub_flag; + int cos_id; + COSTable *cosTableItem; + //CosServiceControl *mtServiceCtrItem = NULL;//*serviceControlItem = NULL, + char prefix[128], areaName[32]=""; + + PutLogFunID("BillingProc_crm"); + + sub_flag = sub_flag0; + cos_id = shmp->caller_info.cos_id; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + //serviceControlItem = &cosTableItem->serviceControl[0]; + + if(shmp->context_info.callType == CT_MT_CALL) + { + switch(shmp->called_info.status) + { + case T_FRESH: + //case T_SUSPEND: + case T_BLACKLIST: + case T_EXTERNAL: + case T_DISABLE: + case T_RELEASED: + shmp->caller_info.valid_time = 0; + shmp->called_info.valid_time = 0; + shmp->process_info.tcos = CALLER_STATUS_ERROR; + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + return FALSE; + break; + default: + break; + } + + shmp->process_info.tariff_flag = 1; + shmp->caller_info.valid_time = 12*ONE_MINUTE_STATE_TIME; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 12*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + shmp->process_info.call_type = CT_LOCAL_CALL_IN; + + if(ocs_get_charge_prefix( (char *)shmp->caller_info.number, prefix, areaName, &shmp->process_info.tariff.call_type) == 0) + return 1; + if(shmp->process_info.tariff.call_type == CT_LOCAL_CALL_OUT) //to get incoming call type + { + shmp->process_info.tariff.call_type = CT_LOCAL_CALL_IN; + shmp->process_info.call_type = CT_LOCAL_CALL_IN; + } + else if(shmp->process_info.tariff.call_type == CT_TRUNK_CALL_OUT) + { + shmp->process_info.tariff.call_type = CT_TRUNK_CALL_IN; + shmp->process_info.call_type = CT_TRUNK_CALL_IN; + } + else if(shmp->process_info.tariff.call_type == CT_IDD_CALL_OUT) + { + shmp->process_info.tariff.call_type = CT_IDD_CALL_IN; + shmp->process_info.call_type = CT_IDD_CALL_IN; + } + + return 1; + + } + + if(shmp->process_info.rest_if.query_tariff_status == 2) + { + shmp->process_info.tariff_flag = 1; + + shmp->process_info.tariff.unit_time = shmp->process_info.rest_if.unit; + shmp->process_info.tariff.tierRating.tierNumber = 0; + shmp->process_info.tariff.tierRating.rating[0].base_fee = shmp->process_info.rest_if.unit_charge; + shmp->process_info.tariff.tierRating.rating[0].units = 1; + shmp->process_info.tariff.tierRating.rating[0].long_distance_fee = 0; + shmp->process_info.tariff.mini_unit = 1; + + } + else + { + shmp->process_info.tariff_flag = 0; + } + + switch(shmp->caller_info.status) + { + case T_FRESH: + case T_SUSPEND: + case T_BLACKLIST: + case T_EXTERNAL: + case T_DISABLE: + case T_RELEASED: + shmp->process_info.tariff_flag = 1; + + shmp->caller_info.valid_time = 0; + shmp->called_info.valid_time = 0; + shmp->process_info.tcos = CALLER_STATUS_ERROR; + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.pre_warning = 1; + return FALSE; + break; + default: + break; + } + + if(crm_check_if_cug_call(&shmp->caller_info, &shmp->called_info)) + //if(shmp->caller_info.cug_id>0 && (shmp->caller_info.cug_id == shmp->called_info.cug_id )) + { + shmp->process_info.tariff_flag = 1; + shmp->caller_info.valid_time = 120*ONE_MINUTE_STATE_TIME; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 120*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + return 1; + } + + shmp->caller_info.free_flag = 0; + + if(shmp->context_info.callType == CT_MO_CALL && + cosTableItem->smsNotificationInquiry[0].smsNotificationWhenBalanceInsufficient) + { + if(GetBalanceWithPromotionControl(shmp,&shmp->caller_info)< + cosTableItem->smsNotificationInquiry[0].insufficientBalanceThreshold) + { + shmp->process_info.pre_warning = 1; + shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; + } + } + else + { + if ((shmp->process_info.rest_if.total_plan_value> 0) && + (shmp->process_info.rest_if.used_plan_value < shmp->process_info.rest_if.total_plan_value)) + { + if(sub_flag) + { + if(shmp->process_info.tariff.call_type != CT_IDD_CALL_OUT) + { + int free_secs = ocs_get_crm_free_seconds(); + if(free_secs>0) + { + shmp->caller_info.free_flag = 1; + shmp->caller_info.valid_time = free_secs*CYCLE_STATE_INTERVAL; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + shmp->called_info.fee = 0; + return 1; + } + } + } + + int left_plan_value = 0; + + left_plan_value = (shmp->process_info.rest_if.total_plan_value - shmp->process_info.rest_if.used_plan_value); + if(left_plan_value > shmp->process_info.tariff.unit_time) + left_plan_value = shmp->process_info.tariff.unit_time; + shmp->caller_info.valid_time = (left_plan_value) * CYCLE_STATE_INTERVAL; + shmp->caller_info.fee = 0; + goto billing_crm_ret; + } + + { + shmp->caller_info.valid_time = + GetValidTime( shmp, + tvnow.tv_sec, + &shmp->process_info.tariff, + GetBalanceWithPromotionControl(shmp,&shmp->caller_info), + sub_flag, + overdraft); + duration = (int)( shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL); + shmp->caller_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration,tvnow.tv_sec,sub_flag); + } + + if(sub_flag && (shmp->caller_info.valid_time) > CYCLE_STATE_INTERVAL) + { + if(shmp->process_info.tariff.call_type != CT_IDD_CALL_OUT) + { + int free_secs = ocs_get_crm_free_seconds(); + if(free_secs>0) + { + shmp->caller_info.free_flag = 1; + shmp->caller_info.valid_time = free_secs*CYCLE_STATE_INTERVAL; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + shmp->called_info.fee = 0; + return 1; + } + } + } + } + +billing_crm_ret: + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + + shmp->process_info.chargedTime ++; + return SUCCESS; +} + +extern float ocs_get_calling_card_left_balance(int head, int tail); +int BillingProc_ccc(_state_data *shmp, int sub_flag0) +{ + int duration=0,overdraft=0,sub_flag; + //int cos_id; + //COSTable *cosTableItem; + //CosServiceControl *serviceControlItem = NULL, *mtServiceCtrItem = NULL; + int balance = 0; + + PutLogFunID("BillingProc_ccc"); + + sub_flag = sub_flag0; + //cos_id = shmp->caller_info.cos_id; + //cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + //serviceControlItem = &cosTableItem->serviceControl[0]; + shmp->caller_info.location = shmp->caller_info.cos_id; + + if (sub_flag ) + { + shmp->process_info.tariff_flag = + GetMOTariffData(shmp,&shmp->process_info.tariff, + (char *)shmp->charge_info.number, + shmp->caller_info.location); + balance = (int)ocs_get_calling_card_left_balance(shmp->card_info.cardhead, shmp->card_info.cardtail); + shmp->card_info.balance = balance; + + }// if sub_flag + else + { + if(shmp->card_info.balance > shmp->card_info.cc_call_charge) + balance = shmp->card_info.balance; + else + balance = 0; + } + + switch(shmp->context_info.callType){ + case CT_MO_CC_CALL: + if( shmp->process_info.callConnected == 1 ) + { + shmp->process_info.tariff_flag = 1; + shmp->caller_info.valid_time = 6*ONE_MINUTE_STATE_TIME; + shmp->caller_info.fee = 0; + shmp->called_info.valid_time = 6*ONE_MINUTE_STATE_TIME; + shmp->called_info.fee = 0; + return 1; + } + + + if(shmp->process_info.chargedTime==0 && shmp->process_info.tariff.free_time) + { + shmp->caller_info.valid_time = + shmp->process_info.tariff.free_time*CYCLE_STATE_INTERVAL; + shmp->caller_info.fee = 0; + } + else + { + if(shmp->process_info.cap_flag>0 && sub_flag0 == 0) /* re-get tariff for cap call during the call */ + { + GetMOTariffData(shmp,&shmp->process_info.tariff, + (char *)shmp->charge_info.number, + shmp->caller_info.location); + + } + + sub_flag = shmp->process_info.chargedTime; + if(shmp->process_info.tariff.free_time) + sub_flag = shmp->process_info.chargedTime - 1; + + shmp->caller_info.valid_time = + GetValidTime( shmp, + tvnow.tv_sec, + &shmp->process_info.tariff, + balance, + sub_flag, + overdraft); + + duration = (int)( shmp->caller_info.valid_time / CYCLE_STATE_INTERVAL); + shmp->caller_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration,tvnow.tv_sec,sub_flag); + } + shmp->called_info.fee = 0; + shmp->called_info.valid_time = shmp->caller_info.valid_time; + break; + default: + shmp->caller_info.valid_time = 0; + shmp->called_info.valid_time = 0; + break; + } + shmp->process_info.chargedTime ++; + return SUCCESS; +} + +int IsEnableToCall_ccc(int proc_id) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + //int call_type=0,rst; + //COSTable *cosTableItem; + + PutLogFunID("IsEnableToCall"); + + shmp += proc_id; + + //call_type = shmp->context_info.callType; + + if(shmp->process_info.tcos == SRVICE_NOT_SUBSCRIBERED) + return FALSE; + + + + if(shmp->process_info.tariff_flag ==0) + { + shmp->process_info.tcos = TARIFF_NOT_SET; + shmp->process_info.voiceID = CALLED_TARIFF_NOT_SET; + return FALSE; + } + + if(shmp->caller_info.valid_time <= 0) + { + shmp->process_info.tcos = CALLER_CREDIT_OUT; + shmp->process_info.voiceID = LOW_ACCOUNT_BALANCE; + return FALSE; + } + return TRUE; +} + +void +SetCallType(_state_data *shmp, int type) +{ + switch(type) + { + case 0: + if(shmp->context_info.callType == CT_MT_CALL) + shmp->process_info.call_type = CT_LOCAL_CALL_IN; + else + shmp->process_info.call_type = CT_LOCAL_CALL_OUT; + break; + case 1: + shmp->process_info.call_type = CT_NDD_CALL_OUT; + break; + case 2: + shmp->process_info.call_type = CT_IDD_CALL_OUT; + break; + case 4: + shmp->process_info.call_type = CT_LOCAL_CALL_IN; + break; + case 5: + shmp->process_info.call_type = CT_TRUNK_CALL_IN; + break; + default: + shmp->process_info.call_type = type; + break; + } +} + +const int +IsNormalRechargeCard(_state_data *shmp) +{ + u_char bcd[CONTEXT_BLOCK_SIZE]; + u_long expiration=0; + + PutLogFunID("IsNormalRechargeCard"); + + memcpy(bcd, &shmp->context_info.context[1], sizeof(_RCI_)); + expiration = ((_RCI_ *)bcd)->expiry_date; + if (((_RCI_ *) bcd)->card_status == T_FRESH + && (u_long) tvnow.tv_sec < expiration) + { + return TRUE; + } + else + { + return FALSE; + } +} + +int GetRechargeCardFaceValue(_state_data *shmp) +{ + u_char bcd[CONTEXT_BLOCK_SIZE]; + + PutLogFunID("GetRechargeCardFaceValue"); + + memcpy(bcd, shmp->context_info.context,//+1 , //sizeof(_RSIR_), + sizeof(_RCI_)); + return ((_RCI_ *) bcd)->face_value; +} + +int GetRechargeCardValidTime(_state_data *shmp) +{ + u_char bcd[CONTEXT_BLOCK_SIZE]; + + PutLogFunID("GetRechargeCardValidTime"); + + memcpy(bcd, shmp->context_info.context,//+1, //+sizeof(_RSIR_), + sizeof(_RCI_)); + return ((_RCI_ *) bcd)->valid_time; +} + +static void PureDigitAscii(u_char *string) +{ + int loop,len; + + len = strlen((char *)string); + for(loop=0;loop'9') + { + string[loop] = 0; + break; + } + } + string[loop] = 0; +} + +char +GetTariffLacInfo(u_char *cgi) +{ + int loc = -1, loop, matchFlag=0,len; + u_short cell, lac; + u_char MCC[32]={0},MNC[32]={0}; + BasicTariffZone *pBTZ; + + PutLogFunID("GetTariffLacInfo"); + + ppsBcdToAsciiR((char *)MCC,cgi,4); + PureDigitAscii(MCC); + + ppsBcdToAsciiR((char *)MNC,&cgi[2],2); + PureDigitAscii(MNC); + + lac = cgi[3] * 256 + cgi[4]; + cell = cgi[5] * 256 + cgi[6]; + + if(cgi[0]==0 && lac==0 && cell==0) //CF /MT call + return loc; + + for(loop=0;loopexistFlag == FALSE) + continue; + matchFlag = 0; + len = strlen((char *)pBTZ->mcc); + if(len == 0) + continue; + if(memcmp(pBTZ->mcc,MCC,len) == 0) + { + len = strlen((char *)pBTZ->mnc); + if(len == 0) + { + matchFlag = 1; + } + else if(memcmp(pBTZ->mnc,MNC,len) ==0 ) + { + if(ppsParam.serviceControl.charge_by_lac_flag == 1) + { + if(pBTZ->cellId == cell) + matchFlag = 1; + } + else + { + if(pBTZ->lac != 0xFFFF) + { + if(pBTZ->cellId != 0xFFFF) + { + if(pBTZ->cellId == cell + && pBTZ->lac == lac) + { + matchFlag = 1; + } + } + else if(pBTZ->lac == lac) + { + matchFlag = 1; + } + } + else + { + matchFlag = 1; + }/* lac */ + } + }/* mcc&mnc */ + + if(matchFlag) + { + return loop; + } + }//if mcc + }/* for */ + return loc; +} + + +int GetAccountZoneIDByLocationInfo(int index) +{ + return ppsParam.ppsTables.basicTariffZone[index].moTariffId%MAX_ZONE_NUM; +} + +int GetAccountMTZoneIDByLocationInfo(int index) +{ + return ppsParam.ppsTables.basicTariffZone[index].mtTariffId%MAX_ZONE_NUM; +} + +void CheckWetherRoamingUser(_state_data *shmp) +{ + _prepaid_data *user_shmp=&ramshm_ptr->prepaid_data; + _account_info *ptr; + int loop; + + PutLogFunID("CheckWetherRoamingUser"); + ptr = &shmp->caller_info; + + shmp->process_info.roamingFlag = 1; + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + for(loop=0;looplocation == + user_shmp->prepaid_info[ptr->head][ptr->tail].home_location[loop]) + { + shmp->process_info.roamingFlag = 0; + return; + } + } + } + pps_print_event(shmp->process_info.logMsisdn,"%s is a MO roaming user",shmp->caller_info.number); +} + +void CheckWetherRoamingMTUser(_state_data *shmp) +{ + _prepaid_data *user_shmp=&ramshm_ptr->prepaid_data; + _account_info *ptr; + int loop; + + PutLogFunID("CheckWetherRoamingMTUser"); + ptr = &shmp->called_info; + + shmp->process_info.roamingFlag = 1; + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + for(loop=0;looplocation == + user_shmp->prepaid_info[ptr->head][ptr->tail].home_location[loop]) + { + shmp->process_info.roamingFlag = 0; + return; + } + } + } + pps_print_event(shmp->process_info.logMsisdn,"%is a MT roaming user",shmp->called_info.number); +} + +/* get HPLMN from xapp , 2003-10-23 */ +void SetRoamingFlag(_state_data *shmp) +{ + char plmn[32]={""},buf[32]={""}; + int plmnlen; + + u_char CC[32],NDC[32]; + + PutLogFunID("SetRoamingFlag"); + + xap_get_cc(CC); + xap_get_ndc(NDC); + + BcdToAscii(plmn,CC,4); + StringCut(plmn,'E'); + BcdToAscii(buf,NDC,6); + StringCut(buf,'E'); + strcat(plmn,buf); + plmnlen = strlen(plmn); + + + if(!strncasecmp(shmp->cdr_info.locationNumber,plmn,plmnlen)) + { + shmp->process_info.roamingFlag = 0; + }else{ + shmp->process_info.roamingFlag = 1; + } + +} + +void +SetLocationInfo(u_char *cgi, u_short proc_id) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SetLocationInfo"); + + shmp += proc_id; + + memcpy(shmp->cdr_info.cgi,cgi,7); + +} + +u_long +GetTimeFunnel(u_short hour, u_short minute, u_short second) +{ + int funnel=0; + + PutLogFunID("GetTimeFunnel"); + + funnel = ((hour-GetTmHour()) * 60 * 60 ) + + ((minute - GetTmMinute() ) * 60) + + (second - GetTmSecond()); + return (funnel <= 0) ? (funnel+24*60*60)*CYCLE_STATE_INTERVAL + : funnel*CYCLE_STATE_INTERVAL; +} + +int +IsEnablePeriodicCharge(int head, int tail) +{ + _prepaid_info *shmp=NULL; + + PutLogFunID("IsEnablePeriodicCharge"); + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if ( shmp->msisdn[MAX_MSISDN_BLEN-1] != 0 + && ((shmp->status == T_NORMAL ) + || (shmp->status == T_BLACKLIST) + || (shmp->status == T_SUSPEND )) + && shmp->mt_expiration_date>=tvnow.tv_sec + && shmp->rent_type != 0) + return TRUE; + else + return FALSE; +} + +int +IsEnablePeriodicAction(int head, int tail) +{ + _prepaid_info *shmp=NULL; + + PutLogFunID("IsEnablePeriodicAction"); + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if ( shmp->msisdn[MAX_MSISDN_BLEN-1] != 0 + && ((shmp->status == T_NORMAL ) + || (shmp->status == T_BLACKLIST) + || (shmp->status == T_SUSPEND )) + && shmp->mt_expiration_date>=tvnow.tv_sec) + return TRUE; + else + return FALSE; +} + +float GetAccountBalance(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountBalance"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + return (shmp->prepaid_info[head][tail].balance + + shmp->prepaid_info[head][tail].promo_balance); + return FALSE; +} + +int GetAccountVoiceID(int head,int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountVoiceID"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + return shmp->prepaid_info[head][tail].language_type; + return 0; + +} + +int +GetUserType(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetUserType"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + return shmp->prepaid_info[head][tail].rent_type; + return FAILURE; +} + +int +GetPeriodicChargeDate(int tariff_id,int id) +{ + _rent_tariff *shmp=NULL; + + PutLogFunID("GetPeriodicChargeDate"); + + if (id < MAX_RENT_TARIFF) { + shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; + return shmp->charge_date; + } else + return 32; +} + +int +GetPeriodicTariffFee(int tariff_id,int id) +{ + _rent_tariff *shmp=NULL; + int rent_amount = 0; + + PutLogFunID("GetPeriodicTariffFee"); + + if (id < MAX_RENT_TARIFF) { + shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; + rent_amount = (int)shmp->rent_amount; + } + return rent_amount; +} + +short +GetPeriodicTariffDate(int tariff_id,int id) +{ + _rent_tariff *shmp=NULL; + + PutLogFunID("GetPeriodicTariffDate"); + + if (id < MAX_RENT_TARIFF) { + shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; + return shmp->charge_date; + } else + return FAILURE; +} + +short +GetPeriodicTariffType(int tariff_id,int id) +{ + _rent_tariff *shmp=NULL; + + PutLogFunID("GetPeriodicTariffType"); + + if (id < MAX_RENT_TARIFF) { + shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; + return shmp->rent_type; + } else + return FAILURE; +} + +void +UpdateAccountBalance(int head, int tail, float charge) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountBalance"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + shmp->prepaid_info[head][tail].balance = shmp->prepaid_info[head][tail].balance + charge; + if(shmp->prepaid_info[head][tail].balance<0) + { + shmp->prepaid_info[head][tail].balance = 0; + } + + } +} + +void UpdateAccountOverdraft(int head, int tail, long overdraft) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountOverdraft"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + shmp->prepaid_info[head][tail].overdraft = overdraft; +} + +void UpdateAccountPromotionBalance(int head, int tail, float charge) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountPromotionBalance"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + shmp->prepaid_info[head][tail].promo_balance = shmp->prepaid_info[head][tail].promo_balance+charge; + +} + +void UpdateAccountPromotionExpiryDay(int head, int tail, int days) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountPromotionExpiryDay"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + if(days>0 ) + { + if(shmp->prepaid_info[head][tail].promo_date< tvnow.tv_sec + days*24*3600) + shmp->prepaid_info[head][tail].promo_date = tvnow.tv_sec + days*24*3600; + } + else + shmp->prepaid_info[head][tail].promo_date = + shmp->prepaid_info[head][tail].mo_expiration_date; + } +} + +void UpdateAccountCUGStatus(_prepaid_info *user_info_ptr, u8 cug_status) +{ + if(user_info_ptr == NULL) + return; + user_info_ptr->crm_info.vas_cug_state = cug_status; +} + +u_long +GetAccountFirstUsedDate(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountFirstUsedDate"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + return shmp->prepaid_info[head][tail].first_used_date; + return FALSE; +} + +int MsisdnToLong(u_long *ulmsisdn, char *cmsisdn) +{ + int len,len1; + char tmpbuf[64],buf[64]; + + PutLogFunID("MsisdnToLong"); + + len = cmsisdn[9]; + if(len>18) len = 18; + len1 = len; + if(len %2 !=0) len1 = len + 1; + + BcdToAscii(tmpbuf, (BYTE *)cmsisdn,len1); + memcpy(buf,tmpbuf,len); + buf[len] = 0; + *ulmsisdn = atol(buf); + + return 1; +} + +int +GetAccountMsisdnStr(int head, int tail,u_char *msisdn) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + int len; + + PutLogFunID("GetAccountMsisdn"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + len = shmp->prepaid_info[head][tail].msisdn[MAX_MSISDN_BLEN-1]; + BcdToAscii((char *)msisdn, shmp->prepaid_info[head][tail].msisdn, (len+1)/2*2); + msisdn[len]=0; + return TRUE; + } + return FALSE; +} + +int +GetAccountMsisdn(int head, int tail,u_char *msisdn) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + int len; + + PutLogFunID("GetAccountMsisdn"); + + if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) + { + // MsisdnToLong(&msisdn,shmp->prepaid_info[head][tail].msisdn); + len = shmp->prepaid_info[head][tail].msisdn[MAX_MSISDN_BLEN-1]; + memcpy(msisdn,shmp->prepaid_info[head][tail].msisdn,MAX_MSISDN_BLEN-1); + + if(len%2==0){ + msisdn[len/2]=0xFF; + }else{ + msisdn[(len)/2] |= 0x0F; + } + return TRUE; + } + return FALSE; +} + + +void +UpdateAccountFirstUsedDate(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + char date_buf[32]; + + PutLogFunID("UpdateAccountFirstUsedDate"); + + GetTmDate(date_buf); + strcat(date_buf, "000000"); + shmp->prepaid_info[head][tail].first_used_date = + MakeTime(NULL, date_buf); +} + +void +UpdateAccountStatus(int head, int tail, int status) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountStatus"); + + shmp->prepaid_info[head][tail].status = status; +} + +void +UpdateAccountRechargeFail(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("UpdateAccountRechargeFail"); + shmp->prepaid_info[head][tail].recharge_fail ++; +} + +u_short +GetAccountRechargeFail(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("GetAccountRechargeFail"); + + return shmp->prepaid_info[head][tail].recharge_fail; +} + +void +ResetAccountRechargeFail(int head, int tail) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + + PutLogFunID("ResetAccountRechargeFail"); + + shmp->prepaid_info[head][tail].recharge_fail = 0; +} + +int isAccountExpired(_account_info *ptr) +{ + if(GetExpiration(ptr) < tvnow.tv_sec) + return 1; + return 0; + +} +/* If the call is valid or invalid + 0: invalid, 1: valid + */ +int +IsEnableToCall(int proc_id) +{ + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + int call_type=0,rst; + COSTable *cosTableItem; + + PutLogFunID("IsEnableToCall"); + + shmp += proc_id; + + call_type = shmp->context_info.callType; + + if(shmp->process_info.tcos == SRVICE_NOT_SUBSCRIBERED) + return FALSE; + + if(call_type == CT_MO_SM) + { + rst = isPoolChildReachSMSLimit(shmp); + if(rst) + { + switch(rst) + { + case 1: + shmp->process_info.tcos= CALLER_REACH_SMS_LIMIT; + break; + case 2: + shmp->process_info.tcos= CALLER_REACH_CHARGE_LIMIT; + break; + } + return FALSE; + } + + if ((shmp->caller_info.valid_time > 0 + && tvnow.tv_sec <= GetExpiration(&shmp->caller_info))) + { + return TRUE; + } + + if (tvnow.tv_sec > GetExpiration(&shmp->caller_info) ) + { + shmp->process_info.tcos= CALLER_EXPIRIED; + return FALSE; + } + else if (shmp->caller_info.valid_time <= 0 ) + { + shmp->process_info.tcos= CALLER_CREDIT_OUT; + return FALSE; + } + } + + switch(call_type) + { + case CT_MT_CALL: + if(shmp->called_info.valid_time >0) + { + SetCallType(shmp,shmp->process_info.tariff.call_type); + + if(tvnow.tv_sec>=GetIncomingExpiration(&shmp->called_info)) + { + shmp->process_info.tcos= CALLED_EXPIRIED; + shmp->process_info.voiceID = MT_EXPIRIED_ACCOUNT; + return FALSE; + } + else + { + SetCallType(shmp,shmp->process_info.tariff.call_type); + } + } + else + { + if(shmp->called_info.status == T_NORMAL) + { + shmp->process_info.tcos = CALLED_CREDIT_OUT; + shmp->process_info.voiceID = MT_LOW_ACCOUNT_BALANCE; + } + else + { + shmp->process_info.tcos = CALLED_STATUS_ERROR; + shmp->process_info.voiceID = MT_ERROR_ACCOUNT_STATUS; + } + return FALSE; + } + + if(shmp->process_info.tariff_flag ==0) + { + shmp->process_info.tcos = TARIFF_NOT_SET; + shmp->process_info.voiceID = CALLED_TARIFF_NOT_SET; + return FALSE; + } + break; + + case CT_MO_CALL: + case CT_MF_CALL: + if(shmp->process_info.tariff_flag ==0) + { + shmp->process_info.tcos = TARIFF_NOT_SET; + shmp->process_info.voiceID = CALLED_TARIFF_NOT_SET; + return FALSE; + } + + if(shmp->caller_info.valid_time >0) + { + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(tvnow.tv_sec>=GetExpiration(&shmp->caller_info)) + { + if(call_type == CT_MO_CALL) + { + shmp->process_info.tcos = CALLER_EXPIRIED; + shmp->process_info.voiceID = EXPIRIED_ACCOUNT; + } + else + { + shmp->process_info.tcos= CALLED_EXPIRIED; + shmp->process_info.voiceID = MT_EXPIRIED_ACCOUNT; + } + return FALSE; + } + else if((call_type == CT_MO_CALL) && + ((tvnow.tv_sec+ + (cosTableItem->smsNotificationInquiry[0].theDaysSendingSMSBeforeExpiredDay)*24*3600) + >=GetExpiration(&shmp->caller_info))) + { + shmp->process_info.pre_warning = 1; + shmp->process_info.voiceID = PRE_WARNING_EXPIRATION_DAY; + } + SetCallType(shmp,shmp->process_info.tariff.call_type); + } + else + { + if(shmp->caller_info.status == T_NORMAL) + { + if(call_type == CT_MO_CALL) + { + shmp->process_info.tcos = CALLER_CREDIT_OUT; + shmp->process_info.voiceID = LOW_ACCOUNT_BALANCE; + } + else + { + shmp->process_info.tcos = CALLED_CREDIT_OUT; + shmp->process_info.voiceID = MT_LOW_ACCOUNT_BALANCE; + } + } + return FALSE; + } + break; + default: + shmp->process_info.tcos = 255; + return FALSE; + break; + } + + return TRUE; +} + +void +SetCSTATimestamp(int instance, u_long timestamp) +{ + PutLogFunID("SetCSTATimestamp"); + + pps_csta_buffer.csta_record[instance].timestamp = timestamp; +} + +static int callTypeToCstaType(u_short callType) +{ + switch(callType) + { + case CT_LOCAL_CALL_OUT: + case CT_TRUNK_CALL_OUT: + case CT_NDD_CALL_OUT: + case CT_IDD_CALL_OUT: + case CT_LOCAL_CALL_IN: + case CT_TRUNK_CALL_IN: + case CT_PERIODIC_CHARGE: + case CT_ASSISTED_UP: + case CT_ASSISTED_DOWN: + case CT_RECHARGE_SUCCESS: + case CT_RECHARGE_FAIL: + case CT_MO_SM: + case CT_DIRECT_DEBITING: + case CT_REFUND_ACCOUNT: + case CT_CONFERENCE_CALL: + case CT_THIRD_PARTY_CHARGE: + case CT_EMERGENCY_CALL: + return callType - PPS_CSTA_TYPE_BASE; + break; + case CT_BUNDLE_PLAN_CHARGE: + return CT_PERIODIC_CHARGE - PPS_CSTA_TYPE_BASE; + break; + case CT_GPRS: + case CT_GPRS_REFUND: + return SERVICE_GPRS; + break; + case CT_MO_CC_CALL: + return SERVICE_CCC; + default: + return -1; + break; + } + return -1; +} + +int CDRStatistics(_tocdr_report* pbuf,float f_charge,ulong gprsVolume) +{ + int charge=0, duration=0; + u_short type; + char buf[BUFSIZE]; + int cstaType; + + PutLogFunID("CDRStatistics"); + + type = pbuf->type[0] + pbuf->type[1] * 256; + memcpy(&charge , pbuf->charge, 4); + memcpy(&duration , pbuf->duration, 4 ); + + BcdToAscii(buf, pbuf->releasetime, 14); + + if (type == CT_REFUND_ACCOUNT) + { + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge -= charge; + reportGprsCDRIncrement(0, -charge, 0); + } + else if (type == CT_DIRECT_DEBITING) + { + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge += charge; + reportGprsCDRIncrement(0, charge, 0); + } + + cstaType = callTypeToCstaType(type); + if(cstaType<0) + return -1; + + if(cstaType == SERVICE_GPRS) + { + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.gprsVolume += gprsVolume; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge += charge; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.duration += duration ; + } + else + { + pps_csta_buffer.csta_record[csta_old_instance].csta_type[cstaType].number ++; + pps_csta_buffer.csta_record[csta_old_instance].csta_type[cstaType].charge += charge; + pps_csta_buffer.csta_record[csta_old_instance].csta_type[cstaType].duration += duration ; + } + + AddPPSStatistics(MIBPPS_CSTANUMBER,0); +#if DEBUG + if(logMsgFlag & 0x04) + DebugMsg(debugmib.display.asciiOut, "type:%d charge:%d duration:%d", + cstaType, charge, duration); +#endif + if(cstaType != SERVICE_GPRS) + reportCDRIncrement(type, duration, f_charge,gprsVolume); + else + reportGprsCDRIncrement(duration,f_charge,gprsVolume); + return 1; +} + +int GprsCDRStatistics(_tocdr_report* pbuf,float f_charge,ulong gprsVolume) +{ + u_long charge=0, duration=0; + u_short type,cstaType; + char buf[BUFSIZE]; + + PutLogFunID("GprsCDRStatistics"); + + type = pbuf->type[0] + pbuf->type[1] * 256; + memcpy(&charge , pbuf->charge, 4); + memcpy(&duration , pbuf->duration, 4 ); + + BcdToAscii(buf, pbuf->releasetime, 14); + + cstaType = callTypeToCstaType(type); + if(cstaType<0) + return -1; + + if( type == CT_GPRS_REFUND) + { + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.gprsVolume -= gprsVolume; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number --; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge -= charge; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.duration -= duration ; + reportGprsCDRIncrement(duration, -f_charge, -gprsVolume); + } + else if(cstaType == SERVICE_GPRS) + { + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.gprsVolume += gprsVolume; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge += charge; + pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.duration += duration ; + reportGprsCDRIncrement(duration,f_charge,gprsVolume); + AddPPSStatistics(MIBPPS_CSTANUMBER,0); + } + +#if DEBUG + if(logMsgFlag & 0x04) + DebugMsg(debugmib.display.asciiOut, "type:%d charge:%d duration:%d volume:%ld", + cstaType, charge, duration,gprsVolume); +#endif + + return 1; +} + +int MsisdnToAscii(char *ascii_in, BYTE *cmsisdn) +{ + int len,len1; + char tmpbuf[64]; + + PutLogFunID("MsisdnToAscii"); + + len = cmsisdn[MAX_MSISDN_BLEN-1]; + len = len % 19; + len1 = len; + if(len%2 !=0) len1 = len + 1; + BcdToAscii(tmpbuf,cmsisdn,len1); + memcpy(ascii_in,tmpbuf,len); + ascii_in[len] = 0; + + return 1; +} + +int ppsInitCSTA() +{ + time_t nowSec,nowSec1; + + PutLogFunID("ppsInitCSTA"); + + nowSec = nowSec1 = tvnow.tv_sec; + nowSec = nowSec % (24 * 3600); + csta_now_instance = \ + csta_old_instance = \ + nowSec / (15 * 60); + + SetCSTATimestamp(csta_old_instance, nowSec1); + return 1; +} + +void +cstaInstanceCheck() +{ + time_t nowSec,nowSec1; + + PutLogFunID("cstaInstanceCheck"); + + nowSec = nowSec1 = tvnow.tv_sec; + nowSec = nowSec % (24 * 3600); + csta_now_instance = \ + nowSec / (15 * 60); + if(csta_old_instance != csta_now_instance) + { + csta_old_instance = csta_now_instance; + memset(&pps_csta_buffer.csta_record[csta_now_instance], + 0, + sizeof(_pps_csta_record)); + SetCSTATimestamp(csta_old_instance, nowSec1); + } +} + +int CheckWetherLocalNumber(char *number) +/*return value is the number property, + 0=unknwon, 1=local, 2=national, 3=internationl +*/ +{ + char plmn[32]={""},buf[BUFSIZE]={""}; + char ndc[32]={""},cc[32]={""}; + int start,/*len,*/plmnlen,ndclen,cclen; + int retval=3; + + u_char CC[32],NDC[32]; + + PutLogFunID("CheckWetherLocalNumber"); + + xap_get_cc(CC); + xap_get_ndc(NDC); + + //len = strlen(number); + BcdToAscii(plmn,CC,4); + StringCut(plmn,'E'); + cclen = strlen(plmn); + strcpy(cc,plmn); + BcdToAscii(buf,NDC,6); + StringCut(buf,'E'); + strcpy(ndc,buf); + ndclen = strlen(buf); + strcat(plmn,buf); + plmnlen = strlen(plmn); + + start = 0; + memcpy(buf,number,plmnlen); + buf[plmnlen] = 0; + + if(!strncasecmp(buf,cc,cclen)) + { + if(!strncasecmp(buf,plmn,plmnlen)) + { + start += plmnlen; + retval = 1; + } + else + { + start += cclen; + retval = 2; + } + } + else if(ndclen>0 && !strncasecmp(buf,ndc,ndclen)) + { + start += ndclen; + retval = 2; + } + +// if((len-start)<0) start = len; +// memcpy(buf,&number[start],len-start); +// buf[len-start] = 0; + +// strcpy(number,buf); + return retval; +} + +int transferIddBillingPrefix(char *number) /* to check if idd/00idd billing prefix need to be tranferred by XAPP */ +{ + char inter_prefix[32]; + char bufi[32]; + int len; + + PutLogFunID("transferIddBillingPrefix"); + + xap_get_interprefix((u8 *)inter_prefix); + + BcdToAscii(bufi, (BYTE *)inter_prefix,4); + StringCut(bufi,'E'); + len = strlen(bufi); + + if(memcmp(number,bufi,len)) /* no international prefix */ + { + return 1; + } + + if(ppsParam.serviceControl.transfer_idd_prefix == 0) /* contains internaltion prefix, e.g 00, but not need to transfer it */ + { + return 0; + } + return 1; +} + +int AddNDC(char *number) +{ + char bufndc[32],buf[BUFSIZE]; + char NDC[32]; + + PutLogFunID("AddNDC"); + + xap_get_ndc((u8 *)NDC); + + BcdToAscii(bufndc, (BYTE *)NDC,6); + StringCut(bufndc,'E'); + strcpy(buf,bufndc); + strcat(buf,number); + strcpy(number,buf); + + return 1; +} + +int AddCC(char *number) +{ + char bufcc[32],buf[BUFSIZE]; + char CC[32]; + + PutLogFunID("AddCC"); + + xap_get_cc((u8 *)CC); + BcdToAscii(bufcc, (BYTE *)CC,4); + StringCut(bufcc,'E'); + strcpy(buf,bufcc); + strcat(buf,number); + strcpy(number,buf); + + return 1; +} + +int AddInterPrefix(char *number) +{ + char inter_prefix[32]; + char bufi[32]; + char buf[32]; + + PutLogFunID("AddInterPrefix"); + xap_get_interprefix((u8 *)inter_prefix); + + + BcdToAscii(bufi, (BYTE *)inter_prefix,4); + StringCut(bufi,'E'); + strcpy(buf,number); + sprintf(number,"%s%s",bufi,buf); + return 1; +} + +int AddNationalPrefix(char *number) +{ + char national_prefix[32]; + char bufn[32]; + char buf[32]; + + PutLogFunID("AddNationalPrefix"); + + xap_get_nationalprefix((u8 *)national_prefix); + BcdToAscii(bufn, (BYTE *)national_prefix,4); + StringCut(bufn,'E'); + strcpy(buf,number); + sprintf(number,"%s%s",bufn,buf); + return 1; +} + +int CutUnknownPrefix(char *number) +{ + char buf[BUFSIZE],buf1[BUFSIZE]; + //char idd_prefix[4], bufi[8]; + //char *offset = NULL; + + PutLogFunID("CutUnknownPrefix"); + + if(number == NULL) + return 0; + + if(strlen(number)>MAX_ASCII_NUMBER_LEN) + { + pps_print_error(0, + "CutUnknowPrefix src number %s is too long",number); + return 0; + } + + strcpy(buf,number); + if(msisdnUnkToInt(buf,buf1)<=0) + return 0; +/* + xap_get_interprefix(idd_prefix); + + BcdToAscii(bufi,idd_prefix,4); + StringCut(bufi,'E'); + if((offset = strstr(bufi, buf1)) != NULL) + strcpy(buf, offset); + else + strcpy(buf, buf1); + */ + strcpy(buf, buf1); + if(strlen(buf)>MAX_ASCII_NUMBER_LEN) + { + pps_print_error(0, + "CutUnknowPrefix manimpulated number %s is too long",buf); + return 0; + } + strcpy(number, buf); + return 1; +} + +int CheckWetherHPLMNUser(char *number) +{ + char bufcc[32],buf[BUFSIZE],bufndc[32]; + char CC[32],NDC[32]; + int len; + + PutLogFunID("CheckWetherHPLMNUser"); + + xap_get_cc((u8 *)CC); + BcdToAscii(bufcc, (BYTE *)CC,4); + StringCut(bufcc,'E'); + + xap_get_ndc((u8 *)NDC); + BcdToAscii(bufndc, (BYTE *)NDC,6); + StringCut(bufndc,'E'); + + strcpy(buf,bufcc); + strcat(buf,bufndc); + len = strlen(buf); + if(strncasecmp(buf,number,len)==0) + return 1; + return 0; +} + +int CheckSeriveIdentification(char *serviceID,char *servicePWD,u_long srcip, + int *result,char *cause) +{ + int loop; + + PutLogFunID("CheckSeriveIdentification"); + + *result = 0; + sprintf(cause,"error service ID"); + for(loop=0;loopMAX_MSISDN_ALEN || strlen(called)>MAX_MSISDN_ALEN) + return 0; + + sprintf(tmpCaller,"91%s",caller); + sprintf(tmpCalled,"91%s",called); + + cliUptoCalled(tmpCaller,tmpCalled); + + if(strlen(tmpCaller)>MAX_MSISDN_ALEN) + return 0; + + strcpy(caller,&tmpCaller[2]); + return strlen(caller); + +} + +int ppsCheckMTSMSCharging(char *msisdn) +{ + _account_info account_info; + + if(msisdn == NULL) return 1; + if(strlen(msisdn)>=23) return 1; + + strcpy((char *)account_info.number, msisdn); + if( !GetAccountPos(&account_info)) return 1; + + account_info.cos_id = GetAccountCosID(&account_info); + if(ppsParam.ppsTables.cosTable[account_info.cos_id].serviceControl[0].mtSMSCharge) + { + if(GetAccountBalance(account_info.head, account_info.tail)>= + ppsParam.ppsTables.cosTable[account_info.cos_id].serviceControl[0].mtSMSCharge) + return 1; + else + return 0; + } + + return 1; +} + +int pps_get_ro_voice_quota(_state_data *shmp) +{ + int retval = 0; + + if(shmp->process_info.tariff_flag == 0) + return 0; + if(shmp->caller_info.status != T_NORMAL) + return 0; + if(GetExpiration(&shmp->caller_info) < tvnow.tv_sec) + return 0; + + retval = GetMaxCallDuration(shmp); + + return retval; +} + + +static int pps_update_last_ro_quota_type(_state_data *shmp, u_char new_type, u32 new_quota)// for Ro refund +{ + if (shmp->process_info.ro_if.last_ro_quota_type == 0)// bundle + { + if (new_type == 0)// bundle + { + shmp->process_info.ro_if.last_bundle_duration += new_quota; + } + else + { + shmp->process_info.ro_if.last_cap_duration = new_quota; + shmp->process_info.ro_if.last_ro_quota_type = 1; + } + } + else + { + if (new_type == 0)// bundle + { + shmp->process_info.ro_if.last_bundle_duration = new_quota; + shmp->process_info.ro_if.last_ro_quota_type = 0; + } + else + { + shmp->process_info.ro_if.last_cap_duration += new_quota; + } + } + + return 0; +} + + +// need_assigned_duration: Param IN and OUT; new_assigned_bundle, Param OUT; +float pps_billing_ro_voice(_state_data *shmp, u32 *assigned_duration, u32 *new_assigned_bundle) +{ + float charge = 0.0, balance = 0.0; + _bill_tariff *bt_ptr; + int discount, left_bundle, left_duration_to_assign = 0; + + bt_ptr = &shmp->process_info.tariff; + discount = GetDiscount(tvnow.tv_sec, bt_ptr->discountID); + + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) // Get left bundle + { + left_bundle = pps_get_account_bundle_mo_voice(shmp); + balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + } + else + { + left_bundle = pps_get_account_bundle_mt_voice(shmp); + balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); + } + + // allocation of the first time + if (shmp->process_info.chargedTime == 0) + { + if (left_bundle > 0) + { + // allocate bunle first, and then balance + if (left_bundle >= *assigned_duration)// enough bundle for first quota + { + *new_assigned_bundle = *assigned_duration; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + goto out; + } + else + { + *new_assigned_bundle = left_bundle; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota + *assigned_duration = left_bundle; + } + } + else + { + // check if balance enough for the min charge unit + if(bt_ptr->unit_time == 0 || bt_ptr->mini_unit == 0)// error param, can't allocate duratioon + { + *assigned_duration = 0; + pps_update_last_ro_quota_type(shmp, 1, 0); + goto out; + } + + charge = (bt_ptr->mini_unit * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; + charge += bt_ptr->adjustment; + if (charge <= balance)// have enough balance for the first basic charge + { + int basic_time = (bt_ptr->mini_unit * bt_ptr->unit_time) + bt_ptr->free_time; + if (basic_time >= *assigned_duration)// basic time is enough for this quota + { + *assigned_duration = basic_time; + pps_update_last_ro_quota_type(shmp, 1, 0);// basic time don't have to refund + goto out; + } + else + { + left_duration_to_assign = *assigned_duration - basic_time;// have to allocate more by balance to meet this quota + *assigned_duration = basic_time; + pps_update_last_ro_quota_type(shmp, 1, 0);// basic time don't have to refund + } + } + else + { + *assigned_duration = 0; + pps_update_last_ro_quota_type(shmp, 1, 0); + goto out; + } + } + } + else + { + if (left_bundle > 0) + { + // allocate bunle first, and then balance + if (left_bundle >= *assigned_duration)// enough bundle for first quota + { + *new_assigned_bundle = *assigned_duration; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + goto out; + } + else + { + *new_assigned_bundle = left_bundle; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota + *assigned_duration = left_bundle; + } + } + else + { + int units = 0; + + // calculate how many unit have to allocate + units = (*assigned_duration + bt_ptr->unit_time -1) / bt_ptr->unit_time; + + // check if balance enough for the min charge unit + charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; + if (charge <= balance)// have enough balance for the first basic charge + { + *assigned_duration = units * bt_ptr->unit_time; + pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); + goto out; + } + else// have no enough balance, so that assign as much unit as it could + { + units = balance / ((1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0); + if (units > 0) + { + charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; + *assigned_duration = units * bt_ptr->unit_time; + pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); + } + else + { + *assigned_duration = 0; + } + goto out; + } + } + } + // + + // have to allocate more quota by balance + if (left_duration_to_assign > 0) + { + int units = 0; + float temp_charge = 0.0; + + // calculate how many unit have to allocate + units = (left_duration_to_assign + bt_ptr->unit_time -1) / bt_ptr->unit_time; + + // check if balance enough for the min charge unit + temp_charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; + if ((temp_charge + charge) <= balance)// have enough balance for the first basic charge + { + charge += temp_charge; + *assigned_duration += units * bt_ptr->unit_time; + pps_update_last_ro_quota_type(shmp, 1, units * bt_ptr->unit_time); + goto out; + } + else// have no enough balance, so that assign as much unit as it could + { + units = (balance - charge) / ((1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0); + if (units > 0) + { + charge += (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; + *assigned_duration += units * bt_ptr->unit_time; + pps_update_last_ro_quota_type(shmp, 1, units * bt_ptr->unit_time); + } + goto out; + } + } + // + + if(0) + DebugMsg(debugmib.display.asciiOut, " %s:%d , tariff: unit=%d, %.2f+%.2f, assigned_duration=%d, , discount=%d ,charge=%.2f", + __FUNCTION__, __LINE__, + bt_ptr->unit_time , + bt_ptr->tierRating.rating[0].base_fee, + bt_ptr->tierRating.rating[0].long_distance_fee, + *assigned_duration, + discount, + charge + ); + +out: + shmp->process_info.chargedTime ++; + + return charge; +} + + +float pps_billing_ro_voice_with_crm(_state_data *shmp, u32 *assigned_duration, u32 *new_assigned_bundle) +{ + float charge = 0.0, balance = 0.0; + int discount, left_bundle, left_duration_to_assign = 0; + + discount = shmp->process_info.rest_if.tariff_discount; + + left_bundle = shmp->process_info.rest_if.total_plan_value - shmp->process_info.rest_if.used_plan_value; + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + } + else + { + balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); + } + + // allocation of the first time + if (0)//(shmp->process_info.chargedTime == 0) + { + if (left_bundle > 0) + { + // allocate bunle first, and then balance + if (left_bundle >= *assigned_duration)// enough bundle for first quota + { + *new_assigned_bundle = *assigned_duration; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + goto out; + } + else + { + *new_assigned_bundle = left_bundle; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota + *assigned_duration = left_bundle; + } + } + else + { + // check if balance enough for the min charge unit + if(shmp->process_info.rest_if.unit == 0)// error param, can't allocate duratioon + { + *assigned_duration = 0; + pps_update_last_ro_quota_type(shmp, 1, 0); + goto out; + } + + charge = ((*assigned_duration / shmp->process_info.rest_if.unit) * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; + if (charge <= balance)// have enough balance for the first basic charge + { + pps_update_last_ro_quota_type(shmp, 1, 0);// basic time don't have to refund + goto out; + } + else + { + if (balance >= shmp->process_info.rest_if.unit_charge)// last unit? + { + charge = balance; + *assigned_duration = shmp->process_info.rest_if.unit; + pps_update_last_ro_quota_type(shmp, 1, 0); + goto out; + } + else + { + *assigned_duration = 0; + pps_update_last_ro_quota_type(shmp, 1, 0); + goto out; + } + } + } + } + else + { + if (left_bundle > 0) + { + // allocate bunle first, and then balance + if (left_bundle >= *assigned_duration)// enough bundle for first quota + { + *new_assigned_bundle = *assigned_duration; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + goto out; + } + else + { + *new_assigned_bundle = left_bundle; + pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); + left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota + *assigned_duration = left_bundle; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + DebugMsg(debugmib.display.asciiOut, " %s:%d, left bundle[%d], assigned=[%d], need assigned by balance=[%d]", + __FUNCTION__, __LINE__, + left_bundle, + *assigned_duration, + left_duration_to_assign + ); + } + else + { + int units = 0; + + // calculate how many unit have to allocate + units = (*assigned_duration + shmp->process_info.rest_if.unit -1) / shmp->process_info.rest_if.unit; + + // check if balance enough for the min charge unit + charge = (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; + if (charge <= balance)// have enough balance for the first basic charge + { + *assigned_duration = units * shmp->process_info.rest_if.unit; + pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); + goto out; + } + else// have no enough balance, so that assign as much unit as it could + { + units = balance / ((1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0); + if (units > 0) + { + charge = (units * 1.0 * (shmp->process_info.rest_if.unit_charge)) * discount / 100.0; + *assigned_duration = units * shmp->process_info.rest_if.unit; + pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); + } + else + { + *assigned_duration = 0; + charge = 0.0; + } + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + DebugMsg(debugmib.display.asciiOut, " %s:%d, no enough balance: units[%d], assigned=[%d], balance=%.2f, charge=%.2f", + __FUNCTION__, __LINE__, + units, + *assigned_duration, + balance, charge + ); + + goto out; + } + } + } + // + + // have to allocate more quota by balance + if (left_duration_to_assign > 0) + { + int units = 0; + float temp_charge = 0.0; + + // calculate how many unit have to allocate + units = (left_duration_to_assign + shmp->process_info.rest_if.unit -1) / shmp->process_info.rest_if.unit; + + // check if balance enough for the min charge unit + temp_charge = (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; + if ((temp_charge + charge) <= balance)// have enough balance for the first basic charge + { + charge += temp_charge; + *assigned_duration += units * shmp->process_info.rest_if.unit; + pps_update_last_ro_quota_type(shmp, 1, units * shmp->process_info.rest_if.unit); + goto out; + } + else// have no enough balance, so that assign as much unit as it could + { + units = (balance - charge) / ((1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0); + if (units > 0) + { + charge += (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; + *assigned_duration += units * shmp->process_info.rest_if.unit; + pps_update_last_ro_quota_type(shmp, 1, units * shmp->process_info.rest_if.unit); + } + goto out; + } + } + // + +out: + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + DebugMsg(debugmib.display.asciiOut, " %s:%d, tariff: unit=%d*%.2f, assigned/bundle/cap=[%d/%d/%d], discount=%d, charge=%.2f", + __FUNCTION__, __LINE__, + shmp->process_info.rest_if.unit, + shmp->process_info.rest_if.unit_charge, + *assigned_duration, *new_assigned_bundle, left_duration_to_assign, + discount, + charge + ); + + shmp->process_info.chargedTime ++; + + return charge; +} + +float pps_refund_ro_voice_with_crm(_state_data *shmp, u32 refund_duration, u32 *refund_bundle) +{ + float charge = 0.0; + u32 bundle_duration = 0, cap_duration = 0; + int discount; + + discount = shmp->process_info.rest_if.tariff_discount; + + if (shmp->process_info.ro_if.last_ro_quota_type == 0)// bundle + { + if (refund_duration <= shmp->process_info.ro_if.last_bundle_duration) + { + // all refund to bundle + bundle_duration = refund_duration; + } + else + { + bundle_duration = shmp->process_info.ro_if.last_bundle_duration; + cap_duration = refund_duration - bundle_duration; + } + } + else + { + if (refund_duration <= shmp->process_info.ro_if.last_cap_duration) + { + // all refund to balance + cap_duration = refund_duration; + } + else + { + cap_duration = shmp->process_info.ro_if.last_cap_duration; + bundle_duration = refund_duration - cap_duration; + } + } + + *refund_bundle = bundle_duration; + if ((shmp->process_info.rest_if.unit > 0) && (cap_duration >= shmp->process_info.rest_if.unit)) + { + int units = 0; + units = cap_duration / shmp->process_info.rest_if.unit; + charge = (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; + } + + return charge; +} + + +float pps_refund_ro_voice(_state_data *shmp, u32 refund_duration, u32 *refund_bundle) +{ + float charge = 0.0; + _bill_tariff *bt_ptr; + u32 bundle_duration = 0, cap_duration = 0; + int discount; + + bt_ptr = &shmp->process_info.tariff; + discount = GetDiscount(tvnow.tv_sec, bt_ptr->discountID); + + if (shmp->process_info.ro_if.last_ro_quota_type == 0)// bundle + { + if (refund_duration <= shmp->process_info.ro_if.last_bundle_duration) + { + // all refund to bundle + bundle_duration = refund_duration; + } + else + { + bundle_duration = shmp->process_info.ro_if.last_bundle_duration; + cap_duration = refund_duration - bundle_duration; + } + } + else + { + if (refund_duration <= shmp->process_info.ro_if.last_cap_duration) + { + // all refund to balance + cap_duration = refund_duration; + } + else + { + cap_duration = shmp->process_info.ro_if.last_cap_duration; + bundle_duration = refund_duration - cap_duration; + } + } + + *refund_bundle = bundle_duration; + if (bt_ptr->unit_time == 0) + { + bt_ptr->unit_time = 60; + } + if (cap_duration >= bt_ptr->unit_time) + { + int units = 0; + units = cap_duration / bt_ptr->unit_time; + charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; + } + + return charge; +} + +/*-----------CRM related functions --------------------------------*/ +int pps_update_user_info_for_crm_create_account(_prepaid_info *user_ptr, + int customer_id, int account_id, int product_id, int plan_id, int balance, int expiry_day, int rent_charge, int birthday, int cug_id) +{ + if(user_ptr == NULL) + return 0; +#ifdef OCS_WITH_CRM + user_ptr->balance = balance; + user_ptr->mo_expiration_date = user_ptr->mt_expiration_date = expiry_day; + + user_ptr->crm_info.customer_id = customer_id; + user_ptr->crm_info.account_id = account_id; + user_ptr->crm_info.product_id = product_id; + user_ptr->crm_info.base_plan_id = plan_id; + user_ptr->crm_info.rent_charge = rent_charge; + user_ptr->crm_info.birthday = birthday; + user_ptr->cug_id = cug_id; + user_ptr->status = T_NORMAL; +#endif + return 1; +} diff --git a/mss/pps/src/main/myipcrm b/mss/pps/src/main/myipcrm new file mode 100644 index 0000000..80534ab --- /dev/null +++ b/mss/pps/src/main/myipcrm @@ -0,0 +1,33 @@ +#!/bin/sh + +ipcrm='To delete ipcrm shm' + +#program name +if [ `whoami` != "root" ] ; then + echo "Permission denied!" + exit +fi + +ipcsm=`ipcs -m` +echo "$ipcsm" + +ipcsm=`ipcs -m|grep '0x'|awk '{print $2}'` +for FILE in $ipcsm; do + ipcrm shm $FILE +done + +ipcsm=`ipcs -s` +echo "$ipcsm" + +ipcsm=`ipcs -s|grep '0x'|awk '{print $2}'` +for FILE in $ipcsm; do + ipcrm sem $FILE +done + +ipcsm=`ipcs -q` +echo "$ipcsm" + +ipcsm=`ipcs -q|grep '0x'|awk '{print $2}'` +for FILE in $ipcsm; do + ipcrm msg $FILE +done diff --git a/mss/pps/src/main/ocs_user_table.c b/mss/pps/src/main/ocs_user_table.c new file mode 100644 index 0000000..74e62e0 --- /dev/null +++ b/mss/pps/src/main/ocs_user_table.c @@ -0,0 +1,189 @@ +#include + +#include "../include/includes.h" +#include "../include/ramdata.h" +#include "../include/ppsm.h" +#include "../include/param.h" +#include "../include/tariff.h" + + + +typedef struct ue_record +{ + char used_flag; + int index; + int tb_index; + long long msisdn; +}_ue_record; + +typedef struct ocs_ue_index_table +{ + int head_index; + int used_record; + int record_num; + _ue_record record[MAX_SUBS_RECORD]; +}_ocs_ue_index_table; + + + +static _ocs_ue_index_table ue_table; + +static GHashTable *htb_ue = NULL; + +/* ----------------------------------------------*/ +int ocs_init_hash_table() +{ + + if(htb_ue != NULL) + g_hash_table_destroy(htb_ue); + + htb_ue = g_hash_table_new(g_direct_hash,g_direct_equal); + + return 1; +} + + +int hash_add_ue_entity(_ue_record *ue_ptr) +{ + if(ue_ptr != NULL) + g_hash_table_insert(htb_ue, GINT_TO_POINTER(ue_ptr->msisdn), ue_ptr); + + return 1; +} + +int ocs_hash_clean_ue_entity(_ue_record *ue_ptr) +{ + if(ue_ptr != NULL) + g_hash_table_remove(htb_ue, GINT_TO_POINTER(ue_ptr->msisdn)); + + return 1; +} + +unsigned int ocs_get_ue_index(long long msisdn) +{ + unsigned int index = INVALID_UE_INDEX; + _ue_record *ptr=NULL; + + ptr = (_ue_record *)g_hash_table_lookup(htb_ue, GINT_TO_POINTER(msisdn)); + if(ptr != NULL) + index = ptr->index; + + return index; +} + +unsigned int ocs_get_ue_tb_index(long long msisdn) +{ + unsigned int index = INVALID_UE_INDEX; + _ue_record *ptr=NULL; + + ptr = (_ue_record *)g_hash_table_lookup(htb_ue, GINT_TO_POINTER(msisdn)); + if(ptr != NULL) + index = ptr->tb_index; + + return index; +} + + _ue_record *ocs_get_ue_record(long long msisdn) +{ + unsigned int index = ocs_get_ue_index(msisdn); + _ue_record *ue_ptr=NULL; + + if(index != INVALID_UE_INDEX) + { + ue_ptr = &ue_table.record[index]; + } + + return ue_ptr; +} + +int ocs_check_ue_record(long long msisdn) +{ + unsigned int index = ocs_get_ue_index(msisdn); + + if(index != INVALID_UE_INDEX) + { + return 1; + } + + return 0; + +} + +long long ocs_get_ue_by_index(int store_index) +{ + long long msisdn=0; + _ue_record *ue_ptr; + + if(store_index != INVALID_UE_INDEX) + { + ue_ptr = &ue_table.record[store_index]; + msisdn = ue_ptr->msisdn; + } + + + return msisdn; +} + +_ue_record *ocs_assign_ue_index(long long msisdn, int store_index) +{ + register int loop; + int index; + _ue_record *ue_ptr; + + for(loop = 0; loop < MAX_SUBS_RECORD; loop++) + { + //index = ue_table.head_index++; + index = loop; + ue_table.head_index %= MAX_SUBS_RECORD; + if(ue_table.record[index].used_flag == 0) + { + ue_table.record_num ++; + + ue_ptr = &ue_table.record[index]; + ue_ptr->used_flag = 1; + ue_ptr->index = store_index; + ue_ptr->msisdn = msisdn; + ue_ptr->tb_index = loop; + return ue_ptr; + } + } + + return NULL; +} + +int ocs_delete_ue_record(long long msisdn) +{ + unsigned int tb_index = ocs_get_ue_tb_index(msisdn); + + if(tb_index != INVALID_UE_INDEX) + { + ue_table.record_num --; + ocs_hash_clean_ue_entity(&ue_table.record[tb_index]); + memset(&ue_table.record[tb_index], 0x00, sizeof(_ue_record)); + + return 1; + } + + return 0; + +} + +int ocs_add_ue_record(long long msisdn, int store_index) +{ + unsigned int index = ocs_get_ue_index(msisdn); + _ue_record *ue_ptr = NULL; + + if(index != INVALID_UE_INDEX) + { + return 0; + } + + ue_ptr = ocs_assign_ue_index(msisdn, store_index); + if(ue_ptr == NULL) + return 0; + hash_add_ue_entity(ue_ptr); + + return 1; + +} +/* ----------------------------------------------*/ diff --git a/mss/pps/src/main/ppsMibTable.c b/mss/pps/src/main/ppsMibTable.c new file mode 100644 index 0000000..072fa40 --- /dev/null +++ b/mss/pps/src/main/ppsMibTable.c @@ -0,0 +1,6417 @@ + +#include "../include/param.h" +#include "../../../../plat/snmp/src/include/snmp.h" +#include "../../../../plat/snmp/src/include/macro.h" +#include "../include/function.h" + +typedef u32 index_t; + +extern int pps_set_nas(BYTE id,RADIUS_NAS_INFORMATION *nasInfo); +extern int pps_del_nas(BYTE id); + +static void initCosTable(COSTable *cosItem); + +PPSParamStruct ppsParam; + +u8 PPS_GET_INTEGER(u_long integer,BYTE *pdata,u8 *vartype) +{ + *((int *)pdata) = htonl(integer); + *vartype = INTEGER; + return 4; +} + + +u_long PPS_SET_INTEGER(BYTE *pdata,BYTE dataLen) +{ + int i; + u_long integer; + + do { + if(dataLen > 4) + return -1; + for(i = 0, integer = 0; i < dataLen; i++) + { + integer = integer << 8; + integer += pdata[i]; + } + } while(0); + return integer; +} + +static int isIndexValid(ppsTableType tableType,int index) +{ + switch(tableType) + { + case PromptResolutionTable: + if(index < 0 || index >= MaxPromptResolutionItem) + return FALSE; + break; + case MnpPrefixTable: + if(index < 0 || index >= MaxMnpPrefixItem) + return FALSE; + break; + case SmsSentenceTable: + if(index < 0 || index >= MaxSmsSentenceItem*2) + return FALSE; + break; + case ThirdPartyInfoTable: + if(index < 0 || index >= MaxThirdPartyInfoItem) + return FALSE; + break; + case BasicTariffZoneTable: + if(index < 0 || index >= MaxBasicTariffZoneItem) + return FALSE; + break; + case IvrSourceTable: + if(index < 0 || index >= MaxIvrSourceItem) + return FALSE; + break; + case SrfNumberTable: + if(index < 0 || index >= MaxSrfNumberItem) + return FALSE; + break; + case ServiceNumberTable: + if(index < 0 || index >= MaxServiceNumberItem) + return FALSE; + break; + case ServiceKeyTable: + if(index < 0 || index >= MaxServiceKeyItem) + return FALSE; + break; + case VmsUserSegmentTable: + if(index < 0 || index >= MaxVmsUserSegmentItem) + return FALSE; + break; + case RadiusGsnTable: + if(index < 0 || index >= MaxRadiusGsnItem) + return FALSE; + break; + case RadiusSgsnTable: + if(index < 0 || index >= MaxRadiusSgsnItem) + return FALSE; + break; + case BundlePlanTable: + if(index <= 0 || index >= MAX_BUNDLE_PLANS) + return FALSE; + break; + case CosTable: + if(index < 0 || index >= MaxCosTableItem) + return FALSE; + break; + case TariffTable: + if(index < 0 || index >= MaxTariffTableItem) + return FALSE; + break; + case ServiceControlTable: + if(index < 0 || index >= MaxServiceControlTableItem) + return FALSE; + break; + case AccountValidityTable: + if(index < 0 || index >= MaxAccountValidityTableItem) + return FALSE; + break; + case SmsNotificationInquiryTable: + if(index < 0 || index >= MaxSmsNotificationInquiryTableItem) + return FALSE; + break; + case RechargeCardValidityTable: + if(index < 0 || index >= MaxRechargeCardType) + return FALSE; + break; + case RechargePromotionTable: + if(index < 0 || index >= MaxRechargeCardType) + return FALSE; + break; + case CapPlanTable: + if(index < 0 || index >= MaxcapPlanTableItem) + return FALSE; + break; + case PoolAccountTable: + if(index < 0 || index >= MaxPoolAccountTableItem) + return FALSE; + break; + case CosGprsTable: + if(index < 0 || index >= MaxGprsTableItem) + return FALSE; + break; + case FriendFamilyTable: + if(index<0 || index>=MaxServiceControlTableItem) + return FALSE; + break; + case UssdServiceNumberTable: + if(index < 0 || index >= MaxServiceNumberItem) + return FALSE; + break; + case UssdServiceKeyTable: + if(index < 0 || index > 10) + return FALSE; + break; + default: + return FALSE; + break; + } + return TRUE; +} + +int pps_getnext_Index(ppsTableType tableType,index_t *id) +{ + u32 i; + PpsTable *ppsTablePoint; + + ppsTablePoint = &ppsParam.ppsTables; + switch(tableType) + { + case PromptResolutionTable: + for(i = *id; i < MaxPromptResolutionItem; i++) + { + if(ppsTablePoint->promptResolution[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case MnpPrefixTable: + for(i = *id; i < MaxMnpPrefixItem; i++) + { + if(ppsTablePoint->mnpPrefix[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case SmsSentenceTable: + for(i = *id; i < MaxSmsSentenceItem; i++) + { + if( ppsTablePoint->smsSentence[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case ThirdPartyInfoTable: + for(i = *id; i < MaxThirdPartyInfoItem; i++) + { + if(ppsTablePoint->thirdPartyInfo[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case BasicTariffZoneTable: + for(i = *id; i < MaxBasicTariffZoneItem; i++) + { + if(ppsTablePoint->basicTariffZone[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case IvrSourceTable: + for(i = *id; i < MaxIvrSourceItem; i++) + { + if(ppsTablePoint->ivrSource[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case SrfNumberTable: + for(i = *id; i < MaxSrfNumberItem; i++) + { + if(ppsTablePoint->srfNumber[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case ServiceNumberTable: + for(i = *id; i < MaxServiceNumberItem; i++) + { + if(ppsTablePoint->serviceNumber[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case ServiceKeyTable: + for(i = *id; i < MaxServiceKeyItem; i++) + { + if(ppsTablePoint->serviceKey[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case VmsUserSegmentTable: + for(i = *id; i < MaxVmsUserSegmentItem; i++) + { + if(ppsTablePoint->vmsUserSegment[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case RadiusGsnTable: + for(i = *id; i < MaxRadiusGsnItem; i++) + { + if(ppsTablePoint->gsn[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case RadiusSgsnTable: + for(i = *id; i < MaxRadiusSgsnItem; i++) + { + if(ppsTablePoint->sgsn[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case BundlePlanTable: + for(i = *id; i < MAX_BUNDLE_PLANS; i++) + { + if(ppsTablePoint->bundlePlans[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + + case CosTable: + for(i = *id; i < MaxCosTableItem; i++) + { + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case TariffTable: + for(i = *(id+1); i < MaxTariffTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].tariff[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case ServiceControlTable: + for(i = *(id+1); i < MaxServiceControlTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].serviceControl[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case AccountValidityTable: + for(i = *(id+1); i < MaxAccountValidityTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].accountValidity[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case SmsNotificationInquiryTable: + for(i = *(id+1); i < MaxSmsNotificationInquiryTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].smsNotificationInquiry[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case RechargeCardValidityTable: + for(i = *(id+1); i < MaxRechargeCardType; i++) + { + if(ppsTablePoint->cosTable[*id].rechargeCardValidity[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case RechargePromotionTable: + for(i = *(id+1); i < MaxRechargeCardType; i++) + { + if(ppsTablePoint->cosTable[*id].rechargePromotion[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case CapPlanTable: + for(i = *(id+1); i < MaxcapPlanTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].capPlan[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case PoolAccountTable: + for(i = *(id+1); i < MaxPoolAccountTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].poolAccount[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case CosGprsTable: + for(i = *(id+1); i < MaxGprsTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].gprs[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + case UssdServiceNumberTable: + for(i = *id; i < MaxServiceNumberItem; i++) + { + if(ppsTablePoint->serviceNumber[i].existFlag == TRUE) + { + *id = i; + return 1; + } + } + break; + case UssdServiceKeyTable: + for(i = *(id+1); i < 10; i++) + { + if(ppsTablePoint->serviceKey[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + break; + case FriendFamilyTable: + for(i = *(id+1); i < MaxFriendFamilyTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].friendFamilyControl[i].existFlag == TRUE) + { + *(id+1) = i; + return 1; + } + } + for(i = *id+1; i < MaxCosTableItem; i++) + { /* next cos item */ + if(ppsTablePoint->cosTable[i].existFlag == TRUE) + { + *id = i; + *(id+1) = 0; + return 1; + } + } + break; + default: + *id = 0; + return 0; + break; + } + + *id = 0; + return 0; +} + +int pps_getIdle_Index(ppsTableType tableType,index_t *id) +{ + u32 i; + PpsTable *ppsTablePoint; + + ppsTablePoint = &ppsParam.ppsTables; + switch(tableType) + { + case PromptResolutionTable: + for(i = *id; i < MaxPromptResolutionItem; i++) + { + if(ppsTablePoint->promptResolution[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case MnpPrefixTable: + for(i = *id; i < MaxMnpPrefixItem; i++) + { + if(ppsTablePoint->mnpPrefix[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case SmsSentenceTable: + for(i = *id; i < MaxSmsSentenceItem; i++) + { + if( ppsTablePoint->smsSentence[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case ThirdPartyInfoTable: + for(i = *id; i < MaxThirdPartyInfoItem; i++) + { + if(ppsTablePoint->thirdPartyInfo[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case BasicTariffZoneTable: + for(i = *id; i < MaxBasicTariffZoneItem; i++) + { + if(ppsTablePoint->basicTariffZone[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case IvrSourceTable: + for(i = *id; i < MaxIvrSourceItem; i++) + { + if(ppsTablePoint->ivrSource[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case SrfNumberTable: + for(i = *id; i < MaxSrfNumberItem; i++) + { + if(ppsTablePoint->srfNumber[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case ServiceNumberTable: + for(i = *id; i < MaxServiceNumberItem; i++) + { + if(ppsTablePoint->serviceNumber[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case ServiceKeyTable: + for(i = *id; i < MaxServiceKeyItem; i++) + { + if(ppsTablePoint->serviceKey[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case VmsUserSegmentTable: + for(i = *id; i < MaxVmsUserSegmentItem; i++) + { + if(ppsTablePoint->vmsUserSegment[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case RadiusGsnTable: + for(i = *id; i < MaxRadiusGsnItem; i++) + { + if(ppsTablePoint->gsn[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case RadiusSgsnTable: + for(i = *id; i < MaxRadiusSgsnItem; i++) + { + if(ppsTablePoint->sgsn[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case BundlePlanTable: + for(i = *id; i < MAX_BUNDLE_PLANS; i++) + { + if(ppsTablePoint->bundlePlans[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case CosTable: + for(i = *id; i < MaxCosTableItem; i++) + { + if(ppsTablePoint->cosTable[i].existFlag == FALSE) + { + *id = i; + return 1; + } + } + break; + case TariffTable: + for(i = *(id+1); i < MaxTariffTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].tariff[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case ServiceControlTable: + for(i = *(id+1); i < MaxServiceControlTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].serviceControl[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case AccountValidityTable: + for(i = *(id+1); i < MaxAccountValidityTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].accountValidity[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case SmsNotificationInquiryTable: + for(i = *(id+1); i < MaxSmsNotificationInquiryTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].smsNotificationInquiry[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case RechargeCardValidityTable: + for(i = *(id+1); i < MaxRechargeCardType; i++) + { + if(ppsTablePoint->cosTable[*id].rechargeCardValidity[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case RechargePromotionTable: + for(i = *(id+1); i < MaxRechargeCardType; i++) + { + if(ppsTablePoint->cosTable[*id].rechargePromotion[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case CapPlanTable: + for(i = *(id+1); i < MaxcapPlanTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].capPlan[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case PoolAccountTable: + for(i = *(id+1); i < MaxPoolAccountTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].poolAccount[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case CosGprsTable: + for(i = *(id+1); i < MaxGprsTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].gprs[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + case FriendFamilyTable: + for(i = *(id+1); i < MaxFriendFamilyTableItem; i++) + { + if(ppsTablePoint->cosTable[*id].friendFamilyControl[i].existFlag == FALSE) + { + *(id+1) = i; + return 1; + } + } + break; + default: + *id = 0; + return 0; + break; + } + + *id = 0; + return 0; +} + +int isIndexBusy(ppsTableType tableType,index_t *id) +{ + PpsTable *ppsTablePoint; + u32 index,subIndex; + + index = *id; + subIndex = *(id+1); + ppsTablePoint = &ppsParam.ppsTables; + switch(tableType) + { + case PromptResolutionTable: + if(index >= MaxPromptResolutionItem) + return TRUE; + return ppsTablePoint->promptResolution[index].existFlag; + break; + case MnpPrefixTable: + if(index >= MaxMnpPrefixItem) + return TRUE; + return ppsTablePoint->mnpPrefix[index].existFlag; + break; + case SmsSentenceTable: + if(index >= MaxSmsSentenceItem*2) + return TRUE; + return ppsTablePoint->smsSentence[index].existFlag; + break; + case ThirdPartyInfoTable: + if(index >= MaxThirdPartyInfoItem) + return TRUE; + return ppsTablePoint->thirdPartyInfo[index].existFlag; + break; + case BasicTariffZoneTable: + if(index >= MaxBasicTariffZoneItem) + return TRUE; + return ppsTablePoint->basicTariffZone[index].existFlag; + break; + case IvrSourceTable: + if(index >= MaxIvrSourceItem) + return TRUE; + return ppsTablePoint->ivrSource[index].existFlag; + break; + case SrfNumberTable: + if(index >= MaxSrfNumberItem) + return TRUE; + return ppsTablePoint->srfNumber[index].existFlag; + break; + case ServiceNumberTable: + if(index >= MaxServiceNumberItem) + return TRUE; + return ppsTablePoint->serviceNumber[index].existFlag; + break; + case ServiceKeyTable: + if(index >= MaxServiceKeyItem) + return TRUE; + return ppsTablePoint->serviceKey[index].existFlag; + break; + case VmsUserSegmentTable: + if(index >= MaxVmsUserSegmentItem) + return TRUE; + return ppsTablePoint->vmsUserSegment[index].existFlag; + break; + case RadiusGsnTable: + if(index >= MaxRadiusGsnItem) + return TRUE; + return ppsTablePoint->gsn[index].existFlag; + break; + case RadiusSgsnTable: + if(index >= MaxRadiusSgsnItem) + return TRUE; + return ppsTablePoint->sgsn[index].existFlag; + break; + case BundlePlanTable: + if(index >= MAX_BUNDLE_PLANS) + return TRUE; + return ppsTablePoint->bundlePlans[index].existFlag; + break; + case CosTable: + if(index >= MaxCosTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].existFlag; + break; + case TariffTable: + if(subIndex >= MaxTariffTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].tariff[subIndex].existFlag; + break; + case ServiceControlTable: + if(subIndex >= MaxServiceControlTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].serviceControl[subIndex].existFlag; + break; + case AccountValidityTable: + if(subIndex >= MaxAccountValidityTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].accountValidity[subIndex].existFlag; + break; + case SmsNotificationInquiryTable: + if(subIndex >= MaxSmsNotificationInquiryTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].smsNotificationInquiry[subIndex].existFlag; + break; + case RechargeCardValidityTable: + if(subIndex >= MaxRechargeCardType) + return TRUE; + return ppsTablePoint->cosTable[index].rechargeCardValidity[subIndex].existFlag; + break; + case RechargePromotionTable: + if(subIndex >= MaxRechargeCardType) + return TRUE; + return ppsTablePoint->cosTable[index].rechargePromotion[subIndex].existFlag; + break; + case CapPlanTable: + if(subIndex >= MaxcapPlanTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].capPlan[subIndex].existFlag; + break; + case PoolAccountTable: + if(subIndex >= MaxPoolAccountTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].poolAccount[subIndex].existFlag; + break; + case CosGprsTable: + if(subIndex >= MaxGprsTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].gprs[subIndex].existFlag; + break; + case FriendFamilyTable: + if(subIndex >= MaxFriendFamilyTableItem) + return TRUE; + return ppsTablePoint->cosTable[index].friendFamilyControl[subIndex].existFlag; + break; + case UssdServiceNumberTable: + if(index >= MaxServiceNumberItem) + return TRUE; + return ppsTablePoint->ussdServiceNumber[index].existFlag; + break; + case UssdServiceKeyTable: + if(index >= 10) + return FALSE; + return ppsTablePoint->ussdServiceKey[index].existFlag; + break; + default: + return TRUE; + break; + } + return TRUE; +} + +/***********************************************************************/ +/************************ prompt resolution ************************/ +int pps_getnext_promptResolution(index_t *id) +{ + return pps_getnext_Index(PromptResolutionTable,id); +} + +int pps_getIdle_promptResolution(index_t *id) +{ + return pps_getIdle_Index(PromptResolutionTable,id); +} + +int isPromptResolutionIndexBusy(index_t *index) +{ + return isIndexBusy(PromptResolutionTable,index); +} + +int pps_get_promptResolution(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + PromptResolution *promptResolutionItem; + + index = instance[0]; + if(isIndexValid(PromptResolutionTable,index) == FALSE) + return -1; + if(isIndexBusy(PromptResolutionTable,(index_t *)&index) == FALSE) + return -1; + promptResolutionItem = &ppsParam.ppsTables.promptResolution[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + promptResolutionItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)promptResolutionItem->title); + memcpy(pdata,promptResolutionItem->title,datalen); + break; + case 3: + *vartype = INTEGER; + pdata[0] = promptResolutionItem->currencyResolution; + datalen = 1; + break; + case 4: + *vartype = INTEGER; + pdata[0] = promptResolutionItem->dataFormat; + datalen = 1; + break; + case 5: + *vartype = INTEGER; + pdata[0] = promptResolutionItem->currencySymbolPosition; + datalen = 1; + break; + case 6:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +extern void ppsSetParameterAutoSaveFlag(); +int pps_set_promptResolution(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + PromptResolution *promptResolutionItem; + int index; + + index = instance[0]; + if(isIndexValid(PromptResolutionTable,index) == FALSE) + return -1; + promptResolutionItem = &ppsParam.ppsTables.promptResolution[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isPromptResolutionIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + promptResolutionItem = &ppsParam.ppsTables.promptResolution[index]; + promptResolutionItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(promptResolutionItem->title,pdata,datalen); + promptResolutionItem->title[datalen] = 0; + break; + case 3: + promptResolutionItem->currencyResolution = pdata[0]; + break; + case 4: + promptResolutionItem->dataFormat = pdata[0]; + break; + case 5: + promptResolutionItem->currencySymbolPosition = pdata[0]; + break; + case 6:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(promptResolutionItem,0,sizeof(PromptResolution)); + promptResolutionItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ prompt resolution ************************/ +/***********************************************************************/ + + +/***********************************************************************/ +/************************ MnpPrefix Table ************************/ +int pps_getnext_mnpPrefix(index_t *id) +{ + return pps_getnext_Index(MnpPrefixTable,id); +} + +int pps_getIdle_mnpPrefix(index_t *id) +{ + return pps_getIdle_Index(MnpPrefixTable,id); +} + +int isMnpPrefixIndexBusy(index_t *index) +{ + return isIndexBusy(MnpPrefixTable,index); +} + +int pps_get_mnpPrefix(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + MnpPrefix *mnpPrefixItem; + + index = instance[0]; + if(isIndexValid(MnpPrefixTable,index) == FALSE) + return -1; + if(isIndexBusy(MnpPrefixTable,(index_t *)&index) == FALSE) + return -1; + mnpPrefixItem = &ppsParam.ppsTables.mnpPrefix[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + mnpPrefixItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)mnpPrefixItem->title); + memcpy(pdata,mnpPrefixItem->title,datalen); + break; + case 3: + datalen = strlen((char *)mnpPrefixItem->prefix); + memcpy(pdata,mnpPrefixItem->prefix,datalen); + break; + case 4:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_mnpPrefix(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + MnpPrefix *mnpPrefixItem; + int index; + + index = instance[0]; + if(isIndexValid(MnpPrefixTable,index) == FALSE) + return -1; + mnpPrefixItem = &ppsParam.ppsTables.mnpPrefix[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isMnpPrefixIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + mnpPrefixItem = &ppsParam.ppsTables.mnpPrefix[index]; + mnpPrefixItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(mnpPrefixItem->title,pdata,datalen); + mnpPrefixItem->title[datalen] = 0; + break; + case 3: + memcpy(mnpPrefixItem->prefix,pdata,datalen); + mnpPrefixItem->prefix[datalen] = 0; + break; + case 4:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(mnpPrefixItem,0,sizeof(MnpPrefix)); + mnpPrefixItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ MnpPrefix Table ************************/ +/***********************************************************************/ + + +/***********************************************************************/ +/************************ SmsSentence Table ************************/ +static void initPrep() +{ + SmsSentence *smsSentenceItem; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_AT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"At",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"at",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_TO]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"To",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"to",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FROM]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"From",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"from",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_ON]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"On",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"on",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; +} + +static void initCMB() +{ + SmsSentence *smsSentenceItem; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CMB_PROMPT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Call Me Back Prompt",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Please enter the destination number following this format:number",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CMB_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Call Me Back Notify",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english," ask for your call ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CMB_REACH_MAX_LIMIT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Call Me Back Limited",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your call me back request reaches the max allowed times",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CMB_AD]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Call Me Back Advertisement",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Welcome to use Call Me Back",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + +} + +static void initFreeService() +{ + SmsSentence *smsSentenceItem; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_ACTIVE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Active",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"activate",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_DEACTIVE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Deactive",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"deactivate",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_ENQUIRY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Inquiry",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"enquire",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_ACTIVED_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Active Notify",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have activated free SMS",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_DEACTIVED_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Deactive Notify",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have deactivated free SMS",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_ACTIVE_ALREADY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Active State",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your free SMS service is active",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_DEACTIVE_ALREADY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Deactive State",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your free SMS service is inactive",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_DEACTIVED_EXPIRED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free Service Expired",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your free SMS service is expired,and deactived by system",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SERVICE_VALID_DAYS_LEFT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Valid Days",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english," valid days left:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + +} + +static void initTransfer() +{ + SmsSentence *smsSentenceItem; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_TRANSFERED_OUT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Transferd Out",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have transfered out ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_WILL_TRANSFER_OUT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Transfering Out",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You will transfer out ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_TRANSFERED_IN]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Transfered In",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have received ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_SERVICE_NOT_APPLIED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Service Not Applied",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Service is not applied",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_TRANSFER_PROMPT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Transfer Out Prompt",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Please enter follow this format:destination number#amount",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FORMAT_ERROR]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Format Error",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Format error",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_INVALID_NUMBER]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Invalid Number",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Invalid number",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_INSUFFICIENT_FEE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Insufficient Fee",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Insufficient fee",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_EXPIRED_ACCOUNT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Expired Account",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your account is expired,please recharge",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_YES_OR_NO]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"SMS_YES_OR_NO",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Press 1 to confirm\nPress 2 to enter again\nPress 0 to cancel\n",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_TRANSFER_SUCCESS]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Transfer Success",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Transfer successfully",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + +} + +static void initPoolAccount() +{ + SmsSentence *smsSentenceItem; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_POOL_CHILD_LOW_FEE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Pool Account",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Child balance is too low,please recharge it on time",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_POOL_ADDED_CHILD]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Pool Account",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have added a child number:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_POOL_DELED_CHILD]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Pool Account",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have deleted a child number:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_POOL_BEEN_ADDED_CHILD]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Pool Account",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have been added as a child number by:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_POOL_BEEN_DELED_CHILD]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Pool Account",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your child role have been deleted by:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; +} + +static void initUSSD() +{ + SmsSentence *smsSentenceItem; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_NOT_REGISTER_PREPAID_USER]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Not Prepaid User",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Not registered as Prepaid Customer",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_USSD_MENU]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"USSD MENU",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"1 Inquiry\n2 Recharge\n3 Transfer\n4 callMeBack\n5 TellMeNo \n6 FF Serivce\n0 Exit",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_USSD_ERROR_INPUT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"USSD Error Input",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); +// memcpy(smsSentenceItem->english,"Error input, please select\n1 Inquiry\n2 Recharge\n3 Transfer\n4 callMeBack\n5 TellMeNo \n6 FF Serivce\n0 Exit",MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Invalid input, please select\n1 Inquiry\n2 Recharge\n3 Transfer\n4 TellMeNo \n0 Exit",MAX_SMS_LEN); + + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RECHARGE_INPUT_PIN]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"USSD Recharge,input PIN",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Please enter validation code",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RECHARGE_INPUT_PIN_AGAIN]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"USSD Recharge,input PIN again",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Error validation code,please check and enter validation code again",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_LOW_BALANCE_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"USSD Low Balance Notify",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your account balance is too low, please top up in time",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_USSD_COMPLETED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"USSD Operation Complete",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your USSD action is completed",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; +} + + +static void initGPRS() +{ + SmsSentence *smsSentenceItem; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_GPRS_VOLUME_THIS_MONTH]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"GPRS Volume This Month",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"GPRS volume of this month is:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_GPRS_VOLUME_CONSUMED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"GPRS Volume",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your consumed GPRS volume is:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_GPRS_DURATION]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"GPRS Duration",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Duration is:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_GPRS_CHARGED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"GPRS Charged",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Charged:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + +} + + + +static void initSmsSentence() +{ + SmsSentence *smsSentenceItem; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_ACCOUNT_BALANCE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Account Balance",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Account balance is ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_ACCOUNT_PROMOTION]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Account Promotion",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Account promotion is ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_EXPIRED_ON]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Expiring On",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Expiring on:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RECHARGE_ON]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Recharge On",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Please recharge your account in time",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_LAST_CALL_ON]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Last Call On",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Last Call sent on:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_LAST_RECEIVE_ON]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Last Receive On",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Last Call received on:",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CLEAR_FEE_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Clear Balance Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your account balance is cleared because the expiry date is reached",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_GPRS_RECHARGE_SUCCESS]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Recharge succeed",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Recharge succeed",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_OVERDRAFT_NOTIFICATION]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Overdraft SMS Notification ",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have applied over-draft,amount is: ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_PROMOTION_NEWS]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Promotion News ",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Promotion News: recharge $$value, will get $$value bonus within $value days.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FREE_SMS_NOTIFICATION]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Free SMS Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"For free SMS serive, Please send 1 to activate, 2 to deactive, 3 to inquery.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RECHARGE_FAILED_NO_CARD]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"SMS recharge failed-no card",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Wrong recharge card password, please check and try again",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RECHARGE_FAILED_CARD_USED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"SMS recharge failed-card used",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"This card is used",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RECHARGE_FAILED_CARD_EXPIRED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"SMS recharge failed-expired",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"This card is expired",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RECHARGE_FAILED_SYS_FAILURE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"SMS recharge failed-sys failure",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"System failure, please try again.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_ACTIVATION_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Acitvation Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Welcome to use XXX mobile system, your name is ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CAPSMS_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"CAP Plan 0 Notification ",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You are about to change the CAP plan with more preferential tariff",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CAPSMS_1_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"CAP Plan 1 Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You will be charged with tariff 1 ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CAPSMS_2_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"CAP Plan 2 Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You will be charged with tariff 2 ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_CAPGRPS_NOTIFY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"GPRS CAP Plan Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your GPRS service will be charged with new tariff ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_TELL_ME_NUMBER]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Tell Me Number Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your phone number is",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_RENT_CHARGE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Rent Charge Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You were charged for $value, amount USD$$value.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_REG]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F Register Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"F&F activation fee USD$$value, monthly rent USD$$value, $value free minutes, $value free SMS.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_REG_FAILED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F Register failed Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your registration of F&Family service failed for low balance.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_SERVICE_SUSPEND]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F suspended Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your F&F service plan is suspended for low balance.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_PLAN_EXHAUST]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F plan exhaust Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your F&F service plan free minutes or free SMS threshold is reached.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_QUERY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F query result",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"$value F&F numbers, $value free minutes, $value free SMS.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_SERIVCE_REACTIVATE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F reactivate Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have reactivated F&F service. ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_REMOVE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F remove Notification",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your F&F service has been removed. ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_QUERY_NOT_REGISTERED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F query not register",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have not registered F&F service.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_QUERY_NOT_PLAN]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F query not plan user",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"$value F&F numbers, $value. $value ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_QUERY_SUSPENDT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F query state suspended",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your F&F service is suspended, please topup your account.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_QUERY_SUSPEND_REAC]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"F&F query to reactive",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your F&F service is suspended, please press 1 to reactivate the service. ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_FRIEND_FAMILY_QUERY_NO_LIMIT]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"No limitation",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"no limit",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"%s%d, charge %d with data %s, voice %d (Min), SMS %d, Validity %d",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_SUBSCRIBE_CMD]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans Command",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"BS",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_SUBSCRIBE_PLEASE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans Command Title",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Please send, ",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_SUBSCRIBE_OK]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans OK",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Subscribe ok,",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_SUBSCRIBE_NOK]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans NOK",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Subscribe bundle plan failed for insufficient balance",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_QUERY]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans Query",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"you have: Data %dMB, voice %dMin, SMS %d, Expiries on %s",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_DATA_WARN]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Data Warn",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have %dMB data left in bundle plan. When plan expires regular data rate applies.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_DATA_USEDUP]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Data Used Up",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your plan data has been used up, regular data rate applies. Text to 555 to check available plans.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_DATA]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"%s%d, charge %d with data %s, Validity %d (Days)",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_QUERY_DATA]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Plans Query",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Remaining data quota is %dMB, expiring on %s. When plan expires regular prepaid data rate applies.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_USSD_MENU1]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"USSD Menu1",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english," 1 Inquiry\n2 Recharge\n3 Transfer\n4 callMeBack\n5 TellMeNo \n6 FF Serivce\n0 Exit",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_USSD_SUB_CHOICE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle USSD Plans",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"%d %s-%d days for $%d, voice %d Min, SMS %d",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_USSD_DATA]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle USSD Data Plans",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"*555*%d# %s-%d days for $%d",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_NO_REFUND]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle No Refund",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"No Refund",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_USSD_MENU]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + sprintf((char *)smsSentenceItem->title,"%s", "Data Plan USSD Menu"); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + sprintf((char *)smsSentenceItem->english,"%s", "1 Check Plan Status\n2 Subscribe Data Plan\n0 Exit"); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_NOT_APPLIED]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + sprintf((char *)smsSentenceItem->title,"%s", "No Bundle Plan"); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + sprintf((char *)smsSentenceItem->english,"%s", "You have no plan activated."); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_USSD_SUB_DATA_CHOICE]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + sprintf((char *)smsSentenceItem->title,"%s", "Bundle Plan Data Choice"); + memset(smsSentenceItem->english,0,MAX_SMS_LEN);// + //sprintf(smsSentenceItem->english,"%s" , "%d %s - %d day(s) for $%d, voice %d Min, SMS %d"); + sprintf((char *)smsSentenceItem->english,"%s" , "%d %s-%d days for $%d"); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_USSD_SUB_MENU]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + sprintf((char *)smsSentenceItem->title,"%s", "Bundle USSD Plan"); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + sprintf((char *)smsSentenceItem->english,"%s" , "*555*%d# %s-%d days for $%d, voice %d Min, SMS %d"); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_DATA_WARN_HAS_V]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Data Warn",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"You have %d MB data, %d Min voice, %d SMS left in plan. When plan expires regular rate applies.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_VOICE_USEDUP]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Voice Used Up",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your plan voice has been used up, regular rate applies. Text to 555 to check available plans.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_SMS_USEDUP]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,"Bundle Sms Used Up",PpsMaxTitleLen); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,"Your plan sms has been used up, regular sms rate applies. Text to 555 to check available plans.",MAX_SMS_LEN); + smsSentenceItem->existFlag = TRUE; + + + smsSentenceItem = &ppsParam.ppsTables.smsSentence[SMS_BUNDLE_PLAN_USSD_MENU1]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + sprintf((char *)smsSentenceItem->title,"%s", "Bundle Plan USSD Menu"); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + sprintf((char *)smsSentenceItem->english,"%s", "1 Check Plan Status\n2 Subscribe Bundle Plan\n0 Exit"); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsExtSentence[SMS_LAST_CALL_INFO-SMS_MAX_ITEM-1]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + sprintf((char *)smsSentenceItem->title,"%s", "Call Event Notification"); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + sprintf((char *)smsSentenceItem->english,"%s", "Last Call Cost: AUD $C. Call Duration: $Ds. Your current balance is AUD $B expiring on $E."); + smsSentenceItem->existFlag = TRUE; + + smsSentenceItem = &ppsParam.ppsTables.smsExtSentence[SMS_LAST_SMS_INFO-SMS_MAX_ITEM-1]; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + sprintf((char *)smsSentenceItem->title,"%s", "SMS Event Notification"); + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + sprintf((char *)smsSentenceItem->english,"%s", "Last SMS Cost: AUD $C. Your current balance is AUD $B expiring on $E."); + smsSentenceItem->existFlag = TRUE; + + + initPrep(); + initCMB(); + initFreeService(); + initTransfer(); + initPoolAccount(); + initUSSD(); + initGPRS(); +} + +static void strReplace(u8 *string,u8 len,u8 oldData,u8 newData) +{ + int i; + + for(i = 0;i < len;i++) + { + if(string[i] == oldData) + string[i] = newData; + } +} + +void initSMSTable() +{ + memset(&ppsParam.ppsTables.smsSentence,0,sizeof(SmsSentence)*(MaxSmsSentenceItem+MaxSmsSentenceReservedItem)); + initSmsSentence(); +} + +u_char *getSmsSentenceNative(u8 languageType,SMS_SENTENCE org_id) +{ + LANGUAGE_INFO *languageInfo; + int id = org_id; + + if(org_id>SMS_MAX_ITEM) + { + id = org_id-(SMS_MAX_ITEM+1); + languageInfo = &ppsParam.ppsTables.smsExtSentence[id].language[languageType%MAX_LANGUAGE_TYPES]; + } + else + languageInfo = &ppsParam.ppsTables.smsSentence[id].language[languageType%MAX_LANGUAGE_TYPES]; + + switch(id) + { + //case SMS_CMB_AD: + + //break; + default: + if(languageInfo->language[MAX_SMS_LEN] == 0) + { + if(org_id>SMS_MAX_ITEM) + { + ppsParam.ppsTables.smsExtSentence[id].english[MAX_SMS_LEN] = strlen((char *)ppsParam.ppsTables.smsExtSentence[id].english); + return ppsParam.ppsTables.smsExtSentence[id].english; + } + else + { + ppsParam.ppsTables.smsSentence[id].english[MAX_SMS_LEN] = strlen((char *)ppsParam.ppsTables.smsSentence[id].english); + return ppsParam.ppsTables.smsSentence[id].english; + } + } + if(strcasecmp((char *)languageInfo->language,"null") == 0) + return ((u_char *)""); + break; + } + return languageInfo->language; +} + +int pps_getnext_smsSentence(index_t *id) +{ + return pps_getnext_Index(SmsSentenceTable,id); +} + +int pps_getIdle_smsSentence(index_t *id) +{ + return pps_getIdle_Index(SmsSentenceTable,id); +} + +int isSmsSentenceIndexBusy(index_t *index) +{ + return isIndexBusy(SmsSentenceTable,index); +} + +int pps_get_smsSentence(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + SmsSentence *smsSentenceItem; + + index = instance[0]; + if(isIndexValid(SmsSentenceTable,index) == FALSE) + return -1; + if(isIndexBusy(SmsSentenceTable,(index_t *)&index) == FALSE) + return -1; + if(index>SMS_MAX_ITEM) + { + index -= (SMS_MAX_ITEM+1); + smsSentenceItem = &ppsParam.ppsTables.smsExtSentence[index]; + } + else + smsSentenceItem = &ppsParam.ppsTables.smsSentence[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + smsSentenceItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)smsSentenceItem->title); + memcpy(pdata,smsSentenceItem->title,datalen); + break; + case 3: + datalen = strlen((char *)smsSentenceItem->english); + memcpy(pdata,smsSentenceItem->english,datalen); + break; + case 4: + datalen = smsSentenceItem->language[0].language[MAX_SMS_LEN]%MAX_SMS_LEN; + memcpy(pdata,smsSentenceItem->language[0].language,datalen); + break; + case 5: + datalen = smsSentenceItem->language[1].language[MAX_SMS_LEN]%MAX_SMS_LEN; + memcpy(pdata,smsSentenceItem->language[1].language,datalen); + break; + case 6: + datalen = smsSentenceItem->language[2].language[MAX_SMS_LEN]%MAX_SMS_LEN; + memcpy(pdata,smsSentenceItem->language[2].language,datalen); + break; + case 7: + datalen = smsSentenceItem->language[3].language[MAX_SMS_LEN]%MAX_SMS_LEN; + memcpy(pdata,smsSentenceItem->language[3].language,datalen); + break; + case 8: + datalen = smsSentenceItem->language[4].language[MAX_SMS_LEN]%MAX_SMS_LEN; + memcpy(pdata,smsSentenceItem->language[4].language,datalen); + break; + case 9:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + if(column >= 2) + { + strReplace(pdata,datalen,'\n','|'); + } + return datalen; +} + +int pps_set_smsSentence(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + SmsSentence *smsSentenceItem; + int index; + + index = instance[0]; + if(isIndexValid(SmsSentenceTable,index) == FALSE) + return -1; + if(column >= 2) + { + strReplace(pdata,datalen,'|','\n'); + } + if(index>SMS_MAX_ITEM) + { + index -= (SMS_MAX_ITEM+1); + smsSentenceItem = &ppsParam.ppsTables.smsExtSentence[index]; + } + else + smsSentenceItem = &ppsParam.ppsTables.smsSentence[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isSmsSentenceIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + smsSentenceItem = &ppsParam.ppsTables.smsSentence[index]; + smsSentenceItem->existFlag = TRUE; + return index; + } + break; + case 2: + datalen %= PpsMaxTitleLen; + memset(smsSentenceItem->title,0,PpsMaxTitleLen); + memcpy(smsSentenceItem->title,pdata,datalen); + smsSentenceItem->title[datalen] = 0; + break; + case 3: + datalen %= MAX_SMS_LEN; + memset(smsSentenceItem->english,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->english,pdata,datalen); + smsSentenceItem->english[datalen] = 0; + smsSentenceItem->english[MAX_SMS_LEN] = datalen; + break; + case 4: + datalen %= MAX_SMS_LEN; + memset(smsSentenceItem->language[0].language,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->language[0].language,pdata,datalen); + smsSentenceItem->language[0].language[MAX_SMS_LEN] = datalen; + break; + case 5: + datalen %= MAX_SMS_LEN; + memset(smsSentenceItem->language[1].language,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->language[1].language,pdata,datalen); + smsSentenceItem->language[1].language[MAX_SMS_LEN] = datalen; + break; + case 6: + datalen %= MAX_SMS_LEN; + memset(smsSentenceItem->language[2].language,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->language[2].language,pdata,datalen); + smsSentenceItem->language[2].language[MAX_SMS_LEN] = datalen; + break; + case 7: + datalen %= MAX_SMS_LEN; + memset(smsSentenceItem->language[3].language,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->language[3].language,pdata,datalen); + smsSentenceItem->language[3].language[MAX_SMS_LEN] = datalen; + break; + case 8: + datalen %= MAX_SMS_LEN; + memset(smsSentenceItem->language[4].language,0,MAX_SMS_LEN); + memcpy(smsSentenceItem->language[4].language,pdata,datalen); + smsSentenceItem->language[4].language[MAX_SMS_LEN] = datalen; + break; + case 9:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + return -1; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ SmsSentence Table ************************/ +/***********************************************************************/ + + + + +/***********************************************************************/ +/************************ ThirdPartyInfo Table ********************/ +int pps_getnext_thirdPartyInfo(index_t *id) +{ + return pps_getnext_Index(ThirdPartyInfoTable,id); +} + +int pps_getIdle_thirdPartyInfo(index_t *id) +{ + return pps_getIdle_Index(ThirdPartyInfoTable,id); +} + +int isThirdPartyInfoIndexBusy(index_t *index) +{ + return isIndexBusy(ThirdPartyInfoTable,index); +} + +int pps_get_thirdPartyInfo(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + ThirdPartyInfo *thirdPartyInfoItem; + + index = instance[0]; + if(isIndexValid(ThirdPartyInfoTable,index) == FALSE) + return -1; + if(isIndexBusy(ThirdPartyInfoTable,(index_t *)&index) == FALSE) + return -1; + thirdPartyInfoItem = &ppsParam.ppsTables.thirdPartyInfo[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + thirdPartyInfoItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)thirdPartyInfoItem->title); + memcpy(pdata,thirdPartyInfoItem->title,datalen); + break; + case 3: + datalen = strlen((char *)thirdPartyInfoItem->serviceID); + memcpy(pdata,thirdPartyInfoItem->serviceID,datalen); + break; + case 4: + datalen = strlen((char *)thirdPartyInfoItem->servicePassword); + memcpy(pdata,thirdPartyInfoItem->servicePassword,datalen); + break; + case 5:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_thirdPartyInfo(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + ThirdPartyInfo *thirdPartyInfoItem; + int index; + + index = instance[0]; + if(isIndexValid(ThirdPartyInfoTable,index) == FALSE) + return -1; + thirdPartyInfoItem = &ppsParam.ppsTables.thirdPartyInfo[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isThirdPartyInfoIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + thirdPartyInfoItem = &ppsParam.ppsTables.thirdPartyInfo[index]; + thirdPartyInfoItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(thirdPartyInfoItem->title,pdata,datalen); + thirdPartyInfoItem->title[datalen] = 0; + break; + case 3: + memcpy(thirdPartyInfoItem->serviceID,pdata,datalen); + thirdPartyInfoItem->serviceID[datalen] = 0; + break; + case 4: + memcpy(thirdPartyInfoItem->servicePassword,pdata,datalen); + thirdPartyInfoItem->servicePassword[datalen] = 0; + break; + case 5:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(thirdPartyInfoItem,0,sizeof(ThirdPartyInfo)); + thirdPartyInfoItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ ThirdPartyInfo Table ************************/ +/***********************************************************************/ + + +/***********************************************************************/ +/************************ BasicTariffZone Table ************************/ +int pps_getnext_basicTariffZone(index_t *id) +{ + return pps_getnext_Index(BasicTariffZoneTable,id); +} + +int pps_getIdle_basicTariffZone(index_t *id) +{ + return pps_getIdle_Index(BasicTariffZoneTable,id); +} + +int isBasicTariffZoneIndexBusy(index_t *index) +{ + return isIndexBusy(BasicTariffZoneTable,index); +} + +int pps_get_basicTariffZone(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + BasicTariffZone *basicTariffZoneItem; + + index = instance[0]; + if(isIndexValid(BasicTariffZoneTable,index) == FALSE) + return -1; + if(isIndexBusy(BasicTariffZoneTable,(index_t *)&index) == FALSE) + return -1; + basicTariffZoneItem = &ppsParam.ppsTables.basicTariffZone[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + basicTariffZoneItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)basicTariffZoneItem->title); + memcpy(pdata,basicTariffZoneItem->title,datalen); + break; + case 3: + datalen = strlen((char *)basicTariffZoneItem->mcc); + memcpy(pdata,basicTariffZoneItem->mcc,datalen); + pdata[datalen] = 0; + break; + case 4: + datalen = strlen((char *)basicTariffZoneItem->mnc); + memcpy(pdata,basicTariffZoneItem->mnc,datalen); + pdata[datalen] = 0; + break; + case 5: + datalen = PPS_GET_INTEGER(basicTariffZoneItem->lac,pdata,vartype); + break; + case 6: + datalen = PPS_GET_INTEGER(basicTariffZoneItem->cellId,pdata,vartype); + break; + case 7: + datalen = PPS_GET_INTEGER(basicTariffZoneItem->moTariffId,pdata,vartype); + break; + case 8: + datalen = PPS_GET_INTEGER(basicTariffZoneItem->mtTariffId,pdata,vartype); + break; + case 9:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_basicTariffZone(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + BasicTariffZone *basicTariffZoneItem; + int index; + + index = instance[0]; + if(isIndexValid(BasicTariffZoneTable,index) == FALSE) + return -1; + basicTariffZoneItem = &ppsParam.ppsTables.basicTariffZone[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isBasicTariffZoneIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + basicTariffZoneItem = &ppsParam.ppsTables.basicTariffZone[index]; + basicTariffZoneItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(basicTariffZoneItem->title,pdata,datalen); + basicTariffZoneItem->title[datalen] = 0; + break; + case 3: + if(datalen > 3) + return -1; + memcpy(basicTariffZoneItem->mcc,pdata,datalen); + basicTariffZoneItem->mcc[datalen] = 0; + break; + case 4: + if(datalen > 3) + return -1; + memcpy(basicTariffZoneItem->mnc,pdata,datalen); + basicTariffZoneItem->mnc[datalen] = 0; + break; + case 5: + basicTariffZoneItem->lac = PPS_SET_INTEGER(pdata,datalen); + break; + case 6: + basicTariffZoneItem->cellId = PPS_SET_INTEGER(pdata,datalen); + break; + case 7: + basicTariffZoneItem->moTariffId = PPS_SET_INTEGER(pdata,datalen)%MAX_ZONE_NUM; + break; + case 8: + basicTariffZoneItem->mtTariffId = PPS_SET_INTEGER(pdata,datalen)%MAX_ZONE_NUM; + break; + case 9:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(basicTariffZoneItem,0,sizeof(BasicTariffZone)); + basicTariffZoneItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ BasicTariffZone Table ************************/ +/***************************************************************************/ + + +/***********************************************************************/ +/************************ IvrSource Table ************************/ +int pps_getnext_ivrSource(index_t *id) +{ + return pps_getnext_Index(IvrSourceTable,id); +} + +int pps_getIdle_ivrSource(index_t *id) +{ + return pps_getIdle_Index(IvrSourceTable,id); +} + +int isIvrSourceIndexBusy(index_t *index) +{ + return isIndexBusy(IvrSourceTable,index); +} + +int pps_get_ivrSource(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + IvrSource *ivrSourceItem; + + index = instance[0]; + if(isIndexValid(IvrSourceTable,index) == FALSE) + return -1; + if(isIndexBusy(IvrSourceTable,(index_t *)&index) == FALSE) + return -1; + ivrSourceItem = &ppsParam.ppsTables.ivrSource[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + ivrSourceItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)ivrSourceItem->title); + memcpy(pdata,ivrSourceItem->title,datalen); + break; + case 3: + *vartype = INTEGER; + datalen = 1; + pdata[0] = ivrSourceItem->inquiry; + break; + case 4: + *vartype = INTEGER; + datalen = 1; + pdata[0] = ivrSourceItem->recharge; + break; + case 5:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_ivrSource(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + IvrSource *ivrSourceItem; + int index; + + index = instance[0]; + if(isIndexValid(IvrSourceTable,index) == FALSE) + return -1; + ivrSourceItem = &ppsParam.ppsTables.ivrSource[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isIvrSourceIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + ivrSourceItem = &ppsParam.ppsTables.ivrSource[index]; + ivrSourceItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(ivrSourceItem->title,pdata,datalen); + ivrSourceItem->title[datalen] = 0; + break; + case 3: + ivrSourceItem->inquiry = pdata[0]; + break; + case 4: + ivrSourceItem->recharge = pdata[0]; + break; + case 5:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(ivrSourceItem,0,sizeof(IvrSource)); + ivrSourceItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ IvrSource Table ************************/ +/***********************************************************************/ + + +/***********************************************************************/ +/************************ SrfNumber Table ************************/ +int pps_getnext_srfNumber(index_t *id) +{ + return pps_getnext_Index(SrfNumberTable,id); +} + +int pps_getIdle_srfNumber(index_t *id) +{ + return pps_getIdle_Index(SrfNumberTable,id); +} + +int isSrfNumberIndexBusy(index_t *index) +{ + return isIndexBusy(SrfNumberTable,index); +} + +int pps_get_srfNumber(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + SrfNumber *srfNumberItem; + + index = instance[0]; + if(isIndexValid(SrfNumberTable,index) == FALSE) + return -1; + if(isIndexBusy(SrfNumberTable,(index_t *)&index) == FALSE) + return -1; + + srfNumberItem = &ppsParam.ppsTables.srfNumber[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + srfNumberItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)srfNumberItem->title); + memcpy(pdata,srfNumberItem->title,datalen); + break; + case 3: + datalen = strlen((char *)srfNumberItem->number); + memcpy(pdata,srfNumberItem->number,datalen); + break; + case 4:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_srfNumber(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + SrfNumber *srfNumberItem; + int index; + + index = instance[0]; + if(isIndexValid(SrfNumberTable,index) == FALSE) + return -1; + srfNumberItem = &ppsParam.ppsTables.srfNumber[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isSrfNumberIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + srfNumberItem = &ppsParam.ppsTables.srfNumber[index]; + srfNumberItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(srfNumberItem->title,pdata,datalen); + srfNumberItem->title[datalen] = 0; + break; + case 3: + memcpy(srfNumberItem->number,pdata,datalen); + srfNumberItem->number[datalen] = 0; + break; + case 4:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(srfNumberItem,0,sizeof(SrfNumber)); + srfNumberItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ SrfNumber Table ************************/ +/***********************************************************************/ + + +/***********************************************************************/ +/************************ ServiceNumber Table ************************/ +int pps_getnext_ussd_serviceNumber(index_t *id) +{ + return pps_getnext_Index(UssdServiceNumberTable,id); +} + +int pps_getIdle_ussd_serviceNumber(index_t *id) +{ + return pps_getIdle_Index(UssdServiceNumberTable,id); +} + +int isUssdServiceNumberIndexBusy(index_t *index) +{ + return isIndexBusy(UssdServiceNumberTable,index); +} + +int pps_get_ussd_serviceNumber(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + ServiceNumber *serviceNumberItem; + + index = instance[0]; + if(isIndexValid(UssdServiceNumberTable,index) == FALSE) + return -1; + if(isIndexBusy(UssdServiceNumberTable,(index_t *)&index) == FALSE) + return -1; + serviceNumberItem = &ppsParam.ppsTables.ussdServiceNumber[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + serviceNumberItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)serviceNumberItem->title); + memcpy(pdata,serviceNumberItem->title,datalen); + break; + case 3: + datalen = strlen((char *)serviceNumberItem->number); + memcpy(pdata,serviceNumberItem->number,datalen); + break; + case 4:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_ussd_serviceNumber(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + ServiceNumber *serviceNumberItem; + int index; + + index = instance[0]; + if(isIndexValid(UssdServiceNumberTable,index) == FALSE) + return -1; + serviceNumberItem = &ppsParam.ppsTables.ussdServiceNumber[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isUssdServiceNumberIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + serviceNumberItem = &ppsParam.ppsTables.ussdServiceNumber[index]; + serviceNumberItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memset(serviceNumberItem->title,0,PpsMaxTitleLen); + memcpy(serviceNumberItem->title,pdata,datalen); + break; + case 3: + memcpy(serviceNumberItem->number,pdata,datalen); + serviceNumberItem->number[datalen] = 0; + break; + case 4:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(serviceNumberItem,0,sizeof(ServiceNumber)); + serviceNumberItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ ServiceNumber Table ************************/ +/***************************************************************************/ + +/***********************************************************************/ +/************************ ServiceKey Table ************************/ +int pps_getnext_ussd_serviceKey(index_t *id) +{ + return pps_getnext_Index(UssdServiceKeyTable,id); +} + +int pps_getIdle_ussd_serviceKey(index_t *id) +{ + return pps_getIdle_Index(UssdServiceKeyTable,id); +} + +int isUssdServiceKeyIndexBusy(index_t *index) +{ + return isIndexBusy(UssdServiceKeyTable,index); +} + +int pps_get_ussd_serviceKey(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + ServiceKey *serviceKeyItem; + + index = instance[0]; + if(isIndexValid(UssdServiceKeyTable,index) == FALSE) + return -1; + if(isIndexBusy(UssdServiceKeyTable,(index_t *)&index) == FALSE) + return -1; + serviceKeyItem = &ppsParam.ppsTables.ussdServiceKey[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + serviceKeyItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)serviceKeyItem->title); + memcpy(pdata,serviceKeyItem->title,datalen); + break; + case 3: + *vartype = INTEGER; + datalen = 1; + pdata[0] = serviceKeyItem->key; + break; + case 4:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_ussd_serviceKey(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + ServiceKey *serviceKeyItem; + int index; + + index = instance[0]; + if(isIndexValid(UssdServiceKeyTable,index) == FALSE) + return -1; + serviceKeyItem = &ppsParam.ppsTables.ussdServiceKey[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isUssdServiceKeyIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + serviceKeyItem = &ppsParam.ppsTables.ussdServiceKey[index]; + serviceKeyItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(serviceKeyItem->title,pdata,datalen); + serviceKeyItem->title[datalen] = 0; + break; + case 3: + serviceKeyItem->key = pdata[0]; + break; + case 4:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(serviceKeyItem,0,sizeof(ServiceKey)); + serviceKeyItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ ServiceKey Table ************************/ + + +/************************ ServiceNumber Table ************************/ +int pps_getnext_serviceNumber(index_t *id) +{ + return pps_getnext_Index(ServiceNumberTable,id); +} + +int pps_getIdle_serviceNumber(index_t *id) +{ + return pps_getIdle_Index(ServiceNumberTable,id); +} + +int isServiceNumberIndexBusy(index_t *index) +{ + return isIndexBusy(ServiceNumberTable,index); +} + +int pps_get_serviceNumber(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + ServiceNumber *serviceNumberItem; + + index = instance[0]; + if(isIndexValid(ServiceNumberTable,index) == FALSE) + return -1; + if(isIndexBusy(ServiceNumberTable,(index_t *)&index) == FALSE) + return -1; + serviceNumberItem = &ppsParam.ppsTables.serviceNumber[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + serviceNumberItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)serviceNumberItem->title); + memcpy(pdata,serviceNumberItem->title,datalen); + break; + case 3: + datalen = strlen((char *)serviceNumberItem->number); + memcpy(pdata,serviceNumberItem->number,datalen); + break; + case 4:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_serviceNumber(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + ServiceNumber *serviceNumberItem; + int index; + + index = instance[0]; + if(isIndexValid(ServiceNumberTable,index) == FALSE) + return -1; + serviceNumberItem = &ppsParam.ppsTables.serviceNumber[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isServiceNumberIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + serviceNumberItem = &ppsParam.ppsTables.serviceNumber[index]; + serviceNumberItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memset(serviceNumberItem->title,0,PpsMaxTitleLen); + memcpy(serviceNumberItem->title,pdata,datalen); + break; + case 3: + memcpy(serviceNumberItem->number,pdata,datalen); + serviceNumberItem->number[datalen] = 0; + break; + case 4:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(serviceNumberItem,0,sizeof(ServiceNumber)); + serviceNumberItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ ServiceNumber Table ************************/ +/***************************************************************************/ + +/***********************************************************************/ +/************************ ServiceKey Table ************************/ +int pps_getnext_serviceKey(index_t *id) +{ + return pps_getnext_Index(ServiceKeyTable,id); +} + +int pps_getIdle_serviceKey(index_t *id) +{ + return pps_getIdle_Index(ServiceKeyTable,id); +} + +int isServiceKeyIndexBusy(index_t *index) +{ + return isIndexBusy(ServiceKeyTable,index); +} + +int pps_get_serviceKey(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + ServiceKey *serviceKeyItem; + + index = instance[0]; + if(isIndexValid(ServiceKeyTable,index) == FALSE) + return -1; + if(isIndexBusy(ServiceKeyTable,(index_t *)&index) == FALSE) + return -1; + serviceKeyItem = &ppsParam.ppsTables.serviceKey[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + serviceKeyItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)serviceKeyItem->title); + memcpy(pdata,serviceKeyItem->title,datalen); + break; + case 3: + *vartype = INTEGER; + datalen = 1; + pdata[0] = serviceKeyItem->key; + break; + case 4:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_serviceKey(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + ServiceKey *serviceKeyItem; + int index; + + index = instance[0]; + if(isIndexValid(ServiceKeyTable,index) == FALSE) + return -1; + serviceKeyItem = &ppsParam.ppsTables.serviceKey[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isServiceKeyIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + serviceKeyItem = &ppsParam.ppsTables.serviceKey[index]; + serviceKeyItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(serviceKeyItem->title,pdata,datalen); + serviceKeyItem->title[datalen] = 0; + break; + case 3: + serviceKeyItem->key = pdata[0]; + break; + case 4:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(serviceKeyItem,0,sizeof(ServiceKey)); + serviceKeyItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ ServiceKey Table ************************/ + +/***********************************************************************/ + +/***********************************************************************/ +/************************ VmsUserSegment Table ************************/ +int pps_getnext_vmsUserSegment(index_t *id) +{ + return pps_getnext_Index(VmsUserSegmentTable,id); +} + +int pps_getIdle_vmsUserSegment(index_t *id) +{ + return pps_getIdle_Index(VmsUserSegmentTable,id); +} + +int isVmsUserSegmentIndexBusy(index_t *index) +{ + return isIndexBusy(VmsUserSegmentTable,index); +} + +int pps_get_vmsUserSegment(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + VmsUserSegment *vmsUserSegmentItem; + + index = instance[0]; + if(isIndexValid(VmsUserSegmentTable,index) == FALSE) + return -1; + if(isIndexBusy(VmsUserSegmentTable,(index_t *)&index) == FALSE) + return -1; + vmsUserSegmentItem = &ppsParam.ppsTables.vmsUserSegment[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + vmsUserSegmentItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)vmsUserSegmentItem->title); + memcpy(pdata,vmsUserSegmentItem->title,datalen); + break; + case 3: + datalen = strlen((char *)vmsUserSegmentItem->startMsisdn); + memcpy(pdata,vmsUserSegmentItem->startMsisdn,datalen); + break; + case 4: + datalen = strlen((char *)vmsUserSegmentItem->endMsisdn); + memcpy(pdata,vmsUserSegmentItem->endMsisdn,datalen); + break; + case 5: + datalen = strlen((char *)vmsUserSegmentItem->vmsPLMNserviceNumber); + memcpy(pdata,vmsUserSegmentItem->vmsPLMNserviceNumber,datalen); + break; + case 6: + datalen = strlen((char *)vmsUserSegmentItem->vmsPSTNserviceNumber); + memcpy(pdata,vmsUserSegmentItem->vmsPSTNserviceNumber,datalen); + break; + case 7: + datalen = strlen((char *)vmsUserSegmentItem->leaveMessageNumber); + memcpy(pdata,vmsUserSegmentItem->leaveMessageNumber,datalen); + break; + case 8:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_vmsUserSegment(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + VmsUserSegment *vmsUserSegmentItem; + int index; + + index = instance[0]; + if(isIndexValid(VmsUserSegmentTable,index) == FALSE) + return -1; + vmsUserSegmentItem = &ppsParam.ppsTables.vmsUserSegment[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isVmsUserSegmentIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + vmsUserSegmentItem = &ppsParam.ppsTables.vmsUserSegment[index]; + vmsUserSegmentItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(vmsUserSegmentItem->title,pdata,datalen); + vmsUserSegmentItem->title[datalen] = 0; + break; + case 3: + memcpy(vmsUserSegmentItem->startMsisdn,pdata,datalen); + vmsUserSegmentItem->startMsisdn[datalen] = 0; + break; + case 4: + memcpy(vmsUserSegmentItem->endMsisdn,pdata,datalen); + vmsUserSegmentItem->endMsisdn[datalen] = 0; + break; + case 5: + memcpy(vmsUserSegmentItem->vmsPLMNserviceNumber,pdata,datalen); + vmsUserSegmentItem->vmsPLMNserviceNumber[datalen] = 0; + break; + case 6: + memcpy(vmsUserSegmentItem->vmsPSTNserviceNumber,pdata,datalen); + vmsUserSegmentItem->vmsPSTNserviceNumber[datalen] = 0; + break; + case 7: + memcpy(vmsUserSegmentItem->leaveMessageNumber,pdata,datalen); + vmsUserSegmentItem->leaveMessageNumber[datalen] = 0; + break; + case 8:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(vmsUserSegmentItem,0,sizeof(VmsUserSegment)); + vmsUserSegmentItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************* VmsUserSegment Table ************************/ + +/************************ gsn Table ************************/ +int pps_getnext_gsn(index_t *id) +{ + return pps_getnext_Index(RadiusGsnTable,id); +} + +int pps_getIdle_gsn(index_t *id) +{ + return pps_getIdle_Index(RadiusGsnTable,id); +} + +int isGsnIndexBusy(index_t *index) +{ + return isIndexBusy(RadiusGsnTable,index); +} + + + +int pps_get_gsn(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,index; + PPS_RADIUS_NAS_INFO *gsnItem; + + index = instance[0]; + if(isIndexValid(RadiusGsnTable,index) == FALSE) + return -1; + if(isIndexBusy(RadiusGsnTable,(index_t *)&index) == FALSE) + return -1; + + gsnItem = &ppsParam.ppsTables.gsn[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + gsnItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)gsnItem->title); + memcpy(pdata,gsnItem->title,datalen); + break; + case 3: + datalen = PPS_GET_INTEGER(gsnItem->volumeMeterUnit,pdata,vartype); + break; + case 4: + datalen = PPS_GET_INTEGER(gsnItem->durationMeterUnit,pdata,vartype); + break; + case 5: + pdata[0] = gsnItem->tariffID; + break; + case 6: + *vartype = 0x40; + memcpy(pdata,&gsnItem->nasInfo.nas_ip,4); + datalen = 4; + break; + case 7: + datalen = strlen((char *)gsnItem->nasInfo.share_key); + memcpy(pdata,&gsnItem->nasInfo.share_key,datalen); + break; + case 8: + datalen = strlen((char *)gsnItem->nasInfo.password); + memcpy(pdata,&gsnItem->nasInfo.password,datalen); + break; + case 9:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_gsn(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + PPS_RADIUS_NAS_INFO *gsnItem; + int index; + + index = instance[0]; + if(isIndexValid(RadiusGsnTable,index) == FALSE) + return -1; + gsnItem = &ppsParam.ppsTables.gsn[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isGsnIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + gsnItem = &ppsParam.ppsTables.gsn[index]; + gsnItem->existFlag = TRUE; + memset(&gsnItem->nasInfo,0,sizeof(RADIUS_NAS_INFORMATION)); + pps_set_nas(index,&gsnItem->nasInfo); + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(gsnItem->title,pdata,datalen); + gsnItem->title[datalen] = 0; + break; + case 3: + gsnItem->volumeMeterUnit = PPS_SET_INTEGER(pdata,datalen) << 10; + break; + case 4: + gsnItem->durationMeterUnit = PPS_SET_INTEGER(pdata,datalen) << 10; + break; + case 5: + gsnItem->tariffID = pdata[0]; + break; + case 6: + memcpy(&gsnItem->nasInfo.nas_ip,pdata,4); + pps_set_nas(index,&gsnItem->nasInfo); + break; + case 7: + datalen %= RADIUS_MAX_LEN_OF_SHARE_KEY; + memcpy(&gsnItem->nasInfo.share_key,pdata,datalen); + gsnItem->nasInfo.share_key[datalen] = 0; + pps_set_nas(index,&gsnItem->nasInfo); + break; + case 8: + datalen %= RADIUS_MAX_LEN_OF_PASSWORD; + memcpy(&gsnItem->nasInfo.password,pdata,datalen); + gsnItem->nasInfo.password[datalen] = 0; + pps_set_nas(index,&gsnItem->nasInfo); + break; + case 9:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(gsnItem,0,sizeof(PPS_RADIUS_NAS_INFO)); + gsnItem->existFlag = FALSE; + pps_del_nas(index); + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ gsn Table ************************/ + + +/************************ sgsn Table ************************/ +int pps_getnext_sgsn(index_t *id) +{ + return pps_getnext_Index(RadiusSgsnTable,id); +} + +int pps_getIdle_sgsn(index_t *id) +{ + return pps_getIdle_Index(RadiusSgsnTable,id); +} + +int isSgsnIndexBusy(index_t *index) +{ + return isIndexBusy(RadiusSgsnTable,index); +} + +int pps_get_sgsn(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,index; + PPS_RADIUS_SGSN_INFO *sgsnItem; + + index = instance[0]; + if(isIndexValid(RadiusSgsnTable,index) == FALSE) + return -1; + if(isIndexBusy(RadiusSgsnTable,(index_t *)&index) == FALSE) + return -1; + + sgsnItem = &ppsParam.ppsTables.sgsn[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + sgsnItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)sgsnItem->title); + memcpy(pdata,sgsnItem->title,datalen); + break; + break; + case 3: + *vartype = 0x40; + memcpy(pdata,&sgsnItem->sgsnIP,4); + datalen = 4; + break; + case 4: + *vartype = INTEGER; + pdata[0] = sgsnItem->cosID; + break; + case 5: + *vartype = OctetString; + strcpy((char *)pdata, (char *)sgsnItem->apnName); + datalen = strlen((char *)sgsnItem->apnName); + break; + case 6: + *vartype = INTEGER; + pdata[0] = sgsnItem->tariffID; + break; + case 7:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_sgsn(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + PPS_RADIUS_SGSN_INFO *sgsnItem; + int index; + + index = instance[0]; + if(isIndexValid(RadiusSgsnTable,index) == FALSE) + return -1; + sgsnItem = &ppsParam.ppsTables.sgsn[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isSgsnIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + sgsnItem = &ppsParam.ppsTables.sgsn[index]; + sgsnItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(sgsnItem->title,pdata,datalen); + sgsnItem->title[datalen] = 0; + break; + case 3: + memcpy(&sgsnItem->sgsnIP,pdata,4); + break; + case 4: + sgsnItem->cosID = pdata[0]; + break; + case 5: + memset(sgsnItem->apnName, 0x00, 16); + memcpy(&sgsnItem->apnName,pdata, datalen); + break; + case 6: + sgsnItem->tariffID = pdata[0]; + break; + case 7:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(sgsnItem,0,sizeof(PPS_RADIUS_SGSN_INFO)); + sgsnItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************ sgsn Table ************************/ + +/************************ Begining of BundlePlan Table ********/ +int pps_getnext_bundlePlan(index_t *id) +{ + return pps_getnext_Index(BundlePlanTable,id); +} + +int pps_getIdle_bundlePlan(index_t *id) +{ + return pps_getIdle_Index(BundlePlanTable, id); +} + +int isBundlePlanIndexBusy(index_t *index) +{ + return isIndexBusy(BundlePlanTable,index); +} + + +int pps_get_bundle_plan(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,index; + serviceBundlePlan *bundlePlan; + + index = instance[0]; + if(isIndexValid(BundlePlanTable,index) == FALSE) + return -1; + if(isIndexBusy(BundlePlanTable,(index_t *)&index) == FALSE) + return -1; + + bundlePlan = &ppsParam.ppsTables.bundlePlans[index]; + *vartype = OctetString; + switch(column) + { + case 1: + *vartype = INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + bundlePlan->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)bundlePlan->title); + memcpy(pdata,bundlePlan->title,datalen); + break; + break; + case 3: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->charge, pdata, vartype); + break; + case 4: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->data, pdata, vartype); + break; + case 5: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->mo_voice, pdata, vartype); + break; + break; + case 6: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->mt_voice, pdata, vartype); + break; + break; + case 7: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->sms, pdata, vartype); + break; + break; + case 8: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->validity, pdata, vartype); + break; + break; + case 9: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->apply_flag, pdata, vartype); + break; + case 10: + *vartype = INTEGER; + datalen = PPS_GET_INTEGER(bundlePlan->apply_code, pdata, vartype); + break; + case 11:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_bundle_plan(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + serviceBundlePlan *bundlePlan; + int index; + + index = instance[0]; + if(isIndexValid(BundlePlanTable,index) == FALSE) + return -1; + bundlePlan = &ppsParam.ppsTables.bundlePlans[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isBundlePlanIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + bundlePlan = &ppsParam.ppsTables.bundlePlans[index]; + bundlePlan->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(bundlePlan->title,pdata,datalen); + bundlePlan->title[datalen] = 0; + break; + case 3: + bundlePlan->charge = PPS_SET_INTEGER(pdata, datalen); + break; + case 4: + bundlePlan->data = PPS_SET_INTEGER(pdata, datalen); + break; + case 5: + bundlePlan->mo_voice = PPS_SET_INTEGER(pdata, datalen); + break; + case 6: + bundlePlan->mt_voice = PPS_SET_INTEGER(pdata, datalen); + break; + case 7: + bundlePlan->sms = PPS_SET_INTEGER(pdata, datalen); + break; + case 8: + bundlePlan->validity = PPS_SET_INTEGER(pdata, datalen); + break; + case 9: + bundlePlan->apply_flag = PPS_SET_INTEGER(pdata, datalen); + break; + case 10: + bundlePlan->apply_code = PPS_SET_INTEGER(pdata, datalen); + break; + case 11:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(bundlePlan,0,sizeof(serviceBundlePlan)); + bundlePlan->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} + +/************************ Begining of BundlePlan Table ********/ + +/***************************************************************/ +/************************* COS Table ************************/ +int pps_getnext_cos(index_t *id) +{ + return pps_getnext_Index(CosTable,id); +} + +int pps_getIdle_cos(index_t *id) +{ + return pps_getIdle_Index(CosTable,id); +} + +int isCosIndexBusy(index_t *id) +{ + return isIndexBusy(CosTable,id); +} + +int pps_get_cos(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 0,index; + COSTable *cosItem; + + index = instance[0]; + if(isIndexValid(CosTable,index) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&index) == FALSE) + return -1; + + cosItem = &ppsParam.ppsTables.cosTable[index]; + *vartype = INTEGER; + switch(column) + { + case 1: + datalen = 1; + pdata[0] = index; + break; + case 2: + *vartype = OctetString; + cosItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)cosItem->title); + memcpy(pdata,cosItem->title,datalen); + break; + case 3: + datalen = 1; + pdata[0] = MaxTariffTableItem; + break; + case 4: + datalen = 1; + pdata[0] = MaxServiceControlTableItem; + break; + case 5: + datalen = 1; + pdata[0] = MaxAccountValidityTableItem; + break; + case 6: + datalen = 1; + pdata[0] = MaxSmsNotificationInquiryTableItem; + break; + case 7: + datalen = 1; + pdata[0] = MaxRechargeCardType; + break; + case 8: + datalen = 1; + pdata[0] = MaxRechargeCardType; + break; + case 9: + datalen = 1; + pdata[0] = MaxcapPlanTableItem; + break; + case 10: + datalen = 1; + pdata[0] = MaxPoolAccountTableItem; + break; + case 11: + datalen = 1; + pdata[0] = MaxGprsTableItem; + break; + case 12:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cos(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + COSTable *cosItem; + int index; + + index = instance[0]; + if(isIndexValid(CosTable,index) == FALSE) + return -1; + cosItem = &ppsParam.ppsTables.cosTable[index]; + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(isCosIndexBusy((index_t *)&index) == TRUE) + return -1; + else + { + cosItem = &ppsParam.ppsTables.cosTable[index]; + initCosTable(cosItem); + cosItem->existFlag = TRUE; + return index; + } + break; + case 2: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(cosItem->title,pdata,datalen); + cosItem->title[datalen] = 0; + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + return -1; + break; + case 11: + return -1; + break; + case 12:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(cosItem,0,sizeof(COSTable)); + cosItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/************************* COS Table ************************/ +/***************************************************************/ + +/***************************************************************/ +/********************** tariff Table **********************/ +int pps_getnext_cosTariff(index_t *id) +{ + return pps_getnext_Index(TariffTable,id); +} + +int pps_getIdle_cosTariff(index_t *id) +{ + return pps_getIdle_Index(TariffTable,id); +} + +int isCosTariffIndexBusy(index_t *id) +{ + return isIndexBusy(TariffTable,id); +} + +int pps_get_cosTariff(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosTariff *tariffCosItem; + promotion_plan_control *pPromotionControl; + + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(TariffTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(TariffTable,(index_t *)instance) == FALSE) + return -1; + + tariffCosItem = &ppsParam.ppsTables.cosTable[cosIndex].tariff[subIndex]; + pPromotionControl = &tariffCosItem->promotionUseControl; + *vartype = INTEGER; + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + tariffCosItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)tariffCosItem->title); + memcpy(pdata,tariffCosItem->title,datalen); + break; + case 4: + pdata[0] = tariffCosItem->moTariffID; + break; + case 5: + pdata[0] = tariffCosItem->mtTariffID; + break; + case 6: + pdata[0] = tariffCosItem->chargeBy; + break; + case 7: + *vartype = OctetString; + datalen = 8; + AsciiTime((char *)pdata,tariffCosItem->promotionUseControl.rechargePromotionStartDate); + break; + case 8: + *vartype = OctetString; + datalen = 8; + AsciiTime((char *)pdata,tariffCosItem->promotionUseControl.rechargePromotionEndDate); + break; + case 9: + pdata[0] = tariffCosItem->capPlanResetDay; + break; + case 10: + pdata[0] = pPromotionControl->usedForCall.IDD; + break; + case 11: + pdata[0] = pPromotionControl->usedForCall.NDD; + break; + case 12: + pdata[0] = pPromotionControl->usedForCall.LOCAL; + break; + case 13: + pdata[0] = pPromotionControl->usedForSMS.IDD; + break; + case 14: + pdata[0] = pPromotionControl->usedForSMS.NDD; + break; + case 15: + pdata[0] = pPromotionControl->usedForSMS.LOCAL; + break; + case 16: + pdata[0] = pPromotionControl->usedForGPRS.allowed; + break; + case 17: + pdata[0] = pPromotionControl->transfer.transfer; + break; + case 18: + pdata[0] = pPromotionControl->transfer.transferPrioriy; + break; + case 19: + pdata[0] = tariffCosItem->promotionUsedForRoDebit; + break; + case 20:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosTariff(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + CosTariff *tariffCosItem; + int cosIndex,subIndex; + promotion_plan_control *pPromotionControl; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(TariffTable,subIndex) == FALSE) + return -1; + + tariffCosItem = &ppsParam.ppsTables.cosTable[cosIndex].tariff[subIndex]; + pPromotionControl = &tariffCosItem->promotionUseControl; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(tariffCosItem->title,pdata,datalen); + tariffCosItem->title[datalen] = 0; + break; + case 4: + tariffCosItem->moTariffID = pdata[0]; + break; + case 5: + tariffCosItem->mtTariffID = pdata[0]; + break; + case 6: + tariffCosItem->chargeBy = pdata[0]; + break; + case 7: + { + u_char buf[32] = {0}; + //struct tm tmnow; + + memcpy(buf,pdata,8); + strcat((char *)buf+8, "000000"); + tariffCosItem->promotionUseControl.rechargePromotionStartDate = MakeTime(NULL, (char *)buf); + } + break; + case 8: + { + u_char buf[32] = {0}; + //struct tm tmnow; + + memcpy(buf,pdata,8); + strcat((char *)buf+8, "000000"); + tariffCosItem->promotionUseControl.rechargePromotionEndDate = MakeTime(NULL, (char *)buf); + } + break; + case 9: + tariffCosItem->capPlanResetDay = pdata[0]; + break; + case 10: + pPromotionControl->usedForCall.IDD = pdata[0]; + break; + case 11: + pPromotionControl->usedForCall.NDD = pdata[0]; + break; + case 12: + pPromotionControl->usedForCall.LOCAL = pdata[0]; + break; + case 13: + pPromotionControl->usedForSMS.IDD = pdata[0]; + break; + case 14: + pPromotionControl->usedForSMS.NDD = pdata[0]; + break; + case 15: + pPromotionControl->usedForSMS.LOCAL = pdata[0]; + break; + case 16: + pPromotionControl->usedForGPRS.allowed = pdata[0]; + break; + case 17: + pPromotionControl->transfer.transfer = pdata[0]; + break; + case 18: + pPromotionControl->transfer.transferPrioriy = pdata[0]; + break; + case 19: + tariffCosItem->promotionUsedForRoDebit = pdata[0]; + break; + case 20:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(tariffCosItem,0,sizeof(CosTariff)); + tariffCosItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/*********************** tariff Table **********************/ +/***************************************************************/ + + +/***************************************************************/ +/****************** serviceControl Table ******************/ +int pps_getnext_cosServiceControl(index_t *id) +{ + return pps_getnext_Index(ServiceControlTable,id); +} + +int pps_getIdle_cosServiceControl(index_t *id) +{ + return pps_getIdle_Index(ServiceControlTable,id); +} + +int isCosServiceControlIndexBusy(index_t *id) +{ + return isIndexBusy(ServiceControlTable,id); +} + +int pps_get_cosServiceControl(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosServiceControl *serviceControlItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(ServiceControlTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(ServiceControlTable,(index_t *)instance) == FALSE) + return -1; + + serviceControlItem = &ppsParam.ppsTables.cosTable[cosIndex].serviceControl[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + serviceControlItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)serviceControlItem->title); + memcpy(pdata,serviceControlItem->title,datalen); + break; + case 4: + pdata[0] = serviceControlItem->moThresholdSet; + break; + case 5: + datalen = PPS_GET_INTEGER(serviceControlItem->moMinimumBalance,pdata,vartype); + break; + case 6: + pdata[0] = serviceControlItem->mtChargeFlag; + break; + case 7: + pdata[0] = serviceControlItem->mtBalanceControl; + break; + case 8: + datalen = PPS_GET_INTEGER(serviceControlItem->mtBalanceThreshold,pdata,vartype); + break; + case 9: + pdata[0] = serviceControlItem->closeUserGroupService; + break; + case 10: + pdata[0] = serviceControlItem->rechargeViaCreditCard; + break; + case 11: + pdata[0] = serviceControlItem->creditVault; + break; + case 12: + datalen = PPS_GET_INTEGER(serviceControlItem->creditVaultAmount,pdata,vartype); + break; + case 13: + pdata[0] = serviceControlItem->poolAccountFlag; + break; + case 14: + pdata[0] = serviceControlItem->poolAccountChangeChargeFlag; + break; + case 15: + pdata[0] = serviceControlItem->poolAccountFreeChangeTimes; + break; + case 16: + pdata[0] = serviceControlItem->relatedCosID; + break; + case 17: + pdata[0] = serviceControlItem->freeSMSActiveDays; + break; + case 18: + pdata[0] = serviceControlItem->freeSMSRentType; + break; + case 19: + pdata[0] = serviceControlItem->callMeBackThreshold; + //datalen = PPS_GET_INTEGER(serviceControlItem->callMeBackThreshold,pdata,vartype); + break; + case 20: + pdata[0] = serviceControlItem->callMeBackMaxTimes; + break; + case 21: + pdata[0] = serviceControlItem->mtSMSCharge; + break; + case 22: + //pdata[0] = serviceControlItem->bundle_data_warning_threashold; + datalen = PPS_GET_INTEGER(serviceControlItem->bundle_data_warning_threashold*5,pdata,vartype); + break; + case 23: + //pdata[0] = serviceControlItem->bundle_data_warning_threashold_low; + datalen = PPS_GET_INTEGER(serviceControlItem->bundle_data_warning_threashold_low*5,pdata,vartype); + break; + case 24:// Event charging flag + datalen = PPS_GET_INTEGER(serviceControlItem->event_charging_flag, pdata, vartype); + break; + case 25:// Cap or Bundle used in Tariff Table + datalen = PPS_GET_INTEGER(serviceControlItem->cap_or_bundle_in_tariff, pdata, vartype); + break; + case 26:// bundle function control + datalen = PPS_GET_INTEGER(serviceControlItem->bundle_plan_contorl, pdata, vartype); + break; + case 30:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosServiceControl(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + CosServiceControl *serviceControlItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(ServiceControlTable,subIndex) == FALSE) + return -1; + + serviceControlItem = &ppsParam.ppsTables.cosTable[cosIndex].serviceControl[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(serviceControlItem->title,pdata,datalen); + serviceControlItem->title[datalen] = 0; + break; + case 4: + serviceControlItem->moThresholdSet = pdata[0]; + break; + case 5: + serviceControlItem->moMinimumBalance = PPS_SET_INTEGER(pdata,datalen); + break; + case 6: + serviceControlItem->mtChargeFlag = pdata[0]; + break; + case 7: + serviceControlItem->mtBalanceControl = pdata[0]; + break; + case 8: + serviceControlItem->mtBalanceThreshold = PPS_SET_INTEGER(pdata,datalen); + break; + case 9: + serviceControlItem->closeUserGroupService = pdata[0]; + break; + case 10: + serviceControlItem->rechargeViaCreditCard = pdata[0]; + break; + case 11: + serviceControlItem->creditVault = pdata[0]; + break; + case 12: + serviceControlItem->creditVaultAmount = PPS_SET_INTEGER(pdata,datalen); + break; + case 13: + serviceControlItem->poolAccountFlag = pdata[0]; + break; + case 14: + serviceControlItem->poolAccountChangeChargeFlag = pdata[0]; + break; + case 15: + serviceControlItem->poolAccountFreeChangeTimes = pdata[0]; + break; + case 16: + serviceControlItem->relatedCosID = pdata[0]; + break; + case 17: + serviceControlItem->freeSMSActiveDays = PPS_SET_INTEGER(pdata,datalen); //pdata[0]; + break; + case 18: + serviceControlItem->freeSMSRentType = pdata[0]; + break; + case 19: + serviceControlItem->callMeBackThreshold = PPS_SET_INTEGER(pdata,datalen); + break; + case 20: + serviceControlItem->callMeBackMaxTimes = PPS_SET_INTEGER(pdata,datalen); + break; + case 21: + serviceControlItem->mtSMSCharge = PPS_SET_INTEGER(pdata,datalen); + break; + case 22: + //serviceControlItem->bundle_data_warning_threashold = pdata[0]; + serviceControlItem->bundle_data_warning_threashold = PPS_SET_INTEGER(pdata,datalen) / 5; + break; + case 23: + //serviceControlItem->bundle_data_warning_threashold_low = pdata[0]; + serviceControlItem->bundle_data_warning_threashold_low = PPS_SET_INTEGER(pdata,datalen) / 5; + break; + case 24:// Event Charging flag + serviceControlItem->event_charging_flag = PPS_SET_INTEGER(pdata,datalen); + break; + case 25:// Cap or Bundle used in Tariff Table + serviceControlItem->cap_or_bundle_in_tariff = PPS_SET_INTEGER(pdata,datalen); + break; + case 26:// Bundle control + serviceControlItem->bundle_plan_contorl = PPS_SET_INTEGER(pdata,datalen); + break; + case 30:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(serviceControlItem,0,sizeof(CosServiceControl)); + serviceControlItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/*********************** serviceControl Table **********************/ +/************************************************************************/ + +/*********************** serviceControl Table **********************/ +/************************************************************************/ + +/***************************************************************/ +/****************** accountValidity Table ******************/ +int pps_getnext_cosAccountValidity(index_t *id) +{ + return pps_getnext_Index(AccountValidityTable,id); +} + +int pps_getIdle_cosAccountValidity(index_t *id) +{ + return pps_getIdle_Index(AccountValidityTable,id); +} + +int isCosAccountValidityIndexBusy(index_t *id) +{ + return isIndexBusy(AccountValidityTable,id); +} + +int pps_get_cosAccountValidity(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosAccountValidity *accountValidityItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(AccountValidityTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(AccountValidityTable,(index_t *)instance) == FALSE) + return -1; + + accountValidityItem = &ppsParam.ppsTables.cosTable[cosIndex].accountValidity[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + accountValidityItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)accountValidityItem->title); + memcpy(pdata,accountValidityItem->title,datalen); + break; + case 4: + datalen = PPS_GET_INTEGER(accountValidityItem->maxAccountValidityDays,pdata,vartype); + break; + case 5: + pdata[0] = accountValidityItem->actionWhenAccountExpires; + break; + case 6: + datalen = PPS_GET_INTEGER(accountValidityItem->daysKeepingAnExpiredAccount,pdata,vartype); + break; + case 7: + pdata[0] = accountValidityItem->actionAfterDaysKeepingAnExpiredAccount; + break; + case 8: + pdata[0] = accountValidityItem->actionAfterRecharge; + break; + case 9: + pdata[0] = accountValidityItem->actionAfterBalanceDepleted; + break; + case 10: + pdata[0] = accountValidityItem->validDaysChangeTo; + break; + case 11: + pdata[0] = accountValidityItem->activiationByInquiryIs; + break; + case 12: + datalen = PPS_GET_INTEGER(accountValidityItem->validiDaysActivatedByInquiringAccountWithZeroBalance,pdata,vartype); + break; + case 13: + pdata[0] = accountValidityItem->actionWhenMOorMTExpired; + break; + case 14: + pdata[0] = accountValidityItem->bundlePlanIDWhenActivated; + break; + case 20:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosAccountValidity(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + CosAccountValidity *accountValidityItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(AccountValidityTable,subIndex) == FALSE) + return -1; + + accountValidityItem = &ppsParam.ppsTables.cosTable[cosIndex].accountValidity[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(accountValidityItem->title,pdata,datalen); + accountValidityItem->title[datalen] = 0; + break; + case 4: + accountValidityItem->maxAccountValidityDays = PPS_SET_INTEGER(pdata,datalen); + break; + case 5: + accountValidityItem->actionWhenAccountExpires = pdata[0]; + break; + case 6: + accountValidityItem->daysKeepingAnExpiredAccount = PPS_SET_INTEGER(pdata,datalen); + break; + case 7: + accountValidityItem->actionAfterDaysKeepingAnExpiredAccount = PPS_SET_INTEGER(pdata,datalen); + break; + case 8: + accountValidityItem->actionAfterRecharge = pdata[0]; + break; + case 9: + accountValidityItem->actionAfterBalanceDepleted = pdata[0]; + break; + case 10: + accountValidityItem->validDaysChangeTo = PPS_SET_INTEGER(pdata,datalen); + break; + case 11: + accountValidityItem->activiationByInquiryIs = PPS_SET_INTEGER(pdata,datalen); + break; + case 12: + accountValidityItem->validiDaysActivatedByInquiringAccountWithZeroBalance = PPS_SET_INTEGER(pdata,datalen); + break; + case 13: + accountValidityItem->actionWhenMOorMTExpired = pdata[0]; + break; + case 14: + accountValidityItem->bundlePlanIDWhenActivated = pdata[0]; + break; + case 20:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(accountValidityItem,0,sizeof(CosAccountValidity)); + accountValidityItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/*********************** accountValidity Table **********************/ +/************************************************************************/ + +/****************** FriendFamilyControl Table ******************/ +int pps_getnext_cos_friend_family(index_t *id) +{ + return pps_getnext_Index(FriendFamilyTable,id); +} + +int pps_getIdle_cos_friend_family(index_t *id) +{ + return pps_getIdle_Index(FriendFamilyTable,id); +} + +int isCosFriendFamilyIndexBusy(index_t *id) +{ + return isIndexBusy(FriendFamilyTable,id); +} + +int pps_get_cos_friend_family(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosFriendFamilyControl *friendFamilyControl; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(FriendFamilyTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(FriendFamilyTable,(index_t *)instance) == FALSE) + return -1; + + friendFamilyControl = &ppsParam.ppsTables.cosTable[cosIndex].friendFamilyControl[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + friendFamilyControl->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)friendFamilyControl->title); + memcpy(pdata,friendFamilyControl->title,datalen); + break; + case 4: + pdata[0] = friendFamilyControl->friendFamilyFlag; + break; + case 5: + pdata[0] = friendFamilyControl->friendFamilyChangeChargeFlag; + break; + case 6: + pdata[0] = friendFamilyControl->friendFamilyFreeChangeTimes; + break; + case 7: + pdata[0] = friendFamilyControl->friendFamilyNumberTypeLocal; + break; + case 8: + pdata[0] = friendFamilyControl->friendFamilyNumberTypeNDD; + break; + case 9: + pdata[0] = friendFamilyControl->friendFamilyNumberTypeIDD; + break; + case 10: + datalen = PPS_GET_INTEGER(friendFamilyControl->balanceThresholdForFriendFamilyCall,pdata,vartype); + break; + case 11: + pdata[0] = friendFamilyControl->keepOrRemoveFriendFamilyNumber; + break; + case 12: + datalen = PPS_GET_INTEGER(friendFamilyControl->balanceThresholdToKeepFriendFamilyNumber,pdata,vartype); + break; + case 13: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[0].rentCharge,pdata,vartype); + break; + case 14: + pdata[0] = friendFamilyControl->friendFamilyPlan[0].maxNumbers; + break; + case 15: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[0].freeCallDuration,pdata,vartype); + break; + case 16: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[0].freeSMS,pdata,vartype); + break; + case 17: + pdata[0] = friendFamilyControl->friendFamilyPlan[0].rentID; + break; + case 18: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[1].rentCharge,pdata,vartype); + break; + case 19: + pdata[0] = friendFamilyControl->friendFamilyPlan[1].maxNumbers; + break; + case 20: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[1].freeCallDuration,pdata,vartype); + break; + case 21: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[1].freeSMS,pdata,vartype); + break; + case 22: + pdata[0] = friendFamilyControl->friendFamilyPlan[1].rentID; + break; + case 23: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[2].rentCharge,pdata,vartype); + break; + case 24: + pdata[0] = friendFamilyControl->friendFamilyPlan[2].maxNumbers; + break; + case 25: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[2].freeCallDuration,pdata,vartype); + break; + case 26: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[2].freeSMS,pdata,vartype); + break; + case 27: + pdata[0] = friendFamilyControl->friendFamilyPlan[2].rentID; + break; + case 28: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[3].rentCharge,pdata,vartype); + break; + case 29: + pdata[0] = friendFamilyControl->friendFamilyPlan[3].maxNumbers; + break; + case 30: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[3].freeCallDuration,pdata,vartype); + break; + case 31: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[3].freeSMS,pdata,vartype); + break; + case 32: + pdata[0] = friendFamilyControl->friendFamilyPlan[3].rentID; + break; + case 33: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[4].rentCharge,pdata,vartype); + break; + case 34: + pdata[0] = friendFamilyControl->friendFamilyPlan[4].maxNumbers; + break; + case 35: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[4].freeCallDuration,pdata,vartype); + break; + case 36: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[4].freeSMS,pdata,vartype); + break; + case 37: + pdata[0] = friendFamilyControl->friendFamilyPlan[4].rentID; + break; + case 38: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[5].rentCharge,pdata,vartype); + break; + case 39: + pdata[0] = friendFamilyControl->friendFamilyPlan[5].maxNumbers; + break; + case 40: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[5].freeCallDuration,pdata,vartype); + break; + case 41: + datalen = PPS_GET_INTEGER(friendFamilyControl->friendFamilyPlan[5].freeSMS,pdata,vartype); + break; + case 42: + pdata[0] = friendFamilyControl->friendFamilyPlan[5].rentID; + break; + case 43:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cos_friend_family(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + CosFriendFamilyControl *friendFamilyControl; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(FriendFamilyTable,subIndex) == FALSE) + return -1; + + friendFamilyControl = &ppsParam.ppsTables.cosTable[cosIndex].friendFamilyControl[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(friendFamilyControl->title,pdata,datalen); + friendFamilyControl->title[datalen] = 0; + break; + case 4: + friendFamilyControl->friendFamilyFlag = pdata[0]; + break; + case 5: + friendFamilyControl->friendFamilyChangeChargeFlag = pdata[0]; + break; + case 6: + friendFamilyControl->friendFamilyFreeChangeTimes = pdata[0]; + break; + case 7: + friendFamilyControl->friendFamilyNumberTypeLocal= pdata[0]; + break; + case 8: + friendFamilyControl->friendFamilyNumberTypeNDD= pdata[0]; + break; + case 9: + friendFamilyControl->friendFamilyNumberTypeIDD= pdata[0]; + break; + case 10: + friendFamilyControl->balanceThresholdForFriendFamilyCall = PPS_SET_INTEGER(pdata,datalen); + break; + case 11: + friendFamilyControl->keepOrRemoveFriendFamilyNumber = pdata[0]; + break; + case 12: + friendFamilyControl->balanceThresholdToKeepFriendFamilyNumber = PPS_SET_INTEGER(pdata,datalen); + break; + case 13: + friendFamilyControl->friendFamilyPlan[0].rentCharge = PPS_SET_INTEGER(pdata,datalen); + break; + case 14: + friendFamilyControl->friendFamilyPlan[0].maxNumbers = pdata[0]; + break; + case 15: + friendFamilyControl->friendFamilyPlan[0].freeCallDuration= PPS_SET_INTEGER(pdata,datalen); + break; + case 16: + friendFamilyControl->friendFamilyPlan[0].freeSMS= PPS_SET_INTEGER(pdata,datalen); + break; + case 17: + friendFamilyControl->friendFamilyPlan[0].rentID = pdata[0]; + break; + case 18: + friendFamilyControl->friendFamilyPlan[1].rentCharge = PPS_SET_INTEGER(pdata,datalen); + break; + case 19: + friendFamilyControl->friendFamilyPlan[1].maxNumbers = pdata[0]; + break; + case 20: + friendFamilyControl->friendFamilyPlan[1].freeCallDuration = PPS_SET_INTEGER(pdata,datalen); + break; + case 21: + friendFamilyControl->friendFamilyPlan[1].freeSMS= PPS_SET_INTEGER(pdata,datalen); + break; + case 22: + friendFamilyControl->friendFamilyPlan[1].rentID = pdata[0]; + break; + case 23: + friendFamilyControl->friendFamilyPlan[2].rentCharge = PPS_SET_INTEGER(pdata,datalen); + break; + case 24: + friendFamilyControl->friendFamilyPlan[2].maxNumbers = pdata[0]; + break; + case 25: + friendFamilyControl->friendFamilyPlan[2].freeCallDuration = PPS_SET_INTEGER(pdata,datalen); + break; + case 26: + friendFamilyControl->friendFamilyPlan[2].freeSMS= PPS_SET_INTEGER(pdata,datalen); + break; + case 27: + friendFamilyControl->friendFamilyPlan[2].rentID = pdata[0]; + break; + case 28: + friendFamilyControl->friendFamilyPlan[3].rentCharge = PPS_SET_INTEGER(pdata,datalen); + break; + case 29: + friendFamilyControl->friendFamilyPlan[3].maxNumbers = pdata[0]; + break; + case 30: + friendFamilyControl->friendFamilyPlan[3].freeCallDuration = PPS_SET_INTEGER(pdata,datalen); + break; + case 31: + friendFamilyControl->friendFamilyPlan[3].freeSMS= PPS_SET_INTEGER(pdata,datalen); + break; + case 32: + friendFamilyControl->friendFamilyPlan[3].rentID = pdata[0]; + break; + case 33: + friendFamilyControl->friendFamilyPlan[4].rentCharge = PPS_SET_INTEGER(pdata,datalen); + break; + case 34: + friendFamilyControl->friendFamilyPlan[4].maxNumbers = pdata[0]; + break; + case 35: + friendFamilyControl->friendFamilyPlan[4].freeCallDuration = PPS_SET_INTEGER(pdata,datalen); + break; + case 36: + friendFamilyControl->friendFamilyPlan[4].freeSMS= PPS_SET_INTEGER(pdata,datalen); + break; + case 37: + friendFamilyControl->friendFamilyPlan[4].rentID = pdata[0]; + break; + case 38: + friendFamilyControl->friendFamilyPlan[5].rentCharge = PPS_SET_INTEGER(pdata,datalen); + break; + case 39: + friendFamilyControl->friendFamilyPlan[5].maxNumbers = pdata[0]; + break; + case 40: + friendFamilyControl->friendFamilyPlan[5].freeCallDuration = PPS_SET_INTEGER(pdata,datalen); + break; + case 41: + friendFamilyControl->friendFamilyPlan[5].freeSMS= PPS_SET_INTEGER(pdata,datalen); + break; + case 42: + friendFamilyControl->friendFamilyPlan[5].rentID = pdata[0]; + break; + + case 43:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(friendFamilyControl,0,sizeof(CosFriendFamilyControl)); + friendFamilyControl->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/****************** FriendFamilyControlTable ******************/ + +/***************************************************************/ +/****************** smsNotification Table ******************/ +int pps_getnext_cosSmsNotification(index_t *id) +{ + return pps_getnext_Index(SmsNotificationInquiryTable,id); +} + +int pps_getIdle_cosSmsNotification(index_t *id) +{ + return pps_getIdle_Index(SmsNotificationInquiryTable,id); +} + +int isCosSmsNotificationIndexBusy(index_t *id) +{ + return isIndexBusy(SmsNotificationInquiryTable,id); +} + +int pps_get_cosSmsNotification(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosSmsNotificationInquiry *smsNotificationItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(SmsNotificationInquiryTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(SmsNotificationInquiryTable,(index_t *)instance) == FALSE) + return -1; + + smsNotificationItem = &ppsParam.ppsTables.cosTable[cosIndex].smsNotificationInquiry[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + smsNotificationItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)smsNotificationItem->title); + memcpy(pdata,smsNotificationItem->title,datalen); + break; + case 4: + pdata[0] = smsNotificationItem->smsNotificationWhenRecharge; + break; + case 5: + pdata[0] = smsNotificationItem->smsNotificationWhenInquiry; + break; + case 6: + pdata[0] = smsNotificationItem->smsNotificationWhenExpired; + break; + case 7: + pdata[0] = smsNotificationItem->theDaysSendingSMSBeforeExpiredDay; + break; + case 8: + pdata[0] = smsNotificationItem->smsNotificationWhenBalanceInsufficient; + break; + case 9: + datalen = PPS_GET_INTEGER(smsNotificationItem->insufficientBalanceThreshold,pdata,vartype); + break; + case 10: + pdata[0] = smsNotificationItem->chargeWhenInquiryBySMS; + break; + case 11: + pdata[0] = smsNotificationItem->freeInquiryPerDay; + break; + case 12: + pdata[0] = smsNotificationItem->smsNotificationWhenCleanBalance; //2010-03-08 + break; + case 13: + pdata[0] = smsNotificationItem->smsNotificationWhenCapPlanChanged; //2010-03-08 + break; + case 14: + pdata[0] = smsNotificationItem->smsNotificationWhenApplyOverdraft; //2010-03-08 + break; + case 15: + pdata[0] = smsNotificationItem->smsNotificationWhenRentCharge; + break; + case 16: + pdata[0] = smsNotificationItem->smsNotificationWhenFriendFamilyServiceReg; + break; + case 17: + pdata[0] = smsNotificationItem->smsNotificationWhenFriendFamilyServiceSuspend; + break; + case 18: + pdata[0] = smsNotificationItem->smsNotificationWhenFriendFamilyPlanExhaust; + break; + case 19: + pdata[0] = smsNotificationItem->smsNotificationWhenFriendFamilyServiceRemoved; + break; + case 20:/* rowStatus */ //2010-03-08 + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosSmsNotification(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + CosSmsNotificationInquiry *smsNotificationItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(SmsNotificationInquiryTable,subIndex) == FALSE) + return -1; + + smsNotificationItem = &ppsParam.ppsTables.cosTable[cosIndex].smsNotificationInquiry[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(smsNotificationItem->title,pdata,datalen); + smsNotificationItem->title[datalen] = 0; + break; + case 4: + smsNotificationItem->smsNotificationWhenRecharge = pdata[0]; + break; + case 5: + smsNotificationItem->smsNotificationWhenInquiry = pdata[0]; + break; + case 6: + smsNotificationItem->smsNotificationWhenExpired = pdata[0]; + break; + case 7: + smsNotificationItem->theDaysSendingSMSBeforeExpiredDay = pdata[0]; + break; + case 8: + smsNotificationItem->smsNotificationWhenBalanceInsufficient = pdata[0]; + break; + case 9: + smsNotificationItem->insufficientBalanceThreshold = PPS_SET_INTEGER(pdata,datalen); + break; + case 10: + smsNotificationItem->chargeWhenInquiryBySMS = pdata[0]; + break; + case 11: + smsNotificationItem->freeInquiryPerDay = pdata[0]; + break; + case 12: + smsNotificationItem->smsNotificationWhenCleanBalance = pdata[0]; + break; + case 13: + smsNotificationItem->smsNotificationWhenCapPlanChanged = pdata[0]; + break; + case 14: + smsNotificationItem->smsNotificationWhenApplyOverdraft = pdata[0]; + break; + case 15: + smsNotificationItem->smsNotificationWhenRentCharge = pdata[0]; + break; + case 16: + smsNotificationItem->smsNotificationWhenFriendFamilyServiceReg = pdata[0]; + break; + case 17: + smsNotificationItem->smsNotificationWhenFriendFamilyServiceSuspend = pdata[0]; + break; + case 18: + smsNotificationItem->smsNotificationWhenFriendFamilyPlanExhaust = pdata[0]; + break; + case 19: + smsNotificationItem->smsNotificationWhenFriendFamilyServiceRemoved = pdata[0]; + break; + case 20:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(smsNotificationItem,0,sizeof(CosSmsNotificationInquiry)); + smsNotificationItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/*********************** smsNotification Table **********************/ +/************************************************************************/ + + + +/***************************************************************/ +/****************** rechargeCardValidity Table ******************/ +int pps_getnext_cosRechargeCardValidity(index_t *id) +{ + return pps_getnext_Index(RechargeCardValidityTable,id); +} + +int pps_getIdle_cosRechargeCardValidity(index_t *id) +{ + return pps_getIdle_Index(RechargeCardValidityTable,id); +} + +int isCosRechargeCardValidityIndexBusy(index_t *id) +{ + return isIndexBusy(RechargeCardValidityTable,id); +} + +int pps_get_cosRechargeCardValidity(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosRechargeCardValidity *rechargeCardValidityItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(RechargeCardValidityTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(RechargeCardValidityTable,(index_t *)instance) == FALSE) + return -1; + + rechargeCardValidityItem = &ppsParam.ppsTables.cosTable[cosIndex].rechargeCardValidity[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + rechargeCardValidityItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)rechargeCardValidityItem->title); + memcpy(pdata,rechargeCardValidityItem->title,datalen); + break; + case 4: + datalen = PPS_GET_INTEGER(rechargeCardValidityItem->cardCredit,pdata,vartype); + break; + case 5: + datalen = PPS_GET_INTEGER(rechargeCardValidityItem->moValidity,pdata,vartype); + break; + case 6: + datalen = PPS_GET_INTEGER(rechargeCardValidityItem->mtValidity,pdata,vartype); + break; + case 7:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosRechargeCardValidity(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + CosRechargeCardValidity *rechargeCardValidityItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(RechargeCardValidityTable,subIndex) == FALSE) + return -1; + + rechargeCardValidityItem = &ppsParam.ppsTables.cosTable[cosIndex].rechargeCardValidity[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(rechargeCardValidityItem->title,pdata,datalen); + rechargeCardValidityItem->title[datalen] = 0; + break; + case 4: + rechargeCardValidityItem->cardCredit = PPS_SET_INTEGER(pdata,datalen); + break; + case 5: + rechargeCardValidityItem->moValidity = PPS_SET_INTEGER(pdata,datalen); + break; + case 6: + rechargeCardValidityItem->mtValidity = PPS_SET_INTEGER(pdata,datalen); + break; + case 7:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(rechargeCardValidityItem,0,sizeof(CosRechargeCardValidity)); + rechargeCardValidityItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/********************* rechargeCardValidity Table *********************/ +/************************************************************************/ + + +/****************************************************************/ +/****************** rechargePromotion Table ******************/ +int pps_getnext_cosRechargePromotion(index_t *id) +{ + return pps_getnext_Index(RechargePromotionTable,id); +} + +int pps_getIdle_cosRechargePromotion(index_t *id) +{ + return pps_getIdle_Index(RechargePromotionTable,id); +} + +int isCosRechargePromotionIndexBusy(index_t *id) +{ + return isIndexBusy(RechargePromotionTable,id); +} + +int pps_get_cosRechargePromotion(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosRechargePromotion *rechargePromotionItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(RechargePromotionTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(RechargePromotionTable,(index_t *)instance) == FALSE) + return -1; + + rechargePromotionItem = &ppsParam.ppsTables.cosTable[cosIndex].rechargePromotion[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + rechargePromotionItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)rechargePromotionItem->title); + memcpy(pdata,rechargePromotionItem->title,datalen); + break; + case 4: + datalen = PPS_GET_INTEGER(rechargePromotionItem->rechargeCardCredit,pdata,vartype); + break; + case 5: + datalen = PPS_GET_INTEGER(rechargePromotionItem->promotionBonus,pdata,vartype); + break; + case 6: + datalen = PPS_GET_INTEGER(rechargePromotionItem->promotionValidity,pdata,vartype); + break; + case 7:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosRechargePromotion(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + CosRechargePromotion *rechargePromotionItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(RechargePromotionTable,subIndex) == FALSE) + return -1; + + rechargePromotionItem = &ppsParam.ppsTables.cosTable[cosIndex].rechargePromotion[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(rechargePromotionItem->title,pdata,datalen); + rechargePromotionItem->title[datalen] = 0; + break; + case 4: + rechargePromotionItem->rechargeCardCredit = PPS_SET_INTEGER(pdata,datalen); + break; + case 5: + rechargePromotionItem->promotionBonus = PPS_SET_INTEGER(pdata,datalen); + break; + case 6: + rechargePromotionItem->promotionValidity = PPS_SET_INTEGER(pdata,datalen); + break; + case 7:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(rechargePromotionItem,0,sizeof(CosRechargePromotion)); + rechargePromotionItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/********************* rechargePromotion Table *********************/ +/************************************************************************/ + + + +/****************************************************************/ +/****************** capPlan Table ******************/ +int pps_getnext_cosCapPlan(index_t *id) +{ + return pps_getnext_Index(CapPlanTable,id); +} + +int pps_getIdle_cosCapPlan(index_t *id) +{ + return pps_getIdle_Index(CapPlanTable,id); +} + +int isCosCapPlanIndexBusy(index_t *id) +{ + return isIndexBusy(CapPlanTable,id); +} + +int pps_get_cosCapPlan(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + CosCapPlan *capPlanItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(CapPlanTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(CapPlanTable,(index_t *)instance) == FALSE) + return -1; + + capPlanItem = &ppsParam.ppsTables.cosTable[cosIndex].capPlan[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + capPlanItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)capPlanItem->title); + memcpy(pdata,capPlanItem->title,datalen); + break; + case 4: + pdata[0] = capPlanItem->flag; + break; + case 5: + pdata[0] = capPlanItem->type; + break; + case 6: + datalen = PPS_GET_INTEGER(capPlanItem->threshold0,pdata,vartype); + break; + case 7: + datalen = PPS_GET_INTEGER(capPlanItem->threshold1,pdata,vartype); + break; + case 8: + datalen = PPS_GET_INTEGER(capPlanItem->threshold2,pdata,vartype); + break; + case 9: + pdata[0] = capPlanItem->tariffID0; + break; + case 10: + pdata[0] = capPlanItem->tariffID1; + break; + case 11: + pdata[0] = capPlanItem->tariffID2; + break; + case 12: + pdata[0] = capPlanItem->tariffID3; + break; + case 13:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosCapPlan(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + CosCapPlan *capPlanItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(CapPlanTable,subIndex) == FALSE) + return -1; + + capPlanItem = &ppsParam.ppsTables.cosTable[cosIndex].capPlan[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(capPlanItem->title,pdata,datalen); + capPlanItem->title[datalen] = 0; + break; + case 4: + capPlanItem->flag = pdata[0]; + break; + case 5: + capPlanItem->type = pdata[0]; + break; + case 6: + capPlanItem->threshold0 = PPS_SET_INTEGER(pdata,datalen); + break; + case 7: + capPlanItem->threshold1 = PPS_SET_INTEGER(pdata,datalen); + break; + case 8: + capPlanItem->threshold2 = PPS_SET_INTEGER(pdata,datalen); + break; + case 9: + capPlanItem->tariffID0 = pdata[0]; + break; + case 10: + capPlanItem->tariffID1 = pdata[0]; + break; + case 11: + capPlanItem->tariffID2 = pdata[0]; + break; + case 12: + capPlanItem->tariffID3 = pdata[0]; + break; + case 13:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(capPlanItem,0,sizeof(CosCapPlan)); + capPlanItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/********************* capPlan Table *********************/ + + +/****************** poolAccount Table ******************/ +int pps_getnext_cosPoolAccount(index_t *id) +{ + return pps_getnext_Index(PoolAccountTable,id); +} + +int pps_getIdle_cosPoolAccount(index_t *id) +{ + return pps_getIdle_Index(PoolAccountTable,id); +} + +int isCosPoolAccountIndexBusy(index_t *id) +{ + return isIndexBusy(PoolAccountTable,id); +} + +int pps_get_cosPoolAccount(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + COS_Pool_Account *poolAccountItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(PoolAccountTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(PoolAccountTable,(index_t *)instance) == FALSE) + return -1; + + poolAccountItem = &ppsParam.ppsTables.cosTable[cosIndex].poolAccount[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + poolAccountItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)poolAccountItem->title); + memcpy(pdata,poolAccountItem->title,datalen); + break; + case 4: + pdata[0] = poolAccountItem->role; + break; + case 5: + pdata[0] = poolAccountItem->roleParty.parent.cosIDForChild[0]; + break; + case 6: + pdata[0] = poolAccountItem->roleParty.parent.cosIDForChild[1]; + break; + case 7: + pdata[0] = poolAccountItem->roleParty.child.isRechargeAllowed; + break; + case 8: + pdata[0] = poolAccountItem->roleParty.child.isTransferAllowed; + break; + case 9: + pdata[0] = poolAccountItem->roleParty.child.periodicTransferOrAutoByParent; + break; + case 10: + datalen = PPS_GET_INTEGER(poolAccountItem->roleParty.child.maxCallsPerDay,pdata,vartype); + break; + case 11: + datalen = PPS_GET_INTEGER(poolAccountItem->roleParty.child.maxSMSPerDay,pdata,vartype); + break; + case 12: + datalen = PPS_GET_INTEGER(poolAccountItem->roleParty.child.maxFeePerDay,pdata,vartype); + break; + case 13:/* rowStatus */ + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + +int pps_set_cosPoolAccount(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + COS_Pool_Account *poolAccountItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(PoolAccountTable,subIndex) == FALSE) + return -1; + + poolAccountItem = &ppsParam.ppsTables.cosTable[cosIndex].poolAccount[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(poolAccountItem->title,pdata,datalen); + poolAccountItem->title[datalen] = 0; + break; + case 4: + poolAccountItem->role = pdata[0]; + break; + case 5: + poolAccountItem->roleParty.parent.cosIDForChild[0] = pdata[0]; + break; + case 6: + poolAccountItem->roleParty.parent.cosIDForChild[1] = pdata[0]; + break; + case 7: + poolAccountItem->roleParty.child.isRechargeAllowed = pdata[0]; + break; + case 8: + poolAccountItem->roleParty.child.isTransferAllowed = pdata[0]; + break; + case 9: + poolAccountItem->roleParty.child.periodicTransferOrAutoByParent = pdata[0]; + break; + case 10: + poolAccountItem->roleParty.child.maxCallsPerDay = PPS_SET_INTEGER(pdata,datalen); + break; + case 11: + poolAccountItem->roleParty.child.maxSMSPerDay = PPS_SET_INTEGER(pdata,datalen);; + break; + case 12: + poolAccountItem->roleParty.child.maxFeePerDay = PPS_SET_INTEGER(pdata,datalen); + break; + case 13:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(poolAccountItem,0,sizeof(COS_Pool_Account)); + poolAccountItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/********************* poolAccount Table *********************/ + + +/****************** cos gprs Table ******************/ +int pps_getnext_cosGprs(index_t *id) +{ + return pps_getnext_Index(CosGprsTable,id); +} + +int pps_getIdle_cosGprs(index_t *id) +{ + return pps_getIdle_Index(CosGprsTable,id); +} + +int isCosGprsBusy(index_t *id) +{ + return isIndexBusy(CosGprsTable,id); +} + +int pps_get_cosGprs(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = 1,cosIndex,subIndex; + PPS_COS_RADIUS_ITEM *gprsItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(CosGprsTable,subIndex) == FALSE) + return -1; + if(isIndexBusy(CosGprsTable,(index_t *)instance) == FALSE) + return -1; + + gprsItem = &ppsParam.ppsTables.cosTable[cosIndex].gprs[subIndex]; + *vartype = INTEGER; + + switch(column) + { + case 1: + pdata[0] = cosIndex; + break; + case 2: + pdata[0] = subIndex; + break; + case 3: + *vartype = OctetString; + gprsItem->title[PpsMaxTitleLen-1] = 0; + datalen = strlen((char *)gprsItem->title); + memcpy(pdata,gprsItem->title,datalen); + break; + case 4: + pdata[0] = gprsItem->gprsChargeFlag; + break; + case 5: + datalen = PPS_GET_INTEGER(gprsItem->miniBalanceForGprs,pdata,vartype); + break; + case 6: + datalen = PPS_GET_INTEGER(gprsItem->inactiveSessionLimit,pdata,vartype); + break; + case 7: + pdata[0] = gprsItem->notificationWhenSessionTerminate; + break; + case 8: + datalen = PPS_GET_INTEGER(gprsItem->maxSmsForGprsNotificationPerDay,pdata,vartype); + break; + case 9: + datalen = PPS_GET_INTEGER(gprsItem->maxVolumeQuotaEachTime>>10,pdata,vartype); + break; + case 10: + datalen = PPS_GET_INTEGER(gprsItem->volumeThresholdDiff>>10,pdata,vartype); + break; + case 11: + datalen = PPS_GET_INTEGER(gprsItem->maxDurationQuotaEachTime,pdata,vartype); + break; + case 12: + datalen = PPS_GET_INTEGER(gprsItem->durationThresholdDiff,pdata,vartype); + break; + case 13: + pdata[0] = gprsItem->gprsChargedBy; + break; + case 14: + pdata[0] = gprsItem->capPlan[0].type; + break; + case 15: + datalen = PPS_GET_INTEGER(gprsItem->capPlan[0].threshold0,pdata,vartype); + break; + case 16: + datalen = PPS_GET_INTEGER(gprsItem->capPlan[0].threshold1,pdata,vartype); + break; + case 17: + datalen = PPS_GET_INTEGER(gprsItem->capPlan[0].threshold2,pdata,vartype); + break; + case 18: + + pdata[0] = gprsItem->capPlan[0].tariffID0; + break; + case 19: + pdata[0] = gprsItem->capPlan[0].tariffID1; + break; + case 20: + pdata[0] = gprsItem->capPlan[0].tariffID2; + break; + case 21: + pdata[0] = gprsItem->capPlan[0].tariffID3; + break; + case 22:/* rowStatus */ //2010-03-08 + *vartype = INTEGER; + pdata[0] = TABLE_ACTIVE_COMMAND; + break; + default: + return -1; + break; + } + return datalen; +} + + +int pps_set_cosGprs(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + int cosIndex,subIndex; + PPS_COS_RADIUS_ITEM *gprsItem; + + cosIndex = instance[0]; + if(isIndexValid(CosTable,cosIndex) == FALSE) + return -1; + if(isIndexBusy(CosTable,(index_t *)&cosIndex) == FALSE) + return -1; + + subIndex = instance[1]; + if(isIndexValid(CosGprsTable,subIndex) == FALSE) + return -1; + + gprsItem = &ppsParam.ppsTables.cosTable[cosIndex].gprs[subIndex]; + switch(column) + { + case 3: + if(datalen > PpsMaxTitleLen) + return -1; + memcpy(gprsItem->title,pdata,datalen); + gprsItem->title[datalen] = 0; + break; + case 4: + gprsItem->gprsChargeFlag = pdata[0]; + break; + case 5: + gprsItem->miniBalanceForGprs = PPS_SET_INTEGER(pdata,datalen); + break; + case 6: + gprsItem->inactiveSessionLimit = PPS_SET_INTEGER(pdata,datalen); + break; + case 7: + gprsItem->notificationWhenSessionTerminate = pdata[0]; + break; + case 8: + gprsItem->maxSmsForGprsNotificationPerDay = PPS_SET_INTEGER(pdata,datalen); + break; + case 9: + gprsItem->maxVolumeQuotaEachTime = PPS_SET_INTEGER(pdata,datalen) << 10; + break; + case 10: + gprsItem->volumeThresholdDiff = PPS_SET_INTEGER(pdata,datalen) << 10; + break; + case 11: + gprsItem->maxDurationQuotaEachTime = PPS_SET_INTEGER(pdata,datalen); + break; + case 12: + gprsItem->durationThresholdDiff = PPS_SET_INTEGER(pdata,datalen); + break; + case 13: + gprsItem->gprsChargedBy = pdata[0]; + break; + case 14: + gprsItem->capPlan[0].type = pdata[0]; + break; + case 15: + gprsItem->capPlan[0].threshold0 = PPS_SET_INTEGER(pdata,datalen); + break; + case 16: + gprsItem->capPlan[0].threshold1 = PPS_SET_INTEGER(pdata,datalen); + break; + case 17: + gprsItem->capPlan[0].threshold2 = PPS_SET_INTEGER(pdata,datalen); + break; + case 18: + gprsItem->capPlan[0].tariffID0 = pdata[0]; + break; + case 19: + gprsItem->capPlan[0].tariffID1 = pdata[0]; + break; + case 20: + gprsItem->capPlan[0].tariffID2 = pdata[0]; + break; + case 21: + gprsItem->capPlan[0].tariffID3 = pdata[0]; + break; + case 22:/* command */ + if(pdata[0] == TABLE_DESTROY_COMMAND) + { + memset(gprsItem,0,sizeof(PPS_COS_RADIUS_ITEM)); + gprsItem->existFlag = FALSE; + } + else + return -1; + break; + default: + return -1; + break; + } + ppsSetParameterAutoSaveFlag(); + return datalen; +} +/*********************** cos gprs Table **********************/ +/************************************************************************/ + +/************************************************************************/ + + +static struct snmp_table_profile pps_tables[] = { + { + .name = "PromptResolutionTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl ,PromptResolutionTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 0}, + .level = 1, + .get_instance = pps_getnext_promptResolution, + .get_resp = pps_get_promptResolution, + .set_resp = pps_set_promptResolution + }, + { + .name = "MnpPrefixTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl, MnpPrefixTable}, + .column = {1, 2, 3, 4, 0}, + .level = 1, + .get_instance = pps_getnext_mnpPrefix, + .get_resp = pps_get_mnpPrefix, + .set_resp = pps_set_mnpPrefix + }, + { + .name = "SmsSentenceTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl, SmsSentenceTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}, + .level = 1, + .get_instance = pps_getnext_smsSentence, + .get_resp = pps_get_smsSentence, + .set_resp = pps_set_smsSentence + }, + { + .name = "ThirdPartyInfoTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl, ThirdPartyInfoTable}, + .column = {1, 2, 3, 4, 5, 0}, + .level = 1, + .get_instance = pps_getnext_thirdPartyInfo, + .get_resp = pps_get_thirdPartyInfo, + .set_resp = pps_set_thirdPartyInfo + }, + { + .name = "BasicTariffZoneTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl, BasicTariffZoneTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, + .level = 1, + .get_instance = pps_getnext_basicTariffZone, + .get_resp = pps_get_basicTariffZone, + .set_resp = pps_set_basicTariffZone + }, + { + .name = "GsnTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl, RadiusGsnTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, + .level = 1, + .get_instance = pps_getnext_gsn, + .get_resp = pps_get_gsn, + .set_resp = pps_set_gsn + }, + { + .name = "SgsnTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl, RadiusSgsnTable}, + .column = {1, 2, 3, 4, 5,6,7,0}, + .level = 1, + .get_instance = pps_getnext_sgsn, + .get_resp = pps_get_sgsn, + .set_resp = pps_set_sgsn + }, + { + .name = "BundlePlanTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, ServiceControl, BundlePlanTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9,10,0}, + .level = 1, + .get_instance = pps_getnext_bundlePlan, + .get_resp = pps_get_bundle_plan, + .set_resp = pps_set_bundle_plan + }, + { + .name = "IvrSourceTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, SrfParameter, IvrSourceTable}, + .column = {1, 2, 3, 4, 5, 0}, + .level = 1, + .get_instance = pps_getnext_ivrSource, + .get_resp = pps_get_ivrSource, + .set_resp = pps_set_ivrSource + }, + { + .name = "SrfNumberTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, SrfParameter, SrfNumberTable}, + .column = {1, 2, 3, 4, 0}, + .level = 1, + .get_instance = pps_getnext_srfNumber, + .get_resp = pps_get_srfNumber, + .set_resp = pps_set_srfNumber + }, + { + .name = "ServiceNumberTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, SrfParameter, ServiceNumberTable}, + .column = {1, 2, 3, 4, 0}, + .level = 1, + .get_instance = pps_getnext_serviceNumber, + .get_resp = pps_get_serviceNumber, + .set_resp = pps_set_serviceNumber + }, + { + .name = "ServiceKeyTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, SrfParameter, ServiceKeyTable}, + .column = {1, 2, 3, 4, 0}, + .level = 1, + .get_instance = pps_getnext_serviceKey, + .get_resp = pps_get_serviceKey, + .set_resp = pps_set_serviceKey + }, + { + .name = "VmsUserSegmentTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, RouteVMS, VmsUserSegmentTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8,0}, + .level = 1, + .get_instance = pps_getnext_vmsUserSegment, + .get_resp = pps_get_vmsUserSegment, + .set_resp = pps_set_vmsUserSegment + }, + { + .name = "CosTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, CosTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0}, + .level = 1, + .get_instance = pps_getnext_cos, + .get_resp = pps_get_cos, + .set_resp = pps_set_cos + }, + { + .name = "TariffTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, TariffTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19, 0}, + .level = 2, + .get_instance = pps_getnext_cosTariff, + .get_resp = pps_get_cosTariff, + .set_resp = pps_set_cosTariff + }, + { + .name = "ServiceControlTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, ServiceControlTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,17,18,19,20,21,22, 23,24,25,26,30,0}, + .level = 2, + .get_instance = pps_getnext_cosServiceControl, + .get_resp = pps_get_cosServiceControl, + .set_resp = pps_set_cosServiceControl + }, + { + .name = "AccountValidityTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, AccountValidityTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20,0}, + .level = 2, + .get_instance = pps_getnext_cosAccountValidity, + .get_resp = pps_get_cosAccountValidity, + .set_resp = pps_set_cosAccountValidity + }, + { + .name = "SmsNotificationInquiryTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, SmsNotificationInquiryTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,15,16,17,18, 0}, + .level = 2, + .get_instance = pps_getnext_cosSmsNotification, + .get_resp = pps_get_cosSmsNotification, + .set_resp = pps_set_cosSmsNotification + }, + { + .name = "RechargeCardValidityTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, RechargeCardValidityTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 0}, + .level = 2, + .get_instance = pps_getnext_cosRechargeCardValidity, + .get_resp = pps_get_cosRechargeCardValidity, + .set_resp = pps_set_cosRechargeCardValidity + }, + { + .name = "RechargePromotionTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, RechargePromotionTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 0}, + .level = 2, + .get_instance = pps_getnext_cosRechargePromotion, + .get_resp = pps_get_cosRechargePromotion, + .set_resp = pps_set_cosRechargePromotion + }, + { + .name = "CapPlanTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, CapPlanTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 2, + .get_instance = pps_getnext_cosCapPlan, + .get_resp = pps_get_cosCapPlan, + .set_resp = pps_set_cosCapPlan + }, + { + .name = "PoolAccountTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, PoolAccountTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 2, + .get_instance = pps_getnext_cosPoolAccount, + .get_resp = pps_get_cosPoolAccount, + .set_resp = pps_set_cosPoolAccount + }, + { + .name = "GprsTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, CosGprsTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,21,22, 0}, + .level = 2, + .get_instance = pps_getnext_cosGprs, + .get_resp = pps_get_cosGprs, + .set_resp = pps_set_cosGprs + }, + { + .name = "FriendFamilyTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, COSID, FriendFamilyTable}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,21,22, 23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,0}, + .level = 2, + .get_instance = pps_getnext_cos_friend_family, + .get_resp = pps_get_cos_friend_family, + .set_resp = pps_set_cos_friend_family + }, + { + .name = "USSDServiceTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, SrfParameter, UssdServiceNumberTable}, + .column = {1, 2, 3, 4, 0}, + .level = 1, + .get_instance = pps_getnext_ussd_serviceNumber, + .get_resp = pps_get_ussd_serviceNumber, + .set_resp = pps_set_ussd_serviceNumber + }, + { + .name = "USSDKeyTable", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID, PPS_PARAMETER, SrfParameter, UssdServiceKeyTable}, + .column = {1, 2, 3, 4, 0}, + .level = 1, + .get_instance = pps_getnext_ussd_serviceKey, + .get_resp = pps_get_ussd_serviceKey, + .set_resp = pps_set_ussd_serviceKey + } + +}; + +extern int snmpGetPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, BYTE *vartype); +extern int snmpSetPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, u_short dataLen); +extern void snmpTrapPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, u_short dataLen,snmp_addr *addr); +extern int snmpResponse(snmp_pdu *pdu, snmp_addr *addr); +extern int thirdPartyChargeProc(snmp_pdu *pdu, snmp_addr *addr); + +extern DWORD PPS_OID_PREFIX[]; +extern DWORD PPS_OID_THIRDPARTY[]; + +static struct snmp_register pps_register = { + .name = "PPS", + .prefix_len = 11, + .prefix_oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 3, PPSOID}, + .num_of_table = sizeof(pps_tables)/sizeof(struct snmp_table_profile), + .table = pps_tables, + .default_get_resp = (getcall)snmpGetPPS, + .default_set_resp = (setcall)snmpSetPPS +}; + + +static void initTables() +{ + int i; + PpsTable *tablePoint; + + tablePoint = &ppsParam.ppsTables; + + /******************* Prompt Resolution **********************/ + memset(tablePoint->promptResolution[0].title,0,PpsMaxTitleLen); + memcpy(tablePoint->promptResolution[0].title,"Prompt Resolution",PpsMaxTitleLen); + tablePoint->promptResolution[0].existFlag = TRUE; + + /******************* IVR source **********************/ + memset(tablePoint->ivrSource[0].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ivrSource[0].title,"IVR Source",PpsMaxTitleLen); + tablePoint->ivrSource[0].existFlag = TRUE; + + /******************* SRF Number **********************/ + memset(tablePoint->srfNumber[0].title,0,PpsMaxTitleLen); + memcpy(tablePoint->srfNumber[0].title,"SRF0 Number",PpsMaxTitleLen); + tablePoint->srfNumber[0].existFlag = TRUE; + + memset(tablePoint->srfNumber[1].title,0,PpsMaxTitleLen); + memcpy(tablePoint->srfNumber[1].title,"SRF1 Number",PpsMaxTitleLen); + tablePoint->srfNumber[1].existFlag = TRUE; + + + /******************* Service Number **********************/ + memset(tablePoint->serviceNumber[HotLineNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[HotLineNumberPosition].title,"HotLine Number",PpsMaxTitleLen); + tablePoint->serviceNumber[HotLineNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[InquiryNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[InquiryNumberPosition].title,"Inquiry Number",PpsMaxTitleLen); + tablePoint->serviceNumber[InquiryNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[ScratchCardRechargeNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[ScratchCardRechargeNumberPosition].title,"Scratch Card Recharge Number",PpsMaxTitleLen); + tablePoint->serviceNumber[ScratchCardRechargeNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[CreditCardRechargeNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[CreditCardRechargeNumberPosition].title,"Bundle Plan Subscribe Number",PpsMaxTitleLen); + tablePoint->serviceNumber[CreditCardRechargeNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[ThirdPartyRechargeNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[ThirdPartyRechargeNumberPosition].title,"ThirdParty Recharge Number",PpsMaxTitleLen); + tablePoint->serviceNumber[ThirdPartyRechargeNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[CustomerCareCenterNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[CustomerCareCenterNumberPosition].title,"Customer Care Center Number",PpsMaxTitleLen); + tablePoint->serviceNumber[CustomerCareCenterNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[RechargeNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[RechargeNumberPosition].title,"Recharge Number",PpsMaxTitleLen); + tablePoint->serviceNumber[RechargeNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[OPRNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[OPRNumberPosition].title,"OPR Number",PpsMaxTitleLen); + tablePoint->serviceNumber[OPRNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[VirtualCallingCardNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[VirtualCallingCardNumberPosition].title,"Virtual Calling Card Number",PpsMaxTitleLen); + tablePoint->serviceNumber[VirtualCallingCardNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[PalimRegisterNumberPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[PalimRegisterNumberPosition].title,"Palim Register Number",PpsMaxTitleLen); + tablePoint->serviceNumber[PalimRegisterNumberPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[PoolAccountPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[PoolAccountPosition].title,"Pool Account Service Number",PpsMaxTitleLen); + tablePoint->serviceNumber[PoolAccountPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[FeeTransferPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[FeeTransferPosition].title,"Credit Transfer Service Number",PpsMaxTitleLen); + tablePoint->serviceNumber[FeeTransferPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[FreeServicePosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[FreeServicePosition].title,"Free SMS Service Number",PpsMaxTitleLen); + tablePoint->serviceNumber[FreeServicePosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[CallMeBackPosition].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[CallMeBackPosition].title,"Call Me Back Service Number",PpsMaxTitleLen); + tablePoint->serviceNumber[CallMeBackPosition].existFlag = TRUE; + + memset(tablePoint->serviceNumber[GPRSPrepaidPostion].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[GPRSPrepaidPostion].title,"Gprs Service Number",PpsMaxTitleLen); + tablePoint->serviceNumber[GPRSPrepaidPostion].existFlag = TRUE; + + memset(tablePoint->serviceNumber[TellMeNumber].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceNumber[TellMeNumber].title,"Tell Me My Number",PpsMaxTitleLen); + tablePoint->serviceNumber[TellMeNumber].existFlag = TRUE; + + + /******************* Service Key **********************/ + memset(tablePoint->serviceKey[HELP].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceKey[HELP].title,"Help",PpsMaxTitleLen); + tablePoint->serviceKey[HELP].existFlag = TRUE; + + memset(tablePoint->serviceKey[INQUIRY_SERVICE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceKey[INQUIRY_SERVICE].title,"Inquiry Service",PpsMaxTitleLen); + tablePoint->serviceKey[INQUIRY_SERVICE].existFlag = TRUE; + + memset(tablePoint->serviceKey[SCRATCH_CARD_RECHARGE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceKey[SCRATCH_CARD_RECHARGE].title,"Scratch Card Recharge",PpsMaxTitleLen); + tablePoint->serviceKey[SCRATCH_CARD_RECHARGE].existFlag = TRUE; + + memset(tablePoint->serviceKey[CREDIT_CARD_RECHARGE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceKey[CREDIT_CARD_RECHARGE].title,"Credit Card Recharge",PpsMaxTitleLen); + tablePoint->serviceKey[CREDIT_CARD_RECHARGE].existFlag = TRUE; + + memset(tablePoint->serviceKey[FAVORITE_NUMBER_SERVICE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceKey[FAVORITE_NUMBER_SERVICE].title,"Favorite Number Service",PpsMaxTitleLen); + tablePoint->serviceKey[FAVORITE_NUMBER_SERVICE].existFlag = TRUE; + + memset(tablePoint->serviceKey[LANGUAGE_MANAGEMENT].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceKey[LANGUAGE_MANAGEMENT].title,"Language Management",PpsMaxTitleLen); + tablePoint->serviceKey[LANGUAGE_MANAGEMENT].existFlag = TRUE; + + memset(tablePoint->serviceKey[PIN_MANAGEMENT].title,0,PpsMaxTitleLen); + memcpy(tablePoint->serviceKey[PIN_MANAGEMENT].title,"Pin Management",PpsMaxTitleLen); + tablePoint->serviceKey[PIN_MANAGEMENT].existFlag = TRUE; + + +/******************* USSD Service Number **********************/ + for(i=0; iussdServiceNumber[i].existFlag = FALSE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_HOTLINE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_HOTLINE].title,"HotLine Number",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_HOTLINE].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_INQUIRY].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_INQUIRY].title,"Inquiry Number",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_INQUIRY].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_RECHARGE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_RECHARGE].title,"Recharge Number",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_RECHARGE].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_FEE_TRANSFER].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_FEE_TRANSFER].title,"Credit Transfer Number",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_FEE_TRANSFER].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_CALL_ME_BACK].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_CALL_ME_BACK].title,"Call Me Back Number",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_CALL_ME_BACK].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_TELL_ME_NUMBER].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_TELL_ME_NUMBER].title,"Tell Me Number",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_TELL_ME_NUMBER].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].title,"Friends and Family Plan Query",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_BUNDLE_PLAN].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_BUNDLE_PLAN].title,"Bundle Plan",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_BUNDLE_PLAN].existFlag = TRUE; + + memset(tablePoint->ussdServiceNumber[USSD_OC_BUNDLE_QUERY].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceNumber[USSD_OC_BUNDLE_QUERY].title,"Bundle Query",PpsMaxTitleLen); + tablePoint->ussdServiceNumber[USSD_OC_BUNDLE_QUERY].existFlag = TRUE; + + /******************* Service Key **********************/ + for(i=0; i<10+3; i++) + tablePoint->ussdServiceKey[i].existFlag = FALSE; + + memset(tablePoint->ussdServiceKey[USSD_OC_HOTLINE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceKey[USSD_OC_HOTLINE].title,"Exit",PpsMaxTitleLen); + //tablePoint->ussdServiceKey[USSD_OC_HOTLINE].key = 0; + tablePoint->ussdServiceKey[USSD_OC_HOTLINE].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_INQUIRY].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceKey[USSD_OC_INQUIRY].title,"Inquiry Service",PpsMaxTitleLen); + //tablePoint->ussdServiceKey[USSD_OC_INQUIRY].key = 1; + tablePoint->ussdServiceKey[USSD_OC_INQUIRY].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_RECHARGE].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceKey[USSD_OC_RECHARGE].title,"Recharge",PpsMaxTitleLen); + //tablePoint->ussdServiceKey[USSD_OC_RECHARGE].key = 2; + tablePoint->ussdServiceKey[USSD_OC_RECHARGE].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_FEE_TRANSFER].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceKey[USSD_OC_FEE_TRANSFER].title,"Credit Transfer",PpsMaxTitleLen); + //tablePoint->ussdServiceKey[USSD_OC_FEE_TRANSFER].key = 3; + tablePoint->ussdServiceKey[USSD_OC_FEE_TRANSFER].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_CALL_ME_BACK].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceKey[USSD_OC_CALL_ME_BACK].title,"Call Me Back",PpsMaxTitleLen); + //tablePoint->ussdServiceKey[USSD_OC_CALL_ME_BACK].key = 4; + tablePoint->ussdServiceKey[USSD_OC_CALL_ME_BACK].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_TELL_ME_NUMBER].title,0,PpsMaxTitleLen); + memcpy(tablePoint->ussdServiceKey[USSD_OC_TELL_ME_NUMBER].title,"Tell Me Number",PpsMaxTitleLen); + //tablePoint->ussdServiceKey[USSD_OC_TELL_ME_NUMBER].key = 5; + tablePoint->ussdServiceKey[USSD_OC_TELL_ME_NUMBER].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_FRIEND_FAMILY_QUERY].title,0,PpsMaxTitleLen); + sprintf((char *)tablePoint->ussdServiceKey[USSD_OC_FRIEND_FAMILY_QUERY].title,"%s", "Friends and Family Plan Query"); + //tablePoint->ussdServiceKey[USSD_OC_FRIEND_FAMILY_QUERY].key = 6; + tablePoint->ussdServiceKey[USSD_OC_FRIEND_FAMILY_QUERY].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_BUNDLE_PLAN].title,0,PpsMaxTitleLen); + sprintf((char *)tablePoint->ussdServiceKey[USSD_OC_BUNDLE_PLAN].title,"%s", "Data Plan"); + //tablePoint->ussdServiceKey[USSD_OC_FRIEND_FAMILY_QUERY].key = 7; + tablePoint->ussdServiceKey[USSD_OC_BUNDLE_PLAN].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_BUNDLE_QUERY].title,0,PpsMaxTitleLen); + sprintf((char *)tablePoint->ussdServiceKey[USSD_OC_BUNDLE_QUERY].title,"%s", "Bundle Query"); + //tablePoint->ussdServiceKey[USSD_OC_FRIEND_FAMILY_QUERY].key = 7; + tablePoint->ussdServiceKey[USSD_OC_BUNDLE_QUERY].existFlag = TRUE; + + memset(tablePoint->ussdServiceKey[USSD_OC_BUNDLE_PLAN_ALL].title,0,PpsMaxTitleLen); + sprintf((char *)tablePoint->ussdServiceKey[USSD_OC_BUNDLE_PLAN_ALL].title,"%s", "Bundle Plan"); + //tablePoint->ussdServiceKey[USSD_OC_FRIEND_FAMILY_QUERY].key = 7; + tablePoint->ussdServiceKey[USSD_OC_BUNDLE_PLAN_ALL].existFlag = TRUE; + + initSmsSentence(); +} + +static void initCosTable(COSTable *cosItem) +{ + int i; + u_char buf[PpsMaxTitleLen]={0}; + + memset(cosItem->tariff,0,MaxTariffTableItem*sizeof(CosTariff)); + memcpy(cosItem->tariff[0].title,"Tariff",PpsMaxTitleLen); + cosItem->tariff[0].existFlag = TRUE; + + memset(cosItem->serviceControl,0,MaxServiceControlTableItem*sizeof(CosServiceControl)); + memcpy(cosItem->serviceControl[0].title,"Service Control",PpsMaxTitleLen); + cosItem->serviceControl[0].existFlag = TRUE; + cosItem->serviceControl[0].serviceNumberFlag = 0xFFFF; + cosItem->serviceControl[0].smsServiceFlag = 0xFFFF; + cosItem->serviceControl[0].ussdServiceFlag = 0xFFFF; + + memset(cosItem->accountValidity,0,MaxAccountValidityTableItem*sizeof(CosAccountValidity)); + memcpy(cosItem->accountValidity[0].title,"Account Validity",PpsMaxTitleLen); + cosItem->accountValidity[0].existFlag = TRUE; + + memset(cosItem->smsNotificationInquiry,0,MaxSmsNotificationInquiryTableItem*sizeof(CosSmsNotificationInquiry)); + + memcpy(cosItem->smsNotificationInquiry[0].title,"SMS Notification & Inquiry",PpsMaxTitleLen); + cosItem->smsNotificationInquiry[0].existFlag = TRUE; + + memset(cosItem->rechargeCardValidity,0, MaxRechargeCardType*sizeof(CosRechargeCardValidity)); + for(i=0;irechargeCardValidity[i].title,buf,PpsMaxTitleLen); + cosItem->rechargeCardValidity[i].existFlag = TRUE; + } + + memset(cosItem->rechargePromotion,0,MaxRechargeCardType*sizeof(CosRechargePromotion)); + for(i=0;irechargePromotion[i].title,buf,PpsMaxTitleLen); + cosItem->rechargePromotion[i].existFlag = TRUE; + } + + memset(cosItem->capPlan,0,MaxcapPlanTableItem*sizeof(CosCapPlan)); + for(i=0;icapPlan[i].title,buf,PpsMaxTitleLen); + cosItem->capPlan[i].existFlag = TRUE; + } + + memset(cosItem->poolAccount,0,MaxPoolAccountTableItem*sizeof(COS_Pool_Account)); + for(i=0;ipoolAccount[i].title,buf,PpsMaxTitleLen); + cosItem->poolAccount[i].existFlag = TRUE; + } + + memset(cosItem->gprs,0,MaxGprsTableItem*sizeof(PPS_COS_RADIUS_ITEM)); + for(i=0;igprs[i].title,buf,PpsMaxTitleLen); + cosItem->gprs[i].existFlag = TRUE; + } + + memset(cosItem->friendFamilyControl,0,MaxFriendFamilyTableItem*sizeof(CosFriendFamilyControl)); + for(i=0;ifriendFamilyControl[i].title,buf,PpsMaxTitleLen); + cosItem->friendFamilyControl[i].existFlag = TRUE; + } +} + +extern int initRCMReponse(); +int initSNMP() +{ + register_snmp_table(&pps_register); + inquire_trapmsg(snmpTrapPPS); + inquire_rspmsg(11,PPS_OID_PREFIX,(void *)snmpResponse); + + inquire_snmpmsg(13,PPS_OID_THIRDPARTY,(void *)thirdPartyChargeProc); + + memset(&debugmib,0,sizeof(_debug_mib)); + pps_debug_set(); + + initTables(); + + initRCMReponse(); + return 1; +} + + diff --git a/mss/pps/src/main/pps_redis.c b/mss/pps/src/main/pps_redis.c new file mode 100644 index 0000000..fa13d39 --- /dev/null +++ b/mss/pps/src/main/pps_redis.c @@ -0,0 +1,1867 @@ +#include "../include/pps_redis.h" +#include "../include/param.h" +#include +#include +#include +//#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////////////////// +extern void RedisLinkMon(); +extern int RedisFlushDb(); + +extern int RedisCreateLogTask(pthread_t *idTask); +extern void RedisAddLogStr(char *time, const char *level, const char *filename, int line, char *text); + +// Redis log writer +#define MAX_REDIS_LOG_LINES 81920 +#define MAX_REDIS_LINE_LEN 512 +typedef struct OCS_redis_log_t +{ + int header; + int tailer; + + char log_str[MAX_REDIS_LOG_LINES][MAX_REDIS_LINE_LEN]; +}OCS_redis_log_t; + +// simple log +enum RedisLogLevel +{ + RS_ERROR = 1, + RS_WARN = 2, + RS_INFO = 3, + RS_DEBUG = 4, +}; + +void mylog1(const char* filename, int line, enum RedisLogLevel level, const char* fmt, ...) __attribute__((format(printf,4,5))); + +#define redislog(level, format, ...) mylog1(__FILE__, __LINE__, level, format, ## __VA_ARGS__) +// + +// all Redis field of one KEY +#define RR_SERVICE_NBR 0 +#define RR_PRD_INST_ID 1 +#define RR_PRICING_SECTION_ID 2 +#define RR_OFR_INST_ID 3 +#define RR_OFR_ID 4 +#define RR_OFR_NAME 5 +#define RR_BEGIN_TIME 6 +#define RR_END_TIME 7 +#define RR_FREE_VALUE 8 +#define RR_USED_VALUE 9 +#define RR_MEASURE_DOMAIN 10 +#define RR_TARIFF_ID 11 +#define RR_STRATEGY_ID 12 +#define RR_START_REF_TIME 13 +#define RR_END_REF_TIME 14 +#define RR_CALC_PRIORITY 15 +#define RR_EVENT_PRIORITY 16 +#define RR_RATE_UNIT 17 +#define RR_UNIT_FEE 18 +#define RR_REDIS_FIELD_MAX_NUM 19 + +#define TARIFF_TARIFF_ID 0 +#define TARIFF_MEASURE_DOMAIN 1 +#define TARIFF_START_TIME 2 +#define TARIFF_END_TIME 3 +#define TARIFF_FEE_UNIT 4 +#define TARIFF_RATE_UNIT 5 +#define TARIFF_CALC_PRIORITY 6 +#define TARIFF_EVENT_PRIORITY 7 +#define TARIFF_OFR_ID 8 +#define TARIFF_OFR_NAME 9 +#define TARIFF_STRATEGY_ID 10 +#define TARIFF_STRATEGY_NAME 11 +#define TARIFF_REDIS_FIELD_MAX_NUM 12 + +#define HD_OFR_ID 0 +#define HD_TARIFF_ID 1 +#define HD_TARIFF_SEQ 2 +#define HD_GROUP 3 +#define HR_STATE 4 +#define HR_DISCOUNT 5 +#define HD_ID 6 +#define HD_NAME 7 +#define HD_TYPE 8 +#define HD_STATE 9 +#define HD_PRIORITY 10 +#define HD_BEGIN_DATE 11 +#define HD_END_DATE 12 +#define HD_REDIS_FIELD_MAX_NUM 13 + + +#define ACCT_EFF_DATE 0 +#define ACCT_EXP_DATE 1 +#define ACCT_OFR_ID 2 +#define ACCT_OFR_INST_ID 3 +#define ACCT_REDIS_FIELD_MAX_NUM 4 +const char *ACCT_REDIS_FN[ACCT_REDIS_FIELD_MAX_NUM] = { +"effTime",// 0 +"expTime",// 1 +"ofrId",// 2 +"ofrInstId",// 3 +}; + +const char *HD_REDIS_FN[HD_REDIS_FIELD_MAX_NUM] = { +"ofrId",// 0 +"tariffId",// 1 +"tariffSeq",// 2 +"hdGroup",// 3 +"hrState",// 4 +"hrDiscount",// 5 +"hdId",// 6 +"hdName",// 7 +"hdType",// 8 +"hdState",// 9 +"hdPriority",// 10 +"hdBeginDate",// 11 +"hdEndDate",// 12 +}; + +const char *RR_REDIS_FN[RR_REDIS_FIELD_MAX_NUM] = { +"serviceNbr",// 0 +"prdInstId",// 1 +"pricingSectionId",// 2 +"ofrInstId",// 3 +"ofrId",// 4 +"ofrName",// 5 +"beginTime",// 6 +"endTime",// 7 +"freeValue",// 8 +"usedValue",// 9 +"measureDomain",// 10 +"tariffId",// 11 +"strategyId",// 12 +"startRefTime",// 13 +"endRefTime",// 14 +"calcPriority",// 15 +"eventPriority",// 16 +"rateUnit",// 17 +"unitFee",// 18 +}; + +const char *TARIFF_REDIS_FN[TARIFF_REDIS_FIELD_MAX_NUM] = { +"tariffId",// 0 +"measureDomain",// 1 +"startTime",// 2 +"endTime",// 3 +"feeUnit",// 4 +"rateUnit",// 5 +"calcPriority",// 6 +"eventPriority",// 7 +"ofrId",// 8 +"ofrName",// 9 +"strategyId",// 10 +"strategyName",// 11 +}; + +/* +double balance;// float, %f +double promo_balance;// float, %f +long long data;// %lld +int mo_voice;// %d +int mt_voice;// %d +u_short sms;// %hu +u_long validity_date;// %lu +int warning_sms_flag;// %d +*/ + +#define OCS_REDIS_PORT 6379 +#define OCS_REDIS_NUM 2// master and slave + +typedef struct OCS_redis_struct { + BOOL is_local_master; + u32 local_ip; + u32 peer_ip; + redisContext *unix_cxt; + redisContext *peer_cxt; +}OCS_redis_struct; +static OCS_redis_struct redis_mngt = {TRUE, 0, 0, NULL, NULL}; +//static pthread_t log_task_id; + +static void RedisRelMaster() +{ + if (redis_mngt.is_local_master) + { + if (redis_mngt.unix_cxt) + { + redisFree(redis_mngt.unix_cxt); + redis_mngt.unix_cxt = NULL; + } + redislog(RS_WARN, "Release current master unix cxt, and set master to peer!"); + } + else + { + if (redis_mngt.peer_cxt) + { + redisFree(redis_mngt.peer_cxt); + redis_mngt.peer_cxt = NULL; + } + redislog(RS_WARN, "Release current master peer cxt, and set master to unix socket!"); + } + redis_mngt.is_local_master = redis_mngt.is_local_master ? FALSE : TRUE; +} + +int RedisInit(u32 localip, u32 peerip) +{ + if (redis_mngt.unix_cxt != NULL) + { + redisFree(redis_mngt.unix_cxt); + } + + if (redis_mngt.peer_cxt != NULL) + { + redisFree(redis_mngt.peer_cxt); + } + + // connect local redis by unix socket + struct timeval timeout = { 1, 500000 }; // 1.5 seconds + redis_mngt.local_ip = localip; + struct in_addr addr_local; + memcpy(&addr_local, &localip, 4); + redis_mngt.unix_cxt = redisConnectWithTimeout( inet_ntoa(addr_local), OCS_REDIS_PORT, timeout); + //redis_mngt.unix_cxt = redisConnectUnixWithTimeout("/var/run/kvdb.sock", timeout); + if (redis_mngt.unix_cxt == NULL || redis_mngt.unix_cxt->err) { + if (redis_mngt.unix_cxt) + { + printf("Connection unix socket error: %s\n", redis_mngt.unix_cxt->errstr); + redisFree(redis_mngt.unix_cxt); + redis_mngt.unix_cxt = NULL; + } + else + { + printf("Connection unix socket error: can't allocate redis context\n"); + } + exit(1); + } else { + redisReply *reply = redisCommand(redis_mngt.unix_cxt, "AUTH %s", "helloearth"); + if (reply != NULL) + { + if (reply->type == REDIS_REPLY_ERROR) { + printf("Authentication error: %s\n", reply->str); + freeReplyObject(reply); + } + else + { + freeReplyObject(reply); + } + } + } + + // if local redis is master + redisReply *reply = NULL; + reply = redisCommand(redis_mngt.unix_cxt, "INFO");//"INFO replication"); + printf("INFO replication: %s\n", reply->str); + if (strstr(reply->str, "role:master") != NULL || strstr(reply->str, "role:active-replica") != NULL) + { + redis_mngt.is_local_master = TRUE; + } + else + { + redis_mngt.is_local_master = FALSE; + } + freeReplyObject(reply); + // + + // connect peer redis by tcp socket + redis_mngt.peer_ip = peerip; + struct in_addr addr_peer; + memcpy(&addr_peer, &peerip, 4); + redis_mngt.peer_cxt = redisConnectWithTimeout( inet_ntoa(addr_peer), OCS_REDIS_PORT, timeout); + if (redis_mngt.peer_cxt == NULL || redis_mngt.peer_cxt->err) { + if (redis_mngt.peer_cxt) + { + printf("Connection redis socket error: %s\n", redis_mngt.peer_cxt->errstr); + redisFree(redis_mngt.peer_cxt); + redis_mngt.peer_cxt = NULL; + } + else + { + printf("Connection redis socket error: can't allocate redis context\n"); + } + //return false; + } else { + reply = redisCommand(redis_mngt.peer_cxt, "AUTH %s", "helloearth"); + if (reply != NULL) + { + if (reply->type == REDIS_REPLY_ERROR) { + printf("Authentication error: %s\n", reply->str); + freeReplyObject(reply); + } + else + { + freeReplyObject(reply); + } + } + } + + //RedisLoadFromRedis(); + + /*openlog("OcsRedis", LOG_CONS|LOG_PID, LOG_LOCAL2); + syslog(LOG_INFO, + "This is a syslog test message generated by program '%s'\n", + "zjd"); + closelog();*/ + + //RedisCreateLogTask(&log_task_id); + + return 1; +} + +void RedisLinkMon() +{ + static u32 timer = 0; + + if (++timer < (CYCLE_STATE_INTERVAL*3)) + { + return; + } + timer = 0; + + struct timeval timeout = { 0, 500000 }; // 0.5 seconds + if (redis_mngt.unix_cxt == NULL) + { + redis_mngt.unix_cxt = redisConnectUnixWithTimeout("/var/run/kvdb.sock", timeout); + if (redis_mngt.unix_cxt == NULL || redis_mngt.unix_cxt->err) { + if (redis_mngt.unix_cxt) + { + redisFree(redis_mngt.unix_cxt); + redis_mngt.unix_cxt = NULL; + redislog(RS_WARN, "unix socket connect fail!"); + } + else + { + redislog(RS_WARN, "unix socket connect fail, err:NA!"); + } + } + redis_mngt.is_local_master = FALSE; + } + else + { + // if local redis is master + redisReply *reply = NULL; + reply = redisCommand(redis_mngt.unix_cxt, "INFO replication"); + if (reply == NULL) + { + redisFree(redis_mngt.unix_cxt); + redis_mngt.unix_cxt = NULL; + redis_mngt.is_local_master = FALSE; + redislog(RS_WARN, "get local INFO fail, lost unix socket!"); + } + else + { + // printf("INFO replication: %s\n", reply->str); + if (strstr(reply->str, "role:master") != NULL) + { + redis_mngt.is_local_master = TRUE; + } + else + { + redis_mngt.is_local_master = FALSE; + } + freeReplyObject(reply); + } + } + + if (redis_mngt.is_local_master || (redis_mngt.peer_ip == 0)) + { + // read and write in local redis; + return; + } + + if (redis_mngt.peer_cxt) + { + // if local redis is master + redisReply *reply = NULL; + reply = redisCommand(redis_mngt.peer_cxt, "INFO replication"); + if (reply == NULL) + { + redisFree(redis_mngt.peer_cxt); + redis_mngt.peer_cxt = NULL; + redis_mngt.is_local_master = TRUE; + redislog(RS_WARN, "get peer INFO fail, lost peer[M] socket!"); + } + else + { + if (strstr(reply->str, "role:master") != NULL) + { + redis_mngt.is_local_master = FALSE; + } + else + { + redis_mngt.is_local_master = TRUE; + } + freeReplyObject(reply); + return;// as master, and already connected + } + } + + // try to connect peer redis for redis write + struct in_addr addr_peer; + memcpy(&addr_peer, &redis_mngt.peer_ip, 4); + redis_mngt.peer_cxt = redisConnectWithTimeout( inet_ntoa(addr_peer), OCS_REDIS_PORT, timeout); + if (redis_mngt.peer_cxt == NULL || redis_mngt.peer_cxt->err) { + if (redis_mngt.peer_cxt) + { + //printf("Connection redis socket error: %s\n", redis_mngt.peer_cxt->errstr); + redisFree(redis_mngt.peer_cxt); + redis_mngt.peer_cxt = NULL; + redislog(RS_WARN, "peer socket connect fail!"); + } + else + { + redislog(RS_WARN, "peer socket connect fail, NA!"); + } + } + + return; +} + +int RedisFlushDb() +{ + redisReply *reply = NULL; + int ret = 0; + + /* FLUSHDB */ + redisContext *cxt = redis_mngt.is_local_master?redis_mngt.unix_cxt:redis_mngt.peer_cxt; + if (cxt == NULL) + { + return ret; + } + reply = redisCommand(cxt, "FLUSHDB");// clear current db + if (reply == NULL)// connection lost + { + RedisRelMaster(); + return ret; + } + //printf("FLUSHDB: %s\n", reply->str); + + if ((reply->type == REDIS_REPLY_ERROR) && (strncmp(reply->str, "READONLY", 8) == 0)) + { + redislog(RS_WARN, "%s change to READONLY slave redis?", redis_mngt.is_local_master?"local":"peer"); + redis_mngt.is_local_master = redis_mngt.is_local_master ? FALSE : TRUE; + } + else if (reply->type != REDIS_REPLY_ERROR)// success + { + ret = 1; + } + freeReplyObject(reply); + + return ret; +} + +int RedisUpdateUsedBundle(char *service_nbr, int service_type, int rr_id, unsigned long long used_bundle_this_time) +{ + redisReply *reply = NULL; + redisContext *cxt = NULL; + + int i, ret = 0; + for (i=0; itype == REDIS_REPLY_ERROR) && (strncmp(reply->str, "READONLY", 8) == 0)) + { + redislog(RS_WARN, "%s change to READONLY slave redis?", redis_mngt.is_local_master?"local":"peer"); + redis_mngt.is_local_master = redis_mngt.is_local_master ? FALSE : TRUE; + freeReplyObject(reply); + } + else if (reply->type != REDIS_REPLY_ERROR) + { + freeReplyObject(reply); + ret = 1; + redislog(RS_DEBUG, "%s rr_id[%d], add used Bundle %llu!", \ + service_nbr, rr_id, used_bundle_this_time); + break; + } + else + { + redislog(RS_ERROR, "%s fail, error: %s!", service_nbr, (reply->str!=NULL)?reply->str:"unknown"); + freeReplyObject(reply); + break; + } + } + + return ret; +} + +typedef struct Tariff_redis_st +{ + char service_num[24]; + char prefix[24]; + int service_type; + + char time_now[32]; + char rr_time_now[32]; + int secOfDayTime; + int week_day; + + int unit; + int unit_charge; + int discount; + int plan_id; + int bundle_plan_id; + unsigned long long free_value; + unsigned long long used_value; +}Tariff_redis_st; + +typedef struct Hd_redis_st +{ + int ofr_id; + int tariff_id; + int tariff_seq; + int hd_group; + int hr_state; + int hr_discount; + + int hd_id; + char hd_name[64]; + char hd_type[4]; + char hd_state[4]; + int hd_priority; + char begin_time[32]; + char end_time[32]; +}Hd_redis_st; + +typedef struct Rr_redis_st +{ + int prd_inst_id; + int pricing_section_id; + int ofr_inst_id; + int rr_id; + int ofr_id; + char ofr_name[128]; + char begin_time[32]; + char end_time[32]; + long long bundle_value; + long long used_value; + char measure_domain[8]; + int tariff_id; + int strategy_id; + int start_ref_time; + int end_ref_time; + int calc_priority; + int event_priority; + + int rate_unit; + int unit_fee; +}Rr_redis_st; + +typedef struct Ofr_redis_st +{ + int tariff_id; + char measure_domain[8]; + int start_ref_time; + int end_ref_time; + int unit; + int unit_charge; + int discount; + int calc_priority; + int event_priority; + int ofr_id; + char ofr_name[128]; + int strategy_id; + char strategy_name[128]; +}Ofr_redis_st; + +#define MIN_RR_KEY_LEN 14 +int RedisCheckPrefix(int tariff_id, char *prefix); +int RedisGetOfrIdByKey(char *key, int *ofrId, int *ofrInstId); +int RedisGetRrInfo(char *key, Tariff_redis_st *pTariff, Rr_redis_st *pRr) +{ + redisReply *reply = NULL; + + if (redis_mngt.unix_cxt == NULL) + { + redislog(RS_ERROR, "lost unix socket!"); + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + + Rr_redis_st rr_info; + reply = redisCommand(redis_mngt.unix_cxt, "HMGET %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", key, + RR_REDIS_FN[RR_PRD_INST_ID], RR_REDIS_FN[RR_PRICING_SECTION_ID], RR_REDIS_FN[RR_OFR_INST_ID], + RR_REDIS_FN[RR_OFR_ID], RR_REDIS_FN[RR_OFR_NAME], RR_REDIS_FN[RR_BEGIN_TIME], RR_REDIS_FN[RR_END_TIME], + RR_REDIS_FN[RR_FREE_VALUE], RR_REDIS_FN[RR_USED_VALUE], RR_REDIS_FN[RR_MEASURE_DOMAIN], RR_REDIS_FN[RR_TARIFF_ID], + RR_REDIS_FN[RR_STRATEGY_ID], RR_REDIS_FN[RR_START_REF_TIME], RR_REDIS_FN[RR_END_REF_TIME], + RR_REDIS_FN[RR_CALC_PRIORITY], RR_REDIS_FN[RR_EVENT_PRIORITY], RR_REDIS_FN[RR_RATE_UNIT], RR_REDIS_FN[RR_UNIT_FEE] + ); + + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + redislog(RS_ERROR, "Get RR info by key %s fail, error: no connection?!", key); + return -1; + } + + int j, count = 0; + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + //printf("%u) %s\n", j, reply->element[j]->str); + if (reply->element[j]->str == NULL) + { + continue; + } + + switch (j+1) + { + case RR_PRD_INST_ID: + count++; + rr_info.prd_inst_id = atoi(reply->element[j]->str); + break; + case RR_PRICING_SECTION_ID: + count++; + rr_info.pricing_section_id = atoi(reply->element[j]->str); + break; + case RR_OFR_INST_ID:// plan id + rr_info.ofr_inst_id = atoi(reply->element[j]->str); + break; + case RR_OFR_ID: + rr_info.ofr_id = atoi(reply->element[j]->str); + break; + case RR_OFR_NAME: + strcpy(rr_info.ofr_name, reply->element[j]->str); + break; + case RR_BEGIN_TIME: + strcpy(rr_info.begin_time, reply->element[j]->str); + break; + case RR_END_TIME: + strcpy(rr_info.end_time, reply->element[j]->str); + break; + case RR_FREE_VALUE: + rr_info.bundle_value = strtoll(reply->element[j]->str, NULL, 0); + break; + case RR_USED_VALUE: + rr_info.used_value = strtoll(reply->element[j]->str, NULL, 0); + break; + case RR_MEASURE_DOMAIN: + strcpy(rr_info.measure_domain, reply->element[j]->str); + break; + case RR_TARIFF_ID: + rr_info.tariff_id = atoi(reply->element[j]->str); + break; + case RR_STRATEGY_ID: + rr_info.strategy_id = atoi(reply->element[j]->str); + break; + case RR_START_REF_TIME: + rr_info.start_ref_time = atoi(reply->element[j]->str); + break; + case RR_END_REF_TIME: + rr_info.end_ref_time = atoi(reply->element[j]->str); + break; + case RR_CALC_PRIORITY: + rr_info.calc_priority = atoi(reply->element[j]->str); + break; + case RR_EVENT_PRIORITY: + rr_info.event_priority = atoi(reply->element[j]->str); + break; + case RR_RATE_UNIT: + rr_info.rate_unit = atoi(reply->element[j]->str); + break; + case RR_UNIT_FEE: + rr_info.unit_fee = atoi(reply->element[j]->str); + break; + default: + break; + } + } + if (rr_info.used_value < 0) + { + rr_info.used_value = 0; + } + + if ((strcmp(rr_info.end_time, pTariff->rr_time_now) < 0) + || (rr_info.used_value >= rr_info.bundle_value)) + {// already expired, or used up, TODO: remove redis RR record + redislog(RS_INFO, "RR expire: end_time[%s], now_time[%s], used[%lld]/total[%lld]", + rr_info.end_time, pTariff->rr_time_now, rr_info.used_value, rr_info.bundle_value); + freeReplyObject(reply); + return 0; + } + if ((pTariff->secOfDayTime < rr_info.start_ref_time) + || (pTariff->secOfDayTime > rr_info.end_ref_time)) + { + redislog(RS_INFO, "RR mismatch time of day: secOfDayTime[%d], start_ref_time[%d], end_ref_time[%d]", + pTariff->secOfDayTime, rr_info.start_ref_time, rr_info.end_ref_time); + freeReplyObject(reply); + return 0; + } + // match prefix for voice call + if ((pTariff->service_type != 2) && RedisCheckPrefix(rr_info.strategy_id, pTariff->prefix) <= 0) + { + freeReplyObject(reply); + return 0; + } + // + if (pRr->prd_inst_id == 0)// the first one + { + memcpy(pRr, &rr_info, sizeof(rr_info)); + pRr->rr_id = atoi(&key[7+strlen(pTariff->service_num)]);// skip Rr:service_num:measure_domain: + } + else// compare priority + { + if ((rr_info.calc_priority > pRr->calc_priority) + || ((rr_info.calc_priority == pRr->calc_priority) && (rr_info.event_priority > pRr->event_priority)) + || ((rr_info.calc_priority == pRr->calc_priority) && (rr_info.event_priority == pRr->event_priority) + && (strcmp(rr_info.end_time, pRr->end_time) < 0))) + { + memcpy(pRr, &rr_info, sizeof(rr_info)); + pRr->rr_id = atoi(&key[7+strlen(pTariff->service_num)]);// skip Rr:service_num:measure_domain: + } + } + } + else + { + redislog(RS_ERROR, "Get RR info by key %s fail, error: %s!", key, (reply->str!=NULL)?reply->str:"unknown"); + freeReplyObject(reply); + return -1; + } + + redislog(RS_INFO, "Get RR info by key %s succ!", key); + freeReplyObject(reply); + + return 1; +} + +int RedisCheckPrefix(int strategy_id, char *prefix) +{ + redisReply *reply = NULL; + + if (redis_mngt.unix_cxt == NULL) + { + redislog(RS_ERROR, "lost unix socket!"); + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + + reply = redisCommand(redis_mngt.unix_cxt, "SISMEMBER Prefix:%d %s", strategy_id, prefix); + + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + redislog(RS_ERROR, "Check prefix %s of strategy_id[%d] fail, error: no connection?!", prefix, strategy_id); + return -1; + } + + // read data + int ret = -1; + if (reply->type == REDIS_REPLY_INTEGER) + { + if (reply->integer >= 1) + { + redislog(RS_DEBUG, "prefix %s is in strategy_id[%d].", prefix, strategy_id); + ret = 1; + } + else + { + //redislog(RS_DEBUG, "prefix %s is not in strategy_id[%d].", prefix, tariff_id); + ret = 0; + } + } + // + freeReplyObject(reply); + return ret; +} + +int RedisGetTariffInfo1(char *key, Tariff_redis_st *pTariff, Ofr_redis_st *pOfr) +{ + redisReply *reply = NULL; + + if (redis_mngt.unix_cxt == NULL) + { + redislog(RS_ERROR, "lost unix socket!"); + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + + Ofr_redis_st ofr_info; + reply = redisCommand(redis_mngt.unix_cxt, "HMGET %s %s %s %s %s %s %s %s %s %s %s %s %s", key, + TARIFF_REDIS_FN[TARIFF_TARIFF_ID], TARIFF_REDIS_FN[TARIFF_MEASURE_DOMAIN], TARIFF_REDIS_FN[TARIFF_START_TIME], + TARIFF_REDIS_FN[TARIFF_END_TIME], TARIFF_REDIS_FN[TARIFF_FEE_UNIT], TARIFF_REDIS_FN[TARIFF_RATE_UNIT], + TARIFF_REDIS_FN[TARIFF_CALC_PRIORITY], TARIFF_REDIS_FN[TARIFF_EVENT_PRIORITY], TARIFF_REDIS_FN[TARIFF_OFR_ID], + TARIFF_REDIS_FN[TARIFF_OFR_NAME], TARIFF_REDIS_FN[TARIFF_STRATEGY_ID], TARIFF_REDIS_FN[TARIFF_STRATEGY_NAME] + ); + + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + redislog(RS_ERROR, "Get tariff by key %s fail, error: no connection?!", key); + return -1; + } + + int j, count = 0; + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + //printf("%u) %s\n", j, reply->element[j]->str); + if (reply->element[j]->str == NULL) + { + continue; + } + + switch (j) + { + case TARIFF_TARIFF_ID: + count++; + ofr_info.tariff_id = atoi(reply->element[j]->str); + break; + case TARIFF_MEASURE_DOMAIN: + count++; + strcpy(ofr_info.measure_domain, reply->element[j]->str); + break; + case TARIFF_START_TIME:// plan id + ofr_info.start_ref_time = atoi(reply->element[j]->str); + break; + case TARIFF_END_TIME: + ofr_info.end_ref_time = atoi(reply->element[j]->str); + break; + case TARIFF_FEE_UNIT: + ofr_info.unit_charge = atoi(reply->element[j]->str); + break; + case TARIFF_RATE_UNIT: + ofr_info.unit = atoi(reply->element[j]->str); + break; + case TARIFF_CALC_PRIORITY: + ofr_info.calc_priority = atoi(reply->element[j]->str); + break; + case TARIFF_EVENT_PRIORITY: + ofr_info.event_priority = atoi(reply->element[j]->str); + break; + case TARIFF_OFR_ID: + ofr_info.ofr_id = atoi(reply->element[j]->str); + break; + case TARIFF_OFR_NAME: + strcpy(ofr_info.ofr_name, reply->element[j]->str); + break; + case TARIFF_STRATEGY_ID: + ofr_info.strategy_id = atoi(reply->element[j]->str); + break; + case TARIFF_STRATEGY_NAME: + strcpy(ofr_info.strategy_name, reply->element[j]->str); + break; + default: + break; + } + } + + if ((pTariff->secOfDayTime < ofr_info.start_ref_time) + || (pTariff->secOfDayTime > ofr_info.end_ref_time)) + { + redislog(RS_INFO, "Tariff mismatch time of day: secOfDayTime[%d], start_ref_time[%d], end_ref_time[%d]", + pTariff->secOfDayTime, ofr_info.start_ref_time, ofr_info.end_ref_time); + freeReplyObject(reply); + return 0; + } + // match prefix for voice call + if ((pTariff->service_type != 2) && RedisCheckPrefix(ofr_info.strategy_id, pTariff->prefix) <= 0) + { + freeReplyObject(reply); + return 0; + } + // + if (pOfr->tariff_id == 0)// the first one + { + memcpy(pOfr, &ofr_info, sizeof(ofr_info)); + } + else// compare priority + { + if ((ofr_info.calc_priority > pOfr->calc_priority) + || ((ofr_info.calc_priority == pOfr->calc_priority) && (ofr_info.event_priority > pOfr->event_priority))) + { + memcpy(pOfr, &ofr_info, sizeof(ofr_info)); + } + } + } + else + { + redislog(RS_ERROR, "Get tariff by key %s fail, error: %s!", key, (reply->str!=NULL)?reply->str:"unknown"); + freeReplyObject(reply); + return -1; + } + + redislog(RS_INFO, "Get tariff by key %s succ", key); + freeReplyObject(reply); + + return 1; +} + +int RedisGetOfrId(char *service_nbr, int *ofrInstId) +{ + redisReply *reply = NULL; + + if (redis_mngt.unix_cxt == NULL) + { + redislog(RS_ERROR, "lost unix socket!"); + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + + + // scan tariff record + int count = 0; + int cursor = 0; + int nbkeys = 0; + int ofrId = -1;//, ofrInstId = 0; + do + { + count++; + reply = redisCommand(redis_mngt.unix_cxt, "SSCAN Acct:%s %d", service_nbr, cursor); + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + int type = reply ? (reply->type) : 0; + + if (type == REDIS_REPLY_STRING || type == REDIS_REPLY_ERROR) + printf("SCAN reply str %s\r\n", reply->str); + else if (type == REDIS_REPLY_ARRAY) + { + size_t nbelem = reply->elements; + + if (nbelem > 1 && reply->element[1]->type == REDIS_REPLY_ARRAY) + { + struct redisReply *replseqkeys = reply->element[1]; + size_t nbcurkeys = replseqkeys->elements, ik; + //printf("#%ld; SCAN nbcurkeys %zd", count, nbcurkeys); + for (ik = 0; ik < nbcurkeys; ik++) + { + struct redisReply *replcurkey = replseqkeys->element[ik]; + int curkeytype = replcurkey->type; + if (curkeytype == REDIS_REPLY_STRING) + { + nbkeys++; + char acctKey[48]; + sprintf(acctKey, "Acct:%s:%s", service_nbr, replcurkey->str); + redislog(RS_DEBUG, "Get Acct key: %s", acctKey); + if (RedisGetOfrIdByKey(acctKey, &ofrId, ofrInstId) > 0) + { + break; + // compare and update + } + } + } + } + + if ((nbelem > 0) && (reply->element[0]->type == REDIS_REPLY_STRING)) + { + cursor = atol(reply->element[0]->str); + printf("#%d; SSCAN updated cursor %d", count, cursor); + } + else + { + cursor = -1; + printf("#%d; SSCAN nocursor", count); + } + } + freeReplyObject (reply); + reply = NULL; + if (ofrId > 0) { + break; + } + }while (cursor > 0); + return ofrId; + + + /*Rr_redis_st rr_info; + reply = redisCommand(redis_mngt.unix_cxt, "HGET Acct:%s %s", service_nbr, + RR_REDIS_FN[RR_OFR_ID] + ); + + if (reply == NULL) + { + //RedisRelMaster(); + redislog(RS_ERROR, "Get ofr id by key Acct:%s fail, error: no connection?!", service_nbr); + return -1; + } + + // read data + if ((reply->type == REDIS_REPLY_STRING) && (reply->len > 0)) + { + int ofr_id = atoi(reply->str); + redislog(RS_DEBUG, "Get ofr id[%d] by key Acct:%s succ.", ofr_id, service_nbr); + freeReplyObject(reply); + return ofr_id; + } + else + { + freeReplyObject(reply); + return -1; + } + */ +} + +static char date_time_str[24]; +void get_cur_data_time_str() +{ + time_t time_ptr; + struct tm *tmp_ptr = NULL; + int year,month,day,hour,minute,sec; + + + time(&time_ptr); + + tmp_ptr = localtime(&time_ptr); + + year = tmp_ptr->tm_year + 1900; + month = tmp_ptr->tm_mon + 1; + day = tmp_ptr->tm_mday; + + hour = tmp_ptr->tm_hour; + minute = tmp_ptr->tm_min; + sec = tmp_ptr->tm_sec; + + sprintf(date_time_str, "%04d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,sec); + return ; +} + +int RedisGetOfrIdByKey(char *key, int *ofrId, int *ofrInstId) +{ + redisReply *reply = NULL; + + if (redis_mngt.unix_cxt == NULL) + { + redislog(RS_ERROR, "lost unix socket!"); + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + + //Rr_redis_st rr_info; + reply = redisCommand(redis_mngt.unix_cxt, "HMGET %s %s %s %s %s", key, + ACCT_REDIS_FN[ACCT_EFF_DATE],ACCT_REDIS_FN[ACCT_EXP_DATE],ACCT_REDIS_FN[ACCT_OFR_ID],ACCT_REDIS_FN[ACCT_OFR_INST_ID] + ); + + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + redislog(RS_ERROR, "Get ofr id by key %s fail, error: no connection?!", key); + return -1; + } + + int j, count = 0; + char effDate[48], expDate[48]; + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + //printf("%u) %s\n", j, reply->element[j]->str); + if (reply->element[j]->str == NULL) + { + continue; + } + + switch (j) + { + case ACCT_EFF_DATE: + count++; + strcpy(effDate, reply->element[j]->str); + break; + case ACCT_EXP_DATE: + count++; + strcpy(expDate, reply->element[j]->str); + break; + case ACCT_OFR_ID: + count++; + *ofrId = atoi(reply->element[j]->str); + break; + case ACCT_OFR_INST_ID: + count++; + *ofrInstId = atoi(reply->element[j]->str); + break; + default: + break; + } + } + get_cur_data_time_str(); + if (strncmp(effDate, date_time_str, 19)<=0 || strncmp(expDate, date_time_str, 19)>=0) + {// match + } + else + { + *ofrId = 0; + } + } + else + { + redislog(RS_ERROR, "Get ofrId by key %s fail, error: %s!", key, (reply->str!=NULL)?reply->str:"unknown"); + freeReplyObject(reply); + return -1; + } + + redislog(RS_INFO, "Get ofrId by key %s succ!", key); + freeReplyObject(reply); + + return *ofrId; + +} + +int RedisGetOfrIdByServiceNbr(char *service_nbr) +{ + redisReply *reply = NULL; + + if (redis_mngt.unix_cxt == NULL) + { + redislog(RS_ERROR, "lost unix socket!"); + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + + //Rr_redis_st rr_info; + reply = redisCommand(redis_mngt.unix_cxt, "HGET Acct:%s %s", service_nbr, + ACCT_REDIS_FN[ACCT_OFR_ID] + ); + + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + redislog(RS_ERROR, "Get ofr id by key Acct:%s fail, error: no connection?!", service_nbr); + return -1; + } + + // read data + if ((reply->type == REDIS_REPLY_STRING) && (reply->len > 0)) + { + int ofr_id = atoi(reply->str); + redislog(RS_DEBUG, "Get ofr id[%d] by key Acct:%s succ.", ofr_id, service_nbr); + freeReplyObject(reply); + return ofr_id; + } + else + { + freeReplyObject(reply); + return -1; + } + // +} + +void setTariffByRrInfo(Tariff_redis_st *pTariff, Rr_redis_st *pRr) +{ + pTariff->unit = pRr->rate_unit; + pTariff->unit_charge = pRr->unit_fee; + pTariff->discount = 100; + pTariff->plan_id = pRr->ofr_inst_id; + pTariff->bundle_plan_id = pRr->rr_id; + pTariff->free_value = pRr->bundle_value; + pTariff->used_value = pRr->used_value; + return; +} + +void setTariffByOfrInfo(Tariff_redis_st *pTariff, Ofr_redis_st *pOfr) +{ + pTariff->unit = pOfr->unit; + pTariff->unit_charge = pOfr->unit_charge; + pTariff->discount = pOfr->discount; + pTariff->plan_id = 0; + pTariff->bundle_plan_id = 0; + pTariff->free_value = 0; + pTariff->used_value = 0; + return; +} + +int RedisGetHdInfo(char *key, Tariff_redis_st *pTariff, Hd_redis_st *pHd) +{ + redisReply *reply = NULL; + + if (redis_mngt.unix_cxt == NULL) + { + redislog(RS_ERROR, "lost unix socket!"); + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + + Hd_redis_st hd_info; + reply = redisCommand(redis_mngt.unix_cxt, "HMGET %s %s %s %s %s %s %s %s %s %s %s %s %s %s", key, + HD_REDIS_FN[HD_OFR_ID], HD_REDIS_FN[HD_TARIFF_ID], HD_REDIS_FN[HD_TARIFF_SEQ], + HD_REDIS_FN[HD_GROUP], HD_REDIS_FN[HR_STATE], HD_REDIS_FN[HR_DISCOUNT], HD_REDIS_FN[HD_ID], + HD_REDIS_FN[HD_NAME], HD_REDIS_FN[HD_TYPE], HD_REDIS_FN[HD_STATE], HD_REDIS_FN[HD_PRIORITY], + HD_REDIS_FN[HD_BEGIN_DATE], HD_REDIS_FN[HD_END_DATE] + ); + + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + redislog(RS_ERROR, "Get HD info by key %s fail, error: no connection?!", key); + return -1; + } + + int j, count = 0; + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + //printf("%u) %s\n", j, reply->element[j]->str); + if (reply->element[j]->str == NULL) + { + continue; + } + + switch (j) + { + case HD_OFR_ID: + count++; + hd_info.ofr_id = atoi(reply->element[j]->str); + break; + case HD_TARIFF_ID: + count++; + hd_info.tariff_id = atoi(reply->element[j]->str); + break; + case HD_TARIFF_SEQ: + hd_info.tariff_seq = atoi(reply->element[j]->str); + break; + case HD_GROUP: + hd_info.hd_group = atoi(reply->element[j]->str); + break; + case HR_STATE: + hd_info.hr_state = atoi(reply->element[j]->str); + break; + case HR_DISCOUNT: + hd_info.hr_discount = atoi(reply->element[j]->str); + break; + case HD_ID: + hd_info.hd_id = atoi(reply->element[j]->str); + break; + case HD_NAME: + strcpy(hd_info.hd_name, reply->element[j]->str); + break; + case HD_TYPE: + strcpy(hd_info.hd_type, reply->element[j]->str); + break; + case HD_STATE: + strcpy(hd_info.hd_state, reply->element[j]->str); + break; + case HD_PRIORITY: + hd_info.tariff_id = atoi(reply->element[j]->str); + break; + case HD_BEGIN_DATE: + strcpy(hd_info.begin_time, reply->element[j]->str); + break; + case HD_END_DATE: + strcpy(hd_info.end_time, reply->element[j]->str); + break; + default: + break; + } + } + + if (hd_info.hr_state != 1 || strncmp(hd_info.hd_state, "L0R", 3) != 0) + { + freeReplyObject(reply); + return 0;// inactive + } + + int bHoliday = 0; + if (strncmp(hd_info.hd_type, "02", 2) == 0)// weekly, 1-7 + { + if (('0' + pTariff->week_day >= hd_info.begin_time[0]) && ('0' + pTariff->week_day <= hd_info.end_time[0])) + { + bHoliday = 1; + } + } + else if (strncmp(hd_info.hd_type, "03", 2) == 0)// holiday period, mmdd-mmdd + { + if ((strncmp(&pTariff->rr_time_now[4], hd_info.begin_time, 4) >= 0) && (strncmp(&pTariff->rr_time_now[4], hd_info.end_time, 4) <= 0)) + { + bHoliday = 1; + } + } + else if (strncmp(hd_info.hd_type, "04", 2) == 0)// day time period, HHmmss-HHmmss + { + if ((strncmp(&pTariff->rr_time_now[8], hd_info.begin_time, 6) >= 0) && (strncmp(&pTariff->rr_time_now[8], hd_info.end_time, 6) <= 0)) + { + bHoliday = 1; + } + } + if (bHoliday == 1) + { + if ((pHd->tariff_id == 0) || (hd_info.hd_priority > pHd->hd_priority))// new, or higer priority + { + memcpy(pHd, &hd_info, sizeof(hd_info)); + } + } + } + else + { + redislog(RS_ERROR, "Get HD info by key %s fail, error: %s!", key, (reply->str!=NULL)?reply->str:"unknown"); + freeReplyObject(reply); + return -1; + } + + redislog(RS_INFO, "Get HD info by key %s succ!", key); + freeReplyObject(reply); + + return 1; +} + +void scanHolidayDiscount(Tariff_redis_st *pTariff, Ofr_redis_st *pOfr) +{ + redisReply *reply = NULL; + int count = 0, cursor = 0, nbkeys = 0; + //Tariff_redis_st tariff_temp; + Hd_redis_st hd_info = {0,0,0,0}; + + // Scan Holiday discount record + do + { + count++; + // scan bundle first + //reply = redisCommand(redis_mngt.unix_cxt, "SCAN %d MATCH Hd:%d:* COUNT 1000", cursor, pOfr->tariff_id); + reply = redisCommand(redis_mngt.unix_cxt, "SSCAN HdSet:%d %d", pOfr->tariff_id, cursor); + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return ; + } + int type = reply ? (reply->type) : 0; + + if (type == REDIS_REPLY_STRING || type == REDIS_REPLY_ERROR) + printf("SCAN reply str %s\r\n", reply->str); + else if (type == REDIS_REPLY_ARRAY) + { + size_t nbelem = reply->elements; + + if (nbelem > 1 && reply->element[1]->type == REDIS_REPLY_ARRAY) + { + struct redisReply *replseqkeys = reply->element[1]; + size_t nbcurkeys = replseqkeys->elements, ik; + //printf("#%ld; SCAN nbcurkeys %zd", count, nbcurkeys); + for (ik = 0; ik < nbcurkeys; ik++) + { + struct redisReply *replcurkey = replseqkeys->element[ik]; + int curkeytype = replcurkey->type; + if (curkeytype == REDIS_REPLY_STRING) + { + nbkeys++; + //printf("got key#%ld : %s", nbkeys, replcurkey->str); + // get rr info, and compare + redislog(RS_DEBUG, "Get Hd key: %s, len[%zu]", replcurkey->str, replcurkey->len); + if (replcurkey->len >= MIN_RR_KEY_LEN) + { + if (RedisGetHdInfo(replcurkey->str, pTariff, &hd_info) > 0) + { + + // compare and update + } + } + } + } + } + + if ((nbelem > 0) && (reply->element[0]->type == REDIS_REPLY_STRING)) + { + cursor = atol(reply->element[0]->str); + printf("#%d; SSCAN updated cursor %d", count, cursor); + } + else + { + cursor = -1; + printf("#%d; SSCAN nocursor", count); + } + } + freeReplyObject (reply); + reply = NULL; + }while (cursor > 0); + + if (hd_info.tariff_id > 0)// get holiday discount + { + redislog(RS_DEBUG, "Get Hd: discount[%d], tariff_id[%d], hd_id[%d].", hd_info.hr_discount, hd_info.tariff_id, hd_info.hd_id); + pTariff->discount = hd_info.hr_discount; + } +} + +int RedisScanTariff(Tariff_redis_st *target_tariff) +{ + redisReply *reply = NULL; + int count = 0, cursor = 0, nbkeys = 0; + //Tariff_redis_st tariff_temp; + Rr_redis_st rr_info = {0,0,0,0}; + + time_t t; + time(&t); + struct tm *tmp_time = localtime(&t); + target_tariff->secOfDayTime = tmp_time->tm_sec + tmp_time->tm_min*60 + tmp_time->tm_hour * 3600; + strftime(target_tariff->time_now, sizeof(target_tariff->time_now), "%04Y-%02m-%02d %H:%M:%S", tmp_time); + strftime(target_tariff->rr_time_now, sizeof(target_tariff->rr_time_now), "%04Y%02m%02d%H%M%S", tmp_time); + target_tariff->week_day = tmp_time->tm_wday + 1; + + // Scan Rr record first + do + { + count++; + // scan bundle first + //reply = redisCommand(redis_mngt.unix_cxt, "SCAN %d MATCH Rr:%s:%02d:* COUNT 1000", cursor, target_tariff->service_num, target_tariff->service_type); + reply = redisCommand(redis_mngt.unix_cxt, "SSCAN RrSet:%s:%02d %d", target_tariff->service_num, target_tariff->service_type, cursor); + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + int type = reply ? (reply->type) : 0; + + if (type == REDIS_REPLY_STRING || type == REDIS_REPLY_ERROR) + printf("SCAN reply str %s\r\n", reply->str); + else if (type == REDIS_REPLY_ARRAY) + { + size_t nbelem = reply->elements; + + if (nbelem > 1 && reply->element[1]->type == REDIS_REPLY_ARRAY) + { + struct redisReply *replseqkeys = reply->element[1]; + size_t nbcurkeys = replseqkeys->elements, ik; + //printf("#%ld; SCAN nbcurkeys %zd", count, nbcurkeys); + for (ik = 0; ik < nbcurkeys; ik++) + { + struct redisReply *replcurkey = replseqkeys->element[ik]; + int curkeytype = replcurkey->type; + if (curkeytype == REDIS_REPLY_STRING) + { + nbkeys++; + //printf("got key#%ld : %s", nbkeys, replcurkey->str); + // get rr info, and compare + //if (replcurkey->len >= MIN_RR_KEY_LEN) + //{ + char rrKey[48]; + sprintf(rrKey, "Rr:%s:%02d:%s",target_tariff->service_num, target_tariff->service_type, replcurkey->str); + redislog(RS_DEBUG, "Get RR key: %s", rrKey); + if (RedisGetRrInfo(rrKey, target_tariff, &rr_info) > 0) + { + + // compare and update + } + //} + } + } + } + + if ((nbelem > 0) && (reply->element[0]->type == REDIS_REPLY_STRING)) + { + cursor = atol(reply->element[0]->str); + printf("#%d; SSCAN updated cursor %d", count, cursor); + } + else + { + cursor = -1; + printf("#%d; SSCAN nocursor", count); + } + } + freeReplyObject (reply); + reply = NULL; + }while (cursor > 0); + + if (rr_info.prd_inst_id > 0)// get rr bundle succ, return + { + setTariffByRrInfo(target_tariff, &rr_info); + redislog(RS_INFO, "Get RR info succ: plan[%d],rr_id[%d],avail[%lld],used[%lld]", + rr_info.ofr_inst_id, rr_info.rr_id, rr_info.bundle_value, rr_info.used_value); + return 0; + } + + int ofr_inst_id = 0; + int ofr_id = RedisGetOfrId(target_tariff->service_num, &ofr_inst_id); + if (ofr_id < 0) + { + return -1; + } + // scan tariff record + count = 0; + cursor = 0; + nbkeys = 0; + Ofr_redis_st ofr_info = {0}; + do + { + count++; + // scan bundle first + //reply = redisCommand(redis_mngt.unix_cxt, "SCAN %d MATCH Tariff:%d:%02d:* COUNT 1000", cursor, ofr_id, target_tariff->service_type); + reply = redisCommand(redis_mngt.unix_cxt, "SSCAN TariffSet:%d:%02d %d", ofr_id, target_tariff->service_type, cursor); + if (reply == NULL) + { + RedisInit(redis_mngt.local_ip, redis_mngt.peer_ip); + return -1; + } + int type = reply ? (reply->type) : 0; + + if (type == REDIS_REPLY_STRING || type == REDIS_REPLY_ERROR) + printf("SCAN reply str %s\r\n", reply->str); + else if (type == REDIS_REPLY_ARRAY) + { + size_t nbelem = reply->elements; + + if (nbelem > 1 && reply->element[1]->type == REDIS_REPLY_ARRAY) + { + struct redisReply *replseqkeys = reply->element[1]; + size_t nbcurkeys = replseqkeys->elements, ik; + //printf("#%ld; SCAN nbcurkeys %zd", count, nbcurkeys); + for (ik = 0; ik < nbcurkeys; ik++) + { + struct redisReply *replcurkey = replseqkeys->element[ik]; + int curkeytype = replcurkey->type; + if (curkeytype == REDIS_REPLY_STRING) + { + nbkeys++; + //printf("got key#%ld : %s", nbkeys, replcurkey->str); + // get rr info, and compare + //if (replcurkey->len >= 8) + //{ + char tariffKey[48]; + sprintf(tariffKey, "Tariff:%d:%02d:%s", ofr_id, target_tariff->service_type, replcurkey->str); + redislog(RS_DEBUG, "Get Tariff key: %s", tariffKey); + if (RedisGetTariffInfo1(tariffKey, target_tariff, &ofr_info) > 0) + { + break; + // compare and update + } + //} + } + } + } + + if ((nbelem > 0) && (reply->element[0]->type == REDIS_REPLY_STRING)) + { + cursor = atol(reply->element[0]->str); + printf("#%d; SSCAN updated cursor %d", count, cursor); + } + else + { + cursor = -1; + printf("#%d; SSCAN nocursor", count); + } + } + freeReplyObject (reply); + reply = NULL; + if (ofr_info.tariff_id > 0) + { + break; + } + }while (cursor > 0); + + if (ofr_info.tariff_id > 0)// get ofr succ, return + { + ofr_info.discount = 100; + setTariffByOfrInfo(target_tariff, &ofr_info); + target_tariff->plan_id = ofr_inst_id; + + // Get Holiday Discount + scanHolidayDiscount(target_tariff, &ofr_info); + + redislog(RS_INFO, "Get Ofr info succ: ofr&tariff id[%d/%d], unit[%d],unit charge[%d]", + ofr_info.ofr_id, ofr_info.tariff_id, ofr_info.unit, ofr_info.unit_charge); + return 0; + } + + redislog(RS_ERROR, "Get RR and Ofr fail for service_num[%s],service type[%d]", + target_tariff->service_num, target_tariff->service_type); + + return -1; +} + +extern _state_machine *smshm_ptr; +extern int logMsgFlag; +//extern _debug_mib debugmib; +void DebugMsg(void *ptr, const char *fmt, ...); +int RedisGetTariffInfo(u_short portid, char *service_nbr, int service_type, char *called_num) +{ + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += portid; + + redislog(RS_DEBUG, "Try to get tariff for service_num[%s],service type[%d],prefix[%s]", + service_nbr, service_type, called_num); + Tariff_redis_st avail_tariff; + strcpy(avail_tariff.service_num, service_nbr); + avail_tariff.service_type = service_type; + strcpy(avail_tariff.prefix, called_num); + + int ret = RedisScanTariff(&avail_tariff); + + if(ret != 0) + { + shmp->process_info.rest_if.query_tariff_status = 3; //not found + + // log message + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d], No tariff for service_num[%s],service type[%d]", + portid, service_nbr, service_type); + } + redislog(RS_WARN, "No tariff for service_num[%s],service type[%d]", + service_nbr, service_type); + /*if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, no data tariff errcode[%d]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, ret); + }*/ + + return 0; + } + + { + shmp->process_info.rest_if.query_tariff_status = 2; //succeed + + /* + shmp->process_info.tariff.unit_time = pRes->unit_time; + shmp->process_info.tariff.tierRating.tierNumber = 0; + shmp->process_info.tariff.tierRating.rating[0].base_fee = pRes->unit_charge; + */ + + shmp->process_info.rest_if.unit = avail_tariff.unit; + shmp->process_info.rest_if.unit_charge = avail_tariff.unit_charge*1.0/100.0; //in CRM, the unit is *100 for better precision + shmp->process_info.rest_if.tariff_discount = avail_tariff.discount; + shmp->process_info.rest_if.plan_id = avail_tariff.plan_id; + shmp->process_info.rest_if.bundle_plan_id = avail_tariff.bundle_plan_id; + shmp->process_info.rest_if.total_plan_value = avail_tariff.free_value; + shmp->process_info.rest_if.used_plan_value = avail_tariff.used_value; + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d], rrID[%d], ofrInstId[%d], Get tariff: %d*%6.3f * %d, %lld-%lld", + portid, avail_tariff.bundle_plan_id, avail_tariff.plan_id, avail_tariff.unit, shmp->process_info.rest_if.unit_charge, avail_tariff.discount, + avail_tariff.free_value, avail_tariff.used_value); + } + redislog(RS_DEBUG, "Get tariff: %d*%6.3f * %d, %lld-%lld", + avail_tariff.unit, shmp->process_info.rest_if.unit_charge, avail_tariff.discount, + avail_tariff.free_value, avail_tariff.used_value); + /*if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, port[%d] tariff: %d*%6.3f * %d, %lld-%lld", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, portid, + avail_tariff.unit, shmp->process_info.rest_if.unit_charge, avail_tariff.discount, + avail_tariff.free_value, avail_tariff.used_value); + }*/ + } + + return 1; + +} + +// Simple log start ===================================================================== +#ifndef LOGLEVEL +#define LOGLEVEL RS_DEBUG +#endif + +static const char* s_loginfo[] = { + [RS_ERROR] = "ERROR", + [RS_WARN] = "WARN", + [RS_INFO] = "INFO", + [RS_DEBUG] = "DEBUG", +}; + +static void get_timestamp(char *buffer) +{ + time_t t; + struct tm *p; + struct timeval tv; + int len; + int millsec; + + t = time(NULL); + p = localtime(&t); + + gettimeofday(&tv, NULL); + millsec = (int)(tv.tv_usec / 1000); + + /* æ—¶é—´æ ¼å¼�:[2011-11-15 12:47:34:888] */ + len = snprintf(buffer, 32, "[%04d-%02d-%02d %02d:%02d:%02d:%03d] ", + p->tm_year+1900, p->tm_mon+1, + p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, millsec); + + buffer[len] = '\0'; +} + +void mylog1(const char* filename, int line, enum RedisLogLevel level, const char* fmt, ...) +{ + return; + if(level > LOGLEVEL) + return; + + va_list arg_list; + char buf[256]; + memset(buf, 0, 256); + va_start(arg_list, fmt); + vsnprintf(buf, 256, fmt, arg_list); + char time[32] = {0}; + + // 去掉*å�¯èƒ½*存在的目录路径,å�ªä¿�留文件å�� + const char* tmp = strrchr(filename, '/'); + if (!tmp) tmp = filename; + else tmp++; + get_timestamp(time); + + //printf("%s[%s] [%s:%d] %s\n", time, s_loginfo[level], tmp, line, buf); + RedisAddLogStr(time, s_loginfo[level], tmp, line, buf); + + va_end(arg_list); + +} +// Simple log end ===================================================================== + +// Redis log writer +static OCS_redis_log_t redis_log = {0, 0}; +static int curHour = 24; +static char auditFileName[64] = {0}; +static char auditOpenPath[128] = {0}; +static FILE *fp = NULL; + +static int RedisCreateFirstLog() +{ + time_t currentTime; + struct tm *log_time; + + currentTime = time(NULL); + log_time = localtime(¤tTime); + /* format file name */ + sprintf(auditFileName, "OcsRedis_%04d-%02d-%02d-%02d:%02d:%02d.log", log_time->tm_year + 1900, log_time->tm_mon +1, \ + log_time->tm_mday, log_time->tm_hour, log_time->tm_min, log_time->tm_sec); + + sprintf(auditOpenPath, "/var/log/redis/%s", auditFileName); + curHour = log_time->tm_hour; + + return 0; +} + +static int RedisCheckCurHour() +{ + time_t currentTime; + struct tm *log_time; + + currentTime = time(NULL); + log_time = localtime(¤tTime); + if(log_time->tm_hour != curHour)// new hour begin, create new log name + { + curHour = log_time->tm_hour; + + /* create the next audit file */ + sprintf(auditFileName, "OcsRedis_%04d-%02d-%02d-%02d:%02d:00.log", log_time->tm_year + 1900, log_time->tm_mon +1, \ + log_time->tm_mday, log_time->tm_hour, log_time->tm_min); + sprintf(auditOpenPath, "/var/log/redis/%s", auditFileName); + } + + return 0; +} + +static int RedisLogWrite() +{ + char *pStr = NULL; + RedisCheckCurHour(); + + if(redis_log.header != redis_log.tailer) + { + if((fp = fopen(auditOpenPath, "a")) != NULL) + { + do + { + pStr = redis_log.log_str[redis_log.header]; + fwrite(pStr, 1, strlen(pStr), fp); + + /* clear this item after it was written to file */ + //memset(pStr, 0, sizeof(MAX_REDIS_LOG_LINES)); + redis_log.header = (redis_log.header+1) % (MAX_REDIS_LOG_LINES); + }while(redis_log.header != redis_log.tailer); + fclose(fp); + } + else + { + printf("RedisLogWrite(): fail to open log!"); + } + } + + return 0; +} + + +void RedisAddLogStr(char *time, const char *level, const char *filename, int line, char *text) +{ + //char *pStr = NULL; + + if((redis_log.tailer+1) % MAX_REDIS_LOG_LINES == redis_log.header) + {// buffer is full + //printf("RedisAddLogStr(): list full, fail to add log!"); + return; + } + else + { + //strncpy(redis_log.log_str[redis_log.tailer], text, MAX_REDIS_LINE_LEN-1); + snprintf(redis_log.log_str[redis_log.tailer], 512, "%s[%s] [%s:%d] %s\n", \ + time, level, filename, line, text); + redis_log.tailer = (redis_log.tailer+1) % MAX_REDIS_LOG_LINES; + } + + return; +} + +static void *RedisWriteLogTask(void *pParam) +{ + RedisCreateFirstLog(); + + while(1) + { + RedisLogWrite(); + usleep(10); + } + return NULL; +} + +int RedisCreateLogTask(pthread_t *idTask) +{ + pthread_attr_t attr; + struct sched_param priority; + + if(0 != pthread_attr_init(&attr)) + { + return -1; + } + if(0 != pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM))/*bind light process*/ + { + return -1; + } + if(0 != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))/*detach thread*/ + { + return -1; + } + + /*set the thread priority and strategy, before create the thread*/ + if(0 != pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) /*return 0 if success*/ + { + return -1; + } + priority.sched_priority = 75;//priority higher + if(0 != pthread_attr_setschedparam(&attr, (struct sched_param*)&priority)) + { + return -1; + } + + if(0 != pthread_create(idTask, &attr, RedisWriteLogTask, NULL)) + { + return -1; + } + + /*pthread_setschedparam (*idTask, SCHED_FIFO, &priority);*/ + return 0; +} + + + diff --git a/mss/pps/src/main/ppsfunc.c b/mss/pps/src/main/ppsfunc.c new file mode 100644 index 0000000..c62fe62 --- /dev/null +++ b/mss/pps/src/main/ppsfunc.c @@ -0,0 +1,223 @@ +/* +** +** function.c +** Created at 2000-05-29 +** Functions for data conversion, tools. +** +*/ + +#include "../include/includes.h" + +/* +** Fill string 'c' into last area of 'str'. +*/ + +/* duplicate with public module 2006-09-25*/ +/* +void +StringCat(char *str, char *c, int slen) +{ + if (strlen(str) >= slen) return; + while (strlen(str) < slen) + strcat(str, c); + str[slen] = 0; +} +*/ +/* +** Cut string while match character c. +*/ +/* +void +StringCut(char *str, int c) +{ + if (toupper(*str) == toupper(c)) *str=0; + while (str && *str++) + if (toupper(*str) == toupper(c)) { + *str = 0; + break; + } +} +*/ +void Bstr2Hstr(char *cptr) +{ + char s[12] = ""; + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + sprintf(s, "%x", j); + cptr = (char *) s; +} + +void bitstring(char *str, long byze, int biz, int strwid) +{ + int i, j; + + j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1)); + for (i = 0; i < j; i++) + *str++ = ' '; + while (--biz >= 0) { + *str++ = ((byze >> biz) & 1) + '0'; +// +// if (!(biz % 4) && biz) +// *str++ = ' '; +// + } + *str = '\0'; +} +/* +** Binary string convert to int. +*/ + +unsigned int Bstr2Int(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + return(j); +} + +/* +** Hex string convert to int. +*/ + +unsigned int Hstr2Int(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && isxdigit(*cptr)) { + i = *cptr++ - '0'; + if (9 < i) + i -= 7; + j <<= 4; + j |= (i & 0x0f); + } + return(j); +} + +/* Convert data from ASCII form to left-aligned compact BCD form. */ +/* +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if (i & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from left-aligned compact BCD form to ASCII form. */ +/* +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ +/* Convert data from ASCII form to right-aligned compact BCD form. */ +/* +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + if (len > 0) memset(bcd_buf ,0,len/2); + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if ((len - i) & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} +*/ +/* Convert data from right-aligned compact BCD form to ASCII form. */ + +void RbcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} + +/* Convert number to compact BCD, the number must in the range from 0 to 99. */ + +BYTE IntToBcd (int n) +{ + return ((n / 10) << 4) | (n % 10); +} + +/* Convert number from compact BCD. */ + +int BcdToInt (BYTE n) +{ + return (n >> 4) * 10 + (n & 0x0f); +} + +/* Copy charaters, then append a null character to array pointed by dst. */ + +void CopyToString (char *dst, const char *src, int len) +{ + if (len) memcpy(dst, src, len); + dst[len] = '\0'; +} + +/* duplicate with public module 2006-09-25*/ +/* +void gettime(time_buf) +char *time_buf; +{ + struct tm *t,tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(time_buf,"%02d:%02d:%02d",t->tm_hour,t->tm_min,t->tm_sec); + time_buf[8]=0; +} +*/ + +const char * getdaytime(char *daytime_buf) +{ + struct tm *t,tt; + long curr_time; + + t=&tt; + curr_time=time((long *)0); + t=localtime(&curr_time); + sprintf(daytime_buf,"%04d%02d%02d%02d%02d%02d", + t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, + t->tm_min, t->tm_sec); + daytime_buf[14] = 0; + return daytime_buf; +} + diff --git a/mss/pps/src/main/ppsm.c b/mss/pps/src/main/ppsm.c new file mode 100644 index 0000000..53cfced --- /dev/null +++ b/mss/pps/src/main/ppsm.c @@ -0,0 +1,12964 @@ +/* +** +** Service Control Management Entity. +** +*/ + +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/crypt.h" +#include "../include/mfunc.h" +#include "../include/version.h" +#include "../include/ppsoid.h" +#include "../include/config.h" +#include "../include/param.h" +#include "../include/report.h" +#include "../include/precard.h" +#include "../include/pps_public.h" +#include "../include/mfunc.h" + +#include "../include/callingCard.h" +#include "../include/gprs.h" + +#include "../include/plat_inc.h" +#include "../../../../plat/scf/src/include/scfmsg.h" +#include "../../../../plat/scf/src/include/scfpub.h" +#include "../../../../plat/public/src/include/license_id.h" + +#include "../../../../plat/diameter/include/gy_message.h" +#include "../../../../plat/tcp/src/include/tcp_if.h" +#include +#ifdef OCS_USE_REDIS_DB +#include "../include/pps_redis.h" +#endif + +// fix multiple definition==================================== +_debug_mib debugmib; +// + +/*------------------------------------------------*/ +extern int logMsgFlag; +extern char logMsisdn[18]; +extern int pps_peer_hb_flag ; +/*------------------------------------------------*/ +#define CONVERT_16DIGIT_CARD 0 +/*------------------------------------------------*/ + + +static int smshm_id; +static int ramshm_id; +static int blf_shmid; +_state_machine *smshm_ptr; +_tariff_private *blf_shmp; +_ram_data *ramshm_ptr; +char prog_name[12]; +int ipsem_id; +int hbsem_id; +int first_flag=TRUE; +int subSystemID; +u_char alarm_code[2]={0x00,0x00}; +u_char version_id[3]; +u_char peer_version_id[3]; + +int csta_now_instance = 0, csta_old_instance = 0; +int cdr_head_ptr = 0, cdr_tail_ptr = 0; //0x7FFFFFFF; +_load_file load_file; /* 0,1=user data/tariff data */ +static u_char chargeID = 0; +u_long primary_data_server = 0x00; +u_long second_data_server = 0x00; +struct timeval tvnow; +int time_now[7]; + +extern PPSParamStruct ppsParam; + +u_char stopPeriodicSync = 0; + +u_long LOCAL_IP; +extern u_long peer_server_ip; +u_short debug_messages=0; +char serialNumber[9]=""; +int stopReceivePeriodicSyncFlag = 0; +int totalPeriodSyncPackets = 0; + +static int ramInitFlag = 0; +char masterFlag = 0; +int data_source = _SRC_NO_SRC; +int systemCapability,msisdn_head_num=0; +char stoprunning_flag = 0; +/* second server, if 1 primary server determined by Sync module */ + +extern u_char uploadUserStatus[6]; /* status for upload */ +extern u_char uploadPrecardStatus[6]; +extern DWORD PPS_OID_THIRDPARTY[]; +extern char peer_server_in_init; + +unsigned short send_activitytest_timer = SEND_ACTIVITYTEST_PERIODIC; +pthread_mutex_t pps_mtx = PTHREAD_MUTEX_INITIALIZER; +int realSyncTcpSap = -1; +int realSyncTcpPid = -1; + +#ifdef OCS_USE_REDIS_DB +extern int RedisInit(u32 localip, u32 peerip); +#endif + +/*------------------------------------------------*/ +extern int ppsDebugCapMsg(); +extern int decode_initialDP(); +extern int decode_initialDPSMS(); +extern int IsMNPCalledNumber(char *number); +extern char* GetCapError(); +extern int pps_refund_data_volume(_state_data *shmp); +/*------------------------------------------------*/ +extern int findTariffIDByAPNName(char *apn_name); +int SendMNP_ATI(unsigned short portid); +int SetIndexMessAlamFlag(); +int pps_ro_call_wait_first_cca(u16 port); +int pps_ro_adaptor_call_init(u16 port); +int CheckCRDRingBackSericeKey(int serviceKey); +int pps_ro_voice_process(u_short pid); +int pps_get_ro_voice_quota(_state_data *shmp); +void SaveSubsData(); +extern int resetAccessTimeout(_state_data *shmp); +/*------------------------------------------------*/ +extern int ImportBillSMS(FILE *fp); +extern int SendScfTcEND(); +extern int UpdateBalanceForRecharge(); +extern int ImportGprsTariff(FILE *fp); +extern int ImportVasMmsSendTariff(FILE *fp); +extern int ImportVasMmsRetrieveTariff(FILE *fp); +extern int ImportVasEmailTariff(FILE *fp); +extern void freeServiceDaysDeduct(u_short head,u_short tail); +extern int SendAccountInfoBySMPP(); +extern int log_warning(); +extern int SendScfUError(); +extern int sendConnectForCRDService(); +extern int CheckWetherRoamingUser(); +extern int GetAccountZoneIDByLocationInfo(); +extern int CheckWetherFavoriteNumber(); +extern int GetAccountMTZoneID(); +extern int CheckWetherRoamingMTUser(); +extern int GetAccountMTZoneIDByLocationInfo(); +extern int pps_send_map_open(); +extern int pps_send_mnp_ati(); +extern int pps_mt_play_voice_flag(); +extern int pps_get_adaptor_vcs_flag(); +extern int pps_get_ocs_proxy_nai_flag(); +extern int gx_release_port_for_timerout(unsigned short pid); +extern int SendConnectForVMSService(); +extern int SendPreWarningRequestBCSMEvent(); +extern int CheckSeriveIdentification(); +extern int CheckSRFResource(); +extern int SendEstablishTemporaryConnection(); +extern int xap_roaming_rule_get_routing_home_flag(char *vlr_number); +extern int pps_get_answer_timer_out(); +extern int SendAccountBalanceBySrf(); +extern int CheckPINValidity(); +extern int GetAccountFavoriteNumberCounter(); +extern int StoreAccountFavoriteNumber(); +extern int IncreaseFavoriteNumberChangeCounter(); +extern int BillingFavoriteNumberChange(); +extern int GetAccountFavoriteNumber(); +extern int SendFavPromptAndCollectUserInfo(); +extern int UpdateAccountDefaultLanguageType(); +extern int UpdateAccountPIN(); +extern int ppsMapState(); +extern int CreatePPSSubsIndexTable(); +extern int CreateQuenceList(); +extern int ReadSyncMessageForInit(); +extern int ppsDebugRt(); +extern int srfActivityMonitor(); +extern void ppsCheckParameterAutoSaveFlag(); +extern int pps_send_routing_home_prn(u_short portid); +extern int GetMSISDNOfSSN ( BYTE ssn, BYTE * msisdn ); +extern int sendSMSRechargeNegativeResponse(_state_data *shmp, u_char error_code); +extern int initSNMP(); +extern void init_radius_gsn(); +extern int vasProcess(u_short portid); +extern int gx_send_ccr_from_client(struct gy_msg *gy_ptr); +extern BOOL isAccessTimeout(_state_data *shmp); +extern long pps_get_quota_per_request(); +extern int allocate_ps_data_volume_quota(_state_data *shmp, char *failReason); +extern int tcpRealSyncProc(WORD usr_port, BYTE *pdata, WORD datalen, DWORD db_type, DWORD instance, DWORD ocode); +extern int gx_handle_cca_from_server(struct gy_msg *gy_ptr); +extern int pps_get_gy_postpaid_flag(); +extern int ocs_get_gy_report_data_metohd(); +extern int callingCardProc(u_short portid); +extern int pps_charge_postpaid_data(_state_data *shmp, long consumed_volume, long *uncharged_volume); +void SaveTariffPlan(); +extern int ocs_get_threshold_supported(); +extern int pps_get_gprs_inactive_timer(_state_data *shmp); +extern int pps_get_control_state(); +extern int pps_get_gy_delay_timer(int flag); +extern int pps_get_max_call_duration_in_second(); +extern int pps_gprs_process(u_short portid); +extern void SyncMessageProc(); +extern int pps_rest_recv_proxy(); + +/*------------------------------------------------*/ +char callTypeName[13][64]= +{ +"","", +"Normal MO call", +"Normal MT call", +"Normal MF call", +"Normal MO SMS", +"Call hotline", +"Inquiry account", +"Scratch card recharge" +"Credit card recharge", +"Third party recharge", +"One time input recharge", +"Call distribution" +}; + +#define CHECK_MSISDN_LOG_LEVEL() do {\ + if(logMsgFlag & 0x08) \ + { \ + if(strstr((char *)shmp->caller_info.number,logMsisdn)){ \ + shmp->process_info.logMsisdn = 0x01; \ + } \ + if(strstr((char *)shmp->called_info.number,logMsisdn)){ \ + shmp->process_info.logMsisdn = 0x01;\ + } \ + } \ +}while(0) +/*------------------------------------------------*/ + + +void +SetLoadFileFlag(int dataID) +{ + char timebuf[64]={""}; + FILE *fpTmp = NULL; + + PutLogFunID("SetLoadFileFlag"); + + switch(dataID) + { + case 0x01: /* user data */ + load_file.log_fp[_FILE_ID_USER_DATA] = fopen(USER_LOG_FILE,"w"); + load_file.fp[_FILE_ID_USER_DATA] = fopen(USER_FILE_NAME,"rb"); + + uploadUserStatus[3] = 0x00; + uploadUserStatus[4] = 0x00; + uploadUserStatus[5] = 0x00; + + if(load_file.log_fp[_FILE_ID_USER_DATA] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA],"# PPS User Data Loading Log File\n\n" ); + getdate(timebuf); + fprintf(load_file.log_fp[_FILE_ID_USER_DATA],"Time created: %s ",timebuf); + GetTimeHMS(timebuf); + fprintf(load_file.log_fp[_FILE_ID_USER_DATA],"%s\n",timebuf); + fprintf(load_file.log_fp[_FILE_ID_USER_DATA],"Total record: %d\n", + uploadUserStatus[0]*65536 + \ + uploadUserStatus[1]*256 + uploadUserStatus[2]); + } + if(load_file.fp[_FILE_ID_USER_DATA] == NULL) + { + load_file.flag[_FILE_ID_USER_DATA] = 0x00; + ppsParam.fileOperation.uploadUserData = 0x04; +#if DEBUG + if(logMsgFlag & 0x01) + DebugMsg(debugmib.display.asciiOut, + "Load user data file failed! --- No file named %s found.",USER_FILE_NAME); +#endif + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "\nError:\n Load user data file failed! --- No file named %s found.", USER_FILE_NAME); + fclose(load_file.log_fp[_FILE_ID_USER_DATA]); + } + else + { + ppsParam.fileOperation.uploadUserData = 0x02; /* being importing */ +#if DEBUG +if(logMsgFlag & 0x04) + DebugMsg(debugmib.display.asciiOut,"Start to read user data file(%s)...",USER_FILE_NAME); +#endif + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "\nStart to read user data from %s\n",USER_FILE_NAME); + load_file.flag[_FILE_ID_USER_DATA] = 0x01; + } + break; + case 0x02: /* prepaid card */ + load_file.fp[_FILE_ID_PREPAID_CARD] = fopen(PREPAID_CARD_FILE,"r"); + load_file.log_fp[_FILE_ID_PREPAID_CARD] = fopen(PREPAID_CARD_LOG_FILE,"w"); + if(load_file.fp[_FILE_ID_PREPAID_CARD] == NULL ) + { + load_file.flag[_FILE_ID_PREPAID_CARD] = 0x00; + ppsParam.fileOperation.uploadPrepaidCard = 0x04; /* failed */ + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "\nError:\n Load prepaid card file failed! --- No file named %s found.", PREPAID_CARD_FILE); + fclose(load_file.log_fp[_FILE_ID_PREPAID_CARD]); + + return ; + } + load_file.flag[_FILE_ID_PREPAID_CARD] = 0x01; + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD],"# PPS Prepaid Card Loading Log File\n\n" ); + getdate(timebuf); + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD],"Time created: %s ",timebuf); + GetTimeHMS(timebuf); + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD],"%s\n",timebuf); + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD],"Total record: %d\n", + + uploadPrecardStatus[0]*65536 + \ + uploadPrecardStatus[1]*256 + uploadPrecardStatus[2]); + + ppsParam.fileOperation.uploadPrepaidCard = 0x02; /* being importing */ +#if DEBUG + DebugMsg(debugmib.display.asciiOut,"Start to read prepaid card data file(%s)...",PREPAID_CARD_FILE); +#endif + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "\nStart to read prepaid card data from %s\n",PREPAID_CARD_FILE); + + + break; + case 0x03:/* tariff data */ + load_file.fp[_FILE_ID_COMM_TARIFF] = fopen(COMM_TARIFF_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_COMM_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_COMM_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + + //return ; + } + else + load_file.flag[_FILE_ID_COMM_TARIFF] = 0x01; + + load_file.fp[_FILE_ID_RENT_TARIFF] = fopen(RENT_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_RENT_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_RENT_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + // return ; + } + else + load_file.flag[_FILE_ID_RENT_TARIFF] = 0x01; + + load_file.fp[_FILE_ID_BILL_TARIFF] = fopen(TARIFF_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_BILL_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_BILL_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_BILL_TARIFF] = 0x01; + + load_file.fp[_FILE_ID_MT_TARIFF] = fopen(MT_TARIFF_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_MT_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_MT_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_MT_TARIFF] = 0x01; + + load_file.fp[_FILE_ID_DISCOUNT] = fopen(DISCOUNT_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_DISCOUNT] == NULL ) + { + load_file.flag[_FILE_ID_DISCOUNT] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_DISCOUNT] = 0x01; + + load_file.fp[_FILE_ID_HOLIDY] = fopen(HOLIDAY_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_HOLIDY] == NULL ) + { + load_file.flag[_FILE_ID_HOLIDY] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_HOLIDY] = 0x01; + + load_file.fp[_FILE_ID_BILL_SMS] = fopen(BILL_SMS_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_BILL_SMS] == NULL ) + { + load_file.flag[_FILE_ID_BILL_SMS] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_BILL_SMS] = 0x01; + + load_file.fp[_FILE_ID_GPRS_TARIFF] = fopen(BILL_GPRS_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_GPRS_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_GPRS_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_GPRS_TARIFF] = 0x01; + + load_file.fp[_FILE_ID_VAS_MMS_SEND_TARIFF] = fopen(BILL_VAS_MMS_SEND_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_VAS_MMS_SEND_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_VAS_MMS_SEND_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_VAS_MMS_SEND_TARIFF] = 0x01; + + load_file.fp[_FILE_ID_VAS_MMS_RETRIEVE_TARIFF] = fopen(BILL_VAS_MMS_RETRIEVE_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_VAS_MMS_RETRIEVE_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_VAS_MMS_RETRIEVE_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_VAS_MMS_RETRIEVE_TARIFF] = 0x01; + + load_file.fp[_FILE_ID_VAS_MMS_EMAIL_TARIFF] = fopen(BILL_VAS_MMS_EMAIL_FILE_NAME,"r"); + if(load_file.fp[_FILE_ID_VAS_MMS_EMAIL_TARIFF] == NULL ) + { + load_file.flag[_FILE_ID_VAS_MMS_EMAIL_TARIFF] = 0x00; + ppsParam.fileOperation.uploadTariffPlan = 0x04; /* failed */ + //return ; + } + else + load_file.flag[_FILE_ID_VAS_MMS_EMAIL_TARIFF] = 0x01; + + ppsParam.fileOperation.uploadTariffPlan = 0x03; /* finished */ + fpTmp=fopen("../log/tariff.log","a+"); + if(fpTmp != NULL) + fprintf(fpTmp,"Update tariff @ 20%02d-%02d-%02d %02d:%02d:%02d\n", + time_now[0],time_now[1],time_now[2], + time_now[3],time_now[4],time_now[5]); + fclose(fpTmp); + memset(&ramshm_ptr->tariff_data,0,sizeof(_tariff_data)); /* clear old tariff */ +// memset(&ramshm_ptr->tariff_data.bill_discount,100, +// sizeof(_bill_discount)*MAX_DISCOUNT_ID*24); + break; + default: + break; + } +} + +int ReadUserDataFromFile() +{ + static int recordnum=0; + char record[512]={""}; + int loop; + + PutLogFunID("ReadUserDataFromFile"); + + for(loop=0;loopstate_data; + + PutLogFunID("ReleaseAll"); + + shmp += portid; + + if(shmp->process_info.tcend) + SendScfTcEND(portid); + + ReleasePortStatus(portid); + + pthread_mutex_lock( &pps_mtx );// mutex lock================= + shmp->process_info.sub_state = S_IDLE; + shmp->context_info.new_flag = 0; + shmp->process_info.tcend = 0; + memset(shmp, 0, sizeof(_state_data)); + pthread_mutex_unlock( &pps_mtx );// mutex unlock============== + /* clear process and context info */ +} + + +void +TariffPlanProc() +{ + _proc_data *shmp=NULL; + u_long next_update_tariff = ppsParam.fileOperation.nextTariffStartTime; + static int tariffCounter=0; + + PutLogFunID("TariffPlanProc"); + + shmp=&smshm_ptr->proc_data[STATE_UPDATE_TARIFF]; + switch(shmp->state_i) { + case 0: + if(tariffCounter++>=CYCLE_STATE_INTERVAL) + { + tariffCounter = 0; + shmp->state_i = 2; + } + break; + case 1: + load_tariff_main(); + #if DEBUG + if(logMsgFlag & 0x04) + DebugMsg(debugmib.display.asciiOut, "Tariff plan take affect at %d", + next_update_tariff); +#endif + shmp->state_i = 0; + break; + default: + shmp->state_i = + (next_update_tariff - tvnow.tv_sec); + if (shmp->state_i < 0 ) shmp->state_i = 0 ; + break; + } +} + +int +BeatTrans() +{ + static int counter = 0; +// static int recreate_index_counter = -3; + /* offset 30seconds for importing subs. data file progress */ + + if(counter++ ==10*CYCLE_STATE_INTERVAL) + { + counter = 0; + ppsSendHeartBeating(); + + peer_server_in_init = 0; + + /* + if((debugmib.display.sysState == _SYS_STATE_NORMAL) && + (debugmib.display.peer_state == 0x10 )) + { + if(debugmib.measurement.peer_usernumber != + debugmib.measurement.usernumber) + { + if((recreate_index_counter++ % 330)==0) // about 330 *10seconds + { + CreatePPSDataIndexForAll(); + } +// recreate_index_counter ++; + } + else + { + recreate_index_counter = -30; + + } + + } + */ + if(debugmib.display.peer_state_counter++>=2) + { + debugmib.display.peer_state = 0x00; + } + } + + return SUCCESS; +} + + +void +PeriodicChargeProc() +{ + _proc_data *shmp=NULL; + int loop=PC_LOOP_NUM; + int id=0, type=0,totalid=0,flag=1,tariff_id=0; + int head=0, tail=0, i, favorite_rent_id=0,sms_send_flag=0; + int charge = 0; + _prepaid_info *shmp_ptr = NULL; + + PutLogFunID("PeriodicChargeProc"); + + shmp = &smshm_ptr->proc_data[STATE_PERIODIC_TARIFF]; + switch(shmp->state_i) + { + case 0: + if (PERIODIC_CHARGE_HOUR == GetTmHour() + && PERIODIC_CHARGE_MINUTE == GetTmMinute() + && 8 < GetTmSecond() + && 10 > GetTmSecond() + && chargeID == 1) + { + shmp->count = 0; + shmp->state_i = 1 ; + } + break; + case 1: + while(loop-- > 0) + { + head = (int) (shmp->count / UNIT_STORE_ACCOUNT); + tail = (int) (shmp->count % UNIT_STORE_ACCOUNT); + sms_send_flag=0; + if (shmp->count++ >=MSISDN_HEAD_NUM*UNIT_STORE_ACCOUNT) + { + shmp->state_i = 0; + return; + } + + + if(IsEnablePeriodicAction(head,tail) == TRUE) + { + freeServiceDaysDeduct(head, tail); + resetPoolSlaveDaily(head,tail); + SendAccountRealSync(head*UNIT_STORE_ACCOUNT+tail,0.0,0.0,OMC_OCODE_EDIT); + } + + if (IsEnablePeriodicCharge(head, tail) ) + { + + totalid = GetUserType(head, tail); /* user type */ + tariff_id = GetMOTariffIDWithFreeServiceControl(head,tail); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) + tariff_id = 0; + + shmp_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(shmp_ptr->favorite_plan_id>0 && shmp_ptr->favorite_plan_state == 0) + { + favorite_rent_id = + ppsParam.ppsTables.cosTable[shmp_ptr->cos_id].friendFamilyControl[0].friendFamilyPlan[shmp_ptr->favorite_plan_id-1].rentID-1; + } + + for(i=0;i<8;i++) + { + flag = 1; + if(!((flag<count, head, tail, tariff_id,id, type); +#endif + switch(type) + { + case 0: /* daily */ + charge = GetPeriodicTariffFee(tariff_id,id); + if (charge != 0) + { + UpdateAccountBalance(head, tail, -charge); + SendAccountRealSync(head*UNIT_STORE_ACCOUNT+tail,-charge,0.0,OMC_OCODE_EDIT); + SendPeriodicChargeCDR(head,tail, charge, CT_RENT_CHARGE_TYPE0+id); + } + break; + case 1: /* monthly */ + if (time_now[2] == GetPeriodicChargeDate(tariff_id,id)) + { + charge = GetPeriodicTariffFee(tariff_id,id); + if(favorite_rent_id == id) // to clear F&F number + { + if(CheckClearFriendFamilyNumber(head, tail, charge, id)) + { + charge = 0; + } + } + if (charge != 0) + { + UpdateAccountBalance(head, tail, -charge); + SendPeriodicChargeCDR(head,tail, charge, CT_RENT_CHARGE_TYPE0+id); + if(ppsParam.ppsTables.cosTable[shmp_ptr->cos_id].smsNotificationInquiry[0].smsNotificationWhenRentCharge) + { + if(sms_send_flag==0) + { + sendPPSNotificationMessage(head, tail, SMS_RENT_CHARGE); + sms_send_flag = 1; + } + } + } + SendAccountRealSync(head*UNIT_STORE_ACCOUNT+tail,-charge,0.0,OMC_OCODE_EDIT); + } + break; + } /* switch(type) */ + }/* for */ + } /* if (...) */ + } + break; + default: + shmp->state_i = 0; + break; + } +} + +int RechargeFailedUpdateAccountData(u_short portid) +{ + int maxThreshold=0, instance; + _account_info pInfo; + _state_data *shmp; + + + PutLogFunID("RechargeFailedUpdateAccountData"); + + if(portid>=MAX_FSM_PROCESS) + return 0; + + shmp=(_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.rechargeByOther) + { + memcpy(&pInfo,&shmp->caller_info,sizeof(_account_info)); + memcpy(&shmp->caller_info,&shmp->recharge_info,sizeof(_account_info)); + } + + SendRechargeCDR(portid, CT_RECHARGE_FAIL, 0); + + UpdateAccountRechargeFail(shmp->caller_info.head, + shmp->caller_info.tail); + + maxThreshold = GetParamRechargeAttemptLimit(); + if ( maxThreshold>0 && + maxThreshold< GetAccountRechargeFail(shmp->caller_info.head, shmp->caller_info.tail)) + { + UpdateAccountStatus(shmp->caller_info.head, shmp->caller_info.tail, T_BLACKLIST); + ResetAccountRechargeFail(shmp->caller_info.head, shmp->caller_info.tail); + } + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + + if(shmp->process_info.rechargeByOther) + { + memcpy(&shmp->caller_info,&pInfo,sizeof(_account_info)); + } + return 1; +} + +int CheckWetherValidRechargeCard(u_short portid, char *card_pwd, int *result) +{ + int retval = 1; + + PutLogFunID("CheckWetherValidRechargeCard"); + + if(portid>=MAX_FSM_PROCESS) + return 0; + + if(RechargeCardRequest(portid,card_pwd,result) != 1) + { + RechargeFailedUpdateAccountData(portid); + retval = 0; + } + return retval; +} + + +int RechargeRequestProc(u_short portid) +{ + int retval = S_IDLE,promo_balance=0; + DWORD instance=0; + _account_info tmp_info; + _state_data *shmp; + COSTable *cosTableItem; + + if(portid>=MAX_FSM_PROCESS) return 0; + + PutLogFunID("RechargeRequestProc"); + + shmp=(_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = shmp->process_info.state; + //shmp->process_info.state = S_IDLE; + + if(shmp->process_info.rechargeByOther ==1) + { + memcpy(&tmp_info, &shmp->caller_info, sizeof(_account_info)); + memcpy(&shmp->caller_info, &shmp->recharge_info, sizeof(_account_info)); + } + + UpdateBalanceForRecharge(&shmp->caller_info, GetRechargeCardFaceValue(shmp)); + UpdateRechargeCard(portid, CARD_USED); + SendRechargeCDR( portid, CT_RECHARGE_SUCCESS, GetRechargeCardFaceValue(shmp)); + + if(T_FRESH == GetAccountStatus(&shmp->caller_info) ) + { + UpdateAccountFirstUsedDate(shmp->caller_info.head, shmp->caller_info.tail); + UpdateAccountStatus(shmp->caller_info.head, shmp->caller_info.tail, T_NORMAL); + UpdateExpirationFirstCharge(shmp); + } + else + { + UpdateExpiration(shmp); + UpdateAccountStatus(shmp->caller_info.head, shmp->caller_info.tail, T_NORMAL); + } + + // promotion + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(IsPromotionTime(cosTableItem,tvnow)) + { + promo_balance = GetPromotionAmount(cosTableItem,GetRechargeCardFaceValue(shmp)); + if(promo_balance !=0) + { + shmp->cdr_info.answertime = tvnow.tv_sec + 1; + UpdateAccountPromotionBalance(shmp->caller_info.head, shmp->caller_info.tail, (float)promo_balance); + UpdateAccountPromotionExpiryDay( + shmp->caller_info.head, + shmp->caller_info.tail, + GetPromotionDay(cosTableItem,GetRechargeCardFaceValue(shmp)) + ); + SendRechargeCDR( portid, CT_RECHARGE_SUCCESS, + GetPromotionAmount(cosTableItem,GetRechargeCardFaceValue(shmp))); + } + } + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + ResetAccountRechargeFail(shmp->caller_info.head, shmp->caller_info.tail); + resetCMBTimes(&shmp->caller_info); + SendAccountRealSync(instance,GetRechargeCardFaceValue(shmp),promo_balance,OMC_OCODE_EDIT); + + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenRecharge) + { + if(shmp->process_info.serviceType == SRV_RECHARGE_ONE_INPUT) + SendAccountInfoBySMPP(&shmp->caller_info, + ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + else + SendAccountInfoBySMPP(&shmp->caller_info, + ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + } + + if(shmp->process_info.rechargeByOther ==1) + { + memcpy(&shmp->caller_info, &tmp_info, sizeof(_account_info)); + } + + return retval; +} + + +int IdleProc(u_short invoke_id) +{ + _state_data *shmp;//, *ptr; + int retval; + shmp=(_state_data *)&smshm_ptr->state_data; + shmp += invoke_id; + retval = shmp->process_info.state; + + if (shmp->context_info.new_flag == NO ){ + return retval; + } + + shmp->context_info.new_flag = NO; + switch(shmp->context_info.mtype) { + case CAP_O_OPEN: + retval = S_WAITING_INITIALDP; + break; + default: + ReleasePortStatus(invoke_id); + retval = S_IDLE; + break; + } + + return retval; +} + +int +WaitingForInitialDP(u_short portid) +{ + int retval, dlgid, msglen; + int caller_status,called_status; + CosServiceControl *serviceControlItem; + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + CAP_Message capmsg; + CapArg capArg; + char buf[BUFSIZE],msisdn[64]; + COSTable *cosTableItem; + + + retval = shmp->process_info.state; + shmp += portid; + dlgid = shmp->context_info.dialogue_id; + shmp->process_info.portid = portid; + PutLogFunID("WaitingForInitialDP"); + if(shmp->process_info.funnel ++ >(ONE_MINUTE_STATE_TIME)) + { + log_warning("Wait InitialDP(First operation) timeout!",portid); + retval = S_RELEASE_ALL; + return retval; + } + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + + + shmp->process_info.funnel = 0; + + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + + capArg.version = shmp->context_info.acn_ver; + + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + retval = S_RELEASE_ALL; + return retval; + } + switch(capmsg.msgOperaCode) + { + case CAP_OC_AssistRequestInstructions: + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + ppsBcdToAsciiR(buf, + &capArg.msg_list.assistRequestInstructionsArg.correlationID[4], + 4); + + shmp->process_info.correlationID = atoi(buf); + retval = S_SEND_PLAY_ANNOUNCEMENT; + AddPPSStatistics(MIBPPS_AST_INS,shmp->process_info.dir); + return retval; + break; + case CAP_OC_InitialDP: + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + AddPPSStatistics(MIBPPS_INITIALDP,shmp->process_info.dir); + if(!decode_initialDP(shmp,portid,capArg)) + { + log_warning("\33[31m %04d Invalid InitialDP Message\33[0m",portid); + + SendReleaseCall(portid); + retval = S_RELEASE_ALL; + return retval; + } + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + + if(logMsgFlag & 0x08) + { + if(strstr((char *)shmp->caller_info.number,logMsisdn)){ + shmp->process_info.logMsisdn = 0x01; + } + if(strstr((char *)shmp->called_info.number,logMsisdn)){ + shmp->process_info.logMsisdn = 0x01; + } + } + + switch(shmp->context_info.callType) + { + case CT_MO_CALL: + shmp->process_info.serviceType = SRV_NORMAL_MO_CALL; + SetCallType(shmp, CT_NDD_CALL_OUT); + break; + case CT_MT_CALL: + shmp->process_info.serviceType = SRV_NORMAL_MT_CALL; + SetCallType(shmp, CT_LOCAL_CALL_IN); + break; + case CT_MF_CALL: + shmp->process_info.serviceType = SRV_NORMAL_MF_CALL; + SetCallType(shmp, CT_NDD_CALL_OUT); + break; + } + + shmp->process_info.routing_home_flag = 0; + + if(pps_get_adaptor_flag()) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut," [%04d] Call type: <%s>", portid, + callTypeName[shmp->process_info.serviceType]); + DebugMsg(debugmib.display.asciiOut," Caller : <%s>, Called : <%s>", + shmp->caller_info.number, shmp->called_info.number); + + } + + if(shmp->context_info.callType == CT_MO_CALL) + { + int routing_home_flag = 0; + + routing_home_flag = xap_roaming_rule_get_routing_home_flag(shmp->cdr_info.locationNumber); + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut," [%04d] check routing home : %d", portid, routing_home_flag); + + } + + if(routing_home_flag>0) + { + shmp->process_info.routing_home_flag = 1; + + } + else + { + shmp->process_info.routing_home_flag = 0; + } + + shmp->process_info.serviceType = GetServiceType(shmp); + switch(shmp->process_info.serviceType) + { + case SRV_INQUIRY: + case SRV_SCRATCH_CARD_RECHARGE: + case SRV_FEE_TRANSFER: + if(shmp->context_info.acn_ver<1) + { + shmp->process_info.tcos = SERVICE_NOT_AVAILABLE; + SendReleaseCall(portid); + return (retval= S_RELEASE_ALL); + + } + + shmp->process_info.promptAndCollectUserInfo = 1; + return (retval = S_REQUEST_EVENTS); + break; + default: + break; + } + + } + + shmp->process_info.state = S_RO_ADAPTOR_CALL_INIT; + + return S_RO_ADAPTOR_CALL_INIT; + } + + GetAccountPos(&shmp->caller_info); + GetAccountPos(&shmp->called_info); + + if(shmp->caller_info.headcaller_info.cos_id = GetAccountCosID(&shmp->caller_info); + shmp->caller_info.cug_id = GetAccountCUG(&shmp->caller_info); + } + + if(shmp->called_info.headcalled_info.cos_id = GetAccountCosID(&shmp->called_info); + shmp->called_info.cug_id = GetAccountCUG(&shmp->called_info); + } + + caller_status = GetAccountStatus(&shmp->caller_info); + shmp->caller_info.status = caller_status; + called_status = GetAccountStatus(&shmp->called_info); + shmp->called_info.status = called_status; + + //shmp->process_info.logMsisdn = 0x00; + + + #if DEBUG + if(shmp->process_info.logMsisdn && logMsgFlag != 0xff) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + + shmp->process_info.callConnected = 0; + switch(shmp->context_info.callType) + { + case CT_MO_CALL: + case CT_MF_CALL: + SetIndexMessAlamFlag(0); + + shmp->process_info.serviceType = GetServiceType(shmp); + + if(shmp->caller_info.status == T_EXTERNAL) + { + if( shmp->process_info.serviceType == SRV_OTHER_VMS_MAITENANCE + || + shmp->process_info.serviceType == SRV_VMS_DEPOSIT + //|| + //shmp->process_info.serviceType == SRV_CRD + ) + { + shmp->process_info.promptAndCollectUserInfo = 1; + return (retval = S_REQUEST_EVENTS); + } + else if(shmp->process_info.serviceType == SRV_CRD) + { /* for OMT roaming postpaid subs to access VMS */ + if(GetCRDDestination((char *)shmp->caller_info.number, + msisdn, + SRV_CRD-SRV_CRD)) + { + shmp->process_info.serviceType = + SRV_NORMAL_MO_CALL; + shmp->process_info.callConnected = 1; + } + else + { + shmp->process_info.promptAndCollectUserInfo = 1; + return (retval = S_REQUEST_EVENTS); + } + } + else if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + DebugMsg(debugmib.display.asciiOut, + "\33[31mcaller <%s> is not Prepaid subs \33[0m", + shmp->caller_info.number); + + shmp->process_info.tcend = 1; + if(CheckCRDRingBackSericeKey(shmp->process_info.serviceKey)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + DebugMsg(debugmib.display.asciiOut, + "\33[31m Postpaid VMS ring bak call, let it gooo \33[0m"); + SendContinue(portid); + SendScfTcEND(portid); + } + else + { + shmp->process_info.tcos = UNALLOCATED_NUMBER; + shmp->process_info.u_error = CAP_ERR_MISSING_CUSTOMER_RECORD; + shmp->process_info.oc = CAP_OC_InitialDP; + SendScfUError(portid); + //SendScfUAbort(portid); + //SendReleaseCall(portid); + } + return (retval = S_RELEASE_ALL); + } + }//if t_external + SetIndexMessAlamFlag(2); + + //CheckPromotionLatchFlag(&shmp->caller_info); + + switch(shmp->process_info.serviceType) + { + case SRV_CALL_HOTLINE: + case SRV_INQUIRY: + case SRV_SCRATCH_CARD_RECHARGE: + case SRV_CREDIT_CARD_RECHARGE: + case SRV_THIRD_PARTY_RECHARGE: + case SRV_RECHARGE_2TYPES: + case SRV_CALLINGCARD_MANAGE:/*calling card */ + case SRV_FEE_TRANSFER: + case SRV_POOL_ACCOUNT: + if(shmp->context_info.acn_ver<1) + { + shmp->process_info.tcos = SERVICE_NOT_AVAILABLE; + SendReleaseCall(portid); + return (retval= S_RELEASE_ALL); + + } + + shmp->process_info.promptAndCollectUserInfo = 1; + return (retval = S_REQUEST_EVENTS); + break; + case SRV_RECHARGE_ONE_INPUT: + shmp->process_info.chargeFrom = 2; + + if( (caller_status != T_RELEASED && caller_status != T_BLACKLIST ) + || + (caller_status == T_EXTERNAL && shmp->process_info.palim_auto_register ) ) + { + //int result; + + shmp->process_info.sub_state = 1; + /* + if(CheckWetherValidRechargeCard(portid,shmp->called_info.number,&result)) + { + RechargeRequestProc(portid); + shmp->process_info.sub_state = 1; + } + else + shmp->process_info.sub_state = 2; + */ + } + + if(shmp->context_info.acn_ver<1) + { + shmp->process_info.tcos = SERVICE_NOT_AVAILABLE; + SendReleaseCall(portid); + return (retval= S_RELEASE_ALL); + + } + + shmp->process_info.promptAndCollectUserInfo = 1; + return (retval = S_REQUEST_EVENTS); + break; + case SRV_CRD: + shmp->process_info.serviceType = SRV_NORMAL_MO_CALL; + shmp->process_info.callConnected = 1; + break; + } + + if(caller_status == T_BLACKLIST && + (strlen((char *)ppsParam.ppsTables.serviceNumber[CustomerCareCenterNumberPosition].number)>=3)) + { + shmp->process_info.callConnected = 1; + strcpy(shmp->process_info.tmpDigits, + (char *)ppsParam.ppsTables.serviceNumber[CustomerCareCenterNumberPosition].number); + sendConnectForCRDService(portid); + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + + serviceControlItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id].serviceControl[0]; + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + + shmp->caller_info.location = + GetTariffLacInfo(shmp->cdr_info.cgi); + if(cosTableItem->tariff[0].chargeBy) + { + pps_print_event(shmp->process_info.logMsisdn,"%s charged by cgi",shmp->caller_info.number); + if(shmp->caller_info.location<0) + { + pps_print_error(shmp->process_info.logMsisdn,"%s isn't matched by cgi,so charged by cos",shmp->caller_info.number); + shmp->caller_info.location = + GetAccountZoneID(shmp->caller_info.head, + shmp->caller_info.tail); + } + else + { + CheckWetherRoamingUser(shmp); + shmp->caller_info.location = + GetAccountZoneIDByLocationInfo(shmp->caller_info.location); + } + } + else + { + pps_print_event(shmp->process_info.logMsisdn,"%s charged by cos",shmp->caller_info.number); + if(shmp->caller_info.location>=0) + { + CheckWetherRoamingUser(shmp); + if(shmp->process_info.roamingFlag) + { + pps_print_event(shmp->process_info.logMsisdn,"%s is roaming,so charged by cgi",shmp->caller_info.number); + shmp->caller_info.location = + GetAccountZoneIDByLocationInfo(shmp->caller_info.location); + } + else + { + shmp->caller_info.location = + GetAccountZoneID(shmp->caller_info.head, + shmp->caller_info.tail); + } + } + else + { + shmp->caller_info.location = + GetAccountZoneID(shmp->caller_info.head, + shmp->caller_info.tail); + + } + } + + if(cosTableItem->friendFamilyControl[0].friendFamilyFlag) + shmp->process_info.favoriteCall = + CheckWetherFavoriteNumber(&shmp->caller_info,shmp->called_info.number); + if(serviceControlItem->poolAccountFlag) + { + if(getPoolAccountRole(portid) != MASTER_SLAVE_NONE) + shmp->process_info.poolCall = + CheckWetherPoolNumber(&shmp->caller_info,&shmp->called_info); + } + + if(serviceControlItem->closeUserGroupService) + if(shmp->caller_info.cug_id !=NOT_CUG_ACCOUNT && + (shmp->caller_info.cug_id == shmp->called_info.cug_id)) + shmp->process_info.cugCall = 1; + + if(shmp->context_info.callType == CT_MO_CALL) + { + shmp->process_info.routing_home_flag = + xap_roaming_rule_get_routing_home_flag(shmp->cdr_info.locationNumber); + } + + + break; //callType + default: //mt call + SetIndexMessAlamFlag(0); + if(shmp->called_info.head>=MSISDN_HEAD_NUM) + { + DebugMsg(debugmib.display.asciiOut, + "\33[31mCalled number <%s> is not Prepaid subs.\33[0m", + shmp->called_info.number); + + shmp->process_info.tcos = DESTINATION_OUT_OF_ORDER; + shmp->process_info.u_error = CAP_ERR_MISSING_CUSTOMER_RECORD; + shmp->process_info.oc = CAP_OC_InitialDP; + SendScfUError(portid); + //SendScfUAbort(portid); + //SendReleaseCall(portid); + shmp->process_info.tcend = 1; + + return (retval = S_RELEASE_ALL); + } + SetIndexMessAlamFlag(2); + + //CheckPromotionLatchFlag(&shmp->called_info); + + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->called_info.cos_id]; + serviceControlItem = &cosTableItem->serviceControl[0]; + + if(cosTableItem->friendFamilyControl[0].friendFamilyFlag) + shmp->process_info.favoriteCall = + CheckWetherFavoriteNumber(&shmp->called_info,shmp->caller_info.number); + + if(serviceControlItem->poolAccountFlag) + { + if(getPoolAccountRole(portid) != MASTER_SLAVE_NONE) + shmp->process_info.poolCall = + CheckWetherPoolNumber(&shmp->called_info,&shmp->caller_info); + } + + if(serviceControlItem->closeUserGroupService) + if(shmp->caller_info.cug_id !=NOT_CUG_ACCOUNT + && + (shmp->caller_info.cug_id == shmp->called_info.cug_id)) + shmp->process_info.cugCall = 1; + + shmp->called_info.location = + GetTariffLacInfo(shmp->cdr_info.cgi); + if(cosTableItem->tariff[0].chargeBy) + { + pps_print_event(shmp->process_info.logMsisdn,"%s charged by cgi",shmp->called_info.number); + if(shmp->called_info.location<0) + { + pps_print_error(shmp->process_info.logMsisdn,"%s isn't matched by cgi,so charged by cos",shmp->called_info.number); + shmp->called_info.location = + GetAccountMTZoneID(shmp->called_info.head, + shmp->called_info.tail); + } + else + { + CheckWetherRoamingMTUser(shmp); + shmp->called_info.location = + GetAccountMTZoneIDByLocationInfo(shmp->called_info.location); + } + } + else + { + pps_print_event(shmp->process_info.logMsisdn,"%s charged by cos",shmp->called_info.number); + if(shmp->called_info.location>=0) + { + CheckWetherRoamingMTUser(shmp); + if(shmp->process_info.roamingFlag) + { + pps_print_event(shmp->process_info.logMsisdn,"%s is roaming,so charged by cgi",shmp->called_info.number); + shmp->called_info.location = + GetAccountMTZoneIDByLocationInfo(shmp->called_info.location); + } + else + { + shmp->called_info.location = + GetAccountMTZoneID(shmp->called_info.head, + shmp->called_info.tail); + } + } + else + { + shmp->called_info.location = + GetAccountMTZoneID(shmp->called_info.head, + shmp->called_info.tail); + + } + } + break; + } + + + shmp->caller_info.charge = 0; + shmp->caller_info.fee = 0; + shmp->called_info.charge = 0; + shmp->called_info.fee = 0; + if(shmp->process_info.tcos != SRVICE_NOT_SUBSCRIBERED) /* this judgement is used for COS based service number */ + shmp->process_info.tcos = NORMAL_CLEARING; + //check called mnp status here + //mt call not implemented ,2006-03-20 + if(shmp->context_info.callType != CT_MT_CALL) + shmp->process_info.mnp_status = + IsMNPCalledNumber((char *)shmp->called_info.number); + + if(OCS_with_external_CRM())//query tariff from CRM database + { + if(shmp->context_info.callType != CT_MT_CALL) + { + pps_send_query_tariff_req(portid); + } + } + + if(shmp->process_info.mnp_status) + { + return S_SEND_MNP_ATI; + } + else + return S_CHECK_CALL_VALIDITY; + + break; + case CAP_OC_InitialDPSMS: + AddPPSStatistics(MIBPPS_INITIALDP_SMS,shmp->process_info.dir); + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + + } + #endif + if(!decode_initialDPSMS(shmp,portid,capArg)) + { + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\33[31m %s Send MO SMS failed, no route for %s\33[0m", + shmp->caller_info.number, + shmp->called_info.number); + } + #endif + SendReleaseSMS(portid); + retval = S_RELEASE_ALL; + return retval; + } + + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + shmp->cdr_info.releasetime = tvnow.tv_sec; + + SetCallType(shmp,CT_MO_SM); + + if(pps_get_adaptor_flag()) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut," Call type: <%s>", + callTypeName[shmp->process_info.serviceType]); + DebugMsg(debugmib.display.asciiOut," Caller : <%s>, Called : <%s>", + shmp->caller_info.number, shmp->called_info.number); + + } + + shmp->process_info.state = S_RO_ADAPTOR_SMS_INIT; + + return S_RO_ADAPTOR_SMS_INIT; + } + + SetIndexMessAlamFlag(0); + GetAccountPos(&shmp->caller_info); + if(shmp->caller_info.head>=MSISDN_HEAD_NUM) + { + if(shmp->process_info.serviceKey != 11)//service key=11 is used for postpaid + { + DebugMsg(debugmib.display.asciiOut, + "%s doesn't register Prepaid service, can't send SMS.", + shmp->caller_info.number); + SendReleaseSMS(portid); + return (retval = S_RELEASE_ALL); + } + } + + SetIndexMessAlamFlag(2); + + GetAccountPos(&shmp->called_info); + caller_status = GetAccountStatus(&shmp->caller_info); + called_status = GetAccountStatus(&shmp->called_info); + shmp->caller_info.status = caller_status; + shmp->called_info.status = called_status; + shmp->caller_info.cug_id = GetAccountCUG(&shmp->caller_info); + shmp->called_info.cug_id = GetAccountCUG(&shmp->called_info); + + if(shmp->caller_info.headcaller_info.cos_id = GetAccountCosID(&shmp->caller_info); + shmp->caller_info.cos_id = GetCosIDByAccount(&shmp->caller_info); + shmp->caller_info.cug_id = GetAccountCUG(&shmp->caller_info); + } + else + { + shmp->caller_info.cos_id = 0; + } + + shmp->process_info.serviceType = GetServiceType(shmp); + + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + serviceControlItem = &cosTableItem->serviceControl[0]; + + if(cosTableItem->friendFamilyControl[0].friendFamilyFlag) + shmp->process_info.favoriteCall = + CheckWetherFavoriteNumber(&shmp->caller_info,shmp->called_info.number); + + //CheckPromotionLatchFlag(&shmp->caller_info); + + #if DEBUG + if(strstr((char *)shmp->caller_info.number,logMsisdn)){ + shmp->process_info.logMsisdn = 0x01; + } + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"MO SMS"); + DebugMsg(debugmib.display.asciiOut, + "caller: %s caller pos: %d %d caller status: %d, cos: %d, balance:%.4f", + shmp->caller_info.number, + shmp->caller_info.head, + shmp->caller_info.tail, + caller_status, + shmp->caller_info.cos_id, + GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail)); + DebugMsg(debugmib.display.asciiOut, + "called: %s called pos: %d %d called status: %d", + shmp->called_info.number, + shmp->called_info.head, + shmp->called_info.tail, + called_status); + } + #endif + shmp->caller_info.charge = 0; + shmp->caller_info.fee = 0; + shmp->called_info.charge = 0; + shmp->called_info.fee = 0; + shmp->context_info.callType = CT_MO_SM; + shmp->process_info.tcos = NORMAL_CLEARING; + + if(shmp->process_info.serviceKey == 11 && shmp->caller_info.status == T_EXTERNAL) + { + return S_SMS_CHECK_VALIDITY; + } + + switch (caller_status) { + case T_NORMAL: + SetCallType(shmp,CT_MO_SM); + break; + case T_FRESH: + case T_SUSPEND: + if(shmp->process_info.serviceType == SRV_SCRATCH_CARD_RECHARGE || + shmp->process_info.serviceType == SRV_INQUIRY) + { + SetCallType(shmp,CT_MO_SM); + break; + } + default: + shmp->process_info.tcos = UNALLOCATED_NUMBER; + SendReleaseSMS(portid); + retval = S_RELEASE_ALL; + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x01) ){ + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Error status: %d Send SM failed!",caller_status); + } + #endif + return retval; + break; + } + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + shmp->caller_info.location = + GetTariffLacInfo(shmp->cdr_info.cgi); + if(cosTableItem->tariff[0].chargeBy) + { + pps_print_event(shmp->process_info.logMsisdn,"%s charged by cgi",shmp->caller_info.number); + if(shmp->caller_info.location<0) + { + pps_print_error(shmp->process_info.logMsisdn,"%s isn't matched by cgi,so charged by cos",shmp->caller_info.number); + shmp->caller_info.location = GetMOTariffIDWithFreeServiceControl(shmp->caller_info.head,shmp->caller_info.tail); + } + else + { + CheckWetherRoamingUser(shmp); + shmp->caller_info.location = + GetAccountZoneIDByLocationInfo(shmp->caller_info.location); + } + } + else + { + pps_print_event(shmp->process_info.logMsisdn,"%s charged by cos",shmp->caller_info.number); + if(shmp->caller_info.location>=0) + { + CheckWetherRoamingUser(shmp); + if(shmp->process_info.roamingFlag) + { + pps_print_event(shmp->process_info.logMsisdn,"%s is roaming,so charged by cgi",shmp->caller_info.number); + shmp->caller_info.location = + GetAccountZoneIDByLocationInfo(shmp->caller_info.location); + } + else + { + shmp->caller_info.location = GetMOTariffIDWithFreeServiceControl(shmp->caller_info.head,shmp->caller_info.tail); + } + } + else + { + shmp->caller_info.location = GetMOTariffIDWithFreeServiceControl(shmp->caller_info.head,shmp->caller_info.tail); + } + } + + //check mnp status here + shmp->process_info.mnp_status = + IsMNPCalledNumber((char *)shmp->called_info.number); + + if(OCS_with_external_CRM())//query tariff from CRM database + pps_send_query_tariff_req(portid); + + if(shmp->process_info.mnp_status) + { + return S_SEND_SMS_MNP_ATI; + } + else + return S_SMS_CHECK_VALIDITY; + break; + default: + /* + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x01) ){ + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "[%04d] Receive Error Message! (Waiting InitialDPx)", + portid); + } + if(logMsgFlag & 0x04 || logMsgFlag & 0x01){ + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + */ + retval = S_RELEASE_ALL; + break; + } + return retval; +} + +static int SendCallMNP_ATI(u_short portid) +{ + int retval = 0; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("SendMNP_ATI"); + + shmp += portid; + + shmp->process_info.mnp_status = 0; + SendMNP_ATI(portid); + shmp->process_info.funnel = 0; + + return (retval = S_WAIT_MNP_ATI_RES); + +} + +int SendMNP_ATI(u_short portid) +{ + int retval = 0; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("SendMNP_ATI"); + + shmp += portid; + + shmp->context_info.acn = AC_anyTimeInfoEnquiry; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[36m================== MNP call, MNP_ATI ===============\33[0m"); + } + pps_send_map_open(portid); + + pps_send_mnp_ati(portid); + + retval = 1; + return retval; +} + +static int WaitingForMNP_ATI_Res(u_short portid) +{ + int retval = 0 ; + int len = 0; + char data_flow[256]; + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + MapComSrv_struct com_data; + //MapOprData_struct opr_data; + MapOprSrv_struct opr_srv; + struct MapATI_Res *ati_res; + struct MnpInfoRes *mnpInfoRes; + + PutLogFunID("WaitingForMNP_ATI_Res"); + + shmp += portid; + if(shmp->process_info.funnel++>(SSHORT_DELAY_TIMER)) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait ATI_Res timeout\33[0m", + portid,shmp->context_info.map_did); + } + pps_send_map_close(portid); + return -1; + } + + if(map_get_oprdata((u8 *)data_flow,shmp->context_info.map_did)) + { + u_char msglen; + msglen = data_flow[0] * 256 + data_flow[1]; + if((data_flow[9] != AnyTimeInter) || msglen<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait ATI_Res but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + //pps_send_map_close(portid); + return -1; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, ATI response \33[0m", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + + //if(map_opr_ftos(&opr_srva,data_flow)<=0) + opr_srv.version = 3; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + (u8 *)&data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode ATI_Res failed \33[0m", + portid,shmp->context_info.map_did); + } + return -1; + } + + ati_res = &opr_srv.msg_list.ati_res; + + + if(ati_res->param_flag & 0x01) + { + if(ati_res->sub_info.param_flag & 0x80) + { + mnpInfoRes = &ati_res->sub_info.mnp_info_res; + + if(mnpInfoRes->param_flag & 0x04)/* msisdn */ + { + + } + /* check msisdn here */ + if(mnpInfoRes->param_flag & 0x08) + { + shmp->process_info.mnp_status = + mnpInfoRes->mnp_status; + /* + + typedef enum NumberPortabilityStatus + { + //notKnownToBePorted = 0, + //ownNumberPortedOut = 1, + //foreignNumberPortedToForeignNetwork = 2, + ownNumberNotPortedOut = 4, + foreignNumberPortedIn = 5 + }NumberPortabilityStatus; + */ + + if(shmp->process_info.mnp_status == 1 || + shmp->process_info.mnp_status == 2 || + shmp->process_info.mnp_status == 5) + { + + if(mnpInfoRes->param_flag & 0x01) + { + len = mnpInfoRes->routing_number[0]%(ISDN_LEN+1); + ppsBcdToAsciiR(shmp->process_info.routing_number, + &mnpInfoRes->routing_number[2], + (len-1)*2); + StringCut(shmp->process_info.routing_number,'F'); + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[p-did,%d.%d] ATI_Res:ported status: %d, RN=%s", + portid,shmp->context_info.map_did, + shmp->process_info.mnp_status, + shmp->process_info.routing_number); + } + } + else + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\33[31m %d.%d error ATI_Res (ported subs. but no RN)\33[0m", + portid,shmp->context_info.map_did); + } + shmp->process_info.mnp_status = 0; + return -1; + } + }//status + else + { + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "p-did: %d.%d ATI_Res received, subs. not ported", + portid,shmp->context_info.map_did); + } + shmp->process_info.mnp_status = 0; + } + }// has status + }//has mnp res info + else + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, ATI_Res received, but no mnp info. \33[0m", + portid,shmp->context_info.map_did); + } + //pps_send_map_close(portid); + return -1; + } + }//has parameter + else + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\33[31m portid: %d ,did: %d, ATI_Res, error <%d> \33[0m", + portid,shmp->context_info.map_did, + ati_res->user_error); + } + //pps_send_map_close(portid); + return -1; + } + retval = 1; + } + if(map_get_comdata_struct(&com_data,shmp->context_info.map_did)) + { + + if(com_data.message_type == MAP_OPEN) + { + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map Open Res. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + map_com_stof(&com_data, (u8 *)data_flow, 0); + pps_debug_map_msg(data_flow,0); + } + } + else + { + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map com, type: %d @ %ld.%ld", + portid,shmp->context_info.map_did, + com_data.message_type, + tvnow.tv_sec,tvnow.tv_usec); + map_com_stof(&com_data, (u8 *)data_flow, 0); + pps_debug_map_msg(data_flow,0); + } + retval = 1; + } + } + return retval; +} + +static int +CheckCallValidity(u_short portid) +{ + int retval,rst; + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("CheckCallValidity"); + + shmp += portid; + retval = shmp->process_info.state; + + if(OCS_with_external_CRM())//query tariff from CRM database + { + if(shmp->context_info.callType != CT_MT_CALL) + { + if((shmp->process_info.funnel ++ < SSHORT_DELAY_TIMER) && shmp->process_info.rest_if.query_tariff_status == 1)//5S + return retval; + } + BillingProc_crm(shmp, TRUE); + + } + else + BillingProc(shmp, TRUE); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut," \n============== number info =============="); + + if(shmp->context_info.callType == CT_MO_CALL) + { + DebugMsg(debugmib.display.asciiOut," Call type: MO call <%s>", + callTypeName[shmp->process_info.serviceType]); + } + else if(shmp->context_info.callType == CT_MF_CALL) + { + DebugMsg(debugmib.display.asciiOut," Call type: MF call <%s>", + callTypeName[shmp->process_info.serviceType]); + } + else + { + DebugMsg(debugmib.display.asciiOut," Call type: MT call"); + } + + + if(shmp->process_info.serviceKey==1) + { + DebugMsg(debugmib.display.asciiOut," ServiceKey = 1, charge on reported time"); + } + else + { + DebugMsg(debugmib.display.asciiOut," ServiceKey = %d, real time charge", + shmp->process_info.serviceKey); + } + + if(shmp->process_info.roamingFlag) + DebugMsg(debugmib.display.asciiOut," roaming call."); + DebugMsg(debugmib.display.asciiOut,"Caller valid_time: %d calltype: %d fee: %.04f", + shmp->caller_info.valid_time, + shmp->process_info.call_type, + shmp->caller_info.fee); + DebugMsg(debugmib.display.asciiOut,"Caller info : %s (%d %d) status:%d,cosid:%d,balance: %.04f", + shmp->caller_info.number, + shmp->caller_info.head, + shmp->caller_info.tail, + shmp->caller_info.status, + shmp->caller_info.cos_id, + GetBalance(&shmp->caller_info)); + DebugMsg(debugmib.display.asciiOut,"Called valid_time: %d calltype: %d fee: %.04f ", + shmp->called_info.valid_time, + shmp->process_info.call_type, + shmp->called_info.fee); + DebugMsg(debugmib.display.asciiOut,"Called info: %s (%d %d) status: %d,cosid:%d, balance: %.04f", + shmp->called_info.number, + shmp->called_info.head, + shmp->called_info.tail, + shmp->called_info.status, + shmp->called_info.cos_id, + GetBalance(&shmp->called_info)); + DebugMsg(debugmib.display.asciiOut, + "Vlr number: %s , CGI: %02X%02X%02X%02X%02X%02X%02X, tariff id:%d", + shmp->cdr_info.locationNumber, + shmp->cdr_info.cgi[0], + shmp->cdr_info.cgi[1], + shmp->cdr_info.cgi[2], + shmp->cdr_info.cgi[3], + shmp->cdr_info.cgi[4], + shmp->cdr_info.cgi[5], + shmp->cdr_info.cgi[6], + (shmp->context_info.callType == CT_MO_CALL) ? + shmp->caller_info.location : shmp->called_info.location + + ); + + DebugMsg(debugmib.display.asciiOut, + "Tariff :(%s) %s CT:%d DI:%d FreeTime:%d unit_time:%d Miniunit:%d Adj:%.04f ,CapFlag%d, Discount: %d", + shmp->charge_info.number, + shmp->process_info.tariff.bill_id, + shmp->process_info.tariff.call_type, + shmp->process_info.tariff.discountID, + shmp->process_info.tariff.free_time, + shmp->process_info.tariff.unit_time, + shmp->process_info.tariff.mini_unit, + shmp->process_info.tariff.adjustment, + shmp->process_info.tariff.cap_flag, + GetDiscount(tvnow.tv_sec,shmp->process_info.tariff.discountID)); + DebugMsg(debugmib.display.asciiOut, + "tierInfo:L-%d,A-(units:%d,bf:%.04f,lf:%.04f),B-(units:%d,bf:%.04f,lf:%.04f),C-(units:%d,bf:%.04f,lf:%.04f)", + shmp->process_info.tariff.tierRating.tierNumber, + shmp->process_info.tariff.tierRating.rating[0].units, + shmp->process_info.tariff.tierRating.rating[0].base_fee, + shmp->process_info.tariff.tierRating.rating[0].long_distance_fee, + shmp->process_info.tariff.tierRating.rating[1].units, + shmp->process_info.tariff.tierRating.rating[1].base_fee, + shmp->process_info.tariff.tierRating.rating[1].long_distance_fee, + shmp->process_info.tariff.tierRating.rating[2].units, + shmp->process_info.tariff.tierRating.rating[2].base_fee, + shmp->process_info.tariff.tierRating.rating[2].long_distance_fee); + } +#endif + shmp->process_info.playAnnouncement = 0; + shmp->process_info.promptAndCollectUserInfo = 0; + if (!IsEnableToCall(portid) ) + { + /* no voice for CAP V1 */ + if(shmp->context_info.acn_ver<1) + { + shmp->process_info.tcos = SERVICE_NOT_AVAILABLE; + SendReleaseCall(portid); + return (retval= S_RELEASE_ALL); + + } + + if(shmp->process_info.serviceKey == 1) + { + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 0; + SendReleaseCall(portid); + return (retval= S_RELEASE_ALL); + } + + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL && + shmp->process_info.callConnected == 1 && + !ppsParam.serviceControl.vms_allways_go) + { + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 0; + shmp->process_info.promptAndCollectUserInfo = 0; + if(shmp->caller_info.status == T_EXTERNAL) + { + return (retval = S_SEND_CONTINUE); + } + return (retval = S_REQUEST_EVENTS); + } + /* edit for mt voice , 2005-11-30 */ + + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 1; + + if(OCS_with_external_CRM())//SUSPENDED FOR EXPIRED CAN RECEIVE CALL + { + if(shmp->process_info.tcos == CALLED_EXPIRIED) + { + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 0; + } + } + else + { + if(pps_mt_play_voice_flag() == 0) + { + if(shmp->context_info.callType != CT_MO_CALL) + { + //shmp->process_info.tcos = SERVICE_NOT_AVAILABLE; + SendReleaseCall(portid); + return (retval= S_RELEASE_ALL); + } + } + } + + } + if(shmp->process_info.serviceKey == 1) + { + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 0; + } + /* for vms service */ + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL && + shmp->process_info.callConnected == 1) + { + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 0; + shmp->process_info.promptAndCollectUserInfo = 0; + if(shmp->caller_info.status == T_EXTERNAL) + { + return (retval = S_SEND_CONTINUE); + } + } + /* added by Pierre, 2006-05-15 for tcap id */ + if(shmp->context_info.callType == CT_MT_CALL && + shmp->called_info.headcontext_info.callType == CT_MO_CALL && + shmp->caller_info.headprocess_info.serviceType == SRV_NORMAL_MO_CALL && + getCurrentFee(shmp) == 0 && + ppsParam.serviceControl.mo_release_for_no_charge&& + shmp->process_info.tariff_flag) + { + SendContinue(portid); + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + + rst = isPoolChildReachCallLimit(shmp); + if(rst) + { + switch(rst) + { + case 1: + shmp->process_info.tcos= CALLER_REACH_CALL_LIMIT; + shmp->process_info.voiceID = CHILD_REACH_CALL_LIMIT; + break; + case 2: + shmp->process_info.tcos= CALLER_REACH_CHARGE_LIMIT; + shmp->process_info.voiceID = CHILD_REACH_CHARGE_LIMIT; + break; + } + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 1; + } + retval = S_REQUEST_EVENTS; + return retval; +} + +static int +ApplyCharging(u_short portid) +{ + int retval; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("ApplyCharging"); + + shmp += portid; + retval = shmp->process_info.state; + + if(shmp->process_info.roamingFlag) + { + if(shmp->process_info.funnel ++ < + ppsParam.serviceControl.delay_timer_for_roaming) + return retval; + } + + SendApplyCharging(portid); + + + if( shmp->process_info.serviceType != SRV_CRD && + shmp->process_info.serviceType != SRV_DIRECT_ACCESS && + shmp->process_info.serviceType != SRV_RESERVED_FUN && + shmp->process_info.serviceType != SRV_OTHER_VMS_MAITENANCE && + shmp->process_info.serviceType != SRV_VMS_DEPOSIT) + { + retval = S_SEND_CONTINUE; + } + else + { + shmp->process_info.promptAndCollectUserInfo = 1; + retval = S_REQUEST_EVENTS; + } + shmp->process_info.funnel = 0; + + + return retval; +} + +int +ReleaseContinue(u_short portid) +{ + int retval; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("ReleaseContinue"); + + shmp += portid; + retval = shmp->process_info.state; + + if(shmp->process_info.roamingFlag) + { + if(shmp->process_info.funnel ++ < + ppsParam.serviceControl.delay_timer_for_roaming) + return retval; + } + shmp->process_info.funnel = 0; + shmp->process_info.down = 0; + + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL && + shmp->process_info.callConnected == 1) /* added on 04-12-16, + for VoiceBox maintenance & Call forward to VMS need not to connect SRF */ + { + if(!GetCRDDestination((char *)shmp->caller_info.number, + shmp->process_info.tmpDigits, + SRV_CRD-SRV_CRD)) + { + return (retval = S_SEND_RELEASE_CALL); + } + if(logMsgFlag & 0x01 || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"VMS conv: %s -> %s", + shmp->caller_info.number, shmp->process_info.tmpDigits); + } + + SendConnectForVMSService(portid); + if(shmp->caller_info.status == T_EXTERNAL) + { + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + } + else if(shmp->process_info.serviceType == SRV_CALLINGCARD_MANAGE) + {/*calling card */ + if(logMsgFlag & 0x01 || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"Calling Card conv: %s -> %s", + shmp->caller_info.number, shmp->process_info.tmpDigits); + } + SendConnectForVMSService(portid); + retval = S_WAITINGFOR_ANSWERED; + } + else if(shmp->process_info.routing_home_flag == 1) + { + if(logMsgFlag & 0x01 || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"[%04d] %s, routing home =%d", + portid, __FUNCTION__, shmp->process_info.routing_home_flag); + } + + SendConnectForVMSService(portid); + } + else + { + SendContinue(portid); + } + + shmp->process_info.sub_state = 0; + + if(shmp->process_info.answerWanted) + { + retval = S_WAITINGFOR_ANSWERED; + } + else + { + retval = S_WAITINGFOR_EVENTS; + } + return retval; +} + +int +RequestBCSMEvent(u_short portid) +{ + int retval; + _state_data *shmp; + + PutLogFunID("RequestBCSMEvent"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + //SendApplyCharging(portid); + //retval = ReleaseContinue(portid); + + if(shmp->process_info.playAnnouncement || + shmp->process_info.promptAndCollectUserInfo || + shmp->process_info.pre_warning) + { + if( shmp->process_info.serviceType == SRV_CRD || + shmp->process_info.serviceType == SRV_DIRECT_ACCESS || + shmp->process_info.serviceType == SRV_RESERVED_FUN || + shmp->process_info.serviceType == SRV_OTHER_VMS_MAITENANCE || + shmp->process_info.serviceType == SRV_VMS_DEPOSIT) + { + if(shmp->caller_info.head>=MSISDN_HEAD_NUM) + SendPreWarningRequestBCSMEvent(portid); + } + else + SendPreWarningRequestBCSMEvent(portid); + retval = S_ESTABLISH_TEMPORARY_CONNECTION; + } + else + { + /* + if(shmp->caller_info.head>=MSISDN_HEAD_NUM && + ppsParam.serviceControl.vms_allways_go + ) + { + SendPreWarningRequestBCSMEvent(portid); + retval = S_ESTABLISH_TEMPORARY_CONNECTION; + return retval; + } + */ + SendRequestBCSMEvent(portid); + if(shmp->context_info.acn_ver>=1) /* CAP V2 and above */ + retval = S_APPLY_CHARGING; + else + retval = S_SEND_CONTINUE; + } + return retval; +} + + +int +WaitingforAnsweredProc(u_short portid) +{ + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + DWORD instance = 0; + int retval, release_flag = 0x00,tcend_flag=0; + int dlgid,msglen,edpr, valid_time=0; + CAP_Message capmsg; + struct CapArg capArg; + CHARGED_FEE chargedFee; + char error[32]; + + PutLogFunID("WaitingforAnsweredProc"); + + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + + retval = shmp->process_info.state; + if (shmp->process_info.funnel >= pps_get_answer_timer_out()) //WAITINGFOR_ANSWERED_DELAY ) + { + shmp->process_info.tcos = NO_ANSWER; + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x01 || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"P/DID: Wait for answer timeout!" + ,portid,dlgid); + } + + SendReleaseCall(portid); + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + { + retval = S_RELEASE_ALL; + } + + return retval; + } + + shmp->process_info.funnel ++; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + + if(capmsg.msgOperaCode != CAP_OC_EventReportBCSM) + { + if(capmsg.msgOperaCode != CAP_OC_ApplyChargingReport) + { + shmp->process_info.tcos = NETWORK_OUT_OF_ORDER; +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x04 || logMsgFlag & 0x01 || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Warning: pid=%d did=%d '%s' received (Waiting for ANSWER)", + portid,dlgid,GetCapError(error,capmsg.msgOperaCode)); + ppsDebugCapMsg(&capmsg,0); + } +#endif + + SendReleaseCall(portid); + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + { +// SendReleaseCall(portid); + retval = S_RELEASE_ALL; + } + +// SendReleaseCall(portid); +// retval = S_RELEASE_ALL; + return retval; + } + else + { + AddPPSStatistics(MIBPPS_CHARGINGREPORT,shmp->process_info.dir); + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES){ + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"[%04d] EventReportBCSM Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + if((logMsgFlag & 0x02 )|| shmp->process_info.logMsisdn ) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + } + #endif + return retval; + } + } +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"portid=%d, dlgid=%d EventReportBCSM Received! (%ld.%ld)", + portid,shmp->context_info.dialogue_id,tvnow.tv_sec,tvnow.tv_usec); + } + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn ) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + + capArg.version = shmp->context_info.acn_ver; + + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + return retval; + edpr = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM; + switch(edpr) + { + case capp_routeSelectFailure: + release_flag = 0x01; + //tcend_flag = 0x01; + shmp->process_info.tcos = NO_ROUTE; + break; + case capp_oCalledPartyBusy: + case capp_tBusy: + release_flag = 0x01; + shmp->process_info.tcos = USER_BUSY; + break; + case capp_oNoAnswer: + case capp_tNoAnswer: + release_flag = 0x01; + shmp->process_info.tcos = NO_ANSWER; + break; + case capp_oAbandon: + case capp_tAbandon: + release_flag = 0x01; + //tcend_flag = 0x01; + shmp->process_info.tcos = CALL_REJECTED; + break; + case capp_oAnswer: + case capp_tAnswer: + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"portid=%d EventReportBCSM (Answered)!",portid); + } + #endif + + shmp->cdr_info.answertime = tvnow.tv_sec; + shmp->process_info.duration = 0; + shmp->process_info.down = 0; + shmp->process_info.funnel = 0; + + AddPPSStatistics(MIBPPS_ANSWERED,shmp->process_info.dir); + retval = S_WAITINGFOR_EVENTS; + + if(shmp->process_info.ro_if.adaptor_enabled) + { + shmp->process_info.ro_if.recv_cmd = 1; + shmp->process_info.ro_if.result = 1; + return retval; + } + + if(shmp->process_info.serviceKey != 1) + { + shmp->caller_info.charge += shmp->caller_info.fee; + shmp->called_info.charge += shmp->called_info.fee; + + if(shmp->context_info.callType == CT_MT_CALL \ + && (shmp->called_info.fee !=0 \ + || shmp->process_info.bundle_flag)) + { + UpdateBalance(shmp,&shmp->called_info, -(shmp->called_info.fee),&chargedFee); + instance = shmp->called_info.head * UNIT_STORE_ACCOUNT + + shmp->called_info.tail; + if(shmp->process_info.cap_flag) + { + UpdateSubsCapInfo( + &shmp->called_info, + 0, + (shmp->called_info.fee), + shmp->called_info.valid_time/CYCLE_STATE_INTERVAL, + shmp); + } + if(shmp->process_info.bundle_flag) + { + int valid_time = shmp->called_info.valid_time/CYCLE_STATE_INTERVAL; + //DebugMsg(debugmib.display.asciiOut, "WaitingforAnsweredProc()->%s update bundle mt valid time[%d]", + // shmp->called_info.number, -valid_time); + pps_update_account_bundle_mt_voice(shmp, -valid_time); + } + + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + } + else if(shmp->caller_info.status != T_EXTERNAL \ + && (shmp->caller_info.fee != 0 \ + || shmp->process_info.bundle_flag)) + { + UpdateBalance(shmp,&shmp->caller_info, -(shmp->caller_info.fee),&chargedFee); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + if(shmp->process_info.cap_flag) + { + UpdateSubsCapInfo( + &shmp->caller_info, + 0, + (shmp->caller_info.fee), + shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL, + shmp); + } + if(shmp->process_info.bundle_flag) + { + valid_time = shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL; + pps_update_account_bundle_mo_voice(shmp, -valid_time); + } + + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + } + + if((shmp->process_info.rest_if.total_plan_value>0) + && (shmp->caller_info.free_flag == 0)) + { + valid_time = shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL; + shmp->process_info.rest_if.used_plan_value += valid_time; + // + shmp->process_info.rest_if.plan_value_add_this_time = valid_time; + pps_send_update_plan_value_req(portid); + } + if (shmp->caller_info.free_flag == 1) + { + shmp->caller_info.free_flag = 0; + } + } + break; + case capp_oDisconnect: + case capp_tDisconnect: + //if(capArg.msg_list.eventReportBCSMArg.legID == 0x01) //calling party + // tcend_flag = 0x01; + release_flag = 0x01; + shmp->process_info.tcos = edpr; + break; + default: + release_flag = 0x01; + shmp->process_info.tcos = NETWORK_OUT_OF_ORDER; + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x04 || logMsgFlag & 0x01 ) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Warning: pid=%d did=%d Error Message %d,edpr:%d (Waiting for ANSWER)", + dlgid,shmp->context_info.dialogue_id,capmsg.msgOperaCode,edpr); + ppsDebugCapMsg(&capmsg,0); + } + #endif + break; + }/* switch */ + + if(release_flag) + { + if(tcend_flag) + { + SendScfTcEND(portid); + retval = S_RELEASE_ALL; + } + else + { + SendReleaseCall(portid); + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + { + retval = S_RELEASE_ALL; + } + } + return retval; + } + + return retval; +} + +void ChargeAccountByRealCallDuration(u_short portid) +{ + _account_info *account_ptr; + int instance; + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + CHARGED_FEE chargedFee; + + PutLogFunID("ChargeAccountByRealCallDuration"); + + shmp += portid; + + switch(shmp->context_info.callType) + { + case CT_MT_CALL: + account_ptr = &shmp->called_info; + break; + default: + account_ptr = &shmp->caller_info; + break; + } + + if(shmp->process_info.realCallDuration != 0) + { + shmp->process_info.realCallDuration /= 10; /* in 100ms intervals */ + account_ptr->charge = ChargeGprsAccountBalance(shmp,shmp->process_info.realCallDuration); + + shmp->cdr_info.releasetime = shmp->cdr_info.answertime + + shmp->process_info.realCallDuration; + shmp->process_info.duration = + (shmp->process_info.realCallDuration * CYCLE_STATE_INTERVAL); + } + else + { + account_ptr->charge = ChargeGprsAccountBalance(shmp,shmp->process_info.duration/CYCLE_STATE_INTERVAL); + + shmp->cdr_info.releasetime = shmp->cdr_info.answertime + + shmp->process_info.duration/CYCLE_STATE_INTERVAL; + } + UpdateBalance(shmp,account_ptr,-(account_ptr->charge),&chargedFee); + instance = account_ptr->head * UNIT_STORE_ACCOUNT + + account_ptr->tail; + SendCDR(portid); + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); +} + +int +WaitingForEventsReport(u_short portid) +{ + int retval, release_flag = 0x00,tcend_flag=0x00, valid_time=0; + int dlgid,msglen, instance = 0,edpr,update_flag=0; + CAP_Message capmsg; + struct CapArg capArg; + CHARGED_FEE chargedFee; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("WaitingForEventsReport"); + + shmp += portid; + retval = shmp->process_info.state; + + + dlgid = shmp->context_info.dialogue_id; + + if (shmp->process_info.funnel >= ACTIVITY_TEST_DELAY ) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn ) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"portid=%d ActivityTest missed! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } +#endif + shmp->process_info.tcos = ACTIVITY_MISSED; + shmp->cdr_info.releasetime = tvnow.tv_sec; + + if(shmp->process_info.serviceKey == 1) + { + ChargeAccountByRealCallDuration(portid); + } + else + { + if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL){ + IncreaseFriendFamilyFreeCallDuration(shmp->caller_info.head, + shmp->caller_info.tail, + shmp->process_info.duration); + } + SendCDR(portid); + } + + SendReleaseCall(portid); + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + retval = S_RELEASE_ALL; + + return (retval); + } + + if(ReadScfMsg(&capmsg,dlgid)) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + if(capmsg.msgOperaCode == CAP_OC_ActivityTest ) + { + if(capmsg.msgContent[2] != 0x03) + { + shmp->process_info.funnel = 0; + AddPPSStatistics(MIBPPS_ACTIVITYR,shmp->process_info.dir); + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d ActivityTest Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + } + } + else if(capmsg.msgOperaCode == 251) //notice + { + shmp->process_info.funnel = 0; + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d Notice Received while waiting for ACT! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + } + else if(capmsg.msgOperaCode == CAP_OC_ApplyChargingReport + /* charging report */ + || capmsg.msgOperaCode == CAP_OC_EventReportBCSM) + /* bcsm event report */ + { + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d Decode failed OC=%d", + portid,capmsg.msgOperaCode); + } + #endif + return retval; + } + + if(capmsg.msgOperaCode == CAP_OC_ApplyChargingReport) + { + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d ApplyChargingReport Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + /* charging time control */ + if(capArg.msg_list.applyChargingReportArg.callActive) + { + if( shmp->process_info.ro_if.adaptor_enabled == 1) + { + if(shmp->process_info.ro_if.granted_value>0) + SendApplyCharging(portid); + } + else + SendApplyCharging(portid); + + } + if(shmp->process_info.serviceKey ==1) + { + shmp->process_info.realCallDuration += + capArg.msg_list.applyChargingReportArg.timeInformation.timeIfNoTariffSwitch; + } + + AddPPSStatistics(MIBPPS_CHARGINGREPORT,shmp->process_info.dir); + } + + if(capmsg.msgOperaCode == CAP_OC_EventReportBCSM) + { + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d EventReportBCSM Received (disconnect)! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + + edpr = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM; + switch(edpr) + { + /* + case capp_routeSelectFailure: + release_flag = 0x01; + tcend_flag = 0x01; + shmp->process_info.tcos = NO_ROUTE; + break; + case capp_oCalledPartyBusy: + case capp_tBusy: + release_flag = 0x01; + shmp->process_info.tcos = USER_BUSY; + break; + case capp_oNoAnswer: + case capp_tNoAnswer: + release_flag = 0x01; + shmp->process_info.tcos = NO_ANSWER; + break; + case capp_oAbandon: + case capp_tAbandon: + release_flag = 0x01; + shmp->process_info.tcos = CALL_REJECTED; + break; + */ + case capp_oDisconnect: + case capp_tDisconnect: + default: + //if(capArg.msg_list.eventReportBCSMArg.legID == 0x01) + // tcend_flag = 0x01; + release_flag = 0x01; + shmp->process_info.tcos = edpr; + AddPPSStatistics(MIBPPS_DISCONNECT,shmp->process_info.dir); + shmp->cdr_info.releasetime = tvnow.tv_sec; + break; + }/* switch */ + + if(release_flag) + { + if(tcend_flag) + SendScfTcEND(portid); + else + SendReleaseCall(portid); + shmp->cdr_info.releasetime = tvnow.tv_sec; + + if(shmp->process_info.serviceKey == 1) + { + ChargeAccountByRealCallDuration(portid); + } + else + { + if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL) + IncreaseFriendFamilyFreeCallDuration(shmp->caller_info.head, + shmp->caller_info.tail, + shmp->process_info.duration); + SendCDR(portid); + } + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + } + else + retval = S_RELEASE_ALL; + return retval; + } + } + } + else + { + shmp->process_info.tcos = INVALID_MESSAGE; + shmp->cdr_info.releasetime = tvnow.tv_sec; + if(shmp->process_info.serviceKey == 1) + { + ChargeAccountByRealCallDuration(portid); + } + else + { + if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL) + IncreaseFriendFamilyFreeCallDuration(shmp->caller_info.head, + shmp->caller_info.tail, + shmp->process_info.duration); + SendCDR(portid); + } + + SendReleaseCall(portid); + if(shmp->process_info.ro_if.adaptor_enabled == 1) + retval = S_RO_CALL_TERMIATED; + else + retval = S_RELEASE_ALL; + + return retval; + } + }/* ReadScfMsg */ + + + if(OCS_with_external_CRM())//query tariff from CRM database + { + if(shmp->caller_info.valid_time == CYCLE_STATE_INTERVAL) + { + pps_send_query_tariff_req(portid); + } + } + + if(shmp->process_info.serviceKey != 1 && shmp->process_info.ro_if.adaptor_enabled == 0) + { + + if (shmp->caller_info.valid_time <= 0 /* Acquire next call period */ + || shmp->called_info.valid_time <= 0) + { + if(OCS_with_external_CRM())//query tariff from CRM database + BillingProc_crm(shmp, FALSE); + else + BillingProc(shmp, FALSE); + #if DEBUG1 + DebugMsg(debugmib.display.asciiOut,"Charge fee: caller=%f, called=%f", + shmp->caller_info.fee,shmp->called_info.fee); + #endif + shmp->caller_info.charge += shmp->caller_info.fee; + shmp->called_info.charge += shmp->called_info.fee; + if((shmp->context_info.callType == CT_MT_CALL)) + { + if((shmp->called_info.fee != 0 )) + { + UpdateBalance(shmp,&shmp->called_info, -(shmp->called_info.fee),&chargedFee); + update_flag = 1; + } + if(shmp->process_info.cap_flag) + { + UpdateSubsCapInfo( + &shmp->called_info, + 0, + (shmp->called_info.fee), + shmp->called_info.valid_time/CYCLE_STATE_INTERVAL, + shmp); + update_flag = 1; + } + if(shmp->process_info.bundle_flag) + { + int valid_time = shmp->called_info.valid_time/CYCLE_STATE_INTERVAL; + //DebugMsg(debugmib.display.asciiOut, "WaitingForEventsReport()->%s update bundle mt valid time[%d]", + // shmp->called_info.number, -valid_time); + pps_update_account_bundle_mt_voice(shmp, -valid_time); + update_flag = 1; + } + + + if(update_flag) + { + instance = shmp->called_info.head * UNIT_STORE_ACCOUNT + + shmp->called_info.tail; + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + } + }else if((shmp->caller_info.status != T_EXTERNAL) ) + { + if((shmp->caller_info.fee != 0)) + { + UpdateBalance(shmp,&shmp->caller_info, -(shmp->caller_info.fee),&chargedFee); + update_flag = 1; + } + if(shmp->process_info.cap_flag) + { + UpdateSubsCapInfo( + &shmp->caller_info, + 0, + (shmp->caller_info.fee), + shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL, + shmp); + update_flag = 1; + } + if(shmp->process_info.bundle_flag) + { + valid_time = shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL; + //DebugMsg(debugmib.display.asciiOut, "WaitingForEventsReport()->%s update bundle mo valid time[%d]", + // shmp->caller_info.number, -valid_time); + pps_update_account_bundle_mo_voice(shmp, -valid_time); + update_flag = 1; + } + + if(update_flag) + { + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + } + + if(shmp->process_info.rest_if.total_plan_value>0 && shmp->process_info.rest_if.used_plan_value < shmp->process_info.rest_if.total_plan_value) + { + valid_time = shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL; + shmp->process_info.rest_if.used_plan_value += valid_time; + shmp->process_info.rest_if.plan_value_add_this_time = valid_time; + pps_send_update_plan_value_req(portid); + } + + } + } + + if (shmp->caller_info.valid_time <= 0 + || shmp->called_info.valid_time <= 0) + { + shmp->cdr_info.releasetime = tvnow.tv_sec; + if(shmp->process_info.tcos != CALLER_REACH_CHARGE_LIMIT) + { + if(shmp->context_info.callType == CT_MT_CALL){ + shmp->process_info.tcos = CALLED_CREDIT_OUT; + /* + SendAccountInfoForLowCredit(shmp->called_info.number, + (int)GetBalance(&shmp->called_info), + GetExpiration(&shmp->called_info)); + */ + }else{ + shmp->process_info.tcos = CALLER_CREDIT_OUT; + /* + SendAccountInfoForLowCredit(shmp->caller_info.number, + (int)GetBalance(&shmp->caller_info), + GetExpiration(&shmp->caller_info)); + */ + } + } + + if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL) + IncreaseFriendFamilyFreeCallDuration(shmp->caller_info.head, + shmp->caller_info.tail, + shmp->process_info.duration); + + SendCDR(portid); + SendReleaseCall(portid); + + return (retval = S_RELEASE_ALL); + } + + shmp->caller_info.valid_time --; + shmp->called_info.valid_time --; + + } + + if(shmp->process_info.ro_if.adaptor_enabled == 1) + { + shmp->caller_info.valid_time --; + shmp->called_info.valid_time --; + + if(shmp->process_info.ro_if.is_final == 0 && + shmp->process_info.ro_if.no_more_ccr != 1) + { + if(shmp->caller_info.valid_time < 3* CYCLE_STATE_INTERVAL || + shmp->process_info.sub_state>0) + { + int ccr_result = 0; + switch(shmp->process_info.sub_state) + { + case 0: + shmp->process_info.ro_if.request_type = RT_UPDATE_REQUEST; + pps_ro_adaptor_call_init(portid); + shmp->process_info.sub_state = 1; + break; + case 1: + ccr_result = pps_ro_call_wait_first_cca(portid); + + if(shmp->process_info.ro_if.recv_cmd == 1) + shmp->process_info.sub_state = 0; + if(ccr_result == -1) + { + shmp->process_info.ro_if.no_more_ccr = 1; + shmp->process_info.sub_state = 0; + /* + SendCDR(portid); + SendReleaseCall(portid); + if(shmp->process_info.ro_if.adaptor_enabled == 1) + retval = S_RO_CALL_TERMIATED; + else + retval = S_RELEASE_ALL; + return retval; + */ + } + break; + case 2: + shmp->process_info.sub_state = 0; + break; + } + } + } + + if(shmp->caller_info.valid_time<=0) + { + SendCDR(portid); + SendReleaseCall(portid); + shmp->process_info.sub_state = 0; + retval = S_RO_CALL_TERMIATED; + + if((logMsgFlag & 0x04) || + (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "portid=%d quota used up, release call! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + + /* + if(shmp->process_info.ro_if.adaptor_enabled == 1) + retval = S_RO_CALL_TERMIATED; + else + retval = S_RELEASE_ALL; + */ + return retval; + } + + } + + shmp->process_info.down ++ ; + if(shmp->process_info.down >=send_activitytest_timer) //SEND_ACTIVITYTEST_PERIODIC) + { + shmp->process_info.down = 0; + SendActivityTest(portid); + } + shmp->process_info.funnel ++; + + shmp->process_info.duration ++; + if(shmp->process_info.duration>ppsParam.max_call_duration*50) + { + if(shmp->process_info.send_warning_sms_flag == 0) + { + char warning_message[256]; + + shmp->process_info.send_warning_sms_flag = 1; + + sprintf(warning_message, "call duration exceed MAX call duration %d minutes, caller=%s, called=%s, port id=%d", + ppsParam.max_call_duration, shmp->caller_info.number, shmp->called_info.number, portid); + + sendPPSTestShortMessage(warning_message); + } + } + return retval; +} + +void SetActivityTestTimer(char timer) +{ + send_activitytest_timer = timer * 20 ; +} +/* ------------------------------ */ +static int SendSMSMNP_ATI(u_short portid) +{ + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + shmp += portid; + + shmp->process_info.mnp_status = 0; + SendMNP_ATI(portid); + shmp->process_info.funnel = 0; + + return S_SMS_WAIT_MNP_ATI_RES; + +} + +static int WaitingForSMSMNP_ATI_Res(u_short portid) +{ + return WaitingForMNP_ATI_Res(portid); +} + +static int +CheckSMSValidity(u_short portid) +{ + int retval ; + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("CheckSMSValidity"); + + shmp += portid; + retval = shmp->process_info.state; + + + if(OCS_with_external_CRM())//query tariff from CRM database + { + if(shmp->process_info.rest_if.query_tariff_status < 2) + { + if(shmp->process_info.funnel ++ > SSHORT_DELAY_TIMER) + { + goto CHECK_SMS_TARIFF_NOT_SET; + } + else + return (retval = S_SMS_CHECK_VALIDITY); + } + else + { + if(shmp->process_info.rest_if.query_tariff_status == 3) + goto CHECK_SMS_TARIFF_NOT_SET; + } + + } + + BillingSMSProc(shmp, 1); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "tariff id: %d, charged prefix: %s ", + shmp->caller_info.location,shmp->charge_info.number); + } + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) + { + DebugMsg(debugmib.display.asciiOut, + "cap SM flag: %d",shmp->process_info.cap_flag); + } + + if (IsEnableToCall(portid) ) + { + retval = S_REQUEST_SMS_EVENTS; + } + else + { + if(shmp->process_info.serviceKey == 11) + { + if(shmp->caller_info.status == T_EXTERNAL) + { + retval = S_REQUEST_SMS_EVENTS; + return retval; + } + } + + SendReleaseSMS(portid); + retval = S_RELEASE_ALL; + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x01) ) + { + DebugMsgDelimiter(); + switch(shmp->process_info.tcos) + { + case CALLER_EXPIRIED: + DebugMsg(debugmib.display.asciiOut, + "\33[31mCaller is expired , Send SM failed!\33[0m"); + break; + case CALLER_CREDIT_OUT: + DebugMsg(debugmib.display.asciiOut, + "\33[31mCaller is out of balance , Send SM failed!\33[0m"); + break; + case CALLER_REACH_SMS_LIMIT: + DebugMsg(debugmib.display.asciiOut, + "\33[31mCaller is a child,reaching Max SMS limit today, Send SM failed!\33[0m"); + break; + case CALLER_REACH_CHARGE_LIMIT: + DebugMsg(debugmib.display.asciiOut, + "\33[31mCaller is a child,reaching Max fee charge limit today, Send SM failed!\33[0m"); + break; + } + } + #endif + } + + return retval; + +CHECK_SMS_TARIFF_NOT_SET: + shmp->process_info.tcos = TARIFF_NOT_SET; + SendReleaseSMS(portid); + + return (retval = S_RELEASE_ALL); + +} + +static int +RequestSMSEvents(u_short portid) +{ + int retval; + + PutLogFunID("RequestSMSEvents"); + + SendRequestSMSEvents(portid); + + //SendContinueSMS(portid); + + //retval = S_WAITINGFOR_SMS_EVENTS; + retval = S_RELEASE_SMS_CONTINUE; + return retval; +} + +int ReleaseContinueSMS(u_short portid) +{ + int retval; + +// SendRequestSMSEvents(portid); + PutLogFunID("ReleaseContinueSMS"); + + SendContinueSMS(portid); + + retval = S_WAITINGFOR_SMS_EVENTS; + return retval; + +} + +static int +WaitingForSMSEvents(u_short portid) +{ + int retval,release_flag = 0x00; + int dlgid,msglen, instance = 0; + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + CAP_Message capmsg; + struct CapArg capArg; + CHARGED_FEE chargedFee; + + PutLogFunID("WaitingForSMSEvents"); + + shmp += portid; + retval = shmp->process_info.state; + + + dlgid = shmp->context_info.dialogue_id; + + if (shmp->process_info.funnel >= ACTIVITY_TEST_DELAY ) + { + shmp->process_info.tcos = ACTIVITY_MISSED; + SendReleaseSMS(portid); + return (retval = S_RELEASE_ALL); + } + + if(ReadScfMsg(&capmsg,dlgid)) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x02) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + if(capmsg.msgOperaCode == CAP_OC_ActivityTest ) + { + if(capmsg.msgContent[2] != 0x03) + { + shmp->process_info.funnel = 0; + AddPPSStatistics(MIBPPS_ACTIVITYR,shmp->process_info.dir); + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"[%04d] ActivityTest Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } + #endif + } + } + else if(capmsg.msgOperaCode == CAP_OC_EventReportSMS) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"[%04d] EventReportSMS Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } +#endif + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + retval = S_RELEASE_ALL; + return retval; + } + + switch(capArg.msg_list.eventReportSMSArg.eventTypeSMS) + { + case capp_osmsFailure: + release_flag = 0x01; + shmp->process_info.tcos = NO_ROUTE; + if(shmp->process_info.ro_if.adaptor_enabled ) + { + retval = S_RO_SMS_REFUND; + return retval; + } + break; + case capp_osmsSubmitted: + release_flag = 0x01; + shmp->process_info.tcos = NORMAL_CLEARING; + AddPPSStatistics(MIBPPS_REPORT_SMS,shmp->process_info.dir); + shmp->cdr_info.answertime = tvnow.tv_sec; + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.releasetime = tvnow.tv_sec; + + if(shmp->process_info.ro_if.adaptor_enabled == 0) + { + if(shmp->caller_info.head>=MSISDN_HEAD_NUM) + { + SendCDR(portid); + SendReleaseSMS(portid); + retval = S_RELEASE_ALL; + return retval; + } + + UpdateBalance(shmp,&shmp->caller_info, -(shmp->caller_info.fee),&chargedFee); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + if(shmp->process_info.cap_flag) + { + UpdateSubsCapInfo( + &shmp->caller_info, + 1, + (shmp->caller_info.fee), + 0, + shmp); + } + if(shmp->process_info.bundle_flag) + { + pps_update_account_bundle_mo_sms(shmp, -1); + } + + if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_SMS) + { + IncreaseFriendFamilyFreeSMSCounter(shmp->caller_info.head, shmp->caller_info.tail); + } + + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + + shmp->caller_info.charge = shmp->caller_info.fee; + + if(OCS_with_external_CRM()) + { + if(shmp->process_info.rest_if.total_plan_value > 0) + { + if(shmp->process_info.rest_if.used_plan_value < shmp->process_info.rest_if.total_plan_value) + { + shmp->process_info.rest_if.used_plan_value ++; + shmp->process_info.rest_if.plan_value_add_this_time = 1; + pps_send_update_plan_value_req(portid); + } + } + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"mo sms submitted %d, charge: %.2f", + shmp->process_info.cap_flag,shmp->caller_info.charge); + } + } + + SendCDR(portid); + + break; + default: + retval = S_RELEASE_ALL; + break; + }/* switch */ + + if(release_flag){ + + SendReleaseSMS(portid); + retval = S_RELEASE_ALL; + return retval; + } + + } + }/* ReadScfMsg */ + + /* + shmp->caller_info.valid_time --; + if (shmp->caller_info.valid_time <= 0) + { + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->process_info.tcos = CALLER_CREDIT_OUT; + SendReleaseSMS(portid); + SendCDR(portid); + return (retval = S_RELEASE_ALL); + } + */ + + shmp->process_info.down ++ ; + if(shmp->process_info.down >=SEND_ACTIVITYTEST_PERIODIC) + { + shmp->process_info.down = 0; + SendActivityTest(portid); + } + shmp->process_info.funnel ++; + + return retval; +} + + + + +int +ConferenceRequest(u_char oidLen, DWORD *oid,u_char *pdata,u_short dataLen) +{ + int duration,instance,caller_status; + int proc_id; + _state_data *shmp; + u_char calledbuf[32]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + CHARGED_FEE chargedFee; + + if(dataLen < 19) return 0; + + PutLogFunID("ConferenceRequest"); + + proc_id = AssignProcID(0); + if(proc_id>=MAX_FSM_PROCESS || proc_id<0) return 0; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += proc_id; + + duration = pdata[16] + pdata[17]*256; + + memcpy(shmp->cdr_info.caller,&pdata[8], 8); + ppsBcdToAsciiR((char *)shmp->caller_info.number, &pdata[8], 16); + StringCut((char *)shmp->caller_info.number, 'F'); + StringCut((char *)shmp->caller_info.number, 'E'); + memcpy(shmp->caller_info.IMSI, pdata, 8); + memcpy(shmp->cdr_info.called,calledbuf,8); + + //CheckWetherLocalNumber(shmp->caller_info.number); + + GetAccountPos(&shmp->caller_info); + + caller_status = GetAccountStatus(&shmp->caller_info); + + shmp->caller_info.charge = 0; + shmp->caller_info.fee = 0; + shmp->process_info.tcos = NORMAL_CLEARING; + shmp->caller_info.status = caller_status; + shmp->process_info.duration = duration*CYCLE_STATE_INTERVAL; + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->context_info.callType = CT_CONFERENCE_CALL; + SetCallType(shmp,CT_CONFERENCE_CALL); + + pdata[18] = 0x01; + + shmp->process_info.logMsisdn = 0x00; + + if(logMsgFlag & 0x08){ + if(strstr((char *)shmp->caller_info.number, logMsisdn)){ + shmp->process_info.logMsisdn = 0x01; + } + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Conference call: "); + DebugMsg(debugmib.display.asciiOut,"Duration: %d seconds",duration); + DebugMsg(debugmib.display.asciiOut,"Caller info : %s (%d %d) status:%d,balance: %.1f", + shmp->caller_info.number, + shmp->caller_info.head, + shmp->caller_info.tail, + caller_status, + GetBalance(&shmp->caller_info)); + } +#endif + + if(!ConferenceCallBillingProc(shmp,duration)){ + pdata[18] = 0x00; + ReleasePortStatus(proc_id); + return dataLen; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"Caller calltype: %d fee: %.0f", + shmp->process_info.call_type, + shmp->caller_info.fee); + } +#endif + UpdateBalance(shmp,&shmp->caller_info, -(shmp->caller_info.fee),&chargedFee); + instance = + shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + SendCDR(proc_id); + ReleasePortStatus(proc_id); + AddPPSStatistics(MIBPPS_CONFERENCE,0); + return dataLen; +} + +int thirdPartyChargeProc(snmp_pdu *pdu, snmp_addr *addr) +{ + int charge=0,instance,caller_status,datalen; + int proc_id,operation_type, + result,loop,vallen,/*msisdnlen,*/ + dataLen; + u_short ptagcode; + char caller[32],called[32]; + u_char pdata1[128],pdata2[128],pflag; + char serviceID[32],servicePWD[32],cardPWD[24],cause[64]=""; + char tagbuf[32]; + _state_data *shmp; + CHARGED_FEE chargedFee; + ASN_BUF *asnbuf, asnbuf1; + ASN_BUF *asnbuf2, asnbuf3; + + PutLogFunID("ThirdPartyChargeReqeust"); + + + memset(pdata1,0,128); + memset(pdata2,0,128); + + + dataLen = pdu->var[0].msglen; + if(dataLen>128) dataLen = 128; + + memcpy(pdata1,pdu->var[0].msg,dataLen); + + asnbuf = &asnbuf1; + + AsnEncode(pdu->var[0].msg,128,asnbuf); + asnbuf2 = &asnbuf3; + + AsnDecode(pdata1, 128, 10, NULL, asnbuf2); + + if(dataLen < 19){ + return dataLen; + } + + proc_id = AssignProcID(0); + if(proc_id>=MAX_FSM_PROCESS || proc_id<0) + return dataLen; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += proc_id; + + AddPPSStatistics(MIBPPS_THIRD_PARTY,shmp->process_info.dir); + //start + for(loop=1;loop<7;loop++) + { + sprintf(tagbuf,"-%d",loop); + if((vallen=GetAnyTLV(tagbuf,128,pdata2,&pflag,&ptagcode,asnbuf2))<=0) + { + break; + } + else + { + sprintf(tagbuf,"%d",ptagcode); + pdata2[vallen]=0; + switch(ptagcode) + { + case 0x01: //serviceID + if(vallen>8) vallen = 8; + memcpy(serviceID,pdata2,vallen); + serviceID[vallen] = 0; + break; + case 0x02: //servicePWD + if(vallen>12) vallen=12; + memcpy(servicePWD,pdata2,vallen); + servicePWD[vallen] = 0; + break; + case 0x03: //serviceType + operation_type = pdata2[0]; + break; + case 0x04: //caller + if(vallen>20) vallen = 20; + memcpy(caller,pdata2,vallen); + //msisdnlen = vallen; + caller[vallen] = 0; + break; + case 0x05: //cardPWD + if(vallen>16) vallen = 16; + memcpy(cardPWD,pdata2,vallen); + cardPWD[vallen] = 0; + break; + case 0x06: //charge + GetInteger(tagbuf,&charge ,pflag,asnbuf2); + // memcpy(&charge,pdata2,vallen); + break; + default: + break; + }//switch + }//else + }//for +//end + + CheckSeriveIdentification(serviceID,servicePWD,addr->remote_ip,&result,cause); + pdu->var_num = 1; + pdu->var[0].vartype = 0x04; + pdu->pdu_type = 2; + + if(result==0) + { + /* + sprintf(tagbuf,"0"); + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = ERROR_SERVICE_KEY; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + datalen =add_tlv(tagbuf,strlen(cause),cause,0x80,asnbuf); + */ + sprintf((char *)pdu->var[0].msg, "%s", cause); + datalen = strlen(cause); + pdu->error_index = 1; + pdu->error_status = 3; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + ReleasePortStatus(proc_id); + return datalen; + } +/* + memcpy(shmp->cdr_info.caller,caller, msisdnlen); + ppsBcdToAsciiR(shmp->caller_info.number, caller, msisdnlen*2); + printf("number: %s\n",shmp->caller_info.number); + StringCut(shmp->caller_info.number, 'F'); + StringCut(shmp->caller_info.number, 'E'); +*/ + strcpy((char *)shmp->caller_info.number, caller); + strcat(caller,"E"); + ppsAsciiToBcdR(shmp->cdr_info.caller,caller,16); + strcpy(caller,serviceID); + strcat(caller,"EE"); + ppsAsciiToBcdR(shmp->cdr_info.msisdn,caller,16); + memset(shmp->cdr_info.called,0xFF,8); + memset(shmp->caller_info.IMSI,0xFF,8); + + + //CheckWetherLocalNumber(shmp->caller_info.number); + GetAccountPos(&shmp->caller_info); + + + if(shmp->caller_info.head>=MSISDN_HEAD_NUM) + { + /* + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = EMPTY_NUMBER; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + + sprintf(cause,"No such account"); + datalen =add_tlv(tagbuf,strlen(cause),cause,0x80,asnbuf); + */ + sprintf(cause,"No such account"); + datalen = strlen(cause); + strcpy((char *)pdu->var[0].msg, cause); + pdu->error_index = 1; + pdu->error_status = 3; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + ReleasePortStatus(proc_id); + + return datalen; + } + caller_status = GetAccountStatus(&shmp->caller_info); + shmp->caller_info.cos_id = GetAccountCosID(&shmp->caller_info); + shmp->caller_info.charge = 0; + shmp->process_info.tcos = 0x8090; + shmp->caller_info.status = caller_status; + shmp->process_info.duration = 0; + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->context_info.callType = CT_THIRD_PARTY_CHARGE; + shmp->process_info.call_type = CT_THIRD_PARTY_CHARGE; + + if(operation_type == 0){//recharge + memset(shmp->cdr_info.called,0xFF,8); + strcpy(called,cardPWD); + strcat(called,"E"); + ppsAsciiToBcdR(shmp->cdr_info.called,called,(strlen(called)+1)/2*2); + shmp->process_info.rechargeByOther = 2; + + switch(caller_status) + { + case T_FRESH: + case T_NORMAL: + case T_SUSPEND: + case T_OPRTRIAL: + if(UseExternalVC()) + { + + strcpy((char *)shmp->called_info.number, cardPWD); + shmp->process_info.state = S_SMMP_RECHAGE_ACCOUNT; + shmp->process_info.sub_state = 0; + + pdu->var_num = 1; + pdu->var[0].vartype = 0x04; + pdu->pdu_type = 2; + pdu->var[0].msglen = dataLen; + memcpy(pdu->var[0].msg,pdata1,dataLen); + snmp_send(pdu,addr); + + return dataLen; + } + + if(RechargeCardRequest(proc_id,cardPWD,&result) != 1){ + SendRechargeCDR(proc_id, CT_RECHARGE_FAIL, 0); + /* + sprintf(tagbuf,"-0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"-1"); + result = ERROR_ACCOUNT_STATUS; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"-2"); + sprintf(cause,"Error card"); + datalen =add_tlv(tagbuf,strlen(cause),cause,0x80,asnbuf); + */ + sprintf(cause,"Error card"); + datalen = strlen(cause); + strcpy((char *)pdu->var[0].msg, cause); + pdu->error_index = 1; + pdu->error_status = 3; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + ReleasePortStatus(proc_id); + return datalen; + } + RechargeRequestProc(proc_id); + ReleasePortStatus(proc_id); + break; + default: + /* + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = ERROR_ACCOUNT_STATUS; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + sprintf(cause,"Unknow operation request"); + datalen =add_tlv(tagbuf,strlen(cause),cause,0x80,asnbuf); + */ + sprintf(cause,"Unknow operation request"); + datalen = strlen(cause); + strcpy((char *)pdu->var[0].msg, cause); + pdu->var[0].msglen = datalen; + pdu->error_index = 1; + pdu->error_status = 3; + snmp_send(pdu,addr); + ReleasePortStatus(proc_id); + return datalen; + break; + } + } + else if(operation_type == 1) + {//charge + shmp->process_info.chargeOther = 2; + if(caller_status != T_NORMAL || + GetExpiration(&shmp->caller_info)caller_info.number); + sprintf(cause,"Account status error or expired"); + datalen = strlen(cause); + strcpy((char *)pdu->var[0].msg, cause); + pdu->error_index = 1; + pdu->error_status = 3; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + ReleasePortStatus(proc_id); + return datalen; + } + if((GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+charge)<0) + { + /* + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = LOW_ACCOUNT_BALANCE; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + sprintf(cause,"Account balance is low"); + datalen =add_tlv(tagbuf,strlen(cause),cause,0x80,asnbuf); + */ + sprintf(cause,"Account balance is low"); + datalen = strlen(cause); + strcpy((char *)pdu->var[0].msg, cause); + pdu->error_index = 1; + pdu->error_status = 3; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + + ReleasePortStatus(proc_id); + return datalen; + } + UpdateBalance(shmp,&shmp->caller_info,charge,&chargedFee); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion, OMC_OCODE_EDIT); + shmp->caller_info.charge = -charge; + + SendCDR(proc_id); + + ReleasePortStatus(proc_id); + } + else if(operation_type == 2 || operation_type == 3) /* type3 = mt sms charge */ + { + if(caller_status == T_FRESH) + { + DebugMsg(debugmib.display.asciiOut, + "Account %s status error", + shmp->caller_info.number); + sprintf(cause,"Account status error or expired"); + datalen = strlen(cause); + strcpy((char *)pdu->var[0].msg, cause); + pdu->error_index = 1; + pdu->error_status = 3; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + ReleasePortStatus(proc_id); + return datalen; + } + shmp->process_info.chargeOther = 2; + shmp->caller_info.charge = -charge; + if(operation_type == 3) + { + shmp->caller_info.charge = ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id].serviceControl[0].mtSMSCharge; + charge = -shmp->caller_info.charge; + shmp->context_info.callType = CT_MT_SM; + shmp->process_info.call_type = CT_MT_SM; + memcpy(&shmp->called_info, &shmp->caller_info, sizeof(_account_info)); + } + + UpdateBalance(shmp,&shmp->caller_info,charge,&chargedFee); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance, chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + + + SendCDR(proc_id); + + ReleasePortStatus(proc_id); + } + else + { + /* + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = ERROR_SERVICE_KEY; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + sprintf(cause,"Unknow operation request"); + datalen =add_tlv(tagbuf,strlen(cause),cause,0x80,asnbuf); + */ + sprintf(cause,"Unknow operation request"); + datalen = strlen(cause); + strcpy((char *)pdu->var[0].msg, cause); + pdu->error_index = 1; + pdu->error_status = 3; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + ReleasePortStatus(proc_id); + return datalen; + } + + /* + sprintf(tagbuf,"0"); + result = 1; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + pdu->var_num = 1; + pdu->var[0].oidlen = 11; + memcpy(pdu->var[0].oid,PPS_OID_THIRDPARTY,11); + pdu->var[0].vartype = 0x04; + pdu->pdu_type = 2; + pdu->var[0].msglen = datalen; + snmp_send(pdu,addr); + return datalen; + */ + + pdu->var_num = 1; + pdu->var[0].vartype = 0x04; + pdu->pdu_type = 2; + pdu->var[0].msglen = dataLen; + memcpy(pdu->var[0].msg,pdata1,dataLen); + snmp_send(pdu,addr); + + return dataLen; +} + +int ThirdPartyChargeReqeust(u_char oidLen,u_long *oid,u_char *pdata,u_short dataLen) +{ + int charge,instance,caller_status,datalen; + int proc_id,operation_type,result,loop,vallen;//,msisdnlen; + u_short ptagcode; + char caller[32]; + u_char pdata1[128],pdata2[128],pflag; + char serviceID[32],servicePWD[32],cardPWD[32],cause[32]=""; + char tagbuf[32]; + _state_data *shmp; + CHARGED_FEE chargedFee; + ASN_BUF *asnbuf, asnbuf1; + ASN_BUF *asnbuf2, asnbuf3; + + PutLogFunID("ThirdPartyChargeReqeust"); + debugmib.watch_dog[4] ++; + return -1; + + memset(pdata1,0,128); + memset(pdata2,0,128); + + memcpy(pdata1,pdata,dataLen); + + asnbuf = &asnbuf1; + + AsnEncode(pdata,128,asnbuf); + asnbuf2 = &asnbuf3; + + AsnDecode(pdata1, 128, 10, NULL, asnbuf2); + + if(dataLen < 19){ +// printf("error datalen: %d\n",dataLen); + return dataLen; + } + + + proc_id = AssignProcID(0); + if(proc_id>=MAX_FSM_PROCESS || proc_id<0) + { + // printf("can't get port id\n"); + return dataLen; + } + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += proc_id; + + AddPPSStatistics(MIBPPS_THIRD_PARTY,shmp->process_info.dir); + //start + for(loop=0;loop<6;loop++) + { + sprintf(tagbuf,"-%d",loop); + if((vallen=GetAnyTLV(tagbuf,128,pdata2,&pflag,&ptagcode,asnbuf2))<=0) + { + break; + } + else + { + sprintf(tagbuf,"%d",ptagcode); + pdata2[vallen]=0; + switch(ptagcode) + { + case 0x00: //serviceID + memcpy(serviceID,pdata2,vallen%9); + serviceID[vallen%9] = 0; + break; + case 0x01: //servicePWD + memcpy(servicePWD,pdata2,vallen%13); + servicePWD[vallen%13] = 0; + break; + case 0x02: //serviceType + operation_type = pdata2[0]; + break; + case 0x03: //caller + memcpy(caller,pdata2,vallen%20); + //msisdnlen = vallen%20; + caller[vallen%20] = 0; + break; + case 0x04: //cardPWD + memcpy(cardPWD,pdata2,vallen%17); + break; + case 0x05: //charge +// GetInteger(tagbuf,&charge ,pflag,asnbuf2); + memcpy(&charge,pdata2,vallen); + break; + default: + break; + }//switch + }//else + }//for +//end + CheckSeriveIdentification(serviceID,servicePWD,0,&result,cause); + + if(result==0) + { + sprintf(tagbuf,"0"); + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = ERROR_SERVICE_KEY; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + datalen =add_tlv(tagbuf,strlen(cause), (u_char *)cause,0x80,asnbuf); + ReleasePortStatus(proc_id); + return datalen; + } +/* + memcpy(shmp->cdr_info.caller,caller, msisdnlen); + ppsBcdToAsciiR(shmp->caller_info.number, caller, msisdnlen*2); + printf("number: %s\n",shmp->caller_info.number); + StringCut(shmp->caller_info.number, 'F'); + StringCut(shmp->caller_info.number, 'E'); +*/ + + strcpy((char *)shmp->caller_info.number, caller); + + strcat(caller,"F"); + + ppsAsciiToBcdR(shmp->cdr_info.caller,caller,16); + memset(shmp->cdr_info.called,0xFF,8); + memset(shmp->caller_info.IMSI,0xFF,8); + //CheckWetherLocalNumber(shmp->caller_info.number); + GetAccountPos(&shmp->caller_info); + + + if(shmp->caller_info.head>=MSISDN_HEAD_NUM) + { + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = EMPTY_NUMBER; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + sprintf(cause,"No such account"); + datalen =add_tlv(tagbuf,strlen(cause), (u_char *)cause,0x80,asnbuf); + ReleasePortStatus(proc_id); + + return datalen; + } + caller_status = GetAccountStatus(&shmp->caller_info); + shmp->caller_info.charge = 0; + shmp->process_info.tcos = NORMAL_CLEARING; + shmp->caller_info.status = caller_status; + shmp->process_info.duration = 0; + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->context_info.callType = CT_THIRD_PARTY_CHARGE; + shmp->process_info.call_type = CT_THIRD_PARTY_CHARGE; + + if(operation_type == 0){//recharge + switch(caller_status) + { + case T_FRESH: + case T_NORMAL: + case T_SUSPEND: + case T_OPRTRIAL: + if(RechargeCardRequest(proc_id,cardPWD, &result) != 1){ + SendRechargeCDR(proc_id, CT_RECHARGE_FAIL, 0); + sprintf(tagbuf,"-0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"-1"); + result = ERROR_ACCOUNT_STATUS; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"-2"); + sprintf(cause,"Error card"); + datalen =add_tlv(tagbuf,strlen(cause), (u_char *)cause,0x80,asnbuf); + ReleasePortStatus(proc_id); + return datalen; + } + shmp->process_info.state = S_RECHARGE_OVER; + break; + default: + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = ERROR_ACCOUNT_STATUS; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + sprintf(cause,"Unknow operation request"); + datalen =add_tlv(tagbuf,strlen(cause), (u_char *)cause,0x80,asnbuf); + ReleasePortStatus(proc_id); + return datalen; + break; + } + } + else if(operation_type == 1) + {//charge + if(caller_status != T_NORMAL || + GetExpiration(&shmp->caller_info)caller_info)+charge)<0) + { + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = LOW_ACCOUNT_BALANCE; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + sprintf(cause,"Account balance is low"); + datalen =add_tlv(tagbuf,strlen(cause), (u_char *)cause,0x80,asnbuf); + + ReleasePortStatus(proc_id); + return datalen; + } + UpdateBalance(shmp,&shmp->caller_info,charge,&chargedFee); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion, OMC_OCODE_EDIT); + shmp->caller_info.charge = charge; + + SendCDR(proc_id); + + ReleasePortStatus(proc_id); + }else{ + sprintf(tagbuf,"0"); + result = 0; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"1"); + result = ERROR_SERVICE_KEY; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + sprintf(tagbuf,"2"); + sprintf(cause,"Unknow operation request"); + datalen =add_tlv(tagbuf,strlen(cause), (u_char *)cause,0x80,asnbuf); + ReleasePortStatus(proc_id); + return datalen; + } + + sprintf(tagbuf,"0"); + result = 1; + datalen = AddInteger(tagbuf,result,0x80,asnbuf); + ReleasePortStatus(proc_id); + return datalen; +} + + +int EstablishTemporaryConnection(u_short portid) +{ + int retval; + _state_data *shmp; + + PutLogFunID("EstablishTemporaryConnection"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; +/* + if(!CheckSRFResource()) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut, + "Warning: SRF is not reachable!"); + } +#endif + return (retval=S_SEND_RELEASE_CALL); + } +*/ + SendEstablishTemporaryConnection(portid); + shmp->process_info.srfRelease = 0; + shmp->process_info.funnel = 0; + shmp->process_info.down = 0; + shmp->process_info.Tassist = 0; + shmp->process_info.connFlag = 1; + retval = S_DISCONNECT_FORWARD_CONNECTION; + return retval; +} + +int SendPlayAnnouncementOrPCUI(u_short portid) +{ + int retval,correlationID; + _state_data *shmp,*shmpconn; + + PutLogFunID("SendPlayAnnouncementOrPCUI"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + correlationID = shmp->process_info.correlationID; + + if(subSystemID) + {/* plan 1 correlation ID range: 4000-(4000+2047) + while plan 0 range: 0-2047*/ + if(correlationID <4000) + { + shmp->process_info.u_error = CAP_ERR_TASK_REFUSED; + shmp->process_info.oc = CAP_OC_AssistRequestInstructions; + SendScfUError(portid); /* add later, 2004-02-17 */ + shmp->process_info.tcend = 1; + //SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + else + { + correlationID -= 4000; + } + } + if(correlationID>=MAX_FSM_PROCESS) + { + shmp->process_info.u_error = CAP_ERR_TASK_REFUSED; + shmp->process_info.oc = CAP_OC_AssistRequestInstructions; + SendScfUError(portid); /* add later, 2004-02-17 */ + shmp->process_info.tcend = 1; + //SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + + shmpconn = (_state_data *)&smshm_ptr->state_data; + shmpconn += correlationID; + shmp->process_info.promptAndCollectUserInfo = + shmpconn->process_info.promptAndCollectUserInfo; + + + if(shmpconn->process_info.connFlag != 1) + { + /* + if(logMsgFlag & 0x02 || + logMsgFlag & 0x04 || + logMsgFlag & 0x10 ) + { + DebugMsg(debugmib.display.asciiOut, + "Warning: port=%d not correlated",correlationID); + } + */ + shmp->process_info.u_error = CAP_ERR_TASK_REFUSED; + shmp->process_info.oc = CAP_OC_AssistRequestInstructions; + SendScfUError(portid); /* add later, 2004-02-17 */ + shmp->process_info.tcend = 1; + //SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + memcpy(&shmp->caller_info,&shmpconn->caller_info,sizeof(_account_info)); + memcpy(&shmp->called_info,&shmpconn->called_info,sizeof(_account_info)); + memcpy(&shmp->cdr_info,&shmpconn->cdr_info,sizeof(_cdr_info)); + + shmp->process_info.connFlag = 2; + shmp->process_info.correlationID = correlationID; + shmpconn->process_info.connFlag = 2; + shmpconn->process_info.correlationID = portid; + + shmp->process_info.voiceID = shmpconn->process_info.voiceID; + shmp->process_info.pre_warning = shmpconn->process_info.pre_warning; + shmp->process_info.tcos = shmpconn->process_info.tcos; + shmp->process_info.logMsisdn = shmpconn->process_info.logMsisdn; + shmp->process_info.serviceType = shmpconn->process_info.serviceType; + shmp->process_info.sub_state = shmpconn->process_info.sub_state; + shmp->context_info.callType = shmpconn->context_info.callType; + shmp->process_info.palim_auto_register = shmpconn->process_info.palim_auto_register; + + if(shmp->process_info.promptAndCollectUserInfo) + { + switch(shmp->process_info.serviceType) + { + case SRV_INQUIRY: + shmp->process_info.sub_state = S_INQ_SEND_PROMPT; + retval = S_INQUIRY_MANAGE; + break; + case SRV_SCRATCH_CARD_RECHARGE: + case SRV_RECHARGE_2TYPES: + /* + shmp->process_info.sub_state = S_REC_CHECK_ACCOUNT_STATUS; + retval = S_RECHARGE_MANAGE; + */ + clearTransferInfo(portid); + retval = S_CHARGE_OR_TRANSFER; + break; + case SRV_CREDIT_CARD_RECHARGE: + shmp->process_info.sub_state = S_CCR_PLAY_INFO; + retval = S_CREDIT_CARD_RECHARGE; + break; + case SRV_THIRD_PARTY_RECHARGE: + shmp->process_info.sub_state = S_REC_INPUT_ACCOUNT; + retval = S_RECHARGE_MANAGE; + break; + case SRV_RECHARGE_ONE_INPUT: + shmp->process_info.srfRelease = 2; + if(UseExternalVC() ) + { + shmp->process_info.sub_state = S_REC_CHECK_CARD_VALIDITY; + return (retval = S_RECHARGE_MANAGE); + } + if(OCS_with_external_CRM()) + { + shmp->process_info.sub_state = S_REC_CHECK_CARD_VALIDITY; + return (retval = S_RECHARGE_MANAGE); + } + + switch(shmp->process_info.sub_state) + { + case 0://error status + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + SendSrfPlayAnnouncement(portid); + break; + case 1://success + SendRechargeInfoPromptToSrf(portid); + break; + case 2://error pwd + shmp->process_info.voiceID = RECHARGE_FAILED; + SendSrfPlayAnnouncement(portid); + break; + } + retval = S_WAITING_SPECIAL_RESOURCE_REPORT; + break; + case SRV_CALL_HOTLINE: + if(shmp->caller_info.headprocess_info.voiceID = SERVICE_SELECT_PROMPT; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + retval = S_WAITING_RR_PCUI; + } + else + { + shmp->process_info.sub_state = S_REC_INPUT_ACCOUNT; + retval = S_RECHARGE_MANAGE; + } + break; + case SRV_CRD: + case SRV_DIRECT_ACCESS: + case SRV_RESERVED_FUN: + retval = S_CRD_SERVICE; + if(shmp->context_info.callType == CT_MF_CALL) + { + shmp->process_info.chargeOther = 2; + shmp->process_info.sub_state = S_CRD_CONNECT; + } + else + shmp->process_info.sub_state = S_CRD_CHECK_CALLER_INFO; + break; + case SRV_OTHER_VMS_MAITENANCE: + retval = S_CRD_SERVICE; + shmp->process_info.sub_state = S_CRD_INPUT_VOICEBOX; + break; + case SRV_VMS_DEPOSIT: + retval = S_CRD_SERVICE; + shmp->process_info.sub_state = S_CRD_SET_DEPOSIT; + break; + case SRV_OPR_MANAGE: + retval = S_OPR_MANAGE; + break; + case SRV_CALLINGCARD_MANAGE:/*calling card */ + clearTransferInfo(portid); + retval = S_CALLING_CARD; + break; + case SRV_FEE_TRANSFER: + clearTransferInfo(portid); + retval = S_FEE_TRANSFER; + break; + case SRV_POOL_ACCOUNT: + clearMasterSlaveInfo(portid); + retval = S_POOL_ACCOUNT; + break; + } + } + else + { + shmp->process_info.srfRelease = 0x00; + SendSrfPlayAnnouncement(portid); + retval = S_WAITING_SPECIAL_RESOURCE_REPORT; + } + shmp->process_info.funnel = 0; + + return retval; +} + +int WaitingForDisconnectForwardConnection(u_short portid) +{ + int retval,dlgid,correlationID; + CAP_Message capmsg; + _state_data *shmp,*shmpconn; + + PutLogFunID("WaitingForDisconnectForwardConnection"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + /* + */ + retval = shmp->process_info.state; + + if(shmp->process_info.funnel++>ACTIVITY_TEST_DELAY) + { + shmp->process_info.tcos = TIMER_OUT; +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut, + "portid=%d ActivityTest missed (waiting DFC)!",portid); + } +#endif + SendReleaseCall(portid); + return (retval = S_RELEASE_ALL); + } + + if(shmp->process_info.connFlag == 1) + if(shmp->process_info.Tassist++>ONE_MINUTE_STATE_TIME) + { + shmp->process_info.tcos = TIMER_OUT; + SendReleaseCall(portid); +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut, + "portid=%d AssistRequest missed (waiting DFC)!",portid); + } +#endif + return (retval = S_RELEASE_ALL); + } + + shmp->process_info.down ++ ; + if(shmp->process_info.down >=SEND_ACTIVITYTEST_PERIODIC) + { + shmp->process_info.down = 0; + SendActivityTest(portid); + } + + if(shmp->process_info.disconnectForwardConnection == 1) + { //released by SRF + + + SendDisconnectForwardConnection(portid); + +//DebugMsg(debugmib.display.asciiOut,"connected:%d",shmp->process_info.callConnected); + + if(shmp->process_info.callConnected) + { + sendConnectForCRDService(portid); + shmp->process_info.chargeOther = 0; + if(shmp->process_info.callConnected == 1) + { + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + } + if(shmp->process_info.serviceType == SRV_CRD || + shmp->process_info.serviceType == SRV_DIRECT_ACCESS || + shmp->process_info.serviceType == SRV_RESERVED_FUN || + shmp->process_info.serviceType == SRV_OTHER_VMS_MAITENANCE || + shmp->process_info.serviceType == SRV_VMS_DEPOSIT) + { + + if(shmp->caller_info.head>=MSISDN_HEAD_NUM ) + { + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + + if((shmp->process_info.serviceType == SRV_CRD || + shmp->process_info.serviceType == SRV_DIRECT_ACCESS || + shmp->process_info.serviceType == SRV_RESERVED_FUN ) + && shmp->caller_info.status != T_NORMAL) + { + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + shmp->process_info.promptAndCollectUserInfo = 0; + shmp->process_info.funnel = 0; + shmp->process_info.down = 0; + return (retval = S_WAITINGFOR_ANSWERED); + } + + if(shmp->process_info.serviceType == SRV_CALLINGCARD_MANAGE) + {/* calling card */ + if(shmp->process_info.callingCardState == sendMainMenu + &&shmp->process_info.callingCardFunction == MakeCall) + {/* calling card routing call */ + shmp->process_info.disconnectForwardConnection = 0; + shmp->process_info.callingCardState = 0; + shmp->process_info.callingCardFunction = 0; + if(ocs_get_calling_card_method() == 0) + return (retval = S_CHECK_CALL_VALIDITY); + else + return (retval = S_CC_CHECK_CALL_VALIDITY); + } + else + { + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + } + + if(!shmp->process_info.pre_warning) + { + return (retval = S_SEND_RELEASE_CALL); + } + else + { + shmp->process_info.pre_warning = 0; + shmp->process_info.playAnnouncement = 0; + shmp->process_info.promptAndCollectUserInfo = 0; + return (retval = S_REQUEST_EVENTS); + } + } + + dlgid = shmp->context_info.dialogue_id; + if(ReadScfMsg(&capmsg,dlgid)) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_EventReportBCSM: + shmp->process_info.tcos = NORMAL_CLEARING; + SendReleaseCall(portid); + break; + case CAP_OC_ActivityTest: + if(capmsg.msgContent[2] != 0x03) + shmp->process_info.funnel = 0; + return retval; + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + shmp->process_info.tcos = INVALID_MESSAGE; + SendReleaseCall(portid); + break; + } + + if(shmp->process_info.connFlag == 2) + { // to release SRF + correlationID = shmp->process_info.correlationID; + shmpconn = (_state_data *)&smshm_ptr->state_data; + shmpconn += correlationID; + if(shmp->process_info.connFlag == 2) + shmpconn->process_info.disconnectForwardConnection = 1; + } + shmp->process_info.connFlag = 0; + retval = S_RELEASE_ALL; + } + return retval; + +} + +int SendSSFReleaseCall(u_short portid) +{ + PutLogFunID("SendSSFReleaseCall"); + + SendReleaseCall(portid); + return S_RELEASE_ALL; +} + +int WaitingForSpecialResourceReport(u_short portid) +{ + int retval,dlgid; + CAP_Message capmsg; + _state_data *shmp; + COSTable *cosTableItem; + + PutLogFunID("WaitingForSpecialResourceReport"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + retval = shmp->process_info.state; + + if(shmp->process_info.funnel++>SPECIAL_RESOURCE_REPORT_TIMER) + { + shmp->process_info.tcos = TIMER_OUT; +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"[%04d] Wait SpecailResourceReport timer out! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } +#endif + + return (retval = S_RELEASE_SRF); + } + + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + + dlgid = shmp->context_info.dialogue_id; + if(ReadScfMsg(&capmsg,dlgid)) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_SpecializedResourceReport: + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + switch(shmp->process_info.srfRelease) + { + case 1: + shmp->process_info.voiceID = SERVICE_SELECT_PROMPT; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + retval = S_WAITING_RR_PCUI; + break; + case 2: + return (retval = S_RELEASE_SRF); + break; + case 0:/* confused , should be re-wroten latter */ + default: + if(!shmp->process_info.pre_warning) + { + + if(shmp->context_info.callType != CT_MO_CALL) + { + return (retval = S_RELEASE_SRF); + }/* above added for mt voice , 2005-11-30 */ + if(shmp->process_info.serviceType != SRV_INQUIRY) + { + if(shmp->caller_info.status != T_SUSPEND && + shmp->caller_info.status != T_BLACKLIST && + shmp->caller_info.status != T_RELEASED) + { + if(shmp->process_info.tcos == TARIFF_NOT_SET) + { + return (retval = S_RELEASE_SRF); + } + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(cosTableItem->serviceControl[0].creditVault && GetOverdraft(&shmp->caller_info)<=0) + if(shmp->process_info.tcos == CALLER_CREDIT_OUT) + { + shmp->process_info.sub_state = S_INQ_PLAY_CREDIT_VAULT; + return (retval = S_INQUIRY_MANAGE); + } + if(shmp->process_info.tcos == CALLER_REACH_CALL_LIMIT + ||shmp->process_info.tcos == CALLER_REACH_CHARGE_LIMIT) + {/* child reach limits ,release call */ + return (retval = S_RELEASE_SRF); + } + + if(shmp->process_info.tcos == SRVICE_NOT_SUBSCRIBERED || pps_get_adaptor_flag()) + return (retval = S_RELEASE_SRF); + + shmp->process_info.sub_state = S_INQ_TO_RECHARGE; + return (retval = S_INQUIRY_MANAGE); + } + } + else + { + shmp->process_info.sub_state = S_INQ_TO_RECHARGE; + return (retval = S_INQUIRY_MANAGE); + } + } + if(shmp->process_info.serviceType == SRV_CRD || + shmp->process_info.serviceType == SRV_DIRECT_ACCESS || + shmp->process_info.serviceType == SRV_RESERVED_FUN) + { + shmp->process_info.sub_state = S_CRD_CHECK_CALLER_INFO; + retval = S_CRD_SERVICE; + } + else if(shmp->process_info.serviceType == SRV_OTHER_VMS_MAITENANCE) + { + shmp->process_info.sub_state = S_CRD_INPUT_VOICEBOX; + retval = S_CRD_SERVICE; + } + else if(shmp->process_info.serviceType == SRV_VMS_DEPOSIT) + { + shmp->process_info.sub_state = S_CRD_SET_DEPOSIT; + retval = S_CRD_SERVICE; + } + else + { + retval = S_RELEASE_SRF; + } + break; + } + break; + case CAP_O_UABORT: + case CAP_O_PABORT: +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut, + "[%04d] Abort Received! (%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + } +#endif + //no end need, later 2004-02-17 + retval = S_RELEASE_SRF; + break; + default: + shmp->process_info.tcos = INVALID_MESSAGE; + retval = S_RELEASE_SRF; + break; + } + } + return retval; +} + +int ReleaseSRF(u_short portid) +{ + int retval,correlationID; + _state_data *shmp,*shmpconn; + + PutLogFunID("ReleaseSRF"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + + if(shmp->process_info.connFlag == 2) + { + correlationID = shmp->process_info.correlationID; + shmpconn = (_state_data *)&smshm_ptr->state_data; + shmpconn += correlationID; + if(shmpconn->process_info.connFlag == 2) + shmpconn->process_info.disconnectForwardConnection = 1; + } + shmp->process_info.connFlag = 0; + SendScfTcEND(portid); + + retval = S_RELEASE_ALL; + return retval; + +} + +int GetRegisteredServiceKey(u_char serviceKey) +{ + int i; + + PutLogFunID("GetRegisteredServiceKey"); + + for(i=0;istate_data; + shmp += portid; + retval = shmp->process_info.state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + DebugMsg(debugmib.display.asciiOut,"[%04d] Wait RR PCUI timeout!(%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + return (retval = S_RELEASE_SRF); + } + + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = S_RELEASE_ALL); + } + dlgid = shmp->context_info.dialogue_id; + if(ReadScfMsg(&capmsg,dlgid)) + { +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = S_RELEASE_SRF); + } + //len = capArg.msg_list.promptAndCollectUserInformationArg.digitsResponse[0]; + serviceKey = capArg.msg_list.promptAndCollectUserInformationArg.digitsResponse[2] &0x0F; + if((regKey=GetRegisteredServiceKey(serviceKey))<0) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + SendDisconnectForwardConnection(portid); + shmp->process_info.tcos = NORMAL_CLEARING; + return (retval = S_RELEASE_SRF); + } + shmp->process_info.srfRelease = 0; + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.voiceID = SERVICE_SELECT_PROMPT; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + return (retval = S_WAITING_RR_PCUI); + } + shmp->process_info.serviceInput = 0; + switch(regKey) + { + case HELP: + //SendDisconnectForwardConnection(portid); + shmp->process_info.tcos = NORMAL_CLEARING; + retval = S_RELEASE_SRF; + break; + case INQUIRY_SERVICE: + shmp->process_info.sub_state = S_INQ_SEND_PROMPT; + retval = S_INQUIRY_MANAGE; + break; + case SCRATCH_CARD_RECHARGE: + shmp->process_info.sub_state = S_REC_CHECK_ACCOUNT_STATUS; + retval = S_RECHARGE_MANAGE; + break; + case CREDIT_CARD_RECHARGE: + shmp->process_info.sub_state = S_CCR_PLAY_INFO; + retval = S_CREDIT_CARD_RECHARGE; + break; + case FAVORITE_NUMBER_SERVICE: + friendFamilyControl = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id].friendFamilyControl[0]; + if(!(friendFamilyControl->friendFamilyFlag)) + { + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + shmp->process_info.srfRelease = 1; + SendSrfPlayAnnouncement(portid); + return (retval = S_WAITING_SPECIAL_RESOURCE_REPORT); + } + if(GetAccountStatus(&shmp->caller_info) != T_NORMAL) + { + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + return (retval = S_WAITING_SPECIAL_RESOURCE_REPORT); + } + shmp->process_info.sub_state = S_FAV_PLAY_MENU; + retval = S_FAVORITE_NUMBER_MANAGE; + break; + case LANGUAGE_MANAGEMENT: + case PIN_MANAGEMENT: + if(GetAccountStatus(&shmp->caller_info) != T_NORMAL) + { + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + retval = S_WAITING_SPECIAL_RESOURCE_REPORT; + } + if(regKey == LANGUAGE_MANAGEMENT) + { + shmp->process_info.sub_state = S_LANGUAGE_MANAGE_MENU; + retval = S_LANGUAGE_MANAGEMENT; + } + else if(regKey == PIN_MANAGEMENT) + { + shmp->process_info.sub_state = S_PIN_INPUT_OLD_PIN; + retval = S_PIN_MANAGEMENT; + } + break; + } + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = S_RELEASE_SRF; + break; + } + } + return retval; +} + +int InquiryManageProc(u_short portid) +{ + int retval,dlgid,msglen; + int key,caller_status,instance; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + COSTable *cosTableItem; + _state_data *shmp; + int tmpval; + + PutLogFunID("InquiryManageProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = inq_mng_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + return (retval = inq_mng_exit); + } + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = inq_mng_exit); + } + + switch(shmp->process_info.sub_state) + { + case S_INQ_SEND_PROMPT: + + if(pps_get_adaptor_flag()) + { + shmp->process_info.sub_state = S_INQ_REST_GET; + shmp->process_info.sub_state_2 = 0; + shmp->process_info.rest_if.rest_oc = 0; + shmp->process_info.rest_if.rest_src = 2; + strcpy((char *)shmp->origin_info.number, (char *)shmp->called_info.number); + return retval; + } + + caller_status = GetAccountStatus(&shmp->caller_info); + if(caller_status == T_NORMAL|| caller_status == T_OPRTRIAL) + { + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP( + &shmp->caller_info, + shmp->called_info.number); + } + + SendAccountInfoPromptToSrf(portid,FALSE,TRUE); + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0x01; + shmp->process_info.sub_state = S_INQ_SRR; + } + else + { + if(caller_status == T_FRESH && shmp->caller_info.headcaller_info.cos_id]; + if(cosTableItem->accountValidity[0].activiationByInquiryIs) + { + UpdateAccountStatus(shmp->caller_info.head, + shmp->caller_info.tail, + T_NORMAL); + UpdateAccountFirstUsedDate( + shmp->caller_info.head, + shmp->caller_info.tail); + UpdateExpirationFirstInquiry( + &shmp->caller_info, + cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance + ); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP( + &shmp->caller_info, + shmp->called_info.number); + } + + SendAccountInfoPromptToSrf(portid,FALSE,TRUE); + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0x01; + shmp->process_info.sub_state = S_INQ_SRR; + return retval; + } + } +// else + { + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_INQ_SRR0; + } + } + break; + case S_INQ_SRR0: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + retval = inq_mng_exit; + break; + case S_INQ_SRR: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + return (retval=inq_mng_exit); + } + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + shmp->process_info.sub_state = S_INQ_TO_RECHARGE; + break; + case S_INQ_PLAY_CREDIT_VAULT: + if (0)// PCUI and wait for input + { + shmp->process_info.voiceID = PRESS_2_TO_USE_CREDIT_VAULT; + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.endOfReplyDigit[0] = 0; + shmp->process_info.endOfReplyDigit[1] = ' '; + SendPromptCollectedRechargedUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_INQ_WAIT_CREDIT_VAULT; + } + if (1)// change to PAI and release + { + shmp->process_info.voiceID = OPERATION_SUCESSFULLY_DONE; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_INQ_WAIT_CREDIT_VAULT; + } + break; + case S_INQ_WAIT_CREDIT_VAULT: + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + else + { + retval = inq_mng_exit; + return retval; + } + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = inq_mng_exit); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + if(pPCUI->digitsResponse[0]<2) + return (retval = inq_mng_exit); + + key = pPCUI->digitsResponse[2] &0x0F; + + if(key == 1) + { + shmp->process_info.serviceInput = 0; + retval = inq_mng_to_recharge; + } + else if(key == 2) + { + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + UpdateAccountOverdraft(shmp->caller_info.head, + shmp->caller_info.tail, + cosTableItem->serviceControl[0].creditVaultAmount); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + shmp->process_info.sub_state = S_INQ_PLAY_OPERATION_DONE; + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenApplyOverdraft) + { + char notificationSMS[256],buf[32]; + + fillMoneyToContent((float)(cosTableItem->serviceControl[0].creditVaultAmount),buf); + + sprintf(notificationSMS, + "%s%s", + getSmsSentenceNative(0,SMS_OVERDRAFT_NOTIFICATION), + buf + ); + smppSendMOSM((char *)shmp->caller_info.number, + (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, + (u_char *)notificationSMS, + strlen(notificationSMS), + 0); + } + } + else + { + retval = inq_mng_exit; + } + break; + default: + retval = inq_mng_exit; + break; + } + break; + case S_INQ_PLAY_OPERATION_DONE: + shmp->process_info.voiceID = OPERATION_SUCESSFULLY_DONE; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_INQ_SRR_OPERATION_DONE; + break; + case S_INQ_SRR_OPERATION_DONE: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + retval = inq_mng_exit; + break; + case S_INQ_TO_RECHARGE: + shmp->process_info.voiceID = INQUIRY_RECHARGE_KEY; + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.endOfReplyDigit[0] = 0; + shmp->process_info.endOfReplyDigit[1] = ' '; + SendPromptCollectedRechargedUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_INQ_TO_RECHARGE_CONFIRM; + break; + case S_INQ_TO_RECHARGE_CONFIRM: + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = inq_mng_exit); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + if(pPCUI->digitsResponse[0]<2) + return (retval = inq_mng_exit); + + key = pPCUI->digitsResponse[2] &0x0F; + if(key == 1) + { + shmp->process_info.serviceInput = 0; + retval = inq_mng_to_recharge; + } + else + { + retval = inq_mng_exit; + } + break; + default: + retval = inq_mng_exit; + break; + } + break; + case S_INQ_REST_GET: + + tmpval = pps_rest_query_process(portid); + if( tmpval == 0) + return retval; + + if(tmpval == 1) + { + //SendRestAccountInfoPromptToSrf(portid); + SendAccountInfoPromptToSrf(portid, FALSE, FALSE); + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0x01; + shmp->process_info.sub_state = S_INQ_SRR; + } + else + { + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_INQ_SRR0; + } + + break; + }//sub_state + return retval; +} + + +int creditCardRechargeProc(u_short portid) +{ + int retval,dlgid; + u_short connPort; + _state_data *shmp,*shmpConn; + + CAP_Message capmsg; + + + PutLogFunID("creditCardRechargeProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = ccr_mng_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + return (retval = ccr_mng_exit); + } + + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = ccr_mng_exit); + } + + switch(shmp->process_info.sub_state) + { + case S_CCR_PLAY_INFO: + + SendAccountInfoPromptToSrf(portid,TRUE,FALSE); + shmp->process_info.sub_state = S_CCR_SSR; + break; + case S_CCR_SSR: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) + || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + return (retval=inq_mng_exit); + } + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + shmp->process_info.sub_state = S_CCR_CONNECT_TO_CREDIT_CENTER; + break; + case S_CCR_CONNECT_TO_IVR_SCRATCH_CARD: + connPort = shmp->process_info.correlationID; + shmpConn = (_state_data *)&smshm_ptr->state_data; + shmpConn += connPort; + shmpConn->process_info.callConnected = 1; + strcpy(shmpConn->process_info.tmpDigits, + (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + retval = ccr_mng_connect_to_credit_center; + break; + case S_CCR_CONNECT_TO_CREDIT_CENTER: + connPort = shmp->process_info.correlationID; + shmpConn = (_state_data *)&smshm_ptr->state_data; + shmpConn += connPort; + shmpConn->process_info.callConnected = 1; + strcpy(shmpConn->process_info.tmpDigits, + (char *)ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number); +// sendConnectForCRDService(connPort); + + retval = ccr_mng_connect_to_credit_center; + break; + } + + return retval; +} + +int WaitingForRechargeTypeResponse(u_short portid) +{ + int retval=0,dlgid,msglen,len,key; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp; + + PutLogFunID("WaitingForRechargeTypeResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 4); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = 4); + + key = pPCUI->digitsResponse[2]&0x0F; + + if(key == 1) + { + retval = 1; + } + else if(key == 2) + { + retval = 2; + } + else + { + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval=4); + } + retval = 3; + } + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 4; + break; + } + return retval; +} + + +int WaitingForRechargeAccountResponse(u_short portid) +{ + int retval=0,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp; + + PutLogFunID("WaitingForRechargeAccountResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) + || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len>11) len = 11; + if(len<=2) // + { + //if(shmp->caller_info.head>=MSISDN_HEAD_NUM) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + } + + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + memset(shmp->cdr_info.msisdn,0xFF,10); + memcpy(shmp->cdr_info.msisdn, + &pPCUI->digitsResponse[2], + len-1); + ppsBcdToAsciiR((char *)shmp->recharge_info.number, + &pPCUI->digitsResponse[2], + 2*(len-1)); + StringCut((char *)shmp->recharge_info.number,'F'); + CutUnknownPrefix((char *)shmp->recharge_info.number); + GetAccountPos(&shmp->recharge_info); + + shmp->recharge_info.status = GetAccountStatus(&shmp->recharge_info); + GetAccountCosID(&shmp->recharge_info); + if(shmp->recharge_info.head>=MSISDN_HEAD_NUM) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + + if(shmp->recharge_info.status != T_FRESH && + shmp->recharge_info.status != T_NORMAL && + shmp->recharge_info.status != T_SUSPEND ) + { + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + retval = 1; + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 3; + break; + } + return retval; +} + +int WaitingForRechargePIN(u_short portid) +{ + int retval=0,dlgid,msglen,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp; + + PutLogFunID("WaitingForRechargePIN"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<=2 || len>12) + { + return (retval = 3); + } + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + ppsBcdToAsciiR(shmp->process_info.tmpDigits, + &pPCUI->digitsResponse[2], + 2*(len-1)); + //StringCut(shmp->process_info.tmpDigits,'F'); + + len = strlen(shmp->process_info.tmpDigits); +// DebugMsg(debugmib.display.asciiOut,"input pwd: %s,len: %d,%s", +// shmp->process_info.tmpDigits,len,shmp->recharge_info.number); + if(len != MAX_PIN_LEN) + return (retval = 2); + if(CheckPINValidity(&shmp->recharge_info,shmp->process_info.tmpDigits)==0) + { + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + retval = 1; + break; + } + return retval; +} + +int WaitingForRechargeAccountConfirmResponse(u_short portid) +{ + int retval=0,dlgid,msglen,len,key; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp; + + PutLogFunID("WaitingForRechargeAccountConfirmResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + { + return (retval = 3); + } + key = pPCUI->digitsResponse[2]&0x0F; + if(key == 2) + { + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval=3); + } + retval = 2; + }else if(key == 1) + { + shmp->process_info.chargeOther = 1; + retval = 1; + } + else + { + shmp->process_info.serviceInput ++; + retval = 3; + } + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 3; + break; + } + return retval; +} + +int WaitingForRechargeCardPasswordResponse(u_short portid) +{ + int retval=0,len,dlgid, + msglen,result; + char card_hrn[32]; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pCUI; + _state_data *shmp; + + PutLogFunID("WaitingForRechargeCardPasswordResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pCUI->digitsResponse[0]; + if(len<2 || len>11) + { + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + len --; + if(pCUI->digitsResponse[1] & 0x80) + pCUI->digitsResponse[len] |= 0xF0; + + memset(shmp->cdr_info.called,0xFF,10); + memcpy(shmp->cdr_info.called,&pCUI->digitsResponse[2],len); + + ppsBcdToAsciiR(card_hrn,&pCUI->digitsResponse[2],len*2); + if(CheckWetherValidRechargeCard(portid,card_hrn, &result)==0) + { + if(result==5) + { + return (retval = 4); + } + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + else + { + shmp->process_info.serviceInput = 0; + retval = 1; + } + break; + default: + retval = 3; + break; + }/* swithc */ + return retval; +} + +int WaitingForRechargeCardPasswordResponseRcm(u_short portid) +{ + int retval=0,len,dlgid, + msglen; + char card_hrn[32]; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pCUI; + _state_data *shmp; + + PutLogFunID("WaitingForRechargeCardPasswordResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + if(portid>=MAX_FSM_PROCESS) + return -1; + + shmp += portid; + + + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode != CAP_OC_PromptAndCollectUserInformation) + return 3; + + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen%140, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pCUI->digitsResponse[0]; + if(len<2 || len>11) + { + return (retval = 2); + } + + len --; + + if(pCUI->digitsResponse[1] & 0x80) + pCUI->digitsResponse[len] |= 0xF0; + + memset(shmp->cdr_info.called,0xFF,10); + memcpy(shmp->cdr_info.called,&pCUI->digitsResponse[2],len); + ppsBcdToAsciiR(card_hrn,&pCUI->digitsResponse[2],len*2); + + strcpy((char *)shmp->called_info.number, card_hrn); + + return (retval = 1); + +} + +int RechargeManageProc(u_short portid) +{ + int retval,retval1,dlgid; + int caller_status,result=0; + CAP_Message capmsg; + _state_data *shmp; + COSTable *cosTableItem; + int tmpval; + + PutLogFunID("RechargeManageProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = rec_mng_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + return (retval = rec_mng_exit); + } + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = rec_mng_exit); + } + + switch(shmp->process_info.sub_state) + { + case S_REC_CHECK_ACCOUNT_STATUS: + if(pps_get_adaptor_flag()) + { + shmp->process_info.sub_state = S_REC_INPUT_PWD; + return retval; + } + + caller_status = GetAccountStatus(&shmp->caller_info); + if(shmp->caller_info.head>=MSISDN_HEAD_NUM) + { + shmp->process_info.sub_state = S_REC_INPUT_ACCOUNT; + } + else + { + if( caller_status != T_NORMAL && + caller_status != T_FRESH && + caller_status != T_SUSPEND && + caller_status != T_OPRTRIAL ) + { + shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; + shmp->process_info.srfRelease = 1; + SendSrfPlayAnnouncement(portid); + shmp->process_info.tcos = NORMAL_CLEARING; + shmp->process_info.sub_state = S_REC_WAIT_SRR; + return retval; + } + + shmp->process_info.sub_state = S_REC_PLAY_BALANCE; + } + break; + case S_REC_INPUT_ACCOUNT: + shmp->process_info.chargeFrom = 1; /* charge from SRF */ + shmp->process_info.funnel = 0; + shmp->process_info.voiceID = INPUT_RECHARGE_ACCOUNT; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + shmp->process_info.maxPCUInfoLen = 20; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state = S_REC_WAIT_ACCOUNT; + break; + case S_REC_WAIT_ACCOUNT: + retval1 = WaitingForRechargeAccountResponse(portid); + switch(retval1) + { + case 0: + break; + case 2: + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = ERROR_RECHARGE_ACCOUNT; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + break; + case 1: + shmp->process_info.serviceInput = 0; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_REC_INPUT_PIN; + break; + case 3: + retval = rec_mng_exit; + break; + } + break; + case S_REC_INPUT_PIN: + shmp->process_info.srfRelease = 0; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + shmp->process_info.voiceID = INPUT_OLD_PIN; + shmp->process_info.maxPCUInfoLen = MAX_PIN_LEN; + SendPromptCollectedRechargedUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state = S_REC_WAIT_PIN; + break; + case S_REC_WAIT_PIN: + retval1 = WaitingForRechargePIN(portid); + switch(retval1) + { + case 0: + break; + case 1: + shmp->process_info.rechargeByOther = 1; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_REC_INPUT_PWD; + break; + case 2: + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = ERROR_PIN; + shmp->process_info.maxPCUInfoLen = MAX_PIN_LEN; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptCollectedRechargedUserInfo(portid); + shmp->process_info.funnel = 0; + break; + case 3: + retval = rec_mng_exit; + break; + } + break; + case S_REC_ACCOUNT_READ: + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = TO_BE_RECHARGED_NUMBER; + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptCollectedRechargedUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state = S_REC_ACCOUNT_CONFRIM; + break; + case S_REC_ACCOUNT_CONFRIM: + retval1 = WaitingForRechargeAccountConfirmResponse(portid); + switch(retval1) + { + case 0: + break; + case 1: + shmp->process_info.sub_state = S_REC_INPUT_PWD; + break; + case 2: + shmp->process_info.sub_state = S_REC_INPUT_ACCOUNT; + break; + case 3: + retval = rec_mng_exit; + break; + } + break; + case S_REC_PLAY_BALANCE: + shmp->process_info.funnel = 0; + SendAccountInfoPromptToSrf(portid,TRUE,FALSE); + shmp->process_info.sub_state = S_REC_WAIT_SRR0; + break; + case S_REC_WAIT_SRR0: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + } + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + if(shmp->process_info.serviceType == SRV_RECHARGE_2TYPES) + shmp->process_info.sub_state = S_REC_INPUT_RECHARGE_TYPE; + else + shmp->process_info.sub_state = S_REC_INPUT_PWD; + break; + case S_REC_INQ_CHECK_MENU: + if(pps_get_adaptor_flag()) + { + shmp->process_info.sub_state = S_REC_INPUT_PWD; + return retval; + } + + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(cosTableItem->serviceControl[0].rechargeViaCreditCard == 0) + shmp->process_info.sub_state = S_REC_INPUT_RECHARGE_TYPE; + else + shmp->process_info.sub_state = S_REC_INPUT_PWD; + break; + case S_REC_INPUT_RECHARGE_TYPE: + shmp->process_info.funnel = 0; + shmp->process_info.voiceID = RECHARGE_TYPE_SELECTION; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state = S_REC_WAIT_TYPE; + break; + case S_REC_WAIT_TYPE: + retval1 = WaitingForRechargeTypeResponse(portid); + switch(retval1) + { + case 0: /* keep state */ + break; + case 1: /* scratch card recharge */ + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state = S_REC_INPUT_PWD; + break; + case 2: /* credit card recharge */ + retval = rec_mng_turn_to_credit_recharge; + break; + case 3: + shmp->process_info.sub_state = S_REC_INPUT_RECHARGE_TYPE; + break; + case 4: /* 3 times input error , hang up */ + retval = rec_mng_exit; + break; + } + break; + case S_REC_INPUT_PWD: + /* return to IVR here */ + if(ppsParam.ppsTables.ivrSource[0].recharge) + { + return (retval = rec_mng_turn_to_ivr_scratch_card); + } + shmp->process_info.chargeFrom = 1; /* charge from SRF */ + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = INPUT_PRECARD_PWD; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + shmp->process_info.maxPCUInfoLen = 20; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state = S_REC_CHECK_PWD; + break; + case S_REC_CHECK_PWD: + retval1 = WaitingForRechargeCardPasswordResponseRcm(portid); + switch(retval1) + { + case 0: + break; + case 1: + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_REC_CHECK_CARD_VALIDITY; + break; + case 2: /* error pwd, input again */ + default: + shmp->process_info.sub_state = S_REC_INPUT_PWD_AGAIN; + break; + } + break; + case S_REC_CHECK_CARD_VALIDITY: + if(UseExternalVC()) + { + shmp->process_info.sub_state_2 = 0; + shmp->process_info.sub_state = S_REC_CHECK_CARD_WITH_RCM; + return retval; + } + if(OCS_with_external_CRM()) + { + shmp->process_info.sub_state_2 = 0; + shmp->process_info.sub_state = S_REC_CHECK_CARD_WITH_CRM; + return retval; + } + + if(pps_get_adaptor_flag()) + { + shmp->process_info.sub_state_2 = 0; + shmp->process_info.sub_state = S_REC_CHECK_CARD_WITH_REST; + strcpy((char *)shmp->origin_info.number, (char *)shmp->called_info.number); + + return retval; + } + + if(CheckWetherValidRechargeCard(portid, (char *)shmp->called_info.number, &result)==0) + { + if(result == 5) /* too much money in account */ + return ( retval = rec_mng_exit ); + else + { + shmp->process_info.sub_state = S_REC_INPUT_PWD_AGAIN; + return retval; + } + } + else + { + shmp->process_info.serviceInput = 0; + } + RechargeRequestProc(portid); + shmp->process_info.srfRelease = 0; + shmp->process_info.maxPCUInfoLen = 1; + SendRechargeInfoPromptToSrf(portid); + shmp->process_info.sub_state = S_REC_WAIT_SRR; + break; + break; + case S_REC_INPUT_PWD_AGAIN: + if(shmp->process_info.serviceInput ++ >SERVICE_INPUT_NUM) + { + return ( retval = rec_mng_exit ); + } + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = RECHARGE_FAILED; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_REC_CHECK_PWD; + break; + case S_REC_CHECK_CARD_WITH_RCM: + switch(shmp->process_info.sub_state_2 ) + { + case 0: + send_scf_update_card_data(portid); + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + shmp->process_info.update_card_ack = 0; + break; + case 1: + if(shmp->process_info.funnel > SSHORT_DELAY_TIMER) + { + if(shmp->process_info.serviceInput ++>3) + { + return rec_mng_exit; + } + shmp->process_info.sub_state_2 = 0; + return retval; + } + if(!shmp->process_info.update_card_ack) + { + return retval; + } + if(shmp->process_info.update_card_result != OC_RESULT_OK) + { + RechargeFailedUpdateAccountData(portid); + shmp->process_info.sub_state = S_REC_INPUT_PWD_AGAIN; + return retval; + } + RechargeRequestProc(portid); + shmp->process_info.srfRelease = 0; + shmp->process_info.maxPCUInfoLen = 1; + SendRechargeInfoPromptToSrf(portid); + shmp->process_info.sub_state = S_REC_WAIT_SRR; + break; + default: + return rec_mng_exit; + break; + } + break; + case S_REC_CHECK_CARD_WITH_CRM: + switch(shmp->process_info.sub_state_2 ) + { + case 0: + pps_send_selfcare_topup_req(portid); + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + shmp->process_info.rest_if.recv_cmd = 0; + break; + case 1: + if(shmp->process_info.funnel > SSHORT_DELAY_TIMER) + { + if(shmp->process_info.serviceInput ++>3) + { + return rec_mng_exit; + } + shmp->process_info.sub_state_2 = 0; + return retval; + } + if(!shmp->process_info.rest_if.recv_cmd) + { + return retval; + } + if(shmp->process_info.rest_if.result) + { + RechargeFailedUpdateAccountData(portid); + shmp->process_info.sub_state = S_REC_INPUT_PWD_AGAIN; + return retval; + } + RechargeSucceedwithCRM(portid); + + shmp->process_info.srfRelease = 0; + shmp->process_info.maxPCUInfoLen = 1; + SendRechargeInfoPromptToSrf(portid); + shmp->process_info.sub_state = S_REC_WAIT_SRR; + break; + default: + return rec_mng_exit; + break; + } + break; + case S_REC_WAIT_SRR: + + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + return retval; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"< Error message received >"); + } + } + AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir); + + retval = rec_mng_exit; + break; + case S_REC_CHECK_CARD_WITH_REST: + tmpval = pps_rest_topup_process(portid); + if(tmpval == 0) + return retval; + if(tmpval == 1) + { + retval = rec_mng_exit; + } + else + { + shmp->process_info.srfRelease = 1; + shmp->process_info.voiceID = RECHARGE_FAILED; + SendSrfPlayAnnouncement(portid); + shmp->process_info.tcos = NORMAL_CLEARING; + shmp->process_info.sub_state = S_REC_WAIT_SRR; + return retval; + } + + break; + case S_REC_CHECK_CARD_WITH_REST_GET: + tmpval = pps_rest_query_process(portid); + if(tmpval == 0) + return retval; + + shmp->process_info.srfRelease = 0; + shmp->process_info.maxPCUInfoLen = 1; + SendRestRechargeInfoPromptToSrf(portid); + shmp->process_info.sub_state = S_REC_WAIT_SRR; + + break; + } + return retval; +} + +/* ------------------- end of recharge functions ----------------*/ + +/* ------------------ favorite number management functions ------*/ + +int WaitingForFavoriteNumberFunctionResponse(u_short portid) +{ + + int retval=0,len,dlgid, + counter,msglen,serviceKey; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + _state_data *shmp; + + PutLogFunID("WaitingForFavoriteNumberFunctionResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) return retval; + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 4); + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = 4); + serviceKey = pPCUI->digitsResponse[2]&0x0F; + + counter = GetAccountFavoriteNumberCounter(&shmp->caller_info); + switch(serviceKey) + { + case 1: /* add */ + if(counter == MAX_FAVORITE_NUMBERS) + { + if(shmp->process_info.serviceInput ++ >=SERVICE_INPUT_NUM) + { + return 6; + } + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = FULL_FAVORITE_NUMBER; /* + main menu */ + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + return (retval = 4); + } + retval = 1; + break; + case 2: /* edit */ + if(counter==0) + { + if(shmp->process_info.serviceInput ++ >=SERVICE_INPUT_NUM) + { + return 6; + } + shmp->process_info.srfRelease = 1; + shmp->process_info.voiceID = NO_FAVORITE_NUMBER; /* + main menu */ + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + return (retval = 4); + } + retval = 2; + break; + case 3: /* inquiry */ + if(counter<=0) + { + if(shmp->process_info.serviceInput ++ >=SERVICE_INPUT_NUM) + { + return 6; + } + shmp->process_info.srfRelease = 1; + shmp->process_info.voiceID = NO_FAVORITE_NUMBER; /*+ main menu */ + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + return (retval = 4); + } + retval = 3; + break; + case 0: // exit to main menu + retval = 5; + break; + default: + retval = 6; + break; + } + break; + default: + retval = 6; + break; + }/* swithc */ + + return retval; + +} + +int WaitingForFavoriteNumberAddResponse(u_short portid) +{ + int retval=0,len,dlgid, + msglen, errflag = 0; + char msisdn[32]; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + _state_data *shmp; + + PutLogFunID("WaitingForFavoriteNumberAddResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) return retval; + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 2); + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]-1; + if(len<0) len=0; + if(len >=MAX_MSISDN_BLEN+1 || len<2) + { + errflag = 1; + } + else + { + if(pPCUI->digitsResponse[1] & 0x20) + pPCUI->digitsResponse[len+1] |= 0xF0; + ppsBcdToAsciiR(msisdn,&pPCUI->digitsResponse[2],(len)*2); + StringCut(msisdn,'F'); + + strcpy(shmp->process_info.tmpDigits,msisdn); + + CutUnknownPrefix(msisdn); + if(CheckWetherFavoriteNumber(&shmp->caller_info, msisdn)==FAVORITE_NUMBER) + errflag = 2; + } + if(errflag>0) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 0); + } + shmp->process_info.srfRelease = 0; + if(errflag == 1) + shmp->process_info.voiceID = ERROR_FAVUMBER_INPUT_AND_INPUT_AGAIN; + else + shmp->process_info.voiceID = FAVUMBER_EXIST_INPUT_AGAIN; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + return (retval = 0); + + } + retval = 1; + break; + default: + retval = 2; + break; + }/* swithc */ + return retval; +} + +int WaitingForFavoriteNumberAddConfirmResponse(u_short portid) +{ + int retval=0,dlgid,msglen,instance, + key; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + CosFriendFamilyControl *serviceControlItem; + + _state_data *shmp; + + PutLogFunID("WaitingForFavoriteNumberAddConfirmResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval=4); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + key = pPCUI->digitsResponse[2]&0x0F; + + + if(key == 2)//cancel + { + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval=4); + } + retval = 2; + } + else if(key == 1)//confirm + { + + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = ADD_FAVORITE_NUMBER_SUC; /* + fav. main menu */ + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + + if(!shmp->process_info.editFavNumber) + { + StoreAccountFavoriteNumber(&shmp->caller_info, + shmp->process_info.tmpDigits, + 0); + + } + else + { + StoreAccountFavoriteNumber(&shmp->caller_info, + shmp->process_info.tmpDigits, + shmp->process_info.choice_sn); + + shmp->process_info.editFavNumber = 0; + serviceControlItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id].friendFamilyControl[0]; + if(serviceControlItem->friendFamilyChangeChargeFlag) + { + if(IncreaseFavoriteNumberChangeCounter(shmp->caller_info.head, + shmp->caller_info.tail)> + serviceControlItem->friendFamilyFreeChangeTimes) + { + BillingFavoriteNumberChange(shmp); + SendPPSGeneralCDR(shmp->caller_info.head, + shmp->caller_info.tail, + shmp->caller_info.charge, + CT_FF_NUMBER_EDIT); + } + } + } + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,-(shmp->caller_info.charge),0.0,OMC_OCODE_EDIT); + + retval = 1; + + }else //quit to main menu + { + retval = 3; + } + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 4; + break; + } + return retval; + +} + +int WaitingForEditFavoriteNumberSNResponse(u_short portid) +{ + int retval=0,len,dlgid, + msglen,sn,counter; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + _state_data *shmp; + + PutLogFunID("WaitingForEditFavoriteNumberSNResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + if(ReadScfMsg(&capmsg,dlgid)) + { + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 3); + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = 3); + len --; + sn = pPCUI->digitsResponse[2]&0x0F; + counter = GetAccountFavoriteNumberCounter(&shmp->caller_info); + + if(sn<1 || sn>counter ) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = NO_SUCH_SN_FAVORITE_NUMBER; /* input again */ + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + return (retval = 2); + } + shmp->process_info.choice_sn = sn; + shmp->process_info.editFavNumber = 1; + retval = 1; + break; + default: + retval = 3; + break; + }/* swithc */ + }/* if */ + return retval; +} + +int WaitingForInquiryFavoriteNumberSNResponse(u_short portid) +{ + int retval=0,len,dlgid, + msglen,sn,counter; + char msisdn[32]; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + _state_data *shmp; + + PutLogFunID("WaitingForInquiryFavoriteNumberSNResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) return retval; + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = 2); + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = 2); + + sn = pPCUI->digitsResponse[2]&0x0F; + + counter = GetAccountFavoriteNumber(&shmp->caller_info,msisdn,sn); + if(!counter ) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = 3); + } + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = NO_SUCH_SN_FAVORITE_NUMBER; /* + input serial no */ + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + return (retval = 2); + } + + + if(IsEnableToAddEditFavoriteNumber(shmp,0)) + shmp->process_info.voiceID = SN_X_FAVORITE_NUMBER_IS; /* + main menu */ + else if(IsEnableToAddEditFavoriteNumber(shmp,1)) + shmp->process_info.voiceID = FAVORITE_READ_NUMBER_DIDT_QUERY; /* + main menu */ + else + shmp->process_info.voiceID = FAVORITE_READ_NUMBER_QUERY; /* + main menu */ + + shmp->process_info.maxPCUInfoLen = 1; + + len = msisdn[MAX_MSISDN_BLEN-1]; + BcdToAscii(shmp->process_info.tmpDigits, (BYTE *)msisdn, (len+1)/2*2); + shmp->process_info.tmpDigits[len]=0; + + SendFavPromptAndCollectUserInfo(portid); + + shmp->process_info.serviceInput = 0; + retval = 1; + break; + default: + retval = 3; + break; + }/* swithc */ + + return retval; +} + +int FavoriteNumberManageProc(u_short portid) +{ + int retval,retval1; + + _state_data *shmp; + + PutLogFunID("FavoriteNumberManageProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = fav_mng_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + { + SendScfTcEND(portid); + return (retval = fav_mng_exit); + } + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = fav_mng_exit); + } + + switch(shmp->process_info.sub_state) + { + case S_FAV_PLAY_MENU: + shmp->process_info.funnel = 0; + if(IsEnableToAddEditFavoriteNumber(shmp,0)) + { + if(IsEnableToAddEditFavoriteNumber(shmp,1)) + shmp->process_info.voiceID = FAVORITE_NUMBER_FUNC; + else + shmp->process_info.voiceID = FAVORITE_NUMBER_FUNC_QUERY; /* play query voice */ + } + else if(IsEnableToAddEditFavoriteNumber(shmp,1)) + shmp->process_info.voiceID = FAVORITE_NUMBER_FUNC_EDIT_QUERY; /* play edit & query voice */ + else + shmp->process_info.voiceID = FAVORITE_NUMBER_FUNC_QUERY; /* play query voice */ + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.serviceInput = 0; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state = S_FAV_SET_TYPE; + break; + case S_FAV_SET_TYPE: + retval1 = WaitingForFavoriteNumberFunctionResponse(portid); + switch(retval1) + { + case 0: + break; + case 1: /* add */ + if(!IsEnableToAddEditFavoriteNumber(shmp,0)) + { + shmp->process_info.voiceID = FULL_FAVORITE_NUMBER; + shmp->process_info.sub_state = S_FAV_PLAY_MENU; + } + else + { + shmp->process_info.voiceID = INPUT_NEW_FAVORITE_NUMBER; + shmp->process_info.sub_state = S_FAV_INPUT_NEW_NUMBER; + } + break; + case 2: /* edit */ + if(!IsEnableToAddEditFavoriteNumber(shmp,1)) + shmp->process_info.sub_state = S_FAV_PLAY_MENU; + else + shmp->process_info.sub_state = S_FAV_INPUT_EDIT_NO; + break; + case 3: /* iquiry */ + shmp->process_info.sub_state = S_FAV_INQUIRY; + break; + case 4: + shmp->process_info.sub_state = S_FAV_SET_TYPE; + break; + case 5: /* to main menu */ + retval = fav_mng_exit_to_main_menu; + break; + case 6: /* exit */ + retval = fav_mng_exit; + break; + } + break; + case S_FAV_INPUT_NEW_NUMBER: + if(shmp->process_info.serviceInput++>3) + { + return (retval = fav_mng_exit); + } + + shmp->process_info.srfRelease = 0; + //shmp->process_info.voiceID = INPUT_NEW_FAVORITE_NUMBER; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_FAV_WAIT_NEW_NUMBER; + break; + case S_FAV_WAIT_NEW_NUMBER: + retval1 = WaitingForFavoriteNumberAddResponse(portid); + switch(retval1) + { + case 0: /* keep */ + break; + case 1: /* success */ + if(!IsFavoriteNumberTypeOk(shmp)) + { + shmp->process_info.voiceID = ERROR_FAVUMBER_INPUT_AND_INPUT_AGAIN; + shmp->process_info.sub_state = S_FAV_INPUT_NEW_NUMBER; + } + else + shmp->process_info.sub_state = S_FAV_SET_CONFIRM; + break; + case 2: + retval = fav_mng_exit; + break; + } + break; + case S_FAV_SET_CONFIRM: + shmp->process_info.srfRelease = 0;//2 + shmp->process_info.voiceID = TO_BE_ADDED_NUMBER_IS; + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.serviceInput = 0; + SendFavPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_FAV_WAIT_CONFIRM; + break; + case S_FAV_WAIT_CONFIRM: + retval1 = WaitingForFavoriteNumberAddConfirmResponse(portid); + switch(retval1) + { + case 1: /* confirm */ + shmp->process_info.sub_state = S_FAV_SET_TYPE; + break; + case 2: /* cancel */ + shmp->process_info.voiceID = INPUT_NEW_FAVORITE_NUMBER; + shmp->process_info.sub_state = S_FAV_INPUT_NEW_NUMBER; + break; + case 3: /* to fav. main menu */ + shmp->process_info.sub_state = S_FAV_PLAY_MENU; + break; + case 4: /* exit */ + retval = fav_mng_exit; + break; + } + break; + case S_FAV_INPUT_EDIT_NO: + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = INPUT_EDIT_FAVORITE_NUMBER_SN; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state = S_FAV_WAIT_EDIT_NO; + break; + case S_FAV_WAIT_EDIT_NO: + retval1 = WaitingForEditFavoriteNumberSNResponse(portid); + switch(retval1) + { + case 0: + break; + case 1: /* ok */ + shmp->process_info.voiceID = INPUT_NEW_FAVORITE_NUMBER; + shmp->process_info.sub_state = S_FAV_INPUT_NEW_NUMBER; + break; + case 2: /* no such serial no. input again */ + break; + case 3: + retval = fav_mng_exit; + break; + } + break; + case S_FAV_INQUIRY: + shmp->process_info.srfRelease = 1; + shmp->process_info.voiceID = INPUT_INQUIRY_FAVORITE_NUMBER_SN; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_FAV_INQUIRY_READ; + break; + case S_FAV_INQUIRY_READ: + retval1 = WaitingForInquiryFavoriteNumberSNResponse(portid); + switch(retval1) + { + case 0: + break; + case 1: + shmp->process_info.sub_state = S_FAV_SET_TYPE; + break; + case 2: + shmp->process_info.sub_state = S_FAV_INQUIRY_READ; + break; + case 3: + retval = fav_mng_exit; + break; + } + break; + } + return retval; +} + +/* ------------- language set functions --------------------*/ +int LanguageManagementProc(u_short portid) +{ + int retval,len,dlgid, + msglen,sn,instance; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp; + + PutLogFunID("LanguageManagementProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = language_mng_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + return (retval = language_mng_exit); + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = language_mng_exit); + } + + switch(shmp->process_info.sub_state) + { + case S_LANGUAGE_MANAGE_MENU: + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.voiceID = LANGUAGE_MANAGEMENT_MENU; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_LANGUAGE_SET; + break; + case S_LANGUAGE_SET: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = language_mng_exit); //timeout ,exit + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = language_mng_exit); //timeout ,exit + sn = pPCUI->digitsResponse[2] & 0x0F; + shmp->process_info.choice_sn = sn; + if( sn > MAX_LANGUAGE_TYPES) //max language types = 5 + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = language_mng_exit); + } + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.voiceID = INVALID_LANGUAGE_SELECTION_KEY; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_LANGUAGE_SET; + } + if(sn == 0) + { + return (retval = language_mng_exit_to_main_menu); + } + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.voiceID = YOUR_DEFAULT_LANGUAGE_SET_IS; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_LANGUAGE_SET_CONFIRM; + break; + default: + return (retval = language_mng_exit); + break; + } + break; + case S_LANGUAGE_SET_CONFIRM: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + + #if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } + #endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = language_mng_exit); //timeout ,exit + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = language_mng_exit); //timeout ,exit + sn = pPCUI->digitsResponse[2] & 0x0F; + if(sn == 1) //confirm + { + shmp->process_info.serviceInput = 0; + UpdateAccountDefaultLanguageType(&shmp->caller_info, + shmp->process_info.choice_sn-1); + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + + retval = language_mng_exit_to_main_menu; + } + else if(sn == 2) //re-input + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + return (retval = language_mng_exit); + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.voiceID = LANGUAGE_MANAGEMENT_MENU; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_LANGUAGE_SET; + } + else + { + retval = language_mng_exit_to_main_menu; + } + break; + default: + return (retval = language_mng_exit); + break; + } + break; + } + + return retval; +} +/* ------------- end of language set functions --------------------*/ + + +/* ------------- PIN set functions --------------------*/ +int PINManagementProc(u_short portid,u_char callingCardFlag) +{/* calling card*/ + int retval,len,dlgid, + msglen,instance; + char pin[MAX_PIN_LEN+1]; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp; + + PutLogFunID("PINManagementProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = pin_mng_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + return (retval = pin_mng_exit); + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = pin_mng_exit); + } + + switch(shmp->process_info.sub_state) + { + case S_PIN_INPUT_OLD_PIN: + shmp->process_info.maxPCUInfoLen = MAX_PIN_LEN; + shmp->process_info.voiceID = INPUT_OLD_PIN; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_CHECK_OLD_PIN; + break; + case S_PIN_CHECK_OLD_PIN: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = pin_mng_exit); //timeout ,exit + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = pin_mng_exit); //timeout ,exit + len --; + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len+1] |= 0xF0; + len =len * 2-1; + } + else + len *=2; + if( len != MAX_PIN_LEN) //max language types = 5 + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = pin_mng_exit); + } + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.voiceID = ERROR_PIN_LENGTH; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_CHECK_OLD_PIN; + return retval; + } + ppsBcdToAsciiR(shmp->process_info.tmpDigits, + &pPCUI->digitsResponse[2], + len); + shmp->process_info.tmpDigits[MAX_PIN_LEN] = 0; + if(!CheckPINValidity(&shmp->caller_info,shmp->process_info.tmpDigits)) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = pin_mng_exit); + } + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.voiceID = ERROR_PIN; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_CHECK_OLD_PIN; + return retval; + } + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state = S_PIN_MANAGE_MENU; + break; + } + break; + case S_PIN_MANAGE_MENU: + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.voiceID = INPUT_NEW_PIN; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_NEW_SET; + break; + case S_PIN_NEW_SET: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = pin_mng_exit); //timeout ,exit + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = pin_mng_exit); //timeout ,exit + len --; + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len+1] |= 0xF0; + len =len * 2-1; + } + else + len *=2; + if( len != MAX_PIN_LEN) //max language types = 5 + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = pin_mng_exit); + } + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.voiceID = ERROR_PIN_LENGTH; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_NEW_SET; + return retval; + } + ppsBcdToAsciiR(shmp->process_info.tmpDigits, + &pPCUI->digitsResponse[2], + len); + shmp->process_info.tmpDigits[MAX_PIN_LEN] = 0; + + DebugMsg(debugmib.display.asciiOut,"%s",shmp->process_info.tmpDigits); + + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.voiceID = INPUT_NEW_PIN_AGAIN; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_SET_AGAIN; + break; + default: + return (retval = pin_mng_exit); + break; + } + break; + case S_PIN_SET_AGAIN: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = pin_mng_exit); //timeout ,exit + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<2 || len>12) + return (retval = pin_mng_exit); //timeout ,exit + len --; + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len+1] |= 0xF0; + len =len * 2-1; + } + else + len *=2; + if( len != MAX_PIN_LEN) //max language types = 5 + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = pin_mng_exit); + } + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.voiceID = ERROR_PIN_LENGTH; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_SET_AGAIN; + return retval; + } + + ppsBcdToAsciiR(pin, + &pPCUI->digitsResponse[2], + len); + pin[MAX_PIN_LEN] = 0; + DebugMsg(debugmib.display.asciiOut,"%s-%s",pin,shmp->process_info.tmpDigits); + if(strcmp(pin,shmp->process_info.tmpDigits)) + { + if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM) + { + return (retval = pin_mng_exit); + } + shmp->process_info.maxPCUInfoLen = 6; + shmp->process_info.voiceID = TWO_PINS_NOT_MATCH; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_PIN_SET_AGAIN; + return retval; + } + shmp->process_info.tmpDigits[MAX_PIN_LEN] = 0; + shmp->process_info.serviceInput = 0; + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + UpdateAccountPIN(&shmp->caller_info,pin); + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + shmp->process_info.sub_state = S_PIN_SET_OK; + break; + default: + return (retval = pin_mng_exit); + break; + } + break; + case S_PIN_SET_OK: + if(!callingCardFlag) + shmp->process_info.voiceID = PIN_SET_OK; + else + shmp->process_info.voiceID = CallingCardPasswordSetSuccess; + shmp->process_info.voiceID = PIN_SET_OK; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_PIN_SET_OK_1; + shmp->process_info.funnel = 0; + break; + case S_PIN_SET_OK_1: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + retval = pin_mng_exit_to_main_menu; + break; + } + + return retval; +} +/* ------------- end of PIN set functions --------------------*/ + +int pps_routing_home_proc(u_short portid) +{ + int retval=0; + _state_data *shmp; + MapComSrv_struct com_data; + MapOprSrv_struct opr_srv; + struct MapPRN_Res *prn_res; + + u_char data_flow[256]; + + PutLogFunID("pps_routing_home_proc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.funnel++>(SSHORT_DELAY_TIMER)) + { + pps_send_map_close(portid); + shmp->process_info.routing_home_flag = 0; + return -1; + } + + switch(shmp->process_info.sub_state) + { + case 0: + pps_send_map_open(portid); + pps_send_routing_home_prn(portid); + shmp->process_info.sub_state = 1; + shmp->process_info.funnel = 0; + break; + case 1: + if(map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + u_char msglen; + msglen = data_flow[0] * 256 + data_flow[1]; + if((data_flow[9] != ProvRoamNum) || msglen<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait PRN_Res but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + return -1; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, PRN response \33[0m", + portid,shmp->context_info.map_did, data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = 2; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode PRN_Res failed \33[0m", + portid,shmp->context_info.map_did); + } + return -1; + } + + prn_res = &opr_srv.msg_list.prn_res; + ppsBcdToAsciiR(shmp->process_info.tmpDigits, &prn_res->roam_num[2], (prn_res->roam_num[0]-1)*2); + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, routing home number: %s \33[0m", + portid,shmp->context_info.map_did, shmp->process_info.tmpDigits); + pps_debug_map_msg(data_flow,0); + } + + retval = 1; + } + else + { + if(map_get_comdata_struct(&com_data,shmp->context_info.map_did)) + { + + if(com_data.message_type == MAP_OPEN) + { + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map Open Res. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + map_com_stof(&com_data,data_flow,0); + pps_debug_map_msg(data_flow,0); + } + } + else + { + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map com, type: %d @ %ld.%ld", + portid,shmp->context_info.map_did, + com_data.message_type, + tvnow.tv_sec,tvnow.tv_usec); + map_com_stof(&com_data,data_flow,0); + pps_debug_map_msg(data_flow,0); + } + retval = 1; + } + } + } + break; + } + return retval; +} + + +/* -------------------call distribution functions------------------*/ +int CheckCRDService(u_short portid) +{ + int retval; + int msglen,len; + char msisdn[32]; + u_short dlgid,correlationID; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + _state_data *shmp,*shmpconn; + + PutLogFunID("CheckCRDService"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = crd_keep_state; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + return (retval = crd_release_call); + + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = crd_release_call); + } + + switch(shmp->process_info.sub_state) + { + case S_CRD_CHECK_CALLER_INFO: + if(shmp->context_info.callType == CT_MF_CALL) + { + shmp->process_info.chargeOther = 2; + shmp->process_info.sub_state = S_CRD_CONNECT; + return retval; + } + /* + if(CheckWetherHPLMNUser(shmp->caller_info.number)) + { + shmp->process_info.sub_state = S_CRD_CONNECT; + } + */ + /* added by Pierre, 2005-11-28, + * for Local other network, CCNDC is the same */ + if(GetCRDDestination((char *)shmp->caller_info.number, + msisdn, + shmp->process_info.serviceType-SRV_CRD)) + { + shmp->process_info.sub_state = S_CRD_CONNECT; + } + else + {/* + shmp->process_info.funnel = 0; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_CRD_SRR; + */ + shmp->process_info.sub_state = S_CRD_INPUT_VOICEBOX; + shmp->process_info.serviceType = SRV_OTHER_VMS_MAITENANCE; + } + break; + case S_CRD_INPUT_VOICEBOX: + case S_CRD_SET_DEPOSIT: + if(shmp->context_info.callType == CT_MF_CALL) + { + shmp->process_info.funnel = 0; + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_CRD_SRR; + return retval; + } + shmp->process_info.maxPCUInfoLen = 16; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + shmp->process_info.voiceID = INPUT_VOICEBOX; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_CRD_SET_DESTINATION; + break; + case S_CRD_SET_DESTINATION: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + if(capmsg.msgOperaCode == CAP_OC_PromptAndCollectUserInformation) + { + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg((char *)&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval = crd_release_call); //timeout ,exit + } + pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + if(len<3 || len>12) + return (retval = crd_release_call); //timeout ,exit + len --; + memcpy(shmp->process_info.tmpNumber, + &pPCUI->digitsResponse[2], + len); + if(pPCUI->digitsResponse[1] & 0x20) + { + shmp->process_info.tmpNumber[len-1] |= 0xF0; + len =len * 2-1; + } + else + len *=2; + shmp->process_info.tmpNumber[MAX_MSISDN_BLEN-1] = len; + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_CRD_CONNECT; + } + shmp->process_info.chargeOther = 1; + break; + case S_CRD_CONNECT: + if(shmp->process_info.chargeOther == 1) + { + len = shmp->process_info.tmpNumber[MAX_MSISDN_BLEN-1]; + ppsBcdToAsciiR(msisdn,shmp->process_info.tmpNumber,(len+1)/2*2); + StringCut(msisdn,'F'); + } + else + { + strcpy(msisdn, (char *)shmp->caller_info.number); + } +// DebugMsg(debugmib.display.asciiOut,"voice box: %s",msisdn); + CutUnknownPrefix(msisdn); +// DebugMsg(debugmib.display.asciiOut,"voice box: %s,type:%d", +// msisdn,shmp->process_info.chargeOther); + //following 2 lines added 09-27 + len = strlen(msisdn); + if(len>18) len = 18; + shmp->process_info.tmpNumber[MAX_MSISDN_BLEN-1] = len; + ppsAsciiToBcdR(shmp->process_info.tmpNumber,msisdn,(len+1)/2*2); + + if(!GetCRDDestination(msisdn, + shmp->process_info.tmpDigits, + shmp->process_info.serviceType-SRV_CRD)) + /* don't want crd.c to include ppsm.h, serivceType changed to 0-2 */ + /* not VMS box number */ + { + shmp->process_info.voiceID = NO_SUCH_VOICEBOX; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state = S_CRD_SRR; + return (retval); /* special resource report ,2004-08-30*/ + } +// DebugMsg(debugmib.display.asciiOut,"VMS address: %s",shmp->process_info.tmpDigits); + + correlationID = shmp->process_info.correlationID; + shmpconn = (_state_data *)&smshm_ptr->state_data; + shmpconn += correlationID; + shmpconn->process_info.chargeOther = shmp->process_info.chargeOther; + memcpy(shmpconn->process_info.tmpNumber, + shmp->process_info.tmpNumber,12); + shmpconn->process_info.callConnected = 2; + strcpy(shmpconn->process_info.tmpDigits, + shmp->process_info.tmpDigits); + + retval = crd_release_call; + break; + case S_CRD_SRR: + dlgid = shmp->context_info.dialogue_id; + if(!ReadScfMsg(&capmsg,dlgid)) + break; + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&capmsg,0); + } + #endif + retval = crd_release_call; /* special resource report ,2004-08-30*/ + break; + } + + return retval; +} + +/* -------------------Gy/Ro interfaces -------------*/ + +#define PRINT_CALL_INFO() do { \ + \ + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) \ + { \ + DebugMsg(debugmib.display.asciiOut,"Call info: PID = [%04d]", pid); \ + DebugMsg(debugmib.display.asciiOut,"Caller info : %s (%d %d) status:%d,cosid:%d,balance: %.04f", \ + shmp->caller_info.number, \ + shmp->caller_info.head, \ + shmp->caller_info.tail, \ + shmp->caller_info.status, \ + shmp->caller_info.cos_id, \ + GetBalance(&shmp->caller_info)); \ + \ + if(shmp->process_info.state != S_GY_PS_INIT) \ + { \ + DebugMsg(debugmib.display.asciiOut,"Called info : %s (%d %d) status: %d,cosid:%d, balance: %.04f", \ + shmp->called_info.number, \ + shmp->called_info.head, \ + shmp->called_info.tail, \ + shmp->called_info.status, \ + shmp->called_info.cos_id, \ + GetBalance(&shmp->called_info)); \ + } \ + \ + DebugMsg(debugmib.display.asciiOut, \ + "Tariff :(%s) %s CT:%d DI:%d FreeTime:%d unit_time:%d Miniunit:%d Adj:%.04f ,CapFlag%d, Discount: %d", \ + shmp->charge_info.number, \ + shmp->process_info.tariff.bill_id, \ + shmp->process_info.tariff.call_type, \ + shmp->process_info.tariff.discountID, \ + shmp->process_info.tariff.free_time, \ + shmp->process_info.tariff.unit_time, \ + shmp->process_info.tariff.mini_unit, \ + shmp->process_info.tariff.adjustment, \ + shmp->process_info.tariff.cap_flag, \ + GetDiscount(tvnow.tv_sec,shmp->process_info.tariff.discountID)); \ + DebugMsg(debugmib.display.asciiOut, \ + "tierInfo:L-%d,A-(units:%d,bf:%.04f,lf:%.04f),B-(units:%d,bf:%.04f,lf:%.04f),C-(units:%d,bf:%.04f,lf:%.04f)", \ + shmp->process_info.tariff.tierRating.tierNumber, \ + shmp->process_info.tariff.tierRating.rating[0].units, \ + shmp->process_info.tariff.tierRating.rating[0].base_fee, \ + shmp->process_info.tariff.tierRating.rating[0].long_distance_fee, \ + shmp->process_info.tariff.tierRating.rating[1].units, \ + shmp->process_info.tariff.tierRating.rating[1].base_fee, \ + shmp->process_info.tariff.tierRating.rating[1].long_distance_fee, \ + shmp->process_info.tariff.tierRating.rating[2].units, \ + shmp->process_info.tariff.tierRating.rating[2].base_fee, \ + shmp->process_info.tariff.tierRating.rating[2].long_distance_fee); \ + }\ +}while(0) + +extern void SendGprsCDR(_account_info *caller_info,_state_data *shmp); +int pps_print_gy_msg(_gy_msg *gy_ptr) +{ + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Time: %ld.%03d, Ro CCR is received", tvnow.tv_sec,tvnow.tv_usec/1000); + DebugMsg(debugmib.display.asciiOut, + " msg type := %d, req type := %d, serice type := %d ", + gy_ptr->msg_type, gy_ptr->request_type, gy_ptr->service_type); + DebugMsg(debugmib.display.asciiOut, + " caller := %s, called := %s, ", + gy_ptr->msg_body.ccr.caller, gy_ptr->msg_body.ccr.called); + DebugMsg(debugmib.display.asciiOut, + " fd port := %d, app port := %d ", + gy_ptr->fd_port, gy_ptr->app_port); + + } + + return 1; +} + + + +int pps_get_number_from_sip_number(char *sip_number, char *number) +{ + int i; + int idd_flag=0; + int len = strlen(sip_number); + + if(len>MAX_ASCII_NUMBER_LEN) len = MAX_ASCII_NUMBER_LEN; + //memset(number, 0x00, MAX_ASCII_NUMBER_LEN); + + for(i=0; inumber, number); + + GetAccountPos(ptr);// get user data position by msisdn: [head]/[tail] + ptr->cos_id = GetAccountCosID( ptr);// user cos in user data + ptr->status = GetAccountStatus(ptr);// user status in user data + ptr->idd_flag = idd_flag; + + ptr->expired_flag = isAccountExpired(ptr);// expiration day in user data + + return 1; +} + + +/* ------------------Start of Ro Adaptor interfaces -------------*/ +int mapping_diameter_error_to_camel(int fd_result) +{ + int tcos=NORMAL_RELEASE; + + switch(fd_result) + { + case 4010: //DIAMETER_END_USER_SERVICE_DENIED + tcos = CALLER_STATUS_ERROR; + break; + case 4011: //DIAMETER_CREDIT_CONTROL_NOT_APPLICABLE + tcos = BOTH_USER_NOT_PREPAID; + break; + case 4012: //DIAMETER_CREDIT_LIMIT_REACHED + tcos = CALLER_CREDIT_OUT; + break; + case 5030: //DIAMETER_USER_UNKNOWN + tcos = BOTH_USER_NOT_PREPAID; + break; + case 5031: //DIAMETER_RATING_FAILED + tcos = TARIFF_NOT_SET; + break; + default: + tcos = TARIFF_NOT_SET; + break; + } + + return tcos; +} + +int start_pps_ocs_procedure(int flag, int nums) +{ + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + int port; + long long msisdn=86755900123; + int i; + + for(i=0;icaller_info.number, "%lld", msisdn+i*1000); + sprintf((char *)shmp->called_info.number, "%lld", msisdn+1+i*1000); + + if(flag == 0) + shmp->process_info.state = S_RO_ADAPTOR_CALL_INIT; + else + shmp->process_info.state = S_RO_ADAPTOR_SMS_INIT; + } + + return 1; +} + +extern int ocs_get_cellid_present_flag(); +int pps_ro_adaptor_call_init(u16 port) +{ + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + _gy_msg gy_msg; + _gy_ccr *ccr_ptr; + int used_duration = 0; + int vcs_enable = pps_get_adaptor_vcs_flag(); + + if( port >= MAX_FSM_PROCESS ) + { + return 0; + } + + shmp += port; + + shmp->process_info.ro_if.adaptor_enabled = 1; + + memset(&gy_msg, 0x00, sizeof(_gy_msg)); + + ccr_ptr = &gy_msg.msg_body.ccr; + + gy_msg.app_port = port; + gy_msg.fd_port = shmp->process_info.ro_if.fd_port; + gy_msg.msg_type = GY_MSG_CCR; + gy_msg.service_type = ST_CS_VOICE; + gy_msg.request_type = shmp->process_info.ro_if.request_type; + + if(shmp->process_info.duration>0) + used_duration = (shmp->process_info.duration - shmp->process_info.ro_if.last_updated_duration); + else + used_duration = 0; + if(used_duration<0) + used_duration = 0; + + shmp->process_info.ro_if.granted_value = 0; + shmp->process_info.ro_if.last_updated_duration = shmp->process_info.duration; + ccr_ptr->used_unit = used_duration / CYCLE_STATE_INTERVAL; + + if(shmp->process_info.serviceType == SRV_NORMAL_MT_CALL) + ccr_ptr->role_of_node = 1; + else if(shmp->process_info.serviceType == SRV_NORMAL_MF_CALL && vcs_enable) + ccr_ptr->role_of_node = 2; + else + ccr_ptr->role_of_node = 0; + + if(pps_get_ocs_proxy_nai_flag() == 0) + strcpy(ccr_ptr->caller, (char *)shmp->caller_info.number); + else + { + if(shmp->caller_info.nai == 0x91) + sprintf(ccr_ptr->caller, "+%s", shmp->caller_info.number); + else + strcpy(ccr_ptr->caller, (char *)shmp->caller_info.number); + } + + + if(shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + if(pps_get_ocs_proxy_nai_flag() == 0) + strcpy(ccr_ptr->origin_caller, (char *)shmp->origin_info.number); + else + { + if(shmp->origin_info.nai == 0x91) + sprintf(ccr_ptr->origin_caller, "+%s", shmp->origin_info.number); + else + strcpy(ccr_ptr->origin_caller, (char *)shmp->origin_info.number); + } + } + + memset(ccr_ptr->imsi, 0x00, 15); + { + if(vcs_enable) + { + char tmp_buf[32]; + if(pps_get_ocs_proxy_nai_flag() == 0) + strcpy(ccr_ptr->called, (char *)shmp->called_info.number); + else + { + if(shmp->called_info.nai == 0x91) + sprintf(ccr_ptr->called, "+%s", shmp->called_info.number); + else + strcpy(ccr_ptr->called, (char *)shmp->called_info.number); + } + if(shmp->process_info.serviceType == SRV_NORMAL_MT_CALL) + ppsBcdToAsciiR(tmp_buf, shmp->called_info.IMSI, 16); + else + ppsBcdToAsciiR(tmp_buf, shmp->caller_info.IMSI, 16); + tmp_buf[15] = '\0'; + strcpy(ccr_ptr->imsi, tmp_buf); + } + else + { + if (ccr_ptr->role_of_node == 1)// MT call + { + strcpy(ccr_ptr->called, (char *)shmp->called_info.number); + } + else + { + strcpy(ccr_ptr->called, (char *)shmp->charge_info.number); + } + } + } + + if(vcs_enable) + { + ccr_ptr->service_key = shmp->process_info.serviceKey; + strcpy(ccr_ptr->msc_addr, shmp->cdr_info.msc_addr); + strcpy(ccr_ptr->vlr_number, shmp->cdr_info.locationNumber); + } + + if(ocs_get_cellid_present_flag()) + { + ccr_ptr->cellid_presented = 1; + BcdToAscii(ccr_ptr->cellid, shmp->cdr_info.cgi, 14); + + } + else + ccr_ptr->cellid_presented = 0; + + if(gx_send_ccr_from_client(&gy_msg)) + shmp->process_info.ro_if.fd_port = gy_msg.fd_port; + + shmp->process_info.ro_if.recv_cmd = 0; + shmp->process_info.wait_timer = 0; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s, called=%s\r\n Send CCR, serivce type=%d, request type=%d\r\n", port, + tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number, + ST_CS_VOICE, gy_msg.request_type); + + if(vcs_enable) + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, vcs enable flag=%d, msc_addr=%s, vlr_num=%s\r\n", port, + tvnow.tv_sec, tvnow.tv_usec/1000, + vcs_enable, + shmp->cdr_info.msc_addr, ccr_ptr->vlr_number); + + } + + return 1; +} + +int pps_ro_call_wait_first_cca(u16 port) +{ + //disconnect/cancel received to cancel Ro + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if( port >= MAX_FSM_PROCESS ) + { + return 0; + } + + shmp += port; + + if(shmp->process_info.wait_timer ++ > 5*CYCLE_STATE_INTERVAL) + { + shmp->process_info.tcend = 1; + //ReleaseAll(port); + gx_release_port_for_timerout(shmp->process_info.ro_if.fd_port); + + return -1; + } + + if(shmp->process_info.ro_if.recv_cmd == 0) + return 0; + + if(shmp->process_info.ro_if.granted_value <= 0 || shmp->process_info.ro_if.result != 2001) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s, called=%s\r\nCCR is not authenticated, result=%d\r\n", port, + tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number, + shmp->process_info.ro_if.result); + + } + + shmp->process_info.tcos = mapping_diameter_error_to_camel(shmp->process_info.ro_if.result); + if(shmp->process_info.duration <= 0) //playannoucment here... + { + shmp->process_info.ro_if.adaptor_enabled = 0; + shmp->process_info.tcend = 1; + //ReleaseAll(port); + return -1; + } + return -1; + } + + + //shmp->caller_info.valid_time += shmp->process_info.ro_if.granted_value * CYCLE_STATE_INTERVAL; + //shmp->called_info.valid_time += shmp->process_info.ro_if.granted_value * CYCLE_STATE_INTERVAL; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s, called=%s \r\n call valididty, caller valid_time=%d, called valid_time=%d\r\n", port, + tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number, + shmp->caller_info.valid_time, shmp->called_info.valid_time); + + } + + return 1; + +} + +int pps_ro_call_termiate(u16 port) +{ + int retval = 0; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if( port >= MAX_FSM_PROCESS ) + { + return 0; + } + + shmp += port; + + switch(shmp->process_info.sub_state) + { + case 0: + default: + shmp->process_info.ro_if.request_type = RT_TERMINATE_REQUEST; + shmp->process_info.duration += 1; //add 100ms to make sure qutation is correct in second + pps_ro_adaptor_call_init(port); + shmp->process_info.sub_state = 1; + break; + case 1: + if(pps_ro_call_wait_first_cca(port) != 0) + retval = 1; + break; + } + + return retval; +} + + +int pps_ro_adaptor_sms_init(u16 port) +{ + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + _gy_msg gy_msg; + _gy_ccr *ccr_ptr; + int vcs_enable = pps_get_adaptor_vcs_flag(); + + if( port >= MAX_FSM_PROCESS ) + { + return 0; + } + + shmp += port; + + shmp->process_info.ro_if.adaptor_enabled = 1; + + memset(&gy_msg, 0x00, sizeof(_gy_msg)); + + ccr_ptr = &gy_msg.msg_body.ccr; + + gy_msg.app_port = port; + gy_msg.msg_type = GY_MSG_CCR; + gy_msg.service_type = ST_CS_SMS; + gy_msg.request_type = RT_EVENT_REQUEST; + ccr_ptr->request_action = shmp->process_info.ro_if.request_action; + + strcpy(ccr_ptr->caller, (char *)shmp->caller_info.number); + if(vcs_enable) + { + char tmp_buf[32]; + + sprintf(ccr_ptr->caller, "+%s", shmp->caller_info.number); + + if(pps_get_ocs_proxy_nai_flag() == 0) + strcpy(ccr_ptr->called, (char *)shmp->called_info.number); + else + { + if(shmp->called_info.nai == 0x91) + sprintf(ccr_ptr->called, "+%s", shmp->called_info.number); + else + strcpy(ccr_ptr->called, (char *)shmp->called_info.number); + } + + //strcpy(ccr_ptr->called, shmp->called_info.number); + strcpy(ccr_ptr->vlr_number, shmp->cdr_info.locationNumber); + strcpy(ccr_ptr->msc_addr, shmp->cdr_info.smsc_addr); + ccr_ptr->service_key = shmp->process_info.serviceKey; + + ppsBcdToAsciiR(tmp_buf, shmp->caller_info.IMSI, 16); + tmp_buf[15] = '\0'; + strcpy(ccr_ptr->imsi, tmp_buf); + + } + else + { + strcpy(ccr_ptr->called, (char *)shmp->charge_info.number); + } + strcpy(ccr_ptr->smsc, shmp->cdr_info.smsc_addr); //pps_get_smsc_addr()); + + ccr_ptr->role_of_node = 0; + + if(ocs_get_cellid_present_flag()) + { + ccr_ptr->cellid_presented = 1; + BcdToAscii(ccr_ptr->cellid, shmp->cdr_info.cgi, 14); + + } + else + ccr_ptr->cellid_presented = 0; + + if(gx_send_ccr_from_client(&gy_msg)) + shmp->process_info.ro_if.fd_port = gy_msg.fd_port; + + shmp->process_info.ro_if.recv_cmd = 0; + shmp->process_info.wait_timer = 0; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + char debug_buf[1024]; + + sprintf(debug_buf, "\r\n [%04d] %s : request_action = %d, TS: %ld.%03ld\r\n", + port, __FUNCTION__, ccr_ptr->request_action, + tvnow.tv_sec, tvnow.tv_usec/1000); + + DebugMsg(debugmib.display.asciiOut, debug_buf); + } + + return 1; +} + +int pps_ro_sms_wait_first_cca(u16 port) +{ + //disconnect/cancel received to cancel Ro + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + + if( port >= MAX_FSM_PROCESS ) + { + return 0; + } + + shmp += port; + + if(shmp->process_info.wait_timer ++ > 5*CYCLE_STATE_INTERVAL) + { + shmp->process_info.tcend = 1; + //ReleaseAll(port); + gx_release_port_for_timerout(shmp->process_info.ro_if.fd_port); + return -1; + } + + if(shmp->process_info.ro_if.recv_cmd == 0) + return 0; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + char debug_buf[1024]; + + sprintf(debug_buf, "\r\n [%04d] %s : result = %d, TS: %ld.%03ld\r\n", + port, __FUNCTION__, shmp->process_info.ro_if.result, + tvnow.tv_sec, tvnow.tv_usec/1000); + + DebugMsg(debugmib.display.asciiOut, debug_buf); + } + + if(shmp->process_info.ro_if.result != 2001) + { + { + shmp->process_info.tcend = 1; + //ReleaseAll(port); + return -1; + } + } + + return 1; +} + +int pps_ro_sms_refund(u16 port) +{ + int retval = 0; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + char debug_buf[1024]; + + if( port >= MAX_FSM_PROCESS ) + { + return 0; + } + + //PutLogFunID("pps_ro_sms_refund"); + + shmp += port; + + switch(shmp->process_info.sub_state) + { + case 0: + shmp->process_info.ro_if.request_action = RA_REFUND_ACCOUNT; + pps_ro_adaptor_sms_init(port); + shmp->process_info.sub_state = 1; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + sprintf(debug_buf, "\r\n [%04d] %s : send CCR, TS: %ld.%03ld\r\n", + port, __FUNCTION__, + tvnow.tv_sec, tvnow.tv_usec/1000); + + DebugMsg(debugmib.display.asciiOut, debug_buf); + } + + break; + case 1: + if(pps_ro_call_wait_first_cca(port) == 0) + break; + retval = 1; + break; + } + + return retval; +} + + +/* ------------------End of Ro Adaptor interfaces -------------*/ + +int pps_ro_voice_process_with_ext_crm(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + char buf[128]; + int len, instance; + int return_duration=0; + float charge=0, pre_charge=0; + u_char cos_id = 0; + _account_info *pChargedUsrInfo = NULL; + + if( pid >= MAX_FSM_PROCESS ) + { + return 0; + } + + //PutLogFunID("pps_ro_voice_process_with_ext_crm"); + + shmp += pid; + switch(shmp->process_info.state) + { + case S_RO_VOC_INIT: + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + pChargedUsrInfo = &shmp->caller_info; + + if(shmp->called_info.idd_flag) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + + //cos_id = shmp->caller_info.cos_id; + } + else// SRV_NORMAL_MT_CALL + { + strcpy((char *)shmp->charge_info.number, (char *)shmp->caller_info.number); + pChargedUsrInfo = &shmp->called_info; + + if(shmp->caller_info.idd_flag) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + + //cos_id = shmp->called_info.cos_id; + } + + sprintf(buf, "%sE", shmp->caller_info.number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(shmp->cdr_info.caller, buf, len);// transfer to BCD for CDR + sprintf(buf, "%sE", shmp->called_info.number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(shmp->cdr_info.called, buf, len);// transfer to BCD for CDR + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + + SetCallType(shmp,shmp->process_info.tariff.call_type); + + PRINT_CALL_INFO(); + + shmp->process_info.funnel = 60 * CYCLE_STATE_INTERVAL;// init to a enouth long timer + shmp->process_info.state = S_RO_VOC_CONNECTED; + + // query tariff + //pps_send_query_tariff_req(pid); + //shmp->process_info.funnel = SSHORT_DELAY_TIMER*2; + //shmp->process_info.state = S_RO_VOC_GET_TARIFF_FROM_CRM; + case S_RO_VOC_CONNECTED: + if(shmp->process_info.funnel -- <= 0) + { + shmp->process_info.state = S_RO_VOC_RELEASE; + + gx_release_port_for_timerout(shmp->process_info.fd_port); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d, caller=%s, called=%s \r\n wait for CCR timer out, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + } + return 0; + } + if ((shmp->process_info.oc == RT_INITIAL_REQUEST) || (shmp->process_info.oc == RT_UPDATE_REQUEST)) + { + pps_send_query_tariff_req(pid); + shmp->process_info.oc = 0; + shmp->process_info.funnel = SSHORT_DELAY_TIMER*2; + shmp->process_info.state = S_RO_VOC_GET_TARIFF_FROM_CRM; + return 0; + } + else if(shmp->process_info.oc == RT_TERMINATE_REQUEST) + { + //gx_release_port_for_timerout(shmp->process_info.fd_port); + shmp->process_info.oc = 0; + shmp->process_info.state = S_RO_VOC_RELEASE; + + // send ccr-T + _gy_msg *gy_ptr = &shmp->process_info.ro_if.gy_ccr_info; + gy_ptr->msg_body.cca.result = 2001; + gy_ptr->msg_body.cca.grant_value = 0; + gy_ptr->msg_body.cca.is_final = 1; + gy_ptr->app_port = pid; + gy_ptr->msg_type = GY_MSG_CCA; + gx_handle_cca_from_server(gy_ptr);// response CCA + // + } + else + { + return 0; + } + case S_RO_VOC_RELEASE: + { + u32 refund_bundle = 0; + return_duration = shmp->process_info.charged_duration - + shmp->process_info.duration; + if(return_duration>0) + { + charge = pps_refund_ro_voice_with_crm(shmp, return_duration, &refund_bundle); + if (return_duration == shmp->process_info.charged_duration) + { + charge = shmp->charge_info.charge;// not used at all, so refund all charged balance + } + + if (charge >= 0.0001f)// update balance + { + pre_charge = shmp->charge_info.charge; + shmp->charge_info.charge = pre_charge - charge; + + UpdateAccountBalance(shmp->caller_info.head, shmp->caller_info.tail, charge); + + instance = shmp->called_info.head*UNIT_STORE_ACCOUNT + shmp->called_info.tail; + SendAccountRealSync(instance, charge, 0, OMC_OCODE_EDIT); + } + if ((refund_bundle > 0) && (shmp->process_info.rest_if.used_plan_value>=refund_bundle))// update bundle usage + { + shmp->process_info.rest_if.used_plan_value -= refund_bundle; + shmp->process_info.rest_if.plan_value_add_this_time = (0x8000000000000000) | refund_bundle; + pps_send_update_plan_value_req(pid); + } + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] , caller=%s, called=%s \r\n call duration[%d], charged duration[%d], refund bundle[%d], pre-charge = %.2f, return charge = %.2f", pid, + shmp->caller_info.number, shmp->called_info.number, + shmp->process_info.duration, shmp->process_info.charged_duration, refund_bundle, pre_charge, charge); + } + + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec - shmp->process_info.duration; + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + shmp->caller_info.charge = shmp->charge_info.charge; + } + else + { + shmp->called_info.charge = shmp->charge_info.charge; + } + shmp->process_info.duration = shmp->process_info.duration *CYCLE_STATE_INTERVAL; + + SendCDR(pid); + + ReleaseAll(pid); + return 1; + } + break; + case S_RO_VOC_GET_TARIFF_FROM_CRM: + if(shmp->process_info.funnel -- <= 0) + { + shmp->process_info.state = S_RO_VOC_RELEASE; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d, caller=%s, called=%s \r\n get tariff timer out, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + } + shmp->process_info.state = S_RO_VOC_RELEASE; + return 0; + } + + if(shmp->process_info.rest_if.query_tariff_status<2) + return 0; + + if (shmp->process_info.rest_if.query_tariff_status == 3 || shmp->process_info.rest_if.unit<=0) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d, caller=%s, called=%s \r\n no tariff or bundle, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + } + + shmp->process_info.state = S_RO_VOC_RELEASE; + break;//return 0; + } + + shmp->process_info.funnel = 120 * CYCLE_STATE_INTERVAL;// init to a enough long timer + shmp->process_info.state = S_RO_VOC_CONNECTED; + break; + } + + unsigned int granted_quota, new_assigned_quota = 0; + _gy_msg *gy_ptr = &shmp->process_info.ro_if.gy_ccr_info; + gy_ptr->msg_body.cca.result = 2001; + + if((gy_ptr->request_type == RT_TERMINATE_REQUEST) || (shmp->process_info.state == S_RO_VOC_RELEASE)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] caller=%s Call Terminated!", pid, shmp->caller_info.number); + + DebugMsg(debugmib.display.asciiOut, + " call duration = %d", shmp->process_info.duration); + } + + gy_ptr->msg_body.cca.grant_value = 0;//shmp->process_info.duration; + gy_ptr->msg_body.cca.is_final = 1; + + //shmp->process_info.oc = RT_TERMINATE_REQUEST; + granted_quota = 0; + } + else + { + int account_unnormal_status_flag = 0; + u32 unused_quota; + + // get acount status, normal or not; =============================== + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + //balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + if(shmp->caller_info.status != T_NORMAL) + account_unnormal_status_flag = 1; + if(shmp->caller_info.expired_flag) + account_unnormal_status_flag = 1; + } + else + { + //balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); + if(shmp->called_info.status != T_NORMAL) + account_unnormal_status_flag = 1; + if(shmp->called_info.expired_flag) + account_unnormal_status_flag = 1; + } + //======================================================= + + // calculate granted quota and new assigned quota========================= + unused_quota = shmp->process_info.charged_duration - shmp->process_info.duration; + int max_duration = pps_get_max_call_duration_in_second(); + if(account_unnormal_status_flag) + { + max_duration = 0; + granted_quota = 0; + } + else + { + if (unused_quota >= max_duration)// unused quota is enough for next grant + { + granted_quota = max_duration; + } + else + { + new_assigned_quota = max_duration - unused_quota; + } + } + //=================================================== + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, max quota[%d], unused[%d], need assign quota[%d]\r\n", pid, tvnow.tv_sec, tvnow.tv_usec/1000, + max_duration, unused_quota, new_assigned_quota); + } + + // Try to assigned new quota to meet max_dration, and charge and sync + if (new_assigned_quota > 0) + { + u32 new_assigned_bundle = 0; + charge = pps_billing_ro_voice_with_crm(shmp, &new_assigned_quota, &new_assigned_bundle); + if (charge >= 0.0001f)// update balance + { + shmp->charge_info.charge += charge; + UpdateAccountBalance(shmp->caller_info.head, shmp->caller_info.tail, -charge); + + instance = shmp->called_info.head*UNIT_STORE_ACCOUNT + shmp->called_info.tail; + SendAccountRealSync(instance, -charge, 0, OMC_OCODE_EDIT); + } + if (new_assigned_bundle > 0)// update bundle usage + { + shmp->process_info.rest_if.used_plan_value += new_assigned_bundle; + shmp->process_info.rest_if.plan_value_add_this_time = new_assigned_bundle; + pps_send_update_plan_value_req(pid); + } + + if ((new_assigned_quota + unused_quota) >= max_duration) + { + granted_quota = max_duration; + } + else + { + granted_quota = new_assigned_quota + unused_quota; + } + + shmp->process_info.charged_duration += new_assigned_quota; + } + // + + // Set is_final flag by granted_quota + if(granted_quota > 0) + { + + gy_ptr->msg_body.cca.is_final = 0; + } + else + { + gy_ptr->msg_body.cca.is_final = 1; + } + gy_ptr->msg_body.cca.grant_value = granted_quota; + // + } + + if(gy_ptr->request_type == RT_INITIAL_REQUEST) + shmp->process_info.funnel = (granted_quota + 35)*CYCLE_STATE_INTERVAL; + else + shmp->process_info.funnel = (granted_quota + 90)*CYCLE_STATE_INTERVAL; + + if(gy_ptr->msg_body.cca.is_final == 1) + { + if (gy_ptr->request_type != RT_TERMINATE_REQUEST) + { + gy_ptr->msg_body.cca.result = 4012; + } + shmp->process_info.state = S_RO_VOC_RELEASE; + } + + gy_ptr->app_port = pid; + + gy_ptr->msg_type = GY_MSG_CCA; + + gx_handle_cca_from_server(gy_ptr);// response CCA + + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + float balance = 0; + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + } + else + { + balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); + } + + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s, called=%s, Send CCA\r\n", pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + DebugMsg(debugmib.display.asciiOut, + " [%04d] Granted duration[%d], new allocated duration[%d], charge duration[%d], charged = %.2f, total charged = %.2f, balance = %.2f", pid, + granted_quota, new_assigned_quota, shmp->process_info.charged_duration, charge, shmp->charge_info.charge, balance); + } + } + return 1; +} + +int pps_ro_voice_process(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + char buf[128]; + int len, instance; + int return_duration=0; + float charge=0, pre_charge=0; + u_char cos_id = 0; + _account_info *pChargedUsrInfo = NULL; + + if(OCS_with_external_CRM()) + { + return pps_ro_voice_process_with_ext_crm(pid); + } + + if( pid >= MAX_FSM_PROCESS ) + { + return 0; + } + + //PutLogFunID("pps_ro_voice_process"); + + shmp += pid; + + switch(shmp->process_info.state) + { + case S_RO_VOC_INIT: + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + pChargedUsrInfo = &shmp->caller_info; + + if(shmp->called_info.idd_flag) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + + cos_id = shmp->caller_info.cos_id; + } + else// SRV_NORMAL_MT_CALL + { + strcpy((char *)shmp->charge_info.number, (char *)shmp->caller_info.number); + pChargedUsrInfo = &shmp->called_info; + + if(shmp->caller_info.idd_flag) + { + AddInterPrefix((char *)shmp->charge_info.number); + } + + cos_id = shmp->called_info.cos_id; + } + + sprintf(buf, "%sE", shmp->caller_info.number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(shmp->cdr_info.caller, buf, len);// transfer to BCD for CDR + sprintf(buf, "%sE", shmp->called_info.number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(shmp->cdr_info.called, buf, len);// transfer to BCD for CDR + + { + //CosServiceControl *serviceControlItem; + COSTable *cosTableItem; + + //serviceControlItem = &ppsParam.ppsTables.cosTable[cos_id].serviceControl[0]; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + pChargedUsrInfo->location = GetAccountZoneID(pChargedUsrInfo->head, pChargedUsrInfo->tail);// tariff ID is location? + + if(cosTableItem->tariff[0].chargeBy)// 0, by cos; 1, by location + { + pChargedUsrInfo->location = + findTariffIDByAPNName(shmp->process_info.ro_if.apn);// get tariff ID(location) by apn(Origin-Host) + + pps_print_event(shmp->process_info.logMsisdn,"%s charged by APN", shmp->process_info.ro_if.apn); + if(pChargedUsrInfo->location<0)// Can't charge by location, so charge by cos. + { + pps_print_error(shmp->process_info.logMsisdn,"%s isn't matched by cgi,so charged by cos", shmp->process_info.ro_if.apn); + pChargedUsrInfo->location = GetAccountZoneID(pChargedUsrInfo->head, pChargedUsrInfo->tail); + } + else + { + //CheckWetherRoamingUser(shmp); + + } + } + + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + shmp->process_info.tariff_flag = GetMOTariffData(shmp, + &shmp->process_info.tariff, + (char *)shmp->charge_info.number, + pChargedUsrInfo->location); + } + else + { + shmp->process_info.tariff_flag = GetMTTariffData(shmp, + pChargedUsrInfo->location, + &shmp->process_info.tariff, + pChargedUsrInfo, + &shmp->charge_info); + } + } + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + + SetCallType(shmp,shmp->process_info.tariff.call_type); + + PRINT_CALL_INFO(); + + shmp->process_info.funnel = 60 * CYCLE_STATE_INTERVAL;// init to a enouth long timer + shmp->process_info.state = S_RO_VOC_CONNECTED; + break; + case S_RO_VOC_CONNECTED: + if(shmp->process_info.funnel -- <= 0) + { + shmp->process_info.state = S_RO_VOC_RELEASE; + + gx_release_port_for_timerout(shmp->process_info.fd_port); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d, caller=%s, called=%s \r\n wait for CCR timer out, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + } + } + if(shmp->process_info.oc == RT_TERMINATE_REQUEST) + { + //gx_release_port_for_timerout(shmp->process_info.fd_port); + + shmp->process_info.state = S_RO_VOC_RELEASE; + } + break; + case S_RO_VOC_RELEASE: + { + u32 refund_bundle = 0; + return_duration = shmp->process_info.charged_duration - + shmp->process_info.duration; + if(return_duration>0) + { + charge = pps_refund_ro_voice(shmp, return_duration, &refund_bundle); + if (return_duration == shmp->process_info.charged_duration) + { + charge = shmp->charge_info.charge;// not used at all, so refund all charged balance + } + + if ((charge >= 0.0001f) || (refund_bundle > 0)) + { + pre_charge = shmp->charge_info.charge; + shmp->charge_info.charge = pre_charge - charge; + + if (shmp->process_info.serviceType == SRV_NORMAL_MO_CALL + ||shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + UpdateAccountBalance(shmp->caller_info.head, shmp->caller_info.tail, charge); + if (refund_bundle > 0) + pps_update_account_bundle_mo_voice(shmp, refund_bundle); + instance = shmp->caller_info.head*UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + } + else + { + UpdateAccountBalance(shmp->called_info.head, shmp->called_info.tail, charge); + if (refund_bundle > 0) + pps_update_account_bundle_mt_voice(shmp, refund_bundle); + instance = shmp->called_info.head*UNIT_STORE_ACCOUNT + shmp->called_info.tail; + } + + SendAccountRealSync(instance, charge, 0, OMC_OCODE_EDIT); + } + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] , caller=%s, called=%s \r\n call duration[%d], charged duration[%d], refund bundle[%d], pre-charge = %.2f, return charge = %.2f", pid, + shmp->caller_info.number, shmp->called_info.number, + shmp->process_info.duration, shmp->process_info.charged_duration, refund_bundle, pre_charge, charge); + } + + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec - shmp->process_info.duration; + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + shmp->caller_info.charge = shmp->charge_info.charge; + } + else + { + shmp->called_info.charge = shmp->charge_info.charge; + } + shmp->process_info.duration = shmp->process_info.duration *CYCLE_STATE_INTERVAL; + + SendCDR(pid); + + ReleaseAll(pid); + } + break; + } + + return 1; +} + +int ocs_gy_data_charge_process_with_ext_crm(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + char buf[128], retval_reason[256]; + int len, instance; + long return_data=0; + int retval; + _gprs_process *gprs_ptr = NULL; + + _gy_msg *gy_ptr = NULL; + + if(pid >= MAX_FSM_PROCESS) + return 0; + + //PutLogFunID("ocs_gy_data_charge_process_with_ext_crm"); + + shmp += pid; + gprs_ptr = &shmp->process_info.ppsService.gprs_process; + + gy_ptr = &shmp->process_info.ro_if.gy_ccr_info; + + if(shmp->process_info.state > S_GY_PS_INIT) + { + shmp->process_info.funnel --; + if(shmp->process_info.funnel <= 0) + { + shmp->process_info.state = S_GY_PS_RELEASE; + shmp->process_info.funnel = SSHORT_DELAY_TIMER; + gx_release_port_for_timerout(shmp->process_info.fd_port); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d , caller=%s, called=%s \r\n wait for tariff timeout, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + } + } + } + + switch(shmp->process_info.state) + { + case S_GY_PS_INIT: + sprintf(buf, "%sE", shmp->caller_info.number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(shmp->cdr_info.caller, buf, len);// transfer "12345678" to 0x21436587, and save in cdr caller num + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec;// Init access time and answer time + + + PRINT_CALL_INFO(); + + if((shmp->caller_info.status == T_FRESH) && (shmp->caller_info.headcaller_info.cos_id]; + if(cosTableItem->accountValidity[0].activiationByInquiryIs) + { + UpdateAccountStatus(shmp->caller_info.head, + shmp->caller_info.tail, + T_NORMAL); + UpdateAccountFirstUsedDate( + shmp->caller_info.head, + shmp->caller_info.tail); + UpdateExpirationFirstInquiry( + &shmp->caller_info, + cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance + ); + shmp->caller_info.expired_flag = isAccountExpired(&shmp->caller_info); + shmp->caller_info.status = T_NORMAL; + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP( + &shmp->caller_info, + shmp->called_info.number); + } + } + } + // shmp->process_info.state = S_GY_PS_GET_TARIFF_FROM_CRM; + //break; + //case S_GY_PS_GET_TARIFF_FROM_CRM: +#ifndef OCS_USE_REDIS_DB + pps_send_query_tariff_req(pid); +#endif + shmp->process_info.funnel = SSHORT_DELAY_TIMER; + shmp->process_info.state = S_GY_PS_GET_TARIFF_FROM_CRM_RES; + return 0; + break; + case S_GY_PS_GET_TARIFF_FROM_CRM_RES: +#ifndef OCS_USE_REDIS_DB + if(shmp->process_info.funnel <= 3) + { + gy_ptr->msg_body.cca.is_final = 0; + + gy_ptr->msg_body.cca.grant_value = shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime = 2048; + shmp->process_info.ro_if.result = 2001; + + gy_ptr->msg_body.cca.time_threshold = 120; + + //pps_send_query_tariff_req(pid); + + } + else + { + if(shmp->process_info.rest_if.query_tariff_status<2) + return 0; +#endif + if(1) + { + retval = allocate_ps_data_volume_quota(shmp, retval_reason); + switch(retval) + { + case 1: //NORMAL + shmp->process_info.ro_if.result = 2001; + break; + case 0: //No more Bundle + shmp->process_info.ro_if.result = 4010; + break; + case -1: //BLACKLISTED + shmp->process_info.ro_if.result = 5030; + //shmp->process_info.state = S_GY_PS_RELEASE; + break; + case -2: //NORMAL but EXPIRED + shmp->process_info.ro_if.result = 4012; + break; + case -3: //Max Qutoa + shmp->process_info.ro_if.result = 4012; + break; + case -4: //No Tariff + shmp->process_info.ro_if.result = 4012; + break; + case -5: //low balance + shmp->process_info.ro_if.result = 4012; + break; + } + } +#ifndef OCS_USE_REDIS_DB + } +#endif + shmp->process_info.funnel = (3600 + 5)*CYCLE_STATE_INTERVAL;// init to a enough long timer + shmp->process_info.state = S_GY_PS_CONNECTED; + + break; + case S_GY_PS_CONNECTED: + if(shmp->process_info.oc == RT_TERMINATE_REQUEST) + { + shmp->process_info.state = S_GY_PS_RELEASE; + shmp->process_info.oc = 0; + } + else if(shmp->process_info.oc == RT_UPDATE_REQUEST) + { + resetAccessTimeout(shmp);// every time receiving CCR Update, reset idle timer + shmp->process_info.oc = 0; + } + + if(isAccessTimeout(shmp))// check idle timer, release session if timeout + {// before releasing diameter, sending Abort-Session-Request to peer? + gx_release_port_for_timerout(shmp->process_info.fd_port); + + shmp->process_info.state = S_GY_PS_RELEASE; + + } + + shmp->process_info.duration ++; + if(0) + { + if((shmp->process_info.duration % (CYCLE_STATE_INTERVAL * 3600)) == 0)//to send GRPS cdr every 60 minutes + { + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->charge_info.charge = shmp->caller_info.charge; + + if(shmp->charge_info.charge != 0 || + shmp->process_info.ppsService.gprs_process.vqConsumed.integer != 0) + { + SendGprsCDR(&shmp->caller_info, shmp); + + shmp->process_info.ppsService.gprs_process.vqConsumed.integer = 0;// reset consumed + shmp->caller_info.charge = 0; + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + + } + } + + if((shmp->process_info.duration % (CYCLE_STATE_INTERVAL*5)) == 0)//every 5 seconds to get data tariff + { + //pps_send_query_tariff_req(pid); + } + } + + return 0; + break; + case S_GY_PS_WAIT_TERM: + if(shmp->process_info.funnel <= 0) + { + shmp->process_info.state = S_GY_PS_RELEASE; + + gx_release_port_for_timerout(shmp->process_info.fd_port); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d , caller=%s\r\nS_GY_PS_WAIT_TERM, release the PS session!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number); + } + } + return 0; + break; + case S_GY_PS_RELEASE: + + { + // return_data = shmp->process_info.ppsService.gprs_process.vqAllocated.integer - + return_data = shmp->process_info.ppsService.gprs_process.vqConsumed.integer - + shmp->process_info.ppsService.gprs_process.dqConsumed; + // if((return_data > 0) && (return_data <= (pps_get_quota_per_request() * 2))) + if((return_data > 0)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] caller=%s \r\nPS charged volume = %lld, consumed volume = %ld, return volume=%ld, total charge = %.2f", + pid, + shmp->caller_info.number, + shmp->process_info.ppsService.gprs_process.vqConsumed.integer, + shmp->process_info.ppsService.gprs_process.dqConsumed, + return_data, + shmp->caller_info.charge); + } + + shmp->process_info.ppsService.gprs_process.dqRefund = return_data; + pps_refund_data_volume(shmp); + + } + } + + //shmp->process_info.ppsService.gprs_process.vqConsumed.integer = + // shmp->process_info.ppsService.gprs_process.dqConsumed; + + + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->charge_info.charge = shmp->caller_info.charge; + + //if(shmp->charge_info.charge != 0 || + // shmp->process_info.ppsService.gprs_process.vqConsumed.integer != 0)// Used quota != 0 + if(shmp->process_info.ppsService.gprs_process.dqConsumed != 0)// Used quota != 0 + SendGprsCDR(&shmp->caller_info, shmp); + + ReleaseAll(pid); + return 1; + break; + } + + gy_ptr = &shmp->process_info.ro_if.gy_ccr_info; + + gy_ptr->msg_body.cca.result = shmp->process_info.ro_if.result; + shmp->process_info.oc = gy_ptr->request_type; + + if(gy_ptr->request_type == RT_TERMINATE_REQUEST) + { + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] PS Session Terminated, state=%d!", pid, shmp->process_info.state); + + DebugMsg(debugmib.display.asciiOut, + " data consumed = %ld", shmp->process_info.ppsService.gprs_process.dqConsumed); + } + + gy_ptr->msg_body.cca.grant_value = 0; + gy_ptr->msg_body.cca.is_final = 1; + + if (gprs_ptr->userType == PPS_PREPAID_USER) + { + shmp->process_info.state = S_GY_PS_RELEASE; + } + + retval = 0; + } + else + { + gy_ptr->msg_body.cca.is_final = 0; + + gy_ptr->msg_body.cca.grant_value = + shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime; + + if(gy_ptr->msg_body.cca.grant_value == 0) + { + //if( gy_ptr->request_type == RT_UPDATE_REQUEST) + { + if(shmp->process_info.ro_if.result == 5030 || + shmp->process_info.ro_if.result == 4010 ) + { + //gy_ptr->msg_body.cca.result = 4012; + //gy_ptr->msg_body.cca.is_final = 1; //final outside the criteria of UPDATE?? + shmp->process_info.state = S_GY_PS_WAIT_TERM; + shmp->process_info.funnel = 2*CYCLE_STATE_INTERVAL; + } + else + { + gy_ptr->msg_body.cca.time_threshold = 60; + //shmp->process_info.funnel = (60 + 2)*CYCLE_STATE_INTERVAL; + shmp->process_info.funnel = (900 + 10)*CYCLE_STATE_INTERVAL; + } + } + } + else + { + //if(shmp->process_info.bundle_flag == 1) + // shmp->process_info.rest_if.used_plan_value += gy_ptr->msg_body.cca.grant_value; + + gy_ptr->msg_body.cca.volume_threshold = gy_ptr->msg_body.cca.grant_value /5; + + if(ocs_get_threshold_supported()) + { + int inactive_timer; + + inactive_timer = pps_get_gprs_inactive_timer(shmp); + + if(pps_get_control_state()) + inactive_timer = inactive_timer / 2; + /* + if (gy_ptr->msg_body.cca.grant_value >= pps_get_quota_per_request()) + { + gy_ptr->msg_body.cca.volume_threshold = gy_ptr->msg_body.cca.grant_value /5; + } + else + { + gy_ptr->msg_body.cca.volume_threshold = 0; + } + */ + if(inactive_timer > 10) + gy_ptr->msg_body.cca.time_threshold = (inactive_timer * 8 / 10); + } + shmp->process_info.funnel = (3600 + 5)*CYCLE_STATE_INTERVAL; + } + } + + + gy_ptr->app_port = pid; + + gy_ptr->msg_type = GY_MSG_CCA; + + gx_handle_cca_from_server(gy_ptr);// response CCA + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + float balance = 0; + + balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s, result=%d, Send CCA\r\n", + pid, + tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, + gy_ptr->msg_body.cca.result); + DebugMsg(debugmib.display.asciiOut, + " [%04d] Granted volume = %ld, charge volume = %ld, consumed volume = %ld, total charged = %.2f, balance = %.2f", pid, + gy_ptr->msg_body.cca.grant_value, + shmp->process_info.ppsService.gprs_process.vqConsumed.integer, + shmp->process_info.ppsService.gprs_process.dqConsumed , + shmp->caller_info.charge, balance); + } + } + + return 1; +} + +int pps_gy_data_charge_process(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + char buf[128], retval_reason[256]; + int len, instance; + long return_data=0; + int retval; + + if(pid >= MAX_FSM_PROCESS) + return 0; + + //PutLogFunID("pps_gy_data_charge_process"); + + if(OCS_with_external_CRM()) + return ocs_gy_data_charge_process_with_ext_crm(pid); + + shmp += pid; + + + switch(shmp->process_info.state) + { + case S_GY_PS_INIT: + sprintf(buf, "%sE", shmp->caller_info.number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(shmp->cdr_info.caller, buf, len);// transfer "12345678" to 0x21436587, and save in cdr caller num + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec;// Init access time and answer time + + + PRINT_CALL_INFO(); + + if((shmp->caller_info.status == T_FRESH) && (shmp->caller_info.headcaller_info.cos_id]; + if(cosTableItem->accountValidity[0].activiationByInquiryIs) + { + UpdateAccountStatus(shmp->caller_info.head, + shmp->caller_info.tail, + T_NORMAL); + UpdateAccountFirstUsedDate( + shmp->caller_info.head, + shmp->caller_info.tail); + UpdateExpirationFirstInquiry( + &shmp->caller_info, + cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance + ); + shmp->caller_info.expired_flag = isAccountExpired(&shmp->caller_info); + shmp->caller_info.status = T_NORMAL; + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP( + &shmp->caller_info, + shmp->called_info.number); + } + } + } + + if(1) + { + retval = allocate_ps_data_volume_quota(shmp, retval_reason); + switch(retval) + { + case 1: //NORMAL + shmp->process_info.ro_if.result = 2001; + break; + case 0: //No more Bundle + shmp->process_info.ro_if.result = 4010; + break; + case -1: //BLACKLISTED + shmp->process_info.ro_if.result = 5030; + //shmp->process_info.state = S_GY_PS_RELEASE; + break; + case -2: //NORMAL but EXPIRED + shmp->process_info.ro_if.result = 4012; + break; + case -3: //Max Qutoa + shmp->process_info.ro_if.result = 4012; + break; + case -4: //No Tariff + shmp->process_info.ro_if.result = 4012; + break; + case -5: //low balance + shmp->process_info.ro_if.result = 4012; + break; + } + } + + shmp->process_info.funnel = (3600 + 5)*CYCLE_STATE_INTERVAL;// init to a enough long timer + shmp->process_info.state = S_GY_PS_CONNECTED; + /* + if(allocate_ps_data_volume_quota(shmp, retval_reason)< 1) + { + shmp->process_info.state = S_GY_PS_RELEASE; + } + else + { + shmp->process_info.state = S_GY_PS_CONNECTED; + } + */ + break; + case S_GY_PS_CONNECTED: + if(shmp->process_info.funnel -- <= 0) + { + shmp->process_info.state = S_GY_PS_RELEASE; + + gx_release_port_for_timerout(shmp->process_info.fd_port); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d , caller=%s, called=%s \r\n wait for CCR timer out, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + } + } + if(shmp->process_info.oc == RT_TERMINATE_REQUEST) + { + shmp->process_info.state = S_GY_PS_RELEASE; + shmp->process_info.oc = 0; + } + else if(shmp->process_info.oc == RT_UPDATE_REQUEST) + { + resetAccessTimeout(shmp);// every time receiving CCR Update, reset idle timer + shmp->process_info.oc = 0; + } + + if(isAccessTimeout(shmp))// check idle timer, release session if timeout + {// before releasing diameter, sending Abort-Session-Request to peer? + gx_release_port_for_timerout(shmp->process_info.fd_port); + + shmp->process_info.state = S_GY_PS_RELEASE; + + } + + shmp->process_info.duration ++; + if(0) + { + if((shmp->process_info.duration % (CYCLE_STATE_INTERVAL * 3600)) == 0)//to send GRPS cdr every 60 minutes + { + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->charge_info.charge = shmp->caller_info.charge; + + if(shmp->charge_info.charge != 0 || + shmp->process_info.ppsService.gprs_process.vqConsumed.integer != 0) + { + SendGprsCDR(&shmp->caller_info, shmp); + + shmp->process_info.ppsService.gprs_process.vqConsumed.integer = 0;// reset consumed + shmp->caller_info.charge = 0; + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + + } + } + } + + break; + case S_GY_PS_WAIT_TERM: + if(shmp->process_info.funnel -- <= 0) + { + shmp->process_info.state = S_GY_PS_RELEASE; + + gx_release_port_for_timerout(shmp->process_info.fd_port); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d , caller=%s\r\nWait for CCR timer out, release the PS session!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number); + } + } + + break; + case S_GY_PS_RELEASE: + { + // return_data = shmp->process_info.ppsService.gprs_process.vqAllocated.integer - + return_data = shmp->process_info.ppsService.gprs_process.vqConsumed.integer - + shmp->process_info.ppsService.gprs_process.dqConsumed; + // if((return_data > 0) && (return_data <= (pps_get_quota_per_request() * 2))) + if((return_data > 0)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] caller=%s \r\nPS charged volume = %lld, consumed volume = %ld, return volume=%ld, total charge = %.2f", + pid, + shmp->caller_info.number, + shmp->process_info.ppsService.gprs_process.vqConsumed.integer, + shmp->process_info.ppsService.gprs_process.dqConsumed, + return_data, + shmp->caller_info.charge); + } + + shmp->process_info.ppsService.gprs_process.dqRefund = return_data; + pps_refund_data_volume(shmp); + + } + } + + //shmp->process_info.ppsService.gprs_process.vqConsumed.integer = + // shmp->process_info.ppsService.gprs_process.dqConsumed; + + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->charge_info.charge = shmp->caller_info.charge; + + if(shmp->charge_info.charge != 0 || + shmp->process_info.ppsService.gprs_process.vqConsumed.integer != 0)// Used quota != 0 + SendGprsCDR(&shmp->caller_info, shmp); + + ReleaseAll(pid); + break; + } + + return 1; +} + + +static int pps_gy_data_postpaid_reqest(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + char buf[128]; + int len; + + if(pid >= MAX_FSM_PROCESS) + return 0; + + //PutLogFunID("pps_gy_data_postpaid_reqest"); + + shmp += pid; + + switch(shmp->process_info.oc) + { + case RT_INITIAL_REQUEST: + sprintf(buf, "%sE", shmp->caller_info.number); + len = (strlen(buf)+1)/2 * 2; + ppsAsciiToBcdR(shmp->cdr_info.caller, buf, len);// transfer "12345678" to 0x21436587, and save in cdr caller num + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec;// Init access time and answer time + shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime = pps_get_quota_per_request(); + //shmp->process_info.ppsService.gprs_process.vqAllocated.integer = shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime; + shmp->process_info.ro_if.result = 2001; + + shmp->process_info.funnel = (3600 + 5)*CYCLE_STATE_INTERVAL;// init to a enough long timer + shmp->process_info.oc = 0; + shmp->process_info.state = S_GY_PS_POSTPAID; + break; + case RT_UPDATE_REQUEST: + shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime = pps_get_quota_per_request(); + /*if (shmp->process_info.ppsService.gprs_process.vqAllocated.integer + >= (shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime + shmp->process_info.ppsService.gprs_process.dqConsumed)) + { + ; + } + else + { + shmp->process_info.ppsService.gprs_process.vqAllocated.integer += shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime; + }*/ + shmp->process_info.ro_if.result = 2001; + shmp->process_info.funnel = (3600 + 5)*CYCLE_STATE_INTERVAL; + shmp->process_info.oc = 0; + break; + case RT_TERMINATE_REQUEST: + shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime = 0; + shmp->process_info.funnel = 10*CYCLE_STATE_INTERVAL; + shmp->process_info.ro_if.result = 2001; + break; + default: + break; + } + + return 1; +} + + +static int pps_gy_data_postpaid_process(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + int rel_flag = 0; + + if(pid >= MAX_FSM_PROCESS) + return 0; + + //PutLogFunID("pps_gy_data_postpaid_process"); + + shmp += pid; + + shmp->process_info.duration ++; + if(shmp->process_info.funnel -- <= 0) + { + gx_release_port_for_timerout(shmp->process_info.fd_port); + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d , caller=%s \r\n wait for CCR timer out, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number); + } + + rel_flag = 1; + } + + if(shmp->process_info.oc == RT_TERMINATE_REQUEST) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d] TS: %ld.%03d , caller=%s \r\n recv terminate request, release the call!", + pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number); + } + + shmp->process_info.oc = 0; + rel_flag = 1; + } + + if (rel_flag) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "PS consumed volume = %ld", + shmp->process_info.ppsService.gprs_process.dqConsumed); + } + + shmp->cdr_info.releasetime = tvnow.tv_sec; + + ReleaseAll(pid); + } + + return 1; +} + + +static int pps_ro_event_sms_process(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + int instance; + CHARGED_FEE chargedFee; + u32 bundle_used_num; + + if( pid >= MAX_FSM_PROCESS ) + { + return 0; + } + + //PutLogFunID("pps_ro_event_sms_process"); + + shmp += pid; + switch(shmp->process_info.state) + { + case S_RO_EVENT_SMS_INIT: + shmp->process_info.funnel = (100)*CYCLE_STATE_INTERVAL;// init to a enough long timer + shmp->process_info.state = S_RO_EVENT_SMS_PROCESS; + break; + case S_RO_EVENT_SMS_PROCESS: + bundle_used_num = shmp->process_info.count; + switch(shmp->process_info.ro_if.request_action) + { + case RA_DIRECT_DEBITING: + UpdateBalance(shmp, &shmp->caller_info, -(shmp->caller_info.fee), &chargedFee);// reduce + + if(shmp->process_info.cap_flag) + { + UpdateSubsCapInfo(&shmp->caller_info, 1, (shmp->caller_info.fee), 0, shmp);// reduce + } + + if(shmp->process_info.bundle_flag) + { + pps_update_account_bundle_mo_sms(shmp, -bundle_used_num);// reduce + } + + if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_SMS) + { + IncreaseFriendFamilyFreeSMSCounter(shmp->caller_info.head, shmp->caller_info.tail); + } + + // Sync + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance, chargedFee.balance, chargedFee.promotion, OMC_OCODE_EDIT);// reduce + + // Send CDR + shmp->caller_info.charge = shmp->caller_info.fee;// reduce + SendSmsDirectDebitAndRefundCDR(shmp, bundle_used_num, 0); + + ReleaseAll(pid); + break; + case RA_REFUND_ACCOUNT: + if(shmp->process_info.bundle_flag)// has bundle, so only has to update bundle. + { + pps_update_account_bundle_mo_sms(shmp, bundle_used_num);// increase + shmp->caller_info.fee = 0.0; + } + else + { + UpdateBalance(shmp, &shmp->caller_info, (shmp->caller_info.fee), &chargedFee);// increase + + if(shmp->process_info.cap_flag) + { + UpdateSubsCapInfo(&shmp->caller_info, 1, -(shmp->caller_info.fee), 0, shmp);// increase + } + } + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + SendAccountRealSync(instance, chargedFee.balance, chargedFee.promotion, OMC_OCODE_EDIT);// increase + + shmp->caller_info.charge = -shmp->caller_info.fee;// increase + SendSmsDirectDebitAndRefundCDR(shmp, bundle_used_num, 1); + + ReleaseAll(pid); + break; + default: + break; + } + break; + } + + return 1; +} + + +static int pps_recv_ro_sms_request(_gy_msg *gy_ptr) +{ + int rst; + //_prepaid_data *pPrepaidData = &ramshm_ptr->prepaid_data; + _state_data state_data, *shmp = (_state_data *) &smshm_ptr->state_data; + COSTable *cosTableItem; + //CosServiceControl *serviceControlItem; + //CHARGED_FEE chargedFee; + int pid; + + //PutLogFunID("pps_recv_ro_sms_request"); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, CCR for Event Request of CS_SMS", tvnow.tv_sec, tvnow.tv_usec/1000); + DebugMsg(debugmib.display.asciiOut, + " fd_port=%04d, requested action[%d], sent sms num[%d]\r\n", gy_ptr->fd_port, \ + gy_ptr->msg_body.ccr.request_action, gy_ptr->msg_body.ccr.sent_msg_num); + } + + // check request action + if (((gy_ptr->msg_body.ccr.request_action != RA_DIRECT_DEBITING) \ + && (gy_ptr->msg_body.ccr.request_action != RA_REFUND_ACCOUNT))\ + || (gy_ptr->msg_body.ccr.sent_msg_num <= 0)) + { + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + goto out; + } + + shmp = &state_data; + memset(shmp, 0, sizeof(_state_data)); + shmp->context_info.callType = CT_MO_SM; + SetCallType(shmp, CT_MO_SM); + pps_get_gy_number(&shmp->caller_info, gy_ptr->msg_body.ccr.caller);// Get user data position and data by msisdn + pps_get_gy_number(&shmp->called_info, gy_ptr->msg_body.ccr.called);// Get user data position and data by msisdn + shmp->caller_info.cug_id = GetAccountCUG(&shmp->caller_info); + shmp->process_info.serviceType = GetServiceType(shmp); + strcpy((char *)shmp->charge_info.number, (char *)shmp->called_info.number); + + CHECK_MSISDN_LOG_LEVEL(); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " fd_port=%04d, caller[%s], called[%s]", gy_ptr->fd_port, \ + shmp->caller_info.number, shmp->called_info.number); + } + + // check if user not exist + if((shmp->caller_info.head>=MSISDN_HEAD_NUM) || (shmp->caller_info.tail>=MSISDN_HEAD_NUM)) + { + gy_ptr->msg_body.cca.result = 5030;// ER_DIAMETER_USER_UNKNOWN; + goto out; + } + + // check user status + switch (shmp->caller_info.status) + { + case T_NORMAL: + break; + case T_FRESH: + case T_SUSPEND: + if(shmp->process_info.serviceType == SRV_SCRATCH_CARD_RECHARGE || + shmp->process_info.serviceType == SRV_INQUIRY) + { + break; + } + default: + shmp->process_info.tcos = UNALLOCATED_NUMBER; + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + goto out; + } + + // check expiration + if (shmp->caller_info.expired_flag) + { + shmp->process_info.tcos= CALLER_EXPIRIED; + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + goto out; + } + + // Check favoriteCall + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + //serviceControlItem = &cosTableItem->serviceControl[0]; + if(cosTableItem->friendFamilyControl[0].friendFamilyFlag) + { + shmp->process_info.favoriteCall = CheckWetherFavoriteNumber(&shmp->caller_info,shmp->called_info.number); + } + + shmp->process_info.tcos = NORMAL_CLEARING; + shmp->caller_info.location = GetAccountZoneID(shmp->caller_info.head, shmp->caller_info.tail);// tariff ID + + int bundle_used_num = 0; + + switch(gy_ptr->msg_body.ccr.request_action) + { + case RA_DIRECT_DEBITING: + // is enabled to call=========================================== + bundle_used_num = BillingSMSProc(shmp, gy_ptr->msg_body.ccr.sent_msg_num); + shmp->process_info.count = bundle_used_num; + rst = isPoolChildReachSMSLimit(shmp); + if(rst) + { + switch(rst) + { + case 1: + shmp->process_info.tcos= CALLER_REACH_SMS_LIMIT; + break; + case 2: + shmp->process_info.tcos= CALLER_REACH_CHARGE_LIMIT; + break; + } + gy_ptr->msg_body.cca.result = 4010;// END_USER_SERVICE_DENIED; + goto out; + } + + if (shmp->caller_info.valid_time <= 0 ) + { + shmp->process_info.tcos= CALLER_CREDIT_OUT; + gy_ptr->msg_body.cca.result = 4012;// CREDIT_LIMIT_REACHED; + goto out; + } + //======================================================= + + /* main processor */ + + gy_ptr->msg_body.cca.result = 2001;// ER_DIAMETER_SUCCESS; + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut, "Ro SMS %d, dibeting: %.2f, sms num: %d, bundle sms: %d", + shmp->process_info.cap_flag, shmp->caller_info.charge, gy_ptr->msg_body.ccr.sent_msg_num, bundle_used_num); + } + break; + case RA_REFUND_ACCOUNT: + if (shmp->process_info.bundle_flag)// has bundle, so only has to update bundle. + { + bundle_used_num = gy_ptr->msg_body.ccr.sent_msg_num; + } + else + { + bundle_used_num = 0; + } + shmp->process_info.count = bundle_used_num; + + /* main processor */ + + gy_ptr->msg_body.cca.result = 2001;// ER_DIAMETER_SUCCESS; + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut, "Ro SMS %d, refund: %.2f, sms num: %d, bundle sms: %d", + shmp->process_info.cap_flag, shmp->caller_info.charge, gy_ptr->msg_body.ccr.sent_msg_num, bundle_used_num); + } + break; + default: + break; + } + + // assign handle port to process================================ + pid = AssignProcID(1); + if( pid >= MAX_FSM_PROCESS || pid<0) + { + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + goto out; + } + + _state_data *tmp_shmp = (_state_data *) &smshm_ptr->state_data; + tmp_shmp += pid; + memcpy(tmp_shmp, shmp, sizeof(_state_data)); + tmp_shmp->process_info.portid = pid; + tmp_shmp->context_info.mtype = CAP_O_OPEN;// set to this value for Ro and Gy request + tmp_shmp->process_info.state = S_RO_EVENT_SMS_INIT;// fsm state + tmp_shmp->process_info.ro_if.gy_ro_enable = 1;// set to 1 for Ro and Gy + tmp_shmp->process_info.ro_if.request_action = gy_ptr->msg_body.ccr.request_action; + tmp_shmp->process_info.count = gy_ptr->msg_body.ccr.sent_msg_num; + tmp_shmp->process_info.fd_port = gy_ptr->fd_port; + + pps_ro_event_sms_process(pid); + //===================================================== + +out: + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " fd_port=%04d, send CCA for Ro SMS Event Request, Result-Code[%d]!", gy_ptr->fd_port, gy_ptr->msg_body.cca.result); + } + + gy_ptr->msg_body.cca.is_final = 1; + gy_ptr->app_port = INVALID_GY_PORT; + gy_ptr->msg_type = GY_MSG_CCA; + + gx_handle_cca_from_server(gy_ptr);// response CCA + + return 1; +} + + +static int pps_ro_event_common_process(u_short pid) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + int instance; + _prepaid_info *user_ptr = NULL; + float charge, promo_charge, refund; + u_char promotion_used_flag = 0; + + if( pid >= MAX_FSM_PROCESS ) + { + return 0; + } + + //PutLogFunID("pps_ro_event_sms_process"); + + shmp += pid; + switch(shmp->process_info.state) + { + case S_RO_EVENT_COMMON_INIT: + shmp->process_info.funnel = (100)*CYCLE_STATE_INTERVAL;// init to a enough long timer + shmp->process_info.state = S_RO_EVENT_COMMON_PROCESS; + break; + case S_RO_EVENT_COMMON_PROCESS: + switch(shmp->process_info.ro_if.request_action) + { + case RA_DIRECT_DEBITING: + charge = shmp->caller_info.charge; + instance = shmp->caller_info.head*UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail]; + if(user_ptr->promo_balance >= charge) + { + UpdateAccountPromotionBalance(shmp->caller_info.head, shmp->caller_info.tail, -charge); + SendAccountRealSync(instance, 0, -charge, OMC_OCODE_EDIT); + + // send cdr + SendDirectDebitAndRefundCDR(&shmp->caller_info, -charge); + } + else + { + promo_charge = user_ptr->promo_balance; + charge = charge - promo_charge; + UpdateAccountPromotionBalance(shmp->caller_info.head, shmp->caller_info.tail, -promo_charge); + UpdateAccountBalance(shmp->caller_info.head, shmp->caller_info.tail, -charge); + + SendAccountRealSync(instance, -charge, -promo_charge, OMC_OCODE_EDIT); + + // send cdr + SendDirectDebitAndRefundCDR(&shmp->caller_info, -(charge+promo_charge)); + } + + ReleaseAll(pid); + break; + case RA_REFUND_ACCOUNT: + instance = shmp->caller_info.head*UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail]; + refund = shmp->caller_info.charge; + + if(isPromotionCanBeUsedForRoDebit(&shmp->caller_info)) + { + if(IsPromotionExpired(&shmp->caller_info) == 0) + { + promotion_used_flag = 1; + } + } + + if(promotion_used_flag && user_ptr->promo_balance>0) + { + UpdateAccountPromotionBalance(shmp->caller_info.head, shmp->caller_info.tail, refund); + SendAccountRealSync(instance, 0, refund, OMC_OCODE_EDIT); + } + else + { + UpdateAccountBalance(shmp->caller_info.head, shmp->caller_info.tail, refund); + SendAccountRealSync(instance, refund, 0, OMC_OCODE_EDIT); + } + + // send cdr + SendDirectDebitAndRefundCDR(&shmp->caller_info, refund); + + ReleaseAll(pid); + break; + default: + break; + } + break; + } + + return 1; +} + + +static int pps_recv_event_request(_gy_msg *gy_ptr) +{ + int flag_log_msisdn = 0; + _account_info user_info; + double user_balance = 0.0; + _prepaid_data *shmp = &ramshm_ptr->prepaid_data; + _prepaid_info *user_ptr = NULL; + //u_char promotion_used_flag = 0; + + //PutLogFunID("pps_recv_event_request"); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, CCR for Event Request", tvnow.tv_sec, tvnow.tv_usec/1000); + DebugMsg(debugmib.display.asciiOut, + " fd_port=%04d, requested action[%d]\r\n", gy_ptr->fd_port, gy_ptr->msg_body.ccr.request_action); + } + + // Check user num + pps_get_gy_number(&user_info, gy_ptr->msg_body.ccr.caller);// Get user data position and data by msisdn + if ((user_info.head < MSISDN_HEAD_NUM) && (user_info.tail < UNIT_STORE_ACCOUNT)) + { + COSTable *cosTableItem = NULL; + CosServiceControl *serviceControlItem = NULL; + + // check log msisdn + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + // Check Event Charging flag + cosTableItem = &ppsParam.ppsTables.cosTable[user_info.cos_id]; + serviceControlItem = &cosTableItem->serviceControl[0]; + if(!serviceControlItem->event_charging_flag) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, + " Event Charging is disabled!\r\n"); + } + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + goto out; + } + } + else + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " user num[%s] not exist!", user_info.number); + } + + gy_ptr->msg_body.cca.result = 5030;// ER_DIAMETER_USER_UNKNOWN; + if (gy_ptr->msg_body.ccr.request_action == RA_CHECK_BALANCE) + { + gy_ptr->msg_body.cca.check_balance_result = CBR_NO_CREDIT; + } + + goto out; + } + + user_ptr = &shmp->prepaid_info[user_info.head][user_info.tail]; + user_balance = user_ptr->balance; + + if(isPromotionCanBeUsedForRoDebit(&user_info)) + { + if(IsPromotionExpired(&user_info) == 0) + { + user_balance = user_ptr->balance + user_ptr->promo_balance; + //promotion_used_flag = 1; + } + } + + switch(gy_ptr->msg_body.ccr.request_action)// Common DCCA event + { + case RA_DIRECT_DEBITING: + { + float charge; + + charge = gy_ptr->msg_body.ccr.req_service_unit; + if ((user_info.status == T_NORMAL) \ + && !user_info.expired_flag \ + && (user_balance >= charge)) + { + // assign handle port to process================================ + int pid = AssignProcID(1); + if( pid >= MAX_FSM_PROCESS || pid<0) + { + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + goto out; + } + + _state_data *tmp_shmp = (_state_data *) &smshm_ptr->state_data; + tmp_shmp += pid; + tmp_shmp->process_info.portid = pid; + tmp_shmp->context_info.mtype = CAP_O_OPEN;// set to this value for Ro and Gy request + tmp_shmp->process_info.state = S_RO_EVENT_COMMON_INIT;// fsm state + tmp_shmp->process_info.ro_if.gy_ro_enable = 1;// set to 1 for Ro and Gy + tmp_shmp->process_info.ro_if.request_action = gy_ptr->msg_body.ccr.request_action; + tmp_shmp->process_info.fd_port = gy_ptr->fd_port; + + memcpy(&tmp_shmp->caller_info, &user_info, sizeof(user_info)); + tmp_shmp->caller_info.charge = charge; + + pps_ro_event_common_process(pid); + //===================================================== + + /* main processor */ + + gy_ptr->msg_body.cca.result = 2001;// ER_DIAMETER_SUCCESS; + } + else + { + if (user_balance < charge) + { + gy_ptr->msg_body.cca.result = 4547;// for low balance + } + else + { + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + } + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, + " Direct Debiting, req_unit[%.2f], result-code[%d], pre balance[%.2f]\r\n", gy_ptr->msg_body.ccr.req_service_unit, \ + gy_ptr->msg_body.cca.result, user_balance); + } + } + break; + case RA_REFUND_ACCOUNT: + { + float refund; + + refund = gy_ptr->msg_body.ccr.req_service_unit; + if ((user_info.status == T_NORMAL) \ + && !user_info.expired_flag) + { + // assign handle port to process================================ + int pid = AssignProcID(1); + if( pid >= MAX_FSM_PROCESS || pid<0) + { + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + goto out; + } + + _state_data *tmp_shmp = (_state_data *) &smshm_ptr->state_data; + tmp_shmp += pid; + tmp_shmp->process_info.portid = pid; + tmp_shmp->context_info.mtype = CAP_O_OPEN;// set to this value for Ro and Gy request + tmp_shmp->process_info.state = S_RO_EVENT_COMMON_INIT;// fsm state + tmp_shmp->process_info.ro_if.gy_ro_enable = 1;// set to 1 for Ro and Gy + tmp_shmp->process_info.ro_if.request_action = gy_ptr->msg_body.ccr.request_action; + tmp_shmp->process_info.fd_port = gy_ptr->fd_port; + + memcpy(&tmp_shmp->caller_info, &user_info, sizeof(user_info)); + tmp_shmp->caller_info.charge = refund; + + pps_ro_event_common_process(pid); + //===================================================== + + /* main processor */ + + gy_ptr->msg_body.cca.result = 2001;// ER_DIAMETER_SUCCESS; + } + else + { + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, + " Refund Account, req_unit[%.2f], result-code[%d], old balance[%.2f]\r\n", gy_ptr->msg_body.ccr.req_service_unit, \ + gy_ptr->msg_body.cca.result, shmp->prepaid_info[user_info.head][user_info.tail].balance); + } + } + break; + case RA_CHECK_BALANCE: + { + //user_balance = shmp->prepaid_info[user_info.head][user_info.tail].balance; + + if ((user_info.status == T_NORMAL) \ + && !user_info.expired_flag \ + && (user_balance >= gy_ptr->msg_body.ccr.req_service_unit)) + { + gy_ptr->msg_body.cca.check_balance_result = CBR_ENOUGH_CREDIT; + } + else + { + gy_ptr->msg_body.cca.check_balance_result = CBR_NO_CREDIT; + } + + gy_ptr->msg_body.cca.result = 2001;// ER_DIAMETER_SUCCESS; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, + " Check Balance, req balance[%.2f], result[%s], user balance[%.2f]\r\n", gy_ptr->msg_body.ccr.req_service_unit, \ + (gy_ptr->msg_body.cca.check_balance_result == CBR_ENOUGH_CREDIT) ? "ENOUGH_CREDIT": "NO_CREDIT", user_balance); + } + } + break; + default : + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " requested action[%d] not support!", gy_ptr->msg_body.ccr.request_action); + } + + gy_ptr->msg_body.cca.result = 5012;// ER_DIAMETER_UNABLE_TO_COMPLY;// rejected for unspecified reasons. + } + break; + } + +out: + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, + " fd_port=%04d, send CCA for Event Request, Result-Code[%d]!", gy_ptr->fd_port, gy_ptr->msg_body.cca.result); + } + + gy_ptr->msg_body.cca.is_final = 1; + gy_ptr->app_port = INVALID_GY_PORT; + gy_ptr->msg_type = GY_MSG_CCA; + + gx_handle_cca_from_server(gy_ptr);// response CCA + + return 1; +} + + + + +static int pps_recv_gy_data_request(_gy_msg *gy_ptr) +{ + int pid; + int retval; + int inactive_timer; + char retval_reason[256]; + long postpaid_consumed_volume = 0;// do not charge a whole quota, after 2K is consumed + + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + _gprs_process *gprs_ptr = NULL; + + //PutLogFunID("pps_recv_gy_data_request"); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, CCR for PS\r\n", tvnow.tv_sec, tvnow.tv_usec/1000); + DebugMsg(debugmib.display.asciiOut, + " fd_port=%04d, app_port=%04d, request_type=%d, rg[%d], si[%d], rr[%d]\r\n", gy_ptr->fd_port, \ + gy_ptr->app_port, gy_ptr->request_type, gy_ptr->rating_group, gy_ptr->service_identifier, gy_ptr->msg_body.ccr.reporting_reason); + } + + if(gy_ptr->request_type == RT_INITIAL_REQUEST)// process Init request + { + pid = AssignProcID(1);// assign handle port + if( pid >= MAX_FSM_PROCESS || pid<0) + { + return 0; + } + + shmp += pid; + shmp->process_info.portid = pid; + shmp->process_info.call_type = CT_GPRS; + shmp->context_info.callType = CT_GPRS; + shmp->context_info.mtype = CAP_O_OPEN;// set to this value for Ro and Gy request + shmp->process_info.state = S_GY_PS_INIT;// fsm state + shmp->process_info.oc = gy_ptr->request_type; + shmp->process_info.ro_if.gy_ro_enable = 1;// set to 1 for Ro and Gy + shmp->process_info.ro_if.request_type = RT_INITIAL_REQUEST; + //shmp->process_info.ro_if.service_identifier = gy_ptr->service_identifier; + shmp->process_info.fd_port = gy_ptr->fd_port; + + gprs_ptr = &shmp->process_info.ppsService.gprs_process; + gprs_ptr->gsnIP = gy_ptr->msg_body.ccr.ggsn_ip; + gprs_ptr->sgsnIP = gy_ptr->msg_body.ccr.sgsn_ip; + gprs_ptr->destIP = gy_ptr->msg_body.ccr.ggsn_ip; + shmp->process_info.ppsService.gprs_process.update_quote_counter = 1; + { + int tmp_len; + char *dot_offset = NULL; + + if( (dot_offset = strstr(gy_ptr->msg_body.ccr.apn, "." )) != NULL)// Origin-Host in CCR, Charged by Location + { + tmp_len = dot_offset - gy_ptr->msg_body.ccr.apn; + memcpy(shmp->process_info.ro_if.apn, gy_ptr->msg_body.ccr.apn, tmp_len); + shmp->process_info.ro_if.apn[tmp_len] = '\0'; + } + + //DebugMsg(debugmib.display.asciiOut, + // " APN = %s", shmp->process_info.ro_if.apn); + + } + + pps_get_gy_number(&shmp->caller_info, gy_ptr->msg_body.ccr.caller);// Get user data position and data by msisdn + + CHECK_MSISDN_LOG_LEVEL(); + + if (pps_get_gy_postpaid_flag() \ + && ((shmp->caller_info.head > MSISDN_HEAD_NUM) || (shmp->caller_info.tail > UNIT_STORE_ACCOUNT))) + { + // process for postpaid user + gprs_ptr->userType = PPS_POSTPAID_USER; + pps_gy_data_postpaid_reqest(pid); + } + else + { + gprs_ptr->userType = PPS_PREPAID_USER; + if(OCS_with_external_CRM()) + { + //shmp->process_info.ro_if.gy_ccr_ptr = (void *)gy_ptr; + memcpy(&shmp->process_info.ro_if.gy_ccr_info, gy_ptr, sizeof(_gy_msg)); + shmp->process_info.funnel = SSHORT_DELAY_TIMER *CYCLE_STATE_INTERVAL; + return ocs_gy_data_charge_process_with_ext_crm(pid); + } + else + { + pps_gy_data_charge_process(pid); + } + } + } + else// handle Update and Terminate + { + pid = gy_ptr->app_port; + + if(pid >= MAX_FSM_PROCESS || pid<0) + { + DebugMsg(debugmib.display.asciiOut, "[%04d] Invalid PID for CCR!", pid); + return 0; + } + + shmp += pid; + gprs_ptr = &shmp->process_info.ppsService.gprs_process; + shmp->process_info.ro_if.request_type = gy_ptr->request_type; + //shmp->process_info.oc = gy_ptr->request_type; + + if(ocs_get_gy_report_data_metohd() == 0)// 0, Report individual Quota: Used-Service-Unit + shmp->process_info.ppsService.gprs_process.dqConsumed = + shmp->process_info.ppsService.gprs_process.dqConsumed + gy_ptr->msg_body.ccr.used_unit; + else// 1, Report total Quota: Used-Service-Unit + shmp->process_info.ppsService.gprs_process.dqConsumed = gy_ptr->msg_body.ccr.used_unit; + + if (gprs_ptr->userType == PPS_POSTPAID_USER)/* process for postpaid user */ + { + shmp->process_info.oc = gy_ptr->request_type; + pps_gy_data_postpaid_reqest(pid); + } + else + { + if(shmp->process_info.state == S_GY_PS_CONNECTED) + { + long not_consumed_volume = 0; + long max_quota_bytes = pps_get_quota_per_request(); + + if(shmp->process_info.ro_if.post_charge == 1) + { + if(shmp->process_info.ppsService.gprs_process.dqConsumed <= 10) //should be ZERO + { + shmp->process_info.ro_if.result = 2001; + goto send_cca_with_last_quota; + } + else + { + shmp->process_info.ppsService.gprs_process.vqAllocated.integer = + shmp->process_info.ppsService.gprs_process.dqConsumed; + not_consumed_volume = 0; + pps_charge_postpaid_data(shmp, shmp->process_info.ppsService.gprs_process.dqConsumed, &postpaid_consumed_volume); + shmp->process_info.ppsService.gprs_process.vqAllocated.integer = + shmp->process_info.ppsService.gprs_process.dqConsumed; + shmp->process_info.ro_if.post_charge = 0; + } + } + + if (shmp->process_info.ppsService.gprs_process.vqConsumed.integer > shmp->process_info.ppsService.gprs_process.dqConsumed) + { + not_consumed_volume = shmp->process_info.ppsService.gprs_process.vqConsumed.integer - + shmp->process_info.ppsService.gprs_process.dqConsumed; + } + + if(gy_ptr->request_type != RT_TERMINATE_REQUEST) + { + + if(1) + { + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] Session duration=%d, consumed data=%lld, update_timer=%d", + pid, + shmp->process_info.duration, shmp->process_info.ppsService.gprs_process.dqConsumed, + shmp->process_info.ppsService.gprs_process.update_quote_counter); + } + + if(shmp->process_info.duration > (CYCLE_STATE_INTERVAL * 3600 * shmp->process_info.ppsService.gprs_process.update_quote_counter)) + { + if(shmp->charge_info.charge != 0 || + //shmp->process_info.ppsService.gprs_process.dqConsumed != 0) + shmp->process_info.ppsService.gprs_process.dqConsumed >= 1048576)//only more than 1M , CDR will be generated + + { + shmp->cdr_info.releasetime = tvnow.tv_sec; + shmp->charge_info.charge = shmp->caller_info.charge; + + SendGprsCDR(&shmp->caller_info, shmp); + + //shmp->process_info.ppsService.gprs_process.vqConsumed.integer = 0;// reset consumed + shmp->process_info.ppsService.gprs_process.vqConsumed.integer -= shmp->process_info.ppsService.gprs_process.dqConsumed; + + shmp->process_info.ppsService.gprs_process.dqConsumed = 0; + shmp->caller_info.charge = 0; + + shmp->cdr_info.seizuretime = tvnow.tv_sec; + shmp->cdr_info.answertime = tvnow.tv_sec; + + } + shmp->process_info.ppsService.gprs_process.update_quote_counter ++; + } + } + + if(not_consumed_volume >= max_quota_bytes*8/10) + { + shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime = not_consumed_volume; + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] Not consumed volume=%ld, no new quato is charged!", pid, not_consumed_volume); + + } + } + else + { + if (gy_ptr->msg_body.ccr.reporting_reason == RR_QUOTA_EXHAUSTED) + { + if (shmp->process_info.bundle_flag && (not_consumed_volume < 1024)) + { + // set quota all used up + shmp->process_info.ppsService.gprs_process.dqConsumed += not_consumed_volume; + } + } + + // + if(OCS_with_external_CRM()) + { +#ifdef OCS_USE_REDIS_DB + memcpy(&shmp->process_info.ro_if.gy_ccr_info, gy_ptr, sizeof(_gy_msg)); + shmp->process_info.state = S_GY_PS_GET_TARIFF_FROM_CRM_RES; + return 0; +#endif + //shmp->process_info.ro_if.gy_ccr_ptr = (void *)gy_ptr; + + //shmp->process_info.state = S_GY_PS_GET_TARIFF_FROM_CRM; + //shmp->process_info.funnel = SSHORT_DELAY_TIMER *CYCLE_STATE_INTERVAL; + //update used plan value here... + //return ocs_gy_data_charge_process_with_ext_crm(pid); + } + // + + retval = allocate_ps_data_volume_quota(shmp, retval_reason); + switch(retval) + { + case 1: //NORMAL + shmp->process_info.ro_if.result = 2001; + break; + case 0: //No more Bundle + shmp->process_info.ro_if.result = 4010; + break; + case -1: //BLACKLISTED + shmp->process_info.ro_if.result = 5030; + break; + case -2: //NORMAL but EXPIRED + shmp->process_info.ro_if.result = 4012; + break; + case -3: //Max Qutoa + shmp->process_info.ro_if.result = 4012; + break; + case -4: //No Tariff + shmp->process_info.ro_if.result = 4012; + break; + case -5: //low balance + shmp->process_info.ro_if.result = 4012; + break; + } + } + } + } + else + { + shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime = 0; + } + + } + } + +send_cca_with_last_quota: + gy_ptr->msg_body.cca.result = shmp->process_info.ro_if.result; + shmp->process_info.oc = gy_ptr->request_type; + + if(gy_ptr->request_type == RT_TERMINATE_REQUEST) + { + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] PS Session Terminated, state=%d!", pid, shmp->process_info.state); + + DebugMsg(debugmib.display.asciiOut, + " data consumed = %ld", shmp->process_info.ppsService.gprs_process.dqConsumed); + } + + gy_ptr->msg_body.cca.grant_value = 0; + gy_ptr->msg_body.cca.is_final = 1; + + if (gprs_ptr->userType == PPS_PREPAID_USER) + { + shmp->process_info.state = S_GY_PS_RELEASE; + } + + retval = 0; + + } + else + { + gy_ptr->msg_body.cca.grant_value = + shmp->process_info.ppsService.gprs_process.vqAllocatedThisTime; + if ((gy_ptr->request_type == RT_UPDATE_REQUEST) && (postpaid_consumed_volume > 0) && (gy_ptr->msg_body.cca.grant_value > postpaid_consumed_volume)) + { + gy_ptr->msg_body.cca.grant_value -= postpaid_consumed_volume; + if (shmp->process_info.ppsService.gprs_process.vqAllocated.integer > postpaid_consumed_volume) + { + shmp->process_info.ppsService.gprs_process.vqAllocated.integer -= postpaid_consumed_volume; + shmp->process_info.ppsService.gprs_process.vqConsumed.integer -= postpaid_consumed_volume; + } + } + + + if(gy_ptr->msg_body.cca.grant_value == 0) + { + //if( gy_ptr->request_type == RT_UPDATE_REQUEST) + { + if(shmp->process_info.ro_if.result == 5030 || + shmp->process_info.ro_if.result == 4010 ) + { + //gy_ptr->msg_body.cca.result = 4012; + //gy_ptr->msg_body.cca.is_final = 1; //final outside the criteria of UPDATE?? + shmp->process_info.state = S_GY_PS_WAIT_TERM; + shmp->process_info.funnel = 2*CYCLE_STATE_INTERVAL; + } + else + { + gy_ptr->msg_body.cca.time_threshold = 60; + //shmp->process_info.funnel = (60 + 2)*CYCLE_STATE_INTERVAL; + shmp->process_info.funnel = (900 + 10)*CYCLE_STATE_INTERVAL; + } + } + } + else + { + if(ocs_get_threshold_supported()) + { + inactive_timer = pps_get_gprs_inactive_timer(shmp); + + if(pps_get_control_state()) + inactive_timer = inactive_timer / 2; + + if (gy_ptr->msg_body.cca.grant_value >= pps_get_quota_per_request()) + { + gy_ptr->msg_body.cca.volume_threshold = gy_ptr->msg_body.cca.grant_value /5; + } + else + { + gy_ptr->msg_body.cca.volume_threshold = 0; + } + + if(inactive_timer > 10) + gy_ptr->msg_body.cca.time_threshold = (inactive_timer * 8 / 10); + } + shmp->process_info.funnel = (3600 + 5)*CYCLE_STATE_INTERVAL; + } + } + + /* + if(gy_ptr->msg_body.cca.is_final == 1) + { + shmp->process_info.state = S_GY_PS_RELEASE ; + } + */ + + //shmp->process_info.funnel = (3600 + 5)*CYCLE_STATE_INTERVAL; + + gy_ptr->app_port = pid; + + gy_ptr->msg_type = GY_MSG_CCA; + + gx_handle_cca_from_server(gy_ptr);// response CCA + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + float balance = 0; + + balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s, result=%d, Send CCA\r\n", + pid, + tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, + gy_ptr->msg_body.cca.result); + DebugMsg(debugmib.display.asciiOut, + " [%04d] Granted volume = %ld, charge volume = %ld, consumed volume = %ld, total charged = %.2f, balance = %.2f", pid, + gy_ptr->msg_body.cca.grant_value, + shmp->process_info.ppsService.gprs_process.vqConsumed.integer, + shmp->process_info.ppsService.gprs_process.dqConsumed , + shmp->caller_info.charge, balance); + } + } + + return 1; +} +static int pps_recv_cca(_gy_msg *gy_ptr) +{ + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + + if(gy_ptr->app_port>=MAX_FSM_PROCESS) + return 0; + + shmp += gy_ptr->app_port; + + + shmp->process_info.ro_if.recv_cmd = 1; + shmp->process_info.ro_if.fd_port = gy_ptr->fd_port; + shmp->process_info.ro_if.result = gy_ptr->msg_body.cca.result; + shmp->process_info.ro_if.granted_value = gy_ptr->msg_body.cca.grant_value; + shmp->process_info.ro_if.is_final = gy_ptr->msg_body.cca.is_final; + + if(shmp->process_info.ro_if.granted_value>0) + { + shmp->caller_info.valid_time += shmp->process_info.ro_if.granted_value * CYCLE_STATE_INTERVAL; + shmp->called_info.valid_time += shmp->process_info.ro_if.granted_value * CYCLE_STATE_INTERVAL; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s \r\nRecv CCA, gy_port=%d, app_port=%d\r\n", gy_ptr->app_port, + tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, + gy_ptr->fd_port, gy_ptr->app_port); + + DebugMsg(debugmib.display.asciiOut, + " result=%d, granted_value=%d, is_final=%d\r\n", + shmp->process_info.ro_if.result, + shmp->process_info.ro_if.granted_value, + shmp->process_info.ro_if.is_final); + + } + + return 1; +} + +static int pps_recv_ro_voice_request(_gy_msg *gy_ptr) +{ + int pid; + unsigned int instance, granted_quota, new_assigned_quota = 0; + float charge=0; + int max_duration = 0; + //int delay_timer = 0; + float balance = 0; + + _state_data *shmp = (_state_data *) &smshm_ptr->state_data; + + //PutLogFunID("pps_recv_ro_voice_request"); + + pps_print_gy_msg(gy_ptr); + + if(gy_ptr->request_type == RT_INITIAL_REQUEST) + { + pid = AssignProcID(0); + if( pid >= MAX_FSM_PROCESS || pid<0) + { + return 0; + } + shmp += pid; + shmp->context_info.mtype = CAP_O_OPEN; + shmp->process_info.state = S_RO_VOC_INIT; + shmp->process_info.fd_port = gy_ptr->fd_port; + shmp->process_info.ro_if.gy_ro_enable = 1; + //shmp->process_info.ro_if.service_identifier = gy_ptr->service_identifier; + shmp->cdr_info.seizuretime = tvnow.tv_sec; + + switch(gy_ptr->msg_body.ccr.role_of_node )// avp Role-of-Node: 0/1/2, ORIGINATING_ROLE/T/F + { + case 0: + shmp->process_info.serviceType = SRV_NORMAL_MO_CALL; + shmp->context_info.callType = CT_MO_CALL; + break; + case 1: + shmp->process_info.serviceType = SRV_NORMAL_MT_CALL; + shmp->context_info.callType = CT_MT_CALL; + break; + case 2: + shmp->process_info.serviceType = SRV_NORMAL_MF_CALL; + shmp->context_info.callType = CT_MF_CALL; + break; + } + + pps_get_gy_number(&shmp->caller_info, gy_ptr->msg_body.ccr.caller); + pps_get_gy_number(&shmp->called_info, gy_ptr->msg_body.ccr.called); + + CHECK_MSISDN_LOG_LEVEL(); + { + int tmp_len; + char *dot_offset = NULL; + + if( (dot_offset = strstr(gy_ptr->msg_body.ccr.apn, "." )) != NULL)// get pod name from Origin-Host, charged by location + { + tmp_len = dot_offset - gy_ptr->msg_body.ccr.apn; + memcpy(shmp->process_info.ro_if.apn, gy_ptr->msg_body.ccr.apn, tmp_len); + shmp->process_info.ro_if.apn[tmp_len] = '\0'; + } + + //DebugMsg(debugmib.display.asciiOut, + // " APN = %s", shmp->process_info.ro_if.apn); + + } + /* + DebugMsg(debugmib.display.asciiOut, + " caller = %s", shmp->caller_info.number); + + DebugMsg(debugmib.display.asciiOut, + " called = %s", shmp->called_info.number); + */ + shmp->process_info.duration = 0; + if(OCS_with_external_CRM()) + { + memcpy(&shmp->process_info.ro_if.gy_ccr_info, gy_ptr, sizeof(_gy_msg)); + shmp->process_info.oc = RT_INITIAL_REQUEST; + shmp->process_info.funnel = SSHORT_DELAY_TIMER *CYCLE_STATE_INTERVAL; + return pps_ro_voice_process_with_ext_crm(pid); + } else { + pps_ro_voice_process(pid); + } + //delay_timer = pps_get_gy_delay_timer(0);// Init Request delay time? Not used! + } + else + { + pid = gy_ptr->app_port; + if( pid >= MAX_FSM_PROCESS || pid<0) + { + return 0; + } + + shmp += pid; + //delay_timer = pps_get_gy_delay_timer(1);// Update Request's delay time? Not used! + + shmp->process_info.duration += gy_ptr->msg_body.ccr.used_unit; + + } + + if(OCS_with_external_CRM()) + { + if(gy_ptr->request_type == RT_TERMINATE_REQUEST) + { + shmp->process_info.ro_if.gy_ccr_info.request_type = RT_TERMINATE_REQUEST; + shmp->process_info.oc = RT_TERMINATE_REQUEST; + } + else + { + shmp->process_info.ro_if.gy_ccr_info.request_type = RT_UPDATE_REQUEST; + shmp->process_info.oc = RT_UPDATE_REQUEST; + } + return 1; + } + + gy_ptr->msg_body.cca.result = 2001; + + if(gy_ptr->request_type == RT_TERMINATE_REQUEST) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + " [%04d] caller=%s Call Terminated!", pid, shmp->caller_info.number); + + DebugMsg(debugmib.display.asciiOut, + " call duration = %d", shmp->process_info.duration); + } + + gy_ptr->msg_body.cca.grant_value = shmp->process_info.duration; + gy_ptr->msg_body.cca.is_final = 1; + + shmp->process_info.oc = RT_TERMINATE_REQUEST; + granted_quota = 0; + //delay_timer = 0;// Terminate Request's delay time? Not used! + } + else + { + int account_unnormal_status_flag = 0; + u32 unused_quota; + + shmp = &smshm_ptr->state_data[pid]; + + // get acount status, normal or not; =============================== + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + //balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + if(shmp->caller_info.status != T_NORMAL) + account_unnormal_status_flag = 1; + if(shmp->caller_info.expired_flag) + account_unnormal_status_flag = 1; + } + else + { + //balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); + if(shmp->called_info.status != T_NORMAL) + account_unnormal_status_flag = 1; + if(shmp->called_info.expired_flag) + account_unnormal_status_flag = 1; + } + //======================================================= + + // calculate granted quota and new assigned quota========================= + unused_quota = shmp->process_info.charged_duration - shmp->process_info.duration; + max_duration = pps_get_max_call_duration_in_second(); + if(account_unnormal_status_flag) + { + max_duration = 0; + granted_quota = 0; + } + else + { + if (unused_quota >= max_duration)// unused quota is enough for next grant + { + granted_quota = max_duration; + } + else + { + new_assigned_quota = max_duration - unused_quota; + } + } + //=================================================== + + // Try to assigned new quota to meet max_dration, and charge and sync + if (new_assigned_quota > 0) + { + u32 new_assigned_bundle = 0; + charge = pps_billing_ro_voice(shmp, &new_assigned_quota, &new_assigned_bundle); + if((charge >= 0.0001f) || (new_assigned_bundle > 0)) + { + shmp->charge_info.charge += charge; + + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + UpdateAccountBalance(shmp->caller_info.head, shmp->caller_info.tail, -charge); + pps_update_account_bundle_mo_voice(shmp, -new_assigned_bundle); + + instance = shmp->caller_info.head*UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + } + else + { + UpdateAccountBalance(shmp->called_info.head, shmp->called_info.tail, -charge); + pps_update_account_bundle_mt_voice(shmp, -new_assigned_bundle); + + instance = shmp->called_info.head*UNIT_STORE_ACCOUNT + shmp->called_info.tail; + } + + SendAccountRealSync(instance, -charge, 0, OMC_OCODE_EDIT); + } + + if ((new_assigned_quota + unused_quota) >= max_duration) + { + granted_quota = max_duration; + } + else + { + granted_quota = new_assigned_quota + unused_quota; + } + + shmp->process_info.charged_duration += new_assigned_quota; + } + // + + // Set is_final flag by granted_quota + if(granted_quota > 0) + { + + gy_ptr->msg_body.cca.is_final = 0; + } + else + { + gy_ptr->msg_body.cca.is_final = 1; + } + gy_ptr->msg_body.cca.grant_value = granted_quota; + // + } + + //sleep(delay_timer); + if(gy_ptr->request_type == RT_INITIAL_REQUEST) + shmp->process_info.funnel = (granted_quota + 35)*CYCLE_STATE_INTERVAL; + else + shmp->process_info.funnel = (granted_quota + 5)*CYCLE_STATE_INTERVAL; + + if(gy_ptr->msg_body.cca.is_final == 1) + { + gy_ptr->msg_body.cca.result = 4012; + shmp->process_info.state = S_RO_VOC_RELEASE; + } + + gy_ptr->app_port = pid; + + gy_ptr->msg_type = GY_MSG_CCA; + + gx_handle_cca_from_server(gy_ptr);// response CCA + + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || + shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) + { + balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + } + else + { + balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); + } + + DebugMsg(debugmib.display.asciiOut, + " [%04d] TS: %ld.%03d, caller=%s, called=%s, Send CCA\r\n", pid, tvnow.tv_sec, tvnow.tv_usec/1000, + shmp->caller_info.number, shmp->called_info.number); + DebugMsg(debugmib.display.asciiOut, + " [%04d] Granted duration[%d], new allocated duration[%d], charge duration[%d], charged = %.2f, total charged = %.2f, balance = %.2f", pid, + granted_quota, new_assigned_quota, shmp->process_info.charged_duration, charge, shmp->charge_info.charge, balance); + } + } + return 1; +} + + +static int pps_recv_ro_gy_process(_gy_msg *gy_ptr) +{ + //PutLogFunID("pps_recv_ro_gy_process"); + + if(gy_ptr == NULL) + return 0; + + // process cca + if(gy_ptr->msg_type == GY_MSG_CCA) + return pps_recv_cca(gy_ptr); + + memset(&gy_ptr->msg_body.cca, 0x00, sizeof(_gy_cca)); + + // process event request + if (gy_ptr->request_type == RT_EVENT_REQUEST) + { + if (gy_ptr->service_type == ST_CS_SMS) + { + return pps_recv_ro_sms_request(gy_ptr);// Ro SMS + } + else + { + return pps_recv_event_request(gy_ptr);// Common DCCA Event + } + } + // + + if(gy_ptr->service_type == ST_PS_DATA) + { + return pps_recv_gy_data_request(gy_ptr); + } + else + { + return pps_recv_ro_voice_request(gy_ptr); + } +} + + +int pps_ro_gy_cb(_gy_msg *gy_ptr) +{ + //pthread_mutex_lock( &pps_mtx ); + pps_recv_ro_gy_process(gy_ptr); + //pthread_mutex_unlock( &pps_mtx ); + + return 1; +} + + +/* ------------------End of Gy/Ro interfaces -------------*/ + +/**---------------end of call distribution--------------------**/ +/**------------------------------------------------------**/ +extern int SmppRechargeProc(u_short portid); +extern int pps_crm_query_tariff_test_proc(u_short portid); +void CallProc() +{ + int portid,retval; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + for(portid=0; portidport_info[portid].status == 0x00) + { + continue; + } + + shmp = (_state_data *) smshm_ptr->state_data; + shmp += (portid); + + switch(shmp->process_info.state) + { + case S_IDLE: + if (shmp->context_info.new_flag == NO ) + { + // smshm_ptr->port_info[portid].status =0; + break; + } + shmp->context_info.new_flag = NO; + switch(shmp->context_info.mtype) + { + case CAP_O_OPEN: + shmp->process_info.state = S_WAITING_INITIALDP; + break; + case 0x80: + shmp->process_info.sub_state = S_MAP_SEND_OPENRSP; + shmp->process_info.state = S_MAP_STATE; + break; + case GPRS_O_OPEN: + shmp->process_info.ppsService.gprs_process.state = pps_gprs_idle; + shmp->process_info.state = S_GPRS_STATE; + break; + case VAS_O_OPEN: + shmp->process_info.ppsService.gprs_process.state = VAS_STATE_IDLE; + shmp->process_info.state = S_VAS_STATE; + break; + default: + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + break; + } + break; + case S_GPRS_STATE: + retval = pps_gprs_process(portid); + switch(retval) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + case SERVICE_EXIT_PPS: + default: + shmp->process_info.state = S_RELEASE_ALL; + break; + } + break; + case S_VAS_STATE: + retval = vasProcess(portid); + switch(retval) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + case SERVICE_EXIT_PPS: + default: + shmp->process_info.state = S_RELEASE_ALL; + break; + } + break; + case S_MAP_STATE: + retval = ppsMapState(portid); + if(retval != 0) + { + shmp->process_info.state = S_RELEASE_ALL; + } + break; + case S_WAITING_INITIALDP: + shmp->process_info.state = WaitingForInitialDP(portid); + break; + case S_SEND_MNP_ATI: + shmp->process_info.state = SendCallMNP_ATI(portid); + break; + case S_WAIT_MNP_ATI_RES: + retval = WaitingForMNP_ATI_Res(portid); + switch(retval) + { + case 0: + break; + case 1: /* get ati response */ + case -1: /* ati res timeout */ + shmp->process_info.state = S_CHECK_CALL_VALIDITY; + break; + default: + shmp->process_info.state = S_RELEASE_ALL; + break; + } + break; + case S_CHECK_CALL_VALIDITY: + shmp->process_info.state = CheckCallValidity(portid); + break; + case S_REQUEST_EVENTS: + shmp->process_info.state = RequestBCSMEvent(portid); + shmp->process_info.funnel = 0; + break; + case S_APPLY_CHARGING: + shmp->process_info.state = ApplyCharging(portid); + /* idle state to make interval between open confirm and the 2nd continue operation longer */ + break; + case S_APPLY_CHARGING_REAL: + shmp->process_info.state = ApplyCharging(portid); + break; + case S_SEND_CONTINUE: + shmp->process_info.state = ReleaseContinue(portid); + break; + case S_WAITINGFOR_EVENTS: + shmp->process_info.fsm_timer = 0; + if(shmp->process_info.ccc_flag == 0) + shmp->process_info.state = WaitingForEventsReport(portid); + else + shmp->process_info.state = WaitingForEventsReport_ccc(portid); + + break; + case S_WAITINGFOR_ANSWERED: + if(shmp->process_info.ccc_flag == 0) + shmp->process_info.state = WaitingforAnsweredProc(portid); + else + shmp->process_info.state = WaitingforAnsweredProc_ccc(portid); + break; + case S_RECHARGE_OVER: + debugmib.watch_dog[3] ++; + shmp->process_info.state = S_IDLE; + break; + case S_SEND_SMS_MNP_ATI: + shmp->process_info.state = SendSMSMNP_ATI(portid); + break; + case S_SMS_WAIT_MNP_ATI_RES: + retval = WaitingForSMSMNP_ATI_Res(portid); + switch(retval) + { + case 0: + break; + case 1: /* get ati response */ + case -1: /* ati res timeout */ + shmp->process_info.state = + S_SMS_CHECK_VALIDITY; + break; + default: + shmp->process_info.state = + S_RELEASE_ALL; + break; + } + break; + case S_SMS_CHECK_VALIDITY: + shmp->process_info.state = + CheckSMSValidity(portid); + break; + case S_REQUEST_SMS_EVENTS: + shmp->process_info.state = + RequestSMSEvents(portid); + break; + case S_RELEASE_SMS_CONTINUE: + shmp->process_info.state = + ReleaseContinueSMS(portid); + break; + case S_WAITINGFOR_SMS_EVENTS: + shmp->process_info.state = + WaitingForSMSEvents(portid); + break; + case S_ESTABLISH_TEMPORARY_CONNECTION: + shmp->process_info.state = + EstablishTemporaryConnection(portid); + break; + case S_DISCONNECT_FORWARD_CONNECTION: + shmp->process_info.state = + WaitingForDisconnectForwardConnection(portid); + break; + case S_SEND_RELEASE_CALL: + shmp->process_info.state = + SendSSFReleaseCall(portid); + break; + case S_SEND_PLAY_ANNOUNCEMENT: + shmp->process_info.state = + SendPlayAnnouncementOrPCUI(portid); + break; + case S_WAITING_SPECIAL_RESOURCE_REPORT: + shmp->process_info.state = + WaitingForSpecialResourceReport(portid); + break; + case S_WAITING_RR_PCUI: + shmp->process_info.state = + WaitingForRRofPromptAndCollectUserInfo(portid); + break; + case S_INQUIRY_MANAGE: + retval = InquiryManageProc(portid); + switch(retval) + { + case inq_mng_keep_state: + break; + case inq_mng_to_recharge: + + shmp->process_info.sub_state = S_REC_INQ_CHECK_MENU; + shmp->process_info.state = S_RECHARGE_MANAGE; + break; + case inq_mng_exit: + shmp->process_info.state = S_RELEASE_SRF; + break; + } + break; + case S_RECHARGE_MANAGE: + retval = RechargeManageProc(portid); + switch(retval) + { + case rec_mng_keep_state: + break; + case rec_mng_turn_to_ivr_scratch_card: + shmp->process_info.sub_state = S_CCR_CONNECT_TO_IVR_SCRATCH_CARD; + shmp->process_info.state = S_CREDIT_CARD_RECHARGE; + break; + case rec_mng_turn_to_credit_recharge: + shmp->process_info.sub_state = S_CCR_CONNECT_TO_CREDIT_CENTER; + shmp->process_info.state = S_CREDIT_CARD_RECHARGE; + break; + case rec_mng_exit: + default: + shmp->process_info.state = S_RELEASE_SRF; + break; + } + break; + case S_CREDIT_CARD_RECHARGE: + retval = creditCardRechargeProc(portid); + switch(retval) + { + case ccr_mng_keep_state: + break; + case ccr_mng_connect_to_credit_center: + default: + shmp->process_info.state = S_RELEASE_SRF; + break; + } + break; + case S_FAVORITE_NUMBER_MANAGE: + retval = FavoriteNumberManageProc(portid); + switch(retval) + { + case fav_mng_keep_state: + break; + case fav_mng_exit: + shmp->process_info.state = S_RELEASE_SRF; + break; + case fav_mng_exit_to_main_menu: + shmp->process_info.voiceID = SERVICE_SELECT_PROMPT; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.state = S_WAITING_RR_PCUI; + break; + } + break; + case S_LANGUAGE_MANAGEMENT: + retval = LanguageManagementProc(portid); + switch(retval) + { + case language_mng_keep_state: + break; + case language_mng_exit: + shmp->process_info.state = S_RELEASE_SRF; + break; + case language_mng_exit_to_main_menu: + shmp->process_info.voiceID = SERVICE_SELECT_PROMPT; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.state = S_WAITING_RR_PCUI; + break; + default: + shmp->process_info.state = S_RELEASE_SRF; + break; + } + break; + case S_PIN_MANAGEMENT: + retval = PINManagementProc(portid,0); + switch(retval) + { + case pin_mng_keep_state: + break; + case pin_mng_exit_to_main_menu: + shmp->process_info.voiceID = SERVICE_SELECT_PROMPT; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.state = S_WAITING_RR_PCUI; + break; + case pin_mng_exit: + default: + shmp->process_info.state = S_RELEASE_SRF; + break; + } + break; + case S_CALLING_CARD:/*calling card */ + retval = callingCardProc(portid); + switch(retval) + { + case pin_mng_keep_state: + break; + case pin_mng_exit: + default: + ReleaseSRF(portid); + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + break; + } + break; + case S_CC_CHECK_CALL_VALIDITY: + shmp->process_info.state = CheckCallValidity_ccc(portid); + break; + case S_CHARGE_OR_TRANSFER: + retval = chargeOrTransfer(portid); + switch(retval) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + retval = getInputtedChoice(shmp); + switch(retval) + { + case CONFIRM_OK: + shmp->process_info.sub_state = S_REC_CHECK_ACCOUNT_STATUS; + shmp->process_info.state = S_RECHARGE_MANAGE; + break; + case CONFIRM_ENTER_AGAIN: + default: + shmp->process_info.state = S_FEE_TRANSFER; + clearTransferInfo(portid); + break; + } + break; + case SERVICE_EXIT_PPS: + default: + ReleaseSRF(portid); + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + break; + } + break; + case S_FEE_TRANSFER: + retval = transferAccountIVRProc(portid); + switch(retval) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + case SERVICE_EXIT_PPS: + default: + shmp->process_info.state = S_RELEASE_SRF; + break; + } + break; + case S_POOL_ACCOUNT: + retval = masterSlaveIVRProc(portid); + switch(retval) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + case SERVICE_EXIT_PPS: + default: + shmp->process_info.state = S_RELEASE_SRF; + break; + } + break; + case S_RELEASE_SRF: + shmp->process_info.state = + ReleaseSRF(portid); + break; + case S_CRD_SERVICE: + retval = CheckCRDService(portid); + switch(retval) + { + case crd_keep_state: + break; + case crd_release_call: + shmp->process_info.state = + S_RELEASE_SRF; + break; + case crd_wait_answer: + default: + shmp->process_info.state = + S_RELEASE_SRF; + break; + } + + break; + + case S_SMMP_RECHAGE_ACCOUNT: + if(SmppRechargeProc(portid) != 0) + { + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + } + break; + + case S_RO_EVENT_SMS_INIT: + break;// do nothing + case S_RO_EVENT_SMS_PROCESS: + pps_ro_event_sms_process(portid); + break; + case S_RO_EVENT_COMMON_INIT: + break;// do nothing + case S_RO_EVENT_COMMON_PROCESS: + pps_ro_event_common_process(portid); + break; + + case S_RO_VOC_INIT: + break;// do nothing + case S_RO_VOC_CONNECTED: + case S_RO_VOC_RELEASE: + case S_RO_VOC_GET_TARIFF_FROM_CRM: + pps_ro_voice_process(portid); + break; + case S_GY_PS_INIT: + break;// do nothing + case S_GY_PS_CONNECTED: + case S_GY_PS_WAIT_TERM: + case S_GY_PS_RELEASE: + //case S_GY_PS_GET_TARIFF_FROM_CRM: + case S_GY_PS_GET_TARIFF_FROM_CRM_RES: + pps_gy_data_charge_process(portid); + break; + case S_GY_PS_POSTPAID: + pps_gy_data_postpaid_process(portid); + break; + + case S_RO_ADAPTOR_CALL_INIT: + shmp->process_info.ro_if.request_type = RT_INITIAL_REQUEST; + if(pps_ro_adaptor_call_init(portid)==1) + shmp->process_info.state = S_RO_CALL_WAIT_FIRST_CCA; + break; + case S_RO_CALL_WAIT_FIRST_CCA: + retval = pps_ro_call_wait_first_cca(portid); + if( retval == 1) + { + if(shmp->process_info.routing_home_flag == 1) + shmp->process_info.state = S_ROUTING_HOME_PRN; + else + shmp->process_info.state = S_REQUEST_EVENTS; + } + else if(retval == -1) + { + shmp->process_info.pre_warning = 0; + if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL) + { + shmp->process_info.playAnnouncement = 1; + shmp->process_info.state = S_REQUEST_EVENTS; + } + else + shmp->process_info.state = S_SEND_RELEASE_CALL; + } + break; + case S_RO_CALL_TERMIATED: + if(pps_ro_call_termiate(portid) == 1) + shmp->process_info.state = S_RELEASE_ALL; + break; + case S_RO_ADAPTOR_SMS_INIT: + shmp->process_info.ro_if.request_type = RT_INITIAL_REQUEST; + shmp->process_info.ro_if.request_action = RA_DIRECT_DEBITING; + if(pps_ro_adaptor_sms_init(portid)==1) + shmp->process_info.state = S_RO_SMS_WAIT_RESULT; + break; + case S_RO_SMS_WAIT_RESULT: + retval = pps_ro_sms_wait_first_cca(portid); + + if( retval == 1) + { + shmp->process_info.state = S_REQUEST_SMS_EVENTS; + } + else if (retval == -1) + { + SendReleaseSMS(portid); + shmp->process_info.state = S_RELEASE_ALL; + + } + break; + case S_RO_SMS_REFUND: + if(pps_ro_sms_refund(portid) == 1) + shmp->process_info.state = S_RELEASE_ALL; + break; + case S_ROUTING_HOME_PRN: + retval = pps_routing_home_proc(portid); + if(retval == 1) + { + shmp->process_info.state = S_REQUEST_EVENTS; + } + else if(retval < 0) + { + shmp->process_info.tcend = 1; + shmp->process_info.state = S_RELEASE_ALL; + } + break; + case S_SMPP_MAIN: + retval = pps_smpp_state(portid); + if(retval !=0 ) + { + ReleaseAll(portid); + } + break; + case S_CRM_QUERY_TARIFF_TEST: + retval = pps_crm_query_tariff_test_proc(portid); + if(retval != 0) + { + ReleaseAll(portid); + } + break; + case S_RELEASE_ALL: + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + break; + + default: + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + break; + } /* switch() */ + + if(shmp->process_info.state != S_IDLE) + shmp->process_info.fsm_timer++; + + if(shmp->process_info.state != S_IDLE && + shmp->process_info.state != S_WAITINGFOR_EVENTS && + shmp->process_info.state != S_GPRS_STATE + && shmp->process_info.state != S_GY_PS_CONNECTED + && shmp->process_info.state != S_RELEASE_ALL + && shmp->process_info.state != S_GY_PS_POSTPAID + && shmp->process_info.state != S_RO_VOC_GET_TARIFF_FROM_CRM + && shmp->process_info.state != S_RO_VOC_CONNECTED + && shmp->process_info.state != S_RO_VOC_RELEASE + ) + { + if(shmp->process_info.fsm_timer>PPS_FSM_TIMEROUT) + { + DebugMsg(debugmib.display.asciiOut,"Release port: %d in state: %d", + portid,shmp->process_info.state); + + SendCDR(portid); + + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + } + } + } /* for() */ +} + + +void ListAllPortStatus(int flag) +{ + FILE *fpStatus=NULL; + + int portid; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(flag) + { + for(portid=0; portidstate_data; + shmp += (portid); + //if(shmp->process_info.state == S_IDLE && + // smshm_ptr->port_info[portid].status == 1) + { + ReleaseAll(portid); + shmp->process_info.state = S_IDLE; + } + } + return; + } + + fpStatus = fopen("../log/pps_state.txt","w"); + if(fpStatus == NULL) + return; + + for(portid=0; portidstate_data; + shmp += (portid); + fprintf(fpStatus,"[%04d].status = %d.%d, %s->%s, duration=%d(s)\n", + portid, smshm_ptr->port_info[portid].status, + shmp->process_info.state, shmp->caller_info.number,shmp->called_info.number, + shmp->process_info.fsm_timer/CYCLE_STATE_INTERVAL); + + } + fclose(fpStatus); +} + +int ClearAllPortForStop() +{ + u_short portid; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + PutLogFunID("ClearAllPortForStop"); + + for(portid=0; portidstate_data; + shmp += portid; + switch(shmp->process_info.state) + { + case S_WAITINGFOR_EVENTS: + shmp->process_info.tcos = NETWORK_OUT_OF_ORDER; + shmp->cdr_info.releasetime = tvnow.tv_sec; + SendCDR(portid); + SendReleaseCall(portid); + break; + + case S_RO_EVENT_SMS_PROCESS: + pps_ro_event_sms_process(portid); + break; + case S_RO_EVENT_COMMON_PROCESS: + pps_ro_event_common_process(portid); + break; + + case S_RO_VOC_INIT: + case S_RO_VOC_CONNECTED: + case S_RO_VOC_RELEASE: + shmp->process_info.state = S_RO_VOC_RELEASE; + pps_ro_voice_process(portid); + break; + case S_GY_PS_INIT: + case S_GY_PS_CONNECTED: + case S_GY_PS_WAIT_TERM: + case S_GY_PS_RELEASE: + shmp->process_info.state = S_GY_PS_RELEASE; + pps_gy_data_charge_process(portid); + break; + case S_GY_PS_POSTPAID: + shmp->process_info.oc = RT_TERMINATE_REQUEST; + pps_gy_data_postpaid_process(portid); + break; + case S_RECHARGE_OVER: + debugmib.watch_dog[5] ++; + //RechargeRequestProc(portid); + break; + default: + break; + } + } + return 1; +} + +#ifdef CONVERT_16DIGIT_CARD +void Convert16DigitCard() +{ + int i,j,len,tail,snRead,snExist; + int foundFlag,consistentCounter=0; + char fileName[]="./conf/card_info_rebuild.txt"; + char record[512],buf[128]; + char card_no[32],card_pwd[32]; + FILE *fp; + _card_data *card_data=&ramshm_ptr->card_data; + + fp = fopen(fileName,"r"); + if(fp == NULL) + { + //printf("File %s not found, abort converting!\n",fileName); + return; + } + + stopReceivePeriodicSyncFlag = 1; + while(fgets(record,512,fp) != (char *)0) + { + memcpy(card_no,record,16); + card_no[16] = 0; + memcpy(card_pwd,&record[17],16); + card_pwd[16] = 0; + snRead = atoi(&card_no[8]); + tail = atoi(&card_no[14]); + foundFlag = 0; + + for(i=0;iprepaid_card[i][tail].card_no[MAX_CARD_LENGTH]; + if(len !=16 ) + { + continue; + } + BcdToAscii(buf,card_data->prepaid_card[i][tail].card_no,len); + snExist = atoi(&buf[8]); + if(snRead == snExist) + { + foundFlag = 1; + consistentCounter ++; + AsciiToBcd(card_data->prepaid_card[i][tail].card_pwd,card_pwd,16); + } + } + if(!foundFlag) + { + for(i=MAX_CARD_SEGMENT-MAX_CLIMAX_CARD_SEGMENT;iprepaid_card[i][j].card_no[MAX_CARD_LENGTH]; + if(len !=16 ) + { + continue; + } + BcdToAscii(buf,card_data->prepaid_card[i][j].card_no,len); + snExist = atoi(&buf[8]); + if(snRead == snExist) + { + foundFlag = 1; + consistentCounter ++; + AsciiToBcd(card_data->prepaid_card[i][j].card_pwd,card_pwd,16); + } + } + }//! + } + //printf("total %d converted\n",consistentCounter); + //stopReceivePeriodicSyncFlag = 0; + fclose(fp); + remove(fileName); +} +#endif + +extern int ocs_init_hash_table(); +extern int ocs_read_crm_base_prefix_file(); +int CreatePPSDataIndexForAll() +{ + int i; + _card_data *card_data=&ramshm_ptr->card_data; + struct timeval tmstart,tmend; + + gettimeofday(&tmstart,NULL); + + PutLogFunID("PrivateRamInit"); +#ifdef OCS_WITH_CRM + ocs_init_hash_table(); +#endif + + CreatePPSSubsIndexTable(); + + debugmib.measurement.cardnumber = 0; + debugmib.measurement.cardheadnumber = 0; + + for(i=0;iface_value[i]=0; + } + + CreateQuenceList(); + + gettimeofday(&tmend,NULL); + printf("create index take: %ld usec\n", + (tmend.tv_sec-tmstart.tv_sec)*1000000 + + tmend.tv_usec-tmstart.tv_usec); + return 1; +} + +static int +PrivateRamInit() +{ + + CreatePPSDataIndexForAll(); + + load_tariff_main(); + + return SUCCESS; +} + + +int realSyncTcpSend(DWORD db_type, DWORD instance, DWORD ocode, BYTE *payload, WORD len) +{ + if ((!ppsParam.serviceControl.tcp_sync_flag) || (realSyncTcpSap < 0) || (realSyncTcpPid < 0)) + { + return -1; + } + + if (tcp_send(realSyncTcpSap, 0, realSyncTcpPid, payload, len, db_type, instance, ocode) < 0) + { + return -1; + } + + return 0; +} + +static int realSyncTcpInit(u_long localip, u_long peerip) +{ + tcp_sap_t realTcpSap; + tcp_session_t sess; + + // bind + strcpy(realTcpSap.name, "PpsRealSync"); + realTcpSap.recv_cb = tcpRealSyncProc; + realSyncTcpSap = tcp_bind(&realTcpSap); + if (realSyncTcpSap < 0) + { + return -1; + } + + // allocate port, 1: client; 0: server; + sess.bServer = subSystemID ? FALSE : TRUE; + sess.src_ip = localip; + sess.src_port = PPS_REALSYNC_PORT; + sess.dst_ip = peerip; + sess.dst_port = PPS_REALSYNC_PORT; + realSyncTcpPid = tcp_port_alloc_port(realSyncTcpSap, 0, &sess); + if (realSyncTcpPid < 0) + { + return -1; + } + + return 0; +} + + +int SystemInit() +{ + blf_shmp = (_tariff_private *) ShmInit(blf_shmid, prog_name, + TARIFF_SHM_KEY, PRIVATE_TARIFF_SIZE, + TARIFF_SHM_PERM|IPC_CREAT); + + memset(blf_shmp, EMPTY, PRIVATE_TARIFF_SIZE); + + ramshm_ptr = (_ram_data *) ShmInit(ramshm_id, prog_name, + RAMDATA_SHM_KEY, 84*1024*1024, + RAMDATA_SHM_PERM|IPC_CREAT); + memset(ramshm_ptr,0,84*1024*1024); + + GetVersionID(VERSION,version_id); + GetVersionID(VERSION,peer_version_id); + + reportInit(); + + ppsInitCSTA(); + + LoadPPSParam(); + pps_smppInit(); + debugmib.display.proc_used = 0; + debugmib.display.ro_used = 0; + debugmib.display.gy_used = 0; + initSNMP(); + + init_radius_gsn(); + realSyncTcpInit(LOCAL_IP, peer_server_ip); + icap_reg_ssn(SSN_SCF); //CAP + imap_reg_ssn(0x99); //gsmSCF + return SUCCESS; +} + + int pps_read_sysparam(int *sysID, u_long *localIP, u_long *peerIP) +{ + FILE *fp; + int ii; + char *ch_ptr,*buf_ptr; + char *temp_ptr; + char hostname[64]; + char temp_info[64],info_str[1024]; + struct hostent *pcn; + struct in_addr temp_addr; + + char sysconf[]="./conf/wxc2_sys.conf"; + + if ((gethostname(hostname,-1)) == -1) + { + printf("Can not get hostname\n"); + return 0; + } + pcn = gethostbyname(hostname); + if (pcn == NULL) + { + printf("Get host ip address fail. Please check your ethernet configure\n"); + return 0; + } + fp = fopen(sysconf,"r"); /* read system configure */ + if (fp == NULL) + { + printf("can not open file %s!!\n",sysconf); + return 0; + } + ch_ptr = strchr(hostname,'.'); + if (ch_ptr != NULL) + ch_ptr[0] = '\0'; /* delete the suffix of host name */ + while (!feof(fp)) + { + info_str[0] = '\n'; + fgets(info_str,250,fp); + if (info_str[0] == '#' || info_str[0] == '\n') + continue; + buf_ptr = info_str; + for (ii = 0;ii < 2;ii ++) + { + ch_ptr = strsep(&(buf_ptr),"=;"); + if (ch_ptr == NULL) + { + printf("This field lacks infomation:%s\n",buf_ptr); + return 0; + } + if (ii == 0) + { + if (strlen(ch_ptr) != strlen(hostname)) + { + printf("Please check host name in file:%s\t%s\n",ch_ptr,hostname); + return 0; + } + temp_ptr = strchr(hostname,'-'); + if (memcmp(ch_ptr,hostname,strlen(hostname)-strlen(temp_ptr)) != 0) + { + printf("The host name is unexpect!\n"); + return 0; + } + strcpy(temp_info,ch_ptr); + } + else + { + if (memcmp(hostname,temp_info,strlen(temp_info)) == 0) /* owner ip address */ + { + if (strcmp(inet_ntoa(*(struct in_addr *)(*pcn->h_addr_list)),ch_ptr) != 0) + { + printf("Error ip address\n"); + return 0; + } + *sysID = temp_info[strlen(temp_info)-1] - '0'; + + if (*sysID > 1) + { + printf("Error system id\n"); + return 0; + } + *localIP = ((struct in_addr *)(*pcn->h_addr_list))->s_addr; + } + else + { + if (!inet_aton(ch_ptr,&temp_addr)) + { + printf("Can not get peer ip address\n"); + return 0; + } + *peerIP = temp_addr.s_addr; + } + } + } + } + fclose(fp); + return 1; +} + + +int InitRamData(int no_sync_flag) +{ + static int initState = _INIT_CHECK_VERSION; + static int trytimes = 0; + int retval=0; + + PutLogFunID("InitRamData"); + + switch(initState) + { + case _INIT_CHECK_VERSION: /* check version, waiting 10s */ + //initState = _INIT_READ_FROM_LOCAL_HD; + + if(no_sync_flag) + { + initState = _INIT_READ_FROM_LOCAL_HD; + trytimes=0; + break; + } + if(pps_peer_hb_flag) + { + if(memcmp(version_id,peer_version_id,2))/* the first 2 version should be the same */ + { + debugmib.display.sysState = _SYS_STATE_SUSPEND; + initState = _INIT_CHECK_VERSION; + trytimes = 0; + alarm_code[0] = 0; /* pps */ + alarm_code[1] = 1; /* version not the same */ + return 1; + } + /* + else if(peer_version_id[2]<4) + { + initState = _INIT_READ_FROM_LOCAL_HD; + trytimes=0; + break; + } + */ + pps_peer_hb_flag = 0; + initState = _INIT_CHECK_SYNC; + trytimes=0; + } + else if(trytimes++>2000) + { + initState = _INIT_READ_FROM_LOCAL_HD; + trytimes=0; + } + //initState = _INIT_CHECK_SYNC; + //trytimes=0; + break; + case _INIT_CHECK_SYNC: + /* + if(ReadPeroidicSyncData()) + { + debugmib.display.dataSrc=_SRC_PEER_SRV; + initState = _INIT_READ_FROM_PEER; + } + else if(trytimes++>MAX_RAM_INIT_RETRY*10) + { + trytimes = 0; + initState = _INIT_READ_FROM_LOCAL_HD; + } + */ + debugmib.display.dataSrc=_SRC_PEER_SRV; + initState = _INIT_READ_FROM_PEER; + break; + case _INIT_READ_FROM_PEER: /* read from peer server */ + retval = ReadDataFromPeerSever(); + if(retval == 1) + { + data_source = _SRC_PEER_SRV; + initState = _INIT_OVER; + } + else if(retval == -1) + { + initState = _INIT_READ_FROM_LOCAL_HD; + } + retval = 0; + break; + case _INIT_READ_FROM_LOCAL_HD: /* read from local backup file */ + retval = LoadDataFromBackfile(); + if(retval<0) + { + //error = no local backup file + initState = _INIT_READ_FROM_OMC_HD; + } + else + { /* retval =0 not supported backup data */ + data_source = _SRC_LOCAL_HD; + debugmib.display.dataSrc =_SRC_LOCAL_HD; + debugmib.display.initProgress = 100; + masterFlag = 1; + initState = _INIT_OVER; + debugmib.display.masterIP = LOCAL_IP; + } + retval = 0; + break; + case _INIT_READ_FROM_OMC_HD: /* read from omc backup file */ + // retval = ReadDataFromOMCServer(); + retval = -1; + if(retval==1) + { + initState = _INIT_OVER; + debugmib.display.dataSrc=_SRC_OMC_HD; + } + else if(retval==-1) + { + debugmib.display.dataSrc = _SRC_NO_SRC; + initState = _INIT_UNNORMAL; + } + retval = 0; + break; + case _INIT_OVER: + initState = _INIT_CHECK_VERSION; + retval = 1; + ramInitFlag = 1; +#ifdef OCS_WITH_CRM + ocs_read_crm_base_prefix_file(); +#endif + + //debugmib.display.sysState = _SYS_STATE_NORMAL; + break; + case _INIT_UNNORMAL: + initState = _INIT_CHECK_VERSION; + retval = 1; + alarm_code[0] = 0x00; + alarm_code[1] = 0x02; /* no data source */ + //debugmib.display.sysState = _SYS_STATE_SUSPEND; + //debugmib.display.sysState = _SYS_STATE_NORMAL; + break; + default: + initState = _INIT_CHECK_VERSION; + retval = 0; + break; + } + return retval; +} + +void ppsRecordLog() +{ + int i; + FILE *fpLog=NULL; + + fpLog = fopen("../log/pps_exit.log","w"); + if(fpLog !=NULL) + { + fprintf(fpLog,"Last function : %s(%d)\n", + smshm_ptr->func_log.func_name[(smshm_ptr->func_log.funcID+MAX_LOG_FUNC-1)%MAX_LOG_FUNC], + (smshm_ptr->func_log.funcID+MAX_LOG_FUNC-1)%MAX_LOG_FUNC); + for(i=0;i %s \n",smshm_ptr->func_log.func_name[i]); + fclose(fpLog); + } +} + +int +pps_init(int max_user, int sysID,u_long localip,u_long peerip,char *sn,int no_sync_flag) +{ + static int firstInit=0; + int retval=0,i; + char buf[128]; + FILE *fpLog=NULL; + + if(!firstInit) + { + smshm_ptr = (_state_machine *) ShmInit(smshm_id, prog_name, + SMMP_SHM_KEY, PPS_FSM_RAMSIZE, + SMMP_SHM_PERM|IPC_CREAT); + + fpLog = fopen("../log/pps_trace.log","w"); + if(fpLog !=NULL) + { + fprintf(fpLog,"Last function : %s(%d)\n", + smshm_ptr->func_log.func_name[(smshm_ptr->func_log.funcID+MAX_LOG_FUNC-1)%MAX_LOG_FUNC], + (smshm_ptr->func_log.funcID+MAX_LOG_FUNC-1)%MAX_LOG_FUNC); + for(i=0;i %s \n",smshm_ptr->func_log.func_name[i]); + fclose(fpLog); + } + memset(smshm_ptr, EMPTY, PPS_FSM_RAMSIZE); + + systemCapability = 10000; + if(max_user<=MSISDN_HEAD_NUM*UNIT_STORE_ACCOUNT && max_user>=1000) + { + systemCapability = max_user; + msisdn_head_num = ceil((float )systemCapability/UNIT_STORE_ACCOUNT); + } + peer_server_ip = peerip; + subSystemID = sysID; + strcpy(serialNumber,sn); + LOCAL_IP = GetLocalIP(); + SystemInit(); + + sprintf(buf,"%08d",systemCapability); + AsciiToBcd(debugmib.measurement.sys_capability,buf,8); + printf("sizoef(user) = %lu, sizeof(card) = %lu, sizeof(tariff) = %lu, total = %lu\r\n", + sizeof(_prepaid_data), sizeof(_card_data), sizeof(_tariff_data), sizeof(_ram_data)); + printf("sizoef(_state_machine) = %lu\r\n", sizeof(_state_machine)); + +#ifdef OCS_USE_REDIS_DB + RedisInit((u32)localip, (u32)peerip); +#endif + + totalPeriodSyncPackets = + (sizeof(_tariff_data) + sizeof(_card_data)) / RAMDATA_PACK_SIZE; + //printf("total: %d\n",totalPeriodSyncPackets); + + debugmib.display.sysState = _SYS_STATE_INIT; + } + retval = InitRamData(no_sync_flag); + ReadSyncMessageForInit(); + + firstInit ++; + if(firstInit %10 ==0) + BeatTrans(); + if(retval) + { + PrivateRamInit(); + pps_exit(0); + pps_real_update_file_init(); + debugmib.display.sysState = _SYS_STATE_NORMAL; + } + return retval; +} + +static void +PrepaidProc() +{ + static int PPS_flag = 0x00; + static int initLocalBackup = 0; +// static int initRemoteBackup = 0; + static int periodicBackup = 0; + static int periodicCounter =0; + + int tmpLicense=0; + + if(PPS_flag) return ; + PPS_flag = 0x01; + debug_messages=0; + + gettimeofday(&tvnow,NULL); + getnowtime(time_now); + + BeatTrans(); + cstaInstanceCheck(); + ppsCheckParameterAutoSaveFlag(); + + TariffPlanProc(); + + CheckLoadFile(); + ppsDebugRt(); + chargeID = masterFlag; + + if(GetMSISDNOfSSN(SSN_SCF,&ppsParam.ppsNumber[1])){ + ppsParam.ppsNumber[0] = 0x91; + } + if(GetMSISDNOfSSN(20,&ppsParam.smscNumber[1])){ + ppsParam.smscNumber[0] = 0x91; + } + if(GetMSISDNOfSSN(19,&ppsParam.esmeNumber[1])){ + ppsParam.esmeNumber[0] = 0x91; + } + + if(debugmib.display.sysState==_SYS_STATE_NORMAL) + { + PeriodicChargeProc(); + smppMonitor(); + reportCreatedDaily(); + + SyncMessageProc(); //receive sync message + + srfActivityMonitor(); + if(PERIODIC_ACTIONS>1) /* 1K/1S */ + { + if(periodicCounter++==(PERIODIC_ACTIONS-1)) + { + PeriodicSyncRamData(); + periodicCounter = 0; + } + } + else + { + PeriodicSyncRamData(); + } + + if(initLocalBackup ==0){ + if(data_source !=_SRC_LOCAL_HD) + { + pps_exit(0); + initLocalBackup = 0x01; + } + } + + /* + if(initRemoteBackup ==0) + { + if(data_source !=_SRC_OMC_HD && masterFlag ==1) + { + if(ppsBackupRamDataToOMCServer()){ + initRemoteBackup = 0x01; + } + } + else + { + initRemoteBackup = 0x01; + } + } + */ + + if(subSystemID == 0) + { + if(time_now[3]==4 && time_now[4]==0 && + time_now[5]<5 && periodicBackup==0) + { + periodicBackup = 1; + } + } + else + { + if(time_now[3]==4 && time_now[4]==10 && + time_now[5]<5 && periodicBackup==0) + { + periodicBackup = 1; + } + } + if(periodicBackup==1){ + if(ppsBackupRamDataToFile()){ + if(masterFlag) + periodicBackup = 0x02; + else + periodicBackup = 0x00; + } + } + if((periodicBackup==2)){ + //if(ppsBackupRamDataToOMCServer()) + //{ + periodicBackup = 0x00; + //} + } + saveCommand(); + + capMessageProc(); + + CallProc(); + + pps_rest_recv_proxy(); + } + else{ + alarm_code[0] = 0; + alarm_code[1] = 2; + } + + + tmpLicense = wxc2_get_license(LIC_PPS_USERS); + //if(tmpLicense>ppsParam.serviceControl.licenseduser) + ppsParam.serviceControl.licenseduser = tmpLicense; + + PPS_flag = 0x00; + +} + +void +pps_proc() +{ +// if(!stoprunning_flag) + PrepaidProc(); +} + +void SaveTariffPlan() +{ + FILE *fp; + + fp=fopen(PPS_TARIFF_DATA_TEMP,"w"); + if(fp !=NULL) + { + fwrite((void *)&ramshm_ptr->tariff_data,sizeof(_tariff_data),1,fp); + fclose(fp); + rename(PPS_TARIFF_DATA_TEMP,PPS_TARIFF_DATA_NAME); + } +} + +void SaveRechargeCard() +{ + FILE *fp; + void *ptr=(void *)ramshm_ptr; + + fp=fopen(PPS_RECAHRGE_CARD_BACKUP_TEMP,"w"); + if(fp !=NULL) + { + ptr = &ramshm_ptr->card_data; + fwrite(ptr,sizeof(_card_data),1,fp); + fclose(fp); + rename(PPS_RECAHRGE_CARD_BACKUP_TEMP,PPS_RECHARGE_CARD_BACKUP_NAME); + } +} + +int SetIndexMessAlamFlag(int flag) +{ + + switch(flag) + { + case 0: + debugmib.measurement.search_table_result[0] ++; + break; + case 1: + debugmib.measurement.index_alarm = 1; + alarm_code[0] = 0x00; + alarm_code[1] = 0x02; + ppsSendHeartBeating(); + break; + case 2: + debugmib.measurement.search_table_result[1] ++; + default: + break; + } + return 1; +} + +void SaveSubsData() +{ + FILE *fp; + void *ptr=(void *)ramshm_ptr; + + printf("save data at %d.%d.%d\n", + time_now[3],time_now[4],time_now[5]); + + fp=fopen(PPS_USER_BACKUP_TEMP,"w"); + if(fp !=NULL) + { + ptr = &ramshm_ptr->prepaid_data; + fwrite(ptr,sizeof(_prepaid_data),1,fp); + fclose(fp); + rename(PPS_USER_BACKUP_TEMP,PPS_USER_BACKUP_NAME); + if(debugmib.measurement.index_alarm) + { + debugmib.measurement.index_alarm = 0; + CreatePPSSubsIndexTable(); + } + else if(debugmib.measurement.search_table_result[0]>0) + { + int succeed_rate = 0; + succeed_rate = debugmib.measurement.search_table_result[1] * 100 / + debugmib.measurement.search_table_result[0]; + + if(succeed_rate<80) + { + CreatePPSSubsIndexTable(); + } + } + } +} + +int SaveSubsDataPeriodic() +{ + FILE *fp; + void *ptr=(void *)ramshm_ptr; + + fp=fopen(PPS_USER_BACKUP_TEMP,"w"); + if(fp !=NULL) + { + ptr = &ramshm_ptr->prepaid_data; + fwrite(ptr,sizeof(_prepaid_data),1,fp); + fclose(fp); + rename(PPS_USER_BACKUP_TEMP,PPS_USER_BACKUP_NAME); + if(debugmib.measurement.index_alarm) + { + debugmib.measurement.index_alarm = 0; + CreatePPSSubsIndexTable(); + } + else if(debugmib.measurement.search_table_result[0]>0) + { + int succeed_rate = 0; + succeed_rate = debugmib.measurement.search_table_result[1] * 100 / + debugmib.measurement.search_table_result[0]; + + if(succeed_rate<80) + { + CreatePPSSubsIndexTable(); + } + } + } + return 1; +} + +int pps_exit(int flag) +{ + + if(debugmib.display.sysState != _SYS_STATE_NORMAL) + { + return 0; + } + + if(flag) + { + stoprunning_flag = 1; + SaveDailyReport(); + ClearAllPortForStop(); + //SaveParam(); + } + pps_real_update_file_close(); + SaveTariffPlan(); + SaveRechargeCard(); + SaveSubsData(); + return 1; +} + +void ReloadPPSSubscriberFromHD() +{ + FILE *fp=NULL; + struct stat fileinfo; + + fp=fopen(PPS_USER_BACKUP_NAME,"r"); + if(fp !=NULL) + { + stat(PPS_USER_BACKUP_NAME,&fileinfo); + if(fileinfo.st_size == sizeof(_prepaid_data)) + { //check length + fread(&ramshm_ptr->prepaid_data,sizeof(_prepaid_data),1,fp); + } + fclose(fp); + CreatePPSSubsIndexTable(); + } +} diff --git a/mss/pps/src/main/ppsmain.c b/mss/pps/src/main/ppsmain.c new file mode 100644 index 0000000..33dd4ed --- /dev/null +++ b/mss/pps/src/main/ppsmain.c @@ -0,0 +1,271 @@ +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" + +#include "../include/plat_inc.h" +#include "../../../../plat/scf/src/include/scfpub.h" +/*------------------------------------------------*/ +static struct termio prev_termio; +static int timer100=0; +extern int subSystemID; + +/*------------------------------------------------*/ +/*------------------------------------------------*/ +extern int smpp_timer(); +extern int smppEncodeSM(); +extern int smppDecodeSM(); +extern int pps_read_sysparam(); +/*------------------------------------------------*/ + + +static void +platInit() +{ + debug_init(); + mtp_shm_init(); + iptrMainInit(); + snmp_init(4957); + sccp_init(); + + tcap_init(512); + xap_init(512); + scsm_init(); +} + +void +ppsModuleProc() +{ + //struct timeval tmstart,tmend; + + iptrans_timer(); + snmp_timer(); + heartbeat_timer(); + debug_rt(); + mtp3_proc(); + sccp_timer(); + smpp_timer(); + tcap_fsm(); + xap_fsm(); + + + scsm(); + +} + + +void +SysGuard(int sig) +{ + struct timeval tm; + char fname[]={"../log/logout.txt"}; + FILE *fp; + + fp = fopen(fname,"w"); + if(fp != NULL) + { + gettimeofday(&tm,NULL); + fprintf(fp,"====================================\n"); + fprintf(fp,"pps restart for segementation fault!\n"); + fprintf(fp,"log time : %s\n",ctime(&tm.tv_sec)); + fclose(fp); + } + fprintf(stderr,"Exception met, exit!\n"); + exit(1); +} + +static void +Terminate(int sig) +{ + int retval=0,loop=0; + char tm_str[30]; + time_t tn; + + + tn = time(NULL); + ioctl(0, TCGETA, prev_termio); + retval = shmdt((char *) 0); + printf("Service down at %s\n", GetAsciiTime(tm_str)); + + pps_exit(1); + loop = 0; + + while(loop<15) + { + loop++; + ppsModuleProc(); + pps_proc(); + usleep(10); + } + + exit(sig); +} + +void +FaultSignalProc(int sig) +{ + system("/usr/local/pps/bin/ppsd restart"); +} + +void +SetFSMTimer() +{ + struct itimerval *ptv, tv; + + ptv = (struct itimerval *) &tv; + ptv->it_interval.tv_sec = SMMP_IT_INTERVAL_SEC; + ptv->it_interval.tv_usec = SMMP_IT_INTERVAL_USEC/2; + ptv->it_value. tv_sec = SMMP_IT_VALUE_SEC; + ptv->it_value.tv_usec = SMMP_IT_VALUE_USEC/2; + setitimer(ITIMER_REAL, ptv, NULL); +} + + + +void +PrepaidAction(int sig) +{ + + timer100++; + ppsModuleProc(); +} + + +void SetTerminate() +{ + struct termio ptermio; + ioctl(0,TCGETA, &ptermio); + ptermio.c_cc[VINTR]='\x03'; + ioctl(0,TCSETA, &ptermio); + signal(SIGINT , Terminate); + signal(SIGTERM, Terminate); +} + +void +SigactionPrepaid() +{ + struct sigaction action; + + action.sa_handler = PrepaidAction; + action.sa_flags = SA_RESTART; + sigemptyset(&action.sa_mask); + sigaction(SIGALRM, &action, NULL); +/* + actsegv.sa_handler = SysGuard; + actsegv.sa_flags = SA_RESTART; + sigemptyset(&actsegv.sa_mask); + sigaction(SIGSEGV,&actsegv,NULL); +*/ +} + +void shortMessageTest() +{ + char sm_in[32]="000001000000",sm_out[32]="",sm_res[32]=""; + smppEncodeSM(sm_in,sm_out,12); + smppDecodeSM(sm_out,sm_res,11*8/7); + printf("result: %s\n",sm_res); +} + +int +main(int argc, char **argv) +{ + int retval=0; + int err_flag = FALSE; + int main_state=0; + struct timeval tmstart,tmend; + u_long peerip,localip=0x018812ac; + //u_char buf[128]; + + while ((retval = getopt(argc, argv, "dvcf:I:")) != -1) + switch (retval) { + case 'd': + DaemonInit("ppsm", LOG_USER); + break; + case '?': + err_flag = TRUE; + break; + } + if (err_flag) { + log_msg("Usage: %s [-d] [-c] [-f RAM file name] [-v]\n", "ppsm"); + log_msg(" -d with daemon mode"); + log_msg(" -c Cancel RAM data initialization"); + log_msg(" -f[RAM file name] Load RAM file"); + log_msg(" -v print version information"); + exit(1); + } + + printf("sizeof _tariff_private: %d\n",sizeof(_tariff_private)); + pps_read_sysparam(&subSystemID,&localip,&peerip); + //printf("smpplength: %d\n",smppEncodeSM("49998,2006-07-01 @2004-09-14 11:08<-86755900093",buf)); + // + while(TRUE) { + switch( main_state ) { + case 0: + platInit(); + + SetTermSignal(&prev_termio, (void *)Terminate); + if(subSystemID) + { + heartbeat_init(0x0901); + } + else + { + heartbeat_init(0x0900); + } + + SetFSMTimer(); + SigactionPrepaid(); + main_state = 1; + gettimeofday(&tmstart,NULL); + + printf("sizeof(all data): %d\n", + sizeof(_ram_data)); + printf("sizeof(tariff_data): %d\n", + sizeof(_tariff_data)); + printf("sizeof(card_data): %d\n", + sizeof(_card_data)); + printf("sizeof(user_data): %d\n", + sizeof(_prepaid_data)); + printf("sizeof(_tariff_private): %d\n", + sizeof(_tariff_private)); + printf("sizeof(_ram_data): %d\n", + sizeof(_state_machine)); + printf("sizeof(_prepaid_info): %d\n", + sizeof(_prepaid_info)); + printf("sizeof(_state_machine): %d\n", + sizeof(_state_machine)); + printf("sizeof(stat): %d\n", + sizeof(_pps_cdr_buffer) + sizeof(_pps_csta_buffer)); + break; + case 1: + ppsModuleProc(); + if (pps_init(100000,subSystemID,localip,peerip,"11200001")) { + main_state = 2; + gettimeofday(&tmend,NULL); + printf("Take %ld senconds\n", + tmend.tv_sec-tmstart.tv_sec); +// shortMessageTest(); + } + break; + case 2: + if(timer100%TIMER_ACTION_STATE==0) + { +gettimeofday(&tmstart,NULL); + pps_proc();/* Normal state */ +gettimeofday(&tmend,NULL); +//printf("Plat takes : %.1fms\n", (tmend.tv_sec-tmstart.tv_sec)*1000+(tmend.tv_usec-tmstart.tv_usec)/1000.0); + + } + break; + default: + main_state = 0; + break; + } + usleep(10); + } +} diff --git a/mss/pps/src/main/ppsmap.c b/mss/pps/src/main/ppsmap.c new file mode 100644 index 0000000..aed98e7 --- /dev/null +++ b/mss/pps/src/main/ppsmap.c @@ -0,0 +1,412 @@ +#include +#include + +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/param.h" + +#include "../include/plat_inc.h" + +/*----------------------------------------*/ + +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr; +extern u_char logMsgFlag; +extern struct timeval tvnow; +/*----------------------------------------*/ +int pps_debug_map_msg(); +/*----------------------------------------*/ +extern int PutLogFunID(); +extern int stuff_sccp_address(); +extern int ppsBcdToAsciiR(); +extern int DebugMsg(); +extern int DebugMsgDelimiter(); +extern int ppsAsciiToBcdR(); +extern void StringCut(char *str, int c); +extern int pps_get_ucbc_number(char *ucbc_number); +extern PPSParamStruct ppsParam; +extern u8 isdn_ston(u8 *normal_isdn, u8 *str_isdn); +extern void isdn_ntoa(u8 * anti_isdn, u8 * normal_isdn); +/*----------------------------------------*/ + +int pps_send_map_open(u_short portid) +{ + u_char data_flow[256]; + char msisdn[32]; + int offset = 0; + SCCP_ADDR srcAddr,dstAddr; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("pps_send_map_open"); + + shmp += portid; + shmp->context_info.map_did = map_get_dialogueid(147); + + data_flow[offset++] = 0; + data_flow[offset++] = 1; + data_flow[offset++] = MAP_FLAG; + data_flow[offset++] = portid>>8; + data_flow[offset++] = portid; + data_flow[offset++] = 0; + data_flow[offset++] = shmp->context_info.map_did>>8; + data_flow[offset++] = shmp->context_info.map_did; + data_flow[offset++] = 0; + data_flow[offset++] = MAP_OPEN; + data_flow[offset++] = MAP_REQUEST; + + if(shmp->process_info.routing_home_flag == 1) + { + char ucbc_number[32]; + data_flow[offset++] = AC_roamingNbEnquiry; + + pps_get_ucbc_number(ucbc_number); + stuff_sccp_address(&dstAddr,ucbc_number,7, 0); + shmp->context_info.map_acn_ver = 2; //map_get_acnver(&dstAddr,AC_roamingNbEnquiry); + data_flow[offset++] = 2; //AC_roamingNbEnquiry; + } + else + { + data_flow[offset++] = shmp->context_info.map_acn; + + stuff_sccp_address(&dstAddr,shmp->called_info.number,6,14); + shmp->context_info.map_acn_ver = map_get_acnver(&dstAddr, + AC_anyTimeInfoEnquiry); + data_flow[offset++] = shmp->context_info.map_acn_ver; + } + + memcpy(&data_flow[offset],&dstAddr,sizeof(SCCP_ADDR )); + offset += sizeof(SCCP_ADDR); + + ppsBcdToAsciiR(msisdn,&ppsParam.ppsNumber[1],20); + StringCut(msisdn,'F'); + stuff_sccp_address(&srcAddr,msisdn,147,0); + memcpy(&data_flow[offset],&srcAddr,sizeof(SCCP_ADDR )); + offset += sizeof(SCCP_ADDR); + + data_flow[offset++] = 0x10; /* delimiter */ + data_flow[offset++] = 0x00; + data_flow[1] = offset - 2; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map Open @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + pps_debug_map_msg(data_flow,1); + } + return map_send_comdata(data_flow); + +} + +int pps_send_map_openrsp(u_short portid, u_char result) +{ + u_char msg_flow[256]; + int did,offset=0; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + did = shmp->context_info.map_did; + msg_flow[offset++] = 0; + msg_flow[offset++] = 0; + msg_flow[offset++] = MAP_FLAG; + msg_flow[offset++] = portid>>8; + msg_flow[offset++] = portid; + msg_flow[offset++] = 0; + msg_flow[offset++] = did>>8; + msg_flow[offset++] = did; + msg_flow[offset++] = 0; + msg_flow[offset++] = MAP_OPEN; + msg_flow[offset++] = MAP_RESPONSE; + msg_flow[offset++] = result; + if(result == OpenResultAccept) + { + msg_flow[offset++] = 0x00; + } + else + { + msg_flow[offset++] = 0x01; + msg_flow[offset++] = 0x03; + msg_flow[offset++] = 0x01; + msg_flow[offset++] = InvalidDesReference; + } + + msg_flow[offset++] = 0x00; + msg_flow[1] = offset; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "[%04d] did=%d, send open response result: %d! (%ld.%ld)", + portid,did,result,tvnow.tv_sec,tvnow.tv_usec); + } + + if(!map_send_comdata(msg_flow)) + { + return 0; + } + return 1; +} + +int pps_send_map_opr(struct MapOprData_struct *opr_ptr, int delimiter_flag) +{ + u_char data_flow[256]; + u_short data_len,portid; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("pps_send_map_opr"); + + map_opr_stof(opr_ptr,data_flow,0); + data_len = data_flow[0]*256 + data_flow[1] + 2; + if(delimiter_flag) + data_flow[data_len-1] = 0x10; + else + data_flow[data_len-1] = 0x00; + data_flow[data_len++] = 0x00; + data_flow[data_len++] = 0x00; + data_flow[0] = (data_len - 2) >>8; + data_flow[1] = (data_len - 2) & 0xff; + + portid = (data_flow[3]*256 + data_flow[4])%(MAX_FSM_PROCESS); + shmp += portid; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map Opr. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + pps_debug_map_msg(data_flow,1); + } + + + return map_send_oprdata(data_flow); +} + +int pps_send_mnp_ati(u_short portid) +{ + char msisdn[32]; + char data_flow[256]; + int len; + struct MapOprData_struct opr_data; + struct MapOprSrv_struct map_opr; + struct MapATI_Arg *ati_arg; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("pps_send_mnp_ati"); + + shmp += portid; + + ati_arg = &map_opr.msg_list.ati_arg; + ati_arg->param_flag = 0x07; + ati_arg->sub_ident.choice_flag = 2; + len = strlen((char *)shmp->called_info.number); /* can be caller */ + if(len>(ISDN_LEN-1)*2) len = (ISDN_LEN-1) * 2; + ati_arg->sub_ident.choice.msisdn[0] = (len+1)/2+1; + ati_arg->sub_ident.choice.msisdn[1] = 0x91; + ppsAsciiToBcdR(&ati_arg->sub_ident.choice.msisdn[2], + shmp->called_info.number, + (len+1)/2*2); + if(len %2) + { + ati_arg->sub_ident.choice.msisdn[(len+1)/2+1] |= 0xF0; + } + ati_arg->req_info.param_flag = 0x40; + + ppsBcdToAsciiR(msisdn,&ppsParam.ppsNumber[1],20); + StringCut(msisdn,'F'); + len = (strlen(msisdn)+1)/2; + if(len>ISDN_LEN-1) len = ISDN_LEN-1; + ati_arg->scf_add[0] = len+1; + ati_arg->scf_add[1] = 0x91; + memcpy(&ati_arg->scf_add[2],&ppsParam.ppsNumber[1],len); + + shmp->context_info.map_iid = + map_get_invokeid(shmp->context_info.map_did); + + map_opr.port_id = portid; + map_opr.dialogue_id = shmp->context_info.map_did; + map_opr.invoke_id = shmp->context_info.map_iid; + map_opr.message_type = AnyTimeInter; + map_opr.message_flag = MAP_REQUEST; + + build_mapparam(&map_opr, (u8 *)data_flow); + + opr_data.port_id = portid; + opr_data.dialogue_id = map_opr.dialogue_id; + opr_data.invoke_id = map_opr.invoke_id; + opr_data.message_type = map_opr.message_type; + opr_data.message_flag = map_opr.message_flag; + opr_data.param_flag = 0x1f; + len = build_mapparam(&map_opr,opr_data.param); + if(len<=0 || len>MAX_MAPPOPR_LEN) + { + return 0; + } + opr_data.param_len = len; + opr_data.param_flag |= 0x20; + + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map ATI_Req. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + + } + return pps_send_map_opr(&opr_data, 1); +} + + +int pps_send_routing_home_prn(u_short portid) +{ + char msisdn[32],buf[32]; + //char data_flow[256]; + int len; + struct MapOprData_struct opr_data; + struct MapOprSrv_struct map_opr; + struct MapPRN_Arg *prn_arg; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("pps_send_routing_home_prn"); + + shmp += portid; + + prn_arg = &map_opr.msg_list.prn_arg; + prn_arg->param_flag = 0x07; + memcpy(prn_arg->imsi, shmp->caller_info.IMSI, 8); + + //isdn_ston(msisdn, shmp->cdr_info.locationNumber); + isdn_ston((u8 *)msisdn, shmp->caller_info.number); + isdn_ntoa(prn_arg->msc_num, (u8 *)msisdn); + + ppsBcdToAsciiR(buf, shmp->cdr_info.called, 14); + StringCut(buf, 'F'); + StringCut(buf, 'E'); + isdn_ston((u8 *)msisdn, (u8 *)buf); + isdn_ntoa(prn_arg->msisdn, (u8 *)msisdn); + + + shmp->context_info.map_iid = + map_get_invokeid(shmp->context_info.map_did); + + map_opr.port_id = portid; + map_opr.dialogue_id = shmp->context_info.map_did; + map_opr.invoke_id = shmp->context_info.map_iid; + map_opr.message_type = ProvRoamNum; + map_opr.message_flag = MAP_REQUEST; + map_opr.version = 2; + + + opr_data.port_id = portid; + opr_data.dialogue_id = map_opr.dialogue_id; + opr_data.invoke_id = map_opr.invoke_id; + opr_data.message_type = map_opr.message_type; + opr_data.message_flag = map_opr.message_flag; + opr_data.param_flag = 0x1f; + + len = build_mapparam(&map_opr,opr_data.param); + if(len<=0 || len>MAX_MAPPOPR_LEN) + { + return 0; + } + opr_data.param_len = len; + opr_data.param_flag |= 0x20; + + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map PRN_Req. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + + } + return pps_send_map_opr(&opr_data, 1); +} + + +int pps_send_map_close(u_short portid) +{ + u_char data_flow[256]; + + _state_data *shmp=(_state_data *)&smshm_ptr->state_data; + + PutLogFunID("pps_send_mnp_ati"); + + shmp += portid; + + data_flow[0] = 0; + data_flow[1] = 12; + data_flow[2] = MAP_FLAG; + data_flow[3] = portid>>8; + data_flow[4] = portid & 0xff; + data_flow[5] = 0; + data_flow[6] = shmp->context_info.map_did >> 8; + data_flow[7] = shmp->context_info.map_did & 0xff; + data_flow[8] = 0x00; + data_flow[9] = MAP_CLOSE; + data_flow[10] = MAP_REQUEST; + data_flow[11] = NormalRelease; + data_flow[12] = 0x00; + data_flow[13] = 0x00; + //data_flow[1] = len; + + map_send_comdata(data_flow); + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map Close @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + pps_debug_map_msg(data_flow,1); + } + return 1; +} + +int pps_debug_map_msg(u_char *data_flow, int flag) +{ + int len,loop; + char buf[1024],buf1[6]; + + if(!flag) + DebugMsg(debugmib.display.asciiOut, + " \33[32m--

Rec. MSG @%ld.%ld\33[0m", + data_flow[3]*256+data_flow[4], + data_flow[6]*256+data_flow[7], + data_flow[9], + tvnow.tv_sec,tvnow.tv_usec); + else + DebugMsg(debugmib.display.asciiOut, + " \33[32m--

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 z z@H$P57CK}Bf-h;V7B`8VO?-%h@ym;((`?OBjH_PtF)l;cV%%Rel}1!&WQg%}6Sf$~ z>np0e8Lt?B+Qne348V8^9uJI?Z z%Hk5^m&7aBcBJeuU)|f%+s}~bMvUUo%+g2kxo6~_o;yDGG;Yw7-8}zdgC5>9jex@* z8!sP9zuh1c13F#1MUS7r>ieJ47)6R@x8HxbORsoA4)S9Cd?&5Cfpvb>MG#JYWO|vY z@HM6hZkn$$;{Qz8R^4oU&GRwijsKIJXo5`vRrmA-QgxE#R9yv!4?^Jjuo-f6< zKHGvIAEH_^m8FF)z30rP%)E7Yu8L!;zBssxNHq>|B)9v}fjU+kT z6d(ztC^rFH@5snG>5Tl$E|H%K7SAZ+4z!=PS03gjqI1E+UArj{@+^mk3_MGDc#P}n z<}=g+jCaLCF@>W0F2K!U0gBAOJY9<`p+)QYx;p>DD?Xc#A#B;q7--p?Wn{?aK_+b3 z9I7vwu4cTlxnf7-B&G$hnR~vlDM=2Sdm+i7(UpjX)V3f5Yhc`~Sb)JO{>Nan7EE0Z z-$9F!avY}CoX2v)A8_P}w!$&QKM}Ub4iNps{k>{ri0lj#w#ZJ`cS-j!UXlGgz#yv% zKz1n}3->2U4zjVLk$yj%sBNVC&{`XtC~8jsRo3MHN>sM^KO(ObEyl0WkylzwR>ah6 zOuI)~qO3m}SFG;s4X1wb*nLZ~&35fYzx8(ZX_pU{W^5EH%4Dv1X?A*KS;l{}sQ&4> ziu6nYy%ky^#u8;6#PQ$IDx*_T?aUQ7AE0`wrZloc2B{J`I#K%?BlT&c6V-Fme^s){ z*tCkZ{;xz?jr<5`Eir6yoHiDF9jA=NuE&Y-a|Y#)j!zhL=ID6AAdKnf2z!W)AuOaJ zoP)4Xf$#`~Gl>P^p$H2uga;!WGV$363kt+zU*!#hGDpWJ4ayiD-)T@ZzLH;y)-FhM zrLVFBjbpO`U%2D4=eljwalDp@zJ})TS2%Yz2QfaUIlTQ>wDvoDAip_iAX0K4R!

Snd. MSG @%ld.%ld\33[0m", + data_flow[3]*256+data_flow[4], + data_flow[6]*256+data_flow[7], + data_flow[9], + tvnow.tv_sec,tvnow.tv_usec); + len = data_flow[0] * 256 + data_flow[1]; + DebugMsg(debugmib.display.asciiOut,"------------ Message Flow ----------------"); + memset(buf,0,1024); + for(loop=0;loop1) + ppsParam.serviceControl.vms_allways_go = 0; + + if(ppsParam.serviceControl.licenseduser<10) + ppsParam.serviceControl.licenseduser = 10; + if(ppsParam.serviceControl.licenseduser>systemCapability) + ppsParam.serviceControl.licenseduser = systemCapability; + sprintf(buf,"%08u",ppsParam.serviceControl.licenseduser); + AsciiToBcd(debugmib.measurement.licensed_user,buf,8); + + if(ppsParam.max_call_duration < 1000 ) + ppsParam.max_call_duration = MAX_PREPAID_CALL_DURATION; + if(ppsParam.serviceControl.max_call_duration <= 0) + ppsParam.serviceControl.max_call_duration = 1; + if(ppsParam.serviceControl.answer_timer<40) + ppsParam.serviceControl.answer_timer = 40; + + if(ppsParam.max_quota_per_request<=0) + ppsParam.max_quota_per_request = 4; + if(ppsParam.data_quota_as_postpaid<=0) + ppsParam.data_quota_as_postpaid = 2; + + if(ppsParam.param_ver != 1) + { + int i; + + ppsParam.param_ver = 1; + + for(i=0;isystemCapability) + { + DebugMsg(debugmib.display.asciiOut,"Error license:%d>capability:%d!", + value,systemCapability); + return 0; + } + if(value255) + { + sprintf((char *)pdata,"Error value, should be 0-255"); + return -2; + } + ppsParam.serviceControl.maxRechargeFailedNum = iValue; + break; + case 4: /* max balance */ + for(loop = 0,ppsParam.serviceControl.maxBalance = 0;loop < dataLen;loop++) + { + ppsParam.serviceControl.maxBalance = ppsParam.serviceControl.maxBalance << 8; + ppsParam.serviceControl.maxBalance += pdata[loop]; + } + break; + case 5: /* currency symbol */ + memset(ppsParam.serviceControl.currencyName,0,8); + memcpy(ppsParam.serviceControl.currencyName,pdata,dataLen); + break; + case 6:/* cos option */ + ppsParam.serviceControl.cos_group_flag = pdata[0]; + break; + case 7: + ppsParam.serviceControl.support_mnp_flag = pdata[0]; + break; + case 8: + ppsParam.serviceControl.callingCardVadilityDays = pdata[0]; + break; + case 9: + case 10: + case 11: + case 12: + case 13: + ppsParam.serviceControl.languageSmEncodeType[oid2-9]= pdata[0]; + break; + case 14: + ppsParam.serviceControl.external_vc = pdata[0]; + break; + case 15: + ppsParam.serviceControl.charge_by_lac_flag = pdata[0]; + break; + case 16: + ppsParam.serviceControl.not_change_expiry_date_when_transfer = pdata[0]; + break; + case 17: + ppsParam.serviceControl.ussd_callback_service_key = pdata[0]; + break; + case 18: + memcpy(ppsParam.serviceControl.ucbc_number,pdata,dataLen); + ppsParam.serviceControl.ucbc_number[dataLen] = 0; + break; + default: + return -1; + break; + } + break; + case COSID: + return 0; + break; + case SrfParameter: + return 0; + break; + case RouteVMS: + return SetCRDParam(oidLen,oid,pdata,dataLen); + break; + case PPSOID_FileOperation: + if(peer_server_in_init) + { + sprintf((char *)pdata,"Peer server is initializing , please wait!"); + return -1; + } + switch(oid2) + { + case 1: /* subs. data */ + if(pdata[0] != 0x01) + { + return 0; /* not import */ + } + if(dataLen != 0x07) + { + return 0; + } + if(ppsParam.fileOperation.uploadUserData == 2) + return 0; + ppsParam.fileOperation.uploadUserData = pdata[0]; + memcpy(uploadUserStatus,&pdata[1],6); + SetLoadFileFlag(1); /* user data */ + break; + case 2: /* recharge card data */ + if(ppsParam.fileOperation.uploadPrepaidCard == 2) + return 0; + ppsParam.fileOperation.uploadPrepaidCard = pdata[0]; + memcpy(uploadPrecardStatus,&pdata[1],6); + SetLoadFileFlag(2); /* prepaid card */ + break; + case 3: /* tariff plan*/ + if(pdata[0] == 1){ + ppsParam.fileOperation.uploadTariffPlan = pdata[0]; + ppsParam.fileOperation.uploadTariffPlan = 0x02; + + SetLoadFileFlag(3); /* tariff data */ + }else if(pdata[0]==0){ + ppsParam.fileOperation.nextTariffStartTime = 0; + } + break; + case 4: /* tariff time*/ + memset(buf,0,sizeof(buf)); + memcpy(buf,pdata,dataLen); + ppsParam.fileOperation.nextTariffStartTime = MakeTime(NULL,buf); + break; + case 5: + + return setSaveCmdFlag(pdata[0],pdata); + break; + } + break; + case Status: /* system action */ + if(oid2 == 1) + { + debugmib.display.sysState = pdata[0]; + } + else if(oid2 == 2) + { + if(pdata[0]==1){ + SavePPSParam(); + }else if(pdata[0]==2){ + pps_exit(0); + } + } + break; + default: + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Get pps data error: error oid[12]:%d",oid[12]); + return 0; + break; + } + return dataLen; +} + + + + +int snmpGetPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, BYTE *vartype) +{ + + int oid0,oid1,oid2,vallen=1,instance; + char buf[BUFSIZE]; + + PutLogFunID("snmpGetPPS"); + + oid0 = oid[11]; + oid1 = oid[12]; + + *vartype = 0x04; + oid2 = oid[13]; + + switch(oid0) + { + case PPS_HEARTBEAT: + switch(oid1) + { + case 0x04: + return ReadDailyReportRequest(oidLen,oid,pdata,vartype); + break; + default: + break; + } + break; + case PPS_PARAMETER: + switch(oid1) + { + case ServiceControl: + switch(oid2) + { + case 1: /* license */ + *vartype = INTEGER; + vallen = 4; + pdata[0] = ppsParam.serviceControl.licenseduser>>24; + pdata[1] = ppsParam.serviceControl.licenseduser>>16; + pdata[2] = ppsParam.serviceControl.licenseduser>>8; + pdata[3] = ppsParam.serviceControl.licenseduser; + break; + case 2: /* cdr flag */ + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.cdrFlag; + break; + case 3: /* recharge failure threshold*/ + *vartype = INTEGER; + vallen = 1; + pdata[0] = ppsParam.serviceControl.maxRechargeFailedNum; + break; + case 4: /* max balance */ + *vartype = INTEGER; + vallen = 4; + pdata[0] = ppsParam.serviceControl.maxBalance>>24; + pdata[1] = ppsParam.serviceControl.maxBalance>>16; + pdata[2] = ppsParam.serviceControl.maxBalance>>8; + pdata[3] = ppsParam.serviceControl.maxBalance; + break; + case 5: /* currency symbol */ + vallen = strlen((char *)ppsParam.serviceControl.currencyName); + memcpy(pdata,ppsParam.serviceControl.currencyName,vallen); + break; + case 6:/* cos option */ + *vartype = INTEGER; + vallen = 1; + pdata[0] = ppsParam.serviceControl.cos_group_flag; + break; + case 7: + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.support_mnp_flag; + vallen = 1; + break; + case 8: + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.callingCardVadilityDays; + vallen = 1; + break; + case 9: + case 10: + case 11: + case 12: + case 13: + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.languageSmEncodeType[oid2-9]; + vallen = 1; + break; + case 14: + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.external_vc; + vallen = 1; + break; + case 15: + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.charge_by_lac_flag; + vallen = 1; + break; + case 16: + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.not_change_expiry_date_when_transfer; + vallen = 1; + break; + case 17: + *vartype = INTEGER; + pdata[0] = ppsParam.serviceControl.ussd_callback_service_key; + vallen = 1; + break; + case 18: + vallen = strlen((char *)ppsParam.serviceControl.ucbc_number); + memcpy(pdata,ppsParam.serviceControl.ucbc_number,vallen); + break; + default: + return 0; + break; + } + break; + case COSID: + return 0; + break; + case SrfParameter: + return 0; + break; + case RouteVMS: + return GetCRDParam(oidLen,oid,pdata,vartype); + break; + case PPSOID_FileOperation: + switch(oid2) + { + case 1: /* import subs data */ + pdata[0] = ppsParam.fileOperation.uploadUserData; + memcpy(&pdata[1],uploadUserStatus,6); + *vartype = 0x44; + vallen = 7; + break; + case 2: /* import recharge card data */ + pdata[0] = ppsParam.fileOperation.uploadPrepaidCard; + memcpy(&pdata[1],uploadPrecardStatus,6); + *vartype = 0x44; + vallen = 7; + break; + case 3: /* tariff plan */ + pdata[0] = ppsParam.fileOperation.uploadTariffPlan; + *vartype = 0x02; + break; + case 4: /* time for new tariff plan to take place */ + AsciiTime(buf,ppsParam.fileOperation.nextTariffStartTime); + AsciiToBcd(pdata,buf,14); + vallen = 7; + break; + } + break; + case Status: /* system action */ + if(oid2 == 1) + { + vallen = 1; + *vartype = INTEGER; + pdata[0] = debugmib.display.sysState; + } + break; + case PPSOID_InitRequest: + return PeerServerRamInitRequest(oidLen,oid,pdata,vartype); + break; + default: + vallen = -1; + break; + } + break; + case PPS_CSTA: /* csta */ + if(oidLen<13) return -1; + instance = oid[12]; + if(instance<0 || instance >= MAX_CSTA_LEN) return -1; + vallen = GetCSTA_Record(instance,pdata); + break; + case PPS_CDR: /* cdr */ + if(oid1 == 1 || oid1 == 2) + return GetCDRParam(oid1,pdata); + if(oidLen<14) return -1; + instance = oid[13]; + vallen = GetCDR_Record(instance,pdata); /* oid2=squence */ + break; + case PPS_USERDATA: + return GetDatabase(oidLen,oid,pdata,vartype); + break; + case 0x09: /* status */ + vallen = 1; + *vartype = INTEGER; + pdata[0] = debugmib.display.sysState; + break; + default: + vallen = -1; + break; + } + return vallen; +} + +void snmpTrapPPS(BYTE oidLen, DWORD *oid, BYTE *pdata, u_short dataLen,snmp_addr *addr) +{ + u_char peerParameterSum; + + PutLogFunID("snmpTrapPPS"); + + if(oid[8]==4) + { /* OMC */ + unsigned char sNumber[5]; + AsciiToBcd(sNumber,serialNumber,8); + if(memcmp(pdata+39,sNumber,4) !=0) + return ; + switch(pdata[0]) + { + case 0: + primary_data_server = addr->remote_ip; + break; + case 1: + second_data_server = addr->remote_ip; + break; + } + + return ; + } + + if(oid[10] == PPSOID) + {/* pps peer server */ + switch(oid[11]) + { + case PPS_HEARTBEAT: /* heartbeat */ + pps_peer_hb_flag = 1; + if(addr->remote_ip !=LOCAL_IP && pdata[1] != pps_get_subid()) + { + memcpy(peer_version_id,&pdata[23],3); + peer_server_ip = addr->remote_ip; + } + peerParameterSum = pdata[27]; + if(peerParameterSum != sumOfParameter) + { + // alarm_code[0] = 0; + // alarm_code[1] = 5; + } + debugmib.display.peer_state = 0x10 | pdata[26]; + /* a method to check peer server hb, and state , + as normal state = 0, so 0x10 is OR to the state */ + debugmib.measurement.peer_usernumber = + pdata[35] * 256 * 65536 + + pdata[36] * 65536 + + pdata[37] * 256+ + pdata[38]; + + if((debugmib.measurement.peer_usernumber > + debugmib.measurement.usernumber) && masterFlag) + { + debugmib.display.masterIP = addr->remote_ip; + masterFlag = 0; + } + else if((debugmib.measurement.peer_usernumber < + debugmib.measurement.usernumber) && !masterFlag) + { + debugmib.display.masterIP = LOCAL_IP; + masterFlag = 1; + } + debugmib.display.peer_state_counter = 0; + +#ifdef CONVERT_16DIGIT_CARD + if(memcmp(peer_version_id,version_id,3)) + stopReceivePeriodicSyncFlag = 1; + else + stopReceivePeriodicSyncFlag = 0; +#endif + break; + case PPS_CSTA: /* csta */ + GotSyncDailyReport(oid,pdata,dataLen); + break; + default: + break; + } + } + if(oid[10] == 26) + { + ppsParam.rcm_ip = addr->remote_ip; + } +} + +/*----------------CDR functions ---------------------------------------*/ + +int SetCDRParam(BYTE oidLen, DWORD *oid, BYTE *pdata, u_short datalen) +{ + int subOID; + int pWriteSub; + + PutLogFunID("SetCDRParam"); + + subOID = oid[12]; + + if(datalen == 1) + { + pWriteSub = pdata[0]; + } + else if(datalen == 2 ) + { + pWriteSub = pdata[1] +pdata[0]* 256; + } + else if(datalen == 3) + { + pWriteSub = pdata[2] + (pdata[1] + pdata[0]*256)*65536; + } + else if(datalen ==4) + { + pWriteSub = (pdata[3] + pdata[2]*256) + (pdata[1] + pdata[0]*256)*65536; + } + else + { + return -1; + } + + switch(subOID) + { + case 0x01: /* head */ + cdr_head_ptr = pWriteSub; + pps_cdr_buffer.pWriteSub = pWriteSub % MAX_CDR_LEN; + break; + case 0x02: /* tail */ + cdr_tail_ptr = pWriteSub; + break; + default: + return -1; + break; + } + return datalen; +} + +int GetCDRParam(DWORD oid, BYTE *pdata) +{ + + int pWriteSub; + + PutLogFunID("GetCDRParam"); + + switch(oid) + { + case 0x01: /* head */ + pWriteSub = cdr_head_ptr ; + break; + case 0x02: /* tail */ + pWriteSub = cdr_tail_ptr ; + break; + default: + return -1; + break; + } + pdata[0] = pWriteSub>>24; + pdata[1] = pWriteSub>>16; + pdata[2] = pWriteSub>>8; + pdata[3] = pWriteSub; + return 4; +} + +int GetCDR_Record(int instance,BYTE *pdata) +{ + int pReadSub,tmpLen = 0; + + PutLogFunID("GetCDR_Record"); + + pReadSub = instance % MAX_CDR_LEN; + if(pReadSub == cdr_head_ptr) + return 0; + tmpLen = pps_cdr_buffer.cdrMsg[pReadSub][0]%254; + memcpy(pdata,&pps_cdr_buffer.cdrMsg[pReadSub][1],tmpLen); + return tmpLen; +} + +/* +int GetCDR_Record(int instance,BYTE *pdata) +{ + int recordType=0,pReadSub; + _tocdr_report *pcdr = NULL; + + PutLogFunID("GetCDR_Record"); + + pReadSub = instance % MAX_CDR_LEN; + if(pReadSub == cdr_head_ptr) + return 0; + pcdr = &pps_cdr_buffer.cdr_record[pReadSub]; + if(pcdr->caller[0] == 0x00) return 0; + + recordType = pcdr->mtype; + switch(recordType) + { + case MO_CDR_TYPE: + return GetMO_CDR(pcdr, pdata); + break; + case MT_CDR_TYPE: + return GetMT_CDR(pcdr, pdata); + break; + default: + break; + } + return 0; +} +*/ + +int GetMO_CDR(_tocdr_report *pcdr, BYTE *pdata) +{ + int len = 0, recordType=0; + ASN_BUF *asnbuf, asnbuf1; + u_char buf[BUFSIZE]={""},charge[8],balance[8],duration[8]; + + PutLogFunID("GetMO_CDR"); + + asnbuf = &asnbuf1; + asn_encode(pdata,asnbuf); + + recordType = pcdr->mtype; + len = add_int("2-1",pcdr->squence,0x00,asnbuf); + len = add_tlv("0-2.0",1,(u_char *)&recordType,0x80,asnbuf); /* record type */ + len = add_tlv("0-2.1",8,pcdr->imsi,0x80,asnbuf); /* served IMSI */ + len = add_tlv("0-2.3",9,pcdr->msisdn,0x80,asnbuf); /* served MSISDN */ + len = add_tlv("0-2.4",9,pcdr->caller,0x80,asnbuf); /* calling number */ + len = add_tlv("0-2.5",12,pcdr->called,0x80,asnbuf); /* called number */ + len = add_tlv("0-2.9",10,ppsParam.ppsNumber,0x80,asnbuf); /* Recording Entity */ + + CharToTimeStamp(buf, (char *)pcdr->seizuretime); + len = add_tlv("0-2.22",8,buf,0x80,asnbuf); /* seizure timestamp */ + CharToTimeStamp(buf, (char *)pcdr->answertime); + len = add_tlv("0-2.23",8,buf,0x80,asnbuf); /* answer timestamp*/ + CharToTimeStamp(buf, (char *)pcdr->releasetime); + len = add_tlv("0-2.24",8,buf,0x80,asnbuf); /* release timestamp*/ + duration[0] = pcdr->duration[3]; + duration[1] = pcdr->duration[2]; + duration[2] = pcdr->duration[1]; + duration[3] = pcdr->duration[0]; + len = add_tlv("0-2.25",4,duration,0x80,asnbuf);/*call duration*/ + len = add_tlv("0-2.30",1,pcdr->tcos,0x80,asnbuf); /* cause for term*/ + len = add_tlv("0-2.128",1,pcdr->type,0x80,asnbuf); /* call type */ + charge[0] = pcdr->charge[3]; + charge[1] = pcdr->charge[2]; + charge[2] = pcdr->charge[1]; + charge[3] = pcdr->charge[0]; + len = add_tlv("0-2.129",4,charge,0x80,asnbuf); /* charge */ + balance[0] = pcdr->balance[3]; + balance[1] = pcdr->balance[2]; + balance[2] = pcdr->balance[1]; + balance[3] = pcdr->balance[0]; + len = add_tlv("0-2.130",4,balance,0x80,asnbuf); /* balance */ + return len; +} + + +int GetMT_CDR(_tocdr_report *pcdr, BYTE *pdata) +{ + int len = 0, recordType=0; + ASN_BUF *asnbuf, asnbuf1; + + u_char buf[BUFSIZE]={""},charge[8],balance[8],duration[8]; + + PutLogFunID("GetMT_CDR"); + + asnbuf = &asnbuf1; + asn_encode(pdata,asnbuf); + + recordType = pcdr->mtype; + len = add_int("2-1",pcdr->squence,0x00,asnbuf); + len = add_tlv("1-2.0",1,(u_char *)&recordType,0x80,asnbuf); /* record type */ + len = add_tlv("1-2.1",8,pcdr->imsi,0x80,asnbuf); /* served IMSI */ + len = add_tlv("1-2.3",9,pcdr->called,0x80,asnbuf); /* called number */ + len = add_tlv("1-2.4",9,pcdr->caller,0x80,asnbuf); /* calling number */ + len = add_tlv("1-2.5",9,pcdr->called,0x80,asnbuf); /* connected number */ + len = add_tlv("1-2.6",10,ppsParam.ppsNumber,0x80,asnbuf); /* Recording Entity */ + + CharToTimeStamp(buf, (char *)pcdr->seizuretime); + len = add_tlv("1-2.19",8,buf,0x80,asnbuf); /* seizure timestamp */ + CharToTimeStamp(buf, (char *)pcdr->answertime); + len = add_tlv("1-2.20",8,buf,0x80,asnbuf); /* answer timestamp*/ + CharToTimeStamp(buf, (char *)pcdr->releasetime); + len = add_tlv("1-2.21",8,buf,0x80,asnbuf); /* release timestamp*/ + duration[0] = pcdr->duration[3]; + duration[1] = pcdr->duration[2]; + duration[2] = pcdr->duration[1]; + duration[3] = pcdr->duration[0]; + len = add_tlv("1-2.22",4,duration,0x80,asnbuf);/*call duration*/ + len = add_tlv("1-2.27",1,pcdr->tcos,0x80,asnbuf); /* cause for term*/ + len = add_tlv("1-2.128",1,pcdr->type,0x80,asnbuf); /* call type */ + charge[0] = pcdr->charge[3]; + charge[1] = pcdr->charge[2]; + charge[2] = pcdr->charge[1]; + charge[3] = pcdr->charge[0]; + len = add_tlv("1-2.129",4,charge,0x80,asnbuf); /* charge */ + balance[0] = pcdr->balance[3]; + balance[1] = pcdr->balance[2]; + balance[2] = pcdr->balance[1]; + balance[3] = pcdr->balance[0]; + len = add_tlv("1-2.130",4,balance,0x80,asnbuf); /* balance */ + return len; +} + + +int GetCSTA_Record(int instance, BYTE *pdata) +{ + int loop,totalsum,start; + _pps_csta_record *pcsta = &pps_csta_buffer.csta_record[instance]; + + PutLogFunID("GetCSTA_Record"); + + pdata[0] = pcsta->timestamp>>24; + pdata[1] = pcsta->timestamp>>16; + pdata[2] = pcsta->timestamp>>8; + pdata[3] = pcsta->timestamp; + + start = 4; + totalsum = 0; + for(loop=0;loopcsta_type[loop].number>>24; + pdata[start++] = pcsta->csta_type[loop].number>>16; + pdata[start++] = pcsta->csta_type[loop].number>>8; + pdata[start++] = pcsta->csta_type[loop].number; + totalsum += pcsta->csta_type[loop].number; + } + totalsum = 0; + for(loop=0;loopcsta_type[loop].charge>>24; + pdata[start++] = pcsta->csta_type[loop].charge>>16; + pdata[start++] = pcsta->csta_type[loop].charge>>8; + pdata[start++] = pcsta->csta_type[loop].charge; + totalsum += pcsta->csta_type[loop].charge; + } + + totalsum = 0; + for(loop=0;loopcsta_type[loop].duration>>24; + pdata[start++] = pcsta->csta_type[loop].duration>>16; + pdata[start++] = pcsta->csta_type[loop].duration>>8; + pdata[start++] = pcsta->csta_type[loop].duration; + totalsum += pcsta->csta_type[loop].duration; + } + + pdata[start++] = pcsta->gprsCsta.number>>24; + pdata[start++] = pcsta->gprsCsta.number>>16; + pdata[start++] = pcsta->gprsCsta.number>>8; + pdata[start++] = pcsta->gprsCsta.number; + + pdata[start++] = pcsta->gprsCsta.charge>>24; + pdata[start++] = pcsta->gprsCsta.charge>>16; + pdata[start++] = pcsta->gprsCsta.charge>>8; + pdata[start++] = pcsta->gprsCsta.charge; + + pdata[start++] = pcsta->gprsCsta.duration>>24; + pdata[start++] = pcsta->gprsCsta.duration>>16; + pdata[start++] = pcsta->gprsCsta.duration>>8; + pdata[start++] = pcsta->gprsCsta.duration; + + pdata[start++] = pcsta->gprsCsta.gprsVolume>>24; + pdata[start++] = pcsta->gprsCsta.gprsVolume>>16; + pdata[start++] = pcsta->gprsCsta.gprsVolume>>8; + pdata[start++] = pcsta->gprsCsta.gprsVolume; + + pdata[start++] = pcsta->vasCsta.smsNumber>>24; + pdata[start++] = pcsta->vasCsta.smsNumber>>16; + pdata[start++] = pcsta->vasCsta.smsNumber>>8; + pdata[start++] = pcsta->vasCsta.smsNumber; + + pdata[start++] = pcsta->vasCsta.smsCharge>>24; + pdata[start++] = pcsta->vasCsta.smsCharge>>16; + pdata[start++] = pcsta->vasCsta.smsCharge>>8; + pdata[start++] = pcsta->vasCsta.smsCharge; + + pdata[start++] = pcsta->vasCsta.mmsSendNumber>>24; + pdata[start++] = pcsta->vasCsta.mmsSendNumber>>16; + pdata[start++] = pcsta->vasCsta.mmsSendNumber>>8; + pdata[start++] = pcsta->vasCsta.mmsSendNumber; + + pdata[start++] = pcsta->vasCsta.mmsSendCharge>>24; + pdata[start++] = pcsta->vasCsta.mmsSendCharge>>16; + pdata[start++] = pcsta->vasCsta.mmsSendCharge>>8; + pdata[start++] = pcsta->vasCsta.mmsSendCharge; + + + pdata[start++] = pcsta->vasCsta.mmsRetrieveNumber>>24; + pdata[start++] = pcsta->vasCsta.mmsRetrieveNumber>>16; + pdata[start++] = pcsta->vasCsta.mmsRetrieveNumber>>8; + pdata[start++] = pcsta->vasCsta.mmsRetrieveNumber; + + pdata[start++] = pcsta->vasCsta.mmsRetrieveCharge>>24; + pdata[start++] = pcsta->vasCsta.mmsRetrieveCharge>>16; + pdata[start++] = pcsta->vasCsta.mmsRetrieveCharge>>8; + pdata[start++] = pcsta->vasCsta.mmsRetrieveCharge; + + pdata[start++] = pcsta->vasCsta.mmsEmailNumber>>24; + pdata[start++] = pcsta->vasCsta.mmsEmailNumber>>16; + pdata[start++] = pcsta->vasCsta.mmsEmailNumber>>8; + pdata[start++] = pcsta->vasCsta.mmsEmailNumber; + + pdata[start++] = pcsta->vasCsta.mmsEmailCharge>>24; + pdata[start++] = pcsta->vasCsta.mmsEmailCharge>>16; + pdata[start++] = pcsta->vasCsta.mmsEmailCharge>>8; + pdata[start++] = pcsta->vasCsta.mmsEmailCharge; + return start; +} + +/*----------------CDR functions ---------------------------------------*/ +/* ------------------ debug functions ---------------------------------*/ + +BYTE pps_disp_line(BYTE page, BYTE line) +/* return display length,disp data ptr per line */ +{ + BYTE disp_length; + + disp_length = 1; + + + switch (page) + { + case 1: /* page 1 */ + disp_length = 1; + switch (line-2) + { + case 0: + disp_ptr=(char *)&ppsParam.serviceControl.cdrFlag; + break; + case 1: + disp_ptr=(char *)&ppsParam.serviceControl.maxRechargeFailedNum; + break; + case 2: + disp_ptr=(char *)&ppsParam.rcm_ip; + disp_length = 4; + break; + case 3: + disp_length = 8; + disp_ptr=(char *)&ppsParam.serviceControl.currencyName; + break; + case 4: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.srfNumber[0].number; + break; + case 5: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.srfNumber[1].number; + break; + case 6: + disp_length = 1; + disp_ptr =(char *)&ppsParam.ppsTables.srfNumber[0].reachable; + break; + case 7: + disp_length = 1; + disp_ptr =(char *)&ppsParam.ppsTables.srfNumber[1].reachable; + break; + case 8: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number; + break; + case 9: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number; + break; + case 10: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number; + break; + case 11: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.serviceNumber[ThirdPartyRechargeNumberPosition].number; + break; + case 12: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.serviceNumber[CustomerCareCenterNumberPosition].number; + break; + case 13: + disp_length = 16; + disp_ptr =(char *)&ppsParam.ppsTables.serviceNumber[RechargeNumberPosition].number; + break; + case 14: + disp_length = 1; + // disp_ptr =(char *)&ppsParam.ppsTables.srf_param.srf_flag; + break; + case 15: + disp_length = 1; + disp_ptr =(char *)&ppsParam.serviceControl.support_mnp_flag; + break; + case 17: + disp_length = 3; + disp_ptr = (char *)&ppsParam.serviceControl.mt_release_for_no_charge; + break; + default: + disp_length = 0; + break; + } + break; + case 2: + disp_length = 2; + switch(line-2){ + case 0: + disp_length = 1; + disp_ptr = (char *)&masterFlag; + break; + case 1: + disp_length = 1; + disp_ptr = &debugmib.display.sysState; + break; + case 2: + disp_length = 1; + disp_ptr = &debugmib.display.dataSrc; + break; + case 3: + disp_length = 1; + disp_ptr = &debugmib.display.initProgress; + break; + case 4: + disp_length = 4; + disp_ptr = (char *)&debugmib.display.masterIP; + break; + case 5: + disp_length = 4; + disp_ptr = (char *)&peer_server_ip; + break; + case 6: + disp_length = 1; + disp_ptr = (char *)&debugmib.display.peer_state; + break; + case 7: + disp_length = 16; + disp_ptr = (char *)&debugmib.display.proc_used; + break; + case 8: + disp_length = 4; + disp_ptr = (char *)&debugmib.display.totalCharge; + break; + case 9: + disp_length = 16; + disp_ptr = (char *)&debugmib.display.ro_used; + break; + default: + disp_length = 0; + break; + } + break; + case 33: + switch(line-2) + { + case 0: + disp_length = 2; + //debugmib.display.proc_begin = 0; + disp_ptr = (char *)&debugmib.display.proc_begin; + break; + default: + disp_length = 16; + disp_ptr = (char *)&smshm_ptr->port_info[(line-2)*8]; + break; + } + break; + case 3: + disp_length = 4; + switch(line-2) + { + case 0: + disp_ptr=(char *)&debugmib.measurement.sys_capability; + break; + case 1: + disp_ptr = (char *)&ppsParam.serviceControl.licenseduser; + break; + case 2: + disp_length = 4; + disp_ptr = (char *)&debugmib.measurement.user_number; + break; + case 3: + disp_length = 4; + disp_ptr = (char *)&debugmib.measurement.free_index; + break; + case 4: + disp_length = 4; + disp_ptr = (char *)&debugmib.measurement.peer_usernumber; + break; + case 6: + disp_length = 16; + disp_ptr = (char *)&debugmib.msgstatistics.send_sync[0]; + break; + case 7: + disp_length = 16; + disp_ptr = (char *)&debugmib.msgstatistics.recv_sync[0]; + break; + case 9: + disp_length = 1; + disp_ptr = (char *)&debugmib.measurement.index_alarm; + break; + case 10: + disp_length = 16; + disp_ptr = (char *)&debugmib.measurement.search_table_result; + break; + default: + disp_length = 0; + break; + } + break; + case 4: + disp_length = 16; + switch(line-2) + { + case 0: + disp_length = 4; + disp_ptr=(char *)&debugmib.measurement.card_number; + break; + case 1: + disp_length = 4; + disp_ptr=(char *)&debugmib.measurement.cardheadnumber; + break; + default: + memset(&debugmib.measurement.card_prefix[(line-4)*4],0,16); + disp_ptr = (char *)&debugmib.measurement.card_prefix[(line-4)*4][0]; + break; + } + break; + case 5: + disp_length = 4; + switch(line-2) + { + case 0: + disp_ptr=(char *)&debugmib.msgstatistics.CapOpen; + break; + case 1: + disp_ptr=(char *)&debugmib.msgstatistics.Initialdp; + disp_length = 8; + break; + case 2: + disp_ptr=(char *)&debugmib.msgstatistics.RequestBCSM; + disp_length = 8; + break; + case 3: + disp_ptr=(char *)&debugmib.msgstatistics.ApplyCharging; + disp_length = 8; + break; + case 4: + // disp_ptr=(char *)&debugmib.msgstatistics.Continue; + disp_length = 8; + break; + case 5: + disp_ptr=(char *)&debugmib.msgstatistics.ActivityS; + disp_length = 8; + break; + case 6: + disp_ptr=(char *)&debugmib.msgstatistics.ChargingReport; + disp_length = 8; + break; + case 7: + //disp_ptr=(char *)&debugmib.msgstatistics.ReportBCSM; + //disp_length = 8; + break; + case 8: + disp_ptr=(char *)&debugmib.msgstatistics.Answered; + disp_length = 8; + break; + case 9: + disp_ptr=(char *)&debugmib.msgstatistics.Disconnect; + disp_length = 8; + break; + case 10: + disp_ptr=(char *)&debugmib.msgstatistics.Releasecall; + disp_length = 8; + break; + case 11: + disp_ptr=(char *)&debugmib.msgstatistics.Inquire; + break; + case 12: + disp_ptr=(char *)&debugmib.msgstatistics.Recharge; + break; + case 13: + disp_ptr=(char *)&debugmib.msgstatistics.ReadCard; + break; + case 14: + disp_ptr=(char *)&debugmib.msgstatistics.ReadCardRsp; + break; + case 15: + disp_ptr=(char *)&debugmib.msgstatistics.WriteCard; + break; + case 16: + disp_ptr=(char *)&debugmib.msgstatistics.WriteCardRsp; + break; + case 17: + disp_ptr=(char *)&debugmib.msgstatistics.Playannounce; + break; + case 18: + disp_ptr=(char *)&debugmib.msgstatistics.Accountinfo; + break; + case 19: + disp_ptr=(char *)&debugmib.msgstatistics.Accinfoack; + break; + default: + disp_length = 0; + break; + } + break; + case 6: + disp_length = 4; + switch(line-2){ + case 0: + disp_ptr = (char *)&debugmib.msgstatistics.InitialDP_SMS; + break; + case 1: + disp_ptr = (char *)&debugmib.msgstatistics.Request_SMS; + break; + case 2: + disp_ptr = (char *)&debugmib.msgstatistics.Continue_SMS; + break; + case 3: + disp_ptr = (char *)&debugmib.msgstatistics.Report_SMS; + break; + case 4: + disp_ptr = (char *)&debugmib.msgstatistics.Release_SMS; + break; + case 6: + disp_ptr = (char *)&debugmib.msgstatistics.Conference; + break; + case 8: + disp_ptr = (char *)&debugmib.msgstatistics.ThirdParty; + break; + case 10: + disp_ptr = (char *)&debugmib.msgstatistics.ConnectToResource; + break; + case 11: + disp_ptr = (char *)&debugmib.msgstatistics.PlayAnnouncement; + break; + case 12: + disp_ptr = (char *)&debugmib.msgstatistics.EstablishTemporaryConnection; + break; + case 13: + disp_ptr = (char *)&debugmib.msgstatistics.AssistInstructions; + break; + case 14: + disp_ptr = (char *)&debugmib.msgstatistics.PCUI; + break; + case 15: + disp_ptr = (char *)&debugmib.msgstatistics.PCUI_rsp; + break; + case 16: + disp_ptr = (char *)&debugmib.msgstatistics.SpecialResourceReport; + break; + case 17: + disp_ptr = (char *)&debugmib.msgstatistics.DisconnectForwardConnection; + break; + case 18: + disp_ptr = (char *)&debugmib.msgstatistics.smInquiry; + break; + case 19: + disp_ptr = (char *)&debugmib.msgstatistics.smRecharge; + break; + default: + disp_length = 0; + break; + } + break; + case 7: + disp_length = 0; + switch(line-2) + { + case 0: + case 1: + case 2: + case 3: + disp_length = 16; + disp_ptr=(char *)&debugmib.watch_dog[(line-5)*16]; + break; + case 4: + break; + case 5: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.update_card_request; + break; + case 6: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.update_card_ok; + break; + case 7: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.update_card_error_msg; + break; + case 8: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.update_card_no_card; + break; + case 9: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.update_card_expired; + break; + case 10: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.update_card_sys_failure; + break; + default: + disp_length = 0; + break; + } + break; + case 8: + disp_length = 16; + switch(line-2) + { + case 0: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation_date[0]; + break; + case 1: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[0][0]; + break; + case 2: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[0][4]; + break; + case 3: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[0][8]; + break; + case 4: + disp_length = 0; + break; + case 5: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation_date[1]; + break; + case 6: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[1][0]; + break; + case 7: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[1][4]; + break; + case 8: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[1][8]; + break; + case 9: + disp_length = 0; + break; + case 10: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation_date[2]; + break; + case 11: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[2][0]; + break; + case 12: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[2][4]; + break; + case 13: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[2][8]; + break; + case 14: + disp_length = 0; + break; + case 15: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation_date[3]; + break; + case 16: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[3][0]; + break; + case 17: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[3][4]; + break; + case 18: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[3][8]; + break; + default: + disp_length = 0; + break; + } + break; + case 9: + disp_length = 16; + switch(line-2) + { + case 0: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation_date[4]; + break; + case 1: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[4][0]; + break; + case 2: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[4][4]; + break; + case 3: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[4][8]; + break; + case 4: + disp_length = 0; + break; + case 5: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation_date[5]; + break; + case 6: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[5][0]; + break; + case 7: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[5][4]; + break; + case 8: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[5][8]; + break; + case 9: + disp_length = 0; + break; + case 10: + disp_length = 4; + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation_date[6]; + break; + case 11: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[6][0]; + break; + case 12: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[6][4]; + break; + case 13: + disp_ptr=(char *)&debugmib.msgstatistics.ussd_operation[6][8]; + break; + default: + disp_length = 0; + break; + } + break; + default: + disp_length = 0; + break; + } + return disp_length; +} + + +void pps_disp_page(BYTE page) +{ + BYTE disp_line; + BYTE disp_length; + + + debug_page_line[PPS_PAGE_POINT] = page + 5;/* page */ + for (disp_line = 2; disp_line < 22; disp_line++) + { + disp_length = pps_disp_line(page,disp_line); + debug_page_line[PPS_LINE_POINT] = disp_line + 2;/* line */ + debug_page_line[PPS_LINE_POINT+1] = 2;/* data pointer */ + debug_set_response(PPS_BASE_ID_LEN+2,debug_page_line, (BYTE *)disp_ptr,disp_length); + } +} + + + +int pps_debug_set() +{ + BYTE page; + BYTE data[32]; + BYTE *ptr; + char version_info[32]={""}; + sprintf(version_info,"V%d.%d.%02d",version_id[0],version_id[1],version_id[2]); + + ptr = data; + + debug_set_response(PPS_BASE_ID_LEN,debug_status_id,&debug_status,1); + debug_set_response(PPS_BASE_ID_LEN,debug_name_id, (BYTE *)version_info,10); + /* module name */ + debug_set_response(PPS_BASE_ID_LEN,debug_ascin_id, (BYTE *)debugmib.display.asciiIn,4096); + /* ascii in buf */ + debug_set_response(PPS_BASE_ID_LEN,debug_ascout_id, (BYTE *)debugmib.display.asciiOut,4096); + /* ascii out buf */ + + for (page = 1; page < 10; page ++) + { + switch (page) + { + case 1: + ptr = title1_p; + break; + case 2: + ptr = title2_p; + break; + case 3: + ptr = title3_p; + break; + case 4: + ptr = title4_p; + break; + case 5: + ptr = title5_p; + break; + case 6: + ptr = title6_p; + break; + case 7: + ptr = title7_p; + break; + case 8: + ptr = title8_p; + break; + case 9: + ptr = title9_p; + break; + default: + ptr = NULL; + continue; + break; + } + debug_page_title[PPS_PAGE_POINT] = 5 + page; + debug_set_response(PPS_BASE_ID_LEN+1,debug_page_title,ptr,strlen((char *)ptr)); + pps_disp_page(page); + } + + return 1; +} + +void AddPPSStatistics(int index,int dir) +{ + PutLogFunID("AddPPSStatistics"); + + switch(index) + { + case MIBPPS_CAPOPEN: + debugmib.msgstatistics.CapOpen ++; + break; + case MIBPPS_INITIALDP: + debugmib.msgstatistics.Initialdp[dir] ++; + break; + case MIBPPS_REQUESTBCSM: + debugmib.msgstatistics.RequestBCSM[dir] ++; + break; + case MIBPPS_APPLYCHARGING: + debugmib.msgstatistics.ApplyCharging[dir] ++; + break; + case MIBPPS_CONTINUE: + //debugmib.msgstatistics.Continue[dir] ++; + break; + case MIBPPS_ACTIVITYS: + debugmib.msgstatistics.ActivityS ++; + break; + case MIBPPS_ACTIVITYR: + debugmib.msgstatistics.ActivityR ++; + break; + case MIBPPS_CHARGINGREPORT: + debugmib.msgstatistics.ChargingReport[dir] ++; + break; + case MIBPPS_REPORTBCSM: + debugmib.msgstatistics.ReportBCSM[dir] ++; + break; + case MIBPPS_ANSWERED: + debugmib.msgstatistics.Answered[dir] ++; + break; + case MIBPPS_DISCONNECT: + debugmib.msgstatistics.Disconnect[dir] ++; + break; + case MIBPPS_RELEASECALL: + debugmib.msgstatistics.Releasecall[dir] ++; + break; + case MIBPPS_INQUIRE: + debugmib.msgstatistics.Inquire ++; + break; + case MIBPPS_RECHARGE: + debugmib.msgstatistics.Recharge ++; + break; + case MIBPPS_PLAYANNOUNCE: + debugmib.msgstatistics.Playannounce ++; + break; + case MIBPPS_READCARD: + debugmib.msgstatistics.ReadCard ++; + break; + case MIBPPS_READCARDRSP: + debugmib.msgstatistics.ReadCardRsp ++; + break; + case MIBPPS_WRITECARD: + debugmib.msgstatistics.WriteCard ++; + break; + case MIBPPS_WRITECARDRSP: + debugmib.msgstatistics.WriteCard ++; + break; + case MIBPPS_ACCOUNTINFO: + debugmib.msgstatistics.Accountinfo ++; + break; + case MIBPPS_ACCINFOACK: + debugmib.msgstatistics.Accinfoack ++; + break; + case MIBPPS_CDRNUMBER: + debugmib.measurement.cdrnumber ++; + break; + case MIBPPS_CSTANUMBER: + debugmib.measurement.cstanumber ++; + break; + case MIBPPS_CDROVERFLOW: + debugmib.measurement.cdroverflow ++; + break; + case MIBPPS_BLACKLIST: + debugmib.measurement.blacklist ++; + break; + case MIBPPS_SUSPEND: + debugmib.measurement.suspend++; + break; + case MIBPPS_INITIALDP_SMS: + debugmib.msgstatistics.InitialDP_SMS++; + break; + case MIBPPS_REQUEST_SMS: + debugmib.msgstatistics.Request_SMS++; + break; + case MIBPPS_CONTINUE_SMS: + debugmib.msgstatistics.Continue_SMS++; + break; + case MIBPPS_REPORT_SMS: + debugmib.msgstatistics.Report_SMS++; + break; + case MIBPPS_RELEASE_SMS: + debugmib.msgstatistics.Release_SMS++; + break; + case MIBPPS_CONFERENCE: + debugmib.msgstatistics.Conference++; + break; + case MIBPPS_THIRD_PARTY: + debugmib.msgstatistics.ThirdParty++; + break; + case MIBPPS_CONNECT_TO_RESOURCE: + debugmib.msgstatistics.ConnectToResource++; + break; + case MIBPPS_PLAY_ANNOUNCEMENT: + debugmib.msgstatistics.PlayAnnouncement++; + break; + case MIBPPS_EST_TMP_CNT: + debugmib.msgstatistics.EstablishTemporaryConnection++; + break; + case MIBPPS_AST_INS: + debugmib.msgstatistics.AssistInstructions++; + break; + case MIBPPS_PCUI: + debugmib.msgstatistics.PCUI++; + break; + case MIBPPS_PCUI_RES: + debugmib.msgstatistics.PCUI_rsp++; + break; + case MIBPPS_SPE_RUS_RPT: + debugmib.msgstatistics.SpecialResourceReport++; + break; + case MIBPPS_DISCNT_FWD_CNT: + debugmib.msgstatistics.DisconnectForwardConnection++; + break; + case MIBPPS_SM_INQUIRY: + debugmib.msgstatistics.smInquiry++; + break; + case MIBPPS_SM_RECHARGE: + debugmib.msgstatistics.smRecharge++; + break; + default: + break; + } +} + +int ppsDebugRt() +{ + int pageno, len; + char cmd[1024]={""}; + + PutLogFunID("ppsDebugRt"); + + if(clearSubsFlag) + { + if(waitClearSubsConfirmCounter++>1200) + { + DebugMsg(debugmib.display.asciiOut,"Command: clear all subs expired!"); + clearSubsFlag = 0; + } + } + if(clearCardFlag) + { + if(waitClearCardConfirmCounter++>1200) + { + DebugMsg(debugmib.display.asciiOut,"Command: clear all card expired!"); + clearCardFlag = 0; + } + } + + SetDebugTariff(0,0,0); + + len = strlen(debugmib.display.asciiIn); + if(len ==0){ + if(ToBeListed){ + ListData(ToBeListed); + } + return 0; + } + pageno = debugmib.display.asciiIn[0]; + memcpy(cmd,&debugmib.display.asciiIn[1],len-1); + + DecodePPSAsciiIn(pageno-1,cmd); + memset(debugmib.display.asciiIn,0,len); + return 1; +} + +void ListParameter() +{ + char buf[4096]; + + PutLogFunID("ListParameter"); + + DebugMsg(debugmib.display.asciiOut,"PPS Parmeter list\n===================="); + DebugMsg(debugmib.display.asciiOut,"CDR Flag: %02x", + ppsParam.serviceControl.cdrFlag); + DebugMsg(debugmib.display.asciiOut,"Max Recharge Attempt: %d", + ppsParam.serviceControl.maxRechargeFailedNum); + BcdToAscii(buf, (BYTE *)debugmib.display.rechargeDigitals,16); + DebugMsg(debugmib.display.asciiOut,"Recharge Digits: %s",buf); + BcdToAscii(buf, (BYTE *)debugmib.display.inquiryDigitals,16); + +} + +void ListData() +{ + PutLogFunID("ListData"); + + if(ToBeListed==1){ + ListSubsSegNo(ToBeListedSegNo,0); + }else{ + ListCardsSegNo(ToBeListedSegNo,0); + } + ToBeListed=0; +} + +void ListSubInfo(char *msisdn) +{ + int len,head,tail,instance;//,i; + char buf[BUFSIZE]; + _prepaid_info *shmp=NULL; + //PoolParent *pParent; + //PoolChild *pChild; + + PutLogFunID("ListSubInfo"); + + len = strlen(msisdn); + if(len<=ACCOUNT_SERIES_LEN){ + DebugMsg(debugmib.display.asciiOut,"Error input of sub.: %s!",msisdn); + return; + } + instance = FindPPSSubsStoreIndex(atoll(msisdn)); + if(instance<0) + { + DebugMsg(debugmib.display.asciiOut,"can not find msisdn: %s!",msisdn); + return; + } + head = instance / UNIT_STORE_ACCOUNT; + tail = instance % UNIT_STORE_ACCOUNT; + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + DebugMsg(debugmib.display.asciiOut, + "<<----------- Sub. Info @ <%d> --------",instance); + DebugMsg(debugmib.display.asciiOut,"msisdn: %s",msisdn); + DebugMsg(debugmib.display.asciiOut,"PIN: %s",shmp->pin); + DebugMsg(debugmib.display.asciiOut,"status: %d",shmp->status); + DebugMsg(debugmib.display.asciiOut,"balance: %07.4f+%07.4f", + shmp->balance,shmp->promo_balance); + AsciiTime(buf,shmp->mo_expiration_date); + DebugMsg(debugmib.display.asciiOut,"mo expire date: %s",buf); + AsciiTime(buf,shmp->mt_expiration_date); + DebugMsg(debugmib.display.asciiOut,"mt expire date: %s",buf); + DebugMsg(debugmib.display.asciiOut,"cos id: %d, CUG ID: %d",shmp->cos_id, shmp->cug_id); + if(OCS_with_external_CRM()) + { + DebugMsg(debugmib.display.asciiOut,"CRM ID: %d.%d",shmp->crm_info.account_id, shmp->crm_info.base_plan_id); + DebugMsg(debugmib.display.asciiOut,"Rent: %d",shmp->crm_info.rent_charge); + } + + DebugMsg(debugmib.display.asciiOut,"free SMS status: %d",shmp->freeSMSActiveDays); + /* + DebugMsg(debugmib.display.asciiOut,"fav numbers: %d",shmp->favorite_numbers); + DebugMsg(debugmib.display.asciiOut,"fav counter: %d",shmp->fav_change_counter); + + for(i=0;i<5;i++) + { + len = shmp->favorite_number[i][MAX_MSISDN_BLEN-1]; + BcdToAscii(buf,shmp->favorite_number[i],16); + buf[len] = 0; + DebugMsg(debugmib.display.asciiOut,"fav number[%d]: %s",i,buf); + } + + if(shmp->poolAccount.role == MASTER_SLAVE_CHILD) + { + pChild = &shmp->poolAccount.roleParty.child; + DebugMsg(debugmib.display.asciiOut,"pool account role: child"); + + len = pChild->parentMsisdn[MAX_MSISDN_BLEN-1]; + BcdToAscii(buf,pChild->parentMsisdn,16); + buf[len] = 0; + DebugMsg(debugmib.display.asciiOut,"parent number: %s",buf); + DebugMsg(debugmib.display.asciiOut,"calls today: %d",pChild->callsToday); + DebugMsg(debugmib.display.asciiOut,"sms today: %d",pChild->smsToday); + DebugMsg(debugmib.display.asciiOut,"charged today: %f",pChild->chargedToday); + } + else if(shmp->poolAccount.role == MASTER_SLAVE_PARENT) + { + pParent = &shmp->poolAccount.roleParty.parent; + DebugMsg(debugmib.display.asciiOut,"pool account role: parent,has %d children",pParent->childNumber); + DebugMsg(debugmib.display.asciiOut,"change times: %d",pParent->changeTimes); + for(i=0;ichildMsisdn[i][MAX_MSISDN_BLEN-1]; + BcdToAscii(buf,pParent->childMsisdn[i],16); + buf[len] = 0; + DebugMsg(debugmib.display.asciiOut,"child number[%d]: %s",i,buf); + } + } + else + DebugMsg(debugmib.display.asciiOut,"pool account role: Normal account"); + */ + DebugMsg(debugmib.display.asciiOut,"Gprs volume: %lld",shmp->gprsVolume); + DebugMsg(debugmib.display.asciiOut,"Gprs balance: %0.4f",shmp->gprsBalance); + DebugMsg(debugmib.display.asciiOut,"Gprs volume ths month: %lld",shmp->gprsVolumeThisMonth); + DebugMsg(debugmib.display.asciiOut,"Gprs notification today: %d",shmp->gprsNotificationTimes); + DebugMsg(debugmib.display.asciiOut,"Call me back times: %d",shmp->callMeBackRequestTimes); + + + AsciiTimeYMD(buf,shmp->bundle_info.validity_date); + DebugMsg(debugmib.display.asciiOut,"Bundle Info >>>"); + DebugMsg(debugmib.display.asciiOut," data (KB) : %lld", (shmp->bundle_info.data + 1023) / 1024); + DebugMsg(debugmib.display.asciiOut," MO (S) : %d", shmp->bundle_info.mo_voice); + DebugMsg(debugmib.display.asciiOut," MT (S) : %d", shmp->bundle_info.mt_voice); + DebugMsg(debugmib.display.asciiOut," SMS : %d", shmp->bundle_info.sms); + DebugMsg(debugmib.display.asciiOut," Validity : %s", buf); + DebugMsg(debugmib.display.asciiOut," SMS Sent : %d", shmp->bundle_info.warning_sms_flag); + + DebugMsg(debugmib.display.asciiOut," "); + + DebugMsg(debugmib.display.asciiOut,"------------- The End ------------------->>"); +} + +void ListSubsSegNo(int segno,int flag) +{ + int i,len; + char buf[1024],tmpbuf[32]; + _prepaid_info *shmp=NULL; + + PutLogFunID("ListSubsSegNo"); + + if(segno>=MSISDN_HEAD_NUM){ + DebugMsg(debugmib.display.asciiOut,"Segno is too big ,should be (0-%d)",MSISDN_HEAD_NUM-1); + return; + } + if(flag){ + ToBeListed = 1; + ToBeListedSegNo = segno; + DebugMsg(debugmib.display.asciiOut,"MSISDN TYPE STATUS BALANCE COS_ID CUGID"); + } + for(i=0;iprepaid_data.prepaid_info[segno][i+(1-flag)*UNIT_STORE_ACCOUNT/2]; + len = shmp->msisdn[9]; + if(len==0 || len>18) continue; + BcdToAscii(buf,shmp->msisdn,len); + sprintf(tmpbuf," %02x ",shmp->rent_type); + strcat(buf,tmpbuf); + sprintf(tmpbuf,"%d ",shmp->status); + strcat(buf,tmpbuf); + sprintf(tmpbuf,"%f ",(shmp->balance)); + strcat(buf,tmpbuf); + sprintf(tmpbuf,"%d ",shmp->cos_id); + strcat(buf,tmpbuf); + sprintf(tmpbuf,"%d",shmp->cug_id); + strcat(buf,tmpbuf); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + } +} + +void ListCardsSegNo(unsigned int segno,int flag) +{ + int i,len; + char buf[1024],tmpbuf[32]; + _recharge_card_info *shmp=NULL; + + PutLogFunID("ListCardsSegNo"); + + if(segno>=MAX_CARD_SEGMENT){ + DebugMsg(debugmib.display.asciiOut,"Segno is too big ,should be (0-%d)",MAX_CARD_SEGMENT-1); + return; + } + if(flag){ + ToBeListed = 2; + ToBeListedSegNo = segno; + DebugMsg(debugmib.display.asciiOut,"CARD NO STATUS VALUE MSISDN"); + } + for(i=0;icard_data.prepaid_card[segno][i+(1-flag)*MAX_CARD_NUM_PSEG/2]; + len = shmp->card_no[MAX_CARD_LENGTH]; + if(len!=12 && len!=16) continue; + BcdToAscii(buf,shmp->card_no,len); + StringCat(buf," ",16); + sprintf(tmpbuf," %02x ",shmp->card_status); + strcat(buf,tmpbuf); + sprintf(tmpbuf,"%07ld ",shmp->face_value); + strcat(buf,tmpbuf); + sprintf(tmpbuf,"%s",shmp->msisdn_used); + strcat(buf,tmpbuf); + DebugMsg(debugmib.display.asciiOut,"%s",buf); + } +} + +void ListUsedCardHead(int segno) +{ + int i,j; + PutLogFunID("ListUsedCardHead"); + + if(segno>=MAX_CARD_SEGMENT) j=MAX_CARD_SEGMENT; + else j = segno; + + for(i=j*MAX_CARD_NUM_PSEG;i<(j+1)*MAX_CARD_NUM_PSEG;i++) + { + if(ramshm_ptr->card_data.segment_used_flag[i]) + { + DebugMsg(debugmib.display.asciiOut,"%04d: %lld", + i,ramshm_ptr->card_data.prepaid_card_head[i]); + } + } +} + +void ListUsedUserHead(int segno) +{ + int i,j; + + PutLogFunID("ListUsedUserHead"); + if(segno>=MSISDN_HEAD_NUM) j=MSISDN_HEAD_NUM; + else j = segno; + + for(i=j*UNIT_STORE_ACCOUNT;i<(j+1)*UNIT_STORE_ACCOUNT;i++) + { + if(ramshm_ptr->prepaid_data.msisdn_head[i]) + { + DebugMsg(debugmib.display.asciiOut,"%04d: %lld", + i,ramshm_ptr->prepaid_data.msisdn_head[i]); + } + } +} + +void cmdSetBalance(int balance) +{ + int i,j,len; + _prepaid_info *shmp=NULL; + + PutLogFunID("cmdSetBalance"); + for(j=0;jprepaid_data.prepaid_info[j][i]; + len = shmp->msisdn[9]; + if(len==0) continue; + shmp->balance = balance*1.0; + } +} + +void SumAccountBalance() +{ + int i,j,len; + double balance=0; + _prepaid_info *shmp=NULL; + + PutLogFunID("SumAccountBalance"); + for(j=0;jprepaid_data.prepaid_info[j][i]; + len = shmp->msisdn[9]; + if(len==0) continue; + balance = balance + shmp->balance + shmp->promo_balance; + } + DebugMsg(debugmib.display.asciiOut,"Total balance: %.0f", balance); +} + +int pps_set_all_balance(int balance) +{ + int i,j,len; + _prepaid_info *shmp=NULL; + + for(j=0;jprepaid_data.prepaid_info[j][i]; + len = shmp->msisdn[9]; + if(len==0) continue; + shmp->balance = balance; + } + + DebugMsg(debugmib.display.asciiOut,"Set balance to : %d", balance); + return 1; +} +/* ------------------------------------------*/ +void ClearAllSubs() +{ + memset(&ramshm_ptr->prepaid_data,0,sizeof(_prepaid_data)); + debugmib.measurement.usernumber = 0; + memset(debugmib.measurement.user_number,0,8); +} + +void ClearAllCard() +{ + memset(&ramshm_ptr->card_data,0,sizeof(_card_data)); + debugmib.measurement.cardnumber = 0; + debugmib.measurement.cardheadnumber = 0; + memset(debugmib.measurement.card_number,0,8); + memset(debugmib.measurement.card_prefix,0,2000*4); +} + +void SetDebugTariff(int tariff_id,int type,int operation_type) +{ + /* type: 0=current, 1=plan */ + /* operation type: 0=periodic check, 1=set parameter */ + static int debug_tariff_flag = 0; + static int debug_tariff_id=0, debug_tariff_type=0; + + if(operation_type) + { + debug_tariff_id = tariff_id; + debug_tariff_type = type; + debug_tariff_flag = 1; + } + else + { + if(debug_tariff_flag) + { + if(debug_tariff_type==0) + { + if(ListCurrentTariff(debug_tariff_id)) + debug_tariff_flag = 0; + } + else + { + //if(ListTariffPlan(debug_tariff_id)) + debug_tariff_flag = 0; + } + } + } +} + +extern _climax_quence climaxQuence; + +void CreatePrepaidCardAuto() +{ + int count = 0,len; + _recharge_card_info shmp; + static long cardNoStart = 50000000; + static long cardPwdStart = 50000000; + u_char cardNo[20]={0}; + u_char pwd[32]={0}; + + while(climaxQuence.counter < MAX_CARD_RECORD) + { + memset(&shmp,0,sizeof(_recharge_card_info)); + /* card no */ + sprintf((char *)cardNo,"%ld",cardNoStart++); + len = strlen((char *)cardNo); + AsciiToBcd(shmp.card_no, (char *)cardNo,len); + shmp.card_no[MAX_CARD_LENGTH] = len; + + /* PWD */ + sprintf((char *)pwd,"%ld",cardPwdStart++); + if(strlen((char *)pwd)!=16) + return; + EncryptCardHRN((char *)pwd,shmp.card_pwd); + + /* face value */ + shmp.face_value = 10; + /* card status */ + shmp.card_status = 1; + /* expiry_date */ + shmp.expiry_date = atol("20080702054842"); + /* valid_time */ + shmp.valid_time = atol("20080702054842");; + /* msisdn_used:NULL */ + + /* updated_date */ + shmp.updated_date = tvnow.tv_sec; + if(AddNewCardIntoClimaxQuence(&shmp)<0) + { + DebugMsg(debugmib.display.asciiOut,"Error: buffer is full,no space to store new card!\n"); + DebugMsg(debugmib.display.asciiOut,"Total new created :%ld\n",count); + return; + } + else + count++; + } + DebugMsg(debugmib.display.asciiOut,"Total new created :%ld\n",count); +} + +int jump =10; +void DeletePrepaidCardAuto() +{ + int count = 0,i,j; + + + for(i=0;ienglish,0,MAX_SMS_LEN); + strcpy((char *)smsSentenceItem->english,&cmd[14]); + smsSentenceItem->existFlag = TRUE; + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set delimiter=",14)) + { + SetSMSDelimiter(&cmd[14]); + PrintCmdOK(); + return 1; + } + if(!strcmp(cmd,"reload pps param")) + { + LoadPPSParam(); + PrintCmdOK(); + return 1; + } + if(!strcmp(cmd,"clear sms table")) + { + initSMSTable(); + PrintCmdOK(); + return 1; + } + if(!strcmp(cmd,"load tariff")) + { + SetLoadFileFlag(3); + PrintCmdOK(); + return 1; + } + if(!strcmp(cmd,"tariff take effect")) + { + load_tariff_main(); + PrintCmdOK(); + return 1; + } + + if(!strncasecmp(cmd,"idd prefix no",13)) + { + ppsParam.serviceControl.transfer_idd_prefix = 0; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"idd prefix yes",14)) + { + ppsParam.serviceControl.transfer_idd_prefix = 1; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + + if(!strcasecmp(cmd,"climax")) + { + printfClimaxQuenceIndex(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"get card=",9)) + { + searchCardInfoByPWD(&cmd[9]); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"replace card on",15)) + { + SetReplaceCardFlag(1); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"replace card off",16)) + { + SetReplaceCardFlag(0); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set replaceable on",18)) + { + SetReplaceSubsDataFlag(1); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set replaceable off",19)) + { + SetReplaceSubsDataFlag(0); + PrintCmdOK(); + return 1; + } + /* + if(!strncasecmp(cmd,"clear all subs",14)) + { + if(clearSubsFlag == 0x00) + { + DebugMsg(debugmib.display.asciiOut, "please input command again!"); + clearSubsFlag = 0x01; + waitClearSubsConfirmCounter = 0; + } + else if(clearSubsFlag == 0x01) + { + DebugMsg(debugmib.display.asciiOut,"clear subs. data and index..."); + ClearAllSubs(); + clearSubsFlag = 0x00; + } + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"clear all card",14)) + { + if(clearCardFlag == 0x00) + { + DebugMsg(debugmib.display.asciiOut, "please input command again!"); + clearCardFlag = 0x01; + waitClearCardConfirmCounter = 0; + } + else if(clearCardFlag == 0x01) + { + DebugMsg(debugmib.display.asciiOut,"clear all scratch data and index..."); + ClearAllCard(); + clearCardFlag = 0x00; + } + PrintCmdOK(); + return 1; + } */ + if(!strncasecmp(cmd,"set sync on",11)) + { + SetSyncFlag(1); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set sync off",12)) + { + SetSyncFlag(0); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set periodic sync on",20)) + { + SetPeriodicSyncFlag(1); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set periodic sync off",21)) + { + SetPeriodicSyncFlag(0); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set tcp sync on",15)) + { + SetTcpSyncFlag(1); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set tcp sync off",16)) + { + SetTcpSyncFlag(0); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"check card=",11)) + { + CheckCardPWD(&cmd[11]); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"get card index=",15)) + { + searchCardByIndex(atoi(&cmd[15])); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set smpp caller=",16)) + { + setPPSSmppNumber(&cmd[16], 0); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set smpp called=",16)) + { + setPPSSmppNumber(&cmd[16], 1); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"test smpp=",10)) + { + sendPPSTestShortMessage(&cmd[10]); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"test ocs",8)) + { + int nums=1; + int len= strlen(cmd); + + if(len>=10) + nums = atoi(&cmd[9]); + + start_pps_ocs_procedure(0, nums); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"test smsocs",11)) + { + start_pps_ocs_procedure(1, 1); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"test rest",9)) + { + int type = atoi(&cmd[10]); + + pps_rest_test_process(type); + + PrintCmdOK(); + return 1; + } + + if(!strncasecmp(cmd,"set max duration=",17)) + { + ppsParam.max_call_duration = atoi(&cmd[17]); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + + if(!strncasecmp(cmd,"card request",12)) + { + RechargeRequestProc(0); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"with crm yes",12)) + { + ppsParam.serviceControl.work_with_crm = 1; + + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"with crm no",11)) + { + ppsParam.serviceControl.work_with_crm = 0; + + SavePPSParam(); + PrintCmdOK(); + return 1; + } + + if(!strncasecmp(cmd,"change expiry day",17)) + { + ppsParam.serviceControl.not_change_expiry_date_when_transfer= 0; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"not change expiry day",21)) + { + ppsParam.serviceControl.not_change_expiry_date_when_transfer= 1; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"onct=yes",8)) + { + ppsParam.serviceControl.only_normal_can_transfer_balance = 1; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"onct=no",7)) + { + ppsParam.serviceControl.only_normal_can_transfer_balance= 0; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + + if(!strncasecmp(cmd,"import user data",16)) + { + SetLoadFileFlag(1); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"import tariff data",18)) + { + SetLoadFileFlag(3); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"max duration=",13)) + { + ppsParam.serviceControl.max_call_duration = atoi(&cmd[13]); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"ans timer=",10)) + { + ppsParam.serviceControl.answer_timer = atoi(&cmd[10]); + if(ppsParam.serviceControl.answer_timer<20) + ppsParam.serviceControl.answer_timer = 20; + + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"gy timer0=",10)) + { + pps_set_gy_delay_timer(0, atoi(&cmd[10])); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"gy timer1=",10)) + { + pps_set_gy_delay_timer(1, atoi(&cmd[10])); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"gy postpaid=",12)) + { + ppsParam.serviceControl.gy_postpaid_flag = atoi(&cmd[12]); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"st_llbn=",8)) + { + pps_set_all_balance(atoi(&cmd[8])); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set volume=",11)) + { + ppsParam.max_quota_per_request = atoi(&cmd[11]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"set post volume=",16)) + { + ppsParam.data_quota_as_postpaid = atoi(&cmd[16]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"adaptor=",8)) + { + ppsParam.scf_work_as_adaptor = atoi(&cmd[8]); + SavePPSParam(); +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ + if (ppsParam.scf_work_as_adaptor) + { + read_yx_ussd_param(); + } +#endif + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"vcs enable=",11)) + { + ppsParam.scf_work_as_adaptor_with_vcs = atoi(&cmd[11]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"no gy threshold=",16)) + { + ocs_set_threshold_supported(atoi(&cmd[16])); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"gy report data=",15)) + { + ocs_set_gy_report_data_method(atoi(&cmd[15])); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + + if(!strncasecmp(cmd,"smsc addr=",10)) + { + strcpy(ppsParam.serviceControl.smsc_addr, &cmd[10]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"sub sync test",13)) + { + + pps_sub_sync_test(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"bt res=", 7)) + { + ppsParam.serviceControl.balance_transfer_resolution = atoi(&cmd[7]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"nai flag=", 9)) + { + ppsParam.serviceControl.nai_for_diameter_proxy = atoi(&cmd[9]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"ctr state=", 10)) + { + debugmib.display.control_state = atoi(&cmd[10]); + if(debugmib.display.control_state) + debugmib.display.control_state_ts = tvnow.tv_sec; + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"srv_no_default",14)) + { + ConfigureDefaultSerivceNumber(); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"srv_no_cfg ivr",14)) + { + + ConfigureSerivceNumberPerCos(cmd, 0); + return 1; + } + if(!strncasecmp(cmd,"srv_no_cfg sms",14)) + { + + ConfigureSerivceNumberPerCos(cmd, 1); + return 1; + } + if(!strncasecmp(cmd,"srv_no_cfg ussd",15)) + { + + ConfigureSerivceNumberPerCos(cmd, 2); + return 1; + } + if(!strncasecmp(cmd,"srv_no_chk ivr",14)) + { + + memcpy(cvalue, &cmd[15], 2); + cvalue[2] = 0; + ivalue = atoi(cvalue); + + PrintCosServiceNumber(ivalue, 0); + + return 1; + } + if(!strncasecmp(cmd,"srv_no_chk sms",14)) + { + + memcpy(cvalue, &cmd[15], 2); + cvalue[2] = 0; + ivalue = atoi(cvalue); + + PrintCosServiceNumber(ivalue, 1); + return 1; + } + if(!strncasecmp(cmd,"srv_no_chk ussd",15)) + { + + memcpy(cvalue, &cmd[16], 2); + cvalue[2] = 0; + ivalue = atoi(cvalue); + + PrintCosServiceNumber(ivalue, 2); + return 1; + } + if(!strncasecmp(cmd,"srv_no_test",11)) + { + + u8 cos_id=0,srv_id=0,call_id=0; + + memcpy(cvalue, &cmd[12], 2); + cvalue[2] = 0; + cos_id = atoi(cvalue); + + memcpy(cvalue, &cmd[15], 2); + cvalue[2] = 0; + srv_id = atoi(cvalue); + + memcpy(cvalue, &cmd[18], 1); + cvalue[1] = 0; + call_id = atoi(cvalue); + + ivalue = GetSerivceNumberFlagPerCos(cos_id, srv_id, call_id); + DebugMsg(debugmib.display.asciiOut,"result=%d", ivalue); + return 1; + } + if(!strcmp(cmd,"enable smpp over tcp")) + { + ppsParam.serviceControl.smpp_over_tcp_flag = 1; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strcmp(cmd,"disable smpp over tcp")) + { + ppsParam.serviceControl.smpp_over_tcp_flag = 0; + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strcmp(cmd,"check smpp link mode?")) + { + if(ppsParam.serviceControl.smpp_over_tcp_flag) + DebugMsg(debugmib.display.asciiOut,"SMPP over TCP link"); + else + DebugMsg(debugmib.display.asciiOut,"SMPP over UDP link"); + return 1; + } + if(!strncasecmp(cmd,"cc method=", 10)) + { + ppsParam.serviceControl.calling_card_method = atoi(&cmd[10]); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strcmp(cmd,"check cc method?")) + { + if(ppsParam.serviceControl.calling_card_method == 0) + DebugMsg(debugmib.display.asciiOut,"calling card with PPS account"); + else + DebugMsg(debugmib.display.asciiOut,"calling card with rechage card"); + return 1; + } + + if(!strncasecmp(cmd,"cc cos id=", 10)) + { + ppsParam.serviceControl.calling_card_cos_id = atoi(&cmd[10]); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"test crm tariff=", 16)) + { + u_char call_type = 1;/*1=mo call, 2=mo sms, 3=data*/ + if(cmd[16] == 'c') + call_type = 1; + else if(cmd[16] == 's') + call_type = 2; + else if(cmd[16] == 'd') + call_type = 3; + + query_tariff_test(call_type); + PrintCmdOK(); + return 1; + } + if(strstr(cmd,"reload prefix definition")) + { + ocs_get_crm_prefix_definition(); + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"free seconds=", 13)) + { + ppsParam.serviceControl.crm_free_seconds = atoi(&cmd[13]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"status vd=", 10)) + { + ppsParam.serviceControl.crm_status_validity = atoi(&cmd[10]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"days before vd=", 15)) + { + ppsParam.serviceControl.crm_days_before_validity = atoi(&cmd[15]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"sms for event=", 14)) + { + ppsParam.serviceControl.crm_notification_for_event = atoi(&cmd[14]); + SavePPSParam(); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"crm tariff=", 11)) + { + char prefix[128], areaName[32]=""; + int call_type; + ocs_get_charge_prefix(&cmd[11], prefix, areaName, &call_type); + + PrintCmdOK(); + return 1; + } + if(!strncasecmp(cmd,"cellid in ccr=", 14)) + { + ppsParam.serviceControl.cellid_present_in_ccr = atoi(&cmd[14]); + SavePPSParam(); + PrintCmdOK(); + return 1; + } + + DebugMsg(debugmib.display.asciiOut,"ERROR COMMAND!"); + break; + case 1: /* parameter */ + break; + case 3: + if(strcasecmp(cmd,"C")==0 || strcasecmp(cmd,"CLR")==0 || strcasecmp(cmd,"CLEAR")==0) + { + memset(debugmib.msgstatistics.send_sync,0,sizeof(int)*4); + memset(debugmib.msgstatistics.recv_sync,0,sizeof(int)*4); + } + break; + case 128: /* NOT USED */ + if(strcasecmp(cmd,"C")==0) + { + debugmib.measurement.cdroverflow = 0; + debugmib.measurement.blacklist = 0; + } + break; + case 5: /* msg counter */ + if(strcasecmp(cmd,"C")==0 || strcasecmp(cmd,"CLR")==0 || strcasecmp(cmd,"CLEAR")==0) + { + debugmib.msgstatistics.CapOpen = 0; + debugmib.msgstatistics.Initialdp[0] = 0; + debugmib.msgstatistics.Initialdp[1] = 0; + debugmib.msgstatistics.RequestBCSM[0] =0; + debugmib.msgstatistics.RequestBCSM[1] =0; + debugmib.msgstatistics.ApplyCharging[0] = 0; + debugmib.msgstatistics.ApplyCharging[1] = 0; + //debugmib.msgstatistics.Continue[0] = 0; + //debugmib.msgstatistics.Continue[1] = 0; + debugmib.msgstatistics.ActivityS = 0; + debugmib.msgstatistics.ActivityR = 0; + debugmib.msgstatistics.ChargingReport[0] = 0; + debugmib.msgstatistics.ChargingReport[1] = 0; + debugmib.msgstatistics.ReportBCSM[0] = 0; + debugmib.msgstatistics.ReportBCSM[1] = 0; + debugmib.msgstatistics.Answered[0] = 0; + debugmib.msgstatistics.Answered[1] = 0; + debugmib.msgstatistics.Disconnect[0] = 0; + debugmib.msgstatistics.Disconnect[1] = 0; + debugmib.msgstatistics.Releasecall[0] = 0; + debugmib.msgstatistics.Releasecall[1] = 0; + debugmib.msgstatistics.Inquire = 0; + debugmib.msgstatistics.Recharge = 0; + debugmib.msgstatistics.ReadCard = 0; + debugmib.msgstatistics.ReadCardRsp = 0; + debugmib.msgstatistics.WriteCard = 0; + debugmib.msgstatistics.WriteCardRsp = 0; + debugmib.msgstatistics.Playannounce = 0; + debugmib.msgstatistics.Accountinfo = 0; + debugmib.msgstatistics.Accinfoack = 0; + } + break; + case 6: + if(strcasecmp(cmd,"C")==0 || strcasecmp(cmd,"CLR")==0 || strcasecmp(cmd,"CLEAR")==0) + { + debugmib.msgstatistics.InitialDP_SMS = 0; + debugmib.msgstatistics.Request_SMS = 0; + debugmib.msgstatistics.Continue_SMS = 0; + debugmib.msgstatistics.Report_SMS = 0; + debugmib.msgstatistics.Release_SMS = 0; + debugmib.msgstatistics.Conference = 0; + debugmib.msgstatistics.ThirdParty = 0; + debugmib.msgstatistics.ConnectToResource = 0; + debugmib.msgstatistics.PlayAnnouncement = 0; + debugmib.msgstatistics.EstablishTemporaryConnection = 0; + debugmib.msgstatistics.AssistInstructions = 0; + debugmib.msgstatistics.PCUI = 0; + debugmib.msgstatistics.PCUI_rsp = 0; + debugmib.msgstatistics.SpecialResourceReport = 0; + debugmib.msgstatistics.DisconnectForwardConnection = 0; + debugmib.msgstatistics.smInquiry=0; + debugmib.msgstatistics.smRecharge=0; + } + break; + case 7: /* cdr&csta counter */ + if(strcasecmp(cmd,"C")==0) + { + debugmib.msgstatistics.update_card_request = 0; + debugmib.msgstatistics.update_card_error_msg = 0; + debugmib.msgstatistics.update_card_ok = 0; + debugmib.msgstatistics.update_card_no_card = 0; + debugmib.msgstatistics.update_card_used = 0; + debugmib.msgstatistics.update_card_expired = 0; + debugmib.msgstatistics.update_card_sys_failure = 0; + } + break; + default: + break; + } + + return 1; +} + +int +GetParamRechargeAttemptLimit() +{ + return ppsParam.serviceControl.maxRechargeFailedNum; +} + +int +UserNumberIncrement() +{ + char buf[32]=""; + debugmib.measurement.usernumber ++; + ramshm_ptr->index_data.free_index.user_counter++; + + sprintf(buf,"%08ld",debugmib.measurement.usernumber); + AsciiToBcd(&debugmib.measurement.user_number[0],buf,8); + return 1; +} + +int +UserNumberDecrement() +{ + char buf[32]=""; + debugmib.measurement.usernumber --; + ramshm_ptr->index_data.free_index.user_counter --; + if(debugmib.measurement.usernumber<0) + debugmib.measurement.usernumber =0; + if(ramshm_ptr->index_data.free_index.user_counter<0) + ramshm_ptr->index_data.free_index.user_counter = 0; + sprintf(buf,"%08ld",debugmib.measurement.usernumber); + AsciiToBcd(&debugmib.measurement.user_number[0],buf,8); + return 1; +} + + +int SetDatabase(BYTE oidLen, DWORD *oid, BYTE *pdata, u_short dataLen) +{ + int dbid; + + + PutLogFunID("SetDatabase"); + + dbid = oid[12]; + switch(dbid) + { + case 1: /* subs index */ + return GetRamData(oidLen,oid,pdata,dataLen); + break; + case 2: /* subs data */ + return SetUserDataByOMC(oidLen,oid,pdata,dataLen); + break; + case 3: /* recharge card index */ + return GetRamData(oidLen,oid,pdata,dataLen); + break; + case 4: /* recharge card data */ + return SetPrepaidCardByOMC(oidLen,oid,pdata,dataLen); + break; + case 5: /* third party recharge */ + //return thirdPartyChargeReqeust(oidLen,oid,pdata,dataLen); + break; + case 6: + break; + case 7: /* daily report */ + break; + case 8: + break; + case 9: /* conference */ + return ConferenceRequest(oidLen,oid,pdata,dataLen); + break; + } + + return dataLen; +} + +int GetDatabase(BYTE oidLen, DWORD *oid, BYTE *pdata, BYTE *vartype) +{ + PutLogFunID("GetDatabase"); + + *vartype = 0x04; + if (oidLen<14) + { + return -1; + } + switch(oid[12]) + { + case 6: + return GetUsedPrepaidCard(oidLen,oid,pdata,vartype); + break; + case 7: + return GetDailyReport(oidLen,oid,pdata,vartype); + break; + } + return -1; +} + +/* ---------------------------------*/ +int SetReplaceSubsDataFlag(int flag) +{ + if(flag<0) return 0; + replaceableFlag = flag; + return 1; +} + +/* ---------------------------------*/ +int ImportUserData(char *userdata) +{ + _prepaid_info *shmp=NULL, + *shmp_old=NULL, + prepaid_info; + char buf[BUFSIZE]={""},*token,msisdn[32]; +// char chead[64]={""},ctail[64]={""},bufhead[32]=""; + int head,tail=0,retval=0,index=0; + int len, i; + int chargeFlag=0,difbalance=0,dif_promo_balance=0; + int favorite_numbers = 0; + const char delimiter[]=",;"; + time_t nowtime=0; + + PutLogFunID("ImportUserData"); + + shmp = &prepaid_info; + memset(&prepaid_info,0,sizeof(_prepaid_info)); + + token = buf; + + if(strlen(userdata)<10) + { + if(load_file.log_fp[_FILE_ID_USER_DATA] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: Wrong record len=%zu : %s\n", + strlen(userdata), userdata); + } + return 0; + } + + int up_balance_only_flag = 0, first_id_not_nul = 0, invalid_record_flag = 0; + while(index 0) + { + if (first_id_not_nul == 0) + { + if (strlen(token) > 0){ + first_id_not_nul = index; + if ((index == 0x03) && replaceableFlag)// first index is balance + { + up_balance_only_flag = 1;// set update balance only + } + } + } + } + strcpy(buf,token); + + switch(index) + { + case 0x00: //msisdn + len = strlen(buf); + if(len>MAX_MSISDN_ALEN || len=%d digits\n", + MAX_MSISDN_ALEN,MIN_MSISDN_ALEN); + } + return 0; + } + for(i=0;i'9' || buf[i]<'0' || buf[0] =='0') + { + if(load_file.log_fp[_FILE_ID_USER_DATA] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: Wrong msisdn format:%s\n",buf); + } + return 0; + } + } + strcpy(msisdn,buf); + + msisdn[len] = 0; + + StringCat(buf,"F",MAX_MSISDN_ALEN); + AsciiToBcd(shmp->msisdn,buf,MAX_MSISDN_ALEN); + if(len %2 ==0) + shmp->msisdn[len/2] = 0xFF; + else + shmp->msisdn[len/2] |= 0x0F; + shmp->msisdn[MAX_MSISDN_BLEN-1] = len; + break; + case 0x01: + memcpy(shmp->pin,buf,6); + break; + case 0x02: //status + shmp->status = atoi(buf); + break; + case 0x03: //balance + shmp->balance = atoi(buf); + if(shmp->balance>ppsParam.serviceControl.maxBalance) + { + if(load_file.log_fp[_FILE_ID_USER_DATA] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: Balance=%.0f is too big : should be 0-%d\n", + shmp->balance,ppsParam.serviceControl.maxBalance); + } + return 0; + } + break; + case 0x04: + shmp->promo_balance = atoi(buf); + if(shmp->promo_balance>ppsParam.serviceControl.maxBalance) + { + if(load_file.log_fp[_FILE_ID_USER_DATA] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: Balance=%.0f is too big : should be 0-%d\n", + shmp->promo_balance,ppsParam.serviceControl.maxBalance); + } + return 0; + } + break; + case 0x05: //overdraft + shmp->overdraft = atoi(buf); + break; + case 0x06: //first used date + string2ltime(&nowtime,buf); + shmp->first_used_date = nowtime; + break; + case 0x07: //mo expiration date + string2ltime(&nowtime,buf); + shmp->mo_expiration_date = nowtime; + break; + case 0x08: //mt expiration date + string2ltime(&nowtime,buf); + shmp->mt_expiration_date = nowtime; + break; + case 0x09: + string2ltime(&nowtime,buf); + shmp->promo_date = nowtime; + break; + case 0x0a: + shmp->cos_id = atoi(buf)%MaxCosTableItem; + if(ppsParam.serviceControl.cos_group_flag) + shmp->cos_id = atoi(buf)%MAX_ZONE_NUM_NEW; + break; + case 0x0b: + shmp->rent_type = atoi(buf); + break; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: /* should from 1- MAX_TAIRFF_LOCATION */ + shmp->home_location[index-12] = atoi(buf); + break; + case 0x10: //cug id + shmp->cug_id = atoi(buf)%(MAX_CUG_ID+1); + break; + case 0x11: + shmp->language_type = atoi(buf); + break; + case 0x12: //free sm counter + shmp->recharge_fail = atoi(buf); + break; + case 0x13: + shmp->free_sm_counter = atoi(buf); + break; + case 0x14: //latch flag + shmp->latch_flag = 0; + break; + case 0x15: //favorite number flag + shmp->favorite_numbers = 0; + break; + case 0x16: //fav change counter + shmp->fav_change_counter = 0; + break; + case 0x17: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + len = strlen(buf); + if(len>MAX_MSISDN_ALEN || lenfavorite_number[index-23][MAX_MSISDN_BLEN-1] = len; + AsciiToBcd(shmp->favorite_number[index-23],buf,MAX_MSISDN_ALEN); + favorite_numbers++; + if(favorite_numbers>MAX_FAVORITE_NUMBERS) + favorite_numbers = MAX_FAVORITE_NUMBERS; + break; + case 61: + shmp->bundle_info.data = atoll(buf); + break; + case 62: + shmp->bundle_info.mo_voice = atoi(buf); + break; + case 63: + shmp->bundle_info.mt_voice = atoi(buf); + break; + case 64: + shmp->bundle_info.sms = atoi(buf); + break; + case 65: + string2ltime(&nowtime,buf); + shmp->bundle_info.validity_date= nowtime; + break; + case 66: + shmp->bundle_info.warning_sms_flag= atoi(buf); + break; + default: + break; + }/* switch */ + index++; + }//while + + if (invalid_record_flag && !up_balance_only_flag) + { + if(load_file.log_fp[_FILE_ID_USER_DATA] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: Wrong record : %s,index=%d\n",userdata,index); + } + return 0; + } + + shmp->favorite_numbers = favorite_numbers; + + retval = FindPPSSubsStoreIndex(atoll(msisdn)); + + if(retval>=0) + { + if(load_file.log_fp[_FILE_ID_USER_DATA] != NULL) + { + if(replaceableFlag == 0) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: account %s is in use, cann't be replaced!\n",msisdn); + } + else + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: account %s is in use, replace it!\n",msisdn); + } + } + if(replaceableFlag == 0) + return 0; + head = retval / UNIT_STORE_ACCOUNT; + tail = retval % UNIT_STORE_ACCOUNT; + shmp_old = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + + if (up_balance_only_flag) + { + if(shmp->balance != shmp_old->balance && masterFlag) + { + chargeFlag |= 0x01; + difbalance = shmp->balance-shmp_old->balance; + + double new_balance = shmp->balance; + memcpy(shmp, shmp_old, sizeof(_prepaid_info)); + shmp->balance = new_balance; + ModifyPPSSubsData(shmp); + } + } + else + { + if(shmp->balance != shmp_old->balance && masterFlag) + { + chargeFlag |= 0x01; + difbalance = shmp->balance-shmp_old->balance; + } + if(shmp->promo_balance != shmp_old->promo_balance && masterFlag) + { + chargeFlag |= 0x02; + dif_promo_balance = shmp->promo_balance - shmp_old->promo_balance; + } + + ModifyPPSSubsData(shmp); + } + } + else + { + if (up_balance_only_flag) + { + if(load_file.log_fp[_FILE_ID_USER_DATA] !=NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: can't create user from balance only record!\n"); + } + return 0; + } + if(debugmib.measurement.usernumber>=ppsParam.serviceControl.licenseduser) + { + if(load_file.log_fp[_FILE_ID_USER_DATA] !=NULL) + { + fprintf(load_file.log_fp[_FILE_ID_USER_DATA], + "Error: exist users exceed lincensed user(%u)!\n", + ppsParam.serviceControl.licenseduser); + } + return 0; + } + + retval = AddPPSSubsData(shmp); + head = retval / UNIT_STORE_ACCOUNT; + tail = retval % UNIT_STORE_ACCOUNT; + + if(shmp->balance !=0) + { + chargeFlag |= 0x01; + difbalance = shmp->balance; + } + if(shmp->promo_balance !=0) + { + chargeFlag |= 0x02; + dif_promo_balance = shmp->promo_balance; + } + } + + if(masterFlag && (chargeFlag & 0x01)) + { + SendOperatorRechargeCDR( + head, + tail, + difbalance); + } + if(masterFlag && (chargeFlag & 0x02)) + { + SendOperatorRechargeCDR( + head, + tail, + dif_promo_balance); + } + + debugmib.display.sysState = _SYS_STATE_NORMAL; + return 1; +} + + +/* ----------------+ Upload data procedure +---------------*/ +/* ----------------+ Upload data procedure +---------------*/ + +int delblankspace(char *astr, char *bstr) +{ + int i,j=0,len ; + + PutLogFunID("delblankspace"); + + len = strlen(bstr); + for(i=0;itariff_data; + + char buf[BUFSIZE],*off,s[BUFSIZE],description[32]; + int start=0,index=0,slen=0,len; + int id=0,ptariff=0,tariff_id, + date=0; + float amount=0; + + PutLogFunID("RentTariffSet"); + + if(strlen(record)<2) return 0; + strcpy(s,record); + while(index<6) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + tariff_id = atoi(buf); + break; + case 0x01: /* id */ + id = atoi(buf); + break; + case 0x02: /* description */ + len = strlen(buf); + if(len<=16) + { + strcpy(description,buf); + }else + { + memcpy(description,buf,16); + description[16] = 0; + } + + break; + case 0x03: /* type */ + ptariff = atoi(buf); + break; + case 0x04: /* rent day */ + date = atoi(buf); + break; + case 0x05:/* amount */ + amount = atof(buf); + break; + default: + break; + }/* switch */ + index++; + } + + if(tariff_id>=MAX_ZONE_NUM) return 0; + if(id>MAX_RENT_TARIFF || id<1) return 0; + shmp->rent_tariff[tariff_id][id-1].id = id; + strcpy(shmp->rent_tariff[tariff_id][id-1].description,description); + shmp->rent_tariff[tariff_id][id-1].rent_type = ptariff; + shmp->rent_tariff[tariff_id][id-1].charge_date = date; + shmp->rent_tariff[tariff_id][id-1].rent_amount = amount; + return 1; +} + +int ImportRentTariffData(FILE *fp) +{ + char record[512]; + + while(fgets(record,512,fp) != (char *)0) + { +// fprintf(stderr,"record:%s\n",record); + RentTariffSet(record); + } + + return 1; +} + + +void pps_print_error(u_char logMsisdnFlag,const char *fmt, ...) +{ + va_list ap; + char buf[2048]; + + if(logMsisdnFlag == 0) + { + if(!(logMsgFlag & 0x01) || (logMsgFlag == 0x08)) + return; + } + else if(!(logMsgFlag & 0x08)) + return; + + sprintf(buf, "\33[31m"); + va_start(ap, fmt); + + vsprintf(buf+strlen(buf), fmt, ap); + + strcat(buf, "\33[0m\n\r"); + + if((strlen(debugmib.display.asciiOut) + strlen(buf)) < PPS_ASCII_OUT_LEN) + strcat(debugmib.display.asciiOut, buf); + else + strcpy(debugmib.display.asciiOut, buf); + + va_end(ap); + +} + + +void pps_print_event(u_char logMsisdnFlag,const char *fmt, ...) +{ + va_list ap; + char buf[2048]; + + if(logMsisdnFlag == 0) + { + if((logMsgFlag == 0x01) || (logMsgFlag == 0) || (logMsgFlag == 0x08)) + return; + } + else if(!(logMsgFlag & 0x08)) + return; + + sprintf(buf, "\33[37m"); + va_start(ap, fmt); + + vsprintf(buf+strlen(buf), fmt, ap); + + strcat(buf, "\33[0m\n\r"); + if((strlen(debugmib.display.asciiOut) + strlen(buf)) < PPS_ASCII_OUT_LEN) + strcat(debugmib.display.asciiOut, buf); + else + strcpy(debugmib.display.asciiOut, buf); + + va_end(ap); + + +} + +int BasicTariffSet(char *record) +{ + _tariff_data *shmp=&ramshm_ptr->tariff_data; + char buf[BUFSIZE],*off,s[BUFSIZE],bill_id[128]; + int start=0,index=0,slen=0,len; + int tariffID=0,u_time=0,m_unit=0,rindex=0; + int call_type,free_time,discountID,cap_flag=0; + float b_fee_a=0,long_fee_a=0, b_fee_b=0,long_fee_b=0, b_fee_c=0,long_fee_c=0,adjustment=0; + char area[128]; + u32 tierLevel=0,units_a = 0,units_b = 0,units_c = 0; + TIER_RATING *pTierRating; + + PutLogFunID("BasicTariffSet"); + + if(strlen(record)<10) return 0; + strcpy(s,record); + while(index <= 0x13) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + + if(slen>=strlen(record)) slen = strlen(record)-start; + + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + + strcpy(s,&record[start]); + switch(index) + { + case 0x00: /* bill */ + delblankspace(bill_id,buf); + break; + case 0x01: /* area */ + len = strlen(buf); + if(len<=TARIFF_AREA_LEN-1) + strcpy(area,buf); + else{ + memcpy(area,buf,TARIFF_AREA_LEN-1); + area[TARIFF_AREA_LEN-1] = 0; + } + break; + case 0x02: /* tariffID */ + tariffID = atoi(buf)%MAX_ZONE_NUM; + break; + case 0x03: + call_type = atoi(buf) % MAX_MO_CALLTYPE; + break; + case 0x04: + discountID = atoi(buf)%MAX_DISCOUNT_ID; + break; + case 0x05: + free_time = atoi(buf); + break; + case 0x06: /* unit_time */ + u_time = atoi(buf); + break; + case 0x07: /* mini_time */ + m_unit = atoi(buf); + break; + case 0x08: /* adjustment */ + adjustment = atof(buf); + break; + case 0x09: + cap_flag = atoi(buf); + break; + case 0x0a: /* tier level */ + tierLevel = atoi(buf); + break; + case 0x0b: /* uints a */ + units_a = atol(buf); + break; + case 0x0c: /* base_fee a */ + b_fee_a = atof(buf); + break; + case 0x0d: /* long distance fee a*/ + long_fee_a = atof(buf); + break; + case 0x0e: /* uints b */ + units_b = atol(buf); + break; + case 0x0f: /* base_fee b */ + b_fee_b = atof(buf); + break; + case 0x10: /* long distance fee b*/ + long_fee_b = atof(buf); + break; + case 0x11: /* uints c */ + units_c = atol(buf); + break; + case 0x12: /* base_fee c */ + b_fee_c = atof(buf); + break; + case 0x13: /* long distance fee c*/ + long_fee_c = atof(buf); + break; + default: + break; + }/* switch */ + index++; + } + + if(ppsParam.serviceControl.cos_group_flag) + { + rindex = zonenum[tariffID] ++; + tariffID = (tariffID * COS_GROUP_NUM ); + tariffID += rindex/BILLING_BASE_NUM; + rindex = rindex%BILLING_BASE_NUM; + tariffID = tariffID%MAX_ZONE_NUM; + } + else + rindex = (zonenum[tariffID] ++)%BILLING_BASE_NUM; + strcpy(shmp->bill_tariff[tariffID][rindex].bill_id,bill_id); + shmp->bill_tariff[tariffID][rindex].tariffID = tariffID; + shmp->bill_tariff[tariffID][rindex].call_type = call_type; + shmp->bill_tariff[tariffID][rindex].discountID = discountID; + strcpy(shmp->bill_tariff[tariffID][rindex].area,area); + shmp->bill_tariff[tariffID][rindex].free_time = free_time; + shmp->bill_tariff[tariffID][rindex].unit_time = u_time; + shmp->bill_tariff[tariffID][rindex].mini_unit = m_unit; + shmp->bill_tariff[tariffID][rindex].adjustment = adjustment; + shmp->bill_tariff[tariffID][rindex].cap_flag = cap_flag; + + pTierRating = &shmp->bill_tariff[tariffID][rindex].tierRating; + pTierRating->tierNumber = tierLevel; + pTierRating->rating[0].units = units_a; + pTierRating->rating[0].base_fee = b_fee_a; + pTierRating->rating[0].long_distance_fee = long_fee_a; + pTierRating->rating[1].units = units_b; + pTierRating->rating[1].base_fee = b_fee_b; + pTierRating->rating[1].long_distance_fee = long_fee_b; + pTierRating->rating[2].units = units_c; + pTierRating->rating[2].base_fee = b_fee_c; + pTierRating->rating[2].long_distance_fee = long_fee_c; + return 1; +} + +int ImportBasicTariffData(FILE *fp) +{ + char record[512]; + + memset(zonenum,0,sizeof(zonenum)); + while(fgets(record,512,fp) != (char *)0) + { + BasicTariffSet(record); + } + + return 1; +} + + +int gprsTariffSet(char *record) +{ + char buf[BUFSIZE],*off,s[BUFSIZE]; + int start=0,index=0,slen=0; + int id=0,tariffid=0; + _gprs_tariff gprsTariff; + + PutLogFunID("BillGPRSSet"); + + if(strlen(record)<2) return 0; + strcpy(s,record); + while(index <= 0x08) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + tariffid = atoi(buf); + if(tariffid>=MAX_ZONE_NUM || tariffid<0) + return 0; + gprsTariff.tariffID = tariffid; + break; + case 0x01: + id = atoi(buf); + if(id>MAX_GPRS_PREFIX || id<1) + return 0; + gprsTariff.gprsID = id; + break; + case 0x02: + gprsTariff.destIp = inet_addr(buf); + break; + case 0x03: + gprsTariff.chargeUnit = atoi(buf); + break; + case 0x04: + gprsTariff.basicFee = atof(buf); + break; + case 0x05: + gprsTariff.miniChargeUnit = atoi(buf); + break; + case 0x06: + gprsTariff.initialAdjustment = atof(buf); + break; + case 0x07: + gprsTariff.cap_flag = atoi(buf)%MaxcapPlanTableItem; + break; + case 0x08: + gprsTariff.discountID = atoi(buf)%MAX_DISCOUNT_ID; + break; + default: + break; + }/* switch */ + index++; + } + memcpy(&ramshm_ptr->tariff_data.gprs_tariff[tariffid][id-1],&gprsTariff,sizeof(_gprs_tariff)); + return 1; +} + +int ImportGprsTariff(FILE *fp) +{ + char record[512]; + + memset(zonenum,0,sizeof(zonenum)); + while(fgets(record,512,fp) != (char *)0) + { + gprsTariffSet(record); + } + + return 1; +} + +int MTTariffSet(char *record) +{ + _tariff_data *shmp=&ramshm_ptr->tariff_data; + char buf[BUFSIZE],*off,s[BUFSIZE],bill_id[128]; + int start=0,index=0,slen=0,len; + int call_type,tariffID=0,u_time=0,m_unit=0,rindex=0,discountID,free_time; + float b_fee_a=0,long_fee_a=0, b_fee_b=0,long_fee_b=0, b_fee_c=0,long_fee_c=0,adjustment=0,cap_flag=0; + char area[128]; + u32 tierLevel=0,units_a = 0,units_b = 0,units_c = 0; + TIER_RATING *pTierRating; + + PutLogFunID("MTTariffSet"); + + if(strlen(record)<10) return 0; + strcpy(s,record); + while(index <= 0x13) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + + if(slen>=strlen(record)) slen = strlen(record)-start; + + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + + strcpy(s,&record[start]); + switch(index) + { + case 0x00: /* bill */ + delblankspace(bill_id,buf); + break; + case 0x01: /* area */ + len = strlen(buf); + if(len<=TARIFF_AREA_LEN-1) + strcpy(area,buf); + else{ + memcpy(area,buf,TARIFF_AREA_LEN-1); + area[TARIFF_AREA_LEN-1] = 0; + } + break; + case 0x02: /* tariffID */ + tariffID = atoi(buf)%MAX_ZONE_NUM; + break; + case 0x03: + call_type = atoi(buf); + break; + case 0x04: + discountID = atoi(buf)%MAX_DISCOUNT_ID; + break; + case 0x05: + free_time = atoi(buf); + break; + case 0x06: /* unit_time */ + u_time = atoi(buf); + break; + case 0x07: /* mini_time */ + m_unit = atoi(buf); + break; + case 0x08: /* adjustment */ + adjustment = atof(buf); + break; + + case 0x09: /* tier level */ + tierLevel = atoi(buf); + break; + case 0x0a: /* uints a */ + units_a = atol(buf); + break; + case 0x0b: /* base_fee a */ + b_fee_a = atof(buf); + break; + case 0x0c: /* long distance fee a*/ + long_fee_a = atof(buf); + break; + case 0x0d: /* uints b */ + units_b = atol(buf); + break; + case 0x0e: /* base_fee b */ + b_fee_b = atof(buf); + break; + case 0x0f: /* long distance fee b*/ + long_fee_b = atof(buf); + break; + case 0x10: /* uints c */ + units_c = atol(buf); + break; + case 0x11: /* base_fee c */ + b_fee_c = atof(buf); + break; + case 0x12: /* long distance fee c*/ + long_fee_c = atof(buf); + break; + case 0x13: /* cap flag */ + cap_flag = atoi(buf); + break; + default: + break; + }/* switch */ + index++; + } + + rindex = (zonenum[tariffID] ++)%CALLED_BASE_NUM; + strcpy(shmp->called_tariff[tariffID][rindex].bill_id,bill_id); + shmp->called_tariff[tariffID][rindex].tariffID = tariffID; + shmp->called_tariff[tariffID][rindex].call_type = call_type; + shmp->called_tariff[tariffID][rindex].discountID = discountID; + strcpy(shmp->called_tariff[tariffID][rindex].area,area); + shmp->called_tariff[tariffID][rindex].free_time = free_time; + shmp->called_tariff[tariffID][rindex].unit_time = u_time; + shmp->called_tariff[tariffID][rindex].mini_unit = m_unit; + shmp->called_tariff[tariffID][rindex].adjustment = adjustment; + shmp->called_tariff[tariffID][rindex].cap_flag = cap_flag; + + pTierRating = &shmp->called_tariff[tariffID][rindex].tierRating; + pTierRating->tierNumber = tierLevel; + pTierRating->rating[0].units = units_a; + pTierRating->rating[0].base_fee = b_fee_a; + pTierRating->rating[0].long_distance_fee = long_fee_a; + pTierRating->rating[1].units = units_b; + pTierRating->rating[1].base_fee = b_fee_b; + pTierRating->rating[1].long_distance_fee = long_fee_b; + pTierRating->rating[2].units = units_c; + pTierRating->rating[2].base_fee = b_fee_c; + pTierRating->rating[2].long_distance_fee = long_fee_c; + return 1; +} + +int ImportMTTariff(FILE *fp) +{ + char record[512]; + + memset(zonenum,0,sizeof(zonenum)); + while(fgets(record,512,fp) != (char *)0) + { + MTTariffSet(record); + } + + return 1; +} +/* ------- bill tariff ----*/ +int BillDiscountSet(char *record) +{ + _tariff_data *shmp=&ramshm_ptr->tariff_data; + + char buf[BUFSIZE],*off,s[BUFSIZE]; + int start=0,index=0,slen=0; + int did=0,hour=0,sun=0,mon=0,tue=0,wed=0,thu=0,fri=0,sat=0,hol=0; + + PutLogFunID("BillDiscountSet"); + + if(strlen(record)<10) return 0; + strcpy(s,record); + while(index<10) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + did = atoi(buf); + if(did>=MAX_DISCOUNT_ID) return 0; + break; + case 0x01: + hour = atoi(buf); + break; + case 0x02: + mon = atoi(buf); + break; + case 0x03: + tue = atoi(buf); + break; + case 0x04: + wed = atoi(buf); + break; + case 0x05: + thu = atoi(buf); + break; + case 0x06: + fri = atoi(buf); + break; + case 0x07: + sat = atoi(buf); + break; + case 0x08: + sun = atoi(buf); + break; + case 0x09: + hol = atoi(buf); + break; + default: + break; + }/* switch */ + index++; + } + shmp->bill_discount[did][hour].discount_id = did; + shmp->bill_discount[did][hour].hours = hour; + shmp->bill_discount[did][hour].days[0] = sun; + shmp->bill_discount[did][hour].days[1] = mon; + shmp->bill_discount[did][hour].days[2] = tue; + shmp->bill_discount[did][hour].days[3] = wed; + shmp->bill_discount[did][hour].days[4] = thu; + shmp->bill_discount[did][hour].days[5] = fri; + shmp->bill_discount[did][hour].days[6] = sat; + shmp->bill_discount[did][hour].days[7] = hol; + + return 1; +} + +int ImportDiscountTariffData(FILE *fp) +{ + char record[512]; + + while(fgets(record,512,fp) != (char *)0) + { + // fprintf(stderr,"record:%s\n",record); + BillDiscountSet(record); + } + + return 1; +} + + +int HolidayTariffSet(char *record) +{ + _tariff_data *shmp=&ramshm_ptr->tariff_data; + + char buf[BUFSIZE],*off,s[BUFSIZE]; + int start=0,index=0,slen=0; + int mon=0,day=0; + + PutLogFunID("HolidayTariffSet"); + + if(strlen(record)<2) return 0; + strcpy(s,record); + while(index<2) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + mon = atoi(buf); + break; + case 0x01: + day = atoi(buf); + break; + default: + break; + }/* switch */ + index++; + } + + if(mon>=1 && mon<13 && day<32 && day>=1) + { + shmp->holiday_flag[mon-1][day-1].month = mon; + shmp->holiday_flag[mon-1][day-1].day = day; + shmp->holiday_flag[mon-1][day-1].mflag = 1; + } + return 1; +} + +int ImportHolidayTariffData(FILE *fp) +{ + char record[512]; + FILE *fpW=NULL; + + // memset(&ramshm_ptr->tariff_data.holiday_flag, + // 0, + // sizeof(_bill_holiday)*12*31); + fpW = fopen(HOLIDAY_CSV,"w"); + + while(fgets(record,512,fp) != (char *)0) + { + HolidayTariffSet(record); + if(fpW !=NULL ) + fprintf(fpW,"%s",record); + } + if(fpW != NULL) + fclose(fpW); + + return 1; +} + +int CommTariffSet(char *record) +{ + _tariff_data *shmp=&ramshm_ptr->tariff_data; + char buf[BUFSIZE]={""},*token; + int index=0,tariff_id=0; + const char delimiter[]=",;"; + + PutLogFunID("CommTariffSet"); + + token = buf; + + if(strlen(record)<10){ + return 0; + } + + while(index <= 0x18) + { + + token = strsep((char **)&(record),delimiter); + if(token == NULL){ + return 0; + } + strcpy(buf,token); + + switch(index) + { + case 0x00: + tariff_id = atoi(buf); + if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) return 0; + break; + case 0x01: /* cf charge unit */ + shmp->comm_tariff[tariff_id].cfChargeUnit = atoi(buf); + break; + case 0x02: /* cf charge amount */ + shmp->comm_tariff[tariff_id].cfChargeAmount = atof(buf); + break; + case 0x03: /* roaming charge unit */ + shmp->comm_tariff[tariff_id].roamingChargeUnit = atoi(buf); + break; + case 0x04: /* roaming charge amount */ + shmp->comm_tariff[tariff_id].roamingChargeAmount = atof(buf); + break; + case 0x05: /* cc charge unit */ + shmp->comm_tariff[tariff_id].ccChargeUnit = atoi(buf); + break; + case 0x06: /* cc charge amount */ + shmp->comm_tariff[tariff_id].ccChargeAmount = atof(buf); + break; + case 0x07: + shmp->comm_tariff[tariff_id].cugChargeUnit = atoi(buf); + break; + case 0x08: + shmp->comm_tariff[tariff_id].cugChargeAmount = atof(buf); + break; + case 0x09: + shmp->comm_tariff[tariff_id].favEditChargeAmount = atof(buf); + break; + case 0x0a: + shmp->comm_tariff[tariff_id].favChargeUnit = atoi(buf); + break; + case 0x0b: + shmp->comm_tariff[tariff_id].favChargeAmount = atof(buf); + break; + case 0x0c: + shmp->comm_tariff[tariff_id].cf_cugChargeUnit = atoi(buf); + break; + case 0x0d: + shmp->comm_tariff[tariff_id].cf_cugChargeAmount = atof(buf); + break; + case 0x0e: + shmp->comm_tariff[tariff_id].cf_favChargeUnit = atoi(buf); + break; + case 0x0f: + shmp->comm_tariff[tariff_id].cf_favChargeAmount = atof(buf); + break; + case 0x10: + shmp->comm_tariff[tariff_id].cug_favChargeUnit = atoi(buf); + break; + case 0x11: + shmp->comm_tariff[tariff_id].cug_favChargeAmount = atof(buf); + break; + case 0x12: + shmp->comm_tariff[tariff_id].cf_cug_favChargeUnit = atoi(buf); + break; + case 0x13: + shmp->comm_tariff[tariff_id].cf_cug_favChargeAmount = atof(buf); + break; + case 0x14: + shmp->comm_tariff[tariff_id].childChangeChargeAmount = atof(buf); + break; + case 0x15: + shmp->comm_tariff[tariff_id].poolAccountChargeUnit = atof(buf); + break; + case 0x16: + shmp->comm_tariff[tariff_id].poolAccountChargeAmount = atof(buf); + break; + case 0x17: + shmp->comm_tariff[tariff_id].activeFreeSMSCharegeAmount = atof(buf); + break; + case 0x18: + shmp->comm_tariff[tariff_id].deactiveFreeSMSCharegeAmount = atof(buf); + break; + default: + break; + }/* switch */ + index++; + } + return 1; +} + +int ImportCommTariffData(FILE *fp) +{ + char record[512]; + + while(fgets(record,512,fp) != (char *)0) + { + //fprintf(stderr,"record:%s\n",record); + CommTariffSet(record); + } + + return 1; +} + + +int BillSMSSet(char *record) +{ + char buf[BUFSIZE],*off,s[BUFSIZE]; + int start=0,index=0,slen=0; + int id=0,tariffid=0; + _bill_sms bill_sms; + + PutLogFunID("BillSMSSet"); + + if(strlen(record)<2) return 0; + strcpy(s,record); + while(index <= 0x07) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + id = atoi(buf); + if(id>MAX_SMS_PREFIX || id<1) return 0; + bill_sms.id = id; + break; + case 0x01: + strcpy(bill_sms.bill_id,buf); + break; + case 0x02: + bill_sms.call_type = atoi(buf); + break; + case 0x03: + strcpy(bill_sms.area,buf); + break; + case 0x04: + tariffid = atoi(buf); + if(tariffid>=MAX_ZONE_NUM || tariffid<0) return 0; + bill_sms.tariffID = tariffid; + break; + case 0x05: + bill_sms.discountID = atoi(buf)%MAX_DISCOUNT_ID; + break; + case 0x06: + bill_sms.base_fee = atof(buf); + break; + case 0x07: + bill_sms.cap_flag = atoi(buf)%3; + break; + default: + break; + }/* switch */ + index++; + } + memcpy(&ramshm_ptr->tariff_data.bill_sms[tariffid][id-1], + &bill_sms,sizeof(_bill_sms)); + return 1; +} + +int ImportBillSMS(FILE *fp) +{ + char record[512]; + + while(fgets(record,512,fp) != (char *)0) + { +// fprintf(stderr,"record:%s",record); + BillSMSSet(record); + } + + return 1; +} + +int vasMMSSendTariffSet(char *record) +{ + char buf[BUFSIZE],*off,s[BUFSIZE]; + int start=0,index=0,slen=0; + int id=0,tariffid=0; + VAS_MMS_TARIFF mmsTariff; + + PutLogFunID("vasMMSSenderTariffSet"); + + if(strlen(record)<2) return 0; + strcpy(s,record); + while(index <= 0x08) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + tariffid = atoi(buf); + if(tariffid>=MAX_ZONE_NUM || tariffid<0) + return 0; + mmsTariff.tariffID = tariffid; + break; + case 0x01: + id = atoi(buf); + if(id>MAX_VAS_MMS_SEND_TARIFF || id<1) + return 0; + mmsTariff.mmsSendID= id; + break; + case 0x02: + mmsTariff.mmsType = atoi(buf); + break; + case 0x03: + strcpy((char *)mmsTariff.prefix, buf); + break; + case 0x04: + mmsTariff.callType= atoi(buf); + break; + case 0x05: + strcpy((char *)mmsTariff.destName,buf); + break; + case 0x06: + mmsTariff.discountID = atoi(buf)%MAX_DISCOUNT_ID; + break; + case 0x07: + mmsTariff.chargeFee = atof(buf); + break; + case 0x08: + mmsTariff.capFlag= atoi(buf); + break; + default: + break; + } + index++; + } + memcpy(&ramshm_ptr->tariff_data.vas_tariff[tariffid].vasMmsSendTariff[id-1],&mmsTariff,sizeof(VAS_MMS_TARIFF)); + return 1; +} + +int ImportVasMmsSendTariff(FILE *fp) +{ + char record[512]; + + memset(zonenum,0,sizeof(zonenum)); + while(fgets(record,512,fp) != (char *)0) + { + vasMMSSendTariffSet(record); + } + + return 1; +} + +int vasMMSTariffRetrieveSet(char *record) +{ + char buf[BUFSIZE],*off,s[BUFSIZE]; + int start=0,index=0,slen=0; + int id=0,tariffid=0; + VAS_MMS_RETRIEVE_TARIFF mmsTariff; + + PutLogFunID("vasMMSTariffRetrieveSet"); + + if(strlen(record)<2) return 0; + strcpy(s,record); + while(index <= 0x07) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + tariffid = atoi(buf); + if(tariffid>=MAX_ZONE_NUM || tariffid<0) + return 0; + mmsTariff.tariffID = tariffid; + break; + case 0x01: + id = atoi(buf); + if(id>MAX_VAS_MMS_RETRIEVE_TARIFF || id<1) + return 0; + mmsTariff.mmsRetrieveID= id; + break; + case 0x02: + strcpy((char *)mmsTariff.prefix,buf); + break; + case 0x03: + mmsTariff.callType= atoi(buf); + break; + case 0x04: + strcpy((char *)mmsTariff.destName,buf); + break; + case 0x05: + mmsTariff.discountID = atoi(buf)%MAX_DISCOUNT_ID; + break; + case 0x06: + mmsTariff.chargeFee = atof(buf); + break; + case 0x07: + mmsTariff.capFlag = atoi(buf); + break; + default: + break; + } + index++; + } + memcpy(&ramshm_ptr->tariff_data.vas_tariff[tariffid].vasMmsRetrieveTariff[id-1],&mmsTariff,sizeof(VAS_MMS_RETRIEVE_TARIFF)); + return 1; +} + + + +int ImportVasMmsRetrieveTariff(FILE *fp) +{ + char record[512]; + + memset(zonenum,0,sizeof(zonenum)); + while(fgets(record,512,fp) != (char *)0) + { + vasMMSTariffRetrieveSet(record); + } + + return 1; +} + + +int vasMMSTariffEmailSet(char *record) +{ + char buf[BUFSIZE],*off,s[BUFSIZE]; + int start=0,index=0,slen=0; + int id=0,tariffid=0; + VAS_MMSEMAIL_DELIVER_TARIFF mmsTariff; + + PutLogFunID("vasMMSTariffEmailSet"); + + if(strlen(record)<2) return 0; + strcpy(s,record); + while(index <= 0x07) + { + if((off=strchr(s,','))==NULL) + off = strchr(s,';'); + slen = off - s; + if(slen>=strlen(record)) slen = strlen(record)-start; + memcpy(buf,s,slen); + buf[slen] = 0; + start += slen+1; + strcpy(s,&record[start]); + switch(index) + { + case 0x00: + tariffid = atoi(buf); + if(tariffid>=MAX_ZONE_NUM || tariffid<0) + return 0; + mmsTariff.tariffID = tariffid; + break; + case 0x01: + id = atoi(buf); + if(id>MAX_VAS_MMSEMAIL_DELIVER_TARIFF || id<1) + return 0; + mmsTariff.emailID= id; + break; + case 0x02: + strcpy((char *)mmsTariff.prefix,buf); + break; + case 0x03: + mmsTariff.callType= atoi(buf); + break; + case 0x04: + strcpy((char *)mmsTariff.destName,buf); + break; + case 0x05: + mmsTariff.discountID = atoi(buf)%MAX_DISCOUNT_ID; + break; + case 0x06: + mmsTariff.chargeFee = atof(buf); + break; + case 0x07: + mmsTariff.capFlag = atoi(buf); + break; + default: + break; + } + index++; + } + memcpy(&ramshm_ptr->tariff_data.vas_tariff[tariffid].vasMmsEmailDeliverTariff[id-1],&mmsTariff,sizeof(VAS_MMSEMAIL_DELIVER_TARIFF)); + return 1; +} + +int ImportVasEmailTariff(FILE *fp) +{ + char record[512]; + + memset(zonenum,0,sizeof(zonenum)); + while(fgets(record,512,fp) != (char *)0) + { + vasMMSTariffEmailSet(record); + } + + return 1; +} + +/* ----------------+ Upload data procedure end +---------------------*/ + +/* ----------------+ Sync configuration data procedures (recall) +---*/ + + +/*message received from peer server,edit,add*/ +int SetUserDataBySync(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen,int reflag) +{ + int instance,ocode,len=0; + //long lmsisdn; + int head,tail,store_index; + char msisdn[64]={""}; + + _prepaid_info *shmp=NULL,tmpSubsData; + +#if DEBUG1 + int i; + char buf[1024]={""},workbuf[32]={""}; + + DebugMsg(debugmib.display.asciiOut,"received user data sync message"); + + for(i=0;i4 || ocode<1) return 0; + debugmib.msgstatistics.recv_sync[ocode-1] ++; + + len = pdata[MAX_MSISDN_BLEN-1]; //len of msisdn + if(len>MAX_MSISDN_ALEN || len=MSISDN_HEAD_NUM) + return 0; + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(ocode == 4) + memset(shmp,0,sizeof(_prepaid_info)); + else + memcpy(shmp,pdata,sizeof(_prepaid_info)); + return datalen; + + } + + BcdToAscii(msisdn,pdata,9*2); + msisdn[len] = 0; + //lmsisdn = atoll(msisdn); + shmp = &tmpSubsData; + + if(ocode == 3) + { + store_index = GetPPSSubsRecord(msisdn,shmp); + if(store_index<0) + { + if(debugmib.measurement.usernumber>=ppsParam.serviceControl.licenseduser) + { + DebugMsg(debugmib.display.asciiOut, + "Error: received sync. messgae to add new subs. %s ",msisdn); + DebugMsg(debugmib.display.asciiOut, + " But exist users %d >= licensed user(%ld)!" , + debugmib.measurement.usernumber, + ppsParam.serviceControl.licenseduser); + return 0; + } + memcpy(shmp,pdata,sizeof(_prepaid_info)); + AddPPSSubsData(shmp); + } + else + { + if(replaceableFlag == 0) + { + DebugMsg(debugmib.display.asciiOut, "Account %s is in use, cann't be replaced!",msisdn); + return 0; + } + DebugMsg(debugmib.display.asciiOut, "Account %s is in use, replaced it!",msisdn); + memcpy(shmp,pdata,sizeof(_prepaid_info)); + ModifyPPSSubsData(shmp); + } + } + else + { + store_index = GetPPSSubsRecord(msisdn,shmp); + + if(store_index<0) + { + /* + if(ocode == 2) + { + memcpy(shmp,pdata,sizeof(_prepaid_info)); + AddPPSSubsData(shmp); + return datalen; + } + */ + /* create the subs if no subs. for update operation,2006-05-09*/ + debugmib.watch_dog[53]++; + DebugMsg(debugmib.display.asciiOut,"Error sync message received: with instance: %d VS %d, not existed", + store_index,instance); + return 0; + } + if(store_index != instance) + { + debugmib.watch_dog[54]++; + DebugMsg(debugmib.display.asciiOut,"Error sync message received: with instance: %d VS %d", + store_index,instance); + //return 0; + } + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + + if(ocode == 4) + { + debugmib.watch_dog[52]++; + if(masterFlag) + SendOperatorRechargeCDR(head,tail,-shmp->balance); + + DeletePPSSubsData(shmp); + } + else if(ocode == 2) + { + double balance,promotion, oldbalance,oldpromotion; + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + oldbalance = shmp->balance; + oldpromotion = shmp->promo_balance; + + if(datalen >= sizeof(_prepaid_info) + sizeof(double)) + memcpy(&balance,&pdata[sizeof(_prepaid_info)],sizeof(double)); + + if(datalen >= sizeof(_prepaid_info) + 2*sizeof(double)) + memcpy(&promotion,&pdata[sizeof(_prepaid_info)+sizeof(double)],sizeof(double)); + + memcpy(shmp,pdata,sizeof(_prepaid_info)); + if(balance != 0) + { + shmp->balance = oldbalance + balance; + if (shmp->balance < 0.0001) + { + shmp->balance = 0; + } + } + if(promotion != 0) + { + shmp->promo_balance = oldpromotion + promotion; + } + pps_real_update_user_file(head, tail); + + //ModifyPPSSubsData(shmp); + } + } + + //if(reflag) +// SendAccountRealSync(oid[15],oid[16]); + + return datalen; +} + + +int SetUserDataByTcpSync(BYTE *pdata, WORD datalen, DWORD instance, DWORD ocode) +{ + int len = 0; + //long lmsisdn; + int head,tail, store_index; + char msisdn[64] = {""}; + + _prepaid_info *shmp = NULL, tmpSubsData; + + PutLogFunID("SetUserDataByTcpSync"); + + // Check msg length + if(datalen < sizeof(_prepaid_info)) + { + debugmib.watch_dog[57]++; + return 0; + } + + // Check operation code + if(ocode>=MAX_OMC_OCODE || ocode<=OMC_OCODE_NULL) + { + return 0; + } + debugmib.msgstatistics.recv_sync[ocode-1] ++; + + // Check msisdn length + len = pdata[MAX_MSISDN_BLEN-1]; //len of msisdn + if(len>MAX_MSISDN_ALEN || len=MSISDN_HEAD_NUM) + { + return 0; + } + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(ocode == OMC_OCODE_DEL) + { + memset(shmp, 0, sizeof(_prepaid_info)); + } + else// modify or add + { + memcpy(shmp, pdata, sizeof(_prepaid_info)); + } + return datalen; + } + + BcdToAscii(msisdn, pdata, 9*2); + msisdn[len] = 0; + //lmsisdn = atoll(msisdn); + shmp = &tmpSubsData; + + if(ocode == OMC_OCODE_ADD) + { + store_index = GetPPSSubsRecord(msisdn, shmp); + if(store_index < 0) + { + if(debugmib.measurement.usernumber >= ppsParam.serviceControl.licenseduser) + { + DebugMsg(debugmib.display.asciiOut, + "Error: received tcp sync. messgae to add new subs. %s ", msisdn); + DebugMsg(debugmib.display.asciiOut, + " But exist users %d >= licensed user(%ld)!" , + debugmib.measurement.usernumber, + ppsParam.serviceControl.licenseduser); + return 0; + } + memcpy(shmp, pdata, sizeof(_prepaid_info)); + AddPPSSubsData(shmp); + } + else + { + if(replaceableFlag == 0) + { + DebugMsg(debugmib.display.asciiOut, "Account %s is in use, cann't be replaced!", msisdn); + return 0; + } + DebugMsg(debugmib.display.asciiOut, "Account %s is in use, replaced it!", msisdn); + memcpy(shmp, pdata, sizeof(_prepaid_info)); + ModifyPPSSubsData(shmp); + } + } + else + { + store_index = GetPPSSubsRecord(msisdn,shmp); + + if(store_index<0) + { + /* + if(ocode == OMC_OCODE_EDIT) + { + memcpy(shmp,pdata,sizeof(_prepaid_info)); + AddPPSSubsData(shmp); + return datalen; + } + */ + + /* create the subs if no subs. for update operation, 2006-05-09*/ + debugmib.watch_dog[53]++; + DebugMsg(debugmib.display.asciiOut, "Error sync message received: with instance: %d VS %d, not existed", + store_index,instance); + return 0; + } + + if(store_index != instance) + { + debugmib.watch_dog[54]++; + DebugMsg(debugmib.display.asciiOut, "Error sync message received: with instance: %d VS %d", + store_index, instance); + //return 0; + } + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + + if(ocode == OMC_OCODE_DEL) + { + debugmib.watch_dog[52]++; + if(masterFlag) + SendOperatorRechargeCDR(head, tail, -shmp->balance); + + DeletePPSSubsData(shmp); + } + else if(ocode == OMC_OCODE_EDIT) + { + double balance, promotion, oldbalance, oldpromotion; + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + oldbalance = shmp->balance; + oldpromotion = shmp->promo_balance; + + if(datalen >= sizeof(_prepaid_info) + sizeof(double)) + memcpy(&balance, &pdata[sizeof(_prepaid_info)], sizeof(double)); + + if(datalen >= sizeof(_prepaid_info) + 2*sizeof(double)) + memcpy(&promotion, &pdata[sizeof(_prepaid_info)+sizeof(double)], sizeof(double)); + + memcpy(shmp, pdata, sizeof(_prepaid_info)); + if(balance != 0) + { + shmp->balance = oldbalance + balance; + if (shmp->balance < 0.0001) + { + shmp->balance = 0; + } + } + if(promotion != 0) + { + shmp->promo_balance = oldpromotion + promotion; + } + pps_real_update_user_file(head, tail); + + //ModifyPPSSubsData(shmp); + } + } + + //if(reflag) +// SendAccountRealSync(oid[15],oid[16]); + + return datalen; +} + + +extern void PrepaidCardTcpRealSyncProc(BYTE *pdata, WORD dataLen, DWORD instance, DWORD ocode); +int tcpRealSyncProc(WORD usr_port, BYTE *pdata, WORD datalen, DWORD db_type, DWORD instance, DWORD ocode) +{ + PutLogFunID("tcpRealSyncProc"); + + switch(db_type){ + case PPS_USER_DATA_DB_OID:/* user data */ + SetUserDataByTcpSync(pdata, datalen, instance, ocode); + break; + case PPS_PREPAID_CARD_DB_OID:/* prepaid card */ + PrepaidCardTcpRealSyncProc(pdata, datalen, instance, ocode); + break; + default: + break; + } + + return 1; +} + +int dataSyncCallPro(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD len,int reflag) +{ + int /*oid0,*/oid1,oid2; + + PutLogFunID("dataSyncCallPro"); + + if(oidlen<14) return 0; + //oid0 = oid[11]; + + oid1 = oid[12]; + oid2 = oid[13]; + + switch(oid1) + { + case 0x01: + return 0; + break; + case 0x02: + switch(oid2){ + case 2:/* user data */ + SetUserDataBySync(oidlen,oid,pdata,len,reflag); + break; + case 3:/* prepaid */ + //SetPrepaidDataBySync(oidlen,oid,pdata,len); + break; + case 4:/* tariff */ + break; + } + break; + default: + break; + } + return 1; +} + +/* +int RealSyncGlobalParam(PPSParamStruct globalparam) +{ + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + PutLogFunID("RealSyncGlobalParam"); + + snmpbuf.pdu_type = 0x07; //trap + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; + snmpaddr.remote_port = PPS_REALSYNC_PORT; + snmpaddr.local_port = PPS_REALSYNC_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 14; + varlist->vartype = 0x04; + + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x02; //configuration + varlist->oid[12] = 0x01; //system parameter + varlist->oid[13] = 0x00; //instance; + + varlist->msglen = sizeof(ppsParam); + memcpy(varlist->msg, + (u_char *) &globalparam, + sizeof(ppsParam)); + snmp_send(&snmpbuf,&snmpaddr); + +#if DEBUG1 + DebugMsg(debugmib.display.asciiOut,"SendGlobalParam Sync message\n"); +#endif + return 1; +} +*/ +int SyncTariffData() +{ + static int sendindex = 0; + if(sendindex ++>1) return 1; + return 0; +} + +/*message received from OMC, delete*/ +int SetUserDataByOMC(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen) +{ + int ocode,send_f_f_sms_flag=0; + int head,tail,store_index; + //long lmsisdn; + int len;//,mslen; + int i,vallen,chargeFlag=0,/*addFlag=0,*/charge=0; + char buf[2048]=""; + char valbuf[32]=""; + //struct tm tmnow; + CosServiceControl *serviceControlItem; + CosFriendFamilyControl *friendFamilyControl; + int totalLen=0; + unsigned int tmpval; + int loop=0; + double balance,difbalance=0,oldbalance,dif_promo_balance=0,old_promo_balance; + u_short portid; + BYTE pdata1[1600],pdata2[1600],pflag; + u_short ptagcode; + char tagbuf[32],tmpBuf[32]; + _prepaid_info *shmp=NULL,tmpSubsData; + PoolParent *pParent; + PoolChild *pChild; + _state_data *stat_shmp; + + + ASN_BUF *asnbuf, asnbuf1; + ASN_BUF *asnbuf2, asnbuf3; + + PutLogFunID("SetUserDataByOMC"); + + if(debugmib.display.sysState != _SYS_STATE_NORMAL) + { + sprintf((char *)pdata,"operation not support for system in error state"); + return -1; + } + memset(pdata1,0,datalen+1); + + memcpy(pdata1,pdata,datalen); + pdata1[datalen]=0; + + asnbuf = &asnbuf1; + + AsnEncode(pdata,1600,asnbuf); + asnbuf2 = &asnbuf3; + + AsnDecode(pdata1, datalen, UNIT_STORE_ACCOUNT, NULL, asnbuf2); + //BcdToAscii(buf,pdata1,datalen*2); + //printf("dataLen:%d,data:%s\n",datalen,buf); + +#if DEBUG1 + { + if((logMsgFlag == 0x40)) + DebugMsg(debugmib.display.asciiOut,"received user data omc message"); + if(logMsgFlag == 0x40) + { + for(i=0;i0x04) + { + return -1; + } + if(oid[13]>0) + sprintf(buf,"%u%08u",oid[13],oid[14]); + else + sprintf(buf,"%u",oid[14]); + len = strlen(buf); + + if(len>MAX_MSISDN_ALEN || len=ppsParam.serviceControl.licenseduser) + { + sprintf((char *)pdata,"Too many msisdn %ld, license is %u", + debugmib.measurement.usernumber,ppsParam.serviceControl.licenseduser); + DebugMsg(debugmib.display.asciiOut,"Too many msisdn %ld, license is %ld", + debugmib.measurement.usernumber,ppsParam.serviceControl.licenseduser); + return -2; + } + debugmib.watch_dog[8]++; + memset(shmp,0,sizeof(_prepaid_info)); + sprintf(shmp->pin,"123456"); + shmp->first_used_date = tvnow.tv_sec; + shmp->mo_expiration_date = tvnow.tv_sec; + shmp->mt_expiration_date = tvnow.tv_sec; + shmp->promo_date = tvnow.tv_sec; + } + else + { + if(ocode == OMC_OCODE_DEL){ //delete + SendAccountRealSync(store_index,0.0,0.0,ocode); //delete + return datalen; + } + if(ocode == OMC_OCODE_ADD) + { + debugmib.watch_dog[9]++; + if(replaceableFlag == 0) + { + sprintf((char *)pdata,"account %s is in use, can not be replaced!",buf); + if(logMsgFlag == 0x40) + DebugMsg(debugmib.display.asciiOut,"account %s is in use, can not be replaced!",buf); + return -2; + } + else + { + if(logMsgFlag == 0x40) + DebugMsg(debugmib.display.asciiOut,"account %s is in use, replace it!",buf); + } + } + else + { + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + } + } + + for(loop=1;loop<=MAX_PPS_USER_FIELD_NUMS;loop++) + { + sprintf(tagbuf,"-%d",loop); + if((vallen=GetAnyTLV(tagbuf,1024,pdata2,&pflag,&ptagcode,asnbuf2))<0){ + break; + } + sprintf(tagbuf,"%d",ptagcode); + pdata2[vallen]=0; + + switch(ptagcode) + { + case 0x01: //msisdn + if(ocode==OMC_OCODE_READ) + { + BcdToAscii(valbuf,shmp->msisdn,MAX_MSISDN_ALEN); + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + if(len==0) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + return -1; + } + else + { + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(vallen == 0) continue; + if(vallen > MAX_MSISDN_ALEN || vallen'9' || pdata2[i]<'0' || pdata2[0] =='0') + { + sprintf((char *)pdata,"Error msisdn"); + DebugMsg(debugmib.display.asciiOut,"Error msisdn"); + return -2; + } + } + if(shmp->msisdn[MAX_MSISDN_BLEN-1]==0) {/*addFlag = 1*/;} + AsciiToBcd(shmp->msisdn, (char *)pdata2,(vallen+1)/2*2); + if(vallen%2==0) + shmp->msisdn[vallen/2] = 0xFF; + else + shmp->msisdn[vallen/2] |= 0x0F; + shmp->msisdn[MAX_MSISDN_BLEN-1] = vallen; + vallen = shmp->msisdn[MAX_MSISDN_BLEN-1]; + BcdToAscii(valbuf,shmp->msisdn,(vallen+1)/2*2); + totalLen = add_tlv(tagbuf,vallen, (u_char *)valbuf,0x80,asnbuf); + } + break; + case 0x02: + if(ocode == OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,MAX_PIN_LEN, (u_char *)shmp->pin,0x80,asnbuf); + } + else + { + if(vallen != MAX_PIN_LEN) + { + sprintf((char *)pdata,"Error PIN length , should be 6 digits!"); + DebugMsg(debugmib.display.asciiOut, + "Error PIN length , should be 6 digits!"); + return -2; + } + for(i=0;i'9' || pdata2[i]<'0') + { + sprintf((char *)pdata,"Error PIN format, only support digits of 0-9!"); + DebugMsg(debugmib.display.asciiOut, + "Error PIN format, only support digits of 0-9!"); + return -2; + } + } + memcpy(shmp->pin,pdata2,MAX_PIN_LEN); + totalLen = add_tlv(tagbuf,MAX_PIN_LEN, (u_char *)shmp->pin,0x80,asnbuf); + } + break; + case 0x03: //status + if(ocode==OMC_OCODE_READ){ + len = 1; + valbuf[0] = shmp->status; + totalLen = add_tlv(tagbuf,1,&shmp->status,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval,pflag,asnbuf2)<=0) continue; + if(tmpval>T_RELEASED) + { + sprintf((char *)pdata,"Error status!"); + return -2; + } + shmp->status = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->status,0x80,asnbuf); + } + break; + case 0x04: /* balance */ + if(ocode==OMC_OCODE_READ) + { + balance = shmp->balance; + totalLen = AddInteger(tagbuf,(int)balance,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + int int_val; + + if(GetInteger(tagbuf,&int_val ,pflag,asnbuf2)<=0) continue; + if(int_val>ppsParam.serviceControl.maxBalance){ + sprintf((char *)pdata,"Too big account balance(%d),should be(0-%d)", + int_val,ppsParam.serviceControl.maxBalance); + DebugMsg(debugmib.display.asciiOut,"Too big account balance(%d)",int_val); + return -2; + } + + balance = (double)int_val; + oldbalance=(int)shmp->balance; + shmp->balance = balance; + if(oldbalance != balance) + { + chargeFlag |= 0x01; + difbalance = balance-oldbalance; + } + totalLen = AddInteger(tagbuf,int_val,0x80,asnbuf); + } + break; + case 0x05: /* promotion balance */ + if(ocode==OMC_OCODE_READ) + { + balance = shmp->promo_balance; + totalLen = AddInteger(tagbuf,(int)balance,0x80,asnbuf); + }else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + int int_val1; + + if(GetInteger(tagbuf,&int_val1 ,pflag,asnbuf2)<=0) continue; + if(int_val1>ppsParam.serviceControl.maxBalance){ + sprintf((char *)pdata,"Too big account balance(%d),should be(0-%d)", + int_val1,ppsParam.serviceControl.maxBalance); + DebugMsg(debugmib.display.asciiOut,"Too big account balance(%d)",int_val1); + return -2; + } + + balance = int_val1; + old_promo_balance = shmp->promo_balance; + shmp->promo_balance = (double) int_val1; + if(old_promo_balance != balance){ + chargeFlag |= 0x02; + dif_promo_balance = balance-old_promo_balance; + } + totalLen = AddInteger(tagbuf,int_val1,0x80,asnbuf); + } + break; + case 0x06: //overdraft + if(ocode==OMC_OCODE_READ) + { + len = 4; + totalLen = AddInteger(tagbuf,shmp->overdraft,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval,pflag,asnbuf2)<=0) continue; + shmp->overdraft = tmpval; + totalLen = AddInteger(tagbuf,shmp->overdraft,0x80,asnbuf); + } + break; + case 0x07: //first used date + if(ocode==OMC_OCODE_READ) + { + AsciiTime(buf,shmp->first_used_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + BcdToAscii(buf,pdata2,vallen*2); + shmp->first_used_date = MakeTime(NULL,buf); + if(ocode==OMC_OCODE_ADD) + { + shmp->first_used_date = tvnow.tv_sec; + } + AsciiTime(buf,shmp->first_used_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + break; + case 0x08: //mo expiration date + if(ocode==OMC_OCODE_READ){ + AsciiTime(buf,shmp->mo_expiration_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + BcdToAscii(buf,pdata2,vallen*2); + shmp->mo_expiration_date = MakeTime(NULL,buf); + + AsciiTime(buf,shmp->mo_expiration_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + break; + case 0x09: //mt expiration date + if(ocode==OMC_OCODE_READ) + { + AsciiTime(buf,shmp->mt_expiration_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + }else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + BcdToAscii(buf,pdata2,vallen*2); + shmp->mt_expiration_date = MakeTime(NULL,buf); + AsciiTime(buf,shmp->mt_expiration_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + break; + case 0x0a: //promotion balance expiration date + if(ocode==OMC_OCODE_READ) + { + AsciiTime(buf,shmp->promo_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + }else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + BcdToAscii(buf,pdata2,vallen*2); + shmp->promo_date = MakeTime(NULL,buf); + + AsciiTime(buf,shmp->promo_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + break; + case 0x0b: + if(ocode == OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->cos_id,0x80,asnbuf); + } + else + { + int max_cos = MaxCosTableItem; + if(GetInteger(tagbuf, (int *)&tmpval,pflag,asnbuf2)<=0) continue; + if(ppsParam.serviceControl.cos_group_flag) + max_cos = MAX_ZONE_NUM_NEW; + + if(tmpval >= max_cos) + { + sprintf((char *)pdata,"Error id of COS, should be 0-%d!",max_cos-1); + DebugMsg(debugmib.display.asciiOut, + "Error id of COS, should be 0-%d!",max_cos-1); + return -2; + } + shmp->cos_id = tmpval; + totalLen = AddInteger(tagbuf,shmp->cos_id,0x80,asnbuf); + } + break; + case 0x0c: //rent_type + if(ocode==OMC_OCODE_READ){ + totalLen = add_tlv(tagbuf,1,&shmp->rent_type,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + /* + if(tmpval>0xFF) + { + sprintf(pdata,"Error rent type value %d, should be less than 0xFF",tmpval); + return -2; + } + */ + shmp->rent_type = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->rent_type,0x80,asnbuf); + } + break; + case 0x0d: + case 0x0e: + case 0x0f: + case 0x10: + if(ocode == OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->home_location[ptagcode-13],0x80,asnbuf); + } + else + { + if(GetInteger(tagbuf, (int *)&tmpval,pflag,asnbuf2)<=0) continue; + if(tmpval>=MaxBasicTariffZoneItem) + { + sprintf((char *)pdata,"Error location id, should be 0-%d",MaxBasicTariffZoneItem-1); + return -2; + } + shmp->home_location[ptagcode-13] = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->home_location[ptagcode-13],0x80,asnbuf); + } + break; + case 0x11: //cug id + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->cug_id,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>MAX_CUG_ID) + { + sprintf((char *)pdata,"Too big cug id(%d),should be(0-%d)", + tmpval,MAX_CUG_ID); + return -2; + } + shmp->cug_id = tmpval; + totalLen = AddInteger(tagbuf,shmp->cug_id,0x80,asnbuf); + } + break; + case 0x12: + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->language_type,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>=MAX_LANGUAGE_TYPES) + { + sprintf((char *)pdata,"Error language type code, should be 0-%d!",MAX_LANGUAGE_TYPES); + return -2; + } + shmp->language_type = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->language_type,0x80,asnbuf); + } + break; + case 0x13: //recharge failure + if(ocode==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->recharge_fail,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval,pflag,asnbuf2)<=0) continue; + shmp->recharge_fail = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->recharge_fail,0x80,asnbuf); + } + break; + case 0x14: //free sm counter + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->free_sm_counter,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->free_sm_counter = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->free_sm_counter,0x80,asnbuf); + } + break; + case 0x15: //latch flag + totalLen = add_tlv(tagbuf,1,&shmp->latch_flag,0x80,asnbuf); + break; + case 0x16: //favorite numbers + totalLen = AddInteger(tagbuf,shmp->favorite_numbers,0x80,asnbuf); + break; + case 0x17: //fav_change counter + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->fav_change_counter,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->fav_change_counter = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->fav_change_counter,0x80,asnbuf); + } + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + if(ocode ==OMC_OCODE_READ) + { + len = shmp->favorite_number[ptagcode-24][MAX_MSISDN_BLEN-1]; + if(len<3 || len>MAX_MSISDN_ALEN) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + BcdToAscii(valbuf,shmp->favorite_number[ptagcode-24],MAX_MSISDN_ALEN); + valbuf[len] = 0; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(vallen == 0 && ocode == OMC_OCODE_EDIT) + { + if(shmp->favorite_number[ptagcode-24][MAX_MSISDN_BLEN-1]>3) + { + if(shmp->favorite_numbers >0 ) + shmp->favorite_numbers --; + /* + serviceControlItem = &ppsParam.ppsTables.cosTable[shmp->cos_id].serviceControl[0]; + if(serviceControlItem->friendFamilyChangeChargeFlag) + { + if(IncreaseFavoriteNumberChangeCounterByOmc(shmp)> + serviceControlItem->friendFamilyFreeChangeTimes) + { + portid = AssignProcID(); + if(portid>0 && portid< MAX_FSM_PROCESS) + { + stat_shmp = (_state_data *)&smshm_ptr->state_data; + stat_shmp += portid; + + stat_shmp->caller_info.head = head; + stat_shmp->caller_info.tail = tail; + + BillingFavoriteNumberChange(stat_shmp); + SendPeriodicChargeCDR(head, + tail, + stat_shmp->caller_info.charge, + CT_PERIODIC_CHARGE); + ReleasePortStatus(portid); + } + } + } + */ + } + memset(shmp->favorite_number[ptagcode-24],0,MAX_MSISDN_BLEN); + //shmp->favorite_number[ptagcode-24][MAX_MSISDN_BLEN-1] = 0; + totalLen = add_null(tagbuf,0x80,asnbuf); + continue; + } + + if((vallen > MAX_MSISDN_ALEN || vallen<3 )&& vallen!=0){ + sprintf((char *)pdata,"Friend and Family number length(%d) error, should be(3-16)",vallen); + DebugMsg(debugmib.display.asciiOut, + "Friends and Family number length(%d) error, should be(3-16)",vallen); + return -2; + } + + if(atoi((char *)pdata2)==0) + { + //sprintf(pdata,"Error favorite number,all digits are 0"); + //DebugMsg(debugmib.display.asciiOut,"Error favorite number,all digits are 0"); + //return -2; + continue; + } + + for(i=0;i'9' || pdata2[i]<'0') + { + sprintf((char *)pdata,"Error Friends and Family number"); + DebugMsg(debugmib.display.asciiOut,"Error Friends and Family number"); + return -2; + } + } + + friendFamilyControl = &ppsParam.ppsTables.cosTable[shmp->cos_id].friendFamilyControl[0]; + if(!(friendFamilyControl->friendFamilyFlag)) + { + sprintf((char *)pdata,"Friends and Family number service not applied!"); + return -2; + } + + portid = AssignProcID(0); + stat_shmp = (_state_data *)&smshm_ptr->state_data; + stat_shmp += portid; + + stat_shmp->caller_info.head = head; + stat_shmp->caller_info.tail = tail; + stat_shmp->caller_info.cos_id = shmp->cos_id; + stat_shmp->caller_info.location = GetAccountZoneID(stat_shmp->caller_info.head, + stat_shmp->caller_info.tail); + if((ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) ) + { + if(shmp->favorite_number[ptagcode-24][MAX_MSISDN_BLEN-1]<3) + { + if(!IsEnableToAddEditFavoriteNumber(stat_shmp, 0)) + { + sprintf((char *)pdata,"Friends and Family number is not allowed for low balance or too many exsiting numbers!"); + ReleasePortStatus(portid); + return -2; + } + } + + strcpy(stat_shmp->process_info.tmpDigits, (char *)pdata2); + if(!IsFavoriteNumberTypeOk(stat_shmp)) + { + sprintf((char *)pdata,"Friends and Family number type is not allowed!"); + ReleasePortStatus(portid); + return -2; + } + + if(shmp->favorite_number[ptagcode-24][MAX_MSISDN_BLEN-1]<2) + { + shmp->favorite_numbers ++; + if(shmp->favorite_numbers>MAX_FAVORITE_NUMBERS) + shmp->favorite_numbers = MAX_FAVORITE_NUMBERS; + } + } + + if(ocode == OMC_OCODE_EDIT) + { + len = shmp->favorite_number[ptagcode-24][MAX_MSISDN_BLEN-1]; + BcdToAscii(tmpBuf,shmp->favorite_number[ptagcode-24],18); + StringCut(tmpBuf,'F'); + tmpBuf[len] = 0; + + if(strcmp(tmpBuf, (char *)pdata2)) + { + strcpy(stat_shmp->process_info.tmpDigits, (char *)pdata2); + if(!IsFavoriteNumberTypeOk(stat_shmp)) + { + sprintf((char *)pdata,"Friends and Family number type is not allowed!"); + ReleasePortStatus(portid); + return -2; + } + if(friendFamilyControl->friendFamilyChangeChargeFlag) + { + if(IncreaseFavoriteNumberChangeCounterByOmc(shmp)> + friendFamilyControl->friendFamilyFreeChangeTimes) + { + charge = -BillingFavoriteNumberChange(stat_shmp); + difbalance += charge; + shmp->balance = shmp->balance + charge; + chargeFlag |= 0x08; + } + } + }//strcmp + } + + ReleasePortStatus(portid); + + AsciiToBcd(shmp->favorite_number[ptagcode-24], (char *)pdata2,(vallen+1)/2*2); + shmp->favorite_number[ptagcode-24][MAX_MSISDN_BLEN-1] = vallen; + if(vallen %2 ==0) + shmp->favorite_number[ptagcode-24][vallen/2] = 0xFF; + else + shmp->favorite_number[ptagcode-24][vallen/2] |= 0x0F; + + totalLen = add_tlv(tagbuf,vallen,pdata2,0x80,asnbuf); + } + break; + case 0x01d: + if(ocode==OMC_OCODE_READ){ + len = 1; + totalLen = add_tlv(tagbuf,1,&shmp->last_call_type,0x80,asnbuf); + } + else + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + break; + case 0x1e: + if(ocode==OMC_OCODE_READ && shmp->last_call_date>0) + { + AsciiTime(buf,shmp->last_call_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + break; + case 0x1f: + if(ocode ==OMC_OCODE_READ) + { + len = shmp->last_call_number[MAX_MSISDN_BLEN-1]; + if(len<3 || len>MAX_MSISDN_ALEN) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + if(len%2==1) + { + ppsBcdToAsciiR(buf,shmp->last_call_number,len+1); + StringCut(buf,'F'); + } + else + { + ppsBcdToAsciiR(buf,shmp->last_call_number,len); + } + totalLen = add_tlv(tagbuf,len, (u_char *)buf,0x80,asnbuf); + } + } + break; + case 32: /* in net cap SM balance */ + if(ocode==OMC_OCODE_READ) + { + balance = shmp->in_net_cap_sms_balance; + totalLen = AddInteger(tagbuf,(int)balance,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + int int_val; + if(GetInteger(tagbuf,&int_val ,pflag,asnbuf2)<=0) continue; + if(int_val>ppsParam.serviceControl.maxBalance){ + sprintf((char *)pdata,"Too big balance(%d),should be(0-%d)", + int_val,ppsParam.serviceControl.maxBalance); + DebugMsg(debugmib.display.asciiOut,"Too big account balance(%d)",int_val); + return -2; + } + balance = (double)int_val; + shmp->in_net_cap_sms_balance = balance; + + totalLen = AddInteger(tagbuf,int_val,0x80,asnbuf); + } + break; + case 33: /* in net cap SM counter */ + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->in_net_cap_sms_counter,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>50000) + { + sprintf((char *)pdata,"Too big value(%d),should be(0-%d)", + tmpval,50000); + return -2; + } + shmp->in_net_cap_sms_counter = tmpval; + totalLen = AddInteger(tagbuf,shmp->in_net_cap_sms_counter,0x80,asnbuf); + } + break; + case 34: /* out net cap SM balance */ + if(ocode==OMC_OCODE_READ) + { + balance = shmp->out_net_cap_sms_balance; + totalLen = AddInteger(tagbuf,(int)balance,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + int int_val; + if(GetInteger(tagbuf,&int_val ,pflag,asnbuf2)<=0) continue; + if(int_val>ppsParam.serviceControl.maxBalance){ + sprintf((char *)pdata,"Too big balance(%d),should be(0-%d)", + int_val,ppsParam.serviceControl.maxBalance); + DebugMsg(debugmib.display.asciiOut,"Too big account balance(%d)",int_val); + return -2; + } + balance = (double)int_val; + shmp->out_net_cap_sms_balance = balance; + totalLen = AddInteger(tagbuf,int_val,0x80,asnbuf); + } + break; + case 35: /* out net cap SM counter */ + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->out_net_cap_sms_counter,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>50000) + { + sprintf((char *)pdata,"Too big value(%d),should be(0-%d)", + tmpval,50000); + return -2; + } + shmp->out_net_cap_sms_counter = tmpval; + totalLen = AddInteger(tagbuf,shmp->out_net_cap_sms_counter,0x80,asnbuf); + } + break; + case 36: /* in_net_cap_call_balance */ + if(ocode==OMC_OCODE_READ) + { + balance = shmp->in_net_cap_call_balance; + totalLen = AddInteger(tagbuf,(int)balance,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + int int_val; + if(GetInteger(tagbuf,&int_val ,pflag,asnbuf2)<=0) continue; + if(int_val>ppsParam.serviceControl.maxBalance){ + sprintf((char *)pdata,"Too big balance(%d),should be(0-%d)", + int_val,ppsParam.serviceControl.maxBalance); + DebugMsg(debugmib.display.asciiOut,"Too big account balance(%d)",int_val); + return -2; + } + balance = (double)int_val; + shmp->in_net_cap_call_balance = balance; + + totalLen = AddInteger(tagbuf,int_val,0x80,asnbuf); + } + break; + case 37: /* in_net_cap_call_duration */ + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->in_net_cap_call_duration,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>50000) + { + sprintf((char *)pdata,"Too big value(%d),should be(0-%d)", + tmpval,50000); + return -2; + } + shmp->in_net_cap_call_duration = tmpval; + totalLen = AddInteger(tagbuf,shmp->in_net_cap_call_duration,0x80,asnbuf); + } + break; + case 38: /* out_net_cap_call_balance */ + if(ocode==OMC_OCODE_READ) + { + balance = shmp->out_net_cap_call_balance; + totalLen = AddInteger(tagbuf,(int)balance,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + int int_val; + if(GetInteger(tagbuf,&int_val ,pflag,asnbuf2)<=0) continue; + if(int_val>ppsParam.serviceControl.maxBalance){ + sprintf((char *)pdata,"Too big balance(%d),should be(0-%d)", + int_val,ppsParam.serviceControl.maxBalance); + DebugMsg(debugmib.display.asciiOut,"Too big account balance(%d)",int_val); + return -2; + } + balance = (double)int_val; + shmp->out_net_cap_call_balance = balance; + + totalLen = AddInteger(tagbuf,int_val,0x80,asnbuf); + } + break; + case 39: /* out_net_cap_call_duration */ + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->out_net_cap_call_duration,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>50000) + { + sprintf((char *)pdata,"Too big value(%d),should be(0-%d)", + tmpval,50000); + return -2; + } + shmp->out_net_cap_call_duration = tmpval; + totalLen = AddInteger(tagbuf,shmp->out_net_cap_call_duration,0x80,asnbuf); + } + break; + case 40: //freeSMSActiveDays + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->freeSMSActiveDays,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->freeSMSActiveDays = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->freeSMSActiveDays,0x80,asnbuf); + } + break; + case 41://pool role + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->poolAccount.role,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->poolAccount.role = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->poolAccount.role,0x80,asnbuf); + } + break; + case 42: + pParent = &shmp->poolAccount.roleParty.parent; + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&pParent->childNumber,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + pParent->childNumber = tmpval; + totalLen = add_tlv(tagbuf,1,&pParent->childNumber,0x80,asnbuf); + } + break; + case 43: + pParent = &shmp->poolAccount.roleParty.parent; + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&pParent->changeTimes,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + pParent->changeTimes = tmpval; + totalLen = add_tlv(tagbuf,1,&pParent->changeTimes,0x80,asnbuf); + } + break; + case 44: + case 45: + case 46: + case 47: + case 48: + ptagcode -= 44; + pParent = &shmp->poolAccount.roleParty.parent; + if(ocode ==OMC_OCODE_READ) + { + len = pParent->childMsisdn[ptagcode][MAX_MSISDN_BLEN-1]; + if(len<3 || len>MAX_MSISDN_ALEN) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + BcdToAscii(valbuf,pParent->childMsisdn[ptagcode],MAX_MSISDN_ALEN); + valbuf[len] = 0; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + int tmp; + + tmp = getHowManyChildren(shmp); + + if(vallen == 0 && ocode == OMC_OCODE_EDIT) + { + if(pParent->childMsisdn[ptagcode][MAX_MSISDN_BLEN-1]>3) + { + decMasterChildren(shmp); + } + memset(pParent->childMsisdn[ptagcode],0,MAX_MSISDN_BLEN); + totalLen = add_null(tagbuf,0x80,asnbuf); + continue; + } + + if((vallen > MAX_MSISDN_ALEN || vallen<3 )&& vallen!=0) + { + sprintf((char *)pdata,"child number length(%d) error, should be(3-16)",vallen); + DebugMsg(debugmib.display.asciiOut, + "child number length(%d) error, should be(3-16)",vallen); + return -2; + } + + if(atoi((char *)pdata2)==0) + { + continue; + } + + for(i=0;i'9' || pdata2[i]<'0') + { + sprintf((char *)pdata,"Error child number"); + DebugMsg(debugmib.display.asciiOut,"Error child number"); + return -2; + } + } + + serviceControlItem = &ppsParam.ppsTables.cosTable[shmp->cos_id].serviceControl[0]; + if(!(serviceControlItem->poolAccountFlag)) + { + sprintf((char *)pdata,"pool account service not applied!"); + return -2; + } + + if(pParent->childMsisdn[ptagcode][MAX_MSISDN_BLEN-1]<2) + { + if(tmp != ptagcode) + { + sprintf((char *)pdata,"pool child must be added one by one!"); + return -2; + } + increMasterChildren(shmp); + } + + len = pParent->childMsisdn[ptagcode][MAX_MSISDN_BLEN-1]; + BcdToAscii(tmpBuf,pParent->childMsisdn[ptagcode],18); + StringCut(tmpBuf,'F'); + tmpBuf[len] = 0; + + if(strcmp(tmpBuf, (char *)pdata2)) + { + if(serviceControlItem->poolAccountChangeChargeFlag) + { + if(increMasterChangeCounter(shmp)> + serviceControlItem->poolAccountFreeChangeTimes) + { + portid = AssignProcID(0); + if(portid>=0 && portid< MAX_FSM_PROCESS) + { + stat_shmp = (_state_data *)&smshm_ptr->state_data; + stat_shmp += portid; + + stat_shmp->caller_info.head = head; + stat_shmp->caller_info.tail = tail; + + BillingChildNumberChange(stat_shmp); + SendPeriodicChargeCDR(head, + tail, + stat_shmp->caller_info.charge, + CT_PERIODIC_CHARGE); + ReleasePortStatus(portid); + } + } + } + }//strcmp + + AsciiToBcd(pParent->childMsisdn[ptagcode], (char *)pdata2,(vallen+1)/2*2); + pParent->childMsisdn[ptagcode][MAX_MSISDN_BLEN-1] = vallen; + if(vallen %2 ==0) + pParent->childMsisdn[ptagcode][vallen/2] = 0xFF; + else + pParent->childMsisdn[ptagcode][vallen/2] |= 0x0F; + + totalLen = add_tlv(tagbuf,vallen,pdata2,0x80,asnbuf); + } + break; + case 49: + pChild= &shmp->poolAccount.roleParty.child; + if(ocode==OMC_OCODE_READ) + { + len = pChild->parentMsisdn[MAX_MSISDN_BLEN-1]; + if(len<3 || len>MAX_MSISDN_ALEN) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + BcdToAscii(valbuf,pChild->parentMsisdn,MAX_MSISDN_ALEN); + valbuf[len] = 0; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(vallen == 0 && ocode == OMC_OCODE_EDIT) + { + memset(pChild->parentMsisdn,0,MAX_MSISDN_BLEN); + totalLen = add_null(tagbuf,0x80,asnbuf); + continue; + } + if((vallen > MAX_MSISDN_ALEN || vallen<3 )&& vallen!=0) + { + sprintf((char *)pdata,"parent number length(%d) error, should be(3-16)",vallen); + DebugMsg(debugmib.display.asciiOut, + "parent number length(%d) error, should be(3-16)",vallen); + return -2; + } + + if(atoi((char *)pdata2)==0) + { + continue; + } + + for(i=0;i'9' || pdata2[i]<'0') + { + sprintf((char *)pdata,"Error parent number"); + DebugMsg(debugmib.display.asciiOut,"Error parent number"); + return -2; + } + } + AsciiToBcd(pChild->parentMsisdn, (char *)pdata2,(vallen+1)/2*2); + pChild->parentMsisdn[MAX_MSISDN_BLEN-1] = vallen; + if(vallen %2 ==0) + pChild->parentMsisdn[vallen/2] = 0xFF; + else + pChild->parentMsisdn[vallen/2] |= 0x0F; + totalLen = add_tlv(tagbuf,vallen,pdata2,0x80,asnbuf); + } + break; + case 50: + pChild= &shmp->poolAccount.roleParty.child; + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,(int)pChild->callsToday,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + pChild->callsToday = tmpval; + totalLen = AddInteger(tagbuf,(int)pChild->callsToday,0x80,asnbuf); + } + break; + case 51: + pChild= &shmp->poolAccount.roleParty.child; + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,(int)pChild->smsToday,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + pChild->smsToday = tmpval; + totalLen = AddInteger(tagbuf,(int)pChild->smsToday,0x80,asnbuf); + } + break; + case 52: + pChild= &shmp->poolAccount.roleParty.child; + if(ocode==OMC_OCODE_READ) + { + balance = pChild->chargedToday; + totalLen = AddInteger(tagbuf,(int)balance,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + int int_val; + + if(GetInteger(tagbuf,&int_val ,pflag,asnbuf2)<=0) continue; + + pChild->chargedToday = (double)int_val; + totalLen = AddInteger(tagbuf,int_val,0x80,asnbuf); + } + break; + case 53:/* KB */ + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,(u32)((shmp->gprsVolume+BYTES_PER_KB-1) >> 10),0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->gprsVolume= (long)tmpval << 10; + totalLen = AddInteger(tagbuf,(u32)(shmp->gprsVolume>>10),0x80,asnbuf); + if (shmp->gprsVolume < 1) + { + shmp->cap_sms_notify_counter = 0; + } + } + break; + case 54: + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,(u32)shmp->gprsBalance,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>ppsParam.serviceControl.maxBalance) + { + sprintf((char *)pdata,"Too big value(%d),should be(0-%d)", + tmpval,ppsParam.serviceControl.maxBalance); + return -2; + } + shmp->gprsBalance= (double)tmpval; + totalLen = AddInteger(tagbuf,tmpval,0x80,asnbuf); + } + break; + case 55:/* KB */ + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,(u32)((shmp->gprsVolumeThisMonth+BYTES_PER_KB-1) >> 10),0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->gprsVolumeThisMonth = (long)tmpval << 10; + totalLen = AddInteger(tagbuf,(u32)(shmp->gprsVolumeThisMonth >> 10),0x80,asnbuf); + } + break; + case 56: + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->gprsNotificationTimes,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->gprsNotificationTimes= tmpval; + totalLen = AddInteger(tagbuf,shmp->gprsNotificationTimes,0x80,asnbuf); + } + break; + case 57: + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->callMeBackRequestTimes,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->callMeBackRequestTimes = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->callMeBackRequestTimes,0x80,asnbuf); + } + break; + case 58: + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->favorite_plan_id,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + if(tmpval>MAX_FAVORITE_PALN) + { + sprintf((char *)pdata,"Too big value(%d),should be(0-6)",tmpval); + return -2; + } + if(tmpval != shmp->favorite_plan_id ) + { + friendFamilyControl = &ppsParam.ppsTables.cosTable[shmp->cos_id].friendFamilyControl[0]; + + if(tmpval==0) + { + unsigned char bValue=0x01; + if(shmp->favorite_plan_id != 0) + { + shmp->rent_type ^= (bValue<<(friendFamilyControl->friendFamilyPlan[shmp->favorite_plan_id-1].rentID -1 )); + } + shmp->favorite_plan_state = 0; + shmp->free_favorite_call = 0; + shmp->free_favorite_sms = 0; + } + else + { + //if(friendFamilyControl->friendFamilyPlan[tmpval-1].rentCharge>0) + { + if(GetAccountBalance(head, tail)>=friendFamilyControl->friendFamilyPlan[tmpval-1].rentCharge) + { + unsigned char bValue=0x01; + if(shmp->favorite_plan_id != 0) + { + shmp->rent_type ^= (bValue<<(friendFamilyControl->friendFamilyPlan[shmp->favorite_plan_id-1].rentID -1 )); + } + + bValue = 0x01; + shmp->rent_type |= (bValue << (friendFamilyControl->friendFamilyPlan[tmpval-1].rentID-1)); + + portid = AssignProcID(0); + stat_shmp = (_state_data *)&smshm_ptr->state_data; + stat_shmp += portid; + + stat_shmp->caller_info.head = head; + stat_shmp->caller_info.tail = tail; + stat_shmp->caller_info.cos_id = shmp->cos_id; + stat_shmp->caller_info.charge = friendFamilyControl->friendFamilyPlan[tmpval-1].rentCharge; + + shmp->balance = shmp->balance -friendFamilyControl->friendFamilyPlan[tmpval-1].rentCharge; + shmp->free_favorite_call = 0; + shmp->free_favorite_sms = 0; + shmp->favorite_plan_state = 0; + + chargeFlag |= 0x04; + difbalance += -friendFamilyControl->friendFamilyPlan[tmpval-1].rentCharge; + + ReleasePortStatus(portid); + send_f_f_sms_flag = 1; + + } + else + { + if(ppsParam.ppsTables.cosTable[shmp->cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceReg) + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_REG_FAILED); + sprintf((char *)pdata,"Failed to provision Friends and Family service for account low balance"); + return -2; + } + } + } + } + shmp->favorite_plan_id = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->favorite_plan_id,0x80,asnbuf); + } + break; + case 59: + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->free_favorite_call,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->free_favorite_call= tmpval; + totalLen = AddInteger(tagbuf,shmp->free_favorite_call,0x80,asnbuf); + } + break; + case 60: + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->free_favorite_sms,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->free_favorite_sms= tmpval; + totalLen = AddInteger(tagbuf,shmp->free_favorite_sms,0x80,asnbuf); + } + break; + case 61: + if(ocode ==OMC_OCODE_READ) + { + totalLen = add_tlv(tagbuf,1,&shmp->favorite_plan_state,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->favorite_plan_state = tmpval; + totalLen = add_tlv(tagbuf,1,&shmp->favorite_plan_state,0x80,asnbuf); + } + break; + case 62: //bundle data + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,(u32)((shmp->bundle_info.data+BYTES_PER_KB-1) >> 10),0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->bundle_info.data = (long)tmpval << 10; + totalLen = AddInteger(tagbuf,(u32)(shmp->bundle_info.data >> 10),0x80,asnbuf); + } + + break; + case 63: //mo voice + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->bundle_info.mo_voice,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->bundle_info.mo_voice = tmpval; + totalLen = AddInteger(tagbuf,shmp->bundle_info.mo_voice,0x80,asnbuf); + } + break; + case 64: //mt voice + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->bundle_info.mt_voice,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->bundle_info.mt_voice = tmpval; + totalLen = AddInteger(tagbuf,shmp->bundle_info.mt_voice,0x80,asnbuf); + } + break; + case 65: //sms + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->bundle_info.sms,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->bundle_info.sms= tmpval; + totalLen = AddInteger(tagbuf,shmp->bundle_info.sms,0x80,asnbuf); + } + break; + case 66: //validity + if(ocode==OMC_OCODE_READ) + { + AsciiTime(buf,shmp->bundle_info.validity_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + }else if(ocode==OMC_OCODE_EDIT || ocode==OMC_OCODE_ADD) + { + BcdToAscii(buf,pdata2,vallen*2); + shmp->bundle_info.validity_date = MakeTime(NULL,buf); + AsciiTime(buf,shmp->bundle_info.validity_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + + break; + case 67: + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->bundle_info.warning_sms_flag,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->bundle_info.warning_sms_flag= tmpval; + totalLen = AddInteger(tagbuf,shmp->bundle_info.warning_sms_flag,0x80,asnbuf); + } + + break; + case 68: + if(ocode ==OMC_OCODE_READ) + { + totalLen = AddInteger(tagbuf,shmp->cap_sms_notify_counter,0x80,asnbuf); + } + else if(ocode==OMC_OCODE_EDIT || ocode ==OMC_OCODE_ADD) + { + if(GetInteger(tagbuf, (int *)&tmpval ,pflag,asnbuf2)<=0) continue; + shmp->cap_sms_notify_counter = tmpval; + totalLen = AddInteger(tagbuf,shmp->cap_sms_notify_counter, 0x80, asnbuf); + } + break; + default: + return 0; + break; + }//switch + }//for + + if(ocode==OMC_OCODE_READ) + { //read + datalen = totalLen; + } + else + { + if(ocode == OMC_OCODE_ADD) + { + store_index = AddPPSSubsData(shmp); + debugmib.watch_dog[7]++; + } + else + { + ModifyPPSSubsData(shmp); + } + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + + if(chargeFlag & 0x01) + { + SendOperatorRechargeCDR(head,tail,difbalance); + AccountLatchFlagCheck(head,tail); + } + if(chargeFlag & 0x02){ + SendOperatorRechargeCDR(head,tail,dif_promo_balance); + } + if(chargeFlag & 0x04) + { + SendPPSGeneralCDR(head, tail, difbalance, CT_FF_ACTIVATION); + } + if(chargeFlag & 0x08) + { + SendPPSGeneralCDR(head, tail, difbalance, CT_FF_NUMBER_EDIT); + } + if(chargeFlag > 0) + pps_real_update_user_file(head, tail); + + SendAccountRealSync(store_index,difbalance,dif_promo_balance,ocode); + if(send_f_f_sms_flag) + { + if(ppsParam.ppsTables.cosTable[shmp->cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceReg) + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_REG); + + } + } + + return totalLen; +} +/* ----------------+ Sync configuration data procedure end +---------------*/ + +int +DeleteSubscriberDataHead(int head) +{ + int i; + _prepaid_info *shmp=NULL; + _prepaid_data *shmp1=&ramshm_ptr->prepaid_data; + + PutLogFunID("DeleteSubscriberDataHead"); + + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][0]; + for(i=0;imsisdn[9] != 0 ) /*if whole segment buf ==0 then, clear the head*/ + { + return 0; + } + shmp ++; + } + shmp1->msisdn_head[head] = 0; + + return 1; +} + +void DebugMsgDelimiter() +{ + char buf[64]=""; + + sprintf(buf,"====================================================="); + DebugMsg(debugmib.display.asciiOut,"%s",buf); +} + +/*----------------------------------------*/ +int GetRamData(BYTE oidLen,DWORD *oid,BYTE *pdata,u_short dataLen) +{ + int totalLen=0,vallen=0; + int loop=0,ramMark,segno=0; + BYTE pdata1[1600],pdata2[1600],pflag; + u_short ptagcode; + char tagbuf[32],msisdnbuf[32]="",card_no[32]; + + ASN_BUF *asnbuf, asnbuf1; + ASN_BUF *asnbuf2, asnbuf3; + + PutLogFunID("GetRamData"); + + + memset(pdata1,0,dataLen+1); + memset(pdata2,0,dataLen+1); + + memcpy(pdata1,pdata,dataLen); + + asnbuf = &asnbuf1; + + AsnEncode(pdata,1600,asnbuf); + asnbuf2 = &asnbuf3; + + AsnDecode(pdata1, dataLen, UNIT_STORE_ACCOUNT, NULL, asnbuf2); + //BcdToAscii(buf,pdata1,dataLen*2); + //printf("dataLen:%d,data:%s\n",dataLen,buf); + + //if(oidLen<15) return 0; + ramMark = oid[12]; + + segno = oid[13]-1; + switch(ramMark) + { + case 0x01: /* MSISDN SEGMENT KEY */ + if(segno>=MSISDN_HEAD_NUM || segno<0 ) + { + return -1; + } + for(loop=1;loop<=UNIT_STORE_ACCOUNT;loop++) + { + sprintf(tagbuf,"-%d",loop); + if((vallen=GetAnyTLV(tagbuf,1600,pdata2,&pflag,&ptagcode,asnbuf2))<0) + { + break; + } + else + { + if(ptagcode<1 || ptagcode>UNIT_STORE_ACCOUNT) continue; + sprintf(tagbuf,"%d",ptagcode); + pdata2[vallen]=0; + + if(GetAccountInfoBySortIndex(segno*UNIT_STORE_ACCOUNT+ptagcode-1,msisdnbuf)) + { + totalLen = add_tlv(tagbuf,strlen(msisdnbuf), (u_char *)msisdnbuf,0x80,asnbuf); + } + else + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + + } + } + break; + case 0x03: /* prepaid card segment key */ + //DebugMsg(debugmib.display.asciiOut,"Get Prepaid Card : segment is:%d",segno); + + if(segno>=MAX_CARD_SEGMENT){ + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut,"Get Prepaid Card error: segment is too big:%d",segno); + return -1; + } + + for(loop=1;loop<=MAX_CARD_NUM_PSEG;loop++) + { + sprintf(tagbuf,"-%d",loop); + if((vallen=GetAnyTLV(tagbuf,1600,pdata2,&pflag,&ptagcode,asnbuf2))<0){ + break; + } + sprintf(tagbuf,"%d",ptagcode); + pdata2[vallen]=0; + if(ptagcode>0 && ptagcode <=MAX_CARD_NUM_PSEG ) + { + if(GetRechargeCardByIndex(segno*MAX_CARD_NUM_PSEG+ptagcode-1,card_no)) + { + totalLen = add_tlv(tagbuf,strlen(card_no), (u_char *)card_no,0x80,asnbuf); + } + else + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + } + } + break; + default: + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Get Ram data error: error oid[13]:%d",oid[13]); + return -1; + break; + } + if(totalLen==0){ + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Get Ram data error: return length=0 oid[14]:%d",oid[14]); + } + return totalLen; +} + +/* ---------------------------------------------------------- */ + + +int IsPromotionTime(COSTable *cosTableItem, struct timeval tvn) +{ + if(cosTableItem->tariff[0].promotionUseControl.rechargePromotionStartDate<=tvn.tv_sec + && + cosTableItem->tariff[0].promotionUseControl.rechargePromotionEndDate>=tvn.tv_sec) + { + return 1; + } + return 0; +} + +int GetPromotionAmount(COSTable *cosTableItem,int charge) +{ + int loop; + + for(loop=0;looprechargePromotion[loop].rechargeCardCredit) + return cosTableItem->rechargePromotion[loop].promotionBonus; + } + return 0; +} + +int GetPromotionDay(COSTable *cosTableItem,int charge) +{ + int loop; + for(loop=0;looprechargePromotion[loop].rechargeCardCredit) + return cosTableItem->rechargePromotion[loop].promotionValidity; + } + return 0; +} + +int IsMNPCalledNumber(char *number) +{ + int len=0,loop=0; + + if(ppsParam.serviceControl.support_mnp_flag==0) + return 0; + for(loop=0;loop32) return; + strcpy(smsDelimiter,delimiter); +} + + char realSentence[1024]=""; +char* ppsParseSentence(char *sentence,int varNum, char *varStr[]) +{ + char buf[128]={""},*ptr1,*ptr2; + + int length,tmplen=0,index=0,offset,loop=0; + + if(varNum<0 || varNum>8) return 0; + if(sentence == NULL) return 0; + length = strlen(sentence); + if(length==6) return 0; + + ptr1 = sentence; + memset(realSentence,0,1024); + loop = 0; + while(tmplen=7) + { + CleanPPSUSSDStatisticsByDay(); + } + + if(shmp->process_info.serviceKey<=0 || shmp->process_info.serviceKey>=5) + index = 4; //other + else + index = shmp->process_info.serviceKey - 1; + + debugmib.msgstatistics.ussd_operation[pps_week_index][index*2] ++; + debugmib.msgstatistics.ussd_operation[pps_week_index][index*2+1] += + shmp->process_info.duration / 2; + + debugmib.msgstatistics.ussd_operation[pps_week_index][10] ++; + debugmib.msgstatistics.ussd_operation[pps_week_index][11] += + shmp->process_info.duration / 2; + + return 1; +} + +int CleanPPSUSSDStatisticsByDay() +{ + char buf[32]; + + ppsGetWeekDay(); + + sprintf(buf,"%04d%02d%02d", GetTmYear(), GetTmMonth(), GetTmDay()); + AsciiToBcd((BYTE *)debugmib.msgstatistics.ussd_operation_date[pps_week_index],buf,8); + + memset(debugmib.msgstatistics.ussd_operation[pps_week_index], 0, sizeof(int) * 3 * 4); + return 0; +} + +int pps_sub_sync_test() +{ + static int test_instance = 0; + + int head = 0, tail = 0; + int balance = 10; + + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + _prepaid_info *sub_ptr = NULL; + + { + head = test_instance / UNIT_STORE_ACCOUNT; + tail = test_instance % UNIT_STORE_ACCOUNT; + + sub_ptr = &shmp->prepaid_info[head][tail]; + sub_ptr->balance = sub_ptr->balance - balance; + sub_ptr->promo_balance = sub_ptr->promo_balance- balance; + + SendAccountRealSync(test_instance, 0-balance, 0-balance, 2); + + } + + return 1; +} + +static char pps_smpp_caller[32]="123"; +static char pps_smpp_called[32]="123"; +int setPPSSmppNumber(char *number, int flag) +{ + if(flag == 0) + strcpy(pps_smpp_caller, number); + else + strcpy(pps_smpp_called, number); + return 1; +} + +int sendPPSTestShortMessage(char *message) +{ + int len = strlen(message); + + smppSendMOSM(pps_smpp_caller, pps_smpp_called, (u_char *)message, len, 0); + return 1; +} + +int get_not_change_transfer_expiry_date() +{ + return ppsParam.serviceControl.not_change_expiry_date_when_transfer; +} + +int get_transfer_status_normal_flag() +{ + return ppsParam.serviceControl.only_normal_can_transfer_balance; +} + +int get_transfer_resolution() +{ + return ppsParam.serviceControl.balance_transfer_resolution; +} + +int pps_get_max_call_duration_in_second() +{ + return (ppsParam.serviceControl.max_call_duration); +} + +int pps_get_gy_postpaid_flag( ) +{ + return ppsParam.serviceControl.gy_postpaid_flag; +} + +int pps_set_gy_delay_timer(int flag, int value) +{ + if(flag == 0) + ppsParam.serviceControl.gy_delay_timer0 = value; + else + ppsParam.serviceControl.gy_delay_timer1 = value; + return 1; +} + +int pps_get_gy_delay_timer(int flag) +{ + if(flag == 0) + return ppsParam.serviceControl.gy_delay_timer0; + else + return ppsParam.serviceControl.gy_delay_timer1; +} + +int ocs_set_threshold_supported(int flag) +{ + ppsParam.serviceControl.gy_not_support_threshold = flag; + return 1; +} + +int ocs_get_threshold_supported() +{ + if(ppsParam.serviceControl.gy_not_support_threshold == 0) + return 1; + else + return 0; +} + +int ocs_set_gy_report_data_method(int flag) +{ + ppsParam.serviceControl.gy_report_data_method = flag; + return 1; +} + +int ocs_get_gy_report_data_metohd() +{ + return ppsParam.serviceControl.gy_report_data_method; +} + +int pps_get_answer_timer_out() +{ + return ppsParam.serviceControl.answer_timer * CYCLE_STATE_INTERVAL; +} + +int pps_get_control_state() +{ + return debugmib.display.control_state; +} + +long pps_get_quota_per_request() +{ + if(pps_get_control_state()) + { + int FKB = (500 * 1024); + long max_quota = 0; + int state_timer ; + + state_timer = (tvnow.tv_sec - debugmib.display.control_state_ts) / 300 + 1; + if(state_timer > 9) state_timer = 9; + + max_quota = ppsParam.max_quota_per_request * 1024 * (10-state_timer) /10; + + if(max_quota < FKB) + max_quota = FKB; + + return max_quota; + } + else + return (ppsParam.max_quota_per_request * 1024);// read from ppsConf.txt, can be modified by command line set volume=x +} + +long pps_get_postpaid_quota_for_first_request() +{ + return (ppsParam.data_quota_as_postpaid * 1024);// read from ppsConf.txt, can be modified by command line set volume=x +} + +int pps_get_adaptor_flag() +{ + return ppsParam.scf_work_as_adaptor; +} + +int pps_get_adaptor_vcs_flag() +{ + return ppsParam.scf_work_as_adaptor_with_vcs; +} + +char *pps_get_smsc_addr() +{ + return ppsParam.serviceControl.smsc_addr; +} + +int pps_get_ucbc_number(char *ucbc_number) +{ + strcpy(ucbc_number, (char *)ppsParam.serviceControl.ucbc_number); + return 1; +} + +int pps_get_ocs_proxy_nai_flag() +{ + return ppsParam.serviceControl.nai_for_diameter_proxy; +} + +int pps_mt_play_voice_flag() +{ + return ppsParam.serviceControl.mt_play_voice_flag; +} + +int pps_mt_cdr_enable_flag() +{ + return ppsParam.serviceControl.mt_not_charged_for_cdr; +} + +int get_debug_log_flag(); +int pps_debug_info(char *app_name, char *str_to_show) +{ + if(get_debug_log_flag() == 0) + return 0; + + DebugMsg(debugmib.display.asciiOut, " ============= %s ==========\r\n", app_name); + + DebugMsg(debugmib.display.asciiOut, "%s",str_to_show); + + return 1; +} + +int get_debug_log_flag() +{ + return logMsgFlag; +} + +int pps_debug_flag_for_fd() +{ + return (logMsgFlag & 0xf7); +} + +void PrintCosServiceNumber(u8 cos_id, u8 type) +{ + COSTable *cos_ptr = NULL; + int i=0, srv_no_flag=0x0000; + char service_type_name[3][8]={"voice","sms","ussd"}; + char service_number_name[16][64]={ + "HotLine", + "Inquiry", + "Scratch Card Recharge", + "Credit Card Recharge", + "ThirdParty Recharge", + "Customer Care Center", + "Recharge", + "OPR", + "Virtual Calling Card", + "Palim Register", + "Pool Account Service", + "Credit Transfer Service", + "Free SMS Service", + "Call Me Back Service", + "Friend&Family", + "Tell Me My Number" + }; + + if(cos_id >= MaxCosTableItem) + { + DebugMsg(debugmib.display.asciiOut,"Invalid COS ID [%02d]",cos_id); + return; + } + + cos_ptr = &ppsParam.ppsTables.cosTable[cos_id]; + if(type == 0) + srv_no_flag = cos_ptr->serviceControl[0].serviceNumberFlag; + else if(type == 1) + srv_no_flag = cos_ptr->serviceControl[0].smsServiceFlag; + else if(type == 2) + srv_no_flag = cos_ptr->serviceControl[0].ussdServiceFlag; + + DebugMsg(debugmib.display.asciiOut,"Service Number of [%6s ] for COS [%02d]",service_type_name[type], cos_id); + + for(i=0;i<16;i++) + { + if(srv_no_flag & (0x0001 << i)) + { + DebugMsg(debugmib.display.asciiOut," %32s is enabled", service_number_name[i]); + } + else + { + DebugMsg(debugmib.display.asciiOut," %32s is disabled", service_number_name[i]); + } + } + +} + +int ConfigureDefaultSerivceNumber() +{ + int cos_id; + COSTable *cos_ptr=NULL; + + for(cos_id=0; cos_idserviceControl[0].serviceNumberFlag = 0xffff; + cos_ptr->serviceControl[0].smsServiceFlag = 0xffff; + cos_ptr->serviceControl[0].ussdServiceFlag = 0xffff; + } + + return 1; +} + +int ConfigureSerivceNumberPerCos(char *cmd, u8 type) +{ + char cvalue[128]; + int ivalue, len, i, len_valid=0, cos_pos=0, value_pos=0; + u8 cos_id=0; + COSTable *cos_ptr=NULL; + + len = strlen(cmd); + + if(type == 0) + { + len_valid = 34; + cos_pos = 15; + value_pos = 18; + } + else if(type == 1) + { + len_valid = 34; + cos_pos = 15; + value_pos = 18; + } + else if(type == 2) + { + len_valid = 35; + cos_pos = 16; + value_pos = 19; + } + + if(len != len_valid) + { + DebugMsg(debugmib.display.asciiOut,"wrong command len (%d-%d): use srv_no_cfg ivr xx 0000000000000000", len, len_valid); + return 0; + } + + memcpy(cvalue, &cmd[cos_pos], 2); + cvalue[2] = 0; + cos_id = atoi(cvalue); + if(cos_id >= MaxCosTableItem) + { + DebugMsg(debugmib.display.asciiOut,"wrong cos id %d, should be (0-%d)!", cos_id, MaxCosTableItem-1); + return 0; + } + + ivalue = 0x0000; + + for(i=value_pos;iserviceControl[0].serviceNumberFlag = ivalue; + else if(type== 1) + cos_ptr->serviceControl[0].smsServiceFlag = ivalue; + else if(type== 2) + cos_ptr->serviceControl[0].ussdServiceFlag = ivalue; + + SavePPSParam(); + PrintCosServiceNumber(cos_id, type); + + return 1; +} + +int GetSerivceNumberFlagPerCos(u8 cos_id, u8 service_type, u8 call_type) +{ + u8 retval = 0; + u8 right_cycle = service_type; + int flag_value=0; + + COSTable *cos_ptr=NULL; + + if(cos_id>=MaxCosTableItem || service_type>FriendFamilyPosition || call_type>2) + return retval; + + cos_ptr = &ppsParam.ppsTables.cosTable[cos_id]; + + if(call_type == 0) + flag_value = cos_ptr->serviceControl[0].serviceNumberFlag; + else if(call_type== 1) + flag_value = cos_ptr->serviceControl[0].smsServiceFlag; + else if(call_type== 2) + flag_value = cos_ptr->serviceControl[0].ussdServiceFlag; + if(service_type == FriendFamilyPosition) right_cycle = 14; + + retval = (flag_value >> right_cycle) & (0x0001); + + return retval; +} + +int pps_get_smpp_link_type() +{ + return ppsParam.serviceControl.smpp_over_tcp_flag; +} + +int ocs_get_calling_card_method() +{ + + return ppsParam.serviceControl.calling_card_method; +} + +int ocs_get_calling_card_cos_id() +{ + return ppsParam.serviceControl.calling_card_cos_id; + +} + +char *pps_get_service_number(unsigned int num_pos) +{ + char *ptr = NULL; + + if(num_pos < MAXServicePostion) + ptr = (char *)ppsParam.ppsTables.serviceNumber[num_pos].number; + + return ptr; +} + +char *ocs_get_crm_prefix_filename(char *ptr) +{ + if(ptr == NULL) + return NULL; + +// strcpy(ptr , ppsParam.ocs_crm_control.base_prefix_file_name); + strcpy(ptr, "/usr/local/agt/etc/tariff/prefix_table.txt"); + return ptr; +} + +int ocs_get_crm_prefix_call_type_method() +{ + return ppsParam.ocs_crm_control.crm_call_type.equal_or_contain; +} + +static char local_mobile_prefix_des[128][128]={"35","67235","0067235"}; +static char local_pstn_prefix_des[128][128]={"32","67232","0067232"}; +static int local_mobile_index=0, local_pstn_index=0; + +void ocs_get_crm_prefix_definition() +{ + char s[80],s1[80]; + int len; + unsigned char conf_state=0xFF; + FILE *fpConf; + char file_name[128]={"/usr/local/agt/etc/tariff/prefix_definition.txt"}; + + fpConf = fopen(file_name, "rb"); + + if(fpConf == NULL) + { + return ; + } + + strcpy(s,""); + strcpy(s1,""); + while(fgets(s,1024,fpConf) !=(char *)0) + { + if( (int *)strchr(s,'#') !=NULL) continue; + if( !strlen(s) ) continue; + len = strlen(s); + if(len < 2) continue; + + if(s[len-1] == 0x0d ||s[len-1] == 0x0a) + { + if(s[len-2] == 0x0d ||s[len-2] == 0x0a) + { + s[len-2] = 0; + len -= 2; + } + else + { + s[len-1] = 0; + len -= 1; + } + } + + if(strstr(s,"[local mobile]")) + { + conf_state = 0; + local_mobile_index = 0; + continue; + } + else if(strstr(s,"[local pstn]")) + { + conf_state = 1; + local_pstn_index = 0; + continue; + } + + switch(conf_state) + { + case 0: + if(local_mobile_index<128) + strcpy(local_mobile_prefix_des[local_mobile_index++], s); + break; + case 1: + if(local_pstn_index<128) + strcpy(local_pstn_prefix_des[local_pstn_index++], s); + break; + } + } + + fclose(fpConf); + +} + + +int ocs_get_crm_prefix_call_type_des(const char *prefix) +{ + int len,index; + + if(prefix == NULL) + return 0; + + for(index=0; index<=local_mobile_index; index++) + { + len = strlen(local_mobile_prefix_des[index]); + if(len<=0) continue; + if(strncasecmp(prefix, local_mobile_prefix_des[index],len) == 0) + return 0; //local mobile + } + + for(index=0; index<=local_pstn_index; index++) + { + len = strlen(local_pstn_prefix_des[index]); + if(len<=0) continue; + if(strncasecmp(prefix, local_pstn_prefix_des[index],len) == 0) + return 1;//local pstn + } + + return (index=4);//idd +} + +int ocs_get_call_type_by_des(const char *prefix) +{ + int index = 0; + //int match_method = ocs_get_crm_prefix_call_type_method(); + //char configured_des[128]; + + index = ocs_get_crm_prefix_call_type_des(prefix); + /* + for(index=0; index opr */ + +extern int CallingCardWaitingForSpecialResourceReport(_state_data *shmp); + +extern long AucGetRandSeed ( ); +int WaitingForSrfResponse(u_short portid,u8 operation); + +#define ONE_DAY (60*60*24) +#define TWO_DAY 2*ONE_DAY + +extern char masterFlag; + +enum opr_state +{ + opr_mng_keep_state, + opr_mng_exit +}; + +enum sub_state +{ + S_REC_OPR_CHECK_ACCOUNT_STATUS = 1, + S_REC_OPR_INPUT_PWD, + S_REC_OPR_CHECK_PWD, + S_REC_OPR_INPUT_IMEI, + S_WAIT_FOR_IMEI, + S_REC_OPR_INPUT_IMEI_AGAIN, + S_REGISTER_IMEI, + S_WAIT_PLAYREGISTER_COMPLTE, + S_CREATE_PPS, + S_REGISTER_DONE, + S_REC_OPR_REGISTER_COMPLETE, + + S_REC_OPR_SWITH_PROMT, + S_REC_OPR_SWITCH_KEY, + S_OPR_SWITCH_OPR_DOING, + S_OPR_SWITCH_ROAMING_DOING, + S_REC_OPR_REPLAY_OR_BACK, + S_REC_SWITCH_FAIL, + S_REC_OPR_SWITCH_FINISH, + + S_REC_OPR_ENQUIRE_KEY, + S_REC_OPR_ENQUIRE, + S_REC_OPR_ENQUIRE_COMPLETE, + + S_OPRREISTER, + S_OPRENQIRE, + S_OPRSWITCH +}; + +enum srf_response +{ + WAITFORIMEI = 0, + WAITFORMAINKEY , + WAITFORSWITCHKEY , + WAITFORENQUIREKEY , + WAITFORENDORBACKKEY +}; + +int IsOprNumber(char *number) +{ + int retval=0; + int len; + u_char *oprNumber; + + oprNumber = ppsParam.ppsTables.serviceNumber[OPRNumberPosition].number; + if(oprNumber[0] == 0) return 0; + len = strlen(oprNumber); + if(!strncasecmp(number,oprNumber,len)) + retval = 1; + + return retval; +} + +int handleReplayBackKey(u_short portid) +{ + int retval1 = opr_mng_keep_state,retval; + _state_data *shmp; + + PutLogFunID("handleReplayBackKey"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + retval = WaitingForSrfResponse(portid,WAITFORENDORBACKKEY); + switch(retval) + { + case 0: + break; + case 1: + switch(shmp->process_info.tmpDigits[0]) + { + case 11:/* to main menu */ + shmp->process_info.sub_state = 0; + break; + case 0: + default: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; /* max length of input digit */ + shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK; + break; + } + break; + default: + retval1 = opr_mng_exit; + break; + } + return retval1; +} + + +void SendMsisdnPrompt(u_short portid) +{ + int dlgid,invokeid=0,len; + u_char u_msisdn[12]; + char buf[32]; + CAP_Message cap_message; + CapArg capArg; + CapMessageID *pMID; + CapPlayAnnouncement *pPlayAnnouncement; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + PutLogFunID("SendMsisdnPrompt"); + + shmp += portid; + AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir); + + dlgid = shmp->context_info.dialogue_id; + + capArg.ocode = CAP_OC_PlayAnnouncement; + capArg.message_flag = REQUEST; + capArg.port_id = portid; + capArg.dialogue_id = dlgid; + capArg.invoke_id = invokeid; + capArg.version = shmp->context_info.acn_ver; + + pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg; + pPlayAnnouncement->optional_flag = 0x03; + pPlayAnnouncement->disconnectFromIPForbidden = 0x01; + pPlayAnnouncement->requestAnnouncementComplete = 0x01; + + pPlayAnnouncement->informationToSend.choice_id = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03; + /* review need 2003-10-08,user prefered language type not taken account */ + + pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID; + pMID->variableMessage.elementaryMessageID = + GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + + +shmp->process_info.voiceID; + + pMID->variableMessage.variableParts.num = 1; + + pMID->variableMessage.variableParts.variablePart[0].choice_id = 1; + strcpy(buf,shmp->process_info.tmpDigits); + len = strlen(buf); + if(len>18) len = 18; + ppsAsciiToBcdR(u_msisdn,buf,((len+1)/2)*2); + pMID->variableMessage.variableParts.variablePart[0].number[0] = (len+1)/2+1; + if(len%2==0) + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x04; + else + pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x24; + memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2], + u_msisdn, + (len+1)/2); + + pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07; + pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 1; + pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00; + pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; /* 1seconds */ + + StuffCapMessage(capArg,&cap_message); + WriteScfMsg(cap_message); + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + ppsDebugCapMsg(&cap_message,1); + debug_messages ++; + } +#endif +} + + +int SendMsisdnPromptToSrf(u_short portid) +{ + int len; + _state_data *shmp; + + PutLogFunID("SendMsisdnPromptToSrf"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + len = strlen(shmp->caller_info.number); + + shmp->process_info.voiceID = YOUR_NUMBER_IS; + memcpy(shmp->process_info.tmpDigits,shmp->caller_info.number,len); + shmp->process_info.tmpDigits[len]=0; + + SendMsisdnPrompt(portid); + return 1; +} + +int WaitingForSrfResponse(u_short portid,u8 operation) +{ + int retval = 0,dlgid,msglen,key,len; + CAP_Message capmsg; + CapArg capArg; + CapPromptAndCollectUserInformation *pPCUI; + + _state_data *shmp; + + PutLogFunID("WaitingForFavoriteNumberAddConfirmResponse"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + dlgid = shmp->context_info.dialogue_id; + + if(!ReadScfMsg(&capmsg,dlgid)) + { + return retval; + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + debug_messages ++; + ppsDebugCapMsg(&capmsg,0); + } +#endif + + switch(capmsg.msgOperaCode) + { + case CAP_OC_PromptAndCollectUserInformation: + AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir); + shmp->process_info.funnel = 0; + msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + capArg.version = shmp->context_info.acn_ver; + if(decode_capmsg(&capmsg.msgContent[5], + msglen, + capmsg.msgOperaCode, + CAP_CONFIRM, + &capArg)<0) + { + return (retval=4); + } + pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg; + len = pPCUI->digitsResponse[0]; + switch(operation) + { + case WAITFORIMEI: + if((len - 1) != IMEI_LEN) + { + if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM) + { + return (retval = 3); + } + return (retval = 2); + } + if(pPCUI->digitsResponse[1] & 0x20) + { + pPCUI->digitsResponse[len] |=0xF0; + } + + ppsBcdToAsciiR(shmp->process_info.tmpDigits, + &pPCUI->digitsResponse[2], + 2*(len-1)); + retval = 1; + break; + case WAITFORMAINKEY: + case WAITFORSWITCHKEY: + case WAITFORENQUIREKEY: + case WAITFORENDORBACKKEY: + key = pPCUI->digitsResponse[2]; + switch(operation) + { + case WAITFORMAINKEY: + //if(((key >= 0 && key <= 3))||(key == 11)) + { + shmp->process_info.tmpDigits[0] = key; + retval = 1; + } + break; + case WAITFORSWITCHKEY: + case WAITFORENQUIREKEY: + //if((key >= 0 && key <= 2)||(key == 11)) + { + shmp->process_info.tmpDigits[0] = key; + retval = 1; + } + break; + case WAITFORENDORBACKKEY: + //if(key == 0 || key == 11) + { + shmp->process_info.tmpDigits[0] = key; + retval = 1; + } + break; + } + } + break; + case CAP_O_UABORT: + case CAP_O_PABORT: + default: + retval = 4; + break; + } + return retval; +} + +static int SMLCIReister(FixSMLCICommand *cmdLine,FixSMLCIResult *resultLine) +{ + _state_data *shmp; + int causeCode,result; + long expired_date; + u_short portid; + + PutLogFunID("FixSMLCIReister"); + + if(logMsgFlag == DEBUG_ALL) + DebugMsg(debugmib.display.asciiOut, + "\33[33m PPS SMLCI Reister OPR service\33[0m"); + + portid = AssignProcID(0); + if(portid < 0 || portid >= MAX_FSM_PROCESS) + { + causeCode = ReturnOprCantAssignProc; + resultLine->result = OPRFAIL; + DetermineCause(causeCode,resultLine->cause); + if(logMsgFlag & DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "\33[31m SMLCI Reister Fail:PPS can't assign proc\33[0m"); + return -1; + } + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + causeCode = RechargeCardRequest(portid,cmdLine->prepaidPwd, &result); + if(causeCode != 1)/* cardPwd has problem */ + { + resultLine->result = OPRFAIL; + DetermineCause(causeCode,resultLine->cause); + if(logMsgFlag & DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "\33[31m SMLCI Reister Fail:Recharge Card problem:%s\33[0m",resultLine->cause); + ReleasePortStatus(portid); + return -1; + } + memcpy(shmp->process_info.tmpDigits,cmdLine->imei,IMEI_IMSI_ASCII_LEN); + causeCode = FixSMCLIRegisterOPR(shmp,resultLine->pin); + if(causeCode < 0) + { + resultLine->result = OPRFAIL; + DetermineCause(causeCode,resultLine->cause); + if(logMsgFlag & DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "\33[31m SMLCI Reister Fail:Opr register problem:%s\33[0m",resultLine->cause); + ReleasePortStatus(portid); + return -1; + } + memcpy(resultLine->msisdn,shmp->caller_info.number,MAX_MSISDN_ALEN+1); + RechargeRequestProc(portid); + sprintf(resultLine->balance,"%32ld",(long)GetBalance(&shmp->caller_info)); + expired_date = GetExpiration(&shmp->caller_info); + AsciiTime(resultLine->expire_date,expired_date); + if(logMsgFlag == DEBUG_ALL) + DebugMsg(debugmib.display.asciiOut, + "\33[33m SMLCI Reister success,msisdn:%s,pin:%s,balance:%ld,expireDate:%s\33[0m" + ,resultLine->msisdn,resultLine->pin,resultLine->balance,resultLine->expire_date); + ReleasePortStatus(portid); + return 1; +} +int OMCReisterCommand(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen) +{ + int i,vallen,totalLen; + int loop=0; + BYTE pdata1[1600],pdata2[1600],pflag; + u_short ptagcode; + char tagbuf[32]; + ASN_BUF *asnbuf, asnbuf1; + ASN_BUF *asnbuf2, asnbuf3; + + FixSMLCICommand cmdLine; + FixSMLCIResult resultLine; + u8 resultSize; + + PutLogFunID("OMCReisterCommand"); + + memset(pdata1,0,datalen+1); + memcpy(pdata1,pdata,datalen); + pdata1[datalen]=0; + + asnbuf = &asnbuf1; + + AsnEncode(pdata,1600,asnbuf); + asnbuf2 = &asnbuf3; + + AsnDecode(pdata1, datalen, UNIT_STORE_ACCOUNT, NULL, asnbuf2); + + resultSize = sizeof(FixSMLCIResult); + memset(&cmdLine,0,sizeof(FixSMLCICommand)); + memset(&resultLine,0,resultSize); + for(loop=1;loop<3;loop++) + { + sprintf(tagbuf,"-%d",loop); + if((vallen=GetAnyTLV(tagbuf,1024,pdata2,&pflag,&ptagcode,asnbuf2))<0){ + break; + } + sprintf(tagbuf,"%d",ptagcode); + pdata2[vallen]=0; + + switch(ptagcode) + { + case 0x01://imei + if(vallen == 0) + { + resultLine.result = OPRFAIL; + memcpy(resultLine.cause,"IMEI length error",32); + if(logMsgFlag == DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "\33[31m IMEI length error,can't be NULL\33[0m"); + break; + } + if(vallen != IMEI_IMSI_ASCII_LEN) + { + resultLine.result = OPRFAIL; + memcpy(resultLine.cause,"IMEI length error",32); + if(logMsgFlag == DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "\33[31m IMEI length error,must be %d\33[0m",IMEI_IMSI_ASCII_LEN); + break; + } + for(i=0;i'9' || pdata2[i]<'0') + { + resultLine.result = OPRFAIL; + memcpy(resultLine.cause,"Error IMEI,not digit",32); + if(logMsgFlag == DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "\33[31m %s:%s \33[0m",resultLine.cause,pdata2); + break; + } + } + if(i >= vallen) + { + memcpy(cmdLine.imei,pdata2,vallen); + cmdLine.imei[vallen] = 0; + } + break; + case 0x02://prepaid card password + for(i=0;i'9' || pdata2[i]<'0') + { + resultLine.result = OPRFAIL; + memcpy(resultLine.cause,"Error prepaid card password,not digit",32); + if(logMsgFlag == DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "\33[31m %s:%s\33[0m",resultLine.cause,pdata2); + break; + } + } + if(i >= vallen) + { + memcpy(cmdLine.prepaidPwd,pdata2,vallen); + cmdLine.prepaidPwd[vallen] = 0; + } + break; + }//switch + }//for + SMLCIReister(&cmdLine,&resultLine); + for(i=1;i<=8;i++) + { + sprintf(tagbuf,"-%d",i); + if((vallen=GetAnyTLV(tagbuf,1024,pdata2,&pflag,&ptagcode,asnbuf2))<0){ + break; + } + sprintf(tagbuf,"%d",ptagcode); + switch(ptagcode) + { + case 1:/* imei */ + totalLen = add_tlv(tagbuf,IMEI_IMSI_ASCII_LEN,cmdLine.imei,0x80,asnbuf); + break; + case 2:/* prepaid card password */ + totalLen = add_tlv(tagbuf,strlen(cmdLine.prepaidPwd),cmdLine.prepaidPwd,0x80,asnbuf); + break; + case 3:/* result */ + { + u_char tmp[16]; + memset(tmp,0,16); + if(resultLine.result == OPRFAIL) + memcpy(tmp,"Fail",4); + else + memcpy(tmp,"Success",7); + totalLen = add_tlv(tagbuf,strlen(tmp),tmp,0x80,asnbuf); + } + break; + case 4:/* msisdn */ + if(resultLine.result == OPRFAIL) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + totalLen = add_tlv(tagbuf,strlen(resultLine.msisdn),resultLine.msisdn,0x80,asnbuf); + } + break; + case 5:/* pin */ + if(resultLine.result == OPRFAIL) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + totalLen = add_tlv(tagbuf,strlen(resultLine.pin),resultLine.pin,0x80,asnbuf); + } + break; + case 6:/* balance */ + if(resultLine.result == OPRFAIL) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + totalLen = add_tlv(tagbuf,strlen(resultLine.balance),resultLine.balance,0x80,asnbuf); + } + break; + case 7:/* expire date */ + if(resultLine.result == OPRFAIL) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + totalLen = add_tlv(tagbuf,strlen(resultLine.expire_date),resultLine.expire_date,0x80,asnbuf); + } + break; + case 8:/* fail cause */ + if(resultLine.result == OPRSUCCESS) + { + totalLen = add_null(tagbuf,0x80,asnbuf); + } + else + { + totalLen = add_tlv(tagbuf,strlen(resultLine.cause),resultLine.cause,0x80,asnbuf); + } + break; + } + } + return totalLen; +} + +int ppsRegisterOprUser(u_short portid) +{ + int retval,retval1 = opr_mng_keep_state,result; + _state_data *shmp; + u8 imsi[24],*tmpimsi; + PPS_REGISTER_OPR_WITH_IMEI mapContent; + OPR_CREATE_PPS_USER mapContentCreatePps; + int caller_status; + + PutLogFunID("RegisterProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = rec_mng_keep_state; + + switch(shmp->process_info.sub_state_2) + { + case S_REC_OPR_CHECK_ACCOUNT_STATUS: + if( xappCheckIfLocalMSISDN(shmp->caller_info.number) == 1)/* local msisdn */ + { + shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE; + break; + } + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = S_REC_OPR_INPUT_PWD; + break; + case S_REC_OPR_INPUT_PWD: + shmp->process_info.funnel = 0; + shmp->process_info.voiceID = INPUT_PRECARD_PWD; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + shmp->process_info.maxPCUInfoLen = 20; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_CHECK_PWD; + break; + case S_REC_OPR_CHECK_PWD: + retval = WaitingForRechargeCardPasswordResponse(portid); + switch(retval) + { + case 0: + break; + case 1: + shmp->process_info.sub_state_2 = S_REC_OPR_INPUT_IMEI; + shmp->process_info.count = 0; + break; + case 2: + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = REGISTER_OPR_FAIL_PWD_ERROR; + shmp->process_info.maxPCUInfoLen = 20; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state_2 = S_REC_OPR_CHECK_PWD; + break; + case 3: + retval1 = opr_mng_exit; + break; + } + break; + case S_REC_OPR_INPUT_IMEI: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = INPUT_MOBILE_IMEI; + shmp->process_info.endOfReplyDigit[0] = 1; + shmp->process_info.endOfReplyDigit[1] = 12; + shmp->process_info.maxPCUInfoLen = MAX_ASCII_NUMBER_LEN; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_WAIT_FOR_IMEI; + shmp->process_info.count = 0; + break; + case S_WAIT_FOR_IMEI: + retval = WaitingForSrfResponse(portid,WAITFORIMEI); + switch(retval) + { + case 0: + break; + case 1:/* successful inputed imei */ + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = IMEI_IMSI_ASCII_LEN; + if(shmp->process_info.count == 0) + { + shmp->process_info.count++; + shmp->process_info.voiceID = INPUT_MOBILE_IMEI_AGAIN; + shmp->process_info.sub_state_2 = S_REC_OPR_INPUT_IMEI_AGAIN; + SendPromptAndCollectUserInfo(portid); + break; + } + else + { + shmp->process_info.count = 0; + if(memcmp(shmp->process_info.routing_number,shmp->process_info.tmpDigits,IMEI_IMSI_ASCII_LEN) == 0) + { + shmp->process_info.sub_state_2 = S_REGISTER_IMEI; + break; + } + else + { + shmp->process_info.voiceID = IMEI_REGISTER_FAIL_IMEI_NOT_SAME; + shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE; + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + break; + } + } + break; + case 2: + shmp->process_info.count = 0; + shmp->process_info.srfRelease = 0; + shmp->process_info.voiceID = REGISTER_OPR_IMEI_ERROR; + shmp->process_info.maxPCUInfoLen = MAX_ASCII_NUMBER_LEN; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state_2 = S_WAIT_FOR_IMEI; + break; + case 3: + retval1 = opr_mng_exit; + break; + } + break; + case S_REC_OPR_INPUT_IMEI_AGAIN: + memset(shmp->process_info.routing_number,0,18); + memcpy(shmp->process_info.routing_number,shmp->process_info.tmpDigits,strlen(shmp->process_info.tmpDigits)); + memset(shmp->process_info.tmpDigits,0,MAX_ASCII_NUMBER_LEN); + shmp->process_info.sub_state_2 = S_WAIT_FOR_IMEI; + break; + case S_REGISTER_IMEI:/* invoke opr */ + if(shmp->caller_info.IMSI[0] == 0)/* Fix register OPR service */ + { + _account_info tmpInfo; + + memcpy(&tmpInfo,&shmp->caller_info,sizeof(_account_info)); + + shmp->process_info.rechargeByOther = 1; + tmpimsi = NULL; + + shmp->process_info.tmpDigits[strlen(shmp->process_info.tmpDigits)] = 0; + shmp->process_info.sub_state_2 = S_REGISTER_DONE; + shmp->process_info.oc = C_FIX_REGISTER_DONE; + shmp->process_info.u_error = OPRSUCCESS; + + result = FixSMCLIRegisterOPR(shmp,mapContentCreatePps.pin); + if(result<0) + { + shmp->process_info.u_error = OPRFAIL; + } + else + { + memcpy(&shmp->recharge_info,&shmp->caller_info,sizeof(_account_info)); + } + memcpy(&shmp->caller_info,&tmpInfo,sizeof(_account_info)); + } + else /* MS register OPR service for itself */ + { + shmp->process_info.rechargeByOther = 0; + ppsBcdToAsciiR(imsi,shmp->caller_info.IMSI,IMEI_IMSI_ASCII_LEN+1); + StringCut(imsi,'F'); + if(strlen(imsi) != IMEI_IMSI_ASCII_LEN) + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m[portid:%d]Pps REGISTER IMEI fail,imsi length error,! = 15\33[0m(%ld.%ld)", + portid,tvnow.tv_sec,tvnow.tv_usec); + + memcpy(mapContent.imei,shmp->process_info.tmpDigits,strlen(shmp->process_info.tmpDigits)); + memcpy(mapContent.imsi,imsi,IMEI_IMSI_ASCII_LEN); + result = mapMsgSendToOpr(PPS_REGISTER_OPR_WITH_IMEI_REQ,portid,-1, + (BYTE *)&mapContent,sizeof(PPS_REGISTER_OPR_WITH_IMEI)); + if(result > 0) + { + shmp->process_info.voiceID = IMEI_REGISTERING; + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_WAIT_PLAYREGISTER_COMPLTE; + } + else + { + shmp->process_info.voiceID = IMEI_REGISTER_FAIL; + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE; + } + } + break; + case S_WAIT_PLAYREGISTER_COMPLTE: + result = CallingCardWaitingForSpecialResourceReport(shmp); + if(result == pin_mng_keep_state) + break; + else if(result == 1) + { + shmp->process_info.sub_state_2 = S_CREATE_PPS; + } + else + retval1 = opr_mng_exit; + break; + case S_CREATE_PPS: + if(shmp->process_info.oc != C_CREATE_PPS + && shmp->process_info.oc != C_MS_REGISTER_DONE) + break; + + if(shmp->process_info.oc == C_CREATE_PPS) + { + shmp->process_info.oc = 0; + result = CreatePPsUserForOpr(shmp,mapContentCreatePps.pin); + mapContentCreatePps.result = result?OPRSUCCESS:OPRFAIL; + result = mapMsgSendToOpr(OPR_CREATE_PPS_USER_RES,portid,shmp->process_info.correlationID, + (BYTE *)&mapContentCreatePps,sizeof(OPR_CREATE_PPS_USER)); + shmp->process_info.sub_state_2 = S_REGISTER_DONE; + if(mapContentCreatePps.result == OPRFAIL) + { + shmp->process_info.oc = C_MS_REGISTER_DONE; + shmp->process_info.u_error = OPRFAIL; + } + else/* only success */ + break; + } + else + { + shmp->process_info.sub_state_2 = S_REGISTER_DONE; + } + case S_REGISTER_DONE: + if(shmp->process_info.oc != C_MS_REGISTER_DONE && + shmp->process_info.oc != C_FIX_REGISTER_DONE) + break; + shmp->process_info.oc = 0; + result =shmp->process_info.u_error; + if(result == OPRSUCCESS) + { + if(shmp->process_info.oc == C_MS_REGISTER_DONE) + shmp->process_info.voiceID = MS_REGISTER_SUCCESS; + else + shmp->process_info.voiceID = FIX_REGISTER_SUCCESS; + RechargeRequestProc(portid); + } + else + { + shmp->process_info.voiceID = IMEI_REGISTER_FAIL; + } + shmp->process_info.funnel = 0; + shmp->process_info.srfRelease = 0; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE; + break; + case S_REC_OPR_REGISTER_COMPLETE: + result = CallingCardWaitingForSpecialResourceReport(shmp); + if(result == pin_mng_keep_state) + break; + else if(result == 1) + { + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; /* max length of input digit */ + shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK; + } + else + retval1 = opr_mng_exit; + case S_REC_OPR_REPLAY_OR_BACK: + retval1 = handleReplayBackKey(portid); + break; + default: + break; + } + return retval1; +} + + + +int ppsCreateOprUser(u_short portid) +{ + + return 1; +} + +int ppsInqueryOprUser(u_short portid) +{ + u8 retval,retval1= opr_mng_keep_state; + _state_data *shmp; + int status,result; + + PutLogFunID("ppsInqueryOprUser"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(shmp->process_info.sub_state_2) + { + case S_REC_OPR_ENQUIRE:/* send inquery promt */ + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = INPUT_INQUERY_KEY; + shmp->process_info.maxPCUInfoLen = 1; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_KEY; + break; + case S_REC_OPR_ENQUIRE_KEY: + retval = WaitingForSrfResponse(portid,WAITFORENQUIREKEY); + switch(retval) + { + case 0: + break; + case 1: + status = ReportUserStatusByImsiBcd(shmp->caller_info.IMSI); + /* + OprWithOutRoamAgreement_OPRState, + OprWithRoamAgreeement_OPRState, + OprWithRoamAgreeement_RoamingState, + */ + if(status != OprWithOutRoamAgreement_OPRState + && status != OprWithRoamAgreeement_OPRState + && status != OprWithRoamAgreeement_RoamingState) + { + shmp->process_info.voiceID = NOT_REGISTER_STATUS; + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_COMPLETE; + SendSrfPlayAnnouncement(portid); + break; + } + + switch(shmp->process_info.tmpDigits[0]) + { + case 1:/* inquery msisdn*/ + SendMsisdnPromptToSrf(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_COMPLETE; + break; + case 2:/* inquery status:opr state or roaming state */ + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; + if(status == OprWithOutRoamAgreement_OPRState + || status == OprWithRoamAgreeement_OPRState) + shmp->process_info.voiceID = OPR_STATUS; + else if(status == OprWithRoamAgreeement_RoamingState) + shmp->process_info.voiceID = ROAMING_STATUS; + else + shmp->process_info.voiceID = NOT_REGISTER_STATUS; + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_COMPLETE; + break; + case 11:/* '*' back to */ + shmp->process_info.sub_state = 0; + break; + case 0:/* replay */ + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE; + break; + default: + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE; + break; + } + break; + case 2: + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE; + break; + case 3: + default: + retval1 = opr_mng_exit; + break; + } + break; + case S_REC_OPR_ENQUIRE_COMPLETE: + result = CallingCardWaitingForSpecialResourceReport(shmp); + if(result == pin_mng_keep_state) + break; + else if(result == 1) + { + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; /* max length of input digit */ + shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK; + } + else + retval1 = opr_mng_exit; + break; + case S_REC_OPR_REPLAY_OR_BACK: + retval1 = handleReplayBackKey(portid); + break; + default: + retval1 = opr_mng_exit; + break; + } + return retval1; +} + +int ppsSwtichOprUser(u_short portid) +{ + int retval,retval1 = opr_mng_keep_state,result; + _state_data *shmp; + PPS_SWITCH_OPR mapContent; + int status; + + PutLogFunID("ppsSwtichOprUser"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + switch(shmp->process_info.sub_state_2) + { + case S_REC_OPR_SWITH_PROMT:/* send switch promt */ + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; + + status = ReportUserStatusByImsiBcd(shmp->caller_info.IMSI); + if(status != OprWithOutRoamAgreement_OPRState + && status != OprWithRoamAgreeement_OPRState + && status != OprWithRoamAgreeement_RoamingState)/* not registered */ + { + shmp->process_info.voiceID = NOT_REGISTER_STATUS; + shmp->process_info.sub_state_2 = S_REC_SWITCH_FAIL; + break; + } + + shmp->process_info.voiceID = INPUT_SWITCH_KEY; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_KEY; + break; + case S_REC_OPR_SWITCH_KEY: + retval = WaitingForSrfResponse(portid,WAITFORSWITCHKEY); + switch(retval) + { + case 0: + break; + case 1: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; /* max length of input digit */ + switch(shmp->process_info.tmpDigits[0]) + { + case 1:/* swith to opr state */ + memcpy(mapContent.imsi,shmp->caller_info.IMSI,8); + mapContent.key = 1; + result = mapMsgSendToOpr(PPS_SWITCH_OPR_REQ,portid,-1, + (BYTE *)&mapContent,sizeof(PPS_SWITCH_OPR)); + if(retval > 0) + shmp->process_info.sub_state_2 = S_OPR_SWITCH_OPR_DOING; + else + { + shmp->process_info.sub_state_2 = S_REC_SWITCH_FAIL; + shmp->process_info.voiceID = INPUT_SWITCH_TO_OPR_FAIL; + } + break; + case 2:/* switch to roaming state */ + memcpy(mapContent.imsi,shmp->caller_info.IMSI,8); + mapContent.key = 2; + result = mapMsgSendToOpr(PPS_SWITCH_OPR_REQ,portid,-1, + (BYTE *)&mapContent,sizeof(PPS_SWITCH_OPR)); + if(retval > 0) + shmp->process_info.sub_state_2 = S_OPR_SWITCH_ROAMING_DOING; + else + { + shmp->process_info.sub_state_2 = S_REC_SWITCH_FAIL; + shmp->process_info.voiceID = INPUT_SWITCH_TO_ROAMING_FAIL; + } + break; + case 11:/* back to */ + shmp->process_info.sub_state = 0; + break; + case 0:/* replay */ + shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT; + break; + default: + shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT; + break; + } + break; + case 2: + shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT; + break; + case 3: + default: + retval1 = opr_mng_exit; + break; + } + break; + case S_OPR_SWITCH_OPR_DOING: + if(shmp->process_info.oc != C_SWITCH_DONE) + break; + result = shmp->process_info.u_error; + if(result == OPRSUCCESS) /* switch success,but vlr not do location update */ + { + shmp->process_info.voiceID = INPUT_SWITCH_TO_OPR_SUCCESS; + } + else /* switch fail */ + { + shmp->process_info.voiceID = INPUT_SWITCH_TO_OPR_FAIL; + } + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_FINISH; + break; + case S_OPR_SWITCH_ROAMING_DOING: + if(shmp->process_info.oc != C_SWITCH_DONE) + break; + result = shmp->process_info.u_error; + if(result == OPRSUCCESS) /* switch success,but vlr not do location update */ + { + shmp->process_info.voiceID = INPUT_SWITCH_TO_ROAMING_SUCCESS; + } + else /* switch fail */ + { + shmp->process_info.voiceID = INPUT_SWITCH_TO_ROAMING_FAIL; + } + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_FINISH; + break; + case S_REC_SWITCH_FAIL: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; /* max length of input digit */ + SendSrfPlayAnnouncement(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_FINISH; + break; + case S_REC_OPR_SWITCH_FINISH: + shmp->process_info.oc = 0; + shmp->process_info.u_error = 0; + result = CallingCardWaitingForSpecialResourceReport(shmp); + if(result == pin_mng_keep_state) + break; + else if(result == 1) + { + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.maxPCUInfoLen = 1; /* max length of input digit */ + shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK; + SendPromptAndCollectUserInfo(portid); + shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK; + } + else + retval1 = opr_mng_exit; + break; + case S_REC_OPR_REPLAY_OR_BACK: + retval1 = handleReplayBackKey(portid); + break; + default: + retval1 = opr_mng_exit; + break; + } + return retval1; +} + + +int OprManagementProc(u_short portid) +{ + u8 retval,retval1 = opr_mng_keep_state; + _state_data *shmp; + + PutLogFunID("OprManagementProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER) + return (retval = opr_mng_exit); + if(shmp->process_info.disconnectForwardConnection == 1) + { + SendScfTcEND(portid); + return (retval = opr_mng_exit); + } + + switch(shmp->process_info.sub_state) + { + case 0: + shmp->process_info.funnel = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.voiceID = OPR_SERVICE_SELECT_PROMPT; + shmp->process_info.maxPCUInfoLen = 1; + shmp->process_info.sub_state = 1; + SendPromptAndCollectUserInfo(portid); + break; + case 1: + retval = WaitingForSrfResponse(portid,WAITFORMAINKEY); + switch(retval) + { + case 0: + break; + case 1: + switch(shmp->process_info.tmpDigits[0]) + { + case 1: /* register */ + shmp->process_info.sub_state = S_OPRREISTER; + shmp->process_info.sub_state_2 = S_REC_OPR_CHECK_ACCOUNT_STATUS; + break; + case 2: /* inquery */ + shmp->process_info.sub_state = S_OPRENQIRE; + shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE; + break; + case 3: /* switch */ + shmp->process_info.sub_state = S_OPRSWITCH; + shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT; + break; + case 0: /* replay */ + shmp->process_info.sub_state = 0; + break; + case 11: /* '*' exit */ + retval1 = opr_mng_exit; + break; + default: + shmp->process_info.sub_state = 0; + break; + } + break; + case 2: + shmp->process_info.sub_state = 0; + break; + case 3: + default: + retval1 = opr_mng_exit; + break; + } + break; + case S_OPRREISTER: + retval1 = ppsRegisterOprUser(portid); + break; + case S_OPRENQIRE: + retval1 = ppsInqueryOprUser(portid); + break; + case S_OPRSWITCH: + retval1 = ppsSwtichOprUser(portid); + break; + default: + retval1 = opr_mng_exit; + break; + } + return retval1; +} + + +void getRandomPin(char *pin) +{ + long long rand_num; + char tmp[32]={0}; + char opr_state[256]={0}; + + initstate ( AucGetRandSeed ( ), opr_state, 256 ); + setstate ( opr_state ); + srandom ( AucGetRandSeed ( ) ); + rand_num = random ( ); + sprintf(tmp,"%lld",rand_num); + memcpy(pin,tmp,6); +} + +BYTE CreatePPsUserForOpr(_state_data *shmpq,u_char *pin)/*opr-> pps */ +{ + int store_index,len; + _prepaid_info shmp; + BYTE *msisdn; + + msisdn = shmpq->caller_info.number; + len = msisdn[MAX_MSISDN_ALEN]; + if(len>MAX_MSISDN_ALEN || len=0 && store_index= 0) + { + GetAccountPos(&shmpq->caller_info); + if(logMsgFlag == DEBUG_ALL) + DebugMsg(debugmib.display.asciiOut, + "Opr receive create pps subscriber %s success! (%ld.%ld)", + msisdn,tvnow.tv_sec,tvnow.tv_usec); + } + else + { + if(logMsgFlag & DEBUG_ERROR) + DebugMsg(debugmib.display.asciiOut, + "Opr receive create pps subscriber %s fail! (%ld.%ld)", + msisdn,tvnow.tv_sec,tvnow.tv_usec); + return 0; + } + SendAccountRealSync(store_index,0.0,0.0,3); + return 1; +} + +void PpsDelete_OPRTRAIL_Account() +{ + static u_long PpsDelete_OPRTRAIL_Account_instance = 0;; + _prepaid_info *shmp; + u_long i,j,loop,Account_instance; + + if( !masterFlag ) + return; + + if(!IsDeleteOprTrailAccount()) + return; + for(loop = 0;loop < 10;loop++) + { + if(PpsDelete_OPRTRAIL_Account_instance >=MSISDN_HEAD_NUM*UNIT_STORE_ACCOUNT ) + PpsDelete_OPRTRAIL_Account_instance = 0; + i=PpsDelete_OPRTRAIL_Account_instance/UNIT_STORE_ACCOUNT; + j=PpsDelete_OPRTRAIL_Account_instance%UNIT_STORE_ACCOUNT; + shmp = &ramshm_ptr->prepaid_data.prepaid_info[i][j]; + Account_instance = PpsDelete_OPRTRAIL_Account_instance++; + if(shmp->status != T_OPRTRIAL) + continue; + if(PPSDeleteOprAccountUser(shmp->msisdn,0)) + { + SendAccountRealSync(Account_instance,0.0,0.0,4); + break; + } + } +} + +void PpsDeleteExpiredOprAccount(_prepaid_info *shmp,u_long instance,u8 expiredFlag) +{ + if(!masterFlag || !expiredFlag || shmp->cos_id != opr_param.oprCosId) + return ; + /* be going to delete Expired Opr user */ + if(PPSDeleteOprAccountUser(shmp->msisdn,0)) + { + SendAccountRealSync(instance,0.0,0.0,4); + } +} + +void PpsHanldeOprProc() +{ + ppsGetOprMessage(); +} + diff --git a/mss/pps/src/main/ppsussd.c b/mss/pps/src/main/ppsussd.c new file mode 100644 index 0000000..2693ee1 --- /dev/null +++ b/mss/pps/src/main/ppsussd.c @@ -0,0 +1,7861 @@ +#include +#include + +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/param.h" +#include "../include/mfunc.h" + +#include "../include/plat_inc.h" +#include "../include/mfunc.h" +#include "../include/precard.h" +#include "../include/report.h" +#include "../include/restapi.h" +/*----------------------------------------*/ + +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr; +extern int logMsgFlag; +extern char logMsisdn[]; +extern struct timeval tvnow; +/*----------------------------------------*/ +/*----------------------------------------*/ +extern int smppEncodeSM(); +extern int DebugMsg(); +extern int pps_send_map_opr(); + +#ifdef OCS_USE_REDIS_DB +extern int RedisGetTariffInfo(u_short portid, char *service_nbr, int service_type, char *called_num); +extern int RedisUpdateUsedBundle(char *service_nbr, int service_type, int rr_id, unsigned long long used_bundle_this_time); +#endif + +//extern int map_get_comdata_struct(); +//extern int map_com_stof(); + +extern int pps_send_map_openrsp(); + +extern int ppsBcdToAsciiR(); +extern int GetAccountPos(); +extern int GetAccountCosID(); +extern int GetAccountCUG(); +extern int AccountLatchFlagCheck(); +extern int CheckWetherValidRechargeCard(); +extern int RechargeRequestProc(); +extern int pps_send_map_open(); +extern void StringCut(char *str, int c); +extern int SendAccountInfoBySMPP(); +extern int ppsAsciiToBcdR(); +extern int transferAccountUSSDProc(u_short portid); +extern int ppsSendUSSDStatistics(_state_data *shmp); +extern void pps_send_update_subs_status_to_crm(_prepaid_info *user_ptr, int update_flag); +extern PPSParamStruct ppsParam; + + +/*----------------------------------------*/ + + +int GetUSSDOperationType(char *ussd_data) +{ + //char ussd_format[128]; + + return 1; +} + + +int ppsGetUssdParameter(char *ussd_data, char *ussd_sc, char *ussd_param, char *ussd_param1) +{ + int i, len, index=0, type=0; + + len = strlen(ussd_data); + + ussd_param[0] = '\0'; /* clear ussd parameter */ + ussd_param1[0]= '\0'; + + for(i=0;i0) + { + type++; + index = 0; + } + } + } + return 1; +} + +int GetUSSDRequest(u_short portid, char *ussd_data) +{ + int retval = 0,len; + u_char data_flow[256]; + MapOprSrv_struct opr_srv; + + struct MapPUSSR_Arg *pussr_arg; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + return retval; + } + + if((data_flow[9] != ProcUnstrctSSReq) || data_flow[1]<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait PSSDR but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + + pps_send_map_close(portid); + return -1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, PUSSR ", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = shmp->context_info.map_acn_ver; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + shmp->context_info.invoke_id = data_flow[11]; //opr_srv.invoke_id; + + pussr_arg = &opr_srv.msg_list.pussr_arg; + if(pussr_arg->param_flag != 0x01) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + + len = pussr_arg->ussd_arg.ussd_string.string_len; + if(len > 24) len = 24; + + switch(pussr_arg->ussd_arg.ussd_scheme & 0x0f) + { + case 0x00: + case 0x0f: /* 7bit */ + smppDecodeSM((char *)pussr_arg->ussd_arg.ussd_string.ussd_data, + ussd_data, + len); + break; + case 0x04: /* 8bit */ + default: + memcpy(ussd_data, + pussr_arg->ussd_arg.ussd_string.ussd_data, + len); + break; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, USSD data: \r\n\%s ", + portid,shmp->context_info.map_did, + ussd_data); + } + + return 1; +} + +int SendUSSDRequest(u_short portid, char *ussd_info) +{ + int len; + u_char buf[256]; + MapOprSrv_struct opr_srv; + MapOprData_struct opr_data; + struct MapUSSR_Arg *ussr_arg; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + shmp->context_info.map_iid = + map_get_invokeid(shmp->context_info.map_did); + + opr_srv.invoke_id = shmp->context_info.map_iid; + opr_srv.version = shmp->context_info.map_acn_ver; + opr_srv.message_type = UnstrctSSReq; + opr_srv.message_flag = MAP_REQUEST; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + ussr_arg = &opr_srv.msg_list.ussr_arg; + ussr_arg->param_flag = 0x01; + ussr_arg->ussd_arg.param_flag = 0x03; +// ussr_arg->ussd_arg.ussd_scheme = 0x04; /* 8bit */ + ussr_arg->ussd_arg.ussd_scheme = 0x0f; /* 7bit */ + + len = smppEncodeSM(ussd_info,buf); + + ussr_arg->ussd_arg.ussd_string.string_len = len;//strlen(ussd_info); + memcpy(ussr_arg->ussd_arg.ussd_string.ussd_data, + buf, + ussr_arg->ussd_arg.ussd_string.string_len); + + opr_data.port_id = portid; + opr_data.dialogue_id = opr_srv.dialogue_id; + opr_data.invoke_id = opr_srv.invoke_id; + opr_data.message_type = opr_srv.message_type; + opr_data.message_flag = opr_srv.message_flag; + opr_data.param_flag = 0x1f; + + len = build_mapparam(&opr_srv,opr_data.param); + if(len<=0 || len>MAX_MAPPOPR_LEN) + { + return 0; + } + opr_data.param_len = len; + opr_data.param_flag |= 0x20; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map USSD_Req. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + + } + pps_send_map_opr(&opr_data, 1); + + return 1; +} + +int SendUSSDNotify(u_short portid, char *ussd_info) +{ + int len; + u_char buf[256]; + MapOprSrv_struct opr_srv; + MapOprData_struct opr_data; + struct MapUSSN_Arg *ussn_arg; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + shmp->context_info.map_iid = + map_get_invokeid(shmp->context_info.map_did); + + opr_srv.invoke_id = shmp->context_info.map_iid; + opr_srv.version = shmp->context_info.map_acn_ver; + opr_srv.message_type = UnstrctSSNoti; + opr_srv.message_flag = MAP_REQUEST; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + ussn_arg = &opr_srv.msg_list.ussn_arg; + ussn_arg->param_flag = 0x01; + ussn_arg->ussd_arg.param_flag = 0x03; + //ussn_arg->ussd_arg.ussd_scheme = 0x04; /* 8bit */ + ussn_arg->ussd_arg.ussd_scheme = 0x0f; /* 7bit */ + + len = smppEncodeSM(ussd_info,buf); + ussn_arg->ussd_arg.ussd_string.string_len = len; //strlen(ussd_info); + memcpy(ussn_arg->ussd_arg.ussd_string.ussd_data, + buf, + ussn_arg->ussd_arg.ussd_string.string_len); + + opr_data.port_id = portid; + opr_data.dialogue_id = opr_srv.dialogue_id; + opr_data.invoke_id = opr_srv.invoke_id; + opr_data.message_type = opr_srv.message_type; + opr_data.message_flag = opr_srv.message_flag; + opr_data.param_flag = 0x1f; + + len = build_mapparam(&opr_srv,opr_data.param); + if(len<=0 || len>MAX_MAPPOPR_LEN) + { + return 0; + } + opr_data.param_len = len; + opr_data.param_flag |= 0x20; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map USSD_Notify. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + + } + pps_send_map_opr(&opr_data, 1); + return 1; +} + +int SendPSSRResponse(u_short portid) +{ + int len; + u_char buf[256]; + MapOprSrv_struct opr_srv; + MapOprData_struct opr_data; + struct MapPUSSR_Res *pussr_res; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + opr_srv.invoke_id = shmp->context_info.invoke_id; + opr_srv.version = shmp->context_info.map_acn_ver; + opr_srv.message_type = ProcUnstrctSSReq; + opr_srv.message_flag = MAP_RESPONSE; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + pussr_res = &opr_srv.msg_list.pussr_res; + pussr_res->param_flag = 0x01; + pussr_res->ussd_res.param_flag = 0x03; + pussr_res->ussd_res.ussd_scheme = 0x0f; /* 7bit */ + + switch(shmp->process_info.u_error) + { + case CAP_ERR_MISSING_CUSTOMER_RECORD: + len = smppEncodeSM(getSmsSentenceNative(0,SMS_NOT_REGISTER_PREPAID_USER),buf); + break; + case _PPS_ERR_SERVICE_NOT_APPLIED: + len = smppEncodeSM(getSmsSentenceNative(0,SMS_SERVICE_NOT_APPLIED),buf); + break; + default: + len = smppEncodeSM(getSmsSentenceNative(0,SMS_USSD_COMPLETED),buf); + break; + } + + pussr_res->ussd_res.ussd_string.string_len = len;//strlen(ussd_info); + memcpy(pussr_res->ussd_res.ussd_string.ussd_data, + buf, + pussr_res->ussd_res.ussd_string.string_len); + + opr_data.port_id = portid; + opr_data.dialogue_id = opr_srv.dialogue_id; + opr_data.invoke_id = opr_srv.invoke_id; + opr_data.message_type = opr_srv.message_type; + opr_data.message_flag = opr_srv.message_flag; + opr_data.param_flag = 0x1f; + + len = build_mapparam(&opr_srv,opr_data.param); + if(len<=0 || len>MAX_MAPPOPR_LEN) + { + return 0; + } + opr_data.param_len = len; + opr_data.param_flag |= 0x20; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "portid: %d ,did: %d, Send Map PUSSR_Ack. @ %ld.%ld", + portid,shmp->context_info.map_did, + tvnow.tv_sec,tvnow.tv_usec); + + } + pps_send_map_opr(&opr_data, 0); + + return 1; +} + + + + +int SendPSSREnd(u_short portid,char *ussd_info) + +{ + + int len; + + u_char buf[256]; + + MapOprSrv_struct opr_srv; + + MapOprData_struct opr_data; + + struct MapPUSSR_Res *pussr_res; + + + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + + + if(portid>=MAX_FSM_PROCESS) + + { + + return -1; + + } + + + + shmp += (portid); + + + + opr_srv.invoke_id = shmp->context_info.invoke_id; + + opr_srv.version = shmp->context_info.map_acn_ver; + + opr_srv.message_type = ProcUnstrctSSReq; + + opr_srv.message_flag = MAP_RESPONSE; + + opr_srv.port_id = portid; + + opr_srv.dialogue_id = shmp->context_info.map_did; + + + + pussr_res = &opr_srv.msg_list.pussr_res; + + pussr_res->param_flag = 0x01; + + pussr_res->ussd_res.param_flag = 0x03; + + pussr_res->ussd_res.ussd_scheme = 0x0f; /* 7bit */ + + + + len = smppEncodeSM(ussd_info,buf); + + + + pussr_res->ussd_res.ussd_string.string_len = len;//strlen(ussd_info); + + memcpy(pussr_res->ussd_res.ussd_string.ussd_data, + + buf, + + pussr_res->ussd_res.ussd_string.string_len); + + + + opr_data.port_id = portid; + + opr_data.dialogue_id = opr_srv.dialogue_id; + + opr_data.invoke_id = opr_srv.invoke_id; + + opr_data.message_type = opr_srv.message_type; + + opr_data.message_flag = opr_srv.message_flag; + + opr_data.param_flag = 0x1f; + + + + len = build_mapparam(&opr_srv,opr_data.param); + + if(len<=0 || len>MAX_MAPPOPR_LEN) + + { + + return 0; + + } + + opr_data.param_len = len; + + opr_data.param_flag |= 0x20; + + + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + + { + + DebugMsg(debugmib.display.asciiOut, + + "portid: %d ,did: %d, Send Map PUSSR_Ack. @ %ld.%ld", + + portid,shmp->context_info.map_did, + + tvnow.tv_sec,tvnow.tv_usec); + + + + } + + pps_send_map_opr(&opr_data, 0); + + + + return 1; + +} + +int SendUSSDTellMeNumberInfo(u_short portid) +{ + char ussd_info[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + sprintf(ussd_info, "%s %s", getSmsSentenceNative(0,SMS_TELL_ME_NUMBER), shmp->caller_info.number); + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[36m portid: %d ,did: %d, USSD Tell Me Number notify\n %s\33[0m", + portid,shmp->context_info.map_did, + ussd_info); + } + SendPSSREnd(portid,ussd_info); + return 1; +} + +int GetAccountRestInfo(u_short portid, char *prompt_info) +{ + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + long balance, promotion=0; + char expire_date[64]={0},promotion_expire_date[64]={0}; + char buf[2*MAX_SMS_LEN]="",buf2[4*MAX_SMS_LEN]=""; + int len,totalLen, tmp_len=0; + + PutLogFunID("GetAccountRestInfo"); + + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + memset(buf,0,MAX_SMS_LEN*2); + memset(buf2,0,MAX_SMS_LEN*4); + + AsciiTime(expire_date,shmp->process_info.rest_if.mo_expiry_date); + balance = shmp->process_info.rest_if.balance; + + /******************** balance **************************************/ +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ + if(strstr(getSmsSentenceNative(0,SMS_ACCOUNT_BALANCE), "%s") == NULL) + { + sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_BALANCE)); + } + else + { + sprintf(buf, (char *)getSmsSentenceNative(0, SMS_ACCOUNT_BALANCE), + (char *)shmp->caller_info.number); + } +#else + sprintf(buf,"Your balance for %s is ", (char *)shmp->caller_info.number); +#endif + len = strlen(buf); + + strcpy(buf2,buf); + totalLen = len; + + memset(buf,0,MAX_SMS_LEN*2); + len = fillMoneyAndDate(balance,expire_date,0,0, (u_char *)buf); + strcat(buf2,buf); + totalLen += len; + + tmp_len = totalLen; + /******************** balance **************************************/ + + /******************** promotion **************************************/ + if(promotion > 0) + { + memset(buf,0,MAX_SMS_LEN*2); + sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_PROMOTION)); + len = strlen(buf); + + strcat(buf2,buf); + totalLen += len; + + memset(buf,0,MAX_SMS_LEN*2); + len = fillMoneyAndDate(promotion,promotion_expire_date,0,0, (u_char *)buf); + strcat(buf2,buf); + totalLen += len; + } + memcpy(prompt_info,buf2,240); + prompt_info[240]=0; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[36m portid: %d ,did: %d, USSD inquiry notify\n %s\33[0m", + portid,shmp->context_info.map_did, + prompt_info); + } + + + /******************** promotion **************************************/ + return tmp_len; +} + +int SendUSSDInqiuryInfo(u_short portid) +{ + char ussd_info[256]; + int len; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + len = GetAccountPromptInfo(&shmp->caller_info,ussd_info)%256; + ussd_info[len] = 0; + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[36m portid: %d ,did: %d, USSD inquiry notify\n %s\33[0m", + portid,shmp->context_info.map_did, + ussd_info); + } + //SendUSSDNotify(portid,ussd_info); + SendPSSREnd(portid,ussd_info); + return 1; +} + +int SendLowBalanceUSSDNotify(u_short portid) +{ + SendUSSDNotify(portid, (char *)getSmsSentenceNative(0,SMS_LOW_BALANCE_NOTIFY)); + + return 1; +} + +int SendUSSDRechargeRequest(u_short portid) +{ + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_RECHARGE_INPUT_PIN)); + return 1; +} + +int SendUSSDRechargeRequestAgain(u_short portid) +{ + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_RECHARGE_INPUT_PIN_AGAIN)); + return 1; +} + + +int UssdInquiryProcess(u_short portid) +{ + int caller_status; + //int instance; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + COSTable *cosTableItem; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(pps_get_adaptor_flag()) + { + shmp->process_info.sub_state = S_MAP_REST_QUERY; + shmp->process_info.sub_state_2 = 0; + shmp->process_info.rest_if.rest_oc = 0; + shmp->process_info.rest_if.rest_src = 0; + + return 0; + } + + shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; + + shmp->process_info.serviceKey = 1; + shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; + + caller_status = GetAccountStatus(&shmp->caller_info); + + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(caller_status == T_FRESH) + { + if(cosTableItem->accountValidity[0].activiationByInquiryIs) + { + int instance; + + UpdateAccountStatus(shmp->caller_info.head, + shmp->caller_info.tail, + T_NORMAL); + UpdateAccountFirstUsedDate( + shmp->caller_info.head, + shmp->caller_info.tail); + + UpdateExpirationFirstInquiry( + &shmp->caller_info, + cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance); + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + smppSendActivicationInfo(&shmp->caller_info, + (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number); + + caller_status = T_NORMAL; + } + } + + if(caller_status == T_NORMAL) + { + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP(&shmp->caller_info, + ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number); + } + } + + SendUSSDInqiuryInfo(portid); + + return 1; +} + +int SendUSSDRechargeSuccessInfo(u_short portid) +{ + char ussd_info[256],account_info[250]; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + GetAccountPromptInfo(&shmp->caller_info,account_info); + sprintf(ussd_info,"%s %s",getSmsSentenceNative(0,SMS_GPRS_RECHARGE_SUCCESS),account_info); + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[36m portid: %d ,did: %d, USSD recharge notify\n %s\33[0m ", + portid,shmp->context_info.map_did, + ussd_info); + } + //SendUSSDNotify(portid,ussd_info); + + SendPSSREnd(portid,ussd_info); + return 1; +} + + +int SendUSSDFavortieInfo(u_short portid, int type) +{ + char ussd_info[256], buf[128]; + int i, head, tail, cos_id, plan_id, free_sms, free_call_duration; + int send_request_flag = 0, retval = 1,counter=0; + _prepaid_info *user_ptr=NULL; + CosFriendFamilyControl *friendFamilyControl; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + char *buf_ptr[8],tmp_buf[8][32]; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + + for(i=0;i<8;i++) + buf_ptr[i] = tmp_buf[i]; + + switch(type) + { + case 0: /* not register F&F service */ + sprintf(ussd_info,"%s",getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NOT_REGISTERED) ); + break; + case 1: /* not F&F plan user */ + sprintf(tmp_buf[0], "%d", user_ptr->favorite_numbers); + counter = 1; + for(i=0;ifavorite_number[i][MAX_MSISDN_BLEN-1]>3) + { + sprintf(tmp_buf[counter], "#%d: ", i); + MsisdnToAscii(buf, user_ptr->favorite_number[i]); + strcat(tmp_buf[counter++], buf); + } + } + if(counter>2) + { + sprintf(ussd_info,"%s ...", ppsParseSentence((char *)getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NOT_PLAN), 2, buf_ptr)); + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_QUERY); + } + else + { + sprintf(ussd_info,"%s", ppsParseSentence((char *)getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NOT_PLAN), counter, buf_ptr)); + } + break; + case 2: /* F&F plan service is suspened */ + cos_id = user_ptr->cos_id; + plan_id = user_ptr->favorite_plan_id; + friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; + if(friendFamilyControl->friendFamilyPlan[plan_id-1].rentCharge > GetAccountBalance(head, tail)) + { + sprintf(ussd_info, "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_SUSPENDT)); + } + else + { + sprintf(ussd_info, "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_SUSPEND_REAC)); + send_request_flag = 1; + retval = 0; + } + break; + case 3: /* F&F plan service is OK */ + cos_id = user_ptr->cos_id; + plan_id = user_ptr->favorite_plan_id-1; + friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; + free_sms = friendFamilyControl->friendFamilyPlan[plan_id].freeSMS; + free_call_duration = friendFamilyControl->friendFamilyPlan[plan_id].freeCallDuration*60; + + sprintf(tmp_buf[0], "%d", user_ptr->favorite_numbers); + if(free_call_duration>0) + sprintf(tmp_buf[1], "%lu", user_ptr->free_favorite_call>free_call_duration ? 0: ((free_call_duration- user_ptr->free_favorite_call)/60)); + else + sprintf(tmp_buf[1], "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NO_LIMIT)); + if(free_sms >0) + sprintf(tmp_buf[2], "%lu", user_ptr->free_favorite_sms> free_sms ? 0: free_sms-user_ptr->free_favorite_sms); + else + sprintf(tmp_buf[2], "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NO_LIMIT)); + + + sprintf(ussd_info, "%s ", ppsParseSentence((char *)getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY), 3, buf_ptr)); + +/* + for(i=0;ifavorite_number[i][MAX_MSISDN_BLEN-1]>3) + { + sprintf(buf, "#%d: ", i); + strcat(ussd_info, buf); + MsisdnToAscii(buf, user_ptr->favorite_number[i]); + strcat(ussd_info, buf); + } + } + */ + default: + break; + } +// GetAccountPromptInfo(&shmp->caller_info,account_info); +// sprintf(ussd_info,"%s,%s",getSmsSentenceNative(0,SMS_GPRS_RECHARGE_SUCCESS),account_info); + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[36m portid: %d ,did: %d, USSD Friends & Family info:\n %s\33[0m ", + portid,shmp->context_info.map_did, ussd_info); + } + + if(send_request_flag == 0) + SendPSSREnd(portid,ussd_info); + else + SendUSSDRequest(portid, ussd_info); + + return retval; +} + + +int reactivateFaviroteSericeUssdProc(u_short portid) +{ + int retval = 0,len, head ,tail,charge=0; + u_char data_flow[256]; + char ussd_data[256],ussd_info[256]; + MapOprSrv_struct opr_srv; + CosFriendFamilyControl *friendFamilyControl; + + //struct MapPUSSR_Arg *pussr_arg; + struct MapUSSR_Res *ussr_ack; + + _prepaid_info *user_ptr=NULL; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return 1; + } + + shmp += portid; + + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + return retval; + } + if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + ppsSendUSSDStatistics(shmp); + + return 1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = shmp->context_info.map_acn_ver; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + + ussr_ack = &opr_srv.msg_list.ussr_res; + + if(ussr_ack->param_flag != 0x01) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, USSR error received \33[0m", + portid,shmp->context_info.map_did); + } + return -1; + } + + retval = 1; + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + + switch(ussr_ack->ussd_res.ussd_scheme & 0x0f) + { + case 0x00: + case 0x0f: /* 7bit */ + smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data, + ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + break; + case 0x04: /* 8bit */ + default: + memcpy(ussd_data, + ussr_ack->ussd_res.ussd_string.ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + break; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, USSD data: %s", + portid,shmp->context_info.map_did, + ussd_data); + } + + len = strlen(ussd_data); + if(len>16) + { + ussd_data[16] = 0; + len = 16; + } + + if(ussd_data[0] == '1') /* check response here */ + { + + } + user_ptr->favorite_plan_state = 0; + user_ptr->free_favorite_call = 0; + user_ptr->free_favorite_sms = 0; + user_ptr->fav_change_counter = 0; + friendFamilyControl = &ppsParam.ppsTables.cosTable[user_ptr->cos_id].friendFamilyControl[0]; + charge = friendFamilyControl->friendFamilyPlan[user_ptr->favorite_plan_id-1].rentCharge; + + shmp->caller_info.charge = charge; + user_ptr->balance = user_ptr->balance - charge; + //UpdateAccountBalance( head, tail, -charge ); + // SendOperatorRechargeCDR(head,tail, -charge); + SendPPSGeneralCDR(head, tail, -charge, CT_FF_ACTIVATION); + SendAccountRealSync(head*UNIT_STORE_ACCOUNT+tail,-charge,0,2); + + if(ppsParam.ppsTables.cosTable[user_ptr->cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceReg) + sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_REG); + + sprintf(ussd_info, "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_SERIVCE_REACTIVATE)); + + SendPSSREnd(portid,ussd_info); + //SendUSSDNotify(portid,ussd_info); + + return retval; + +} +int favoriteNumberUssdProc(u_short portid) +{ + int retval = SERVICE_KEEP_STATE; + int head,tail; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + _prepaid_info *user_ptr=NULL; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + switch(shmp->process_info.sub_state_2) + { + case 0: + head = shmp->caller_info.head; + tail = shmp->caller_info.tail; + user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(user_ptr->favorite_plan_id<1 && user_ptr->favorite_numbers<=0) + { + shmp->process_info.sub_state_2 = 1; + } + else + { + if(user_ptr->favorite_plan_id<1) + { + shmp->process_info.sub_state_2 = 2; + } + else + { + if(user_ptr->favorite_plan_state>0) + { + shmp->process_info.sub_state_2 = 3; + } + else + { + shmp->process_info.sub_state_2 = 4; + } + } + } + break; + case 1: + SendUSSDFavortieInfo(portid,0);/* not register F&F service */ + return SERVICE_EXIT_PPS; + break; + case 2: + SendUSSDFavortieInfo(portid, 1); /* not F&F plan user */ + return SERVICE_EXIT_PPS; + break; + case 3: + if( SendUSSDFavortieInfo(portid, 2)== 0) /* F&F plan service is suspended */ + shmp->process_info.sub_state_2 = 5; + else + return SERVICE_EXIT_PPS; + break; + case 4: + SendUSSDFavortieInfo(portid, 3); /* F&F plan service is OK */ + return SERVICE_EXIT_PPS; + break; + case 5: + if(reactivateFaviroteSericeUssdProc(portid)) + { + return SERVICE_EXIT_PPS; //SERVICE_RETURN_TO_PARENT; + } + break; + default: + return SERVICE_EXIT_PPS; + break; + } + + return retval; +} + +static int pps_send_rest_msg(u8 *msg_buf, int len) +{ + message_list iptr_msg; + + iptr_msg.msgSrcPort = REST_PROXY_PORT; + iptr_msg.msgDstPort = 4900; + iptr_msg.msgDstIP = GetLocalIP(); + iptr_msg.msgLength = len; + memcpy(iptr_msg.msgContent, msg_buf, len); + iptrPutMessage(iptr_msg); + + return 0; +} + +int pps_send_rest_query_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_QUERY; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + strcpy(rest_msg.msg.query.msisdn, (char *)shmp->caller_info.number); + + len = encode_rest_query(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +extern _prepaid_info *getPrepaidInfo(_account_info *account); +static int pps_handle_send_authcode_req(_rest_msg_s *rest_req) +{ + _rest_send_authcode_req *pReq = &rest_req->msg.send_authcode_req; + _rest_msg_s rest_rsp; + _rest_send_authcode_rsp *pRsp = &rest_rsp.msg.send_authcode_rsp; + u8 msg_buf[256]; + int len; + + PutLogFunID("pps_handle_send_authcode_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_send_authcode_req(), msisdn[%s], sms[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn, pReq->sms_content); + } + + // check log msisdn + int flag_log_msisdn = 0; + _account_info user_info; + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + int err_code = ERR_REST_SUCCESS; + if ((strlen(pReq->msisdn) == 0) || (strlen(pReq->sms_content) == 0)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_send_authcode_req(), invalid param"); + } + + err_code = ERR_REST_INVALID_PARAMETER_VALUE; + goto out; + } + + // get user info + GetAccountPos(&user_info); + int status = GetAccountStatus(&user_info); + if ((status != T_NORMAL) && (status != T_SUSPEND)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_send_authcode_req(), msisdn[%s], err status[%d]", \ + pReq->msisdn, status); + } + err_code = ERR_REST_USER_UNKNOWN; + } + else + { + // send authcode + smppSendMOSM((char *)user_info.number, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, \ + (u_char *)pReq->sms_content, strlen(pReq->sms_content), 0); + } + +out: + // send response msg================ + rest_rsp.msg_type = REST_SEND_AUTHCODE_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_TRANSFER_RSP, result[%d]", err_code); + } + + len = encode_rest_send_authcode_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +static int pps_handle_query_userdata_req(_rest_msg_s *rest_req) +{ + _rest_query_user_data_req *pReq = &rest_req->msg.query_user_data_req; + + PutLogFunID("pps_handle_query_userdata_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_query_userdata_req(), msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); + } + + int flag_log_msisdn = 0; + _account_info user_info; + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + int err_code = ERR_REST_SUCCESS; + _prepaid_info *pUsrInfo = NULL; + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_query_userdata_req(), msisdn[%s], not found", \ + pReq->msisdn); + } + err_code = ERR_REST_USER_UNKNOWN;// not found + } + + // set message + _rest_msg_s rest_rsp; + _rest_query_user_data_rsp *pRsp = &rest_rsp.msg.query_user_data_rsp; + memset(pRsp, 0, sizeof(_rest_query_user_data_rsp)); + memcpy(pRsp->msisdn, pReq->msisdn, 24); + if (pUsrInfo != NULL) + { + //usrGroupName + int cos_id = GetAccountCosID(&user_info); + strcpy(pRsp->usrGrpName, (char *)ppsParam.ppsTables.cosTable[cos_id].title); + + pRsp->status = pUsrInfo->status; + pRsp->balance = (u32)pUsrInfo->balance; + pRsp->mo_expiry = pUsrInfo->mo_expiration_date; + pRsp->remain_mo_voc_min = pUsrInfo->bundle_info.mo_voice/60; + pRsp->remain_mt_voc_min = pUsrInfo->bundle_info.mt_voice/60; + pRsp->remain_sms_num = pUsrInfo->bundle_info.sms; + pRsp->remain_data_vol = pUsrInfo->bundle_info.data/(1024*1024); + } + else + { + pRsp->status = T_EXTERNAL; + } + + // send response msg================ + rest_rsp.msg_type = REST_QUERY_USERDATA_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_QUERY_USERDATA_RSP, result[%d]", err_code); + } + + u8 msg_buf[256]; + int len = encode_rest_query_user_data_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +static int pps_handle_bundle_subs_req(_rest_msg_s *rest_req) +{ + _rest_bundle_subs_req *pReq = &rest_req->msg.bundle_subs_req; + _rest_msg_s rest_rsp; + _rest_bundle_subs_rsp *pRsp = &rest_rsp.msg.bundle_subs_rsp; + int len; + + PutLogFunID("pps_handle_bundle_subs_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_bundle_subs_req(), msisdn[%s], pay type[%d], charge[%d]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn, pReq->payType, pReq->charge); + DebugMsg(debugmib.display.asciiOut, + "mo[%dMin], mt[%dMin], data[%dMB], sms[%d], valid day[%d]", \ + pReq->moVoiceMinute, pReq->mtVoiceMinute, pReq->dataVolume, pReq->smsNum, pReq->validDays); + } + + // log msisdn + _account_info user_info; + int flag_log_msisdn = 0; + memset(pRsp, 0, sizeof(_rest_bundle_subs_rsp)); + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + // get user info + int err_code = ERR_REST_SUCCESS; + GetAccountPos(&user_info); + user_info.status = GetAccountStatus(&user_info); + user_info.expired_flag = (u_char)isAccountExpired(&user_info); + if ((user_info.status != T_NORMAL) || user_info.expired_flag) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_bundle_subs_req(), msisdn[%s], error, status[%d], expired[%d]", \ + pReq->msisdn, user_info.status, user_info.expired_flag); + err_code = ERR_REST_USER_UNKNOWN;// not found + goto out; + } + + int sms_len = 0; + char sms_msg[256] = {0}; + float charge = 0.0; + if (pReq->payType == 1)// pay by balance + { + charge = (float)pReq->charge; + float balance = GetAccountBalance(user_info.head, user_info.tail); + + if(balance < charge) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_bundle_subs_req(), msisdn[%s], balance[%.4f] < request[%.4f]", \ + pReq->msisdn, balance, charge); + err_code = ERR_REST_CREDIT_LIMIT;// not acceptable + + sprintf(sms_msg, "%s", getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_NOK)); + goto out; + } + + // update balance + UpdateAccountBalance(user_info.head, user_info.tail, -charge); + } + + // update bundle info + long ret_value[10]; + ret_value[0] = 0 - (long)charge; + ret_value[1] = pReq->dataVolume; + ret_value[2] = pReq->moVoiceMinute; + ret_value[3] = pReq->mtVoiceMinute; + ret_value[4] = pReq->smsNum; + ret_value[5] = pReq->validDays; + ret_value[6] = 0; + UpdateAccountBundlePlanInfo(&user_info, ret_value); + // + + // sync + int instance = user_info.head*UNIT_STORE_ACCOUNT + user_info.tail; + SendAccountRealSync(instance, -charge, 0, OMC_OCODE_EDIT); + // + + // send cdr=========================================== + SendSelfcareBundleSubCDR(&user_info, (int)charge, pReq->dataVolume*1024, pReq->moVoiceMinute*60); + // + + // set sms string + char expire_date[64]; + char msg_buf[256] = {0}; + GetAccountBundlePlanInfo(&user_info, ret_value); + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "new bundle, data [%ld]MB, mo [%ld]Min, mt [%ld]Min, sms[%ld]", \ + ret_value[0], ret_value[1], ret_value[2], ret_value[3]); + } + + AsciiTimeYMD(expire_date, ret_value[4]); + sprintf(sms_msg, "%s", getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_OK)); + if(ret_value[1]>0 || ret_value[3]>0) + { + sprintf(msg_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY), + ret_value[0], + ret_value[1], + // ret_value[2],// disable MT voice + ret_value[3], + expire_date); + } + else + { + sprintf(msg_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY_DATA), + ret_value[0], + expire_date); + } + + strcat(sms_msg, msg_buf); + // + +out: + // send sms + sms_len = strlen(sms_msg); + if (sms_len > 0) + { + smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, sms_len, 0); + } + // + + // send response msg================ + rest_rsp.msg_type = REST_BUNDLE_SUBS_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_BUNDLE_SUBS_RSP, result[%d]", err_code); + } + + len = encode_rest_bundle_subs_rsp(&rest_rsp, (u8 *)msg_buf); + pps_send_rest_msg((u8 *)msg_buf, len); + // + + return 0; +} + +static int pps_handle_bundle_usage_req(_rest_msg_s *rest_req) +{ + _rest_bundle_usage_req *pReq = &rest_req->msg.bundle_usage_req; + + PutLogFunID("pps_handle_bundle_usage_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_bundle_usage_req(), msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); + } + + _account_info user_info; + int flag_log_msisdn = 0; + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + int err_code = ERR_REST_SUCCESS; + _prepaid_info *pUsrInfo = NULL; + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_bundle_usage_req(), msisdn[%s], not found", \ + pReq->msisdn); + err_code = ERR_REST_USER_UNKNOWN;// not found + } + + // set msg + _rest_msg_s rest_rsp; + _rest_bundle_usage_rsp *pRsp = &rest_rsp.msg.bundle_usage_rsp; + memset(pRsp, 0, sizeof(_rest_bundle_usage_rsp)); + if (pUsrInfo != NULL) + { + pRsp->moVoiceInSec = pUsrInfo->bundle_info.mo_voice; + pRsp->mtVoiceInSec = pUsrInfo->bundle_info.mt_voice; + pRsp->smsNum = pUsrInfo->bundle_info.sms; + pRsp->dataVolInKB = pUsrInfo->bundle_info.data/1024; + pRsp->expiredTime = pUsrInfo->bundle_info.validity_date; + } + // + + // send response msg================ + rest_rsp.msg_type = REST_BUNDLE_USAGE_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_BUNDLE_USAGE_RSP, result[%d], data[%d]KB, mo[%d]sec, mt[%d]sec, sms[%d]", + err_code, pRsp->dataVolInKB, pRsp->moVoiceInSec, pRsp->mtVoiceInSec, pRsp->smsNum); + } + + u8 msg_buf[256]; + int len = encode_rest_bundle_usage_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +static int pps_handle_recharge_req(_rest_msg_s *rest_req) +{ + _rest_recharge_req *pReq = &rest_req->msg.recharge_req; + int len; + int op_type = CT_ASSISTED_UP; + u8 msg_buf[256]; + int flag_log_msisdn = 0; + _account_info user_info; + int err_code = ERR_REST_SUCCESS; + + char sms_msg[256] = {0}; + int balance; + float recharge; + _prepaid_info *pUserInfo = NULL; + + _rest_msg_s rest_rsp; + _rest_recharge_rsp *pRsp = &rest_rsp.msg.recharge_rsp; + + + PutLogFunID("pps_handle_recharge_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_recharge_req(), op_type=%d, msisdn[%s], amount[%d]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->op_type, pReq->msisdn, pReq->amount); + } + + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + GetAccountPos(&user_info); + user_info.status = GetAccountStatus(&user_info); + user_info.expired_flag = (u_char)isAccountExpired(&user_info); + user_info.cos_id = (u_char)GetCosIDByAccount(&user_info); + if ((user_info.status != T_NORMAL && user_info.status != T_FRESH && user_info.status != T_SUSPEND && user_info.status != T_DISABLE)) +// if ((user_info.status != T_NORMAL && user_info.status != T_FRESH && user_info.status != T_SUSPEND) || user_info.expired_flag) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_req(), msisdn[%s], error, status[%d], expired[%d]", \ + pReq->msisdn, user_info.status, user_info.expired_flag); + err_code = ERR_REST_USER_UNKNOWN;// not found + goto out; + } + + memset(pRsp, 0, sizeof(_rest_recharge_rsp)); + + balance = (int)GetAccountBalance(user_info.head, user_info.tail); + + if(pReq->op_type == 0) + { + if (balance < pReq->amount ) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_req(), msisdn[%s], balance[%d] exceed maximum[%d]", \ + pReq->msisdn, (balance + pReq->amount), ppsParam.serviceControl.maxBalance); + err_code = ERR_REST_CREDIT_LIMIT; + sprintf(sms_msg, "%s", "Recharge failed, you have exceeded your maximum balance."); + smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, strlen(sms_msg), 0); + goto out; + } + op_type = CT_ASSISTED_DOWN; + recharge = (-1)*(float)pReq->amount; + + } + else if(pReq->op_type == 1) + { + if ((balance + pReq->amount) >= ppsParam.serviceControl.maxBalance) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_req(), msisdn[%s], balance[%d] exceed maximum[%d]", \ + pReq->msisdn, (balance + pReq->amount), ppsParam.serviceControl.maxBalance); + err_code = ERR_REST_INVALID_PARAMETER_VALUE; + sprintf(sms_msg, "%s", "Recharge failed, you have exceeded your maximum balance."); + smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, strlen(sms_msg), 0); + goto out; + } + op_type = CT_ASSISTED_UP; + recharge = (float)pReq->amount; + + } + else + { + err_code = ERR_REST_INVALID_PARAMETER_VALUE; + sprintf(sms_msg, "%s", "Recharge failed, wrong op_type."); + goto out; + } + + // update balance + //UpdateAccountBalance(user_info.head, user_info.tail, pReq->amount); + UpdateAccountBalance(user_info.head, user_info.tail, recharge); + + pUserInfo = getPrepaidInfo(&user_info); + + // send cdr===================================================== + + SendSelfcareRechargeCDR(&user_info, "", op_type, (int)pReq->amount); + + // update status + COSTable *cosTableItem = &ppsParam.ppsTables.cosTable[user_info.cos_id]; + if (T_FRESH == user_info.status) + { + // update first used date + //int index; + //int mo_valid_time = 30, mt_valid_time = 30; + /* + _prepaid_data *shmp = &ramshm_ptr->prepaid_data; + if((index=GetCardSystemParamByNearestValue(user_info.cos_id, (u_short)pReq->amount))>=0){ + mo_valid_time = cosTableItem->rechargeCardValidity[index].moValidity; + mt_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; + } + */ + /* + mo_valid_time = mt_valid_time = pReq->valid_days; + if(mo_valid_time<=0) + mo_valid_time = mt_valid_time = 1; + + shmp->prepaid_info[user_info.head][user_info.tail].mo_expiration_date = + mo_valid_time*24*60*60 + tvnow.tv_sec; + shmp->prepaid_info[user_info.head][user_info.tail].mt_expiration_date = + mt_valid_time*24*60*60 + tvnow.tv_sec; + */ + UpdateAccountFirstUsedDate(user_info.head, user_info.tail); + UpdateExpirationForRechargeCard(&user_info, pReq->valid_days, (u_short)pReq->amount); + UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); + } + else + { + if(op_type == CT_ASSISTED_UP) + { + int old_status=0x00; + + old_status = GetAccountStatus(&user_info); + + UpdateExpirationForRechargeCard(&user_info, pReq->valid_days, (u_short)pReq->amount); + UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); + + if(old_status != T_NORMAL && old_status != T_FRESH) + pps_send_update_subs_status_to_crm(pUserInfo, 1); //update status to CRM , may then invoke procedures towards HLR/HSS + } + } + // + + // Sync + u32 instance = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; + SendAccountRealSync(instance, recharge, 0.0, OMC_OCODE_EDIT); + + // send notification sms + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenRecharge) + { + SendAccountInfoBySMPP(&user_info, ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + } + + // set respons msg + pRsp->status = GetAccountStatus(&user_info); + pRsp->balance = GetBalance(&user_info); + pRsp->expiredTime = (u64)GetExpiration(&user_info); + + + if(pUserInfo->cug_id>0 && pUserInfo->crm_info.vas_cug_state>0) + { + pps_send_rent_charge_to_crm(user_info.head, user_info.tail); + } +out: + // send response msg================ + rest_rsp.msg_type = REST_RECHARGE_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_RECHARGE_RSP, result[%d], balance[%d]", err_code, pRsp->balance); + } + + len = encode_rest_recharge_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +extern int isChildTransferAllowed(_prepaid_info *prepaidInfo); +extern int checkTransferedPartialFee(_account_info *callerInfo, float feeTransfered); + +static int pps_handle_transfer_req(_rest_msg_s *rest_req) +{ + _rest_transfer_req *pReq = &rest_req->msg.transfer_req; + int err_code = ERR_REST_SUCCESS, len; + u8 msg_buf[256]; + u_char tmp[MAX_SMS_LEN*4] = {0}; + + PutLogFunID("pps_handle_transfer_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_transfer_req(), transfer out[%s], in[%s], amount[%d]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->transferOutMsisdn, pReq->transferInMsisdn, pReq->amount); + } + + _account_info user_info; + strcpy((char *)user_info.number, pReq->transferOutMsisdn); + + // check log msisdn + int flag_log_msisdn = 0; + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + // check param + _rest_msg_s rest_rsp; + _rest_transfer_rsp *pRsp = &rest_rsp.msg.transfer_rsp; + memset(pRsp, 0, sizeof(_rest_transfer_rsp)); + if ((pReq->amount == 0) || (strlen(pReq->transferOutMsisdn) == 0) || (strlen(pReq->transferInMsisdn) == 0)) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_transfer_req(), err param, transfer out msisdn[%s]", pReq->transferOutMsisdn); + } + goto out; + } + + // check src number + _prepaid_info *prepaidInfo = NULL; + GetAccountPos(&user_info); + if ((GetAccountStatus(&user_info) != T_NORMAL)\ + || ((prepaidInfo = getPrepaidInfo(&user_info)) == NULL)\ + || ((prepaidInfo->poolAccount.role == MASTER_SLAVE_CHILD)\ + && (isChildTransferAllowed(prepaidInfo) == FALSE))) + { + strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_SERVICE_NOT_APPLIED)); + smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "src number[%s], SMS_SERVICE_NOT_APPLIED", pReq->transferOutMsisdn); + } + + err_code = ERR_REST_USER_UNKNOWN;// not found + goto out; + } + + // check transfer fee + float amount = (float)pReq->amount; + int result = checkTransferedPartialFee(&user_info, amount); + switch(result) + { + case CHECK_TRANSFERED_FEE_INSUFFIENT: + strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_INSUFFICIENT_FEE)); + smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "src number[%s], SMS_INSUFFICIENT_FEE", pReq->transferOutMsisdn); + } + + err_code = ERR_REST_CREDIT_LIMIT; + goto out; + break; + case CHECK_TRANSFERED_FEE_EXPIERED: + strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_EXPIRED_ACCOUNT)); + smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "src number[%s], SMS_EXPIRED_ACCOUNT", pReq->transferOutMsisdn); + } + + err_code = ERR_REST_INVALID_USER_STATUS; + goto out; + break; + default: + break; + } + // + + // check dst number + _account_info dst_user; + strcpy((char *)dst_user.number, pReq->transferInMsisdn); + int bDstAllowFlag = 0; + if (GetAccountPos(&dst_user) == TRUE) + { + if (get_transfer_status_normal_flag()) + { + int status = GetAccountStatus(&dst_user); + if ((status == T_NORMAL) || (status == T_FRESH) || (status == T_SUSPEND)) + { + bDstAllowFlag = 1; + } + } + else + { + bDstAllowFlag = 1; + } + } + + if (!bDstAllowFlag) + { + strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_INVALID_NUMBER)); + smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "dst number[%s], SMS_INVALID_NUMBER", pReq->transferInMsisdn); + } + + err_code = ERR_REST_DEST_USER_NOT_ALLOWED; + goto out; + } + // + + // fee transfer + poolTransferAccount(&user_info, &dst_user, amount); + if(OCS_with_external_CRM() == 0) + { + notifyUserTransferResult_1(&user_info, &dst_user, (int)amount, NOTIFY_CALLER); + notifyUserTransferResult_1(&user_info, &dst_user, (int)amount, NOTIFY_CALLED); + } + // send cdr + float charge = (float)pReq->amount; + SendSelfcareTransferCDR(&user_info, &dst_user, -charge); + SendSelfcareTransferCDR(&dst_user, &user_info, charge); + // + + // set response message + pRsp->balance = (u32)GetAccountBalance(user_info.head, user_info.tail); + +out: + // send response msg================ + rest_rsp.msg_type = REST_TRANSFER_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_TRANSFER_RSP, result[%d], balance[%d]", err_code, pRsp->balance); + } + + len = encode_rest_transfer_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +extern _climax_quence climaxQuence; +extern int GetClimaxQuenceStorePos(u_char *card_pwd,int start,int end); +extern int pps_real_update_card_file(int head, int tail); +static int pps_handle_recharge_card_req(_rest_msg_s *rest_req) +{ + _rest_recharge_card_req *pReq = &rest_req->msg.recharge_card_req; + int err_code = ERR_REST_SUCCESS, len; + u8 msg_buf[256]; + char sms_msg[256] = {0}; + + PutLogFunID("pps_handle_recharge_card_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_recharge_card_req(), msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); + } + + _account_info user_info; + int flag_log_msisdn = 0; + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + _rest_msg_s rest_rsp; + _rest_recharge_card_rsp *pRsp = &rest_rsp.msg.recharge_card_rsp; + memset(pRsp, 0, sizeof(_rest_recharge_card_rsp)); + GetAccountPos(&user_info); + user_info.status = GetAccountStatus(&user_info); + user_info.expired_flag = isAccountExpired(&user_info); + user_info.cos_id = GetCosIDByAccount(&user_info); + if ((user_info.status != T_NORMAL && user_info.status != T_FRESH && user_info.status != T_SUSPEND) || user_info.expired_flag) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], error status[%d] or expired[%d]", \ + pReq->msisdn, user_info.status, user_info.expired_flag); + err_code = ERR_REST_USER_UNKNOWN;// not found + goto out; + } + + len = strlen(pReq->cardPwd);/* to judge length of pwd,6,8 */ + if(len <10 || len >16) + { + SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], error pwd len[%d]", \ + pReq->msisdn, len); + err_code = ERR_REST_INVALID_RECHARGE_PWD; + goto fail; + } + + if(OCS_with_external_CRM()) + { + int proc_id = 0; + _state_data *shmp; + + proc_id = AssignProcID(0); + if(proc_id<0) return 0; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += proc_id; + shmp->process_info.portid = proc_id; + + memcpy(&shmp->caller_info, &user_info, sizeof(_account_info)); + strcpy((char *)shmp->called_info.number, pReq->cardPwd); + + shmp->process_info.state = S_SMMP_RECHAGE_ACCOUNT; + shmp->process_info.chargeFrom = 3; + shmp->process_info.sub_state = 2; + shmp->process_info.rest_if.src_ref = rest_req->header.src_ref; + shmp->process_info.rest_if.dst_ref = proc_id; + + return 1; + } + + + char card_pwd[64]=""; + int cardsqu = 0, cardtail = 0; + _recharge_card_info *cardshmp = NULL; + EncryptCardHRN(pReq->cardPwd, (u_char *)card_pwd); + if((cardsqu = GetClimaxQuenceStorePos((u_char *)card_pwd, 0, climaxQuence.counter)) < 0) + { + SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], card not found", \ + pReq->msisdn); + err_code = ERR_REST_INVALID_RECHARGE_PWD; + goto fail; + } + cardtail = cardsqu % MAX_CARD_NUM_PSEG; + cardsqu = cardsqu / MAX_CARD_NUM_PSEG; + + cardshmp=&ramshm_ptr->card_data.prepaid_card[cardsqu][cardtail]; + if(memcmp(card_pwd, cardshmp->card_pwd, MAX_CARD_HRN_BLEN)) + { /* error password */ + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], error pwd", \ + pReq->msisdn); + err_code = ERR_REST_INVALID_RECHARGE_PWD; + goto fail; + } + + if(cardshmp->card_status != CARD_FRESH) + { + SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], card already used", \ + pReq->msisdn); + err_code = ERR_REST_INVALID_RECHARGE_PWD; + goto fail; + } + + if(cardshmp->expiry_date < time(NULL)) + { + SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], card expired", \ + pReq->msisdn); + err_code = ERR_REST_INVALID_RECHARGE_PWD; + goto fail; + } + + int balance = (int)GetAccountBalance(user_info.head, user_info.tail); + if ((balance + cardshmp->face_value) >= ppsParam.serviceControl.maxBalance) + { + SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); + DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], balance[%d] exceed maximum[%d]", \ + pReq->msisdn, (balance + cardshmp->face_value), ppsParam.serviceControl.maxBalance); + err_code = ERR_REST_UNABLE_TO_COMPLY; + sprintf(sms_msg, "%s", "Recharge failed, you have exceeded your maximum balance."); + smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, strlen(sms_msg), 0); + goto fail; + } + + // update balance + float amount = (float)cardshmp->face_value; + UpdateAccountBalance(user_info.head, user_info.tail, amount); + + // update card + cardshmp->card_status = CARD_USED; + cardshmp->updated_date = tvnow.tv_sec; + strcpy(cardshmp->msisdn_used, pReq->msisdn); + SendPrepaidCardRealSync(cardsqu*MAX_CARD_NUM_PSEG+cardtail, 5);//delete + pps_real_update_card_file(cardsqu, cardtail); + // + + // send cdr===================================================== + SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_SUCCESS, (int)cardshmp->face_value); + + // update status + COSTable *cosTableItem = &ppsParam.ppsTables.cosTable[user_info.cos_id]; + if (T_FRESH == user_info.status) + { + // update first used date + int index; + int mo_valid_time = cardshmp->valid_time, mt_valid_time = cardshmp->valid_time; + _prepaid_data *shmp = &ramshm_ptr->prepaid_data; + if((index=GetCardSystemParam(user_info.cos_id, (u_short)cardshmp->face_value))>=0){ + mo_valid_time = cosTableItem->rechargeCardValidity[index].moValidity; + mt_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; + } + + shmp->prepaid_info[user_info.head][user_info.tail].mo_expiration_date = + mo_valid_time*24*60*60 + tvnow.tv_sec; + shmp->prepaid_info[user_info.head][user_info.tail].mt_expiration_date = + mt_valid_time*24*60*60 + tvnow.tv_sec; + // + + UpdateAccountFirstUsedDate(user_info.head, user_info.tail); + UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); + } + else + { + UpdateExpirationForRechargeCard(&user_info, cardshmp->valid_time, (u_short)cardshmp->face_value); + UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); + } + // + + // promotion + int promo_balance = 0; + if(IsPromotionTime(cosTableItem, tvnow)) + { + int promo_balance = GetPromotionAmount(cosTableItem, (int)cardshmp->face_value); + if(promo_balance !=0) + { + UpdateAccountPromotionBalance(user_info.head, user_info.tail, (float)promo_balance); + UpdateAccountPromotionExpiryDay(user_info.head, user_info.tail, GetPromotionDay(cosTableItem, cardshmp->face_value)); + + // send cdr========================================================================== + //shmp->cdr_info.answertime = tvnow.tv_sec + 1; + SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_SUCCESS, promo_balance); + } + } + // + + // Sync + u32 instance = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; + ResetAccountRechargeFail(user_info.head, user_info.tail); + resetCMBTimes(&user_info); + SendAccountRealSync(instance, amount, promo_balance, OMC_OCODE_EDIT); + + // send notification sms + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenRecharge) + { + SendAccountInfoBySMPP(&user_info, ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + } + + // set respons msg + pRsp->balance = GetBalance(&user_info); + pRsp->rechargeAmount = (u32)cardshmp->face_value; + pRsp->expiredTime = (u64)GetExpiration(&user_info); + + goto out; + +fail: + // send cdr========================================================== + //SendRechargeCDR(proc_id, CT_RECHARGE_FAIL, 0); + UpdateAccountRechargeFail(user_info.head, user_info.tail); + int maxThreshold = GetParamRechargeAttemptLimit(); + if ((maxThreshold>0) && (maxThreshold < GetAccountRechargeFail(user_info.head, user_info.tail))) + { + UpdateAccountStatus(user_info.head, user_info.tail, T_BLACKLIST); + ResetAccountRechargeFail(user_info.head, user_info.tail); + } + instance = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; + SendAccountRealSync(instance, 0.0, 0.0, OMC_OCODE_EDIT); + +out: + // send response msg================ + rest_rsp.msg_type = REST_RECHARGE_CARD_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_RECHARGE_CARD_RSP, result[%d], recharge amount[%d], balance[%d]", \ + err_code, pRsp->rechargeAmount, pRsp->balance); + } + + len = encode_rest_recharge_card_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +static int pps_handle_check_balance_req(_rest_msg_s *rest_req) +{ + _rest_check_balance_req *pReq = &rest_req->msg.check_balance_req; + + PutLogFunID("pps_handle_check_balance_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_check_balance_req(), msisdn[%s], amount[%d]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn, pReq->amount); + } + + _account_info user_info; + int flag_log_msisdn = 0; + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + _prepaid_info *pUsrInfo = NULL; + int err_code = ERR_REST_SUCCESS; + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_check_balance_req(), msisdn[%s], not found", \ + pReq->msisdn); + err_code = ERR_REST_USER_UNKNOWN;// not found + } + + // set msg + _rest_msg_s rest_rsp; + _rest_check_balance_rsp *pRsp = &rest_rsp.msg.check_balance_rsp; + memset(pRsp, 0, sizeof(_rest_check_balance_rsp)); + if (pUsrInfo != NULL) + { + if ((pUsrInfo->status != T_NORMAL) || (pUsrInfo->balance < pReq->amount)) + { + pRsp->available = 1;// not enough balance + } + else + { + pRsp->available = 0;// enough balance + } + } + // + + // send response msg================ + rest_rsp.msg_type = REST_CHECK_BALANCE_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_CHECK_BALANCE_RSP, result[%d]", err_code); + } + + u8 msg_buf[256]; + int len = encode_rest_check_balance_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +static int pps_handle_query_balance_req(_rest_msg_s *rest_req) +{ + _rest_query_balance_req *pReq = &rest_req->msg.query_balance_req; + + PutLogFunID("pps_handle_query_balance_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, pps_handle_query_balance_req(), msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); + } + + int flag_log_msisdn = 0; + _account_info user_info; + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + flag_log_msisdn = 1; + } + } + + _prepaid_info *pUsrInfo = NULL; + int err_code = ERR_REST_SUCCESS; + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_query_balance_req(), msisdn[%s], not found", \ + pReq->msisdn); + err_code = ERR_REST_USER_UNKNOWN;// not found + } + + // set msg + _rest_msg_s rest_rsp; + _rest_query_balance_rsp *pRsp = &rest_rsp.msg.query_balance_rsp; + memset(pRsp, 0, sizeof(_rest_query_balance_rsp)); + if (pUsrInfo != NULL) + { + if(pUsrInfo->status == T_NORMAL ) + { + UpdateAccountStatusFromNormalToSuspendedforExpiration(pUsrInfo, user_info.head, user_info.tail); + } + + //if (pUsrInfo->status == T_NORMAL) + { + pRsp->status = pUsrInfo->status; + pRsp->balance = (u32)pUsrInfo->balance; + pRsp->mo_expiry = (u32)pUsrInfo->mo_expiration_date; + } + } + // + + // send response msg================ + rest_rsp.msg_type = REST_QUERY_BALANCE_RSP; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_QUERY_BALANCE_RSP, result[%d]", err_code); + } + + u8 msg_buf[256]; + int len = encode_rest_query_balance_rsp(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + // + + return 0; +} + +int pps_handle_crm_sms_deliver_req(_rest_msg_s *rest_req) +{ + _rest_sms_deliver_req *pReq = &rest_req->msg.sms_deliver; + + int err_code = ERR_REST_SUCCESS; + + u8 msg_buf[256]; + int len; + + _rest_msg_s rest_rsp; + _rest_sms_deliver_res *pRsp = &rest_rsp.msg.sms_deliver_res; + + PutLogFunID("pps_handle_crm_sms_deliver_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); + } + + + // set msg + memset(pRsp, 0, sizeof(_rest_sms_deliver_res)); + + // send response msg================ + rest_rsp.msg_type = REST_CRM_SMS_DELIVER_RES; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) + { + DebugMsg(debugmib.display.asciiOut, "reply CRM_SMS_DELIVER_RSP, result[%d]", err_code); + } + + len = encode_rest_sms_deliver_res(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + + len = strlen(pReq->sms_content); + smppSendMOSM(pReq->msisdn, pps_get_service_number(HotLineNumberPosition), (u_char *)pReq->sms_content, len, 0); + + return 1; +} + +int pps_handle_crm_create_account_req(_rest_msg_s *rest_req) +{ + _rest_create_acct_req *pReq = &rest_req->msg.create_acct; + int err_code = ERR_REST_SUCCESS; + u8 msg_buf[256]; + int len, user_index=0; + _account_info user_info; + //int flag_log_msisdn = 0; + int ocode=OMC_OCODE_EDIT; + + _prepaid_info *pUsrInfo = NULL; + int dif_balance = 0; + _prepaid_info *shmp=NULL,tmpSubsData; + + _rest_msg_s rest_rsp; + _rest_create_acct_res *pRsp = &rest_rsp.msg.create_acct_res; + + PutLogFunID("pps_handle_crm_create_account_req"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); + } + + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + //flag_log_msisdn = 1; + } + } + + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + + //create it, check license + + if(debugmib.measurement.usernumber>=ppsParam.serviceControl.licenseduser) + { + DebugMsg(debugmib.display.asciiOut, + "pps_handle_crm_create_account_req(), exist users %d >= licensed user(%ld)!" , + debugmib.measurement.usernumber, + ppsParam.serviceControl.licenseduser); + + err_code = ERR_REST_NO_LICENSE; + goto ret_err; + + } + + shmp = &tmpSubsData; + memset(shmp, 0x00, sizeof(_prepaid_info)); + len = strlen(pReq->msisdn); + shmp->msisdn[MAX_MSISDN_BLEN-1] = len; + AsciiToBcd(shmp->msisdn, pReq->msisdn, (len+1)/2*2); + strcpy(shmp->pin, "123456"); + shmp->balance = pReq->balance; + shmp->mo_expiration_date = shmp->mt_expiration_date = pReq->expiry_date; + shmp->crm_info.customer_id = pReq->customer_id; + shmp->crm_info.account_id = pReq->account_id; + shmp->crm_info.product_id = pReq->product_id; + shmp->crm_info.base_plan_id = pReq->plan_id; + shmp->crm_info.user_class = pReq->user_class; + shmp->crm_info.birthday = pReq->birthday; + shmp->crm_info.rent_charge = pReq->rent_charge; + shmp->cug_id = pReq->cug_id; + shmp->status = T_NORMAL; + dif_balance = pReq->balance; + + user_index = AddPPSSubsData(shmp); + + ocode = OMC_OCODE_ADD; + + DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_create_account_req(), msisdn[%s], not found", \ + pReq->msisdn); + + + } + else + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_create_account_req(), msisdn[%s], already exsits", \ + pReq->msisdn); + //update + dif_balance = pReq->balance - pUsrInfo->balance; + + pps_update_user_info_for_crm_create_account(pUsrInfo, + pReq->customer_id, + pReq->account_id, + pReq->product_id, + pReq->plan_id, + pReq->balance, + pReq->expiry_date, + pReq->rent_charge, + pReq->birthday, + pReq->cug_id); + user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; + ocode = OMC_OCODE_EDIT; + + } + + //sync... + if(1) + { + int head = user_index / UNIT_STORE_ACCOUNT; + int tail = user_index % UNIT_STORE_ACCOUNT; + + if(dif_balance != 0) + { + SendOperatorRechargeCDR(head,tail,dif_balance); + AccountLatchFlagCheck(head,tail); + pps_real_update_user_file(head, tail); + } + + SendAccountRealSync(user_index,dif_balance,0,ocode); + } + +ret_err: + // set msg + memset(pRsp, 0, sizeof(_rest_create_acct_res)); + + // send response msg================ + rest_rsp.msg_type = REST_CRM_CREATE_ACCT_RES; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) + { + DebugMsg(debugmib.display.asciiOut, "reply CRM_CREATE_ACCOUNT_RSP, result[%d]", err_code); + } + + len = encode_rest_create_account_res(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + + + if(0)//CRM should send a Welcome message to new created user + { + char sms_content[256]; + strcpy(sms_content, (char *)getSmsSentenceNative(0,SMS_ACTIVATION_NOTIFY)); + len = strlen(sms_content); + smppSendMOSM(pReq->msisdn, pps_get_service_number(HotLineNumberPosition), (u_char *)sms_content, len, 0); + } + + + return 1; +} + + +int pps_handle_crm_query_tariff_res(_rest_msg_s *rest_res) +{ + int portid; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_query_tariff_res *pRes = &rest_res->msg.query_tariff_res; + + PutLogFunID("pps_handle_crm_query_tariff_res"); + + portid = rest_res->header.dst_ref; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += portid; + + if(shmp->process_info.rest_if.query_tariff_status != 1) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, port[%d] is not waiting for query tariff result", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, portid); + } + + return -1; + } + + if(pRes->result != 0) + { + shmp->process_info.rest_if.query_tariff_status = 3; //not found + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, no data tariff errcode[%d]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pRes->error_code); + } + + return 0; + } + + { + shmp->process_info.rest_if.query_tariff_status = 2; //succeed + + /* + shmp->process_info.tariff.unit_time = pRes->unit_time; + shmp->process_info.tariff.tierRating.tierNumber = 0; + shmp->process_info.tariff.tierRating.rating[0].base_fee = pRes->unit_charge; + */ + + shmp->process_info.rest_if.unit = pRes->unit_time; + shmp->process_info.rest_if.unit_charge = pRes->unit_charge*1.0/100.0; //in CRM, the unit is *100 for better precision + shmp->process_info.rest_if.tariff_discount = pRes->discount; + shmp->process_info.rest_if.plan_id = pRes->plan_id; + shmp->process_info.rest_if.bundle_plan_id = pRes->bundle_plan_id; + shmp->process_info.rest_if.total_plan_value = pRes->total_plan_value; + shmp->process_info.rest_if.used_plan_value = pRes->used_plan_value; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, port[%d] tariff: %d*%6.3f * %d, %lld-%lld", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, portid, + pRes->unit_time, shmp->process_info.rest_if.unit_charge, pRes->discount, + pRes->total_plan_value, pRes->used_plan_value); + } + + + } + + return 1; +} + +int pps_handle_crm_update_subs(_rest_msg_s *rest_req) +{ + _rest_update_subs_req *pReq = &rest_req->msg.update_subs; + int err_code = ERR_REST_SUCCESS; + u8 msg_buf[256]; + int len, user_index=0; + _account_info user_info; + //int flag_log_msisdn = 0; + int ocode=OMC_OCODE_EDIT; + + _prepaid_info *pUsrInfo = NULL; + int dif_balance = 0; + //_prepaid_info *shmp=NULL;//,tmpSubsData; + + _rest_msg_s rest_rsp; + _rest_update_subs_res *pRsp = &rest_rsp.msg.update_subs_res; + + PutLogFunID("pps_handle_crm_update_subs"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); + } + + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + //flag_log_msisdn = 1; + } + } + + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + + + DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_update_subs(), msisdn[%s], not found", \ + pReq->msisdn); + err_code = ERR_REST_USER_UNKNOWN; + goto ret_err; + + + } + else + { + DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_update_subs(), msisdn[%s]", \ + pReq->msisdn); + + if((pReq->optional_flag & 0x01) == 0x01) + pUsrInfo->status = pReq->status; //check if valid status + if((pReq->optional_flag & 0x02) == 0x02) + { + pUsrInfo->balance = pReq->balance; + dif_balance = pReq->balance - pUsrInfo->balance; + } + if((pReq->optional_flag & 0x04) == 0x04) + pUsrInfo->mo_expiration_date = pUsrInfo->mt_expiration_date = pReq->balance_expiry_date; + if((pReq->optional_flag & 0x08) == 0x08) + pUsrInfo->crm_info.new_plan_id = pReq->basic_plan_id; + if((pReq->optional_flag & 0x10) == 0x10) + pUsrInfo->crm_info.new_rent_charge = pReq->basic_plan_rent; + if((pReq->optional_flag & 0x20) == 0x20) + pUsrInfo->crm_info.vas_cug_state = pReq->vas_cug_status; + + user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; + ocode = OMC_OCODE_EDIT; + + } + + //sync... + if(1) + { + int head = user_index / UNIT_STORE_ACCOUNT; + int tail = user_index % UNIT_STORE_ACCOUNT; + + if(dif_balance != 0) + { + SendOperatorRechargeCDR(head,tail,dif_balance); + AccountLatchFlagCheck(head,tail); + pps_real_update_user_file(head, tail); + } + + SendAccountRealSync(user_index,dif_balance,0,ocode); + } + +ret_err: + // set msg + memset(pRsp, 0, sizeof(_rest_update_subs_res)); + + // send response msg================ + rest_rsp.msg_type = REST_CRM_UPDATE_SUBS_RES; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) + { + DebugMsg(debugmib.display.asciiOut, "reply CRM_UPDATE_SUBS_RSP, result[%d]", err_code); + } + + len = encode_rest_update_subs_res(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + + return 1; +} + +int pps_handle_crm_delete_subs(_rest_msg_s *rest_req) +{ + _rest_delete_subs_req *pReq = &rest_req->msg.delete_subs; + int err_code = ERR_REST_SUCCESS; + u8 msg_buf[256]; + int len, user_index=0; + _account_info user_info; + //int flag_log_msisdn = 0; + int ocode=OMC_OCODE_DEL; + + _prepaid_info *pUsrInfo = NULL; + int dif_balance = 0; + + _rest_msg_s rest_rsp; + _rest_delete_subs_res *pRsp = &rest_rsp.msg.delete_subs_res; + + PutLogFunID("pps_handle_crm_delete_subs"); + + // log message + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); + } + + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + //flag_log_msisdn = 1; + } + } + + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + + + DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], not found", __FUNCTION__, pReq->msisdn); + err_code = ERR_REST_USER_UNKNOWN; + goto ret_err; + + + } + else + { + DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], found", __FUNCTION__, pReq->msisdn); + + dif_balance = pUsrInfo->balance; + + user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; + ocode = OMC_OCODE_DEL; + } + + //sync... + if(1) + { + int head = user_index / UNIT_STORE_ACCOUNT; + int tail = user_index % UNIT_STORE_ACCOUNT; + + if(dif_balance != 0) + { + SendOperatorRechargeCDR(head, tail, 0-dif_balance); + // pps_real_update_user_file(head, tail); + } + + SendAccountRealSync(user_index, 0-dif_balance, 0, ocode); + + DeletePPSSubsData(pUsrInfo); + + } + +ret_err: + // set msg + memset(pRsp, 0, sizeof(_rest_delete_subs_res)); + + // send response msg================ + rest_rsp.msg_type = REST_CRM_UPDATE_SUBS_RES; + rest_rsp.header.dst_ref = rest_req->header.src_ref; + rest_rsp.header.src_ref = rest_req->header.dst_ref; + pRsp->error_code = err_code; + if (err_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + } + else + { + pRsp->result = RES_SUCCEED; + } + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) + { + DebugMsg(debugmib.display.asciiOut, "reply CRM_DELETE_SUBS_RSP, result[%d]", err_code); + } + + len = encode_rest_delete_subs_res(&rest_rsp, msg_buf); + pps_send_rest_msg(msg_buf, len); + + return 1; +} + +int pps_handle_crm_rent_charge(_rest_msg_s *rest_req) +{ + _rest_rent_charge_req *pReq = &rest_req->msg.rent_charge; + + int user_index=0; + _account_info user_info; + //int flag_log_msisdn = 0; + int charge; + + _prepaid_info *pUsrInfo = NULL; + + PutLogFunID("pps_handle_crm_rent_charge"); + + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) + { + DebugMsg(debugmib.display.asciiOut, + " TS: %ld.%03d, %s, msisdn[%s]", \ + tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); + } + + strcpy((char *)user_info.number, pReq->msisdn); + if(logMsgFlag & 0x08) + { + if(strstr((char *)user_info.number, logMsisdn)) + { + //flag_log_msisdn = 1; + } + } + + if ((GetAccountPos(&user_info) == FALSE) + || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) + { + + + DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], not found", __FUNCTION__, pReq->msisdn); + return 0; + + } + else + { + + charge = pReq->rent_charge; + + user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; + + DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], found, charge=%d", __FUNCTION__, pReq->msisdn, charge); + } + + //sync... + if(1) + { + int head = user_index / UNIT_STORE_ACCOUNT; + int tail = user_index % UNIT_STORE_ACCOUNT; + + UpdateAccountCUGStatus(pUsrInfo, 0); + UpdateAccountBalance(head, tail, -charge); + SendAccountRealSync(user_index,-charge, 0.0, OMC_OCODE_EDIT); + SendPeriodicChargeCDR(head,tail, charge, CT_RENT_CHARGE_TYPE0); + + } + + return 1; +} + +/*----------------------------------------------------------*/ + +int pps_rest_recv_proxy() +{ + int loop, retval, portid=0; + message_list msgGet; + _rest_msg_s rest_msg; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + for(loop = 0; loop<5; loop++) + { + if(iptrGetMessage( &msgGet, REST_PROXY_PORT) <=0 ) + return 0; + + retval = decode_rest_api_msg( msgGet.msgContent, + msgGet.msgLength, + &rest_msg); + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m Get RestProxy API: type=%d, retval=%d, dst ref=%d\33[0m", + rest_msg.msg_type, retval, rest_msg.header.dst_ref); + } + + if(retval <= 0) + { + continue; + } + + if ((rest_msg.msg_type == REST_QUERY) || (rest_msg.msg_type == REST_TOPUP) + || (rest_msg.msg_type == REST_TRANSFER) || (rest_msg.msg_type == REST_ORDER) + || (rest_msg.msg_type == REST_FREE_RESOURCE) || (rest_msg.msg_type == REST_CHANNEL) + || (rest_msg.msg_type == REST_POINT_QUERY) || (rest_msg.msg_type == REST_POINT_TRANSFER) + )// Alepo + { + portid = rest_msg.header.dst_ref; + if ((portid < 0) || (portid >= MAX_FSM_PROCESS)) + continue; + shmp = (_state_data *) smshm_ptr->state_data; + shmp += portid; + shmp->process_info.rest_if.recv_cmd = 1; + if(rest_msg.msg_type == REST_QUERY) + { + shmp->process_info.rest_if.result = rest_msg.msg.query_res.result; + shmp->process_info.rest_if.error_code = rest_msg.msg.query_res.error_code; + if ((rest_msg.msg.query_res.balance & 0x80000000) != 0) + { + shmp->process_info.rest_if.balance = rest_msg.msg.query_res.balance & 0x7fffffff; + shmp->process_info.rest_if.balance = -shmp->process_info.rest_if.balance; + } + else + { + shmp->process_info.rest_if.balance = rest_msg.msg.query_res.balance; + } + shmp->process_info.rest_if.mo_expiry_date = rest_msg.msg.query_res.mo_expiry; + shmp->process_info.rest_if.mt_expiry_date = rest_msg.msg.query_res.mt_expiry; + } + else if(rest_msg.msg_type == REST_TOPUP) + { + shmp->process_info.rest_if.result = rest_msg.msg.topup_res.result; + shmp->process_info.rest_if.error_code = rest_msg.msg.topup_res.error_code; + shmp->process_info.rest_if.balance = rest_msg.msg.topup_res.balance; + shmp->process_info.rest_if.mo_expiry_date = rest_msg.msg.topup_res.mo_expiry; + shmp->process_info.rest_if.mt_expiry_date = rest_msg.msg.topup_res.mt_expiry; + } + else if(rest_msg.msg_type == REST_TRANSFER) + { + shmp->process_info.rest_if.result = rest_msg.msg.transfer_rsp.result; + shmp->process_info.rest_if.error_code = rest_msg.msg.transfer_rsp.error_code; + } + else if(rest_msg.msg_type == REST_CHANNEL) + { + shmp->process_info.rest_if.result = rest_msg.msg.chnl_res.result; + shmp->process_info.rest_if.error_code = rest_msg.msg.chnl_res.error_code; + shmp->process_info.ppsService.chnl_info.sess_state = rest_msg.msg.chnl_res.sess_state; + strcpy(shmp->process_info.ppsService.chnl_info.prompt, rest_msg.msg.chnl_res.prompt); + } + else if(rest_msg.msg_type == REST_POINT_QUERY) + { + shmp->process_info.rest_if.result = rest_msg.msg.queryPoint_res.result; + shmp->process_info.rest_if.error_code = rest_msg.msg.queryPoint_res.error_code; + shmp->process_info.rest_if.unit = rest_msg.msg.queryPoint_res.amount; + shmp->process_info.rest_if.balance = rest_msg.msg.queryPoint_res.airtime_amount; + } + else if(rest_msg.msg_type == REST_POINT_TRANSFER) + { + shmp->process_info.rest_if.result = rest_msg.msg.queryPoint_res.result; + shmp->process_info.rest_if.error_code = rest_msg.msg.queryPoint_res.error_code; + } + } + else// Selfcare + { + switch (rest_msg.msg_type) + { + case REST_SEND_AUTHCODE_REQ: + pps_handle_send_authcode_req(&rest_msg); + break; + case REST_QUERY_USERDATA_REQ: + pps_handle_query_userdata_req(&rest_msg); + break; + case REST_BUNDLE_SUBS_REQ: + pps_handle_bundle_subs_req(&rest_msg); + break; + case REST_BUNDLE_USAGE_REQ: + pps_handle_bundle_usage_req(&rest_msg); + break; + case REST_RECHARGE_REQ: + pps_handle_recharge_req(&rest_msg); + break; + case REST_TRANSFER_REQ: + pps_handle_transfer_req(&rest_msg); + break; + case REST_RECHARGE_CARD_REQ: + pps_handle_recharge_card_req(&rest_msg); + break; + case REST_CHECK_BALANCE_REQ: + pps_handle_check_balance_req(&rest_msg); + break; + case REST_QUERY_BALANCE_REQ: + pps_handle_query_balance_req(&rest_msg); + break; + case REST_CRM_SMS_DELIVER_REQ: + pps_handle_crm_sms_deliver_req(&rest_msg); + break; + case REST_CRM_CREATE_ACCT_REQ: + pps_handle_crm_create_account_req(&rest_msg); + break; + case REST_CRM_QUERY_TARIFF_RES: + pps_handle_crm_query_tariff_res(&rest_msg); + break; + case REST_CRM_UPDATE_SUBS_REQ: + pps_handle_crm_update_subs(&rest_msg); + break; + case REST_CRM_DELETE_SUBS_REQ: + pps_handle_crm_delete_subs(&rest_msg); + break; + case REST_CRM_RENT_CHARGE: + pps_handle_crm_rent_charge(&rest_msg); + break; + default: + break; + } + } + } + + return 1; +} + +int pps_rest_query_process(u_short portid) +{ + int retval = 0 ,result; + char ussd_data[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(shmp->process_info.rest_if.timer ++ > 20*CYCLE_STATE_INTERVAL) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_QUERY_CODE_STR, USSDCODE_TYPE_QUERY, USSDCODE_STAT_ERR_TIMEOUT, 0); +#endif + return -1; + } + + switch(shmp->process_info.sub_state_2) + { + case 0: +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_QUERY_CODE_STR, USSDCODE_TYPE_QUERY, USSDCODE_STAT_REQ, 0); +#endif + pps_send_rest_query_req(portid); + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 1; + break; + case 1: + if(shmp->process_info.rest_if.recv_cmd == 0) + break; + result = shmp->process_info.rest_if.result; + if(result == 0) + { + retval = 1; + + if(shmp->process_info.rest_if.rest_oc == 1) //recharge and query + { + char tmp_ussd_data[256]; + + GetAccountRestInfo(portid, tmp_ussd_data); + sprintf(ussd_data, "Refill succeed. %s", tmp_ussd_data); + + } + else + { + GetAccountRestInfo(portid, ussd_data); + } + } + else + { + retval = -1; + + sprintf(ussd_data, "Operation failed, the number %s is not a prepaid subscriber.", shmp->caller_info.number); + } + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , recv query_res, result=%d\33[0m", + portid, result); + } + if(shmp->process_info.rest_if.rest_src == 0) //from USSD + { + SendPSSREnd(portid, ussd_data); + } + else if(shmp->process_info.rest_if.rest_src == 1 ) //from SMPP + { + smppSendMOSM((char *)shmp->caller_info.number, (char *)shmp->origin_info.number, (u_char *)ussd_data, strlen(ussd_data), 0); + + } + else if(shmp->process_info.rest_if.rest_src == 2) //from voice + { + //SendPSSREnd(portid, ussd_data); + } + + break; + default: + retval = -1; + break; + + } + + return retval; +} + +int pps_send_rest_topup_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_TOPUP; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + strcpy(rest_msg.msg.topup.msisdn, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.topup.username, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.topup.password, (char *)shmp->called_info.number); + strcpy(rest_msg.msg.topup.pincode, (char *)shmp->process_info.tmpNumber); + + len = encode_rest_topup(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_rest_channel_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *)smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_CHANNEL; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + strcpy(rest_msg.msg.chnl.msisdn, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.chnl.input, (char *)shmp->process_info.ppsService.chnl_info.input); + strncpy(rest_msg.msg.chnl.sc_url, (char *)shmp->process_info.ppsService.chnl_info.scUrl, 127); + strncpy(rest_msg.msg.chnl.sess_id, (char *)shmp->process_info.ppsService.chnl_info.sessId, 63); + + len = encode_rest_channel(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_rest_order_req(u_short portid, u32 busicode) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_ORDER; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = 0xffff;//portid; + rest_msg.msg.order.busicode = busicode;// recharge: 1000, order: 1001, cancel: 1002 + rest_msg.msg.order.offer_id = shmp->process_info.rest_if.bundle_plan_id; + rest_msg.msg.order.paymethod = shmp->process_info.rest_if.plan_id | (shmp->process_info.rest_if.unit << 8); + + rest_msg.msg.order.pincode[0] = '\0'; + rest_msg.msg.order.callerMsisdn[0] = '\0'; + if (shmp->process_info.routing_number[0] != '\0') + { + strcpy(rest_msg.msg.order.msisdn, (char *)shmp->process_info.routing_number); + strcpy(rest_msg.msg.order.payMsisdn, (char *)shmp->caller_info.number); + if (busicode == 1000)// recharge airtime, buy for other + { + strcpy(rest_msg.msg.order.callerMsisdn, (char *)shmp->caller_info.number); + } + } + else + { + strcpy(rest_msg.msg.order.msisdn, (char *)shmp->caller_info.number); + rest_msg.msg.order.payMsisdn[0] = '\0'; + } + if (shmp->process_info.rest_if.plan_id == 10)// mobile money + { + strcpy(rest_msg.msg.order.payMsisdn, shmp->process_info.tmpDigits); + } + rest_msg.msg.order.balance = (u32)shmp->process_info.rest_if.balance; + + len = encode_rest_order(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_rest_free_resource_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_FREE_RESOURCE; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = 0xffff;//portid; + strcpy(rest_msg.msg.free_resource.msisdn, (char *)shmp->caller_info.number); + + len = encode_rest_free_resource(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_rest_download_app_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_DOWNLOAD_APP; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = 0xffff;//portid; + strcpy(rest_msg.msg.downloadApp.msisdn, (char *)shmp->caller_info.number); + + len = encode_rest_downloadApp(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_rest_offer_change_req(u_short portid, u8 flag_opt_out) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_OFFER_CHANGE; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = 0xffff;//portid; + strcpy(rest_msg.msg.offerChange.msisdn, (char *)shmp->caller_info.number); + rest_msg.msg.offerChange.opt_out = flag_opt_out; + + len = encode_rest_offerChange(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_rest_point_query_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_POINT_QUERY; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + strcpy(rest_msg.msg.queryPoint.msisdn, (char *)shmp->caller_info.number); + + len = encode_rest_queryPoint(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_rest_point_transfer_req(u_short portid, u32 busicode) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_POINT_TRANSFER; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid;//0xffff; + strcpy(rest_msg.msg.transferPoint.msisdn, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.transferPoint.target_msisdn, (char *)shmp->process_info.routing_number); + rest_msg.msg.transferPoint.amount = shmp->process_info.rest_if.unit; + rest_msg.msg.transferPoint.busicode = busicode; + + len = encode_rest_transferPoint(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_send_selfcare_topup_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_UPDATE_RECHARGE_CARD_REQ; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + strcpy(rest_msg.msg.topup.msisdn, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.topup.username, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.topup.password, (char *)shmp->called_info.number); + if(1) + { + rest_msg.msg.topup.optional_flag = 0x03; + rest_msg.msg.topup.account_id = 10024; + rest_msg.msg.topup.balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + + } + + len = encode_rest_topup(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; +} + +int pps_rest_topup_process(u_short portid) +{ + int retval = 0, /*len, error_input = 0, */result; + //u_char data_flow[256], service_type=0; + char ussd_data[256];//, ussd_sc[256], ussd_param[256]; + //MapComSrv_struct com_data; + //MapOprSrv_struct opr_srv; + //COSTable *cosTableItem; + + //struct MapPUSSR_Arg *pussr_arg; + //struct MapUSSR_Res *ussr_ack; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(shmp->process_info.rest_if.timer ++ > 20*CYCLE_STATE_INTERVAL) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_TIMEOUT, 0); +#endif + return -1; + } + + switch(shmp->process_info.sub_state_2) + { + case 0: + pps_send_rest_topup_req(portid); + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 1; + break; + case 1: + if(shmp->process_info.rest_if.recv_cmd == 0) + break; + result = shmp->process_info.rest_if.result; + if(result == 0) + { + //char tmp_ussd_data[256]; + if(0) + { + shmp->process_info.sub_state_2 = 2; + shmp->process_info.wait_timer = 0; + return 0; + } + //GetAccountRestInfo(portid, tmp_ussd_data); + //sprintf(ussd_data, "You successfully "); + sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_GPRS_RECHARGE_SUCCESS)); + + } + else + { + //sprintf(ussd_data, "Operation failed, wrong password, please check and try again!"); + sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_RECHARGE_FAILED_NO_CARD)); + } + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , recv topup_res, result=%d\33[0m", + portid, result); + } + + if( shmp->process_info.rest_if.rest_src == 0) // recharge by USSD + { + SendPSSREnd(portid, ussd_data); + } + else if( shmp->process_info.rest_if.rest_src == 1) // recharge by SMPP + { + smppSendMOSM((char *)shmp->caller_info.number, (char *)shmp->origin_info.number, (u_char *)ussd_data, strlen(ussd_data), 0); + } + else if( shmp->process_info.rest_if.rest_src == 2) // recharge by Voice + { + // + } + + retval = 1; + break; + case 2: + if(shmp->process_info.wait_timer ++ >= 1*CYCLE_STATE_INTERVAL) //wait for 1second to send GET + { + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + if( shmp->process_info.rest_if.rest_src == 0) // recharge by USSD + { + shmp->process_info.sub_state = S_MAP_REST_QUERY; + } + else if( shmp->process_info.rest_if.rest_src == 1) // recharge by SMPP + { + shmp->process_info.sub_state = S_SMPP_REST_QUERY; + } + else //recharge by voice + shmp->process_info.sub_state = S_MAP_REST_QUERY; + + shmp->process_info.sub_state_2 = 0; + shmp->process_info.wait_timer = 0; + shmp->process_info.rest_if.rest_oc = 1; + } + break; + default: + retval = -1; + break; + } + + + return retval; + +} + + +int pps_send_rest_transfer_req(u_short portid) +{ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_TRANSFER; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + strcpy(rest_msg.msg.transfer_req.transferOutMsisdn, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.transfer_req.transferInMsisdn, (char *)shmp->process_info.ppsService.feeTransfer.account.number); + rest_msg.msg.transfer_req.amount = shmp->process_info.ppsService.feeTransfer.fee;; + + len = encode_rest_transfer_req(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} + +int pps_rest_transfer_process(u_short portid) +{ + int retval = 0, result; + int op_src = 0; + char ussd_data[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(shmp->process_info.rest_if.timer ++ > 20*CYCLE_STATE_INTERVAL) + { + return -1; + } + + switch(shmp->process_info.sub_state_2) + { + case 0: + pps_send_rest_transfer_req(portid); + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 1; + break; + case 1: + if(shmp->process_info.rest_if.recv_cmd == 0) + break; + result = shmp->process_info.rest_if.result; + op_src = shmp->process_info.rest_if.rest_src; + + + if(result == 0) + { + + SendTransferSuccessRequest(portid, op_src); + + } + else + { + sprintf(ussd_data, "Operation failed, please check and try again!"); + + if(op_src == 0) + SendPSSREnd(portid, (char *)ussd_data); + else + smppSendMsg(shmp->caller_info.number, (u_char *)ussd_data, FeeTransferPosition); + + } + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , recv transfer_res, result=%d\33[0m", + portid, result); + } + + retval = 1; + break; + default: + retval = -1; + break; + } + + + return retval; + +} + +int RechargeSucceedwithCRM(u_short portid) +{ + int retval = S_IDLE,promo_balance=0; + DWORD instance=0; + //_account_info tmp_info; + _state_data *shmp; + COSTable *cosTableItem; + + if(portid>=MAX_FSM_PROCESS) return 0; + + PutLogFunID("RechargeRequestProc"); + + shmp=(_state_data *)&smshm_ptr->state_data; + shmp += portid; + retval = shmp->process_info.state; + + + UpdateBalanceForRecharge(&shmp->caller_info, shmp->process_info.rest_if.balance); + + SendRechargeCDR( portid, CT_RECHARGE_SUCCESS, shmp->process_info.rest_if.balance); + + if(T_FRESH == GetAccountStatus(&shmp->caller_info) ) + { + UpdateAccountFirstUsedDate(shmp->caller_info.head, shmp->caller_info.tail); + } + UpdateAccountStatus(shmp->caller_info.head, shmp->caller_info.tail, T_NORMAL); + UpdateAccountExpiration(shmp->caller_info.head, shmp->caller_info.tail, shmp->process_info.rest_if.balance, shmp->process_info.rest_if.mo_expiry_date); + + // promotion + cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; + if(IsPromotionTime(cosTableItem,tvnow)) + { + promo_balance = GetPromotionAmount(cosTableItem,shmp->process_info.rest_if.balance); + if(promo_balance !=0) + { + shmp->cdr_info.answertime = tvnow.tv_sec + 1; + UpdateAccountPromotionBalance(shmp->caller_info.head, shmp->caller_info.tail, (float)promo_balance); + UpdateAccountPromotionExpiryDay( + shmp->caller_info.head, + shmp->caller_info.tail, + GetPromotionDay(cosTableItem,shmp->process_info.rest_if.balance) + ); + SendRechargeCDR( portid, CT_RECHARGE_SUCCESS, GetPromotionAmount(cosTableItem,shmp->process_info.rest_if.balance)); + } + } + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + ResetAccountRechargeFail(shmp->caller_info.head, shmp->caller_info.tail); + resetCMBTimes(&shmp->caller_info); + SendAccountRealSync(instance,shmp->process_info.rest_if.balance,promo_balance,OMC_OCODE_EDIT); + + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenRecharge) + { + if(shmp->process_info.serviceType == SRV_RECHARGE_ONE_INPUT) + SendAccountInfoBySMPP(&shmp->caller_info, + ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + else + SendAccountInfoBySMPP(&shmp->caller_info, + ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); + } + + return retval; +} + +int pps_bundle_plan_process(u_short portid) +{ + char ussd_data[1024]; + int retval = 0, result=0; + int key_input; + //int cos_bundle_control=0; + + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(shmp->process_info.funnel ++ > 50*CYCLE_STATE_INTERVAL) + { + return -1; + } + + switch(shmp->process_info.sub_state_2 ) + { + case 0: + subscribe_bundle_plan(shmp, shmp->process_info.tmpDigits, 1, ussd_data); + ussd_data[160] = 0; + if(strlen(ussd_data) <= 160) + { + if(1) + { + SendPSSREnd(portid, ussd_data); + retval = 1; + } + else + { + SendUSSDRequest(portid, ussd_data); + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + retval = 0; + } + } + break; + case 1: + retval = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(retval >= 1) + { + subscribe_bundle_plan(shmp, shmp->process_info.tmpDigits, 1, ussd_data); + ussd_data[160] = 0; + SendPSSREnd(portid, ussd_data); + } + break; + case 2: + result = ocs_bundle_plan_query(shmp, shmp->process_info.tmpDigits, 1, ussd_data); + ussd_data[160] = 0; + if(1) + //if(result == 0) + { + SendPSSREnd(portid, ussd_data); + retval = 1; + } + else + { + SendUSSDRequest(portid, ussd_data); + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + retval = 0; + } + break; + case 5://send sub-menu of bundle plan + //cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); + if(shmp->process_info.serviceKey == 6)// data plan only + sprintf(ussd_data, "%s", getSmsSentenceNative(0,SMS_BUNDLE_PLAN_USSD_MENU)); + else + sprintf(ussd_data, "%s", getSmsSentenceNative(0,SMS_BUNDLE_PLAN_USSD_MENU1)); + + if(shmp->process_info.serviceInput ++ > 3) + { + SendPSSRResponse(portid); + return 1; + } + SendUSSDRequest(portid, ussd_data); + shmp->process_info.sub_state_2 = 6; + shmp->process_info.funnel = 0; + break; + case 6: + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + shmp->process_info.sub_state_2 = 5; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + shmp->process_info.sub_state_2 = 5; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + shmp->process_info.sub_state_2 = 7; //inquiry + break; + case 2: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 8; //subscribe + break; + case 0: + default: + SendPSSRResponse(portid); + retval = 1; + break; + } + } + } + else if(result == -1) + { + SendPSSRResponse(portid); + retval = 1; + } + break; + case 7: + result = ocs_bundle_plan_query(shmp, shmp->process_info.tmpDigits, 1, ussd_data); + ussd_data[160] = 0; + if(result == 0) + { + SendPSSREnd(portid, ussd_data); + retval = 1; + } + else + { + sprintf(ussd_data, "%s", getSmsSentenceNative(0,SMS_BUNDLE_PLAN_NOT_APPLIED)); + SendPSSREnd(portid, ussd_data); + retval = 1; + } + break; + case 8:// ussd adaptor enter here + if(shmp->process_info.serviceInput ++ > 3) + { + SendPSSRResponse(portid); + return 1; + } + subscribe_bundle_plan_query_info(shmp, 0, 2, ussd_data); + SendUSSDRequest(portid, ussd_data); + shmp->process_info.sub_state_2 = 9; + shmp->process_info.funnel = 0; + break; + case 9: + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 2) + { + shmp->process_info.sub_state_2 = 8; + shmp->process_info.funnel = 0; + break; + } + + if (0)//(pps_get_adaptor_flag()) + {/* + pps_send_rest_order_req(portid);// send bundle subs req + shmp->process_info.funnel = 0; + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 11;*/ + } + else + { + result = subscribe_bundle_plan(shmp, shmp->process_info.tmpDigits, 2, ussd_data); + if(result == 1) + { + SendPSSREnd(portid, ussd_data); + retval = 1; + } + else + { + shmp->process_info.sub_state_2 = 8; + shmp->process_info.funnel = 0; + } + } + } + else if(result == -1) + { + SendPSSRResponse(portid); + retval = 1; + } + + break; + /*case 11: + if(shmp->process_info.rest_if.recv_cmd == 0) + break; + result = shmp->process_info.rest_if.result; + if(result == 0) + { + //char tmp_ussd_data[256]; + if(0) + { + shmp->process_info.sub_state_2 = 2; + shmp->process_info.wait_timer = 0; + return 0; + } + //GetAccountRestInfo(portid, tmp_ussd_data); + //sprintf(ussd_data, "You successfully "); + sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_GPRS_RECHARGE_SUCCESS)); + + } + else + { + //sprintf(ussd_data, "Operation failed, wrong password, please check and try again!"); + sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_RECHARGE_FAILED_NO_CARD)); + } + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , recv topup_res, result=%d\33[0m", + portid, result); + } + + //if( shmp->process_info.rest_if.rest_src == 0) // recharge by USSD + //{ + SendPSSREnd(portid, ussd_data); + //} + break;*/ + } + + return retval; +} + + +int pps_send_query_tariff_req(u_short portid) +{ + char prefix[32], areaName[32] = ""; + int service_type = 1; /*1=mo call, 2=sms, 3=data */ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_CRM_QUERY_TARIFF_REQ; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + + if(shmp->context_info.callType == CT_MO_CALL || shmp->context_info.callType == CT_MF_CALL) + service_type = 1; + else if(shmp->context_info.callType == CT_MT_CALL) + service_type = 1; + else if(shmp->context_info.callType == CT_MO_SM) + service_type = 3; + else//data + service_type = 2; + + rest_msg.msg.query_tariff.service_type = service_type; + + if(service_type != 2) + { + if(ocs_get_charge_prefix( (char *)shmp->charge_info.number, prefix, areaName, &shmp->process_info.tariff.call_type) == 0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , ocs_get_charge_prefix() failed, charge_number=%s \33[0m", + portid, shmp->charge_info.number); + } + + return 0; + } + strncpy(shmp->process_info.ppsService.areaName, areaName, 31); + } + else + {//CRM bug, data billing must take a area_code... + memcpy(prefix, shmp->caller_info.number, 5); + prefix[5] = 0; + } + + if(service_type == 1) + shmp->process_info.call_type = shmp->process_info.tariff.call_type; + +#ifdef OCS_USE_REDIS_DB// get tariff and bundle + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d], prefix[%s] caller=%s charge_number=%s, srv_type=%d", + portid, prefix, shmp->caller_info.number, shmp->charge_info.number, service_type); + } + + RedisGetTariffInfo(portid, (char *)shmp->caller_info.number, + service_type, prefix); + return 1; +#endif + shmp->process_info.rest_if.query_tariff_status = 1; //wait for result + + strcpy(rest_msg.msg.query_tariff.msisdn, (char *)shmp->caller_info.number); + strcpy(rest_msg.msg.query_tariff.called_number, prefix); + + len = encode_rest_query_tariff(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , ocs_get_charge_prefix() caller=%s charge_number=%s , srv_type=%d\33[0m", + portid, shmp->caller_info.number, shmp->charge_info.number, service_type); + } + + return 1; + +} + + +int pps_send_update_plan_value_req(u_short portid) +{ + int service_type = 1; /*1=mo call, 2=sms, 3=data */ + int len = 0; + u_char data_flow[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + _rest_msg_s rest_msg; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + shmp += (portid); + + rest_msg.msg_type = REST_CRM_UPDATE_PLAN_INFO_REQ; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = portid; + + if(shmp->context_info.callType == CT_MO_CALL || shmp->context_info.callType == CT_MF_CALL) + service_type = 1; + else if(shmp->context_info.callType == CT_MT_CALL) + service_type = 1; + else if(shmp->context_info.callType == CT_MO_SM) + service_type = 3; + else//data + service_type = 2; + /* + if(shmp->process_info.call_type == CT_MO_CALL || shmp->process_info.call_type == CT_MF_CALL) + service_type = 0; + else if(shmp->process_info.call_type == CT_MT_CALL) + service_type = 1; + else if(shmp->process_info.call_type == CT_MO_SM) + service_type = 3; + else//data + service_type = 2; + */ +#ifdef OCS_USE_REDIS_DB + if ((shmp->process_info.rest_if.plan_value_add_this_time & 0x8000000000000000) == 0)// not refund + { + RedisUpdateUsedBundle((char *)shmp->caller_info.number, service_type, shmp->process_info.rest_if.bundle_plan_id, + shmp->process_info.rest_if.plan_value_add_this_time); + } +#endif + + strcpy(rest_msg.msg.update_plan_info.msisdn, (char *)shmp->caller_info.number); + rest_msg.msg.update_plan_info.service_type = service_type; + rest_msg.msg.update_plan_info.account_id = GetAccountID(&shmp->caller_info); + rest_msg.msg.update_plan_info.plan_id = shmp->process_info.rest_if.plan_id; + rest_msg.msg.update_plan_info.bundle_id = shmp->process_info.rest_if.bundle_plan_id; + rest_msg.msg.update_plan_info.plan_total_value = shmp->process_info.rest_if.total_plan_value; + rest_msg.msg.update_plan_info.plan_used_value = shmp->process_info.rest_if.used_plan_value; + rest_msg.msg.update_plan_info.sess_update_times = shmp->process_info.rest_if.sess_update_times++; + rest_msg.msg.update_plan_info.this_time_add_value = shmp->process_info.rest_if.plan_value_add_this_time; + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid[%04d], update_plan_value_req() caller=%s, ID[%d], total-used[%llu-%llu], this[0x%llx], srv_type=%d\33[0m", + portid, shmp->caller_info.number, shmp->process_info.rest_if.bundle_plan_id, shmp->process_info.rest_if.total_plan_value, + shmp->process_info.rest_if.used_plan_value, shmp->process_info.rest_if.plan_value_add_this_time, service_type); + } + len = encode_rest_update_plan_info(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); + + return 1; + +} +int query_tariff_test(u_char call_type) +{ + int portid = AssignProcID(0); + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + shmp += (portid); + sprintf((char *)shmp->caller_info.number, "%s", "672350004"); + sprintf((char *)shmp->called_info.number, "%s", "008675512345678"); + shmp->process_info.call_type = call_type; + shmp->process_info.state = S_CRM_QUERY_TARIFF_TEST; + + pps_send_query_tariff_req(portid); + + return 1; +} + + + +int pps_crm_query_tariff_test_proc(u_short portid) +{ + int retval = 0; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + + if(shmp->process_info.funnel ++ > SSHORT_DELAY_TIMER) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d wait query tariff result timeout\33[0m", portid); + } + return -1; + } + + if(shmp->process_info.rest_if.query_tariff_status == 2) + { + retval = 1; + } + + return retval; +} + + +void pps_send_update_subs_status_to_crm(/*int head, int tail*/_prepaid_info *user_ptr, int update_flag) +{ + int len = 0; + u_char data_flow[256]; + _rest_msg_s rest_msg; + //_prepaid_info *user_ptr=NULL; + char msisdn[32]; + + //user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + + rest_msg.msg_type = REST_CRM_UPDATE_SUBS_REQ; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = 0xffff; + + if (update_flag == 1) + rest_msg.msg.update_subs.optional_flag = 0x01; + else if (update_flag == 2) + rest_msg.msg.update_subs.optional_flag = 0x04 | 0x08; + + len = user_ptr->msisdn[MAX_MSISDN_BLEN-1]; + + if(lenMAX_MSISDN_ALEN) + { + return; + } + BcdToAscii(msisdn,user_ptr->msisdn,(MAX_MSISDN_BLEN-1)*2); + msisdn[len] = 0; + strcpy(rest_msg.msg.update_subs.msisdn, msisdn); + + rest_msg.msg.update_subs.account_id = user_ptr->crm_info.account_id; + rest_msg.msg.update_subs.status = user_ptr->status; + rest_msg.msg.update_subs.basic_plan_id = user_ptr->crm_info.base_plan_id; + rest_msg.msg.update_subs.balance_expiry_date = user_ptr->mo_expiration_date; + + len = encode_rest_update_subs(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); +} + +/* +rent charge to CRM, if succeed then CRM sends payment request to OCS +if failed, CRM sends update account status with CUG status (crm_info.vas_cug_state = 1 +*/ +void pps_send_rent_charge_to_crm(int head, int tail) +{ + int len = 0; + u_char data_flow[256]; + _rest_msg_s rest_msg; + _prepaid_info *user_ptr=NULL; + char msisdn[32]; + + user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + + rest_msg.msg_type = REST_CRM_RENT_CHARGE; + rest_msg.header.dst_ref = 0x0000; + rest_msg.header.src_ref = 0xffff; + + rest_msg.msg.rent_charge.optional_flag = 0x01; + + len = user_ptr->msisdn[MAX_MSISDN_BLEN-1]; + + if(lenMAX_MSISDN_ALEN) + { + return; + } + BcdToAscii(msisdn,user_ptr->msisdn,(MAX_MSISDN_BLEN-1)*2); + msisdn[len] = 0; + strcpy(rest_msg.msg.rent_charge.msisdn, msisdn); + + rest_msg.msg.rent_charge.balance = user_ptr->balance; + + len = encode_rest_rent_charge(&rest_msg, data_flow); + + pps_send_rest_msg(data_flow, len); +} + +/*---------------------------------------------------------*/ + +int ppsMapState(u_short portid) +{ + int retval = 0,len, error_input = 0, result; + u_char data_flow[256], service_type=0; + char ussd_data[256], ussd_sc[64], ussd_param[256], ussd_param1[256]; + MapComSrv_struct com_data; + MapOprSrv_struct opr_srv; + //COSTable *cosTableItem; + + struct MapPUSSR_Arg *pussr_arg; + struct MapUSSR_Res *ussr_ack; + + int cos_bundle_control=0; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + shmp->process_info.duration ++; + + if(shmp->process_info.funnel ++ > USSD_DELAY_TIMER) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + if(pps_get_adaptor_flag()) + { + if (shmp->process_info.sub_state == S_MAP_RECHARGE_WAIT_PIN) + { + pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_TIMEOUT, shmp->process_info.duration); + } + } +#endif + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait pussdr request timeout\33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + return -1; + } + + if(map_get_comdata_struct(&com_data,shmp->context_info.map_did)) + { + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map com, type: %d @ %ld.%ld", + portid,shmp->context_info.map_did, + com_data.message_type, + tvnow.tv_sec,tvnow.tv_usec); + map_com_stof(&com_data,data_flow,0); + pps_debug_map_msg(data_flow,0); + } + if(com_data.message_type != MAP_DELIMITER) + { + ppsSendUSSDStatistics(shmp); + return (retval = 1); + } + } + + switch(shmp->process_info.sub_state) + { + case S_MAP_SEND_OPENRSP: + if(shmp->context_info.map_acn == AC_networkUnstructuredSs) + { + pps_send_map_openrsp(portid, OpenResultAccept); + } + else + { + pps_send_map_openrsp(portid,OpenResultRefuse); + } + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_MAP_GET_PUSSDR; + break; + case S_MAP_GET_PUSSDR: + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + break; + } + if((data_flow[9] != ProcUnstrctSSReq) || data_flow[1]<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait PSSDR but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + return -1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, PUSSR ", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = shmp->context_info.map_acn_ver; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + shmp->context_info.invoke_id = data_flow[11]; //opr_srv.invoke_id; + + pussr_arg = &opr_srv.msg_list.pussr_arg; + if(pussr_arg->param_flag != 0x01) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + + switch(pussr_arg->ussd_arg.ussd_scheme & 0x0f) + { + case 0x00: + case 0x0f: /* 7bit */ + smppDecodeSM((char *)pussr_arg->ussd_arg.ussd_string.ussd_data, + ussd_data, + pussr_arg->ussd_arg.ussd_string.string_len); + break; + case 0x04: /* 8bit */ + default: + memcpy(ussd_data, + pussr_arg->ussd_arg.ussd_string.ussd_data, + pussr_arg->ussd_arg.ussd_string.string_len); + break; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, USSD data: \r\n\%s ", + portid,shmp->context_info.map_did, + ussd_data); + } + + len = pussr_arg->ussd_arg.msisdn[0]; + if(len<3 || len>11) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode PUSSR failed, error MSISDN length: %d\33[0m", + portid,shmp->context_info.map_did,len); + } + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + return retval; + } + ppsBcdToAsciiR(shmp->caller_info.number, + &pussr_arg->ussd_arg.msisdn[2], + (len-1)*2); + StringCut((char *)shmp->caller_info.number, 'F'); + GetAccountPos(&shmp->caller_info); + memset(shmp->cdr_info.caller,0xFF,8); + memcpy(shmp->cdr_info.caller,&pussr_arg->ussd_arg.msisdn[2],(len-1)); + memset(shmp->caller_info.IMSI, 0xFF, 8); + + if(logMsgFlag & 0x08) + { + if(strstr((char *)shmp->caller_info.number, logMsisdn)){ + shmp->process_info.logMsisdn = 0x01; + } + } + + if(pps_get_adaptor_flag()) + { + shmp->caller_info.cos_id = 0; + shmp->caller_info.cug_id = 0; + shmp->caller_info.head = 0; + shmp->caller_info.tail = 0; + } + else + { + if(shmp->caller_info.headcaller_info.cos_id = GetAccountCosID(&shmp->caller_info); + shmp->caller_info.cug_id = GetAccountCUG(&shmp->caller_info); + shmp->caller_info.status = GetAccountStatus(&shmp->caller_info); + + if(shmp->caller_info.status == T_BLACKLIST || + shmp->caller_info.status == T_RELEASED) + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + return retval; + + } + } + else + { + /* send error info */ + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, PUSSR, msisdn=%s not prepaid subs. \33[0m", + portid,shmp->context_info.map_did, + shmp->caller_info.number); + } + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = CAP_ERR_MISSING_CUSTOMER_RECORD; + return retval; + } + } + + memset(ussd_sc, 0x00, 24); + memset(ussd_param, 0x00, 24); + memset(ussd_param1, 0x00, 24); + ppsGetUssdParameter(ussd_data, ussd_sc, ussd_param, ussd_param1); + ussd_sc[23] = 0; + ussd_param[23] = 0; + ussd_param1[23] = 0; + + strcpy((char *)shmp->called_info.number, ussd_sc); + + service_type = GetUssdServiceType(shmp); + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[32mportid: %d ,USSD Service Code:<%s>, service type=%d , Param: %s \33[0m", + portid, + ussd_sc, + service_type, + ussd_param); + } + + shmp->process_info.funnel = 0; + shmp->process_info.serviceKey = 0; + shmp->process_info.sub_state_2 = 0; + + memset(shmp->process_info.tmpDigits, 0x00, MAX_ASCII_NUMBER_LEN); + if(strlen(ussd_param) < MAX_ASCII_NUMBER_LEN) + strcpy(shmp->process_info.tmpDigits, ussd_param); + else + { + memcpy(shmp->process_info.tmpDigits, ussd_param, MAX_ASCII_NUMBER_LEN - 1); + } + + switch(service_type) + { + case SRV_INQUIRY: + shmp->process_info.serviceKey = 1; + UssdInquiryProcess(portid); + break; + case SRV_SCRATCH_CARD_RECHARGE: + case SRV_RECHARGE_2TYPES: + len = strlen(ussd_param); + if(len>=8)// (len>=10) + { + memset(shmp->cdr_info.called,0xFF,10); + ppsAsciiToBcdR(shmp->cdr_info.called, + ussd_param, + (len+1)/2*2); + + if(len%2) + shmp->cdr_info.called[(len+1)/2] |= 0xF0; + strcpy((char *)shmp->called_info.number, ussd_param); + strcpy((char *)shmp->process_info.tmpNumber, ussd_param1); + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[32mportid: %d ,did: %d, PUSSR, msisdn=%s [ all-in-one input ]. \33[0m", + portid,shmp->context_info.map_did, + shmp->caller_info.number); + DebugMsg(debugmib.display.asciiOut, + "\n\33[32 Service code:%s, recharge card password:%s. \33[0m",ussd_sc,ussd_param); + } + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_MAP_CHECK_USSD_INPUT_CARD_VALIDITY; + } + else + { + SendUSSDRechargeRequest(portid); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state = S_MAP_RECHARGE_WAIT_PIN; + shmp->process_info.serviceKey = 2; + } +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_REQ, 0); +#endif + break; + case SRV_FEE_TRANSFER: + + if(!pps_get_adaptor_flag()) + { + if(shmp->caller_info.status == T_FRESH || + shmp->caller_info.status == T_SUSPEND) + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + return retval; + + } + } + if(strlen(ussd_param) > 2 && strlen(ussd_param1)>0) + { + shmp->process_info.ussd_transfer_one_input_flag = 1; + strcpy((char *)shmp->process_info.ppsService.feeTransfer.account.number, ussd_param); + shmp->process_info.ppsService.feeTransfer.fee = atoi(ussd_param1); + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[32mportid: %d ,did: %d, PUSSR, msisdn=%s [ ussd balance transfer all-in-one ]. \33[0m", + portid,shmp->context_info.map_did, + shmp->caller_info.number); + DebugMsg(debugmib.display.asciiOut, + "\n\33[32 received number :%s, balance to be transferred:%d. \33[0m",ussd_param, + shmp->process_info.ppsService.feeTransfer.fee); + } + + } + else + shmp->process_info.ussd_transfer_one_input_flag = 0; + shmp->process_info.sub_state = S_MAP_FEE_TRANSFER; + shmp->process_info.serviceKey = 3; + break; + case SRV_CALL_ME_BACK: + clearCMBInfo(portid); + shmp->process_info.sub_state = S_MAP_CALL_ME_BACK; + shmp->process_info.serviceKey = 4; + break; + case SRV_TELL_ME_NUMBER: + shmp->process_info.sub_state = S_MAP_TELL_ME_NUMBER; + shmp->process_info.serviceKey = 5; + break; + case SRV_FAVORITE_NUMBER: + shmp->process_info.sub_state = S_MAP_FAVORITE_NUMBER; + shmp->process_info.serviceKey = 6; + break; + case SRV_BUNDLE_PLAN: + if(shmp->caller_info.status == T_FRESH || + shmp->caller_info.status == T_SUSPEND) + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + return retval; + + } + + if(1) + { + char called_buf[32]; + strcpy((char *)shmp->called_info.number, ussd_sc); + len = strlen((char *)shmp->called_info.number); + strcpy(called_buf, (char *)shmp->called_info.number); + if(len %2 ==1){ + strcat(called_buf,"F"); + len ++; + } + strcat(called_buf,"FF"); + ppsAsciiToBcdR(shmp->cdr_info.called, called_buf, len+2); + } + + shmp->process_info.sub_state = S_MAP_BUNDLE_PLAN; + shmp->process_info.serviceKey = 7; + break; + case SRV_BUNDLE_QUERY: + if(shmp->caller_info.status == T_FRESH || + shmp->caller_info.status == T_SUSPEND) + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + return retval; + + } + + shmp->process_info.sub_state = S_MAP_BUNDLE_PLAN; + shmp->process_info.sub_state_2 = 2; + shmp->process_info.serviceKey = 8; + break; + case SRV_CALL_HOTLINE: + default: + if(pps_get_adaptor_flag()) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ + if (match_channel_info(ussd_sc, shmp->process_info.ppsService.chnl_info.scUrl) > 0) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(ussd_sc, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_REQ, 0); +#endif + shmp->process_info.sub_state = S_MAP_THIRD_PARTY_CHANNEL; + shmp->process_info.sub_state_2 = 1; + break; + } + else if (memcmp(ussd_sc, "117", 3) == 0) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_REQ, 0); +#endif + shmp->process_info.sub_state = S_MAP_THIRD_PARTY_HOTLINE; + shmp->process_info.sub_state_2 = 1; + break; + } + else +#endif + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + return retval; + } + } + cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); + if(cos_bundle_control == 1)// data plan only + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU)); + else + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU1)); + shmp->process_info.sub_state = S_MAP_GET_USSDACK; + break; + } + + break; + case S_MAP_GET_USSDACK: + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + break; + } + if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + return -1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = shmp->context_info.acn_ver; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + + ussr_ack = &opr_srv.msg_list.ussr_res; + + if(ussr_ack->param_flag != 0x01) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, USSR error received \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + + switch(ussr_ack->ussd_res.ussd_scheme & 0x0f) + { + case 0x00: + case 0x0f: /* 7bit */ + smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data, + ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + break; + case 0x04: /* 8bit */ + default: + memcpy(ussd_data, + ussr_ack->ussd_res.ussd_string.ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + break; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, USSD data: \r\n\%s ", + portid,shmp->context_info.map_did, + ussd_data); + } + + cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); + if(ussr_ack->ussd_res.ussd_string.string_len == 1) + { + unsigned char key; + + if(ussd_data[0]>=0x30 && ussd_data[0]<=0x39) + ussd_data[0] -= 0x30; /* 0-9 */ + else if(ussd_data[0]>=0x61 ) + ussd_data[0] -= 0x61; /* a- z */ + else if(ussd_data[0] >=0x41 ) + ussd_data[0] -= 0x41; /* A-Z */ + /* change ascii to digits */ + + key = GetUssdServiceKey(ussd_data[0]); + + switch(key) + { + case USSD_OC_INQUIRY: + UssdInquiryProcess(portid); + break; + case USSD_OC_RECHARGE: + SendUSSDRechargeRequest(portid); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state = S_MAP_RECHARGE_WAIT_PIN; + shmp->process_info.serviceKey = 2; + break; + case USSD_OC_FEE_TRANSFER: + if(shmp->caller_info.status == T_FRESH || + shmp->caller_info.status == T_SUSPEND) + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + return retval; + + } + + shmp->process_info.sub_state = S_MAP_FEE_TRANSFER; + shmp->process_info.serviceKey = 3; + break; + case USSD_OC_CALL_ME_BACK: + clearCMBInfo(portid); + shmp->process_info.sub_state = S_MAP_CALL_ME_BACK; + shmp->process_info.serviceKey = 4; + break; + case USSD_OC_TELL_ME_NUMBER: + shmp->process_info.sub_state = S_MAP_TELL_ME_NUMBER; + shmp->process_info.serviceKey = 5; + break; + case USSD_OC_FRIEND_FAMILY_QUERY: + shmp->process_info.sub_state = S_MAP_FAVORITE_NUMBER; + shmp->process_info.sub_state_2 = 0; + shmp->process_info.serviceKey = 6; + break; + case USSD_OC_EXIT: + case USSD_OC_HOTLINE: + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.serviceKey = 7; + break; + case USSD_OC_BUNDLE_PLAN: + case USSD_OC_BUNDLE_PLAN_ALL: + if(shmp->caller_info.status == T_FRESH || + shmp->caller_info.status == T_SUSPEND) + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; + return retval; + + } + + if((cos_bundle_control == 1) && (key == USSD_OC_BUNDLE_PLAN_ALL))// user has data plan only, not allow to request bundle plan! + { + error_input = 1; + break; + } + + if(1) + { + char called_buf[32]; + strcpy((char *)shmp->called_info.number, ussd_sc); + len = strlen((char *)shmp->called_info.number); + strcpy(called_buf, (char *)shmp->called_info.number); + if(len %2 ==1){ + strcat(called_buf,"F"); + len ++; + } + strcat(called_buf,"FF"); + ppsAsciiToBcdR(shmp->cdr_info.called, called_buf, len+2); + } + + shmp->process_info.sub_state = S_MAP_BUNDLE_PLAN; + shmp->process_info.sub_state_2 = 5; + if(key == USSD_OC_BUNDLE_PLAN_ALL) + shmp->process_info.serviceKey = 7; + else + shmp->process_info.serviceKey = 6; + break; + + default: + error_input = 1; + break; + + } + } + else + { + error_input = 1; + } + /* error input */ + if(error_input) + { + if(shmp->process_info.serviceInput++>=3) + { + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + } + else + { + if (cos_bundle_control == 0)// user has bundle plan, no suitable sentance, so has to repeat it + { + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU1));// repeat this menu + } + else + { + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_ERROR_INPUT)); + } + } + } + shmp->process_info.funnel = 0; + break; + case S_MAP_RECHARGE_WAIT_PIN: + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + break; + } + if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_SYSTEM, shmp->process_info.duration); +#endif + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + return -1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ", + portid,shmp->context_info.map_did, + data_flow[9]); + pps_debug_map_msg(data_flow,0); + } + + opr_srv.version = shmp->context_info.acn_ver; + opr_srv.message_type = data_flow[9]; + opr_srv.message_flag = data_flow[10]; + opr_srv.port_id = portid; + opr_srv.dialogue_id = shmp->context_info.map_did; + + if(extract_mapparam(&opr_srv, + data_flow[9], + data_flow[10], + data_flow[14]*256+data_flow[15], + &data_flow[16])<=0) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_MSG, shmp->process_info.duration); +#endif + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m", + portid,shmp->context_info.map_did); + } + ppsSendUSSDStatistics(shmp); + return -1; + } + + ussr_ack = &opr_srv.msg_list.ussr_res; + + if(ussr_ack->param_flag != 0x01) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_MSG, shmp->process_info.duration); +#endif + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31mportid: %d ,did: %d, USSR error received \33[0m", + portid,shmp->context_info.map_did); + } + return -1; + } + + switch(ussr_ack->ussd_res.ussd_scheme & 0x0f) + { + case 0x00: + case 0x0f: /* 7bit */ + smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data, + ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + break; + case 0x04: /* 8bit */ + default: + memcpy(ussd_data, + ussr_ack->ussd_res.ussd_string.ussd_data, + ussr_ack->ussd_res.ussd_string.string_len); + break; + } + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, USSD data: %s", + portid,shmp->context_info.map_did, + ussd_data); + } + len = strlen(ussd_data); + if(len>16) + { + ussd_data[16] = 0; + len = 16; + } + + memset(shmp->cdr_info.called,0xFF,10); + + ppsAsciiToBcdR(shmp->cdr_info.called, + ussd_data, + (len+1)/2*2); + + if(len%2) + shmp->cdr_info.called[(strlen(ussd_data)+1)/2] |= 0xF0; + strcpy((char *)shmp->called_info.number, ussd_data); + + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_MAP_CHECK_USSD_INPUT_CARD_VALIDITY; + break; + case S_MAP_CHECK_USSD_INPUT_CARD_VALIDITY: + if(UseExternalVC()) + { + shmp->process_info.sub_state_2 = 0; + shmp->process_info.sub_state = S_MAP_USSD_CHECK_CARD_DATA_RCM; + return retval; + } + if(OCS_with_external_CRM()) + { + shmp->process_info.sub_state_2 = 0; + shmp->process_info.sub_state = S_MAP_USSD_CHECK_CARD_DATA_CRM; + return retval; + + } + + if(pps_get_adaptor_flag()) + { + shmp->process_info.sub_state = S_MAP_REST_TOPUP; + shmp->process_info.sub_state_2 = 0; + return retval; + } + if(CheckWetherValidRechargeCard(portid,shmp->called_info.number, &result)==0) + { + if(result == 5 ) + { + shmp->process_info.u_error = 0xee; + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + } + else + { + shmp->process_info.sub_state = S_MAP_USSD_INPUT_CARD_PWD_AGAIN; + } + return retval; + } + RechargeRequestProc(portid); + SendUSSDRechargeSuccessInfo(portid); + //shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK_SEND_USSN; + + if(1) + { + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + retval = 1; + + } + + + break; + case S_MAP_USSD_INPUT_CARD_PWD_AGAIN: + if(shmp->process_info.serviceInput++>3) + { + shmp->process_info.u_error = 0xee; + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + return retval; + } + SendUSSDRechargeRequestAgain(portid); + shmp->process_info.sub_state = S_MAP_RECHARGE_WAIT_PIN; + break; + case S_MAP_USSD_CHECK_CARD_DATA_RCM: + switch(shmp->process_info.sub_state_2 ) + { + case 0: + send_scf_update_card_data(portid); + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + shmp->process_info.update_card_ack = 0; + break; + case 1: + if(!shmp->process_info.update_card_ack) + { + return retval; + } + if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) + { + shmp->process_info.u_error = 0xee; + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + return retval; + } + if(shmp->process_info.update_card_result != OC_RESULT_OK) + { + RechargeFailedUpdateAccountData(portid); + shmp->process_info.sub_state = S_MAP_USSD_INPUT_CARD_PWD_AGAIN; + return retval; + } + RechargeRequestProc(portid); + SendUSSDRechargeSuccessInfo(portid); + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK_SEND_USSN; + break; + default: + shmp->process_info.u_error = 0xee; + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + break; + } + break; + case S_MAP_USSD_CHECK_CARD_DATA_CRM: + switch(shmp->process_info.sub_state_2 ) + { + case 0: + pps_send_selfcare_topup_req(portid); + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + shmp->process_info.rest_if.recv_cmd = 0; + break; + case 1: + if(shmp->process_info.rest_if.recv_cmd == 0) + { + return retval; + } + if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) + { + shmp->process_info.u_error = 0xee; + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + return retval; + } + if(shmp->process_info.rest_if.result) + { + RechargeFailedUpdateAccountData(portid); + shmp->process_info.sub_state = S_MAP_USSD_INPUT_CARD_PWD_AGAIN; + return retval; + } + RechargeSucceedwithCRM(portid); + SendUSSDRechargeSuccessInfo(portid); + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK_SEND_USSN; + break; + default: + shmp->process_info.u_error = 0xee; + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + break; + } + break; + case S_MAP_SEND_PUSSR_ACK: + SendPSSRResponse(portid); + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + return 1; + break; + case S_MAP_SEND_PUSSR_ACK_SEND_USSN: + if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) + { + break; + } + + + if((data_flow[9] != UnstrctSSNoti) || data_flow[1]<10) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d ,did: %d, wait USSDN_ACK but %d received\33[0m", + portid,shmp->context_info.map_did,data_flow[9]); + } + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + return -1; + } + + if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\nportid: %d ,did: %d, Get Map opr < USSN_ACK > ", + portid,shmp->context_info.map_did); + pps_debug_map_msg(data_flow,0); + } + + SendPSSRResponse(portid); + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + shmp->process_info.funnel = 0; + + return 1; + break; + case S_MAP_WAIT_USSN_ACK: + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + retval = 1; + break; + case S_MAP_FEE_TRANSFER: + result = transferAccountUSSDProc(portid); + switch(result) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU)); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_MAP_GET_USSDACK; + break; + case SERVICE_EXIT_PPS: + default: + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + break; + } + break; + case S_MAP_CALL_ME_BACK: + result = callMebackUSSDProc(portid); + switch(result) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_RETURN_TO_PARENT: + SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU)); + shmp->process_info.funnel = 0; + shmp->process_info.sub_state = S_MAP_GET_USSDACK; + break; + case SERVICE_EXIT_PPS: + default: + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + break; + } + break; + case S_MAP_TELL_ME_NUMBER: + SendUSSDTellMeNumberInfo(portid); + shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; + break; + case S_MAP_FAVORITE_NUMBER: + result = favoriteNumberUssdProc(portid); + switch(result) + { + case SERVICE_KEEP_STATE: + break; + case SERVICE_EXIT_PPS: + shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; + break; + case SERVICE_RETURN_TO_PARENT: + default: + shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; + break; + } + break; + case S_MAP_REST_QUERY: + retval = pps_rest_query_process(portid); + if(retval != 0) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_QUERY_CODE_STR, USSDCODE_TYPE_QUERY, USSDCODE_STAT_DUR, shmp->process_info.duration); +#endif + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + retval = 1; + +// shmp->process_info.serviceKey = 1; +// shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; + } + break; + case S_MAP_REST_TOPUP: + retval = pps_rest_topup_process(portid); + if(retval != 0) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_DUR, shmp->process_info.duration); +#endif + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + retval = 1; + +// shmp->process_info.serviceKey = 2; +// shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; + } + break; + + case S_MAP_BUNDLE_PLAN: + retval = pps_bundle_plan_process(portid); + if(retval != 0) + { + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + retval = 1; + } + break; + case S_MAP_THIRD_PARTY_HOTLINE: + retval = pps_third_party_plan_process(portid); + if(retval != 0) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_DUR, shmp->process_info.duration); +#endif + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + retval = 1; + } + break; + case S_MAP_THIRD_PARTY_CHANNEL: + retval = pps_third_party_channel_process(portid); + if(retval != 0) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(shmp->process_info.ppsService.chnl_info.scUrl, USSDCODE_TYPE_CHANNEL, USSDCODE_STAT_DUR, shmp->process_info.duration); +#endif + ppsSendUSSDStatistics(shmp); + pps_send_map_close(portid); + shmp->process_info.sub_state = S_IDLE; + retval = 1; + } + break; + default: + retval = 1; + break; + } + return retval; +} + +int pps_rest_test_process(int flag) +{ + int portid; + _state_data *shmp=(_state_data *) &smshm_ptr->state_data; + + portid = AssignProcID(0); + if( portid< MAX_FSM_PROCESS && portid>=0 ) + { + shmp += portid; + memset(shmp, 0x00, sizeof(_state_data)); + + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , %s , flag=%d\33[0m", + portid, __FUNCTION__, flag); + + shmp->process_info.state = S_MAP_STATE; + if(flag == 0) + { + shmp->process_info.sub_state = S_MAP_REST_QUERY; + } + else + { + shmp->process_info.sub_state = S_MAP_REST_TOPUP; + strcpy((char *)shmp->called_info.number, "123456789012"); + + } + + strcpy((char *)shmp->caller_info.number, "86755900123"); + } + + return 1; +} + + +int SmppRechargeProc(u_short portid) +{ + _state_data *shmp; + int retval=0; + int error_code = ERR_REST_SUCCESS; + + PutLogFunID("SnmpRechargeProc"); + + shmp = (_state_data *)&smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + return -1; + shmp += portid; + + if(shmp->process_info.funnel ++>SSHORT_DELAY_TIMER) + { + sendSMSRechargeNegativeResponse(shmp, OC_RESULT_SYSTEM_FAILURE); + return -1; + } + switch(shmp->process_info.sub_state) + { + case 0: + send_scf_update_card_data(portid); + shmp->process_info.sub_state = 1; + shmp->process_info.funnel = 0; + shmp->process_info.update_card_ack = 0; + break; + case 1: + if(!shmp->process_info.update_card_ack) + { + return retval; + } + if(shmp->process_info.update_card_result != OC_RESULT_OK) + { + RechargeFailedUpdateAccountData(portid); + sendSMSRechargeNegativeResponse(shmp, shmp->process_info.update_card_result ); + return (retval = -1); + } + RechargeRequestProc(portid); + retval = 1; + break; + case 2: + pps_send_selfcare_topup_req(portid); + shmp->process_info.funnel = 0; + shmp->process_info.rest_if.recv_cmd = 0; + if(shmp->process_info.chargeFrom == 3) + { + shmp->process_info.sub_state = 4; + } + else + shmp->process_info.sub_state = 3; + + break; + case 3: + if(shmp->process_info.rest_if.recv_cmd == 0) + { + return retval; + } + if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) + { + return (retval = -1); + } + if(shmp->process_info.rest_if.result) + { + RechargeFailedUpdateAccountData(portid); + sendSMSRechargeNegativeResponse(shmp, shmp->process_info.rest_if.result ); + return (retval = -1); + } + RechargeSucceedwithCRM(portid); + retval = 1; + break; + case 4: + if(shmp->process_info.rest_if.recv_cmd == 0) + { + return retval; + } + if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) + { + error_code = ERR_REST_UNABLE_TO_COMPLY; + } + if(shmp->process_info.rest_if.result) + { + switch(shmp->process_info.rest_if.result == 1) + { + case 1: + error_code = ERR_REST_INVALID_RECHARGE_PWD; + break; + case 2: //error status + error_code = ERR_REST_INVALID_PARAMETER_VALUE; + break; + case 3: //expired + default: + error_code = ERR_REST_INVALID_PARAMETER_VALUE; + break; + } + } + + if(1) + { + int len; + char msg_buf[256]; + _rest_msg_s rest_rsp; + _rest_recharge_card_rsp *pRsp = &rest_rsp.msg.recharge_card_rsp; + + memset(pRsp, 0, sizeof(_rest_recharge_card_rsp)); + + rest_rsp.msg_type = REST_RECHARGE_CARD_RSP; + rest_rsp.header.dst_ref = shmp->process_info.rest_if.src_ref; + rest_rsp.header.src_ref = shmp->process_info.rest_if.dst_ref; + pRsp->error_code = error_code; + if (error_code != ERR_REST_SUCCESS) + { + pRsp->result = RES_FAILED; + pRsp->rechargeAmount = 0; + + } + else + { + pRsp->result = RES_SUCCEED; + + RechargeSucceedwithCRM(portid); + pRsp->rechargeAmount = shmp->process_info.rest_if.balance; + } + + pRsp->balance = GetBalance(&shmp->caller_info); + pRsp->expiredTime = (u64)GetExpiration(&shmp->caller_info); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) + { + DebugMsg(debugmib.display.asciiOut, "reply REST_RECHARGE_CARD_RSP, result[%d], recharge amount[%d], balance[%d]", \ + error_code, pRsp->rechargeAmount, pRsp->balance); + } + + len = encode_rest_recharge_card_rsp(&rest_rsp, (u8 *)msg_buf); + pps_send_rest_msg((u8 *)msg_buf, len); + } + + retval = 1; + + break; + default: + retval = 1; + break; + } + return retval; +} + +// for restproxy(zmobile) ========================================= +char yx_ussd_menu[YX_USSD_MENU_NUM_MAX][512]= { + /*0main*/"Welcome to the Ultimate DATA experience - zedmobile!\n1. UNLIMITED zedmobile calls and Data @ an Unbelievable K20 for 30 days\n2. zedDATA\n3. zedVOICE\n4. zedMIFI & Router\n5. Buy for Other\n6. Balance Check", + /*1k20*/"Try our K20 UNLIMITED Calls & Data\n1. Yes\n0. To return to main menu", + /*2data*/"1. 24 Hrs\n2. 7 days\n3. 30 days\n0. To return to main menu", + /*3voice*/"1. Daily\n2. Weekly\n3. Monthly\n0. To return to main menu", + /*4mifi*/"Welcome to the ULTIMATE DATA experience - zedmobile!\n1. K50 = 6 GB for 30 days\n2. K100 = 15GB for 30 days\n3. K200 = 40GB for 30 days\n4. K500 = 65GB +5GBDaily for 30 days + Unlimited netflix\n5. K700 = 80 GB + 6 GB daily for 30 days + Unlimited Netflix + Youtube\n6. K1000 = 100 GB +8Gb Daily + Unlimited netflix + Youtube\n0. To return to main menu", + /*5buy4Other*/"Share the ULTIMATE DATA experience - zedmobile!\nKindly enter the number you wish to share a zedmobile bundle with.(098X xxxxxx)", + /*6balanceCheck*/"Dear Customer, your balance is processed. You will receive a confirmation message shortly", + /*7*/"", + /*8*/"", + /*9*/"", + /*10data 24Hrs*/"1. K2= 100 MB for 24Hrs\n2. K5= 350 MB for 24Hrs\n3. K10= 1.5 GB for 24Hrs\n0. To return to main menu", + /*11data 7days*/"1. K5= 500 MB for 7 days\n2. K10= 1 GB for 7 days\n3. K20= 2 GB for 7 days\n4. K50= 7.5 GB for 7 days\n0. To return to main menu", + /*12data 30days*/"1. K50= 5 GB for 30 days\n2. K100= 10 GB for 30 days\n3. K200= 30 GB for 30 days\n0. To return to main menu", + /*13voic Daily*/"Press\n1 . K2= 8 min allnet + 20MB + 50 SMS\n2. K5= 26 min allnet + 40MB + 100 SMS\n3. K10= 40 Min allnet + 70MB + 100 SMS\n0. To return to main menu", + /*14voic Weekly*/"Press\n1. K5= 17 min allnet + 100MB + 50 SMS\n2. K10= 45 min allnet + 300 MB + 100 SMS\n3. K20= 120min allnet + 400MB +100 SMS\n4. K50= 350 min allnet + 500MB + 100 SMS\n0. To return to main menu", + /*15voic Monthly*/"Press\n1. K50= 200 min allnet + 1 GB + 500 SMS\n2. K100= 725min allnet + 3GB + 500 SMS\n3. K200= 1750 min allnet + 5GB + 500 SMS\n4. K250= 800min allnet + 15GB + 500 SMS\n0. To return to main menu", + /*16MIFI*/"", + /*17otherMenu*/"1. ZedLife na K20\n2. zedDATA\n3. zedVoice\n4. zedMIFI & Router\n0. To return to main menu", + /*18thirdParty*/"1. Airtel\n2. MTN", + /*19enterPhone*/"Enter mobile number", + /*20payMethod*/"1. Main account\n2. Mobile money", + /*21Paid*/"Your transaction is being processed. You will receive a confirmation SMS soon. For the ULTIMATE experience use My zedLife App ( selfcare)\n1. Download zedLife App and don’t miss out on anything.\n0. To return to the main menu", + /*22enterPin*/"Enter pin to confirm", + /*23complete*/"Thank you. You will soon receive the link via text message.", + /*24cancel auto renewal*/"Are you certain about canceling auto renewal?\n1. No\n2. Yes\n0. To return to main menu", +}; +char yx_chnl_info[YX_USSD_CHNL_NUM_MAX][128]= { +}; +char yx_momo_info[YX_MOBILE_MONEY_MAX][32]= {"Airtel Money", "MTN MoMo", "Zamtel Kwacha", ""}; +int yx_offerIds[YX_OFFER_TYPE_MAX][YX_OFFER_PER_TYPE]; +char yx_offerStrs[YX_OFFER_TYPE_MAX][YX_OFFER_PER_TYPE][128]= {}; +int yx_ussd_daily_report = 0; +extern int time_now[7]; +int match_channel_info(char *sc, char *url) +{ + int i; + if (strlen(sc) < 3) + { + return 0; + } + for (i=0; i 12) && (strncmp(sc, yx_chnl_info[i], 3) == 0)) + { + strcpy(url, yx_chnl_info[i]); + return 1; + } + } + return 0; +} + +int read_yx_ussd_param(void) +{ + //char *temp_ptr; + char info_str[512]; + char sysconf[]="/usr/local/ussdgw/bin/conf/yx_ussd.conf"; + FILE *fp = fopen(sysconf,"r");// read configure + if (fp == NULL) + { + printf("can not open file %s!!\n",sysconf); + return 0; + } + + int i, ret; + while (!feof(fp)) + { + info_str[0] = '\n'; + ret = fgets(info_str, 250, fp); + if (info_str[0] == '#' || info_str[0] == '\n') + continue; + + i = 0; + while (info_str[i] != '\0') + { + if (info_str[i] == '|') + { + info_str[i] = '\n'; + } + i++; + } + + if(!strncasecmp(info_str,"dailyreport=", 12)) + { + yx_ussd_daily_report = atoi(&info_str[12]); + } + else if(!strncasecmp(info_str,"bundle11=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][0] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"bundle12=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][1] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"bundle13=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][2] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"bundle14=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][3] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"bundle15=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][4] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"bundle16=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][5] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"bundle17=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][6] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"bundle18=", 9)) + { + yx_offerIds[YX_OFFER_TYPE_BUNDLE][7] = atoi(&info_str[9]); + } + else if(!strncasecmp(info_str,"data11=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_1][0] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data12=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_1][1] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data13=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_1][2] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data14=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_1][3] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data21=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_2][0] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data22=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_2][1] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data23=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_2][2] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data24=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_2][3] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data31=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_3][0] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data32=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_3][1] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data33=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_3][2] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"data34=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DATA_3][3] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"voice11=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_1][0] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice12=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_1][1] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice13=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_1][2] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice14=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_1][3] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice21=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_2][0] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice22=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_2][1] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice23=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_2][2] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice24=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_2][3] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice31=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_3][0] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice32=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_3][1] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice33=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_3][2] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"voice34=", 8)) + { + yx_offerIds[YX_OFFER_TYPE_VOICE_3][3] = atoi(&info_str[8]); + } + else if(!strncasecmp(info_str,"mifi11=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_MIFI_1][0] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"mifi12=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_MIFI_1][1] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"mifi13=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_MIFI_1][2] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"mifi14=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_MIFI_1][3] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"mifi15=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_MIFI_1][4] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"mifi16=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_MIFI_1][5] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"mifi17=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_MIFI_1][6] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"ama01=", 6)) + { + yx_offerIds[YX_OFFER_TYPE_AMA_1][0] = atoi(&info_str[6]); + } + else if(!strncasecmp(info_str,"ama02=", 6)) + { + yx_offerIds[YX_OFFER_TYPE_AMA_1][1] = atoi(&info_str[6]); + } + else if(!strncasecmp(info_str,"ama03=", 6)) + { + yx_offerIds[YX_OFFER_TYPE_AMA_1][2] = atoi(&info_str[6]); + } + else if(!strncasecmp(info_str,"ama04=", 6)) + { + yx_offerIds[YX_OFFER_TYPE_AMA_1][3] = atoi(&info_str[6]); + } + else if(!strncasecmp(info_str,"ama05=", 6)) + { + yx_offerIds[YX_OFFER_TYPE_AMA_1][4] = atoi(&info_str[6]); + } + else if(!strncasecmp(info_str,"ama06=", 6)) + { + yx_offerIds[YX_OFFER_TYPE_AMA_1][5] = atoi(&info_str[6]); + } + else if(!strncasecmp(info_str,"ama07=", 6)) + { + yx_offerIds[YX_OFFER_TYPE_AMA_1][6] = atoi(&info_str[6]); + } + else if(!strncasecmp(info_str,"diba01=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][0] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba02=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][1] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba03=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][2] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba04=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][3] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba05=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][4] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba06=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][5] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba07=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][6] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba08=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][7] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba09=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][8] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba10=", 7)) + { + yx_offerIds[YX_OFFER_TYPE_DIBA_1][9] = atoi(&info_str[7]); + } + else if(!strncasecmp(info_str,"diba01str=", 10)) + { + snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][0], 127, "%s", &info_str[10]);//strncpy(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][0], &info_str[10], 127); + } + else if(!strncasecmp(info_str,"diba02str=", 10)) + { + snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][1], 127, "%s", &info_str[10]); + } + else if(!strncasecmp(info_str,"diba03str=", 10)) + { + snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][2], 127, "%s", &info_str[10]); + } + else if(!strncasecmp(info_str,"diba04str=", 10)) + { + snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][3], 127, "%s", &info_str[10]); + } + else if(!strncasecmp(info_str,"diba05str=", 10)) + { + snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][4], 127, "%s", &info_str[10]); + } + else if(!strncasecmp(info_str,"0main=",6)) + { + strcpy(yx_ussd_menu[0], &info_str[6]); + } + else if(!strncasecmp(info_str,"1k20=",5)) + { + strcpy(yx_ussd_menu[1], &info_str[5]); + } + else if(!strncasecmp(info_str,"2data=",6)) + { + strcpy(yx_ussd_menu[2], &info_str[6]); + } + else if(!strncasecmp(info_str,"3voice=",7)) + { + strcpy(yx_ussd_menu[3], &info_str[7]); + } + else if(!strncasecmp(info_str,"4mifi=",6)) + { + strcpy(yx_ussd_menu[4], &info_str[6]); + } + else if(!strncasecmp(info_str,"5buy4Other=",11)) + { + strcpy(yx_ussd_menu[5], &info_str[11]); + } + else if(!strncasecmp(info_str,"6balanceCheck=",14)) + { + strcpy(yx_ussd_menu[6], &info_str[14]); + } + else if(!strncasecmp(info_str,"7ama=",5)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_PRESS_AMA], &info_str[5]); + } + else if(!strncasecmp(info_str,"8unlimited=",11)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_PRESS_UNLIMITED_BUNDLES], &info_str[11]); + } + else if(!strncasecmp(info_str,"9airtime=",9)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_PRESS_PURCHASE_AIRTIME], &info_str[9]); + } + else if(!strncasecmp(info_str,"10data24Hrs=",12)) + { + strcpy(yx_ussd_menu[10], &info_str[12]); + } + else if(!strncasecmp(info_str,"11data7days=",12)) + { + strcpy(yx_ussd_menu[11], &info_str[12]); + } + else if(!strncasecmp(info_str,"12data30days=",13)) + { + strcpy(yx_ussd_menu[12], &info_str[13]); + } + else if(!strncasecmp(info_str,"13voiceDaily=",13)) + { + strcpy(yx_ussd_menu[13], &info_str[13]); + } + else if(!strncasecmp(info_str,"14voiceWeekly=",14)) + { + strcpy(yx_ussd_menu[14], &info_str[14]); + } + else if(!strncasecmp(info_str,"15voiceMonthly=",15)) + { + strcpy(yx_ussd_menu[15], &info_str[15]); + } + else if(!strncasecmp(info_str,"17otherMenu=",12)) + { + strcpy(yx_ussd_menu[17], &info_str[12]); + } + else if(!strncasecmp(info_str,"18thirdParty=",13)) + { + strcpy(yx_ussd_menu[18], &info_str[13]); + + /* mobile moneys + int i=0, offset; + char *token; + char delimiter[] = "|"; + char str[160]=""; + strncpy(str, yx_ussd_menu[18], 159); + token = strtok(str, delimiter); + while ((token != NULL) && (i < YX_MOBILE_MONEY_MAX)) { + if (token[0]<'0' || token[0]>'9') + { + token = strtok(NULL, delimiter); + continue; + } + offset = 2; + if (token[2] == ' ') + { + offset = 3; + } + strncpy(yx_momo_info[i], &token[offset], 31); + i++; + token = strtok(NULL, delimiter); + }*/ + } + else if(!strncasecmp(info_str,"19enterPhone=",13)) + { + strcpy(yx_ussd_menu[19], &info_str[13]); + } + else if(!strncasecmp(info_str,"20payMethod=",12)) + { + strcpy(yx_ussd_menu[20], &info_str[12]); + } + else if(!strncasecmp(info_str,"21Paid=",7)) + { + strcpy(yx_ussd_menu[21], &info_str[7]); + } + else if(!strncasecmp(info_str,"22enterPin=",11)) + { + strcpy(yx_ussd_menu[22], &info_str[11]); + } + else if(!strncasecmp(info_str,"23complete=",11)) + { + strcpy(yx_ussd_menu[23], &info_str[11]); + } + else if(!strncasecmp(info_str,"24cancelrenewal=",16)) + { + strcpy(yx_ussd_menu[24], &info_str[16]); + } + else if(!strncasecmp(info_str,"25enteramount=",14)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT], &info_str[14]); + } + else if(!strncasecmp(info_str,"26airtimeno=",12)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_AIRTIME_NO], &info_str[12]); + } + else if(!strncasecmp(info_str,"27dibaama=",10)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_DIBAAMA], &info_str[10]); + } + else if(!strncasecmp(info_str,"28diba=",7)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_DIBA], &info_str[7]); + } + else if(!strncasecmp(info_str,"29momopin=",10)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_MOMO_PIN], &info_str[10]); + } + else if(!strncasecmp(info_str,"30promo=",8)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_PROMO], &info_str[8]); + } + else if(!strncasecmp(info_str,"31querypoint=",13)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], &info_str[13]); + } + else if(!strncasecmp(info_str,"32curpoint=",11)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_CUR_POINT], &info_str[11]); + } + else if(!strncasecmp(info_str,"33point2num=",12)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_POINT2NUM], &info_str[12]); + } + else if(!strncasecmp(info_str,"34offerchange=",14)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_OFFER_CHANGED], &info_str[14]); + } + else if(!strncasecmp(info_str,"35pointtrans=",13)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_POINT_TRANSFERED], &info_str[13]); + } + else if(!strncasecmp(info_str,"36pointlow=",11)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_POINT_LOW], &info_str[11]); + } + else if(!strncasecmp(info_str,"37offerout=",11)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_OFFER_OUT], &info_str[11]); + } + else if(!strncasecmp(info_str,"38transfail=",12)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_POINT_TRANS_FAIL], &info_str[12]); + } + else if(!strncasecmp(info_str,"39shareno=",10)) + { + strcpy(yx_ussd_menu[YX_USSD_MENU_SHARE_NBR], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel00=", 10)) + { + strcpy(yx_chnl_info[0], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel01=", 10)) + { + strcpy(yx_chnl_info[1], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel02=", 10)) + { + strcpy(yx_chnl_info[2], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel03=", 10)) + { + strcpy(yx_chnl_info[3], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel04=", 10)) + { + strcpy(yx_chnl_info[4], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel05=", 10)) + { + strcpy(yx_chnl_info[5], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel06=", 10)) + { + strcpy(yx_chnl_info[6], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel07=", 10)) + { + strcpy(yx_chnl_info[7], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel08=", 10)) + { + strcpy(yx_chnl_info[8], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel09=", 10)) + { + strcpy(yx_chnl_info[9], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel10=", 10)) + { + strcpy(yx_chnl_info[10], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel11=", 10)) + { + strcpy(yx_chnl_info[11], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel12=", 10)) + { + strcpy(yx_chnl_info[12], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel13=", 10)) + { + strcpy(yx_chnl_info[13], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel14=", 10)) + { + strcpy(yx_chnl_info[14], &info_str[10]); + } + else if(!strncasecmp(info_str,"channel15=", 10)) + { + strcpy(yx_chnl_info[15], &info_str[10]); + } + } + + fclose(fp); + return 1; +} + +int pps_third_party_plan_process(u_short portid) +{ + char ussd_data[1024]; + int retval = 0, result=0; + int key_input; + + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + if(shmp->process_info.funnel ++ > 100*CYCLE_STATE_INTERVAL) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_TIMEOUT, 0); +#endif + return -1; + } + + switch(shmp->process_info.sub_state_2 ) + { + case 1: + if(shmp->process_info.serviceInput++ > 3) + { + SendPSSRResponse(portid); + return 1; + } + shmp->process_info.funnel = 0; + shmp->process_info.rest_if.plan_id = 0; + shmp->process_info.rest_if.bundle_plan_id = 0; + shmp->process_info.routing_number[0] = '\0'; + + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_MAIN]); + shmp->process_info.sub_state_2 = 2; + break; + case 2: + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_UNLIMITED_BUNDLES]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 20;//1. UNLIMITED Data + break; + case 2: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_DATA]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 22;//zedDATA + break; + case 3: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_VOICE]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 23;//zedVOICE + break; + case 4: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_MIFI_AND_ROUTER]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 24;//zedMifi & Router + break; + case 5: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_INPUT_NO]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 25;//Buy for Other + break; + case 6: + //SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_BALANCE_CHECK]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 26;//Balance Check, inform BOSS + break; + case 7: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_PURCHASE_AIRTIME]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 28;//Recharge Airtime + break; + case 0: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DIBAAMA]);// YX_USSD_MENU_PRESS_AMA + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 15;//27;//diba & amaFive + break; + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break;// + case 3: + if(shmp->process_info.serviceInput++ > 3) + { + SendPSSRResponse(portid); + return 1; + } + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_BUY_FOR_OTHER]);// menu 1-4 + shmp->process_info.sub_state_2 = 4; + break; + case 4:// Buy for others, select menu 1-4 + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + shmp->process_info.sub_state_2 = 3; + shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + shmp->process_info.sub_state_2 = 3; + shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_UNLIMITED_BUNDLES]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 20;//1. UNLIMITED Data + break; + case 2: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_DATA]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 22;//zedDATA + break; + case 3: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_VOICE]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 23;//zedVOICE + break; + case 4: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_MIFI_AND_ROUTER]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 24;//zedMifi & Router + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 10:// Recharge Promo + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// Opt-in, send transfer Plan and return + pps_send_rest_offer_change_req(portid, 0); + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_OFFER_CHANGED]); + shmp->process_info.serviceInput = 0; + retval = 1; + break; + case 2:// Query Bonus, send query points + pps_send_rest_point_query_req(portid); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 11;// query points + break; + case 3:// Transfer Gift + //pps_send_rest_point_query_req(portid); + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_CUR_POINT]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 13;// transfer Gift + break; + case 4:// Opt-out, send transfer Plan and return + pps_send_rest_offer_change_req(portid, 1); + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_OFFER_OUT]); + shmp->process_info.serviceInput = 0; + retval = 1; + break; + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break;// + case 11:// query points + if(shmp->process_info.rest_if.recv_cmd == 0) + break; + shmp->process_info.rest_if.recv_cmd = 0; + result = shmp->process_info.rest_if.result; + if(result == 0) + { + retval = 1; + sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], shmp->process_info.rest_if.unit, + shmp->process_info.rest_if.balance/100, shmp->process_info.rest_if.balance%100); + } + else + { + retval = -1; + sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], 0); + } + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , recv query_points_res, result=%d, point=%d\33[0m", + portid, result, shmp->process_info.rest_if.unit); + } + SendPSSREnd(portid, ussd_data); + break; + case 12:// current points + if(shmp->process_info.rest_if.recv_cmd == 0) + break; + shmp->process_info.rest_if.recv_cmd = 0; + result = shmp->process_info.rest_if.result; + if(result == 0) + { + /*if (shmp->process_info.rest_if.unit <= 0) + { + retval = -1; + sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], 0); + SendPSSREnd(portid, ussd_data); + } + else + { + sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_CUR_POINT], shmp->process_info.rest_if.unit); + SendUSSDRequest(portid, ussd_data); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 13;// enter number that transfer Gift to + }*/ + sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT_TRANSFERED], shmp->process_info.rest_if.unit, shmp->process_info.routing_number); + SendPSSREnd(portid, ussd_data); + retval = 1; + } + else + { + retval = -1; + sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT_TRANS_FAIL], shmp->process_info.routing_number); + SendPSSREnd(portid, ussd_data); + } + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d , recv query_points_res, result=%d, point=%d\33[0m", + portid, result, shmp->process_info.rest_if.unit); + } + break; + case 13:// input No. transfer Gift for + result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); + if(result >= 1) + { + sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT2NUM], shmp->process_info.routing_number); + SendUSSDRequest(portid, ussd_data); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 14;// =>Amount Input + shmp->process_info.funnel = 0; + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 14:// Point Amount Input + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + if (key_input <= 0) + { + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_POINT_LOW]); + retval = 1; + } + else + { + shmp->process_info.rest_if.unit = key_input; + pps_send_rest_point_transfer_req(portid, 1070); + //sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT_TRANSFERED], shmp->process_info.rest_if.unit, shmp->process_info.routing_number); + //SendPSSREnd(portid, ussd_data); + } + //retval = 1; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 12;// =>wait result + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 15: + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 2: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DIBA]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 16;//diba 5x + break; + case 1: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PROMO]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 10;//Recharge Promo + break; + case 3: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_AMA]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 27;//amaFive + break; + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break;// + case 16:// 0, DIBA sub menu + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + case 4: + case 5: + { + char tmp_buf[160]=""; + snprintf(tmp_buf, 159, "%s\n%s", yx_offerStrs[YX_OFFER_TYPE_DIBA_1][key_input-1], + yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); + SendUSSDRequest(portid, tmp_buf);//yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); + } + shmp->process_info.rest_if.bundle_plan_id = key_input -1; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 17;//once, recur or cancel + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 17:// 0, diba: once, recur + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + int bundleId = shmp->process_info.rest_if.bundle_plan_id * 2; + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// once off + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DIBA_1][bundleId]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 2:// recur + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DIBA_1][bundleId + 1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 3:// cancel recur + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_CANCEL_RENEWAL]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DIBA_1][bundleId + 1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 36;//cancel auto renewal + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 18:// input No. share airtime with + result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); + if(result >= 1) + { + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 19;// =>Airtime Amount Input + shmp->process_info.funnel = 0; + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 19:// Airtime Amount Input, share with + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + + shmp->process_info.rest_if.unit = key_input; + pps_send_rest_point_transfer_req(portid, 1069); + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]); + retval = 1; + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 20:// unlimited data + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// K20 Unlimited-24hrs + /*SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); + shmp->process_info.rest_if.bundle_plan_id = 0;// yx_offerIds[YX_OFFER_TYPE_BUNDLE][0]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 21;//once, recur or cancel + shmp->process_info.funnel = 0;*/ + + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][0]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 2:// K20 Unlimited-3 Days + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); + shmp->process_info.rest_if.bundle_plan_id = 1;// yx_offerIds[YX_OFFER_TYPE_BUNDLE][2]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 21;//once, recur or cancel + shmp->process_info.funnel = 0; + break; + case 3:// K100 Unlimited-7 Days + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); + shmp->process_info.rest_if.bundle_plan_id = 2;//yx_offerIds[YX_OFFER_TYPE_BUNDLE][3]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 21;//once, recur or cancel + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 21:// 1, k20 unlimited calls and data + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + int bundleId = shmp->process_info.rest_if.bundle_plan_id * 2; + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][bundleId]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 2: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][bundleId + 1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 3: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_CANCEL_RENEWAL]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][bundleId + 1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 36;//cancel auto renewal + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 22:// 2, zed DATA + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// 24Hrs + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DATA_24HRS]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 41; + shmp->process_info.funnel = 0; + break; + case 2:// 7 days + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DATA_7DAYS]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 42; + shmp->process_info.funnel = 0; + break; + case 3:// 30 days + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DATA_30DAYS]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 43; + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 23:// 3, zed VOICE + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// 24Hrs + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_VOICE_DAILY]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 51; + shmp->process_info.funnel = 0; + break; + case 2:// 7 days + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_VOICE_WEEKLY]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 52; + shmp->process_info.funnel = 0; + break; + case 3:// 30 days + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_VOICE_MONTHLY]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 53; + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 24:// 4, MIFI sub menu + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_MIFI_1][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 25:// input No. + result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); + if(result >= 1) + { + //SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_BUY_FOR_OTHER]);// menu 1-4 + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 3; + shmp->process_info.funnel = 0; + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 26:// Balance Check + if (1) + { + pps_send_rest_free_resource_req(portid);// send free resource req, no need to handle rsp + } + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_BALANCE_CHECK]); + retval = 1; + break; + case 27:// 0, AMA sub menu + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_AMA_1][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 28:// 7. Recharge Airtime + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// Buy for self, order->msisdn = shmp->caller_info.number + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 30;//=>Airtime Amount Input + shmp->process_info.funnel = 0; + break; + case 2:// Buy for other + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_NO]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 29;//=>input No. buy airtime for + shmp->process_info.funnel = 0; + break; + case 3:// Me2U + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SHARE_NBR]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 18;//=>input No. share airtime with + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 29:// input No. buy airtime for + result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); + if(result >= 1) + { + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT]); + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 30;// =>Airtime Amount Input + shmp->process_info.funnel = 0; + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 30:// Airtime Amount Input + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + shmp->process_info.rest_if.balance = (long)key_input; + + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_PROVIDER]); + shmp->process_info.rest_if.plan_id = 10;// mobile money + shmp->process_info.rest_if.busicode = 1000;// busicode: recharge + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 34;//select provider; 33;//enter pin + shmp->process_info.funnel = 0; + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 41:// zed Data sub 24Hrs + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DATA_1][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 42:// zed Data sub 7 days + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + case 4: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DATA_2][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 43:// zed Data sub 30 days + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DATA_3][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 51:// zed VOICE sub daily + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_VOICE_1][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 52:// zed VOICE sub weekly + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + case 4: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_VOICE_2][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 53:// zed VOICE sub monthly + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1: + case 2: + case 3: + case 4: + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); + shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_VOICE_3][key_input-1]; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 31;//select money + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 31:// select money + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// pay by balance + shmp->process_info.rest_if.plan_id = 4;// balance + if (1)//(pps_get_adaptor_flag()) + { + pps_send_rest_order_req(portid, 1001);// send bundle subs req + /*shmp->process_info.funnel = 0; + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 11;*/ + } + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]);// SendUSSDRequest + shmp->process_info.serviceInput = 0; + //shmp->process_info.sub_state_2 = 32;//paid money + retval = 1; + break; + case 2:// pay by mobile money + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_PROVIDER]); + shmp->process_info.rest_if.plan_id = 10;// mobile money + shmp->process_info.rest_if.busicode = 1001;// busicode: order + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 34;//select provider; 33;//enter pin + shmp->process_info.funnel = 0; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 32:// paid + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// complete + // send download app req + pps_send_rest_download_app_req(portid); + + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_SUBSCRIB_COMPLETE]); + retval = 1; + break; + case 0: + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 33:// enter pin, not in used currently + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + // subscribe bundle + if (1)//(pps_get_adaptor_flag()) + { + pps_send_rest_order_req(portid, 1001);// send bundle subs req + /*shmp->process_info.funnel = 0; + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 11;*/ + } + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]);//SendUSSDRequest + shmp->process_info.serviceInput = 0; + //shmp->process_info.sub_state_2 = 32;//paid money + retval = 1; + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 34:// select provider + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 1:// Airtel + case 2:// MTN + case 3:// Zemtel + case 4:// NULL + case 5:// NULL + shmp->process_info.rest_if.unit = key_input;// operator + if (strstr(yx_ussd_menu[YX_USSD_MENU_ENTER_PAY_NUMBER], "%s") != NULL) + { + char tmp_buf[160]=""; + sprintf(tmp_buf, (char *)yx_ussd_menu[YX_USSD_MENU_ENTER_PAY_NUMBER], + (char *)yx_momo_info[key_input-1]); + SendUSSDRequest(portid, tmp_buf); + } + else + { + SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_ENTER_PAY_NUMBER]); + } + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 35;//enter pay number + break; + case 0: + default: + //shmp->process_info.serviceInput = 0; + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 35:// enter pay number + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + // subscribe bundle + if (1)//(pps_get_adaptor_flag()) + { + pps_send_rest_order_req(portid, shmp->process_info.rest_if.busicode);// send bundle subs req + } + if (strstr(yx_ussd_menu[YX_USSD_MENU_MOMO_PIN], "%s") != NULL) + { + char tmp_buf[160]="", tmp_nbr[64]=""; + sprintf(tmp_nbr, "%s %s", yx_momo_info[shmp->process_info.rest_if.unit-1], shmp->process_info.tmpDigits); + sprintf(tmp_buf, (char *)yx_ussd_menu[YX_USSD_MENU_MOMO_PIN], tmp_nbr); + SendPSSREnd(portid, tmp_buf);//SendUSSDRequest + } + else + { + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_MOMO_PIN]);//SendUSSDRequest + } + shmp->process_info.serviceInput = 0; + //shmp->process_info.sub_state_2 = 32;//paid money + retval = 1; + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + case 36:// cancel auto renewal + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + if(strlen(shmp->process_info.tmpDigits) > 1) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + + if(isdigit(shmp->process_info.tmpDigits[0]) == 0) + { + //shmp->process_info.sub_state_2 = 1; + //shmp->process_info.funnel = 0; + break; + } + else + { + key_input = atoi(shmp->process_info.tmpDigits); + switch(key_input) + { + case 2:// Yes + // send cancel auto renewal req + shmp->process_info.rest_if.plan_id = 4;// balance + pps_send_rest_order_req(portid, 1002); + SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]);//SendUSSDRequest + shmp->process_info.serviceInput = 0; + //shmp->process_info.sub_state_2 = 32;//paid money + retval = 1; + break; + case 0: + case 1:// No + default: + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 1; + shmp->process_info.funnel = 0; + break; + } + } + } + else if(result == -1) + { +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report + pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); +#endif + SendPSSRResponse(portid); + retval = 1; + } + break; + } + + return retval; +} + +int pps_third_party_channel_process(u_short portid) +{ + int retval = 0, result; + int key_input; + char ussd_data[256]; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + if(shmp->process_info.rest_if.timer ++ > 100*CYCLE_STATE_INTERVAL) + { + return -1; + } + + switch(shmp->process_info.sub_state_2) + { + case 1: + shmp->process_info.ppsService.chnl_info.input[0] = '\0'; + shmp->process_info.ppsService.chnl_info.prompt[0] = '\0'; + sprintf(shmp->process_info.ppsService.chnl_info.sessId,"%04d%02d%02d%02d%02d%02d%s", + time_now[0],time_now[1],time_now[2], + time_now[3],time_now[4],time_now[5], shmp->caller_info.number); + pps_send_rest_channel_req(portid);// send channel req + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 2; + break; + case 2: + if(shmp->process_info.rest_if.recv_cmd == 0) + break; + result = shmp->process_info.rest_if.result; + + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d, recv channel_res, result=%d\33[0m", + portid, result); + } + + if(result != 0)// error + { + SendPSSRResponse(portid); + retval = 1; + } + else + { + if (shmp->process_info.ppsService.chnl_info.sess_state == 1)// continue + { + sprintf(ussd_data, "%s", shmp->process_info.ppsService.chnl_info.prompt); + SendUSSDRequest(portid, ussd_data); + shmp->process_info.funnel = 0; + shmp->process_info.rest_if.timer = 0; + shmp->process_info.serviceInput = 0; + shmp->process_info.sub_state_2 = 3; + } + else// 0, terminate + { + sprintf(ussd_data, "%s", shmp->process_info.ppsService.chnl_info.prompt); + SendPSSREnd(portid, ussd_data); + retval = 1; + } + } + break; + case 3: + result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); + if(result >= 1) + { + strncpy(shmp->process_info.ppsService.chnl_info.input, shmp->process_info.tmpDigits, MAX_ASCII_NUMBER_LEN-1); + pps_send_rest_channel_req(portid);// send channel req + shmp->process_info.funnel = 0; + shmp->process_info.rest_if.timer = 0; + shmp->process_info.rest_if.recv_cmd = 0; + shmp->process_info.sub_state_2 = 2; + } + else if(result == -1) + { + SendPSSRResponse(portid); + retval = 1; + } + break; + default: + retval = -1; + break; + } + + return retval; +} + +// + diff --git a/mss/pps/src/main/precard.c b/mss/pps/src/main/precard.c new file mode 100644 index 0000000..a51a11a --- /dev/null +++ b/mss/pps/src/main/precard.c @@ -0,0 +1,2184 @@ +#include "../include/includes.h" +#include "../include/message.h" +#include "../include/ppsm.h" +#include "../include/cdrme.h" +#include "../include/ramdata.h" +#include "../include/mfunc.h" +#include "../include/config.h" +#include "../include/param.h" +#include "../include/precard.h" + +#include "../include/plat_inc.h" + +/*-----------------------------------------------------*/ +_USED_REPAID_CARD_BUFFER usedPrepaidCardBuffer={0,0}; +/*-----------------------------------------------------*/ +extern _state_machine *smshm_ptr; +extern _ram_data *ramshm_ptr; +extern char prog_name[12]; +extern char alarm_code[2]; +extern int subSystemID; +extern _pps_cdr_buffer pps_cdr_buffer; +extern _load_file load_file; /* 0,1,2=user data/tariff data/prepaid card */ +extern struct timeval tvnow; +extern u_long PPS_OID_PREFIX[]; +extern u_long LOCAL_IP; +extern u_char logMsgFlag; +extern u_long peer_server_ip; +extern u_short debug_messages; +/*-----------------------------------------------------*/ +static u_long card_counter[MAX_VALUE_TYPE]={0,0,0,0}; +_free_mem_quence freeQuence; +_climax_quence climaxQuence; +extern PPSParamStruct ppsParam; +static u_char replaceCardFlag=0; +/*-----------------------------------------------------*/ +int GetClimaxQuenceStorePos(u_char *card_pwd,int start,int end); +int AddNewCardIntoClimaxQuence(_recharge_card_info *cardShmp); +int searchCardByIndex(int instance); +int GetClimaxQuenceStorePosByCardNo(long long card_no,int start,int end); +int DeleteCardFromClimaxQuence(_recharge_card_info *cardInfo,int store_pos); +int UpdateCardInfo(_recharge_card_info *cardShmp); +void DeleteCardFaceValue(long face_value); +extern int pps_real_update_card_file(int head, int tail); +extern void ReadSyncMessageForInit(); + +int StorePrepaidCard(int *head_no, int head) +{ + int loop; + _card_data *shmp=&ramshm_ptr->card_data; + + PutLogFunID("StorePrepaidCard"); + + for(loop=0;loopprepaid_card_head[loop]) + && shmp->segment_used_flag[loop]) + { + *head_no = loop; + return 1; + } + } + + for(loop=0;loopsegment_used_flag[loop] == 0) + { + *head_no = loop; + return 2; + } + } + return -1; +} + +int InquiryPrepaidCardStorePos(long long head) +{ + int loop; + _card_data *shmp=&ramshm_ptr->card_data; + + PutLogFunID("InquiryPrepaidCardStorePos"); + + for(loop=0;loopprepaid_card_head[loop]) + && shmp->segment_used_flag[loop]) + { + return loop; + } + } + return -1; +} + +void CardHeadInDecrement(int flag) +{ + char buf[32]=""; + + PutLogFunID("CardHeadInDecrement"); + + if(flag) + debugmib.measurement.cardheadnumber ++; + else + debugmib.measurement.cardheadnumber --; + sprintf(buf,"%08ld",debugmib.measurement.cardheadnumber); + AsciiToBcd(&debugmib.measurement.card_number[4],buf,8); +} + +void CardNumberInDecrement(int flag) +{ + char buf[32]=""; + + PutLogFunID("CardNumberInDecrement"); + + if(flag) + debugmib.measurement.cardnumber ++; + else + debugmib.measurement.cardnumber --; + sprintf(buf,"%08ld",debugmib.measurement.cardnumber); + AsciiToBcd(&debugmib.measurement.card_number[0],buf,8); +} + +void DeletePrepaidCardHead(int head) +{ + int loop; + char buf[16]; + + _card_data *shmp=&ramshm_ptr->card_data; + + PutLogFunID("DeletePrepaidCardHead"); + + for(loop=0;loopprepaid_card[head][loop].card_no[MAX_CARD_LENGTH]>=12) + { + return; + } + } + shmp->prepaid_card_head[head] = 0; + shmp->segment_used_flag[head] = 0; + CardHeadInDecrement(0); + sprintf(buf,"%08d",0); + AsciiToBcd(debugmib.measurement.card_prefix[head],buf,8); + +} + +/*-----------------------------------------------------*/ + +void SetReplaceCardFlag(u_char flag) +{ + replaceCardFlag = flag; + DebugMsg(debugmib.display.asciiOut,"replace flag: %d",replaceCardFlag); +} + +int ImportPrepaidCardData(char *carddata) +{ + _recharge_card_info *shmp=NULL, card_info; + char buf[BUFSIZE]={""},buftmp[32],*token; + int len,retval, i, index=0,instance=0; + const char delimiter[]=",;"; + + PutLogFunID("ImportPrepaidCardData"); + + shmp=&card_info; + token = buf; + + if(strlen(carddata)<10) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Error: Wrong record length : %s\n",carddata); + } + return 0; + } + + while(index<8) + { + token = strsep((char **)&(carddata),delimiter); + if(token == NULL) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Error: Wrong record : %s\n",carddata); + } + return 0; + } + + strcpy(buf,token); + + switch(index) + { + case 0x00: /* card number */ + len = strlen(buf); + if(len>MAX_CARD_LENGTH*2 || len<12 || len%2) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Error: Wrong card no length : %s\n",buf); + } + return 0; + } + for(i=0;i'9' || buf[i]<'0' || buf[0] =='0') + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Error: Wrong card format:%s\n",buf); + } + return 0; + } + } + AsciiToBcd(shmp->card_no,buf,len); + shmp->card_no[MAX_CARD_LENGTH] = len; + strcpy(buftmp,buf); + break; + case 0x01: /* PWD */ + if(strlen(buf)!=16) + return 0; + AsciiToBcd(shmp->card_pwd,buf,16); + break; + case 0x02: /* face value */ + shmp->face_value = atoi(buf); + break; + case 0x03: /* card status */ + shmp->card_status = atoi(buf); + break; + case 0x04: /* expiry_date */ + shmp->expiry_date = atol(buf); + break; + case 0x05: /* valid_time */ + shmp->valid_time = atoi(buf); + break; + case 0x06: /* msisdn_used */ + strcpy(shmp->msisdn_used,buf); + break; + case 0x07: /* updated_date */ + //string2ltime(&nowtime,buf); + //shmp->updated_date = nowtime; + shmp->updated_date = tvnow.tv_sec; + break; + default: + break; + }/* switch */ + index++; + } + + retval = SetPrepaidCardFaceValue(shmp->face_value); + + if(retval == 0) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Error: there are 4 types of face value, cann't store any more!\n"); + } + return 0; + } + + if(replaceCardFlag) + { + if((instance=GetClimaxQuenceStorePos(shmp->card_pwd, 0 , climaxQuence.counter))>=0) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Warning: card %s is inuse, is replaced!\n",buftmp); + } + UpdateCardInfo(shmp); + DeleteCardFaceValue(shmp->face_value); + } + else if(AddNewCardIntoClimaxQuence(shmp)<0) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Error: buffer is full,no space to store new card!\n"); + } + DeleteCardFaceValue(shmp->face_value); + return 0; + } + return 1; + } + + if((instance=GetClimaxQuenceStorePos(shmp->card_pwd, 0 , climaxQuence.counter))>=0) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Warning: card %s is inuse, cann't be replaced!\n",buftmp); + } + DeleteCardFaceValue(shmp->face_value); + return 0; + } + + if(AddNewCardIntoClimaxQuence(shmp)<0) + { + if(load_file.log_fp[_FILE_ID_PREPAID_CARD] != NULL) + { + fprintf(load_file.log_fp[_FILE_ID_PREPAID_CARD], + "Error: buffer is full,no space to store new card!\n"); + } + DeleteCardFaceValue(shmp->face_value); + return 0; + } + + return 1; +} + +int CheckCardPWD(char *pin) +{ + char pwd[256],buf[256]; + int instance; + + strcpy(pwd,pin); + + EncryptCardHRN(pin, (u_char *)pwd); + + if((instance = GetClimaxQuenceStorePos((u_char *)pwd, 0 , climaxQuence.counter))<0) + { + DebugMsg(debugmib.display.asciiOut, + "Warning: not found card with PWD< %s >!",pin); + BcdToAscii(buf, (BYTE *)pwd,16); + DebugMsg(debugmib.display.asciiOut,"%s-%s", + pin,buf); + + } + else + { + searchCardByIndex(instance); + } + + + return 1; +} + +int RechargeCardRequest(u_short proc_id,char *card_hrn,int *result) +{ + char card_pwd[64]=""; + int len; + int cardsqu=0,cardtail=0; + _recharge_card_info *cardshmp=NULL; + _state_data *shmp=NULL; + + PutLogFunID("RechargeCardRequest"); + shmp =(_state_data *) &smshm_ptr->state_data; + shmp += proc_id; + + len = strlen(card_hrn); /* to judge length of pwd,6,8 */ + + + if(len <10 || len >18 ) + { +#if DEBUG + if(debug_messages!",card_hrn); + } + #endif + *result = 1; /* no card found */ + return 0; + } + cardtail = cardsqu % MAX_CARD_NUM_PSEG; + cardsqu = cardsqu / MAX_CARD_NUM_PSEG; + + cardshmp=&ramshm_ptr->card_data.prepaid_card[cardsqu][cardtail]; + + + if(memcmp(card_pwd,cardshmp->card_pwd,MAX_CARD_HRN_BLEN)) + { /* error password */ +#if DEBUG + if(logMsgFlag & 0x01 || logMsgFlag & 0x02 || + logMsgFlag & 0x04 || + logMsgFlag & 0x10 ) + { + char buf[64]; + BcdToAscii(buf,cardshmp->card_pwd,16); + DebugMsg(debugmib.display.asciiOut, + "Warning: Error password! %s-%s",card_hrn,buf); + } + #endif + *result = 2; /* error pwd */ + return 0; + } + + if(cardshmp->card_status != CARD_FRESH && cardshmp->card_status !=CARD_AS_CC_USED) + { +#if DEBUG + if(logMsgFlag & 0x01 || logMsgFlag & 0x02 || + logMsgFlag & 0x04 || logMsgFlag & 0x10 ) + { + DebugMsg(debugmib.display.asciiOut, + "Warning: This card has been recharged!"); + } +#endif + *result = 3; /* card used */ + return 0; + } + + if(cardshmp->expiry_datecard_info.cardhead = cardsqu; + shmp->card_info.cardtail = cardtail; + memcpy(&shmp->context_info.context, cardshmp,sizeof(_recharge_card_info)); + { + int balance; + _account_info *account_ptr; + + if(shmp->process_info.rechargeByOther ==1) + { + account_ptr = &shmp->recharge_info; + } + else + account_ptr = &shmp->caller_info; + + if(GetAccountPos(account_ptr)==FALSE) + balance = 0; + else + balance = (int)GetAccountBalance(account_ptr->head,account_ptr->tail); + + balance += GetRechargeCardFaceValue(shmp); + if(balance >= ppsParam.serviceControl.maxBalance) + { + #if DEBUG + if(logMsgFlag & 0x02 || logMsgFlag & 0x04 || logMsgFlag & 0x10 ) + { + DebugMsg(debugmib.display.asciiOut, + "Recharge failed for balance+card value>maxBalance"); + } + #endif + *result = 5; /* too much money */ + return 0; + } + } + +#if DEBUG + if(debug_messages<=MAX_DEBUG_MESSAGES) + if(logMsgFlag & 0x02 || logMsgFlag & 0x04 || logMsgFlag & 0x10 ) + { + debug_messages ++; + DebugMsg(debugmib.display.asciiOut, + "Face value: %d, valid days: %d",cardshmp->face_value,cardshmp->valid_time); + } +#endif + + memcpy(&shmp->context_info.context, cardshmp,sizeof(_recharge_card_info)); + return 1; +} + +int SendPrepaidCardRealSync(int instance,int ocode) +{ + _recharge_card_info *cardshmp=NULL; + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + int cardhead, cardtail; + + PutLogFunID("SendPrepaidCardRealSync"); + cardhead = instance/MAX_CARD_NUM_PSEG; + cardtail = instance%MAX_CARD_NUM_PSEG; + + cardshmp=&ramshm_ptr->card_data.prepaid_card[cardhead][cardtail]; + + snmpbuf.pdu_type = PDU_TRAP; /* trap */ + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; + snmpaddr.local_ip = LOCAL_IP; + snmpaddr.remote_port = PPS_REALSYNC_PORT; + snmpaddr.local_port = PPS_REALSYNC_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 17; + varlist->vartype = 0x04; + + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x02; /* configuration */ + varlist->oid[12] = 0x02; /* database */ + varlist->oid[13] = 0x03; /* prepaid card */ + varlist->oid[14] = 0x01; /* prepaid card */ + varlist->oid[15] = instance; + varlist->oid[16] = ocode; + varlist->msglen = sizeof(_recharge_card_info); + memcpy(varlist->msg, cardshmp, sizeof(_recharge_card_info)); + + if (realSyncTcpSend(PPS_PREPAID_CARD_DB_OID, instance, ocode, varlist->msg, varlist->msglen) < 0) + { + snmp_send(&snmpbuf,&snmpaddr); + } + + if(ocode==4 || ocode == 5) + { + snmpaddr.remote_ip = LOCAL_IP; + snmp_send(&snmpbuf,&snmpaddr); + } + + return 1; +} + + +static int DeleteCardInfo(_recharge_card_info *cardShmp) +{ + int instance; + char buf[64]; + + if((instance=GetClimaxQuenceStorePos(cardShmp->card_pwd, + 0 , climaxQuence.counter))>=0) + { + MoveUsedCardToBuffer(instance); + } + else + { + BcdToAscii(buf,cardShmp->card_no,cardShmp->card_no[MAX_CARD_LENGTH]%17); + DebugMsg(debugmib.display.asciiOut, + "Update card: %s, card not found!",buf); + + return 0; + } + + return 1; + +} + +void PrepaidCardTcpRealSyncProc(BYTE *pdata, WORD dataLen, DWORD instance, DWORD ocode) +{ + int head, tail; + _recharge_card_info *shmp = NULL, card_info; + + PutLogFunID("PrepaidCardTcpRealSyncProc"); + + if(dataLen != sizeof(_recharge_card_info)) + { + return; + } + +#if DEBUG + if ((logMsgFlag & 0x02) && (debug_messages<=MAX_DEBUG_MESSAGES)) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "prepaid card tcp real sync: instance: %d ocode: %d\n", instance, ocode); + } +#endif + + head = instance/MAX_CARD_NUM_PSEG; + tail = instance%MAX_CARD_NUM_PSEG; + + if (head >= MAX_CARD_SEGMENT || tail >= MAX_CARD_NUM_PSEG) + { + return ; + } + + if(ocode==5 || ocode == OMC_OCODE_EDIT) // 2: updated + {/* + shmp=&ramshm_ptr->card_data.prepaid_card[head][tail]; + if(shmp->card_no[MAX_CARD_LENGTH] == 0) + { + return ; + } + + memcpy(shmp, pdata, sizeof(_recharge_card_info)); + pps_real_update_card_file(head, tail);*/ + + + shmp = &card_info; + memcpy(shmp, pdata, sizeof(_recharge_card_info)); + UpdateCardInfo(shmp); + return ; + } + + if (ocode == OMC_OCODE_DEL)// 4: del + {/* + shmp=&ramshm_ptr->card_data.prepaid_card[head][tail]; + if(shmp->card_no[MAX_CARD_LENGTH] == 0) + { + return ; + } + + memcpy(shmp, pdata, sizeof(_recharge_card_info)); + MoveUsedCardToBuffer(instance);*/ + + shmp = &card_info; + memcpy(shmp, pdata, sizeof(_recharge_card_info)); + DeleteCardInfo(shmp); + } + else if (ocode == OMC_OCODE_ADD)// 3: add + {/* update head */ + shmp = &card_info; + memcpy(shmp, pdata, sizeof(_recharge_card_info)); + AddNewCardIntoClimaxQuence(shmp); + }/* else add prepaid card */ + + /* + if(reflag) + { + SendPrepaidCardRealSync(oid[15],oid[16]); + } + */ + return; +} + + +void PrepaidCardRealSyncMessageProc(u_char oidLen, + DWORD *oid, u_char *pdata, u_short dataLen,int reflag) +{ + int instance, /*head, tail, */ocode; + + _recharge_card_info *shmp=NULL,card_info; + + PutLogFunID("PrepaidCardRealSyncMessageProc"); + if(oidLen<16) return; + if(dataLen != sizeof(_recharge_card_info)) return; + + instance = oid[15];/* instance */ + ocode = oid[16];/* ocode */ + +#if DEBUG + if((logMsgFlag & 0x02) && (debug_messages<=MAX_DEBUG_MESSAGES)) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "prepaid card real sync: instance: %d ocode: %d\n",instance,ocode); + } +#endif + //head = instance/MAX_CARD_NUM_PSEG; + //tail = instance%MAX_CARD_NUM_PSEG; + if(ocode==5 || ocode == OMC_OCODE_EDIT) //updated + {/* + shmp=&ramshm_ptr->card_data.prepaid_card[head][tail]; + if(shmp->card_no[MAX_CARD_LENGTH] == 0) + return ; + memcpy(shmp,pdata,sizeof(_recharge_card_info)); + + pps_real_update_card_file(head, tail);*/ + + shmp = &card_info; + memcpy(shmp, pdata, sizeof(_recharge_card_info)); + UpdateCardInfo(shmp); + return ; + } + if(ocode==OMC_OCODE_DEL){ + /*shmp=&ramshm_ptr->card_data.prepaid_card[head][tail]; + if(shmp->card_no[MAX_CARD_LENGTH] == 0) + return ; + memcpy(shmp,pdata,sizeof(_recharge_card_info)); + MoveUsedCardToBuffer(instance);*/ + + shmp = &card_info; + memcpy(shmp, pdata, sizeof(_recharge_card_info)); + DeleteCardInfo(shmp); + } + else + {/* update head */ + shmp = &card_info; + memcpy(shmp,pdata,sizeof(_recharge_card_info)); + AddNewCardIntoClimaxQuence(shmp); + }/* else add prepaid card */ + /* + if(reflag){ + SendPrepaidCardRealSync(oid[15],oid[16]); + } + */ +} + +int UpdateRechargeCard(u_short proc_id, int status) +{ + int cardhead,cardtail; + _recharge_card_info *cardshmp=NULL; + _state_data *shmp=NULL; + int ocode = 5; /*default to delete card for being recharged */ + + PutLogFunID("UpdateRechargeCard"); + shmp =(_state_data *) &smshm_ptr->state_data; + shmp += proc_id; + + cardhead = shmp->card_info.cardhead; + cardtail = shmp->card_info.cardtail; + + cardshmp=&ramshm_ptr->card_data.prepaid_card[cardhead][cardtail]; + + cardshmp->card_status = status; + cardshmp->updated_date = tvnow.tv_sec; + + strcpy(cardshmp->msisdn_used, (char *)shmp->caller_info.number); + + if(shmp->process_info.ccc_flag ) + ocode = 2; + SendPrepaidCardRealSync(cardhead*MAX_CARD_NUM_PSEG+cardtail, ocode); + + pps_real_update_card_file(cardhead, cardtail); + + return 1; +} + +int UpdateRechargeCardBalance(_card_info *card_info, float charge) +{ + int cardhead,cardtail; + _recharge_card_info *cardshmp=NULL; + + PutLogFunID("UpdateRechargeCardBalance"); + + + cardhead = card_info->cardhead; + cardtail = card_info->cardtail; + + cardshmp = &ramshm_ptr->card_data.prepaid_card[cardhead][cardtail]; + + cardshmp->face_value += ceil(charge+0.5); + cardshmp->updated_date = tvnow.tv_sec; + + SendPrepaidCardRealSync(cardhead*MAX_CARD_NUM_PSEG+cardtail, 2);//modify + + pps_real_update_card_file(cardhead, cardtail); + + return 1; +} + +int SetPrepaidCardFaceValue(long face_value) +{ + int i; + + PutLogFunID("SetPrepaidCardFaceValue"); + if(face_value >1000000) return 0; + + for(i=0;icard_data.face_value[i]) + { + card_counter[i] ++; + return 1; + } + } + + for(i=0;icard_data.face_value[i]==0) + { + ramshm_ptr->card_data.face_value[i] = face_value; + card_counter[i] ++; + return 1; + } + } + return 0; +} + +void PrintfCounter() +{ + int i; + + for(i=0;icard_data.face_value[i],i, card_counter[i]); + } +} + +int GetCardIndex(long face_value) +{ + int i; + + PutLogFunID("GetCardIndex"); + if(face_value == 0) return -1; + for(i=0;icard_data.face_value[i]==face_value ){ + return i; + } + } + return -1; +} + +void DeleteCardFaceValue(long face_value) +{ + int i; + + PutLogFunID("DeleteCardFaceValue"); + if(face_value == 0) return ; + for(i=0;icard_data.face_value[i]==face_value ) + { + card_counter[i] --; + if(card_counter[i]<=0) + { + card_counter[i] = 0; + ramshm_ptr->card_data.face_value[i] = 0; + } + return ; + } + } + +} + +static int pps_reuse_recharge_card = 0; + +void SetPPSRechargeCardReusable(int flag) +{ + pps_reuse_recharge_card = flag; +} + +int SetPrepaidCardByOMC(u_char oidlen, DWORD *oid, BYTE *pdata, u_short datalen) +{ + int instance,ocode; + int head,tail,len; + int vallen;//chargeFlag=0; + char buf[1025]={""},workbuf[128]={""}; + char valbuf[128]=""; + //struct tm tmnow; + long long cardNo; + int totalLen=0; + int loop=0; + BYTE pdata1[1601],pdata2[1025],pflag; + + u_short ptagcode; + char tagbuf[32]; + _recharge_card_info *shmp=NULL; + + ASN_BUF *asnbuf, asnbuf1; + ASN_BUF *asnbuf2, asnbuf3; + + PutLogFunID("SetPrepaidCardByOMC"); + + memset(pdata1, 0, datalen+1); + memcpy(pdata1,pdata,datalen); + + asnbuf = &asnbuf1; + AsnEncode(pdata,1024,asnbuf); + + asnbuf2 = &asnbuf3; + AsnDecode(pdata1, 1024, UNIT_STORE_ACCOUNT, NULL, asnbuf2); + + +#if DEBUG1 + BcdToAscii(buf,pdata1,datalen*2); + DebugMsg(debugmib.display.asciiOut,"received prepaid card data omc message"); + + for(i=0;i0x04) return 0; + + sprintf(buf,"%u",oid[13]); + sprintf(workbuf,"%08u",oid[14]); + strcat(buf,workbuf); + + cardNo = atoll(buf); + instance = GetClimaxQuenceStorePosByCardNo(cardNo,0,climaxQuence.counter); +#if DEBUG1 + DebugMsg(debugmib.display.asciiOut,"prepaid card: %lld,ocode: %d,instance:%d", + cardNo,ocode,instance); +#endif + + if(instance<0) + { + #if DEBUG + if(logMsgFlag & 0x01 || logMsgFlag & 0x02 || + logMsgFlag & 0x04 || + logMsgFlag & 0x10 ) + { + DebugMsg(debugmib.display.asciiOut, + "Warning: Error card number %lld, not found,%d!",cardNo,climaxQuence.counter); + } + #endif + return -1; + } + else + { + //DebugMsg(debugmib.display.asciiOut, + // "Get card %s, found,%d!",buf,instance); + + } + head = instance / MAX_CARD_NUM_PSEG; + tail = instance % MAX_CARD_NUM_PSEG; + + shmp = &ramshm_ptr->card_data.prepaid_card[head][tail]; + +#if DEBUG1 + DebugMsg(debugmib.display.asciiOut,"instance: %d,ocode:%d",instance,ocode); +#endif + + if(ocode ==OMC_OCODE_DEL){ /* delete */ + SendPrepaidCardRealSync(instance,ocode); + //MoveUsedCardToBuffer(instance); + return datalen; + } + + /* + if(ocode == 3) + { + sprintf(pdata,"Operation not supported"); + return -2; + } + else + */ + {/* read */ + for(loop=1;loop<10;loop++) + { + sprintf(tagbuf,"-%d",loop); + if((vallen=GetAnyTLV(tagbuf,1024,pdata2,&pflag,&ptagcode,asnbuf2))<0){ + break; + } + else + { + pdata2[vallen]=0; + sprintf(tagbuf,"%d",ptagcode); + //printf("tag:%d\n",ptagcode); + if(ptagcode<=0 || ptagcode>MAX_CARD_NUM_PSEG) continue; + switch(ptagcode) + { + case 0x01: /* card number */ + if(ocode==1){ + BcdToAscii(valbuf,shmp->card_no,MAX_CARD_LENGTH*2); + len = shmp->card_no[MAX_CARD_LENGTH]; + if(len==0) return -1; + len = len % 17; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else if(ocode==2 || ocode ==3) + { + /* + AsciiToBcd(shmp->card_no,pdata2,vallen*2); + shmp->card_no[MAX_CARD_LENGTH] = vallen; + */ + + vallen = shmp->card_no[MAX_CARD_LENGTH]; + BcdToAscii(valbuf,shmp->card_no,vallen*2); + if(strcmp(valbuf, (char *)pdata2)) + { + sprintf((char *)pdata,"can't change card no."); + return -2; + } + else + { + totalLen = add_tlv(tagbuf,vallen, (u_char *)valbuf,0x80,asnbuf); + } + } + break; + case 0x02: /* pwd */ + if(ocode==1){ + len = MAX_CARD_HRN_BLEN; + memcpy(valbuf,&shmp->card_pwd,MAX_CARD_HRN_BLEN); + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else if(ocode==2 || ocode==3){ + if(memcmp(shmp->card_pwd ,pdata2,vallen)) + { + sprintf((char *)pdata,"password not changed!"); + return -2; + } + totalLen = add_tlv(tagbuf, + MAX_CARD_HRN_BLEN, + shmp->card_pwd, + 0x80, + asnbuf); + } + break; + case 0x03: /* face value */ + if(ocode==1){ + totalLen = AddInteger(tagbuf,shmp->face_value,0x80,asnbuf); + }else if(ocode==2 || ocode==3){ + totalLen = AddInteger(tagbuf,shmp->face_value,0x80,asnbuf); + } + break; + case 0x04: /* card status */ + if(ocode==1){ + len = 1; + valbuf[0] = shmp->card_status ; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else if(ocode==2 || ocode==3) + { + if(pdata2[0] >2) + { + sprintf((char *)pdata,"error field value,should be 0-2."); + return -2; + } + + if(shmp->card_status == 1 && pdata2[0] == 0) + { + if(pps_reuse_recharge_card) + { + shmp->card_status = pdata2[0] ; + pps_reuse_recharge_card = 0; + } + else + { + + sprintf((char *)pdata,"Operation not supported!"); + return -2; + } + } + else if(shmp->card_status == 0 && pdata2[0] == 2) + { + // chargeFlag = 1; + shmp->card_status = pdata2[0]; + totalLen = add_tlv(tagbuf,1,&shmp->card_status,0x80,asnbuf); + } + else if(shmp->card_status == 2 && pdata2[0] == 0) + { + shmp->card_status = pdata2[0]; + totalLen = add_tlv(tagbuf,1,&shmp->card_status,0x80,asnbuf); + } + else + { + sprintf((char *)pdata,"Operation not supported!"); + return -2; + } + + totalLen = add_tlv(tagbuf,1,&shmp->card_status,0x80,asnbuf); + } + break; + case 0x05: /* expiry_date */ + if(ocode==1) + { + len = 7; + AsciiTime(buf,shmp->expiry_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else if(ocode==2 || ocode==3) + { + /* + BcdToAscii(buf,pdata2,vallen*2); + shmp->expiry_date = MakeTime(&tmnow,buf); + AsciiTime(buf,shmp->expiry_date); + AsciiToBcd(valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len,valbuf,0x80,asnbuf); + */ + } + break; + case 0x06: /* valid_time */ + if(ocode==1){ + len = 4; + totalLen = AddInteger(tagbuf,shmp->valid_time,0x80,asnbuf); + }else if(ocode==2 || ocode==3){ + } + break; + case 0x07: /* msisdn_used */ + if(ocode==1){ + len = strlen(shmp->msisdn_used); + if(len>16) len=16; + if(shmp->msisdn_used[0]=='0') len=0; + totalLen = add_tlv(tagbuf,len, (u_char *)shmp->msisdn_used,0x80,asnbuf); + } + else if(ocode==2 || ocode==3) + { + if(vallen>18) + { + vallen = 18; + pdata2[vallen] = 0; + } + if(vallen<1) + memset(shmp->msisdn_used,0,18); + + if(pdata2[0] == 'F') + { + vallen = 0; + memset(shmp->msisdn_used,0,18); + } + else + { + strcpy(shmp->msisdn_used, (char *)pdata2); + } + totalLen = add_tlv(tagbuf,vallen, (u_char *)shmp->msisdn_used,0x80,asnbuf); + + } + break; + case 0x08: /* updated_date */ + if(ocode==1){ + AsciiTime(buf,shmp->updated_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + } + else if(ocode==2 || ocode==3) + { + BcdToAscii(buf,pdata2,vallen*2); + shmp->updated_date = MakeTime(NULL,buf); + + AsciiTime(buf,shmp->updated_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + + } + break; + default: + break; + }/* switch */ + }/* else */ + }/* for */ + + if(ocode==1) + { /* read */ + //BcdToAscii(buf,pdata,totalLen*2); + //printf("len:%d code:%s\n",totalLen,buf); + datalen = totalLen; + } + else + { + //if(chargeFlag) + //{ + // SendManualRechargeCDR(shmp); + //} + pps_real_update_card_file(head, tail); + + SendPrepaidCardRealSync(instance,ocode); + } + } + return datalen; +} + +/*--------------------------------------------------*/ +void MoveUsedCardToBuffer(int instance) +{ + int head,tail,head0,tail0; + int len; + _recharge_card_info *shmp=NULL; + + PutLogFunID("MoveUsedCardToBuffer"); + + head0 = instance/MAX_CARD_NUM_PSEG; + tail0 = instance%MAX_CARD_NUM_PSEG; + if(head0>=MAX_CARD_SEGMENT) return; + shmp = &ramshm_ptr->card_data.prepaid_card[head0][tail0]; + + DeleteCardFaceValue(shmp->face_value); + + head = usedPrepaidCardBuffer.ptrHead; + tail = usedPrepaidCardBuffer.ptrTail%MAX_USED_CARD_STORED; + + memcpy(&usedPrepaidCardBuffer.used_precard[tail], + shmp, + sizeof(_recharge_card_info)); + tail ++; + tail = tail %0x80000000; + if (tail == head ) + { + head ++; + head = head %0x80000000; + } + usedPrepaidCardBuffer.ptrHead = head; + usedPrepaidCardBuffer.ptrTail = tail ; + + len = shmp->card_no[MAX_CARD_LENGTH]; + if(len<12 || len%2==1 || len>20) + return; + + if(DeleteCardFromClimaxQuence(shmp,instance)<0) + { + return; + } + //CardNumberInDecrement(0); + + memset(shmp,0,sizeof(_recharge_card_info)); + + pps_real_update_card_file(head0, tail0); + + //DeletePrepaidCardHead(head0); +} + +int GetUsedPrepaidCard(u_char oidLen,DWORD *oid, u_char *pdata,BYTE *vartype) +{ + int instance,totalLen=0,i,len; + int index; + char valbuf[128]="",tagbuf[4]="",buf[32]=""; + ASN_BUF *asnbuf,asnbuf1; + _recharge_card_info *shmp=NULL; + + *vartype = 0x04; + + PutLogFunID("GetUsedPrepaidCard"); + + if(oid[13]==0x01)/* head pointer */ + { + pdata[0] = usedPrepaidCardBuffer.ptrHead>>24; + pdata[1] = usedPrepaidCardBuffer.ptrHead>>16; + pdata[2] = usedPrepaidCardBuffer.ptrHead>>8; + pdata[3] = usedPrepaidCardBuffer.ptrHead; + *vartype = 0x02; + return 4; + }else if(oid[13]==0x02)/* tail pointer */ + { + pdata[0] = usedPrepaidCardBuffer.ptrTail>>24; + pdata[1] = usedPrepaidCardBuffer.ptrTail>>16; + pdata[2] = usedPrepaidCardBuffer.ptrTail>>8; + pdata[3] = usedPrepaidCardBuffer.ptrTail; + *vartype = 0x02; + return 4; + } + instance = oid[14]; + + index = instance % MAX_USED_CARD_STORED; + + asnbuf = &asnbuf1; + AsnEncode(pdata,1024,asnbuf); + + shmp = &usedPrepaidCardBuffer.used_precard[index]; + for(i=1;i<9;i++) + { + sprintf(tagbuf,"%d",i); + switch(i) + { + case 1: + BcdToAscii(valbuf,shmp->card_no,MAX_CARD_LENGTH*2); + len = shmp->card_no[MAX_CARD_LENGTH]; + if(len>MAX_CARD_LENGTH*2) len = MAX_CARD_LENGTH*2; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + if(len==0) + { + //DebugMsg(debugmib.display.asciiOut,"Zero data of used_card: instance=%d",instance); + } + break; + case 2: + len = MAX_CARD_HRN_BLEN; + memcpy(valbuf,&shmp->card_pwd,MAX_CARD_HRN_BLEN); + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + break; + case 3: + totalLen = AddInteger(tagbuf,shmp->face_value,0x80,asnbuf); + break; + case 4: + len = 1; + valbuf[0] = shmp->card_status ; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + break; + case 5: + len = 7; + AsciiTime(buf,shmp->expiry_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + break; + case 6: + len = 4; + totalLen = AddInteger(tagbuf,shmp->valid_time,0x80,asnbuf); + break; + case 7: + len = strlen(shmp->msisdn_used); + if(shmp->msisdn_used[0]=='0') len=0; + totalLen = add_tlv(tagbuf,len, (u_char *)shmp->msisdn_used,0x80,asnbuf); + break; + case 8: + AsciiTime(buf,shmp->updated_date); + AsciiToBcd((BYTE *)valbuf,buf,14); + len = 7; + totalLen = add_tlv(tagbuf,len, (u_char *)valbuf,0x80,asnbuf); + break; + } + } + return totalLen; +} + +/*--------- store prepaid card test ---------- 06-30 -----*/ +/* +int GetClimaxQuenceIndex(u_char *card_pwd,int start,int end) +{ + int index; + + index = start + (end-start)/2; + if(start == end ) return start; + + if(memcmp(card_pwd,climaxQuence.card_pwd[index],MAX_CARD_HRN_BLEN)==0) + { + return index; + } + else if(memcmp(card_pwd,climaxQuence.card_pwd[index],MAX_CARD_HRN_BLEN)>0) + { + if(start == end-1) return end; + return GetClimaxQuenceIndex(card_pwd,index,end); + } + else + { + if(start == end-1) return start; + return GetClimaxQuenceIndex(card_pwd,start,index); + } +} + +int GetClimaxQuenceStorePos(u_char *card_pwd,int start,int end) +{ + int index; + + index = start + (end-start)/2; + if(start == end ) + { + if(strcmp(card_pwd,climaxQuence.card_pwd[start])==0) + return start; + else + return -1; + } + if(start == (end-1)) + { + if(memcmp(card_pwd,climaxQuence.card_pwd[start],MAX_CARD_HRN_BLEN)==0) + { + return start; + } + else if(memcmp(card_pwd,climaxQuence.card_pwd[end],MAX_CARD_HRN_BLEN)==0) + { + return end; + } + else + return -1; + } + + if(strcmp(card_pwd,climaxQuence.card_pwd[index])==0) + { + return index; + } + else if(strcmp(card_pwd,climaxQuence.card_pwd[index])>0) + { + return GetClimaxQuenceStorePos(card_pwd,index,end); + } + else + { + return GetClimaxQuenceStorePos(card_pwd,start,index); + } +} + +int StoreCardToClimaxQuence(u_char *card_pwd,int store_pos) +{ + int index; + _climax_quence climaxTemp; + + if(climaxQuence.counter == 0) + { + memcpy(&climaxQuence.card_pwd[climaxQuence.counter], + card_pwd, + MAX_CARD_HRN_BLEN); + climaxQuence.store_pos[0] = store_pos; + return 0; + } + else + { + index = GetClimaxQuenceIndex(card_pwd,0,climaxQuence.counter); + if(index 0) + { + if(start == end-1) return end; + return GetClimaxQuenceIndex(card_pwd,index,end); + } + else + { + if(start == end-1) return start; + return GetClimaxQuenceIndex(card_pwd,start,index); + } +} + +int GetClimaxQuenceStorePos(u_char *card_pwd,int start,int end) +{ + int index,result=0; + + if(climaxQuence.counter == 0) return -1; + if(start>end) return -1; + index = start + (end-start)/2; + + if(start == end ) + { + if(memcmp(card_pwd,climaxQuence.card_pwd[start],MAX_CARD_HRN_BLEN)==0) + return climaxQuence.store_pos[start]; + else + return -1; + } + + if(start == (end-1)) + { + if(memcmp(card_pwd , climaxQuence.card_pwd[start],MAX_CARD_HRN_BLEN)==0) + { + return climaxQuence.store_pos[start]; + } + else if(memcmp(card_pwd , climaxQuence.card_pwd[end],8)==0) + { + return climaxQuence.store_pos[end]; + } + else + return -1; + } + + result = memcmp(card_pwd, + climaxQuence.card_pwd[index], + MAX_CARD_HRN_BLEN); + if(result == 0 ) + { + return climaxQuence.store_pos[index]; + } + else if(result > 0) + { + return GetClimaxQuenceStorePos(card_pwd,index,end); + } + else + { + return GetClimaxQuenceStorePos(card_pwd,start,index); + } +} + + +int GetClimaxQuenceIndexByCardNo(long long card_no,int start,int end) +{ + int index; + + index = start + (end-start)/2; + if(start == end ) return start; + + //printf("start: %d,end: %d, index: %d, card_no: %lld - %lld\n", + // start,end,index,card_no,climaxQuence.card_no[index]); + + if(card_no == climaxQuence.card_no[index]) + { + return index; + } + else if(card_no > climaxQuence.card_no[index]) + { + if(start == end-1) return end; + return GetClimaxQuenceIndexByCardNo(card_no,index,end); + } + else + { + if(start == end-1) return start; + return GetClimaxQuenceIndexByCardNo(card_no,start,index); + } +} + +int GetClimaxQuenceStorePosByCardNo(long long card_no,int start,int end) +{ + int index; + + if(climaxQuence.counter == 0) return -1; + if(start>end) return -1; + index = start + (end-start)/2; + +// printf("start: %d,end: %d, index: %d, card_no: %lld - %lld\n", + // start,end,index,card_no,climaxQuence.card_no[index]); + + if(start == end ) + { + if(card_no==climaxQuence.card_no[start]) + return climaxQuence.store_pos_card_no[start]; + else + return -1; + } + + if(start == (end-1)) + { + if(card_no == climaxQuence.card_no[start]) + { + return climaxQuence.store_pos_card_no[start]; + } + else if(card_no == climaxQuence.card_no[end]) + { + return climaxQuence.store_pos_card_no[end]; + } + else + return -1; + } + + if(card_no == climaxQuence.card_no[index] ) + { + return climaxQuence.store_pos_card_no[index]; + } + else if(card_no > climaxQuence.card_no[index]) + { + return GetClimaxQuenceStorePosByCardNo(card_no,index,end); + } + else + { + return GetClimaxQuenceStorePosByCardNo(card_no,start,index); + } +} + +int AssignFreeQuenceMem() +{ + int pos; + + if(freeQuence.pWriteSub>0) + { + pos = freeQuence.free_pos[freeQuence.pWriteSub-1]; + freeQuence.pWriteSub --; + if(freeQuence.pWriteSub<0) + freeQuence.pWriteSub = 0; + debugmib.measurement.cardheadnumber = + freeQuence.pWriteSub; + + return pos; + } + return -1; +} + +int AddCardIntoClimaxQuence(_recharge_card_info *cardInfo,int store_pos) +{ + int index=0; + _climax_quence climaxTemp; + long long cardNo=0; + char buf[64]; + + if(climaxQuence.counter == 0) + { + memcpy(climaxQuence.card_pwd[climaxQuence.counter] , + cardInfo->card_pwd, + MAX_CARD_HRN_BLEN); + + BcdToAscii(buf,cardInfo->card_no,cardInfo->card_no[MAX_CARD_LENGTH]%17); + buf[cardInfo->card_no[MAX_CARD_LENGTH]%17] = 0; + //len = strlen(buf); + cardNo = atoll(buf); + climaxQuence.card_no[climaxQuence.counter] = cardNo; + /* + printf("%lld - %s store at %d-%d, total: %d\n", + cardNo,buf, + index,store_pos, + climaxQuence.counter); + */ + climaxQuence.store_pos[0] = store_pos; + climaxQuence.store_pos_card_no[0] = store_pos; + index = 0; + + climaxQuence.counter++; + //climaxQuence.counter %= MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG; + CardNumberInDecrement(1); + debugmib.watch_dog[16] = climaxQuence.counter ; + } + else if(climaxQuence.counter< MAX_CARD_RECORD) + { + index = GetClimaxQuenceIndex(cardInfo->card_pwd,0,climaxQuence.counter); + //printf("index: %d to store new card\n",index); + if(index<=climaxQuence.counter) + { + memcpy(&climaxTemp.card_pwd[0], + &climaxQuence.card_pwd[index], + MAX_CARD_HRN_BLEN*(climaxQuence.counter-index)); + memcpy(&climaxQuence.card_pwd[index+1], + &climaxTemp.card_pwd, + MAX_CARD_HRN_BLEN*(climaxQuence.counter-index)); + memcpy(&climaxTemp.store_pos[0], + &climaxQuence.store_pos[index], + sizeof(int)*(climaxQuence.counter-index)); + memcpy(&climaxQuence.store_pos[index+1], + &climaxTemp.store_pos, + sizeof(int)*(climaxQuence.counter-index)); + + } + memcpy(climaxQuence.card_pwd[index],cardInfo->card_pwd,MAX_CARD_HRN_BLEN); + climaxQuence.store_pos[index] = store_pos; + + BcdToAscii(buf,cardInfo->card_no,cardInfo->card_no[MAX_CARD_LENGTH]%17); + buf[cardInfo->card_no[MAX_CARD_LENGTH]%17] = 0; + cardNo = atoll(buf); + + index = GetClimaxQuenceIndexByCardNo(cardNo,0,climaxQuence.counter); + /* + printf("%lld - %s store at %d-%d, total: %d\n", + cardNo,buf, + index,store_pos, + climaxQuence.counter); + */ + if(index<=climaxQuence.counter) + { + memcpy(&climaxTemp.card_no[0], + &climaxQuence.card_no[index], + sizeof(long long)*(climaxQuence.counter-index)); + memcpy(&climaxQuence.card_no[index+1], + &climaxTemp.card_no, + sizeof(long long)*(climaxQuence.counter-index)); + + memcpy(&climaxTemp.store_pos_card_no[0], + &climaxQuence.store_pos_card_no[index], + sizeof(int)*(climaxQuence.counter-index)); + memcpy(&climaxQuence.store_pos_card_no[index+1], + &climaxTemp.store_pos_card_no, + sizeof(int)*(climaxQuence.counter-index)); + + climaxQuence.card_no[index]= cardNo; + climaxQuence.store_pos_card_no[index] = store_pos; + + } + climaxQuence.counter++; + //climaxQuence.counter %= MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG; + CardNumberInDecrement(1); + debugmib.watch_dog[16] = climaxQuence.counter ; + } + + return index; +} + +int DeleteCardFromClimaxQuence(_recharge_card_info *cardInfo,int store_pos) +{ + int index,totalIndex=MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG; + _climax_quence climaxTemp; + long long cardNo=0; + char buf[64]; + + if(climaxQuence.counter == 0) + { +// climaxQuence.card_no[climaxQuence.counter] = card_no; +// climaxQuence.store_pos[0] = store_pos; + return -1; + } + else + { + index = GetClimaxQuenceIndex(cardInfo->card_pwd,0,climaxQuence.counter); + if(memcmp(climaxQuence.card_pwd[index], + cardInfo->card_pwd, + MAX_CARD_HRN_BLEN) !=0) + return -1; + if(indexcard_no,cardInfo->card_no[MAX_CARD_LENGTH]%17); + buf[cardInfo->card_no[MAX_CARD_LENGTH]%17] = 0; + cardNo = atoll(buf); + index = GetClimaxQuenceIndexByCardNo(cardNo,0,climaxQuence.counter); + if(indexcard_data; + rear_ptr = freeQuence.pWriteSub = 0; + + for(i=MAX_CARD_SEGMENT-1;i>=0;i--) + { + if(i%10 == 0) + ReadSyncMessageForInit(); + + for(j=MAX_CARD_NUM_PSEG-1;j>=0;j--) + { + len = card_data->prepaid_card[i][j].card_no[MAX_CARD_LENGTH]; + if(len<=0 || len(MAX_CARD_LENGTH*2)) + { + memset(&card_data->prepaid_card[i][j], + 0, + sizeof(_recharge_card_info)); + freeQuence.free_pos[rear_ptr] = i*MAX_CARD_NUM_PSEG + j; + rear_ptr ++; + rear_ptr %= (MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG+1); + continue; + } + AddCardIntoClimaxQuence(&card_data->prepaid_card[i][j], + i*MAX_CARD_NUM_PSEG+j); + SetPrepaidCardFaceValue(card_data->prepaid_card[i][j].face_value); + } + } + freeQuence.pWriteSub = rear_ptr; + debugmib.watch_dog[16] = climaxQuence.counter ; + + debugmib.measurement.cardheadnumber = + freeQuence.pWriteSub; + + DebugMsg(debugmib.display.asciiOut,"rear ptr: %d, counter: %d", + rear_ptr,climaxQuence.counter); + + +} + +int UpdateCardInfo(_recharge_card_info *cardShmp) +{ + int instance,head,tail; + char buf[64]; + + if((instance=GetClimaxQuenceStorePos(cardShmp->card_pwd, + 0 , climaxQuence.counter))>=0) + { + head = instance / MAX_CARD_NUM_PSEG; + tail = instance % MAX_CARD_NUM_PSEG; + + memcpy(&ramshm_ptr->card_data.prepaid_card[head][tail], + cardShmp, + sizeof(_recharge_card_info)); + } + else + { + BcdToAscii(buf,cardShmp->card_no,cardShmp->card_no[MAX_CARD_LENGTH]%17); + DebugMsg(debugmib.display.asciiOut, + "Update card: %s, card not found!",buf); + + return 0; + } + + pps_real_update_card_file(head, tail); + + return 1; + +} + +int AddNewCardIntoClimaxQuence(_recharge_card_info *cardShmp) +{ + int freePos = -1; + unsigned int head,tail; + + freePos = AssignFreeQuenceMem(); + + + + if(freePos<0 || freePos>= MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG) + { + return -1; + } + + head = freePos / MAX_CARD_NUM_PSEG; + tail = freePos % MAX_CARD_NUM_PSEG; + + memcpy(&ramshm_ptr->card_data.prepaid_card[head][tail], + cardShmp, + sizeof(_recharge_card_info)); + + pps_real_update_card_file(head, tail); + + return AddCardIntoClimaxQuence(cardShmp,freePos); + +} + + +int GetRechargeCardByIndex(int index, char *card_no) +{ + if(index<0 || index>=climaxQuence.counter) + return 0; + + sprintf(card_no,"%lld",climaxQuence.card_no[index]); + return 1; +} +/*--------------- Debug func --------------------------------------*/ +void printfClimaxQuenceIndex() +{ + int i; + + DebugMsg(debugmib.display.asciiOut,"Total quenced :%d",climaxQuence.counter); + + for (i=0;i20 || len%2) + { + DebugMsg(debugmib.display.asciiOut,"Error card pwd:%s",pwd); + return ; + } + EncryptCardHRN(pwd, (u_char *)card_pwd); + if((storePos = GetClimaxQuenceStorePos((u_char *)card_pwd, 0 , climaxQuence.counter))<0) + { + DebugMsg(debugmib.display.asciiOut,"card [%s] not found in DB!",pwd); + return ; + } + DebugMsg(debugmib.display.asciiOut,"card [%s] stored @ [%d] in DB second area!", + pwd,storePos); + + gettimeofday(&tmend,NULL); + searchCardByIndex(storePos); + DebugMsg(debugmib.display.asciiOut,"search time: %ld.%06ld-%ld.%06ld", + tmend.tv_sec,tmend.tv_usec, + tmstart.tv_sec,tmstart.tv_usec); +} + +int searchCardByIndex(int instance) +{ + int head,tail,len; + char buf[32]; + _recharge_card_info *shmp=NULL; + _card_data *card_data; + + + if(instance>=MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG || instance<0) + { + DebugMsg(debugmib.display.asciiOut,"Error index %d, should be 0-%d!", + instance,MAX_CARD_SEGMENT*MAX_CARD_NUM_PSEG); + return 0; + } + head = instance / MAX_CARD_NUM_PSEG; + tail = instance % MAX_CARD_NUM_PSEG; + card_data = &ramshm_ptr->card_data; + shmp = &card_data->prepaid_card[head][tail]; + len = shmp->card_no[MAX_CARD_LENGTH]; + if(len<=0 || len(MAX_CARD_LENGTH*2)) + { + DebugMsg(debugmib.display.asciiOut,"Index %d not used.", + instance); + return 0; + } + BcdToAscii(buf,shmp->card_no,len); + DebugMsg(debugmib.display.asciiOut,"Card info. of index %d .", + instance); + DebugMsg(debugmib.display.asciiOut," no: %s", + buf); + BcdToAscii(buf,shmp->card_pwd,16); + DebugMsg(debugmib.display.asciiOut," card pwd: %s", + buf); + DebugMsg(debugmib.display.asciiOut," faceValue: %d", + shmp->face_value); + DebugMsg(debugmib.display.asciiOut," status: %d", + shmp->card_status); + return 1; +} + + +int ppsCleanCardFaceValue(int faceValue) +{ + static int pps_clean_card_face_value=0; + register int i,j; + + _recharge_card_info *shmp=NULL; + _card_data *card_data; + + if(faceValue == 0) + { + pps_clean_card_face_value = faceValue; + return 0; + } + if(pps_clean_card_face_value == 0) + { + pps_clean_card_face_value = faceValue; + return 0; + } + if(pps_clean_card_face_value != faceValue) + { + pps_clean_card_face_value = 0; + return 0; + } + + DebugMsg(debugmib.display.asciiOut,"\nBefore clean command:"); + PrintfCounter(); + + card_data = &ramshm_ptr->card_data; + for(i=0;iprepaid_card[i][j]; + if(shmp->face_value == faceValue) + MoveUsedCardToBuffer(i*MAX_CARD_NUM_PSEG + j); + } + + pps_clean_card_face_value = 0; + + DebugMsg(debugmib.display.asciiOut,"\nAfter clean command:"); + PrintfCounter(); + + for(i=0;icard_data.face_value[i]== faceValue && card_counter[i]) + card_counter[i] = 0; + } + return 1; +} + +float ocs_get_calling_card_left_balance(int head, int tail) +{ + _recharge_card_info *shmp=NULL; + + if(head >=MAX_CARD_SEGMENT || tail >= MAX_CARD_NUM_PSEG) + return 0; + + shmp = &ramshm_ptr->card_data.prepaid_card[head][tail]; + + return shmp->face_value; +} +/****----------------------------------------------------*/ + +DWORD RCM_OID_PREFIX_UPDATE_CARD[18]={1,3,6,1,4,1,1373,2,3,3,26,5,10}; + +int send_scf_update_card_data(u_short portid) +{ + int len,oidlen=13; + _scf_rcm_msg *scf_update_msg, msg; + char encrypt_pwd[32]; + + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + _state_data *shmp; + + PutLogFunID("send_scf_update_card_data"); + + shmp = (_state_data *)&smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + return -1; + shmp += portid; + + len = sizeof(_scf_rcm_msg); + + scf_update_msg = &msg; + memset(scf_update_msg,0x00,len); + + scf_update_msg->ocode = OC_UPDATE_CARD; + scf_update_msg->invoke_id = portid; + + EncryptCardHRN((char *)shmp->called_info.number, (u_char *)encrypt_pwd ); + memcpy(scf_update_msg->card_pwd, encrypt_pwd, MAX_CARD_HRN_BLEN); + strcpy(scf_update_msg->msisdn, (char *)shmp->caller_info.number); + + snmpbuf.pdu_type = PDU_SET; + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = ppsParam.rcm_ip; + snmpaddr.remote_port = HEART_BEATING_PORT; + snmpaddr.local_port = HEART_BEATING_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = oidlen; + varlist->vartype = 0x04; + + memcpy(&varlist->oid, RCM_OID_PREFIX_UPDATE_CARD, oidlen*4); + varlist->msglen = sizeof(_scf_rcm_msg); + + memcpy(varlist->msg, (u_char *)scf_update_msg, + sizeof(_scf_rcm_msg)); + snmp_send(&snmpbuf,&snmpaddr); + + debugmib.msgstatistics.update_card_request ++; + + #if DEBUG + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"[%04d] send update card data to RCM %08x @ %ld",portid, ppsParam.rcm_ip,tvnow.tv_sec); + DebugMsg(debugmib.display.asciiOut,"[%04d] CARD PWD: %s", portid, shmp->called_info.number); + } +#endif + return 1; +} + + +int scf_update_rcm_card_data_ack(snmp_pdu *pdu, snmp_addr *addr) +{ + u_short portid; + + _state_data *shmp; + _scf_rcm_msg *scf_update_msg; + + PutLogFunID("scf_update_rcm_card_data_ack"); + + if(pdu->var[0].msglen != sizeof(_scf_rcm_msg)) + { + debugmib.msgstatistics.update_card_error_msg ++; + return 0; + } + + if(pdu->error_status) + { + debugmib.msgstatistics.update_card_error_msg ++; + return 0; + } + + scf_update_msg = (_scf_rcm_msg *)pdu->var[0].msg; + portid = scf_update_msg->invoke_id; + + if(portid>=MAX_FSM_PROCESS) + { + debugmib.msgstatistics.update_card_error_msg ++; + return 0; + } + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + + /* + if(shmp->process_info.sub_state != S_REC_CHECK_CARD_WITH_RCM && shmp->process_info.sub_state_2 != 1) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"\n[%04d] receive update card ack, but state not in waiting ack: %d-%d @ %ld", + portid, shmp->process_info.sub_state ,shmp->process_info.sub_state_2, tvnow.tv_sec); + } + debugmib.msgstatistics.update_card_error_msg ++; + return 0; + } + */ + + shmp->process_info.update_card_ack = 1; + shmp->process_info.update_card_result = scf_update_msg->result; + + memcpy(&shmp->context_info.context, &scf_update_msg->card_data,sizeof(_recharge_card_info)); + + switch(scf_update_msg->result) + { + case OC_RESULT_OK: + debugmib.msgstatistics.update_card_ok++; + break; + case OC_RESULT_NO_CARD: + debugmib.msgstatistics.update_card_no_card++; + break; + case OC_RESULT_CARD_USED: + debugmib.msgstatistics.update_card_used ++; + break; + case OC_RESULT_CARD_EXPIRED: + debugmib.msgstatistics.update_card_expired ++; + break; + case OC_RESULT_SYSTEM_FAILURE: + debugmib.msgstatistics.update_card_sys_failure ++; + break; + default: + debugmib.msgstatistics.update_card_error_msg ++; + break; + } + return 1; +} + +extern int smppSendMsg(u_char *peerNumber, u_char *msg, u_char serviceNumPosition); +int sendSMSRechargeNegativeResponse(_state_data *shmp, u_char error_code ) +{ + char sms[512]; + + if(shmp == NULL) + return 0; + + PutLogFunID("sendSMSRechargeNegativeResponse"); + + switch(error_code) + { + case OC_RESULT_NO_CARD: + sprintf(sms, "%s", getSmsSentenceNative(0,SMS_RECHARGE_FAILED_NO_CARD)); + break; + case OC_RESULT_CARD_USED: + sprintf(sms, "%s", getSmsSentenceNative(0,SMS_RECHARGE_FAILED_CARD_USED)); + break; + case OC_RESULT_CARD_EXPIRED: + sprintf(sms, "%s", getSmsSentenceNative(0,SMS_RECHARGE_FAILED_CARD_EXPIRED)); + break; + case OC_RESULT_SYSTEM_FAILURE: + sprintf(sms, "%s", getSmsSentenceNative(0,SMS_RECHARGE_FAILED_SYS_FAILURE)); + default: + break; + } + + smppSendMsg(shmp->caller_info.number, (u_char *)sms, ScratchCardRechargeNumberPosition); + return 1; +} + +int initRCMReponse() +{ + inquire_rspmsg(13,RCM_OID_PREFIX_UPDATE_CARD,(void *)scf_update_rcm_card_data_ack); + return 1; +} + diff --git a/mss/pps/src/main/radius.c b/mss/pps/src/main/radius.c new file mode 100644 index 0000000..cb0dfd3 --- /dev/null +++ b/mss/pps/src/main/radius.c @@ -0,0 +1,735 @@ + +#include "../include/gprs.h" + +static int pps_radius_sap_id; + +extern int subSystemID; +extern _state_machine *smshm_ptr; +extern PPSParamStruct ppsParam; +extern _ram_data *ramshm_ptr; +extern struct timeval tvnow; + +extern PPS_COS_RADIUS_ITEM *getCosRadiusItem(_account_info *ptr); +extern int intiateGprsReportedInfo(_state_data *shmp); + +/**************************** vas *******************************/ +extern BOOL isVas(WORD pid,RADIUS_ACCESS_REQUEST *access_request); +extern int vas_process_access_request(WORD pid,RADIUS_ACCESS_REQUEST *access_request); + +/**************************** vas *******************************/ + + +static ulong getNasVolumeMeterUnit(DWORD ip) +{ + int i; + PPS_RADIUS_NAS_INFO *nasItem; + + return 1; + for(i=0;i < RADIUS_MAX_NUM_OF_NAS;i++) + { + nasItem = &ppsParam.ppsTables.gsn[i]; + if(ip == nasItem->nasInfo.nas_ip) + { + if(nasItem->volumeMeterUnit > 0) + return nasItem->volumeMeterUnit; + } + } + return 1; +} + +static ulong getNasDurationMeterUnit(DWORD ip) +{ + int i; + PPS_RADIUS_NAS_INFO *nasItem; + + return 1; + for(i=0;i < RADIUS_MAX_NUM_OF_NAS;i++) + { + nasItem = &ppsParam.ppsTables.gsn[i]; + if(ip == nasItem->nasInfo.nas_ip) + { + if(nasItem->durationMeterUnit > 0) + return nasItem->durationMeterUnit; + } + } + return 1; +} + +static int checkSupportedCapability(WORD pid,const RADIUS_VENDOR_SPECIFIC *vendorSpecific) +{ + int i; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC *ppac; + RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *specific; + + for(i=0;inum;i++) + { + specific = (RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *)&vendorSpecific->vendor_specific[i]; + if(specific->flag == 0) + { + pps_print_error(0,"Radius pid[%5ld],No vendor spefific content in %d",pid,i); + continue; + } + + if(specific->vendor_type == RADIUS_VENDOR_TYPE_3GPP2_PPAC) + { + ppac = &specific->attribute_3gpp2.ppac; + if(ppac->aic.aic & 0x03) + { + return 1; + } + break; + } + } + pps_print_error(0,"Radius pid[%5ld],Peer not support Volume Meter and Duration Meter",pid); + return -1; +} + +static RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR *getSGSNAddr(WORD pid,const RADIUS_VENDOR_SPECIFIC *vendorSpecific) +{ + int i; + RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *specific; + + for(i=0;inum;i++) + { + specific = (RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *)&vendorSpecific->vendor_specific[i]; + if(specific->flag == 0) + { + pps_print_error(0,"Radius pid[%5ld],No vendor spefific content in %d",pid,i); + continue; + } + + if(specific->vendor_type == RADIUS_VENDOR_TYPE_3GPP_SGSN_ADDR) + { + return &specific->attribute_3gpp.sgsn_addr; + } + } + pps_print_error(0,"Radius pid[%5ld],Peer no sgsn address",pid); + return NULL; +} + + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS *getNASIP(WORD pid,const RADIUS_ACCESS_REQUEST *accessRequest) +{ + if(accessRequest->nas_ip_addr.flag != 0) + { + return (RADIUS_ATTRIBUTE_NAS_IP_ADDRESS *)&accessRequest->nas_ip_addr; + } + pps_print_error(0,"Radius pid[%5ld],Peer no nas ip",pid); + return NULL; +} + +static void updateReason(u8 reasonID,u_char *reason) +{ + switch(reasonID) + { + case RADIUS_PPAQ_UR_PRE_INIT: + strcpy((char *)reason,"PRE INIT"); + break; + case RADIUS_PPAQ_UR_INIT_REQUEST: + strcpy((char *)reason,"INIT REQUEST"); + break; + case RADIUS_PPAQ_UR_THRESHOLD_REACHED: + strcpy((char *)reason,"THRESHOLD REACHED"); + break; + case RADIUS_PPAQ_UR_QUOTA_REACHED: + strcpy((char *)reason,"QUOTA REACHED"); + break; + case RADIUS_PPAQ_UR_TITSU_APPROACHING: + strcpy((char *)reason,"TITSU APPROACHING"); + break; + case RADIUS_PPAQ_UR_REMOTE_DISC: + strcpy((char *)reason,"REMOTE DISC"); + break; + case RADIUS_PPAQ_UR_CLIENT_SERVICE_TER: + strcpy((char *)reason,"CLIENT SERVICE TER"); + break; + case RADIUS_PPAQ_UR_ACCESS_SERVICE_TER: + strcpy((char *)reason,"ACCESS SERVICE TER"); + break; + case RADIUS_PPAQ_UR_SERVICE_NOT_EST: + strcpy((char *)reason,"SERVICE NOT EST"); + break; + case RADIUS_PPAQ_UR_ONE_TIME_CHARGING: + strcpy((char *)reason,"ONE TIME CHARGING"); + break; + default: + strcpy((char *)reason,"Unknown Reason"); + break; + } +} + +static int process_PPAQ(WORD pid, RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq, RADIUS_ATTRIBUTE_ACCT_SESSION_ID *pAsi) +{ + u_short pps_port,qid; + _gprs_process *gprsProc; + _RADIUS_REPORTED_INFO *radiusReportedInfo; + _state_data *shmp; + u_char reason[256]={0}; + + PutLogFunID("process_PPAQ"); + + if(ppaq->qid.flag != 0) + { + if(ppaq->qid.qid.length != 2*sizeof(u_short)) + { + pps_print_error(0,"Incorrect QID,length error"); + return -1; + } + + // get pps port + pps_port = ppaq->qid.qid.value >> 16; + if(subSystemID != 0) + { + if ((pps_port < QID_DUAL_PLAT_POIND) || (pps_port >= (MAX_FSM_PROCESS + QID_DUAL_PLAT_POIND))) + { + pps_print_error(0,"Incorrect pps port[%d]", pps_port); + return -1; + } + pps_port = pps_port - QID_DUAL_PLAT_POIND; + } + if (pps_port >= MAX_FSM_PROCESS) + { + pps_print_error(0,"Incorrect pps port[%d]", pps_port); + return -1; + } + // + + // get qid, initial is 2 + qid = ppaq->qid.qid.value & 0xffff; + if (qid < 2) + { + pps_print_error(0,"Incorrect qid[%d]", qid); + return -1; + } + // + } + else + { + pps_print_error(0,"No QID"); + return -1; + } + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += pps_port; + gprsProc = &shmp->process_info.ppsService.gprs_process; + if(gprsProc->qid != qid) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Incorrect QID:%d,not same as pps allocated:%d",pps_port,qid,gprsProc->qid); + return -1; + } + + /* match acct-session-id + if ((pAsi == NULL) || (pAsi->flag == 0)) + { + pps_print_error(0, "No accounting session id"); + return -1; + } + + if ((pAsi->acct_session_id.length < 2) || (pAsi->acct_session_id.length != gprsProc->acct_session_id.length) \ + || (memcmp(pAsi->acct_session_id.value, gprsProc->acct_session_id.value, pAsi->acct_session_id.length-2) != 0)) + { + pps_print_error(0, "accounting session id not match, discard"); + return -1; + } + */ + + gprsProc->accessRequestTimer = 0; + + if(ppaq->ur.flag != 0) + { + updateReason(ppaq->ur.ur.value,reason); + pps_print_event(shmp->process_info.logMsisdn,"[%05d] ppaq updated reason:%s",pps_port,reason); + switch(ppaq->ur.ur.value) + { + case RADIUS_PPAQ_UR_PRE_INIT: + pps_print_error(shmp->process_info.logMsisdn,"Pre-initialization is unsupported"); + return -1; + break; + case RADIUS_PPAQ_UR_INIT_REQUEST: + pps_print_error(shmp->process_info.logMsisdn,"Initial Request is unsupported"); + return -1; + break; + case RADIUS_PPAQ_UR_THRESHOLD_REACHED: + gprsProc->radiusCommand = PPS_RADIUS_THRESHOLD_REACHED; + break; + case RADIUS_PPAQ_UR_QUOTA_REACHED: + gprsProc->radiusCommand = PPS_RADIUS_QUOTA_REACHED; + break; + case RADIUS_PPAQ_UR_TITSU_APPROACHING: + pps_print_error(shmp->process_info.logMsisdn,"TITSU Approaching is unsupported"); + return -1; + break; + case RADIUS_PPAQ_UR_REMOTE_DISC: + gprsProc->radiusCommand = PPS_RADIUS_REMOTE_DISC; + break; + case RADIUS_PPAQ_UR_CLIENT_SERVICE_TER: + gprsProc->radiusCommand = PPS_RADIUS_CLIENT_SERVICE_TER; + break; + case RADIUS_PPAQ_UR_ACCESS_SERVICE_TER: + gprsProc->radiusCommand = PPS_RADIUS_ACCESS_SERVICE_TER; + break; + case RADIUS_PPAQ_UR_SERVICE_NOT_EST: + gprsProc->radiusCommand = PPS_RADIUS_SERVICE_NOT_EST; + break; + case RADIUS_PPAQ_UR_ONE_TIME_CHARGING: + pps_print_error(shmp->process_info.logMsisdn,"One-Time Charging is unsupported"); + return -1; + break; + default: + pps_print_error(shmp->process_info.logMsisdn,"Unknow update reason:%d", ppaq->ur.ur.value); + return -1; + break; + } + } + else + { + pps_print_error(shmp->process_info.logMsisdn,"No update reason"); + return -1; + } + + radiusReportedInfo = &gprsProc->radiusReportedInfo; + if(ppaq->vq.flag != 0) + { + memcpy(&radiusReportedInfo->vq,&ppaq->vq,sizeof(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQ)); + pps_print_event(shmp->process_info.logMsisdn,"[%05d] ppaq reported vq is:(integer:%lld,exponent:%d)", + pps_port,radiusReportedInfo->vq.vq.integer,radiusReportedInfo->vq.vq.exponent); + } + if(ppaq->vt.flag != 0) + { + memcpy(&radiusReportedInfo->vt,&ppaq->vt,sizeof(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VT)); + pps_print_event(shmp->process_info.logMsisdn,"[%05d] ppaq reported vth is:(integer:%lld,exponent:%d)", + pps_port,radiusReportedInfo->vt.vt.integer,radiusReportedInfo->vq.vq.exponent); + } + if(ppaq->dq.flag != 0) + { + memcpy(&radiusReportedInfo->dq,&ppaq->dq,sizeof(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DQ)); + } + if(ppaq->dt.flag != 0) + { + memcpy(&radiusReportedInfo->dt,&ppaq->dt,sizeof(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DT)); + } + return pps_port; +} + +static int getPPAQ(WORD pid,const RADIUS_VENDOR_SPECIFIC *vendorSpecific, RADIUS_ATTRIBUTE_ACCT_SESSION_ID *pAsi) +{ + int i; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq; + RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *specific; + + for(i=0;inum;i++) + { + specific = (RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *)&vendorSpecific->vendor_specific[i]; + if(specific->flag == 0) + { + pps_print_error(0,"Radius pid[%5ld],No vendor spefific content in %d",pid,i); + continue; + } + + if(specific->vendor_type == RADIUS_VENDOR_TYPE_3GPP2_PPAQ) + { + ppaq = &specific->attribute_3gpp2.ppaq; + return process_PPAQ(pid, ppaq, pAsi); + } + } + return -2; +} + + +static int allocate_GPRS_PORT(WORD pid,RADIUS_TLV_TS *csi,RADIUS_TLV_TS *asi) +{ + int gprs_port; + _state_data *shmp; + _gprs_process *gprsProc; + u_char msisdn[MAX_ASCII_NUMBER_LEN]; + + gprs_port = AssignProcID(1);// gprs and gy has the same port range + if(gprs_port < 0) + { + pps_print_error(0,"System busy ,no idle port"); + return -2; + } + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += gprs_port; + shmp->context_info.mtype = GPRS_O_OPEN; + shmp->context_info.new_flag = YES; + memset(msisdn,0,MAX_ASCII_NUMBER_LEN); + if(csi->value[0] == '+') + memcpy(msisdn,&csi->value[1],csi->length-1); + else + memcpy(msisdn,&csi->value[0],csi->length); + strcpy((char *)shmp->caller_info.number, (char *)msisdn); + gprsProc = &shmp->process_info.ppsService.gprs_process; + memcpy(&gprsProc->acct_session_id,asi,sizeof(RADIUS_TLV_TS)); + gprsProc->radiusCommand = PPS_RADIUS_NEW_SERVICE; + gprsProc->radiusPid = pid; + gprsProc->qid = INIT_QID; + + memcpy(&gprsProc->calling_station_id,csi,sizeof(RADIUS_TLV_TS)); + if(logMsgFlag & 0x08) + { + if(strstr((char *)shmp->caller_info.number,logMsisdn)) + shmp->process_info.logMsisdn = 0x01; + } + return gprs_port; +} + + +static int process_access_request(WORD pid,RADIUS_ACCESS_REQUEST *access_request) +{ + RADIUS_TLV_TS *csi,*asi; + RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR *sgsnAddr; + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS *nasAddr; + int ppsPort=-1; + + if(access_request->vendor_specific.num == 0) + { + pps_print_error(0,"No vendor spefific"); + return -1; + } + + + sgsnAddr = getSGSNAddr(pid,&access_request->vendor_specific); + if(sgsnAddr == NULL) + { + return -1; + } + nasAddr = getNASIP(pid,access_request); + if(nasAddr == NULL) + { + return -1; + } + + ppsPort = getPPAQ(pid, &access_request->vendor_specific, &access_request->acct_session_id); + if(ppsPort == -1) + { + return -1; + } + + if(ppsPort == -2)/* First Access Request */ + { + if(checkSupportedCapability(pid,&access_request->vendor_specific) < 0) + { + return -1; + } + + csi = &access_request->calling_station_id.calling_station_id; + asi = &access_request->acct_session_id.acct_session_id; + if(access_request->calling_station_id.flag != 0) + { + if(csi->length > MAX_ASCII_NUMBER_LEN) + { + pps_print_error(0,"calling station id is too long:%d",csi->length); + return -1; + } + } + else + { + pps_print_error(0,"No calling station id"); + return -1; + } + ppsPort = allocate_GPRS_PORT(pid,csi,asi); + } + + if(ppsPort >= 0) + { + _state_data *shmp; + _gprs_process *gprsProc; + _RADIUS_REPORTED_INFO *radiusReportedInfo; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += ppsPort; + + shmp->process_info.portid = ppsPort; + radiusReportedInfo = &shmp->process_info.ppsService.gprs_process.radiusReportedInfo; + memcpy(&radiusReportedInfo->nasIP,nasAddr,sizeof(RADIUS_ATTRIBUTE_NAS_IP_ADDRESS)); + memcpy(&radiusReportedInfo->sgsnIP,sgsnAddr,sizeof(RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR)); + + gprsProc = &shmp->process_info.ppsService.gprs_process; + gprsProc->volumeMeterUnit = getNasVolumeMeterUnit(radiusReportedInfo->nasIP.nas_ip_addr.value); + gprsProc->accessRequestTimer = 0; + gprsProc->gsnIP = nasAddr->nas_ip_addr.value; + gprsProc->sgsnIP = sgsnAddr->sgsn_addr; + gprsProc->radiusPid = pid; + + return ppsPort; + } + return -1; +} + +static int process_accounting_request(WORD pid,RADIUS_ACCOUNTING_REQUEST *accounting_request) +{ + int ppsPort=-1; + _state_data *shmp; + _gprs_process *gprsProc; + + ppsPort = getPPAQ(pid,&accounting_request->vendor_specific, &accounting_request->acct_session_id); + if(ppsPort < 0) + { + return -1; + } + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += ppsPort; + gprsProc = &shmp->process_info.ppsService.gprs_process; + memcpy(&gprsProc->acct_session_id,&accounting_request->acct_session_id.acct_session_id, + sizeof(RADIUS_TLV_TS)); + gprsProc->radiusCommand = PPS_RADIUS_NO_CMD;/* upper layer does not has any interest of this message,just ignore it here */ + return ppsPort; +} + +int pps_process_radius_ind(WORD *usr_pid, WORD pid, RADIUS_MSG *msg_pdu) +{ + int ppsPort; + + switch(msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + if(isVas(pid,&msg_pdu->msg.access_request)== TRUE) + { + pps_print_event(0,"PPS receive radius msg:Access Request,for VAS prepaid"); + ppsPort = vas_process_access_request(pid,&msg_pdu->msg.access_request); + } + else + { + pps_print_event(0,"PPS receive radius msg:Access Request"); + ppsPort = process_access_request(pid,&msg_pdu->msg.access_request); + } + if(ppsPort < 0) + *usr_pid = 0; + else + *usr_pid = ppsPort; + return ppsPort; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + pps_print_event(0,"PPS receive radius msg:Accounting Request but ignore it"); + return 0; + break; + default: + pps_print_error(0,"PPS not support radius msg type:%d ",msg_pdu->msg_type); + break; + } + return -1; +} + + +int pps_process_radius_cnf(WORD usr_pid, WORD pid, RADIUS_MSG *msg_pdu) +{ + int ppsPort; + _state_data *shmp; + _gprs_process *gprsProc; + + + ppsPort = usr_pid; + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += ppsPort; + gprsProc = &shmp->process_info.ppsService.gprs_process; + switch(msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + gprsProc->radiusCommand = PPS_RADIUS_DISCONNECT_ACK; + pps_print_event(0,"PPS receive radius msg:disconnect ACK for pid %d",ppsPort); + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + gprsProc->radiusCommand = PPS_RADIUS_DISCONNECT_NAK; + pps_print_error(0,"PPS receive radius msg:disconnect NAK for pid %d",ppsPort); + break; + default: + pps_print_error(0,"PPS not support radius conf"); + break; + } + return 1; +} + +int pps_bind_radius() +{ + RADIUS_SAP sap; + + strcpy(sap.name,"PPS"); + sap.radius_ind = pps_process_radius_ind; + sap.radius_cnf = pps_process_radius_cnf; + pps_radius_sap_id = radius_bind(&sap); + if(pps_radius_sap_id< 0) + return -1; + return 1; +} + +int pps_set_nas(BYTE id,RADIUS_NAS_INFORMATION *nasInfo) +{ + return radius_set_nas_info(pps_radius_sap_id,id,nasInfo); +} + +int pps_del_nas(BYTE id) +{ + return radius_delet_nas_info(pps_radius_sap_id,id); +} + +void init_radius_gsn() +{ + int i; + PPS_RADIUS_NAS_INFO *gsnItem; + + pps_bind_radius(); + + for(i=0;iexistFlag == TRUE) + { + pps_set_nas(i,&gsnItem->nasInfo); + } + } +} + + + +int sendRadiusAccessReject(u_short portid,u_char *reason) +{ + _state_data *shmp; + _gprs_process *gprsProc; + RADIUS_MSG radiusMsg; + RADIUS_ACCESS_REJECT *accessReject; + int len; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + gprsProc = &shmp->process_info.ppsService.gprs_process; + + len = strlen((char *)reason)%RADIUS_TS_VALUE_LEN; + radiusMsg.msg_type = RADIUS_MSG_TYPE_ACCESS_REJECT; + + accessReject = &radiusMsg.msg.access_reject; + memset(accessReject,0,sizeof(RADIUS_ACCESS_REJECT)); + if(len > 0) + { + accessReject->reply_message.num = 1; + accessReject->reply_message.reply_message[0].flag = 1; + accessReject->reply_message.reply_message[0].reply_message.length = len; + memcpy(accessReject->reply_message.reply_message[0].reply_message.value,reason,len); + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d] send radius access reject,reason:%s",portid,reason); + return radius_send_access_reject(pps_radius_sap_id,gprsProc->radiusPid,portid,&radiusMsg); +} + +static int allocateQID(_state_data *shmp) +{ + _gprs_process *gprsProc; + + gprsProc = &shmp->process_info.ppsService.gprs_process; + gprsProc->qid++; + return 1; +} + +int sendRadiusAccessAccept(u_short portid,BOOL volumeFlag,BOOL durationFlag) +{ + _state_data *shmp; + _gprs_process *gprsProc; + RADIUS_MSG radiusMsg; + RADIUS_ACCESS_ACCEPT *accessAccept; + RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *vendorSpecific; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq; + DWORD qid=0; + ulong meterUnit; + //PPS_COS_RADIUS_ITEM *radiusItem; + + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + gprsProc = &shmp->process_info.ppsService.gprs_process; + + radiusMsg.msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT; + + accessAccept = &radiusMsg.msg.access_accept; + memset(accessAccept,0,sizeof(RADIUS_ACCESS_ACCEPT)); + accessAccept->vendor_specific.num = 1; + + vendorSpecific = &accessAccept->vendor_specific.vendor_specific[0]; + vendorSpecific->vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAC; + vendorSpecific->attribute_3gpp2.ppac.sfs.flag = 1; + vendorSpecific->attribute_3gpp2.ppac.sfs.sfs= 0x01; + + + if(volumeFlag != FALSE || durationFlag != FALSE) + { + allocateQID(shmp); + accessAccept->vendor_specific.num++; + vendorSpecific = &accessAccept->vendor_specific.vendor_specific[1]; + vendorSpecific->vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAQ; + ppaq = &vendorSpecific->attribute_3gpp2.ppaq; + + ppaq->qid.flag = 1; + if(subSystemID == 0) + { + qid = portid; + qid <<=16; + + } + else + { + qid = portid + QID_DUAL_PLAT_POIND; + qid <<=16; + } + ppaq->qid.qid.value = qid | (gprsProc->qid & 0xffff); + + //radiusItem = getCosRadiusItem(&shmp->caller_info); + + + if(volumeFlag == TRUE) + { + meterUnit = getNasVolumeMeterUnit(gprsProc->radiusReportedInfo.nasIP.nas_ip_addr.value); + if(gprsProc->vqAllocated.integer> 0) + { + ppaq->vq.flag = 1; + ppaq->vq.vq.integer = gprsProc->vqAllocated.integer/meterUnit; + ppaq->vq.vq.exponent = gprsProc->vqAllocated.exponent; + } + if(gprsProc->vthAllocated.integer> 0) + { + ppaq->vt.flag = 1; + ppaq->vt.vt.integer = (gprsProc->vthAllocated.integer)/meterUnit; + ppaq->vt.vt.exponent = gprsProc->vthAllocated.exponent; + } + } + + if(durationFlag == TRUE) + { + meterUnit = getNasDurationMeterUnit(gprsProc->radiusReportedInfo.nasIP.nas_ip_addr.value); + ppaq->dq.flag = 1; + ppaq->dq.dq.value = gprsProc->dqAllocated/meterUnit; + + ppaq->dt.flag = 1; + ppaq->dt.dt.value = gprsProc->dthAllocated/meterUnit; + } + } + intiateGprsReportedInfo(shmp); + pps_print_event(shmp->process_info.logMsisdn,"[%05d] send radius access accept",portid); + return radius_send_access_accept(pps_radius_sap_id,gprsProc->radiusPid,portid,&radiusMsg); +} + + +int sendRadiusDisconnectReq(u_short portid) +{ + _state_data *shmp; + _gprs_process *gprsProc; + RADIUS_MSG radiusMsg; + RADIUS_DISCONNECT_REQUEST *disconnectReq; + RADIUS_ADDR addr; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + gprsProc = &shmp->process_info.ppsService.gprs_process; + + radiusMsg.msg_type = RADIUS_MSG_TYPE_DISCONNECT_REQUEST; + + disconnectReq = &radiusMsg.msg.disconnect_request; + memset(disconnectReq,0,sizeof(RADIUS_DISCONNECT_REQUEST)); + + addr.addr.ipV4 = gprsProc->gsnIP; + disconnectReq->calling_station_id.flag = 1; + memcpy(&disconnectReq->calling_station_id.calling_station_id,&gprsProc->calling_station_id,sizeof(RADIUS_TLV_TS)); + disconnectReq->acct_session_id.flag = 1; + memcpy(&disconnectReq->acct_session_id.acct_session_id,&gprsProc->acct_session_id,sizeof(RADIUS_TLV_TS)); + + return radius_send_disconnect_request(pps_radius_sap_id,portid,&radiusMsg,&addr); +} + + + diff --git a/mss/pps/src/main/rammng.c b/mss/pps/src/main/rammng.c new file mode 100644 index 0000000..207556b --- /dev/null +++ b/mss/pps/src/main/rammng.c @@ -0,0 +1,1872 @@ +#include "../include/includes.h" +#include "../include/ramdata.h" +#include "../include/ppsm.h" +#include "../include/param.h" +#include "../include/tariff.h" + +#include "../../../../plat/iptrans/src/include/iptrans.h" + +#include "../include/plat_inc.h" + +/*------------------------------------------------*/ +extern _ram_data *ramshm_ptr; +extern _tariff_private *blf_shmp; + +extern char masterFlag; +extern u_long PPS_OID_PREFIX[]; // +extern u_long primary_data_server, + second_data_server; +extern u_long LOCAL_IP; +extern u_char stopPeriodicSync; +extern int stopReceivePeriodicSyncFlag ; +extern int totalPeriodSyncPackets; +/*------------------------------------------------*/ +//u_char ram_oper[4] = {0xaa,0x01,0x00,0x00}; +/*1=read,2=send,3=periodic sync,4=real sync*/ +u_long peer_server_ip; +DWORD PPS_RAM_OID_PREFIX[]={1,3,6,1,4,1,1373,2,3,3,6,2,PPSOID_InitRequest}; +static int readResponseCount=0; +u_short tftp_port; +u_long tftp_ip; + +extern int time_now[7]; +extern struct timeval tvnow; +extern int ValidateAsciiMSISDN(char *msisdn, int len); +extern void PrepaidCardRealSyncMessageProc(); +extern int GetDailyReportResponse(); +extern int dataSyncCallProc(); +int pps_real_update_file_init(); +/*------------------------------------------------*/ +static int readPacketNo=0; +static int syncFlag = 1; +char peer_server_in_init = 0; +/*------------------------------------------------*/ +int GetAccountInfoBySortIndex(int index, char *msisdn); +extern int scf_update_rcm_card_data_ack(snmp_pdu *pdu, snmp_addr *addr); +/*------------------------------------------------*/ +extern int dataSyncCallPro(); +extern void SaveTariffPlan(); +extern void SaveRechargeCard(); +extern void SaveSubsData(); +int pps_real_update_file_close(); +/*------------------------------------------------*/ +int SetSyncFlag(int flag) +{ + /* manually set sync funtion on/off */ + if(flag<0) return 0; + + syncFlag = flag; + return 1; +} + +int SetPeriodicSyncFlag(int flag) +{ + if(flag) + stopPeriodicSync = 0; + else + stopPeriodicSync = 1; + return 1; +} + +int ReadPeroidicSyncData() +{ + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + + PutLogFunID("ReadPeroidicSyncData"); + + + snmpaddr.local_port = PPS_REALSYNC_PORT; + if(snmp_receive(&snmpbuf,&snmpaddr)) + { + peer_server_ip = snmpaddr.remote_ip; + return 1; + } + return 0; +} + +void ReadSyncMessageForInit() +{ + + int i,reflag=0; +// int instance=0; + int dataType; + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varptr=NULL; + + PutLogFunID("ReadSyncMessageForInit"); + + snmpaddr.local_port = PPS_REALSYNC_PORT; + + for(i=0;i<4;i++) + { + if(!snmp_receive(&snmpbuf,&snmpaddr)) + { + break; + } + varptr = &snmpbuf.var[0]; + dataType = varptr->oid[12]; + + if(dataType == 2) + {//real sync message + switch(varptr->oid[13]) + { + case 2: //user data + dataSyncCallPro(varptr->oidlen, + varptr->oid,varptr->msg,varptr->msglen,reflag); + break; + case 3: //prepaid card + PrepaidCardRealSyncMessageProc(varptr->oidlen, + varptr->oid,varptr->msg,varptr->msglen,reflag); + break; + case 4: //tariff data + break; + default: + DebugMsg(debugmib.display.asciiOut, + "Error sync message received"); + break; + } + } + }//for +} + +void SyncMessageProc() +{ + static int noPeriodicSyncCount=0; + //void *ptr = (void *)ramshm_ptr; + int i,periodicFlag=0,reflag=0; + int instance=0,dataType; + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varptr=NULL; + + u_long masterIP=LOCAL_IP; + + PutLogFunID("SyncMessageProc"); + + snmpaddr.local_port = PPS_REALSYNC_PORT; + + if(debugmib.display.sysState != _SYS_STATE_NORMAL) + { + return ; + }/* not sure about this function, 10-13 */ + + for(i=0;ioid[12]; + + if(dataType == 2) {//real sync message + if(snmpaddr.remote_ip !=LOCAL_IP && masterFlag) reflag=1; + + switch(varptr->oid[13]) + { + case 2: //user data + dataSyncCallPro(varptr->oidlen, + varptr->oid,varptr->msg,varptr->msglen,reflag); + break; + case 3: //prepaid card + PrepaidCardRealSyncMessageProc(varptr->oidlen, + varptr->oid,varptr->msg,varptr->msglen,reflag); + break; + case 4: //tariff data + break; + default: + DebugMsg(debugmib.display.asciiOut, + "Error sync message received"); + break; + } + } + else + { + //periodic sync message + //if(stopReceivePeriodicSyncFlag ) continue; + instance = varptr->oid[13]; + if(varptr->msglen == RAMDATA_PACK_SIZE) + { + if(instance>=RAMDATA_PACK_NUM) continue ; + /* + memcpy(ptr+instance*RAMDATA_PACK_SIZE, + varptr->msg, + RAMDATA_PACK_SIZE); + */ + } + /* + else if(varptr->msglen == sizeof(_prepaid_info)) + { + if(instance>=MAX_SUBS_RECORD) continue; + ModifyPPSSubsData((_prepaid_info *)varptr->msg); + } + else + { + continue; + } + */ + masterIP = snmpaddr.remote_ip; + debugmib.display.masterIP = masterIP; + periodicFlag = 1; + } + }//for + + + if(debugmib.measurement.peer_usernumber < + debugmib.measurement.usernumber) + return; + + if(periodicFlag) + { + if(masterFlag && (masterIP MAX_RAM_INIT_RETRY*100) + { + masterFlag = 1; + masterIP = LOCAL_IP; + debugmib.display.masterIP = masterIP; + } +} + +void TrapPPSSubsData(_prepaid_info *shmp,int store_pos) +{ + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + snmpbuf.pdu_type = 0x07; //trap + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; + +// snmpaddr.local_ip = LOCAL_IP; + snmpaddr.remote_port = PPS_REALSYNC_PORT; + snmpaddr.local_port = PPS_REALSYNC_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 13 + 1; + varlist->vartype = 0x04; + + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x02; //configuration + varlist->oid[12] = 0x04; //sync ram + varlist->oid[13] = store_pos; //account_db + varlist->msglen = sizeof(_prepaid_info); + memcpy(varlist->msg, shmp, sizeof(_prepaid_info)); + snmp_send(&snmpbuf,&snmpaddr); + +} + +int PeriodicSyncSubsData() +{ + static int packetPeriodicNoOfSubs=0; + + _prepaid_info *shmp; + + int loop = 0,head,tail; + + + for(loop=0;loop=MAX_SUBS_RECORD) + { + packetPeriodicNoOfSubs = 0; + return 1; + } + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + if(shmp->msisdn[MAX_MSISDN_BLEN-1] > 2 && + shmp->msisdn[MAX_MSISDN_BLEN-1] <18) + { + TrapPPSSubsData(shmp,packetPeriodicNoOfSubs); + break; + } + } + return 0; +} + +void PeriodicSyncRamData() +{ + static int packetPeriodicNo=0; + void *ptr = (void *)ramshm_ptr; + + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + PutLogFunID("PeriodicSyncRamData"); + + if(stopPeriodicSync) + { + return ; + } + if(!syncFlag) /* stop sync function by command */ + { + return ; + } + + if(!masterFlag) + return; + //send periodic sync message + /* + if(packetPeriodicNo>=totalPeriodSyncPackets) + { + if(!PeriodicSyncSubsData()) + { + return; + } + packetPeriodicNo = 0; + } + */ + + snmpbuf.pdu_type = 0x07; //trap + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; + +// snmpaddr.local_ip = LOCAL_IP; + snmpaddr.remote_port = PPS_REALSYNC_PORT; + snmpaddr.local_port = PPS_REALSYNC_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 13 + 1; + varlist->vartype = 0x04; + + memcpy(&varlist->oid,PPS_OID_PREFIX,11*4); + varlist->oid[11] = 0x02; //configuration + varlist->oid[12] = 0x04; //sync ram + varlist->oid[13] = packetPeriodicNo; //account_db + varlist->msglen = RAMDATA_PACK_SIZE; + memcpy(varlist->msg, + ptr+packetPeriodicNo*RAMDATA_PACK_SIZE, + RAMDATA_PACK_SIZE); + snmp_send(&snmpbuf,&snmpaddr); +// snmpaddr.remote_ip = LOCAL_IP; +// snmp_send(&snmpbuf,&snmpaddr); + packetPeriodicNo++; + packetPeriodicNo %= RAMDATA_PACK_NUM; + +} + + +int ReadDataFromPeerSever() +{ + int retval = 0; + static int readState=0; + int i; + static int trytimes = 0; + static int reReadTimes = 0; + + snmp_pdu snmpbuf; + snmp_addr snmpaddr; + var_list *varlist; + + PutLogFunID("ReadDataFromPeerSever"); + + switch(readState) + { + case 0: //send request + if(readPacketNo>=RAMDATA_PACK_NUM) + { //init over + readState = 0; + readResponseCount = 0; + trytimes = 0; + reReadTimes = 0; + readPacketNo = 0; + return 1; + } + + snmpbuf.pdu_type = PDU_GET; //trap + snmpbuf.var_num = 0x01; + + snmpaddr.remote_ip = peer_server_ip; +// snmpaddr.local_ip = LOCAL_IP; + snmpaddr.remote_port = HEART_BEATING_PORT; + snmpaddr.local_port = HEART_BEATING_PORT; + snmpaddr.broadcast = 0x00; + + varlist = snmpbuf.var; + varlist->oidlen = 14; + varlist->vartype = 0x04; + + memcpy(&varlist->oid,PPS_RAM_OID_PREFIX,13*4); + varlist->msglen = 0; + for(i=0;ioid[13] = readPacketNo+i; + snmp_send(&snmpbuf,&snmpaddr); + } + readState = 1; + readResponseCount = 0; + trytimes = 0; + break; + case 1: //wait response + if(readResponseCount>=MAX_READ_PACKET_NUM) + { + readState = 0; + reReadTimes = 0; + readPacketNo +=MAX_READ_PACKET_NUM; + } + else if(trytimes++>=MAX_RAM_INIT_RETRY) + { + readState = 0; + readResponseCount = 0; + trytimes = 0; + if(reReadTimes++>=MAX_RAM_INIT_RETRY){ + reReadTimes = 0; + readPacketNo = 0; + return -1; + } + } + break; + default: + readState = 0; + break; + } + return retval; +} + +int snmpResponse(snmp_pdu *pdu, snmp_addr *addr) +{ + //int request_id;//,pdu_type; + int instance,dataType; + void *ptr = (void *)ramshm_ptr; + + PutLogFunID("snmpResponse"); + + //pdu_type = pdu->pdu_type; + //request_id = pdu->request_id; + + dataType = pdu->var[0].oid[11]; + + if(dataType == 1) + { //statistics + switch(pdu->var[0].oid[12]) + { + case 4: + return GetDailyReportResponse(pdu,addr); + break; + default: + return 0; + break; + } + } + if(dataType == 5) + { + return scf_update_rcm_card_data_ack(pdu,addr); + } + + instance = pdu->var[0].oid[13]; //for init + + switch(pdu->var[0].oid[12]) + { + case PPSOID_InitRequest: //ram data init + if(instance>=RAMDATA_PACK_NUM) + return 0; + if(instancereadPacketNo+MAX_READ_PACKET_NUM) + return 0; + if(pdu->var[0].msglen != RAMDATA_PACK_SIZE) + return 0; + + debugmib.display.initProgress = (instance+1)*100/RAMDATA_PACK_NUM; + + memcpy(ptr+instance*RAMDATA_PACK_SIZE, + pdu->var[0].msg, + pdu->var[0].msglen); + readResponseCount++; + break; + default: + break; + } + return 1; +} + +int PeerServerRamInitRequest(u_char oidLen, DWORD *oid, u_char *pdata,BYTE *vartype) +{ + u_long instance; + void *ptr = (void *)ramshm_ptr; + + PutLogFunID("PeerServerRamInitRequest"); + + peer_server_in_init = 1; + + if(debugmib.display.sysState != _SYS_STATE_NORMAL) + { + return 0; + } + + if(!syncFlag) /* stop sync function by command */ + return 0; + + instance = oid[13]; + if(instance>=RAMDATA_PACK_NUM) + { + return 0; + } + *vartype = 0x04; + + memcpy(pdata,ptr+instance*RAMDATA_PACK_SIZE,RAMDATA_PACK_SIZE); + return RAMDATA_PACK_SIZE; +} + +int LoadDataFromBackfile() +{ + //int i; + FILE *fp=NULL; + //void *ptr=(void *)blf_shmp; + + struct stat fileinfo; + + PutLogFunID("LoadDataFromBackfile"); + + fp = fopen(PPS_TARIFF_DATA_NAME,"r"); + if(fp !=NULL) + { + stat(PPS_TARIFF_DATA_NAME,&fileinfo); + if(fileinfo.st_size == sizeof(_tariff_data)) + { + fread(&ramshm_ptr->tariff_data, sizeof(_tariff_data), 1, fp); + } + /* + stat(PPS_TARIFF_DATA_NAME,&fileinfo); + if(fileinfo.st_size == sizeof(_tariff_data)) + { //check length + fread(&ramshm_ptr->tariff_data,sizeof(_tariff_data),1,fp); + } + else if(fileinfo.st_size == sizeof(_tariff_data_old)) + { + _tariff_data_old oldTariffData; + memset(&ramshm_ptr->tariff_data,0,sizeof(_tariff_data)); + fread(&oldTariffData,sizeof(_tariff_data_old),1,fp); + memcpy(&ramshm_ptr->tariff_data.comm_tariff, + &oldTariffData.comm_tariff, + sizeof(_comm_tariff)*MAX_ZONE_NUM_OLD); + memcpy(&ramshm_ptr->tariff_data.bill_discount, + &oldTariffData.bill_discount, + sizeof(_bill_discount)*MAX_DISCOUNT_ID*24); + memcpy(&ramshm_ptr->tariff_data.holiday_flag, + &oldTariffData.holiday_flag, + sizeof(_bill_holiday)*12*31); + + memcpy(&ramshm_ptr->tariff_data.rent_tariff, + &oldTariffData.rent_tariff, + sizeof(_rent_tariff)*MAX_ZONE_NUM_OLD*MAX_RENT_TARIFF); + memcpy(&ramshm_ptr->tariff_data.bill_tariff, + &oldTariffData.bill_tariff, + sizeof(_bill_tariff)*BILLING_BASE_NUM*MAX_ZONE_NUM_OLD); + memcpy(&ramshm_ptr->tariff_data.called_tariff, + &oldTariffData.called_tariff, + sizeof(_bill_tariff)*MAX_ZONE_NUM_OLD*CALLED_BASE_NUM); + memcpy(&ramshm_ptr->tariff_data.bill_sms, + &oldTariffData.bill_sms, + sizeof(_bill_sms)*MAX_ZONE_NUM_OLD*MAX_SMS_PREFIX); + + } + */ + fclose(fp); + } + + fp=fopen(PPS_RECHARGE_CARD_BACKUP_NAME,"r"); + if(fp !=NULL) + { + stat(PPS_RECHARGE_CARD_BACKUP_NAME,&fileinfo); + if(fileinfo.st_size == sizeof(_card_data)) + { //check length + fread(&ramshm_ptr->card_data,sizeof(_card_data),1,fp); + } + fclose(fp); + } + + fp=fopen(PPS_USER_BACKUP_NAME,"r"); + if(fp !=NULL) + { + stat(PPS_USER_BACKUP_NAME,&fileinfo); + if(fileinfo.st_size == sizeof(_prepaid_data)) + { //check length + fread(&ramshm_ptr->prepaid_data,sizeof(_prepaid_data),1,fp); + } + + fclose(fp); + } + + + return 1; +} + +static int base_prefix_index = 0; + +int ocs_set_crm_base_prefix_record(char *prefix, char *area, int call_type, int base_prefix_index) +{ + _base_tariff * ptr = &ramshm_ptr->tariff_data.base_tariff[base_prefix_index]; + + strcpy(ptr->bill_id, prefix); + strcpy(ptr->area, area); + ptr->call_type = call_type; + + return 1; +} + +extern int ocs_get_call_type_by_des(const char *prefix); +int ocs_parse_base_prefix(char *data) +{ + const char delimiter[] = ",; "; + char buf[1024] = {""},*token; + char prefix[64], area[128]; + int index = 0; + int call_type = PPS_CSTA_TYPE_BASE; + + while(index<3) + { + token = strsep((char **)&(data),delimiter); + if(token == NULL ) + { + index++; + continue; + } + + strcpy(buf,token); + + switch(index) + { + case 0x00: //prefix + strcpy(prefix, buf); + break; + case 0x01: //area des + strcpy(area, buf); + break; + } + index ++; + } + + call_type = ocs_get_call_type_by_des(prefix) + PPS_CSTA_TYPE_BASE; + + ocs_set_crm_base_prefix_record(prefix, area, call_type, base_prefix_index); + base_prefix_index ++; + + return 1; + +} + +extern void ocs_get_crm_prefix_definition(); +extern char *ocs_get_crm_prefix_filename(char *ptr); +int ocs_read_crm_base_prefix_file() +{ + FILE *fp = NULL; + char file_name[128] = {""}; + char buf[1024]; + + ocs_get_crm_prefix_definition(); + + ocs_get_crm_prefix_filename(file_name); + fp = fopen(file_name,"rb"); + if(fp == NULL) + { + printf("can't open file %s\r\n", file_name); + return 0; + } + + base_prefix_index = 0; + while(fgets(buf,1023,fp) !=(char *)0) + { + if( (int *)strchr(buf,'#') !=NULL) continue; + if( !strlen(buf) ) continue; + ocs_parse_base_prefix(buf); + } + + fclose(fp); + + return 1; +} + +int ppsBackupRamDataToFile() +{ + static int backupState = 0; + int retval = 0; + static int backupCounter = 0; + + PutLogFunID("ppsBackupRamDataToFile"); + + switch(backupState){ + case 0: + pps_real_update_file_close(); + SaveTariffPlan(); + backupState = 1; + break; + case 1: + SaveRechargeCard(); + backupState = 2; + break; + case 2: + SaveSubsData(); + backupState = 3; + break; + case 3: + //SaveTariffData(); + //mnpf_exit(1); + pps_real_update_file_init(); + backupState = 4; + break; + case 4: + if(backupCounter++>(5*CYCLE_STATE_INTERVAL)) + { + backupCounter = 0; + backupState = 0; + retval = 1; + } + break; + default: + retval = 1; + break; + } + return retval; +} + + +/*------------------------------------------------*/ + +int tftpReadRequest(u_short portno, char *filename) +{ + int retval=1,filename_len; + char readmode[BUFSIZE]="octetoblksizeo1024"; + _msg_list ipmsg; + + PutLogFunID("tftpReadRequest"); + + filename_len = strlen(filename); + + ipmsg.msgSrcPort = portno; +// ipmsg.msgSrcIP = LOCAL_IP; + tftp_port = 69; + tftp_ip = primary_data_server;// + ipmsg.msgDstPort = tftp_port; //TFTP_PORT; + ipmsg.msgDstIP = tftp_ip; + ipmsg.msgBroadcast = 0x00; + + ipmsg.msgContent[0] = 0; + ipmsg.msgContent[1] = 1; //read request + memcpy(ipmsg.msgContent + 2,filename,filename_len); + memcpy(ipmsg.msgContent + filename_len + 3,readmode,18); + ipmsg.msgContent[filename_len + 2]=0; + ipmsg.msgContent[filename_len + 8]=0; + ipmsg.msgContent[filename_len + 16]=0; + ipmsg.msgContent[filename_len + 21]=0; + ipmsg.msgLength = filename_len + 22; + iptrPutMessage(ipmsg); + return retval; +} + +int tftpReadData(u_short portno, u_char *databuf,int flag) +{ + static int readblocknum=0; + static int proc_len = 0; + int ackblocknum; + int retval=0; + _msg_list ipmsg,ipack; + + PutLogFunID("tftpReadData"); + + if(flag) + { + ipack.msgLength = 4; + ipack.msgContent[0]=0x00; + ipack.msgContent[1]=0x04; + ipack.msgContent[2]=readblocknum>>8; + ipack.msgContent[3]=readblocknum; +// ipack.msgSrcIP = LOCAL_IP; + ipack.msgSrcPort = PPS_SERVICE_PORT; + tftp_port = ipmsg.msgSrcPort; + tftp_ip = ipmsg.msgSrcIP; + ipack.msgDstPort = tftp_port; + ipack.msgDstIP = tftp_ip; + iptrPutMessage(ipack); + return 0; + } + + if(iptrGetMessage(&ipmsg,PPS_SERVICE_PORT)) + { + if(ipmsg.msgContent[1]==3) + { + ackblocknum = ipmsg.msgContent[2]*256+ipmsg.msgContent[3]; + proc_len +=ipmsg.msgLength-4; + if(ackblocknum == readblocknum+1){ + readblocknum = ackblocknum; + }else if(ackblocknum==0x0000){ + if(readblocknum==0xffff){ + readblocknum = ackblocknum; + } + } + //if(ipmsg.msgLength<4+RAMDATA_PACK_SIZE){//last packet + //} + memcpy(databuf,ipmsg.msgContent,ipmsg.msgLength); //length + + retval = ipmsg.msgLength; + ipack.msgLength = 4; + ipack.msgContent[0]=0x00; + ipack.msgContent[1]=0x04; + ipack.msgContent[2]=ackblocknum>>8; + ipack.msgContent[3]=ackblocknum; +// ipack.msgSrcIP = LOCAL_IP; + ipack.msgSrcPort = PPS_SERVICE_PORT; + tftp_port = ipmsg.msgSrcPort; + tftp_ip = ipmsg.msgSrcIP; + ipack.msgDstPort = tftp_port; + ipack.msgDstIP = tftp_ip; + iptrPutMessage(ipack); + } + else if(ipmsg.msgContent[1]==5) + { + //printf("Error!\n"); + } + if(ipmsg.msgContent[1] ==6){ + proc_len = 0; + readblocknum=0; + + ipack.msgLength = 4; + ipack.msgContent[0]=0x00; + ipack.msgContent[1]=0x04; + ipack.msgContent[2]=readblocknum>>8; + ipack.msgContent[3]=readblocknum; +// ipack.msgSrcIP = LOCAL_IP; + ipack.msgSrcPort = PPS_SERVICE_PORT; + ipack.msgDstPort = tftp_port; + ipack.msgDstIP = tftp_ip; + iptrPutMessage(ipack); + } + } + return retval; +} + +int ReadDataFromOMCServer() +{ + static int tftpState = 0; + u_char databuf[1024]; + int retval=0; + static int trytimes=0,retrytimes=0; + u_short blocknum,length; + char filename[BUFSIZE]="pps_backup.dat"; + void *ptr = (void *)ramshm_ptr; + int i; + + PutLogFunID("ReadDataFromOMCServer"); + + switch(tftpState) + { + case 0: + sprintf(filename,"pps_backup%02d.dat",(time_now[6]+7-1)%7); + if(tftpReadRequest(PPS_SERVICE_PORT,filename)) + tftpState = 1; + break; + case 1: + for(i=0;i<1;i++) + { + length = tftpReadData(PPS_SERVICE_PORT,databuf,0); + if(length>=4){ + blocknum = databuf[2] * 256 + databuf[3]; +// if(blocknum>=RAMDATA_PACK_NUM) continue; + debugmib.display.dataSrc=_SRC_OMC_HD; + debugmib.display.initProgress = (blocknum)*100/RAMDATA_PACK_NUM; + memcpy(ptr+(blocknum-1)*RAMDATA_PACK_SIZE, + &databuf[4], + length-4); //length is variable + + trytimes=0; + retrytimes = 0; + if(blocknum>=RAMDATA_PACK_NUM) + { + retval = 1; + } + }else if(trytimes++>MAX_RAM_INIT_RETRY){ + trytimes = 0; + tftpReadData(PPS_SERVICE_PORT,databuf,1); + if(retrytimes++>MAX_RAM_INIT_RETRY) + { + retrytimes = 0; + retval = -1; + } + } + } + break; + default: + break; + } + return retval; +} + +int tftpWriteRequest(int portno,char *filename) +{ + int retval=1,filename_len; + char writemode[BUFSIZE]="octetoblksizeo1024"; + _msg_list ipmsg; + + PutLogFunID("tftpWriteRequest"); + + filename_len = strlen(filename); + ipmsg.msgSrcPort = portno; +// ipmsg.msgSrcIP = LOCAL_IP; + tftp_port = 69; + tftp_ip = primary_data_server; + ipmsg.msgDstPort = tftp_port; + ipmsg.msgDstIP = tftp_ip; + ipmsg.msgBroadcast = 0x00; + + ipmsg.msgContent[0] = 0; + ipmsg.msgContent[1] = 2; //write request + memcpy(&ipmsg.msgContent[2],filename,filename_len); + memcpy(&ipmsg.msgContent[ filename_len + 3],writemode,18); + ipmsg.msgContent[filename_len + 2]=0; + ipmsg.msgContent[filename_len + 8]=0; + ipmsg.msgContent[filename_len + 16]=0; + ipmsg.msgContent[filename_len + 21]=0; + ipmsg.msgLength = filename_len + 22; + iptrPutMessage(ipmsg); + + return retval; +} + +int tftpWriteData() +{ + int retval = 0; + static int blocknum=1,ackblocknum=0; + static int trytimes=0; + static int reSendTimes=0; + _msg_list ipmsg,ipsend; + void *ptr = (void *)ramshm_ptr; + + PutLogFunID("tftpWriteData"); + + if(iptrGetMessage(&ipmsg,PPS_SERVICE_PORT)) + { + if(ipmsg.msgContent[1] == 4){ + ackblocknum = ipmsg.msgContent[2]*256+ipmsg.msgContent[3]; + if(ackblocknum == blocknum){ + if(blocknum++>=RAMDATA_PACK_NUM){ + blocknum=0; + ackblocknum=0; + trytimes=0; + reSendTimes = 0; + return 1; + } + } + }else if(ipmsg.msgContent[1] == 6) + { + blocknum = 1; + } +// ipsend.msgSrcIP = LOCAL_IP; + tftp_port = ipmsg.msgSrcPort; + tftp_ip = ipmsg.msgSrcIP; + ipsend.msgSrcPort = PPS_SERVICE_PORT; + ipsend.msgDstPort = tftp_port; + ipsend.msgDstIP = tftp_ip; + ipsend.msgLength = 4 + 1024; + ipsend.msgContent[0] = 0x00; + ipsend.msgContent[1] = 0x03; + ipsend.msgContent[2] = blocknum>>8; + ipsend.msgContent[3] = blocknum; + memcpy(&ipsend.msgContent[4], + ptr+(blocknum-1)*RAMDATA_PACK_SIZE, + RAMDATA_PACK_SIZE); + iptrPutMessage(ipsend); + reSendTimes = 0; + }else if(trytimes++>MAX_RAM_INIT_RETRY) + { + trytimes=0; + if(reSendTimes++>=MAX_RAM_INIT_RETRY){ + reSendTimes = 0; + blocknum=0; + ackblocknum=0; + retval = 1; + }else{ +// ipsend.msgSrcIP = LOCAL_IP; + ipsend.msgSrcPort = PPS_SERVICE_PORT; + ipsend.msgDstPort = tftp_port; + ipsend.msgDstIP = tftp_ip; + ipsend.msgLength = 4 + 1024; + ipsend.msgContent[0] = 0x00; + ipsend.msgContent[1] = 0x03; + ipsend.msgContent[2] = blocknum>>8; + ipsend.msgContent[3] = blocknum; + memcpy(&ipsend.msgContent[4], + ptr+(blocknum-1)*RAMDATA_PACK_SIZE, + RAMDATA_PACK_SIZE); + iptrPutMessage(ipsend); + } + } + return retval; +} + +int ppsBackupRamDataToOMCServer() +{ + int retval = 0; + static int backupState = 0; + char filename[32]; + + PutLogFunID("ppsBackupRamDataToOMCServer"); + + sprintf(filename,"pps_backup%02d.dat",time_now[6]); + switch(backupState){ + case 0: + if(tftpWriteRequest(PPS_SERVICE_PORT,filename)){ + backupState = 1; + } + break; + case 1: + if(tftpWriteData()){ + backupState = 0; + retval = 1; + } + break; + default: + break; + } + return retval; +} + +/* --- pps subscriber index management routines -------*/ +u_long ppsBinSearchIndex(int low, int high, long long key) +//make sure that the value of low and high is valid before invoke this function. +{ + int mid; + long long midvalue; + + + if(low > high) //bug occured + { + printf("BinSearchIndex ERR,low=%d,high=%d,key=%lld",low,high,key); + return low; + } + + if(high == low + 1 ) + { + if(key <= ramshm_ptr->index_data.index_table.prim_index[low].key) + return low; + else if(key <= ramshm_ptr->index_data.index_table.prim_index[high].key) + return high; + else + return high + 1; + } + + if(low == high) + { + //if(low == 0) + // return 0; + if(key <= ramshm_ptr->index_data.index_table.prim_index[low].key) + return low; + else + return low + 1; + } + + mid = (low + high)/2; + midvalue = ramshm_ptr->index_data.index_table.prim_index[mid].key; + + if(key == midvalue) + { + return mid; + } + else if(key < midvalue) + { + return ppsBinSearchIndex(low, mid, key); + } + else + { + return ppsBinSearchIndex(mid, high, key); + } +} + +int AssignPPSStoreIndex() +{ + int index; + int pWriteSub; + + pWriteSub = ramshm_ptr->index_data.free_index.pWriteSub; + + + if(pWriteSub<=0) + { + if(debugmib.measurement.usernumber != MAX_SUBS_RECORD) + { + printf("Store index error!, no free space while exist subs.= %ld\n", + debugmib.measurement.usernumber); + } + return -1; + } + + index = ramshm_ptr->index_data.free_index.free_memory[pWriteSub-1]; + pWriteSub -- ; + if(pWriteSub<0) pWriteSub = 0; + ramshm_ptr->index_data.free_index.pWriteSub = pWriteSub; + + if(ramshm_ptr->index_data.free_index.status[index] == 1) + { + return AssignPPSStoreIndex(); + } + + debugmib.measurement.free_index = + ramshm_ptr->index_data.free_index.pWriteSub; + + return index; +} + +int FreePPSStoreIndex(int store_index) +{ + int pWriteSub; + _pps_index_db *shmp; + + if(store_index<0 || store_index>=MAX_SUBS_RECORD) + return 0; + + shmp = &ramshm_ptr->index_data; + pWriteSub = shmp->free_index.pWriteSub; + + if(pWriteSub>=MAX_SUBS_RECORD) + { + printf("Store index error!, all space are free while %ld subs. exist\n", + debugmib.measurement.usernumber); + return 0; + } + shmp->free_index.status[store_index] = 0; + shmp->free_index.free_memory[pWriteSub] = store_index; + + pWriteSub ++ ; + pWriteSub %= (MAX_SUBS_RECORD+1); + shmp->free_index.pWriteSub = pWriteSub; + + + debugmib.measurement.free_index = shmp->free_index.pWriteSub; + return 1; +} + +/*------------------------------*/ +int AddPPSTableIndex(long long key, int store_index) +{ + int index; + _pps_index_db *shmp; + + shmp = &ramshm_ptr->index_data; + + if(debugmib.measurement.usernumber == 0) + { + index = 0; + shmp->index_table.prim_index[index].store_index = store_index; + shmp->index_table.prim_index[index].key = key; + return 1; + } + + index = ppsBinSearchIndex(0,debugmib.measurement.usernumber-1,key); + + if(index>=MAX_SUBS_RECORD) + { + DebugMsg(debugmib.display.asciiOut,"Space is full with total %ld subs!\n",debugmib.measurement.usernumber); + return 0; + } + + if(shmp->index_table.prim_index[index].key == key) + { + //DebugMsg(debugmib.display.asciiOut,"index: %lld existing at: %d\n",key,index); + return 0; + } + + //DebugMsg(debugmib.display.asciiOut,"index: %lld at: %d\n",key,index); + + if(index>=debugmib.measurement.usernumber ) + { + shmp->index_table.prim_index[index].store_index = store_index; + shmp->index_table.prim_index[index].key = key; + } + else + { + /* + memmove(&tmpIndexTable, + &shmp->index_table.prim_index[index], + (debugmib.measurement.usernumber-index)*sizeof(_pps_index_node)); + memmove(&shmp->index_table.prim_index[index+1], + &tmpIndexTable, + (debugmib.measurement.usernumber-index)*sizeof(_pps_index_node)); + */ + memmove(&shmp->index_table.prim_index[index+1], + &shmp->index_table.prim_index[index], + (debugmib.measurement.usernumber-index)*sizeof(_pps_index_node)); + + shmp->index_table.prim_index[index].store_index = store_index; + shmp->index_table.prim_index[index].key = key; + } + return 1; +} + + +int DeletePPSTableIndex(int index, int store_index) +{ + + _pps_index_db *shmp; + + FreePPSStoreIndex(store_index); + + shmp = &ramshm_ptr->index_data; + shmp->index_table.prim_index[index].key = 0; + shmp->index_table.prim_index[index].store_index = 0; + if(index == debugmib.measurement.usernumber-1) + { + return 1; + } + + memmove(&shmp->index_table.prim_index[index], + &shmp->index_table.prim_index[index+1], + //(MAX_SUBS_RECORD-index-1)*sizeof(_pps_index_node)); + (debugmib.measurement.usernumber-index-1)*sizeof(_pps_index_node)); + + return 1; +} + +int FindPPSTableIndex(long long key) +{ + int index; + + if(debugmib.measurement.usernumber == 0) + return -1; + index = ppsBinSearchIndex(0,debugmib.measurement.usernumber-1,key); + + if(index>=MAX_SUBS_RECORD) + return -1; + + if(ramshm_ptr->index_data.index_table.prim_index[index].key != key) + { + return -1; + } + + return index; +} + +int FindPPSSubsStoreIndex(long long key) +{ + int index; + int store_index = 0; + +#ifdef OCS_WITH_CRM + store_index = ocs_get_ue_index(key); + if(store_index == INVALID_UE_INDEX) + store_index = -1; + return store_index; +#endif + index = FindPPSTableIndex(key); + + + if(index<0) + { + return index; + } + //DebugMsg(debugmib.display.asciiOut,"find store index: %lld -%d\n",key,index); + store_index = + ramshm_ptr->index_data.index_table.prim_index[index].store_index; + if(store_index<0 || store_index>= MAX_SUBS_RECORD) + { + return -1; + } + + return store_index; +} + + +int GetAccountInfoBySortIndex(int index, char *msisdn) +{ + int retval = 0; + + if(index<0 || index>=debugmib.measurement.usernumber) + return retval; + if(debugmib.measurement.usernumber == 0) + return retval; + if(msisdn == NULL) + return retval; + + retval = 1; +#ifdef OCS_WITH_CRM + //if(OCS_with_external_CRM()) + { + long long llmsisdn = ocs_get_ue_by_index(index); + sprintf(msisdn,"%lld",llmsisdn); + } + //else +#else + { + sprintf(msisdn,"%lld",ramshm_ptr->index_data.index_table.prim_index[index].key); + } +#endif + + return retval; +} + + +int GetPPSSubsRecord(char *msisdn, _prepaid_info *shmp) +{ + // msisdn in what format? NAI+NUMBER OR NUMBER ? + + int store_index, len; + int head,tail; + + len = strlen(msisdn); + + if(lenMAX_MSISDN_ALEN) return -1; + + store_index = FindPPSSubsStoreIndex(atoll(msisdn)); + + if(store_index<0) return -1; + head = store_index /UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + + memcpy(shmp, + &ramshm_ptr->prepaid_data.prepaid_info[head][tail], + sizeof(_prepaid_info)); + return store_index; +} + +/*-----------------subs management ----------------*/ +extern int ocs_add_ue_record(long long msisdn, int store_index); +int CreatePPSSubsIndexTable() +{ + int loop,len,head,tail,l; + int user_counter = 0; + char buf[BUFSIZE],msisdn[32]; + _prepaid_info *shmp; + + memset(&ramshm_ptr->index_data.free_index, + 0, + sizeof(_pps_free_index)); /* clear flag table */ + memset(&ramshm_ptr->index_data.index_table, + 0, + sizeof(_pps_index_table)); /* clear index table */ + + ramshm_ptr->index_data.free_index.user_counter = 0; + ramshm_ptr->index_data.free_index.pWriteSub = 0; + debugmib.measurement.usernumber = 0; + + for(loop=MAX_SUBS_RECORD;loop>=0;loop--) + { + if(loop%200==0) + ReadSyncMessageForInit(); + + head = loop / UNIT_STORE_ACCOUNT; + tail = loop % UNIT_STORE_ACCOUNT; + + if(head>=MSISDN_HEAD_NUM) continue; + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + + if(lenMAX_MSISDN_ALEN) + { + memset(shmp,0,sizeof(_prepaid_info)); + FreePPSStoreIndex(loop); + continue; + } + BcdToAscii(msisdn,shmp->msisdn,(MAX_MSISDN_BLEN-1)*2); + msisdn[len] = 0; + if(!ValidateAsciiMSISDN(msisdn,len)) + { + memset(shmp,0,sizeof(_prepaid_info)); + FreePPSStoreIndex(loop); + continue; + } + + shmp->favorite_numbers = 0; + for(l=0;lfavorite_number[l][MAX_MSISDN_BLEN-1]; + if(len>=3 && len<=MAX_MSISDN_ALEN) + { + BcdToAscii(buf,shmp->favorite_number[l],(MAX_MSISDN_BLEN-1)*2); + buf[len] = 0; + if(!ValidateAsciiMSISDN(msisdn,len)) + { + memset(shmp->favorite_number[l],0,MAX_MSISDN_BLEN); + } + else + { + shmp->favorite_numbers ++; + } + } + else + memset(shmp->favorite_number[l],0,MAX_MSISDN_BLEN); + } + + shmp->latch_flag = 0; +#ifdef OCS_WITH_CRM + if(ocs_add_ue_record(atoll(msisdn), loop)==0) + { + DebugMsg(debugmib.display.asciiOut, + "msisdn %s is duplicated, delete!", msisdn); + memset(shmp,0,sizeof(_prepaid_info)); + FreePPSStoreIndex(loop); + } +#else + if(!AddPPSTableIndex(atoll(msisdn), loop)) + { + DebugMsg(debugmib.display.asciiOut, + "msisdn %s is duplicated, delete!", msisdn); + memset(shmp,0,sizeof(_prepaid_info)); + FreePPSStoreIndex(loop); + continue; + } +#endif + user_counter++; + UserNumberIncrement(); + + } + +#if DEBUG + DebugMsg(debugmib.display.asciiOut,"total user: %d",user_counter); + DebugMsg(debugmib.display.asciiOut,"free index: %d", + ramshm_ptr->index_data.free_index.pWriteSub); + +#endif + ramshm_ptr->index_data.free_index.user_counter = user_counter; + return 1; +} + +extern int pps_real_update_user_file(int head, int tail); +extern int ocs_delete_ue_record(long long msisdn); +int AddPPSSubsData(_prepaid_info *shmp) +{ + int store_index,head,tail; + int len=0; + char msisdn[32]; + long long lmsisdn; + _prepaid_data *pdata_shmp; + + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + + if(lenMAX_MSISDN_ALEN) + return -1; + + BcdToAscii(msisdn,shmp->msisdn,9*2); + msisdn[len] = 0; + lmsisdn = atoll(msisdn); + pdata_shmp = &ramshm_ptr->prepaid_data; + + if(debugmib.measurement.usernumber>0) + { + store_index = FindPPSSubsStoreIndex(lmsisdn); + if(store_index>=0 && store_indexprepaid_info[head][tail], + shmp, + sizeof(_prepaid_info)); + DebugMsg(debugmib.display.asciiOut,"Subs. %s exist @%d, replace it!\n", + msisdn,store_index); + return store_index; + } + } + + if(debugmib.measurement.usernumber>=MAX_SUBS_RECORD) + { + DebugMsg(debugmib.display.asciiOut,"Space is full,cann't store subs. data any more!\n"); + return -1; + } + + store_index = AssignPPSStoreIndex(); + if(store_index<0 || store_index>=MAX_SUBS_RECORD) + { + return -1; + } + //DebugMsg(debugmib.display.asciiOut,"Subs. %s does not exist,stored at: %d!\n",msisdn,store_index); +#ifdef OCS_WITH_CRM + if(ocs_add_ue_record(lmsisdn, store_index) == 0) + { + return -1; + } +#else + + if(!AddPPSTableIndex(lmsisdn,store_index)) + { + + return -1; + } +#endif + + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + memcpy(&pdata_shmp->prepaid_info[head][tail], + shmp, + sizeof(_prepaid_info)); + + UserNumberIncrement(); + + pps_real_update_user_file(head, tail); + + return store_index; +} + +int ModifyPPSSubsData(_prepaid_info *shmp) +{ + int store_index,len; + int head, tail; + char msisdn[32]; + long long lmsisdn; + _prepaid_data *pdata_shmp; + + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + + if(lenMAX_MSISDN_ALEN) + return 0; + + BcdToAscii(msisdn,shmp->msisdn,9*2); + msisdn[len] = 0; + lmsisdn = atoll(msisdn); + +#ifdef OCS_WITH_CRM + store_index = ocs_get_ue_index(lmsisdn); + +#else + store_index = FindPPSSubsStoreIndex(lmsisdn); +#endif + + if(store_index==-1 || store_index == INVALID_UE_INDEX) + { + //AddPPSSubsData(shmp); + return 0; + } + pdata_shmp = &ramshm_ptr->prepaid_data; + + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + memcpy(&pdata_shmp->prepaid_info[head][tail], + shmp, + sizeof(_prepaid_info)); + + pps_real_update_user_file(head, tail); + + return 1; +} + +int DeletePPSSubsData(_prepaid_info *shmp) +{ + int store_index; + int head, tail; + + int len=0; + char msisdn[32]; + long long lmsisdn; + _prepaid_data *pdata_shmp; + + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + + if(lenMAX_MSISDN_ALEN) + { + debugmib.watch_dog[49]++; + return 0; + } + BcdToAscii(msisdn,shmp->msisdn,9*2); + msisdn[len] = 0; + lmsisdn = atoll(msisdn); + +#ifdef OCS_WITH_CRM + store_index = ocs_get_ue_index(lmsisdn); + if(store_index == INVALID_UE_INDEX) + { + DebugMsg(debugmib.display.asciiOut,"Subs. %s doesn't exist, cann't delete it!\n",msisdn); + return 0; + } + ocs_delete_ue_record(lmsisdn); + + DebugMsg(debugmib.display.asciiOut,"Delete subs %s ,stored at: %d!\n",msisdn, store_index); + +#else + int index = FindPPSTableIndex(lmsisdn); + if(index==-1) + { + debugmib.watch_dog[50]++; + return 0; + } + + store_index = ramshm_ptr->index_data.index_table.prim_index[index].store_index; + + if(store_index==-1)/* never set to -1? , 10-12 */ + { + debugmib.watch_dog[51]++; + DebugMsg(debugmib.display.asciiOut,"Subs. %s doesn't exist, cann't delete it!\n",msisdn); + return 0; + } + + DeletePPSTableIndex(index,store_index); + { + DebugMsg(debugmib.display.asciiOut,"Delete subs %s ,stored at: %d.%d!\n",msisdn,index,store_index); + } +#endif + + pdata_shmp = &ramshm_ptr->prepaid_data; + + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + + memset(&pdata_shmp->prepaid_info[head][tail], + 0, + sizeof(_prepaid_info)); + + UserNumberDecrement(); + + pps_real_update_user_file(head, tail); + + return 1; +} + + +/* ---- test functins ----- */ +void ppsListAllIndexByOrder() +{ + int i; + FILE *fp=NULL; + + fp = fopen("/usr/local/subsManage/pps_index.txt","w"); + if(fp==NULL) + return; + + if(debugmib.measurement.usernumber == 0) + { + fprintf(fp,"No subs exists!\n"); + } + else + { + fprintf(fp,"# msisdn index\n"); + for(i=0;iindex_data.index_table.prim_index[i].key, + ramshm_ptr->index_data.index_table.prim_index[i].store_index); + } + } + fclose(fp); +} + +void ppsListAllSubsNumber() +{ + int i,len; + int head,tail,store_index; + FILE *fp=NULL; + _prepaid_info *shmp; + char msisdn[32]; + + fp = fopen("/usr/local/subsManage/pps_subs.txt","w"); + if(fp==NULL) + return; + + if(debugmib.measurement.usernumber == 0) + { + fprintf(fp,"No subs exists!\n"); + } + else + { + fprintf(fp,"# msisdn\n"); + for(i=0;iindex_data.index_table.prim_index[i].store_index; + if(store_index<0 || store_index>=MAX_SUBS_RECORD) continue; + head = store_index / UNIT_STORE_ACCOUNT; + tail = store_index % UNIT_STORE_ACCOUNT; + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + len = shmp->msisdn[MAX_MSISDN_BLEN-1]%17; + ppsBcdToAsciiR(msisdn,shmp->msisdn,18); + msisdn[len] = 0; + fprintf(fp,"%05d %s\n", + store_index,msisdn); + } + } + fclose(fp); +} + +void ppsListAllSubsMSISDN() +{ + int len; + int head,tail,loop; + FILE *fp=NULL; + _prepaid_info *shmp; + char msisdn[32]; + char timebuf[128]; + + fp = fopen("/usr/local/subsManage/pps_msisdn.txt","w"); + if(fp==NULL) + return; + + fprintf(fp,"# msisdn\n"); + for(loop=0;loop=MSISDN_HEAD_NUM) continue; + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + + if(len<1) + { + continue; + } + BcdToAscii(msisdn,shmp->msisdn,(MAX_MSISDN_BLEN-1)*2); + msisdn[len] = 0; + AsciiTime(timebuf,shmp->mo_expiration_date); + fprintf(fp,"%05d %s-%d-%s-%.02f\n", loop,msisdn, shmp->status, timebuf, shmp->balance); + } + fclose(fp); +} + +void ppsAddBalanceToAll(int balance) +{ + int len; + int head,tail,loop; + + _prepaid_info *shmp; + //char msisdn[32]; + + for(loop=0;loop=MSISDN_HEAD_NUM) continue; + shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; + len = shmp->msisdn[MAX_MSISDN_BLEN-1]; + + if(len<2) + { + continue; + } + + shmp->balance += balance; + + } +} + + +/*--------- real time write user/card data functions -------*/ +/*--------- definitions -------------------------------*/ +typedef struct real_file_type +{ + FILE *fp; + char file_name[128]; + int open_time; + int last_update_time; + int last_update_index; +}_real_file_type; + +_real_file_type pps_user_file, pps_card_file; + +/*---------- routines ------------------------------*/ +int pps_real_update_file_init() +{ + FILE *fp=NULL; + + fp = fopen(PPS_USER_BACKUP_NAME,"r+b"); + if(fp == NULL) + { + fp = fopen(PPS_USER_BACKUP_NAME,"a+b"); + if(fp == NULL) + return 0; + } + + if(pps_user_file.fp) + fclose(pps_user_file.fp); + + pps_user_file.fp = fp; + strcpy(pps_user_file.file_name, PPS_USER_BACKUP_NAME); + pps_user_file.open_time = tvnow.tv_sec; + + fp = fopen(PPS_RECHARGE_CARD_BACKUP_NAME,"r+b"); + if(fp == NULL) + { + fp = fopen(PPS_RECHARGE_CARD_BACKUP_NAME,"a+b"); + if(fp == NULL) + return 0; + } + + if(pps_card_file.fp) + fclose(pps_card_file.fp); + + pps_card_file.fp = fp; + strcpy(pps_card_file.file_name, PPS_RECHARGE_CARD_BACKUP_NAME); + pps_card_file.open_time = tvnow.tv_sec; + + return 1; +} + + +int pps_real_update_file_close() +{ + if(pps_user_file.fp) + { + fclose(pps_user_file.fp); + pps_user_file.fp = NULL; + } + + if(pps_card_file.fp) + { + fclose(pps_card_file.fp); + pps_card_file.fp = NULL; + } + + return 1; +} + +int pps_real_update_user_file(int head, int tail) +{ + long base_size = sizeof(long long) * MSISDN_HEAD_NUM; + long offset_size; + + if( pps_user_file.fp == NULL) + { + pps_real_update_file_init(); + return 0; + } + if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) + return 0; + + offset_size = (head*UNIT_STORE_ACCOUNT+tail)*sizeof(_prepaid_info); + + fseek(pps_user_file.fp, base_size+offset_size, SEEK_SET); + + fwrite((void *)&ramshm_ptr->prepaid_data.prepaid_info[head][tail], sizeof(_prepaid_info),1,pps_user_file.fp); + + fflush(pps_user_file.fp); + + pps_user_file.last_update_time = tvnow.tv_sec; + pps_user_file.last_update_index = head * UNIT_STORE_ACCOUNT + tail ; + + return 1; +} + + +int pps_real_update_card_file(int head, int tail) +{ + long base_size = sizeof(long) * MAX_VALUE_TYPE + + sizeof(u_char) * MAX_CARD_SEGMENT + + sizeof(long long)*MAX_CARD_SEGMENT; + + long offset_size; + + if( pps_card_file.fp == NULL) + { + pps_real_update_file_init(); + return 0; + } + if(head>=MAX_CARD_SEGMENT || tail>=MAX_CARD_NUM_PSEG) + return 0; + + offset_size = (head*MAX_CARD_NUM_PSEG+tail)*sizeof(_recharge_card_info); + + fseek(pps_card_file.fp, base_size+offset_size, SEEK_SET); + + fwrite((void *)&ramshm_ptr->card_data.prepaid_card[head][tail], sizeof(_recharge_card_info),1,pps_card_file.fp); + + pps_card_file.last_update_time = tvnow.tv_sec; + pps_card_file.last_update_index = head * MAX_CARD_NUM_PSEG + tail ; + + return 1; +} diff --git a/mss/pps/src/main/restapi.c b/mss/pps/src/main/restapi.c new file mode 100644 index 0000000..e8cbfd3 --- /dev/null +++ b/mss/pps/src/main/restapi.c @@ -0,0 +1,2860 @@ +#include +#include +#include +#include "../include/restapi.h" + +static void _encode_u64(u8 *buf, int *len, const u64 val) +{ + *(u32*)(&buf[*len]) = htonl((val >> 32) & 0xFFFFFFFF); + *len += 0x04; + *(u32*)(&buf[*len]) = htonl(val & 0xFFFFFFFF); + *len += 0x04; +} + +static u64 _decode_u64(u8 *buf) +{ + u64 val = 0; + val = ntohl( *(u32*)(&buf[0]) ); + val = val << 32; + val += ntohl( *(u32*)(&buf[4]) ) & 0xffffffff; + + return val; +} + + +#define ENCODE_HEADER() \ +do{ \ + buf[len++] = ptr->msg_type; \ + buf[len++] = IE_SRC_REF; \ + buf[len++] = 0x02; \ + *(u16*)(&buf[len]) = htons(ptr->header.src_ref); \ + len += 2; \ + buf[len++] = IE_DST_REF; \ + buf[len++] = 0x02; \ + *(u16*)(&buf[len]) = htons(ptr->header.dst_ref); \ + len += 2; \ +}while(0) + +int encode_rest_query(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.query.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.query.msisdn); + len += vallen; + + return len; +} + +static int decode_rest_query(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.query.msisdn, &buf[offset], vallen); + ptr->msg.query.msisdn[vallen] = '\0'; + break; + case IE_RESULT: + ptr->msg.query_res.result = buf[offset]; + break; + case IE_ERROR_CODE: + ptr->msg.query_res.error_code = buf[offset]; + break; + case IE_BALANCE: + ptr->msg.query_res.balance = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_MO_EXPIRY: + ptr->msg.query_res.mo_expiry = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_MT_EXPIRY: + ptr->msg.query_res.mt_expiry = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_USERNAME: + { + memcpy(ptr->msg.topup.username, &buf[offset], vallen); + ptr->msg.topup.username[vallen] = '\0'; + } + break; + case IE_PASSWORD: + { + memcpy(ptr->msg.topup.password, &buf[offset], vallen); + ptr->msg.topup.password[vallen] = '\0'; + } + break; + } + offset += vallen; + } + + return retval; +} + +int encode_rest_query_res(_rest_msg_s *ptr, u8 *buf) +{ + int len=0/*, vallen=0*/; + + ENCODE_HEADER(); + + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.query_res.result; + if(ptr->msg.query_res.result == 1) + { + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x01; + buf[len++] = ptr->msg.query_res.error_code; + + return len; + } + + buf[len++] = IE_BALANCE; + buf[len++] = 0x04; + // memcpy(&buf[len], &ptr->msg.query_res.balance, 0x04); + *(u32*)(&buf[len]) = htonl(ptr->msg.query_res.balance); + len += 0x04; + + buf[len++] = IE_MO_EXPIRY; + buf[len++] = 0x04; + // memcpy(&buf[len], &ptr->msg.query_res.mo_expiry, 0x04); + *(u32*)(&buf[len]) = htonl(ptr->msg.query_res.mo_expiry); + len += 0x04; + + buf[len++] = IE_MT_EXPIRY; + buf[len++] = 0x04; + // memcpy(&buf[len], &ptr->msg.query_res.mt_expiry, 0x04); + *(u32*)(&buf[len]) = htonl(ptr->msg.query_res.mt_expiry); + len += 0x04; + + return len; +} + +int encode_rest_topup(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.topup.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.topup.msisdn); + len += vallen; + + buf[len++] = IE_USERNAME; + vallen = strlen(ptr->msg.topup.username); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.topup.username); + len += vallen; + + + buf[len++] = IE_PASSWORD; + vallen = strlen(ptr->msg.topup.password); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.topup.password); + len += vallen; + + if (strlen(ptr->msg.topup.pincode)>0) + { + buf[len++] = IE_PINCODE; + vallen = strlen(ptr->msg.topup.pincode); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.topup.pincode); + len += vallen; + } + + if((ptr->msg.topup.optional_flag & 0x01) == 0x01) + { + buf[len++] = IE_ACCOUNT_ID; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.topup.account_id); + len += vallen; + + } + + if((ptr->msg.topup.optional_flag & 0x02) == 0x02) + { + buf[len++] = IE_BALANCE_AVAILABLE; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.topup.balance); + len += vallen; + + } + + + return len; +} + +int encode_rest_order(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.order.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.order.msisdn); + len += vallen; + + buf[len++] = IE_SERVICE_TYPE; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.order.busicode); + len += vallen; + + buf[len++] = IE_BUNDLE_ID; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.order.offer_id); + len += vallen; + + buf[len++] = IE_PAY_TYPE; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.order.paymethod); + len += vallen; + + if (ptr->msg.order.busicode == 1000)// airtime recharge + { + buf[len++] = IE_RECHARGE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.order.balance); + len += 0x04; + } + + if ((ptr->msg.order.paymethod & 0xff) == 10 && strlen(ptr->msg.order.pincode) > 0) + { + buf[len++] = IE_PINCODE; + vallen = strlen(ptr->msg.order.pincode); + buf[len++] = vallen; + memcpy(&buf[len], ptr->msg.order.pincode, vallen); + len += vallen; + } + + if (ptr->msg.order.payMsisdn[0] != '\0') + { + buf[len++] = IE_MSISDN_TRANS_OUT; + vallen = strlen(ptr->msg.order.payMsisdn); + buf[len++] = vallen; + memcpy(&buf[len], ptr->msg.order.payMsisdn, vallen); + len += vallen; + } + + if (ptr->msg.order.callerMsisdn[0] != '\0') + { + buf[len++] = IE_CALLER_NUMBER; + vallen = strlen(ptr->msg.order.callerMsisdn); + buf[len++] = vallen; + memcpy(&buf[len], ptr->msg.order.callerMsisdn, vallen); + len += vallen; + } + + return len; +} + +int encode_rest_free_resource(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.free_resource.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.free_resource.msisdn); + len += vallen; + + return len; +} + +int encode_rest_downloadApp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.downloadApp.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.downloadApp.msisdn); + len += vallen; + + return len; +} + +int encode_rest_offerChange(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.offerChange.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.offerChange.msisdn); + len += vallen; + + buf[len++] = IE_SERVICE_TYPE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl((u32)(ptr->msg.offerChange.opt_out)); + len += 0x04; + + return len; +} + +int encode_rest_queryPoint(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.queryPoint.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.queryPoint.msisdn); + len += vallen; + + return len; +} + +int encode_rest_transferPoint(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.transferPoint.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.transferPoint.msisdn); + len += vallen; + + buf[len++] = IE_MSISDN_TRANS_IN; + vallen = strlen(ptr->msg.transferPoint.target_msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.transferPoint.target_msisdn); + len += vallen; + + buf[len++] = IE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.transferPoint.amount); + len += 0x04; + + buf[len++] = IE_SERVICE_TYPE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.transferPoint.busicode); + len += 0x04; + + return len; +} + +int encode_rest_channel(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.chnl.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.chnl.msisdn); + len += vallen; + + buf[len++] = IE_USERNAME; + vallen = strlen(ptr->msg.chnl.sess_id); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.chnl.sess_id); + len += vallen; + + buf[len++] = IE_REMARK; + vallen = strlen(ptr->msg.chnl.sc_url); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.chnl.sc_url); + len += vallen; + + if (strlen(ptr->msg.chnl.input)>0) + { + buf[len++] = IE_MSG_CONTENT; + vallen = strlen(ptr->msg.chnl.input); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.chnl.input); + len += vallen; + } + + return len; +} + +static int decode_rest_channel_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + { + ptr->msg.chnl_res.result = buf[offset]; + } + break; + case IE_ERROR_CODE: + { + ptr->msg.chnl_res.error_code = buf[offset]; + } + break; + case IE_STATUS: + { + ptr->msg.chnl_res.sess_state = buf[offset]; + } + break; + case IE_MSG_CONTENT: + { + memcpy(ptr->msg.chnl_res.prompt, &buf[offset], vallen); + ptr->msg.chnl_res.prompt[vallen] = '\0'; + } + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_queryPoint_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + { + ptr->msg.queryPoint_res.result = buf[offset]; + } + break; + case IE_ERROR_CODE: + { + ptr->msg.queryPoint_res.error_code = buf[offset]; + } + break; + case IE_AMOUNT: + { + ptr->msg.queryPoint_res.amount = ntohl( *(u32*)(&buf[offset]) ); + } + break; + case IE_BALANCE_AVAILABLE: + { + ptr->msg.queryPoint_res.airtime_amount = ntohl( *(u32*)(&buf[offset]) ); + } + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_transferPoint_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + { + ptr->msg.queryPoint_res.result = buf[offset]; + } + break; + case IE_ERROR_CODE: + { + ptr->msg.queryPoint_res.error_code = buf[offset]; + } + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_topup(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + { + memcpy(ptr->msg.topup.msisdn, &buf[offset], vallen); + ptr->msg.topup.msisdn[vallen] = '\0'; + } + break; + case IE_ACCOUNT_ID: + { + ptr->msg.topup.account_id = ntohl( *(u32*)(&buf[offset]) ); + ptr->msg.topup.optional_flag |= 0x01; + } + break; + case IE_BALANCE_AVAILABLE: + { + ptr->msg.topup.balance = ntohl( *(u32*)(&buf[offset]) ); + ptr->msg.topup.optional_flag |= 0x02; + } + break; + + case IE_RESULT: + { + ptr->msg.topup_res.result = buf[offset]; + } + break; + case IE_ERROR_CODE: + { + ptr->msg.topup_res.error_code = buf[offset]; + } + break; + case IE_BALANCE: + { + ptr->msg.topup_res.balance = ntohl( *(u32*)(&buf[offset]) ); + } + break; + case IE_MO_EXPIRY: + { + ptr->msg.topup_res.mo_expiry = ntohl( *(u32*)(&buf[offset]) ); + } + break; + case IE_MT_EXPIRY: + { + ptr->msg.topup_res.mt_expiry = ntohl( *(u32*)(&buf[offset]) ); + } + break; + case IE_USERNAME: + { + memcpy(ptr->msg.topup.username, &buf[offset], vallen); + ptr->msg.topup.username[vallen] = '\0'; + } + break; + case IE_PASSWORD: + { + memcpy(ptr->msg.topup.password, &buf[offset], vallen); + ptr->msg.topup.password[vallen] = '\0'; + } + break; + } + offset += vallen; + } + + return retval; +} + +int encode_rest_topup_res(_rest_msg_s *ptr, u8 *buf) +{ + return encode_rest_query_res(ptr, buf); +} + +int decode_rest_transfer_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + { + ptr->msg.transfer_rsp.result = buf[offset]; + } + break; + case IE_ERROR_CODE: + { + ptr->msg.transfer_rsp.error_code = buf[offset]; + } + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +// for selfcare====================================== +int encode_rest_send_authcode_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + // IE_MSISDN + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.send_authcode_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.send_authcode_req.msisdn); + len += vallen; + + // IE_MSG_CONTENT + buf[len++] = IE_MSG_CONTENT; + vallen = strlen(ptr->msg.send_authcode_req.sms_content); + buf[len++] = vallen >> 8; + buf[len++] = vallen & 0xff; + strcpy((char*)( &buf[len] ), ptr->msg.send_authcode_req.sms_content); + len += vallen; + + return len; +} + +int encode_rest_send_authcode_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0/*, vallen=0*/; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.send_authcode_rsp.result; + + // IE_ERROR_CODE + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.send_authcode_rsp.error_code); + len += 0x04; + + return len; +} + + +int encode_rest_query_user_data_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.query_user_data_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.query_user_data_req.msisdn); + len += vallen; + + return len; +} + +int encode_rest_query_user_data_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.query_user_data_rsp.result; + + // IE_ERROR_CODE + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_user_data_rsp.error_code); + len += 0x04; + + // IE_MSISDN + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.query_user_data_rsp.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.query_user_data_rsp.msisdn); + len += vallen; + // + + // IE_REMARK + buf[len++] = IE_REMARK; + vallen = strlen(ptr->msg.query_user_data_rsp.remark); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.query_user_data_rsp.remark); + len += vallen; + // + + // IE_GROUP_NAME + buf[len++] = IE_GROUP_NAME; + vallen = strlen(ptr->msg.query_user_data_rsp.usrGrpName); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.query_user_data_rsp.usrGrpName); + len += vallen; + // + + // IE_STATUS + buf[len++] = IE_STATUS; + buf[len++] = 0x01; + buf[len++] = ptr->msg.query_user_data_rsp.status; + // + + // IE_BALANCE + buf[len++] = IE_BALANCE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_user_data_rsp.balance); + len += 0x04; + // + + // IE_EXPIRY_TIME + buf[len++] = IE_EXPIRY_TIME; + buf[len++] = 0x08; + *(u32*)(&buf[len]) = htonl((ptr->msg.query_user_data_rsp.mo_expiry >> 32) & 0xFFFFFFFF); + len += 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_user_data_rsp.mo_expiry & 0xFFFFFFFF); + len += 0x04; + // + + // IE_REMAIN_MO_VOICE_MIN + buf[len++] = IE_REMAIN_MO_VOICE_MIN; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_user_data_rsp.remain_mo_voc_min); + len += 0x04; + // + + // IE_REMAIN_MT_VOICE_MIN + buf[len++] = IE_REMAIN_MT_VOICE_MIN; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_user_data_rsp.remain_mt_voc_min); + len += 0x04; + // + + // IE_REMAIN_SMS_NUM + buf[len++] = IE_REMAIN_SMS_NUM; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_user_data_rsp.remain_sms_num); + len += 0x04; + // + + // IE_REMAIN_DATA_VOL_MB + buf[len++] = IE_REMAIN_DATA_VOL_MB; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_user_data_rsp.remain_data_vol); + len += 0x04; + // + + return len; +} + +int encode_rest_bundle_subs_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.bundle_subs_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.bundle_subs_req.msisdn); + len += vallen; + + // IE_PAY_TYPE + buf[len++] = IE_PAY_TYPE; + buf[len++] = 0x01; + buf[len++] = ptr->msg.bundle_subs_req.payType; + // + + // IE_AMOUNT + buf[len++] = IE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_subs_req.charge); + len += 0x04; + // + + // IE_MO_VOICE_MIN + buf[len++] = IE_MO_VOICE_MIN; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_subs_req.moVoiceMinute); + len += 0x04; + // + + // IE_MT_VOICE_MIN + buf[len++] = IE_MT_VOICE_MIN; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_subs_req.mtVoiceMinute); + len += 0x04; + // + + // IE_SMS_NUM + buf[len++] = IE_SMS_NUM; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_subs_req.smsNum); + len += 0x04; + // + + // IE_DATA_VOL_MB + buf[len++] = IE_DATA_VOL_MB; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_subs_req.dataVolume); + len += 0x04; + // + + // IE_VALID_DAYS + buf[len++] = IE_VALID_DAYS; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_subs_req.validDays); + len += 0x04; + // + + return len; +} + +int encode_rest_bundle_subs_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.bundle_subs_rsp.result; + + // IE_ERROR_CODE + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_subs_rsp.error_code); + len += 0x04; + + return len; +} + +int encode_rest_bundle_usage_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.bundle_usage_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.bundle_usage_req.msisdn); + len += vallen; + + return len; +} + +int encode_rest_bundle_usage_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.bundle_usage_rsp.result; + + // IE_ERROR_CODE + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_usage_rsp.error_code); + len += 0x04; + + // IE_REMAIN_MO_VOICE_MIN + buf[len++] = IE_REMAIN_MO_VOICE_SEC; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_usage_rsp.moVoiceInSec); + len += 0x04; + // + + // IE_REMAIN_MT_VOICE_MIN + buf[len++] = IE_REMAIN_MT_VOICE_SEC; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_usage_rsp.mtVoiceInSec); + len += 0x04; + // + + // IE_REMAIN_SMS_NUM + buf[len++] = IE_REMAIN_SMS_NUM; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_usage_rsp.smsNum); + len += 0x04; + // + + // IE_REMAIN_DATA_VOL_MB + buf[len++] = IE_REMAIN_DATA_VOL_KB; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_usage_rsp.dataVolInKB); + len += 0x04; + // + + // IE_EXPIRY_TIME + buf[len++] = IE_EXPIRY_TIME; + buf[len++] = 0x08; + *(u32*)(&buf[len]) = htonl((ptr->msg.bundle_usage_rsp.expiredTime >> 32) & 0xFFFFFFFF); + len += 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.bundle_usage_rsp.expiredTime & 0xFFFFFFFF); + len += 0x04; + // + + return len; +} + + +int encode_rest_recharge_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.recharge_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.recharge_req.msisdn); + len += vallen; + + buf[len++] = IE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.recharge_req.amount); + len += 0x04; + + buf[len++] = IE_RECHARGE_TYPE; + buf[len++] = 0x01; + buf[len] = ptr->msg.recharge_req.op_type; + len += 0x01; + + buf[len++] = IE_VALID_DAYS; + buf[len++] = 0x02; + *(u16*)(&buf[len]) = htons(ptr->msg.recharge_req.valid_days); + len += 0x02; + + return len; +} + +int encode_rest_recharge_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.recharge_rsp.result; + + if(ptr->msg.recharge_rsp.result == RES_FAILED) + { + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x01; + buf[len++] = ptr->msg.recharge_rsp.error_code; + + return len; + } + // + + // IE_STATUS + buf[len++] = IE_STATUS; + buf[len++] = 0x01; + buf[len] = ptr->msg.recharge_rsp.status; + len += 0x01; + // + + // IE_BALANCE + buf[len++] = IE_BALANCE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.recharge_rsp.balance); + len += 0x04; + // + + // IE_EXPIRY_TIME + buf[len++] = IE_EXPIRY_TIME; + buf[len++] = 0x08; + *(u32*)(&buf[len]) = htonl((ptr->msg.recharge_rsp.expiredTime >> 32) & 0xFFFFFFFF); + len += 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.recharge_rsp.expiredTime & 0xFFFFFFFF); + len += 0x04; + // + + return len; +} + +int encode_rest_transfer_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN_TRANS_OUT; + vallen = strlen(ptr->msg.transfer_req.transferOutMsisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.transfer_req.transferOutMsisdn); + len += vallen; + + buf[len++] = IE_MSISDN_TRANS_IN; + vallen = strlen(ptr->msg.transfer_req.transferInMsisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.transfer_req.transferInMsisdn); + len += vallen; + + buf[len++] = IE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.transfer_req.amount); + len += 0x04; + + return len; +} + +int encode_rest_transfer_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.transfer_rsp.result; + + // IE_ERROR_CODE + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.transfer_rsp.error_code); + len += 0x04; + + buf[len++] = IE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.transfer_rsp.balance); + len += 0x04; + + return len; +} + +int encode_rest_recharge_card_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.recharge_card_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.recharge_card_req.msisdn); + len += vallen; + + buf[len++] = IE_PASSWORD; + vallen = strlen(ptr->msg.recharge_card_req.cardPwd); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.recharge_card_req.cardPwd); + len += vallen; + + return len; +} + +int encode_rest_recharge_card_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.recharge_card_rsp.result; + + // IE_ERROR_CODE + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.recharge_card_rsp.error_code); + len += 0x04; + + // IE_BALANCE + buf[len++] = IE_RECHARGE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.recharge_card_rsp.rechargeAmount); + len += 0x04; + // + + // IE_BALANCE + buf[len++] = IE_BALANCE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.recharge_card_rsp.balance); + len += 0x04; + // + + // IE_EXPIRY_TIME + buf[len++] = IE_EXPIRY_TIME; + buf[len++] = 0x08; + *(u32*)(&buf[len]) = htonl((ptr->msg.recharge_card_rsp.expiredTime >> 32) & 0xFFFFFFFF); + len += 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.recharge_card_rsp.expiredTime & 0xFFFFFFFF); + len += 0x04; + // + + return len; +} + +int encode_rest_check_balance_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.check_balance_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.check_balance_req.msisdn); + len += vallen; + + buf[len++] = IE_AMOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.check_balance_req.amount); + len += 0x04; + + return len; +} + +int encode_rest_check_balance_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.check_balance_rsp.result; + + // IE_ERROR_CODE + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.check_balance_rsp.error_code); + len += 0x04; + + // IE_BALANCE_AVAILABLE + buf[len++] = IE_BALANCE_AVAILABLE; + buf[len++] = 0x01; + buf[len++] = ptr->msg.check_balance_rsp.available; + // + + return len; +} + +int encode_rest_query_balance_req(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.query_balance_req.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.query_balance_req.msisdn); + len += vallen; + + return len; +} + +int encode_rest_query_balance_rsp(_rest_msg_s *ptr, u8 *buf) +{ + int len=0/*, vallen=0*/; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.query_balance_rsp.result; + if(ptr->msg.query_balance_rsp.result == RES_FAILED) + { + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_balance_rsp.error_code); + len += 0x04; + + return len; + } + // + + // IE_STATUS + buf[len++] = IE_STATUS; + buf[len++] = 0x01; + buf[len] = ptr->msg.query_balance_rsp.status; + len += 1; + + // IE_BALANCE + buf[len++] = IE_BALANCE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_balance_rsp.balance); + len += 0x04; + // + + // IE_BALANCE + buf[len++] = IE_MO_EXPIRY; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_balance_rsp.mo_expiry); + len += 0x04; + // + + return len; +} + +int encode_rest_sms_deliver(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.sms_deliver.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.sms_deliver.msisdn); + len += vallen; + + buf[len++] = IE_SMS_CONTENT; + vallen = strlen(ptr->msg.sms_deliver.sms_content); + buf[len++] = vallen>>8; + buf[len++] = vallen & 0xff; + strcpy((char*)( &buf[len] ), ptr->msg.sms_deliver.sms_content); + len += vallen; + + return len; + +} + +int encode_rest_sms_deliver_res(_rest_msg_s *ptr, u8 *buf) +{ + int len=0/*, vallen=0*/; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.sms_deliver_res.result; + + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.sms_deliver_res.error_code); + len += 0x04; + + + return len; + +} + +int encode_rest_create_account(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.create_acct.msisdn); + buf[len++] = vallen; + strcpy((char*)( &buf[len] ), ptr->msg.create_acct.msisdn); + len += vallen; + + buf[len++] = IE_CUSTOMER_ID; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.customer_id); + len += 0x04; + + buf[len++] = IE_ACCOUNT_ID; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.account_id); + len += 0x04; + + buf[len++] = IE_PRODUCT_ID; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.product_id); + len += 0x04; + + buf[len++] = IE_PLAN_ID; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.plan_id); + len += 0x04; + + buf[len++] = IE_BALANCE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.balance); + len += 0x04; + + buf[len++] = IE_EXPIRY_TIME; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.expiry_date); + len += 0x04; + + buf[len++] = IE_RENT_CHARGE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.rent_charge); + len += 0x04; + + buf[len++] = IE_BIRTHDAY; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.birthday); + len += 0x04; + + + buf[len++] = IE_CUG_ID; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct.cug_id); + len += 0x04; + + buf[len++] = IE_USER_CLASS; + buf[len++] = 0x01; + buf[len] = ptr->msg.create_acct.user_class; + len += 0x01; + + return len; + +} + +int encode_rest_create_account_res(_rest_msg_s *ptr, u8 *buf) +{ + int len=0/*, vallen=0*/; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.create_acct_res.result; + + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.create_acct_res.error_code); + len += 0x04; + + return len; + +} + +int encode_rest_query_tariff(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.query_tariff.msisdn); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.query_tariff.msisdn); + len += vallen; + + buf[len++] = IE_SERVICE_TYPE; + vallen = 1; + buf[len++] = vallen; + buf[len]= ptr->msg.query_tariff.service_type; + len += vallen; + + buf[len++] = IE_TARIIFF_PREFIX; + vallen = strlen(ptr->msg.query_tariff.called_number); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.query_tariff.called_number); + len += vallen; + + return len; + +} + +int encode_rest_query_tariff_res(_rest_msg_s *ptr, u8 *buf) +{ + int len= 0, vallen=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.query_tariff_res.result; + if(ptr->msg.query_tariff_res.result == RES_FAILED) + { + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x01; + buf[len++] = ptr->msg.query_tariff_res.error_code; + + return len; + } + + + buf[len++] = IE_TARIIFF_PREFIX; + vallen = strlen(ptr->msg.query_tariff_res.prefix); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.query_tariff_res.prefix); + len += vallen; + + buf[len++] = IE_TARIFF_UNIT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_tariff_res.unit_time); + len += 0x04; + + buf[len++] = IE_TARIFF_CHARGE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_tariff_res.unit_charge); + len += 0x04; + + buf[len++] = IE_TARIFF_DISCOUNT; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_tariff_res.discount); + len += 0x04; + + buf[len++] = IE_PLAN_ID; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_tariff_res.plan_id); + len += 0x04; + + buf[len++] = IE_PLAN_VALUE; + buf[len++] = 0x08; + _encode_u64(buf, &len, ptr->msg.query_tariff_res.total_plan_value); + + buf[len++] = IE_PLAN_USED_VALUE; + buf[len++] = 0x08; + _encode_u64(buf, &len, ptr->msg.query_tariff_res.used_plan_value); + + buf[len++] = IE_BUNDLE_ID; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.query_tariff_res.bundle_plan_id); + len += 0x04; + + + + return len; + +} + +int encode_rest_update_subs(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.update_subs.msisdn); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.update_subs.msisdn); + len += vallen; + + buf[len++] = IE_ACCOUNT_ID; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_subs.account_id); + len += vallen; + + if((ptr->msg.update_subs.optional_flag & 0x01) == 0x01) + { + buf[len++] = IE_STATUS; + vallen = 1; + buf[len++] = vallen; + buf[len]= ptr->msg.update_subs.status; + len += vallen; + } + if((ptr->msg.update_subs.optional_flag & 0x02) == 0x02) + { + buf[len++] = IE_BALANCE; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_subs.balance); + len += vallen; + } + if((ptr->msg.update_subs.optional_flag & 0x04) == 0x04) + { + buf[len++] = IE_EXPIRY_TIME; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_subs.balance_expiry_date); + len += vallen; + } + + if((ptr->msg.update_subs.optional_flag & 0x08) == 0x08) + { + buf[len++] = IE_PLAN_ID; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_subs.basic_plan_id); + len += vallen; + } + + if((ptr->msg.update_subs.optional_flag & 0x10) == 0x10) + { + buf[len++] = IE_RENT_CHARGE; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_subs.basic_plan_rent); + len += vallen; + } + + if((ptr->msg.update_subs.optional_flag & 0x20) == 0x20) + { + buf[len++] = IE_VAS_CUG_STATUS; + vallen = 1; + buf[len++] = vallen; + buf[len]= ptr->msg.update_subs.vas_cug_status; + len += vallen; + } + + + return len; + +} + + +int encode_rest_update_subs_res(_rest_msg_s *ptr, u8 *buf) +{ + int len= 0;//, vallen=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.update_subs_res.result; + + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_subs_res.error_code); + len += 0x04; + + return len; + +} + + +int encode_rest_delete_subs(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.delete_subs.msisdn); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.delete_subs.msisdn); + len += vallen; + + buf[len++] = IE_CAUSE; + vallen = 1; + buf[len++] = vallen; + buf[len]= ptr->msg.delete_subs.cause; + len += vallen; + + + return len; + +} + +int encode_rest_delete_subs_res(_rest_msg_s *ptr, u8 *buf) +{ + int len= 0;//, vallen=0; + + ENCODE_HEADER(); + + // IE_RESULT + buf[len++] = IE_RESULT; + buf[len++] = 0x01; + buf[len++] = ptr->msg.delete_subs_res.result; + + buf[len++] = IE_ERROR_CODE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.delete_subs_res.error_code); + len += 0x04; + + return len; + +} + +int encode_rest_update_sess_info(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.update_sess_info.msisdn); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.update_sess_info.msisdn); + len += vallen; + + buf[len++] = IE_SESS_FLAG; + vallen = 1; + buf[len++] = vallen; + buf[len]= ptr->msg.update_sess_info.first_sess; + len += vallen; + + buf[len++] = IE_SERVICE_TYPE; + vallen = 1; + buf[len++] = vallen; + buf[len]= ptr->msg.update_sess_info.service_type; + len += vallen; + + buf[len++] = IE_TIMESTAMP; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_sess_info.start_time); + len += vallen; + + { + buf[len++] = IE_CONSUME_VALUE; + vallen = 4; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_sess_info.consumed_value); + len += vallen; + } + + if((ptr->msg.update_sess_info.optional_flag & 0x01) == 0x01) + { + buf[len++] = IE_CALLED_NUMBER; + vallen = strlen(ptr->msg.update_sess_info.called); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.update_sess_info.called); + len += vallen; + } + if((ptr->msg.update_sess_info.optional_flag & 0x02) == 0x02) + { + buf[len++] = IE_UE_IP; + vallen = 0x04; + buf[len++] = vallen; + memcpy(&buf[len], &ptr->msg.update_sess_info.ue_ip, vallen); + len += vallen; + } + if((ptr->msg.update_sess_info.optional_flag & 0x04) == 0x04) + { + buf[len++] = IE_GW_IP; + vallen = 0x04; + buf[len++] = vallen; + memcpy(&buf[len], &ptr->msg.update_sess_info.gw_ip, vallen); + len += vallen; + } + + return len; + +} + +int encode_rest_update_plan_info(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.update_plan_info.msisdn); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.update_plan_info.msisdn); + len += vallen; + + + buf[len++] = IE_SERVICE_TYPE; + vallen = 1; + buf[len++] = vallen; + buf[len]= ptr->msg.update_plan_info.service_type; + len += vallen; + + buf[len++] = IE_ACCOUNT_ID; + vallen = 0x04; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_plan_info.account_id); + len += vallen; + + buf[len++] = IE_PLAN_ID; + vallen = 0x04; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_plan_info.plan_id); + len += vallen; + + buf[len++] = IE_BUNDLE_ID; + vallen = 0x04; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_plan_info.bundle_id); + len += vallen; + + buf[len++] = IE_PLAN_VALUE; + vallen = 0x08; + buf[len++] = vallen; + _encode_u64(buf, &len, ptr->msg.update_plan_info.plan_total_value); + + buf[len++] = IE_PLAN_USED_VALUE; + vallen = 0x08; + buf[len++] = vallen; + _encode_u64(buf, &len, ptr->msg.update_plan_info.plan_used_value); + + buf[len++] = IE_SESS_UPDATE_TIME; + vallen = 0x04; + buf[len++] = vallen; + *(u32*)(&buf[len]) = htonl(ptr->msg.update_plan_info.sess_update_times); + len += vallen; + + buf[len++] = IE_PLAN_VALUE_ADD_THIS_TIME; + buf[len++] = 0x08; + _encode_u64(buf, &len, ptr->msg.update_plan_info.this_time_add_value); + + return len; + +} + + +int encode_rest_rent_charge(_rest_msg_s *ptr, u8 *buf) +{ + int len=0, vallen=0; + + if(ptr == NULL || buf == NULL) + return 0; + + ENCODE_HEADER(); + + buf[len++] = IE_MSISDN; + vallen = strlen(ptr->msg.rent_charge.msisdn); + buf[len++] = vallen; + strcpy((char *)&buf[len], ptr->msg.rent_charge.msisdn); + len += vallen; + + if((ptr->msg.update_subs.optional_flag & 0x01) == 0x01) + { + buf[len++] = IE_BALANCE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.rent_charge.balance); + len += 0x04; + + } + if((ptr->msg.update_subs.optional_flag & 0x02) == 0x02) + { + buf[len++] = IE_RENT_CHARGE; + buf[len++] = 0x04; + *(u32*)(&buf[len]) = htonl(ptr->msg.rent_charge.rent_charge); + len += 0x04; + + } + + return len; +} + +int decode_rest_rent_charge(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.rent_charge.msisdn, &buf[offset], vallen); + ptr->msg.rent_charge.msisdn[vallen] = '\0'; + break; + case IE_BALANCE: + ptr->msg.rent_charge.balance = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_RENT_CHARGE: + ptr->msg.rent_charge.rent_charge = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} +/*--------------------------------------------------------------------*/ + +static int decode_rest_send_authcode_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.send_authcode_req.msisdn, &buf[offset], vallen); + ptr->msg.send_authcode_req.msisdn[vallen] = '\0'; + break; + case IE_MSG_CONTENT: + { + int sms_len = vallen * 256 + buf[offset++]; + + memcpy(ptr->msg.send_authcode_req.sms_content, &buf[offset], sms_len); + ptr->msg.send_authcode_req.sms_content[sms_len] = '\0'; + } + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_query_user_data_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.query_user_data_req.msisdn, &buf[offset], vallen); + ptr->msg.query_user_data_req.msisdn[vallen] = '\0'; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_bundle_subs_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.bundle_subs_req.msisdn, &buf[offset], vallen); + ptr->msg.bundle_subs_req.msisdn[vallen] = '\0'; + break; + case IE_PAY_TYPE: + ptr->msg.bundle_subs_req.payType = buf[offset]; + break; + case IE_AMOUNT: + ptr->msg.bundle_subs_req.charge = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_MO_VOICE_MIN: + ptr->msg.bundle_subs_req.moVoiceMinute = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_MT_VOICE_MIN: + ptr->msg.bundle_subs_req.mtVoiceMinute = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_DATA_VOL_MB: + ptr->msg.bundle_subs_req.dataVolume = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_SMS_NUM: + ptr->msg.bundle_subs_req.smsNum = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_VALID_DAYS: + ptr->msg.bundle_subs_req.validDays = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_bundle_usage_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.bundle_usage_req.msisdn, &buf[offset], vallen); + ptr->msg.bundle_usage_req.msisdn[vallen] = '\0'; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_recharge_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.recharge_req.msisdn, &buf[offset], vallen); + ptr->msg.recharge_req.msisdn[vallen] = '\0'; + break; + case IE_AMOUNT: + ptr->msg.recharge_req.amount = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_RECHARGE_TYPE: + ptr->msg.recharge_req.op_type = buf[offset]; + break; + case IE_VALID_DAYS: + ptr->msg.recharge_req.valid_days = ntohs( *(u16*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_transfer_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN_TRANS_OUT: + memcpy(ptr->msg.transfer_req.transferOutMsisdn, &buf[offset], vallen); + ptr->msg.transfer_req.transferOutMsisdn[vallen] = '\0'; + break; + case IE_MSISDN_TRANS_IN: + { + int num_len = vallen; + if (num_len > 20) + { + num_len = 20; + } + memcpy(ptr->msg.transfer_req.transferInMsisdn, &buf[offset], num_len); + ptr->msg.transfer_req.transferInMsisdn[num_len] = '\0'; + } + break; + case IE_AMOUNT: + ptr->msg.transfer_req.amount = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_recharge_card_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.recharge_card_req.msisdn, &buf[offset], vallen); + ptr->msg.recharge_card_req.msisdn[vallen] = '\0'; + break; + case IE_PASSWORD: + { + int pwd_len = vallen; + if (pwd_len > 20) + { + pwd_len = 20; + } + memcpy(ptr->msg.recharge_card_req.cardPwd, &buf[offset], pwd_len); + ptr->msg.recharge_card_req.cardPwd[pwd_len] = '\0'; + } + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_check_balance_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.check_balance_req.msisdn, &buf[offset], vallen); + ptr->msg.check_balance_req.msisdn[vallen] = '\0'; + break; + case IE_AMOUNT: + ptr->msg.check_balance_req.amount = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_query_balance_req(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.query_balance_req.msisdn, &buf[offset], vallen); + ptr->msg.query_balance_req.msisdn[vallen] = '\0'; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} +// + +static int decode_rest_query_balance_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + ptr->msg.query_balance_rsp.result = buf[offset]; + break; + case IE_ERROR_CODE: + ptr->msg.query_balance_rsp.error_code = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_STATUS: + ptr->msg.query_balance_rsp.status = buf[offset]; + break; + case IE_BALANCE: + ptr->msg.query_balance_rsp.balance = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_MO_EXPIRY: + ptr->msg.query_balance_rsp.mo_expiry = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} +static int decode_rest_sms_deliver(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.sms_deliver.msisdn, &buf[offset], vallen); + ptr->msg.sms_deliver.msisdn[vallen] = '\0'; + break; + case IE_SMS_CONTENT: + vallen = vallen * 256 + buf[offset++]; + ptr->msg.sms_deliver.sms_len = vallen; + memcpy(ptr->msg.sms_deliver.sms_content, &buf[offset], vallen); + ptr->msg.sms_deliver.sms_content[vallen] = '\0'; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_sms_deliver_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + ptr->msg.sms_deliver_res.result = buf[offset]; + break; + case IE_ERROR_CODE: + ptr->msg.sms_deliver_res.error_code = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_create_account(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + memcpy(ptr->msg.create_acct.msisdn, &buf[offset], vallen); + ptr->msg.create_acct.msisdn[vallen] = '\0'; + break; + case IE_CUSTOMER_ID: + ptr->msg.create_acct.customer_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_ACCOUNT_ID: + ptr->msg.create_acct.account_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_PRODUCT_ID: + ptr->msg.create_acct.customer_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_PLAN_ID: + ptr->msg.create_acct.plan_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_BALANCE: + ptr->msg.create_acct.balance= ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_EXPIRY_TIME: + ptr->msg.create_acct.expiry_date = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_RENT_CHARGE: + ptr->msg.create_acct.rent_charge = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_BIRTHDAY: + ptr->msg.create_acct.birthday = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_CUG_ID: + ptr->msg.create_acct.cug_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_USER_CLASS: + ptr->msg.create_acct.user_class = buf[offset]; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_create_account_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + ptr->msg.create_acct_res.result = buf[offset]; + break; + case IE_ERROR_CODE: + ptr->msg.create_acct_res.error_code = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_query_tariff(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_SERVICE_TYPE: + ptr->msg.query_tariff.service_type = buf[offset]; + break; + case IE_MSISDN: + strcpy(ptr->msg.query_tariff.msisdn, (char *)&buf[offset]); + ptr->msg.query_tariff.msisdn[vallen] = 0; + break; + case IE_TARIIFF_PREFIX: + strcpy(ptr->msg.query_tariff.called_number, (char *)&buf[offset]); + ptr->msg.query_tariff.called_number[vallen] = 0; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_query_tariff_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + ptr->msg.query_tariff_res.result = buf[offset]; + break; + case IE_ERROR_CODE: + ptr->msg.query_tariff_res.error_code = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_TARIIFF_PREFIX: + strcpy(ptr->msg.query_tariff_res.prefix, (char *)&buf[offset]); + break; + case IE_TARIFF_UNIT: + ptr->msg.query_tariff_res.unit_time = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_TARIFF_CHARGE: + ptr->msg.query_tariff_res.unit_charge = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_TARIFF_DISCOUNT: + ptr->msg.query_tariff_res.discount = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_PLAN_ID: + ptr->msg.query_tariff_res.plan_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_PLAN_VALUE: + ptr->msg.query_tariff_res.total_plan_value = _decode_u64( &buf[offset] ); + break; + case IE_PLAN_USED_VALUE: + ptr->msg.query_tariff_res.used_plan_value = _decode_u64( &buf[offset] ); + break; + case IE_BUNDLE_ID: + ptr->msg.query_tariff_res.bundle_plan_id = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_update_subs(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + ptr->msg.update_subs.optional_flag = 0x00; + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + strcpy(ptr->msg.update_subs.msisdn, (char *)&buf[offset]); + ptr->msg.update_subs.msisdn[vallen] = 0; + break; + case IE_ACCOUNT_ID: + ptr->msg.update_subs.account_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_STATUS: + ptr->msg.update_subs.status = buf[offset]; + ptr->msg.update_subs.optional_flag |= 0x01; + break; + case IE_BALANCE: + ptr->msg.update_subs.balance = ntohl( *(u32*)(&buf[offset]) ); + ptr->msg.update_subs.optional_flag |= 0x02; + break; + case IE_EXPIRY_TIME: + ptr->msg.update_subs.balance_expiry_date = ntohl( *(u32*)(&buf[offset]) ); + ptr->msg.update_subs.optional_flag |= 0x04; + break; + case IE_PLAN_ID: + ptr->msg.update_subs.basic_plan_id = ntohl( *(u32*)(&buf[offset]) ); + ptr->msg.update_subs.optional_flag |= 0x08; + break; + case IE_RENT_CHARGE: + ptr->msg.update_subs.basic_plan_rent = ntohl( *(u32*)(&buf[offset]) ); + ptr->msg.update_subs.optional_flag |= 0x10; + break; + case IE_VAS_CUG_STATUS: + ptr->msg.update_subs.vas_cug_status = buf[offset]; + ptr->msg.update_subs.optional_flag |= 0x20; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_update_subs_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + ptr->msg.update_subs_res.result = buf[offset]; + break; + case IE_ERROR_CODE: + ptr->msg.update_subs_res.error_code = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} +static int decode_rest_delete_subs(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + strcpy(ptr->msg.delete_subs.msisdn, (char *)&buf[offset]); + ptr->msg.delete_subs.msisdn[vallen] = 0; + break; + case IE_CAUSE: + ptr->msg.delete_subs.cause = buf[offset]; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_delete_subs_res(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_RESULT: + ptr->msg.delete_subs_res.result = buf[offset]; + break; + case IE_ERROR_CODE: + ptr->msg.delete_subs_res.error_code = ntohl( *(u32*)(&buf[offset]) ); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + + +static int decode_rest_update_sess_info(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + strcpy(ptr->msg.update_sess_info.msisdn, (char *)&buf[offset]); + ptr->msg.update_sess_info.msisdn[vallen] = 0; + break; + case IE_SESS_FLAG: + ptr->msg.update_sess_info.first_sess = buf[offset]; + break; + case IE_SERVICE_TYPE: + ptr->msg.update_sess_info.first_sess = buf[offset]; + break; + case IE_TIMESTAMP: + ptr->msg.update_sess_info.start_time = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_CONSUME_VALUE: + ptr->msg.update_sess_info.consumed_value = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_CALLED_NUMBER: + strcpy(ptr->msg.update_sess_info.called, (char *)&buf[offset]); + ptr->msg.update_sess_info.called[vallen] = 0; + ptr->msg.update_sess_info.optional_flag |= 0x01; + break; + case IE_UE_IP: + memcpy(&ptr->msg.update_sess_info.ue_ip, &buf[offset], 4); + ptr->msg.update_sess_info.optional_flag |= 0x02; + break; + case IE_GW_IP: + memcpy(&ptr->msg.update_sess_info.gw_ip, &buf[offset], 4); + ptr->msg.update_sess_info.optional_flag |= 0x04; + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +static int decode_rest_update_plan_info(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + int tag = 0, vallen=0; + + while(offsetheader.src_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_DST_REF: + ptr->header.dst_ref = ntohs( *(u16*)(&buf[offset]) ); + break; + case IE_MSISDN: + strcpy(ptr->msg.update_plan_info.msisdn, (char *)&buf[offset]); + ptr->msg.update_plan_info.msisdn[vallen] = 0; + break; + case IE_SERVICE_TYPE: + ptr->msg.update_plan_info.service_type = buf[offset]; + break; + case IE_ACCOUNT_ID: + ptr->msg.update_plan_info.account_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_PLAN_ID: + ptr->msg.update_plan_info.plan_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_BUNDLE_ID: + ptr->msg.update_plan_info.bundle_id = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_PLAN_VALUE: + ptr->msg.update_plan_info.plan_total_value = _decode_u64(&buf[offset] ); + break; + case IE_PLAN_USED_VALUE: + ptr->msg.update_plan_info.plan_used_value = _decode_u64( &buf[offset] ); + break; + case IE_SESS_UPDATE_TIME: + ptr->msg.update_plan_info.sess_update_times = ntohl( *(u32*)(&buf[offset]) ); + break; + case IE_PLAN_VALUE_ADD_THIS_TIME: + ptr->msg.update_plan_info.this_time_add_value = _decode_u64(&buf[offset]); + break; + default: + break; + } + offset += vallen; + } + + return retval; +} + +/* --------------------------------------------------------*/ +int decode_rest_api_msg(u8 *buf, int len, _rest_msg_s *ptr) +{ + int retval = 1; + int offset = 0; + + if (len <= 9) + { + return -1; + } + + ptr->msg_type = buf[offset++]; + + switch (ptr->msg_type) + { + case REST_QUERY: + decode_rest_query(buf+1, len-1, ptr); + break; + case REST_TOPUP: + decode_rest_topup(buf+1, len-1, ptr); + break; + case REST_TRANSFER: + decode_rest_transfer_res(buf+1, len-1, ptr); + break; + case REST_CHANNEL: + decode_rest_channel_res(buf+1, len-1, ptr); + break; + case REST_POINT_QUERY: + decode_rest_queryPoint_res(buf+1, len-1, ptr); + break; + case REST_POINT_TRANSFER: + decode_rest_transferPoint_res(buf+1, len-1, ptr); + break; + // for selfcare + case REST_SEND_AUTHCODE_REQ: + decode_rest_send_authcode_req(buf+1, len-1, ptr); + break; + case REST_QUERY_USERDATA_REQ: + decode_rest_query_user_data_req(buf+1, len-1, ptr); + break; + case REST_BUNDLE_SUBS_REQ: + decode_rest_bundle_subs_req(buf+1, len-1, ptr); + break; + case REST_BUNDLE_USAGE_REQ: + decode_rest_bundle_usage_req(buf+1, len-1, ptr); + break; + case REST_RECHARGE_REQ: + decode_rest_recharge_req(buf+1, len-1, ptr); + break; + case REST_TRANSFER_REQ: + decode_rest_transfer_req(buf+1, len-1, ptr); + break; + case REST_RECHARGE_CARD_REQ: + decode_rest_recharge_card_req(buf+1, len-1, ptr); + break; + case REST_CHECK_BALANCE_REQ: + decode_rest_check_balance_req(buf+1, len-1, ptr); + break; + case REST_QUERY_BALANCE_REQ: + decode_rest_query_balance_req(buf+1, len-1, ptr); + break; + case REST_CRM_SMS_DELIVER_REQ: + decode_rest_sms_deliver(buf+1, len-1, ptr); + break; + case REST_CRM_SMS_DELIVER_RES: + decode_rest_sms_deliver_res(buf+1, len-1, ptr); + break; + case REST_CRM_CREATE_ACCT_REQ: + decode_rest_create_account(buf+1, len-1, ptr); + break; + case REST_CRM_CREATE_ACCT_RES: + decode_rest_create_account_res(buf+1, len-1, ptr); + break; + case REST_CRM_QUERY_TARIFF_RES: + decode_rest_query_tariff_res(buf+1, len-1, ptr); + break; + case REST_CRM_UPDATE_SUBS_REQ: + decode_rest_update_subs(buf+1, len-1, ptr); + break; + case REST_CRM_DELETE_SUBS_REQ: + decode_rest_delete_subs(buf+1, len-1, ptr); + break; + case REST_CRM_UPDATE_SESS_INFO_REQ: + decode_rest_update_sess_info(buf+1, len-1, ptr); + break; + case REST_CRM_UPDATE_PLAN_INFO_REQ: + decode_rest_update_plan_info(buf+1, len-1, ptr); + break; + default: + break; + } + + return retval; +} + diff --git a/mss/pps/src/main/smppapi.c b/mss/pps/src/main/smppapi.c new file mode 100644 index 0000000..3dc08d5 --- /dev/null +++ b/mss/pps/src/main/smppapi.c @@ -0,0 +1,2199 @@ +#include +#include +#include +#include "../include/includes.h" + +#include "../include/ppsm.h" +#include "../include/param.h" +#include "../include/ramdata.h" +#include "../include/message.h" +#include "../include/mfunc.h" +//#include "../include/ppsMibTable.h" + +#include "../../../../plat/smpp/src/include/smpp.h" +/*----------------------------------------------------------*/ + +extern int SendAccountInfoBySMPP(); +extern int RechargeCardRequest(u_short proc_id,char *card_hrn, int *result); +extern int RechargeRequestProc(u_short portid); + +extern int saveCMBSMSACK(u_short portid,u_char *sms); +extern int callMebackSMSProc(u_short portid); +extern int switchServiceProc(u_short portid, u_char *shortMsg); +extern int saveTransferSMSACK(u_short portid,u_char *sms); +extern int transferAccountSMSProc(u_short portid); + +extern PPSParamStruct ppsParam; +extern char logMsisdn[18]; + +#define MAX_SMPP_MSG 128 +#define MAX_SMPP_LINK_SET 4 + +#define PROMPT_SM_DELAY_TIME 20 //seconds delay to send SM promtp +/*---------------------------------------------------------*/ +int smppSendMOSM(char *caller, char *called, u_char *msg, int msgLen,u_char dataCoding); + + +typedef enum _SMPP_DIR +{ + _SMPP_SEND, + _SMPP_RECV, +}SMPP_DIR; + +typedef enum _SMPP_LINK_STATUS +{ + _SMPP_UNUSED=0, + _SMPP_USED, +}SMPP_LINK_STATUS; + +typedef struct _SMPP_STATUS +{ + int linkNo[MAX_SMPP_LINK_SET]; + int link_state[MAX_SMPP_LINK_SET]; + int dir[MAX_SMPP_LINK_SET]; +}SMPP_STATUS; +/* index=0/1/2=Recharge Tx, Inquiry Tx, Recharge Rx */ + +SMPP_STATUS smpp_status; + +typedef struct _smpp_recv_buf +{ + struct SMPP_MSG rSM_msg; +}smpp_recv_buf; + +typedef struct _smpp_send_buf +{ + struct SMPP_MSG sSM_msg[MAX_SMPP_MSG]; + u_long submitTime[MAX_SMPP_MSG]; + u_short head; + u_short tail; +}smpp_send_buf; + +typedef struct _pps_smpp_msg_buf{ + smpp_send_buf ppsSMPPsBufRecharge; + smpp_send_buf ppsSMPPsBufInquiry; +}pps_smpp_msg_buf; + +pps_smpp_msg_buf ppsSMPPmsgBuf; +static int smpp_link_selection = 0; +/*---------------------------------------------------------*/ +extern int logMsgFlag; +extern u_short debug_messages; +extern _ram_data *ramshm_ptr; +extern _state_machine *smshm_ptr; +extern u_char alarm_code[2]; +/*---------------------------------------------------------*/ +static int pps_smppOnDataRecv(BYTE linkNo, SMPP_MSG *pdaa, WORD dataLen); +static int pps_smppOnLinkStateChange(BYTE linkNo, BYTE state); +extern int GetAccountLastCallInfo(_account_info *ptr, _last_call_info *pInfo); +extern void SendAccountInfoBySMPPtoThirdParty(_account_info *ptr, char *called, char *third_party_number); +extern int getTransferInfo(u_short portid,u_char *ussd_data); +/*---------------------------------------------------------*/ +int smppEncodeSM(char *asciiIn, u_char *bcdOut) +{ + + int i,len,n,cur,index=0; + unsigned char mid1,mid2; + char strIn[180]; + + n=0; + + len=strlen(asciiIn); + if(len < 1) + { + return 0; + } + + if(len > 160) + { + len=160; + memcpy(strIn, asciiIn, len); + strIn[160] = 0; + } + else + { + strcpy(strIn,asciiIn); + } + + for(i=0;i>n) |((mid2<<(7-n))&0xff); + } + else + { + mid1=strIn[i]; + if(n==6) + { + mid2 = 0x0d; /* ussd filler, isn't the same as SMS, refer to gsm03.38 */ + } + else + { + mid2 = 0x00; + } + cur=(mid1>>n) | ((mid2<<(7-n))&0xff); + } + bcdOut[index++]=cur; + n=(n+1)%7; + if(n==0 ) i++; + } + + bcdOut[index]='\0'; + return index; +} +int smppDecodeSM(char *strIn, char *strOut,int length) +{ + int i,n,j; + int len; + unsigned char mid1,mid2,cur; + unsigned char strHex[512]; + + PutLogFunID("smppDecodeSM"); + + n=0;j=0; + //len = length - length/8; + len = length; + if(len>160) len = 160; + + memcpy(strHex,strIn,len); + + for(i=0;i<=len;i++) + { + if(i>0) + { + mid1=strHex[i]; + mid2=strHex[i-1]; + cur=((mid1<>(8-n)); + } + else + { + mid1=strHex[i]&0x7f; + cur=mid1; + } + strOut[j++] = cur; + n =(n+1)%8; + if(n==0) i--; + } + + for(i=0;i70 ) len=70; + if(len<1) return 0; + + index = 0; + for(i=0;i>6); + bcdOut[index++] = 0x80 | (mid1 & 0x3f); + } + } + + bcdOut[index]='\0'; + return index; +} + +/*---------------------------------------------------------------*/ +int isValidMsisdn(char *msisdn) +{ + int len = strlen(msisdn); + int i; + for (i=0; ipdu.deliver_sm.short_message, + short_message, + pMsg->pdu.deliver_sm.sm_length); + sms_len = strlen(short_message); + if((pMsg->pdu.deliver_sm.sm_length %7 == 0) && (sms_len > 0)) + { + if(short_message[sms_len-1] == '@') /* the last char can't be '@', it's a padding byte */ + short_message[sms_len-1] = '\0'; + } + + + proc_id = AssignProcID(0); + if(proc_id<0) return 0; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += proc_id; + shmp->process_info.portid = proc_id; + shmp->process_info.chargeOther = 0; + + strcpy((char *)shmp->caller_info.number,pMsg->pdu.deliver_sm.source_addr); + strcpy((char *)shmp->called_info.number,pMsg->pdu.deliver_sm.destination_addr); + strcpy((char *)shmp->origin_info.number,pMsg->pdu.deliver_sm.destination_addr); + + + shmp->cdr_info.seizuretime = time(NULL); + shmp->cdr_info.answertime = time(NULL); + + + len = strlen((char *)shmp->called_info.number); + strcpy(buf, (char *)shmp->called_info.number); + if(len %2 ==1){ + strcat(buf,"F"); + len ++; + } + strcat(buf,"FF"); + ppsAsciiToBcdR(shmp->cdr_info.called, buf, len+2); + + if((logMsgFlag & 0x02) && debug_messages<=MAX_DEBUG_MESSAGES) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Recv SM from %s to %s through SMPP : %s\n", + pMsg->pdu.deliver_sm.source_addr, + shmp->called_info.number, + short_message); + } + + shmp->process_info.all_in_one_input_flag = 0; + shmp->context_info.callType = CT_MO_SM; + action = GetServiceType_0(shmp); + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + DebugMsg(debugmib.display.asciiOut, + "%s, Service number: %s, action = %d\n", __FUNCTION__, + shmp->called_info.number, action); + } + + if((action == SRV_SCRATCH_CARD_RECHARGE && sms_len > 16 ) || + (action == SRV_BUNDLE_PLAN && sms_len >6)) + {//the operation is: xx*MSISDN, minimum length of MSISDN is 5 digits + int offset = 0; + char *delimeter_ptr = NULL; + + if((delimeter_ptr = strstr(short_message, "*") ) != NULL) + { + offset = delimeter_ptr - short_message; + if((sms_len - offset)>5) + { + strcpy((char *)shmp->origin_info.number, (char *)shmp->caller_info.number); + strncpy((char *)shmp->caller_info.number, &short_message[offset+1], MAX_ASCII_NUMBER_LEN-1); + shmp->caller_info.number[MAX_ASCII_NUMBER_LEN-1] = '\0'; + short_message[offset] = '\0'; + shmp->process_info.chargeOther = 1; + + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + + DebugMsg(debugmib.display.asciiOut, + "[%04d], by 3rd party, real caller is: %s, sms=%s\r\n", proc_id, + shmp->caller_info.number, + short_message); + } + + if(isValidMsisdn((char *)shmp->caller_info.number) <= 0) + { + if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "[%04d], invalid real caller=%s\r\n", proc_id, + shmp->caller_info.number); + } + return 0; + } + } + } + + } + + + memset(shmp->caller_info.IMSI, 0xFF, 8); + + len = strlen((char *)shmp->caller_info.number); + strcpy(buf, (char *)shmp->caller_info.number); + if(len %2 ==1){ + strcat(buf,"F"); + len ++; + } + strcat(buf,"FF"); + ppsAsciiToBcdR(shmp->cdr_info.caller,buf,len+2); + memcpy(shmp->cdr_info.msisdn, shmp->cdr_info.caller,12); + + /* + len = strlen(short_message); + strcpy(buf,short_message); + strcat(buf,"F"); + ppsAsciiToBcdR(shmp->cdr_info.called,buf,len+2); + */ + + + GetAccountPos(&shmp->caller_info); + cos_id = GetAccountCosID(&shmp->caller_info); + + shmp->caller_info.status = GetAccountStatus(&shmp->caller_info); + shmp->caller_info.cos_id = cos_id; + + if(!pps_get_adaptor_flag()) + { + if(shmp->caller_info.head>=MSISDN_HEAD_NUM || + shmp->caller_info.status == T_BLACKLIST || + shmp->caller_info.status == T_RELEASED) + { + DebugMsg(debugmib.display.asciiOut, + "Unused caller for SM recharging/inqurying"); + ReleasePortStatus(proc_id); + return 0; + } + } + + if(logMsgFlag & 0x08) + { + if(strstr((char *)shmp->caller_info.number,logMsisdn)) + { + shmp->process_info.logMsisdn = 0x01; + } + if(strstr((char *)shmp->called_info.number,logMsisdn)) + { + shmp->process_info.logMsisdn = 0x01; + } + } + + shmp->process_info.all_in_one_input_flag = 0; + + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + if(action == SRV_INQUIRY ) + { + AddPPSStatistics(MIBPPS_SM_INQUIRY,shmp->process_info.dir); + + if(pps_get_adaptor_flag()) + { + shmp->process_info.state = S_SMPP_MAIN; + shmp->process_info.sub_state = S_SMPP_REST_QUERY; + shmp->process_info.sub_state_2 = 0; + shmp->process_info.rest_if.rest_oc = 0; + shmp->process_info.rest_if.rest_src = 1; + return 0; + } + + switch(shmp->caller_info.status) + { + case T_FRESH: + if(!(cosTableItem->accountValidity[0].activiationByInquiryIs)) + break; + UpdateAccountStatus(shmp->caller_info.head, + shmp->caller_info.tail, + T_NORMAL); + UpdateAccountFirstUsedDate( + shmp->caller_info.head, + shmp->caller_info.tail); + UpdateExpirationFirstInquiry(&shmp->caller_info, + cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance); + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + smppSendActivicationInfo(&shmp->caller_info, + (char *)shmp->called_info.number); + ReleasePortStatus(proc_id); + return 1; + break; + case T_NORMAL: + case T_OPRTRIAL: + AsciiTime(expire_date,GetExpiration(&shmp->caller_info)); + if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) + { + SendAccountInfoBySMPP(&shmp->caller_info, + shmp->called_info.number); + } + break; + default: + DebugMsg(debugmib.display.asciiOut, "Error caller : %s\n", shmp->caller_info.number); + ReleasePortStatus(proc_id); + return 0; + break; + } + } + else if(action == SRV_FEE_TRANSFER) + { + clearTransferInfo(proc_id); + saveTransferSMSACK(proc_id, (u_char *)short_message); + + if(pps_get_adaptor_flag()) + { + result = getTransferInfo(proc_id, (u_char *)short_message); + if(result == 1) + { + shmp->process_info.state = S_SMPP_MAIN; + shmp->process_info.sub_state = S_SMPP_REST_TRANSFER; + shmp->process_info.sub_state_2 = 0; + shmp->process_info.rest_if.rest_oc = 1; + shmp->process_info.rest_if.rest_src = 1; + return 0; + } + } + + + transferAccountSMSProc(proc_id); + } + else if(action == SRV_CALL_ME_BACK) + { + clearCMBInfo(proc_id); + if(shmp->process_info.all_in_one_input_flag) + saveCMBSMSACK(proc_id,shmp->called_info.number); + else + saveCMBSMSACK(proc_id, (u_char *)short_message); + callMebackSMSProc(proc_id); + } + else if(action == SRV_FREE_SMS) + { + switchServiceProc(proc_id, (u_char *)short_message); + } + else if(action == SRV_SCRATCH_CARD_RECHARGE) + {//RECHARGE_REQUEST + AddPPSStatistics(MIBPPS_SM_RECHARGE,shmp->process_info.dir); + + if(!pps_get_adaptor_flag()) + { + if(shmp->caller_info.status != T_FRESH && + shmp->caller_info.status != T_NORMAL && + shmp->caller_info.status != T_SUSPEND && + shmp->caller_info.status != T_OPRTRIAL + ) //LOW BALANCE, EXPIRED + { + if(0) + DebugMsg(debugmib.display.asciiOut, + "Recharging failed for caller status is error!\n"); + ReleasePortStatus(proc_id); + return 0; + } + } + + len = strlen(short_message); + if(len>16) + { + if(0) + DebugMsg(debugmib.display.asciiOut, + "Recharging failed for wrong card length!\n"); + ReleasePortStatus(proc_id); + return 0; + } + + shmp->process_info.chargeFrom = 2; /*recharge from SHORT MESSAGE */ + shmp->process_info.rechargeByOther = 3; + strcpy((char *)shmp->called_info.number,short_message); + + len = strlen((char *)shmp->called_info.number); + strcpy(buf, (char *)shmp->called_info.number); + if(len %2 ==1){ + strcat(buf,"F"); + len ++; + } + strcat(buf,"FF"); + ppsAsciiToBcdR(shmp->cdr_info.called, buf, len+2); + + if(UseExternalVC()) + { + strcpy((char *)shmp->called_info.number, short_message); + shmp->process_info.state = S_SMMP_RECHAGE_ACCOUNT; + shmp->process_info.sub_state = 0; + return 1; + } + if(OCS_with_external_CRM()) + { + strcpy((char *)shmp->called_info.number, short_message); + shmp->process_info.state = S_SMMP_RECHAGE_ACCOUNT; + shmp->process_info.sub_state = 2; + return 1; + } + + if(pps_get_adaptor_flag()) + { + strcpy((char *)shmp->called_info.number, short_message); + shmp->process_info.state = S_SMPP_MAIN; + shmp->process_info.sub_state = S_SMPP_REST_TOPUP; + shmp->process_info.sub_state_2 = 0; + shmp->process_info.rest_if.rest_oc = 1; + shmp->process_info.rest_if.rest_src = 1; + return 0; + } + + if(RechargeCardRequest(proc_id,short_message, &result)!= 1) + { + SendRechargeCDR(proc_id, CT_RECHARGE_FAIL, 0); + UpdateAccountRechargeFail(shmp->caller_info.head, + shmp->caller_info.tail); + maxThreshold = GetParamRechargeAttemptLimit(); + + if(maxThreshold>0 && + maxThreshold < GetAccountRechargeFail( shmp->caller_info.head, shmp->caller_info.tail) ) + { + UpdateAccountStatus(shmp->caller_info.head, + shmp->caller_info.tail, + T_BLACKLIST); + ResetAccountRechargeFail(shmp->caller_info.head, + shmp->caller_info.tail); + } + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + + shmp->caller_info.tail; + SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); + + if(result == 5) + { + char maxBalanceNote[]={"Recharge failed, you have exceeded your maximum balance"}; + smppSendMOSM((char *)shmp->caller_info.number, + (char *)shmp->origin_info.number, + (u_char *)maxBalanceNote, + strlen(maxBalanceNote), + 0); + } + else + { + char failedNote[]={"Recharge failed, check PIN and try again"}; + smppSendMOSM((char *)shmp->caller_info.number, + (char *)shmp->origin_info.number, + (u_char *)failedNote, + strlen(failedNote), + 0); + + } + if(0) + DebugMsg(debugmib.display.asciiOut, + "Recharge failed for error prepaid card!\n"); + ReleasePortStatus(proc_id); + return 0; + } + AsciiTime(expire_date,GetExpiration(&shmp->caller_info)); + RechargeRequestProc(proc_id); + + if(shmp->process_info.chargeOther == 1) + { + SendAccountInfoBySMPPtoThirdParty(&shmp->caller_info, + (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, + (char *)shmp->origin_info.number); + } + + } + else if(action == SRV_BUNDLE_PLAN) + { + subscribe_bundle_plan(shmp, short_message, 0, NULL); + } + else if(action == SRV_BUNDLE_QUERY) + { + ocs_bundle_plan_query(shmp, short_message, 0, NULL); + } + else + { + if(0) + DebugMsg(debugmib.display.asciiOut, + "Unknown service number: %s\n", + shmp->called_info.number); + } + + ReleasePortStatus(proc_id); + + return 1; +} + +int get_cos_bundle_control(int cos_id) +{ + COSTable *cosTableItem; + + if(cos_id >= MaxCosTableItem) return 1; //default is data plan only + + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + return cosTableItem->serviceControl[0].bundle_plan_contorl; + +} + +int subscribe_bundle_plan_send_used_up_info(char *caller_number, SMS_SENTENCE id) +{ + char sms_msg[256]; + char bundle_service_number[32]; + + if(OCS_with_external_CRM()) + return 0; + + switch (id) + { + case SMS_BUNDLE_PLAN_DATA_USEDUP: + case SMS_BUNDLE_PLAN_VOICE_USEDUP: + case SMS_BUNDLE_PLAN_SMS_USEDUP: + break; + default: + return 0; + } + + sprintf(sms_msg, "%s" , getSmsSentenceNative(0, id)); + sprintf(bundle_service_number, "%s", + ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number); + + smppSendMOSM(caller_number, + bundle_service_number, + (u_char *)sms_msg, + strlen(sms_msg), + 0); + + return 1; +} + +int subscribe_bundle_plan_send_warning_info(_state_data *shmp) +{ + char sms_msg[256]; + char bundle_service_number[32]; + long ret_value[10], data_warning_threshold = 2, data_warning_threshold_low=1, warning_sms_counter=0; + + int cos_id; + + if(OCS_with_external_CRM()) + return 0; + + cos_id = GetAccountCosID(&shmp->caller_info); + + data_warning_threshold = ppsParam.ppsTables.cosTable[cos_id].serviceControl[0].bundle_data_warning_threashold * 5;// COS + data_warning_threshold_low = ppsParam.ppsTables.cosTable[cos_id].serviceControl[0].bundle_data_warning_threashold_low * 5;// COS + + GetAccountBundlePlanInfo(&shmp->caller_info, ret_value); + + warning_sms_counter = ret_value[5]; + if(warning_sms_counter >= 2)// warning_sms_flag, don't send warning SMS, if 2 threshold warning SMS is already sent. + return 0; + if(ret_value[0] > data_warning_threshold)// remain bundle > threshold, don't send warning SMS + return 0; + if(warning_sms_counter == 1) + { + if(ret_value[0] > data_warning_threshold_low) + return 0; + } + + if ((ret_value[1] > 0) || (ret_value[3] > 0)) + { + sprintf(sms_msg, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_DATA_WARN_HAS_V), + ret_value[0], ret_value[1], ret_value[3]); + } + else + { + sprintf(sms_msg, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_DATA_WARN), + ret_value[0]); + } + + sprintf(bundle_service_number, "%s", + ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number); + + UpdateAccountBundlePlanInfoWarningFlag(shmp, ret_value[5]+1); + + smppSendMOSM((char *)shmp->caller_info.number, + bundle_service_number, + (u_char *)sms_msg, + strlen(sms_msg), + 0); + + return 1; +} + +int subscribe_bundle_plan_query_info(_state_data *shmp, int operation, int method, char *ret_prompt) +{ + char sms_msg[1024], sms_buf[1024]; + int i, unit_index=0, unit = 1; + char data_unit_name[2][8] ={"MB","GB"}; + char data_content[128]; + int cos_bundle_control=0;; + int menu_index = 1; + + memset(sms_msg, 0x00, 1024); + + cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); + + if(operation == 1) + { + if(method == 0) + sprintf(sms_msg, "%s\r\n" , getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_PLEASE)); + } + else + { + //sprintf(sms_msg, "%s\r\n" , getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_CMD)); + if(method == 0) + sprintf(sms_msg, "%s\r\n" , getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_PLEASE)); + } + + + for(i=1; i 0) \ + || (ppsParam.ppsTables.bundlePlans[i].sms > 0)) + ) + { + if (cos_bundle_control)// usr has data plan only + { + continue; + } + + if(ppsParam.ppsTables.bundlePlans[i].data > 1000) + { + unit_index = 1; + unit = 1024; + if(ppsParam.ppsTables.bundlePlans[i].data % unit) + { + sprintf(data_content, "%.1f%s", ppsParam.ppsTables.bundlePlans[i].data*1.0/unit, data_unit_name[unit_index]); + } + else + { + sprintf(data_content, "%d%s", ppsParam.ppsTables.bundlePlans[i].data/unit, data_unit_name[unit_index]); + } + } + else + { + unit_index = 0; + unit = 1; + sprintf(data_content, "%d%s", ppsParam.ppsTables.bundlePlans[i].data/unit, data_unit_name[unit_index]); + } + + if(method == 0) + { + sprintf(sms_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN), + getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_CMD), + ppsParam.ppsTables.bundlePlans[i].charge / 100, + ppsParam.ppsTables.bundlePlans[i].charge /100, + //ppsParam.ppsTables.bundlePlans[i].data, + data_content, + ppsParam.ppsTables.bundlePlans[i].mo_voice, + //ppsParam.ppsTables.bundlePlans[i].mt_voice, + ppsParam.ppsTables.bundlePlans[i].sms, + ppsParam.ppsTables.bundlePlans[i].validity + ); + } + else if(method == 1) + { + continue;/* + sprintf(sms_buf, getSmsSentenceNative(0, SMS_BUNDLE_PLAN_USSD_SUB_MENU), + menu_index++, //i, + data_content, + ppsParam.ppsTables.bundlePlans[i].validity, + ppsParam.ppsTables.bundlePlans[i].charge /100, + ppsParam.ppsTables.bundlePlans[i].mo_voice, + ppsParam.ppsTables.bundlePlans[i].sms + );*/ + } + else if(method == 2) + { + u8 apply_code; + if (shmp->process_info.serviceKey != 7)// not query bundle plan + { + continue; + } + + apply_code = menu_index++; + if(ppsParam.ppsTables.bundlePlans[i].apply_code > 0) + apply_code = ppsParam.ppsTables.bundlePlans[i].apply_code; + + sprintf(sms_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_USSD_SUB_CHOICE), + apply_code, + data_content, + ppsParam.ppsTables.bundlePlans[i].mo_voice, + ppsParam.ppsTables.bundlePlans[i].sms, + ppsParam.ppsTables.bundlePlans[i].validity, + ppsParam.ppsTables.bundlePlans[i].charge /100 + ); + + } + } + else + { + + if(ppsParam.ppsTables.bundlePlans[i].data > 1000) + { + unit_index = 1; + unit = 1024; + if(ppsParam.ppsTables.bundlePlans[i].data % unit) + { + sprintf(data_content, "%.1f%s", ppsParam.ppsTables.bundlePlans[i].data*1.0/unit, data_unit_name[unit_index]); + } + else + { + sprintf(data_content, "%d%s", ppsParam.ppsTables.bundlePlans[i].data/unit, data_unit_name[unit_index]); + } + } + else + { + + unit_index = 0; + unit = 1; + sprintf(data_content, "%d%s", ppsParam.ppsTables.bundlePlans[i].data/unit, data_unit_name[unit_index]); + } + + if(method == 0) + { + sprintf(sms_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_DATA), + getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_CMD), + ppsParam.ppsTables.bundlePlans[i].charge / 100, + ppsParam.ppsTables.bundlePlans[i].charge /100, + //ppsParam.ppsTables.bundlePlans[i].data /unit, + //data_unit_name[unit_index], + data_content, + ppsParam.ppsTables.bundlePlans[i].validity + ); + } + else if(method == 1) + { + u8 apply_code = menu_index++; //i; + if(ppsParam.ppsTables.bundlePlans[i].apply_code > 0) + apply_code = ppsParam.ppsTables.bundlePlans[i].apply_code; + + sprintf(sms_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_USSD_DATA), + apply_code, + data_content, + ppsParam.ppsTables.bundlePlans[i].validity, + ppsParam.ppsTables.bundlePlans[i].charge /100 + ); + + } + else if(method == 2) + { + u8 apply_code; + if (shmp->process_info.serviceKey != 6)// not query data plan + { + continue; + } + + apply_code = menu_index++; + if(ppsParam.ppsTables.bundlePlans[i].apply_code > 0) + apply_code = ppsParam.ppsTables.bundlePlans[i].apply_code; + + sprintf(sms_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_USSD_SUB_DATA_CHOICE), + apply_code, + data_content, + ppsParam.ppsTables.bundlePlans[i].validity, + ppsParam.ppsTables.bundlePlans[i].charge /100 + ); + + } + + } + + strcat(sms_msg, sms_buf); + strcat(sms_msg, "\r\n"); + + } + } + strcat(sms_msg, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_NO_REFUND)); + + if(method == 0) + { + smppSendMOSM((char *)shmp->caller_info.number, + (char *)shmp->called_info.number, + (u_char *)sms_msg, + strlen(sms_msg), + 0); + } + else + { + if(ret_prompt != NULL) + strcpy(ret_prompt, sms_msg); + } + + return 1; +} + +int subscribe_bundle_plan_subs_index(_state_data *shmp, int plan_index, int method, char *ret_prompt) +{ + float charge = 0.0; + + serviceBundlePlan *bp_ptr = NULL; + float balance; + char sms_msg[256], sms_tmp[256]; + + balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); + bp_ptr = &ppsParam.ppsTables.bundlePlans[plan_index]; + + charge = bp_ptr->charge; + if(balance < charge) + { + sprintf(sms_msg, "%s", getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_NOK)); + + goto bundle_plan_send_sms; + } + + if(1) + { + CHARGED_FEE chargeFee; + int instance; + long ret_value[10]; + char expire_date[64]; + + UpdateBalance(shmp, &shmp->caller_info, -charge, &chargeFee); + + ret_value[0] = 0 - bp_ptr->charge; + ret_value[1] = bp_ptr->data; + ret_value[2] = bp_ptr->mo_voice; + ret_value[3] = bp_ptr->mt_voice; + ret_value[4] = bp_ptr->sms; + ret_value[5] = bp_ptr->validity; + ret_value[6] = 0; + + UpdateAccountBundlePlanInfo(&shmp->caller_info, ret_value); + + instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; + + SendAccountRealSync(instance, chargeFee.balance, chargeFee.promotion, OMC_OCODE_EDIT); + + shmp->caller_info.charge = charge; + shmp->process_info.call_type = CT_BUNDLE_PLAN_CHARGE; + shmp->process_info.duration = 0; + if ((bp_ptr->mo_voice > 0) || (bp_ptr->mt_voice > 0)) + { + shmp->process_info.tcos = 1;// bundle plan + } + else + { + shmp->process_info.tcos = 0;// data plan + } + + shmp->cdr_info.seizuretime = time(NULL); + shmp->cdr_info.answertime = time(NULL); + shmp->cdr_info.releasetime = time(NULL); + + SendCDR(shmp->process_info.portid); + + GetAccountBundlePlanInfo(&shmp->caller_info, ret_value); + + AsciiTimeYMD(expire_date,ret_value[4]); + + sprintf(sms_msg, "%s", (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_OK)); + if(ret_value[1]>0 || ret_value[3]>0) + sprintf(sms_tmp, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY), + ret_value[0], + ret_value[1], + // ret_value[2],// disable MT voice + ret_value[3], + expire_date); + else + sprintf(sms_tmp, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY_DATA), + ret_value[0], + expire_date); + + strcat(sms_msg, sms_tmp); + + } + +bundle_plan_send_sms: + if(method) + { + if(ret_prompt != NULL) + strcpy(ret_prompt, sms_msg); + } + else + { + smppSendMOSM((char *)shmp->caller_info.number, + (char *)shmp->called_info.number, + (u_char *)sms_msg, + strlen(sms_msg), + 0); + + if(shmp->process_info.chargeOther == 1) + { + char real_sms[1024]; + sprintf(real_sms, "%s: %s", shmp->caller_info.number, + sms_msg); + smppSendMOSM((char *)shmp->origin_info.number, + (char *)shmp->called_info.number, + (u_char *)real_sms, + strlen(real_sms), + 0); + } + + } + + return 1; +} + +int ocs_bundle_plan_query(_state_data *shmp, char *sms, int method, char *ret_prompt) +{ + //int sms_len; + //int i; + //char bs_command[128]; + + u_long ret_value[10]; + char expire_date[64]; + char sms_msg[256]; + + if(0) + DebugMsg(debugmib.display.asciiOut, + "[%04d] %s, content: %s, method=%d\n", + shmp->process_info.portid, __FUNCTION__, sms, method); + + + if(1) + { + if(GetAccountBundlePlanInfo(&shmp->caller_info, (long *)ret_value)) + { + AsciiTimeYMD(expire_date,ret_value[4]); + + if(ret_value[1]>0 || ret_value[3]>0) + { + sprintf(sms_msg, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY), + ret_value[0], + ret_value[1], + // ret_value[2],// disable MT voice + ret_value[3], + expire_date); + } + else + sprintf(sms_msg, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY_DATA), + ret_value[0], + expire_date); + + if(method) + { + if(ret_prompt != NULL) + strcpy(ret_prompt, sms_msg); + } + else + { + smppSendMOSM((char *)shmp->caller_info.number, (char *)shmp->called_info.number, + (u_char *)sms_msg, + strlen(sms_msg), + 0); + } + return 0; + + } + + } + + return subscribe_bundle_plan_query_info(shmp, 0, method, ret_prompt); + +} + +int subscribe_bundle_plan(_state_data *shmp, char *sms, int method, char *ret_prompt) +{/*method=0/1, over SMS or USSD */ + int sms_len; + int i; + char bs_command[128]; + + u_long ret_value[10]; + char expire_date[64]; + char sms_msg[256]; + int menu_index=1; + //int cos_bundle_control=0; + + //cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); + + sms_len = strlen(sms); + + /* + if(sms_len <= 1) + { + return subscribe_bundle_plan_query_info(shmp, 0); + } + */ + /* + DebugMsg(debugmib.display.asciiOut, + "[%04d] %s, content: %s, method=%d\n", + shmp->process_info.portid, __FUNCTION__, sms, method); + */ + + if(sms_len > 0) + { + for(i=1; i 0 || ppsParam.ppsTables.bundlePlans[i].sms > 0) + continue; + + apply_code = menu_index ++; + if (ppsParam.ppsTables.bundlePlans[i].apply_code > 0) + { + apply_code = ppsParam.ppsTables.bundlePlans[i].apply_code; + } + if(atoi(sms) == apply_code) + { + subscribe_bundle_plan_subs_index(shmp, i, method, ret_prompt); + return 1; + } + } + else if (method == 2) + { + int apply_code ; + if (shmp->process_info.serviceKey == 7) + { + if(ppsParam.ppsTables.bundlePlans[i].mo_voice <= 0 && ppsParam.ppsTables.bundlePlans[i].sms <= 0) + continue; + } + else if (shmp->process_info.serviceKey == 6) + { + if(ppsParam.ppsTables.bundlePlans[i].mo_voice > 0 || ppsParam.ppsTables.bundlePlans[i].sms > 0) + continue; + } + + apply_code = menu_index ++; + if (ppsParam.ppsTables.bundlePlans[i].apply_code > 0) + { + apply_code = ppsParam.ppsTables.bundlePlans[i].apply_code; + } + if(atoi(sms) == apply_code) + { + subscribe_bundle_plan_subs_index(shmp, i, method, ret_prompt); + return 1; + } + } + } + } + } + + ocs_bundle_plan_query(shmp, sms, method, ret_prompt); + + return 0; + + { + if(GetAccountBundlePlanInfo(&shmp->caller_info, (long *)ret_value)) + { + AsciiTimeYMD(expire_date,ret_value[4]); + + if(ret_value[1]>0 || ret_value[3]>0) + sprintf(sms_msg, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY), + ret_value[0], + ret_value[1], + // ret_value[2],// disable MT voice + ret_value[3], + expire_date); + else + sprintf(sms_msg, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY_DATA), + ret_value[0], + expire_date); + + if(method) + { + if(ret_prompt != NULL) + strcpy(ret_prompt, sms_msg); + } + else + { + smppSendMOSM((char *)shmp->caller_info.number, (char *)shmp->called_info.number, + (u_char *)sms_msg, + strlen(sms_msg), + 0); + } + return 1; + + } + + //return subscribe_bundle_plan_query_info(shmp, 1); + } + + return subscribe_bundle_plan_query_info(shmp, 0, method, ret_prompt); + + return 1; +} +/*---------------------------------------------------------------*/ + + + +static int pps_smppOnDataRecv(BYTE linkNo, SMPP_MSG *pMsg, WORD dataLen) +{ /* no trafic control method applied */ + + + SMPP_MSG smpp_msg; + + switch(pMsg->message_type) + { + case 0x0B: /* Submit SM */ + break; + case 0x0C: /*Submit SM Resp. */ + if((logMsgFlag & 0x02) && debug_messages<=MAX_DEBUG_MESSAGES) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "Submit SM response received , link = %d", linkNo); + } + break; + case 0x0D: /*Submit Multi. */ + break; + case 0x0E: /*Submit Multi. Resp. */ + break; + case 0x0F: /*Deliver SM */ + + /*send deliver sm response */ + smpp_msg.message_type = 0x10; + smpp_msg.pdu.deliver_sm_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.deliver_sm_resp.head.sequence_number = + pMsg->pdu.deliver_sm.head.sequence_number; + smpp_msg.pdu.deliver_sm_resp.message_id = 0x00; + smpp_send(linkNo,&smpp_msg,dataLen); + + DecodeDeliverSM(pMsg); + + break; + case 0x10: /*Deliver SM Resp. */ + + break; + case 0x11: /*Data SM */ + break; + case 0x12: /*Data SM Resp. */ + break; + case 0x13: /*Query SM */ + break; + case 0x14: /*Query SM Resp. */ + break; + case 0x15: /*Cancel SM */ + break; + case 0x16: /*Cancel SM Resp. */ + break; + case 0x17: /*Replace SM */ + break; + case 0x18: /*Replace SM Resp. */ + break; + default: + break; + } + return 1; +} + +static int pps_smppOnLinkStateChange(BYTE linkNo, BYTE state) +{ + int i; + + for(i=0;i=2) + { + if(pps_get_smpp_link_type()) + smpp_status.linkNo[0] = smpp_registerLink(SMPP_CLIENT, + BIND_TRX, + (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, + TRANSACTION); + else + smpp_status.linkNo[0] = smpp_registerLink(SMPP_CLIENT, + BIND_TRX, + (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, + DATAGRAM); + if((logMsgFlag & 0x02)) + { + // DebugMsg(debugmib.display.asciiOut, + // "pps register smppLink TRx Client [%s], result=%02x", + // ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, + // smpp_status.linkNo[0]); + } + + if(!(smpp_status.linkNo[0] & 0x80)) + { + //alarm_code[0] = 3; + //alarm_code[1] = 1; + //ppsSendHeartBeating(); + return 0; + } + else + { + ppsSetupSMPPLink(0); + smpp_status.dir[0] = _SMPP_SEND; + } + } + if((smpp_status.linkNo[0] & 0x80) && !(smpp_status.link_state[0])) + { + ppsSetupSMPPLink(0); + } + + if(!(smpp_status.linkNo[1]&0x80) && strlen((char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number)>=2) + //||!(smpp_status.link_state[1])) + { + if(pps_get_smpp_link_type()) + smpp_status.linkNo[0] = smpp_registerLink(SMPP_CLIENT, + BIND_TRX, + (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, + TRANSACTION); + else + smpp_status.linkNo[1] = smpp_registerLink(SMPP_CLIENT, + BIND_TRX, + (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, + DATAGRAM); + if((logMsgFlag & 0x02)) + { + // DebugMsg(debugmib.display.asciiOut, + // "pps register smppLink TRx Client [%s], result=%02x", + // ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, + // smpp_status.linkNo[1]); + } + + if(!(smpp_status.linkNo[1] & 0x80)) + { + //alarm_code[0] = 3; + //alarm_code[1] = 2; + //ppsSendHeartBeating(); + return 0; + } + else + { + ppsSetupSMPPLink(1); + smpp_status.dir[1] = _SMPP_SEND; + } + + } + if((smpp_status.linkNo[1] & 0x80) && !(smpp_status.link_state[1])) + { + ppsSetupSMPPLink(1); + } + + return 1; +} + +void pps_resetupSMPPLink() +{ + int i; + + for(i=0;ihead ; + tail = ptr->tail ; + if(head != tail) + { + if(time(NULL)>(ptr->submitTime[head]+PROMPT_SM_DELAY_TIME)) + { + smpp_send((smpp_status.linkNo[i]&0x7f), + &ptr->sSM_msg[head], + 0); + ptr->head ++; + ptr->head %= MAX_SMPP_MSG; + } + } + } + } + return 1; +} + +int smppSendMOSMReal(SMPP_MSG *sm_msg) +{ + int i; + + if(sm_msg == NULL) return 0; + + for(i=0;i<2;i++) + { + if(smpp_status.link_state[0] == 1 && smpp_status.link_state[1] == 1) + { + if(smpp_link_selection%2==i) + { + smpp_send((smpp_status.linkNo[i]&0x7f), + sm_msg, + 0); + smpp_link_selection++; + break; + } + } + else + { + if(smpp_status.link_state[i] == 1) + { + smpp_send((smpp_status.linkNo[i]&0x7f), + sm_msg, + 0); + smpp_link_selection++; + break; + } + } + } + return 1; +} + +int smppSendMOSM(char *called, char *caller, u_char *msg, int msgLen,u_char dataCoding) +{ + static int smpp_sm_ref_id = 0; + + int msgLength,head,tail,i,totalPackets,lastPacketLen; + SMPP_MSG sm_msg; + smpp_send_buf *ptr; + + PutLogFunID("smppSendMOSM"); + + if(msgLen == 0) //empty sms is not sent + return 0; + + memset(&sm_msg,0,sizeof(SMPP_MSG)); + sm_msg.message_type = 0x0B; + sm_msg.optional_param_flag1 = 0x00; + sm_msg.optional_param_flag2 = 0x00; + +// strcpy(sm_msg.pdu.submit_sm.service_type, "USSD"); + memset(sm_msg.pdu.submit_sm.service_type,0,6); + sm_msg.pdu.submit_sm.source_addr_ton = 0x00; + //Unknown , 1=international, 2=National + sm_msg.pdu.submit_sm.source_addr_npi = 0x01; //ISDN + strcpy(sm_msg.pdu.submit_sm.source_addr, caller); + sm_msg.pdu.submit_sm.dest_addr_ton = 0x01; //National + sm_msg.pdu.submit_sm.dest_addr_npi = 0x01; //ISDN + strcpy(sm_msg.pdu.submit_sm.destination_addr, called); + sm_msg.pdu.submit_sm.esm_class = 0x00; + sm_msg.pdu.submit_sm.protocol_id = 0x00; + sm_msg.pdu.submit_sm.priority_flag = 0x03; + memset(sm_msg.pdu.submit_sm.schedule_delivery_time, 0,1); + memset(sm_msg.pdu.submit_sm.validity_period, 0,1); + sm_msg.pdu.submit_sm.registered_delivery = 0x00;//0x11; + sm_msg.pdu.submit_sm.replace_if_present_flag = 0x01; + sm_msg.pdu.submit_sm.data_coding = dataCoding; + sm_msg.pdu.submit_sm.sm_default_msg_id = 0x01; + + if(msgLen>140) + { + totalPackets = msgLen / 134; + lastPacketLen = msgLen % 134; + sm_msg.pdu.submit_sm.esm_class = 0x40; + } + else + { + totalPackets = 0; + lastPacketLen = msgLen; + } + + i = 0; + for(i=0;i 0) + { + sm_msg.pdu.submit_sm.short_message[0] = 0x05; + sm_msg.pdu.submit_sm.short_message[1] = 0x00; + sm_msg.pdu.submit_sm.short_message[2] = 0x03; + sm_msg.pdu.submit_sm.short_message[3] = smpp_sm_ref_id; + sm_msg.pdu.submit_sm.short_message[4] = totalPackets + 1; + sm_msg.pdu.submit_sm.short_message[5] = i + 1; + memcpy(&sm_msg.pdu.submit_sm.short_message[6], &msg[i*134], msgLength); + + sm_msg.pdu.submit_sm.short_message[msgLength] = 0; + } + /* + else + { + memcpy(sm_msg.pdu.submit_sm.short_message,&msg[i*140],msgLength); + sm_msg.pdu.submit_sm.short_message[msgLength] = 0; + } + */ + + if((logMsgFlag & 0x02)) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "[%s]Send account info. throught SMPP\r\n%s %s len:%d", + called,caller,sm_msg.pdu.submit_sm.short_message,msgLength); + } + + smppSendMOSMReal(&sm_msg); + } + + if(lastPacketLen>0) + { + if(totalPackets >= 1) + { + msgLength = lastPacketLen + 6; + + sm_msg.pdu.submit_sm.sm_length = msgLength; + + sm_msg.pdu.submit_sm.short_message[0] = 0x05; + sm_msg.pdu.submit_sm.short_message[1] = 0x00; + sm_msg.pdu.submit_sm.short_message[2] = 0x03; + sm_msg.pdu.submit_sm.short_message[3] = smpp_sm_ref_id; + sm_msg.pdu.submit_sm.short_message[4] = totalPackets + 1; + sm_msg.pdu.submit_sm.short_message[5] = i + 1; + memcpy(&sm_msg.pdu.submit_sm.short_message[6], &msg[i*134], msgLength); + } + else + { + msgLength = lastPacketLen ; + sm_msg.pdu.submit_sm.sm_length = msgLength; + + memcpy(&sm_msg.pdu.submit_sm.short_message, &msg[i*140], msgLength); + } + sm_msg.pdu.submit_sm.short_message[msgLength] = 0; + + if((logMsgFlag & 0x02) ) + { + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "[%s]Send account info. throught SMPP\r\n%s %s len:%d", + called,caller,sm_msg.pdu.submit_sm.short_message,msgLength); + } + smppSendMOSMReal(&sm_msg); + } + + smpp_sm_ref_id ++; + + return 1; /* no buffer msg , 2005-07-24 , lhb */ + ptr = &ppsSMPPmsgBuf.ppsSMPPsBufRecharge; + ptr = &ppsSMPPmsgBuf.ppsSMPPsBufInquiry; + + head = ptr->head; + tail = ptr->tail; + memcpy(&ptr->sSM_msg[tail], + &sm_msg, + sizeof(SMPP_MSG)); + ptr->submitTime[tail] = time(NULL); + tail ++; + + if(tail == head ) head++; + tail = tail %MAX_SMPP_MSG; + head = head %MAX_SMPP_MSG; + ptr->head = head; + ptr->tail = tail; + + if((logMsgFlag & 0x02) && debug_messages<=MAX_DEBUG_MESSAGES) + { + debug_messages ++; + DebugMsgDelimiter(); + DebugMsg(debugmib.display.asciiOut, + "[%s]Send account info. throught SMPP\n%s %s len:%d-%d", + called,caller,msg,strlen((char *)msg),msgLength); + } + return 1; +} + +int fillMoneyToContent(float balance,char *sms) +{ + char tmpbuf[MAX_SMS_LEN]={0}; + + sprintf(tmpbuf,"%s",ppsParam.serviceControl.currencyName); + + switch(ppsParam.ppsTables.promptResolution[0].currencyResolution) + { + case 0: + sprintf(sms,"%ld",(long)balance); + break; + case 1: + sprintf(sms,"%.1f",(float)balance/10); + break; + case 2: + default: + sprintf(sms,"%.2f",(float)balance/100); + break; + } + + if(ppsParam.ppsTables.promptResolution[0].currencySymbolPosition == 0) /* front */ + { + strcat(tmpbuf,sms); + strcpy(sms,tmpbuf); + } + else /* rear */ + { + strcat(sms,tmpbuf); + } + return strlen(sms); +} + +int fillMoneyToContentWithoutCurrency(float balance,char *sms) +{ + switch(ppsParam.ppsTables.promptResolution[0].currencyResolution) + { + case 0: + sprintf(sms,"%ld",(long)balance); + break; + case 1: + sprintf(sms,"%.1f",(float)balance/10.0); + break; + case 2: + default: + sprintf(sms,"%.2f",(float)balance/100.0); + break; + } + return strlen(sms); +} + +int fillDateToContent(char *expire_date,char *sms) +{ + switch(ppsParam.ppsTables.promptResolution[0].dataFormat) + { + case 0: /* YYYY-MM-DD */ + memcpy(sms,expire_date,4); + sms[4]='-'; + memcpy(&sms[5],&expire_date[4],2); + sms[7]='-'; + memcpy(&sms[8],&expire_date[6],2); + break; + case 1: /* DD-MM-YYYY */ + memcpy(&sms[0],&expire_date[6],2); + sms[2]='-'; + memcpy(&sms[3],&expire_date[4],2); + sms[5]='-'; + memcpy(&sms[6],expire_date,4); + break; + case 2: /* MM-DD-YYYY */ + memcpy(&sms[0],&expire_date[4],2); + sms[2]='-'; + memcpy(&sms[3],&expire_date[6],2); + sms[5]='-'; + memcpy(&sms[6],expire_date,4); + break; + } + sms[10]=0; + return 10; +} + +int fillMoneyAndDate( + long balance, char *expire_date, + int calltype0, + u_char flag, + u_char *smMsgBuf) /* flag = 0, normal, 1= low balance prompt */ +{ + char buf[128]={0}; + u_char daybuf[32]={0},bcd_buf[140]; + int instance=0,len,totalLen=0; + u_char dataCoding=0; + //int calltype = calltype0; + + instance = (flag & 0x7f)%MAX_LANGUAGE_TYPES; + dataCoding = ppsParam.serviceControl.languageSmEncodeType[instance]; + + memset(buf,0,128); + fillMoneyToContent(balance,buf); + + len = strlen(buf); + + if(dataCoding ==0) + { + strcat((char *)smMsgBuf, buf); + + } + else + { + len = smppEncodeASCtoUC2(buf,bcd_buf,len); + memcpy(&smMsgBuf[totalLen],bcd_buf,len); + } + memset(buf,0,128); + totalLen += len; +#ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ + return totalLen; +#endif + if(strlen((char *)getSmsSentenceNative(0,SMS_EXPIRED_ON)) || !(flag&0x80)) + { + sprintf(buf,","); + + len = strlen(buf); + + if(dataCoding ==0) + { + strcat((char *)smMsgBuf, buf); + + } + else + { + len = smppEncodeASCtoUC2(buf,bcd_buf,len); + memcpy(&smMsgBuf[totalLen],bcd_buf,len); + } + totalLen += len; + + sprintf(buf,"%s",getSmsSentenceNative(0,SMS_EXPIRED_ON)); + + len = strlen(buf); + memcpy(&smMsgBuf[totalLen],buf,len); + totalLen += len; + + len = fillDateToContent(expire_date, (char *)daybuf); + if(dataCoding ==0) + { + memcpy(&smMsgBuf[totalLen],daybuf,len); + } + else + { + len = smppEncodeASCtoUC2((char *)daybuf, bcd_buf, len); + memcpy(&smMsgBuf[totalLen],bcd_buf,len); + } + totalLen += len; + } + return totalLen; +} + +int smppSendAccountInfo(char *caller, char *called, + long balance, char *expire_date, + long promotion,char *promotionExpireDate, + int calltype0, + char *call_date, + char *msisdn, + u_char flag) /* flag = 0, normal, 1= low balance prompt */ +{ + + char smMsgBuf[MAX_SMS_LEN*8]={0},buf[MAX_SMS_LEN*2]={0}; + u_char daybuf[32]={0},bcd_buf[140]; + int len,totalLen;//instance=0, + u_char dataCoding=0; + int calltype = calltype0; + + //instance = (flag & 0x7f)%MAX_LANGUAGE_TYPES; + //dataCoding = ppsParam.ppsTables.smsSentence[instance].smEncodeType; + + memset(smMsgBuf,0,MAX_SMS_LEN*8); + + + /******************** balance **************************************/ + if((flag & 0x40) == 0x40) + sprintf(buf,"%s: %s",msisdn, getSmsSentenceNative(0,SMS_ACCOUNT_BALANCE)); + else + sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_BALANCE)); + len = strlen(buf); + + strcpy(smMsgBuf,buf); + totalLen = len; + + memset(buf,0,128); + len = fillMoneyAndDate(balance, expire_date, calltype0, flag, (u_char *)buf); + strcat(smMsgBuf,buf); + totalLen += len; + /******************** balance **************************************/ + + /******************** promotion **************************************/ + if(promotion > 0) + { + sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_PROMOTION)); + len = strlen(buf); + + strcat(smMsgBuf,buf); + totalLen += len; + + memset(buf,0,128); + len = fillMoneyAndDate(promotion, promotionExpireDate, calltype0, flag, (u_char *)buf); + strcat(smMsgBuf,buf); + totalLen += len; + } + /******************** promotion **************************************/ + + if(calltype>0 && strlen((char *)getSmsSentenceNative(0,SMS_LAST_CALL_ON)) + && strlen((char *)getSmsSentenceNative(0,SMS_LAST_RECEIVE_ON))) + { + if(calltype == 2) + sprintf(buf," %s ",getSmsSentenceNative(0,SMS_LAST_RECEIVE_ON)); + else + sprintf(buf," %s ",getSmsSentenceNative(0,SMS_LAST_CALL_ON)); + + len = strlen(buf); + + memcpy(&smMsgBuf[totalLen],buf,len); + totalLen += len; + + len = fillDateToContent(call_date, (char *)daybuf); + + if(dataCoding ==0) + { + strcat(smMsgBuf, (char *)daybuf); + + } + else + { + len = smppEncodeASCtoUC2((char *)daybuf,bcd_buf,len); + memcpy(&smMsgBuf[totalLen],bcd_buf,len); + } + totalLen += len; + + sprintf(buf," %s ",getSmsSentenceNative(0,SMS_AT)); + + len = strlen(buf); + + memcpy(&smMsgBuf[totalLen],buf,len); + totalLen += len; + + memcpy(&daybuf[0],&call_date[8],2); + daybuf[2]=':'; + memcpy(&daybuf[3],&call_date[10],2); + daybuf[5]=0; + + len = 5; + if(dataCoding ==0) + { + strcat(smMsgBuf, (char *)daybuf); + + } + else + { + len = smppEncodeASCtoUC2((char *)daybuf,bcd_buf,len); + memcpy(&smMsgBuf[totalLen],bcd_buf,len); + } + totalLen += len; + + switch(calltype) + { + case 2: + sprintf(buf," %s ",getSmsSentenceNative(0,SMS_FROM)); + break; + default: + sprintf(buf," %s ",getSmsSentenceNative(0,SMS_TO)); + break; + } + len = strlen(buf); + memcpy(&smMsgBuf[totalLen],buf,len); + totalLen += len; + + len = strlen(msisdn); + + //if(calltype == 2) /* mt call */ /* added by pierre for CLI */ + { + cliManipulationFunction(msisdn,caller); + len = strlen(msisdn); + } + + if(dataCoding ==0) + { + strcat(smMsgBuf,msisdn); + } + else + { + len = smppEncodeASCtoUC2(msisdn,bcd_buf,len); + memcpy(&smMsgBuf[totalLen],bcd_buf,len); + } + totalLen += len; + }//if(callType>0) + + if((flag & 0x80)) + { + sprintf(buf,",%s",getSmsSentenceNative(0,SMS_RECHARGE_ON)); + + len = strlen(buf); + memcpy(&smMsgBuf[totalLen],buf,len); + totalLen += len; + } +/* +DebugMsg(debugmib.display.asciiOut,"TotalLen: %03d-%03d,DCS:%d", + totalLen,strlen(smMsgBuf),dataCoding); +buf[0]=0; +for(len=0;len 254) totalLen = 254; + smppSendMOSM(caller, called, (u_char *)smMsgBuf, totalLen, dataCoding); + + return 1; + } + + + +int GetAccountPromptInfo(_account_info *caller_info,char *prompt_info) +{ + long balance, promotion; + char expire_date[64]={0},promotion_expire_date[64]={0}; + char buf[2*MAX_SMS_LEN]="",buf2[4*MAX_SMS_LEN]=""; + int len,totalLen, tmp_len=0; + + PutLogFunID("GetAccountPromptInfo"); + + memset(buf,0,MAX_SMS_LEN*2); + memset(buf2,0,MAX_SMS_LEN*4); + + AsciiTime(expire_date,GetExpiration(caller_info)); + AsciiTime(promotion_expire_date,GetPromotionExpiration(caller_info)); + balance = GetBalanceWithOutPromotion(caller_info->head,caller_info->tail); + promotion = GetPromotion(caller_info); + /******************** balance **************************************/ + sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_BALANCE)); + len = strlen(buf); + + strcpy(buf2,buf); + totalLen = len; + + memset(buf,0,MAX_SMS_LEN*2); + len = fillMoneyAndDate(balance,expire_date,0,0, (u_char *)buf); + strcat(buf2,buf); + totalLen += len; + + tmp_len = totalLen; + /******************** balance **************************************/ + + /******************** promotion **************************************/ + if(promotion > 0) + { + memset(buf,0,MAX_SMS_LEN*2); + sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_PROMOTION)); + len = strlen(buf); + + strcat(buf2,buf); + totalLen += len; + + memset(buf,0,MAX_SMS_LEN*2); + len = fillMoneyAndDate(promotion,promotion_expire_date,0,0, (u_char *)buf); + strcat(buf2,buf); + totalLen += len; + } + memcpy(prompt_info,buf2,240); + prompt_info[240]=0; + /******************** promotion **************************************/ + return tmp_len; +} + + +int smppSendActivicationInfo(_account_info *caller_info, char *called) +{ + char account_info[256], msg_send[560], notify_sms[256]; + + GetAccountPromptInfo(caller_info, account_info); + + sprintf(notify_sms,"%s", getSmsSentenceNative(0,SMS_ACTIVATION_NOTIFY)); + + if(strlen(notify_sms)) + sprintf(msg_send, "%s %s, %s", notify_sms, caller_info->number, account_info); + else + sprintf(msg_send, "%s",account_info); + + smppSendMOSM((char *)caller_info->number, called, (u_char *)msg_send, strlen(msg_send), 0); + return 1; +} + +int pps_smpp_state(u_short portid) +{ + int retval = 0; + _state_data *shmp = (_state_data *) smshm_ptr->state_data; + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + + if(portid>=MAX_FSM_PROCESS) + { + return -1; + } + + shmp += (portid); + shmp->process_info.duration ++; + + if(shmp->process_info.funnel ++ > ONE_MINUTE_STATE_TIME) + { + if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut, + "\n\33[31m portid: %d %s timeout\33[0m", portid, __FUNCTION__); + } + return -1; + } + + switch(shmp->process_info.sub_state) + { + case S_SMPP_IDLE: + retval = -1; + break; + case S_SMPP_REST_QUERY: + retval = pps_rest_query_process(portid); + break; + case S_SMPP_REST_TOPUP: + retval = pps_rest_topup_process(portid); + if(retval == -1) + { + /* + char failedNote[]={"Refill failed, check PIN and try again."}; + smppSendMOSM((char *)shmp->caller_info.number, + (char *)shmp->origin_info.number, + (u_char *)failedNote, + strlen(failedNote), + 0); + */ + } + break; + case S_SMPP_REST_TRANSFER: + retval = pps_rest_transfer_process(portid); + break; + default: + retval = -1; + break; + } + + return retval; +} diff --git a/mss/pps/src/main/tariffApplication.c b/mss/pps/src/main/tariffApplication.c new file mode 100644 index 0000000..d905365 --- /dev/null +++ b/mss/pps/src/main/tariffApplication.c @@ -0,0 +1,624 @@ + +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + +#include "../include/plat_inc.h" + +#include "../include/ppsMibTable.h" +#include "../include/mfunc.h" + +extern PPSParamStruct ppsParam; +extern struct timeval tvnow; +extern _ram_data *ramshm_ptr; + +extern void DebugMsg(void *ptr, const char *fmt, ...); +extern u_short debug_messages; +extern int logMsgFlag; + +enum PROMOTION_USED_SERVICE{ + PROMOTION_USED_CALL, + PROMOTION_USED_SMS, + PROMOTION_USED_GPRS, +}; + +enum PROMOTION_USED_RANGE{ + MO_LOCAL, + MO_NDD, + MO_IDD, +}; + + +enum _TIER_RATING_PLAN{ + BILL_TIER_PLAN_A = 0, + BILL_TIER_PLAN_B, + BILL_TIER_PLAN_C, +}; + + +BOOL isPromotionCanBeUsedForRoDebit(_account_info *shmp) +{ + if(shmp == NULL) return 0; + COSTable *cosTableItem; + int cos_id=0; + + cos_id = GetAccountCosID(shmp)%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + + return cosTableItem->tariff[0].promotionUsedForRoDebit; +} + +BOOL isPromotionCanBeUsedAtThisPoint(_state_data *shmp) +{ + COSTable *cosTableItem; + int cos_id=0; + promotion_plan_control *pPromotionControl; + u8 serviceType,call_type; + + cos_id = GetAccountCosID(&shmp->caller_info)%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pPromotionControl = &cosTableItem->tariff[0].promotionUseControl; + + serviceType = shmp->context_info.callType; + switch(serviceType) + { + case CT_MO_CALL: + call_type = shmp->process_info.tariff.call_type; + switch(call_type) + { + case MO_LOCAL: + return pPromotionControl->usedForCall.LOCAL; + break; + case MO_NDD: + return pPromotionControl->usedForCall.NDD; + break; + case MO_IDD: + return pPromotionControl->usedForCall.IDD; + break; + } + break; + case CT_MO_SM: + call_type = shmp->process_info.smsTariff.call_type; + switch(call_type) + { + case MO_LOCAL: + return pPromotionControl->usedForSMS.LOCAL; + break; + case MO_NDD: + return pPromotionControl->usedForSMS.NDD; + break; + case MO_IDD: + return pPromotionControl->usedForSMS.IDD; + break; + } + break; + case CT_GPRS: + return pPromotionControl->usedForGPRS.allowed; + break; + case CT_RO_DEBIT: + return cosTableItem->tariff[0].promotionUsedForRoDebit; + break; + default: + return TRUE; + break; + } + return TRUE; +} + +BOOL isPromotionCanBeTransfered(_account_info *accountInfo) +{ + COSTable *cosTableItem; + int cos_id=0; + promotion_plan_control *pPromotionControl; + + cos_id = GetAccountCosID(accountInfo)%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pPromotionControl = &cosTableItem->tariff[0].promotionUseControl; + + return pPromotionControl->transfer.transfer; +} + +BOOL isPromotionFirstTransfered(_account_info *accountInfo) +{ + COSTable *cosTableItem; + int cos_id=0; + promotion_plan_control *pPromotionControl; + + cos_id = GetAccountCosID(accountInfo)%MaxCosTableItem; + cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; + pPromotionControl = &cosTableItem->tariff[0].promotionUseControl; + + return pPromotionControl->transfer.transferPrioriy; +} + + +double GetBalanceWithPromotionControl(_state_data *stateProc,_account_info *ptr) +{ + _prepaid_data *shmp=&ramshm_ptr->prepaid_data; + double balance=0; + + PutLogFunID("GetBalanceWithPromotionControl"); + + if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) + { + if(shmp->prepaid_info[ptr->head][ptr->tail].balance>=ppsParam.serviceControl.maxBalance)// balance overflow prevetion + shmp->prepaid_info[ptr->head][ptr->tail].status = T_SUSPEND; + if(shmp->prepaid_info[ptr->head][ptr->tail].msisdn[MAX_MSISDN_BLEN-1]<=2)// msisdn length field + return 0; + if(GetExpiration(ptr) > tvnow.tv_sec)// check validity date + { + balance = shmp->prepaid_info[ptr->head][ptr->tail].balance; + } + else + pps_print_error(stateProc->process_info.logMsisdn,"[%05d]%s balance validity expired",stateProc->process_info.portid,ptr->number); + if(isPromotionCanBeUsedAtThisPoint(stateProc)) + { + if(GetPromotionExpiration(ptr)> tvnow.tv_sec) + balance += shmp->prepaid_info[ptr->head][ptr->tail].promo_balance ; + else + ; //pps_print_error(stateProc->process_info.logMsisdn,"[%05d]%s promotion validity expired",stateProc->process_info.portid,ptr->number); + } + return balance; + } + return 0; +} + +static void supplementaryServiceChangeBasciFee(_state_data *shmp,_bill_tariff *ptar) +{ + if(shmp->context_info.callType == CT_MF_CALL) + { + if(shmp->process_info.poolCall) + { + ChangeTariffToPoolCallTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"Pool call!"); + } + #endif + + } + else if(shmp->process_info.cugCall) + { + if(shmp->process_info.favoriteCall) + { + ChangeTariffToCfCugFavTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"CF + CUG + Favorite call!"); + } + #endif + + } + else + { + ChangeTariffToCfCugTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"CF + CUG call!"); + } + #endif + + } + } + else if(shmp->process_info.favoriteCall) + { + ChangeTariffToCfFavTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"CF + Favorite call!"); + } + #endif + + } + else + { + ChangeTariffToCfTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"CF call!"); + } + #endif + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d]CF service,replace basic fee with common fee", + shmp->process_info.portid); + }//MF CALL + else if(shmp->context_info.callType == CT_MO_CALL) + { + if(shmp->process_info.poolCall) + { + ChangeTariffToPoolCallTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"Pool call!"); + } + #endif + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Pool call service,replace basic fee with common fee", + shmp->process_info.portid); + } + else if(shmp->process_info.cugCall) + { + if(shmp->process_info.favoriteCall) + { + ChangeTariffToCugFavTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"CUG + Favorite call!"); + } + #endif + } + else + { + ChangeTariffToCugTariff(shmp,ptar); + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"CUG call!"); + } + #endif + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d]CUG service,replace basic fee with common fee", + shmp->process_info.portid); + } + else if(shmp->process_info.favoriteCall) + { + if(shmp->context_info.callType != CT_MT_CALL) + { + ChangeTariffToFavoriteCallTariff(shmp,ptar);// + } + #if DEBUG + if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn) + { + DebugMsg(debugmib.display.asciiOut,"Favorite call!"); + } + #endif + pps_print_event(shmp->process_info.logMsisdn,"[%05d]Favorite call service,replace basic fee with common fee", + shmp->process_info.portid); + } + } + + + if(shmp->process_info.roamingFlag == 1) + { + if(shmp->context_info.callType == CT_MT_CALL) + { + ChangeTariffToMTRoamingTariff(shmp,ptar); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]MT Roaming service,change basic fee with roaming fee,long fee", + shmp->process_info.portid); + } + else + { + ChangeTariffToMORoamingTariff(shmp,ptar); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]MO Roaming service,replace basic fee with common fee", + shmp->process_info.portid); + } + } +} + +static int getTierIndex(_state_data *shmp,_bill_tariff *ptar,u32 talkTime) +{ + TIER_RATING *pTierRating; + u8 tierNum,tierIndex; + u32 tierAUnits,tierBUnits,tierCUnits; + u32 duration,duration_units,tierCycle; + int unit_time=60; + + + pTierRating = &ptar->tierRating; + tierNum = pTierRating->tierNumber; + if ((unit_time = ptar->unit_time) <= 0) + unit_time = 60; + + if(talkTime >= ptar->free_time) + duration = talkTime - ptar->free_time; + else + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]get tier index error,free time,no need to charge,use tier 0", + shmp->process_info.portid); + return BILL_TIER_PLAN_A; + } + + duration_units = duration / unit_time; + switch(tierNum) + { + case BILL_TIERS_ONE: + tierIndex = BILL_TIER_PLAN_A; + break; + case BILL_TIERS_TWO: + tierAUnits = pTierRating->rating[BILL_TIER_PLAN_A].units; + tierBUnits = pTierRating->rating[BILL_TIER_PLAN_B].units; + if(tierAUnits == 0 || tierBUnits == 0) + { + tierIndex = BILL_TIER_PLAN_A; + pps_print_error(shmp->process_info.logMsisdn,"[%05d]get tier index,Tier level is 1,but the units of tier 0/1 is 0,only use tier 0", + shmp->process_info.portid); + } + else + { + tierCycle = duration_units%(tierAUnits+tierBUnits); + if(tierCycle >= tierAUnits) + tierIndex = BILL_TIER_PLAN_B; + else + tierIndex = BILL_TIER_PLAN_A; + } + break; + case BILL_TIERS_TRREE: + tierAUnits = pTierRating->rating[BILL_TIER_PLAN_A].units; + tierBUnits = pTierRating->rating[BILL_TIER_PLAN_B].units; + tierCUnits = pTierRating->rating[BILL_TIER_PLAN_C].units; + if(tierAUnits == 0 || tierBUnits == 0 ||tierCUnits == 0) + { + tierIndex = BILL_TIER_PLAN_A; + pps_print_error(shmp->process_info.logMsisdn,"[%05d]get tier index,Tier level is 2,but the units of tier 0/1/2 is 0,only use tier 0", + shmp->process_info.portid); + } + else + { + tierCycle = duration_units%(tierAUnits+tierBUnits+tierCUnits); + if(tierCycle >= (tierBUnits + tierAUnits)) + tierIndex = BILL_TIER_PLAN_C; + else if(tierCycle >= tierAUnits) + tierIndex = BILL_TIER_PLAN_B; + else + tierIndex = BILL_TIER_PLAN_A; + } + break; + default: + tierIndex = BILL_TIER_PLAN_A; + break; + } + return tierIndex; +} + +u_char getCurrentTier(_state_data *shmp,_bill_tariff *ptar) +{ + u32 talkTime; + + talkTime = shmp->process_info.duration/CYCLE_STATE_INTERVAL; + return getTierIndex(shmp,ptar,talkTime); +} + +float getCurrentFee(_state_data *shmp) +{ + u_char tier; + TIER_RATING *pTierRating; + _bill_tariff *ptar; + + ptar = &shmp->process_info.tariff; + tier = getCurrentTier(shmp,ptar); + supplementaryServiceChangeBasciFee(shmp,ptar); + pTierRating = &ptar->tierRating; + return pTierRating->rating[tier].base_fee + pTierRating->rating[tier].long_distance_fee; +} + +float BillingFormula(_state_data *shmp,_bill_tariff *ptar,int startTime) +{ + float num=0; + u8 index; + TIER_RATING *pTierRating; + + PutLogFunID("BillingFormula"); + + pTierRating = &ptar->tierRating; + + index = getTierIndex(shmp,ptar,startTime); + supplementaryServiceChangeBasciFee(shmp,ptar); + num = pTierRating->rating[index].base_fee + pTierRating->rating[index].long_distance_fee ; + pps_print_event(shmp->process_info.logMsisdn,"[%05d]current tier is %d,basic fee:%0.4f,long fee:%0.4f", + shmp->process_info.portid,index,pTierRating->rating[index].base_fee,pTierRating->rating[index].long_distance_fee); + return num; +} + +float TimeToCharge(_state_data *shmp,_bill_tariff *ptar, int duration,int begin_time, int init_bill) +{ + int i=0,j=0; + int discount=0; + float charge=0; + int itimes=0, unit_time=60, curr_time=0,startTime; + int truncationFlag=0; + + PutLogFunID("TimeToCharge"); + + if(duration<=0) return (charge = 0); + if ((unit_time = ptar->unit_time) <= 0) + unit_time = 60; + itimes = (ceil)((double) duration / unit_time); + startTime = shmp->process_info.duration/CYCLE_STATE_INTERVAL; + + if(ppsParam.serviceControl.truncation_flag) + { + charge = BillingFormula(shmp,ptar,startTime); + if(charge == floorf(charge)) + truncationFlag = 1; + } + charge = 0; + for (i=1; i<=itimes; i++) + { + curr_time = begin_time + unit_time * (i - 1); + if(OCS_with_external_CRM())//query tariff from CRM database + discount = shmp->process_info.rest_if.tariff_discount; + else + discount = GetDiscount(curr_time,ptar->discountID); + if (i <= ptar->mini_unit && (!init_bill)) + { + for(j=0;j < ptar->mini_unit;j++) + { + charge += BillingFormula(shmp,ptar,startTime); + startTime += unit_time; + } + i = ptar->mini_unit; + } + else + { + charge += BillingFormula(shmp,ptar,startTime); + startTime += unit_time; + } + } + + if(!init_bill) + { + charge = (charge + ptar->adjustment)*discount/100; + } + else + { + charge = (charge * discount)/100; + } + if(truncationFlag ) + return (floorf(charge)); + else + return (charge); +} + +float caculateMiniCharge(_state_data *shmp,_bill_tariff *ptar) +{ + float charge=0; + int unit_time=60, curr_time=0,startTime,j; + float discount; + + charge = 0; + curr_time = tvnow.tv_sec; + if ((unit_time = ptar->unit_time) <= 0) + unit_time = 60; + startTime = shmp->process_info.duration/CYCLE_STATE_INTERVAL; + discount = GetDiscount(curr_time,ptar->discountID)/100; + for(j=0;j < ptar->mini_unit;j++) + { + charge += BillingFormula(shmp,ptar,startTime); + startTime += unit_time; + } + return charge*discount; +} + +static int caculateLeftTime(_state_data *shmp,float balance,_bill_tariff *ptar) +{ + float charge=0; + int unit_time=60, curr_time=0,startTime; + float discount; + + charge = 0; + curr_time = tvnow.tv_sec; + if ((unit_time = ptar->unit_time) <= 0) + unit_time = 60; + startTime = shmp->process_info.duration/CYCLE_STATE_INTERVAL; + discount = GetDiscount(curr_time,ptar->discountID)/100; + if(discount <= 0) + return MAX_CALL_DURATION; + charge += BillingFormula(shmp,ptar,startTime); + while((charge*discount) <= balance) + { + startTime += unit_time; + curr_time += unit_time; + charge += BillingFormula(shmp,ptar,startTime); + } + return curr_time - tvnow.tv_sec; +} + +int preLeftTime(_state_data *shmp,float balance,_bill_tariff *ptar) +{ + TIER_RATING *pTierRating; + TIER_INFO *pTierInfo; + u8 tierNum; + u32 tierAUnits,tierBUnits,tierCUnits,S_UNITS_CYCLE; + float tierA_V_perUnit,tierB_V_perUnit,tierC_V_perUnit,units; + long double S_V_CYLCE; + int unit_time=60,cycleTimes; + float maxDuration; + float discount; + + pTierRating = &ptar->tierRating; + tierNum = pTierRating->tierNumber; + if ((unit_time = ptar->unit_time) <= 0) + unit_time = 60; + + discount = GetDiscount(tvnow.tv_sec,ptar->discountID)*1.0/100; + if(discount <= 0.0001) + return MAX_CALL_DURATION; + + switch(tierNum) + { + case BILL_TIERS_TWO: + pTierInfo = &pTierRating->rating[BILL_TIER_PLAN_A]; + tierA_V_perUnit = pTierInfo->base_fee + pTierInfo->long_distance_fee; + tierAUnits = pTierInfo->units; + pTierInfo = &pTierRating->rating[BILL_TIER_PLAN_B]; + tierB_V_perUnit = pTierInfo->base_fee + pTierInfo->long_distance_fee; + tierBUnits = pTierInfo->units; + + S_V_CYLCE = tierA_V_perUnit*tierAUnits + tierB_V_perUnit*tierBUnits; + if( S_V_CYLCE <= 0) + return MAX_CALL_DURATION; + if(tierAUnits == 0 || tierBUnits == 0) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Pre time,Tier level is 1,but the units of tier 0/1 is 0,only use tier 0", + shmp->process_info.portid); + break; + } + S_UNITS_CYCLE = tierAUnits + tierBUnits; + cycleTimes = balance/(discount*S_V_CYLCE); + + maxDuration = cycleTimes*S_UNITS_CYCLE*unit_time; + if(maxDuration < MAX_CALL_DURATION) + { + maxDuration = caculateLeftTime(shmp,balance,ptar); + } + return maxDuration; + break; + case BILL_TIERS_TRREE: + pTierInfo = &pTierRating->rating[BILL_TIER_PLAN_A]; + tierA_V_perUnit = pTierInfo->base_fee + pTierInfo->long_distance_fee; + tierAUnits = pTierInfo->units; + pTierInfo = &pTierRating->rating[BILL_TIER_PLAN_B]; + tierB_V_perUnit = pTierInfo->base_fee + pTierInfo->long_distance_fee; + tierBUnits = pTierInfo->units; + pTierInfo = &pTierRating->rating[BILL_TIER_PLAN_C]; + tierC_V_perUnit = pTierInfo->base_fee + pTierInfo->long_distance_fee; + tierCUnits = pTierInfo->units; + + S_V_CYLCE = tierA_V_perUnit*tierAUnits + tierB_V_perUnit*tierBUnits + tierC_V_perUnit*tierCUnits; + if( S_V_CYLCE <= 0) + return MAX_CALL_DURATION; + if(tierAUnits == 0 || tierBUnits == 0 || tierCUnits == 0 ) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Pre time,Tier level is 2,but the units of tier 0/1/2 is 0,only use tier 0", + shmp->process_info.portid); + break; + } + S_UNITS_CYCLE = tierAUnits + tierBUnits + tierCUnits; + cycleTimes = balance/(discount*S_V_CYLCE); + + maxDuration = cycleTimes*S_UNITS_CYCLE*unit_time; + if(maxDuration < MAX_CALL_DURATION) + { + maxDuration = caculateLeftTime(shmp,balance,ptar); + } + return maxDuration; + break; + } + + pTierInfo = &pTierRating->rating[BILL_TIER_PLAN_A]; + tierA_V_perUnit = pTierInfo->base_fee + pTierInfo->long_distance_fee; + + if( tierA_V_perUnit <= 0) + return MAX_CALL_DURATION; + + units = (floorf)(balance/(discount*tierA_V_perUnit)); + maxDuration = units*unit_time; + + return maxDuration; +} + + + diff --git a/mss/pps/src/main/vas.c b/mss/pps/src/main/vas.c new file mode 100644 index 0000000..0135e44 --- /dev/null +++ b/mss/pps/src/main/vas.c @@ -0,0 +1,1080 @@ +#include "../include/includes.h" +#include "../include/ppsm.h" +#include "../include/ramdata.h" +#include "../include/ppsinf.h" +#include "../include/message.h" +#include "../include/iofunc.h" +#include "../include/version.h" +#include "../include/pps_public.h" +#include "../include/cdrme.h" +#include "../include/param.h" + + +#include "../include/gprs.h" +#include "../include/plat_inc.h" + + +#define VAS_PREAUTHS_PER_TIME 5 + + +#define VAS_EMAIL_DOT '@' + +#define pps_set_vas_state(val) do { \ + vasProc->state = val; \ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \ +} while(0) + + +extern _state_machine *smshm_ptr; +extern _tariff_private *blf_shmp; +extern struct timeval tvnow; +extern _pps_report pps_report; +extern int csta_now_instance,csta_old_instance; + +extern float GetSMSTariff(_state_data *shmp,u_char tariff_id); +extern int GetMTTariffIDWithFreeServiceControl(_account_info *ptr); +extern RADIUS_ATTRIBUTE_NAS_IP_ADDRESS *getNASIP(WORD pid,const RADIUS_ACCESS_REQUEST *accessRequest); +extern int sendRadiusAccessAccept(u_short portid,BOOL volumeFlag,BOOL durationFlag); +extern int sendRadiusAccessReject(u_short portid,u_char *reason); + +extern int CutUnknownPrefix(char *number); + +typedef enum _VAS_CMD{ + VAS_NULL = 0, + VAS_SMS_AUTH, + VAS_SMS_ACCOUNT, + VAS_MMS_AUTH, + VAS_MMS_SEND_CHARGING, + VAS_MMS_RETRIEVE_ACCOUNTING, + VAS_EMAIL_AUTH, + VAS_EMAIL_CHARGING +}VAS_CMD; + +enum{ + VAS_CALLED_FORMAT_ERROR, + VAS_CALLED_PHONENUMBER, + VAS_CALLED_EMAIL, +}; + +static int vasChargeNow(_state_data *shmp,float fee,u_char *peerAddr); +static int checkVasNumber(u_char *number); +static void SendVasCDR(_account_info *userInfo,_state_data *shmp,u_char *peerAddr); + +static int getVasMsgType(WORD pid,RADIUS_ACCESS_REQUEST *accessRequest) +{ + if(accessRequest->pre_auth_type.flag != 0) + { + return accessRequest->pre_auth_type.pre_auth_type.value; + } + return -1; +} + +static int getVasCalledNumber(WORD pid,RADIUS_ACCESS_REQUEST *accessRequest) +{ + if(accessRequest->count_id_size.flag != 0) + { + if(accessRequest->count_id_size.msg_count.flag != 0) + return accessRequest->count_id_size.msg_count.msg_count.value; + } + return -1; +} + +static int getVasMsgID(WORD pid,RADIUS_ACCESS_REQUEST *accessRequest) +{ + if(accessRequest->count_id_size.flag != 0) + { + if(accessRequest->count_id_size.msg_id.flag != 0) + return accessRequest->count_id_size.msg_id.msg_id.value; + } + return -1; +} + +static DWORD getVasVolume(WORD pid,RADIUS_ACCESS_REQUEST *accessRequest) +{ + if(accessRequest->count_id_size.flag != 0) + { + if(accessRequest->count_id_size.size.flag != 0) + return accessRequest->count_id_size.size.size.value; + } + return 0; +} + +static VAS_CMD getVasCmd(WORD pid,RADIUS_ACCESS_REQUEST *access_request) +{ + int msgType; + + msgType = getVasMsgType(pid,access_request); + switch(msgType) + { + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_SMS: + pps_print_event(0,"SEND SMS PREAUTH"); + return VAS_SMS_AUTH; + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_ACCOUNT_SMS: + pps_print_event(0,"SEND SMS ACCOUNTING"); + return VAS_SMS_ACCOUNT; + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_MMS: + pps_print_event(0,"SEND MMS AUTH"); + return VAS_MMS_AUTH; + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_CHARGE_MMS_SEND: + pps_print_event(0,"SEND MMS CHARGING"); + return VAS_MMS_SEND_CHARGING; + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_ACCOUNT_MMS_RETRIEVE: + pps_print_event(0,"RETRIEVE MMS ACCOUNTING"); + return VAS_MMS_RETRIEVE_ACCOUNTING; + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_MMSE: + pps_print_event(0,"SEND MMSEMAIL AUTH"); + return VAS_EMAIL_AUTH; + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_CHARGE_MMSE: + pps_print_event(0,"SEND MMSEMAIL CHARGING"); + return VAS_EMAIL_CHARGING; + break; + default: + pps_print_error(0,"Unsupported VAS message type"); + return VAS_NULL; + break; + } + return VAS_NULL; +} + +static RADIUS_ATTRIBUTE_CALLED_STATION_ID *getCalledList(WORD pid,RADIUS_ACCESS_REQUEST *access_request) +{ +// int calledNum; + + if(access_request->called_station_id.option != 1) + { + pps_print_error(0,"No called station id"); + return NULL; + } + return &access_request->called_station_id; +} + + +BOOL isVas(WORD pid,RADIUS_ACCESS_REQUEST *access_request) +{ + int msgType; + + msgType = getVasMsgType(pid,access_request); + switch(msgType) + { + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_SMS: + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_ACCOUNT_SMS: + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_MMS: + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_CHARGE_MMS_SEND: + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_ACCOUNT_MMS_RETRIEVE: + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_MMSE: + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_CHARGE_MMSE: + return TRUE; + break; + default: + return FALSE; + break; + } + return FALSE; +} + +static int allocate_VAS_PORT(WORD pid,u_char *msisdn) +{ + int vas_port,callerLen; + _state_data *shmp; + + callerLen = strlen((char *)msisdn); + if(callerLen > MAX_ASCII_NUMBER_LEN) + { + pps_print_error(0,"calling station id is too long:%d",callerLen); + return -1; + } + + vas_port = AssignProcID(0); + if(vas_port < 0) + { + pps_print_error(0,"System busy ,no idle port"); + return -2; + } + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += vas_port; + shmp->context_info.mtype = VAS_O_OPEN; + shmp->context_info.new_flag = YES; + if(msisdn[0] == '+') + strcpy((char *)shmp->caller_info.number, (char *)msisdn+1); + else + strcpy((char *)shmp->caller_info.number, (char *)msisdn); + shmp->process_info.ppsService.gprs_process.radiusPid = pid; + shmp->process_info.ppsService.gprs_process.qid = INIT_QID; + if(logMsgFlag & 0x08) + { + if(strstr((char *)shmp->caller_info.number, logMsisdn)) + shmp->process_info.logMsisdn = 0x01; + } + return vas_port; +} + +int vas_process_access_request(WORD pid,RADIUS_ACCESS_REQUEST *access_request) +{ + RADIUS_TLV_TS *csi; + u_char msisdn[RADIUS_MAX_LEN_OF_ATTR]; + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS *nasAddr; + int ppsPort=-1; + RADIUS_ATTRIBUTE_CALLED_STATION_ID *calledList; + VAS_CMD vasCmd; + int rst; + u_char action[64]; + + vasCmd = getVasCmd(pid,access_request); + if(vasCmd == VAS_NULL) + return -1; + nasAddr = getNASIP(pid,access_request); + if(nasAddr == NULL) + { + return -1; + } + + csi = &access_request->calling_station_id.calling_station_id; + if(access_request->calling_station_id.flag != 0) + { + memset(msisdn,0,RADIUS_MAX_LEN_OF_ATTR); + memcpy(msisdn,&csi->value[0],csi->length%RADIUS_MAX_LEN_OF_ATTR); + } + else + { + pps_print_error(0,"No calling station id"); + return -1; + } + + calledList = getCalledList(pid,access_request); + if(calledList == NULL) + return -1; + + switch(vasCmd) + { + case VAS_NULL: + break; + case VAS_SMS_AUTH: + sprintf((char *)action, "SMS AUTH"); + rst = checkVasNumber(msisdn); + if(rst != VAS_CALLED_PHONENUMBER) + { + pps_print_error(0,"%s fail,caller:%s is not a phone number",action,msisdn); + return -1; + } + break; + case VAS_SMS_ACCOUNT: + sprintf((char *)action, "SMS ACCOUNTING"); + rst = checkVasNumber(msisdn); + if(rst != VAS_CALLED_PHONENUMBER) + { + pps_print_error(0,"%s fail,caller:%s is not a phone number",action,msisdn); + return -1; + } + break; + case VAS_MMS_AUTH: + sprintf((char *)action, "MMS AUTH"); + rst = checkVasNumber(msisdn); + if(rst != VAS_CALLED_PHONENUMBER) + { + pps_print_error(0,"%s fail,caller:%s is not a phone number",action,msisdn); + return -1; + } + break; + case VAS_MMS_SEND_CHARGING: + sprintf((char *)action, "MMS CHARGING"); + rst = checkVasNumber(msisdn); + if(rst != VAS_CALLED_PHONENUMBER) + { + pps_print_error(0,"%s fail,caller:%s is not a phone number/email address",action,msisdn); + return -1; + } + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + sprintf((char *)action, "SMS RETRIEVE ACCOUNTING"); + break; + case VAS_EMAIL_AUTH: + sprintf((char *)action, "EMAIL AUTH"); + break; + case VAS_EMAIL_CHARGING: + sprintf((char *)action, "EMAIL CHARGING"); + break; + } + pps_print_event(0,"Incoming value added service,caller:%s,%s at %s",msisdn,action,__FUNCTION__); + switch(vasCmd) + { + case VAS_MMS_RETRIEVE_ACCOUNTING: + case VAS_EMAIL_AUTH: + case VAS_EMAIL_CHARGING: + //memset(msisdn,0,RADIUS_MAX_LEN_OF_ATTR); + break; + default: + break; + } + + ppsPort = allocate_VAS_PORT(pid,msisdn); + + if(ppsPort >= 0) + { + _state_data *shmp; + _gprs_process *vasProc; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += ppsPort; + shmp->process_info.portid = ppsPort; + vasProc = &shmp->process_info.ppsService.gprs_process; + vasProc->gsnIP = nasAddr->nas_ip_addr.value; + vasProc->radiusPid = pid; + vasProc->radiusCommand = vasCmd; + vasProc->calledList = calledList; + vasProc->calculateCount = 0; + + return ppsPort; + } + else + pps_print_error(0,"%s fail,allocate process port fail",action); + return -1; +} + + +static float GetMMSTariff(_state_data *shmp,u_char *calledNumber,u_char tariffid,u_char phoneOrEmail) +{ + int i,flag=0,len=0,maxlen=0,index=0; + float sms_fee = 0; + int discount=100; + VAS_MMS_TARIFF *senderTariff; + u_char bill_no[RADIUS_TS_VALUE_LEN]; + + + strcpy((char *)bill_no, (char *)calledNumber); + + for(i=2;ivas_tariff[tariffid].vasMmsSendTariff[i]; + if(senderTariff->mmsType != phoneOrEmail) + continue; + len = strlen((char *)senderTariff->prefix); + if(len == 0) + continue; + if(!strncasecmp((char *)bill_no, (char *)senderTariff->prefix, len)) + if(len>maxlen) + { + maxlen = len; + flag = 1; + index = i; + } + } + + if(flag == 0) + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]can't find suitable prefix for %s in tariff:%d ,at %s,use default", + shmp->process_info.portid,bill_no,tariffid,__FUNCTION__); + if(phoneOrEmail == VAS_CALLED_PHONENUMBER) + index = 0; + else /* VAS_CALLED_EMAIL*/ + index = 1; + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d]prefix %s, tariff is is :%d ,index is:%d at %s", + shmp->process_info.portid,bill_no,tariffid,index,__FUNCTION__); + senderTariff = &blf_shmp->vas_tariff[tariffid].vasMmsSendTariff[index]; + + sms_fee = senderTariff->chargeFee; + discount = GetDiscount(tvnow.tv_sec,senderTariff->discountID); + + sms_fee = sms_fee * discount /100; + return sms_fee; +} + + + +static float getVasMMSSenderTariffFee(_state_data *shmp,u_char *calledNumber,int tariffid) +{ + u_short portid; + _gprs_process *vasProc; + u_char *pEmailDot; + + vasProc = &shmp->process_info.ppsService.gprs_process; + portid = shmp->process_info.portid; + + switch(vasProc->calledType) + { + case VAS_CALLED_PHONENUMBER: + CutUnknownPrefix((char *)calledNumber); + return GetMMSTariff(shmp,calledNumber,tariffid,VAS_CALLED_PHONENUMBER); + break; + case VAS_CALLED_EMAIL: + pEmailDot = (u_char *)strchr((char *)calledNumber,VAS_EMAIL_DOT); + return GetMMSTariff(shmp,pEmailDot+1,tariffid,VAS_CALLED_EMAIL); + break; + default: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]unsupported called type:%d at %s", + portid,vasProc->calledType,__FUNCTION__); + break; + } + return -1; +} + +static float getVasSenderTariffFee(_state_data *shmp,u_char *calledNumber) +{ + u_short portid; + int tariffid; + _gprs_process *vasProc; + + + vasProc = &shmp->process_info.ppsService.gprs_process; + portid = shmp->process_info.portid; + tariffid = GetMOTariffIDWithFreeServiceControl(shmp->caller_info.head,shmp->caller_info.tail); + + switch(vasProc->radiusCommand) + { + case VAS_SMS_AUTH: + case VAS_SMS_ACCOUNT: + if(vasProc->calledType != VAS_CALLED_PHONENUMBER) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]unsupported call type:%d at %s", + portid,vasProc->calledType,__FUNCTION__); + return -1; + } + strcpy((char *)shmp->charge_info.number, (char *)calledNumber); + CutUnknownPrefix((char *)shmp->charge_info.number); + return GetSMSTariff(shmp,tariffid); + break; + case VAS_MMS_AUTH: + case VAS_MMS_SEND_CHARGING: + if(vasProc->calledType != VAS_CALLED_PHONENUMBER && vasProc->calledType != VAS_CALLED_EMAIL) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]unsupported call type:%d at %s", + portid,vasProc->calledType,__FUNCTION__); + return -1; + } + return getVasMMSSenderTariffFee(shmp,calledNumber,tariffid); + break; + default: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]unsupported cmd:%d at %s", + portid,vasProc->radiusCommand,__FUNCTION__); + break; + } + return -1; +} + +static float getVasMMSRetrieveTariffFee(_state_data *shmp,int tariffid) +{ + u_short portid; + VAS_MMS_RETRIEVE_TARIFF *mmsRetrieveTariff; + float fee,discount; + + portid = shmp->process_info.portid; + + mmsRetrieveTariff = &blf_shmp->vas_tariff[tariffid].vasMmsRetrieveTariff[0]; + fee = mmsRetrieveTariff->chargeFee; + discount = (float)GetDiscount(tvnow.tv_sec,mmsRetrieveTariff->discountID)/100; + pps_print_event(shmp->process_info.logMsisdn,"[%05d]fee:%0.4f,disount:%0.4f,at %s", + portid,fee,discount,__FUNCTION__); + return fee*discount; +} + +static float getVasEmailTariffFee(_state_data *shmp,int tariffid) +{ + u_short portid; + VAS_MMSEMAIL_DELIVER_TARIFF *mmsEmailTariff; + float fee,discount; + + portid = shmp->process_info.portid; + + mmsEmailTariff = &blf_shmp->vas_tariff[tariffid].vasMmsEmailDeliverTariff[0]; + fee = mmsEmailTariff->chargeFee; + discount = (float)GetDiscount(tvnow.tv_sec,mmsEmailTariff->discountID)/100; + pps_print_event(shmp->process_info.logMsisdn,"[%05d]fee:%0.4f,disount:%0.4f,at %s", + portid,fee,discount,__FUNCTION__); + return fee*discount; +} + +static float getVasReceiverTariffFee(_state_data *shmp,u_char *calledNumber) +{ + u_short portid; + int tariffid; + _gprs_process *vasProc; + + + vasProc = &shmp->process_info.ppsService.gprs_process; + portid = shmp->process_info.portid; + + tariffid = GetMTTariffIDWithFreeServiceControl(&shmp->charge_info); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]%s tariff id is:%d,at %s", + portid,shmp->charge_info.number,tariffid,__FUNCTION__); + switch(vasProc->radiusCommand) + { + case VAS_MMS_RETRIEVE_ACCOUNTING: + return getVasMMSRetrieveTariffFee(shmp,tariffid); + break; + case VAS_EMAIL_AUTH: + case VAS_EMAIL_CHARGING: + return getVasEmailTariffFee(shmp,tariffid); + break; + default: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]unsupported cmd:%d at %s", + portid,vasProc->radiusCommand,__FUNCTION__); + break; + } + return -1; +} + +static int checkVasNumber(u_char *number) +{ + int i,len; + u_char *pEmailDot; + + pEmailDot = (u_char *)strchr((char *)number,VAS_EMAIL_DOT); + if(pEmailDot == NULL) + { + len = strlen((char *)number); + if(len >= MAX_ASCII_NUMBER_LEN) + { + pps_print_error(0,"too long phone number at %s",__FUNCTION__); + return VAS_CALLED_FORMAT_ERROR; + } + for(i = 0;i < len;i++) + { + if(!isdigit(number[i])&& number[i] != '+') + { + pps_print_error(0,"illegal character in phone number at %s",__FUNCTION__); + return VAS_CALLED_FORMAT_ERROR; + } + } + return VAS_CALLED_PHONENUMBER; + } + else if(*(pEmailDot+1) == 0) + { + pps_print_error(0,"illegal email address at %s",__FUNCTION__); + return VAS_CALLED_FORMAT_ERROR; + } + return VAS_CALLED_EMAIL; +} + +extern BOOL isUseLegal(_account_info *userInfo, u_char *reason); +static float getVasSingleFee(_state_data *shmp,u_char *calledNumber,u_char *failReason) +{ + u_short portid; + _gprs_process *vasProc; + float chargedFee; + + portid = shmp->process_info.portid; + vasProc = &shmp->process_info.ppsService.gprs_process; + + switch(vasProc->radiusCommand) + { + case VAS_SMS_AUTH: + case VAS_SMS_ACCOUNT: + case VAS_MMS_AUTH: + case VAS_MMS_SEND_CHARGING: + chargedFee = getVasSenderTariffFee(shmp,calledNumber); + if(chargedFee < 0) + return -1; + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + case VAS_EMAIL_AUTH: + case VAS_EMAIL_CHARGING: + if(vasProc->calledType != VAS_CALLED_PHONENUMBER) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Wrong called type:%d ,not phone number at %s", + portid,vasProc->calledType,__FUNCTION__); + return -1; + } + strcpy((char *)shmp->charge_info.number, (char *)calledNumber); + CutUnknownPrefix((char *)shmp->charge_info.number); + if(GetAccountPos(&shmp->charge_info) == TRUE) + { + if(isUseLegal(&shmp->charge_info,failReason) == FALSE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s",shmp->process_info.portid ,failReason); + return -1; + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d]prepaid user:%s ask for mms retrieve/email preauth/email charging",portid,calledNumber); + } + else + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]postpaid user:%s ask for mms retrieve/email preauth/email charging",portid,calledNumber); + return 0; + } + chargedFee = getVasReceiverTariffFee(shmp,calledNumber); + if(chargedFee < 0) + return -1; + break; + default: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]unsupported cmd:%d at %s", + portid,vasProc->radiusCommand,__FUNCTION__); + return -1; + break; + } + return chargedFee; +} + +enum{ + VAS_SELECT_PREAUTH, + VAS_SELECT_CHARGE, +}; +static long getVasTotalFee(_state_data *shmp,u_char authOrCharge,u_char *failReason) +{ + int i,calledListNum,rst; + _gprs_process *vasProc; + RADIUS_ATTRIBUTE_CALLED_STATION_ID *calledList; + RADIUS_TLV_TS *called; + u_char calledNumber[RADIUS_TS_VALUE_LEN],*ptr; + u_short portid; + float chargedFee; + + portid = shmp->process_info.portid; + vasProc = &shmp->process_info.ppsService.gprs_process; + + if(vasProc->calledList == NULL) + { + sprintf((char *)failReason, "no called list"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%sfail,%s",portid,shmp->caller_info.number,failReason); + return -1; + } + calledList = vasProc->calledList; + if(calledList->option != 1) + { + sprintf((char *)failReason,"called list's option is not 1,option is:%d",calledList->option); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s fail,%s",portid,shmp->caller_info.number,failReason); + return -1; + } + calledListNum = calledList->called.server.num; + for(i=0;icalculateCount > RADIUS_MAX_NUM_OF_NOWSMS_CALLED_ID) + { + sprintf((char *)failReason,"called list num:%d > Max calledlist Num:%d", + vasProc->calculateCount,RADIUS_MAX_NUM_OF_NOWSMS_CALLED_ID); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s fail,%s",portid,shmp->caller_info.number,failReason); + return -1; + } + if(vasProc->calculateCount >= calledListNum) + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]%s,total calledNum:%d,total fee:%0.4f", + portid,shmp->caller_info.number,calledListNum,vasProc->chargedFee.balance); + return (long)vasProc->chargedFee.balance; + } + called = &calledList->called.server.called_station_id[vasProc->calculateCount]; + memcpy(calledNumber,called->value,called->length%RADIUS_TS_VALUE_LEN); + calledNumber[called->length%RADIUS_TS_VALUE_LEN] = 0; + rst = checkVasNumber(calledNumber); + if(rst == VAS_CALLED_FORMAT_ERROR) + { + sprintf((char *)failReason,"Called Number:%s format error",calledNumber); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s fail,%s",portid,shmp->caller_info.number,failReason); + return -1; + } + vasProc->calledType = rst; + ptr = calledNumber; + if(rst == VAS_CALLED_PHONENUMBER) + { + if(calledNumber[0] == '+') + ptr = calledNumber+1; + } + chargedFee = getVasSingleFee(shmp,ptr,failReason); + if(chargedFee < 0) + { + return -1; + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d]caller:%s,called:%s,fee:%0.4f", + portid,shmp->caller_info.number,calledNumber,chargedFee); + vasProc->chargedFee.balance += chargedFee; + + if(authOrCharge == VAS_SELECT_CHARGE) + { + vasChargeNow(shmp,chargedFee,ptr); + } + vasProc->calculateCount++; + switch(vasProc->radiusCommand) + { + case VAS_SMS_AUTH: + case VAS_MMS_AUTH: + /* multiple recipients */ + break; + case VAS_MMS_SEND_CHARGING: + case VAS_SMS_ACCOUNT: + case VAS_MMS_RETRIEVE_ACCOUNTING: + case VAS_EMAIL_AUTH: + case VAS_EMAIL_CHARGING: + /* only one recipient */ + pps_print_event(shmp->process_info.logMsisdn,"[%05d]%s,total calledNum:%d,total fee:%0.4f", + portid,shmp->caller_info.number,vasProc->calculateCount,vasProc->chargedFee.balance); + return (long)vasProc->chargedFee.balance; + break; + } + } + return -2;/* continue */ +} + +static int vasPreAuth(_state_data *shmp,u_char *failReason) +{ + _gprs_process *vasProc; + //u_short portid; + float balance; + long totalChargedFee; + + //portid = shmp->process_info.portid; + vasProc = &shmp->process_info.ppsService.gprs_process; + + totalChargedFee = getVasTotalFee(shmp,VAS_SELECT_PREAUTH,failReason); + switch(totalChargedFee) + { + case -1: + return -1; + break; + case -2: + return 0; + break; + } + + switch(vasProc->radiusCommand) + { + case VAS_SMS_AUTH: + case VAS_SMS_ACCOUNT: + case VAS_MMS_AUTH: + case VAS_MMS_SEND_CHARGING: + balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info); + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + case VAS_EMAIL_AUTH: + case VAS_EMAIL_CHARGING: + balance = GetBalanceWithPromotionControl(shmp,&shmp->charge_info)+GetOverdraft(&shmp->caller_info); + break; + } + if(balance < totalChargedFee) + return -1; + return 1; +} + +static int vasChargeNow(_state_data *shmp,float fee,u_char *peerAddr) +{ + _gprs_process *vasProc; + u_short portid; + _account_info *userInfo; + DWORD instance; + CHARGED_FEE chargedFee; + + if(fee == 0) + return 1; + vasProc = &shmp->process_info.ppsService.gprs_process; + portid = shmp->process_info.portid; + switch(vasProc->radiusCommand) + { + case VAS_SMS_ACCOUNT: + case VAS_MMS_SEND_CHARGING: + userInfo = &shmp->caller_info; + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + case VAS_EMAIL_CHARGING: + userInfo = &shmp->charge_info; + break; + default: + pps_print_error(shmp->process_info.logMsisdn,"[%05d]Vas cmd:%d ,no need to charge", + portid,vasProc->radiusCommand); + return -1; + break; + } + userInfo->charge = fee; + UpdateBalance(shmp,userInfo, -fee,&chargedFee); + instance = userInfo->head * UNIT_STORE_ACCOUNT + userInfo->tail; + SendAccountRealSync(instance,chargedFee.balance,chargedFee.promotion,OMC_OCODE_EDIT); + SendVasCDR(userInfo,shmp,peerAddr); + pps_print_event(shmp->process_info.logMsisdn,"[%05d]%s charged fee(balance:%0.4f,promotion:%0.4f)", + portid,userInfo->number,chargedFee.balance,chargedFee.promotion); + return 1; +} + +static int vasCharge(_state_data *shmp,u_char *failReason) +{ + //_gprs_process *vasProc; + //u_short portid; + long totalChargedFee; + + //portid = shmp->process_info.portid; + //vasProc = &shmp->process_info.ppsService.gprs_process; + + totalChargedFee = getVasTotalFee(shmp,VAS_SELECT_CHARGE,failReason); + switch(totalChargedFee) + { + case -1: + return -1; + break; + case -2: + return 0; + break; + } + return 1; +} + +extern BOOL checkMiniBalanceForGprs(_state_data *shmp); +int vasProcess(u_short portid) +{ + _gprs_process *vasProc; + _state_data *shmp; + int result = SERVICE_KEEP_STATE,rst; + u_char failReason[128]={0}; + + shmp = (_state_data *)&smshm_ptr->state_data; + shmp += portid; + vasProc = &shmp->process_info.ppsService.gprs_process; + + switch(vasProc->state) + { + case VAS_STATE_IDLE: + if(vasProc->radiusCommand != VAS_NULL) + shmp->cdr_info.answertime = tvnow.tv_sec; + switch(vasProc->radiusCommand) + { + case VAS_SMS_AUTH: + case VAS_MMS_AUTH: + CutUnknownPrefix((char *)shmp->caller_info.number); + if(GetAccountPos(&shmp->caller_info) == TRUE) + { + if(isUseLegal(&shmp->caller_info,failReason) == FALSE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s",shmp->process_info.portid ,failReason); + sendRadiusAccessReject(portid,failReason); + pps_set_vas_state(VAS_STATE_TERMINATE); + break; + } + if(checkMiniBalanceForGprs(shmp) == FALSE) + { + sendRadiusAccessReject(portid, (u_char *)"Low Balance for vas service"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s Low Balance for vas service",portid,shmp->caller_info.number); + pps_set_vas_state(VAS_STATE_TERMINATE); + break; + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d]prepaid user:%s ask for vas preauth",portid,shmp->caller_info.number); + pps_set_vas_state(VAS_STATE_AUTH); + } + else + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]postpaid user:%s ask for vas preauth",portid,shmp->caller_info.number); + pps_set_vas_state(VAS_STATE_ACCEPT); + } + break; + case VAS_EMAIL_AUTH: + pps_set_vas_state(VAS_STATE_AUTH); + break; + case VAS_SMS_ACCOUNT: + case VAS_MMS_SEND_CHARGING: + CutUnknownPrefix((char *)shmp->caller_info.number); + if(GetAccountPos(&shmp->caller_info) == TRUE) + { + if(isUseLegal(&shmp->caller_info,failReason) == FALSE) + { + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s",shmp->process_info.portid ,failReason); + sendRadiusAccessReject(portid,failReason); + pps_set_vas_state(VAS_STATE_TERMINATE); + break; + } + if(checkMiniBalanceForGprs(shmp) == FALSE) + { + sendRadiusAccessReject(portid, (u_char *)"Low Balance for vas service"); + pps_print_error(shmp->process_info.logMsisdn,"[%05d]%s Low Balance for vas service",portid,shmp->caller_info.number); + pps_set_vas_state(VAS_STATE_TERMINATE); + break; + } + pps_print_event(shmp->process_info.logMsisdn,"[%05d]prepaid user:%s ask for vas charging",portid,shmp->caller_info.number); + pps_set_vas_state(VAS_STATE_CHARGE); + } + else + { + pps_print_event(shmp->process_info.logMsisdn,"[%05d]postpaid user:%s ask for vas charging",portid,shmp->caller_info.number); + pps_set_vas_state(VAS_STATE_ACCEPT); + } + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + case VAS_EMAIL_CHARGING: + pps_set_vas_state(VAS_STATE_CHARGE); + break; + } + break; + case VAS_STATE_AUTH: + rst = vasPreAuth(shmp,failReason); + if(rst > 0) + pps_set_vas_state(VAS_STATE_ACCEPT); + else if(rst < 0) + pps_set_vas_state(VAS_STATE_REJECT); + break; + case VAS_STATE_CHARGE: + rst = vasCharge(shmp,failReason); + if(rst > 0) + pps_set_vas_state(VAS_STATE_ACCEPT); + else if(rst < 0) + pps_set_vas_state(VAS_STATE_REJECT); + break; + case VAS_STATE_ACCEPT: + sendRadiusAccessAccept(portid,FALSE,FALSE); + pps_set_vas_state(VAS_STATE_TERMINATE); + break; + case VAS_STATE_REJECT: + sendRadiusAccessReject(portid,failReason); + pps_set_vas_state(VAS_STATE_TERMINATE); + break; + default: + case VAS_STATE_TERMINATE: + memset(vasProc,0,sizeof(_gprs_process)); + result = SERVICE_EXIT_PPS; + break; + } + return result; +} + + +static int reportVasCDRIncrement(u8 vasType,float charge) +{ + int index=0; + _pps_vas_record *vas_record; + + PutLogFunID("reportVasCDRIncrement"); + + index = pps_report.ptrTail; + vas_record = &pps_report.daily_report[index].call_report.vas_record; + switch(vasType) + { + case VAS_SMS_ACCOUNT: + vas_record->smsNumber++; + vas_record->smsCharge += charge; + break; + case VAS_MMS_SEND_CHARGING: + vas_record->mmsSendNumber++; + vas_record->mmsSendCharge += charge; + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + vas_record->mmsRetrieveNumber++; + vas_record->mmsRetrieveCharge += charge; + break; + case VAS_EMAIL_CHARGING: + vas_record->mmsEmailNumber++; + vas_record->mmsEmailCharge += charge; + break; + default: + return -1; + break; + } + + pps_report.daily_report[index].balance_summary.today_charge += charge; + return 1; +} + +static int vasCDRStatistics(_tocdr_report* pbuf,u8 vasType) +{ + long charge=0; + //char buf[BUFSIZE]; + _pps_vas_csta_items *vasCsta; + + PutLogFunID("vasCDRStatistics"); + + memcpy(&charge , pbuf->charge, 4); + vasCsta = &pps_csta_buffer.csta_record[csta_old_instance].vasCsta; + + switch(vasType) + { + case VAS_SMS_ACCOUNT: + vasCsta->smsNumber++; + vasCsta->smsCharge += charge; + break; + case VAS_MMS_SEND_CHARGING: + vasCsta->mmsSendNumber++; + vasCsta->mmsSendCharge += charge; + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + vasCsta->mmsRetrieveNumber++; + vasCsta->mmsRetrieveCharge += charge; + break; + case VAS_EMAIL_CHARGING: + vasCsta->mmsEmailNumber++; + vasCsta->mmsEmailCharge += charge; + break; + default: + return -1; + break; + } + + reportVasCDRIncrement(vasType,charge); + AddPPSStatistics(MIBPPS_CSTANUMBER,0); + return 1; +} + +static void SendVasCDR(_account_info *userInfo,_state_data *shmp,u_char *peerAddr) +{ + _tocdr_report pcdr; + char buf[BUFSIZE]={""}; + int balance; + int head, tail; + long charge; + _gprs_process *vasProc; + //struct in_addr nas_addr; + u16 cdrType; + + PutLogFunID("SendVasCDR"); + + memset(&pcdr,0,sizeof(_tocdr_report)); + + vasProc = &shmp->process_info.ppsService.gprs_process; + + switch(vasProc->radiusCommand) + { + case VAS_SMS_ACCOUNT: + cdrType = CT_VAS_SMS; + pcdr.mtype = MO_CDR_TYPE; + memcpy(pcdr.peerAddress,peerAddr,strlen((char *)peerAddr)%128); + break; + case VAS_MMS_SEND_CHARGING: + cdrType = CT_VAS_MMS_SEND; + pcdr.mtype = MO_CDR_TYPE; + memcpy(pcdr.peerAddress,peerAddr,strlen((char *)peerAddr)%128); + break; + case VAS_MMS_RETRIEVE_ACCOUNTING: + cdrType = CT_VAS_MMS_RETRIEVE; + pcdr.mtype = MT_CDR_TYPE; + memcpy(pcdr.peerAddress,shmp->caller_info.number,strlen((char *)shmp->caller_info.number)%128); + break; + case VAS_EMAIL_CHARGING: + cdrType = CT_VAS_MMS_EMAIL; + pcdr.mtype = MT_CDR_TYPE; + memcpy(pcdr.peerAddress,shmp->caller_info.number,strlen((char *)shmp->caller_info.number)%128); + break; + default: + return; + break; + } + + + head = userInfo->head; + tail = userInfo->tail; + + pcdr.type[0] = cdrType; + pcdr.type[1] = cdrType>>8; + + shmp->cdr_info.releasetime = shmp->cdr_info.answertime; + AsciiTime(buf, shmp->cdr_info.answertime); + AsciiToBcd(pcdr.answertime,buf,14); + + AsciiTime(buf, shmp->cdr_info.releasetime); + AsciiToBcd(pcdr.releasetime,buf,14); + + charge = (long)userInfo->charge; + charge = abs(charge); + memcpy(pcdr.charge,&charge,4); + balance = (int) GetAccountBalance(head, tail); + memcpy(pcdr.balance,&balance,4); + + GetAccountMsisdn(head,tail,&pcdr.msisdn[1]); + ByteRev(pcdr.msisdn,9,0); + pcdr.msisdn[0]=0x91; + buf[0] = 0; + + pcdr.tcos[0] = NORMAL_CLEARING%256; + + vasCDRStatistics(&pcdr,vasProc->radiusCommand); + StoreCDR(&pcdr); + pps_real_update_user_file(head, tail); + + pps_print_event(shmp->process_info.logMsisdn,"[%05d]%s send vas cdr,vas type:%d,charge:%ld" + ,shmp->process_info.portid ,userInfo->number,vasProc->radiusCommand,charge); +} + + diff --git a/mss/pps/src/object/makefile b/mss/pps/src/object/makefile new file mode 100644 index 0000000..87628e1 --- /dev/null +++ b/mss/pps/src/object/makefile @@ -0,0 +1,9 @@ +#!/bin/sh +create: + cp -f ../lib/*.o . + cp -f ../main/*.o . + ar r libpps.a loadtl.o message.o mfunc.o ppsmib.o ppsMibTable.o comfunc.o daemon.o debug.o error.o errorlog.o ppsfun.o iofunc.o ipcfunc.o logfunc.o queuefunc.o signal.o time.o version.o capmsg.o smppapi.o precard.o dailyreport.o rammng.o ppsm.o crd.o ppsmap.o ppsussd.o callingCardMsg.o callingCardState.o tariffApplication.o callMeBack.o freeSMS.o feeTransfer.o masterSlaveCard.o radius.o gprs.o vas.o restapi.o ocs_user_table.o pps_redis.o +# rm -f ../../wxc2app/applib/pps/libpps.a +# cp -uf libpps.a /home/mnp/wxc2app/applib/pps +clean: + rm -f *.o *.a diff --git a/plat/debug/Makefile b/plat/debug/Makefile new file mode 100644 index 0000000..24c4ed1 --- /dev/null +++ b/plat/debug/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = debug +TYPE = plat + +DBUG_FLAGS_ADD = -DDEBUG +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/debug/src/debug.c b/plat/debug/src/debug.c new file mode 100644 index 0000000..d7833a9 --- /dev/null +++ b/plat/debug/src/debug.c @@ -0,0 +1,15652 @@ +/* +* ******************************************** +* debug.c * +* Author: Li Long * +* Verified by Liu Zhiguo 2003-04-21 * +* Verified by Wang Jian 2005-01-17 * +* Verified by liu Wei 2005-05-15 * +* 2005-05-15 * +* Function: * +* 1. Monitor other modules status; * +* 2. Use serial port; * +* 3. Use telnet; * +* 4. Use SNMP Agent set MIB tree * +* 5. SNMP sernior agent * +* 6. Custmor setting menu * +* ******************************************** +*/ + + +/* +printf("\033[1;33m Hello World. \033[0m \n"); + +ÑÕÉ«ÈçÏÂ: +none = "\033[0m" +black = "\033[0;30m" +dark_gray = "\033[1;30m" +blue = "\033[0;34m" +light_blue = "\033[1;34m" +green = "\033[0;32m" +light_green -= "\033[1;32m" +cyan = "\033[0;36m" +light_cyan = "\033[1;36m" +red = "\033[0;31m" +light_red = "\033[1;31m" +purple = "\033[0;35m" +light_purple = "\033[1;35m" +brown = "\033[0;33m" +yellow = "\033[1;33m" +light_gray = "\033[0;37m" +white = "\033[1;37m" + + +×Ö±³¾°ÑÕÉ«·¶Î§: 40--49 ×ÖÑÕÉ«: 30--39 + 40: ºÚ 30: ºÚ + 41: ºì 31: ºì + 42: ÂÌ 32: ÂÌ + 43: »Æ 33: »Æ + 44: À¶ 34: À¶ + 45: ×Ï 35: ×Ï + 46: ÉîÂÌ 36: ÉîÂÌ + 47: °×É« 37: °×É« +ANSI¿ØÖÆÂë: +QUOTE: + \033[0m ¹Ø±ÕËùÓÐÊôÐÔ + \033[1m ÉèÖøßÁÁ¶È + \03[4m Ï»®Ïß + \033[5m ÉÁ˸ + \033[7m ·´ÏÔ + \033[8m ÏûÒþ + \033[30m -- \033[37m ÉèÖÃǰ¾°É« + \033[40m -- \033[47m ÉèÖñ³¾°É« + \033[nA ¹â±êÉÏÒÆnÐÐ + \03[nB ¹â±êÏÂÒÆnÐÐ + \033[nC ¹â±êÓÒÒÆnÐÐ + \033[nD ¹â±ê×óÒÆnÐÐ + \033[y;xHÉèÖùâ±êλÖà + \033[2J ÇåÆÁ + \033[K Çå³ý´Ó¹â±êµ½ÐÐβµÄÄÚÈÝ + \033[s ±£´æ¹â±êλÖà + \033[u »Ö¸´¹â±êλÖà + \033[?25l Òþ²Ø¹â±ê + \33[?25h ÏÔʾ¹â±ê + + + +\033=\x1b +*/ + +#include "./include/debug.h" +#include "../../public/src/include/pub_log.h" +#include "../../public/src/include/pub_debug.h" + +// fix multiple definition +struct debug_shm_struct *debug_shm_ptr; +mib_node *mib_root_node; +mib_node *mib_curr_node; +menu_node *menu_root_node; +menu_node *menu_curr_node; +mib_node mib_nodes[MIB_MAX_NODES]; +menu_node menu_nodes[MENU_MAX_NODES]; +mib_child_node mib_child_nodes[MIB_MAX_CHILD_NODES]; +debug_snmp_agent debug_snmp_agent_buf[MAX_PACKET_NUM]; + + +#define DEBUG_VERSION "V1.0.01" +#define DEBUG_PATCH 1 +/*@ignore@*/ +static char ascii[16] = + { + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46 + }; + +static char title_top[] = {0xc,0x1b,'[','H',0x1b,'[','2','J','\0'}; + +static char prompt_line25[] = {0x1b,'[','2','5','H',0x1b,'[','0','J','>','\0'}; + +static char max_access[7][32]={"invalid", "not-accessible", "accessible-for-notify", "read-only","read-write","read-create "," write-only"}; + +static char title1[TITLE_CHAR*DEBUG_MAX_PAGE] = "\0"; // show the menu page from conf file +char title1_show[TITLE_CHAR*DEBUG_MAX_PAGE] ="\0"; // show the menu page + +unsigned int com_port; +char recser_buf[SERIAL_BUF_LEN]; +int recserbuf_h; +int recserbuf_t; +char sendser_buf[SERIAL_BUF_LEN]; +int sendserbuf_h; +int sendserbuf_t; + +INSTANCE_ARR curr_instance_arr[256]; +char instance_eable_name[80]; +int temp_instance; +BYTE curr_module; +BYTE host_group=0; +debug_snmp_agent snmp_agent_packet; +debug_snmp_agent snmp_agent_packet1; +DWORD debug_mem_size; +DWORD debug_alloc_mem; + +BYTE remark_meet_lf=0; + +debug_shm_struct debug_shared_memory; + +DWORD heap_remark_index; +void *heap_remark_curr; +void *heap_remark; +char heap_work_buf[300*1024]; + +char curr_instance_value[256]; +char set_ins_value[256]; +BYTE none_instance=0; +BYTE set_str_len=0; +BYTE set_all=0; +char set_val_str[256] ; +BYTE SendTelnetFlag=0; +BYTE disp_main_flag; // display the main page +BYTE disp_sub_module_flag; // current module +BYTE disp_page_flag; // current page of each module +BYTE disp_main_page_num; //main page number +BYTE command_flag; // whether in command mode +BYTE first_page; +BYTE bind_num; +BYTE comp_disp[500]; +BYTE m_state; +BYTE m_state_sub_module; +WORD title_top_pt; +WORD title_pt; +WORD title_sub_module_pt; +WORD ascii_in_pt; +WORD space_counter; +WORD row_ptr,col_ptr; +int list_flag,list_start,list_end; +int show_all_value; +int show_type; +int show_expend; +int show_range; +int get_show_state; +int save_flag; +int show_empty=0; +int del_flag; +int expend_view=0; +int list_field=0; +int show_snmp_state; +int show_list; +int list_once; +BYTE set_after_get=0; +BYTE show_field=0; +DWORD list_field_arr[64]; +BYTE Module_Count_Index=0; +BYTE Init_Page=0; +BYTE send_char_flag=0; + +BYTE debug_agent_index; +BYTE snmp_agent_flag=0; // 0 idel 1 get 2 set + +static BYTE *disp_ptr; +static WORD disp_length;/* displaying length of each row */ +WORD disp_index; /* row number */ +WORD char_ptr; /* how many hex code in a row, < disp_length */ +WORD hex_state; /* the state in function disp_hex */ +BYTE cursor_p[8]; /* control characters as 'ESC[**;**H' */ + +WORD ascii_out_ph,ascii_out_pt; +static BYTE ascii_out_array[MAX_ASCII_LEN]; +static BYTE ascii_in_array[MAX_ASCII_LEN]; + +static BYTE debug_ascii_in_array[MAX_ASCII_LEN]; +static BYTE debug_ascii_out_array[MAX_ASCII_LEN]; +int debug_ascii_out_ph=0; +int debug_ascii_out_pt=0; + + + +BYTE list_msg[128]; + +static BYTE test_array[20]; +WORD t10s_flag; +WORD ascii_out_len; +DWORD debug_counter; +BYTE debug_heartbeat[8]; +char time_buf[64] = "\0"; +char hostip_buf[64] = "\0"; +char current_timer[64]="\0"; + + +BYTE bind_index; +BYTE get_state; +BYTE set_state; +DWORD set_val; + + +DWORD Local_IP; +DWORD Peer_IP[16]; +char Remote_Host_Name[16][64]; +char Remote_Host_IP[16][16]; +BYTE IP_Selected[16]; +BYTE ip_num; +BYTE ip_index; +snmp_pdu send_msgbuf,recv_msgbuf; +snmp_addr send_addr, recv_addr; +WORD t5s_flag; +WORD t100ms_flag; +mib_node_param *param_node; +char paraname[128]; +mib_node *temp_mib_node; +WORD mib_line_count; +mib_node temp_leaf_node; + + +DWORD root_oid[32] = {1,3,6,1,4,1}; //SNMPv2 +DWORD cur_oid[32] = {1,3,6,1,4,1,1373,1,3}; +BYTE root_oid_len = 6; +WORD treehost; +BYTE debug_remark_flag; +WORD debug_remark_ptr; + + +struct _wxc2_debug_info wxc2_debuginfo; + +//mib_node *mib_root_node; +//mib_node *mib_curr_node; +WORD mib_node_index=0; +WORD menu_node_index=0; +WORD mib_child_node_index; +int mib_type_num; + +BYTE leaf_compute_field_num=0; +WORD mib_param_select_index; +WORD mib_param_input_index; +WORD mib_node_param_index; + +BYTE debug_cfg; //0: command status, 1: configure status +BYTE debug_log_all; // 0: log none , 1: log all +BYTE debug_log_error_on; //0: log error off, 1: log erro on +BYTE debug_module_num; //if in command status, debug_module_num shows which module's ascii in buf the command send to +BYTE debug_cfg_end; // 0: configure command not over, 1: configure command over +int debug_get_all_value; // 0: not get all value, or means how much children value have to get + +WORD gobal_module_index; +BYTE node_save_flag; +module_command_save_flag node_save_module; + +mib_subsys_module subsys_module[MIB_SUBSYS_MODULE_MAX_NUM]; +mib_host module_host[MIB_HOST_MAX_NUM]; +module_command_save_flag module_save_flag[MIB_SUBSYS_MODULE_MAX_NUM]; + + +mib_param_select mib_param_select_array[MIB_MAX_PARAM_SELECTS]; +mib_param_input mib_param_input_array[MIB_MAX_PARAM_INPUTS]; +mib_node_param mib_node_param_array[MIB_MAX_NODE_PARAMS]; + +mibfile_imports_data imports_data; +mibfile_module_data module_data; +mibfile_object_data object_data; +mibfile_type_data type_data; + +BYTE set_ok_once=0; + + +char *field_input_type[7]={"toDec high 0","KeepHex high 0","KeepHex low 0", + "KeepHex Low E","KeepHex Low F","ToAscii Low 0","KeepAscii Low F"}; + + +//add for compute field +BYTE compute_field_num; //for all compute +compute_field compute_field_arr[16]; //for all compute +compute_list compute_field_list[6]; //unit list +BYTE compute_list_num; //unit list//curr node compute_list_num=0 +char OID_name_str[5][65]; //unit read +DWORD OID_val[5][32]; //unit read +BYTE OID_index=0; //unit read +BYTE line_index; //unit read +BYTE print_line_index=0;; +BYTE compute_field_list_index; +compute_field compute_curr_unit; //unit read +BYTE read_syntax_nor_list=0; //unit read +BYTE compute_state=0; +WORD compute_curr_instance; +mib_node *temp_compute_node; +char temp_value[256][32]; +BYTE print_once=0; +//0 idle +//1 print once(list all once) +//2 print again +BYTE field_compute_state=0; +//field_compute_state +//0 idle +//1 find compute field +//2 translate [v] [l] +//3 list curr node self +//4 list "OID" +//5 list over +//6 translate [c] [p] +//7 translate over +//8 print over + +//end of define for compute field + + + +struct timeval tv_start_rt, tv_end_rt; +mib_node *agent_tmp_node; +menu_node *tmp_menu_node; + + +BYTE ShowRegister=0; +BYTE debug_busy_alarm=0; + + +static char switch_stat[][32] = {"off", "on"}; + +///////////////////////////////////declaration//////////////////////// +void debug_init_serial(); + +void debug_init_shm(); + +void debug_init_var(); + +void debug_ascii_in_cmd_handle(); + + + + +void debug_read_main_title(); + +void debug_change_title1(); + +void debug_module_page(int count); + +void debug_disp_hex(); + +void debug_set_para(); + + + + +int OBJECT_found(char *name, FILE *fp, mib_node *father_node_ptr, DWORD *last_node_oid); + + +int BEGIN_found(FILE *fp); + +int TYPE_found(char *name, FILE *fp, mib_node *father_node_ptr, DWORD +*last_node_oid); + +mib_node *IMPORTS_found(FILE *fp); + +int MODULE_found(char *name, FILE *fp, mib_node *father_node_ptr, DWORD +*last_node_oid); + +int Analyze_Leaf_Description(FILE * fp, mib_node * leaf_node); + +//int analyze_setTemplate(FILE *fp, mib_node *father_node_ptr); + +int MIB_create_tree(char *conf_dir, char *conf_file); + +//int MIB_create_leaves(char *conf_dir, char *sysConf_file, char *param_list_file); + +mib_child_node *create_mib_child_node(char *name, DWORD oid); + +mib_node *create_mib_node(char *name, BYTE oid_len, DWORD *oid, WORD total_instance); + + +mib_node *create_node(char *line, char *nod_name, int instance, mib_node *father_ptr, DWORD *last_node_oid); + +int register_node(mib_node *mib_node_ptr, DWORD *oid, BYTE oid_len); + +int register_child_node(mib_node *mib_node_ptr, mib_child_node *mib_child_node_ptr); + + + + +void debug_mmi_remark(); + + +void debug_mmi_log_status(); + +int debug_mmi_log(char *log_str); + +void debug_mmi_option(char *str); + +int debug_mmi_select_host(char *host_str); + + + +void show_node(mib_node *node_ptr,char *separation); + +int find_OID(int obj_num, char *sysConf_file_name, DWORD *OID); + + +void debug_mmi_view(); + + +void pick_name(char *str_ptr, char *word_ptr,char *temp_ch); + + +void debug_send_serial(); + +int debug_send_char(BYTE ch); + +void debug_read_serial(); + +int debug_read_char(); + +void debug_recv_cmd(); + + + +int debug_mmi_cd(char *path); + +int debug_mmi_contents(char *str); + +int debug_mmi_parent(); + +int debug_mmi_child(char *name); + +int debug_mmi_setins(char *ins); + +void debug_mmi_save(); + +void register_host(); + +int debug_mmi_pwd(); + +int debug_mmi_ip(char *ips); + +void debug_mmi_list(); + +void register_instance(); + +void debug_mmi_create(char *str); + +void debug_mmi_del(char *str); + +void debug_mmi_option(char *str); + +void debug_mmi_remark(); + +void debug_mmi_tree(mib_node *node_ptr,char *separation, BYTE node_levels); + +void debug_mmi_find_host(); + +int debug_mmi_show_host(); + +void debug_mmi_cmm_help(); + +void debug_mmi_cfg_help(); + +int debug_mmi_get(char *child_name); + +int debug_mmi_set(char *set_str); + +int debug_mmi_get_all(); + +int debug_snmp_get(BYTE oidlen,DWORD *oid,BYTE *data_ptr,BYTE *vartype); + +int debug_snmp_set(BYTE oidlen,DWORD *oid,BYTE *data_ptr,WORD data_len); + +void debug_snmp_get_rt(); + +void debug_snmp_set_rt(); + + +int default_value(DWORD *oid,BYTE oid_len,char *value);//,char *default_Value); + +int debug_mmi_select_host(char *host_str); + + + + + +void debug_set_currenttime(); + +void del_space(char *str,BYTE type); + +int read_line(FILE *fp, char *line_ptr); + +int read_begin(FILE *fp, char *stop_ch); + +int read_until(FILE *fp, char *data_ptr, char *stop_ch); + +int read_part(FILE *fp, char *data_ptr,char *start_ch, char *stop_ch); + +char *pick_first_word(char *str_ptr, char *word_ptr); + +int take_str(char *data_str, FILE *fp, char *data_ptr); + +void debug_color_out(int attr,int color,int bg,char *str); + +void help_cmm(int index,char *str1,char *str2); + +void formatstr(int len,char *str,BYTE type); + +void switchchar(char *out_text,BYTE num); + +void debug_ascii_out_proc(const char *str_ptr); + +DWORD my_pow(int x, int y); // y \u4E2A x \u76F8\u4E58 + +BYTE test_str(char *str,BYTE type); + +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len); + +void strpcat(char *dest_str,DWORD *dest_p,const char *src_str); + +//void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len); + + +int create_menu_tree(char *conf_dir,char *menu_page,mib_node *sys_node); + +void debug_mmi_view(); + +void debug_mmi_mcd(char *str); + +void main_menu(char *str); + +int debug_send_string(const char *str_send); + + + + +BYTE create_compute_field(FILE * fp, mib_node * node_ptr, BYTE field_id,char *name); + +void translate_compute_field(); + +BYTE take_compute_value(char *str,char *temp_value); + +void compute_field_WatchDog(); + +void print_compute_field(); + + +//////////////////////////////////end of declaration////////////////// + + + + +void debug_netcap_start() +{ + char str[] = "net cap start"; + int i; + + NcStart(0,0); + for(i=0; i < MODULE_COUNT; i++) + { + if( (i !='n'-'a') && (debug_shm_ptr->module_d[i].ascii_in_set_flag == 1)) + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1,str); + } + } +} + +void debug_netcap_stop() +{ + char str[] = "net cap stop"; + int i; + + NcStop(); + for(i=0; i < MODULE_COUNT; i++) + { + if( (i !='n'-'a') && (debug_shm_ptr->module_d[i].ascii_in_set_flag == 1)) + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1,str); + } + } +} + + +////////////////////////////////////Intial//////////////////////////// +/* +* +* Fun: debug_read_conf +* +* Desc: debug read conf +* +* Ret: void +* +* File: debug.c +* +*/ +void debug_read_conf () +{ + char file_name[32]; + char *p, *q, line[512]; + BYTE conf_flag = 0; + FILE *fp_conf; + DIR *pdir; + + strcpy ( file_name, "./conf/debug.conf" ); + + wxc2_debuginfo.mmi_switch = 0; //off + + if( ( pdir = opendir ( MIB_FILES_DIR ) ) == NULL && errno == ENOENT ) + { + return; + } + else + { + + closedir ( pdir ); + if( ( fp_conf = fopen ( file_name, "rw" ) ) == NULL ) + { + printf ( "[debug] Error: cannot open debug conf_file: [%s].\r\n", file_name ); + return; + } + } + + while ( !feof ( fp_conf ) ) + { + if( fgets ( line, 256, fp_conf ) == NULL ) + { + break; + } + line[128] = '\0'; + p = line; + while ( *p == ' ' ) + p++; + if( ( q = strstr ( p, "//" ) ) != NULL ) + *q = '\0'; + if( strstr ( p, "System Type" ) ) + { + p = p + 11; + if( ( p = strchr ( p, '=' ) ) && ( q = strchr ( p, ';' ) ) ) + { + p++; + *q = '\0'; + + if( strstr ( p, "CDMA" ) ) + { + wxc2_debuginfo.sys_type = 1; + conf_flag |= 0x01; + } + else if( strstr ( p, "GSM" ) ) + { + wxc2_debuginfo.sys_type = 2; + conf_flag |= 0x01; + } + else if( strstr ( p, "SSW" ) ) + { + wxc2_debuginfo.sys_type = 3; + conf_flag |= 0x01; + } + } + + } + else if( strstr ( p, "MMI Switch" ) ) + { + p = p + 10; + if( ( p = strchr ( p, '=' ) ) && ( q = strchr ( p, ';' ) ) ) + { + p++; + *q = '\0'; + + if( strstr ( p, "ON" ) || strstr ( p, "On" ) || strstr ( p, "on" ) ) + { + wxc2_debuginfo.mmi_switch = 1; + conf_flag |= 0x02; + } + else if( strstr ( p, "off" ) || strstr ( p, "Off" ) || strstr ( p, "OFF" ) ) + { + wxc2_debuginfo.mmi_switch = 0; + conf_flag |= 0x02; + } + } + + } + + } + fclose ( fp_conf ); + if( conf_flag != 0x03 ) + { + printf ( "[debug] Error: debug conf_file ([%s])is incorrect .\r\n", file_name ); + return; + } + return; + +} + +/* +* +* Fun: debug_init +* +* Desc: debug intial function +* +* Ret: void +* +* File: debug.c +* +*/ +extern void WxcDump(int nSigno); + +void debug_init() +{ + + + int i,j; + char temp_str[64]; + char file_name[64]; + FILE *fp_conf; + mib_node *sys_base_node; + +// signal(SIGSEGV, &WxcDump); + NcInit(); + + //heap_remark=calloc(sizeof(char),1024*300); + heap_remark=heap_work_buf; + heap_remark_index=0; + heap_remark_curr=heap_remark; + + for(i=0;ih_addr_list)); + sprintf(hostip_buf,"\x1b[22;10HLocal IP: %s\x1b[22;35H hostname: %s",host_ip,hostname); + // Local_IP = ((struct in_addr *)(*host->h_addr_list))->s_addr; + Peer_IP[0] = Local_IP; + for(i=1; i<16; i++) + { + Peer_IP[i] = 0; + IP_Selected[i] = 1; + } + } + } + + + debug_counter = 0; + show_all_value=0; + show_type=0; + show_expend=1; + show_range=0; + get_show_state=0; + show_list=1; + + + + show_snmp_state=0; + list_once=0; + for(i=0;i<=255;i++) + { + curr_instance_arr[i].ins=i; + curr_instance_arr[i].eable=0; + } + for(i=0;i<64;i++) + { + list_field_arr[i]=0xFF; + } + list_flag=list_start=list_end=0; + debug_get_all_value = 0; + debug_cfg = 0; + debug_cfg_end = 1; + debug_log_all = 0; + debug_log_error_on = 0; + debug_module_num = 13; + t10s_flag = 0; + t5s_flag=0; + t100ms_flag = 0; + get_state = 0; + set_state = 0; + ip_num=0; + ip_index=0; + set_val = 0; + param_node = NULL; + bind_num=0; + + debug_heartbeat[0] = 3; + debug_heartbeat[1] = 3; + debug_heartbeat[2] = 2; + debug_heartbeat[3] = 1; //status 1-normal 0-abnormal + debug_heartbeat[4] = 0; //module count + debug_heartbeat[5] = 0; //sub module status + debug_heartbeat[6] = 0; //sub module status + debug_heartbeat[7] = 0; + first_page=1; + disp_main_flag = 0; //--lw + disp_main_page_num = 0; + treehost=1; //--lw + disp_sub_module_flag = 13; + disp_page_flag = 0; + m_state = 0; + command_flag = 0; + ascii_out_len = 0; + strcpy((char *)test_array,""); + ascii_in_pt = 1; + ascii_out_ph = 0; + ascii_out_pt = 0; + title_top_pt = 0; + cursor_p[0] = 0x1b; + cursor_p[1] = '['; + cursor_p[4] = ';'; + cursor_p[7] = 'H'; + memset(comp_disp,0x80,500); + for(i = 0;i < MODULE_COUNT;i ++) + { + strcpy(debug_shm_ptr->module_d[i].name,""); + strcpy(debug_shm_ptr->module_d[i].status,""); + strcpy(debug_shm_ptr->module_d[i].version,""); + debug_shm_ptr->module_d[i].maxpage = 0; + debug_shm_ptr->module_d[i].ascii_in_set_flag = 0; + debug_shm_ptr->module_d[i].ascii_out_set_flag = 0; + debug_shm_ptr->module_d[i].ascii_in = NULL; + debug_shm_ptr->module_d[i].ascii_out = NULL; + for(j = 0;j < PAGE_COUNT;j ++) + { + strcpy(debug_shm_ptr->module_d[i].page_d[j].title,title_top); + debug_shm_ptr->module_d[i].page_d[j].pointer_set_flag = 0; + for (k = 0;k < LINE_COUNT;k ++) + { + debug_shm_ptr->module_d[i].page_d[j].line_d[k].length = 0; + debug_shm_ptr->module_d[i].page_d[j].line_d[k].pt_vartype = 0; + debug_shm_ptr->module_d[i].page_d[j].line_d[k].pointer = NULL; + } + } + debug_shm_ptr->module_d[i].seqid_h = 0; + debug_shm_ptr->module_d[i].seqid_t = 0; + for (j = 0;j < DEBUG_SEQID_LEN;j ++) + strcpy((char *)debug_shm_ptr->module_d[i].omc_outbuf[j],""); + } + debug_shm_ptr->TelnetSendData.telsend_datah = 0; + memset(debug_shm_ptr->TelnetSendData.telsend_data,0,sizeof(BYTE)*TELNET_SEND_BUF_LEN); + memset(debug_snmp_agent_buf,0,8*sizeof(debug_snmp_agent)); + memset(&snmp_agent_packet,0,sizeof(debug_snmp_agent)); +} + +////////////////////////////End of Intial/////////////////////////////// + + + + + +////////////////////////////////////Main///////////////////////////// +/* +* +* Fun: debug_rt +* +* Desc: debug main function +* +* Ret: void +* +* File: debug.c +* +*/ +void debug_rt() +{ + register int jj,kk; + int ii; + int otherAsciiOutLen=0; + int localAsciiOutLen=0; + struct debug_module_struct *module_ptr; + //int i; + + + if(Init_Page) + { + if( disp_sub_module_flag == ('n' - 'a') ) // in debug_module + { + + //receive the ascii out buffer of debug module + module_ptr = (struct debug_module_struct *) &debug_shm_ptr->module_d['n'-'a']; + if (module_ptr->ascii_out_set_flag == 1) + { + if (debug_ascii_out_ph < debug_ascii_out_pt) + otherAsciiOutLen = MAX_ASCII_LEN - 1 + debug_ascii_out_ph - debug_ascii_out_pt; + else + otherAsciiOutLen = debug_ascii_out_ph - debug_ascii_out_pt; + + if (ascii_out_ph < ascii_out_pt) + localAsciiOutLen = MAX_ASCII_LEN - 1 + ascii_out_ph - ascii_out_pt; + else + localAsciiOutLen = ascii_out_ph - ascii_out_pt; + if ((otherAsciiOutLen > 0) && (otherAsciiOutLen+localAsciiOutLen < MAX_ASCII_LEN)) + { + kk = ascii_out_ph; + for (jj = 0;jj < otherAsciiOutLen;jj ++) + { + ascii_out_array[kk] = *(module_ptr->ascii_out+debug_ascii_out_pt); + kk = (kk + 1) % MAX_ASCII_LEN; + debug_ascii_out_pt=(debug_ascii_out_pt+1) % MAX_ASCII_LEN; + } + ascii_out_ph = kk % MAX_ASCII_LEN; + } + else if((localAsciiOutLen+MAX_SEND_CHAR_NUM 0)) + { + kk = ascii_out_ph; + for (jj = 0;jj < MAX_SEND_CHAR_NUM;jj ++) + { + ascii_out_array[kk] = *(module_ptr->ascii_out+debug_ascii_out_pt); + kk = (kk + 1) % MAX_ASCII_LEN; + debug_ascii_out_pt=(debug_ascii_out_pt+1) % MAX_ASCII_LEN; + } + ascii_out_ph = kk % MAX_ASCII_LEN; + } + + } + //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 15 + //a b c d e f g h i j k l m n o p q r s t u v w x y z + //a b c d e f g h i j k l m n o p r s t u v w y z + if(debug_cfg == 0 && Init_Page==2) // in debug cmm status, receive the ascii out buffer of all the other modules + { + for(ii=0;ii< MODULE_COUNT;ii++) + { + if(ii=='l'-'a' || ii=='a'-'a') + continue; + module_ptr = (struct debug_module_struct *) &debug_shm_ptr->module_d[ii]; + if (module_ptr->ascii_out_set_flag == 1) + { + otherAsciiOutLen=strlen((char *)module_ptr->ascii_out)+strlen(module_ptr->name)+5; + if (disp_sub_module_flag != ii) + { + + if (ascii_out_ph < ascii_out_pt) + localAsciiOutLen = MAX_ASCII_LEN - 1 + ascii_out_ph - ascii_out_pt; + else + localAsciiOutLen = ascii_out_ph - ascii_out_pt; + if ((otherAsciiOutLen > (strlen(module_ptr->name)+5)) && (otherAsciiOutLen+localAsciiOutLen < MAX_ASCII_LEN)) + { + + ascii_out_array[ascii_out_ph] = '\r'; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + ascii_out_array[ascii_out_ph] = '\n'; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + ascii_out_array[ascii_out_ph] = '['; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + for (jj = 0;jj < strlen(module_ptr->name);jj ++) + { + ascii_out_array[ascii_out_ph] = module_ptr->name[jj]; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + } + ascii_out_array[ascii_out_ph] = ']'; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + ascii_out_array[ascii_out_ph] = ':'; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + ascii_out_array[ascii_out_ph] = '\r'; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + ascii_out_array[ascii_out_ph] = '\n'; + ascii_out_ph = (ascii_out_ph + 1) % MAX_ASCII_LEN; + + kk = ascii_out_ph; + for (jj = 0;jj < otherAsciiOutLen;jj ++) + { + ascii_out_array[kk] = module_ptr->ascii_out[jj]; + module_ptr->ascii_out[jj] = '\0'; + kk = (kk + 1) % MAX_ASCII_LEN; + } + ascii_out_ph = kk % MAX_ASCII_LEN; + } + } + } + + } + } + } + else + { + for (ii = 0;ii < MODULE_COUNT;ii ++) // not in debug_module + { + module_ptr = (struct debug_module_struct *) &debug_shm_ptr->module_d[ii]; + if (module_ptr->ascii_out_set_flag == 1) + { + otherAsciiOutLen = strlen((char *)module_ptr->ascii_out); + if (disp_sub_module_flag == ii) + { + if (ascii_out_ph < ascii_out_pt) + localAsciiOutLen = MAX_ASCII_LEN - 1 + ascii_out_ph - ascii_out_pt; + else + localAsciiOutLen = ascii_out_ph - ascii_out_pt; + if ((otherAsciiOutLen > 0) && (otherAsciiOutLen+localAsciiOutLen < MAX_ASCII_LEN)) + { + kk = ascii_out_ph; + for (jj = 0;jj < otherAsciiOutLen;jj ++) + { + ascii_out_array[kk] = module_ptr->ascii_out[jj]; + module_ptr->ascii_out[jj] = '\0'; + kk = (kk + 1) % MAX_ASCII_LEN; + } + ascii_out_ph = kk % MAX_ASCII_LEN; + } + } + if ((otherAsciiOutLen > 0) && (otherAsciiOutLen < DEBUG_OMCBUF_LEN-1)) + { + ii = module_ptr->seqid_h % DEBUG_SEQID_LEN; + strcpy((char *)module_ptr->omc_outbuf[ii], (char *)module_ptr->ascii_out); + if (((module_ptr->seqid_h+1)%DEBUG_SEQID_LEN) == (module_ptr->seqid_t%DEBUG_SEQID_LEN)) + if (disp_sub_module_flag == ii) + module_ptr->seqid_t = (module_ptr->seqid_t+1) % DEBUG_MAX_SEQID; + module_ptr->seqid_h = (module_ptr->seqid_h+1) % DEBUG_MAX_SEQID; + for (jj = 0;jj < otherAsciiOutLen;jj ++) + module_ptr->ascii_out[jj] = '\0'; + } + } + } + } + } + //else + // debug_mmi_log("none"); + + + // in debug_module, in the configure state, not in command mode, and there is nothing to send by serial, there is nothing received, + if ( (disp_sub_module_flag == ('n'-'a')) && (debug_cfg > 0) && (command_flag == 0) && (ascii_out_ph == ascii_out_pt) && (sendserbuf_h == sendserbuf_t) && (recserbuf_h == recserbuf_t) && (debug_cfg_end == 1) ) + { + recser_buf[recserbuf_h] = 27; // set the debug module in command mode + recserbuf_h = (recserbuf_h + 1) % SERIAL_BUF_LEN; + + } + if((disp_main_flag==0) && (first_page==1) && (command_flag == 0) && (ascii_out_ph == ascii_out_pt) && (sendserbuf_h == sendserbuf_t) && (recserbuf_h == recserbuf_t) ) + { + recser_buf[recserbuf_h] ='n'; // set the debug module in command mode + recserbuf_h = (recserbuf_h + 1) % SERIAL_BUF_LEN; + first_page = 0; + } + debug_read_serial(); + + for (ii = 0;ii < MAX_SEND_CHAR_NUM ;ii ++) + { + debug_recv_cmd(); + if(send_char_flag) + { + send_char_flag=0; + break; + } + debug_module_page(ii); + } + + debug_send_serial(); + + if(disp_sub_module_flag == ('n'-'a')) + debug_ascii_in_cmd_handle(); // handle the ascii command of the debug module + for(ii = 0;ii < 20;ii ++) + test_array[ii] = test_array[ii] + 1; + if ((t10s_flag++) >= 500) + { + t10s_flag = 0; + debug_heartbeat[4] = debug_counter; + set_status(5,7,debug_heartbeat); + } + if( wxc2_debuginfo.mmi_switch ) + { + if((t100ms_flag++) >= 1)//20 ms + { + t100ms_flag=0; + if(get_show_state==0 && list_flag==0) + { + show_all_value=0; + show_type=0; + show_expend=1; + show_range=0; + show_empty=0; + show_snmp_state=0; + } + if(t5s_flag > 250) + t5s_flag=0; + else + t5s_flag++; + debug_get_agent(); + debug_set_agent(); + //if((field_compute_state>0) && print_once==1) + // compute_field_WatchDog(); + + debug_snmp_get_rt(); // get command state machine + + debug_snmp_set_rt(); // set command state machine + if(list_flag>0 ) //&& debug_cfg_end==0 && debug_cfg==1) + { + debug_mmi_list(); + } + if(debug_remark_flag>0) + debug_mmi_remark(); + } + } + +} +//////////////////////////////End of Main//////////////////////////////// + + + +char *StrTrimCh( char *pSrc , char cTrim ); + char *StrToLower( char *pStr ); +////////////////////////////////////Shell/////////////////////////// +/* +* +* Fun: debug_ascii_in_cmd_handle +* +* Desc: handle the command in the debug_ascii_in_array and clear the debug_ascii_in_array +* +* Ret: REVOID +* +* File: debug.c +* +*/ +void debug_ascii_in_cmd_handle() +{ + BYTE cmd_valid, i; + char temp_str[256]=""; + BYTE index_len; + mib_node *find_node_ptr ; + /* + for(i=0;i<80;i++) + { + if(*(debug_ascii_in_array+i)!=' ') + for(j=i;j<80;j++) + debug_ascii_in_array[j]=debug_ascii_in_array[j+1]; + } + */ + if(snmp_agent_flag>0 && debug_cfg>0 && *debug_ascii_in_array!=0) + { + if(!debug_busy_alarm) + { + debug_ascii_out_proc("Busy : Busy now,Debug is working for ews now!\r\n"); + debug_ascii_in_array[0]='\0'; + } + debug_busy_alarm=1; + return; + }else if(snmp_agent_flag==0) + debug_busy_alarm=0; + StrToLower( (char *)debug_ascii_in_array +1 ); + if ( *debug_ascii_in_array) + { + cmd_valid = 1; + debug_ascii_in_array[79] = '\0'; + if(debug_cfg == 0) + { + if(debug_module_num != 13) + { + if(strncasecmp((char *)debug_ascii_in_array+1, "DEBUG", 5) == 0) + { + debug_module_num= 13; + debug_shm_ptr->module_d[13].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[13].ascii_in+1, "help"); + debug_color_out(BRIGHT,WHITE,BLACK,"\r\nOK\r\n");/// + return; + } + else + { + i = debug_module_num; + if(debug_shm_ptr->module_d[i].ascii_in_set_flag != 1) + { + sprintf(temp_str, "The module %s did not register\r\nFail\r\n", debug_shm_ptr->module_d[i].name);/// + debug_color_out(BRIGHT,RED,BLACK,temp_str); + return; + } + else + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1, (char *)debug_ascii_in_array+1); + strcpy(temp_str,"OK!\r\n"); + debug_color_out(BRIGHT,WHITE,BLACK,temp_str); + strcpy((char *)debug_ascii_in_array, ""); + } + return; + } + } + + for (i=0; i < MODULE_COUNT; i++) + { + if(debug_shm_ptr->module_d[i].ascii_in_set_flag == 1) + { + char module_name[10] , *chpos; + int len = strlen(debug_shm_ptr->module_d[i].name) ; + + + if( len == 0 || len > 8 ) + continue; + strcpy( module_name , debug_shm_ptr->module_d[i].name ); + StrToLower( module_name ); + if( strstr( (char *)debug_ascii_in_array+1, module_name ) != NULL ) + { + if( ( ( chpos = strstr( (char *)debug_ascii_in_array+1 , "log all" ) ) != NULL ) + ||( ( chpos = strstr( (char *)debug_ascii_in_array+1 , "log none" )) != NULL ) + ||( ( chpos = strstr( (char *)debug_ascii_in_array+1 , "log error" )) != NULL ) + ||( ( chpos = strstr( (char *)debug_ascii_in_array+1 , "log status" )) != NULL ) ) + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1,chpos ); + strcpy(temp_str,"OK!\r\n"); + debug_color_out(BRIGHT,WHITE,BLACK,temp_str); + cmd_valid = 5; + continue; + } + else + { + if(strlen((char *)debug_ascii_in_array) > (2+strlen(debug_shm_ptr->module_d[i].name))) + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1, (char *)debug_ascii_in_array+2+strlen(debug_shm_ptr->module_d[i].name)); + strcpy(temp_str,"OK!\r\n"); + debug_color_out(BRIGHT,WHITE,BLACK,temp_str); + strcpy((char *)debug_ascii_in_array, ""); + debug_module_num = 13; + } + else + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1, "help"); + strcpy(temp_str,"OK!\r\n"); + debug_color_out(BRIGHT,WHITE,BLACK,temp_str); + strcpy((char *)debug_ascii_in_array, ""); + debug_module_num = i; + } + return; + } + } + } + } + if( cmd_valid == 5 ) + { + strcpy((char *)debug_ascii_in_array, ""); + return; + } + if (strncasecmp((char *)debug_ascii_in_array+1,"help",4) == 0) + { + debug_mmi_cmm_help(debug_ascii_in_array+5); + + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"log status",10) == 0) + { + debug_mmi_log_status(); + } + else if( strncasecmp((char *)debug_ascii_in_array+ 1 , "net cap start" ,13) == 0) + { + int ip; + char tmpStr[512]; + + strcpy( tmpStr , (char *)debug_ascii_in_array+14); + StrTrimCh(tmpStr, ' '); + ip = inet_addr(tmpStr); + if( -1 == ip ) + { + sprintf(tmpStr , "invalid Ip Addr : %s ", debug_ascii_in_array+14); + debug_color_out(BRIGHT,RED,BLACK,tmpStr); + cmd_valid = 2; + } + NcSetIP(ip); + debug_netcap_start(); + debug_color_out(BRIGHT,RED,BLACK,"net cap start!\r\n"); + } + else if( strncasecmp((char *)debug_ascii_in_array+ 1 , "net cap stop" ,12)== 0) + { + debug_netcap_stop(); + debug_color_out(BRIGHT,RED,BLACK,"net cap stop!\r\n"); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"log ",4) == 0) + { + if( debug_mmi_log((char *)debug_ascii_in_array+5) == 0) + cmd_valid = 2; + }else if(strncasecmp((char *)debug_ascii_in_array+1, "cfg", 3) == 0) + { + if( !wxc2_debuginfo.mmi_switch ) + { + debug_ascii_out_proc("[debug] : The debug MMI is not configurated!\r\n"); + cmd_valid = 3; + } + else + { + strcpy(temp_str, "log none"); + debug_log_all = 0; + for (i=0; i < MODULE_COUNT; i++) + { + if( (i != 13) && (debug_shm_ptr->module_d[i].ascii_in_set_flag == 1)) + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1,temp_str); + } + } + debug_cfg = 1; + debug_cfg_end = 1; + debug_mmi_cfg_help(" "); + index_len=9; + find_node_ptr = search_mib_node(mib_root_node, cur_oid, index_len); + if(find_node_ptr) + mib_curr_node = find_node_ptr; + else + { + debug_ascii_out_proc("[debug] : The debug can not find the system node!\r\n"); + return; + } + } + } + else if(strncasecmp((char *)debug_ascii_in_array+1, "menu", 4) == 0) + { + if( !wxc2_debuginfo.mmi_switch ) + { + debug_ascii_out_proc("[debug] : The debug MMI is not configurated!\r\n"); + cmd_valid = 3; + } + else + { + menu_curr_node=menu_root_node; + mib_curr_node=menu_curr_node->menu_oid_node; + main_menu(""); + debug_cfg = 2; + debug_cfg_end = 1 ; + } + } + + else + cmd_valid = 2;//Err + } + else if(debug_cfg == 1 ) + { + if (strncasecmp((char *)debug_ascii_in_array+1,"contents",8) == 0) + { + debug_mmi_contents((char *)debug_ascii_in_array+9); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"parent",6) == 0) + { + debug_mmi_parent(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"quit",4) == 0) + { + debug_send_char('q'); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"child ", 6) == 0) + { + debug_mmi_child((char *)debug_ascii_in_array+7); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"create", 6) == 0) + { + debug_mmi_create((char *)debug_ascii_in_array+7); + } + else if (strncmp((char *)debug_ascii_in_array+1,"delete",6) == 0) + { + debug_mmi_del((char *)debug_ascii_in_array+7); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"list", 4) == 0) + { + list_flag=1; + strcpy((char *)list_msg, (char *)debug_ascii_in_array+5); + debug_cfg_end=0; + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"save",4) == 0) + { + save_flag=2; + debug_mmi_save(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"option ", 7) == 0) + { + debug_mmi_option((char *)debug_ascii_in_array+8); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"setins ", 7) == 0) + { + debug_mmi_setins((char *)debug_ascii_in_array+8); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"set", 3) == 0) + { + if(debug_mmi_set((char *)debug_ascii_in_array+4) == 0) + { + cmd_valid = 3; //fail + debug_cfg_end = 1; + } + else + { + debug_cfg_end = 0; + cmd_valid = 4; //wait + } + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"get ", 4) == 0) + { + if(debug_mmi_get((char *)debug_ascii_in_array+5) == 0) + { + cmd_valid = 3; //fail + debug_cfg_end = 1; + } + else + { + debug_cfg_end = 0; + cmd_valid = 4; //wait + } + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"get", 3) == 0) + { + if(debug_ascii_in_array[4] != '\0') + { + cmd_valid = 2; //fail + debug_cfg_end = 1; + } + else if(debug_mmi_get_all() == 0) + { + cmd_valid = 3; //fail + debug_cfg_end = 1; + } + else + { + debug_cfg_end = 0; + cmd_valid = 4; //wait + } + } + else if (strcmp((char *)debug_ascii_in_array+1,"pwd") == 0) + { + debug_mmi_pwd(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"tree", 4) == 0) + { + /*BYTE node_layer; + if(isdigit(debug_ascii_in_array+5)) + node_layer=(BYTE)(debug_ascii_in_array+5); + */ + debug_mmi_tree(mib_curr_node, "{*}--", 3); + treehost=1; + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"cd", 2) == 0) + { + debug_mmi_cd((char *)debug_ascii_in_array+3); + } + /*else if (strncasecmp(debug_ascii_in_array+1,"ip ", 3) == 0) + { + if( debug_mmi_ip(debug_ascii_in_array+4) == 0) + cmd_valid = 3; //Fail + }*/ + else if (strncasecmp((char *)debug_ascii_in_array+1,"find host", 9) == 0) + { + debug_mmi_find_host(debug_ascii_in_array+10); + debug_mmi_show_host(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"show host", 9) == 0) + { + if( debug_mmi_show_host() ==0) + cmd_valid = 3; //Fail + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"select", 6) == 0) + { + if( debug_mmi_select_host((char *)debug_ascii_in_array+7) ==0) + cmd_valid = 3; //Fail + else + debug_mmi_show_host(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"help",4) == 0) + { + debug_mmi_cfg_help(debug_ascii_in_array+5); + } + else if (strcmp((char *)debug_ascii_in_array+1,"pwd") == 0) + { + debug_mmi_pwd(); + } + else if(strcmp((char *)debug_ascii_in_array+1,"remark") == 0) + { + debug_remark_flag=1; + debug_cfg_end=0; + } + else if(strcmp((char *)debug_ascii_in_array+1, "cmm")==0) + { + + debug_cfg = 0; + debug_cfg_end = 1; + debug_mmi_cmm_help(" "); + } + else + { + cmd_valid = 2; //Err + } + } + else if(debug_cfg==2) + { + if (strncasecmp((char *)debug_ascii_in_array+1,"contents",8) == 0) + { + debug_mmi_view(); + //debug_cfg_end=1; + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"cd",2) == 0) + { + debug_mmi_mcd((char *)debug_ascii_in_array+3); + debug_cfg_end=1; + } + else if(strcmp((char *)debug_ascii_in_array+1,"remark") == 0) + { + debug_remark_flag=1; + debug_cfg_end=0; + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"child",5) == 0) + { + debug_mmi_mcd((char *)debug_ascii_in_array+6); + debug_cfg_end=1; + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"quit",4) == 0) + { + debug_send_char('q'); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"create", 6) == 0) + { + debug_mmi_create((char *)debug_ascii_in_array+7); + } + else if (strncmp((char *)debug_ascii_in_array+1,"delete",6) == 0) + { + debug_mmi_del((char *)debug_ascii_in_array+7); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"list", 4) == 0) + { + list_flag=1; + strcpy((char *)list_msg, (char *)debug_ascii_in_array+5); + debug_cfg_end=0; + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"save",4) == 0) + { + save_flag=2; + debug_mmi_save(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"option ", 7) == 0) + { + debug_mmi_option((char *)debug_ascii_in_array+8); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"setins ", 7) == 0) + { + debug_mmi_setins((char *)debug_ascii_in_array+8); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"set", 3) == 0) + { + if(debug_mmi_set((char *)debug_ascii_in_array+4) == 0) + { + cmd_valid = 3; //fail + debug_cfg_end = 1; + } + else + { + debug_cfg_end = 0; + cmd_valid = 4; //wait + } + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"get ", 4) == 0) + { + if(debug_mmi_get((char *)debug_ascii_in_array+5) == 0) + { + cmd_valid = 3; //fail + debug_cfg_end = 1; + } + else + { + debug_cfg_end = 0; + cmd_valid = 4; //wait + } + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"get", 3) == 0) + { + if(debug_ascii_in_array[4] != '\0') + { + cmd_valid = 2; //fail + debug_cfg_end = 1; + } + else if(debug_mmi_get_all() == 0) + { + cmd_valid = 3; //fail + debug_cfg_end = 1; + } + else + { + debug_cfg_end = 0; + cmd_valid = 4; //wait + } + } + /*else if (strcmp(debug_ascii_in_array+1,"pwd") == 0) + { + debug_mmi_pwd(); + } + else if (strncasecmp(debug_ascii_in_array+1,"tree", 4) == 0) + { + BYTE node_layer; + if(isdigit(debug_ascii_in_array+5)) + node_layer=(BYTE)(debug_ascii_in_array+5); + + debug_mmi_tree(mib_curr_node, "{*}--", 3); + treehost=1; + } + */ + else if (strncasecmp((char *)debug_ascii_in_array+1,"find host", 9) == 0) + { + debug_mmi_find_host(debug_ascii_in_array+10); + debug_mmi_show_host(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"show host", 9) == 0) + { + if( debug_mmi_show_host() ==0) + cmd_valid = 3; //Fail + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"select", 6) == 0) + { + if( debug_mmi_select_host((char *)debug_ascii_in_array+7) ==0) + cmd_valid = 3; //Fail + else + debug_mmi_show_host(); + } + else if (strncasecmp((char *)debug_ascii_in_array+1,"help",4) == 0) + { + main_menu((char *)debug_ascii_in_array+5); + } + /* + else if(strcmp(debug_ascii_in_array+1,"remark") == 0) + { + debug_mmi_remark(); + }*/ + else if(strcmp((char *)debug_ascii_in_array+1, "cmm")==0) + { + + debug_cfg = 0; + debug_cfg_end = 1; + debug_mmi_cmm_help(" "); + } + else + { + cmd_valid = 2; //Err + } + } + + if (cmd_valid == 1) + { + // debug_color_out(BRIGHT,WHITE,BLACK,"OK!\r\n"); + } + else if(cmd_valid == 3)//Fail + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : Command excute fail!\r\n"); + } + else if(cmd_valid == 2) + { + sprintf(temp_str, "Error : Incorrect command: %s\r\n",debug_ascii_in_array); + debug_color_out(BRIGHT,RED,BLACK,temp_str); + } + strcpy((char *)debug_ascii_in_array, ""); + } +} // end of debug_ascii_in_cmd_handle +///////////////////////////////End of Shell////////////////////////////// + + + + + +//////////////////////////////////buffer process///////////////////// +/* +* +* Fun: debug_ascii_out_porc +* +* Desc: store the string into the out buffer,print in the telnet or pc serial port +* +* Ret: REVOID + +* File: debug.c +* +*/ + +void debug_ascii_out_proc(const char *str_ptr) +{ + int str_len,local_len; + str_len=strlen(str_ptr); + if (debug_ascii_out_ph < debug_ascii_out_pt) + local_len = MAX_ASCII_LEN - 1 + debug_ascii_out_ph - debug_ascii_out_pt;/// + else + local_len = debug_ascii_out_ph - debug_ascii_out_pt; + if( str_len>0 && (local_len + str_len) < (MAX_ASCII_LEN)) + { + while((*(debug_ascii_out_array+debug_ascii_out_ph)=*str_ptr++)) + debug_ascii_out_ph=(debug_ascii_out_ph+1)%MAX_ASCII_LEN; + } +} // debug_ascii_out_proc + +/* +void debug_ascii_out_proc(char *str_ptr) +{ + if( (strlen(debug_ascii_out_array) + strlen(str_ptr)) < (MAX_ASCII_LEN)) + strcat(debug_ascii_out_array, str_ptr); +} // debug_ascii_out_proc +*/ +/////////////////////////////////End of buffer process/////////////////////// + + + + + + + +////////////////////////////////page 0////////////////////////////// +/* +* +* Fun: debug_change_title1 +* +* Desc: show module page form module_page.txt(page=0) +* +* Ret: REVOID +* File: debug.c +* +*/ +void debug_read_main_title() +{ + FILE *fp; + int i,j,k; + int row; + char *temp_ch; + char temp_str[256]; + char top[9]="\0",tail[6]="\0",/*add_help[6]="\0",*/add_menu[6]="\0"; + char title_row[MAX_ROW][MAX_COLUMN]; + + top[0] = 0xc; + top[1] = 0x1b; + top[2] = '['; + top[3] = 'H'; + top[4] = 0x1b; + top[5] = '['; + top[6] = '2'; + top[7] = 'J'; + top[8] = '\0'; + tail[0] = 0x1b; + tail[1] = '['; + tail[2] = '0'; + tail[3] = 'm'; + tail[4] = '%'; + tail[5] = '\0'; + + //page 0 + row = 0; + if ((fp = fopen("./conf/menu_page","r")) == NULL) + { + printf("[debug] Cannot open file [menu_page].\n"); + return; + } + for (i = 0;i < MAX_ROW; i++) + { + if (feof(fp)) + break; + temp_str[0] = '\0'; + fgets(temp_str,256,fp); + if (temp_str[0] == '$') + break; + temp_ch = strchr(temp_str,0xa); + if (temp_ch != NULL) + *temp_ch = '\0'; + strcpy(title_row[row++],temp_str); + } + fclose(fp); + strcpy(title1,top); + add_menu[0] = 0x1b; + add_menu[1] = '['; + for (i = 0;i < row;i ++) + { + for (j = 0;j < PAGE_MODULE_COUNT;j ++) + { + int alph_num = j; + if( j >=22 ) alph_num = j + 2; + if( j > 15 && j < 22 ) alph_num = j + 1; + sprintf(temp_str,"%c -- ",'a'+alph_num); + temp_ch = strstr(title_row[i],temp_str); + if (temp_ch != NULL) + { + temp_ch = temp_ch + strlen(temp_str); + for (k = 0;k < DEBUG_NAME_LEN - 1;k ++) + { + if (isalpha(temp_ch[k]) || isdigit(temp_ch[k])) + debug_shm_ptr->module_d[j].name[k] = temp_ch[k]; + else + break; + } + debug_shm_ptr->module_d[j].name[k] = '\0'; + } + } + if (i < 10) + { + add_menu[2] = i+'0'; + add_menu[3] = 'H'; + add_menu[4] = '\0'; + } + else + { + add_menu[2] = i/10+'0'; + add_menu[3] = i%10+'0'; + add_menu[4] = 'H'; + add_menu[5] = '\0'; + } + strcat(title1,add_menu); + strcat(title1,title_row[i]); + } + + //page 1 + row = 0; + memset(title_row,0,MAX_ROW*MAX_COLUMN); + if ((fp = fopen("./conf/menu_page2","r")) == NULL) + { + printf("[debug] Cannot open file [menu_page].\n"); + return; + } + for (i = 0;i < MAX_ROW; i++) + { + if (feof(fp)) + break; + temp_str[0] = '\0'; + fgets(temp_str,256,fp); + if (temp_str[0] == '$') + break; + temp_ch = strchr(temp_str,0xa); + if (temp_ch != NULL) + *temp_ch = '\0'; + strcpy(title_row[row++],temp_str); + } + fclose(fp); + strcpy(title1+TITLE_CHAR,top); + add_menu[0] = 0x1b; + add_menu[1] = '['; + for (i = 0;i < row;i ++) + { + for (j = 0;j < PAGE_MODULE_COUNT;j ++) + { + int alph_num = j; + if( j >=22 ) alph_num = j + 2; + if( j > 15 && j < 22 ) alph_num = j + 1; + sprintf(temp_str,"%c -- ",'a'+alph_num); + temp_ch = strstr(title_row[i],temp_str); + if (temp_ch != NULL) + { + temp_ch = temp_ch + strlen(temp_str); + for (k = 0;k < DEBUG_NAME_LEN - 1;k ++) + { + if (isalpha(temp_ch[k]) || isdigit(temp_ch[k])) + debug_shm_ptr->module_d[j+PAGE_MODULE_COUNT].name[k] = temp_ch[k]; + else + break; + } + debug_shm_ptr->module_d[j+PAGE_MODULE_COUNT].name[k] = '\0'; + } + } + if (i < 10) + { + add_menu[2] = i+'0'; + add_menu[3] = 'H'; + add_menu[4] = '\0'; + } + else + { + add_menu[2] = i/10+'0'; + add_menu[3] = i%10+'0'; + add_menu[4] = 'H'; + add_menu[5] = '\0'; + } + strcat(title1+TITLE_CHAR,add_menu); + strcat(title1+TITLE_CHAR,title_row[i]); + } +} + +/* +* +* Fun: debug_change_title1 +* +* Desc: Add String to module page(page=0) +* +* Ret: REVOID + +* File: debug.c +* +*/ +void debug_change_title1() +{ + char ch_tmp1[14]="\0"; + int i; + DWORD title_len; + char tail[6] = "\0"; + char menu_line[TITLE_CHAR] = "\0"; + + if(disp_main_page_num >=DEBUG_MAX_PAGE) + { + return; + } + title_len=strlen(title1+TITLE_CHAR*disp_main_page_num); + if (title_len < TITLE_CHAR) + strcpy(title1_show+TITLE_CHAR*disp_main_page_num,title1+TITLE_CHAR*disp_main_page_num); + + sprintf(menu_line,"\x1b[20;20H*** %s ***\x1b[16;4H\r\n",wxc2_debuginfo.wxc2_ver); + //In current page, press 'a--p' or 'A--P' to enter selected sub module",wxc2_debuginfo.wxc2_ver); + //sprintf(menu_line+strlen(menu_line),"\x1b[17;4HIn sub module, press '0--9' and 'a--f' to turn over pages"); + //sprintf(menu_line+strlen(menu_line),"\x1b[18;4HIn sub module, press 'x' or 'X' to return menu page"); + sprintf(menu_line+strlen(menu_line),"\x1b[24;25Hsystem start time:%s\x1b[25;1Hr -- refresh\x1b[22;60H%d/%d",time_buf,disp_main_page_num+1,DEBUG_MAX_PAGE); + tail[0] = 0x1b; + tail[1] = '['; + tail[2] = '0'; + tail[3] = 'm'; + tail[4] = '%'; + tail[5] = '\0'; + for (i = 0;i < PAGE_MODULE_COUNT;i ++) + { + if (debug_shm_ptr->module_d[i+disp_main_page_num*PAGE_MODULE_COUNT].status[0] == 1) + { + ch_tmp1[0] = 0x1b; + ch_tmp1[1] = '['; + if (i < PAGE_MODULE_COUNT/2) + { + ch_tmp1[2] = (i+5)/10 + '0'; //x =?? + ch_tmp1[3] = (i+5)%10 + '0'; + } + else + { + ch_tmp1[2] = (i+5-PAGE_MODULE_COUNT/2)/10 + '0'; + ch_tmp1[3] = (i+5-PAGE_MODULE_COUNT/2)%10 + '0'; + } + ch_tmp1[4] = ';'; + if(i < PAGE_MODULE_COUNT/2) + { + ch_tmp1[5] = '2'; //y =28 + ch_tmp1[6] = '8'; + } + else + { + ch_tmp1[5] = '5'; + ch_tmp1[6] = '2'; + } + + ch_tmp1[7] = 'H'; + ch_tmp1[8] = '('; + ch_tmp1[9] = '\0'; + if ((title_len+strlen(ch_tmp1)) < TITLE_CHAR) + strpcat(title1_show+TITLE_CHAR*disp_main_page_num,&title_len,ch_tmp1); + if ((title_len+strlen(debug_shm_ptr->module_d[i+disp_main_page_num*PAGE_MODULE_COUNT].version)) < TITLE_CHAR) + strpcat(title1_show+TITLE_CHAR*disp_main_page_num,&title_len,debug_shm_ptr->module_d[i+disp_main_page_num*PAGE_MODULE_COUNT].version); + if ((title_len+1) < TITLE_CHAR) + strpcat(title1_show+TITLE_CHAR*disp_main_page_num,&title_len,")"); + } + } + if (title_len+strlen(hostip_buf) < TITLE_CHAR) + strpcat(title1_show+TITLE_CHAR*disp_main_page_num,&title_len,hostip_buf); + if (title_len+strlen(menu_line) < TITLE_CHAR) + strpcat(title1_show+TITLE_CHAR*disp_main_page_num,&title_len,menu_line); + if (title_len+strlen(tail) < TITLE_CHAR) + strpcat(title1_show+TITLE_CHAR*disp_main_page_num,&title_len,tail); + + title_pt = TITLE_CHAR*disp_main_page_num; + memset(current_timer,0,sizeof(current_timer)); +} +////////////////////////////End of Page 0////////////////////////////// + + + + + +////////////////////////////////Module Page///////////////////////// +int debug_set_response(BYTE oidlen,DWORD *oid,BYTE *data_ptr,WORD data_len) +{ + WORD temp_len; + BYTE temp_id,temp_page; + BYTE ch_m = 0x80; + WORD title_len = 0; + BYTE cancel_control[] = {0x1b,'[','0','m','%','\0'}; + + switch(oid[12]) + { + case 0: + break; + case 1: + break; + case 2: // configure + if (oid[13] > MODULE_COUNT+1 || oid[13] < 2) + return -1; + temp_id = oid[13] - 2; + if( debug_shm_ptr == NULL ) + { + printf("Wanning : Debug is not init! Here register your module to debug share memery would fail!\r\n"); + printf(" Please make assure that you function is need to inital debug or not!\r\n"); + return -1; + } + //printf("Module ID: %d regiseted! oid[14] :%ld\n", temp_id, oid[14]); + switch(oid[14]) + { + case 1: // status + if (data_len != 1) + return -1; + debug_shm_ptr->module_d[temp_id].status[0] = *data_ptr; + debug_counter += 1; + if (temp_id <= 7) + debug_heartbeat[5] |= (ch_m >> temp_id); + else + debug_heartbeat[6] |= (ch_m >> (temp_id - 8)); + ch_m = 0x80; + return 1; + break; + case 2: // module version + if (data_len > 20) + return -1; + memcpy(debug_shm_ptr->module_d[temp_id].version,data_ptr,data_len); + debug_shm_ptr->module_d[temp_id].version[data_len] = '\0'; + return strlen(debug_shm_ptr->module_d[temp_id].version); + break; + case 3: // ascii in buffer + debug_shm_ptr->module_d[temp_id].ascii_in = data_ptr; + debug_shm_ptr->module_d[temp_id].ascii_in_set_flag = 1; + return data_len; + break; + case 4: // ascii out buffer + ascii_out_len = (data_len < strlen((char *)data_ptr))?data_len:strlen((char *)data_ptr); + *(data_ptr+ascii_out_len) = '\0'; + debug_shm_ptr->module_d[temp_id].ascii_out = data_ptr; + debug_shm_ptr->module_d[temp_id].ascii_out_set_flag = 1; + return ascii_out_len; + break; + default: // display page 0 -- 15 + if (oid[14] > 20) + return -1; + temp_page = oid[14] - 5; + if (temp_page == 0) // do not fill page 0 + return -1; + switch(oid[15]) + { + case 0: + break; + case 1: // title + title_len = (data_len < strlen((char *)data_ptr))?data_len:strlen((char *)data_ptr); + if (title_len > TITLE_CHAR - 8) + break; + data_ptr[title_len] = '\0'; + strcpy(debug_shm_ptr->module_d[temp_id].page_d[temp_page].title,title_top); + strcat(debug_shm_ptr->module_d[temp_id].page_d[temp_page].title, (char *)data_ptr); + temp_len = strlen(debug_shm_ptr->module_d[temp_id].page_d[temp_page].title); + if (temp_len+strlen((char *)cancel_control) < TITLE_CHAR) + debug_shm_ptr->module_d[temp_id].page_d[temp_page].title[temp_len] = '\0'; + if (temp_len+strlen((char *)cancel_control) < TITLE_CHAR) + strcat(debug_shm_ptr->module_d[temp_id].page_d[temp_page].title, (char *)cancel_control); + return title_len; + break; + default: // line + if (oid[15] > MAX_ROW || oid[15] < 2) + return -1; + switch(oid[16]) + { + case 0: + break; + case 1: + debug_shm_ptr->module_d[temp_id].page_d[temp_page].line_d[oid[15]-2].pt_vartype = *data_ptr; + break; + case 2: + if (data_len <= 20) + debug_shm_ptr->module_d[temp_id].page_d[temp_page].line_d[oid[15]-2].length = data_len; + else + debug_shm_ptr->module_d[temp_id].page_d[temp_page].line_d[oid[15]-2].length = 20; + debug_shm_ptr->module_d[temp_id].page_d[temp_page].line_d[oid[15]-2].pointer = data_ptr; + debug_shm_ptr->module_d[temp_id].page_d[temp_page].pointer_set_flag = 1; + if (debug_shm_ptr->module_d[temp_id].maxpage < temp_page) + debug_shm_ptr->module_d[temp_id].maxpage = temp_page; + return data_len; + break; + default: + break; + } + break; + } + break; + } + break; + case 3: + break; + default: + break; + } + return -1; +} + + +/* +* +* Fun: debug_module_page +* +* Desc: set debug page(page>0) +* +* Ret: REVOID +* File: debug.c +* +*/ +void debug_module_page(int count) +{ + if (command_flag == 1) + return; + switch (disp_main_flag) + { + case 0: + switch(m_state) + { + case 0: + m_state = 1; + debug_change_title1(); + if(count>=1) + send_char_flag=1; + break; + case 1: + if (title1_show[title_pt] != '%') + { + if (debug_send_char(title1_show[title_pt])) + title_pt++; + } + else + { + debug_set_currenttime(); + SendTelnetFlag = 1; + send_char_flag=1; + } + break; + } + break; + case 1: // module flag + switch(m_state_sub_module) + { + case 0: + title_top_pt = 0; + m_state_sub_module = 1; + break; + case 1: + if (disp_page_flag == 0) + { + debug_send_string(title_top); + SendTelnetFlag = 1; + m_state_sub_module = 2; + ascii_out_ph = ascii_out_pt = 0; + send_char_flag=1; + } + else + { + m_state_sub_module = 3; + title_sub_module_pt = 0; + } + break; + case 2: // send page 0 + if (ascii_out_pt != ascii_out_ph) + { + debug_send_char(ascii_out_array[ascii_out_pt]); + ascii_out_pt = (ascii_out_pt + 1) % MAX_ASCII_LEN; + if (ascii_out_pt == ascii_out_ph) + SendTelnetFlag = 1; + } + else + send_char_flag=1; + break; + case 3: // title + if (disp_page_flag > debug_shm_ptr->module_d[disp_sub_module_flag].maxpage) + return; + if (debug_shm_ptr->module_d[disp_sub_module_flag].page_d[disp_page_flag].title[title_sub_module_pt] == '%') + { + SendTelnetFlag = 1; + m_state_sub_module = 4; + disp_index = 0; + memset(comp_disp,0xeb,500); + } + else if (debug_send_char(debug_shm_ptr->module_d[disp_sub_module_flag].page_d[disp_page_flag].title[title_sub_module_pt])) + title_sub_module_pt = (title_sub_module_pt+1)%TITLE_CHAR; + //if(count>=3) + // send_char_flag=1; + break; + case 4: + char_ptr = 0; + hex_state = 0; + disp_length = debug_shm_ptr->module_d[disp_sub_module_flag].page_d[disp_page_flag].line_d[disp_index].length; + if (debug_shm_ptr->module_d[disp_sub_module_flag].page_d[disp_page_flag].pointer_set_flag == 1) + m_state_sub_module = 5; + disp_ptr = debug_shm_ptr->module_d[disp_sub_module_flag].page_d[disp_page_flag].line_d[disp_index].pointer; + break; + case 5: + if (char_ptr == disp_length) + { + if (disp_index%3 == 0) + SendTelnetFlag = 1; + disp_index = (disp_index + 1) % 23; + m_state_sub_module = 4; + } + else + debug_disp_hex(); + break; + default: + break; + } + break; + default: + break; + } +} + +/* +* +* Fun: debug_disp_hex +* +* Desc: Set debug page show data as hex(page>0) +* +* Ret: REVOID +* File: debug.c +* +*/ +void debug_disp_hex() +{ + WORD r_no; + WORD i; + + switch(hex_state) + { + case 0: + r_no = disp_index*20 + char_ptr; + if (comp_disp[r_no] != disp_ptr[char_ptr]) + { + comp_disp[r_no] = disp_ptr[char_ptr]; + row_ptr = disp_index + 3; + col_ptr = char_ptr; + col_ptr = (col_ptr*3) + 20; + hex_state = 1; + } + else + char_ptr = char_ptr + 1; + break; + case 1: + cursor_p[2] = ascii[row_ptr/10]; + cursor_p[3] = ascii[row_ptr%10]; + cursor_p[5] = ascii[col_ptr/10]; + cursor_p[6] = ascii[col_ptr%10]; + space_counter = 0; + hex_state = 2; + break; + case 2: + if (space_counter == 8) + hex_state = 3; + else + { + if (sendserbuf_t != (sendserbuf_h + 1)) + { + debug_send_char(cursor_p[space_counter]); + space_counter = space_counter + 1; + } + } + break; + case 3: + i = disp_ptr[char_ptr]; + i = ascii[(i>>4)&0xf]; /* high bit */ + if (sendserbuf_t != (sendserbuf_h + 1)) + { + debug_send_char(i); + hex_state = 4; + } + break; + case 4: + i = disp_ptr[char_ptr]; + i = ascii[i&0xf]; + if (sendserbuf_t != (sendserbuf_h + 1)) + { + debug_send_char(i); + // SendTelnetFlag = 1; + char_ptr = char_ptr + 1; + hex_state = 0; + } + break; + default: + break; + } +} + + +void debug_set_para() +{ + DWORD object_id[20]={1,3,6,1,4,1,1373,1,3,2,3,1,2,15,1}; + BYTE data_ptr[TITLE_CHAR]; + int i,j; + BYTE agent_buf_arr[16]; + + /* object_id[0] = 1; + object_id[1] = 3; + object_id[2] = 6; + object_id[3] = 1; + object_id[4] = 4; + object_id[5] = 1; + object_id[6] = 1373; + object_id[7] = 1; + object_id[8] = 3; + object_id[9] = 2; + object_id[10] = 3; + object_id[11] = 1; //debug + object_id[12] = 2; //configuration + object_id[13] = 15; //debug module + object_id[14] = 1; + */ + data_ptr[0] = 1; + debug_set_response(13,object_id,data_ptr,1);//debug status + + object_id[14] = 2; + strcpy((char *)data_ptr,DEBUG_VERSION); + debug_set_response(13,object_id,data_ptr,strlen((char *)data_ptr));//debug name + + object_id[14] = 3; + debug_set_response(13,object_id,debug_ascii_in_array,1); + + object_id[14] = 4; + debug_set_response(13,object_id,debug_ascii_out_array,1); + + object_id[14] = 6; + object_id[15] = 1; + strcpy((char *)data_ptr,"\tDebug\tPage 01\t\tmodule status\r\ + 1 2\r\ + M0 status\r\ + M1 status\r\ + M2 status\r\ + M3 status\r\ + M4 status\r\ + M5 status\r\ + M6 status\r\ + M7 status\r\ + M8 status\r\ + M9 status\r\ + M10 status\r\ + M11 status\r\ + M12 status\r\ + M13 status\r\ + M14 status\r\ + M15 status"); + debug_set_response(14,object_id,data_ptr,strlen((char *)data_ptr));//debug title + + for (i = 0;i < MODULE_COUNT;i ++) + { + object_id[14] = 6; + object_id[15] = 2 + i; + object_id[16] = 2; + debug_set_response( 15 ,object_id, (BYTE *)debug_shm_ptr->module_d[i].status,1);//debug page 0 line 1 + } + + object_id[14] = 7; + object_id[15] = 1; + strcpy((char *)data_ptr,"\tDebug\tPage 02\t\tascii_in_flag\r\ + 1 2 3\r\ + current module\r\ + M0 ascii in flag\r\ + M1 ascii in flag\r\ + M2 ascii in flag\r\ + M3 ascii in flag\r\ + M4 ascii in flag\r\ + M5 ascii in flag\r\ + M6 ascii in flag\r\ + M7 ascii in flag\r\ + M8 ascii in flag\r\ + M9 ascii in flag\r\ + M10 ascii in flag\r\ + M11 ascii in flag\r\ + M12 ascii in flag\r\ + M13 ascii in flag\r\ + M14 ascii in flag\r\ + M15 ascii in flag"); + debug_set_response(14,object_id,data_ptr,strlen((char *)data_ptr)); + + for (i = 0;i <= MODULE_COUNT;i ++) + { + object_id[14] = 7; + object_id[15] = i + 2; + object_id[16] = 2; + if (i==0) + debug_set_response(15,object_id,&disp_sub_module_flag,1); + else + debug_set_response(15,object_id,&debug_shm_ptr->module_d[i-1].ascii_in_set_flag,1); + } + object_id[14] = 8; + object_id[15] = 1; + strcpy((char *)data_ptr,"\tDebug\tPage 03\t\tTest Page\r\ + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\r\ + line1"); + debug_set_response(14,object_id,data_ptr,strlen((char *)data_ptr));//debug page 1 line 1 title + + object_id[14] = 8; + object_id[15] = 2; + object_id[16] = 2; + debug_set_response(15,object_id,test_array,20);//debug page 2 line 1 title + /* + object_id[14] = 9; + object_id[15] = 1; + strcpy(data_ptr,"\tDebug\tPage 04\t\tascii_out_flag\r + 1 2 3\r + M0 ascii out flag\r + M1 ascii out flag\r + M2 ascii out flag\r + M3 ascii out flag\r + M4 ascii out flag\r + M5 ascii out flag\r + M6 ascii out flag\r + M7 ascii out flag\r + M8 ascii out flag\r + M9 ascii out flag\r + M10 ascii out flag\r + M11 ascii out flag\r + M12 ascii out flag\r + M13 ascii out flag\r + M14 ascii out flag\r + M15 ascii out flag"); + debug_set_response(14,object_id,data_ptr,strlen(data_ptr)); + + for (i = 0;i < MODULE_COUNT;i ++) + { + object_id[14] = 9; + object_id[15] = i + 2; + object_id[16] = 2; + debug_set_response(15,object_id,&debug_shm_ptr->module_d[i].ascii_out_set_flag,1); + } + */ + object_id[14] = 9; + object_id[15] = 1; + strcpy((char *)data_ptr,"\tDebug\tPage 05\t\tdebug_snmp_agent_buf\r\ + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\r\ + oid 10 \t\r\ + oid 11 \t\r\ + oid 12 \t\r\ + oid 13 \t\r\ + oid 14 \t\r\ + oid 15 \t\r\ + oid 16 \t\r\ + oid 17 \t\r\ + oid 18 \t\r\ + oid_len \t\r\ + cmm_state \t\r\ + result_state \t\r\ + totoal_instance\t\r\ + totoal_field \t\r\ + total_ip "); + /* + para0 in_type \t\r + para0selectid \t\r + total_select \t\r + paran in_type \t\r + paranselectid \t\r + total_select" + */ + debug_set_response(14,object_id,data_ptr,strlen((char *)data_ptr)); + object_id[14]=9; + object_id[15]=2; + object_id[16]=2; + for(j=9;j<18;j++) + { + for(i=0;i<16;i++) + { + agent_buf_arr[i]=(BYTE)debug_snmp_agent_buf[i].oid[j]; + } + debug_set_response(15,object_id,agent_buf_arr,16); + object_id[15]++; + } + for(i=0;i<16;i++) + { + agent_buf_arr[i]=debug_snmp_agent_buf[i].oid_len; + } + debug_set_response(15,object_id,agent_buf_arr,16); + object_id[15]++; + for(i=0;i<16;i++) + { + agent_buf_arr[i]=debug_snmp_agent_buf[i].cmm_state; + } + debug_set_response(15,object_id,agent_buf_arr,16); + object_id[15]++; + for(i=0;i<16;i++) + { + agent_buf_arr[i]=debug_snmp_agent_buf[i].result_state; + } + debug_set_response(15,object_id,agent_buf_arr,16); + object_id[15]++; + for(i=0;i<16;i++) + { + agent_buf_arr[i]=debug_snmp_agent_buf[i].total_instance; + } + debug_set_response(15,object_id,agent_buf_arr,16); + object_id[15]++; + for(i=0;i<16;i++) + { + agent_buf_arr[i]=debug_snmp_agent_buf[i].total_field; + } + debug_set_response(15,object_id,agent_buf_arr,16); + object_id[15]++; + for(i=0;i<16;i++) + { + agent_buf_arr[i]=debug_snmp_agent_buf[i].total_ip; + } + debug_set_response(15,object_id,agent_buf_arr,16); + object_id[15]++; + /* + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].total_field,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[0].input_type,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[0].curr_select_id,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[0].total_select ,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[1].input_type,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[1].curr_select_id,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[1].total_select ,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[debug_snmp_agent_buf[i].total_field-1].input_type,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[debug_snmp_agent_buf[i].total_field-1].curr_select_id,1); + object_id[15]++; + debug_set_response(15,object_id,&debug_snmp_agent_buf[i].param_field_arr[debug_snmp_agent_buf[i].total_field-1].total_select ,1); + object_id[15]++; + */ + +} + +/////////////////////////////End of Module Page/////////////////////////// + + + + + + +///////////////////////////////Create OID Tree////////////////////// +/* +* +* Fun: MIB_create_tree +* +* Desc: Create a new MIB tree in memory using the name of configure file which lists mib files +* +* Ret: 1: Successful; 0: Fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int MIB_create_tree(char *conf_dir, char *conf_file) +{ + FILE *fp_conf, *fp_mib; + char *temp_ch; + char file_name[256], temp_str[256]; + int i; + BYTE line_count; + mib_type_num = 0; + mib_node_index = 0; + mib_child_node_index = 0; + mib_root_node = NULL; + mib_curr_node = NULL; + memset((BYTE *)mib_nodes, 0, sizeof(mib_node) * MIB_MAX_NODES); + memset((BYTE *)mib_child_nodes, 0, sizeof(mib_child_node) * MIB_MAX_CHILD_NODES); + + strcpy(file_name, ""); + strcpy(file_name, MIB_FILES_DIR); + strcat(file_name, MIB_WRITE_TREE); + remove(file_name); + + + for(i=0;ioid_len;index++) + { + last_node_oid[index] = father_node_ptr->oid[index]; + } + next_line_flag = 1; + state = 0; + break; + } + else + { + printf("[debug] There is error in IMPORTS part.line:%d.\r\n",mib_line_count); + return 0; + } + //} + //next_line_flag =0; + //state=0; + //break; + case 2: // except "MODULE-IDENTITY" + //temp_ch = strstr(temp_str,"MODULE-IDENTITY"); + //if(temp_ch != NULL) + // { + //*temp_ch = '\0'; + pick_name(temp_str, temp_str,temp_ch); // take the first word as a the name of this module-identity + if(strlen(temp_str) == 0) + { + printf("[debug] Error: There is no module name in the line [%s].line:%d.\r\n",temp_str,mib_line_count); + return 0; + } + //printf("module name [%s].\r\nmodule_found:\r\n",temp_str); + if(MODULE_found(temp_str, fp, father_node_ptr, last_node_oid) == 1) + { + next_line_flag = 1; + state = 0; + break; + } + else + { + printf("[debug] Error: There is error in MODULE-IDENTITY part.line:%d.\r\n",mib_line_count); + return 0; + } + // } + //next_line_flag = 0; + //state = 2; + //break; + case 3: // except "OBJECT-IDENTITY" + //temp_ch = strstr(temp_str,"OBJECT-IDENTITY"); + //if(temp_ch != NULL) + //{ + //*temp_ch = '\0'; + pick_name(temp_str, temp_str,temp_ch); // take the first word as a the name of this object-identity + if(strlen(temp_str) == 0) + { + printf("[debug] Error: There is no object name in the line [%s].line:%d.\r\n",temp_str,mib_line_count); + return 0; + } + if(OBJECT_found(temp_str, fp, father_node_ptr, last_node_oid) == 1) + { + next_line_flag = 1; + state = 0; + break; + } + else + { + printf("[debug] Error: There is error in OBJECT-IDENTITY part.line:%d.\r\n",mib_line_count); + return 0; + } + //} + //next_line_flag = 0; + //state = 3; + //break; + case 4: // except "OBJECT-TYPE" + //temp_ch = strstr(temp_str,"OBJECT-TYPE"); + //if(temp_ch != NULL) + //{ + //*temp_ch = '\0'; + pick_name(temp_str, temp_str,temp_ch); // take the first word as a the name of this object-type + if(strlen(temp_str) == 0) + { + printf("[debug] Error: There is no object-type name in the line [%s].line:%d.\r\n",temp_str,mib_line_count); + return 0; + } + + //printf("type_found(temp_str: %s\r\n",temp_str); + if(TYPE_found(temp_str, fp, father_node_ptr, last_node_oid) == 1) + { + next_line_flag = 1; + state = 0; + break; + } + else + { + printf("[debug] Error: There is error in OBJECT-TYPE part.line:%d.\r\n",mib_line_count); + return 0; + } + //} + //next_line_flag=0; + //state=4; + //break; + default: + next_line_flag=0; + state=0; + break; + } + } + printf("[debug] Error: There is not word [END].line:%d.\r\n",mib_line_count); + return 0; +} /* end of BEGIN_found */ + + +/* +* +* Fun: OBJECT_found +* +* Desc: Analyze the OBJECT part and collect data after the string "OBJECT-IDENTITY" was found +* +* Ret: 1: Successful; 0: Fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int OBJECT_found(char *name, FILE *fp, mib_node *father_node_ptr, DWORD *last_node_oid) +{ + char temp_str[256]; + char temp_child_str[256]; + char *temp_ch; + DWORD size; + DWORD i; + BYTE find_module=0; + FILE *fp_conf; + char file_name[128]; + int state, next_line, found, index; + mib_node *node_ptr; + next_line=1; + state=1; + + + strcpy(file_name, ""); + strcpy(file_name, MIB_FILES_DIR); + strcat(file_name, MIB_WRITE_TREE ); + for(index=0;index<256;index++) + { + temp_str[index] = '\0'; + temp_child_str[index] = '\0'; + } + temp_ch = NULL; + + strcpy(object_data.name, ""); + object_data.ST = 0; + strcpy(object_data.DE, ""); + strcpy(object_data.RF, ""); + strcpy(object_data.father_name, ""); + strcpy(object_data.ID, ""); + + if(strlen(name) ==0) + { + printf("[debug] Error: Object name can not be NULL.line:%d.\r\n",mib_line_count); + return 0; + } + strcpy(object_data.name,name); + found=0; + + while(!feof(fp)) + { + if(next_line) + { + mib_line_count++; + if( read_line(fp,temp_str) == 0 ) + continue; + } + temp_ch = strchr(temp_str,'"'); // take the string between '"' and '"' into temp_child_str[] + if(temp_ch != NULL) + { + int index = 0; + while(temp_ch[index + 1] != '"') + { + temp_child_str[index] = temp_ch[index + 1]; + index++; + } + temp_child_str[index] = '\0'; + } + else + strcpy(temp_child_str, ""); + + switch(state) + { + case 1: // must be "STATUS" + temp_ch = strstr(temp_str, "STATUS"); + if(temp_ch != NULL) + { + if(strstr(temp_str, "current")) // fill the object_data.ST accroding to the word behind "STATUS" + { + object_data.ST = 1; + } + else + { + if(strstr(temp_str, "deprecated")) + { + object_data.ST = 2; + } + else + { + if(strstr(temp_str, "obsolete")) + { + object_data.ST = 3; + } + else + { + object_data.ST = 0; + printf("[debug] Error: Fail to collect the contents of STATUS.line:%d.\r\n",mib_line_count); + return 0; + } + } + } + found = 1; + next_line=1; + state=2; + break; + } + next_line = 1; + state = 1; + break; + case 2: // must be "DESCRIPTION" + temp_ch = strstr(temp_str,"DESCRIPTION"); + if(temp_ch != NULL) + { + take_str(temp_child_str, fp, temp_str); + if((temp_ch=strstr(temp_str,"[SubSystem_Module]"))) + { + strcpy(object_data.DE, temp_ch+18); + + find_module=1; + found = 2; + next_line=1; + state=3; + break; + + }else if(strlen(temp_str)) + { + strcpy(object_data.DE,temp_str); + found = 2; + next_line=1; + state=3; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of DESCRIPTION field.line:%d.\r\n",mib_line_count); + return 0; + } + } + next_line = 1; + state = 2; + break; + case 3: // may be "REFERENCE" + temp_ch = strstr(temp_str,"REFERENCE"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, object_data.RF) ) // take the string between '"' and '"' after "REFERENCE " into object_data.RF[] + { + next_line = 1; + found = 3; + state=4; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of the REFERENCE field.line:%d.\r\n",mib_line_count); + return 0; + } + } + next_line=0; + state = 4; + break; + case 4: // must be "::=" + temp_ch = strstr(temp_str,"::="); + if(temp_ch != NULL) + { + //printf("object_data.name: %s.\r\n",object_data.name); + if((node_ptr=create_node(temp_str, object_data.name, 0, father_node_ptr, last_node_oid)) ) // create the object nod + { + //show_node(father_node_ptr,"{ }--", 1); + //printf("\r\nmib_node_index: %d. node_name: %s.\r\n",mib_node_index, object_data.name); + if(find_module) + { + strcpy(subsys_module[gobal_module_index].name,object_data.name); + subsys_module[gobal_module_index].index=gobal_module_index; + node_ptr->module_index=gobal_module_index; + for(index=6;indexoid_len;index++) + subsys_module[gobal_module_index].oid[index-6]=node_ptr->oid[index]; + gobal_module_index++; + } + else + node_ptr->module_index=gobal_module_index-1; + if((fp_conf = fopen(file_name,"a+")) == NULL) + { + printf("[debug] Error: cannot open conf_file: [%s].\r\n",file_name); + return 0; + } + if(!strlen(object_data.DE)) + { + node_ptr->remark_ptr=NULL; + } + else + { + for(i=0;i0;i--) + if(temp_str2[i]==' ' || temp_str2[i]=='\t' || temp_str2[i]=='\n') + temp_str2[i]='\0'; + else + break; + strcpy(object_data.DE,temp_str2); + } + + size=strlen(object_data.DE); + memcpy(heap_remark_curr,object_data.DE,sizeof(char)*(size+1)); + node_ptr->remark_ptr=heap_remark_curr; + heap_remark_index+=size+1; + heap_remark_curr=heap_remark+heap_remark_index; + } + fprintf(fp_conf,"Remark: %s\r\n",node_ptr->remark_ptr); + fprintf(fp_conf,"\r\n\r\n"); + fclose(fp_conf); + return 1; + } + else + { + printf("[debug] Error: Fail to create the object nod: [%s].line:%d.\r\n",object_data.name,mib_line_count); + return 0; + } + } + default: + next_line = 1; + state = 1; + break; + } + } + + switch(found) + { + case 0: + printf("[debug] Error: Can not find STATUS field.line:%d.\r\n",mib_line_count); + break; + case 1: + printf("[debug] Error: Can not find DESCRIPTION field.line:%d.\r\n",mib_line_count); + break; + default: + printf("[debug] Error: Can not find ::= field.line:%d.\r\n",mib_line_count); + break; + } + return 0; +} /* end of OBJECT_found */ + + + + + +/* +* +* Fun: TYPE_found +* +* Desc: Analyze the TYPE part and collect data after the string "TYPE-IDENTITY" was found +* +* Ret: 1: Successful; 0: Fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int TYPE_found(char *name, FILE *fp, mib_node *father_node_ptr, DWORD *last_node_oid) +{ + char temp_str[256]; + char temp_child_str[256]; + char *temp_ch; + int state, next_line, found, index; + FILE *fp_conf; + char file_name[128]; + char access_str[32]; + mib_node *node_ptr; + mib_node *leaf_node; + mib_child_node *mib_child_node_point; + mib_node_param *mib_node_param_point; + mib_param_select *mib_param_select_point; + WORD i; + BYTE j; + next_line=1; + state=1; + i=j=0; + for(index=0;index<256;index++) + { + temp_str[index] = '\0'; + temp_child_str[index] = '\0'; + } + temp_ch = NULL; + + strcpy(type_data.name, ""); + type_data.ST = 0; + strcpy(type_data.UP, ""); + type_data.MA = 0; + type_data.SY = 0; + strcpy(type_data.DE, ""); + type_data.total_instance = 0; + strcpy(type_data.RF, ""); + strcpy(type_data.father_name, ""); + strcpy(type_data.ID, ""); + + if(strlen(name) ==0) + { + printf("[debug] Error: Type name can not be NULL.line:%d.\r\n",mib_line_count); + return 0; + } + strcpy(type_data.name,name); + + found=0; + + while(!feof(fp)) + { + if(next_line) + { + mib_line_count++; + if( read_line(fp,temp_str) == 0 ) + continue; + + } + + temp_ch = strchr(temp_str,'"'); // take the string between '"' and '"' into temp_child_str[] + if(temp_ch != NULL) + { + int index = 0; + while(temp_ch[index + 1] != '"') + { + temp_child_str[index] = temp_ch[index + 1]; + index++; + } + temp_child_str[index] = '\0'; + } + else + strcpy(temp_child_str, ""); + //printf("t_f read_line: %s. temp_child_str: %s. state= %d\r\n",temp_str, temp_child_str, state); + //printf("state=%d\r\n",state); + switch(state) + { + case 1: // must be "SYNTAX" + temp_ch = strstr(temp_str,"SYNTAX"); + if(temp_ch != NULL) + { + // fill the type_data.SY accroding to the word behind "SYNTAX" + // 1: Integer32, 2: INTEGER, 3: OCTET STRING, + // 4: OBJECT IDENTIFIER, 5: BITS, 6: IpAddress, 7: Counter32, + // 8: Gauge32, 9: TimeTicks, 10: Opaque, 11: Counter64, + // 12: Unsigned32, 13:Conceptual Tables + if(strstr(temp_str, "Integer32")) + { + type_data.ST = 1; + } + else + { + if(strstr(temp_str, "INTEGER")) + { + type_data.SY = 2; + } + else + { + if(strstr(temp_str, "OCTET") && strstr(temp_str, " STRING")) + { + type_data.SY = 3; + } + else + { + if(strstr(temp_str, "OBJECT") && strstr(temp_str, " IDENTIFIER")) + { + type_data.SY = 4; + } + else + { + if(strstr(temp_str, "BITS")) + { + type_data.SY = 5; + } + else + { + if(strstr(temp_str, "IpAddress")) + { + type_data.SY = 6; + } + else + { + if(strstr(temp_str, "Counter32")) + { + type_data.SY = 7; + } + else + { + if(strstr(temp_str, "Gauge32")) + { + type_data.SY = 8; + } + else + { + if(strstr(temp_str, "TimeTicks") && strstr(temp_str, " STRING")) + { + type_data.SY = 9; + } + else + { + if(strstr(temp_str, "Opaque")) + { + type_data.SY = 10; + } + else + { + if(strstr(temp_str, "Counter64")) + { + type_data.SY = 11; + } + else + { + if(strstr(temp_str, "Unsigned32")) + { + type_data.SY = 12; + } + else + { + if(strstr(temp_str, "Conceptual") && strstr(temp_str, " Tables")) + { + type_data.SY = 13; + } + else + { + type_data.SY = 0; + printf("[debug] Error: Fail to collect the contents of SYNTAX field.line:%d.\r\n",mib_line_count); + return 0; + } + } + } + } + } + } + } + } + } + } + } + } + } + found = 1; + next_line=1; + state=2; + break; + } + next_line = 1; + state = 1; + break; + case 2: // may be "UnitsPart" + temp_ch = strstr(temp_str,"UnitsPart"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, type_data.UP) ) // take the string between '"' and '"' after "UnitsPart " into type_data.UP[] + { + next_line=1; + state=3; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of UnitsPart field.line:%d.\r\n",mib_line_count); + return 0; + } + } + next_line = 0; + state = 3; + break; + case 3: // must be "MAX-ACCESS" + temp_ch = strstr(temp_str,"MAX-ACCESS"); + if(temp_ch != NULL) + { + // fill the type_data.MA accroding to the word behind "MAX-ACCESS" + // 0: invalid, 1: not-accessible, 2: accessible-for-notify, 3: read-only, 4: read-write, 5: read-create + if(strstr(temp_str, "not-accessible")) + { + type_data.MA = 1; + } + else + { + if(strstr(temp_str, "accessible-for-notify")) + { + type_data.MA = 2; + } + else + { + if(strstr(temp_str, "read-only")) + { + type_data.MA = 3; + } + else + { + if(strstr(temp_str, "read-write")) + { + type_data.MA = 4; + } + else + { + if(strstr(temp_str, "read-create")) + { + type_data.MA = 5; + } + else + { + if(strstr(temp_str, "write-only")) + { + type_data.MA = 6; + } + else + { + type_data.MA = 0; + printf("[debug] Error: Fail to collect the contents of MAX-ACCESS field.line:%d.\r\n",mib_line_count); + return 0; + } + } + } + } + } + } + found = 2; + next_line=1; + state = 4; + break; + } + next_line = 1; + state = 3; + break; + case 4: // must be "STATUS" + temp_ch = strstr(temp_str, "STATUS"); + if(temp_ch != NULL) + { + if(strstr(temp_str, "current")) // fill the type_data.ST accroding to the word behind "STATUS" + { + type_data.ST = 1; + } + else + { + if(strstr(temp_str, "deprecated")) + { + type_data.ST = 2; + } + else + { + if(strstr(temp_str, "obsolete")) + { + type_data.ST = 3; + } + else + { + type_data.ST = 0; + printf("[debug] Error: Fail to collect the contents of STATUS.line:%d.\r\n",mib_line_count); + return 0; + } + } + } + found = 3; + next_line=1; + state=5; + break; + } + next_line = 1; + state = 4; + break; + case 5: // must be "DESCRIPTION" + temp_ch = strstr(temp_str,"DESCRIPTION"); + if(temp_ch != NULL) + { + //printf("description: beginline:%d.\r\n",mib_line_count); + //if( take_str(temp_child_str, fp, type_data.DE) ) // take the string between '"' and '"' after "DESCRIPTION " into type_data.DE[] + //{ + /*int i=0; + // take the first word of Description into type_data.total_instance + while(type_data.DE[i] != 0xa) + { + temp_str[i] = type_data.DE[i]; + i++; + } + temp_str[i]='\0'; + type_data.total_instance = atoi(temp_str);*/ + // type_data.total_instance = 256; + //printf("description end: %s\r\n",type_data.DE); + if(!(strchr(temp_str,'"'))) + { + mib_line_count++; + read_line(fp,temp_str); + if(!(strchr(temp_str,'"'))) + { + printf("[debug] Error: There is no first quotes .line:%d.\r\n",mib_line_count); + return 0; + } + } + memset(&temp_leaf_node,0,sizeof(mib_node)); + leaf_compute_field_num=0; + if(!Analyze_Leaf_Description(fp, &temp_leaf_node)) + { + printf("[debug] Error: Fail to collect the contents of DESCRIPTION field.line:%d.\r\n",mib_line_count); + return 0; + } + mib_line_count++; + read_line(fp,temp_str); + if(!(strchr(temp_str,'"'))) + { + printf("[debug] Error: There is no second quotes.line:%d.\r\n",mib_line_count); + return 0; + } + found = 4; + next_line=1; + state=6; + break; + } + next_line = 1; + state = 5; + break; + case 6: // may be "REFERENCE" + temp_ch = strstr(temp_str,"REFERENCE"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, type_data.RF) ) // take the string between '"' and '"' after "REFERENCE" into type_data.RF + { + next_line = 1; + state=7; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of the REFERENCE field %d.line:%d.\r\n",module_data.RE_index,mib_line_count); + return 0; + } + } + next_line=0; + state = 7; + break; + case 7: // may be "INDEX" or "AUGMENTS" + temp_ch = strstr(temp_str,"INDEX"); + if(temp_ch != NULL) + { + // handle the line contenting "INDEX" + next_line = 1; + state = 8; + break; + } + else + { + temp_ch = strstr(temp_str,"AUGMENTS"); + if(temp_ch != NULL) + { + // handle the line contenting "AUGMENTS" + next_line = 1; + state = 8; + break; + } + else + { + next_line = 0; + state = 8; + break; + } + } + case 8: // must be "::=" + temp_ch = strstr(temp_str,"::="); + if(temp_ch != NULL) + { + //printf("type.::= begin: tmep_str: %s....type_data.name: %s\r\n",temp_str,type_data.name); + if( (node_ptr = create_node(temp_str, type_data.name, 0, father_node_ptr, last_node_oid)) ) // create the module node + { + mib_type_num++; + node_ptr->max_access = type_data.MA; + leaf_node=&temp_leaf_node; + node_ptr->module_index=gobal_module_index-1; + node_ptr->data_length=leaf_node->data_length; + node_ptr->total_instance=leaf_node->total_instance; + node_ptr->total_child_nodes=leaf_node->total_child_nodes; + node_ptr->enable_field_id=leaf_node->enable_field_id; + strncpy(node_ptr->init_value,leaf_node->init_value,leaf_node->data_length); + node_ptr->remark_ptr=leaf_node->remark_ptr; + for(index=0;indexchild_nodes[index]=leaf_node->child_nodes[index]; + } + if(node_save_flag==1) + { + module_save_flag[node_ptr->module_index].module_index=node_ptr->module_index; + module_save_flag[node_ptr->module_index].save_select_id=node_save_module.save_select_id; + module_save_flag[node_ptr->module_index].save_field_id=node_save_module.save_field_id; + for(i=0;i<32;i++) + module_save_flag[node_ptr->module_index].oid[i]=node_ptr->oid[i]; + module_save_flag[node_ptr->module_index].oid_len=node_ptr->oid_len; + node_save_flag=0; + if(node_ptr->max_access<4) + { + printf("[Debug] : The save command node can not right!Please check the MIB files!\r\n"); + exit(0); + } + } + + if(leaf_compute_field_num!=0) + for(i=0;iname); + fprintf(fp_conf,"Instance: %d\r\n",node_ptr->total_instance); + fprintf(fp_conf,"Length : %d\r\n",node_ptr->data_length); + fprintf(fp_conf,"Flag : %d\r\n",node_ptr->enable_field_id); + fprintf(fp_conf,"Default : %s\r\n",node_ptr->init_value); + fprintf(fp_conf,"Remark : %s\r\n",node_ptr->remark_ptr); + fprintf(fp_conf,"Field : total(%d)\r\n",node_ptr->total_child_nodes); + + switch(node_ptr->max_access) + { + case 1: + strcpy(access_str,"not-accessible"); + break; + case 2: + strcpy(access_str,"accessible-for-notify"); + break; + case 3: + strcpy(access_str,"read-only"); + break; + case 4: + strcpy(access_str,"read-write"); + break; + case 5: + strcpy(access_str,"read-create"); + break; + case 6: + strcpy(access_str,"write-only"); + break; + default: + strcpy(access_str,"access type error"); + break; + } + fprintf(fp_conf,"Access : %s",access_str); + for(i=0;itotal_child_nodes;i++) + { + mib_child_node_point=node_ptr->child_nodes[i]; + if(mib_child_node_point) + if(mib_child_node_point->child_ptr) + { + mib_node_param_point=(mib_node_param* )mib_child_node_point->child_ptr; + if(mib_node_param_point->select_total==0) + { + if(mib_node_param_point->input_ptr!=NULL) + fprintf(fp_conf,"[%d]%s\r\n {\r\n [u]%d.%d-%d.%d\r\n [u]input\r\n [v]%s\r\n }\r\n",mib_node_param_point->id+1,mib_node_param_point->name,mib_node_param_point->byte_begin,mib_node_param_point->bit_begin,mib_node_param_point->byte_end,mib_node_param_point->bit_end,field_input_type[mib_node_param_point->input_ptr->input_param_type]); + } + else + { + fprintf(fp_conf," [%d]%s\r\n {\r\n [u]%d.%d-%d.%d\r\n [u]select\r\n",mib_node_param_point->id+1,mib_node_param_point->name,mib_node_param_point->byte_begin,mib_node_param_point->bit_begin,mib_node_param_point->byte_end,mib_node_param_point->bit_end); + for(j=0;jselect_total;j++) + { + mib_param_select_point=mib_node_param_point->select_ptr[j]; + if(mib_param_select_point) + fprintf(fp_conf," [v]%d[opt]%s\r\n", mib_param_select_point->number,mib_param_select_point->description); + } + fprintf(fp_conf," }\r\n"); + } + } + } + fprintf(fp_conf,"\r\n\r\n"); + fclose(fp_conf); + return 1; + } + else + { + printf("[debug] Error: Fail to create the type nod: [%s].line:%d.\r\n",type_data.name,mib_line_count); + return 0; + } + } + next_line = 1; + state = 8; + break; + default: + next_line = 1; + state = 0; + break; + } + } + switch(found) + { + case 0: + printf("[debug] Error: Can not find SYNTAX field.line:%d.\r\n",mib_line_count); + break; + case 1: + printf("[debug] Error: Can not find MAX-ACCESS field.line:%d.\r\n",mib_line_count); + break; + case 2: + printf("[debug] Error: Can not find STATUS field.line:%d.\r\n",mib_line_count); + break; + case 3: + printf("[debug] Error: Can not find DESCRIPTION field.line:%d.\r\n",mib_line_count); + break; + default: + printf("[debug] Error: Can not find ::= field.line:%d.\r\n",mib_line_count); + break; + } + return 0; +} /* end of TYPE_found */ + + +/* +* +* Fun: IMPORTS_found +* +* Desc: Analyze the IMPORTS part and collect data after the string "IMPORTS" was found +* +* Ret: return the pointer to the father node if successful. If fail, return null pointer +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +mib_node *IMPORTS_found(FILE *fp) +{ + char temp_str[256]; + char *temp_ch; + int index, found[3] = {0,0,0}; + mib_node *father_node_ptr; + + for(index=0;index<256;index++) + temp_str[index] = '\0'; + temp_ch = NULL; + + strcpy(imports_data.father_name, ""); + strcpy(imports_data.from_file, ""); + + while(!feof(fp)) + { + mib_line_count++; + if( read_line(fp,temp_str) == 0) + continue; + //printf("read_line: %s.\r\n",temp_str); + temp_ch = strchr(temp_str,','); // skip the line contents ',' + if(temp_ch == NULL) + { + temp_ch = strstr(temp_str, "FROM"); // except a line contents "FROM" and ';' + if(temp_ch != NULL) + { + found[1] = 1; + if(strchr(temp_str, ';') != NULL) // if the line contents ';', collect the word between "FROM " and ';' + { + index=0; + temp_ch = &temp_ch[5]; + pick_first_word(temp_ch, imports_data.from_file); + temp_ch = strchr(imports_data.from_file, ';'); + if (temp_ch != NULL) + *temp_ch = '\0'; + found[2] = 1; + //printf("from_file: %s.\r\n",imports_data.from_file); + if( strlen(imports_data.father_name) ==0 ) + { + printf("[debug] Error: Can't not find name of Father_nod in IMPORTS part.line:%d.\r\n",mib_line_count); + return NULL; + } + if(mib_node_index == 0) + { + father_node_ptr = create_mib_node(imports_data.father_name, root_oid_len, root_oid, 0); + mib_curr_node = mib_root_node = father_node_ptr; + //printf("the first nod [%s]. return\r\n", imports_data.father_name); + return father_node_ptr; + } + else + father_node_ptr = find_node(mib_root_node, imports_data.father_name, 0, NULL); + return father_node_ptr; + } + } + else // take the name of the father nod into imports_data.father_name[] + { + pick_first_word(temp_str, imports_data.father_name); + //printf("father name: %s.\r\n",imports_data.father_name); + found[0] = 1; + } + } + } + if(found[0]==0) + printf("[debug] Error: Can't not find name of Father_nod in IMPORTS part.line:%d.\r\n",mib_line_count); + else if(found[1] == 0) + printf("[debug] Error: Can't not find name of Import_from_file in IMPORTS part.line:%d.\r\n",mib_line_count); + else if(found[2] == 0) + printf("[debug] Error: Can't not find end sign ';' in IMPORTS part.line:%d.\r\n",mib_line_count); + return NULL; +} // end of IMPORTS_found + + +/* +* +* Fun: MODULE_found +* +* Desc: Analyze the MODULE part and collect data after the string "MODULE-IDENTITY" was found +* +* Ret: 1: Successful; 0: Fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int MODULE_found(char *name, FILE *fp, mib_node *father_node_ptr, DWORD *last_node_oid) +{ + char temp_str[256]; + char temp_child_str[256]; + char *temp_ch; + int state, next_line, found, index; + WORD size; + mib_node *node_ptr; + if(strlen(name) ==0) + { + printf("[debug] Error: Module name can not be NULL.line:%d.\r\n",mib_line_count); + return 0; + } + strcpy(module_data.name,name); + found=0; + + next_line=1; + state=1; + strcpy(temp_str, ""); + strcpy(temp_child_str, ""); + temp_ch = NULL; + + strcpy(module_data.LU, ""); + strcpy(module_data.OR, ""); + strcpy(module_data.CI, ""); + strcpy(module_data.DE, ""); + for(index = 0; index < MIB_MODULE_REVISION_MAX_NUM; index++) + { + strcpy(module_data.RE[index], ""); + strcpy(module_data.RE_DE[index], ""); + } + module_data.RE_index = 0; + strcpy(module_data.father_name, ""); + strcpy(module_data.ID, ""); + + while(!feof(fp)) + { + if(next_line) + { + mib_line_count++; + if( read_line(fp,temp_str) == 0 ) + continue; + } + temp_ch = strchr(temp_str,'"'); // take the string between '"' and '"' into temp_child_str[] + if(temp_ch != NULL) + { + int index = 0; + while(temp_ch[index + 1] != '"') + { + temp_child_str[index] = temp_ch[index + 1]; + index++; + } + temp_child_str[index] = '\0'; + } + else + strcpy(temp_child_str, ""); + + //printf("module state [%d].\r\n", state); + switch(state) + { + case 1: // must be "LAST-UPDATED" + temp_ch = strstr(temp_str,"LAST-UPDATED"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, module_data.LU) ) // take the string between '"' and '"' after "LAST-UPDATED " into module_data.LA[] + { + //printf("module_data.LAST-UPDATED [%s].\r\n", module_data.LU); + found = 1; + next_line=1; + state=2; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of LAST-UPDATED field.line:%d.\r\n",mib_line_count); + return 0; + } + } + next_line = 1; + state = 1; + break; + case 2: // must be "ORGANIZATION" + temp_ch = strstr(temp_str,"ORGANIZATION"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, module_data.OR) ) // take the string between '"' and '"' after "ORGANIZATION " into module_data.OR[] + { + //printf("module_data.ORGANIZATION [%s].\r\n", module_data.OR); + found= 2; + next_line=1; + state=3; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of ORGANIZATION field.line:%d.\r\n",mib_line_count); + return 0; + } + } + next_line = 1; + state = 2; + break; + case 3: // must be "CONTACT-INFO" + temp_ch = strstr(temp_str,"CONTACT-INFO"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, module_data.CI) ) // take the string between '"' and '"' after "ORGANIZATION " into module_data.CI[] + { + //printf("module_data.CONTACT-INFO [%s].\r\n", module_data.CI); + found = 3; + next_line=1; + state=4; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of CONTACT-INFO field.line:%d.\r\n",mib_line_count); + return 0; + } + } + next_line = 1; + state = 3; + break; + case 4: // must be "DESCRIPTION" + temp_ch = strstr(temp_str,"DESCRIPTION"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, module_data.DE) ) // take the string between '"' and '"' after "DESCRIPTION " into module_data.DE[] + { + //printf("module_data.DESCRIPTION [%s].\r\n", module_data.DE); + found = 4; + next_line=1; + state=5; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of DESCRIPTION field.line:%d.\r\n",mib_line_count); + return 0; + } + } + next_line = 1; + state = 4; + break; + case 5: // may be "REVISION" + temp_ch = strstr(temp_str,"REVISION"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, module_data.RE[module_data.RE_index]) ) // take the string between '"' and '"' after "REVISION " into module_data.RE[RE_index] + { + //printf("module_data.REVISION(index) [%s](%d).\r\n", module_data.RE[module_data.RE_index], module_data.RE_index); + next_line = 1; + found = 5; + state=6; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of the REVISION field %d.line:%d.\r\n",module_data.RE_index,mib_line_count); + return 0; + } + } + next_line=0; + state = 7; + break; + case 6: // must be "DESCRIPTION" which belong to the nearest "REVISION" + temp_ch = strstr(temp_str,"DESCRIPTION"); + if(temp_ch != NULL) + { + if( take_str(temp_child_str, fp, module_data.RE_DE[module_data.RE_index]) ) // take the string between '"' and '"' after "DESCRIPTION " into module_data.RE_DE[RE_index] + { + //printf("module_data.REVISION.DESCRIPTION(index) [%s](%d).\r\n", module_data.RE_DE[module_data.RE_index], module_data.RE_index); + module_data.RE_index = (module_data.RE_index + 1) % MIB_MODULE_REVISION_MAX_NUM; + next_line = 1; + found = 6; + state=5; + break; + } + else + { + printf("[debug] Error: Fail to collect the contents of DESCRIPTION field of the REVISION field: %d.line:%d.\r\n",module_data.RE_index,mib_line_count); + return 0; + } + } + next_line = 1; + state = 6; + break; + case 7: // must be "::=" + temp_ch = strstr(temp_str,"::="); + if(temp_ch != NULL) + { + //printf("entering create_node().line:%d.\r\n",mib_line_count); + if( (node_ptr=create_node(temp_str, module_data.name, 0, father_node_ptr, last_node_oid))) // create the module nod + { + if(!strlen(module_data.DE)) + { + node_ptr->remark_ptr=NULL; + return 1; + } + else + { + size=strlen(module_data.DE); + memcpy(heap_remark_curr,module_data.DE,sizeof(char)*(size+1)); + node_ptr->remark_ptr=heap_remark_curr; + heap_remark_index+=size+1; + heap_remark_curr=heap_remark+heap_remark_index; + } + return 1; + } + else + { + printf("[debug] Error: Fail to create the module nod: [%s].line:%d.\r\n",module_data.name,mib_line_count); + return 0; + } + } + default: + next_line = 1; + state = 0; + break; + } + } + switch(found) + { + case 0: + printf("[debug] Error: Can not find LAST-UPDATED field.line:%d.\r\n",mib_line_count); + break; + case 1: + printf("[debug] Error: Can not find ORGANIZATION field.line:%d.\r\n",mib_line_count); + break; + case 2: + printf("[debug] Error: Can not find CONTACT-INFO field.line:%d.\r\n",mib_line_count); + break; + case 3: + printf("[debug] Error: Can not find DESCRIPTION field.line:%d.\r\n",mib_line_count); + break; + case 5: + printf("[debug] Error: Can not find the DESCRIPTION of REVISION field.line:%d.\r\n",mib_line_count); + break; + default: + printf("[debug] Error: Can not find ::= field.line:%d.\r\n",mib_line_count); + break; + } + return 0; +} /* end of MODULE_found */ + + +/* +* +* Fun: Analyze_Description +* +* Desc: Analyze leaf node Description script in the mib script +* +* Ret: 0 err 1 successfull +* +* File: debug.c +* +*/ +int Analyze_Leaf_Description(FILE *fp, mib_node *leaf_node) +{ + BYTE unit_start_flag, + remark_start_flag, + select_start_flag, + field_start_flag, + new_line=0, + leaf_state, + field_state, + i, + j; + char instance_str[5], + default_str[256], + length_str[4], + data_arr[512], + temp_str[128], + *temp_ch, + *p; + WORD total_instance, + pos_arr[4], + length, + size; + mib_child_node *mib_child_node_ptr = NULL; + mib_param_select *mib_param_select_ptr = NULL; + mib_param_input *mib_param_input_ptr = NULL; + mib_node_param *mib_node_param_ptr = NULL; + + unit_start_flag=remark_start_flag=select_start_flag=field_start_flag=0; + leaf_node->enable_field_id=0xFF; + leaf_state=0; + field_state=0; + while(!feof(fp)) + { + if(leaf_state==10) + { + printf("[Debug] Error: Script error.The field segment error.Line: %d.\r\n", mib_line_count); + return 0; + } + if((leaf_state<=5 && field_start_flag==0) || ((remark_start_flag==1)&& leaf_state>=8)) + { + mib_line_count++; + memset(data_arr,0,512*sizeof(char)); + if( read_line(fp,data_arr) == 0 ) + continue; + + } + new_line=0; + switch (leaf_state) + { + case 0: + temp_ch = strstr(data_arr, "[Begin]"); + if(temp_ch != NULL) + leaf_state = 1; + else + leaf_state = 10; + break; + case 1: + temp_ch = strstr(data_arr, "Instance"); + if(temp_ch != NULL) + { + temp_ch+=8; + for(i=0;i MAX_TOTAL_INSTANCE) + { + printf + ("[Debug] Error: script error.The max instance number is %d.line:%d.\r\n", + MAX_TOTAL_INSTANCE, mib_line_count); + return 0; + } + leaf_node->total_instance = total_instance; + leaf_state = 2; + break; + } + } + leaf_state = 10; + break; + case 2: + temp_ch = strstr(data_arr, "Length"); + if(temp_ch != NULL) + { + temp_ch+=6; + for(i=0;i MAX_NODE_PACKET_LENGTH) + { + printf + ("[Debug] Error: script error.The max data length is %d. line:%d.\r\n", + MAX_NODE_PACKET_LENGTH, + mib_line_count); + return 0; + } + leaf_node->data_length = length; + leaf_state = 3; + break; + } + } + leaf_state = 10; + break; + case 3: + temp_ch = strstr(data_arr, "Default"); + if(temp_ch != NULL) + { + temp_ch+=7; + for(i=0;i 256 && (test_str(default_str,1))) + { + printf("[Debug] Error: script error.The max default value length is 256.Line: %d.\r\n", mib_line_count); + return 0; + } + memset(leaf_node->init_value,0,256*sizeof(char)); + AsciiToRbcd ((BYTE *)leaf_node->init_value, default_str, strlen(default_str)); + leaf_node->init_value[leaf_node->data_length]='\0'; + leaf_state = 5; + break; + } + leaf_state=10; + break; + case 5: + temp_ch = strstr(data_arr, "Flag"); + if(temp_ch != NULL) + { + temp_ch+=4; + if((temp_ch=strstr(data_arr, "E")) ) + { + leaf_state=6; + break; + } + else if((temp_ch=strstr(data_arr, "S"))) + { + leaf_state=7; + break; + } + else leaf_state=10; + } + field_start_flag=1; + leaf_state=4; + break; + case 6: + temp_ch++; + if(*temp_ch=='\0') + { + printf("[Debug] Error: script error.The enable Flag format is not right.Line: %d.\r\n", mib_line_count); + return 0; + } + strcpy(temp_str,temp_ch); + leaf_node->enable_field_id=atoi(temp_ch)-1; + leaf_state=4; + break; + case 7: + temp_ch++; + i=0; + while(*(temp_ch+i)!='\0') + { + if(*(temp_ch+i)=='.') + break; + if(!isdigit(*(temp_ch+i))) + { + printf("[Debug] Error: script error.The save Flag format is not right.Line: %d.\r\n", mib_line_count); + return 0; + } + i++; + } + if(*(temp_ch+i)=='\0') + { + printf("[Debug] Error: script error.The save Flag format is not right.Line: %d.\r\n", mib_line_count); + return 0; + } + node_save_flag=1; + strncpy(temp_str,temp_ch,i); + temp_str[i]='\0'; + temp_ch=temp_ch+i+1; + node_save_module.save_field_id=atoi(temp_str); + strcpy(temp_str,temp_ch); + if(!(test_str(temp_str,0)) ) + { + printf("[Debug] Error: script error.The save Flag format is not right.Line: %d.\r\n", mib_line_count); + return 0; + } + node_save_module.save_select_id=atoi(temp_str); + leaf_state=4; + break; + case 4: + field_start_flag=0; + if(unit_start_flag==0) + { + temp_ch = strstr(data_arr, "Field"); + if(temp_ch != NULL) + { + temp_ch = strstr(data_arr, "["); + if(temp_ch != NULL) + { + field_state = 1; + } + else + { + field_state=0; + temp_ch=data_arr; + } + } + else + { + leaf_state = 10; + break; + } + unit_start_flag=1; + } + else if(field_state!=1 && (temp_ch=strstr(data_arr,"Remark"))!=NULL) + { + printf("[Debug] Error: The field is not over! line:%d.\r\n",mib_line_count); + return 0; + } + else + temp_ch=data_arr; + p=temp_ch; + while(*p != '\0') + { + if(field_state==13) + { + printf("[Debug] Error: Script error.The field segment error.Line: %d.\r\n", mib_line_count); + return 0; + } + if((strstr(p,"Remark")!=NULL) && (strstr(p,":"))!=NULL) + { + leaf_state=8; + break; + } + if(new_line==1) + break; + switch (field_state) + { + case 0: //idle + field_state = 1; + new_line=1; + break; + case 1: //meet the "[" + if(select_start_flag==1) + { + temp_ch=strstr(p,"}"); + if(temp_ch != NULL) + { + field_state=7; + break; + } + } + temp_ch = strstr(p, "["); + if(temp_ch != NULL) + { + p = temp_ch + 1; + if(isdigit(*p)) + { + field_state = 2; + break; + } + else if(*p == 'i' || *p == 'I') + { + field_state = 3; + break; + } + else if(*p == 'u' || *p == 'U') + { + field_state = 4; + break; + } + else if(*p == 'v' || *p == 'V') + { + field_state = 5; + break; + } + } + field_state = 13; + break; + case 2: //meet the "[num" + // p--; + i = strcspn(p, "]"); + if(i != 0) + { + strncpy(temp_str, p, i); + temp_str[i]='\0'; + del_space(temp_str,2); + if((test_str(temp_str,0)) && strlen(temp_str)<4) + { + p=p+i+1; + if(*p=='\0') + { + printf("[debug] : Script Error. There is no field name.Line: %d.\r\n", mib_line_count); + return 0; + } + if (mib_node_param_index >= MIB_MAX_NODE_PARAMS) + { + printf("[debug] : Script Error. There is no field have been alloced in the memery.Line: %d.\r\n", mib_line_count); + return 0; + } + mib_node_param_ptr = &mib_node_param_array[mib_node_param_index++]; + strcpy( mib_node_param_ptr->name, p); + if(atoi(temp_str)>0) + mib_node_param_ptr->id =(BYTE)(atoi(temp_str)-1); + else + { + printf("[Debug] : The field id start from 1!line:%d.\r\n",mib_line_count); + return 0; + } + //leaf_node->total_child_nodes++; + mib_node_param_ptr->parent_ptr=leaf_node; + if (!(mib_child_node_ptr = create_mib_child_node(mib_node_param_ptr->name, leaf_node->total_child_nodes))) + { + printf("[debug] Error: Faile to Create child nod.id:%s,name:%s.line:%d\r\n", temp_str,p,mib_line_count); + return 0; + } + if (!register_child_node(leaf_node, mib_child_node_ptr)) + { + printf("[debug] Error: Fail to register the child nod id:%s,name:%s..line:%d.\r\n",temp_str,p,mib_line_count); + return 0; + } + mib_child_node_ptr->child_ptr = mib_node_param_ptr; + + field_state=6; + new_line=1; + break; + } + } + field_state = 13; + break; + case 3: //meet the "[I" + p++; + i = strcspn(p, "]"); + if(i != 0) + { + strncpy(temp_str, p, i); + temp_str[i]='\0'; + p+=i+1; + i = 0; + while(temp_str[i] != '\0') + { + if(!isdigit(temp_str[i])) + break; + i++; + } + if(i == strlen(temp_str) && atoi(temp_str)<256) + { + j=atoi(temp_str)-1; + + } + else + { + printf("[debug] Error: The field id is not right.line:%d.\r\n",mib_line_count); + return 0; + } + if(*p!='\0') + strcpy(temp_str,p); + else + { + printf("[debug] Error: There field name is not right.line:%d.\r\n",mib_line_count); + return 0; + } + if(create_compute_field(fp,leaf_node,j,temp_str)==0) + { + field_state=13; + break; + } + field_state=1; + leaf_compute_field_num++; + new_line=1; + break; + } + field_state = 13; + break; + case 4: //meet the "[u" + temp_ch=strstr(data_arr, "[u]select"); + if(temp_ch!=NULL) + { + field_state = 8; + break; + } + temp_ch=strstr(data_arr, "[u]input"); + if(temp_ch!=NULL) + { + field_state = 9; + break; + } + temp_ch=strstr(data_arr,"]"); + if(temp_ch!=NULL) + if(isdigit(temp_ch[1])) + { + p=temp_ch; + field_state=10; + break; + } + field_state=13; + break; + case 5: //meet the "[v" + if(strncasecmp(mib_node_param_ptr->name,"Reserved",strlen("Reserved"))==0 && strcmp(p,"{")) + { + field_state=7; + break; + } + temp_ch=strstr(p,"]"); + if(temp_ch!=NULL) + { + if(isdigit(*(temp_ch+1))) + field_state=12; + else + field_state=11; + break; + } + field_state=13; + break; + case 6: //meet the "{" + temp_ch=strstr(p,"{"); + field_state=1; + new_line=1; + break; + case 7: //meet the "}" + temp_ch=strstr(p,"}"); + field_state=1; + new_line=1; + break; + case 8: //meet the "[u]select" + field_state=5; + new_line=1; + break; + case 9: //meet the "[u]input" + field_state=5; + new_line=1; + break; + case 10: //meet the "[u]00.0-10.0" + p++; + for(i=0,j=0;i<4;i++) + { + while(*p!='\0') + { + if(*(p+j)=='.' || *(p+j)=='-') + break; + j++; + } + strncpy(temp_str,p,j); + temp_str[j]='\0'; + pos_arr[i]=atoi(temp_str); + p+=j+1; + j=0; + } + + mib_node_param_ptr->byte_begin=pos_arr[0]; + mib_node_param_ptr->bit_begin=pos_arr[1]; + mib_node_param_ptr->byte_end=pos_arr[2]; + mib_node_param_ptr->bit_end=pos_arr[3]; + field_state=1; + new_line=1; + break; + case 11: //meet the "[v]keepHex-low-E" + if (mib_param_input_index >= MIB_MAX_PARAM_INPUTS) + { + printf("[debug] Error: There are not enough mib_param_inputs in the array.line:%d.\r\n",mib_line_count); + return 0; + } + mib_param_input_ptr = &mib_param_input_array[mib_param_input_index++]; + mib_node_param_ptr->input_ptr = mib_param_input_ptr; + strcpy(temp_str,data_arr); + if(strstr(temp_str, "toDec-high-0")) + { + mib_param_input_ptr->input_param_type = TODEC_HIGH_0; + } + else + { + if(strstr(temp_str, "keepHex-high-0")) + mib_param_input_ptr->input_param_type = KEEPHEX_HIGH_0; + else + { + if(strstr(temp_str, "keepHex-low-0")) + mib_param_input_ptr->input_param_type = KEEPHEX_LOW_0; + else + { + if(strstr(temp_str, "keepHex-low-E")) + mib_param_input_ptr->input_param_type = KEEPHEX_LOW_E; + else + { + if(strstr(temp_str, "keepHex-low-F")) + mib_param_input_ptr->input_param_type = KEEPHEX_LOW_F; + else + { + if(strstr(temp_str, "toAscii-low-0")) + mib_param_input_ptr->input_param_type = TOASCII_LOW_0; + else + { + if(strstr(temp_str, "keepAsc-low-F")) + mib_param_input_ptr->input_param_type = KEEPASC_LOW_F; + else + { + printf("[debug] Error: There is not input param like %s.line:%d.\r\n",temp_str,mib_line_count); + return 0; + } + } + } + } + } + } + } + field_state=7; + new_line=1; + break; + case 12: //meet the "[v]1[opt]Spare" + mib_param_select_ptr = &mib_param_select_array[mib_param_select_index++]; + mib_node_param_ptr->select_ptr[mib_node_param_ptr->select_total++] = mib_param_select_ptr; + temp_ch=strtok(data_arr,"[]"); //'V' + temp_ch=strtok(NULL,"[]"); //'1' + for(i=0;inumber = (BYTE)atoi(temp_ch); + } + else + { + field_state=13; + break; + } + temp_ch=strtok(NULL,"[]"); //'opt' + temp_ch=strtok(NULL,"[]"); //'Spare' + if(temp_ch!=NULL) + strcpy(mib_param_select_ptr->description, temp_ch); + else + printf("[Debug] : There is no select option .line:%d.\r\n",mib_line_count); + select_start_flag=1; + field_state=1; + new_line=1; + break; + } + //if(*p!='\0') + // p++; + } + break; + case 8: + i=0; + if(remark_start_flag==0) + { + temp_ch = strstr(data_arr, "Remark"); + + if(temp_ch != NULL) + { + temp_ch+=6; + for(i=0;iremark_ptr=NULL; + leaf_state=1; + break; + } + else + strcpy(temp_str,temp_ch+i); + } + else + leaf_state=10; + } + else + { + if(strstr(data_arr,"[End]")==NULL) + strcpy(temp_str,data_arr); + else + { + remark_start_flag=0; + leaf_state=9; + break; + } + } + strcat(temp_str,"\n"); + /* + if(strlen(temp_str)>0) + { + for(i=strlen(temp_str)-1;i>0;i--) + { + if(temp_str[i]==' ' || temp_str[i]=='\n') + temp_str[i]='\0'; + else + break; + } + } + */ + size=strlen(temp_str); + if(remark_start_flag==1) + strcat(leaf_node->remark_ptr,temp_str); + else + memcpy(heap_remark_curr,temp_str,sizeof(char)*(size+1)); + if(remark_start_flag==0) + leaf_node->remark_ptr=heap_remark_curr; + heap_remark_index+=size+1; + heap_remark_curr=heap_remark+heap_remark_index; + remark_start_flag=1; + //strcpy(father_node_ptr->remark, temp_str); + break; + case 9: + temp_ch = strstr(data_arr, "[End]"); + if(temp_ch != NULL) + { + + return 1; + } + else + leaf_state = 10; + break; + } + } + return 1; +} + + + + +/* +* +* Fun: analyze_setTemplate +* +* Desc: analyze the text of the setTemplate field, create and register field nods to the father nod which father_nod_ptr points to +* +* Ret: successful: 1, fail: 0 +* +* Notes: Wang Jian add +* +* File: debug.c +* + +int analyze_setTemplate(FILE *fp, mib_node *father_node_ptr) +{ + char temp_str[1024*6], *temp_ch, stop_ch[32], temp_ch_2; + int state = 0,i; + DWORD size; + mib_child_node *mib_child_node_ptr = NULL; + mib_param_select *mib_param_select_ptr = NULL; + mib_param_input *mib_param_input_ptr = NULL; + mib_node_param *mib_node_param_ptr = NULL; + fpos_t pos_3; + + strcpy(stop_ch , "["); + while(!feof(fp)) + { + read_until(fp, temp_str, stop_ch); + if(mib_node_param_ptr) + { + if(temp_str[strlen(temp_str)-3]=='#' && temp_str[strlen(temp_str)-2]=='*' && temp_str[strlen(temp_str)-1]=='#') + { + father_node_ptr->enable_field_id=mib_node_param_ptr->id-1;//remember the param id + //remember the enable select id,no need ,default is 1 or 0 + } + if(temp_str[strlen(temp_str)-3]=='#' && temp_str[strlen(temp_str)-2]=='#' && temp_str[strlen(temp_str)-1]=='*') + {//remmember the param id and the save select id + module_save_flag[father_node_ptr->module_index].module_index=father_node_ptr->module_index; + module_save_flag[father_node_ptr->module_index].save_field_id=father_node_ptr->total_child_nodes; + //father_node_ptr->max_access=4; + module_save_flag[father_node_ptr->module_index].save_select_id=mib_node_param_ptr->select_total; + for(i=0;i<32;i++) + module_save_flag[father_node_ptr->module_index].oid[i]=father_node_ptr->oid[i]; + module_save_flag[father_node_ptr->module_index].oid_len=father_node_ptr->oid_len; + } + } + //printf("setTem state: %d , temp_str: %s\r\n",state,temp_str); + switch(state) + { + case 0: // name of the father node, not save, not null + strcpy(stop_ch , "]"); + state = 1; + break; + case 1: // find unit or remark + if( strstr(temp_str, "remark") != NULL ) + { + strcpy(stop_ch,";"); + state = 18; + } + else if( strstr(temp_str, "unit") != NULL ) + { + strcpy(stop_ch,"["); + state = 2; + } + else + { + printf("[debug] Error: Fail to find [unit] or [remark] in the setTemplate.\r\n"); + return 0; + } + break; + case 2: // apply a mib_node_param and fill its name + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the field name after the string [unit] in the setTemplate.\r\n"); + return 0; + } + if (mib_node_param_index >= MIB_MAX_NODE_PARAMS) + { + printf("[debug] Error: There are not enough mib_node_param in the array.\r\n"); + return 0; + } + mib_node_param_ptr = &mib_node_param_array[mib_node_param_index++]; + strcpy( mib_node_param_ptr->name, temp_str); + mib_node_param_ptr->id = (BYTE)(father_node_ptr->total_child_nodes+1); + mib_node_param_ptr->parent_ptr=father_node_ptr; + if (!(mib_child_node_ptr = create_mib_child_node(temp_str, father_node_ptr->total_child_nodes+1))) + { + printf("[debug] Error: Faile to Create child nod: [%s].\r\n", temp_str); + return 0; + } + if (!register_child_node(father_node_ptr, mib_child_node_ptr)) + { + printf("[debug] Error: Fail to register the child nod which named [%s].\r\n",temp_str); + return 0; + } + mib_child_node_ptr->child_ptr = mib_node_param_ptr; + + strcpy(stop_ch,"]"); + state = 3; + break; + case 3: + if( strstr(temp_str, "u") == NULL ) + { + printf("[debug] Error: Fail to find [%s] after [%s] in the setTemplate.\r\n", "u", "unit"); + return 0; + } + strcpy(stop_ch,"."); + state = 4; + break; + case 4: + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the byte_begin in the setTemplate.\r\n"); + return 0; + } + mib_node_param_ptr->byte_begin = (BYTE)atoi(temp_str); + strcpy(stop_ch,"-"); + state = 5; + break; + case 5: + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the bit_begin in the setTemplate.\r\n"); + return 0; + } + mib_node_param_ptr->bit_begin = (BYTE)atoi(temp_str); + strcpy(stop_ch,"."); + state = 6; + break; + case 6: + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the byte_end in the setTemplate.\r\n"); + return 0; + } + mib_node_param_ptr->byte_end = (BYTE)atoi(temp_str); + strcpy(stop_ch,"["); + state = 7; + break; + case 7: + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the bit_end in the setTemplate.\r\n"); + return 0; + } + mib_node_param_ptr->bit_end = (BYTE)atoi(temp_str); + strcpy(stop_ch,"]"); + state = 8; + break; + case 8: + if( strstr(temp_str, "u") == NULL ) + { + printf("[debug] Error: Fail to find [%s] after [%s] in the setTemplate.\r\n", "u", "u"); + return 0; + } + strcpy(stop_ch,"["); + state = 9; + break; + case 9: // meet "select" or "input" + if( strstr(temp_str, "select") != NULL ) + state = 10; + else + { + if( strstr(temp_str, "input") != NULL ) + { + state = 15; + } + else + { + printf("[debug] Error: Fail to find [%s] or [%s] in the setTemplate.\r\n", "select", "input"); + return 0; + } + } + strcpy(stop_ch,"]"); + break; + case 10: // "v" or "remark" or "unit" + if( strstr(temp_str, "v") != NULL ) + { + strcpy(stop_ch,"["); + state = 11; + } + else + { + if( strstr(temp_str, "unit") != NULL ) + { + strcpy(stop_ch,"["); + state = 2; + } + else + { + if( strstr(temp_str, "remark") != NULL ) + { + strcpy(stop_ch, ";"); + // may meet "[uint]" or a ';', so must handle the whole remark field and then find "[unit]" or ';' + state = 18; + } + else + { + printf("[debug] Error: Fail to find [%s] or [%s] or [%s] in the setTemplate.\r\n", "v", "unit", "remark"); + return 0; + } + } + } + break; + case 11: + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the select number in the setTemplate.\r\n"); + return 0; + } + if(mib_param_select_index >= MIB_MAX_PARAM_SELECTS) + { + printf("[debug] Error: There are not enough mib_param_selects in the array.\r\n"); + return 0; + } + mib_param_select_ptr = &mib_param_select_array[mib_param_select_index++]; + mib_node_param_ptr->select_ptr[mib_node_param_ptr->select_total++] = mib_param_select_ptr; + mib_param_select_ptr->number = (BYTE)atoi(temp_str); + strcpy(stop_ch,"]"); + state = 12; + break; + case 12: + if( strstr(temp_str, "opt") == NULL ) + { + printf("[debug] Error: Fail to find [%s] after [%s] in the setTemplate.\r\n", "opt", "v"); + return 0; + } + strcpy(stop_ch,"["); + + fgetpos(fp, &pos_3); + while(!feof(fp)) + { + temp_ch_2 = fgetc(fp); + if(temp_ch_2 == '[') + { + strcpy(stop_ch,"["); + break; + } + else if(temp_ch_2 == ';') + { + strcpy(stop_ch,";"); + break; + } + } + fsetpos(fp, &pos_3); + + state = 13; + break; + case 13: + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the description of the select option in the setTemplate.\r\n"); + return 0; + } + if( (temp_ch=strchr(temp_str, 0xd)) != NULL ) + *temp_ch = '\0'; + if( (temp_ch=strchr(temp_str, 0xa)) != NULL ) + *temp_ch = '\0'; + strcpy(mib_param_select_ptr->description, temp_str); + if(stop_ch =="[") + strcpy(stop_ch,"]"); + else + { + strcpy(stop_ch,";"); + return 1; + } + state = 10; + break; + case 15: // has meet "input" + if( strstr(temp_str, "v") == NULL ) + { + printf("[debug] Error: Fail to find [%s] after [%s] in the setTemplate.\r\n", "v", "input"); + return 0; + } + state = 16; + strcpy(stop_ch,"["); + break; + case 16: + if (mib_param_input_index >= MIB_MAX_PARAM_INPUTS) + { + printf("[debug] Error: There are not enough mib_param_inputs in the array.\r\n"); + return 0; + } + mib_param_input_ptr = &mib_param_input_array[mib_param_input_index++]; + mib_node_param_ptr->input_ptr = mib_param_input_ptr; + + if(strstr(temp_str, "toDec-high-0")) + { + mib_param_input_ptr->input_param_type = TODEC_HIGH_0; + } + else + { + if(strstr(temp_str, "keepHex-high-0")) + mib_param_input_ptr->input_param_type = KEEPHEX_HIGH_0; + else + { + if(strstr(temp_str, "keepHex-low-0")) + mib_param_input_ptr->input_param_type = KEEPHEX_LOW_0; + else + { + if(strstr(temp_str, "keepHex-low-E")) + mib_param_input_ptr->input_param_type = KEEPHEX_LOW_E; + else + { + if(strstr(temp_str, "keepHex-low-F")) + mib_param_input_ptr->input_param_type = KEEPHEX_LOW_F; + else + { + if(strstr(temp_str, "toAscii-low-0")) + mib_param_input_ptr->input_param_type = TOASCII_LOW_0; + else + { + if(strstr(temp_str, "keepAsc-low-F")) + mib_param_input_ptr->input_param_type = KEEPASC_LOW_F; + else + { + printf("[debug] Error: There is not input param like %s.\r\n",temp_str); + return 0; + } + } + } + } + } + } + } + strcpy(stop_ch,"]"); + state = 17; + break; + case 17: + if( strstr(temp_str, "unit") != NULL ) + { + strcpy(stop_ch,"["); + state = 2; + } + else + { + if( strstr(temp_str, "remark") != NULL ) + { + strcpy(stop_ch, ";"); + // may meet "[uint]" or a ';', so must handle the whole remark field and then find "[unit]" or ';' + state = 18; + } + else + { + printf("[debug] Error: Fail to find [%s] or [%s] in the setTemplate.\r\n", "unit", "remark"); + return 0; + } + } + break; + case 18: + if(strlen(temp_str) == 0) + { + father_node_ptr->remark_ptr=NULL; + return 1; + } + else + { + while((temp_ch = strstr(temp_str, "\n")) != NULL) + { + temp_ch[0] = ' '; + } + while((temp_ch = strstr(temp_str, "

")) != NULL) + { + temp_ch[0] = '\n'; + temp_ch[1] = ' '; + temp_ch[2] = ' '; + temp_ch[3] = '\r'; + temp_ch[4] = ' '; + temp_ch[5] = ' '; + temp_ch[6] = ' '; + temp_ch[7] = ' '; + } + while((temp_ch = strstr(temp_str, "
")) != NULL) + { + temp_ch[0] = ' '; + temp_ch[1] = ' '; + temp_ch[2] = ' '; + temp_ch[3] = ' '; + } + size=strlen(temp_str); + memcpy(heap_remark_curr,temp_str,sizeof(char)*(size+1)); + father_node_ptr->remark_ptr=heap_remark_curr; + heap_remark_index+=size+1; + heap_remark_curr=heap_remark+heap_remark_index; + //strcpy(father_node_ptr->remark, temp_str); + return 1; + } + } + } + printf("[debug] Error: There is an Error in the state %d in the setTemplate.\r\n", state); + return 0; +} // end of analyze_setTemplate + + +* +* Fun: MIB_create_leaves +* +* Desc: Create the leaves of the MIB tree in memory using the name of configure file which lists mib files +* +* Ret: 1: Successful; 0: Fail +* +* Notes: Wang Jian add +* +* File: debug.c +* + +int MIB_create_leaves(char *conf_dir, char *sysConf_file, char *param_list_file) +{ + FILE *fp_list, *fp_param; + char ch, file_name[256], temp_str[256],out_text[32], temp_str_2[DEBUG_OMCBUF_LEN]; + DWORD OID[32]; + int obj_num, oid_len, state, index, Disable; + fpos_t pos_1, pos_2; + mib_node *grand_node_ptr, *father_node_ptr; + mib_child_node *mib_child_node_ptr; + int module_index,i; + char total_instance[4]; + + mib_node_param_index = 0; + mib_param_select_index = 0; + mib_param_input_index = 0; + + memset((BYTE *)mib_param_select_array, 0, sizeof(mib_param_select) * MIB_MAX_PARAM_SELECTS); + memset((BYTE *)mib_param_input_array, 0, sizeof(mib_param_input) * MIB_MAX_PARAM_INPUTS); + memset((BYTE *)mib_node_param_array, 0, sizeof(mib_node_param) * MIB_MAX_NODE_PARAMS); + grand_node_ptr = NULL; + father_node_ptr = NULL; + + strcpy(temp_str, ""); + strcpy(temp_str_2, ""); + + strcpy(file_name, ""); + strcpy(file_name, conf_dir); + strcat(file_name, param_list_file); + + if((fp_list = fopen(file_name, "r")) == NULL) + { + printf("[debug] Error: cannot open param_list_file: [%s].\n",file_name); + return 0; + } + + while(!feof(fp_list)) + { + strcpy(file_name, ""); + strcpy(file_name, conf_dir); + strcpy(temp_str, ""); + if( read_line(fp_list, temp_str) == 0) + continue; + + if(!( (strstr(temp_str, "OBJ_")) && (strstr(temp_str, "_paramConf.csv"))) ) + { + strcpy(temp_str, "OBJ_***_paramConf.csv"); + printf("[debug] Error: The name of a mib_param_file should like %s, the * presents digit. \nAnd we need the digit to find the OID prefix of this file.\n",temp_str); + fclose(fp_list); + return 0; + } + + for(index = 4; (index < 7) && (temp_str[index] != '_'); index++) + { + temp_str_2[index - 4] = temp_str[index]; + } + temp_str_2[index - 4] = '\0'; + i=0; + while(i256) + { + printf("the max init value long is 256!\r\n"); + printf(father_node_ptr->name); + strcpy(temp_str_2,""); + for(i=0;i<32;i++) + { + printf("%ld.",father_node_ptr->oid[i]); + strcat(temp_str_2,out_text); + } + printf("oid:%s\n",temp_str_2); + strcpy(temp_str_2,""); + printf("length:%d\n",strlen(temp_str)); + printf("OBJ_%d_param.cvs\r\nstring:",obj_num); + printf(temp_str); + return 0; + } + } + state++; + break; + case 14: + fgetpos(fp_param, &pos_1); + state++; + break; + case 19: + //printf("state: %d. ",state); + for(index=0;index<10;index++) + { + read_until(fp_param, temp_str, ";"); + OID[oid_len + index] = atoi(temp_str); + //printf("%ld. ",OID[oid_len + index]); + if(OID[oid_len + index] == 0) + break; + } + read_until(fp_param, temp_str, ";"); + read_until(fp_param, temp_str, "\n");//0x0a + if(Disable==0) // used + { + fgetpos(fp_param, &pos_2); + + fsetpos(fp_param, &pos_1); + if(fgetc(fp_param) != ';') + { + fsetpos(fp_param, &pos_1); + + father_node_ptr = search_mib_node(grand_node_ptr, OID, oid_len + index); + if( father_node_ptr == NULL ) + { + int length = oid_len + index; + printf("[debug] Error: can not find the father node whose oid is %d",(int)OID[0]); + for(index = 1; index < length; index ++) + printf(".%d",(int)OID[index]); + printf("\ngrand_father->name: %s, OID= %d",grand_node_ptr->name, (int)grand_node_ptr->oid[0]); + for(index = 1; index < grand_node_ptr->oid_len; index ++) + printf(".%d",(int)grand_node_ptr->oid[index]); + printf("\n"); + for(index=0; indextotal_child_nodes; index++) + { + mib_child_node_ptr=grand_node_ptr->child_nodes[index]; + if(mib_child_node_ptr) + printf("oid: %d, name: %s\n", (int)mib_child_node_ptr->oid,grand_node_ptr->child_nodes[index]->name); + } + fclose(fp_param); + fclose(fp_list); + return 0; + } + else + { + if(strlen(total_instance)) + father_node_ptr->total_instance=atoi(total_instance); + else + father_node_ptr->total_instance=0; + strcpy(father_node_ptr->init_value,curr_instance_value); + father_node_ptr->module_index=module_index; + if(analyze_setTemplate(fp_param, father_node_ptr) != 1) + { + printf("analyze_setTemplate2 fail.\n"); + fclose(fp_param); + fclose(fp_list); + return 0; + } + } + } + fsetpos(fp_param, &pos_2); + } + state = 0; + break; + default: + ch = fgetc(fp_param); + if( ch == ';' ) + state++; + break; + } + } + if(state == 0) + fclose(fp_param); + else + { + printf("[debug] Error: There is an error in the mib_param_file %s.\n", file_name); + fclose(fp_param); + fclose(fp_list); + return 0; + } + } + fclose(fp_list); + return 1; +}// end of MIB_create_leaves +*/ + + + + +/* +* +* Fun: create_node +* +* Desc: create and register node using the given parameters +* +* Ret: successful: 1, fail: 0 +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +mib_node *create_node(char *line, char *nod_name, int instance, mib_node *father_ptr, DWORD *last_node_oid) +{ + mib_node *mib_node_ptr, *father_node_ptr; + mib_child_node *mib_child_node_ptr; + char *tmp_ch, father_name[64], id[32]; + DWORD ID_c=0, curr_oid[32]; + int index , curr_oid_len; + FILE *fp_conf; + char file_name[128]; + char space[32]="-> ";; + + strcpy(file_name, ""); + + strcpy(file_name, MIB_FILES_DIR); + strcat(file_name, MIB_WRITE_TREE ); + + if((fp_conf = fopen(file_name,"a+")) == NULL) + { + printf("[debug] Error: cannot open conf_file: [%s].\r\n",file_name); + return 0; + } + + strcpy(father_name, ""); + strcpy(id, ""); + //fprintf(fp_conf,"line = [%s], nod_name = [%s].\r\n",line , nod_name); + tmp_ch = strchr(line, '}'); // collect the father_name and nod's ID from the line + if(tmp_ch != NULL) + { + tmp_ch = strchr(line, '{'); + if(tmp_ch != NULL) + { + tmp_ch = &tmp_ch[1]; + tmp_ch = pick_first_word(tmp_ch, father_name); + if( strchr(father_name, '}') ) + { + printf("[debug] Error: There is not ID between '{' and '}' in line [%s].\r\n",line); + fclose(fp_conf); + return 0; + } + pick_first_word(tmp_ch, id); + tmp_ch = strchr(id, '}'); + if(tmp_ch != NULL) + *tmp_ch = '\0'; + if(strlen(id) == 0) + { + printf("[debug] Error: There is not ID between '{' and '}' in line [%s].\r\n",line); + fclose(fp_conf); + return 0; + } + ID_c = atol(id); + + } + else + { + printf("[debug] Error: Can not find a '{' as a beginning of a text.\r\n"); + fclose(fp_conf); + return NULL; + } + } + else + { + printf("[debug] Error: Can not find a '}' as an ending of a text.\r\n"); + fclose(fp_conf); + return NULL; + } + + father_node_ptr = find_node(father_ptr, father_name, 1, last_node_oid); + if(!father_node_ptr) + { + fprintf(fp_conf,"father_ptr->name: %s , father_name: %s\r\n",father_ptr->name,father_name); + printf("[debug] Error: Can not find the father nod which named [%s].\r\n",father_name); + fclose(fp_conf); + return NULL; + } + + for(index=0; index<32; index++) + curr_oid[index] = father_node_ptr->oid[index]; + curr_oid_len = father_node_ptr->oid_len; + + curr_oid[curr_oid_len++] = ID_c; + + if(!(mib_node_ptr = create_mib_node(nod_name, curr_oid_len, curr_oid, instance))) + { + printf("[debug] Error: Create nod: [%s] fail. mib_node_index = %d.\r\n", nod_name, mib_node_index); + fclose(fp_conf); + return 0; + } + + //mib_node_ptr->module_index=gobal_module_index-1; + + fprintf(fp_conf,"Create node: %s(OID: ",nod_name); + for(index=0;index "); + // this nod is not the first nod, must register it to its father nod and itself. + if (!(mib_child_node_ptr = create_mib_child_node(nod_name, ID_c))) + { + printf("[debug] Error: Create child nod: [%s] fail.\r\n", nod_name); + fclose(fp_conf); + return NULL; + } + + if (!register_child_node(father_node_ptr, mib_child_node_ptr)) + { + printf("[debug] Error: Can not register the child nod which named [%s].\r\n",nod_name); + fclose(fp_conf); + return NULL; + } + + //fprintf(fp_conf,"register the child nod [%s].father nod name [%s] father nod total_child_nodes [%d].\r\n",nod_name,father_node_ptr->name, father_node_ptr->total_child_nodes); + for(index = 0; index< father_node_ptr->total_child_nodes; index++) + { + mib_child_node_ptr=father_node_ptr->child_nodes[index]; + if(mib_child_node_ptr) + fprintf(fp_conf,"%s %s(%d)\r\n", space,father_node_ptr->child_nodes[index]->name,index); + } + + if (!register_node(mib_node_ptr, curr_oid, curr_oid_len)) + { + printf("[debug] Error: Can not register the nod which named [%s].\r\n",nod_name); + fclose(fp_conf); + return NULL; + } + memset(last_node_oid, 0, sizeof(DWORD) * 32); + for(index =0; index < mib_node_ptr->oid_len; index++) + last_node_oid[index] = mib_node_ptr->oid[index]; + fprintf(fp_conf,"\r\n\r\n"); + fclose(fp_conf); + return mib_node_ptr; +} // end of create_node + +/* +* +* Fun: create_mib_child_node +* +* Desc: create a mib_child_node +* +* Ret: return the mib_child_node pointer if successful, return null if fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +mib_child_node *create_mib_child_node(char *name, DWORD oid) +{ + mib_child_node *mib_child_node_ptr; + + if (mib_child_node_index >= MIB_MAX_CHILD_NODES) + return NULL; + + mib_child_node_ptr = &mib_child_nodes[mib_child_node_index++]; + + strcpy(mib_child_node_ptr->name, name); + mib_child_node_ptr->oid = oid; + mib_child_node_ptr->child_ptr = NULL; + + return mib_child_node_ptr; +} // end of create_mib_child_node + + + +/* +* +* Fun: create_mib_node +* +* Desc: create a mib_node +* +* Ret: return the mib_node pointer if successful, return null if fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +mib_node *create_mib_node(char *name, BYTE oid_len, DWORD *oid, WORD total_instance) +{ + mib_node *mib_node_ptr; + if (mib_node_index >= MIB_MAX_NODES) + return NULL; + + mib_node_ptr = &mib_nodes[mib_node_index++]; + /* + index=0xFF; + if(oid_len>9) + { + memcpy(temp_oid, oid, oid_len * sizeof(DWORD)); + max_len=0; + for(j=0;subsys_module[j].index!=0xFF;j++) + { + for(i=8;subsys_module[j].oid[i-6]!=0 && i<14;i++) + if(temp_oid[i]!=subsys_module[j].oid[i-6]) + break; + if(subsys_module[j].oid[i-6]==0 && i>max_len) + { + max_len=i; + index=j; + } + } + if(index!=0xFF) + mib_node_ptr->module_index=index; + } + */ + strcpy(mib_node_ptr->name, name); + mib_node_ptr->oid_len = oid_len; + memcpy(mib_node_ptr->oid, oid, oid_len * sizeof(DWORD)); + mib_node_ptr->total_instance = total_instance; + mib_node_ptr->curr_instance = 0; + mib_node_ptr->parent_ptr = NULL; + //mib_node_ptr->mib_proc = mib_proc; + + return mib_node_ptr; +} // end of create_mib_node + + + + +int register_node(mib_node *mib_node_ptr, DWORD *oid, BYTE oid_len) +{ + mib_node *node_ptr; + mib_child_node *child_node_ptr = NULL; + BYTE i, loop_times; + WORD child_index; + + if (oid_len <= mib_root_node->oid_len) + return 0; + if ((loop_times = oid_len - mib_root_node->oid_len) >= 20) + return 0; + + node_ptr = mib_root_node; + for (i = 0; i < loop_times; i++) + { + if ((child_index = find_child_index(node_ptr, oid[mib_root_node->oid_len + i], NULL, 0)) >= MIB_MAX_CHILD_NODES_PER_NODE) + return 0; + child_node_ptr = node_ptr->child_nodes[child_index]; + if(child_node_ptr) + if (i != (loop_times - 1)) + { + if (child_node_ptr->child_ptr == NULL) + return 0; + node_ptr = (mib_node *) child_node_ptr->child_ptr; + } + } + + child_node_ptr->child_ptr = mib_node_ptr; + mib_node_ptr->parent_ptr = node_ptr; + + return 1; +} + + +/* +* +* Fun: register_child_node +* +* Desc: register a child node to its father mib node +* +* Ret: return 1 if successful, return 0 if fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int register_child_node(mib_node *mib_node_ptr, mib_child_node *mib_child_node_ptr) +{ + char text_out[128]; + int index; + mib_child_node *tmp_child_node; + if (mib_node_ptr->total_child_nodes >= MIB_MAX_CHILD_NODES_PER_NODE) + { + printf("[Debug] Error: The total child is more then the max child number.%d,MAX:%d.\r\n",mib_node_ptr->total_child_nodes,MIB_MAX_CHILD_NODES_PER_NODE); + return 0; + } + if(!mib_child_node_ptr) + { + sprintf(text_out,"[Debug] : The child node is NULL! Father:%s,ID: %d\r\n",mib_node_ptr->name,mib_node_ptr->total_child_nodes); + TxtColor(BRIGHT,RED,BLACK,text_out); + printf("%s", text_out); + return 0; + } + for (index = 0; index < mib_node_ptr->total_child_nodes; index++) + { + tmp_child_node = mib_node_ptr->child_nodes[index]; + if ( mib_child_node_ptr->oid <= tmp_child_node->oid ) + { + printf("[debug] Error: The oid have register or it is not written by ascending! Can not be Reisterted again\r\nLine: %d.\r\n", mib_line_count); + exit(1); + } + } + mib_node_ptr->child_nodes[mib_node_ptr->total_child_nodes] = mib_child_node_ptr; + mib_node_ptr->total_child_nodes++; + return 1; +}// end of register_child_node + +//////////////////////////////End of Create OID Tree////////////////////// + + + +void debug_mmi_remark() +{ + + //char out_char[16]; + char out_text[128]; + WORD out_len=0; + WORD i; + BYTE j,k,m; + BYTE line_count=0; + char ch; + switch(debug_remark_flag) + { + case 0: + return; + case 1: + if(mib_curr_node->remark_ptr==NULL) + { + debug_ascii_out_proc("Fail : Sorry,No Remark for the object!\r\n"); + return; + } + debug_ascii_out_proc("Remark : "); + for(i=0;*(mib_curr_node->remark_ptr+i);i++) + { + ch=mib_curr_node->remark_ptr[i]; + if(ch!='\n' && ch!='\t' && ch!=' ') + break; + } + if(!*(mib_curr_node->remark_ptr+i)) + { + debug_remark_flag=0; + debug_cfg_end=1; + return; + } + debug_remark_ptr=i; + debug_remark_flag=2; + debug_cfg_end=0; + remark_meet_lf=0; + break; + case 2: + if(debug_remark_ptr) + { + strcpy(out_text," "); + out_len=10; + } + else + { + strcpy(out_text," "); + out_len=3; + j=3; + } + if(remark_meet_lf) + { + j=3; + strcat(out_text," "); + out_len=13; + remark_meet_lf=0; + } + else if(debug_remark_ptr) + j=0; + i=debug_remark_ptr; + for(;*(mib_curr_node->remark_ptr+i)!='\0';i++) + { + ch=mib_curr_node->remark_ptr[i]; + if(ch!='\n' && ch!='\t') + { + *(out_text+out_len++)=ch; + j++; + } + if((ch=='\n' && i) || j==70) + { + if(ch!='\n') + { + while((ch=mib_curr_node->remark_ptr[i+1])) + { + if(ch==' ' || ch=='\t') + { + i++; + continue; + }else if(ch=='\n') + { + i++; + j=0; + continue; + } + else + break; + } + } + else + { + i++; + while((ch=*(mib_curr_node->remark_ptr+i))) + if(ch!=' ' || ch!='\n' || ch!='\t') + break; + else + i++; + if(*(mib_curr_node->remark_ptr+i)=='\0') + line_count=3; + i--; + } + + *(out_text+out_len++)='\r'; + *(out_text+out_len++)='\n'; + *(out_text+out_len)='\0'; + debug_color_out(BRIGHT,YELLOW,BLACK,out_text); + line_count++; + if(j==70) + m=10; + else + { + m=13; + remark_meet_lf=1; + } + if(line_count==3) + { + debug_remark_ptr=(mib_curr_node->remark_ptr[i]=='\n')?(i+1):i; + if(*(mib_curr_node->remark_ptr+i)=='\0') + { + debug_remark_flag=0; + debug_remark_ptr=0; + remark_meet_lf=0; + debug_cfg_end=1; + } + return; + } + *out_text='\0'; + out_len=0; + for(k=0;kremark_ptr+i)=='\0' && j!=0 && line_count<3) + debug_color_out(BRIGHT,YELLOW,BLACK,out_text); + if(!(out_text[out_len-1]=='\n' && out_text[out_len-2]=='\r')) + debug_ascii_out_proc("\r\n"); + debug_remark_flag=0; + debug_remark_ptr=0; + remark_meet_lf=0; + debug_cfg_end=1; + break; + } +} + + +void register_host() +{ + char file_name[48],temp_str[128],ch2[32],*p,*q,*m,ip[4],stop_ch[32]; + char temp_str2[32]; + FILE *fp; + BYTE i,j,state,group_index,member_index,max_group; + WORD module_index; + group_index=0; + member_index=0; + /* + strcpy(file_name, ""); + strcpy(file_name, MIB_FILES_DIR); + strcat(file_name, MIB_SYSTEM_CONFIG_FILE ); + */ + /* + if((fp = fopen(file_name, "r")) == NULL) + { + sprintf(temp_str, "Fail : cannot open system config file: [%s].\r\n",file_name); + debug_color_out(BRIGHT,RED,BLACK,temp_str); + return ; + } + strcpy(stop_ch," "); + module_index=0; + state=1; + while(!feof(fp)) + { + read_until(fp, temp_str,stop_ch); + if(strlen(temp_str)>64) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : The config file is not right format!\r\n"); + return ; + } + switch(state) + { + case 1: //get the module oid + for(i=0;i<=12;i++) //del the root_oid 6X2=1.3.6.1.4.1. + { + p=temp_str+i; + } + subsys_module[module_index].index=module_index; + i=0; + for(j=0;j<6;j++) + { + while(*(p+i)!='.' && *(p+i)!='\0') + { + oid[i]=*(p+i); + i++; + } + oid[i]='\0'; + subsys_module[module_index].oid[j]=atoi(oid); + if(*(p+i)=='\0') + break; + q=p+i+1; + p=q; + i=0; + } + state=2; + break; + case 2: //get the module name + strcpy(subsys_module[module_index].name,temp_str); + state=3; + break; + case 3://get the module obj_type_num + strcpy(subsys_module[module_index].obj_type_no,temp_str); + while((ch=fgetc(fp))!=0xa && ch!=EOF) + {} + if(ch==EOF) + break; + state=1; + module_index++; + break; + } + + } + fclose(fp); + */ + strcpy(file_name, ""); + strcpy(file_name, MIB_FILES_DIR); + strcat(file_name, MIB_SYSTEM_IP_LIST_FILE); + + if((fp = fopen(file_name, "r")) == NULL) + { + sprintf(temp_str, "Fail : cannot open system ip list file: [%s].\r\n",file_name); + debug_color_out(BRIGHT,RED,BLACK,temp_str); + return; + } + state=1; + module_index=0; + strcpy(stop_ch," "); + while(!feof(fp)) + { + read_line(fp, temp_str); + if(temp_str[0]=='/' && temp_str[1]=='/') + { + continue; + } + if(strlen(temp_str)==0) + continue; + else if(strlen(temp_str)>64) + { + printf("Error : The config file is not right format!\r\n"); + return ; + } + for(i=0;i=1) + { + for(j=i-1;j>0;j--) + { + if(temp_str[j]!=' ') + break; + } + } + strncpy(temp_str2,temp_str,j+1); + temp_str2[j+1]='\0'; + m=temp_str+i+1; + module_host[module_index].index=module_index; + strcpy(module_host[module_index].host_name,temp_str2); + for(i=0;i=1) + { + if(module_save_flag[curr_module].save_field_id==0) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : The module do not contain save flag!\r\n"); + save_flag=0; + return; + } + if(mib_curr_node->module_index!=curr_module || save_flag==2) + { + if(debug_cfg==1) + temp_mib_node=mib_curr_node; + else if(debug_cfg==2) + { + tmp_menu_node=menu_curr_node; + temp_mib_node=mib_curr_node; + } + find_node_ptr=search_mib_node(mib_root_node,module_save_flag[curr_module].oid,module_save_flag[curr_module].oid_len); + if(find_node_ptr) + mib_curr_node=find_node_ptr; + mib_child_node_ptr=mib_curr_node->child_nodes[module_save_flag[curr_module].save_field_id-1]; + if(mib_child_node_ptr) + param_node = (mib_node_param *)mib_child_node_ptr->child_ptr; + else + printf("[Debug] : The child node is NULL. Father_node:%s,ID:%d.\r\n",mib_curr_node->name,module_save_flag[curr_module].save_field_id-1); + strcpy(temp_text,"#0."); + gcvt((double)(module_save_flag[curr_module].save_field_id),2,temp_text2); + strcat(temp_text,temp_text2); + strcat(temp_text,"="); + sprintf(temp_text2,"%X",param_node->select_ptr[module_save_flag[curr_module].save_select_id-1]->number); + //gcvt((double)param_node->select_ptr[module_save_flag[curr_module].save_select_id]->number,4,temp_text2); + strcat(temp_text,temp_text2); + if(save_flag==1) + save_flag=3; + else + save_flag=4; + debug_mmi_set(temp_text); + + } + } + else + debug_color_out(BRIGHT,RED,BLACK,"Fail : No change the data ,so not need to save!\r\n"); + debug_ascii_out_proc("Status : "); + sprintf(temp_text2,"Saving the module of %s,NOW!\r\n",subsys_module[curr_module].name); + debug_color_out(BRIGHT,CYAN,BLACK,temp_text2); + +} + + +///////////////////////////////Create Menu Tree////////////////////// +int create_menu_tree(char *conf_dir,char *menu_page,mib_node *sys_node) +{ + char *p,*q,temp_str1[256],file_name[64],temp_str2[64],temp_str3[64],oid[16]; + BYTE index1,index2,sys_group,group_type;//group_type:'/' is 0,'M' is 1,'m' afer '/' is 2 + WORD index3, line_count=0; + menu_node *menu_node_ptr; + menu_node *menu_father_node; + mib_node *mib_tmp_node; + BYTE father_id[16]; + FILE *fp; + DWORD full_oid[32]; + + mib_tmp_node=search_mib_node(mib_root_node,cur_oid,9); + strcpy(file_name, ""); + strcpy(file_name, conf_dir); + strcat(file_name, menu_page); + if((fp = fopen(file_name, "r")) == NULL) + { + printf("Error: cannot open menu tree file [%s].\n",file_name); + return 0; + } + while(!feof(fp)) + { + line_count++; + if( read_line(fp,temp_str1) == 0) + continue; + if(temp_str1[0]=='#') + continue; + for(index1=0;index1name,"WXC2"); + menu_node_ptr->father_ptr=NULL; + menu_node_ptr->menu_id[0]=0; + menu_node_ptr->id_len=0; + menu_node_ptr->sys_group=9; + for(index1=0;index1<10;index1++) + menu_node_ptr->oid[index1]=0; + menu_node_ptr->menu_oid_node=search_mib_node(mib_root_node,cur_oid,9); + menu_root_node=menu_father_node=menu_node_ptr; + father_id[0]=0; + break; + } + else + { + strcpy(temp_str2,p); + q=strtok(temp_str2,"."); + index2=0; + for(index2=0;index2<16;index2++) + { + father_id[index2]=0; + } + index2=0; + father_id[index2++]=atoi(q); + while((q=strtok(NULL,"."))) + { + if(q!=NULL && isdigit(*q)) + father_id[index2++]=atoi(q); + else if(*q!='\0') + break; + } + menu_father_node=search_menu_node(menu_root_node,father_id,index2);//(BYTE)((father_id-1)/2)); + if(!menu_father_node) + { + printf("[Debug] Error: Can not find menu father node,line:%d\n",line_count); + return 0; + } + p=q; + } + } + break; + case '(' : + p++; + if(isdigit(*(p))) + { + if(group_type==0) + { + *(p+1)='\0'; + sys_group=atoi(p); + group_type=1; + *p=';'; + } + else if(group_type==1) + { + temp_str2[0]=*p; + temp_str2[1]='\0'; + menu_node_ptr->sys_group=atoi(temp_str2); + if(menu_node_ptr->sys_group==0) + { + for(index1=0;index1name);index1++) + if(menu_node_ptr->name[index1]=='_') + break; + if(index1==strlen(menu_node_ptr->name)) + { + printf("[Debug] Error: The menu item sysgroup for '8kE1' format must be '8KE1_*',line:%d\n",line_count); + return 0; + } + } + p+=2; + } + + } + break; + case 'M': + case 'm': + menu_node_ptr=&menu_nodes[menu_node_index++]; + if(menu_father_node) + menu_node_ptr->father_ptr=menu_father_node; + else + { + printf("[Debug] Error:fail to create the menu tree,id %s,line:%d\n",temp_str3,line_count); + return 0; + } + if(index3child_node[index3]=menu_node_ptr; + index3++; + menu_father_node->total_menu_child=index3; + + } + else + { + printf("The child node is more than the max number!,line:%d\n",line_count); + return 0; + } + if(*(p+1)==':') + { + p+=2; + for(index1=0;*(p+index1)!='\0';index1++) + { + if(*(p+index1)==' ') + { + break; + } + } + } + if(index1==0) + { + printf("Format is not right,eg: 'M:13 name {1.2};',line:%d\n",line_count); + return 0; + } + strncpy(temp_str2,p,index1); + temp_str2[index1]='\0'; + for(index2=0;father_id[index2]!=0;index2++) + menu_node_ptr->menu_id[index2]=father_id[index2]; + menu_node_ptr->menu_id[index2]=strtoul(temp_str2, NULL, 10); + menu_node_ptr->id_len=index2+1; + if(group_type==1) + menu_node_ptr->sys_group=sys_group; + p+=index1-1; + break; + case '[': + q=p+1; + index1=0; + while(*p!=']' && *p!='\0') + { + p++; + index1++; + } + if(*p==']') + strncpy(menu_node_ptr->name,q,index1-1); + p++; + break; + case '{': + p++; + q=p; + while(*p!='}' && *p!='\0') + { + p++; + index1++; + } + if(*p=='}') + strncpy(oid,q,index1); + p=oid; + index2=0; + for(index1=0;index1<10;index1++) + menu_node_ptr->oid[index1]=0; + index1=0; + while(*p!=';') + { + if(isdigit(*(p+index1))) + { + index1++; + continue; + } + strncpy(temp_str2,p,index1); + temp_str2[index1]='\0'; + menu_node_ptr->oid[index2++]=strtoul(temp_str2, NULL, 10); + p+=index1+1; + index1=0; + } + for(index1=0;index1<9;index1++) + full_oid[index1]=cur_oid[index1]; + for(index1=9;index1<19 && menu_node_ptr->oid[index1-9]!=0;index1++) + full_oid[index1]=(DWORD)menu_node_ptr->oid[index1-9]; + menu_node_ptr->menu_oid_node=search_mib_node(mib_tmp_node,full_oid,index1); + if(!menu_node_ptr->menu_oid_node) + { + printf("[debug] : can not find mib node ,please check oid.menu_tree.txt,line:%d\r\n",line_count); + printf("oid: "); + for(index2=0;index2Press \"Esc\" then \"Enter\"<--\r\n"); +} // end of debug_mmi_cmm_help + + +/* +* +* Fun: debug_mmi_log_status +* +* Desc: display the log status +* +* Ret: REVOID +* +* File: debug.c +* +*/ +void debug_mmi_log_status() +{ + char temp_str[256]=""; + int i; + + if(debug_log_all == 1) + strcat(temp_str, " log all\r\n"); + else + strcat(temp_str, " log none \r\n"); + if(debug_log_error_on == 1) + strcat(temp_str, " log error on\r\n"); + else + strcat(temp_str, " log error off\r\n"); + debug_ascii_out_proc(temp_str); + + strcpy(temp_str, "lot status"); + for (i=0; i < MODULE_COUNT; i++) + { + if( (i != 13) && (debug_shm_ptr->module_d[i].ascii_in_set_flag == 1)) + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1,temp_str); + } + } +} // end of debug_mmi_log_status + +/* +* +* Fun: debug_mmi_log +* +* Desc: send the log command(log_str) to all the other modules +* +* Ret: 1: succeful, 0: fail +* +* File: debug.c +* +*/ +int debug_mmi_log(char *log_str) +{ + char temp_str[128]=""; + int i; + + if( strstr(log_str, "all") != NULL ) + { + strcpy(temp_str, "log all"); + debug_log_all = 1; + } + else if( strstr(log_str, "none") != NULL ) + { + strcpy(temp_str, "log none"); + debug_log_all = 0; + } + else if( strstr(log_str, "error on") != NULL ) + { + strcpy(temp_str, "log error on"); + debug_log_error_on = 1; + } + else if( strstr(log_str, "error off") != NULL ) + { + strcpy(temp_str, "log error off"); + debug_log_error_on = 0; + } + else + return 0; + + for(i=0; i < MODULE_COUNT; i++) + { + if( (i !='n'-'a') && (debug_shm_ptr->module_d[i].ascii_in_set_flag == 1)) + { + debug_shm_ptr->module_d[i].ascii_in[0] = 1; + strcpy((char *)debug_shm_ptr->module_d[i].ascii_in+1,temp_str); + } + } + return 1; +} // end of debug_mmi_log +//////////////////////////////End of CMM Command///////////////////////// + + + + +///////////////////////////////Cfg OID Tree Command///////////////// + + +/* +* +* Fun: debug_mmi_cfg_help +* +* Desc: display the commands and their usage in the configure state +* +* Ret: RVOID +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +void debug_mmi_cfg_help(char *str) +{ + char out_text[128],*ch; + BYTE i; + for(i=0;i<80 && *(str+i)!='\0';i++) + { + if(*(str+i)!=' ') + break; + } + ch=str+i; + strcpy(out_text,ch); + if(*out_text!='\0') + { + if(strncasecmp(out_text,"help",4)==0) + { + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"help \r\n"); + debug_ascii_out_proc(" Show the cfg main page\r\n"); + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"help command\r\n"); + debug_ascii_out_proc(" Show the usage of the command\r\n"); + } + else if(strncasecmp(out_text,"cd",2)==0) + { + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd \r\n"); + debug_ascii_out_proc(" Enter the root node:enterprises oid=1.3.6.1.4.1\r\n"); + debug_ascii_out_proc(" Usage 2: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd //\r\n"); + debug_ascii_out_proc(" Enter our system node:wxc2 oid=1.3.6.1.4.1.1373.1.3\r\n"); + debug_ascii_out_proc(" Usage 3: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd ....\r\n"); + debug_ascii_out_proc(" Enter the above node untill up to the roor node,the layer to go back \r\n"); + debug_ascii_out_proc(" can control by the point number(layers=point number-1,the max point \r\n"); + debug_ascii_out_proc(" number is 8) behind the 'cd'. eg:'cd ..' enter the parent node \r\n"); + debug_ascii_out_proc(" Usage 4: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd ./XXX or ./name\r\n"); + debug_ascii_out_proc(" Enter the child node which id or name is xxx or name\r\n"); + debug_ascii_out_proc(" Usage 5: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd ./X.X.X\r\n"); + debug_ascii_out_proc(" Enter the descendant's node whose oid is x.x.x from the current oid\r\n"); + debug_ascii_out_proc(" Usage 6: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd ../X.X.X\r\n"); + debug_ascii_out_proc(" Enter the descendant's node whose oid is x.x.x from the parent oid\r\n"); + debug_ascii_out_proc(" Usage 7: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd module\r\n"); + debug_ascii_out_proc(" Enter the module's node \r\n"); + debug_ascii_out_proc(" Usage 8: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd -name\r\n"); + debug_ascii_out_proc(" Find the node as the name from the current node\r\n"); + debug_ascii_out_proc(" Usage 9: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd --name\r\n"); + debug_ascii_out_proc(" Find the node as the name from the root node \r\n"); + } + else if(strncasecmp(out_text,"get",3)==0) + { + help_cmm(1,"get or get *","Get and printf the current instance's value of the node\r\n"); + help_cmm(2,"get #XX","Get and printf the special instance's value of the node\r\n"); + help_cmm(3,"get *.X or get *.name","Get and printf the current instance's special field value of the node\r\n"); + help_cmm(4,"get #X.X or get #x.name","Get and printf the special instance's special field value of the node\r\n"); + } + else if(strncasecmp(out_text,"set",3)==0) + { + help_cmm(1,"set or set *","Set the current instance's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(2,"set #XX ","Set the special instance's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(3,"set *.X =X or set *.name=X ","Set the current instance's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(4,"set #X.X =X or set #x.name=X ","Set the special instance's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(5,"set #X =XXX","Set the special instance's whole value to given value of the node and open the isntance ,then printf\r\n"); + } + else if(strncasecmp(out_text,"create",3)==0) + { + help_cmm(1,"creat or create *","Create an instance with the min closed instance id and set it's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(2,"create #XX","Create the special instance,and set it's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(3,"create *.X =X or create *.name=X ","Create an instance's with the min closed instance id ,and set it's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(4,"create #X.X =X or create #x.name=X ","Create the special instance,and set it's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(5,"create #X =XXX","Create the special instance,and set is's whole value to given value of the node and open the isntance ,then printf\r\n"); + } + else if(strncasecmp(out_text,"delete",3)==0) + { + help_cmm(1,"delete ","Delete the current instance ,if it is opened,clost it.set the value to default value of the node\r\n"); + help_cmm(2,"delete #XX","Delete the special instance,if it is opened,clost it.set the value to default value of the node\r\n"); + } + else if(strncasecmp(out_text,"contents",3)==0) + { + help_cmm(1,"contents ","Show the information about the object .if it is parent node ,will print the name,the all child node.if it is leaf node ,will print the module,the read-write property,the type,the current instance(the mix id of the opened instance),the total instance,the all instance which are opened,and show the current isntance and all it's field .if it is parent node\r\n"); + } + else if(strncasecmp(out_text,"list",3)==0) + { + help_cmm(1,"list [-a]","the switch of show all the field and value of the instance include the 'NULL' and the closed instance,default:off\r\n"); + help_cmm(2,"list [-e]","the switch of show opened the instance,hide the field and it's value default:off\r\n"); + help_cmm(3,"list [-r]","the switch of show the field data range.default:off\r\n"); + help_cmm(4,"list [-t]","the switch of show input data type ,default:off\r\n"); + help_cmm(5,"list [-f[X XX X]]","the switch of show the special field list in the [ ] ,default:off\r\n"); + help_cmm(6,"list [X-XX]","the switch of show the instance range form x to xxx.default:off\r\n"); + } + else if(strncasecmp(out_text,"child",3)==0) + { + help_cmm(1,"child X","Enter the child node whose id is X\r\n"); + help_cmm(2,"child name","Enter the child node whose name is 'name'\r\n"); + } + else if(strncasecmp(out_text,"parent",3)==0) + { + help_cmm(1,"parent","Enter the parent node\r\n"); + } + else if(strncasecmp(out_text,"pwd",3)==0) + { + help_cmm(1,"pwd","Show the full path and the full oid\r\n"); + } + else if(strncasecmp(out_text,"remark",3)==0) + { + help_cmm(1,"remark","Show the description of the node\r\n"); + } + else if(strncasecmp(out_text,"option",3)==0) + { + help_cmm(1,"option X","Show the select option of the fied node whose id is x of leaf node \r\n"); + help_cmm(2,"option name","Show the select option of the fied node whose name is ''name' of leaf node \r\n"); + } + else if(strncasecmp(out_text,"save",3)==0) + { + help_cmm(1,"save","save the debug\r\n"); + } + else if(strncasecmp(out_text,"quit",3)==0) + { + help_cmm(1,"quit","Quit and save teh debug\r\n"); + } + else if(strncasecmp(out_text,"find host",3)==0) + { + help_cmm(1,"find host","Find all the host who have the object about the current node\r\n"); + } + else if(strncasecmp(out_text,"select",3)==0) + { + help_cmm(1,"select X","Select the host ip list,if been selected ,the set command would do effect on the host\r\n"); + } + else if(strncasecmp(out_text,"setinst",3)==0) + { + help_cmm(1,"setinst X","Set the current instance as the special number\r\n"); + } + else if(strncasecmp(out_text,"cmm",3)==0) + { + help_cmm(1,"cmm","Enter the debug cmm state\r\n"); + } + else if(strncasecmp(out_text,"addhost",3)==0) + {} + else if(strncasecmp(out_text,"delhost",3)==0) + {} + else if(strncasecmp(out_text,"tree",4)==0) + { + help_cmm(1,"tree","Print the three layer of the tree from the current node\r\n"); + } + else + { + sprintf(out_text,"Error : Sorry, No support this command %s!\r\n" ,ch); + debug_color_out(BRIGHT,RED,BLACK,out_text); + } + } + else + { + time_t tick_2; + char time_buf_2[64]= "\0", str_buf[128]="\0"; + tick_2 = time(NULL); + debug_ascii_out_proc("\033[2J\033[1;1H"); + snprintf(time_buf_2, sizeof(time_buf_2), "%.24s", ctime(&tick_2)); + sprintf(str_buf, " -----Start Time: %s----- \r\n", time_buf_2); + debug_color_out(BRIGHT,CYAN,WHITE,str_buf); + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*************************\r\n");//80-20=60/2=30 + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*"); + debug_ascii_out_proc(" "); + debug_color_out(BRIGHT,WHITE,BLACK,"Configure Help Menu");//80-20=60/2=30 + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*\r\n"); + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*************************\r\n");//80-20=60/2=30 + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc("================================================================================\r\n"); + debug_ascii_out_proc("|help : show the configure command help or main cfg menu |\r\n"); + debug_ascii_out_proc("|contents : show the contents of the current object |\r\n"); + debug_ascii_out_proc("|parent : enter the parent object of the current object |\r\n"); + debug_ascii_out_proc("|child : entr the child object of the current object |\r\n"); + debug_ascii_out_proc("|cd : go to the object use name or oid or other control char |\r\n"); + debug_ascii_out_proc("|pwd : show the current object path from the root object |\r\n"); + debug_ascii_out_proc("|tree : show the object tree from the current object node |\r\n"); + //debug_ascii_out_proc("|setins : set the instance number of the current object |\r\n"); + //debug_ascii_out_proc("|find host : find the hosts in which the current node exist. |\r\n"); + //debug_ascii_out_proc("|show host : show the hosts in which the current node exist. |\r\n"); + debug_ascii_out_proc("|select : select the host which get and set command use. |\r\n"); + debug_ascii_out_proc("|get : get the value of a paticular parameter field |\r\n"); + debug_ascii_out_proc("|set : set the value of a paticular parameter field |\r\n"); + debug_ascii_out_proc("|create : create and set the intance value of a parameter field |\r\n"); + debug_ascii_out_proc("|delete : delete an opened instance of a parameter field |\r\n"); + debug_ascii_out_proc("|cmm : change to the state of command |\r\n"); + debug_ascii_out_proc("|quit : exit the debug telnet interview |\r\n"); + debug_ascii_out_proc("================================================================================\r\n"); + } +} // end of debug_mmi_cfg_help + + + + +/* +* +* Fun: debug_mmi_cd +* +* Desc: change to a mib_node by path +* +* Ret: return 1 if successful, return 0 if fail +* +* File: debug.c +* +*/ +int debug_mmi_cd(char *path) +{ + BYTE str_len, index, index_2, index_3; + mib_node *find_node_ptr; + mib_node_param *find_node_ptr2; + DWORD OID[32]; + char temp_str[128], path_name[128], *temp_ch,temp_str2[128]; + int temp; + int i; + strcpy(path_name, path); + temp_mib_node=mib_curr_node; + for(i=0;i!=strlen(path_name);i++) + { + if(*(path+i)!=' ') + break; + } + if(*(path_name+i)=='\0') + { + index_3=6; + temp_mib_node=mib_curr_node; + mib_curr_node= mib_root_node; + if(curr_module!=mib_curr_node->module_index && save_flag==1) + debug_mmi_save(); + else + debug_mmi_contents(""); + //find_node_ptr=find_node(mib_root_node,"MTP3",0,0); + //if(find_node_ptr!=NULL) + // mib_curr_node=find_node_ptr; + + return 1; + } + temp_ch=path_name+i; + strcpy(path_name,temp_ch); + strcpy(temp_str,path_name); + for(i=0;i3) + strcpy(path_name,temp_ch+2); + } + if(!isdigit(*temp_ch)) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please input system number!\r\n"); + return 0; + } + host_group=atoi(temp_str2); + if(host_group>GROUP_NUM-1) + { + sprintf(temp_str2,"Error : Please input valid system id,the max is %d!\r\n",GROUP_NUM-1); + debug_color_out(BRIGHT,RED,BLACK,temp_str2); + return 0; + } + } + + + + + if (!(str_len = strlen(path_name))) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : The path you put is not right for current object!\r\n"); + return 0; + } + index=0; + while(path_name[index]==' ') + { + temp=index+1; + while(path_name[temp]!='\0') + { + path_name[temp-1]=path_name[temp]; + temp++; + } + path_name[temp-1]=path_name[temp]; + } + temp=0; + if(strncmp(path_name,"--",2)==0)//locate the para or node by name + { + temp=1;//find from the root node + } + else if(path_name[0]=='-') + { + temp=2;//find from the current node + } + if(temp>0) + { + if(strlen(path_name)>80) + debug_color_out(BRIGHT,RED,BLACK,"Error : no node have so long name!\r\n"); + if(temp==1) + { + mib_curr_node=mib_root_node; + strcpy(temp_str,path_name+2); + } + if(temp==2) + strcpy(temp_str,path_name+1); + find_node_ptr= find_node(mib_curr_node, temp_str, 0, NULL); + if(find_node_ptr!=NULL) + { + mib_curr_node=find_node_ptr; + if(mib_curr_node->total_instance) + { + list_once=0; + curr_module=mib_curr_node->module_index; + register_instance(); + } + if(curr_module!=mib_curr_node->module_index && save_flag==1) + debug_mmi_save(); + else + debug_mmi_contents(""); + return 1; + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : There is no the special node of the name!\r\n"); + return 0; + } + } + index=0; + if(path_name[0]=='.' && path_name[1]=='.' && path_name[2]=='\0') + { + if(curr_module!=mib_curr_node->module_index && save_flag==1) + debug_mmi_save(); + else + debug_mmi_parent(); + return 1 ; + } + while(path_name[index]=='.') + index++; + if(index>2 && path_name[index]=='\0' && index<8 ) + { + for(index_2=1;index_2oid_len-1; + if(index_3<=6) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Have reached the root!\r\n"); + debug_mmi_contents(""); + return 0; + } + mib_curr_node= search_mib_node(mib_root_node, mib_curr_node->oid, index_3); + if(mib_curr_node==mib_root_node) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : Have reached the root node!\r\n"); + return 0; + } + + } + + if(mib_curr_node->total_instance) + { + list_once=0; + curr_module=mib_curr_node->module_index; + register_instance(); + //for(i=0;i<=255;i++) + // if(curr_instance_arr[i].eable==1) + // break; + // mib_curr_node->curr_instance=i; + //debug_mmi_get_all(); + } + if(curr_module!=mib_curr_node->module_index && save_flag==1) + debug_mmi_save(); + else + debug_mmi_contents(""); + return 1; + } + else if(index>8) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Input error,the max layer number you can go back is 8.\r\n"); + return 0; + } + + if(path_name[0]=='/' && path_name[1]=='/') + { + index_3=9; + mib_curr_node= search_mib_node(mib_root_node, cur_oid, index_3); + if(curr_module!=mib_curr_node->module_index && save_flag==1) + debug_mmi_save(); + else + debug_mmi_contents(""); + return 1; + } + + if( (path_name[0] != '.') && ( !isdigit(path_name[0]) ) ) // path is module_name + { + + index_2 = strlen(path_name); + for(index=0; indexoid[index]; + index_3 = mib_curr_node->oid_len - 1; + OID[index_3] = 0; + index = 3; + } + else if( (path_name[0]== '.') && (path_name[1] == '/') ) // path is ./oid, \u5C06\u5728\u5F53\u524D\u76EE\u5F55\u4E0B\u67E5\u627Eoid\u6240\u5BF9\u5E94\u7684object + { + for(index=0; index<32; index++) + OID[index] = mib_curr_node->oid[index]; + index_3 = mib_curr_node->oid_len; + index = 2; + } + else + { + OID[0]=1; + OID[1]=3; + OID[2]=6; + OID[3]=1; + OID[4]=4; + OID[5]=1; + OID[6]=1373; + for(index=7; index<32; index++) + OID[index]=0; + index_3 = 7; + index = 0; + } + str_len = strlen(path_name); + for(index_2=0; indexparent_ptr; + if(find_node_ptr!=NULL) + { + if (find_node_ptr->total_instance) + { + if(strlen(path_name)>4) + mib_curr_node=find_node_ptr->parent_ptr; + debug_color_out(BRIGHT,RED,BLACK,"Error : Have reach the leaf node!\r\n"); + return 0; + } + else + mib_curr_node = (mib_node*)find_node_ptr2; + } + } + + if(mib_curr_node->total_instance) + { + list_once=0; + + curr_module=mib_curr_node->module_index; + register_instance(); + //for(i=0;i<=255;i++) + //{ + // if(curr_instance_arr[i].eable==1) + // break; + //} + //mib_curr_node->curr_instance=i; + //debug_mmi_get_all(); + } + //debug_ascii_out_proc("Current object changed to: "); + //debug_color_out(BRIGHT,YELLOW,BLACK,mib_curr_node->name); + //debug_ascii_out_proc("\r\n"); + if(curr_module!=mib_curr_node->module_index && save_flag==1) + debug_mmi_save(); + else + debug_mmi_contents(""); + return 1; +} // end of debug_mmi_cd + +/* +* +* Fun: debug_mmi_contents +* +* Desc: show the current mib_node's all information such as name, path, child nodes and so on +* +* Ret: 1: succeful, 0: fail +* +* File: debug.c +* +*/ +int debug_mmi_contents(char *str) +{ + WORD i,j; + DWORD k; + char ascii_text[256*5]; + //char temp_str[64]; + mib_child_node *child_node_ptr; + mib_node *mib_tmp_node; + char ins_str[16],temp_str[128]; + BYTE max_group,ismodule; + + if(strlen(str)!=0) + { + for(i=0;itotal_child_nodes) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No contents in this object,no child,Please go back! \r\n"); + return 0; + } + debug_ascii_out_proc("Name : "); + sprintf(ascii_text,"%s",mib_curr_node->name); + debug_color_out(BRIGHT,YELLOW,BLACK,ascii_text); + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc("Type : "); + if(mib_curr_node->total_instance) + { + debug_mmi_find_host(""); + } + if(mib_curr_node->total_instance) + { + debug_color_out(BRIGHT,YELLOW,BLACK,"Leaf node("); + debug_color_out(BRIGHT,YELLOW,BLACK,max_access[mib_curr_node->max_access]); + debug_color_out(BRIGHT,YELLOW,BLACK,")"); + } + else + debug_color_out(BRIGHT,YELLOW,BLACK,"Parent node"); + debug_ascii_out_proc("\r\n"); + + if(debug_cfg==1) + { + if(mib_curr_node->module_index!=0xFF) + { + max_group=subsys_module[mib_curr_node->module_index].max_group; + if(host_group<=max_group) + { + debug_ascii_out_proc("Module : "); + sprintf(temp_str,"%s-%d\r\n",subsys_module[mib_curr_node->module_index].name,host_group); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + } + else + { + debug_ascii_out_proc("Module : "); + sprintf(temp_str,"%s-0\r\n",subsys_module[mib_curr_node->module_index].name); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + sprintf(temp_str,"Error : the max system id is %d.\r\n",max_group); + debug_color_out(BRIGHT,RED,BLACK,temp_str); + } + } + } + else if(debug_cfg==2) + { + if(menu_curr_node->sys_group==9) + { + debug_ascii_out_proc("Module : "); + for(i=0;imodule_index].name,i); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + } + debug_ascii_out_proc("\r\n"); + } + else + { + debug_ascii_out_proc("Module : "); + sprintf(temp_str,"%s-%d",subsys_module[mib_curr_node->module_index].name,menu_curr_node->sys_group); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + debug_ascii_out_proc("\r\n"); + } + + + } + + if(!mib_curr_node->total_instance) + { + debug_ascii_out_proc("Child : "); + sprintf(temp_str, "[%d]\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + max_group=0; + for (i = 0; i < mib_curr_node->total_child_nodes; i++) + { + child_node_ptr = mib_curr_node->child_nodes[i]; + if(!child_node_ptr) + continue; + mib_tmp_node=(mib_node*)child_node_ptr->child_ptr; + if(mib_tmp_node!=NULL) + { + max_group=subsys_module[mib_tmp_node->module_index].max_group; + } + if(strncmp(subsys_module[mib_tmp_node->module_index].name,mib_tmp_node->name,strlen(mib_tmp_node->name))==0) + ismodule=1; + else + ismodule=0; + if(ismodule==0 || max_group==0) + { + sprintf(temp_str, " |---(%u) %s\r\n", child_node_ptr->oid,child_node_ptr->name); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + } + else + { + j=0; + while(max_group>0) + { + sprintf(temp_str, " |---(%u) %s-%d\r\n", child_node_ptr->oid,child_node_ptr->name,j); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + j++; + if(j==max_group+1) + break; + } + } + } + } + else + { + if(list_once==0) + list_flag=1; + debug_cfg_end=0; + } + if(list_once==1) + { + + if (mib_curr_node->total_instance) + { + strcpy(ascii_text,""); + k=0; + for(i=0;i<=255;i++) + { + if(curr_instance_arr[i].eable==1) + { + sprintf(ins_str,"#%-3d ",i); + strpcat(ascii_text,&k,ins_str); + } + } + debug_ascii_out_proc("Instance: "); + strcpy(ins_str,""); + if(strlen(ascii_text)) + sprintf(ins_str, "#%-3d(%-3d): ", mib_curr_node->curr_instance,mib_curr_node->total_instance); + else + sprintf(ins_str, "None(%-3d): ", mib_curr_node->total_instance); + debug_color_out(BRIGHT,YELLOW,BLACK,ins_str); + //formatstr(10,ascii_text,1);//,(int)ceil(strlen(ascii_text)/70)+1); + debug_color_out(BRIGHT,BLUE,BLACK,ascii_text); + debug_ascii_out_proc("\r\n"); + if(strlen(ascii_text)) + { + none_instance=0; + } + else + none_instance=1; + if(none_instance==0) + { + if(mib_curr_node->max_access>=2 && mib_curr_node->max_access<=5) + { + IP_Selected[0]=1; + for(i=1;i<16;i++) + { + IP_Selected[i]=0; + } + debug_cfg_end=0; + debug_mmi_get_all(); + debug_cfg_end=0; + } + } + else + { + + strcpy(ascii_text,""); + debug_ascii_out_proc("Child : "); + sprintf(ascii_text, "[%d]\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,YELLOW,BLACK,ascii_text); + + for (i = 0; i < mib_curr_node->total_child_nodes; i++) + { + child_node_ptr = mib_curr_node->child_nodes[i]; + if(!child_node_ptr) + continue; + sprintf(ascii_text, " |---(%u) %s\r\n",child_node_ptr->oid+1, child_node_ptr->name); + debug_color_out(BRIGHT,YELLOW,BLACK,ascii_text); + } + debug_cfg_end=1; + } + } + } + + /* + if(!mib_curr_node->total_instance) + { + debug_ascii_out_proc("Command : Now,you can execute the commands include "); + debug_color_out(BRIGHT,YELLOW,BLACK,"\"cd ,child ,parent ,contnets ,pwd ,tree ,remark ,"); + } + else + { + debug_ascii_out_proc("Command : Now,you can execute the commands include "); + debug_color_out(BRIGHT,YELLOW,BLACK,"\"cd ,parent ,contnets ,pwd , tree ,get ,set ,list ,create ,del ,remark ,"); + } + if(save_flag==1) + debug_color_out(BRIGHT,YELLOW,BLACK,"save ,cmm ,q ,help .\"\r\n"); + else + debug_color_out(BRIGHT,YELLOW,BLACK,"cmm ,q ,help .\"\r\n"); + */ + return 1; +} +// end of debug_mmi_contents + + +/* +* +* Fun: debug_mmi_child +* +* Desc: change to the current mib_node's child node by the child node's name or id if it exists +* +* Ret: 1: succeful, 0: fail +* +* File: debug.c +* +*/ +int debug_mmi_child(char *name) +{ + BYTE str_len; + WORD child_index; + WORD oid=0; + mib_child_node *child_node_ptr; + + if (mib_curr_node->total_instance) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : The current object is a leaf node, can not change to its child node.\r\n"); + return 0; + } + + if (!(str_len = strlen(name))) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such child object for the current object\r\n"); + return 0; + } + + if (!mib_curr_node->total_child_nodes) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No child object for the current object\r\n"); + return 0; + } + + name[str_len] = '\0'; + + if (isdigit(name[0])) + { + oid = strtoul(name, NULL, 10); + child_index = find_child_index(mib_curr_node, oid, NULL, 0); + } + else + child_index = find_child_index(mib_curr_node, 0, name, 1); + + if (child_index < MIB_MAX_CHILD_NODES_PER_NODE) + { + child_node_ptr = mib_curr_node->child_nodes[child_index]; + if(child_node_ptr) + { + if (!child_node_ptr->child_ptr) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such child object for the current object\r\n"); + return 0; + } + mib_curr_node = (mib_node *)child_node_ptr->child_ptr; + //debug_ascii_out_proc("Current object changed to: "); + //debug_color_out(BRIGHT,YELLOW,BLACK,mib_curr_node->name); + //debug_ascii_out_proc("\r\n"); + debug_mmi_contents(""); + return 1; + } + } + + debug_color_out(BRIGHT,RED,BLACK,"Error : No such child object for the current object\r\n"); + return 0; +} // end of debug_mmi_child + +/* +* +* Fun: debug_mmi_parent +* +* Desc: changet to the current mib_node's parent node if it exists +* +* Ret: 1: succeful, 0: fail +* +* File: debug.c +* +*/ +int debug_mmi_parent() +{ + if (mib_curr_node->parent_ptr == NULL) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No parent object for the current object\r\n"); + return 0; + } + + mib_curr_node = (mib_node *) mib_curr_node->parent_ptr; + //debug_ascii_out_proc("Current object changed to: "); + //debug_color_out(BRIGHT,YELLOW,BLACK,mib_curr_node->name); + //debug_ascii_out_proc("\r\n"); + debug_mmi_contents(""); + return 1; +}// end of debug_mmi_parent + +/* +* +* Fun: debug_mmi_pwd +* +* Desc: show the current object path +* +* Ret: return 1 if successful, return 0 if fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int debug_mmi_pwd() +{ + mib_node *node_ptr; + mib_child_node *child_node_ptr = NULL; + BYTE i, loop_times; + WORD child_index; + char tem_str[128], text_string[1024], text_oid[128]; + char ascii_text[DEBUG_OMCBUF_LEN],oid[16]; + //DWORD temp_oid[32]={1,3,6,1,4,1,1373,1,3,3,2,2,2,1,2,0}; + + + /*if(!ShowRegister) + { + for(i=0;i<16;i++) + { + printf("id:%d,Module name: %s,ascii_in: 0X%ld,ascii_out:0X%ld\r\n",i,debug_shm_ptr->module_d[i].name,&(debug_shm_ptr->module_d[i].ascii_in),&(debug_shm_ptr->module_d[i].ascii_out)); + } + ShowRegister=1; + } + */ + if ((loop_times = mib_curr_node->oid_len - mib_root_node->oid_len) >= 15) + { + sprintf(tem_str, "Object path error for the current object\r\n"); + TxtColor(BRIGHT,RED,BLACK,tem_str); + debug_ascii_out_proc(tem_str); + return 0; + } + sprintf(text_string,"%s(%u)", mib_root_node->name,mib_root_node->oid[mib_root_node->oid_len-1]); + node_ptr = mib_root_node; + for (i = 0; i < loop_times; i++) + { + if ((child_index = find_child_index(node_ptr, mib_curr_node->oid[mib_root_node->oid_len + i], NULL, 0)) >= MIB_MAX_CHILD_NODES_PER_NODE) + { + sprintf(tem_str,"Object path error for the current object\r\n"); + TxtColor(BRIGHT,RED,BLACK,tem_str); + debug_ascii_out_proc(tem_str); + return 0; + } + child_node_ptr = node_ptr->child_nodes[child_index]; + if(child_node_ptr) + { + sprintf(text_oid, ".%s(%u)", child_node_ptr->name, child_node_ptr->oid); + strcat(text_string, text_oid); + + if (i != (loop_times - 1)) + { + if (child_node_ptr->child_ptr == NULL) + { + debug_color_out(BRIGHT,RED,BLACK,"Object path error for the current object\r\n"); + return 0; + } + node_ptr = (mib_node *) child_node_ptr->child_ptr; + } + } + } + debug_ascii_out_proc("Path : "); + formatstr(10,text_string,0);//,(int)ceil(strlen(text_string)/70)+1); + debug_color_out(BRIGHT,YELLOW,BLACK,text_string); + debug_ascii_out_proc("\r\n"); + strcpy(ascii_text, "\0"); + for (i = 0; i < (mib_curr_node->oid_len - 1); i++) + { + sprintf(oid, "%u.", mib_curr_node->oid[i]); + strcat(ascii_text, oid); + } + sprintf(oid, "%u", mib_curr_node->oid[mib_curr_node->oid_len - 1]); + strcat(ascii_text, oid); + debug_ascii_out_proc("OID : "); + debug_color_out(BRIGHT,YELLOW,BLACK,ascii_text); + debug_ascii_out_proc("\r\n"); + /* + for(i=0;i<32;i++) + snmp_agent_packet1.oid[i]=temp_oid[i]; + snmp_agent_packet1.oid_len=16; + snmp_agent_packet1.total_ip=1; + strcpy(snmp_agent_packet1.dst_ip[0],"172.18.144.1"); + snmp_agent_packet1.cmm_state=1; + snmp_agent_packet1.total_instance=255; + for(i=0;i=1 && node_levels<=8) + layer=node_levels; + else + { + layer=3; + debug_ascii_out_proc("the max layer number is eight!\r\n"); + } + */ + debug_ascii_out_proc("Layers : "); + sprintf(print_buf,"%d-%d\r\n",mib_curr_node->oid_len,mib_curr_node->oid_len+layer); + debug_color_out(BRIGHT,GREEN,BLACK,print_buf); + debug_ascii_out_proc("Host OID: "); + sprintf(print_buf,"%d",(int)mib_curr_node->oid[0]); + debug_color_out(BRIGHT,GREEN,BLACK,print_buf); + for(index=1; indexoid_len-1; index++) // ."id"."id"... + { + sprintf(print_buf, ".%d",(int)mib_curr_node->oid[index]); + TxtColor(BRIGHT,GREEN,BLACK,print_buf); + debug_ascii_out_proc(print_buf); + } + debug_ascii_out_proc("\r\n"); + } + treehost=0; + strcpy(separation2, separation); + length = strlen(separation2); + if(node_ptr == NULL) + { + debug_ascii_out_proc("\r\n"); + return; + } + for(index=0; indexname, (int)node_ptr->oid[node_ptr->oid_len-1]);//[][][]node name: "node name" + debug_color_out(BRIGHT,YELLOW,BLACK,print_buf); + if( node_ptr->total_child_nodes == 0 ) + return; + + if(node_ptr->total_instance != 0) + { + for(index = 0; index < (node_ptr->total_child_nodes); index++) + { + mib_node_param *mib_node_param_ptr; + mib_child_node_ptr=node_ptr->child_nodes[index]; + if(!mib_child_node_ptr) + continue; + mib_node_param_ptr = (mib_node_param *)mib_child_node_ptr->child_ptr; // id:"id",name: "name",byte_begin.bit_begin-byte_end.bit_end + sprintf(print_buf, "%s id:%d; %s; [%d.%d-%d.%d]\r\n", spaces, (int)mib_node_param_ptr->id+1, mib_node_param_ptr->name, (int)mib_node_param_ptr->byte_begin, (int)mib_node_param_ptr->bit_begin, (int)mib_node_param_ptr->byte_end, (int)mib_node_param_ptr->bit_end); + debug_color_out(BRIGHT,YELLOW,BLACK,print_buf); + } + return; + } + spaces[index-1]='-'; + spaces[index-2]='*'; + spaces[index-3]='-'; + spaces[index-4]='|'; + for(index = 0; index < node_ptr->total_child_nodes; index++) + { + mib_child_node_ptr=node_ptr->child_nodes[index]; + if(!mib_child_node_ptr) + continue; + sprintf(print_buf, "%s %s(%d)\r\n",spaces, mib_child_node_ptr->name,(int)mib_child_node_ptr->oid); + TxtColor(BRIGHT,YELLOW,BLACK,print_buf); + debug_ascii_out_proc(print_buf); + } + sprintf(print_buf,"{%d}--",(int)node_ptr->oid[node_ptr->oid_len-1]); + strcat(separation2, print_buf); + for(index = 0; index < node_ptr->total_child_nodes; index++) + { + mib_child_node_ptr=node_ptr->child_nodes[index]; + if(!mib_child_node_ptr) + continue; + child_node_ptr = mib_child_node_ptr->child_ptr; + debug_mmi_tree(child_node_ptr,separation2, layer-1); + } + debug_ascii_out_proc("\r\n"); +} // end of debug_mmi_tree + +void debug_mmi_create(char *str) +{ + //DWORD oid[20]; + BYTE i; + BYTE byte,bit; + char str_id[10]; + //char str_value[128]; + char temp_str[256]; + char *p; + int id; + //mib_node *temp_node; + save_flag=1; + strcpy(str_id,""); + //strcpy(str_value,""); + for(i=0;i!=strlen(str);i++) + { + if(*(str+i)!=' ') + break; + } + p=str+i; + strcpy(str,p); + if(str[0]=='\0') + { + if(mib_curr_node->enable_field_id==0xFF) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please input the instance value for the special input type!\r\n"); + return ; + } + for(id=0;id<255;id++) + if(curr_instance_arr[id].eable==0) + { + curr_instance_arr[id].eable=1; + break; + } + byte=(id)/8; + bit=(id)%8; + mib_curr_node->enable_flag[byte]=mib_curr_node->enable_flag[byte] | (BYTE)my_pow(2,bit); + mib_curr_node->curr_instance=id; + debug_mmi_set("*"); + //debug_mmi_contents(""); + if(mib_curr_node->enable_flag[byte] & (BYTE)my_pow(2,bit)) + { + debug_ascii_out_proc("State : "); + sprintf(temp_str,"The %s #%d have been created successfully!\r\n",mib_curr_node->name,id); + debug_color_out(BRIGHT,CYAN,BLACK,temp_str); + } + return; + } + else if(str[0]=='#') + { + p=str+1; + strcpy(str,p); + for(i=0;ienable_field_id==0xFF) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please input the value !\r\n"); + return ; + } + id=strtol(str_id,NULL,10); + if(id>mib_curr_node->total_instance-1) + { + sprintf(temp_str,"Error : The max instance id is %d\r\n",mib_curr_node->total_instance-1); + debug_color_out(BRIGHT,RED,BLACK,temp_str); + return; + } + /* + for(i=0;i0) + { + strncpy(str_id,str,i); + break; + } + } + + if(curr_instance_arr[id].eable==1) + { + debug_color_out(BRIGHT,RED,BLACK,"Erorr : the instance is not exist!please select another id!\r\n"); + return; + } + p=str+i; + strcpy(str_value,p); + + for(i=0;i96 && *(str_value+i)<103) || (*(str_value+i)>64 && *(str_value+i)<72))//other flag||0-f + ; + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please in put Value form 0-f!\r\n"); + return ; + } + } + //for(i=0;ioid_len;i++) + // oid[i]=mib_curr_node->oid[i]; + //oid[i+1]=id; + //temp_node=search_mib_node(mib_root_node, oid, i+1); + //if(!temp_node) + //{ + // mib_curr_node=temp_node; + */ + + if(curr_instance_arr[id].eable==1) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : The instance have exist!\r\n"); + return; + } + else + { + if(mib_curr_node->enable_field_id!=0xFF) + { + byte=(id)/8; + bit=(id)%8; + mib_curr_node->enable_flag[byte]=mib_curr_node->enable_flag[byte] | ((BYTE)my_pow(2,bit)); + } + curr_instance_arr[id].eable=1; + + } + temp_instance=mib_curr_node->curr_instance; + mib_curr_node->curr_instance=id; + + if(*(str+i)=='\0') + { + + debug_mmi_set("*"); + //debug_mmi_contents(""); + mib_curr_node->curr_instance=temp_instance; + if(curr_instance_arr[id].eable==1) + { + debug_ascii_out_proc("State : "); + sprintf(temp_str,"The %s #%d have been created successfully!\r\n",mib_curr_node->name,id); + debug_color_out(BRIGHT,CYAN,BLACK,temp_str); + } + return; + } + else if(*(str+i)=='=') + { + p=str+i+1; + strcpy(str,p); + if(strlen(str)>254) + { + str[255]='\0'; + } + strcpy(temp_str,"*="); + strcat(temp_str,str); + debug_mmi_set(temp_str); + //debug_mmi_contents(""); + mib_curr_node->curr_instance=temp_instance; + if(curr_instance_arr[id].eable==1) + { + debug_ascii_out_proc("State : "); + sprintf(temp_str,"The %s #%d have been created successfully!\r\n",mib_curr_node->name,id); + debug_color_out(BRIGHT,CYAN,BLACK,temp_str); + } + return; + } + else if(*(str+i)=='.') + { + p=str+i+1; + strcpy(str,p); + if(strlen(str)>254) + { + str[255]='\0'; + } + strcpy(temp_str,"*."); + strcat(temp_str,str); + debug_mmi_set(temp_str); + //debug_mmi_contents(""); + mib_curr_node->curr_instance=temp_instance; + if(curr_instance_arr[id].eable==1) + { + debug_ascii_out_proc("State : "); + sprintf(temp_str,"The %s #%d have been created successfully!\r\n",mib_curr_node->name,id); + debug_color_out(BRIGHT,CYAN,BLACK,temp_str); + } + return; + } + } + else + debug_color_out(BRIGHT,RED,BLACK,"Error : Input error!\r\n"); +} + +void debug_mmi_del(char *str) +{ + //DWORD oid[20]; + int i; + BYTE byte,bit; + char str_id[128]; + char str_value[128]; + char *p; + int id; + //mib_node *temp_node; + save_flag=1; + strcpy(str_id,""); + strcpy(str_value,""); + for(i=0;i!=strlen(str);i++) + { + if(*(str+i)!=' ') + break; + } + p=str+i; + strcpy(str,p); + if(str[0]!='\0' && str[0]!='#') + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Input Error!\r\n"); + return; + } + + if(strlen(str)==0) + { + id=mib_curr_node->curr_instance; + } + else if(str[0]=='#') + { + p=str+1; + strcpy(str,p); + for(i=0;imib_curr_node->total_instance-1) + { + sprintf(str_value,"Error : The max instance id is %d\r\n",mib_curr_node->total_instance-1); + debug_color_out(BRIGHT,RED,BLACK,str_value); + return; + } + } + /* + for(i=0;i0) + { + strncpy(str_id,str,i); + break; + } + } + + if(curr_instance_arr[id].eable==1) + { + debug_color_out(BRIGHT,RED,BLACK,"Erorr : the instance is not exist!please select another id!\r\n"); + return; + } + p=str+i; + strcpy(str_value,p); + + for(i=0;i96 && *(str_value+i)<103) || (*(str_value+i)>64 && *(str_value+i)<72))//other flag||0-f + ; + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please in put Value form 0-f!\r\n"); + return ; + } + } + //for(i=0;ioid_len;i++) + // oid[i]=mib_curr_node->oid[i]; + //oid[i+1]=id; + //temp_node=search_mib_node(mib_root_node, oid, i+1); + //if(!temp_node) + //{ + // mib_curr_node=temp_node; + */ + + + + if(curr_instance_arr[id].eable!=0) + { + byte=(id)/8; + bit=(id)%8; + mib_curr_node->enable_flag[byte]=mib_curr_node->enable_flag[byte] & (~(BYTE)my_pow(2,bit)); + curr_instance_arr[id].eable=0; + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : The instance is not exist!\r\n"); + return; + } + temp_instance=mib_curr_node->curr_instance; + mib_curr_node->curr_instance=id; + del_flag=1; + debug_mmi_set("*"); + // debug_mmi_contents(""); + if(temp_instance==id) + { + for(i=0;i<256;i++) + if(curr_instance_arr[i].eable==1) + { + temp_instance=i; + break; + } + } + mib_curr_node->curr_instance=temp_instance; + debug_ascii_out_proc("State : "); + sprintf(str_value,"The %s #%d have been deleted successfully!\r\n",mib_curr_node->name,id); + debug_color_out(BRIGHT,CYAN,BLACK,str_value); + return ; +} + + + +void debug_mmi_option(char *str) +{ + int select_id; + int child_index; + mib_child_node *child_node_ptr; + char out_text[80]; + int i=0; + if(!mib_curr_node->total_instance) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This is no a leaf node!\r\n"); + return ; + } + del_space(str,0); + if(isdigit(str[0])) + { + for(i=0;imib_curr_node->total_child_nodes+1 || select_id==0) + { + sprintf(out_text,"Error : The max field id is %d\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,RED,BLACK,out_text); + return; + } + select_id--; + child_index = find_child_index(mib_curr_node, select_id, NULL, 0); + } + else + child_index = find_child_index(mib_curr_node, 0, str, 1); + + + if (child_index < MIB_MAX_CHILD_NODES_PER_NODE) + { + child_node_ptr = mib_curr_node->child_nodes[child_index]; + if (!child_node_ptr->child_ptr) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such child object for the current object\r\n"); + return ; + } + + param_node = (mib_node_param *)child_node_ptr->child_ptr; + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : There is no such child.\n"); + return ; + } + debug_ascii_out_proc("Option : "); + debug_color_out(BRIGHT,YELLOW,BLACK,param_node->name); + debug_ascii_out_proc("\r\n"); + + if(param_node->select_total == 0) + { + debug_ascii_out_proc("Fail : There is no description for the select option.\n"); + return ; + } + else + { + i=0; + while(iselect_total) + { + debug_ascii_out_proc(" "); + sprintf(out_text, "%-2d :%-18s ", param_node->select_ptr[i]->number, param_node->select_ptr[i]->description); + debug_color_out(BRIGHT,BLUE,BLACK,out_text); + i+=1; + if(iselect_total) + { + + sprintf(out_text, "%-2d :%-18s ", param_node->select_ptr[i]->number, param_node->select_ptr[i]->description); + debug_color_out(BRIGHT,BLUE,BLACK,out_text); + i+=1; + if(iselect_total) + { + sprintf(out_text, "%-2d :%-18s\r\n", param_node->select_ptr[i]->number, param_node->select_ptr[i]->description); + debug_color_out(BRIGHT,BLUE,BLACK,out_text); + i+=1; + } + } + } + if(param_node->select_total%3!=0) + debug_ascii_out_proc("\r\n"); + } + return; +} + +/* +* +* Fun: debug_mmi_ip +* +* Desc: set the hosts' ip which are used by get or set command +* +* Ret: return 1 if successful, return 0 if fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int debug_mmi_ip(char *ips) +{ + BYTE str_len, index, index_2, index_3, index_4; + char temp_str[32], ip[80]; + + strcpy(ip, ips); + printf("ips: %s\r\n", ip); + if (!(str_len = strlen(ip))) + { + debug_ascii_out_proc("Null IP strings.\r\n"); + return 0; + } + strcpy(temp_str, ""); + Peer_IP[0] = 0; + for(index_4=0, index_3=0, index_2=0, index=0; index <= str_len; index++) + { + if( (ip[index] != '.') && (ip[index] != ' ')) + { + temp_str[index_2] = ip[index]; + index_2++; + if(index_2 > 3) + break; + } + else + { + temp_str[index_2] = '\0'; + Peer_IP[index_3] += atoi(temp_str) * my_pow(256, index_4++); + index_2 = 0; + if(index_4 >= 4) + { + index_3++; + Peer_IP[index_3] = 0; + index_4 = 0; + if(index_3 >= 16) + break; + } + } + } + + if(index < str_len) + { + debug_ascii_out_proc("Wrong IP.\r\n"); + return 0; + } + + temp_str[index_2] = '\0'; + if(index_3<16) + Peer_IP[index_3++] += atoi(temp_str) * my_pow(256, index_4++); + if(index_3<16) + Peer_IP[index_3] = 0; + + for(index = 0; index<16; index++) + printf("peer_id[%d] = %x ", index,Peer_IP[index]); + return 1; +} // end of debug_mmi_ip + + +void debug_mmi_find_host(char *str) +{ + BYTE index,i,j,find_all=0,find; + char temp_str1[64],temp_str2[64],temp_str3[64],*p; + + + for(i=0;imodule_index].name); + if(debug_cfg==2 && menu_curr_node!=NULL) + { + if(menu_curr_node->sys_group==9) + find_all=1; + else if(menu_curr_node->sys_group==0) + { + strcpy(temp_str2,menu_curr_node->name); + for(i=0;isys_group-1; + } + if(find_all==0) + { + strcat(temp_str1,"_"); + gcvt(host_group,1,temp_str2); + strcat(temp_str1,temp_str2); + } + i=0; + ip_num=0; + if(mib_curr_node->total_instance) + { + while(module_host[i].index!=0xFF) + { + find=!strncmp(module_host[i].host_name,temp_str1,strlen(temp_str1)); + if(find_all==2 && isdigit(module_host[i].host_name[strlen(temp_str1)])) + find=0; + if(find) + { + strcpy(Remote_Host_Name[ip_num],module_host[i].host_name); + IP_Selected[ip_num]=1; + strcpy(temp_str2,""); + strcpy(temp_str3,""); + for(j=0;j<4;j++) + { + + Peer_IP[ip_num] += module_host[i].host_ip[j] * my_pow(256, j); + gcvt((double)(module_host[i].host_ip[j]),3,temp_str2); + strcat(temp_str3,temp_str2); + strcat(temp_str3,"."); + } + temp_str3[strlen(temp_str3)-1]='\0'; + strcpy(Remote_Host_IP[ip_num],temp_str3); + ip_num++; + if(ip_num >= 16) + break; + + } + i++; + } + } + for(index=0;index<16;index++) + { + if(Peer_IP[index]!=0) + break; + } + if(list_once==1) + if(snmp_agent_flag==0) + if(index==16) + { + debug_color_out(BRIGHT,RED,BLACK,"Fial : Can not find the host!\r\n"); + return ; + } + + find_all=0; +} + +/* +* +* Fun: debug_mmi_show_host +* +* Desc: if the current node is a leaf node, show its hosts' name and ips +* +* Ret: 1: succeful, 0: fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int debug_mmi_show_host() +{ + int index; + char out_text[256]; + if( (strlen(Remote_Host_Name[0])<=0) && (strlen(Remote_Host_IP[0])<=0)) + { + debug_color_out(BRIGHT,RED,BLACK,"Host : there is no host for the object!\r\n"); + return 0; + } + if (mib_curr_node->total_instance) + { + if(ip_num!=0) + debug_ascii_out_proc("Host : Count Host Name Host IP Selected\r\n"); + else + { + if(list_once==1) + debug_color_out(BRIGHT,RED,BLACK,"Host : can not show host because no host for the object!\r\n"); + } + for(index=0; index= index_2) + { + if(index_2!=0) + sprintf(temp_str, "Error : The select item must be less than %d.\r\n", index_2); + debug_color_out(BRIGHT,RED,BLACK,temp_str); + return 0; + } + IP_Selected[num]=1; + index_2=0; + temp_str[index_2] = '\0'; + } + } + } + return 1; +}// end of debug_mmi_select_host + + +/* +* +* Fun: debug_mmi_setins +* +* Desc: if the current node is a leaf node, set the current node's current instance number +* +* Ret: 1: succeful, 0: fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +int debug_mmi_setins(char *ins) +{ + BYTE str_len; + WORD instance; + BYTE ascii_text[128]; + + if (!(str_len = strlen(ins))) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such instance for the current object\r\n"); + return 0; + } + + if (!mib_curr_node->total_instance) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No instance for the current object\r\n"); + return 0; + } + + ins[str_len] = '\0'; + + instance = strtoul(ins, NULL, 10); + + if ( instance >= mib_curr_node->total_instance ) + { + sprintf((char *)ascii_text, "Error : The instance value must less than the total instance: %d\r\n",mib_curr_node->total_instance); + debug_ascii_out_proc((char *)ascii_text); + return 0; + } + + mib_curr_node->curr_instance = instance; + debug_ascii_out_proc("Current instance changed to:"); + sprintf((char *)ascii_text,"%d\r\n", instance); + debug_color_out(BRIGHT,YELLOW,BLACK, (char *)ascii_text); + + return 1; +} // end of debug_mmi_setins + + +////////////////////////////////End of Cfg OID Tree Command///////// + + + +////////////////////////////////MIB OID Operation////////////////// +//find the the child index on just given node +WORD find_child_index(mib_node *node_ptr, DWORD oid, char *name, BYTE type) +{ + WORD i; + mib_child_node *child_node_ptr; + + //printf("oid[%d], name [%s], type [%d], total_child: %d.\r\n",(int)oid, name,(int)type,node_ptr->total_child_nodes); + if (!node_ptr->total_child_nodes) + return 0xFFFF; + + for (i = 0; i < node_ptr->total_child_nodes; i++) + { + child_node_ptr = node_ptr->child_nodes[i]; + //printf("child_nod_ptr id [%d], name [%s]. para_name: [%s]\r\n", (int)child_node_ptr->oid, child_node_ptr->name, name); + if ( (!type) && (oid == child_node_ptr->oid) ) + { + return i; + } + else if (type && (!strncasecmp(child_node_ptr->name, name,strlen(child_node_ptr->name)))) + return i; + } + //printf("can't find the nod oid=%d.\r\n",(int)oid); + return 0xFFFF; +} + + +/* +* +* Fun: search_mib_node +* +* Desc: begin form the start_mib_node_ptr, search the node whose OID is equal to the oid +* +* Ret: the pionter which point to the node whose OID is equal to the oid , or the NULL pointer if fali +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +mib_node *search_mib_node(mib_node *start_mib_node_ptr, DWORD *oid, BYTE oid_len) +{ + mib_node *node_ptr; + mib_child_node *child_node_ptr = NULL; + BYTE i, loop_times; + WORD child_index; + + if(start_mib_node_ptr == NULL) + { + printf("start_mib_node_ptr is NULL.\r\n"); + return NULL; + } + if (oid_len <= start_mib_node_ptr->oid_len) + return NULL; + if ((loop_times = oid_len - start_mib_node_ptr->oid_len) >= 15) + return NULL; + node_ptr = start_mib_node_ptr; + for (i = 0; i < loop_times; i++) + { + if ((child_index = find_child_index(node_ptr, oid[start_mib_node_ptr->oid_len + i], NULL, 0)) >= MIB_MAX_CHILD_NODES_PER_NODE) + return NULL; + child_node_ptr = node_ptr->child_nodes[child_index]; + if (i != (loop_times - 1)) + { + if (child_node_ptr->child_ptr == NULL) + return NULL; + node_ptr = (mib_node *) child_node_ptr->child_ptr; + } + } + return (mib_node *) child_node_ptr->child_ptr; +} // end of search_mib_node + + + +/* +* +* Fun: find_node +* +* Desc: find the node whose name is node_name from the start_node_ptr +* +* Ret: successful: the pointer to the node, fail: NULL +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +mib_node *find_node(mib_node *start_node_ptr, char *node_name, int find_type, DWORD *last_node_oid) +{ + int index, index_2; + mib_node *child_node_ptr; + mib_child_node *mib_child_node_ptr; + //printf("find_node begin: %s", start_node_ptr->name); + if(start_node_ptr == NULL) + return NULL; + //printf("nod_name: %s.\r\n",start_node_ptr->name); + if(!strcmp(start_node_ptr->name, node_name)) + { + if(find_type) + { + for(index_2=0; index_2 < start_node_ptr->oid_len-1; index_2++) + { + //printf("%ld.\r\n",start_node_ptr->oid[index_2]); + if(start_node_ptr->oid[index_2] != last_node_oid[index_2]) + break; + } + if(index_2 == (start_node_ptr->oid_len -1)) + return start_node_ptr; + } + else + return start_node_ptr; + } + if(start_node_ptr->total_child_nodes == 0) + return NULL; + if(!start_node_ptr->total_instance) + { + for(index = 0; index < start_node_ptr->total_child_nodes; index++) + { + //printf("child nod_name[%d]: %s.\r\n",index,start_node_ptr->child_nodes[index]->name); + mib_child_node_ptr=start_node_ptr->child_nodes[index]; + if(mib_child_node_ptr) + if( !(strcmp(mib_child_node_ptr->name, node_name)) ) + { + child_node_ptr = mib_child_node_ptr->child_ptr; + if(child_node_ptr!=NULL) + { + if(find_type) + { + for(index_2=0; index_2 < child_node_ptr->oid_len-1; index_2++) + { + if(child_node_ptr->oid[index_2] != last_node_oid[index_2]) + break; + } + if(index_2 == (child_node_ptr->oid_len -1)) + return child_node_ptr; + } + else + return child_node_ptr; + } + } + } + + for(index = 0; index < start_node_ptr->total_child_nodes; index++) + { + mib_child_node_ptr=start_node_ptr->child_nodes[index]; + if(mib_child_node_ptr) + { + child_node_ptr = find_node(mib_child_node_ptr->child_ptr, node_name, find_type, last_node_oid); + if( child_node_ptr != NULL) + { + if(find_type) + { + for(index_2=0; index_2oid_len-1; index_2++) + { + if(child_node_ptr->oid[index_2] != last_node_oid[index_2]) + break; + } + if(index_2 == (child_node_ptr->oid_len -1)) + return child_node_ptr; + } + else + return child_node_ptr; + } + } + } + } + return NULL; +} // end of find_node + +/* +** +* Fun: show_node +* +* Desc: show the mib_tree start from the node_ptr whit the separation as a class sign +* +* Ret: RETVOID +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +void show_node(mib_node *node_ptr,char *separation) +{ + int index, length; + mib_node *child_node_ptr; + char spaces[256], separation2[256]; + strcpy(separation2, separation); + length = strlen(separation2); + if(node_ptr == NULL) + { + printf("\r\n"); + return; + } + for(index=0; indexname, spaces, (int)node_ptr->oid[0]); + + for(index=1; indexoid_len; index++) + { + printf(".%d",(int)node_ptr->oid[index]); + } + } + else + printf("%snode name: %s\r\n%soid: %d",separation2, node_ptr->name, spaces, (int)node_ptr->oid[node_ptr->oid_len - 1]); + printf("\n"); + if( node_ptr->total_child_nodes == 0 ) + return; + else + { + printf("%schild nodes:\r\n",spaces); + } + if(node_ptr->total_instance != 0) + { + for(index = 0; index < (node_ptr->total_child_nodes); index++) + { + mib_node_param *mib_node_param_ptr; + + printf("%s oid: %d, name: %s\r\n",spaces, (int)node_ptr->child_nodes[index]->oid, node_ptr->child_nodes[index]->name); + + mib_node_param_ptr = (mib_node_param *)node_ptr->child_nodes[index]->child_ptr;//?? + + printf("%s id: %d, name: %s, %d . %d - %d . %d\r\n", spaces, (int)mib_node_param_ptr->id+1, mib_node_param_ptr->name, (int)mib_node_param_ptr->byte_begin, (int)mib_node_param_ptr->bit_begin, (int)mib_node_param_ptr->byte_end, (int)mib_node_param_ptr->bit_end ); + + if(mib_node_param_ptr->select_total != 0) + { + int index_s; + mib_param_select *mib_param_select_ptr; + + printf("%s selects: \r\n", spaces); + + for(index_s=0; index_s< mib_node_param_ptr->select_total; index_s++) + { + mib_param_select_ptr = mib_node_param_ptr->select_ptr[index_s]; + + printf("%s number: %d, opt: %s\r\n", spaces, (int)mib_param_select_ptr->number, mib_param_select_ptr->description); + } + } + if(mib_node_param_ptr->input_ptr != NULL) + { + mib_param_input *mib_param_input_ptr; + mib_param_input_ptr = mib_node_param_ptr->input_ptr; + printf("%s input:\r\n%s input_param_type: %d, input_string: %s\r\n", spaces, spaces, (int)mib_param_input_ptr->input_param_type, mib_param_input_ptr->input); + } + } + return; + } + + for(index = 0; index < node_ptr->total_child_nodes; index++) + printf("%s oid: %d, name: %s\r\n",spaces, (int)node_ptr->child_nodes[index]->oid, node_ptr->child_nodes[index]->name); + strcat(separation2, "{ }--"); + for(index = 0; index < node_ptr->total_child_nodes; index++) + { + child_node_ptr = node_ptr->child_nodes[index]->child_ptr; + show_node(child_node_ptr,separation2); + } + printf("\r\n"); +} // end of show_node + + +/* +* +* Fun: find_OID +* +* Desc: search the OID which number is obj_num in the sysConf_file, and store them to the *OID +* +* Ret: the length of the OID; 0: Fail +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ + +int find_OID(int obj_num, char *sysConf_file_name, DWORD *OID) +{ + char temp_str[256], stop_ch[32]; + int state = 0, find; + FILE *fp_sysConf; + + if((fp_sysConf = fopen(sysConf_file_name, "r")) == NULL) + { + printf("[debug] Error: cannot open param_sysConf_file: [%s].\r\n",sysConf_file_name); + return 0; + } + + strcpy(stop_ch,";"); + while( !feof(fp_sysConf) ) + { + read_until(fp_sysConf, temp_str, stop_ch); + + switch(state) + { + case 0: + if(strlen(temp_str) == 0) + { + printf("[debug] Error: Fail to get the object number in the sysConf_file.\r\n"); + fclose(fp_sysConf); + return 0; + } + if( obj_num == atoi(temp_str) ) + find = 1; + else + find = 0; + strcpy(stop_ch,";"); + state = 1; + break; + case 6: + if(find && (strlen(temp_str) != 0)) + { + int i, j, k, length=strlen(temp_str); + char temp_str_2[256]; + strcpy(temp_str_2, ""); + for(k=0; k<32; k++) + OID[k] = 0; + for(i=0,j=0,k=0 ; imenu_oid_node==mib_curr_node && menu_curr_node->total_menu_child) + { + debug_ascii_out_proc("Name : "); + sprintf(ascii_text,"%s",menu_curr_node->name); + debug_color_out(BRIGHT,YELLOW,BLACK,ascii_text); + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc("Contents: "); + sprintf(ascii_text, "[%d]\r\n",menu_curr_node->total_menu_child); + debug_color_out(BRIGHT,YELLOW,BLACK,ascii_text); + for (i = 0; i < menu_curr_node->total_menu_child; i++) + { + menu_tmp_node = menu_curr_node->child_node[i]; + if(menu_tmp_node!=NULL) + { + sprintf(ascii_text, " |---(%d) %s\r\n",menu_tmp_node->menu_id[menu_tmp_node->id_len-1], menu_tmp_node->name); + debug_color_out(BRIGHT,YELLOW,BLACK,ascii_text); + } + } + } + else + { + debug_mmi_contents(""); + } +} + +void debug_mmi_mcd(char *str) +{ + char input_str[32]; + int index;//,index1; + menu_node *menu_tmp_node; + mib_child_node *child_node_ptr; + mib_node *find_node_ptr; + DWORD temp_index; + DWORD OID[32]; + BYTE index_start,index_end; + + + if(mib_curr_node->total_instance && strstr(str,"..")==0) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Have reached the leaf node!\r\n"); + return; + } + + + if(strlen(str)>32) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No need so long command!\r\n"); + return ; + } + + for(index_start=0;index_start0;index_start--) + { + if(*(str+index_end)!=' ') + break; + } + strncpy(input_str,str+index_start,index_end-index_start); + if(!strlen(input_str)) + { + menu_curr_node=menu_root_node; + if(menu_curr_node->menu_oid_node) + mib_curr_node=menu_curr_node->menu_oid_node; + list_once=0; + debug_mmi_view(); + return ; + } + if(input_str[0]=='.'&& input_str[1]=='.') + { + if(mib_curr_node!=menu_curr_node->menu_oid_node) + { + mib_curr_node=(mib_node*)mib_curr_node->parent_ptr; + } + else if(mib_curr_node==menu_curr_node->menu_oid_node) + { + menu_tmp_node=(menu_node *)menu_curr_node->father_ptr; + if(menu_tmp_node) + { + menu_curr_node=menu_tmp_node; + if(menu_curr_node->menu_oid_node) + { + mib_curr_node=menu_curr_node->menu_oid_node; + list_once=0; + } + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Have reach the 'WXC2' or no father node\r\n"); + return ; + } + } + } + else if(!isdigit(input_str[0]) || (isdigit(input_str[0]) && !isdigit(input_str[1]) && input_str[1]!='\0')) + { + if(mib_curr_node==menu_curr_node->menu_oid_node && menu_curr_node->total_menu_child) + { + for(index=0;indextotal_menu_child;index++) + { + if((menu_tmp_node=(menu_node*)menu_curr_node->child_node[index])) + if(strncasecmp(input_str,menu_tmp_node->name,strlen(menu_tmp_node->name))==0) + { + menu_curr_node=menu_tmp_node; + if(menu_curr_node->menu_oid_node) + mib_curr_node=menu_curr_node->menu_oid_node; + break; + } + } + if(index==menu_curr_node->total_menu_child) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No such object as the name or input error!\r\n"); + return ; + } + } + else + { + index = find_child_index(mib_curr_node, 0, input_str, 1); + + if (index < MIB_MAX_CHILD_NODES_PER_NODE) + { + child_node_ptr = mib_curr_node->child_nodes[index]; + if (!child_node_ptr->child_ptr) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such child object for the current object\r\n"); + return ; + } + else + mib_curr_node=child_node_ptr->child_ptr; + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Input error!\r\n"); + return ; + } + } + } + else if(isdigit(input_str[0])) + { + for(index=0;index4) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Input error!\r\n"); + return ; + } + temp_index=atoi(input_str); + } + if(mib_curr_node==menu_curr_node->menu_oid_node && menu_curr_node->total_menu_child) + { + if(temp_index<=0 || temp_index>menu_curr_node->total_menu_child) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Input error!\r\n"); + return ; + } + if(!menu_curr_node->total_menu_child || temp_index>menu_curr_node->total_menu_child) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No child menu item!\r\n"); + return ; + } + else if((menu_tmp_node=(menu_node*)menu_curr_node->child_node[temp_index-1])) + { + menu_curr_node=menu_tmp_node; + if(menu_curr_node->menu_oid_node) + mib_curr_node=menu_curr_node->menu_oid_node; + } + } + else + { + if(mib_curr_node->total_child_nodes) + { + OID[mib_curr_node->oid_len]=temp_index; + find_node_ptr =(mib_node*)search_mib_node(mib_curr_node, OID,mib_curr_node->oid_len+1); + //child_node_ptr=mib_curr_node->child_nodes[temp_index-1]; + if(!find_node_ptr) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No such child item!\r\n"); + return ; + } + else + { + mib_curr_node=find_node_ptr; + list_once=0; + } + //if(child_node_ptr->child_ptr) + // mib_curr_node=child_node_ptr->child_ptr; + //else + //{ + // debug_color_out(BRIGHT,RED,BLACK,"Error : No such child node!\r\n"); + // return ; + //} + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No child for current node!\r\n"); + return ; + } + } + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Input error!\r\n"); + return ; + } + /* + for(index=0;index3) + { + field_compute_state=0; + read_syntax_nor_list=0; + line_index=0; + compute_state=0; + print_line_index=0; + } + */ + if(mib_curr_node==menu_curr_node->menu_oid_node && menu_curr_node->total_menu_child) + debug_mmi_view(); + else + { + if(menu_curr_node->menu_oid_node) + { + curr_module=mib_curr_node->module_index; + if(mib_curr_node->total_instance) + { + list_once=0; + curr_module=mib_curr_node->module_index; + register_instance(); + debug_mmi_contents(" "); + debug_cfg_end=0; + } + else + { + debug_mmi_contents(" "); + } + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No oid node match along with the menu item!\r\n"); + return ; + } + } + +} + +void main_menu(char *str) +{ + char out_text[128],*ch; + BYTE i; + for(i=0;i<80 && *(str+i)!='\0';i++) + { + if(*(str+i)!=' ') + break; + } + ch=str+i; + strcpy(out_text,ch); + if(*out_text!='\0') + { + if(strncasecmp(out_text,"help",4)==0) + { + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"help \r\n"); + debug_ascii_out_proc(" Show the WXC2 configer menu page\r\n"); + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"help command\r\n"); + debug_ascii_out_proc(" Show the usage of the command: contents,cd,child,parent,get,set,lsit,\r\n create,delete,remark,option,cmm,help\r\n"); + } + else if(strncasecmp(out_text,"cd",2)==0) + { + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd \r\n"); + debug_ascii_out_proc(" Enter the system main menu WXC2\r\n"); + debug_ascii_out_proc(" Usage 2: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd ..\r\n"); + debug_ascii_out_proc(" Enter the parent menu item \r\n"); + debug_ascii_out_proc(" Usage 3: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd name\r\n"); + debug_ascii_out_proc(" Enter the child menu item name as 'name'\r\n"); + debug_ascii_out_proc(" Usage 4: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"cd XX\r\n"); + debug_ascii_out_proc(" Enter the child menu item whose id is 'XX' \r\n"); + } + else if(strncasecmp(out_text,"get",3)==0) + { + help_cmm(1,"get or get *","Get and printf the current instance's value of the node\r\n"); + help_cmm(2,"get #XX","Get and printf the special instance's value of the node\r\n"); + help_cmm(3,"get *.X or get *.name","Get and printf the current instance's special field value of the node\r\n"); + help_cmm(4,"get #X.X or get #x.name","Get and printf the special instance's special field value of the node\r\n"); + } + else if(strncasecmp(out_text,"set",3)==0) + { + help_cmm(1,"set or set *","Set the current instance's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(2,"set #XX ","Set the special instance's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(3,"set *.X =X or set *.name=X ","Set the current instance's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(4,"set #X.X =X or set #x.name=X ","Set the special instance's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(5,"set #X =XXX","Set the special instance's whole value to given value of the node and open the isntance ,then printf\r\n"); + } + else if(strncasecmp(out_text,"create",3)==0) + { + help_cmm(1,"creat or create *","Create an instance with the min closed instance id and set it's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(2,"create #XX","Create the special instance,and set it's value to default value of the node and open the isntance ,then printf\r\n"); + help_cmm(3,"create *.X =X or create *.name=X ","Create an instance's with the min closed instance id ,and set it's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(4,"create #X.X =X or create #x.name=X ","Create the special instance,and set it's field value to given value of the node and open the isntance ,then printf\r\n"); + help_cmm(5,"create #X =XXX","Create the special instance,and set is's whole value to given value of the node and open the isntance ,then printf\r\n"); + } + else if(strncasecmp(out_text,"delete",3)==0) + { + help_cmm(1,"delete ","Delete the current instance ,if it is opened,clost it.set the value to default value of the node\r\n"); + help_cmm(2,"delete #XX","Delete the special instance,if it is opened,clost it.set the value to default value of the node\r\n"); + } + else if(strncasecmp(out_text,"contents",3)==0) + { + help_cmm(1,"contents ","Show the current menu item or the informat about the oid node\r\n"); + } + else if(strncasecmp(out_text,"list",3)==0) + { + help_cmm(1,"list [-a]","the switch of show all the field and value of the instance include the 'NULL' and the closed instance,default:off\r\n"); + help_cmm(2,"list [-e]","the switch of show opened the instance,hide the field and it's value default:off\r\n"); + help_cmm(3,"list [-r]","the switch of show the field data range.default:off\r\n"); + help_cmm(4,"list [-t]","the switch of show input data type ,default:off\r\n"); + help_cmm(5,"list [-f[X XX X]]","the switch of show the special field list in the [ ] ,default:off\r\n"); + help_cmm(6,"list [X-XX]","the switch of show the instance range form x to xxx.default:off\r\n"); + } + else if(strncasecmp(out_text,"child",3)==0) + { + help_cmm(1,"child X","Enter the child node whose id is X\r\n"); + help_cmm(2,"child name","Enter the child node whose name is 'name'\r\n"); + } + else if(strncasecmp(out_text,"parent",3)==0) + { + help_cmm(1,"parent","Enter the parent node\r\n"); + } + /* + else if(strncasecmp(out_text,"pwd",3)==0) + { + help_cmm(1,"pwd","Show the full path and the full oid\r\n"); + } + */ + else if(strncasecmp(out_text,"remark",3)==0) + { + help_cmm(1,"remark","Show the description of the node\r\n"); + } + else if(strncasecmp(out_text,"option",3)==0) + { + help_cmm(1,"option X","Show the select option of the fied node whose id is x of leaf node \r\n"); + help_cmm(2,"option name","Show the select option of the fied node whose name is ''name' of leaf node \r\n"); + } + else if(strncasecmp(out_text,"save",3)==0) + { + help_cmm(1,"save","save the debug\r\n"); + } + else if(strncasecmp(out_text,"find host",3)==0) + { + help_cmm(1,"find host","Find all the host who have the object about the current node\r\n"); + } + else if(strncasecmp(out_text,"select",3)==0) + { + help_cmm(1,"select X","Select the host ip list,if been selected ,the set command would do effect on the host\r\n"); + } + else if(strncasecmp(out_text,"setinst",3)==0) + { + help_cmm(1,"setinst X","Set the current instance as the special number\r\n"); + } + else if(strncasecmp(out_text,"cmm",3)==0) + { + help_cmm(1,"cmm","Enter the debug cmm state\r\n"); + } + /* + else if(strncasecmp(out_text,"addhost",3)==0) + {} + else if(strncasecmp(out_text,"delhost",3)==0) + {} + else if(strncasecmp(out_text,"tree",4)==0) + { + help_cmm(1,"tree","Print the menu three\r\n"); + } + */ + else + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No such Command!\r\n"); + return ; + } + } + else + { + time_t tick_2; + char time_buf_2[64]= "\0", str_buf[128]="\0"; + BYTE count=0; + tick_2 = time(NULL); + debug_ascii_out_proc("\033[2J\033[1;1H"); + snprintf(time_buf_2, sizeof(time_buf_2), "%.24s", ctime(&tick_2)); + sprintf(str_buf, " -----Start Time: %s----- \r\n", time_buf_2); + debug_color_out(BRIGHT,CYAN,WHITE,str_buf); + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*************************\r\n");//80-20=60/2=30 + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*"); + debug_ascii_out_proc(" "); + debug_color_out(BRIGHT,WHITE,BLACK,"WXC2 System Configer Menu");//80-20=60/2=30 + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*\r\n"); + debug_ascii_out_proc(" "); + debug_ascii_out_proc("*************************\r\n");//80-20=60/2=30 + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc(" ============================================================================== \r\n"); + debug_ascii_out_proc(" | | | | | | \r\n"); + debug_ascii_out_proc(" "); + count=menu_root_node->total_menu_child; + for(i=0;ichild_node[i])->name); + debug_color_out(BRIGHT,YELLOW,GREEN,out_text); + debug_ascii_out_proc(" "); + } + debug_ascii_out_proc("\r\n\r\n\r\n\r\n"); + if(debug_cfg==2) + { + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"help \r\n"); + debug_ascii_out_proc(" Show the WXC2 configer menu page\r\n"); + debug_ascii_out_proc(" Usage 1: "); + debug_color_out(BRIGHT,YELLOW,BLACK,"help command\r\n"); + debug_ascii_out_proc(" Show the usage of the command: contents,cd,child,parent,get,set,list,\r\n create,delete,remark,option,cmm,save,help\r\n"); + } + } +} // end of debug_mmi_cfg_help + + + +menu_node *search_menu_node(menu_node *start_menu_node_ptr, BYTE *menu_id, BYTE id_len) +{ + menu_node *node_ptr,*menu_node_ptr; + BYTE i, loop_times; + + + if(start_menu_node_ptr == NULL) + { + printf("start_menu_node_ptr is NULL.\r\n"); + return NULL; + } + if (id_len <= start_menu_node_ptr->id_len) + return NULL; + if ((loop_times = id_len - start_menu_node_ptr->id_len) >= 15) + return NULL; + node_ptr = start_menu_node_ptr; + for (i = 0; i < loop_times; i++) + { + menu_node_ptr= (menu_node*)node_ptr->child_node[menu_id[i]-1]; + if(menu_node_ptr) + node_ptr=menu_node_ptr; + else + { + printf("[debug] :Fail to search menu node!father node: %s,search_id:%d\n",node_ptr->name,menu_id[loop_times]); + return NULL; + } + } + return (menu_node *) node_ptr; +} // end of search_menu_node +//////////////////////////////End of CMM Menu Tree Command//////////// + + + + + + +///////////////////////////////snmp senior agnet///////////////// + +void debug_set_agent() +{ + DWORD oid[32]; + mib_child_node *child_node_ptr; + mib_node *find_node_ptr; + char *p,temp_str1[16],temp_str2[4]; + WORD ip[16][4]; + DWORD Set_IP[16],sum,sub_sum; + BYTE m; + param_field *tmp_param_field; + WORD i,j,k,child_index,index3,index,index2,index4,select_id; + WORD total_field; + if(snmp_agent_flag==0 && (get_state!=0 || set_state!=0)) + return ; + + + + for(i=0;itotal_instance) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=3; + return ; + } + agent_tmp_node=mib_curr_node; + mib_curr_node=find_node_ptr; + for(i=0;itotal_child_nodes;i++) + { + child_node_ptr=mib_curr_node->child_nodes[i]; + if(child_node_ptr) + { + param_node = (mib_node_param *)child_node_ptr->child_ptr; + tmp_param_field=&debug_snmp_agent_buf[debug_agent_index].param_field_arr[i]; + if(param_node->select_total!=0) + { + tmp_param_field->total_select=param_node->select_total; + for(index=0; indexselect_total; index++) + { + tmp_param_field->value_arr[index]=param_node->select_ptr[index]->number; + strcpy(tmp_param_field->value_arr_remark[index],param_node->select_ptr[index]->description); + } + tmp_param_field->input_type=0xFF; + } + else if(param_node->input_ptr!=NULL) + { + tmp_param_field->total_select=0; + tmp_param_field->input_type=param_node->input_ptr->input_param_type; + } + strcpy(tmp_param_field->name,param_node->name); + } + + } + + if(mib_curr_node->max_access ==0 || mib_curr_node->max_access ==1 || mib_curr_node->max_access ==3) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=6; + mib_curr_node=agent_tmp_node; + return ; + } + + if(snmp_agent_packet.oid[snmp_agent_packet.oid_len-1] >mib_curr_node->total_instance) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=5; + mib_curr_node=agent_tmp_node; + return ; + } + + mib_curr_node->curr_instance=snmp_agent_packet.oid[snmp_agent_packet.oid_len-1]; + + + + + //set the param + if(snmp_agent_packet.total_field!=mib_curr_node->total_child_nodes) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=7; + mib_curr_node=agent_tmp_node; + return ; + } + j=mib_curr_node->data_length; + for(i=0;iinit_value[i]; + } + + total_field=snmp_agent_packet.total_field; + //total_field=mib_curr_node->total_child_nodes; + for(child_index=0;child_indexchild_nodes[child_index]; + if (!child_node_ptr->child_ptr) + { + strcpy(temp_str1,"1"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + param_node = (mib_node_param *)child_node_ptr->child_ptr; + + if(param_node->select_total != 0) + { + select_id=atoi(snmp_agent_packet.param_field_arr[child_index].curr_input_value); + if(select_id>param_node->select_total) + { + strcpy(temp_str1,"2"); + sprintf(temp_str2,"%d",snmp_agent_packet.param_field_arr[child_index].curr_select_id); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + + } + else + { + j=select_id; + set_val=param_node->select_ptr[j]->number; + index3 = sum = 0; + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + index3++; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + } + } + } + else if(param_node->input_ptr != NULL) + { + strcpy(set_val_str,snmp_agent_packet.param_field_arr[child_index].curr_input_value); + switch(param_node->input_ptr->input_param_type)// ananlise + { + case 0: //toDec_high_0 //\u5224\u65AD\u8F93\u5165\u7684\u6570\u503C\u662F\u5426\u6709\u6548 + j = strlen(set_val_str); + for(i=0; ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin); + set_val = atol(set_val_str); + if(set_val > my_pow(2, j)) + { + strcpy(temp_str1,"3"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + } + break; + case 1: //keepHex_high_0 //\u5224\u65AD\u8F93\u5165\u7684\u6570\u503C\u5B57\u7B26\u4E32set_val_str\u662F\u5426\u6709\u6548, \u5982\u679C\u6709\u6548\u5219\u5C06\u9AD8\u4F4D\u8865\u6210\u5B57\u7B26'0'\uFF0C\u8865\u8DB3\u4F4D\u6570 + j = strlen(set_val_str); + for(i=0; i= 'A') && (set_val_str[i] <= 'F')) //is A to F + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + strcpy(temp_str1,"3"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u9AD8\u4F4D\u8865\u6210'0' + k = i-j; + for(j=i-1; (j-k)>=0 && j!=0 ; j--) + set_val_str[j]=set_val_str[j-k]; + set_val_str[i] = '\0'; + for(j=0; j= 'A') && (set_val_str[i] <= 'F')) //is A to F + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + strcpy(temp_str1,"3"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'0' + for(; j= 'A') && (set_val_str[i] < 'E')) //is A to D + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + strcpy(temp_str1,"3"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210E + for(; j= 'A') && (set_val_str[i] < 'F')) //is A to E + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + strcpy(temp_str1,"3"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'F' + for(; jbyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/8; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + strcpy(temp_str1,"3"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'0' + for(; jbyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/8; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + strcpy(temp_str1,"3"); + sprintf(temp_str2,"%d",child_index); + strcat(temp_str1,temp_str2); + j=atoi(temp_str1); + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=j; + mib_curr_node=agent_tmp_node; + return ; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'F' + for(; jinput_ptr->input_param_type)// set + { + case 0: //toDec_high_0 + index3 = sum = 0; + for(index=param_node->byte_end; index >=param_node->byte_begin; index--) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + index3++; + if( (index == param_node->byte_begin) && (((param_node->byte_begin==param_node->byte_end)&& index2 == param_node->bit_end) || ((param_node->byte_begin!=param_node->byte_end)&& index2==7))) + break; + + } + if( (index == param_node->byte_begin) && (((param_node->byte_begin==param_node->byte_end)&& index2 == param_node->bit_end) || ((param_node->byte_begin!=param_node->byte_end)&& index2==7))) + break; + } + break; + case 1: //keepHex_high_0 + case 2: //keepHex_low_0 + case 3: //keepHex_low_E + case 4: //keepHex_low_F + + index3 = index4 = sum = sub_sum = 0; + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + if((index3 == 0) && ( (index4+1) <= strlen(set_val_str) )) //\u53D6\u4E24\u4F4D\u5B57\u7B26 + { + set_val = 0; + if( isdigit(set_val_str[index4]) ) //\u6570\u5B57\u5B57\u7B26 + set_val += (set_val_str[index4++] - '0') * 16; + else // A \u81F3 E \u4E4B\u95F4 + set_val += (set_val_str[index4++] - 'A' + 10) * 16; + + if( isdigit(set_val_str[index4]) ) + set_val += set_val_str[index4++] - '0'; + else + set_val += set_val_str[index4++] - 'A' + 10; + } + + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + index3++; + if(index3 == 8) + index3 = 0; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + } + break; + case 5: //toAscii_low_0 + case 6: //keepAscii_low_F + + index3 = index4 = sum = sub_sum = 0; + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + if(index3 == 0) //\u53D6\u4E00\u4F4D\u5B57\u7B26 + set_val = set_val_str[index4++]; + + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + index3++; + if(index3 == 8) + index3 = 0; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + } + break; + } + } + + + } + j=recv_msgbuf.var[0].msglen; + + for(i=0;i15) + break; + } + for(i=0;i<=ip_num;i++) + { + Peer_IP[i]=Set_IP[i]; + IP_Selected[i]=1; + } + for(ip_index=0;ip_index<16;ip_index++) + { + if(IP_Selected[ip_index] != 1) + continue; + send_addr.remote_ip = Peer_IP[ip_index]; + break; + } + if(ip_index>=16) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=4; + mib_curr_node=agent_tmp_node; + return ; + } + } + else + debug_mmi_find_host(""); + send_addr.local_ip = Local_IP; + send_addr.remote_port = SNMP_PORT; + send_addr.local_port = DEBUG_SNMP_PORT; + + send_addr.broadcast = 0; + send_msgbuf.pdu_type = 0; + send_msgbuf.request_id = 0; + send_msgbuf.var_num = 1; + for(i=0; i<32; i++) + send_msgbuf.var[0].oid[i] = mib_curr_node->oid[i]; + send_msgbuf.var[0].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance; + send_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = 0; + recv_msgbuf.var_num = 1; + for(i=0; i<32; i++) + recv_msgbuf.var[0].oid[i] = mib_curr_node->oid[i]; + recv_msgbuf.var[mib_curr_node->oid_len].oid[i] = (DWORD)mib_curr_node->curr_instance; + recv_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + + for(i=0; i<256; i++) + recv_msgbuf.var[0].msg[i] = 0; + + recv_addr.remote_ip = send_addr.remote_ip; + recv_addr.local_ip = Local_IP; + recv_addr.remote_port = SNMP_PORT; + recv_addr.local_port = DEBUG_SNMP_PORT; + recv_addr.broadcast = 0; + + snmp_agent_flag=2; + debug_snmp_agent_buf[debug_agent_index].cmm_state=3; + ip_index = 0; + set_state = 1; + debug_cfg_end = 0; + return ; +} + +void debug_get_agent() +{ + DWORD oid[32]; + mib_node *find_node_ptr; + char *p,temp_str1[16],temp_str2[4]; + WORD ip[16][4]; + DWORD Set_IP[16]; + BYTE m; + WORD i,j,k; + static BYTE t1s; + + if(snmp_agent_flag==0 && (get_state!=0 || set_state!=0)) + return ; + + if(bind_num>0 && snmp_agent_flag>0) + { + for(i=0;i50) + { + t1s=0; + bind_num=0; + get_state=0; + snmp_agent_flag=0; + for(i=0;icurr_instance+=bind_num-1; + + if(mib_curr_node->curr_instance==mib_curr_node->total_instance-1) + { + bind_num=0; + get_state=0; + snmp_agent_flag=0; + mib_curr_node->curr_instance=0; + mib_curr_node=agent_tmp_node; + return; + } + if(mib_curr_node->curr_instancetotal_instance-MAX_PACKET_NUM) + { + //mib_curr_node->curr_instance+=bind_num; + mib_curr_node->curr_instance++; + snmp_agent_flag=1; + for(i=0;icurr_instancetotal_instance-1) + { + mib_curr_node->curr_instance++; + bind_num=mib_curr_node->total_instance+1-mib_curr_node->curr_instance; + snmp_agent_flag=1; + for(i=0;icurr_instance=0; + mib_curr_node=agent_tmp_node; + return; + } + } + + + for(i=0;itotal_child_nodes; + if(mib_curr_node->max_access ==0 || mib_curr_node->max_access ==1) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=6; + mib_curr_node=agent_tmp_node; + return ; + } + + if(snmp_agent_packet.oid[snmp_agent_packet.oid_len-1]>mib_curr_node->total_instance) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=5; + mib_curr_node=agent_tmp_node; + return ; + } + if(mib_curr_node->total_instance==snmp_agent_packet.total_instance && mib_curr_node->total_instance>=MAX_PACKET_NUM ) + { + if(debug_agent_index==0 && !debug_snmp_agent_buf[debug_agent_index].oid[ debug_snmp_agent_buf[debug_agent_index].oid_len-1]) + { + bind_num=MAX_PACKET_NUM; + snmp_agent_flag=1; + mib_curr_node->curr_instance=0; + } + else + printf("Error : The debug SNMP Agent buffer is not start from 0,while getting all instance\r\n"); + } + else if(mib_curr_node->total_instance==snmp_agent_packet.total_instance && mib_curr_node->total_instancecurr_instance=0; + bind_num=mib_curr_node->total_instance; + snmp_agent_flag=1; + } + else + printf("Error : The debug SNMP Agent buffer is not start from 0,while getting all instance\r\n"); + } + else + { + bind_num=1; + snmp_agent_flag=1; + mib_curr_node->curr_instance=snmp_agent_packet.oid[snmp_agent_packet.oid_len-1]; + } + debug_get_all_value=mib_curr_node->total_child_nodes; + + //set the ip + if(snmp_agent_packet.total_ip) + { + for(i=0;i<16;i++) + { + Set_IP[i]=0; + IP_Selected[i]=0; + Peer_IP[i]=0; + } + ip_num=0; + for(m=0;m15) + break; + } + for(i=0;i<=ip_num;i++) + { + Peer_IP[i]=Set_IP[i]; + IP_Selected[i]=1; + } + for(ip_index=0;ip_index<16;ip_index++) + { + if(IP_Selected[ip_index] != 1) + continue; + send_addr.remote_ip = Peer_IP[ip_index]; + break; + } + if(ip_index>=16) + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=4; + mib_curr_node=agent_tmp_node; + return ; + } + } + else + debug_mmi_find_host(""); + + + +bind_set: + send_msgbuf.pdu_type = 0; + send_msgbuf.request_id = 0; + send_msgbuf.var_num = bind_num; + for(j=0;joid[i]; + send_msgbuf.var[j].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance+j; + send_msgbuf.var[j].oidlen = mib_curr_node->oid_len + 1; + } + + send_addr.local_ip = Local_IP; + send_addr.remote_port = SNMP_PORT; + send_addr.local_port = DEBUG_SNMP_PORT; + send_addr.broadcast = 0; + + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = 0; + recv_msgbuf.var_num = bind_num; + for(j=0;joid[i]; + recv_msgbuf.var[j].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance+j; + recv_msgbuf.var[j].oidlen = mib_curr_node->oid_len + 1; + for(i=0; i<256; i++) + recv_msgbuf.var[j].msg[i] = 0; + } + + recv_addr.remote_ip = send_addr.remote_ip; + recv_addr.local_ip = Local_IP; + recv_addr.remote_port = SNMP_PORT; + recv_addr.local_port = DEBUG_SNMP_PORT; + recv_addr.broadcast = 0; + + get_state = 1; + debug_cfg_end = 0; + if(bind_num!=MAX_PACKET_NUM) + debug_snmp_agent_buf[debug_agent_index].cmm_state=3; + else + for(i=0;itotal_instance)) + { + debug_ascii_out_proc("Fail : There is no instance for the current object\r\n"); + debug_cfg_end=1; + return 0; + } + + if (mib_curr_node->max_access == 0) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS property is 'INVALID'. Can not get its value.\r\n"); + debug_cfg_end=1; + return 0; + } + if (mib_curr_node->max_access == 1) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS property is 'NOT-ACCESSIBLE'. Can not get its value.\r\n"); + debug_cfg_end=1; + return 0; + } + if (mib_curr_node->max_access == 6 && snmp_agent_flag==0) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS property is 'WRITE-ONLY'. Can not get its value.\r\n"); + debug_cfg_end=1; + return 0; + } + + if(mib_curr_node->total_child_nodes == 0) + { + strcpy(paraname, mib_curr_node->name); + } + else + { + debug_get_all_value = mib_curr_node->total_child_nodes; + if(mib_curr_node->total_child_nodes==1) + param_node = mib_curr_node->child_nodes[0]->child_ptr; + } + + if( (toupper(temp_str[0]) == 'R') && (toupper(temp_str[1]) == 'E') && (toupper(temp_str[2]) == 'S') && (toupper(temp_str[3]) == 'E') && (toupper(temp_str[4]) == 'R') && (toupper(temp_str[5]) == 'V') && (toupper(temp_str[6]) == 'E') && (toupper(temp_str[7]) == 'D') && (toupper(temp_str[8]) == '\0') ) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This node is Reserved. Can not get its value.\r\n"); + return 0; + } + + //if(print_once==0 && field_compute_state==5) + // print_once=2; + + + send_msgbuf.pdu_type = 0; + send_msgbuf.request_id = 0; + send_msgbuf.var_num = 1; + for(i=0; i<32; i++) + send_msgbuf.var[0].oid[i] = mib_curr_node->oid[i]; + send_msgbuf.var[0].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance; + send_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + + for(i=0;ip_index=16) + { + debug_ascii_out_proc("Fail : There is not host ip available.\r\n"); + return 0; + } + send_addr.local_ip = Local_IP; + send_addr.remote_port = SNMP_PORT; + send_addr.local_port = DEBUG_SNMP_PORT; + send_addr.broadcast = 0; + + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = 0; + recv_msgbuf.var_num = 1; + for(i=0; i<32; i++) + recv_msgbuf.var[0].oid[i] = mib_curr_node->oid[i]; + recv_msgbuf.var[0].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance; + recv_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + + for(i=0; i<256; i++) + recv_msgbuf.var[0].msg[i] = 0; + + recv_addr.remote_ip = send_addr.remote_ip; + recv_addr.local_ip = Local_IP; + recv_addr.remote_port = SNMP_PORT; + recv_addr.local_port = DEBUG_SNMP_PORT; + recv_addr.broadcast = 0; + bind_num=1; + + ip_index = 0; + get_state = 1; + debug_cfg_end = 0; + for(i=0;i<256;i++) + { + if(curr_instance_arr[i].eable==1) + break; + } + if(i==256) + none_instance=1; + else + none_instance=0; + if(list_flag==0) + { + get_show_state=1; + //show_snmp_state=1; + show_all_value = 1; + } + + /* + if(show_snmp_state==1) + { + debug_ascii_out_proc("GetStatus:"); + debug_color_out(BRIGHT,CYAN,BLACK,"Waiting..."); + } + //sprintf(out_text, "1 %s = ", temp_str); + //debug_ascii_out_proc(out_text); + */ + return 1; +}// end of debug_mmi_get_all + + +/* +* +* Fun: debug_mmi_get +* +* Desc: handle the get command, if valid, start the debug_snmp_get_rt +* +* Ret: return 1 if successful, return 0 if fail +* +* File: debug.c +* +*/ +int debug_mmi_get(char *child_name) +{ + int i,ins; + WORD child_index; + mib_child_node *child_node_ptr; + char out_text[256], temp_str[256]; + char *p,str_ins_id[32]; + WORD oid=0; + + if (!(mib_curr_node->total_instance)) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : There is no instance for the current object\r\n"); + debug_cfg_end=1; + return 0; + } + if (!mib_curr_node->total_child_nodes) + { + debug_cfg_end=1; + debug_color_out(BRIGHT,RED,BLACK,"Fail : No child object for the current object\r\n"); + return 0; + } + + if (mib_curr_node->max_access == 0) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS is 'INVALID'. Can not get its value.\r\n"); + debug_cfg_end=1; + return 0; + } + if (mib_curr_node->max_access == 1) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS is 'NOT-ACCESSIBLE'. Can not get its value.\r\n"); + debug_cfg_end=1; + return 0; + } + if (mib_curr_node->max_access == 6 && snmp_agent_flag==0) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS is 'WRITE-ONLY'. Can not get its value.\r\n"); + debug_cfg_end=1; + return 0; + } + for(i=0;i!=strlen(child_name);i++) + { + if(*(child_name+i)!=' ') + break; + } + p=child_name+i; + strcpy(child_name,p); + if(child_name[0]=='#')//get # + { + p=child_name+1; + strcpy(child_name,p); + for(i=0;icurr_instance; + if(ins>mib_curr_node->total_instance-1) + { + sprintf(temp_str,"Error : The max instance id is %d\r\n",mib_curr_node->total_instance-1); + debug_color_out(BRIGHT,RED,BLACK,temp_str); + return 0; + } + mib_curr_node->curr_instance=ins; + if(i==strlen(child_name)) //#3 + { + debug_get_all_value= mib_curr_node->total_child_nodes; + } + else + { + p=child_name+i+1; + strcpy(child_name,p); + if (isdigit(child_name[0])) //#3.2 + { + oid = strtoul(child_name, NULL, 10); + if(oid>0) + { + oid--; + child_index = find_child_index(mib_curr_node, oid, NULL, 0); + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : There is no such child.\n"); + return 0; + } + } + else //#3.ENABLE + child_index = find_child_index(mib_curr_node, 0, child_name, 1); + + if (child_index < MIB_MAX_CHILD_NODES_PER_NODE) + { + child_node_ptr = mib_curr_node->child_nodes[child_index]; + if (!child_node_ptr->child_ptr) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such child object for the current object\r\n"); + return 0; + } + debug_get_all_value= 301; + param_node = (mib_node_param *)child_node_ptr->child_ptr; + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : There is no such child.\n"); + return 0; + } + strcpy(temp_str, param_node->name); + if( (toupper(temp_str[0]) == 'R') && (toupper(temp_str[1]) == 'E') && (toupper(temp_str[2]) == 'S') && (toupper(temp_str[3]) == 'E') && (toupper(temp_str[4]) == 'R') && (toupper(temp_str[5]) == 'V') && (toupper(temp_str[6]) == 'E') && (toupper(temp_str[7]) == 'D') && (toupper(temp_str[8]) == '\0') ) + { + sprintf(out_text, "Error : %s is Reserved. Can not get its value.\r\n", param_node->name); + debug_color_out(BRIGHT,RED,BLACK,out_text); + return 0; + } + } + } + else if(child_name[0]=='*' && child_name[1]=='\0') //get * + { + debug_mmi_get_all(); + return 1; + } + else if(strncmp(child_name,"*.",2)==0) //get *. + { + p=child_name+2; + strcpy(child_name,p); + + if (isdigit(child_name[0])) + { + oid = strtoul(child_name, NULL, 10); + if(oid>0) + { + oid--; + child_index = find_child_index(mib_curr_node, oid, NULL, 0); + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such child object for the current object\r\n"); + return 0; + } + } + else + child_index = find_child_index(mib_curr_node, 0, child_name, 1); + + if (child_index < MIB_MAX_CHILD_NODES_PER_NODE) + { + child_node_ptr = mib_curr_node->child_nodes[child_index]; + if (!child_node_ptr->child_ptr) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : No such child object for the current object\r\n"); + return 0; + } + debug_get_all_value= 301; + param_node = (mib_node_param *)child_node_ptr->child_ptr; + } + else + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : There is no such child.\n"); + return 0; + } + strcpy(temp_str, param_node->name); + if( (toupper(temp_str[0]) == 'R') && (toupper(temp_str[1]) == 'E') && (toupper(temp_str[2]) == 'S') && (toupper(temp_str[3]) == 'E') && (toupper(temp_str[4]) == 'R') && (toupper(temp_str[5]) == 'V') && (toupper(temp_str[6]) == 'E') && (toupper(temp_str[7]) == 'D') && (toupper(temp_str[8]) == '\0') ) + { + sprintf(out_text, "Error : %s is Reserved. Can not get its value.\r\n", param_node->name); + debug_color_out(BRIGHT,RED,BLACK,out_text); + return 0; + } + } + /* + if(debug_get_all_value==mib_curr_node->total_child_nodes) + if(print_once==0 && field_compute_state==5) + print_once=2; + */ + + send_msgbuf.pdu_type = 0; + send_msgbuf.request_id = 0; + send_msgbuf.var_num = 1; + for(i=0; i<32; i++) + send_msgbuf.var[0].oid[i] = mib_curr_node->oid[i]; + send_msgbuf.var[0].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance; + send_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + + for(ip_index=0;ip_index<16;ip_index++) + { + if(IP_Selected[ip_index] != 1) + continue; + send_addr.remote_ip = Peer_IP[ip_index]; + break; + } + if(ip_index>=16) + { + debug_ascii_out_proc("Fail : There is not host ip available.\r\n"); + return 0; + } + send_addr.local_ip = Local_IP; + send_addr.remote_port = SNMP_PORT; + send_addr.local_port = DEBUG_SNMP_PORT; + send_addr.broadcast = 0; + + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = 0; + recv_msgbuf.var_num = 1; + for(i=0; i<32; i++) + recv_msgbuf.var[0].oid[i] = mib_curr_node->oid[i]; + recv_msgbuf.var[0].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance; + recv_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + + for(i=0; i<256; i++) + recv_msgbuf.var[0].msg[i] = 0; + + recv_addr.remote_ip = send_addr.remote_ip; + recv_addr.local_ip = Local_IP; + recv_addr.remote_port = SNMP_PORT; + recv_addr.local_port = DEBUG_SNMP_PORT; + recv_addr.broadcast = 0; + bind_num=1; + + get_state = 1; + debug_cfg_end = 0; + for(i=0;i<256;i++) + { + if(curr_instance_arr[i].eable==1) + break; + } + if(i==256) + none_instance=1; + else + none_instance=0; + if(list_flag==0) + { + get_show_state=1; + //if(contents_state!=0) + // show_snmp_state=1; + show_all_value = 1; + } + /*if(show_snmp_state==1) + { + debug_ascii_out_proc("GetStatus:"); + debug_color_out(BRIGHT,CYAN,BLACK,"Waiting..."); + }*/ + // strcpy(paraname,child_node_ptr->name); + + return 1; +} // end of deubg_mmi_get + +/* +* +* Fun: debug_mmi_set +* +* Desc: handle the set command, if valid, full fill the value and start the debug_snmp_set_rt +* +* Ret: return 1 if successful, return 0 if fail +* +* File: debug.c +* +*/ +int debug_mmi_set(char *set_str) +{ + int i, j, k, ins; + BYTE str_len; + WORD child_index; + WORD oid=0; + mib_child_node *child_node_ptr; + char child_name[80], out_text[256], *temp_ch; + char str_ins_id[10]; + char p,q; + if(save_flag==0) + save_flag=1; + + if(strlen(set_str)>80) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : the string is too long !\r\n"); + return 0; + } + + strcpy(child_name, set_str); + for(i=0;i!=strlen(child_name);i++) + { + if(*(child_name+i)!=' ') + break; + } + if(*(child_name+i)=='\0') //set + { + strcpy(set_ins_value, curr_instance_value); + temp_instance=mib_curr_node->curr_instance; + strcpy(child_name,""); + set_all=1; + } + temp_ch=child_name+i; + strcpy(child_name,temp_ch); + if(child_name[0]=='#')//set # + { + temp_ch=child_name+1; + strcpy(child_name,temp_ch); + for(i=0;imib_curr_node->total_instance-1) + { + sprintf(out_text,"Error : The max instance id is %d\r\n",mib_curr_node->total_instance-1); + debug_color_out(BRIGHT,RED,BLACK,out_text); + return 0; + } + temp_instance=mib_curr_node->curr_instance; + mib_curr_node->curr_instance=ins; + + if(*(child_name+i)=='\0') //set #3 + { + //debug_get_all_value= mib_curr_node->total_child_nodes; + /* if(mib_curr_node->enable_field_id==0xFF) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please input the value !\r\n"); + return 0; + } + */ + + + strcpy(set_ins_value, curr_instance_value); + strcpy(child_name,""); + set_all=1; + } + else if(*(child_name+i)=='=')//#3= + { + if(mib_curr_node->total_child_nodes==1) + { + temp_ch=child_name+i+1; + strcpy(out_text,"1="); + strcat(out_text,temp_ch); + strcpy(child_name,out_text); + strcpy(set_ins_value,""); + } + else + { + temp_ch=child_name+i+1; + if(temp_ch!=NULL) + { + strcpy(child_name,temp_ch); + for(i=0;icurr_instance; + if(child_name[1]=='\0') //* + { + /* + if(mib_curr_node->enable_field_id==0xFF) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please input the value !\r\n"); + return 0 ; + } + */ + strcpy(set_ins_value, curr_instance_value); + strcpy(child_name,""); + set_all=1; + } + else if(child_name[1]=='=') //*= + { + if(mib_curr_node->total_child_nodes==1 && save_flag<3) + { + temp_ch=child_name+2; + strcpy(out_text,"1="); + strcat(out_text,temp_ch); + strcpy(child_name,out_text); + strcpy(set_ins_value,""); + } + else + { + if(child_name[2]!='\0') + temp_ch=child_name+2; + strcpy(child_name,temp_ch); + for(i=0;i=48 ))&& (!(*(set_ins_value+i)<=70 && *(set_ins_value+i)>=65)) && (!(*(set_ins_value+i)>=97 && *(set_ins_value+i)<=102))) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : please input 0-9 or a-f or A-F\r\n"); + return 0; + } + else if(isdigit(*(set_ins_value+i))) + { + out_text[i]=*(set_ins_value+i)-48; + } + else if((*(set_ins_value+i)<=70 && *(set_ins_value+i)>=65))//A-F + { + out_text[i]=*(set_ins_value+i)-55; + } + else if((*(set_ins_value+i)>=97 && *(set_ins_value+i)<=102))//a-f + { + out_text[i]=*(set_ins_value+i)-87; + } + } + //strncpy(set_ins_value,out_text,set_str_len); + i=0; + j=0; + k=0; + while(itotal_instance)) + { + debug_ascii_out_proc("Fail : There is no instance for the current object\r\n"); + return 0; + } + + if (!(str_len = strlen(child_name))) + { + debug_ascii_out_proc("Fail : No child name in the set command.\r\n"); + return 0; + } + + if (!mib_curr_node->total_child_nodes) + { + debug_ascii_out_proc("Fail : No child object for the current object\r\n"); + return 0; + } + + if (mib_curr_node->max_access == 0) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS property is 'INVALID'. Can not set its value.\r\n"); + return 0; + } + if (mib_curr_node->max_access == 1) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS property is 'NOT-ACCESSIBLE'. Can not set its value.\r\n"); + return 0; + } + if (mib_curr_node->max_access == 3) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS property is 'READ-ONLY'. Can not set its value.\r\n"); + return 0; + } + + child_name[str_len] = '\0'; + + if (isdigit(child_name[0])) + { + oid = strtoul(child_name, NULL, 10)-1; + child_index = find_child_index(mib_curr_node, oid, NULL, 0); + } + else + child_index = find_child_index(mib_curr_node, 0, child_name, 1); + + if (child_index < MIB_MAX_CHILD_NODES_PER_NODE) + { + child_node_ptr = mib_curr_node->child_nodes[child_index]; + if (!child_node_ptr->child_ptr) + { + debug_ascii_out_proc("Fail : No such child object for the current object\r\n"); + return 0; + } + param_node = (mib_node_param *)child_node_ptr->child_ptr; + if(param_node->select_total != 0) //\u5224\u65AD\u8F93\u5165\u7684\u6570\u503C\u662F\u5426\u6709\u6548\uFF0C\u662F\u5426\u5B58\u5728\u8BE5\u6570\u503C\u4EE3\u8868\u7684select\u9009\u9879 + { + if(set_val == -1) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : The select option value must be digit or a-f.\r\n"); + return 0; + } + + for(i=0; iselect_total; i++) + { + if(param_node->select_ptr[i]->number == set_val) + break; + } + if(i >= param_node->select_total) + { + sprintf( out_text, "Fail : The value %u is not exist in the select options:\r\n", set_val); + debug_color_out(BRIGHT,RED,BLACK,out_text); + sprintf(out_text,"%d",param_node->id+1); + debug_mmi_option(out_text); + return 0; + } + } + if(param_node->input_ptr != NULL) + { + switch(param_node->input_ptr->input_param_type) + { + case 0: //toDec_high_0 //\u5224\u65AD\u8F93\u5165\u7684\u6570\u503C\u662F\u5426\u6709\u6548 + j = strlen(set_val_str); + for(i=0; i(param_node->byte_end-param_node->byte_begin+(param_node->bit_end-param_node->bit_begin+1)/8)) + { + sprintf( out_text, "Error : The value must be less than %d byte!\r\n",(param_node->byte_end-param_node->byte_begin+(param_node->bit_end-param_node->bit_begin+1)/8)); + debug_ascii_out_proc(out_text); + return 0; + } + */ + j =(param_node->byte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin); + set_val = atol(set_val_str); + if(set_val > my_pow(2, j)) + { + sprintf( out_text, "Error : The value must be less than %u.\r\n", (my_pow(2,j)-1) ); + debug_ascii_out_proc(out_text); + return 0; + } + } + break; + case 1: //keepHex_high_0 //\u5224\u65AD\u8F93\u5165\u7684\u6570\u503C\u5B57\u7B26\u4E32set_val_str\u662F\u5426\u6709\u6548, \u5982\u679C\u6709\u6548\u5219\u5C06\u9AD8\u4F4D\u8865\u6210\u5B57\u7B26'0'\uFF0C\u8865\u8DB3\u4F4D\u6570 + j = strlen(set_val_str); + for(i=0; i= 'A') && (set_val_str[i] <= 'F')) //is A to F + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + sprintf(out_text, "Error : The length of the value string must be less than %d.\r\n", i); + debug_ascii_out_proc(out_text); + return 0; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u9AD8\u4F4D\u8865\u6210'0' + k = i-j; + for(j=i-1; (j-k)>=0 && j!=0; j--) + set_val_str[j]=set_val_str[j-k]; + set_val_str[i] = '\0'; + for(j=0; j= 'A') && (set_val_str[i] <= 'F')) //is A to F + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + sprintf(out_text, "The length of the value string must be less than %d.\r\nFAIL\r\n", i); + debug_ascii_out_proc(out_text); + return 0; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'0' + for(; j= 'A') && (set_val_str[i] < 'E')) //is A to D + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + sprintf(out_text, "The length of the value string must be less than %d.\r\nFail\r\n", i); + debug_ascii_out_proc(out_text); + return 0; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210E + for(; j= 'A') && (set_val_str[i] < 'F')) //is A to E + continue; + break; + } + if(ibyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/4; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + sprintf(out_text, "The length of the value string must be less than %d.\r\nFAIL\r\n", i); + debug_ascii_out_proc(out_text); + return 0; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'F' + for(; jbyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/8; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + sprintf(out_text, "The length of the AscII string must be less than %d.\r\nFAIL\r\n", i); + debug_ascii_out_proc(out_text); + return 0; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'0' + for(; jbyte_end * 8 + 1 + param_node->bit_end) - (param_node->byte_begin * 8 - param_node->bit_begin) )/8; + if(j > i) //\u5B57\u7B26\u4E32\u957F\u5EA6\u5927\u4E8E\u6240\u80FD\u5B58\u50A8\u7684\u4F4D\u6570\uFF0C\u5219\u63D0\u793A\u5E76\u9000\u51FA + { + sprintf(out_text, "The length of the AscII string must be less than %d.\r\nFAIL\r\n", i); + debug_ascii_out_proc(out_text); + return 0; + } + + //\u8F93\u5165\u6709\u6548\uFF0C\u5219\u5C06\u4F4E\u4F4D\u8865\u6210'F' + for(; jsys_group==9) + for(i=0;ioid[i]; + send_msgbuf.var[0].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance; + send_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + + for(i=0;i<16;i++) + { + if(IP_Selected[i] != 1) + continue; + send_addr.remote_ip = Peer_IP[i]; + break; + } + if(i>=16) + { + debug_ascii_out_proc("There is not host ip available.\r\n"); + return 0; + } + + + send_addr.local_ip = Local_IP; + send_addr.remote_port = SNMP_PORT; + send_addr.local_port = DEBUG_SNMP_PORT; + send_addr.broadcast = 0; + + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = 0; + recv_msgbuf.var_num = 1; + for(i=0; i<32; i++) + recv_msgbuf.var[0].oid[i] = mib_curr_node->oid[i]; + recv_msgbuf.var[mib_curr_node->oid_len].oid[i] = (DWORD)mib_curr_node->curr_instance; + recv_msgbuf.var[0].oidlen = mib_curr_node->oid_len + 1; + + for(i=0; i<256; i++) + recv_msgbuf.var[0].msg[i] = 0; + + recv_addr.remote_ip = send_addr.remote_ip; + recv_addr.local_ip = Local_IP; + recv_addr.remote_port = SNMP_PORT; + recv_addr.local_port = DEBUG_SNMP_PORT; + recv_addr.broadcast = 0; + + ip_index = 0; + set_state = 1; + debug_cfg_end = 0; + + return 1; +} // end of debug_mmi_set + + + +/* +* +* Fun: debug_snmp_get_rt +* +* Desc: get the mib_node's value from the host by snmp, then analyze and show the value of its field's value +* +* Ret: RVOID +* +* Notes: Wang Jian add +* +* File debug.c +* +*/ +void debug_snmp_get_rt() +{ + int request_id=0, index,i; + char out_text[256]=""; + BYTE value_valid; + char type_str[31]; + char out_text1[128]; + char temp_str[32]; + char out_ins_text[256]; + BYTE ins_byte,field_id; + BYTE ins_bit; + BYTE byte,bit; + WORD curr_select_id; + mib_child_node *child_node_ptr; + param_field *tmp_param_field; + + + + + switch(get_state) + { + case 0: //idle + break; + case 1: //send local get request to local host + t5s_flag=0; + + if (mib_curr_node->max_access == 0) + { + //debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS is 'INVALID'. Can not get its value.\r\n"); + get_state=0; + debug_cfg_end=1; + return ; + } + if (mib_curr_node->max_access == 1) + { + //debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS is 'NOT-ACCESSIBLE'. Can not get its value.\r\n"); + get_state=0; + debug_cfg_end=1; + return ; + } + if (mib_curr_node->max_access == 6 && snmp_agent_flag==0) + { + //debug_color_out(BRIGHT,RED,BLACK,"Error : This leaf node's MAX-ACCESS is 'WRITE-ONLY'. Can not get its value.\r\n"); + get_state=0; + debug_cfg_end=1; + return ; + } + for(ip_index=0;ip_index=ip_num) + { + if(snmp_agent_flag==0) + debug_color_out(BRIGHT,RED,BLACK,"Fail : Can not get the value because there is not host ip available.\r\n"); + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=4; + mib_curr_node=agent_tmp_node; + } + ip_index = 0; + snmp_agent_flag=0; + debug_cfg_end = 1; + get_state = 0; + snmp_agent_flag=0; + debug_get_all_value = 0; + break; + } + + request_id = snmp_send(&send_msgbuf, &send_addr); + if(request_id == 0) + { + if(snmp_agent_flag==0) + { + sprintf(out_text, "Error : Fail to send snmp get request to the host: %s %s\r\n", Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + debug_ascii_out_proc(out_text); + } + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=9; + mib_curr_node=agent_tmp_node; + } + ip_index = 0; + snmp_agent_flag=0; + debug_cfg_end = 1; + get_state = 0; + snmp_agent_flag=0; + debug_get_all_value = 0; + } + else + { + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = request_id; + recv_addr.remote_ip = send_addr.remote_ip; + get_state = 2; + } + break; + case 2: //receive local get response + request_id = snmp_receive(&recv_msgbuf, &recv_addr); + if(request_id == 0) // not received + { + if(t5s_flag > 250) + { + if(snmp_agent_flag==0) + { + //if(list_once==1) + { + if(list_once==0) + { + mib_node_param *node_param_ptr; + debug_ascii_out_proc("Child : "); + sprintf(out_text, "[%d]\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,YELLOW,BLACK,out_text); + for (i = 0; i < mib_curr_node->total_child_nodes; i++) + { + child_node_ptr = mib_curr_node->child_nodes[i]; + node_param_ptr=(mib_node_param *)child_node_ptr->child_ptr; + sprintf(out_text, " |---(%u) %s\r\n",child_node_ptr->oid+1, node_param_ptr->name); + debug_color_out(BRIGHT,YELLOW,BLACK,out_text); + } + } + sprintf(out_text, "Fail : Time out! Check the connection to Host:%s(%s)\r\n",Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + debug_ascii_out_proc(out_text); + } + + } + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=1; + mib_curr_node=agent_tmp_node; + } + ip_index=0; + list_flag=0; + snmp_agent_flag=0; + list_start=list_end=0; + get_show_state=0; + debug_cfg_end = 1; + get_state = 0; + snmp_agent_flag=0; + debug_get_all_value = 0; + break; + } + else + break; + } + debug_cfg_end = 0; + get_state = 3; + break; + case 3: // received + //for look + if(snmp_agent_flag==0) + { + if(recv_msgbuf.error_status != 0) + { + //sprintf(out_text, "Fail : get value from the host: %s[%s]",Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + switch(recv_msgbuf.error_status) + { + case 1: + strcat(out_text,"Error : TooBig\r\n"); + break; + case 5: + strcat(out_text,"Error : GenErr\r\n"); + break; + case 6: + strcat(out_text,"Error : NoAccessl\r\n"); + break; + case 7: + strcat(out_text,"Error : WrongType\r\n"); + break; + case 8: + strcat(out_text,"Error : WrongLength\r\n"); + break; + case 9: + strcat(out_text,"Error : WrongEncoding\r\n"); + break; + case 10: + strcat(out_text,"Error : WrongValue\r\n"); + break; + case 11: + strcat(out_text,"Error : NoCreation\r\n"); + break; + case 12: + strcat(out_text,"Error : inconsistentValue\r\n"); + break; + case 13: + strcat(out_text,"Error : resourceUnavailable\r\n"); + break; + case 14: + strcat(out_text,"Error : commitFailed\r\n"); + break; + case 15: + strcat(out_text,"Error : UndoFailed\r\n"); + break; + case 16: + strcat(out_text,"Error : AuthorizationError\r\n"); + break; + case 17: + strcat(out_text,"Error : NoWritable\r\n"); + break; + case 18: + strcat(out_text,"Error : inconsistentName\r\n"); + break; + default: + break; + } + if(snmp_agent_flag==0) + debug_color_out(BRIGHT,RED,BLACK,out_text); + ip_index=0; + snmp_agent_flag=0; + debug_cfg_end = 1; + get_state = 0; + snmp_agent_flag=0; + debug_get_all_value = 0; + break; + } + strcpy(out_ins_text,""); + if(get_show_state==1) + { + show_all_value=1; + show_type=0; + show_expend=1; + show_range=0; + } + } + + while(bind_indexname); + TxtColor(BRIGHT,YELLOW,BLACK,out_text1); + strcat(out_ins_text,out_text1); + if(!(none_instance==1 || show_empty==1)) + sprintf(out_text1,"#%-3d ",mib_curr_node->curr_instance+bind_index); + else + strcpy(out_text1,""); + + if(mib_curr_node->total_child_nodes>1 || show_expend==0) + strcat(out_text1,"\r\n"); + strcat(out_ins_text,out_text1); + + show_list=1; + } + + if(show_all_value==0 ) + { + if(mib_curr_node->total_child_nodes==1) + { + param_node=mib_curr_node->child_nodes[0]->child_ptr; + if(param_node!=NULL) + { + if(param_node->input_ptr!=NULL) + { + if(param_node->input_ptr->input_param_type==0) + index=1; + else + index=strncmp(mib_curr_node->init_value, (char *)recv_msgbuf.var[bind_index].msg,mib_curr_node->data_length); + } + } + } + else + index=strncmp(mib_curr_node->init_value, (char *)recv_msgbuf.var[bind_index].msg,mib_curr_node->data_length); + + if(mib_curr_node->enable_field_id!=0xFF) + { + param_node = mib_curr_node->child_nodes[mib_curr_node->enable_field_id]->child_ptr; + if(param_node->byte_begin==param_node->byte_end && param_node->bit_begin ==param_node->bit_end) + { + ins_byte=param_node->byte_begin; + ins_bit=param_node->bit_begin ; + if(recv_msgbuf.var[bind_index].msg[ins_byte] & (BYTE)my_pow(2,ins_bit)) + index=1; + else + index=0; + } + } + if(index) + { + byte=(mib_curr_node->curr_instance+bind_index)/8; + bit=(mib_curr_node->curr_instance+bind_index)%8; + mib_curr_node->enable_flag[byte]=mib_curr_node->enable_flag[byte] | (BYTE)my_pow(2,bit); + curr_instance_arr[mib_curr_node->curr_instance+bind_index].ins=mib_curr_node->curr_instance+bind_index; + curr_instance_arr[mib_curr_node->curr_instance+bind_index].eable=1; + } + else + { + byte=(mib_curr_node->curr_instance+bind_index)/8; + bit=(mib_curr_node->curr_instance+bind_index)%8; + mib_curr_node->enable_flag[byte]=mib_curr_node->enable_flag[byte] & (~(BYTE)my_pow(2,bit)); + curr_instance_arr[mib_curr_node->curr_instance+bind_index].ins=mib_curr_node->curr_instance+bind_index; + curr_instance_arr[mib_curr_node->curr_instance+bind_index].eable=0; + } + } + } + if(((bind_num==1 && debug_snmp_agent_buf[debug_agent_index].cmm_state==3 )|| (debug_snmp_agent_buf[bind_index].cmm_state ==3 && bind_num!=1)) && snmp_agent_flag==1) + { + show_list=1; + show_all_value=1; + show_expend=1; + debug_get_all_value=mib_curr_node->total_child_nodes; + } + + + if(show_list==1) + { + if(index!=0 || show_all_value==1) + { + if(snmp_agent_flag==0 && field_compute_state!=4) + debug_ascii_out_proc(out_ins_text); + if(show_expend==1) + { + + while(debug_get_all_value != 0 ) + { + debug_cfg_end = 0; + get_state = 3; + if(debug_get_all_value!=301) + { + param_node = mib_curr_node->child_nodes[mib_curr_node->total_child_nodes - debug_get_all_value]->child_ptr; + if(snmp_agent_flag==0) + if(show_field==1) + { + for(i=0;list_field_arr[i]!=0xFF && i<64;i++) + { + if(list_field_arr[i]==mib_curr_node->total_child_nodes - debug_get_all_value+1) + { + break; + } + } + if( list_field_arr[i]==0xFF || i==64) + { + debug_get_all_value--; + continue; + } + else if(list_field_arr[i]==mib_curr_node->total_child_nodes - debug_get_all_value+1) + { + ; + } + } + } + if(param_node == NULL) + {// not error but mib_curr_node has no child + int index2, index3; + DWORD sum; + int sub_sum, find_first, byte_begin, byte_end, bit_begin, bit_end; + find_first = 0; + strcpy(out_text, ""); + sub_sum=0; + index3 = 0; + sum = 0; + byte_begin = 0; + byte_end = recv_msgbuf.var[bind_index].msglen - 1; + bit_begin = 0; + bit_end = 7; + strcpy(out_text, "0x"); + for(index=byte_begin; index <= byte_end; index++) + { + if(index == byte_begin) //index--byte index + index2 = bit_begin; + else + index2 = 0; + for(; index2<8; index2++)//index2--bit index + { + if(index3 == 0) + sub_sum = 0; + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0)//get index bit + sub_sum += my_pow(2, index3); + index3++; + if( (index == byte_end) && (index2 == bit_end)) + { + switchchar(out_text,sub_sum & 0xF0); + switchchar(out_text,sub_sum & 0x0F); + } + if(index3==8) + { + switchchar(out_text,sub_sum & 0xF0); + switchchar(out_text,sub_sum & 0x0F); + index3 = 0; + } + } + } + if(strlen(out_text) == 2) + value_valid=0; + strcpy(type_str,"Hex"); + ip_index = 0; + debug_cfg_end = 1; + get_state = 0; + debug_get_all_value = 0; + break; + } + + else if((recv_msgbuf.var[bind_index].vartype == 2) || (recv_msgbuf.var[bind_index].vartype == 4)) //int or string + {// not error but mib_curr_node has children + + char temp_str[16]=""; + int index2, index3; + DWORD sum; + int sub_sum, find_first, index4; + find_first = 0; + strcpy(out_text, ""); + + if(param_node->input_ptr != NULL) + { + switch(param_node->input_ptr->input_param_type) + { + case 0: //toDec_high_0 + index3 = sum = 0; + for(index=param_node->byte_end; index >=param_node->byte_begin; index--) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sum += my_pow(2, index3); + index3++; + if( (index == param_node->byte_begin) && (((param_node->byte_begin==param_node->byte_end)&& index2 == param_node->bit_end) || ((param_node->byte_begin!=param_node->byte_end)&& index2==7))) + break; + + } + if( (index == param_node->byte_begin) && (((param_node->byte_begin==param_node->byte_end)&& index2 == param_node->bit_end) || ((param_node->byte_begin!=param_node->byte_end)&& index2==7))) + break; + } + sprintf(out_text, "%u", sum); + strcpy(type_str,"toDec-hight-0"); + break; + case 1: //keepHex_high_0 + sub_sum=0; + index3 = 0; + sum = 0; + strcpy(out_text, ""); + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if(index3 == 0) + sub_sum = 0; + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sub_sum += my_pow(2, index3); + index3++; + + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + { + switchchar(out_text,sub_sum & 0xF0); + switchchar(out_text,sub_sum & 0x0F); + if(out_text[strlen(out_text)]=='0') + ; + value_valid=0; + break; + } + if(index3==8) + { + switchchar(out_text,sub_sum & 0xF0); + switchchar(out_text,sub_sum & 0x0F); + index3 = 0; + } + } + } + sprintf(out_text1,"%s ",out_text); + strcpy(out_text,out_text1); + strcpy(type_str,"keepHex-high-0"); + break; + case 2: //keepHex_low_0 + sub_sum=0; + index4=0; + index3 = 0; + sum = 0; + strcpy(out_text, ""); + for(index=param_node->byte_begin; index <= param_node->byte_end ; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if(index3 == 0) + sub_sum = 0; + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sub_sum += my_pow(2, index3); + index3++; + if(index3==8) + { + switchchar(out_text,sub_sum & 0xF0); + if((sub_sum & 0xF0)==0x00 ) + { + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + switchchar(out_text,sub_sum & 0x0F); + if((sub_sum & 0x0F)==0x00) + { + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + index3 = 0; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + { + switchchar(out_text,sub_sum & 0x00); + if((sub_sum & 0xF0)==0x00 ) + { + if(strlen(out_text) == 1) + value_valid=0; + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + switchchar(out_text,sub_sum & 0x0F); + if((sub_sum & 0x0F)==0x00) + { + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + index3=0; + } + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + if(find_first == 1) + break; + } + strcpy(type_str,"keepHex-low-0"); + break; + case 3: //keepHex_low_E + sub_sum=0; + index4=0; + index3 = 0; + sum = 0; + strcpy(out_text, ""); + for(index=param_node->byte_begin; index <= param_node->byte_end ; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if(index3 == 0) + sub_sum = 0; + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sub_sum += my_pow(2, index3); + index3++; + if(index3==8) + { + switchchar(out_text,sub_sum & 0xF0); + if((sub_sum & 0xF0)==0xE0 ) + { + if(strlen(out_text) == 1) + value_valid=0; + out_text[strlen(out_text)-1]='\0'; + + find_first = 1; + break; + } + switchchar(out_text,sub_sum & 0x0F); + if((sub_sum & 0x0F)==0x0E) + { + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + index3 = 0; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end) && param_node->bit_end!=7) + { + switchchar(out_text,sub_sum & 0xF0); + if((sub_sum & 0xF0)==0xE0 ) + { + out_text[strlen(out_text)]='\0'; + find_first = 1; + break; + } + switchchar(out_text,sub_sum & 0x0F); + if((sub_sum & 0x0F)==0x0E) + { + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + index3=0; + } + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + if(find_first == 1) + break; + } + strcpy(type_str,"keepHex-low-E"); + //printf("The keephex_low_e:%s",out_text); + break; + case 4: //keepHex_low_F + sub_sum=0; + index4=0; + index3 = 0; + sum = 0; + strcpy(out_text, ""); + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if(index3 == 0) + sub_sum = 0; + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sub_sum += my_pow(2, index3); + index3++; + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + { + switchchar(out_text,sub_sum & 0xF0); + if((sub_sum & 0xF0)==0xF0 ) + { + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + switchchar(out_text,sub_sum & 0x0F); + if((sub_sum & 0x0F)==0x0F) + { + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + index3=0; + } + if(index3==8) + { + switchchar(out_text,sub_sum & 0xF0); + if((sub_sum & 0xF0)==0xF0 ) + { + if(strlen(out_text) == 1) + value_valid=0; + out_text[strlen(out_text)-1]='\0'; + find_first = 1; + break; + } + switchchar(out_text,sub_sum & 0x0F); + if((sub_sum & 0x0F)==0x0F) + { + out_text[strlen(out_text)-1]='\0'; + + find_first = 1; + break; + } + index3 = 0; + } + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + if(find_first == 1) + break; + } + strcpy(type_str,"keepHex-low-F"); + break; + case 5: //toAscii_low_0 + sub_sum=0; + index3 = 0; + sum = 0; + strcpy(out_text, ""); + strcpy(temp_str, ""); + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if(index3 == 0) + sub_sum = 0; + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sub_sum += my_pow(2, index3); + index3++; + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + { + if(sub_sum == '0') //\u4EE5 '0' \u7ED3\u5C3E + { + if(strlen(out_text) == 2) + value_valid=0; + find_first = 1; + break; + } + else + { + strcpy(temp_str, ""); + sprintf(temp_str, "%c", sub_sum); + strcat(out_text, temp_str); + } + break; + } + if(index3==8) + { + if(sub_sum == '0') //\u4EE5 0 \u7ED3\u5C3E + { + if(strlen(out_text) == 0) + value_valid=0; + find_first = 1; + break; + } + else + { + strcpy(temp_str, ""); + sprintf(temp_str, "%c", sub_sum); + strcat(out_text, temp_str); + } + index3 = 0; + } + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + if(find_first == 1) + break; + } + strcpy(type_str,"toAscii-low-0"); + break; + case 6: //keepAscii_low_F + sub_sum=0; + index3 = 0; + sum = 0; + strcpy(out_text, ""); + strcpy(temp_str, ""); + + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if(index3 == 0) + sub_sum = 0; + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sub_sum += my_pow(2, index3); + index3++; + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + { + if(sub_sum == 'F') //\u4EE5 'F' \u7ED3\u5C3E + { + if(strlen(out_text) == 2) + value_valid=0; + find_first = 1; + break; + } + else + { + strcpy(temp_str, ""); + sprintf(temp_str, "%c", sub_sum); + strcat(out_text, temp_str); + } + break; + } + if(index3==8) + { + if(sub_sum == 'F') //\u4EE5 'F' \u7ED3\u5C3E + { + if(strlen(out_text) == 0) + value_valid=0; + find_first = 1; + break; + } + else + { + strcpy(temp_str, ""); + sprintf(temp_str, "%c", sub_sum); + strcat(out_text, temp_str); + } + index3 = 0; + } + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + if(find_first == 1) + break; + } + strcpy(type_str,"toAscii-low-F"); + break; + default: + break; + } + param_node->input_ptr->input[0] = sum; + } + else if(param_node->select_total != 0) + { + index3 = sum = 0; + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if((recv_msgbuf.var[bind_index].msg[index] & (BYTE)my_pow(2, index2)) != 0) + sum += my_pow(2, index3); + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + index3++; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + } + strcpy(out_text, ""); + for(index=0; indexselect_total; index++) + { + if(param_node->select_ptr[index]->number == sum) + { + sprintf(out_text, "%u (%s)", sum, param_node->select_ptr[index]->description); + curr_select_id=index; + } + } + if(strlen(out_text) == 0) + sprintf(out_text, "%u (UNREGESTER VALUE)", sum); + } + else + sprintf(out_text, "%u ", sum); + } + + + + del_space(out_text,1); + if(strncasecmp(param_node->name, "reserved", 8) == 0 ) + { + if(snmp_agent_flag==1) + { + field_id=mib_curr_node->total_child_nodes-debug_get_all_value; + tmp_param_field=&snmp_agent_packet.param_field_arr[field_id]; + strcpy(tmp_param_field->name,param_node->name); + } + } + else + { + + if(snmp_agent_flag==0 && field_compute_state!=4) + { + if(mib_curr_node->total_child_nodes==1) + sprintf(out_text1, " |---(%d) %s",param_node->id+1, param_node->name); + else + { + if(debug_get_all_value==301) + sprintf(out_text1, " |---(%d) %s",param_node->id+1, param_node->name); + else + sprintf(out_text1, " |---(%d) %s",1+mib_curr_node->total_child_nodes - debug_get_all_value, param_node->name); + } + + debug_color_out(BRIGHT,YELLOW,BLACK,out_text1); + + if(!(none_instance==1 && show_empty==1)) + { + if(!strlen(out_text)) + { + debug_ascii_out_proc(" = "); + debug_color_out(BRIGHT,BLUE,BLACK,"NULL "); + } + else + { + debug_ascii_out_proc(" = "); + debug_color_out(BRIGHT,BLUE,BLACK,out_text); + debug_ascii_out_proc(" "); + } + } + + if(param_node->input_ptr!=NULL) + { + if(show_type==1 ) + { + //debug_ascii_out_proc("Type : "); + debug_color_out(BRIGHT,YELLOW,BLACK,type_str); + } + } + if(show_range==1) + { + //debug_ascii_out_proc("Range : "); + sprintf(out_text, " [%d.%d - %d.%d]\r\n", param_node->byte_begin, param_node->bit_begin, param_node->byte_end, param_node->bit_end); + debug_color_out(BRIGHT,YELLOW,BLACK,out_text); //for look + } + else + { + if( strncasecmp(param_node->name, "reserved", 8) != 0 ) + debug_ascii_out_proc("\r\n"); + } + + } + else if(snmp_agent_flag==1) + { + + field_id=mib_curr_node->total_child_nodes-debug_get_all_value; + tmp_param_field=&snmp_agent_packet.param_field_arr[field_id]; + if(param_node->select_total!=0) + { + + tmp_param_field->curr_select_id=curr_select_id; + for(index=0; indexselect_total; index++) + { + tmp_param_field->value_arr[index]=param_node->select_ptr[index]->number; + strcpy(tmp_param_field->value_arr_remark[index],param_node->select_ptr[index]->description); + } + tmp_param_field->total_select=param_node->select_total; + tmp_param_field->curr_input_value[0]='\0'; + tmp_param_field->input_type=0xFF; + } + else if(param_node->input_ptr!=NULL) + { + tmp_param_field->curr_select_id=0xFF; + for(index=0; indexvalue_arr[index]=0xFF; + strcpy(tmp_param_field->value_arr_remark[index],""); + } + tmp_param_field->total_select=0; + strcpy(tmp_param_field->curr_input_value,out_text); + tmp_param_field->input_type=param_node->input_ptr->input_param_type; + } + strcpy(tmp_param_field->name,param_node->name); + } + else if(field_compute_state==4 ) + { + if(param_node->select_total!=0) + { + sprintf(temp_str,"%d",param_node->select_ptr[curr_select_id]->number); + strcpy(compute_field_list[compute_field_list_index].field_val[mib_curr_node->curr_instance+bind_index-1],temp_str); + } + else if(param_node->input_ptr!=NULL) + { + strcpy(compute_field_list[compute_field_list_index].field_val[mib_curr_node->curr_instance+bind_index-1],out_text); + } + } + + } + + if(debug_get_all_value==301) + debug_get_all_value=1; + debug_get_all_value--; + + + } + + } + } + } + if(snmp_agent_flag==1) + { + + if(bind_num==1) + { + memcpy(&debug_snmp_agent_buf[debug_agent_index],&snmp_agent_packet,sizeof(debug_snmp_agent)); + debug_snmp_agent_buf[debug_agent_index].cmm_state=5; + debug_snmp_agent_buf[debug_agent_index].result_state=0; + } + else + { + memcpy(&debug_snmp_agent_buf[bind_index],&snmp_agent_packet,sizeof(debug_snmp_agent)); + debug_snmp_agent_buf[bind_index].cmm_state=5; + debug_snmp_agent_buf[bind_index].result_state=0; + debug_snmp_agent_buf[bind_index].oid[debug_snmp_agent_buf[bind_index].oid_len-1]=mib_curr_node->curr_instance+bind_index; + } + + } + bind_index++; + //printf("send ins %d ",mib_curr_node->curr_instance+bind_index); + if(bind_indextotal_child_nodes>4) + return; + } + if(snmp_agent_flag==0 && list_once==1) + { + if(recv_msgbuf.var[bind_index].vartype == 5) //NULL + { + debug_ascii_out_proc("Error : NULL\r\n"); + } + else if(recv_msgbuf.var[bind_index].vartype == 6) //Object identifier + { + debug_ascii_out_proc("Error : Object identifier wrong\r\n"); + } + else if(recv_msgbuf.var[bind_index].vartype == 0x80) //noSuchObject + { + debug_ascii_out_proc("Error : noSuchObject\r\n"); + } + else if(recv_msgbuf.var[bind_index].vartype == 0x81) //NoSuchInstance + { + debug_ascii_out_proc("Error : NoSuchInstance\r\n"); + } + else if(recv_msgbuf.var[bind_index].vartype == 0x82) //endOfMibView + { + debug_ascii_out_proc("Error : endOfMibView\r\n"); + } + } + //sprintf(out_text,"%d-%d ",debug_snmp_agent_buf[debug_agent_index].cmm_state,debug_snmp_agent_buf[debug_agent_index].result_state); + ip_index = 0; + if(list_flag==0) + debug_cfg_end=1; + if(((list_start>=list_end && list_flag) || !list_flag) && !snmp_agent_flag) + { + get_state=0; + bind_num=0; + bind_index=0; + } + if(snmp_agent_flag>0) + get_state=0; + if(snmp_agent_flag>0) + bind_index=0; + get_show_state=0; + //if(snmp_agent_flag==0) + // bind_num=0; + //snmp_agent_flag=0; + expend_view=0; + debug_get_all_value = 0; + t5s_flag=0; + break; + default: + debug_ascii_out_proc("\r\nError : no value for this node.\r\nFail\r\n"); + while(debug_get_all_value != 0) + { + param_node = mib_curr_node->child_nodes[mib_curr_node->total_child_nodes - debug_get_all_value]->child_ptr; + if( strncmp(param_node->name, "Reserved", 8) == 0 ) + { + sprintf(out_text, "%d Reserved.\r\n",1+mib_curr_node->total_child_nodes - debug_get_all_value); + debug_ascii_out_proc(out_text); + debug_get_all_value--; + } + else + break; + } + if(debug_get_all_value != 0) + { + param_node = mib_curr_node->child_nodes[mib_curr_node->total_child_nodes - debug_get_all_value]->child_ptr; + sprintf(out_text, "%d %s = ", 1+mib_curr_node->total_child_nodes - debug_get_all_value, param_node->name); + debug_get_all_value--; + debug_ascii_out_proc(out_text); + debug_cfg_end = 0; + get_state = 3; + } + else + { + ip_index =0; + debug_cfg_end = 1; + get_state = 0; + } + break; + } + +}//end of debug_snmp_get_rt + + + +/* +* +* Fun: debug_snmp_set_rt +* +* Desc: get the mib_node's value from the host by snmp, then analyze and replace the value of its field's value, then set back the mib_node's value to the host by snmp +* +* Ret: RVOID +* +* Notes: Wang Jian add +* +* File: debug.c +* +*/ +void debug_snmp_set_rt() +{ + int request_id=0, index; + char out_text[256]=""; + char out_text2[256]=""; + int ins_byte,ins_bit; + mib_node_param *temp_param; + int i; + + switch(set_state) + { + case 0: //idle + break; + case 1: //send the not null and selected ip in the Peer_IP[16] set request to local host + t5s_flag=0; + if(ip_index >= ip_num) + { + debug_cfg_end = 1; + set_state = 0; + ip_index = 0; + set_ok_once=0; + save_flag=0; + break; + } + if(Peer_IP[ip_index] == 0) + { + debug_cfg_end = 1; + set_state = 0; + if(snmp_agent_flag==0) + { + if(ip_index == 0 ) + debug_color_out(BRIGHT,RED,BLACK,"Error : There is not host ip available.\r\n"); + + } + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=4; + mib_curr_node=agent_tmp_node; + return ; + } + ip_index = 0; + break; + } + + if(IP_Selected[ip_index] == 1) + send_addr.remote_ip = Peer_IP[ip_index]; + else + { + for(; ip_index 250) + { + if(snmp_agent_flag==0) + { + if(save_flag>=3) + { + + //debug_ascii_out_proc("Status : "); + //sprintf(out_text,"Fail to save the module of %s,time out,please check the host\r\n",subsys_module[curr_module].name); + //debug_color_out(BRIGHT,CYAN,BLACK,out_text); + mib_curr_node=temp_mib_node; + sprintf(out_text, "Host : %s %s (State: Time out !)\r\n", Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + if(save_flag==3) + debug_mmi_contents(""); + if(debug_cfg==1) + mib_curr_node=temp_mib_node; + else if(debug_cfg==2) + { + menu_curr_node=tmp_menu_node; + mib_curr_node=temp_mib_node; + } + save_flag=0; + } + else + sprintf(out_text, "Host : %s %s (State: Time out !)\r\n", Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + debug_color_out(BRIGHT,RED,BLACK,out_text); + } + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=1; + mib_curr_node=agent_tmp_node; + snmp_agent_flag=0; + } + ip_index++; + debug_cfg_end = 0; + set_ok_once=0; + set_state = 1; + break; + } + else + break; + } + else //received + { + char byte_val1[16]; + if(snmp_agent_flag==0) + { + if(save_flag<3 || save_flag==4) + { + // debug_ascii_out_proc("OldValue: "); + for(index=0; indexbyte_begin, param_node->bit_begin, param_node->byte_end, param_node->bit_end); + //debug_color_out(BRIGHT,YELLOW,BLACK,out_text1);//for look + } + if(recv_msgbuf.error_status != 0) + { + if(snmp_agent_flag==0) + { + //sprintf(out_text, "Error : get value from the host: %s %s\r\n",Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + //debug_color_out(BRIGHT,RED,BLACK,out_text); + switch(recv_msgbuf.error_status) + { + case 1: + debug_color_out(BRIGHT,RED,BLACK,"Error : TooBig\r\n"); + break; + case 5: + debug_color_out(BRIGHT,RED,BLACK,"Error : GenErr\r\n"); + break; + case 6: + debug_color_out(BRIGHT,RED,BLACK,"Error : NoAccess\r\n"); + break; + case 7: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongType\r\n"); + break; + case 8: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongLength\r\n"); + break; + case 9: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongEncoding\r\n"); + break; + case 10: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongValue\r\n"); + break; + case 11: + debug_color_out(BRIGHT,RED,BLACK,"Error : NoCreation\r\n"); + break; + case 12: + debug_color_out(BRIGHT,RED,BLACK,"Error : inconsistentValue\r\n"); + break; + case 13: + debug_color_out(BRIGHT,RED,BLACK,"Error : resourceUnavailable\r\n"); + break; + case 14: + debug_color_out(BRIGHT,RED,BLACK,"Error : commitFailed\r\n"); + break; + case 15: + debug_color_out(BRIGHT,RED,BLACK,"Error : UndoFailed\r\n"); + break; + case 16: + debug_color_out(BRIGHT,RED,BLACK,"Error : AuthorizationError\r\n"); + break; + case 17: + debug_color_out(BRIGHT,RED,BLACK,"Error : NoWritable\r\n"); + break; + case 18: + debug_color_out(BRIGHT,RED,BLACK,"Error : inconsistentName\r\n"); + break; + default: + break; + } + ip_index++; + debug_cfg_end = 0; + set_state = 1; + } + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=9; + mib_curr_node=agent_tmp_node; + snmp_agent_flag=0; + } + break; + } + else if((recv_msgbuf.var[0].vartype == 2) || (recv_msgbuf.var[0].vartype == 4)) //int or string + { + char out_text[128]; + int index2, index3, index4; + DWORD sum; + int sub_sum; + //int child_index; + strcpy(out_text, ""); + if(debug_snmp_agent_buf[debug_agent_index].cmm_state==3 && snmp_agent_flag==2) + { + index2=mib_curr_node->data_length*2; + for(i=0;ienable_field_id!=0xFF) + { + param_node = (mib_node_param *)mib_curr_node->child_nodes[mib_curr_node->enable_field_id]->child_ptr; + + if(param_node->byte_begin==param_node->byte_end && param_node->bit_begin ==param_node->bit_end) + { + ins_byte=param_node->byte_begin; + ins_bit=param_node->bit_begin ; + if(del_flag==0) + { + recv_msgbuf.var[0].msg[ins_byte] =recv_msgbuf.var[0].msg[ins_byte] | (BYTE)my_pow(2,ins_bit); + } + else + { + recv_msgbuf.var[0].msg[ins_byte] =recv_msgbuf.var[0].msg[ins_byte] & (~(BYTE)my_pow(2,ins_bit)); + } + } + } + set_all=0; + } + else + { + temp_param=param_node; + + if(mib_curr_node->enable_field_id!=0xFF) + { + param_node = (mib_node_param *)mib_curr_node->child_nodes[mib_curr_node->enable_field_id]->child_ptr; + + if(param_node->byte_begin==param_node->byte_end && param_node->bit_begin ==param_node->bit_end) + { + ins_byte=param_node->byte_begin; + ins_bit=param_node->bit_begin ; + if(del_flag==0) + recv_msgbuf.var[0].msg[ins_byte] =recv_msgbuf.var[0].msg[ins_byte] | (BYTE)my_pow(2,ins_bit); + else + recv_msgbuf.var[0].msg[ins_byte] =recv_msgbuf.var[0].msg[ins_byte] & (~(BYTE)my_pow(2,ins_bit)); + } + } + param_node=temp_param; + if(param_node->select_total != 0) + { + index3 = sum = 0; + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + index3++; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + } + } + else if(param_node->input_ptr != NULL) + { + switch(param_node->input_ptr->input_param_type) + { + case 0: //toDec_high_0 + strcpy(out_text, ""); + index3 = sum = 0; + for(index=param_node->byte_end; index >=param_node->byte_begin; index--) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + index3++; + if( (index == param_node->byte_begin) && (((param_node->byte_begin==param_node->byte_end)&& index2 == param_node->bit_end) || ((param_node->byte_begin!=param_node->byte_end)&& index2==7))) + break; + + } + if( (index == param_node->byte_begin) && (((param_node->byte_begin==param_node->byte_end)&& index2 == param_node->bit_end) || ((param_node->byte_begin!=param_node->byte_end)&& index2==7))) + break; + } + break; + case 1: //keepHex_high_0 + case 2: //keepHex_low_0 + case 3: //keepHex_low_E + case 4: //keepHex_low_F + strcpy(out_text, ""); + index3 = index4 = sum = sub_sum = 0; + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + if((index3 == 0) && ( (index4+1) <= strlen(set_val_str) )) //\u53D6\u4E24\u4F4D\u5B57\u7B26 + { + set_val = 0; + if( isdigit(set_val_str[index4]) ) //\u6570\u5B57\u5B57\u7B26 + set_val += (set_val_str[index4++] - '0') * 16; + else // A \u81F3 E \u4E4B\u95F4 + set_val += (set_val_str[index4++] - 'A' + 10) * 16; + + if( isdigit(set_val_str[index4]) ) + set_val += set_val_str[index4++] - '0'; + else + set_val += set_val_str[index4++] - 'A' + 10; + } + + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + index3++; + if(index3 == 8) + index3 = 0; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + } + break; + case 5: //toAscii_low_0 + case 6: //keepAscii_low_F + strcpy(out_text, ""); + index3 = index4 = sum = sub_sum = 0; + for(index=param_node->byte_begin; index <= param_node->byte_end; index++) + { + if(index == param_node->byte_begin) + index2 = param_node->bit_begin; + else + index2 = 0; + if(index3 == 0) //\u53D6\u4E00\u4F4D\u5B57\u7B26 + set_val = set_val_str[index4++]; + + for(; index2<8; index2++) + { + if((set_val & (BYTE)my_pow(2, index3)) == 0) + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] & (255 - my_pow(2, index2)); + else + recv_msgbuf.var[0].msg[index] = recv_msgbuf.var[0].msg[index] | my_pow(2, index2); + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + index3++; + if(index3 == 8) + index3 = 0; + } + if( (index == param_node->byte_end) && (index2 == param_node->bit_end)) + break; + } + break; + default: + if(snmp_agent_flag==0) + { + sprintf(out_text, "Get value (%s)\r\n", recv_msgbuf.var[0].msg); + debug_ascii_out_proc(out_text); + sprintf(out_text,"from the host: %s %s.\r\nBut can not parse the value type (%d).\r\n", Remote_Host_Name[ip_index], Remote_Host_IP[ip_index], recv_msgbuf.var[0].vartype); + debug_ascii_out_proc(out_text); + } + ip_index++; + debug_cfg_end = 0; + set_state = 1; + return; + } + } + } + } + // send set request + t5s_flag=0; + recv_msgbuf.pdu_type = 3; + recv_msgbuf.request_id = 0; + recv_addr.remote_ip = Peer_IP[ip_index]; + request_id = snmp_send(&recv_msgbuf, &recv_addr); + if(request_id == 0) + { + if(snmp_agent_flag==0) + { + sprintf(out_text, "Error : Fail to send snmp set request to the host: %s %s\r\n",Remote_Host_Name[ip_index],Remote_Host_IP[ip_index]); + debug_color_out(BRIGHT,RED,BLACK,out_text); + } + ip_index++; + debug_cfg_end = 0; + set_state =1; + } + else + { + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = request_id; + recv_addr.remote_ip = Peer_IP[ip_index]; + set_state = 3; + } + break; + } + else + { + if(snmp_agent_flag==0) + { + if(recv_msgbuf.var[0].vartype == 5) //NULL + { + debug_color_out(BRIGHT,RED,BLACK,"Error : NULL\r\n"); + } + else if(recv_msgbuf.var[0].vartype == 6) //Object identifier + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Object identifier wrong\r\n"); + } + else if(recv_msgbuf.var[0].vartype == 0x80) //noSuchObject + { + debug_color_out(BRIGHT,RED,BLACK,"Error : noSuchObject\r\n"); + } + else if(recv_msgbuf.var[0].vartype == 0x81) //NoSuchInstance + { + debug_color_out(BRIGHT,RED,BLACK,"Error : NoSuchInstance\r\n"); + } + else if(recv_msgbuf.var[0].vartype == 0x82) //endOfMibView + { + debug_color_out(BRIGHT,RED,BLACK,"Error : endOfMibView\r\n"); + } + if(save_flag>3) + { + if(debug_cfg==1) + mib_curr_node=temp_mib_node; + else if(debug_cfg==2) + { + menu_curr_node=tmp_menu_node; + mib_curr_node=temp_mib_node; + } + save_flag=0; + } + } + } + + } + debug_cfg_end = 0; + ip_index++; + set_state = 1; + break; + case 3: //receive set response + request_id = snmp_receive(&recv_msgbuf, &recv_addr); + + if(request_id == 0) // not received + { + if(t5s_flag > 250) + { + if(snmp_agent_flag==0) + { + sprintf(out_text, "Error : Time out to set value to the host: %s %s\r\n",Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + debug_color_out(BRIGHT,RED,BLACK,out_text); + } + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=1; + mib_curr_node=agent_tmp_node; + snmp_agent_flag=0; + } + ip_index++; + set_ok_once=0; + debug_cfg_end = 0; + set_state = 1; + break; + } + else + break; + } + else //received + { + if(snmp_agent_flag==0) + { + char out_text1[256], byte_val1[16]; + //debug_ascii_out_proc("\rStatus : "); + //debug_color_out(BRIGHT,CYAN,BLACK,"Successful! \r\n"); + //debug_ascii_out_proc("SNMP MSG: "); + //sprintf(out_text1, "receive snmp response: error_status: %d, vartype: %d, msg_len: %d\r\n",recv_msgbuf.error_status, recv_msgbuf.var[0].vartype, recv_msgbuf.var[0].msglen); + //debug_color_out(BRIGHT,CYAN,BLACK,out_text1); + strcpy(out_text1,""); + for(index=0; indexbyte_begin, param_node->bit_begin, param_node->byte_end, param_node->bit_end); + //debug_color_out(BRIGHT,YELLOW,BLACK,out_text1);//for look + //debug_ascii_out_proc("\r\n"); + //} + //*/ + } + if(recv_msgbuf.error_status != 0) + { + if(snmp_agent_flag==0) + { + //sprintf(out_text, "Error : set value to the host: %s %s\r\n",Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + //debug_color_out(BRIGHT,RED,BLACK,out_text); + switch(recv_msgbuf.error_status) + { + case 1: + debug_color_out(BRIGHT,RED,BLACK,"Error : TooBig\r\n"); + break; + case 5: + debug_color_out(BRIGHT,RED,BLACK,"Error : GenErr\r\n"); + break; + case 6: + debug_color_out(BRIGHT,RED,BLACK,"Error : NoAccess\r\n"); + break; + case 7: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongType\r\n"); + break; + case 8: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongLength\r\n"); + break; + case 9: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongEncoding\r\n"); + break; + case 10: + debug_color_out(BRIGHT,RED,BLACK,"Error : WrongValue\r\n"); + break; + case 11: + debug_color_out(BRIGHT,RED,BLACK,"Error : NoCreation\r\n"); + break; + case 12: + debug_color_out(BRIGHT,RED,BLACK,"Error : inconsistentValue\r\n"); + break; + case 13: + debug_color_out(BRIGHT,RED,BLACK,"Error : resourceUnavailable\r\n"); + break; + case 14: + debug_color_out(BRIGHT,RED,BLACK,"Error : commitFailed\r\n"); + break; + case 15: + debug_color_out(BRIGHT,RED,BLACK,"Error : UndoFailed\r\n"); + break; + case 16: + debug_color_out(BRIGHT,RED,BLACK,"Error : AuthorizationError\r\n"); + break; + case 17: + debug_color_out(BRIGHT,RED,BLACK,"Error : NoWritable\r\n"); + break; + case 18: + debug_color_out(BRIGHT,RED,BLACK,"Error : inconsistentName\r\n"); + break; + default: + break; + } + } + else + { + debug_snmp_agent_buf[debug_agent_index].cmm_state=4; + debug_snmp_agent_buf[debug_agent_index].result_state=9; + mib_curr_node=agent_tmp_node; + snmp_agent_flag=0; + } + } + else + { + if( save_flag==4) + { + debug_ascii_out_proc("Host : "); + sprintf(out_text, "%s %s (State: Successful!)\r\n",Remote_Host_Name[ip_index], Remote_Host_IP[ip_index]); + debug_color_out(BRIGHT,YELLOW,BLACK,out_text); + if(debug_cfg==1) + mib_curr_node=temp_mib_node; + else if(debug_cfg==2) + { + menu_curr_node=tmp_menu_node; + mib_curr_node=temp_mib_node; + } + + } + + } + } + debug_cfg_end = 0; + set_state = 1; + if(snmp_agent_flag==0) + { + if(save_flag>=3) + { + if(debug_cfg==1) + mib_curr_node=temp_mib_node; + else if(debug_cfg==2) + { + menu_curr_node=tmp_menu_node; + mib_curr_node=temp_mib_node; + } + if(save_flag==3 && ip_index==0) + debug_mmi_contents(""); + save_flag=5; + ip_index++; + break; + } + } + if(recv_msgbuf.error_status == 0) + { + if(snmp_agent_flag==2) + { + set_after_get=1; + debug_snmp_agent_buf[debug_agent_index].cmm_state=1; + debug_snmp_agent_buf[debug_agent_index].result_state=0; + snmp_agent_flag=1; + } + else + { + if(save_flag<3 && !set_ok_once) + { + get_state=3; + set_ok_once=1; + } + } + bind_num=1; + set_state=0; + debug_get_all_value = mib_curr_node->total_child_nodes; + } + if(del_flag==1) + debug_mmi_contents("*"); + del_flag=0; + ip_index++; + if(snmp_agent_flag==0) + set_state=1; + break; + + default: + ip_index=0; + debug_cfg_end = 1; + set_state = 0; + break; + } +}//end of debug_snmp_set_rt + +int debug_snmp_get(BYTE oidlen,DWORD *oid,BYTE *data_ptr,BYTE *vartype) +{//?? + DWORD ii; + BYTE temp_id; + struct debug_module_struct *module_ptr; + + switch(oid[12]) + { + case 0: + break; + case 1: + break; + case 2: // configure + if (oid[13] > MODULE_COUNT+1 || oid[13] < 2) + return -1; + temp_id = oid[13] - 2; + module_ptr = (struct debug_module_struct *) &debug_shm_ptr->module_d[temp_id]; + switch(oid[14]) + { + case 0: + break; + case 1: + data_ptr[0] = module_ptr->status[0]; + *vartype = 4; + return 1; + break; + case 2: + strcpy((char *)data_ptr,module_ptr->version); + return strlen(module_ptr->version); + break; + case 3: // ascii in buffer + break; + case 4: // ascii out buffer + switch (oid[15]) + { + case 1: // get tail seq id + ii = u32tobcd(data_ptr,module_ptr->seqid_t); + *vartype = 4; + return ii; + break; + case 2: // get head seq id + ii = u32tobcd(data_ptr,module_ptr->seqid_h); + *vartype = 4; + return ii; + break; + case 3: // get out buffer + if (module_ptr->seqid_h < module_ptr->seqid_t) + { + ii = module_ptr->seqid_h + DEBUG_MAX_SEQID; + if (oid[16] >= ii || oid[16] < module_ptr->seqid_t) + return -1; + } + else + { + if (oid[16] >= module_ptr->seqid_h || oid[16] < module_ptr->seqid_t) + return -1; + } + ii = oid[16] % DEBUG_SEQID_LEN; + strcpy((char *)data_ptr, (char *)module_ptr->omc_outbuf[ii]); + *vartype = 4; + return strlen((char *)module_ptr->omc_outbuf[ii]); + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + return -1; +} + +int debug_snmp_set(BYTE oidlen,DWORD *oid,BYTE *data_ptr,WORD data_len) +{ + BYTE temp_id; + + switch(oid[12]) + { + case 0: + break; + case 1: + break; + case 2: // configure + if (oid[13] > MODULE_COUNT+1 || oid[13] < 2) + return -1; + temp_id = oid[13] - 2; + if (oid[14] != 3) // not ascii in buffer + return -1; + if (data_len < 80) + { + if (debug_shm_ptr->module_d[temp_id].ascii_in_set_flag == 1) + { + debug_shm_ptr->module_d[temp_id].ascii_in[0] = disp_page_flag + 1; + memcpy(debug_shm_ptr->module_d[temp_id].ascii_in+1,data_ptr,data_len); + debug_shm_ptr->module_d[temp_id].ascii_in[data_len+1] = '\0'; + } + return data_len; + } + break; + default: + break; + } + return -1; +} + +void debug_mmi_list() +{ + int cur_b,cur_end,list_give_num; + char cur_c[64],temp[2],*p,arr[256],temp_str[256*5],*temp_ch; + char ins_str[16]; + int i,j; + DWORD k; + BYTE index; + mib_child_node *child_node_ptr; + if(strlen((char *)list_msg)>96) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : No need so long string!\r\n"); + list_flag=0; + debug_cfg_end=1; + return; + } + switch(list_flag) + { + case 0: //idel + return; + case 1: + strcpy(arr, (char *)list_msg); + for(i=0;i!=strlen(arr);i++) + { + if(*(arr+i)!=' ') + break; + } + p=arr+i; + strcpy(arr,p); + list_give_num=0; + if(mib_curr_node->total_instance==0) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : This is not leaf node,so can't list the para and value.\r\n"); + list_flag=0; + debug_cfg_end=1; + return; + } + strcpy(temp,""); + p=temp; + if(strlen(arr)==0) + { + list_give_num=0; + } + while(strlen(arr)!=0) + { + for(i=0;i!=strlen(arr);i++) + { + if(*(arr+i)!=' ') + break; + } + p=arr+i; + strcpy(temp_str,""); + strcpy(temp_str,p); + strcpy(arr,temp_str); + i=0; + if(arr[0]!='-' && !isdigit(arr[0])) + { + debug_color_out(BRIGHT,RED,BLACK,"Fail : Format is not right!list [-a] [-e] [xxx-xxx].\r\n"); + list_flag=0; + debug_cfg_end=1; + return; + } + + else if(strncmp(arr,"-s",2)==0) //show get state,default hide + { + show_snmp_state=1; + p=arr+2; + strcpy(arr,p); + } + else if(strncmp(arr,"-a",2)==0) //show all include NULL,default hide + { + show_all_value=1; + p=arr+2; + strcpy(arr,p); + } + else if(strncmp(arr,"-f",2)==0) //show the special field + { + for(i=2;i=3) + { + sprintf(cur_c,"Error : Please input number between 1-%d!\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,RED,BLACK,cur_c); + list_flag=0; + debug_cfg_end=1; + return; + } + } + if(i!=0) + { + strncpy(cur_c,temp_ch,i); + list_field_arr[index]=atoi(cur_c); + if(list_field_arr[index]<1 || list_field_arr[index]>(mib_curr_node->total_child_nodes)) + { + sprintf(cur_c,"Error : Please input number between 1-%d!\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,RED,BLACK,cur_c); + list_flag=0; + debug_cfg_end=1; + return; + } + else + index++; + } + if(*(temp_ch+i)!='\0') + k+=i+1; + else + k+=i; + j=0; + } + } + + else if(strncmp(arr,"-r",2)==0) //show para arrange,default hide + { + show_range=1; + p=arr+2; + strcpy(arr,p); + } + + + else if(strncmp(arr,"-t",2)==0) //show para type,defualt hide + { + show_type=1; + p=arr+2; + strcpy(arr,p); + } + + else if(strncmp(arr,"-e",2)==0) //show without expand ,defualt expand + { + show_expend=0; + p=arr+2; + strcpy(arr,p); + } + else if(isdigit(arr[0]) || (arr[0]=='-' && isdigit(arr[1]))) + { + p=temp; + for(i=0;i<=strlen(arr);i++) + { + *p=arr[i]; + if(!isdigit(*p) && *p!='-') + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Please input number!format list:2-10\r\n"); + list_flag=0; + debug_cfg_end=1; + return; + } + if(*p=='-') + { + if(i>=1) + { + strncpy(cur_c,arr,i); + cur_b=strtoul(cur_c,NULL,10); + break; + } + else + { + cur_b=0; + break; + } + } + } + i++; + if(i==(strlen(arr)+2)) + cur_end=mib_curr_node->total_instance-1; + else + { + strcpy(cur_c,""); + for(;itotal_instance-1; + } + list_start=cur_b; + list_end=cur_end; + if(list_start>list_end) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Input error!Example:list -a -e 2-10!\r\n"); + list_flag=0; + debug_cfg_end=1; + return; + } + if(list_end>mib_curr_node->total_instance-1) + { + sprintf(cur_c,"Error : The max instance num is %d!\r\n",mib_curr_node->total_instance-1); + debug_color_out(BRIGHT,RED,BLACK,cur_c); + list_flag=0; + debug_cfg_end=1; + return; + } + list_flag=2; + debug_cfg_end=0; + break; + case 2: + //temp_instance=mib_curr_node->curr_instance; + if(list_start<=list_end) + { + mib_curr_node->curr_instance=(DWORD)list_start; + if(list_start+15<=list_end) + bind_num=16; + else + bind_num=list_end-list_start+1; + send_msgbuf.pdu_type = 0; + send_msgbuf.request_id = 0; + send_msgbuf.var_num =bind_num; + for(j=0;joid[i]; + send_msgbuf.var[j].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance+j; + send_msgbuf.var[j].oidlen = mib_curr_node->oid_len + 1; + } + for(ip_index=0;ip_index<16;ip_index++) + { + if(IP_Selected[ip_index] != 1) + continue; + send_addr.remote_ip = Peer_IP[ip_index]; + break; + } + if(ip_index>=16) + { + debug_ascii_out_proc("Fail : There is not host ip available.\r\n"); + return ; + } + send_addr.local_ip = Local_IP; + send_addr.remote_port = SNMP_PORT; + send_addr.local_port = DEBUG_SNMP_PORT; + send_addr.broadcast = 0; + recv_msgbuf.pdu_type = 2; + recv_msgbuf.request_id = 0; + recv_msgbuf.var_num = bind_num; + for(j=0;joid[i]; + recv_msgbuf.var[j].oid[mib_curr_node->oid_len] = (DWORD)mib_curr_node->curr_instance+j; + recv_msgbuf.var[j].oidlen = mib_curr_node->oid_len + 1; + for(i=0; i<256; i++) + recv_msgbuf.var[j].msg[i] = 0; + } + recv_addr.remote_ip = send_addr.remote_ip; + recv_addr.local_ip = Local_IP; + recv_addr.remote_port = SNMP_PORT; + recv_addr.local_port = DEBUG_SNMP_PORT; + recv_addr.broadcast = 0; + bind_index=0; + get_state=1; + debug_cfg_end = 0; + list_field=mib_curr_node->total_child_nodes; + list_start+=bind_num; + } + list_flag=3; + break; + case 3: + if(get_state==3 && bind_index=bind_num && bind_num!=0 && list_start=list_end+1) + { + + show_all_value=0; + show_type=0; + show_range=0; + show_field=0; + bind_num=1; + bind_index=0; + show_snmp_state=0; + show_expend=1; + debug_cfg_end=0; + /* + if(read_syntax_nor_list==0 && list_once==1) + { + list_start=0; + list_end=0; + list_flag=0; + compute_field_list_index++; + if(compute_field_list_index == compute_list_num && compute_field_list_index>0) + { + read_syntax_nor_list = 1; + field_compute_state=5; + mib_curr_node=temp_compute_node; + list_field=mib_curr_node->total_child_nodes; + debug_mmi_get_all(); + debug_cfg_end=0; + } + return; + } + */ + + + list_flag=4; + break; + } + if(t5s_flag> 250 && list_once==0) + { + list_flag=0; + list_start=0; + list_end=0; + debug_ascii_out_proc("Instance: "); + debug_color_out(BRIGHT,RED,BLACK,"Unknow Because can not get it value in time\r\n"); + strcpy(temp_str,""); + debug_ascii_out_proc("Child : "); + sprintf(temp_str, "[%d]\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + + for (i = 0; i < mib_curr_node->total_child_nodes; i++) + { + child_node_ptr = mib_curr_node->child_nodes[i]; + if(child_node_ptr) + sprintf(temp_str, " |---(%u) %s\r\n",child_node_ptr->oid+1,child_node_ptr->name); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + } + debug_cfg_end=1; + } + break; + case 4: + if(list_once==0) + { + if(list_start>=list_end+1) + { + for(i=0;i<256;i++) + { + if(curr_instance_arr[i].eable==1) + break; + } + if(i==256) + { + //debug_color_out(BRIGHT,RED,BLACK,"Error : no instance was used!\r\n"); + none_instance=1; + } + else + none_instance=0; + mib_curr_node->curr_instance=i; + temp_instance=mib_curr_node->curr_instance; + } + } + else + mib_curr_node->curr_instance=temp_instance; + + if (mib_curr_node->total_instance) + { + strcpy(temp_str,""); + strcpy(ins_str,""); + k=0; + for(i=0;i<=255;i++) + { + if(curr_instance_arr[i].eable==1) + { + sprintf(ins_str,"#%-3d ",i); + strpcat(temp_str,&k,ins_str); + } + } + debug_ascii_out_proc("Instance: "); + strcpy(ins_str,""); + if(k) + sprintf(ins_str, "#%-3d(%-3d): ", mib_curr_node->curr_instance,mib_curr_node->total_instance); + else + sprintf(ins_str, "None(%-3d): ", mib_curr_node->total_instance); + debug_color_out(BRIGHT,YELLOW,BLACK,ins_str); + debug_color_out(BRIGHT,BLUE,BLACK,temp_str); + debug_ascii_out_proc("\r\n"); + if(k) + none_instance=0; + else + none_instance=1; + } + list_flag=0; + get_state=0; + debug_cfg_end=1; + + IP_Selected[0]=1; + for(i=1;i<16;i++) + IP_Selected[i]=0; + if(list_once==0) + { + if(none_instance==0) + { + if(mib_curr_node->max_access>=2 && mib_curr_node->max_access<=5) + { + + debug_mmi_get_all(); + debug_cfg_end=0; + } + } + else + { + + strcpy(temp_str,""); + debug_ascii_out_proc("Child : "); + sprintf(temp_str, "[%d]\r\n",mib_curr_node->total_child_nodes); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + + for (i = 0; i < mib_curr_node->total_child_nodes; i++) + { + child_node_ptr = mib_curr_node->child_nodes[i]; + sprintf(temp_str, " |---(%u) %s\r\n",child_node_ptr->oid+1, child_node_ptr->name); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str); + } + debug_cfg_end=1; + + } + } + list_once=1; + list_start=0; + list_end=0; + list_flag=0; + break; + + } + return ; +} + + + +void register_instance() +{ + char ascii_text[32],byte_val1[8]; + int i,index; + if(mib_curr_node->total_instance) + { + memset(curr_instance_value,0,sizeof(char)); + //strncpy(curr_instance_value,mib_curr_node->init_value,mib_curr_node->data_length); + *curr_instance_value='\0'; + for(index=0; indexdata_length; index++) + { + if((mib_curr_node->init_value[index] & 0xF0)==0) + { + strcat(curr_instance_value,"0"); + sprintf(byte_val1,"%X",mib_curr_node->init_value[index]); + strcat(curr_instance_value,byte_val1); + } + else + { + sprintf(byte_val1, "%X", mib_curr_node->init_value[index]); + strcat(curr_instance_value,byte_val1); + } + } + gcvt((double)(mib_curr_node->total_instance-1),3,ascii_text); + strcpy((char *)list_msg,""); + strcat((char *)list_msg," -e "); + strcat((char *)list_msg,"0"); + strcat((char *)list_msg,"-"); + strcat((char *)list_msg,ascii_text); + + + //default_value(mib_curr_node->oid,mib_curr_node->oid_len,curr_instance_value); + show_list=0; + for(i=0;i<=255;i++) + { + curr_instance_arr[i].eable=0; + } + debug_mmi_list(); + } +} + + + +//////////////////////////////End of Operation get-set/////////// + + + + +//////////////////////////////Data Send and recieve////////////// + +void debug_send_serial() +{ + //int n; + int i; + message_list iptr_msg; + + for (i = 0;i < MAX_SEND_CHAR_NUM ;i ++) + { + if (sendserbuf_t != sendserbuf_h) + { + //n = write(com_port,&sendser_buf[sendserbuf_t],1); + // if (n > -1) + // { + debug_shm_ptr->TelnetSendData.telsend_data[debug_shm_ptr->TelnetSendData.telsend_datah] = sendser_buf[sendserbuf_t]; + sendserbuf_t = (sendserbuf_t + 1) % SERIAL_BUF_LEN; + debug_shm_ptr->TelnetSendData.telsend_datah = (debug_shm_ptr->TelnetSendData.telsend_datah+1)%TELNET_SEND_BUF_LEN; + if (debug_shm_ptr->TelnetSendData.telsend_datah > 256) + // if (debug_shm_ptr->TelnetSendData.telsend_datah == 0) + SendTelnetFlag = 1; + // } + } + } + if (SendTelnetFlag == 1) + { + if (debug_shm_ptr->TelnetSendData.telsend_datah > 0) + { + iptr_msg.msgSrcPort = DEBUG_PORT; + iptr_msg.msgLength = debug_shm_ptr->TelnetSendData.telsend_datah; + memcpy(iptr_msg.msgContent,debug_shm_ptr->TelnetSendData.telsend_data,debug_shm_ptr->TelnetSendData.telsend_datah); + iptrPutMessage(iptr_msg); + memset(debug_shm_ptr->TelnetSendData.telsend_data,0,sizeof(BYTE)*TELNET_SEND_BUF_LEN); + debug_shm_ptr->TelnetSendData.telsend_datah = 0; + } + SendTelnetFlag = 0; + } +} + +int debug_send_char(BYTE ch) +{ + sendser_buf[sendserbuf_h] = ch; + sendserbuf_h = (sendserbuf_h + 1) % SERIAL_BUF_LEN; + return 1; +} + + +int debug_send_string(const char *str_send) +{ + int len,i; + i=0; + len=strlen(str_send); + if(sendserbuf_h+len>SERIAL_BUF_LEN && (sendserbuf_h+len)% SERIAL_BUF_LEN='a' && recser_buf[recserbuf_h]<='a'+MODULE_COUNT) + // send_char_flag=0; + recserbuf_h = (recserbuf_h + 1) % SERIAL_BUF_LEN; + } + } +} + +int debug_read_char() +{ + char sig; + + if (recserbuf_t == recserbuf_h) + return 0; + if (recserbuf_t != recserbuf_h) + { + sig = recser_buf[recserbuf_t]; + recserbuf_t = (recserbuf_t + 1) % SERIAL_BUF_LEN; + } + return sig; +} + + +void debug_recv_cmd() +{ + int i; + char pp; + int temp_page; + char pr_buf[30];//--lw + pp = debug_read_char(); + switch(pp) + { + case 0: + return; + case 113://"Q" + case 81: //'q' //--lw + { + first_page = 1; + disp_main_flag = 0; + if(debug_cfg) + debug_mmi_save(); + Init_Page=0; + mib_curr_node=mib_root_node; + menu_curr_node=menu_root_node; + debug_cfg=0; + debug_cfg_end=0; + debug_ascii_out_ph=debug_ascii_out_pt=0; + ascii_out_pt=ascii_out_ph=0; + /* + if(debug_cfg>0) + { + debug_send_char('C'); + debug_send_char('M'); + debug_send_char('M'); + debug_cfg=0; + } + */ + break; + } + } + switch (disp_main_flag) + { + case 0: // enter in menu page + if (isupper(pp)) // transfer the upper to lower + pp = tolower(pp); + if (pp == 'x') + { + m_state = 0; + disp_main_flag = 0; + } + //else if ((pp >= 'a') && (pp < 'a'+MODULE_COUNT)) + else if ((pp >= 'a') && ((pp <= 'a'+15 ) || (pp >= 17 + 'a' && pp <= 22 + 'a') || pp == 'y' || pp == 'z' ) ) //!=x !=q + { + disp_main_flag = 1; + debug_module_num= pp - 'a'; + disp_sub_module_flag = pp - 'a'; + if( disp_sub_module_flag >= PAGE_MODULE_COUNT ) + disp_sub_module_flag -= 2; + else if( disp_sub_module_flag > 16 && disp_sub_module_flag < 23 ) + disp_sub_module_flag--; + debug_module_num += disp_main_page_num*PAGE_MODULE_COUNT; + disp_sub_module_flag += disp_main_page_num*PAGE_MODULE_COUNT; + m_state_sub_module = 0; + disp_page_flag = 0; + command_flag = 0; + // title_top_pt = 0; + ascii_out_ph = ascii_out_pt = 0; + // strcpy(ascii_out_array,""); + // show the help info when enter in a new module + if(debug_shm_ptr != NULL) + if (debug_shm_ptr->module_d[disp_sub_module_flag].ascii_in_set_flag == 1) + { + debug_shm_ptr->module_d[disp_sub_module_flag].ascii_in[0] = disp_page_flag + 1; + strcpy((char *)debug_shm_ptr->module_d[disp_sub_module_flag].ascii_in+1,"help"); + } + memset(current_timer,0,sizeof(current_timer)); + } + else if ((pp >= '1') && (pp <= '9')) + { + disp_main_page_num = pp - '1'; + if(disp_main_page_num >= DEBUG_MAX_PAGE) + disp_main_page_num = 0; + m_state = 0; + disp_main_flag = 0; + } + break; + case 1: // enter in module page + if (command_flag == 0) + { + if (isupper(pp)) // transfer the upper to lower + pp = tolower(pp); + if (pp == 'x') + { + disp_main_flag = 0; + m_state = 0; + disp_page_flag = 0; + } + else if ((pp >= '0') && (pp <= '9')) + { + temp_page = pp - '0'; + if ( (debug_shm_ptr->module_d[disp_sub_module_flag].page_d[temp_page].pointer_set_flag == 0) && (temp_page != 0)) + return; // invalid page + disp_page_flag = pp - '0'; + m_state_sub_module = 0; + // title_top_pt = 0; + } + else if ((pp >= 'a') && (pp <= 'f')) + { + temp_page = pp - 'a' + 0x0a; + if (debug_shm_ptr->module_d[disp_sub_module_flag].page_d[temp_page].pointer_set_flag == 0) + return; // invalid page + disp_page_flag = pp - 'a' + 0xa; + m_state_sub_module = 0; + // title_top_pt = 0; + } + else if (pp == 27) // ESC + { + //debug_clear_serial(); + if (disp_page_flag != 0) // not page 0 + { + for (i = 0;i < strlen(prompt_line25);i ++) + debug_send_char(prompt_line25[i]); + } + else + { + //debug_send_char(0xa);//--lw + //debug_send_char(0xd);//--lw + if(disp_sub_module_flag == ('n'-'a')) + { + if(debug_cfg == 0) //cmm status + { + if(debug_module_num == ('n'-'a')) + { + sprintf(pr_buf,"CMM>"); + Init_Page=2; + TxtColor(BRIGHT,WHITE,BLACK,pr_buf); + for(i=0;i<30;i++) + if(pr_buf[i]!='\0') + debug_send_char(pr_buf[i]); + else + break; + m_state_sub_module = 2; + } + else + { + sprintf(pr_buf,"%s>",debug_shm_ptr->module_d[debug_module_num].name); + TxtColor(BRIGHT,WHITE,BLACK,pr_buf); + for (i = 0;i < strlen(pr_buf);i ++) + debug_send_char(pr_buf[i]); + } + } + else if(debug_cfg ==1) //cfg status + { + sprintf(pr_buf,"CFG>"); + TxtColor(BRIGHT,WHITE,BLACK,pr_buf); + debug_send_string(pr_buf); + } + else if(debug_cfg==2) + { + sprintf(pr_buf,"MENU>"); + TxtColor(BRIGHT,WHITE,BLACK,pr_buf); + debug_send_string(pr_buf); + } + } + else + { + debug_send_string(debug_shm_ptr->module_d[disp_sub_module_flag].name); + debug_send_char('>'); + } + + } + ascii_in_array[0] = disp_page_flag + 1; + ascii_in_pt = 1; + command_flag = 1; + SendTelnetFlag = 1; + } + } + else // in command mode + { + switch (pp) + { + case 27: // ESC + //debug_send_char(0xa); + //debug_send_char(0xd); + command_flag = 0; + ascii_in_array[0] = disp_page_flag + 1; + ascii_in_pt = 1; + break; + case 8: // backspace + if (ascii_in_pt > 1) + ascii_in_pt -= 1; + debug_send_char(pp); + SendTelnetFlag = 1; + break; + case 10: // line feed + if (ascii_in_pt == 1) // empty + return; + break; + case 13: // return + if (ascii_in_pt == 1) // empty + return; + //debug_send_char(pp); + SendTelnetFlag = 1; + //if (disp_page_flag == 0) // display page 0 + // debug_send_char(10); // send line feed + ascii_in_array[ascii_in_pt] = '\0'; + if (debug_shm_ptr->module_d[disp_sub_module_flag].ascii_in_set_flag == 1) + strncpy((char *)debug_shm_ptr->module_d[disp_sub_module_flag].ascii_in, (char *)ascii_in_array,80); + command_flag = 0; + ascii_in_pt = 0; + ascii_in_array[0] = '\0'; + break; + default: + ascii_in_array[ascii_in_pt++] = pp; + //debug_send_char(pp); + SendTelnetFlag = 1; + break; + } + } + break; + default: + disp_main_flag = 0; + break; + } +} + + + + +//////////////////////////////end of Data Send and recieve////////////// + +/////////////////////////////compute field//////////////////////////// + +/* +* +* [I]TG to Prefix +* { +* [v]OID="3.2.2.1.3" +* [l]OID.#.1 //for while +* [p]TG=(OID.*.1) //print +* } +* +* +* [I]Prefix to TG +* { +* [v]OID1="3.2.2.1.3" +* [v]OID2="3.2.2.1.4" +* [l]OID1.#.1 +* [l]OID2.#.1 +* [c](OID1.#.1)==(*) [p]prefix (#)=(OID2.#.1) //if +* } + */ +BYTE create_compute_field(FILE * fp, mib_node * node_ptr, BYTE field_id,char *name) +{ + char data_arr[256]; + + + compute_field_arr[compute_field_num].field_id = field_id; + strcpy(compute_field_arr[compute_field_num].name,name); + while(!feof(fp)) + { + mib_line_count++; + if(read_line(fp, data_arr) == 0) + continue; + del_space(data_arr, 2); + switch (data_arr[0]) + { + case '{': //"{" + break; + case '[': + if(data_arr[1] == 'c' || data_arr[1] == 'v' || data_arr[1] == 'p' || data_arr[1] == 'l') + { + if(strlen(data_arr) < 64) + strcpy(compute_field_arr[compute_field_num].syntax_str[compute_field_arr[compute_field_num].syntax_count], data_arr); + else + { + printf("[Debug] Error : Do not support so much line script for compute node.line:%d", mib_line_count); + return 0; + } + if(compute_field_arr[compute_field_num].syntax_count < 10) + compute_field_arr[compute_field_num].syntax_count++; + else + { + printf("[Debug] Error : Do not support so much line script for compute node.line:%d", mib_line_count); + return 0; + } + } + break; + case '}': + if(compute_field_num<16) + compute_field_num++; + else + return 0; + + return 1; + default: + printf("[Debug] Error : The mib compute field is not right.line:%d", mib_line_count); + return 0; + } + } + return 1; +} + +void translate_compute_field() +{ + char *p, *temp_ch, temp_str[32],temp_str1[64], line[64]; + DWORD oid[32]; + char cmp_value[2][32]; + char temp_value[32]; + BYTE i,j, value_index,read_next_line=1,index; + WORD curr_instance_index; + mib_node *find_list_node; + + if(field_compute_state == 1) + { + memset(OID_val, 0, 5 * 16 * sizeof(DWORD)); + memset(OID_name_str, 0, 5 * 32 * sizeof(char)); + line_index = 0; + OID_index=0; + compute_field_list_index=0; + compute_list_num=0; + compute_state = 0; + } + + if(read_syntax_nor_list>0) + { + while(line_index < compute_curr_unit.syntax_count && strlen(compute_curr_unit.syntax_str[line_index]) != 0) + { + if(!print_line_index) + field_compute_state=2; + else + field_compute_state=6; + if(read_syntax_nor_list == 0) + { + field_compute_state=3; + print_line_index=line_index; + return ; + } + if(read_next_line==1 && line_index 5) + { + printf("[Debug] Error: The max define oid number is 5.\r\n"); + return ; + } + temp_ch += 3; + p = strtok(temp_ch, "="); //variable name + strcpy(OID_name_str[OID_index], p); + p=strtok(NULL,"="); + strcpy(temp_str, p); + p = strtok(temp_str, "."); + for(i=0;i<9;i++) + OID_val[OID_index][i]=cur_oid[i]; + OID_val[OID_index][i++] = atoi(p); + while((p = strtok(NULL, "."))) + OID_val[OID_index][i++] = atoi(p); + OID_index++; + } + else if((temp_ch = strstr(line, "[l]")) != NULL) + { + compute_state = 2; + line_index--; + break; + } + else + { + printf("[Debug] Error: The compute filed script is error.\r\n"); + return ; + } + compute_state = 1; + break; + case 2: //[l] + if((temp_ch = strstr(line, "[l]")) != NULL) + { + temp_ch +=3; + /* + if(temp_ch[0] == '.' && temp_ch[1]=='#') + { + compute_field_list[compute_list_num].list_node = mib_curr_node; + strcpy(temp_str,temp_ch+3); + if(test_str(temp_str, 0) && atoi(temp_str) < MAX_SELECT_OPTION_NUM) + { + compute_field_list[compute_list_num].list_field_id = atoi(temp_str); + compute_list_num++; + break; + } + printf("[Debug] Error: The field id in [l] field is error.%s", temp_str); + return ; + } + else + */ + if((p=strtok(temp_ch,"."))!=NULL) + { + for(i = 0; i < OID_index && strlen(OID_name_str[i]) != 0; i++) + { + if(strcmp(OID_name_str[i], p) == 0) + break; + } + if(i == OID_index || strlen(OID_name_str[i]) == 0) + { + printf("[Debug] Error: Can not define the string:%s.\r\n", p); + return ; + } + for(j = 0; j < 32 && OID_val[i][j] != 0; j++) + { + oid[j] = OID_val[i][j]; + } + find_list_node=search_mib_node(mib_root_node,oid,j); + if(find_list_node!=NULL) + compute_field_list[compute_list_num].list_node = find_list_node; + else + { + printf("[Debug] Error: [l] field :no such mib node for the oid.\r\n"); + return ; + } + p=strtok(NULL,"."); + if(*p=='?') + { + if((p=strtok(NULL,"."))!=NULL) + { + if(test_str(p, 0) && atoi(p) < MAX_SELECT_OPTION_NUM) + { + compute_field_list[compute_list_num].list_field_id = atoi(p); + compute_list_num++; + break; + } + } + } + printf("[Debug] Error: [l] field is error.%s", temp_str); + return ; + } + } + else if((temp_ch = strstr(line, "[p]") )!= NULL) + { + read_syntax_nor_list = 0; + compute_state = 3; + line_index--; + break; + } + compute_state = 2; + break; + case 3: //[p] + if((temp_ch = strstr(line, "[p]")) != NULL && (strstr(line, "[c]")) == NULL) + { + temp_ch += 3; + for(i=0;temp_ch[i] != '\0';i++) + { + if(temp_ch[i] == '=') + break; + } + if(temp_ch[i] == '\0') + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + strncpy(temp_str, temp_ch, i); + temp_str[i] = '\0'; + if(strstr(temp_str,"(")) + { + for(i=0;temp_str[i] != '\0';i++) + { + if(temp_str[i] == '(') + break; + } + if(i == strlen(temp_str) && strstr(temp_str, ")") == NULL) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + strncpy(compute_curr_unit.print_name_str[compute_curr_unit.print_count], temp_str, i); + compute_curr_unit.print_name_str[compute_curr_unit.print_count][i] = '\0'; + value_index = take_compute_value(temp_str + i,temp_value); + if(value_index == 0) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + if(value_index == 1) + strcat(compute_curr_unit.print_name_str[compute_curr_unit.print_count], temp_value); + } + else + strcpy(compute_curr_unit.print_name_str[compute_curr_unit.print_count], temp_str); + temp_ch+=i+1; + for(i=0;temp_ch[i] != '\0';i++) + { + if(temp_ch[i] == '(') + break; + } + if(temp_ch[i] == '\0' && strstr(temp_ch, ")") == NULL) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + temp_ch += i; + value_index = take_compute_value(temp_ch,temp_value); + if(value_index == 0) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + if(value_index == 1) + strcpy(compute_curr_unit.print_val_str[compute_curr_unit.print_count], temp_value); + compute_curr_unit.print_count++; + } + else if((temp_ch = strstr(line, "[c]") )!= NULL) + { + line_index--; + compute_state = 4; + break; + } + compute_state = 3; + break; + case 4: //[c] + if((temp_ch = strstr(line, "[c]")) != NULL && strstr(line, "==") != NULL && (strstr(line, "[p]")) != NULL) + { + + for(curr_instance_index=0;curr_instance_indextotal_instance;curr_instance_index++) + { + strcpy(temp_str1,line); + temp_ch = strstr(temp_str1, "[c]"); + compute_curr_instance=curr_instance_index; + temp_ch += 3; + p = strtok(temp_ch, "=["); + if(p[0] == '(' && p[strlen(p) - 1] == ')') + { + value_index = take_compute_value(p,temp_value); + if(value_index == 0) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + if(value_index == 1) + strcpy(cmp_value[0], temp_value); + } + p = strtok(NULL, "=[");; + if(p[0] == '(' && p[strlen(p) - 1] == ')') + { + value_index = take_compute_value(p,temp_value); + if(value_index == 0) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + if(value_index == 1) + strcpy(cmp_value[1], temp_value); + } + else + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + if(strcmp(cmp_value[0], cmp_value[1]) == 0) + { + strcpy(temp_str1,line); + if((temp_ch = strstr(temp_str1, "[p]")) != NULL) + { + + temp_ch += 3; + for(i=0;temp_ch[i] != '\0';i++) + { + if(temp_ch[i] == '=') + break; + } + if(temp_ch[i] == '\0') + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + strncpy(temp_str, temp_ch, i); + temp_str[i] = '\0'; + if(strstr(temp_str,"(")) + { + for(i=0;temp_str[i] != '\0';i++) + { + if(temp_str[i] == '(') + break; + } + if(i == strlen(temp_str) && strstr(temp_str, ")") == NULL) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + strncpy(compute_curr_unit.print_name_str[compute_curr_unit.print_count], temp_str, i); + compute_curr_unit.print_name_str[compute_curr_unit.print_count][i] = '\0'; + value_index = take_compute_value(temp_str + i,temp_value); + if(value_index == 0) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + if(value_index == 1) + strcat(compute_curr_unit.print_name_str[compute_curr_unit.print_count], temp_value); + + } + else + strcpy(compute_curr_unit.print_name_str[compute_curr_unit.print_count], temp_str); + temp_ch+=i+1; + for(i=0;temp_ch[i] != '\0';i++) + { + if(temp_ch[i] == '(') + break; + } + if(temp_ch[i] == '\0' && strstr(temp_ch, ")") == NULL) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + temp_ch += i; + value_index = take_compute_value(temp_ch,temp_value); + if(value_index == 0) + { + printf("[Debug] Error: The field format is not right.\r\n"); + return ; + } + if(value_index == 1) + strcpy(compute_curr_unit.print_val_str[compute_curr_unit.print_count], temp_value); + compute_curr_unit.print_count++; + + } + else + { + printf("[Debug] Error: No '[p]' in the [c] line.\r\n"); + return ; + } + } + + } + compute_curr_instance=0; + } + else if((temp_ch = strstr(line, "[p]")) != NULL) + { + line_index--; + compute_state = 4; + break; + } + break; + } + } + line_index=print_line_index; + for(index=0;indexcurr_instance+bind_index); + value_index = 1; + return value_index; + } + else if(temp_str[0] == '#') + { + sprintf(temp_str,"%d",compute_curr_instance); + strcpy(temp_value, temp_str); + value_index =1; + return value_index; + } + else + /* + if(temp_str[0] == '.') + { + if(temp_str[2]=='.') + { + strcpy(temp_str1,temp_str); + if(*(temp_str1+1)=='\0' && atoi(temp_str1)==compute_field_list[0].list_field_id) + { + if(temp_str[1] == '#') + { + for(i = 0; i < mib_curr_node->total_instance; i++) + { + strcpy(temp_value[i], compute_field_list[0].field_val[i]); + } + value_index = mib_curr_node->total_instance; + return value_index; + } + else if(temp_str[1] == '*') + { + strcpy(temp_value[0], compute_field_list[0].field_val[mib_curr_node->curr_instance]); + value_index = 1; + return value_index; + } + } + } + } + else + */ + if((temp_ch = strstr(temp_str, "OID"))!=NULL) + { + if(isdigit(temp_ch[3])) + { + strncpy(temp_str1, temp_ch, 4); + temp_ch += 4; + } + else + { + strcpy(temp_str1,"OID"); + temp_ch += 3; + } + for(i = 0; i < OID_index; i++) + { + if(strcmp(OID_name_str[i], temp_str1) == 0) + break; + } + if(i == OID_index) + { + printf("[Debug] Error: Can not find the oid define.\r\n"); + return 0; + } + compute_list_index= i; + + if(temp_ch[0] == '.') + { + strcpy(temp_str1,temp_ch+3); + if(*(temp_str1+1)=='\0' && atoi(temp_str1)==compute_field_list[compute_list_index].list_field_id) + { + if(temp_ch[1] == '#') + { + strcpy(temp_value, compute_field_list[compute_list_index].field_val[compute_curr_instance]); + value_index = 1; + return value_index; + } + else if(temp_ch[1] == '*') + { + strcpy(temp_value, compute_field_list[compute_list_index].field_val[mib_curr_node->curr_instance+bind_index]); + value_index = 1; + return value_index; + } + } + + } + } + return 0; +} + +void compute_field_WatchDog() +{ + char temp_str[32]; + if(list_once==1 && read_syntax_nor_list == 0) + { + if(list_flag == 0 && get_state==0) + { + if(compute_field_list_index < compute_list_num) + { + field_compute_state=4; + mib_curr_node = compute_field_list[compute_field_list_index].list_node; + strcpy((char *)list_msg,""); + //strcat(list_msg," -e "); + strcat((char *)list_msg, "-f["); + sprintf(temp_str, "%d", compute_field_list[compute_field_list_index].list_field_id); + strcat((char *)list_msg, temp_str); + strcat((char *)list_msg, "] "); + strcat((char *)list_msg,"0"); + strcat((char *)list_msg,"-"); + gcvt((double)(mib_curr_node->total_instance-1),3,temp_str); + strcat((char *)list_msg,temp_str); + list_flag=1; + show_list=0; + debug_mmi_list(); + } + } + } + +} + + +void print_compute_field() +{ + char out_text[256],temp_str[64]; + BYTE j,index,k,i=0; + if(list_once==1) + { + if(compute_field_list_index >= compute_list_num && compute_list_num>0) + { + for(index=0;indextotal_child_nodes==1) + { + strcpy(temp_str,""); + for(k=0;kname)+9;k++) + { + strcat(temp_str," "); + } + sprintf(out_text, "%s|---(%d) %s %d",temp_str,compute_field_arr[index].field_id+1, compute_field_arr[index].name,mib_curr_node->curr_instance); + } + else + sprintf(out_text, " |---(%d) %s %d",compute_field_arr[index].field_id+1, compute_field_arr[index].name,mib_curr_node->curr_instance); + debug_color_out(BRIGHT,CYAN,BLACK,out_text); + + if(compute_field_arr[index].print_count==1) + { + sprintf(out_text, " %s" ,compute_field_arr[index].print_name_str[0]); + debug_color_out(BRIGHT,CYAN,BLACK,out_text); + debug_ascii_out_proc(" = "); + if(strlen(compute_field_arr[index].print_val_str[0])) + sprintf(out_text, "%-8s",compute_field_arr[index].print_val_str[0]); + else + sprintf(out_text, "NULL "); + debug_color_out(BRIGHT,BLUE,BLACK,out_text); + debug_ascii_out_proc("\r\n"); + } + else + { + debug_ascii_out_proc("\r\n"); + for(j=0;j0) + compute_curr_unit.print_count=0; + } + } + field_compute_state=5; + print_once=0; + } + } + +} +/////////////////////////////////end of compute field///////////////////////// + +////////////////////////////////Other/////////////////////////////// +void debug_set_currenttime() +{ + u8 ii,jj; + char temp_timer[64]="\0"; + char send_buf[64]="\0"; + time_t tick; + + tick = time(NULL); + + sprintf(temp_timer,"\x1b[25;25Hcurrent time:%.24s",ctime(&tick)); + if (strlen(current_timer) == 0) // current timer is empty + { + for (jj = 0;jj < strlen(temp_timer);jj ++) + debug_send_char(temp_timer[jj]); + strcpy(current_timer,temp_timer); + return; + } + for (ii = 0;ii < strlen(temp_timer);ii ++) + { + if (temp_timer[ii] != current_timer[ii]) + { + sprintf(send_buf,"\x1b[25;%dH%c",25+ii-8,temp_timer[ii]); + for (jj = 0;jj < strlen(send_buf);jj ++) + debug_send_char(send_buf[jj]); + } + } + strcpy(current_timer,temp_timer); +} +/* +* +* Fun: del_space +* +* Desc: remove the spaces at the beginning of string +* +* Ret: string +* +* File: debug.c +* +*/ +void del_space(char *str,BYTE type) +{ + int i,j,k; + if(!strlen(str)) + return; + if(type==0) //del the ahead space + { + for(i=0;i0;i--) + { + if(str[i]!=' ') + { + break; + } + } + str[i+1]='\0'; + + }else if(type==2) //del all the space + { + for(i=0;i0;i--) + { + if(str[i]!=' ') + { + break; + } + } + str[i+1]='\0'; + + } + + +} + + + +/* +* +* Fun: read_line +* +* Desc: Read a line from file fp, remove the spaces in the beginning and in the end of the line, store it in line_ptr +* +* Ret: the length of line +* +* File: debug.c +* +*/ +int read_line(FILE *fp, char *line_ptr) +{ + char *temp_ch_ptr; + int index, index2, length; + + if(feof(fp)) + return 0; + strcpy(line_ptr, ""); + + fgets(line_ptr,512,fp); + temp_ch_ptr = strchr(line_ptr, 0xa); + if (temp_ch_ptr != NULL ) + *temp_ch_ptr = '\0'; + + + length = strlen(line_ptr); + for(index=0; index=0; index--) // cut off all spaces in the ending of the line + { + /* + if(!isprint(line_ptr[index])) + line_ptr[index] = '\0'; + else + { + if(line_ptr[index] == ' ' || line_ptr[index] == '\t') + line_ptr[index] = '\0'; + else + break; + } + */ + if(line_ptr[index] == ' ' || line_ptr[index] == '\t') + line_ptr[index] = '\0'; + else + break; + } + return strlen(line_ptr); +} /* end of read_line */ + + +/* +* +* Fun: read_begin +* +* Desc: read the fp, stop until meet the stop_ch +* +* Ret: the length of the stored string +* +* File: debug.c +* +*/ +int read_begin(FILE *fp, char *stop_ch) +{ + char ch; + int index = 0,i=0; + + while((ch=fgetc(fp)) != EOF) + { + if(stop_ch[i]!='\0') + { + if(ch==stop_ch[i]) + { + i++; + if(stop_ch[i]=='\0') + { + index-=i-1; + break; + } + } + else + i=0; + } + else + break; + if(index == 3072) + break; + } + + return index; +} // end of read_begin + + + +/* +* +* Fun: read_until +* +* Desc: read the fp, store the string to the data_ptr until meet the stop_ch +* +* Ret: the length of the stored string +* +* File: debug.c +* +*/ +int read_until(FILE *fp, char *data_ptr, char *stop_ch) +{ + char ch; + int index = 0,i=0; + while((ch=fgetc(fp)) != EOF) + { + if(stop_ch[i]!='\0') + { + if(ch==stop_ch[i]) + { + i++; + if(stop_ch[i]=='\0') + { + index-=i-1; + break; + } + } + else + i=0; + } + else + break; + data_ptr[index++] = ch; + if(index == 3072) + break; + } + data_ptr[index]= '\0'; + return index; +} // end of read_until + + + +/* +* +* Fun: read_part +* +* Desc: read the fp, store the string to from the start_ch to syop_ch +* +* Ret: the length of the stored string +* +* File: debug.c +* +*/ +int read_part(FILE *fp, char *data_ptr,char *start_ch, char *stop_ch) +{ + read_begin(fp,start_ch); + read_until(fp,data_ptr,stop_ch); + return strlen(data_ptr); +} // end of read_until + + +/* +* +* Fun: pick_first_word(char *str_ptr, char *word_ptr) +* +* Desc: pick out the first word into word_ptr from the str_ptr +* +* Ret: the char pionter which point to the ending of the first word in the string +* +* File: debug.c +* +*/ +char * pick_first_word(char *str_ptr, char *word_ptr) +{ + int index, index2, length; + length = strlen(str_ptr); + for(index = 0; index < length; index ++) + { + if(!isprint(str_ptr[index]))//find the first print char exclude spacebar + continue; + else + { + if(str_ptr[index] == ' ') + continue; + else + break; + } + } + for(index2=0; index <= length; index++, index2++) + { + if( (isprint(str_ptr[index])) && (str_ptr[index] != ' ')) + word_ptr[index2] = str_ptr[index]; + else + break; + } + word_ptr[index2] = '\0'; + return &str_ptr[index]; +} // end of pick_first_word + + +/* +* +* Fun: take_str +* +* Desc: copy the data_str to the data_ptr if data_str is not NULL, or find two '"' in the file fp and take string between the two '"' into data_ptr +* +* Ret: successful: 1, fail: 0 +* +* File: debug.c +* +*/ +int take_str(char *data_str, FILE *fp, char *data_ptr) +{ + char tmp_ch= '"'; + int index; + //printf("take_str begin:\r\n"); + if(strlen(data_str) != 0) + { + strcpy(data_ptr, data_str); + return 1; + } + else + { + while(( !feof(fp) ) && (fgetc(fp) != '"')) + ; + if(feof(fp)) + { + printf("[debug] Error: Can't find a [%c] as beginning of a text befor the End of file.\r\n",'"'); + return 0; + } + index = 0; + while( !feof(fp) ) + { + if( (tmp_ch = fgetc(fp)) != '"' ) + data_ptr[index++] = tmp_ch; + else + { + data_ptr[index] = '\0'; + //printf("take_str end: %s.\r\n",data_ptr); + return 1; + } + } + printf("[debug] Error: Can't find a [%c] as ending of a text before the End of file.\r\n",'"'); + return 0; + } + //printf("take_str end: %s.\r\n",data_ptr); +} // end of take_str; + +void debug_color_out(int attr,int color,int bg,char *str) +{ + int len=strlen(str); + char tmp_str[len+14]; + strcpy(tmp_str,str); + TxtColor(attr,color,bg,tmp_str); + debug_ascii_out_proc(tmp_str); +} + + +void help_cmm(int index,char *str1,char *str2) +{ + char temp_str[3]; + char temp_str1[64],temp_str2[1024]; + strcpy(temp_str1,str1); + strcpy(temp_str2,str2); + debug_ascii_out_proc("Usage "); + sprintf(temp_str,"%d : ",index); + debug_ascii_out_proc(temp_str); + debug_color_out(BRIGHT,YELLOW,BLACK,temp_str1); + debug_ascii_out_proc("\r\n"); + debug_ascii_out_proc(" "); + formatstr(10,temp_str2,0); + debug_ascii_out_proc(temp_str2); + debug_ascii_out_proc("\r\n"); +} + +void formatstr(int len,char *str,BYTE type) +{ + int i, index_1=0, index_2=0; + char temp_str1[1024],temp_str2[1024]; + char format_str[1024]; + char space[80]; + char *p; + int str_len; + double line_num; + if(type) + { + for(i=0;i1024) + { + debug_color_out(BRIGHT,RED,BLACK,"Error : Remark is too long !\r\n"); + return ; + } + p=str; + strcpy(format_str,""); + while(*p!='\0') + { + i=0; + while(i70 && str[i]<97) || str[i]>102)) + break; + } + if(i==strlen(str)) + return 1; + else + return 0; + } + else if(type==2) + { + for(i=0;i90 && str[i]<97) || str[i]>122)) + break; + } + if(i==strlen(str)) + return 1; + else + return 0; + } + else + return 0; +} + +void strpcat(char *dest_str,DWORD *dest_p,const char *src_str) +{ + while((*(dest_str+(*dest_p)++)=*src_str++)); + (*dest_p)--; +} + +void pick_name(char *str_ptr, char *word_ptr,char *temp_ch) +{ + int start_index,end_index,i; + char temp_str[512],*ch; + strcpy(temp_str,str_ptr); + start_index=end_index=i=0; + if(temp_ch!=NULL) + { + for(start_index=0;start_index0;end_index--) + if(*(word_ptr+end_index)!=' ' && *(word_ptr+end_index)!='\t') + break; + *(word_ptr+end_index+1)='\0'; + } +} + + +int get_my_address (struct in_addr *addr) +{ + struct ifreq req; + int sock; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + strncpy (req.ifr_name, "eth0", IFNAMSIZ); + + if ( ioctl(sock, SIOCGIFADDR, &req) < 0 ) + { + printf("failed to ioctl: %s\n", strerror (errno)); + return 0; + } + + memcpy (addr, &((struct sockaddr_in *) &req.ifr_addr)->sin_addr, sizeof (struct in_addr)); + return 1; +} +/*@end@*/ + +////////////////////////////End of Other/////////////////////////// diff --git a/plat/debug/src/include/debug.h b/plat/debug/src/include/debug.h new file mode 100644 index 0000000..733c1dd --- /dev/null +++ b/plat/debug/src/include/debug.h @@ -0,0 +1,60 @@ +/* Debug module strucutre head file */ +/* Written by Liu Wei 2005-05-10 */ +/* Version 4.0 */ +/* -------------------------------- */ + +#ifndef _DEBUG +#define _DEBUG + +#include "debug_struct.h" +#include "dirent.h" + +extern mib_node *mib_root_node; +extern mib_node *mib_curr_node; +extern menu_node *menu_root_node; +extern menu_node *menu_curr_node; +extern mib_node mib_nodes[MIB_MAX_NODES]; + +/*for test + char file_name[128]; + FILE *fp_prt; + long int timeuse,max_time; + struct timeval tv_start, tv_end;*/ +//for test + +extern menu_node menu_nodes[MENU_MAX_NODES]; +extern mib_child_node mib_child_nodes[MIB_MAX_CHILD_NODES]; + +extern debug_snmp_agent debug_snmp_agent_buf[MAX_PACKET_NUM]; + + + +//////////////////////////////interface declaration//////////////////////// + +void debug_init(); + +void debug_rt(); + + +WORD find_child_index(mib_node *node_ptr, DWORD oid, char *name, BYTE type); + +mib_node *find_node(mib_node *start_node_ptr, char *node_name, int find_type, DWORD *last_node_oid); + +mib_node *search_mib_node(mib_node *start_mib_node_ptr, DWORD *oid, BYTE oid_len); + +int debug_set_response(unsigned char object_id_len,unsigned int *object_id,unsigned char *data,unsigned short data_len); + +int debug_get_response(unsigned char object_id_len,unsigned int *object_id,unsigned char *data,unsigned char *vartype); + +menu_node *search_menu_node(menu_node *start_menu_node_ptr, BYTE *menu_id, BYTE id_len); + +void Clear_Access_History(); + +void debug_set_agent(); + +void debug_get_agent(); + +int get_my_address (struct in_addr *addr); + +//////////////////////////////end of interface declaration//////////////////////// +#endif diff --git a/plat/debug/src/include/debug_struct.h b/plat/debug/src/include/debug_struct.h new file mode 100644 index 0000000..a069d40 --- /dev/null +++ b/plat/debug/src/include/debug_struct.h @@ -0,0 +1,374 @@ + /* Debug module strucutre head file */ +/* Written by Liu Zhiguo 2003-04-22 */ +/* Version 2.0 */ +/* -------------------------------- */ + +#ifndef _DEBUG_STRUCT +#define _DEBUG_STRUCT + +#include "../../../public/src/include/pub_include.h" +#include "../../../iptrans/src/include/iptrans.h" +#include "../../../snmp/src/include/snmp.h" +#include "../../../snmp/src/include/heartbeat.h" + +//Module ID +//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 +//a b c d e f g h i j k l m n o p q r s t u v w x y z +//a b c d e f g h i j k l m n o p r s t u v w y z + +#define DEBUG_PORT 4965 +#define DEBUG_SNMP_PORT 4956 +#define SNMP_PORT 4957 +#define DEBUG_VERSION "V1.0.01" + +#define TELNET_SEND_BUF_LEN 1000 +#define SERIAL_BUF_LEN 2048 +#define DEBUG_MAX_PAGE 2 +#define PAGE_MODULE_COUNT 24 +#define MODULE_COUNT (PAGE_MODULE_COUNT*DEBUG_MAX_PAGE) +#define DEBUG_MAX_SEQID 0x7fffffff +#define DEBUG_SEQID_LEN 8 +#define DEBUG_OMCBUF_LEN 1024 +#define DEBUG_NAME_LEN 8 +#define PAGE_COUNT 24 +#define LINE_COUNT 23 +#define MAX_ROW 25 +#define MAX_COLUMN 80 +#define TITLE_CHAR 2048 +#define MAX_ASCII_LEN (1024*16) + +#define DEBUG_SHM_KEY 0xa0600000 +#define DEBUG_SHM_PERM 0664 + +#define MENU_TYPE 0 +#define OID_TYPE 1 + +// MIB wangjian add +#define MIB_LIST_FILE "mib_list_file.txt" +#define MIB_FILES_DIR "./conf/MIB_files/" +#define MIB_OMC_PUB_SYSCONF_FILE "OMC_PUB_sysConf.csv" +#define MIB_PARAM_LIST_FILE "mib_param_list_file.txt" +#define MIB_WRITE_TREE "mib_write_tree.txt" +#define MIB_SYSTEM_CONFIG_FILE "System_Config.txt" +#define MIB_SYSTEM_IP_LIST_FILE "System_IP_List.txt" +#define MENU_TREE_FILE "menu_tree.txt" + +#define MIB_MAX_CHILD_NODES_PER_NODE 256 +#define MIB_MAX_NODES 1536 +#define MIB_MAX_CHILD_NODES 1536 * 5 + +#define MIB_MAX_PARAM_SELECTS 1536 * 8 +#define MIB_MAX_PARAM_INPUTS 1536 * 8 +#define MIB_MAX_NODE_PARAMS 1536 * 4 +#define MAX_TOTAL_INSTANCE 2048 +#define MAX_NODE_PACKET_LENGTH 256 +#define MAX_SEND_CHAR_NUM 512 + +//#define MIB_OPER_TYPE_GET 1 +//#define MIB_OPER_TYPE_GET_ALL 2 +//#define MIB_OPER_TYPE_SET 3 +//#define MIB_OPER_TYPE_HELP 4 + +#define MIB_MODULE_REVISION_MAX_NUM 10 + +#define MIB_SUBSYS_MODULE_MAX_NUM 64 + +#define MIB_HOST_MAX_NUM 127 + +#define MIB_NODE_PARAM_MAX_LEN 64 +#define GROUP_NUM 2 +#define MEMBER_MAX_NUM 16 +#define MENU_MAX_NODES 640 + +#define TODEC_HIGH_0 0 +#define KEEPHEX_HIGH_0 1 +#define KEEPHEX_LOW_0 2 +#define KEEPHEX_LOW_E 3 +#define KEEPHEX_LOW_F 4 +#define TOASCII_LOW_0 5 +#define KEEPASC_LOW_F 6 + + +#define MAX_PACKET_NUM 16 +#define MAX_SELECT_OPTION_NUM 21 +#define MAX_OPTION_LENGTH 32 +#define MAX_HOST_IP 16 +#define MAX_PARAM_NUM 64 + +typedef struct CommandList +{ + char cmm[128]; + struct CommandList *nextcmm; +}cmmset,cmmrem; + +// MIB end + +typedef struct _DEBUG_TELNET_SEND_DATA +{ + int telsend_datah; + BYTE telsend_data[TELNET_SEND_BUF_LEN]; +}DEBUG_TELNET_SEND_DATA; + +struct debug_line +{ + BYTE pt_vartype; + WORD length; + BYTE *pointer; +}; + +struct debug_page +{ + BYTE pointer_set_flag; + char title[TITLE_CHAR]; + struct debug_line line_d[LINE_COUNT]; +}; + +typedef struct debug_module_struct +{ + char name[DEBUG_NAME_LEN]; + char status[2]; + char version[20]; + BYTE maxpage; + BYTE ascii_in_set_flag; + BYTE ascii_out_set_flag; + BYTE *ascii_in; + WORD ascii_in_len; + BYTE *ascii_out; + WORD ascii_out_len; + struct debug_page page_d[PAGE_COUNT]; + int seqid_h; // head sequence id for omc get + int seqid_t; // tail sequence id for omc get + BYTE omc_outbuf[DEBUG_SEQID_LEN][DEBUG_OMCBUF_LEN]; +} debug_module_struct; + +typedef struct debug_shm_struct +{ + debug_module_struct module_d[MODULE_COUNT]; + DEBUG_TELNET_SEND_DATA TelnetSendData; +} debug_shm_struct; + +extern struct debug_shm_struct *debug_shm_ptr; +//struct iptrans_shm *pIptransShm; + +// MIB wangjian add +typedef struct _mibfile_imports_data +{ + char father_name[64]; + char from_file[32]; +} mibfile_imports_data; + +typedef struct _mibfile_module_data +{ + char name[64]; // nod name + char LU[32]; // LAST-UPDATED + char OR[64]; // ORGANIZATION + char CI[128]; // CONTACT-INFO + char DE[1024]; // DESCRIPTION + char RE[MIB_MODULE_REVISION_MAX_NUM][32]; // REVISION + char RE_DE[MIB_MODULE_REVISION_MAX_NUM][1024]; // REVISION'S DESCRIPTION + int RE_index; // the number of RE and RE_DE + char father_name[64]; // father's name + char ID[32]; // child ID +} mibfile_module_data; + +typedef struct _mibfile_object_data +{ + char name[64]; // nod name + int ST; // STATUS: 1: current, 2: deprecated, 3: obsolete. 0: invalid + char DE[1024]; // DESCRIPTION + char RF[1024]; // ReferPart + char father_name[64]; // father's name + char ID[32]; // child ID +} mibfile_object_data; + +typedef struct _mibfile_type_data +{ + char name[64]; // nod name + int SY; // SYNTAX: 0:invalid. 1: Integer32, 2: INTEGER, 3: OCTET STRING, 4: OBJECT IDENTIFIER, 5: BITS, 6: IpAddress, 7: Counter32, + // 8: Gauge32, 9: TimeTicks, 10: Opaque, 11: Counter64, 12: Unsigned32, 13:Conceptual Tables + char UP[32]; // UnitsPart + BYTE MA; // MAX-ACCESS: 0: invalid, 1: not-accessible, 2: accessible-for-notify, 3: read-only, 4: read-write, 5: read-create 6: write-only + int ST; // STATUS + char DE[8192]; // DESCRIPTION + int total_instance; // total_instance + char RF[1024]; // ReferPart; + char father_name[64]; // father's name + char ID[32]; // child ID +} mibfile_type_data; + +//typedef int (*mib_call)(DWORD *oid, BYTE oid_len, char *name, char *value, BYTE oper_type); + +typedef struct _mib_child_node +{ + char name[64]; + DWORD oid; + void *child_ptr; +} mib_child_node; + +typedef struct _mib_node +{ + void *parent_ptr; + char name[32]; + BYTE oid_len; + DWORD oid[32]; + BYTE data_length; + BYTE module_index; + WORD total_instance; + WORD curr_instance; + WORD total_child_nodes; + BYTE enable_field_id; + BYTE enable_flag[32]; + BYTE access_history; + char init_value[256]; + //mib_call mib_proc; + char *remark_ptr; + //char remark[DEBUG_OMCBUF_LEN * 2]; + mib_child_node *child_nodes[MIB_MAX_CHILD_NODES_PER_NODE]; + BYTE max_access; // MAX-ACCESS: 0: invalid, 1: not-accessible, 2: accessible-for-notify, 3: read-only, 4: read-write, 5: read-create 6: write-only +}mib_node; + +typedef struct _menu_node +{ + void *father_ptr; + void *child_node[MENU_MAX_NODES]; + mib_node *menu_oid_node; + BYTE oid[23]; + BYTE id_len; + BYTE total_menu_child; + char name[32]; + BYTE menu_id[20]; + BYTE sys_group; +}menu_node; + +// MIB FIELD struct +typedef struct _mib_param_select +{ + WORD number; + char description[MIB_NODE_PARAM_MAX_LEN]; +} mib_param_select; + +typedef struct _instance_arr +{ + DWORD ins; + BYTE eable; +}INSTANCE_ARR; + +typedef struct _mib_param_input +{ + BYTE input_param_type; // 0: toDec_high_0 + // 1: keepHex_high_0 + // 2: keepHex_low_0 + // 3: keepHex_low_E + // 4: keepHex_low_F + // 5: toAscii_low_0 + // 6: keepAscii_low_F + char input[MIB_NODE_PARAM_MAX_LEN]; +} mib_param_input; + +typedef struct _mib_node_param +{ + void *parent_ptr; + char name[64]; + BYTE id; + BYTE byte_begin; + BYTE byte_end; + BYTE bit_begin; + BYTE bit_end; + mib_param_select *select_ptr[16]; + BYTE select_total; + BYTE select_value; + mib_param_input *input_ptr; +} mib_node_param; + + + + +typedef struct _mib_subsys_module +{ + BYTE index; + DWORD oid[8]; + char name[10]; + BYTE max_group; + //char obj_type_no[3]; +}mib_subsys_module; + +typedef struct _mib_host +{ + BYTE index; + BYTE group_index; + BYTE member_index; + char host_name[32]; + WORD host_ip[4]; +}mib_host; + +typedef struct _module_command_save_flag +{ + BYTE module_index; + DWORD oid[32]; + BYTE oid_len; + BYTE save_select_id; + BYTE save_field_id; +}module_command_save_flag; + + +typedef struct param_field +{ + char name[48]; //set fill in + char curr_input_value[32]; //set fill in + BYTE input_type; + BYTE curr_select_id; + BYTE total_select; + WORD value_arr[MAX_SELECT_OPTION_NUM]; + char value_arr_remark[MAX_SELECT_OPTION_NUM][MAX_OPTION_LENGTH]; +}param_field; + +typedef struct debug_snmp_agent_packet +{ + DWORD oid[32]; //set fill in + //0 idle 1 waitting get 2 waitting set 3 process 4 fail 5 success + BYTE cmm_state; //set fill in + //0 success 1 time out 2 buffer full 3 oid error 4 ip str error + //5 instance error 6 leaf node param forbidden 7 total field error + //8 no select option 9 snmp send error 1xx no child 2xx no select 3xx field input error + BYTE result_state; + BYTE agentClient; + BYTE oid_len; //set fill in + BYTE total_field; //set fill in + WORD total_instance; //set fill in + BYTE total_ip; //set fill in + char dst_ip[MAX_HOST_IP][15]; //set fill inxxx.xxx.xxx.xxx + param_field param_field_arr[MAX_PARAM_NUM]; + +}debug_snmp_agent; + +//MIB end + + + +typedef struct _comput_list +{ + BYTE list_field_id; + char field_val[256][32]; + mib_node *list_node; +}compute_list; + +typedef struct _compute_field +{ + char name[32]; + mib_node *compute_node; + BYTE field_id; + char syntax_str[10][64]; + BYTE syntax_count; + char print_val_str[128][32]; + char print_name_str[128][32]; + BYTE print_count; +}compute_field; + +typedef struct _wxc2_debug_info +{ + char wxc2_ver[32]; + BYTE sys_type; // cdma 1 gsm 2 gc_ssw 3 + BYTE mmi_switch; // on 1 0 off +}wxc2_debug_info; + +#endif diff --git a/plat/debug/ut/debug_test.c b/plat/debug/ut/debug_test.c new file mode 100644 index 0000000..fb54ba2 --- /dev/null +++ b/plat/debug/ut/debug_test.c @@ -0,0 +1,926 @@ + +/************************************************ + * debug_test.c + * Author: LiuWei + * Create: 2005-05-31 +************************************************/ + +#include "./include/debug.h" +#include "../../iptrans/src/include/iptrans.h" +#include "../../snmp/src/include/snmp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define BUFLEN 1024 +#define MAX_RECV_NONE 20 +#define REC_NUM 50 + +char shellcode[] = "\x97\x97\x97\x97\x97\x97"; + +//add test line + +static struct itimerval itimer, old_itimer; +fd_set rset; +BYTE connect_flag = 0; +struct sockaddr_in sin_addr; +int flag = 1; +int sockfd; +char buffer[2048]; +int command_list_count; +BYTE recv_over = 0; +int addr_len = sizeof(struct sockaddr_in); +int len = 0; +BYTE recv_ten_times = 0; +BYTE test_style = 2; +BYTE test_snmp_mode = 0; +char oid_cmm_state[128]; +BYTE recv_none = 0; +//char file_name[128]; +FILE *fp_conf,*fp_agent; +struct timeval tv_start, tv_end; +long timeuse; +long max_time; +int i, j; +int time_vel; +int multi; +char data_arr[1024], multi_str[16]; +char command[1024]; +char oid_command[128]; + + +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len); +void MMI_telnet(); +void MMI_telnet_send(char *str); +void MMI_auto_test(); +void MMI_telnet_recv(); +void Set_Timer(); +void On_Timer(); +void MMI_telnet_cmd(); +void debug_snmp_agent_test_input(); +void debug_snmp_agent_test_output(); +void debug_snmp_print(); +void MMI_File_Test(char *data_arr); + +void usage(char *p) +{ + printf("Usage: %s [ip] [-a atuo test] [-m manual test] [-n normal start] [-f script file]\n\n", p); + printf("\n"); + exit(0); +} + +void msg(char *msg) +{ + perror(msg); + exit(errno); +} + +u_int32_t get_ip(char *host) +{ + struct hostent *hp; + + if(!(hp = gethostbyname(host))) + { + fprintf(stderr, "cannot resolve %s\n", host); + return (0); + } + return (*(u_int32_t *) hp->h_addr_list[0]); +} + +int get_socket(char *target, int port) +{ + int sock; + u_int32_t ip; + + if(!(ip = get_ip(target))) + return (0); + + bzero(&sin_addr, sizeof(sin_addr)); + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = htons(port); + sin_addr.sin_addr.s_addr = ip; + + if(!(sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + msg("Get socket:"); + if(ioctl(sock, FIONBIO, &flag) == -1) + { + printf("Set nonblock:"); + close(sockfd); + exit(1); + } + if(connect(sock, (struct sockaddr *)&sin_addr, sizeof(sin_addr)) < 0) + if((errno != EWOULDBLOCK) && (errno != EINPROGRESS)) + msg("Connect:"); + return (sock); +} + +void send_wont(int sock, int option) +{ + char buf[3], *ptr = buf; + + *ptr++ = IAC; + *ptr++ = WONT; + *ptr++ = (unsigned char)option; + if(write(sock, buf, 3) < 0) + msg("write"); + return; +} + +void send_will(int sock, int option) +{ + char buf[3], *ptr = buf; + + *ptr++ = IAC; + *ptr++ = WILL; + *ptr++ = (unsigned char)option; + if(write(sock, buf, 3) < 0) + msg("write"); + return; +} + +void send_do(int sock, int option) +{ + char buf[3], *ptr = buf; + + *ptr++ = IAC; + *ptr++ = DO; + *ptr++ = (unsigned char)option; + if(write(sock, buf, 3) < 0) + msg("write"); + return; +} + +void send_env(int sock, char *name, char *value) +{ + char buf[BUFLEN], *ptr = buf; + + *ptr++ = IAC; + *ptr++ = SB; + *ptr++ = TELOPT_NEW_ENVIRON; + *ptr++ = TELQUAL_IS; + *ptr++ = NEW_ENV_VAR; + strncpy(ptr, name, BUFLEN - 20); + ptr += strlen(ptr); + *ptr++ = NEW_ENV_VALUE; + strncpy(ptr, value, (&buf[BUFLEN - 1] - ptr) - 1); + ptr += strlen(ptr); + *ptr++ = IAC; + *ptr++ = SE; + + if(write(sock, buf, (ptr - buf)) < 0) + msg("write"); + return; +} + +void do_negotiate(int sock) +{ + send_will(sock, TELOPT_ECHO); + send_wont(sock, TELOPT_TTYPE); + send_wont(sock, TELOPT_NAWS); + send_wont(sock, TELOPT_LFLOW); + send_wont(sock, TELOPT_LINEMODE); + send_wont(sock, TELOPT_XDISPLOC); + send_will(sock, TELOPT_LFLOW); + send_will(sock, TELOPT_LINEMODE); + send_wont(sock, TELOPT_OLD_ENVIRON); + send_will(sock, TELOPT_NEW_ENVIRON); + send_will(sock, TELOPT_BINARY); + send_env(sock, "TTYPROMPT", shellcode); + return; +} + +int main(int argc, char **argv) +{ + int c, port = DEBUG_PORT; + char host[36] = "172.18.234.231"; + + strcpy(command, ""); + strcpy(oid_command, ""); + strcpy(oid_cmm_state, ""); + if(argc < 2) + usage(argv[0]); + + tv_start.tv_sec = 0; + tv_start.tv_usec = 0; + tv_end.tv_sec = 0; + tv_end.tv_usec = 0; + + + + + //ioperm(0x378,3,1); + /* + strcpy(file_name, ""); + strcat(file_name, "debug_agent.txt"); + remove(file_name); + */ + + strcpy(file_name, ""); + strcat(file_name, "debug_test_time_log.txt"); + remove(file_name); + + if((fp_prt = fopen(file_name, "a+")) == NULL) + { + printf("[debug] Error: cannot open %s.\r\n", file_name); + return 0; + } + + + while((c = getopt(argc, argv, "famn")) != -1) + { + switch (c) + { + case 'f': // costumer test + printf("The Debug test control by command script!"); + test_style = 4; + break; + case 'a': // auto test + printf("The Debug Atuo Test!"); + test_style = 1; + break; + case 'm': // manually test + printf("The Debug manually Test!"); + test_style = 2; + break; + case 'n': // normal start + printf("The Debug Normal start!"); + test_style = 3; + break; + } + } + debug_init(1); + iptrMainInit(); + snmp_init(4957); + + if(!(sockfd = get_socket(host, port))) + exit(-1); + command_list_count = 0; + if(test_style == 4) + strcpy(command, ""); + strcpy(multi_str, ""); + strcpy(data_arr, ""); + strcpy(file_name, ""); + strcat(file_name, "debug_test_conf.txt"); + j = REC_NUM + 1; + if((fp_conf = fopen(file_name, "r")) == NULL) + { + printf("[debug] Error: cannot open %s.\r\n", file_name); + return 0; + } + + Set_Timer(); + while(1) + { + usleep(10); + } + +} + +void MMI_File_Test(char *data_arr) +{ + + for(i = 0; i < strlen(data_arr); i++) + if(data_arr[i] == ' ') + break; + if(i != strlen(data_arr)) + strncpy(multi_str, data_arr, i); + multi_str[i] = '\0'; + multi = strtoul(multi_str, NULL, 10); + for(; i < strlen(data_arr); i++) + { + if(data_arr[i] != ' ') + break; + } + strcpy(command, data_arr + i); + if(strncasecmp(command, "\\e", 2) == 0) + { + command[0] = 27; + command[1] = '\0'; + } + if(strcmp(command, oid_command) != 0) + { + strcpy(oid_command, command); + if(strcmp(command, "\e") == 0) + fprintf(fp_prt, "Command :\e\n"); + else + fprintf(fp_prt, "Command :%s \n", command); + } + + if(strcmp(command, "\e") != 0) + { + strcat(command, "\r\n"); + } + printf("%s", command); + MMI_telnet_send(command); + usleep(5); + + recv_over = 0; + usleep(time_vel); + +} + +void MMI_auto_test() +{ + + strcpy(command, ""); + switch (command_list_count) + { + case 0: + strcpy(command, "\e"); + multi = 1; + break; + case 1: + strcpy(command, "menu"); + multi = 5; + break; + case 2: + + strcpy(command, "contents"); + multi = 8; + break; + case 3: + strcpy(command, "cd 1"); + multi = 10; + break; + case 4: + strcpy(command, "cd 4"); + multi = 10; + break; + case 5: + strcpy(command, "list -a -f[2 4 10] -r -t"); + multi = 25; + break; + case 6: + strcpy(command, "get #0.1"); + multi = 15; + break; + case 7: + strcpy(command, "cmm"); + multi = 15; + break; + case 8: + strcpy(command, "\e"); + multi = 20; + break; + /* + case 9: + strcpy(command, "log all"); + multi = 150; + break; + case 10: + strcpy(command, "\e"); + multi = 10; + break; + case 11: + strcpy(command, "\e"); + multi = 10; + break; + case 12: + strcpy(command, "log none"); + multi = 15; + break; + case 13: + strcpy(command, "\e"); + multi = 15; + break; + case 14: + strcpy(command, "help"); + multi = 15; + break; + case 15: + strcpy(command, "\e"); + multi = 15; + break; + */ + default: + command_list_count = 0xfffe; + break; + } + command_list_count++; + if(command_list_count == 0xffff) + { + test_snmp_mode = 1; + printf("The command test over\r\n"); + printf("Test snmp senior interface......\r\n"); + return; + } + time_vel = multi * 500; + if(command_list_count != 0xffff && recv_over == 2) + { + + if(strcmp(command, oid_command) != 0) + { + strcpy(oid_command, command); + if(strcmp(command, "\e") == 0) + fprintf(fp_prt, "Command :\e"); + else + fprintf(fp_prt, "Command :%s ", command); + } + + if(strcmp(command, "\e") != 0) + { + strcat(command, "\r\n"); + } + MMI_telnet_send(command); + + usleep(5); + if(command_list_count > 0) + printf("%s", command); + recv_over = 0; + usleep(time_vel); + } + else + command_list_count--; +} + +void MMI_telnet_recv() +{ + + len = 0; + bzero(buffer, sizeof(buffer)); + + len = recvfrom(sockfd, buffer, sizeof(buffer), 0, + (struct sockaddr *)&sin_addr, &addr_len); + if(len > 0) + { + printf("%s", buffer); + recv_none = 0; + } + else + { + if(recv_none < MAX_RECV_NONE) + recv_none++; + else if(recv_over == 1) + recv_over = 2; + return; + } + if(strstr(buffer, "<--")) + { + recv_over = 1; + return; + } + if(strstr(buffer, "CMM>") || strstr(buffer, "CFG>") || + strstr(buffer, "MENU>") || recv_over == 1) + recv_over = 2; + return; +} + +void MMI_telnet_cmd() +{ + + + + if(ioctl(fileno(stdin), FIONBIO, &flag) == -1) + { + printf("Set stdin nonblock:"); + exit(1); + } + len = 0; + bzero(buffer, sizeof(buffer)); + strcpy(command, ""); + fgets(buffer, sizeof(buffer), stdin); + len = strlen(buffer); + if(!len) + return; + strcpy(command, buffer); + if(strcmp(command, oid_command) != 0) + { + strcpy(oid_command, command); + + if(strcmp(command, "\e") == 0) + fprintf(fp_prt, "Command :ESC"); + else + fprintf(fp_prt, "Command :%s ", command); + + } + usleep(5); + if(strstr(buffer, "\e\n")) + recv_over = 2; + if(strcmp(buffer, "\e\n") != 0) + { + buffer[strlen(buffer) - 1] = '\0'; + strcat(buffer, "\r\n"); + } + if(recv_over > 1) + { + if(sendto(sockfd, buffer, len, 0, (struct sockaddr *)&sin_addr, + addr_len) < 0) + msg("Send"); + recv_over = 0; + } +} + +void MMI_telnet_send(char *str) +{ + bzero(buffer, sizeof(buffer)); + strcpy(buffer, str); + len = strlen(buffer); + if(strlen(str)) + if(sendto(sockfd, buffer, len, 0, (struct sockaddr *)&sin_addr, + addr_len) < 0) + msg("Send"); +} + +void On_Timer() +{ + if(test_style == 1) + { + iptrans_timer(); + snmp_timer(); + outb(0xff, 0x378); + //timeuse = 0; + //gettimeofday(&tv_start, NULL); + debug_rt(); + /* + gettimeofday(&tv_end, NULL); + timeuse = + 1000000 * (tv_end.tv_sec - tv_start.tv_sec) - + tv_start.tv_usec + tv_end.tv_usec; + if(timeuse > max_time) + max_time = timeuse; + fprintf(fp_prt, + " debug_rt time used: %ld (u sec)<=%ld\r\n\r\n", + timeuse, max_time); + */ + outb(0x00, 0x378); + if(connect_flag == 0) + { + do_negotiate(sockfd); + MMI_telnet_recv(); + send_wont(sockfd, TELOPT_BINARY); + MMI_telnet_recv(); + FD_ZERO(&rset); + connect_flag = 1; + } + MMI_telnet_recv(); + if(!test_snmp_mode) + MMI_auto_test(); + else + { + debug_snmp_agent_test_input(); + debug_snmp_agent_test_output(); + debug_snmp_print(); + } + } + if(test_style == 2) + { + + iptrans_timer(); + snmp_timer(); + outb(0xff, 0x378); + //timeuse = 0; + //gettimeofday(&tv_start, NULL); + debug_rt(); + /* + gettimeofday(&tv_end, NULL); + timeuse = + 1000000 * (tv_end.tv_sec - tv_start.tv_sec) - + tv_start.tv_usec + tv_end.tv_usec; + if(timeuse > max_time) + max_time = timeuse; + fprintf(fp_prt, + " debug_rt time used: %ld (u sec)<=%ld\r\n\r\n", + timeuse, max_time); + */ + outb(0x00, 0x378); + if(connect_flag == 0) + { + do_negotiate(sockfd); + MMI_telnet_recv(); + send_wont(sockfd, TELOPT_BINARY); + MMI_telnet_recv(); + FD_ZERO(&rset); + connect_flag = 1; + } + MMI_telnet_recv(); + MMI_telnet_cmd(); + } + if(test_style == 3) + { + iptrans_timer(); + snmp_timer(); + + //timeuse = 0; + // gettimeofday(&tv_start, NULL); + //outb(0xff, 0x378); + debug_rt(); + //outb(0x00, 0x378); + /* + gettimeofday(&tv_end, NULL); + timeuse = + 1000000 * (tv_end.tv_sec - tv_start.tv_sec) - + tv_start.tv_usec + tv_end.tv_usec; + if(timeuse > max_time) + max_time = timeuse; + fprintf(fp_prt, + "debug_rt time used: %ld (u sec)<=%ld\r\n\r\n", + timeuse, max_time); + */ + + } + if(test_style == 4) + { + iptrans_timer(); + snmp_timer(); + + timeuse = 0; + gettimeofday(&tv_start, NULL); + outb(0xff, 0x378); + debug_rt(); + outb(0x00, 0x378); + + gettimeofday(&tv_end, NULL); + timeuse = + 1000000 * (tv_end.tv_sec - tv_start.tv_sec) - + tv_start.tv_usec + tv_end.tv_usec; + + if(timeuse > max_time) + max_time = timeuse; + if(timeuse>500) + fprintf(fp_prt, + " debug_rt time used: %ld (u sec)<=%ld\r\n\r\n", + timeuse, max_time); + + if(connect_flag == 0) + { + do_negotiate(sockfd); + MMI_telnet_recv(); + send_wont(sockfd, TELOPT_BINARY); + MMI_telnet_recv(); + FD_ZERO(&rset); + connect_flag = 1; + } + MMI_telnet_recv(); + if(recv_over == 2) + { + if(!feof(fp_conf)) + { + + fgets(data_arr, 1024, fp_conf); + if(data_arr[strlen(data_arr) - 1] == '\n') + data_arr[strlen(data_arr) - 1] = '\0'; + else + { + if(!feof(fp_conf)) + { + printf("Debug test conf file error!:%s\n",data_arr); + exit(0); + } + } + + if(!strlen(data_arr) ||(strstr(data_arr,"\\")) == data_arr + 0) + return; + MMI_File_Test(data_arr); + + } + else + { + if(j == 1) + test_style = 0; + else if(j > 0) + { + j--; + rewind(fp_conf); + } + } + } + } +} + +void Set_Timer() +{ + struct sigaction act; + + act.sa_handler = On_Timer; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + if(sigaction(SIGALRM, &act, NULL) < 0) + { + perror("Produce Sigaction"); + exit(1); + } + + itimer.it_interval.tv_sec = 0; + itimer.it_interval.tv_usec = 20 * 1000; + itimer.it_value.tv_sec = 0; + itimer.it_value.tv_usec = 20 * 1000; + + if(setitimer(ITIMER_REAL, &itimer, &old_itimer) != 0) + { + printf("Setting Timer error! \n"); + exit(1); + } +} + +void debug_snmp_agent_test_input() +{ + debug_snmp_agent snmp_agent_packet1; + DWORD temp_oid1[32] = + { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 3, 2, 2, 2, 1, 2 }; + DWORD temp_oid2[32] = + { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 3, 2, 2, 2, 1, 3 }; + WORD i,index; + + for(i=0;i3) + debug_snmp_agent_buf[i].cmm_state=6; + } + +} + + +void debug_snmp_print() +{ + char cmm_state_flag[128], result_state_flag[128], temp_str[32]; + WORD i, j; + + + strcpy(file_name, ""); + strcat(file_name, "debug_agent.txt"); + + if((fp_agent = fopen(file_name, "a+")) == NULL) + { + printf("[debug] Error: cannot open %s.\r\n", file_name); + return ; + } + + strcpy(cmm_state_flag, "cmm_state: "); + strcpy(result_state_flag, "result : "); + fprintf(fp_agent,"\r\nDebug snmp senior interface buffer: \r\n"); + fprintf(fp_agent,"index : "); + for(i = 0; i < 16; i++) + fprintf(fp_agent,"%3d ", i); + fprintf(fp_agent,"\r\n"); + for(i = 0; i < MAX_PACKET_NUM; i++) + if(debug_snmp_agent_buf[i].cmm_state != 0) + break; + //if(i == MAX_PACKET_NUM) + // return; + + for(i = 0; i < MAX_PACKET_NUM; i++) + { + sprintf(temp_str, "%3d ", debug_snmp_agent_buf[i].cmm_state); + strcat(cmm_state_flag, temp_str); + } + if(strcmp(oid_cmm_state, cmm_state_flag) != 0) + { + + strcpy(oid_cmm_state, cmm_state_flag); + fprintf(fp_agent,cmm_state_flag); + fprintf(fp_agent,"\r\n"); + for(i = 0; i < MAX_PACKET_NUM; i++) + { + sprintf(temp_str, "%3d ",debug_snmp_agent_buf[i].result_state); + strcat(result_state_flag, temp_str); + } + fprintf(fp_agent,result_state_flag); + + fprintf(fp_agent,"\r\n id OID OID_len Total field Total instance \r\n"); + for(i = 0; i < MAX_PACKET_NUM; i++) + { + strcpy(cmm_state_flag, ""); + sprintf(temp_str, "[%2d]: ", i); + strcat(cmm_state_flag, temp_str); + for(j = 0; j < 32 && debug_snmp_agent_buf[i].oid[j] != 0; + j++) + { + sprintf(temp_str, "%ld.", + debug_snmp_agent_buf[i].oid[j]); + strcat(cmm_state_flag, temp_str); + } + if(j < debug_snmp_agent_buf[i].oid_len - 1) + { + fprintf(fp_agent,"%ld.", debug_snmp_agent_buf[i].oid[j]); + } + sprintf(temp_str, " %d ", + debug_snmp_agent_buf[i].oid_len); + strcat(cmm_state_flag, temp_str); + fprintf(fp_agent,cmm_state_flag); + fprintf(fp_agent," %3d ", + debug_snmp_agent_buf[i].total_field); + fprintf(fp_agent," %3d \r\n", + debug_snmp_agent_buf[i].total_instance); + } + fprintf(fp_agent,"\r\n"); + } + fclose(fp_agent); +} + + + +/* +#define numFuncs 2 + + +typedef void ( *ptFuncDef )(); +ptFuncDef ptFuncArr[] = { &debug_mmi_list, &debug_snmp_get_rt,&debug_snmp_set_rt,&debug_ }; + +for ( i = 0; i < numFuncs; i++ ) +{ + gettimeofday( &start, NULL ); + ptFuncArr[i](); + gettimeofday( &end, NULL ); +} +*/ diff --git a/plat/diameter/daemon/daemon.c b/plat/diameter/daemon/daemon.c new file mode 100644 index 0000000..f0d158d --- /dev/null +++ b/plat/diameter/daemon/daemon.c @@ -0,0 +1,10 @@ +extern int fd_main(int argc, char * argv[]); + +int main(int argc, char *argv[]) +{ + + + fd_main(argc, argv); + + return 0; +} diff --git a/plat/diameter/doc/acl_wl.conf.sample b/plat/diameter/doc/acl_wl.conf.sample new file mode 100644 index 0000000..0422194 --- /dev/null +++ b/plat/diameter/doc/acl_wl.conf.sample @@ -0,0 +1,19 @@ +# Configuration file for the peer whitelist extension. +# +# This extension is meant to allow connection from remote peers, without actively +# maintaining this connection ourselves (as it would be the case by declaring the +# peer in a ConnectPeer directive). +# The format of this file is very simple. It contains a list of peer names +# separated by spaces or newlines. +# +# The peer name must be a fqdn. We allow also a special "*" character as the +# first label of the fqdn, to allow all fqdn with the same domain name. +# Example: *.example.net will allow host1.example.net and host2.example.net +# +# At the beginning of a line, the following flags are allowed (case sensitive) -- either or both can appear: +# ALLOW_OLD_TLS : we accept unprotected CER/CEA exchange with Inband-Security-Id = TLS +# ALLOW_IPSEC : we accept implicitly protected connection with with peer (Inband-Security-Id = IPSec) +# It is specified for example as: +# ALLOW_IPSEC vpn.example.net vpn2.example.net *.vpn.example.net +# These flag take effect from their position, until the end of the line. + diff --git a/plat/diameter/doc/app_acct.conf.sample b/plat/diameter/doc/app_acct.conf.sample new file mode 100644 index 0000000..dd80ead --- /dev/null +++ b/plat/diameter/doc/app_acct.conf.sample @@ -0,0 +1,82 @@ +####################### +# This file contains the description of configuration and general information about the +# "App_Acct" extension. + +# This extension provides a simple Diameter Accounting server. +# The extension does receive the Accounting-Request message, then +# saves the contents of the AVP in a database, as configured here. +# The data is not processed at all. The intent is that a dedicated +# application will then pull from this database and process the data (consolidate +# sessions, ...) + +# In order to enable this extension, the main freeDiameter configuration file +# must contain the following declaration: +# LoadExtension = "extensions/app_acct.fdx" : "/path/to/app_acct.conf" ; +####################### + +################# +## Part I: AVP ## +################# + +# Configure here the AVPs that must be stored in the database. +# The format is: +# "AVP-dictionary-name" = { +# field = "db-field-name"; +# required; +# multi=N; +# }; +# Where: +# AVP-dictionary-name: +# The name of the AVP, such as "Session-Id". Only this field is mandatory. +# field="...": +# The name of the field in the database where is AVP contents will be saved. +# The default is that the field is named as the AVP-dictionary-name. +# required: +# By default, if the AVP is not in the Diameter message, it is not passed in +# the INSERT statement (will get NULL). If Required is specified for the AVP, +# an error is returned in the Diameter answer, and the data is discarded. +# multi=N: +# If an AVP may appear several times in a request, you may specify a number of +# occurrences to save in the database. The Nth first occurrences of the AVP +# will be saved in fields "db-field-name1", "db-field-name2", ... "db-field-nameN" +# +# In case the default behavior for an AVP is fine, you can use the short syntax: +# "AVP-dictionary-name"; +# +# Note that at the moment, GROUPED AVP are not supported. Also, only the top-level AVPs are +# searched. This behavior can be changed quite easily if needed. + +# You may look at contrib/app_acct_tools/app_acct.conf and database.sql files +# for an example of setup. + + +####################### +## Part II: Database ## +####################### + +# You must specify the connection information to the database here. +# Please note that if the connection is terminated, it will trig the shutdown of the freeDiameter daemon +# For this reason, you should as much as possible use a local database. + +# ConnInfo: +# The connection string to the database. See http://www.postgresql.org/docs/8.4/static/libpq-connect.html +# Example: ConnInfo = "host=localhost port=5432 dbname=acct user=acct password=freediameter"; + +# Table: +# The name of the table to use. The fields and types in this table must be created accordingly to the Part I configuration in this file. +# Example: Table = "incoming"; + +# Timestamp_field: +# Optionally, you can specify a name of a field that will receive the value 'now' when a new record is inserted. +# Default: no timestamp is inserted. +# Example: Timestamp_field = "recorded_on"; + +# Server_name_field: +# Optionally, you can specify a field which will receive the Diameter Identity of the local server for each record saved. +# This is useful especially if you have several Accounting servers and want to check Load-Balancing behavior or so, +# after aggregating all the data. +# Default: no server name inserted. +# Example: Server_name_field = "recorded_serv"; + + + diff --git a/plat/diameter/doc/app_diameap.conf.sample b/plat/diameter/doc/app_diameap.conf.sample new file mode 100644 index 0000000..dfa2c61 --- /dev/null +++ b/plat/diameter/doc/app_diameap.conf.sample @@ -0,0 +1,44 @@ +##### a sample Configuration file for DiamEAP + +# MySQL Database settings +# Specify connection parameters for DiamEAP MySQL database: +# - username and password to connect to the MySQL Server +# - databaseserver : the MySQL server location. It can be the IP address or the host name where MySQL server is located. 'localhost' can be used as the location if the server is locatd in the same host than DiamEAP. +# - database_name : the created database for DiamEAP. + +# Syntax : +# DiamEAP_MySQL = "" , "" , "" , ""; + + + +##### Extensible Authentication Protocol (EAP) Methods Plugins ##### +# An EAP method is identified by its EAP method name, EAP TYPE, VENDOR and path to its EAP Method Plugin. +# Optionally, path to a configuration file of plugin can also be provided. +# Location of plugins and their configuration files can be provided by the absolute pathor the relative path from the location configured in cmake. +# An EAP Method Plugin can not be loaded twice. Only the first added method will be loaded. +# Any EAP Method plugin with a same EAP_TYPE value than an already loaded one will be discarded. +# EAP Methods are added in the same order they are added to the the configuration file. + +# Syntax : +# Load_plugin = "":EAP_TYPE:VENDOR:"":""; +# +# Example: +# Load_plugin = "EAP MD5":4:0:"/extensions/eap_md5.emp":""; +# Load_plugin = "EAP TLS":13:0;"/extensions/eap_tls.emp":"/doc/eap_tls_plugin.diameap.conf"; + +Load_plugin = "EAP Identity":1:0:"/extensions/eap_identity.emp":""; + +# Enable/disable checking User's Identity. If disabled, default parameters value will be used for authentication and authorization attributes. +# Default values are defined in database for 'Default User'. +Check_User_Identity = 1; + +# In addition to authentication DiamEAP can be configured to check authorization of authenticated users. If set to 0 authorization is disabled, otherwise enabled.( by default disabled). +Authorization = 1; + +# This parameter specify the maximum number of seconds provided to the access device for responding to an EAP request. (by default set to 30 seconds) +#Multi_Round_Time_Out=30; + +# After receivin a number of invalid EAP packets, DiamEAP reject the authentication by responding with Failure Authentication. +# The default value of maximum number of invalid EAP packets is set to 5 packets. +# The value of maximum invalid EAP packets can be modified by adding a new value. +#MAX_Invalid_EAP_Packets=5; diff --git a/plat/diameter/doc/app_radgw.conf.sample b/plat/diameter/doc/app_radgw.conf.sample new file mode 100644 index 0000000..b22492b --- /dev/null +++ b/plat/diameter/doc/app_radgw.conf.sample @@ -0,0 +1,105 @@ +# This file contains information for configuring the app_radgw extension. +# To find how to have freeDiameter load this extension, please refer to the freeDiameter documentation. +# +# The app_radgw extension allows a freeDiameter agent to serve as a +# RADIUS/Diameter gateway. Typically, a RADIUS client (e.g. a NAS) will connect to +# this agent, and the message will be converted to Diameter and sent to a Diameter server. +# +# Note that this extension does not provide a fully functionnal RADIUS/Diameter gateway. +# You need to load plugins to handle specific RADIUS messages and convert them to +# Diameter apps such as NASREQ, EAP, ... See the next section for information. + + +########### +# PLUGINS # +########### + +# Additional plugins must be loaded to support specific RADIUS messages and attributes. + +# Plugins are registered either for every message, or by port (auth or acct), or by port and code. +# The general format is: +# RGWX = plugin [: conf_file] [: port] [: code(s)] ; +# Where: +# plugin is the quoted file name (relative or absolute) of the plugin to load (.rgwx files). +# conf_file (optional) is the quoted name of the configuration file. +# port (optional), either auth or acct. +# If not specified, extension is called for messages incoming on both ports +# code(s): space-separated list of command codes for which this extension must be called. +# If not specified, the extension is called for all incoming messages. +# The values are interpreted as hexadecimal. +# +# The plugins are called in the order they appear in this file. +# Here are some explained examples: +# RGWX = "3579.rgwx"; Load this extension and call it for all messages. No configuration file. +# RGWX = "3579.rgwx" : "3579.conf"; Same as previous but with a configuration file specified. +# RGWX = "3579.rgwx" : auth; No configuration file, but called only for RADIUS messages received on authentication port. +# RGWX = "3579.rgwx" : 4 8 b; Called for messages with command code 4, 8, or 11 only. +# RGWX = "3579.rgwx" : "3579.conf" : auth : 4 8 b; All parameters combined. + +# Once the list of extensions for an incoming message has been called (or if the list is empty), +# an error is logged if some RADIUS attributes of the message have not been handled. + +RGWX = "extensions/echodrop.rgwx" : "echodrop.rgwx.conf"; # See echodrop.rgwx.conf.sample file +RGWX = "extensions/auth.rgwx" : auth; +RGWX = "extensions/acct.rgwx" : acct; +# RGWX = "extensions/debug.rgwx"; # Uncomment to see the result of the translation plugins. + +# For some extensions (auth, acct), a false configuration file name +# can be passed to specify flags, such as "nonai" to ignore NAI-based routing. + +################## +# RADIUS Clients # +################## + +# Each RADIUS client must be declared in the form: +# nas = IP / shared-secret ; +# IP can be ipv4 or ipv6 +# port can be additionaly restricted with brackets: IP[port] (ex: 192.168.0.1[1812]) +# shared-secret can be a quoted string, or a list of hexadecimal values. +# examples: +# nas = 192.168.100.1 / "secret key" ; # the shared secret buffer is 0x736563726574206b6579 (length 10 bytes) +# nas = fe00::1 / 73 65 63 72 65 74 20 6b 65 79; # same shared secret as previously +# When a packet is received from an IP not declared here, it is discarded. + +# If the RADIUS client is a Proxy that forwards messages from different peers, it must be +# declared instead as follow: +# pxy = IP / shared-secret ; +# Note that it is not recommended to use this gateway implementation with a proxy currently, +# since the management of duplicate messages might be insufficient. + +# The old notation cli = ... is equivalent to nas = ... and kept for backward compatibility. + + +#################### +# Authentication # +# Authorization # +#################### + +# Enable the RADIUS/Diameter authentication/authorization gateway? +# auth_server_enable = 1; + +# The port on which the accounting server listens +# auth_server_port = 1812; + +# The IPv4 on which to bind the server, or "disable" if IPv4 must not be used. +# auth_server_ip4 = 0.0.0.0; + +# The IPv6 address to which the server is bound, or "disable" +# auth_server_ip6 = :: ; + + +################ +# Accounting # +################ + +# Enable the RADIUS/Diameter accounting gateway? +# acct_server_enable = 1; + +# The port on which the accounting server listens +# acct_server_port = 1813; + +# The IPv4 on which to bind the server, or "disable" if no IPv4 is wanted. +# acct_server_ip4 = 0.0.0.0; + +# The IPv6 address to which the server is bound, or "disable" +# acct_server_ip6 = :: ; diff --git a/plat/diameter/doc/app_redirect.conf.sample b/plat/diameter/doc/app_redirect.conf.sample new file mode 100644 index 0000000..3ef6eff --- /dev/null +++ b/plat/diameter/doc/app_redirect.conf.sample @@ -0,0 +1,97 @@ +# This file contains the configuration for the app_redirect extension of freeDiameter. +# +# This extension provides configurable Redirect messages. + +# Lines starting with a # are comments and ignored. +# Spaces and newlines are not meaningful, except inside quoted areas. + +######################################################################################### +# See Diameter RFC for a detailed explanation on Redirects semantics # +######################################################################################### + +## default_redirect_cache_time +# Specify the default value for Redirect-Max-Cache-Time. +# This value can be overwritten for each rule as specified below. +# If this value is not specified, the default is: +#default_redirect_cache_time = 86400; ## => 1 day + +# The remaining of this file contains a list of RULE elements. +# Each RULE consists in three parts: +# - a CRITERIA that specifies which messages the RULE applies to. +# - a REDIRECT_TYPE that specifies what type of redirect is to be sent, and its duration. +# - a TARGET_HOSTS list that specifies the host(s) to send the message to. +# +# The rules are matched in the order they appear in this file. Once a rule has matched, the +# remaining rules are not processed. +# +# The basic format of a rule is: +# REDIRECT_TYPE : CRITERIA to TARGET_HOSTS ; + +# These are a few examples. The definition of each term follows. +# +# 1) REALM_AND_APPLICATION : app=3 "Destination-Realm"="myrealm.net" to "aaas://acct1.myrealm.net" "aaas://acct2.myrealm.net"; +# will ask all peers sending a Base Accounting message for realm "myrealm.net" to send +# this message directly to either 'acct1.myrealm.net' or 'acct2.myrealm.net'. +# +# 2) ALL_SESSION 3600 : "Origin-AAA-Protocol"=1 "Destination-Realm"="myrealm.net" to "aaas://raddiam.myrealm.net"; +# Will ask any peer sending messages translated from RADIUS and targeted to this realm +# to address all the messages from the same session to 'raddiam.myrealm.net'. The +# redirect entry should be stored for 1 hour. +# +# 3) ALL_HOST : from.realm=[".*\.(fr|de|es)"] to "aaas://relay-EU.myrealm.net"; +# ALL_HOST : from.realm=[".*\.(cn|jp|vn)"] to "aaas://relay-ASIA.myrealm.net"; +# Redirect messages to different relays depending on where they come from. +# +# 4) ALL_HOST : to "aaas://newserv.myrealm.net"; +# This server was relocated, tell all peers to go directly to the new one. +# This rule should appear last because it matches all messages, so further rules will never be used. + + +# +# REDIRECT_TYPE +# + +# The redirect_type is one of the following (see Redirect-Host-Usage AVP definition in RFC for semantics): +# DONT_CACHE +# ALL_SESSION +# ALL_REALM +# REALM_AND_APPLICATION +# ALL_APPLICATION +# ALL_HOST +# ALL_USER + +# In addition, an integer can follow. If specified, it overwrites the default_redirect_cache_time +# value for this rule. The value is always specified in seconds. + +# +# CRITERIA +# + +# Each RULE can contain 0 or more criteria. +# If no criteria is specified, all messages are assumed to match (wildcard). +# If more than one criteria is specified, an "AND" relationship is assumed. +# If you need to specify "OR", just create separate rules. +# +# In the following definitions, "STR/REG" stands for: +# - a quoted string "some.peer" that will match exactly this string (case-insensitive), or +# - a bracket-quoted string ["some regex"] that will be interpreted as a POSIX extended regular expression (case-sensitive), and attempt to match the string. +# +# A criteria is one of the following: +# from.id="STR/REG" -> matches messages received from peer with this Diameter Identity. +# from.realm="STR/REG" -> matches messages received from peer with this Realm. +# app=U32_VALUE -> matches messages with this Diameter Application-Id value in its header. +# "AVP-name"=U32_VALUE -> matches messages that contain an avp "AVP-name" (replace with the realm name) with this value. +# "AVP-name"="STR/REG" -> matches messages that contain an avp "AVP-name" (replace with the realm name) with this . + +# +# TARGET_HOSTS +# + +# This is a simple list of DiameterURI that must be sent back. +# See the RFC for valid format of Diameter URI: +# "aaa://" FQDN [ port ] [ transport ] [ protocol ] +# "aaas://" FQDN [ port ] [ transport ] [ protocol ] + +###################################################################################### + + diff --git a/plat/diameter/doc/app_sip.conf.sample b/plat/diameter/doc/app_sip.conf.sample new file mode 100644 index 0000000..d502b11 --- /dev/null +++ b/plat/diameter/doc/app_sip.conf.sample @@ -0,0 +1,28 @@ + +# MODE Diameter-SIP server (DSSERVER) or Subscriber Locator (SL) +#You must have at least in your network a Diameter SIP server and a Subscriber Locator (on different nodes) +mode = DSSERVER; + + +# Administrator commands port (port should be provided with "-p" in remote line) +ppr_port=90; +rtr_port=91; + + +#******************# +#*****DATABASE*****# +#******************# +# DATASOURCE: MYSQL +datasource = MYSQL; + +#MYSQL connection details +mysql_login = "login"; +mysql_password = "password"; +mysql_database = "db"; +mysql_server = "server.fr"; + +#If value=0, default port for mysql will be set +mysql_port = 0; + +#Prefix for tables (default is "ds") +mysql_prefix = "ds"; diff --git a/plat/diameter/doc/app_sip.sql b/plat/diameter/doc/app_sip.sql new file mode 100644 index 0000000..4c4a541 --- /dev/null +++ b/plat/diameter/doc/app_sip.sql @@ -0,0 +1,117 @@ +--Can be used in phpMyAdmin + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; + +-- +-- DIAMETER SERVER DATABASE +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_data_types` +-- + +CREATE TABLE IF NOT EXISTS `ds_data_types` ( + `id_data_type` int(11) NOT NULL AUTO_INCREMENT, + `label_type` varchar(255) NOT NULL, + PRIMARY KEY (`id_data_type`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_networks` +-- + +CREATE TABLE IF NOT EXISTS `ds_networks` ( + `id_network` int(11) NOT NULL AUTO_INCREMENT, + `label_network` varchar(255) NOT NULL, + PRIMARY KEY (`id_network`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_sip_aor` +-- + +CREATE TABLE IF NOT EXISTS `ds_sip_aor` ( + `id_sip_aor` int(11) NOT NULL AUTO_INCREMENT, + `id_user` int(11) NOT NULL, + `sip_aor` varchar(255) NOT NULL, + `sip_server_uri` varchar(255) DEFAULT NULL, + `registered` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id_sip_aor`,`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_sip_services` +-- + +CREATE TABLE IF NOT EXISTS `ds_sip_services` ( + `id_service` int(11) NOT NULL AUTO_INCREMENT, + `label_service` varchar(255) NOT NULL, + PRIMARY KEY (`id_service`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_users` +-- + +CREATE TABLE IF NOT EXISTS `ds_users` ( + `id_user` int(11) NOT NULL AUTO_INCREMENT, + `username` varchar(50) NOT NULL, + `password` varchar(50) NOT NULL, + `SIP_Server_URI` varchar(255) DEFAULT NULL, + `temp_SIP_Server_URI` varchar(255) DEFAULT NULL, + `authentication_pending` tinyint(1) NOT NULL DEFAULT '0', + `registrated` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id_user`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_user_data` +-- + +CREATE TABLE IF NOT EXISTS `ds_user_data` ( + `id_user_data` int(11) NOT NULL AUTO_INCREMENT, + `id_sip_aor` int(11) NOT NULL, + `id_data_type` int(11) NOT NULL, + `data` longblob NOT NULL, + PRIMARY KEY (`id_user_data`,`id_sip_aor`,`id_data_type`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_user_networks` +-- + +CREATE TABLE IF NOT EXISTS `ds_user_networks` ( + `id_user_network` int(11) NOT NULL AUTO_INCREMENT, + `id_user` int(11) NOT NULL, + `id_network` int(11) NOT NULL, + PRIMARY KEY (`id_user_network`,`id_user`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_user_services` +-- + +CREATE TABLE IF NOT EXISTS `ds_user_services` ( + `id_user_service` int(11) NOT NULL AUTO_INCREMENT, + `id_user` int(11) NOT NULL, + `id_service` int(11) NOT NULL, + `compulsory` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id_user_service`,`id_user`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ; + diff --git a/plat/diameter/doc/app_sip_SL.sql b/plat/diameter/doc/app_sip_SL.sql new file mode 100644 index 0000000..d2aded8 --- /dev/null +++ b/plat/diameter/doc/app_sip_SL.sql @@ -0,0 +1,21 @@ + + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; + +-- +-- SUBSCRIBER LOCATOR DATABASE +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ds_sip_aor_map` +-- + +CREATE TABLE IF NOT EXISTS `ds_sip_aor_map` ( + `id_map` int(11) NOT NULL AUTO_INCREMENT, + `sip_aor` varchar(255) NOT NULL, + `diameter_uri` varchar(255) NOT NULL, + PRIMARY KEY (`id_map`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; + diff --git a/plat/diameter/doc/dbg_interactive.py.sample b/plat/diameter/doc/dbg_interactive.py.sample new file mode 100644 index 0000000..b5f0130 --- /dev/null +++ b/plat/diameter/doc/dbg_interactive.py.sample @@ -0,0 +1,783 @@ +# Example file for the dbg_interactive.fdx extension. +# +# This extension provides an interactive python interpreter console that allows +# interacting with freeDiameter framework. +# +# The adaptation layer between Python and C is provided by SWIG (http://swig.org). +# You may refer to SWIG documentation for more information on how the wrapper is generated and used. +# The name of the module wrapping freeDiameter framework is: _fDpy +# +# Similar to all freeDiameter extensions, an optional filename can be specified in the +# main freeDiameter.conf configuration file for the dbg_interactive.fdx extension. +# If such file is provided, it will be passed to the python interpreter as a python script +# to execute. Otherwise, the interpreter will be interactive. +# +# SWIG deals with structures as follow: +# Given the structure: +# struct foo { int a; } +# The following functions are available to python (their C equivalent processing is given in [ ]): +# s = new_foo() [ s = calloc(1, sizeof(struct foo)) ] +# foo_a_set(s, 2) [ s->a = 2 ] +# foo_a_get(s) [ returns s->a value ] +# delete_foo(s) [ free(s) ] +# +# In addition, thanks to the proxy (aka shadow) class, we can also do the more user-friendly: +# s = foo() +# s.a = 2 +# s.a +# del s +# + +# The remaining of this file gives some examples of how to use the python interpreter. +# Note that at the moment not 100% of the framework is usable. +# You may have to extend some classes or write some typemaps in the source code +# of the extension to do what you want. + + +############# Compilation-time constants (from freeDiameter-host.h) ############ + +# Display current version +print "%s %d.%d.%d" % (FD_PROJECT_NAME, FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, FD_PROJECT_VERSION_REV) + + +############# Debug ############ + +# Change the global debug level of the framework (cvar contains all global variables) +cvar.fd_g_debug_lvl = 1 + + +# Turn on debug for a specific function (if framework compiled with DEBUG support) +cvar.fd_debug_one_function = "gc_th_fct" + + +# Print messages to freeDiameter's debug facility +# Note: the python version does not support printf-like argument list. The formating should be done in python. +# See SWIG documentation about varargs functions for more information. +fd_log(FD_LOG_NOTICE, "3 + 4 = %d" % (7)) + + +# Display some framework state information +conf = fd_conf_dump(); +print conf; + +fd_peer_dump_list(0) +fd_servers_dump(0) +fd_ext_dump(0) + + +############# Global variables ############ + +# Display the local Diameter Identity: +print "Local Diameter Identity:", cvar.fd_g_config.cnf_diamid + +# Display realm, using the low-level functions (skip proxy classe definitions): +print "Realm:", _fDpy.fd_config_cnf_diamrlm_get(_fDpy.cvar.fd_g_config) + + + +############# Lists ############ + +# Note: we use different names from the C API here, for usability. +l1 = fd_list() # Will be our sentinel +l2 = fd_list() +l3 = fd_list() +l1.isempty() +l1.insert_next(l2) # l1 -> l2 +l1.isempty() +l1.insert_prev(l3) # l1 -> l2 -> l3 (circular list) +l1.dump() +l3.detach() # l1 -> l2 +l4=fd_list() +l5=fd_list() +l3.insert_next(l4) # l3 -> l4 +l3.insert_next(l5) # l3 -> l5 -> l4 +l1.concat(l3) # l1 -> l2 -> l5 -> l4 + +elements = l1.enum_as() # default: enumerates as fd_list. Warning: this a copy, changing the python list has no effect on the underlying fd_list. +for li in elements: + li.dump() + +del elements +del l2 +del l3 +del l4 +del l5 +l1.isempty() # The destructor has an implicit fd_list_unlink call +del l1 + + +############# Hash ############ + +hex(fd_os_hash("hello world")) # It accepts binary data + + +############# Dictionary ############ + +##### Create a dedicated dictionary for our tests +d = dictionary() +d.dump() + +# New vendor +v = dict_vendor_data() +v.vendor_id = 123 +v.vendor_name = "My test vendor" +my_vendor = d.new_obj(DICT_VENDOR, v) +del v +d.dump() +d.vendors_list() + +# Compact invocation also possible: +v2 = dict_vendor_data(124, "My test vendor 2") +del v2 + +# New application +a = dict_application_data() +a.application_id = 99 +a.application_name = "My test appl" +my_appl = d.new_obj(DICT_APPLICATION, a, my_vendor) +del a + +a2 = dict_application_data(99, "My test appl 2") +del a2 + +# New type (callbacks are not supported yet...) +t = dict_type_data() +t.type_base = AVP_TYPE_INTEGER32 +t.type_name = "My integer AVP" +my_type_int = d.new_obj(DICT_TYPE, t, my_appl) +t.type_base = AVP_TYPE_OCTETSTRING +t.type_name = "My binary buffer AVP" +my_type_os = d.new_obj(DICT_TYPE, t, my_appl) +del t + +t2 = dict_type_data(AVP_TYPE_UNSIGNED32, "u32 type") +del t2 + +# Constants +c = dict_enumval_data() +c.enum_name = "AVP_VALUE_TROIS" +c.enum_value.i32 = 3 +d.new_obj(DICT_ENUMVAL, c, my_type_int) + +c.enum_name = "A_BUFFER_CONSTANT" +c.enum_value.os = "This is a very long AVP value that we prefer to represent as a constant" +c.enum_value.os.dump() +d.new_obj(DICT_ENUMVAL, c, my_type_os) +del c + +c2 = dict_enumval_data("enum 23", 23) # The constructor only accepts unsigned32, for other values, set them afterwards +c3 = dict_enumval_data("enum other") +c3.os = "other value" +del c2 +del c3 + +# AVP +a = dict_avp_data() +a.avp_code = 234 +a.avp_name = "my integer avp" +a.avp_flag_mask = AVP_FLAG_MANDATORY +a.avp_basetype = AVP_TYPE_INTEGER32 +my_avp_int = d.new_obj(DICT_AVP, a, my_type_int) + +a.avp_vendor = 123 +a.avp_name = "my OS avp" +a.avp_flag_mask = AVP_FLAG_MANDATORY + AVP_FLAG_VENDOR +a.avp_flag_val = AVP_FLAG_VENDOR +a.avp_basetype = AVP_TYPE_OCTETSTRING +my_avp_os = d.new_obj(DICT_AVP, a, my_type_os) +del a + +a2 = dict_avp_data(235, "no vendor, not mandatory", AVP_TYPE_OCTETSTRING) +a3 = dict_avp_data(236, "vendor 12, not mandatory", AVP_TYPE_OCTETSTRING, 12) +a4 = dict_avp_data(237, "vendor 12, mandatory", AVP_TYPE_OCTETSTRING, 12, 1) +a5 = dict_avp_data(238, "no vendor, mandatory", AVP_TYPE_OCTETSTRING, 0, 1) +del a2 +del a3 +del a4 +del a5 + + +# Command +c = dict_cmd_data() +c.cmd_code = 345 +c.cmd_name = "My-Python-Request" +c.cmd_flag_mask = CMD_FLAG_REQUEST + CMD_FLAG_PROXIABLE +c.cmd_flag_val = CMD_FLAG_REQUEST + CMD_FLAG_PROXIABLE +my_req = d.new_obj(DICT_COMMAND, c, my_appl) +c.cmd_name = "My-Python-Answer" +c.cmd_flag_val = CMD_FLAG_PROXIABLE +my_ans = d.new_obj(DICT_COMMAND, c, my_appl) +del c + +c2 = dict_cmd_data(346, "Second-Request", 1) # Default created with PROXIABLE flag. +c3 = dict_cmd_data(346, "Second-Answer", 0) +del c2 +del c3 + +# Rule +r = dict_rule_data() +r.rule_avp = my_avp_int +r.rule_position = RULE_REQUIRED +r.rule_min = -1 +r.rule_max = -1 +d.new_obj(DICT_RULE, r, my_req) +d.new_obj(DICT_RULE, r, my_ans) +r.rule_avp = my_avp_os +d.new_obj(DICT_RULE, r, my_req) +d.new_obj(DICT_RULE, r, my_ans) +del r + +r2 = dict_rule_data(my_avp_int, RULE_REQUIRED) # min & max are optional parameters, default to -1 +r3 = dict_rule_data(my_avp_int, RULE_REQUIRED, 2, 3) # min is 2, max is 3 +r4 = dict_rule_data(my_avp_int, RULE_FIXED_HEAD) # The r4.rule_order = 1 by default, change afterwards if needed. +del r2 +del r3 +del r4 + +d.dump() +del d + +####### Now play with the "real" dictionary + +gdict = cvar.fd_g_config.cnf_dict + +appl = gdict.search ( DICT_APPLICATION, APPLICATION_BY_ID, 3 ) +appl.dump() +avp = gdict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Host") +avp.dump() +errcmd = gdict.error_cmd() + +v = avp.getval() +print v.avp_code +del v + +t = avp.gettype() +print t +del t + +dict = avp.getdict() +del dict + + +############# Sessions ############ + +# handler +def my_cleanup(state,sid): + print "Cleaning up python state for session:", sid + print "Received state:", state + del state + +hdl = session_handler(my_cleanup) +hdl.dump() +del hdl + +# Session +hdl = session_handler(my_cleanup) +s1 = session() +s1.getsid() +s2 = session("this.is.a.full.session.id") +r,s3,isnew = fd_sess_fromsid("this.is.a.full.session.id") # use this call if "isnew" is really needed... +s4 = session("host.id", "optional.part") +s4.settimeout(30) # the python wrapper takes a number of seconds as parameter for simplicity +s4.dump() + +# states +mystate = [ 34, "blah", [ 32, 12 ] ] +s1.store(hdl, mystate) +del mystate +gotstate = s1.retrieve(hdl) +print gotstate +del gotstate + + +############# Routing ############ + +rd = rt_data() + +rd.add("p1.testbed.aaa", "testbed.aaa") +rd.add("p2.testbed.aaa", "testbed.aaa") +rd.add("p3.testbed.aaa", "testbed.aaa") +rd.add("p4.testbed.aaa", "testbed.aaa") + +rd.remove("p2.testbed.aaa") + +rd.error("p3.testbed.aaa", "relay.testbed.aaa", 3002) + +list = rd.extract(-1) +for c in list.enum_as("struct rtd_candidate *"): + print "%s (%s): %s" % (c.diamid, c.realm, c.score) + +del rd + + +# A rt_fwd callback has the following prototype: +def my_rtfwd_cb(msg): + print "Forwarding the following message:" + msg.dump() + return [ 0, msg ] # return None instead of msg to stop forwarding. + +fwdhdl = fd_rt_fwd_hdl( my_rtfwd_cb, RT_FWD_REQ ) + + +# A rt_out cb has the following prototype: +def my_rtout_cb(msg, list): + print "Sending out the following message:" + msg.dump() + print "The possible candidates are:" + for c in list.enum_as("struct rtd_candidate *"): + print "%s (%s): %s" % (c.diamid, c.realm, c.score) + return 0 # returns an error code (standard errno values) + +outhdl = fd_rt_out_hdl( my_rtout_cb ) # a priority can be specified as 2nd parameter, default is 0. + + + + + +############# Messages, AVPs ############ + +## AVP + +# Create empty +blank_avp = avp() +del blank_avp + +# Create from dictionary definitions +oh = avp(cvar.fd_g_config.cnf_dict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Host")) # Octet String +vi = avp(cvar.fd_g_config.cnf_dict.search ( DICT_AVP, AVP_BY_NAME, "Vendor-Id")) # U32 +vsai = avp(cvar.fd_g_config.cnf_dict.search ( DICT_AVP, AVP_BY_NAME, "Vendor-Specific-Application-Id")) # Grouped + +# Set values +val = avp_value() +val.u32 = 123 +vi.setval(None) # this cleans a previous value (usually not needed) +vi.setval(val) +val.os = "my.origin.host" +oh.setval(val) +vsai.add_child(vi) # call as add_child(vi, 1) to add the new AVP at the beginning, default is at the end + +# It is possible to initialize the AVP with a blank value as follow: +blank_with_value = avp(None, AVPFL_SET_BLANK_VALUE) +# it enables this without doing the setval call: +blank_with_value.header().avp_value.u32 = 12 + + +## Messages + +# Create empt (as for avps, pass None or a dictionary object as 1st param, and flags as optional 2nd param)y +a_msg = msg() +a_msg.dump() +del a_msg + +# It is also possible to pass MSGFL_* flags in second parameter (ALLOC_ETEID is default) +msg_no_eid = msg(None, 0) +msg_no_eid.dump() +del msg_no_eid + +# Create from dictionary +dwr_dict = cvar.fd_g_config.cnf_dict.search ( DICT_COMMAND, CMD_BY_NAME, "Device-Watchdog-Request" ) +dwr = msg(dwr_dict) +dwr.dump() + +# Create msg from a binary buffer (then you should call parse_dict and parse_rules methods) +dwr2 = msg("\x01\x00\x00\x14\x80\x00\x01\x18\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xf0\x00\x01") + +# Create answer from request (optional parameters: dictionary to use, and flags): +dwr3 = msg(cvar.fd_g_config.cnf_dict.search ( DICT_COMMAND, CMD_BY_NAME, "Device-Watchdog-Request" )) +dwa3 = dwr3.create_answer() +dwr3cpy = dwa3.get_query() + + +## Other functions with AVPs & messages + +# Add the AVPs in the message +dwr.add_child(oh) +oh.add_next(vsai) # equivalent to add_child on the parent + +# Create a network byte buffer from the message +dwr.bufferize() + +# Get first child AVP (fast) +avp = dwr.first_child() + +# then: +avp = avp.get_next() # when last AVP, returns None + + +# Get all 1st level children (slower) -- warning, changes to the python list will not be reflected on the underlying message. read-only use. +dwr.children() +# example use: +for a in dwr.children(): + a.dump(0) # 0 means: dump only this object, do not walk the tree + + +# Search the first AVP of a given type +oh_dict = cvar.fd_g_config.cnf_dict.search( DICT_AVP, AVP_BY_NAME, "Origin-Host") +oh = dwr.search( oh_dict ) + +# After adding AVPs, the length in the message header is outdated, refresh as follow: +dwr.update_length() + +# Get dictionary model for a message or avp +dwr.model() +oh.model().dump() + +# Retrieve the header of messages & avp: +dwr_hdr = dwr.header() +dwr_hdr.msg_version +dwr_hdr.msg_hbhid + +oh_hdr = oh.header() +hex(oh_hdr.avp_flags) +oh_hdr.avp_vendor +oh_hdr.avp_value.os.as_str() + + +# Get or set the routing data +rd = rt_data() +dwr.set_rtd(rd) +rd = dwr.get_rtd() + +# Test if message is routable +dwr.is_routable() + +# Which peer the message was received from (when received from network) +dwr.source() + +# The session corresponding to this message (returns None when no Session-Id AVP is included) +dwr.get_session() + + +# Parse a buffer +buf = "\x01\x00\x00@\x80\x00\x01\x18\x00\x00\x00\x00\x00\x00\x00\x00N\x10\x00\x00\x00\x00\x01\x08@\x00\x00\x16my.origin.host\x00\x00\x00\x00\x01\x04@\x00\x00\x14\x00\x00\x01\n@\x00\x00\x0c\x00\x00\x00{" +mydwr = msg(buf) +# Resolve objects in the dictionary. Return value is None or a struct pei_error in case of problem. +mydwr.parse_dict() # if not using the fD global dict, pass it as parameter +err = mydwr.parse_rules() +err.pei_errcode + + +# Grouped AVPs are browsed with same methods as messages: +gavp = dwr.children()[1] +gavp.first_child().dump() +gavp.children() + + +# Send a message: +mydwr = msg(buf) +mydwr.send() + +# Optionally, a callback can be registered when a request is sent, with an optional object. +# This callback takes the answer message as parameter and should return None or a message. (cf. fd_msg_send) +def send_callback(msg, obj): + print "Received answer:" + msg.dump() + print "Associated data:" + obj + return None + +mydwr = msg(buf) +mydwr.send(send_callback, some_object) + +# Again optionally, a time limit can be specified in this case as follow: +mydwr.send(send_callback, some_object, 10) +# In that case, if no answer / error is received after 10 seconds (the value specified), +# the callback is called with the request as parameter. +# Testing for timeout case is done by using msg.is_request() +def send_callback(msg, obj): + if (msg.is_request()): + print "Request timed out without answer:" + else: + print "Received answer:" + msg.dump() + print "Associated data:" + obj + return None + + +# Set a result code in an answer message. +mydwr = msg(buf) +dwa = mydwr.create_answer() +dwa.rescode_set() # This adds the DIAMETER_SUCCESS result code +dwa.rescode_set("DIAMETER_LIMITED_SUCCESS" ) # This adds a different result code +dwa.rescode_set("DIAMETER_LIMITED_SUCCESS", "Something went not so well" ) # This adds a different result code + specified Error-Message +dwa.rescode_set("DIAMETER_INVALID_AVP", None, faulty_avp ) # This adds a Failed-AVP +dwa.rescode_set("DIAMETER_SUCCESS", None, None, 1 ) # This adds origin information (see fd_msg_rescode_set's type_id for more info) + +# Set the origin to local host +mydwr.add_origin() # adds Origin-Host & Origin-Realm +mydwr.add_origin(1) # adds Origin-State-Id in addition. + + +############# DISPATCH (aka. server application) ############ + +# As for sessions, only one dispatch handler can be registered in this extension at the moment. +# The callback for the handler has the following syntax: +def dispatch_cb_model(inmsg, inavp, insession): + print "Callback trigged on message: " + inmsg.dump() + # inavp is None or the AVP that trigged the callback, depending on how it was registered. + if inavp: + print "From the following AVP:" + inavp.dump() + else: + print "No AVP" + # Session is provided only if a Session-Id is in the message + if insession: + print "The session is: ", insession.getsid() + else: + print "No session" + # Now, for the return value. + # This callback must return 3 elements: + # - an integer which is interpreted as an error code (errno.h) + # - a message or None, depending on the next item + # - an enum disp_action value, with the same meaning as in C (see libfreeDiameter.h) + del inmsg + return [ 0, None, DISP_ACT_CONT ] + + +### Example use: rebuild the server-side of test_app.fdx in python + +# The following block defines the dictionary objects from the test_app.fdx application that we use on the remote peer +gdict = cvar.fd_g_config.cnf_dict +d_si = gdict.search ( DICT_AVP, AVP_BY_NAME, "Session-Id" ) +d_oh = gdict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Host" ) +d_or = gdict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Realm" ) +d_dh = gdict.search ( DICT_AVP, AVP_BY_NAME, "Destination-Host" ) +d_dr = gdict.search ( DICT_AVP, AVP_BY_NAME, "Destination-Realm" ) +d_rc = gdict.search ( DICT_AVP, AVP_BY_NAME, "Result-Code" ) +d_vnd = gdict.new_obj(DICT_VENDOR, dict_vendor_data(999999, "app_test_py vendor") ) +d_app = gdict.new_obj(DICT_APPLICATION, dict_application_data(0xffffff, "app_test_py appli"), d_vnd) +d_req = gdict.new_obj(DICT_COMMAND, dict_cmd_data(0xfffffe, "Test_py-Request", 1), d_app) +d_ans = gdict.new_obj(DICT_COMMAND, dict_cmd_data(0xfffffe, "Test_py-Answer", 0), d_app) +d_avp = gdict.new_obj(DICT_AVP, dict_avp_data(0xffffff, "app_test_py avp", AVP_TYPE_INTEGER32, 999999 )) +gdict.new_obj(DICT_RULE, dict_rule_data(d_si, RULE_FIXED_HEAD, 1, 1), d_req) +gdict.new_obj(DICT_RULE, dict_rule_data(d_si, RULE_FIXED_HEAD, 1, 1), d_ans) +gdict.new_obj(DICT_RULE, dict_rule_data(d_avp, RULE_REQUIRED, 1, 1), d_req) +gdict.new_obj(DICT_RULE, dict_rule_data(d_avp, RULE_REQUIRED, 1, 1), d_ans) +gdict.new_obj(DICT_RULE, dict_rule_data(d_oh, RULE_REQUIRED, 1, 1), d_req) +gdict.new_obj(DICT_RULE, dict_rule_data(d_oh, RULE_REQUIRED, 1, 1), d_ans) +gdict.new_obj(DICT_RULE, dict_rule_data(d_or, RULE_REQUIRED, 1, 1), d_req) +gdict.new_obj(DICT_RULE, dict_rule_data(d_or, RULE_REQUIRED, 1, 1), d_ans) +gdict.new_obj(DICT_RULE, dict_rule_data(d_dr, RULE_REQUIRED, 1, 1), d_req) +gdict.new_obj(DICT_RULE, dict_rule_data(d_dh, RULE_OPTIONAL, 0, 1), d_req) +gdict.new_obj(DICT_RULE, dict_rule_data(d_rc, RULE_REQUIRED, 1, 1), d_ans) + +# Now, create the Test_app server callback: +def test_app_cb(inmsg, inavp, insession): + tval = inmsg.search(d_avp).header().avp_value.u32 + print "Py ECHO Test message from '%s' with test value %x, replying..." % (inmsg.search(d_oh).header().avp_value.os.as_str(), tval) + answ = inmsg.create_answer() + answ.rescode_set() + answ.add_origin() + ta = avp(d_avp, AVPFL_SET_BLANK_VALUE) + ta.header().avp_value.u32 = tval + answ.add_child(ta) + return [ 0, answ, DISP_ACT_SEND ] + +# Register the callback for dispatch thread: +hdl = disp_hdl(test_app_cb, DISP_HOW_CC, disp_when(d_app, d_req)) # disp_when() takes 0 to 4 arguments as follow: (app=NULL, cmd=NULL, avp=NULL, val=NULL) + +# Don't forget to register the application in the daemon for CER/CEA capabilities. +fd_disp_app_support ( d_app, d_vnd, 1, 0 ) + + +### For the fun, the client part of the test_app: + +def receive_answer(ans, testval): + try: + tval = ans.search(d_avp).header().avp_value.u32 + except: + print "Error in receive_answer: no Test-AVP included" + tval = 0 + try: + print "Py RECV %x (expected: %x) Status: %d From: '%s'" % (tval, testval, ans.search(d_rc).header().avp_value.u32, ans.search(d_oh).header().avp_value.os.as_str()) + except: + print "Error in receive_answer: Result-Code or Origin-Host are missing" + del ans + return None + +import random + +def send_query(destrealm="localdomain"): + qry = msg(d_req) + sess = session() + tv = random.randint(1, 1<<32) + # Session-Id + a = avp(d_si, AVPFL_SET_BLANK_VALUE) + a.header().avp_value.os = sess.getsid() + qry.add_child(a) + # Destination-Realm + a = avp(d_dr, AVPFL_SET_BLANK_VALUE) + a.header().avp_value.os = destrealm + qry.add_child(a) + # Origin-Host, Origin-Realm + qry.add_origin() + # Test-AVP + a = avp(d_avp, AVPFL_SET_BLANK_VALUE) + a.header().avp_value.u32 = tv + qry.add_child(a) + print "Py SEND %x to '%s'" % (tv, destrealm) + qry.send(receive_answer, tv) + +send_query() + + +############# FIFO queues ############ + +myqueue = fifo() + +# enqueue any object +myqueue.post(3) +myqueue.post("blah") +myqueue.post( [ 3, 2 ] ) + +# Simple get (blocks when the queue is empty) +myqueue.get() + +# Try get: returns the next object, or None if the queue is empty +myqueue.tryget() + +# timed get: like get, but returns None after x seconds +myqueue.timedget(3) + +# Show the number of items in the queue +myqueue.length() + + +## Variants: +# All the previous calls are suitable to queue Python objects. +# In order to interact with objects queued / poped by C counterpart, +# a second parameter must be passed to specify the object type, +# as follow: +ev = fd_event() +ev.code = FDEV_DUMP_EXT +cvar.fd_g_config.cnf_main_ev.post(ev, "struct fd_event *") + +# Similarly, for *get, we can specify the structure that was queued: +myqueue.get("struct fd_event *") +myqueue.tryget("struct fd_event *") +myqueue.timedget(3, "struct fd_event *") + +del myqueue + + +############# HOOKS ############ + +def my_hook_cb(type, msg, peer, other, oldpmd): + print "callback type ", type, " called: ", msg, other, oldpmd + return "this is the new pmd" + +# Create a wrapped fd_hook_data_hdl: +datahdl = fd_hook_data_hdl() + +# Register the hook callback: +hdl = fd_hook_hdl(1 << HOOK_MESSAGE_SENT, my_hook_cb, datahdl) + + + + +############# PEERS ############ + +# Get the list of peers defined in the system +# (we are supposed to readlock fd_g_peers_rw before accessing this list) +cvar.fd_g_peers_rw.rdlock() +peers = cvar.fd_g_peers.enum_as("struct peer_hdr *") +cvar.fd_g_peers_rw.unlock() +for p in peers: + print "Peer:", p.info.pi_diamid + + +# Create a new peer +np = peer_info() +np.pi_diamid = "nas.localdomain" +np.config.pic_flags.pro4 = PI_P4_TCP + + +# Add this peer into the framework. +np.add() + +# It is possible to specify a callback for when the connection completes or fails with this peer. +# The prototype is as follow: +def add_cb(peer): + if peer: + if peer.runtime.pir_state == STATE_OPEN: + print "Connection to peer '%s' completed" % (peer.pi_diamid) + # can find more information in peer.runtime.* + else: + print "Connection to peer '%s' failed (state:%d)" % (peer.pi_diamid, peer.runtime.pir_state) + else: + print "The peer has been destroyed before it completed the connection." + +# Then add the peer like this: +np.add(add_cb) + + +# Search a peer by its diameter id (returns a peer_hdr object if found) -- similar to fd_peer_getbyid +p = peer_search("nas.domain.aaa") + + +## Validation callback (see fd_peer_validate_register documentation) + +# cb2 prototype: +def my_validate_cb2(pinfo): + print "Cb2 callback trigged for peer %s" % (pinfo.pi_diamid) + # Usually, this would be used only to check some TLS properties, + # which is not really possible yet through the python interpreter... + return 0 # return an error code if the peer is not validated + +# cb prototype: +def my_validate_cb(pinfo): + print "Validate callback trigged for peer %s" % (pinfo.pi_diamid) + # If the peer is not allowed to connect: + #return -1 + # If the peer is authorized: + #return 1 + # In addition, if IPsec is allowed, + #pinfo.config.pic_flags.sec = PI_SEC_NONE + # If no decision has been made: + #return 0 + # If the peer is temporarily authorized but a second callback must be called after TLS negociation: + return my_validate_cb2 + +# Register the callback, it will be called on new incoming connections. +peer_validate_register(my_validate_cb) + + + +############# ENDPOINTS ############ + +ep = fd_endpoint("129.168.168.192") + +# with port: +ep = fd_endpoint("129.168.168.192", 3868) + +# With different flags: +ep = fd_endpoint("129.168.168.192", 3868, EP_FL_PRIMARY) + +# Add IP information for the peer +np = peer_info() +ep.add_merge(np.pi_endpoints) +fd_ep_dump(0, np.pi_endpoints) + + + +############# POSIX functions wrappers ############ + +# The interface also provides wrappers around base POSIX +# synchronization functions: + +m = pthread_mutex_t() +m.lock() +m.unlock() + +c = pthread_cond_t() +c.signal() +c.broadcast() +c.wait(m) +c.timedwait(m, 5) # it takes a relative time + +r = pthread_rwlock_t() +r.rdlock() +r.unlock() +r.wrlock() diff --git a/plat/diameter/doc/dict_legacy_xml.conf.sample b/plat/diameter/doc/dict_legacy_xml.conf.sample new file mode 100644 index 0000000..5907523 --- /dev/null +++ b/plat/diameter/doc/dict_legacy_xml.conf.sample @@ -0,0 +1,15 @@ +# This file documents the configuration format for the dict_legacy_xml.fdx freeDiameter extension. +# In order to load this extension, please refer to main freeDiameter.conf manual. + +# This extension allows the use of Diameter dictionary files in XML format, +# as roughly specified in draft-frascone-xml-dictionary-00. +# (the actual format is the one from OpenDiameter latest version) +# Note that this format, although more widely used, is less efficient than the +# internal freeDiameter format. It is recommended when possible to use the later. + +# You may refer to the contrib/dict_legacy/README file for information on where to find such resources. + +# This file simply consists in a list of XML dictionary files that must be parsed. +# Example: +# "/etc/freeDiameter/dictionary.xml"; + diff --git a/plat/diameter/doc/eap_tls_plugin.diameap.conf.sample b/plat/diameter/doc/eap_tls_plugin.diameap.conf.sample new file mode 100644 index 0000000..4405812 --- /dev/null +++ b/plat/diameter/doc/eap_tls_plugin.diameap.conf.sample @@ -0,0 +1,13 @@ +#### a sample configuration file for EAP-TLS + +#Certificate and Private key files +#Cred = "" : ""; + +#CA file +#CA = ""; + +#CRL file +#CRL = ""; + +#Enable/disable checking certificate's CN +check_cert_cn_username = 1; diff --git a/plat/diameter/doc/echodrop.rgwx.conf.sample b/plat/diameter/doc/echodrop.rgwx.conf.sample new file mode 100644 index 0000000..9ea2e96 --- /dev/null +++ b/plat/diameter/doc/echodrop.rgwx.conf.sample @@ -0,0 +1,33 @@ +# Sample configuration file for the echodrop.rgwx plugin of RADIUS/Diameter translation agent. +# +# This plugin allows to easily specify the following handling of RADIUS attributes +# received in a RADIUS request: +# - ECHO: the attribute will be copied verbatim in the RADIUS answer. +# - DROP: the attribute is discarded. +# +# In both cases, the attribute is NOT translated in Diameter message. +# +# The format of this file is: +# CODE [ VENDOR [ TLV | EXT ] ]; +# Where: +# : is either DROP or ECHO. +# : is a (decimal) integer between 0 and 255, and designates the type of the attribute. +# +# The remaining of the line is optional, and should only be used +# with lines containing "CODE 26" (Vendor-Specific Attribute) +# : a Vendor value (32 bit), see RFC2865 section 5.26 for detail. +# +# : The attribute is interpreted as TLV (rfc3865, section 5.26) +# and we match only this "vendor type" value (8 bits). +# +# : NOTE: THIS OPTION IS NOT SUPPORTED PROPERLY YET!!!! +# The attribute is interpreted as extended attribute (draft-ietf-radext-extended-attributes-08) +# and we match only this "Ext-Type" value (16 bits). +# This option should only be used with "CODE 26 VENDOR 0". +# +# Note that the Proxy-State (code 33) attribute is handled directly as an ECHO parameter by the gateway core. + +# Examples: +# DROP code 18 ; # Reply-Message attribute, should not be included in requests +# DROP code 26 vendor 9 ; # Drop any Cisco-specific attribute +# ECHO code 26 vendor 0 ext 256 ; # Echo any extended attribute with the type 256. diff --git a/plat/diameter/doc/freediameter.conf.sample b/plat/diameter/doc/freediameter.conf.sample new file mode 100644 index 0000000..b9fe46d --- /dev/null +++ b/plat/diameter/doc/freediameter.conf.sample @@ -0,0 +1,252 @@ +# This is a sample configuration file for freeDiameter daemon. + +# Most of the options can be omitted, as they default to reasonable values. +# Only TLS-related options must be configured properly in usual setups. + +# It is possible to use "include" keyword to import additional files +# e.g.: include "/etc/freeDiameter.d/*.conf" +# This is exactly equivalent as copy & paste the content of the included file(s) +# where the "include" keyword is found. + + +############################################################## +## Peer identity and realm + +# The Diameter Identity of this daemon. +# This must be a valid FQDN that resolves to the local host. +# Default: hostname's FQDN +#Identity = "aaa.koganei.freediameter.net"; + +# The Diameter Realm of this daemon. +# Default: the domain part of Identity (after the first dot). +#Realm = "koganei.freediameter.net"; + +############################################################## +## Transport protocol configuration + +# The port this peer is listening on for incoming connections (TCP and SCTP). +# Default: 3868. Use 0 to disable. +#Port = 3868; + +# The port this peer is listening on for incoming TLS-protected connections (TCP and SCTP). +# See TLS_old_method for more information about TLS flavours. +# Note: we use TLS/SCTP instead of DTLS/SCTP at the moment. This will change in future version of freeDiameter. +# Default: 5868. Use 0 to disable. +#SecPort = 5868; + +# Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA exchange is completed +# on the unsecure connection. The alternative is RFC6733 mechanism, where TLS protects also the +# CER/CEA exchange on a dedicated secure port. +# This parameter only affects outgoing connections. +# The setting can be also defined per-peer (see Peers configuration section). +# Default: use RFC6733 method with separate port for TLS. +#TLS_old_method; + +# Disable use of TCP protocol (only listen and connect over SCTP) +# Default : TCP enabled +#No_TCP; + +# Disable use of SCTP protocol (only listen and connect over TCP) +# Default : SCTP enabled +#No_SCTP; +# This option is ignored if freeDiameter is compiled with DISABLE_SCTP option. + +# Prefer TCP instead of SCTP for establishing new connections. +# This setting may be overwritten per peer in peer configuration blocs. +# Default : SCTP is attempted first. +#Prefer_TCP; + +# Default number of streams per SCTP associations. +# This setting may be overwritten per peer basis. +# Default : 30 streams +#SCTP_streams = 30; + +############################################################## +## Endpoint configuration + +# Disable use of IP addresses (only IPv6) +# Default : IP enabled +#No_IP; + +# Disable use of IPv6 addresses (only IP) +# Default : IPv6 enabled +#No_IPv6; + +# Specify local addresses the server must bind to +# Default : listen on all addresses available. +#ListenOn = "202.249.37.5"; +#ListenOn = "2001:200:903:2::202:1"; +#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0"; + + +############################################################## +## Server configuration + +# How many Diameter peers are allowed to be connecting at the same time ? +# This parameter limits the number of incoming connections from the time +# the connection is accepted until the first CER is received. +# Default: 5 unidentified clients in paralel. +#ThreadsPerServer = 5; + +############################################################## +## TLS Configuration + +# TLS is managed by the GNUTLS library in the freeDiameter daemon. +# You may find more information about parameters and special behaviors +# in the relevant documentation. +# http://www.gnu.org/software/gnutls/manual/ + +# Credentials of the local peer +# The X509 certificate and private key file to use for the local peer. +# The files must contain PKCS-1 encoded RSA key, in PEM format. +# (These parameters are passed to gnutls_certificate_set_x509_key_file function) +# Default : NO DEFAULT +#TLS_Cred = "" , ""; +TLS_Cred = "/etc/ssl/certs/freeDiameter.pem", "/etc/ssl/private/freeDiameter.key"; + +# Certificate authority / trust anchors +# The file containing the list of trusted Certificate Authorities (PEM list) +# (This parameter is passed to gnutls_certificate_set_x509_trust_file function) +# The directive can appear several times to specify several files. +# Default : GNUTLS default behavior +#TLS_CA = ""; + +# Certificate Revocation List file +# The information about revoked certificates. +# The file contains a list of trusted CRLs in PEM format. They should have been verified before. +# (This parameter is passed to gnutls_certificate_set_x509_crl_file function) +# Note: openssl CRL format might have interoperability issue with GNUTLS format. +# Default : GNUTLS default behavior +#TLS_CRL = ""; + +# GNU TLS Priority string +# This string allows to configure the behavior of GNUTLS key exchanges +# algorithms. See gnutls_priority_init function documentation for information. +# You should also refer to the Diameter required TLS support here: +# http://tools.ietf.org/html/rfc6733#section-13.1 +# Default : "NORMAL" +# Example: TLS_Prio = "NONE:+VERS-TLS1.1:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL"; +#TLS_Prio = "NORMAL"; + +# Diffie-Hellman parameters size +# Set the number of bits for generated DH parameters +# Valid value should be 768, 1024, 2048, 3072 or 4096. +# (This parameter is passed to gnutls_dh_params_generate2 function, +# it usually should match RSA key size) +# Default : 1024 +#TLS_DH_Bits = 1024; + +# Alternatively, you can specify a file to load the PKCS#3 encoded +# DH parameters directly from. This accelerates the daemon start +# but is slightly less secure. If this file is provided, the +# TLS_DH_Bits parameters has no effect. +# Default : no default. +#TLS_DH_File = ""; + + +############################################################## +## Timers configuration + +# The Tc timer of this peer. +# It is the delay before a new attempt is made to reconnect a disconnected peer. +# The value is expressed in seconds. The recommended value is 30 seconds. +# Default: 30 +#TcTimer = 30; + +# The Tw timer of this peer. +# It is the delay before a watchdog message is sent, as described in RFC 3539. +# The value is expressed in seconds. The default value is 30 seconds. Value must +# be greater or equal to 6 seconds. See details in the RFC. +# Default: 30 +#TwTimer = 30; + +############################################################## +## Applications configuration + +# Disable the relaying of Diameter messages? +# For messages not handled locally, the default behavior is to forward the +# message to another peer if any is available, according to the routing +# algorithms. In addition the "0xffffff" application is advertised in CER/CEA +# exchanges. +# Default: Relaying is enabled. +#NoRelay; + +# Number of server threads that can handle incoming messages at the same time. +# Default: 4 +#AppServThreads = 4; + +# Other applications are configured by loaded extensions. + +############################################################## +## Extensions configuration + +# The freeDiameter framework merely provides support for +# Diameter Base Protocol. The specific application behaviors, +# as well as advanced functions, are provided +# by loadable extensions (plug-ins). +# These extensions may in addition receive the name of a +# configuration file, the format of which is extension-specific. +# +# Format: +#LoadExtension = "/path/to/extension" [ : "/optional/configuration/file" ] ; +# +# Examples: +#LoadExtension = "extensions/sample.fdx"; +#LoadExtension = "extensions/sample.fdx":"conf/sample.conf"; + +# Extensions are named as follow: +# dict_* for extensions that add content to the dictionary definitions. +# dbg_* for extensions useful only to retrieve more information on the framework execution. +# acl_* : Access control list, to control which peers are allowed to connect. +# rt_* : routing extensions that impact how messages are forwarded to other peers. +# app_* : applications, these extensions usually register callbacks to handle specific messages. +# test_* : dummy extensions that are useful only in testing environments. + + +# The dbg_msg_dump.fdx extension allows you to tweak the way freeDiameter displays some +# information about some events. This extension does not actually use a configuration file +# but receives directly a parameter in the string passed to the extension. Here are some examples: +## LoadExtension = "dbg_msg_dumps.fdx" : "0x1111"; # Removes all default hooks, very quiet even in case of errors. +## LoadExtension = "dbg_msg_dumps.fdx" : "0x2222"; # Display all events with few details. +## LoadExtension = "dbg_msg_dumps.fdx" : "0x0080"; # Dump complete information about sent and received messages. +# The four digits respectively control: connections, routing decisions, sent/received messages, errors. +# The values for each digit are: +# 0 - default - keep the default behavior +# 1 - quiet - remove any specific log +# 2 - compact - display only a summary of the information +# 4 - full - display the complete information on a single long line +# 8 - tree - display the complete information in an easier to read format spanning several lines. + + +############################################################## +## Peers configuration + +# The local server listens for incoming connections. By default, +# all unknown connecting peers are rejected. Extensions can override this behavior (e.g., acl_wl). +# +# In addition to incoming connections, the local peer can +# be configured to establish and maintain connections to some +# Diameter nodes and allow connections from these nodes. +# This is achieved with the ConnectPeer directive described below. +# +# Note that the configured Diameter Identity MUST match +# the information received inside CEA, or the connection will be aborted. +# +# Format: +#ConnectPeer = "diameterid" [ { parameter1; parameter2; ...} ] ; +# Parameters that can be specified in the peer's parameter list: +# No_TCP; No_SCTP; No_IP; No_IPv6; Prefer_TCP; TLS_old_method; +# No_TLS; # assume transparent security instead of TLS. DTLS is not supported yet (will change in future versions). +# Port = 5868; # The port to connect to +# TcTimer = 30; +# TwTimer = 30; +# ConnectTo = "202.249.37.5"; +# ConnectTo = "2001:200:903:2::202:1"; +# TLS_Prio = "NORMAL"; +# Realm = "realm.net"; # Reject the peer if it does not advertise this realm. +# Examples: +#ConnectPeer = "aaa.wide.ad.jp"; +#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; Port=3868; } ; + + +############################################################## diff --git a/plat/diameter/doc/rt_busypeers.conf.sample b/plat/diameter/doc/rt_busypeers.conf.sample new file mode 100644 index 0000000..6b23d71 --- /dev/null +++ b/plat/diameter/doc/rt_busypeers.conf.sample @@ -0,0 +1,47 @@ +# This file contains information for configuring the rt_busypeers extension. +# To find how to have freeDiameter load this extension, please refer to the freeDiameter documentation. +# +# The rt_busypeers extension has two purposes. +# - when the local peer receives an error DIAMETER_TOO_BUSY from a peer, +# this extension catchs this error and attempts to retransmit the query to another peer if it makes sense, i.e.: +# * the peer issuing the error is not the peer referenced in the Destination-Host AVP of the message, +# * we have a direct link with the peer that issued the error (see parameter RetryDistantPeers below) +# +# - When a request is forwarded by the local peer, start a timer and if the corresponding answer/error has +# not been received within RelayTimeout seconds, either send to another peer or return a DIAMETER_TOO_BUSY +# error, depending on the RetryMaxPeers parameter. +# +# This extension is mainly useful for Diameter agents, for Diameter clients it is recommended to +# implement this logic directly in the client application. + + +# Parameter: SkipTooBusyErrors +# If defined, this parameter disables the handling of Diameter Errors message with a Result-Code set to DIAMETER_TOO_BUSY in this extension. +# When this parameter is defined, the parameter RetryDistantPeer has no effect. +# Default: parameter is not defined. +#SkipTooBusyErrors; + + +# Parameter: RetryDistantPeers +# By default, the extension only retries to send messages if the peer that issued the DIAMETER_TOO_BUSY error is directly connected to +# the local peer (not through a Diameter agent). This avoids the situation where the message is sent to a different relay that will deliver +# to the same busy peer afterwards. If the parameter is defined, then the extension will also retry sending messages for errors generated in +# distant peers. This should increase the chance that the message is delivered, but also can increase the load of the network unnecessarily. +# Default: parameter is not defined. +#RetryDistantPeers; + + +# Parameter: RetryMaxPeers +# This parameter specifies the limit on the number of times a request can be re-sent to a different peer, before the local relay gives up and +# forwards the error to upstream. +# Default: 0, meaning all possible candidates are attempted before give up. +#RetryMaxPeers=0; + + +# Parameter: RelayTimeout +# If the value of this parameter is not 0, it specifies the number of milliseconds (1/1000 s) that the local relay waits for an answer to a +# forwarded request before considering the remote peer is busy and taking corrective action (similar as if that relay had returned TOO_BUSY status). +# Note: this parameter does not apply for requests issued locally. In that case, the extension issuing the request should directly specify the timeout. +# Default: 0, meaning that there is no timeout parameter. +#RelayTimeout=0; + diff --git a/plat/diameter/doc/rt_default.conf.sample b/plat/diameter/doc/rt_default.conf.sample new file mode 100644 index 0000000..0307f44 --- /dev/null +++ b/plat/diameter/doc/rt_default.conf.sample @@ -0,0 +1,91 @@ +# This file contains the configuration for the rt_default extension of freeDiameter. +# +# This extension provides configurable routing properties for freeDiameter. + +# Lines starting with a # are comments and ignored. + +############################################################################## +# The freeDiameter daemon will not allow forwarding a message to a peer that: +# - already forwarded the message (appear as Route-Record inside the message) +# - connection is not in STATE_OPEN state. +# We call here "eligible peer" a peer that is not screened out by one of these criteria. +# +# Even if a peer is specified as route for a message here, the daemon may +# choose to send a message to another peer, or return a UNABLE_TO_DELIVER error, if that peer is not eligible +# at the time where the message is to be forwarded. +# +# Note also that defining a peer here will not result in the daemon trying to establish +# a connection to this peer. For this purpose, the peer must be defined in the main +# configuration (ConnectPeer), or connection established through other means (e.g. dynamic peer +# discovery extension). +# +# The default forwarding behavior of freeDiameter is: +# - if the message contains a Destination-Host AVP, and the designated peer is an eligible candidate, send to this peer. +# - if a peer does not support the message application or Relay application, give it a penalty for this message +# (it means that unless overwritten by an extension, the message will not be sent to that peer) +# - if one of the eligible peer advertised a realm matching the message's Destination-Realm, send to this peer. +# +# The mechanism is as follow: +# - the daemon builds a list of eligible peers, then attributes a score to these peers (see enum fd_rt_out_score in freeDiameter.h) +# - any number of extensions can register a callback and modify the score +# - after all callbacks have been called, the message is sent to the peer with the higher score. If an error is received, it is retried to the next peer in the list, and so on, +# until the list is empty. In such situation, an error UNABLE_TO_DELIVER is generated. +# +# This extension allows to modify the score of some peers based on some criteria of the message. +# +# Finally, please note that the freeDiameter daemon does not support REDIRECT indications natively. +# You have to load the rt_redir extension to add this support. +############################################################################## + +# This file contains a list of RULE elements. +# Each RULE is made of three components: +# - a CRITERIA, which specifies which messages the RULE apply to. +# - a TARGET string, that specifies which peer(s) in the eligible list the rule is applied to +# - and a SCORE, that is added to the matching peer's current score. +# +# In the following definitions, "STR/REG" stands for: +# - a quoted string "some.peer" that will match exactly this string (case-insensitive), or +# - a bracket-quoted string ["some regex"] that will be interpreted as a POSIX extended regular expression (case-sensitive), and attempt to match the string. +# +# The RULE is specified as: +# CRITERIA : TARGET += SCORE ; +# +# The CRITERIA can be: +# * -> matches any message. +# oh="STR/REG" -> selects the message if the string or regular expression matches the message's Origin-Host AVP content +# or="STR/REG" -> idem with Origin-Realm +# dh="STR/REG" -> idem with Destination-Host +# dr="STR/REG" -> idem with Destination-Realm +# un="STR/REG" -> idem with User-Name +# si="STR/REG" -> idem with Session-Id +# +# The TARGET is also of a similar form: +# "STR/REG" -> Will apply the score to this peer if its Diameter-Id is matched by the string or regular expression. +# rlm="STR/REG" -> Idem with the peer's advertized Diameter-Realm. +# +# The SCORE is either numeric (positive or negative), or one of the following constants (see values in libfdcore.h): +# NO_DELIVERY +# DEFAULT +# DEFAULT_REALM +# REALM +# REDIR_HOST +# REDIR_APP +# REDIR_REALM +# REDIR_REALM_APP +# REDIR_USER +# REDIR_SESSION +# FINALDEST +# +# +# Here are some examples: +# 1) Rule to add a default next-hop peer to all messages: +# * : "proxy.testbed.aaa" += DEFAULT ; +# +# 2) Rule to route messages for a given realm (realmA) through another realm (realmB): +# dr="realmA" : rlm="realmB" += DEFAULT_REALM ; +# +# 3) Avoid sending messages with decorated NAI to the proxy A: +# un=[".+!.+@.+"] : "proxy.A" += NO_DELIVERY ; + + + diff --git a/plat/diameter/doc/rt_ereg.conf.sample b/plat/diameter/doc/rt_ereg.conf.sample new file mode 100644 index 0000000..c12ae1b --- /dev/null +++ b/plat/diameter/doc/rt_ereg.conf.sample @@ -0,0 +1,21 @@ +# This file contains information for configuring the rt_ereg extension. +# To find how to have freeDiameter load this extension, please refer to the freeDiameter documentation. +# +# The rt_ereg extension allows creation of routing rules based on AVP value matching regular expressions. + +# First, one must indicate which AVP should be used for matching. +# At the moment, only AVP with OCTETSTRING types are valid. +# AVP = "User-Name"; +# This parameter is mandatory. There is no default value. + +# Then a list of rules follow. A rule has this format: +# "pattern" : "server" += score ; +# Where: +# pattern is the quoted-string regex to match, +# server is the next hop in the routing list that will receive the +# score, which can be positive or negative. +# Example: +# "[[:digit:]]*" : "serverA.example.net" += -3 ; +# means that if the AVP value is only numeric, the ServerA will have its score decreased by 3 points. +# (reminder: the server with the peer with the highest score gets the message) +# Note that all rules are tested for each message that contain the AVP, not only the first match. diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.chain.crt b/plat/diameter/doc/single_host/CAGenerate/ca.chain.crt new file mode 100644 index 0000000..c8c06c4 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.chain.crt @@ -0,0 +1,87 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 17253258667433909647 (0xef6fe358aa53dd8f) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=com, DC=example, CN=Test Certifying CA + Validity + Not Before: Jun 18 16:54:51 2016 GMT + Not After : Jun 18 16:54:51 2017 GMT + Subject: DC=com, DC=example, CN=Test Certifying CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e9:29:6f:b7:08:85:18:17:c4:7a:4c:de:89:29: + 28:01:07:ef:60:c9:f5:71:b2:40:51:b2:c5:be:dc: + 41:9c:e1:0f:ba:62:9e:5a:d2:58:1f:7b:71:aa:c3: + e8:d7:b6:49:78:b8:1d:21:96:98:c6:8b:c3:95:47: + 45:58:c8:6c:e4:32:4c:53:a7:0f:97:e5:91:8b:66: + a8:a6:17:89:1b:f3:33:05:40:34:1c:8d:f3:66:0c: + 0c:a7:cb:98:01:35:78:5d:bd:8d:d7:ee:62:bd:78: + 9b:14:69:2f:03:fd:99:b3:45:9e:a6:11:cf:e7:6f: + 9d:a2:ea:34:59:c2:57:82:0b:70:5f:f2:1d:a2:de: + 36:90:34:2a:81:0b:14:f2:c2:42:c0:19:44:05:11: + d6:c4:e7:48:a6:64:1e:b5:87:ea:ce:d0:cc:1c:bb: + 37:71:30:a8:47:87:38:90:ae:4f:c6:3a:cb:32:a8: + 26:e4:01:cf:69:2c:e5:36:35:9c:52:15:08:ca:b9: + 2a:eb:d6:76:00:c2:6c:70:c4:10:23:12:43:9b:a9: + 31:6f:84:51:ef:1e:a7:e9:7d:20:3a:c6:34:f5:35: + 6c:36:b9:b6:e1:8c:2d:77:af:b1:d0:d0:e2:28:c7: + 93:f2:84:f5:8f:b1:5d:0d:05:e8:4a:5d:c7:b3:69: + a3:73 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + X509v3 Authority Key Identifier: + keyid:5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + DirName:/DC=com/DC=example/CN=Test Certifying CA + serial:EF:6F:E3:58:AA:53:DD:8F + + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + Netscape Comment: + Testing CA Certificate + Signature Algorithm: sha1WithRSAEncryption + 34:24:3a:34:f7:8d:58:de:dc:b5:34:6e:06:ea:53:77:c9:9a: + fe:7f:29:7f:3e:74:d1:f9:97:c4:7b:b5:0e:82:99:ac:89:03: + a6:48:9e:17:f9:6f:06:eb:c2:93:33:de:45:82:8a:2d:4b:1a: + 4b:3c:30:36:6f:a2:b9:f9:d0:24:97:65:5c:82:19:0c:83:5e: + ae:16:09:25:fa:83:5c:59:5c:18:83:8b:c8:e6:c2:77:c5:d0: + 1a:8c:95:6e:ba:18:a6:29:86:92:e7:8b:71:26:12:1b:1e:c7: + 3f:0a:de:28:95:0b:4e:02:2f:8f:56:83:f2:0d:0f:d0:54:f1: + 25:15:e8:3f:02:c1:2a:f7:cd:0a:07:51:85:c9:9a:3a:64:66: + 1e:25:4a:b0:ac:38:96:3e:db:36:04:e4:23:06:e5:93:f0:24: + db:ff:60:1d:ce:eb:a2:37:f1:86:9f:a7:d2:23:f7:c7:9e:72: + a8:20:87:2d:ca:37:7a:15:d7:d6:47:13:ce:58:0f:d8:6b:f3: + 34:2c:7d:42:01:bf:32:8d:65:62:af:e0:1f:6c:9f:04:07:6c: + 0d:f0:93:c3:67:f1:9a:73:a7:4f:82:8f:c8:05:7d:63:b3:48: + a0:e2:3b:2e:da:c7:cb:05:91:32:59:1a:54:94:22:7b:01:92: + 9a:c4:c2:e7 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIJAO9v41iqU92PMA0GCSqGSIb3DQEBBQUAMEsxEzARBgoJ +kiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMRswGQYDVQQD +ExJUZXN0IENlcnRpZnlpbmcgQ0EwHhcNMTYwNjE4MTY1NDUxWhcNMTcwNjE4MTY1 +NDUxWjBLMRMwEQYKCZImiZPyLGQBGRYDY29tMRcwFQYKCZImiZPyLGQBGRYHZXhh +bXBsZTEbMBkGA1UEAxMSVGVzdCBDZXJ0aWZ5aW5nIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA6SlvtwiFGBfEekzeiSkoAQfvYMn1cbJAUbLFvtxB +nOEPumKeWtJYH3txqsPo17ZJeLgdIZaYxovDlUdFWMhs5DJMU6cPl+WRi2aopheJ +G/MzBUA0HI3zZgwMp8uYATV4Xb2N1+5ivXibFGkvA/2Zs0WephHP52+douo0WcJX +ggtwX/Idot42kDQqgQsU8sJCwBlEBRHWxOdIpmQetYfqztDMHLs3cTCoR4c4kK5P +xjrLMqgm5AHPaSzlNjWcUhUIyrkq69Z2AMJscMQQIxJDm6kxb4RR7x6n6X0gOsY0 +9TVsNrm24Ywtd6+x0NDiKMeT8oT1j7FdDQXoSl3Hs2mjcwIDAQABo4HkMIHhMB0G +A1UdDgQWBBRbCQmMGChSXFs56QdiB1RDc4HxMzB7BgNVHSMEdDBygBRbCQmMGChS +XFs56QdiB1RDc4HxM6FPpE0wSzETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmS +JomT8ixkARkWB2V4YW1wbGUxGzAZBgNVBAMTElRlc3QgQ2VydGlmeWluZyBDQYIJ +AO9v41iqU92PMAsGA1UdDwQEAwIB/jAPBgNVHRMBAf8EBTADAQH/MCUGCWCGSAGG ++EIBDQQYFhZUZXN0aW5nIENBIENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAA4IB +AQA0JDo0941Y3ty1NG4G6lN3yZr+fyl/PnTR+ZfEe7UOgpmsiQOmSJ4X+W8G68KT +M95FgootSxpLPDA2b6K5+dAkl2VcghkMg16uFgkl+oNcWVwYg4vI5sJ3xdAajJVu +uhimKYaS54txJhIbHsc/Ct4olQtOAi+PVoPyDQ/QVPElFeg/AsEq980KB1GFyZo6 +ZGYeJUqwrDiWPts2BOQjBuWT8CTb/2AdzuuiN/GGn6fSI/fHnnKoIIctyjd6FdfW +RxPOWA/Ya/M0LH1CAb8yjWVir+AfbJ8EB2wN8JPDZ/Gac6dPgo/IBX1js0ig4jsu +2sfLBZEyWRpUlCJ7AZKaxMLn +-----END CERTIFICATE----- diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.crl b/plat/diameter/doc/single_host/CAGenerate/ca.crl new file mode 100644 index 0000000000000000000000000000000000000000..2166de6d3dee560e29d4aac97ca7d73423908692 GIT binary patch literal 404 zcmXqLVw_-5Wx&hEsnzDu_MMlJk(HIfz}ryRK#+}#bCO!;pr){yFEpmI-9HD!6 cxwbu7ZdSj8$zF#cUF*%^tI7WjH*#?S0EdgC761SM literal 0 HcmV?d00001 diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.crt b/plat/diameter/doc/single_host/CAGenerate/ca.crt new file mode 100644 index 0000000..c8c06c4 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.crt @@ -0,0 +1,87 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 17253258667433909647 (0xef6fe358aa53dd8f) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=com, DC=example, CN=Test Certifying CA + Validity + Not Before: Jun 18 16:54:51 2016 GMT + Not After : Jun 18 16:54:51 2017 GMT + Subject: DC=com, DC=example, CN=Test Certifying CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e9:29:6f:b7:08:85:18:17:c4:7a:4c:de:89:29: + 28:01:07:ef:60:c9:f5:71:b2:40:51:b2:c5:be:dc: + 41:9c:e1:0f:ba:62:9e:5a:d2:58:1f:7b:71:aa:c3: + e8:d7:b6:49:78:b8:1d:21:96:98:c6:8b:c3:95:47: + 45:58:c8:6c:e4:32:4c:53:a7:0f:97:e5:91:8b:66: + a8:a6:17:89:1b:f3:33:05:40:34:1c:8d:f3:66:0c: + 0c:a7:cb:98:01:35:78:5d:bd:8d:d7:ee:62:bd:78: + 9b:14:69:2f:03:fd:99:b3:45:9e:a6:11:cf:e7:6f: + 9d:a2:ea:34:59:c2:57:82:0b:70:5f:f2:1d:a2:de: + 36:90:34:2a:81:0b:14:f2:c2:42:c0:19:44:05:11: + d6:c4:e7:48:a6:64:1e:b5:87:ea:ce:d0:cc:1c:bb: + 37:71:30:a8:47:87:38:90:ae:4f:c6:3a:cb:32:a8: + 26:e4:01:cf:69:2c:e5:36:35:9c:52:15:08:ca:b9: + 2a:eb:d6:76:00:c2:6c:70:c4:10:23:12:43:9b:a9: + 31:6f:84:51:ef:1e:a7:e9:7d:20:3a:c6:34:f5:35: + 6c:36:b9:b6:e1:8c:2d:77:af:b1:d0:d0:e2:28:c7: + 93:f2:84:f5:8f:b1:5d:0d:05:e8:4a:5d:c7:b3:69: + a3:73 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + X509v3 Authority Key Identifier: + keyid:5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + DirName:/DC=com/DC=example/CN=Test Certifying CA + serial:EF:6F:E3:58:AA:53:DD:8F + + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + Netscape Comment: + Testing CA Certificate + Signature Algorithm: sha1WithRSAEncryption + 34:24:3a:34:f7:8d:58:de:dc:b5:34:6e:06:ea:53:77:c9:9a: + fe:7f:29:7f:3e:74:d1:f9:97:c4:7b:b5:0e:82:99:ac:89:03: + a6:48:9e:17:f9:6f:06:eb:c2:93:33:de:45:82:8a:2d:4b:1a: + 4b:3c:30:36:6f:a2:b9:f9:d0:24:97:65:5c:82:19:0c:83:5e: + ae:16:09:25:fa:83:5c:59:5c:18:83:8b:c8:e6:c2:77:c5:d0: + 1a:8c:95:6e:ba:18:a6:29:86:92:e7:8b:71:26:12:1b:1e:c7: + 3f:0a:de:28:95:0b:4e:02:2f:8f:56:83:f2:0d:0f:d0:54:f1: + 25:15:e8:3f:02:c1:2a:f7:cd:0a:07:51:85:c9:9a:3a:64:66: + 1e:25:4a:b0:ac:38:96:3e:db:36:04:e4:23:06:e5:93:f0:24: + db:ff:60:1d:ce:eb:a2:37:f1:86:9f:a7:d2:23:f7:c7:9e:72: + a8:20:87:2d:ca:37:7a:15:d7:d6:47:13:ce:58:0f:d8:6b:f3: + 34:2c:7d:42:01:bf:32:8d:65:62:af:e0:1f:6c:9f:04:07:6c: + 0d:f0:93:c3:67:f1:9a:73:a7:4f:82:8f:c8:05:7d:63:b3:48: + a0:e2:3b:2e:da:c7:cb:05:91:32:59:1a:54:94:22:7b:01:92: + 9a:c4:c2:e7 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIJAO9v41iqU92PMA0GCSqGSIb3DQEBBQUAMEsxEzARBgoJ +kiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMRswGQYDVQQD +ExJUZXN0IENlcnRpZnlpbmcgQ0EwHhcNMTYwNjE4MTY1NDUxWhcNMTcwNjE4MTY1 +NDUxWjBLMRMwEQYKCZImiZPyLGQBGRYDY29tMRcwFQYKCZImiZPyLGQBGRYHZXhh +bXBsZTEbMBkGA1UEAxMSVGVzdCBDZXJ0aWZ5aW5nIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA6SlvtwiFGBfEekzeiSkoAQfvYMn1cbJAUbLFvtxB +nOEPumKeWtJYH3txqsPo17ZJeLgdIZaYxovDlUdFWMhs5DJMU6cPl+WRi2aopheJ +G/MzBUA0HI3zZgwMp8uYATV4Xb2N1+5ivXibFGkvA/2Zs0WephHP52+douo0WcJX +ggtwX/Idot42kDQqgQsU8sJCwBlEBRHWxOdIpmQetYfqztDMHLs3cTCoR4c4kK5P +xjrLMqgm5AHPaSzlNjWcUhUIyrkq69Z2AMJscMQQIxJDm6kxb4RR7x6n6X0gOsY0 +9TVsNrm24Ywtd6+x0NDiKMeT8oT1j7FdDQXoSl3Hs2mjcwIDAQABo4HkMIHhMB0G +A1UdDgQWBBRbCQmMGChSXFs56QdiB1RDc4HxMzB7BgNVHSMEdDBygBRbCQmMGChS +XFs56QdiB1RDc4HxM6FPpE0wSzETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmS +JomT8ixkARkWB2V4YW1wbGUxGzAZBgNVBAMTElRlc3QgQ2VydGlmeWluZyBDQYIJ +AO9v41iqU92PMAsGA1UdDwQEAwIB/jAPBgNVHRMBAf8EBTADAQH/MCUGCWCGSAGG ++EIBDQQYFhZUZXN0aW5nIENBIENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAA4IB +AQA0JDo0941Y3ty1NG4G6lN3yZr+fyl/PnTR+ZfEe7UOgpmsiQOmSJ4X+W8G68KT +M95FgootSxpLPDA2b6K5+dAkl2VcghkMg16uFgkl+oNcWVwYg4vI5sJ3xdAajJVu +uhimKYaS54txJhIbHsc/Ct4olQtOAi+PVoPyDQ/QVPElFeg/AsEq980KB1GFyZo6 +ZGYeJUqwrDiWPts2BOQjBuWT8CTb/2AdzuuiN/GGn6fSI/fHnnKoIIctyjd6FdfW +RxPOWA/Ya/M0LH1CAb8yjWVir+AfbJ8EB2wN8JPDZ/Gac6dPgo/IBX1js0ig4jsu +2sfLBZEyWRpUlCJ7AZKaxMLn +-----END CERTIFICATE----- diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.csr b/plat/diameter/doc/single_host/CAGenerate/ca.csr new file mode 100644 index 0000000..8e26fa4 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICkDCCAXgCAQAwSzETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmSJomT8ixk +ARkWB2V4YW1wbGUxGzAZBgNVBAMTElRlc3QgQ2VydGlmeWluZyBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOkpb7cIhRgXxHpM3okpKAEH72DJ9XGy +QFGyxb7cQZzhD7pinlrSWB97carD6Ne2SXi4HSGWmMaLw5VHRVjIbOQyTFOnD5fl +kYtmqKYXiRvzMwVANByN82YMDKfLmAE1eF29jdfuYr14mxRpLwP9mbNFnqYRz+dv +naLqNFnCV4ILcF/yHaLeNpA0KoELFPLCQsAZRAUR1sTnSKZkHrWH6s7QzBy7N3Ew +qEeHOJCuT8Y6yzKoJuQBz2ks5TY1nFIVCMq5KuvWdgDCbHDEECMSQ5upMW+EUe8e +p+l9IDrGNPU1bDa5tuGMLXevsdDQ4ijHk/KE9Y+xXQ0F6Epdx7Npo3MCAwEAAaAA +MA0GCSqGSIb3DQEBBQUAA4IBAQCvHeXfLukUAajL7H52zH8cSbojf+r/Y3z1Gc6R +sZ+tVTI/FVskjvhQ/tyHxktXVU8A5iXHD1aOE78dfNM9OTv9ys0k0/rD6lSAdWfE +L9HgWll4hYm9a1DKEqPOuEIkj/p1sQkNgZUmUWyELvyp4safgD+h2ugmPBzis/hF +je3q29+lhTe38GG91mGxhnHTJcsLF0Te0y4yv1JScryZ7uqnzjyrLxiJLRYGc2di +7db1WmjtxDQUxclLkt6BBhVIi87K04S1hglY8mxlLiVdF0tEY4a/a1hLGs1Q4U8Z +2BtSYR+OYLHNnCU5iDlaI5Z207f0ErTpYWw/PlgCF0G7dMLa +-----END CERTIFICATE REQUEST----- diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.db b/plat/diameter/doc/single_host/CAGenerate/ca.db new file mode 100644 index 0000000..a8ceee5 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.db @@ -0,0 +1,2 @@ +V 170618165451Z 00 unknown /DC=com/DC=example/CN=OCSP Signer for Test Certifying CA +V 170618165451Z 01 unknown /DC=com/DC=example/mail=root@example.com/CN=localhost diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.db.attr b/plat/diameter/doc/single_host/CAGenerate/ca.db.attr new file mode 100644 index 0000000..afc5de7 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.db.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.db.attr.old b/plat/diameter/doc/single_host/CAGenerate/ca.db.attr.old new file mode 100644 index 0000000..afc5de7 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.db.attr.old @@ -0,0 +1 @@ +unique_subject = yes diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.db.old b/plat/diameter/doc/single_host/CAGenerate/ca.db.old new file mode 100644 index 0000000..c1b03a4 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.db.old @@ -0,0 +1 @@ +V 170618165451Z 00 unknown /DC=com/DC=example/CN=OCSP Signer for Test Certifying CA diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.srl b/plat/diameter/doc/single_host/CAGenerate/ca.srl new file mode 100644 index 0000000..61586c1 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.srl @@ -0,0 +1 @@ +02 diff --git a/plat/diameter/doc/single_host/CAGenerate/ca.srl.old b/plat/diameter/doc/single_host/CAGenerate/ca.srl.old new file mode 100644 index 0000000..85ebd3a --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ca.srl.old @@ -0,0 +1 @@ +01 diff --git a/plat/diameter/doc/single_host/CAGenerate/fdTestExt b/plat/diameter/doc/single_host/CAGenerate/fdTestExt new file mode 100644 index 0000000000000000000000000000000000000000..72aea67fb4265e4a80d04deb5ebd392c08252120 GIT binary patch literal 1984180 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%0A=ssfI(Qv|oqYr$vRt$m1{Ta1z{=F3Ats4qG??j2 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
RhR|uaFC~MSmU5xG2|kI0k#4ff;hh1TeM4Re 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

_r~6t;XrA@$q{9SO7Se?b*NuK^bB{iOZ_he_*~x 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%0DyIv{M@mwJ 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 J<` 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%0A;25PYPSjfuS+l~d7X?)0gBB>L%86TH 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

7Zr=^iheQg&u=|t-4zE)GWlft#a6MD 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%0Du4?Q24vhZbQqXPjlD19G7Rq^> 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 literal 0 HcmV?d00001 diff --git a/plat/diameter/doc/single_host/CAGenerate/freeDiameter-1.conf b/plat/diameter/doc/single_host/CAGenerate/freeDiameter-1.conf new file mode 100644 index 0000000..53d5169 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/freeDiameter-1.conf @@ -0,0 +1,16 @@ + +# -------- Test configuration --------- + +Identity = "peer1.localdomain"; +Realm = "localdomain"; +# Port = 3868; +# SecPort = 3869; + +TLS_Cred = "./ca.crt", + "./ca.key"; +TLS_CA = "./ca.pem"; + +#LoadExtension = "extensions/test_app.fdx" : "test_app1.conf"; + +ConnectPeer = "peer2.localdomain" { ConnectTo = "127.0.0.1"; No_TLS; port = 30868; }; + diff --git a/plat/diameter/doc/single_host/CAGenerate/localhost.crt b/plat/diameter/doc/single_host/CAGenerate/localhost.crt new file mode 100644 index 0000000..54630fe --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/localhost.crt @@ -0,0 +1,152 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=com, DC=example, CN=Test Certifying CA + Validity + Not Before: Jun 18 16:54:51 2016 GMT + Not After : Jun 18 16:54:51 2017 GMT + Subject: DC=com, DC=example/mail=root@example.com, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b7:cf:a3:84:a5:55:ae:d8:6f:a6:e9:4f:33:2c: + b1:b6:5f:b2:b2:ac:e8:dc:ee:94:ba:55:15:ff:06: + 63:1b:48:c4:24:c1:d0:44:86:1b:52:a4:75:25:97: + 67:30:e2:6e:6f:13:f9:6c:ac:58:d7:55:1c:71:48: + 12:d6:06:1f:b5:1e:98:10:2a:73:74:19:5b:a0:22: + 9f:28:96:06:b1:e0:8a:40:ee:2d:2a:ab:01:2a:8d: + d7:96:c6:1f:a3:d4:2c:af:fb:31:f4:a3:26:c8:39: + d6:ee:fa:1f:06:b4:35:82:6e:5e:de:79:89:38:c9: + 02:7f:a9:56:cb:be:24:fd:c2:d5:6a:86:6b:d9:4e: + 90:08:01:e1:32:80:dc:2d:ae:40:9e:da:ad:ba:69: + ea:31:e2:94:f1:1b:41:07:f1:fa:a8:a6:6e:b9:03: + 1f:1a:3e:64:18:4f:20:79:0f:49:de:df:f9:5a:b2: + 52:ad:72:9b:29:39:13:f1:0f:5f:cd:e2:a1:ef:54: + 1d:2b:63:d0:09:f1:08:c3:a8:0e:e1:46:be:29:d9: + 7e:93:06:da:98:4f:f6:49:f4:31:9d:2c:29:35:36: + 51:65:98:84:b7:87:03:ea:ba:61:94:ba:f3:00:17: + 43:10:9d:18:c6:58:7f:73:ff:6b:36:7c:ed:f4:66: + ef:15 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + + X509v3 Subject Key Identifier: + B8:31:DB:64:96:F7:F9:88:99:4B:A3:D3:D9:98:2F:06:AF:AB:84:A7 + X509v3 Authority Key Identifier: + keyid:5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + DirName:/DC=com/DC=example/CN=Test Certifying CA + serial:EF:6F:E3:58:AA:53:DD:8F + + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + Testing Certificate for localhost + Signature Algorithm: sha1WithRSAEncryption + 24:a1:20:db:9b:c2:87:81:84:64:d7:ce:de:81:29:63:63:19: + 2b:b9:21:4f:c1:82:79:02:fa:c4:b4:2e:5e:2c:cb:a4:86:f6: + 4f:02:f9:cb:a5:bb:ad:00:58:fd:4a:0a:45:19:74:5e:d5:80: + 18:fd:96:0a:05:22:33:ae:8b:65:41:47:07:3a:5f:5b:ab:c1: + 8d:92:1d:22:b1:74:8a:d6:db:81:c8:8c:d1:d3:d3:52:36:ec: + a3:e4:64:c1:23:7c:0a:9c:36:ec:e4:cf:a2:f5:9b:1b:39:a4: + 94:0f:12:18:0a:f4:91:a1:71:89:13:c1:86:24:b5:46:d1:c9: + de:8e:bc:c3:a9:90:c4:99:d3:99:36:de:47:10:89:b9:c7:e8: + d4:2b:a4:65:3a:a9:9d:ea:d0:16:08:20:0c:c0:ec:b5:b1:2d: + 17:9e:45:32:ee:91:ee:9e:6f:59:03:2c:8f:dd:36:6d:d3:29: + d0:4b:b0:f4:d5:76:dd:92:1b:89:d7:5b:e6:bb:90:61:0b:5f: + 55:84:f3:1c:cc:61:01:e5:3f:5c:08:0d:a5:41:51:00:6e:a8: + e6:9b:f1:76:bd:f8:96:62:22:42:37:db:3e:29:a7:2c:70:2b: + 22:82:60:b8:9c:83:83:3c:d9:02:c7:0d:9f:b4:a6:a1:8f:81: + 76:41:48:53 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=com, DC=example, CN=Test Certifying CA + Validity + Not Before: Jun 18 16:54:51 2016 GMT + Not After : Jun 18 16:54:51 2017 GMT + Subject: DC=com, DC=example/mail=root@example.com, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b7:cf:a3:84:a5:55:ae:d8:6f:a6:e9:4f:33:2c: + b1:b6:5f:b2:b2:ac:e8:dc:ee:94:ba:55:15:ff:06: + 63:1b:48:c4:24:c1:d0:44:86:1b:52:a4:75:25:97: + 67:30:e2:6e:6f:13:f9:6c:ac:58:d7:55:1c:71:48: + 12:d6:06:1f:b5:1e:98:10:2a:73:74:19:5b:a0:22: + 9f:28:96:06:b1:e0:8a:40:ee:2d:2a:ab:01:2a:8d: + d7:96:c6:1f:a3:d4:2c:af:fb:31:f4:a3:26:c8:39: + d6:ee:fa:1f:06:b4:35:82:6e:5e:de:79:89:38:c9: + 02:7f:a9:56:cb:be:24:fd:c2:d5:6a:86:6b:d9:4e: + 90:08:01:e1:32:80:dc:2d:ae:40:9e:da:ad:ba:69: + ea:31:e2:94:f1:1b:41:07:f1:fa:a8:a6:6e:b9:03: + 1f:1a:3e:64:18:4f:20:79:0f:49:de:df:f9:5a:b2: + 52:ad:72:9b:29:39:13:f1:0f:5f:cd:e2:a1:ef:54: + 1d:2b:63:d0:09:f1:08:c3:a8:0e:e1:46:be:29:d9: + 7e:93:06:da:98:4f:f6:49:f4:31:9d:2c:29:35:36: + 51:65:98:84:b7:87:03:ea:ba:61:94:ba:f3:00:17: + 43:10:9d:18:c6:58:7f:73:ff:6b:36:7c:ed:f4:66: + ef:15 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + + X509v3 Subject Key Identifier: + B8:31:DB:64:96:F7:F9:88:99:4B:A3:D3:D9:98:2F:06:AF:AB:84:A7 + X509v3 Authority Key Identifier: + keyid:5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + DirName:/DC=com/DC=example/CN=Test Certifying CA + serial:EF:6F:E3:58:AA:53:DD:8F + + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + Testing Certificate for localhost + Signature Algorithm: sha1WithRSAEncryption + 24:a1:20:db:9b:c2:87:81:84:64:d7:ce:de:81:29:63:63:19: + 2b:b9:21:4f:c1:82:79:02:fa:c4:b4:2e:5e:2c:cb:a4:86:f6: + 4f:02:f9:cb:a5:bb:ad:00:58:fd:4a:0a:45:19:74:5e:d5:80: + 18:fd:96:0a:05:22:33:ae:8b:65:41:47:07:3a:5f:5b:ab:c1: + 8d:92:1d:22:b1:74:8a:d6:db:81:c8:8c:d1:d3:d3:52:36:ec: + a3:e4:64:c1:23:7c:0a:9c:36:ec:e4:cf:a2:f5:9b:1b:39:a4: + 94:0f:12:18:0a:f4:91:a1:71:89:13:c1:86:24:b5:46:d1:c9: + de:8e:bc:c3:a9:90:c4:99:d3:99:36:de:47:10:89:b9:c7:e8: + d4:2b:a4:65:3a:a9:9d:ea:d0:16:08:20:0c:c0:ec:b5:b1:2d: + 17:9e:45:32:ee:91:ee:9e:6f:59:03:2c:8f:dd:36:6d:d3:29: + d0:4b:b0:f4:d5:76:dd:92:1b:89:d7:5b:e6:bb:90:61:0b:5f: + 55:84:f3:1c:cc:61:01:e5:3f:5c:08:0d:a5:41:51:00:6e:a8: + e6:9b:f1:76:bd:f8:96:62:22:42:37:db:3e:29:a7:2c:70:2b: + 22:82:60:b8:9c:83:83:3c:d9:02:c7:0d:9f:b4:a6:a1:8f:81: + 76:41:48:53 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMRMwEQYKCZImiZPyLGQB +GRYDY29tMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTEbMBkGA1UEAxMSVGVzdCBD +ZXJ0aWZ5aW5nIENBMB4XDTE2MDYxODE2NTQ1MVoXDTE3MDYxODE2NTQ1MVowZDET +MBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxIDAe +BgoJkiaJk/IsZAEDFBByb290QGV4YW1wbGUuY29tMRIwEAYDVQQDEwlsb2NhbGhv +c3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3z6OEpVWu2G+m6U8z +LLG2X7KyrOjc7pS6VRX/BmMbSMQkwdBEhhtSpHUll2cw4m5vE/lsrFjXVRxxSBLW +Bh+1HpgQKnN0GVugIp8olgax4IpA7i0qqwEqjdeWxh+j1Cyv+zH0oybIOdbu+h8G +tDWCbl7eeYk4yQJ/qVbLviT9wtVqhmvZTpAIAeEygNwtrkCe2q26aeox4pTxG0EH +8fqopm65Ax8aPmQYTyB5D0ne3/laslKtcpspORPxD1/N4qHvVB0rY9AJ8QjDqA7h +Rr4p2X6TBtqYT/ZJ9DGdLCk1NlFlmIS3hwPqumGUuvMAF0MQnRjGWH9z/2s2fO30 +Zu8VAgMBAAGjge8wgewwEQYDVR0gBAowCDAGBgRVHSAAMB0GA1UdDgQWBBS4Mdtk +lvf5iJlLo9PZmC8Gr6uEpzB7BgNVHSMEdDBygBRbCQmMGChSXFs56QdiB1RDc4Hx +M6FPpE0wSzETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4 +YW1wbGUxGzAZBgNVBAMTElRlc3QgQ2VydGlmeWluZyBDQYIJAO9v41iqU92PMAkG +A1UdEwQCMAAwMAYJYIZIAYb4QgENBCMWIVRlc3RpbmcgQ2VydGlmaWNhdGUgZm9y +IGxvY2FsaG9zdDANBgkqhkiG9w0BAQUFAAOCAQEAJKEg25vCh4GEZNfO3oEpY2MZ +K7khT8GCeQL6xLQuXizLpIb2TwL5y6W7rQBY/UoKRRl0XtWAGP2WCgUiM66LZUFH +BzpfW6vBjZIdIrF0itbbgciM0dPTUjbso+RkwSN8Cpw27OTPovWbGzmklA8SGAr0 +kaFxiRPBhiS1RtHJ3o68w6mQxJnTmTbeRxCJucfo1CukZTqpnerQFgggDMDstbEt +F55FMu6R7p5vWQMsj902bdMp0Euw9NV23ZIbiddb5ruQYQtfVYTzHMxhAeU/XAgN +pUFRAG6o5pvxdr34lmIiQjfbPimnLHArIoJguJyDgzzZAscNn7SmoY+BdkFIUw== +-----END CERTIFICATE----- diff --git a/plat/diameter/doc/single_host/CAGenerate/localhost.csr b/plat/diameter/doc/single_host/CAGenerate/localhost.csr new file mode 100644 index 0000000..cd88764 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/localhost.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqTCCAZECAQAwZDETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmSJomT8ixk +ARkWB2V4YW1wbGUxIDAeBgoJkiaJk/IsZAEDFBByb290QGV4YW1wbGUuY29tMRIw +EAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC3z6OEpVWu2G+m6U8zLLG2X7KyrOjc7pS6VRX/BmMbSMQkwdBEhhtSpHUll2cw +4m5vE/lsrFjXVRxxSBLWBh+1HpgQKnN0GVugIp8olgax4IpA7i0qqwEqjdeWxh+j +1Cyv+zH0oybIOdbu+h8GtDWCbl7eeYk4yQJ/qVbLviT9wtVqhmvZTpAIAeEygNwt +rkCe2q26aeox4pTxG0EH8fqopm65Ax8aPmQYTyB5D0ne3/laslKtcpspORPxD1/N +4qHvVB0rY9AJ8QjDqA7hRr4p2X6TBtqYT/ZJ9DGdLCk1NlFlmIS3hwPqumGUuvMA +F0MQnRjGWH9z/2s2fO30Zu8VAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAQEACe/8 +eLWyhbHx6YZzliLGQsOZDqZrV+7rLCD7eYOt09DcxfHGqWuXYJfL6LCTAEkZtd2Z +BYWVxmqNqeWvqlZUq7EMsYsAtAnQEnGE7mBoY0dEMMiRuirYmOblt1y1k3paDAY7 +HBt3hGiCxwZq8hlUQDmyB19GyoAogyaneqCWyMObisBeyFEjoYssXD+0KKGcZ/kt +qKNK+8S/X2HBBB76chO0gJ3cTOpDVi5YjHOOk3Ovx4D2igN1C7xysecvXIrLVSj/ +9xSpzK0i1W5gWn1c6P5y4kxF/prmfwrJB8LyqP7x7VLqhlwDA6bkk17D4y/ogQM+ +0dIWUwwfxJdiEdjL4w== +-----END CERTIFICATE REQUEST----- diff --git a/plat/diameter/doc/single_host/CAGenerate/ocsp.crt b/plat/diameter/doc/single_host/CAGenerate/ocsp.crt new file mode 100644 index 0000000..6ce83e1 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ocsp.crt @@ -0,0 +1,159 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=com, DC=example, CN=Test Certifying CA + Validity + Not Before: Jun 18 16:54:51 2016 GMT + Not After : Jun 18 16:54:51 2017 GMT + Subject: DC=com, DC=example, CN=OCSP Signer for Test Certifying CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b3:36:dc:c6:0e:a5:f3:e1:2f:0e:9c:94:19:10: + 00:fb:40:2b:6f:d0:1c:c6:de:64:32:fd:ac:d0:45: + 55:38:d8:77:11:46:8f:22:1f:93:c3:e9:fd:64:c8: + 1d:8d:21:65:8e:83:ae:91:53:bc:b9:a3:4d:b2:0e: + ef:16:f8:52:9f:7b:69:dc:9c:73:cb:06:66:27:23: + 8d:6f:ba:11:e4:d6:0d:6f:25:9c:8e:d3:d8:1a:d5: + 2f:9d:00:06:b9:47:0c:24:00:87:e2:77:46:d0:6e: + 57:cd:f8:47:6e:50:cb:e7:71:d1:c5:50:bb:a5:2a: + 15:be:b4:cb:ea:d7:03:12:1b:d3:67:3c:76:12:df: + e0:01:0d:69:36:16:1b:93:99:db:c2:5d:68:a4:f3: + 1f:56:24:4d:0c:da:1f:e4:81:04:bd:2c:d2:ec:8b: + 05:ff:eb:fb:2c:f9:92:93:e0:99:11:fa:64:aa:6b: + 83:ce:34:20:59:4b:b2:fa:d7:f7:6a:cd:b1:9d:90: + 56:43:ae:f2:ab:2e:e3:66:84:15:f5:ad:aa:6e:ce: + c5:f5:3b:7b:bc:83:0c:7f:8f:f6:95:2c:b8:71:1a: + d3:34:39:07:2e:2c:76:1c:6a:01:f2:1b:dd:59:ab: + 8c:4b:c9:bf:a7:54:bf:d4:3a:9f:13:fe:3d:7f:77: + ce:89 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 30:46:BF:06:40:30:42:09:BE:75:D8:AC:C3:AC:7B:D3:4C:92:75:71 + X509v3 Authority Key Identifier: + keyid:5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + DirName:/DC=com/DC=example/CN=Test Certifying CA + serial:EF:6F:E3:58:AA:53:DD:8F + + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Certificate Sign, CRL Sign + X509v3 Basic Constraints: + CA:FALSE + X509v3 Extended Key Usage: + OCSP Signing + Netscape Comment: + Testing OCSP Certificate + OCSP No Check: + + Signature Algorithm: sha1WithRSAEncryption + e0:4d:17:4c:a4:ff:57:a1:db:d5:d2:77:7a:2d:70:51:8b:11: + 96:31:9f:fd:7e:d5:a7:a0:bb:d4:0d:ab:c2:5e:56:70:aa:84: + 47:f4:e9:28:51:c9:62:ca:3b:ad:5c:da:8c:60:37:72:d9:06: + 27:a1:60:cc:58:33:de:f1:85:3b:72:28:57:61:d6:8f:ce:46: + 84:53:bb:ad:61:2c:b8:c0:c0:db:88:9d:1c:a4:09:b8:8c:ca: + 49:d1:13:32:4b:b0:10:e9:65:b3:0b:68:30:65:e6:a0:6f:db: + 7c:ce:7b:52:c0:eb:7a:11:50:eb:2f:0e:2f:36:83:95:15:09: + 5f:f2:f8:2c:7d:a8:b2:c1:5e:f5:61:72:b7:a8:38:de:22:b7: + a7:1c:43:03:c5:d4:01:ef:f0:fd:4e:9c:28:c7:b2:29:89:23: + ff:c4:75:28:d2:c3:d8:e1:68:b1:08:9f:af:60:60:2a:ed:a0: + 96:b1:6c:f4:cc:61:bb:9d:af:5b:69:1f:3d:81:6c:ba:e2:e2: + d6:38:aa:77:6b:a6:3f:e0:8a:8d:55:6d:df:06:cb:5b:1d:53: + f7:96:4f:6f:98:8b:b3:0c:c3:2b:52:51:99:2d:09:fa:d0:a7: + d5:1f:be:8b:43:21:0c:60:e0:bc:e3:42:f1:8a:d3:85:d1:cb: + 02:58:5a:98 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=com, DC=example, CN=Test Certifying CA + Validity + Not Before: Jun 18 16:54:51 2016 GMT + Not After : Jun 18 16:54:51 2017 GMT + Subject: DC=com, DC=example, CN=OCSP Signer for Test Certifying CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b3:36:dc:c6:0e:a5:f3:e1:2f:0e:9c:94:19:10: + 00:fb:40:2b:6f:d0:1c:c6:de:64:32:fd:ac:d0:45: + 55:38:d8:77:11:46:8f:22:1f:93:c3:e9:fd:64:c8: + 1d:8d:21:65:8e:83:ae:91:53:bc:b9:a3:4d:b2:0e: + ef:16:f8:52:9f:7b:69:dc:9c:73:cb:06:66:27:23: + 8d:6f:ba:11:e4:d6:0d:6f:25:9c:8e:d3:d8:1a:d5: + 2f:9d:00:06:b9:47:0c:24:00:87:e2:77:46:d0:6e: + 57:cd:f8:47:6e:50:cb:e7:71:d1:c5:50:bb:a5:2a: + 15:be:b4:cb:ea:d7:03:12:1b:d3:67:3c:76:12:df: + e0:01:0d:69:36:16:1b:93:99:db:c2:5d:68:a4:f3: + 1f:56:24:4d:0c:da:1f:e4:81:04:bd:2c:d2:ec:8b: + 05:ff:eb:fb:2c:f9:92:93:e0:99:11:fa:64:aa:6b: + 83:ce:34:20:59:4b:b2:fa:d7:f7:6a:cd:b1:9d:90: + 56:43:ae:f2:ab:2e:e3:66:84:15:f5:ad:aa:6e:ce: + c5:f5:3b:7b:bc:83:0c:7f:8f:f6:95:2c:b8:71:1a: + d3:34:39:07:2e:2c:76:1c:6a:01:f2:1b:dd:59:ab: + 8c:4b:c9:bf:a7:54:bf:d4:3a:9f:13:fe:3d:7f:77: + ce:89 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 30:46:BF:06:40:30:42:09:BE:75:D8:AC:C3:AC:7B:D3:4C:92:75:71 + X509v3 Authority Key Identifier: + keyid:5B:09:09:8C:18:28:52:5C:5B:39:E9:07:62:07:54:43:73:81:F1:33 + DirName:/DC=com/DC=example/CN=Test Certifying CA + serial:EF:6F:E3:58:AA:53:DD:8F + + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Certificate Sign, CRL Sign + X509v3 Basic Constraints: + CA:FALSE + X509v3 Extended Key Usage: + OCSP Signing + Netscape Comment: + Testing OCSP Certificate + OCSP No Check: + + Signature Algorithm: sha1WithRSAEncryption + e0:4d:17:4c:a4:ff:57:a1:db:d5:d2:77:7a:2d:70:51:8b:11: + 96:31:9f:fd:7e:d5:a7:a0:bb:d4:0d:ab:c2:5e:56:70:aa:84: + 47:f4:e9:28:51:c9:62:ca:3b:ad:5c:da:8c:60:37:72:d9:06: + 27:a1:60:cc:58:33:de:f1:85:3b:72:28:57:61:d6:8f:ce:46: + 84:53:bb:ad:61:2c:b8:c0:c0:db:88:9d:1c:a4:09:b8:8c:ca: + 49:d1:13:32:4b:b0:10:e9:65:b3:0b:68:30:65:e6:a0:6f:db: + 7c:ce:7b:52:c0:eb:7a:11:50:eb:2f:0e:2f:36:83:95:15:09: + 5f:f2:f8:2c:7d:a8:b2:c1:5e:f5:61:72:b7:a8:38:de:22:b7: + a7:1c:43:03:c5:d4:01:ef:f0:fd:4e:9c:28:c7:b2:29:89:23: + ff:c4:75:28:d2:c3:d8:e1:68:b1:08:9f:af:60:60:2a:ed:a0: + 96:b1:6c:f4:cc:61:bb:9d:af:5b:69:1f:3d:81:6c:ba:e2:e2: + d6:38:aa:77:6b:a6:3f:e0:8a:8d:55:6d:df:06:cb:5b:1d:53: + f7:96:4f:6f:98:8b:b3:0c:c3:2b:52:51:99:2d:09:fa:d0:a7: + d5:1f:be:8b:43:21:0c:60:e0:bc:e3:42:f1:8a:d3:85:d1:cb: + 02:58:5a:98 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBLMRMwEQYKCZImiZPyLGQB +GRYDY29tMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTEbMBkGA1UEAxMSVGVzdCBD +ZXJ0aWZ5aW5nIENBMB4XDTE2MDYxODE2NTQ1MVoXDTE3MDYxODE2NTQ1MVowWzET +MBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxKzAp +BgNVBAMTIk9DU1AgU2lnbmVyIGZvciBUZXN0IENlcnRpZnlpbmcgQ0EwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzNtzGDqXz4S8OnJQZEAD7QCtv0BzG +3mQy/azQRVU42HcRRo8iH5PD6f1kyB2NIWWOg66RU7y5o02yDu8W+FKfe2ncnHPL +BmYnI41vuhHk1g1vJZyO09ga1S+dAAa5RwwkAIfid0bQblfN+EduUMvncdHFULul +KhW+tMvq1wMSG9NnPHYS3+ABDWk2FhuTmdvCXWik8x9WJE0M2h/kgQS9LNLsiwX/ +6/ss+ZKT4JkR+mSqa4PONCBZS7L61/dqzbGdkFZDrvKrLuNmhBX1rapuzsX1O3u8 +gwx/j/aVLLhxGtM0OQcuLHYcagHyG91Zq4xLyb+nVL/UOp8T/j1/d86JAgMBAAGj +ggEHMIIBAzAdBgNVHQ4EFgQUMEa/BkAwQgm+ddisw6x700ySdXEwewYDVR0jBHQw +coAUWwkJjBgoUlxbOekHYgdUQ3OB8TOhT6RNMEsxEzARBgoJkiaJk/IsZAEZFgNj +b20xFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMRswGQYDVQQDExJUZXN0IENlcnRp +ZnlpbmcgQ0GCCQDvb+NYqlPdjzALBgNVHQ8EBAMCAf4wCQYDVR0TBAIwADATBgNV +HSUEDDAKBggrBgEFBQcDCTAnBglghkgBhvhCAQ0EGhYYVGVzdGluZyBPQ1NQIENl +cnRpZmljYXRlMA8GCSsGAQUFBzABBQQCBQAwDQYJKoZIhvcNAQEFBQADggEBAOBN +F0yk/1eh29XSd3otcFGLEZYxn/1+1aegu9QNq8JeVnCqhEf06ShRyWLKO61c2oxg +N3LZBiehYMxYM97xhTtyKFdh1o/ORoRTu61hLLjAwNuInRykCbiMyknREzJLsBDp +ZbMLaDBl5qBv23zOe1LA63oRUOsvDi82g5UVCV/y+Cx9qLLBXvVhcreoON4it6cc +QwPF1AHv8P1OnCjHsimJI//EdSjSw9jhaLEIn69gYCrtoJaxbPTMYbudr1tpHz2B +bLri4tY4qndrpj/gio1Vbd8Gy1sdU/eWT2+Yi7MMwytSUZktCfrQp9UfvotDIQxg +4LzjQvGK04XRywJYWpg= +-----END CERTIFICATE----- diff --git a/plat/diameter/doc/single_host/CAGenerate/ocsp.csr b/plat/diameter/doc/single_host/CAGenerate/ocsp.csr new file mode 100644 index 0000000..86aefb3 --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ocsp.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICoDCCAYgCAQAwWzETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmSJomT8ixk +ARkWB2V4YW1wbGUxKzApBgNVBAMTIk9DU1AgU2lnbmVyIGZvciBUZXN0IENlcnRp +ZnlpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzNtzGDqXz +4S8OnJQZEAD7QCtv0BzG3mQy/azQRVU42HcRRo8iH5PD6f1kyB2NIWWOg66RU7y5 +o02yDu8W+FKfe2ncnHPLBmYnI41vuhHk1g1vJZyO09ga1S+dAAa5RwwkAIfid0bQ +blfN+EduUMvncdHFULulKhW+tMvq1wMSG9NnPHYS3+ABDWk2FhuTmdvCXWik8x9W +JE0M2h/kgQS9LNLsiwX/6/ss+ZKT4JkR+mSqa4PONCBZS7L61/dqzbGdkFZDrvKr +LuNmhBX1rapuzsX1O3u8gwx/j/aVLLhxGtM0OQcuLHYcagHyG91Zq4xLyb+nVL/U +Op8T/j1/d86JAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAQEArFHItPRlHAT2Bfgk +5eerQ0NJYRmo6Rz5R57rGjf92eZfH855KUy43tPdc+EFtp+RgBumpQi7RpeZyqmZ +wtwQIev66I+Ls9/hXE8+VxtBlFAl99gFyzj5kRdfkjb0uOxWN6MSfxPcNE4J7oWm +f8PBeIIcUCZEmFGvo1G2hoPyD2xUNYpMw0+XAPIsuqnqS/eY7SbYs+vByt9jPzTx +cOZ0jpXRfHrf2gsvcQSmO6MLRwKiF3P62BUMp+UcTRtpznxSpwl9GdQN5E0H4pQh +4HUYPmFRSkwFa8FkJGorMTcsR8U2/NiVGZnJgRz2ElSxLL4epBT7M/+MvURgH0Py +4/ab4Q== +-----END CERTIFICATE REQUEST----- diff --git a/plat/diameter/doc/single_host/CAGenerate/ssl_make_certs.sh b/plat/diameter/doc/single_host/CAGenerate/ssl_make_certs.sh new file mode 100644 index 0000000..1b3926f --- /dev/null +++ b/plat/diameter/doc/single_host/CAGenerate/ssl_make_certs.sh @@ -0,0 +1,545 @@ +#!/bin/bash -e +# +# Generate a root CA cert for signing, and then a subject cert. +# Usage: make-certs.sh hostname [user[@domain]] [more ...] +# For testing only, probably still has some bugs in it. +# + +DOMAIN=example.com +DAYS=365 +KEYTYPE=RSA +KEYSIZE=2048 +CURVE=prime256v1 +DIGEST=SHA1 +CRLHOURS=24 +CRLDAYS= + +# Cleanup temporary files at exit. +touch openssl.cnf +newcertdir=`mktemp -d` +cleanup() { + test -f openssl.cnf && rm -f openssl.cnf + test -f ca.txt && rm -f ca.txt + test -f ocsp.txt && rm -f ocsp.txt + test -n "$newcertdir" && rm -fr "$newcertdir" +} +trap cleanup EXIT + +# The first argument is either a common name value or a flag indicating that +# we're doing something other than issuing a cert. +commonname="$1" +refresh_crl=false +revoke_cert=false +ocsp_serve=false +if test "x$commonname" = "x-refresh-crl" ; then + refresh_crl=true + commonname="$1" +fi +if test "x$commonname" = "x-refresh_crl" ; then + refresh_crl=true + commonname="$1" +fi +if test "x$commonname" = "x-revoke" ; then + revoke_cert=true + shift + commonname="$1" +fi +if test "x$commonname" = "x-ocsp" ; then + ocsp_serve=true + commonname="$1" +fi +if test "x$commonname" = x ; then + echo Usage: `basename $0` 'commonname' user'[@domain]' '[more [...]]' + echo Usage: `basename $0` -revoke 'commonname' + echo Usage: `basename $0` -ocsp + echo Usage: `basename $0` -refresh-crl + echo More: + echo -e \\tKey type: "[RSA|DSA|EC]" + echo -e \\tElliptic curve: "[prime256v1|secp384r1|secp521r1]" + echo -e \\tKey usage: "[sign|signing|encrypt|encryption|agree|agreement|all]" + echo -e \\tAuthority Access Info OCSP responder: "ocsp:URI" + echo -e \\tCRL distribution point: "crl:URI" + echo -e \\tSubject Alternative Name: + echo -e \\t\\tHostname: "*" + echo -e \\t\\tIP address: w.x.y.z + echo -e \\t\\tEmail address: "*@*.com/edu/net/org/local" + echo -e \\t\\tKerberos principal name: "*@*.COM/EDU/NET/ORG/LOCAL" + echo -e \\tExtended key usage: + echo -e \\t\\t1.... + echo -e \\t\\t2.... + echo -e \\t\\tid-kp-server-auth \| tls-server + echo -e \\t\\tid-kp-client-auth \| tls-client + echo -e \\t\\tid-kp-email-protection \| email + echo -e \\t\\tid-ms-kp-sc-logon \| id-ms-sc-logon + echo -e \\t\\tid-pkinit-kp-client-auth \| id-pkinit-client + echo -e \\t\\tid-pkinit-kp-kdc \| id-pkinit-kdc + echo -e \\t\\tca \| CA + exit 1 +fi + +# Choose a user name part for email attributes. +GIVENUSER=$2 +test x"$GIVENUSER" = x && GIVENUSER=$USER +echo "$GIVENUSER" | grep -q @ || GIVENUSER="$GIVENUSER"@$DOMAIN +DOMAIN=`echo "$GIVENUSER" | cut -f2- -d@` + +shift || true +shift || true + +# Done already? +done=: + +keygen() { + case "$KEYTYPE" in + DSA) + openssl dsaparam $KEYSIZE -genkey + ;; + EC) + openssl ecparam -name $CURVE -noout -param_enc named_curve -genkey + ;; + RSA|*) + openssl genrsa $KEYSIZE -nodes + ;; + esac +} + +# Set some defaults. +CA=FALSE +if test -s ca.crldp.uri.txt ; then + crlval="`cat ca.crldp.uri.txt`" + crl="URI:$crlval" +fi +if test -s ca.ocsp.uri.txt ; then + aiaval="`cat ca.ocsp.uri.txt`" + aia="OCSP;URI:$aiaval" +fi +if test -s ca.domain.txt ; then + domval="`cat ca.domain.txt`" + if test -n "$domval" ; then + DOMAIN="$domval" + fi +fi + +# Parse the arguments which indicate what sort of information we want. +while test $# -gt 0 ; do + type= + value="$1" + case "$value" in + RSA|rsa) + KEYTYPE=RSA + ;; + DSA|dsa) + KEYTYPE=DSA + ;; + EC|ec) + KEYTYPE=EC + ;; + prime256v1|secp384r1|secp521r1) + CURVE=$1 + ;; + OCSP:*|ocsp:*) + aiaval=`echo "$value" | cut -f2- -d:` + aia="OCSP;URI:$aiaval" + ;; + CRL:*|crl:*) + crlval=`echo "$value" | cut -f2- -d:` + crl="URI:$crlval" + ;; + signing|sign) + keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature" + ;; + encryption|encrypt) + keyusage="${keyusage:+${keyusage},}keyEncipherment,dataEncipherment" + ;; + agreement|agree) + keyusage="${keyusage:+${keyusage},}keyAgreement" + ;; + all) + keyusage="digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly" + ;; + ca|CA) + CA=TRUE + keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign" + ;; + 1.*|2.*|id-*|tls-*|email|mail) + ekuval=`echo "$value" | tr '[A-Z]' '[a-z]' | sed 's,\-,,g'` + case "$ekuval" in + idkpserverauth|tlsserver) ekuval=1.3.6.1.5.5.7.3.1;; + idkpclientauth|tlsclient) ekuval=1.3.6.1.5.5.7.3.2;; + idkpemailprotection|email|mail) ekuval=1.3.6.1.5.5.7.3.4;; + idmskpsclogon|idmssclogon) ekuval=1.3.6.1.4.1.311.20.2.2;; + idpkinitkpclientauth|idpkinitclient) ekuval=1.3.6.1.5.2.3.4;; + idpkinitkpkdc|idpkinitkdc) ekuval=1.3.6.1.5.2.3.5;; + esac + if test -z "$eku" ; then + eku="$ekuval" + else + eku="$eku,$ekuval" + fi + ;; + *@*.COM|*@*.EDU|*@*.NET|*@*.ORG|*@*.LOCAL) + luser=`echo "$value" | tr '[A-Z]' '[a-z]'` + if test "$luser" = "$value" ; then + luser= + fi + type="otherName:1.3.6.1.5.2.2;SEQUENCE:$value,${luser:+otherName:1.3.6.1.4.1.311.20.2.3;UTF8:${luser},}otherName:1.3.6.1.4.1.311.20.2.3;UTF8" + unset luser + principals="$principals $value" + ;; + *@*.com|*@*.edu|*@*.net|*@*.org|*@*.local) type=email;; + [0-9]*.[0-9]*.[0-9]*.[0-9]*) type=IP;; + *) type=DNS;; + esac + if test -n "$type" ; then + newvalue="${type}:$value" + if test -z "$altnames" ; then + altnames="${newvalue}" + else + altnames="${altnames},${newvalue}" + fi + fi + shift +done + +# Build the configuration file, including bits on how to construct the CA +# certificate, an OCSP responder certificate, and the issued certificate. +cat > openssl.cnf <<- EOF +[ca] +default_ca = issuer + +[issuer] +private_key = `pwd`/ca.key +certificate = `pwd`/ca.crt +database = `pwd`/ca.db +serial = `pwd`/ca.srl +default_md = $DIGEST +new_certs_dir = $newcertdir +policy = no_policy + +[no_policy] + +[req_oids] +domainComponent = 0.9.2342.19200300.100.1.25 + +[req_ca] +prompt = no +oid_section = req_oids +distinguished_name = req_ca_name +default_md = $DIGEST + +[req_ca_name] +EOF +echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf +cat >> openssl.cnf <<- EOF +commonName = Test Certifying CA + +[v3_ca] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +keyUsage=nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign +basicConstraints=critical,CA:TRUE +nsComment="Testing CA Certificate" +EOF +if test -n "$aia" ; then + echo "authorityInfoAccess = ${aia}" >> openssl.cnf + echo -n "$aiaval" > ca.ocsp.uri.txt +fi +if test -n "$crl" ; then + echo "crlDistributionPoints = ${crl}" >> openssl.cnf + echo -n "$crlval" > ca.crldp.uri.txt +fi +echo "$DOMAIN" > ca.domain.txt +cat >> openssl.cnf <<- EOF + +[req_ocsp] +prompt = no +oid_section = req_oids +distinguished_name = req_ocsp_name +default_md = $DIGEST + +[req_ocsp_name] +EOF +echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf +cat >> openssl.cnf <<- EOF +commonName = OCSP Signer for Test Certifying CA + +[v3_ocsp] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign +basicConstraints=CA:FALSE +extendedKeyUsage=1.3.6.1.5.5.7.3.9 +nsComment="Testing OCSP Certificate" +1.3.6.1.5.5.7.48.1.5=ASN1:NULL +EOF +if test -n "$aia" ; then + echo "authorityInfoAccess = ${aia}" >> openssl.cnf +fi +if test -n "$crl" ; then + echo "crlDistributionPoints = ${crl}" >> openssl.cnf +fi +cat >> openssl.cnf <<- EOF + +[req_issued] +prompt = no +oid_section = req_oids +distinguished_name = req_issued_name +default_md = $DIGEST + +[req_issued_name] +EOF +echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf +cat >> openssl.cnf <<- EOF +mail = $GIVENUSER +commonName = $commonname + +[v3_issued] +certificatePolicies=2.5.29.32.0${eku:+,${eku}} +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +EOF +if test -n "$aia" ; then + echo "authorityInfoAccess = ${aia}" >> openssl.cnf +fi +if test -n "$crl" ; then + echo "crlDistributionPoints = ${crl}" >> openssl.cnf +fi +if test -n "$keyusage" ; then + echo "keyUsage = critical,${keyusage}" >> openssl.cnf +fi +if test -n "$altnames" ; then + echo "subjectAltName = ${altnames}" >> openssl.cnf +fi +if test -n "$eku" ; then + echo "extendedKeyUsage = ${eku}" >> openssl.cnf +fi +if test "x$CA" = xTRUE ; then + echo "basicConstraints=critical,CA:TRUE" >> openssl.cnf + echo 'nsComment="Testing CA Certificate for '"$commonname"'"' >> openssl.cnf +else + echo "basicConstraints=CA:FALSE" >> openssl.cnf + echo 'nsComment="Testing Certificate for '"$commonname"'"' >> openssl.cnf +fi +for value in $principals; do + user=`echo "$value" | cut -f1 -d@` + realm=`echo "$value" | cut -f2- -d@` + echo "" >> openssl.cnf + echo "[$value]" >> openssl.cnf + echo "realm=EXPLICIT:0,GeneralString:$realm" >> openssl.cnf + echo "kerberosname=EXPLICIT:1,SEQUENCE:krb5$user" >> openssl.cnf + + echo "" >> openssl.cnf + echo "[krb5$user]" >> openssl.cnf + echo "nametype=EXPLICIT:0,INTEGER:1" >> openssl.cnf + echo "namelist=EXPLICIT:1,SEQUENCE:krb5basic$user" >> openssl.cnf + + echo "[krb5basic$user]" >> openssl.cnf + count=0 + for part in `echo "$user" | sed 's,/, ,g'` ; do + echo "$count.part=GeneralString:$part" >> openssl.cnf + count=`expr "$count" + 1` + done +done + +# Create the data files for a new CA. +if ! test -s ca.srl ; then + (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > ca.srl +else + echo "You already have a ca.srl file; not replacing." +fi +if ! test -s ca.db ; then + touch ca.db +else + echo "You already have a ca.db file; not replacing." +fi +if ! test -s ca.db.attr ; then + touch ca.db.attr +else + echo "You already have a ca.db.attr file; not replacing." +fi + +# If we need a CA key, generate one. +if ! test -s ca.key ; then + umask=`umask -p` + umask 077 + keygen ca > ca.key 2> /dev/null + $umask +else + echo "You already have a ca.key file; not replacing." + done=echo +fi + +# If we need a CA certificate, generate one. +if ! test -s ca.crt ; then + sed -i -e 's,^\[req_ca\]$,\[req\],g' `pwd`/openssl.cnf + openssl req -config `pwd`/openssl.cnf -new -key ca.key > ca.csr 2> /dev/null + sed -i -e 's,^\[req\]$,\[req_ca\],g' `pwd`/openssl.cnf + openssl x509 -extfile `pwd`/openssl.cnf -CAserial ca.srl -signkey ca.key -extensions v3_ca -req -in ca.csr -days $DAYS -out ca.crt ; : 2> /dev/null + openssl x509 -noout -text -in ca.crt > ca.txt + cat ca.crt >> ca.txt + cat ca.txt > ca.crt + rm ca.txt + cat ca.crt > ca.chain.crt +else + echo "You already have a ca.crt file; not replacing." + done=echo +fi + +# If we need an OCSP key, generate one. +if ! test -s ocsp.key ; then + umask=`umask -p` + umask 077 + keygen ocsp > ocsp.key 2> /dev/null + $umask +else + echo "You already have an ocsp.key file; not replacing." + done=echo +fi + +# Generate the OCSP signing cert. Set the X.509v3 basic constraints and EKU. +if ! test -s ocsp.crt ; then + sed -i -e 's,^\[req_ocsp\]$,\[req\],g' `pwd`/openssl.cnf + openssl req -config `pwd`/openssl.cnf -new -key ocsp.key > ocsp.csr 2> /dev/null + sed -i -e 's,^\[req\]$,\[req_ocsp\],g' `pwd`/openssl.cnf + openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_ocsp -preserveDN -in ocsp.csr -days $DAYS -out ocsp.crt 2> /dev/null + openssl x509 -noout -text -in ocsp.crt > ocsp.txt + cat ocsp.crt >> ocsp.txt + cat ocsp.txt > ocsp.crt + rm ocsp.txt +else + echo "You already have an ocsp.crt file; not replacing." + done=echo +fi + +# If we were told to revoke the certificate with the specified common name, +# do so. +if $revoke_cert ; then + openssl ca -config `pwd`/openssl.cnf -revoke "$commonname".crt +fi + +# Always refresh the CRL. +openssl ca -config `pwd`/openssl.cnf -gencrl ${CRLHOURS:+-crlhours ${CRLHOURS}} ${CRLDAYS:+-crldays ${CRLDAYS}} -out ca.crl.pem +openssl crl -in ca.crl.pem -outform der -out ca.crl +openssl crl -in ca.crl -inform der -noout -text > ca.crl.pem +openssl crl -in ca.crl -inform der >> ca.crl.pem + +# If we were told to start up the mini OCSP server, do so. +if $ocsp_serve ; then + openssl ocsp -text -index `pwd`/ca.db -CA `pwd`/ca.crt -rsigner `pwd`/ocsp.crt -rkey `pwd`/ocsp.key -rother `pwd`/ocsp.crt -port "`cut -f3 -d/ ca.ocsp.uri.txt | sed -r 's,(^[^:]*),0.0.0.0,g'`" + exit 0 +fi + +# If we're just here to do a revocation or refresh the CRL, we're done. +if $revoke_cert || $refresh_crl ; then + exit 0 +fi + +# Create a new serial number and whatnot if this is a new sub-CA. +if test "x$CA" = xTRUE ; then + if ! test -d "$commonname" ; then + mkdir "$commonname" + fi + if ! test -s "$commonname/ca.srl" ; then + (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > "$commonname/ca.srl" + else + echo "You already have a $commonname/ca.srl file; not replacing." + fi + if test -n "$aia" ; then + echo -n "$aiaval" > "$commonname/ca.ocsp.uri.txt" + fi + if test -n "$crl" ; then + echo -n "$crlval" > "$commonname/ca.crldp.uri.txt" + fi + echo "$DOMAIN" > "$commonname/ca.domain.txt" + touch "$commonname/ca.db" "$commonname/ca.db.attr" + cert="$commonname/ca.crt" + csr="$commonname/ca.csr" + key="$commonname/ca.key" + pem="$commonname/ca.pem" + pfx="$commonname/ca.p12" + ln -s ../`basename $0` "$commonname"/ +else + cert="$commonname.crt" + csr="$commonname.csr" + key="$commonname.key" + pem="$commonname.pem" + pfx="$commonname.p12" +fi + +# Generate the subject's certificate. Set the X.509v3 basic constraints. +if ! test -s "$cert" ; then + # Generate another key, unless we have a key or CSR. + if ! test -s "$key" && ! test -s "$csr" ; then + umask=`umask -p` + umask 077 + keygen "$commonname" > "$key" 2> /dev/null + $umask + else + echo "You already have a $key or $csr file; not replacing." + done=echo + fi + + if ! test -s "$csr" ; then + sed -i -e 's,^\[req_issued\]$,\[req\],g' `pwd`/openssl.cnf + openssl req -config `pwd`/openssl.cnf -new -key "$key" > "$csr" 2> /dev/null + sed -i -e 's,^\[req\]$,\[req_issued\],g' `pwd`/openssl.cnf + fi + openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_issued -preserveDN -in "$csr" -days $DAYS -out "$cert" 2> /dev/null + openssl x509 -noout -text -in "$cert" > "$cert.txt" + cat "$cert" >> "$cert.txt" + cat "$cert.txt" > "$cert" + rm -f "$cert.txt" +else + echo "You already have a $cert file; not replacing." + done=echo +fi + +if test -s ca.chain.crt ; then + chain=ca.chain.crt +else + chain=ca.crt +fi +if test "x$CA" = xTRUE ; then + cat "$chain" "$cert" > "$commonname/ca.chain.crt" +fi + +# Create ca.pem and the subject's name.pem for the benefit of applications +# which expect both the private key and the certificate in one file. +umask=`umask -p` +umask 077 +if ! test -s ca.pem ; then + cat ca.key ca.crt > ca.pem +else + echo "You already have a ca.pem file; not replacing." + done=echo +fi +if ! test -s "$pem" ; then + cat "$key" "$cert" > "$pem" +else + echo "You already have a $pem file; not replacing." + done=echo +fi +if ! test -s "$pfx" ; then + openssl pkcs12 -export -inkey "$key" -in "$cert" -name "$commonname" -out "$pfx" -nodes -passout pass: +else + echo "You already have a $pfx file; not replacing." + done=echo +fi +$umask +$done + +echo CA certificate: +openssl x509 -noout -issuer -in ca.crt | sed s,=\ ,\ ,g +openssl x509 -noout -subject -in ca.crt | sed s,=\ ,\ ,g +echo +echo End entity certificate: +openssl x509 -noout -issuer -in "$cert" | sed s,=\ ,\ ,g +openssl x509 -noout -subject -in "$cert" | sed s,=\ ,\ ,g +openssl x509 -noout -serial -in "$cert" | sed s,=,\ ,g +echo +echo PKCS12 bag: +openssl pkcs12 -in "$pfx" -nodes -nokeys -nocerts -info -passin pass: +echo +echo Verifying: +echo + openssl verify -CAfile "$chain" "$cert" +openssl verify -CAfile "$chain" "$cert" diff --git a/plat/diameter/doc/single_host/demoCA/index.txt.attr b/plat/diameter/doc/single_host/demoCA/index.txt.attr new file mode 100644 index 0000000..afc5de7 --- /dev/null +++ b/plat/diameter/doc/single_host/demoCA/index.txt.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/plat/diameter/doc/single_host/demoCA/index.txt.attr.old b/plat/diameter/doc/single_host/demoCA/index.txt.attr.old new file mode 100644 index 0000000..afc5de7 --- /dev/null +++ b/plat/diameter/doc/single_host/demoCA/index.txt.attr.old @@ -0,0 +1 @@ +unique_subject = yes diff --git a/plat/diameter/doc/single_host/demoCA/index.txt.old b/plat/diameter/doc/single_host/demoCA/index.txt.old new file mode 100644 index 0000000..26c3086 --- /dev/null +++ b/plat/diameter/doc/single_host/demoCA/index.txt.old @@ -0,0 +1 @@ +V 170618170115Z 01 unknown /C=FR/ST=BdR/O=fD/OU=Tests/CN=peer1.localdomain diff --git a/plat/diameter/doc/single_host/demoCA/serial b/plat/diameter/doc/single_host/demoCA/serial new file mode 100644 index 0000000..7f60683 --- /dev/null +++ b/plat/diameter/doc/single_host/demoCA/serial @@ -0,0 +1 @@ +03 diff --git a/plat/diameter/doc/single_host/demoCA/serial.old b/plat/diameter/doc/single_host/demoCA/serial.old new file mode 100644 index 0000000..61586c1 --- /dev/null +++ b/plat/diameter/doc/single_host/demoCA/serial.old @@ -0,0 +1 @@ +02 diff --git a/plat/diameter/doc/single_host/fdTestExt b/plat/diameter/doc/single_host/fdTestExt new file mode 100644 index 0000000000000000000000000000000000000000..72aea67fb4265e4a80d04deb5ebd392c08252120 GIT binary patch literal 1984180 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%0A=ssfI(Qv|oqYr$vRt$m1{Ta1z{=F3Ats4qG??j2 zPS>l+VrlAQJY|LjW!H(Os zU|?iqH-TFgzO#^Y}yBb;7a7wen%8yw*k}O!6NPaeQ(752SUHe@F+abbK_C z@ewYq^q1d!ZR)72f^|W}glUIr%MBUJ0VqN5Md)Bb_lHFWw8TY76ZG5tRo;ddt=|#Q z5*I1x6Qm?Sw?DKt=t+kOXvuOwk3<$)7=#vTv4AUku;tJ*bbz+=0*np@whME9CXKi` zB!2?PA{jk+2MASgm>;3-?Ca;zPHpBt9BPtwWy8dmGCa&(Aa zTeC;w{J;J>#mIiJM1GyYU&|yyMh4q|M&$~P+ys>yrE>h0{~&jl%FW_mXl1C%U8i#V zmH!}jvC7dJ%3Y#zr>UISsB*`sT&a;eR^=L~9Dn6M)VK3SAtC!CQQvQi#f}a9wM?G9 zZ{)r!dQryeqV_OH6!4*PV~Fb=~vJ zta&FJ8M zsN?y&vtgq@==w&D97Uv?T#ulfAl%_g|u^LN)v7-XNnd;U^E%;)beGg5s1Zjnl1 zx09SdXev@QpT8S`$p3fG-#r3;iBrOs+z5?Cs`*m%X&J}5m|n| z&zzX6K)*fGifn3dhH1Q6N`x@zRfidnvQBmf_PmBzWd;7Y$ zaha$)G6s4%^MU~%6Ad&yB*C(zM9T)^0WrpHRVFr}W$UhWESo7uA!#cpqn5Rkl9)Eec~~~J zfmkM4j%8zzrIyVE8&9XL#Dq)Bq_|_*#VC$F_wkMy9K9V1pK6q+>slcl9%EcLc9AtO zHNn8&u5k=pu8+ap#(+T$^h-$?=;gW(>euPILS(6dlNhvmtz$pSbmZ;2TTvXx(QrVh z&-UQw2vTRW+s3El3<}^uv%VYXB)tENDw`qM25D>h02r8_;xUgL%~~2C`Dgh zi?lUpeu*{c5+g%{PIe92t52kD6*p*6GGLaQc9fEXtfa$iMerQeYYh-9@m)?%=Qq|ORD5Jg` zFC}4Wm51*dsHu|W_%50hGj$WD@>pnz$5JD-#PhcqTAs(C8ora_j_=+;aY#iw@pM30 zW<~L1-S}O}ISl(Rc#nwPkJ(Zh;B7@Xw~QW&M-+3%J-6?d?O$W0IjyH*hDiAHvLYP$ zeyijzFmW5noq@C^H~s@luBDM7xq7`Ea$oF`xq2@n2qkxelmxkEO={28pX_hMxmvOu za_=B3OgpvfH-VOTA~c7n831R<+a%iRtwK96ZxW)^3M{aehJ zEXVvg$kH*g9=gTGNC$aA!>M{J&|jEJX|oh}Y`!1GA+@bOfW>F^@GvNmaKhlbjBmm6v0Px9Q0zk4H z0Pi46g3rjOo%x11eR4e_`${<|YP!h*M~t7-g(5AM&lC(MPSe^SRCjaDef4w_D?Zrg^7n~P$|;ZpcCQ-%`q}G z=-DeAgYM9$_C84&H7GitC}7YJ9tQP8vzTop%Q2`MvLZL_r*pQ;Tfkup-USX@`0V)! znEh#slyq!qq_!j_*s=>@khSFo(MY1)EhapoE#=)ETVB{HBd3%yYRhpkTdF;5DcCEv zNS0$uHnJj3AK>Az$C->WPIa(FN;3kg?Sj{XhP$ zrU{tC$ytg!oExDy6iiAmXcrb*YtRj%miB)WElB^r%rWQ%eL`+2WlaB%8RYjcs9=w9 zmMq7hY-B|y;aq-f)r2ka*BX^!`lc;X(y^s8N`?oZwS)tM+0ZM}XnUhr$eFvnH;&qi z7CjEJ$UYb^>uKa3tP}e5vENNlK-X?XI^5o@p*`QTJ??8GLlWUkhs1b&Ebe^DD2XGa zBzoKw4-$|4E+iz&Au$wLXyH1x5X#{$4tXVbejnVqnZ1R9&;HAaNvCfF7nr^gTyXj> zWIqKasn)@CB&v-*g^(0W*M+=tmzwt|{<<*AWT3fRy7K*MLIYy>9%+l=vUe?pwMK>* z7F_CJctRh9`wnFk!y!@<7}j}Ucyza5kSqtoAY}P@&u4CRgVekLLR}myaQhi&cdSsX zErO4Pvltzui0^n;somRg)k+;|c6m1D##b}Z9vNPKcPMq9B z87271J7$i!0!p|iPA-J9SRN(IA$UBp^xoR=b@nuCYF;jkl6hjZM&Uy-%d^u+6;7ww z^c!mL2Q^n-?5H_yTLM!akw+Hb7c+QM^LU#mW27bFA%q*hT$+y>qfa2WAezU|NE*hV zIbUgB7uG)VAl!pE4{t~JebkK{mJ}7D8r+grd>UQC_Q*T~^R8YPJPNx%BH#VUljZVO z;;as#%nguu3KA&3a5amEd=E=)@%u$L!J`n2eu+I2i*`dMvI)?NR}boy6y94?@pX7Z z5o-9%gfsN-Vx+@O%tX-!RhiiIT_Z#PPGpPtooD^z#MlshhHpM))W2KbGX6dKh}!<` zk7nUt$#VRAF|s20=yoQ~=1YYbVHcx5I#kM>hB_05$YCg>#J1q<-=a&A8+n3^5PzL2 zXA~nN6zyr}7pn4s)9~pVJ!)oLg({$C=unVD0g4@epbc z7jAe!7q#Nn;$U-cqrc2|3EE;Vfc7vk7#)y-v~|EMv#kT#8yPy_NLS6DA~L`Zp^Q4< zPAQ2g>NP0k4zLYX;sD8V9IzN!x(MI;3=P#88RrQwBjY>)XXL}M2+$W&+!ZfVRs;H4g2IxYuF7&hK6hM2I4Lh4MYFL4kgkhx~hSgWYB+D@@f=5oF zh0iZSO`)7>Guj@;V|rteHjG514I>$8x5E@qBc&?G$QMx+q@vmIHL85dghVuQEYjA< zAJC7@@Oi+<(8%klLgMggrw{49iZW{Cn^F=+?(i_OC7Q?Zku1l^`pAl0n-!0^YnXcn8Oh&H{Aw6&>e+@_a|3~d^Fp<`1YeZ1~}DWf)h`MQ}B zd`H&qkyoI3*d$qwO=lu2@^%*<5ozQNn|6tx_}H2;SV(A-lyq#`{j)3<(a#uf;QYUd zZ)nrkNL!mO6wUPfzmcI$Z+CHQ8lw-#eT_0|Q~j7t$9UNE5SoWglI7TR6S5*tEX2Ki z<{T1iLX?ZXR}Guq;+hPbq@-h0Yq6<1`Ug8O_5&o?)G*PeJ7?Lx_q&N5Xw%o79h=_T zA~VMt%BW3eN=fv+GdygXj`$NcNtR>Np`Hl2gk|+w|CsILWE__a=UKF}%pCm1(~|s^-v#oG_aB&m zgr2WNI$U+MUe>x~rlqvn$XpAVxfeK;9@ppa&Zdk~I!H=ppNRcV(m343O2Y%FGS_mQ zL?74&UMILhk5P!asZdV{VKW=+N#bq5zSG!#XrflkCzJS2NwA=0q6K4Kvlbj?Wa#Ie zog523(ud@3Wz3@%TrMTy=RyxZ7jG3mOP1s3myxA<--|mJV&}uqfpIRE-3)8ftwx46 zWp;F&)l6-=kTUA5=cOcU`q;y!L)9k9a%|cei8n0?yKEZ>sUk}G z5WV8zBEB@nuRTlg^AvyZQ-8aq{$PbXy=P9WE)~h1f=7FI58@L1l5j&5N|+K3hk__y ziY*Gb-yQX!t}t!^fCgoez%*LM%+Yv^(-_a@Go7}2qAeT@EeWUAZ0Pl$(2xg#mvI>4 z5@<%lf|-RNP<{c^<~dhFV0CQ*70|4(CV_H?Kw+H(nou!5cS#8pvMx&?w@?Tmb999g zsNFmcMe0qZ*%3EL&E5+F;$ zch_Xvhc)6Qee_lLsn8Vr!Axw#p>rP6cIZ3@U!q#x25^#*;m|qwTxaNP+$if=J<90N zxkXB1=-h|a-AH)N4>BD{mNRq~AS?3qERGsI6N~i>@gYu2Fh1n`&ru^Kol!FyB_Xvf zbrFK8q(}#hW*GtgG0V6z#a;-SyFJ}(yXaw}Ct96>ba=H{pI(9gjMeRp46Q!$9LMUP zHi*@SP)4o3Q%b_>aUNE0*dkU-mSgo|WG%|zHQohSA3Q^@!;nGKrMP4ISQN+cc{IWy zh?#?~?On}fq8fS+G7%N+?2ELu^MjYIoqi)jJ5M{?v2*`7VrLu5sGVb^Bq!# zCKKFH%e6>{3yhZM#kE{&WT@rL4vv=p)o1R$Oc~X3-;1;lS|%S=dx+f!RS+^tmg9u$ zkfou-{A6BQ+a-}bR;PG;KkXHDf)sb0kcQ&yY$m>Mm|)mmgbCKL{-U1D9a~NKK*LtH zcMO}RkIP+788z&Lm|@L444d?w7$#YcVIz^HhF$z317h7N0mI@!e))7YOo}^(bwP0) z3Pg9wDDs_dl%~g8CmNQANz+UZO%n{;eWqhrd4&v{pBZPUVOK~=c&xpLVI`Gfm}EJI zO-GizE~j|dq;C4E>qWD;k10B-j!{%8i!iotvmwXM>rfj{)-Pe3|6#`M?6Ua;05VPxpmJ!d%9f1*#W{q=lneGe%K>%At&MVrKWugP%+vUJjT z9#(nw*B!FrdQXnGqd5EPcW`UuE}SXUS@9|=1~<~ci;=blzWTg1@GK)k1CMeIjII~= z9u_xnsFdWi;V~h!0H7hPfmKqoZBF|Z|i80V?R?I_jXI9MJ-Xt;{-4CYn;C4wk z2mK)7$!J%j2!=(yhcmU^ZnAD=HD5RkUM}v1$u8k!b(<-F?~fF1+P`1U{zWPVCY2P*zCJ^x^q{FP8YtzNgS;VW13=zM7n$w3K`$7=E zNf{kMDN>S%Jx0*Tjf$9A&IlTSEVR&_E$F2X9Z%2}C;u5|L#^$nG3@X-jD7}lw5&-U zqp2ZkCVjoR!H%KyNHzKgIxE6ZF3W8F8xuf~$10@5y$z4EK-kPEi;N6;ymG3;;~{;1 z?+cVs9@Uds5uwrqDib&G1mGd0o(n6lDvIm8o!sq(MjIi9JhA+(i3u*9t9uRsW`PBkGB zwJbo|YWdri<(bsV$e8a1Ux zxq>e#`@FJ1KP)S9MNv{5G%VDXh2mSIH&meih(NSyYBKJVor66eyl{aVOpB1b0^(46 zo(Yg>=IcmXGY^TI`J9oVnYXutIp`w1E+o#7yEH>-*_2T;*Gw?8#1N|Gn3)N+V5Vd_ zW}bp9K0HMBrihEoQ$t81%)Z8c{t~Wv;Z9K?$SvWgJo`rzc=ity5bA}An*&RlDXs}- z>6ZjU!D#iNF)%nShm(r}W~G9eY62|rKhhS=Z_mX2Z)C*(Z5=Q-paonI?ME5oe<=z7 zdx1F(YSjUzDYE_DPe_uXeTo;8M7}+2Tp6v`;m+odF!R(f={iZ6tzWI3I!1X*B8L(F`T*x6*909S`E z$aIJ><)<*!1eh`bq0N{y$yAzgI@|SVMg^mx#{U!3Q;)Gs*X_4VyZvREcBtQ-Om~?u zhD;+!Tc%eQSf&+5hD>Li=rDcf59z0KDWgoAO36By=B=xf>7B^>XQmt1lIh*Tl%K*> z6JW{&m_CIGy)LHp(2NR3&p-HoV%lDrvPb^DM|$LZ6ZDYY8%SGvhdyoTJ#S=4Z*Uuj z-u*c7fl>YtWt869r&zKMdY7%OlisPw`e%ACuOYo*LXV$9PZOZW1nBj~++7#FWot-} zg3&+l2Gajwly|O0Z@5|WNbhc>ExlFwmR>(2LwapbaOj<_JGeViM(ItIl6BBaf$o?i zy~gv;pZ^TZ`Vlla&VPRUvKZT^q9WDvb>3%}#gdEzk|hA5uo? zHJ6fg(0g)Ko%HTU)<4txVI}E}5_n4Q34`gITQ{2Jh>h<|4`{gET1#217vH4c^AB6b6#ztf%)N3k)K%Kx^=} zkRcncGc06yP>koqCxv6{YU*EPks~blDJ(Pr7EFM}6PSX@LYi~d)xSR@3kpWh#xtsE zzggGFq7rG#;*y|cvD(Ox#nhG#itZi&4-3bCF~@EN(>>SX6nj z;1X1mMg4tbktZzpDJ(Pr7EFM}BUn_(LYi|}>|8+>6pWr+UszO{Rf;UuA#GWlKhCmP zW@N~s;5diH3%U=vkTS~Rug6&uEYgpy-7khg1F(=RheaP`fkm|!3oa-%S?t+M7UP5k zKZS)Rz=8>|cmPWTSx9pZiyuEF3kpV$ttTwjnKg$j%8|A#P8EyfXtT)3kVRe#hsDzp zBBnh{8D+8KF~g$3gT)|d02Y$vu;`8~ut+b+sNWWq%Dh9Vv(?zZDhz|_^}R)T-`T4jxx&P zhk#*G<-wvaGyn_9a#&o5EU-v{cC}bA^sUKaQ#Dx>KsdLApTa^DV8H}f+=%I$ETlPy z#mbM#f`ZsL96RVk@W_YxV%%eHiX9hU+@fdF@<1tmEL|R0jIWHcz%qRCR3nfC%py#L zBapTTH{{u&b*GUb!gG&t5N7Cx>rBch!s${HL#sEMcBkAlC=P^@LYE@4IXRJ{bm+4 zqFZ#dgYFY-a>ilGD#|Fj)1)L9H;-QT@^V2ZSx&FZLzX|3FAKc~!EmhK{r(Z*O%-_j z6nL5dJSG5dCgxzmlZKprcPtuG!D#P&F?a`g!E1cn0f+1wv$_%9a-=Q1c4I8O`9_BD z#vbLs%h#>X&rn9;{hGs)b@aR2KB}|dU5>1O?sp$7Bf3IC$4^1037}&F=#E)FTDj;T!Xaz=-DI;E5?u&si|&_4ExM6LhUhL&bI@Iboz&=e zH&8~=&6Scs*B(u~v)##19J8HdIsNVsWTD?lP<5bw_sCMhn<4P{DeyD_cuWA^nOL<5 zPa1Oi-78B8kAl$(?7;k|Lp(Vzsi(mnfkim?H4OaBf-*dw%!wx{@Pf*&j{jN_Pgcg0 z6nGV~WdY`kTgn1e@%-v|G6})FX_o?TNGax1MePGkz52jM5cFE{#4@}O)~sOc1CJwZ z`@q)GwhugPWY`BTIl}1!SLxR0Ybm3BV2+eTAE-dnZXY;diSz-+3Hiu)O0mg!4IUJIZg|T2b z41NISE+s)>hzErj4t0T6dpC}D=9pPw572Azm~#4BSQ*jHgPCi zpj)!LQbs9Em6D(^$AdyDGynz3awzNyCsN?R_ogs7ObT;_0zZXMXyzPfN@b>5i;(bS2c>j@-fagck?zFn%LxCq* z4!n1fh3Q0&(GRq=p70^zeJJqwDeyD_cuWA^I?U~aCk;99{Afr8qoa4m;I;LFH}$~q z_M0_^@P0$u!n^)q3-5a)LwN5T;=n7ecXQEu>@}@SgslPIy_!`Zw@?#Eb9n z&JuygPl2Ziz+(dNCSyUU3tnS1q=L~5?0nD#{X{Q#uOArR60&%+a9p+e#P(Hok4gX zG;-iA|3-S=r<756ZKWjOMbNanV7xG2;7OLVVB{d{-@w~BkMLFtJbns1O#mJffcFX} zUc!@xoCV`(G^B#j9(drE&UvlnaK<@pcVYSgSKF0l^(4F{NZX!w;{6uhdq#%v9%<;n z3+jgGrzoTFwhd!R!0U~sU3fRo6L^y4z`F!l|9lQ$!CazSC+PSo=rjRzOaR>wOxQ#x z%{b^b%q2PsMw@Pnp=;sQ?_Q__9S^9?;Vio*-f)JnN{=N+A;o`X0Up+(QVNbkl5Qvq z6j;G$t>BcHAl`>)R%1HjT%@ftrrc+paiWo-Gj=p^oUu>$Iww;`opH02gfnJ&IOFs8 z#Tk<2IAcDt;zyJTaicw=j75$oy-$Z!h(q`(4$%Z0!UP=hC8lyZM4ECOawVEl!DvpD z4r#_(@GtrcE{lO5V|V@?k{tg)+@Q1CpIqusUM+9$NRIeVFTfj&@V3EVfQR*EfqnnB z#36WTAkGdPpynLb3+jGTTOfva9*{+9-g~gf{_!gQ2uVJ? zat)?*dPN#^yt4cqHt2gf$ua2->~*e*zZAa&<#kVZMZo`p|CO5fuS1Lams^px zzU+CI_2t(_hQ54lfBTx-H{V?=LBV{=s4tI@l3dq3E(|>OwytZ;a(p=ySzb=m6LYa? zbkke(z~ohm`!w5f{vep zP7^@K1km-lw{CPF&n7wwM*rT7DJg&6FtGF7;K>Z>V!G-_fD#?D3Hl#K8k5c9$@F-V z0x8FfZ2S1H9plN2c#;CgLbfcxd`@}l%Tv94*$RRO7zV$ZWre={9%<{#%kHqgTx(?L z%a`{#zITonzhD86tPV(>)xP0cZomw zDgM+1{K*9T8Ni&(q2P6n`j0p0PYOoQ_>N1A?kBD(oumHkbyA>Uv~8tO_|7a?r0@mOmO{tdErpMa3@MD?>rj}wQYcKLj8gb}kQv!t z=cw<823+8H%F>w>uSZs#0=v97h4NXXuumxPQz&Qx6qo>o5tx}}VPiwiwD|KZQlMb; z_)S9L8?(ld!YZUKg|oyK+3c~%$dE$l4~N2}&xFDYlu-)R0}TbQv$I2?0VsH#o$ZaR zI0a7FH7Udvhb1#fAqkIQ&n@AnP|yS@FaZh=VtOV8ud}m1%_Id1MqA)1!#bg0e^~9s zp<^8rikaScZHYTU^unGV^i0KXdeFm-?wqhN4|1bB*JvD?BE_MNGfGylC@xrvBv+)e zK)DrMVFg#m1abePS)%E;qmj0L`|oYG_ck&z^xN7!j^DohRQ&cm*DLi~hLpq@_BuLx z|26TO*U`}wWX0#Q1i#t2EathC*XX$h;yHeb=QIJ&F#*pl#FR?Uc^w^{j;2&FdfNs< zY{5~0f3c&ZIp{U~J0v-tA^tGjW+X>PMUX8EeE4rm;OL0^eGX9b0M-lxd1)MH|M6*# zjx<^8=!i|jHGTh5*U*(ckhZRTXMlBO7b8Pgru^=>@`z8wmCY!luFRH_aHZGLQDla= z((CBxGh`jWK%BXW+7&N`2dddVLC6md5{#od~KyP1HyKf!EEcY7TjT_oyIF!~_g zQ;i0tU2}AlwAvf`tr>F)|Vd|8TxYEPRH;G%f**dD5JjI-H#>dOEm2s=?W&)Oc`bfxwnR4s;4en}3NO{SQGtmo_Y8 z!-22}wISIXK?)~YB>Tpb1L8>vRH*E*_^-p`$((qS0^dUxEg)sq%z}9Slz6f*o}|F9 zQi}OT#X0f(qIj}2o}|DZQi}N!WtRn3$MY-V$;x<=0;wlZL*|=fo~n3$bv&7bI|d9H z3bc|^%$HRVhez@JX7OZtJV}AJQi}O_b|+e8-{xKIwJt<;fZzeP z$n)Kc?A$!Go8mF&p>3wDGaNV!WS=)LK~sLPoba*P+$TS9>YW}Go8mF&)yeE zfr8O9*9e7(S-41H1JeJGxOaiGsrvu_hYX6EsVI_6xug)HklT>qyjC=*?DlcE~Z7?&DK8l_OG`4n|_BaNs=DgW2&z1CU#%$mJtcs#z3|F6fR z?LFuHUVE+ee6RI>ueJ9+`xpw{@nvlN%7d-ih7_{*TNIY&3x#F0Q50gOBq(@2mNN-0 zK<@T>EaxVuTnbsf6h2!(3eANAk3vBSpg;i>(vfsX!RxV{!wX1(hR#LXg~AUyi;==t zkPU@SLkxwFv<)ddU2IW!cAZdILK{Wl*kG0fg#dz*o%QZR3qV0sR@S>7Dwo0vUkY2E zA%&Jgfk&aB1W=#=3X_K`3R01k^$t8k3N&;Y7Yc zu_(;X6AFuHqbM91q$y;1P`C>%00mK56t0EJrBLWgVPiHav=ItC3I!#A0tHY=L6GKH zkcun{;cQZ%q0{g)q3~6SOW|Y4hC(api%?jjZAjs9$D%On1EDaFHj2Wb>okR39u&r) z1)v}*i$XuBTnZ(=6h4?w3hmK};0HVk1tow21yHyLA(|AVB8$Qg^GSh*&e_|9LZQxm z91EKu8wwXnUxdOcZ9@v_VT(fMTA`3d8%5#Qfto@>lkziS1X=(JqOvF?LFH25g1|dR zyf=>&Itm3Ig@O`5fdVLuMTjN^smP+RXC5ig&^i56q42TJe58;E*-$uN`XUsTYa3FS z{If+N<9(sw-{ss9Xx=cQ%pB3UAFNg)TyYN1>nuP@n(` zw<1K7g4YG1ujY~h4V_wBBg-v(^|btQYYhD8wcOG-T4v~kNqCP!Ht_Z)6M?|HSKAO? z*PkqSfi(he0Bsb!SEVF^s@L6uhG;n8iOL#6RiX0QLzKPI^1vLTOB8fG3OXeK9R;Af z5E+5!q#A1gEu2GiG;|6-#sI2hBN27C;1Qry3tPNKqCDyO6_akPlQK!44cU;Me2pPp zL)(z_7ke$z-{lJFADPw^=|m|B(q0SOm9tgI;-lym>1?QuZ(&<=Hfi?~+B^zvC4e>s z&|Zz0D?y7@S+rZBDrM;0x<#gI1D%%1Ar7+PaNpI2!!ez-$l;S8Ee>D3Cmg<^jpEQz zN`iyebbak<-|3nK)$vT%s!x+bKq&Ai6qEo86hL7mVy@qGy$}^CL+8fLpiq#}#@#*f z7p3&}E728cuv7*d_54*3u=rl5F|zvtvSD}m0K;yhwjsNjKUnM*yesS$(?+p7+MgxC zE+3WIOQ7+ygq^6YF*FD&mmOQ{9q>QOBD?;=jz?jq1hAt3b`ue)$xbS=Mo@7U+0oER zC=hnZE~TNaIKmZaaB5RdR_eFoZaY{k)ya?S=0i5@{_bbkJ)v#L?z;b3>~4NX*o~r% zVwW!^eb}`_yAkQU*wur|WyjWfvwLzT*(D1*9)+C}z>Wggbw;l8WB2AvvZJB1_d{Vf z!KF0G71Ldj2ImPo>OWWPZr3T3?1n=&?DF~=cKx&s*_~ZvvAbZEu)B~pirrKx>BH`? zr+nG%fy!ma)_SwM`YEy-BF@x-e3OgQ!of5!~0@!Ut(Dh^20Tn4j=dO*yZiP!J*A??!kp_c=9rbGzyWeyU zB)cCW8+N?|hFv62lHKBOEq1TICG6hhdDOV8EhT-}O_}b?ZZuRbJGR!F-B+1pccZZ5 zQP?Q~>?nZU6A0IS?Ec9lI~qD|HVC^ym(ng*EOJE}j2Cv)zpvP>)OnNaUWRPgozlm! zo3CxiZqy!&-90OW-Tkyt>6^l?18o$$Ia1PxT@AF`hu!{AG&{D|o88SJvKuYzcocR@06Pj`7l(x9$1aG9 zl%bQmPT0k}l==!nigNl@)^KhQ9YvWSt z=!%K1NQ1Y99rbyN-LdZ#3$i-|*{~aOrD6A@wjsMWcUkP#ye{n4(MGX5S4#S@oB4z< zyA-Hgc5JOTyPqB>ySs!PkHSs~U`GM$<|F9(v8#oOl%bROfv`(m0I&YNWS9%RGroSuf=%i4zQ?%!##d*n4?7o?41SJZ}R~EaTuL`?9v{CF{kdi*^&PKa^;@#1y(d^h-Z+7=gCA$=1$D^=Q z0@zUiyGBS@e(YwWB4y}o#_xh)PnP9U%67#ZSENC$X53d$zh1HHr}HM+b%$)&E$MF9 zwbnLd_spH8>&@=cAlXe4c039@C4e0Tu=^1~ z*N@%xs7M()({XtQ>{hsxa$Pas6=~2^*ipYhv5V7rlk84{Y}k$IX4oD2TJa*gbzfNQ zK7Lu)eMTF_uBDXpVYm1(Uv^WWa@n!9-t7K-l|paMH(auJL;d8XIf&v(0P;W3LqPH7k4%6-qSW@7yR5}_tZTc zyOJ&}>BDZ+qrU6{P`T{bT5oo1(#bAe*zqXrlmK=V!0t|jYd?11r;{BGojUIcyAqdD zsVm0(iId|$z@@=RVMqNE#csaNn`D;>*|0m%*|2*^+mKzK?H0R%FABTsX`|S!l9E2` zE=0S1;$3a1Ty|`&H@iosklj>a$D^=Q0@zUiyVgipe(aV`Av+p6yWSBr@h+u$u9)D8 zG?*yts9&ns4cB>-?5=@q*u8y)Vb@*TkX@}pi``i-2)hQfQS2s3NgsB_kNC1Hgvw>d z)_Sw+`3Tuf6LvfbJ0*Y}1+Y7WpzFu(c2uMcokgpJT^pBDM^{XAMH*xXJL*Gcq7?T3 zI&YHQnUD>;2Ra#cCutk9`)r%V?&~GO?)xtdyDn1FhuxcLzU<~e<+5XIz1dYyBfIIs zjz?jq1hAt3cJCqR`mt+)ij<)Y#SyMZgXe@D^-n5xKkB?mb~_;(c2{&X z>pvF9so;O>ikqa>aC4q(Q#0qdrryds*jAvReq*u>0?F!!A?XklpoL zEq1r&2)o;9qu6bdl0NJ@pxr+4?p&x`c5JOTyQe0T-5g=Zqp(u~*iitx?nqdE>{d=D zI~qD+{FocqWx15HT`|WMX;38WsGqLb-Kp~?+1&!!u-kB%VRwzTA-e{jSnQfD7IrOY zqu5Q8l0NMIdC-?#5mYWaw$_{7zz4}LTiEd^?34g@6u|BzBrHF66H$>ebY6c`*sX9W z<+@_NE7IT}VMqN8#jdr^n`GA*vSIgld&BNbZ9{h7Z?V|@@~p7?jX6ZI>n|mJ*sYu7 z%kBlJTy|`&H@mYYk=-I;$D^=Q0@zUiy8;AVKX#o_kur29EEjf#E~Q#e(d9hHTjNZD-i+)HYEhQP?Q~>?nX;CW5XXyJHWK9SxoKZwR{*mr|)K#^C+hk@X!uZ7J-ipQ+fr zr}HM+y$0E^JMB`#ZlSgzyW0yacK0n5b`xo%*zIV`l0NMEpxr+4t|e41J9fvL-E*mA z_kytFQP?Q~>?nZUH68rfZA>LQ8akz~3A=cgQax8pa77vfgdO!+irqsxZ<5`3$cEkL zZ4A3xv<=y{_{d^+`2u0rnKp`Dwv_Z?R}1a-VONq8%}!d2RT#cfqJGoBybtWw6tY_; z?06J*N&q_wV0R`GmfyI00u?DkXYH%Pu8m8nqbnx5A`Qk0JL+dCcHMQ}B)fKy4ZC@* z4ZFtLhU|XZWU>1@Ti6|A4pHoGl#)K|KD*zS-72WuamUtrkGp2~lilmWjz?jq1hAt3 zb~_Pt{n+(GMas}ge?{0OyOf5y;s{ryL6)$i{%OVTB%L?O?yrxd*bTeHu=^RGN8SUn za-+pAZ@#eGNE^j2K}!0tn|+@zyGc;F?ATgwcE8+9b}NJ(kHSs~U`GM$79!~Sv5P}R z%FyYxOxR68WjeA=a>aC4q`{lQj{4b(U4hP~2B0_G9q`CvYP_gu=}BfVK-jekX`5X7Q5bagjsn;x%iV zNQ1DjqkgVpca6@QWOpTG!|tVv4ZC*QhU|{5v)G+7N7%*DMzOm~O8T(-{vKa;o1k*p zv9;dpF29HD)(Sfwg`E<>jsn>IjG*hsZa6AZhECQC!miMzw96HXT#*Jfn#=kQ(mciP zOr1B$t_Ebo?v9HLyT3kEyvS~2p2cq4)57ix+9-Byq@)kKrFZ+Xn+BE3j;-}(_xD|7 zmoMyi6n07gI|^X;8iKALyGE!;89IZO3cC`QQmHG(;MZp&>pOhfT-Z@RU$NV%^CsDS z0@<*;q`6`DzP2H|CqA&)Jv~d<&8LlGclbh<^kH}VUB2x4L*=q#cf8r<-AQ(vgdLB< zP6=Q~0qn*jT>G*6@lLX%p;K>(u#0yo)pNxJSENBe*ioOY*e%p~lk8?fHtc?HX4p;9 zHe}att;KFgmarR68^tbHO8T&Cfp+`EyLhNvcG6nU_1$B4klkis$D^=Q0@zUiyLL!e ze(YYpgY0PN?8y;!ZCpwnT`|!WX>hx+qy8Di?iQUl$?iJHhTXeO4ZAC~4cW!LZ?QXv zKRTaTw-Id=yN9Ku54+#S`Lf#qmCKH;^&WS<$C2GuVaKDeQv%pg0K2~sbp6=fiHek= zle0MTsBwL-2VjH1RpwD++$f8B>GlOWaT4BHkPW;Cn;3Z2wGH8YzS@HK?F@nUL%xC6 zT}lF;*GsqG9xL#?Ub;OWD!{AsrQ0WuCA>m`$D_bg0^m^qyfuirgy;3r?MqORGIT~g z7lGHz3*M}X;qB9zlkj#!Ht@PMHt@D+8^W8LYr)HzF7RHYjT(7Xr6l0V8!WBgGfcf* z;EBq5@^ctefLG~jRkw~Iyd46MM}emVz@q?oX$aVaCly&wejXe{crpxcyS&|Rx-h_2zg7P{t73c6ObQRtqOl0NAE9qo(m2dFAXH)J%??Gbc53OXeK z9R;APfrRCU?jcm844oAVkSmV=`vIGQQhh(*VlUDMd`RnWVw|M&EJ^=`ykSTWYh+0O ztn&#;uUuu3&YLErH_}FtPLPry?e+bD*`tKCsH_=23994!en9wE(k>F(JPK_kfHnot zeg;vRw52L*j-QIEl%dn}8PLY_5o=Vx$l*80hQq+~42SQv4LQ8F(&F&$6T;zr+9(e7 zq$D_aeLo=cR^j0Fb)E@OxjEMV>pVYo=+qDfx!?SN$ zqhVQwjD|O8qejCiQqpHuq>b>M6}Lile6!;7TR0xVG9Gx8@t_2Z2MQPuL1YlWS@G8` z91k>fTF#SMu}`NYa@Y;oaOl#&aM+@4$YJgZi$l&-;qW4D6o;x(5*)m~2%U-+Acc9o z`)L?d?yTUz@?Lpvy_ppD3k4p9f)YT10w|;*8IXchWW|PqH>jiPY0K1+gv*B7D3qXnSg^+o7GP`MO1QM@U9bQ39* z2n8O6f)YT10w_#Gpe6;cFG3gJL<%%?66Oen-S4Pgk;12t4TUz+7x~WK2ik@dLdz`* za~=~4&(KCu__Lm-;Ppl5acBW3czqH2YN%WaocP`p@^2)C!$N^ap`Zj%pa2T@B21Hl z*B7Dp-AD>Fbk3PA6u!{;j}!_Z8wwXoUxdPY+J+Q@Z&(zbdQ>RPrj4Rda<-=6l_y4_ z1)$)SCjwBp6#VnVn&G5SDinAW3Q7P43ZQUjLq)+WPkcX|6lmzwc{&nS@q4WZu+|%7 z#`}a-iTs(d^K{ZAyeA@EUu;o9qKmuhedM zTfrc_0gw&66?F}~uG)t1PJYdTS7(aAt4|vR?*S>{2p8Bx(@(kK2UyhfO@TJ#= z<%c2SORo(}0aVAgH0v;g{;Vnfen3Dc1+O>t3_(T8(8fkWP#LW@D9fJ*R24jzSq5fH#}&?~~7j|Nn*`JC{o@(#T@8nW?b!KucZ zgR~93nXuIIW{Zj9%{H`A-kc#NeIi`UK;H&+TiHNdc=tP~cH0C;=2GfI*zmaND7BDfmaYE3YPnCPINnp`Zj%pa2So5oY}&+*nkk44r4EMwUzsWbtHe zyDs+$D0=76NT+_nI}@^j_rS>p-bvbq@IHIag7@`(0`Ge!PX(`wlmtAlox__01fJK< zVGdN4FMn$eAiCy)jz>YK1fZh;bgNHO=)86gtx%0JbZ!ks(5a|wq3i8~j>bT-S7%D1 z+XdO6>s-^I+pKMfZqBn7y2bYjx)*4p&{dI=K5lc2euURj z;PEK%lmK`X0PkTW1dcne9cxKH!lR+n^f6F4{=Gx8%B*eNyx7qd6J3!8_rMlERscy* z<4viqeyA&sa77wCBBiL;Tb2o~ev&JuyCMx1Nh#`iS(wk{yZUTb%yC5;tdLUF%RIuC z#ntD!V!kWVV6&8>US7L}@7cNfU9MQR`En4*OxuD;Y2WB!IeU4uhXih8^- zMb;^k8HJ?Zn;)aCWqj*}ye^V|)SDD&==}4rP*|l?Cn+q0Y$(){z6gbE zZ9@v9=UWuU-zgMQXrm}>uc9e?7J!1+Me>WFaw$ykrLZuG6uJln9)*GuK!E}% z^sk{PcwHpVPa*{xI)6MQ6qf5OND50J8w#<~7oqU9wjqU^=UEiS-60h2p^c*ONsOl8 z^|sJ%XaOjAy)CpcR4#=qUkY=3kwT(S;87?j0Td{JLhtH|g4f$Z*YqL<8alsC77EK2 zsa}!7BFKiqv19*6_Ak@54JizrYf%_APAH6}jiT_Olw^GLcw1;kv;Y*m-WJ*rDwo0v zUkWp?B!yl=fk&aB1W=#=3W*5s5*^tF>*m?2D@lQdj`N^UShCQiFb}e!aO6Kj;c;z4 z3Ipd@6mA+T6mF%BqOeX%fz@t!50w_=b zg)6El3R00pVR=tdprP~QB%!cK=RS^wEXan!p??j9bZtWl{bySguD@L<+(;WmVYQS5 zg^ozm_AB&Sq6MHJDvQGDP`MOJd?^HbkV1c0FbqQzzD0p41i-pRi;J=rh*qsyx2?ZX7f)YT1 z0w^>`a3=+?t96UIlL8H$?WvJP=UHBh&X0T+oq8{Oolcm9*9WqJ_v+sUUI%SMcqe69 z@J<^o@Xn--f;T}*0-o1i_Q!4l&ucHc8LGAeBbW1){um>dh8A)B%A9PU-?aMD8C za4h^a!x{@!Z8?{IIkbapIL!OYaA>S;$lqhI%SeVE69dI)}Mw#Lv2F}PNqfS@GU~&2$PPYFhoj%g4YIQ%N0VwYXhPZ0Lki!9EDGV9gu<`P9*RO=DG3T* zDfWYoLcuG=E`iFW;GbgabR>nlgaVI3K?$Hh0Tezwq9}N!*iNWO89Mje0}7So2_3MR zClU~5c~J}=LOiCJ?TR_BNP}L=c7^+Ct}EudA`PyCEgm0$q;pE4tKa2{MXpGLo1_%= zx``#OzSI?C{xPkk!JSfydiTlCIIo-%gkc32wGKU{Mgm99&ydZ?>HE7GIXkrtN6ykG ztdX;PxQv{Yv{54`UP@x*c;%Gf`h!jxVR|x{PCIf{Yy=W$Y*cV}}C9P6#30 zFQ@!_8OII{olEbM8C0xuB{_T#*>LE2&~W%n+mOS;$1M&o4HFKp(MEBoDJ8+d>*m`- zXaTov9zTII0xEX~Wx>VXapd#%q>v&McoYgs00j!55JX5P1+T{o{%TJOG;~_tDHQhU zOi2p6AsY%^@MNTpBU`i$Da_5VDCFEA6keo_qEJ;zf`V6OO+^bp!7H;4gUY3_!k5C< zcBC*#DDWs0lmH48Kp_nwofNz>>%n%UKtre59YW!IoheD-3&@7T<-ZvU8?_B7%$#ab zSTIy5ET)a3aP$C6f`V6O9gh}(f>&l81eHsn(3iqTmy*K6LV-u2paf8$016Wk(n-N9 zvld@U3N&;Q#tDVpI#ZIur;rVWHqsZlsP%!iA%#%TqA=%rq3{fC6oo&3)fBug?TteV zK*8(M-qldK6d3-zXGDHmQb-pHJPHLRfC2?jxc88v;B{$lUt3b3p>xhyq40&yl%!Aq z*-*Gx`XUtG(>A0Ke9WTo)DWRCn>LC<37)lsG`h6QxprKRe_Q-}M-YdB*^hqvy!!mE0fy*|+H%-v-DCm>`bQFND z4dOb{d2L=_Xiao9bavksL04aPeb$ZG6+Y->>45kD>pV+z*FZMt-u}g)>#l8xu2#B* z?yNzAt^sWnx=B*f2VL_*pYTAbA3Lml1eKSzd6*0LfbX}z+&}~N5_O-_qtpuH@ ztgCKwp~94{S=sM))@Vg|Spttofu{t(qX2lhh`WR*6IwMCRa2@|*IKGv7 z;>%rL)^o)KSB!_)4z{?H3P~?;+qn9Uu9)bGG)RfK8%MP89>EDS4H7Vpu?jAN(}vKd3|el}w$U)yjDO@G)LL-Uhm z3@xIK8be2ZVo8i4uVwLFEo2ONEsL*(>iCw$>o4Xgnj@o#M;S#*z$l`CQFI@&4@Z$y zWsRbrF6Jnrq0?Zbq`w_Hosq+4$c94;>5ZhnTx~-RQy;Q8%)CZ8%%P3qaB!dI;I$we zjTRt+do2jBg33*Q@o=&CBH;atNFiG&@F*0N016a9;Vz^RQt(<37F|RNG<52Y5DMFL zULu7JkPU^V(ifrdwzeUKM)M7CCOv3T z2o4Ym(`ch8?E6tu@LCWKMGHW|YeCo*DwjgCFNHTRB!wKIz@t!50w_=bg%Jquq~Nt6 z+;Jf((9k*gW}&cQis}_9ybIY-s4smH3NL9JQn+uDMIo)fPYPam zD$Q}O-W&y zP~cH0C;=2GfWjbzcT(_L7H@7!3N&>79UfVr4E9=}Oz}xBdRaUrO~D|%`ym^6U*W6V zdY3&)+Ynys2P}A3^c8sBX`|pRl9E1ayErr)@Vu7AhnoPN$1jSnMz><}d7u{;8Do59)`-p!*I1)DPW2RHF=? zCvJ$KYw0!WmiwTSwHm%3r&BZ0{fh);(2e-cp!-!PE}~m~zlCm7A3?W;HVR!cDd~gm znG1Z;Jpxtb=zc$+=vE0j9tE8efQ|ytEk)GzLw7c+QHDMiJ=qK!gVyoV)$&g-ezo6i??UQfkd2^FGU34^`Iyfsty zodm+m6?i-fJS6}g1;87FU`=>lPsM(nKzKBC;;xUtYveU$clf}Q=#d#aOD90W%Yba) zg}*WIQnd}?^|;r9*FQ<%T}vAUZ@HB88F%NS;Xcu>I#gcN%0|1%jfifopyN@{DFNsx z09^}YE5C8KxDnCO(Ak0fZ~~jL5}@Rr33!(Qn0F>zF~=2YQ2!Ec#;BJGj@!zvKGzlV zU6BSYq!jgfGgj#8ce!GbE7G8|l%n3f+wh~;Sm+DG3bs`lI+JlMJP6s0g+05?SQw{m zI2JA&Z;ge-D`hMs(MFAhB~lV&!E0Mp_dFR3UfZg_8*(hnh*w+l3Ain!7f)A(HmmU< z`%bv}j)oi$`7$1Ol<}Yhj0XxZYJe=l@!++snu)5Ep|j~aSw5wus(z8fy^sxu9lH#N zk=lkFTHRxD=-5*@bft~rus}+JgV(m|RI~td!fRXg`?(TOG>0s>*n1H<`dm`jBoufQ z3Q7P43ZPII34s*6wpAfiqzs+BfkI)TPR^uoCuBom+fGAaxV9mM3-7ilT-rk@bfAr* zFh@#)f^2E5w{6ux3qZkZTeZJIGzCr+ZwfazAcf6Bfk&aB1W=#=3USB^q~Nu!3Zf!q z=;U526zI((04Mh=D$FrdrSf3OMg#wR4K?$Hh0TfO` zsv-ri4aG!Mqzs+cuK|S_bF=W)?Yx{e17dRdy{ABECyE{lyomnx(^-*xxrZ2FW@YFsyqar{1Vm>hLgxU2F|r|dcl;Y)mSfx= zRTu~r2CC!-suTv+7o8NS5)QPQ5C?T)O{{%jTadB#cuUkqh=*+jXCA>bql0|eB34E? z21~1?)QX7JQfuTg6Bozg_oiZC$Ex9pSvrT&a~Y70=fa;G&!uV`dalP<%X9s^i07`Q zjq==bDGAS&B$W5u`DcsgL}hudI#d;Okmv%L@yLqNyJ$&b3bj9;uB(G4r4 z&`0Y?Iy?-Y;4O600v=;hI#t>|l-`hc&G`dj)-k_}tHKBB)`-dFddO)a?TGzWXBzr! zJ7nXt_S=om)@vL3Y{nR?t=U(I&z_}?^4Z^oED4`wd(5`G(E!9`QCU742vtSVNWKXL z(3|RT@)ZdS9%JIBzKtFQKhS@?h(GWOIA~yeHxdNBA{AO*`ClDY7`x^+t4kktvhja| zPw+xEsglRz#=o>I{_&_W_blRnu`gOIbGwRiWU#bm+~X%5=%E-WKt*2~HOsKWpi%Nsk^w?l2y`^)utq-*ir)N8cZ9b^oJ|;?YlNqdeMN zN;1EAcy!^JD!+Kd&vdBVm1opcGb>N|P8{4+at3`G7Qj5p3{wJT7zG$Tk1$SON-Hd1 z)>18Ng1pfbmU6pW~;IG}R*Uy!lqcuOFlau-p-nIi#pubA=lI-n}CTtH>j za82SJ$~AOld&tI>^FKANY@%)G%92|xSN?OkxH5(|%9S@sNuPjPc)D*ueFv%vI_L(} z=(Ut@KQ&ytz!Okr#yOeIb`F}(?2#IeNNlZ zqj%h5bw9P8cyuytlt*`NVM(8W+V?cyfZ7@=H=ss&v|K=4d@6liRGfWAXVHDuY zWW;s9fV$~aPIwwRN3LW*ZEgircZEt##R1h`p;l7DtWbUJA_4UTSE#?~Tt`>_2-&!@ z_h#eDFSHF^x%ei_m9MrHSH4Lb<;vPp(kGx!sqGt3M?;kO>w>wr4{MvKFeHuj9p#V2^NnY4gMnbE%f zQ~AOxp!P>Y)C%>n9uiPHk5YBhXRRR{pFRDN@mV8nL!T87x7zw=Yw_7XOpeNDL#3oo zK>g$t-+;OTDmS1;t!MP_M@0ha1*dTG)f5&ynt-bRPyv;Hz$>31y88vx?owfFJ-bVd z(WSB*giiPbZ{U(Dc|30XRzUsqn2=0p6jAyJ-GBQKvmQ7~J?AJ+(LnikIYshSDB|~O2ZPbuyDkXg)c6LqQh@A$N z8?mE?Ou2~tYYh&Xc+kPy!*G--tOQJ93K%TUA#wOc>@!f6GIaWMBkh(}#Adz#au`wL z8+PQHg1rQ;q=Z=l``Se!_6aV5yXs_0SGI+0Tsdchapn2ihOYeeddroiEyR`o-fUbs zOiKDh>`$xvM(nqtssx>i*im`8hwl=&y*$}pN8HV$xLXNuHwC!+%>w_3-B_AKLuY6g ziP%!Fj@bK#SR6_&wnIjBkim<+qy;=m$nf=_f5cu88;RJ3oh4$2bk?NL(jXh373CYB z-K}ltvrcwfd!emZ0$)WNHT_D%uVBQc2NALP zPq4IVBx1AcI%0EbuPDC+RuOwXzIcy&Z6%dPY!%v%BVw!2USY(>+e1+yf9|CqqX-hO zR~2OJg~a~~GQyB_vM7PbU*{;uC^d#hjbY3|ZI~HbP3KGw!qQ<;gK&7B8H8bc9{Ksd zRo7V_TX&%h!cDYMgYbMQ>5~KIRQ1gP4?^YUfT%%OE(bVOI1HPh)4>mTl%Svl1O*Bh zehW7G=YZ2tl`?d$>_~`hFbo*;%U@Tfrs5o6ui7gqVOH(Fc99%#f~)pUIz7{stst9t zlC{>jvZ1zNJaMkITzR;uxbnzQt&JyGISoM&mM$qe70we@!2?SL!Vt{w>1%MMGi=!jhcQ-q@+&{sEY>p zwj~0RMnj>LMZe<$#b>7<=nA7XG^%+xUa{1aE7S zDtSC^{8kP)8#SsNFrYni06mBtz<+|J)gn27W22tCYA^WzZ`ICMKd4o^3hkb&_JKNQ za>(?CY=+D$xn{^*u5CDEs$OmJJ@o<^GH1|64Vm#$(kEj7a8!njTurvFoE1RjM(m1K z?H!JC(BO(WA~ugQg_VFQOaX%>{DFVOz7bU^LuVGA*eb|q52r;(Y~~C8jhAv&6m~pU z?Uj@;t9D(i|E(OWKrMwYTnP zak!$99Ws*fNhl)`CkTGPqlAn~y5|+K_a2Ev>~o|Yv0vz{NuL!!Ha@%f9pkh2v<-b0 z>}$34sq@5VvuUGzRi*hu#iQ$K zqda<^l=KOxv;Oi8s1HEp2Gl5zmRkb<^e27VUjXwcGfWAXVHDuY`H1U&mqBWwDrM*- z;!-|deFLV^0hQrg1ypKIYzbUR39|(DwTlGQ6I=pcu5%q-c`;<;${BANSDvG7=*pjZ zTdq8Kj=1vA0mhZrNlBl8`q3Z00rfSgkgzI3cLGb`R`S4ovbdW^akmoSZVGVsGQ@tm z+w0MabEP>nbgpetZVCKdlEuNPZ_nss_yljjk{0kNGrE%Qc?Hzjha&-X%f+$;eoQAd z`s@M7#%H_VG(H=nZRoR0?Y4GB%a8r5Zw1sks8I#f zz85i|(t`-7{3lo%8@&Xs>Mnu*G)v$j^=L(Y8D39eB0>0C!w z?uKk!+2wWP$}QT4uAJM$a%E0kapjA&QLd~iC4B;FYKd<^9R?NFjuoLhf$Pe9&f_Jd z(c*3%#obDPyD7lk*CY1(1=LS|V{>Te#560nLYT4GXs3*8WouhLdT{#W1ab@vK#+8$_4PDu*i{;8|;>DGNXro;DmX!1f zs7;D}1M108;f2i=p*w*UYNkB=K1tloqqtiMa5n|GyE=}I%KEW%Gqy;?6jIN}6U|8-V?Lj9JP%o5r#1`qKMxX6~Y<$+?MdPzg z+J-*My25Jf!qdcOIkZte`}YNw^a-dF&;Xwm>R_ncfEu-)u~w)BVNAZH^k7;#Lg`DG zG)h_oDKjY@o_H7$-7koigjq@KmQGeTcARP>{{^3flBNdJrXDwJD|}8xU1~kL<~)W^ z`U~Nc{{%~G$30#bf_l{VOm{t6SHdSBq_Eec2^|nV?MHnRbTX#@>OeOBo4C~YubQ@@ z{|Y-=9sj1b_^*grMftC*l=KOoD}MG3pL3yd!)KKL%B@FZf2Ieg1=FVC*COS3NoLYC zcy0qCw_nJ-9H)nsb5BFY%U)myhsQVtDqgw^P--fUm-Yg*k`iVC>T4H?mnXOY9j#Lt zeK!=c@!k8+8{Y-A4SiRqgXOzMwZwN#Xrp}hsFd`HmxuTH#>?GM;nnUHp*w*E=x{!s zpENy~HeLLSBm6rZ{`~>r+%HBBVH1+3J5S-;K=^iqq+f)Q2hi~bms=fgc8Wb)yWo>h zQdTf6OJ-{&J@E>SU+s;A#@fQbR`aeanH`U|0v|HwnT7em0W>tH#lLnG>i=ys zVn>8VTygA^!W2Hp+h&NJ*d2IQIwN z&^Q??H#A21uUu&S<$v_xqF~x0nL0RP>MVliUPe^*3ylqMdRRHv)njN3fL(NGWF+R_ z_|XDrDh`eIQnHc~W+~}w7YU6gxRks~=V$t^D`exloJGcWt+Wk&cciW5yK2?NcPGMoR1=E(9&`3#z z#$|9oZ$x#!(75J135~N`Titl>BpdcBd=g4}J(%|Tal^Jkghu`o zEIl>uaTOZb(KFmtV}IXOV@@Z8Ml3(egvMWVs-pkCgKYfQ;~C?>ZQ6$ZTX2ch@fWL# z|6Zky@?Q-p=@S|!f9o3>Z-L4UjZyw97aBj?Ll3S9rmc{vgCnNS3V3chqOxCTjKS$) z<#argp|QUe8X1XIXr!j%&}gq3D=A@CjlOn~(0GEY#!Ga5rtdC*YsBoXHB6KIPYHZ3!=95+h(^iRpafE+Y!N0E~ za{GnG1U4aQl{55o35}9k^{R1S3#;QL$NsY}lvM|cP*QF%Emvl1B|QPIavSQLuOp%H zt9S{GGcQ%O(mg@Q#yvmHHSW1z+t5AT?N;_hD{;%`8rmrLye=i-9aarN1G_n~)&|qon$So|g~qjTKnp~5ztFgNw}i$?7hAA{|Jksg!6%`l{9s!C zal^JkV>{HPLgP4mdpjs2522B63znW7361Qi4vn0%xB9LcJ+DW8rc)LDw-K`OU$Z&J ze=D^O{Ws+ztK(1pEB>2F8|A6!7Xq*NWZeCY}?gUnir^GTe zZVskx7XRW1|89nVXCZR?g~nJmA!)PIwYG#tNv%3Ge%#FJ_?Lg%v$YtXgp#%f)3(ZN zt)wSjp)upjNN9Y&mW0NXR;pIIXDnpno=>ujdxmNox~GZV%GPKTLSuW{DEG{gl0Koa z8XDje8l4@{p)qRJVTH!wJ2T+aT`DwQeF{S({e{rTf8<)DyK3YQXXw`oO!QwhUV&9(Cu`NXN~bFN zZy99czgjbm|FX3W{WrRa)$#H8o-h2DLL243?N3z@8hd@=8yYWy$_PktU&^T?oZ)m(5D*Rkr zMd(go)%Y8JiaC_DCz!TJ{EH*}y9fS#0Fm1-H2zXZ|L$?{&O~mgqgRb@o^N%0%^&t` zEyO3Gq@rM2k<8Xgdg2ut??C2SGCeT10WmstjIL(>8fq$o|ElX)syEqvUttd;~#+8fEC!{v7 z2iH%7$_XxwDq zwx*`y&}gq3D=A@CjlOn~(0GEY#&30+qVKjtHoj{=&G>G;wxRE4G_-t|eNcS&ENztU z{(gcbeL~~iTYW?0K&bF@kQJdjfmP#)O_}#yRI&9bb&srj(tn@8FYA(&1p*VVSL!^u#MPUW58oXw2Y3B{Q~LV^u5Nb17uw zp1F@3_gtWD=$-=&tX3ZRP2BSzGn#VGa4G2%8n=Dy8yZ(a<%Y(nRfn}|Z2B?5mj=^H z5fGPRekkb~NSR5caKP7y&3>WrYN;glLc1H6q8nvl2k=QK>1Z(R=yAigLgNoxbZ9JY z5R_quxJaJ`OV5mZycGobitLt+Sy_Vvp?!hi{`f#Btu%m6@D+HyfH4q?%{T{O@g89O zvt=Xgt_wW6KU)H1+O$9@H9a)${B<;l!sVa7iPGPMf52GB~kXzDgK+I}f zN5LO_$=;!t;^uFNdpbX~z4`jk=D56k{l4&ay689*t-;#ydDY@m)}`ZpY2kr#`nqv) z%8zhED16scnT?$@-(fofnFG?%gK3#_<-v_QO?re5V$~?~0oCW_;3V?KHR*eJ-DV7j zPRCcYh(*zQ{ie04D2f)Q=_JPid@tlY_LBT|1kC^*sckrbFRO3$C>?KLL2mC#8#RCz zNJ$Lf`0i+N0Eeg+pUM{3SE`$-a$EF!0a_$C+|R^6=`ks_AN_z#(qZyItAeEcd@&hw zzJF_$amIeUWdI#Zn#T7bAYhHaqq>%y_b(~ zG^CuyhsLI!j%n@eMs!gR#59dbkBQ01kIM+Nd}dNsW@0tCv!94VtFiIN!gnANpTCjv zl<>`vJ8ew4SlfbQe|&<+17nK1@{kg*HNnzjaT!nJBQQO3o?=QL{0iClAo(%lgKxD> zFW9_ww&jDPm<;g2YT76toFyew&&taxi~p&QfWJ=OuCnAO;Zqq<&L`l>76yX(Rl#VP zb4z&^uSn<t24&J3m-XU1zA zI&*Jb%bBgQz=JdQGoLAEUL_^VJ9GUeFK51nPn9$OJmYMG7sV0u)r|`9&sx?g$hogy)zQ|a2Yzn)r zrY-J4IsrAxass%QkI%E?-b+rvznrmSI&Fx1tiICQpFfeHK98E&H88VN+7;g_C}sqz z@oX3$P1eYdK!mn2+Vy_qUu3JjT6F;`T~XXu7pSQ}ZN5eYe<@Jcqd@)D44!Kyqn~+< z_Uo3R+u;Uj{~qH$WYXQT8=3i-8uQE85x{;BXJ4V@R0aop&VN>n3B?zWR66}J`+fh( zI!6@~2FgY09%u_4dLL8VJgc}$7W6stPB{L9|2rp5i_3Tw(YpAQtl}D3#not}Hb|?4 zS?s+!TX9_62HA{@&FF$27lXA8bHPPtT0=LbREBO_+Nh!Xl$1m+SOFAvE~v6Wa)GF< zT=3KS>cEG-gj-@{MaBUB-G$V!D<-vLcYBq1Hlbdf(NR|XI1&xDPuzXuxjuC!XXT+ ziJ^Q}EqI_>=-_(iq|g@R@k4>v0-?V{2VsI@)s+SRtcpKt=(F(eDpaeQ;FfHYnQFg_ zM#@@5uK_ql69Q^@UI>hV%)y)pm=N-c-|urJlVxY7=b$U04Yg#&z*B~@_=)P=qnolJ z55Gy4K3F2P!4hd#D0K(C7p$keM{iGroVP<~{;wZ0-o9Pi41rDO(=Bg5{-=2RO4=xI z=Sa!a=9z<0LDH@scqK4g!t>^p&?Ow4(ynmze7L@uhh0LCGLhoDb+Ss?sWTqi`Uzyy z)=S*BzOQXKGH1qHZTOFRM>v435B@Dt-fNt+15Ifnip)eN)i9L|OwX(q zH;cSIg`sK+en2Ef*m-Y(90-`B+%P#v#}Z-6abjCWzXE*=r>Vl|Bs&i?xR{0&f)s2EI1sr;t* zns;2^|31On_w%BBAGLd3hTUsUAT&5TG+<7DJg^)nND@QzDmx~%W?%+Z=3G1Rp`w%v z(3E9rN0f3FJ{NJV9C`%QD#yRqG%1I38o@BzqLAe2-LnGQK3=d05VA$n>;Ws38U=WpsVTa^t(;f1FtNU#_ajIB}j6Ire6qNC{vd zWCP%x`wf7e+J*qmI@tm+@_+z1k2VUxLsAj|63_vA92`I_1OQQ40KQORa#~&W6c;*uCbN8c2OgDtSEDpGId(!yE)(&{HbcjpD8ug-66_# zwz5j%RA}?=5^bK+-jv-x^QN5snS&9D`ZtLWga$Ri(xqCHt3pSv3YDzB2eyIG*Zo7^ z^$+b-vvfW4s#(K#2emGWED{G02H63}@lQ3WGfSmKhrx z)#)Qh8m7}X-fcSV=w!l9e^AxxbWPRi4{4)1eSwrjrvo0Hp8J+`T2xl2Cqos;Oe@SB zFeke2SB2z0g6wj++u}{$)DGd=V^yb*VnxWD!v#A!Ehn}*eLhYsotBF=a6AVR{=xrp zF=mHcwv~KqHg5={?mdij^e7OD-BJa8#P1#AA7hsgN;`@LAohiWu^)_mSErwIAiqjE z6CbM!1+@@lF^ZZ&ldY}JhdfNTd! z;N8c?H~c6kyPYR6rwjRbh=~j z8$r%{TaSXr5H57@0zmN7Libae z7V=XXA!yVb^>5_nrM`8^*(4xCgZGdlHgub@aLF%7D&?TYKr0H&7=Riu=+q^_7Sa*k z#=R%CtE%o~R+Bk+k5rGxFl*uO&4B`*fcu(!B;$+K5YE@1I`Yb0T>sO_mOi@^a$b)1 z*|yt_&xUIo`mDphme0DWn-(2tqeko;DG8tL@$gxV*TrX|vV6AxHJNOlBQ#Os;d*sS z%SWrEobnOSyFMz6;E47SrY(JhhrJ`8(mDB2J{mpJ_EAE_N5#Cm1z#kh4Ez!*IQF@G z0MA~6Qjjs<)WB1N?zU;waepjj3&@?SlQ&6Mft;7FNsmT6(zD~B&UGaH=|2|f9Y-WK zd`cTd`eG>w(tABfKl`eX7L`T%F{q@iXm{)D+-cELf|2xygF6!cp~`IubJM=$P}){RD!6!XE}D_SoC@Cb z!-J6XMrc3m8EyP9PTSlFnD>EZ1;M|rrk~4cE6=NDr@}ogi4;ku7R198h4Q@+9*FgASDsA>h&o<=A0MBPolE?v<<3tIp5tE6W%d`cWl+e zTnCE=GYz(+bnSx-Ta63%R)pjFQv^<-liUa<PHc+J>M?{;)v( zrEX!A95tW@NJ)T7^Z=Frf`Ag01?okp6sU!_5|ljem4fwNX-o>%dwkC8_uCXGDQXRgjNMG!IO&mXC`ve z7iCULKn#Gd;9>d?*O3N<*7G9L@2J3BZ9js{gmW0jMzguyRqLtL(WUkbD{5zrr$fYO)_j&9<=(sM%`;zNgLJgcqy66xrl88Hn&`b z1W;$xD&%22M_nd{E3s7=)^$;dm$SHeTEwZJG2d+!HZo{Vj*}> z-ECMw8-?IhDJjpRN$uHXd;bV(FK$q#X=sXW+DIq`L1YoRDLs@n9XIo9G_HM=@PTBY&D^50R1>vH57Py(Zi8oQzmeStE8i zR0zcR++{v}1IO$#x&Ma@iMxQvkjtPrg2Bw;ASbZK?A36CP14Kcfsjqt z-oeRr%<8Fa*tPTQt~FJ+LC$l#_K=iB*TNoMJAg!r<))~tu6@BAi>~Ey1F9~1OIZNC?}SumA7M_4@UQ+=6M~ouejZD6{3Sx==oljsIj|r zCZw0PLN;D%eZBG0T5UrwWity$dug${caTjR<)uG{uq3=R$-_%yQ7uNHs4OoHP>W{t zII#_)Szrb-kNhhdOnrtm2cP+oH&$T9wSZnf2`i~$V5@J(g!!57-_gEzU;t78||D`h!JH8HbUJ*RVcyNIP} z5yxs#jB3#lrZd%|A(0k&?T@x(ON+erN6Vp7u2=c+OyS4fV6vE{jVO0SJ0}fY>hqvjRx+YYw_o~I!Du8@sN$X z?neW4gpJWQbl0A+1?R_~WSs6{W>IiDNlDCIuW|bNeBW_83n~TY2@I9Ua<0rZ@b55y z{l@7)6py|J?)|-!t!P{z6ni(jf#+!Oj~TtzJ)5dJSMr|CpUf+n=AO;<1BDIm+3eLB zhxcrDDJv{wWY^hNtjgZAc@ZYQ_iPZc(y;qaEyTH|>hsbslOX54nXIPKHwa(aFJraM z^{`p=v+I{atZ%}269{)By=bHS^1PHxy$Bsa4N1Fj>5D9R;=B?RiJDZ^=fO*OvcJ4x z^L}Nf*tc_KihZS16kGc-WYgMKZfnZB%OyCF@Cl4Qk9A#%kS3 zKL*ue(u-ZQToAjbO{`4UJV&j*sd^wdh{lE^U!O zaaiXr_M*Ani%fN6s8Dv9^7WxskzOqG=ta&P>4m7QUSvSEZYUyI_!AHe;7KWXtO)<= zOE+B6AX=qIm$ z$ptUU7@~5)3yuD0T@E&);fzcfaRhR|uaFC~MSmU5xG2|kI0k#4ff;hh1TeM4Re z3AwwRvk*CDpW!Oq!FJ?nYoD=y#Q*VimiN9vU%Ik)aT&E$Y@ZYL(GmCx!|h(3DLKh* zgPgZihlI@oOh_24Z8$tbKU#$LtM7%hrHz_oPf1CH>iGWUCs`Hr8A&^NwSU|o}H)|4TqkyDINdO6W04d25AfmE> zdHFA|Aw^S4Z(37j0^Lqy!Q ze`fClJi3*uF7@!Do_Ts}%j(kx42bC;`dq=TjWq#ylmIqvoOcM<>Z3sG2OwUT@PP*) zaAF&D0vatRkqfN5qOSO;p*SnDnw3k1CQl}E^dq*y861{h>&!zhY=fMarH5r(L@1r9 z^0ZAdY<@4Yyf9eZs#!oA<%PfcO6*q`DG}6o#=Pd}byNx%H51NA09dfm7FW>%jnd1% z9d|*$_xxeg!cZgBRs`cGRkla15?+Nr%|k#00LPl4)o{Z$UT<9pdL5E3f3uXIi?6J74H>aDWi&){>_MGv-nMmRkHWefAr9;^*W*M#dadz#g5=j8k%4& zG*TW}Ep8RW7>}G06s?AF3mccw7GI4M;AVQX!PAUII2{K-o=#Gn8*f9-o22JPU4%nD zHj0m1?iVh3V2ajsbLLN!UFAIgA9yV zUH+{KvB*1&V{!s3A3lf^@P1`Hy0)gqHBs3_&4}F+mUOyJZ6AJ6&Smqjhk{W{-zGSz zBDNY6bj_ghr+rLLt4pUK`#o#a7}smC9DJhh*2GQS zgyDfZHdW1csbs{BV9VSX_hblBVgW4O0kk1cY}`mP1~$d`YG&+Q6*5`*xlmZv z7uh%^cdqJ$BnJt7UD`GO5KR&OZ1gavN~845~;dN>l@)X0#I%%JOT5 zwiV+^5S>|M0F}3Qo&M+JZaaCOMaoIYn|d~^!17$X#Z!3WML9rEg}HL$MGZu>7^%LZ z7WXRK;uN%?!WN6Y+u~ksi*Z?@AiN2S6Lj+~H1*z{7Tg`UzhRonQ-puPCy|ldDcqc4 zITQ&fvbdDV7^Hejhi}4jqIb$zdB&$ z16jBq77(~jvq(-W*9?wymkf_@ET-ln!sO#YB_!JfZUGQ+2G^sI00Dg*)C6;Va1I3^ z<~KdKO~@R)A`q&BFM9CZBuFZ3YF-ijZ zC6S>^(U82c1Iu){9a@9ktf(HL%57*ps8GW=OyT}=w`9OFVJQ650RCY@O#}EYP5NgJ z0QZ9M;w$+?o_>SbS?Hhos(x+hDZkUzj=KTCmkOt`Lif7U%Lse;=9g1~k5F;8PGUqc z9kN03TUUePVQoVcxnEc)YN+c@LusQ>ydx!nA_q0wD4L^spb(XX;#3L9u~#ER95;$N zJ&7XB2k_&jo`xry?l0;4k=|XvP$7F zP98Pb*Pt*jvYw>6^_tE;?ABt)rdw6rZq3v-?A9k-Iz$J|b5ytPq>bv<<|_yU-HIPn z-ou?yJ-Q_-t6K@|mMpo_Cm}K(x0jc8r z{MsYLQR49O3A(q4NeSH}jx5Lq$DvNf%jw#NIM#k<;i#pqVckd@g=4jp^zm{_RPW>E z)1mVBa@4b*T8mex6sM8#~wHmVN*12xCUePw});?zQXfL-{7lkrtqq_A& zNA2Zl9$p@d>d`GxSzf*ZD(&U$6Y=r~UFl`DT5cn z>&xD%_>8RRx4Gygis$>#+Jj3V6#MU|=r8U!;U9BBApvWdFh0CjXF#q(ZljDi+Ucf3e>SW~H@ZD+!a*mu*Rv;5QXw>OkIlP5K)XL$PhXl2#3aD}u>1R*@ zHLeR3gb%@8ktJlAN3zaAY9c;4!FHa&O^i?B1m*hupiXxjOLs%gTY*lqio(my6uC*; zu!F0&S{A<*Q0QkL!z03dF|za~~ccz<=!ZW8>L|*ikz3k;?Uu z^By0msI0lnQ0b#>NM-3KE|qhK!0ivHMMGoSC@Sev5>z@uZ@c}_gW`5kSyXmGRYCKE zcu!8*F4VZxMOWtj?th5nL?^Xa==?xQEaY7v1C66T{c9zkZX&O+SP?>GdpUG z)#_7(uoOawN;kW0sdjT+*EYf;%-B%$VG(_w&)4hBnVGZiaryo8>+xvj?3~xRJfE-E zd7aDqobyhMz6plqREz_qNsZ`Q9bcq&rBhsO6*P2d|SOz0(v6P=+v7BdQ zsQf24I9SH(FzLtymY}4B@&lJNR{qapMfnotDF0(bq1V76E1omJ?GCBu3?xZDvP^2_ z^O1yoMZPW$JYc#sf+<1Rg4qT$fuo`Wn`mSRW>d8TW`T|fE~SiG^2?HvU7!b;&I(4N z958z!YE{{1c*@uu{y4t8kg|V$2%0^$D#;xaefw4d+Yy`2_Uzk$dIlSsPi~KOU<5g0 zsB9AUy@W8VQkpaRf79_1d?~^f{7>C1_#z`i@SCd~@GqGDpE3%5xugX6Wgg(Wpo-`y zCCUN6H=-2$DX@ij*9Y*}la8%>+>?G8ItGH5c#EA3dqW|FFw`+_E#c2f zO0z(*G?sAFzZ5_-KC7j-M7Cy89r&9p&=@l@s#d3aA?{xq7oPYEJj6nH2+WuJmSMg> z8%y@pMj^YK?vV=Fg`T7$&$x*zv#mmYFg?tTkU4+7qmT|da(SIHs*p~SvhWNvcT6n% zF2rssc!}BZ$$DABU4U8^S5e0X10yms>9GY+TCabeJZDgf)98-msA)G-Ya;8IjBMI* z7Fk;(LsPqDorCObJ)5+hJ&7XgCn;fS(@~<^W2_z{rY2F2sXd7(c#DPVG;kjdoJP|9 zp_0UL8e@=zv!j!AqIk9G&Io1@!d6WykF{U|MuuSKt#!bR)x$|gB*09OlmIi|1I&)m z0!E@7Fq;sysutRc9s)%NczXjMNZFfCx<|)$)@QPHSoTCKYKLxvtw=I+TG8Fe3{o+< z!$Gpa6Ds5_-Q54*y&8bUg{4xnWtD%T0hLyxb^=%yqDpJG=XpxQqyLr2kxcEx~SHfg~B>_rj~+`!Za6chF~Tw!|(pgeI|8vIl$^ID|h;H$F7yjz{E6ThBFpBzfzB zu;pzIYG(S>&PIm3g;qPf4KmNaD5JbxDJj8Q%S#)#^$##8MYkeR4sR-;q9KT z)$1H-8@w&ez0KIYHV#uHpS zE^*UhmYGx?WcpJQm5FdgwsH4kj3S-uXQF-&NJ=R3Ru4t)!HTulC`XaoZxpAEYc^6BeIy&lTd#vGM?$4&##Oo72rG7- zdV^>LC;sIDKfD2k%yLXS8o}xLt2P8ye~uqt3-qYrIo(`W6od?HBfQ>6s;l+!*WQ#-Ro)~i)A)+dN2c`^>k*Y0wltd1rP%y4N2M8T zZAW8B=PRy}0vcl3>MI$ZLWs*C-IVrPcL4(RoIlxGZO6m-oIqzj;*@BrN#m4YLa zC6M7|8H6p;JrhVDG%`f`^D+nN20bBkD`gbvd*D+S{RcN5j{FBT0n$uH zIY^I@N+yt=4hhMsNz&d6_W%>i0@kb%7H3*h-(M->ni&7fp6-Q#ND-$9 z^o>kdi>kn*%ACnVW=zTvf0lDvZcX7+^*Ce2bL{@mJ<pq8t-EhxIMN)Q4JANBrK=EwBQ)LtOdE@|lhCIowwS9+wM1dfUW>dukFe!sZ$T%#JYrr-wrpKh?lFaKMgrz zNWftq|6}lYTJAFOZ5SMgZ>vd;5sy|I-)qmxaOd($dbEh|9@FoUt2+?3Tzv%>Vcghg zBSWsg%XLcu9Z{9K*BnF-=v(HlHANdIMfM$21-hD z_!Tb6##jAe!SbH?-gENJkq`qZi%_j3(}-jkY{(vi3utCBmHraulex$&mKI#oGAx1m zwh)nGutI}hfscRTl55Fb3(FXP7xWyF%mcx-qs(#yZw=?gj^Xm#IbR7c86{t{^5v^! zIKDv8AbcfXZV>HO8I%Nj-r9b75q!;x!_gP&h;thJMfA*ee}J8ls0G=9wPc%4kJfbr z!WB%#AwYEE+7B=6f z_dhH*l*6aSC7~kJ(RQf!pp4v}4qitp9kl9Fr0Me5MV0 z`}EL#nRwV6h_w7G5k3zN^jKYZ$=?e7vwZw&CNQ6jSSCLIK3nKN)Bt8;i^a4gEaSm& zC_oCTLK*l{yVGCHun%+{9SD}wm@^8p&}Kv&Z;lgFkRi&8T(S*I1|XL4eIjPj+5Ap68a`oV+de@VZAwigC7M#5M^h>sEKNzGoTfAw zQGbCZr70aNO=%n;1zfp${}B5)}l7*1NV-hK(zK)!EJ zohM6ONGY~-UAKOnQq>~mTV*;B)^riVwx;_fYC6}*&@y(-cWV0XM^e+tl+l`Q-p5!* zzK3P>N7=9piE=FCL`0$9>{+XtA3;xd=5khA-@Zw6=U)|>b)z#@wZupCu>Cot4ds*b zU^%}s3QvkYx2I0kiX*wjFra>DPfRN%ItH}nVi3Vgj?v7Ir3#P>O3&b8QAoOWj1_UK z#&Q5LXQWp7A>ppa)kf`9&(P+(W6HhU@7;WivWfP$?xkRE|Z7v4Z`@ z+uZP6f{4ozwnVH!Lo!3;{zhg1hE%0dkCd?C^X)9*Ai#q@u^ z2o?AVmkB`RN+U9yA~YJc`}ZhPqaszt+f!L95w>;gkf`IcMuuCBTDW!mXrt6|DrK~e zTl`}8-T&H()>KSOt#~ii>QvV1FRgD)#e!5cKBjA`Xnr;RnrOa5*rLgkI>`j?6C*>@ z>+yuc_#TR8Ib{^heu@US0D72S_`=!+`D0V z)6m~okye~fV1LP@oP=4Ms)7~FVX5Tcd;S@vhEzU|u%*(smo?rQMut>= zKi8ph^#@`YH&I5Zd>tN1x=Jr9Pe<8l9OB`K`d3u$y^l~?q*U^YRL*IsRF>k64WP0Y z9D6z{UmO4;p5IrfJb2zeqOvxX%A1+PNXbDwIR@YU;`_J`Q5D)o-->?*6J~q-MZCIs zG(NL?3%&+*cO(2K@`f;_xT+EVx$Q9i>}zg1O=_wE-ICSR5V$SlW}>FMqNdJ%+|ktj z?~A6^Qbsj(sHB9y%|a3GW|^6JqA7`T{Ox!|{VPo^+9>{Znrez))YOl=sitN|a%VzQ z|AqIbrlds2-?l)BvF7`b%vr)udWfcY!08kwcF+(+NEU6FHHiv0~{ zUYAH-zJ8|bA;D)MYzck>DmSh6cq2oC?|H-__=*}KcrVH*!8b_CG_Cg2K51L+tB3-v zqu^ft*?{wp_k`4CN-DodYR_g$>YPaK9FY16ynVV>I{+od`t1cxjZ0;yyHv&ZG{J^L znJl0xREaOsLaSL8{z(hvAB|gR4S$Vj+LRW`Y@8O#0@Ak71?LMblApFvsgGuDTj+j1 zX`w1r&aXrZ^{k-4Nv%f-GZy=8)IyI!C1OYHN%Qj^Xu4RMj2~fZGNa)yjmhjX&YdPR zWR7Dp$G$~s+I}qlPqwvnmy~Ht=GpVonoKF8{*}qR_KuiLEp-qq=NC<;RTDLtGMr_E z$vm@rdXwpZ5@QGMk>sk@R4hz2p5M=9rF{QK1x{)`O0*tc?)}>U zIQs^D30V1*z6(Y|<9QchYdj~x7aHSPV`OMN9UgRyXZ!1XfdPO8GVtb~uzp z6RrwnqA25(+OgEQQ{o?uol+Km#q%7dO>s)hCe;}%p-@_<^wHTukmRRMN%GXJty4N1 z?TS@p=D~7)C7hCH1qDuOJxa75UQTHsDiOnsE^gLH=r0~BPiTETOpirl>WZ*6rqW$I z8Rh-m~fI}A)Hh-oGqP{*V0i>lo;!Q6NX?tpHoE7<+sQz9jMFvrrqW6VTt=_ ze#7y0uyO-g!IMO_wQSVH*jjg1DsF51qp_{!@Yjf@O|dm*ld9t-EWoj~L|tx@x`ZS@ zwKb`aW^HY)_II&0l`7{~!qz-17;0RP60JwV))JM7;gEamYo6x*$CRE!N)z3}Q_Nu= zbNDCo_RXDS-rf-m#wY98m#GT?C9^odHhUa?Xaz5g{Xg`trc>^Pu(kIx_#opvyBZnV zdw7Op??cy8U2R*5pB8(+R#K+1_f0uz?Y#m~|H|Imd@c4Kpj`yZ`9*s_s=#l`A^2hWg&L4wp5-J{7&4yNBG) zeFApx0Q8p`W+cM=oay8x$S-yg>}!2)W!Lq&t1WoX#$Lh$n$pr2(kv5(ohjAwO(F1b zC|g^49&}(@`XH(!-qQI; zRaL2SekEGEX9Yuz>rtZh@M`J1a0I?I=~>lr@Vl^#sOcbRNt+S2mUPCi){@>ZGPI;l z(;Z9ty^<`ooi8p`EXgM+VM%o!mNX94fF((kV@bmhr4Rgqs9QK!?>5KAF5GR7eVn}8 z{2A$a@i^1Na5^A)0NZwOqq)8`0ymlu{uv;rtmTG`#Bq^K?CWfRWCPcarlGQduY8ge-)nWNjh(ZZjrZnoY4Z; zC)KFzo`fEyMxU{XMB3K(ocMkQPnh8o_}?df>HKj%nH6yHqZCNRn(FK| z%XECAe}ohG|ChjTWCZ`+F8-a0UmT|DUs3{p##J8pdkB7sa`7XI_@_0(KZy9RMsAM& z^NGJ!cJTv0j-La6E%DPwLH|;Uiyx&xD%MnIq*mGcihI? zzmXCAY@I3i_3V8e{i4AyDSE&a@rN4WA5Q#lHpYJq@q3&wT`5BX ztU|B?E`F54d&io}MA4UJ{JG#qIDvnA0>6&SJf4wpOtB8LqFIpge zd;N!Mf@KUe@~8o&~i~0 z#y?jO{|?#75B=kS7WB{k{43#siC;=_@uL);%5AC(Ls`b33x0$X_`gfwH!^~stuqC` z9?_gufH8-FhN5l-OWn!s;l1V3A63VuB#Uq`=a@JmYIpN1MY(toz#mnauMqKJQT zBmCWoKO?^p{>zDfC+=mJlk)g9uZdp?4@~@0ii;nm@SoQGRbDq&t& zl`*%W#NQwq@%_)ZK2jA!xT4fd75da$sx}#!JjfKXAtzI{SdYmsp^Q?skEE1i^7C0? z=2+1VK$GS$la2#pS(tYvBzjPSwbZH1P)MM>fl2i{H@SWbzP0u1VPvSv57^L>>(@r> z*EUhV(UKCX?1vIvRep7>s8XUFRlbHOoP(J!$K-3Vg$k5oH-ly~h_z2lNFISK2c)xg zKsMbtSh5^M*s}a}%%T`$WQfA=qUfiG{rgi!SzaJ1fuhI*#UYA9q8t>>i30OiHb^X( z*d6c_vGVRY?(7ZEPc=$rj@>QoN|>8tFLK;ff-^}~R3Pju2e|Q#eRsE`oJbC)**s_F zyH)>ehd-C$&#}hwl9wA0w!FL*wY&^5GUVkKHlt+ip1e&4DyL9Jd6_9G!OKDqURt2O zSa6UihnKBg$O~=;F5z7$vR^%?Bac>j3`Mii8ITgm$Dw2%^5IbQ5gm%nGOm>f!w6f1 zTfeag#~T?UZ0jPtNYCjHq>LhbNm2q~tp~!6D4uKdjB*gR7KB(ML#wO6KmqyT1#!1f z?H0(fl;Cyj7K60C44gxIpLg~weCl;zV11yyas-qFeNhw=BA?wGa7r3 zqbg79eri0*!EWDxTK8=IvlITLbw6NyC3z`9*z&UNE35m7Muxn!XRVX1dyrlSa4BV! zmzO0ac**hLr8DXaUL?xlWiLcQ@6}1xedS@aZjXWH1@PabMDlScS>KtIY>idwKx?V- zQ$+YI!WQ9P34{+B86rG|%|998t$Ox5QRglJQ|s> z?)f)S?H+^4o6rXkqvYgZ{Gt;vZi{WkU@ACq9xi}=Q-@U>=rd7!qNV?|XtSiwvaI%; zks;c1Z*$O2(_{T%$|%~ezcgseJkVZ>iU6%dIcQHu6iQe%0XdZntg&{!6f51HqsNKp zE(lmMa{zBYihy^->ao!7ZRe|QJuV|s#M@rf&{r8RMJ5&@Y?;_k@CXxgjSQJMgY`_- z`y@T~KbbPh#O5yy6SW>p^hXWBghV+^oQNpsye7%AryWAe_83BrL*GCWBp-)_tw)lC zhS=BIZ+&8X6cN6Iutj*H)Kd_yHZnvwj7>io;T%2N|1f0~;cuTCge|Xc?9*;U@jxh1 z4#Eo%1y_nii8rNB1(-0%jo zE0OtEe4o;?yZvRK2mBRb^q0PCF*h3Sf}pq zeLZ^fhRvBkAmWaBouF>y{1^>UW&q>KrvEMq9>W}VU3?1E+{0*vBtHCLM@&fjS_T0 zA1$vER~XKgV>cXA{E(Su+|&R+N!yfs9ormXcdf>@#)#P1>s_E||naY5D=)!Y`~5NStq^B~Q! z(S15Lnq@p6afA`JIJSObaf~-I#L?EpagkmgFpx5e<0VN694&8X>_<8(4vBJbv=$t` zpGHx0d8|-Wf}=9=4g|EqzIY;-TZw~})ZsTfsY8!txD(;w#lNs{M~CwdCH83SL0yJ= z!1zQKRf4d^zHPI`KGDb!d;0=MhlBKjfJ-T(*k6{Ez@G1cy)%mE=zviU_Pr1#Iz(rQ zC)3sDq4eHuTLPuW7^ok-JW)zs4$3uIM7cG#SjRw%jJG4orx3O%TPIN7Z)Aw_gfR}v z(R#Fh3}qB$&Bx>iC}(@1?2Y1qQlcD`oe+f*HnDA%3|wYM1&?8Q+;bQ-0uG!oB{K)+ z$A=K+wwMflN^;8@&Fy$o2!57JLNJfVc|_wo$;875TP89Dk9esPBSR)Sv!2O)X8srA zYpGO_+6!$h?Q6FpEvFdXZIVmwu9Dj2Jb z3^86sCz7ni$LmCkb19=3GvXLKjcn|(#-Mm$lqd(|AVdLUB{3Q;_Qi%x&vDNjcy}U{ zd>n+Cg3uZFOxY@T?1jr)^6`6kNrrsQl5Ml$l5Kbbes(ytHL+KOLknzcitiOcP_||0 zuld}efqzxGW%|WSeDK$7eu1QWjB6vQcOYDmXNFK;ZM3d%w2`?TGJDWnsTSWQo){QX&X&BnEYf%wo;;r9rcZC2qwh9{t?|*gkf~>Ue6hO75i)t(NFcPG`xhDhCII zD5zKF;X6zI27cr2$i*atEf=4EV7a)-$dHTHH#%IL`-yOI9%Yn^rz9n~Xz<|T0Mr{? zNR-3HuJ+VU+q#j+DdPJ)pI@>$1E=dUL5uFukYhRTtYH1Ehna=zJHom1I4|boDSYDb z1UHl)1Rqb+lH#29SBl~w6?>#D8$(E2nr@km_{JC?Nm@oAY-xGzeM`$FMuxQfbb~|7 z@tcK~6DXs!luAm_GW^EI{-zl!16m}?p(WZ*jP{)o$$X3gAAyotO3UTo!qCFKZFU)L z(mAAMK39iH3qC>1e9+=U$3R-7IER+;C=ODwsd|R=dgDk*#AOIuB38d=iRfo!NW{0- zJ4AHW+2j2I_kv&M^Z*P2uez}5f2W2-cQ>IqZ|%CMie-pH?;$)d6-mS1w<}5 zhnjKCIn>OZ${lKr^)n*}`V3?QsaTnuyYvN(izCFb2wR9By<;JcFfxSL%!PQC9{BG~ z8HHFTDFHF-rpETZuR@e42Vz58vG+}E|0Qy5lSO(HR?5SIHu@~g1sBZ?nEb2|1cOqApnzN^BiY zX=+n$>JR;_tECSaKTX)v5w@^@e9OX~Y-9-gz-t}#4*pQoJA^U{dzqvJ?1dh%k3n4k zTcRA;nTSFOpI?KVN@fjDZqavQVLY5$Depi7>`H-M3D|wmhY+^p=fJMqhp;PSZ{bX) zx1FQ3$Q39}o_xg(e!TvIhhL!pO$_bdxNvfG1HzW0x8AfI4KXt0=$ES&(0zZ(D9#0v5;!w&ZtU|8LGi#T zQ4Y@Lf>Vqj?%m@}V8X?;g=*eE%1#`gKw1r?Ip{)&RPu9>F3u#<>ew0{whWq6iN%|^ zZkIGxtje8+4h|E7Is5{`iS)U~DcpjvW#s+WEhASL88Y(6m5%0nz9+4t7iE-@2PGvK z33xEFC#nfXB+6mrN58a=*I7czEY4(XFOZML^>FSRc-f~gf=@8=1{gUOJq{U>{2WFe zM}ClsE#zk0609iWc!$hDWc1LaW;a~c;14z9!v@?C0}}kjKPxHu#`Dokh9Yc9S@oJF zrH_#zDN#14?>DSWNI57gk^cp&B-0mGZClc z=HQ%x+_)E{O!tBWjc=n`$0BTTepF>~jxaLB+04ax*4u)!H)RxOnWO~HtWk}9;l7Gf zq8ywJyA$WEarF6dJCsKHAsVUYW{{K7yAY@3=HPq=x$&9BGJR(8&{YY2PDj|{{Bga- zIoZe%=Yf|w`W&q1?}t!EaW0dTz!~tsc?^oDhhvn3Gm|*u)0u%qrZI1Sn;<>5cML$+ zLXeV`19Dw!f~eKn_*lx6@Dke zmWbFoOT?{4hD7W$%pqdHo1*XwD5FHYASpq_I1eHYLlr@UL^(vXKvW2XZEzJk|mERo^-u zz@5NmL;w~>8^2A~u0`0gw&7LF+QmkOto=CHVXd3qHE=v-l(p%S60B|WV67>jfHjG7 zSo@|09fEY(q|7vw%-2bn$5WC{=uSwOWaSVx2U+nc$urU`%*-fgBOOR&;57fs7qkq% zmNhM}W&J)WzkTr;ev=2JdtoFc7Z>=8uR(f%?rXdtNjei@OVYeGmZWY*h9tdtsYB8p zdda|^lu?qdmy{qW^OnY5^ON0#B#ClJT7xK*5Mc==v$!5?`@`;7l=pnl@+UkrnUee* zrbZ(_K4>Z8yvcLc9A~589N4lhP@6f0{-yVJpdu(^jXu4Pl+?+XYvYg42g22XUvPJE zl-DK&AXJ}=Y%)YTo{jwVFS7v$OO30dR-Q%JYGtq0Rx1w~8EWN}L5@~#t(FEqmNKf9 z_bZtaTFLRy$~ivKibOeD>4GT0qB>INFBATtPIffjP<=gm6Y4~Ab9C})bLwPAjBj&9 zz27#Dia1|I*y21=YAeq~78x1h?0<=a^Bz5EKbjDnZN<4ns!xCLavf})#@68mjMj_LT@b0{=OEqDj7S^Yt;2cP6H<#kAvM?&g6DjF zEAckPWk9xWh$15s%Mq@~F%L2h59-@pg@kNDUqRfMdfv6ss zkSK?VQxOIKQOhgWBX~JSq;F+FHh>k@n1|R$N)PYxIP7NhDkMa*bqM*gsSpy&*9nSb zUotRid|~tToW2x}K*3S}%Q-EJE5{FsSE8ivw&ZK+{)mZaPegCSz_##&xEwT6{|o9a z;|AuBZ7;HU!lYim3Z5V%x?(Pw@?B`$eLIBDLD(|>Ou21irx+PB{@z6nj{CNmhoM_DLxmPUsQ;iI_9({PB1HP>u`QMK+3Vw{FEacWB zlrXT4noMjxV*V9bqf?%Yy^{e(xb-NV{2Gk4C`Y^9 zSR-n;0OKZ}nC1(ct6g17N=Mhf{9$!H5h~-0uG#EV=f;WF<1C~(20vwMDf`1Pb_<0I zi>h+#X!A)M1?LY`jO1hv!W9`tr36$3|seU`*CT;yLPt!|g^%Y;01HhZV&Orji}O+*y5G%cfGU$n1j?8C73LB$oh&!i=}qqx(NoX@1AG7Z)A z(m`V$YM!`6e67w$H6zm+s3hGBQ)>1-Wew(xt@iIRGGzDYeh$0WRS3J+ zQ%2dXdfBvy{vPa}`n#|zQ4YI@Aj&|lG`-aM6&xIS%x|wke?ZHUe4Jit<8P#SOKghF zZ*wcP$M=WZ>m!b3#$yrj0)#DMztmd>LvxG_5qIzFARb#Th{sVz5r446AkOzd96)tA zEM$~}xU1B3A#I2kTx6K>93JvFI~SQp?h-2~DO`p@NBHe%lPt0k6{mrvZnzFC>_(yX zf#_k#hLqv3vEf&;5si((92jU;7>`Eu&m(Nn?=2Vv{Ub((=uhqApdbH=pr1e)MZa;e zL0|2G{yY>9^b+NuKMqlFU$f!9=EFo`rn$?`Tqf(Qz_cee2zbt4^WmxqR7@~vjG*)*QYWB-mu7jJ2@3#$n4qm5n2*=kj8Ei^!i?l%sO6h#oW6n($Q zHi_Ge3@O^5Efz)DgZLM(6pAjPj8e2%QlgV+SJ1eVI0}^pMH1yuveC*dzX2lj)vY+@a^7eW}k0`lqTn#h#o>@fAxFTRY}U~Lgk8jnf94_BQf`z@2a}B&f^Ww^Jr!Xu}`p|i| zU(OzC#j_Bq;8hB%?nkYo(-$KDxD*zUW82j}#u^t$x^6(&()HGhmaZX2hIIWBaOgUD zxzKeAWt6U&k`i>y_n@l{Eb2I!R(95DWoP(xvL@L% ztUZkE>i1$pETHx*bz>vx3H8d<8Aq1dC{6o7V4+#=H#a*{+tI z2fplGJee4QG$5vdjq!cp4TOCMlNszE!(f6gm(@b z!?+y!L9@eaGJIQ&mpT;TI+a2OVm>`Ys?a#t_K|@*u@4?1J=RQaA?xK#4M@WHx6Uzu@Z#5xmUi}jc1E!JWqL#)I9<6zxau@0w82jt5OTc^Cd4H%R}d*FQRozt~aETvFb;Xu_M+|yk3Gy z*yG*55~9EOcQ6NNvy6iy6=8%e6ElMyYs7Qi6&i4=OsM zW}rf%94cBPN~kC)r5$K++QN9y7=zx{*5?MY;<0ja61pF+zbf6cae}JEVbg3Ewdvg-M&UK1qESof7?5 zRT1guKmJ)&B(nA|rsh8pO|;cs@T1#wJ-s0ii8ntusmyxLCGeXzYZ&90skmED3t}tf zKUIV3sH{M0;;MxJPt2H=#f zc{Iatd9|#AFR8>=c-AZYELp~%bhVq5Ajn5J5(FQ{8PRMvB3!Y>IO8>B>F60~wUVi0wat*J3dSxtp2p?dZhQ_Ae}%9`9C+Fy{=mo(@ryYQ;;S2^ zp}t5NMZA}!1mcArh^Krfh$YHFd@Z6-LjRt~DZV3l7N2CqcO=&=-*+6wS1DJDb=B5+g4IS!Pptygp#*TV+C?@@WdpOKkp&Eo^JTY zW$E|{wOno-7I}LPVar?Qe9POzMuxnNKf~dzi(WG{o-)eYhfgsjcstE@t zQ4Vj%A_|rw&wNT|(VFcusd-o?PkC1*4W=g$U`vm_ArtIehCYStNZt-R@79wYridMy zE$meGRv-kv7-0*1f2qFA{N@=M0xzPAG1D3u%bcM13l&jDfqw#bBf#@KfajqG04`Au z@RJY);6#k4BBGe!nkO&@bdZ4f~AY7~)|Pca$>z}>O%=rkHB)#2{( zD7m9xYq@T}H_)*3r!G z@;+m$$rA$jDFkQ$1TX*sPK0kK0g|($`T1Xy01C!_Ia)M-pYeQzeHX$O_IHn2*b|Hl zVPD+Cf!#_k{<)Yk3VV^H1Z*#NaU^Px#$D`=s5I_k$}t3fkpSnX0M`J3GXUVH!M78* zm%Di3D*~rr?9a{u{9)tw2>f1zE$|&>7Wfn+L*T>MMw3lGa~r)$+hLSZ;4360fCoJE z-4!(eaEWsCy$_;L!tW;_r!-z*ej_jN+`eoKgM<=(3MCoBi3;_6X=(5szfw{ouimVjXdYth=|w&aNKHsj<- z$IS>^I^KQ6(s8+wAswfk?9lPO-i~t`Wt5KDk}{1)*d6ss;}N!fk;WsO{xKWIa3O=A zLWTxF1_L1DF!WC8Ji>j*Sp{QX9Vu2&Y#bY5k3-nP{`g@FJKx9<_Sq*nuz%Sq4dZOe zDD1~1Wg3sr1~o|I5q|wVtw*?-8^1$W3vhl4a18)B0|4F`eNZ}&@G$aL!PwT00z6_| z8-Y(o*aH7zjs5-C=2wO_t ze#lZX)X0#M?sQ?vPO@IF(dkYZrDT?*Oydz+q6TR^!grsg^$1sCAw4Xwn>R0r=74CV zFaY2T0QkY^mC|{Hdy%&a#_A4_j|(=@H{d=&euor5O#tZ!PNm?&( z-QfgYAi()4Ca(c#o&f+q9DPtaFK|EdR>9cUhw_LR*IzOU_Y9VE2?kG?s^y8Z?`GrV zNXJzOTRPUywsc%*WJt$x*$y3F=>0awQAX*wTT+6K9JFM2bhvA?&>>NdZ`gt;lNmJ)5+$WNzTqa6s)DidED~k-`9Kz!ef^Cu zBtN|ow){MKzvbryBSU`t^lZtFVvXL0 zq_YQQl!EIdWg17Z`J=RsVl|>XClG#|3JB*GaSsO%kl_?ZrmcC;Rwno&MA^Ijc3@gDXnMNgs3z#hW@x; zC7fFvoLDSK@d>2GK-$(I^_nGwksqXDA0KR8fxmdYTKJ8|!4dWq2wT`|XIj_;j0|CS z?c%_$(_3`9Qbu9lB`MQb_#d@tE&K~arLpiqSn&_%PLq8*P%w7y0QNM%?tnfgomJ03 zevpc7IVf(@vX+bWK;y-T`9_2-=9>Rn%)^WfG54TPN^aF#^}d`Qlu^w0Ny;=P-AXZg z&56I?n8u`g%1NNRgA?x-MdK5Q`EKnl=x)-PbQyAkRP4tC#iZ{w-iSCu2wR-d85U=u zks;0jM>{y1E6xFwQJl|9$}}c@D2h+h+3hAcJ=e@`KZqt>8k|@vNbw1zr9gTXdJ-b_ zGU=DG_Z3pHmPCqoUa?ohKLi^R!3?@U{)+QI#w(GE2?$#%KDpOYalMft760k%Q1NS> zwC?{IW($%IWBS|9~p@Z8-utrRnIp-{ua2?`zHmFf%w22RhII z@ClM;f~14dosc9c$?4qgMM;o~ec4_(xWjlXa&RlcmV-^DmV;}J3^_Qflf%LPJ`)bk zqKtCzsH6l3gHU6)v)>2Bg9C|jIQZp#;h^sDWDcmV#N&p>3xqS8k%QShs6r0#2@Yn1 zgZAi8$bppPa8QDhAQk(pop3P8xG!=r8ez-92h%MFR~i{|aQaaW2irf@@gHTBgNGy~ z?ZAVBy-+;ufKd(yKfNa$Y(6ZR0~&IIgD$tbc5qKqaxf=|^QzZ^#M(ltk zIUIyh5~N}u?=KuoFz$>T+=Q^@;GKIc2bUQca&Rh^;8Wb+cb^Ccr&2~axL;C&gB;Y@ zwS(3u9vn!N!@&>l3J0}^CUd|RoZw(VBM$CrLJrD;6U&4He1ZeMn0Ie1STcZiW8eZRAzC-)xDZx;G~r;Abg21!bqkOzIQzoRC^D2KjUl8#}ayo@&JsC*OG)|GoPeRxtpMAGQ-qFYq zc@r1;V!bG*Ndoz0k`lsQ-<(g#?Lm)c+!)K!SPr*b>^Z4?gi>OV!ON2Wb_e5+h}J9UKhZHt^vc6$z1Fgs?@vbectewvi$7 ztSkrldwOF|7G)IqL`ezc(>#!Gdqa>*l!N>OM4^U+4CFQRaJp~o@O9Mpvc@+9?TbE$ zxFt6S_f+J@n}IfEie-;8j)^!&B5ZNKJ=NkIYGjDB`ymd_dc7j2J7pB-EJ+ER3q5eQ zRGbp!;Qa1&v24K^5eu{@!>_`PDV{e2bw+nVq>`V5^kL-3n}L3i4$XHDM_8~;BE17) zi}b5IEz;3OhDiH$aF8}pr2QzPNS~FIK#_OxOd_ppd>POg z=pKmFYYMRFH6pEy`Lyd!bkGLc$uUoP&OXxV<{-mDR*u9oti`IQr|(db)8?Bq4~fCE@F!C1H$_Aqo8tbVz8bxBc{| zjFPZGQi24p&iWA44J3GV*3A(G61+O=30NEVyzM6k-3Dp!>Z})6k%l*7yYc=by#K?v zC?b6TVT*L<9TsWW$Pno@2RKOE=@mZLP)3oik(5-ohoPT@;;C*%Ifi}!qSAEMrMMHt z^B$jz(M^cLnV)0mudOH2n%F_S*T{4UwzGcDI4t6R3}K7Ac>?#nMuxa=Z13RC(#v{o zq>SQzZ3-C!Zm-U|7b*kXUY+$}h(i6mI_ue3kN14J=w;|Oh})~Pes>*lzaKk7UM?Cp zblX`kGOmiqpF-FoZ!Ptg9Z~li86qFk&Ov@;jWqBvlu_h0MFzR_q0Ywk-lz_cOO&JW zPKb(YCZ)5!wVe8{ZTwQvYte}ix8&yN`=hnQT^sAtN-XD5^eLGi%p)mi5t3YP8FS-;$hNH;fredz7zE{N2tv)=Y9 zk#3Hi)l!gtZoChXet@t=+Fj}^NY@z|B7JN>2kAw6bI)UxQKWxPGDy8T>swGfka~62 z7b7ashO5zM*fu`koo+9*ESdv))aR*2M@08CKps4?kXuUW8mpey;tmrd4c-b-^<_-Nb=GFv(bLd>1h< zLD*t$Cp8z$PZ$|up3=s_eBv9@;-^qXF@Jiy!R*zg4?sm=A6{Mh$%q2x#$9^xa#}~U z@d3vI_+ujW>e8c?L>!Hss@EB9GMi7C=Xr!JJ$nmCq301JLwY9cy}c_DLoRNjpGlspAG$%B#7&e@ zE?ysRxbWHvemaT=7hYSz4@VT5gx6N^2e1+zKhS~I7@U8^ilv-?gkvXCukGLOl@qC+ zb&81o1G59G>zW3diGlDWpG=G4|BP=V2@fM|Nyrc=LPCj=Aqm%IIwTxaEhJn=86{!; zxWDiVJy5eWexU=RJpIDRC2TDo2b+e%U#Ig6HLs9@hS*^|Q3C&G{26gBLD=GKC$$xv zPZ$~EoZ@$Io~XA0iCm2rf&6@yriB=@AE&ntI!_kaf0RiL?`s!0o*!Z{;0zr z5s8N_&4Ht(RZBsRv(7|8Di~XXG(h#IaXn<=M}#d40}Ct*Ul-5 z-jcGgeMP&;DMymSOL3Au8xKG$@)$w;ltvjH#fbe80Up?wL^8TIfyoCOj`mN@z|Y}I z82Gxt)V>+J>WoPIynT0@1kJpN+44#f&9*(VT~6~}aWHbL;K`#^OCS=>pgRecv+2O5 zBJw!WbYeM~Jl7mz6s~g^l^TT}yYR0HoDY|!1$Is?aQY}ZK5dGTKqni_%QDp$IFV5; zQ~u1*TbJl53r=XkTa$~w(8q?ywQ`j3MI}yRYD+dJF&pqpIMhZO4?i;s&bGw{Qi~;E z?ZWY%-bhYMeZd9zTt+@Iz%hJoSR$4xj;AVP7b1~R|H^6Cu84oe8?*cx&TFZ!eCYe{ zXuJaDD2=D5(ipfoiN>5kP=~+xPE-$Od2maIk(yO5BVXeeJ-ZhyZzqhjsmMdElMsHh zI2mD)K(Ywu{{_MuL@!A!<~gb~PYre)Pdyg)u*7A&mRd;kFACXBm4BA;$ZWAEBWzpj z1E9xv@FR^3eOJ>K4mC?E#Dh1bjJDXzB_(`UyD5#w-R~|E-z8Cw?^=qe6yr$)yY|=? zG!E^G&KiUy5{y8HW(6%+9%XARJTrRu^*iAJ!l8qpqKJIL{wv^I>E@&oj+;9kl~BRh z7JYD$jDGjLw$~x{N`=e-#pL#)rtIwk&eLbP zcN)hq5#+CMJDA9|}hxY~cTawX+C zTt!fx3dVZr<6di~e`ALOkW&3&VX7T=M^iCvDUy?)9J1;B{V;v38^7w{hL;EAPQB>c_h_xnvSrR z6UiBw)M_^EIyQAt=I*7g-8_z8Qg2^qQ;{7^X*F{f{Ds{Nhitl5bCfD<*o-$XWvZX~v`r5VA_6OrJ2_5}PzD>WgqqtB zpNa4{fIPrBK{mj>5Vj5Q7LZ^X;Gf1-umOJbheJxq5@~=RQAQi!DUuQmuoC#(2KdY~ z(f}pOX@Jua1;R`ZTnhxLGu(^X;tKdPV-MfscXTDZXx;bP?+z0a7YP%uQAU|KN>XB`8vqkY zmv22fAC|j>O>Z_MXplN3y^|4q@e6nm0{DWczj0(2AdNQW_fi{kk1NHIF(2GZ#~11p z+}Nu%zxL?WlwU{3?m@}Ha%nOJErPO*sYz1N9A`7K{yOtIOe+*Dmo{bpb`r7a)t~4J zxtTbLm}9AV1E;_EK5eB}|K_l~|4Xhb>WW`dZ?iZ-ueE4exL-vr2~NyWJ3a;TYoot{ z0zSvn|fcx>GAt2PSR^AAT)`6 z9vY7n;542epJ3w&Ksm8_cr02PFAP0nXeBOsHd^%;)3ktfjq#J@=4FH}H|+(XtROyV zWXR1O4GuRaEfj9J;6z6UoKpne$GNR-3PDTqRK7m7z&Rs=>OvuMu|+5KQH zttL?z$S=*u6<>dMy~V}sAHkCp=J52|Jo40sJl&2(CS&~m;!E^t;j_kZl9opiwzM=A za6-#;BSTtl_{E{6!wW*o4U|z@sxLRREc2k{G*pLE8%8;_WFg9%7B)e>7*#qT&{77= zNV)U^ODfX!NMLcc^g^go6uR5DTR_|iv-%qo-2QZD?55)OpfrCh+_ zFK!N4!Sah#3BQ0BdlAP=SE&-DXh#W0qG)pwN3HN;Yw>qV*!oyp2?wPr;k_aMKna&3 z4M=^;xIrr6A%v|G{v2wR5HT`T!iXJ?5)N1(N*F;IRl-_H2_+2oP{JvwG}?efIZ8MP zQGclf8jm!BxDxI|XP$E9hrjp^2nEXrsS-H(j>ND2=*qqqEkTNQl<-&?mB3W73x$_| ztb`FrsV$*PsuKDQPE`VzZ0YsFdE;WA0!R|lzf*KGTgEA=Wqf;SY8hy4huoTerE(ec zk!~u(^)ge#NNHJW{URAM?+pJGUj5#e;o4U5X=hjj>-R0K&n&Iqv$Vc-X?=^*`sSs0 z1PM#&YrG{b>r8~LWz7RKrbF&#WN2A?{^(d%<v~BE%i88)S)V*2mL*Y+ zWvxLJz?s23zjQE9gJOp~3kP~rZ%{ccSU!|CRB*h#LFGHRcG`~=;MmUP*;qE`n_=qV5V3VhMYmms$(Yx$gT$go!j2Etzjf?Kog?X!572JUx7 z_3$RD9sB}8JB|M%q1zCySZSUEUI;TVgw`1u68g$EhtQkn3!$%2MhR^%DM4u2w8sAO z?uUg?iE;?N1yLyBw;zxb-alZMB_`uxwCA(>g>cLyPcn1JI|7;US^bq_g1D6y8flnI zNQL=)1dB;Qc4gETtZU|fxe|N1uph$X=cZr)rte!{e{4oXo;l-(Ln+AFDrdMgz?d}d zd~Ocl;iZn-#0s$g!FV>(doRM4-W^btp?8XrA-%&09>4SEZ@D5b^C_Ws7-f{+6_OJ4 zW`!Hm+m+>Gj})UEdiOyTYF>+X3`F|whz#5&FL(eg@59-8?hwdhzYBgPH;3P~50T%U ze|6RIV?QYtVxNU@#X@6R4HsMNAtOWVSA6eaZ}X&Jzk)J~y+Tp~dp{5C-B2Z9mnaAO zeuxT`=u2MAqW5rQ?rBwn(bEvMp``u25mg6jCUczMF?Aj`y~+0H8Mmv`8x;U z@lOcC$&^uqn+J-G9=KwZ2g3d+9tb7ML3kpfXqR}sfx4e>uWjPJ?_&Zxa^RC(9DLtD zpjthUS*^en8ds5<{64<1iO!)9&8nF_bP-f?!%<^g8Ky{L)?*= zgZuQy1b2ioiaR>M;2!RQdkAU-+!E#B&OwyHZ9B_W*HW)LxU0`!d?W8zxrC)WO<}Sh>9fb^pb9AY!dY z*kbLMN6iSOYa2<4o@%}a)~PcEt3)|iMn94cNFJ?|K~D7@C* z;V)i;YVC_u^dOWvDI9+%5P#uY>uLc~=1)Msirq%E`AKBNCb><^sWBPbK4duhkoo9C z%J8<7I;5jEt}`Bz+8Bm#MUm-0D*IV&^ffZnM(3{`ZESv6w9%O|s*O7(CA85p(%7^7 zIzzM}QI0k~MU;*k`j!C=YAT(^<2w@06B}sZJh6e6&a(r2KJ_4ZIeM6ZytvnTr1l$e ze@K*L;TtW=kNR4aBaF`^%HCf&D1V+KD0@>zQI<(cpv?9_xv!#>C^D!VS z3zX#6iP2Hf`=3aAQx^)HaG}6S7kV;$JaI~H4$fzg8@EIkOFu!*s-hQQCKzn+`9l$P zt@7h-aD;TMdr2eAEu-LuPGW$liVm-b14+_?dOxYD?;PV($=zuPTkam|W4SxV$dJ1h zTO96IJS5z;pp0^NwWI`hl^)z}EENlpD2KaO5T%w;6+Ir?POR_cYh2a$-ina=-d%8j zq)jq%Xd8o!xWBqD87j$L7;l1AIarFuPgObGTEg#k<~vKja~FPzDx>{WH}IQQYRJpJ zJB7Tx<5ewLI4-V+l4+yj<%Q*qP+32d8Q)jN!;#@l2wR4Go^Ki6U}VVf6JIzC4|-4- zeu6T}a8pSMhD%W`_n}$gbYWPc9EJxY3f5VsEXzv?rsE!DGj{hEvumT%_ZRPp5axU^ zqx;}}NwnnW5ZxO2ab~!MY~nr)<2{J<2ZSxs3(m7hKQl5!y7F@e=}iv^(v_4^r0pbS z8l;hX(jpy&C=&Pmiz@@@X_To3b^F?JO)WR1PoM!L{DK0gMxW?2?Y}6P!L8`!U&Qc z!>nj`54h}(4|au@-3XYWo&XzvPXkEcpYk-E0SG+@r%Do}9EXHMQI6RJaEI)f@%arv zlF$rcOTx9emV}>-e{%{mv+5ul1s%HbiSk;BhI9q7t=WhPu z5*dIbwMu{SD0U?()v(9dea!ZzO71_;**Kc7Rh$C6D@v)W61fBx^{6O9<<$ulo`sqv z8am3&n8ZQz`lKIAN=Bi4L&CY?ZHU#eb9HC_?7PDFQfg};!d6?$dRuMf8X0Qq(2pH$ zy+1>=btq+2TazRuwDqcowzf|dZAp})tq&2ERCB<2hL;4ST!Re#p|7}JB2EVa;SP1QAt#llysqzOJ;GaL?E(6x;#+R=?%8- zv+-m6)f~g)flKVGIo^hoC4W+m!(Z>za z*DLtdUwknPyw_ax75?I98GHwi{QaThrN6K(Ath6)h?!#hRz|cVG6jzn#!Hg-mk_qR zw>{JH{wQ3s94e?jBkVB*m_Jel@J-!$+)-mkkJ}-k{Wqi%=~1;KOKRGRvgI0{)Z)M zQ-$QGFjz|v?2)1}NF7?E`zup^gk9jRjUtttvNCxqW)pu%A3OT?{?K7*ZAlVK1QY!T zzoc#kae-H-lJn*rGzs5&4qxC`X!k1+wswE;>DKO_F*3CKJ3nx$(gOu!Q}3OWQM>=L zm$CZ>l<0P(7o%7#j!Bf`Z%&gM2`3m(@%3(YEwIb7MteGTAU;^0M}zPee}g~l3r(&< z*T9A#WjMZO;}ni0m@3v?ceyO7NqQi5zR^j1-r1=X1_e1|EDs>Hkud(L6asvB29XSP zQXd?KykFI=3TyxsFe`}QTJe5t6uyDRVUzH45w?Uc=xGV>VPr^n+xH#9t0O{qTgoWm zqa`IAO*Lxc68=?@5H3*;;jbae0?x~`LE%2W!2Zq(+E)b#78Fm`I~zL+hL}wq1sB*2 z9iPKzQUg+`qk(~mLJf!6_qrV3dnh=Zj3R-*qj9w4t3AS&uiH8P#%F&&E|`cP-47B5l42xx=dcm=RGdG6{_s{T zGKGeM0kfOHUpxhMk8dp)XSWv2I78WyJRNh|4SAZEvy4b00YM?*`SWZ~6v^oWKZnQB z09pA48hy@*fk+9PDB7>eza3pQAl^Z>Ps$CMNp7vg*ZF1`A4p2+4=ts!?v~P9jSMNh z04^rwfr4+EPuUTSNj?AcRth$IOEJka=HVJzqpRv#VN*bRiP~8 z#(x--h@Ha2@h9By@Z5m zY72)-O4x$e0Ac1>u?4RI!gxf*5!wNQHput@Aq9&(f_rHj2MEQ&5DYC*Db8tFvI zhJvxf#B6;-)*hRB#ai)$2`xl&Zs%Nkn%Z#Ao60=tI1yn>$Nkxsjw6f=>By*dG_`25 z(2+qIrDK?+1Rdi%=%^_WIwZ=WV+o?H4KFMb592F+75SC~^5LlSfe_v$5Pm!Q6*`M> zXeNFLmh)3M(*QVQ0GxdQze>)eEQhmmQI-nEzQ=KDthONyrpASUcyN^iv1XEMj9=rI zaA>xa&(FrjSeI&yo5omU%%0g7V~|lu1r21xM(F|HPWao*Jvnf?cY=7D&~%;7F*aqk z9<0N*N`FX6636C5qwN*=b*Ll7%+@*0nd=>FJ0`l=S_`&0C^1;hPfT)$AaO+=>Yd~< zTL4k)ES(mxdb;GmN_9}n`f#07RJc)5kK&hbs7#9DCyx%7r5026f6TpmoYm9&K0Fl#1vu&vo7R+H3Eu_E7z3z2C^dSg;yB99b?IX+W#8hLVE$~$m7mD9J#%e8 zIf=4$4;`nx^MxchZjz$nM1-i9cYa8(#NnVrId0uC6>K_eLkWZ)E6Fuz#% z>C>VWOpH-&tE{i(8&^rL9zoc0wed8|)m=u0TxHS=Bs%Q9Il@&YWt6KKk`i1M zdT`Ye)dW`(<#6@y-3eUDdM@>B#xt==oLSFB|0j)Z{Wl!LRX{GVgr6x~&(#3da~S|_ z&CXKVq)>;p{CJ_pq7GfpU3xf3U4@N1;2&W8EcxnBDlOXzSOeFLYx)5S^n4t(P9GVebLT{OoBk(KxbcbQ66 z`6)YR4Cv08W}K1E{fl|1Lc*|e-bj$f>B_+toK%p)aW!N z>m}CLd65Hr3r>_I4>$aSa`9bCQBb8Y*}iVZdsaP zWXRI^g$_$+-!CkUr;M`neOsmkOJ3VVSEIUM$!nYFTtvkT2B6;`!nLZc!VEvrZi|5< zu*CeqLmwfDhwun=1!Tx;tLXdN$q-XTb1|V0ETM^}q~@OzXC-0oKlEPK-fpeYS%&#M z0F8HW7vbzF}eBjY%^$~OpNZbV?91IOb*l)u1YZ}L5LLU$2kBQ?| zC|CE{?`yyqZA%3cW#nv@-*sRpgnkt{t^%7@*Tw`x{`8W0bbbZ-JCJiYMYgKSwL=RX z4=!RW`2~!3N;b!kcGZ`XrD~{qYAg-tyk(J9gFW-IPTYs@X5-;#EY~7zjb;7`)>wKP z85&EQ`Hrzv-os*BwxNs~%UDSXV@Y}C(5~ROVPY&2%hDwrm5^yttqYq}YQs$d;^h?82| zJ;cEFVR)LR7*Es8^9Kja4)&Yr$4lkd^1eO;Jyzxpe?ey1|KV;C9^eS z=_n&3?f*kZr3da3mG+^GY5$TED)oAJb@E`v*_n!Fy~Sb&W9@W#deZ^^mOI6IPaE5eqX<gNo zIUOmZCGj$qDl$53Q(3tVr(6H})V;U0e#w(5Eia(RGm_ z$;~n37mypDx@avvQ7In_N6yZopSU&rX7;y+B|r3YL#!gGhg75(C*e`E|K}#y_+w>_ zEboKIuq@xw%CcNzJPBDYf8Sww>P7{0#Q85$za}!Na9`;Dh z+Xk?F#83At^)bKFHg%iexyT4oQF>)O3{++w3aT;>1zB>tBtKlS|0a}QFrdsI>W5Yf zPW1`5*2~ZV+|7Kt@`!VJW>pcaN4&xj52xZgh!ja@p>enYWn7mI0|-|_wv=Y0T||+0 z86Pi28L_)PL~_-qh33+VGd2Dhj6reJ3-_Hvt4?BR_DAsP;6(q!}q(FsGj2c1%_T#x1 zIG~G`J>Hn(C;EJR#w*Z89)d5=jPO_FH^+D@n$|Rg!=-OZ zW3EJ}Ou?n(`wog}-AfrYtyL{qbC^~K#D_cKBjMOZ_Z!8uB&rvqSP!NBBt-f7uB)7m zxR8QJFR8bsnoSmE<0{&71FdIA^b&PoReaJDWj2+ZqNgYP3MdnsK_7Vkh4DRv`Z2;5 zYAdO*_^LOJ450?+I8f6R>IBLt)E`?IsAD{!UW+ZN2RY6hz-KUW)%HZ{MYxG3MscO3}*4q(EiDqdNNVNput zcKl+WP5Y7E=eWJ~bFep}wZqWvT^0yNjhe=yK)ECk6pfmv`IFMy5Vn-AXl@*+)pr8FcdlPXZb3ecFsq)km?&z ze3BhQIvfK_!T(&{z(j5nmQAEt;e91?!v><{Zx&>uvQa-tB~dUX{3&km$ZMrI31=RW zFzgd&S#v~8?opm(VH#WT-gxdg8%&fbI58@0-0FnwWz<1X4$GHkRuVB7USnJpHL?QX z@DAhJ+QT21vB}3qhWmOi&yE|)1t2(*{;z1{S<0wJeovG3&a-8HIe&wjkdSFOD_I|d z20$O&UQ7~tkV34Rn(;Xhiiw1BS!ql}B*BDbW&G=+%GCT$(yBF|P_F!ZsL){)DvR za%qkLwZ$*7_Y|IkcP_%`_Bx6#YncUzg3J}WWFhWN&bl76lyU10WVbM)wk{DIY!NKc z4`o*)GuI!?EQ;zOSl@2rNvPZi!dAIgrCQ}y85uhB#cw$%F5fH4olhB6ZZk>AArY$R z_FH-V#hFW#EfeU#ZljDcP%0_GK$Qmr=b&C-K%yK5 zjzv_=b0`Dag32TQXUTxa`w_3_7!M3cb`Ap-*N}lo^lsgoT4Wp=fxd^Z1)3HII@QP! z=!6*#&?XA>5y~jg^-WDfX!ZJ`4WT!R2T+M}fObMuGEk1m*px35RqK66Nmq8CDTxcJvuoj=YOL%!yOtM3$TxnvLxB%B8YK4t$K#jS-5ZzNeC16+ ztcUeSSc@72k}xlM0AHq47=vI!r*JHAm@I5}u;K1lckl-KHmGIGl!S9R*BNmwW?1+1 z>AumKiRY6)O#yjjIW19#TTlo4e$@;d1M5wwGWZW4zJU1zJi!RiOQnG^BHG~_nL z_%$|;LWFJO*wxs2fm|cQ#&HMSNo+w!22C|P#0w0ej5dx%k`i8^)wDw!$60-~aWKkh z9L*3_IuG@X3_6T9&jl1t__6R37&k8^r)%W>`tnAH%-y=;m4)s|ng%m-n#S_0*fe%W zhjT4hvcYyJ@|F>XyfyFtv)AhZ7Vfgq`TY4AG|SA{s|K`ZVzed2L!BjHdkrB9vKZ*x1lR*?`Uq zYY<5bhz*go1+2t|Z=}Ix7(-@O;)ZybaVQ1S_)6$M{TF9WOwB(Q6J0<0zoLZZ!pExe zPnQ;u(7KQ4j+NwQ@~dx>@qA#`my57%4?i`u?P0W$VSBh99wDhceE*xYhrX22_VBi( ztfM`g(7Vp|P!Cbs9cmY~nn#W8 zpeE^lTzl!1w63BNf{1H;tPPdfSJqh^2{Rrn!+!b*MZm6yjmf=6XEa%GpD^C zuFwoqHyatwX;-}Lm}B1>F~=p8QFA;_Qp)pEyw`*V!%V}u$+!YnfFaIllZ2*Ih;E#KNEwLCUn%WO%BMzes<-C0!pHB%amL^++v z=ZM0UHRM;XtYIke%9_sQnTvI;aWRlf7S38@5LxI%bdU_8Rax9*EJt1Z*rW<~p>~31 zhp_`%A%B$_8LR=EiF#wp8%)2j#v-W;Q-*UG(3XPn zADUt=e*(nJ-UGhUB+&rKENid4JcZ|Y@PHZ}UJWkdQXLi)mYLjB7v|Elr!K58ac2I| zyle2w_ee+^gFs`r!N?9aR1=$; zHvo&kytKVMbK>@PJ;?@>`7!kH7s&N4b}G`U0awXpb2w5&^>g@Bhz?~UbW*$4NK-$l zaIFb{X8eQlVm2)^BP~ICx@mkemwe}PWW;SoS=I~rni}UwqdbVgi#5ty_gka<9lx_C zG|IKlJ4SiK&tjCTDWl|{E-7J@g&s!v3WlJVu1b_+l#k2k)U-D_dP)G=s?ZrG-yv|@ zyJTrjVB8$+2|f!<8u~9nq0Bj8XF6Ou%~MKp%(G>@B-3brJEYNGyP1vFXsJAM>9-_M zD~H?*#k=XBx`sgOpjOf!KUfhSJ8;}l8mbc8Lr4fk1cpEWXEwa-b8FRXaTS1+Nid*FF& zT?b2vvVZln@klg;RnIzg&CAdE*-2ZNIdHIl9|96E6nx z^dt#qFK0L;P~Oml`t?t&--5qv{Vq2$RLSXX{pN0x`n8SM?=eXUl|(#L@<%sOi9|Un zS%)a8G56~50w20N!0UcRFTJNJ(tPJWsLSJ~&Zg)bC@Q%+>Kcz+54ow+=qH%76_AD) z2T2uWAsn7(RP+%PYMO6`kr@b?b_I@#-u+Q1IDs;%qDLfUPW#XR6p$I|8N|eEX$kWU zcfm)(+-uWC;Nvt8xsjBMd)0-IL)r6;gJfN2B5dp0I9}Hmj11K^W|C9a+8?B@qbZ|x z{bDy!LS0_dlnhp{wMIGWI+ZmF@H+oy#F#iiIioytzfMs01Gd)$C4x(iqK8XgA{()y zY>ptrg@k++#zhk6VuUTuwo+T^IOZ4`;w%g~IFD7F6DgxOf8J$q7E%q)bZju{!x03d z9GsURO3c!y7Fiy-19_YC2Xvaa3>|KRs~1mjv;@SGjbn#@U1+j_Tz9xJ*%9G}GTJcS zWP@LDG{^I7&JaNM2Ynwu1t=lkTzu7aHs?9xFL^fSNru^ybXDTlKgE`LHYeLi@odgW zmD*vXmWottUrW#CoDY#Y&gPiy_fUrE&5&VjK2OiYF6>y<&M=18>7yUHpcg}(~%hk2=v-5?)~;ac$H>t$T4%N%$f&^RGl$7=|O zH^0N_QF)}EqT~snr;W^TgvSQs){!<7+vJn=Sj^p&QR^s&Z$T^QYPLZ`lchu)x<$dg zgR4vnW;x;Z$RVKxx48hOgO{|*_UZqWZWzRo{-f9S|f z|3ywp1J@}F1{9g&YfB%;W1%`$=GNvM+1TS4c^uq78-ZlHk(pw|VaA3#&!aP*6MY}E zE7%98BB^=jiW~5KV_X%nuR_>jKT8k@_C-d9*xzK$;GTJ`OO#rs2XiJA|5E9ywe)4;Np7c69} z0tGXkbSPMY134wy7|c0`uki~>9@{X1@mBmpU%?(bH2l9`0D8W0vD8logspxi{VuMB zjjpwkp?-XB<s3R)z5X35?xOQu)4On;vCVBL^=9-2T>R=Uk+b`f+kJiSMFYN zQc%DP7<Tt??5$5agG``1VI)R}!XO4iVGzTi z@Laf55+h|f#GH(>AQi3F(=OAbIpd--R-loAOG^HQo3fPLj5GO$l5NI)k&^WRhmxIp zWu&r_GD^uQk`k0OdFxPfd9jO7B2f+{k0MGMk&=KFoix*`kLpC!iv!~p%jpDs0`+2` zE{4A)YRS$)eHOBVRCJr1Zt=BoE8Z0qPi}-);}`6CaLXe#ZwDDSlQOgAg9R&CDyQ6C zfh=KHd1+@1lh|i~ppTz$2&%*uZ*n=m;Fn5Vvv6scR+jChOo7Ve%q`)d}m~6 z4=dTK6W#k}d2K?=1(Z>HXf7#X4;3Ev@Fa?bdzUE39`4Z^T|W*v8NU%KU`H=AWYfR( zzMc;M^T4>z#We5<)A$^wF%_K(O+#{aOrsfchE((`S#|f-Pr&>aoR!6VL)2pag-#4O ziFqv>Z6fC1^n}hb$|&Zxk`kEHW*yoFp6e)>CCb74Frwo9c;b!dFq4$f7;bmudMsi~}U{m;{Z^mzs zf(_#x3U=dY3VOIzlu-&!la!#K%!7iL&lCzI%AsI9q6`JL7d#t%W$f@HoPCvmuLAg` z@UR3g89Ct3M@Bf&8{H-A?!MDZ^$GE~M2O>lu@IXkK>UlXEz!1{Da2psY!u?)+k)b)PZ{iGUXY@hPutb%x#8S zQ|iSyWuw`_H;CZ0gSc07V`q8f$b)#scqv!gLcV{DGb35QA#Cj->t{>W4@QReu<9{~ ztgSo69u`qX$vQ?-f~@q}hdP2_2O&$M9I{3sDppl=V92gKa?)QUsQS=jiXXtk(jFuu zhoDoD5sxYUBqK|~uB+*ED9rVU1A_g4acacA6Jd+}dOY!J+`(oeL+oEX>R`vF2iw9D z$|&~ZBxN0jQqaCmLwOKU|C6CSwVFK0Va3$EM!>~MdTQQ&j2`vS;&gal^5JDLEs;47 zEqn{(0M$2#y11H9yJye)o-y*Th(ED!|negr%a6iIp@s6W)s z5yLQiCyW@LIh_!F6OB(L>5n07N#C@^l76p|A?btNTK(q_A>B_ICH+lF3DTeNFt}DI z7QL-RIRdKBWz*r-E3jz8yUiU;1P%XN!a&=ZQV*4g&CHVfa%rMoQ+BVrdL;UjMh(_P;yuE zke?Q?Tb_=Ax7{t?b~oVmhf611udb&2R9e&SXuhtIv8%~B5`$RjX7Zk56T|#(j00y0 zPVOYz(%1MUwq}YIWAuSMaioLIqGZ##9z`0@klc_j|A(bX3r}58D3>>`Za7f_(Q2(p zE92d%h$9fTint#S{+mX=-#9fYBJ!|P^9Fk6sERVGi1Q^S6yeq3&2A@(@apgi5EXN9 zcG|a-Dv;+Yxy6GOJ8bcA#jX-wlq&G*@OmL5NMVx}7-MU06Sfx;aZrwD_=6vhrdi_| zK8oPG!hBcCH^x5(GkMt!#}=+MD^-IwSzfjphsT#YRX*hKQlp1o$|$3}w2_qZawjQV z_w3BeotS+%LcPLn%;Lghr+_QG6G``h4i#_pHpE$9U5n@kan$4rQ!CcITVlN$-0 z_b1h=WajvhQOJzLnAJL19cmmOVfIJZDrmtE7UtzfhA=y`5{bi@K6>t_EoD?ek4Z|v z9PI(~kCOzZL^&|mAquUt%nmcA?c^5S#=y9ZGDgKG#;6-%wZ|EJl8b}yY2?Cj%QhLK z`W`nPkNEzBu*J82qs4c-ks-covK@SP>yeutlu>+BBqi__dEiS`d=lm0+np|IEcg#{ zDi}~{Vcv%YcF)nrx#)4&I3+U&<}75!(MJQqEXd6LKVQeX&p1soax21?k>%f8My@q7 zWaJXoH&Nq*BhqJdq>M81l%%9#d#u$QXsd?JD2I_Ph(ho4=!3`!_y3OKms!W^ms|HD z)}vQ*)xzVMiu&lgNSN0m)rhT^kd)v=)|VD@xi{{wKW`(PNR-3L2Z(};5Ec@a zv93Ixu(!)=QZd4azbthpJT75NUJmR#kr$u5SSq92BA!u){*8MR{UdC#&H@+EGZ%T! zGcuz8(GJ#&_2f=k9P53O5?H&kZ*s6!pCDKz%E7t*-!~1M7&yWq za^QHF!72GTIL9F$K6kxAr{<%KgCoM*5Viuzs<-H`_=R}iP-Pb!#S5yMzOytDS^GnL*GZCUYH_Cl%wxmt%+Ta$>OkW z@*>4ia6YktIwnQ?Wm3c!Pj^J;LJ}lLNAJ^-qZyrg?;WQ@P5z*7!o8?G_CfJg*WU3! zMl%i`?rF%z^#; zs*E3@mOe)~-1U83knF5w)9)-cGSt$%d*WK!0WCyobw{^|GODFL*!q%<&nEA}?_7e9 z1Rp!HmHJpl^=A|;CpP{?6gED;yc;%FX zt4;GuvD3_I*j8%ZV)?_j#rPJYUXQRveUa2%yzNROL)0a#ld(-feVC%2K^a9|yVjr{ z!@4-AA4FX^ePxt`dJv)jwHlBk#@k-Jk#Kd=l+-L=WxoiElzbexsRDOzbQAbQemDXZ z+wv?TFYztUUyebqOD&gNz*b8*rC&oN@7&GK@dqK(J#(h$)wQwil&c>K;TO$pL#{7qIGgRwOBb}O`qdVE3QAX9;UQ)v4 zbeVIgT3>A`YLzHQt+|Lo3C&mnG;60$Ph-Q`vzI9qhk@6Qvm8ga=OQ!qGMm(T+ZhOi z*(wp{qtKukD>O-fxqpNM^D5mC-b&}BFndZ$_M{##=eH1;66L^r8Bx@y#dqgcPMth# zcN2U!ZC7$}@byP7>{4pQc745AFW?})t_WK-zWSBL*WSobjVHMH?$J%%hH-qiN=o3H z=z(utbHOK34!%W*f z-iIKLn%r+(C~JN@!nWoszpyp$Z)B*{EAMn_{v!5rQS;96nop9HP-?694sDyY%|xjZ z+Uc2dQkmb;}i)u8(|Cg z+s`fBJB$qB4!*;II}01VfSW-XRn$~T3AkN7;HD{DiE`lXNfQP9I21X>c3t~bByPE` z$4M&BdF>hK)CgU&b)dh7Y&oy(soPS|7+*@j0fa5!Up}*d|6^nbc*N}v;03zPd<|t3 z@El1Az_}iP+oE`MsS@P?ZYY37zvh7eTBDxAu0&ScBiZ<89hU=K2!~I|lCcB%-Bd!3 zM6cG(r76bm5ON{H7V@su7ILnUA>{1a9LS&QF7pt|DC9+w5|ASvkk3N#fGklC>ScJzQK895Lujv~bE(R*Zb$+yV(4?=toVGA)W4soiHA;f2Ibs$#j zmhvN%QHbkTksLrwn|o-h?Tz9AQKB4(oe%|x#r9Twc__0&yfQU<#XLG>+1yCY>xiC` z^VHNl-sP%u)tk`=5VmCQz+Q7CVeg1$YwKNRoDX3yK-j`=EtQw?;af(AuwNPGz>ex3 z>l2hw*qbU0>>eJluS4;GEm02a3lSA_RzP{wo$>JlW-Hj!z!6yPX*>=$PIQuogKpOm zCXaG91Yt4O`E2=HJ0Ci)Y+l?{Y+n<_`vG1k!_!h&3ax33J_t;LRIG;LwyVtI#4BE( zxXE1c+OHTpW0d3Dfby!fENbVhZ;^KIVX65?>aKmPn6iiu&vOUL>hZ+~4VW*!f@_v; z_SqV~e%NZQV^Zygp>}yc2^wE><2LMv&rTsnB^~T|%E{Sr~H4#y)CovC1^EP9l)V!8rk$Yj0JbkUx?9brQsWZvQ(OC~< z#4*tph1kVZpAg$2Y$5)4rG?lc0b&yu;vn6~-a#Lv5c^3=Kpg1-v8<^;lqd({n}{Mr z>u7F*ZeyeSq@hp^960ewE)Kq-$c00pq)nc{_H^_3Muzc~#CsmX;WRVQd1-~k+s?>j zL8jHsj!H*hFBd9JiQ~OlQpO+OV2O0QkoUbYn)uR> zvF_VA7Be%Pfe42WK)I~eqGgtpD~t@SyW5QpDM8(}J()5}%HxtUZr#k$weFfmiPkL= zj&-ksgj%<5H*a}8usYp(Ul_gl`H$FdzL$)np?*UMTPVLTwNM^4GSu(=H#ktj+ohon zqKrbBFDdKL@9D(gt=}U|(Vi*0IJbacyrD!|}DfugZiTuI&vmQe4~1QmNS5-rFLTytdZ{B6Y6qr5g)NF?mug zyWwTRT~?`u4bpPC6tdNLAF5^W;J8|{;PxW8Or8F-j54a0Hd+@9$LSX5<0HXw7B&>M zNYrXZ(HH0hFb7ezDXQfzP#056(qd~FoHNxT8LVRl@s+&ukbz}5gY#lkxUH!?0X8SV zzN;1BL#5X48W1Qc4r5U|pDFxXHXEoU`Bc2%MWw~4R`LM0PC)xN}`#9GXkmandKDT$x92t%(Ef&TZ)hG^D5#dzh zl!)+Ige}6|cpAbiLrpL;M7U>wgK(Ozw%tq_)j)})1j5lC2s@%`KqyfT!lMyYT7i*e zWH5B-M7yez3(OQz!MXDwD0i5|)Ln;e9 zc7$xV*=dyl3m&#gwp19B`-&# zyJ{OkquZk$Wl}3VrR#tu##3~+WiTT-<|~Qu%`@(U%*;gCGSgV_$&By?BSU7I^mmx~ zNEhBlQ%0HjqQo#$>A_3}stjY7D2JI-5v9x&p{ilFUAoqXU*ul29_~xpqrDS;o6JaF z4l^4Ll9?UR<~r|PZJdzkA7P8~B&n;QoNHu6|JOMvztBaxrzm6ezsR86>w)q{6c3aV z<)G|=C`CC84bJNS*~vudu}k~7G<>{Zi^Vu7cO4+g-O-Np5Pv~oK^z*!o<`y9n63*7 z=f#3r?W#YmK~yHkgeAuJy76YD>Uo4MRe!2wRkC zagIA%!82m`fA5U#_Iy%#gtL@ ziX>%DFT99dN)O3%ci7mMnuYYn=3t9Q!B9>(tm4Rr_hUlq+hG%uu`}}d@*mp7_UNDTOr7B~qZJaT=IKR7 z@!!hjOfJ+8D_Ew30dtFU@Y_G<`tg|G-{_39Fo2Gy(Z^ZWKimix_T&r&6F>KLm?*@e zp{NTyh_WJY;g{IMfjC5*klC_udytc`Nt%l4%O+{`YysdqXqqAw^C!YqF$3mX#cVM$ zRLnrPI`wo7GfWv(%<+;Ein-cDF;DLm#YmK+nExQkUtn+FIR_f|eE9DZ^c8Hfl84h| zJ0lN1{MTO|{?oidlU2h<lNZ*#C=_gJ2*D&zBse3l!ZIDk`z z&in&-H8LStJ4~F4tRWTcE!R}5O$5r)V2SZky8LfffAVD}a;=myXzbkFtMjSxLo}U* z2wT%R?nBGtEF(i6kMHB~xKbD20+dl6t3O~$@L1u&V}FcN(WWKJ;jya>V5bU?iS}O} z8HIktAH2M)KZO6h#xpQ(B1ifw=jcd(c_?!^m>eNucxsU4I!u0#F)*Z}wQ?jm*1Eb# zlQ&cp8+S!2<{)gTNEJXbBAQ}kNJUz2hl)>hMQ;pcl!|ZW87k5~I@G=SQ6*3zQ4SRy zWyJ1K(S<|5+tDe2iY!o(1uAfj*|~&tjCpqBpAJ!ikL|0SD)N2@oI9p*snno(Iz}$nG}VW zN4)A3;tHhZKSZ}1Si(LStLb>wiQQ0|@m|zZLxioKM!auLcDHHn)YHf-9X&PIWyVU% zsGd4XN|@|m4?RuWC3=!5M^E{P@`qx2(xF0mq!hl>9}GmKy80ErnExycF(XI5quTmh zA9tNA2{3-~(ALQ)f{(jip?j~*4KRXljIafN_goA9Z_`Ez{+=rw@W<$K;@6Z>@LeP& zz~_2^e*;5c7^y@#;3vxHSiqOgLefY%9Oxmqr@=y}(L!6lt(Yr09LK7x2xAq<19Ka)?7>d{PGLu)9Cq$TROz(p2U8-W;iWtugIx$0OV2OKokn^llJhaxYdDX^ zwXbFCAEfQ~>c)ymL#ufdER2zHiMawh#LkD|_$7j&(Y8P01Mmgo=JgKlW&7QEAG@O} zE}4u!Jf2amtf3r+acwhLZ_Qb_e*+z8yO;n@Q5a7!K_1Rwty1%|Q3+g;$g3Vw^NlmT z$FIy%6GIWUnpg%$W#&xR7#V8f)5{%AjM8U5&ZLZLVxpvkCboEJVjuhw>{Oy0O;jhi zDj*;J5I0BW^GXWy+(#$b>1?mheVhzuPo+psj#6HfLSn`jVSj#^1N&ip6y!Y0DC}n?C19t_KeP{NsIVoZx?-zBy&l-dBSiV*gUu~1saf-AX>+MJA1yr$A*^#k^;f{n6R+gu z;4S%$c(+D>RFv-;&p?!~BWzLDkE49X$Pi@%7v)@iNaG&LD9Vc2TaJY+^&NdJbG8QT{GIv6zVTPmR_w{*SQZl=41N-3u<59K&H4X(vS~~PU}n-9t&tYF z#W)rsS&y(qa*@cDHH@IIxC!b^|AOZoUvhx7b4fhSQ8yfKK<9`Cg`+2eVv+^&EN7l*@~9TU9> z$vG)sDGhgVO7_F3?)B%gTA7tKx4>R15vsyB{!34XZ}fBpyaO^v?8)?PEl1c#SaPtI zk0YJv#;~j(LE!eHly!6(Uqw`hv|dMt^AV*wdCpunc~F9Hpz#s}+6Uoqn(->{y%{v<_ z_(?89GH_hRwqF{iM00dstD08YvJ5xH!17O2A0oeNl=W}F6jc@AOA%bw|0Z%-H*^77Y3j^3tMOP7BOWt5jsBqa!-ko}@wm92eaUpRXzU$S%@Pnite(7Zv?N#BzY4(zJ& zwD+Q7RL-29U0I4Xn3Tw_CxwwomncFql8dlqVMyzM+U|5>ftj!sF<2pPewr7fv*=@HF=PX93G0d!eZ8o zU-Zo}E{6D~A#CwAh~q0XGQ`)=#rOV?g703+D85y%o0i~(uRF@F1K&xA5(7o`_gzeU zy7ARn9!~6_2R`pbk5d<}YTTY8j+PxqE;rH=EGKPgLunQ3u|XZxm%FGX9J}FvZW`P2 z#1I0;1(2wR5w=8q_nI|?5k`hYeSd*t2v6doQ;dc$r;HLcO;Xm;G@28PchlIrMVdxW zsv_Prsu$T^wA8#V(zou0Nt`Ao!PBH?qpPT^X}l>}Dj|)k{+Fgv6%a-q;1m_}05WnX z!j_SWsg{ueMuv>6I^SU=d!sONwoG+pG3jYZSx3{ThdS0_I=^g=n@-t9G#xz?hvO*d z&&-9gXT!JGWjb$a2DBS)O(xJ&>?(rKD5xz=I>Ul)2M^!{2VlI* zE{G3o`K~f9k}UN=IK0Cg+L_2<2;9@tG^eP4yTOT%}7a^(*>hzj;t{X z$%IE=Wp1rt{^7I*Ngd;4}jLk<7R zK^!cCH!;e2oaerix?e*Xt@|8F2@Q`%iSBuqwyY*jgD}c*ehpb8=_cC}ZbCPi!!b7Q zR^u33kHaL4u_Y^~!(6mU$JiaTe}s~9XER7G?@_P#;)M!?z@I|c0{`t53w*4RA@JWh zj7$Xn@&*AukTMGVBS{J1l^(!PLzMtrq8#9dBMOLZEkm@fez3AHr5oG9!JCXoQ}g=U zM&H{u`tES!GIu_u>wMqRXda27ynb-Z}X^ z4BPo9T^y!{e=AI#LK$T$S5ns1&Y6EW1NBZA0ROnL?shKnxs;E$^SO{mU1k}d!@9qU zu&w(+z&9&BAtOUA*LHU5{?2--`v}Tt-Iq&BXt~%!%NMemtu@Ng@(HYwv~xbJn%K^> zlV{J8uhX(OeXlLMj3-~{6jJlnp(UWkD~x9%!bJ#MgeSxizHMZPu#Jnb;u}GjPZ>qH zglWZx+VKF?1PCR{LD&sZfL87I@ni=ZaeMT7p0nu3;pl0*l8s}#yS^jV?a_7W z#bAPkI|M5YI1Lci8lObSD-pJkJ4nT4!C--rA>=bUIZFLzoj`t$G79;R$p&&)56HKn zLVzq$4&*Bll??e#&>kD#VUsj|`NSmj4}>h)IFM5W@{Z_c;-s@r&0C}D{l&N)V*L(b zi}ezzv0z+9Y8nf8RPQe1KM46(ge~MgFW5Hwt&t(*tIl#D|Fu>i ze?%FDoF*w@(Gxu&2dV_JL^+U0A}Sg3lOQiP21{B~cn{8>kR=-j@=3_XV@)9oYYN2x zP(K0iUud4;#m2$j@Vo{5i)pr5kiYRv2e3~8FQbeCZYwEeO`({zVvg?N;Lx|goep?$ z3FmO|U64R|x0$l3kb#NyTlAc*-xWrN3Mo0mso$MzL?I`~>-V^%ghIRy2miTV6e3ZM zLcT>58c4CMI9BTsnQGwkIvo5iWZ{jXEoHwPC}o`tV+;iC;^ULXHxS!cge~_!JZrJt zZDfe;#|{p*V5MNYf-=he8Xcg>t#xi#=j{^r>=(5QZet+9$T&5XU zLJ<9Bd1RPoEa9Sf#+9**CoGc`$UAKEmcN;IJn9V-B?kh45y!iv8uB*^=@HAgJeNQ5 zpGf%Rd@=;S`@)!oPsZfHY)9VNG|))3yOdjYFa7-h7(V0GoUvrn`bN zYPu&&N||olh=yrN|a-|V-cmbmK7G%@uWxXq8wl0f{iN7xFd)tg@2`Am24bu zf39TXJIhp>z|s?e1qv*%v;<&zr#iqoe=fkbv#lzy-jWi)MtT5SyheaYlml!!q7;}c z0igc=u>_{u8vur@zyOS^YrnuT6PRS<0J~AL@%1;(gTSst*lO&ZNfy|JMur-Dx19rQ z;AaA?c^ueiNeN&RJ%IgGDZnJk0ak%11r{5UJcRZZ8-4*;{LH(~&0+T2Q*dJfTfW?N=Q_;d= zV=VxSKT3TbTs$=<**L&vOE$jgr^kU!M%V(|3%1NGDBs8s*gq#bz-F!zV7F36frTX{ zfK__{I~&EKdypsx*fACu&qdQeZAEL1ji>-DzN&Q-dLROmY#d-;sZ*mTl*2RtkuHW1 zGKXu#JC#WhD`i@U*H_YIp}^!XZvdz+*Lx6CT+D@mFNe*?D(ZYAm@ zMzJ2n{D_pONBzh+64q!I!nQ_D<28E8$goC-yER%+E;afOWwb_>6Nv>iIvXXrYg?CV zjU>v^c6&rcnrHD$gS>8nP83h>!`JYz<5*~(3YL_Pf`9*<4ZwGQy2I9SsGERC&Ggi9 z7yJ^;tdLFV7GXar!6eyGGE1|WW?T>{c>!Td$>0CAO3E`bq-1Yfr`R`E3MIoRqm(R> zl%OQngOV;N7D|#Rhmw|v((TFPkwfg&5#R-{jsP!wb;NCO^W;U6JG`v_On9kn!HQ%S zMbFcjaS;Yct?Y zOkW`k+(H>;;1fv+24;IO&>@q-6_zI} zeM_1H*d?-oehm4F|JhjHzH2sw`A&K~_i7v@+3ba|Wph@(W%E2ELpEo(aoFs?T-Z#b zjIw#3qy(E)9&A>x5;i5uVRHqd)Sf;Ods-*&s(?M=T@|n=zN_MBbV8(2k~=g$iRALa znf!n}ZsyA|-hj~VLfAt49B$M2vm1;Ip?z_J18vNw0_}XtD75D!C7`8za;W$4DKv?4 zplz#w%6Mrnnz}f+Rj@d7;_s2Jkw^7?c++Za6q?x=Lyll4*} zH?WE!-_gdYk>W-OTZ-=rSc?BL9*7j*eY`_)OH>IPZfhx{6nB=Cb$Fv0<#l?a{~}7Q zr{D>4t0(MWJ=J18)!=muRV! zh*$HiH=cxmRwHZyb&LZlF){?y$py5bQ~2njOdK10ByIf=2;IpK`M&zus9>WUvWTg?7-kf%TgyTmWQtsf6HkB znTe2*^TU)Wf{ePdY*|nAozu!u<_}@Faqq$}v3XF7@U_Y9`tIdo-M1SbLCOaqY$-2+ z12P`*N+UzcKRMPZb~p+_b3KJJN_noNtfRT^`n1mGT7@XJp&!SSYduDApUiVc=rMv* z(T~*CTwi9+Jy6B6BTy9`G0a0VoyTT6{3m)u4WEUrVbD7-xmD(Tg5+}CtB~on4Ss;^ z9*F-r1Am@l{1pj14Pi@I5S2EB9b;rj*i*+igq^=c2>bImOV~A%vW`Z#3|%{H)T?)# zg(xL#Dy%#lCZ{0#Qr6G29A0QHS+$v z7;RYk`qXa@_?y89egfmZR6+w4q^JSHmZIU~EJeFa( zG}@z=eI0HV6iJlR%jO}fG<`Ep`9Jj-Dbn)={beTBPj?#Epl={WlHBQ9Gnw6Ivw7q2)eADJ{24Q`7fJ!(GR(TrPpj zB`uQNp`{a&%Sc1FS9=cZIiTnDd^A_q-ICu664a-Pg7R=|uVDTV&O^&HCvwaadqOnl zaJX6yDdcgafIPZ@W79GJhe0i9!0M=ZOjB=p`u8KrlDqy)WX9`trVHx8?lD2Lvoq=z?;1DgjU^(`q{XP)ER zi!5PDI$(Pm-KXC^E!HhkkfYs81!ncIwoYi?)PD4SF(U-=jWezGIPvCsn6iuOwQuGgeh>Uy-Jt(>tH3CHvcgti#cFI0vaF^gOIaO{iY#(~qeMEjBKQ z{LDkx^3z;UiV00KGUTVlkq$ql9|=E?QAYXM0RJKUqyvGw?AI5y0Y4Ju@N+hzNKCKL zXgr0RS(LgUVk$e`NDl&<+=n|+-V-Y1%LtjZ^@<8r%NWq9rTL{`oghfrY^XyOHbSknwhsY`?REAdglIHFQ-Y*k~5j2QO}Z& z`0f|{8o^Iusr!YV;}%-K{IwX?K%}$e`X2lJzM(hu(ekOB^z;g5x9i$B*tcDmzQJDY z+WUi#wM+NoH%z|!woCH|ucs4h*sfo2LqD7Y@5*d~+xiB7@dr0)bG?{-Fh^{%q24vp zZIqg#Sy1^NKANT|8g@+anuW#`YYxYFI5x__V_6*D+|+YO&zpPRVjs@Rl1tF=a25`b z76<#y$JmBq=!v8Xq~}FMux_II>(ub{&MX+G4^LDqsG1+&Pt4ZB$#rIedq!)c8PL~y%(Z%ig7n` zh|S3`P>k7!=RImjyLE>392~UxG-mF=Z-mUFt#uI_C74-dYTj?O51jwu%o2Jd4c{Yd zX}A<_6Th=x{LILZh8|5E8n(?98fH;OX=o@Z(Jxkc(D3klp+TY?8ipV$5&NS0%M#rB zAM7=QILsQr>POBwk>BrD3ij#@>KXW8QXm;S6f}@Bm0_^~tW8(x+Vn0tn(fdfsJxu_Vo?TX+kI{WCT}F96 z*3KjZn5#{rrg4N34v#iY;3NSj#xd8(@bv;GH*#qCVvf-A6lIi_U+)uIaAoRb)&s7M zwKC_=nSHnkw4QJ-^@9EIj13R5D&Ov!F<02}|?8WF^$_Y)~XamE*v z=WoRCa{fv}Fm1`)ImXi-nTJFmdik+z&_XA359Vhf13>c`m{j6FXuVd6L+-V<9W||* zRNUOqp`yvVqQn)HQ7TTBlxX3jJ*b#GPpFV6hl;U?Djmj^kkRNxg85kZt_>{VXG-=Z zvA}sD`5hCBPtX8p=aQ9U=be$23P$^YCDi-p22$_T{O)je<@p#2*EUgC-@u?F1An9C zS_W=}8#O-eSJR@&z)hM{e9@!PJHo)Hlu-uKB_$Xr@?hZk_k{t8au^tcD3oyPL3Bp3 zR}4;ORrM`{J&Ol}9b6Duat=?DWfW7mQXOcJt~RDoW(DFTw?>Sc?#y^m@RC8pMqWkK+gcs2jQ2AUJ7u~ zADBb*6pXfNF0MifK_At65gl(y8%%S;eDNJZ(+FbX7jt`hJw-kxYPuNNbaGGG(5-MB;uAw(ir^ir+3PxW#3cU~qH_-xw0BxA@8l>WS zge?^dZ?{zRGBTv1c%MVX?K6ambjm0d<0K`h@Vb;~$1I`3>r$p~5Tyg~?{8y=Gg}bz zQxIzah#3IlW8m+J*z1C(r;wEjM&CRVIB`!T5^?4M2vc_eLNGrAzeJ~j3Xsk)e(K7v zkol6!0`(W(D3RcpM!SxwV98@hX)d@puN^L&$e)8B0!#RrGXAJ|39N?sIp+u+{9~w; zQqwsk<0kkeUgsp$k)fo7CM@BX&YP~m@(8x$0!wn4b!vV&FA*r0DkC4ld)hcSYV-+& ztww*o)oS!XBSVe;LU)zu5TBhU8oin_s?m2PB{X`mhjE|ymS|L>9OG_)D1U+S35_kA z4#mkdCnTT2{CPqLKU1QBP?_tne3pe7k?%I+*ht(!ge`H4hFapTFft^r-Qk;&o{L7Gs+?ETSUc)OB3RdCkB?U6K{E>5xOMz0=s-@N$wytgk5)|5>_mP z@e>JuyF&?+3OR(`ic)pvErcD0Q&h$Q#9pznx?b!R8)C=y=lV%ML&?zJvTy{*66VnL z1(Zpcb#?%mWu0vbD9`AXrapM%zsf4LP>HbB!nwCtEtDA-U94%~`B3hV28P&o+ zH!~%)&}t>9p3ku*{ftgP?wui8kSIqB*CNW)kDPytm5SsRyBM4Xmhe+rtOn3x89;&w z@clGS$=l(2&vdldS-J-&CK<$49^#nI$nLe5Sh(*Cj10Mp?sB+$;T7TTTFNMQb0sA`p$B&-q4M;EjB>bZgs2#I z^6mf{)K2sy!TjaI8b4FA&j~EiK!=e04x#Q45)a2*9k%AZZgVZq-N7yo{{W=OcqRg$ zgs=tv2V8;y{+N*=@Ew0Tz+Zh?fDfjO0{>W20{BD^;O$Wl0GB8S_>u7{`YrJGu)tt` zg#hQL0M`J3GXUV14^!Zhs{?%DYZiD+?_2i8e30*D;}QtJ0AUM%#|;+#I3q*&J9j$p zrxXeN8z`gj7f4FL_i8g8P@6j1%u(@*QscP`-8S>NkibuIAsT=SVE_p(MF&z>TlsJ* z+R7ceEBKaa_JsTj!WQy@!4~pUMuw0Na@dzR&UyPKfjpct3i(q>3CP7B8ovN#1F}Rp z8b2OUrLACyky~Li=*LF_3T$7#g88HQS6~Uh*sH(SUpuKv{2j{YCs6z0>WNyicT~T4 zN>V3vhb*pX=H+Vt&<@HoFe8*MOlvSXi$(L82GNNbhVBsPZRy9F!F??FD= z=(}pSQblTeAZ)3fG00Ne*~pOEH~w&_z4}F=_HfE5wId}ZsEv3~`~9mztwcH0mLUpt z6UP|J9V5^uD}ps8q&&Qtt`iJiS#!V{U9JQ8z!H8+YtsN)8v{u24Vok=mtq~tdrPst z%Zz&@5f>nAiFkRSCE_$ALn2=J-60}#vJg?9GD^fyNeLpnZVX-fiV)#-W9ULe>Fnq| zSZOf7O2F|`W=9&p?1%w?+Y7Hva9+2E-ixeMFp3i-=(6&dOU{YlxfMe85n{C&HL;o- z&6vGBGSy_AQQnWE`)VW!r^rT!IncBb1|G``vzUU(6wx=pauGl*6bIjBMxJr;K{NtZ z06S2TJN)Oiklm4NU*s6(GGRHlP~x{?b}^ULy>0v#6*Cp#aF*F1Nf}@jQ($DWAXD!* zM=^7r7scE~8CA^6>zOisSsil>j{(Mnk<&RZLqF-Vp#^S5Vm2iRNyk=ckU)8dCDiW# z9FMKvFeydGFuxgxM8mmtyHmd-w0^5(t}6E|ou>6WzN8!_xAz8jK5ydOejpce`s-~x8j)Xuu+`tR>n!q)Muz&EzRf}2_gO)H z7-iJHhD%B|{E9>Mx8X%?_>6LphY_X6HJ4wDhVS*}$iod*$=SjBIFe(hHo6_$DP?%% z1cy{3T@>k11~CAv@K;6>0^=-NV|9-{bRBql_&@4 zIz%bb)vyxJm&u%jZiH@4k~>HzBRO9tlk_H2^9W>c$zUv;;N2r&f$j4y;}3}XW`x6O z#($Kd$26$>85yEp8gWqH`;4IOKp92-q@)DuVIHXec|lN1l!N+5L@DZq$RT#hBI$ya zGtp-dwIp{?zmDW=vhQn?P5F@(!u9NPVcX@I5y4xYSv78AFJ4t%&EwE;+B_X<-{rI) zJ`)GX(IWgs93k;40yHnQi(ok(E>&rEvAfvx;(xa5i$8Jij`3aOvKhjb%j|0`m-UPc zxyJJo+BJAWf=`EgT|Kuz{0z>ku?i09XRw?&5jUZ_eAGOrKc4jffvx0gd}HYn zV2`K+2;N?Eeyl>}xvY@rCVnF=FP~-0OwI3gP;8aS^r?gr<6cPdT!byf&EWKmxxQv( zNb%9XI213LBovROjGF7W{g|?jM%w4OIvZ(cM5(!+D(0%kB$D3v^cZ{YIvVMYXSI>y zuIufqKJ|XD=e+>s5Bk3O8I=wBzQmWk$tykiy`D3SGva$aUt}0#2;<2AhH-)!zSlF) zNb$X%V^nH~ky;~C$?x^dgh-w5_0$1KtYL+G=_YS#rUk;`+%^3`FYKJw!!#@M{VAQDT_op$3{aEwgV%jMwU5~J(^rAkN(v?OAw_W>| zZE@n2m)s3@q9>fHXPKl(g z#61&cCP3>;O~BEBIOZ9LFkEUQIChzq!B+A|wS!}uzPj@($|#Pr6bH_{pxUlOcpbwy zjF~0MX(f3w!edWY9+?dmV6l9K%^>gFnK+f$-6iE@Rn16kg&Y&b=1t|1lLyEeb53_eR@-yzyt$Ho zHKPerGK$voR~{9P8@+{0nJ8WM1R$78^3@Sj-kk5uc^V}7jN>4w|Dd&6QilMTF^{Ne z#U%CT9~@Gv_060sD5K_avZMs5gFQ%{928O|${}?uqLkFpFfcR5PR+{}cfA8k_je!LUgD8!C|LA-FJ3x0|9Q*9-= z**(go8OM8y|{DO<}eopE}|DH8I1NG zW@9a_g-B#X&waH6{K22&4=#4aaJ#hL7l^wAdIpibOe-hxT@enyYW&-)ms#T58=3x) zY3J6pEl-b!S~jGN5`U|t%t2q1&*DfEGj(0u>L)=Hy6|Kn$IHD5A(Z+WXMAW*tmShE z+gk1cLetEiFfufc@!vU&K7!XkqL#PF%u$w_K9Q6#k2J91`mRo_8?K9Blw%&v5mlP9 z1&a%Zq054=k=qtB<+BG|35;VH$C5xT$sOZZmk(W$j*{Dxb@fRPB!b@_m6FLxY$c2E z7vyJvK|6`PP#X4DTpbvn#G-BDt~WD@r8Iq6Cpc!4n12qvB=!LBo-aYnCFwE)YpP?P zwFy6&cV~4r?VEI;g0Q9g$qY+(b0b5#Q#UwtH{B(4|G`$OM$uPNva9f*yA-Y$bW4;& z_e?~E$wg@ykM{b21nXfurk|R(3vNV1QH1oOg01kL7UVx$ki)5`}yf zU!c0`@$_Bp*@xWq+gj6S+w{W#CsK=AA^l#{Hb~ocge`5?K)1$9HyRnzR`snz+t)jV zwqnXCZ7n4wX#3EEwu$h@piQD2+U}#HmX6F^zS0-wZaUgWdPk1xrt65ZFi;+OA5NB} zRk9F=v{R6if_~V77U$AbK*Oa;Uz$6N)^yRb$GX5Co!?UPPY_e%lPBy(b4RLdYJr)8 zl$z#B;yyyy5_b#~V~Bgh$dI_#*E__$vO|b_oH9z>M$}Hc|6UK`u3^89SAjFiA?`dx zNiBT>2;=#<@l^_Xsdx3NR`)?|y`^CWm%50$mPyl#Cr7zn>7}aeOk5%Pywz zfERn);=PZF(|g;rDzY*aVarO2V3SdHfsr9A!EYQ^^8OH3?xKvcva-8jCF4s#cc$GJ zp@v{Zq8wIEM3m7Tx2G08kL0q)5ytylka>CJy-Ms%>5UetdCy^*!Y8Ow^ClvsV~(rP zE07z>-r=S+m)0u2j(P1sEm2y6XT$vj>jYfR;do>Xoolo+GRE?P3{0osb(+$}0HuyT zKEyAv(MOB$Jk&N}$Z;)8!~1`#lrGYHDZ-ZC=}?F7qs|`hhiC?~BXg3{VJ;sjljmq@sOtU3u@Ktr z2!|(`PJJcXy@A%>$Pn5!97N-HF4zdPKKhQ%&XiGTlO!deF{^NsufQk_!AzxV#|t!x zYR4$Vn5eCYLJ2>Z7Rwr~LD<&lym*b48X4AT$y%pI#oLAKsg%(g{dauXHy1mY2_?i&O<*X$6BlEUj>`SIDjz3Xt3!1vEr%+;@x4oZqZ*a8{c4e^N$q9v#D(>wzp@4$iv~r8uvt z7sEM^I6pX-I6c-hXR{jwPRY%|c>;1fWaA;QJslY8C1BozMiPF&Sli&P*4lnHjfa>w zS2~zC>YFx~QbsYKC@EoWpL$?^7VZ&#N}?Rh4KxrU$w3w5a-gp%^M5h-?QvF4 zZP?RcS8|v^spK#T6-6jYV#2VaVWg5n8Rs*p8FI)wnHk!4!-UjJQiMnh71L;T(}5|+ z$*GCTq_DRRCWR@f@4D`LJ!|j1dggt-zweLl>-THV+I!vWa9#Idt!F*!S&z&R^FBq9 zx$&!(*)KXX$$PBo)%bo0&4+$Ca z1a~+v)C3!19DsBrXGIn|i}@cSpBWa;Ff!SY>Gi3D@syuMd2Qnu^Q5G#W#J+OckfVR zBnZ3-qr>!ym$0 z_qleHu)apx!s;cRlQH1~BSTn=K6YR&&^KgGr;NhdeX@b&7f$X*yMW~vPKF>$eTL(a zxA2C+4hwG>?6~mu5<)NahUk}kg)KT{cddYH>Iuu#jZJpbjOQVxy z+?T`HaA~xyt6mz_>9qA}#1_(#Lc?}Etp)0vPm3?787Hi}{EFGBG!!n8mS{m4=i(Tf zMtrd!+`#-C7`~98uzGn5ey=g1xfW^sw?%Qmh;;vmWF@46M8b zo8s~%umAIk@#`|&HqMZ-0U5eEb*P{fO-*{GzEcMM= zP~(kfNpC4>Zh-lXXAht_#xuJ!q{RQe^LCnMDDYzy6oL0);E%oe;oNsV&V(V}cRqsY z_Pb^H#*de|+D$unR*)pkldpolxIK+Cps=hdSNJh#h|DKsEQB$52M0ev3dRLthZx zbD?ITj~F8)%Yk~bhVmNTE|1@LKI5bYoNW|>F`Z4Sx+$57pGT;(`QCTF_5%lk+;>(L z|Kt1453oUuMrI;$4;u9DJKt(tm6Q%g+ETjccxycu85!Pp{(>{zMC&p4osXl8Qu?Tr zOuF$snH`8<3IBcNJWpp?w>x$j(?%*gsXVQD`1ou#{RRu(`^ zhN->pJCEIz&mk&QF_Sk@Li47{pNW&@PjLzUVDA@eLeKMzUl8dnNJri=A>$MHnTh9@ z8<~-iS+h8fwAq&k8O!v}bWh4C(kG>49*)AACryTnr32w2=}veeJHU6y_qXqmXPc39 z)RtfvtM32}XaA3N_1*lIN!~OE8&ifpfu*$p;1IMoVg8icD7msRanUM^jjFRx0lmrQ{`H*lJ`UVmt%ORl=vhe5wjUy$uB~r8q*@?VCcOq{9 zUMc7d6w7WS-VL#STtmgNwBd|aoS^Z5+OU{+_@GcW4oa4s;_ODaSH?y{T;dyVTvYHQ z9mjuc9KVqf{G4f;=q85#z20~pKpBHyN&@f z>xg=AA%lyT_&u>w%vEM$q97YPDa}d4p$OilFuz`S6u!oL9m*`@ExgpiJsL>5n!rGQ z(~-9P793;wO*1m&_vwhk@4xhh^d>r=^4niZg5O#neiz&#{7RO??{s9*2!h2UU<^eP zZ;H$KwqI^vRS4XA^c&iVwwy*^k>d!>`O=s{;w&?4tEdC&4-mG=y0qi4-W%=29u@b> zEF(n|hX>I2MKDHbGn`qL_52C)A3)2Ptz+&T z*Ap&MaF5*RiPCI!Bxgigm|tH?r=9{+jQ>&}B}iL+Z0l(Ck#A(EkERulK7Q3Zz*kX5 z^)X*cLLZ&K%GxXFb-h{iAz6+-4n!6@J`L|>oecVQIFfTO_Wgqxm3*It{2-Bme5uqS zf5A&>R`i8Hb?XKn5F!y5^yOtM3w7{X0F};Omy^lw3>NfbmEym?Z*)XInWtA{} zGZtnU8B(_5eTT9IdKb3~Wt6f6Holn_CG0OB91g_r0thKHK)K(!r! zv{l>PM_6;+ZA_GEd-y#^ZFlJH=x-^bYCBCzBAg5bGI!ef`n94q$#T^81hPD}=>wDT z(_|uR%^m6X@9JTx(>HrtQcjMrC0PzznaE1;fWyj2&ITcepCBh4zEDtMzVI;Xu;c^reF)Pe zN9uLR*?cu@=0|uDy1&ji0^xp*w1wMCI<4#fMuu?v&voGT(0kw0DWh(M>;aqOdi&^wLUb$$lL^(?Qc6gejk&` z!vM-CkFQC|yxzfZF6B4+$4E(xPJRnUbyo#NLw;qZ*9pq&B&09_uq8LctvkAA50k~V}z6h88tqpw*GPekV`(~%Qv#}@jXGj>5MP-8(F9-T1IojKQEHVg|V8c zTqEI-A4u3>*gD=#34u8Cj@j66WPFEgeuuPW^UQ-Rn;#n)vU%|=ht1R1%OLeCWt7dP zQW9*A@L}`bA;P9)Ic#2qtoZmO-4E+H8^8W}9AQppe`b!CI5kQwtOg@ydX!qY1YhhF z=`M^lWLFw?*j+yu4V&>KwQ#%?<7^Tp+shPd@Vf5aRMczwr=vpS3*Awn;j6plfBfx~ z?mJsdN=BK4r4x5%l7E1mnG|eFH_!aFH%?DorXn4gU?v@zdQZ^4oNgr#BOom<)?wiaQ1eK;^?JF)(P6_a6rVtN90_{Cu+GhXmLfZE4 z3y^3o!LBwkw6*m!o&J4REB)&e@84u830tf7v9*2KF`SXhEXUUBE~U!3){VR3nbCyR zq`Wji63(ASM?;U!dtHLutz4Ny-T7a`1XNL!d2p)>jq zU9UPYfBs%z4x)^z;cY1inAtVJ;>7Bs(L7*EmIHGi!lYujF`&3yAOXa|oy>02XmB4{ z@|CBQlQw9ah0%cums%ZvnKO`hx5r{oF#12^b?ra#PDa||{cC@Vcbt(S-u+y>f36k0 z*HcFEE|QYKTjGPa2bu?7$#U?vLzYn=!(0RkL6ud}PcJ7-UGGiWt}zsmpD?8|2j(Z2 z5N3S4hCHSf_qN%_dkA|v(vka&w>6E!o?v9?ZLME%)SRNQ@1Tsr{%AiE7WX#R=z80! z=vCa?M8fg5R**n@`zQ3TQDXnDmsaF5ZmaPyswMAbr++zXL@l3EM*DZ1_OE^UG9R@( zj|E7mMY0^VJd7;$Hg45R^ft%4q_E>%nJ7%}`bfR&RMTbBejL)4_Tqi5wH=xOYw8RK zR%o@r`h!-eur8I7u(ova?ReLR7Yi)Oa$wCuR-&~r;L+NyzN`VK`UTOH)+UuX);1iK z(W%y}Q(bJFgfP!R+QNLLrGvF`@5A;fw%YRcFL$FE^i?LpnZ9aD%ygNgmLzaEK!kUHT^be zfbD=Rzr9Z)n?_k&Y?;CM_W{(yKRk0|TvO-+`(2F_5$ZgoE!4KsVTmO#8yQ0FH{F4n zCbP}fV=1Fh*ETm$d!c(S)JxDu#1hGJpq`2>SW8Xv-lq&iCf|*Q_aYe6<)o_1l9||e zp}L&!-lvDAIS^#;ldAY1?|r(B4dQafP=7xf^!7g8X&jc6UW>G)^n+&B!3P={?tR+w zg3}+f_vr-6D5YU3nY8z596P{KP}g#HV5QI9`y_pYgc13MB4+Q?{cfAG_sQenf7|=? zRx%ZLu^F@X={n;Wq~bE9EfwVfOU3y{hI^mZPj#p;d!IT|Mybe`l74%is*@S{xj!t; zXYZ4AH_l2W#Kh_n=H&5RnP&d|oUwZ1cmnB2?QdD=P*wCdc#)a-{maPEOWM0Q%$XZk zQbuu7k(G46Oivd}_CLXUbR z_GpsSD*^cEgdSBs=k(|a-Ak1c@6j-?N4?OZYg*OkNslDUF|B#XTA0J9>t`YOdk=8o z;sIM&uyKf6SQ;Zkf-Y-z4C@{gm*IyCA$X`Ewde{cCLA~fJ?8sV25_2(-GV=ylgYoe zY$;e=G$L`M$`=?r+>I)=m;ltk++{-%rD^)hVfv;pzwZ2dCr7hw#>lANpOLoey`Yg* z?@A*>^^SVhA@gkAm^Ftos@^my3H9dqkXeu^WJ;Dp=FP~85aPmVWOO+?s5_;+=@lFn zPdOfo=@I(>I^ke2lbRe}k3dZcP%lP@VpC+)4Kzu>`zK7*;=Llp;{Dl}F!2`r+rc|f zH%cv`jN(m~lE6FJ2k%qo3SP-_@Qy~78qZX8&~sy4lHsM_*#E>Qv_C-TCP*pnfb5Op z++Cu_w%G|J_J5h~Q>Cp4@onR=_wL#0h2EwK5T{LcAl{{CWYp4c6k=Z~35cx9_1MyL z1fpa)9y<|P=*8p41KFd8k+wbhakuT!NFzhi4{&?5Mt4J96z|b2DTyA5TROADBeX}7 z<&fS4SxWj23@5(Rq-@UfI8E~L*rjLdG>KQ!Re@V4bxUC+MVDt8zaYdHkhTyT$00sp zWC-zi6!j*+65My{?xou(qogl`18A7^v8z7l2*V_^9Ej=2QWv^s2VKbL5#c)!y9rT> zJ9f3MA0gIzkDPpA9Du++MA`!DBHfc{`>v58uz}Awz&a?fCn=-Ae%)n&iCH_kyB5s@ zm}EJ?&PSH&?hcUZ>o89vkT>KoEd)P#AMomRO%Rbic}hS?J1|*qj4%nxhmaEuO7!Q-jO-ovER0F-XW1v zAV`>5%{ddD$C(ZMm7zedEuP1(>~~}>e&=X=?Uke!8jT+_Dv~j5X&~pf8?PbfIY?X1 zm%xS1bUE9|kn>GXI-P%CcPn+JjB*~5l8BHg-|x-&uD-&#WI3F#L)OCDT8zLy*VD^3 z6pYy*yW;VQIn4&3IRV1~*_GlByDy?RcZuUQjRdy-5q2nZ*~TE?V*_nQTYRfV8vpq^ zC;sKToM`ML_#J=w-j=H9m-Fpb?9q6=1`A6~c-n7SEnXXy_oi&+K!M^Cbp?p%t=Zl^ zW!PzBJd~vFi?k*6P5?8c{$-4pq)wXPkb0wTb6QCmCAEi?1gYJ9NPYDTAyu**QpY1p zNqrcu;QJ)&Do)5isuXuf%|da^-eVz56qTd=GA8M@6*>TYTjF&7HS9V{Hs^)-#has^ zhdFBFJTCYf!WTz!04c$;SM>p!Bli-B8+jQ7G`mDPBUR;BN*A->r;DIQoF?!&W}(cg zk}jjOTBu4S^=se`JlSEO>KU{0lPr=9Cf3NYU(j52~Cal(bV6k zi>4&Y(bNyflK#R3XW~Y&?-ZdM0y}jj6*#(@jtaPVxkmN!r14Zjdjx3vRXvK*}hzx1=PXP4nWpX7fHzm;#d##2(tyhIMxnX z>T*Y-246Ma2w!X{j(yup)%dLpiadNmf()$U!BZr<%r_24sI!r_P}Aa2pEoju+Pm0+ z+Crh;M;V3s%{G$MKy>Mk4gsoPbU6W83iW7My{A@OhQ<$tc>tq9L(%2e(?qSYU)5r3 zjRg|eS4dl6r%Cr@BDB=V5LnK52iS?ayJ;F_6xiRt8DMjKEOrE%2QbNUEOs!m;Eb|# z6B1|i*@8a}F`3Y$0>@%o3A9}s+i(!e+s~`(>5KO4k@45ATXn}QuqHOfC_9|em+vsi z?b`PT{z>c0)gEjuMt1CU&mi~`Ihe!#pW*7VSJID}b!Z6x0Uw)RjyF3^K2+^MAE!8*-_e3=cu};U;XjtCBg%E)Lw=r0Vci%+3 zcm8Ve{uNe?#5-x6gZD<=D7BI@inoW91m0{PyssiK!ki?_!8=}JCZlLQI|^8@gE`Nl zPLVZ_Zo1~N0^yT*r5XosCaMvH^XWlSjpIR0 zPz^$GtP!p|!-HY8nKhvj4IY7?jV}=GcSu{bXG))C;Q!dj5baHc4%$<7&(y1wQM64x zw52|1?>$k_N|uB6DrAW4^5GD*ED2Ry8LY8LH;ve>o7I)vZqZQbtvCvy_BtN_|xG-EpEC z$#PUvi7bsx<2bLxA+EHj=)a+9FF@gZZ5&aC^R;3?fD>G}4gPm6iga4+CGWf?2EC~kF)@SWCKHSnt7?doB!HbY3y$i^NA^Q0H=S}>t zN1uWhl0vD*p|ClsNxo)4r7$m26!_&K?LOhIMLJSz45puSS|&fA85zR8^#KQN?;3&o zI%O1Ya}Vx`K5*|pR^UpO1NUlVHE=AqkjTCStl{omJsZ zWBA1M%>53g8&(RYZz!XfPLYyOVTKQ;SB?=(lI36uBTH52T>##P2;>d)@B+LV3U~H- z!CQ^EOchEsjtb8;)#!_+_YiyeIW4@togtg{7n5cR5YJB$|u0y69&&C)_~foqDsnp|<0z-%OE%p41j?v#!cwvU zKi%D-K|fuOEDwpj_WBHHLq*$xuAqXSa-N1JaGnMez|xMCG~l+ys5Q2#H^&$uN!?e* z!*F1PaYv%R9%+ld3S=4dgNzK(*X23r7k(k=yHiHd7fZFr=|1RF))IZa zpy#Kc*96cr0rc$=>xtgao1Z|fvF~~jeW1Yj6~W$%v<3U^cNXkTMuuRUxM06nAz;s; zjDnpeB?0zDpICJ;+Qub@WI3^_{z&tvceDwHu22yk%!PjWDF`(IgiHWoZv-+Tl&YL~ zH5*mMcARGQoBD442)JZHEsoaB#Zj-K^zv5laO-vtW5TwvN4QwylL{a|B_u}^UC-P@ zN;V!`vN5e>YKdl$^nJb`d)C)`KZ=9Z%(-&!LIn!2I%jsrhXgSMAIvh>@Tr6iF%BbbsC?#Pz zQ6I}$b+}lLWI2`-L6(QJxKuAKOz<;H_Z5@LQ*m*L{FxZVpZ=j8=1`XnT*w2*_l)3S z1x-ao{1mg(1k8>J2rY*9(d?ujj@g}xe#9Q`Y0Zw6u9c@ETS%q++>=_EEfRsUyB$Iv z{meC*=kZIZXg?{;PZ$j!>?)|>m&SQ_d!WNZ(+7lS6WoCC%Y+&(B1AO*4I^=AF-9C# z0;4)elY84z=&+-+Lb0q+EzY^&ix{&uBw5oHhk^dP{(FNr{NFVgH?vrKtV30>+bMbN zbXcvh!|E;QT(s(IT$75#ex3yP!Rf%8Pl=bUL~~Dq>)$FdjS>ZrP_p`d2QzqRfAfVl z@z8@X+k-|pT3Yu>f|l6b=%4r{RJ4=?SMW0>_qec_m}M&?T{&Hr%xN<~RAftSujFcb z^H;W4a;LB8B;+g9mZ^^(dl;2Y3rstfZU8`j~E%c=}~t%c(;BmZh9?c)J+#kNw{ep;JC~3Cm$+qDp`)3wm}v` zmbjvsoam+FhrjOzfqV|7pn{(;^9eXe)P5<%m$2l+qWfWZp#w?_jswnX2M26)GVY50 zdJ;LJ6ZBmJRi+k=Jpy!86-~o0Aco0mFNt#@k;Hs;9RJ{mK>e04-zMrG&C~84BCijS z@*u3AabptP6KPBEWGK-Pe2kGH!He#22rl_Z2yR3fC3v`$1i@{8+?(JPZG~XTatMAG zS$IlY`d>VeP%-IKY%+?S-j_#2v=W~A37+p2!!lpw6^D`!o>w6llV@qj;WFOL6R537E_}6^W{Nm?FU{8_!;UA2U;4xB5k{2bC$MizO=M$F}6tB9=qM4 z?egV9+eeg9+B!)|(3b5(+p}$iHpy~m`xmmTtIB}ka~{^dH*s)iE8OuD+|^;Lc|nEw zvL0W;k`L~luTk!#HHW(c(OT@t6X~2{jqnKJQEjUW4$J}CO?N6r}k&<9%vJX2C9wO{Wmc!09$g=EYV@sSFS%c{w0G%QY*~$YI z4ikd-DWj(*FnTfpVhUF(G18DjOnqw*bM6UVplh55V9F2*2KV)z+!wRfi4PBRsRJ4y zTqq}GwSG@bO+-*={2i!qn5?!3o;7YqMjuDoGPM$DnP#C>}GRo+C zQWA`&|FpN89tSj-=t`EuXezQiXvGs}(uq|0J!?o|x=_eZp->Z`kO_e5_l;60H9Hi} zYsL82O>B$xdWW~1&x>`$f8#^sfc|7T*!;QW;C>@R4i34+;o!#)go7cJQ4Z!vNpR51 zhl69$9o|o1mczlm$N~rKB+l*iCbGqkl_DM?q?F=!Ht>0L+aS!ri;fmf_$i!d0-P`b zPP$=4Vyu#u98RVm3{Ey5FPyMi430^bwWUP^mNf$1wwCq&+$767`8HJAM4kc&WEkHg zt38mmtWH9tGXucUMux0b-sG_Q#8P23g)++OFewREXZo;Ojol|;Rk9pb=OGJR3QW&; z;9+>|i#s4Ar~_Ib{+db{B~J6zyvQ+Ghenu@$O)sn5~=Fw_@&t+P;i3A+cg zCd^EvEzFr8TbMnK3}LRg-hnx7k-$7K4)aba37BnvMx=1|d8|tnn3Cnd{191a;jQ6l zAv{hNa=p#>kMJIoCPtJdBO7SUTHA!_{DrEhWK@-xBwd1B4yF zCGMHX@{GVPojnC;p`u=bpPzzX6Tr^|@gt}czu$`YK-3zWdaU5*j1PBn%*j}dyvFRw zSjQUgBN>MxZOIt3+>+7K$dHUzu64-BTPS4wL{CvN&XJNJLl(9iQ+aoPA;WJa?Kxz5 z{j+4e3uZ$_X9yYm6f!gcGME4vD>z>T8Gb8inW!~3;TX|;Z{yAc+YM<8wq%(Fd$^Gy z*!kBuV8=xS><;>if*m3y0d|~^Uo78Gz)F_m7jGg9E&R$B%yocHFlyG}HdRrE0OqFv z)&u}E0l>ANDqyMEvHn4*IX3NRFFIrQ#wx~o^*X!C#slMuD&ra9i~$H3*yx2$HNLW2 zN;snjE>mbdxKLmm`wl?wLht?+cF*3A?m#=ngB6oq<#E*0gwTZK(By3`v zk4?;LDK;Tlj!is^tgv)4R1}o1@)K7v*JGqCs4!nHld+axUlDuXqOM>JeV7UWQ_C7+gWH}`FM3$Y) ziqXiGq+MjrngwD-37#r)MHT#%qfs@1qfwcF3I-uUQ3cYNqk?5EL8rQ7mG@yAllgcx2F>Mr9metdyOgyT#}>ok?u^SE!{JrX+w8UBSX4ZT;v+)YZf(rBH9DE5&K2YyO zY$dZ&ufyz}s5e%Aq*$AdaXh2GAv)6*C0Y2?T^^lcs14G23$A@YPh;cqr1KA0rls?8 zXvxs|ld)LR`7q*VlJ#DK4ak@wdV{l3wlZ*S9SKWNKkQYy$0js3Z?YB`Kem=SGHn-FCUd*Xi#HU$ZEqe6^60;43Y*cTjtvsqiIP4qrLQ0$<*G z0`KB48oQ2TZamb{)O8u?kb5{74iMt_38444;0R;B+<`A)$p>+H9Iio}H0ux-YZA9c zu4hNv3o&09`zJ9UB5jH3vd|Lqu8|=z1BW`qbeJc^JV_ZP=GO>IHsCMUq8qr{_VbtX z6M6_RM_fsN$rj}N1o9r}b3ujq(g|O}k`LhrFv1YIpWpn7%h=eCLj~@7;|GMh5@`$f zbm_Eg1FAAIgnQj(4&0OH3fz|{qi|C^xIrH~7=^Y0SF#*C7>cZaZU{%PI@O{#RDNGC3-%72^C!>?ea4v zH{EnPoUtEflkL+r+np z`DT<+=C6~I@WrSP^WW@gLgppQVg7w&p@kV2p{8)YECm!7Gb)v%tEgP=fBYM}wL(QX z0-T>>lbV1{G6AC3Axx5JX~iLWFj|RSsNnk>Pb2ugNL%pJ$}RYAMuy;*U+RFLTq@xA zp^SpRQAz@Q_g}L1ns%<*E#M`~0UtpYG(@=lfOfrL=ci!T z1h6v!p&t=LiCr3TuwRZwVi&`JfF;Yg5V7||+G3wE-(o+>$PoLd10C#B-V*HlQ%14h zDkV8OZQL9Cn!g3RWI5OuBMaDdn&!QAM!xAanovOkR=hx~zgY<2C%kPeOrxMezT}P$ zOCAJk5g$o{wC0d7h#koSqQ5S25PkHf>t?n1B~)~~G{{eEE{kLUT!L!_wDU4iJdb4QwQ$4D&-AdYxz9ZgaTGY*C^);Iar0R{DqQw#q-2m{<9Fo%NrKrVjT zH?@#^jblyX781Xztd#e{lo=te@*o4+AS9ZeZk>es+8 zGoz@FQwDd6QYFiA%5KQ=oD%w)HiiRTp(vG~aJ|NaR$;#U4igPaK7_Bq2tegZy^i~R zy#q0*1E?{Tr@mVv`?@|#8z%|#b3a)On!nE`c#n508utiNqQ5^YdSQ47XPB!fFmY#) zYf|0!UX!}xQ>;miJTRd>vyZGPSGXp`GpsH)%cdqfVcD?=$mOj*Xwu&GIE2-HfbHld zv4!|FR`I=9#ZX)opi3LGRXJ4V_efi1o;}wp^K&CZW!{$MDD(8!MVYfGqsnX{CE=l+ z!Hc`7@j$&OQ?eXo<{-;cW}p%@Mw;V;A$9g?98<=LUim4`stGtN6A+q!z)pQi)s8*` zQgvXru|$IX4QUH@@Ei;F2O~qU4-Ig@X1yk0Ba~6F?WH8Z=5N{??Bjn5Sjlq0jzU&4 z*faz7(bEZbynyAWfYk)RG6AqN$`q_r?SO47RR<0jid1>h18-VnZ|ire`?q+ z-V}mAcDvahkkGASgHeBU=vzRD^)KUT)L$mjR(~@~t^Rr%8R~CEe@B1QUJ?BrNEy}N zol+9|%RxJ?XRg~W`jae2e;*1{%$WI1Hshb*tpVN_NX&AO0tk;y_AKgHuU0lQ}cLhm4|k}j#zq3hU$Dyv8W8< zL&1GsgH={yx1_O3p6roYbVia@)>0PF|6HJ`$UQY*b8EcrDyf@Qn<-MXDPA;lFSj!bDX40KJXh)su6j(D>|Ct}q=aZNO{$%! zT$+(t?%V7cwi_dGU)il6IPN@$vmGxcOz43#C7SvYAjk`A3o51wz%iO=oY%*j$o;1c zwu>WewDlZqp%g<7}I(&rnWklc)>Ug&F3kk zt@-?cz-XMTz{t>ij?8qZ*fL$r=W5ER`7Dr<4Vce~=o>E6{miG8cH7T<+93#rie`xU z@Kel36EGhpp!0LzZrFUve*F*TQ{ObTa6isD>jSApy?iFoE#}E2dX#Y;a&;5ZmaC6m zw_IIjWXRRFa~!S~PZO?Ap^S1>A|=6<-z2&TI?W}Gjahqbk&14K;{o(5M>2TN6n^-L zN%YAwi8f!3!I!Y)L-;U|NjLMGM3(318p0ftm1i*qai&MG6J>ob6!# z442l)PdjXoi|se0v;0J7KgM46f(m|VoOk9wv-z8o-DTxwbi5GN{12r;it(6#v-Ei= zT@uTXI--bSeYwvYmty#|`;ETmQ53qp8V6}t|H^~3q3O$wSI{!DkhYdlI@4N4Un4`y zSk=#AY35Y1jCPb!%eY5M!ZKb3P4S$&My4*qj>LP8VDCA6<%kr zgjHOGt^D>~TK(_^1G)0B3Gtj(A@w>uTNXZ5w|30w>Bmb6Yk|wXY zotj)An&c-m`6xEO7gU%p_v1@g@?p_OVYF!|@;`%mV?V%(^`Vp7VA}~#sg8aTCBuOZ zF0Q(NCq#EffoL-z)wjTVuYMn>^A5Cs10p~4|4%}+OxA+1mxLA3Z9jvRrX~7TT(vf{ zie=PC?&Y4};Xy1fi7J1tqZOsyvmQ1(KkZokLA+zaphqd>y81+AtWW^FVJF*k?wU# zBg^kULi=El2R|$-7m0zCAS&J9^(7?G-Y3RL*}qDpZT~vP`&VjY=&S?W{JMK|nT#g4VpEGO*tlOE|&6yW?tC^Dj) zgb^Ys!rnMhP_CqmqU<3hp|olrl&`KAl#=D39FHtPsW0E7=McoHw|Fn#`}p6u8Zie< zCcOe-F=9GJrB(;;si>8&KnRGf+M_+vc{WTilvfK(2OE6UbaSL5rN*&tooYGw(-#5Tm4z7J#IQWt>%0YK28Fwt!=sMPv9}*o)Bpk=O9};M9lxds&y9sIAzmE`0jE*id zGStzwQ=R@TeoFdxO1yt1QW84yJH@XFJJwFK934fmS+#*_th;JGd(;P(!-H$_7_O{&M!W;ILfx?dohc`BrWU>lm*OEMdfdDoRMLq9 zI80L-a7^<#GytiM4*|znJsq7L0378s3ZT#z`5cX3Ja@;@-1T}iH_oNe3xaIOCJfqV zqH;N!J6V9kkw)#qA>ii|I8VU%ICbzRY&}ve-KdIQ@toDc&&CJn4+TA(z7L!rI#@y( z)j_(HjQay?bp2uc_lf=>5{^II3JJ7#ooSo>yDYJP<~;Yoz!t!(J+d3S^aWf=DI5%P;_ufBY`PT4VB5 z%vVT9rvH^Cq@1Sh^Ie8ZjSLl2cM^IDh4En3lx?_i@fYT(n2SxLj4I~uN$fck(*^mF z6Y!C6c|T&cn4n~x%PhFD@#DeBl7m(A5P|D-ic<&nMK+tVSV%FlT_7tjlaecF9>B(4 zd55QVO86D}UGNn25f1!ryoXR@NL#1_q{A`~T4iJiHQ+)`Q>gPOqfig>ppN!|TJ)Vj zl`IG9t;mA6Nw?!CKj$L0c!xyc5KJ5rg;!AUkf>P*{Io-P61zt36N=lzW+ETh>qIK&>j11pp_|Az=f6TiK zuceGqx=>0cy~}VJI}nfe-PnO1(g9@<7dO(!xGA-yh_m$H>r2zVGJX_yy-FARs(J8O5;) z{wD#U7rN~Rgsaghj7gH^c*(iiUpc4mW|)OHWyWZPw}#;WHNG|M2@C`D4XMEKjV7qT zgkE!iVhFE_gWq}g%Xkn2QL-ZsVojGUpzV6X&<8g8ct`zxB zN~r#6L|>}Dl#Mv5Zz0$+fu6dnjy2PGfg@TOGx#DNVZ9a%EyH*GmT_~i_u>anPWl0~ zb-}TrpZ|I3`j?+unr@E`ZSEZ#+GX)ZjF1UcXbBuDT0Bn95&e&4gW;@%#uq&ZRcBS2 z-sA*B9|yZE!Ko`7+xh++EQsQv$gG-h|IWd1UTyePY-#8psto-WsYzDz-(QK_1F}#d z==)@rrWS4Dcvi49=p8gVc2fpf3dy=t;<*83=VmUgY^-Yvft63@~^YBvEB5i9?IV+8{{XHq#bpxJ_9bKW` z6pF{X76LlZD500X!)|RahsJyPqp@e&_JM9M57S;QqKx+P2<>J2@{7=-8_gzsDYh+H zj&0wAENlXiHNCtOt1>6+3}-S7Sj3$f&iN3R2py}y7zMP-dqyugb8jHprlTYuxVIku z!CyJ4-9eTbl>pP<$0_sF)K;V|2ZJ8Bnp$UM$ie=dRi0Bk@$a_3i+@*8MmacCN@9wa zKJhAuDad%2vo??;^*G*r9O_YW zreXgFcK?iqQNB4hGr982{Gj*HAjfFb`6TKLWljrcPSb-AkAySi<3SS^N4}hTSS@B= z6@3KJ&y;7;_dtV=CwCBeqiSUMU=%I1zl@O*=@ zHR|PZq^({SK#k^_sK1e+Uh{q3 zJKIYZRE{>+8C`%rlsThd%nU3F{0W9Mg=Y-*gfnM=o)%;a+LGEGZ9RzEV>ig0Jb@F5 zzvF;wn6WqVa0$|uhq+lHkE_{Mr1u@ZdN8e1Rlq#Khz>zB!s4RA;+)G!`7M39u&MXCi)rh7fP+D>9=3KNA>!t%YnM=p$lN~1~O~>$}o8_m#kd6-A zYwED@q@$8qc)AzAgfibK81qI-?)CU=oCiIa^739jw$hfvP5<^N$q)*C1FxQ(B}@1BR>(7k}SuhE<+Z8ihhfW zbEwnei9_+n-X-We6+7lK=N62ao05xFb9~~(!E*s~JUo;(B-J`Ll!9tw*XnIu*2YzW zcJpZ!<#Rw*gah2dB6KzSO%cfod~VE$lq^BoQgW;SlU0H_MuwDppYBld%VweE3CbuX zn-DXEk`f0hN4cfw#jc&i8$l z0i)SY>z#ja8*kAE?m0?{BC)q3ZHfI9#GB#n3L`^eA34$?b^=dJ2)90!GD_@IQWCay z@{{%30*ccW->0uH6StZqgIGxfmbM>u3%zfs8AhcZgmjZ!l2R9q||%w?4zFiZ{)E)2Cg zx_@Y^JkGPIoUKH9q2CG1EfIvOjW|-{zm&>nDPS?tZ=3|Uz*yrQ#F2-z#Zd!ZjM8r~ zGF1A6!yOz`^u2-oD5E&0N=c4cK1x53oyD7?ndK<`4~ENvF_Tkr55=F7l-z^C09cUa z%;xxMTnZN+6K?%TEzY#O6t(cy&wHGAh6B@$krLlTq%FRB=-A*ZGBU*X_F)db1#+%J z>uV^Z_##pg_@X}ePD1m*Cs_`@Ly)y_1QZax3YrdL)CIm${KeZz5h(I{Mdyyuxyx#O zZSY{kcv`ho=2-Re4+(R1tQt>aXf=x?tXn4C7#<7OH3}9j&)sKSW4xlcQNfl*@>^s6 z*7C*>e{5W^rLp|jR0QR>rUhG?hPEz>H3==pTaC8`XJPAjXluc`rYP1-CHS>5zBV_t z@OvX>YfI7>45nsUdiwixWNI-@dnu!MDb1Q^Gy#5bc6ZIed2cJDEk!=C(O4O^_C3;8 zYiEzOTKn9{P-}l3>S(Q5RJ>~zWmIb|q$ISKRu9v27QG+%K(r=Vj@ELJB^@lN%t2MU z>d^-#ZeGQFU$5xj52)H|!C|GbT4I-1e|}u@+{6P@-5Dv zjYSgY!7k1t^c9OsD5E&jr6h3n^1=DkQo$)%4$jfY0?x@YV+4wufx`E7%L_RS1D;gk zz&iz%@O8_l<3<1~8y9XNRTdAf(MNC};Rq4Rti*Z_$Eqw0c0kp)ouj=V&RURAN5VN} ziVnvwq0DFj-z#>Q)SQ9|U=AQAOaSLCF{(oMU%L;zBplT6GQ^@|WpD~iXs>P2vWk$l zj7J}`jOQ5{GCsYn)3-Np^aBRDODLm^zbPdd@9OuqtPbcC;~ldc#+zw(E#t>Rb7m9Kp^KOL2vC;Ru(IbBVJc#)T@(OOj*ed zXR-`KoViy;OP=9e0q?CY7_$rm?b9+Tlclp#y^d%Z3_+m-vFw?xiVbIUMuC|dv0k1z zQ)l~Jxs%suXXEcOMsHkAowN6Ed9BTFLsbqdt`Nk1HmL|r@UNI-I+ku{<~@&ZUbL8L zKt2AR2P%IiD8SS)wa8q%zh-QTdVU^htLGHNSQGb)jSTfX{}4ydOZ9z(w@^m){NaNv z$++*M=iZAn?)&KZ2xJMA@Zib8;&SOJ{AW&?x7%dcy;OW1-hmC)kAS^vii;FjxQ1c| zV8oGuz{db8D>1!^5q$z%sYNU0m%xk0d`ZJINLw0qAZ8gF9x*bc;hokF4Hf#zz-uX^ zG%S>oprQK?n4=R&PeyNG?vmx0dmCh#KH}oDD%u?NcsJ8v?(sLS3`e9UTB*b__b=e? z=;p_5w3~#r5NQkRs5q>*j0|CY*UEwQlfD};Oc{k0z29hes1K|w(JWv|mIEt8dK8bF zIj|D%t~@S+@XljQ{p*4EQMfl@NhJ=fzaosAd%em!1M^P42MyCscv9eNW1~d99O=mH zzp~K%s%Tf~yIlErc03F+KOXF$uB(;UHIelw>faD1VbdpKzPZf2fU$pQc|W{X3q57^ zk$ljRFxk8WJ>A%?VevAG!}iQ9^C*a;C+!n@o|@S6kg#y7=cj7VzoU%y zyqESI@4xcV*Q^TBmt;BmDnS+kTn%0hCvnc1Qc4kLN;wQgIHmkp0%G7I(^0D7Y^1Fk zULI|I>f{74!w+)QaLf0ih6CbYZj+J?4BBfK2pGRXdkM1OQ#Ib8JqJUPi6ps6Z)t3a z464*`(0&M&AkM@#$!LtqiU)7P8)S9F&fyDaG1b9H#OTTs`T#q8pabcdwHUG09LW=l1X{$ECMMk~L<=yP6il)ttcfcB!itD1F+!ZtCwSJBW z%TH#4mHnh1aJ-sRwW=Z<+^~nC60GesmP3}eAZ=N`B-gUM*2s|MmIpX2x5oJrn3k4P zMp12G3Hv!}Eb!yHtt!2k;6FSODcusqYSKQGnwdIKA|G0Fj9#(fGIbb2{C; z`)uz>4l#;wHtX{k=lSqLFX9Uni}N3b$~xEM#zM*U!$@1Me;jGK9%*FA_0;_wu3y8c z4dD7B$|%>fq$Icw`fz;&W~ty>vK+3P$OKk)3{39@kn+=<*pV+JJOH z1wUchV=x-oFMP#fSn|Qj;TTQGzqIJ^KLJ6{REOuE5JV_A4!sT*7uBKS2)9gtT3JVk zo-zUgaYjjb#Vn6v4>4s3JMT~z}Q9FDYwoDWJ3l(MU!%HZz-OW(H)+y!F@4r)8@$=u+SH|K26HXZ8x98Q27w(N$(KU!VIEw z?+|mayVra<@-_+C`a%T!5P6%K(jz8S&sJ| zoPaW*7s6H1CLl3XR3kX~DL6F&oJ;^`|51ulYIXds;%#!5$tC=z$8?7Ozr?C-3U`Kk163C`PINu9Jf z^~uW6iq4Bd%TgnihR4%QQS$f*tH&#g9^|4&g_Kdv zuDi|jD2Ns#cO~~|koHKjijsTO8(9&)Qg30+4a?hqGUBSrTLWfWZ#58X^Q z@1VN}&BJab%RzS~vLZ(iT`kegJFkJqpcOCICE_AnyGK%gPDG6(;_CYuKO+hDF4!SYOir}ctl!Z~ETbUW( zZJ+e;(+77cI;q1!*Bf=<8rgmL2^U&pYN|5pP&q*#YyeTE%?WzGG1yygv7rAnYRrbr zIZYhUCtzO!Kz~UY1>Idr%JUw$C|p#|8YA^IELf2-tSPgBJzXxJJc;%YOK_vx1qxm@Gw^tu?GH@&HNKbq>kzffMMoSim!=+vBS5e+^*PRf=HkIYB}B91J8`|2KWf{B>4vT>H(als_+mT>l^zN zk)s3vuQT>XLM}tv5>kGnCFFb~LqeWPaR_;6huA|$$|xcEQWAu`;6uo^*M$(tatNtG zmRfLCwCK`!{7G74?1;EeW~2g#nMtT1@#4RMu`vw_!`QfLPggp`7x-hx#`NT8W6m?i z&u3#!XF7~WX7tkKxf_HYJ{!~7Nb%X2!&IuyNacxC^0P5~f7L&JHfE`@KdPq;>B!R^ zE&|UO|FnHR8#B|$P(4iv%8bahpx=8orjRnKo^{u==TOf+yWy?};3FZ940=t}BUwi? zi(yU2uHMM9?wasyjL3GUY}{Sv?6sVHrK)ncAVu^?{@pv*6an5(de*yuT zHYruzo6JNLRMp_KF+=`#Ajq>Zs^WkAY)qI9#@8I5d=-~y=GmA>j5Uzb`;oSkuDRAa z_pL^T&&GVX%ju7KHs(CaD5Wn+$)smvX0ikEq3A$%poa!0Q9RZ~rH^q_+VToS%(F2A z-8SXf7>|Sh?b(>mlc{)=&6sCn9x&EID(*tsQt`z#mWr#544;j8|1XCM^K48X$|x0+ zrKI1pF?Gp|?0FfMhAriM-cE-ueHKEx8)u~kVj`f6!{T-E$b@MIiU;NxlOc{*k&e`v zfY36IW0H}fmu%bV;P^$KjTuE5#Ze9alYr26&)xyy9QGa0FEh*WlFr&+L`0m&1W)ru zvZQBYMqx0ZZ%74>Z~Q#NJ{wc8N#;@5fmDr7e`aigAQvMYIk=-nyvR$MOH=KJfeuz)pK;0rH$v&CY zc`IZALLMLThM|Sev3r5%jkS`n2}oPQwhy<~J=VyOur>8@s}RDzs+UoG7-f{Oaw&;n zVww+O-2e!LNtQ#{LC8XnEn$sem!4%L&9yH_SSMjpi9^_@FOslb?p!;Yb8Xs4Xz(Y& zP*x?7ykt~QVbn3 zP&7|OajW!2T=!37eME8TAC5jQ(5GF#q>Q5I?x7g!gW{!WfNcIw{~lxeNt(7xY=VoCpL>H>r>_khThW;Yw>-T@#>;``v-^FMVjGMI6cvQW8!z z&Id}(3j#&594HmYTG$IiMYIWwA&9$`u*zEejY3UPZmhd!h1(Js!Z;9OFf z<6I+98K)$3G#a6r#Szvm1J3{3jditlfARXKB#Z#(;A-3nO%KE40a^Fd@mJm-?GDYn zXbgy2dIo8$r5%@BEj?mnXmCGlbF{QdA7QzcGHP%Or6jae>Z7HTr;3&&%h6IBWU-Tx z%9SHgS5>qFu8q9GBIzn-7)BAQM{04@v*LNGr+#A_sJ1dCcVE<43A|8KTJn@2am1Wr zY>zCIARVbaN=M9XLoEyWM&>fetp3em;Y)ph>4>_Q)sHiL4VJPJ=8%-F$Dkf&Lc`q$i+hm5Aov%PjXz6VT*r zb-2GwABw4^Wh$D!QW6%}%Lh#<#(bcWECz)-jlI6hp5LpY; z*JH)*lfey4yAH}Al8>}S zvi?$wWQ38Sem~jlAX%c1&#nMuR>xkX2ba1F6^Rq5Bb##b()#W3yYHQOErMdIoY$n3lwumd-$!#w=v-8A!VE z0&1xh(pF3NUSe&nsga?UayB})c9}jXQ%mismikIbXeryr)=Ck=pe4z2Y;B@MH_Sk4 z%?#uP#A4r&@*P4l)g!ey>bV%TFr@rXGmt}#?U988kd91)Q*#n@ceZ6=_a;To8ORmC zI4oSEkJ)@n8D-%#DY@4SgcZ9pkSR}t6L$t8g3b(N6a>-w?WQN}Z4T15w@VNwz4&ir zB>u;o-oB&{&2)|THY6pXGrt+gE=*^kGrt+gI?i;x_>ge1~Gmr~VgEyB?TKJiOSWHin;*KW;1X%J6WcGNmz+a3-5#(B=Ey#Y-Rk=|9%*YVr zaX&jc>!1(DyiOSf+1vxU%m?KC69lAWIUuh_mVz7%8}lu>qK7m5ksnlTHF;d%jve!H%Xd%w1GVO zl9tf-rip#ONqQif-EOo=&1V1T^!NV+V^hS_x9yiqeXY_G3^P_tYkTwEkYJz zORa7NpXokbC`BA!9Ec)Z1UXyRbIvgxr6Nv4+A8AN3#=kKC4ec|;DEVbwmi3P5(kqb zB@tRi`GEQIaRDP)4wy1z;dV?V2V!pn;U#=*R-P+K-VMGBhD>{vdK`NlfqEE3bM!K< z64y!y4K3y3+PwUbPv(I8%$iu|Qo$X)V!mQmmsW4ffH9nzML2ZNT5eT)q0xZwwfj;r+H zn;&U4O2^q!5_Ht~&@m6O6Omf796Fwru$oD2!n<+!(PQ~o(*hyYtoQS14I-EqzmwKt zRv>DU3aQkgA`_KzEv6R;t_BZz2a@S<6arfjZfW0Atz+Lepjt@9y5rV8 zKn^jMM8FpyZ2`|d*8)D>$WVLFtaShvua!~v5Xz|bMoCEk9_Iu2r*Q&UvK+u4BMV^h zJmg?Z5#*rJx3U=QH_3COn1SKxQQUgt)1#>dq159bEI>Vwid`gc{m3j!eK&)zSr~V- z#`UsrO5gTa9!f3by}7=8$4qL`0Lcpkjct;RGmy4yyl{?XqpOi28{^hEY?x}tDEl*9240*~~?eKJ&K0i}SYf_&2O34OzDt)9uo_LHdT6pN|26Y!GIzX?@6qE&Hd*Q&UN%Bt|E()3l5eKIGf7F~!f&dEc2cMR=V zTh6P+&|U*gr5XFCW}6}%$u{HnO=nrnZa3QG_?^AV(d_xFB#Ks3Mm5__O3L_+7UbFm z8~wa%7uFxifzA`IUBU%WH?Lh9lAla@C?G|^M6ZNA`ZCD$i+v9wZTmj!OxyQfMut}T zbdA&Zus+AqD&F_Ir6jC!sgG4|cv!4bvK*^ijx4AW#~~bmKjsn!n?;XHIv_<#I+rj{ zpk$2LsK@w|mYS-{WcW;p6={An7*2z+;w-*K)v52MoY6s^+OG}MxN=w?2j_&+WkYe5D+iZA^x0nvQg&yD_n*eXW`%7#W(_W)2((D%_|q`#m;%BPMnSWz@tz zI)f#}#Ad?8O3|T&%VX9bsZBPq&SQ;=ZlGLH73Kp|A@5hdr*2HQ^c>0 z3{C7Lx9^>`?{8B^`+k7-9ZU0Q(Y-t#i)L}nAX$!y-N+uv5mq#@(!{IeO?ouuCd4=? z>6lnol;pHxosOJf3w_C~#B2o*7iX;od8I*pym%$z9*(gA`5nW9aqLYE_I~1N;nk}1 zN;9{)U^kze%xgu~6SjZFKryWtzez~O{;!p)NwW7U(w4oJeXQmu85y#-?JGy~zv!bb zqbQ^7Ri7@J#{;`Q?49#3VNbFg_BtbrS3Hv$k8gttAmCvE`ULHCj$DssX`9IXX zd3;mF7d{*cVH0U(Q8uvxDkwXGAd7$o!=|W!xFK$ciVE5yC`dIe5<;;eC<BVjHL(aqP>Uk`p6ASDl1y*)`~KcP-p|YDLpsTvnK{pM&YYP$Gxy#- z7U-Au;HG#Ld-U@S-^DNf=;g>F#8^b|r1T+5;r8lJ@9N5Mg95Gq&U3M^1bSBoG*~pP zMRk9z7K8np`}oVSl7XWsD;Pz1wW9{Am6Ji-RsV16V{cOR-H!U`#S((yySy=%t`!P< zJ4W9w<=ZwU_JCr(kRA7u=kc_$e>E0Z@MrEk`IDW4Kh_QAA-RtY&7mK=f7f0^FN+`@ zY^dY*pi7LGeW7LOWu13hgty);UbdPt%FF6VNqAY@{JQ5@{38^ytnzEM04QJLLPTCvy( zPa-=MjBJ*xQ+59+C(F-^yR4=y)(?U1-axiETDIK5+}~fCcoXvjofsL6E#bSzABf(= z95Zl5w=fqp;=Lj9r7zwc^Nsk?sFA4YZl}GHmTHc)vD7rgAPjW8DWR^Gp`{-D$goInqa*1V6;#`)x z&D@t?Eba?SsRS&=1Q^?efJaM7E0(2tp%o<Z+&^MJy^hp*1BKsRfFC`Et8%a^@+a-d&G)fSc9*BlHrzG+?1`g$9(MKBkQUJmDFmBihD2V>DMBFrUwO z4S7Dm7p{0u*MD>5uYLlo9}5H_PpPu$CS%8?`r#zM*BvXysiNqkrM$ zp`%hhwg>iBsAb?RK(UbR)mvBv~NX}njO$n#4urOJK zjx+(|59xE-h5F@T(1*7|q|{=}lBdUGZL)gudj;oZ0K4CV^RDjg+CPYX9nuDU6Tu*n z_DwBA^zNM&`V)nMK8rF6{r9knpr7a9Ps5-Tu9YOq@~2CYh0B{DRkfci3fABaY;73#^eyPuLpI;uT?9zK5C^jIi7p7fuCDCh4^j^k!yqB>M zY9`*xm{L#fWfb8VyKt$0FB+8696IZ$FS(3%NAHeSmCLH=Ql_fY@g=;yt~|YCq;?w8 zd@a(3=GASCll9dyr1@nIH}TzeZb)cuN*P7-V^R`MR_Z|Wq47eqWLY$Sf-JPqge{P5 z#kA{6uEXu)DUr0P@;M1}Rv@g$ksl08RTjh3Q5B>j%WxAF=*fk~>3qkG5Vvo1lp0~V zWeuCkR)e*`EsR{~itd(PhpKtRJ~=CgOQRvr3UZ9UGPeefD%v5*Y*}F( zvp2Oi%!cth*(9@9?68>azC)PZMj6HIxl$6$j)Kni#r~Xe!mMOj%uYg~W#+7scK@dzhfWDr)3LwNgk z3*imh1>yI!xI%cDlmx=*4hUC1C;@>#BX5Jw4BDzu>XLxsE$A6t!3ahZk=miam@9B{w5&BF1_Hq5$Ibk^5`Z{U~c z16Bw5rW{C0Z-Fslt<o<@=;Eh8;N zy^xB8)E?e!?O#MZ4QYco($XNFpk;`7&lU^u&MkuYTFNNI%cUd`dmRurL-Rl^Sr+1I z3US7uY!8NwDLGgfn+}t0;}C)?{QkVc$4dSlf_B)}>xz+zprvXH^wO~eeK3NuU{Wlf zoH+?!0-kNYvP#LB*p7A~@lb7FSyFPQ7yc8$J@Sxs-?pK(3$I+C36Js>SHfOkRwFfJ zNL(zqEg>#KC^lrE!@I(>PnRL%BJKX9`5dGT%}-unXinBLr1`$h7R|SB7Me@waEfNH zlw`Mepn1c6s@pTmqB$2?XdzO7noNfXf7qKthJNJgVzMC*U!9K>w*0{R7l@6eKWQ0>%F2?Tb9fEjaZlE7fW058t zECcSJwNDW6S4bPcy+m!9-Mz162>60c7T~6v1n?V_QGlyN0T(*}egw^^D@GHTy5aE=(Ze$cOtHIO=Uk}JN}U$k>Vmc`(pI{c`?xk2(f*3GK|7>{ zG4Iz}hG@G5Ewt@}f_5Ec6xuVTWCcCOKc>PS^8m8Y!kT>46zehbd(xyQbR@W90|B>5vRQ26v5e^x2~;Qi0q zcgX&ONC%Vjb=00_hW%T$4B6knAu7Iet=uT=cc+YEf1Z>C`%c$Ur`;{=J6%VWjt2YL zbBjeWt)@)J&b$yKLDmSM@#XW=#l;Dgz~TfGptTtWBO1f$n(8^!tOO%1+XxA4B;m3u zi?o5AxC~!$s$V$t6gzI>rIIkTI%ui_Eyzk)GZy>5ie^0J~qt+)_}X@@KP zKs6a7s%Z}<=YPZ34Cf=yHJq2w2leFlN{mbiocG!woQEi*IBy{(!FhW$Y6rCE?-I@> z%j(~gk>$neAyihEK~y?86CZTdW;o35&$?NN=cf>_5+I%l2)&6YOyZ?_tE-=l>Xl$* z`9*rB7Fmpxq4cA3V2@B%b=FS*3}vOnk_~h+l;t(4K_)dSDyXa$;Big9IYVrSZ@#iq z$yt__j^AKgDX*NB3f*F*+q9?CO2d#gR$6n?XkUH-Ibruu30R2<2vx=aKr2c0 zmX#hs^-3^O0rL?Txp zZHTPf*btekWk}?SRThy)R|%1mDWiz|q7h4i$T1GiH|SO&QnD=P>wqk@&}bQIik?M` z(kkAeHeDXbBdy~=A6^|t60_3q>C5LQDBz>m&6jWSB_R2rx=*U2TH3b!arHQeluZ}*^oZj!Nj%c&FW-8X5^llX_UA$Vm&L-1u< zM&jSQ7QwUM6@nX6MiD$wN`l}O4g{CnA_Pm8MQ{&GI(#+@+TdnOdd`!1Hy zwY)UNDoM)2c1>|P!r~1lh9yx@ssCTUHA8cb3 z(#G6d&obs7qGf3Ar5u9d2mROH5p%buj54=hN>?)@OSi z`cu=zc7K{I*5{|`Px_1MPy7O79YMgP7dZ8&yQFQ^KOFkgyF;RO{@?r4Lnov^ou>N- z2|l$lj^Nv2V-U$b;=}lzq>|u)D=dQht`LIXr;H-FrIf6oKh3|f!v2(jtpDmyso$_a zWeB7El>Vd==ub?5$u|&dE9y^;(TEa^yq#J>fBO2JXn&dkk+}Xe@aibf(f;Hu*Pj~w zZTiz7RoVruVkeQMKlu{-)3mzmPqD7z&uSoL+_&V>*?7#>eXS&U(pG2ku&qwU^{m_W zMtjyER3Sa>(vnz_N=Fng%-xWL9i9~tZi5rOdP2)fytN8Pt&vX7uB=)1^)0n0(?b1 z>ojS*!k%>l?qyI{k^g(oYH(b7);r4;VI+7l(uUybu(s}5bF~Z!KC;vzIJ{H{9#0uX z@JDr6vVxw~=lTkJ*7?Z#ub#EzOZKek!YDtbXQ>2w7877{aD$3_*5={tSrm+1cXkCm z%eO4rv)V%>u4f$?809(Ivogx{tb#vH&-$&2ly>M@3le))>lEo(GMn_vRc&HF{ zNwwhY(jHEO9eX>@VAr2v40Zs&M?+z6j(PDt;*up|umZ{`gPkoUE9en9!z%0%>Bxc> zBNw5jf9Vk``I_5=x!X+O@#XW=^a%Y$^$31}9kV!qS1{HbAIi2X>=9QEh+67@?-5o1 zkRI`h_HYvXEYhY&{E=)3_GuaRh;QGt2;Tdq5PU0T6u}#%WCcB<9gtu!cbdD^6OjKt zcU$#2dqj>f%1`MLDuEus1eokzzv3RT{5tjs3P$=gs-Q=VUlQ#RO(7E3Bfj-Ud5-po z73F%wvSX%46gRA>M=Ve55sgk~k8oFhm98aox3Yyy{?Bu_Q@AsS8~6h`rw?Vd1ibH{ zS)A%EM0KpF>P5}Dl(E)TWln$SsQATGoKm49(JvlD+W5sc&{apu`?L)GBE*3rzT*Yo z5Wl#RGRiL&NlExc8C0{^G|swK{6ey{ z6Dk3pU;;uHa5zWrk_N2#{CqT^1S4&56)wxjk>*I{`0~9{;aR@?L6X2(_x$QiC1>ep zu#VInf<#@5v>|GBEkjgaEkmMSe%&H!?(0HSQ_3i!9+Q$F%IRLDLqmipr+bk;K^6?G zFVp!))+_nId?D)fnOxeK2lajV{B))DiY7V-NmcTB_ZRj1F3CF?#u8 zVe|vaC`MaJNiaGcjoPla;A&x1vMkqo0$B+@N2P_n$72FQ z%Q)JBPpRH=yk@9g2}V}ck2>C4NGZRol$1{SJ;%YN0<#m ztdqFHsii{cI_-3H(zlT|l%~`)l)j{8Na^v{EJ{mX6G|shMp3%A21|m{mS>cwwEtB? zsbpD{wnY|Nn93ILY9L;ys{o|782hHWVeCFFBk_;1J0bqPDvVu8 z86E$mBp93Mz}Q((8snm5S&W?+WH}+tY*w~k#mQ}d)*_*epW=in0ViYvbhWCj=#uI! zx?V!{N-)x{Zqy0SLrOVeQrhXNPbVd3T`LagzG=R73Lta5tPGfao;5fyleo{bFP>*y z?6|_yeife2;dDxO_PR(Lo+nf@JXh8-t*!fX=9@*)WYq8TcSJ>H18O2Uh zDG7FRh|bzscxHgGBUu(Z6Oe@^HFXi3O*O%li+|LbWj0Pr`sEK42A>&K;U1s}IArw#SvzL~LFMXnYgKUM6Hf&w!Hf*iYGGwdn zD;8TdUlF#RrHo>$vVTIHMZw4fyn9GF)L5j{ss-1iDya^;Ub_W}S%$PB z<_v)+3ra6*84~l?OBOLlUJ_y+rHmrx^U9i-F@R&c(Ew=16+32G#I!>eS{TO`62kut zXEXe-5IXoNbf^UAU;=d9hCzpPNX-@vK zG@d2nXK`3OYm)X95_mt-hQOjE<5{<884|c|fkoho1wvpq$|wS#lalZ(r}47}uz*0P z@$*nWA@DM`kU(IACM0l`5XesOEJ>nYi}^6tZJ0P4%%DP&HupfNEf<5{Lfqj@xp>u# z2{>|cR$mzyhqBh>tj-dnO-FjHtKE^xN2LJ=q$B;HU4mSGj9|A#FS`E;(az<<1yMV+yNZ>qNDsmz?`ax%A8b9^MpJ)-DE8=&& zhJz=EpT-I|24AU;4;zW)RZ5=KOKNfFU|dNs$WwE9|Dl|(({J&43BM%VNt>Mc8@hzL zn>H!EgRU5>W$lqv7nHkk^$|>|mvBIS^<}u-h3*49;-~tm<0bfn@f+9Q#&5Er_{^6d@CE16PzfA!B4RqbhqP>UkApoK z5%w#=tF>S*wC6~UUlZ@|o%JVbiuwg!w$q8>)vSXeR-uHo4l0wCpT1#?HDUQc$Nw&e z5zZA}mRRn*xiDNvszI)+WI(jD)I#N{Xd90WD8YLQbQ-tvt8Nx;8cuqa_lbN;@{#n( zSx=n6I$M<-EVadT+=j;q(!EEUo9?j#Y2zNP(6LbyH;&)aGIWnRvn{u-F_2atosM`-drMW8y-#$fy$^ta$Sk=mRz`tV z`hFF)NT%XU3W$r2vzgX{S!#!W9a?!HD|~pr46W0jjdiriNE;@<{lhRhR?Cpd!W@gq zO*z7(mokdU#ZnRji_q>N(hVJTU`WaOuA!kE(~()-9l3r*NU0%O0|CSze?jGwNw?)uKWXkChX*_CHf+bbeadWSAZA-gQDDgNtdGqB9d&yZ1v3d(ud$Td&(!EW47_)D0+na*lR~bQ(2@Lv5GK?|Av|GWlJswtgP4MJHJq{M{c?)6-Um$g7G2D7>asbh4x) zLq(IUCq9!&mPn!8)c>KJOtShXmMaKEH|$r*mb-grKpBh%&PUo9I28_{Cqi#)85+2T z-!ibvF9!BgMj7}gKvWYU2Ls>GNeo=XEX%;XkQM6#U10*<_3!+HT|Wmu`11KF&aV=1 zekQ=kI0R-IRcf}3dY~hXO2J5e12L)#XjOd+0%iHu!6`E>`#ktMiwFkT<>WUlZUsEHawgzXoQCswG4UqW17Xo zuhWEw36xPhd~#6pka}kMu-Ff}fCtI4c(@2z(ca<|79VK9usBb6;HP+oO29LifM*Ox zG$#+zfW^bE_T+(rk=O7nKA>4UU7;cRrAQm}$$~-9FVHeXUzTN|Kb$4#CsIbC|Exr# zAK`%B3k?|Ym}Q}FgRB^ObqY*wVVhfxuonnyehO@r0Bj}z`&L9~iE^yjg8fN5!lqzk zDK^p3h}6y%x9`-V>pR-HNyB2K4Gq-=jLsWfTn`{i11j%z=hJ z&wIR+$#2LaSHS})%2=$Xw>yh^A0ukdS0%7k4_<4vV-D|W%lZ+)u z8!~DOBq3wImLVB`K51G0(33*OBa~5Od>Ynd6grS`CDa5Nl4X(68d>m7rP#z#Cg~kv zl6;-578sX`B)vr6^569XI!Yc;1>`ef3o$vfDK6mjeqwSak0_a~#Pc{tgH%z;BK3vV zRLMPCdjLtAhO{9m@-v|dNfWdTN!s&-MbgeEgrsXJqexmVC2?gj=B)BDvKg8MNs?ue zR1I0mWBw73SpmSle15vpIz|(%%*LP>L7d>EDhu4ki|8?AEHW3{?VwY+N7QMsyuu%f z_i}k<6EDEC&R>8Ekh;>Gb|=HWe5{q$|xolOGz*>&w+^s(2;$I zSr!xjTo`5IC>-uTcldfCpiAFjRTdK~QI+1|3*fdh=$)(GoH*woZE*hiqrsV}Wr(wQ zs)h6Ose*G9WfabQDG8j_9d6xe4-J4*vMikSkp^crUHs5%r5<38Dh z-MHk;%6M#t-kM9!{DV)hi0;aDMLZ`9(vZc%(pF?)E&U-2yX8RjqV{95FbiqJ!jS`p zg~zoFS@`mCi-p~f3kx?=MzOF)N`eKaTkS4{24KPIR=Z?mfd#?`3%&VA9gq6;SHjcB@+wHU%TIqqaa%Th1ql;5Ja-@UF5p-k4k zO?Jj1ZP@wb2gA-NEkkxTPO;c|cZ#sngEESp7o;Skf`gCLf})HH%(8ss$ORIozMO!X z%o%LWRgNs3s0U1pw_{|1@WxM^OPL@sQh&KeVkEzSzeWkc9t~5vlV>b z0nm=rJ%a39i?m^9_4kIIzFLOtygb=rXYOQSrzvF=JC8|8u;X;|+oAJ?9j61-pCAjj z6wH$lHaAcHtQLLMY@5C4;kN)(wr>ArOZP7XZPMU$^V{3U)jUC#2XY8w&rwF%;V2Z5OFpM_xTDWgk&F*! zx4d*9vY?~(%UC3X!=UO=xan=|%7x;R{FHOJDuHvjOh9M?h6{;cY`}8GUs})x6pU=e z^)PlqRb!m#w!t&A0WYN8jC5>3+R)KdK*>JHPRo##-zHk5MDPGZ+*JP% zWfUnNf1^n$bs(iL^aCl9Ws!0LvebLy2BU`m+%6u2;e;$mRTc~Tn~{Ygz>TcN9tIXc zM4 zd}xB0{t?P3(|@{OOpnI`{x7->p>B)-YQ^jV=vLD0e=91mP*N8?m@0$dkJ>qj=nJF` zq8_4`IP*>|LuWqEM$|+hT1***C`lp0*-$8J?**r$Sva#~S?`SjUunzI6Fx@TctS^XP}IR~-%VPEp3peW z^6ffl;@k5nqdcJu49U>vYFOSA?rSQZAX%0t3_+F(YyIF$|M}qPXApO3QmM)^sT)

wIlw@`j{f1R$-5dChX4f=}(gP`B6Wr+Ulhb{E=9v1X3QAVNvYoA8n z-U0pnIH-z#AXygrYmo)par9w)e4X!=`mYB@&qDYo1yY|yK@#fIJKtZag$=1X<|q+w z+k#daL;Hc=y)he@-b+p4*J+EBqqmVZ9Hj_S;pinTLynG*w>T;tFC0yxjN)kT z=b9s@S1ingfgrnrFMVK$>lO{S=B9`DyJtl4zB{TkQ z(ZBF=$+DnjBTGSh7vw}A>IY~iTxo#Dhx&cV z@e|ObxCQMh6gLMT%>9Kgy=O4Ag*@fK2ujHd=UJMhx-AQ1ZS_`lVN6R ziiPlE3^0CA4j&CEM_JE7hsl7sSQMnlg-NNH4)+rw((3Z$YuAVPiua#u-ymOWkT!fZ z+HLrHL(7n_%J*4({dKSK<)e(^s~A?1d684RxUPPM@uDlTRHteyu;%!t%yFfmQ{fYx zY7UgnB8Cd$#qoM{0HMmf&FV*OU84H}X@jnZ=&0uZT88M(yVpY3M4?+u8HFw>iq0uy zq(cV`SWY41Mr0{;8DJJKA@EI^=SpiQpRMqOVW4{hv81Aq(U>*kJY&FpMjR%0Jf<-p z8;kv}twc=M++$(#-Xj*lOJSNUVQ_(O$^uuKM?NnLcoqQD zCy1~WS?o#_U&lDI9_RV>5tIn}Shy{GGvICy#d+*vP61w8;P>PLOMQ)t_N;-lvFF&2 z4EE#NhQvN>jD>v=UaP?OUrj$I_S^dDRChHR|LoaDJ+9K=x(L&a8$|$mG zNlB1(5kXitPff)kQ}lYtvdFpXg-xBN!U~xnF zl4M|N8kc`F^JBww0QqPuQ~MdIo`|%e`m0?=w=r6VRByY}(rp9YMTri1MNGGaQW8|B zIZ$1XYBf|@7S+dVOZ->PGFQ!`Far8Lt9(;dVMn9jFI*u>>OG_ao>eeGXZ9|bK$@~l z@FwcR3D(GTNJI0Qw&semt{SECm`lf8; z?lC`G2Rs`=QVKdZNs^KlNtvuPdeS~R(^w8Q?1_lXZ0swT=XS(h!KB~{rVOs&za4mR zd9dzFf|$_&6Cfz@@v&3UGsC`vQPHcSqCZfy;5;R|$Vv2~sOTYzUOrTbPKp=Bnw)!; zwla;9hjeh2o?4%Vn5IL=JS{_`9J|djO37_vlr+jHqwEf`B#h!}Qa*HCQA>;>S(Z^+ zAqy?kxe0fbuF04V_eow;5X6`ud<;abUcdVaf#vSWKXET>e0z(E!1`s4S8=Wf3raJV z1-G2W2z5ZeK+pZI_A(Oi2GWLrngT;+OwVf>5^!{sMZhlz+OXoolu-l}!OB9w5C;M- zNAu{=l4TLl5?N^Bj2jaO;2j8bhykb-1azkX0`80X2XC;!+bZ!2->%`Mn-u|J^?r-N z2;U??nz0DjT$2QZBj149kf#{cyCNwn^1e=5VRe%6BGQJ8f3_QMn4x7z#!t5@d2=!G z^{qn2XfY2SEBtwQtCWN{%yS^43seCal4X(67+GjxDCp+++F$G zVEnezyZO7y-b(Tu_(2){V(;SWRlpg_!SZjm?~HMPyhw`{FK^Z$F9#z#5V?Gw;!0>~ z+K6~lboUe|KfPBj(cF`DKOj@%kTy(xvdu6xO3RR`jUz3l-W@4S^$Q!hwKFco%S zsuq+3Q<7ydb)-73ql&qm17NR4Y1p)n3lW_+kqCKd1z*ThDlb6c%PLx9(4o9kXc3W% z3i+~%e6>#ajP`g!%|hBh4R1A2)3pqt?!Lu>T6l{m$fG79QeDG8_(9iVnW^MEQ@7SzVblCv)BxmzGxbemp2;c!4bJ*8oUdvb;yj6%oUmx{`%QxL zampy1Um*ZV&?|Dlc@>%mPRX)xc0!hob4I0puJG$vmxwMjVH$~rCQKu_&@^5~0vvy4 zLl({--NbpK#4W?GUUK62iT!`=mc$%HI+&|Rx^qQy3G~af3^CWVF;`NUXHZ6A{uyDW z!VCW!p$afNEfijcEOjZ>8Casm#DzbMsTT@oO0;)gD0HEC$bAyS1iY5!JgnW2(0)ML zKab_dJS3mh&E}fIFalhDfF&ZFv7a-ynHV%Mi)?*IP)o zTrWrlQbzHfCnbTzY2B=`LgLhYT*y*B_6Nq1=xhAoWBbI%_!_^#$e@o&am&XxSE6Zf zvF^fVm|kna3+CN#YEL1;myk9HT``2&T80QC!!3lx!v*0zlu-zGY}5h5sTXyF9taRl zy{IX&6v8WHR8y~+146uJ4!wx4nY#~>x}sk6t*bH?2=-%1a!;XN)Rv*0ltiT=ZHW4OgK>pBwG4?W7-kW*W|$Dw zn=*>1m!u?I!D($K11q_fzYWFTns%b=mZT7!pqy4C{u$F%}-DrFSN z{cCkkcXHsXp-Ke~d@-^T9JsDvm1*pxj^WSVRStX%lT_fHfM`&W1OIXYjdaA&v;uZ5 z@OImhJaYgxYvX=M$E{!Tw#Y)sZOyG*Sz%wU-IRR1hP2_Ms-Tkj!?Rk3d>p>U;^U`l zgpUU)qxkq>jpifIVU)Uzsy19NS=K1k0$I>Mmsh;qz_R1y=s|RH(jXOB(fx1@1~@ zZQA!eE>=TLSu+Z<)B)s_zXYUYSs-sm)}~^Dyl7Ab_FE1g zCrBx7fozWA>(4j`AbA11iPyE^BfksC>Tw`Xz)A+>t*cFJI;gEjklw2;ke6L8APXs@ zK%OTh5u46ti`FvtyyF5=vMi8OkhLjHko^V{q?pAvcvh>XMRxLwgY#6LsGD}4((FL$>)}1oS81tkgjNx@K#%X0@49T*LQTnH_ z*|0CP5L^J!3Rg6aX6b|wPqRoxmRa6V6&3e^NC)@;mD#}8-wjf!! z2Wi8?2P+K=H)t8MuzHZi!cz1Ru+Uj7B+Edvr6gF$abUp>4G~-<%VOb|KZJ!&(A2Q7 z7>l!x5wr~gJ6Vv5EEX23ivH?N7K-JFp=ROpxSz;Ect#+};c^XArt}s5VN3mk^Yr>+ z$g^KN+!fm4NLW{-gYC83%zwua)>6yd0h!E!7GaN}zk#qSlu>STo0LrN97tapeUEWq zSRT%9^f6~Q*hp|6_>9}|S^qnz?DSuS8l)y%)@7j(w0c}SGf_N*v_bLN3WMTyEkm;h z2UsXp4-gc+D5Fr!my$610JLaFqT1B8p~|w%e)JeLk{y^@*b{W6cj6^pdYgo6JE_vT zw%dSmSSg9zfZL@)o_*Rpi?x3e*b7J-U?-LvV16w_U_bV^fbH)u!0w`q0=7j;0@xS_ zV4a}_fJv4GtPz1_58J2a;Bs%kJ%=h`7xVz$d@ZjR$0uIrd;qRGDKL}M);Rk5c(*i5Edg~%5-451H$XjJP=Bjg|Mq= zwhxa*OM|__>RLPu7$R)h>ogG#N8VIhz9+Ot5k@J}2F7)wj12h2T81!scr8P9QZP1B zM!{$pg^}j~W9DxHL$WLwi3v+8-L4b^ZlR1qevXucixxT{ zpM6A-OO}QF5oBo>#TBTy=#CO1cUW-WfUr*FQjdka9qQqN`-f^3I#p{=+t!Om_{dU& zuu2@lQT;50*Y^{I#k9FX*i%XZVTl966}aq$i%OP-a4xa}9=K>Fy67?GqQ?M3ge?~x zBf`fbRTYdIw9663V5E(qRxB|vdTJRO>IIJlBgZ2!8pdEukdlB=odMmNu0;+D49T)! ze1t6RqESPQ`IUw$lQmZ?FJt8u%ga2XSqH-j4JGwhhMIQ?(7AnvnP%T zq~`?&FAWUakJXtz{!;&ra8A30^({^ufnkZDdIm6S)M(yPgvH%l4@hMmB3h#}H# z%T)7HPKJJSII|dE{Q0dp>+!4ODE@35Av!e(2g&76Hjmn67Nn&nxAJ5pw;G(2+-g{E za;sZbB)7V&Ai353Maiwwi<4VTfd;EnA&Q4n;uAL(}dg+a?-s~(~ zd7!Z@#3LSop)`&_vS=Vn>G2UbyAsSRC2vs=(()Z_kCowlcxQSTb(6@5_8F}ZH`k|Lu6~O{+pCh-KMIPgunGie()-M#7!V3 z{VM(@S$8svddO@!JQ7)IXBNGtRP~xt_>{UE!z>Y?EH9uAy8mPH$bhT_cP%B zQu8aIY+nS|!G4TZolt*6+CUwaXP|zsWeBy)T5Z!uEy`gRpUEqj+#wI-2?mZ*xGah=pET-YlwBCevM z$-|i4Cs^xM-1f3wnK*jC7=F=RIyv(j6hpU8N^c(34(plkv%%PU=9&_$`K?yf3WTWu8q~J$LIuub7E=BZfWgfKKd>Qw38V=;ad#mt^zV1oR{1VmRk~As(LJ1t&x%~1V)Z`WkR4n}k z&AbJ9K+DxslZrXKsET%^KNlM+GPTSw$n4`~K|B@JpaiHGMHxj!zLZSo&I#h0#wvQW zryemzT0oDI^U8~fx-nM%iD<7=hvnn0QTq(*GxRzsM$6lzEt&Bh(w2~UkFDkSqzqYp-2a5 zm`%m_2=8V=-4@FB7>man!!}xYm=Qij;YD%6fs7(##>oyhvJKCJ>_m}ukJm)geeOcq z7^d)5(_MyX85-uzo|gOU`%?_lfilW4v!o<~aaXis8>Z6FVi?J?4D-`ZFidv-M7npj zjN2GdaXty((qGmb=tss}QovVnPevY|mWWSR+9lCM+kpHIuBu{CV6>LDtZ4lx+KQCH zj(EQ<%J=*RLt1hs)+bz&oLZ~r*Z3tZHL{sMeJikH*^dG<_ne9_LqxEhM)((uUmoKt6uwZH#4_P?9^ShehsVvOrq@Q_3iEJ4i{8 zJI;aJML!C;l4X(WM;2x#LT6wuCq;qP!nF1+x)=CE%HkjB^p? zNxigVQ9l>$MC#I2YvUuw-1#N}FCzyI%f~DHiSbTljShKUhVUgqmR;{2TDmWJHmn4;P=9; zWLeCog??I;BpFgu;6lP4l=gBrr4FXEOswJTanee z*JI0dwBHkrQdT&4YMIQ<6{Dzi!=I=X&sphe@sRynTyKEIT;bR7OZ4WG_PF^ZDgDgg z8c-7F@+-ar8}-z$u!o+Ty@+3BUV+KTzB|30>Ydk;nr8lh&&U_}K>HK49cZ_Ekv4Yw zaDlPgjar6wTXu=1@7G7fZe1v&?Dnjbgxz*J*sUrxZK$#=yOk6txx!D!N z4zsAzZ^24xf`m1N`UnzeFQnOqa4hFm=hF$NmG!?1`9sd2$2eCbEv?HNC4RuPI!A zHe|fG&#=G$I2JP!??JqlMUlrw#=vF3(}UWMBqA6TJ0qmF&c>0=AkMn&@%Tiq%yfSFH%q?T?a5_a~h!Oi92b?uv#sNhoT7U!pf0 zAQWwM2u0@+S-DV@j9;UnsLX_-G<2ns-*3 zH(vjBNy+r~*hyOp+ZI5@!v4m#tUp+mXxoRr z1Z#N1Nrm$5TP7H{FXW+1_c-0##p^zMuF?G*Ekolz+}_gt)n7#SzllldK0-<&W(-4% zcFcJH3o))_S;k#~EEu;?8MnZd-Z|tss3Pw{1OO>w8FvbbguCWMjT`x11>t>&G!1aM zlAKjXP3(qg#%ZDcNE-_+onugT(=tSv-OfU}F(N4I$51{bC4q931Ii!w2};SbQ0_uj zIO}N!wXLw~K5sT(D$Tz`Qspm)pzQQw#`U2WVm4PfP+6a(OT&x~u8$dA7@0>nI{+`z zh!q&`LL-sS;GF?av0MhG*V2w3`Br?EOFyQ)mUy1Ix7B7ZpVj0kf)YjE?w+-e)ChSF za2{5Yj0FC|UE~-ZB^1Mc+y)}amU2f32czBa)*^i%q8%ubO+vf}C|V*E-kHrnjqkpK z244M;g-~zaUW3lrJB5Es&NB6)iOQ&u@_s&f)l*cG8tyj>$FWkhOjotUzVaDVt2(#W zx6ON#nJlHC_hP*ti}~39&~~LC^g%kfLif}~2oSobcF;2PgRC}|AFTRW{NQxTC~v=4 zO2Q9{9Q@$xz2XOwW%kuw9 zi~ZtMeDNZS#hpKjip^pwPL+~iak_(wzkMnyN|vSK=g1Nj7pzb!z77`6UK8gF=uYl; zG)Gi;G19?Tv~O0ADLhxp41rAKLQCNWO5yR8QJj8+b}%dEtR3BF^Lo}8EQIoLbAn5$ zcWQ#fFO*$4GKw40n0hw9;07VEG6AgKN(T7_zal!TkKcR=<29zi8p7OEA<+B6D4!he7ld3X=a zmLu3CfGU_64P*|4+YNjA6V9c6^DN8Z7ArPv4GGtxcJAsdF+-%TZA*}Cs(Gz{x9_`3 z-mINzHKr$deOoH|4&knN{FcPuYL52v$0XmOB>Az52+D6&e21#|k8F-q_V2{ahDW_i zy#BxZM||H^L9wbzf?t#HwVJMl-zza&wImK05S2`@S+j%v#yw9{P7}>U+L-9@Ok<+S zT855Sbb)1}Q{Rb+Mo>nXXtk7ti6%OjsO4@kkz`pWIvrVYnqmk`HQHVSTR84ydl}YY z6{*m&%ElsErK|+lU~7dRqXNu6WQ3T+go#wStibcHS}Js8<8h>e&*(7mUBIyMfRX-kV)}ig zWoWHtwtm+r{obOC(yyA*ukrejgS8$-v$(jIEX!KAQX@{8c#ln)nn{)cpU7Hap%Y{y zd8%)OqlUl?GV@tAgRC0|t6Ds)duJHh|I|ydw0}Yw1*^T3gcBAyzApf~3$qlwI}qP%Wpe!I*B@BZLEdqO~Kb{Y$&J#a=y3$BhQ-{>1!@E6bL#D@EEZT<| zb2$Aa4PWc_#6hl1L%n&JT3>;N{OQyE!*a0W$u)BS;0zQ*mM1sl`IMT)4p*Jt-143t zUt<+xy7Y9t%YH3>@q6~mtreN?p)^uS=}ko_Sob1~;IR$%;UB=cXHyrv|E-0pn*FmE z(m_=#&Ko~v9J#HQp(8)p%u?l@{o=?qDWe?uZYjxm5d%j{woPIreuck$UmRJoL@ng# ztWC&53u`r4YP1w-qfv59qXk-q8kL@FX>^X#Xd-2lMxRY17HH&!GWI2?S7{_!R@Z7n zjrbItwED2kbj~PXT`?EZe3(|;>_RHA!pOm0SR#UPPesO56S}|B^by?0NE>h+MMar4 zZPGFXSJwvD_bZ`$K4lcRvMdd5j03p)pa8<5WLe;bAPcB+Icm|xhoBz6r&#W0>mr}+ zak+?$=Mir?4oD@|fOVPy_!MqPR3`qFDrOJ<)Eh{j9)N$d4ODaU3H&TiJRW1=a%*5}I@CjaQN@ya9Pxsq7%BheMA=ynzwMgPG&!SY~heWn7=2!-ad{ z7j$*GO0E~oN$dpI?9{7w;hxY}Y2L}CS|Nr0C#K`p0veodH@N1DxCXJ~>I#2|U-U`X zlveHfr6Ks$kF|f=C;OI9EaCPUJ=AlqGjl! zw38T&9_&Z@h}M@eTKr(hcYvv$YH@@lzAa67@e9OFTdsWr_En(7__t!4kbN!GC1f#j2}4)FKrx2eYvtR6p+YcJh=uC#Gmj-) zt17VqJ<2HF#!E@?7Ixt6z*gZ+vMkp{thpoC`;iW+T0`N> z5WDn}!UtN0T&LQqT#beiPxC0FxOPiPa4l`OF^wLUlF+DDoAMF=D+> z&8no3HLH3Kg~ZyCOVp}OmZpppPeR&IydPmmQ+$t>A;tM;S%41i7C;`#D2iW|k^tm1 ztE#U6InAp6DiC)riq5M3LN|{dxy7ssM{Y5z;*r}v5+a;uRjW~n0yrFYRknMcoM#Wl z|;;-hHOU>T^ZH>S402SREuKD+m&supbLI zaS9TPkOj33t8?IPjzOY?QLlm^aVsh@LE@mfD9dF8@K3=YBXL4b(&JDVn!``Hs?(bt zArG(KFoT%KKiKZe<=>DekAHyvp86L0c^@N!q{l~)W%xzUN23uW%m_juJA$kX#v;h; znphg*MWlnO)=>DLNyZQ}vX1f6fh{k-TiTj1@h!BJ2KS+Y&}XPXBMNkW28z-Zyn&Xov7_#oH;5~2UFLAhPbt) znouXAUOeqSso5m^zaeedAC_*||6a@RAy8dx#qNS);4DZPnF+NmMiv(eBPYp}vfoWoQuY!`>Cvpw z-b)Cr0WqmiEGA*?B`k&n+Iv}Bfcniw+UWQDLq@+RwG1t`_jF4?x6*H9Our3M5*Dl8 zw*0)cEfvEXFqvib?z*B8wwZf=r1o&11W+{jx2A+D9!A=zcx_C@Z?z0n>}0EWdq^nU zKp910gQ$wV9aIdwCn`#orQ$ebfz+~KgI!9+WToPWI28xQtGFCNNXN(?aVqB2vRK@- zLsV=KQ!!mig2jmrDu!2!ijrli_#v`H#k>Ng;-CkF#nqY>viK&_hQ(Sj6<^RYWbxP2 zEESt571JrBSlly?;Gp6P2NgX^Mai;MyiloF>J3CUUeR0Rc*YRe#dM=_T-LAn2<`#R zApz|}I@nwHtnQ+gtf>`h8TPCuHlTsqh4V#}QGhBbK+V7(I`-!EtkJ%a>Hbx^XT>C} zBe(-0fg197-YxO4>0$811Eu9onuhO(jr2*=lfsVs{+bs53$|f|Q5f|p%a!;Avk!Uj z_yByWI{@|3)&eZUrL;>JS603Y)z77B>QtT)i3R+pAp)+ZYp%%cWTXwZ-@=)+KabTi zbd~~+$oQQ%n96-(hqns1UdkwL7fVSvOK&J;uU9spW(`%Am^?Z@gC zw0a7f*hfLz1?x#a$Z&wx6AA#DWLeOfSmFu`!bW!U7bQb0iSCpEKF_cx@Cy2GSV z@$&Dr4At#ot9#cLu|$wEO5Mg$b=NwmJL?@$SF$X1A4Zn)>+0%H@2>h~M=~>-Rhh?& z)kDT{RgQ;@!#sS*_!4w#nn&uiW?tu@PGz3g72XNeEV>tOw%vXMeu1y0$)iBJ>Yhf| zn7@<_apD$ra4bKg87R>WEi5aF+M#0<kDvS40} ztT=pp;(KrUJRJ81RH+;nX3Hs(o&XDK++2F%-XRVnt+-QN(}b}!g>u(CsCt$(XZ5V@ zZT=qy2r+>D}YB7m&_7 zkv4RO#u%>|s%1!LUS*5U&+~=O_LNa{W=lzUP5Tbzy~YI)pi{CeI)7ZM=+rF5^yPw9 zN|29|Cbbt_!Pkj6JfEe$9yFwGi#tE+#tJ~BGlq=OKF`TYadsQs-E%Vesnv3m7Ht%7 zE=Dpvllfj2^Rb4Qu>wExT{l_3i(TEVwTqF%RHO}uzPk;FDO!dc-kD@^`0PgE@F2NW z9QK!z;P62Q4mU0l4kgRta3Qjk=|kb&d(BdO;`7rFV!&lEkqRuLMxg>+V?=7jJWDu` z<5e=Fi{Pd-fVf0E0zqGdv;jS9v;o~%%MkQ~l`PONZxGObk_-iUsFVcg=?d3Q}x3oqc{v7lZ9m*2gmX>IiY_ zE2DS#dWb`lAzCYHenq_IZy<2#dE>=ehGw3A>Y~JX){(Ep_#8(J+gc-X$dO7?Wdcl7g|NZflUa2X(90kwse7 zpvk22Xje~4&T6gZntilkNJnR+jUngVVdywd%aD#qCoMYiu(pm#Kqbm3LynY^pktx~ z9lPHUIwZ@Y<2_`>081y$p1VT)QTpj{I(_`h$R~9&?;x*+77*_vdVK}e`6FB9;`drmt_=QWK^7N!oRsl^U0mPl6{egs4LD~>@_w9zTW11uq z=CvDp1XY8uBFZSj+DJ(dR^UKbE^f=m_##;rVOhv3M;KMb;|A2*aAelo6xAoZzI;+E z_2MPOi#@j~-lTeqxARfG>N<5`B`fp^|B0p1=(WT(H0HddTH zw1{1gf{|ssA-i1HtF1g~hbDvsu1DGscs3ke6Zn>vA%Q3VvIuOmS_qs*8Aad^x3VM% z9OppbaOee3k}QkB?xONqV#7o$TRNRm+ss{7D++%Cg;*8gg|0YP2XQXGwbPf+PuHZo z)VtC^QaZFDNz$U_Tsv{{UUkYDG7XmSWEz{R8jIeZ4|^$lswJ4Na-&>@C4e9?FV6af zN_B}R-^-%E`?9|ktu#X?q>UM#8)?kYT+7f5j~utm@cO%AhEp_;GQ-VM5@y)vV1|!h z6*EYdWrkJAvXzgc;@^S!3UFb!d;OF9;$FS8bp(Am?(OYqcsnz{%G;TlfSH!**eM!W zzT6BNsn@$lzL%M%3IbZm=vdWVeocPrr@zUBJ<=>j7X)vgYu?E7`$!v}+umY$-k@d3 zb8?x*bFY=c^YfHZJRiGRyZiMQmyZ{BFBG07%i?(uvJisj9!5=pEH%X7Wo@w#ceU!F zE#g#e5U=uM(y**-RF6~n=07c!1Mi5+2M9%}+$XB?LoLY7K)Y|({t)3R!D<|X8gUoVoDppRy{&eh^x@%}t)0_W+ z&cR~+e7jLM8gKqpW8vaSpWiK9;??hXfK}3eiWqY~ospl(nX@uc9nAGh}6yH<2c1_JR*^u>cbhzDfY9Kdz}I)Q6BZ zruYoD)8pvvT82>HJ8D7w@oj2sDk#XrEx*K_H_u_PERd$V_2ctrDdzLPD0DP%xyw?^m;(p#AmJt>_H!k zlu0Lb57gEsWtSmsD0}sKLs>g5L&|)=S(L3@DwLf@8AaI`DGACl94Py0zIcaZS(FtZ zD~=rWKX`~t+b~hXh_-pXAt!w78ZzT>*;|6BN>ORRV&+yfQ0}rf_R9L++8ap4#YhK> zbVq)ExS^tjmLU}rk62W^u|%kFQASa5iVSB5h#j4l}UZXc@wOqSS)D;w^z) zgE9*CXekNUsa?u-V|+uxf9ic*CMU=j%{w$FhC+RN6qpnkNA(eD5vhYon-wG3^y{g9>K zu{_ala7@3qq+|sydo~rr%hTx1mhFql=!2Z%&JXb*yu zGu0xVd!{Cw1Y{s>2>9VzL%=vKLjtz_Y7ubs4Iy98oBUb8!Xu2r8!)%>wuAlE-ZChk!$gD71piiTh30s22LHjGcJ{r z7Lahg_5zYN5b0os_UdJbs@iM1YZ-d=(+4fmg0Bl{XHiCxmL?@*UdGud_lzyKMA+id*`bsM1?A5KQ(f_4a zm(GD#H;M(~za-wq4gS#`4T)~z)q7M(eoqrl0^UN}5OBJ{kgJUswG0V3^ovEn*^9+M z6DXqy_~dF$zzPSi?gvdlfMi)-eG#%M^lDuChr$h^Qw0*C-dzExf?3EBr+~Xro07;^ zARQc~U9+y}FUWJX3|;eB#6sSDkszN;8HN0ds|0zoXgFn!wrhHxjdx9vuw1h_B+y=y zIQ>%M^?O)a5&c|RhL#y>>*sq-^xIF1DgC-B{ha3rOJ`T;n$IBX|JF5!p==~M7H|(K zzw4#_i0pSn+OR)&un7#!v<%Tr2wUtgepS$&Bx;53CMk)I7k2QwkDd{9l4bebyU41* zt7N7e3TJ~!$3PlJ0B0bTYOO$eGpcnCmH#+~%GTO`WF!^oU~lb@zCnhO6fHwW?)=$e zl%msS@m@?k|3({-@cJNa;4K|3=eCy7wS$==knS^owCMJ{B6Pn@8RboX_h(7a?G)D^m?d;O z#r5luRRMZg(#8EL(5V86e~s&Ybfma)Way{MbyXpGbTh{Ukw8{k?6JpYC@Gkslp(8( zrG`)ezq{c9fW`aY@FzAuPkbN4G|dy=$M7iAvG*~2({1?^2ht6B>b@z@`Jtc5w}nKO+frnvW7E@ zo}f0Cwjzr@5pcosRr_&{EH7`H)IL0>uR2F^LOs5s21XS2eyL>?Yl$78o1$w8xo{gp z^m6WrgBgef{`{Fx*4oJirU5_1IOv6RaE0bzA(YUQ;kH`l8pzN1F2+F`S`YX6NBU$< z$|w%*mXf%SJ&R593Jz5Ua}v4OGXq?ln<%m(k(1>RL5q2sby{fw(niBm2s~QDnOcTc z3Kv@%z9PZC{us(A4Yx~4SZNztw5`;Ynl)5emX*#%mQRRuO~w8**UQ!ZGgAO6)fEv% z%q9^(7mq0r$>@k1rm~hI34;*Yhnh@6+l;h<)*=S&9W6s>r`yoB$v#8Zu+fd$wj=+~SPp7~qfFNT`PP*4~P&$SdvG+#HBPDu+_6P(`>cs5OwaK;^AX%zIt( z=Bd2m#Jm~E3uQ5HdR^L>HSlo_z%onQj5dA}X=CFb;icNf4`~_N_@n(6_N+3o@l}*j zHeMnnVdLuE%iFl=G_kQ{SvIbWEOZ~*INE*05z&3XfGcX>6Fq5P?hN_z`APdu@1g9= z?`qcw_HB-Fg!YxTEc-s6Mf*}b(zdM-@%vX6u%&;-8C5#U7W~4F!Y2%XitDr+kh&|8 zHq^b<+fa9jmLYY|+ARz~edr!_DWj+xCnYQB9zSGO*gXo7rK!VljeqSP`G_?BtZhOc zKS^Kz?utHs4@e&9JHR<<1>Iu=+Eap&!+7JU@z)`+c$~l10liCt>gkQEIefhG- z3Clg*O<9iL^)_WFd?Cg!T29)t9RKAfX*r5VI$snEZ1p6t9oc8$%)@IP45t#{Ay)_UIW=ULBMd+oLN zmOKlLWBqv*k~baIvQ2;9Rmj7QdPdu3bd2$4XgWqI(w<|iMu0KL7;Z9jjOx`6Vb}6e z`e;EhWz;bqmXdIc1~l!?lkz8sV@Q_c7(b8q93vSG#d{GA)1Bh`u5^l800>v{m)-gL zqtz*R>}}2}z_3WCkhUDBh@dSMOcZsL9`fx+4zNeCuhsJeiH37+K7f8t_`qYOvHQA>YAnPCYsh7Hwz7K>x{*t~P zM=5$vewM@HhUbs|x${H~>e`)HHBh}PA z_I8@pBhJ#)(w@^(&O>`DnD}M?RQSx5@HzW^2j|5`237wcoRzM$O2-+sohR&%Z_U8S1or(Xl?y9HIHC@LS@~KOXtC_ge=; zjpAcRL_`$?PnO8XGFad^Gc(=dXrw*2co6Z(+~Po!p<9ICbLi^MHw8oswxf)?#V{#J zw}3LPTfBdRx&^Zwx2QyxxkWN~iti?`#LOjL?#$j_2LRzJ{?a9S9-%J5W8JWXxzHK} zad8Q@<+#MjXiEhXU+pLT``O7kiK<7AAd>T)=o+vkE4mS_i1t)4@#Maai?8sz;OhYSS1$g9<~Ql$Va;#S#V;g@{%I$^H~Ow)%zLq6)Njn^ zaE8X@1-{NREl?hAW};d5N7^&%B*YyvYk|qotXH{hbwJJN5u0i~vks7wFl$4G9h?w2qptjLkGfq;No0}Zyk7?N(_1rXCmcWL<#<;Vi37)JX!05_Vil!lQwLQK*4bH$}Qjt zTY|HTd23`ztU3Ost&(g&GrlG5-%T}|?0cj=lbwoQZ6;f5GBjEDHyo2~S|=u3Kp8dJ z?otwcrUTk`!_94D#AK4?nCwbqnaPq9De)^zq|(hb3Z{va^NvZlioZ11<_>Bu9!Dh) z=DHJO3(X~MIp*39ZK+`5!9B%y&tKsHD+DmlM&kE};SBx0yM~)ZMg^&R1!<4E-4OhY zx+hGA)NQMATA25hP#+mA%nKlJvFXd+VHOz7h;>6?3?(#PYd z*kK&1Q_V_FJ8|`<$%LQ@Z=j9F)Grx4XUV<|jV@yA@6It(xw8#4N zgFV&{H5sxVaoZ|J%?R=>D5I>8kdkoN$r&8><12-A$#NVvhOEC}os);;dfF@Ew7J4M zf602U1C(_hN6YyO);~d{B2JhlTsh1T@)gNP8yxuA^tN>rI9x`)H{HrJ_zu zb_QkCWUoj`m@KPz;}~-Q^v1m%$#P7#1G1WkG3n-N2Gc~!^Mxt?(p;0(R?;E{Z3P!fi(Y`}1`N*qqPPY$P$}O`J)KG3S_7N!=+(d(_QF#IqRF z%VbF1G`EG*P#?U#4P}(Nu~M=LZ?C_sNpG)3)<5+2Wr!z{^435euHrB0J9R&$kH=BT z1AQA1DVy^4VQ5bU6Tf0LvgskN1TK&^#I+#e3j6f%a=Dqc0C%DQ|5w}{#m8N+jxZcb z08KP-=@Q2x`>u5@(iLZDk&WJLXR5mOBI8=(KhmCUb_4um{5Khi|BIcr=HVL%u+2@B zvG@BIRvSL%52+saV8X z8qar5LyJ1!S-%S!46cJnwcqghpcC)Yz{4Y4@o(^F{)G0T!S%@K)W_#8pGd}!Y|)>w z7#TIeAE_XO zI@))qOXplHHkT~N=EcY|n^Nnh5L8SyDoEW#q&@1sMP#tRynN2xXbNOA&O&D3GbU1d#O)yUXwUlD_srAAd>TE$x&(9!Dh) z^zDNYsj2QVWhCjNc;XP;W>)Xr=y$i%fUZgJ?SjmV-rH6(GI;NHB+IwHv>YEPTrSsz z*~`oC;w8p%S;588JvhQ2u0r6?6#c`cE4-W~u*U2_yRAgpv)jKwjoEFX$ zT_bjzN*T4=&+tic`3}c5cKJ~w#BP%1xO{(P!EU^^O}ac?ots{Ez~AI#>v-5FQr+-Dtl`fCn1-3dT z`r&@OkwOx0McN~AeUV4vwI)Ln-+#?%>o&9n=O0KJC2^LNg!7NiK;nMT9?maW4vD$Q zG7>Y573oC&i8v7{KSYS+FNut_Q6hO9l{^sH9)k*rl=d7Vrw%8P6i@sM%SKV#-qJ!w ziuwf(&c{DW<5Wh9N}P$5cM>J|n;I#|E#o#fpzsQ@692Q}9nhYR6xDclM&3Me`Mh}? z6J~*_w3))^s2Ta}3z{GI=P%NHxy>Qv3;X)YKdSlcJz75G&%a6Y*{w8xtUv!e&1Zkp z{2BiIUYaj!$kP5AfBxQ@f4^5gH|W!E+lTa-K=awSjWTci?I0&y*K8s_D|<2GGcvAt z)gga>6!2g2_P`lBbfcx7C1yA}^gN_Jhu#C7&!WQ9CPRnLaoc+J199k^DWeYk`Cb+k zx&nqf5T15{IJ9Ir4t+GT;LuGi^}q?d$Z!anh?E~GzQkWTbY-DBG>@Z_2ZtVrk%bN| z?Kuuzb3PrK;)$Vn6;{%rb*X31N{7=`@27Dp4*f08M9RC068ud$G>6T`4t*xtQ-}Tm z9^dplc#_}x*&jHUVR>c(nru6yJ(G<2U{sL06-ay39gJvb)K!`cscY@F z@YX7!?q13$b({A53vVBOUX$M54_W`v+mA&Pk@8}pkH4hv%>t#5$5F`xeHURUY0BF_ z9!mNso*0d9f;H`a`N#W$&&@!b_?AY+_jczxgfFah34ae~BISKWSN>+@O?(c8!&N-s zH>rwQeJaZLfm(@4TK!SRHm!3I(w=oH_VBE;r^)n%%r$cybq+=2aO_{Grdns9l*Biw z#`{sdbuJ9kT9rZLHss93S=8Ikt@p!sU6}PaL%(_)kw9JA$O$=VX+YuA+@_%oPl6ZPQ z&P2*j7A5%mck#42+S7RYD9BfbM$|1l!RNnAP^)jHyw(_}g_a`iS?EBJU>2HVGPF>> zt9gxnWMML8)XTox&0;_?+IB58>>RO>WH}ZJBCCn;nQon9VTnk2i4enI>Hj;cb$A?= zJobNtaau>(a;)?5*|ZMD6Qj}n0PN_O9g}>&GR-6sKAQn5-Mk|Vgc4JX3Q`wA+M{j* zqLEQ|oym~84`(?o+>RFD+=D2i)XkQXO*r@d(76fcZi%eF2%qWnZEH>XP8a(4OZuYu zN*|A-k_Y+@z#!0+b3b?%>7#h!aEv9Mw@vqZ+vx%@@Yzca@O$2JseKk_BISccEB<yz=Om~sCoZfaR+ET$LUhDH995DU4vJH_kJ|o}REJeBwL^?M4 zY<)E9wp~2Bb~l;RA#?Q$4qXT7$02?qjcVBvDOq*^9!|siT6;%op)zZYg+O20RaE5} zV6J^5sqvIbS^jQFq1~vNiF)3Iw5R8nh)ZVHD@}%GeQTzp=glj`tS6=PoFOG))@L)A zwGEZqL$e&SW+96oq`AreG9RhMc_!$?L9hy5=JS>M=25Ov-_@X(D&zK?%XU!H9tq2v z_za5Sv%Bn^bI3}nbN(9@Cp+h8GYP2~j>3?tENcG8){*y-F zlQ8z3Df=>Ah+m(IqTOI+eIFcDBDDg4S4788M~$6>h5H5bvE+kC9)l~er>_XFpw21V zJ{(+^UEe$$jA!eohbyfPsi8-3QrR3nV>f7Bb}h=b6y*}1BaDW}-J4UEhjp~j)X?I( zW@xOs9-rOgA-*WH_={$IP?lLap^Dbah$$3#Kh*K{P-G2XUIg(F?#CK|B>X3&W23Fl zoPnNfgnwl+^u=D!IfVbRObA~@86~`}l!PxfWbnm12Z}FBmg9@1$O7i+0)I(pyFt)T zK5}3Wd~Sx1hoXaEiX1P4Ul+rN=jqfrrFjAxx1hpye?b})iQ5lNb~W^<#coAm3OxDNy)O7_|jN4Hb7+6=Q1S^)d-aQ zB);rgG%_oB6iK3mi&121G^?Tn%Z~U;P(JWg=a(IU1AKUhpOfOtsAl0J5mZ#$YaDMw zgymVhbY=30NJ&oOaT+_NdrsN;QV1oycbXi~O3RF>$!ba2S*Sg?2IZtAk6NW2RSeEw zglL`>|9l4o`0Yf#qNFw3h!(exAI5Tblq2xg?Ay-I$3ege>2-lIW&t7^fwYI{jg}swGfakvWGSAu9#7CVmdw#y7{~Ye{9YSBh6tG6A%^V-O%(sn9_iMTIJu z7>H|KI1YP}zC@cTyf`dB)I;v9a;%gD2L(ITyb|#?`Nl`zrCr{{yBLZq%15)7h~4+r zXBzFkx7rjjgCgN78aStHcWiQIe}>-YZI73YMaswEsJu zcia+hNRXjOUmTAawGKz(!_k(Zin(MWvLy0uyfb6F>=_7G4a3Q-yvS>qXT+!Fs5|pq zRPsU8Q4HxYuqfpi__>p4V2UTk@N&6E7J3=LkSu1+_*WyV6><{qmF_%whCOypsa+zOIx}MyE(gFuEcGqq)$K7st$U82#?V96t9^1T_KklxDx- zj%35h>V+2RE2eOX1=JA>*zSryHGSLX(l2Y8wdbGyk;T0u4SXfW+@DdAY_W*l;Qu^ACeG)KK?MA|~B{kJucl6K}P zq+}PQJxa=8S)(M!WJt--M;%HE^urKqNtII4LrQ{@VHqfSF(i~omP5%s$nsc-PT_J= z8PAJF$}bZl_?uPQJzS-U!=rK@Ldy}oNrF`DkkB0!t6&os%ok@n7t8<}Fx!)u z-vByxgiVizZ08Y^Ffs-}CisX$%$8ThSC&ymiP=|5mKE{iri&M_zSv|?ly;pw`2?`j zE-imH^WhIRwHb|kv~{tyOWn>**R2|%$c)zCWN5T!A9i#brn+@Z>2`~hWH`uRwBL@` zaKJ3bXls!LePbA?=(LZ*_Q}_rbcs*+vtb*C|De6*WM71T>BX$avC(}}&lWR~tzKl9 z*YdOH6&wX^UW*HeS>&fCxRQU8-!KN~zGe`T)D`JizzjGI);5wln9Nm>nfQ=HQjbb8 zU^B|70ne9`Wyj^spUe2?o7mzl?o=xjY2CiJH^F6-u{zq2om!`-GlL+r_kUMK(aAnH zxENJH;|t8JM0f_$9>P}6CPO!Pe42ystoed)U&<)Lo1`S%U@%&AXShH16*rJ9 z#|>5^D>=h0J^U}HEX9qdELdIHBJ<(k7IX}$-=QtM%(z2byQq-u5Z?9dN76Ariv~Z#ng@tz8{)TF@zqp}!T5f!N^?AZ8$l}V za4R$dPrn*Z&klmExm8_{B$q>X7{c@qk0A$_YCApsK_RdPPx?hOk9C z!pjiE%yWJ-R75yvs)MkVBK(jtitq?234{$95I)sg5K5MV@HS+nrdS(bfwU=B|JqQ+ zpp~JDvRR>u;PfV^RYNzVSXsxHi<1@nf|Ye(<$i>FvLekptn7g16ZiAV1M6Rgl6LUqCo3Al3wlnFygR{n#u$4c=Z z9xHE~3|Z-TpTkPs%fiaDlu=f;my%#5o`IF?&^D&ylI5^66j>=&svG`>6|m8ml_U6U zqxB&DQX5#=AgpWvE0v^OC81Bo-S~9~HBoe$ zC>E)swkYu`rGc($a|6MvG|$CPf^>M?2e`bO!^4FT;3Vb)sJzisCd73}dk{|$Mde+o zAD9epp>(>}f%xr90&x~)6ylBw5pPWX0NQLr+k7Oe&JT5LPte?qS2rT{u}S5h;zNBJ zrPj(cKRBJSy!TJ2ttL1fFleA7(zHJyUHb^!#tgKZ$w$C8TGevUs=tMr>W`4LaJZ>XyTk@WtrueZcd;213R=?Q{&%o}C{3)kAuS$q?zJyB(yxUKBg!rjTAFC4uz(3`p1X5TugjAgw}H z3Mr!!AWRaclXv~&ZGdP0s2;Xi-GSYO*lr#so$E{nU-9Blv;u>LF5f zh)m06#%`mn@5nh-@!?2<5_yM^xU64-qsseTpd4tvcub- z&kJwMDWkmYCnd{p>r0l!@hK{~h>&fsm=sbYUOixW9B+{Wbha3q%q|YwT41}f8|W?m zuWG1e4XD6sI21KN-vdl{;@dMF-#A#sVnIujpneUBS&m;!LsnRYN>_oU~`hU@Dq9HfWilMmvKz^NnZ2{_Yee<~G!m9=oJ1_Nm~vF9I^ z+)uR(`MA4NLeuEuA|oRCIB}Yu&`W#V)~jNFzz8rI@<~%xl;E;Oo|X$?X*QA@ik_Go ziiG$#AAfOg@Wev=g+)&+!rvnN?SQ`>@V68GcEaDT_}dkKi}4rz=)@5IhVZupe@pOp zF#Zn4-(mPW41Y)A?mpqVRiZR_3%)lBk6`7oNwiNYuI%0g&UtWC!j%-Jt~$F~f24$vuWnZ@sP$^3J*~T^w5~B3 zcA))Stv}Ik8azQ6)jCVHZnI!@h7NQ!n#C+wvYZYym>Pwvh*WN{@xFz|3#Ncs3OVs& zKNPYjZU*Z$;Ld4?0_liG!M0|HpA7{OoqC&Nhg?OpiZY7mFe!r95YnCp zR(|K%D`+yb*JG0$r3OPO+!on~GHS0Ir6lZCf@a+b?Ivu`g9l2MW3P{pg<+XIMW?jI zFG!<1zKZSSs2k6Ijrs#<86v|~{FVD0n!tSyCLol>2|Mg0EjV^6MGGpJcvddBrbuIA zf)F=M==%;{UbbW8fB#TN2EQ9 z2W{{u{?cSf@v*l$6#x9VP#mL-Qrt#Lg5pUTD88eUP%K#v#aAOMHA)hI_KXap%T}o+tgvQWsTec!?AHW9$ebgB`?xU-E)a? zLGI=u?QypU)U$B%w8@aWoLe03UVTisyO}b|-RJ1tGQ(JrfxFY7B=6cW%i->5WPv*Z zNLsui)K>Y!E*ZGqly6B{R|tfw_{-Z(i@#Qyc&vAhAUFgunlwo>4o$U(ktT{K^nxT1 zGfd=QHqssk1%gDbm>)M8a6RL)Pq zXwE03n=**8n_fSh-ITM;a20>$W|Jmxvxx}^orR!I3ZxZ>g0~MP1r%)JX44k#&UJklP%ui&B9Yet(4J!a+24!-asg70L?D86T#itnLWj>lwEBO6*v zcTHZ9l(w*rUUp1PaG^{yf(zjdQn@q7SafhsR{Z)e5plC5ves0?rrYEh2B`j+nTAlO zAnieIfR7l|a+4v{FD5upr#>uD&!>z+jY&yB-DP0o&T%-j0aVFypzek&M26AO4mF8Y z;y=PIBEgyAaWk{7J0?Eo3ke3nnbF`(^Z~|y_JIy;$LRxa9E8dY>V8}@O|Dqjr5Ls| zL0{W)5~{$Bh~)5td6=6MoEpMTKfFo46Z4R)DbD4dBTe$7X_CZ_y!=okI31^_<8p$1 z2NxFT-h~25t_5{4;0926=0sbTT>_Yo4~CpJ5x8!=!*i#HFnQ5_wtNxSaN@_~47MnS z$IZeuN(Ig!l~Z;c+LMXb=&@c;u>CnDx!QX2=HMz!ZA!ph+C|dc9buln|3ekzK&R%X zunKM+R5gmn;_+S1Efzom#4^x7R7b-FCu8U2WUO({LgDzD&uQCm!w#kS@s*ZtmREi+ z^NvC1f$#lnoX}SjNPE6|@;c8~KQZ`j*N%-pB8GN<8gZQds zIlg)cvO*QX@t&jhgVRTXbHd~1&{1~~062~Y=K$|a3>S3NSs5I)h&7p`UJtOL=%Df7 zPJ6+sP{+j~Y*f5>qrRJd&?IDy6>pNP1)m-{Z}rV<+Z;!sU)P5g|Go=TiyL}z`>B@2 z=fr!m^o>~9$Di05T0CX0=?4NN#~?b5EQ4|k`b6Fhk~gsn=5FzxYf1m0$-jOAZ>|YW zh9J!`!sw+r&PLiZM-_sNg^m+VhUR#BoMVo29}sgKKp8bhSW3biJD=V-bo_FFm_xE0 zb9{;{^t#EBU}bn*CD-yI|ItuUi5;xKa}eSPEg*%RQ1OTr4n@Z`3=efaM)s(d2I3#V zh~6k!%j=Rz)u`VYoaPRbKT`(FpNbOvIT`&Kf84PW8-VaF4e@-e?WK}kQ^{gWE@}s{ z_&)F>#D>8*SyMhKDTVzXMjpxj4(Zrr8*)n!6OHWum<+%3-0j~E*&FW{vR|c)lD(Uh zEGxk^g8+$E2rTT?A*|>W;t54gZ=Z`aA*NOa$t2s46~atuzI6Kjun=~l{Ll3bV|`>x zLrF8#2P}UY7GmFow1@q4#1X^(g~`y-dfwn*-+Z57ucC}%-&0D$(H_j;Xcg_n(Im@p zv@yuSAWVj`u#GQVMdq?fxn@X;bj^^&$r`{0*iY90m;z~1r87S7jVhz%6iEC>-riC! z)<|ycE*I*(Bi3yP73Fm}03ac2fit3&7okRY(niYElsDiHJAJ64e4}P$@ekI3@Fxoc zBttf~{_zO^5_>~B*wDd z@ev>ErN!+y#^c@iMWD#WfI#<_)|^05hSpRt(HUk%#iR?HUfF(L_*D`gS08VrFKvhh|BRH7EaHTyRCYMKXQG#kJ?2^N(V8M$WoikD84k%MgaSpv9j!)670Rp6jhP8MZB47Q8|kb-jEk*~E|&E^2bf z8HFqWBIHQ$HoUSmoLtbd6|W*&jsYF(WmNki=Tkr+a|`dSP; z(!mpp@Cqwy5uK5)hlObT?mr$bMjlVz;+@LEIiC7S-U*ZJ0AtxeG_cn-4l5tr1w-qA zVsp#&I1?$K3i)sqf3r%@(?m|$AxR%88H*IvfZt*!xrVVD6AX*pp}j%fL4PHinuD~3 zEF`I(uJ9e24gJFn&GK#y<6SI~YCJizY#0WdZFNw8XqlsaK_m4K7WE$z_4%7s+Bsas zL=K)Z%N^uX^wD-uw6&g1sT9FkwDn`D)7G_b-z>0JAm0z9w?eC425;IT&&FyNIp?^0=+Vk&A&^Il#{%Y`fbAO<#UP~wg|9+n` z>ffEDWEnoyXZ$ABD5e@Iz*F}E4ec9AiLy}6tU3l#X!p~r9a`?b)1_qw&P2+e6k7P} z(ZT~CEiILnA%0qN(NdC@Ee4acY((0lWgvo!(NbqJq~#b_y`Sz7S{719Y1uB^>PIR{c`cj*|1mK)Hn-&^j&nMnBzp@qL5Ej;kivXjy>$xq9sHYr-Z zHkhR4W28M=jzIu2THY`j(z3s+-e(m;%Ttt5T5_ahIxVKgR6i}3K#g>7Nmn*SOJ7K# z-50KMXc>-n{j^+Ad!}f4$6%6{B}jX;?2ou=w9Gac z(z27Q-m=?;mOCh;wA6pdlIgUV8cY4O41^l#w4^JWqUBIXp`&Sh{~Yl>(V06avHy3p zLsSoF;t?em{iotgqGB#M$_7o$o4hP z;H!Mn7Jp%s)j)wy^htXiELcRxPr_M@0IkmO1=i!yP~vH1p|$SDF>P`f(wEHVv3XtkN!>T9>T zoUFnbd`eF^;jhOD4|2*0_0>*q&-f?z3*|-(qzcVh$|dU z_JS_pO6LhWR;}xx0^(bX8NF+zKJTmsaR4%C(m}dQ6F=u_RvlJkH=- zf5H-f#Y>r>mrn9ivNx4!t!GnaYay)%#<*>DOm9oPw3oD1Ep71^7HI$qdujdS zqrWo#*2M2XXVxGx%dg3l-C&%BC=0S9MmCKz4r$Lgb*nt%Ty8Q$A@jy%4k_a&iE;W- zMve2dlq~DiNTEOB$*NGyZ>MHZsQ$1<@^5?c0w86w4+_MMd%C)8zBSE2LRw2`hfm%K zY5WCgKMQF*$l=4xGFyliH=|-T@w2@q*Z4U*A5A8BkpK<`nX$-OKcqd*X4ZO~bu*cB zAv5JthqIHRCmgzfGRoN)DOvU}SD!cG=t|i)e#%z024&cC;8%Z|Cobxz7<(Mz5Kc|C z6Eoz-X5hC=9NlK!lE$Gp`Es1W$LEAY{)&?`K_|~T(-#Z7Q?1r|Hs$2)rS(9C+g9K7 zw!~g%OIs_YE&jq@?})v4kdx~0#mzVq_nRoTD@-(9O*Gpmr-`0M+A~p$cRdr`XEInA z3jBDnL&LM>VxlpWQ4_uU4ojBtT9XraxC~TqtkMH2)ED_A97F5@3AA^!+g>-c=Z%0u z#VI(0&$|f~{Pn2dK{^$=(BnYA8D7~XMa475I;oh3v`59(w>>JNCPON|9pzB*$V8!H zBxRI}rBX7D3aW4$@xlX8=*UTR;Z_t+#B&NbkJOKXz037K0 zrmnuo9T{0vi%uz)(%kCBrBA3Elin|jVxe$D-Zd>yI156_8>v|3#Zh7z$YvWzM~icN zP6R`?O$_f_9^vqG&CM=Px8n>xd4|&AD*mD{o^!{L#RGL=s~RND@{_bN58(IlwVxD9 zG4vLNwusl5lC8oG*`A7RT@~M-;HsFwnMiq^sK{Ta_!8>FN5LEwTcP#1U&a1xeS)v` zq)OI3T>bis91;&t*HGfX2{^+g4z5?m3J3c-*-YfYKCH}hqT~D` zk#v#b934!~^~+r3laZltN$gs`Oz)HoTmd-m^5^f9o=>u#^XF%$=eI`w>;C*N#(Pkr z#f8ZK%%8tFm7h01AE4>Uxb0YPFYuT`Pr_22t`&d8zVaO+Ht#<&BV5HlS$XA${>gR% z*~1;;D{pdL;~kvAH_lKjT*Y6w23L#qAg8RC=^(_fz=13%dW%K4f3NFB4aAXJFDl#- z{=mzN|E74#ojz`b;!`zJ^}Nu*u=z$8LrcLB7YzKB^(`ivUf=3~^`|s_N1?$c*SADA zrQ9))l{Gx~7Sq+sc#CPWyg?*-uWrRp+8DZ_CAi;1vs#~nEb1Wy$5$Z>x0Tmq zmEnobjdJq^Pi!n!*&@nfL@?Q>AdBZY5lmyfe)N`R`D^$sHpnlVWBekks;hB8n z8@v%M&vld@86LMetMo8^rsKf3=unHbm63iXrlBfGC9n^ZRmL&)ZObdSMfaUt2>lT% z7O08sJz^K)3|{KP=P2?fu4OP7hxcaTs#~=~)VhHUrh5B9XfQDsf}p6Kc>^ik1!<4c zvZWrSIVN)|WNtjqp|lF?-teBa)Ke+#AtikZOr-*;F8ORO6gW~8@avdzrCTVnv+CH= zZL=TR^fvml{^U*-5PpStwuRr($n5!#OY%VgL~o!pJAcvyt{dRxS2Go@g=zxqOHNGN2$2po|(TEF}T5I0MLE0s>O9 z9FU(POF?GC+~$S2=P_sK7`@|vVJ>^K7MOP%GN>m>&-yK zdIi$4erC{B)gIQNCPS>Boa11{i;8K`?vzoi_e;qp4BAq$ibWi(Kj0xm#rieI2#Y#= zh_*o<7v+;%#~_1PrMQE27K$f6P1AQ%3R4my%7`@*rq|5iFA}^E`ZA;0;Mz9wN5HBbv135R4d2*|K)KoYYLASO)4y zS#2mXXhkT}zZyNaIut>G$NQ+vM1(vI=~%IubZg9m95oq2Ztg-p{#SuKk}?W;sgwld zVHw=_Xeb8AlI57REwZ2)W-Yjo+bY-)hgRTW*; ztL*6bL$B&)AA8A1PegyxBTYHxe>umdV)e}>ibajA-e>e4)cf>-c#qv=`bK2jB+RhJ zV>>K&TSY2L@yo4G$m9MGp3ExSAyk1qY>{%=kQE*`DXSFWQ(sny7`F!|vXT?kS%qaS zmq7pE$s{c}H4&5xRBSG^eS@UnCB%hDaAmlPtztl3C^M13FK3~QO+D5l9qVKU>tE#= z>=Tor!Oj@0^87@m1l1{c&k_3IJj$rSc9oJa*o+JYyCqu;CRvWbE=5*&+{&!d_V~>% zZH?a?%pcdED<5^-qJMT7Iv}fGWLf?8y{q;?68NY0jgH3cL6FvsQ5UF1u8?7io9MQc&)_b@glM!Quc&Cu!{NhbnFLF+F?Fe z(;7 zXQ2M|=!$eHA;WR0p;_iqi3&ATeLKs z5-ABojfc|i==Yy(+3Z=8Ey(Xh-^HBBE2sshmvr%vv)B{);!*LW#gpXDUq6auCuU zEfotqTJ|&<(sJJ*hn5e26k2{ET}sP9DG6HQ8E9F)RcMhchnDA&<wAR zK}98~sKmvw>_R>qCu?7x!}#eSxg1olEG?z+UAe+qWVa z7s{4XM*GZuQj)i4hWR*}_B$GF9qY=oDN@RD7Mc|UN23jWfl<~n4LT%UyF~~SrrpUV z!ydh&#L=#~YS$s9UAdG*j~)d*+#cQVoAhYOa(eWCkYy&qcvu{&m{LNOb#bTv*V%ac z=?t6*SMfKiw0APmH7e&p`VJUg*xjUdr@P&R+SS*2^_(cghAht?FpB3*T#C~;qixp2 z3x8%^OJeu=Dejt55+26Y=qc5C^Dw`Yg1yBTdzUBx?h7BRk9qT<|50;@pgG;;gi+= z%^ydHt7eH&4~xpC5YW~O;{styrH(CM`87K$aRy*R_h(K~-HCM?(jL~WAkDBwO@>&T zyI7B}7px;Gqga5>F~!$vOdMB3xx$Co`WZZa8i z@du~x;K-X=cV91DoI@GqqEbqNi;@gn91Oj{g=9Hg<@D=W2DUt3`6QAE?Ax2IOd~c!YR3!~axdp@j*>s3|(Bfyx@hiYZy-EAkEl&fTZb z1l%PQuHr8O&U=vc4wm5{D)|te!{HaEkoFu?bddHu5^wp2B$Bd1HYTwZD>QQRoevb@ zWSXfKiIswPiye~v;!%4Xv;n{~&IZb#`}+X0=`L9QNXD~hpxoG|b*@9&v(9JFd)B$w zWN4kQk9Vxoew|n+NEz)Nk4s5dr{jfu9 z^+5-E$FBtXiIh?3&qzr?4`qP9C$vCdkSquKw(kWxG2^ZCxIf2D>O9Juho^9>uPd;_ zXmP8a*@%F76C?1!8rg=T4_~bz3%K#ccAZ;*k89;g7aD>$0*J#xG@}dknE?T>U(})E z#_=?o* z^ptC)X5o-bJVRGd8}e{!nrHB;=sSs^f!=);DVgblw8zZUXFO*1HyJYXSRaR(y3d7~ zY|1DzL!~5`IV1x!tLlXr$#R&PhpeRULg5O$z1O!1sT6$3ZlqH1!32bUoT+?BeGVTZ zSRWo*ha|9i-VJl}lMw3Zc-H%7yt*^BYJ!}Qx>fvu$MELBswY`IZ{iLc(G_|DP}=?Z z02+|#3~mO*@nml6iaX*)FDz8;z~Ul;UD?9Qy^xP(gd@Sj_qkn zF9lC~CV1RrXo7aV9TS|pR!ndsWz++AKIDg9!$#7ZXU9V}j1e!iv|5tg?f! zdqQ_7#Nlot>x8D}kWB<79P=Ah#YOb8*S@AbYT}=XErTn(i{*YY)CAr$-HCNM(jL~1 zqOrW|WS+?o>k%C8Ww5n-1Xuk>u-;7>#rgxt7OaCaV7(wASS8EBdIGXS_>5Lk^^Plf zH!H)-UGLzq3=*Ug$H#I|NurqR$M{MU42&8B-igAY|#<3YN-WV5*lI38$5LxLMYu+IgzSUZ8v(>`Z`1Dnm_#cnx>gGm$edt5a zDq^Y9L7a~&6TEB#;x#&INL_V^H6?IrZ@jn_mEd+ZZeeTS#xwlEI`kAwHg$}kG=1ep z4OGd)mmWpq(ZCF2g)BaVw8!GM$Gu*0yUCEn++!UUPxw?=97P#raha4vub7^J#jf89 zi<0HAxEHdF#o|x}znLWgyWc{rTR3&4vhqX3srw?NS; z1Hf+31pp<>0oV>%i%MXV_;5H-D1tA>;ien@;%jBx$kjc*aGJ0CoQt?k%u<U*zyy%Mti+U3f`O`1>3= z*-QlGT(j`^%_5r?C$@{c5sIw-DfB!RU?Q8sUo=Cp?Nx$@IXG-?weUEb+1iqTiVlK4 z;@!m`i__QQrO=U*4$Qj!ubYgu+76?iESjyvCYlM62-&S#qxm-_M4AzQ!C>}nx!0<8Ohm*W0|^1~0#iWUzGO^p>=gn0d70>V`(-KZp_CM*tx@S1=4W*vRA=mGUjdui}u1RPQz z%{UZvK{HCh6vX$M;0Cmkl^DZV&jzBbe?#a(G*uhQuI3B%7T0ZuFGKP>gE*P5aKV*G-MFwWi{X&?PEQi@X z$Wpb*+Tu+3vKOnsX#8o69&fL~Ta^}kJoyA&v#0;{zn>%D7TFQw+vC(%;s@Rfm%;xk z>x}&RHsRm~P#U=JUt;ba!3}wL@|%WK!y@H`4aH)Wz!=D20#kx(laWk@mlTJ()$$3C zz?qs=jI5K>vV1#cBf;CrFS7IIjpt)_;kx{Z)p_NkWN9hTni=zpyN=)mLy=y2=bJHT zykO4DBFf9ZWOUM*$Rc!x?!bc+rn8jn2FKNsUkmSenf zWa*8PiBLUW$t_%XCP1jtKauh{kHS^_!*6`M|BOTIiUL~YGK^Y}2OG<*Y$_%7k{U0GsvK-O|BP*$;aZz!7 zCt`c?aqGMBd+%Y#of^iSdhSieFZL!+1r1RIZi-694h`ErBMnm%ZQ6*R)Ez8+rh9sy z`OILEhFYXO8ahw)Xs9+B(r`>?hlU$!g@%VHqcr@67$a9b8#B;w8C1e#MzS0lPDPeX zFc(RmnfMDTcKb|&x&;5wCDz`pF7Z$__z<|bNyZ$!dz}qCT>SJYxp*j%x2JHi&TtU- z8l*kkJw$uC5?Wz0#NGD@2Y2{g!Tls<6nAzKcj3s!v7!{s1Gi*3xX(hC*JqA72=)2; z%t1JVKGWUnGkvggr^!B(#VeO^75|W+s=Jh+>Db5wf`(!&qO*t^4ngmILV~6zzQ+ij z^u}bLS@oXunU{rC{g~=tP65q-Tr2;cMfc@kE zgf-K=@@;sR49%4{ak<|4j--p^P~>v?jyr`>JERhiVyOl=N;@eI;vR*xhx;uAHp4yGWQhBN!yMeZ zt`yuyQbuv#B_)A-RtDV76t`qKxD%_zncq7=t%JwcbYBCnZ2{_cuG=*=B;_j~{6jv5 z-l2ThTQ#>KW|9wS)#2l6w2F6cChja~+`Y!UD;kxUt;tbeq&<$FL6|d+jx-r^G>hYF zx^MjOrf`%`8Rh75DcQu3RELqUiSD&b21y%?b$D(xBxP5yd&x^QIV8=J?llVxHXsl- z)x9o5#rPg~ViN9t1494(#RxhiSr_SNrY8+Ok@jeqj$mdq9BMM8;n_nR8scvV4J|06 zG>njvprIjyt9<;S&>&fktHh8c>x6pOY!f$$qKHH5cKU>LNwT2mg?d9#Q4P-X{4O;ywA0RvkV{&???J znYe71#$Du;m7>w1W@~b^57Hh-6A_t=qn%BL993{QP46NrYlNfk$enU@qLgf+i&VYe zWEXiHS${VIt&OmYEDVoZC?gPlF#;__7x@q|yQwbH4;4cyana7wMGo2*Mo5l8%{aV_ zlYL}?otfbbFFTq~ke_U%J${BGQW-y+j1%&6c}ItznahQrw<)9i93&;dk3@Oral(f& zF+d2BEXRj#MpoMJGMC%C+`iL6eT9GMD|w)cAM2{d8Zbzjg#b^Iq;|(w+M{+zC5rQf zqyoc4+%1sya9@TXWw?Jcti)Z0q1opbbCwD24=JO#kC2kUJuE}td1{s5mMjPNZOB3k zR~M;uyuQP4TmsZIuD~_bcRDE_{6jvr-Ku;njRu#Z=yU{g@*%A{e6&WZkVN`84Vn`)A%FFu#-?!5MCRaSi%NDl4dV@t8)*|iE z&>NA;Xn4nDNW+PkC-__?^19IQ9A%V-=28+gWEx(s$KZ}Gl4*E34_Rr$%iW0#U8JkJ z1pm+_Hk7MNtmK#Ta3>N0o?K)aUb0a;q!N2+xcJd<5cfAod${}E=HdRxWQhAT49z~= zcP$azvnivv^Q0tj&&be4Zhl8_OP13`Mj{I>l;_+bWDL3T#{^8ogtf$Dm%q`G(3kj~S6IrMP?K6#2A+m0_hQrlGI8%~36CFPtu`OJe&9%5$ zdhJt+>by}47e#o_FK%q34Bl-p0$-uYn|PZFo|G<#;mr|jnKyB`3hqn6yp7*BUmMo_)PeWG9w0ZMapt)=JP*b5} zqaV|EQ< zMEdnFhM#<`N8017KfGRoJkQnHDDeG5k1Ci?ZIG8q5$ zmDMvhv0vB8hmbM!;d96s`sxtwA3?xvsz2|7iXoLaOge7hr`3GJq)a=Ob^T&!zq7#ywK@DI89 zaGY`z$D_dTlWQ>OkQ>p!=`QP+lbd*Adu#!MCcf^HfJuPA#_*G`*O2!3YKMqrd_8Y6 zTz78W+}PZnD|O>H_u>wdMEE;sd|ar z$-4|-Dm1GY_jYbh%i_C6c5!i@T8XXxdP~l>a*xEBp;6S7Hd& zs41@o|2SlFMJidFOhyCwZIxMCq8ZYjB}O8in%izRt!RnSd#b!=iI?V!C2A?7mN-;O z!V;q|Y23}Hzb=-LEXNY%$ih}iDu)M8sBWl20K7T}72!^-+!2fCVOWQ+jn&S~KUrm+ z;r9s=$-enMlA>fsOdoR@jdo3696sfbpat zaGg?MuO)aI(UufQgAN6IN`peKLJCwC$UBsl#16&ZG>_W2m}IFW+Wg{Ld+(jM$EOph zdCRCFm5Y#$)!7S~_C<&_Dqk`gQh9KpL**rNg~}*pl*%~blf*t&73)N$5IS@}L;M^l z1u7-$WMa10#&yzJ zz*##`Gj4bbtTp8c_C2IMuw6uDxeK<$WC-?HSCw&d1neV}QLum9U|`1+tg~En1=Ijo z$#VQ=AhNKHpbo(nw?1p)D^YVYHed@IUdDtiY@3nsAVw1Uf>h%8!cNIbqQyn5asJWbs-7noRSXv#_N+a zzK^aD#DpS&ew<1~1AXwvi#X2v=mr>9d>>sOruj-KwZIc&gkYGH@?_b>UrS_NCs5Q(=bH9XiZ2D*!z~Z~8 zLfvuxQIny$FXS`;@*Gr$VgF5hz4%+f4U|!HuR-7yb4QRLn~ooeVjA>LS}5k0ta;3W z8WzMlAq&0<{a~uAui?Z-Y>jVLeK^K9UR;A%O?yi%)vN`RU8`mNYg&tbeBQG}r^vX^ zB4umv<~ufMK?6Nt13E_UN^FRP_Nx{!ZpUy@K@AqeL6TFe5%Gbh!A5X!-YzK)K0xd7 zZ?KJaL7fn15qk^HB*WW2y0v*RVlH=FZlu1c(A^#Sax#Xu?_hoBvzB?~f2e}g1&!@# zgwsGfAsy3pYT{RcA?uG@O(7a+2}fo#kSN!Wdwin>pHM~(bhMPj*k5#cV*@=063`zd z%Q4WM$ZA9x_FH7dIx1y%fFz4!*J1tRD&IV3F~TT~CN(=o>w=oGgE{f15BlB)i_mvP z+Jk;gnFoElH0U+?4)g)in+rZCB?|o*DGBI&94)lAG)d)H)rWd*JmU{p; z>91Yl`;Yed>vD+@*!{^y9q8RrGu~Zgo2XL$DjhdcRu>uc8Q`}ztCEUbq+`|AO)o`w zH!o-~_4iG$+CY%`=fzDb?kY)`TCz)8j01%CPCe_t~(jg zv;NSg#j7a}N~|NEFTpl&wrNGp2O#Zf{xbTPX@0E9(0_AW%_DriDq65-O7m-_B#iiN z1|zPYFGiFs$B6GDOJZSZbNs;`RlEpui#}?y1(>Bs13{#s$wMdt>m=UcH43hWOgVy? zfV2l@9X#K_TxBu@(`6^e3=8#TZ~ZBwW_V6YvNK-MxHImhU?j@{lS42V$@MM13mCLy z!3DlJ65}n07TFieaHj3S>UC4qcc2ITvpd4wU!a**dDOU8-(6#mFZz`Zj( zB^h*aF`RnA=kXYkh*N5Fa4wijoSPHeatytnH@%7TQKUVbIVqfXnhbFcY~|qmMBn{( zDP_7PRVj`79mS;WV^yA*Cl&s&AK;|0eTOF=Q{~qpjW2bZeQe+vU=N==Qtm zL!-o6I=Tf_w~yq~2oKD!j(1kw+AOHcV3em{5u-?!W0WYeps(!shs&Mp3;Ty%;tTul z!csJb)Z-ZAIH|`8`x7=)(+eY2gSlc5nadk0ktrwRH}yv0mWGpd+6tVpah}CCjnv zE67UTyD2TgG6KPKrhF4WElonQ_-SbpM|B)Gc9lnM0)xy51lkX2&uB9* z^MH0U83O&YxdU_}ckki*A1R6Ip;qL>Y#TLuAq`OYpkl zia}%WNcCz=mAUHr8(dxn4Yuoe_2sA>Qi-;@6fxB7McAhy?ZKXlsAcx;V={!jy$icS z-)q;7GHTx&q$FSu&H(%Smjt$CIk4YHR&>xhA95KqJ_EDKX})g-b!WpVwK+J;SsNzp zM{-(F6Rdr<_5@51gX=Hnc*`}(e^6@Bf)r@Y!|R17kQC;FkHuS3&*Na)QY(Kpjk)YbRt{D%5q=ohiUW6@h=@SQ( z;eV)1=V@f0+ zCsNaV4!)S>hay;u!SgUiK8>{x(y`GN+$WCmjJ31L41vst+c{JW(Rbl}M~ak+6QyJs zzLnIUURQ_iDR23#h5oEPw#IL_=VpSPLz3z49L`Oe_N>1lRGp~qs6(K++_s}fIgzKM&Msib?lYD*KecB{n zYIB11d=z1@-ps)l>j5=c<0Tb%#MC6LyOH)_{XD{hb+gG3*6}%xIo_5}u@nrYjGE&$ zDG69zGr&3wiU5{mIk0vmEIz`Fc_2)vQ^6ZAOgU+n_^k7NPI@W^2s)|M<~ZrH=ZH8p z70kGu6=mhy=K-E6@Nu#Rc4Cw@tbu_b5?CgZB@VIqZrQ74T`89Y`L|V_50wESi zUB3V48Qd2skSo|=9PCGU$r!IGZdSAF4#G2Mc%{4YWE5Z3ZGJ5t5@ph^ks?d@z$qU! zwI@ykE@5#o< zUNVfGYbx3fgtGaREj&W5TlT|BeLZ?cBcWPv!jT1$aIhhpUz*6f<3jOThzF{nrYH32 zwCq%O?&M!=dSp(#58clu@;pO35Y`n^=8p zwBHN%dm1=1FE)wz48Lb=eoDrn?@SYF{sq#W=6zF|uQD0>>Qh@B&D*NxFHlA`Z>gHM zS+E8zy1qIN%_3k+mgB1zP$SOC;9fEuwZiJIc_d{`xNuw~s{RdrGQnQD;#3mdjft9P>afj7Jt zOFY2+zu&ccushw2bgYjBf}hXz0>RBD16K*0@tf0~-qyvip_I|?^qQ39W8!qM#S2(t ztOV|vHUb>@IC@o)PvR;{fY#*v4-#l^tF=e{eni^SZ%|6VFHMHseO`m3-=V5sj54ZU z8`TecbI_vO-S2ozy1QgK-Ti80X?K@CgKs_d8dG?GWZH7PKIo-@eK(a zY;=^#>b5vyoqG z7Wb}{w0r_6w-km>-5qNSXvulG()iyF*8f*Jfgy9gNsqz{E(FUXe{on|i{&Uk%bRf~ zdCR&JZdvnVlNb9Tc4Kv|^=zt<{cu(~C8i=g>-Ek2-7B3A)fS-gqx7C5^ z1_?Ttm4A6U?r)!!ex{aZPDno!;~BhlRZ1b0)x>A=48Kn0)$<_F@a;g}nMpV^*{@GM ztpWkqx>)MLn+uSZGWnq%!G^NWlL9<=&nt}qg`Y)|aVej(^N!vDhL`9rc<<|k#kHs` z+GK9Ytenk`lU=84Vl647F>9oh#B{nEUf{;8PdH)RL$jQiwFp^@vcASk6PBInT}YN5 zCoh!h3F84^tD$-kDK&pf$4yPH$FpXVNX+2}w!NlU3H3p4TuB z20fDH&@&xbO3!^~k)8}2Pre(X^hj}sp7T*$u!5CAr}ArtzKKd^a|1NTy0``SVp)Emx{l4a;fgU~{-!S3j?;#dbTkT%f99t3!P z|E!VVDHMe9EaXjrAnS^jK+)hvbn0Chno!H23)xR*7dC&Q*bYll8xZ9Vi)ea4`hHVf)3oLA?SkpU*HZk^$GVhq+@l@ z>XO4;giv$lJ|;uByKQu=TcOKh?I@$xy+KMgg3F3sxOEIpu60Gwfjb|9G%Mb-RHA=N ziU>ax9nE9>EiPi;Zc(tEI}WKAUt@X`=OswTstxDc13jE)n+$Ot_Jf1-DP1Q!iZY7x z9x2%fCo6VwHZbJ4I7QIG`7Q(&c-Ee+=nul|Y$q?u9 z-#a*~_>^q4U;t$l=krps5l&X@;>^#4Qv@BH-`=P03%dx$;8T2AlAi^fY8uoaVHeB!%kjJ=Qw&)TV zD8An*O^g^Vzf+&04{qH69~^H!cz%iJgWuykM-}?ul6uDnyXglR-lUBB;DJ)Ikq@$B z*9ULEH$z_&LB|I#gdk!6e;qN}7!<}(i_^FX9y#fI~?0UplX({R=& z9Gn-#1?Nx1uQ*GjWFwrc*u^;)7l4g$ilBq@b_o6xoNISV!&#JEUbF>MK z$BGQ@wEiC44kkmhZizc^uh!2iG)uufUrGwxI;a>=&U-SzU4ECrZ6xTxeHenQOTD-* zHSh7A@r5J1rY;S@`Rlu}Fy6-AFbxVor9HT=0InbFBw z4$`qKW9_1oJ=T6SrpVgzZynZpej`ru4rSCy4wjOQoP-s-PBM9N1}70ghqaLq1k?sZ z_`+xjqaXSOlErPiEs<{U*Wcz(=wPPE6A(@aOm{Foq{=n9flk zGHz<5>|Wf4orI5pj;{%>!%2V$Ofw2e`JG6|zM7#^xF1jSD8I>ME`rR!Zyd_s)Gr;J zLm8#KQc9K`jgNRviuS)3x=+Ove0(U<8sA^sgs;GJU5w4dX8EVE;tRfCUNUv z+~Wdj@<}-a-Gixfw0LljV7zQ^ta^>d?(*lg%v7u%7b6>R@)P$b&*>xNA$-ZRemF9x zt2-2;{I$FJkMr(Mn@HGGe_k6WXniOy*CEnIXPo0hfnzyLBL^(=50ni|rwMxmr zI+o_+^mzMTS>g`>1vIXOC4N8}c`!Xb@rc(K;Ssd4yoSNQ)EapOPo*!DhvRrbZm?1c z=$ox8al9g(FAw(&nJCO4ZW|&j%_$3CI~=U$4EvcD_=bq?*7QK1rpiG+1^QU;9N{7> z4epGxDH-6lN`sq~f?FGk1}fL7%hJVXBJH_&UdVIthfIc-+@rs8T>M+SEgD1YSjwo2 ze|Q2*;*z`5HE?6+24CoQxG`RM%q-`U`%q*7jI6DU#=s3<+kwYi>&huT+_w@c<(-w# z@1po*M{u1yR=B4uovwp@xiCu?#fKHOcDOFxxTQ3OgZf-yklrmFF(>h{&O_-DYXEtQ zK_*2Jq&YGo-0u^@o{IdbzL4!cZcOV_BwEXv^od!8*2sf z*_2Vp^QGk93;=A#9RPL$g1;F6q?j`Rte#{8KtbNbb`t0dH~_T901#sIY}hSt;?Ht^ z_q>TaBRC}A5Z-tI2o$knz~>HUkBN@&ibIY9`&t)UhWeNjs`!7zy$O6&MHW8Vfiy&1 zIsyu~5fv0%ac6M}N@I(laY0dBP!VtiH4$8b!A?usHX0X{am@^?J`hNo?F|GR?2-dPC$0DYje)@6{+k2A!yPjRf=g`BPYnd4 z?KP5W1_A>&`#`WKN+jXpqhYib;c_5&?lW~=y80ZXt*duB*1G!LMuxq6;-`+QfA)#E z`ee$etG_vvCDFTUv-Iv`Zjs(CSx)cngDhw!1HnXmFv&X*baVy+Dev_4wUJbmJ1Aoy z*ty+-fI|Xi4h3{lGZd_sw2;&U(6<`UBxyR*mZUEVElF1z8IpADYKNpc^Zf(LC`pe? zNs!c*g`}N;1R+qe9Fn$_r-p)Kal(doDCp!21ybH2=~a|Zj+Wa1W%^L?YicO4qa_Hy zXqkm1Gd^5lz>=H`khbJ3JI0c8ijg5XeLr!?c~HNdus>y#oLi-2JLAJ2;daM|HOOiV z{x9RhJe0tei_Gz%icCaHYoaA{af2`$Hwab97YJki>kR}#z7pyB*Ub3v&e0a~c}9lg z!@(arke_IhPBWM?3i&=MDdWTJ*r>U1Np$SdRp~bfY{nfQ*57Q#hrcN1j1MoP7|z5E zxAhK`=fDrbZ3Q}63b*YRi13a;dWFt)Yq43PB7J5&3IQawdqk(j4JabhVf<|fA--6~ z2&RnBwQ+S`%LT~CoZC)|O4B(Y$vc zZO!|`k=DF785w%?X-$rKS9~Dm9ZMNCZ>^MsM-QBuIXT{UhIq7OIo&-USpXw5ztb?O z@OJlHCnidHr@ODjxBx52N^1udKD9mjuaxoFNd z3zqT@7t3x+aq%NaNP4Go(M(!cyN3%C;bI08Ik*XF%fXt#mV?Pgh8!ICfy2SVRl>oE zlu-_9q+~l0Zf7Xk&J5Tm80JD(IQ`teGXwtb^t1@K&dz{+G<0H7I5+I>05!k=Pfu7b?4_Z|4JyeIHSQbyrFAtg(W!?!Hi zWUNx!k42~q-bG^j>5-33x{+^VDQLoy(*IJ069u0~6|o2#54ZITL`H7|z>SeY{8sD{ zB?J=zd=JIIA`RCeZE09N(9&>;k)anHwaTGkzJ8J+NExN!Us4iYFfU6_*n#kRX_nIy zHrB2nzz-~j&O`+89bcY3~B!>5|4>c&H(LBI?I<~PzgKvgQ-$Wq)9v3zB6;gVRXb?jVR~4mxXP-jd_2kh1fWr}ejufLc?(Die;E;pj4!4MeV{8m3zAY1euhp)95~qfr-t$Q0)UZIPY? zt>y7>1>PUm$HQf?l{_9MfjvPW=1~$#3XrbN;G!CpL#HCtC0sCJxabEJQa@!zSBtvl zk&F6`kXEW8)gYO|mgj z)4*XvNpjg%UII--BnPYEqRjswuc;{u3qp8$&po?vifnlf z+-5ml!DH7ZG;M24gUc7GDJ^idMZ(ooI$T~0M8^IZ+y}6JlZ1PRrnADGM7WVOyYdpz zie0bv*flL9?FmvexR!6DcuYj@ zrqSzVO=pEWjd0Bt<_hlApda%hEt_?7hk$2}BN;N=K(Iq2`4r0I&v`&+Yfi(x9@@z& zB;%B}Ox&7E$IWYj$f?w>y{P>knYt+MS2djtcd#tE-L-5R` z!rR>Fz$?+uICM(EyGTj`Ube?5A50N=*&d_3f~-cl>w#*%@M7No_)7Nu%ZDjpl;dJq zE}o<;v-gp>D~Ag#uEoaZ=z{t9Hx!*!BY!HZ@ux93kF5aFFk>(>Fc9hbC(M211N&MA z`WYGCNB;hX!@xEAL5Ez*=xp->DJl1nY%*3U?Z+Zi2KSL{Km9(EO}h7yPfrF@ypQ}J zs&MWjFF_Tt2pbQ_55_aOz|6Psr4OB4<=>!_tB6#O8PI%7iP5vHfdoY(JX*BnI&>vD zV^qc^JT9L<6*qa#CFhBGZMd{nV>A(Cez}`|Zbj>n-m6sPCvuTPX&I6npg~0NC7zUTn+Qr^>B(X-{nHqk4Yl|`&qSP;GA80W zeKp0RdiR~28%GA9f(+`KmAWQUcOx2PLMJfX*XsGnx#$8`fvf#QmB#pf-*QH}h~ILN z5zesJoKJr>Wz*Pu138oy_OvOorzyjpXp}r!_)@kMUYwo1X{as9-sRe+b{t&?@tlbp z^LKtd6+V7j=IK1=^|PI)1=ks37(QNo&FMUc>!%(XDWjdIkCa6CXvh*B@4H;Whh#a? z@kV5Y7t`5~C^-r|4HQ!CvO|O3!!_U@PD(qm@o1FB@^E5$K!U=7MrQ_vJ-xVY+1ujk z=E3#NQU}+0`gw-$iC1xrl#;;ZyDsyl`_;;26?GorYw|IYcFd~_A(|sy)5-p zdKs&Lo<;lva^Cowy=*zZ_u}nk*UL9d%&GZly=)wEC@sBA>t-+0loIF{jfTjzK;%z* zSy$ASq_dNzfrdmHaAo|Z-)=S2W^rkGeNDgUs-YOW%rNC?FVC4a%fgHoZcLWhOnqr^ zuR;zNZ{(IgF3cwNNh+zg{LBkP&Lyqw`A%Qdl?2;MTdZM?=I$yjq|9&7uEefagR~uw zx9(%R-fSbokaGE}PS^W#G3~rVF=e#ty|X7vqU(jSbiHAdr0YqR)Ajlz3t06IP!=;! zG(WMNi3%BJG*cFQxVq_CDv}zVF!SL=_PUjc9=f)-+~`iMi;%WhdyB?$-ptcRhFHt$ z9jw3TXA&wXqgcP%!(gq+f^`g<$4ZxEIarTEmIc={9b5q;1Hi4)7`h4}MXGSXZNe*` z{Laf@`Ob@nwm>-_Y(W1eqd)P!iL}LgplB_47a1Aity=8h?W}lbQ%3Rrw7bFEoCWVB zXau~H<=`EKEQ^=M%uhFFG4M7i-X`FcDjd9B1aDJfgsl5nyiw`FiI3zyMXrjs1j^r) zKx4xsvXcfqiRSc#_EEh)Qf)8{*2*32qvTco?3{}62lf3#}{dDc-?S8?#PSf zZkOFGcTX4@a#vdCaJTVg;VwcMJ+)pxIa{!{&;{_$!}~osB%F*6UZ3bp+E=Y3z)a#kP&gj^>jc zO{L#(@>(GI2t;V-hL;FaX3tAYXG0Ax8yv>aK9o)H4DuBAYOWXpJ06A2Lk4pwr67|x z1o^lk_?htFPyH19HK?mv@PADFZG7824ZlRFh?YvnFXKg^cvzpN444#%UIVXrVpd6R* zI^vm}UBRP$vDd94T2hX+JMGDpQvkm)xSG`iN`-+!=rGO%S!_9d)sBt1t9Cz+1vx|hZeeG=t`3D`!SZn1 z(KmGqw;dIz+=YJDc4Tq4#5IiMZN~)4d!y?mF4p*~oNyN#{%e#d3MHXs@-U^!N%GU( z5jRf?cwQK>j55rW6|mnUytGV&9D)Q_=jC;5la|iYfV^6Ep6MU5^Tmg&h8LTgM^ zWO3;^%3gk=m^k>5jqk`HQyN0D0y|yV?2zE>k|=tK)FKOeQqnB!9gfn_6@tFRK1jb2 z{DTod3cm{}n_x9T;r~N|Yn``#);epL`kd)}Xeedy z%3MEvdoKC2e?^e5&uuPmxb7IfJr`X%V@(-aLHdtDOH1}mVhNOACxM^!q%m@#j5K&W z)ms}OBak5@qBb^*2lPREd#n`5=%TFPeQ}>*1obS(4#|~J2ABNjJg>eFWBQAbwteNr z?zXQK8X1O(?(>|!5_?wq$}W`AzH*(EM3^YVVzT>g&AKrXCM3(5XuX3hAe0T2-CvT8 zGJEnjcgb`rfr7#1BpQ_RYcWjsFK?KJxtQnlA*t61BiEr`KH%s|bF=nOHkhGP4PVltH}hGMN$tSw!!tDpiD zldCDk#(EU{jmY{iY|<)^Bd;YW*h9$k19wwS=aAGgL~pGrY_{L;NP&@bV92H3rL}7h*`c3@o1AWZ4Fmi70{HWE@yln}H>~ ztSn;(b(~ewFAV*}x*yW@cbW0zj_obhU5pHOP`5tqV4e7sU~MA@igmP<{EHpbY{nf) zo*oSz_=;uwJE*0YGlrC)nCze)9*Eq{V9*$B5Oj^f<%$wvS6{LiVJt~{xjdA zJ;2D&vK?Hs*F7m{yQI)gl#;OQfEzO-!pEnJWhKjr2(Kbbx~H5vxl+f423%?2p@n?= zf*S}K&}6+9p}=E!sn7`pSE530BRogqq5piNI-#D1w1xUoz(PIF$Pj9eryRrH{)9m7 zO&K-pjZzX&r)7cq{b>SKvK*+ZkOf2y96Nhp`hmO5-T7OBUorNcYSLe_wImDo)7wx_ z=#yFmQ6BG9C+^Z%ilAOt5Rx77 z4Df|TNH^PW5`fm^j;UZRPe#KW1yNW3lR1p%x6EUjA=5-#yo3*{B==YJhMRFG`p()W z%18jm%~F1%v%LmpSUuYGSEFlT?owM)DJ9eQ^z&2@XehH56I9=RLivVf{@0MU_StJ& zYo8a54DB#vms~2&&k-{nxYgt|(z< z>z?Do5me*${O~A_@sxL_`073Xo0iAFG5pJeqjAc(9EQJGBF5BY zpk6oN|4g0T{`WfNA^A417s%PBX&RpZjf=b*FTk*B?^znaB6c0!8{2u~UrI>PkF97p(Rt~kOilu<|cvWszq zNm)AT87GS)NS4!4had|xfg)-f8yFKsL$M?YiXx_%bj9X`=&xksT`wDtW5C6otK6A{ z7xRy=WN^INujhfA?~f0~D8W@m(ZX3}TyT;(Z7?wdOSSr$3mh7B+E!SXH7e!4-c-iT z3;gmtM+T#E5stH8g){L6Exm>_8pTnVFE9MO3ATL+90WtoPc&SeMk1b7H5+u zp?PyKRqWSZ4h{-B21r}{wFUgcEgH&0THV-KWk0PlA}==j&Co^fhH_Q}Ug{cnX$5k` zVUwm7XC8{9F=6VQ*B|Tb(z@vDN$k z6kAQ8jN0loDG6JZ0gZdtayXR3!xG7IY_&78Tyo@|yY4AeWFy$49N(k3edC)Dfyl#n zL=dm;pzOe9`DkG%f;`!gRvdN~oS0;1hCW=FYY>rv*+^Rke(Pizs4y~Q;GBOs47^t@ z42-9YGO$ESf`NHi7&sIPfC0&J80dv8<56;CY`UWe7xa=Jy>#5m;h%foWkikKh35eA zJ9Cr{^L_P$F>;X(Y0{zNu@Ol+u9hbV{#gbd>4+k2=~#ytW1h8KXJkmnsDCSxXBj%-JYLU=U4LYhp$91`&x?wyc9nz#j$4oRS6NkiUC<%Di8hE7RQlu>%Zy`V#_c+_gkd6Z$ap-vTA)(`N z$|xOoOG(gCm4%K@PylpDmP1F&@sTRz6xW z4TgJk#8^WJ_lCgP4Ox3l-JTfW8BsA{`{JizN&rsgfs=XQ zWGp7q@ss{gPWUk+aPmE3IysSc9ZoJnyUNLddUJHD!AMSqBW*c(0&&T3a=4KpCtV(L zIGOQ)aMG1B%E@FY2~PS!aktB?2?{5Y<#5u7EW-)6L1%Z8y34$51UY5kjR*Hj1|sM` zzIfs9%7*zU&=-jBWJ6kX*cgo#m5tqXHZ;tjBO3#ewro6rsASmaXJp96?+-X^Tywv$ zkxLn6;{quOHl}1@W7RNWL$Vw;>X2o>;FdNCv13b}p#py4ix1|A%=3=8PEax;KIk{4 z!Fr$^vIT=49dK9Gpg$H}sXBGfwigbQ=1~PWa0zu|TN#9bk{nuk6fhe`anja`T2R z+Eq(0$|#LpF34ZpTk{uZUJ4QOHd z#f_$4SpQc4UugW_YnPP&qkkB?XYT=>UlFrs=^twKMaJrx{exDAZ$5ZBV9;+L^jJ>Y zr`;hjJ7^?kXGj>|zo*DZ+~bu{->*8={)$(iaLY1=(Jdbz5!>2r=Q+u65V|q-5s7jzE4ps_#m?A z@Av~RzXyNd*Z`%z5H8_#xs`DjU6u!h1V7R`C^oB zB-bUm#x?puS|Q^zD7dVeDuRS`R>HZx@u9!EP`DKJ?tXb6tue> zgG~bl8^nlF^M*x(PY;WZLfqgBtXu%W-xzkF;!Kf1q^r#Pc!dj+xR9e0!Epniw0Ykzm%$-a$p#(SI1Xvc#$&%&HV!c|WTW%l4ja?&6gC2sQ8q4@lAHnp zgUiO}Lv#wrEQgI{$nvsLcdD0zGmjGvn!y3S5*HBP@M5ECi`SU zh%KJJwa)8TTMEUmbQuDEwfTFc)vQoGvPo%`1|3?vp+WVl2V{*-pB=+gC)~@YJAp{9 zx?79EOpZQB+H!R4M$6ILMur^Cxx?XTr`v_2rzoQwoN0Q}mG!9t~ zM|Fpy3cG06dW_Ja%MhUB`}InPS)r=>Rq2qr9XfJRx6*N&EZC8LU!qJG@4hjZ$iXK_ zTMmv!9K&RSUwZtHks$|<-0pC&W2JELIAxTBTqy|-LRmPNdW3KwSq=y1APZAS9cHJE zF-iF*4VQ^|osS?pPsMXb^9#$!=zYFu#hbNgmSa%O6b<7P!wo@OQY4{?)Hy~~K{S0Bk@Ozn&A-~5| zI{dyA6Mm1UjPg5IN`l{-Ed2I>N?7iZEQjCU5A*O_I3_j?Iw{+gd<{CSgAR?hF}5{+ zg~n408`lC;ykwp7V-~-5#Hd1kq(z6HThXF=URPZUyw0E_8&@E0*;v_X**Mq8kd1?G zbJ(c4RoECr8D-;MDG4_6$}@Z1R!{(JNS4FK`a>-n|My&spSQ%6DzAMK!Qjv>E5V;G zg}}E4wJ3LHq3mNsRB|W!IozED{gk^8Fh2?}W_ZT~-(I>xG{6u;BKsh1iJXZrY22#2 zks*=sTOA_Lj|!2kF-znqDG4GAvk=*Eh!81R4v~){3p1n2P>$18Zhy3 zOgu$f-tIWi&!d5bb?kbR^i4AL`_8EYRpPz)kjjzMll7CxNXfC)5o1xn~?I|6#LZ>X%J zlkl!T3E`~(-s&qkBHsDyG{S2T?Mb+_;t;+IT9Llc(%BGUC(ilw(dgoyh@qkAf_(Wi zD^LDZa=$wECilZ1WqdI+d?nk3D$NV;`r1HPiu-t=e?%&hzEg}(Hkj86*p*7QP35W? zZZWjd4A&!Ff2c9Tr|9Lz43`=in&Ie(V}=D`F~e}ms2S!+Nthv&#SA+hAZCy(#|*#W zEi%l!1#nE^$CM03#7BWqRB1!?4V*DVBLm4$SWY}-cq(42CaJ}eAS|{6#toW8T69bj zMT;7qPUXo8;l*rQ4iuGF2V%aX8sG8xiuXe=6lj;} z^-Livk&=v}S&+r|)hNm=2iaT5`YUhgcZMae}h6WD4 zK}?s3$rc?B#-hc<2tD86WCM&u9EY?e;xPmSL&PCQhD3C}*)j3-G9e;B8SOTgOGyw> z1g$gHKlTwKB+DUU8M2Zlt_&4s^;JYO%+fHd%fI6CbcJE9P{N!-7hW7PlpOMfQnE}B zL0E;TN=l?{hmsK5P8^{pAc&78HxJ6G9tnQ78sPUZ;7QhwNL#Y5`^u8l$;gnbkINjg zPPs|QS~J6vb&Qk*S=kngUg$4mNtQ#_eaOnnQ2MIT?iiv$Op*Eu|1h%b)U3oT$Cw88 zUct1&~~Deo?xH~kY`P4l=4@@QSr_fuLUCYSZM+q&4vwn&?=-Ydq;d}*;{60 z$lmPf4ts%8VXvAp%HAL7__Ez|c^3Aj>@Dm`mc!m?Wc^j#=|0mFcizW{2aMxLcUT?? zG4A~LQ{`+WmQ~?PlM&y^nY8F|_T^sS>|Hq%!2h8EMk4-$v?byIfg|f7uNWB;aYv~` zL?=8Kz`JVqQAUZ_i0&>#420Hh+?j~Bafd2d4iO`fW#djoflRZr43pNAAb^P!{z1cy z@qf2K5Ay`q+!uhA+SSU+DsD||jGu+EfviaL4l8f<1uKiNt1+nq-c^xlR9fhH+~6l) z4F39>Dq31D#743zd`F)b1r&QSS&oP+D!F@t{wnn3Rd_=~%;|YW>!^h!9hJ19H=I}A&TH&KBWt5M}QWAVj%EHGQ1Xu7O zSq>kK$oeans6~|sxe|Kg$8+#cZYKo=!#`9C;<}vt4F&^JAZ|Wt4);r6ee5%0j{CSjGVblI2ja3|T3ckXJsl z-LBbjh|Z82hd%s5T*5rZIV^to2g-+8KK>BFo_t8d4j(6?;lyBlI(&@5M?MZg+VXKP z0+iunPa{JO7@W^=oxrmky2k**0Bq9H2Wd;k zOhh0jLJ@p3`E^vRA+*UFLK`L~k0Y)V ztkmOx-C64~i&Kfu0UL_@JwSg22n+NaL?#0?VZagS;;S8?hh8N>U#E-$-9t*Y19aBT z?E<|XSq{*N@VaR5_i*X&SO$`Ru~_mufYu{mw+HlK)FaW>E})Lf+|}jZ#(<)QeFWaG zMmlBuB7`6Vyw!ju@MTvyz=uo`;BQh!f%lh^0A6rwX2^JOCjl;5j)i9+3yYsM$(?j{ zC!oBI58XNK@UH*AlNKN5BW{xksn{`jKU6GCBu+z|G+$;(9EyN3184AHD6tQ_Hyd1183>#~V4B2>Tio?eKlZB0X$|xHnis=qMyd+HuI)8to`Khs!+1zsX=C2kVix9GtSs za`2gvAqOu^b~xyNrEsv2GRi>@DG3g0vT$%~PvJna91bQUOF78LO9aVxssb-9m$Q>P z%Z^Pv-QG+(tmBl{Vh7|2(S|x-Ecu#K69?zy79`xqeE46b$2>clhVDgrL^UU!6J<3Rs3G9<6$N{764c!Y_7 zSxOlt@8fq_66ECrk2^^n1+6dwOO`|4!N^Ln60EHogz~mKz0UC&@7!Xz#g3#S;>+Gr zO3X8xixH(siB#-R^3jfl5_yDB>wQF1fCz(U;w7!2=x98P8PyD$nqvdyUyN|L7DFC3 z(hb!SY=~E-gQ1d*RatAo3yrKQBrl-ay3Brsptr8CF{J%@U4Nq0Dc+hM{L7mDRI9Px zx{Cg?F1%9VOTJN&Vk`YciY|Xy3tmE?=`BO)uO6(x2$2C%A zd+FPkI$(xhBE9rO%4jb=R7#?kt^@+NmpLWD&09kOsU)#0S0%!wJ;BrOn=hyHmJ37%(Qc0?EhM>G$i+b zAqJBMso$X?7xgO*JL+=7j|K~|e}lBeJ_3=_VE@p_5c^Y;9PE2c6znfjMzQBhNnoFn z1$%gV!7f=2_DRUXqx#fa-02j&?4{s44w=c#NEqtYH7W&hy|b>wU_uI{8Ha)#G@}%B z(-nqR1Bn!@McPtu{F|17RYrys)J$|J=siIwm`53&Mf1gT^`)|O&3>q4MqJd9}T3=Th z%q{etE0qSR-=V>e`jrOxgs)lh#mAfVPWo$uj7)rtv}NL`6_$w=Mutp0e6hpC4&#N1 z$0(yrbd-`{Vjv*6f#6zf41_00mcztYWPyn?FB2op7QN(FGTkH;h~PC!U;Nu;%7VEO zjv-Lf8KiE9g)Q5%?o{upo9LzYt{rfjyip_L`vxEh`8U#*ko^#OO?0R;G9;vOyhBLt zMMB6d$|xZ}AXv#fZ(0^YE{0|xM6w)0Mu^fGgkZfFIL+QVvo&XM{L|Nz3^Vhcj%Z9W zq+W-NAGS%lL@u2`d&Un6{{sVu@K+#h;qNaXsP*9^xc@41a6PZ*ErS zbxvTwv3dHvb*Pf>ekIR~8-qG@OAS-Hk4d)FNQ<(=Mz++LTyCieFP5zZfe4%f^!WQ4 z1JGc-kgjhwGoBj}DviHxWn^fuPcLu`b~>IM!eC!rXbpC(ltc$^&SJ0yUBqCL z$#ST<30c{xndqfvD@0{bW4A))H7GS^n)3uAE2)td9BOt&3rfvpvSe(j(G#|G7ZVni zhGFCec7FJBAbgHn%Kd?I<4jG40W$U`(w4CU5o!%%i;N5zt2*Cdtn+!o*lfxuV?QA- zY4FR!*rYrSe#~+h8-=Xwj6LUN>_ZNpHVh1oe^9TCnF+#F1Z@d}Y{6lyrE`+8L9#w# z8QVvHk{-ObH3rq|4(34ltJa0mSg3K$Vz(R80>>npDf%DC=T0zMxu=)V|;zve9JUTY#E06 z^Dw-uS1?S!$jfxkk$B}!-rz%`hKaoBE`3hW?Z$JY-sGOvBjR%xsmH{19v#GJMUN3} z9gnH=CkGDLA?Yr7A+Zg_kJZ<0@ggET!kn~)bHNOCr1}P=>sOlS{26+-q53i-b0%bt zIme;;rL%?V<0+$5&y|um);%`585WM8fX5EdmlfAfy8}1b7#B1W#J7UJEqiAZtf3%X zPC`b!8504t{*h^&+P;Of)pkHi+r>tPj&bK$N83Er_8*i{ZGV2%bpMrT(G8fFpjiz5 zlI1wYNz{ldSjD(I;_lzZ_^lU+Tc@9YCS{!y>AIpU&p+FqC1Wh#9L*P?sl^eGjlMJ} zi26gM>l=)X28-@8^5A$f-->dCyhct-AuC}h}Lg6v{T!gk+#}? zg>YlcbhVM8nTEUCE@OUqs^|gd|q77)hcTZ=p?*x6rizh8r;YEJ1oQGeSdGk#E#z-HGi);|P)_JtQNv=#Ko03WF3ox|O z48NTTGgKR=IqwxQ!?C#Dg6kM21LaFuY0Ur18II!|JX%cg8s*e+3Z!%(!pVJjF?ID7 zZ?B2YQ}bdGUTK#WeJ(sDFIFialOL2aUq8fw51954a0qYKgJQ!$cZ^>f@NAf|o*?R* z(j9bH5Fy{N`2S0vF?XhgtIEwn<}HRy8sK`QtpPr*v;E*wBg1}h^k|3t1*Zx5!zrWW z&ykYo2g}i-8?JUlv*-ts<@AH!{(wed@h{nPFJFl;d+ECz!s$#S@Q8(F|l zH}n+`(APtR0(mC{EJz`Th5Jz`F$y!=WJz=>nM(W1jHX0ZjI>4e;ma1;cq2n(15b01 zJ$H&AE2NAfdq_$G+2L7`EF5wmRcu+f+Z??T!l{OKi&@Ma@JglC-UAbbmJ4Y1vLlu?AQNJ$_p%7X9! zC<5C_mV>Zc3Za}?94J3ZmI?&3-0zj}?vD(_czSW59FLvwSqN@bR05a+0aCd`z)PDz zz$LOH-~Xh+K+F##Z87JhFyC%ui21@(9Lyh`ESN8)jACwFK(>H+WfshX(KawkmV>!B zvXYqc{;UUXGiXWiLHZS2#mZ$IV3kT8tSf#6)>7=RuTpFK1CevopXV7QL_Qa3i@dYw zFH^>Qj0}-aDsqs2ev%-cLK#K=)_jB9cXwt_ErcdOE?ExpzQ_V{87M1@azmAsD>-)P zs4}z;`ueb(9E!fPkYCoS=ZuEKZ~fjFvE^>dyx9~epN%a0BZeP(HwNK@7V15bwC~&# zJ=(_h{kNR#ApBz#o(k${`-aS;;@yBb8aWbthZpl-A6}l+o%&QhR+t-IT0afoJx>Wk zs64T0YqVfuQK0-|0>HU|hEZBz52URHA}`wh*44<+0$-ox=yxvkLw{ROz10FIN=f+M zyet-|$1W;ZK(ZVQ%t2Pt_jnAo*aAn14O+^`$-8*L+rlWoMvpO2H9GHucm2@<$ zOu{XG#n7y=bC?Cm6hKPd4#*o&LE->?&tS4K2XS45w8izt^A^`>Muxcdc5yv?qTo7^ zGHSltq$F?^X2G@PC&49I4z9JxO5u|DNV{F&l+sLS(!cVVkpAU&MXJp2xK|f zPPf>YVn<^+2U}NSdtD!Pck;m51XV4Zb44kE^R0nEIQ1tua1Mj}BTl|S8HKZF5>80z1j>9iZ20`Sm$ihflB_Ek7=1#WJ`v|w|zpEadQ;e|!&$G=M)-I@C1ru-YVyEHyak%IQj91+N#mo(2l`>#zuDK)KNkWRzO214Q z<+?=jicT4e#(<@Hh9x@5T%;|lou9GY`yL}hRwsoVRzDvutWKefvijE3#!04RVYP6B zuqs&&t9_9L9p!6}X7}tKs46PA$uapi8o_!k23`K^D?TEbI3On1LCh%_5=g7m@6h^s zE1c<)os%5}+le+{PNBEB+)*^|e)FArF=OSFaYC7d zZ{fp>t(1mxefL1ol$S(HQ-D7b7fLBQ$=+;y7PWT6>Gn7(UoH#j;+F|c0N_p z@0w^=u~myxR@TZp6Djr&_zhJ@Gpdg0+q|X~*ZA4j6V&G0PNq_ zP(aFhBW)?W8D=p{tN|lK%Dz0-q3rCTLRrgkma>qP1Z69;Q1(iTP$pRpW!1=XD67Qy z6^)D+n)t7;_~7tjP4th+bjZ_fc+g^ zeAnZS!`_0S5BcI%xS}t`ns;K0Pu4_-5**iQ2D-ume4w!2cW>IASpByE&+piafnpvR zbPh8D-wzop!H@YEVSdL)M}gQBUTqRnvx>%e^MnpuRUQxf95>Xl&%$Fo`m>q%N?g&S z{_KfR&&q)bX=)XutKJc6C1ye_wRD`Ql~Vqdg-(;ldz%!>&Xp#oY@xgJUmq!BB9pSh z^mb#2iy4%OOp3CJkg+`dP0F6RSSXtY%JNLO+whYSymSLs4f^caUmUxpexiW<{|M*b@_GLcE+&FKma zL%SI?icCtk0>~K0(vLUNOYy)Px8S5HakQh~xT9Q}uEmw89BLb0e52BIHdcQ02WhHK z*Xmh}KZ${m(2SHSvzXCa4rNF>Wj}eka4Q_xI)70=YxTl@c+;Sm9~V5=TsQM;GYwacdx4HJn{Bk4dz3@s&KcSr zB-)kp+kb)b-9@`{YWH@!c2`r04%ALEQrexxj0BcJQq6NqMW8&LyMf+pqg^LgyV4;p zcX#6oUe1-zzLejBR*<50U!`le>MJNQ5!srN((V;zoP-Qd2bdzt`YVofxY;t;ZG8u6 z{kCxFZNB1>_&3e(@oa2q{jceIj6`!@zfZ}eRO$yAkf8z9jGc0;b2D!15mxC{>xMYG zU6i5Qb-03ecJ-TTle>_aDl*gKzO*r5;aU(-glx@7sqs%{9D$6ix_p+>Wt^+ahl5<6 zzQdJh@Sbq#J@BEgx1uihP?!DFbvb}dHX>UyQo8KGjAxPIvC<0s1QTlpJ4~FF(fVX* zeKx=SLMzQqvyzO9!_xJ5?8|g3rDRen-3*zm%!IHaYOFNe)s1`E(g*MNa3vaiFkJc| zn0Y&o%sfbDE=bp?J6cQ3L$+q5)c9=;GVVi0R$ZP->9TN;!_z?-x*RXMRP&AAK>2Xd zrJA~2o32X*o7|haNJdJR$;{X;rAw@c2Z?Fa-o|FSPip(KZRB`u}1D8lQ_q$5o zc(}{fUATg?$-|{jgRT2_F>9=a!9K=HpeAW)j7vsJ$pU8J zJMZ2u@jiYUUSe_wrX97w_`&;!I9iR&(CR|bYB`T(4V2%A>X4#V)#+NzS&hcerB;%W z(&|=b4D+Z_Sb+Tx^3izGhnvW78;**eDZU`&#)^`+p|Qd~M$!FTMduvk(pQHo(cqim z(l?>#2T%YhD!MRT(M_K~pO=xX87W1-V8+AvZTU)0&trxC@EUM=gGWW!oS!H#-3mWe zB})|+U?VcVVZNofQ@C{1mXh7@U4)J$+wiOAa>Xa>A(m1uBnxO6Rcvfy88 z?)yhtK>gw)=-6GarZoQ#u6mcKX3=S3Ygws^=G*n_k&JYWk!IwAW+vmQWUEQ)V(MaVisvfFbKrmQ+B|LL1`n(EUi6)PQ&6B(3$d$kq zA9F|AUg}@}q03v+s_!>0{wXEF$LuV8tp8B>kSvFf_mHLL`X4s+rH(^ypFXU2$${vRd{73@;vXMAnX$+1 zY40q&Hd|Q}-5l1AfNpq|JMo=*QT_oA3p4lgxIbMv{t&K2gRMMIxOg|1nReveW*(Le zJv%Kv`+%VNLaVV)vr;=1d}PzUZRS&n%QMHXHNkj|LRNpTPpyP-K^yq0M$G}b;q+g^+`m_@RzHj0|!9ypMzPivEIgGx00V zu~HH^$7I3z-}eNkWH~rrL>6#0;{5#2Z0!w!{xc7T2ebQ1zHSNEk7$D6K1 zC6JP{YRqBh37n=U1j+{)xX-#Nwa*$!v!R%$KU}mT>fLRf(-6wRJ7W#o#Bw8(u+fxz zN-=n;HRQ+<%ffD z9A_2BiSlnEoVDa&>1rKjSE4;EvI6%E(5Q>?0s72lXlH%qf=cT%>y6g*nWg<41cQJ8 zdmmO%Mtx>)DG8sc&EhlnWAhJ!mSj0Ta}%<>J~J7NKfA;u#1 zq30Zp>v2UMD6i2nwR<~E9JrS-(Lgz6Vpl0$a=px}w#L7mr{Y+PwST?qebibI5ywZ( zvArESjmFzcvgaKh#trXyt10T;>rQR!L{Izwq~&Q3qGd9v?)UQB!s$H2 z4>_HSwB@uj0=9`p_ZS&^)}*~0K0n7u3(uND8Rhe>TUipG)rJ<`;jj?R!m}jH@vOeo z2z|jJ$daZjC^-#Mvg81m1TBuP#@FXg;L%?zVPMu? zUj|q41cU0elJf+{6`t95aK~dTPxmEZXxb&WN5{odOHv=-%TL?LFfwcY$@3e z#J85W3-JYHIS^MV#8vG;EJFz#xt{1JSOlVM$ukhQk<0$Gja3NoB&03G=ff7_(ME<4 zySfmgy9&geQV^#~NkHtE#ZkX)6o``LIO^NT0>lQ+@4NPudl`IoFWA5ddB-%BnJt+wLrv{g)U31bi;i7I4GO7Vsz|L%_T5=Gb)hE&{ke zWz?p(NXd2p|N2I|fImZ467cRAy)lVN2fSJVuWkqM!zdpMu1*Zc^Bk!sy`SzQm;KWW z00O=oX$$!685Zz4Muva~?CJo1d}jeXkTME*mXrkGNm(qM2dxltCCjn!cUTim0v@nu zI^Y~yxLE-=1F)2LEc^`0<0ddMTAn zzqFG8KAtiPc&?Oe2XGH))ehj_m!$w7gXxIZ!UA}$0$$q=;6*5p34UTcmpj=t(p@?v zm;Lt|00ew1(iZS{H(9{f8yNyVX=exU>%9c<8I)1LFG@)O&dXxqy`U8UOO|8dt&s&q zy@O3$A;tkwN;o$C=rux&CuZpS0|y(~duqbe#ky4aqEVR;A4l3k?2>|bpOGQN%XV@g zuIVWduc3@WTsfWOv;*-tXw?qHe#mkl%I!FA5Zi(H^HM@wmv~ra`Vxs{d#-_av)%x# zG%6F~GNdiUy+u)(@6I-Nk`DsaP+~a%j(^M*KQE zZzw!ICDl0WudY|0s?sR;meGnRmLP3W^hu$3-pCL|WCw@k-@6HlO3En9-(F`zz_ctV z&PDS;Az2QJW0CdhIH(n`fSp3JAk1?lxGJC@9d9nyWqfn^-3$a`8c8a1)&hQ7EKZhq zqJwlqRI{|6b&Cn{nr!%soKWQ7#amT$2!)sCgxBZDwGO=2WkQq}JA~JFkc+t@DA#hs z>vN+UmLxhx{~d~c_+#j)P;^stL->na6zilC{Mi9NJDXbgJBQiY5*(|!(Z}xrg3KaA zCdnU$v?c%XY1V}fH8LbWue(G3OKS4c^?P)!!{n-MWUzGOM%zm6>G#swJI z0Y5M$&M)DjgC1LtRTvyzk5w2RTi+Su1DTha9OiF8O}t}0P=d15SZLozo+=9CVq@XB z&!C|+*;rPE2DfIT)PM&bMT^j-k@gp$mU`Gw^ciGJmlfjrx2X!I;AhXY3aSPq+xPPx z#A4bw&otxbm~StCYAVQSQzsk*i8*i2iX(p`ZG)nyyaT!Al-}%9pszs9S1oN z4~3oNfL6bF&4!dLD&JSIeAVThiMoS7IR~ctk&* z^K_X00?0kUkV|9ifwVP7TeK*X$+~yF~(Tb!%5v{i4y*i)Xa3KLZmIiIagbR1B?t2 z=DG-P*hUa;lR|ijlmx=&EC^S>BnTzTLAV524#M*QBGW< zE+uT!nDr8*t?qA5vAUmSWN6m?UESw)5#0|<>3)}#gjuJcMK@0RsU~KJ%yP{7?R;Za zm|=g6pn7ZNxq*~IPEcHcLcD?Or}z7h8TDw2`;oSA{+Mjx+-hV9=e(^QQ@p>Gz?nc9 z4T`TxNx-Sd0_Siv4>*$Lz}eZrN!?n>^K-qmYLcUFcx&akb(C5heDA+Ve65L)2K{Hd zIQsU5zTywi_Em&BUwjCzm`759^7Xia$5I_iuuVjt-*-xWn7pW&CCxCrEA(!;=KqsM5y4HPH7|%y|I?5}Czyq_ zb%M4ltP@0x44vSttsGKUb`~eNfHLX?^->Z}Pym>&PalM4;RKT9IKhsh5r-0Nb1>2P zVAPe2Rfxv;niOWMeAs>#B0jsfROG~}x1N_+mEe3*tmdx<>=14~S`NYQX3i>jq-rI< zaLcD>{Bk`{w%hV9ZcOC91bbOkE_uhoB6!R_W2sby{T44_>jL<=!0l_XZdQn=#q;IKTlv%$g$oQG!H;x(fr;m}m!gALY<2^-pVNPs<;-S3Ko%H&+q6K9UPIbyv{y=_7mW-xn%T+GXmhS;bO&Wr zqji@O3pA?AVv+MzBgt|sGE6k$nb5l3XgumkJ^?>mo`4U~C*Uy*1GI)z;#gzLv!=@? zj_33Y-+wX+6W|)8Ex@3tDbw|LjSK-k=63+@ssNv*i~`&`39umx!0Au`luMQa@FHZP zr!0?^4MR8!H{^t7*JE%&wTL5!Cs3x4U@LxN2ukASqOA&n%LB5g@-o@D*{3L`_3hvqsY*LDyuI)O4u z@?%mGUX<+(^HOQwB!P9 zv+dRc@Tnop(qJLd=)cRrAnaR^uFp5!IRVB@IJ?%!a6`a|jt=Z4IRg7s$|&sTq@-*J zKntUrF$1w10$6+f09eFxzZ!t1vLPV5^dw5d#mq4F#Z%HJJ~nz#@Bbog^*$)2cfFCJ zx$f%V=)INdeLrPX?_VaEPJb6#bceA^(JcCeWI27}WYLH|-x$9OJFInT=2^j$LeA7> zClr!ZVHvXgTYKPafvOhHg`$*n@$U@;!g(#nfiu`AX7~?f6i&Y+oSH0f9(YpVNR|Vq z3|aITJLN$t+=io4_2Qpy8jJac1lMum=2<2Q7{!=sTu+R|U{K{~W_d6lP` z#EUiy)-T9`Vm(?)W*m*oit8ugA5UMKQv>AgDdQq|7X<;pbhGOrh}N$$OjFy5NLy`J zTx7L9)5y>=`?}ix>krZPkd(GnQWBP#NBwrcI!(Wh)DK7ZG0U+`{Bf}iHqXg9)XB|r z+=PQ~=cS)wE#)0+)u4RRT5(uwoD8n)w#jw7s;beU=vO!uJ|DNTZ7^yZ?UE06Ls9=( zn_&mM?|?rxmX3p5jqJ9H1@Sl7FrhJs6#-0|Frkvax>B9u)?n;b=#);2$XlCN$j z%E^&eKRy-d3J9Y02}Tn-!`VpJvrbhoM9tctj~KYO~0QX6=#sF-I$fq=o4hY@HM{T)Fv!X z%#kAfSOkyu4Tu^PVaz#RZWe&_$lyJmL{!6%!EXPM) zMwSMowC9N;>hz7)<-HKOcX^g4IaE(~39)U>aVQ44Eci79tSh zmbxSv0Av2a1{Zla0O|S$6D#gK*YdENkzr)p)aLMT)h6L#)326?Go_>qa}CgBxruD7 zxW0n^3?rGozUZG|g~MEiU;_mqX9VwtAX>kTtsury+cKoBwqKrOwVh&QXtj~9wy*sv z+Kx*K%~L3DMwYa~nmon`$ftpkhL9283w_0wG_Hw1xaO;)j8J zj*%hcfj>KtpZi5152TDjo+Tv#xiAalJcTS-4&?71PJ`UlSsIlh4&;R>!pQYKj0sT9 zfZQbs8Icgn6R|F#DE>V)k3BmXzQP6sK~F{6g8uj{3wolFA?V|NazHQqSwJ6083kP} zCEE#K-Jm8qLbmYL_R!xBUvEK_;VW%3%8YeB8Z^2XJGcTE7>koDHl_((6ToD44l-9^#u3=4@8lQ<)?fG z&g8y<$|@sMPzZF$Y-(Y?wD=2_hPn437NIK1{vDXPw|Jp{(?%thhFFhueYJ_7r;M?N z_{_-A5DR~F3~|s;taXQllu<+UkdiROxGdgx>w{tl$#T4JGP10iA-Ifk7*j@L@|q^U zg83Y(#e77kj4d39qjF9?$Q&SK7RJ|}DnoDjL9sU>u5$pEww;N|j}Mqgofw2k7_>07 zCUldk;m#L$3IA_c(wrAvYBhxs8*(&btCbU?kt?A?;AQzEVQxN%4!7k6%Fpb`1Wrtj zVI^xqqZo_f!E2aKf$}58Fy4zOYpgZWuup3hB5kcT=L~DD0Y-+_+U5txTHznXTH8=Y zt#yf%gteAuvDWJQ#afc(SZfKgtnPnet(~6nSnDW^|FG6TdZIa2zN9dI_$g|wb8y+7 zKl=`+2C$a2?N}>_w#EDjQt7eQjrvnPordA8GE&Uu(rC^LMD}z=J7M&K`L2d=qEpI3 zjAmYAbj@a=?$$z2ZcxT)p@)&S7RniIEp)q)p@lAObu9G72C>kklu-*cp3ai6&_Gb> z&fN$9Lo6g&j)i(7%j*6o7K(W-^gy*(s8B7$KR#IKo|Dx=c-XVTcs}R58drSODQWC`1WFdaZeL}osImADPEQ>7^)vK^YVku|Rk+|M*Idimw@|6iveKScLzAqS7;!B5Bv5 zXu~W+Q44k@CEbLAyE^j4cHSO8{f^A_+Qx?t=`N#vu|K{JhO(6fc+0M# z@D*`BqrfE}o?pauND4O>qR<{_0t;H)`Xt$WUp)M6PAF$3q;UHGYx>ObyLD<-y1^Gn z*O!^ez_23g2JaXdy1_FojvMs(PTb%b%BUN3k&tUN=~S5ghEb0%@zSRNtVM`NLL%o>(CauR&Ln z*J))QQ{T{+lhY;5`FI$XgNcr0b)Y}hbM6zGjhCO$w$18js*_^yDKSHAbZe-#Y{uvt z(e<|2i)0rW?tMLJZUW7EqlEjS+Op|ShC?}WgLJ0hker{0bbX=W{Mk{K^C3otocBn8 zTiAjt*|KnFGQ@IX+`+OmAy`hNjAE&glEBiM1aMyW|_uc0@|s$E743AlusZPSmfLW;qV9<#q`m7;Ct;z0!Tb zINRFxn<&CKf-m$E%wnS)!90(&1=BqR=ATA}U`oGosNeXtfGMSnQvdM@qyb>^pUa#! zj6(AOBUuiZg9*kwc(0_#$WeRt(j+S9Z`UOY>_~y{-x!?a0G-n^u@x{{^F0L<9tB`2j0X+wJn@DVZwyy@?XAPvZ+IK`I5HY(Rcde!CtswfQ`ZJ zN%mhFUAd&WL(a;ahUg0Za0_u02-c>+D5Ei}X}K&m>i56hWTxa_HtB6lKc9VCXvVrY zVMiB_;anoRK<4^U{qT2GJ_GJuVvBQ$Erv)n-W&Kd$2egUU9@%&k&>zn84v&!v*wyQsEWY~GGZ&rCb zIoa@qboJ{gqn+o&VI~A-TR$5SmCloG{p>(wL1(#jmwu4t%jg;FXHQ|^4)GK4JbJfe zaQw+*bj)9g7#D4fpNK%tIGJtD?A40oO{IRTG|5)tb}V$IDPnZOtuUSyYoB~@BR8-F z%C}V-uQ9YR22DiT(zxO{OXHbFhBO}XxkKZV%|hcLlu;V1q$Ea?Nm*i0N9c|iBw0=j ziqE9>S-7iv3>Ddh$E!J>^Qj+C<^^$A9j(Nz!kGpjt}Dhd5+^M<1I#UGLGQ-L>%xX{ z!o+A@%9volk&LsEwqz_m){-&8$dHV^K6A);=yM@sFUlwxVJQhR>a&pX^DRP#WI1Gf zf-H2M>QLn@uKk!{^{b-@4!4qga0Kin_>F}&Y+nvG0sD@K{=_a7I@oVTg^GQWSUy+* zr)W0yo+Z!X{1Xfw!H;wb|IieEBO~}fb@6|u_$g!XOG)5w%7#B8_$AB5kE~&_N@5?T zUucOf=3+vu@^bzwYq*tTa$^4%b#ERYRgtxiH%mi6wBr&5afylwuDBowE{W1kqo8rY zZCs+FqJknOBcf<9$(Xh$8hu40ipD+eQ4vFwCLof?AO;tViWn8OV^HG;QBi)+b57m5 zo#JNZo%i>Ce&65s4@h;@sk-NR>eQ*_)~%8?#?j@KlX`byJY#`!EY7mZ9vvS$sQ>8r z=s}tB8wO>>`whyCe;AE7&!47#L%2z0p$iAWct6gSf#Ip`j!=SE<2VHn{PJ;1uxRWM zJOmm`A#Htq2gXrL`ntqvFxJ>i-h>qTt2$ZiM#-_0Fnm}6H;f4xds2>ls7yO{TZvD_ zzNpnoI4fvA!pVB$^mfXz74)Q$VFi_b>{QUk)lxyFl+g>tsIV1eIeO)$8Fn*~d70dMQ;F4*c1&SMERNh&UmWe|R#IPp zm!RzIwyU7PMI77XAC@BzUp)1V&7!W!l;sndR+rQl{8eUbL0jCbbki25de>R)?5_>nTWyoKrUD39t1gUPVUIXv=53Uv+=mJ7yqx%1PM57 z_<#2yReT7b8ap@-4*}{k3~DlU0>YN5=in8<6u+VzWn|de-fnhSTCCfFcA$*1R3JIw z4!3*>*mlN$Y1qCllGY|khcL<4XgQL^>C2R{+MO~=mKrKxjU6jFjw) zjs=T=-3y~A7zIq3sDESm`j@vgGCn77O#BDE2N|RA6@Z(74EIj5vQn8?OMI8kd+j9P+5(Feb z8IT)qBt9jB?Vg9e2{W-#(JI_9rd>2+&P-1}6Umv8(rf(W{Pg5}B=?V$p5Z4?Oi!MO ziGgJ5gm#Z1^Ly$>S01PcSaYo$AE}%v`<^# ziniYNwmYtl0yF>MA3iXMlrDmy>1BA*?U>$R<~r%};xo$Pg(cq0wz$017^_#mp($3% zV;iDX<}b5Ajd1gOeg!Q@I2kgI`oIykf?hK+S3o|`glz>Kt9zCz8Lt)e%WyINBV&n| zr*RlHt^^3mFzDvc$~a%V=iwNV4@+jx?c|`2y8%@=>c5*gpP7k87)kX(W@y>nXi2kM z|85$pvqU#>s$U_Vrb)A#Zo(GTF}rJ#1dmu2 zD#*kwS=|bTW7bMqT<qnng5{}$bjS*-f3PO9nG2#_D?GIH;FWdUp z3_+e@kP!LCchZobf0(V$b%^(n7n!g{jt}JM%o-W5$oG_-XmIrb$SbD{a!GQK&p;9e zsRT<)F2_-l-UpQP-l9i0*Eh@tCcVg^LeMQoBYOd^mj)u`I*n{kl*E0N?w#>bIb%hGQ*{gaU2!`&C5 z0(^yu|M3+jr_b-gg%he2=s^7o3gp3oFZ2g|VEs5==MLalk*f%*uR zB4E!Qj8~}RB`2U31wd`QR-j6f1NB)Xb%u(eq>P^Ly@o(>5eQb>0TllODCf%Gz=;y5 z6z2dv55+;MwNV@HNk(x3Jr-dL^znl&&_j$2fi|pgfY#~epNJ21lH>%?>Hwgh{!M^N zk^^)Jk}S|XD1-&1@^MwU^S6f~>yWB$R|JzBPjRAh(PP9fH^E?l#4k^A z@#85xKd=#v9(YbNcmzMfKK_Gz{6Pt+^lX}=-qglMLT!;-Q2@0?ptb<&CU{9{zAVszdJPIhC*JxA8oRK`wXr94Ip_?7 zgSbyX*y4U}sKq_X$PoA2%N^W{bxY9>lu_ITk`uT`1mOOh}moiGmrIHh56bF#;(KSMbBspX(L=uLERZy`S z3j>joUx6G4Qm_pqqA7rrTuzT2M=qqc{sadI{iYlJi04X#EuNJJSUl$$8RGeInSotccqGZe^Zit+k2MnhN!#fxvJQ&ZA(`B12XaJ z$d)&;bCYLOz8{sLg>zPIMsoBE6v~soiScC!PtowKDKf&(n}*uIsZmXt)^ZKP)>>BW zYfb+mBSUN1(BPQNB9x!YT~AQ!icGsU9lLh~R#S4o^3rNWzr} zTM|}65wo~+o{^FEztkb&%QorMMp8yexJPn=gbdWDI}hm#RncT5$sytUD?Jjv+>a#a z%(l~O^CQr2kOax@kWho{nE!GknklV2fiIAFI+EI6K0m9LIroM>(80_LDJ&xBixravDegaeuNzc_!|a z2wU8TiuN)|USwp5d%OwTSwu{CE6riN;{I)K4|hNdojj?_7J3Sjw1u9D61=l6ITPvHJ3d&4H_&FuRFm{j1L%lj5qba zr_}#0bu21*EdEPtkdrURn(H61Jxx8IsWe5=EOio7KUK>-);x)pIUHfD*=#9aDrj#b z!wPzJks`60J*PX5dia{yTwp0H>ho={xhKS_mYO54fa zBRx%HKRHcfFEltLY=D1ebxC246TLzUD`8KYl6Z%oa?Z&B72T299`Ll&e4)uEqqDhF<$lib9b@*fpxRFsQGYb#jeI<;qxV_wzEd3QzLm3-1!qkk!_@` z|GH%#$Z}wQwoWew8m)*Tg0Mv~RdkVdvMH%ZiQ+yJwkT%nyQ7a8uP8=%DB1&1JPrQ| z6q4kis6f)fZ1~^QDli!1Yar=)v2-mbD~w1Tuydyo`P=ZAY$sCK4t1Si9*e>_BELpQ z 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

_r~6t;XrA@$q{9SO7Se?b*NuK^bB{iOZ_he_*~x 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%0DyIv{M@mwJ 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 J<` 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%0A;25PYPSjfuS+l~d7X?)0gBB>L%86TH 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

7Zr=^iheQg&u=|t-4zE)GWlft#a6MD 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%0Du4?Q24vhZbQqXPjlD19G7Rq^> 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 literal 0 HcmV?d00001 diff --git a/plat/diameter/doc/single_host/freeDiameter-1.conf b/plat/diameter/doc/single_host/freeDiameter-1.conf new file mode 100644 index 0000000..3890e02 --- /dev/null +++ b/plat/diameter/doc/single_host/freeDiameter-1.conf @@ -0,0 +1,16 @@ + +# -------- Test configuration --------- + +Identity = "peer1.localdomain"; +Realm = "localdomain"; +Port = 3868; +SecPort = 3869; + +TLS_Cred = "./cacert.pem", + "./cakey.pem"; +TLS_CA = "./cacert.pem"; + +#LoadExtension = "extensions/test_app.fdx" : "test_app1.conf"; + +ConnectPeer = "peer2.localdomain" { ConnectTo = "127.0.0.1"; No_TLS; port = 30868; }; + diff --git a/plat/diameter/doc/single_host/freeDiameter-2.conf b/plat/diameter/doc/single_host/freeDiameter-2.conf new file mode 100644 index 0000000..5d57493 --- /dev/null +++ b/plat/diameter/doc/single_host/freeDiameter-2.conf @@ -0,0 +1,15 @@ +# -------- Test configuration --------- + +Identity = "peer2.localdomain"; +Realm = "localdomain"; +Port = 30868; +SecPort = 30869; + +TLS_Cred = "peer2.cert.pem", + "peer2.key.pem"; +TLS_CA = "cacert.pem"; + +LoadExtension = "extensions/test_app.fdx" : "test_app2.conf"; + +ConnectPeer = "peer1.localdomain" { ConnectTo = "127.0.0.1"; No_TLS; }; + diff --git a/plat/diameter/doc/single_host/make_certs.sh b/plat/diameter/doc/single_host/make_certs.sh new file mode 100644 index 0000000..7bda31f --- /dev/null +++ b/plat/diameter/doc/single_host/make_certs.sh @@ -0,0 +1,20 @@ +rm -rf demoCA +mkdir demoCA +echo 01 > demoCA/serial +touch demoCA/index.txt + + + +# CA self certificate +openssl req -new -batch -x509 -days 3650 -nodes -newkey rsa:1024 -out cacert.pem -keyout cakey.pem -subj /CN=ca.localdomain/C=FR/ST=BdR/L=Aix/O=fD/OU=Tests + +#peer1 +openssl genrsa -out peer1.key.pem 1024 +openssl req -new -batch -out peer1.csr.pem -key peer1.key.pem -subj /CN=peer1.localdomain/C=FR/ST=BdR/L=Aix/O=fD/OU=Tests +openssl ca -cert cacert.pem -keyfile cakey.pem -in peer1.csr.pem -out peer1.cert.pem -outdir . -batch + +#peer2 +openssl genrsa -out peer2.key.pem 1024 +openssl req -new -batch -out peer2.csr.pem -key peer2.key.pem -subj /CN=peer2.localdomain/C=FR/ST=BdR/L=Aix/O=fD/OU=Tests +openssl ca -cert cacert.pem -keyfile cakey.pem -in peer2.csr.pem -out peer2.cert.pem -outdir . -batch + diff --git a/plat/diameter/doc/single_host/test_app1.conf b/plat/diameter/doc/single_host/test_app1.conf new file mode 100644 index 0000000..e69de29 diff --git a/plat/diameter/doc/single_host/test_app2.conf b/plat/diameter/doc/single_host/test_app2.conf new file mode 100644 index 0000000..e69de29 diff --git a/plat/diameter/doc/test_app.conf.sample b/plat/diameter/doc/test_app.conf.sample new file mode 100644 index 0000000..3b28884 --- /dev/null +++ b/plat/diameter/doc/test_app.conf.sample @@ -0,0 +1,74 @@ +####################### +# This file contains the description of configuration and general information about the +# "test_app" extension. + +# This extension provides a simple way to send a predefined message over the Diameter Network. +# It may be used to test the Routing or other base mechanisms from the Diameter network. + +# In order to enable this extension, the main freeDiameter configuration file +# must contain the following declaration: +# LoadExtension = "extensions/app_test.fdx" : "/path/to/app_test.conf" ; +# Note that the conffile may be omitted, in which case default parameters will be assumed. +####################### + + +####################### +# Configuration of the test message + +# This application is defined as a Vendor-Specific application. +# Since freeDiameter does not have a IANA-assigned Vendor ID, we let a configurable value here: +# vendor-id = 999999; + +# The application id. Same remark as previously. +# appli-id = 999999; + +# The command code for Test-Request and Test-Answer. The range 0xfffffe-ffffff (dec: 16777215) is reserved for experimental use. +# cmd-id = 16777214; + +# The AVP id for the test. +# avp-id = 345678; + +# Another AVP id for long payload test. default to value 0, meaning this is not used. +# long-avp-id = 0; + +# Define the payload length of the long-avp. Default 5000 bytes. +# long-avp-len = 5000; + + +####################### +# Configuration of the extension behavior + +# The mode for the extension. +# - server: Answer incoming requests. The signal is ignored. +# - client: Send a request when the signal is received, and measure the time to receiving answer. +# - both: acts as client and server +# mode = both; + +# The behavior can be changed by specifying additional "benchmark;" keyword. +# When this keyword appears, it changes the behavior as follow: +# - server is silent on message reception, only the activity summary is displayed every 30 seconds +# - client attempts to send as many messages as possible during 10 seconds and counts them. +# The benchmark keyword can be followed optionally by two integers: +# duration is the time for the measurement, in seconds (default 10). +# concurrency is the number of messages that can be on the wire before waiting for an answer (default 100). +# benchmark [duration concurrency]; + + +####################### +# Client-specific configuration + +# The Destination-Realm for the message +# (default is sending to same realm as local peer). +# dest-realm = "foreign.net"; + +# The Destination-Host for the message. +# (default is not providing this AVP). +# dest-host = "server.foreign.net"; + +# The User-Name for the message (may be useful for some routing tests). +# (default is not providing this AVP). +# user-name = "user@server.foreign.net"; + +# The signal that triggers sending the test message +# Note: Symbolic names are not recognized, you must use integers +# signal = 10; diff --git a/plat/diameter/doc/test_netemul.conf.sample b/plat/diameter/doc/test_netemul.conf.sample new file mode 100644 index 0000000..484899c --- /dev/null +++ b/plat/diameter/doc/test_netemul.conf.sample @@ -0,0 +1,59 @@ +# This file contains information for configuring the test_netemul extension. +# To find how to have freeDiameter load this extension, please refer to the freeDiameter documentation. +# +# The test_netemul extension implements a Diameter proxy that behaves like simple forwarding agent, +# with the exception that it can introduce delay in the forwarding of the messages and generate duplicates +# of messages, as can be expected from a real Diameter network. It can also generate routing errors when +# connected to more than 2 peers. + + +# LATENCY: +# Two parameters are used to control the delay introduced in the messages. +# - latency_average: +# This is the average delay introduced in the packets. +# Set to 0 to not add any latency (beyond the normal processing time). +# The value is expressed as an integer followed by a unit which can +# be 's' (seconds) or 'ms' (milliseconds). Example: +# latency_average = 700 ms; +# +# - latency_deviation: +# This parameter controls the variance in the latency. It is expressed +# as a value between 0 % and 100 %. When set to 0 %, all messages will be delayed +# by exactly latency_average. Otherwise, it represents the width of the interval +# "around" the average where "most" of the latency will be chosen (the distribution +# has a Gaussian shape). Example: +# latency_deviation = 25 %; +# +# The default values give an added latency "mostly" between 0.4 and 0.6 seconds: +# latency_average = 500 ms; +# latency_deviation = 20 % ; + + +# REORDERING: +# There is no special control over the reordering of messages. It may simply happen +# as a result of the latency. If you want to get a lot of reordering, set the +# latency_variance to a high value. + + +# DUPLICATES: +# Duplicate messages are expected in the Diameter protocol by design, as a consequence +# of the failover mechanism that provides the protocol's reliability. +# - dupl_proba: +# This value gives the probability of producing a duplicate of a forwarded message. +# The value is comprized between 0 (no duplicates) and 1 (duplicate all messages). +# Duplicates are created for requests, but may result in duplicate answers +# received by your Diameter client(s), depending on your server(s)'s behavior. +# In the case of freeDiameter client, the duplicate answer is automatically filtered out +# because the hop-by-hop id has already been used. +# Note that each duplicate copy is an independent message, +# which receives a different latency, and might be routed to a different server if you +# use for example load-balancing. +# The parameter can take several forms: +# dupl_proba = 0 ; +# Disables the generation of duplicate messages completely. +# dupl_proba = 1 / 10000 ; +# dupl_proba = 0.0001 ; +# Around 1 messages over ten thousands will be duplicated. +# +# Default value: +# dupl_proba = 1 / 100 ; diff --git a/plat/diameter/doc/test_sip.conf.sample b/plat/diameter/doc/test_sip.conf.sample new file mode 100644 index 0000000..10fc31d --- /dev/null +++ b/plat/diameter/doc/test_sip.conf.sample @@ -0,0 +1,8 @@ +#User configuration +username = "awestfahl" +password = "test" +sip_aor = "sip:awestfahl@tera.ics.keio.ac.jp" + +#Destination information +destination_realm = "freediameter.net" +destination_sip = "sip:awestfahl@freediameter.net" diff --git a/plat/diameter/extensions/sh_app/dict_dcca.c b/plat/diameter/extensions/sh_app/dict_dcca.c new file mode 100644 index 0000000..681d07b --- /dev/null +++ b/plat/diameter/extensions/sh_app/dict_dcca.c @@ -0,0 +1,1559 @@ +/**************** + Contributed by: Konstantin Chekushin and Thomas Klausner + License: same as freeDiameter +****************/ + + +/* + * Dictionary definitions of objects specified in DCCA (rfc4006). + */ +#include "extension.h" + + +/* The content of this file follows the same structure as dict_base_proto.c */ + +#define CHECK_dict_new( _type, _data, _parent, _ref ) \ + CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) ); + +#define CHECK_dict_search( _type, _criteria, _what, _result ) \ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) ); + +struct local_rules_definition { + char *avp_name; + enum rule_position position; + int min; + int max; +}; + +#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 ) + +#define PARSE_loc_rules( _rulearray, _parent) { \ + int __ar; \ + for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \ + struct dict_rule_data __data = { NULL, \ + (_rulearray)[__ar].position, \ + 0, \ + (_rulearray)[__ar].min, \ + (_rulearray)[__ar].max}; \ + __data.rule_order = RULE_ORDER(__data.rule_position); \ + CHECK_FCT( fd_dict_search( \ + fd_g_config->cnf_dict, \ + DICT_AVP, \ + AVP_BY_NAME, \ + (_rulearray)[__ar].avp_name, \ + &__data.rule_avp, 0 ) ); \ + if ( !__data.rule_avp ) { \ + TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \ + return ENOENT; \ + } \ + CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \ + { \ + TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \ + (_rulearray)[__ar].avp_name ); \ + return EINVAL; \ + } ); \ + } \ + } + +#define enumval_def_u32( _val_, _str_ ) \ + { _str_, { .u32 = _val_ }} + +#define enumval_def_os( _len_, _val_, _str_ ) \ + { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}} + +struct dict_object * g_dict_dba; +struct dict_object * g_dict_dcca; +struct dict_object * g_dict_cxdx; + +extern int PARSE_loc_rules_(struct local_rules_definition _rulearray[], int len, struct dict_object *_parent); +int dict_dcca_entry(char * conffile) +{ + TRACE_ENTRY("%p", conffile); + + /* Applications section */ + { + /* DBA */ + { + struct dict_application_data data = { 3, "Diameter Base Accounting" }; + CHECK_dict_new( DICT_APPLICATION, &data, NULL, &g_dict_dba); + } + + /* DCCA */ + { + struct dict_application_data data = { 4, "Diameter Credit Control Application" }; + CHECK_dict_new( DICT_APPLICATION, &data, NULL, &g_dict_dcca); + } + /* CXDX */ + { + struct dict_application_data data = { 16777216, "CX/DX" }; + CHECK_dict_new( DICT_APPLICATION, &data, NULL, &g_dict_cxdx); + } + + } + + /* Result codes */ + { + struct dict_object *ResultCodeType; + CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated*(Result-Code)", &ResultCodeType); + + { + struct dict_enumval_data error_code = {"END_USER_SERVICE_DENIED", + { .u32 = 4010}}; + CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL); + } + { + struct dict_enumval_data error_code = {"CREDIT_CONTROL_NOT_APPLICABLE", + { .u32 = 4011}}; + CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL); + } + { + struct dict_enumval_data error_code = {"CREDIT_LIMIT_REACHED", + { .u32 = 4012}}; + CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL); + } + { + struct dict_enumval_data error_code = {"USER_UNKNOWN", + { .u32 = 5030}}; + CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL); + } + { + struct dict_enumval_data error_code = {"RATING_FAILED", + { .u32 = 5031}}; + CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL); + } + + } + + + + /* AVP section */ + { + struct dict_object * Address_type; + struct dict_object * UTF8String_type; + struct dict_object * DiameterIdentity_type; + struct dict_object * DiameterURI_type; + struct dict_object * Time_type; + struct dict_object * IPFilterRule_type; + + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type); + + + /* CC-Correlation-Id */ + { + /* + OctetString. + */ + struct dict_avp_data data = { + 411, /* Code */ + 0, /* Vendor */ + "CC-Correlation-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Input-Octets */ + { + /* + Unsigned64. + */ + struct dict_avp_data data = { + 412, /* Code */ + 0, /* Vendor */ + "CC-Input-Octets", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Output-Octets */ + { + /* + Unsigned64. + */ + struct dict_avp_data data = { + 414, /* Code */ + 0, /* Vendor */ + "CC-Output-Octets", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Request-Number */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 415, /* Code */ + 0, /* Vendor */ + "CC-Request-Number", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Request-Type */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Request-Type)", NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "INITIAL_REQUEST", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "UPDATE_REQUEST", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "TERMINATION_REQUEST", { .i32 = 3 }}; + struct dict_enumval_data t_4 = { "EVENT_REQUEST", { .i32 = 4 }}; + + + struct dict_avp_data data = { + 416, /* Code */ + 0, /* Vendor */ + "CC-Request-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + + /* CC-Service-Specific-Units */ + { + /* + Unsigned64. + */ + struct dict_avp_data data = { + 417, /* Code */ + 0, /* Vendor */ + "CC-Service-Specific-Units", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Session-Failover */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Session-Failover)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "FAILOVER_NOT_SUPPORTED", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "FAILOVER_SUPPORTED", { .i32 = 1 }}; + + + struct dict_avp_data data = { + 418, /* Code */ + 0, /* Vendor */ + "CC-Session-Failover", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* CC-Sub-Session-Id */ + { + /* + Unsigned64. + */ + struct dict_avp_data data = { + 419, /* Code */ + 0, /* Vendor */ + "CC-Sub-Session-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Time */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 420, /* Code */ + 0, /* Vendor */ + "CC-Time", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Total-Octets */ + { + /* + Unsigned64. + */ + struct dict_avp_data data = { + 421, /* Code */ + 0, /* Vendor */ + "CC-Total-Octets", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* CC-Unit-Type */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Unit-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "TIME", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "MONEY", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "TOTAL-OCTETS", { .i32 = 2 }}; + struct dict_enumval_data t_4 = { "INPUT-OCTETS", { .i32 = 3 }}; + struct dict_enumval_data t_5 = { "OUTPUT-OCTETS", { .i32 = 4 }}; + struct dict_enumval_data t_6 = { "SERVICE-SPECIFIC-UNITS", { .i32 = 5 }}; + + + struct dict_avp_data data = { + 454, /* Code */ + 0, /* Vendor */ + "CC-Unit-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_5 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_6 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Check-Balance-Result */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Check-Balance-Result)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "ENOUGH_CREDIT", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "NO_CREDIT", { .i32 = 1 }}; + + + struct dict_avp_data data = { + 422, /* Code */ + 0, /* Vendor */ + "Check-Balance-Result", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Cost-Unit */ + { + /* + UTF8String. + */ + struct dict_avp_data data = { + 424, /* Code */ + 0, /* Vendor */ + "Cost-Unit", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Credit-Control */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Credit-Control)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "CREDIT_AUTHORIZATION", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "RE_AUTHORIZATION", { .i32 = 1 }}; + + struct dict_avp_data data = { + 426, /* Code */ + 0, /* Vendor */ + "Credit-Control", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Credit-Control-Failure-Handling */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Credit-Control-Failure-Handling)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "TERMINATE", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "CONTINUE", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "RETRY_AND_TERMINATE", { .i32 = 2 }}; + + struct dict_avp_data data = { + 427, /* Code */ + 0, /* Vendor */ + "Credit-Control-Failure-Handling", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Currency-Code */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 425, /* Code */ + 0, /* Vendor */ + "Currency-Code", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Direct-Debiting-Failure-Handling */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Direct-Debiting-Failure-Handling)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "TERMINATE_OR_BUFFER", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "CONTINUE", { .i32 = 1 }}; + + struct dict_avp_data data = { + 428, /* Code */ + 0, /* Vendor */ + "Direct-Debiting-Failure-Handling", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Exponent */ + { + /* + Integer32. + */ + struct dict_avp_data data = { + 429, /* Code */ + 0, /* Vendor */ + "Exponent", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Final-Unit-Action */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Final-Unit-Action)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "TERMINATE", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "REDIRECT", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "RESTRICT_ACCESS", { .i32 = 2 }}; + + struct dict_avp_data data = { + 449, /* Code */ + 0, /* Vendor */ + "Final-Unit-Action", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* G-S-U-Pool-Identifier */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 453, /* Code */ + 0, /* Vendor */ + "G-S-U-Pool-Identifier", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Multiple-Services-Indicator */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Multiple-Services-Indicator)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "MULTIPLE_SERVICES_NOT_SUPPORTED", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "MULTIPLE_SERVICES_SUPPORTED", { .i32 = 1 }}; + + struct dict_avp_data data = { + 455, /* Code */ + 0, /* Vendor */ + "Multiple-Services-Indicator", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Rating-Group */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 432, /* Code */ + 0, /* Vendor */ + "Rating-Group", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Redirect-Address-Type */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Redirect-Address-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "IPV4_ADDRESS", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "IPV6_ADDRESS", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "URL", { .i32 = 2 }}; + struct dict_enumval_data t_4 = { "SIP_URI", { .i32 = 3 }}; + + struct dict_avp_data data = { + 433, /* Code */ + 0, /* Vendor */ + "Redirect-Address-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Redirect-Server-Address */ + { + /* + UTF8String. + */ + struct dict_avp_data data = { + 435, /* Code */ + 0, /* Vendor */ + "Redirect-Server-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Requested-Action */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Requested-Action)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "DIRECT_DEBITING", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "REFUND_ACCOUNT", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "CHECK_BALANCE", { .i32 = 2 }}; + struct dict_enumval_data t_4 = { "PRICE_ENQUIRY", { .i32 = 3 }}; + + struct dict_avp_data data = { + 436, /* Code */ + 0, /* Vendor */ + "Requested-Action", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Restriction-Filter-Rule */ + { + /* + IPFiltrRule. + */ + struct dict_avp_data data = { + 438, /* Code */ + 0, /* Vendor */ + "Restriction-Filter-Rule", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , IPFilterRule_type, NULL); + } + /*Service-Context-Id */ + { + /* + UTF8String. + */ + struct dict_avp_data data = { + 461, /* Code */ + 0, /* Vendor */ + "Service-Context-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Service-Identifier */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 439, /* Code */ + 0, /* Vendor */ + "Service-Identifier", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Service-Parameter-Type */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 441, /* Code */ + 0, /* Vendor */ + "Service-Parameter-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Service-Parameter-Value */ + { + /* + OctetString. + */ + struct dict_avp_data data = { + 442, /* Code */ + 0, /* Vendor */ + "Service-Parameter-Value", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Subscription-Id-Data */ + { + /* + UTF8String. + */ + struct dict_avp_data data = { + 444, /* Code */ + 0, /* Vendor */ + "Subscription-Id-Data", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Subscription-Id-Type */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Subscription-Id-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "END_USER_E164", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "END_USER_IMSI", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "END_USER_SIP_URI", { .i32 = 2 }}; + struct dict_enumval_data t_4 = { "END_USER_NAI", { .i32 = 3 }}; + + struct dict_avp_data data = { + 450, /* Code */ + 0, /* Vendor */ + "Subscription-Id-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Tariff-Change-Usage */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Tariff-Change-Usage)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "UNIT_BEFORE_TARIFF_CHANGE", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "UNIT_AFTER_TARIFF_CHANGE", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "UNIT_INDETERMINATE", { .i32 = 2 }}; + + struct dict_avp_data data = { + 452, /* Code */ + 0, /* Vendor */ + "Tariff-Change-Usage", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Tariff-Time-Change */ + { + /* + Time. + */ + struct dict_avp_data data = { + 451, /* Code */ + 0, /* Vendor */ + "Tariff-Time-Change", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , Time_type, NULL); + } + + /* User-Equipment-Info-Type */ + { + /* + Enumerated. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(User-Equipment-Info-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "IMEISV", { .i32 = 0 }}; + struct dict_enumval_data t_2 = { "MAC", { .i32 = 1 }}; + struct dict_enumval_data t_3 = { "EUI64", { .i32 = 2 }}; + + struct dict_avp_data data = { + 459, /* Code */ + 0, /* Vendor */ + "User-Equipment-Info-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* User-Equipment-Info-Value */ + { + /* + OctetString. + */ + struct dict_avp_data data = { + 460, /* Code */ + 0, /* Vendor */ + "User-Equipment-Info-Value", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Value-Digits */ + { + /* + Integer64. + */ + struct dict_avp_data data = { + 447, /* Code */ + 0, /* Vendor */ + "Value-Digits", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER64 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Validity-Time */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 448, /* Code */ + 0, /* Vendor */ + "Validity-Time", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Time-Quota-Threshold */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 868, /* Code */ + 10415, /* Vendor */ + "Time-Quota-Threshold", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + + /* Grouped AVPs below since they have dependencies on types above */ + + /* Redirect-Server */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 434, /* Code */ + 0, /* Vendor */ + "Redirect-Server", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Redirect-Address-Type", RULE_REQUIRED, -1, 1 }, + { "Redirect-Server-Address", RULE_REQUIRED, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Service-Parameter-Info */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 440, /* Code */ + 0, /* Vendor */ + "Service-Parameter-Info", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Service-Parameter-Type", RULE_REQUIRED, -1, 1 }, + { "Service-Parameter-Value", RULE_REQUIRED, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Subscription-Id */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 443, /* Code */ + 0, /* Vendor */ + "Subscription-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Subscription-Id-Type", RULE_REQUIRED, -1, 1 }, + { "Subscription-Id-Data", RULE_REQUIRED, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Unit-Value */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 445, /* Code */ + 0, /* Vendor */ + "Unit-Value", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Value-Digits", RULE_REQUIRED, -1, 1 }, + { "Exponent", RULE_OPTIONAL, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* User-Equipment-Info */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 458, /* Code */ + 0, /* Vendor */ + "User-Equipment-Info", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "User-Equipment-Info-Type", RULE_REQUIRED, -1, 1 }, + { "User-Equipment-Info-Value", RULE_REQUIRED, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* grouped AVPs using grouped AVPs */ + + /* CC-Money */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 413, /* Code */ + 0, /* Vendor */ + "CC-Money", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Unit-Value", RULE_REQUIRED, -1, 1 }, + { "Currency-Code", RULE_OPTIONAL, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Cost-Information */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 423, /* Code */ + 0, /* Vendor */ + "Cost-Information", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Unit-Value", RULE_REQUIRED, -1, 1 }, + { "Currency-Code", RULE_REQUIRED, -1, 1 }, + { "Cost-Unit", RULE_OPTIONAL, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Final-Unit-Indication */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 430, /* Code */ + 0, /* Vendor */ + "Final-Unit-Indication", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Final-Unit-Action", RULE_REQUIRED, -1, 1 }, + { "Restriction-Filter-Rule", RULE_OPTIONAL, -1, -1 }, + { "Filter-Id", RULE_OPTIONAL, -1, -1 }, + { "Redirect-Server", RULE_OPTIONAL, -1, 1 }, + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Granted-Service-Unit */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 431, /* Code */ + 0, /* Vendor */ + "Granted-Service-Unit", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Tariff-Time-Change", RULE_OPTIONAL, -1, 1 }, + { "CC-Time", RULE_OPTIONAL, -1, 1 }, + { "CC-Money", RULE_OPTIONAL, -1, 1 }, + { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 } + /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* G-S-U-Pool-Reference */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 457, /* Code */ + 0, /* Vendor */ + "G-S-U-Pool-Reference", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "G-S-U-Pool-Identifier", RULE_REQUIRED, -1, 1 }, + { "CC-Unit-Type", RULE_REQUIRED, -1, 1 }, + { "Unit-Value", RULE_REQUIRED, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Requested-Service-Unit */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 437, /* Code */ + 0, /* Vendor */ + "Requested-Service-Unit", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "CC-Time", RULE_OPTIONAL, -1, 1 }, + { "CC-Money", RULE_OPTIONAL, -1, 1 }, + { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 } + /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + /* Used-Service-Unit */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 446, /* Code */ + 0, /* Vendor */ + "Used-Service-Unit", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Tariff-Change-Usage", RULE_OPTIONAL, -1, 1 }, + { "CC-Time", RULE_OPTIONAL, -1, 1 }, + { "CC-Money", RULE_OPTIONAL, -1, 1 }, + { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 }, + { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 } + /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + + /* fj added 20170511. huawei expended */ + /* Volume-Quota-Threshold */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 869, /* Code */ + 10415, /* Vendor */ + "Volume-Quota-Threshold", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Quota-Holding-Time */ + { + /* + Unsigned32. + */ + struct dict_avp_data data = { + 871, /* Code */ + 10415, /* Vendor */ + "Quota-Holding-Time", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + + /* at least three levels of grouping */ + /* Multiple-Services-Credit-Control */ + { + /* + Grouped + */ + struct dict_object * avp; + struct dict_avp_data data = { + 456, /* Code */ + 0, /* Vendor */ + "Multiple-Services-Credit-Control", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = { + { "Granted-Service-Unit", RULE_OPTIONAL, -1, 1 }, + { "Requested-Service-Unit", RULE_OPTIONAL, -1, 1 }, + { "Used-Service-Unit", RULE_OPTIONAL, -1, -1 }, + { "Tariff-Change-Usage", RULE_OPTIONAL, -1, 1 }, + { "Service-Identifier", RULE_OPTIONAL, -1, -1 }, + { "Rating-Group", RULE_OPTIONAL, -1, 1 }, + { "G-S-U-Pool-Reference", RULE_OPTIONAL, -1, -1 }, + { "Validity-Time", RULE_OPTIONAL, -1, 1 }, + { "Result-Code", RULE_OPTIONAL, -1, 1 }, + { "Final-Unit-Indication", RULE_OPTIONAL, -1, 1 }, + { "Time-Quota-Threshold", RULE_OPTIONAL, -1, 1 }, + { "Volume-Quota-Threshold", RULE_OPTIONAL, -1, 1 }, + { "Quota-Holding-Time", RULE_OPTIONAL, -1, 1 }, + + /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + + } + + + /* Commands section */ + { + /* Credit-Control-Request (CCR) Command */ + { + /* + From RFC 4006: + + 3.1. Credit-Control-Request (CCR) Command + + The Credit-Control-Request message (CCR) is indicated by the + command-code field being set to 272 and the 'R' bit being set in the + Command Flags field. It is used between the Diameter credit-control + client and the credit-control server to request credit authorization + for a given service. + + The Auth-Application-Id MUST be set to the value 4, indicating the + Diameter credit-control application. + + Message Format + + ::= < Diameter Header: 272, REQ, PXY > + < Session-Id > + { Origin-Host } + { Origin-Realm } + { Destination-Realm } + { Auth-Application-Id } + { Service-Context-Id } + { CC-Request-Type } + { CC-Request-Number } + [ Destination-Host ] + [ User-Name ] + [ CC-Sub-Session-Id ] + [ Acct-Multi-Session-Id ] + [ Origin-State-Id ] + [ Event-Timestamp ] + *[ Subscription-Id ] + [ Service-Identifier ] + [ Termination-Cause ] + [ Requested-Service-Unit ] + [ Requested-Action ] + *[ Used-Service-Unit ] + [ Multiple-Services-Indicator ] + *[ Multiple-Services-Credit-Control ] + *[ Service-Parameter-Info ] + [ CC-Correlation-Id ] + [ User-Equipment-Info ] + *[ Proxy-Info ] + *[ Route-Record ] + *[ AVP ] + + 10.1. Credit-Control AVP Table + + The table in this section is used to represent which credit-control + applications specific AVPs defined in this document are to be present + in the credit-control messages. + + +-----------+ + | Command | + | Code | + |-----+-----+ + Attribute Name | CCR | CCA | + ------------------------------|-----+-----+ + Acct-Multi-Session-Id | 0-1 | 0-1 | + Auth-Application-Id | 1 | 1 | + CC-Correlation-Id | 0-1 | 0 | + CC-Session-Failover | 0 | 0-1 | + CC-Request-Number | 1 | 1 | + CC-Request-Type | 1 | 1 | + CC-Sub-Session-Id | 0-1 | 0-1 | + Check-Balance-Result | 0 | 0-1 | + Cost-Information | 0 | 0-1 | + Credit-Control-Failure- | 0 | 0-1 | + Handling | | | + Destination-Host | 0-1 | 0 | + Destination-Realm | 1 | 0 | + Direct-Debiting-Failure- | 0 | 0-1 | + Handling | | | + Event-Timestamp | 0-1 | 0-1 | + Failed-AVP | 0 | 0+ | + Final-Unit-Indication | 0 | 0-1 | + Granted-Service-Unit | 0 | 0-1 | + Multiple-Services-Credit- | 0+ | 0+ | + Control | | | + Multiple-Services-Indicator | 0-1 | 0 | + Origin-Host | 1 | 1 | + Origin-Realm | 1 | 1 | + Origin-State-Id | 0-1 | 0-1 | + Proxy-Info | 0+ | 0+ | + Redirect-Host | 0 | 0+ | + Redirect-Host-Usage | 0 | 0-1 | + Redirect-Max-Cache-Time | 0 | 0-1 | + Requested-Action | 0-1 | 0 | + Requested-Service-Unit | 0-1 | 0 | + Route-Record | 0+ | 0+ | + Result-Code | 0 | 1 | + Service-Context-Id | 1 | 0 | + Service-Identifier | 0-1 | 0 | + Service-Parameter-Info | 0+ | 0 | + Session-Id | 1 | 1 | + Subscription-Id | 0+ | 0 | + Termination-Cause | 0-1 | 0 | + User-Equipment-Info | 0-1 | 0 | + Used-Service-Unit | 0+ | 0 | + User-Name | 0-1 | 0-1 | + Validity-Time | 0 | 0-1 | + ------------------------------|-----+-----+ + + + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 272, /* Code */ + "Credit-Control-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { + { "Session-Id", RULE_FIXED_HEAD, -1, 1 }, + { "Origin-Host", RULE_REQUIRED, -1, 1 }, + { "Origin-Realm", RULE_REQUIRED, -1, 1 }, + { "Destination-Realm", RULE_REQUIRED, -1, 1 }, + { "Auth-Application-Id", RULE_REQUIRED, -1, 1 }, + { "Service-Context-Id", RULE_REQUIRED, -1, 1 }, + { "CC-Request-Type", RULE_REQUIRED, -1, 1 }, + { "CC-Request-Number", RULE_REQUIRED, -1, 1 }, + { "Destination-Host", RULE_OPTIONAL, -1, 1 }, + { "User-Name", RULE_OPTIONAL, -1, 1 }, + { "CC-Sub-Session-Id", RULE_OPTIONAL, -1, 1 }, + { "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 }, + { "Origin-State-Id", RULE_OPTIONAL, -1, 1 }, + { "Event-Timestamp", RULE_OPTIONAL, -1, 1 }, + { "Subscription-Id", RULE_OPTIONAL, -1, -1 }, + { "Service-Identifier", RULE_OPTIONAL, -1, 1 }, + { "Termination-Cause", RULE_OPTIONAL, -1, 1 }, + { "Requested-Service-Unit", RULE_OPTIONAL, -1, 1 }, + { "Requested-Action", RULE_OPTIONAL, -1, 1 }, + { "Used-Service-Unit", RULE_OPTIONAL, -1, -1 }, + { "Multiple-Services-Indicator", RULE_OPTIONAL, -1, 1 }, + { "Multiple-Services-Credit-Control", RULE_OPTIONAL, -1, -1 }, + { "Service-Parameter-Info", RULE_OPTIONAL, -1, -1 }, + { "CC-Correlation-Id", RULE_OPTIONAL, -1, 1 }, + { "User-Equipment-Info", RULE_OPTIONAL, -1, 1 }, + { "Proxy-Info", RULE_OPTIONAL, -1, -1 }, + { "Route-Record", RULE_OPTIONAL, -1, -1 }, + { "Service-Information", RULE_OPTIONAL, -1, 1 }, + /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */ + }; + + CHECK_dict_new( DICT_COMMAND, &data, g_dict_dcca, &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), cmd ); + } + + /* Credit-Control-Answer (CCA) Command */ + { + /* + From RFC 4006: + 3.2. Credit-Control-Answer (CCA) Command + + The Credit-Control-Answer message (CCA) is indicated by the command- + code field being set to 272 and the 'R' bit being cleared in the + Command Flags field. It is used between the credit-control server + and the Diameter credit-control client to acknowledge a Credit- + Control-Request command. + + Message Format + + ::= < Diameter Header: 272, PXY > + < Session-Id > + { Result-Code } + { Origin-Host } + { Origin-Realm } + { Auth-Application-Id } + { CC-Request-Type } + { CC-Request-Number } + [ User-Name ] + [ CC-Session-Failover ] + [ CC-Sub-Session-Id ] + [ Acct-Multi-Session-Id ] + [ Origin-State-Id ] + [ Event-Timestamp ] + [ Granted-Service-Unit ] + *[ Multiple-Services-Credit-Control ] + [ Cost-Information] + [ Final-Unit-Indication ] + [ Check-Balance-Result ] + [ Credit-Control-Failure-Handling ] + [ Direct-Debiting-Failure-Handling ] + [ Validity-Time] + *[ Redirect-Host] + [ Redirect-Host-Usage ] + [ Redirect-Max-Cache-Time ] + *[ Proxy-Info ] + *[ Route-Record ] + *[ Failed-AVP ] + *[ AVP ] + + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 272, /* Code */ + "Credit-Control-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { + { "Session-Id", RULE_FIXED_HEAD, -1, 1 }, + { "Result-Code", RULE_REQUIRED, -1, 1 }, + { "Origin-Host", RULE_REQUIRED, -1, 1 }, + { "Origin-Realm", RULE_REQUIRED, -1, 1 }, + { "Auth-Application-Id", RULE_REQUIRED, -1, 1 }, + { "CC-Request-Type", RULE_REQUIRED, -1, 1 }, + { "CC-Request-Number", RULE_REQUIRED, -1, 1 }, + { "User-Name", RULE_OPTIONAL, -1, 1 }, + { "CC-Session-Failover", RULE_OPTIONAL, -1, 1 }, + { "CC-Sub-Session-Id", RULE_OPTIONAL, -1, 1 }, + { "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 }, + { "Origin-State-Id", RULE_OPTIONAL, -1, 1 }, + { "Event-Timestamp", RULE_OPTIONAL, -1, 1 }, + { "Granted-Service-Unit", RULE_OPTIONAL, -1, 1 }, + { "Multiple-Services-Credit-Control", RULE_OPTIONAL, -1, -1 }, + { "Cost-Information", RULE_OPTIONAL, -1, 1 }, + { "Final-Unit-Indication", RULE_OPTIONAL, -1, 1 }, + { "Check-Balance-Result", RULE_OPTIONAL, -1, 1 }, + { "Credit-Control-Failure-Handling", RULE_OPTIONAL, -1, 1 }, + { "Direct-Debiting-Failure-Handling", RULE_OPTIONAL, -1, 1 }, + { "Validity-Time", RULE_OPTIONAL, -1, 1 }, + { "Time-Quota-Threshold", RULE_OPTIONAL, -1, 1 }, + { "Redirect-Host", RULE_OPTIONAL, -1, -1 }, + { "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }, + { "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }, + { "Proxy-Info", RULE_OPTIONAL, -1, -1 }, + { "Route-Record", RULE_OPTIONAL, -1, -1 }, + { "Failed-AVP", RULE_OPTIONAL, -1, -1 } + /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */ + }; + + CHECK_dict_new( DICT_COMMAND, &data, g_dict_dcca, &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), cmd ); + } + } + LOG_D( "Extension 'Dictionary definitions for DCCA (rfc4006)' initialized"); + return 0; +} + +/* needs dict_nasreq for Filter-Id */ +// EXTENSION_ENTRY("dict_dcca", dict_dcca_entry, "dict_nasreq"); diff --git a/plat/diameter/extensions/sh_app/dict_dcca_3gpp.c b/plat/diameter/extensions/sh_app/dict_dcca_3gpp.c new file mode 100644 index 0000000..37ea3d6 --- /dev/null +++ b/plat/diameter/extensions/sh_app/dict_dcca_3gpp.c @@ -0,0 +1,859 @@ +/* + * Dictionary definitions of objects specified in DCCA (Nokia, 3GPP). + */ +#include "extension.h" + + +/* The content of this file follows the same structure as dict_base_proto.c */ + +#define CHECK_dict_new( _type, _data, _parent, _ref ) \ + CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) ); + +#define CHECK_dict_search( _type, _criteria, _what, _result ) \ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) ); + +struct local_rules_definition { + char *avp_name; + enum rule_position position; + int min; + int max; +}; + +#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 ) + +#define PARSE_loc_rules( _rulearray, _parent) { \ + int __ar; \ + for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \ + struct dict_rule_data __data = { NULL, \ + (_rulearray)[__ar].position, \ + 0, \ + (_rulearray)[__ar].min, \ + (_rulearray)[__ar].max}; \ + __data.rule_order = RULE_ORDER(__data.rule_position); \ + CHECK_FCT( fd_dict_search( \ + fd_g_config->cnf_dict, \ + DICT_AVP, \ + AVP_BY_NAME, \ + (_rulearray)[__ar].avp_name, \ + &__data.rule_avp, 0 ) ); \ + if ( !__data.rule_avp ) { \ + TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \ + return ENOENT; \ + } \ + CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \ + { \ + TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \ + (_rulearray)[__ar].avp_name ); \ + return EINVAL; \ + } ); \ + } \ +} + + +#define enumval_def_u32( _val_, _str_ ) \ + { _str_, { .u32 = _val_ }} + +#define enumval_def_os( _len_, _val_, _str_ ) \ + { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}} + + +int dict_dcca_3gpp_entry(char * conffile) +{ + TRACE_ENTRY("%p", conffile); + + #if 0 + /* Applications section */ + { + /* Create the vendors */ + { + struct dict_vendor_data vendor_data = { 10415, "3GPP" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, NULL)); + } + + } + #endif + + + /* AVP section */ + { + struct dict_object * Address_type; + struct dict_object * UTF8String_type; + struct dict_object * DiameterIdentity_type; + struct dict_object * DiameterURI_type; + struct dict_object * Time_type; + + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type); + + /* Reporting-Reason */ + { + /* + Enumerated. Will be present if quota was + exhausted for one or more metering types. Only + one Reporting-Reason AVP can be present in the + Used-Service-Unit AVP. (Note that the Reporting- + Reason AVP may be present also at the MSCC + level; see below.) + The following values are supported: + + QUOTA_EXHAUSTED(3); Quota for the + associated metering type has been + exhausted. With this reporting reason there is + only one metering type in this Used-Service- + Unit AVP. + + OTHER_QUOTA_TYPE(5); Quota for one or + more of the other metering types has been + exhausted. With this reporting reason there + may be multiple metering types in Used- + Service-Unit AVP. + + POOL_EXHAUSTED(8); Quota from the + credit pool has been exhausted. This reporting + reason is used if the quota for the associated + metering type was granted from a credit pool + by using the GSU-Pool-Reference AVP in the + CCA. With this reporting reason there is only + one metering type in the Used-Service-Unit + AVP. + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Reporting-Reason)" , NULL, NULL, NULL }; +// struct dict_enumval_data t_1 = { "QHT", { .i32 = 1 }}; +// struct dict_enumval_data t_2 = { "FINAL", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "QUOTA_EXHAUSTED", { .i32 = 3 }}; +// struct dict_enumval_data t_4 = { "VALIDITY_TIME", { .i32 = 4 }}; + struct dict_enumval_data t_5 = { "OTHER_QUOTA_TYPE", { .i32 = 5 }}; +// struct dict_enumval_data t_6 = { "RATING_CONDITION_CHANGE", { .i32 = 6 }}; +// struct dict_enumval_data t_7 = { "FORCED_REAUTHORIZATION", { .i32 = 7 }}; + struct dict_enumval_data t_8 = { "POOL_EXHAUSTED", { .i32 = 8 }}; + + struct dict_avp_data data = { + 872, /* Code */ + 10415, /* Vendor */ + "Reporting-Reason", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_5 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_8 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Trigger */ + { + /* + Grouped. The presence of the Trigger AVP in the + CCR identifies the event(s) triggering the CCR. + */ + + struct dict_avp_data data = { + 1264, /* Code */ + 10415, /* Vendor */ + "Trigger", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Trigger-Type */ + { + /* + Enumerated. One or more of these AVPs may be + present. Indicates the event that triggered the + MSCC. Supported values are: + + CHANGE_IN_SGSN_IP_ADDRESS (1), a change in the SGSN address. + + CHANGEINQOS_ANY (2), a change in the QoS profile + + CHANGEINRAT (4), a change in radio access technology + + */ + + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Trigger-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "CHANGE_IN_SGSN_IP_ADDRESS", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "CHANGEINQOS_ANY", { .i32 = 2 }}; + struct dict_enumval_data t_4 = { "CHANGEINRAT", { .i32 = 4 }}; + + struct dict_avp_data data = { + 870, /* Code */ + 10415, /* Vendor */ + "Trigger-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Service-Information */ + { + /* + Grouped. The Service-Information purpose is to + allow the transmission of additional 3GPP service + specific information elements (3GPP 32.299 + Rel7). + Service-Information :: = < AVP Header: 873> + * [ Subscription-Id ] + [ AoC-Information ] + [ PS-Information ] + [ WLAN-Information ] + [ IMS-Information ] + [ MMS-Information ] + [ LCS-Information ] + [ PoC-Information ] + [ MBMS-Information ] + [ SMS-Information ] + [ MMTel-Information ] + [ Service-Generic-Information ] + [ IM-Information ] + [ DCD-Information ] + */ + + struct dict_avp_data data = { + 873, /* Code */ + 10415, /* Vendor */ + "Service-Information", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* PS-Information */ + { + /* + Grouped. Its purpose is to allow the transmission + of additional PS service specific information + elements (3GPP 32.299 Rel7). + */ + + struct dict_avp_data data = { + 874, /* Code */ + 10415, /* Vendor */ + "PS-Information", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* PDP-Address */ + { + /* + Address. Present only in the initial CCR. Contains + the user equipment IP address. This AVP is + defined in 3GPP 32.299 Rel7. + */ + + struct dict_avp_data data = { + 1227, /* Code */ + 10415, /* Vendor */ + "PDP-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , Address_type, NULL); + } + + /* 3GPP-IMSI */ + { + /* + IMSI encoded in UTF-8 per 3GPP TS 23.003. No + padding. Maximum length of data: 15. + */ + struct dict_avp_data data = { + 1, /* Code */ + 10415, /* Vendor */ + "3GPP-IMSI", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-Charging-Id */ + { + /* + Unsigned32. (3GPP TS 29.061 Rel7) . The + charging identifier for the PDP context. The Flexi + ISN generates the 3GPP charging ID for both + virtual and normal PDP contexts with one excep- + tion. If the Flexi ISN acts as a NAS server and the + charging ID selection is set to NAS Client, the + charging ID will be the NAand not the 3GPP charging ID of Flexi ISN. + Present in the initial CCR only.S client + */ + struct dict_avp_data data = { + 2, /* Code */ + 10415, /* Vendor */ + "3GPP-Charging-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* 3GPP-PDP-Type */ + { + /* + Enumerated. (3GPP TS 29.061 Rel7 ). Type of + PDP context, for example, IP or PPP. Present in + the initial CCR only. + 0 = IPv4 + 1 = PPP + 2 = IPv6 + 3 = IPv4v6 + */ + struct dict_avp_data data = { + 3, /* Code */ + 10415, /* Vendor */ + "3GPP-PDP-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* 3GPP-CG-Address */ + { + /* + OctetString. (3GPP TS 29.061 Rel4). The address + of the charging gateway that has been marked as + the default charging gateway for the PDP context. + The address is expressed as a four-byte integer. + Present in the initial CCR only. + */ + struct dict_avp_data data = { + 4, /* Code */ + 10415, /* Vendor */ + "3GPP-CG-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , Address_type, NULL); + } + + /* 3GPP-GPRS-Negotiated-QoS-Profile */ + { + /* + UTF8String. (3GPP TS 29.061 Rel7 ). The QoS + profile applied by the Flexi ISN. In update and ter- + mination requests, this AVP is present only when + the CCR has been triggered by a PDP context + update affecting the negotiated QoS + Each octet is described by two UTF-8-encoded + characters denoting the hexadecimal + representation. + */ + struct dict_avp_data data = { + 5, /* Code */ + 10415, /* Vendor */ + "3GPP-GPRS-Negotiated-QoS-Profile", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-SGSN-Address */ + { + /* + OctetString. (3GPP TS 29.061 Rel4). The address + of the charging gateway that has been marked as + the default charging gateway for the PDP context. + The address is expressed as a four-byte integer. + Present in the initial CCR only. + */ + struct dict_avp_data data = { + 6, /* Code */ + 10415, /* Vendor */ + "3GPP-SGSN-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , Address_type, NULL); + } + + /* 3GPP-GGSN-Address */ + { + /* + OctetString. (3GPP TS 29.061 Rel4). Usually the + IP address of Flexi ISN. The only exception is + when the Flexi ISN acts as a NAS server and the + charging ID selection is set to NAS Client; then the + GGSN IP address will be the NAIP address. Present in the initial CCR only.S client + */ + struct dict_avp_data data = { + 7, /* Code */ + 10415, /* Vendor */ + "3GPP-GGSN-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , Address_type, NULL); + } + + /* 3GPP-IMSI-MCC-MNC */ + { + /* + UTF8String. MCC and MNC extracted from the + user's IMSI (first 5 or 6 digits, as applicable from + the presented IMSI). The MCC-MNCs are + extracted from the tables configured in FlexiISN + configuration under the General and Roaming + configurations. + */ + struct dict_avp_data data = { + 8, /* Code */ + 10415, /* Vendor */ + "3GPP-IMSI-MCC-MNC", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-GGSN-MCC-MNC */ + { + /* + UTF8String. (3GPP TS 29.061 Rel7 ). Contains + the mobile country and network code of the PLMN + that the Flexi ISN belongs to. Present in the initial + CCR only. The first entry in the list of local PLMNs + in the Flexi ISN configuration determines the value + of this AVP. + */ + struct dict_avp_data data = { + 9, /* Code */ + 10415, /* Vendor */ + "3GPP-GGSN-MCC-MNC", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-NSAPI */ + { + /* + UTF8String. (3GPP TS 29.061 Rel7 ). Indicates + the NSAPI of the PDP context. Contains one octet + consisting of a single digit. Present in the initial + CCR only. + */ + struct dict_avp_data data = { + 10, /* Code */ + 10415, /* Vendor */ + "3GPP-NSAPI", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-Session-Stop-Indicator */ + { + /* + OctetString. (3GPP TS 29.061 Rel4). The + presence of this AVP indicates that the last + context of the PDP session has been deleted. May + be present in the termination CCR only. Contains + one octet that has a value of 0xff. + */ + struct dict_avp_data data = { + 11, /* Code */ + 10415, /* Vendor */ + "3GPP-Session-Stop-Indicator", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* 3GPP-Selection-Mode */ + { + /* + UTF8String. (3GPP TS 29.061 Rel7 ). Consists of + one octet containing the selection mode as + received from SGSN in the Create PDP Context + Request. Present in the initial CCR only. + */ + struct dict_avp_data data = { + 12, /* Code */ + 10415, /* Vendor */ + "3GPP-Selection-Mode", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-Charging-Characteristics */ + { + /* + UTF8String. (3GPP TS 29.061 Rel7 ). The + charging characteristics for the PDP context. + Present in the initial CCR only. Consists of four + octets. Each octet contains a single UTF-8 + encoded digit. The content of the charging charac- + teristics is described in 3GPP TS 32.215. + */ + struct dict_avp_data data = { + 13, /* Code */ + 10415, /* Vendor */ + "3GPP-Charging-Characteristics", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-CG-IPv6-Address */ + { + /* + UTF8String.. (3GPP TS 29.061 Rel? (<=10) ). The + IPv6 address of the charging gateway. + */ + struct dict_avp_data data = { + 14, /* Code */ + 10415, /* Vendor */ + "3GPP-CG-IPv6-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-SGSN-IPv6-Address */ + { + /* + UTF8String.. (3GPP TS 29.061 Rel? (<=10) ). The + IPv6 address of the SGSN. + */ + struct dict_avp_data data = { + 15, /* Code */ + 10415, /* Vendor */ + "3GPP-SGSN-IPv6-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-GGSN-IPv6-Address */ + { + /* + UTF8String.. (3GPP TS 29.061 Rel? (<=10) ). The + IPv6 address of the GGSN. + */ + struct dict_avp_data data = { + 16, /* Code */ + 10415, /* Vendor */ + "3GPP-GGSN-IPv6-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-GGSN-IPv6-DNS-Servers */ + { + /* + UTF8String.. (3GPP TS 29.061 Rel? (<=10) ). List + of IPv6 addresses of DNS servers for an APN in + order of preference (max. 15 servers, 16 bytes + each). + */ + struct dict_avp_data data = { + 17, /* Code */ + 10415, /* Vendor */ + "3GPP-GGSN-IPv6-DNS-Servers", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-SGSN-MCC-MNC */ + { + /* + UTF8String. (3GPP TS 29.061 Rel7 ). MCC and + MNC extracted from the RAI within Create or + Update PDP Context Request. In update and ter- + mination requests, this AVP is present only when + the CCR has been triggered by a routing area + update. + */ + struct dict_avp_data data = { + 18, /* Code */ + 10415, /* Vendor */ + "3GPP-SGSN-MCC-MNC", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Missing: 3GPP-Teardown-Indicator (19) */ + + /* 3GPP-IMEISV */ + { + /* + IMEI(SV) encoded as sequence of UTF8 characters. + */ + struct dict_avp_data data = { + 20, /* Code */ + 10415, /* Vendor */ + "3GPP-IMEISV", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* 3GPP-RAT-Type */ + { + /* + OctetString. (3GPP TS 29.061 Rel7 ) Defines the + method used to access the network. Consists of a + single octet. The following values may be sent: + UTRAN (1), GERAN (2), WLAN (3), NAS (254), + Unspecified (255). + This AVP is included in the initial CCR and in + update or termination CCRs if the value changes. + */ + struct dict_avp_data data = { + 21, /* Code */ + 10415, /* Vendor */ + "3GPP-RAT-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* 3GPP-User-Location-Info */ + { + /* + OctetString. (3GPP TS 29.061 Rel7 ) Contains + information about the user's current geographical + location as received from the SGSN. Present + always in initial CCR if the value is known and in + update and termination CCRs if the value + changes. + */ + struct dict_avp_data data = { + 22, /* Code */ + 10415, /* Vendor */ + "3GPP-User-Location-Info", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* 3GPP-MS-TimeZone */ + { + /* + OctetString. (3GPP TS 29.061 Rel7 ) 3GPP-MS- + TimeZone is AVP is present always in the initial CCR if the + value is known and in the update and termination + CCRs if the value changes. This IE is encoded + according to 3GPP TS 29.061 Rel7 + */ + struct dict_avp_data data = { + 23, /* Code */ + 10415, /* Vendor */ + "3GPP-MS-TimeZone", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Missing: 3GPP-CAMEL-Charging-Info (24) */ + /* Missing: 3GPP-Packet-Filter (25) */ + /* Missing: 3GPP-Negotiated-DSCP (26) */ + /* Missing: 3GPP-Allocate-IP-Type (27) */ + + /* PDP-Context-Type */ + { + /* + Enumerated. Indicates the type of a PDP context + and is only included in CCR initial. + + values are 0 for primary and 1 for secondary + (3GPP 32.299 Rel7) + */ + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(PDP-Context-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "PRIMARY", { .i32 = 0 }}; + struct dict_enumval_data t_1 = { "SECONDARY", { .i32 = 1 }}; + + struct dict_avp_data data = { + 1247, /* Code */ + 10415, /* Vendor */ + "PDP-Context-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* IMS-Information */ + { + /* + Grouped. Its purpose is to allow the transmission + of additional IMS service specific information ele- + ments. (3GPP 32.299 Rel7) + */ + struct dict_avp_data data = { + 876, /* Code */ + 10415, /* Vendor */ + "IMS-Information", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* IMS-Charging-Identifier */ + { + /* + UTF8String. Contains the IMS charging identifier + as given to the Flexi ISN by the IMS. This AVP is + defined in 3GPP TS 32.225. This AVP is present + in IMS sessions only. Present in the initial CCR + only. + */ + struct dict_avp_data data = { + 841, /* Code */ + 10415, /* Vendor */ + "IMS-Charging-Identifier", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + + + + /* Max-Requested-Bandwidth-UL */ + { + /* + Unsigned32. The Max-Requested-Bandwidth- + UL/DL AVP indicates the maximum allowed bit + rate (in bits per second) for the uplink direction. + (Re-used from 3GPP 29.214) + */ + struct dict_avp_data data = { + 516, /* Code */ + 10415, /* Vendor */ + "Max-Requested-Bandwidth-UL", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Max-Requested-Bandwidth-DL */ + { + /* + Unsigned32. The Max-Requested-Bandwidth- + UL/DL AVP indicates the maximum allowed bit + rate (in bits per second) for the uplink direction. + */ + struct dict_avp_data data = { + 515, /* Code */ + 10415, /* Vendor */ + "Max-Requested-Bandwidth-DL", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* QoS-Information */ + { + /* + Grouped. This is the QoS that the DCCA + server requests from Flexi ISN to be applied for + this PDP context. This AVP and all AVPs con- + tained within are described in 3GPP TS 29.212 + Release 7. The ARP AVP is introduced with + Release 8. The relevant types are defined on + table 5.3.1 of TS 29.212. + */ + + struct dict_avp_data data = { + 1016, /* Code */ + 10415, /* Vendor */ + "QoS-Information", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + } + + + + TRACE_DEBUG(INFO, "Extension 'Dictionary definitions for DCCA 3GPP' initialized"); + return 0; +} + +// EXTENSION_ENTRY("dict_dcca_3gpp", dict_dcca_3gpp_entry, "dict_dcca"); diff --git a/plat/diameter/extensions/sh_app/gx_app.c b/plat/diameter/extensions/sh_app/gx_app.c new file mode 100644 index 0000000..01c69bf --- /dev/null +++ b/plat/diameter/extensions/sh_app/gx_app.c @@ -0,0 +1,3789 @@ +/**************** + Contributed by: Krishnan Srinivasan + License: to be specified. + TODO: + + ****************/ + +#include "extension.h" +#include +#include +#include +#include "sh_app.h" +#include "sh_conf.h" +#include "../../include/gy_message.h" + +#define _TEST_CCA 0 +#define PS_ENABLED 0 +#define FD_DEBUG_PROCESS 1 + +#define AUTH_APP_ID 16777238 +#define VENDOR_ID_3GPP 10415 +/* The content of this file follows the same structure as dict_base_proto.c */ + +void dump_sess_eyec(struct session *sess, const char *); + +static long ts_sec, ts_msec; +static long gx_start_ts = 0; + +static int gx_rec_ccr( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act); +static void gx_rec_cca(void *para, struct msg **msg); +_gy_port *gy_get_port_by_cxt_id(char *cxt_id); + +static struct disp_hdl * ccr_cb_hdl = NULL; /* handler for ccr req cb */ +//static struct disp_hdl * cca_cb_hdl = NULL; /* handler for cca req cb */ +// static struct disp_hdl * reauth_cb_hdl = NULL; /* handler for cca req cb */ + +struct dict_object *ccr_cmd = NULL; +struct dict_object *cca_cmd = NULL; +struct dict_object *dataobj_re_auth_request_type = NULL; +struct dict_object *session_id = NULL; +struct dict_object *origin_host = NULL; +struct dict_object *origin_realm = NULL; +struct dict_object *dest_host = NULL; +struct dict_object *dest_realm = NULL; +struct dict_object *reauth_cmd = NULL; +struct dict_object *auth_app_id = NULL; +struct dict_object *service_cxt_id = NULL ; +struct dict_object *cc_req_type = NULL; +struct dict_object *cc_req_num = NULL; +struct dict_object *result_code = NULL; + +struct dict_object *requested_action = NULL; +struct dict_object *check_balance_result = NULL; + +/* fj added 20160802 */ +struct dict_object *event_timestamp = NULL; +struct dict_object *subscription_id = NULL, *subscription_id_type = NULL, *subscription_id_data = NULL; +struct dict_object *service_information = NULL; +struct dict_object *ims_information = NULL; +struct dict_object *sms_information = NULL; +struct dict_object *time_stamps = NULL; + +struct dict_object *service_identifier = NULL; +struct dict_object *rating_group = NULL; +struct dict_object *multiple_services_indicator = NULL; +struct dict_object *multiple_services_credit_control = NULL; +struct dict_object *requested_service_unit = NULL; +struct dict_object *cc_time = NULL; +struct dict_object *cc_total_octects = NULL; +struct dict_object *reporting_reason = NULL; +struct dict_object *final_unit_action = NULL; + +struct dict_object *ps_information = NULL; + +extern struct dict_object *g_dict_dcca; +struct dict_object *term_cause = NULL; + +struct session *g_sess = NULL; +struct session_handler *g_hdlr = NULL; + +//static struct dict_avp_request __avp; + +enum gx_state +{ + STATE_INIT = 0, + STATE_INTERMEDIATE , + STATE_FINAL +}; +struct gx_sm_t +{ + enum gx_state state; + pthread_t tid; + struct fifo *events; + pthread_mutex_t p_sm_mtx; + int req_num; + struct session *sess; +} g_gx_sm; + + +/*---------------------------------*/ +static pthread_mutex_t gy_port_lock = PTHREAD_MUTEX_INITIALIZER; +//static pthread_mutex_t gy_cca_lock = PTHREAD_MUTEX_INITIALIZER; + +struct session *gy_sess[MAX_GY_PORT]; + +static _gy_space gy_space; +static _gy_stat gy_stat; +extern GHashTable *g_sess_hash; +//static pthread_mutex_t gy_msg_mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t sess_hash_mutx = PTHREAD_MUTEX_INITIALIZER; + +/* -------------------------------------------*/ +int pps_recv_gy_process(_gy_msg *gy_ptr); +//static int gx_add_msg_to_list(_gy_msg *pInMsg); +int pps_debug_info(char *app_name, char *str_to_show); +int pps_debug_flag_for_fd(); +unsigned int GetLocalIP( ); +extern int pps_ro_gy_cb(_gy_msg *gy_ptr); +int fdAsciiToBcdR(char *bcd_buf, int *bcd_buf_len, const char *ascii_buf, int len) +{ + int i; + char ch; + + *bcd_buf_len = len%2 + len/2; + + for(i = 0; i < len; i++) + { + ch = ascii_buf[i]; + if(ch >='a' ) ch -= 'a' -10; + else if(ch >='A') ch -= 'A'-10; + else ch -= '0'; + if(i & 1) *(bcd_buf++) |= ch<<4; + else *(bcd_buf) = ch & 0x0f; + } + + if(len%2) + { + *(bcd_buf++) |= 0xf0; + } + + return 0; +} + +int fdAsciiToBcd(unsigned char *bcd_buf, int *bcd_buf_len, const char *ascii_buf, int len) +{ + int i; + char ch; + + *bcd_buf_len = len%2 + len/2; + + + for(i=0;i='a') ch -='a' -10; + else if(ch>='A') ch -='A'-10; + else ch -='0'; + if(i &1) *(bcd_buf++) |=ch & 0x0f; + else *(bcd_buf) =ch<<4; + } + if(len%2) + { + *(bcd_buf++) |= 0x0f; + } + + return 0; +} + + +/* -------------------------------------------*/ +static void gy_port_init(_gy_port *gy_port_ptr, int index) +{ + if (gy_port_ptr == NULL) + { + return; + } + + gy_port_ptr->used_flag = 0; + gy_port_ptr->index = index; + gy_port_ptr->updated_ts = ts_sec; + gy_port_ptr->app_port = INVALID_GY_PORT; + gy_port_ptr->context_id[0] = '\0'; + gy_port_ptr->service_type = 0; + gy_port_ptr->request_number = 0; + gy_port_ptr->as_client = 0; + + return ; +} + +// start================================== +static int print_duplicated_sess_id(const char *cxt_id) +{ + int loop=0; + FILE *fpSess=NULL; + + fpSess = fopen("../log/dul_sess_id.txt","a"); + if(fpSess == NULL) + return 0; + + fprintf(fpSess,"now ts=%ld, sess: %s\r\n", ts_sec, cxt_id); + + fclose(fpSess); + + return 1; +} + +int gy_assign_port(char *cxt_id) +{ + int i, index, retval = INVALID_GY_PORT; + _gy_port *gy_port_ptr = NULL; + +// check if session id already in use========start + gy_port_ptr = gy_get_port_by_cxt_id(cxt_id); + if (gy_port_ptr != NULL) + { + print_duplicated_sess_id(cxt_id); + return retval; + } + + CHECK_POSIX_DO( pthread_mutex_lock(&gy_port_lock), { ASSERT(0); } ); + + for(i=0; iused_flag = 1; + strcpy(gy_port_ptr->context_id, cxt_id); + + gy_space.used_ports ++; + retval = index; + + if(pps_debug_flag_for_fd()) + { + char tmp_info[1024]; + + sprintf(tmp_info, " [fd=%04d][app=0000], ts=%ld.%03ld, used_pots=%d, %s\r\n", + index, ts_sec, ts_msec, gy_space.used_ports, __FUNCTION__); + pps_debug_info("diameter", tmp_info); + } + + break; + } + } + + CHECK_POSIX_DO( pthread_mutex_unlock(&gy_port_lock), { ASSERT(0); } ); + + if (gy_port_ptr != NULL) + { + pthread_mutex_lock(&sess_hash_mutx); + //g_hash_table_insert(g_sess_hash, strdup(context_id), (gpointer)gy_cxt_tb.gy_cxt_port[index].index); + g_hash_table_insert(g_sess_hash, gy_port_ptr->context_id, (gpointer)gy_port_ptr); + pthread_mutex_unlock(&sess_hash_mutx); + } + + return retval; +} + +int gy_release_port(unsigned short index) +{ + if(indexused_flag) + { + pthread_mutex_lock(&sess_hash_mutx); + if(g_sess_hash != NULL) + g_hash_table_remove(g_sess_hash, gy_port_ptr->context_id);// delete hash index + pthread_mutex_unlock(&sess_hash_mutx); + + CHECK_POSIX_DO( pthread_mutex_lock(&gy_port_lock), { ASSERT(0); } ); + gy_port_init(gy_port_ptr, index); + gy_space.used_ports --; + CHECK_POSIX_DO( pthread_mutex_unlock(&gy_port_lock), { ASSERT(0); } ); + } + + if(0) + { + char tmp_info[1024]; + + sprintf(tmp_info, " [fd=%04d][app=%04d], ts=%ld.%03ld, %s, used_ports=%d\r\n", + index, gy_space.gy_port[index].app_port,ts_sec, ts_msec, + __FUNCTION__, + gy_space.used_ports); + pps_debug_info("diameter", tmp_info); + + } + + } + + return 1; +} + +_gy_port *gy_get_port_space(unsigned short index) +{ + if(indexcnf_dict, DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &ccr_cmd, ENOENT)); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &cca_cmd, ENOENT)); + } + + // Do registeration and init stuff + { + LOG_D("Initializing dispatch callbacks for Gx interface"); + + if(ta_conf->mode & MODE_SERV ) + { + struct disp_when data; + memset(&data, 0, sizeof(data)); + data.app = g_dict_dcca; + data.command = ccr_cmd; + /* Now specific handler for CCR-CMD */ + CHECK_FCT( fd_disp_register( gx_rec_ccr, DISP_HOW_CC, &data, NULL, &ccr_cb_hdl ) ); + + LOG_D("fj app_gx_entry register gx_rec_ccr"); + } + +#ifdef REAUTH + CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &reauth_cmd, ENOENT)); + memset(&data, 0, sizeof(data)); + data.app = g_dict_dcca; + data.command = reauth_cmd; + printf("register REAUTH\n"); + CHECK_FCT( fd_disp_register( reauth_cb, DISP_HOW_CC, &data, NULL, &reauth_cb_hdl ) ); +#endif + } + + SEARCH_AVP_("Session-Id", 0, &session_id); + SEARCH_AVP_("Origin-Host", 0, &origin_host); + SEARCH_AVP_("Origin-Realm", 0, &origin_realm); + SEARCH_AVP_("Destination-Host", 0, &dest_host); + SEARCH_AVP_("Destination-Realm", 0, &dest_realm); + SEARCH_AVP_("Auth-Application-Id", 0, &auth_app_id); + SEARCH_AVP_("Service-Context-Id", 0, &service_cxt_id); + SEARCH_AVP_("CC-Request-Type", 0, &cc_req_type); + SEARCH_AVP_("Termination-Cause", 0, &term_cause); + SEARCH_AVP_("CC-Request-Number", 0, &cc_req_num); + SEARCH_AVP_("Requested-Action", 0, &requested_action); + SEARCH_AVP_("Result-Code", 0, &result_code); + SEARCH_AVP_("Check-Balance-Result", 0, &check_balance_result); + + /* fj added 20160802 */ + SEARCH_AVP_("Event-Timestamp", 0, &event_timestamp); + SEARCH_AVP_("Subscription-Id", 0, &subscription_id); + SEARCH_AVP_("Service-Information", 10415, &service_information); + SEARCH_AVP_("IMS-Information", 10415, &ims_information); + SEARCH_AVP_("SMS-Information", 10415, &sms_information); + SEARCH_AVP_("Time-Stamps", 10415, &time_stamps); + + SEARCH_AVP_("PS-Information", 10415, &ps_information); + + SEARCH_AVP_("Service-Identifier", 0, &service_identifier); + SEARCH_AVP_("Rating-Group", 0, &rating_group); + SEARCH_AVP_("Multiple-Services-Indicator", 0, &multiple_services_indicator); + SEARCH_AVP_("Multiple-Services-Credit-Control", 0, &multiple_services_credit_control); + SEARCH_AVP_("Requested-Service-Unit", 0, &requested_service_unit); + + CHECK_FCT(fd_sess_handler_create( &g_hdlr, (void *)free, NULL, NULL)); + CHECK_FCT( fd_fifo_new(&g_gx_sm.events, 0)); + CHECK_FCT( fd_disp_app_support( g_dict_dcca, NULL, 1 , 0)); + CHECK_FCT( fd_event_trig_regcb(SIGUSR1, "app_gx", gx_sig_hdlr ) ); + +out: + LOG_D("Extension 'Gx' initialized"); + return 0; +} + +void * gx_sm_th(void *sm) +{ + struct gx_sm_t *gx_sm = (struct gx_sm_t *) sm; + struct timespec tout; + int evt_code; + + CHECK_SYS_DO( clock_gettime( CLOCK_REALTIME, &tout), goto out); + tout.tv_sec =+ 60 ; + + while(1) + { + fd_event_timedget(gx_sm->events, &tout , ETIMEDOUT, &evt_code, NULL, NULL ); + CHECK_SYS_DO( clock_gettime( CLOCK_REALTIME, &tout), goto out); + printf("in tout sec %d\n", (int)tout.tv_sec); + if(evt_code == ETIMEDOUT) + { + gx_send_ccr(&gx_sm, ccr_cmd); + gx_sm->req_num++ ; + gx_sm->state = STATE_INTERMEDIATE; + CHECK_SYS_DO( clock_gettime( CLOCK_REALTIME, &tout), goto out); + tout.tv_sec += 30 ; + } + // printf("press enter\n"); + // getchar(); + } + +out: + + return NULL; +} +//TBD +int init_gx_sm(struct gx_sm_t *sm) +{ + int i; + sm->state = STATE_INIT; + sm->tid = 0;// + sm->events = NULL; + // pthread_mutex_t p_sm_mtx; + sm->req_num = 0; + sm->sess = NULL; + + for(i=0; i=MAX_GY_PORT)) + return 0; + + gy_port_ptr = &gy_space.gy_port[gy_port]; + if (gy_port_ptr->used_flag == 0) + { + return 0; + } + + pthread_mutex_lock(&sess_hash_mutx); + g_hash_table_remove(g_sess_hash, gy_port_ptr->context_id);// delete hash index + pthread_mutex_unlock(&sess_hash_mutx); + + strcpy(gy_port_ptr->context_id, cxt_value); + + pthread_mutex_lock(&sess_hash_mutx); + //g_hash_table_insert(g_sess_hash, strdup(context_id), (gpointer)gy_port_ptr); + g_hash_table_insert(g_sess_hash, gy_port_ptr->context_id, (gpointer)gy_port_ptr); + pthread_mutex_unlock(&sess_hash_mutx); + + return 1; +} + + +/*--------------------------------------------*/ + +struct gx_sm_t *gl_gx_sm = NULL; + +void gx_sig_hdlr() +{ + struct gx_sm_t *gx_sm = gl_gx_sm; + + if( gx_sm) + { + // fd_sess_dump( 0 , g_gx_sm.sess); + } + else + { + if( NULL != (gx_sm= (struct gx_sm_t *)malloc(sizeof(struct gx_sm_t)) ) ) + { + init_gx_sm(gx_sm); + } + gl_gx_sm = gx_sm; + } + + gx_send_ccr( &gx_sm, ccr_cmd); + return; +} + + +int gx_sig_hdlr_app(_gy_msg *msg_ptr) +{ + struct gx_sm_t *gx_sm = gl_gx_sm; + + if( gx_sm) + { + // fd_sess_dump( 0 , g_gx_sm.sess); + } + else + { + if( NULL != (gx_sm= (struct gx_sm_t *)malloc(sizeof(struct gx_sm_t)) ) ) + { + init_gx_sm(gx_sm); + } + gl_gx_sm = gx_sm; + } + + return gx_send_ccr_real( &gx_sm, ccr_cmd, msg_ptr); +} + +/* Search a given AVP model in an AVP (extracted from libfreediameter/message.c ) */ +int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp ) +{ + struct avp * nextavp; + struct avp_hdr * nextavphdr; + struct dict_avp_data dictdata; + + + TRACE_ENTRY("%p %p %p", groupedavp, what, avp); + + CHECK_FCT( fd_dict_getval(what, &dictdata) ); + + // Loop only in the group AVP + CHECK_FCT( fd_msg_browse(groupedavp, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) ); + CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) ); + + while (nextavphdr) + { + + if ( (nextavphdr->avp_code == dictdata.avp_code) && (nextavphdr->avp_vendor == dictdata.avp_vendor) ) // always 0 if no Vendor flag + { + break; + } + + // Otherwise move to next AVP in the grouped AVP + CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) ); + + if(nextavp!=NULL) + { + CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) ); + } + else + nextavphdr=NULL; + } + if (avp) + *avp = nextavp; + + if (avp && nextavp) + { + struct dictionary * dict; + CHECK_FCT( fd_dict_getdict( what, &dict) ); + CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), ); + } + + if (avp || nextavp) + return 0; + else + return ENOENT; +} + +static int dcca_ans_from_req( struct dict_object * obj, struct msg *qry, struct msg **msg) +{ + struct avp *avp = NULL; + struct avp_hdr * avpdata; + int rc = -1; + + CHECK_FCT(fd_msg_search_avp( qry, obj, &avp)); + CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata)); + avp = NULL; + + CHECK_FCT_DO( fd_msg_avp_new ( obj, 0, &avp ), goto out ); + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, avpdata->avp_value ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( *msg, MSG_BRW_LAST_CHILD, avp ), goto out ); + + rc = 0; +out: + return rc; +} +static int gx_parse_cca( struct msg ** msg) +{ + struct msg* cca_msg = *msg; + struct avp *avp, *grpavp = NULL, *grpavp_sub1 = NULL; + struct avp_hdr *avphdr; + + char tmp_buf[1024], session_id_str[128]; + _gy_port *gy_port_ptr = NULL; + _gy_msg gy_msg; + _gy_cca *cca_ptr = NULL; + + LOG_N("fj Parse CCA enter"); + + memset(&gy_msg, 0x00, sizeof(_gy_msg)); + memset(session_id_str, 0x00, 128); + + cca_ptr = &gy_msg.msg_body.cca; + gy_msg.msg_type = GY_MSG_CCA; + /* Session-Id */ + PARSE_AVP_STR(cca_msg, session_id, avp, avphdr, "Parse CCA Session-Id", avphdr->avp_value->os.data) + if (avphdr != NULL ) + fd_get_session_id((char *)avphdr->avp_value->os.data, session_id_str, 0); + + gy_port_ptr = gy_get_port_by_cxt_id(session_id_str); + if((gy_port_ptr == NULL) || (gy_port_ptr->used_flag == 0)) + { + if (pps_debug_flag_for_fd()) + { + sprintf(tmp_buf, "%s, can't find gy_port, cxt_id=%s\r\n", + __FUNCTION__, session_id_str); + pps_debug_info("diameter", tmp_buf); + } + + return 0; + } + + if (pps_debug_flag_for_fd()) + { + sprintf(tmp_buf, "\r\n%s, gy_port=%d, app_port=%d, cxt_id=%s\r\n", + __FUNCTION__, gy_port_ptr->index, gy_port_ptr->app_port, session_id_str); + pps_debug_info("diameter", tmp_buf); + } + + gy_msg.service_type = gy_port_ptr->service_type; + gy_msg.app_port = gy_port_ptr->app_port; + gy_msg.fd_port = gy_port_ptr->index; + + /* Origin-Host */ + PARSE_AVP_STR(cca_msg, origin_host, avp, avphdr, "Parse CCA Origin-Host", avphdr->avp_value->os.data) + + /* Origin-Realm */ + PARSE_AVP_STR(cca_msg, origin_realm, avp, avphdr, "Parse CCA Origin-Realm", avphdr->avp_value->os.data) + + /*Destination-Host */ + PARSE_AVP_STR(cca_msg, dest_host, avp, avphdr, "Parse CCA Destination-Host", avphdr->avp_value->os.data) + + /* Destination-Realm */ + PARSE_AVP_STR(cca_msg, dest_realm, avp, avphdr, "Parse CCA Destination-Realm", avphdr->avp_value->os.data) + + /* Auth-Application-Id */ + PARSE_AVP_U32(cca_msg, auth_app_id, avp, avphdr, "Parse CCA Auth-Application-Id", avphdr->avp_value->u32) + + /* CC-Request-Type */ + PARSE_AVP_U32(cca_msg, cc_req_type, avp, avphdr, "Parse CCA CC-Request-Type", avphdr->avp_value->u32) + if (avphdr != NULL ) + gy_msg.request_type = avphdr->avp_value->u32; + + /* CC-Request-Number */ + PARSE_AVP_U32(cca_msg, cc_req_num, avp, avphdr, "Parse CCA CC-Request-Number", avphdr->avp_value->u32) + + /* Result-Code */ + PARSE_AVP_U32(cca_msg, result_code, avp, avphdr, "Parse CCA CC-Result-Code", avphdr->avp_value->u32) + if (avphdr != NULL ) + cca_ptr->result = avphdr->avp_value->u32; + + /* Multiple-Services-Credit-Control */ + struct dict_object *multiple_services_credit_control = NULL; + SEARCH_AVP_("Multiple-Services-Credit-Control", 0, &multiple_services_credit_control); + CHECK_FCT( fd_msg_search_avp ( cca_msg, multiple_services_credit_control, &grpavp) ); + if(grpavp != NULL) + { + LOG_N("fj Parse CCA Multiple-Services-Credit-Control"); + + /* Result-Code */ + struct dict_object *result_code = NULL; + SEARCH_AVP_("Result-Code", 0, &result_code); + if(result_code != NULL) + { + PARSE_GRPAVP_U32(grpavp, result_code, avp, avphdr, "Parse CCA Result-Code", avphdr->avp_value->u32) + if (avphdr != NULL ) + cca_ptr->result = avphdr->avp_value->u32; + } + + /* Granted-Service-Unit */ + struct dict_object *granted_service_unit = NULL; + SEARCH_AVP_("Granted-Service-Unit", 0, &granted_service_unit); + CHECK_FCT( fd_sh_avp_search_avp ( grpavp, granted_service_unit, &grpavp_sub1) ); + if(grpavp_sub1 != NULL) + { + /* CC-Time */ + struct dict_object *cc_time = NULL; + SEARCH_AVP_("CC-Time", 0, &cc_time); + PARSE_GRPAVP_U32(grpavp_sub1, cc_time, avp, avphdr, "Parse CCA CC-Time", avphdr->avp_value->u32) + if (avphdr != NULL ) + cca_ptr->grant_value = avphdr->avp_value->u32; + } + + cca_ptr->is_final = 0; + + struct dict_object *final_unit_indication = NULL; + SEARCH_AVP_("Final-Unit-Indication", 0, &final_unit_indication); + CHECK_FCT( fd_sh_avp_search_avp ( grpavp, final_unit_indication, &grpavp_sub1) ); + if(grpavp_sub1 != NULL) + { + /* Final-Unit-Action */ + struct dict_object *final_unit_action= NULL; + SEARCH_AVP_("Final-Unit-Action", 0, &final_unit_action); + PARSE_GRPAVP_U32(grpavp_sub1, final_unit_action, avp, avphdr, "Parse CCA Final-Unit-Action", avphdr->avp_value->u32) + if (avphdr != NULL ) + cca_ptr->is_final = 1; + } + + /* + struct dict_object *final_unit_indication = NULL; + SEARCH_AVP_("Final-Unit-Indication", 0, &final_unit_indication); + if(final_unit_indication != NULL) + { + PARSE_GRPAVP_U32(grpavp, final_unit_indication, avp, avphdr, "Parse CCA Final-Unit-Indication", avphdr->avp_value->u32) + + cca_ptr->is_final = avphdr->avp_value->u32; + if(cca_ptr->is_final>1) + cca_ptr->is_final = 0; + + } + */ + } + + //pps_recv_gy_process(&gy_msg); + pps_ro_gy_cb(&gy_msg); + /*pthread_mutex_lock( &gy_msg_mtx ); + gx_add_msg_to_list(&gy_msg); + pthread_mutex_unlock( &gy_msg_mtx );*/ + + gx_stat_increase_recv_cca(gy_msg.request_type); + + if(gy_msg.request_type == RT_TERMINATE_REQUEST || + gy_msg.request_type == RT_EVENT_REQUEST || + (cca_ptr->result != 2001 && gy_msg.request_type != RT_UPDATE_REQUEST)) + { + unsigned int gy_port; + + gy_port = gy_port_ptr->index; + if(gy_port < MAX_GY_PORT) + { + gy_release_port(gy_port); + if(gy_sess[gy_port] != NULL) + fd_sess_destroy(&gy_sess[gy_port]); + } + } +out: + LOG_N("fj Parse CCA exit"); + return 0; +} + + +static int gx_parse_ccr( struct msg ** msg, struct gy_msg *gy_ptr) +{ + struct msg* ccr_msg = *msg; + struct avp *avp, *groupedavp=NULL, *groupedavp_sub=NULL, *groupedavp_sub_sub=NULL; + struct avp_hdr *avphdr; + struct gy_ccr *gy_ccr = NULL; + int len; + + // struct dict_object *dict_obj_tmp = NULL; + + LOG_N("fj Parse CCR enter"); + + gy_ccr = &gy_ptr->msg_body.ccr; + + /* Session-Id */ + PARSE_AVP_STR(ccr_msg, session_id, avp, avphdr, "Parse CCR Session-Id", avphdr->avp_value->os.data) + { + //char padding[12]={";CCR_SESS"}; + char sess_id[128]; + + //sprintf(sess_id, "%s%s",avphdr->avp_value->os.data, padding); + if (avphdr != NULL) + { + if (avphdr->avp_value->os.len >= 128) + { + avphdr->avp_value->os.len = 127; + } + memcpy(sess_id, avphdr->avp_value->os.data, avphdr->avp_value->os.len); + sess_id[avphdr->avp_value->os.len] = '\0'; + //sprintf(sess_id, "%s",avphdr->avp_value->os.data); + //fd_get_session_id(sess_id, gy_ptr->cxt_id, 0); + strcpy(gy_ptr->cxt_id, sess_id); + } + } + + /* Origin-Host */ + PARSE_AVP_STR(ccr_msg, origin_host, avp, avphdr, "Parse CCR Origin-Host", avphdr->avp_value->os.data) + if (avphdr != NULL) + { + if (avphdr->avp_value->os.len >= GY_APN_LEN) + { + avphdr->avp_value->os.len = GY_APN_LEN-1; + } + memcpy(gy_ccr->apn, avphdr->avp_value->os.data, avphdr->avp_value->os.len); + gy_ccr->apn[avphdr->avp_value->os.len] = '\0'; + } + + /* Origin-Realm */ + PARSE_AVP_STR(ccr_msg, origin_realm, avp, avphdr, "Parse CCR Origin-Realm", avphdr->avp_value->os.data) + + /*Destination-Host */ + PARSE_AVP_STR(ccr_msg, dest_host, avp, avphdr, "Parse CCR Destination-Host", avphdr->avp_value->os.data) + + /* Destination-Realm */ + PARSE_AVP_STR(ccr_msg, dest_realm, avp, avphdr, "Parse CCR Destination-Realm", avphdr->avp_value->os.data) + + /* Auth-Application-Id */ + PARSE_AVP_U32(ccr_msg, auth_app_id, avp, avphdr, "Parse CCR Auth-Application-Id", avphdr->avp_value->u32) + + /* Service-Context-Id */ + PARSE_AVP_STR(ccr_msg, service_cxt_id, avp, avphdr, "Parse CCR Service-Context-Id", avphdr->avp_value->os.data) + + /* CC-Request-Type */ + PARSE_AVP_U32(ccr_msg, cc_req_type, avp, avphdr, "Parse CCR CC-Request-Type", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->request_type = avphdr->avp_value->u32; + } + + /* Requested-Action */ + PARSE_AVP_U32(ccr_msg, requested_action, avp, avphdr, "Parse CCR Requested-Action", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->msg_body.ccr.request_action = avphdr->avp_value->u32; + } + + /* CC-Request-Number */ + PARSE_AVP_U32(ccr_msg, cc_req_num, avp, avphdr, "Parse CCR CC-Request-Number", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->request_number = avphdr->avp_value->u32; + } + + /* Requested-Service-Unit */ + CHECK_FCT( fd_msg_search_avp ( ccr_msg, requested_service_unit, &groupedavp) ); + if(groupedavp != NULL) + { + LOG_N("fj Parse CCR Requested-Service-Unit"); + + /* CC-Money */ + struct dict_object *cc_money = NULL; + SEARCH_AVP_("CC-Money", 0, &cc_money); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp, cc_money, &groupedavp_sub) ); + if(groupedavp_sub != NULL) + { + /* Unit-Value */ + struct dict_object *unit_value = NULL; + SEARCH_AVP_("Unit-Value", 0, &unit_value); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub, unit_value, &groupedavp_sub_sub)); + if(groupedavp_sub_sub != NULL) + { + /* Value-Digits */ + struct dict_object *value_digits = NULL; + SEARCH_AVP_("Value-Digits", 0, &value_digits); + avphdr = NULL; + PARSE_GRPAVP_U64(groupedavp_sub_sub, value_digits, avp, avphdr, "Parse CCR value-digits", avphdr->avp_value->u64) + if (avphdr != NULL) + { + gy_ptr->msg_body.ccr.req_service_unit = avphdr->avp_value->u64; + } + + /* Exponent */ + struct dict_object *exponent = NULL; + SEARCH_AVP_("Exponent", 0, &exponent); + avphdr = NULL; + PARSE_GRPAVP_U32(groupedavp_sub_sub, exponent, avp, avphdr, "Parse CCR Exponent", avphdr->avp_value->i32) + if ((avphdr != NULL) && (avphdr->avp_value->i32 != 0)) + { + gy_ptr->msg_body.ccr.req_service_unit *= pow(10, avphdr->avp_value->i32); + } + } + } + } + + /* Event-Timestamp */ + PARSE_AVP_STR(ccr_msg, event_timestamp, avp, avphdr, "Parse CCR Event-Timestamp", avphdr->avp_value->os.data) + + /* Subscription-Id */ + CHECK_FCT( fd_msg_search_avp ( ccr_msg, subscription_id, &groupedavp) ); + if(groupedavp != NULL) + { + LOG_N("fj Parse CCR Subscription-Id"); + + /* Subscription-Id-Type */ + SEARCH_AVP_("Subscription-Id-Type", 0, &subscription_id_type); + PARSE_GRPAVP_U32(groupedavp, subscription_id_type, avp, avphdr, "Parse CCR Subscription-Id-Type", avphdr->avp_value->u32) + + /* Subscription-Id-Data */ + SEARCH_AVP_("Subscription-Id-Data", 0, &subscription_id_data); + PARSE_GRPAVP_STR(groupedavp, subscription_id_data, avp, avphdr, "Parse CCR Subscription-Id-Data", avphdr->avp_value->os.data) + if(avphdr != NULL ) + { + if(avphdr->avp_value != NULL) + { + if(avphdr->avp_value->os.data != NULL) + { + if(strlen((char *)avphdr->avp_value->os.data) >= NUMBER_LEN) + { + memcpy(gy_ccr->caller, avphdr->avp_value->os.data, NUMBER_LEN - 1); + gy_ccr->caller[NUMBER_LEN-1] = '\0'; + } + else + strcpy(gy_ccr->caller, (char *)avphdr->avp_value->os.data); + } + } + } + } + + gy_ptr->service_type = ST_PS_DATA; + + /* Service-Information */ + CHECK_FCT( fd_msg_search_avp ( ccr_msg, service_information, &groupedavp) ); + if(groupedavp != NULL) + { + LOG_N("fj Parse CCR Service-Information"); + + /* Value-Digits */ + /*struct dict_object *value_digits = NULL; + SEARCH_AVP_("Value-Digits", 0, &value_digits); + avphdr = NULL; + PARSE_GRPAVP_U64(groupedavp, value_digits, avp, avphdr, "Parse CCR value_digits", avphdr->avp_value->u64) + if (avphdr != NULL) + { + gy_ptr->msg_body.ccr.balance_to_check = avphdr->avp_value->u64; + }*/ + + /* IMS-Information */ + SEARCH_AVP_("IMS-Information", 10415, &ims_information); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp, ims_information, &groupedavp_sub) ); + if(groupedavp_sub == NULL) + { + gy_ptr->service_type = ST_PS_DATA; + + /* PS-Information */ + SEARCH_AVP_("PS-Information", 10415, &ps_information); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp, ps_information, &groupedavp_sub) ); + if(groupedavp_sub != NULL) + { + gy_ptr->service_type = ST_PS_DATA; + + /* SGSN-Address */ + struct dict_object *sgsn_address = NULL; + SEARCH_AVP_("SGSN-Address", 10415, &sgsn_address); + PARSE_GRPAVP_STR(groupedavp_sub, sgsn_address, avp, avphdr, "Parse CCR SGSN-Address", avphdr->avp_value->os.data) + if(avphdr != NULL ) + { + if(avphdr->avp_value != NULL) + { + if(avphdr->avp_value->os.data != NULL) + { + memcpy(&gy_ptr->msg_body.ccr.sgsn_ip, &avphdr->avp_value->os.data[2], 4); + } + } + } + + + /* GGSN-Address */ + struct dict_object *ggsn_address = NULL; + SEARCH_AVP_("GGSN-Address", 10415, &ggsn_address); + PARSE_GRPAVP_U32(groupedavp_sub, ggsn_address, avp, avphdr, "Parse CCR GGSN-Address", avphdr->avp_value->u32) + if(avphdr != NULL ) + { + if(avphdr->avp_value != NULL) + { + if(avphdr->avp_value->os.data != NULL) + { + memcpy(&gy_ptr->msg_body.ccr.ggsn_ip, &avphdr->avp_value->os.data[2], 4); + } + } + } + + } + else + { + /* SMS-Information */ + SEARCH_AVP_("SMS-Information", 10415, &sms_information); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp, sms_information, &groupedavp_sub) ); + if(groupedavp_sub != NULL) + { + gy_ptr->service_type = ST_CS_SMS; + + /* Recipient-Info */ + struct dict_object *recipient_info = NULL; + SEARCH_AVP_("Recipient-Info", 10415, &recipient_info); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub, recipient_info, &groupedavp_sub_sub) ); + if (groupedavp_sub_sub != NULL) + { + /* Recipient-Address */ + struct avp *grp_sub = NULL; + struct dict_object *recipient_addr = NULL; + SEARCH_AVP_("Recipient-Address", 10415, &recipient_addr); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub_sub, recipient_addr, &grp_sub) ); + if (grp_sub != NULL) + { + /* Address-Data */ + struct dict_object *address_data = NULL; + SEARCH_AVP_("Address-Data", 10415, &address_data); + avphdr = NULL; + PARSE_GRPAVP_STR(grp_sub, address_data, avp, avphdr, "Parse CCR Address-Data", avphdr->avp_value->os.data) + if(avphdr != NULL ) + { + if(avphdr->avp_value != NULL) + { + if(avphdr->avp_value->os.data != NULL) + { + int len = avphdr->avp_value->os.len; + if (len >= NUMBER_LEN) + { + len = NUMBER_LEN-1; + } + + memcpy(&gy_ccr->called, &avphdr->avp_value->os.data[0], len); + gy_ccr->called[len] = '\0'; + } + } + } + } + } + + /* Number-of-Messages-Sent */ + struct dict_object *num_msg_sent = NULL; + SEARCH_AVP_("Number-Of-Messages-Sent", 10415, &num_msg_sent); + avphdr = NULL; + PARSE_GRPAVP_U32(groupedavp_sub, num_msg_sent, avp, avphdr, "Parse CCR Number-Of-Messages-Sent", avphdr->avp_value->u32) + if((avphdr != NULL) && (avphdr->avp_value != NULL)) + { + gy_ccr->sent_msg_num = avphdr->avp_value->u32; + } + + /* SMSC-Address */ + struct dict_object *smsc_address = NULL; + SEARCH_AVP_("SMSC-Address", 10415, &smsc_address); + avphdr = NULL; + PARSE_GRPAVP_STR(groupedavp_sub, smsc_address, avp, avphdr, "Parse CCR SMSC-Address", avphdr->avp_value->os.data) + if(avphdr != NULL ) + { + if(avphdr->avp_value != NULL) + { + if((avphdr->avp_value->os.data != NULL) && (avphdr->avp_value->os.len > 2)) + { + int len = avphdr->avp_value->os.len - 2; + if (len >= NUMBER_LEN) + { + len = NUMBER_LEN-1; + } + + memcpy(&gy_ccr->smsc, &avphdr->avp_value->os.data[2], len); + gy_ccr->smsc[len] = '\0'; + } + } + } + } + } + } + else if(groupedavp_sub != NULL) + { + gy_ptr->service_type = ST_CS_VOICE; + + /* Node-Functionality */ + struct dict_object *node_functionality = NULL; + SEARCH_AVP_("Node-Functionality", 10415, &node_functionality); + PARSE_GRPAVP_U32(groupedavp_sub, node_functionality, avp, avphdr, "Parse CCR Node-Functionality", avphdr->avp_value->u32) + + /* Event-Type */ + struct dict_object *event_type = NULL; + SEARCH_AVP_("Event-Type", 10415, &event_type); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub, event_type, &groupedavp_sub_sub) ); + if(groupedavp_sub_sub != NULL) + { + /* SIP-Method */ + struct dict_object *sip_method = NULL; + SEARCH_AVP_("SIP-Method", 10415, &sip_method); + PARSE_GRPAVP_STR(groupedavp_sub_sub, sip_method, avp, avphdr, "Parse CCR Parse CCR SIP-Method", avphdr->avp_value->os.data) + } + + /* Role-of-Node */ + struct dict_object *role_of_node = NULL; + SEARCH_AVP_("Role-of-Node", 10415, &role_of_node); + PARSE_GRPAVP_U32(groupedavp_sub, role_of_node, avp, avphdr, "Parse CCR Role-of-Node", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->msg_body.ccr.role_of_node = avphdr->avp_value->u32; + } + + /* User-Session-Id */ + struct dict_object *user_session_id = NULL; + SEARCH_AVP_("User-Session-Id", 10415, &user_session_id); + PARSE_GRPAVP_STR(groupedavp_sub, user_session_id, avp, avphdr, "Parse CCR User-Session-Id", avphdr->avp_value->os.data) + + /* Time-Stamps */ + struct dict_object *time_stamps = NULL; + SEARCH_AVP_("Time-Stamps", 10415, &time_stamps); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub, time_stamps, &groupedavp_sub_sub) ); + if(groupedavp_sub_sub != NULL) + { + /* SIP-Request-Timestamp */ + struct dict_object *sip_request_timestamp = NULL; + SEARCH_AVP_("SIP-Request-Timestamp", 10415, &sip_request_timestamp); + PARSE_GRPAVP_STR(groupedavp_sub_sub, sip_request_timestamp, avp, avphdr, "Parse CCR SIP-Request-Timestamp", avphdr->avp_value->os.data) + + /*SIP-Response-Timestamp */ + struct dict_object *sip_response_timestamp = NULL; + SEARCH_AVP_("SIP-Response-Timestamp", 10415, &sip_response_timestamp); + PARSE_GRPAVP_STR(groupedavp_sub_sub, sip_response_timestamp, avp, avphdr, "Parse CCR SIP-Response-Timestamp", avphdr->avp_value->os.data) + } + + /*Inter-Operator-Identifier */ + struct dict_object *inter_operator_identifier = NULL; + SEARCH_AVP_("Inter-Operator-Identifier", 10415, &inter_operator_identifier); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub, inter_operator_identifier, &groupedavp_sub_sub) ); + if(groupedavp_sub_sub != NULL) + { + /* Originating-IOI */ + struct dict_object *originating_ioi = NULL; + SEARCH_AVP_("Originating-IOI", 10415, &originating_ioi); + PARSE_GRPAVP_STR(groupedavp_sub_sub, originating_ioi, avp, avphdr, "Parse CCR Originating-IOI", avphdr->avp_value->os.data) + + /* Terminating-IOI */ + struct dict_object *terminating_ioi = NULL; + SEARCH_AVP_("Terminating-IOI", 10415, &terminating_ioi); + PARSE_GRPAVP_STR(groupedavp_sub_sub, terminating_ioi, avp, avphdr, "Parse CCR Terminating-IOI", avphdr->avp_value->os.data) + } + + /* IMS-Charging-Identifier */ + struct dict_object *ims_charging_dentifier = NULL; + SEARCH_AVP_("IMS-Charging-Identifier", 10415, &ims_charging_dentifier); + PARSE_GRPAVP_STR(groupedavp_sub, ims_charging_dentifier, avp, avphdr, "Parse CCR IMS-Charging-Identifier", NULL/*avphdr->avp_value->os.data*/) + + /* SDP-Session-Description */ + struct dict_object *sdp_session_description = NULL; + SEARCH_AVP_("SDP-Session-Description", 10415, &sdp_session_description); + PARSE_GRPAVP_STR(groupedavp_sub, sdp_session_description, avp, avphdr, "Parse CCR SDP-Session-Description", NULL/*avphdr->avp_value->os.data*/) + + /* SDP-Media-Component */ + struct dict_object *sdp_media_component = NULL; + SEARCH_AVP_("SDP-Media-Component", 10415, &sdp_media_component); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub, sdp_media_component, &groupedavp_sub_sub) ); + if(groupedavp_sub_sub != NULL) + { + /* SDP-Media-Name */ + struct dict_object *sdp_media_name = NULL; + SEARCH_AVP_("SDP-Media-Name", 10415, &sdp_media_name); + PARSE_GRPAVP_STR(groupedavp_sub_sub, sdp_media_name, avp, avphdr, "Parse CCR SDP-Media-Name", NULL/*avphdr->avp_value->os.data*/) + + /* SDP-Media-Description */ + struct dict_object *sdp_media_description = NULL; + SEARCH_AVP_("SDP-Media-Description", 10415, &sdp_media_description); + PARSE_GRPAVP_STR(groupedavp_sub_sub, sdp_media_description, avp, avphdr, "Parse CCR SDP-Media-Description", NULL/*avphdr->avp_value->os.data*/) + } + + /* Message-Body */ + struct dict_object *message_body = NULL; + SEARCH_AVP_("Message-Body", 10415, &message_body); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp_sub, message_body, &groupedavp_sub_sub) ); + if(groupedavp_sub_sub != NULL) + { + /* Content-Type */ + struct dict_object *content_type = NULL; + SEARCH_AVP_("Content-Type", 10415, &content_type); + PARSE_GRPAVP_STR(groupedavp_sub_sub, content_type, avp, avphdr, "Parse CCR Content-Type", NULL/*avphdr->avp_value->os.data*/) + + /* Content-Length */ + struct dict_object *content_length = NULL; + SEARCH_AVP_("Content-Length", 10415, &content_length); + PARSE_GRPAVP_U32(groupedavp_sub_sub, content_length, avp, avphdr, "Parse CCR Content-Length", avphdr->avp_value->u32) + } + + /* Access-Network-Information */ + struct dict_object *access_network_information = NULL; + SEARCH_AVP_("Access-Network-Information", 10415, &access_network_information); + PARSE_GRPAVP_STR(groupedavp_sub, access_network_information, avp, avphdr, "Parse CCR Access-Network-Information", NULL/*avphdr->avp_value->os.data*/) + + /* Calling-Party-Address */ + struct dict_object *calling_party_address = NULL; + SEARCH_AVP_("Calling-Party-Address", 10415, &calling_party_address); + PARSE_GRPAVP_STR(groupedavp_sub, calling_party_address, avp, avphdr, "Parse CCR Calling-Party-Address", NULL/*avphdr->avp_value->os.data*/) + if (avphdr != NULL && avphdr->avp_value != NULL) + { + if( avphdr->avp_value->os.data != NULL) + { + len = strlen((char *)avphdr->avp_value->os.data); + if(len>NUMBER_LEN) len = NUMBER_LEN; + memcpy(gy_ccr->caller, avphdr->avp_value->os.data, len); + } + } + + /* Called-Party-Address */ + struct dict_object *called_party_address = NULL; + SEARCH_AVP_("Called-Party-Address", 10415, &called_party_address); + PARSE_GRPAVP_STR(groupedavp_sub, called_party_address, avp, avphdr, "Parse CCR Called-Party-Address", avphdr->avp_value->os.data) + if (avphdr != NULL && avphdr->avp_value != NULL) + { + if(avphdr->avp_value->os.data != NULL) + { + len = strlen((char *)avphdr->avp_value->os.data); + if(len>NUMBER_LEN) len = NUMBER_LEN; + + memcpy(gy_ccr->called, avphdr->avp_value->os.data, len); + gy_ptr->service_type = ST_CS_VOICE; + } + } + + /* Requested-Party-Address */ + struct dict_object *requested_party_address = NULL; + SEARCH_AVP_("Requested-Party-Address", 10415, &requested_party_address); + PARSE_GRPAVP_STR(groupedavp_sub, requested_party_address, avp, avphdr, "Parse CCR Requested-Party-Address", avphdr->avp_value->os.data) + + /* huawei_avp_20820 */ + struct dict_object *huawei_avp_20820 = NULL; + SEARCH_AVP_("huawei_avp_20820", 2011, &huawei_avp_20820); + PARSE_GRPAVP_U32(groupedavp_sub, huawei_avp_20820, avp, avphdr, "Parse CCR huawei_avp_20820", avphdr->avp_value->u32) + + /* Subscription-Id-Type */ + PARSE_GRPAVP_U32(groupedavp_sub, subscription_id_type, avp, avphdr, "Parse CCR Subscription-Id-Type", avphdr->avp_value->u32) + + /* IMS-Information */ + PARSE_GRPAVP_STR(groupedavp_sub, subscription_id_data, avp, avphdr, "Parse CCR Parse CCR IMS-Information", avphdr->avp_value->os.data) +// if(strlen(avphdr->avp_value->os.data)) +// strcpy(gy_ccr->caller, avphdr->avp_value->os.data); + } + } + + /* Service-Identifier */ + PARSE_AVP_U32(ccr_msg, service_identifier, avp, avphdr, "Parse CCR Service-Identifier", avphdr->avp_value->u32) + + /* Multiple-Services-Indicator */ + PARSE_AVP_U32(ccr_msg, multiple_services_indicator, avp, avphdr, "Parse CCR Multiple-Services-Indicator", avphdr->avp_value->u32) + + /* Multiple-Services-Credit-Control */ + //gy_ptr->msg_body.ccr.mscc_presented = 0; + struct dict_object *multiple_services_credit_control = NULL; + SEARCH_AVP_("Multiple-Services-Credit-Control", 0, &multiple_services_credit_control); + CHECK_FCT( fd_msg_search_avp ( ccr_msg, multiple_services_credit_control, &groupedavp) ); + gy_ptr->rating_group = 100;// init to 100(huawei PNCC) + gy_ptr->service_identifier = -1;// init to -1(invalid, huawei PNCC) + gy_ptr->msg_body.ccr.reporting_reason = -1;// init to -1 + if(groupedavp != NULL) + { + LOG_N("fj Parse CCR Multiple-Services-Credit-Control"); + + //gy_ptr->msg_body.ccr.mscc_presented = 1; + /* Requested-Service-Unit */ + struct dict_object *requested_service_unit = NULL; + SEARCH_AVP_("Requested-Service-Unit", 0, &requested_service_unit); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp, requested_service_unit, &groupedavp_sub) ); + if(groupedavp_sub != NULL) + { + /* CC-Time */ + /*struct dict_object *cc_time = NULL; + SEARCH_AVP_("CC-Time", 0, &cc_time); + PARSE_GRPAVP_U32(groupedavp_sub, cc_time, avp, avphdr, "Parse CCR CC-Time", avphdr->avp_value->u32)*/ + } + + /* Used-Service-Unit */ + struct dict_object *used_service_unit = NULL; + SEARCH_AVP_("Used-Service-Unit", 0, &used_service_unit); + CHECK_FCT( fd_sh_avp_search_avp ( groupedavp, used_service_unit, &groupedavp_sub) ); + if(groupedavp_sub != NULL) + { + if(gy_ptr->service_type == ST_CS_VOICE) + { + /* CC-Time */ + struct dict_object *cc_time = NULL; + SEARCH_AVP_("CC-Time", 0, &cc_time); + PARSE_GRPAVP_U32(groupedavp_sub, cc_time, avp, avphdr, "Parse CCR CC-Time", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->msg_body.ccr.used_unit = avphdr->avp_value->u32; + } + } + else if(gy_ptr->service_type == ST_PS_DATA) + { + /* CC-Total-Octets */ + struct dict_object *cc_total_octets = NULL; + SEARCH_AVP_("CC-Total-Octets", 0, &cc_total_octets); + PARSE_GRPAVP_U32(groupedavp_sub, cc_total_octets, avp, avphdr, "Parse CCR CC-Total-Octets", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->msg_body.ccr.used_unit = avphdr->avp_value->u32; + } + + /* Reporting-Reason */ + struct dict_object *reporting_reason = NULL; + avphdr = NULL; + SEARCH_AVP_("Reporting-Reason", 10415, &reporting_reason); + PARSE_GRPAVP_U32(groupedavp_sub, reporting_reason, avp, avphdr, "Parse CCR Reporting-Reason", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->msg_body.ccr.reporting_reason = avphdr->avp_value->u32; + } + } + + } + + /* Service-Identifier */ + struct dict_object *service_id = NULL; + avphdr = NULL; + SEARCH_AVP_("Service-Identifier", 0, &service_id); + PARSE_GRPAVP_U32(groupedavp, service_id, avp, avphdr, "Parse CCR Service-Identifier", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->service_identifier = avphdr->avp_value->u32; + } + + /* Rating-Group */ + struct dict_object *rating_group = NULL; + avphdr = NULL; + SEARCH_AVP_("Rating-Group", 0, &rating_group); + PARSE_GRPAVP_U32(groupedavp, rating_group, avp, avphdr, "Parse CCR Rating-Group", avphdr->avp_value->u32) + if (avphdr != NULL) + { + gy_ptr->rating_group = avphdr->avp_value->u32; + } + + /* Reporting-Reason */ + struct dict_object *reporting_reason = NULL; + avphdr = NULL; + SEARCH_AVP_("Reporting-Reason", 10415, &reporting_reason); + PARSE_GRPAVP_U32(groupedavp, reporting_reason, avp, avphdr, "Parse CCR Reporting-Reason", avphdr->avp_value->u32) + //if (avphdr != NULL) + //{ + // gy_ptr->msg_body.ccr.reporting_reason = avphdr->avp_value->u32; + //} + } + +// strcpy(gy_ptr->cxt_id, gy_ccr->caller); +out: + LOG_N("fj Parse CCR exit"); + return 0; +} + +struct msg *g_direct_cca_fail_msg_ptr = NULL; +struct msg *g_ccr_msg_ptr[MAX_GY_PORT+1]; +struct msg *g_ccr_msg_ptr_ptr[MAX_GY_PORT+1]; +int gx_send_cca_test() +{ + struct msg *ans; + struct avp *avp = NULL; + struct avp *grpavp = NULL; + struct avp *grpavp_sub1 = NULL; + union avp_value val; + //struct dict_object *dict_obj_tmp = NULL; + + ans = g_ccr_msg_ptr[0]; + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( ans, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + msg_hdr->msg_flags = msg_hdr->msg_flags & (~CMD_FLAG_PROXIABLE); + + } + + /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ + CHECK_FCT_DO( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ), goto out ); + + /* Get the auth_app_id and from the reply and set it in the reply */ + EN_AVP_U32(auth_app_id, 4, ans, "fj CCA Auth-Application-ID"); + EN_AVP_U32(cc_req_type, 1, ans, "fj CCA cc_req_type"); + EN_AVP_U32(cc_req_num, 0, ans, "fj CCA cc_req_num"); + + /* Multiple-Services-Credit-Control */ + { + CHECK_FCT_DO( fd_msg_avp_new ( multiple_services_credit_control, 0, &grpavp ), goto out ); + + /* Result-Code */ + struct dict_object *result_code = NULL; + EN_GRPAVP_U32("Result-Code", 0, result_code, 2001); + + /* Granted-Service-Unit */ + struct dict_object *granted_service_unit = NULL; + SEARCH_AVP_("Granted-Service-Unit", 0, &granted_service_unit); + { + CHECK_FCT_DO( fd_msg_avp_new ( granted_service_unit, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("CC-Time", 0, cc_time, 1/*granted_value*/, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + LOG_D("fj CCA Granted-Service-Unit Ok\n"); + } + + CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("fj CCA Multiple-Services-Credit-Control Ok\n"); + } + + /* Send the answer */ + CHECK_FCT_DO( fd_msg_send((struct msg **)(g_ccr_msg_ptr_ptr), NULL, NULL ), goto out ); + +out: + return 1; +} + +int gx_send_cca(_gy_msg *gy_ptr) +{ + //struct msg *req = NULL; + struct msg *ans;//, *qry; + struct avp *avp = NULL; + struct avp *grpavp = NULL; + struct avp *grpavp_sub1 = NULL; + union avp_value val; + //struct dict_object *dict_obj_tmp = NULL; + struct msg **pAnsPtr = NULL; + //int ret; + + long granted_value = gy_ptr->msg_body.cca.grant_value; + int port = gy_ptr->fd_port; + _gy_port *gy_port = NULL; + long valid_time_len = 900; + + gy_port = gy_get_port_space(port); + if(gy_port == NULL) + return 0; + gy_port->app_port = gy_ptr->app_port; + + gy_port->updated_ts = ts_sec; + + if (pps_debug_flag_for_fd()) + { + char tmp_buf[256]; + sprintf(tmp_buf, " [%04d] %s , app_port=%d, gy_port=%d", + port, __FUNCTION__, gy_ptr->app_port, gy_port->index); + pps_debug_info("diameter", tmp_buf); + } + + gx_stat_increase_send_cca(gy_ptr->request_type); + + ans = g_ccr_msg_ptr[port]; + + //memset(ans, 0x00, sizeof(ans)); +// CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &ans, 0 ) , goto out); + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( ans, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + msg_hdr->msg_flags = msg_hdr->msg_flags | (CMD_FLAG_PROXIABLE); + } + + /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ + if (gy_ptr->request_type == RT_EVENT_REQUEST) + { + EN_AVP_U32(result_code, gy_ptr->msg_body.cca.result, ans, "fj CCA Result-Code"); + } + /*else if (gy_ptr->msg_body.ccr.mscc_presented==0) + { + int result = gy_ptr->msg_body.cca.result; + if (result < 2001) + { + result = 2001; + } + else if (resutl == 4012) + { + result = 4547; + } + else if (resutl != 2001) + { + result = 5012; + } + EN_AVP_U32(result_code, result, ans, "fj CCA Result-Code"); + }*/ + else + { + CHECK_FCT_DO( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ), goto out ); + } + + /* Get the auth_app_id and from the reply and set it in the reply */ + EN_AVP_U32(auth_app_id, 4, ans, "fj CCA Auth-Application-ID"); + EN_AVP_U32(cc_req_type, gy_ptr->request_type, ans, "fj CCA cc_req_type"); + EN_AVP_U32(cc_req_num, gy_port->request_number++, ans, "fj CCA cc_req_num"); + + if (gy_ptr->request_type == RT_EVENT_REQUEST) + { + if ((gy_ptr->msg_body.ccr.request_action == RA_CHECK_BALANCE)\ + && (gy_ptr->msg_body.cca.result == 2001))// only support CHECK_BALANCE in event request + { + EN_AVP_U32(check_balance_result, gy_ptr->msg_body.cca.check_balance_result, ans, "fj CCA check_balance_result"); + } + } + else// if (gy_ptr->msg_body.ccr.mscc_presented) + /* Multiple-Services-Credit-Control */ + { + CHECK_FCT_DO( fd_msg_avp_new ( multiple_services_credit_control, 0, &grpavp ), goto out ); + + /* Result-Code */ + struct dict_object *result_code = NULL; + if(gy_ptr->msg_body.cca.result < 2001) + gy_ptr->msg_body.cca.result = 2001; + EN_GRPAVP_U32("Result-Code", 0, result_code, gy_ptr->msg_body.cca.result); + + if(gy_ptr->msg_body.cca.is_final && gy_ptr->msg_body.cca.result == 2001) //only successful result can contain this AVP + { + struct dict_object *final_unit_indication = NULL; + SEARCH_AVP_("Final-Unit-Indication", 0, &final_unit_indication); + { + CHECK_FCT_DO( fd_msg_avp_new ( final_unit_indication, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("Final-Unit-Action", 0, final_unit_action, 0, grpavp_sub1)// 0, fixed to terminate + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + LOG_D("fj CCA Final-Unit-Indication Ok\n"); + } + + } + + struct dict_object *rate_group = NULL; + EN_GRPAVP_U32("Rating-Group", 0, rate_group, gy_ptr->rating_group); //fixed for COOK, should be the same as CCR + + if(gy_ptr->service_identifier >= 0)// huawei has no si in CCR, and should not include si in CCA; iplook has si in CCR, and should include si in CCA. + { + struct dict_object *service_id = NULL; + EN_GRPAVP_U32("Service-Identifier", 0, service_id, gy_ptr->service_identifier); + } + + struct dict_object *valid_time = NULL; + EN_GRPAVP_U32("Validity-Time", 0, valid_time, valid_time_len); + + if (gy_ptr->request_type != RT_TERMINATE_REQUEST) + { + /* Granted-Service-Unit */ + struct dict_object *granted_service_unit = NULL; + SEARCH_AVP_("Granted-Service-Unit", 0, &granted_service_unit); + { + CHECK_FCT_DO( fd_msg_avp_new ( granted_service_unit, 0, &grpavp_sub1 ), goto out ); + if(gy_port->service_type == ST_PS_DATA) + { + EN_GRPAVP_U64_("CC-Total-Octets", 0, cc_total_octects, granted_value, grpavp_sub1) + /*if (granted_value > 0) + { + EN_GRPAVP_U32_("CC-Time", 0, cc_time, 2400, grpavp_sub1) + } + else + { + EN_GRPAVP_U32_("CC-Time", 0, cc_time, 0, grpavp_sub1) + }*/ + } + else + EN_GRPAVP_U32_("CC-Time", 0, cc_time, granted_value, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + LOG_D("fj CCA Granted-Service-Unit Ok\n"); + } + } + + /*if(granted_value > 0) + { + struct dict_object *time_threshold = NULL; + gy_ptr->msg_body.cca.time_threshold = 60; + EN_GRPAVP_U32("Time-Quota-Threshold", 10415, time_threshold, gy_ptr->msg_body.cca.time_threshold); + }*/ + + if(gy_ptr->request_type != RT_TERMINATE_REQUEST) + { + struct dict_object *volume_threshold = NULL; + EN_GRPAVP_U32("Volume-Quota-Threshold", 10415, volume_threshold, gy_ptr->msg_body.cca.volume_threshold); + + struct dict_object *quota_hold_time = NULL; + EN_GRPAVP_U32("Quota-Holding-Time", 10415, quota_hold_time, gy_ptr->msg_body.cca.time_threshold + 10); + + if(1) + { + struct dict_object *time_threshold = NULL; + EN_GRPAVP_U32("Time-Quota-Threshold", 10415, time_threshold, gy_ptr->msg_body.cca.time_threshold); + } + + } + + CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("fj CCA Multiple-Services-Credit-Control Ok\n"); + } + + /* Send the answer */ + pAnsPtr = &ans; + //CHECK_FCT_DO( fd_msg_send((struct msg **)g_ccr_msg_ptr_ptr[gy_ptr->fd_port], NULL, NULL ), goto out ); + //CHECK_FCT_DO( fd_msg_send(pAnsPtr, NULL, NULL ), goto out ); + fd_msg_send(pAnsPtr, NULL, NULL ); + /*pthread_mutex_lock(&gy_cca_lock); + ret = fd_msg_send(pAnsPtr, NULL, NULL); + pthread_mutex_unlock(&gy_cca_lock); + if (ret != 0) + { + goto out; + }*/ + + if(gy_ptr->msg_body.cca.is_final) + { + gy_release_port(gy_ptr->fd_port); + } +out: + return 1; +} + +static int gx_send_cca_fail(_gy_msg *gy_ptr) +{ + //struct msg *req = NULL; + struct msg *ans;//, *qry; + struct avp *avp = NULL; + struct avp *grpavp = NULL; + struct avp *grpavp_sub1 = NULL; + union avp_value val; + //struct dict_object *dict_obj_tmp = NULL; + struct msg **pAnsPtr = NULL; + //int ret; + + long granted_value = gy_ptr->msg_body.cca.grant_value; + long valid_time_len = 3; + + gx_stat_increase_send_cca(gy_ptr->request_type); + + //ans = g_ccr_msg_ptr[port]; + ans = g_direct_cca_fail_msg_ptr; + + //memset(ans, 0x00, sizeof(ans)); +// CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &ans, 0 ) , goto out); + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( ans, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + msg_hdr->msg_flags = msg_hdr->msg_flags | (CMD_FLAG_PROXIABLE); + } + + /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ + EN_AVP_U32(result_code, 4001, ans, "fj CCA Result-Code");// DIAMETER_AUTHENTICATION_REJECTED + + /* Get the auth_app_id and from the reply and set it in the reply */ + EN_AVP_U32(auth_app_id, 4, ans, "fj CCA Auth-Application-ID"); + EN_AVP_U32(cc_req_type, gy_ptr->request_type, ans, "fj CCA cc_req_type"); + EN_AVP_U32(cc_req_num, gy_ptr->request_number, ans, "fj CCA cc_req_num"); + + if (gy_ptr->request_type == RT_EVENT_REQUEST) + { + if ((gy_ptr->msg_body.ccr.request_action == RA_CHECK_BALANCE)\ + && (gy_ptr->msg_body.cca.result == 2001))// only support CHECK_BALANCE in event request + { + EN_AVP_U32(check_balance_result, gy_ptr->msg_body.cca.check_balance_result, ans, "fj CCA check_balance_result"); + } + } + else + /* Multiple-Services-Credit-Control */ + { + CHECK_FCT_DO( fd_msg_avp_new ( multiple_services_credit_control, 0, &grpavp ), goto out ); + + /* Result-Code */ + struct dict_object *result_code = NULL; + if(gy_ptr->msg_body.cca.result < 2001) + gy_ptr->msg_body.cca.result = 2001; + EN_GRPAVP_U32("Result-Code", 0, result_code, gy_ptr->msg_body.cca.result); + + /*if(gy_ptr->msg_body.cca.is_final && gy_ptr->msg_body.cca.result == 2001) //only successful result can contain this AVP + { + struct dict_object *final_unit_indication = NULL; + SEARCH_AVP_("Final-Unit-Indication", 0, &final_unit_indication); + { + CHECK_FCT_DO( fd_msg_avp_new ( final_unit_indication, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("Final-Unit-Action", 0, final_unit_action, 0, grpavp_sub1)// 0, fixed to terminate + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + LOG_D("fj CCA Final-Unit-Indication Ok\n"); + } + + }*/ + + struct dict_object *rate_group = NULL; + EN_GRPAVP_U32("Rating-Group", 0, rate_group, gy_ptr->rating_group); //fixed for COOK, should be the same as CCR + + if(gy_ptr->service_identifier >= 0)// huawei has no si in CCR, and should not include si in CCA; iplook has si in CCR, and should include si in CCA. + { + struct dict_object *service_id = NULL; + EN_GRPAVP_U32("Service-Identifier", 0, service_id, gy_ptr->service_identifier); + } + + struct dict_object *valid_time = NULL; + EN_GRPAVP_U32("Validity-Time", 0, valid_time, valid_time_len); + + + /* Granted-Service-Unit */ + struct dict_object *granted_service_unit = NULL; + SEARCH_AVP_("Granted-Service-Unit", 0, &granted_service_unit); + { + CHECK_FCT_DO( fd_msg_avp_new ( granted_service_unit, 0, &grpavp_sub1 ), goto out ); + if(gy_ptr->service_type == ST_PS_DATA) + { + EN_GRPAVP_U64_("CC-Total-Octets", 0, cc_total_octects, granted_value, grpavp_sub1) + /*if (granted_value > 0) + { + EN_GRPAVP_U32_("CC-Time", 0, cc_time, 2400, grpavp_sub1) + } + else + { + EN_GRPAVP_U32_("CC-Time", 0, cc_time, 0, grpavp_sub1) + }*/ + } + else + EN_GRPAVP_U32_("CC-Time", 0, cc_time, granted_value, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + LOG_D("fj CCA Granted-Service-Unit Ok\n"); + } + + /*if(granted_value > 0) + { + struct dict_object *time_threshold = NULL; + gy_ptr->msg_body.cca.time_threshold = 60; + EN_GRPAVP_U32("Time-Quota-Threshold", 10415, time_threshold, gy_ptr->msg_body.cca.time_threshold); + }*/ + + /*if(gy_ptr->request_type != RT_TERMINATE_REQUEST) + { + struct dict_object *volume_threshold = NULL; + EN_GRPAVP_U32("Volume-Quota-Threshold", 10415, volume_threshold, gy_ptr->msg_body.cca.volume_threshold); + + struct dict_object *quota_hold_time = NULL; + EN_GRPAVP_U32("Quota-Holding-Time", 10415, quota_hold_time, 750); + }*/ + + CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("fj CCA Multiple-Services-Credit-Control Ok\n"); + } + + /* Send the answer */ + pAnsPtr = &ans; + //CHECK_FCT_DO( fd_msg_send((struct msg **)g_ccr_msg_ptr_ptr[gy_ptr->fd_port], NULL, NULL ), goto out ); + //CHECK_FCT_DO( fd_msg_send(pAnsPtr, NULL, NULL ), goto out ); + fd_msg_send(pAnsPtr, NULL, NULL ); + /*pthread_mutex_lock(&gy_cca_lock); + ret = fd_msg_send(pAnsPtr, NULL, NULL); + pthread_mutex_unlock(&gy_cca_lock); + if (ret != 0) + { + goto out; + }*/ + + /*if(gy_ptr->msg_body.cca.is_final) + { + gy_release_port(gy_ptr->fd_port); + }*/ +out: + return 1; +} + +int gx_send_ccr_real(struct gx_sm_t **sm , struct dict_object *cmd_r, _gy_msg *msg_ptr) +{ + struct msg *req = NULL; + struct avp *avp = NULL; + struct avp *grpavp = NULL; + struct avp *grpavp_sub1 = NULL; + struct avp *grpavp_sub2 = NULL; + struct avp *grpavp_sub3 = NULL; +#if PS_ENABLED + struct avp *grpavp_sub4 = NULL; +#endif + union avp_value val; + struct session *sess = NULL; + struct gx_sm_t *gx_sm = NULL; + struct dict_object *dict_obj_tmp = NULL; + char tmp_buf[128], value_buf[128]; + struct in_addr hostAddr; + hostAddr.s_addr = GetLocalIP(); + char* phostAddr = inet_ntoa(hostAddr); + + int port = msg_ptr->fd_port; + //int cxt_port; + _gy_port *gy_port = NULL; + int tmp_len =0, len; + + gy_port = gy_get_port_space(port); + if(gy_port == NULL) + return 0; + + gy_port->updated_ts = ts_sec; + gy_port->app_port = msg_ptr->app_port; + //cxt_port = gy_port->cxt_port; + + LOG_N("fj gx_send_ccr_real enter"); + + gx_stat_increase_send_ccr(msg_ptr->request_type); + + /* Create the request from template */ + CHECK_FCT_DO( fd_msg_new( cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out1 ); + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( req, &msg_hdr ) ); + msg_hdr->msg_flags = msg_hdr->msg_flags & (~CMD_FLAG_PROXIABLE); + } + + gx_sm = *sm; + /* Create a new session */ + // if(!gx_sm->sess) + if(gy_sess[gy_port->index] == NULL) + { + CHECK_FCT_DO( fd_sess_new( &sess, + fd_g_config->cnf_diamid, + fd_g_config->cnf_diamid_len, + (uint8_t *)("CCR_SESSION"), + strlen("CCR_SESSION") ), goto out ); + + gy_sess[gy_port->index] = sess; + //Hold the session till terminate happens + CHECK_FCT( fd_sess_ref_msg(sess) ); + } + else + { + //sess = gx_sm->sess; + sess = gy_sess[gy_port->index]; + printf("use previous session %p \n", sess); + } + + // fd_sess_dump( 0 , sess); + + // dump_sess_eyec( sess, __FUNCTION__); + /* Now set all AVPs values */ + + /* Session-Id */ + { + os0_t sid; + size_t sidlen; + struct dict_object *sess_id = NULL; + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id, ENOENT) ); + + CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out ); + CHECK_FCT_DO( fd_msg_avp_new ( sess_id, 0, &avp ), goto out ); + val.os.data = sid; + val.os.len = sidlen; + + fd_get_session_id((char *)val.os.data, tmp_buf, 0); + fd_update_cxt_id(port, tmp_buf); + + printf("\r\ncxt_port=%d, app_port=%d, session id=%s\r\n", port, gy_port->app_port, tmp_buf); + + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out ); + } + + char *pRealm = g_sh_conf_ext.pi_diamid_realm_peer, *pHost = g_sh_conf_ext.pi_diamid_peer; + if ((msg_ptr->service_type == ST_CS_SMS) || (msg_ptr->service_type == ST_CS_VOICE)) + { + GetRoDiamIdPeer(&pRealm, &pHost, (msg_ptr->service_type == ST_CS_SMS)?1:0); + } + if (pRealm == NULL || pHost == NULL) + { + LOG_N("fj gx_send_ccr_real, no link available, pRealm[%p], pHost[%p]", pRealm, pHost); + return 0; + } + /*if ((msg_ptr->service_type == ST_CS_SMS) && (g_rosms_conf_ext.pi_diamid_realm_peer!=NULL) && (g_rosms_conf_ext.pi_diamid_peer!=NULL)) + { + pRealm = g_rosms_conf_ext.pi_diamid_realm_peer; + pHost = g_rosms_conf_ext.pi_diamid_peer; + } + else if ((msg_ptr->service_type == ST_CS_VOICE) && (g_rovoice_conf_ext.pi_diamid_realm_peer!=NULL) && (g_rovoice_conf_ext.pi_diamid_peer!=NULL)) + { + pRealm = g_rovoice_conf_ext.pi_diamid_realm_peer; + pHost = g_rovoice_conf_ext.pi_diamid_peer; + }*/ + + /* Destination-Realm */ + EN_AVP_STR(dest_realm, pRealm, req, "fj CCR Destination-Realm Ok"); + + /* Destination-Host */ + EN_AVP_STR(dest_host, pHost, req, "fj CCR Destination-Host-Ok"); + + /* Origin-Host & Origin-Realm */ + CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out ); + + /* Auth-Application-Id */ + EN_AVP_U32(auth_app_id, 4, req, "fj CCR Auth-Application-ID"); + + /* Service-Context-ID */ + if(msg_ptr->service_type == ST_CS_SMS) + { + //EN_AVP_STR(service_cxt_id, "agrandtech_sms@3gpp.org", req, "fj CCR Service-Context-ID Ok"); + EN_AVP_STR(service_cxt_id, fd_g_config->service_context_sms, req, "fj CCR Service-Context-ID Ok"); + //EN_AVP_STR(route_record, "ocsclient.seagullCTF.org", req , "fj CCR Route-Record OK"); + } + else + { + //EN_AVP_STR(service_cxt_id, "agrandtech_ro@3gpp.org", req, "fj CCR Service-Context-ID Ok"); + EN_AVP_STR(service_cxt_id, fd_g_config->service_context_voice, req, "fj CCR Service-Context-ID Ok"); + } + + /* CC-Request-Type */ + { +#define CCR_INIT_REQUEST 1 +#define CCR_UPDATE_REQUEST 2 +#define CCR_TERMINATION_REQUEST 3 +#define CCR_EVENT_REQUEST 4 + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( cc_req_type, 0, &avp ), goto out ); + /* + if(gx_sm->state == STATE_INIT) + val.i32 = CCR_INIT_REQUEST; + else if(gx_sm->state == STATE_FINAL) + val.i32 = CCR_TERMINATION_REQUEST; + else + val.i32 = CCR_UPDATE_REQUEST; + */ + if(msg_ptr->request_type>RT_EVENT_REQUEST) + val.i32 = RT_EVENT_REQUEST; + else + val.i32 = msg_ptr->request_type; + + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + + /* CC-Requested-Action */ + if(msg_ptr->service_type == ST_CS_SMS) + EN_AVP_U32(requested_action, msg_ptr->msg_body.ccr.request_action, req, "fj CCR Requested-Action"); + + /* CC-Request-Number */ + EN_AVP_U32(cc_req_num, msg_ptr->request_number, req, "fj CCR CC-Request-Number"); + + /* Event-Timestamp */ + + time_t_to_diameter_timestamp(tmp_buf); + EN_AVP_BCDSTR(event_timestamp, tmp_buf, 4, req, "fj CCR Event-Timestamp"); + + /* Subscription-Id */ + { + int offset = 0; + if(msg_ptr->msg_body.ccr.role_of_node == 0) + { + if(msg_ptr->msg_body.ccr.caller[0] == '+') + offset = 1; + sprintf(tmp_buf, "%s", &msg_ptr->msg_body.ccr.caller[offset]); + } + else if(msg_ptr->msg_body.ccr.role_of_node == 1) + { + if(msg_ptr->msg_body.ccr.called[0] == '+') + offset = 1; + + sprintf(tmp_buf, "%s", &msg_ptr->msg_body.ccr.called[offset]); + } + else if(msg_ptr->msg_body.ccr.role_of_node == 2) + { + if(msg_ptr->msg_body.ccr.caller[0] == '+') + offset = 1; + + sprintf(tmp_buf, "%s", &msg_ptr->msg_body.ccr.caller[offset]); + } + + CHECK_FCT_DO( fd_msg_avp_new ( subscription_id, 0, &grpavp ), goto out ); + + EN_GRPAVP_U32_("Subscription-Id-Type", 0, subscription_id_type, 0, grpavp); + EN_GRPAVP_STR("Subscription-Id-Data", 0, subscription_id_data, tmp_buf, grpavp); + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + if(1) + { + tmp_len = strlen(msg_ptr->msg_body.ccr.imsi); + if(tmp_len>4) + { + strcpy(tmp_buf, msg_ptr->msg_body.ccr.imsi); + CHECK_FCT_DO( fd_msg_avp_new ( subscription_id, 0, &grpavp ), goto out ); + + EN_GRPAVP_U32_("Subscription-Id-Type", 0, subscription_id_type, 1, grpavp); + EN_GRPAVP_STR("Subscription-Id-Data", 0, subscription_id_data, tmp_buf, grpavp); + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + } + } + + } + + /* Service-Information */ + { + CHECK_FCT_DO( fd_msg_avp_new ( service_information, 0, &grpavp ), goto out ); + + /* AoC-Information */ + /* SMS-Information */ + + if(msg_ptr->service_type == ST_CS_SMS) + { + + struct dict_object *SMS_Information = NULL; + SEARCH_AVP_("SMS-Information", SH_VND_ID, &SMS_Information); + CHECK_FCT_DO( fd_msg_avp_new ( SMS_Information, 0, &grpavp_sub1 ), goto out); + + EN_GRPAVP_U32_("SMS-Node", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1) + /* + EN_GRPAVP_U32_("SM-Message-Type", SH_VND_ID, dict_obj_tmp, 0, grpavp_sub1) + */ + EN_GRPAVP_U32_("Number-Of-Messages-Sent", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub1) + /* + EN_GRPAVP_U32_("SM-Service-Type", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub1) + */ + EN_GRPAVP_STR("SMSC-Address", SH_VND_ID, dict_obj_tmp, msg_ptr->msg_body.ccr.smsc, grpavp_sub1) + + /* + struct dict_object *SMSC_Address = NULL; + SEARCH_AVP_("SMSC-Address", SH_VND_ID, &SMSC_Address); + CHECK_FCT_DO( fd_msg_avp_new ( SMSC_Address, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("Address-Type", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_STR("Address-Data", SH_VND_ID, dict_obj_tmp, msg_ptr->msg_body.ccr.smsc, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + */ + struct dict_object *Originator_Received_Address = NULL; + SEARCH_AVP_("Originator-Received-Address", SH_VND_ID, &Originator_Received_Address); + CHECK_FCT_DO( fd_msg_avp_new ( Originator_Received_Address, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("Address-Type", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_STR("Address-Data", SH_VND_ID, dict_obj_tmp, msg_ptr->msg_body.ccr.caller, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + struct dict_object *Recipient_Info = NULL; + SEARCH_AVP_("Recipient-Info", SH_VND_ID, &Recipient_Info); + CHECK_FCT_DO( fd_msg_avp_new ( Recipient_Info, 0, &grpavp_sub2 ), goto out); + { + struct dict_object *Recipient_Address = NULL; + SEARCH_AVP_("Recipient-Address", SH_VND_ID, &Recipient_Address); + CHECK_FCT_DO( fd_msg_avp_new ( Recipient_Address, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("Address-Type", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_STR("Address-Data", SH_VND_ID, dict_obj_tmp, msg_ptr->msg_body.ccr.called, grpavp_sub3) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + if(msg_ptr->msg_body.ccr.cellid_presented == 1) + { + + /* fj added 2021.2.24 for OCS CCR witch avp Service-Specific-Info */ + struct dict_object *service_specific_info = NULL; + SEARCH_AVP_("Service-Specific-Info", SH_VND_ID, &service_specific_info); + CHECK_FCT_DO( fd_msg_avp_new ( service_specific_info, 0, &grpavp_sub2 ), goto out); + { /* ¸ù¾ÝÐèÒªÓ¦ÓòãÌîÈë²ÎÊý */ + EN_GRPAVP_U32_("Service-Specific-Type", SH_VND_ID, dict_obj_tmp, 6006, grpavp_sub2) + EN_GRPAVP_STR("Service-Specific-Data", SH_VND_ID, dict_obj_tmp, msg_ptr->msg_body.ccr.cellid, grpavp_sub2) + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + } + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + } + else /* IMS-Information */ + { + CHECK_FCT_DO( fd_msg_avp_new ( ims_information, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("Node-Functionality", SH_VND_ID, dict_obj_tmp, 6, grpavp_sub1) + + + if(msg_ptr->msg_body.ccr.cellid_presented == 1) + { + + /* fj added 2021.2.24 for OCS CCR witch avp Service-Specific-Info */ + struct dict_object *service_specific_info = NULL; + SEARCH_AVP_("Service-Specific-Info", SH_VND_ID, &service_specific_info); + CHECK_FCT_DO( fd_msg_avp_new ( service_specific_info, 0, &grpavp_sub2 ), goto out); + { /* ¸ù¾ÝÐèÒªÓ¦ÓòãÌîÈë²ÎÊý */ + EN_GRPAVP_U32_("Service-Specific-Type", SH_VND_ID, dict_obj_tmp, 6006, grpavp_sub2) + EN_GRPAVP_STR("Service-Specific-Data", SH_VND_ID, dict_obj_tmp, msg_ptr->msg_body.ccr.cellid, grpavp_sub2) + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + } + + struct dict_object *event_type = NULL; + SEARCH_AVP_("Event-Type", SH_VND_ID, &event_type); + CHECK_FCT_DO( fd_msg_avp_new ( event_type, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("SIP-Method", SH_VND_ID, dict_obj_tmp, "INVITE", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_U32_("Role-of-Node", SH_VND_ID, dict_obj_tmp, msg_ptr->msg_body.ccr.role_of_node, grpavp_sub1) + + sprintf( tmp_buf,"%04d.agt@%s", msg_ptr->fd_port, phostAddr ); + EN_GRPAVP_STR("User-Session-Id", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1) + + /* Time-Stamps */ + CHECK_FCT_DO( fd_msg_avp_new ( time_stamps, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("SIP-Request-Timestamp", SH_VND_ID, dict_obj_tmp, "3580", grpavp_sub2) + EN_GRPAVP_STR("SIP-Response-Timestamp", SH_VND_ID, dict_obj_tmp, "3580", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Inter-Operator-Identifier */ + struct dict_object *inter_operator_identifier = NULL; + SEARCH_AVP_("Inter-Operator-Identifier", SH_VND_ID, &inter_operator_identifier); + CHECK_FCT_DO( fd_msg_avp_new ( inter_operator_identifier, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("Originating-IOI", SH_VND_ID, dict_obj_tmp, fd_g_config->cnf_diamid, grpavp_sub2) + +// EN_GRPAVP_STR("Originating-IOI", SH_VND_ID, dict_obj_tmp, "agrandtech_ocs@3gpp.org", grpavp_sub2) + EN_GRPAVP_STR("Terminating-IOI", SH_VND_ID, dict_obj_tmp, pHost, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_STR("IMS-Charging-Identifier", SH_VND_ID, dict_obj_tmp, "286eae5698fb00530e05090ffee03c60.3580811571.1100844.12", grpavp_sub1) + + if(msg_ptr->service_type != ST_CS_SMS) + { + + sprintf(tmp_buf, "v=0 o=- 26967515390 IN IP4 %s s=SBC call c=IN IP4 %s t=0 0", phostAddr, phostAddr); + EN_GRPAVP_STR("SDP-Session-Description", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1) + + /* SDP-Media-Component */ + struct dict_object *sdp_media_component = NULL; + SEARCH_AVP_("SDP-Media-Component", SH_VND_ID, &sdp_media_component); + CHECK_FCT_DO( fd_msg_avp_new ( sdp_media_component, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("SDP-Media-Name", SH_VND_ID, dict_obj_tmp, "audio 19556 RTP/AVP 8 101", grpavp_sub2) + EN_GRPAVP_STR("SDP-Media-Description", SH_VND_ID, dict_obj_tmp, " a=rtpmap:8 PCMA/8000 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15 a=ptime:20 a=sendrecv", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Message-Body */ + struct dict_object *message_body = NULL; + SEARCH_AVP_("Message-Body", SH_VND_ID, &message_body); + CHECK_FCT_DO( fd_msg_avp_new ( message_body, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("Content-Type", SH_VND_ID, dict_obj_tmp, "application/sdp", grpavp_sub2) + EN_GRPAVP_U32_("Content-Length", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + + LOG_D("fj CCR Message-Body Ok\n"); + } + } + + if(msg_ptr->msg_body.ccr.cellid_presented == 1) + { + if (msg_ptr->msg_body.ccr.cellid[3] == 'F') + { + char mcc[8]=""; + strncpy(mcc, msg_ptr->msg_body.ccr.cellid, 3); + sprintf(tmp_buf, "3GPP-GERAN;cgi-3gpp=%s%s", mcc, &msg_ptr->msg_body.ccr.cellid[4]); + } + else + { + sprintf(tmp_buf, "3GPP-GERAN;cgi-3gpp=%s", msg_ptr->msg_body.ccr.cellid); + } + } + else + { + sprintf(tmp_buf, "XDSL;'location-info=%s'", phostAddr ); + } + EN_GRPAVP_STR("Access-Network-Information", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1) + + if(msg_ptr->msg_body.ccr.role_of_node == 2) + sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.origin_caller); + else + sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.caller); + + // sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.caller); + EN_GRPAVP_STR("Calling-Party-Address", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1) + + sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.called); + EN_GRPAVP_STR("Called-Party-Address", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1) + /* + if(msg_ptr->msg_body.ccr.role_of_node == 0) + { + sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.caller); + } + else + { + sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.called); + } + EN_GRPAVP_STR("Requested-Party-Address", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1) + */ + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + } + +#if PS_ENABLED + /* PS-Information */ + struct dict_object *ps_information = NULL; + SEARCH_AVP_("PS-Information", SH_VND_ID, &ps_information); + { + CHECK_FCT_DO( fd_msg_avp_new ( ps_information, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("3GPP-Charging-Id", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub1); + EN_GRPAVP_U32_("PDN-Connection-ID", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub1); + EN_GRPAVP_STR("Node-Id", SH_VND_ID, dict_obj_tmp, "Node-Id", grpavp_sub1); + EN_GRPAVP_U32_("3GPP-PDP-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + EN_GRPAVP_STR("PDP-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_U32_("Dynamic-Address-Flag", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + /* QoS-Information */ + struct dict_object *qos_information = NULL; + SEARCH_AVP_("QoS-Information", SH_VND_ID, &qos_information); + CHECK_FCT_DO( fd_msg_avp_new ( qos_information, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("QoS-Class-Identifier", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_U32_("Max-Requested-Bandwidth-UL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub2) + EN_GRPAVP_U32_("Guaranteed-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub2) + EN_GRPAVP_U32_("Guaranteed-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub2) + EN_GRPAVP_STR("Bearer-Identifier", SH_VND_ID, dict_obj_tmp, "Bearer-Identifier", grpavp_sub2) + + /* Allocation-Retention-Priority */ + struct dict_object *allocation_retention_priority = NULL; + SEARCH_AVP_("Allocation-Retention-Priority", SH_VND_ID, &allocation_retention_priority); + CHECK_FCT_DO( fd_msg_avp_new ( allocation_retention_priority, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("Priority-Level", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("Pre-emption-Capability", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + EN_GRPAVP_U32_("Pre-emption-Vulnerability", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub2) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 6, grpavp_sub2) + + /* Conditional-APN-Aggregate-Max-Bitrate */ + struct dict_object *conditional_apn_aggregate_max_btrate = NULL; + SEARCH_AVP_("Conditional-APN-Aggregate-Max-Bitrate", SH_VND_ID, &conditional_apn_aggregate_max_btrate); + CHECK_FCT_DO( fd_msg_avp_new ( conditional_apn_aggregate_max_btrate, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + EN_GRPAVP_U32_("IP-CAN-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + EN_GRPAVP_U32_("RAT-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_STR("SGSN-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_STR("GGSN-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_STR("SGW-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_STR("CG-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_U32_("Serving-Node-Type", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + EN_GRPAVP_U32_("SGW-Change", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + EN_GRPAVP_STR("3GPP-IMSI-MCC-MNC", SH_VND_ID, dict_obj_tmp, "3GPP-IMSI-MCC-MNC", grpavp_sub1); + EN_GRPAVP_U32_("IMSI-Unauthenticated-Flag", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + EN_GRPAVP_STR("3GPP-GGSN-MCC-MNC", SH_VND_ID, dict_obj_tmp, "3GPP-GGSN-MCC-MNC", grpavp_sub1); + EN_GRPAVP_STR("3GPP-NSAPI", SH_VND_ID, dict_obj_tmp, "3GPP-NSAPI", grpavp_sub1); + EN_GRPAVP_STR("Called-Station-Id", 0, dict_obj_tmp, "Called-Station-Id", grpavp_sub1); + EN_GRPAVP_STR("3GPP-Session-Stop-Indicator", SH_VND_ID, dict_obj_tmp, "3GPP-Session-Stop-Indicator", grpavp_sub1); + EN_GRPAVP_STR("3GPP-Selection-Mode", SH_VND_ID, dict_obj_tmp, "3GPP-Selection-Mode", grpavp_sub1); + EN_GRPAVP_STR("3GPP-Charging-Characteristics", SH_VND_ID, dict_obj_tmp, "3GPP-Charging-Characteristics", grpavp_sub1); + EN_GRPAVP_U32_("Charging-Characteristics-Selection-Mode", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub1); + EN_GRPAVP_STR("3GPP-SGSN-MCC-MNC", SH_VND_ID, dict_obj_tmp, "3GPP-SGSN-MCC-MNC", grpavp_sub1); + EN_GRPAVP_STR("3GPP-MS-TimeZone", SH_VND_ID, dict_obj_tmp, "3GPP-MS-TimeZone", grpavp_sub1); + EN_GRPAVP_STR("Charging-Rule-Base-Name", SH_VND_ID, dict_obj_tmp, "Charging-Rule-Base-Name", grpavp_sub1); + EN_GRPAVP_STR("3GPP-User-Location-Info", SH_VND_ID, dict_obj_tmp, "3GPP-User-Location-Info", grpavp_sub1); + + /* User-CSG-Information */ + struct dict_object *user_csg_information = NULL; + SEARCH_AVP_("User-CSG-Information", SH_VND_ID, &user_csg_information); + CHECK_FCT_DO( fd_msg_avp_new ( user_csg_information, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("CSG-Id", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_U32_("CSG-Access-Mode", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub2) + EN_GRPAVP_U32_("CSG-Membership-Indication", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub2) + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_STR("3GPP2-BSID", 5535, dict_obj_tmp, "3GPP2-BSID", grpavp_sub1); + EN_GRPAVP_STR("3GPP-RAT-Type", SH_VND_ID, dict_obj_tmp, "3GPP-RAT-Type", grpavp_sub1); + + /* PS-Furnish-Charging-Information */ + struct dict_object *ps_furnish_charging_information = NULL; + SEARCH_AVP_("PS-Furnish-Charging-Information", SH_VND_ID, &ps_furnish_charging_information); + CHECK_FCT_DO( fd_msg_avp_new ( ps_furnish_charging_information, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("PS-Free-Format-Data", SH_VND_ID, dict_obj_tmp, "PS-Free-Format-Data", grpavp_sub2) + EN_GRPAVP_U32_("PS-Append-Free-Format-Data", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_U32_("PDP-Context-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + LOG_D("fj CCR PDP-Context-Type Ok\n"); + + /* Offline-Charging */ + struct dict_object *offline_charging = NULL; + SEARCH_AVP_("Offline-Charging", SH_VND_ID, &offline_charging); + CHECK_FCT_DO( fd_msg_avp_new ( offline_charging, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("Quota-Consumption-Time", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + /* Time-Quota-Mechanism */ + struct dict_object *time_quota_mechanism = NULL; + SEARCH_AVP_("Time-Quota-Mechanism", SH_VND_ID, &time_quota_mechanism); + CHECK_FCT_DO( fd_msg_avp_new ( time_quota_mechanism, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("Time-Quota-Type", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("Base-Time-Interval", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + EN_GRPAVP_U32_("Envelope-Reporting", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Traffic-Data-Volumes */ + struct dict_object *traffic_data_volumes = NULL; + SEARCH_AVP_("Traffic-Data-Volumes", SH_VND_ID, &traffic_data_volumes); + CHECK_FCT_DO( fd_msg_avp_new ( traffic_data_volumes, 0, &grpavp_sub2 ), goto out ); + { + /* QoS-Information */ + struct dict_object *qos_information = NULL; + SEARCH_AVP_("QoS-Information", SH_VND_ID, &qos_information); + CHECK_FCT_DO( fd_msg_avp_new ( qos_information, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("QoS-Class-Identifier", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("Max-Requested-Bandwidth-UL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + EN_GRPAVP_U32_("Guaranteed-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + EN_GRPAVP_U32_("Guaranteed-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub3) + EN_GRPAVP_STR("Bearer-Identifier", SH_VND_ID, dict_obj_tmp, "Bearer-Identifier", grpavp_sub3) + + /* Allocation-Retention-Priority */ + struct dict_object *allocation_retention_priority = NULL; + SEARCH_AVP_("Allocation-Retention-Priority", SH_VND_ID, &allocation_retention_priority); + CHECK_FCT_DO( fd_msg_avp_new ( allocation_retention_priority, 0, &grpavp_sub4 ), goto out); + { + EN_GRPAVP_U32_("Priority-Level", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub4) + EN_GRPAVP_U32_("Pre-emption-Capability", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub4) + EN_GRPAVP_U32_("Pre-emption-Vulnerability", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub4) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub3, MSG_BRW_LAST_CHILD, grpavp_sub4 ), goto out ); + } + + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub3) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 6, grpavp_sub3) + + /* Conditional-APN-Aggregate-Max-Bitrate */ + struct dict_object *conditional_apn_aggregate_max_btrate = NULL; + SEARCH_AVP_("Conditional-APN-Aggregate-Max-Bitrate", SH_VND_ID, &conditional_apn_aggregate_max_btrate); + CHECK_FCT_DO( fd_msg_avp_new ( conditional_apn_aggregate_max_btrate, 0, &grpavp_sub4 ), goto out); + { + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub4) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub4) + EN_GRPAVP_U32_("IP-CAN-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub4) + EN_GRPAVP_U32_("RAT-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub4) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub3, MSG_BRW_LAST_CHILD, grpavp_sub4 ), goto out ); + } + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + EN_GRPAVP_U64_("Accounting-Input-Octets", 0, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_U64_("Accounting-Input-Packets", 0, dict_obj_tmp, 2, grpavp_sub2) + EN_GRPAVP_U64_("Accounting-Output-Octets", 0, dict_obj_tmp, 3, grpavp_sub2) + EN_GRPAVP_U64_("Accounting-Output-Packets", 0, dict_obj_tmp, 4, grpavp_sub2) + EN_GRPAVP_U32_("Change-Condition", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub2) + EN_GRPAVP_STR("Change-Time", SH_VND_ID, dict_obj_tmp, "1111", grpavp_sub2) + EN_GRPAVP_STR("3GPP-User-Location-Info", SH_VND_ID, dict_obj_tmp, "3GPP-User-Location-Info", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Service-Data-Container */ + + /* User-Equipment-Info */ + struct dict_object *user_equipment_info = NULL; + SEARCH_AVP_("User-Equipment-Info", 0, &user_equipment_info); + CHECK_FCT_DO( fd_msg_avp_new ( user_equipment_info, 0, &grpavp_sub2 ), goto out ); + { + EN_GRPAVP_U32_("User-Equipment-Info-Type", 0, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_STR("User-Equipment-Info-Value", 0, dict_obj_tmp, "User-Equipment-Info-Value", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Terminal-Information */ + + EN_GRPAVP_STR("Start-Time", SH_VND_ID, dict_obj_tmp, "2016-08-10T19:09:30-05:00", grpavp_sub1); + EN_GRPAVP_STR("Stop-Time", SH_VND_ID, dict_obj_tmp, "2016-08-10T19:09:30-05:00 ", grpavp_sub1); + EN_GRPAVP_U32_("Change-Condition", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + EN_GRPAVP_U32_("Diagnostics", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + } + +#endif + + /* fj added 20170218. for ccr.vcs_information */ + /* VCS-Information */ + tmp_len = strlen(msg_ptr->msg_body.ccr.vlr_number); + if(tmp_len == 0) + tmp_len = strlen(msg_ptr->msg_body.ccr.msc_addr); + if(tmp_len) + { + struct dict_object *vcs_information = NULL; + SEARCH_AVP_("VCS-Information", SH_VND_ID, &vcs_information); + { + CHECK_FCT_DO( fd_msg_avp_new ( vcs_information, 0, &grpavp_sub1 ), goto out ); + //if(strlen(msg_ptr->msg_body.ccr.msc_addr)) + { + tmp_len = strlen(msg_ptr->msg_body.ccr.msc_addr); + fdAsciiToBcd((unsigned char *)tmp_buf, &len, msg_ptr->msg_body.ccr.msc_addr, tmp_len); + //sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.msc_addr); + //EN_GRPAVP_STR("MSC-Address", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1); + EN_GRPAVP_STR_BCD("MSC-Address", SH_VND_ID, dict_obj_tmp, tmp_buf, len, grpavp_sub1); + } + + /* Basic-Service-Code */ + struct dict_object *basic_service_code = NULL; + SEARCH_AVP_("Basic-Service-Code", SH_VND_ID, &basic_service_code); + CHECK_FCT_DO( fd_msg_avp_new ( basic_service_code, 0, &grpavp_sub2 ), goto out ); + { + sprintf(value_buf, "%d", 0); + tmp_len = strlen(value_buf); + fdAsciiToBcd((unsigned char *)tmp_buf, &len, value_buf, tmp_len); + //EN_GRPAVP_STR("Bearer-Service", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub2); + EN_GRPAVP_STR_BCD("Bearer-Service", SH_VND_ID, dict_obj_tmp, tmp_buf, len, grpavp_sub2); + + sprintf(value_buf, "%d", msg_ptr->msg_body.ccr.service_key); + tmp_len = strlen(value_buf); + fdAsciiToBcd((unsigned char *)tmp_buf, &len, value_buf, tmp_len); + //EN_GRPAVP_STR("Teleservice", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub2); + EN_GRPAVP_STR_BCD("Teleservice", SH_VND_ID, dict_obj_tmp, tmp_buf, len, grpavp_sub2); + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + //if(strlen(msg_ptr->msg_body.ccr.vlr_number)) + { + tmp_len = strlen(msg_ptr->msg_body.ccr.vlr_number); + fdAsciiToBcd((unsigned char *)tmp_buf, &len, msg_ptr->msg_body.ccr.vlr_number, tmp_len); + //sprintf(tmp_buf, "%s", msg_ptr->msg_body.ccr.vlr_number); + //EN_GRPAVP_STR("VLR-Number", SH_VND_ID, dict_obj_tmp, tmp_buf, grpavp_sub1); + EN_GRPAVP_STR_BCD("VLR-Number", SH_VND_ID, dict_obj_tmp, tmp_buf, len, grpavp_sub1); + } + } + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + } + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("fj CCR Service-Information Ok\n"); + } + + if(msg_ptr->service_type != ST_CS_SMS) + { + /* Service-Identifier */ + EN_AVP_U32(service_identifier, 65534, req, "fj CCR Service-Identifier"); + + /* Multiple-Services-Indicator */ + EN_AVP_U32(multiple_services_indicator, 1, req, "fj CCR Multiple-Services-Indicator"); + + /* Multiple-Services-Credit-Control */ + { + CHECK_FCT_DO( fd_msg_avp_new ( multiple_services_credit_control, 0, &grpavp ), goto out); + + /* Requested-Service-Unit */ + if(msg_ptr->request_type != RT_TERMINATE_REQUEST) + { + CHECK_FCT_DO( fd_msg_avp_new ( requested_service_unit, 0, &grpavp_sub1 ), goto out); + + EN_GRPAVP_U32_("CC-Time", 0, dict_obj_tmp, 60, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out); + } + + /* Used-Service-Unit */ + + if(msg_ptr->msg_body.ccr.used_unit>0 || msg_ptr->request_type == RT_TERMINATE_REQUEST) + { + struct dict_object* used_service_unit = NULL; + SEARCH_AVP_("Used-Service-Unit", 0, &used_service_unit); + { + CHECK_FCT_DO( fd_msg_avp_new ( used_service_unit, 0, &grpavp_sub1 ), goto out); + + EN_GRPAVP_U32_("CC-Time", 0, dict_obj_tmp, msg_ptr->msg_body.ccr.used_unit, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out); + } + } + + if(msg_ptr->request_type == RT_UPDATE_REQUEST) + EN_GRPAVP_U32("Reporting-Reason", SH_VND_ID, reporting_reason, 0); + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + } + } + + /* CC-Correlation-Id */ + + /* User-Equipment-Info */ + + #if 0 + switch(gx_sm->state) { + + case STATE_INIT: + + { + //Set Bearer-Usage + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( bearer_usage, 0, &avp ), goto out ); + val.i32 = 1;//IMS + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + { + //Set Packet Filter Operation + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( pflt_oper, 0, &avp ), goto out ); + val.i32 = 1;//ADDITION + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + struct avp *flt_info = NULL; + { + //Set Packet Filter Information + CHECK_FCT_DO( fd_msg_avp_new ( pflt_info, 0, &flt_info ), goto out ); + + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, flt_info ), goto out ); + } + // Set Packet Filter Identity + { + + CHECK_FCT_DO( fd_msg_avp_new ( pflt_id, 0, &avp ), goto out ); + val.os.data = (unsigned char *)("ID"); + val.os.len = strlen("ID"); + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + if(flt_info) { + CHECK_FCT_DO( fd_msg_avp_add( flt_info, MSG_BRW_LAST_CHILD, avp ), goto out ); + }else { + printf("flt_info NULL\n"); + } + + } + + CHECK_FCT(fd_sess_state_store(g_hdlr, sess, &gx_sm)); + + break; + case STATE_FINAL: + { + //Set Packet Filter Operation + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( term_cause, 0, &avp ), goto out ); + val.i32 = 1;//Diameter logout + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + break; + default: + printf("State mismatch \n"); + } + #else + /* fj added 20160828: this allow send more than once */ + // CHECK_FCT(fd_sess_state_store(g_hdlr, sess, &gx_sm)); + #endif + fflush(stderr); + + /* Send the request */ + //printf("CCA %p\n",req); + // Everthing Done Store the state: reply should retreive it + CHECK_FCT_DO( fd_msg_send( &req, gx_rec_cca, NULL ), goto out ); + +out: + if(req != NULL) + fd_msg_free(req); +out1: + return 1; +} + +int gx_send_ccr(struct gx_sm_t **sm , struct dict_object *cmd_r ) +{ + struct msg *req = NULL; + struct avp *avp = NULL; + struct avp *grpavp = NULL; + struct avp *grpavp_sub1 = NULL; + struct avp *grpavp_sub2 = NULL; + struct avp *grpavp_sub3 = NULL; + struct avp *grpavp_sub4 = NULL; + union avp_value val; + struct session *sess = NULL; + struct gx_sm_t *gx_sm = NULL; + struct dict_object *dict_obj_tmp = NULL; + + fprintf(stderr, "ECHO ccr send from done...\n"); + + LOG_N("fj gx_send_ccr enter"); + + /* Create the request from template */ + CHECK_FCT_DO( fd_msg_new( cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out ); + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( req, &msg_hdr ) ); + msg_hdr->msg_flags = msg_hdr->msg_flags | (CMD_FLAG_PROXIABLE); + } + + gx_sm = *sm; + /* Create a new session */ + if(!gx_sm->sess) + { + CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (uint8_t *)("CCR_SESSION"), strlen("CCR_SESSION") ), goto out ); + + printf("statemachine: %p %p %p\n", *(&gx_sm), gx_sm , *sm); + gx_sm->sess = sess; + printf("new session %p \n", sess); + //Hold the session till terminate happens + CHECK_FCT( fd_sess_ref_msg(sess) ); + } + else + { + sess = gx_sm->sess; + printf("use previous session %p \n", sess); + } + + // fd_sess_dump( 0 , sess); + + // dump_sess_eyec( sess, __FUNCTION__); + /* Now set all AVPs values */ + + /* Session-Id */ + { + os0_t sid; + size_t sidlen; + struct dict_object *sess_id = NULL; + + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id, ENOENT) ); + + CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out ); + CHECK_FCT_DO( fd_msg_avp_new ( sess_id, 0, &avp ), goto out ); + val.os.data = sid; + val.os.len = sidlen; + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out ); + } + + /* Destination-Realm */ + EN_AVP_STR(dest_realm, g_sh_conf_ext.pi_diamid_realm_peer, req, "fj CCR Destination-Realm Ok"); + + /* Destination-Host */ + EN_AVP_STR(dest_host, g_sh_conf_ext.pi_diamid_peer, req, "fj CCR Destination-Host-Ok"); + + /* Origin-Host & Origin-Realm */ + CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out ); + + /* Auth-Application-Id */ + EN_AVP_U32(auth_app_id, 4, req, "fj CCR Auth-Application-ID"); + + /* Service-Context-ID */ + EN_AVP_STR(service_cxt_id, "32260@3gpp.org", req, "fj CCR Service-Context-ID Ok"); + + /* CC-Request-Type */ + { +#define CCR_INIT_REQUEST 1 +#define CCR_UPDATE_REQUEST 2 +#define CCR_TERMINATION_REQUEST 3 +#define CCR_EVENT_REQUEST 4 + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( cc_req_type, 0, &avp ), goto out ); + if(gx_sm->state == STATE_INIT) + val.i32 = CCR_INIT_REQUEST; + else if(gx_sm->state == STATE_FINAL) + val.i32 = CCR_TERMINATION_REQUEST; + else + val.i32 = CCR_UPDATE_REQUEST; + + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + + /* CC-Request-Number */ + EN_AVP_U32(cc_req_num, gx_sm->req_num, req, "fj CCR CC-Request-Number"); + gx_sm->req_num++; + + /* Event-Timestamp */ + EN_AVP_STR(event_timestamp, "20130721T135252+00", req, "fj CCR Event-Timestamp"); + + /* Subscription-Id */ + { + CHECK_FCT_DO( fd_msg_avp_new ( subscription_id, 0, &grpavp ), goto out ); + + EN_GRPAVP_U32_("Subscription-Id-Type", 0, subscription_id_type, 0, grpavp); + EN_GRPAVP_STR("Subscription-Id-Data", 0, subscription_id_data, "+23412340001", grpavp); + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + } + + /* Service-Information */ + { + CHECK_FCT_DO( fd_msg_avp_new ( service_information, 0, &grpavp ), goto out ); + + /* AoC-Information */ + + /* IMS-Information */ + { + CHECK_FCT_DO( fd_msg_avp_new ( ims_information, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("Node-Functionality", SH_VND_ID, dict_obj_tmp, 6, grpavp_sub1) + + struct dict_object *event_type = NULL; + SEARCH_AVP_("Event-Type", SH_VND_ID, &event_type); + CHECK_FCT_DO( fd_msg_avp_new ( event_type, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("SIP-Method", SH_VND_ID, dict_obj_tmp, "INVITE", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_U32_("Role-of-Node", SH_VND_ID, dict_obj_tmp, 0, grpavp_sub1) + EN_GRPAVP_STR("User-Session-Id", SH_VND_ID, dict_obj_tmp, "sbccOVeV.003P3wh421n1w0HG3ezL@192.168.200.2", grpavp_sub1) + + /* Time-Stamps */ + CHECK_FCT_DO( fd_msg_avp_new ( time_stamps, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("SIP-Request-Timestamp", SH_VND_ID, dict_obj_tmp, "3580", grpavp_sub2) + EN_GRPAVP_STR("SIP-Response-Timestamp", SH_VND_ID, dict_obj_tmp, "3580", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Inter-Operator-Identifier */ + struct dict_object *inter_operator_identifier = NULL; + SEARCH_AVP_("Inter-Operator-Identifier", SH_VND_ID, &inter_operator_identifier); + CHECK_FCT_DO( fd_msg_avp_new ( inter_operator_identifier, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("Originating-IOI", SH_VND_ID, dict_obj_tmp, "spectranet.com.ng", grpavp_sub2) + EN_GRPAVP_STR("Terminating-IOI", SH_VND_ID, dict_obj_tmp, "spectranet.com.ng", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_STR("IMS-Charging-Identifier", SH_VND_ID, dict_obj_tmp, "286eae5698fb00530e05090ffee03c60.3580811571.1100844.12", grpavp_sub1) + EN_GRPAVP_STR("SDP-Session-Description", SH_VND_ID, dict_obj_tmp, " v=0 o=- 26967515390 IN IP4 10.10.80.80 s=SBC call c=IN IP4 10.10.80.80 t=0 0", grpavp_sub1) + + /* SDP-Media-Component */ + struct dict_object *sdp_media_component = NULL; + SEARCH_AVP_("SDP-Media-Component", SH_VND_ID, &sdp_media_component); + CHECK_FCT_DO( fd_msg_avp_new ( sdp_media_component, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("SDP-Media-Name", SH_VND_ID, dict_obj_tmp, "audio 19556 RTP/AVP 8 101", grpavp_sub2) + EN_GRPAVP_STR("SDP-Media-Description", SH_VND_ID, dict_obj_tmp, " a=rtpmap:8 PCMA/8000 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15 a=ptime:20 a=sendrecv", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Message-Body */ + struct dict_object *message_body = NULL; + SEARCH_AVP_("Message-Body", SH_VND_ID, &message_body); + CHECK_FCT_DO( fd_msg_avp_new ( message_body, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("Content-Type", SH_VND_ID, dict_obj_tmp, "application/sdp", grpavp_sub2) + EN_GRPAVP_U32_("Content-Length", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + + LOG_D("fj CCR Message-Body Ok\n"); + } + + EN_GRPAVP_STR("Access-Network-Information", SH_VND_ID, dict_obj_tmp, " XDSL;'location-info=10.10.80.80'", grpavp_sub1) + EN_GRPAVP_STR("Calling-Party-Address", SH_VND_ID, dict_obj_tmp, " tel:+23412340001", grpavp_sub1) + EN_GRPAVP_STR("Called-Party-Address", SH_VND_ID, dict_obj_tmp, " tel:+23412340020", grpavp_sub1) + EN_GRPAVP_STR("Requested-Party-Address", SH_VND_ID, dict_obj_tmp, " tel:012340020", grpavp_sub1) + EN_GRPAVP_U32_("huawei_avp_20820", 2011, dict_obj_tmp, 0, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + } + + /* PS-Information */ + struct dict_object *ps_information = NULL; + SEARCH_AVP_("PS-Information", SH_VND_ID, &ps_information); + { + CHECK_FCT_DO( fd_msg_avp_new ( ps_information, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("3GPP-Charging-Id", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub1); + EN_GRPAVP_U32_("PDN-Connection-ID", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub1); + EN_GRPAVP_STR("Node-Id", SH_VND_ID, dict_obj_tmp, "Node-Id", grpavp_sub1); + EN_GRPAVP_U32_("3GPP-PDP-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + EN_GRPAVP_STR("PDP-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_U32_("Dynamic-Address-Flag", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + /* QoS-Information */ + struct dict_object *qos_information = NULL; + SEARCH_AVP_("QoS-Information", SH_VND_ID, &qos_information); + CHECK_FCT_DO( fd_msg_avp_new ( qos_information, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("QoS-Class-Identifier", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_U32_("Max-Requested-Bandwidth-UL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub2) + EN_GRPAVP_U32_("Guaranteed-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub2) + EN_GRPAVP_U32_("Guaranteed-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub2) + EN_GRPAVP_STR("Bearer-Identifier", SH_VND_ID, dict_obj_tmp, "Bearer-Identifier", grpavp_sub2) + + /* Allocation-Retention-Priority */ + struct dict_object *allocation_retention_priority = NULL; + SEARCH_AVP_("Allocation-Retention-Priority", SH_VND_ID, &allocation_retention_priority); + CHECK_FCT_DO( fd_msg_avp_new ( allocation_retention_priority, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("Priority-Level", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("Pre-emption-Capability", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + EN_GRPAVP_U32_("Pre-emption-Vulnerability", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub2) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 6, grpavp_sub2) + + /* Conditional-APN-Aggregate-Max-Bitrate */ + struct dict_object *conditional_apn_aggregate_max_btrate = NULL; + SEARCH_AVP_("Conditional-APN-Aggregate-Max-Bitrate", SH_VND_ID, &conditional_apn_aggregate_max_btrate); + CHECK_FCT_DO( fd_msg_avp_new ( conditional_apn_aggregate_max_btrate, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + EN_GRPAVP_U32_("IP-CAN-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + EN_GRPAVP_U32_("RAT-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_STR("SGSN-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_STR("GGSN-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_STR("SGW-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_STR("CG-Address", SH_VND_ID, dict_obj_tmp, "10.10.10.10", grpavp_sub1); + EN_GRPAVP_U32_("Serving-Node-Type", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + EN_GRPAVP_U32_("SGW-Change", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + EN_GRPAVP_STR("3GPP-IMSI-MCC-MNC", SH_VND_ID, dict_obj_tmp, "3GPP-IMSI-MCC-MNC", grpavp_sub1); + EN_GRPAVP_U32_("IMSI-Unauthenticated-Flag", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub1); + EN_GRPAVP_STR("3GPP-GGSN-MCC-MNC", SH_VND_ID, dict_obj_tmp, "3GPP-GGSN-MCC-MNC", grpavp_sub1); + EN_GRPAVP_STR("3GPP-NSAPI", SH_VND_ID, dict_obj_tmp, "3GPP-NSAPI", grpavp_sub1); + EN_GRPAVP_STR("Called-Station-Id", 0, dict_obj_tmp, "Called-Station-Id", grpavp_sub1); + EN_GRPAVP_STR("3GPP-Session-Stop-Indicator", SH_VND_ID, dict_obj_tmp, "3GPP-Session-Stop-Indicator", grpavp_sub1); + EN_GRPAVP_STR("3GPP-Selection-Mode", SH_VND_ID, dict_obj_tmp, "3GPP-Selection-Mode", grpavp_sub1); + EN_GRPAVP_STR("3GPP-Charging-Characteristics", SH_VND_ID, dict_obj_tmp, "3GPP-Charging-Characteristics", grpavp_sub1); + EN_GRPAVP_U32_("Charging-Characteristics-Selection-Mode", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub1); + EN_GRPAVP_STR("3GPP-SGSN-MCC-MNC", SH_VND_ID, dict_obj_tmp, "3GPP-SGSN-MCC-MNC", grpavp_sub1); + EN_GRPAVP_STR("3GPP-MS-TimeZone", SH_VND_ID, dict_obj_tmp, "3GPP-MS-TimeZone", grpavp_sub1); + EN_GRPAVP_STR("Charging-Rule-Base-Name", SH_VND_ID, dict_obj_tmp, "Charging-Rule-Base-Name", grpavp_sub1); + EN_GRPAVP_STR("3GPP-User-Location-Info", SH_VND_ID, dict_obj_tmp, "3GPP-User-Location-Info", grpavp_sub1); + + /* User-CSG-Information */ + struct dict_object *user_csg_information = NULL; + SEARCH_AVP_("User-CSG-Information", SH_VND_ID, &user_csg_information); + CHECK_FCT_DO( fd_msg_avp_new ( user_csg_information, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("CSG-Id", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_U32_("CSG-Access-Mode", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub2) + EN_GRPAVP_U32_("CSG-Membership-Indication", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub2) + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_STR("3GPP2-BSID", 5535, dict_obj_tmp, "3GPP2-BSID", grpavp_sub1); + EN_GRPAVP_STR("3GPP-RAT-Type", SH_VND_ID, dict_obj_tmp, "3GPP-RAT-Type", grpavp_sub1); + + /* PS-Furnish-Charging-Information */ + struct dict_object *ps_furnish_charging_information = NULL; + SEARCH_AVP_("PS-Furnish-Charging-Information", SH_VND_ID, &ps_furnish_charging_information); + CHECK_FCT_DO( fd_msg_avp_new ( ps_furnish_charging_information, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_STR("PS-Free-Format-Data", SH_VND_ID, dict_obj_tmp, "PS-Free-Format-Data", grpavp_sub2) + EN_GRPAVP_U32_("PS-Append-Free-Format-Data", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + EN_GRPAVP_U32_("PDP-Context-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + LOG_D("fj CCR PDP-Context-Type Ok\n"); + + /* Offline-Charging */ + struct dict_object *offline_charging = NULL; + SEARCH_AVP_("Offline-Charging", SH_VND_ID, &offline_charging); + CHECK_FCT_DO( fd_msg_avp_new ( offline_charging, 0, &grpavp_sub2 ), goto out); + { + EN_GRPAVP_U32_("Quota-Consumption-Time", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + /* Time-Quota-Mechanism */ + struct dict_object *time_quota_mechanism = NULL; + SEARCH_AVP_("Time-Quota-Mechanism", SH_VND_ID, &time_quota_mechanism); + CHECK_FCT_DO( fd_msg_avp_new ( time_quota_mechanism, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("Time-Quota-Type", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("Base-Time-Interval", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + EN_GRPAVP_U32_("Envelope-Reporting", SH_VND_ID, dict_obj_tmp, 22, grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Traffic-Data-Volumes */ + struct dict_object *traffic_data_volumes = NULL; + SEARCH_AVP_("Traffic-Data-Volumes", SH_VND_ID, &traffic_data_volumes); + CHECK_FCT_DO( fd_msg_avp_new ( traffic_data_volumes, 0, &grpavp_sub2 ), goto out ); + { + /* QoS-Information */ + struct dict_object *qos_information = NULL; + SEARCH_AVP_("QoS-Information", SH_VND_ID, &qos_information); + CHECK_FCT_DO( fd_msg_avp_new ( qos_information, 0, &grpavp_sub3 ), goto out); + { + EN_GRPAVP_U32_("QoS-Class-Identifier", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub3) + EN_GRPAVP_U32_("Max-Requested-Bandwidth-UL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub3) + EN_GRPAVP_U32_("Guaranteed-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub3) + EN_GRPAVP_U32_("Guaranteed-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 4, grpavp_sub3) + EN_GRPAVP_STR("Bearer-Identifier", SH_VND_ID, dict_obj_tmp, "Bearer-Identifier", grpavp_sub3) + + /* Allocation-Retention-Priority */ + struct dict_object *allocation_retention_priority = NULL; + SEARCH_AVP_("Allocation-Retention-Priority", SH_VND_ID, &allocation_retention_priority); + CHECK_FCT_DO( fd_msg_avp_new ( allocation_retention_priority, 0, &grpavp_sub4 ), goto out); + { + EN_GRPAVP_U32_("Priority-Level", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub4) + EN_GRPAVP_U32_("Pre-emption-Capability", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub4) + EN_GRPAVP_U32_("Pre-emption-Vulnerability", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub4) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub3, MSG_BRW_LAST_CHILD, grpavp_sub4 ), goto out ); + } + + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub3) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 6, grpavp_sub3) + + /* Conditional-APN-Aggregate-Max-Bitrate */ + struct dict_object *conditional_apn_aggregate_max_btrate = NULL; + SEARCH_AVP_("Conditional-APN-Aggregate-Max-Bitrate", SH_VND_ID, &conditional_apn_aggregate_max_btrate); + CHECK_FCT_DO( fd_msg_avp_new ( conditional_apn_aggregate_max_btrate, 0, &grpavp_sub4 ), goto out); + { + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, dict_obj_tmp, 1, grpavp_sub4) + EN_GRPAVP_U32_("APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, dict_obj_tmp, 2, grpavp_sub4) + EN_GRPAVP_U32_("IP-CAN-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub4) + EN_GRPAVP_U32_("RAT-Type", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub4) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub3, MSG_BRW_LAST_CHILD, grpavp_sub4 ), goto out ); + } + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub2, MSG_BRW_LAST_CHILD, grpavp_sub3 ), goto out ); + } + + EN_GRPAVP_U64_("Accounting-Input-Octets", 0, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_U64_("Accounting-Input-Packets", 0, dict_obj_tmp, 2, grpavp_sub2) + EN_GRPAVP_U64_("Accounting-Output-Octets", 0, dict_obj_tmp, 3, grpavp_sub2) + EN_GRPAVP_U64_("Accounting-Output-Packets", 0, dict_obj_tmp, 4, grpavp_sub2) + EN_GRPAVP_U32_("Change-Condition", SH_VND_ID, dict_obj_tmp, 5, grpavp_sub2) + EN_GRPAVP_STR("Change-Time", SH_VND_ID, dict_obj_tmp, "1111", grpavp_sub2) + EN_GRPAVP_STR("3GPP-User-Location-Info", SH_VND_ID, dict_obj_tmp, "3GPP-User-Location-Info", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Service-Data-Container */ + + /* User-Equipment-Info */ + struct dict_object *user_equipment_info = NULL; + SEARCH_AVP_("User-Equipment-Info", 0, &user_equipment_info); + CHECK_FCT_DO( fd_msg_avp_new ( user_equipment_info, 0, &grpavp_sub2 ), goto out ); + { + EN_GRPAVP_U32_("User-Equipment-Info-Type", 0, dict_obj_tmp, 1, grpavp_sub2) + EN_GRPAVP_STR("User-Equipment-Info-Value", 0, dict_obj_tmp, "User-Equipment-Info-Value", grpavp_sub2) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp_sub1, MSG_BRW_LAST_CHILD, grpavp_sub2 ), goto out ); + } + + /* Terminal-Information */ + + EN_GRPAVP_STR("Start-Time", SH_VND_ID, dict_obj_tmp, "2016-08-10T19:09:30-05:00", grpavp_sub1); + EN_GRPAVP_STR("Stop-Time", SH_VND_ID, dict_obj_tmp, "2016-08-10T19:09:30-05:00 ", grpavp_sub1); + EN_GRPAVP_U32_("Change-Condition", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + EN_GRPAVP_U32_("Diagnostics", SH_VND_ID, dict_obj_tmp, 3, grpavp_sub1); + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + } + + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("fj CCR Service-Information Ok\n"); + } + + + /* Service-Identifier */ + EN_AVP_U32(service_identifier, 65534, req, "fj CCR Service-Identifier"); + + /* Multiple-Services-Indicator */ + EN_AVP_U32(multiple_services_indicator, 1, req, "fj CCR Multiple-Services-Indicator"); + + /* Multiple-Services-Credit-Control */ + { + CHECK_FCT_DO( fd_msg_avp_new ( multiple_services_credit_control, 0, &grpavp ), goto out); + + /* Requested-Service-Unit */ + { + CHECK_FCT_DO( fd_msg_avp_new ( requested_service_unit, 0, &grpavp_sub1 ), goto out); + + EN_GRPAVP_U32_("CC-Time", 0, dict_obj_tmp, 60, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out); + } + + /* Used-Service-Unit */ + struct dict_object* used_service_unit = NULL; + SEARCH_AVP_("Used-Service-Unit", 0, &used_service_unit); + { + CHECK_FCT_DO( fd_msg_avp_new ( used_service_unit, 0, &grpavp_sub1 ), goto out); + + EN_GRPAVP_U32_("CC-Time", 0, dict_obj_tmp, 0, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out); + } + + EN_GRPAVP_U32("Reporting-Reason", SH_VND_ID, reporting_reason, 0); + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + } + + /* CC-Correlation-Id */ + + /* User-Equipment-Info */ + + + + + #if 0 + switch(gx_sm->state) { + + case STATE_INIT: + + { + //Set Bearer-Usage + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( bearer_usage, 0, &avp ), goto out ); + val.i32 = 1;//IMS + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + { + //Set Packet Filter Operation + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( pflt_oper, 0, &avp ), goto out ); + val.i32 = 1;//ADDITION + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + struct avp *flt_info = NULL; + { + //Set Packet Filter Information + CHECK_FCT_DO( fd_msg_avp_new ( pflt_info, 0, &flt_info ), goto out ); + + + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, flt_info ), goto out ); + } + // Set Packet Filter Identity + { + + CHECK_FCT_DO( fd_msg_avp_new ( pflt_id, 0, &avp ), goto out ); + val.os.data = (unsigned char *)("ID"); + val.os.len = strlen("ID"); + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + if(flt_info) { + CHECK_FCT_DO( fd_msg_avp_add( flt_info, MSG_BRW_LAST_CHILD, avp ), goto out ); + }else { + printf("flt_info NULL\n"); + } + + } + + CHECK_FCT(fd_sess_state_store(g_hdlr, sess, &gx_sm)); + + break; + case STATE_FINAL: + { + //Set Packet Filter Operation + //TODO Change this to use enum object + CHECK_FCT_DO( fd_msg_avp_new ( term_cause, 0, &avp ), goto out ); + val.i32 = 1;//Diameter logout + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + break; + default: + printf("State mismatch \n"); + } + #else + /* fj added 20160828: this allow send more than once */ + // CHECK_FCT(fd_sess_state_store(g_hdlr, sess, &gx_sm)); + #endif + fflush(stderr); + + /* Send the request */ + printf("CCA %p\n",req); + // Everthing Done Store the state: reply should retreive it + CHECK_FCT_DO( fd_msg_send( &req, gx_rec_cca, NULL ), goto out ); + +out: + return 0; +} + +/* Dummy ccr which : + Read the cc-req-type && cc-req-number from the msg and stick it back + in the reply + +*/ +int gx_handle_ccr_from_client_getport(char *cxt_id, struct gy_msg *gy_ptr) +{ + int sh_port, app_port=INVALID_GY_PORT; + struct gy_port *gy_port_ptr = NULL; + + gx_stat_increase_recv_ccr(gy_ptr->request_type); + + if(gy_ptr->request_type == RT_INITIAL_REQUEST || + gy_ptr->request_type == RT_EVENT_REQUEST) + { + sh_port = gy_assign_port(cxt_id); + if(sh_port == INVALID_GY_PORT) + { + return INVALID_GY_PORT; + } + + gy_port_ptr = &gy_space.gy_port[sh_port]; + gy_port_ptr->service_type = gy_ptr->service_type; + } + else + { + gy_port_ptr = gy_get_port_by_cxt_id(cxt_id); + if((gy_port_ptr == NULL) || (gy_port_ptr->used_flag == 0)) + { + return INVALID_GY_PORT; + } + + sh_port = gy_port_ptr->index; + app_port = gy_port_ptr->app_port; + } + + gy_ptr->app_port = app_port; + gy_ptr->fd_port = sh_port; + + gy_port_ptr->service_type = gy_ptr->service_type; + + return sh_port; +} + +int gx_handle_cca_from_server(struct gy_msg *gy_ptr) +{ + gx_send_cca(gy_ptr); + + return 1; +} + +int gx_send_ccr_from_client(struct gy_msg *gy_ptr) +{ + int sh_port, app_port=INVALID_GY_PORT; + int retval = 0; + struct gy_port *gy_port_ptr = NULL; + + app_port = gy_ptr->app_port; + if(gy_ptr->request_type == RT_INITIAL_REQUEST || + gy_ptr->request_type == RT_EVENT_REQUEST) + { + char context_id[32]; + sprintf(context_id, "%d", app_port); + sh_port = gy_assign_port(context_id); + if(sh_port == INVALID_GY_PORT) + { + return 0; + } + + gy_port_ptr = &gy_space.gy_port[sh_port]; + gy_port_ptr->app_port = app_port; + + gy_port_ptr->service_type = gy_ptr->request_type; + gy_port_ptr->as_client = 1; + fd_sess_destroy(&gy_sess[sh_port]); + gy_sess[sh_port] = NULL; + } + else + { + sh_port = gy_ptr->fd_port; + if(sh_port >= INVALID_GY_PORT) + return 0; + gy_port_ptr = &gy_space.gy_port[sh_port]; + } + + gy_ptr->app_port = app_port; + gy_ptr->fd_port = sh_port; + gy_ptr->request_number = gy_port_ptr->request_number++; + gy_port_ptr->service_type = gy_ptr->service_type; + + retval = gx_sig_hdlr_app(gy_ptr); + + if(pps_debug_flag_for_fd()) + { + char tmp_info[1024]; + + sprintf(tmp_info, "[fd=%04d][app=%04d], ts=%ld.%03ld, %s \r\nmsg_type=%d, result=%d, cxt_id=%s\r\n", + sh_port, app_port, ts_sec, ts_msec, __FUNCTION__, + gy_ptr->request_type, retval, gy_port_ptr->context_id); + + pps_debug_info("diameter", tmp_info); + } + + return 1; +} + +int gx_release_port_for_timerout(unsigned short pid) +{ + _gy_port *gy_port = NULL; + + gy_port = gy_get_port_space(pid); + if(gy_port == NULL) + return 0; + + if(0) + { + char tmp_info[1024]; + + printf(" [fd=%04d][app=%04d], ts=%ld.%03ld, %s \r\n", + pid, gy_port->app_port, ts_sec, ts_msec, __FUNCTION__); + pps_debug_info("diameter", tmp_info); + + } + + CHECK_POSIX_DO( pthread_mutex_lock(&gy_port_lock), { ASSERT(0); } ); + if(1) + { + gy_port_init(gy_port, pid); + gy_space.used_ports --; + } + else + { + gy_release_port(pid); + } + CHECK_POSIX_DO( pthread_mutex_unlock(&gy_port_lock), { ASSERT(0); } ); + + return 1; +} + +static int gx_rec_ccr( struct msg ** msg, struct avp * r_avp, struct session * sess, void * opaque, enum disp_action * act) +{ + //struct msg *tmp_ccr_msg_ptr; + //struct msg *tmp_ccr_msg_ptr_ptr; + + struct msg *ans, *qry; + struct avp *avp = NULL; + struct avp *grpavp = NULL; + struct avp *grpavp_sub1 = NULL; + union avp_value val; + // struct avp *avp = NULL; + // struct avp_hdr * avp_data; + int rc = - 1; + int fd_port = -1; + struct gy_msg gy_msg; + struct gy_msg *gy_ptr=&gy_msg; + + LOG_D("%p %p %p %p", msg, r_avp, sess, act); + + if (msg == NULL) + return EINVAL; + + fprintf(stderr, "ECHO ccr rec from done...\n"); + + LOG_D("fj gx_rec_ccr enter"); + + memset(gy_ptr, 0x00, sizeof(_gy_msg)); + gy_ptr->msg_type = GY_MSG_CCR; + +#if _TEST_CCA + gx_send_cca_test(); +#else + gx_parse_ccr(msg, gy_ptr); +#endif + + + CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) , goto out); + + /* + tmp_ccr_msg_ptr = *msg; + tmp_ccr_msg_ptr_ptr = msg; + */ + + *act = DISP_ACT_ERROR + 1; + + fd_port = gx_handle_ccr_from_client_getport(gy_ptr->cxt_id, gy_ptr); + + if (pps_debug_flag_for_fd()) + { + char tmp_buf[256]; + + sprintf(tmp_buf, "CCR received with context id=%s, fd_port=%d, app_port=%d", + gy_ptr->cxt_id, fd_port, gy_ptr->app_port); + pps_debug_info("diameter", tmp_buf); + } + + if(fd_port >= INVALID_GY_PORT ) + { + // add CCA fail======================================== + gy_ptr->fd_port = INVALID_GY_PORT; + gy_ptr->app_port = INVALID_GY_PORT; + gy_ptr->msg_type = GY_MSG_CCA; + gy_ptr->msg_body.cca.result = 4010; + gy_ptr->msg_body.cca.check_balance_result = CBR_NO_CREDIT; + gy_ptr->msg_body.cca.grant_value = 0; + gy_ptr->msg_body.cca.volume_threshold = 0; + gy_ptr->msg_body.cca.time_threshold = 0; + gy_ptr->msg_body.cca.is_final = 0; + g_direct_cca_fail_msg_ptr = *msg; + gx_send_cca_fail(gy_ptr);// response CCA + // + + return 0; + } + + //CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) , goto out); + + if(fd_port != INVALID_GY_PORT ) + { + g_ccr_msg_ptr[fd_port] = *msg; + //g_ccr_msg_ptr_ptr[fd_port] = msg; + } + + //pps_recv_gy_process(gy_ptr); + pps_ro_gy_cb(gy_ptr); + /*pthread_mutex_lock( &gy_msg_mtx ); + gx_add_msg_to_list(gy_ptr); + pthread_mutex_unlock( &gy_msg_mtx );*/ + + rc = 0; + + return rc; + + /* Create answer header */ + qry = *msg; + CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) , goto out); + ans = *msg; + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( ans, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + msg_hdr->msg_flags = msg_hdr->msg_flags & (~CMD_FLAG_PROXIABLE); + } + + /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ + CHECK_FCT_DO( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ), goto out ); + + // Get the auth_app_id and from the reply and set it in the reply + CHECK_FCT_DO(dcca_ans_from_req( auth_app_id, qry, msg), goto out); + CHECK_FCT_DO(dcca_ans_from_req( cc_req_type, qry, msg), goto out); + CHECK_FCT_DO(dcca_ans_from_req( cc_req_num, qry, msg), goto out); + + /* Multiple-Services-Credit-Control */ + { + CHECK_FCT_DO( fd_msg_avp_new ( multiple_services_credit_control, 0, &grpavp ), goto out ); + + /* Result-Code */ + struct dict_object *result_code = NULL; + EN_GRPAVP_U32("Result-Code", 0, result_code, 2001); + + /* Granted-Service-Unit */ + struct dict_object *granted_service_unit = NULL; + SEARCH_AVP_("Granted-Service-Unit", 0, &granted_service_unit); + { + CHECK_FCT_DO( fd_msg_avp_new ( granted_service_unit, 0, &grpavp_sub1 ), goto out ); + + EN_GRPAVP_U32_("CC-Time", 0, cc_time, 120, grpavp_sub1) + + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, grpavp_sub1 ), goto out ); + + LOG_D("fj CCR Granted-Service-Unit Ok\n"); + } + + CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("fj CCR Multiple-Services-Credit-Control Ok\n"); + } + + /* Send the answer */ + CHECK_FCT_DO( fd_msg_send( msg, NULL, NULL ), goto out ); + rc = 0; +out: + + LOG_D("fj gx_rec_ccr rc:%d exit", rc); + + //Free up the memory + return rc ; +} + +static void gx_rec_cca(void *para, struct msg **msg) +{ + LOG_D("fj gx_rec_cca enter"); + + gx_parse_cca(msg); + + CHECK_FCT_DO( fd_msg_free( *msg), return); + *msg = NULL; + + LOG_D("fj gx_rec_cca exit"); +} + +int gx_stat_clean_all() +{ + memset(&gy_stat, 0x00, sizeof(gy_stat)); + + return 1; +} + +int gx_stat_increase_recv_ccr(int type) +{ + gy_stat.recv_stat.ccr ++; + switch(type) + { + case RT_INITIAL_REQUEST: + gy_stat.recv_stat.ccr_init ++; + break; + case RT_UPDATE_REQUEST: + gy_stat.recv_stat.ccr_update ++; + break; + case RT_TERMINATE_REQUEST: + gy_stat.recv_stat.ccr_terminate ++; + break; + case RT_EVENT_REQUEST: + gy_stat.recv_stat.ccr_event ++; + break; + } + + return 1; +} + +int gx_stat_increase_send_ccr(int type) +{ + gy_stat.send_stat.ccr ++; + switch(type) + { + case RT_INITIAL_REQUEST: + gy_stat.send_stat.ccr_init ++; + break; + case RT_UPDATE_REQUEST: + gy_stat.send_stat.ccr_update ++; + break; + case RT_TERMINATE_REQUEST: + gy_stat.send_stat.ccr_terminate ++; + break; + case RT_EVENT_REQUEST: + gy_stat.send_stat.ccr_event ++; + break; + } + + return 1; +} + +int gx_stat_increase_recv_cca(int type) +{ + gy_stat.recv_stat.cca ++; + switch(type) + { + case RT_INITIAL_REQUEST: + gy_stat.recv_stat.cca_init ++; + break; + case RT_UPDATE_REQUEST: + gy_stat.recv_stat.cca_update ++; + break; + case RT_TERMINATE_REQUEST: + gy_stat.recv_stat.cca_terminate ++; + break; + case RT_EVENT_REQUEST: + gy_stat.recv_stat.cca_event ++; + break; + } + + return 1; +} + +int gx_stat_increase_send_cca(int type) +{ + gy_stat.send_stat.cca ++; + switch(type) + { + case RT_INITIAL_REQUEST: + gy_stat.send_stat.cca_init ++; + break; + case RT_UPDATE_REQUEST: + gy_stat.send_stat.cca_update ++; + break; + case RT_TERMINATE_REQUEST: + gy_stat.send_stat.cca_terminate ++; + break; + case RT_EVENT_REQUEST: + gy_stat.send_stat.cca_event ++; + break; + } + + return 1; +} + +int gx_print_all_port_status() +{ + int loop=0; + FILE *fpStatus=NULL; + + fpStatus = fopen("../log/fd_state.txt","w"); + if(fpStatus == NULL) + return 0; + + fprintf(fpStatus,"start ts=%ld, now ts=%ld\r\n", gx_start_ts, ts_sec); + + for(loop=0; loop 10) //timeout for SMS + { + gx_release_port_for_timerout(index); + } + } + else + { + if( ( ts_sec - updated_ts ) >1800 ) //half hour + { + gx_release_port_for_timerout(index); + } + } + } + else + { + if(( ts_sec - updated_ts) > 1800) //half hour + { + gx_release_port_for_timerout(index); + } + } + } + } + + return 1; +} + +int gx_fsm(long sec, int msec) +{ + ts_sec = sec; + ts_msec = msec; + if(gx_start_ts<=1) + gx_start_ts = sec; + + return gx_clear_all_port_for_timeout(); +} + +// ********************************************************************* +/*#define MAX_GY_MSG_NUM 8192 +#define MAX_HANDLED_GY_MSG_PER_CYCLE 100 +typedef struct +{ + unsigned int header; + unsigned int tailer; + _gy_msg msg[MAX_GY_MSG_NUM]; +}GY_MSG_LIST; + +GY_MSG_LIST gy_msg_list = {0, 0, }; + +static int gx_add_msg_to_list(_gy_msg *pInMsg) +{ + _gy_msg *pMsg = NULL; + + if (pInMsg == NULL) + { + return -1; + } + + if(((gy_msg_list.tailer+1) % MAX_GY_MSG_NUM) == gy_msg_list.header) + { + return -1; + } + + pMsg = &gy_msg_list.msg[gy_msg_list.tailer]; + memcpy(pMsg, pInMsg, sizeof(_gy_msg)); + + gy_msg_list.tailer = (gy_msg_list.tailer+1) % MAX_GY_MSG_NUM; + + return 0; +} + + +static int gx_get_msg_from_list(_gy_msg *pOutMsg) +{ + _gy_msg *pMsg = NULL; + + if (pOutMsg == NULL) + { + return -1; + } + + if (gy_msg_list.header != gy_msg_list.tailer) + { + pMsg = &gy_msg_list.msg[gy_msg_list.header]; + memcpy(pOutMsg, pMsg, sizeof(_gy_msg)); + + gy_msg_list.header = (gy_msg_list.header+1) % (MAX_GY_MSG_NUM); + + return 0; + } + + return -1; +} + +void gx_handle_msg_cb() +{ + int i, ret; + _gy_msg gy_msg, *gy_ptr; + gy_ptr = &gy_msg; + + for (i=0; i * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* + * Test application for freeDiameter. + */ + +#include "sh_app.h" +#include "sh_conf.h" + + +/* Initialize the configuration */ +struct ta_conf * ta_conf = NULL; +static struct ta_conf _conf; +static pthread_t ta_stats_th = (pthread_t)NULL; +#if 0 +static int ta_init_peer_addr(struct peer_info* inf) +{ +// uint16_t str; +// int ev; + + /* Initialize the server addresses */ + { + struct addrinfo hints, *ai, *aip; + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_NUMERICSERV; + hints.ai_family = AF_INET; + getaddrinfo("localhost", _stringize(TEST_PORT), &hints, &ai); + aip = ai; + while (aip) { + ASSERT( 0 == fd_ep_add_merge( &inf->pi_endpoints, aip->ai_addr, aip->ai_addrlen, EP_FL_DISC | EP_ACCEPTALL )); + aip = aip->ai_next; + }; + freeaddrinfo(ai); + } + + return 0; +} +#endif +/* fj added 20170114. when the peer was free. we can reconnect to peer here*/ +static void peer_free_cb(struct peer_info *died_peer, void *cb_data) +{ + LOG_N("peer_free_cb.%p %p", died_peer, cb_data); + SH_CONF_S *ptr = (SH_CONF_S *)cb_data; + if(NULL == died_peer && MODE_CLI == ta_conf->mode) + { + struct peer_info inf; + memset(&inf, 0, sizeof(inf)); + inf.pi_diamid = strdup(ptr->pi_diamid_peer);//strdup(g_sh_conf_ext.pi_diamid_peer); + inf.config.pic_flags.sec = PI_SEC_NONE; + inf.config.pic_port = ptr->peer_port; + // ta_init_peer_addr( (struct peer_info*)(&inf.pi_endpoints) ); + + ASSERT( 0 == fd_peer_add(&inf, __FILE__, peer_free_cb, ptr));//NULL)); + } +} +static int ta_conf_init(void) +{ + ta_conf = &_conf; + memset(ta_conf, 0, sizeof(struct ta_conf)); + + /* Set the default values */ + ta_conf->vendor_id = SH_VND_ID; + ta_conf->appli_id = SH_APP_ID; + ta_conf->cmd_id = 0xfffffe; + ta_conf->avp_id = 0xffffff; + ta_conf->long_avp_len = 5000; + + ta_conf->mode = g_sh_conf_ext.mode; + /* fj added 20170114. only diameter client connect to peer. In this case, connect to peer when started. */ + if(MODE_CLI == ta_conf->mode) + { + if (g_sh_conf_ext.pi_diamid_peer != NULL) + { + struct peer_info inf; + memset(&inf, 0, sizeof(inf)); + inf.pi_diamid = strdup(g_sh_conf_ext.pi_diamid_peer); + inf.config.pic_flags.sec = PI_SEC_NONE; + inf.config.pic_port = g_sh_conf_ext.peer_port; + // ta_init_peer_addr( (struct peer_info*)(&inf.pi_endpoints) ); + + ASSERT( 0 == fd_peer_add(&inf, __FILE__, peer_free_cb, &g_sh_conf_ext)); + } + + int i=0; + SH_CONF_S *pcfg = NULL; + for (i=0; ipi_diamid_peer != NULL) + { + struct peer_info inf; + memset(&inf, 0, sizeof(inf)); + inf.pi_diamid = strdup(pcfg->pi_diamid_peer); + inf.config.pic_flags.sec = PI_SEC_NONE; + inf.config.pic_port = pcfg->peer_port; + // ta_init_peer_addr( (struct peer_info*)(&inf.pi_endpoints) ); + + ASSERT( 0 == fd_peer_add(&inf, __FILE__, peer_free_cb, pcfg)); + } + } + for (i=0; ipi_diamid_peer != NULL) + { + struct peer_info inf; + memset(&inf, 0, sizeof(inf)); + inf.pi_diamid = strdup(pcfg->pi_diamid_peer); + inf.config.pic_flags.sec = PI_SEC_NONE; + inf.config.pic_port = pcfg->peer_port; + // ta_init_peer_addr( (struct peer_info*)(&inf.pi_endpoints) ); + + ASSERT( 0 == fd_peer_add(&inf, __FILE__, peer_free_cb, pcfg)); + } + } + /*if (g_rosms_conf_ext.pi_diamid_peer != NULL) + { + struct peer_info inf; + memset(&inf, 0, sizeof(inf)); + inf.pi_diamid = strdup(g_rosms_conf_ext.pi_diamid_peer); + inf.config.pic_flags.sec = PI_SEC_NONE; + inf.config.pic_port = g_rosms_conf_ext.peer_port; + // ta_init_peer_addr( (struct peer_info*)(&inf.pi_endpoints) ); + + ASSERT( 0 == fd_peer_add(&inf, __FILE__, peer_free_cb, &g_rosms_conf_ext)); + } + + if (g_rovoice_conf_ext.pi_diamid_peer != NULL) + { + struct peer_info inf; + memset(&inf, 0, sizeof(inf)); + inf.pi_diamid = strdup(g_rovoice_conf_ext.pi_diamid_peer); + inf.config.pic_flags.sec = PI_SEC_NONE; + inf.config.pic_port = g_rovoice_conf_ext.peer_port; + // ta_init_peer_addr( (struct peer_info*)(&inf.pi_endpoints) ); + + ASSERT( 0 == fd_peer_add(&inf, __FILE__, peer_free_cb, &g_rovoice_conf_ext)); + }*/ + } + + ta_conf->dest_realm = strdup(fd_g_config->cnf_diamrlm); + ta_conf->signal = TEST_APP_DEFAULT_SIGNAL; + ta_conf->bench_concur = 100; + ta_conf->bench_duration = 10; + + /* Initialize the mutex */ + CHECK_POSIX( pthread_mutex_init(&ta_conf->stats_lock, NULL) ); + + return 0; +} + +static void ta_conf_dump(void) +{ + if (!TRACE_BOOL(INFO)) + return; + fd_log_debug( "------- app_test configuration dump: ---------"); + fd_log_debug( " Vendor Id .......... : %u", ta_conf->vendor_id); + fd_log_debug( " Application Id ..... : %u", ta_conf->appli_id); + fd_log_debug( " Command Id ......... : %u", ta_conf->cmd_id); + fd_log_debug( " AVP Id ............. : %u", ta_conf->avp_id); + fd_log_debug( " Long AVP Id ........ : %u", ta_conf->long_avp_id); + fd_log_debug( " Long AVP len ....... : %zu", ta_conf->long_avp_len); + fd_log_debug( " Mode ............... : %s%s%s", ta_conf->mode & MODE_SERV ? "Serv" : "", ta_conf->mode & MODE_CLI ? "Cli" : "", ta_conf->mode & MODE_BENCH ? " (Benchmark)" : ""); + fd_log_debug( " Destination Realm .. : %s", ta_conf->dest_realm ?: "- none -"); + fd_log_debug( " Destination Host ... : %s", ta_conf->dest_host ?: "- none -"); + fd_log_debug( " Signal ............. : %i", ta_conf->signal); + fd_log_debug( "------- /app_test configuration dump ---------"); +} + +/* Function to display statistics periodically */ +static void * ta_stats(void * arg) { + + struct timespec start, now; + struct ta_stats copy; + + /* Get the start time */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &start), ); + + /* Now, loop until canceled */ + while (1) { + /* Display statistics every XX seconds */ + sleep(ta_conf->bench_duration + 3); + + /* Now, get the current stats */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + memcpy(©, &ta_conf->stats, sizeof(struct ta_stats)); + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + + /* Get the current execution time */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), ); + + /* Now, display everything */ + fd_log_debug( "------- app_test statistics ---------"); + if (now.tv_nsec >= start.tv_nsec) { + fd_log_debug( " Executing for: %d.%06ld sec", + (int)(now.tv_sec - start.tv_sec), + (long)(now.tv_nsec - start.tv_nsec) / 1000); + } else { + fd_log_debug( " Executing for: %d.%06ld sec", + (int)(now.tv_sec - 1 - start.tv_sec), + (long)(now.tv_nsec + 1000000000 - start.tv_nsec) / 1000); + } + + if (ta_conf->mode & MODE_SERV) { + fd_log_debug( " Server: %llu message(s) echoed", copy.nb_echoed); + } + if (ta_conf->mode & MODE_CLI) { + fd_log_debug( " Client:"); + fd_log_debug( " %llu message(s) sent", copy.nb_sent); + fd_log_debug( " %llu error(s) received", copy.nb_errs); + fd_log_debug( " %llu answer(s) received", copy.nb_recv); + fd_log_debug( " fastest: %ld.%06ld sec.", copy.shortest / 1000000, copy.shortest % 1000000); + fd_log_debug( " slowest: %ld.%06ld sec.", copy.longest / 1000000, copy.longest % 1000000); + fd_log_debug( " Average: %ld.%06ld sec.", copy.avg / 1000000, copy.avg % 1000000); + } + fd_log_debug( "-------------------------------------"); + } + + return NULL; /* never called */ +} + +static struct fd_hook_hdl * hookhdl[2] = { NULL, NULL }; +static void ta_hook_cb_silent(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata) { +} +static void ta_hook_cb_oneline(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata) { + char * buf = NULL; + size_t len; + + CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 0), + { LOG_E("Error while dumping a message"); return; } ); + + LOG_N("{%d} %s: %s", type, (char *)other ?:"", buf ?:""); + + free(buf); +} + +extern int sh_dict_init(char * conffile); +extern int dict_dcca_3gpp_entry(char * conffile); +extern int dict_dcca_entry(char * conffile); +extern struct dict_object * sh_appli; +extern struct dict_object * sh_vendor; +extern struct dict_object *hw_vendor; +extern struct dict_object *uname_vendor_5535; + + +extern int app_gx_entry(char * conffile); +/* entry point */ +static int ta_entry(char * conffile) +{ + TRACE_ENTRY("%p", conffile); + + /* Initialize configuration */ + CHECK_FCT( ta_conf_init() ); + + /* Parse configuration file */ + /* fj added 2016/06/21 */ + #if 0 + if (conffile != NULL) { + CHECK_FCT( ta_conf_handle(conffile) ); + } + #endif + + TRACE_DEBUG(INFO, "Extension Test_App initialized with configuration: '%s'", conffile); + ta_conf_dump(); + + /* Install objects definitions for this test application */ + #if 0 + CHECK_FCT( ta_dict_init() ); + #else + CHECK_FCT( sh_dict_init(NULL) ); + CHECK_FCT( dict_dcca_3gpp_entry(NULL) ); + CHECK_FCT( dict_dcca_entry(NULL) ); + #endif + + /* gx entry */ + app_gx_entry(NULL); + + + /* Install the handlers for incoming messages */ + if (ta_conf->mode & MODE_SERV) { + CHECK_FCT( sh_serv_init() ); + } + + /* Start the signal handler thread */ + if (ta_conf->mode & MODE_CLI) { + if (ta_conf->mode & MODE_BENCH) { + CHECK_FCT( ta_bench_init() ); + } else { + CHECK_FCT( sh_cli_init() ); + } + } + + /* Advertise the support for the test application in the peer */ + CHECK_FCT( fd_disp_app_support ( sh_appli, sh_vendor, 1, 0 ) ); + + CHECK_FCT( fd_disp_app_support ( sh_appli, hw_vendor, 1, 0 ) ); + + CHECK_FCT( fd_disp_app_support ( sh_appli, uname_vendor_5535, 1, 0 ) ); + + if (ta_conf->mode & MODE_BENCH) { + /* Register an empty hook to disable the default handling */ + CHECK_FCT( fd_hook_register( HOOK_MASK( HOOK_DATA_RECEIVED, HOOK_MESSAGE_RECEIVED, HOOK_MESSAGE_LOCAL, HOOK_MESSAGE_SENT, HOOK_MESSAGE_ROUTING_FORWARD, HOOK_MESSAGE_ROUTING_LOCAL ), + ta_hook_cb_silent, NULL, NULL, &hookhdl[0]) ); + CHECK_FCT( fd_hook_register( HOOK_MASK( HOOK_MESSAGE_ROUTING_ERROR, HOOK_MESSAGE_DROPPED ), + ta_hook_cb_oneline, NULL, NULL, &hookhdl[1]) ); + + } + + /* Start the statistics thread */ + CHECK_POSIX( pthread_create(&ta_stats_th, NULL, ta_stats, NULL) ); + + return 0; +} + +/* Unload */ +void fd_ext_fini(void) +{ + if (ta_conf->mode & MODE_CLI) + sh_cli_finit(); + if (ta_conf->mode & MODE_SERV) + sh_serv_fini(); + if (hookhdl[0]) + fd_hook_unregister( hookhdl[0] ); + if (hookhdl[1]) + fd_hook_unregister( hookhdl[1] ); + CHECK_FCT_DO( fd_thr_term(&ta_stats_th), ); + CHECK_POSIX_DO( pthread_mutex_destroy(&ta_conf->stats_lock), ); +} + +/* + * fj added 2016/06/21 + * parse config file + * + */ + +/* fj added 2016/06/20 */ +/* The cryptographic data */ +static char ca_data[] = "-----BEGIN CERTIFICATE-----\n" + "MIIEqjCCA5KgAwIBAgIJANKgDwdlDYQDMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD\n" + "VQQGEwJKUDEOMAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB0tvZ2FuZWkxDTALBgNV\n" + "BAoMBFdJREUxDzANBgNVBAsMBkFBQSBXRzEfMB0GA1UEAwwWY2hhdnJvdXguY293\n" + "YWRkaWN0Lm9yZzEiMCAGCSqGSIb3DQEJARYTc2RlY3VnaXNAbmljdC5nby5qcDAe\n" + "Fw0wOTEwMDUwODUxNDRaFw0xOTEwMDMwODUxNDRaMIGUMQswCQYDVQQGEwJKUDEO\n" + "MAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB0tvZ2FuZWkxDTALBgNVBAoMBFdJREUx\n" + "DzANBgNVBAsMBkFBQSBXRzEfMB0GA1UEAwwWY2hhdnJvdXguY293YWRkaWN0Lm9y\n" + "ZzEiMCAGCSqGSIb3DQEJARYTc2RlY3VnaXNAbmljdC5nby5qcDCCASIwDQYJKoZI\n" + "hvcNAQEBBQADggEPADCCAQoCggEBAM5c6w4NnngTvGNWcJzbo0Kklp+kvUNQNgGu\n" + "myvz826qPp07HTSyJrIcgFnuYDR0Nd130Ot9u5osqpQhHTvolxDE87Tii8i3hJSj\n" + "TTY9K0ZwGb4AZ6QkuyMXS1jtOY657HqjpGZqT/2Syh0i7dM/hqSXFw0SPbyq+W1H\n" + "SVFWa1CTkPywFWAzwdr5WKah77uZ1dxWqgPgUdcZOiIQtLRp5n3fg40Nwso5YdwS\n" + "64+ebBX1pkhrCQ8AGc8O61Ep1JTXcO7jqQmPgzjiN+FeostI1Dp73S3MqleTAHjR\n" + "hqZ77VF7nkroMM9btMHJBaxnfwc2ewULUJwnuOiGWrvMq/9Z4J8CAwEAAaOB/DCB\n" + "+TAdBgNVHQ4EFgQUkqpVn7N3gmiJ7X5zQ2bki+7qv4UwgckGA1UdIwSBwTCBvoAU\n" + "kqpVn7N3gmiJ7X5zQ2bki+7qv4WhgZqkgZcwgZQxCzAJBgNVBAYTAkpQMQ4wDAYD\n" + "VQQIDAVUb2t5bzEQMA4GA1UEBwwHS29nYW5laTENMAsGA1UECgwEV0lERTEPMA0G\n" + "A1UECwwGQUFBIFdHMR8wHQYDVQQDDBZjaGF2cm91eC5jb3dhZGRpY3Qub3JnMSIw\n" + "IAYJKoZIhvcNAQkBFhNzZGVjdWdpc0BuaWN0LmdvLmpwggkA0qAPB2UNhAMwDAYD\n" + "VR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAJy0XLk8j8YLSTt2/VMy9TAUx\n" + "esXUiZj0Ung+gkr7A1K0NnwYxDzG2adMhf13upHoydu2ErLMmD6F77x+QuY/q7nc\n" + "ZvO0tvcoAP6ToSDwiypU5dnTmnfkgwVwzFkNCi1sGRosEm8c/c/8MfK0I0nVdj1/\n" + "BIkIG7tTDVi9JvkWYl0UlSKWTZKrntVwCmscfC02DGb+GoLbO9+QmiNM5Y3yOYZ4\n" + "Pc7SSoKLL0rwJBmpPNs7boYsweeSuCAVu0shRfgC90odXcej2EN5ETfCuU1evXNW\n" + "5cA+zZsDK/nWJwxBaW0CxAHX579FElFWlK4+BnzhZRdDhmJDnN5dh4ekJGM6Lg==\n" + "-----END CERTIFICATE-----\n"; + +/* Client: + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 5 (0x5) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=chavroux.cowaddict.org/emailAddress=sdecugis@nict.go.jp + Validity + Not Before: Oct 27 04:04:05 2009 GMT + Not After : Oct 25 04:04:05 2019 GMT + Subject: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=client.test/emailAddress=client@test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:bd:eb:50:1e:9d:7a:cd:9d:bb:e7:bc:4e:38:4a: + b2:cc:9e:b4:89:77:01:ef:d1:c6:19:29:00:fe:ce: + 3c:62:05:13:b1:8c:ff:31:7a:0f:c1:2e:4b:3c:0c: + 40:1e:36:4e:76:da:0a:64:43:fc:1e:ea:0c:97:b2: + 57:9c:9c:8c:90:bd:eb:23:7b:b8:b7:5c:03:ed:6f: + 48:55:8a:88:08:38:c5:cd:33:b7:ab:a8:3a:6f:7f: + 13:10:65:a5:50:b9:f4:8b:cc:2e:e9:79:58:a6:11: + f0:58:45:41:ef:36:b3:35:cb:14:ec:82:0c:ad:11: + 6a:ea:64:ef:28:a2:6e:47:45 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + BE:B3:89:4F:9D:8F:6C:20:C4:D0:3E:6A:05:11:82:50:54:49:70:A2 + X509v3 Authority Key Identifier: + keyid:92:AA:55:9F:B3:77:82:68:89:ED:7E:73:43:66:E4:8B:EE:EA:BF:85 + + Signature Algorithm: sha1WithRSAEncryption + a3:88:f5:15:b5:ad:20:60:a1:85:19:3f:b9:5e:1e:be:31:7f: + 84:7a:c2:18:3a:63:6a:67:1f:46:86:4d:10:d6:1d:ad:a2:c8: + 0b:95:33:fa:e4:05:f4:b8:70:34:77:f7:85:6e:70:46:ac:39: + 54:a9:5f:ea:5e:d1:33:bb:c9:a3:42:81:41:90:25:b5:92:8b: + e8:6e:3e:97:06:dd:9a:cc:29:61:34:5a:d3:1c:5d:ad:d1:a3: + eb:6a:47:b4:d0:c2:17:89:e1:e2:2d:36:18:50:1a:e7:d4:fc: + 38:2e:47:0b:39:50:87:2f:aa:07:64:f8:9a:4d:47:01:da:10: + d8:97:c7:a6:13:bc:0e:ca:63:c1:f2:09:fb:f8:6a:a4:5f:08: + b5:ad:ed:4f:71:b9:89:7f:43:27:85:72:e7:8d:a8:4a:cc:f6: + 36:ca:8a:ae:82:b5:a8:42:41:99:87:84:7c:f0:90:fd:ca:96: + 37:a2:e0:d9:fa:dd:a4:c9:f1:50:b7:e5:e6:8f:af:83:8c:23: + b6:20:cc:66:e3:08:60:13:02:8f:42:3a:07:91:a7:38:b2:72: + 16:fd:bd:a9:60:f0:e2:9f:23:f3:c0:99:e3:17:bc:00:7c:b3: + 89:9c:ea:fa:3e:f6:69:a1:98:c2:ec:46:da:70:b6:f9:c3:93: + a7:fc:36:dd +*/ +/* +static char client_cert_data[] ="-----BEGIN CERTIFICATE-----\n" + "MIIDiTCCAnGgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMCSlAx\n" + "DjAMBgNVBAgMBVRva3lvMRAwDgYDVQQHDAdLb2dhbmVpMQ0wCwYDVQQKDARXSURF\n" + "MQ8wDQYDVQQLDAZBQUEgV0cxHzAdBgNVBAMMFmNoYXZyb3V4LmNvd2FkZGljdC5v\n" + "cmcxIjAgBgkqhkiG9w0BCQEWE3NkZWN1Z2lzQG5pY3QuZ28uanAwHhcNMDkxMDI3\n" + "MDQwNDA1WhcNMTkxMDI1MDQwNDA1WjCBgTELMAkGA1UEBhMCSlAxDjAMBgNVBAgM\n" + "BVRva3lvMRAwDgYDVQQHDAdLb2dhbmVpMQ0wCwYDVQQKDARXSURFMQ8wDQYDVQQL\n" + "DAZBQUEgV0cxFDASBgNVBAMMC2NsaWVudC50ZXN0MRowGAYJKoZIhvcNAQkBFgtj\n" + "bGllbnRAdGVzdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvetQHp16zZ27\n" + "57xOOEqyzJ60iXcB79HGGSkA/s48YgUTsYz/MXoPwS5LPAxAHjZOdtoKZEP8HuoM\n" + "l7JXnJyMkL3rI3u4t1wD7W9IVYqICDjFzTO3q6g6b38TEGWlULn0i8wu6XlYphHw\n" + "WEVB7zazNcsU7IIMrRFq6mTvKKJuR0UCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg\n" + "hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O\n" + "BBYEFL6ziU+dj2wgxNA+agURglBUSXCiMB8GA1UdIwQYMBaAFJKqVZ+zd4Joie1+\n" + "c0Nm5Ivu6r+FMA0GCSqGSIb3DQEBBQUAA4IBAQCjiPUVta0gYKGFGT+5Xh6+MX+E\n" + "esIYOmNqZx9Ghk0Q1h2tosgLlTP65AX0uHA0d/eFbnBGrDlUqV/qXtEzu8mjQoFB\n" + "kCW1kovobj6XBt2azClhNFrTHF2t0aPrake00MIXieHiLTYYUBrn1Pw4LkcLOVCH\n" + "L6oHZPiaTUcB2hDYl8emE7wOymPB8gn7+GqkXwi1re1PcbmJf0MnhXLnjahKzPY2\n" + "yoqugrWoQkGZh4R88JD9ypY3ouDZ+t2kyfFQt+Xmj6+DjCO2IMxm4whgEwKPQjoH\n" + "kac4snIW/b2pYPDinyPzwJnjF7wAfLOJnOr6PvZpoZjC7EbacLb5w5On/Dbd\n" + "-----END CERTIFICATE-----\n"; +static char client_priv_data[] ="-----BEGIN RSA PRIVATE KEY-----\n" + "MIICXgIBAAKBgQC961AenXrNnbvnvE44SrLMnrSJdwHv0cYZKQD+zjxiBROxjP8x\n" + "eg/BLks8DEAeNk522gpkQ/we6gyXslecnIyQvesje7i3XAPtb0hViogIOMXNM7er\n" + "qDpvfxMQZaVQufSLzC7peVimEfBYRUHvNrM1yxTsggytEWrqZO8oom5HRQIDAQAB\n" + "AoGBAIYnsOLPby3LnC5n8AEHkyHDgdgQvsd/MSYYtuFHIZRD7dNfu+xhQru9TdvO\n" + "84Pj7K07/FczRuc3gUmu6wBv/UIP9To15RHZh+/n537nybGus5S4IYKVvap477To\n" + "0rQDf9ec27iw77gxb7moQ9Otuxwbv0h0Z+1EVLI8d8jHOq0BAkEA9YNr0R+7KXBS\n" + "48yT43g5HpOFkTZzNXWVdpSvYGneb56wslk5Eatp235I4uz/a7Rej5v99W0M3nSe\n" + "/AgHfYn75QJBAMYH/pBx/WkrLj+pPaARlNwInCIC5zUhr6B0IKCt2tvy5eyuc5sd\n" + "AoTFaU+cSI+ZqsRzY8jMKkonktxBg48oJ+ECQQCt4AtlqcFVkbVCm8pJGQXq/7Ni\n" + "qlthiwr1Vkv2TkQ4bPza8pGWT/3Cc2ePPyWN08n8jw+G11p72cAW4mDbqfN5AkEA\n" + "mNYKrkiLn+NnqlJf8W4gSUGL3uQGtYbuGRQHKnuDckWhFm39YzWcgAQsJvkjN1EN\n" + "7thvpsWLzfeE7ODTPGVtgQJATObxYJOt6rms3fAStwuXW3ET77TA1ja4XsUEe5Yu\n" + "JpcQOruJb9XwndqzNbL0dSUePb9gFiBCGKYOyreNTTRTmw==\n" + "-----END RSA PRIVATE KEY-----\n"; +*/ + +/* Server: + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4 (0x4) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=chavroux.cowaddict.org/emailAddress=sdecugis@nict.go.jp + Validity + Not Before: Oct 27 04:03:39 2009 GMT + Not After : Oct 25 04:03:39 2019 GMT + Subject: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=serv.test/emailAddress=serv@test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:a6:f7:1c:a9:90:5b:fa:c8:f6:a3:04:0c:d0:8b: + 45:c3:90:f7:2d:c2:c9:d7:bd:66:8a:7c:1c:51:89: + 40:9e:cd:70:57:cb:00:47:a3:e8:76:8b:00:b3:c9: + c3:0d:b1:b9:2a:08:9f:52:92:82:d3:18:c1:d8:d1: + b8:1e:fd:71:fe:23:ec:19:e9:6d:9d:fd:ae:88:bc: + 39:44:7a:37:ad:c6:88:d1:64:7c:b1:d4:3c:a9:30: + c4:de:51:02:c4:48:4f:25:3e:2f:93:ae:25:32:66: + 9a:dc:f4:44:45:ff:7f:12:49:97:0d:01:8d:13:9a: + d3:8f:9e:2d:62:95:02:0a:c7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 0C:33:C4:7F:39:D0:34:FF:F8:61:A1:46:8B:49:1D:A3:57:B3:4D:58 + X509v3 Authority Key Identifier: + keyid:92:AA:55:9F:B3:77:82:68:89:ED:7E:73:43:66:E4:8B:EE:EA:BF:85 + + Signature Algorithm: sha1WithRSAEncryption + 87:f5:49:a6:04:f9:98:9a:f1:1a:68:ce:06:ae:4c:0c:08:eb: + ba:98:e7:3f:df:22:7f:35:88:1d:b7:8a:f3:89:a3:68:0d:53: + 45:eb:23:a1:dd:6b:dc:b0:80:58:0c:10:0b:49:74:ea:a8:b6: + 8c:2e:c6:73:dc:7a:74:c7:59:3e:79:5a:d2:5c:15:0b:f1:d8: + 19:37:2a:c0:22:75:10:3f:4c:e9:a1:e0:eb:b2:9e:09:70:3d: + 2a:4c:fe:9c:99:36:4b:aa:6c:e1:8b:9c:aa:e1:29:1f:49:6b: + 14:db:12:ae:cf:68:4a:dd:03:e1:3b:ad:79:b4:54:84:1d:bb: + ac:45:c4:85:f1:03:65:65:96:23:ae:e7:97:3c:5c:db:ce:55: + 34:5d:c3:73:ec:cd:f6:0f:a5:81:5f:c2:ab:a3:42:fa:36:7f: + 83:ef:db:0f:cd:62:0b:ea:d9:4f:73:35:68:5f:23:d5:0a:be: + ff:7f:23:9a:af:0d:a5:f8:3e:3a:f0:63:1c:e1:d2:96:81:cf: + 7b:5a:6b:d0:9b:67:56:9e:aa:a9:e8:f1:6c:fb:54:2b:1a:f4: + ef:16:5a:be:1d:a9:c8:d6:cc:f7:42:8c:fe:83:2c:84:8c:80: + fb:1c:88:f6:35:1c:ae:43:72:fa:68:30:9c:25:8b:db:2c:84: + 87:76:9d:b9 +*/ +static char server_cert_data[] ="-----BEGIN CERTIFICATE-----\n" + "MIIDhDCCAmygAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMCSlAx\n" + "DjAMBgNVBAgMBVRva3lvMRAwDgYDVQQHDAdLb2dhbmVpMQ0wCwYDVQQKDARXSURF\n" + "MQ8wDQYDVQQLDAZBQUEgV0cxHzAdBgNVBAMMFmNoYXZyb3V4LmNvd2FkZGljdC5v\n" + "cmcxIjAgBgkqhkiG9w0BCQEWE3NkZWN1Z2lzQG5pY3QuZ28uanAwHhcNMDkxMDI3\n" + "MDQwMzM5WhcNMTkxMDI1MDQwMzM5WjB9MQswCQYDVQQGEwJKUDEOMAwGA1UECAwF\n" + "VG9reW8xEDAOBgNVBAcMB0tvZ2FuZWkxDTALBgNVBAoMBFdJREUxDzANBgNVBAsM\n" + "BkFBQSBXRzESMBAGA1UEAwwJc2Vydi50ZXN0MRgwFgYJKoZIhvcNAQkBFglzZXJ2\n" + "QHRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKb3HKmQW/rI9qMEDNCL\n" + "RcOQ9y3Cyde9Zop8HFGJQJ7NcFfLAEej6HaLALPJww2xuSoIn1KSgtMYwdjRuB79\n" + "cf4j7BnpbZ39roi8OUR6N63GiNFkfLHUPKkwxN5RAsRITyU+L5OuJTJmmtz0REX/\n" + "fxJJlw0BjROa04+eLWKVAgrHAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4\n" + "QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQM\n" + "M8R/OdA0//hhoUaLSR2jV7NNWDAfBgNVHSMEGDAWgBSSqlWfs3eCaIntfnNDZuSL\n" + "7uq/hTANBgkqhkiG9w0BAQUFAAOCAQEAh/VJpgT5mJrxGmjOBq5MDAjrupjnP98i\n" + "fzWIHbeK84mjaA1TResjod1r3LCAWAwQC0l06qi2jC7Gc9x6dMdZPnla0lwVC/HY\n" + "GTcqwCJ1ED9M6aHg67KeCXA9Kkz+nJk2S6ps4YucquEpH0lrFNsSrs9oSt0D4Tut\n" + "ebRUhB27rEXEhfEDZWWWI67nlzxc285VNF3Dc+zN9g+lgV/Cq6NC+jZ/g+/bD81i\n" + "C+rZT3M1aF8j1Qq+/38jmq8Npfg+OvBjHOHSloHPe1pr0JtnVp6qqejxbPtUKxr0\n" + "7xZavh2pyNbM90KM/oMshIyA+xyI9jUcrkNy+mgwnCWL2yyEh3aduQ==\n" + "-----END CERTIFICATE-----\n"; +static char server_priv_data[] ="-----BEGIN RSA PRIVATE KEY-----\n" + "MIICXQIBAAKBgQCm9xypkFv6yPajBAzQi0XDkPctwsnXvWaKfBxRiUCezXBXywBH\n" + "o+h2iwCzycMNsbkqCJ9SkoLTGMHY0bge/XH+I+wZ6W2d/a6IvDlEejetxojRZHyx\n" + "1DypMMTeUQLESE8lPi+TriUyZprc9ERF/38SSZcNAY0TmtOPni1ilQIKxwIDAQAB\n" + "AoGAZv3Ddm0P79CLIt9asEFY1VvUvSuMqkGwwPfx1/HcJJkBFYapM4fN22G/Gyf3\n" + "47ifSWhsLtklTeXVnVMwSh14dJaJQuSEnaFnUUWfjiRbEAXZnMFwAIiaszEZbPap\n" + "NUNpcGl06FZrphYAMkjOVUfjCjfOZDAvL4JGpo271Zx4l0ECQQDYoFFQpBCPx0PK\n" + "TWUmvatXI/Amo94XkGfofbdeeI8PiAJBO5UI6rmjjIVwsJwO9dQb/IlP1/OnBeJv\n" + "p9YW5uixAkEAxVAOKu7mpGu0Q/K2iEUUYDX9YHf253kgkdIDF4iZk4Tcecjoxuru\n" + "fIWu9dMtyDVV+HT2X4cNEnO1/oS3kJII9wJBAJkdwDwiqz4lV6o/yFZ4zAoc8dsu\n" + "CoZXYMq5SYox5tTQit928OHLn4mVgqBjhPsiEVnyx0+zUZpmE2ZemHm5nxECQHfE\n" + "FBVzVYRP6+eil7E3XRrZKqc3qiLunxpkA4RxYebtKnaxwLmdOI1VB9InEQ8JcNmT\n" + "BUkOzJx6p+mJ3XJfchkCQQDWmbMYYJajsjlS4YpdUUj7cBSotA6vtkNVHFr0/ak/\n" + "S+tLkMNuruaInWizK+BKYTIJLlQDf5u5NTrw41vye5Hv\n" + "-----END RSA PRIVATE KEY-----\n"; + +/* Expired: + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 6 (0x6) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=chavroux.cowaddict.org/emailAddress=sdecugis@nict.go.jp + Validity + Not Before: Oct 27 04:06:35 2009 GMT + Not After : Oct 28 04:06:35 2009 GMT + Subject: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=expired.test/emailAddress=expired@test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:e3:17:15:54:85:dc:cf:c7:a0:32:4a:49:7d:55: + 75:9b:29:15:db:7e:87:17:d9:0e:65:44:53:d7:19: + 37:27:c7:c6:fe:c6:dc:72:2b:dc:86:1a:ff:24:6c: + 63:3f:75:9c:0a:14:e1:70:06:79:d4:b9:26:d4:68: + 4c:28:38:ba:34:60:56:02:3d:94:55:4a:1f:4e:5a: + f0:a5:71:4c:3e:71:69:39:ad:bc:aa:55:35:fb:73: + 5b:5f:6c:30:71:8e:8a:b6:a5:06:cc:ee:dd:29:c7: + 52:0d:a7:9c:0f:a1:ba:52:11:e2:1b:b9:74:6b:08: + 87:11:d2:ec:a9:ac:63:63:4f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 1C:AF:66:42:5B:AD:AA:A5:9B:D9:AE:3A:C1:5A:AC:2F:CC:CE:22:6C + X509v3 Authority Key Identifier: + keyid:92:AA:55:9F:B3:77:82:68:89:ED:7E:73:43:66:E4:8B:EE:EA:BF:85 + + Signature Algorithm: sha1WithRSAEncryption + 60:8f:55:55:59:82:0f:64:cb:b8:11:c8:44:ce:bf:69:07:0d: + be:c2:34:be:42:6a:78:15:39:9f:be:8a:17:d6:43:42:c9:7c: + f1:6d:5d:aa:c3:1b:4d:b0:f0:b6:73:46:2a:87:cd:55:56:a3: + 6d:cc:de:a8:28:6a:53:85:9e:e5:68:b7:3c:f5:72:13:7b:d0: + 21:f2:91:49:35:e0:37:1e:28:19:d5:1b:cc:e1:32:1e:7f:b0: + 86:df:43:a4:47:0f:29:0b:eb:51:60:9a:f5:ca:50:f4:2d:59: + cd:fc:50:9d:29:ed:45:98:de:a2:5c:d1:b5:7a:34:ad:7a:73: + 48:8b:a2:9b:89:8e:4a:2e:2a:04:19:d6:62:6a:0d:f0:96:f2: + f0:d0:22:77:3b:7f:b1:2a:f4:3b:17:47:5e:38:07:09:65:ad: + 1d:ea:46:69:6a:96:b6:6b:3b:5c:cc:6e:30:d7:cb:53:69:59: + c2:63:78:2b:03:d4:d4:f7:17:29:99:9a:43:ff:78:0a:af:42: + c5:b3:8d:09:38:5b:30:70:28:c1:97:ab:fd:7f:87:9a:ec:f2: + 97:44:ff:f5:b9:41:30:d1:c6:32:98:69:34:c4:39:30:6f:e2: + d3:b2:70:97:66:ee:41:f5:ae:0f:09:f0:ed:60:96:67:a9:8a: + cd:d6:95:f2 +*/ +/* +static char expired_cert_data[]="-----BEGIN CERTIFICATE-----\n" + "MIIDizCCAnOgAwIBAgIBBjANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMCSlAx\n" + "DjAMBgNVBAgMBVRva3lvMRAwDgYDVQQHDAdLb2dhbmVpMQ0wCwYDVQQKDARXSURF\n" + "MQ8wDQYDVQQLDAZBQUEgV0cxHzAdBgNVBAMMFmNoYXZyb3V4LmNvd2FkZGljdC5v\n" + "cmcxIjAgBgkqhkiG9w0BCQEWE3NkZWN1Z2lzQG5pY3QuZ28uanAwHhcNMDkxMDI3\n" + "MDQwNjM1WhcNMDkxMDI4MDQwNjM1WjCBgzELMAkGA1UEBhMCSlAxDjAMBgNVBAgM\n" + "BVRva3lvMRAwDgYDVQQHDAdLb2dhbmVpMQ0wCwYDVQQKDARXSURFMQ8wDQYDVQQL\n" + "DAZBQUEgV0cxFTATBgNVBAMMDGV4cGlyZWQudGVzdDEbMBkGCSqGSIb3DQEJARYM\n" + "ZXhwaXJlZEB0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjFxVUhdzP\n" + "x6AySkl9VXWbKRXbfocX2Q5lRFPXGTcnx8b+xtxyK9yGGv8kbGM/dZwKFOFwBnnU\n" + "uSbUaEwoOLo0YFYCPZRVSh9OWvClcUw+cWk5rbyqVTX7c1tfbDBxjoq2pQbM7t0p\n" + "x1INp5wPobpSEeIbuXRrCIcR0uyprGNjTwIDAQABo3sweTAJBgNVHRMEAjAAMCwG\n" + "CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV\n" + "HQ4EFgQUHK9mQlutqqWb2a46wVqsL8zOImwwHwYDVR0jBBgwFoAUkqpVn7N3gmiJ\n" + "7X5zQ2bki+7qv4UwDQYJKoZIhvcNAQEFBQADggEBAGCPVVVZgg9ky7gRyETOv2kH\n" + "Db7CNL5CangVOZ++ihfWQ0LJfPFtXarDG02w8LZzRiqHzVVWo23M3qgoalOFnuVo\n" + "tzz1chN70CHykUk14DceKBnVG8zhMh5/sIbfQ6RHDykL61FgmvXKUPQtWc38UJ0p\n" + "7UWY3qJc0bV6NK16c0iLopuJjkouKgQZ1mJqDfCW8vDQInc7f7Eq9DsXR144Bwll\n" + "rR3qRmlqlrZrO1zMbjDXy1NpWcJjeCsD1NT3FymZmkP/eAqvQsWzjQk4WzBwKMGX\n" + "q/1/h5rs8pdE//W5QTDRxjKYaTTEOTBv4tOycJdm7kH1rg8J8O1glmepis3WlfI=\n" + "-----END CERTIFICATE-----\n"; +static char expired_priv_data[]="-----BEGIN RSA PRIVATE KEY-----\n" + "MIICXgIBAAKBgQDjFxVUhdzPx6AySkl9VXWbKRXbfocX2Q5lRFPXGTcnx8b+xtxy\n" + "K9yGGv8kbGM/dZwKFOFwBnnUuSbUaEwoOLo0YFYCPZRVSh9OWvClcUw+cWk5rbyq\n" + "VTX7c1tfbDBxjoq2pQbM7t0px1INp5wPobpSEeIbuXRrCIcR0uyprGNjTwIDAQAB\n" + "AoGASwPoDui9XYHTIGm7xwRA+kVjLAOq+qy//aHJlEeHGcP7r1PfpHNqwH4QhGat\n" + "jlv6dLYbFld9TVDwS8A8UBkVIPLWnCysd5tF2A4C5akx6ouW6HliW/JheYrgl8AV\n" + "PVeR3bm91UbnpC0ABVlw87jp1Ovyr60Suo4jsoJz+CyTa2ECQQD0LJWpnwn1jIlR\n" + "DGkLi7F3E70JJcdhTWzBjGFD+Na+/2ZO0MKLhK+O1WUkKa0oi+e5P1JOnGIpTI8c\n" + "BJOO415RAkEA7hauapYuqGI/auSPH8/nFB5z1G94RTxo2a5THKcG5MqS/8N3ubFj\n" + "i2PPS0lEYVjqoHEsZUsMnDmXp6KDKMAfnwJBAIp+T1UqM8fmsmwaEerOjRXxSCNM\n" + "Hk5+T9Vn/jNDjOpAipLhrbbcx4bIWtmsGd8Jm6Fi3RhhcvvhxLorjlZZeEECQQCf\n" + "IaPD88sNmlUewdLzhUbCiLQMadCuHflKfRxpyy1tYAQuVFxCTdDlynkzra25ju+K\n" + "+vmcXjP4evnk/lbBtt+rAkEAgOr4Apgs3nMppngPV5yFx0NDqH2n8PlEAM1Il4Qs\n" + "IuuK18v0KwlUGAfEEmCiNh1e1qkLmD0CnI2QjYAjcLQUhw==\n" + "-----END RSA PRIVATE KEY-----\n"; +*/ + +/* Unknown CA certificate : + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=chavroux.cowaddict.org/emailAddress=sdecugis@nict.go.jp + Validity + Not Before: Oct 28 08:04:40 2009 GMT + Not After : Oct 28 08:04:40 2010 GMT + Subject: C=JP, ST=Tokyo, L=Koganei, O=WIDE, OU=AAA WG, CN=unknown.cs/emailAddress=unknown@ca + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:e6:3a:d5:8a:14:c8:15:d0:f0:5c:03:c3:af:33: + 51:2c:17:b7:65:ac:45:e8:48:2d:ae:70:fd:7c:79: + 3a:c7:80:c8:50:53:d0:19:d8:3a:26:a8:16:4d:4c: + 04:17:09:df:69:9b:59:2b:89:c8:e0:60:bb:1d:37: + 82:d2:3f:17:39:c9:8f:5d:76:e1:0f:6e:08:9a:8f: + 16:4a:ea:83:86:f9:bd:15:14:56:68:87:79:05:f9: + 5f:66:11:bd:22:46:26:64:be:57:16:51:66:41:50: + ac:f2:b1:ca:d0:38:11:4b:4c:b2:ee:25:36:6e:d3: + b9:63:72:c4:84:82:1c:2b:27 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + BA:5A:9D:D2:B0:4B:72:D6:1F:00:11:0B:B5:7B:59:DF:08:38:81:BE + X509v3 Authority Key Identifier: + keyid:52:C5:A4:63:B8:DB:AC:F2:92:34:2F:72:56:71:C8:11:8E:76:E6:DF + + Signature Algorithm: sha1WithRSAEncryption + 90:8f:3b:bd:e3:a1:ca:6a:92:a6:fd:f0:64:ae:46:83:32:35: + 61:80:57:8b:30:12:70:02:e1:51:d9:87:c8:af:d9:4b:b9:6d: + bf:ab:86:5f:19:1f:dc:af:84:67:bf:3c:bf:33:f3:7c:c6:81: + 7b:e4:e9:26:1d:bc:d6:8c:ab:72:94:7f:85:33:95:d9:24:ec: + fd:7b:d2:fd:50:3e:e5:61:4f:75:51:ae:c6:4a:ec:df:cf:aa: + 73:a5:08:f7:f3:9a:40:66:48:f0:8e:9b:43:b1:30:f3:e3:c8: + 36:3f:68:36:6a:1c:aa:16:40:49:b4:73:9a:71:f1:17:6c:0b: + d3:e1:a7:b7:40:de:2c:3c:36:7c:d4:dd:d6:94:c9:d7:5f:f5: + ae:35:56:e8:cc:65:9c:bb:3d:e8:7a:ca:0e:ed:78:03:41:cb: + fd:80:81:de:f9:de:b2:14:4b:81:24:36:de:29:c1:06:11:86: + 8c:a9:b0:0c:c7:57:cf:79:a7:3a:84:0c:27:dc:86:6d:cb:44: + 2d:26:dc:7e:fb:17:d6:b2:3d:31:03:d3:f1:ab:5d:91:5d:94: + e4:94:88:70:96:b3:7c:0f:15:fe:c8:c6:4d:99:37:ab:09:0c: + da:ba:b6:0e:fa:5e:bb:4b:ce:04:21:06:09:a9:2c:27:86:76: + cc:ee:73:6f +*/ +/* +static char notrust_ca_data[] = "-----BEGIN CERTIFICATE-----\n" + "MIIEqjCCA5KgAwIBAgIJAP3UMghSlH9PMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD\n" + "VQQGEwJKUDEOMAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB0tvZ2FuZWkxDTALBgNV\n" + "BAoMBFdJREUxDzANBgNVBAsMBkFBQSBXRzEfMB0GA1UEAwwWY2hhdnJvdXguY293\n" + "YWRkaWN0Lm9yZzEiMCAGCSqGSIb3DQEJARYTc2RlY3VnaXNAbmljdC5nby5qcDAe\n" + "Fw0wOTEwMjgwODAzNDRaFw0xOTEwMjYwODAzNDRaMIGUMQswCQYDVQQGEwJKUDEO\n" + "MAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB0tvZ2FuZWkxDTALBgNVBAoMBFdJREUx\n" + "DzANBgNVBAsMBkFBQSBXRzEfMB0GA1UEAwwWY2hhdnJvdXguY293YWRkaWN0Lm9y\n" + "ZzEiMCAGCSqGSIb3DQEJARYTc2RlY3VnaXNAbmljdC5nby5qcDCCASIwDQYJKoZI\n" + "hvcNAQEBBQADggEPADCCAQoCggEBALKW9iSUggF5mbvYe1Xk128Csfiijx+fwH5y\n" + "ZqWrHNt0YG/tZSwyCDMWBLXTeuYsntg5y0mcpsrN8v02tvrPiCzDfRPyz3mG68us\n" + "DPEEgQ1kqL2Gsti2DUcsdyZcDM+4rgsWRivgOTVyoNimv5f+xgmPYoElkgelLwZK\n" + "WxGt1VCebOxP3qZA3hSHWE1hJgL4svful7RD1PbwPzidxJKITyAiJoPKWQA9cjSa\n" + "gVzRQ7S4vmYALJn7xe+dMFRcfAK8RMv7/gJF6Rw7zufW0DIZK98KZs6aL0lmMPVk\n" + "f31N2uvndf+cjy0n4luwEoXY+TeJZY205lbwHrzR0rH75FSm0RsCAwEAAaOB/DCB\n" + "+TAdBgNVHQ4EFgQUUsWkY7jbrPKSNC9yVnHIEY525t8wgckGA1UdIwSBwTCBvoAU\n" + "UsWkY7jbrPKSNC9yVnHIEY525t+hgZqkgZcwgZQxCzAJBgNVBAYTAkpQMQ4wDAYD\n" + "VQQIDAVUb2t5bzEQMA4GA1UEBwwHS29nYW5laTENMAsGA1UECgwEV0lERTEPMA0G\n" + "A1UECwwGQUFBIFdHMR8wHQYDVQQDDBZjaGF2cm91eC5jb3dhZGRpY3Qub3JnMSIw\n" + "IAYJKoZIhvcNAQkBFhNzZGVjdWdpc0BuaWN0LmdvLmpwggkA/dQyCFKUf08wDAYD\n" + "VR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEACANo6IR3OQlQaXHJaprVVDvl\n" + "oMJC0FRbVCK503sbmWTJL98UqxRdsTZNIL07gXlK0oUKyiNijIXiLG8d5IlUrDxF\n" + "H/Vsu6s8k3/PpAUVeiO2oygWqvU5NGvt0jg54MrOJKhYYPWrzbmHty+cAXyoNzOR\n" + "+W5RX6HRQgxvZWQq2Ok46VX622R1nNjFmCBYT7I7/gWG+hkbIAoH6d9sULLjpC+B\n" + "bI+L/N7ac9/Og8pGIgpUI60Gn5zO93+E+Nhg+1BlcDHGnQD6vFNs8LYp5CCX/Zj1\n" + "tWFVXZnx58odaU3M4t9/ZQnkZdx9YJIroETbN0PoqlnSagBjgUvbWwn4YCotCA==\n" + "-----END CERTIFICATE-----\n"; + +static char notrust_cert_data[]="-----BEGIN CERTIFICATE-----\n" + "MIIDhjCCAm6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMCSlAx\n" + "DjAMBgNVBAgMBVRva3lvMRAwDgYDVQQHDAdLb2dhbmVpMQ0wCwYDVQQKDARXSURF\n" + "MQ8wDQYDVQQLDAZBQUEgV0cxHzAdBgNVBAMMFmNoYXZyb3V4LmNvd2FkZGljdC5v\n" + "cmcxIjAgBgkqhkiG9w0BCQEWE3NkZWN1Z2lzQG5pY3QuZ28uanAwHhcNMDkxMDI4\n" + "MDgwNDQwWhcNMTAxMDI4MDgwNDQwWjB/MQswCQYDVQQGEwJKUDEOMAwGA1UECAwF\n" + "VG9reW8xEDAOBgNVBAcMB0tvZ2FuZWkxDTALBgNVBAoMBFdJREUxDzANBgNVBAsM\n" + "BkFBQSBXRzETMBEGA1UEAwwKdW5rbm93bi5jczEZMBcGCSqGSIb3DQEJARYKdW5r\n" + "bm93bkBjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5jrVihTIFdDwXAPD\n" + "rzNRLBe3ZaxF6EgtrnD9fHk6x4DIUFPQGdg6JqgWTUwEFwnfaZtZK4nI4GC7HTeC\n" + "0j8XOcmPXXbhD24Imo8WSuqDhvm9FRRWaId5BflfZhG9IkYmZL5XFlFmQVCs8rHK\n" + "0DgRS0yy7iU2btO5Y3LEhIIcKycCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgB\n" + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE\n" + "FLpandKwS3LWHwARC7V7Wd8IOIG+MB8GA1UdIwQYMBaAFFLFpGO426zykjQvclZx\n" + "yBGOdubfMA0GCSqGSIb3DQEBBQUAA4IBAQCQjzu946HKapKm/fBkrkaDMjVhgFeL\n" + "MBJwAuFR2YfIr9lLuW2/q4ZfGR/cr4Rnvzy/M/N8xoF75OkmHbzWjKtylH+FM5XZ\n" + "JOz9e9L9UD7lYU91Ua7GSuzfz6pzpQj385pAZkjwjptDsTDz48g2P2g2ahyqFkBJ\n" + "tHOacfEXbAvT4ae3QN4sPDZ81N3WlMnXX/WuNVbozGWcuz3oesoO7XgDQcv9gIHe\n" + "+d6yFEuBJDbeKcEGEYaMqbAMx1fPeac6hAwn3IZty0QtJtx++xfWsj0xA9Pxq12R\n" + "XZTklIhwlrN8DxX+yMZNmTerCQzaurYO+l67S84EIQYJqSwnhnbM7nNv\n" + "-----END CERTIFICATE-----\n"; +static char notrust_priv_data[]="-----BEGIN RSA PRIVATE KEY-----\n" + "MIICXQIBAAKBgQDmOtWKFMgV0PBcA8OvM1EsF7dlrEXoSC2ucP18eTrHgMhQU9AZ\n" + "2DomqBZNTAQXCd9pm1kricjgYLsdN4LSPxc5yY9dduEPbgiajxZK6oOG+b0VFFZo\n" + "h3kF+V9mEb0iRiZkvlcWUWZBUKzyscrQOBFLTLLuJTZu07ljcsSEghwrJwIDAQAB\n" + "AoGAeRec1SGVE5Rvt5XrSK0vFofq2DlCE6hTDpszWFLTDbe4pDdRDybhfw+Nm15O\n" + "EGgK8BrbTcEMvKdkAzv9POQeLDE8JImgesHZFxN3jnkK+b762BGRDt57DzvMJsfj\n" + "1LBle+UBnZB1CvjrINvu+tNMVPlUpjIstbpMq0D+s01+ijECQQD8MHTv/M+Uc86u\n" + "1SFywgs+eQPQ8g0OoTLxzqo6YhW8FtwLjoRCZx2TNQS5gYBuQrixd/yE0Spfv9aS\n" + "UtlAaOc1AkEA6bVufggHVHcgiWqS8CHzb6g/GRxQixVshOsoVLMkCSz04zlwIfXF\n" + "c03hh5RJVv7jmuBmhHbayujMgvinw75oawJAQb9oXUDt5Wgj1FTgeYi5YbovEoRo\n" + "fw3ruDsHCl2UCQt0ptarCJzVixFhf/ORRi3C9RGxFfdqMrhS+qb62N4AmQJBALYU\n" + "T1BLiwJoiWXmLTJ/EP0V9Irov2uMtm5cE6DhrJqlduksz8r1gu7RZ3tMsVLg5Iy+\n" + "dcCQJOffNa54caQUTZ8CQQDTs/70Nr6F6ktrtmtU/S7lIitpQJCu9u/SPyBYPmFZ\n" + "9Axy6Ee66Php+eWDNP4Ln4axrapD0732wD8DcmGDVHij\n" + "-----END RSA PRIVATE KEY-----\n"; +*/ + +/* Diffie-Hellman parameters, generated with GNUTLS certtool: +certtool --generate-dh-params + Generator: 06 + + Prime: ea:c3:75:0b:32:cf:d9:17:98:5c:da:d1 + e0:1d:b9:7c:be:29:60:b0:6f:68:a9:f6 + 8d:75:05:59:69:04:ae:39:7c:2b:74:04 + 3c:e2:da:28:8a:9b:93:aa:67:05:a7:3e + 06:3e:0d:31:63:88:55:ad:5a:bd:41:22 + b7:58:a7:45:b3:d5:03:ad:de:3c:8d:69 + 42:bf:84:3d:c1:90:e7:39:6a:4b:87:01 + 19:e5:f3:a4:e5:8e:e2:45:d5:0c:6b:17 + 22:2b:2e:50:83:91:0c:5b:82:fc:72:27 + 49:3b:9f:29:11:53:c7:90:b8:8d:87:73 + 1a:7b:05:ab:cb:30:59:16:71:30:60:1b + 4c:80:15:3a:a2:d3:47:b7:4a:61:de:64 + 7e:79:de:88:53:b7:7a:c6:a2:9a:bb:55 + 40:2d:7a:71:c7:41:b5:29:df:d7:5c:fb + 42:e4:d8:5e:0b:99:d3:3c:93:0f:33:51 + 8b:f4:60:e4:c5:b5:58:21:c0:51:c4:43 + 25:7c:37:fe:5c:d3:62:6c:2a:af:a7:2a + 82:d5:d3:e2:bb:5d:ad:84:15:f6:78:d9 + d5:a8:f7:f0:48:5c:8d:e0:3d:04:ac:cf + aa:34:3f:5d:f2:0d:3d:ee:ec:b8:d8:e8 + ad:dc:d3:40:59:a0:fd:45:62:47:63:c0 + bd:f5:df:8b +*/ +static char dh_params_data[] = "-----BEGIN DH PARAMETERS-----\n" + "MIIBCAKCAQEA6sN1CzLP2ReYXNrR4B25fL4pYLBvaKn2jXUFWWkErjl8K3QEPOLa\n" + "KIqbk6pnBac+Bj4NMWOIVa1avUEit1inRbPVA63ePI1pQr+EPcGQ5zlqS4cBGeXz\n" + "pOWO4kXVDGsXIisuUIORDFuC/HInSTufKRFTx5C4jYdzGnsFq8swWRZxMGAbTIAV\n" + "OqLTR7dKYd5kfnneiFO3esaimrtVQC16ccdBtSnf11z7QuTYXguZ0zyTDzNRi/Rg\n" + "5MW1WCHAUcRDJXw3/lzTYmwqr6cqgtXT4rtdrYQV9njZ1aj38EhcjeA9BKzPqjQ/\n" + "XfINPe7suNjordzTQFmg/UViR2PAvfXfiwIBBg==\n" + "-----END DH PARAMETERS-----\n"; + + + +int fddparse(struct fd_config * conf) +{ + return shParse(conf); + +#if 0 + /* sctp */ + conf->cnf_sec_data.tls_disabled = 1; + conf->cnf_port_tls = 0; // DIAMETER_SECURE_PORT; + conf->cnf_sctp_str = 10; + conf->cnf_flags.no_fwd = 1; + conf->cnf_flags.no_ip4 = 0; + conf->cnf_flags.no_ip6 = 0; + conf->cnf_flags.no_tcp = 1; + conf->cnf_flags.no_sctp = 0; + conf->cnf_flags.pr_tcp = 0; + conf->cnf_flags.tls_alg = 0; + + /* tcp */ + conf->cnf_sec_data.tls_disabled = 0; + conf->cnf_port_tls = 0; + conf->cnf_sctp_str = 10; + conf->cnf_flags.no_fwd = 1; + conf->cnf_flags.no_ip4 = 0; + conf->cnf_flags.no_ip6 = 0; + conf->cnf_flags.no_tcp = 0; + conf->cnf_flags.no_sctp = 1; + conf->cnf_flags.pr_tcp = 1; + conf->cnf_flags.tls_alg = 0; +#endif + + return 0; + + gnutls_datum_t ca = { (uint8_t *)ca_data, sizeof(ca_data) }; + gnutls_datum_t server_cert = { (uint8_t *)server_cert_data, sizeof(server_cert_data) }; + gnutls_datum_t server_priv = { (uint8_t *)server_priv_data, sizeof(server_priv_data) }; + // gnutls_datum_t client_cert = { (uint8_t *)client_cert_data, sizeof(client_cert_data) }; + // gnutls_datum_t client_priv = { (uint8_t *)client_priv_data, sizeof(client_priv_data) }; + // gnutls_datum_t expired_cert = { (uint8_t *)expired_cert_data, sizeof(expired_cert_data) }; + // gnutls_datum_t expired_priv = { (uint8_t *)expired_priv_data, sizeof(expired_priv_data) }; + // gnutls_datum_t notrust_ca = { (uint8_t *)notrust_ca_data, sizeof(notrust_ca_data) }; + // gnutls_datum_t notrust_cert = { (uint8_t *)notrust_cert_data, sizeof(notrust_cert_data) }; + // gnutls_datum_t notrust_priv = { (uint8_t *)notrust_priv_data, sizeof(notrust_priv_data) }; + gnutls_datum_t dh_params = { (uint8_t *)dh_params_data, sizeof(dh_params_data) }; + + int ret; + + /* Set the CA parameter in the config */ + CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( conf->cnf_sec_data.credentials, + &ca, + GNUTLS_X509_FMT_PEM), ); + assert( 1 == ret ); + +#ifdef GNUTLS_VERSION_300 + { + /* We import these CA in the trust list */ + gnutls_x509_crt_t * calist; + unsigned int cacount = 0; + + CHECK_GNUTLS_DO( ret = gnutls_x509_crt_list_import2(&calist, &cacount, &ca, GNUTLS_X509_FMT_PEM, + GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED), ); + CHECK( 1, cacount ); + + CHECK_GNUTLS_DO( ret = gnutls_x509_trust_list_add_cas (conf->cnf_sec_data.trustlist, calist, cacount, 0), ); + CHECK( 1, ret ); + } + + /* Use certificate verification during the handshake */ + gnutls_certificate_set_verify_function (conf->cnf_sec_data.credentials, fd_tls_verify_credentials_2); + +#endif /* GNUTLS_VERSION_300 */ + + + /* Set the server credentials (in config) */ + CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_key_mem( conf->cnf_sec_data.credentials, + &server_cert, + &server_priv, + GNUTLS_X509_FMT_PEM), ); + assert( GNUTLS_E_SUCCESS == ret ); + + /* Set the default priority */ + CHECK_GNUTLS_DO( ret = gnutls_priority_init( &conf->cnf_sec_data.prio_cache, "NORMAL"/*GNUTLS_DEFAULT_PRIORITY*/, NULL), ); + assert( GNUTLS_E_SUCCESS == ret ); + + /* Set default DH params */ + CHECK_GNUTLS_DO( ret = gnutls_dh_params_import_pkcs3( conf->cnf_sec_data.dh_cache, &dh_params, GNUTLS_X509_FMT_PEM), ); + assert( GNUTLS_E_SUCCESS == ret ); + + return 0; +} + +int fd_sh_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp ) +{ + struct avp * nextavp; + struct avp_hdr * nextavphdr; + struct dict_avp_data dictdata; + + + TRACE_ENTRY("%p %p %p", groupedavp, what, avp); + + CHECK_FCT( fd_dict_getval(what, &dictdata) ); + + // Loop only in the group AVP + CHECK_FCT( fd_msg_browse(groupedavp, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) ); + CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) ); + + while (nextavphdr) { + + if ( (nextavphdr->avp_code == dictdata.avp_code) && (nextavphdr->avp_vendor == dictdata.avp_vendor) ) // always 0 if no Vendor flag + { + break; + } + + // Otherwise move to next AVP in the grouped AVP + CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) ); + + if(nextavp!=NULL) + { + CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) ); + } + else + nextavphdr=NULL; + } + if (avp) + *avp = nextavp; + + if (avp && nextavp) { + struct dictionary * dict; + CHECK_FCT( fd_dict_getdict( what, &dict) ); + CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), ); + } + + if (avp || nextavp) + return 0; + else + return ENOENT; +} + + +EXTENSION_ENTRY("test_app", ta_entry); diff --git a/plat/diameter/extensions/sh_app/sh_app.h b/plat/diameter/extensions/sh_app/sh_app.h new file mode 100644 index 0000000..b2dccdc --- /dev/null +++ b/plat/diameter/extensions/sh_app/sh_app.h @@ -0,0 +1,538 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Header file for the app_test extension. + * + * This extension provides a way to send configurable messages on the network + * + * See the app_test.conf.sample file for the format of the configuration file. + */ +#ifndef __SH_APP_H__ +#define __SH_APP_H__ + +#include "extension.h" +#include + + +#define SH_VND_ID 10415 +#define SH_APP_ID_OLD 16777217 +#define SH_APP_ID 4 + +#define HW_VND_ID 2011 + +/* Mode for the extension */ +#define MODE_SERV 0x1 +#define MODE_CLI 0x2 +#define MODE_BENCH 0x4 + + + +#ifndef TEST_APP_DEFAULT_SIGNAL +#define TEST_APP_DEFAULT_SIGNAL SIGUSR1 +#endif /* TEST_APP_DEFAULT_SIGNAL */ + +#if 0 +/* encode avp */ +#define SEARCH_AVP_OLD_(name, vendor_id, retval) \ + __avp.avp_code = 0; \ + __avp.avp_name = name; \ + __avp.avp_vendor = vendor_id; \ + LOG_D("SEARCH_AVP_ avpName:%s avpVendorID:%d", name, SH_VND_ID); \ + CHECK_FCT_DO( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_AND_VENDOR, &__avp, retval, ENOENT), goto out ) +#endif +#define SEARCH_AVP_(name, vendor_id, retval) \ +{ struct dict_avp_request tmp_avp;\ + tmp_avp.avp_code = 0; \ + tmp_avp.avp_name = name; \ + tmp_avp.avp_vendor = vendor_id; \ + LOG_D("SEARCH_AVP_ avpName:%s avpVendorID:%d", name, SH_VND_ID); \ + CHECK_FCT_DO( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_AND_VENDOR, &tmp_avp, retval, ENOENT), goto out ); \ +} + + + +#define EN_GRPAVP_U32(udr_search_name, vendor_id, udr, u32_val) \ +{ \ + SEARCH_AVP_(udr_search_name, vendor_id, &udr); \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ), goto out ); \ + val.u32 = u32_val; \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, avp ), goto out ); \ +} +#define EN_GRPAVP_U32_(udr_search_name, vendor_id, udr, u32_val, grpavp) \ +{ \ + SEARCH_AVP_(udr_search_name, vendor_id, &udr); \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ), goto out ); \ + val.u32 = u32_val; \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, avp ), goto out ); \ +} +#define EN_GRPAVP_U64(udr_search_name, vendor_id, udr, u64_val) \ +{ \ + SEARCH_AVP_(udr_search_name, vendor_id, &udr); \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ), goto out ); \ + val.u64 = u64_val; \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, avp ), goto out ); \ +} + +#define EN_GRPAVP_U64_(udr_search_name, vendor_id, udr, u64_val, grpavp) \ +{ \ + SEARCH_AVP_(udr_search_name, vendor_id, &udr); \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ), goto out ); \ + val.u64 = u64_val; \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, avp ), goto out ); \ +} +#define EN_GRPAVP_STR(udr_search_name, vendor_id, udr, str, grpavp) \ +{ \ + SEARCH_AVP_(udr_search_name, vendor_id, &udr); \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ), goto out ); \ + val.os.data = (uint8_t*)(str); \ + val.os.len = strlen(str); \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, avp ), goto out ); \ +} +#define EN_GRPAVP_STR_BCD(udr_search_name, vendor_id, udr, str, str_len, grpavp) \ +{ \ + SEARCH_AVP_(udr_search_name, vendor_id, &udr); \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ), goto out ); \ + val.os.data = (uint8_t*)(str); \ + memcpy(val.os.data, str, str_len);\ + val.os.len = str_len; \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( grpavp, MSG_BRW_LAST_CHILD, avp ), goto out ); \ +} + +#define EN_AVP_U32(udr, u32_val, msg_name, log_info) \ +{ \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ), goto out ); \ + val.u32 = u32_val; \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( msg_name, MSG_BRW_LAST_CHILD, avp ), goto out ); \ + LOG_N("%s\n", log_info); \ +} + +#define EN_AVP_STR(udr, str, msg_name, log_info) \ +{ \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ) , goto out ); \ + val.os.data = (unsigned char *)(str); \ + val.os.len = strlen(str); \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( msg_name, MSG_BRW_LAST_CHILD, avp ), goto out ); \ + LOG_N("%s\n", log_info); \ +} + +#define EN_AVP_BCDSTR(udr, str, tmplen, msg_name, log_info) \ +{ \ + CHECK_FCT_DO( fd_msg_avp_new ( udr, 0, &avp ) , goto out ); \ + val.os.data = (unsigned char *)(str); \ + val.os.len = tmplen; \ + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); \ + CHECK_FCT_DO( fd_msg_avp_add( msg_name, MSG_BRW_LAST_CHILD, avp ), goto out ); \ + LOG_N("%s\n", log_info); \ +} + +/* parse avp */ +#define PARSE_GRPAVP_U32(grpavp, obj, avp, avphdr, tip, val) \ +CHECK_FCT( fd_sh_avp_search_avp ( grpavp, obj, &avp) ); \ +if(avp != NULL) \ +{ \ + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); \ +} +// LOG_N("fj %s:%d", tip, val); + +#define PARSE_GRPAVP_U64(grpavp, obj, avp, avphdr, tip, val) \ +CHECK_FCT( fd_sh_avp_search_avp ( grpavp, obj, &avp) ); \ +if(avp != NULL) \ +{ \ + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); \ +} +// LOG_N("fj %s:%lu", tip, val); + + +#define PARSE_GRPAVP_STR(grpavp, obj, avp, avphdr, tip, val) \ +CHECK_FCT( fd_sh_avp_search_avp ( grpavp, obj, &avp) ); \ +if(avp != NULL) \ +{ \ + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); \ +} + + + +#define PARSE_AVP_U32(msg, obj, avp, avphdr, tip, val) \ +CHECK_FCT( fd_msg_search_avp ( msg, obj, &avp) ); \ +if(avp != NULL) \ +{ \ + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); \ +} +// LOG_N("fj %s:%d", tip, val); + +#define PARSE_AVP_STR(msg, obj, avp, avphdr, tip, val) \ +CHECK_FCT( fd_msg_search_avp ( msg, obj, &avp) ); \ +if(avp != NULL) \ +{ \ + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); \ +} +// LOG_N("fj %s:%s", tip, val); + + + +/* udr avp */ +/* +< Session-Id > +[ DRMP ] +{ Vendor-Specific-Application-Id } +{ Auth-Session-State } +{ Origin-Host } +{ Origin-Realm } +[ Destination-Host ] +{ Destination-Realm } +*[ Supported-Features ] +{ User-Identity } +[ Wildcarded-Public-Identity ] +[ Wildcarded-IMPU ] +[ Server-Name ] +*[ Service-Indication ] +*{ Data-Reference } +*[ Identity-Set ] +[ Requested-Domain ] +[ Current-Location ] +*[ DSAI-Tag ] +[ Session-Priority ] +[ User-Name ] +[ Requested-Nodes ] +[ Serving-Node-Indication ] +[ Pre-paging-Supported ] +[ Local-Time-Zone-Indication ] +[ UDR-Flags ] +[ Call-Reference-Info ] +[ OC-Supported-Features ] +*[ AVP ] +*[ Proxy-Info ] +*[ Route-Record ] +*/ +struct sh_udr_msg{ + struct dict_object * udr_session_id ; + struct dict_object * udr_drmp; + + struct dict_object * udr_vendor_specific_application_id; + struct dict_object * udr_auth_application_d; + struct dict_object * udr_acct_application_id; + + struct dict_object * udr_auth_session_state; + struct dict_object * udr_origin_host; + struct dict_object * udr_origin_realm; + struct dict_object * udr_destination_host; + struct dict_object * udr_destination_realm; + + struct dict_object * udr_supported_features; + struct dict_object * udr_vendor_id; + struct dict_object * udr_feature_list_id; + struct dict_object * udr_feature_list; + + struct dict_object * udr_user_identity; + struct dict_object * udr_public_identity; + struct dict_object * udr_msisdn; + + struct dict_object * udr_wildcarded_public_identity; + struct dict_object * udr_wildcarded_impu; + struct dict_object * udr_server_name; + struct dict_object * udr_service_indication; + struct dict_object * udr_data_reference; + struct dict_object * udr_identity_set; + struct dict_object * udr_requested_domain; + struct dict_object * udr_current_location; + struct dict_object * udr_dsai_tag; + struct dict_object * udr_session_priority; + struct dict_object * udr_user_name; + struct dict_object * udr_requested_nodes; + struct dict_object * udr_serving_node_indication; + struct dict_object * udr_pre_paging_supported; + struct dict_object * udr_local_time_zone_indication; + struct dict_object * udr_udr_flags; + + struct dict_object * udr_call_reference_info; + struct dict_object * udr_call_reference_number; + struct dict_object * udr_as_number; + + struct dict_object * udr_oc_supported_features; + struct dict_object * udr_oc_feature_vector; + + struct dict_object * udr_proxy_info; + struct dict_object * udr_route_record; +}; + +/* uda avp */ +/* +< Session-Id > +[ DRMP ] +{ Vendor-Specific-Application-Id } +[ Result-Code ] +[ Experimental-Result ] +{ Auth-Session-State } +{ Origin-Host } +{ Origin-Realm } +*[ Supported-Features ] +[ Wildcarded-Public-Identity ] +[ Wildcarded-IMPU ] +[ User-Data ] +[ OC-Supported-Features ] +[ OC-OLR ] +*[ AVP ] +*[ Failed-AVP ] +*[ Proxy-Info ] +*[ Route-Record ] +*/ +struct sh_uda_msg{ + struct dict_object * uda_session_id; + struct dict_object * uda_drmp; + + struct dict_object * uda_vendor_specific_application_id; + struct dict_object * uda_vendor_id; + struct dict_object * uda_auth_application_d; + struct dict_object * uda_acct_application_id; + + struct dict_object * uda_result_code; + + struct dict_object * uda_experimental_result; + struct dict_object * uda_experimental_result_code; + + struct dict_object * uda_auth_session_state; + struct dict_object * uda_origin_host; + struct dict_object * uda_origin_realm; + + struct dict_object * uda_supported_features; + struct dict_object * uda_feature_list_id; + struct dict_object * uda_feature_list; + + struct dict_object * uda_wildcarded_public_identity; + struct dict_object * uda_wildcarded_impu; + struct dict_object * uda_user_data; + struct dict_object * uda_oc_supported_features; + struct dict_object * uda_oc_feature_vector; + + struct dict_object * uda_oc_olr; + struct dict_object * uda_oc_sequence_number; + struct dict_object * uda_oc_report_type; + struct dict_object * uda_oc_reduction_percentage; + struct dict_object * uda_oc_validity_duration; + + struct dict_object * uda_failed_avp; + struct dict_object * uda_proxy_info; + struct dict_object * uda_route_record; +}; + + +/* +< Profile-Update-Request > ::= < Diameter Header: 307, REQ, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Destination-Host ] + { Destination-Realm } + *[ Supported-Features ] + { User-Identity } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ User-Name ] + *{ Data-Reference } + { User-Data } + [ OC-Supported-Features ] + *[ AVP ] + *[ Proxy-Info ] + *[ Route-Record ] +*/ +struct sh_pur_msg{ + struct dict_object * pur_session_id ; + struct dict_object * pur_drmp; + + struct dict_object * pur_vendor_specific_application_id; + struct dict_object * pur_auth_application_d; + struct dict_object * pur_acct_application_id; + + struct dict_object * pur_auth_session_state; + struct dict_object * pur_origin_host; + struct dict_object * pur_origin_realm; + struct dict_object * pur_destination_host; + struct dict_object * pur_destination_realm; + + struct dict_object * pur_supported_features; + struct dict_object * pur_vendor_id; + struct dict_object * pur_feature_list_id; + struct dict_object * pur_feature_list; + + struct dict_object * pur_user_identity; + struct dict_object * pur_public_identity; + struct dict_object * pur_msisdn; + + struct dict_object * pur_wildcarded_public_identity; + struct dict_object * pur_wildcarded_impu; + struct dict_object * pur_user_name; + struct dict_object * pur_data_reference; + + struct dict_object * pur_user_date; + + struct dict_object * pur_oc_supported_features; + struct dict_object * pur_oc_feature_vector; + + struct dict_object * pur_proxy_info; + struct dict_object * udr_route_record; +}; + + +/* +< Profile-Update-Answer > ::=< Diameter Header: 307, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ Repository-Data-ID ] + [ Data-Reference ] + *[ Supported-Features ] + [ OC-Supported-Features ] + [ OC-OLR ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] +*/ +struct sh_pua_msg{ + struct dict_object * pua_session_id ; + struct dict_object * pua_drmp; + + struct dict_object * pua_vendor_specific_application_id; + struct dict_object * pua_vendor_id; + struct dict_object * pua_auth_application_d; + struct dict_object * pua_acct_application_id; + + struct dict_object * pua_result_code; + + struct dict_object * pua_experimental_result; + struct dict_object * pua_experimental_result_code; + + struct dict_object * pua_auth_session_state; + + struct dict_object * pua_origin_host; + struct dict_object * pua_origin_realm; + + struct dict_object * pua_wildcarded_public_identity; + struct dict_object * pua_wildcarded_impu; + + struct dict_object * pua_repository_data_id; + struct dict_object * pua_service_indication; + struct dict_object * pua_sequence_number; + + struct dict_object * pua_data_reference; + + struct dict_object * pua_supported_features; + struct dict_object * pua_feature_list_id; + struct dict_object * pua_feature_list; + + struct dict_object * pua_oc_supported_features; + struct dict_object * pua_oc_feature_vector; + + struct dict_object * pua_oc_olr; + struct dict_object * pua_oc_sequence_number; + struct dict_object * pua_oc_report_type; + struct dict_object * pua_oc_reduction_percentage; + struct dict_object * pua_oc_validity_duration; + + struct dict_object * pua_proxy_info; + struct dict_object * pua_route_record; +}; + + + +/* The module configuration */ +struct ta_conf { + uint32_t vendor_id; /* default 999999 */ + uint32_t appli_id; /* default 123456 */ + uint32_t cmd_id; /* default 234567 */ + uint32_t avp_id; /* default 345678 */ + uint32_t long_avp_id; /* default 0 */ + size_t long_avp_len; /* default 5000 */ + int mode; /* default MODE_SERV | MODE_CLI */ + char * dest_realm; /* default local realm */ + char * dest_host; /* default NULL */ + char * user_name; /* default NULL */ + int signal; /* default TEST_APP_DEFAULT_SIGNAL */ + int bench_concur; /* default 100 */ + int bench_duration; /* default 10 */ + struct ta_stats { + unsigned long long nb_echoed; /* server */ + unsigned long long nb_sent; /* client */ + unsigned long long nb_recv; /* client */ + unsigned long long nb_errs; /* client */ + unsigned long shortest; /* fastest answer, in microseconds */ + unsigned long longest; /* slowest answer, in microseconds */ + unsigned long avg; /* average answer time, in microseconds */ + } stats; + pthread_mutex_t stats_lock; +}; +extern struct ta_conf * ta_conf; + +/* Parse the configuration file */ +int ta_conf_handle(char * conffile); + +/* Handle incoming messages (server) */ +int sh_serv_init(void); +void sh_serv_fini(void); + +/* Create outgoing message (client) */ +int sh_cli_init(void); +void sh_cli_finit(void); + +/* Benchmark flavour */ +int ta_bench_init(void); +void ta_bench_fini(void); + +/* Initialize dictionary definitions */ +int ta_dict_init(void); + + +int fd_sh_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp ); + + +#endif /* __SH_APP_H__ */ diff --git a/plat/diameter/extensions/sh_app/sh_bench.c b/plat/diameter/extensions/sh_app/sh_bench.c new file mode 100644 index 0000000..cccab76 --- /dev/null +++ b/plat/diameter/extensions/sh_app/sh_bench.c @@ -0,0 +1,344 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Create and send a message, and receive it */ + +#include "sh_app.h" +#include + +#ifndef __APPLE__ /* they deprecated the semaphore there... */ +#include + +#define my_sem_t sem_t +#define my_sem_init sem_init +#define my_sem_destroy sem_destroy +#define my_sem_timedwait sem_timedwait +#define my_sem_post sem_post + +#else // on APPLE +#include +#include + +#define my_sem_t dispatch_semaphore_t + +static int my_sem_init(my_sem_t * s, int pshared, unsigned int value ) { + *s = dispatch_semaphore_create(value); + if (*s == NULL) + return ENOMEM; + return 0; +} + +static int my_sem_destroy(my_sem_t *s) { + dispatch_release(*s); + *s = NULL; + return 0; +} + +static int my_sem_timedwait(my_sem_t * s, struct timespec *ts) { + struct timespec tsn; + int64_t nsec; + dispatch_time_t when; + + CHECK_SYS( clock_gettime(CLOCK_REALTIME, &tsn) ); + + nsec = (ts->tv_sec * 1000000000) + ts->tv_nsec + - (tsn.tv_sec * 1000000000) - tsn.tv_nsec; + + when = dispatch_time ( DISPATCH_TIME_NOW, nsec ); + + return dispatch_semaphore_wait ( *s, when ) ? ETIMEDOUT : 0; +} + +static int my_sem_post(my_sem_t *s) { + dispatch_semaphore_signal(*s); + return 0; +} + +#endif // APPLE + + + +struct ta_mess_info { + int32_t randval; /* a random value to store in Test-AVP */ + struct timespec ts; /* Time of sending the message */ +}; + +static my_sem_t ta_sem; /* To handle the concurrency */ + +/* Cb called when an answer is received */ +#if 0 + +static void sh_cb_udr_ans(void * data, struct msg ** msg) +{ + + struct ta_mess_info * mi = (struct ta_mess_info *)data; + struct timespec ts; + struct avp * avp; + struct avp_hdr * hdr; + unsigned long dur; + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return ); + + /* Value of Result Code */ + CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_res_code, &avp), return ); + if (avp) { + CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + } + if (!avp || !hdr || hdr->avp_value->i32 != 2001) { + /* error */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + ta_conf->stats.nb_errs++; + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + goto end; + } + + /* Check value of Test-AVP */ + CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_avp, &avp), return ); + if (avp) { + CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + ASSERT(hdr->avp_value->i32 == mi->randval); + } + + /* Compute how long it took */ + dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + ((ts.tv_nsec - mi->ts.tv_nsec) / 1000); + + /* Add this value to the stats */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + + if (ta_conf->stats.nb_recv) { + /* Ponderate in the avg */ + ta_conf->stats.avg = (ta_conf->stats.avg * ta_conf->stats.nb_recv + dur) / (ta_conf->stats.nb_recv + 1); + /* Min, max */ + if (dur < ta_conf->stats.shortest) + ta_conf->stats.shortest = dur; + if (dur > ta_conf->stats.longest) + ta_conf->stats.longest = dur; + } else { + ta_conf->stats.shortest = dur; + ta_conf->stats.longest = dur; + ta_conf->stats.avg = dur; + } + ta_conf->stats.nb_recv++; + + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + +end: + /* Free the message */ + CHECK_FCT_DO(fd_msg_free(*msg), ); + *msg = NULL; + + free(mi); + + /* Post the semaphore */ + CHECK_SYS_DO( my_sem_post(&ta_sem), ); + + return; + +} +#endif + + +/* Create a test message */ +static void ta_bench_test_message() +{ +#if 0 + struct msg * req = NULL; + struct avp * avp; + union avp_value val; + struct ta_mess_info * mi = NULL; + + TRACE_DEBUG(FULL, "Creating a new message for sending."); + + /* Create the request */ + CHECK_FCT_DO( fd_msg_new( ta_cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out ); + + /* Create a new session */ + #define TEST_APP_SID_OPT "app_testb" + CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out ); + + /* Create the random value to store with the session */ + mi = malloc(sizeof(struct ta_mess_info)); + if (mi == NULL) { + fd_log_debug("malloc failed: %s", strerror(errno)); + goto out; + } + + mi->randval = (int32_t)random(); + + /* Now set all AVPs values */ + + /* Set the Destination-Realm AVP */ + { + CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_realm, 0, &avp ), goto out ); + val.os.data = (unsigned char *)(ta_conf->dest_realm); + val.os.len = strlen(ta_conf->dest_realm); + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + + /* Set the Destination-Host AVP if needed*/ + if (ta_conf->dest_host) { + CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_host, 0, &avp ), goto out ); + val.os.data = (unsigned char *)(ta_conf->dest_host); + val.os.len = strlen(ta_conf->dest_host); + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + + /* Set Origin-Host & Origin-Realm */ + CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out ); + + /* Set the User-Name AVP if needed*/ + if (ta_conf->user_name) { + CHECK_FCT_DO( fd_msg_avp_new ( ta_user_name, 0, &avp ), goto out ); + val.os.data = (unsigned char *)(ta_conf->user_name); + val.os.len = strlen(ta_conf->user_name); + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + + /* Set the Test-AVP AVP */ + { + CHECK_FCT_DO( fd_msg_avp_new ( ta_avp, 0, &avp ), goto out ); + val.i32 = mi->randval; + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); + CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); + } + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out ); + + /* Send the request */ + CHECK_FCT_DO( fd_msg_send( &req, sh_rec_uda, mi ), goto out ); + + /* Increment the counter */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + ta_conf->stats.nb_sent++; + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + +out: + return; +#endif +} + +/* The function called when the signal is received */ +static void ta_bench_start() { + struct timespec end_time, now; + struct ta_stats start, end; + int nsec = 0; + + /* Save the initial stats */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + memcpy(&start, &ta_conf->stats, sizeof(struct ta_stats)); + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + + /* We will run for ta_conf->bench_duration seconds */ + LOG_N("Starting benchmark client, %ds", ta_conf->bench_duration); + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &end_time), ); + end_time.tv_sec += ta_conf->bench_duration; + + /* Now loop until timeout is reached */ + do { + /* Do not create more that NB_CONCURRENT_MESSAGES in paralel */ + int ret = my_sem_timedwait(&ta_sem, &end_time); + if (ret == -1) { + ret = errno; + if (ret != ETIMEDOUT) { + CHECK_POSIX_DO(ret, ); /* Just to log it */ + } + break; + } + + /* Update the current time */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), ); + + if (!TS_IS_INFERIOR(&now, &end_time)) + break; + + /* Create and send a new test message */ + ta_bench_test_message(); + } while (1); + + do { + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), ); /* Re-read the time because we might have spent some time wiating for the mutex */ + memcpy(&end, &ta_conf->stats, sizeof(struct ta_stats)); + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + + /* Now, display the statistics */ + LOG_N( "------- app_test Benchmark results, end sending +%ds ---------", nsec); + if (now.tv_nsec >= end_time.tv_nsec) { + LOG_N( " Executing for: %d.%06ld sec", + (int)(now.tv_sec + ta_conf->bench_duration - end_time.tv_sec), + (long)(now.tv_nsec - end_time.tv_nsec) / 1000); + } else { + LOG_N( " Executing for: %d.%06ld sec", + (int)(now.tv_sec + ta_conf->bench_duration - 1 - end_time.tv_sec), + (long)(now.tv_nsec + 1000000000 - end_time.tv_nsec) / 1000); + } + LOG_N( " %llu messages sent", end.nb_sent - start.nb_sent); + LOG_N( " %llu error(s) received", end.nb_errs - start.nb_errs); + LOG_N( " %llu answer(s) received", end.nb_recv - start.nb_recv); + LOG_N( " Overall:"); + LOG_N( " fastest: %ld.%06ld sec.", end.shortest / 1000000, end.shortest % 1000000); + LOG_N( " slowest: %ld.%06ld sec.", end.longest / 1000000, end.longest % 1000000); + LOG_N( " Average: %ld.%06ld sec.", end.avg / 1000000, end.avg % 1000000); + LOG_N( " Throughput: %llu messages / sec", (end.nb_recv - start.nb_recv) / (( now.tv_sec + ta_conf->bench_duration - end_time.tv_sec ) + ((now.tv_nsec - end_time.tv_nsec) / 1000000000))); + LOG_N( "-------------------------------------"); + + nsec ++; + sleep(1); + } while ( (end.nb_sent - start.nb_sent) > (end.nb_errs - start.nb_errs) + (end.nb_recv - start.nb_recv) ); + LOG_N( "--------------- Test Complete --------------"); + +} + + +int ta_bench_init(void) +{ + CHECK_SYS( my_sem_init( &ta_sem, 0, ta_conf->bench_concur) ); + + CHECK_FCT( fd_event_trig_regcb(ta_conf->signal, "test_app.bench", ta_bench_start ) ); + + return 0; +} + +void ta_bench_fini(void) +{ + // CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ ); + + CHECK_SYS_DO( my_sem_destroy(&ta_sem), ); + + return; +}; diff --git a/plat/diameter/extensions/sh_app/sh_cli.c b/plat/diameter/extensions/sh_app/sh_cli.c new file mode 100644 index 0000000..419f024 --- /dev/null +++ b/plat/diameter/extensions/sh_app/sh_cli.c @@ -0,0 +1,997 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Create and send a message, and receive it */ + +/* Note that we use both sessions and the argument to answer callback to pass the same value. + * This is just for the purpose of checking everything went OK. + */ +#include "sh_app.h" +#include +#include "sh_conf.h" + +// static struct disp_hdl * sh_hdl_fb = NULL; /* handler for fallback cb */ +extern struct dict_object * sh_appli; +static struct disp_hdl * sh_hdl_uda = NULL; /* handler for PUR req cb */ +static struct disp_hdl * sh_hdl_pua = NULL; /* handler for PUR req cb */ +extern struct dict_object * uda_cmd; +extern struct dict_object * pua_cmd; + + +struct sess_state { + int32_t randval; /* a random value to store in Test-AVP */ + struct timespec ts; /* Time of sending the message */ +} ; + + +static struct session_handler * sh_cli_reg = NULL; + +static struct sh_udr_msg g_udr_cmd; +static struct sh_pur_msg g_pur_cmd; + +static struct sh_uda_msg g_uda_cmd; +static struct sh_pua_msg g_pua_cmd; + + +//static struct dict_avp_request __avp; + +static char * g_test_buf = NULL; +static size_t g_test_len; +#define FD_DUMP_TEST_PARAMS &g_test_buf, &g_test_len, NULL +#define SH_TEST_ON 1 + + +#if 0 +static void sh_send_pur() +{ + struct msg *pur_msg = NULL; + struct avp *avp, *grpavp; + union avp_value val; + struct sess_state *mi = NULL, *svg; + struct session *sess = NULL; + + TRACE_DEBUG(FULL, "Creating a new message for sending."); + + /* Create a new session */ + #define TEST_APP_SID_OPT "sh_app" + + /* Create the message object from model */ + { + struct dict_object * acr_model = NULL; + + /* Now find the UDR dictionary object */ + ASSERT( 0 == fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Profile-Update-Request", &acr_model, ENOENT ) ); + + /* Create the instance, using the templates */ + ASSERT( 0 == fd_msg_new ( acr_model, MSGFL_ALLOC_ETEID, &pur_msg ) ); + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( pur_msg, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + } + + /* Check there is no child */ + ASSERT( ENOENT == fd_msg_browse ( pur_msg, MSG_BRW_FIRST_CHILD, NULL, NULL) ); + } + + + CHECK_FCT_DO( fd_msg_new_session( pur_msg, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out ); + CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, pur_msg, &sess, NULL), goto out ); + + /* Create the random value to store with the session */ + mi = malloc(sizeof(struct sess_state)); + if (mi == NULL) { + fd_log_debug("malloc failed: %s", strerror(errno)); + goto out; + } + + mi->randval = (int32_t)random(); + + /* Now resolve some other useful AVPs */ + /* resolve udr avps */ + SEARCH_AVP_("Session-Id", 0, &g_pur_cmd.pur_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_pur_cmd.pur_drmp); + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_pur_cmd.pur_vendor_specific_application_id); + SEARCH_AVP_("Auth-Session-State", 0, &g_pur_cmd.pur_auth_session_state); + SEARCH_AVP_("Origin-Host", 0, &g_pur_cmd.pur_origin_host); + SEARCH_AVP_("Origin-Realm", 0, &g_pur_cmd.pur_origin_realm); + SEARCH_AVP_("Destination-Host", 0, &g_pur_cmd.pur_destination_host); + SEARCH_AVP_("Destination-Realm", 0, &g_pur_cmd.pur_destination_realm); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_pur_cmd.pur_supported_features); + SEARCH_AVP_("User-Identity", SH_VND_ID, &g_pur_cmd.pur_user_identity); + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_pur_cmd.pur_wildcarded_public_identity); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_pur_cmd.pur_wildcarded_impu); + SEARCH_AVP_("User-Name", 0, &g_pur_cmd.pur_user_name); + SEARCH_AVP_("Data-Reference", SH_VND_ID, &g_pur_cmd.pur_data_reference); + + SEARCH_AVP_("User-Data", SH_VND_ID, &g_pur_cmd.pur_user_date); + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_pur_cmd.pur_oc_supported_features); + + /* Now set all AVPs values */ + EN_AVP_U32(g_pur_cmd.pur_drmp, 0, pur_msg, "DRMP Ok") + + /* Set Vendor-Specific-Application-Id AVP if needed*/ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_pur_cmd.pur_vendor_specific_application_id, 0, &grpavp ), goto out ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_pur_cmd.pur_vendor_id, SH_VND_ID) + EN_GRPAVP_U32("Auth-Application-Id", 0, g_pur_cmd.pur_auth_application_d, SH_APP_ID) + EN_GRPAVP_U32("Acct-Application-Id", 0,g_pur_cmd.pur_acct_application_id, SH_APP_ID) + + CHECK_FCT_DO( fd_msg_avp_add( pur_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("Vendor-Specific-Application-Id Ok\n"); + } + + EN_AVP_U32(g_pur_cmd.pur_auth_session_state, 1, pur_msg, "pur_auth_session_state Ok\n") + + /* Set Origin-Host & Origin-Realm AVP */ + CHECK_FCT_DO( fd_msg_add_origin ( pur_msg, 0 ), goto out ); + + /* Set the Destination-Host AVP if needed*/ + if (ta_conf->dest_host) { + EN_AVP_STR(g_pur_cmd.pur_destination_host, g_sh_conf_ext.pi_diamid_peer, pur_msg, "pur_origin_host Ok"); + } + + /* Set the Destination-Realm AVP */ + EN_AVP_STR(g_pur_cmd.pur_destination_realm, g_sh_conf_ext.pi_diamid_realm_peer, pur_msg, "pur_origin_realm Ok"); + + /* Set the Supported-Features group AVP if needed*/ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_pur_cmd.pur_supported_features, 0, &grpavp ), goto out ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_pur_cmd.pur_vendor_id, SH_VND_ID) + EN_GRPAVP_U32("Feature-List-ID", SH_VND_ID,g_pur_cmd.pur_feature_list_id, 2) + EN_GRPAVP_U32("Feature-List", SH_VND_ID,g_pur_cmd.pur_feature_list, 3) + + CHECK_FCT_DO( fd_msg_avp_add( pur_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("Supported-Features Ok\n"); + } + + /* Set the User-Identity AVP if needed*/ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_pur_cmd.pur_user_identity, 0, &grpavp ), goto out ); + + EN_GRPAVP_STR("Public-Identity", SH_VND_ID, g_pur_cmd.pur_public_identity, "public_id", grpavp) + EN_GRPAVP_STR("MSISDN", SH_VND_ID, g_pur_cmd.pur_msisdn, "12345", grpavp) + + CHECK_FCT_DO( fd_msg_avp_add( pur_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("pur_user_identity Ok\n"); + } + + EN_AVP_STR( g_pur_cmd.pur_wildcarded_public_identity, "wildcarded_public_id", pur_msg, "wildcarded_public_id Ok") + EN_AVP_STR( g_pur_cmd.pur_wildcarded_impu, "wildcarded_impu", pur_msg, "wildcarded_impu Ok") + EN_AVP_STR( g_pur_cmd.pur_user_name, "User-Name", pur_msg, "user_name Ok") + EN_AVP_U32( g_pur_cmd.pur_data_reference, 1,pur_msg, "Data-Reference Ok") + EN_AVP_STR( g_pur_cmd.pur_user_date, "User-Data", pur_msg, "User-Data Ok") + + /* Set the OC-Supported-Features AVP */ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_pur_cmd.pur_oc_supported_features, 0, &grpavp ), goto out); + + EN_GRPAVP_U64("OC-Feature-Vector", SH_VND_ID, g_pur_cmd.pur_oc_feature_vector, 1) + + CHECK_FCT_DO( fd_msg_avp_add( pur_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("OC-Feature-Vector Ok\n"); +#if SH_TEST_ON + fd_log_debug("%s", fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, pur_msg, fd_g_config->cnf_dict, 0, 1)); +#endif + } + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out ); + LOG_D("CLOCK_REALTIME Ok\n"); + + /* Keep a pointer to the session data for debug purpose, in real life we would not need it */ + svg = mi; + + /* Store this value in the session */ + // CHECK_FCT_DO( fd_sess_state_store ( sh_cli_reg, sess, &mi ), goto out ); + LOG_D("sess Ok\n"); + + /* Log sending the message */ + fprintf(stderr, "SEND %x to '%s' (%s)\n", svg->randval, ta_conf->dest_realm, ta_conf->dest_host?:"-" ); + fflush(stderr); + + // assert( 0 == fd_msg_source_set( pur_msg, "client.domain", CONSTSTRLEN("client.domain") ) ); + + /* Send the request */ + CHECK_FCT_DO( fd_msg_send( &pur_msg, NULL, svg ), goto out ); + LOG_D("fd_msg_send Ok\n"); + + /* Increment the counter */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + ta_conf->stats.nb_sent++; + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + +out: + printf("end\n"); + return; +} + + +static void sh_send_udr() +{ + struct msg *udr_msg = NULL; + struct avp *avp, *grpavp; + union avp_value val; + struct sess_state *mi = NULL, *svg; + struct session *sess = NULL; + + TRACE_DEBUG(FULL, "Creating a new message for sending."); + + /* Create a new session */ + #define TEST_APP_SID_OPT "sh_app" + + /* Create the message object from model */ + { + struct dict_object * acr_model = NULL; + + /* Now find the UDR dictionary object */ + ASSERT( 0 == fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "User-Data-Request", &acr_model, ENOENT ) ); + + /* Create the instance, using the templates */ + ASSERT( 0 == fd_msg_new ( acr_model, MSGFL_ALLOC_ETEID, &udr_msg ) ); + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( udr_msg, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + msg_hdr->msg_flags = msg_hdr->msg_flags & (~CMD_FLAG_PROXIABLE); + } + + /* Check there is no child */ + ASSERT( ENOENT == fd_msg_browse ( udr_msg, MSG_BRW_FIRST_CHILD, NULL, NULL) ); + } + + + CHECK_FCT_DO( fd_msg_new_session( udr_msg, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out ); + CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, udr_msg, &sess, NULL), goto out ); + + /* Create the random value to store with the session */ + mi = malloc(sizeof(struct sess_state)); + if (mi == NULL) { + fd_log_debug("malloc failed: %s", strerror(errno)); + goto out; + } + + mi->randval = (int32_t)random(); + + /* Now resolve some other useful AVPs */ + /* resolve udr avps */ + SEARCH_AVP_("Session-Id", 0, &g_udr_cmd.udr_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_udr_cmd.udr_drmp); + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_udr_cmd.udr_vendor_specific_application_id); + SEARCH_AVP_("Auth-Session-State", 0, &g_udr_cmd.udr_auth_session_state); + SEARCH_AVP_("Origin-Host", 0, &g_udr_cmd.udr_origin_host); + SEARCH_AVP_("Origin-Realm", 0, &g_udr_cmd.udr_origin_realm); + SEARCH_AVP_("Destination-Host", 0, &g_udr_cmd.udr_destination_host); + SEARCH_AVP_("Destination-Realm", 0, &g_udr_cmd.udr_destination_realm); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_udr_cmd.udr_supported_features); + SEARCH_AVP_("User-Identity", SH_VND_ID, &g_udr_cmd.udr_user_identity); + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_udr_cmd.udr_wildcarded_public_identity); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_udr_cmd.udr_wildcarded_impu); + SEARCH_AVP_("Server-Name", SH_VND_ID, &g_udr_cmd.udr_server_name); + SEARCH_AVP_("Service-Indication", SH_VND_ID, &g_udr_cmd.udr_service_indication); + SEARCH_AVP_("Data-Reference", SH_VND_ID, &g_udr_cmd.udr_data_reference); + SEARCH_AVP_("Identity-Set", SH_VND_ID, &g_udr_cmd.udr_identity_set); + SEARCH_AVP_("Requested-Domain", SH_VND_ID, &g_udr_cmd.udr_requested_domain); + SEARCH_AVP_("Current-Location", SH_VND_ID, &g_udr_cmd.udr_current_location); + SEARCH_AVP_("DSAI-Tag", SH_VND_ID, &g_udr_cmd.udr_dsai_tag); + SEARCH_AVP_("Session-Priority", SH_VND_ID, &g_udr_cmd.udr_session_priority); + SEARCH_AVP_("User-Name", 0, &g_udr_cmd.udr_user_name); + SEARCH_AVP_("Requested-Nodes", SH_VND_ID, &g_udr_cmd.udr_requested_nodes); + SEARCH_AVP_("Serving-Node-Indication", SH_VND_ID, &g_udr_cmd.udr_serving_node_indication); + SEARCH_AVP_("Pre-paging-Supported", SH_VND_ID, &g_udr_cmd.udr_pre_paging_supported); + SEARCH_AVP_("Local-Time-Zone-Indication", SH_VND_ID, &g_udr_cmd.udr_local_time_zone_indication); + SEARCH_AVP_("UDR-Flags", SH_VND_ID, &g_udr_cmd.udr_udr_flags); + SEARCH_AVP_("Call-Reference-Info", SH_VND_ID, &g_udr_cmd.udr_call_reference_info); + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_udr_cmd.udr_oc_supported_features); + + /* Now set all AVPs values */ + EN_AVP_U32(g_udr_cmd.udr_drmp, 0, udr_msg, "DRMP Ok") + + /* Set Vendor-Specific-Application-Id AVP if needed*/ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_udr_cmd.udr_vendor_specific_application_id, 0, &grpavp ), goto out ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_udr_cmd.udr_vendor_id, SH_VND_ID) + EN_GRPAVP_U32("Auth-Application-Id", 0, g_udr_cmd.udr_auth_application_d, SH_APP_ID) + EN_GRPAVP_U32("Acct-Application-Id", 0,g_udr_cmd.udr_acct_application_id, SH_APP_ID) + + CHECK_FCT_DO( fd_msg_avp_add( udr_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("Vendor-Specific-Application-Id Ok\n"); + } + + EN_AVP_U32(g_udr_cmd.udr_auth_session_state, 1, udr_msg, "udr_auth_session_state Ok\n") + + /* Set Origin-Host & Origin-Realm AVP */ + CHECK_FCT_DO( fd_msg_add_origin ( udr_msg, 0 ), goto out ); + + /* Set the Destination-Host AVP if needed*/ + if (ta_conf->dest_host) { + EN_AVP_STR(g_udr_cmd.udr_destination_host, g_sh_conf_ext.pi_diamid_peer, udr_msg, "udr_origin_host Ok"); + } + + /* Set the Destination-Realm AVP */ + EN_AVP_STR(g_udr_cmd.udr_destination_realm, g_sh_conf_ext.pi_diamid_realm_peer, udr_msg, "udr_origin_realm Ok"); + + /* Set the Supported-Features group AVP if needed*/ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_udr_cmd.udr_supported_features, 0, &grpavp ), goto out ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_udr_cmd.udr_vendor_id, 1) + EN_GRPAVP_U32("Feature-List-ID", SH_VND_ID,g_udr_cmd.udr_feature_list_id, 2) + EN_GRPAVP_U32("Feature-List", SH_VND_ID,g_udr_cmd.udr_feature_list, 3) + + CHECK_FCT_DO( fd_msg_avp_add( udr_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("Supported-Features Ok\n"); + } + + /* Set the User-Identity AVP if needed*/ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_udr_cmd.udr_user_identity, 0, &grpavp ), goto out ); + + EN_GRPAVP_STR("Public-Identity", SH_VND_ID, g_udr_cmd.udr_public_identity, "public_id", grpavp) + EN_GRPAVP_STR("MSISDN", SH_VND_ID, g_udr_cmd.udr_msisdn, "12345", grpavp) + + CHECK_FCT_DO( fd_msg_avp_add( udr_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("udr_user_identity Ok\n"); + } + + EN_AVP_STR(g_udr_cmd.udr_wildcarded_public_identity, "Wildcarded-public-ID", udr_msg, "Wildcarded-Public-ID Ok") + EN_AVP_STR( g_udr_cmd.udr_wildcarded_impu, "Wildcarded-IMPU", udr_msg, "Wildcarded-IMPU Ok") + EN_AVP_STR( g_udr_cmd.udr_server_name, "Server-Name", udr_msg, "Server-Name Ok") + EN_AVP_STR( g_udr_cmd.udr_service_indication, "Service-Indication", udr_msg, "Service-Indication Ok") + EN_AVP_U32(g_udr_cmd.udr_data_reference, 1,udr_msg, "Data-Reference Ok") + EN_AVP_U32(g_udr_cmd.udr_identity_set, 1,udr_msg, "Identity-Set Ok") + + EN_AVP_U32(g_udr_cmd.udr_requested_domain, 2,udr_msg, "Req-Domain Ok") + + EN_AVP_U32( g_udr_cmd.udr_current_location, 3, udr_msg, "Cur-Location Ok") + EN_AVP_STR( g_udr_cmd.udr_dsai_tag, "DSAI-Tag", udr_msg, "DSAI-Tag Ok") + + EN_AVP_U32( g_udr_cmd.udr_session_priority, 4, udr_msg, "Session-Priority Ok") + EN_AVP_STR( g_udr_cmd.udr_user_name, "User-Name", udr_msg, "User-Name Ok") + + /* Set User-Name AVP */ + EN_AVP_U32( g_udr_cmd.udr_requested_nodes, 5, udr_msg, "Requested-Nodes Ok") + EN_AVP_U32( g_udr_cmd.udr_serving_node_indication, 6, udr_msg, "Serving-Node-Indication Ok") + EN_AVP_U32( g_udr_cmd.udr_pre_paging_supported, 7, udr_msg, "Pre-paging-Supported Ok") + EN_AVP_U32( g_udr_cmd.udr_local_time_zone_indication, 8, udr_msg, "Local-Time-Zone-Indication Ok") + + EN_AVP_U32( g_udr_cmd.udr_udr_flags, 9, udr_msg, "UDR-Flags Ok") + + /* Set the Call-Reference-Info AVP */ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_udr_cmd.udr_call_reference_info, 0, &grpavp ), goto out ); + + EN_GRPAVP_STR("Call-Reference-Number", SH_VND_ID, g_udr_cmd.udr_call_reference_number, "Call-Reference-Number", grpavp) + EN_GRPAVP_STR("AS-Number", SH_VND_ID, g_udr_cmd.udr_as_number, "AS-Number", grpavp) + + CHECK_FCT_DO( fd_msg_avp_add( udr_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("Call-Reference-Info Ok\n"); + } + + /* Set the OC-Supported-Features AVP */ + { + CHECK_FCT_DO( fd_msg_avp_new ( g_udr_cmd.udr_oc_supported_features, 0, &grpavp ), goto out); + + EN_GRPAVP_U64("OC-Feature-Vector", SH_VND_ID, g_udr_cmd.udr_oc_feature_vector, 1) + + CHECK_FCT_DO( fd_msg_avp_add( udr_msg, MSG_BRW_LAST_CHILD, grpavp ), goto out ); + + LOG_D("OC-Feature-Vector Ok\n"); +#if SH_TEST_ON + fd_log_debug("%s", fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, udr_msg, fd_g_config->cnf_dict, 0, 1)); +#endif + } + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out ); + LOG_D("CLOCK_REALTIME Ok\n"); + + /* Keep a pointer to the session data for debug purpose, in real life we would not need it */ + svg = mi; + + /* Store this value in the session */ + CHECK_FCT_DO( fd_sess_state_store ( sh_cli_reg, sess, &mi ), goto out ); + LOG_D("sess Ok\n"); + + /* Log sending the message */ + fprintf(stderr, "SEND %x to '%s' (%s)\n", svg->randval, ta_conf->dest_realm, ta_conf->dest_host?:"-" ); + fflush(stderr); + + /* Send the request */ + CHECK_FCT_DO( fd_msg_send( &udr_msg, NULL, svg ), goto out ); + LOG_D("fd_msg_send Ok\n"); + + /* Increment the counter */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + ta_conf->stats.nb_sent++; + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + +out: + printf("end\n"); + return; +} +#endif +static int sh_parse_pua( struct msg ** msg) +{ + struct msg* pua_msg = *msg; + struct avp *avp, *grpavp=NULL; + struct avp_hdr *avphdr; + + LOG_D("fj sh_parse_pua"); + + SEARCH_AVP_("Session-Id", 0, &g_pua_cmd.pua_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_pua_cmd.pua_drmp); + + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_pua_cmd.pua_vendor_specific_application_id); + SEARCH_AVP_("Vendor-Id", 0, &g_pua_cmd.pua_vendor_id); + SEARCH_AVP_("Auth-Application-Id", 0, &g_pua_cmd.pua_auth_application_d); + SEARCH_AVP_("Acct-Application-Id", 0, &g_pua_cmd.pua_acct_application_id); + + + SEARCH_AVP_("Result-Code", 0, &g_pua_cmd.pua_result_code); + + SEARCH_AVP_("Experimental-Result", 0, &g_pua_cmd.pua_experimental_result); + SEARCH_AVP_("Experimental-Result-Code", 0, &g_pua_cmd.pua_experimental_result_code); + + SEARCH_AVP_("Auth-Session-State", 0, &g_pua_cmd.pua_auth_session_state); + SEARCH_AVP_("Origin-Host", 0, &g_pua_cmd.pua_origin_host); + SEARCH_AVP_("Origin-Realm", 0, &g_pua_cmd.pua_origin_realm); + + + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_pua_cmd.pua_wildcarded_public_identity ); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_pua_cmd.pua_wildcarded_impu ); + + SEARCH_AVP_("Repository-Data-ID", SH_VND_ID, &g_pua_cmd.pua_repository_data_id ); + SEARCH_AVP_("Service-Indication", SH_VND_ID, &g_pua_cmd.pua_service_indication); + SEARCH_AVP_("Sequence-Number", SH_VND_ID, &g_pua_cmd.pua_sequence_number); + + SEARCH_AVP_("Data-Reference", SH_VND_ID, &g_pua_cmd.pua_data_reference); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_pua_cmd.pua_supported_features ); + SEARCH_AVP_("Feature-List-ID", SH_VND_ID, &g_pua_cmd.pua_feature_list_id); + SEARCH_AVP_("Feature-List", SH_VND_ID, &g_pua_cmd.pua_feature_list); + + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_pua_cmd.pua_oc_supported_features ); + SEARCH_AVP_("OC-Feature-Vector", SH_VND_ID, &g_pua_cmd.pua_oc_feature_vector); + + SEARCH_AVP_("OC-OLR", SH_VND_ID, &g_pua_cmd.pua_oc_olr ); + SEARCH_AVP_("OC-Sequence-Number", SH_VND_ID, &g_pua_cmd.pua_oc_sequence_number); + SEARCH_AVP_("OC-Report-Type", SH_VND_ID, &g_pua_cmd.pua_oc_report_type); + SEARCH_AVP_("OC-Reduction-Percentage", SH_VND_ID, &g_pua_cmd.pua_oc_reduction_percentage); + SEARCH_AVP_("OC-Validity-Duration", SH_VND_ID, &g_pua_cmd.pua_oc_validity_duration); + + /* Session-Id */ + PARSE_AVP_STR(pua_msg, g_pua_cmd.pua_session_id, avp, avphdr, "ession-Id", avphdr->avp_value->os.data) + + /* DRMP */ + PARSE_AVP_U32(pua_msg, g_pua_cmd.pua_drmp, avp, avphdr, "DRMP", avphdr->avp_value->u32) + + /* Vendor-Specific-Application-Id */ + CHECK_FCT( fd_msg_search_avp ( pua_msg, g_pua_cmd.pua_vendor_specific_application_id, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Vendor-Specific-Application-Id"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Auth-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_auth_application_d, avp, avphdr, "Auth-Application-Id", avphdr->avp_value->u32) + + /* Acct-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_acct_application_id, avp, avphdr, "Acct-Application-Id", avphdr->avp_value->u32) + } + + /* Result-Code */ + PARSE_AVP_U32(pua_msg, g_pua_cmd.pua_result_code, avp, avphdr, "Result-Code", avphdr->avp_value->u32) + + /* Experimental-Result */ + CHECK_FCT( fd_msg_search_avp ( pua_msg, g_pua_cmd.pua_experimental_result, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Experimental-Result"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Experimental-Result-Code */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_experimental_result_code, avp, avphdr, "Experimental-Result-Code", avphdr->avp_value->u32) + } + + /* Auth-Session-State */ + PARSE_AVP_U32(pua_msg, g_pua_cmd.pua_auth_session_state, avp, avphdr, "Auth-Session-State", avphdr->avp_value->u32) + + + /* Origin-Host */ + PARSE_AVP_STR(pua_msg, g_pua_cmd.pua_origin_host, avp, avphdr, "Origin-Host", avphdr->avp_value->os.data) + + /* Origin-Realm */ + PARSE_AVP_STR(pua_msg, g_pua_cmd.pua_origin_realm, avp, avphdr, "Origin-Realm", avphdr->avp_value->os.data) + + + /* Wildcarded-Public-Identity */ + PARSE_AVP_STR(pua_msg, g_pua_cmd.pua_wildcarded_public_identity, avp, avphdr, "Wildcarded-Public-Identity", avphdr->avp_value->os.data) + + /* Wildcarded-IMPU */ + PARSE_AVP_STR(pua_msg, g_pua_cmd.pua_wildcarded_impu, avp, avphdr, "Wildcarded-IMPU", avphdr->avp_value->os.data) + + /* Repository-Data-ID */ + CHECK_FCT( fd_msg_search_avp ( pua_msg, g_pua_cmd.pua_repository_data_id, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Repository-Data-ID"); + + /* Service-Indication */ + PARSE_GRPAVP_STR(grpavp, g_pua_cmd.pua_service_indication, avp, avphdr, "Service-Indication", avphdr->avp_value->os.data) + + /* Sequence-Number */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_sequence_number, avp, avphdr, "Sequence-Number", avphdr->avp_value->u32) + } + + /* Data-Reference */ + PARSE_AVP_U32(pua_msg, g_pua_cmd.pua_data_reference, avp, avphdr, "Data-Reference", avphdr->avp_value->u32) + + /* Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( pua_msg, g_pua_cmd.pua_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Supported-Features"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Feature-List-ID */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_feature_list_id, avp, avphdr, "Feature-List-ID", avphdr->avp_value->u32) + + /* Feature-List */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_feature_list, avp, avphdr, "Feature-List", avphdr->avp_value->u32) + } + + /* OC-Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( pua_msg, g_pua_cmd.pua_oc_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj OC-Supported-Features"); + + /* OC-Feature-Vector */ + PARSE_GRPAVP_U64(grpavp, g_pua_cmd.pua_oc_feature_vector, avp, avphdr, "OC-Feature-Vector", avphdr->avp_value->u64) + } + + /* OC-OLR */ + CHECK_FCT( fd_msg_search_avp ( pua_msg, g_pua_cmd.pua_oc_olr, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj OC-OLR"); + + /* OC-Sequence-Number */ + PARSE_GRPAVP_U64(grpavp, g_pua_cmd.pua_oc_feature_vector, avp, avphdr, "OC-Sequence-Number", avphdr->avp_value->u64) + + /* OC-Report-Type */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_oc_report_type, avp, avphdr, "OC-Report-Type", avphdr->avp_value->u32) + + /* OC-Reduction-Percentage */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_oc_reduction_percentage, avp, avphdr, "OC-Reduction-Percentage", avphdr->avp_value->u32) + + /* OC-Validity-Duration */ + PARSE_GRPAVP_U32(grpavp, g_pua_cmd.pua_oc_validity_duration, avp, avphdr, "OC-Validity-Duration", avphdr->avp_value->u32) + + } + +out: + return 0; + +} + +static int sh_parse_uda(struct msg** msg) +{ + struct msg* udr_msg = *msg; + struct avp *avp, *grpavp=NULL; + struct avp_hdr *avphdr; + + LOG_D("fj sh_parse_uda"); + + SEARCH_AVP_("Origin-Host", 0, &g_uda_cmd.uda_origin_host); + SEARCH_AVP_("Session-Id", 0, &g_uda_cmd.uda_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_uda_cmd.uda_drmp); + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_uda_cmd.uda_vendor_specific_application_id); + SEARCH_AVP_("Vendor-Id", 0, &g_uda_cmd.uda_vendor_id); + SEARCH_AVP_("Auth-Application-Id", 0, &g_uda_cmd.uda_auth_application_d); + SEARCH_AVP_("Acct-Application-Id", 0, &g_uda_cmd.uda_acct_application_id); + + + SEARCH_AVP_("Result-Code", 0, &g_uda_cmd.uda_result_code); + + SEARCH_AVP_("Experimental-Result", 0, &g_uda_cmd.uda_experimental_result); + SEARCH_AVP_("Experimental-Result-Code", 0, &g_uda_cmd.uda_experimental_result_code); + + SEARCH_AVP_("Auth-Session-State", 0, &g_uda_cmd.uda_auth_session_state); + + SEARCH_AVP_("Origin-Realm", 0, &g_uda_cmd.uda_origin_realm); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_uda_cmd.uda_supported_features ); + SEARCH_AVP_("Feature-List-ID", SH_VND_ID, &g_uda_cmd.uda_feature_list_id); + SEARCH_AVP_("Feature-List", SH_VND_ID, &g_uda_cmd.uda_feature_list); + + + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_uda_cmd.uda_wildcarded_public_identity ); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_uda_cmd.uda_wildcarded_impu ); + SEARCH_AVP_("User-Data", SH_VND_ID, &g_uda_cmd.uda_user_data ); + + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_uda_cmd.uda_oc_supported_features ); + // SEARCH_AVP_("OC-Feature-Vector", SH_VND_ID, &g_uda_cmd.uda_oc_feature_vector); + + SEARCH_AVP_("OC-OLR", SH_VND_ID, &g_uda_cmd.uda_oc_olr ); + SEARCH_AVP_("OC-Sequence-Number", SH_VND_ID, &g_uda_cmd.uda_oc_sequence_number); + SEARCH_AVP_("OC-Report-Type", SH_VND_ID, &g_uda_cmd.uda_oc_report_type); + SEARCH_AVP_("OC-Reduction-Percentage", SH_VND_ID, &g_uda_cmd.uda_oc_reduction_percentage); + SEARCH_AVP_("OC-Validity-Duration", SH_VND_ID, &g_uda_cmd.uda_oc_validity_duration); + + /* Session-Id */ + PARSE_AVP_STR(udr_msg, g_uda_cmd.uda_session_id, avp, avphdr, "Session-Id", avphdr->avp_value->os.data) + + /* DRMP */ + PARSE_AVP_U32(udr_msg, g_uda_cmd.uda_drmp, avp, avphdr, "DRMP", avphdr->avp_value->u32) + + /* Vendor-Specific-Application-Id */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_uda_cmd.uda_vendor_specific_application_id, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Vendor-Specific-Application-Id"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Auth-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_auth_application_d, avp, avphdr, "Auth-Application-Id", avphdr->avp_value->u32) + + /* Acct-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_acct_application_id, avp, avphdr, "Acct-Application-Id", avphdr->avp_value->u32) + } + + /* Result-Code */ + PARSE_AVP_U32(udr_msg, g_uda_cmd.uda_result_code, avp, avphdr, "Result-Code", avphdr->avp_value->u32) + + /* Experimental-Result */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_uda_cmd.uda_experimental_result, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Experimental-Result"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Experimental-Result-Code */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_experimental_result_code, avp, avphdr, "Experimental-Result-Code", avphdr->avp_value->u32) + } + + /* Auth-Session-State */ + PARSE_AVP_U32(udr_msg, g_uda_cmd.uda_auth_session_state, avp, avphdr, "Auth-Session-State", avphdr->avp_value->u32) + + + /* Origin-Host */ + PARSE_AVP_STR(udr_msg, g_uda_cmd.uda_origin_host, avp, avphdr, "Origin-Host", avphdr->avp_value->os.data) + + /* Origin-Realm */ + PARSE_AVP_STR(udr_msg, g_uda_cmd.uda_origin_realm, avp, avphdr, "Origin-Realm", avphdr->avp_value->os.data) + + /* Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_uda_cmd.uda_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Supported-Features"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Feature-List-ID */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_feature_list_id, avp, avphdr, "Feature-List-ID", avphdr->avp_value->u32) + + /* Feature-List */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_feature_list, avp, avphdr, "Feature-List", avphdr->avp_value->u32) + } + + /* Wildcarded-Public-Identity */ + PARSE_AVP_STR(udr_msg, g_uda_cmd.uda_wildcarded_public_identity, avp, avphdr, "Wildcarded-Public-Identity", avphdr->avp_value->os.data) + + /* Wildcarded-IMPU */ + PARSE_AVP_STR(udr_msg, g_uda_cmd.uda_wildcarded_impu, avp, avphdr, "Wildcarded-IMPU", avphdr->avp_value->os.data) + + /* User-Data */ + PARSE_AVP_STR(udr_msg, g_uda_cmd.uda_user_data, avp, avphdr, "User-Data", avphdr->avp_value->os.data) + + + /* OC-Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_uda_cmd.uda_oc_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj OC-Supported-Features"); + + /* OC-Feature-Vector */ + // PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_oc_feature_vector, avp, avphdr, "OC-Feature-Vector", avphdr->avp_value->u64) + } + + /* OC-OLR */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_uda_cmd.uda_oc_olr, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj OC-OLR"); + + /* OC-Sequence-Number */ + PARSE_GRPAVP_U64(grpavp, g_uda_cmd.uda_oc_sequence_number, avp, avphdr, "OC-Sequence-Number", avphdr->avp_value->u64) + + /* OC-Report-Type */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_oc_report_type, avp, avphdr, "OC-Report-Type", avphdr->avp_value->u32) + + /* OC-Reduction-Percentage */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_oc_reduction_percentage, avp, avphdr, "OC-Reduction-Percentage", avphdr->avp_value->u32) + + /* OC-Validity-Duration */ + PARSE_GRPAVP_U32(grpavp, g_uda_cmd.uda_oc_validity_duration, avp, avphdr, "OC-Validity-Duration", avphdr->avp_value->u32) + } +out: + return 0; +} + + + +/* Cb called when an answer is received */ +static int sh_rec_pua( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act) +{ + LOG_D("fj sh_rec_pua in"); + + fprintf(stderr, "ECHO PUA received from 'server.domain', done...\n"); + + sh_parse_pua(msg); + + /* Free the message */ + CHECK_FCT_DO(fd_msg_free(*msg), return 0); + *msg = NULL; + + return 0; +} + +static int sh_rec_uda( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act) +{ + LOG_D("fj sh_rec_uda in\n"); + + fprintf(stderr, "ECHO UDA received from 'server.domain', replying...\n"); + + sh_parse_uda(msg); + + // sh_send_pur(); + + /* Free the message */ + CHECK_FCT_DO(fd_msg_free(*msg), return 0); + *msg = NULL; + + return 0; +#if 0 + struct sess_state * mi = NULL; + struct timespec ts; + struct session * sess; + struct avp * avp; + struct avp_hdr * hdr; + unsigned long dur; + int error = 0; + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return ); + + /* Search the session, retrieve its data */ + { + int new; + CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new), return ); + ASSERT( new == 0 ); + + CHECK_FCT_DO( fd_sess_state_retrieve( sh_cli_reg, sess, &mi ), return ); + ASSERT( (void *)mi == data ); + } + + /* Now log content of the answer */ + fprintf(stderr, "RECV "); + + /* Value of Test-AVP */ + CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_avp, &avp), return ); + if (avp) { + CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + if (hdr->avp_value->i32 == mi->randval) { + fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "Ok"); + } else { + fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "PROBLEM"); + error++; + } + } else { + fprintf(stderr, "no_Test-AVP "); + error++; + } + + /* Value of Result Code */ + CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_res_code, &avp), return ); + if (avp) { + CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + fprintf(stderr, "Status: %d ", hdr->avp_value->i32); + if (hdr->avp_value->i32 != 2001) + error++; + } else { + fprintf(stderr, "no_Result-Code "); + error++; + } + + /* Value of Origin-Host */ + CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_host, &avp), return ); + if (avp) { + CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + fprintf(stderr, "From '%.*s' ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data); + } else { + fprintf(stderr, "no_Origin-Host "); + error++; + } + + /* Value of Origin-Realm */ + CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_realm, &avp), return ); + if (avp) { + CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + fprintf(stderr, "('%.*s') ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data); + } else { + fprintf(stderr, "no_Origin-Realm "); + error++; + } + + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + ((ts.tv_nsec - mi->ts.tv_nsec) / 1000); + if (ta_conf->stats.nb_recv) { + /* Ponderate in the avg */ + ta_conf->stats.avg = (ta_conf->stats.avg * ta_conf->stats.nb_recv + dur) / (ta_conf->stats.nb_recv + 1); + /* Min, max */ + if (dur < ta_conf->stats.shortest) + ta_conf->stats.shortest = dur; + if (dur > ta_conf->stats.longest) + ta_conf->stats.longest = dur; + } else { + ta_conf->stats.shortest = dur; + ta_conf->stats.longest = dur; + ta_conf->stats.avg = dur; + } + + if (error) + ta_conf->stats.nb_errs++; + else + ta_conf->stats.nb_recv++; + + + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + + /* Display how long it took */ + if (ts.tv_nsec > mi->ts.tv_nsec) { + fprintf(stderr, "in %d.%06ld sec", + (int)(ts.tv_sec - mi->ts.tv_sec), + (long)(ts.tv_nsec - mi->ts.tv_nsec) / 1000); + } else { + fprintf(stderr, "in %d.%06ld sec", + (int)(ts.tv_sec + 1 - mi->ts.tv_sec), + (long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000); + } + fprintf(stderr, "\n"); + fflush(stderr); + + /* Free the message */ + CHECK_FCT_DO(fd_msg_free(*msg), return); + *msg = NULL; + + free(mi); +#endif +} + + +#if 0 +static void sh_send_entry() +{ + static int i = 0; + + if((++i)%2) + sh_send_udr(); + else + sh_send_pur(); +} +#endif +/* Default callback for the application. */ +#if 0 +static int ta_fb_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act) +{ + /* This CB should never be called */ + TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); + + fd_log_debug("Unexpected message received!"); + + return ENOTSUP; +} +#endif + +int sh_cli_init(void) +{ + CHECK_FCT( fd_sess_handler_create(&sh_cli_reg, (void *)free, NULL, NULL) ); + + /* fj added */ + { + struct disp_when data; + + LOG_D("Initializing dispatch callbacks for test"); + + memset(&data, 0, sizeof(data)); + data.app = sh_appli; + data.command = uda_cmd; + + /* Now specific handler for UDR */ + CHECK_FCT( fd_disp_register( sh_rec_uda, DISP_HOW_CC, &data, NULL, &sh_hdl_uda ) ); + + memset(&data, 0, sizeof(data)); + data.app = sh_appli; + data.command = pua_cmd; + /* Now specific handler for PUR */ + CHECK_FCT( fd_disp_register( sh_rec_pua, DISP_HOW_CC, &data, NULL, &sh_hdl_pua ) ); + } + + return 0; +} + +void sh_cli_finit(void) +{ + CHECK_FCT_DO( fd_sess_handler_destroy(&sh_cli_reg, NULL), /* continue */ ); + + /* fj added */ + if (sh_hdl_uda) { + (void) fd_disp_unregister(&sh_hdl_uda, NULL); + } + + if (sh_hdl_pua) { + (void) fd_disp_unregister(&sh_hdl_pua, NULL); + } + + return; +} diff --git a/plat/diameter/extensions/sh_app/sh_conf.c b/plat/diameter/extensions/sh_app/sh_conf.c new file mode 100644 index 0000000..a3008db --- /dev/null +++ b/plat/diameter/extensions/sh_app/sh_conf.c @@ -0,0 +1,371 @@ +#include "sh_conf.h" + +Ro_LinkSet rolkset={0,0}; + +int GetRoDiamIdPeer(DiamId_t **realm, DiamId_t **host, int bSms) +{ + struct peer_hdr*peer = NULL; + SH_CONF_S *pcfg = NULL; + int i; + int ret = -1; + int peer_state = -1; + if (bSms) + { + int curlk = rolkset.cursmslk; + for (i=0; ipi_diamid_peer != NULL) + { + ret = fd_peer_getbyid(pcfg->pi_diamid_peer, strlen(pcfg->pi_diamid_peer), 0, &peer); + if( !ret && peer ) + { + peer_state = fd_peer_get_state(peer); + if( STATE_OPEN == peer_state ) + { + if (rolkset.smslk[curlk].bconn == 0) + { + printf("diam peer disconn to conn, host[%s]\r\n", pcfg->pi_diamid_peer); + rolkset.smslk[curlk].bconn = 1; + } + *realm = pcfg->pi_diamid_realm_peer; + *host = pcfg->pi_diamid_peer; + return 1; + } + else + { + if (rolkset.smslk[curlk].bconn == 1) + { + printf("diam peer conn to discon, host[%s]\r\n", pcfg->pi_diamid_peer); + rolkset.smslk[curlk].bconn = 0; + } + } + } + else + { + printf("diam peer NA, host[%s], ret[%d], peer[%p]\r\n", pcfg->pi_diamid_peer, ret, peer); + rolkset.smslk[curlk].bconn = 0; + } + } + } + } + else + { + int curlk = rolkset.curvoicelk; + for (i=0; ipi_diamid_peer != NULL) + { + ret = fd_peer_getbyid(pcfg->pi_diamid_peer, strlen(pcfg->pi_diamid_peer), 0, &peer); + if( !ret && peer ) + { + peer_state = fd_peer_get_state(peer); + if( STATE_OPEN == peer_state ) + { + if (rolkset.voicelk[curlk].bconn == 0) + { + printf("diam peer disconn to conn, host[%s]\r\n", pcfg->pi_diamid_peer); + rolkset.voicelk[curlk].bconn = 1; + } + *realm = pcfg->pi_diamid_realm_peer; + *host = pcfg->pi_diamid_peer; + return 1; + } + else + { + if (rolkset.voicelk[curlk].bconn == 1) + { + printf("diam peer conn to discon, host[%s]\r\n", pcfg->pi_diamid_peer); + rolkset.voicelk[curlk].bconn = 0; + } + } + } + else + { + printf("diam peer NA, host[%s], ret[%d], peer[%p]\r\n", pcfg->pi_diamid_peer, ret, peer); + rolkset.voicelk[curlk].bconn = 0; + } + } + } + } + return 0; +} + +int AddRoLink(SH_CONF_S *cfg, uint16_t port, int bSms) +{ + if (bSms) + { + if(rolkset.smslknum >= MaxRoLinkNum) + { + return 0; + } + + rolkset.smslk[rolkset.smslknum].cfg.pi_diamid_peer = strdup(cfg->pi_diamid_peer); + rolkset.smslk[rolkset.smslknum].cfg.pi_diamid_realm_peer = strdup(cfg->pi_diamid_realm_peer); + rolkset.smslk[rolkset.smslknum].cfg.peer_port = port; + rolkset.smslknum++; + } + else + { + if(rolkset.voicelknum >= MaxRoLinkNum) + { + return 0; + } + + rolkset.voicelk[rolkset.voicelknum].cfg.pi_diamid_peer = strdup(cfg->pi_diamid_peer); + rolkset.voicelk[rolkset.voicelknum].cfg.pi_diamid_realm_peer = strdup(cfg->pi_diamid_realm_peer); + rolkset.voicelk[rolkset.voicelknum].cfg.peer_port = port; + rolkset.voicelknum++; + } + return 1; +} + +SH_CONF_S g_sh_conf_ext; +//SH_CONF_S g_rovoice_conf_ext; +//SH_CONF_S g_rosms_conf_ext; + +#define SH_PARSE_BUFFER_LEN 1024 + +static char* shParseStr_(char* buffer, char* _key, char *ret_str, int flag_from_begin) +{ + char *pos = strstr(buffer, _key); + char *pos_1 = NULL; + char *pos_2 = NULL; + if(NULL != pos && (flag_from_begin ? (buffer == pos) : 1) ) + { + pos_1 = strstr(pos, "\""); + if(NULL != pos_1) + { + pos_2 = strstr(pos_1 + 1, "\""); + if(NULL != pos_2) + { + memcpy(ret_str, pos_1 + 1, pos_2 - pos_1 - 1); + ret_str[pos_2 - pos_1] = '\0'; + // fprintf(stderr, "%s=%s\n", _key, ret_str); + return ret_str; + } + } + } + return NULL; +} + +static char* shParseStr(char* buffer, char* _key, char *ret_str) +{ + return shParseStr_(buffer, _key, ret_str, 1); +} +static char* shParseStrSub(char* buffer, char* _key, char *ret_str) +{ + return shParseStr_(buffer, _key, ret_str, 0); +} + +uint16_t shParseInt(char* buffer, char* _key, uint16_t* ret_int) +{ + char buff_num[16] = {0}; + + char *pos = strstr(buffer, _key); + char *pos_1 = NULL; + char *pos_2 = NULL; + /* first address is start of the line */ + if(NULL != pos && buffer == pos) + { + pos_1 = strstr(pos, "="); + if(NULL != pos_1) + { + pos_2 = strstr(pos_1 + 1, ";"); + if(NULL != pos_2) + { + memcpy(buff_num, pos_1 + 1, pos_2 - pos_1 - 1); + *ret_int = atol( buff_num ); + // fprintf(stderr, "%s=%d\n", _key, *ret_int); + return *ret_int; + } + } + } + return 0; +} + +int shParseFlags(char* buffer, char* _key, char* no_flag_key) +{ + char *pos = strstr(buffer, _key); + char *pos_1 = NULL; + char *pos_2 = NULL; + /* first address is start of the line */ + if(NULL != pos && buffer == pos) + { + pos_1 = strstr(pos, "{"); + if(NULL != pos_1) + { + pos_2 = strstr(pos_1 + 1, "}"); + if(NULL != pos_2) + { + if(strstr( pos_1 + 1, no_flag_key) ) + { + // fprintf(stderr, "%s\n", no_flag_key); + return 1; + } + } + } + } + return 0; +} + +int shParse_(struct fd_config * conf) +{ + FILE* fd; + char buffer[SH_PARSE_BUFFER_LEN] = {0}; + char ret_str[512] = {0}; + + /* Create input file descriptor */ + fd = fopen (conf->cnf_file, "r"); + if (fd == NULL) + { + perror ("open"); + return 2; + } + + conf->ro_voiceport = 29100; + conf->ro_smsport = 19500; + strcpy(conf->service_context_voice, "agrandtech_ro@3gpp.org"); + strcpy(conf->service_context_sms, "agrandtech_sms@3gpp.org"); + /* Copy process */ + while((fgets(buffer, SH_PARSE_BUFFER_LEN, fd)) != NULL) + { + if( shParseStr(buffer, "Identity", ret_str) ) + { + conf->cnf_diamid = strdup(ret_str); + conf->cnf_diamid_len = strlen(ret_str); + + memset( ret_str, 0, strlen(ret_str) ); + } + if( shParseStr(buffer, "Realm", ret_str) ) + { + conf->cnf_diamrlm = strdup(ret_str); + conf->cnf_diamrlm_len = strlen(ret_str); + + memset( ret_str, 0, strlen(ret_str) ); + } + if( shParseStr(buffer, "ServiceCxtRoVoice", ret_str) ) + { + strcpy(conf->service_context_voice, ret_str); + memset( ret_str, 0, strlen(ret_str) ); + } + if( shParseStr(buffer, "ServiceCxtRoSms", ret_str) ) + { + strcpy(conf->service_context_sms, ret_str); + memset( ret_str, 0, strlen(ret_str) ); + } + shParseInt(buffer, "RoVoicePort", &conf->ro_voiceport); + shParseInt(buffer, "RoSmsPort", &conf->ro_smsport); + shParseInt(buffer, "Port", &conf->cnf_port); + shParseInt(buffer, "SecPort", &conf->cnf_port_tls); + shParseInt(buffer, "SCTPStr", &conf->cnf_sctp_str); + + if( shParseFlags(buffer, "ConnectPeer", "No_TLS") ) + { + conf->cnf_sec_data.tls_disabled = 1; + } + if( shParseFlags(buffer, "ConnectPeer", "No_FWD") ) + { + conf->cnf_flags.no_fwd = 1; + } + if( shParseFlags(buffer, "ConnectPeer", "No_IP4") ) + { + conf->cnf_flags.no_ip4 = 1; + } + if( shParseFlags(buffer, "ConnectPeer", "No_IP6") ) + { + conf->cnf_flags.no_ip6 = 1; + } + if( shParseFlags(buffer, "ConnectPeer", "No_TCP") ) + { + conf->cnf_flags.no_tcp = 1; + } + if( shParseFlags(buffer, "ConnectPeer", "No_SCTP") ) + { + conf->cnf_flags.no_sctp = 1; + } + if( shParseFlags(buffer, "ConnectPeer", "Prefer_TCP") ) + { + conf->cnf_flags.pr_tcp = 1; + } + + memset(buffer, 0, SH_PARSE_BUFFER_LEN); + } + + fclose (fd); + + conf->cnf_flags.tls_alg = 0; + + return 0; +} + +int shParseExt(struct fd_config * conf) +{ + FILE* fd; + char buffer[SH_PARSE_BUFFER_LEN] = {0}; + char ret_str[512] = {0}; + + fd = fopen (conf->cnf_file, "r"); + if(NULL == fd) + { + perror ("open"); + return 2; + } + + while((fgets(buffer, SH_PARSE_BUFFER_LEN, fd)) != NULL) + { + shParseInt( buffer, "ServiceMod", (uint16_t*)(&g_sh_conf_ext.mode) ); + + if( shParseStr(buffer, "ConnectPeer", ret_str) ) + { + g_sh_conf_ext.pi_diamid_peer = strdup(ret_str); + memset( ret_str, 0, strlen(ret_str) ); + + if( shParseStrSub(buffer, "Realm", ret_str) ) + { + g_sh_conf_ext.pi_diamid_realm_peer = strdup(ret_str); + memset( ret_str, 0, strlen(ret_str) ); + } + g_sh_conf_ext.peer_port = fd_g_config->cnf_port; + if( shParseFlags(buffer, "ConnectPeer", "Ro_SMS") ) + { + //g_rosms_conf_ext.pi_diamid_peer = strdup(g_sh_conf_ext.pi_diamid_peer); + //g_rosms_conf_ext.pi_diamid_realm_peer = strdup(g_sh_conf_ext.pi_diamid_realm_peer); + //g_rosms_conf_ext.peer_port = fd_g_config->ro_smsport; + AddRoLink(&g_sh_conf_ext, fd_g_config->ro_smsport, 1); + free(g_sh_conf_ext.pi_diamid_peer); + g_sh_conf_ext.pi_diamid_peer = NULL; + free(g_sh_conf_ext.pi_diamid_realm_peer); + g_sh_conf_ext.pi_diamid_realm_peer = NULL; + } + if( shParseFlags(buffer, "ConnectPeer", "Ro_VOICE") ) + { + //g_rovoice_conf_ext.pi_diamid_peer = strdup(g_sh_conf_ext.pi_diamid_peer); + //g_rovoice_conf_ext.pi_diamid_realm_peer = strdup(g_sh_conf_ext.pi_diamid_realm_peer); + //g_rovoice_conf_ext.peer_port = fd_g_config->ro_voiceport; + AddRoLink(&g_sh_conf_ext, fd_g_config->ro_voiceport, 0); + free(g_sh_conf_ext.pi_diamid_peer); + g_sh_conf_ext.pi_diamid_peer = NULL; + free(g_sh_conf_ext.pi_diamid_realm_peer); + g_sh_conf_ext.pi_diamid_realm_peer = NULL; + } + } + + + shParseInt( buffer, "LogLevel", (uint16_t*)(&fd_g_debug_lvl) ); + + memset(buffer, 0, SH_PARSE_BUFFER_LEN); + } + + fclose (fd); + + return 0; +} + +int shParse(struct fd_config * conf) +{ + return shParse_(conf) || shParseExt(conf); +} diff --git a/plat/diameter/extensions/sh_app/sh_conf.h b/plat/diameter/extensions/sh_app/sh_conf.h new file mode 100644 index 0000000..9241bef --- /dev/null +++ b/plat/diameter/extensions/sh_app/sh_conf.h @@ -0,0 +1,48 @@ +#ifndef __SH_CONF_H__ +#define __SH_CONF_H__ + + +#include +#include +#include +#include +#include "sh_app.h" + +typedef struct _SH_CONF_S +{ + int mode; + DiamId_t pi_diamid_peer; + DiamId_t pi_diamid_realm_peer; + uint16_t peer_port; +}SH_CONF_S; + +extern SH_CONF_S g_sh_conf_ext; + +// Ro link from scp to ocs=============================== +typedef struct _Ro_Link_S +{ + int bconn; + SH_CONF_S cfg; +}Ro_Link_S; + +#define MaxRoLinkNum 4 +typedef struct _Ro_LinkSet +{ + int smslknum; + int voicelknum; + int cursmslk; + int curvoicelk; + + Ro_Link_S smslk[MaxRoLinkNum]; + Ro_Link_S voicelk[MaxRoLinkNum]; +}Ro_LinkSet; +extern Ro_LinkSet rolkset; +// + +//extern SH_CONF_S g_rosms_conf_ext; +//extern SH_CONF_S g_rovoice_conf_ext; + +int shParse(struct fd_config * conf); + + +#endif /* __SH_CONF_H__ */ diff --git a/plat/diameter/extensions/sh_app/sh_dict.c b/plat/diameter/extensions/sh_app/sh_dict.c new file mode 100644 index 0000000..f6b89db --- /dev/null +++ b/plat/diameter/extensions/sh_app/sh_dict.c @@ -0,0 +1,4723 @@ +#include "extension.h" +#include "sh_app.h" + + + +/* The content of this file follows the same structure as dict_base_proto.c */ + +#define CHECK_dict_new( _type, _data, _parent, _ref ) \ + CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) ); + +#define CHECK_dict_search( _type, _criteria, _what, _result ) \ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) ); + +struct local_rules_definition { + char *avp_name; + vendor_id_t avp_vendor; + enum rule_position position; + int min; + int max; +}; + +#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 ) +#if 0 +#define PARSE_loc_rules( _rulearray, _parent) { \ + int __ar; \ + for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \ + struct dict_rule_data __data = { NULL, \ + (_rulearray)[__ar].position, \ + 0, \ + (_rulearray)[__ar].min, \ + (_rulearray)[__ar].max}; \ + __data.rule_order = RULE_ORDER(__data.rule_position); \ + CHECK_FCT( fd_dict_search( \ + fd_g_config->cnf_dict, \ + DICT_AVP, \ + AVP_BY_NAME, \ + (_rulearray)[__ar].avp_name, \ + &__data.rule_avp, 0 ) ); \ + if ( !__data.rule_avp ) { \ + TRACE_DEBUG(INFO, "Fun:%s Line:%d AVP Not found: '%s'", __FUNCTION__, __LINE__, (_rulearray)[__ar].avp_name ); \ + return ENOENT; \ + } \ + CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \ + { \ + TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \ + (_rulearray)[__ar].avp_name ); \ + return EINVAL; \ + } ); \ + } \ +} +#endif + +int PARSE_loc_rules_(struct local_rules_definition _rulearray[], int len, struct dict_object *_parent) +{ + // LOG_E("PARSE_loc_rules_ enter. len:%d\n", len); + int __ar; + int ret = 0; + for (__ar=0; __ar < len /* sizeof(_rulearray) / sizeof((_rulearray)[0])*/ ; __ar++) { + struct dict_avp_request __avp; + struct dict_rule_data __data = { NULL, + (_rulearray)[__ar].position, + 0, + (_rulearray)[__ar].min, + (_rulearray)[__ar].max}; + __data.rule_order = RULE_ORDER(__data.rule_position); + + __avp.avp_vendor = (_rulearray)[__ar].avp_vendor; + __avp.avp_code = 0; + __avp.avp_name = (_rulearray)[__ar].avp_name; + + ret = fd_dict_search( + fd_g_config->cnf_dict, + DICT_AVP, + AVP_BY_NAME_AND_VENDOR, + &__avp, + &__data.rule_avp, 0); + if(ret != 0) + { + LOG_N("ret err\n"); + } + if ( !__data.rule_avp ) { + LOG_N("AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); + ret = ENOENT; + goto END; + } + CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), + { + LOG_N("Error on rule with AVP '%s'", (_rulearray)[__ar].avp_name ); + ret = EINVAL; + goto END; + } ); + } + +END: + LOG_N("PARSE_loc_rules_ out.len:%d i:%d", len, __ar); + return ret; +} + + + +struct dict_object * udr_cmd = NULL; +struct dict_object * uda_cmd = NULL; + +struct dict_object * pur_cmd = NULL; +struct dict_object * pua_cmd = NULL; + + +struct dict_object * sh_appli; +struct dict_object * sh_vendor; +struct dict_object * hw_vendor; +struct dict_object *uname_vendor_5535; +struct dict_object *uname_vendor_12645; +struct dict_object *uname_vendor_3199; +struct dict_object *uname_vendor_35; +struct dict_object *uname_vendor_11; +struct dict_object * ven1_vendor; + +#define SH_DEF_AVP(avp_code, vendor, name, flxed_flags, fixed_flags_val, base_type, ex_type) \ +{ \ + struct dict_avp_data data = { \ + avp_code, /* Code */ \ + vendor, /* Vendor */ \ + name, /* Name */ \ + flxed_flags, /* Fixed flags */ \ + fixed_flags_val, /* Fixed flag values */ \ + base_type /* base type of data */ \ + }; \ + CHECK_dict_new( DICT_AVP, &data , ex_type, NULL); \ +} + +#define SH_DEF_AVP_EM(avp_code, vendor, name, flxed_flags, fixed_flags_val, ex_name, arr) \ +{ \ + int i; \ + struct dict_avp_data data = { \ + avp_code, /* Code */ \ + vendor, /* Vendor */ \ + name, /* Name */ \ + flxed_flags, /* Fixed flags */ \ + fixed_flags_val, /* Fixed flag values */ \ + fixed_flags_val /* base type of data */ \ + }; \ + struct dict_object *type; \ + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, ex_name, NULL, NULL, NULL }; \ + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); \ + for(i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i) \ + { \ + CHECK_dict_new( DICT_ENUMVAL, &arr[i] , type, NULL); \ + } \ + CHECK_dict_new(DICT_AVP, &data, type, NULL); \ +} + + +struct dict_object * UTF8String_type; +struct dict_object * DiameterIdentity_type; +struct dict_object * DiameterURI_type; +struct dict_object * Time_type; + +int sh_dict_def_avp_base() +{ + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type); + + return 0; +} +int sh_dict_def_avp() +{ + + SH_DEF_AVP(1, 0, "User-Name", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) +#if 0 + SH_DEF_AVP(263, SH_VND_ID, "Session-Id", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(264, SH_VND_ID, "Origin-Host", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, DiameterIdentity_type) + + SH_DEF_AVP(296, SH_VND_ID, "Origin-Realm", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, DiameterIdentity_type) + + SH_DEF_AVP(293, SH_VND_ID, "Destination-Host", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, DiameterIdentity_type) + + SH_DEF_AVP(283, SH_VND_ID, "Destination-Realm", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, DiameterIdentity_type) + + SH_DEF_AVP(266, SH_VND_ID, "Vendor-Id", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_UNSIGNED32, NULL) + #endif + + SH_DEF_AVP(601, SH_VND_ID, "Public-Identity",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(602,SH_VND_ID,"Server-Name",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + #if 0 + SH_DEF_AVP(258, SH_VND_ID, "Auth-Application-Id", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(259, SH_VND_ID, "Acct-Application-Id", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, AVP_TYPE_UNSIGNED32, NULL) + + #endif + + SH_DEF_AVP(622, SH_VND_ID, "OC-Feature-Vector",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED64, NULL) + + SH_DEF_AVP(624, SH_VND_ID, "OC-Sequence-Number", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED64, NULL) + + SH_DEF_AVP(627, SH_VND_ID, "OC-Reduction-Percentage", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(629, SH_VND_ID, "Feature-List-ID", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(630,SH_VND_ID, "Feature-List", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(634, SH_VND_ID, "Wildcarded-Public-Identity", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(636, SH_VND_ID,"Wildcarded-IMPU", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(701, SH_VND_ID, "MSISDN", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(702, SH_VND_ID, "User-Data", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(704, SH_VND_ID,"Service-Indication", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, NULL) + + #if 0 + SH_DEF_AVP(709, SH_VND_ID, "Expiry-Time", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, Time_type) + #endif + + SH_DEF_AVP(711, SH_VND_ID, "DSAI-Tag", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + + SH_DEF_AVP(713, SH_VND_ID, "Requested-Nodes", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(716, SH_VND_ID, "Sequence-Number", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(719, SH_VND_ID, "UDR-Flags", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(721, SH_VND_ID,"Call-Reference-Number", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(722, SH_VND_ID, "AS-Number", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + #if 0 + SH_DEF_AVP(723, SH_VND_ID, "DRMP", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + #endif + return 0; +} +int sh_dict_def_avp_group_268() +{ + struct dict_enumval_data arr[] = { + { "DIAMETER_MULTI_ROUND_AUTH", { .u32 = ER_DIAMETER_MULTI_ROUND_AUTH }} + ,{ "DIAMETER_SUCCESS", { .u32 = ER_DIAMETER_SUCCESS }} + ,{ "DIAMETER_LIMITED_SUCCESS", { .u32 = ER_DIAMETER_LIMITED_SUCCESS }} + ,{ "DIAMETER_COMMAND_UNSUPPORTED", { .u32 = ER_DIAMETER_COMMAND_UNSUPPORTED }} + ,{ "DIAMETER_UNABLE_TO_DELIVER", { .u32 = ER_DIAMETER_UNABLE_TO_DELIVER }} + ,{ "DIAMETER_REALM_NOT_SERVED", { .u32 = ER_DIAMETER_REALM_NOT_SERVED }} + ,{ "DIAMETER_TOO_BUSY", { .u32 = ER_DIAMETER_TOO_BUSY }} + ,{ "DIAMETER_LOOP_DETECTED", { .u32 = ER_DIAMETER_LOOP_DETECTED }} + ,{ "DIAMETER_REDIRECT_INDICATION", { .u32 = ER_DIAMETER_REDIRECT_INDICATION }} + ,{ "DIAMETER_APPLICATION_UNSUPPORTED", { .u32 = ER_DIAMETER_APPLICATION_UNSUPPORTED }} + ,{ "DIAMETER_INVALID_HDR_BITS", { .u32 = ER_DIAMETER_INVALID_HDR_BITS }} + ,{ "DIAMETER_INVALID_AVP_BITS", { .u32 = ER_DIAMETER_INVALID_AVP_BITS }} + ,{ "DIAMETER_UNKNOWN_PEER", { .u32 = ER_DIAMETER_UNKNOWN_PEER }} + ,{ "DIAMETER_AUTHENTICATION_REJECTED", { .u32 = ER_DIAMETER_AUTHENTICATION_REJECTED }} + ,{ "DIAMETER_OUT_OF_SPACE", { .u32 = ER_DIAMETER_OUT_OF_SPACE }} + ,{ "ELECTION_LOST", { .u32 = ER_ELECTION_LOST }} + ,{ "DIAMETER_AVP_UNSUPPORTED", { .u32 = ER_DIAMETER_AVP_UNSUPPORTED }} + ,{ "DIAMETER_UNKNOWN_SESSION_ID", { .u32 = ER_DIAMETER_UNKNOWN_SESSION_ID }} + ,{ "DIAMETER_AUTHORIZATION_REJECTED",{ .u32 = ER_DIAMETER_AUTHORIZATION_REJECTED }} + ,{ "DIAMETER_INVALID_AVP_VALUE", { .u32 = ER_DIAMETER_INVALID_AVP_VALUE }} + ,{ "DIAMETER_MISSING_AVP", { .u32 = ER_DIAMETER_MISSING_AVP }} + ,{ "DIAMETER_RESOURCES_EXCEEDED", { .u32 = ER_DIAMETER_RESOURCES_EXCEEDED }} + ,{ "DIAMETER_CONTRADICTING_AVPS", { .u32 = ER_DIAMETER_CONTRADICTING_AVPS }} + ,{ "DIAMETER_AVP_NOT_ALLOWED", { .u32 = ER_DIAMETER_AVP_NOT_ALLOWED }} + ,{ "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES",{ .u32 = ER_DIAMETER_AVP_OCCURS_TOO_MANY_TIMES }} + ,{ "DIAMETER_NO_COMMON_APPLICATION",{ .u32 = ER_DIAMETER_NO_COMMON_APPLICATION }} + ,{ "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES",{ .u32 = ER_DIAMETER_AVP_OCCURS_TOO_MANY_TIMES }} + ,{ "DIAMETER_NO_COMMON_APPLICATION",{ .u32 = ER_DIAMETER_NO_COMMON_APPLICATION }} + ,{ "DIAMETER_UNSUPPORTED_VERSION", { .u32 = ER_DIAMETER_UNSUPPORTED_VERSION }} + ,{ "DIAMETER_UNABLE_TO_COMPLY", { .u32 = ER_DIAMETER_UNABLE_TO_COMPLY }} + ,{ "DIAMETER_INVALID_BIT_IN_HEADER", { .u32 = ER_DIAMETER_INVALID_BIT_IN_HEADER }} + ,{ "DIAMETER_INVALID_AVP_LENGTH", { .u32 = ER_DIAMETER_INVALID_AVP_LENGTH }} + ,{ "DIAMETER_INVALID_MESSAGE_LENGTH", { .u32 = ER_DIAMETER_INVALID_MESSAGE_LENGTH }} + ,{ "DIAMETER_INVALID_AVP_BIT_COMBO", { .u32 = ER_DIAMETER_INVALID_AVP_BIT_COMBO }} + ,{ "DIAMETER_NO_COMMON_SECURITY", { .u32 = ER_DIAMETER_NO_COMMON_SECURITY }} + //,{ "DIAMETER_USER_UNKNOWN", { .u32 = ER_DIAMETER_USER_UNKNOWN }} + }; + SH_DEF_AVP_EM(268, 0, "Result-Code", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY, "Enumerated*(Result-Code)", arr) + + return 0; +} +int sh_dict_def_avp_group_298() +{ + /* Experimental-Result-Code */ + { + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Experimental-Result-Code)" , NULL, NULL, NULL }; + struct dict_avp_data data = { + 298, /* Code */ + SH_VND_ID, /* Vendor */ + "Experimental-Result-Code", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + return 0; +} +int sh_dict_def_avp_group_297() +{ + /* Experimental-Result */ + /* + The Experimental-Result AVP (AVP Code 297) is of type Grouped, and + indicates whether a particular vendor-specific request was completed + successfully or whether an error occurred. Its Data field has the + following ABNF grammar: + + AVP Format + + Experimental-Result ::= < AVP Header: 297 > + { Vendor-Id } + { Experimental-Result-Code } + + The Vendor-Id AVP (see Section 5.3.3) in this grouped AVP identifies + the vendor responsible for the assignment of the result code which + follows. All Diameter answer messages defined in vendor-specific + applications MUST include either one Result-Code AVP or one + Experimental-Result AVP. + */ + struct dict_object * avp; + struct dict_avp_data data = { + 297, /* Code */ + SH_VND_ID, /* Vendor */ + "Experimental-Result", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + /* ABNF from RFC6733 */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } +#else /* WORKAROUND_ACCEPT_INVALID_VSAI */ + /* ABNF from RFC3588 (including erratum, because original text is nonsense) */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, -1} +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + ,{ "Experimental-Result-Code", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + /* Create the grouped AVP */ + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_260() +{ + /* Vendor-Specific-Application-Id */ + /* + ::= < AVP Header: 260 > + { Vendor-Id } + [ Auth-Application-Id ] + [ Acct-Application-Id ] + + A Vendor-Specific-Application-Id AVP MUST contain exactly one of + either Auth-Application-Id or Acct-Application-Id. If a Vendor- + Specific-Application-Id is received without any of these two AVPs, + then the recipient SHOULD issue an answer with a Result-Code set to + DIAMETER_MISSING_AVP. The answer SHOULD also include a Failed-AVP + which MUST contain an example of an Auth-Application-Id AVP and an + Acct-Application-Id AVP. + + If a Vendor-Specific-Application-Id is received that contains both + Auth-Application-Id and Acct-Application-Id, then the recipient + SHOULD issue an answer with Result-Code set to + DIAMETER_AVP_OCCURS_TOO_MANY_TIMES. The answer SHOULD also include a + Failed-AVP which MUST contain the received Auth-Application-Id AVP + and Acct-Application-Id AVP. + */ + struct dict_object * avp; + struct dict_avp_data data = { + 260, /* Code */ +#if AC_VENDOR_SPECIFIC_APPLICATION_ID != 260 +#error "AC_VENDOR_SPECIFIC_APPLICATION_ID definition mismatch" +#endif + SH_VND_ID, /* Vendor */ + "Vendor-Specific-Application-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + /* ABNF from RFC6733 */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } +#else /* WORKAROUND_ACCEPT_INVALID_VSAI */ + /* ABNF from RFC3588 (including erratum, because original text is nonsense) */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, -1} +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + ,{ "Auth-Application-Id", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Application-Id", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + /* Create the grouped AVP */ + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_631() +{ + /* Supported-Applications */ + struct dict_avp_data data = { + 631, /* Code */ + SH_VND_ID, /* Vendor */ + "Supported-Applications", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + + return 0; +} + +int sh_dict_def_avp_group_628() +{ + /* Supported-Features */ + /* + Supported-Features ::= < AVP header: 628 10415 > + { Vendor-Id } + { Feature-List-ID } + { Feature-List } + *[AVP] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 628, /* Code */ + SH_VND_ID, /* Vendor */ + "Supported-Features", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Feature-List-ID", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Feature-List", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_650() +{ + /* Session-Priority */ + struct dict_avp_data data = { + 650, /* Code */ + SH_VND_ID, /* Vendor */ + "Session-Priority", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Priority)", NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "PRIORITY-0", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "PRIORITY-1", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "PRIORITY-2", { .u32 = 2 }}; + struct dict_enumval_data t_3 = { "PRIORITY-3", { .u32 = 3 }}; + struct dict_enumval_data t_4 = { "PRIORITY-4", { .u32 = 4 }}; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_623_() +{ + #if 0 + SH_DEF_AVP( + 623, /* Code */ + 0, /* Vendor */ /* confi with 29.329 */ + "User-Authorization-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + ) + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "User-Authorization-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "REGISTRATION", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "DE_REGISTRATION", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + #endif + return 0; +} +int sh_dict_def_avp_group_703() +{ + /* Data-Reference */ + struct dict_avp_data data = { + 703, /* Code */ + SH_VND_ID, /* Vendor */ + "Data-Reference", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Data-Reference)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "RepositoryData", { .u32 = 0 }}; + struct dict_enumval_data t_10 = { "IMSPublicIdentity", { .u32 = 10 }}; + struct dict_enumval_data t_11 = { "IMSUserState", { .u32 = 11 }}; + struct dict_enumval_data t_12 = { "S-CSCFName", { .u32 = 12 }}; + struct dict_enumval_data t_13 = { "InitialFilterCriteria", { .u32 = 13 }}; + struct dict_enumval_data t_14 = { "LocationInformation", { .u32 = 14 }}; + struct dict_enumval_data t_15 = { "UserState", { .u32 = 15 }}; + struct dict_enumval_data t_16 = { "ChargingInformation", { .u32 = 16 }}; + struct dict_enumval_data t_17 = { "MSISDN", { .u32 = 17 }}; + struct dict_enumval_data t_18 = { "PSIActivation", { .u32 = 18 }}; + struct dict_enumval_data t_19 = { "DSAI", { .u32 = 19 }}; + struct dict_enumval_data t_21 = { "ServiceLevelTraceInfo", { .u32 = 21 }}; + struct dict_enumval_data t_22 = { "IPAddressSecureBindingInformation", { .u32 = 22 }}; + struct dict_enumval_data t_23 = { "ServicePriorityLevel", { .u32 = 23 }}; + struct dict_enumval_data t_24 = { "SMSRegistrationInfo", { .u32 = 24 }}; + struct dict_enumval_data t_25 = { "UEReachabilityForIP", { .u32 = 25 }}; + struct dict_enumval_data t_26 = { "TADSinformation", { .u32 = 26 }}; + struct dict_enumval_data t_27 = { "STN-SR", { .u32 = 27 }}; + struct dict_enumval_data t_28 = { "UE-SRVCC-Capability", { .u32 = 28 }}; + struct dict_enumval_data t_29 = { "ExtendedPriority", { .u32 = 29 }}; + struct dict_enumval_data t_30 = { "CSRN", { .u32 = 30 }}; + struct dict_enumval_data t_31 = { "ReferenceLocationInformation", { .u32 = 31 }}; + struct dict_enumval_data t_32 = { "IMSI", { .u32 = 32 }}; + struct dict_enumval_data t_33 = { "IMSPrivateUserIdentity", { .u32 = 33 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_10 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_11 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_12 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_13 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_14 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_15 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_16 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_17 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_18 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_19 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_21 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_22 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_23 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_24 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_25 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_26 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_27 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_28 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_29 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_30 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_31 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_32 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_33 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_705() +{ + /* Subs-Req-Type AVP */ + struct dict_avp_data data = { + 705, /* Code */ + SH_VND_ID, /* Vendor */ + "Subs-Req-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Subs-Req-Type AVP", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "Subscribe", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "Unsubscribe", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_706() +{ + /* Requested-Domain AVP */ + struct dict_avp_data data = { + 706, /* Code */ + SH_VND_ID, /* Vendor */ + "Requested-Domain", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Requested-Domain", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "CS-Domain", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "PS-Domain", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_707() +{ + /* Current-Location AVP */ + struct dict_avp_data data = { + 707, /* Code */ + SH_VND_ID, /* Vendor */ + "Current-Location", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Current-Location", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "DoNotNeedInitiateActiveLocationRetrieval", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "InitiateActiveLocationRetrieval", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_708() +{ + /* Identity-Set AVP */ + struct dict_avp_data data = { + 708, /* Code */ + SH_VND_ID, /* Vendor */ + "Identity-Set", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Identity-Set", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ALL_IDENTITIES", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "REGISTERED_IDENTITIES", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "IMPLICIT_IDENTITIES", { .u32 = 2 }}; + struct dict_enumval_data t_3 = { "ALIAS_IDENTITIES", { .u32 = 3 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_701() +{ + /* Send-Data-Indication AVP*/ + struct dict_avp_data data = { + 710, /* Code */ + SH_VND_ID, /* Vendor */ + "Send-Data-Indication", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Send-Data-Indication)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "USER_DATA_NOT_REQUESTED", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "USER_DATA_REQUESTED", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_712() +{ + /* One-Time-Notification AVP*/ + struct dict_avp_data data = { + 712, /* Code */ + SH_VND_ID, /* Vendor */ + "One-Time-Notification", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(One-Time-Notification)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ONE_TIME_NOTIFICATION_REQUESTED", { .u32 = 0 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_714() +{ + /* Serving-Node-Indication AVP*/ + struct dict_avp_data data = { + 714, /* Code */ + SH_VND_ID, /* Vendor */ + "Serving-Node-Indication", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Serving-Node-Indication)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ONLY_SERVING_NODES_REQUIRED", { .u32 = 0 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_715() +{ + /* Repository-Data-ID AVP */ + /* + The Repository-Data-ID AVP is of type Grouped. This AVP shall contain a Service-Indication AVP and a Sequence- + Number AVP. + AVP format + Repository-Data-ID ::= + {Service-Indication} + {Sequence-Number} + *[AVP] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 715, /* Code */ + SH_VND_ID, /* Vendor */ + "Repository-Data-ID", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Service-Indication", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Sequence-Numbe", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_717() +{ + /* Pre-paging-Supported AVP */ + struct dict_avp_data data = { + 717, /* Code */ + SH_VND_ID, /* Vendor */ + "Pre-paging-Supported", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Pre-paging-Supported)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "PREPAGING_NOT_SUPPORTED", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "PREPAGING_SUPPORTED", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_718() +{ + /* Local-Time-Zone-Indication AVP */ + struct dict_avp_data data = { + 718, /* Code */ + SH_VND_ID, /* Vendor */ + "Local-Time-Zone-Indication", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Local-Time-Zone-Indication)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ONLY_LOCAL_TIME_ZONE_REQUESTED", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "LOCAL_TIME_ZONE_WITH_LOCATION_INFO_REQUESTED", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_720() +{ + /* Call-Reference-Info AVP */ + /* + The Call-Reference-Info AVP is of type Grouped. This AVP shall contain a Call-Reference-Number AVP and an ASNumber + AVP. + AVP format + Call-Reference-Info ::= + {Call-Reference-Number} + {AS-Number} + *[AVP] + + */ + struct dict_object * avp; + struct dict_avp_data data = { + 720, /* Code */ + SH_VND_ID, /* Vendor */ + "Call-Reference-Info", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "Call-Reference-Number", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "AS-Number}", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_621() +{ + /* OC-Supported-Features AVP */ + /* + The OC-Supported-Features AVP (AVP Code 621) is of type Grouped and + serves two purposes. First, it announces a node's support for the + DOIC solution in general. Second, it contains the description of the + supported DOIC features of the sending node. The OC-Supported- + Features AVP MUST be included in every Diameter request message a + DOIC supporting node sends. + + OC-Supported-Features ::= < AVP Header: 621 > + [ OC-Feature-Vector ] + * [ AVP ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 621, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Supported-Features", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "OC-Feature-Vector", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_626() +{ + /* OC-Report-Type AVP */ + struct dict_avp_data data = { + 626, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Report-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "OC-Report-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "HOST_REPORT", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "REALM_REPORT", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_627() +{ + /* OC-Reduction-Percentage AVP */ + struct dict_avp_data data = { + 627, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Reduction-Percentage", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "OC-Reduction-Percentage", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_623() +{ + /* OC-OLR AVP */ + /* + OC-OLR ::= < AVP Header: 623 > + < OC-Sequence-Number > + < OC-Report-Type > + [ OC-Reduction-Percentage ] + [ OC-Validity-Duration ] + * [ AVP ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 623, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-OLR", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "OC-Sequence-Number", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } /* flag to be make sure */ + ,{ "OC-Report-Type", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } /* flag to be make sure */ + ,{ "OC-Reduction-Percentage", SH_VND_ID, RULE_OPTIONAL, -1, 1 } /* flag to be make sure */ + ,{ "OC-Validity-Duration", SH_VND_ID, RULE_OPTIONAL, -1, 1 } /* flag to be make sure */ + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_625() +{ + /* OC-Validity-Duration AVP */ + struct dict_avp_data data = { + 625, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Validity-Duration", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "OC-Validity-Duration", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_700() +{ + /* + User-Identity ::= + [Public-Identity] + [MSISDN] + *[AVP] + */ + /* User-Identity group */ + struct dict_object * avp = NULL; + struct dict_avp_data data = { + 700, /* Code */ + SH_VND_ID, /* Vendor */ + "User-Identity", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "MSISDN", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_723() +{ + /* OC-Validity-Duration AVP */ + struct dict_avp_data data = { + 723, /* Code */ + SH_VND_ID, /* Vendor */ + "DRMP", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "DRMP", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_15 = { "PRIORITY_15", { .u32 = 15 }}; + struct dict_enumval_data t_14 = { "PRIORITY_14", { .u32 = 14 }}; + struct dict_enumval_data t_13 = { "PRIORITY_13", { .u32 = 13 }}; + struct dict_enumval_data t_12 = { "PRIORITY_12", { .u32 = 12 }}; + struct dict_enumval_data t_11 = { "PRIORITY_11", { .u32 = 11 }}; + struct dict_enumval_data t_10 = { "PRIORITY_10", { .u32 = 10 }}; + struct dict_enumval_data t_9 = { "PRIORITY_9", { .u32 = 9 }}; + struct dict_enumval_data t_8 = { "PRIORITY_8", { .u32 = 8 }}; + struct dict_enumval_data t_7 = { "PRIORITY_7", { .u32 = 7 }}; + struct dict_enumval_data t_6 = { "PRIORITY_6", { .u32 = 6 }}; + struct dict_enumval_data t_5 = { "PRIORITY_5", { .u32 = 5 }}; + struct dict_enumval_data t_4 = { "PRIORITY_4", { .u32 = 4 }}; + struct dict_enumval_data t_3 = { "PRIORITY_3", { .u32 = 3 }}; + struct dict_enumval_data t_2 = { "PRIORITY_2", { .u32 = 2 }}; + struct dict_enumval_data t_1 = { "PRIORITY_1", { .u32 = 1 }}; + struct dict_enumval_data t_0 = { "PRIORITY_0", { .u32 = 0 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_15 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_14 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_13 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_12 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_11 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_10 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_9 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_8 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_7 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_6 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_5 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + + return 0; +} + +int sh_dict_def_cmd_udr() +{ + /* User-Data-Request (UDR) Command */ + /* + The User-Data-Request (UDR) command, indicated by the Com + mand-Code field set to 306 and the ‘R?bit set in the + Command Flags field, is sent by a Diameter client to a Diameter server in order to request user data. + Message Format: + + < User-Data -Request> ::= < Diameter Header: 306, REQ, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Destination-Host ] + { Destination-Realm } + *[ Supported-Features ] + { User-Identity } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ Server-Name ] + *[ Service-Indication ] + *{ Data-Reference } + *[ Identity-Set ] + [ Requested-Domain ] + [ Current-Location ] + *[ DSAI-Tag ] + [ Session-Priority ] + [ User-Name ] + [ Requested-Nodes ] + [ Serving-Node-Indication ] + [ Pre-paging-Supported ] + [ Local-Time-Zone-Indication ] + [ UDR-Flags ] + [ Call-Reference-Info ] + [ OC-Supported-Features ] + *[ AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + */ + // struct dict_object * udr_cmd; // cmd; + struct dict_cmd_data data = { + 306, /* Code */ + "User-Data-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", 0, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", 0, RULE_REQUIRED, -1, 1 } + ,{ "Auth-Session-State", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", 0, RULE_REQUIRED, -1, 1 } + ,{ "Destination-Host", 0, RULE_OPTIONAL, -1, 1 } + ,{ "Destination-Realm", 0, RULE_REQUIRED, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "User-Identity", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Server-Name", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Service-Indication", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Data-Reference", SH_VND_ID, RULE_REQUIRED, -1, -1 } + ,{ "Identity-Set", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Requested-Domain", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Current-Location", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "DSAI-Tag", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Session-Priority", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "User-Name", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Requested-Nodes", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Serving-Node-Indication", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Pre-paging-Supported", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Local-Time-Zone-Indication", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "UDR-Flags", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Call-Reference-Info", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &udr_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), udr_cmd); // cmd ); + + return 0; +} +int sh_dict_def_cmd_uda() +{ + /* User-Data-Answer (UDA) Command */ + /* + The User-Data-Answer (UDA) command, indicated by the Command-Code field set to 306 and the ‘R?bit cleared in + the Command Flags field, is sent by a server in response to the User-Data-Request command. The Experimental-Result + AVP may contain one of the values defined in section 6.2 or in 3GPP TS 29.229 [6]. + Message Format: + + < User-Data-Answer > ::= < Diameter Header: 306, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + *[ Supported-Features ] + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ User-Data ] + [ OC-Supported-Features ] + [ OC-OLR ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + */ + // struct dict_object *uda_cmd; // cmd; + struct dict_cmd_data data = { + 306, /* Code */ + "User-Data-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", 0, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", 0, RULE_REQUIRED, -1, 1 } + ,{ "Result-Code", 0, RULE_OPTIONAL, -1, 1 } + ,{ "Experimental-Result", 0, RULE_OPTIONAL, -1, 1 } + ,{ "Auth-Session-State", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", 0, RULE_REQUIRED, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "User-Data", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-OLR", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &uda_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), uda_cmd/*cmd*/); + + return 0; +} +int sh_dict_def_cmd_pur() +{ + /* Profile-Update-Request (PUR) Command */ + /* + The Profile-Update-Request (PUR) command, indicated by the Command-Code field set to 307 and the ‘R?bit set in + the Command Flags field, is sent by a Diameter client to a Diameter server in order to update user data in the server. + Message Format: + + < Profile-Update-Request > ::= < Diameter Header: 307, REQ, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Destination-Host ] + { Destination-Realm } + *[ Supported-Features ] + { User-Identity } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ User-Name ] + *{ Data-Reference } + { User-Data } + [ OC-Supported-Features ] + *[ AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + */ + // struct dict_object * pur_cmd; // cmd; + struct dict_cmd_data data = { + 307, /* Code */ + "Profile-Update-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", 0, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", 0, RULE_REQUIRED, -1, 1 } + ,{ "Auth-Session-State", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", 0, RULE_REQUIRED, -1, 1 } + ,{ "Destination-Host", 0, RULE_OPTIONAL, -1, 1 } + ,{ "Destination-Realm", 0, RULE_REQUIRED, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "User-Identity", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "User-Name", 0, RULE_OPTIONAL, -1, 1 } + ,{ "Data-Reference", SH_VND_ID, RULE_REQUIRED, -1, -1 } + ,{ "User-Data", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &pur_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), pur_cmd); // cmd ); + + return 0; +} +int sh_dict_def_cmd_pua() +{ + /* Profile-Update-Answer (PUA) Command */ + /* + The Profile-Update-Answer (PUA) command, indicated by the Command-Code field set to 307 and the ‘R?bit cleared + in the Command Flags field, is sent by a server in response to the Profile-Update-Request command. The Experimental- + Result AVP may contain one of the values defined in section 6.2 or in 3GPP TS 29.229 [6]. + Message Format: + + < Profile-Update-Answer > ::=< Diameter Header: 307, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ Repository-Data-ID ] + [ Data-Reference ] + *[ Supported-Features ] + [ OC-Supported-Features ] + [ OC-OLR ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + + */ +// struct dict_object * pur_cmd;// cmd; + struct dict_cmd_data data = { + 307, /* Code */ + "Profile-Update-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", 0, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", 0, RULE_REQUIRED, -1, 1 } + ,{ "Result-Code", 0, RULE_OPTIONAL, -1, 1 } + ,{ "Experimental-Result", 0, RULE_OPTIONAL, -1, 1 } + ,{ "Auth-Session-State", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", 0, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", 0, RULE_REQUIRED, -1, 1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Repository-Data-ID", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Data-Reference", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-OLR", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &pua_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), pua_cmd); // cmd ); + + return 0; +} +int sh_dict_def_avp_3x() +{ + SH_DEF_AVP(30,0,"Called-Station-Id",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + return 0; +} + +int sh_dict_def_avp_3xx() +{ + SH_DEF_AVP(363,0,"Accounting-Input-Octets",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED64, NULL) + + SH_DEF_AVP(364,0,"Accounting-Output-Octets",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED64, NULL) + + SH_DEF_AVP(365,0,"Accounting-Input-Packets",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED64, NULL) + + SH_DEF_AVP(366,0,"Accounting-Output-Packets",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED64, NULL) + + return 0; +} + +int sh_dict_def_avp_8xx() +{ + SH_DEF_AVP(824,SH_VND_ID,"SIP-Method",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(825,SH_VND_ID,"Event",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(826,SH_VND_ID,"Content-Type",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(827,SH_VND_ID,"Content-Length",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(828,SH_VND_ID,"Content-Disposition",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(829,SH_VND_ID,"Role-of-Node",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(830,SH_VND_ID,"User-Session-Id",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(831,SH_VND_ID,"Calling-Party-Address",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(832,SH_VND_ID,"Called-Party-Address",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(834, SH_VND_ID, "SIP-Request-Timestamp", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, Time_type) + + SH_DEF_AVP(835, SH_VND_ID, "SIP-Response-Timestamp", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, Time_type) + + SH_DEF_AVP(839,SH_VND_ID,"Originating-IOI",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(840,SH_VND_ID,"Terminating-IOI",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(841,SH_VND_ID,"IMS-Charging-Identifier",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(842,SH_VND_ID,"SDP-Session-Description",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(844,SH_VND_ID,"SDP-Media-Name",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(845,SH_VND_ID,"SDP-Media-Description",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(846, SH_VND_ID, "CG-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(847, SH_VND_ID, "GGSN-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(849,SH_VND_ID,"Authorized-QoS",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(852,SH_VND_ID,"Incoming-Trunk-Group-ID",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(853,SH_VND_ID,"Outgoing-Trunk-Group-Id",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(854,SH_VND_ID,"Bearer-Service",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(862,SH_VND_ID,"Node-Functionality",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + /* fj added 2021.2.24 for OCS CCR witch avp Service-Specific-Info */ + SH_DEF_AVP(863, SH_VND_ID, "Service-Specific-Data", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(866,SH_VND_ID,"PS-Free-Format-Data",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(867,SH_VND_ID,"PS-Append-Free-Format-Data",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(872,SH_VND_ID,"Reporting-Reason",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(881,SH_VND_ID,"Quota-Consumption-Time",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(882,SH_VND_ID,"Media-Initiator-Flag",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(888, SH_VND_ID, "Expires", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + /* fj added 20161221 for OCS SMS start */ + SH_DEF_AVP(897,SH_VND_ID,"Address-Data",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + /* fj added 20161221 for OCS SMS end */ + return 0; +} + +int sh_dict_def_avp_1xxx() +{ + SH_DEF_AVP(1004, SH_VND_ID, "Charging-Rule-Base-Name", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(1020,SH_VND_ID,"Bearer-Identifier",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(1025,SH_VND_ID,"Guaranteed-Bitrate-DL",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(1026,SH_VND_ID,"Guaranteed-Bitrate-UL",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(1027,SH_VND_ID,"IP-CAN-Type",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1028,SH_VND_ID,"QoS-Class-Identifier",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1032,SH_VND_ID,"RAT-Type",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1040,SH_VND_ID,"APN-Aggregate-Max-Bitrate-DL",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1041,SH_VND_ID,"APN-Aggregate-Max-Bitrate-UL",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1046,SH_VND_ID,"Priority-Level",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(1047,SH_VND_ID,"Pre-emption-Capability",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1048,SH_VND_ID,"Pre-emption-Vulnerability",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + /* fj added 20161221 for OCS SMS start */ + SH_DEF_AVP(1200,SH_VND_ID,"Domain-Name",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + /* fj added 20161221 for OCS SMS end */ + + SH_DEF_AVP(1228, SH_VND_ID, "SGSN-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(1251,SH_VND_ID,"Requested-Party-Address",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + /* fj added 2021.2.24 for OCS CCR witch avp Service-Specific-Info */ + SH_DEF_AVP(1257, SH_VND_ID, "Service-Specific-Type", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(1263,SH_VND_ID,"Access-Network-Information",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(1265,SH_VND_ID,"Base-Time-Interval",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(1268,SH_VND_ID,"Envelope-Reporting",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1271,SH_VND_ID,"Time-Quota-Type",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(1288,SH_VND_ID,"Media-Initiator-Party",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(1437,SH_VND_ID,"CSG-Id",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + return 0; +} + +int sh_dict_def_avp_2xxx() +{ + /* fj added 20161221 for OCS SMS start */ + SH_DEF_AVP(2001,SH_VND_ID,"Data-Coding-Scheme",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(2003,SH_VND_ID,"Interface-Id",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2004,SH_VND_ID,"Interface-Port",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2005,SH_VND_ID,"Interface-Text",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2008, SH_VND_ID, "Originator-SCCP-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2010, SH_VND_ID, "Recipient-SCCP-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2012, SH_VND_ID, "SM-Discharge-Time", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, Time_type) + + SH_DEF_AVP(2013,SH_VND_ID,"SM-Protocol-ID",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2014,SH_VND_ID,"SM-Status",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2015,SH_VND_ID,"SM-User-Data-Header",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2017, SH_VND_ID, "SMSC-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2018, SH_VND_ID, "Client-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2019,SH_VND_ID,"Number-Of-Messages-Sent",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2029,SH_VND_ID,"SM-Service-Type",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + /* fj added 20161221 for OCS SMS end */ + + SH_DEF_AVP(2036,SH_VND_ID,"SDP-Type",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(2037,SH_VND_ID,"Change-Condition",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(2038, SH_VND_ID, "Change-Time", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, Time_type) + + SH_DEF_AVP(2039,SH_VND_ID,"Diagnostics",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(2041,SH_VND_ID,"Start-Time",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2042,SH_VND_ID,"Stop-Time",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2047, SH_VND_ID, "Serving-Node-Type", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2050, SH_VND_ID, "PDN-Connection-ID", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2051, SH_VND_ID, "Dynamic-Address-Flag", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2064, SH_VND_ID, "Node-Id", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2065, SH_VND_ID, "SGW-Change", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2066,SH_VND_ID,"Charging-Characteristics-Selection-Mode",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(2067, SH_VND_ID, "SGW-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(2301, SH_VND_ID, "SIP-Request-Timestamp-Fraction", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2302, SH_VND_ID, "SIP-Response-Timestamp-Fraction", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2308, SH_VND_ID, "IMSI-Unauthenticated-Flag", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32, NULL) + + SH_DEF_AVP(2317,SH_VND_ID,"CSG-Access-Mode",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + SH_DEF_AVP(2318,SH_VND_ID,"CSG-Membership-Indication",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY,AVP_TYPE_INTEGER32, NULL) + + return 0; +} + +int sh_dict_def_avp_3xxx() +{ + SH_DEF_AVP(3413, SH_VND_ID, "Teleservice", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(3417, SH_VND_ID, "MSC-Address", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + SH_DEF_AVP(3420, SH_VND_ID, "VLR-Number", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING, UTF8String_type) + + return 0; +} + +int sh_dict_def_avp_9xxx() +{ + SH_DEF_AVP(9010, 5535, "3GPP2-BSID", AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING, UTF8String_type) + + return 0; +} + +int sh_dict_def_avp_2xxxx() +{ + SH_DEF_AVP(20820,2011,"huawei_avp_20820",AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR,AVP_TYPE_INTEGER32, NULL) + + return 0; +} + + +int sh_dict_def_avp_group_823() +{ + /* Event-Type AVP */ + /* + :: = + [ SIP-Method ] + [ Event ] + [ Expires ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 823, /* Code */ + SH_VND_ID, /* Vendor */ + "Event-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "SIP-Method", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Event", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Expires", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_833() +{ + /* Event-Type AVP */ + /* + Time-Stamps ::= < AVP Header: 833 > + [ SIP-Request-Timestamp ] + [ SIP-Response-Timestamp ] + [ SIP-Request-Timestamp-Fraction ] + [ SIP-Response-Timestamp-Fraction ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 833, /* Code */ + SH_VND_ID, /* Vendor */ + "Time-Stamps", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "SIP-Request-Timestamp", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SIP-Response-Timestamp", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SIP-Request-Timestamp-Fraction", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SIP-Response-Timestamp-Fraction", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_838() +{ + /* Inter-Operator-Identifier AVP */ + /* + [ Originating-IOI ] + [ Terminating-IOI ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 838, /* Code */ + SH_VND_ID, /* Vendor */ + "Inter-Operator-Identifier", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Originating-IOI", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Terminating-IOI", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_843() +{ + /* SDP-Media-Component AVP */ + /* + [ SDP-Media-Name ] + * [ SDP-Media-Description ] + [ Media-Initiator-Flag ] + [ Media-Initiator-Party ] + [ Authorized-QoS ] + [ 3GPP-Charging-Id ] + [ Access-Network-Charging-Identifier-Value ] + [ SDP-Type ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 843, /* Code */ + SH_VND_ID, /* Vendor */ + "SDP-Media-Component", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "SDP-Media-Name", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SDP-Media-Description", SH_VND_ID, RULE_REQUIRED, -1, -1 } + ,{ "Media-Initiator-Flag", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Media-Initiator-Party", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Authorized-QoS", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "3GPP-Charging-Id", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Access-Network-Charging-Identifier-Value", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SDP-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_851() +{ + /* PS-Furnish-Charging-Information AVP */ + /* + Trunk-Group-ID :: = + [ Incoming-Trunk-Group-ID ] + [ Outgoing-Trunk-Group-ID ] + + */ + struct dict_object * avp; + struct dict_avp_data data = { + 851, /* Code */ + SH_VND_ID, /* Vendor */ + "Trunk-Group-ID", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Incoming-Trunk-Group-ID", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Outgoing-Trunk-Group-ID", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_865() +{ + /* PS-Furnish-Charging-Information AVP */ + /* + ::= < AVP Header: 865 > + { PS-Free-Format-Data } 866/10415 OctetString 3H + [ PS-Append-Free-Format-Data ] 867/10415 Enumerated SH + + */ + struct dict_object * avp; + struct dict_avp_data data = { + 865, /* Code */ + SH_VND_ID, /* Vendor */ + "PS-Furnish-Charging-Information", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "PS-Free-Format-Data", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "PS-Append-Free-Format-Data", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_889() +{ + /* Message-Body AVP */ + /* + ::= < AVP Header: 889 > + { Content-Type } + { Content-Length } + [ Content-Disposition + */ + struct dict_object * avp; + struct dict_avp_data data = { + 889, /* Code */ + SH_VND_ID, /* Vendor */ + "Message-Body", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Content-Type", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Content-Length", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Content-Disposition", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_898() +{ + /* Address-Domain AVP */ + /* + Address-Domain :: = < AVP Header: 898 > + [ Domain-Name ] + [ 3GPP-IMSI-MCC-MNC ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 898, /* Code */ + SH_VND_ID, /* Vendor */ + "Address-Domain", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Domain-Name", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "3GPP-IMSI-MCC-MNC", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_899() +{ + /* Address-Type AVP */ + struct dict_avp_data data = { + 899, /* Code */ + SH_VND_ID, /* Vendor */ + "Address-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Address-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "e-mail address", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "MSISDN", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "IPv4 Address", { .u32 = 2 }}; + struct dict_enumval_data t_3 = { "IPv6 Address", { .u32 = 3 }}; + struct dict_enumval_data t_4 = { "Numeric Shortcode", { .u32 = 4 }}; + struct dict_enumval_data t_5 = { "Alphanumeric Shortcode", { .u32 = 5 }}; + struct dict_enumval_data t_6 = { "Other", { .u32 = 6 }}; + struct dict_enumval_data t_7 = { "IMSI", { .u32 = 7 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_5 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_6 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_7 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} + +int sh_dict_def_avp_group_1034() +{ + /* Allocation-Retention-Priority AVP */ + /* + ::= < AVP Header: 1034 > + { Priority-Level } 1046/10415 Unsigned32 SH + [ Pre-emption-Capability ] 1047/10415 Enumerated SH + [ Pre-emption-Vulnerability ] 1048/10415 Enumerated SH + */ + struct dict_object * avp; + struct dict_avp_data data = { + 1034, /* Code */ + SH_VND_ID, /* Vendor */ + "Allocation-Retention-Priority", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Priority-Level", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Pre-emption-Capability", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Pre-emption-Vulnerability", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_1201() +{ + /* Recipient-Address AVP */ + /* + Recipient-Address :: = < AVP Header: 1201 > + [ Address-Type ] + [ Address-Data ] + [ Address-Domain ] + [ Addressee-Type ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 1201, /* Code */ + SH_VND_ID, /* Vendor */ + "Recipient-Address", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Address-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Address-Data", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "RAddress-Domain", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Addressee-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_1208() +{ + /* Addressee-Type AVP */ + struct dict_avp_data data = { + 1208, /* Code */ + SH_VND_ID, /* Vendor */ + "Addressee-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Addressee-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "UTO", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "CC", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "BCC", { .u32 = 2 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} + +int sh_dict_def_avp_group_1249(void) +{ + /* Service-Specific-Info AVP */ + /* + Service-Specific-Info ::= < AVP Header: 1249 > + [ Service-Specific-Data ] + [ Service-Specific-Type ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 1249, /* Code */ + SH_VND_ID, /* Vendor */ + "Service-Specific-Info", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Service-Specific-Data", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Service-Specific-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_1270() +{ + /* Time-Quota-Mechanism AVP */ + /* + ::= < AVP Header: 1270 > + { Time-Quota-Type } 1271/10415 Enumerated SH + { Base-Time-Interval } 1265/10415 Unsigned32 SH + */ + struct dict_object * avp; + struct dict_avp_data data = { + 1270, /* Code */ + SH_VND_ID, /* Vendor */ + "Time-Quota-Mechanism", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Time-Quota-Type", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Base-Time-Interval", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_1278() +{ + /* Offline-Charging AVP */ + /* + ::= < AVP Header: 1278 > + [ Quota-Consumption-Time ] 881/10415 Unsigned32 SH + [ Time-Quota-Mechanism ] 1270/10415 + { Time-Quota-Type } 1271/10415 Enumerated SH + { Base-Time-Interval } 1265/10415 Unsigned32 SH + [ Envelope-Reporting ] 1268/10415 Enumerated SH + * [ Multiple-Services-Credit-Control ] + [ Granted-Service-Unit ]XXXXXXXXXXXXXXXXXXXXXXXXXXXX + [ Requested-Service-Unit ]XXXXXXXXXXXXXXXXXXXXXXXXXX + * [ Used-Service-Unit ] + [ Tariff-Change-Usage ]XXXXXXXXXXXXXXXXXXXXXXXXXXXXX + * [ Service-Identifier ] + [ Rating-Group ] + * [ G-S-U-Pool-Reference ] + [ Validity-Time ] + [ Result-Code ] + [ Final-Unit-Indication ] + [ Time-Quota-Threshold ] + [ Volume-Quota-Threshold ] + [ Unit-Quota-Threshold ] + [ Quota-Holding-Time ] + [ Quota-Consumption-Time ] + * [ Reporting-Reason ] + [ Trigger ] + [ PS-Furnish-Charging-Information ] + [ Refund-Information ] + * [ AVP ]XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + */ + struct dict_object * avp; + struct dict_avp_data data = { + 1278, /* Code */ + SH_VND_ID, /* Vendor */ + "Offline-Charging", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Quota-Consumption-Time", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Time-Quota-Mechanism", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Envelope-Reporting", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_2000() +{ + /* SMS-Information AVP */ + /* + SMS-Information :: = < AVP Header: 2000> + [ SMS-Node ] + [ Client-Address ] + [ Originator-SCCP-Address ] + [ SMSC-Address ] + [ Data-Coding-Scheme ] + [ SM-Discharge-Time ] + [ SM-Message-Type ] + [ Originator-Interface ] + [ SM-Protocol-ID ] + [ Reply-Path-Requested ] + [ SM-Status ] + [ SM-User-Data-Header ] + [ Number-Of-Messages-Sent ] + * [ Recipient-Info ] + [ Originator-Received-Address ] + [ SM-Service-Type ] + + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2000, /* Code */ + SH_VND_ID, /* Vendor */ + "SMS-Information", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "SMS-Node", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Client-Address", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Originator-SCCP-Address", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SMSC-Address", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Data-Coding-Scheme", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SM-Discharge-Time", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SM-Message-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Originator-Interface", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SM-Protocol-ID", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Reply-Path-Requested", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SM-Status", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SM-User-Data-Header", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Number-Of-Messages-Sent", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Recipient-Info", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Originator-Received-Address", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SM-Service-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_2002() +{ + /* Destination-Interface AVP */ + /* + Destination-Interface ::= < AVP Header: 2002 > + [ Interface-Id ] + [ Interface-Text ] + [ Interface-Port ] + [ Interface-Type ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2002, /* Code */ + SH_VND_ID, /* Vendor */ + "Destination-Interface", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Interface-Id", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Interface-Text", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Interface-Port", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Interface-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_2006() +{ + /* Interface-Type AVP */ + struct dict_avp_data data = { + 2012, /* Code */ + SH_VND_ID, /* Vendor */ + "Interface-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Interface-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "Unknown", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "MOBILE_ORIGINATING", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "MOBILE_TERMINATING", { .u32 = 2 }}; + struct dict_enumval_data t_3 = { "APPLICATION_ORIGINATING", { .u32 = 3 }}; + struct dict_enumval_data t_4 = { "MAPPLICATION_TERMINATION", { .u32 = 4 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} + +int sh_dict_def_avp_group_2009() +{ + /* Originator-Interface AVP */ + /* + Originator-Interface ::= < AVP Header: 2009 > + [ Interface-Id ] + [ Interface-Text ] + [ Interface-Port ] + [ Interface-Type ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2009, /* Code */ + SH_VND_ID, /* Vendor */ + "Originator-Interface", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Interface-Id", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Interface-Text", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Interface-Port", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Interface-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_2011() +{ + /* Reply-Path-Requested AVP */ + struct dict_avp_data data = { + 2011, /* Code */ + SH_VND_ID, /* Vendor */ + "Reply-Path-Requested", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Reply-Path-Requested", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "No Reply Path Set", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "Reply path Set", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} +int sh_dict_def_avp_group_2026() +{ + /* ORecipient-Info AVP */ + /* + Recipient-Info :: = < AVP Header: 2026 > + [ Destination-Interface ] + * [ Recipient-Address ] + * [ Recipient-Received-Address ] + [ Recipient-SCCP-Address ] + [ SM-Protocol-ID ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2026, /* Code */ + SH_VND_ID, /* Vendor */ + "Recipient-Info", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Destination-Interface", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Recipient-Address", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Recipient-Received-Address", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Recipient-SCCP-Address", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "SM-Protocol-ID", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_2027() +{ + /* Originator-Received-Address AVP */ + /* + Originator-Received-Address :: = < AVP Header: 2027> + [ Address-Type ] + [ Address-Data ] + [ Address-Domain ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2027, /* Code */ + SH_VND_ID, /* Vendor */ + "Originator-Received-Address", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Address-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Address-Data", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Address-Domain", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_2028() +{ + /* Recipient-Received-Address AVP */ + /* + Recipient-Received-Address :: = < AVP Header: 2028> + [ Address-Type ] + [ Address-Data ] + [ Address-Domain ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2028, /* Code */ + SH_VND_ID, /* Vendor */ + "Recipient-Received-Address", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Address-Type", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Address-Data", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Address-Domain", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + +int sh_dict_def_avp_group_2046() +{ + /* Traffic-Data-Volumes AVP */ + /* + + [ QoS-Information ] 1016/10415 + [ QoS-Class-Identifier ] 1028/10415 Enumerated SH + [ Max-Requested-Bandwidth-UL ] 516/10415 Unsigned32 SH + [ Max-Requested-Bandwidth-DL ] 515/10415 Unsigned32 SH + [ Guaranteed-Bitrate-UL ] 1026/10415 Unsigned32 SH + [ Guaranteed-Bitrate-DL ] 1025/10415 Unsigned32 SH + [ Bearer-Identifier ] 1020/10415 OctetString SH + [ Allocation-Retention-Priority ] 1034/10415 + { Priority-Level } 1046/10415 Unsigned32 SH + [ Pre-emption-Capability ] 1047/10415 Enumerated SH + [ Pre-emption-Vulnerability ] 1048/10415 Enumerated SH + [ APN-Aggregate-Max-Bitrate-UL ] 1041/10415 Enumerated SH + [ APN-Aggregate-Max-Bitrate-DL ] 1040/10415 Enumerated SH + *[ Conditional-APN-Aggregate-Max-Bitrate ] 2818/10415 + [ APN-Aggregate-Max-Bitrate-UL ] 1041/10415 Unsigned32 SH + [ APN-Aggregate-Max-Bitrate-DL ] 1040/10415 Unsigned32 SH + *[ IP-CAN-Type ] 1027/10415 Enumerated SH + *[ RAT-Type ] 1032/10415 Enumerated SH + *[ AVP ] + *[ AVP ] + [ Accounting-Input-Octets ] 363/ Unsigned64 + [ Accounting-Input-Packets ] 365/ Unsigned64 + [ Accounting-Output-Octets ] 364/ Unsigned64 + [ Accounting-Output-Packets ] 366/ Unsigned64 + [ Change-condition ] 2037/10415 Signed32 SH + [ Change-Time ] 2038/10415 Time SH + [ 3GPP-User-Location-Info ] 22/ OctetString + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2046, /* Code */ + SH_VND_ID, /* Vendor */ + "Traffic-Data-Volumes", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "QoS-Information", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Input-Octets", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Input-Packets", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Output-Octets", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Output-Packets", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Change-Condition", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Change-Time", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "3GPP-User-Location-Info", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_2012() +{ + /* SM-Message-Type AVP */ + struct dict_avp_data data = { + 2012, /* Code */ + SH_VND_ID, /* Vendor */ + "SM-Message-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "SM-Message-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "SUBMISSION", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "DELIVERY_REPORT", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "SM Service Request", { .u32 = 2 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} + +int sh_dict_def_avp_group_2139() +{ + /* User-CSG-Information AVP */ + /* + ::= < AVP Header: 2139 > + { CSG-Id } 1437/10415 Unsigned32 SH + { CSG-Access-Mode } 2317/10415 Enumerated SH + [ CSG-Membership-Indication ] 2318/10415 Enumerated SH + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2319, /* Code */ + SH_VND_ID, /* Vendor */ + "User-CSG-Information", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "CSG-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "CSG-Access-Mode", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "CSG-Membership-Indication", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_2016() +{ + /* SMS-Node AVP */ + struct dict_avp_data data = { + 2016, /* Code */ + SH_VND_ID, /* Vendor */ + "SMS-Node", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "SMS-Node", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "SMS Router", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "IP-SM-GW", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "SMS Router and IP-SM-GW", { .u32 = 2 }}; + struct dict_enumval_data t_3 = { "SMS-SC", { .u32 = 3 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + + return 0; +} + +int sh_dict_def_avp_group_2818() +{ + /* Conditional-APN-Aggregate-Max-Bitrate AVP */ + /* + ::= < AVP Header: 2818 > + [ APN-Aggregate-Max-Bitrate-UL ] 1041/10415 Unsigned32 SH + [ APN-Aggregate-Max-Bitrate-DL ] 1040/10415 Unsigned32 SH + *[ IP-CAN-Type ] 1027/10415 Enumerated SH + *[ RAT-Type ] 1032/10415 Enumerated SH + *[ AVP ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 2818, /* Code */ + SH_VND_ID, /* Vendor */ + "Conditional-APN-Aggregate-Max-Bitrate", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "APN-Aggregate-Max-Bitrate-UL", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "APN-Aggregate-Max-Bitrate-DL", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "IP-CAN-Type", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "RAT-Type", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_3410() +{ + /* VCS-Information AVP */ + /* + VCS-Information :: = < AVP Header: 3410> + [ Bearer-Capability ] + [ Network-Call-Reference-Number ] + [ MSC-Address ] + [ Basic-Service-Code ] + [ ISUP-Location-Number ] + [ VLR-Number ] + [ Forwarding-Pending ] + [ ISUP-Release-Cause ] + [ Start-Time ] + [ Start-of-Charging ] + [ Stop-Time ] + [ PS-Free-Format-Data ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 3410, /* Code */ + SH_VND_ID, /* Vendor */ + "VCS-Information", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "MSC-Address", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Basic-Service-Code", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "VLR-Number", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} +int sh_dict_def_avp_group_3411() +{ + /* Basic-Service-Code AVP */ + /* + Basic-Service-Code:: = < AVP Header: 3411 > + [ Bearer-Service ] + [ Teleservice ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 3411, /* Code */ + SH_VND_ID, /* Vendor */ + "Basic-Service-Code", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Bearer-Service", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Teleservice", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + return 0; +} + + +int sh_dict_init(char * conffile) +{ + /* Applications section */ + /* Create the vendors */ + { + struct dict_vendor_data vendor_data = { SH_VND_ID, "sh_vnd_id" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &sh_vendor)); + } + { + struct dict_vendor_data vendor_data = { HW_VND_ID, "hw_vnd_id" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &hw_vendor)); + } + + { + struct dict_vendor_data vendor_data = { 5535, "5535" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &uname_vendor_5535)); + } + { + struct dict_vendor_data vendor_data = { 12645, "12645" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &uname_vendor_12645)); + } + { + struct dict_vendor_data vendor_data = { 3199, "3199" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &uname_vendor_3199)); + } + { + struct dict_vendor_data vendor_data = { 35, "35" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &uname_vendor_35)); + } + { + struct dict_vendor_data vendor_data = { 11, "11" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &uname_vendor_11)); + } + +/* + { + struct dict_vendor_data vendor_data = { 0, "Vendor0" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &ven1_vendor)); + } +*/ + /* Create the application */ + { + struct dict_application_data data = { SH_APP_ID_OLD, "Gy/Ro Application" }; + CHECK_dict_new( DICT_APPLICATION, &data , NULL/*sh_vendor*/, &sh_appli); + } + + assert( 0 == sh_dict_def_avp() ); + sh_dict_def_avp_group_628(); + sh_dict_def_avp_group_700(); + sh_dict_def_avp_group_703(); + sh_dict_def_avp_group_708(); + sh_dict_def_avp_group_706(); + sh_dict_def_avp_group_707(); + sh_dict_def_avp_group_650(); + sh_dict_def_avp_group_714(); + sh_dict_def_avp_group_717(); + sh_dict_def_avp_group_718(); + sh_dict_def_avp_group_720(); + sh_dict_def_avp_group_621(); + sh_dict_def_avp_group_623();sh_dict_def_avp_group_626();sh_dict_def_avp_group_625(); + sh_dict_def_avp_group_723(); + sh_dict_def_avp_group_715(); + + assert( 0 == sh_dict_def_cmd_udr() ); + assert( 0 == sh_dict_def_cmd_uda() ); + assert( 0 == sh_dict_def_cmd_pur() ); + assert( 0 == sh_dict_def_cmd_pua() ); + + /* fj added 20160803 for CCR&CCA */ + assert( 0 == sh_dict_def_avp_3x() ); + assert( 0 == sh_dict_def_avp_3xx() ); + assert( 0 == sh_dict_def_avp_8xx() ); + assert( 0 == sh_dict_def_avp_1xxx() ); + assert( 0 == sh_dict_def_avp_2xxx() ); + assert( 0 == sh_dict_def_avp_9xxx() ); + assert( 0 == sh_dict_def_avp_2xxxx() ); + sh_dict_def_avp_group_823(); + sh_dict_def_avp_group_833(); + sh_dict_def_avp_group_838(); + sh_dict_def_avp_group_843(); + sh_dict_def_avp_group_851(); + sh_dict_def_avp_group_865(); + sh_dict_def_avp_group_889(); + sh_dict_def_avp_group_1034(); + sh_dict_def_avp_group_1270(); + sh_dict_def_avp_group_1278(); + /* fj added 20161221 for OCS SMS start */ + sh_dict_def_avp_group_2028(); + sh_dict_def_avp_group_1208(); + sh_dict_def_avp_group_898(); + sh_dict_def_avp_group_899(); + sh_dict_def_avp_group_2027(); + sh_dict_def_avp_group_1201(); + sh_dict_def_avp_group_2006(); + sh_dict_def_avp_group_2002(); + sh_dict_def_avp_group_2026(); + sh_dict_def_avp_group_2011(); + sh_dict_def_avp_group_2009(); + sh_dict_def_avp_group_2012(); + sh_dict_def_avp_group_2016(); + sh_dict_def_avp_group_2000(); + /* fj added 20161221 for OCS SMS end */ + + sh_dict_def_avp_group_2046(); + sh_dict_def_avp_group_2818(); + sh_dict_def_avp_group_2139(); + + /* fj added 2021.2.24 for OCS CCR witch avp Service-Specific-Info */ + sh_dict_def_avp_group_1249(); + sh_dict_def_avp_group_1270(); + sh_dict_def_avp_group_1278(); + + /* fj added 20170218 for RRC.VCS-Information */ + sh_dict_def_avp_3xxx(); + sh_dict_def_avp_group_3411(); + sh_dict_def_avp_group_3410(); + + LOG_D( "Extension 'Dictionary definitions for 3GPP29.229&...' initialized"); + return 0; +} +#if 0 +int sh_dict_init_bak(char * conffile) +{ + /* Applications section */ + /* Create the vendors */ + { + struct dict_vendor_data vendor_data = { SH_VND_ID, "sh_vnd_id" }; + CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, &sh_vendor)); + } + #if 1 + /* Create the application */ + { + struct dict_application_data data = { SH_APP_ID, "Sh Interface between AS and HSS Application" }; + CHECK_dict_new( DICT_APPLICATION, &data , NULL/*sh_vendor*/, &sh_appli); + } + #endif + + /* AVP section */ + { + struct dict_object * UTF8String_type; + struct dict_object * DiameterIdentity_type; + struct dict_object * DiameterURI_type; + struct dict_object * Time_type; + + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type); + + /* base diameter avp. redefine of different vendor id */ + { + /* User-Name */ + { + /* + The User-Name AVP (AVP Code 1) [RFC2865] is of type UTF8String, which + contains the User-Name, in a format consistent with the NAI + specification [RFC4282]. + */ + struct dict_avp_data data = { + 1, /* Code */ + SH_VND_ID, /* Vendor */ + "User-Name", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + { + struct dict_avp_data data = { + 263, /* Code */ +#if AC_SESSION_ID != 263 +#error "AC_SESSION_ID definition mismatch" +#endif + SH_VND_ID, /* Vendor */ + "Session-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Origin-Host */ + { + /* + The Origin-Host AVP (AVP Code 264) is of type DiameterIdentity, and + MUST be present in all Diameter messages. This AVP identifies the + endpoint that originated the Diameter message. Relay agents MUST NOT + modify this AVP. + + The value of the Origin-Host AVP is guaranteed to be unique within a + single host. + + Note that the Origin-Host AVP may resolve to more than one address as + the Diameter peer may support more than one address. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 264, /* Code */ + #if AC_ORIGIN_HOST != 264 + #error "AC_ORIGIN_HOST definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Origin-Host", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + /* Origin-Realm */ + { + /* + The Origin-Realm AVP (AVP Code 296) is of type DiameterIdentity. + This AVP contains the Realm of the originator of any Diameter message + and MUST be present in all messages. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 296, /* Code */ + #if AC_ORIGIN_REALM != 296 + #error "AC_ORIGIN_REALM definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Origin-Realm", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Destination-Host */ + { + /* + The Destination-Host AVP (AVP Code 293) is of type DiameterIdentity. + This AVP MUST be present in all unsolicited agent initiated messages, + MAY be present in request messages, and MUST NOT be present in Answer + messages. + + The absence of the Destination-Host AVP will cause a message to be + sent to any Diameter server supporting the application within the + realm specified in Destination-Realm AVP. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 293, /* Code */ + #if AC_DESTINATION_HOST != 293 + #error "AC_DESTINATION_HOST definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Destination-Host", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Destination-Realm */ + { + /* + The Destination-Realm AVP (AVP Code 283) is of type DiameterIdentity, + and contains the realm the message is to be routed to. The + Destination-Realm AVP MUST NOT be present in Answer messages. + Diameter Clients insert the realm portion of the User-Name AVP. + Diameter servers initiating a request message use the value of the + Origin-Realm AVP from a previous message received from the intended + target host (unless it is known a priori). When present, the + Destination-Realm AVP is used to perform message routing decisions. + + Request messages whose ABNF does not list the Destination-Realm AVP + as a mandatory AVP are inherently non-routable messages. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 283, /* Code */ + #if AC_DESTINATION_REALM != 283 + #error "AC_DESTINATION_REALM definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Destination-Realm", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + } + + /* Result-Code */ + { + /* + The Result-Code AVP (AVP Code 268) is of type Unsigned32 and + indicates whether a particular request was completed successfully or + whether an error occurred. All Diameter answer messages defined in + IETF applications MUST include one Result-Code AVP. A non-successful + Result-Code AVP (one containing a non 2xxx value other than + DIAMETER_REDIRECT_INDICATION) MUST include the Error-Reporting-Host + AVP if the host setting the Result-Code AVP is different from the + identity encoded in the Origin-Host AVP. + + The Result-Code data field contains an IANA-managed 32-bit address + space representing errors (see Section 11.4). Diameter provides the + following classes of errors, all identified by the thousands digit in + the decimal notation: + + o 1xxx (Informational) + + o 2xxx (Success) + + o 3xxx (Protocol Errors) + + o 4xxx (Transient Failures) + + o 5xxx (Permanent Failure) + + A non-recognized class (one whose first digit is not defined in this + section) MUST be handled as a permanent failure. + */ + + /* Although the RFC does not specify an "Enumerated" type here, we go forward and create one. + * This is the reason for the "*" in the type name + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Result-Code)" , NULL, NULL, NULL }; + struct dict_avp_data data = { + 268, /* Code */ + #if AC_RESULT_CODE != 268 + #error "AC_RESULT_CODE definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Result-Code", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + + /* Informational */ + { + /* 1001 */ + { + /* + This informational error is returned by a Diameter server to + inform the access device that the authentication mechanism being + used requires multiple round trips, and a subsequent request needs + to be issued in order for access to be granted. + */ + struct dict_enumval_data error_code = { "DIAMETER_MULTI_ROUND_AUTH", { .u32 = ER_DIAMETER_MULTI_ROUND_AUTH }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Success */ + { + /* 2001 */ + { + /* + The Request was successfully completed. + */ + struct dict_enumval_data error_code = { "DIAMETER_SUCCESS", { .u32 = ER_DIAMETER_SUCCESS }}; + #if ER_DIAMETER_SUCCESS != 2001 + #error "ER_DIAMETER_SUCCESS definition mismatch" + #endif + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 2002 */ + { + /* + When returned, the request was successfully completed, but + additional processing is required by the application in order to + provide service to the user. + */ + struct dict_enumval_data error_code = { "DIAMETER_LIMITED_SUCCESS", { .u32 = ER_DIAMETER_LIMITED_SUCCESS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Protocol Errors */ + { + /* 3001 -- might be changed to 5xxx soon */ + { + /* + The Request contained a Command-Code that the receiver did not + recognize or support. This MUST be used when a Diameter node + receives an experimental command that it does not understand. + */ + struct dict_enumval_data error_code = { "DIAMETER_COMMAND_UNSUPPORTED", { .u32 = ER_DIAMETER_COMMAND_UNSUPPORTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3002 */ + { + /* + This error is given when Diameter can not deliver the message to + the destination, either because no host within the realm + supporting the required application was available to process the + request, or because Destination-Host AVP was given without the + associated Destination-Realm AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNABLE_TO_DELIVER", { .u32 = ER_DIAMETER_UNABLE_TO_DELIVER }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3003 */ + { + /* + The intended realm of the request is not recognized. + */ + struct dict_enumval_data error_code = { "DIAMETER_REALM_NOT_SERVED", { .u32 = ER_DIAMETER_REALM_NOT_SERVED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3004 */ + { + /* + When returned, a Diameter node SHOULD attempt to send the message + to an alternate peer. This error MUST only be used when a + specific server is requested, and it cannot provide the requested + service. + */ + struct dict_enumval_data error_code = { "DIAMETER_TOO_BUSY", { .u32 = ER_DIAMETER_TOO_BUSY }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3005 */ + { + /* + An agent detected a loop while trying to get the message to the + intended recipient. The message MAY be sent to an alternate peer, + if one is available, but the peer reporting the error has + identified a configuration problem. + */ + struct dict_enumval_data error_code = { "DIAMETER_LOOP_DETECTED", { .u32 = ER_DIAMETER_LOOP_DETECTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3006 */ + { + /* + A redirect agent has determined that the request could not be + satisfied locally and the initiator of the request should direct + the request directly to the server, whose contact information has + been added to the response. When set, the Redirect-Host AVP MUST + be present. + */ + struct dict_enumval_data error_code = { "DIAMETER_REDIRECT_INDICATION", { .u32 = ER_DIAMETER_REDIRECT_INDICATION }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3007 */ + { + /* + A request was sent for an application that is not supported. + */ + struct dict_enumval_data error_code = { "DIAMETER_APPLICATION_UNSUPPORTED", { .u32 = ER_DIAMETER_APPLICATION_UNSUPPORTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3008 -- will change to 5xxx soon */ + { + /* + A request was received whose bits in the Diameter header were + either set to an invalid combination, or to a value that is + inconsistent with the command code's definition. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_HDR_BITS", { .u32 = ER_DIAMETER_INVALID_HDR_BITS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3009 -- will change to 5xxx soon */ + { + /* + A request was received that included an AVP whose flag bits are + set to an unrecognized value, or that is inconsistent with the + AVP's definition. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_BITS", { .u32 = ER_DIAMETER_INVALID_AVP_BITS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3010 -- will change to 5xxx soon */ + { + /* + A CER was received from an unknown peer. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNKNOWN_PEER", { .u32 = ER_DIAMETER_UNKNOWN_PEER }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Transient Failures */ + { + /* 4001 */ + { + /* + The authentication process for the user failed, most likely due to + an invalid password used by the user. Further attempts MUST only + be tried after prompting the user for a new password. + */ + struct dict_enumval_data error_code = { "DIAMETER_AUTHENTICATION_REJECTED", { .u32 = ER_DIAMETER_AUTHENTICATION_REJECTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 4002 */ + { + /* + A Diameter node received the accounting request but was unable to + commit it to stable storage due to a temporary lack of space. + */ + struct dict_enumval_data error_code = { "DIAMETER_OUT_OF_SPACE", { .u32 = ER_DIAMETER_OUT_OF_SPACE }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 4003 */ + { + /* + The peer has determined that it has lost the election process and + has therefore disconnected the transport connection. + */ + struct dict_enumval_data error_code = { "ELECTION_LOST", { .u32 = ER_ELECTION_LOST }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Permanent Failures */ + { + /* 5001 */ + { + /* + The peer received a message that contained an AVP that is not + recognized or supported and was marked with the Mandatory bit. A + Diameter message with this error MUST contain one or more Failed- + AVP AVP containing the AVPs that caused the failure. + */ + struct dict_enumval_data error_code = { "DIAMETER_AVP_UNSUPPORTED", { .u32 = ER_DIAMETER_AVP_UNSUPPORTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5002 */ + { + /* + The request contained an unknown Session-Id. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNKNOWN_SESSION_ID", { .u32 = ER_DIAMETER_UNKNOWN_SESSION_ID }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5003 */ + { + /* + A request was received for which the user could not be authorized. + This error could occur if the service requested is not permitted + to the user. + */ + struct dict_enumval_data error_code = { "DIAMETER_AUTHORIZATION_REJECTED",{ .u32 = ER_DIAMETER_AUTHORIZATION_REJECTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5004 */ + { + /* + The request contained an AVP with an invalid value in its data + portion. A Diameter message indicating this error MUST include + the offending AVPs within a Failed-AVP AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_VALUE", { .u32 = ER_DIAMETER_INVALID_AVP_VALUE }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5005 */ + { + /* + The request did not contain an AVP that is required by the Command + Code definition. If this value is sent in the Result-Code AVP, a + Failed-AVP AVP SHOULD be included in the message. The Failed-AVP + AVP MUST contain an example of the missing AVP complete with the + Vendor-Id if applicable. The value field of the missing AVP + should be of correct minimum length and contain zeroes. + */ + struct dict_enumval_data error_code = { "DIAMETER_MISSING_AVP", { .u32 = ER_DIAMETER_MISSING_AVP }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5006 */ + { + /* + A request was received that cannot be authorized because the user + has already expended allowed resources. An example of this error + condition is a user that is restricted to one dial-up PPP port, + attempts to establish a second PPP connection. + */ + struct dict_enumval_data error_code = { "DIAMETER_RESOURCES_EXCEEDED", { .u32 = ER_DIAMETER_RESOURCES_EXCEEDED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5007 */ + { + /* + The Home Diameter server has detected AVPs in the request that + contradicted each other, and is not willing to provide service to + the user. The Failed-AVP AVPs MUST be present which contains the + AVPs that contradicted each other. + */ + struct dict_enumval_data error_code = { "DIAMETER_CONTRADICTING_AVPS", { .u32 = ER_DIAMETER_CONTRADICTING_AVPS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5008 */ + { + /* + A message was received with an AVP that MUST NOT be present. The + Failed-AVP AVP MUST be included and contain a copy of the + offending AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_AVP_NOT_ALLOWED", { .u32 = ER_DIAMETER_AVP_NOT_ALLOWED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5009 */ + { + /* + A message was received that included an AVP that appeared more + often than permitted in the message definition. The Failed-AVP + AVP MUST be included and contain a copy of the first instance of + the offending AVP that exceeded the maximum number of occurrences + */ + struct dict_enumval_data error_code = { "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES",{ .u32 = ER_DIAMETER_AVP_OCCURS_TOO_MANY_TIMES }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5010 */ + { + /* + This error is returned by a Diameter node that is not acting as a + relay when it receives a CER which advertises a set of + applications that it does not support. + */ + struct dict_enumval_data error_code = { "DIAMETER_NO_COMMON_APPLICATION",{ .u32 = ER_DIAMETER_NO_COMMON_APPLICATION }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5011 */ + { + /* + This error is returned when a request was received, whose version + number is unsupported. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNSUPPORTED_VERSION", { .u32 = ER_DIAMETER_UNSUPPORTED_VERSION }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5012 */ + { + /* + This error is returned when a request is rejected for unspecified + reasons. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNABLE_TO_COMPLY", { .u32 = ER_DIAMETER_UNABLE_TO_COMPLY }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5013 -- will change to 3xxx */ + { + /* + This error is returned when an unrecognized bit in the Diameter + header is set to one (1). + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_BIT_IN_HEADER", { .u32 = ER_DIAMETER_INVALID_BIT_IN_HEADER }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5014 */ + { + /* + The request contained an AVP with an invalid length. A Diameter + message indicating this error MUST include the offending AVPs + within a Failed-AVP AVP. In cases where the erroneous avp length + value exceeds the message length or is less than the minimum AVP + header length, it is sufficient to include the offending AVP + header and a zero filled payload of the minimum required length + for the payloads data type. If the AVP is a grouped AVP, the + grouped AVP header with an empty payload would be sufficient to + indicate the offending AVP. In the case where the offending AVP + header cannot be fully decoded when avp length is less than the + minimum AVP header length, it is sufficient to include an + offending AVP header that is formulated by padding the incomplete + AVP header with zero up to the minimum AVP header length. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_LENGTH", { .u32 = ER_DIAMETER_INVALID_AVP_LENGTH }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5015 -- will change to 3xxx */ + { + /* + This error is returned when a request is received with an invalid + message length. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_MESSAGE_LENGTH", { .u32 = ER_DIAMETER_INVALID_MESSAGE_LENGTH }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5016 */ + { + /* + The request contained an AVP with which is not allowed to have the + given value in the AVP Flags field. A Diameter message indicating + this error MUST include the offending AVPs within a Failed-AVP + AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_BIT_COMBO", { .u32 = ER_DIAMETER_INVALID_AVP_BIT_COMBO }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5017 */ + { + /* + This error is returned when a CER message is received, and there + are no common security mechanisms supported between the peers. A + Capabilities-Exchange-Answer (CEA) MUST be returned with the + Result-Code AVP set to DIAMETER_NO_COMMON_SECURITY. + */ + struct dict_enumval_data error_code = { "DIAMETER_NO_COMMON_SECURITY", { .u32 = ER_DIAMETER_NO_COMMON_SECURITY }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + } + /* Vendor-Id */ + { + /* + The Vendor-Id AVP (AVP Code 266) is of type Unsigned32 and contains + the IANA "SMI Network Management Private Enterprise Codes" [RFC3232] + value assigned to the vendor of the Diameter device. It is + envisioned that the combination of the Vendor-Id, Product-Name + (Section 5.3.7) and the Firmware-Revision (Section 5.3.4) AVPs may + provide useful debugging information. + + A Vendor-Id value of zero in the CER or CEA messages is reserved and + indicates that this field is ignored. + */ + struct dict_avp_data data = { + 266, /* Code */ + #if AC_VENDOR_ID != 266 + #error "AC_VENDOR_ID definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Vendor-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data, NULL, NULL); + } + /* Experimental-Result-Code */ + { + /* + The Experimental-Result-Code AVP (AVP Code 298) is of type Unsigned32 + and contains a vendor-assigned value representing the result of + processing the request. + + It is recommended that vendor-specific result codes follow the same + conventions given for the Result-Code AVP regarding the different + types of result codes and the handling of errors (for non 2xxx + values). + */ + /* Although the RFC does not specify an "Enumerated" type here, we go forward and create one. + * This is the reason for the "*" in the type name. Vendors will have to define their values. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Experimental-Result-Code)" , NULL, NULL, NULL }; + struct dict_avp_data data = { + 298, /* Code */ + SH_VND_ID, /* Vendor */ + "Experimental-Result-Code", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Experimental-Result */ + { + /* + The Experimental-Result AVP (AVP Code 297) is of type Grouped, and + indicates whether a particular vendor-specific request was completed + successfully or whether an error occurred. Its Data field has the + following ABNF grammar: + + AVP Format + + Experimental-Result ::= < AVP Header: 297 > + { Vendor-Id } + { Experimental-Result-Code } + + The Vendor-Id AVP (see Section 5.3.3) in this grouped AVP identifies + the vendor responsible for the assignment of the result code which + follows. All Diameter answer messages defined in vendor-specific + applications MUST include either one Result-Code AVP or one + Experimental-Result AVP. + */ + struct dict_object * avp; + struct dict_avp_data data = { + 297, /* Code */ + SH_VND_ID, /* Vendor */ + "Experimental-Result", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + /* ABNF from RFC6733 */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } +#else /* WORKAROUND_ACCEPT_INVALID_VSAI */ + /* ABNF from RFC3588 (including erratum, because original text is nonsense) */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, -1} +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + ,{ "Experimental-Result-Code", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + /* Create the grouped AVP */ + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + #if 0 + /* Auth-Session-State */ + { + /* + The Auth-Session-State AVP (AVP Code 277) is of type Enumerated and + specifies whether state is maintained for a particular session. The + client MAY include this AVP in requests as a hint to the server, but + the value in the server's answer message is binding. The following + values are supported: + + + STATE_MAINTAINED 0 + + This value is used to specify that session state is being + maintained, and the access device MUST issue a session termination + message when service to the user is terminated. This is the + default value. + + + NO_STATE_MAINTAINED 1 + + This value is used to specify that no session termination messages + will be sent by the access device upon expiration of the + Authorization-Lifetime. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Auth-Session-State)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "STATE_MAINTAINED", { .i32 = 0 }}; + struct dict_enumval_data t_1 = { "NO_STATE_MAINTAINED", { .i32 = 1 }}; + struct dict_avp_data data = { + 277, /* Code */ + SH_VND_ID, /* Vendor */ + "Auth-Session-State", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + #endif + /* + * from 3GPP Dict + */ + /* Server-Name */ + { + struct dict_avp_data data = { + 602, /* Code */ + SH_VND_ID, /* Vendor */ + "Server-Name", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL); + }; + #if 1 + /* Auth-Application-Id */ + { + /* + The Auth-Application-Id AVP (AVP Code 258) is of type Unsigned32 and + is used in order to advertise support of the Authentication and + Authorization portion of an application (see Section 2.4). If + present in a message other than CER and CEA, the value of the Auth- + Application-Id AVP MUST match the Application Id present in the + Diameter message header. + */ + struct dict_avp_data data = { + 258, /* Code */ + #if AC_AUTH_APPLICATION_ID != 258 + #error "AC_AUTH_APPLICATION_ID definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Auth-Application-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + /* Acct-Application-Id */ + { + /* + The Acct-Application-Id AVP (AVP Code 259) is of type Unsigned32 and + is used in order to advertise support of the Accounting portion of an + application (see Section 2.4). If present in a message other than + CER and CEA, the value of the Acct-Application-Id AVP MUST match the + Application Id present in the Diameter message header. + */ + struct dict_avp_data data = { + 259, /* Code */ + #if AC_ACCT_APPLICATION_ID != 259 + #error "AC_ACCT_APPLICATION_ID definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Acct-Application-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + /* Vendor-Specific-Application-Id */ + { + /* + The Vendor-Specific-Application-Id AVP (AVP Code 260) is of type + Grouped and is used to advertise support of a vendor-specific + Diameter Application. Exactly one instance of either Auth- + Application-Id or Acct-Application-Id AVP MUST be present. The + Application Id carried by either Auth-Application-Id or Acct- + Application-Id AVP MUST comply with vendor specific Application Id + assignment described in Sec 11.3. It MUST also match the Application + Id present in the diameter header except when used in a CER or CEA + messages. + + The Vendor-Id AVP is an informational AVP pertaining to the vendor + who may have authorship of the vendor-specific Diameter application. + It MUST NOT be used as a means of defining a completely separate + vendor-specific Application Id space. + + This AVP MUST also be present as the first AVP in all experimental + commands defined in the vendor-specific application. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + + AVP Format + + ::= < AVP Header: 260 > + { Vendor-Id } + [ Auth-Application-Id ] + [ Acct-Application-Id ] + + A Vendor-Specific-Application-Id AVP MUST contain exactly one of + either Auth-Application-Id or Acct-Application-Id. If a Vendor- + Specific-Application-Id is received without any of these two AVPs, + then the recipient SHOULD issue an answer with a Result-Code set to + DIAMETER_MISSING_AVP. The answer SHOULD also include a Failed-AVP + which MUST contain an example of an Auth-Application-Id AVP and an + Acct-Application-Id AVP. + + If a Vendor-Specific-Application-Id is received that contains both + Auth-Application-Id and Acct-Application-Id, then the recipient + SHOULD issue an answer with Result-Code set to + DIAMETER_AVP_OCCURS_TOO_MANY_TIMES. The answer SHOULD also include a + Failed-AVP which MUST contain the received Auth-Application-Id AVP + and Acct-Application-Id AVP. + */ + struct dict_object * avp; + struct dict_avp_data data = { + 260, /* Code */ + #if AC_VENDOR_SPECIFIC_APPLICATION_ID != 260 + #error "AC_VENDOR_SPECIFIC_APPLICATION_ID definition mismatch" + #endif + SH_VND_ID, /* Vendor */ + "Vendor-Specific-Application-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + /* ABNF from RFC6733 */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } +#else /* WORKAROUND_ACCEPT_INVALID_VSAI */ + /* ABNF from RFC3588 (including erratum, because original text is nonsense) */ + { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, -1} +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + ,{ "Auth-Application-Id", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Application-Id", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + /* Create the grouped AVP */ + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + #endif + /* Feature-List-ID */ + { + struct dict_avp_data data = { + 629, /* Code */ + SH_VND_ID, /* Vendor */ + "Feature-List-ID", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + /* Feature-List */ + { + struct dict_avp_data data = { + 630, /* Code */ + SH_VND_ID, /* Vendor */ + "Feature-List", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + /* Supported-Features */ + { + /* + Supported-Features ::= < AVP header: 628 10415 > + { Vendor-Id } + { Feature-List-ID } + { Feature-List } + *[AVP] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 628, /* Code */ + SH_VND_ID, /* Vendor */ + "Supported-Features", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "Vendor-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Feature-List-ID", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Feature-List", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + }; + + /* Supported-Applications */ + { + struct dict_avp_data data = { + 631, /* Code */ + SH_VND_ID, /* Vendor */ + "Supported-Applications", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + /* Public-Identity */ + { + struct dict_avp_data data = { + 601, /* Code */ + SH_VND_ID, /* Vendor */ + "Public-Identity", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL); + }; + /* Wildcarded-Public-Identity */ + { + struct dict_avp_data data = { + 634, /* Code */ + SH_VND_ID, /* Vendor */ + "Wildcarded-Public-Identity", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL); + }; + /* in 29.229 */ + /* Wildcarded-Public-Identity */ + /* Wildcarded-IMPU */ + { + struct dict_avp_data data = { + 636, /* Code */ + SH_VND_ID, /* Vendor */ + "Wildcarded-IMPU", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL); + }; + /* Session-Priority */ + { + struct dict_avp_data data = { + 650, /* Code */ + SH_VND_ID, /* Vendor */ + "Session-Priority", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Priority)", NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "PRIORITY-0", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "PRIORITY-1", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "PRIORITY-2", { .u32 = 2 }}; + struct dict_enumval_data t_3 = { "PRIORITY-3", { .u32 = 3 }}; + struct dict_enumval_data t_4 = { "PRIORITY-4", { .u32 = 4 }}; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + #if 0 + /* Primary-Charging-Collection-Function-Name */ + { + struct dict_avp_data data = { + 621, /* Code */ + SH_VND_ID, /* Vendor */ + "Primary-Charging-Collection-Function-Name", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL); + }; + #endif + /* User-Authorization-Type */ + { + struct dict_avp_data data = { + 623, /* Code */ + 0, /* Vendor */ /* confi with 29.329 */ + "User-Authorization-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "User-Authorization-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "REGISTRATION", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "DE_REGISTRATION", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + /* MSISDN */ + { + struct dict_avp_data data = { + 701, /* Code */ + SH_VND_ID, /* Vendor */ + "MSISDN", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + /* User-Data AVP */ + { + /* + The User-Data AVP is of type OctetString. This AVP contains the user data requested in the UDR/UDA, SNR/SNA + and PNR/PNA operations and the data to be modified in the PUR/PUA operation. The exact content and format of this + AVP is described in 3GPP TS 29.328 [1] Annex C as ta_appli-Data. + */ + struct dict_avp_data data = { + 702, /* Code */ + SH_VND_ID, /* Vendor */ + "User-Data", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + + } + + /* Data-Reference */ + { + struct dict_avp_data data = { + 703, /* Code */ + SH_VND_ID, /* Vendor */ + "Data-Reference", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Data-Reference)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "RepositoryData", { .u32 = 0 }}; + struct dict_enumval_data t_10 = { "IMSPublicIdentity", { .u32 = 10 }}; + struct dict_enumval_data t_11 = { "IMSUserState", { .u32 = 11 }}; + struct dict_enumval_data t_12 = { "S-CSCFName", { .u32 = 12 }}; + struct dict_enumval_data t_13 = { "InitialFilterCriteria", { .u32 = 13 }}; + struct dict_enumval_data t_14 = { "LocationInformation", { .u32 = 14 }}; + struct dict_enumval_data t_15 = { "UserState", { .u32 = 15 }}; + struct dict_enumval_data t_16 = { "ChargingInformation", { .u32 = 16 }}; + struct dict_enumval_data t_17 = { "MSISDN", { .u32 = 17 }}; + struct dict_enumval_data t_18 = { "PSIActivation", { .u32 = 18 }}; + struct dict_enumval_data t_19 = { "DSAI", { .u32 = 19 }}; + struct dict_enumval_data t_21 = { "ServiceLevelTraceInfo", { .u32 = 21 }}; + struct dict_enumval_data t_22 = { "IPAddressSecureBindingInformation", { .u32 = 22 }}; + struct dict_enumval_data t_23 = { "ServicePriorityLevel", { .u32 = 23 }}; + struct dict_enumval_data t_24 = { "SMSRegistrationInfo", { .u32 = 24 }}; + struct dict_enumval_data t_25 = { "UEReachabilityForIP", { .u32 = 25 }}; + struct dict_enumval_data t_26 = { "TADSinformation", { .u32 = 26 }}; + struct dict_enumval_data t_27 = { "STN-SR", { .u32 = 27 }}; + struct dict_enumval_data t_28 = { "UE-SRVCC-Capability", { .u32 = 28 }}; + struct dict_enumval_data t_29 = { "ExtendedPriority", { .u32 = 29 }}; + struct dict_enumval_data t_30 = { "CSRN", { .u32 = 30 }}; + struct dict_enumval_data t_31 = { "ReferenceLocationInformation", { .u32 = 31 }}; + struct dict_enumval_data t_32 = { "IMSI", { .u32 = 32 }}; + struct dict_enumval_data t_33 = { "IMSPrivateUserIdentity", { .u32 = 33 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_10 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_11 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_12 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_13 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_14 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_15 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_16 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_17 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_18 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_19 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_21 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_22 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_23 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_24 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_25 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_26 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_27 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_28 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_29 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_30 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_31 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_32 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_33 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + } + + /* Service-Indication AVP */ + { + /* + The Service-Indication AVP is of type OctetString. This AVP contains the Service Indication that identifies a service or + a set of services in an AS and the related repository data in the HSS. Standardized values of Service-Indication + identifying a standardized service or set of services in the AS and standardized format of the related repository data are + defined in 3GPP TS 29.364 [10]. + */ + struct dict_avp_data data = { + 704, /* Code */ + SH_VND_ID, /* Vendor */ + "Service-Indication", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + } + + + /* Subs-Req-Type AVP */ + { + struct dict_avp_data data = { + 705, /* Code */ + SH_VND_ID, /* Vendor */ + "Subs-Req-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Subs-Req-Type AVP", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "Subscribe", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "Unsubscribe", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* Requested-Domain AVP */ + { + struct dict_avp_data data = { + 706, /* Code */ + SH_VND_ID, /* Vendor */ + "Requested-Domain", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Requested-Domain", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "CS-Domain", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "PS-Domain", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* Current-Location AVP */ + { + struct dict_avp_data data = { + 707, /* Code */ + SH_VND_ID, /* Vendor */ + "Current-Location", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Current-Location", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "DoNotNeedInitiateActiveLocationRetrieval", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "InitiateActiveLocationRetrieval", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* Identity-Set AVP */ + { + struct dict_avp_data data = { + 708, /* Code */ + SH_VND_ID, /* Vendor */ + "Identity-Set", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Identity-Set", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ALL_IDENTITIES", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "REGISTERED_IDENTITIES", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "IMPLICIT_IDENTITIES", { .u32 = 2 }}; + struct dict_enumval_data t_3 = { "ALIAS_IDENTITIES", { .u32 = 3 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* Expiry-Time AVP*/ + { + struct dict_avp_data data = { + 709, /* Code */ + SH_VND_ID, /* Vendor */ + "Expiry-Time", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, Time_type, NULL); + }; + + + /* Send-Data-Indication AVP*/ + { + struct dict_avp_data data = { + 710, /* Code */ + SH_VND_ID, /* Vendor */ + "Send-Data-Indication", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Send-Data-Indication)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "USER_DATA_NOT_REQUESTED", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "USER_DATA_REQUESTED", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* in 29.229 */ + /* Server-Name */ + /* Supported-Features */ + /* Feature-List-ID */ + /* Feature-List */ + /* Supported-Applications */ + /* Public-Identity */ + /* DSAI-Tag */ + { + struct dict_avp_data data = { + 711, /* Code */ + SH_VND_ID, /* Vendor */ + "DSAI-Tag", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + /* in 29.229 */ + /* Session-Priority */ + /* One-Time-Notification AVP*/ + { + struct dict_avp_data data = { + 712, /* Code */ + SH_VND_ID, /* Vendor */ + "One-Time-Notification", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(One-Time-Notification)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ONE_TIME_NOTIFICATION_REQUESTED", { .u32 = 0 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* Requested-Nodes AVP */ + { + struct dict_avp_data data = { + 713, /* Code */ + SH_VND_ID, /* Vendor */ + "Requested-Nodes", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + /* Serving-Node-Indication AVP*/ + { + struct dict_avp_data data = { + 714, /* Code */ + SH_VND_ID, /* Vendor */ + "Serving-Node-Indication", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Serving-Node-Indication)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ONLY_SERVING_NODES_REQUIRED", { .u32 = 0 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* Repository-Data-ID AVP */ + { + /* + The Repository-Data-ID AVP is of type Grouped. This AVP shall contain a Service-Indication AVP and a Sequence- + Number AVP. + AVP format + Repository-Data-ID ::= + {Service-Indication} + {Sequence-Number} + *[AVP] + */ + struct dict_avp_data data = { + 715, /* Code */ + SH_VND_ID, /* Vendor */ + "Repository-Data-ID", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + } + + /* Sequence-Number AVP*/ + { + struct dict_avp_data data = { + 716, /* Code */ + SH_VND_ID, /* Vendor */ + "Sequence-Number", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + + /* Pre-paging-Supported AVP */ + { + struct dict_avp_data data = { + 717, /* Code */ + SH_VND_ID, /* Vendor */ + "Pre-paging-Supported", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Pre-paging-Supported)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "PREPAGING_NOT_SUPPORTED", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "PREPAGING_SUPPORTED", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* Local-Time-Zone-Indication AVP */ + { + struct dict_avp_data data = { + 718, /* Code */ + SH_VND_ID, /* Vendor */ + "Local-Time-Zone-Indication", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Local-Time-Zone-Indication)", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "ONLY_LOCAL_TIME_ZONE_REQUESTED", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "LOCAL_TIME_ZONE_WITH_LOCATION_INFO_REQUESTED", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* UDR-Flags */ + { + struct dict_avp_data data = { + 719, /* Code */ + SH_VND_ID, /* Vendor */ + "UDR-Flags", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + /* Call-Reference-Number AVP */ + { + struct dict_avp_data data = { + 721, /* Code */ + SH_VND_ID, /* Vendor */ + "Call-Reference-Number", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + /* AS-Number AVP */ + { + struct dict_avp_data data = { + 722, /* Code */ + SH_VND_ID, /* Vendor */ + "AS-Number", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + /* Call-Reference-Info AVP */ + { + /* + The Call-Reference-Info AVP is of type Grouped. This AVP shall contain a Call-Reference-Number AVP and an ASNumber + AVP. + AVP format + Call-Reference-Info ::= + {Call-Reference-Number} + {AS-Number} + *[AVP] + + */ + struct dict_object * avp; + struct dict_avp_data data = { + 720, /* Code */ + SH_VND_ID, /* Vendor */ + "Call-Reference-Info", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "Call-Reference-Number", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "AS-Number}", SH_VND_ID, RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + + + + /* OC-Feature-Vector AVP */ + { + struct dict_avp_data data = { + 622, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Feature-Vector", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + + #if 1 + /* OC-Supported-Features AVP */ + { + /* + The OC-Supported-Features AVP (AVP Code 621) is of type Grouped and + serves two purposes. First, it announces a node's support for the + DOIC solution in general. Second, it contains the description of the + supported DOIC features of the sending node. The OC-Supported- + Features AVP MUST be included in every Diameter request message a + DOIC supporting node sends. + + OC-Supported-Features ::= < AVP Header: 621 > + [ OC-Feature-Vector ] + * [ AVP ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 621, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Supported-Features", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "OC-Feature-Vector", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + #endif + + /* OC-Sequence-Number AVP*/ + { + /* + The OC-Sequence-Number AVP (AVP Code 624) is of type Unsigned64. Its + usage in the context of overload control is described in Section 5.2. + + From the functionality point of view, the OC-Sequence-Number AVP is + used as a nonvolatile increasing counter for a sequence of overload + reports between two DOIC nodes for the same overload occurrence. + Sequence numbers are treated in a unidirectional manner, i.e., two + sequence numbers in each direction between two DOIC nodes are not + related or correlated. + */ + struct dict_avp_data data = { + 624, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Sequence-Number", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + /* OC-Report-Type AVP */ + { + struct dict_avp_data data = { + 626, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Report-Type", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "OC-Report-Type", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + struct dict_enumval_data t_0 = { "HOST_REPORT", { .u32 = 0 }}; + struct dict_enumval_data t_1 = { "REALM_REPORT", { .u32 = 1 }}; + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + /* OC-Reduction-Percentage AVP */ + { + struct dict_avp_data data = { + 627, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Reduction-Percentage", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "OC-Reduction-Percentage", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + /* OC-Validity-Duration AVP */ + { + struct dict_avp_data data = { + 625, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-Validity-Duration", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + struct dict_object *type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "OC-Validity-Duration", NULL, NULL, NULL }; + CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type); + CHECK_dict_new(DICT_AVP, &data, type, NULL); + }; + + #if 1 + /* OC-OLR AVP */ + { + /* + The OC-OLR AVP (AVP Code 623) is of type Grouped and contains the + information necessary to convey an overload report on an overload + condition at the reporting node. The application the OC-OLR AVP + applies to is identified by the Application-ID found in the Diameter + message header. The host or realm the OC-OLR AVP concerns is + determined from the Origin-Host AVP and/or Origin-Realm AVP found in + the encapsulating Diameter command. The OC-OLR AVP is intended to be + sent only by a reporting node. + + OC-OLR ::= < AVP Header: 623 > + < OC-Sequence-Number > + < OC-Report-Type > + [ OC-Reduction-Percentage ] + [ OC-Validity-Duration ] + * [ AVP ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 623, /* Code */ + SH_VND_ID, /* Vendor */ + "OC-OLR", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { { "OC-Sequence-Number", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } /* flag to be make sure */ + ,{ "OC-Report-Type", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } /* flag to be make sure */ + ,{ "OC-Reduction-Percentage", SH_VND_ID, RULE_OPTIONAL, -1, 1 } /* flag to be make sure */ + ,{ "OC-Validity-Duration", SH_VND_ID, RULE_OPTIONAL, -1, 1 } /* flag to be make sure */ + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + } + #endif + + + /* Error: Editor’s Note: The code for DRMP AVP is to be updated when it is available within the draft-ietf-dime-drmp-02 [13]. */ + /* DRMP AVP */ + { + struct dict_avp_data data = { + 723, /* Code */ + SH_VND_ID, /* Vendor */ + "DRMP", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new(DICT_AVP, &data, NULL, NULL); + }; + } + + /* group AVP */ + { + /* + User-Identity ::= + [Public-Identity] + [MSISDN] + *[AVP] + */ + /* User-Identity group */ + struct dict_object * avp = NULL; + struct dict_avp_data data = { + 700, /* Code */ + SH_VND_ID, /* Vendor */ + "User-Identity", /* Name */ + AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "MSISDN", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), avp ); + + } + + + /* Command section */ + { + /* User-Data-Request (UDR) Command */ + { + /* + The User-Data-Request (UDR) command, indicated by the Com + mand-Code field set to 306 and the ‘R?bit set in the + Command Flags field, is sent by a Diameter client to a Diameter server in order to request user data. + Message Format: + + < User-Data -Request> ::= < Diameter Header: 306, REQ, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Destination-Host ] + { Destination-Realm } + *[ Supported-Features ] + { User-Identity } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ Server-Name ] + *[ Service-Indication ] + *{ Data-Reference } + *[ Identity-Set ] + [ Requested-Domain ] + [ Current-Location ] + *[ DSAI-Tag ] + [ Session-Priority ] + [ User-Name ] + [ Requested-Nodes ] + [ Serving-Node-Indication ] + [ Pre-paging-Supported ] + [ Local-Time-Zone-Indication ] + [ UDR-Flags ] + [ Call-Reference-Info ] + [ OC-Supported-Features ] + *[ AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + */ + // struct dict_object * udr_cmd; // cmd; + struct dict_cmd_data data = { + 306, /* Code */ + "User-Data-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Auth-Session-State", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Destination-Host", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Destination-Realm", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "User-Identity", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Server-Name", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Service-Indication", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Data-Reference", SH_VND_ID, RULE_REQUIRED, -1, -1 } + ,{ "Identity-Set", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Requested-Domain", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Current-Location", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "DSAI-Tag", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Session-Priority", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "User-Name", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Requested-Nodes", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Serving-Node-Indication", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Pre-paging-Supported", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Local-Time-Zone-Indication", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "UDR-Flags", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Call-Reference-Info", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &udr_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), udr_cmd); // cmd ); + } + + /* User-Data-Answer (UDA) Command */ + { + /* + The User-Data-Answer (UDA) command, indicated by the Command-Code field set to 306 and the ‘R?bit cleared in + the Command Flags field, is sent by a server in response to the User-Data-Request command. The Experimental-Result + AVP may contain one of the values defined in section 6.2 or in 3GPP TS 29.229 [6]. + Message Format: + + < User-Data-Answer > ::= < Diameter Header: 306, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + *[ Supported-Features ] + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ User-Data ] + [ OC-Supported-Features ] + [ OC-OLR ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + */ + // struct dict_object *uda_cmd; // cmd; + struct dict_cmd_data data = { + 306, /* Code */ + "User-Data-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Result-Code", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Experimental-Result", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Auth-Session-State", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "User-Data", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-OLR", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &uda_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), uda_cmd/*cmd*/); + } + + /* Profile-Update-Request (PUR) Command */ + { + /* + The Profile-Update-Request (PUR) command, indicated by the Command-Code field set to 307 and the ‘R?bit set in + the Command Flags field, is sent by a Diameter client to a Diameter server in order to update user data in the server. + Message Format: + + < Profile-Update-Request > ::= < Diameter Header: 307, REQ, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Destination-Host ] + { Destination-Realm } + *[ Supported-Features ] + { User-Identity } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ User-Name ] + *{ Data-Reference } + { User-Data } + [ OC-Supported-Features ] + *[ AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + */ + struct dict_object * pur_cmd; // cmd; + struct dict_cmd_data data = { + 307, /* Code */ + "Profile-Update-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Auth-Session-State", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Destination-Host", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Destination-Realm", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "User-Identity", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "User-Name", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Data-Reference", SH_VND_ID, RULE_REQUIRED, -1, -1 } + ,{ "User-Data", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &pur_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), pur_cmd); // cmd ); + } + + /* Profile-Update-Answer (PUA) Command */ + { + /* + The Profile-Update-Answer (PUA) command, indicated by the Command-Code field set to 307 and the ‘R?bit cleared + in the Command Flags field, is sent by a server in response to the Profile-Update-Request command. The Experimental- + Result AVP may contain one of the values defined in section 6.2 or in 3GPP TS 29.229 [6]. + Message Format: + + < Profile-Update-Answer > ::=< Diameter Header: 307, PXY, 16777217 > + < Session-Id > + [ DRMP ] + { Vendor-Specific-Application-Id } + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Wildcarded-Public-Identity ] + [ Wildcarded-IMPU ] + [ Repository-Data-ID ] + [ Data-Reference ] + *[ Supported-Features ] + [ OC-Supported-Features ] + [ OC-OLR ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + + */ +// struct dict_object * pur_cmd;// cmd; + struct dict_cmd_data data = { + 307, /* Code */ + "Profile-Update-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", SH_VND_ID, RULE_FIXED_HEAD, -1, 1 } + ,{ "DRMP", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Result-Code", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Experimental-Result", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Auth-Session-State", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", SH_VND_ID, RULE_REQUIRED, -1, 1 } + ,{ "Wildcarded-Public-Identity", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Wildcarded-IMPU", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Repository-Data-ID", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Data-Reference", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, -1 } + ,{ "OC-Supported-Features", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + ,{ "OC-OLR", SH_VND_ID, RULE_OPTIONAL, -1, 1 } + + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL/*sh_appli*/, &pua_cmd); // &cmd); + PARSE_loc_rules_( rules, sizeof(rules)/sizeof(rules[0]), pua_cmd); // cmd ); + } + + } + + LOG_D( "Extension 'Dictionary definitions for 3GPP29.229' initialized"); + return 0; +} +#endif + diff --git a/plat/diameter/extensions/sh_app/sh_serv.c b/plat/diameter/extensions/sh_app/sh_serv.c new file mode 100644 index 0000000..d4701be --- /dev/null +++ b/plat/diameter/extensions/sh_app/sh_serv.c @@ -0,0 +1,753 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Install the dispatch callbacks */ + +#include "sh_app.h" + +static struct disp_hdl * sh_hdl_fb = NULL; /* handler for fallback cb */ +static struct disp_hdl * sh_hdl_udr = NULL; /* handler for PUR req cb */ +static struct disp_hdl * sh_hdl_pur = NULL; /* handler for PUR req cb */ + +static struct sh_udr_msg g_udr_cmd; +static struct sh_pur_msg g_pur_cmd; + + +static struct sh_uda_msg g_uda_cmd; +static struct sh_pua_msg g_pua_cmd; +//static struct dict_avp_request __avp; + + + +/* Default callback for the application. */ +#if 0 +static int ta_fb_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act) +{ + /* This CB should never be called */ + TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); + + fd_log_debug("Unexpected message received!"); + + return ENOTSUP; +} +#endif + +static int sh_parse_pur(struct msg** msg) +{ + struct msg* udr_msg = *msg; + struct avp *avp, *grpavp=NULL; + struct avp_hdr *avphdr; + + LOG_D("fj sh_parse_pur"); + + SEARCH_AVP_("Session-Id", 0, &g_pur_cmd.pur_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_pur_cmd.pur_drmp); + + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_pur_cmd.pur_vendor_specific_application_id); + SEARCH_AVP_("Vendor-Id", 0, &g_pur_cmd.pur_vendor_id); + SEARCH_AVP_("Auth-Application-Id", 0, &g_pur_cmd.pur_auth_application_d); + SEARCH_AVP_("Acct-Application-Id", 0, &g_pur_cmd.pur_acct_application_id); + + SEARCH_AVP_("Auth-Session-State", 0, &g_pur_cmd.pur_auth_session_state); + SEARCH_AVP_("Origin-Host", 0, &g_pur_cmd.pur_origin_host); + SEARCH_AVP_("Origin-Realm", 0, &g_pur_cmd.pur_origin_realm); + SEARCH_AVP_("Destination-Host", 0, &g_pur_cmd.pur_destination_host); + SEARCH_AVP_("Destination-Realm", 0, &g_pur_cmd.pur_destination_realm); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_pur_cmd.pur_supported_features); + SEARCH_AVP_("Feature-List-ID", SH_VND_ID, &g_pur_cmd.pur_feature_list_id); + SEARCH_AVP_("Feature-List", SH_VND_ID, &g_pur_cmd.pur_feature_list); + + + SEARCH_AVP_("User-Identity", SH_VND_ID, &g_pur_cmd.pur_user_identity); + SEARCH_AVP_("Public-Identity", SH_VND_ID, &g_pur_cmd.pur_public_identity); + SEARCH_AVP_("MSISDN", SH_VND_ID, &g_pur_cmd.pur_msisdn); + + + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_pur_cmd.pur_wildcarded_public_identity); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_pur_cmd.pur_wildcarded_impu); + SEARCH_AVP_("User-Name", 0, &g_pur_cmd.pur_user_name); + SEARCH_AVP_("Data-Reference", SH_VND_ID, &g_pur_cmd.pur_data_reference); + + SEARCH_AVP_("User-Data", SH_VND_ID, &g_pur_cmd.pur_user_date); + + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_pur_cmd.pur_oc_supported_features); + SEARCH_AVP_("OC-Feature-Vector", SH_VND_ID, &g_pur_cmd.pur_oc_feature_vector); + + /* Session-Id */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_session_id, avp, avphdr, "Session-Id", avphdr->avp_value->os.data) + + /* DRMP */ + PARSE_AVP_U32(udr_msg, g_pur_cmd.pur_drmp, avp, avphdr, "DRMP", avphdr->avp_value->u32) + + /* Vendor-Specific-Application-Id */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_pur_cmd.pur_vendor_specific_application_id, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Vendor-Specific-Application-Id"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_pur_cmd.pur_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Auth-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_pur_cmd.pur_auth_application_d, avp, avphdr, "Auth-Application-Id", avphdr->avp_value->u32) + + /* Acct-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_pur_cmd.pur_acct_application_id, avp, avphdr, "Acct-Application-Id", avphdr->avp_value->u32) + } + + /* Auth-Session-State */ + PARSE_AVP_U32(udr_msg, g_pur_cmd.pur_auth_session_state, avp, avphdr, "Auth-Session-State", avphdr->avp_value->i32) + + /* Origin-Host */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_origin_host, avp, avphdr, "Origin-Host", avphdr->avp_value->os.data) + + /* Origin-Realm */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_origin_realm, avp, avphdr, "Origin-Realm", avphdr->avp_value->os.data) + + /* Destination-Host */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_destination_host, avp, avphdr, "Dest-Host", avphdr->avp_value->os.data) + + /* Destination-Realm */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_destination_realm, avp, avphdr, "Dest-Realm", avphdr->avp_value->os.data) + + /* Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_pur_cmd.pur_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Supported-Features "); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_pur_cmd.pur_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Feature-List-ID */ + PARSE_GRPAVP_U32(grpavp, g_pur_cmd.pur_feature_list_id, avp, avphdr, "Feature-List-ID", avphdr->avp_value->u32) + + /* Feature-List */ + PARSE_GRPAVP_U32(grpavp, g_pur_cmd.pur_feature_list, avp, avphdr, "Feature-List", avphdr->avp_value->u32) + } + + /* User-Identity */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_pur_cmd.pur_user_identity, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj User-Identity"); + + /* Public-Identity */ + PARSE_GRPAVP_STR(grpavp, g_pur_cmd.pur_public_identity, avp, avphdr, "Public-Identity", avphdr->avp_value->os.data) + + /* MSISDN */ + PARSE_GRPAVP_STR(grpavp, g_pur_cmd.pur_msisdn, avp, avphdr, "MSISDN", avphdr->avp_value->os.data) + } + + /* wildcarded_public_id */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_wildcarded_public_identity, avp, avphdr, "Wild-Pub-ID", avphdr->avp_value->os.data) + + /* wildcarded_impu */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_wildcarded_impu, avp, avphdr, "Wild-Pub-IMPU", avphdr->avp_value->os.data) + + /* User-Name */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_user_name, avp, avphdr, "User-Name", avphdr->avp_value->os.data) + + /* User-Data */ + PARSE_AVP_STR(udr_msg, g_pur_cmd.pur_user_date, avp, avphdr, "User-Data", avphdr->avp_value->os.data) + + + /* OC-Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_pur_cmd.pur_oc_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj OC-Supported-Features"); + + /* OC-Feature-Vector */ + PARSE_GRPAVP_U64(grpavp, g_pur_cmd.pur_oc_feature_vector, avp, avphdr, "OC-Feature-Vector", avphdr->avp_value->u64) + } + +out: + return 0; +} + +static int sh_parse_udr(struct msg** msg) +{ + struct msg* udr_msg = *msg; + struct avp *avp, *grpavp=NULL; + struct avp_hdr *avphdr; + + LOG_D("fj sh_parse_udr"); + + + SEARCH_AVP_("Session-Id", 0, &g_udr_cmd.udr_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_udr_cmd.udr_drmp); + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_udr_cmd.udr_vendor_specific_application_id); + SEARCH_AVP_("Vendor-Id", 0, &g_udr_cmd.udr_vendor_id); + SEARCH_AVP_("Auth-Application-Id", 0, &g_udr_cmd.udr_auth_application_d); + SEARCH_AVP_("Acct-Application-Id", 0, &g_udr_cmd.udr_acct_application_id); + + SEARCH_AVP_("Auth-Session-State", 0, &g_udr_cmd.udr_auth_session_state); + SEARCH_AVP_("Origin-Host", 0, &g_udr_cmd.udr_origin_host); + SEARCH_AVP_("Origin-Realm", 0, &g_udr_cmd.udr_origin_realm); + SEARCH_AVP_("Destination-Host", 0, &g_udr_cmd.udr_destination_host); + SEARCH_AVP_("Destination-Realm", 0, &g_udr_cmd.udr_destination_realm); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_udr_cmd.udr_supported_features); + SEARCH_AVP_("Feature-List-ID", SH_VND_ID, &g_udr_cmd.udr_feature_list_id); + SEARCH_AVP_("Feature-List", SH_VND_ID, &g_udr_cmd.udr_feature_list); + + SEARCH_AVP_("User-Identity", SH_VND_ID, &g_udr_cmd.udr_user_identity); + SEARCH_AVP_("Public-Identity", SH_VND_ID, &g_udr_cmd.udr_public_identity); + SEARCH_AVP_("MSISDN", SH_VND_ID, &g_udr_cmd.udr_msisdn); + + + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_udr_cmd.udr_wildcarded_public_identity); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_udr_cmd.udr_wildcarded_impu); + SEARCH_AVP_("Server-Name", SH_VND_ID, &g_udr_cmd.udr_server_name); + SEARCH_AVP_("Service-Indication", SH_VND_ID, &g_udr_cmd.udr_service_indication); + SEARCH_AVP_("Data-Reference", SH_VND_ID, &g_udr_cmd.udr_data_reference); + SEARCH_AVP_("Identity-Set", SH_VND_ID, &g_udr_cmd.udr_identity_set); + SEARCH_AVP_("Requested-Domain", SH_VND_ID, &g_udr_cmd.udr_requested_domain); + SEARCH_AVP_("Current-Location", SH_VND_ID, &g_udr_cmd.udr_current_location); + SEARCH_AVP_("DSAI-Tag", SH_VND_ID, &g_udr_cmd.udr_dsai_tag); + SEARCH_AVP_("Session-Priority", SH_VND_ID, &g_udr_cmd.udr_session_priority); + SEARCH_AVP_("User-Name", 0, &g_udr_cmd.udr_user_name); + SEARCH_AVP_("Requested-Nodes", SH_VND_ID, &g_udr_cmd.udr_requested_nodes); + SEARCH_AVP_("Serving-Node-Indication", SH_VND_ID, &g_udr_cmd.udr_serving_node_indication); + SEARCH_AVP_("Pre-paging-Supported", SH_VND_ID, &g_udr_cmd.udr_pre_paging_supported); + SEARCH_AVP_("Local-Time-Zone-Indication", SH_VND_ID, &g_udr_cmd.udr_local_time_zone_indication); + SEARCH_AVP_("UDR-Flags", SH_VND_ID, &g_udr_cmd.udr_udr_flags); + + SEARCH_AVP_("Call-Reference-Info", SH_VND_ID, &g_udr_cmd.udr_call_reference_info); + SEARCH_AVP_("Call-Reference-Number", SH_VND_ID, &g_udr_cmd.udr_call_reference_number); + SEARCH_AVP_("AS-Number", SH_VND_ID, &g_udr_cmd.udr_as_number); + + + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_udr_cmd.udr_oc_supported_features); + SEARCH_AVP_("OC-Feature-Vector", SH_VND_ID, &g_udr_cmd.udr_oc_feature_vector); + + + /* Session-Id */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_session_id, avp, avphdr, "fj Session-Id", avphdr->avp_value->os.data) + + /* DRMP */ + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_drmp, avp, avphdr, "fj DRMP", avphdr->avp_value->u32) + + /* Vendor-Specific-Application-Id */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_udr_cmd.udr_vendor_specific_application_id, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Vendor-Specific-Application-Id"); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_udr_cmd.udr_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Auth-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_udr_cmd.udr_auth_application_d, avp, avphdr, "Auth-Application-Id", avphdr->avp_value->u32) + + /* Acct-Application-Id */ + PARSE_GRPAVP_U32(grpavp, g_udr_cmd.udr_acct_application_id, avp, avphdr, "Acct-Application-Id", avphdr->avp_value->u32) + } + + /* Auth-Session-State */ + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_auth_session_state, avp, avphdr, "Auth-Session-State", avphdr->avp_value->i32) + + /* Origin-Host */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_origin_host, avp, avphdr, "Origin-Host", avphdr->avp_value->os.data) + + /* Origin-Realm */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_origin_realm, avp, avphdr, "Origin-Realm", avphdr->avp_value->os.data) + + /* Destination-Host */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_destination_host, avp, avphdr, "Dest-Host", avphdr->avp_value->os.data) + + /* Destination-Realm */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_destination_realm, avp, avphdr, "Dest-Realm", avphdr->avp_value->os.data) + + /* Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_udr_cmd.udr_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Supported-Features "); + + /* Vendor-Id */ + PARSE_GRPAVP_U32(grpavp, g_udr_cmd.udr_vendor_id, avp, avphdr, "Vendor-Id", avphdr->avp_value->u32) + + /* Feature-List-ID */ + PARSE_GRPAVP_U32(grpavp, g_udr_cmd.udr_feature_list_id, avp, avphdr, "Feature-List-ID", avphdr->avp_value->u32) + + /* Feature-List */ + PARSE_GRPAVP_U32(grpavp, g_udr_cmd.udr_feature_list, avp, avphdr, "Feature-List", avphdr->avp_value->u32) + } + + /* User-Identity */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_udr_cmd.udr_user_identity, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj User-Identity"); + + /* Public-Identity */ + PARSE_GRPAVP_STR(grpavp, g_udr_cmd.udr_public_identity, avp, avphdr, "Public-Identity", avphdr->avp_value->os.data) + + /* MSISDN */ + PARSE_GRPAVP_STR(grpavp, g_udr_cmd.udr_msisdn, avp, avphdr, "MSISDN", avphdr->avp_value->os.data) + } + + /* wildcarded_public_id */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_wildcarded_public_identity, avp, avphdr, "Wild-Pub-ID", avphdr->avp_value->os.data) + + /* wildcarded_impu */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_wildcarded_impu, avp, avphdr, "Wild-Pub-IMPU", avphdr->avp_value->os.data) + + /* server_name */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_server_name, avp, avphdr, "Server-Name", avphdr->avp_value->os.data) + + /* Service-Indication */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_service_indication, avp, avphdr, "Service-ID", avphdr->avp_value->os.data) + + /* Data-Reference */ + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_data_reference, avp, avphdr, "Data-Reference", avphdr->avp_value->u32) + + /* Identity-Set */ + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_identity_set, avp, avphdr, "Identity-Set", avphdr->avp_value->u32) + + /* Req-Domain*/ + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_requested_domain, avp, avphdr, "Req-Domain", avphdr->avp_value->u32) + + /* Cur-Location*/ + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_current_location, avp, avphdr, "Cur-Location", avphdr->avp_value->u32) + + /* DSAI-Tag */ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_dsai_tag, avp, avphdr, "DSAI-Tag", avphdr->avp_value->os.data) + + /* Session-Priority */ + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_session_priority, avp, avphdr, "Session-Priority", avphdr->avp_value->u32) + + /* User-Name*/ + PARSE_AVP_STR(udr_msg, g_udr_cmd.udr_user_name, avp, avphdr, "User-Name", avphdr->avp_value->os.data) + + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_requested_nodes, avp, avphdr, "Requested-Nodes", avphdr->avp_value->u32) + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_serving_node_indication, avp, avphdr, "Serving-Node-Indication", avphdr->avp_value->u32) + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_pre_paging_supported, avp, avphdr, "Pre-paging-Supported", avphdr->avp_value->u32) + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_local_time_zone_indication, avp, avphdr, "Local-Time-Zone-Indication", avphdr->avp_value->u32) + PARSE_AVP_U32(udr_msg, g_udr_cmd.udr_udr_flags, avp, avphdr, "UDR-Flags", avphdr->avp_value->u32) + + /* Call-Reference-Info */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_udr_cmd.udr_call_reference_info, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Call-Reference-Info"); + + /* Call-Reference-Number */ + PARSE_GRPAVP_STR(grpavp, g_udr_cmd.udr_call_reference_number, avp, avphdr, "Call-Reference-Number", avphdr->avp_value->os.data) + + /* AS-Number */ + PARSE_GRPAVP_STR(grpavp, g_udr_cmd.udr_as_number, avp, avphdr, "AS-Number", avphdr->avp_value->os.data) + } + + /* OC-Supported-Features */ + CHECK_FCT( fd_msg_search_avp ( udr_msg, g_udr_cmd.udr_oc_supported_features, &grpavp) ); + if(grpavp != NULL) + { + LOG_D("fj Call-Reference-Info"); + + /* OC-Feature-Vector */ + PARSE_GRPAVP_U64(grpavp, g_udr_cmd.udr_oc_feature_vector, avp, avphdr, "OC-Feature-Vector", avphdr->avp_value->u64) + } +out: + + return 0; +} + +static int sh_rec_pur( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act) +{ + struct dict_object * pur_origin_host = NULL; + + struct msg *ans/*, *qry*/; + struct avp * a, *grpavp; + union avp_value val; + + TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); + LOG_D("fj sh_rec_pur in\n"); + + if (msg == NULL) + return EINVAL; + + sh_parse_pur(msg); + + SEARCH_AVP_("Origin-Host", 0, &pur_origin_host); + + /* Value of Origin-Host */ + if (! (ta_conf->mode & MODE_BENCH)) { + fprintf(stderr, "ECHO PUR received from "); + CHECK_FCT( fd_msg_search_avp ( *msg, pur_origin_host, &a) ); + if (a) { + struct avp_hdr * hdr; + CHECK_FCT( fd_msg_avp_hdr( a, &hdr ) ); + fprintf(stderr, "'%.*s'", (int)hdr->avp_value->os.len, hdr->avp_value->os.data); + } else { + fprintf(stderr, "no_Origin-Host"); + } + fprintf(stderr, ", replying...\n"); + } + + /* Create answer header */ + // qry = *msg; + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); + ans = *msg; + + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( ans, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + msg_hdr->msg_flags = msg_hdr->msg_flags & (~CMD_FLAG_PROXIABLE); + } + + + /* resolve uda avps */ + // SEARCH_AVP_("Session-Id", 0, &uda_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_pua_cmd.pua_drmp); + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_pua_cmd.pua_vendor_specific_application_id); + SEARCH_AVP_("Result-Code", 0, &g_pua_cmd.pua_result_code); + SEARCH_AVP_("Experimental-Result", 0, &g_pua_cmd.pua_experimental_result); + SEARCH_AVP_("Auth-Session-State", 0, &g_pua_cmd.pua_auth_session_state); + SEARCH_AVP_("Origin-Host", 0, &g_pua_cmd.pua_origin_host); + SEARCH_AVP_("Origin-Realm", 0, &g_pua_cmd.pua_origin_realm); + + + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_pua_cmd.pua_wildcarded_public_identity ); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_pua_cmd.pua_wildcarded_impu ); + SEARCH_AVP_("Repository-Data-ID", SH_VND_ID, &g_pua_cmd.pua_repository_data_id ); + + SEARCH_AVP_("Data-Reference", SH_VND_ID, &g_pua_cmd.pua_data_reference); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_pua_cmd.pua_supported_features ); + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_pua_cmd.pua_oc_supported_features ); + SEARCH_AVP_("OC-OLR", SH_VND_ID, &g_pua_cmd.pua_oc_olr ); + + + EN_AVP_U32(g_pua_cmd.pua_drmp, 0, ans, "DRMP Ok") + + /* Set Vendor-Specific-Application-Id AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_pua_cmd.pua_vendor_specific_application_id, 0, &grpavp ) ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_pua_cmd.pua_vendor_id, SH_VND_ID) + EN_GRPAVP_U32("Auth-Application-Id", 0, g_pua_cmd.pua_auth_application_d, SH_APP_ID) + EN_GRPAVP_U32("Acct-Application-Id", 0,g_pua_cmd.pua_acct_application_id, SH_APP_ID) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Vendor-Specific-Application-Id Ok\n"); + } + + // EN_AVP_U32(g_uda_cmd.uda_result_code, 2001, ans, "Result-Code Ok\n") + + /* Set the Experimental-Result group AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_pua_cmd.pua_experimental_result, 0, &grpavp ) ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_pua_cmd.pua_vendor_id, SH_VND_ID) + EN_GRPAVP_U32("Experimental-Result-Code", 0, g_pua_cmd.pua_experimental_result_code, 3) + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Experimental-Result Ok\n"); + } + + EN_AVP_U32(g_pua_cmd.pua_auth_session_state, 0, ans, "Auth-Session-State Ok\n") + + + EN_AVP_STR(g_pua_cmd.pua_wildcarded_public_identity, "wildcarded_public_id", ans, "wildcarded_public_id Ok") + EN_AVP_STR( g_pua_cmd.pua_wildcarded_impu, "wildcarded_impu", ans, "wildcarded_impu Ok") + /* Set the Repository-Data-ID AVP */ + { + CHECK_FCT( fd_msg_avp_new ( g_pua_cmd.pua_repository_data_id, 0, &grpavp ) ); + + EN_GRPAVP_STR("Service-Indication", SH_VND_ID, g_pua_cmd.pua_service_indication, "Service-Indicatioin", grpavp) + EN_GRPAVP_U32_("Sequence-Number", SH_VND_ID, g_pua_cmd.pua_sequence_number, 1234, grpavp) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Repository-Data-ID Ok\n"); + } + + EN_AVP_U32(g_pua_cmd.pua_data_reference, 0, ans, "Data-Reference Ok\n") + + /* Set the Supported-Features group AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_pua_cmd.pua_supported_features, 0, &grpavp ) ); + + EN_GRPAVP_U32_("Vendor-Id", 0, g_pua_cmd.pua_vendor_id, SH_VND_ID, grpavp) + EN_GRPAVP_U32_("Feature-List-ID", SH_VND_ID, g_pua_cmd.pua_feature_list_id, 2, grpavp) + EN_GRPAVP_U32_("Feature-List", SH_VND_ID, g_pua_cmd.pua_feature_list, 3, grpavp) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Supported-Features Ok\n"); + } + + /* Set the OC-Supported-Features AVP */ + { + CHECK_FCT( fd_msg_avp_new ( g_pua_cmd.pua_oc_supported_features, 0, &grpavp ) ); + + EN_GRPAVP_U64("OC-Feature-Vector", SH_VND_ID, g_pua_cmd.pua_oc_feature_vector, 1) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("OC-Feature-Vector Ok\n"); + } + + /* Set the OC-OLR group AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_pua_cmd.pua_oc_olr, 0, &grpavp ) ); + + EN_GRPAVP_U64("OC-Sequence-Number", SH_VND_ID, g_pua_cmd.pua_oc_sequence_number, 1) + EN_GRPAVP_U32("OC-Report-Type", SH_VND_ID,g_pua_cmd.pua_oc_report_type, 2) + EN_GRPAVP_U32("OC-Reduction-Percentage", SH_VND_ID, g_pua_cmd.pua_oc_reduction_percentage, 3) + EN_GRPAVP_U32("OC-Validity-Duration", SH_VND_ID, g_pua_cmd.pua_oc_validity_duration, 4) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("OC-OLR Ok\n"); + } + + /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ + CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) ); + + /* Send the answer */ + CHECK_FCT( fd_msg_send( msg, NULL, NULL ) ); + + /* Add this value to the stats */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + ta_conf->stats.nb_echoed++; + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + +out: + printf("sh_rec_pur end.\n"); + return 0; +} + +static int sh_rec_udr( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act) +{ + struct msg *ans/*, *qry*/; + struct avp * a, *grpavp; + union avp_value val; + + TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); + LOG_D("fj sh_rec_udr in\n"); + + if (msg == NULL) + return EINVAL; + + sh_parse_udr(msg); + + SEARCH_AVP_("Origin-Host", 0, &g_uda_cmd.uda_origin_host); + SEARCH_AVP_("Session-Id", 0, &g_uda_cmd.uda_session_id); + + /* Value of Origin-Host */ + if (! (ta_conf->mode & MODE_BENCH)) { + fprintf(stderr, "ECHO UDR received from "); + CHECK_FCT( fd_msg_search_avp ( *msg, g_uda_cmd.uda_origin_host, &a) ); + if (a) { + struct avp_hdr * hdr; + CHECK_FCT( fd_msg_avp_hdr( a, &hdr ) ); + fprintf(stderr, "'%.*s'", (int)hdr->avp_value->os.len, hdr->avp_value->os.data); + } else { + fprintf(stderr, "no_Origin-Host"); + } + fprintf(stderr, ", replying...\n"); + } + + /* Create answer header */ + // qry = *msg; + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); + ans = *msg; + + /* set application id */ + { + struct msg_hdr * msg_hdr = NULL; + ASSERT( 0 == fd_msg_hdr ( ans, &msg_hdr ) ); + msg_hdr->msg_appl = SH_APP_ID; + msg_hdr->msg_flags = msg_hdr->msg_flags & (~CMD_FLAG_PROXIABLE); + } + + /* resolve uda avps */ + // SEARCH_AVP_("Session-Id", 0, &uda_session_id); + SEARCH_AVP_("DRMP", SH_VND_ID, &g_uda_cmd.uda_drmp); + SEARCH_AVP_("Vendor-Specific-Application-Id", 0, &g_uda_cmd.uda_vendor_specific_application_id); + SEARCH_AVP_("Result-Code", 0, &g_uda_cmd.uda_result_code); + SEARCH_AVP_("Experimental-Result", 0, &g_uda_cmd.uda_experimental_result); + SEARCH_AVP_("Auth-Session-State", 0, &g_uda_cmd.uda_auth_session_state); + + SEARCH_AVP_("Origin-Realm", 0, &g_uda_cmd.uda_origin_realm); + + SEARCH_AVP_("Supported-Features", SH_VND_ID, &g_uda_cmd.uda_supported_features ); + SEARCH_AVP_("Wildcarded-Public-Identity", SH_VND_ID, &g_uda_cmd.uda_wildcarded_public_identity ); + SEARCH_AVP_("Wildcarded-IMPU", SH_VND_ID, &g_uda_cmd.uda_wildcarded_impu ); + SEARCH_AVP_("User-Data", SH_VND_ID, &g_uda_cmd.uda_user_data ); + SEARCH_AVP_("OC-Supported-Features", SH_VND_ID, &g_uda_cmd.uda_oc_supported_features ); + SEARCH_AVP_("OC-OLR", SH_VND_ID, &g_uda_cmd.uda_oc_olr ); + + + EN_AVP_U32(g_uda_cmd.uda_drmp, 0, ans, "DRMP Ok") + + /* Set Vendor-Specific-Application-Id AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_uda_cmd.uda_vendor_specific_application_id, 0, &grpavp ) ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_uda_cmd.uda_vendor_id, SH_VND_ID) + EN_GRPAVP_U32("Auth-Application-Id", 0, g_uda_cmd.uda_auth_application_d, SH_APP_ID) + EN_GRPAVP_U32("Acct-Application-Id", 0,g_uda_cmd.uda_acct_application_id, SH_APP_ID) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Vendor-Specific-Application-Id Ok\n"); + } + + // EN_AVP_U32(g_uda_cmd.uda_result_code, 2001, ans, "Result-Code Ok\n") + + /* Set the Experimental-Result group AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_uda_cmd.uda_experimental_result, 0, &grpavp ) ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_uda_cmd.uda_vendor_id, 3) + EN_GRPAVP_U32("Experimental-Result-Code", 0, g_uda_cmd.uda_experimental_result_code, 3) + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Experimental-Result Ok\n"); + } + + EN_AVP_U32(g_uda_cmd.uda_auth_session_state, 0, ans, "Auth-Session-State Ok\n") + + /* Set the Supported-Features group AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_uda_cmd.uda_supported_features, 0, &grpavp ) ); + + EN_GRPAVP_U32("Vendor-Id", 0, g_uda_cmd.uda_vendor_id, 1) + EN_GRPAVP_U32("Feature-List-ID", SH_VND_ID, g_uda_cmd.uda_feature_list_id, 2) + EN_GRPAVP_U32("Feature-List", SH_VND_ID, g_uda_cmd.uda_feature_list, 3) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Supported-Features Ok\n"); + } + EN_AVP_STR(g_uda_cmd.uda_wildcarded_public_identity, "wildcarded_public_id", ans, "wildcarded_public_id Ok") + EN_AVP_STR( g_uda_cmd.uda_wildcarded_impu, "wildcarded_impu", ans, "wildcarded_impu Ok") + EN_AVP_STR( g_uda_cmd.uda_user_data, "User-Data", ans, "User-Data Ok") + /* Set the OC-Supported-Features AVP */ + { + CHECK_FCT( fd_msg_avp_new ( g_uda_cmd.uda_oc_supported_features, 0, &grpavp ) ); + + EN_GRPAVP_U64("OC-Feature-Vector", SH_VND_ID, g_uda_cmd.uda_oc_feature_vector, 1) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("OC-Feature-Vector Ok\n"); + } + /* Set the OC-OLR group AVP if needed*/ + { + CHECK_FCT( fd_msg_avp_new ( g_uda_cmd.uda_oc_olr, 0, &grpavp ) ); + + EN_GRPAVP_U64("OC-Sequence-Number", SH_VND_ID, g_uda_cmd.uda_oc_sequence_number, 1) + EN_GRPAVP_U32("OC-Report-Type", SH_VND_ID,g_uda_cmd.uda_oc_report_type, 2) + EN_GRPAVP_U32("OC-Reduction-Percentage", SH_VND_ID, g_uda_cmd.uda_oc_reduction_percentage, 3) + EN_GRPAVP_U32("OC-Validity-Duration", SH_VND_ID, g_uda_cmd.uda_oc_validity_duration, 4) + + CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, grpavp ) ); + + LOG_D("Supported-Features Ok\n"); +#if SH_TEST_ON + fd_log_debug("%s", fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, ans, fd_g_config->cnf_dict, 0, 1)); +#endif + } + + /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ + CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) ); + + /* Send the answer */ + CHECK_FCT( fd_msg_send( msg, NULL, NULL ) ); + + /* Add this value to the stats */ + CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), ); + ta_conf->stats.nb_echoed++; + CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), ); + +out: + return 0; +} + +extern struct dict_object * sh_appli; +extern struct dict_object * sh_vendor; +extern struct dict_object * udr_cmd; +extern struct dict_object * pur_cmd; + +int sh_serv_init(void) +{ + struct disp_when data; + + TRACE_DEBUG(FULL, "Initializing dispatch callbacks for test"); + + memset(&data, 0, sizeof(data)); + data.app = sh_appli; + data.command = udr_cmd; // udr_cmd; // ta_cmd_r; + + /* fallback CB if command != Test-Request received */ + // CHECK_FCT( fd_disp_register( ta_fb_cb, DISP_HOW_APPID, &data, NULL, &sh_hdl_fb ) ); + + /* Now specific handler for UDR */ + CHECK_FCT( fd_disp_register( sh_rec_udr, DISP_HOW_CC, &data, NULL, &sh_hdl_udr ) ); + + memset(&data, 0, sizeof(data)); + data.app = sh_appli; + data.command = pur_cmd; // udr_cmd; // ta_cmd_r; + /* Now specific handler for PUR */ + CHECK_FCT( fd_disp_register( sh_rec_pur, DISP_HOW_CC, &data, NULL, &sh_hdl_pur ) ); + + return 0; +} + +void sh_serv_fini(void) +{ + if (sh_hdl_fb) { + (void) fd_disp_unregister(&sh_hdl_fb, NULL); + } + if (sh_hdl_udr) { + (void) fd_disp_unregister(&sh_hdl_udr, NULL); + } + if (sh_hdl_pur) { + (void) fd_disp_unregister(&sh_hdl_pur, NULL); + } + + return; +} diff --git a/plat/diameter/extensions/sh_app/ta_conf.l b/plat/diameter/extensions/sh_app/ta_conf.l new file mode 100644 index 0000000..8759a4c --- /dev/null +++ b/plat/diameter/extensions/sh_app/ta_conf.l @@ -0,0 +1,177 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Lex extension's configuration parser. + * + * The configuration file contains a default priority, and a list of peers with optional overwite priority. + * -- see the app_test.conf.sample file for more detail. + */ + +%{ +#include "test_app.h" +/* Include yacc tokens definitions */ +#include "ta_conf.tab.h" + +/* Update the column information */ +#define YY_USER_ACTION { \ + yylloc->first_column = yylloc->last_column + 1; \ + yylloc->last_column = yylloc->first_column + yyleng - 1; \ +} + +/* Avoid warning with newer flex */ +#define YY_NO_INPUT + +%} + +%option bison-bridge bison-locations +%option noyywrap +%option nounput + +%% + + /* Update the line count */ +\n { + yylloc->first_line++; + yylloc->last_line++; + yylloc->last_column=0; + } + + /* Eat all spaces but not new lines */ +([[:space:]]{-}[\n])+ ; + /* Eat all comments */ +#.*$ ; + + /* Recognize any integer */ +[-]?[[:digit:]]+ { + /* Convert this to an integer value */ + int ret=0; + ret = sscanf(yytext, "%i", &yylval->integer); + if (ret != 1) { + /* No matching: an error occurred */ + fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno)); + return LEX_ERROR; /* trig an error in yacc parser */ + /* Maybe we could REJECT instead of failing here? */ + } + return INTEGER; + } + + /* Recognize quoted strings -- we do not support escaped \" in the string currently. */ +\"[^\"]+\" { + /* Match a quoted string. Let's be very permissive. */ + yylval->string = strdup(yytext+1); + if (!yylval->string) { + fd_log_debug("Unable to copy the string '%s': %s", yytext, strerror(errno)); + TRACE_DEBUG(INFO, "strdup failed"); + return LEX_ERROR; /* trig an error in yacc parser */ + } + yylval->string[strlen(yytext) - 2] = '\0'; + return QSTRING; + } + + /* Recognize the tokens */ +(?i:"vendor-id") { + return VENDOR_ID; + } + +(?i:"appli-id") { + return APPLI_ID; + } + +(?i:"cmd-id") { + return CMD_ID; + } + +(?i:"avp-id") { + return AVP_ID; + } + +(?i:"long-avp-id") { + return LONG_AVP_ID; + } + +(?i:"long-avp-len") { + return LONG_AVP_LEN; + } + +(?i:"mode") { + return MODE; + } + +(?i:"server") { + yylval->integer = MODE_SERV; + return INTEGER; + } + +(?i:"client") { + yylval->integer = MODE_CLI; + return INTEGER; + } + +(?i:"both") { + yylval->integer = MODE_SERV | MODE_CLI; + return INTEGER; + } + +(?i:"dest-realm") { + return DEST_REALM; + } + +(?i:"dest-host") { + return DEST_HOST; + } + +(?i:"user-name") { + return USER_NAME; + } + +(?i:"Signal") { + return SIGNAL; + } + +(?i:"Benchmark") { + return BENCH; + } + + + /* Valid single characters for yyparse */ +[=;] { return yytext[0]; } + + /* Unrecognized sequence, if it did not match any previous pattern */ +[^[:space:]"*=>;\n]+ { + fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext); + return LEX_ERROR; + } + +%% diff --git a/plat/diameter/extensions/sh_app/ta_conf.y b/plat/diameter/extensions/sh_app/ta_conf.y new file mode 100644 index 0000000..d39e1e7 --- /dev/null +++ b/plat/diameter/extensions/sh_app/ta_conf.y @@ -0,0 +1,239 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Yacc extension's configuration parser. + * See doc/app_test.conf.sample for configuration file format + */ + +/* For development only : */ +%debug +%error-verbose + +/* The parser receives the configuration file filename as parameter */ +%parse-param {char * conffile} + +/* Keep track of location */ +%locations +%pure-parser + +%{ +#include "test_app.h" +#include "ta_conf.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */ + +#include +#include + +/* Forward declaration */ +int yyparse(char * conffile); + +/* Parse the configuration file */ +int ta_conf_handle(char * conffile) +{ + extern FILE * ta_confin; + int ret; + + TRACE_ENTRY("%p", conffile); + + TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile); + + ta_confin = fopen(conffile, "r"); + if (ta_confin == NULL) { + ret = errno; + fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret)); + TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file."); + return ret; + } + + ret = yyparse(conffile); + + fclose(ta_confin); + + if (ret != 0) { + TRACE_DEBUG (INFO, "Unable to parse the configuration file."); + return EINVAL; + } + + return 0; +} + +/* The Lex parser prototype */ +int ta_conflex(YYSTYPE *lvalp, YYLTYPE *llocp); + +/* Function to report the errors */ +void yyerror (YYLTYPE *ploc, char * conffile, char const *s) +{ + TRACE_DEBUG(INFO, "Error in configuration parsing"); + + if (ploc->first_line != ploc->last_line) + fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s); + else if (ploc->first_column != ploc->last_column) + fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s); + else + fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s); +} + +%} + +/* Values returned by lex for token */ +%union { + char *string; /* The string is allocated by strdup in lex.*/ + int integer; /* Store integer values */ +} + +/* In case of error in the lexical analysis */ +%token LEX_ERROR + +/* Key words */ +%token VENDOR_ID +%token APPLI_ID +%token CMD_ID +%token AVP_ID +%token LONG_AVP_ID +%token LONG_AVP_LEN +%token MODE +%token DEST_REALM +%token DEST_HOST +%token USER_NAME +%token SIGNAL +%token BENCH + +/* Tokens and types for routing table definition */ +/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */ +%token QSTRING + +/* An integer value */ +%token INTEGER + + + +/* -------------------------------------- */ +%% + + /* The grammar definition */ +conffile: /* empty grammar is OK */ + | conffile vendor + | conffile appli + | conffile cmd + | conffile avp + | conffile long_avp_id + | conffile long_avp_len + | conffile mode + | conffile dstrealm + | conffile dsthost + | conffile usrname + | conffile signal + | conffile bench + ; + +vendor: VENDOR_ID '=' INTEGER ';' + { + ta_conf->vendor_id = $3; + } + ; + +appli: APPLI_ID '=' INTEGER ';' + { + ta_conf->appli_id = $3; + } + ; + +cmd: CMD_ID '=' INTEGER ';' + { + ta_conf->cmd_id = $3; + } + ; + +avp: AVP_ID '=' INTEGER ';' + { + ta_conf->avp_id = $3; + } + ; + +long_avp_id: LONG_AVP_ID '=' INTEGER ';' + { + ta_conf->long_avp_id = $3; + } + ; + +long_avp_len: LONG_AVP_LEN '=' INTEGER ';' + { + ta_conf->long_avp_len = $3; + } + ; + +mode: MODE '=' INTEGER ';' + { + ta_conf->mode = $3 | (ta_conf->mode & ~3); /* overwrite the 2 lsb */ + } + ; + +bench: BENCH ';' + { + ta_conf->mode |= MODE_BENCH; + } + | BENCH INTEGER INTEGER ';' + { + ta_conf->mode |= MODE_BENCH; + ta_conf->bench_duration = $2; + ta_conf->bench_concur = $3; + } + ; + +dstrealm: DEST_REALM '=' QSTRING ';' + { + free(ta_conf->dest_realm); + ta_conf->dest_realm = $3; + } + ; + +dsthost: DEST_HOST '=' QSTRING ';' + { + free(ta_conf->dest_host); + ta_conf->dest_host = $3; + } + ; + +usrname: USER_NAME '=' QSTRING ';' + { + free(ta_conf->user_name); + ta_conf->user_name = $3; + } + ; + +signal: SIGNAL '=' INTEGER ';' + { + ta_conf->signal = $3; + } + ; diff --git a/plat/diameter/freeDiameter-1.conf b/plat/diameter/freeDiameter-1.conf new file mode 100644 index 0000000..096c9ea --- /dev/null +++ b/plat/diameter/freeDiameter-1.conf @@ -0,0 +1,26 @@ +#Service mode 1:Server 2:Client 4:Server&Client +ServiceMod = 3; + +Identity = "a.client.com"; + +Realm = "client.com"; + +Port = 3868; + +SecPort = 0; + +SCTPStr = 10; + +#TLS_Cred = "./cacert.pem", +# "./cakey.pem"; +#TLS_CA = "./cacert.pem"; + +#Connect to peer. e.g ConnectPeer = "peer1.localdomain" { No_TLS; No_FWD; No_IP4; No_IP6; No_TCP; No_SCTP; Prefer_TCP; }; +#SCTP +#ConnectPeer = "a.server.net" { Realm = "server.net"; No_TLS; No_FWD; No_TCP; }; +#TCP +ConnectPeer = "a.server.net" { Realm = "server.net"; No_TLS; No_FWD; No_SCTP; Prefer_TCP; }; + +#Log levels 0:anything 1:debug 3:notice 5:error 6:fatal +LogLevel = 3; + diff --git a/plat/diameter/freeDiameter-2.conf b/plat/diameter/freeDiameter-2.conf new file mode 100644 index 0000000..9f21069 --- /dev/null +++ b/plat/diameter/freeDiameter-2.conf @@ -0,0 +1,25 @@ +#Service mode 1:Server 2:Client 3:Server&Client +ServiceMod = 3; + +Identity = "a.server.net"; + +Realm = "server.net"; + +Port = 3868; + +SecPort = 0; + +SCTPStr = 10; + +#TLS_Cred = "./cacert.pem", +# "./cakey.pem"; +#TLS_CA = "./cacert.pem"; + +#Connect to peer. e.g ConnectPeer = "peer1.localdomain" { No_TLS; No_FWD; No_IP4; No_IP6; No_TCP; No_SCTP; Prefer_TCP; }; +#SCTP +#ConnectPeer = "a.client.com" { Realm = "client.com"; No_TLS; No_FWD; No_TCP; }; +#TCP +ConnectPeer = "a.client.com" { Realm = "client.com"; No_FWD; No_TLS; No_SCTP; Prefer_TCP; }; + +#Log levels 0:anything 1:debug 3:notice 5:error 6:fatal +LogLevel = 3; diff --git a/plat/diameter/freeDiameterd/freeDiameter-host.h b/plat/diameter/freeDiameterd/freeDiameter-host.h new file mode 100644 index 0000000..c7671ec --- /dev/null +++ b/plat/diameter/freeDiameterd/freeDiameter-host.h @@ -0,0 +1,108 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Configuration from compile-time */ +#ifndef FD_IS_CONFIG +#define FD_IS_CONFIG + +#ifdef __cplusplus +extern "C" { +#endif + +/* #undef HAVE_NTOHLL */ +#define HAVE_MALLOC_H +/* #undef HAVE_SIGNALENT_H */ +#define HAVE_AI_ADDRCONFIG +#define HAVE_CLOCK_GETTIME +#define HAVE_STRNDUP +#define HAVE_PTHREAD_BAR + +/* #undef HOST_BIG_ENDIAN */ + +/* #undef DISABLE_SCTP */ +/* #undef DEBUG_SCTP */ +/* #undef DEBUG_WITH_META */ +/* #undef SCTP_USE_MAPPED_ADDRESSES */ +#define SCTP_CONNECTX_4_ARGS +/* #undef SKIP_DLCLOSE */ +/* #undef DIAMID_IDNA_IGNORE */ +/* #undef DIAMID_IDNA_REJECT */ +/* #undef DISABLE_PEER_EXPIRY */ +/* #undef WORKAROUND_ACCEPT_INVALID_VSAI */ +#define GNUTLS_VERSION_210 +#define GNUTLS_VERSION_212 +/* #undef GNUTLS_VERSION_300 */ +/* #undef GNUTLS_VERSION_310 */ + +/* #undef ERRORS_ON_TODO */ +/* #undef DEBUG */ + +#define FD_PROJECT_BINARY "agtocs" +//#define FD_PROJECT_NAME "freeDiameter" +#define FD_PROJECT_NAME "AGT_OCS" + +#define FD_PROJECT_VERSION_MAJOR 1 +#ifndef FD_PROJECT_VERSION_MAJOR +# define FD_PROJECT_VERSION_MAJOR 0 +#endif /*FD_PROJECT_VERSION_MAJOR*/ +#define FD_PROJECT_VERSION_MINOR 2 +#ifndef FD_PROJECT_VERSION_MINOR +# define FD_PROJECT_VERSION_MINOR 0 +#endif /*FD_PROJECT_VERSION_MINOR*/ +#define FD_PROJECT_VERSION_REV 1 +#ifndef FD_PROJECT_VERSION_REV +# define FD_PROJECT_VERSION_REV 0 +#endif /*FD_PROJECT_VERSION_REV*/ +#define FD_PROJECT_VERSION_API 6 +#ifndef FD_PROJECT_VERSION_API +# define FD_PROJECT_VERSION_API 0 +#endif /*FD_PROJECT_VERSION_API*/ +#define FD_PROJECT_COPYRIGHT "Copyright (c) 2008-2015, WIDE Project (www.wide.ad.jp) and NICT (www.nict.go.jp)" + +#define DEFAULT_CONF_PATH "DEFAULT_CONF_PATH" +#define DEFAULT_EXTENSIONS_PATH "CMAKE_INSTALL_PREFIX/INSTALL_EXTENSIONS_SUFFIX" + +#ifndef FD_DEFAULT_CONF_FILENAME +#define FD_DEFAULT_CONF_FILENAME "freeDiameter.conf" +#endif /* FD_DEFAULT_CONF_FILENAME */ + +/* Maximum number of hooks handlers that can be registered. Make this compilation option if needed */ +#define FD_HOOK_HANDLE_LIMIT 5 + +#ifdef __cplusplus +} +#endif + +#endif /* FD_IS_CONFIG */ diff --git a/plat/diameter/freeDiameterd/main.c b/plat/diameter/freeDiameterd/main.c new file mode 100644 index 0000000..87db49e --- /dev/null +++ b/plat/diameter/freeDiameterd/main.c @@ -0,0 +1,312 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "freeDiameter-host.h" +#include "libfdcore.h" + +#include +#include +#include + + +/* forward declarations */ +//static int main_cmdline(int argc, char *argv[]); +static void * catch_signals(void * arg); +static pthread_t signals_thr; +static pthread_t fd_thread; + +static char *conffile = NULL; +//static int gnutls_debug = 0; +#if 0 +/* gnutls debug */ +static void fd_gnutls_debug(int level, const char * str) { + fd_log_debug(" [gnutls:%d] %s", level, str); +} +#endif + +/* freeDiameter starting point */ +int fd_main_real(int argc, char * argv[]) +{ + int ret; + //sigset_t sig_all; + char conf_file[128] = {"./conf/fd_server.conf"}; + + conffile = conf_file; + + /* Block all signals from the current thread and all its future children -- we will catch everything in catch_signals */ + /* + sigfillset(&sig_all); + ret = pthread_sigmask(SIG_BLOCK, &sig_all, NULL); + ASSERT(ret == 0); + */ + /* Parse the command-line */ + /* + ret = main_cmdline(argc, argv); + if (ret != 0) { + return ret; + } + */ + /* Initialize the core library */ + ret = fd_core_initialize(); + if (ret != 0) { + fprintf(stderr, "An error occurred during freeDiameter core library initialization.\n"); + return ret; + } + + /* Set gnutls debug level ? */ + /* + if (gnutls_debug) { + gnutls_global_set_log_function((gnutls_log_func)fd_gnutls_debug); + gnutls_global_set_log_level (gnutls_debug); + TRACE_DEBUG(INFO, "Enabled GNUTLS debug at level %d", gnutls_debug); + } + */ + /* Parse the configuration file */ + CHECK_FCT_DO( fd_core_parseconf(conffile), goto error ); + + /* Start the servers */ + CHECK_FCT_DO( fd_core_start(), goto error ); + + return 1; + + /* Allow SIGINT and SIGTERM from this point to terminate the application */ + CHECK_POSIX_DO( pthread_create(&signals_thr, NULL, catch_signals, NULL), goto error ); + + TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized."); + + /* Now, just wait for termination */ + CHECK_FCT( fd_core_wait_shutdown_complete() ); + + /* Just in case it was not the result of a signal, we cancel signals_thr */ + fd_thr_term(&signals_thr); + + return 0; +error: + CHECK_FCT_DO( fd_core_shutdown(), ); + CHECK_FCT( fd_core_wait_shutdown_complete() ); + fd_thr_term(&signals_thr); + return -1; +} + +int fd_main(int argc, char * argv[]) +{ + + CHECK_POSIX_DO( pthread_create(&fd_thread, NULL, fd_main_real , NULL), return 0 ); + + return 1; +} + +/* Display package version */ +static void main_version_core(void) +{ + printf("%s, version %s\n", FD_PROJECT_NAME, fd_core_version); +} + +/* Display package version and general info */ +static void main_version(void) +{ + main_version_core(); + printf( "%s\n", FD_PROJECT_COPYRIGHT); + printf( "\nSee " FD_PROJECT_NAME " homepage at http://www.freediameter.net/\n" + " for information, updates and bug reports on this software.\n"); +} + +/* Print command-line options */ +static void main_help( void ) +{ + main_version_core(); + printf( " This daemon is an implementation of the Diameter protocol\n" + " used for Authentication, Authorization, and Accounting (AAA).\n"); + printf("\nUsage: " FD_PROJECT_BINARY " [OPTIONS]...\n"); + printf( " -h, --help Print help and exit\n" + " -V, --version Print version and exit\n" + " -c, --config=filename Read configuration from this file instead of the \n" + " default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ").\n"); + printf( "\nDebug:\n" + " These options are mostly useful for developers\n" + " -l, --dbglocale Set the locale for error messages\n" + " -d, --debug Increase verbosity of debug messages if default logger is used\n" + " -q, --quiet Decrease verbosity if default logger is used\n" + " -f, --dbg_func Enable all traces within the function \n" + " -F, --dbg_file Enable all traces within the file (basename match)\n" + " --dbg_gnutls Enable GNU TLS debug at level \n" + ); +} +#if 0 +/* Parse the command-line */ +static int main_cmdline(int argc, char *argv[]) +{ + int c; + int option_index = 0; + char * locale; + + struct option long_options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { "config", required_argument, NULL, 'c' }, + { "debug", no_argument, NULL, 'd' }, + { "quiet", no_argument, NULL, 'q' }, + { "dbglocale", optional_argument, NULL, 'l' }, + { "dbg_func", required_argument, NULL, 'f' }, + { "dbg_file", required_argument, NULL, 'F' }, + { "dbg_gnutls", required_argument, NULL, 'g' }, + { NULL, 0, NULL, 0 } + }; + + /* Loop on arguments */ + while (1) { + c = getopt_long (argc, argv, "hVc:dql:f:F:g:", long_options, &option_index); + if (c == -1) + break; /* Exit from the loop. */ + + switch (c) { + case 'h': /* Print help and exit. */ + main_help(); + exit(0); + + case 'V': /* Print version and exit. */ + main_version(); + exit(0); + + case 'c': /* Read configuration from this file instead of the default location.. */ + if (optarg == NULL ) { + fprintf(stderr, "Missing argument with --config directive\n"); + return EINVAL; + } + conffile = optarg; + break; + + case 'l': /* Change the locale. */ + locale = setlocale(LC_ALL, optarg?:""); + if (!locale) { + fprintf(stderr, "Unable to set locale (%s)\n", optarg); + return EINVAL; + } + break; + + case 'd': /* Increase verbosity of debug messages. */ + fd_g_debug_lvl--; + break; + + case 'f': /* Full debug for the function with this name. */ + #ifdef DEBUG + fd_debug_one_function = optarg; + fd_g_debug_lvl = FD_LOG_DEBUG; + #else /* DEBUG */ + fprintf(stderr, "Error: must compile with DEBUG support to use --dbg_func feature!\n"); + return EINVAL; + #endif /* DEBUG */ + break; + + case 'F': /* Full debug for the file with this name. */ + #ifdef DEBUG + fd_debug_one_file = basename(optarg); + fd_g_debug_lvl = FD_LOG_DEBUG; + #else /* DEBUG */ + fprintf(stderr, "Error: must compile with DEBUG support to use --dbg_file feature!\n"); + return EINVAL; + #endif /* DEBUG */ + break; + + case 'g': /* Set a debug level and function for GNU TLS calls. */ + gnutls_debug = (int)atoi(optarg); + break; + + case 'q': /* Decrease verbosity then remove debug messages. */ + fd_g_debug_lvl++; + break; + + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + fprintf(stderr, "getopt_long found an invalid character\n"); + return EINVAL; + + default: /* bug: option not considered. */ + fprintf(stderr, "A command-line option is missing in parser: %c\n", c); + ASSERT(0); + return EINVAL; + } + } + + return 0; +} +#endif +/* Handle some signals */ +static void * catch_signals(void * arg) +{ + sigset_t ss; + fd_log_threadname ( "signals catcher" ); + + sigemptyset(&ss); + + /* Signals that terminate the daemon */ + sigaddset(&ss, SIGTERM); + sigaddset(&ss, SIGINT); + + /* Signals that send an event */ + sigaddset(&ss, SIGUSR1); + sigaddset(&ss, SIGUSR2); + + /* We unblock all other signals, so that their default handler is used (such as SIGTSTP) */ + CHECK_SYS_DO( pthread_sigmask( SIG_SETMASK, &ss, NULL ), goto out ); + + /* Now loop on the reception of the signal */ + while (1) { + int sig, *ps; + + /* Wait to receive the next signal */ + CHECK_POSIX_DO( sigwait(&ss, &sig), break ); + + TRACE_DEBUG(FULL, "Signal %d caught", sig); + + switch (sig) { + case SIGUSR1: + case SIGUSR2: + CHECK_MALLOC_DO( ps = malloc(sizeof(int)), goto out); + *ps = sig; + CHECK_FCT_DO( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TRIGGER, sizeof(int), ps), goto out ); + break; + + case SIGINT: + case SIGTERM: + CHECK_FCT_DO( fd_core_shutdown(), goto out ); + + } + } +out: + /* Better way to handle this ? */ + ASSERT(0); + return NULL; +} diff --git a/plat/diameter/include/freeDiameter/extension.h b/plat/diameter/include/freeDiameter/extension.h new file mode 100644 index 0000000..d56a72b --- /dev/null +++ b/plat/diameter/include/freeDiameter/extension.h @@ -0,0 +1,72 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#ifndef _EXTENSION_H +#define _EXTENSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Include definition of freeDiameter API */ +#include "freeDiameter-host.h" +#include "libfdcore.h" + +/* Macro that define the entry point of the extension */ +#define EXTENSION_ENTRY(_name, _function, _depends...) \ +const char *fd_ext_depends[] = { _name , ## _depends , NULL }; \ +static int extension_loaded = 0; \ +int fd_ext_init(int major, int minor, char * conffile) { \ + if ((major != FD_PROJECT_VERSION_MAJOR) \ + || (minor != FD_PROJECT_VERSION_MINOR)) { \ + TRACE_ERROR("This extension (" _name ") was compiled for a different version of freeDiameter."); \ + TRACE_DEBUG(INFO, "daemon %d.%d != ext %d.%d", \ + major, minor, \ + FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR); \ + return EINVAL; \ + } \ + if (extension_loaded) { \ + TRACE_ERROR("Extension (" _name ") cannot be loaded twice!"); \ + return ENOTSUP; \ + } \ + extension_loaded++; \ + return (_function)(conffile); \ +} + +#ifdef __cplusplus +} +#endif + +#endif /* _EXTENSION_H */ diff --git a/plat/diameter/include/freeDiameter/freeDiameter-host.h.in b/plat/diameter/include/freeDiameter/freeDiameter-host.h.in new file mode 100644 index 0000000..bea8f99 --- /dev/null +++ b/plat/diameter/include/freeDiameter/freeDiameter-host.h.in @@ -0,0 +1,106 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Configuration from compile-time */ +#ifndef FD_IS_CONFIG +#define FD_IS_CONFIG + +#ifdef __cplusplus +extern "C" { +#endif + +#cmakedefine HAVE_NTOHLL +#cmakedefine HAVE_MALLOC_H +#cmakedefine HAVE_SIGNALENT_H +#cmakedefine HAVE_AI_ADDRCONFIG +#cmakedefine HAVE_CLOCK_GETTIME +#cmakedefine HAVE_STRNDUP +#cmakedefine HAVE_PTHREAD_BAR + +#cmakedefine HOST_BIG_ENDIAN @HOST_BIG_ENDIAN@ + +#cmakedefine DISABLE_SCTP +#cmakedefine DEBUG_SCTP +#cmakedefine DEBUG_WITH_META +#cmakedefine SCTP_USE_MAPPED_ADDRESSES +#cmakedefine SCTP_CONNECTX_4_ARGS +#cmakedefine SKIP_DLCLOSE +#cmakedefine DIAMID_IDNA_IGNORE +#cmakedefine DIAMID_IDNA_REJECT +#cmakedefine DISABLE_PEER_EXPIRY +#cmakedefine WORKAROUND_ACCEPT_INVALID_VSAI +#cmakedefine GNUTLS_VERSION_210 +#cmakedefine GNUTLS_VERSION_212 +#cmakedefine GNUTLS_VERSION_300 +#cmakedefine GNUTLS_VERSION_310 + +#cmakedefine ERRORS_ON_TODO +#cmakedefine DEBUG + +#cmakedefine FD_PROJECT_BINARY "@FD_PROJECT_BINARY@" +#cmakedefine FD_PROJECT_NAME "@FD_PROJECT_NAME@" +#cmakedefine FD_PROJECT_VERSION_MAJOR @FD_PROJECT_VERSION_MAJOR@ +#ifndef FD_PROJECT_VERSION_MAJOR +# define FD_PROJECT_VERSION_MAJOR 0 +#endif /*FD_PROJECT_VERSION_MAJOR*/ +#cmakedefine FD_PROJECT_VERSION_MINOR @FD_PROJECT_VERSION_MINOR@ +#ifndef FD_PROJECT_VERSION_MINOR +# define FD_PROJECT_VERSION_MINOR 0 +#endif /*FD_PROJECT_VERSION_MINOR*/ +#cmakedefine FD_PROJECT_VERSION_REV @FD_PROJECT_VERSION_REV@ +#ifndef FD_PROJECT_VERSION_REV +# define FD_PROJECT_VERSION_REV 0 +#endif /*FD_PROJECT_VERSION_REV*/ +#cmakedefine FD_PROJECT_VERSION_API @FD_PROJECT_VERSION_API@ +#ifndef FD_PROJECT_VERSION_API +# define FD_PROJECT_VERSION_API 0 +#endif /*FD_PROJECT_VERSION_API*/ +#cmakedefine FD_PROJECT_COPYRIGHT "@FD_PROJECT_COPYRIGHT@" + +#cmakedefine DEFAULT_CONF_PATH "@DEFAULT_CONF_PATH@" +#cmakedefine DEFAULT_EXTENSIONS_PATH "@DEFAULT_EXTENSIONS_PATH@" + +#ifndef FD_DEFAULT_CONF_FILENAME +#define FD_DEFAULT_CONF_FILENAME "freeDiameter.conf" +#endif /* FD_DEFAULT_CONF_FILENAME */ + +/* Maximum number of hooks handlers that can be registered. Make this compilation option if needed */ +#define FD_HOOK_HANDLE_LIMIT 5 + +#ifdef __cplusplus +} +#endif + +#endif /* FD_IS_CONFIG */ diff --git a/plat/diameter/include/freeDiameter/libfdcore.h b/plat/diameter/include/freeDiameter/libfdcore.h new file mode 100644 index 0000000..f9a1aff --- /dev/null +++ b/plat/diameter/include/freeDiameter/libfdcore.h @@ -0,0 +1,1216 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#ifndef _LIBFDCORE_H +#define _LIBFDCORE_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libfdproto.h" +#include +#include +#include + +/* GNUTLS version */ +#ifndef GNUTLS_VERSION +#define GNUTLS_VERSION LIBGNUTLS_VERSION +#endif /* GNUTLS_VERSION */ + +/* GNUTLS calls debug level */ +#ifndef GNUTLS_DBG_LEVEL +#define GNUTLS_DBG_LEVEL ANNOYING +#endif /* GNUTLS_DBG_LEVEL */ + + +/* Check the return value of a GNUTLS function, log and propagate */ +#define CHECK_GNUTLS_GEN( faillevel, __call__, __fallback__ ) { \ + CHECK_PRELUDE(__call__); \ + if (__ret__ < 0) { \ + LOG(faillevel, "TLS ERROR: in '%s' :\t%s", #__call__ , gnutls_strerror(__ret__)); \ + __fallback__; \ + } \ +} + +/* we use this macro to help debugging gnutls usage issues -- just change the content to display what you need */ +#define GNUTLS_TRACE( __call__) { \ + TRACE_CALL("Check: %s", #__call__ ); \ + (__call__); \ +} + + +#ifndef EXCLUDE_DEPRECATED +/* Macro for transition, replace with CHECK_GNUTLS_GEN */ +#define CHECK_GNUTLS_DO( __call__, __fallback__ ) \ + CHECK_GNUTLS_GEN( FD_LOG_ERROR, __call__, __fallback__ ) + +#endif /* EXCLUDE_DEPRECATED */ + + +/*============================================================*/ +/* INITIALIZATION */ +/*============================================================*/ + + +/* Initialize the libfdcore internals. This also initializes libfdproto */ +int fd_core_initialize(void); + +/* A string describing the version of the library */ +extern const char fd_core_version[]; + +/* Parse the freeDiameter.conf configuration file, load the extensions */ +int fd_core_parseconf(const char * conffile); + +/* Start the server & client threads */ +int fd_core_start(void); + +/* Block until the framework has completed its initialization -- useful for extensions */ +int fd_core_waitstartcomplete(void); + +/* Initialize shutdown of the framework */ +int fd_core_shutdown(void); + +/* Wait for the shutdown to be complete -- this should always be called after fd_core_shutdown */ +int fd_core_wait_shutdown_complete(void); + + +/*============================================================*/ +/* CONFIG */ +/*============================================================*/ + +/* Structure to hold the configuration of the freeDiameter daemon */ +#define EYEC_CONFIG 0xC011F16 +struct fd_config { + int cnf_eyec; /* Eye catcher: EYEC_CONFIG */ + + const char *cnf_file; /* Configuration file to parse, default is DEFAULT_CONF_FILE */ + + DiamId_t cnf_diamid; /* Diameter Identity of the local peer (FQDN -- ASCII) */ + size_t cnf_diamid_len;/* cached length of the previous string */ + DiamId_t cnf_diamrlm; /* Diameter realm of the local peer, default to realm part of cnf_diamid */ + size_t cnf_diamrlm_len;/* length of the previous string */ + + unsigned int cnf_timer_tc; /* The value in seconds of the default Tc timer */ + unsigned int cnf_timer_tw; /* The value in seconds of the default Tw timer */ + + char service_context_voice[128]; + char service_context_sms[128]; + uint16_t ro_voiceport;// yaxin + uint16_t ro_smsport;// yaxin + uint16_t cnf_port; /* the local port for legacy Diameter (default: 3868) in host byte order */ + uint16_t cnf_port_tls; /* the local port for Diameter/TLS (default: 5868) in host byte order */ + uint16_t cnf_port_3436; /* Open an additional server port to listen to old TLS/SCTP clients (RFC3436, freeDiameter versions < 1.2.0) */ + uint16_t cnf_sctp_str; /* default max number of streams for SCTP associations (def: 30) */ + struct fd_list cnf_endpoints; /* the local endpoints to bind the server to. list of struct fd_endpoint. default is empty (bind all). After servers are started, this is the actual list of endpoints including port information. */ + int cnf_thr_srv; /* Number of threads per servers handling the connection state machines */ + struct fd_list cnf_apps; /* Applications locally supported (except relay, see flags). Use fd_disp_app_support to add one. list of struct fd_app. */ + uint16_t cnf_dispthr; /* Number of dispatch threads to create */ + struct { + unsigned no_fwd : 1; /* the peer does not relay messages (0xffffff app id) */ + unsigned no_ip4 : 1; /* disable IP */ + unsigned no_ip6 : 1; /* disable IPv6 */ + unsigned no_tcp : 1; /* disable use of TCP */ + unsigned no_sctp: 1; /* disable the use of SCTP */ + unsigned pr_tcp : 1; /* prefer TCP over SCTP */ + unsigned tls_alg: 1; /* TLS algorithm for initiated cnx. 0: separate port. 1: inband-security (old) */ + } cnf_flags; + + struct { + int tls_disabled; + + /* Credentials parameters (backup) */ + char * cert_file; + char * key_file; + + char * ca_file; + int ca_file_nr; + char * crl_file; + + char * prio_string; + unsigned int dh_bits; + char * dh_file; + + /* GNUTLS parameters */ + gnutls_priority_t prio_cache; + gnutls_dh_params_t dh_cache; + + /* GNUTLS server credential(s) */ + gnutls_certificate_credentials_t credentials; /* contains local cert + trust anchors */ + #ifdef GNUTLS_VERSION_300 + gnutls_x509_trust_list_t trustlist; /* the logic to check local certificate has changed */ + #endif /* GNUTLS_VERSION_300 */ + + } cnf_sec_data; + + uint32_t cnf_orstateid; /* The value to use in Origin-State-Id, default to random value */ + struct dictionary *cnf_dict; /* pointer to the global dictionary */ + struct fifo *cnf_main_ev; /* events for the daemon's main (struct fd_event items) */ +}; +extern struct fd_config *fd_g_config; /* The pointer to access the global configuration, initalized in main */ + + + +/*============================================================*/ +/* PEERS */ +/*============================================================*/ + +/* States of a peer */ +enum peer_state { + /* Stable states */ + STATE_NEW = 0, /* The peer has been just been created, PSM thread not started yet */ + STATE_OPEN, /* Connexion established */ + + /* Peer state machine */ + STATE_CLOSED, /* No connection established, will re-attempt after TcTimer. */ + STATE_CLOSING, /* the connection is being shutdown (DPR/DPA in progress) */ + STATE_WAITCNXACK, /* Attempting to establish transport-level connection */ + STATE_WAITCNXACK_ELEC, /* Received a CER from this same peer on an incoming connection (other peer object), while we were waiting for cnx ack */ + STATE_WAITCEA, /* Connection established, CER sent, waiting for CEA */ + /* STATE_WAITRETURNS_ELEC, */ /* This state is not stable and therefore deprecated: + We have sent a CER on our initiated connection, and received a CER from the remote peer on another connection. Election. + If we win the election, we must disconnect the initiated connection and send a CEA on the other => we go to OPEN state. + If we lose, we disconnect the other connection (receiver) and fallback to WAITCEA state. */ + STATE_OPEN_HANDSHAKE, /* TLS Handshake and validation are in progress in open state -- we use it only for debug purpose, it is never displayed */ + + /* Failover state machine */ + STATE_SUSPECT, /* A DWR was sent and not answered within TwTime. Failover in progress. */ + STATE_REOPEN, /* Connection has been re-established, waiting for 3 DWR/DWA exchanges before putting back to service */ + + /* Ordering issues with multistream & state machine. -- see top of p_psm.c for explanation */ + STATE_OPEN_NEW, /* after CEA is sent, until a new message is received. Force ordering in this state */ + STATE_CLOSING_GRACE, /* after DPA is sent or received, give a short delay for messages in the pipe to be received. */ + + /* Error state */ + STATE_ZOMBIE /* The PSM thread is not running anymore; it must be re-started or peer should be deleted. */ +#define STATE_MAX STATE_ZOMBIE +}; +/* The following macro is called in freeDiameter/p_psm.c */ +#define DECLARE_STATE_STR() \ +const char *peer_state_str[] = { \ + "STATE_NEW" \ + , "STATE_OPEN" \ + , "STATE_CLOSED" \ + , "STATE_CLOSING" \ + , "STATE_WAITCNXACK" \ + , "STATE_WAITCNXACK_ELEC" \ + , "STATE_WAITCEA" \ + , "STATE_OPEN_HANDSHAKE" \ + , "STATE_SUSPECT" \ + , "STATE_REOPEN" \ + , "STATE_OPEN_NEW" \ + , "STATE_CLOSING_GRACE" \ + , "STATE_ZOMBIE" \ + }; +extern const char *peer_state_str[]; +#define STATE_STR(state) \ + (((unsigned)(state)) <= STATE_MAX ? peer_state_str[((unsigned)(state)) ] : "") + +/* Constants for the peer_info structure below */ +#define PI_P3_DEFAULT 0 /* Use any available protocol */ +#define PI_P3_IP 1 /* Use only IP to connect to this peer */ +#define PI_P3_IPv6 2 /* resp, IPv6 */ + +#define PI_P4_DEFAULT 0 /* Attempt any available protocol */ +#define PI_P4_TCP 1 /* Only use TCP */ +#define PI_P4_SCTP 2 /* Only use SCTP */ + +#define PI_ALGPREF_SCTP 0 /* SCTP is attempted first (default) */ +#define PI_ALGPREF_TCP 1 /* TCP is attempted first */ + +#define PI_SEC_DEFAULT 0 /* New TLS security (handshake after connection, protecting also CER/CEA) */ +#define PI_SEC_NONE 1 /* Transparent security with this peer (IPsec) */ +#define PI_SEC_TLS_OLD 2 /* Old TLS security (use Inband-Security-Id AVP during CER/CEA) */ + /* Set sec = 3 to authorize use of (Inband-Security-Id == NONE) with this peer, sec = 2 only authorizing TLS */ + +#define PI_SCTPSEC_DEF 0 /* Use DTLS over SCTP to connect to this peer (default) */ +#define PI_SCTPSEC_3436 1 /* Use TLS over SCTP to connect to this peer (RFC3436) */ + +#define PI_EXP_NONE 0 /* the peer entry does not expire */ +#define PI_EXP_INACTIVE 1 /* the peer entry expires (i.e. is deleted) after pi_lft seconds without activity */ + +#define PI_PRST_NONE 0 /* the peer entry is deleted after disconnection / error */ +#define PI_PRST_ALWAYS 1 /* the peer entry is persistant (will be kept as ZOMBIE in case of error) */ + +/* Information about a remote peer */ +struct peer_info { + + DiamId_t pi_diamid; /* (supposedly) UTF-8, \0 terminated. The Diameter Identity of the remote peer. */ + size_t pi_diamidlen; /* cached length of pi_diamid */ + + struct { + struct { + unsigned pro3 :2; /* PI_P3_* */ + unsigned pro4 :2; /* PI_P4_* */ + unsigned alg :1; /* PI_ALGPREF_* */ + unsigned sec :2; /* PI_SEC_* */ + unsigned sctpsec :1; /* PI_SCTPSEC_* */ + unsigned exp :1; /* PI_EXP_* */ + unsigned persist :1; /* PI_PRST_* */ + + } pic_flags; /* Flags influencing the connection to the remote peer */ + + DiamId_t pic_realm; /* If configured, the daemon will check the received realm in CER/CEA matches this. */ + uint16_t pic_port; /* port to connect to. 0: default. */ + + uint32_t pic_lft; /* lifetime of this peer when inactive (see pic_flags.exp definition) */ + int pic_tctimer; /* use this value for TcTimer instead of global, if != 0 */ + int pic_twtimer; /* use this value for TwTimer instead of global, if != 0 */ + + char * pic_priority; /* Priority string for GnuTLS if we don't use the default */ + + } config; /* Configured data (static for this peer entry) */ + + struct { + + /* enum peer_state pir_state; */ + /* Since 1.1.0, read the state with fd_peer_getstate(peer). */ + + DiamId_t pir_realm; /* The received realm in CER/CEA. */ + size_t pir_realmlen; /* length of the realm */ + + uint32_t pir_vendorid; /* Content of the Vendor-Id AVP, or 0 by default */ + uint32_t pir_orstate; /* Origin-State-Id value */ + os0_t pir_prodname; /* copy of Product-Name AVP (\0 terminated) */ + uint32_t pir_firmrev; /* Content of the Firmware-Revision AVP */ + int pir_relay; /* The remote peer advertized the relay application */ + struct fd_list pir_apps; /* applications advertised by the remote peer, except relay (pi_flags.relay) */ + int pir_isi; /* Inband-Security-Id advertised (PI_SEC_* bits) */ + + uint32_t pir_lastDC; /* The last Disconnect-Cause value received */ + + int pir_proto; /* The L4 protocol currently used with the peer (IPPROTO_TCP or IPPROTO_SCTP) */ + const gnutls_datum_t *pir_cert_list; /* The (valid) credentials that the peer has presented, or NULL if TLS is not used */ + /* This is inspired from http://www.gnu.org/software/gnutls/manual/gnutls.html#ex_003ax509_002dinfo + see there for example of using this data */ + unsigned int pir_cert_list_size; /* Number of certificates in the list */ + + } runtime; /* Data populated after connection, may change between 2 connections -- not used by fd_peer_add */ + + struct fd_list pi_endpoints; /* Endpoint(s) of the remote peer (configured, discovered, or advertized). list of struct fd_endpoint. DNS resolved if empty. */ +}; + + +struct peer_hdr { + struct fd_list chain; /* Link into the list of all the peers, ordered by their Diameter Id (fd_os_cmp) */ + struct peer_info info; /* The public data */ + + /* This header is followed by more data in the private peer structure definition */ +}; + +/* the global list of peers. + Since we are not expecting so many connections, we don't use a hash, but it might be changed. + The list items are peer_hdr structures (actually, fd_peer, but the cast is OK) */ +extern struct fd_list fd_g_peers; +extern pthread_rwlock_t fd_g_peers_rw; /* protect the list */ + +/* + * FUNCTION: fd_peer_add + * + * PARAMETERS: + * info : Information to create the peer. + * orig_dbg : A string indicating the origin of the peer information, for debug (ex: conf, redirect, ...) + * cb : optional, a callback to call (once) when the peer connection is established or failed + * cb_data : opaque data to pass to the callback. + * + * DESCRIPTION: + * Add a peer to the list of peers to which the daemon must maintain a connexion. + * + * The content of info parameter is copied, except for the list of endpoints if + * not empty, which is simply moved into the created object. It means that the list + * items must have been malloc'd, so that they can be freed. + * + * If cb is not null, the callback is called when the connection is in OPEN state or + * when an error has occurred. The callback should use the pi_state information to + * determine which one it is. If the first parameter of the called callback is NULL, it + * means that the peer is being destroyed before attempt success / failure. + * cb is called to allow freeing cb_data in * this case. + * + * The orig_dbg string is only useful for easing debug, and can be left to NULL. + * + * RETURN VALUE: + * 0 : The peer is added. + * EINVAL : A parameter is invalid. + * EEXIST : A peer with the same Diameter-Id is already in the list. + * (other standard errors may be returned, too, with their standard meaning. Example: + * ENOMEM : Memory allocation for the new object element failed.) + */ +int fd_peer_add ( struct peer_info * info, const char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data ); + +/* + * FUNCTION: fd_peer_getbyid + * + * PARAMETERS: + * diamid : an UTF8 string describing the diameter Id of the peer to seek + * diamidlen : length of the diamid + * igncase : perform an almost-case-insensitive search? (slower) + * peer : The peer is stored here if it exists. + * + * DESCRIPTION: + * Search a peer by its Diameter-Id. + * + * RETURN VALUE: + * 0 : *peer has been updated (to NULL if the peer is not found). + * !0 : An error occurred. + */ +int fd_peer_getbyid( DiamId_t diamid, size_t diamidlen, int igncase, struct peer_hdr ** peer ); + +/* + * FUNCTION: fd_peer_get_state + * + * PARAMETERS: + * peer : The peer which state to read + * + * DESCRIPTION: + * Returns the current state of the peer. + * + * RETURN VALUE: + * -1 : peer is invalid + * >=0 : the state of the peer at the time of reading. + */ +int fd_peer_get_state(struct peer_hdr *peer); + +/* + * FUNCTION: fd_peer_cnx_proto_info + * + * PARAMETERS: + * peer : The peer which information to be read + * buf : Where to store the protocol information + * len : available space in bug + * + * DESCRIPTION: + * Creates a string describing the current connection to this peer, e.g.: "TCP,TLS,soc#3". + * + * RETURN VALUE: + * 0 : buffer was written + * >=0 : error code. + */ +int fd_peer_cnx_proto_info(struct peer_hdr *peer, char * buf, size_t len); + +/* + * FUNCTION: fd_peer_get_load_pending + * + * PARAMETERS: + * peer : The peer which load to read + * to_receive : (out) number of requests sent to this peer without matching answer yet. + * to_send : (out) number of requests received from this peer and not yet answered. + * + * DESCRIPTION: + * Returns the current number of requests sent to this peer + * that have not been answered yet. This is an empirical indication + * of the workload of this peer. + * + * RETURN VALUE: + * 0 : The load parameter has been updated. (it should have a positive value always) + * !0 : An error occurred + */ +int fd_peer_get_load_pending(struct peer_hdr *peer, long * to_receive, long * to_send); + +/* + * FUNCTION: fd_peer_validate_register + * + * PARAMETERS: + * peer_validate : Callback as defined below. + * + * DESCRIPTION: + * Add a callback to authorize / reject incoming peer connections. + * All registered callbacks are called until a callback sets auth = -1 or auth = 1. + * If no callback returns a clear decision, the default behavior is applied (reject unknown connections) + * The callbacks are called in FILO order of their registration. + * + * RETURN VALUE: + * 0 : The callback is added. + * !0 : An error occurred. + */ +int fd_peer_validate_register ( int (*peer_validate)(struct peer_info * /* info */, int * /* auth */, int (**cb2)(struct peer_info *)) ); +/* + * CALLBACK: peer_validate + * + * PARAMETERS: + * info : Structure containing information about the peer attempting the connection. + * auth : Store there the result if the peer is accepted (1), rejected (-1), or unknown (0). + * cb2 : If != NULL and in case of PI_SEC_TLS_OLD, another callback to call after handshake (if auth = 1). + * + * DESCRIPTION: + * This callback is called when a new connection is being established from an unknown peer, + * after the CER is received. An extension must register such callback with peer_validate_register. + * + * The callback can learn if the peer has sent Inband-Security-Id AVPs in runtime.pir_isi fields. + * It can also learn if a handshake has already been performed in runtime.pir_cert_list field. + * The callback must set the value of config.pic_flags.sec appropriately to allow a connection without TLS. + * + * If the old TLS mechanism is used, + * the extension may also need to check the credentials provided during the TLS + * exchange (remote certificate). For this purpose, it may set the address of a new callback + * to be called once the handshake is completed. This new callback receives the information + * structure as parameter (with pir_cert_list set) and returns 0 if the credentials are correct, + * or an error code otherwise. If the error code is received, the connection is closed and the + * peer is destroyed. + * Note that freeDiameter already achieves some usual checks. The callback may be used to enforce + * additional restrictions. + * + * RETURN VALUE: + * 0 : The authorization decision has been written in the location pointed by auth. + * !0 : An error occurred. + */ + + + +/*============================================================*/ +/* MESSAGES */ +/*============================================================*/ + +/* + * FUNCTION: fd_msg_send, fd_msg_send_timeout + * + * PARAMETERS: + * pmsg : Location of the message to be sent on the network (set to NULL on function return to avoid double deletion). + * anscb : A callback to be called when corresponding answer is received, when sending a request (not used with answers) + * anscb_data : opaque data to be passed back to the anscb (or expirecb) when it is called. + * expirecb : (only for fd_msg_send_timeout) If the request did not get an answer before timeout, this callback is called. + * timeout : (only for fd_msg_send_timeout) sets the absolute time until when to wait for an answer. Past this time, + * the expirecb is called with the request and the answer will be discarded if received later. + * + * DESCRIPTION: + * Sends a message on the network. (actually simply queues it in a global queue, to be picked by a daemon's thread) + * For requests, the end-to-end id must be set (see fd_msg_get_eteid / MSGFL_ALLOC_ETEID). + * For answers, the message must be created with function fd_msg_new_answer_from_req. + * + * The routing module will handle sending to the correct peer, usually based on the Destination-Realm / Destination-Host AVP. + * + * If the msg is a request, there are two ways of receiving the answer: + * - either having registered a callback in the dispatch module (see fd_disp_register) + * - or provide a anscb callback here. If such callback is provided, it is called before the dispatch callbacks. + * The prototype for this anscb callback function is: + * void anscb(void * data, struct msg ** answer) + * where: + * data : opaque data that was registered along with the callback. + * answer : location of the pointer to the answer. + * note1: on function return, if *answer is not NULL, the message is passed to the dispatch module for regular callbacks. + * otherwise, the callback must take care of freeing the message (fd_msg_free). + * note2: the opaque data is not freed by the daemon in any case, extensions should ensure clean handling in fd_ext_fini. + * + * If no callback is registered to handle an answer, the message is discarded and an error is logged. + * + * fd_msg_send_timeout is similar to fd_msg_send, except that it takes two additional arguments "expirecb" and "timeout". + * If the message parameter is an answer, there is no difference with fd_msg_send. + * Otherwise, if the corresponding answer (or error) is received before the timeout date elapses, everything occurs as with fd_msg_send. + * Otherwise, the request is removed from the queue (meaning the matching answer will be discarded upon reception) and passed to the expirecb + * function. Upon return, if the *msg parameter is not NULL, it is freed (not passed to other callbacks). + * expirecb is called in a dedicated thread. + * + * The prototype for the expirecb callback function is: + * void expirecb(void * data, struct peer_hdr * sentto, struct msg ** request) + * where: + * data : opaque data that was registered along with the callback. + * sentto : pointer to the peer to which the message was sent and no answer received within timeout. + * request: location of the pointer to the request that was not answered. + * + * RETURN VALUE: + * 0 : The message has been queued for sending (sending may fail asynchronously). + * EINVAL : A parameter is invalid (ex: anscb provided but message is not a request). + * ... + */ +int fd_msg_send ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data ); +int fd_msg_send_timeout ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ); + +/* + * FUNCTION: fd_msg_rescode_set + * + * PARAMETERS: + * msg : A msg object -- it must be an answer. + * rescode : The name of the returned error code (ex: "DIAMETER_INVALID_AVP") + * errormsg : (optional) human-readable error message to put in Error-Message AVP + * optavp : (optional) If provided, the content will be put inside a Failed-AVP + * type_id : 0 => nothing; 1 => adds Origin-Host and Origin-Realm with local info. 2=> adds Error-Reporting-Host. + * + * DESCRIPTION: + * This function adds a Result-Code AVP to a message, and optionally + * - sets the 'E' error flag in the header, + * - adds Error-Message, Error-Reporting-Host and Failed-AVP AVPs. + * + * RETURN VALUE: + * 0 : Operation complete. + * !0 : an error occurred. + */ +int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id ); + +/* Add Origin-Host, Origin-Realm, (if osi) Origin-State-Id AVPS at the end of the message */ +int fd_msg_add_origin ( struct msg * msg, int osi ); + +/* Generate a new Session-Id and add it at the beginning of the message (opt is added at the end of the sid if provided) */ +int fd_msg_new_session( struct msg * msg, os0_t opt, size_t optlen ); + + +/* Parse a message against our dictionary, + return 0 in case of success. + log parsing error & return error code in case of failure in parsing. + In addition, if the error code is EBADMSG (the message does not follow our dictionary) + if *msg was a request, *msg is NULL and *error contains the error message ready to send back on return + if *msg was an answer, *msg is untouched and *error==*msg if *msg was an error message, *error is null otherwise */ +int fd_msg_parse_or_error( struct msg ** msg, struct msg **error ); + + + + +/*============================================================*/ +/* DISPATCH */ +/*============================================================*/ + +/* + * FUNCTION: fd_disp_app_support + * + * PARAMETERS: + * app : The dictionary object corresponding to the Application. + * vendor : (Optional) the dictionary object of a Vendor to claim support in Vendor-Specific-Application-Id + * auth : Support auth app part. + * acct : Support acct app part. + * + * DESCRIPTION: + * Registers an application to be advertized in CER/CEA exchanges. + * Messages with an application-id matching a registered value are passed to the dispatch module, + * while other messages are simply relayed or an error is returned (if local node does not relay) + * + * RETURN VALUE: + * 0 : The application support is registered. + * EINVAL : A parameter is invalid. + */ +int fd_disp_app_support ( struct dict_object * app, struct dict_object * vendor, int auth, int acct ); + +/* Note: if we want to support capabilities updates, we'll have to add possibility to remove an app as well... */ + + +/*============================================================*/ +/* ROUTING */ +/*============================================================*/ + +/* This file contains the definitions of types and functions involved in the routing decisions in freeDiameter, + * and that can be called by extensions. + * + * Three different type of messages must be distinguished: + * - Messages received, and the peer is final recipient (IN messages) + * - Messages received, and the peer is not final recipient (FWD messages) + * - Message is locally generated (OUT messages) + * + * There are three global message queues (in queues.c) and also peers-specific queues (in struct fd_peer). + * + * (*) IN messages processing details: + * - the message is received from the remote peer, a FDEVP_CNX_MSG_RECV event is generated for the peer. + * - the PSM thread parses the buffer, does some verifications, handles non routable messages (fd_msg_is_routable) + * - routable messages are queued in the fd_g_incoming global queue. + * - a thread (routing-in) picks the message and takes the decision if it is handled locally or forwarded, + * based on local capabilities (registered by extensions with fd_disp_app_support). + * - If the message is handled locally, it is queued in fd_g_local. + * - Another thread (dispatch.c) will handle this message and pass it to registered callbacks (see fd_disp_register in libfreeDiameter.h). + * + * (*) FWD messages details: + * - The process is the same as for IN messages, until the routing-in threads makes its decision that the message is not handled locally. + * - If the local peer does not relay message, an error DIAMETER_APPLICATION_UNSUPPORTED is returned. + * - All callbacks registered with fd_rt_fwd_register are called for the message (see below). + * - these callbacks will typically do proxying work. Note that adding the route-record is handled by the daemon. + * - Once all callbacks have been called, the message is queued in the global fd_g_outgoing queue. + * - The remaining processing is the same as for OUT messages, as described below. + * + * (*) OUT messages details: + * - The message are picked from fd_g_outgoing (they are queued there as result of forwarding process or call to fd_msg_send.) + * - The (routing-out) thread builds a list of possible destinations for the message, as follow: + * - create a list of all known peers in the "OPEN" state. + * - remove from that list all peers that are in a Route-Record AVP of the message, to avoid routing loops. + * - remove also all peers that have previously replied an error message for this message. + * - If the list is empty, create an error UNABLE_TO_DELIVER (note: should we trig dynamic discovery here???) and reply. + * - Otherwise, call all callbacks registered by function fd_rt_out_register, with the list of peers and the message. + * - Order the resulting list of peers by score (see below), and sent the message to the peer with highest (positive) score. + * - in case the peer is no longer in the "OPEN" state, send the message to the second peer in the list. + * - if no peer is in OPEN state anymore, restart the process of creating the list. + * - Once a peer has been selected, the message is queued into that peer's outgoing queue. + * + * The following functions allow an extension to register or remove a callback as described above. + */ + +/********** Forwarding callbacks: for Proxy operations ***********/ + +/* Handle to registered callback */ +struct fd_rt_fwd_hdl; + +/* Message direction for the callback */ +enum fd_rt_fwd_dir { + RT_FWD_REQ = 1, /* The callback will be called on forwarded requests only */ + RT_FWD_ALL = 2, /* The callback will be called on all forwarded messages (requests and answers )*/ + RT_FWD_ANS = 3 /* The callback will be called on answers and errors only */ +}; + +/* + * FUNCTION: fd_rt_fwd_register + * + * PARAMETERS: + * rt_fwd_cb : The callback function to register (see prototype below). + * cbdata : Pointer to pass to the callback when it is called. The data is opaque to the daemon. + * dir : One of the RT_FWD_* directions defined above. + * handler : On success, a handler to the registered callback is stored here. + * This handler will be used to unregister the cb. + * + * DESCRIPTION: + * Register a new callback for forwarded messages. See explanations above. + * Note that there is no guaranteed order for the callbacks calls. + * + * RETURN VALUE: + * 0 : The callback is registered. + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_rt_fwd_register ( int (*rt_fwd_cb)(void * cbdata, struct msg ** msg), void * cbdata, enum fd_rt_fwd_dir dir, struct fd_rt_fwd_hdl ** handler ); +/* + * CALLBACK: rt_fwd_cb + * + * PARAMETERS: + * data : pointer to some data that was passed when the callback was registered (optional). + * msg : The message that is being forwarded. + * + * DESCRIPTION: + * This callback is called when a message is forwarded to another peer. It may for example add a Proxy-Info AVP. + * The callback may also choose to handle the message in a more complex form. In that case, it must set *msg = NULL + * and handle it differently. In such case, the forwarding thread will stop processing this message. + * + * RETURN VALUE: + * 0 : Operation complete. + * !0 : An error occurred -- will result in daemon's termination. + */ + +/* + * FUNCTION: fd_rt_fwd_unregister + * + * PARAMETERS: + * handler : The handler of the callback that must be unregistered. + * cbdata : Will receive the data registered with the callback, that can be freed if needed. + * + * DESCRIPTION: + * Removes a callback from the list of registered callbacks. + * + * RETURN VALUE: + * 0 : The callback is unregistered. + * EINVAL : A parameter is invalid. + */ +int fd_rt_fwd_unregister ( struct fd_rt_fwd_hdl * handler, void ** cbdata ); + + +/********** Out callbacks: for next hop routing decision operations ***********/ + +/* Handle to registered callback */ +struct fd_rt_out_hdl; + +enum fd_rt_out_score { + FD_SCORE_NO_DELIVERY = -70, /* We should not send this message to this candidate */ + FD_SCORE_SENT_REDIRECT = -60, /* If this peer previously sent a Redirect indication that applies to this message */ + FD_SCORE_INI = -2, /* All candidates are initialized with this value */ + FD_SCORE_LOAD_BALANCE = 1, /* Use this to differentiate between several peers with the same score */ + FD_SCORE_DEFAULT = 5, /* The peer is a default route for all messages */ + FD_SCORE_DEFAULT_REALM = 10, /* The peer is a default route for this realm */ + FD_SCORE_REALM = 15, /* The peer belongs to Destination-Realm of the message */ + FD_SCORE_REDIR_HOST = 25, /* If there is a redirect rule with ALL_HOST for these message and peer */ + FD_SCORE_REDIR_APP = 30, /* If there is a redirect rule with ALL_APPLICATION for these message and peer */ + FD_SCORE_REDIR_REALM = 35, /* If there is a redirect rule with ALL_REALM for these message and peer */ + FD_SCORE_REDIR_REALM_APP = 40, /* If there is a redirect rule with REALM_AND_APPLICATION for these message and peer */ + FD_SCORE_REDIR_USER = 45, /* If there is a redirect rule with ALL_USER for these message and peer */ + FD_SCORE_REDIR_SESSION = 50, /* If there is a redirect rule with ALL_SESSION for these message and peer */ + FD_SCORE_REDIR_ONCE = 55, /* If there is a redirect rule with DONT_CACHE for these message and peer */ + FD_SCORE_FINALDEST = 100 /* If the peer is the final recipient of the message (i.e. matching Destination-Host), it receives a big score. */ +}; + +/* + * FUNCTION: fd_rt_out_register + * + * PARAMETERS: + * rt_out_cb : The callback function to register (see prototype below). + * cbdata : Pointer to pass to the callback when it is called. The data is opaque to the daemon. + * priority : Order for calling this callback. The callbacks are called in reverse priority order (higher priority = called sooner). + * handler : On success, a handler to the registered callback is stored here. + * This handler will be used to unregister the cb. + * + * DESCRIPTION: + * Register a new callback to handle OUT routing decisions. See explanations above. + * + * RETURN VALUE: + * 0 : The callback is registered. + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_rt_out_register ( int (*rt_out_cb)(void * cbdata, struct msg ** pmsg, struct fd_list * candidates), void * cbdata, int priority, struct fd_rt_out_hdl ** handler ); +/* + * CALLBACK: rt_out_cb + * + * PARAMETERS: + * cbdata : pointer to some data that was registered with the callback. + * pmsg : pointer to the message that must be sent. upon return if *msg is NULL, the processing stops and the message is not sent. + * list : The list of peers to which the message may be sent to, as returned by fd_rtd_candidate_extract + * + * DESCRIPTION: + * This callback must attribute a score (preferably from FD_SCORE_*) to each candidate peer in the list. + * Once all registered callbacks have been called, the message is sent to the candidate with the highest score. + * Note that each callback must *add* its locally-attributed score to the candidate current "score" parameter, not replace it! + * Note also that this callback must be re-entrant since it may be called by several threads at the same time + * (for different messages) + * + * RETURN VALUE: + * 0 : Operation complete. + * !0 : An error occurred. + */ + +/* + * FUNCTION: fd_rt_out_unregister + * + * PARAMETERS: + * handler : The handler of the callback that must be unregistered. + * cbdata : Will receive the data registered with the callback, that can be freed if needed. + * + * DESCRIPTION: + * Removes a callback from the list of registered callbacks. + * + * RETURN VALUE: + * 0 : The callback is unregistered. + * EINVAL : A parameter is invalid. + */ +int fd_rt_out_unregister ( struct fd_rt_out_hdl * handler, void ** cbdata ); + + +/*============================================================*/ +/* EVENTS */ +/*============================================================*/ + +struct fd_event { + int code; /* codespace depends on the queue */ + size_t size; + void *data; +}; + +/* Daemon's codespace: 1000->1999 (1500->1999 defined in fdcore-internal.h) */ +enum { + FDEV_TERMINATE_INT= 1000 /* request to terminate. DO NOT USE. Use fd_core_shutdown() instead. */ + ,FDEV_TRIGGER /* Trigger available for extensions. size is sizeof(int), data is int * */ +}; + +int fd_event_send(struct fifo *queue, int code, size_t datasz, void * data); +int fd_event_get(struct fifo *queue, int * code, size_t * datasz, void ** data); +int fd_event_timedget(struct fifo *queue, struct timespec * timeout, int timeoutcode, int * code, size_t * datasz, void ** data); +void fd_event_destroy(struct fifo **queue, void (*free_cb)(void * data)); +const char * fd_ev_str(int event); + +/* for extensions */ +int fd_event_trig_regcb(int trigger_val, const char * module, void (*cb)(void)); + +#ifndef SWIG +DECLARE_FD_DUMP_PROTOTYPE(fd_event_trig_dump); + +/* The "old" FD_EV_DUMP_* events are replaced with direct calls to the following dump functions */ +DECLARE_FD_DUMP_PROTOTYPE(fd_conf_dump); + +DECLARE_FD_DUMP_PROTOTYPE(fd_ext_dump); +#else /* SWIG */ +DECLARE_FD_DUMP_PROTOTYPE_simple(fd_event_trig_dump); +DECLARE_FD_DUMP_PROTOTYPE_simple(fd_conf_dump); +DECLARE_FD_DUMP_PROTOTYPE_simple(fd_ext_dump); +#endif /* SWIG */ +DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump, int details); +DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump_list, int details); +DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump, struct peer_hdr * p, int details); + +/*============================================================*/ +/* ENDPOINTS */ +/*============================================================*/ + +struct fd_endpoint { + struct fd_list chain; /* link in cnf_endpoints list */ + + union { + sSS ss; /* the socket information. List is always ordered by ss value (memcmp) -- see fd_ep_add_merge */ + sSA4 sin; + sSA6 sin6; + sSA sa; + } +#ifdef SWIG /* nested anonymous unions are not supported yet */ + s +#endif /* SWIG */ + ; + +#define EP_FL_CONF (1 << 0) /* This endpoint is statically configured in a configuration file */ +#define EP_FL_DISC (1 << 1) /* This endpoint was resolved from the Diameter Identity or other DNS query */ +#define EP_FL_ADV (1 << 2) /* This endpoint was advertized in Diameter CER/CEA exchange */ +#define EP_FL_LL (1 << 3) /* Lower layer mechanism provided this endpoint */ +#define EP_FL_PRIMARY (1 << 4) /* This endpoint is primary in a multihomed SCTP association */ +#define EP_ACCEPTALL (1 << 15) /* This flag allows bypassing the address filter in fd_ep_add_merge. */ + uint32_t flags; /* Additional information about the endpoint */ + + /* To add: a validity timestamp for DNS records ? How do we retrieve this lifetime from DNS ? */ +}; + +int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, uint32_t flags ); +int fd_ep_filter( struct fd_list * list, uint32_t flags ); +int fd_ep_filter_family( struct fd_list * list, int af ); +int fd_ep_clearflags( struct fd_list * list, uint32_t flags ); +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, int preamble, struct fd_endpoint * ep ); +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int preamble, int indent, struct fd_list * eps ); + + +/*============================================================*/ +/* APPLICATIONS IDs */ +/*============================================================*/ + +struct fd_app { + struct fd_list chain; /* link in cnf_apps list. List ordered by appid. */ + struct { + unsigned auth : 1; + unsigned acct : 1; + } flags; + vendor_id_t vndid; /* if not 0, Vendor-Specific-App-Id AVP will be used */ + application_id_t appid; /* The identifier of the application */ +}; + +int fd_app_merge(struct fd_list * list, application_id_t aid, vendor_id_t vid, int auth, int acct); +int fd_app_check(struct fd_list * list, application_id_t aid, struct fd_app **detail); +int fd_app_check_common(struct fd_list * list1, struct fd_list * list2, int * common_found); +int fd_app_empty(struct fd_list * list); + + + +/*============================================================*/ +/* MONITORING */ +/*============================================================*/ + +/* These functions allow an extension to collect state information about the + * framework, as well as being hooked at some key checkpoints in the processing + * for logging or statistics purpose. + */ + + +/* CALLBACK: fd_hook_cb + * + * PARAMETERS: + * type : The type of hook that triggered this call, in case same cb is registered for several hooks. + * msg : If relevant, the pointer to the message triggering the call. NULL otherwise. + * peer : If relevant, the pointer to the peer associated with the call. NULL otherwise. + * other : For some callbacks, the remaining information is passed in this parameter. See each hook detail. + * permsgdata : Structure associated with a given message, across several hooks. + * A different structure is associated with requests and corresponding answers. + * See fd_hook_data_hdl below for details. + * If no fd_hook_data_hdl is registered with this callback, this parameter is always NULL + * regdata : Data pointer stored at registration, opaque for the framework. + * + * DESCRIPTION: + * When such callback is registered with fd_hook_register function, it will be called on matching events with + * the parameters as described in the list of fd_hook_type below. One can use this mechanism for e.g.: + * - log completely the messages for safety / backup + * - create statistics information on the throughput + * - ... + * + * IMPORTANT: the callback MUST NOT change the memory pointed by the different parameters (peer, message, ...) + * + * RETURN VALUE: + * none. + */ + +/* The available hooks in the framework */ +enum fd_hook_type { + + HOOK_DATA_RECEIVED = 0, + /* Hook called as soon as a message has been received from the network, after TLS & boundary processing. + - {msg} is NULL. + - {peer} is NULL. + - {other} is a pointer to a struct fd_cnx_rcvdata containing the received buffer. + - {permsgdata} points to either a new empty structure allocated for this message (cf. fd_hook_data_hdl), or NULL if no hdl is registered. + */ + + HOOK_MESSAGE_RECEIVED, + /* Hook called when a message has been received and the structure has been parsed successfully (list of AVPs). + - {msg} points to the parsed message. At this time, the objects have not been dictionary resolved. If you + try to call fd_msg_parse_dict, it will slow down the operation of a relay agent. + - {peer} is set if the message is received from a peer's connection, and NULL if the message is from a new client + connected and not yet identified + - {other} is NULL, or a char * identifying the connection when {peer} is null. + - {permsgdata} points to either a new empty structure allocated for this message or the one passed to HOOK_DATA_RECEIVED if used. + */ + + HOOK_MESSAGE_LOCAL, + /* Hook called when a request message has been created locally by an extension and is being sent. + - {msg} points to the message. + - {peer} is NULL + - {other} is NULL + - {permsgdata} points to a new empty structure allocated for this request (cf. fd_hook_data_hdl) + */ + + HOOK_MESSAGE_SENDING, + /* Hook called when a message is about to be sent to a peer. The message pointer cannot be modified here, but the content of the message + could still be changed (for example add or remove some AVP. This is the last chance. + - {msg} points to the message. Some objects may not have been dictionary resolved. If you + try to call fd_msg_parse_dict, it will slow down the operation of the instance. + - {peer} is the one the message is being sent to. + - {other} is NULL. + - {permsgdata} points to existing structure if any, or a new structure otherwise. + */ + + HOOK_MESSAGE_SENT, + /* Hook called when a message has been sent to a peer. The message might be freed as soon as the hook function returns, + so it is not safe to store the pointer for asynchronous processing. + - {msg} points to the sent message. Again, the objects may not have been dictionary resolved. If you + try to call fd_msg_parse_dict, it will slow down the operation of a relay agent. + - {peer} is set if the message is sent to a peer's connection, and NULL if the message is sent to a new client + connected and not yet identified, or being rejected + - {other} is NULL. + - {permsgdata} points to existing structure if any, or a new structure otherwise. + */ + + HOOK_MESSAGE_FAILOVER, + /* Hook called when a message that was sent to a peer is being requeued, because e.g. the connection was torn down. + In that case the message will go again through the routing process. + - {msg} points to the corresponding request message (the answer is discarded). Again, the objects may not have been dictionary resolved. If you + try to call fd_msg_parse_dict, it might slow down the operation of a relay agent, although this hook is not on the normal execution path. + - {peer} is the peer this message was previously sent to. + - {other} is NULL. + - {permsgdata} points to existing structure if any, or a new structure otherwise. + */ + + HOOK_MESSAGE_PARSING_ERROR, + /* Hook called when a message being processed cannot be parsed successfully. + - {msg} points to the message if buffer was parsed successfully, or NULL otherwise. You should not call fd_msg_parse_dict on this in any case. + - {peer} is NULL or the peer that received the message. If NULL and the message is not NULL, you can still retrieve the source from the message itself. + - {other} is a char * pointer to the error message (human-readable) if {msg} is not NULL, a pointer to struct fd_cnx_rcvdata containing the received buffer otherwise. + - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered). + */ + + HOOK_MESSAGE_ROUTING_ERROR, + /* Hook called when a message being processed by the routing thread meets an error such as no remaining available peer for sending, based on routing callbacks decisions (maybe after retries). + - {msg} points to the message. Again, the objects may not have been dictionary resolved. If you + try to call fd_msg_parse_dict, it might slow down the operation of a relay agent, although this hook is not on the normal execution path. + - {peer} is NULL. + - {other} is a char * pointer to the error message (human-readable). + - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered). + */ + + HOOK_MESSAGE_ROUTING_FORWARD, + /* Hook called when a received message is deemed to be not handled locally by the routing_dispatch process. + The decision of knowing which peer it will be sent to is not made yet (or if an error will be returned). + The hook is trigged before the callbacks registered with fd_rt_fwd_register are called. + - {msg} points to the message. Again, the objects may not have been dictionary resolved. + If you try to call fd_msg_parse_dict, it will slow down the operation of a relay agent. + - {peer} is NULL. + - {other} is NULL. + - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered). + */ + + HOOK_MESSAGE_ROUTING_LOCAL, + /* Hook called when a received message is handled locally by the routing_dispatch process (i.e., not forwarded). + The hook is trigged before the callbacks registered with fd_disp_register are called. + - {msg} points to the message. Here, the message has been already parsed completely & successfully. + - {peer} is NULL. + - {other} is NULL. + - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered). + */ + + HOOK_MESSAGE_DROPPED, + /* Hook called when a message is being discarded by the framework because of some error condition (normal or abnormal). + It is probably a good idea to log this for analysis / backup. + - {msg} points to the message, which will be freed as soon as the hook returns. + - {peer} may be NULL or a peer related to the event. + - {other} is a char * pointer to the error message (human-readable). + - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered). + */ + + HOOK_PEER_CONNECT_FAILED, + /* Hook called when a connection attempt to/from a remote peer has failed. This hook is also called when the peer was in OPEN state and the connection is broken. + - {msg} may be NULL (lower layer error, e.g. connection timeout) or points to a message showing the error (either invalid incoming message, or the CEA message sent or received with an error code). + - {peer} may be NULL for incoming requests from unknown peers being rejected, otherwise it points to the peer structure associated with the attempt. + - {other} is a char * pointer to the error message (human-readable). + - {permsgdata} is always NULL for this hook. + */ + + HOOK_PEER_CONNECT_SUCCESS, + /* Hook called when a connection attempt to/from a remote peer has succeeded (the peer moves to OPEN_HANDSHAKE or OPEN state). + In case of deprecated TLS handshake after the CER/CEA exchange, this hook can still be followed by HOOK_PEER_CONNECT_FAILED if TLS handshake fails. + - {msg} points to the CEA message sent or received (with a success code) -- in case it is sent, you can always get access to the matching CER. + - {peer} points to the peer structure. + - {other} is NULL. + - {permsgdata} is always NULL for this hook. + */ + + HOOK_MESSAGE_PARSING_ERROR2, + /* Hook called after an error message has been generated due to a dictionary parsing error. + - {msg} points to the error message that has been generated. + - {peer} is NULL. You can still retrieve the source from the message itself. + - {other} is NULL + - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered). + Use this hook if you need to populate more data in the error being returned, from the error message. + (e.g. some AVP need to be added to replies even if error case. + */ +#define HOOK_LAST HOOK_MESSAGE_PARSING_ERROR2 +}; + + +/* Type of the {permsgdata} pointer. It is up to each extension to define its own structure. This is opaque for the framework. */ +struct fd_hook_permsgdata; + +/* A handle that will be associated with the extension, and with the permsgdata structures. */ +struct fd_hook_data_hdl; + +/* The following structure is what is passed to the HOOK_DATA_RECEIVED hook */ +struct fd_cnx_rcvdata { + size_t length; + uint8_t * buffer; /* internal note: the buffer is padded with a struct fd_msg_pmdl, not accounted for in length */ +}; + +/* Function to register a new fd_hook_data_hdl. Should be called by your extension init function. + * The arguments are the functions called to initialize a new fd_hook_permsgdata and to free this structure when the corresponding message is being freed. + */ +/* + * FUNCTION: fd_hook_data_register + * + * PARAMETERS: + * permsgdata_size : the size of the fd_hook_permsgdata structure. + * permsgdata_init_cb : function called to initialize a new fd_hook_permsgdata structure, when a hook will be called for a message that does not have such structure yet. + * The memory is already allocated and blanked, so you can pass NULL if no further handling is required. + * permsgdata_fini_cb : function called when a message is being disposed. It should free the resources associated with the fd_hook_permsgdata. + * You can pass NULL if no special handling is required. The memory of the permsgdata structure itself will be freed by the framework. + * new_handle : On success, a handler to the registered callback is stored here. + * This handler will be used to unregister the cb. + * + * DESCRIPTION: + * Register a new fd_hook_data_hdl. This handle is used during hooks registration (see below) in order to associate data with the messages, to allow keeping tracking of the message easily. + * Note that these handlers are statically allocated and cannot be unregistered. FD_HOOK_HANDLE_LIMIT handlers can be registered at maximum (recompile libfdproto if you change this value) + * + * RETURN VALUE: + * 0 : The callback is registered. + * EINVAL : A parameter is invalid. + * ENOSPC : Too many handles already registered. You may need to increase the limit in the code. + */ +int fd_hook_data_register( + size_t permsgdata_size, + void (*permsgdata_init_cb) (struct fd_hook_permsgdata *), + void (*permsgdata_fini_cb) (struct fd_hook_permsgdata *), + struct fd_hook_data_hdl **new_handle +); + +/* A handler associated with a registered hook callback (for cleanup) */ +struct fd_hook_hdl; + +/* Helper for building a mask of hooks for registration */ +#define HOOK_MASK(hooklist...) fd_hook_mask_helper(0, ## hooklist, -1) + +/* + * FUNCTION: fd_hook_register + * + * PARAMETERS: + * type_mask : A bitmask of fd_hook_type bits for which this cb is registered, e.g. HOOK_MASK( HOOK_MESSAGE_RECEIVED, HOOK_MESSAGE_SENT ) + * fd_hook_cb : The callback function to register (see prototype above). + * regdata : Pointer to pass to the callback when it is called. The data is opaque to the daemon. + * data_hdl : If permsgdata is requested for the hooks, a handler registered with fd_hook_data_register. NULL otherwise. + * handler : On success, a handler to the registered callback is stored here. + * This handler can be used to unregister the cb. + * + * DESCRIPTION: + * Register a new hook in the framework. See explanations above. + * + * RETURN VALUE: + * 0 : The callback is registered. + * EEXIST : Another callback is already registered for this type of hook (HOOK_DATA_RECEIVED). + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_hook_register ( uint32_t type_mask, + void (*fd_hook_cb)(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata), + void *regdata, + struct fd_hook_data_hdl *data_hdl, + struct fd_hook_hdl ** handler ); + +/* Remove a hook registration */ +int fd_hook_unregister( struct fd_hook_hdl * handler ); + + +/* Use the following function to retrieve any pmd structure associated with a request matching the current answer. Returns NULL in case of error / no such structure */ +struct fd_hook_permsgdata * fd_hook_get_request_pmd(struct fd_hook_data_hdl *data_hdl, struct msg * answer); + +/* The following is used by HOOK_MASK macro */ +uint32_t fd_hook_mask_helper(int dummy, ...); + +/*============================================================*/ + +/* + * The following allows an extension to retrieve stat information on the different fifo queues involved in the freeDiameter framework. + * There are three global queues, plus per-peer queues. + * This information can be used to build SNMP-like data for example, or quickly get a status of the framework to find the loaded path of execution / bottlenecks. + */ +enum fd_stat_type { + /* For the following, no peer is associated with the stat */ + STAT_G_LOCAL= 1, /* Get statistics for the global queue of messages processed by local extensions */ + STAT_G_INCOMING, /* Get statistics for the global queue of received messages to be processed by routing_in thread */ + STAT_G_OUTGOING, /* Get statistics for the global queue of messages to be processed by routing_out thread */ + + /* For the following, the peer must be provided */ + STAT_P_PSM, /* Peer state machine queue (events to be processed for this peer, including received messages) */ + STAT_P_TOSEND, /* Queue of messages for sending to this peer */ +}; + +/* + * FUNCTION: fd_stat_getstats + * + * PARAMETERS: + * stat : Which queue is being queried + * peer : (depending on the stat parameter) which peer is being queried + * current_count : (out) The number of items in the queue currently + * limit_count : (out) The max number of items the queue accepts before becoming blocking -- 0 means no max. + * highest_count : (out) The highest count the queue has reached since startup + * total_count : (out) Total number of items that this queue has processed (always growing, use deltas for monitoring) + * total : (out) Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring) + * blocking : (out) Cumulated time threads trying to post new items were blocked (queue full). + * last : (out) For the last element retrieved from the queue, how long it took between posting (including blocking) and poping + * + * DESCRIPTION: + * Get statistics information about a given queue. + * Any of the (out) parameters can be NULL if not requested. + * + * RETURN VALUE: + * 0 : The callback is registered. + * EINVAL : A parameter is invalid. + */ +int fd_stat_getstats(enum fd_stat_type stat, struct peer_hdr * peer, + int * current_count, int * limit_count, int * highest_count, long long * total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last); + +/*============================================================*/ +/* EOF */ +/*============================================================*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBFDCORE_H */ diff --git a/plat/diameter/include/freeDiameter/libfdproto.h b/plat/diameter/include/freeDiameter/libfdproto.h new file mode 100644 index 0000000..953e42a --- /dev/null +++ b/plat/diameter/include/freeDiameter/libfdproto.h @@ -0,0 +1,3254 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY S_OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* This file contains the definitions of functions and types used by the libfreeDiameter library. + * + * This library is meant to be used by both the freeDiameter daemon and its extensions. + * It provides the tools to manipulate Diameter messages and related data. + * This file should always be included as #include + * + * If any change is made to this file, you must increment the FD_PROJECT_VERSION_API version. + * + * The file contains the following parts: + * DEBUG + * MACROS + * OCTET STRINGS + * THREADS + * LISTS + * DICTIONARY + * SESSIONS + * MESSAGES + * DISPATCH + * QUEUES + */ + +#ifndef _LIBFDPROTO_H +#define _LIBFDPROTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef FD_IS_CONFIG +#error "You must include 'freeDiameter-host.h' before this file." +#endif /* FD_IS_CONFIG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* for basename */ + +#ifdef SWIG +#define _ATTRIBUTE_PRINTFLIKE_(_f,_v) +#else +#define _ATTRIBUTE_PRINTFLIKE_(_f,_v) __attribute__ ((format (printf, _f, _v))) +#endif /* SWIG */ + +/* Remove some deprecated warnings from some gnutls versions, when possible */ +#if defined(__GNUC__) +# define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x) +# define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x) +# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 /* 4.6.x */ +# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \ + GCC_DIAG_PRAGMA(ignored x) +# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop) +# else /* older */ +# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored x) +# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning x) +# endif +#else +# define GCC_DIAG_OFF(x) +# define GCC_DIAG_ON(x) +#endif + +/*============================================================*/ +/* CONSTANTS */ +/*============================================================*/ + +#define DIAMETER_PORT 3868 +#define DIAMETER_SECURE_PORT 5868 + + +/*============================================================*/ +/* INIT */ +/*============================================================*/ + +/* This function must be called first, before any call to another library function */ +int fd_libproto_init(void); /* note if you are using libfdcore, it handles this already */ + +/* Call this one when the application terminates, to destroy internal threads */ +void fd_libproto_fini(void); + +/* Retrieve the version of the binary */ +extern const char fd_libproto_version[]; + +/*============================================================*/ +/* DEBUG */ +/*============================================================*/ + + +/* + * FUNCTION: fd_log + * + * PARAMETERS: + * loglevel : Integer, how important the message is. Valid values are macros FD_LOG_* + * format : Same format string as in the printf function + * ... : Same list as printf + * + * DESCRIPTION: + * Write information to log. + * The format and arguments may contain UTF-8 encoded data. The + * output medium is expected to support this encoding. + * + * RETURN VALUE: + * None. + */ +void fd_log ( int, const char *, ... ) _ATTRIBUTE_PRINTFLIKE_(2,3); +#ifndef SWIG +void fd_log_va( int, const char *, va_list); +#endif /* SWIG */ + +/* these are internal objects of the debug facility, +might be useful to control the behavior from outside */ +extern pthread_mutex_t fd_log_lock; +extern char * fd_debug_one_function; +extern char * fd_debug_one_file; + +/* + * FUNCTION: fd_log_threadname + * + * PARAMETERS: + * name : \0-terminated string containing a name to identify the current thread. + * + * DESCRIPTION: + * Name the current thread, useful for debugging multi-threaded problems. + * + * This function assumes that a global thread-specific key called "fd_log_thname" exists + * in the address space of the current process. + * + * RETURN VALUE: + * None. + */ +void fd_log_threadname ( const char * name ); +extern pthread_key_t fd_log_thname; + +/* + * FUNCTION: fd_log_time + * + * PARAMETERS: + * ts : The timestamp to log, or NULL for "now" + * buf : An array where the time must be stored + * len : size of the buffer + * incl_date : The day of year is included in the output + * incl_ms : millisecond value is included in the output + * + * DESCRIPTION: + * Writes the timestamp (in human readable format) in a buffer. + * + * RETURN VALUE: + * pointer to buf. + */ +char * fd_log_time ( struct timespec * ts, char * buf, size_t len, int incl_date, int incl_ms ); + +/* + * FUNCTION: fd_log_handler_register + * MACRO: + * + * PARAMETERS: + * loglevel : priority of the message + * format : Same format string as in the printf function + * va_list : Argument list + * + * DESCRIPTION: + * Register an external method for logging purposes. + * + * RETURN VALUE: + * int : Success or failure + */ +int fd_log_handler_register ( void (*logger)(int loglevel, const char * format, va_list args) ); + +/* + * FUNCTION: fd_log_handler_unregister + * MACRO: + * + * PARAMETERS: + * + * DESCRIPTION: + * Unregister the external logging function. + * + * RETURN VALUE: + * int : Success or failure + */ +int fd_log_handler_unregister ( void ); + + +/* All dump functions follow this same prototype: + * PARAMETERS: + * buf : *buf can be NULL on entry, it will be malloc'd. Otherwise it is realloc'd if needed. + * len : the current size of the buffer (in/out) + * offset: (optional) if provided, starts writing dump at offset in the buffer, and updated upon exit. if NULL, starts at offset O. + * + * RETURN VALUE: + * *buf upon success, NULL upon failure. + * + * REMARKS: + * - After the buffer has been used, it should be freed. + * - Depending on the function, the created string may be multi-line. However, it should never be terminated with a '\n'. + */ +#define DECLARE_FD_DUMP_PROTOTYPE( function_name, args... ) \ + char * function_name(char ** buf, size_t *len, size_t *offset, ##args) + +#ifdef SWIG +#define DECLARE_FD_DUMP_PROTOTYPE_simple( function_name ) \ + char * function_name(char ** buf, size_t *len, size_t *offset) +#endif /* SWIG */ + + +/* Helper functions for the *dump functions that add into a buffer */ +DECLARE_FD_DUMP_PROTOTYPE( fd_dump_extend, const char * format, ... ) _ATTRIBUTE_PRINTFLIKE_(4,5); +DECLARE_FD_DUMP_PROTOTYPE( fd_dump_extend_hexdump, uint8_t *data, size_t datalen, size_t trunc, size_t wrap ); + + +/* Some helpers macro for writing such *_dump routine */ +#define FD_DUMP_STD_PARAMS buf, len, offset +#define FD_DUMP_HANDLE_OFFSET() size_t o = 0; if (!offset) offset = &o; if (buf && (*buf) && !(*offset)) **buf='\0' +#define FD_DUMP_HANDLE_TRAIL() while ((*buf) && (*offset > 0) && ((*buf)[*offset - 1] == '\n')) { *offset -= 1; (*buf)[*offset] = '\0'; } + + + +/*============================================================*/ +/* DEBUG MACROS */ +/*============================================================*/ + +#ifndef ASSERT +#define ASSERT(x) assert(x) +#endif /* ASSERT */ + +/* log levels definitions, that are passed to the logger */ +#define FD_LOG_ANNOYING 0 /* very verbose loops and such "overkill" traces. Only active when the framework is compiled in DEBUG mode. */ +#define FD_LOG_DEBUG 1 /* Get a detailed sense of what is going on in the framework. Use this level for normal debug */ +#define FD_LOG_NOTICE 3 /* Normal execution states worth noting */ +#define FD_LOG_ERROR 5 /* Recoverable or expected error conditions */ +#define FD_LOG_FATAL 6 /* Unrecoverable error, e.g. malloc fail, etc. that requires the framework to shutdown */ + +/* The level used by the default logger, can be changed by command-line arguments. Ignored for other loggers. */ +extern int fd_g_debug_lvl; + +/* Some portability code to get nice function name in __PRETTY_FUNCTION__ */ +#if (!defined( __func__)) && (__STDC_VERSION__ < 199901L) +# if __GNUC__ >= 2 +# define __func__ __FUNCTION__ +# else /* __GNUC__ >= 2 */ +# define __func__ "" +# endif /* __GNUC__ >= 2 */ +#endif /*(!defined( __func__)) && (__STDC_VERSION__ < 199901L) */ +#ifndef __PRETTY_FUNCTION__ +#define __PRETTY_FUNCTION__ __func__ +#endif /* __PRETTY_FUNCTION__ */ + +/* A version of __FILE__ without the full path. This is specific to each C file being compiled */ +static char * file_bname = NULL; +static char * file_bname_init(char * full) { file_bname = basename(full); return file_bname; } +#define __STRIPPED_FILE__ (file_bname ?: file_bname_init((char *)__FILE__)) + + + +/* In DEBUG mode, we add meta-information along each trace. This makes multi-threading problems easier to debug. */ +#if (defined(DEBUG) && defined(DEBUG_WITH_META)) +# define STD_TRACE_FMT_STRING "pid:%s in %s@%s:%d: " +# define STD_TRACE_FMT_ARGS , ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"), __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__ +#else /* DEBUG && DEBUG_WITH_META */ +# define STD_TRACE_FMT_STRING "" +# define STD_TRACE_FMT_ARGS +#endif /* DEBUG && DEBUG_WITH_META */ + +/************************* + The general debug macro + *************************/ +#define LOG(printlevel,format,args... ) \ + fd_log((printlevel), STD_TRACE_FMT_STRING format STD_TRACE_FMT_ARGS, ## args) + +/* + * Use the following macros in the code to get traces with location & pid in debug mode: + */ +#ifdef DEBUG +# define LOG_A(format,args... ) \ + do { if ((fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__)) \ + || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) ) ) { \ + LOG(FD_LOG_DEBUG,"[DBG_MATCH] " format,##args); \ + } else { \ + LOG(FD_LOG_ANNOYING,format,##args); \ + } } while (0) +#else /* DEBUG */ +# define LOG_A(format,args... ) /* not defined in release */ +#endif /* DEBUG */ + +/* Debug information useful to follow in detail what is going on */ +#define LOG_D(format,args... ) \ + LOG(FD_LOG_DEBUG, format, ##args) + +/* Report a normal message that is useful for normal admin monitoring */ +#define LOG_N(format,args... ) \ + LOG(FD_LOG_NOTICE, format,##args) + +/* Report an error */ +#define LOG_E(format,args... ) \ + LOG(FD_LOG_ERROR, format, ##args) + +/* Report a fatal error */ +#define LOG_F(format,args... ) \ + LOG(FD_LOG_FATAL, format, ##args) + + +/************* + Derivatives + ************/ +/* Trace a binary buffer content */ +#define LOG_BUFFER(printlevel, prefix, buf, bufsz, suffix ) { \ + int __i; \ + size_t __sz = (size_t)(bufsz); \ + uint8_t * __buf = (uint8_t *)(buf); \ + char __strbuf[1024+1]; \ + for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) { \ + sprintf(__strbuf + (2 * __i), "%02hhx", __buf[__i]); \ + } \ + fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s" STD_TRACE_FMT_ARGS, \ + (prefix), __strbuf, (suffix)); \ +} + +/* Split a multi-line buffer into separate calls to the LOG function. */ +#define LOG_SPLIT(printlevel, per_line_prefix, mlbuf, per_line_suffix ) { \ + char * __line = (mlbuf), *__next; \ + char * __p = (per_line_prefix), *__s = (per_line_suffix); \ + while ((__next = strchr(__line, '\n')) != NULL) { \ + LOG(printlevel, "%s%.*s%s", __p ?:"", (int)(__next - __line), __line, __s ?:""); \ + __line = __next + 1; \ + } \ + LOG(printlevel, "%s%s%s", __p ?:"", __line, __s ?:""); \ +} + +/* Helper for function entry -- for very detailed trace of the execution */ +#define TRACE_ENTRY(_format,_args... ) \ + LOG_A("[enter] %s(" _format ") {" #_args "}", __PRETTY_FUNCTION__, ##_args ); + +/* Helper for debugging by adding traces -- for debuging a specific location of the code */ +#define TRACE_HERE() \ + LOG_F(" -- debug checkpoint %d -- ", fd_breakhere()); +int fd_breakhere(void); + +/* Helper for tracing the CHECK_* macros below -- very very verbose code execution! */ +#define TRACE_CALL( str... ) \ + LOG_A( str ) + +/* For development only, to keep track of TODO locations in the code */ +#ifndef ERRORS_ON_TODO +# define TODO( _msg, _args... ) \ + LOG_F( "TODO: " _msg , ##_args); +#else /* ERRORS_ON_TODO */ +# define TODO( _msg, _args... ) \ + "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */ +#endif /* ERRORS_ON_TODO */ + + +/*============================================================*/ +/* ERROR CHECKING MACRO */ +/*============================================================*/ + +/* Macros to check a return value and branch out in case of error. + * These macro additionally provide the logging information. + * + * The name "__ret__" is always available in the __fallback__ parameter and contains the error code. + */ + +#define CHECK_PRELUDE(__call__) \ + int __ret__; \ + TRACE_CALL("Check: %s", #__call__ ); \ + __ret__ = (__call__) + +#define DEFAULT_FB return __ret__; + +/* System check: error case if < 0, error value in errno */ +#define CHECK_SYS_GEN( faillevel, __call__, __fallback__ ) { \ + CHECK_PRELUDE(__call__); \ + if (__ret__ < 0) { \ + __ret__ = errno; \ + LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ + __fallback__; \ + } \ +} + + +/* Check the return value of a function and execute fallback in case of error or special value */ +#define CHECK_FCT_GEN2( faillevel, __call__, __speval__, __fallback1__, __fallback2__ ) { \ + CHECK_PRELUDE(__call__); \ + if (__ret__ != 0) { \ + if (__ret__ == (__speval__)) { \ + __fallback1__; \ + } else { \ + LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ + __fallback2__; \ + } \ + } \ +} + +/* Check the return value of a function and execute fallback in case of error (return value different from 0) */ +#define CHECK_FCT_GEN( faillevel, __call__, __fallback__) \ + CHECK_FCT_GEN2( faillevel, (__call__), 0, , (__fallback__) ) + +/* Check that a memory allocator did not return NULL, otherwise log an error and execute fallback */ +#define CHECK_MALLOC_GEN( faillevel, __call__, __fallback__ ) { \ + void * __ptr__; \ + TRACE_CALL("Check: %s", #__call__ ); \ + __ptr__ = (void *)(__call__); \ + if (__ptr__ == NULL) { \ + int __ret__ = errno; \ + LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ + __fallback__; \ + } \ +} + +/* Check parameters at function entry, execute fallback on error */ +#define CHECK_PARAMS_GEN( faillevel, __bool__, __fallback__ ) { \ + TRACE_CALL("Check: %s", #__bool__ ); \ + if ( ! (__bool__) ) { \ + int __ret__ = EINVAL; \ + LOG(faillevel, "ERROR: invalid parameter '%s'", #__bool__ ); \ + __fallback__; \ + } \ +} + + +/*============================================================*/ +/* COMPATIBILITY MACROS, TO BE REMOVED */ +/*============================================================*/ +/* Redefine the old macros for transition of the code */ +#ifndef EXCLUDE_DEPRECATED + +#define MARK_DEPRECATED /* __attribute__ ((deprecated)) */ + +enum old_levels { + NONE = 0, + INFO = 1, + FULL = 2, + ANNOYING = 4, + FCTS = 6, + CALL = 9 +} MARK_DEPRECATED; + +static __inline__ int old_TRACE_BOOL( enum old_levels level, const char * file, const char * func ) MARK_DEPRECATED +{ + if ((fd_debug_one_function && !strcmp(fd_debug_one_function, func)) + || (fd_debug_one_file && !strcmp(fd_debug_one_file, file) )) + return 2; /* Level override */ + if ((int)level <= fd_g_debug_lvl) + return 1; /* Normal level */ + return 0; /* No trace */ +} +#define TRACE_BOOL(level) old_TRACE_BOOL((level), __STRIPPED_FILE__, __PRETTY_FUNCTION__) + +#ifndef SWIG +static __inline__ void fd_log_deprecated( int level, const char *format, ... ) MARK_DEPRECATED +{ + va_list ap; + va_start(ap, format); + fd_log_va(level, format, ap); + va_end(ap); +} +#else /* SWIG */ +void fd_log_deprecated( int level, const char *format, ... ); +#endif /* SWIG */ +static __inline__ void replace_me() MARK_DEPRECATED { } + +#define TRACE_BUFFER(...) replace_me(); +#define TRACE_NOTICE(...) replace_me(); + + +/* Use the LOG_* instead, or use the new *_dump functions when dumping an object */ +#define fd_log_debug(format,args...) fd_log_deprecated(FD_LOG_DEBUG, format, ## args) +#define fd_log_notice(format,args...) fd_log_deprecated(FD_LOG_NOTICE, format, ## args) +#define fd_log_error(format,args...) fd_log_deprecated(FD_LOG_ERROR, format, ## args) + +/* old macro for traces. To be replaced by appropriate LOG_* macros. */ +# define TRACE_DEBUG(oldlevel, format,args... ) { \ + int __l__; \ + if ((__l__ = TRACE_BOOL(oldlevel))) { \ + if (oldlevel <= NONE) { LOG_E(format,##args); } \ + else if (oldlevel <= INFO) { LOG_N(format,##args); } \ + else if (__l__ == 2) { LOG_N(format,##args); } \ + else if (oldlevel <= FULL) { LOG_D(format,##args); } \ + else { LOG_A(format,##args); } \ +} } + +/* the following macro must be replaced with LOG_E or LOG_F */ +# define TRACE_ERROR LOG_E + + +/* The following macros are missing the faillevel information, which indicates at what log level the error case should be displayed. */ +# define CHECK_SYS_DO( __call__, __fallback__ ) { \ + CHECK_PRELUDE(__call__); \ + if (__ret__ < 0) { \ + __ret__ = errno; \ + TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ + __fallback__; \ + } \ +} + +# define CHECK_SYS( __call__ ) \ + CHECK_SYS_DO( (__call__), return __ret__ ) + + +# define CHECK_POSIX_DO2( __call__, __speval__, __fallback1__, __fallback2__ ) { \ + CHECK_PRELUDE(__call__); \ + if (__ret__ != 0) { \ + if (__ret__ == (__speval__)) { \ + __fallback1__; \ + } else { \ + TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ + __fallback2__; \ + } \ + } \ +} + +# define CHECK_POSIX_DO( __call__, __fallback__ ) \ + CHECK_POSIX_DO2( (__call__), 0, , __fallback__ ) + +# define CHECK_POSIX( __call__ ) \ + CHECK_POSIX_DO( (__call__), return __ret__ ) + +# define CHECK_MALLOC_DO( __call__, __fallback__ ) { \ + void * __ptr__; \ + TRACE_CALL("Check: %s", #__call__ ); \ + __ptr__ = (void *)(__call__); \ + if (__ptr__ == NULL) { \ + int __ret__ = errno; \ + TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ + __fallback__; \ + } \ +} + +# define CHECK_MALLOC( __call__ ) \ + CHECK_MALLOC_DO( (__call__), return __ret__ ) + +# define CHECK_PARAMS_DO( __bool__, __fallback__ ) { \ + TRACE_CALL("Check: %s", #__bool__ ); \ + if ( ! (__bool__) ) { \ + int __ret__ = EINVAL; \ + TRACE_ERROR("ERROR: Invalid parameter '%s', %d", #__bool__, __ret__ ); \ + __fallback__; \ + } \ +} + +# define CHECK_PARAMS( __bool__ ) \ + CHECK_PARAMS_DO( (__bool__), return __ret__ ) + +# define CHECK_FCT_DO CHECK_POSIX_DO +# define CHECK_FCT CHECK_POSIX + +#endif /* EXCLUDE_DEPRECATED */ + + +/*============================================================*/ +/* Optimized code: remove all debugging code */ +/*============================================================*/ +#ifdef STRIP_DEBUG_CODE +#undef LOG_D +#undef LOG_N +#undef LOG_E +#undef LOG_F +#undef LOG_BUFFER + +#define LOG_D(format,args... ) /* noop */ +#define LOG_N(format,args...) fd_log(FD_LOG_NOTICE, format, ## args) +#define LOG_E(format,args...) fd_log(FD_LOG_ERROR, format, ## args) +#define LOG_F(format,args...) fd_log(FD_LOG_FATAL, format, ## args) +#define LOG_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ + if (printlevel > FD_LOG_DEBUG) { \ + int __i; \ + size_t __sz = (size_t)(bufsz); \ + uint8_t * __buf = (uint8_t *)(buf); \ + char * __strbuf[1024+1]; \ + for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2); __i++) { \ + sprintf(__strbuf + (2 * __i), "%02.2hhx", __buf[__i]); \ + } \ + fd_log(printlevel, prefix"%s"suffix, __strbuf); \ + } +#endif /* STRIP_DEBUG_CODE */ + +/*============================================================*/ +/* OTHER MACROS */ +/*============================================================*/ +/* helper macros (pre-processor hacks to allow macro arguments) */ +#define __tostr( arg ) #arg +#define _stringize( arg ) __tostr( arg ) +#define __agr( arg1, arg2 ) arg1 ## arg2 +#define _aggregate( arg1, arg2 ) __agr( arg1, arg2 ) + +/* Some aliases to socket addresses structures */ +#define sSS struct sockaddr_storage +#define sSA struct sockaddr +#define sSA4 struct sockaddr_in +#define sSA6 struct sockaddr_in6 + +/* The sockaddr length of a sSS structure */ +#define sSAlen( _sa_ ) \ + ( (socklen_t) ( (((sSA *)_sa_)->sa_family == AF_INET) ? (sizeof(sSA4)) : \ + ((((sSA *)_sa_)->sa_family == AF_INET6) ? (sizeof(sSA6)) : \ + 0 ) ) ) +#define sSAport( _sa_ ) \ + ( (socklen_t) ( (((sSA *)_sa_)->sa_family == AF_INET) ? (((sSA4 *)(_sa_))->sin_port) : \ + ((((sSA *)_sa_)->sa_family == AF_INET6) ? (((sSA6 *)(_sa_))->sin6_port) : \ + 0 ) ) ) + +DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump, sSA * sa, int flags); +#define sSA_DUMP_STRLEN (INET6_ADDRSTRLEN + 1 + 32 + 2) +void fd_sa_sdump_numeric(char * buf /* must be at least sSA_DUMP_STRLEN */, sSA * sa); + + +/* A l4 protocol name (TCP / SCTP) */ +#ifdef DISABLE_SCTP +#define IPPROTO_NAME( _proto ) \ + (((_proto) == IPPROTO_TCP) ? "TCP" : \ + "Unknown") +#else /* DISABLE_SCTP */ +#define IPPROTO_NAME( _proto ) \ + ( ((_proto) == IPPROTO_TCP) ? "TCP" : \ + (((_proto) == IPPROTO_SCTP) ? "SCTP" : \ + "Unknown")) +#endif /* DISABLE_SCTP */ + +/* Define the value of IP loopback address */ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK inet_addr("127.0.0.1") +#endif /* INADDR_LOOPBACK */ + +#ifndef INADDR_BROADCAST +#define INADDR_BROADCAST ((in_addr_t) 0xffffffff) +#endif /* INADDR_BROADCAST */ + +/* An IP equivalent to IN6_IS_ADDR_LOOPBACK */ +#ifndef IN_IS_ADDR_LOOPBACK +#define IN_IS_ADDR_LOOPBACK(a) \ + ((((long int) (a)->s_addr) & ntohl(0xff000000)) == ntohl(0x7f000000)) +#endif /* IN_IS_ADDR_LOOPBACK */ + +/* An IP equivalent to IN6_IS_ADDR_UNSPECIFIED */ +#ifndef IN_IS_ADDR_UNSPECIFIED +#define IN_IS_ADDR_UNSPECIFIED(a) \ + (((long int) (a)->s_addr) == 0x00000000) +#endif /* IN_IS_ADDR_UNSPECIFIED */ + +/* create a V4MAPPED address */ +#define IN6_ADDR_V4MAP( a6, a4 ) { \ + ((uint32_t *)(a6))[0] = 0; \ + ((uint32_t *)(a6))[1] = 0; \ + ((uint32_t *)(a6))[2] = htonl(0xffff); \ + ((uint32_t *)(a6))[3] = (uint32_t)(a4); \ +} + +/* Retrieve a v4 value from V4MAPPED address ( takes a s6_addr as param) */ +#define IN6_ADDR_V4UNMAP( a6 ) \ + (((in_addr_t *)(a6))[3]) + + +/* We provide macros to convert 64 bit values to and from network byte-order, on systems where it is not already provided. */ +#ifndef HAVE_NTOHLL /* Defined by the cmake step, if the ntohll symbol is defined on the system */ +# if HOST_BIG_ENDIAN + /* In big-endian systems, we don't have to change the values, since the order is the same as network */ +# define ntohll(x) (x) +# define htonll(x) (x) +# else /* HOST_BIG_ENDIAN */ + /* For these systems, we must reverse the bytes. Use ntohl and htonl on sub-32 blocs, and inverse these blocs. */ +# define ntohll(x) (typeof (x))( (((uint64_t)ntohl( (uint32_t)(x))) << 32 ) | ((uint64_t) ntohl( ((uint64_t)(x)) >> 32 ))) +# define htonll(x) (typeof (x))( (((uint64_t)htonl( (uint32_t)(x))) << 32 ) | ((uint64_t) htonl( ((uint64_t)(x)) >> 32 ))) +# endif /* HOST_BIG_ENDIAN */ +#endif /* HAVE_NTOHLL */ + +/* This macro will give the next multiple of 4 for an integer (used for padding sizes of AVP). */ +#define PAD4(_x) ((_x) + ( (4 - (_x)) & 3 ) ) + +/* Useful to display any value as (safe) ASCII (will garbage UTF-8 output...) */ +#define ASCII(_c) ( ((_c < 32) || (_c > 127)) ? ( _c ? '?' : ' ' ) : _c ) + +/* Compare timespec structures */ +#define TS_IS_INFERIOR( ts1, ts2 ) \ + ( ((ts1)->tv_sec < (ts2)->tv_sec ) \ + || (((ts1)->tv_sec == (ts2)->tv_sec ) && ((ts1)->tv_nsec < (ts2)->tv_nsec) )) + +/* Compute diff between two timespecs (pointers) */ +#define TS_DIFFERENCE( tsdiff, tsstart, tsend ) { \ + if ((tsend)->tv_nsec < (tsstart)->tv_nsec ) { \ + (tsdiff)->tv_sec = (tsend)->tv_sec - (tsstart)->tv_sec - 1; \ + (tsdiff)->tv_nsec = (tsend)->tv_nsec + 1000000000 - (tsstart)->tv_nsec; \ + } else { \ + (tsdiff)->tv_sec = (tsend)->tv_sec - (tsstart)->tv_sec; \ + (tsdiff)->tv_nsec = (tsend)->tv_nsec - (tsstart)->tv_nsec; \ + }} + + +/* This gives a good size for buffered reads */ +#ifndef BUFSIZ +#define BUFSIZ 96 +#endif /* BUFSIZ */ + +/* This gives the length of a const string */ +#define CONSTSTRLEN( str ) (sizeof(str) - 1) + + +/*============================================================*/ +/* PORTABILITY */ +/*============================================================*/ +#ifndef HAVE_CLOCK_GETTIME + #define CLOCK_REALTIME 0 + #include + int clock_gettime(int clk_id, struct timespec* ts); +#endif /* HAVE_CLOCK_GETTIME */ + +#ifndef HAVE_STRNDUP +char * strndup (char *str, size_t len); +#endif /* HAVE_STRNDUP */ + + +/*============================================================*/ +/* BINARY STRINGS */ +/*============================================================*/ + +/* Compute a hash value of a binary string. +The hash must remain local to this machine, there is no guarantee that same input +will give same output on a different system (endianness) */ +uint32_t fd_os_hash ( uint8_t * string, size_t len ); + +/* This type used for binary strings that contain no \0 except as their last character. +It means some string operations can be used on it. */ +typedef uint8_t * os0_t; + +/* Same as strdup but for os0_t strings */ +os0_t os0dup_int(os0_t s, size_t l); +#define os0dup( _s, _l) (void *)os0dup_int((os0_t)(_s), _l) + +/* Check that an octet string value can be used as os0_t */ +static __inline__ int fd_os_is_valid_os0(uint8_t * os, size_t oslen) { + /* The only situation where it is not valid is when it contains a \0 inside the octet string */ + return (memchr(os, '\0', oslen) == NULL); +} + +/* The following type denotes a verified DiameterIdentity value (that contains only pure letters, digits, hyphen, dot) */ +typedef char * DiamId_t; + +/* Maximum length of a hostname we accept */ +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 512 +#endif /* HOST_NAME_MAX */ + +/* Check if a binary string contains a valid Diameter Identity value. + rfc3588 states explicitely that such a Diameter Identity consists only of ASCII characters. */ +int fd_os_is_valid_DiameterIdentity(uint8_t * os, size_t ossz); + +/* The following function validates a string as a Diameter Identity or applies the IDNA transformation on it + if *inoutsz is != 0 on entry, *id may not be \0-terminated. + memory has the following meaning: 0: *id can be realloc'd. 1: *id must be malloc'd on output (was static) +*/ +int fd_os_validate_DiameterIdentity(char ** id, size_t * inoutsz, int memory); + +/* Create an order relationship for binary strings (not needed to be \0 terminated). + It does NOT mimic strings relationships so that it is more efficient. It is case sensitive. + (the strings are actually first ordered by their lengh, then by their bytes contents) + returns: -1 if os1 < os2; +1 if os1 > os2; 0 if they are equal */ +int fd_os_cmp_int(os0_t os1, size_t os1sz, os0_t os2, size_t os2sz); +#define fd_os_cmp(_o1, _l1, _o2, _l2) fd_os_cmp_int((os0_t)(_o1), _l1, (os0_t)(_o2), _l2) + +/* A roughly case-insensitive variant, which actually only compares ASCII chars (0-127) in a case-insentitive maneer + -- it does not support locales where a lowercase letter uses more space than upper case, such as ß -> ss + It is slower than fd_os_cmp. + Note that the result is NOT the same as strcasecmp !!! + + This function gives the same order as fd_os_cmp, except when it finds 2 strings to be equal. + However this is not always sufficient: + for example fd_os_cmp gives: "Ac" < "aB" < "aa" + if you attempt to fd_os_almostcasesrch "Aa" you will actually have to go past "aB" which is > "Aa". + Therefore you can use the maybefurther parameter. + This parameter is 1 on return if os1 may have been stored further that os2 (assuming os2 values are ordered by fd_os_cmp) + and 0 if we are sure that it is not the case. + When looping through a list of fd_os_cmp classified values, this parameter must be used to stop looping, in addition to the comp result. + */ +int fd_os_almostcasesrch_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz, int * maybefurther); +#define fd_os_almostcasesrch(_o1, _l1, _o2, _l2, _mb) fd_os_almostcasesrch_int((os0_t)(_o1), _l1, (os0_t)(_o2), _l2, _mb) + +/* Analyze a DiameterURI and return its components. + Return EINVAL if the URI is not valid. + *diamid is malloc'd on function return and must be freed (it is processed by fd_os_validate_DiameterIdentity). + *secure is 0 (no security) or 1 (security enabled) on return. + *port is 0 (default) or a value in host byte order on return. + *transport is 0 (default) or IPPROTO_* on return. + *proto is 0 (default) or 'd' (diameter), 'r' (radius), or 't' (tacacs+) on return. + */ +int fd_os_parse_DiameterURI(uint8_t * uri, size_t urisz, DiamId_t * diamid, size_t * diamidlen, int * secure, uint16_t * port, int * transport, char *proto); + +/*============================================================*/ +/* THREADS */ +/*============================================================*/ + +/* Terminate a thread */ +static __inline__ int fd_thr_term(pthread_t * th) +{ + void * th_ret = NULL; + + CHECK_PARAMS(th); + + /* Test if it was already terminated */ + if (*th == (pthread_t)NULL) + return 0; + + /* Cancel the thread if it is still running - ignore error if it was already terminated */ + (void) pthread_cancel(*th); + + /* Then join the thread */ + CHECK_POSIX( pthread_join(*th, &th_ret) ); + + if (th_ret == PTHREAD_CANCELED) { + TRACE_DEBUG(ANNOYING, "The thread %p was canceled", (void *)*th); + } else { + TRACE_DEBUG(CALL, "The thread %p returned %p", (void *)*th, th_ret); + } + + /* Clean the location */ + *th = (pthread_t)NULL; + + return 0; +} + + +/************* + Cancelation cleanup handlers for common objects + *************/ +static __inline__ void fd_cleanup_mutex( void * mutex ) +{ + CHECK_POSIX_DO( pthread_mutex_unlock((pthread_mutex_t *)mutex), /* */); +} + +static __inline__ void fd_cleanup_rwlock( void * rwlock ) +{ + CHECK_POSIX_DO( pthread_rwlock_unlock((pthread_rwlock_t *)rwlock), /* */); +} + +static __inline__ void fd_cleanup_buffer( void * buffer ) +{ + free(buffer); +} +static __inline__ void fd_cleanup_socket(void * sockptr) +{ + if (sockptr && (*(int *)sockptr > 0)) { + CHECK_SYS_DO( close(*(int *)sockptr), /* ignore */ ); + *(int *)sockptr = -1; + } +} + + +/*============================================================*/ +/* LISTS */ +/*============================================================*/ + +/* The following structure represents a chained list element */ +struct fd_list { + struct fd_list *next; /* next element in the list */ + struct fd_list *prev; /* previous element in the list */ + struct fd_list *head; /* head of the list */ + void *o; /* additional pointer, used for any purpose (ex: start of the parent object) */ +}; + +/* Initialize a list element */ +#define FD_LIST_INITIALIZER( _list_name ) \ + { .next = & _list_name, .prev = & _list_name, .head = & _list_name, .o = NULL } +#define FD_LIST_INITIALIZER_O( _list_name, _obj ) \ + { .next = & _list_name, .prev = & _list_name, .head = & _list_name, .o = _obj } +void fd_list_init ( struct fd_list * list, void * obj ); + +/* Return boolean, true if the list is empty */ +#define FD_IS_LIST_EMPTY( _list ) ((((struct fd_list *)(_list))->head == (_list)) && (((struct fd_list *)(_list))->next == (_list))) + +/* Insert an item in a list at known position */ +void fd_list_insert_after ( struct fd_list * ref, struct fd_list * item ); +void fd_list_insert_before ( struct fd_list * ref, struct fd_list * item ); + +/* Move all elements from a list at the end of another */ +void fd_list_move_end(struct fd_list * ref, struct fd_list * senti); + +/* Insert an item in an ordered list -- ordering function must be provided. If duplicate object found, EEXIST and it is returned in ref_duplicate */ +int fd_list_insert_ordered( struct fd_list * head, struct fd_list * item, int (*cmp_fct)(void *, void *), void ** ref_duplicate); + +/* Unlink an item from a list */ +void fd_list_unlink ( struct fd_list * item ); + + + + +/*============================================================*/ +/* DICTIONARY */ +/*============================================================*/ + +/* Structure that contains the complete dictionary definitions */ +struct dictionary; + +/* Structure that contains a dictionary object */ +struct dict_object; + +/* Types of object in the dictionary. */ +enum dict_object_type { + DICT_VENDOR = 1, /* Vendor */ + DICT_APPLICATION, /* Diameter Application */ + DICT_TYPE, /* AVP data type */ + DICT_ENUMVAL, /* Named constant (value of an enumerated AVP type) */ + DICT_AVP, /* AVP */ + DICT_COMMAND, /* Diameter Command */ + DICT_RULE /* a Rule for AVP in command or grouped AVP */ +#define DICT_TYPE_MAX DICT_RULE +}; + +/* Initialize a dictionary */ +int fd_dict_init(struct dictionary ** dict); +/* Destroy a dictionary */ +int fd_dict_fini(struct dictionary ** dict); + +/* + * FUNCTION: fd_dict_new + * + * PARAMETERS: + * dict : Pointer to the dictionnary where the object is created + * type : What kind of object must be created + * data : pointer to the data for the object. + * type parameter is used to determine the type of data (see below for detail). + * parent : a reference to a parent object, if needed. + * ref : upon successful creation, reference to new object is stored here if !null. + * + * DESCRIPTION: + * Create a new object in the dictionary. + * See following object sections in this header file for more information on data and parent parameters format. + * + * RETURN VALUE: + * 0 : The object is created in the dictionary. + * EINVAL : A parameter is invalid. + * EEXIST : This object is already defined in the dictionary (with conflicting data). + * If "ref" is not NULL, it points to the existing element on return. + * (other standard errors may be returned, too, with their standard meaning. Example: + * ENOMEM : Memory allocation for the new object element failed.) + */ +int fd_dict_new ( struct dictionary * dict, enum dict_object_type type, void * data, struct dict_object * parent, struct dict_object ** ref ); + +/* + * FUNCTION: fd_dict_search + * + * PARAMETERS: + * dict : Pointer to the dictionnary where the object is searched + * type : type of object that is being searched + * criteria : how the object must be searched. See object-related sections below for more information. + * what : depending on criteria, the data that must be searched. + * result : On successful return, pointer to the object is stored here. + * retval : this value is returned if the object is not found and result is not NULL. + * + * DESCRIPTION: + * Perform a search in the dictionary. + * See the object-specific sections below to find how to look for each objects. + * If the "result" parameter is NULL, the function is used to check if an object is in the dictionary. + * Otherwise, a reference to the object is stored in result if found. + * If result is not NULL and the object is not found, retval is returned (should be 0 or ENOENT usually) + * + * RETURN VALUE: + * 0 : The object has been found in the dictionary, or *result is NULL. + * EINVAL : A parameter is invalid. + * ENOENT : No matching object has been found, and result was NULL. + */ +int fd_dict_search ( struct dictionary * dict, enum dict_object_type type, int criteria, const void * what, struct dict_object ** result, int retval ); + +/* Special case: get the generic error command object */ +int fd_dict_get_error_cmd(struct dictionary * dict, struct dict_object ** obj); + +/* + * FUNCTION: fd_dict_getval + * + * PARAMETERS: + * object : Pointer to a dictionary object. + * data : pointer to a structure to hold the data for the object. + * The type is the same as "data" parameter in fd_dict_new function. + * + * DESCRIPTION: + * Retrieve content of a dictionary object. + * See following object sections in this header file for more information on data and parent parameters format. + * + * RETURN VALUE: + * 0 : The content of the object has been retrieved. + * EINVAL : A parameter is invalid. + */ +int fd_dict_getval ( struct dict_object * object, void * val); +int fd_dict_gettype ( struct dict_object * object, enum dict_object_type * type); +int fd_dict_getdict ( struct dict_object * object, struct dictionary ** dict); + +/* Debug functions */ +DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj); +DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict); + +/* Function to access full contents of the dictionary, see doc in dictionary.c */ +int fd_dict_getlistof(int criteria, void * parent, struct fd_list ** sentinel); + +/* Function to remove an entry from the dictionary. + This cannot be used if the object has children (for example a vendor with vendor-specific AVPs). + In such case, the children must be removed first. */ +int fd_dict_delete(struct dict_object * obj); + +/* + *************************************************************************** + * + * Vendor object + * + * These types are used to manage vendors in the dictionary + * + *************************************************************************** + */ + +/* Type to hold a Vendor ID: "SMI Network Management Private Enterprise Codes" (RFC3232) */ +typedef uint32_t vendor_id_t; + +/* Type to hold data associated to a vendor */ +struct dict_vendor_data { + vendor_id_t vendor_id; /* ID of a vendor */ + char * vendor_name; /* The name of this vendor */ +}; + +/* The criteria for searching a vendor object in the dictionary */ +enum { + VENDOR_BY_ID = 10, /* "what" points to a vendor_id_t */ + VENDOR_BY_NAME, /* "what" points to a char * */ + VENDOR_OF_APPLICATION, /* "what" points to a struct dict_object containing an application (see below) */ + VENDOR_OF_AVP, /* "what" points to a struct dict_object containing an avp (see below) */ +}; + +/*** + * API usage : + +Note: the value of "vendor_name" is copied when the object is created, and the string may be disposed afterwards. +On the other side, when value is retrieved with dict_getval, the string is not copied and MUST NOT be freed. It will +be freed automatically along with the object itself with call to dict_fini later. + +- fd_dict_new: + The "parent" parameter is not used for vendors. + Sample code to create a vendor: + { + int ret; + struct dict_object * myvendor; + struct dict_vendor_data myvendordata = { 23455, "my vendor name" }; -- just an example... + ret = fd_dict_new ( dict, DICT_VENDOR, &myvendordata, NULL, &myvendor ); + } + +- fd_dict_search: + Sample codes to look for a vendor object, by its id or name: + { + int ret; + struct dict_object * vendor_found; + vendor_id_t vendorid = 23455; + ret = fd_dict_search ( dict, DICT_VENDOR, VENDOR_BY_ID, &vendorid, &vendor_found, ENOENT); + - or - + ret = fd_dict_search ( dict, DICT_VENDOR, VENDOR_BY_NAME, "my vendor name", &vendor_found, ENOENT); + } + + - fd_dict_getval: + Sample code to retrieve the data from a vendor object: + { + int ret; + struct dict_object * myvendor; + struct dict_vendor_data myvendordata; + ret = fd_dict_search ( dict, DICT_VENDOR, VENDOR_BY_NAME, "my vendor name", &myvendor, ENOENT); + ret = fd_dict_getval ( myvendor, &myvendordata ); + printf("my vendor id: %d\n", myvendordata.vendor_id ); + } + +*/ + +/* Special function: */ +uint32_t * fd_dict_get_vendorid_list(struct dictionary * dict); + +/* + *************************************************************************** + * + * Application object + * + * These types are used to manage Diameter applications in the dictionary + * + *************************************************************************** + */ + +/* Type to hold a Diameter application ID: IANA assigned value for this application. */ +typedef uint32_t application_id_t; + +/* Type to hold data associated to an application */ +struct dict_application_data { + application_id_t application_id; /* ID of the application */ + char * application_name; /* The name of this application */ +}; + +/* The criteria for searching an application object in the dictionary */ +enum { + APPLICATION_BY_ID = 20, /* "what" points to a application_id_t */ + APPLICATION_BY_NAME, /* "what" points to a char * */ + APPLICATION_OF_TYPE, /* "what" points to a struct dict_object containing a type object (see below) */ + APPLICATION_OF_COMMAND /* "what" points to a struct dict_object containing a command (see below) */ +}; + +/*** + * API usage : + +The "parent" parameter of dict_new may point to a vendor object to inform of what vendor defines the application. +for standard-track applications, the "parent" parameter should be NULL. +The vendor associated to an application is retrieved with VENDOR_OF_APPLICATION search criteria on vendors. + +- fd_dict_new: + Sample code for application creation: + { + int ret; + struct dict_object * vendor; + struct dict_object * appl; + struct dict_vendor_data vendor_data = { + 23455, + "my vendor name" + }; + struct dict_application_data app_data = { + 9789, + "my vendor's application" + }; + + ret = fd_dict_new ( dict, DICT_VENDOR, &vendor_data, NULL, &vendor ); + ret = fd_dict_new ( dict, DICT_APPLICATION, &app_data, vendor, &appl ); + } + +- fd_dict_search: + Sample code to retrieve the vendor of an application + { + int ret; + struct dict_object * vendor, * appli; + + ret = fd_dict_search ( dict, DICT_APPLICATION, APPLICATION_BY_NAME, "my vendor's application", &appli, ENOENT); + ret = fd_dict_search ( dict, DICT_VENDOR, VENDOR_OF_APPLICATION, appli, &vendor, ENOENT); + } + + - fd_dict_getval: + Sample code to retrieve the data from an application object: + { + int ret; + struct dict_object * appli; + struct dict_application_data appl_data; + ret = fd_dict_search ( dict, DICT_APPLICATION, APPLICATION_BY_NAME, "my vendor's application", &appli, ENOENT); + ret = fd_dict_getval ( appli, &appl_data ); + printf("my application id: %s\n", appl_data.application_id ); + } + +*/ + +/* + *************************************************************************** + * + * Type object + * + * These types are used to manage AVP data types in the dictionary + * + *************************************************************************** + */ + +/* Type to store any AVP value */ +union avp_value { + struct { + uint8_t *data; /* bytes buffer */ + size_t len; /* length of the data buffer */ + } os; /* Storage for an octet string */ + int32_t i32; /* integer 32 */ + int64_t i64; /* integer 64 */ + uint32_t u32; /* unsigned 32 */ + uint64_t u64; /* unsigned 64 */ + float f32; /* float 32 */ + double f64; /* float 64 */ +}; + +/* These are the basic AVP types defined in RFC3588bis */ +enum dict_avp_basetype { + AVP_TYPE_GROUPED, + AVP_TYPE_OCTETSTRING, + AVP_TYPE_INTEGER32, + AVP_TYPE_INTEGER64, + AVP_TYPE_UNSIGNED32, + AVP_TYPE_UNSIGNED64, + AVP_TYPE_FLOAT32, + AVP_TYPE_FLOAT64 +#define AVP_TYPE_MAX AVP_TYPE_FLOAT64 +}; + +/* Callbacks that can be associated with a derived type to easily interpret the AVP value. */ +/* + * CALLBACK: dict_avpdata_interpret + * + * PARAMETERS: + * val : Pointer to the AVP value that must be interpreted. + * interpreted : The result of interpretation is stored here. The format and meaning depends on each type. + * + * DESCRIPTION: + * This callback can be provided with a derived type in order to facilitate the interpretation of formated data. + * For example, when an AVP of type "Address" is received, it can be used to convert the octetstring into a struct sockaddr. + * This callback is not called directly, but through the message's API msg_avp_value_interpret function. + * + * RETURN VALUE: + * 0 : Operation complete. + * !0 : An error occurred, the error code is returned. + */ +typedef int (*dict_avpdata_interpret) (union avp_value * value, void * interpreted); +/* + * CALLBACK: dict_avpdata_encode + * + * PARAMETERS: + * data : The formated data that must be stored in the AVP value. + * val : Pointer to the AVP value storage area where the data must be stored. + * + * DESCRIPTION: + * This callback can be provided with a derived type in order to facilitate the encoding of formated data. + * For example, it can be used to convert a struct sockaddr in an AVP value of type Address. + * This callback is not called directly, but through the message's API msg_avp_value_encode function. + * If the callback is defined for an OctetString based type, the created string must be malloc'd. free will be called + * automatically later. + * + * RETURN VALUE: + * 0 : Operation complete. + * !0 : An error occurred, the error code is returned. + */ +typedef int (*dict_avpdata_encode) (void * data, union avp_value * val); + +/* + * CALLBACK: dict_avpdata_check + * + * PARAMETERS: + * val : Pointer to the AVP value that was received and needs to be sanity checked. + * data : a parameter stored in the type structure (to enable more generic check functions) + * error_msg: upon erroneous value, a string describing the error can be returned here (it will be strcpy by caller). This description will be returned in the error message, if any. + * + * DESCRIPTION: + * This callback can be provided with a derived type in order to improve the operation of the + * fd_msg_parse_dict function. When this callback is present, the value of the AVP that has + * been parsed is passed to this function for finer granularity check. For example for some + * speccific AVP, the format of an OCTETSTRING value can be further checked, or the + * interger value can be verified. + * + * RETURN VALUE: + * 0 : The value is valid. + * !0 : An error occurred, the error code is returned. It is advised to return EINVAL on incorrect val + */ +typedef int (*dict_avpdata_check) (void * data, union avp_value * val, char ** error_msg); + + + +/* Type to hold data associated to a derived AVP data type */ +struct dict_type_data { + enum dict_avp_basetype type_base; /* How the data of such AVP must be interpreted */ + char * type_name; /* The name of this type */ + dict_avpdata_interpret type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */ + dict_avpdata_encode type_encode; /* cb to convert formatted data into an AVP value (or NULL) */ + DECLARE_FD_DUMP_PROTOTYPE((*type_dump), union avp_value * val); /* cb called by fd_msg_dump_* for this type of data (if != NULL). Returned string must be freed. */ + dict_avpdata_check type_check; + void * type_check_param; +}; + +/* The criteria for searching a type object in the dictionary */ +enum { + TYPE_BY_NAME = 30, /* "what" points to a char * */ + TYPE_OF_ENUMVAL, /* "what" points to a struct dict_object containing an enumerated constant (DICT_ENUMVAL, see below). */ + TYPE_OF_AVP /* "what" points to a struct dict_object containing an AVP object. */ +}; + +/**** + Callbacks defined in libfdproto/dictionary_functions.c file -- see that file for usage. + */ + +/* Convert an Address type AVP into a struct sockaddr_storage */ +int fd_dictfct_Address_encode(void * data, union avp_value * avp_value); +int fd_dictfct_Address_interpret(union avp_value * avp_value, void * interpreted); +DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Address_dump, union avp_value * avp_value); + +/* Display the content of an AVP of type UTF8String in the log file */ +DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_UTF8String_dump, union avp_value * avp_value); + +/* For Time AVPs, map with time_t value directly */ +int fd_dictfct_Time_encode(void * data, union avp_value * avp_value); +int fd_dictfct_Time_interpret(union avp_value * avp_value, void * interpreted); +DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value); + + +/* For string AVP, the following type_check function provides simple basic check for specific characters presence, e.g. use "@." for trivial email address check */ +int fd_dictfct_CharInOS_check(void * data, union avp_value * val, char ** error_msg); + + +/****/ + +/*** + * API usage : + +- fd_dict_new: + The "parent" parameter may point to an application object, when a type is defined by a Diameter application. + + Sample code: + { + int ret; + struct dict_object * mytype; + struct dict_type_data mytypedata = + { + AVP_TYPE_OCTETSTRING, + "Address", + NULL, + NULL + }; + ret = fd_dict_new ( dict, DICT_TYPE, &mytypedata, NULL, &mytype ); + } + +- fd_dict_search: + Sample code: + { + int ret; + struct dict_object * address_type; + ret = fd_dict_search ( dict, DICT_TYPE, TYPE_BY_NAME, "Address", &address_type, ENOENT); + } + +*/ + +/* + *************************************************************************** + * + * Enumerated values object + * + * These types are used to manage named constants of some AVP, + * for enumerated types. freeDiameter allows constants for types others than Unsigned32 + * + *************************************************************************** + */ + +/* Type to hold data of named constants for AVP */ +struct dict_enumval_data { + char * enum_name; /* The name of this constant */ + union avp_value enum_value; /* Value of the constant. Union term depends on parent type's base type. */ +}; + +/* The criteria for searching a constant in the dictionary */ +enum { + ENUMVAL_BY_STRUCT = 40, /* "what" points to a struct dict_enumval_request as defined below */ + ENUMVAL_BY_NAME, /* This cannot be used for researches */ + ENUMVAL_BY_VALUE /* This cannot be used for researches */ +}; + +struct dict_enumval_request { + /* Identifier of the parent type, one of the following must not be NULL */ + struct dict_object *type_obj; + char * type_name; + + /* Search criteria for the constant */ + struct dict_enumval_data search; /* search.enum_value is used only if search.enum_name == NULL */ +}; + +/*** + * API usage : + +- fd_dict_new: + The "parent" parameter must point to a derived type object. + Sample code to create a type "Boolean" with two constants "True" and "False": + { + int ret; + struct dict_object * type_boolean; + struct dict_type_data type_boolean_data = + { + AVP_TYPE_INTEGER32, + "Boolean", + NULL, + NULL + }; + struct dict_enumval_data boolean_false = + { + .enum_name="False", + .enum_value.i32 = 0 + }; + struct dict_enumval_data boolean_true = + { + .enum_name="True", + .enum_value.i32 = -1 + }; + ret = fd_dict_new ( dict, DICT_TYPE, &type_boolean_data, NULL, &type_boolean ); + ret = fd_dict_new ( dict, DICT_ENUMVAL, &boolean_false, type_boolean, NULL ); + ret = fd_dict_new ( dict, DICT_ENUMVAL, &boolean_true , type_boolean, NULL ); + + } + +- fd_dict_search: + Sample code to look for a constant name, by its value: + { + int ret; + struct dict_object * value_found; + struct dict_enumval_request boolean_by_value = + { + .type_name = "Boolean", + .search.enum_name=NULL, + .search.enum_value.i32 = -1 + }; + + ret = fd_dict_search ( dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &boolean_by_value, &value_found, ENOENT); + } + + - fd_dict_getval: + Sample code to retrieve the data from a constant object: + { + int ret; + struct dict_object * value_found; + struct dict_enumval_data boolean_data = NULL; + struct dict_enumval_request boolean_by_value = + { + .type_name = "Boolean", + .search.enum_name=NULL, + .search.enum_value.i32 = 0 + }; + + ret = fd_dict_search ( dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &boolean_by_value, &value_found, ENOENT); + ret = fd_dict_getval ( value_found, &boolean_data ); + printf(" Boolean with value 0: %s", boolean_data.enum_name ); + } +*/ + +/* + *************************************************************************** + * + * AVP object + * + * These objects are used to manage AVP definitions in the dictionary + * + *************************************************************************** + */ + +/* Type to hold an AVP code. For vendor 0, these codes are assigned by IANA. Otherwise, it is managed by the vendor */ +typedef uint32_t avp_code_t; + +/* Values of AVP flags */ +#define AVP_FLAG_VENDOR 0x80 +#define AVP_FLAG_MANDATORY 0x40 +#define AVP_FLAG_RESERVED3 0x20 +#define AVP_FLAG_RESERVED4 0x10 +#define AVP_FLAG_RESERVED5 0x08 +#define AVP_FLAG_RESERVED6 0x04 +#define AVP_FLAG_RESERVED7 0x02 +#define AVP_FLAG_RESERVED8 0x01 + +/* For dumping flags and values */ +#define DUMP_AVPFL_str "%c%c%s%s%s%s%s%s" +#define DUMP_AVPFL_val(_val) (_val & AVP_FLAG_VENDOR)?'V':'-' , (_val & AVP_FLAG_MANDATORY)?'M':'-', \ + (_val & AVP_FLAG_RESERVED3)?"3":"", (_val & AVP_FLAG_RESERVED4)?"4":"", \ + (_val & AVP_FLAG_RESERVED5)?"5":"", (_val & AVP_FLAG_RESERVED6)?"6":"", (_val & AVP_FLAG_RESERVED7)?"7":"", (_val & AVP_FLAG_RESERVED8)?"8":"" + +/* Type to hold data associated to an avp */ +struct dict_avp_data { + avp_code_t avp_code; /* Code of the avp */ + vendor_id_t avp_vendor; /* Vendor of the AVP, or 0 */ + char * avp_name; /* Name of this AVP */ + uint8_t avp_flag_mask; /* Mask of fixed AVP flags */ + uint8_t avp_flag_val; /* Values of the fixed flags */ + enum dict_avp_basetype avp_basetype; /* Basic type of data found in the AVP */ +}; + +/* The criteria for searching an avp object in the dictionary */ +enum { + AVP_BY_CODE = 50, /* "what" points to an avp_code_t, vendor is always 0 */ + AVP_BY_NAME, /* "what" points to a char *, vendor is always 0 */ + AVP_BY_NAME_ALL_VENDORS,/* "what" points to a string. Might be quite slow... */ + AVP_BY_STRUCT, /* "what" points to a struct dict_avp_request_ex (see below) */ + + /* kept for backward compatibility, better use AVP_BY_STRUCT above instead */ + AVP_BY_CODE_AND_VENDOR, /* "what" points to a struct dict_avp_request (see below), where avp_vendor and avp_code are set */ + AVP_BY_NAME_AND_VENDOR /* "what" points to a struct dict_avp_request (see below), where avp_vendor and avp_name are set */ +}; + +/* Struct used for some researchs */ +struct dict_avp_request_ex { + struct { + /* Only one of the following fields must be set. */ + struct dict_object * vendor; /* most efficient if already known, set to NULL to ignore */ + vendor_id_t vendor_id; /* set to 0 to ignore -- prefer AVP_BY_CODE or AVP_BY_NAME for vendor 0 */ + const char * vendor_name; /* set to NULL to ignore */ + } avp_vendor; + + struct { + /* Only one of the following fields must be set */ + avp_code_t avp_code; /* set to 0 to ignore */ + const char * avp_name; /* set to NULL to ignore */ + } avp_data; +}; + +struct dict_avp_request { + vendor_id_t avp_vendor; + avp_code_t avp_code; + char * avp_name; +}; + + + +/*** + * API usage : + +If "parent" parameter is not NULL during AVP creation, it must point to a DICT_TYPE object. +The extended type is then attached to the AVP. In case where it is an enumerated type, the value of +AVP is automatically interpreted in debug messages, and in message checks. +The derived type of an AVP can be retrieved with: dict_search ( DICT_TYPE, TYPE_OF_AVP, avp, ... ) + +To create the rules (ABNF) for children of Grouped AVP, see the DICT_RULE related part. + +- fd_dict_new: + Sample code for AVP creation: + { + int ret; + struct dict_object * user_name_avp; + struct dict_object * boolean_type; + struct dict_object * sample_boolean_avp; + struct dict_avp_data user_name_data = { + 1, // code + 0, // vendor + "User-Name", // name + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, // fixed mask: V and M values must always be defined as follow. other flags can be set or cleared + AVP_FLAG_MANDATORY, // the V flag must be cleared, the M flag must be set. + AVP_TYPE_OCTETSTRING // User-Name AVP contains OctetString data (further precision such as UTF8String can be given with a parent derived type) + }; + struct dict_avp_data sample_boolean_data = { + 31337, + 23455, + "Sample-Boolean", + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, + AVP_FLAG_VENDOR, + AVP_TYPE_INTEGER32 // This MUST be the same as parent type's + }; + + -- Create an AVP with a base type -- + ret = fd_dict_new ( dict, DICT_AVP, &user_name_data, NULL, &user_name_avp ); + + -- Create an AVP with a derived type -- + ret = fd_dict_search ( dict, DICT_TYPE, TYPE_BY_NAME, "Boolean", &boolean_type, ENOENT); + ret = fd_dict_new ( dict, DICT_AVP, &sample_boolean_data , boolean_type, &sample_boolean_avp ); + + } + +- fd_dict_search: + Sample code to look for an AVP + { + int ret; + struct dict_object * avp_username; + struct dict_object * avp_sampleboolean; + struct dict_avp_request avpvendorboolean = + { + .avp_vendor = 23455, + .avp_name = "Sample-Boolean" + }; + + ret = fd_dict_search ( dict, DICT_AVP, AVP_BY_NAME, "User-Name", &avp_username, ENOENT); + + ret = fd_dict_search ( dict, DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avpvendorboolean, &avp_sampleboolean, ENOENT); + + -- this would also work, but be slower, because it has to search all vendor dictionaries -- + ret = fd_dict_search ( dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Sample-Boolean", &avp_sampleboolean, ENOENT); + + } + + - fd_dict_getval: + Sample code to retrieve the data from an AVP object: + { + int ret; + struct dict_object * avp_username; + struct dict_avp_data user_name_data; + ret = fd_dict_search ( dict, DICT_AVP, AVP_BY_NAME, "User-Name", &avp_username, ENOENT); + ret = fd_dict_getval ( avp_username, &user_name_data ); + printf("User-Name code: %d\n", user_name_data.avp_code ); + } + +*/ + +/* + *************************************************************************** + * + * Command object + * + * These types are used to manage commands objects in the dictionary + * + *************************************************************************** + */ + +/* Type to hold a Diameter command code: IANA assigned values. 0x0-0x7fffff=standard, 0x800000-0xfffffd=vendors, 0xfffffe-0xffffff=experimental */ +typedef uint32_t command_code_t; + +/* Values of command flags */ +#define CMD_FLAG_REQUEST 0x80 +#define CMD_FLAG_PROXIABLE 0x40 +#define CMD_FLAG_ERROR 0x20 +#define CMD_FLAG_RETRANSMIT 0x10 +#define CMD_FLAG_RESERVED5 0x08 +#define CMD_FLAG_RESERVED6 0x04 +#define CMD_FLAG_RESERVED7 0x02 +#define CMD_FLAG_RESERVED8 0x01 + +/* For dumping flags and values */ +#define DUMP_CMDFL_str "%c%c%c%c%s%s%s%s" +#define DUMP_CMDFL_val(_val) (_val & CMD_FLAG_REQUEST)?'R':'-' , (_val & CMD_FLAG_PROXIABLE)?'P':'-' , (_val & CMD_FLAG_ERROR)?'E':'-' , (_val & CMD_FLAG_RETRANSMIT)?'T':'-', \ + (_val & CMD_FLAG_RESERVED5)?"5":"", (_val & CMD_FLAG_RESERVED6)?"6":"", (_val & CMD_FLAG_RESERVED7)?"7":"", (_val & CMD_FLAG_RESERVED8)?"8":"" + +/* Type to hold data associated to a command */ +struct dict_cmd_data { + command_code_t cmd_code; /* code of the command */ + char * cmd_name; /* Name of the command */ + uint8_t cmd_flag_mask; /* Mask of fixed-value flags */ + uint8_t cmd_flag_val; /* values of the fixed flags */ +}; + +/* The criteria for searching an avp object in the dictionary */ +enum { + CMD_BY_NAME = 60, /* "what" points to a char * */ + CMD_BY_CODE_R, /* "what" points to a command_code_t. The "Request" command is returned. */ + CMD_BY_CODE_A, /* "what" points to a command_code_t. The "Answer" command is returned. */ + CMD_ANSWER /* "what" points to a struct dict_object of a request command. The corresponding "Answer" command is returned. */ +}; + + +/*** + * API usage : + +The "parent" parameter of dict_new may point to an application object to inform of what application defines the command. +The application associated to a command is retrieved with APPLICATION_OF_COMMAND search criteria on applications. + +To create the rules for children of commands, see the DICT_RULE related part. + +Note that the "Request" and "Answer" commands are two independant objects. This allows to have different rules for each. + +- fd_dict_new: + Sample code for command creation: + { + int ret; + struct dict_object * cer; + struct dict_object * cea; + struct dict_cmd_data ce_data = { + 257, // code + "Capabilities-Exchange-Request", // name + CMD_FLAG_REQUEST, // mask + CMD_FLAG_REQUEST // value. Only the "R" flag is constrained here, set. + }; + + ret = fd_dict_new (dict, DICT_COMMAND, &ce_data, NULL, &cer ); + + ce_data.cmd_name = "Capabilities-Exchange-Answer"; + ce_data.cmd_flag_val = 0; // Same constraint on "R" flag, but this time it must be cleared. + + ret = fd_dict_new ( dict, DICT_COMMAND, &ce_data, NULL, &cea ); + } + +- fd_dict_search: + Sample code to look for a command + { + int ret; + struct dict_object * cer, * cea; + command_code_t code = 257; + ret = fd_dict_search ( dict, DICT_COMMAND, CMD_BY_NAME, "Capabilities-Exchange-Request", &cer, ENOENT); + ret = fd_dict_search ( dict, DICT_COMMAND, CMD_BY_CODE_R, &code, &cer, ENOENT); + } + + - fd_dict_getval: + Sample code to retrieve the data from a command object: + { + int ret; + struct dict_object * cer; + struct dict_object * cea; + struct dict_cmd_data cea_data; + ret = fd_dict_search ( dict, DICT_COMMAND, CMD_BY_NAME, "Capabilities-Exchange-Request", &cer, ENOENT); + ret = fd_dict_search ( dict, DICT_COMMAND, CMD_ANSWER, cer, &cea, ENOENT); + ret = fd_dict_getval ( cea, &cea_data ); + printf("Answer to CER: %s\n", cea_data.cmd_name ); + } + +*/ + +/* + *************************************************************************** + * + * Rule object + * + * These objects are used to manage rules in the dictionary (ABNF implementation) + * This is used for checking messages validity (more powerful than a DTD) + * + *************************************************************************** + */ + +/* This defines the kind of rule that is defined */ +enum rule_position { + RULE_FIXED_HEAD = 1, /* The AVP must be at the head of the group. The rule_order field is used to specify the position. */ + RULE_REQUIRED, /* The AVP must be present in the parent, but its position is not defined. */ + RULE_OPTIONAL, /* The AVP may be present in the message. Used to specify a max number of occurences for example */ + RULE_FIXED_TAIL /* The AVP must be at the end of the group. The rule_order field is used to specify the position. */ +}; + +/* Content of a RULE object data */ +struct dict_rule_data { + struct dict_object *rule_avp; /* Pointer to the AVP object that is concerned by this rule */ + enum rule_position rule_position; /* The position in which the rule_avp must appear in the parent */ + unsigned rule_order; /* for RULE_FIXED_* rules, the place. 1,2,3.. for HEAD rules; ...,3,2,1 for TAIL rules. */ + int rule_min; /* Minimum number of occurences. -1 means "default": 0 for optional rules, 1 for other rules */ + int rule_max; /* Maximum number of occurences. -1 means no maximum. 0 means the AVP is forbidden. */ +}; + +/* The criteria for searching a rule in the dictionary */ +enum { + RULE_BY_AVP_AND_PARENT = 70 /* "what" points to a struct dict_rule_request -- see below. This is used to query "what is the rule for this AVP in this group?" */ +}; + +/* Structure for querying the dictionary about a rule */ +struct dict_rule_request { + struct dict_object *rule_parent; /* The grouped avp or command to which the rule apply */ + struct dict_object *rule_avp; /* The AVP concerned by this rule */ +}; + + +/*** + * API usage : + +The "parent" parameter can not be NULL. It points to the object (grouped avp or command) to which this rule apply (i.e. for which the ABNF is defined). + +- fd_dict_new: + Sample code for rule creation. Let's create the Proxy-Info grouped AVP for example. + { + int ret; + struct dict_object * proxy_info_avp; + struct dict_object * proxy_host_avp; + struct dict_object * proxy_state_avp; + struct dict_object * diameteridentity_type; + struct dict_rule_data rule_data; + struct dict_type_data di_type_data = { AVP_TYPE_OCTETSTRING, "DiameterIdentity", NULL, NULL }; + struct dict_avp_data proxy_info_data = { 284, 0, "Proxy-Info", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_FLAG_MANDATORY, AVP_TYPE_GROUPED }; + struct dict_avp_data proxy_host_data = { 280, 0, "Proxy-Host", AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING }; + struct dict_avp_data proxy_state_data = { 33, 0, "Proxy-State",AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, AVP_FLAG_MANDATORY, AVP_TYPE_OCTETSTRING }; + + -- Create the parent AVP + ret = fd_dict_new ( dict, DICT_AVP, &proxy_info_data, NULL, &proxy_info_avp ); + + -- Create the first child AVP. + ret = fd_dict_new ( dict, DICT_TYPE, &di_type_data, NULL, &diameteridentity_type ); + ret = fd_dict_new ( dict, DICT_AVP, &proxy_host_data, diameteridentity_type, &proxy_host_avp ); + + -- Create the other child AVP + ret = fd_dict_new ( dict, DICT_AVP, &proxy_state_data, NULL, &proxy_state_avp ); + + -- Now we can create the rules. Both children AVP are mandatory. + rule_data.rule_position = RULE_REQUIRED; + rule_data.rule_min = -1; + rule_data.rule_max = -1; + + rule_data.rule_avp = proxy_host_avp; + ret = fd_dict_new ( dict, DICT_RULE, &rule_data, proxy_info_avp, NULL ); + + rule_data.rule_avp = proxy_state_avp; + ret = fd_dict_new ( dict, DICT_RULE, &rule_data, proxy_info_avp, NULL ); +} + +- fd_dict_search and fd_dict_getval are similar to previous examples. + +*/ + +/* Define some hard-coded values */ +/* Application */ +#define AI_RELAY 0xffffffff + +/* Commands Codes */ +#define CC_CAPABILITIES_EXCHANGE 257 +#define CC_RE_AUTH 258 +#define CC_ACCOUNTING 271 +#define CC_ABORT_SESSION 274 +#define CC_SESSION_TERMINATION 275 +#define CC_DEVICE_WATCHDOG 280 +#define CC_DISCONNECT_PEER 282 + +/* AVPs (Vendor 0) */ +#define AC_USER_NAME 1 +#define AC_PROXY_STATE 33 +#define AC_HOST_IP_ADDRESS 257 +#define AC_AUTH_APPLICATION_ID 258 +#define AC_ACCT_APPLICATION_ID 259 +#define AC_VENDOR_SPECIFIC_APPLICATION_ID 260 +#define AC_REDIRECT_HOST_USAGE 261 +#define AC_REDIRECT_MAX_CACHE_TIME 262 +#define AC_SESSION_ID 263 +#define AC_ORIGIN_HOST 264 +#define AC_SUPPORTED_VENDOR_ID 265 +#define AC_VENDOR_ID 266 +#define AC_FIRMWARE_REVISION 267 +#define AC_RESULT_CODE 268 +#define AC_PRODUCT_NAME 269 +#define AC_DISCONNECT_CAUSE 273 +#define ACV_DC_REBOOTING 0 +#define ACV_DC_BUSY 1 +#define ACV_DC_NOT_FRIEND 2 +#define AC_ORIGIN_STATE_ID 278 +#define AC_FAILED_AVP 279 +#define AC_PROXY_HOST 280 +#define AC_ERROR_MESSAGE 281 +#define AC_ROUTE_RECORD 282 +#define AC_DESTINATION_REALM 283 +#define AC_PROXY_INFO 284 +#define AC_REDIRECT_HOST 292 +#define AC_DESTINATION_HOST 293 +#define AC_ERROR_REPORTING_HOST 294 +#define AC_ORIGIN_REALM 296 +#define AC_INBAND_SECURITY_ID 299 +#define ACV_ISI_NO_INBAND_SECURITY 0 +#define ACV_ISI_TLS 1 + +/* Error codes from Base protocol +(reference: http://www.iana.org/assignments/aaa-parameters/aaa-parameters.xml#aaa-parameters-4) +Note that currently, rfc3588bis-26 has some different values for some of these +*/ +#define ER_DIAMETER_MULTI_ROUND_AUTH 1001 + +#define ER_DIAMETER_SUCCESS 2001 +#define ER_DIAMETER_LIMITED_SUCCESS 2002 + +#define ER_DIAMETER_COMMAND_UNSUPPORTED 3001 /* 5019 ? */ +#define ER_DIAMETER_UNABLE_TO_DELIVER 3002 +#define ER_DIAMETER_REALM_NOT_SERVED 3003 +#define ER_DIAMETER_TOO_BUSY 3004 +#define ER_DIAMETER_LOOP_DETECTED 3005 +#define ER_DIAMETER_REDIRECT_INDICATION 3006 +#define ER_DIAMETER_APPLICATION_UNSUPPORTED 3007 +#define ER_DIAMETER_INVALID_HDR_BITS 3008 /* 5020 ? */ +#define ER_DIAMETER_INVALID_AVP_BITS 3009 /* 5021 ? */ +#define ER_DIAMETER_UNKNOWN_PEER 3010 /* 5018 ? */ + +#define ER_DIAMETER_AUTHENTICATION_REJECTED 4001 +#define ER_DIAMETER_OUT_OF_SPACE 4002 +#define ER_ELECTION_LOST 4003 + +#define ER_DIAMETER_AVP_UNSUPPORTED 5001 +#define ER_DIAMETER_UNKNOWN_SESSION_ID 5002 +#define ER_DIAMETER_AUTHORIZATION_REJECTED 5003 +#define ER_DIAMETER_INVALID_AVP_VALUE 5004 +#define ER_DIAMETER_MISSING_AVP 5005 +#define ER_DIAMETER_RESOURCES_EXCEEDED 5006 +#define ER_DIAMETER_CONTRADICTING_AVPS 5007 +#define ER_DIAMETER_AVP_NOT_ALLOWED 5008 +#define ER_DIAMETER_AVP_OCCURS_TOO_MANY_TIMES 5009 +#define ER_DIAMETER_NO_COMMON_APPLICATION 5010 +#define ER_DIAMETER_UNSUPPORTED_VERSION 5011 +#define ER_DIAMETER_UNABLE_TO_COMPLY 5012 +#define ER_DIAMETER_INVALID_BIT_IN_HEADER 5013 /* 3011 ? */ +#define ER_DIAMETER_INVALID_AVP_LENGTH 5014 +#define ER_DIAMETER_INVALID_MESSAGE_LENGTH 5015 /* 3012 ? */ +#define ER_DIAMETER_INVALID_AVP_BIT_COMBO 5016 /* deprecated? */ +#define ER_DIAMETER_NO_COMMON_SECURITY 5017 +#define ER_DIAMETER_USER_UNKNOWN 5030 + + +/*============================================================*/ +/* SESSIONS */ +/*============================================================*/ + +/* Modules that want to associate a state with a Session-Id must first register a handler of this type */ +struct session_handler; + +/* This opaque structure represents a session associated with a Session-Id */ +struct session; + +/* The state information that a module associate with a session -- each module defines its own data format */ +struct sess_state; /* declare this in your own extension */ + +typedef DECLARE_FD_DUMP_PROTOTYPE((*session_state_dump), struct sess_state * st); + +/* The following function must be called to activate the session expiry mechanism */ +int fd_sess_start(void); + +/* + * FUNCTION: fd_sess_handler_create + * + * PARAMETERS: + * handler : location where the new handler must be stored. + * cleanup : a callback function that must be called when the session with associated data is destroyed. + * dumper : if not NULL, will be called during fd_sess_dump to display the data associated with a session. NULL otherwise. + * opaque : A pointer that is passed to the cleanup callback -- the content is never examined by the framework. + * + * DESCRIPTION: + * Create a new session handler. This is needed by a module to associate a state with a session object. + * The cleanup handler is called when the session timeout expires, or fd_sess_destroy is called. It must free + * the state associated with the session, and eventually trig other actions (send a STR, ...). + * + * RETURN VALUE: + * 0 : The new handler has been created. + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_sess_handler_create ( struct session_handler ** handler, void (*cleanup)(struct sess_state * state, os0_t sid, void * opaque), session_state_dump dumper, void * opaque ); + + +/* + * FUNCTION: fd_sess_handler_destroy + * + * PARAMETERS: + * handler : location of an handler created by fd_sess_handler_create. + * opaque : the opaque pointer registered with the callback is restored here (if ! NULL). + * + * DESCRIPTION: + * This destroys a session handler (typically called when an application is shutting down). + * If sessions states are registered with this handler, the cleanup callback is called on them. + * + * RETURN VALUE: + * 0 : The handler was destroyed. + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_sess_handler_destroy ( struct session_handler ** handler, void **opaque ); + + + +/* + * FUNCTION: fd_sess_new + * + * PARAMETERS: + * session : The location where the session object will be created upon success. + * diamid : a Diameter Identity, or NULL. + * diamidlen : if diamid is \0-terminated, this can be 0. Otherwise, the length of diamid. + * opt : Additional string, or NULL. Usage is described below. + * optlen : if opt is \0-terminated, this can be 0. Otherwise, the length of opt. + * + * DESCRIPTION: + * Create a new session object. The Session-Id string associated with this session is generated as follow: + * If diamId parameter is provided, the string is created according to the RFC: ;;[;opt] where + * diamId is a Diameter Identity. + * high32 and low32 are the parts of a monotonic 64 bits counter initialized to (time, 0) at startup. + * opt is an optional string that can be concatenated to the identifier. + * If diamId is NULL, the string is exactly the content of opt. + * + * RETURN VALUE: + * 0 : The session is created, the initial msg refcount is 1. + * EINVAL : A parameter is invalid. + * EALREADY : A session with the same name already exists (returned in *session), the msg refcount is increased. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen ); + +/* + * FUNCTION: fd_sess_fromsid + * + * PARAMETERS: + * sid : pointer to a string containing a Session-Id (should be UTF-8). + * len : length of the sid string (which does not need to be '\0'-terminated) + * session : On success, pointer to the session object created / retrieved. + * isnew : if not NULL, set to 1 on return if the session object has been created, 0 if it was simply retrieved. + * + * DESCRIPTION: + * Retrieve a session object from a Session-Id string. In case no session object was previously existing with this + * id, a new object is silently created (equivalent to fd_sess_new with flag SESSION_NEW_FULL). + * + * RETURN VALUE: + * 0 : The session parameter has been updated. + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * isnew); + +/* only use the following in specific situations, e.g. app_radgw extension. They are normally handled by the framework only */ +int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * isnew); +int fd_sess_ref_msg ( struct session * session ); + +/* + * FUNCTION: fd_sess_getsid + * + * PARAMETERS: + * session : Pointer to a session object. + * sid : On success, the location of the sid is stored here. + * + * DESCRIPTION: + * Retrieve the session identifier (Session-Id) corresponding to a session object. + * The returned sid is a \0-terminated binary string which might be UTF-8 (but there is no guarantee in the framework). + * It may be used for example to set the value of an AVP. + * Note that the sid string is not copied, just its reference... do not free it! + * + * RETURN VALUE: + * 0 : The sid & len parameters have been updated. + * EINVAL : A parameter is invalid. + */ +int fd_sess_getsid ( struct session * session, os0_t * sid, size_t * sidlen ); + +/* + * FUNCTION: fd_sess_settimeout + * + * PARAMETERS: + * session : The session for which to set the timeout. + * timeout : The date when the session times out. + * + * DESCRIPTION: + * Set the lifetime for a given session object. This function may be + * called several times on the same object to update the timeout value. + * When the timeout date is reached, the cleanup handler of each + * module that registered data with this session is called, then the + * session is cleared. + * + * There is a possible race condition between cleanup of the session + * and use of its data; applications should ensure that they are not + * using data from a session that is about to expire / expired. + * + * RETURN VALUE: + * 0 : The session timeout has been updated. + * EINVAL : A parameter is invalid. + */ +int fd_sess_settimeout( struct session * session, const struct timespec * timeout ); + +/* + * FUNCTION: fd_sess_destroy + * + * PARAMETERS: + * session : Pointer to a session object. + * + * DESCRIPTION: + * Destroys all associated states of a session, if any. + * Equivalent to a session timeout expired, but the effect is immediate. + * The session itself is marked as deleted, and will be freed when it is not referenced + * by any message anymore. + * + * RETURN VALUE: + * 0 : The session no longer exists. + * EINVAL : A parameter is invalid. + */ +int fd_sess_destroy ( struct session ** session ); + +/* + * FUNCTION: fd_sess_reclaim + * + * PARAMETERS: + * session : Pointer to a session object. + * + * DESCRIPTION: + * Equivalent to fd_sess_destroy, only if no session_state is associated with the session. + * Otherwise, this function has no effect (except that it sets *session to NULL). + * + * RETURN VALUE: + * 0 : The session was reclaimed. + * EINVAL : A parameter is invalid. + */ +int fd_sess_reclaim ( struct session ** session ); + + + + +/* + * FUNCTION: fd_sess_state_store + * + * PARAMETERS: + * handler : The handler with which the state is registered. + * session : The session object with which the state is registered. + * state : An application state (opaque data) to store with the session. + * + * DESCRIPTION: + * Stores an application state with a session. This state can later be retrieved + * with fd_sess_state_retrieve, or implicitly in the cleanup handler when the session + * is destroyed. + * + * RETURN VALUE: + * 0 : The state has been stored. + * EINVAL : A parameter is invalid. + * EALREADY : Data was already associated with this session and client. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_sess_state_store ( struct session_handler * handler, struct session * session, struct sess_state ** state ); + +/* + * FUNCTION: fd_sess_state_retrieve + * + * PARAMETERS: + * handler : The handler with which the state was registered. + * session : The session object with which the state was registered. + * state : Location where the state must be saved if it is found. + * + * DESCRIPTION: + * Retrieves a state saved by fd_sess_state_store. + * After this function has been called, the state is no longer associated with + * the session. A new call to fd_sess_state_store must be performed in order to + * store again the data with the session. + * + * RETURN VALUE: + * 0 : *state is updated (NULL or points to the state if it was found). + * EINVAL : A parameter is invalid. + */ +int fd_sess_state_retrieve ( struct session_handler * handler, struct session * session, struct sess_state ** state ); + + +/* For debug */ +DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump, struct session * session, int with_states); +DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump_hdl, struct session_handler * handler); + +/* For statistics / monitoring: get the number of struct session in memory */ +int fd_sess_getcount(uint32_t *cnt); + +/*============================================================*/ +/* ROUTING */ +/*============================================================*/ + +/* The following functions are helpers for the routing module. + The routing data is stored in the message itself. */ + +/* Structure that contains the routing data for a message */ +struct rt_data; + +/* Following functions are helpers to create the routing data of a message */ +int fd_rtd_init(struct rt_data ** rtd); +void fd_rtd_free(struct rt_data ** rtd); + +/* Add a peer to the candidates list. */ +int fd_rtd_candidate_add(struct rt_data * rtd, DiamId_t peerid, size_t peeridlen, DiamId_t realm, size_t realmlen); + +/* Remove a peer from the candidates (if it is found). The search is case-insensitive. */ +void fd_rtd_candidate_del(struct rt_data * rtd, uint8_t * id, size_t idsz); + +/* Extract the list of valid candidates, and initialize their scores to 0 */ +void fd_rtd_candidate_extract(struct rt_data * rtd, struct fd_list ** candidates, int ini_score); + +/* If a peer returned a protocol error for this message, save it so that we don't try to send it there again. Optionally retrieve the current list of candidates. */ +int fd_rtd_error_add(struct rt_data * rtd, DiamId_t sentto, size_t senttolen, uint8_t * origin, size_t originsz, uint32_t rcode, struct fd_list ** candidates, int * sendingattemtps); + +/* Only retrieve the number of times this message has been processed by the routing-out mechanism (i.e. number of times it was failed over) */ +int fd_rtd_get_nb_attempts(struct rt_data * rtd, int * sendingattemtps); + +/* The extracted list items have the following structure: */ +struct rtd_candidate { + struct fd_list chain; /* link in the list returned by the previous fcts */ + DiamId_t diamid; /* the diameter Id of the peer */ + size_t diamidlen; /* cached size of the diamid string */ + DiamId_t realm; /* the diameter realm of the peer */ + size_t realmlen; /* cached size of realm */ + int score; /* the current routing score for this peer, see fd_rt_out_register definition for details */ +}; + +/* Reorder the list of peers by score */ +int fd_rtd_candidate_reorder(struct fd_list * candidates); + +/* Note : it is fine for a callback to add a new entry in the candidates list after the list has been extracted. The diamid must then be malloc'd. */ +/* Beware that this could lead to routing loops */ + +/*============================================================*/ +/* MESSAGES */ +/*============================================================*/ + +/* The following types are opaque */ +struct msg; /* A message: command with children AVPs (possibly grand children) */ +struct avp; /* AVP object */ + +/* Some details about chaining: + * + * A message is made of a header ( msg ) and 0 or more AVPs ( avp ). + * The structure is a kind of tree, where some AVPs (grouped AVPs) can contain other AVPs. + * Example: + * msg + * |-avp + * |-gavp + * | |-avp + * | |-avp + * | \-avp + * |-avp + * \-avp + * + */ + +/* The following type is used to point to either a msg or an AVP */ +typedef void msg_or_avp; + +/* The Diameter protocol version */ +#define DIAMETER_VERSION 1 + +/* In the two following types, some fields are marked (READONLY). + * This means that the content of these fields will be overwritten by the daemon so modifying it is useless. + */ + +/* The following structure represents the header of a message. All data is in host byte order. */ +struct msg_hdr { + uint8_t msg_version; /* (READONLY) Version of Diameter: must be DIAMETER_VERSION. */ + uint32_t msg_length; /* (READONLY)(3 bytes) indicates the length of the message */ + uint8_t msg_flags; /* Message flags: CMD_FLAG_* */ + command_code_t msg_code; /* (3 bytes) the command-code. See dictionary-api.h for more detail */ + application_id_t msg_appl; /* The application issuing this message */ + uint32_t msg_hbhid; /* The Hop-by-Hop identifier of the message */ + uint32_t msg_eteid; /* The End-to-End identifier of the message */ +}; + +/* The following structure represents the visible content of an AVP. All data is in host byte order. */ +struct avp_hdr { + avp_code_t avp_code; /* the AVP Code */ + uint8_t avp_flags; /* AVP_FLAG_* flags */ + uint32_t avp_len; /* (READONLY)(Only 3 bytes are used) the length of the AVP as described in the RFC */ + vendor_id_t avp_vendor; /* Only used if AVP_FLAG_VENDOR is present */ + union avp_value *avp_value; /* pointer to the value of the AVP. NULL means that the value is not set / not understood. + One should not directly change this value. Use the msg_avp_setvalue function instead. + The content of the pointed structure can be changed directly, with this restriction: + if the AVP is an OctetString, and you change the value of the pointer avp_value->os.data, then + you must call free() on the previous value, and the new one must be free()-able. + */ +}; + +/* The following enum is used to browse inside message hierarchy (msg, gavp, avp) */ +enum msg_brw_dir { + MSG_BRW_NEXT = 1, /* Get the next element at the same level, or NULL if this is the last element. */ + MSG_BRW_PREV, /* Get the previous element at the same level, or NULL if this is the first element. */ + MSG_BRW_FIRST_CHILD, /* Get the first child AVP of this element, if any. */ + MSG_BRW_LAST_CHILD, /* Get the last child AVP of this element, if any. */ + MSG_BRW_PARENT, /* Get the parent element of this element, if any. Only the msg_t object has no parent. */ + MSG_BRW_WALK /* This is equivalent to FIRST_CHILD or NEXT or PARENT->next, first that is not NULL. Use this to walk inside all AVPs. */ +}; + +/* Some flags used in the functions below */ +#define AVPFL_SET_BLANK_VALUE 0x01 /* When creating an AVP, initialize its value to a blank area */ +#define AVPFL_SET_RAWDATA_FROM_AVP 0x02 /* When creating an AVP, initialize its rawdata area from an existing AVP -- it is only blank padding (for error reporting) */ +#define AVPFL_MAX AVPFL_SET_RAWDATA_FROM_AVP /* The biggest valid flag value */ + +#define MSGFL_ALLOC_ETEID 0x01 /* When creating a message, a new end-to-end ID is allocated and set in the message */ +#define MSGFL_ANSW_ERROR 0x02 /* When creating an answer message, set the 'E' bit and use the generic error ABNF instead of command-specific ABNF */ +#define MSGFL_ANSW_NOSID 0x04 /* When creating an answer message, do not add the Session-Id even if present in request */ +#define MSGFL_ANSW_NOPROXYINFO 0x08 /* When creating an answer message, do not add the Proxy-Info AVPs presents in request */ +#define MSGFL_MAX MSGFL_ANSW_NOPROXYINFO /* The biggest valid flag value */ + +/**************************************************/ +/* Message creation, manipulation, disposal */ +/**************************************************/ +/* + * FUNCTION: fd_msg_avp_new + * + * PARAMETERS: + * model : Pointer to a DICT_AVP dictionary object describing the avp to create, or NULL if flags are used. + * flags : Flags to use in creation (AVPFL_*, see above). + * avp : Upon success, pointer to the new avp is stored here. It points to reference AVP upon function call when flags are used. + * + * DESCRIPTION: + * Create a new AVP instance. + * + * RETURN VALUE: + * 0 : The AVP is created. + * EINVAL : A parameter is invalid. + * (other standard errors may be returned, too, with their standard meaning. Example: + * ENOMEM : Memory allocation for the new avp failed.) + */ +int fd_msg_avp_new ( struct dict_object * model, int flags, struct avp ** avp ); + +/* + * FUNCTION: fd_msg_new + * + * PARAMETERS: + * model : Pointer to a DICT_COMMAND dictionary object describing the message to create, or NULL. + * flags : combination of MSGFL_* flags. + * msg : Upon success, pointer to the new message is stored here. + * + * DESCRIPTION: + * Create a new empty Diameter message. + * + * RETURN VALUE: + * 0 : The message is created. + * EINVAL : A parameter is invalid. + * (other standard errors may be returned, too, with their standard meaning. Example: + * ENOMEM : Memory allocation for the new message failed.) + */ +int fd_msg_new ( struct dict_object * model, int flags, struct msg ** msg ); + +/* + * FUNCTION: msg_new_answer_from_req + * + * PARAMETERS: + * dict : Pointer to the dictionary containing the model of the query. + * msg : The location of the query on function call. Updated by the location of answer message on return. + * flag : Pass MSGFL_ANSW_ERROR to indicate if the answer is an error message (will set the 'E' bit) + * : See other MSGFL_ANSW_* definition above for other flags. + * + * DESCRIPTION: + * This function creates the empty answer message corresponding to a request. + * The header is set properly (R flag, ccode, appid, hbhid, eteid) + * The Session-Id AVP is copied if present. + * The calling code should usually call fd_msg_rescode_set function on the answer. + * Upon return, the original query may be retrieved by calling fd_msg_answ_getq on the message. + * + * RETURN VALUE: + * 0 : Operation complete. + * !0 : an error occurred. + */ +int fd_msg_new_answer_from_req ( struct dictionary * dict, struct msg ** msg, int flag ); + +/* + * FUNCTION: fd_msg_browse + * + * PARAMETERS: + * reference : Pointer to a struct msg or struct avp. + * dir : Direction for browsing + * found : If not NULL, updated with the element that has been found, if any, or NULL if no element was found / an error occurred. + * depth : If not NULL, points to an integer representing the "depth" of this object in the tree. This is a relative value, updated on return. + * + * DESCRIPTION: + * Explore the content of a message object (hierarchy). If "found" is null, only error checking is performed. + * If "depth" is provided, it is updated as follow on successful function return: + * - not modified for MSG_BRW_NEXT and MSG_BRW_PREV. + * - *depth = *depth + 1 for MSG_BRW_FIRST_CHILD and MSG_BRW_LAST_CHILD. + * - *depth = *depth - 1 for MSG_BRW_PARENT. + * - *depth = *depth + X for MSG_BRW_WALK, with X between 1 (returned the 1st child) and -N (returned the Nth parent's next). + * + * RETURN VALUE: + * 0 : found has been updated (if non NULL). + * EINVAL : A parameter is invalid. + * ENOENT : No element has been found where requested, and "found" was NULL (otherwise, *found is set to NULL and 0 is returned). + */ +int fd_msg_browse_internal ( msg_or_avp * reference, enum msg_brw_dir dir, msg_or_avp ** found, int * depth ); +/* Macro to avoid having to cast the third parameter everywhere */ +#define fd_msg_browse( ref, dir, found, depth ) \ + fd_msg_browse_internal( (ref), (dir), (void *)(found), (depth) ) + + +/* + * FUNCTION: fd_msg_avp_add + * + * PARAMETERS: + * reference : Pointer to a valid msg or avp. + * dir : location where the new AVP should be inserted, relative to the reference. MSG_BRW_PARENT and MSG_BRW_WALK are not valid. + * avp : pointer to the AVP object that must be inserted. + * + * DESCRIPTION: + * Adds an AVP into an object that can contain it: grouped AVP or message. + * Note that the added AVP will be freed at the same time as the object it is added to, + * so it should not be freed after the call to this function. + * + * RETURN VALUE: + * 0 : The AVP has been added. + * EINVAL : A parameter is invalid. + */ +int fd_msg_avp_add ( msg_or_avp * reference, enum msg_brw_dir dir, struct avp *avp); + +/* + * FUNCTION: fd_msg_search_avp + * + * PARAMETERS: + * msg : The message structure in which to search the AVP. + * what : The dictionary model of the AVP to search. + * avp : location where the AVP reference is stored if found. + * + * DESCRIPTION: + * Search the first top-level AVP of a given model inside a message. + * Note: only the first instance of the AVP is returned by this function. + * Note: only top-level AVPs are searched, not inside grouped AVPs. + * Use msg_browse if you need more advanced research features. + * + * RETURN VALUE: + * 0 : The AVP has been found. + * EINVAL : A parameter is invalid. + * ENOENT : No AVP has been found, and "avp" was NULL (otherwise, *avp is set to NULL and 0 returned). + */ +int fd_msg_search_avp ( struct msg * msg, struct dict_object * what, struct avp ** avp ); + +/* + * FUNCTION: fd_msg_free + * + * PARAMETERS: + * object : pointer to the message or AVP object that must be unlinked and freed. + * + * DESCRIPTION: + * Unlink and free a message or AVP object and its children. + * If the object is an AVP linked into a message, the AVP is removed before being freed. + * + * RETURN VALUE: + * 0 : The message has been freed. + * EINVAL : A parameter is invalid. + */ +int fd_msg_free ( msg_or_avp * object ); + +/***************************************/ +/* Dump functions */ +/***************************************/ +/* + * FUNCTION: fd_msg_dump_* + * + * PARAMETERS: + * see definition of DECLARE_FD_DUMP_PROTOTYPE, + * obj : A msg or avp object to dump. + * dict : the dictionary to use if parsing is requested (optional) + * force_parsing: by default these functions do not parse the object but dump hexa values in that case. + * use !0 to force parsing. If parsing fails, the hexa dump is still provided. + * recurse : allow the function to go through the children objects if any to dump more information. might require parsing. + * + * DESCRIPTION: + * These functions dump the content of a message or avp into a buffer + * either recursively or only the object itself. + * + * RETURN VALUE: + * - see DECLARE_FD_DUMP_PROTOTYPE, + */ +/* one-line dump with only short information */ +DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ); +/* one-line dump with all the contents of the message */ +DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ); +/* multi-line human-readable dump similar to wireshark output */ +DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_treeview, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ); + + +/*********************************************/ +/* Message metadata management functions */ +/*********************************************/ +/* + * FUNCTION: fd_msg_model + * + * PARAMETERS: + * reference : Pointer to a valid msg or avp. + * model : on success, pointer to the dictionary model of this command or AVP. NULL if the model is unknown. + * + * DESCRIPTION: + * Retrieve the dictionary object describing this message or avp. If the object is unknown or the fd_msg_parse_dict has not been called, + * *model is set to NULL. + * + * RETURN VALUE: + * 0 : The model has been set. + * EINVAL : A parameter is invalid. + */ +int fd_msg_model ( msg_or_avp * reference, struct dict_object ** model ); + +/* + * FUNCTION: fd_msg_hdr + * + * PARAMETERS: + * msg : Pointer to a valid message object. + * pdata : Upon success, pointer to the msg_hdr structure of this message. The fields may be modified. + * + * DESCRIPTION: + * Retrieve location of modifiable section of a message. + * + * RETURN VALUE: + * 0 : The location has been written. + * EINVAL : A parameter is invalid. + */ +int fd_msg_hdr ( struct msg *msg, struct msg_hdr ** pdata ); + +/* + * FUNCTION: fd_msg_avp_hdr + * + * PARAMETERS: + * avp : Pointer to a valid avp object. + * pdata : Upon success, pointer to the avp_hdr structure of this avp. The fields may be modified. + * + * DESCRIPTION: + * Retrieve location of modifiable data of an avp. + * + * RETURN VALUE: + * 0 : The location has been written. + * EINVAL : A parameter is invalid. + */ +int fd_msg_avp_hdr ( struct avp *avp, struct avp_hdr ** pdata ); + +/* + * FUNCTION: fd_msg_answ_associate, fd_msg_answ_getq, fd_msg_answ_detach + * + * PARAMETERS: + * answer : the received answer message + * query : the corresponding query that had been sent + * + * DESCRIPTION: + * fd_msg_answ_associate associates a query msg with the received answer. + * Query is retrieved with fd_msg_answ_getq. + * If answer message is freed, the query is also freed. + * If the msg_answ_detach function is called, the association is removed. + * This is meant to be called from the daemon only. + * + * RETURN VALUE: + * 0 : ok + * EINVAL: a parameter is invalid + */ +int fd_msg_answ_associate( struct msg * answer, struct msg * query ); +int fd_msg_answ_getq ( struct msg * answer, struct msg ** query ); +int fd_msg_answ_detach ( struct msg * answer ); + +/* + * FUNCTION: fd_msg_anscb_associate, fd_msg_anscb_get + * + * PARAMETERS: + * msg : the request message + * anscb : the callback to associate with the message + * data : the data to pass to the callback + * expirecb : the expiration callback to associate with the message + * timeout : (optional, use NULL if no timeout) a timeout associated with calling the cb. + * + * DESCRIPTION: + * Associate or retrieve callbacks with an message. + * This is meant to be called from the daemon only. + * + * RETURN VALUE: + * 0 : ok + * EINVAL: a parameter is invalid + */ +int fd_msg_anscb_associate( struct msg * msg, void ( *anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ); +int fd_msg_anscb_get( struct msg * msg, void (**anscb)(void *, struct msg **), void (**expirecb)(void *, DiamId_t, size_t, struct msg **), void ** data ); +int fd_msg_anscb_reset(struct msg * msg, int clear_anscb, int clear_expirecb); +struct timespec *fd_msg_anscb_gettimeout( struct msg * msg ); /* returns NULL or a valid non-0 timespec */ + +/* + * FUNCTION: fd_msg_rt_associate, fd_msg_rt_get + * + * PARAMETERS: + * msg : the query message to be sent + * list : the ordered list of possible next-peers + * + * DESCRIPTION: + * Associate a routing list with a query, and retrieve it. + * If the message is freed, the list is also freed. + * + * RETURN VALUE: + * 0 : ok + * EINVAL: a parameter is invalid + */ +int fd_msg_rt_associate( struct msg * msg, struct rt_data * rtd ); +int fd_msg_rt_get ( struct msg * msg, struct rt_data ** rtd ); + +/* + * FUNCTION: fd_msg_is_routable + * + * PARAMETERS: + * msg : A msg object. + * + * DESCRIPTION: + * This function returns a boolean telling if a given message is routable in the Diameter network, + * or if it is a local link message only (ex: CER/CEA, DWR/DWA, ...). + * + * RETURN VALUE: + * 0 : The message is not routable / an error occurred. + * 1 : The message is routable. + */ +int fd_msg_is_routable ( struct msg * msg ); + +/* + * FUNCTION: fd_msg_source_(g/s)et + * + * PARAMETERS: + * msg : A msg object. + * diamid,len : The diameter id of the peer from which this message was received. + * dict : a dictionary with definition of Route-Record AVP (for fd_msg_source_setrr) + * + * DESCRIPTION: + * Store or retrieve the diameted id of the peer from which this message was received. + * Will be used for example by the routing module to add the Route-Record AVP in forwarded requests, + * or to direct answers to the appropriate peer. + * + * RETURN VALUE: + * 0 : Operation complete. + * !0 : an error occurred. + */ +int fd_msg_source_set( struct msg * msg, DiamId_t diamid, size_t diamidlen ); +int fd_msg_source_setrr( struct msg * msg, DiamId_t diamid, size_t diamidlen, struct dictionary * dict ); +int fd_msg_source_get( struct msg * msg, DiamId_t *diamid, size_t * diamidlen ); + +/* + * FUNCTION: fd_msg_eteid_get + * + * PARAMETERS: + * - + * + * DESCRIPTION: + * Get a new unique end-to-end id value for the local peer. + * + * RETURN VALUE: + * The new assigned value. No error code is defined. + */ +uint32_t fd_msg_eteid_get ( void ); + + +/* + * FUNCTION: fd_msg_sess_get + * + * PARAMETERS: + * dict : the dictionary that contains the Session-Id AVP definition + * msg : A valid message. + * session : Location to store the session pointer when retrieved. + * isnew : Indicates if the session has been created. + * + * DESCRIPTION: + * This function retrieves or creates the session object corresponding to a message. + * If the message does not contain a Session-Id AVP, *session == NULL on return. + * Note that the Session-Id AVP must never be modified after created in a message. + * + * RETURN VALUE: + * 0 : success + * !0 : standard error code. + */ +int fd_msg_sess_get(struct dictionary * dict, struct msg * msg, struct session ** session, int * isnew); + +/* This one is used by the libfdcore, you should use fd_msg_new_session rather than fd_sess_new, when possible */ +int fd_msg_sess_set(struct msg * msg, struct session * session); + + +/* Helper for the hooks mechanism, for use from libfdcore */ +struct fd_msg_pmdl { + struct fd_list sentinel; /* if the sentinel.o field is NULL, the structure is not initialized. Otherwise it points to the cleanup function in libfdcore. */ + pthread_mutex_t lock; +}; +struct fd_msg_pmdl * fd_msg_pmdl_get(struct msg * msg); + + +/***************************************/ +/* Manage AVP values */ +/***************************************/ + +/* + * FUNCTION: fd_msg_avp_setvalue + * + * PARAMETERS: + * avp : Pointer to a valid avp object with a NULL avp_value pointer. The model must be known. + * value : pointer to an avp_value. The content will be COPIED into the internal storage area. + * If data type is an octetstring, the data is also copied. + * If value is a NULL pointer, the previous data is erased and value is unset in the AVP. + * + * DESCRIPTION: + * Initialize the avp_value field of an AVP header. + * + * RETURN VALUE: + * 0 : The avp_value pointer has been set. + * EINVAL : A parameter is invalid. + */ +int fd_msg_avp_setvalue ( struct avp *avp, union avp_value *value ); + +/* + * FUNCTION: fd_msg_avp_value_encode + * + * PARAMETERS: + * avp : Pointer to a valid avp object with a NULL avp_value. The model must be known. + * data : Pointer to the data that must be encoded as AVP value and stored in the AVP. + * This is only valid for AVPs of derived type for which type_data_encode callback is set. (ex: Address type) + * + * DESCRIPTION: + * Initialize the avp_value field of an AVP object from formatted data, using the AVP's type "type_data_encode" callback. + * + * RETURN VALUE: + * 0 : The avp_value has been set. + * EINVAL : A parameter is invalid. + * ENOTSUP : There is no appropriate callback registered with this AVP's type. + */ +int fd_msg_avp_value_encode ( void *data, struct avp *avp ); +/* + * FUNCTION: fd_msg_avp_value_interpret + * + * PARAMETERS: + * avp : Pointer to a valid avp object with a non-NULL avp_value value. + * data : Upon success, formatted interpretation of the AVP value is stored here. + * + * DESCRIPTION: + * Interpret the content of an AVP of Derived type and store the result in data pointer. The structure + * of the data pointer is dependent on the AVP type. This function calls the "type_data_interpret" callback + * of the type. + * + * RETURN VALUE: + * 0 : The avp_value has been set. + * EINVAL : A parameter is invalid. + * ENOTSUP : There is no appropriate callback registered with this AVP's type. + */ +int fd_msg_avp_value_interpret ( struct avp *avp, void *data ); + + +/***************************************/ +/* Message parsing functions */ +/***************************************/ + +/* + * FUNCTION: fd_msg_bufferize + * + * PARAMETERS: + * msg : A valid msg object. All AVPs must have a value set. + * buffer : Upon success, this points to a buffer (malloc'd) containing the message ready for network transmission (or security transformations). + * The buffer may be freed after use. + * len : if not NULL, the size of the buffer is written here. In any case, this size is updated in the msg header. + * + * DESCRIPTION: + * Renders a message in memory as a buffer that can be sent over the network to the next peer. + * + * RETURN VALUE: + * 0 : The location has been written. + * EINVAL : The buffer does not contain a valid Diameter message. + * ENOMEM : Unable to allocate enough memory to create the buffer object. + */ +int fd_msg_bufferize ( struct msg * msg, uint8_t ** buffer, size_t * len ); + +/* + * FUNCTION: fd_msg_parse_buffer + * + * PARAMETERS: + * buffer : Pointer to a buffer containing a message received from the network. + * buflen : the size in bytes of the buffer. + * msg : Upon success, this points to a valid msg object. No AVP value is resolved in this object, nor grouped AVP. + * + * DESCRIPTION: + * This function parses a buffer an creates a msg object to represent the structure of the message. + * Since no dictionary lookup is performed, the values of the AVPs are not interpreted. To interpret the values, + * the returned message object must be passed to fd_msg_parse_dict function. + * The buffer pointer is saved inside the message and will be freed when not needed anymore. + * + * RETURN VALUE: + * 0 : The location has been written. + * ENOMEM : Unable to allocate enough memory to create the msg object. + * EBADMSG : The buffer does not contain a valid Diameter message (or is truncated). + * EINVAL : A parameter is invalid. + */ +int fd_msg_parse_buffer ( uint8_t ** buffer, size_t buflen, struct msg ** msg ); + +/* Parsing Error Information structure */ +struct fd_pei { + char * pei_errcode; /* name of the error code to use */ + struct avp * pei_avp; /* pointer to invalid (in original message) or missing AVP (to be freed) */ + int pei_avp_free; /* Set to 1 if the pei_avp must be freed */ + char * pei_message; /* Overwrite default message if needed */ + int pei_protoerr; /* do we set the 'E' bit in the error message ? */ +}; + +/* + * FUNCTION: fd_msg_parse_dict + * + * PARAMETERS: + * object : A msg or AVP object as returned by fd_msg_parse_buffer. + * dict : the dictionary containing the objects definitions to use for resolving all AVPs. + * error_info : If not NULL, will contain the detail about error upon return. May be used to generate an error reply. + * + * DESCRIPTION: + * This function looks up for the command and each children AVP definitions in the dictionary. + * If the dictionary definition is found, avp_model is set and the value of the AVP is interpreted accordingly and: + * - for grouped AVPs, the children AVP are created and interpreted also. + * - for numerical AVPs, the value is converted to host byte order and saved in the avp_value field. + * - for octetstring AVPs, the string is copied into a new buffer and its address is saved in avp_value. + * If the dictionary definition is not found, avp_model is set to NULL and + * the content of the AVP is saved as an octetstring in an internal structure. avp_value is NULL. + * As a result, after this function has been called, there is no more dependency of the msg object to the message buffer, that is freed. + * + * RETURN VALUE: + * 0 : The message has been fully parsed as described. + * EINVAL : The msg parameter is invalid for this operation. + * ENOMEM : Unable to allocate enough memory to complete the operation. + * ENOTSUP : No dictionary definition for the command or one of the mandatory AVP was found. + */ +int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict, struct fd_pei * error_info ); + +/* + * FUNCTION: fd_msg_parse_rules + * + * PARAMETERS: + * object : A msg or grouped avp object that must be verified. + * dict : The dictionary containing the rules definitions. + * error_info : If not NULL, the first problem information will be saved here. + * + * DESCRIPTION: + * Check that the children of the object do not conflict with the dictionary rules (ABNF compliance). + * + * RETURN VALUE: + * 0 : The message has been fully parsed and complies to the defined rules. + * EBADMSG : A conflict was detected, or a mandatory AVP is unknown in the dictionary. + * EINVAL : The msg or avp object is invalid for this operation. + * ENOMEM : Unable to allocate enough memory to complete the operation. + */ +int fd_msg_parse_rules ( msg_or_avp * object, struct dictionary * dict, struct fd_pei * error_info); + + + +/* + * FUNCTION: fd_msg_update_length + * + * PARAMETERS: + * object : Pointer to a valid msg or avp. + * + * DESCRIPTION: + * Update the length field of the object passed as parameter. + * As a side effect, all children objects are also updated. Therefore, all avp_value fields of + * the children AVPs must be set, or an error will occur. + * + * RETURN VALUE: + * 0 : The size has been recomputed. + * EINVAL : A parameter is invalid. + */ +int fd_msg_update_length ( msg_or_avp * object ); + + +/*============================================================*/ +/* DISPATCH */ +/*============================================================*/ + +/* Dispatch module (passing incoming messages to extensions registered callbacks) + * is split between the library and the daemon. + * + * The library provides the support for associating dispatch callbacks with + * dictionary objects. + * + * The daemon is responsible for calling the callbacks for a message when appropriate. + * + * + * The dispatch module has two main roles: + * - help determine if a message can be handled locally (during the routing step) + * This decision involves only the application-id of the message. + * - pass the message to the callback(s) that will handle it (during the dispatch step) + * + * The first role is handled by the daemon. + * + * About the second, these are the possibilities for registering a dispatch callback: + * + * -> For All messages. + * This callback is called for all messages that are handled locally. This should be used only + * for debug purpose. + * + * -> by AVP value (constants only). + * This callback will be called when a message is received and contains an AVP with a specified enumerated value. + * + * -> by AVP. + * This callback will be called when the received message contains a certain AVP. + * + * -> by command-code. + * This callback will be called when the message is a specific command (and 'R' flag). + * + * -> by application. + * This callback will be called when the message has a specific application-id. + * + * ( by vendor: would this be useful? it may be added later) + */ +enum disp_how { + DISP_HOW_ANY = 1, /* Any message. This should be only used for debug. */ + DISP_HOW_APPID, /* Any message with the specified application-id */ + DISP_HOW_CC, /* Messages of the specified command-code (request or answer). App id may be specified. */ + DISP_HOW_AVP, /* Messages containing a specific AVP. Command-code and App id may be specified. */ + DISP_HOW_AVP_ENUMVAL /* Messages containing a specific AVP with a specific enumerated value. Command-code and App id may be specified. */ +}; +/* + * Several criteria may be selected at the same time, for example command-code AND application id. + * + * If several callbacks are registered for the same object, they are called in the order they were registered. + * The order in which the callbacks are called is: + * DISP_HOW_ANY + * DISP_HOW_AVP_ENUMVAL & DISP_HOW_AVP + * DISP_HOW_CC + * DISP_HOW_APPID + */ + +/* When a callback is registered, a "when" argument is passed in addition to the disp_how value, + * to specify which values the criteria must match. */ +struct disp_when { + struct dict_object * app; + struct dict_object * command; + struct dict_object * avp; + struct dict_object * value; +}; + +/* Note that all the dictionary objects should really belong to the same dictionary! + * + * Here is the details on this "when" argument, depending on the disp_how value. + * + * DISP_HOW_ANY. + * In this case, "when" must be NULL. + * + * DISP_HOW_APPID. + * Only the "app_id" field must be set, other fields are ignored. It points to a dictionary object of type DICT_APPLICATION. + * + * DISP_HOW_CC. + * The "command" field must be defined and point to a dictionary object of type DICT_COMMAND. + * The "app_id" may be also set. In the case it is set, it restricts the callback to be called only with this command-code and app id. + * The other fields are ignored. + * + * DISP_HOW_AVP. + * The "avp" field of the structure must be set and point to a dictionary object of type DICT_AVP. + * The "app_id" field may be set to restrict the messages matching to a specific app id. + * The "command" field may also be set to a valid DICT_COMMAND object. + * The content of the "value" field is ignored. + * + * DISP_HOW_AVP_ENUMVAL. + * All fields have the same constraints and meaning as in DISP_REG_AVP. In addition, the "value" field must be set + * and points to a valid DICT_ENUMVAL object. + * + * Here is a sumary of the fields: ( M : must be set; m : may be set; 0 : ignored ) + * field: app_id command avp value + * APPID : M 0 0 0 + * CC : m M 0 0 + * AVP : m m M 0 + * ENUMVA: m m M M + */ + +enum disp_action { + DISP_ACT_CONT, /* The next handler should be called, unless *msg == NULL. */ + DISP_ACT_SEND, /* The updated message must be sent. No further callback is called. */ + DISP_ACT_ERROR /* An error must be created and sent as a reply -- not valid for callbacks, only for fd_msg_dispatch. */ +}; +/* The callbacks that are registered have the following prototype: + * int dispatch_callback( struct msg ** msg, struct avp * avp, struct session * session, enum disp_action * action ); + * + * CALLBACK: dispatch_callback + * + * PARAMETERS: + * msg : the received message on function entry. may be updated to answer on return (see description) + * avp : for callbacks registered with DISP_HOW_AVP or DISP_HOW_AVP_ENUMVAL, direct link to the triggering AVP. + * session : if the message contains a Session-Id AVP, the corresponding session object, NULL otherwise. + * opaque : An opaque pointer that is registered along the session handler. + * action : upon return, this tells the daemon what to do next. + * + * DESCRIPTION: + * Called when a received message matchs the condition for which the callback was registered. + * This callback may do any kind of processing on the message, including: + * - create an answer for a request. + * - proxy a request or message, add / remove the Proxy-Info AVP, then forward the message. + * - update a routing table or start a connection with a new peer, then forward the message. + * - ... + * + * When *action == DISP_ACT_SEND on callback return, the msg pointed by *msg is passed to the routing module for sending. + * When *action == DISP_ACT_CONT, the next registered callback is called. + * When the last callback gives also DISP_ACT_CONT action value, a default handler is called. It's behavior is as follow: + * - if the message is an answer, it is discarded. + * - if the message is a request, it is passed again to the routing stack, and marked as non-local handling. + * + * RETURN VALUE: + * 0 : The callback executed successfully and updated *action appropriately. + * !0 : standard errors. In case of error, the message is discarded. + */ + +/* This structure represents a handler for a registered callback, allowing its de-registration */ +struct disp_hdl; + +/* + * FUNCTION: fd_disp_register + * + * PARAMETERS: + * cb : The callback function to register (see dispatch_callback description above). + * how : How the callback must be registered. + * when : Values that must match, depending on the how argument. + * opaque : A pointer that is passed back to the handler. The content is not interpreted by the framework. + * handle : On success, a handler to the registered callback is stored here if not NULL. + * This handler can be used to unregister the cb. + * + * DESCRIPTION: + * Register a new callback to handle messages delivered locally. + * + * RETURN VALUE: + * 0 : The callback is registered. + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation + */ +int fd_disp_register ( int (*cb)( struct msg **, struct avp *, struct session *, void *, enum disp_action *), + enum disp_how how, struct disp_when * when, void * opaque, struct disp_hdl ** handle ); + +/* + * FUNCTION: fd_disp_unregister + * + * PARAMETERS: + * handle : Location of the handle of the callback that must be unregistered. + * opaque : If not NULL, the opaque data that was registered is restored here. + * + * DESCRIPTION: + * Removes a callback previously registered by fd_disp_register. + * + * RETURN VALUE: + * 0 : The callback is unregistered. + * EINVAL : A parameter is invalid. + */ +int fd_disp_unregister ( struct disp_hdl ** handle, void ** opaque ); + +/* Destroy all handlers */ +void fd_disp_unregister_all ( void ); + +/* + * FUNCTION: fd_msg_dispatch + * + * PARAMETERS: + * msg : A msg object that have already been fd_msg_parse_dict. + * session : The session corresponding to this object, if any. + * action : Upon return, the action that must be taken on the message + * error_code : Upon return with action == DISP_ACT_ERROR, contains the error (such as "DIAMETER_UNABLE_TO_COMPLY") + * drop_reason : if set on return, the message must be freed for this reason. + * drop_msg : if drop_reason is set, this points to the message to be freed while *msg is NULL. + * + * DESCRIPTION: + * Call all handlers registered for a given message. + * The session must have already been resolved on entry. + * The msg pointed may be updated during this process. + * Upon return, the action parameter points to what must be done next. + * + * RETURN VALUE: + * 0 : Success. + * EINVAL : A parameter is invalid. + * (other errors) + */ +int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code, char ** drop_reason, struct msg ** drop_msg ); + + + +/*============================================================*/ +/* QUEUES */ +/*============================================================*/ + +/* Management of FIFO queues of elements */ + +/* A queue is an opaque object */ +struct fifo; + +/* + * FUNCTION: fd_fifo_new + * + * PARAMETERS: + * queue : Upon success, a pointer to the new queue is saved here. + * max : max number of items in the queue. Above this number, adding a new item becomes a + * blocking operation. Use 0 to disable this maximum. + * + * DESCRIPTION: + * Create a new empty queue. + * + * RETURN VALUE : + * 0 : The queue has been initialized successfully. + * EINVAL : The parameter is invalid. + * ENOMEM : Not enough memory to complete the creation. + */ +int fd_fifo_new ( struct fifo ** queue, int max ); + +/* + * FUNCTION: fd_fifo_del + * + * PARAMETERS: + * queue : Pointer to an empty queue to delete. + * + * DESCRIPTION: + * Destroys a queue. This is only possible if no thread is waiting for an element, + * and the queue is empty. + * + * RETURN VALUE: + * 0 : The queue has been destroyed successfully. + * EINVAL : The parameter is invalid. + */ +int fd_fifo_del ( struct fifo ** queue ); + +/* + * FUNCTION: fd_fifo_move + * + * PARAMETERS: + * oldq : Location of a FIFO that is to be emptied. + * newq : A FIFO that will receive the old data. + * loc_update : if non NULL, a place to store the pointer to new FIFO atomically with the move. + * + * DESCRIPTION: + * Empties a queue and move its content to another one atomically. + * + * RETURN VALUE: + * 0 : The queue has been destroyed successfully. + * EINVAL : A parameter is invalid. + */ +int fd_fifo_move ( struct fifo * oldq, struct fifo * newq, struct fifo ** loc_update ); + +/* + * FUNCTION: fd_fifo_getstats + * + * PARAMETERS: + * queue : The queue from which to retrieve the information. + * current_count : How many items in the queue at the time of execution. This changes each time an item is pushed or poped. + * limit_count : The maximum number of items allowed in this queue. This is specified during queue creation. + * highest_count : The maximum number of items this queue has contained. This enables to see if limit_count count was reached. + * total_count : the total number of items that went through the queue (already pop'd). Always increasing. + * total : Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring) + * blocking : Cumulated time threads trying to post new items were blocked (queue full). + * last : For the last element retrieved from the queue, how long it take between posting (including blocking) and poping + * + * DESCRIPTION: + * Retrieve the timing information associated with a queue, for monitoring purpose. + * + * RETURN VALUE: + * 0 : The statistics have been updated. + * EINVAL : A parameter is invalid. + */ +int fd_fifo_getstats( struct fifo * queue, int * current_count, int * limit_count, int * highest_count, long long * total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last); + +/* + * FUNCTION: fd_fifo_length + * + * PARAMETERS: + * queue : The queue from which to retrieve the number of elements. + * + * DESCRIPTION: + * Retrieve the number of elements in a queue, without error checking. + * + * RETURN VALUE: + * The number of items currently queued. + */ +int fd_fifo_length ( struct fifo * queue ); + +/* + * FUNCTION: fd_fifo_setthrhd + * + * PARAMETERS: + * queue : The queue for which the thresholds are being set. + * data : An opaque pointer that is passed to h_cb and l_cb callbacks. + * high : The high-level threshold. If the number of elements in the queue increase to this value, h_cb is called. + * h_cb : if not NULL, a callback to call when the queue lengh is bigger than "high". + * low : The low-level threshold. Must be < high. + * l_cb : If the number of elements decrease to low, this callback is called. + * + * DESCRIPTION: + * This function allows to adjust the number of producer / consumer threads of a queue. + * If the consumer are slower than the producers, the number of elements in the queue increase. + * By setting a "high" value, we allow a callback to be called when this number is too high. + * The typical use would be to create an additional consumer thread in this callback. + * If the queue continues to grow, the callback will be called again when the length is 2 * high, then 3*high, ... N * high + * (the callback itself should implement a limit on the number of consumers that can be created) + * When the queue starts to decrease, and the number of elements go under ((N - 1) * high + low, the l_cb callback is called + * and would typially stop one of the consumer threads. If the queue continues to reduce, l_cb is again called at (N-2)*high + low, + * and so on. + * + * Since there is no destructor for the data pointer, if cleanup operations are required, they should be performed in + * l_cb when the length of the queue is becoming < low. + * + * Note that the callbacks are called synchronously, during fd_fifo_post or fd_fifo_get. Their operation should be quick. + * + * RETURN VALUE: + * 0 : The thresholds have been set + * EINVAL : A parameter is invalid. + */ +int fd_fifo_setthrhd ( struct fifo * queue, void * data, uint16_t high, void (*h_cb)(struct fifo *, void **), uint16_t low, void (*l_cb)(struct fifo *, void **) ); + +/* + * FUNCTION: fd_fifo_post + * + * PARAMETERS: + * queue : The queue in which the element must be posted. + * item : The element that is put in the queue. + * + * DESCRIPTION: + * An element is added in a queue. Elements are retrieved from the queue in FIFO order + * with the fd_fifo_get, fd_fifo_tryget, or fd_fifo_timedget functions. + * + * RETURN VALUE: + * 0 : The element is queued. + * EINVAL : A parameter is invalid. + * ENOMEM : Not enough memory to complete the operation. + */ +int fd_fifo_post_int ( struct fifo * queue, void ** item ); +#define fd_fifo_post(queue, item) \ + fd_fifo_post_int((queue), (void *)(item)) + +/* Similar function but does not block. It can cause the number of items in the queue to exceed the maximum set. Do not use for normal operation, +only for failure recovery for example. */ +int fd_fifo_post_noblock( struct fifo * queue, void ** item ); + +/* + * FUNCTION: fd_fifo_get + * + * PARAMETERS: + * queue : The queue from which the first element must be retrieved. + * item : On return, the first element of the queue is stored here. + * + * DESCRIPTION: + * This function retrieves the first element from a queue. If the queue is empty, the function will block the + * thread until a new element is posted to the queue, or until the thread is canceled (in which case the + * function does not return). + * + * RETURN VALUE: + * 0 : A new element has been retrieved. + * EINVAL : A parameter is invalid. + */ +int fd_fifo_get_int ( struct fifo * queue, void ** item ); +#define fd_fifo_get(queue, item) \ + fd_fifo_get_int((queue), (void *)(item)) + +/* + * FUNCTION: fd_fifo_tryget + * + * PARAMETERS: + * queue : The queue from which the element must be retrieved. + * item : On return, the first element of the queue is stored here. + * + * DESCRIPTION: + * This function is similar to fd_fifo_get, except that it will not block if + * the queue is empty, but return EWOULDBLOCK instead. + * + * RETURN VALUE: + * 0 : A new element has been retrieved. + * EINVAL : A parameter is invalid. + * EWOULDBLOCK : The queue was empty. + */ +int fd_fifo_tryget_int ( struct fifo * queue, void ** item ); +#define fd_fifo_tryget(queue, item) \ + fd_fifo_tryget_int((queue), (void *)(item)) + +/* + * FUNCTION: fd_fifo_timedget + * + * PARAMETERS: + * queue : The queue from which the element must be retrieved. + * item : On return, the element is stored here. + * abstime : the absolute time until which we allow waiting for an item. + * + * DESCRIPTION: + * This function is similar to fd_fifo_get, except that it will block if the queue is empty + * only until the absolute time abstime (see pthread_cond_timedwait for + info). + * If the queue is still empty when the time expires, the function returns ETIMEDOUT + * + * RETURN VALUE: + * 0 : A new item has been retrieved. + * EINVAL : A parameter is invalid. + * ETIMEDOUT : The time out has passed and no item has been received. + */ +int fd_fifo_timedget_int ( struct fifo * queue, void ** item, const struct timespec *abstime ); +#define fd_fifo_timedget(queue, item, abstime) \ + fd_fifo_timedget_int((queue), (void *)(item), (abstime)) + + +/* + * FUNCTION: fd_fifo_select + * + * PARAMETERS: + * queue : The queue to test. + * abstime : the absolute time until which we can block waiting for an item. If NULL, the function returns immediatly. + * + * DESCRIPTION: + * This function is similar to select(), it waits for data to be available in the queue + * until the abstime is expired. + * Upon function entry, even if abstime is already expired the data availability is tested. + * + * RETURN VALUE: + * 0 : timeout expired without available data. + * <0 : An error occurred (e.g., -EINVAL...) + * >0 : data is available. The next call to fd_fifo_get will not block. + */ +int fd_fifo_select ( struct fifo * queue, const struct timespec *abstime ); + + + +/* Dump a fifo list and optionally its inner elements -- beware of deadlocks! */ +typedef DECLARE_FD_DUMP_PROTOTYPE((*fd_fifo_dump_item_cb), void * item); /* This function should be 1 line if possible, or use indent level. Ends with '\n' */ +DECLARE_FD_DUMP_PROTOTYPE(fd_fifo_dump, char * name, struct fifo * queue, fd_fifo_dump_item_cb dump_item); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBFDPROTO_H */ diff --git a/plat/diameter/include/freeDiameter/version.h.in b/plat/diameter/include/freeDiameter/version.h.in new file mode 100644 index 0000000..696c4e7 --- /dev/null +++ b/plat/diameter/include/freeDiameter/version.h.in @@ -0,0 +1,3 @@ +/* Following variable is expended at build time based on the result of "hg id" command */ +#cmakedefine FD_PROJECT_VERSION_HG +#define FD_PROJECT_VERSION_HG_VAL "@FD_PROJECT_VERSION_HG@" diff --git a/plat/diameter/include/gy_message.h b/plat/diameter/include/gy_message.h new file mode 100644 index 0000000..bed2bad --- /dev/null +++ b/plat/diameter/include/gy_message.h @@ -0,0 +1,159 @@ +#ifndef _GY_MSG_H +#define _GY_MSG_H + +#define MAX_GY_PORT 16384// 8192 +#define INVALID_GY_PORT 0xFFFF + +#define NUMBER_LEN 32 +#define GY_APN_LEN 64 +//#define ADDRESS_LEN 64 +#define CONTEXT_ID_LEN 128 + +typedef enum GY_MSG_TYPE +{ + GY_MSG_CCR, + GY_MSG_CCA, +}_GY_MSG_TYPE; + +typedef enum SERVICE_TYPE +{ + ST_CS_VOICE, + ST_CS_SMS, + ST_CS_VEDIO, + ST_PS_DATA, + ST_PS_VEDIO, +}_SERVICE_TYPE; + +typedef enum REQUEST_TYPE +{ + RT_INITIAL_REQUEST=1, + RT_UPDATE_REQUEST, + RT_TERMINATE_REQUEST, + RT_EVENT_REQUEST, +}_REQUEST_TYPE; + +typedef enum REQUEST_ACTION +{ + RA_DIRECT_DEBITING = 0, + RA_REFUND_ACCOUNT = 1, + RA_CHECK_BALANCE = 2, + RA_PRICE_ENQUIRY = 3, +}_REQUEST_ACTION; + +typedef enum CHECK_BALANCE_RESULT +{ + CBR_ENOUGH_CREDIT = 0, + CBR_NO_CREDIT = 1, +}_CHECK_BALANCE_RESULT; + +typedef enum REPORTING_REASON +{ + RR_THRESHOLD = 0, + RR_QHT = 1, + RR_FINAL = 2, + RR_QUOTA_EXHAUSTED = 3, + RR_VALIDITY_TIME = 4, + RR_OTHER_QUOTA_TYPE = 5, + RR_RATING_CONDITION_CHANGE = 6, + RR_FORCED_REAUTHORISATION = 7, + RR_POOL_EXHAUSTED = 8, +}_REPORTING_REASON; + +typedef struct gy_ccr +{ + + char caller[NUMBER_LEN]; + char called[NUMBER_LEN]; + char smsc[NUMBER_LEN]; + char origin_caller[NUMBER_LEN]; + char msc_addr[NUMBER_LEN]; + char vlr_number[NUMBER_LEN]; + char imsi[NUMBER_LEN]; + char apn[GY_APN_LEN]; + char cellid[16]; + int sgsn_ip; + int ggsn_ip; + char request_action; + char cellid_presented; + //char mscc_presented; + char role_of_node; + //long balance_to_check; + float req_service_unit; + int service_key; + int reporting_reason; + int sent_msg_num; + long used_unit; +}_gy_ccr; + +typedef struct gy_cca +{ + + int result; + int check_balance_result; + long grant_value; + long volume_threshold; + long time_threshold; + int is_final; +}_gy_cca; + +typedef struct gy_msg +{ + int fd_port; + int app_port; + enum GY_MSG_TYPE msg_type; + enum SERVICE_TYPE service_type; + enum REQUEST_TYPE request_type; + int request_number; + int service_identifier; + int rating_group; + char cxt_id[CONTEXT_ID_LEN]; + struct msg_body + { + _gy_ccr ccr; + _gy_cca cca; + }msg_body; + +}_gy_msg; + +typedef struct gy_port +{ + int used_flag; + int index; + long updated_ts; + int app_port; + char context_id[CONTEXT_ID_LEN]; + enum SERVICE_TYPE service_type; + int request_number; + int as_client; +}_gy_port; + +typedef struct gy_space +{ + int cur_index; + int used_ports; + _gy_port gy_port[MAX_GY_PORT]; +}_gy_space; + +typedef struct gy_msg_stat +{ + int ccr; + int ccr_init; + int ccr_update; + int ccr_terminate; + int ccr_event; + int cca; + int cca_init; + int cca_update; + int cca_terminate; + int cca_event; +}_gy_msg_stat; + +typedef struct gy_stat +{ + + _gy_msg_stat send_stat; + _gy_msg_stat recv_stat; +}_gy_stat; + + +#endif diff --git a/plat/diameter/libfdcore/apps.c b/plat/diameter/libfdcore/apps.c new file mode 100644 index 0000000..750a780 --- /dev/null +++ b/plat/diameter/libfdcore/apps.c @@ -0,0 +1,152 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2011, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Merge information into a list of apps */ +int fd_app_merge(struct fd_list * list, application_id_t aid, vendor_id_t vid, int auth, int acct) +{ + struct fd_list * li; + int skip = 0; + + /* List is ordered by appid. Avoid duplicates */ + for (li = list; li->next != list; li = li->next) { + struct fd_app * na = (struct fd_app *)(li->next); + if (na->appid < aid) + continue; + + if (na->appid > aid) + break; + + /* Otherwise, we merge with existing entry -- ignore vendor id in this case */ + skip = 1; + + if (auth) + na->flags.auth = 1; + if (acct) + na->flags.acct = 1; + break; + } + + if (!skip) { + struct fd_app * new = NULL; + + CHECK_MALLOC( new = malloc(sizeof(struct fd_app)) ); + memset(new, 0, sizeof(struct fd_app)); + fd_list_init(&new->chain, NULL); + new->flags.auth = (auth ? 1 : 0); + new->flags.acct = (acct ? 1 : 0); + new->vndid = vid; + new->appid = aid; + fd_list_insert_after(li, &new->chain); + } + + return 0; +} + +/* Check if a given application id is in a list */ +int fd_app_check(struct fd_list * list, application_id_t aid, struct fd_app **detail) +{ + struct fd_list * li; + + TRACE_ENTRY("%p %d %p", list, aid, detail); + CHECK_PARAMS(list && detail); + + *detail = NULL; + + /* Search in the list */ + for (li = list->next; li != list; li = li->next) { + struct fd_app * a = (struct fd_app *)li; + if (a->appid < aid) + continue; + + if (a->appid == aid) + *detail = a; + break; + } + + return 0; +} + +/* Check if two lists have at least one common application */ +int fd_app_check_common(struct fd_list * list1, struct fd_list * list2, int * common_found) +{ + struct fd_list * li1, *li2; + + TRACE_ENTRY("%p %p %p", list1, list2, common_found); + CHECK_PARAMS( list1 && list2 && common_found ); + + /* Both lists are ordered, so advance both pointers at the same time */ + for (li1 = list1->next, li2 = list2->next; (li1 != list1) && (li2 != list2); ) { + struct fd_app * a1 = (struct fd_app *)li1, *a2 = (struct fd_app *)li2; + if (a1->appid < a2->appid) { + li1 = li1->next; + continue; + } + if (a1->appid > a2->appid) { + li2 = li2->next; + continue; + } + /* They are equal, compare the applications */ + if ((a1->flags.auth && a2->flags.auth) || (a1->flags.acct && a2->flags.acct)) { + /* found! */ + *common_found = 1; + return 0; + } + + /* This application is not common, advance both lists */ + li1 = li1->next; + li2 = li2->next; + } + + /* We did not find a common app */ + *common_found = 0; + return 0; +} + +/* Remove the apps from a list */ +int fd_app_empty(struct fd_list * list) +{ + TRACE_ENTRY("%p", list); + CHECK_PARAMS( list ); + + while (!FD_IS_LIST_EMPTY(list)) { + struct fd_list * li = list->next; + fd_list_unlink(li); + free(li); + } + + return 0; +} diff --git a/plat/diameter/libfdcore/cnxctx.c b/plat/diameter/libfdcore/cnxctx.c new file mode 100644 index 0000000..a1b90c1 --- /dev/null +++ b/plat/diameter/libfdcore/cnxctx.c @@ -0,0 +1,2045 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" +#include "cnxctx.h" + +#include +#include /* for getifaddrs */ +#include /* writev */ + +/* The maximum size of Diameter message we accept to receive (<= 2^24) to avoid too big mallocs in case of trashed headers */ +#ifndef DIAMETER_MSG_SIZE_MAX +#define DIAMETER_MSG_SIZE_MAX 65535 /* in bytes */ +#endif /* DIAMETER_MSG_SIZE_MAX */ + + +/* Connections contexts (cnxctx) in freeDiameter are wrappers around the sockets and TLS operations . + * They are used to hide the details of the processing to the higher layers of the daemon. + * They are always oriented on connections (TCP or SCTP), connectionless modes (UDP or SCTP) are not supported. + */ + +/* Lifetime of a cnxctx object: + * 1) Creation + * a) a server socket: + * - create the object with fd_cnx_serv_tcp or fd_cnx_serv_sctp + * - start listening incoming connections: fd_cnx_serv_listen + * - accept new clients with fd_cnx_serv_accept. + * b) a client socket: + * - connect to a remote server with fd_cnx_cli_connect + * + * 2) Initialization + * - if TLS is started first, call fd_cnx_handshake + * - otherwise to receive clear messages, call fd_cnx_start_clear. fd_cnx_handshake can be called later. + * + * 3) Usage + * - fd_cnx_receive, fd_cnx_send : exchange messages on this connection (send is synchronous, receive is not, but blocking). + * - fd_cnx_recv_setaltfifo : when a message is received, the event is sent to an external fifo list. fd_cnx_receive does not work when the alt_fifo is set. + * - fd_cnx_getid : retrieve a descriptive string for the connection (for debug) + * - fd_cnx_getremoteid : identification of the remote peer (IP address or fqdn) + * - fd_cnx_getcred : get the remote peer TLS credentials, after handshake + * + * 4) End + * - fd_cnx_destroy + */ + +/*******************************************/ +/* Creation of a connection object */ +/*******************************************/ + +/* Initialize a context structure */ +static struct cnxctx * fd_cnx_init(int full) +{ + struct cnxctx * conn = NULL; + + TRACE_ENTRY("%d", full); + + CHECK_MALLOC_DO( conn = malloc(sizeof(struct cnxctx)), return NULL ); + memset(conn, 0, sizeof(struct cnxctx)); + + if (full) { + CHECK_FCT_DO( fd_fifo_new ( &conn->cc_incoming, 5 ), return NULL ); + } + + return conn; +} + +#define CC_ID_HDR "{----} " + +/* Create and bind a server socket to the given endpoint and port */ +struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep) +{ + struct cnxctx * cnx = NULL; + sSS dummy; + sSA * sa = (sSA *) &dummy; + + TRACE_ENTRY("%hu %d %p", port, family, ep); + + CHECK_PARAMS_DO( port, return NULL ); + CHECK_PARAMS_DO( ep || family, return NULL ); + CHECK_PARAMS_DO( (! family) || (family == AF_INET) || (family == AF_INET6), return NULL ); + CHECK_PARAMS_DO( (! ep) || (ep->ss.ss_family == AF_INET) || (ep->ss.ss_family == AF_INET6), return NULL ); + CHECK_PARAMS_DO( (! ep) || (!family) || (ep->ss.ss_family == family), return NULL ); + + /* The connection object */ + CHECK_MALLOC_DO( cnx = fd_cnx_init(0), return NULL ); + + /* Prepare the socket address information */ + if (ep) { + memcpy(sa, &ep->ss, sizeof(sSS)); + } else { + memset(&dummy, 0, sizeof(dummy)); + sa->sa_family = family; + } + if (sa->sa_family == AF_INET) { + ((sSA4 *)sa)->sin_port = htons(port); + cnx->cc_family = AF_INET; + } else { + ((sSA6 *)sa)->sin6_port = htons(port); + cnx->cc_family = AF_INET6; + } + + /* Create the socket */ + CHECK_FCT_DO( fd_tcp_create_bind_server( &cnx->cc_socket, sa, sSAlen(sa) ), goto error ); + + /* Generate the name for the connection object */ + { + char addrbuf[INET6_ADDRSTRLEN]; + int rc; + rc = getnameinfo(sa, sSAlen(sa), addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); + if (rc) + snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc)); + snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "TCP srv [%s]:%hu (%d)", addrbuf, port, cnx->cc_socket); + } + + cnx->cc_proto = IPPROTO_TCP; + + return cnx; + +error: + fd_cnx_destroy(cnx); + return NULL; +} + +/* Same function for SCTP, with a list of local endpoints to bind to */ +struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list) +{ +#ifdef DISABLE_SCTP + TRACE_DEBUG(INFO, "This function should never been called when SCTP is disabled..."); + ASSERT(0); + CHECK_FCT_DO( ENOTSUP, ); + return NULL; +#else /* DISABLE_SCTP */ + struct cnxctx * cnx = NULL; + + TRACE_ENTRY("%hu %p", port, ep_list); + + CHECK_PARAMS_DO( port, return NULL ); + + /* The connection object */ + CHECK_MALLOC_DO( cnx = fd_cnx_init(0), return NULL ); + + if (fd_g_config->cnf_flags.no_ip6) { + cnx->cc_family = AF_INET; + } else { + cnx->cc_family = AF_INET6; /* can create socket for both IP and IPv6 */ + } + + /* Create the socket */ + CHECK_FCT_DO( fd_sctp_create_bind_server( &cnx->cc_socket, cnx->cc_family, ep_list, port ), goto error ); + + /* Generate the name for the connection object */ + snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "SCTP srv :%hu (%d)", port, cnx->cc_socket); + + cnx->cc_proto = IPPROTO_SCTP; + + return cnx; + +error: + fd_cnx_destroy(cnx); + return NULL; +#endif /* DISABLE_SCTP */ +} + +/* Allow clients to connect on the server socket */ +int fd_cnx_serv_listen(struct cnxctx * conn) +{ + CHECK_PARAMS( conn ); + + switch (conn->cc_proto) { + case IPPROTO_TCP: + CHECK_FCT(fd_tcp_listen(conn->cc_socket)); + break; + +#ifndef DISABLE_SCTP + case IPPROTO_SCTP: + CHECK_FCT(fd_sctp_listen(conn->cc_socket)); + break; +#endif /* DISABLE_SCTP */ + + default: + CHECK_PARAMS(0); + } + + return 0; +} + +/* Accept a client (blocking until a new client connects) -- cancelable */ +struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv) +{ + struct cnxctx * cli = NULL; + sSS ss; + socklen_t ss_len = sizeof(ss); + int cli_sock = 0; + + TRACE_ENTRY("%p", serv); + CHECK_PARAMS_DO(serv, return NULL); + + /* Accept the new connection -- this is blocking until new client enters or until cancellation */ + CHECK_SYS_DO( cli_sock = accept(serv->cc_socket, (sSA *)&ss, &ss_len), return NULL ); + + CHECK_MALLOC_DO( cli = fd_cnx_init(1), { shutdown(cli_sock, SHUT_RDWR); close(cli_sock); return NULL; } ); + cli->cc_socket = cli_sock; + cli->cc_family = serv->cc_family; + cli->cc_proto = serv->cc_proto; + + /* Set the timeout */ + fd_cnx_s_setto(cli->cc_socket); + + /* Generate the name for the connection object */ + { + char addrbuf[INET6_ADDRSTRLEN]; + char portbuf[10]; + int rc; + + rc = getnameinfo((sSA *)&ss, ss_len, addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV); + if (rc) { + snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc)); + portbuf[0] = '\0'; + } + + /* Numeric values for debug... */ + snprintf(cli->cc_id, sizeof(cli->cc_id), CC_ID_HDR "%s from [%s]:%s (%d<-%d)", + IPPROTO_NAME(cli->cc_proto), addrbuf, portbuf, serv->cc_socket, cli->cc_socket); + + + /* ...Name for log messages */ + rc = getnameinfo((sSA *)&ss, ss_len, cli->cc_remid, sizeof(cli->cc_remid), NULL, 0, 0); + if (rc) + snprintf(cli->cc_remid, sizeof(cli->cc_remid), "[err:%s]", gai_strerror(rc)); + } + + LOG_D("Incoming connection: '%s' <- '%s' {%s}", fd_cnx_getid(serv), cli->cc_remid, cli->cc_id); + +#ifndef DISABLE_SCTP + /* SCTP-specific handlings */ + if (cli->cc_proto == IPPROTO_SCTP) { + /* Retrieve the number of streams */ + CHECK_FCT_DO( fd_sctp_get_str_info( cli->cc_socket, &cli->cc_sctp_para.str_in, &cli->cc_sctp_para.str_out, NULL ), {fd_cnx_destroy(cli); return NULL;} ); + if (cli->cc_sctp_para.str_out < cli->cc_sctp_para.str_in) + cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_out; + else + cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_in; + + LOG_A( "%s : client '%s' (SCTP:%d, %d/%d streams)", fd_cnx_getid(serv), fd_cnx_getid(cli), cli->cc_socket, cli->cc_sctp_para.str_in, cli->cc_sctp_para.str_out); + } +#endif /* DISABLE_SCTP */ + + return cli; +} + +/* Client side: connect to a remote server -- cancelable */ +struct cnxctx * fd_cnx_cli_connect_tcp(sSA * sa /* contains the port already */, socklen_t addrlen) +{ + int sock = 0; + struct cnxctx * cnx = NULL; + char sa_buf[sSA_DUMP_STRLEN]; + + TRACE_ENTRY("%p %d", sa, addrlen); + CHECK_PARAMS_DO( sa && addrlen, return NULL ); + + fd_sa_sdump_numeric(sa_buf, sa); + + LOG_D("Connecting to TCP %s...", sa_buf); + + /* Create the socket and connect, which can take some time and/or fail */ + { + int ret = fd_tcp_client( &sock, sa, addrlen ); + if (ret != 0) { + LOG_D("TCP connection to %s failed: %s", sa_buf, strerror(ret)); + return NULL; + } + } + + /* Once the socket is created successfuly, prepare the remaining of the cnx */ + CHECK_MALLOC_DO( cnx = fd_cnx_init(1), { shutdown(sock, SHUT_RDWR); close(sock); return NULL; } ); + + cnx->cc_socket = sock; + cnx->cc_family = sa->sa_family; + cnx->cc_proto = IPPROTO_TCP; + + /* Set the timeout */ + fd_cnx_s_setto(cnx->cc_socket); + + /* Generate the names for the object */ + { + int rc; + + snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "TCP,#%d->%s", cnx->cc_socket, sa_buf); + + /* ...Name for log messages */ + rc = getnameinfo(sa, addrlen, cnx->cc_remid, sizeof(cnx->cc_remid), NULL, 0, 0); + if (rc) + snprintf(cnx->cc_remid, sizeof(cnx->cc_remid), "[err:%s]", gai_strerror(rc)); + } + + LOG_A("TCP connection to %s succeed (socket:%d).", sa_buf, sock); + + return cnx; +} + +/* Same for SCTP, accepts a list of remote addresses to connect to (see sctp_connectx for how they are used) */ +struct cnxctx * fd_cnx_cli_connect_sctp(int no_ip6, uint16_t port, struct fd_list * list) +{ +#ifdef DISABLE_SCTP + TRACE_DEBUG(INFO, "This function should never be called when SCTP is disabled..."); + ASSERT(0); + CHECK_FCT_DO( ENOTSUP, ); + return NULL; +#else /* DISABLE_SCTP */ + int sock = 0; + struct cnxctx * cnx = NULL; + char sa_buf[sSA_DUMP_STRLEN]; + sSS primary; + + TRACE_ENTRY("%p", list); + CHECK_PARAMS_DO( list && !FD_IS_LIST_EMPTY(list), return NULL ); + + fd_sa_sdump_numeric(sa_buf, &((struct fd_endpoint *)(list->next))->sa); + + LOG_D("Connecting to SCTP %s:%hu...", sa_buf, port); + + { + int ret = fd_sctp_client( &sock, no_ip6, port, list ); + if (ret != 0) { + LOG_D("SCTP connection to [%s,...] failed: %s", sa_buf, strerror(ret)); + return NULL; + } + } + + /* Once the socket is created successfuly, prepare the remaining of the cnx */ + CHECK_MALLOC_DO( cnx = fd_cnx_init(1), { shutdown(sock, SHUT_RDWR); close(sock); return NULL; } ); + + cnx->cc_socket = sock; + cnx->cc_family = no_ip6 ? AF_INET : AF_INET6; + cnx->cc_proto = IPPROTO_SCTP; + + /* Set the timeout */ + fd_cnx_s_setto(cnx->cc_socket); + + /* Retrieve the number of streams and primary address */ + CHECK_FCT_DO( fd_sctp_get_str_info( sock, &cnx->cc_sctp_para.str_in, &cnx->cc_sctp_para.str_out, &primary ), goto error ); + if (cnx->cc_sctp_para.str_out < cnx->cc_sctp_para.str_in) + cnx->cc_sctp_para.pairs = cnx->cc_sctp_para.str_out; + else + cnx->cc_sctp_para.pairs = cnx->cc_sctp_para.str_in; + + fd_sa_sdump_numeric(sa_buf, (sSA *)&primary); + + /* Generate the names for the object */ + { + int rc; + + snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "SCTP,#%d->%s", cnx->cc_socket, sa_buf); + + /* ...Name for log messages */ + rc = getnameinfo((sSA *)&primary, sSAlen(&primary), cnx->cc_remid, sizeof(cnx->cc_remid), NULL, 0, 0); + if (rc) + snprintf(cnx->cc_remid, sizeof(cnx->cc_remid), "[err:%s]", gai_strerror(rc)); + } + + LOG_A("SCTP connection to %s succeed (socket:%d, %d/%d streams).", sa_buf, sock, cnx->cc_sctp_para.str_in, cnx->cc_sctp_para.str_out); + + return cnx; + +error: + fd_cnx_destroy(cnx); + return NULL; +#endif /* DISABLE_SCTP */ +} + +/* Return a string describing the connection, for debug */ +char * fd_cnx_getid(struct cnxctx * conn) +{ + CHECK_PARAMS_DO( conn, return "" ); + return conn->cc_id; +} + +/* Return the protocol of a connection */ +int fd_cnx_getproto(struct cnxctx * conn) +{ + CHECK_PARAMS_DO( conn, return 0 ); + return conn->cc_proto; +} + +/* Set the hostname to check during handshake */ +void fd_cnx_sethostname(struct cnxctx * conn, DiamId_t hn) +{ + CHECK_PARAMS_DO( conn, return ); + conn->cc_tls_para.cn = hn; +} + +/* We share a lock with many threads but we hold it only very short time so it is OK */ +static pthread_mutex_t state_lock = PTHREAD_MUTEX_INITIALIZER; +uint32_t fd_cnx_getstate(struct cnxctx * conn) +{ + uint32_t st; + CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); + st = conn->cc_state; + CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); + return st; +} +int fd_cnx_teststate(struct cnxctx * conn, uint32_t flag) +{ + uint32_t st; + CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); + st = conn->cc_state; + CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); + return st & flag; +} +void fd_cnx_update_id(struct cnxctx * conn) { + if (conn->cc_state & CC_STATUS_CLOSING) + conn->cc_id[1] = 'C'; + else + conn->cc_id[1] = '-'; + + if (conn->cc_state & CC_STATUS_ERROR) + conn->cc_id[2] = 'E'; + else + conn->cc_id[2] = '-'; + + if (conn->cc_state & CC_STATUS_SIGNALED) + conn->cc_id[3] = 'S'; + else + conn->cc_id[3] = '-'; + + if (conn->cc_state & CC_STATUS_TLS) + conn->cc_id[4] = 'T'; + else + conn->cc_id[4] = '-'; +} +void fd_cnx_addstate(struct cnxctx * conn, uint32_t orstate) +{ + CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); + conn->cc_state |= orstate; + fd_cnx_update_id(conn); + CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); +} +void fd_cnx_setstate(struct cnxctx * conn, uint32_t abstate) +{ + CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); + conn->cc_state = abstate; + fd_cnx_update_id(conn); + CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); +} + + +/* Return the TLS state of a connection */ +int fd_cnx_getTLS(struct cnxctx * conn) +{ + CHECK_PARAMS_DO( conn, return 0 ); + return fd_cnx_teststate(conn, CC_STATUS_TLS); +} + +/* Mark the connection to tell if OOO delivery is permitted (only for SCTP) */ +int fd_cnx_unordered_delivery(struct cnxctx * conn, int is_allowed) +{ + CHECK_PARAMS( conn ); + conn->cc_sctp_para.unordered = is_allowed; + return 0; +} + +/* Return true if the connection supports unordered delivery of messages */ +int fd_cnx_is_unordered_delivery_supported(struct cnxctx * conn) +{ + CHECK_PARAMS_DO( conn, return 0 ); + #ifndef DISABLE_SCTP + if (conn->cc_proto == IPPROTO_SCTP) + return (conn->cc_sctp_para.str_out > 1); + #endif /* DISABLE_SCTP */ + return 0; +} + + +/* Get the list of endpoints (IP addresses) of the local and remote peers on this connection */ +int fd_cnx_getremoteeps(struct cnxctx * conn, struct fd_list * eps) +{ + TRACE_ENTRY("%p %p", conn, eps); + CHECK_PARAMS(conn && eps); + + /* Check we have a full connection object, not a listening socket (with no remote) */ + CHECK_PARAMS( conn->cc_incoming ); + + /* Retrieve the peer endpoint(s) of the connection */ + switch (conn->cc_proto) { + case IPPROTO_TCP: { + sSS ss; + socklen_t sl; + CHECK_FCT(fd_tcp_get_remote_ep(conn->cc_socket, &ss, &sl)); + CHECK_FCT(fd_ep_add_merge( eps, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY )); + } + break; + + #ifndef DISABLE_SCTP + case IPPROTO_SCTP: { + CHECK_FCT(fd_sctp_get_remote_ep(conn->cc_socket, eps)); + } + break; + #endif /* DISABLE_SCTP */ + + default: + CHECK_PARAMS(0); + } + + return 0; +} + +/* Get a string describing the remote peer address (ip address or fqdn) */ +char * fd_cnx_getremoteid(struct cnxctx * conn) +{ + CHECK_PARAMS_DO( conn, return "" ); + return conn->cc_remid; +} + +static int fd_cnx_may_dtls(struct cnxctx * conn); + +/* Get a short string representing the connection */ +int fd_cnx_proto_info(struct cnxctx * conn, char * buf, size_t len) +{ + CHECK_PARAMS( conn ); + + if (fd_cnx_teststate(conn, CC_STATUS_TLS)) { + snprintf(buf, len, "%s,%s,soc#%d", IPPROTO_NAME(conn->cc_proto), fd_cnx_may_dtls(conn) ? "DTLS" : "TLS", conn->cc_socket); + } else { + snprintf(buf, len, "%s,soc#%d", IPPROTO_NAME(conn->cc_proto), conn->cc_socket); + } + + return 0; +} + +/* Retrieve a list of all IP addresses of the local system from the kernel, using getifaddrs */ +int fd_cnx_get_local_eps(struct fd_list * list) +{ + struct ifaddrs *iflist, *cur; + + CHECK_SYS(getifaddrs(&iflist)); + + for (cur = iflist; cur != NULL; cur = cur->ifa_next) { + if (cur->ifa_flags & IFF_LOOPBACK) + continue; + + if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */ + continue; + + if (fd_g_config->cnf_flags.no_ip4 && (cur->ifa_addr->sa_family == AF_INET)) + continue; + + if (fd_g_config->cnf_flags.no_ip6 && (cur->ifa_addr->sa_family == AF_INET6)) + continue; + + CHECK_FCT(fd_ep_add_merge( list, cur->ifa_addr, sSAlen(cur->ifa_addr), EP_FL_LL )); + } + + freeifaddrs(iflist); + + return 0; +} + + +/**************************************/ +/* Use of a connection object */ +/**************************************/ + +/* An error occurred on the socket */ +void fd_cnx_markerror(struct cnxctx * conn) +{ + TRACE_ENTRY("%p", conn); + CHECK_PARAMS_DO( conn, goto fatal ); + + TRACE_DEBUG(FULL, "Error flag set for socket %d (%s, %s)", conn->cc_socket, conn->cc_id, conn->cc_remid); + + /* Mark the error */ + fd_cnx_addstate(conn, CC_STATUS_ERROR); + + /* Report the error if not reported yet, and not closing */ + if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING | CC_STATUS_SIGNALED )) { + TRACE_DEBUG(FULL, "Sending FDEVP_CNX_ERROR event"); + CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), FDEVP_CNX_ERROR, 0, NULL), goto fatal); + fd_cnx_addstate(conn, CC_STATUS_SIGNALED); + } + + return; +fatal: + /* An unrecoverable error occurred, stop the daemon */ + ASSERT(0); + CHECK_FCT_DO(fd_core_shutdown(), ); +} + +/* Set the timeout option on the socket */ +void fd_cnx_s_setto(int sock) +{ + struct timeval tv; + + /* Set a timeout on the socket so that in any case we are not stuck waiting for something */ + memset(&tv, 0, sizeof(tv)); + tv.tv_usec = 100000L; /* 100ms, to react quickly to head-of-the-line blocking. */ + CHECK_SYS_DO( setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)), ); + CHECK_SYS_DO( setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)), ); +} + + +#ifdef GNUTLS_VERSION_300 +/* The pull_timeout function for gnutls */ +static int fd_cnx_s_select (struct cnxctx * conn, unsigned int ms) +{ + fd_set rfds; + struct timeval tv; + + FD_ZERO (&rfds); + FD_SET (conn->cc_socket, &rfds); + + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms * 1000) % 1000000; + + return select (conn->cc_socket + 1, &rfds, NULL, NULL, &tv); +} +#endif /* GNUTLS_VERSION_300 */ + +/* A recv-like function, taking a cnxctx object instead of socket as entry. We use it to quickly react to timeouts without traversing GNUTLS wrapper each time */ +ssize_t fd_cnx_s_recv(struct cnxctx * conn, void *buffer, size_t length) +{ + ssize_t ret = 0; + int timedout = 0; +again: + ret = recv(conn->cc_socket, buffer, length, 0); + /* Handle special case of timeout / interrupts */ + if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { + pthread_testcancel(); + if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING )) + goto again; /* don't care, just ignore */ + if (!timedout) { + timedout ++; /* allow for one timeout while closing */ + goto again; + } + } + + /* Mark the error */ + if (ret <= 0) { + CHECK_SYS_DO(ret, /* continue, this is only used to log the error here */); + fd_cnx_markerror(conn); + } + + return ret; +} + +/* Send */ +static ssize_t fd_cnx_s_sendv(struct cnxctx * conn, const struct iovec * iov, int iovcnt) +{ + ssize_t ret = 0; + struct timespec ts, now; + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return -1 ); +again: + ret = writev(conn->cc_socket, iov, iovcnt); + /* Handle special case of timeout */ + if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { + ret = -errno; + pthread_testcancel(); + + /* Check how much time we were blocked for this sending. */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), return -1 ); + if ( ((now.tv_sec - ts.tv_sec) * 1000 + ((now.tv_nsec - ts.tv_nsec) / 1000000L)) > MAX_HOTL_BLOCKING_TIME) { + LOG_D("Unable to send any data for %dms, closing the connection", MAX_HOTL_BLOCKING_TIME); + } else if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING )) { + goto again; /* don't care, just ignore */ + } + + /* propagate the error */ + errno = -ret; + ret = -1; + CHECK_SYS_DO(ret, /* continue */); + } + + /* Mark the error */ + if (ret <= 0) + fd_cnx_markerror(conn); + + return ret; +} + +/* Send, for older GNUTLS */ +#ifndef GNUTLS_VERSION_212 +static ssize_t fd_cnx_s_send(struct cnxctx * conn, const void *buffer, size_t length) +{ + struct iovec iov; + iov.iov_base = (void *)buffer; + iov.iov_len = length; + return fd_cnx_s_sendv(conn, &iov, 1); +} +#endif /* GNUTLS_VERSION_212 */ + +#define ALIGNOF(t) ((char *)(&((struct { char c; t _h; } *)0)->_h) - (char *)0) /* Could use __alignof__(t) on some systems but this is more portable probably */ +#define PMDL_PADDED(len) ( ((len) + ALIGNOF(struct fd_msg_pmdl) - 1) & ~(ALIGNOF(struct fd_msg_pmdl) - 1) ) + +size_t fd_msg_pmdl_sizewithoverhead(size_t datalen) +{ + return PMDL_PADDED(datalen) + sizeof(struct fd_msg_pmdl); +} + +struct fd_msg_pmdl * fd_msg_pmdl_get_inbuf(uint8_t * buf, size_t datalen) +{ + return (struct fd_msg_pmdl *)(buf + PMDL_PADDED(datalen)); +} + +static int fd_cnx_init_msg_buffer(uint8_t * buffer, size_t expected_len, struct fd_msg_pmdl ** pmdl) +{ + *pmdl = fd_msg_pmdl_get_inbuf(buffer, expected_len); + fd_list_init(&(*pmdl)->sentinel, NULL); + CHECK_POSIX(pthread_mutex_init(&(*pmdl)->lock, NULL) ); + return 0; +} + +static uint8_t * fd_cnx_alloc_msg_buffer(size_t expected_len, struct fd_msg_pmdl ** pmdl) +{ + uint8_t * ret = NULL; + + CHECK_MALLOC_DO( ret = malloc( fd_msg_pmdl_sizewithoverhead(expected_len) ), return NULL ); + CHECK_FCT_DO( fd_cnx_init_msg_buffer(ret, expected_len, pmdl), {free(ret); return NULL;} ); + return ret; +} + +#ifndef DISABLE_SCTP /* WE use this function only in SCTP code */ +static uint8_t * fd_cnx_realloc_msg_buffer(uint8_t * buffer, size_t expected_len, struct fd_msg_pmdl ** pmdl) +{ + uint8_t * ret = NULL; + + CHECK_MALLOC_DO( ret = realloc( buffer, fd_msg_pmdl_sizewithoverhead(expected_len) ), return NULL ); + CHECK_FCT_DO( fd_cnx_init_msg_buffer(ret, expected_len, pmdl), {free(ret); return NULL;} ); + return ret; +} +#endif /* DISABLE_SCTP */ + +static void free_rcvdata(void * arg) +{ + struct fd_cnx_rcvdata * data = arg; + struct fd_msg_pmdl * pmdl = fd_msg_pmdl_get_inbuf(data->buffer, data->length); + (void) pthread_mutex_destroy(&pmdl->lock); + free(data->buffer); +} + +/* Receiver thread (TCP & noTLS) : incoming message is directly saved into the target queue */ +static void * rcvthr_notls_tcp(void * arg) +{ + struct cnxctx * conn = arg; + + TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Receiver (%d) TCP/noTLS)", conn->cc_socket); + fd_log_threadname ( buf ); + } + + ASSERT( conn->cc_proto == IPPROTO_TCP ); + ASSERT( ! fd_cnx_teststate(conn, CC_STATUS_TLS ) ); + ASSERT( fd_cnx_target_queue(conn) ); + + /* Receive from a TCP connection: we have to rebuild the message boundaries */ + do { + uint8_t header[4]; + struct fd_cnx_rcvdata rcv_data; + struct fd_msg_pmdl *pmdl=NULL; + ssize_t ret = 0; + size_t received = 0; + + do { + ret = fd_cnx_s_recv(conn, &header[received], sizeof(header) - received); + if (ret <= 0) { + goto out; /* Stop the thread, the event was already sent */ + } + + received += ret; + + if (header[0] != DIAMETER_VERSION) + break; /* No need to wait for 4 bytes in this case */ + } while (received < sizeof(header)); + + rcv_data.length = ((size_t)header[1] << 16) + ((size_t)header[2] << 8) + (size_t)header[3]; + + /* Check the received word is a valid begining of a Diameter message */ + if ((header[0] != DIAMETER_VERSION) /* defined in */ + || (rcv_data.length > DIAMETER_MSG_SIZE_MAX)) { /* to avoid too big mallocs */ + /* The message is suspect */ + LOG_E( "Received suspect header [ver: %d, size: %zd] from '%s', assuming disconnection", (int)header[0], rcv_data.length, conn->cc_remid); + fd_cnx_markerror(conn); + goto out; /* Stop the thread, the recipient of the event will cleanup */ + } + + /* Ok, now we can really receive the data */ + CHECK_MALLOC_DO( rcv_data.buffer = fd_cnx_alloc_msg_buffer( rcv_data.length, &pmdl ), goto fatal ); + memcpy(rcv_data.buffer, header, sizeof(header)); + + while (received < rcv_data.length) { + pthread_cleanup_push(free_rcvdata, &rcv_data); /* In case we are canceled, clean the partialy built buffer */ + ret = fd_cnx_s_recv(conn, rcv_data.buffer + received, rcv_data.length - received); + pthread_cleanup_pop(0); + + if (ret <= 0) { + free_rcvdata(&rcv_data); + goto out; + } + received += ret; + } + + fd_hook_call(HOOK_DATA_RECEIVED, NULL, NULL, &rcv_data, pmdl); + + /* We have received a complete message, pass it to the daemon */ + CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), FDEVP_CNX_MSG_RECV, rcv_data.length, rcv_data.buffer), + { + free_rcvdata(&rcv_data); + goto fatal; + } ); + + } while (conn->cc_loop); + +out: + TRACE_DEBUG(FULL, "Thread terminated"); + return NULL; + +fatal: + /* An unrecoverable error occurred, stop the daemon */ + CHECK_FCT_DO(fd_core_shutdown(), ); + goto out; +} + +#ifndef DISABLE_SCTP +/* Receiver thread (SCTP & noTLS) : incoming message is directly saved into cc_incoming, no need to care for the stream ID */ +static void * rcvthr_notls_sctp(void * arg) +{ + struct cnxctx * conn = arg; + struct fd_cnx_rcvdata rcv_data; + int event; + + TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto fatal); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Receiver (%d) SCTP/noTLS)", conn->cc_socket); + fd_log_threadname ( buf ); + } + + ASSERT( conn->cc_proto == IPPROTO_SCTP ); + ASSERT( ! fd_cnx_teststate(conn, CC_STATUS_TLS ) ); + ASSERT( fd_cnx_target_queue(conn) ); + + do { + struct fd_msg_pmdl *pmdl=NULL; + CHECK_FCT_DO( fd_sctp_recvmeta(conn, NULL, &rcv_data.buffer, &rcv_data.length, &event), goto fatal ); + if (event == FDEVP_CNX_ERROR) { + fd_cnx_markerror(conn); + goto out; + } + + if (event == FDEVP_CNX_SHUTDOWN) { + /* Just ignore the notification for now, we will get another error later anyway */ + continue; + } + + if (event == FDEVP_CNX_MSG_RECV) { + CHECK_MALLOC_DO( rcv_data.buffer = fd_cnx_realloc_msg_buffer(rcv_data.buffer, rcv_data.length, &pmdl), goto fatal ); + fd_hook_call(HOOK_DATA_RECEIVED, NULL, NULL, &rcv_data, pmdl); + } + CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), event, rcv_data.length, rcv_data.buffer), goto fatal ); + + } while (conn->cc_loop || (event != FDEVP_CNX_MSG_RECV)); + +out: + TRACE_DEBUG(FULL, "Thread terminated"); + return NULL; + +fatal: + /* An unrecoverable error occurred, stop the daemon */ + CHECK_FCT_DO(fd_core_shutdown(), ); + goto out; +} +#endif /* DISABLE_SCTP */ + +/* Start receving messages in clear (no TLS) on the connection */ +int fd_cnx_start_clear(struct cnxctx * conn, int loop) +{ + TRACE_ENTRY("%p %i", conn, loop); + + CHECK_PARAMS( conn && fd_cnx_target_queue(conn) && (!fd_cnx_teststate(conn, CC_STATUS_TLS)) && (!conn->cc_loop)); + + /* Release resources in case of a previous call was already made */ + CHECK_FCT_DO( fd_thr_term(&conn->cc_rcvthr), /* continue */); + + /* Save the loop request */ + conn->cc_loop = loop; + + switch (conn->cc_proto) { + case IPPROTO_TCP: + /* Start the tcp_notls thread */ + CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_notls_tcp, conn ) ); + break; +#ifndef DISABLE_SCTP + case IPPROTO_SCTP: + /* Start the tcp_notls thread */ + CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_notls_sctp, conn ) ); + break; +#endif /* DISABLE_SCTP */ + default: + TRACE_DEBUG(INFO, "Unknown protocol: %d", conn->cc_proto); + ASSERT(0); + return ENOTSUP; + } + + return 0; +} + + + + +/* Returns 0 on error, received data size otherwise (always >= 0). This is not used for DTLS-protected associations. */ +static ssize_t fd_tls_recv_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz) +{ + ssize_t ret; +again: + CHECK_GNUTLS_DO( ret = gnutls_record_recv(session, data, sz), + { + switch (ret) { + case GNUTLS_E_REHANDSHAKE: + if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING)) { + CHECK_GNUTLS_DO( ret = gnutls_handshake(session), + { + if (TRACE_BOOL(INFO)) { + fd_log_debug("TLS re-handshake failed on socket %d (%s) : %s", conn->cc_socket, conn->cc_id, gnutls_strerror(ret)); + } + goto end; + } ); + } + + case GNUTLS_E_AGAIN: + case GNUTLS_E_INTERRUPTED: + if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING)) + goto again; + TRACE_DEBUG(FULL, "Connection is closing, so abord gnutls_record_recv now."); + break; + + case GNUTLS_E_UNEXPECTED_PACKET_LENGTH: + /* The connection is closed */ + TRACE_DEBUG(FULL, "Got 0 size while reading the socket, probably connection closed..."); + break; + + default: + if (gnutls_error_is_fatal (ret) == 0) { + LOG_N("Ignoring non-fatal GNU TLS error: %s", gnutls_strerror (ret)); + goto again; + } + LOG_E("Fatal GNUTLS error: %s", gnutls_strerror (ret)); + } + } ); + + if (ret == 0) + CHECK_GNUTLS_DO( gnutls_bye(session, GNUTLS_SHUT_RDWR), ); + +end: + if (ret <= 0) + fd_cnx_markerror(conn); + return ret; +} + +/* Wrapper around gnutls_record_send to handle some error codes. This is also used for DTLS-protected associations */ +static ssize_t fd_tls_send_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz) +{ + ssize_t ret; + struct timespec ts, now; + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return -1 ); +again: + CHECK_GNUTLS_DO( ret = gnutls_record_send(session, data, sz), + { + pthread_testcancel(); + switch (ret) { + case GNUTLS_E_REHANDSHAKE: + if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING)) { + CHECK_GNUTLS_DO( ret = gnutls_handshake(session), + { + if (TRACE_BOOL(INFO)) { + fd_log_debug("TLS re-handshake failed on socket %d (%s) : %s", conn->cc_socket, conn->cc_id, gnutls_strerror(ret)); + } + goto end; + } ); + } + + case GNUTLS_E_AGAIN: + case GNUTLS_E_INTERRUPTED: + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), return -1 ); + if ( ((now.tv_sec - ts.tv_sec) * 1000 + ((now.tv_nsec - ts.tv_nsec) / 1000000L)) > MAX_HOTL_BLOCKING_TIME) { + LOG_D("Unable to send any data for %dms, closing the connection", MAX_HOTL_BLOCKING_TIME); + } else if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING )) { + goto again; + } + break; + + default: + if (gnutls_error_is_fatal (ret) == 0) { + LOG_N("Ignoring non-fatal GNU TLS error: %s", gnutls_strerror (ret)); + goto again; + } + LOG_E("Fatal GNUTLS error: %s", gnutls_strerror (ret)); + } + } ); +end: + if (ret <= 0) + fd_cnx_markerror(conn); + + return ret; +} + + +/* The function that receives TLS data and re-builds a Diameter message -- it exits only on error or cancelation */ +/* For the case of DTLS, since we are not using SCTP_UNORDERED, the messages over a single stream are ordered. + Furthermore, as long as messages are shorter than the MTU [2^14 = 16384 bytes], they are delivered in a single + record, as far as I understand. + For larger messages, however, it is possible that pieces of messages coming from different streams can get interleaved. + As a result, we do not use the following function for DTLS reception, because we use the sequence number to rebuild the + messages. */ +int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session) +{ + /* No guarantee that GnuTLS preserves the message boundaries, so we re-build it as in TCP. */ + do { + uint8_t header[4]; + struct fd_cnx_rcvdata rcv_data; + struct fd_msg_pmdl *pmdl=NULL; + ssize_t ret = 0; + size_t received = 0; + + do { + ret = fd_tls_recv_handle_error(conn, session, &header[received], sizeof(header) - received); + if (ret <= 0) { + /* The connection is closed */ + goto out; + } + received += ret; + } while (received < sizeof(header)); + + rcv_data.length = ((size_t)header[1] << 16) + ((size_t)header[2] << 8) + (size_t)header[3]; + + /* Check the received word is a valid beginning of a Diameter message */ + if ((header[0] != DIAMETER_VERSION) /* defined in */ + || (rcv_data.length > DIAMETER_MSG_SIZE_MAX)) { /* to avoid too big mallocs */ + /* The message is suspect */ + LOG_E( "Received suspect header [ver: %d, size: %zd] from '%s', assume disconnection", (int)header[0], rcv_data.length, conn->cc_remid); + fd_cnx_markerror(conn); + goto out; + } + + /* Ok, now we can really receive the data */ + CHECK_MALLOC( rcv_data.buffer = fd_cnx_alloc_msg_buffer( rcv_data.length, &pmdl ) ); + memcpy(rcv_data.buffer, header, sizeof(header)); + + while (received < rcv_data.length) { + pthread_cleanup_push(free_rcvdata, &rcv_data); /* In case we are canceled, clean the partialy built buffer */ + ret = fd_tls_recv_handle_error(conn, session, rcv_data.buffer + received, rcv_data.length - received); + pthread_cleanup_pop(0); + + if (ret <= 0) { + free_rcvdata(&rcv_data); + goto out; + } + received += ret; + } + + fd_hook_call(HOOK_DATA_RECEIVED, NULL, NULL, &rcv_data, pmdl); + + /* We have received a complete message, pass it to the daemon */ + CHECK_FCT_DO( ret = fd_event_send( fd_cnx_target_queue(conn), FDEVP_CNX_MSG_RECV, rcv_data.length, rcv_data.buffer), + { + free_rcvdata(&rcv_data); + CHECK_FCT_DO(fd_core_shutdown(), ); + return ret; + } ); + + } while (1); + +out: + return ENOTCONN; +} + +/* Receiver thread (TLS & 1 stream SCTP or TCP) */ +static void * rcvthr_tls_single(void * arg) +{ + struct cnxctx * conn = arg; + + TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), return NULL ); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Receiver (%d) TLS/single stream", conn->cc_socket); + fd_log_threadname ( buf ); + } + + ASSERT( fd_cnx_teststate(conn, CC_STATUS_TLS) ); + ASSERT( fd_cnx_target_queue(conn) ); + + /* The next function only returns when there is an error on the socket */ + CHECK_FCT_DO(fd_tls_rcvthr_core(conn, conn->cc_tls_para.session), /* continue */); + + TRACE_DEBUG(FULL, "Thread terminated"); + return NULL; +} + +/* Prepare a gnutls session object for handshake */ +int fd_tls_prepare(gnutls_session_t * session, int mode, int dtls, char * priority, void * alt_creds) +{ + if (dtls) { + LOG_E("DTLS sessions not yet supported"); + return ENOTSUP; + } + + /* Create the session context */ + CHECK_GNUTLS_DO( gnutls_init (session, mode), return ENOMEM ); + + /* Set the algorithm suite */ + if (priority) { + const char * errorpos; + CHECK_GNUTLS_DO( gnutls_priority_set_direct( *session, priority, &errorpos ), + { TRACE_DEBUG(INFO, "Error in priority string '%s' at position: '%s'", priority, errorpos); return EINVAL; } ); + } else { + CHECK_GNUTLS_DO( gnutls_priority_set( *session, fd_g_config->cnf_sec_data.prio_cache ), return EINVAL ); + } + + /* Set the credentials of this side of the connection */ + CHECK_GNUTLS_DO( gnutls_credentials_set (*session, GNUTLS_CRD_CERTIFICATE, alt_creds ?: fd_g_config->cnf_sec_data.credentials), return EINVAL ); + + /* Request the remote credentials as well */ + if (mode == GNUTLS_SERVER) { + gnutls_certificate_server_set_request (*session, GNUTLS_CERT_REQUIRE); + } + + return 0; +} + +#ifndef GNUTLS_VERSION_300 + +/* Verify remote credentials after successful handshake (return 0 if OK, EINVAL otherwise) */ +int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, int verbose) +{ + int i, ret = 0; + unsigned int gtret; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size; + gnutls_x509_crt_t cert; + time_t now; + + TRACE_ENTRY("%p %d", conn, verbose); + CHECK_PARAMS(conn); + + /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */ + #ifdef DEBUG + if (verbose) { + const char *tmp; + gnutls_kx_algorithm_t kx; + gnutls_credentials_type_t cred; + + LOG_D("TLS Session information for connection '%s':", conn->cc_id); + + /* print the key exchange's algorithm name */ + GNUTLS_TRACE( kx = gnutls_kx_get (session) ); + GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) ); + LOG_D("\t - Key Exchange: %s", tmp); + + /* Check the authentication type used and switch + * to the appropriate. */ + GNUTLS_TRACE( cred = gnutls_auth_get_type (session) ); + switch (cred) + { + case GNUTLS_CRD_IA: + LOG_D("\t - TLS/IA session"); + break; + + case GNUTLS_CRD_PSK: + /* This returns NULL in server side. */ + if (gnutls_psk_client_get_hint (session) != NULL) + LOG_D("\t - PSK authentication. PSK hint '%s'", + gnutls_psk_client_get_hint (session)); + /* This returns NULL in client side. */ + if (gnutls_psk_server_get_username (session) != NULL) + LOG_D("\t - PSK authentication. Connected as '%s'", + gnutls_psk_server_get_username (session)); + break; + + case GNUTLS_CRD_ANON: /* anonymous authentication */ + LOG_D("\t - Anonymous DH using prime of %d bits", + gnutls_dh_get_prime_bits (session)); + break; + + case GNUTLS_CRD_CERTIFICATE: /* certificate authentication */ + /* Check if we have been using ephemeral Diffie-Hellman. */ + if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) { + LOG_D("\t - Ephemeral DH using prime of %d bits", + gnutls_dh_get_prime_bits (session)); + } + break; +#ifdef ENABLE_SRP + case GNUTLS_CRD_SRP: + LOG_D("\t - SRP session with username %s", + gnutls_srp_server_get_username (session)); + break; +#endif /* ENABLE_SRP */ + + default: + fd_log_debug("\t - Different type of credentials for the session (%d).", cred); + break; + + } + + /* print the protocol's name (ie TLS 1.0) */ + tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session)); + LOG_D("\t - Protocol: %s", tmp); + + /* print the certificate type of the peer. ie X.509 */ + tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session)); + LOG_D("\t - Certificate Type: %s", tmp); + + /* print the compression algorithm (if any) */ + tmp = gnutls_compression_get_name (gnutls_compression_get (session)); + LOG_D("\t - Compression: %s", tmp); + + /* print the name of the cipher used. ie 3DES. */ + tmp = gnutls_cipher_get_name (gnutls_cipher_get (session)); + LOG_D("\t - Cipher: %s", tmp); + + /* Print the MAC algorithms name. ie SHA1 */ + tmp = gnutls_mac_get_name (gnutls_mac_get (session)); + LOG_D("\t - MAC: %s", tmp); + } + #endif /* DEBUG */ + + /* First, use built-in verification */ + CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (session, >ret), return EINVAL ); + if (gtret) { + LOG_E("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + if (gtret & GNUTLS_CERT_INVALID) + LOG_E(" - The certificate is not trusted (unknown CA? expired?)"); + if (gtret & GNUTLS_CERT_REVOKED) + LOG_E(" - The certificate has been revoked."); + if (gtret & GNUTLS_CERT_SIGNER_NOT_FOUND) + LOG_E(" - The certificate hasn't got a known issuer."); + if (gtret & GNUTLS_CERT_SIGNER_NOT_CA) + LOG_E(" - The certificate signer is not a CA, or uses version 1, or 3 without basic constraints."); + if (gtret & GNUTLS_CERT_INSECURE_ALGORITHM) + LOG_E(" - The certificate signature uses a weak algorithm."); + return EINVAL; + } + + /* Code from http://www.gnu.org/software/gnutls/manual/gnutls.html#Verifying-peer_0027s-certificate */ + if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { + LOG_E("TLS: Remote peer did not present a certificate, other mechanisms are not supported yet. socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + return EINVAL; + } + + GNUTLS_TRACE( cert_list = gnutls_certificate_get_peers (session, &cert_list_size) ); + if (cert_list == NULL) + return EINVAL; + + now = time(NULL); + + #ifdef DEBUG + char serial[40]; + char dn[128]; + size_t size; + unsigned int algo, bits; + time_t expiration_time, activation_time; + + LOG_D("TLS Certificate information for connection '%s' (%d certs provided):", conn->cc_id, cert_list_size); + for (i = 0; i < cert_list_size; i++) + { + + CHECK_GNUTLS_DO( gnutls_x509_crt_init (&cert), return EINVAL); + CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL); + + LOG_A(" Certificate %d info:", i); + + GNUTLS_TRACE( expiration_time = gnutls_x509_crt_get_expiration_time (cert) ); + GNUTLS_TRACE( activation_time = gnutls_x509_crt_get_activation_time (cert) ); + + LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate is valid since: %.24s", ctime (&activation_time)); + LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate expires: %.24s", ctime (&expiration_time)); + + /* Print the serial number of the certificate. */ + size = sizeof (serial); + gnutls_x509_crt_get_serial (cert, serial, &size); + + { + int j; + char buf[1024]; + snprintf(buf, sizeof(buf), "\t - Certificate serial number: "); + for (j = 0; j < size; j++) { + snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02hhx", serial[j]); + } + LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "%s", buf); + } + + /* Extract some of the public key algorithm's parameters */ + GNUTLS_TRACE( algo = gnutls_x509_crt_get_pk_algorithm (cert, &bits) ); + LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate public key: %s", + gnutls_pk_algorithm_get_name (algo)); + + /* Print the version of the X.509 certificate. */ + LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate version: #%d", + gnutls_x509_crt_get_version (cert)); + + size = sizeof (dn); + GNUTLS_TRACE( gnutls_x509_crt_get_dn (cert, dn, &size) ); + LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - DN: %s", dn); + + size = sizeof (dn); + GNUTLS_TRACE( gnutls_x509_crt_get_issuer_dn (cert, dn, &size) ); + LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Issuer's DN: %s", dn); + + GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) ); + } + #endif /* DEBUG */ + + /* Check validity of all the certificates */ + for (i = 0; i < cert_list_size; i++) + { + time_t deadline; + + CHECK_GNUTLS_DO( gnutls_x509_crt_init (&cert), return EINVAL); + CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL); + + GNUTLS_TRACE( deadline = gnutls_x509_crt_get_expiration_time(cert) ); + if ((deadline != (time_t)-1) && (deadline < now)) { + LOG_E("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + LOG_E(" - The certificate %d in the chain is expired", i); + ret = EINVAL; + } + + GNUTLS_TRACE( deadline = gnutls_x509_crt_get_activation_time(cert) ); + if ((deadline != (time_t)-1) && (deadline > now)) { + LOG_E("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + LOG_E(" - The certificate %d in the chain is not yet activated", i); + ret = EINVAL; + } + + if ((i == 0) && (conn->cc_tls_para.cn)) { + if (!gnutls_x509_crt_check_hostname (cert, conn->cc_tls_para.cn)) { + LOG_E("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + LOG_E(" - The certificate hostname does not match '%s'", conn->cc_tls_para.cn); + ret = EINVAL; + } + } + + GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) ); + } + + return ret; +} + +#else /* GNUTLS_VERSION_300 */ + +/* Verify remote credentials DURING handshake (return gnutls status) */ +int fd_tls_verify_credentials_2(gnutls_session_t session) +{ + /* inspired from gnutls 3.x guidelines */ + unsigned int status; + const gnutls_datum_t *cert_list = NULL; + unsigned int cert_list_size; + gnutls_x509_crt_t cert; + struct cnxctx * conn; + int hostname_verified = 0; + + TRACE_ENTRY("%p", session); + + /* get the associated connection */ + conn = gnutls_session_get_ptr (session); + + /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */ +#ifdef DEBUG + const char *tmp; + gnutls_credentials_type_t cred; + gnutls_kx_algorithm_t kx; + int dhe, ecdh; + + dhe = ecdh = 0; + + LOG_A("TLS Session information for connection '%s':", conn->cc_id); + + /* print the key exchange's algorithm name + */ + GNUTLS_TRACE( kx = gnutls_kx_get (session) ); + GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) ); + LOG_D("\t- Key Exchange: %s", tmp); + + /* Check the authentication type used and switch + * to the appropriate. + */ + GNUTLS_TRACE( cred = gnutls_auth_get_type (session) ); + switch (cred) + { + case GNUTLS_CRD_IA: + LOG_D("\t - TLS/IA session"); + break; + + + #ifdef ENABLE_SRP + case GNUTLS_CRD_SRP: + LOG_D("\t - SRP session with username %s", + gnutls_srp_server_get_username (session)); + break; + #endif + + case GNUTLS_CRD_PSK: + /* This returns NULL in server side. + */ + if (gnutls_psk_client_get_hint (session) != NULL) + LOG_D("\t - PSK authentication. PSK hint '%s'", + gnutls_psk_client_get_hint (session)); + /* This returns NULL in client side. + */ + if (gnutls_psk_server_get_username (session) != NULL) + LOG_D("\t - PSK authentication. Connected as '%s'", + gnutls_psk_server_get_username (session)); + + if (kx == GNUTLS_KX_ECDHE_PSK) + ecdh = 1; + else if (kx == GNUTLS_KX_DHE_PSK) + dhe = 1; + break; + + case GNUTLS_CRD_ANON: /* anonymous authentication */ + LOG_D("\t - Anonymous DH using prime of %d bits", + gnutls_dh_get_prime_bits (session)); + if (kx == GNUTLS_KX_ANON_ECDH) + ecdh = 1; + else if (kx == GNUTLS_KX_ANON_DH) + dhe = 1; + break; + + case GNUTLS_CRD_CERTIFICATE: /* certificate authentication */ + + /* Check if we have been using ephemeral Diffie-Hellman. + */ + if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) + dhe = 1; + else if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) + ecdh = 1; + + /* Now print some info on the remote certificate */ + if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509) { + gnutls_datum_t cinfo; + + cert_list = gnutls_certificate_get_peers (session, &cert_list_size); + + LOG_D("\t Peer provided %d certificates.", cert_list_size); + + if (cert_list_size > 0) + { + int ret; + + /* we only print information about the first certificate. + */ + gnutls_x509_crt_init (&cert); + + gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER); + + LOG_A("\t Certificate info:"); + + /* This is the preferred way of printing short information about + a certificate. */ + + ret = gnutls_x509_crt_print (cert, GNUTLS_CRT_PRINT_ONELINE, &cinfo); + if (ret == 0) + { + LOG_D("\t\t%s", cinfo.data); + gnutls_free (cinfo.data); + } + + if (conn->cc_tls_para.cn) { + if (!gnutls_x509_crt_check_hostname (cert, conn->cc_tls_para.cn)) { + LOG_E("\tTLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + LOG_E("\t - The certificate hostname does not match '%s'", conn->cc_tls_para.cn); + gnutls_x509_crt_deinit (cert); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + } + + hostname_verified = 1; + + gnutls_x509_crt_deinit (cert); + + } + } + break; + + default: + LOG_E("\t - unknown session type (%d)", cred); + + } /* switch */ + + if (ecdh != 0) + LOG_D("\t - Ephemeral ECDH using curve %s", + gnutls_ecc_curve_get_name (gnutls_ecc_curve_get (session))); + else if (dhe != 0) + LOG_D("\t - Ephemeral DH using prime of %d bits", + gnutls_dh_get_prime_bits (session)); + + /* print the protocol's name (ie TLS 1.0) + */ + tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session)); + LOG_D("\t - Protocol: %s", tmp); + + /* print the certificate type of the peer. + * ie X.509 + */ + tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session)); + LOG_D("\t - Certificate Type: %s", tmp); + + /* print the compression algorithm (if any) + */ + tmp = gnutls_compression_get_name (gnutls_compression_get (session)); + LOG_D("\t - Compression: %s", tmp); + + /* print the name of the cipher used. + * ie 3DES. + */ + tmp = gnutls_cipher_get_name (gnutls_cipher_get (session)); + LOG_D("\t - Cipher: %s", tmp); + + /* Print the MAC algorithms name. + * ie SHA1 + */ + tmp = gnutls_mac_get_name (gnutls_mac_get (session)); + LOG_D("\t - MAC: %s", tmp); + +#endif /* DEBUG */ + + /* This verification function uses the trusted CAs in the credentials + * structure. So you must have installed one or more CA certificates. + */ + CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (session, &status), return GNUTLS_E_CERTIFICATE_ERROR ); + if (status & GNUTLS_CERT_INVALID) { + LOG_E("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) + LOG_E(" - The certificate hasn't got a known issuer."); + + if (status & GNUTLS_CERT_REVOKED) + LOG_E(" - The certificate has been revoked."); + + if (status & GNUTLS_CERT_EXPIRED) + LOG_E(" - The certificate has expired."); + + if (status & GNUTLS_CERT_NOT_ACTIVATED) + LOG_E(" - The certificate is not yet activated."); + } + if (status & GNUTLS_CERT_INVALID) + { + return GNUTLS_E_CERTIFICATE_ERROR; + } + + /* Up to here the process is the same for X.509 certificates and + * OpenPGP keys. From now on X.509 certificates are assumed. This can + * be easily extended to work with openpgp keys as well. + */ + if ((!hostname_verified) && (conn->cc_tls_para.cn)) { + if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { + LOG_E("TLS: Remote credentials are not x509, rejected on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + CHECK_GNUTLS_DO( gnutls_x509_crt_init (&cert), return GNUTLS_E_CERTIFICATE_ERROR ); + + cert_list = gnutls_certificate_get_peers (session, &cert_list_size); + CHECK_PARAMS_DO( cert_list, return GNUTLS_E_CERTIFICATE_ERROR ); + + CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER), return GNUTLS_E_CERTIFICATE_ERROR ); + + if (!gnutls_x509_crt_check_hostname (cert, conn->cc_tls_para.cn)) { + LOG_E("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :", conn->cc_socket, conn->cc_remid, conn->cc_id); + LOG_E(" - The certificate hostname does not match '%s'", conn->cc_tls_para.cn); + gnutls_x509_crt_deinit (cert); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + gnutls_x509_crt_deinit (cert); + } + + /* notify gnutls to continue handshake normally */ + return 0; +} + +#endif /* GNUTLS_VERSION_300 */ + +static int fd_cnx_may_dtls(struct cnxctx * conn) { +#ifndef DISABLE_SCTP + if ((conn->cc_proto == IPPROTO_SCTP) && (conn->cc_tls_para.algo == ALGO_HANDSHAKE_DEFAULT)) + return 1; +#endif /* DISABLE_SCTP */ + return 0; +} + +#ifndef DISABLE_SCTP +static int fd_cnx_uses_dtls(struct cnxctx * conn) { + return fd_cnx_may_dtls(conn) && (fd_cnx_teststate(conn, CC_STATUS_TLS)); +} +#endif /* DISABLE_SCTP */ + +/* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */ +int fd_cnx_handshake(struct cnxctx * conn, int mode, int algo, char * priority, void * alt_creds) +{ + int dtls = 0; + + TRACE_ENTRY( "%p %d %d %p %p", conn, mode, algo, priority, alt_creds); + CHECK_PARAMS( conn && (!fd_cnx_teststate(conn, CC_STATUS_TLS)) && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) && (!conn->cc_loop) ); + + /* Save the mode */ + conn->cc_tls_para.mode = mode; + conn->cc_tls_para.algo = algo; + + /* Cancel receiving thread if any -- it should already be terminated anyway, we just release the resources */ + CHECK_FCT_DO( fd_thr_term(&conn->cc_rcvthr), /* continue */); + + /* Once TLS handshake is done, we don't stop after the first message */ + conn->cc_loop = 1; + + dtls = fd_cnx_may_dtls(conn); + + /* Prepare the master session credentials and priority */ + CHECK_FCT( fd_tls_prepare(&conn->cc_tls_para.session, mode, dtls, priority, alt_creds) ); + + /* Special case: multi-stream TLS is not natively managed in GNU TLS, we use a wrapper library */ + if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) { +#ifdef DISABLE_SCTP + ASSERT(0); + CHECK_FCT( ENOTSUP ); +#else /* DISABLE_SCTP */ + /* Initialize the wrapper, start the demux thread */ + CHECK_FCT( fd_sctp3436_init(conn) ); +#endif /* DISABLE_SCTP */ + } else { + /* Set the transport pointer passed to push & pull callbacks */ + GNUTLS_TRACE( gnutls_transport_set_ptr( conn->cc_tls_para.session, (gnutls_transport_ptr_t) conn ) ); + + /* Set the push and pull callbacks */ + if (!dtls) { + #ifdef GNUTLS_VERSION_300 + GNUTLS_TRACE( gnutls_transport_set_pull_timeout_function( conn->cc_tls_para.session, (void *)fd_cnx_s_select ) ); + #endif /* GNUTLS_VERSION_300 */ + GNUTLS_TRACE( gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv) ); + #ifndef GNUTLS_VERSION_212 + GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) ); + #else /* GNUTLS_VERSION_212 */ + GNUTLS_TRACE( gnutls_transport_set_vec_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_sendv) ); + #endif /* GNUTLS_VERSION_212 */ + } else { + TODO("DTLS push/pull functions"); + return ENOTSUP; + } + } + + /* additional initialization for gnutls 3.x */ + #ifdef GNUTLS_VERSION_300 + /* the verify function has already been set in the global initialization in config.c */ + + /* fd_tls_verify_credentials_2 uses the connection */ + gnutls_session_set_ptr (conn->cc_tls_para.session, (void *) conn); + + if ((conn->cc_tls_para.cn != NULL) && (mode == GNUTLS_CLIENT)) { + /* this might allow virtual hosting on the remote peer */ + CHECK_GNUTLS_DO( gnutls_server_name_set (conn->cc_tls_para.session, GNUTLS_NAME_DNS, conn->cc_tls_para.cn, strlen(conn->cc_tls_para.cn)), /* ignore failure */); + } + + #endif /* GNUTLS_VERSION_300 */ + + #ifdef GNUTLS_VERSION_310 + GNUTLS_TRACE( gnutls_handshake_set_timeout( conn->cc_tls_para.session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT)); + #endif /* GNUTLS_VERSION_310 */ + + /* Mark the connection as protected from here, so that the gnutls credentials will be freed */ + fd_cnx_addstate(conn, CC_STATUS_TLS); + + /* Handshake master session */ + { + int ret; + + CHECK_GNUTLS_DO( ret = gnutls_handshake(conn->cc_tls_para.session), + { + if (TRACE_BOOL(INFO)) { + fd_log_debug("TLS Handshake failed on socket %d (%s) : %s", conn->cc_socket, conn->cc_id, gnutls_strerror(ret)); + } + fd_cnx_markerror(conn); + return EINVAL; + } ); + + #ifndef GNUTLS_VERSION_300 + /* Now verify the remote credentials are valid -- only simple tests here */ + CHECK_FCT_DO( fd_tls_verify_credentials(conn->cc_tls_para.session, conn, 1), + { + CHECK_GNUTLS_DO( gnutls_bye(conn->cc_tls_para.session, GNUTLS_SHUT_RDWR), ); + fd_cnx_markerror(conn); + return EINVAL; + }); + #endif /* GNUTLS_VERSION_300 */ + } + + /* Multi-stream TLS: handshake other streams as well */ + if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) { +#ifndef DISABLE_SCTP + /* Start reading the messages from the master session. That way, if the remote peer closed, we are not stuck inside handshake */ + CHECK_FCT(fd_sctp3436_startthreads(conn, 0)); + + /* Resume all additional sessions from the master one. */ + CHECK_FCT(fd_sctp3436_handshake_others(conn, priority, alt_creds)); + + /* Start decrypting the messages from all threads and queuing them in target queue */ + CHECK_FCT(fd_sctp3436_startthreads(conn, 1)); +#endif /* DISABLE_SCTP */ + } else { + /* Start decrypting the data */ + if (!dtls) { + CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_tls_single, conn ) ); + } else { + TODO("Signal the dtls_push function that multiple streams can be used from this point."); + TODO("Create DTLS rcvthr (must reassembly based on seq numbers & stream id ?)"); + return ENOTSUP; + } + } + + return 0; +} + +/* Retrieve TLS credentials of the remote peer, after handshake */ +int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size) +{ + TRACE_ENTRY("%p %p %p", conn, cert_list, cert_list_size); + CHECK_PARAMS( conn && fd_cnx_teststate(conn, CC_STATUS_TLS) && cert_list && cert_list_size ); + + /* This function only works for X.509 certificates. */ + CHECK_PARAMS( gnutls_certificate_type_get (conn->cc_tls_para.session) == GNUTLS_CRT_X509 ); + + GNUTLS_TRACE( *cert_list = gnutls_certificate_get_peers (conn->cc_tls_para.session, cert_list_size) ); + if (*cert_list == NULL) { + TRACE_DEBUG(INFO, "No certificate was provided by remote peer / an error occurred."); + return EINVAL; + } + + TRACE_DEBUG( FULL, "Saved certificate chain (%d certificates) in peer structure.", *cert_list_size); + + return 0; +} + +/* Receive next message. if timeout is not NULL, wait only until timeout. This function only pulls from a queue, mgr thread is filling that queue aynchrounously. */ +/* if the altfifo has been set on this conn object, this function must not be called */ +int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len) +{ + int ev; + size_t ev_sz; + void * ev_data; + + TRACE_ENTRY("%p %p %p %p", conn, timeout, buf, len); + CHECK_PARAMS(conn && (conn->cc_socket > 0) && buf && len); + CHECK_PARAMS(conn->cc_rcvthr != (pthread_t)NULL); + CHECK_PARAMS(conn->cc_alt == NULL); + + /* Now, pull the first event */ +get_next: + if (timeout) { + CHECK_FCT( fd_event_timedget(conn->cc_incoming, timeout, FDEVP_PSM_TIMEOUT, &ev, &ev_sz, &ev_data) ); + } else { + CHECK_FCT( fd_event_get(conn->cc_incoming, &ev, &ev_sz, &ev_data) ); + } + + switch (ev) { + case FDEVP_CNX_MSG_RECV: + /* We got one */ + *len = ev_sz; + *buf = ev_data; + return 0; + + case FDEVP_PSM_TIMEOUT: + TRACE_DEBUG(FULL, "Timeout event received"); + return ETIMEDOUT; + + case FDEVP_CNX_EP_CHANGE: + /* We ignore this event */ + goto get_next; + + case FDEVP_CNX_ERROR: + TRACE_DEBUG(FULL, "Received ERROR event on the connection"); + return ENOTCONN; + } + + TRACE_DEBUG(INFO, "Received unexpected event %d (%s)", ev, fd_pev_str(ev)); + return EINVAL; +} + +/* Where the events are sent */ +struct fifo * fd_cnx_target_queue(struct cnxctx * conn) +{ + struct fifo *q; + CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); + q = conn->cc_alt ?: conn->cc_incoming; + CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); + return q; +} + +/* Set an alternate FIFO list to send FDEVP_CNX_* events to */ +int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo) +{ + int ret; + TRACE_ENTRY( "%p %p", conn, alt_fifo ); + CHECK_PARAMS( conn && alt_fifo && conn->cc_incoming ); + + /* The magic function does it all */ + CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); + CHECK_FCT_DO( ret = fd_fifo_move( conn->cc_incoming, alt_fifo, &conn->cc_alt ), ); + CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); + + return ret; +} + +/* Send function when no multi-stream is involved, or sending on stream #0 (send() always use stream 0)*/ +static int send_simple(struct cnxctx * conn, unsigned char * buf, size_t len) +{ + ssize_t ret; + size_t sent = 0; + TRACE_ENTRY("%p %p %zd", conn, buf, len); + do { + if (fd_cnx_teststate(conn, CC_STATUS_TLS)) { + CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_tls_para.session, buf + sent, len - sent), ); + } else { + struct iovec iov; + iov.iov_base = buf + sent; + iov.iov_len = len - sent; + CHECK_SYS_DO( ret = fd_cnx_s_sendv(conn, &iov, 1), ); + } + if (ret <= 0) + return ENOTCONN; + + sent += ret; + } while ( sent < len ); + return 0; +} + +/* Send a message -- this is synchronous -- and we assume it's never called by several threads at the same time (on the same conn), so we don't protect. */ +int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len) +{ + TRACE_ENTRY("%p %p %zd", conn, buf, len); + + CHECK_PARAMS(conn && (conn->cc_socket > 0) && (! fd_cnx_teststate(conn, CC_STATUS_ERROR)) && buf && len); + + TRACE_DEBUG(FULL, "Sending %zdb %sdata on connection %s", len, fd_cnx_teststate(conn, CC_STATUS_TLS) ? "TLS-protected ":"", conn->cc_id); + + switch (conn->cc_proto) { + case IPPROTO_TCP: + CHECK_FCT( send_simple(conn, buf, len) ); + break; + +#ifndef DISABLE_SCTP + case IPPROTO_SCTP: { + int dtls = fd_cnx_uses_dtls(conn); + if (!dtls) { + int stream = 0; + if (conn->cc_sctp_para.unordered) { + int limit; + if (fd_cnx_teststate(conn, CC_STATUS_TLS)) + limit = conn->cc_sctp_para.pairs; + else + limit = conn->cc_sctp_para.str_out; + + if (limit > 1) { + conn->cc_sctp_para.next += 1; + conn->cc_sctp_para.next %= limit; + stream = conn->cc_sctp_para.next; + } + } + + if (stream == 0) { + /* We can use default function, it sends over stream #0 */ + CHECK_FCT( send_simple(conn, buf, len) ); + } else { + if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) { + struct iovec iov; + iov.iov_base = buf; + iov.iov_len = len; + + CHECK_SYS_DO( fd_sctp_sendstrv(conn, stream, &iov, 1), { fd_cnx_markerror(conn); return ENOTCONN; } ); + } else { + /* push the data to the appropriate session */ + ssize_t ret; + size_t sent = 0; + ASSERT(conn->cc_sctp3436_data.array != NULL); + do { + CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctp3436_data.array[stream].session, buf + sent, len - sent), ); + if (ret <= 0) + return ENOTCONN; + + sent += ret; + } while ( sent < len ); + } + } + } else { + /* DTLS */ + /* Multistream is handled at lower layer in the push/pull function */ + CHECK_FCT( send_simple(conn, buf, len) ); + } + } + break; +#endif /* DISABLE_SCTP */ + + default: + TRACE_DEBUG(INFO, "Unknown protocol: %d", conn->cc_proto); + ASSERT(0); + return ENOTSUP; /* or EINVAL... */ + } + + return 0; +} + + +/**************************************/ +/* Destruction of connection */ +/**************************************/ + +/* Destroy a conn structure, and shutdown the socket */ +void fd_cnx_destroy(struct cnxctx * conn) +{ + TRACE_ENTRY("%p", conn); + + CHECK_PARAMS_DO(conn, return); + + fd_cnx_addstate(conn, CC_STATUS_CLOSING); + + /* Initiate shutdown of the TLS session(s): call gnutls_bye(WR), then read until error */ + if (fd_cnx_teststate(conn, CC_STATUS_TLS)) { +#ifndef DISABLE_SCTP + int dtls = fd_cnx_uses_dtls(conn); + if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) { + if (! fd_cnx_teststate(conn, CC_STATUS_ERROR )) { + /* Bye on master session */ + CHECK_GNUTLS_DO( gnutls_bye(conn->cc_tls_para.session, GNUTLS_SHUT_WR), fd_cnx_markerror(conn) ); + } + + if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) { + /* and other stream pairs */ + fd_sctp3436_bye(conn); + } + + if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) { + /* Now wait for all decipher threads to terminate */ + fd_sctp3436_waitthreadsterm(conn); + } else { + /* Abord the threads, the connection is dead already */ + fd_sctp3436_stopthreads(conn); + } + + /* Deinit gnutls resources */ + fd_sctp3436_gnutls_deinit_others(conn); + if (conn->cc_tls_para.session) { + GNUTLS_TRACE( gnutls_deinit(conn->cc_tls_para.session) ); + conn->cc_tls_para.session = NULL; + } + + /* Destroy the wrapper (also stops the demux thread) */ + fd_sctp3436_destroy(conn); + + } else { +#endif /* DISABLE_SCTP */ + /* We are TLS, but not using the sctp3436 wrapper layer */ + if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) { + /* Master session */ + CHECK_GNUTLS_DO( gnutls_bye(conn->cc_tls_para.session, GNUTLS_SHUT_WR), fd_cnx_markerror(conn) ); + } + + if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) { + /* In this case, just wait for thread rcvthr_tls_single to terminate */ + if (conn->cc_rcvthr != (pthread_t)NULL) { + CHECK_POSIX_DO( pthread_join(conn->cc_rcvthr, NULL), /* continue */ ); + conn->cc_rcvthr = (pthread_t)NULL; + } + } else { + /* Cancel the receiver thread in case it did not already terminate */ + CHECK_FCT_DO( fd_thr_term(&conn->cc_rcvthr), /* continue */ ); + } + + /* Free the resources of the TLS session */ + if (conn->cc_tls_para.session) { + GNUTLS_TRACE( gnutls_deinit(conn->cc_tls_para.session) ); + conn->cc_tls_para.session = NULL; + } +#ifndef DISABLE_SCTP + } +#endif /* DISABLE_SCTP */ + } + + /* Terminate the thread in case it is not done yet -- is there any such case left ?*/ + CHECK_FCT_DO( fd_thr_term(&conn->cc_rcvthr), /* continue */ ); + + /* Shut the connection down */ + if (conn->cc_socket > 0) { + shutdown(conn->cc_socket, SHUT_RDWR); + close(conn->cc_socket); + conn->cc_socket = -1; + } + + /* Empty and destroy FIFO list */ + if (conn->cc_incoming) { + fd_event_destroy( &conn->cc_incoming, free ); + } + + /* Free the object */ + free(conn); + + /* Done! */ + return; +} diff --git a/plat/diameter/libfdcore/cnxctx.h b/plat/diameter/libfdcore/cnxctx.h new file mode 100644 index 0000000..8216404 --- /dev/null +++ b/plat/diameter/libfdcore/cnxctx.h @@ -0,0 +1,153 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* This file contains the definitions for internal use in the connection context files */ + +#ifndef _CNXCTX_H +#define _CNXCTX_H + +/* Maximum time we allow a connection to be blocked because of head-of-the-line buffers. After this delay, connection is considered in error. */ +#define MAX_HOTL_BLOCKING_TIME 1000 /* ms */ + +/* The connection context structure */ +struct cnxctx { + char cc_id[60]; /* The name of this connection. the first 5 chars are reserved for flags display (cc_state). */ + char cc_remid[60]; /* Id of remote peer */ + + int cc_socket; /* The socket object of the connection -- <=0 if no socket is created */ + + int cc_family; /* AF_INET or AF_INET6 (mixed) */ + int cc_proto; /* IPPROTO_TCP or IPPROTO_SCTP */ + + uint32_t cc_state; /* True if the object is being destroyed: we don't send events anymore. access with fd_cnx_getstate() */ + #define CC_STATUS_CLOSING 1 + #define CC_STATUS_ERROR 2 + #define CC_STATUS_SIGNALED 4 + #define CC_STATUS_TLS 8 + + pthread_t cc_rcvthr; /* thread for receiving messages on the connection */ + int cc_loop; /* tell the thread if it loops or stops after the first message is received */ + + struct fifo * cc_incoming; /* FIFO queue of events received on the connection, FDEVP_CNX_* */ + struct fifo * cc_alt; /* alternate fifo to send FDEVP_CNX_* events to. */ + + /* If cc_tls == true */ + struct { + DiamId_t cn; /* If not NULL, remote certif will be checked to match this Common Name */ + int mode; /* GNUTLS_CLIENT / GNUTLS_SERVER */ + int algo; /* ALGO_HANDSHAKE_DEFAULT / ALGO_HANDSHAKE_3436 */ + gnutls_session_t session; /* Session object (stream #0 in case of SCTP) */ + } cc_tls_para; + + /* If cc_proto == SCTP */ + struct { + uint16_t str_out; /* Out streams */ + uint16_t str_in; /* In streams */ + uint16_t pairs; /* max number of pairs ( = min(in, out)) */ + uint16_t next; /* # of stream the next message will be sent to */ + int unordered; /* boolean telling if use of streams > 0 is permitted */ + } cc_sctp_para; + + /* If both conditions */ + struct { + struct sctp3436_ctx *array; /* an array of cc_sctp_para.pairs elements -- the #0 is special (session is outside)*/ + struct sr_store *sess_store; /* Session data of the master session, to resume the children sessions */ + } cc_sctp3436_data; +}; + +void fd_cnx_markerror(struct cnxctx * conn); +uint32_t fd_cnx_getstate(struct cnxctx * conn); +int fd_cnx_teststate(struct cnxctx * conn, uint32_t flag); +void fd_cnx_addstate(struct cnxctx * conn, uint32_t orstate); +void fd_cnx_setstate(struct cnxctx * conn, uint32_t abstate); +struct fifo * fd_cnx_target_queue(struct cnxctx * conn); + + +/* Socket */ +ssize_t fd_cnx_s_recv(struct cnxctx * conn, void *buffer, size_t length); +void fd_cnx_s_setto(int sock); + +/* TLS */ +int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session); +int fd_tls_prepare(gnutls_session_t * session, int mode, int dtls, char * priority, void * alt_creds); +#ifndef GNUTLS_VERSION_300 +int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, int verbose); +#endif /* GNUTLS_VERSION_300 */ + +/* TCP */ +int fd_tcp_create_bind_server( int * sock, sSA * sa, socklen_t salen ); +int fd_tcp_listen( int sock ); +int fd_tcp_client( int *sock, sSA * sa, socklen_t salen ); +int fd_tcp_get_local_ep(int sock, sSS * ss, socklen_t *sl); +int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl); + +#ifndef DISABLE_SCTP +/* SCTP */ +int fd_sctp_create_bind_server( int * sock, int family, struct fd_list * list, uint16_t port ); +int fd_sctp_listen( int sock ); +int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list ); +int fd_sctp_get_local_ep(int sock, struct fd_list * list); +int fd_sctp_get_remote_ep(int sock, struct fd_list * list); +int fd_sctp_get_str_info( int sock, uint16_t *in, uint16_t *out, sSS *primary ); +ssize_t fd_sctp_sendstrv(struct cnxctx * conn, uint16_t strid, const struct iovec *iov, int iovcnt); +int fd_sctp_recvmeta(struct cnxctx * conn, uint16_t * strid, uint8_t ** buf, size_t * len, int *event); + +/* TLS over SCTP (multi-stream) */ +struct sctp3436_ctx { + struct cnxctx *parent; /* for info such as socket, conn name, event list */ + uint16_t strid; /* Stream # of this session */ + struct fifo *raw_recv; /* Raw data received on this stream, for demux */ + struct { + uint8_t *buf; + size_t bufsz; + size_t offset; + } partial; /* If the pull function did not read the full content of first message in raw, it stores it here for next read call. */ + pthread_t thr; /* Thread to decrypt raw data in this pair of streams */ + gnutls_session_t session; /* TLS context using this pair of streams -- except if strid == 0, in that case session is outside the array */ +}; + +int fd_sctp3436_init(struct cnxctx * conn); +int fd_sctp3436_handshake_others(struct cnxctx * conn, char * priority, void * alt_creds); +int fd_sctp3436_startthreads(struct cnxctx * conn, int others); +void fd_sctp3436_bye(struct cnxctx * conn); +void fd_sctp3436_waitthreadsterm(struct cnxctx * conn); +void fd_sctp3436_gnutls_deinit_others(struct cnxctx * conn); +void fd_sctp3436_stopthreads(struct cnxctx * conn); +void fd_sctp3436_destroy(struct cnxctx * conn); + +#endif /* DISABLE_SCTP */ + +#endif /* _CNXCTX_H */ + diff --git a/plat/diameter/libfdcore/config.c b/plat/diameter/libfdcore/config.c new file mode 100644 index 0000000..3865e0e --- /dev/null +++ b/plat/diameter/libfdcore/config.c @@ -0,0 +1,643 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" +#include +/* Configuration management */ + +#ifndef GNUTLS_DEFAULT_PRIORITY +# define GNUTLS_DEFAULT_PRIORITY "NORMAL" +#endif /* GNUTLS_DEFAULT_PRIORITY */ +#ifndef GNUTLS_DEFAULT_DHBITS +# define GNUTLS_DEFAULT_DHBITS 1024 +#endif /* GNUTLS_DEFAULT_DHBITS */ + +/* Initialize the fd_g_config structure to default values -- it should already have been initialized to all-0 */ +int fd_conf_init() +{ + TRACE_ENTRY(); + + fd_g_config->cnf_eyec = EYEC_CONFIG; + + fd_g_config->cnf_timer_tc = 30; + fd_g_config->cnf_timer_tw = 30; + + fd_g_config->cnf_port = DIAMETER_PORT; + fd_g_config->cnf_port_tls = DIAMETER_SECURE_PORT; + fd_g_config->cnf_sctp_str = 30; + fd_g_config->cnf_thr_srv = 10; + fd_g_config->cnf_dispthr = 1;// = 10; + fd_list_init(&fd_g_config->cnf_endpoints, NULL); + fd_list_init(&fd_g_config->cnf_apps, NULL); + #ifdef DISABLE_SCTP + fd_g_config->cnf_flags.no_sctp = 1; + #endif /* DISABLE_SCTP */ + + fd_g_config->cnf_orstateid = (uint32_t) time(NULL); + + CHECK_FCT( fd_dict_init(&fd_g_config->cnf_dict) ); + CHECK_FCT( fd_fifo_new(&fd_g_config->cnf_main_ev, 0) ); + + /* TLS parameters */ + CHECK_GNUTLS_DO( gnutls_certificate_allocate_credentials (&fd_g_config->cnf_sec_data.credentials), return ENOMEM ); + CHECK_GNUTLS_DO( gnutls_dh_params_init (&fd_g_config->cnf_sec_data.dh_cache), return ENOMEM ); +#ifdef GNUTLS_VERSION_300 + CHECK_GNUTLS_DO( gnutls_x509_trust_list_init(&fd_g_config->cnf_sec_data.trustlist, 0), return ENOMEM ); +#endif /* GNUTLS_VERSION_300 */ + return 0; +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_conf_dump) +{ + FD_DUMP_HANDLE_OFFSET(); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "freeDiameter configuration:\n"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Default trace level .... : %+d\n", fd_g_debug_lvl), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Configuration file ..... : %s\n", fd_g_config->cnf_file), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Diameter Identity ...... : %s (l:%zi)\n", fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Diameter Realm ......... : %s (l:%zi)\n", fd_g_config->cnf_diamrlm, fd_g_config->cnf_diamrlm_len), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Tc Timer ............... : %u\n", fd_g_config->cnf_timer_tc), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Tw Timer ............... : %u\n", fd_g_config->cnf_timer_tw), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local port ............. : %hu\n", fd_g_config->cnf_port), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local secure port ...... : %hu\n", fd_g_config->cnf_port_tls), return NULL); + if (fd_g_config->cnf_port_3436) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local SCTP TLS port .... : %hu\n", fd_g_config->cnf_port_3436), return NULL); + } + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Number of SCTP streams . : %hu\n", fd_g_config->cnf_sctp_str), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Number of clients thr .. : %d\n", fd_g_config->cnf_thr_srv), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Number of app threads .. : %hu\n", fd_g_config->cnf_dispthr), return NULL); + if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local endpoints ........ : Default (use all available)\n"), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local endpoints ........ : "), return NULL); + CHECK_MALLOC_DO( fd_ep_dump( FD_DUMP_STD_PARAMS, 0, 0, &fd_g_config->cnf_endpoints ), return NULL); + } + if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_apps)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : (none)"), return NULL); + } else { + struct fd_list * li = fd_g_config->cnf_apps.next; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : "), return NULL); + while (li != &fd_g_config->cnf_apps) { + struct fd_app * app = (struct fd_app *)li; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "App: %u,%s%s,Vnd:%u\t", + app->appid, + app->flags.auth ? "Au" : "--", + app->flags.acct ? "Ac" : "--", + app->vndid), return NULL); + li = li->next; + } + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n Flags : - IP ........... : %s\n", fd_g_config->cnf_flags.no_ip4 ? "DISABLED" : "Enabled"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - IPv6 ......... : %s\n", fd_g_config->cnf_flags.no_ip6 ? "DISABLED" : "Enabled"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Relay app .... : %s\n", fd_g_config->cnf_flags.no_fwd ? "DISABLED" : "Enabled"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - TCP .......... : %s\n", fd_g_config->cnf_flags.no_tcp ? "DISABLED" : "Enabled"), return NULL); + #ifdef DISABLE_SCTP + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - SCTP ......... : DISABLED (at compilation)\n"), return NULL); + #else /* DISABLE_SCTP */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - SCTP ......... : %s\n", fd_g_config->cnf_flags.no_sctp ? "DISABLED" : "Enabled"), return NULL); + #endif /* DISABLE_SCTP */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Pref. proto .. : %s\n", fd_g_config->cnf_flags.pr_tcp ? "TCP" : "SCTP"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - TLS method ... : %s\n", fd_g_config->cnf_flags.tls_alg ? "INBAND" : "Separate port"), return NULL); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " TLS : - Certificate .. : %s\n", fd_g_config->cnf_sec_data.cert_file ?: "(NONE)"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Private key .. : %s\n", fd_g_config->cnf_sec_data.key_file ?: "(NONE)"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - CA (trust) ... : %s (%d certs)\n", fd_g_config->cnf_sec_data.ca_file ?: "(none)", fd_g_config->cnf_sec_data.ca_file_nr), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - CRL .......... : %s\n", fd_g_config->cnf_sec_data.crl_file ?: "(none)"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Priority ..... : %s\n", fd_g_config->cnf_sec_data.prio_string ?: "(default: '" GNUTLS_DEFAULT_PRIORITY "')"), return NULL); + if (fd_g_config->cnf_sec_data.dh_file) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - DH file ...... : %s\n", fd_g_config->cnf_sec_data.dh_file), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - DH bits ...... : %d\n", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS), return NULL); + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Origin-State-Id ........ : %u", fd_g_config->cnf_orstateid), return NULL); + + return *buf; +} + +/* read contents of a file opened in "rb" mode and alloc this data into a gnutls_datum_t (must be freed afterwards) */ +int fd_conf_stream_to_gnutls_datum(FILE * pemfile, gnutls_datum_t *out) +{ + size_t alloc = 0; + + CHECK_PARAMS( pemfile && out ); + memset(out, 0, sizeof(gnutls_datum_t)); + + do { + uint8_t * realloced = NULL; + size_t read = 0; + + if (alloc < out->size + BUFSIZ + 1) { + alloc += alloc / 2 + BUFSIZ + 1; + CHECK_MALLOC_DO( realloced = realloc(out->data, alloc), + { + free(out->data); + return ENOMEM; + } ) + out->data = realloced; + } + + read = fread( out->data + out->size, 1, alloc - out->size - 1, pemfile ); + out->size += read; + + if (ferror(pemfile)) { + int err = errno; + TRACE_DEBUG(INFO, "An error occurred while reading file: %s", strerror(err)); + return err; + } + } while (!feof(pemfile)); + + out->data[out->size] = '\0'; + return 0; +} + +#ifdef GNUTLS_VERSION_300 +/* inspired from GnuTLS manual */ +static int fd_conf_print_details_func (gnutls_x509_crt_t cert, + gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl, + unsigned int verification_output) +{ + char name[512]; + char issuer_name[512]; + size_t name_size; + size_t issuer_name_size; + + if (!TRACE_BOOL(GNUTLS_DBG_LEVEL)) + return 0; + + issuer_name_size = sizeof (issuer_name); + gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size); + + name_size = sizeof (name); + gnutls_x509_crt_get_dn (cert, name, &name_size); + + fd_log_debug("\tSubject: %s", name); + fd_log_debug("\tIssuer: %s", issuer_name); + + if (issuer != NULL) + { + issuer_name_size = sizeof (issuer_name); + gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size); + + fd_log_debug("\tVerified against: %s", issuer_name); + } + + if (crl != NULL) + { + issuer_name_size = sizeof (issuer_name); + gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size); + + fd_log_debug("\tVerified against CRL of: %s", issuer_name); + } + + fd_log_debug("\tVerification output: %x", verification_output); + + return 0; +} +#endif /* GNUTLS_VERSION_300 */ + +#ifndef GNUTLS_VERSION_300 +GCC_DIAG_OFF("-Wdeprecated-declarations") +#endif /* !GNUTLS_VERSION_300 */ +/* Parse the configuration file (using the yacc parser) */ +int fd_conf_parse() +{ + FILE * fddin; + const char * orig = NULL; + + /* Attempt to find the configuration file */ + if (!fd_g_config->cnf_file) + fd_g_config->cnf_file = FD_DEFAULT_CONF_FILENAME; + + fddin = fopen(fd_g_config->cnf_file, "r"); + if ((fddin == NULL) && (*fd_g_config->cnf_file != '/')) { + char * new_cnf = NULL; + /* We got a relative path, attempt to add the default directory prefix */ + orig = fd_g_config->cnf_file; + CHECK_MALLOC( new_cnf = malloc(strlen(orig) + strlen(DEFAULT_CONF_PATH) + 2) ); /* we will not free it, but not important */ + sprintf( new_cnf, DEFAULT_CONF_PATH "/%s", orig ); + fd_g_config->cnf_file = new_cnf; + fddin = fopen(fd_g_config->cnf_file, "r"); + } + if (fddin == NULL) { + int ret = errno; + LOG_F("Unable to open configuration file for reading; tried the following locations: %s%s%s; Error: %s", + orig ?: "", orig? " and " : "", fd_g_config->cnf_file, strerror(ret)); + return ret; + } + + /* call yacc parser */ + TRACE_DEBUG (FULL, "Parsing configuration file: %s", fd_g_config->cnf_file); + CHECK_FCT( fddparse(fd_g_config) ); + + /* close the file */ + fclose(fddin); + + /* Check that TLS private key was given */ + if (! fd_g_config->cnf_sec_data.key_file) { + /* If TLS is not enabled, we allow empty TLS configuration */ + if ((fd_g_config->cnf_port_tls == 0) && (fd_g_config->cnf_flags.tls_alg == 0)) { + LOG_N("TLS is disabled, this is *NOT* a recommended practice! Diameter protocol conveys highly sensitive information on your users."); + fd_g_config->cnf_sec_data.tls_disabled = 1; + } else { + LOG_F( "Missing private key configuration for TLS. Please provide the TLS_cred configuration directive."); + return EINVAL; + } + } + + /* Resolve hostname if not provided */ + if (fd_g_config->cnf_diamid == NULL) { + char buf[HOST_NAME_MAX + 1]; + struct addrinfo hints, *info; + int ret; + + /* local host name */ + CHECK_SYS(gethostname(buf, sizeof(buf))); + + /* get FQDN */ + memset(&hints, 0, sizeof hints); + hints.ai_flags = AI_CANONNAME; + + ret = getaddrinfo(buf, NULL, &hints, &info); + if (ret != 0) { + TRACE_ERROR( "Error resolving local FQDN : '%s' : %s" + ". Please provide Identity in configuration file.", + buf, gai_strerror(ret)); + return EINVAL; + } + fd_g_config->cnf_diamid = info->ai_canonname; + CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamid, &fd_g_config->cnf_diamid_len, 1) ); + freeaddrinfo(info); + } else { + CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamid, &fd_g_config->cnf_diamid_len, 0) ); + } + + /* Handle the realm part */ + if (fd_g_config->cnf_diamrlm == NULL) { + char * start = NULL; + + /* Check the diameter identity is a fqdn */ + start = strchr(fd_g_config->cnf_diamid, '.'); + if ((start == NULL) || (start[1] == '\0')) { + TRACE_ERROR( "Unable to extract realm from the Identity '%s'." + " Please fix your Identity setting or provide Realm.", + fd_g_config->cnf_diamid); + return EINVAL; + } + + fd_g_config->cnf_diamrlm = start + 1; + CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamrlm, &fd_g_config->cnf_diamrlm_len, 1) ); + } else { + CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamrlm, &fd_g_config->cnf_diamrlm_len, 0) ); + } + + /* Validate some flags */ + if (fd_g_config->cnf_flags.no_ip4 && fd_g_config->cnf_flags.no_ip6) { + TRACE_ERROR( "IP and IPv6 cannot be disabled at the same time."); + return EINVAL; + } + if (fd_g_config->cnf_flags.no_tcp && fd_g_config->cnf_flags.no_sctp) { + TRACE_ERROR( "TCP and SCTP cannot be disabled at the same time."); + return EINVAL; + } + + /* Validate local endpoints */ + if ((!FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) && (fd_g_config->cnf_flags.no_ip4 || fd_g_config->cnf_flags.no_ip6)) { + struct fd_list * li; + for ( li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + if ( (fd_g_config->cnf_flags.no_ip4 && (ep->sa.sa_family == AF_INET)) + ||(fd_g_config->cnf_flags.no_ip6 && (ep->sa.sa_family == AF_INET6)) ) { + char sa_buf[sSA_DUMP_STRLEN];; + li = li->prev; + fd_list_unlink(&ep->chain); + fd_sa_sdump_numeric(sa_buf, &ep->sa); + LOG_N("Info: Removing local address conflicting with the flags no_IP / no_IP6 : %s", sa_buf); + free(ep); + } + } + } + + /* Configure TLS default parameters */ + if ((!fd_g_config->cnf_sec_data.tls_disabled) && (!fd_g_config->cnf_sec_data.prio_string)) { + const char * err_pos = NULL; + CHECK_GNUTLS_DO( gnutls_priority_init( + &fd_g_config->cnf_sec_data.prio_cache, + GNUTLS_DEFAULT_PRIORITY, + &err_pos), + { TRACE_ERROR("Error in priority string at position : %s", err_pos); return EINVAL; } ); + } + + /* Verify that our certificate is valid -- otherwise remote peers will reject it */ + if (!fd_g_config->cnf_sec_data.tls_disabled) { + int ret = 0, i; + + gnutls_datum_t certfile; + + gnutls_x509_crt_t * certs = NULL; + unsigned int cert_max = 0; + + + /* Read the certificate file */ + FILE *stream = fopen (fd_g_config->cnf_sec_data.cert_file, "rb"); + if (!stream) { + int err = errno; + TRACE_DEBUG(INFO, "An error occurred while opening '%s': %s", fd_g_config->cnf_sec_data.cert_file, strerror(err)); + return err; + } + CHECK_FCT( fd_conf_stream_to_gnutls_datum(stream, &certfile) ); + fclose(stream); + + /* Import the certificate(s) */ + GNUTLS_TRACE( ret = gnutls_x509_crt_list_import(NULL, &cert_max, &certfile, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED) ); + if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { + CHECK_GNUTLS_DO(ret, return EINVAL); + } + + CHECK_MALLOC( certs = calloc(cert_max, sizeof(gnutls_x509_crt_t)) ); + CHECK_GNUTLS_DO( gnutls_x509_crt_list_import(certs, &cert_max, &certfile, GNUTLS_X509_FMT_PEM, + #ifdef GNUTLS_VERSION_300 + GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED + #else /* GNUTLS_VERSION_300 */ + 0 + #endif /* GNUTLS_VERSION_300 */ + ), + { + TRACE_ERROR("Failed to import the data from file '%s'", fd_g_config->cnf_sec_data.cert_file); + free(certfile.data); + return EINVAL; + } ); + free(certfile.data); + + ASSERT(cert_max >= 1); + + /* Now, verify the list against the local CA and CRL */ + + #ifdef GNUTLS_VERSION_300 + + /* We use the trust list for this purpose */ + { + unsigned int output; + + gnutls_x509_trust_list_verify_named_crt ( + fd_g_config->cnf_sec_data.trustlist, + certs[0], + fd_g_config->cnf_diamid, + fd_g_config->cnf_diamid_len, + 0, + &output, + fd_conf_print_details_func); + + /* if this certificate is not explicitly trusted verify against CAs + */ + if (output != 0) + { + gnutls_x509_trust_list_verify_crt ( + fd_g_config->cnf_sec_data.trustlist, + certs, + cert_max, + 0, + &output, + fd_conf_print_details_func); + } + + if (output & GNUTLS_CERT_INVALID) + { + fd_log_debug("TLS: Local certificate chain '%s' is invalid :", fd_g_config->cnf_sec_data.cert_file); + if (output & GNUTLS_CERT_SIGNER_NOT_FOUND) + TRACE_ERROR(" - The certificate hasn't got a known issuer. Did you forget to specify TLS_CA ?"); + if (output & GNUTLS_CERT_SIGNER_NOT_CA) + TRACE_ERROR(" - The certificate signer is not a CA, or uses version 1, or 3 without basic constraints."); + if (output & GNUTLS_CERT_NOT_ACTIVATED) + TRACE_ERROR(" - The certificate is not yet activated."); + if (output & GNUTLS_CERT_EXPIRED) + TRACE_ERROR(" - The certificate is expired."); + return EINVAL; + } + + /* Now check the subject matches our hostname */ + if (!gnutls_x509_crt_check_hostname (certs[0], fd_g_config->cnf_diamid)) + { + TRACE_ERROR("TLS: The certificate owner does not match the hostname '%s'", fd_g_config->cnf_diamid); + return EINVAL; + } + + } + + + #else /* GNUTLS_VERSION_300 */ + + /* GnuTLS 2.x way of checking certificates */ + { + gnutls_x509_crt_t * CA_list; + int CA_list_length; + + gnutls_x509_crl_t * CRL_list; + int CRL_list_length; + + unsigned int verify; + time_t now; + /* + GNUTLS_TRACE( gnutls_certificate_get_x509_cas (fd_g_config->cnf_sec_data.credentials, &CA_list, (unsigned int *) &CA_list_length) ); + GNUTLS_TRACE( gnutls_certificate_get_x509_crls (fd_g_config->cnf_sec_data.credentials, &CRL_list, (unsigned int *) &CRL_list_length) ); + CHECK_GNUTLS_DO( gnutls_x509_crt_list_verify(certs, cert_max, CA_list, CA_list_length, CRL_list, CRL_list_length, 0, &verify), + { + TRACE_ERROR("Failed to verify the local certificate '%s' against local credentials. Please check your certificate is valid.", fd_g_config->cnf_sec_data.cert_file); + return EINVAL; + } ); + */ + if (verify) { + fd_log_debug("TLS: Local certificate chain '%s' is invalid :", fd_g_config->cnf_sec_data.cert_file); + if (verify & GNUTLS_CERT_INVALID) + TRACE_ERROR(" - The certificate is not trusted (unknown CA? expired?)"); + if (verify & GNUTLS_CERT_REVOKED) + TRACE_ERROR(" - The certificate has been revoked."); + if (verify & GNUTLS_CERT_SIGNER_NOT_FOUND) + TRACE_ERROR(" - The certificate hasn't got a known issuer."); + if (verify & GNUTLS_CERT_SIGNER_NOT_CA) + TRACE_ERROR(" - The certificate signer is not a CA, or uses version 1, or 3 without basic constraints."); + if (verify & GNUTLS_CERT_INSECURE_ALGORITHM) + TRACE_ERROR(" - The certificate signature uses a weak algorithm."); + return EINVAL; + } + + /* Check the local Identity is valid with the certificate */ + if (!gnutls_x509_crt_check_hostname (certs[0], fd_g_config->cnf_diamid)) { + TRACE_ERROR("TLS: Local certificate '%s' is invalid :", fd_g_config->cnf_sec_data.cert_file); + TRACE_ERROR(" - The certificate hostname does not match '%s'", fd_g_config->cnf_diamid); + return EINVAL; + } + + /* Check validity of all the certificates in the chain */ + now = time(NULL); + for (i = 0; i < cert_max; i++) + { + time_t deadline; + + GNUTLS_TRACE( deadline = gnutls_x509_crt_get_expiration_time(certs[i]) ); + if ((deadline != (time_t)-1) && (deadline < now)) { + TRACE_ERROR("TLS: Local certificate chain '%s' is invalid :", fd_g_config->cnf_sec_data.cert_file); + TRACE_ERROR(" - The certificate %d in the chain is expired", i); + return EINVAL; + } + + GNUTLS_TRACE( deadline = gnutls_x509_crt_get_activation_time(certs[i]) ); + if ((deadline != (time_t)-1) && (deadline > now)) { + TRACE_ERROR("TLS: Local certificate chain '%s' is invalid :", fd_g_config->cnf_sec_data.cert_file); + TRACE_ERROR(" - The certificate %d in the chain is not yet activated", i); + return EINVAL; + } + } + } + #endif /* GNUTLS_VERSION_300 */ + + /* Everything checked OK, free the certificate list */ + for (i = 0; i < cert_max; i++) + { + GNUTLS_TRACE( gnutls_x509_crt_deinit (certs[i]) ); + } + free(certs); + + #ifdef GNUTLS_VERSION_300 + /* Use certificate verification during the handshake */ + gnutls_certificate_set_verify_function (fd_g_config->cnf_sec_data.credentials, fd_tls_verify_credentials_2); + #endif /* GNUTLS_VERSION_300 */ + + } + + /* gnutls_certificate_set_verify_limits -- so far the default values are fine... */ + + /* DH */ + if (!fd_g_config->cnf_sec_data.tls_disabled) { + if (fd_g_config->cnf_sec_data.dh_file) { + gnutls_datum_t dhparams = { NULL, 0 }; + size_t alloc = 0; + FILE *stream = fopen (fd_g_config->cnf_sec_data.dh_file, "rb"); + if (!stream) { + int err = errno; + TRACE_DEBUG(INFO, "An error occurred while opening '%s': %s", fd_g_config->cnf_sec_data.dh_file, strerror(err)); + return err; + } + do { + uint8_t * realloced = NULL; + size_t read = 0; + + if (alloc < dhparams.size + BUFSIZ + 1) { + alloc += alloc / 2 + BUFSIZ + 1; + CHECK_MALLOC_DO( realloced = realloc(dhparams.data, alloc), + { + free(dhparams.data); + return ENOMEM; + } ) + dhparams.data = realloced; + } + + read = fread( dhparams.data + dhparams.size, 1, alloc - dhparams.size - 1, stream ); + dhparams.size += read; + + if (ferror(stream)) { + int err = errno; + TRACE_DEBUG(INFO, "An error occurred while reading '%s': %s", fd_g_config->cnf_sec_data.dh_file, strerror(err)); + return err; + } + } while (!feof(stream)); + dhparams.data[dhparams.size] = '\0'; + fclose(stream); + CHECK_GNUTLS_DO( gnutls_dh_params_import_pkcs3( + fd_g_config->cnf_sec_data.dh_cache, + &dhparams, + GNUTLS_X509_FMT_PEM), + { TRACE_ERROR("Error in DH bits value : %d", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); return EINVAL; } ); + free(dhparams.data); + + } else { + LOG_D( "Generating fresh Diffie-Hellman parameters of size %d (this takes some time)... ", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); + CHECK_GNUTLS_DO( gnutls_dh_params_generate2( + fd_g_config->cnf_sec_data.dh_cache, + fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS), + { TRACE_ERROR("Error in DH bits value : %d", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); return EINVAL; } ); + } + + } + + return 0; +} +#ifndef GNUTLS_VERSION_300 +GCC_DIAG_ON("-Wdeprecated-declarations") +#endif /* !GNUTLS_VERSION_300 */ + + +/* Destroy contents of fd_g_config structure */ +int fd_conf_deinit() +{ + TRACE_ENTRY(); + + if (!fd_g_config) + return 0; + + /* Free the TLS parameters */ +#ifdef GNUTLS_VERSION_300 + gnutls_x509_trust_list_deinit(fd_g_config->cnf_sec_data.trustlist, 1); +#endif /* GNUTLS_VERSION_300 */ + gnutls_priority_deinit(fd_g_config->cnf_sec_data.prio_cache); + gnutls_dh_params_deinit(fd_g_config->cnf_sec_data.dh_cache); + gnutls_certificate_free_credentials(fd_g_config->cnf_sec_data.credentials); + + free(fd_g_config->cnf_sec_data.cert_file); fd_g_config->cnf_sec_data.cert_file = NULL; + free(fd_g_config->cnf_sec_data.key_file); fd_g_config->cnf_sec_data.key_file = NULL; + free(fd_g_config->cnf_sec_data.ca_file); fd_g_config->cnf_sec_data.ca_file = NULL; + free(fd_g_config->cnf_sec_data.crl_file); fd_g_config->cnf_sec_data.crl_file = NULL; + free(fd_g_config->cnf_sec_data.prio_string); fd_g_config->cnf_sec_data.prio_string = NULL; + free(fd_g_config->cnf_sec_data.dh_file); fd_g_config->cnf_sec_data.dh_file = NULL; + + /* Destroy dictionary */ + CHECK_FCT_DO( fd_dict_fini(&fd_g_config->cnf_dict), ); + + /* Destroy the main event queue */ + CHECK_FCT_DO( fd_fifo_del(&fd_g_config->cnf_main_ev), ); + + /* Destroy the local endpoints and applications */ + CHECK_FCT_DO(fd_ep_filter(&fd_g_config->cnf_endpoints, 0 ), ); + CHECK_FCT_DO(fd_app_empty(&fd_g_config->cnf_apps ), ); + + /* Destroy the local identity */ + free(fd_g_config->cnf_diamid); fd_g_config->cnf_diamid = NULL; + free(fd_g_config->cnf_diamrlm); fd_g_config->cnf_diamrlm = NULL; + + return 0; +} + + diff --git a/plat/diameter/libfdcore/core.c b/plat/diameter/libfdcore/core.c new file mode 100644 index 0000000..b46336a --- /dev/null +++ b/plat/diameter/libfdcore/core.c @@ -0,0 +1,403 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +GCC_DIAG_OFF("-Wdeprecated-declarations") +#include +GCC_DIAG_ON("-Wdeprecated-declarations") + +/* hash: session-id===>port id */ +GHashTable *g_sess_hash = NULL; + +/* The static configuration structure */ +static struct fd_config g_conf; +struct fd_config * fd_g_config = NULL; + +/* gcrypt functions to support posix threads */ +#ifndef GNUTLS_VERSION_210 +GCRY_THREAD_OPTION_PTHREAD_IMPL; +#endif /* GNUTLS_VERSION_210 */ + +/* Thread that process incoming events on the main queue -- and terminates the framework when requested */ +static pthread_t core_runner = (pthread_t)NULL; + +/* Signal extensions when the framework is completely initialized (they are waiting in fd_core_waitstartcomplete()) */ +static enum core_state { + CORE_NOT_INIT, /* initial state */ + CORE_LIBS_INIT, /* fd_core_initialize was called */ + CORE_CONF_READY,/* Configuration was parsed, extensions are loaded */ + CORE_RUNNING, /* Servers and clients are started, core_runner thread is running */ + CORE_SHUTDOWN, /* The framework is terminating all objects */ + CORE_TERM /* Shutdown complete. */ +} core_state = CORE_NOT_INIT; +static pthread_mutex_t core_mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t core_cnd = PTHREAD_COND_INITIALIZER; + +static enum core_state core_state_get(void) +{ + enum core_state cur_state; + CHECK_POSIX_DO( pthread_mutex_lock( &core_mtx ), ); + cur_state = core_state; + CHECK_POSIX_DO( pthread_mutex_unlock( &core_mtx ), ); + return cur_state; +} + +static void core_state_set(enum core_state newstate) +{ + CHECK_POSIX_DO( pthread_mutex_lock( &core_mtx ), ); + LOG_D("Core state: %d -> %d", core_state, newstate); + core_state = newstate; + CHECK_POSIX_DO( pthread_cond_broadcast( &core_cnd ), ); + CHECK_POSIX_DO( pthread_mutex_unlock( &core_mtx ), ); +} + +static int core_state_wait(enum core_state waitstate) +{ + int ret = 0; + CHECK_POSIX( pthread_mutex_lock( &core_mtx )); + pthread_cleanup_push( fd_cleanup_mutex, &core_mtx ); + while (waitstate > core_state) { + CHECK_POSIX_DO(ret = pthread_cond_wait(&core_cnd, &core_mtx), break); + } + pthread_cleanup_pop( 0 ); + CHECK_POSIX( pthread_mutex_unlock( &core_mtx )); + return ret; +} + +static void core_shutdown(void) +{ + LOG_N( FD_PROJECT_BINARY " framework is stopping..."); + fd_log_threadname("fD Core Shutdown"); + + /* cleanups */ + CHECK_FCT_DO( fd_servers_stop(), /* Stop accepting new connections */ ); + CHECK_FCT_DO( fd_rtdisp_cleanstop(), /* Stop dispatch thread(s) after a clean loop if possible */ ); + CHECK_FCT_DO( fd_peer_fini(), /* Stop all connections */ ); + CHECK_FCT_DO( fd_rtdisp_fini(), /* Stop routing threads and destroy routing queues */ ); + + CHECK_FCT_DO( fd_ext_term(), /* Cleanup all extensions */ ); + CHECK_FCT_DO( fd_rtdisp_cleanup(), /* destroy remaining handlers */ ); + + GNUTLS_TRACE( gnutls_global_deinit() ); + + CHECK_FCT_DO( fd_conf_deinit(), ); + + CHECK_FCT_DO( fd_event_trig_fini(), ); + + fd_log_debug(FD_PROJECT_BINARY " framework is terminated."); + + fd_libproto_fini(); + + g_hash_table_destroy(g_sess_hash); + +} + + +static void * core_runner_thread(void * arg) +{ + char cause[128]={"no cb"}; + + fd_log_threadname("fD Core Runner"); + + core_state_wait(CORE_RUNNING); + + /* Handle events incoming on the main event queue */ + while (1) { + int code; size_t sz; void * data; + CHECK_FCT_DO( fd_event_get(fd_g_config->cnf_main_ev, &code, &sz, &data), break ); + switch (code) { + case FDEV_TRIGGER: + { + int tv, *p; + CHECK_PARAMS_DO( sz == sizeof(int), + { + TRACE_DEBUG(NONE, "Internal error: got FDEV_TRIGGER without trigger value!"); + ASSERT(0); + sprintf(cause,"Internal error: got FDEV_TRIGGER without trigger value!"); + goto end; + } ); + p = data; + tv = *p; + free(p); + CHECK_FCT_DO( fd_event_trig_call_cb(tv), goto end ); + } + break; + + case FDEV_TERMINATE_INT: + sprintf(cause,"Internal error: got FDEV_TERMINATE_INT!"); + + goto end; + + default: + TRACE_DEBUG(INFO, "Unexpected event in the main event queue (%d), ignored.", code); + } + } + +end: + core_shutdown(); + if(1) + { + FILE *fp=NULL; + + fp = fopen("fd_cause.txt","w"); + if(fp) + { + fprintf(fp,"%s\r\n",cause); + fclose(fp); + } + exit(12); + } + return NULL; +} + +/*********************************/ +/* Public interfaces */ + +/* Initialize the libfdcore internals. This also initializes libfdproto */ +int fd_core_initialize(void) +{ + int ret; + + if (core_state_get() != CORE_NOT_INIT) { + fprintf(stderr, "fd_core_initialize() called more than once!\n"); + return EINVAL; + } + + /* Initialize the library -- must come first since it initializes the debug facility */ + ret = fd_libproto_init(); + if (ret != 0) { + fprintf(stderr, "Unable to initialize libfdproto: %s\n", strerror(ret)); + return ret; + } + + /* Name this thread */ + fd_log_threadname("Main"); + + LOG_N("libfdproto '%s' initialized.", fd_libproto_version); + + /* Initialize gcrypt and gnutls */ + #ifndef GNUTLS_VERSION_210 + GNUTLS_TRACE( (void) gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread) ); + GNUTLS_TRACE( (void) gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0) ); + #endif /* GNUTLS_VERSION_210 */ + CHECK_GNUTLS_DO( gnutls_global_init(), return EINVAL ); + if ( ! gnutls_check_version(GNUTLS_VERSION) ) { + TRACE_ERROR( "The GNUTLS library is too old; found '%s', need '" GNUTLS_VERSION "'", gnutls_check_version(NULL)); + return EINVAL; + } else { + #ifdef GNUTLS_VERSION_210 + TRACE_DEBUG(INFO, "libgnutls '%s' initialized.", gnutls_check_version(NULL) ); + #else /* GNUTLS_VERSION_210 */ + TRACE_DEBUG(INFO, "libgnutls '%s', libgcrypt '%s', initialized.", gnutls_check_version(NULL), gcry_check_version(NULL) ); + #endif /* GNUTLS_VERSION_210 */ + } + + /* Initialize the config with default values */ + memset(&g_conf, 0, sizeof(struct fd_config)); + fd_g_config = &g_conf; + CHECK_FCT( fd_conf_init() ); + + /* Add definitions of the base protocol */ + CHECK_FCT( fd_dict_base_protocol(fd_g_config->cnf_dict) ); + + /* Initialize some modules */ + CHECK_FCT( fd_hooks_init() ); + CHECK_FCT( fd_queues_init() ); + CHECK_FCT( fd_sess_start() ); + CHECK_FCT( fd_p_expi_init() ); + + core_state_set(CORE_LIBS_INIT); + + LOG_N("libfdcore '%s' initialized.", fd_core_version); + + + /* Next thing is to parse the config, leave this for a different function */ + return 0; +} + +static pthread_mutex_t core_lock = PTHREAD_MUTEX_INITIALIZER; + +/* Parse the freeDiameter.conf configuration file, load the extensions */ +static int fd_core_parseconf_int(const char * conffile) +{ + char * buf = NULL, *b; + size_t len = 0, offset=0; + + + TRACE_ENTRY("%p", conffile); + + /* Conf file */ + if (conffile) + fd_g_config->cnf_file = conffile; /* otherwise, we use the default name */ + + CHECK_FCT( fd_conf_parse() ); + + /* The following module use data from the configuration */ + CHECK_FCT( fd_rtdisp_init() ); + + /* Now, load all dynamic extensions */ + CHECK_FCT( fd_ext_load() ); + + /* Display configuration */ + b = fd_conf_dump(&buf, &len, NULL); + LOG_SPLIT(FD_LOG_NOTICE, NULL, b ?: "", NULL); + + /* Display extensions status */ + b = fd_ext_dump(&buf, &len, NULL); + LOG_SPLIT(FD_LOG_NOTICE, "Loaded extensions: ", b?:"", NULL); + + /* Display registered triggers for FDEV_TRIGGER */ + b = fd_event_trig_dump(&buf, &len, &offset); + if (!b || offset) { + LOG_N("%s", b ?: "Error during triggers dump..."); + } + + free(buf); + + /* Since some extensions might have modified the definitions from the dict_base_protocol, we only load the objects now */ + CHECK_FCT( fd_msg_init() ); + + /* Ok, ready for next step */ + core_state_set(CORE_CONF_READY); + + return 0; +} + +int fd_core_parseconf(const char * conffile) +{ + int ret; + CHECK_POSIX( pthread_mutex_lock(&core_lock) ); + ret = fd_core_parseconf_int(conffile); + CHECK_POSIX( pthread_mutex_unlock(&core_lock) ); + return ret; +} + + +/* For threads that would need to wait complete start of the framework (ex: in extensions) */ +int fd_core_waitstartcomplete(void) +{ + TRACE_ENTRY(""); + + return core_state_wait(CORE_RUNNING); +} + +/*static void free_key(gpointer data) +{ + //printf("We free key: %s /n", data); + free(data); +}*/ + +/* Start the server & client threads */ +static int fd_core_start_int(void) +{ + /* create hash: session id===>port id */ + g_sess_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); + + /* Start server threads */ + CHECK_FCT( fd_servers_start() ); + + /* Start the peer state machines */ + CHECK_FCT( fd_psm_start() ); + + /* Start the core runner thread that handles main events (until shutdown) */ + CHECK_POSIX( pthread_create(&core_runner, NULL, core_runner_thread, NULL) ); + + /* Unlock threads waiting into fd_core_waitstartcomplete */ + core_state_set(CORE_RUNNING); + + /* Ok, everything is running now... */ + return 0; +} + +int fd_core_start(void) +{ + int ret; + CHECK_POSIX( pthread_mutex_lock(&core_lock) ); + ret = fd_core_start_int(); + CHECK_POSIX( pthread_mutex_unlock(&core_lock) ); + return ret; +} + +/* Initialize shutdown of the framework. This is not blocking. */ +int fd_core_shutdown(void) +{ + enum core_state cur_state = core_state_get(); + + LOG_F("Initiating freeDiameter shutdown sequence (%d)", cur_state); + + if (cur_state < CORE_RUNNING) { + /* Calling application must make sure the initialization is not ongoing in a separate thread... */ + if (pthread_mutex_lock(&core_lock) != 0) { + /* This function must not be called asynchronously from fd_core_parseconf / fd_core_start ! Please review your main app design */ + ASSERT(0); + return EINVAL; + } + core_shutdown(); + core_state_set(CORE_TERM); + pthread_mutex_unlock(&core_lock); + } else if (cur_state == CORE_RUNNING) { + core_state_set(CORE_SHUTDOWN); + CHECK_FCT( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE_INT, 0, NULL) ); + } + + /* Other case, the framework is already shutting down */ + + return 0; +} + + +/* Wait for the shutdown to be complete -- this must be called after fd_core_shutdown to reclaim some resources. */ +int fd_core_wait_shutdown_complete(void) +{ + enum core_state cur_state = core_state_get(); + void * th_ret = NULL; + + CHECK_FCT(core_state_wait(CORE_SHUTDOWN)); + + if (cur_state == CORE_TERM) + return 0; + + /* Just wait for core_runner_thread to complete and return gracefully */ + CHECK_POSIX(pthread_join(core_runner, &th_ret)); + + core_state_set(CORE_TERM); + + return 0; +} + + + + diff --git a/plat/diameter/libfdcore/dict_base_proto.c b/plat/diameter/libfdcore/dict_base_proto.c new file mode 100644 index 0000000..f868edb --- /dev/null +++ b/plat/diameter/libfdcore/dict_base_proto.c @@ -0,0 +1,3355 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Diameter Base protocol definitions. + */ + +#include "fdcore-internal.h" + +#include +#include + +/* The pointer for the global dictionary (initialized from main) */ +struct dictionary * fd_g_dict = NULL; + + + +#define CHECK_dict_new( _type, _data, _parent, _ref ) \ + CHECK_FCT( fd_dict_new( dict, (_type), (_data), (_parent), (_ref)) ); + +#define CHECK_dict_search( _type, _criteria, _what, _result ) \ + CHECK_FCT( fd_dict_search( dict, (_type), (_criteria), (_what), (_result), ENOENT) ); + +struct local_rules_definition { + char *avp_name; + enum rule_position position; + int min; + int max; +}; + +#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 ) + +#define PARSE_loc_rules( _rulearray, _parent) { \ + int __ar; \ + for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \ + struct dict_rule_data __data = { NULL, \ + (_rulearray)[__ar].position, \ + 0, \ + (_rulearray)[__ar].min, \ + (_rulearray)[__ar].max}; \ + __data.rule_order = RULE_ORDER(__data.rule_position); \ + CHECK_FCT( fd_dict_search( \ + dict, \ + DICT_AVP, \ + AVP_BY_NAME, \ + (_rulearray)[__ar].avp_name, \ + &__data.rule_avp, 0 ) ); \ + if ( !__data.rule_avp ) { \ + TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \ + return ENOENT; \ + } \ + CHECK_FCT_DO( fd_dict_new( dict, DICT_RULE, &__data, _parent, NULL), \ + { \ + TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \ + (_rulearray)[__ar].avp_name ); \ + return EINVAL; \ + } ); \ + } \ +} + +int fd_dict_base_protocol(struct dictionary * dict) +{ + TRACE_ENTRY("%p", dict); + CHECK_PARAMS(dict); + + /* Vendors section */ + { + /* The base RFC has no vendor information */ + ; + } + + /* Applications section */ + { + /* base accounting application */ + { + struct dict_application_data data = { 3, "Diameter Base Accounting" }; + CHECK_dict_new( DICT_APPLICATION, &data, NULL, NULL); + } + + /* relay application */ + { + struct dict_application_data data = { 0xffffffff, "Relay" }; + #if AI_RELAY != 0xffffffff + #error "AI_RELAY definition mismatch" + #endif + CHECK_dict_new( DICT_APPLICATION, &data , NULL, NULL); + } + } + + /* Derived AVP types section */ + { + /* Address */ + { + /* + The Address format is derived from the OctetString AVP Base + Format. It is a discriminated union, representing, for example a + 32-bit (IPv4) [RFC791] or 128-bit (IPv6) [RFC4291] address, most + significant octet first. The first two octets of the Address AVP + represents the AddressType, which contains an Address Family + defined in [IANAADFAM]. The AddressType is used to discriminate + the content and format of the remaining octets. + */ + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "Address" , fd_dictfct_Address_interpret , fd_dictfct_Address_encode, fd_dictfct_Address_dump }; + CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); + } + + /* Time */ + { + /* + The Time format is derived from the OctetString AVP Base Format. + The string MUST contain four octets, in the same format as the + first four bytes are in the NTP timestamp format. The NTP + Timestamp format is defined in chapter 3 of [RFC4330]. + + This represents the number of seconds since 0h on 1 January 1900 + with respect to the Coordinated Universal Time (UTC). + + On 6h 28m 16s UTC, 7 February 2036 the time value will overflow. + SNTP [RFC4330] describes a procedure to extend the time to 2104. + This procedure MUST be supported by all DIAMETER nodes. + */ + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "Time" , fd_dictfct_Time_interpret , fd_dictfct_Time_encode, fd_dictfct_Time_dump }; + CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); + } + + /* UTF8String */ + { + /* + The UTF8String format is derived from the OctetString AVP Base + Format. This is a human readable string represented using the + ISO/IEC IS 10646-1 character set, encoded as an OctetString using + the UTF-8 [RFC3629] transformation format described in RFC 3629. + + Since additional code points are added by amendments to the 10646 + standard from time to time, implementations MUST be prepared to + encounter any code point from 0x00000001 to 0x7fffffff. Byte + sequences that do not correspond to the valid encoding of a code + point into UTF-8 charset or are outside this range are prohibited. + + The use of control codes SHOULD be avoided. When it is necessary + to represent a new line, the control code sequence CR LF SHOULD be + used. + + The use of leading or trailing white space SHOULD be avoided. + + For code points not directly supported by user interface hardware + or software, an alternative means of entry and display, such as + hexadecimal, MAY be provided. + + For information encoded in 7-bit US-ASCII, the UTF-8 charset is + identical to the US-ASCII charset. + + UTF-8 may require multiple bytes to represent a single character / + code point; thus the length of an UTF8String in octets may be + different from the number of characters encoded. + + Note that the AVP Length field of an UTF8String is measured in + octets, not characters. + */ + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "UTF8String" , NULL , NULL , fd_dictfct_UTF8String_dump }; + CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); + } + + /* DiameterIdentity */ + { + /* + The DiameterIdentity format is derived from the OctetString AVP + Base Format. + + DiameterIdentity = FQDN + + + DiameterIdentity value is used to uniquely identify a Diameter + node for purposes of duplicate connection and routing loop + detection. + + The contents of the string MUST be the FQDN of the Diameter node. + If multiple Diameter nodes run on the same host, each Diameter + node MUST be assigned a unique DiameterIdentity. If a Diameter + + node can be identified by several FQDNs, a single FQDN should be + picked at startup, and used as the only DiameterIdentity for that + node, whatever the connection it is sent on. Note that in this + document, DiameterIdentity is in ASCII form in order to be + compatible with existing DNS infrastructure. See Appendix D for + interactions between the Diameter protocol and Internationalized + Domain Name (IDNs). + */ + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "DiameterIdentity" , NULL , NULL , fd_dictfct_UTF8String_dump }; + CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); + } + + /* DiameterURI */ + { + /* + The DiameterURI MUST follow the Uniform Resource Identifiers (URI) + syntax [RFC3986] rules specified below: + + "aaa://" FQDN [ port ] [ transport ] [ protocol ] + + ; No transport security + + "aaas://" FQDN [ port ] [ transport ] [ protocol ] + + ; Transport security used + + FQDN = Fully Qualified Host Name + + port = ":" 1*DIGIT + + ; One of the ports used to listen for + ; incoming connections. + ; If absent, + ; the default Diameter port (3868) is + ; assumed. + + transport = ";transport=" transport-protocol + + ; One of the transports used to listen + ; for incoming connections. If absent, + ; the default SCTP [RFC2960] protocol is + ; assumed. UDP MUST NOT be used when + ; the aaa-protocol field is set to + ; diameter. + + transport-protocol = ( "tcp" / "sctp" / "udp" ) + + protocol = ";protocol=" aaa-protocol + + ; If absent, the default AAA protocol + ; is diameter. + + aaa-protocol = ( "diameter" / "radius" / "tacacs+" ) + + The following are examples of valid Diameter host identities: + + aaa://host.example.com;transport=tcp + aaa://host.example.com:6666;transport=tcp + aaa://host.example.com;protocol=diameter + aaa://host.example.com:6666;protocol=diameter + aaa://host.example.com:6666;transport=tcp;protocol=diameter + aaa://host.example.com:1813;transport=udp;protocol=radius + */ + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "DiameterURI" , NULL , NULL , fd_dictfct_UTF8String_dump }; + CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); + } + + /* Enumerated */ + { + /* + Enumerated is derived from the Integer32 AVP Base Format. The + definition contains a list of valid values and their + interpretation and is described in the Diameter application + introducing the AVP. + */ + + /* We don't use a generic "Enumerated" type in freeDiameter. Instead, we define + * types of the form "Enumerated()" where is replaced + * by the name of the AVP to which the type applies. + * Example: Enumerated(Disconnect-Cause) + */ + ; + } + + /* IPFilterRule */ + { + /* + The IPFilterRule format is derived from the OctetString AVP Base + Format and uses the ASCII charset. The rule syntax is a modified + subset of ipfw(8) from FreeBSD. Packets may be filtered based on + the following information that is associated with it: + + Direction (in or out) + Source and destination IP address (possibly masked) + Protocol + Source and destination port (lists or ranges) + TCP flags + IP fragment flag + IP options + ICMP types + + Rules for the appropriate direction are evaluated in order, with + the first matched rule terminating the evaluation. Each packet is + evaluated once. If no rule matches, the packet is dropped if the + last rule evaluated was a permit, and passed if the last rule was + a deny. + + IPFilterRule filters MUST follow the format: + + action dir proto from src to dst [options] + + (...skipped loooong explanation...) + + There is one kind of packet that the access device MUST always + discard, that is an IP fragment with a fragment offset of one. + This is a valid packet, but it only has one use, to try to + circumvent firewalls. + + An access device that is unable to interpret or apply a deny rule + MUST terminate the session. An access device that is unable to + interpret or apply a permit rule MAY apply a more restrictive + rule. An access device MAY apply deny rules of its own before the + supplied rules, for example to protect the access device owner's + infrastructure. + */ + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "IPFilterRule" , NULL , NULL , fd_dictfct_UTF8String_dump }; + CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); + } + } + + /* AVP section */ + { + struct dict_object * Address_type; + struct dict_object * UTF8String_type; + struct dict_object * DiameterIdentity_type; + struct dict_object * DiameterURI_type; + struct dict_object * Time_type; + + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type); + CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type); + + /* Vendor-Id */ + { + /* + The Vendor-Id AVP (AVP Code 266) is of type Unsigned32 and contains + the IANA "SMI Network Management Private Enterprise Codes" [RFC3232] + value assigned to the vendor of the Diameter device. It is + envisioned that the combination of the Vendor-Id, Product-Name + (Section 5.3.7) and the Firmware-Revision (Section 5.3.4) AVPs may + provide useful debugging information. + + A Vendor-Id value of zero in the CER or CEA messages is reserved and + indicates that this field is ignored. + */ + struct dict_avp_data data = { + 266, /* Code */ + #if AC_VENDOR_ID != 266 + #error "AC_VENDOR_ID definition mismatch" + #endif + 0, /* Vendor */ + "Vendor-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data, NULL, NULL); + } + + /* Firmware-Revision */ + { + /* + The Firmware-Revision AVP (AVP Code 267) is of type Unsigned32 and is + used to inform a Diameter peer of the firmware revision of the + issuing device. + + For devices that do not have a firmware revision (general purpose + computers running Diameter software modules, for instance), the + revision of the Diameter software module may be reported instead. + */ + struct dict_avp_data data = { + 267, /* Code */ + #if AC_FIRMWARE_REVISION != 267 + #error "AC_FIRMWARE_REVISION definition mismatch" + #endif + 0, /* Vendor */ + "Firmware-Revision", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + 0, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Host-IP-Address */ + { + /* + The Host-IP-Address AVP (AVP Code 257) is of type Address and is used + to inform a Diameter peer of the sender's IP address. All source + addresses that a Diameter node expects to use with SCTP [RFC2960] + MUST be advertised in the CER and CEA messages by including a + Host-IP- Address AVP for each address. This AVP MUST ONLY be used in + the CER and CEA messages. + */ + struct dict_avp_data data = { + 257, /* Code */ + #if AC_HOST_IP_ADDRESS != 257 + #error "AC_HOST_IP_ADDRESS definition mismatch" + #endif + 0, /* Vendor */ + "Host-IP-Address", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , Address_type, NULL); + } + + /* Supported-Vendor-Id */ + { + /* + The Supported-Vendor-Id AVP (AVP Code 265) is of type Unsigned32 and + contains the IANA "SMI Network Management Private Enterprise Codes" + [RFC3232] value assigned to a vendor other than the device vendor but + including the application vendor. This is used in the CER and CEA + messages in order to inform the peer that the sender supports (a + subset of) the vendor-specific AVPs defined by the vendor identified + in this AVP. The value of this AVP SHOULD NOT be set to zero. + Multiple instances of this AVP containing the same value SHOULD NOT + be sent. + */ + struct dict_avp_data data = { + 265, /* Code */ + #if AC_SUPPORTED_VENDOR_ID != 265 + #error "AC_SUPPORTED_VENDOR_ID definition mismatch" + #endif + 0, /* Vendor */ + "Supported-Vendor-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Product-Name */ + { + /* + The Product-Name AVP (AVP Code 269) is of type UTF8String, and + contains the vendor assigned name for the product. The Product-Name + AVP SHOULD remain constant across firmware revisions for the same + product. + */ + struct dict_avp_data data = { + 269, /* Code */ + #if AC_PRODUCT_NAME != 269 + #error "AC_PRODUCT_NAME definition mismatch" + #endif + 0, /* Vendor */ + "Product-Name", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + 0, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Disconnect-Cause */ + { + /* + The Disconnect-Cause AVP (AVP Code 273) is of type Enumerated. A + Diameter node MUST include this AVP in the Disconnect-Peer-Request + message to inform the peer of the reason for its intention to + shutdown the transport connection. The following values are + supported: + + REBOOTING 0 + A scheduled reboot is imminent. Receiver of DPR with above result + code MAY attempt reconnection. + + BUSY 1 + The peer's internal resources are constrained, and it has + determined that the transport connection needs to be closed. + Receiver of DPR with above result code SHOULD NOT attempt + reconnection. + + DO_NOT_WANT_TO_TALK_TO_YOU 2 + The peer has determined that it does not see a need for the + transport connection to exist, since it does not expect any + messages to be exchanged in the near future. Receiver of DPR + with above result code SHOULD NOT attempt reconnection. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Disconnect-Cause)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "REBOOTING", { .i32 = 0 }}; + struct dict_enumval_data t_1 = { "BUSY", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "DO_NOT_WANT_TO_TALK_TO_YOU", { .i32 = 2 }}; + struct dict_avp_data data = { + 273, /* Code */ + #if AC_DISCONNECT_CAUSE != 273 + #error "AC_DISCONNECT_CAUSE definition mismatch" + #endif + 0, /* Vendor */ + "Disconnect-Cause", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Origin-Host */ + { + /* + The Origin-Host AVP (AVP Code 264) is of type DiameterIdentity, and + MUST be present in all Diameter messages. This AVP identifies the + endpoint that originated the Diameter message. Relay agents MUST NOT + modify this AVP. + + The value of the Origin-Host AVP is guaranteed to be unique within a + single host. + + Note that the Origin-Host AVP may resolve to more than one address as + the Diameter peer may support more than one address. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 264, /* Code */ + #if AC_ORIGIN_HOST != 264 + #error "AC_ORIGIN_HOST definition mismatch" + #endif + 0, /* Vendor */ + "Origin-Host", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Origin-Realm */ + { + /* + The Origin-Realm AVP (AVP Code 296) is of type DiameterIdentity. + This AVP contains the Realm of the originator of any Diameter message + and MUST be present in all messages. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 296, /* Code */ + #if AC_ORIGIN_REALM != 296 + #error "AC_ORIGIN_REALM definition mismatch" + #endif + 0, /* Vendor */ + "Origin-Realm", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Destination-Host */ + { + /* + The Destination-Host AVP (AVP Code 293) is of type DiameterIdentity. + This AVP MUST be present in all unsolicited agent initiated messages, + MAY be present in request messages, and MUST NOT be present in Answer + messages. + + The absence of the Destination-Host AVP will cause a message to be + sent to any Diameter server supporting the application within the + realm specified in Destination-Realm AVP. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 293, /* Code */ + #if AC_DESTINATION_HOST != 293 + #error "AC_DESTINATION_HOST definition mismatch" + #endif + 0, /* Vendor */ + "Destination-Host", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Destination-Realm */ + { + /* + The Destination-Realm AVP (AVP Code 283) is of type DiameterIdentity, + and contains the realm the message is to be routed to. The + Destination-Realm AVP MUST NOT be present in Answer messages. + Diameter Clients insert the realm portion of the User-Name AVP. + Diameter servers initiating a request message use the value of the + Origin-Realm AVP from a previous message received from the intended + target host (unless it is known a priori). When present, the + Destination-Realm AVP is used to perform message routing decisions. + + Request messages whose ABNF does not list the Destination-Realm AVP + as a mandatory AVP are inherently non-routable messages. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + */ + struct dict_avp_data data = { + 283, /* Code */ + #if AC_DESTINATION_REALM != 283 + #error "AC_DESTINATION_REALM definition mismatch" + #endif + 0, /* Vendor */ + "Destination-Realm", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Route-Record */ + { + /* + The Route-Record AVP (AVP Code 282) is of type DiameterIdentity. The + identity added in this AVP MUST be the same as the one received in + the Origin-Host of the Capabilities Exchange message. + */ + struct dict_avp_data data = { + 282, /* Code */ + #if AC_ROUTE_RECORD != 282 + #error "AC_ROUTE_RECORD definition mismatch" + #endif + 0, /* Vendor */ + "Route-Record", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Proxy-Host */ + { + /* + The Proxy-Host AVP (AVP Code 280) is of type DiameterIdentity. This + AVP contains the identity of the host that added the Proxy-Info AVP. + */ + struct dict_avp_data adata = { + 280, /* Code */ + #if AC_PROXY_HOST != 280 + #error "AC_PROXY_HOST definition mismatch" + #endif + 0, /* Vendor */ + "Proxy-Host", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &adata , DiameterIdentity_type, NULL); + } + + /* Proxy-State */ + { + /* + The Proxy-State AVP (AVP Code 33) is of type OctetString, and + contains state local information, and MUST be treated as opaque data. + */ + struct dict_avp_data adata = { + 33, /* Code */ + #if AC_PROXY_STATE != 33 + #error "AC_PROXY_STATE definition mismatch" + #endif + 0, /* Vendor */ + "Proxy-State", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &adata , NULL, NULL); + } + + /* Proxy-Info */ + { + /* + The Proxy-Info AVP (AVP Code 284) is of type Grouped. The Grouped + Data field has the following ABNF grammar: + + Proxy-Info ::= < AVP Header: 284 > + { Proxy-Host } + { Proxy-State } + * [ AVP ] + */ + struct dict_object * avp; + struct dict_avp_data data = { + 284, /* Code */ + #if AC_PROXY_INFO != 284 + #error "AC_PROXY_INFO definition mismatch" + #endif + 0, /* Vendor */ + "Proxy-Info", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + struct local_rules_definition rules[] = + { { "Proxy-Host", RULE_REQUIRED, -1, 1 } + ,{ "Proxy-State", RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules( rules, avp ); + } + + /* Auth-Application-Id */ + { + /* + The Auth-Application-Id AVP (AVP Code 258) is of type Unsigned32 and + is used in order to advertise support of the Authentication and + Authorization portion of an application (see Section 2.4). If + present in a message other than CER and CEA, the value of the Auth- + Application-Id AVP MUST match the Application Id present in the + Diameter message header. + */ + struct dict_avp_data data = { + 258, /* Code */ + #if AC_AUTH_APPLICATION_ID != 258 + #error "AC_AUTH_APPLICATION_ID definition mismatch" + #endif + 0, /* Vendor */ + "Auth-Application-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Acct-Application-Id */ + { + /* + The Acct-Application-Id AVP (AVP Code 259) is of type Unsigned32 and + is used in order to advertise support of the Accounting portion of an + application (see Section 2.4). If present in a message other than + CER and CEA, the value of the Acct-Application-Id AVP MUST match the + Application Id present in the Diameter message header. + */ + struct dict_avp_data data = { + 259, /* Code */ + #if AC_ACCT_APPLICATION_ID != 259 + #error "AC_ACCT_APPLICATION_ID definition mismatch" + #endif + 0, /* Vendor */ + "Acct-Application-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Inband-Security-Id */ + { + /* + The Inband-Security-Id AVP (AVP Code 299) is of type Unsigned32 and + is used in order to advertise support of the Security portion of the + application. + + Currently, the following values are supported, but there is ample + room to add new security Ids. + + + NO_INBAND_SECURITY 0 + + This peer does not support TLS. This is the default value, if the + AVP is omitted. + + TLS 1 + + This node supports TLS security, as defined by [RFC4346]. + */ + + /* Although the RFC does not specify an "Enumerated" type here, we go forward and create one. + * This is the reason for the "*" in the type name + */ + + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Inband-Security-Id)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "NO_INBAND_SECURITY", { .u32 = ACV_ISI_NO_INBAND_SECURITY }}; + struct dict_enumval_data t_1 = { "TLS", { .u32 = ACV_ISI_TLS }}; + struct dict_avp_data data = { + 299, /* Code */ + #if AC_INBAND_SECURITY_ID != 299 + #error "AC_INBAND_SECURITY_ID definition mismatch" + #endif + 0, /* Vendor */ + "Inband-Security-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Vendor-Specific-Application-Id */ + { + /* + The Vendor-Specific-Application-Id AVP (AVP Code 260) is of type + Grouped and is used to advertise support of a vendor-specific + Diameter Application. Exactly one instance of either Auth- + Application-Id or Acct-Application-Id AVP MUST be present. The + Application Id carried by either Auth-Application-Id or Acct- + Application-Id AVP MUST comply with vendor specific Application Id + assignment described in Sec 11.3. It MUST also match the Application + Id present in the diameter header except when used in a CER or CEA + messages. + + The Vendor-Id AVP is an informational AVP pertaining to the vendor + who may have authorship of the vendor-specific Diameter application. + It MUST NOT be used as a means of defining a completely separate + vendor-specific Application Id space. + + This AVP MUST also be present as the first AVP in all experimental + commands defined in the vendor-specific application. + + This AVP SHOULD be placed as close to the Diameter header as + possible. + + AVP Format + + ::= < AVP Header: 260 > + { Vendor-Id } + [ Auth-Application-Id ] + [ Acct-Application-Id ] + + A Vendor-Specific-Application-Id AVP MUST contain exactly one of + either Auth-Application-Id or Acct-Application-Id. If a Vendor- + Specific-Application-Id is received without any of these two AVPs, + then the recipient SHOULD issue an answer with a Result-Code set to + DIAMETER_MISSING_AVP. The answer SHOULD also include a Failed-AVP + which MUST contain an example of an Auth-Application-Id AVP and an + Acct-Application-Id AVP. + + If a Vendor-Specific-Application-Id is received that contains both + Auth-Application-Id and Acct-Application-Id, then the recipient + SHOULD issue an answer with Result-Code set to + DIAMETER_AVP_OCCURS_TOO_MANY_TIMES. The answer SHOULD also include a + Failed-AVP which MUST contain the received Auth-Application-Id AVP + and Acct-Application-Id AVP. + */ + struct dict_object * avp; + struct dict_avp_data data = { + 260, /* Code */ + #if AC_VENDOR_SPECIFIC_APPLICATION_ID != 260 + #error "AC_VENDOR_SPECIFIC_APPLICATION_ID definition mismatch" + #endif + 0, /* Vendor */ + "Vendor-Specific-Application-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + + struct local_rules_definition rules[] = + { +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + /* ABNF from RFC6733 */ + { "Vendor-Id", RULE_REQUIRED, -1, 1 } +#else /* WORKAROUND_ACCEPT_INVALID_VSAI */ + /* ABNF from RFC3588 (including erratum, because original text is nonsense) */ + { "Vendor-Id", RULE_REQUIRED, -1, -1} +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + ,{ "Auth-Application-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Application-Id", RULE_OPTIONAL, -1, 1 } + }; + + /* Create the grouped AVP */ + CHECK_dict_new( DICT_AVP, &data , NULL, &avp); + PARSE_loc_rules( rules, avp ); + + } + + /* Redirect-Host */ + { + /* + One or more of instances of this AVP MUST be present if the answer + message's 'E' bit is set and the Result-Code AVP is set to + DIAMETER_REDIRECT_INDICATION. + + Upon receiving the above, the receiving Diameter node SHOULD forward + the request directly to one of the hosts identified in these AVPs. + The server contained in the selected Redirect-Host AVP SHOULD be used + for all messages pertaining to this session. + */ + struct dict_avp_data data = { + 292, /* Code */ + #if AC_REDIRECT_HOST != 292 + #error "AC_REDIRECT_HOST definition mismatch" + #endif + 0, /* Vendor */ + "Redirect-Host", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterURI_type, NULL); + } + + /* Redirect-Host-Usage */ + { + /* + The Redirect-Host-Usage AVP (AVP Code 261) is of type Enumerated. + This AVP MAY be present in answer messages whose 'E' bit is set and + the Result-Code AVP is set to DIAMETER_REDIRECT_INDICATION. + + When present, this AVP dictates how the routing entry resulting from + the Redirect-Host is to be used. The following values are supported: + + + DONT_CACHE 0 + + The host specified in the Redirect-Host AVP should not be cached. + This is the default value. + + + ALL_SESSION 1 + + All messages within the same session, as defined by the same value + of the Session-ID AVP MAY be sent to the host specified in the + Redirect-Host AVP. + + + ALL_REALM 2 + + All messages destined for the realm requested MAY be sent to the + host specified in the Redirect-Host AVP. + + + REALM_AND_APPLICATION 3 + + All messages for the application requested to the realm specified + MAY be sent to the host specified in the Redirect-Host AVP. + + ALL_APPLICATION 4 + + All messages for the application requested MAY be sent to the host + specified in the Redirect-Host AVP. + + + ALL_HOST 5 + + All messages that would be sent to the host that generated the + Redirect-Host MAY be sent to the host specified in the Redirect- + Host AVP. + + + ALL_USER 6 + + All messages for the user requested MAY be sent to the host + specified in the Redirect-Host AVP. + + + When multiple cached routes are created by redirect indications and + they differ only in redirect usage and peers to forward requests to + (see Section 6.1.8), a precedence rule MUST be applied to the + redirect usage values of the cached routes during normal routing to + resolve contentions that may occur. The precedence rule is the order + that dictate which redirect usage should be considered before any + other as they appear. The order is as follows: + + + 1. ALL_SESSION + + 2. ALL_USER + + 3. REALM_AND_APPLICATION + + 4. ALL_REALM + + 5. ALL_APPLICATION + + 6. ALL_HOST + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Redirect-Host-Usage)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "DONT_CACHE", { .i32 = 0 }}; + struct dict_enumval_data t_1 = { "ALL_SESSION", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "ALL_REALM", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "REALM_AND_APPLICATION", { .i32 = 3 }}; + struct dict_enumval_data t_4 = { "ALL_APPLICATION", { .i32 = 4 }}; + struct dict_enumval_data t_5 = { "ALL_HOST", { .i32 = 5 }}; + struct dict_enumval_data t_6 = { "ALL_USER", { .i32 = 6 }}; + struct dict_avp_data data = { + 261, /* Code */ + #if AC_REDIRECT_HOST_USAGE != 261 + #error "AC_REDIRECT_HOST_USAGE definition mismatch" + #endif + 0, /* Vendor */ + "Redirect-Host-Usage", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_5 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_6 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Redirect-Max-Cache-Time */ + { + /* + The Redirect-Max-Cache-Time AVP (AVP Code 262) is of type Unsigned32. + This AVP MUST be present in answer messages whose 'E' bit is set, the + Result-Code AVP is set to DIAMETER_REDIRECT_INDICATION and the + Redirect-Host-Usage AVP set to a non-zero value. + + This AVP contains the maximum number of seconds the peer and route + table entries, created as a result of the Redirect-Host, will be + cached. Note that once a host created due to a redirect indication + is no longer reachable, any associated peer and routing table entries + MUST be deleted. + */ + struct dict_avp_data data = { + 262, /* Code */ + #if AC_REDIRECT_MAX_CACHE_TIME != 262 + #error "AC_REDIRECT_MAX_CACHE_TIME definition mismatch" + #endif + 0, /* Vendor */ + "Redirect-Max-Cache-Time", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Result-Code */ + { + /* + The Result-Code AVP (AVP Code 268) is of type Unsigned32 and + indicates whether a particular request was completed successfully or + whether an error occurred. All Diameter answer messages defined in + IETF applications MUST include one Result-Code AVP. A non-successful + Result-Code AVP (one containing a non 2xxx value other than + DIAMETER_REDIRECT_INDICATION) MUST include the Error-Reporting-Host + AVP if the host setting the Result-Code AVP is different from the + identity encoded in the Origin-Host AVP. + + The Result-Code data field contains an IANA-managed 32-bit address + space representing errors (see Section 11.4). Diameter provides the + following classes of errors, all identified by the thousands digit in + the decimal notation: + + o 1xxx (Informational) + + o 2xxx (Success) + + o 3xxx (Protocol Errors) + + o 4xxx (Transient Failures) + + o 5xxx (Permanent Failure) + + A non-recognized class (one whose first digit is not defined in this + section) MUST be handled as a permanent failure. + */ + + /* Although the RFC does not specify an "Enumerated" type here, we go forward and create one. + * This is the reason for the "*" in the type name + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Result-Code)" , NULL, NULL, NULL }; + struct dict_avp_data data = { + 268, /* Code */ + #if AC_RESULT_CODE != 268 + #error "AC_RESULT_CODE definition mismatch" + #endif + 0, /* Vendor */ + "Result-Code", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + + /* Informational */ + { + /* 1001 */ + { + /* + This informational error is returned by a Diameter server to + inform the access device that the authentication mechanism being + used requires multiple round trips, and a subsequent request needs + to be issued in order for access to be granted. + */ + struct dict_enumval_data error_code = { "DIAMETER_MULTI_ROUND_AUTH", { .u32 = ER_DIAMETER_MULTI_ROUND_AUTH }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Success */ + { + /* 2001 */ + { + /* + The Request was successfully completed. + */ + struct dict_enumval_data error_code = { "DIAMETER_SUCCESS", { .u32 = ER_DIAMETER_SUCCESS }}; + #if ER_DIAMETER_SUCCESS != 2001 + #error "ER_DIAMETER_SUCCESS definition mismatch" + #endif + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 2002 */ + { + /* + When returned, the request was successfully completed, but + additional processing is required by the application in order to + provide service to the user. + */ + struct dict_enumval_data error_code = { "DIAMETER_LIMITED_SUCCESS", { .u32 = ER_DIAMETER_LIMITED_SUCCESS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Protocol Errors */ + { + /* 3001 -- might be changed to 5xxx soon */ + { + /* + The Request contained a Command-Code that the receiver did not + recognize or support. This MUST be used when a Diameter node + receives an experimental command that it does not understand. + */ + struct dict_enumval_data error_code = { "DIAMETER_COMMAND_UNSUPPORTED", { .u32 = ER_DIAMETER_COMMAND_UNSUPPORTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3002 */ + { + /* + This error is given when Diameter can not deliver the message to + the destination, either because no host within the realm + supporting the required application was available to process the + request, or because Destination-Host AVP was given without the + associated Destination-Realm AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNABLE_TO_DELIVER", { .u32 = ER_DIAMETER_UNABLE_TO_DELIVER }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3003 */ + { + /* + The intended realm of the request is not recognized. + */ + struct dict_enumval_data error_code = { "DIAMETER_REALM_NOT_SERVED", { .u32 = ER_DIAMETER_REALM_NOT_SERVED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3004 */ + { + /* + When returned, a Diameter node SHOULD attempt to send the message + to an alternate peer. This error MUST only be used when a + specific server is requested, and it cannot provide the requested + service. + */ + struct dict_enumval_data error_code = { "DIAMETER_TOO_BUSY", { .u32 = ER_DIAMETER_TOO_BUSY }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3005 */ + { + /* + An agent detected a loop while trying to get the message to the + intended recipient. The message MAY be sent to an alternate peer, + if one is available, but the peer reporting the error has + identified a configuration problem. + */ + struct dict_enumval_data error_code = { "DIAMETER_LOOP_DETECTED", { .u32 = ER_DIAMETER_LOOP_DETECTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3006 */ + { + /* + A redirect agent has determined that the request could not be + satisfied locally and the initiator of the request should direct + the request directly to the server, whose contact information has + been added to the response. When set, the Redirect-Host AVP MUST + be present. + */ + struct dict_enumval_data error_code = { "DIAMETER_REDIRECT_INDICATION", { .u32 = ER_DIAMETER_REDIRECT_INDICATION }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3007 */ + { + /* + A request was sent for an application that is not supported. + */ + struct dict_enumval_data error_code = { "DIAMETER_APPLICATION_UNSUPPORTED", { .u32 = ER_DIAMETER_APPLICATION_UNSUPPORTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3008 -- will change to 5xxx soon */ + { + /* + A request was received whose bits in the Diameter header were + either set to an invalid combination, or to a value that is + inconsistent with the command code's definition. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_HDR_BITS", { .u32 = ER_DIAMETER_INVALID_HDR_BITS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3009 -- will change to 5xxx soon */ + { + /* + A request was received that included an AVP whose flag bits are + set to an unrecognized value, or that is inconsistent with the + AVP's definition. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_BITS", { .u32 = ER_DIAMETER_INVALID_AVP_BITS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 3010 -- will change to 5xxx soon */ + { + /* + A CER was received from an unknown peer. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNKNOWN_PEER", { .u32 = ER_DIAMETER_UNKNOWN_PEER }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Transient Failures */ + { + /* 4001 */ + { + /* + The authentication process for the user failed, most likely due to + an invalid password used by the user. Further attempts MUST only + be tried after prompting the user for a new password. + */ + struct dict_enumval_data error_code = { "DIAMETER_AUTHENTICATION_REJECTED", { .u32 = ER_DIAMETER_AUTHENTICATION_REJECTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 4002 */ + { + /* + A Diameter node received the accounting request but was unable to + commit it to stable storage due to a temporary lack of space. + */ + struct dict_enumval_data error_code = { "DIAMETER_OUT_OF_SPACE", { .u32 = ER_DIAMETER_OUT_OF_SPACE }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 4003 */ + { + /* + The peer has determined that it has lost the election process and + has therefore disconnected the transport connection. + */ + struct dict_enumval_data error_code = { "ELECTION_LOST", { .u32 = ER_ELECTION_LOST }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + } + /* Permanent Failures */ + { + /* 5001 */ + { + /* + The peer received a message that contained an AVP that is not + recognized or supported and was marked with the Mandatory bit. A + Diameter message with this error MUST contain one or more Failed- + AVP AVP containing the AVPs that caused the failure. + */ + struct dict_enumval_data error_code = { "DIAMETER_AVP_UNSUPPORTED", { .u32 = ER_DIAMETER_AVP_UNSUPPORTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5002 */ + { + /* + The request contained an unknown Session-Id. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNKNOWN_SESSION_ID", { .u32 = ER_DIAMETER_UNKNOWN_SESSION_ID }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5003 */ + { + /* + A request was received for which the user could not be authorized. + This error could occur if the service requested is not permitted + to the user. + */ + struct dict_enumval_data error_code = { "DIAMETER_AUTHORIZATION_REJECTED",{ .u32 = ER_DIAMETER_AUTHORIZATION_REJECTED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5004 */ + { + /* + The request contained an AVP with an invalid value in its data + portion. A Diameter message indicating this error MUST include + the offending AVPs within a Failed-AVP AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_VALUE", { .u32 = ER_DIAMETER_INVALID_AVP_VALUE }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5005 */ + { + /* + The request did not contain an AVP that is required by the Command + Code definition. If this value is sent in the Result-Code AVP, a + Failed-AVP AVP SHOULD be included in the message. The Failed-AVP + AVP MUST contain an example of the missing AVP complete with the + Vendor-Id if applicable. The value field of the missing AVP + should be of correct minimum length and contain zeroes. + */ + struct dict_enumval_data error_code = { "DIAMETER_MISSING_AVP", { .u32 = ER_DIAMETER_MISSING_AVP }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5006 */ + { + /* + A request was received that cannot be authorized because the user + has already expended allowed resources. An example of this error + condition is a user that is restricted to one dial-up PPP port, + attempts to establish a second PPP connection. + */ + struct dict_enumval_data error_code = { "DIAMETER_RESOURCES_EXCEEDED", { .u32 = ER_DIAMETER_RESOURCES_EXCEEDED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5007 */ + { + /* + The Home Diameter server has detected AVPs in the request that + contradicted each other, and is not willing to provide service to + the user. The Failed-AVP AVPs MUST be present which contains the + AVPs that contradicted each other. + */ + struct dict_enumval_data error_code = { "DIAMETER_CONTRADICTING_AVPS", { .u32 = ER_DIAMETER_CONTRADICTING_AVPS }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5008 */ + { + /* + A message was received with an AVP that MUST NOT be present. The + Failed-AVP AVP MUST be included and contain a copy of the + offending AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_AVP_NOT_ALLOWED", { .u32 = ER_DIAMETER_AVP_NOT_ALLOWED }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5009 */ + { + /* + A message was received that included an AVP that appeared more + often than permitted in the message definition. The Failed-AVP + AVP MUST be included and contain a copy of the first instance of + the offending AVP that exceeded the maximum number of occurrences + */ + struct dict_enumval_data error_code = { "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES",{ .u32 = ER_DIAMETER_AVP_OCCURS_TOO_MANY_TIMES }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5010 */ + { + /* + This error is returned by a Diameter node that is not acting as a + relay when it receives a CER which advertises a set of + applications that it does not support. + */ + struct dict_enumval_data error_code = { "DIAMETER_NO_COMMON_APPLICATION",{ .u32 = ER_DIAMETER_NO_COMMON_APPLICATION }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5011 */ + { + /* + This error is returned when a request was received, whose version + number is unsupported. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNSUPPORTED_VERSION", { .u32 = ER_DIAMETER_UNSUPPORTED_VERSION }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5012 */ + { + /* + This error is returned when a request is rejected for unspecified + reasons. + */ + struct dict_enumval_data error_code = { "DIAMETER_UNABLE_TO_COMPLY", { .u32 = ER_DIAMETER_UNABLE_TO_COMPLY }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5013 -- will change to 3xxx */ + { + /* + This error is returned when an unrecognized bit in the Diameter + header is set to one (1). + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_BIT_IN_HEADER", { .u32 = ER_DIAMETER_INVALID_BIT_IN_HEADER }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5014 */ + { + /* + The request contained an AVP with an invalid length. A Diameter + message indicating this error MUST include the offending AVPs + within a Failed-AVP AVP. In cases where the erroneous avp length + value exceeds the message length or is less than the minimum AVP + header length, it is sufficient to include the offending AVP + header and a zero filled payload of the minimum required length + for the payloads data type. If the AVP is a grouped AVP, the + grouped AVP header with an empty payload would be sufficient to + indicate the offending AVP. In the case where the offending AVP + header cannot be fully decoded when avp length is less than the + minimum AVP header length, it is sufficient to include an + offending AVP header that is formulated by padding the incomplete + AVP header with zero up to the minimum AVP header length. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_LENGTH", { .u32 = ER_DIAMETER_INVALID_AVP_LENGTH }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5015 -- will change to 3xxx */ + { + /* + This error is returned when a request is received with an invalid + message length. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_MESSAGE_LENGTH", { .u32 = ER_DIAMETER_INVALID_MESSAGE_LENGTH }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5016 */ + { + /* + The request contained an AVP with which is not allowed to have the + given value in the AVP Flags field. A Diameter message indicating + this error MUST include the offending AVPs within a Failed-AVP + AVP. + */ + struct dict_enumval_data error_code = { "DIAMETER_INVALID_AVP_BIT_COMBO", { .u32 = ER_DIAMETER_INVALID_AVP_BIT_COMBO }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5017 */ + { + /* + This error is returned when a CER message is received, and there + are no common security mechanisms supported between the peers. A + Capabilities-Exchange-Answer (CEA) MUST be returned with the + Result-Code AVP set to DIAMETER_NO_COMMON_SECURITY. + */ + struct dict_enumval_data error_code = { "DIAMETER_NO_COMMON_SECURITY", { .u32 = ER_DIAMETER_NO_COMMON_SECURITY }}; + CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + } + /* 5030 */ + //{ + /* + The specified end user is unknown in the credit-control server. + */ + // struct dict_enumval_data error_code = { "DIAMETER_USER_UNKNOWN", { .u32 = ER_DIAMETER_USER_UNKNOWN }}; + // CHECK_dict_new( DICT_ENUMVAL, &error_code , type, NULL); + //} + } + } + + /* Error-Message */ + { + /* + The Error-Message AVP (AVP Code 281) is of type UTF8String. It MAY + accompany a Result-Code AVP as a human readable error message. The + Error-Message AVP is not intended to be useful in real-time, and + SHOULD NOT be expected to be parsed by network entities. + */ + struct dict_avp_data data = { + 281, /* Code */ + #if AC_ERROR_MESSAGE != 281 + #error "AC_ERROR_MESSAGE definition mismatch" + #endif + 0, /* Vendor */ + "Error-Message", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + 0, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Error-Reporting-Host */ + { + /* + The Error-Reporting-Host AVP (AVP Code 294) is of type + DiameterIdentity. This AVP contains the identity of the Diameter + host that sent the Result-Code AVP to a value other than 2001 + (Success), only if the host setting the Result-Code is different from + the one encoded in the Origin-Host AVP. This AVP is intended to be + used for troubleshooting purposes, and MUST be set when the Result- + Code AVP indicates a failure. + */ + struct dict_avp_data data = { + 294, /* Code */ + #if AC_ERROR_REPORTING_HOST != 294 + #error "AC_ERROR_REPORTING_HOST definition mismatch" + #endif + 0, /* Vendor */ + "Error-Reporting-Host", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + 0, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , DiameterIdentity_type, NULL); + } + + /* Failed-AVP */ + { + /* + The Failed-AVP AVP (AVP Code 279) is of type Grouped and provides + debugging information in cases where a request is rejected or not + fully processed due to erroneous information in a specific AVP. The + value of the Result-Code AVP will provide information on the reason + for the Failed-AVP AVP. A Diameter message SHOULD contain only one + Failed-AVP that corresponds to the error indicated by the Result-Code + AVP. For practical purposes, this Failed-AVP would typically refer + to the first AVP processing error that a Diameter node encounters. + + The possible reasons for this AVP are the presence of an improperly + constructed AVP, an unsupported or unrecognized AVP, an invalid AVP + value, the omission of a required AVP, the presence of an explicitly + excluded AVP (see tables in Section 10), or the presence of two or + more occurrences of an AVP which is restricted to 0, 1, or 0-1 + occurrences. + + A Diameter message SHOULD contain one Failed-AVP AVP, containing the + entire AVP that could not be processed successfully. If the failure + reason is omission of a required AVP, an AVP with the missing AVP + code, the missing vendor id, and a zero filled payload of the minimum + required length for the omitted AVP will be added. If the failure + reason is an invalid AVP length where the reported length is less + than the minimum AVP header length or greater than the reported + message length, a copy of the offending AVP header and a zero filled + payload of the minimum required length SHOULD be added. + + In the case where the offending AVP is embedded within a grouped AVP, + the Failed-AVP MAY contain the grouped AVP which in turn contains the + single offending AVP. The same method MAY be employed if the grouped + AVP itself is embedded in yet another grouped AVP and so on. In this + case, the Failed-AVP MAY contain the grouped AVP heirarchy up to the + single offending AVP. This enables the recipient to detect the + location of the offending AVP when embedded in a group. + + AVP Format + + ::= < AVP Header: 279 > + 1* {AVP} + */ + struct dict_avp_data data = { + 279, /* Code */ + #if AC_FAILED_AVP != 279 + #error "AC_FAILED_AVP definition mismatch" + #endif + 0, /* Vendor */ + "Failed-AVP", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Experimental-Result */ + { + /* + The Experimental-Result AVP (AVP Code 297) is of type Grouped, and + indicates whether a particular vendor-specific request was completed + successfully or whether an error occurred. Its Data field has the + following ABNF grammar: + + AVP Format + + Experimental-Result ::= < AVP Header: 297 > + { Vendor-Id } + { Experimental-Result-Code } + + The Vendor-Id AVP (see Section 5.3.3) in this grouped AVP identifies + the vendor responsible for the assignment of the result code which + follows. All Diameter answer messages defined in vendor-specific + applications MUST include either one Result-Code AVP or one + Experimental-Result AVP. + */ + struct dict_avp_data data = { + 297, /* Code */ + 0, /* Vendor */ + "Experimental-Result", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_GROUPED /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Experimental-Result-Code */ + { + /* + The Experimental-Result-Code AVP (AVP Code 298) is of type Unsigned32 + and contains a vendor-assigned value representing the result of + processing the request. + + It is recommended that vendor-specific result codes follow the same + conventions given for the Result-Code AVP regarding the different + types of result codes and the handling of errors (for non 2xxx + values). + */ + /* Although the RFC does not specify an "Enumerated" type here, we go forward and create one. + * This is the reason for the "*" in the type name. Vendors will have to define their values. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Experimental-Result-Code)" , NULL, NULL, NULL }; + struct dict_avp_data data = { + 298, /* Code */ + 0, /* Vendor */ + "Experimental-Result-Code", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Auth-Request-Type */ + { + /* + The Auth-Request-Type AVP (AVP Code 274) is of type Enumerated and is + included in application-specific auth requests to inform the peers + whether a user is to be authenticated only, authorized only or both. + Note any value other than both MAY cause RADIUS interoperability + issues. The following values are defined: + + + AUTHENTICATE_ONLY 1 + + The request being sent is for authentication only, and MUST + contain the relevant application specific authentication AVPs that + are needed by the Diameter server to authenticate the user. + + + AUTHORIZE_ONLY 2 + + The request being sent is for authorization only, and MUST contain + the application specific authorization AVPs that are necessary to + identify the service being requested/offered. + + + AUTHORIZE_AUTHENTICATE 3 + + The request contains a request for both authentication and + authorization. The request MUST include both the relevant + application specific authentication information, and authorization + information necessary to identify the service being requested/ + offered. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Auth-Request-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "AUTHENTICATE_ONLY", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "AUTHORIZE_ONLY", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "AUTHORIZE_AUTHENTICATE", { .i32 = 3 }}; + struct dict_avp_data data = { + 274, /* Code */ + 0, /* Vendor */ + "Auth-Request-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Session-Id */ + { + /* + The Session-Id AVP (AVP Code 263) is of type UTF8String and is used + to identify a specific session (see Section 8). All messages + pertaining to a specific session MUST include only one Session-Id AVP + and the same value MUST be used throughout the life of a session. + When present, the Session-Id SHOULD appear immediately following the + Diameter Header (see Section 3). + + The Session-Id MUST be globally and eternally unique, as it is meant + to uniquely identify a user session without reference to any other + information, and may be needed to correlate historical authentication + information with accounting information. The Session-Id includes a + mandatory portion and an implementation-defined portion; a + recommended format for the implementation-defined portion is outlined + below. + + (skipped, see RFC for detail) + */ + struct dict_avp_data data = { + 263, /* Code */ + #if AC_SESSION_ID != 263 + #error "AC_SESSION_ID definition mismatch" + #endif + 0, /* Vendor */ + "Session-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Authorization-Lifetime */ + { + /* + The Authorization-Lifetime AVP (AVP Code 291) is of type Unsigned32 + and contains the maximum number of seconds of service to be provided + to the user before the user is to be re-authenticated and/or re- + authorized. Great care should be taken when the Authorization- + Lifetime value is determined, since a low, non-zero, value could + create significant Diameter traffic, which could congest both the + network and the agents. + + A value of zero (0) means that immediate re-auth is necessary by the + access device. This is typically used in cases where multiple + authentication methods are used, and a successful auth response with + this AVP set to zero is used to signal that the next authentication + method is to be immediately initiated. The absence of this AVP, or a + value of all ones (meaning all bits in the 32 bit field are set to + one) means no re-auth is expected. + + If both this AVP and the Session-Timeout AVP are present in a + message, the value of the latter MUST NOT be smaller than the + Authorization-Lifetime AVP. + + An Authorization-Lifetime AVP MAY be present in re-authorization + messages, and contains the number of seconds the user is authorized + to receive service from the time the re-auth answer message is + received by the access device. + + This AVP MAY be provided by the client as a hint of the maximum + lifetime that it is willing to accept. However, the server MAY + return a value that is equal to, or smaller, than the one provided by + the client. + */ + struct dict_avp_data data = { + 291, /* Code */ + 0, /* Vendor */ + "Authorization-Lifetime", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Auth-Grace-Period */ + { + /* + The Auth-Grace-Period AVP (AVP Code 276) is of type Unsigned32 and + contains the number of seconds the Diameter server will wait + following the expiration of the Authorization-Lifetime AVP before + cleaning up resources for the session. + */ + struct dict_avp_data data = { + 276, /* Code */ + 0, /* Vendor */ + "Auth-Grace-Period", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Auth-Session-State */ + { + /* + The Auth-Session-State AVP (AVP Code 277) is of type Enumerated and + specifies whether state is maintained for a particular session. The + client MAY include this AVP in requests as a hint to the server, but + the value in the server's answer message is binding. The following + values are supported: + + + STATE_MAINTAINED 0 + + This value is used to specify that session state is being + maintained, and the access device MUST issue a session termination + message when service to the user is terminated. This is the + default value. + + + NO_STATE_MAINTAINED 1 + + This value is used to specify that no session termination messages + will be sent by the access device upon expiration of the + Authorization-Lifetime. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Auth-Session-State)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "STATE_MAINTAINED", { .i32 = 0 }}; + struct dict_enumval_data t_1 = { "NO_STATE_MAINTAINED", { .i32 = 1 }}; + struct dict_avp_data data = { + 277, /* Code */ + 0, /* Vendor */ + "Auth-Session-State", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Re-Auth-Request-Type */ + { + /* + The Re-Auth-Request-Type AVP (AVP Code 285) is of type Enumerated and + is included in application-specific auth answers to inform the client + of the action expected upon expiration of the Authorization-Lifetime. + If the answer message contains an Authorization-Lifetime AVP with a + positive value, the Re-Auth-Request-Type AVP MUST be present in an + answer message. The following values are defined: + + + AUTHORIZE_ONLY 0 + + An authorization only re-auth is expected upon expiration of the + Authorization-Lifetime. This is the default value if the AVP is + not present in answer messages that include the Authorization- + Lifetime. + + + AUTHORIZE_AUTHENTICATE 1 + + An authentication and authorization re-auth is expected upon + expiration of the Authorization-Lifetime. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Re-Auth-Request-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "AUTHORIZE_ONLY", { .i32 = 0 }}; + struct dict_enumval_data t_1 = { "AUTHORIZE_AUTHENTICATE", { .i32 = 1 }}; + struct dict_avp_data data = { + 285, /* Code */ + 0, /* Vendor */ + "Re-Auth-Request-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Session-Timeout */ + { + /* + The Session-Timeout AVP (AVP Code 27) [RFC2865] is of type Unsigned32 + and contains the maximum number of seconds of service to be provided + to the user before termination of the session. When both the + Session-Timeout and the Authorization-Lifetime AVPs are present in an + answer message, the former MUST be equal to or greater than the value + of the latter. + + A session that terminates on an access device due to the expiration + of the Session-Timeout MUST cause an STR to be issued, unless both + the access device and the home server had previously agreed that no + session termination messages would be sent (see Section 8.11). + + A Session-Timeout AVP MAY be present in a re-authorization answer + message, and contains the remaining number of seconds from the + beginning of the re-auth. + + A value of zero, or the absence of this AVP, means that this session + has an unlimited number of seconds before termination. + + This AVP MAY be provided by the client as a hint of the maximum + timeout that it is willing to accept. However, the server MAY return + a value that is equal to, or smaller, than the one provided by the + client. + */ + struct dict_avp_data data = { + 27, /* Code */ + 0, /* Vendor */ + "Session-Timeout", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* User-Name */ + { + /* + The User-Name AVP (AVP Code 1) [RFC2865] is of type UTF8String, which + contains the User-Name, in a format consistent with the NAI + specification [RFC4282]. + */ + struct dict_avp_data data = { + 1, /* Code */ + 0, /* Vendor */ + "User-Name", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Termination-Cause */ + { + /* + The Termination-Cause AVP (AVP Code 295) is of type Enumerated, and + is used to indicate the reason why a session was terminated on the + access device. The following values are defined: + + + DIAMETER_LOGOUT 1 + + The user initiated a disconnect + + + DIAMETER_SERVICE_NOT_PROVIDED 2 + + This value is used when the user disconnected prior to the receipt + of the authorization answer message. + + + DIAMETER_BAD_ANSWER 3 + + This value indicates that the authorization answer received by the + access device was not processed successfully. + + + DIAMETER_ADMINISTRATIVE 4 + + The user was not granted access, or was disconnected, due to + administrative reasons, such as the receipt of a Abort-Session- + Request message. + + + DIAMETER_LINK_BROKEN 5 + + The communication to the user was abruptly disconnected. + + + DIAMETER_AUTH_EXPIRED 6 + + The user's access was terminated since its authorized session time + has expired. + + + DIAMETER_USER_MOVED 7 + + The user is receiving services from another access device. + + + DIAMETER_SESSION_TIMEOUT 8 + + The user's session has timed out, and service has been terminated. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Termination-Cause)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "DIAMETER_LOGOUT", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "DIAMETER_SERVICE_NOT_PROVIDED", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "DIAMETER_BAD_ANSWER", { .i32 = 3 }}; + struct dict_enumval_data t_4 = { "DIAMETER_ADMINISTRATIVE", { .i32 = 4 }}; + struct dict_enumval_data t_5 = { "DIAMETER_LINK_BROKEN", { .i32 = 5 }}; + struct dict_enumval_data t_6 = { "DIAMETER_AUTH_EXPIRED", { .i32 = 6 }}; + struct dict_enumval_data t_7 = { "DIAMETER_USER_MOVED", { .i32 = 7 }}; + struct dict_enumval_data t_8 = { "DIAMETER_SESSION_TIMEOUT", { .i32 = 8 }}; + struct dict_avp_data data = { + 295, /* Code */ + 0, /* Vendor */ + "Termination-Cause", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_5 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_6 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_7 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_8 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Origin-State-Id */ + { + /* + The Origin-State-Id AVP (AVP Code 278), of type Unsigned32, is a + monotonically increasing value that is advanced whenever a Diameter + entity restarts with loss of previous state, for example upon reboot. + Origin-State-Id MAY be included in any Diameter message, including + CER. + + A Diameter entity issuing this AVP MUST create a higher value for + this AVP each time its state is reset. A Diameter entity MAY set + Origin-State-Id to the time of startup, or it MAY use an incrementing + counter retained in non-volatile memory across restarts. + + The Origin-State-Id, if present, MUST reflect the state of the entity + indicated by Origin-Host. If a proxy modifies Origin-Host, it MUST + either remove Origin-State-Id or modify it appropriately as well. + Typically, Origin-State-Id is used by an access device that always + starts up with no active sessions; that is, any session active prior + to restart will have been lost. By including Origin-State-Id in a + message, it allows other Diameter entities to infer that sessions + associated with a lower Origin-State-Id are no longer active. If an + access device does not intend for such inferences to be made, it MUST + either not include Origin-State-Id in any message, or set its value + to 0. + */ + struct dict_avp_data data = { + 278, /* Code */ + 0, /* Vendor */ + "Origin-State-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Session-Binding */ + { + /* + The Session-Binding AVP (AVP Code 270) is of type Unsigned32, and MAY + be present in application-specific authorization answer messages. If + present, this AVP MAY inform the Diameter client that all future + application-specific re-auth messages for this session MUST be sent + to the same authorization server. This AVP MAY also specify that a + Session-Termination-Request message for this session MUST be sent to + the same authorizing server. + + This field is a bit mask, and the following bits have been defined: + + + RE_AUTH 1 + + When set, future re-auth messages for this session MUST NOT + include the Destination-Host AVP. When cleared, the default + value, the Destination-Host AVP MUST be present in all re-auth + messages for this session. + + + STR 2 + + When set, the STR message for this session MUST NOT include the + Destination-Host AVP. When cleared, the default value, the + Destination-Host AVP MUST be present in the STR message for this + session. + + + ACCOUNTING 4 + + When set, all accounting messages for this session MUST NOT + include the Destination-Host AVP. When cleared, the default + value, the Destination-Host AVP, if known, MUST be present in all + accounting messages for this session. + */ + + /* Although the RFC does not specify an "Enumerated" type here, we go forward and create one. + * This is the reason for the "*" in the type name + * The actual values of the AVP will not always be defined here, but at least it can be used in some cases. + * ... maybe the code will be changed later to support bitfields AVP ... + */ + + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Session-Binding)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "RE_AUTH", { .u32 = 1 }}; + struct dict_enumval_data t_2 = { "STR", { .u32 = 2 }}; + struct dict_enumval_data t_4 = { "ACCOUNTING", { .u32 = 4 }}; + struct dict_avp_data data = { + 270, /* Code */ + 0, /* Vendor */ + "Session-Binding", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Session-Server-Failover */ + { + /* + The Session-Server-Failover AVP (AVP Code 271) is of type Enumerated, + and MAY be present in application-specific authorization answer + messages that either do not include the Session-Binding AVP or + include the Session-Binding AVP with any of the bits set to a zero + value. If present, this AVP MAY inform the Diameter client that if a + re-auth or STR message fails due to a delivery problem, the Diameter + client SHOULD issue a subsequent message without the Destination-Host + AVP. When absent, the default value is REFUSE_SERVICE. + + The following values are supported: + + + REFUSE_SERVICE 0 + + If either the re-auth or the STR message delivery fails, terminate + service with the user, and do not attempt any subsequent attempts. + + + TRY_AGAIN 1 + + If either the re-auth or the STR message delivery fails, resend + the failed message without the Destination-Host AVP present. + + + ALLOW_SERVICE 2 + + If re-auth message delivery fails, assume that re-authorization + succeeded. If STR message delivery fails, terminate the session. + + + TRY_AGAIN_ALLOW_SERVICE 3 + + If either the re-auth or the STR message delivery fails, resend + the failed message without the Destination-Host AVP present. If + the second delivery fails for re-auth, assume re-authorization + succeeded. If the second delivery fails for STR, terminate the + session. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Session-Server-Failover)" , NULL, NULL, NULL }; + struct dict_enumval_data t_0 = { "REFUSE_SERVICE", { .i32 = 0 }}; + struct dict_enumval_data t_1 = { "TRY_AGAIN", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "ALLOW_SERVICE", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "TRY_AGAIN_ALLOW_SERVICE", { .i32 = 3 }}; + struct dict_avp_data data = { + 271, /* Code */ + 0, /* Vendor */ + "Session-Server-Failover", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Multi-Round-Time-Out */ + { + /* + The Multi-Round-Time-Out AVP (AVP Code 272) is of type Unsigned32, + and SHOULD be present in application-specific authorization answer + messages whose Result-Code AVP is set to DIAMETER_MULTI_ROUND_AUTH. + This AVP contains the maximum number of seconds that the access + device MUST provide the user in responding to an authentication + request. + */ + struct dict_avp_data data = { + 272, /* Code */ + 0, /* Vendor */ + "Multi-Round-Time-Out", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Class */ + { + /* + The Class AVP (AVP Code 25) is of type OctetString and is used to by + Diameter servers to return state information to the access device. + When one or more Class AVPs are present in application-specific + authorization answer messages, they MUST be present in subsequent re- + authorization, session termination and accounting messages. Class + AVPs found in a re-authorization answer message override the ones + found in any previous authorization answer message. Diameter server + implementations SHOULD NOT return Class AVPs that require more than + 4096 bytes of storage on the Diameter client. A Diameter client that + receives Class AVPs whose size exceeds local available storage MUST + terminate the session. + */ + struct dict_avp_data data = { + 25, /* Code */ + 0, /* Vendor */ + "Class", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Event-Timestamp */ + { + /* + The Event-Timestamp (AVP Code 55) is of type Time, and MAY be + included in an Accounting-Request and Accounting-Answer messages to + record the time that the reported event occurred, in seconds since + January 1, 1900 00:00 UTC. + */ + struct dict_avp_data data = { + 55, /* Code */ + 0, /* Vendor */ + "Event-Timestamp", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , Time_type, NULL); + } + + + /* Accounting-Record-Type */ + { + /* + The Accounting-Record-Type AVP (AVP Code 480) is of type Enumerated + and contains the type of accounting record being sent. The following + values are currently defined for the Accounting-Record-Type AVP: + + + EVENT_RECORD 1 + + An Accounting Event Record is used to indicate that a one-time + event has occurred (meaning that the start and end of the event + are simultaneous). This record contains all information relevant + to the service, and is the only record of the service. + + + START_RECORD 2 + + An Accounting Start, Interim, and Stop Records are used to + indicate that a service of a measurable length has been given. An + Accounting Start Record is used to initiate an accounting session, + and contains accounting information that is relevant to the + initiation of the session. + + + INTERIM_RECORD 3 + + An Interim Accounting Record contains cumulative accounting + information for an existing accounting session. Interim + Accounting Records SHOULD be sent every time a re-authentication + or re-authorization occurs. Further, additional interim record + triggers MAY be defined by application-specific Diameter + applications. The selection of whether to use INTERIM_RECORD + records is done by the Acct-Interim-Interval AVP. + + + STOP_RECORD 4 + + An Accounting Stop Record is sent to terminate an accounting + session and contains cumulative accounting information relevant to + the existing session. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Accounting-Record-Type)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "EVENT_RECORD", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "START_RECORD", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "INTERIM_RECORD", { .i32 = 3 }}; + struct dict_enumval_data t_4 = { "STOP_RECORD", { .i32 = 4 }}; + struct dict_avp_data data = { + 480, /* Code */ + 0, /* Vendor */ + "Accounting-Record-Type", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + /* Acct-Interim-Interval */ + { + /* + The Acct-Interim-Interval AVP (AVP Code 85) is of type Unsigned32 and + is sent from the Diameter home authorization server to the Diameter + client. The client uses information in this AVP to decide how and + when to produce accounting records. With different values in this + AVP, service sessions can result in one, two, or two+N accounting + records, based on the needs of the home-organization. The following + accounting record production behavior is directed by the inclusion of + this AVP: + + + 1. The omission of the Acct-Interim-Interval AVP or its inclusion + with Value field set to 0 means that EVENT_RECORD, START_RECORD, + and STOP_RECORD are produced, as appropriate for the service. + + + 2. The inclusion of the AVP with Value field set to a non-zero value + means that INTERIM_RECORD records MUST be produced between the + START_RECORD and STOP_RECORD records. The Value field of this + AVP is the nominal interval between these records in seconds. + + The Diameter node that originates the accounting information, + known as the client, MUST produce the first INTERIM_RECORD record + roughly at the time when this nominal interval has elapsed from + the START_RECORD, the next one again as the interval has elapsed + once more, and so on until the session ends and a STOP_RECORD + record is produced. + + The client MUST ensure that the interim record production times + are randomized so that large accounting message storms are not + created either among records or around a common service start + time. + */ + struct dict_avp_data data = { + 85, /* Code */ + 0, /* Vendor */ + "Acct-Interim-Interval", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Accounting-Record-Number */ + { + /* + The Accounting-Record-Number AVP (AVP Code 485) is of type Unsigned32 + and identifies this record within one session. As Session-Id AVPs + are globally unique, the combination of Session-Id and Accounting- + Record-Number AVPs is also globally unique, and can be used in + matching accounting records with confirmations. An easy way to + produce unique numbers is to set the value to 0 for records of type + EVENT_RECORD and START_RECORD, and set the value to 1 for the first + INTERIM_RECORD, 2 for the second, and so on until the value for + STOP_RECORD is one more than for the last INTERIM_RECORD. + */ + struct dict_avp_data data = { + 485, /* Code */ + 0, /* Vendor */ + "Accounting-Record-Number", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED32 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Acct-Session-Id */ + { + /* + The Acct-Session-Id AVP (AVP Code 44) is of type OctetString is only + used when RADIUS/Diameter translation occurs. This AVP contains the + contents of the RADIUS Acct-Session-Id attribute. + */ + struct dict_avp_data data = { + 44, /* Code */ + 0, /* Vendor */ + "Acct-Session-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Acct-Multi-Session-Id */ + { + /* + The Acct-Multi-Session-Id AVP (AVP Code 50) is of type UTF8String, + following the format specified in Section 8.8. The Acct-Multi- + Session-Id AVP is used to link together multiple related accounting + sessions, where each session would have a unique Session-Id, but the + same Acct-Multi-Session-Id AVP. This AVP MAY be returned by the + Diameter server in an authorization answer, and MUST be used in all + accounting messages for the given session. + */ + struct dict_avp_data data = { + 50, /* Code */ + 0, /* Vendor */ + "Acct-Multi-Session-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_OCTETSTRING /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL); + } + + /* Accounting-Sub-Session-Id */ + { + /* + The Accounting-Sub-Session-Id AVP (AVP Code 287) is of type + Unsigned64 and contains the accounting sub-session identifier. The + combination of the Session-Id and this AVP MUST be unique per sub- + session, and the value of this AVP MUST be monotonically increased by + one for all new sub-sessions. The absence of this AVP implies no + sub-sessions are in use, with the exception of an Accounting-Request + whose Accounting-Record-Type is set to STOP_RECORD. A STOP_RECORD + message with no Accounting-Sub-Session-Id AVP present will signal the + termination of all sub-sessions for a given Session-Id. + */ + struct dict_avp_data data = { + 287, /* Code */ + 0, /* Vendor */ + "Accounting-Sub-Session-Id", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_UNSIGNED64 /* base type of data */ + }; + CHECK_dict_new( DICT_AVP, &data , NULL, NULL); + } + + /* Accounting-Realtime-Required */ + { + /* + The Accounting-Realtime-Required AVP (AVP Code 483) is of type + Enumerated and is sent from the Diameter home authorization server to + the Diameter client or in the Accounting-Answer from the accounting + server. The client uses information in this AVP to decide what to do + if the sending of accounting records to the accounting server has + been temporarily prevented due to, for instance, a network problem. + + + DELIVER_AND_GRANT 1 + + The AVP with Value field set to DELIVER_AND_GRANT means that the + service MUST only be granted as long as there is a connection to + an accounting server. Note that the set of alternative accounting + servers are treated as one server in this sense. Having to move + the accounting record stream to a backup server is not a reason to + discontinue the service to the user. + + + GRANT_AND_STORE 2 + + The AVP with Value field set to GRANT_AND_STORE means that service + SHOULD be granted if there is a connection, or as long as records + can still be stored as described in Section 9.4. + + This is the default behavior if the AVP isn't included in the + reply from the authorization server. + + + GRANT_AND_LOSE 3 + + The AVP with Value field set to GRANT_AND_LOSE means that service + SHOULD be granted even if the records can not be delivered or + stored. + */ + struct dict_object * type; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Accounting-Realtime-Required)" , NULL, NULL, NULL }; + struct dict_enumval_data t_1 = { "DELIVER_AND_GRANT", { .i32 = 1 }}; + struct dict_enumval_data t_2 = { "GRANT_AND_STORE", { .i32 = 2 }}; + struct dict_enumval_data t_3 = { "GRANT_AND_LOSE", { .i32 = 3 }}; + struct dict_avp_data data = { + 483, /* Code */ + 0, /* Vendor */ + "Accounting-Realtime-Required", /* Name */ + AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */ + AVP_FLAG_MANDATORY, /* Fixed flag values */ + AVP_TYPE_INTEGER32 /* base type of data */ + }; + /* Create the Enumerated type, and then the AVP */ + CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type); + CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL); + CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL); + CHECK_dict_new( DICT_AVP, &data , type, NULL); + } + + } + + /* Commands section */ + { + /* To avoid defining global variables for all the AVP that we use here, we do search the dictionary in each sub-block. + * This is far from optimal, but the code is clearer like this, and the time it requires at execution is not noticeable. + */ + + /* Generic message syntax when the 'E' bit is set */ + { + /* + The 'E' (Error Bit) in the Diameter header is set when the request + caused a protocol-related error (see Section 7.1.3). A message with + the 'E' bit MUST NOT be sent as a response to an answer message. + Note that a message with the 'E' bit set is still subjected to the + processing rules defined in Section 6.2. When set, the answer + message will not conform to the ABNF specification for the command, + and will instead conform to the following ABNF: + + Message Format + + ::= < Diameter Header: code, ERR [PXY] > + 0*1< Session-Id > + { Origin-Host } + { Origin-Realm } + { Result-Code } + [ Origin-State-Id ] + [ Error-Message ] + [ Error-Reporting-Host ] + [ Failed-AVP ] + * [ Proxy-Info ] + * [ AVP ] + + Note that the code used in the header is the same than the one found + in the request message, but with the 'R' bit cleared and the 'E' bit + set. The 'P' bit in the header is set to the same value as the one + found in the request message. + */ + struct dict_object * cmd_error; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD,0, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + }; + CHECK_FCT( fd_dict_get_error_cmd(dict, &cmd_error) ); + PARSE_loc_rules( rules, cmd_error ); + } + + /* Capabilities-Exchange-Request */ + { + /* + The Capabilities-Exchange-Request (CER), indicated by the Command- + Code set to 257 and the Command Flags' 'R' bit set, is sent to + exchange local capabilities. Upon detection of a transport failure, + this message MUST NOT be sent to an alternate peer. + + When Diameter is run over SCTP [RFC2960], which allows for + connections to span multiple interfaces and multiple IP addresses, + the Capabilities-Exchange-Request message MUST contain one Host-IP- + Address AVP for each potential IP address that MAY be locally used + when transmitting Diameter messages. + + Message Format + + ::= < Diameter Header: 257, REQ > + { Origin-Host } + { Origin-Realm } + 1* { Host-IP-Address } + { Vendor-Id } + { Product-Name } + [ Origin-State-Id ] + * [ Supported-Vendor-Id ] + * [ Auth-Application-Id ] + * [ Inband-Security-Id ] + * [ Acct-Application-Id ] + * [ Vendor-Specific-Application-Id ] + [ Firmware-Revision ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 257, /* Code */ + #if CC_CAPABILITIES_EXCHANGE != 257 + #error "CC_CAPABILITIES_EXCHANGE definition mismatch" + #endif + "Capabilities-Exchange-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Host-IP-Address", RULE_REQUIRED, -1,-1 } + ,{ "Vendor-Id", RULE_REQUIRED, -1, 1 } + ,{ "Product-Name", RULE_REQUIRED, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Supported-Vendor-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Auth-Application-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Inband-Security-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Acct-Application-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Vendor-Specific-Application-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Firmware-Revision", RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Capabilities-Exchange-Answer */ + { + /* + The Capabilities-Exchange-Answer (CEA), indicated by the Command-Code + set to 257 and the Command Flags' 'R' bit cleared, is sent in + response to a CER message. + + When Diameter is run over SCTP [RFC2960], which allows connections to + span multiple interfaces, hence, multiple IP addresses, the + Capabilities-Exchange-Answer message MUST contain one Host-IP-Address + AVP for each potential IP address that MAY be locally used when + transmitting Diameter messages. + + Message Format + + ::= < Diameter Header: 257 > + { Result-Code } + { Origin-Host } + { Origin-Realm } + 1* { Host-IP-Address } + { Vendor-Id } + { Product-Name } + [ Origin-State-Id ] + [ Error-Message ] + [ Failed-AVP ] + * [ Supported-Vendor-Id ] + * [ Auth-Application-Id ] + * [ Inband-Security-Id ] + * [ Acct-Application-Id ] + * [ Vendor-Specific-Application-Id ] + [ Firmware-Revision ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 257, /* Code */ + #if CC_CAPABILITIES_EXCHANGE != 257 + #error "CC_CAPABILITIES_EXCHANGE definition mismatch" + #endif + "Capabilities-Exchange-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT, /* Fixed flags */ + 0 /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Host-IP-Address", RULE_REQUIRED, -1,-1 } + ,{ "Vendor-Id", RULE_REQUIRED, -1, 1 } + ,{ "Product-Name", RULE_REQUIRED, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + ,{ "Supported-Vendor-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Auth-Application-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Inband-Security-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Acct-Application-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Vendor-Specific-Application-Id", RULE_OPTIONAL, -1,-1 } + ,{ "Firmware-Revision", RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Disconnect-Peer-Request */ + { + /* + The Disconnect-Peer-Request (DPR), indicated by the Command-Code set + to 282 and the Command Flags' 'R' bit set, is sent to a peer to + inform its intentions to shutdown the transport connection. Upon + detection of a transport failure, this message MUST NOT be sent to an + alternate peer. + + Message Format + + ::= < Diameter Header: 282, REQ > + { Origin-Host } + { Origin-Realm } + { Disconnect-Cause } + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 282, /* Code */ + #if CC_DISCONNECT_PEER != 282 + #error "CC_DISCONNECT_PEER definition mismatch" + #endif + "Disconnect-Peer-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Disconnect-Cause", RULE_REQUIRED, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Disconnect-Peer-Answer */ + { + /* + The Disconnect-Peer-Answer (DPA), indicated by the Command-Code set + to 282 and the Command Flags' 'R' bit cleared, is sent as a response + to the Disconnect-Peer-Request message. Upon receipt of this + message, the transport connection is shutdown. + + Message Format + + ::= < Diameter Header: 282 > + { Result-Code } + { Origin-Host } + { Origin-Realm } + [ Error-Message ] + [ Failed-AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 282, /* Code */ + #if CC_DISCONNECT_PEER != 282 + #error "CC_DISCONNECT_PEER definition mismatch" + #endif + "Disconnect-Peer-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT, /* Fixed flags */ + 0 /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Device-Watchdog-Request */ + { + /* + The Device-Watchdog-Request (DWR), indicated by the Command-Code set + to 280 and the Command Flags' 'R' bit set, is sent to a peer when no + traffic has been exchanged between two peers (see Section 5.5.3). + Upon detection of a transport failure, this message MUST NOT be sent + to an alternate peer. + + Message Format + + ::= < Diameter Header: 280, REQ > + { Origin-Host } + { Origin-Realm } + [ Origin-State-Id ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 280, /* Code */ + #if CC_DEVICE_WATCHDOG != 280 + #error "CC_DEVICE_WATCHDOG definition mismatch" + #endif + "Device-Watchdog-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Device-Watchdog-Answer */ + { + /* + The Device-Watchdog-Answer (DWA), indicated by the Command-Code set + to 280 and the Command Flags' 'R' bit cleared, is sent as a response + to the Device-Watchdog-Request message. + + Message Format + + ::= < Diameter Header: 280 > + { Result-Code } + { Origin-Host } + { Origin-Realm } + [ Error-Message ] + [ Failed-AVP ] + [ Origin-State-Id ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 280, /* Code */ + #if CC_DEVICE_WATCHDOG != 280 + #error "CC_DEVICE_WATCHDOG definition mismatch" + #endif + "Device-Watchdog-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT, /* Fixed flags */ + 0 /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Re-Auth-Request */ + { + /* + The Re-Auth-Request (RAR), indicated by the Command-Code set to 258 + and the message flags' 'R' bit set, may be sent by any server to the + access device that is providing session service, to request that the + user be re-authenticated and/or re-authorized. + + + Message Format + + ::= < Diameter Header: 258, REQ, PXY > + < Session-Id > + { Origin-Host } + { Origin-Realm } + { Destination-Realm } + { Destination-Host } + { Auth-Application-Id } + { Re-Auth-Request-Type } + [ User-Name ] + [ Origin-State-Id ] + * [ Proxy-Info ] + * [ Route-Record ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 258, /* Code */ + #if CC_RE_AUTH != 258 + #error "CC_RE_AUTH definition mismatch" + #endif + "Re-Auth-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Destination-Host", RULE_REQUIRED, -1, 1 } + ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 } + ,{ "Re-Auth-Request-Type", RULE_REQUIRED, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + ,{ "Route-Record", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Re-Auth-Answer */ + { + /* + The Re-Auth-Answer (RAA), indicated by the Command-Code set to 258 + and the message flags' 'R' bit clear, is sent in response to the RAR. + The Result-Code AVP MUST be present, and indicates the disposition of + the request. + + A successful RAA message MUST be followed by an application-specific + authentication and/or authorization message. + + + Message Format + + ::= < Diameter Header: 258, PXY > + < Session-Id > + { Result-Code } + { Origin-Host } + { Origin-Realm } + [ User-Name ] + [ Origin-State-Id ] + [ Error-Message ] + [ Error-Reporting-Host ] + [ Failed-AVP ] + * [ Redirect-Host ] + [ Redirect-Host-Usage ] + [ Redirect-Max-Cache-Time ] + * [ Proxy-Info ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 258, /* Code */ + #if CC_RE_AUTH != 258 + #error "CC_RE_AUTH definition mismatch" + #endif + "Re-Auth-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + ,{ "Redirect-Host", RULE_OPTIONAL, -1,-1 } + ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 } + ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Session-Termination-Request */ + { + /* + The Session-Termination-Request (STR), indicated by the Command-Code + set to 275 and the Command Flags' 'R' bit set, is sent by the access + device to inform the Diameter Server that an authenticated and/or + authorized session is being terminated. + + + Message Format + + ::= < Diameter Header: 275, REQ, PXY > + < Session-Id > + { Origin-Host } + { Origin-Realm } + { Destination-Realm } + { Auth-Application-Id } + { Termination-Cause } + [ User-Name ] + [ Destination-Host ] + * [ Class ] + [ Origin-State-Id ] + * [ Proxy-Info ] + * [ Route-Record ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 275, /* Code */ + #if CC_SESSION_TERMINATION != 275 + #error "CC_SESSION_TERMINATION definition mismatch" + #endif + "Session-Termination-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 } + ,{ "Termination-Cause", RULE_REQUIRED, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 } + ,{ "Class", RULE_OPTIONAL, -1,-1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + ,{ "Route-Record", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Session-Termination-Answer */ + { + /* + The Session-Termination-Answer (STA), indicated by the Command-Code + set to 275 and the message flags' 'R' bit clear, is sent by the + Diameter Server to acknowledge the notification that the session has + been terminated. The Result-Code AVP MUST be present, and MAY + contain an indication that an error occurred while servicing the STR. + + Upon sending or receipt of the STA, the Diameter Server MUST release + all resources for the session indicated by the Session-Id AVP. Any + intermediate server in the Proxy-Chain MAY also release any + resources, if necessary. + + Message Format + + ::= < Diameter Header: 275, PXY > + < Session-Id > + { Result-Code } + { Origin-Host } + { Origin-Realm } + [ User-Name ] + * [ Class ] + [ Error-Message ] + [ Error-Reporting-Host ] + [ Failed-AVP ] + [ Origin-State-Id ] + * [ Redirect-Host ] + [ Redirect-Host-Usage ] + [ Redirect-Max-Cache-Time ] + * [ Proxy-Info ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 275, /* Code */ + #if CC_SESSION_TERMINATION != 275 + #error "CC_SESSION_TERMINATION definition mismatch" + #endif + "Session-Termination-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Class", RULE_OPTIONAL, -1,-1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Redirect-Host", RULE_OPTIONAL, -1,-1 } + ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 } + ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Abort-Session-Request */ + { + /* + The Abort-Session-Request (ASR), indicated by the Command-Code set to + 274 and the message flags' 'R' bit set, may be sent by any server to + the access device that is providing session service, to request that + the session identified by the Session-Id be stopped. + + + Message Format + + ::= < Diameter Header: 274, REQ, PXY > + < Session-Id > + { Origin-Host } + { Origin-Realm } + { Destination-Realm } + { Destination-Host } + { Auth-Application-Id } + [ User-Name ] + [ Origin-State-Id ] + * [ Proxy-Info ] + * [ Route-Record ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 274, /* Code */ + #if CC_ABORT_SESSION != 274 + #error "CC_ABORT_SESSION definition mismatch" + #endif + "Abort-Session-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Destination-Host", RULE_REQUIRED, -1, 1 } + ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + ,{ "Route-Record", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Abort-Session-Answer */ + { + /* + The Abort-Session-Answer (ASA), indicated by the Command-Code set to + 274 and the message flags' 'R' bit clear, is sent in response to the + ASR. The Result-Code AVP MUST be present, and indicates the + disposition of the request. + + If the session identified by Session-Id in the ASR was successfully + terminated, Result-Code is set to DIAMETER_SUCCESS. If the session + is not currently active, Result-Code is set to + DIAMETER_UNKNOWN_SESSION_ID. If the access device does not stop the + session for any other reason, Result-Code is set to + DIAMETER_UNABLE_TO_COMPLY. + + Message Format + + ::= < Diameter Header: 274, PXY > + < Session-Id > + { Result-Code } + { Origin-Host } + { Origin-Realm } + [ User-Name ] + [ Origin-State-Id ] + [ Error-Message ] + [ Error-Reporting-Host ] + [ Failed-AVP ] + * [ Redirect-Host ] + [ Redirect-Host-Usage ] + [ Redirect-Max-Cache-Time ] + * [ Proxy-Info ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 274, /* Code */ + #if CC_ABORT_SESSION != 274 + #error "CC_ABORT_SESSION definition mismatch" + #endif + "Abort-Session-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + ,{ "Redirect-Host", RULE_OPTIONAL, -1,-1 } + ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 } + ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Accounting-Request */ + { + /* + The Accounting-Request (ACR) command, indicated by the Command-Code + field set to 271 and the Command Flags' 'R' bit set, is sent by a + Diameter node, acting as a client, in order to exchange accounting + information with a peer. + + One of Acct-Application-Id and Vendor-Specific-Application-Id AVPs + MUST be present. If the Vendor-Specific-Application-Id grouped AVP + is present, it MUST include an Acct-Application-Id AVP. + + The AVP listed below SHOULD include service specific accounting AVPs, + as described in Section 9.3. + + + Message Format + + ::= < Diameter Header: 271, REQ, PXY > + < Session-Id > + { Origin-Host } + { Origin-Realm } + { Destination-Realm } + { Accounting-Record-Type } + { Accounting-Record-Number } + [ Acct-Application-Id ] + [ Vendor-Specific-Application-Id ] + [ User-Name ] + [ Destination-Host ] + [ Accounting-Sub-Session-Id ] + [ Acct-Session-Id ] + [ Acct-Multi-Session-Id ] + [ Acct-Interim-Interval ] + [ Accounting-Realtime-Required ] + [ Origin-State-Id ] + [ Event-Timestamp ] + * [ Proxy-Info ] + * [ Route-Record ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 271, /* Code */ + #if CC_ACCOUNTING != 271 + #error "CC_ACCOUNTING definition mismatch" + #endif + "Accounting-Request", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Accounting-Record-Type", RULE_REQUIRED, -1, 1 } + ,{ "Accounting-Record-Number", RULE_REQUIRED, -1, 1 } + ,{ "Acct-Application-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", RULE_OPTIONAL, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Sub-Session-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Session-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Interim-Interval", RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Realtime-Required", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Event-Timestamp", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + ,{ "Route-Record", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + + /* Accounting-Answer */ + { + /* + The Accounting-Answer (ACA) command, indicated by the Command-Code + field set to 271 and the Command Flags' 'R' bit cleared, is used to + acknowledge an Accounting-Request command. The Accounting-Answer + command contains the same Session-Id as the corresponding request. + + Only the target Diameter Server, known as the home Diameter Server, + SHOULD respond with the Accounting-Answer command. + + One of Acct-Application-Id and Vendor-Specific-Application-Id AVPs + MUST be present. If the Vendor-Specific-Application-Id grouped AVP + is present, it MUST contain an Acct-Application-Id AVP. + + The AVP listed below SHOULD include service specific accounting AVPs, + as described in Section 9.3. + + + Message Format + + ::= < Diameter Header: 271, PXY > + < Session-Id > + { Result-Code } + { Origin-Host } + { Origin-Realm } + { Accounting-Record-Type } + { Accounting-Record-Number } + [ Acct-Application-Id ] + [ Vendor-Specific-Application-Id ] + [ User-Name ] + [ Accounting-Sub-Session-Id ] + [ Acct-Session-Id ] + [ Acct-Multi-Session-Id ] + [ Error-Message ] + [ Error-Reporting-Host ] + [ Failed-AVP ] + [ Acct-Interim-Interval ] + [ Accounting-Realtime-Required ] + [ Origin-State-Id ] + [ Event-Timestamp ] + * [ Proxy-Info ] + * [ AVP ] + */ + struct dict_object * cmd; + struct dict_cmd_data data = { + 271, /* Code */ + #if CC_ACCOUNTING != 271 + #error "CC_ACCOUNTING definition mismatch" + #endif + "Accounting-Answer", /* Name */ + CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */ + CMD_FLAG_PROXIABLE /* Fixed flag values */ + }; + struct local_rules_definition rules[] = + { { "Session-Id", RULE_FIXED_HEAD, -1, 1 } + ,{ "Result-Code", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Host", RULE_REQUIRED, -1, 1 } + ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 } + ,{ "Accounting-Record-Type", RULE_REQUIRED, -1, 1 } + ,{ "Accounting-Record-Number", RULE_REQUIRED, -1, 1 } + ,{ "Acct-Application-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Vendor-Specific-Application-Id", RULE_OPTIONAL, -1, 1 } + ,{ "User-Name", RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Sub-Session-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Session-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Message", RULE_OPTIONAL, -1, 1 } + ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 } + ,{ "Failed-AVP", RULE_OPTIONAL, -1, 1 } + ,{ "Acct-Interim-Interval", RULE_OPTIONAL, -1, 1 } + ,{ "Accounting-Realtime-Required", RULE_OPTIONAL, -1, 1 } + ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 } + ,{ "Event-Timestamp", RULE_OPTIONAL, -1, 1 } + ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 } + }; + + CHECK_dict_new( DICT_COMMAND, &data , NULL, &cmd); + PARSE_loc_rules( rules, cmd ); + } + } + + return 0; +} diff --git a/plat/diameter/libfdcore/endpoints.c b/plat/diameter/libfdcore/endpoints.c new file mode 100644 index 0000000..10d8ed8 --- /dev/null +++ b/plat/diameter/libfdcore/endpoints.c @@ -0,0 +1,271 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + + +/* Add an endpoint information in a list */ +int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, uint32_t flags ) +{ + struct fd_endpoint * ep; + struct fd_list * li; + union { + sSA * sa; + sSA4 *sin; + sSA6 *sin6; + } ptr; + in_port_t * port; + int cmp = -1; + + TRACE_ENTRY("%p %p %u %x", list, sa, sl, flags); + CHECK_PARAMS( list && sa && (sl <= sizeof(sSS)) ); + + if (list->next == NULL) { + /* the list is not initialized yet, do it */ + fd_list_init(list, NULL); + } + + ptr.sa = sa; + + /* Filter out a bunch of invalid addresses */ + switch (sa->sa_family) { + case AF_INET: + if (! (flags & EP_ACCEPTALL)) { + if (IN_IS_ADDR_UNSPECIFIED(&ptr.sin->sin_addr) + || IN_IS_ADDR_LOOPBACK(&ptr.sin->sin_addr) + /* the next one filters both EXPERIMENTAL, BADCLASS and MULTICAST. */ + || ((ntohl(ptr.sin->sin_addr.s_addr) & 0xe0000000) == 0xe0000000) + || (ptr.sin->sin_addr.s_addr == INADDR_BROADCAST)) { + LOG_A(" DEBUG:fd_ep_add_merge Address was ignored, not added."); + return 0; + } + } + port = &ptr.sin->sin_port; + break; + + case AF_INET6: + if (! (flags & EP_ACCEPTALL)) { + if (IN6_IS_ADDR_UNSPECIFIED(&ptr.sin6->sin6_addr) + || IN6_IS_ADDR_LOOPBACK(&ptr.sin6->sin6_addr) + || IN6_IS_ADDR_MULTICAST(&ptr.sin6->sin6_addr) + || IN6_IS_ADDR_LINKLOCAL(&ptr.sin6->sin6_addr) + || IN6_IS_ADDR_SITELOCAL(&ptr.sin6->sin6_addr)) { + LOG_A(" DEBUG:fd_ep_add_merge Address was ignored, not added."); + return 0; + } + } + port = &ptr.sin6->sin6_port; + break; + + default: + LOG_A(" DEBUG:fd_ep_add_merge Address family was unknown, not added."); + return 0; + } + + /* remove the ACCEPTALL flag */ + flags &= ~EP_ACCEPTALL; + + /* Search place in the list */ + for (li = list->next; li != list; li = li->next) { + ep = (struct fd_endpoint *)li; + in_port_t * ep_port; + + /* First, compare the address family */ + if (ep->sa.sa_family < sa->sa_family) + continue; + if (ep->sa.sa_family > sa->sa_family) + break; + + /* Then compare the address field */ + switch (sa->sa_family) { + case AF_INET: + cmp = memcmp(&ep->sin.sin_addr, &ptr.sin->sin_addr, sizeof(struct in_addr)); + ep_port = &ep->sin.sin_port; + break; + case AF_INET6: + cmp = memcmp(&ep->sin6.sin6_addr, &ptr.sin6->sin6_addr, sizeof(struct in6_addr)); + ep_port = &ep->sin6.sin6_port; + break; + default: + ASSERT( 0 ); /* we got a different value previously in this same function */ + } + if (cmp < 0) + continue; + if (cmp > 0) + break; + + /* Finally compare the port, only if not 0 */ + if (*port == 0) + break; + if (*ep_port == 0) { + /* save the port information in the list, and break */ + *ep_port = *port; + break; + } + if (*ep_port < *port) { + cmp = -1; + continue; + } + if (*ep_port > *port) + cmp = 1; + break; + } + + if (cmp) { + /* new item to be added */ + CHECK_MALLOC( ep = malloc(sizeof(struct fd_endpoint)) ); + memset(ep, 0, sizeof(struct fd_endpoint)); + fd_list_init(&ep->chain, NULL); + memcpy(&ep->ss, sa, sl); + + /* Insert in the list */ + fd_list_insert_before(li, &ep->chain); + } + + /* Merge the flags */ + ep->flags |= flags; + + return 0; +} + +/* Delete endpoints that do not have a matching flag from a list (0: delete all endpoints) */ +int fd_ep_filter( struct fd_list * list, uint32_t flags ) +{ + struct fd_list * li; + + TRACE_ENTRY("%p %x", list, flags); + CHECK_PARAMS(list); + + for (li = list->next; li != list; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + + if (! (ep->flags & flags)) { + li = li->prev; + fd_list_unlink(&ep->chain); + free(ep); + } + } + + return 0; +} + +/* Keep only endpoints of the same family as af */ +int fd_ep_filter_family( struct fd_list * list, int af ) +{ + struct fd_list * li; + + TRACE_ENTRY("%p %d", list, af); + CHECK_PARAMS(list); + + for (li = list->next; li != list; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + + if (ep->sa.sa_family != af) { + li = li->prev; + fd_list_unlink(&ep->chain); + free(ep); + } + } + + return 0; +} + +/* Reset the given flag(s) from all items in the list */ +int fd_ep_clearflags( struct fd_list * list, uint32_t flags ) +{ + struct fd_list * li; + + TRACE_ENTRY("%p %x", list, flags); + CHECK_PARAMS(list); + + for (li = list->next; li != list; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + ep->flags &= ~flags; + if (ep->flags == 0) { + li = li->prev; + fd_list_unlink(&ep->chain); + free(ep); + } + } + + return 0; +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, int preamble, struct fd_endpoint * ep ) +{ + FD_DUMP_HANDLE_OFFSET(); + + if (preamble) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{ep}(@%p): ", ep), return NULL); + } + + if (!ep) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); + return *buf; + } + + CHECK_MALLOC_DO( fd_sa_dump( FD_DUMP_STD_PARAMS, &ep->sa, NI_NUMERICHOST | NI_NUMERICSERV ), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{%s%s%s%s%s}", + (ep->flags & EP_FL_CONF) ? "C" : "-", + (ep->flags & EP_FL_DISC) ? "D" : "-", + (ep->flags & EP_FL_ADV) ? "A" : "-", + (ep->flags & EP_FL_LL) ? "L" : "-", + (ep->flags & EP_FL_PRIMARY) ? "P" : "-"), return NULL); + return *buf; +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int preamble, int indent, struct fd_list * eps ) +{ + struct fd_list * li; + + FD_DUMP_HANDLE_OFFSET(); + + if (preamble) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{eps}(@%p):", indent, "", eps), return NULL); + } + if (eps) { + for (li = eps->next; li != eps; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + if (preamble) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n%*s", indent+1, ""), return NULL); + } else if (li->prev != eps) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\t"), return NULL); + } + CHECK_MALLOC_DO( fd_ep_dump_one( FD_DUMP_STD_PARAMS, preamble, ep ), return NULL); + } + } + return *buf; +} + diff --git a/plat/diameter/libfdcore/events.c b/plat/diameter/libfdcore/events.c new file mode 100644 index 0000000..cf1a5b6 --- /dev/null +++ b/plat/diameter/libfdcore/events.c @@ -0,0 +1,231 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Events are a subset of fifo queues, with a known type */ + +int fd_event_send(struct fifo *queue, int code, size_t datasz, void * data) +{ + struct fd_event * ev; + CHECK_MALLOC( ev = malloc(sizeof(struct fd_event)) ); + ev->code = code; + ev->size = datasz; + ev->data = data; + CHECK_FCT( fd_fifo_post(queue, &ev) ); + return 0; +} + +int fd_event_get(struct fifo *queue, int *code, size_t *datasz, void ** data) +{ + struct fd_event * ev; + CHECK_FCT( fd_fifo_get(queue, &ev) ); + if (code) + *code = ev->code; + if (datasz) + *datasz = ev->size; + if (data) + *data = ev->data; + free(ev); + return 0; +} + +int fd_event_timedget(struct fifo *queue, struct timespec * timeout, int timeoutcode, int *code, size_t *datasz, void ** data) +{ + struct fd_event * ev; + int ret = 0; + ret = fd_fifo_timedget(queue, &ev, timeout); + if (ret == ETIMEDOUT) { + if (code) + *code = timeoutcode; + if (datasz) + *datasz = 0; + if (data) + *data = NULL; + } else { + CHECK_FCT( ret ); + if (code) + *code = ev->code; + if (datasz) + *datasz = ev->size; + if (data) + *data = ev->data; + free(ev); + } + return 0; +} + +void fd_event_destroy(struct fifo **queue, void (*free_cb)(void * data)) +{ + struct fd_event * ev; + /* Purge all events, and free the associated data if any */ + while (fd_fifo_tryget( *queue, &ev ) == 0) { + (*free_cb)(ev->data); + free(ev); + } + CHECK_FCT_DO( fd_fifo_del(queue), /* continue */ ); + return ; +} + +const char * fd_ev_str(int event) +{ + switch (event) { + #define case_str( _val )\ + case _val : return #_val + case_str(FDEV_TERMINATE_INT); + case_str(FDEV_TRIGGER); + + default: + TRACE_DEBUG(FULL, "Unknown event : %d", event); + return "Unknown event"; + } +} + +/**********************************************************************/ +/* Trigged events */ +/* This allows extensions to register for / send triggers to other extensions */ +/* It is used for example for users interactions (through signals or ...) */ + +/* Because the number of triggers is not expected to grow, we use a simple ordered chained list */ +static pthread_rwlock_t trig_rwl = PTHREAD_RWLOCK_INITIALIZER; +static struct fd_list trig_list = FD_LIST_INITIALIZER(trig_list); /* The list of triggers ordered by trigger value */ +struct trig_item { + struct fd_list chain; + int trig_value; + const char * trig_module; + void (*cb)(void); +}; + +/* Add a new entry in the trigger list */ +int fd_event_trig_regcb(int trigger_val, const char * module, void (*cb)(void)) +{ + struct trig_item * ti; + struct fd_list * li; + + TRACE_ENTRY("%d %p %p", trigger_val, module, cb); + CHECK_PARAMS( trigger_val && cb ); + + /* Create a new trig_item */ + CHECK_MALLOC( ti = malloc(sizeof(struct trig_item)) ); + memset(ti, 0, sizeof(struct trig_item)); + fd_list_init(&ti->chain, ti); + ti->trig_value = trigger_val; + ti->trig_module = module; + ti->cb = cb; + + /* Now insert in the list */ + CHECK_POSIX( pthread_rwlock_wrlock(&trig_rwl) ); + + for (li = trig_list.next; li != &trig_list; li = li->next) { + struct trig_item *t = li->o; + if (t->trig_value >= trigger_val) + break; + } + + fd_list_insert_before(li, &ti->chain); + + CHECK_POSIX( pthread_rwlock_unlock(&trig_rwl) ); + + return 0; +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_event_trig_dump) +{ + struct fd_list * li; + FD_DUMP_HANDLE_OFFSET(); + + CHECK_POSIX_DO( pthread_rwlock_rdlock(&trig_rwl), ); + + for (li = trig_list.next; li != &trig_list; li = li->next) { + struct trig_item *t = li->o; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{signal:%d}'%s'->%p ", t->trig_value, t->trig_module, t->cb), break); + } + + CHECK_POSIX_DO( pthread_rwlock_unlock(&trig_rwl), ); + return *buf; +} + +static void *call_cb_detached(void * arg) +{ + void (*cb)(void) = arg; + fd_log_threadname("Trig'd callback thread"); + TRACE_ENTRY("%p", arg); + (*cb)(); + TRACE_DEBUG(ANNOYING, "Callback %p completed", cb); + return NULL; +} + +int fd_event_trig_call_cb(int trigger_val) +{ + struct fd_list * li; + pthread_attr_t detached; + pthread_t th; + + CHECK_POSIX( pthread_attr_init(&detached) ); + CHECK_POSIX( pthread_attr_setdetachstate(&detached, PTHREAD_CREATE_DETACHED) ); + + CHECK_POSIX( pthread_rwlock_rdlock(&trig_rwl) ); + + for (li = trig_list.next; li != &trig_list; li = li->next) { + struct trig_item *t = li->o; + if (t->trig_value == trigger_val) { + TRACE_DEBUG(FULL, "Trigger %d: Calling %p in %s", t->trig_value, t->cb, t->trig_module); + CHECK_POSIX_DO( pthread_create( &th, &detached, call_cb_detached, t->cb ), break ); + } + if (t->trig_value > trigger_val) + break; + } + + CHECK_POSIX( pthread_rwlock_unlock(&trig_rwl) ); + + return 0; +} + +int fd_event_trig_fini(void) { + + TRACE_ENTRY(""); + + CHECK_POSIX( pthread_rwlock_wrlock(&trig_rwl) ); + + while (!FD_IS_LIST_EMPTY(&trig_list)) { + struct fd_list * li = trig_list.next; + fd_list_unlink(li); + free(li); + } + + CHECK_POSIX( pthread_rwlock_unlock(&trig_rwl) ); + + return 0; +} diff --git a/plat/diameter/libfdcore/extensions.c b/plat/diameter/libfdcore/extensions.c new file mode 100644 index 0000000..ff41a9a --- /dev/null +++ b/plat/diameter/libfdcore/extensions.c @@ -0,0 +1,293 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +#include /* We may use libtool's later for better portability.... */ +#include /* for "basename" */ + +/* plugins management */ + +/* List of extensions to load, from the configuration parsing */ +struct fd_ext_info { + struct fd_list chain; /* link in the list */ + char *filename; /* extension filename. must be a dynamic library with fd_ext_init symbol. */ + char *conffile; /* optional configuration file name for the extension */ + void *handler; /* object returned by dlopen() */ + const char **depends; /* names of the other extensions this one depends on (if provided) */ + char *ext_name; /* points to the extension name, either inside depends, or basename(filename) */ + int free_ext_name; /* must be freed if it was malloc'd */ + void (*fini)(void); /* optional address of the fd_ext_fini callback */ +}; + +/* list of extensions */ +static struct fd_list ext_list = FD_LIST_INITIALIZER(ext_list); + +/* Add new extension */ +int fd_ext_add( char * filename, char * conffile ) +{ + struct fd_ext_info * new; + + TRACE_ENTRY("%p %p", filename, conffile); + + /* Check the filename is valid */ + CHECK_PARAMS( filename ); + + /* Create a new object in the list */ + CHECK_MALLOC( new = malloc( sizeof(struct fd_ext_info) ) ); + memset(new, 0, sizeof(struct fd_ext_info)); + fd_list_init(&new->chain, NULL); + new->filename = filename; + new->conffile = conffile; + fd_list_insert_before( &ext_list, &new->chain ); + TRACE_DEBUG (FULL, "Extension %s added to the list.", filename); + return 0; +} + +/* Dump the list */ +DECLARE_FD_DUMP_PROTOTYPE(fd_ext_dump) +{ + struct fd_list * li; + FD_DUMP_HANDLE_OFFSET(); + + if (FD_IS_LIST_EMPTY(&ext_list)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "-none-"), return NULL); + } else { + for (li = ext_list.next; li != &ext_list; li = li->next) + { + struct fd_ext_info * ext = (struct fd_ext_info *)li; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'[%s], %sloaded%s", + ext->filename, + ext->conffile?:"(no config file)", + ext->handler ? "" : "not ", (li->next == &ext_list) ? "":"\n"), return NULL); + } + } + return *buf; +} + +/* Check the dependencies. The object must have been dlopened already. */ +#if 0 +static int check_dependencies(struct fd_ext_info * ext) +{ + int i = 1; + TRACE_ENTRY( "%p", ext ); + + /* Attempt to resolve the dependency array */ + ext->depends = dlsym( ext->handler, "fd_ext_depends" ); + if (!ext->depends) { + /* Duplicate the filename */ + char * tmp = strdup(ext->filename); + ext->ext_name = strdup(basename(tmp)); + free(tmp); + ext->free_ext_name = 1; + TRACE_DEBUG(FULL, "Old extension's [%s] API: missing dependencies (ignored)", ext->ext_name); + return 0; + } + + ext->ext_name = (char *)ext->depends[0]; + + TRACE_DEBUG(FULL, "Checking dependencies for '%s'...", ext->ext_name); + + while (ext->depends[i]) { + struct fd_list * li; + for (li = ext_list.next; li != &ext->chain; li = li->next) + { + struct fd_ext_info * e = (struct fd_ext_info *)li; + if (!strcasecmp(e->ext_name, ext->depends[i])) { + /* the dependency was already loaded */ + break; + } + } + + if (li == &ext->chain) { + /* the dependency was not found */ + LOG_F("Error: extension [%s] depends on [%s] which was not loaded first. Please fix your configuration file.", + ext->ext_name, ext->depends[i]); + return ESRCH; + } + + i++; + } + + /* All dependencies resolved successfully */ + return 0; +} +#endif + +/* Load all extensions in the list */ +/* fj added 2016/06/22 */ +#if 1 +extern int fd_ext_init(int major, int minor, char * conffile); +int fd_ext_load() +{ + TRACE_ENTRY(); + + fd_ext_init(FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, NULL); + + return 0; +} +#else +int fd_ext_load() +{ + int ret; + int (*fd_ext_init)(int, int, char *) = NULL; + struct fd_list * li; + + TRACE_ENTRY(); + + /* Loop on all extensions */ + for (li = ext_list.next; li != &ext_list; li = li->next) + { + struct fd_ext_info * ext = (struct fd_ext_info *)li; + LOG_D( "Loading : %s", ext->filename); + + /* Load the extension */ +#ifndef DEBUG + ext->handler = dlopen(ext->filename, RTLD_LAZY | RTLD_GLOBAL); +#else /* DEBUG */ + /* We resolve symbols immediatly so it's easier to find problems in ABI */ + ext->handler = dlopen(ext->filename, RTLD_NOW | RTLD_GLOBAL); +#endif /* DEBUG */ + if (ext->handler == NULL) { + /* An error occured */ + LOG_F("Loading of extension %s failed: %s", ext->filename, dlerror()); + ext->handler = dlopen(ext->filename, RTLD_LAZY | RTLD_GLOBAL); + if (ext->handler) { + if (!check_dependencies(ext)) { + LOG_F("In addition, not all declared dependencies are satisfied (Internal Error!)"); + } + } + return EINVAL; + } + + /* Check if declared dependencies are satisfied. */ + CHECK_FCT( check_dependencies(ext) ); + + /* Resolve the entry point of the extension */ + fd_ext_init = ( int (*) (int, int, char *) )dlsym( ext->handler, "fd_ext_init" ); + + if (fd_ext_init == NULL) { + /* An error occured */ + TRACE_ERROR("Unable to resolve symbol 'fd_ext_init' for extension %s: %s", ext->filename, dlerror()); + return EINVAL; + } + + /* Resolve the exit point of the extension, which is optional for extensions */ + ext->fini = ( void (*) (void) )dlsym( ext->handler, "fd_ext_fini" ); + + if (ext->fini == NULL) { + /* Not provided */ + TRACE_DEBUG (FULL, "Extension [%s] has no fd_ext_fini function.", ext->filename); + } else { + /* Provided */ + TRACE_DEBUG (FULL, "Extension [%s] fd_ext_fini has been resolved successfully.", ext->filename); + } + + /* Now call the entry point to initialize the extension */ + ret = (*fd_ext_init)( FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, ext->conffile ); + if (ret != 0) { + /* The extension was unable to load cleanly */ + TRACE_ERROR("Extension %s returned an error during initialization: %s", ext->filename, strerror(ret)); + return ret; + } + + /* Proceed to the next extension */ + } + + LOG_N("All extensions loaded."); + + /* We have finished. */ + return 0; +} +#endif + + +/* Now unload the extensions and free the memory */ +/* fj added 2016/06/22 */ +#if 1 +extern void fd_ext_fini(void); +int fd_ext_term( void ) +{ + TRACE_ENTRY(); + + fd_ext_fini(); + return 0; +} + +#else +int fd_ext_term( void ) +{ + TRACE_ENTRY(); + + /* Loop on all extensions, in FIFO order */ + while (!FD_IS_LIST_EMPTY(&ext_list)) + { + struct fd_list * li = ext_list.next; + struct fd_ext_info * ext = (struct fd_ext_info *)li; + + /* Unlink this element from the list */ + fd_list_unlink(li); + + /* Call the exit point of the extension, if it was resolved */ + if (ext->fini != NULL) { + TRACE_DEBUG (FULL, "Calling [%s]->fd_ext_fini function.", ext->ext_name ?: ext->filename); + (*ext->fini)(); + } + +#ifndef SKIP_DLCLOSE + /* Now unload the extension */ + if (ext->handler) { + TRACE_DEBUG (FULL, "Unloading %s", ext->ext_name ?: ext->filename); + if ( dlclose(ext->handler) != 0 ) { + TRACE_DEBUG (INFO, "Unloading [%s] failed : %s", ext->ext_name ?: ext->filename, dlerror()); + } + } +#endif /* SKIP_DLCLOSE */ + + /* Free the object and continue */ + if (ext->free_ext_name) + free(ext->ext_name); + free(ext->filename); + free(ext->conffile); + free(ext); + } + + /* We always return 0 since we would not handle an error anyway... */ + return 0; +} + +#endif + + diff --git a/plat/diameter/libfdcore/fdcore-internal.h b/plat/diameter/libfdcore/fdcore-internal.h new file mode 100644 index 0000000..38519b9 --- /dev/null +++ b/plat/diameter/libfdcore/fdcore-internal.h @@ -0,0 +1,375 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* This file contains the definitions for internal use in the freeDiameter core library */ + +#ifndef _FDCORE_INTERNAL_H +#define _FDCORE_INTERNAL_H + +#include "freeDiameter-host.h" +#include "libfdcore.h" + +#ifdef DISABLE_SCTP +#undef IPPROTO_SCTP +#define IPPROTO_SCTP (2 = 4) /* some compilation error to spot the references */ +#endif /* DISABLE_SCTP */ + +#ifndef HAVE_AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 /* ignore this flag at the moment */ +#endif /* HAVE_AI_ADDRCONFIG */ + +/* Timeout for establishing a connection */ +#ifndef CNX_TIMEOUT +#define CNX_TIMEOUT 10 /* in seconds */ +#endif /* CNX_TIMEOUT */ + +/* Timeout for receiving a CER after incoming connection is established */ +#ifndef INCNX_TIMEOUT +#define INCNX_TIMEOUT 20 /* in seconds */ +#endif /* INCNX_TIMEOUT */ + +/* Timeout for receiving a CEA after CER is sent */ +#ifndef CEA_TIMEOUT +#define CEA_TIMEOUT 20 /* in seconds */ +#endif /* CEA_TIMEOUT */ + +/* The timeout value to wait for answer to a DPR */ +#ifndef DPR_TIMEOUT +#define DPR_TIMEOUT 15 /* in seconds */ +#endif /* DPR_TIMEOUT */ + +/* Delay where the connection is maintained opened to allow exchanging remaining pending answers after DPR/DPA */ +#ifndef GRACE_TIMEOUT +#define GRACE_TIMEOUT 1 /* in seconds */ +#endif /* GRACE_TIMEOUT */ + +/* The Vendor-Id to advertise in CER/CEA */ +#ifndef MY_VENDOR_ID +#define MY_VENDOR_ID 0 /* Reserved value to tell it must be ignored */ +#endif /* MY_VENDOR_ID */ + + + +/* Configuration */ +int fd_conf_init(); +int fd_conf_deinit(); +int fd_conf_parse(); +int fddparse(struct fd_config * conf); /* yacc generated */ +int fd_conf_stream_to_gnutls_datum(FILE * pemfile, gnutls_datum_t *out); + + +/* Extensions */ +int fd_ext_add( char * filename, char * conffile ); +int fd_ext_load(); +int fd_ext_term(void); + +/* Messages */ +int fd_msg_init(void); +extern struct dict_object * fd_dict_avp_OSI; /* Origin-State-Id */ +extern struct dict_object * fd_dict_cmd_CER; /* Capabilities-Exchange-Request */ +extern struct dict_object * fd_dict_cmd_DWR; /* Device-Watchdog-Request */ +extern struct dict_object * fd_dict_avp_DC; /* Disconnect-Cause */ +extern struct dict_object * fd_dict_cmd_DPR; /* Disconnect-Peer-Request */ + +/* Global message queues */ +extern struct fifo * fd_g_incoming; /* all messages received from other peers, except local messages (CER, ...) */ +extern struct fifo * fd_g_outgoing; /* messages to be sent to other peers on the network following routing procedure */ +extern struct fifo * fd_g_local; /* messages to be handled to local extensions */ +/* Message queues */ +int fd_queues_init(void); +int fd_queues_fini(struct fifo ** queue); + +/* Trigged events */ +int fd_event_trig_call_cb(int trigger_val); +int fd_event_trig_fini(void); + +/* Create all the dictionary objects defined in the Diameter base RFC. */ +int fd_dict_base_protocol(struct dictionary * dict); + +/* Routing */ +int fd_rtdisp_init(void); +int fd_rtdisp_cleanstop(void); +int fd_rtdisp_fini(void); +int fd_rtdisp_cleanup(void); + +/* Sentinel for the sent requests list */ +struct sr_list { + struct fd_list srs; /* requests ordered by hop-by-hop id */ + struct fd_list exp; /* requests that have a timeout set, ordered by timeout */ + long cnt; /* number of requests in the srs list */ + long cnt_lost; /* number of requests that have not been answered in time. + It is decremented when an unexpected answer is received, so this may not be accurate. */ + pthread_mutex_t mtx; /* mutex to protect these lists */ + pthread_cond_t cnd; /* cond var used by the thread that handles timeouts */ + pthread_t thr; /* the thread that handles timeouts (expirecb called in separate forked threads) */ +}; + +/* Peers */ +struct fd_peer { /* The "real" definition of the peer structure */ + + /* The public data */ + struct peer_hdr p_hdr; + + /* Eye catcher, EYEC_PEER */ + int p_eyec; + #define EYEC_PEER 0x373C9336 + + /* Origin of this peer object, for debug */ + char *p_dbgorig; + + /* State of the peer, and its lock */ + enum peer_state p_state; + pthread_mutex_t p_state_mtx; + + /* Chaining in peers sublists */ + struct fd_list p_actives; /* list of peers in the STATE_OPEN state -- used by routing */ + struct fd_list p_expiry; /* list of expiring peers, ordered by their timeout value */ + struct timespec p_exp_timer; /* Timestamp where the peer will expire; updated each time activity is seen on the peer (except DW) */ + + /* Some flags influencing the peer state machine */ + struct { + unsigned pf_responder : 1; /* The peer has been created to handle incoming connection */ + unsigned pf_delete : 1; /* Destroy the peer when the connection is terminated */ + unsigned pf_localterm : 1; /* If the latest DPR/DPA was initiated from this side */ + + unsigned pf_dw_pending : 1; /* A DWR message was sent and not answered yet */ + + unsigned pf_cnx_pb : 1; /* The peer was disconnected because of watchdogs; must exchange 3 watchdogs before putting back to normal */ + unsigned pf_reopen_cnt : 2; /* remaining DW to be exchanged after re-established connection */ + + } p_flags; + + /* The events queue, peer state machine thread, timer for states timeouts */ + struct fifo *p_events; /* The mutex of this FIFO list protects also the state and timer information */ + pthread_t p_psm; + struct timespec p_psm_timer; + + /* Outgoing message queue, and thread managing sending the messages */ + struct fifo *p_tosend; + pthread_t p_outthr; + + /* The next hop-by-hop id value for the link, only read & modified by p_outthr */ + uint32_t p_hbh; + + /* Sent requests (for fallback), list of struct sentreq ordered by hbh */ + struct sr_list p_sr; + struct fifo *p_tofailover; + + /* Pending received requests not yet answered (count only) */ + long p_reqin_count; /* We use p_state_mtx to protect this value */ + + /* Data for transitional states before the peer is in OPEN state */ + struct { + struct cnxctx * p_receiver; /* Only used in case of election */ + struct msg * p_cer; /* Only used in case of election */ + + pthread_t p_ini_thr; /* Initiator thread for establishing a connection */ + struct fd_list p_connparams; /* The list of connection attempts, see p_cnx.c */ + }; + + /* connection context: socket and related information */ + struct cnxctx *p_cnxctx; + + /* Callback for peer validation after the handshake */ + int (*p_cb2)(struct peer_info *); + + /* Callback on initial connection success / failure after the peer was added */ + void (*p_cb)(struct peer_info *, void *); + void *p_cb_data; + +}; +#define CHECK_PEER( _p ) \ + (((_p) != NULL) && (((struct fd_peer *)(_p))->p_eyec == EYEC_PEER)) + +#define fd_peer_getstate(peer) fd_peer_get_state((struct peer_hdr *)(peer)) + + +/* Events codespace for struct fd_peer->p_events */ +enum { + /* request to terminate this peer : disconnect, requeue all messages */ + FDEVP_TERMINATE = 1500 + + /* A connection object has received a message. (data contains the buffer + padding + struct fd_msg_pmdl) */ + ,FDEVP_CNX_MSG_RECV + + /* A connection object has encountered an error (disconnected). */ + ,FDEVP_CNX_ERROR + + /* Endpoints of a connection have been changed (multihomed SCTP). */ + ,FDEVP_CNX_EP_CHANGE + + /* The connection is being shutdown (SCTP notification). */ + ,FDEVP_CNX_SHUTDOWN + + /* A new connection (with a CER) has been received */ + ,FDEVP_CNX_INCOMING + + /* A new connection has been established to the remote peer (event data is the cnxctx object) */ + ,FDEVP_CNX_ESTABLISHED + + /* A connection attempt (initiator side) has failed */ + ,FDEVP_CNX_FAILED + + /* The PSM state is expired */ + ,FDEVP_PSM_TIMEOUT + +}; +#define CHECK_PEVENT( _e ) \ + (((int)(_e) >= FDEVP_TERMINATE) && ((int)(_e) <= FDEVP_PSM_TIMEOUT)) +/* The following macro is actually called in p_psm.c -- another solution would be to declare it static inline */ +#define DECLARE_PEV_STR() \ +const char * fd_pev_str(int event) \ +{ \ + switch (event) { \ + case_str(FDEVP_TERMINATE); \ + case_str(FDEVP_CNX_MSG_RECV); \ + case_str(FDEVP_CNX_ERROR); \ + case_str(FDEVP_CNX_EP_CHANGE); \ + case_str(FDEVP_CNX_INCOMING); \ + case_str(FDEVP_CNX_ESTABLISHED); \ + case_str(FDEVP_CNX_FAILED); \ + case_str(FDEVP_PSM_TIMEOUT); \ + } \ + TRACE_DEBUG(FULL, "Unknown event : %d", event); \ + return "Unknown event"; \ +} +const char * fd_pev_str(int event); + +/* The data structure for FDEVP_CNX_INCOMING event */ +struct cnx_incoming { + struct msg * cer; /* the CER message received on this connection */ + struct cnxctx * cnx; /* The connection context */ + int validate; /* The peer is new, it must be validated (by an extension) or error CEA to be sent */ +}; + +/* Functions */ +int fd_peer_fini(); +int fd_peer_alloc(struct fd_peer ** ptr); +int fd_peer_free(struct fd_peer ** ptr); +int fd_peer_handle_newCER( struct msg ** cer, struct cnxctx ** cnx ); +/* fd_peer_add declared in freeDiameter.h */ +int fd_peer_validate( struct fd_peer * peer ); +void fd_peer_failover_msg(struct fd_peer * peer); + +/* Peer expiry */ +int fd_p_expi_init(void); +int fd_p_expi_fini(void); +int fd_p_expi_update(struct fd_peer * peer ); + +/* Peer state machine */ +int fd_psm_start(); +int fd_psm_begin(struct fd_peer * peer ); +int fd_psm_terminate(struct fd_peer * peer, char * reason ); +void fd_psm_abord(struct fd_peer * peer ); +void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay); +int fd_psm_change_state(struct fd_peer * peer, int new_state); +void fd_psm_cleanup(struct fd_peer * peer, int terminate); + +/* Peer out */ +int fd_out_send(struct msg ** msg, struct cnxctx * cnx, struct fd_peer * peer, int update_reqin_cnt); +int fd_out_start(struct fd_peer * peer); +int fd_out_stop(struct fd_peer * peer); + +/* Initiating connections */ +int fd_p_cnx_init(struct fd_peer * peer); +void fd_p_cnx_abort(struct fd_peer * peer, int cleanup_all); + +/* Peer sent requests cache */ +int fd_p_sr_store(struct sr_list * srlist, struct msg **req, uint32_t *hbhloc, uint32_t hbh_restore); +int fd_p_sr_fetch(struct sr_list * srlist, uint32_t hbh, struct msg **req); +int fd_p_sr_start(struct sr_list * srlist); +int fd_p_sr_stop(struct sr_list * srlist); +void fd_p_sr_failover(struct sr_list * srlist); + +/* Local Link messages (CER/CEA, DWR/DWA, DPR/DPA) */ +int fd_p_ce_msgrcv(struct msg ** msg, int req, struct fd_peer * peer); +int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid); +int fd_p_ce_handle_newcnx(struct fd_peer * peer, struct cnxctx * initiator); +int fd_p_ce_process_receiver(struct fd_peer * peer); +void fd_p_ce_clear_cnx(struct fd_peer * peer, struct cnxctx ** cnx_kept); +int fd_p_dw_handle(struct msg ** msg, int req, struct fd_peer * peer); +int fd_p_dw_timeout(struct fd_peer * peer); +int fd_p_dw_reopen(struct fd_peer * peer); +int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer); +int fd_p_dp_initiate(struct fd_peer * peer, char * reason); +int fd_p_dp_newdelay(struct fd_peer * peer); + +/* Active peers -- routing process should only ever take the read lock, the write lock is managed by PSMs */ +extern struct fd_list fd_g_activ_peers; +extern pthread_rwlock_t fd_g_activ_peers_rw; /* protect the list */ + + +/* Server sockets */ +int fd_servers_start(); +int fd_servers_stop(); + +/* Connection contexts -- there are also definitions in cnxctx.h for the relevant files */ +struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep); +struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list); +int fd_cnx_serv_listen(struct cnxctx * conn); +struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv); +struct cnxctx * fd_cnx_cli_connect_tcp(sSA * sa, socklen_t addrlen); +struct cnxctx * fd_cnx_cli_connect_sctp(int no_ip6, uint16_t port, struct fd_list * list); +int fd_cnx_start_clear(struct cnxctx * conn, int loop); +void fd_cnx_sethostname(struct cnxctx * conn, DiamId_t hn); +int fd_cnx_proto_info(struct cnxctx * conn, char * buf, size_t len); +#define ALGO_HANDSHAKE_DEFAULT 0 /* TLS for TCP, DTLS for SCTP */ +#define ALGO_HANDSHAKE_3436 1 /* For TLS for SCTP also */ +int fd_cnx_handshake(struct cnxctx * conn, int mode, int algo, char * priority, void * alt_creds); +char * fd_cnx_getid(struct cnxctx * conn); +int fd_cnx_getproto(struct cnxctx * conn); +int fd_cnx_getTLS(struct cnxctx * conn); +int fd_cnx_is_unordered_delivery_supported(struct cnxctx * conn); +int fd_cnx_unordered_delivery(struct cnxctx * conn, int is_allowed); +int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size); +int fd_cnx_get_local_eps(struct fd_list * list); +int fd_cnx_getremoteeps(struct cnxctx * conn, struct fd_list * eps); +char * fd_cnx_getremoteid(struct cnxctx * conn); +int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len); +int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */ +int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len); +void fd_cnx_destroy(struct cnxctx * conn); +#ifdef GNUTLS_VERSION_300 +int fd_tls_verify_credentials_2(gnutls_session_t session); +#endif /* GNUTLS_VERSION_300 */ + +/* Internal calls of the hook mechanism */ +void fd_hook_call(enum fd_hook_type type, struct msg * msg, struct fd_peer * peer, void * other, struct fd_msg_pmdl * pmdl); +void fd_hook_associate(struct msg * msg, struct fd_msg_pmdl * pmdl); +int fd_hooks_init(void); +size_t fd_msg_pmdl_sizewithoverhead(size_t datalen); +struct fd_msg_pmdl * fd_msg_pmdl_get_inbuf(uint8_t * buf, size_t datalen); + +#endif /* _FDCORE_INTERNAL_H */ diff --git a/plat/diameter/libfdcore/fdd.l b/plat/diameter/libfdcore/fdd.l new file mode 100644 index 0000000..ad57576 --- /dev/null +++ b/plat/diameter/libfdcore/fdd.l @@ -0,0 +1,285 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Lex configuration parser. + * + * This file defines the token for parsing the daemon's configuration file + * Note that each extension has a separate independant configuration file. + * + * Note : This module is NOT thread-safe. All processing must be done from one thread only. + */ +%{ +/* Include the daemon's header files */ +#include "fdcore-internal.h" +/* Include yacc tokens definitions */ +#include "fdd.tab.h" + +/* Update the column information */ +#ifdef DEBUG_LEX +#define YY_USER_ACTION { \ + yylloc->first_column = yylloc->last_column + 1; \ + yylloc->last_column = yylloc->first_column + yyleng - 1; \ + fd_log_debug( \ + "(%d:%d-%d:%d) matched rule %d, length=%d, txt='%s'", \ + yylloc->first_line, yylloc->first_column, \ + yylloc->last_line, yylloc->last_column, \ + yy_act, yyleng, yytext); \ +} +#else /* DEBUG_LEX */ +#define YY_USER_ACTION { \ + yylloc->first_column = yylloc->last_column + 1; \ + yylloc->last_column = yylloc->first_column + yyleng - 1; \ +} +#endif + +/* %option noinput ? */ +#define YY_NO_INPUT + +/* Additional for files inclusion */ +#include +#include + +#define MAX_NESTED_CONF_FILES 5 + +struct nested_conffiles_t { + YY_BUFFER_STATE parent_level_state; + glob_t filelist; + int current_file; +} nested_conffiles[MAX_NESTED_CONF_FILES]; + +int current_nested_level = 0; + +int globerrfct(const char *epath, int eerrno) +{ + TRACE_ERROR("Failed to scan %s: %s", epath, strerror(eerrno)); + return 1; +} + +%} + +%option bison-bridge bison-locations +%option noyywrap +%option nounput + +%x in_include + +/* Quoted string. Multilines do not match. */ +qstring \"[^\"\n]*\" + +%% +<*>\n { + /* Update the line count */ + yylloc->first_line++; + yylloc->last_line++; + yylloc->last_column=0; + } + +<*>([[:space:]]{-}[\n])+ ; /* Eat all spaces, not new lines */ +<*>#.*$ ; /* Eat all comments */ + + +include BEGIN(in_include); + /* Following an "include" keyword */ +{ +{qstring} { /* Name of the file to include. This is directly sent to glob. */ + int globerror=0; + char * buf = strdup(yytext+1); + if (buf[yyleng-2] != '"') + { + TRACE_ERROR("Unterminated string: %s", yytext); + return LEX_ERROR; + } + buf[yyleng-2] = '\0'; + + if (current_nested_level >= MAX_NESTED_CONF_FILES) + { + TRACE_ERROR("Too many recursion levels in configuration files includes"); + return LEX_ERROR; + } + + /* glob the include */ + globerror = glob(buf, GLOB_ERR, globerrfct, &nested_conffiles[current_nested_level].filelist); + + if (globerror == GLOB_NOSPACE) + { + TRACE_ERROR("Not enough memory to parse include directive."); + return LEX_ERROR; + } + if (globerror == GLOB_ABORTED) + { + TRACE_ERROR("An error was encountered in include directive."); + return LEX_ERROR; + } + if (globerror == GLOB_NOMATCH) + { + globfree(&nested_conffiles[current_nested_level].filelist); + goto nomatch; + } + if (globerror) + { + TRACE_ERROR("Unexpected error in glob (%d).", globerror); + return LEX_ERROR; + } + + /* We have a list of files to include. */ + + /* save the current buffer for returning when this include has been parsed */ + nested_conffiles[current_nested_level].parent_level_state = YY_CURRENT_BUFFER; + + /* Start with the first match */ + nested_conffiles[current_nested_level].current_file = 0; + + yyin = fopen( nested_conffiles[current_nested_level].filelist.gl_pathv[0], "r" ); + + if ( ! yyin ) + { + TRACE_ERROR("Error in %s: %s", nested_conffiles[current_nested_level].filelist.gl_pathv[0], strerror(errno)); + return LEX_ERROR; + } + + yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE )); + + /* In case of recursive includes */ + current_nested_level++; + +nomatch: + BEGIN(INITIAL); + } +} + +<> { + if (current_nested_level == 0) + { + /* We are at the end of parsing */ + yyterminate(); + } + + /* Otherwise we are doing an include statement */ + --current_nested_level; + yy_delete_buffer(YY_CURRENT_BUFFER); + + /* Go to next file, if any */ + nested_conffiles[current_nested_level].current_file++; + if ( nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file] == NULL ) + { + /* We have finished with this list of includes */ + globfree(&nested_conffiles[current_nested_level].filelist); + yy_switch_to_buffer(nested_conffiles[current_nested_level].parent_level_state); + } + else + { + /* Proceed to next included file */ + yyin = fopen( nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file], "r" ); + + if ( ! yyin ) + { + TRACE_ERROR("Error in %s: %s", nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file], strerror(errno)); + return LEX_ERROR; + } + + yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE )); + + /* In case of recursive includes */ + current_nested_level++; + } + +} + +{qstring} { + /* First copy the string without the quotes for use in the yacc parser */ + CHECK_MALLOC_DO( yylval->string = strdup(yytext+1), /* This allocates one useless tail char but... it's easier :D */ + return LEX_ERROR );/* on error, trig an error in yacc parser */ + + yylval->string[yyleng-2] = '\0'; + + /* the yacc parser will check the string is valid */ + return QSTRING; + } + +[[:digit:]]+ { + /* Convert this to an integer value */ + int ret = sscanf(yytext, "%i", &yylval->integer); + if (ret != 1) { + /* No matching: an error occurred */ + TRACE_ERROR("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno)); + return LEX_ERROR; /* trig an error in yacc parser */ + /* Maybe we could REJECT instead of failing here? */ + } + return INTEGER; + } + + /* Full words tokens (keywords) */ +(?i:"Identity") { return IDENTITY; } +(?i:"Realm") { return REALM; } +(?i:"Port") { return PORT; } +(?i:"SecPort") { return SECPORT; } + /* (?i:"SctpSec3436") { return SEC3436; } */ +(?i:"No_IPv6") { return NOIP6; } +(?i:"No_IP") { return NOIP; } +(?i:"No_TCP") { return NOTCP; } +(?i:"No_SCTP") { return NOSCTP; } +(?i:"Prefer_TCP") { return PREFERTCP; } +(?i:"TLS_old_method") { return OLDTLS; } +(?i:"SCTP_streams") { return SCTPSTREAMS; } +(?i:"AppServThreads") { return APPSERVTHREADS;} +(?i:"ListenOn") { return LISTENON; } +(?i:"ThreadsPerServer") { return THRPERSRV; } +(?i:"TcTimer") { return TCTIMER; } +(?i:"TwTimer") { return TWTIMER; } +(?i:"NoRelay") { return NORELAY; } +(?i:"LoadExtension") { return LOADEXT; } +(?i:"ConnectPeer") { return CONNPEER; } +(?i:"ConnectTo") { return CONNTO; } +(?i:"No_TLS") { return NOTLS; } +(?i:"TLS_Cred") { return TLS_CRED; } +(?i:"TLS_CA") { return TLS_CA; } +(?i:"TLS_CRL") { return TLS_CRL; } +(?i:"TLS_Prio") { return TLS_PRIO; } +(?i:"TLS_DH_bits") { return TLS_DH_BITS; } +(?i:"TLS_DH_file") { return TLS_DH_FILE; } + + + /* Valid single characters for yyparse */ +<*>[=,:;{}] { return yytext[0]; } + + /* Unrecognized token */ +<*>[[:alnum:]]+ | /* This rule is only useful to print a complete token in error messages */ + /* Unrecognized character */ +<*>. { + TRACE_ERROR("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext); + return LEX_ERROR; + } + +%% diff --git a/plat/diameter/libfdcore/fdd.y b/plat/diameter/libfdcore/fdd.y new file mode 100644 index 0000000..f959585 --- /dev/null +++ b/plat/diameter/libfdcore/fdd.y @@ -0,0 +1,667 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Yacc configuration parser. + * + * This file defines the grammar of the configuration file. + * Note that each extension has a separate independant configuration file. + * + * Note : This module is NOT thread-safe. All processing must be done from one thread only. + */ + +/* For development only : */ +%debug +%error-verbose + +%parse-param {struct fd_config * conf} + +/* Keep track of location */ +%locations +%pure-parser + +%{ +#include "fdcore-internal.h" +#include "fdd.tab.h" /* bug : bison does not define the YYLTYPE before including this bloc, so... */ + +/* The Lex parser prototype */ +int fddlex(YYSTYPE *lvalp, YYLTYPE *llocp); + +/* Function to report error */ +void yyerror (YYLTYPE *ploc, struct fd_config * conf, char const *s) +{ + if (ploc->first_line != ploc->last_line) { + TRACE_ERROR("%s:%d.%d-%d.%d : %s", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s); + } else if (ploc->first_column != ploc->last_column) { + TRACE_ERROR("%s:%d.%d-%d : %s", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_column, s); + } else { + TRACE_ERROR("%s:%d.%d : %s", conf->cnf_file, ploc->first_line, ploc->first_column, s); + } +} + +int got_peer_noip = 0; +int got_peer_noipv6 = 0; +int got_peer_notcp = 0; +int got_peer_nosctp = 0; + +struct peer_info fddpi; + +%} + +/* Values returned by lex for token */ +%union { + char *string; /* The string is allocated by strdup in lex.*/ + int integer; /* Store integer values */ +} + +/* In case of error in the lexical analysis */ +%token LEX_ERROR + +%token QSTRING +%token INTEGER + +%type extconf + +%token IDENTITY +%token REALM +%token PORT +%token SECPORT +%token SEC3436 +%token NOIP +%token NOIP6 +%token NOTCP +%token NOSCTP +%token PREFERTCP +%token OLDTLS +%token NOTLS +%token SCTPSTREAMS +%token APPSERVTHREADS +%token LISTENON +%token THRPERSRV +%token TCTIMER +%token TWTIMER +%token NORELAY +%token LOADEXT +%token CONNPEER +%token CONNTO +%token TLS_CRED +%token TLS_CA +%token TLS_CRL +%token TLS_PRIO +%token TLS_DH_BITS +%token TLS_DH_FILE + + +/* -------------------------------------- */ +%% + + /* The grammar definition - Sections blocs. */ +conffile: /* Empty is OK -- for simplicity here, we reject in daemon later */ + | conffile identity + | conffile realm + | conffile tctimer + | conffile twtimer + | conffile port + | conffile secport + | conffile sec3436 + | conffile sctpstreams + | conffile listenon + | conffile thrpersrv + | conffile norelay + | conffile appservthreads + | conffile noip + | conffile noip6 + | conffile notcp + | conffile nosctp + | conffile prefertcp + | conffile oldtls + | conffile loadext + | conffile connpeer + | conffile tls_cred + | conffile tls_ca + | conffile tls_crl + | conffile tls_prio + | conffile tls_dh + | conffile errors + { + yyerror(&yylloc, conf, "An error occurred while parsing the configuration file"); + return EINVAL; + } + ; + + /* Lexical or syntax error */ +errors: LEX_ERROR + | error + ; + +identity: IDENTITY '=' QSTRING ';' + { + conf->cnf_diamid = $3; + } + ; + +realm: REALM '=' QSTRING ';' + { + conf->cnf_diamrlm = $3; + } + ; + +tctimer: TCTIMER '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 > 0), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_timer_tc = (unsigned int)$3; + } + ; + +twtimer: TWTIMER '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 > 5), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_timer_tw = (unsigned int)$3; + } + ; + +port: PORT '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 >= 0) && ($3 < 1<<16), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_port = (uint16_t)$3; + } + ; + +secport: SECPORT '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 >= 0) && ($3 < 1<<16), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_port_tls = (uint16_t)$3; + } + ; + +sec3436: SEC3436 '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 >= 0) && ($3 < 1<<16), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_port_3436 = (uint16_t)$3; + } + ; + +sctpstreams: SCTPSTREAMS '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_sctp_str = (uint16_t)$3; + } + ; + +listenon: LISTENON '=' QSTRING ';' + { + struct addrinfo hints, *ai; + int ret; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + ret = getaddrinfo($3, NULL, &hints, &ai); + if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; } + CHECK_FCT_DO( fd_ep_add_merge( &conf->cnf_endpoints, ai->ai_addr, ai->ai_addrlen, EP_FL_CONF ), YYERROR ); + freeaddrinfo(ai); + free($3); + } + ; + +thrpersrv: THRPERSRV '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 > 0), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_thr_srv = $3; + } + ; + +norelay: NORELAY ';' + { + conf->cnf_flags.no_fwd = 1; + } + ; + +appservthreads: APPSERVTHREADS '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($3 > 0) && ($3 < 256), + { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); + conf->cnf_dispthr = (uint16_t)$3; + } + ; + +noip: NOIP ';' + { + if (got_peer_noipv6) { + yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IPv6."); + YYERROR; + } + conf->cnf_flags.no_ip4 = 1; + } + ; + +noip6: NOIP6 ';' + { + if (got_peer_noip) { + yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IP."); + YYERROR; + } + conf->cnf_flags.no_ip6 = 1; + } + ; + +notcp: NOTCP ';' + { + #ifdef DISABLE_SCTP + yyerror (&yylloc, conf, "No_TCP cannot be specified for daemon compiled with DISABLE_SCTP option."); + YYERROR; + #endif + if (conf->cnf_flags.no_sctp) + { + yyerror (&yylloc, conf, "No_TCP conflicts with No_SCTP directive." ); + YYERROR; + } + if (got_peer_nosctp) { + yyerror (&yylloc, conf, "No_TCP conflicts with a ConnectPeer directive No_SCTP."); + YYERROR; + } + conf->cnf_flags.no_tcp = 1; + } + ; + +nosctp: NOSCTP ';' + { + if (conf->cnf_flags.no_tcp) + { + yyerror (&yylloc, conf, "No_SCTP conflicts with No_TCP directive." ); + YYERROR; + } + if (got_peer_notcp) { + yyerror (&yylloc, conf, "No_SCTP conflicts with a ConnectPeer directive No_TCP."); + YYERROR; + } + conf->cnf_flags.no_sctp = 1; + } + ; + +prefertcp: PREFERTCP ';' + { + conf->cnf_flags.pr_tcp = 1; + } + ; + +oldtls: OLDTLS ';' + { + conf->cnf_flags.tls_alg = 1; + } + ; + +loadext: LOADEXT '=' QSTRING extconf ';' + { + char * fname; + char * cfname; + FILE * fd; + + /* Try and open the extension file */ + fname = $3; + fd = fopen(fname, "r"); + if ((fd == NULL) && (*fname != '/')) { + char * bkp = fname; + CHECK_MALLOC_DO( fname = malloc( strlen(bkp) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ), + { yyerror (&yylloc, conf, "Not enough memory"); YYERROR; } ); + sprintf(fname, DEFAULT_EXTENSIONS_PATH "/%s", bkp); + fd = fopen(fname, "r"); + if (fd == NULL) { + free(fname); + fname = bkp; + } else { + free(bkp); + } + } + if (fd != NULL) { + fclose(fd); + } /* otherwise, LD_LIBRARY_PATH will be tested by dl_open. + This should not give any security issue, otherwise we can add an "else fail" here. */ + + /* Try and open the configuration file (optional) */ + cfname = $4; + if (cfname) { + fd = fopen(cfname, "r"); + if ((fd == NULL) && (*cfname != '/')) { + char * test; + CHECK_MALLOC_DO( test = malloc( strlen(cfname) + strlen(DEFAULT_CONF_PATH) + 2 ), + { yyerror (&yylloc, conf, "Not enough memory"); YYERROR; } ); + sprintf(test, DEFAULT_CONF_PATH "/%s", cfname); + fd = fopen(test, "r"); + if (fd) { + free(cfname); + cfname=test; + } else { + /* This is not an error, we allow an extension to wait for something else than a real conf file. */ + free(test); + } + } + if (fd) + fclose(fd); + } + + CHECK_FCT_DO( fd_ext_add( fname, cfname ), + { yyerror (&yylloc, conf, "Error adding extension"); YYERROR; } ); + } + ; + +extconf: /* empty */ + { + $$ = NULL; + } + | ':' QSTRING + { + $$ = $2; + } + ; + +connpeer: { + memset(&fddpi, 0, sizeof(fddpi)); + fddpi.config.pic_flags.persist = PI_PRST_ALWAYS; + fd_list_init( &fddpi.pi_endpoints, NULL ); + } + CONNPEER '=' QSTRING peerinfo ';' + { + fddpi.pi_diamid = $4; + CHECK_FCT_DO( fd_peer_add ( &fddpi, conf->cnf_file, NULL, NULL ), + { yyerror (&yylloc, conf, "Error adding ConnectPeer information"); YYERROR; } ); + + /* Now destroy any content in the structure */ + free(fddpi.pi_diamid); + free(fddpi.config.pic_realm); + free(fddpi.config.pic_priority); + while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) { + struct fd_list * li = fddpi.pi_endpoints.next; + fd_list_unlink(li); + free(li); + } + } + ; + +peerinfo: /* empty */ + | '{' peerparams '}' + ; + +peerparams: /* empty */ + | peerparams NOIP ';' + { + if ((conf->cnf_flags.no_ip6) || (fddpi.config.pic_flags.pro3 == PI_P3_IP)) { + yyerror (&yylloc, conf, "No_IP conflicts with a No_IPv6 directive."); + YYERROR; + } + got_peer_noip++; + fddpi.config.pic_flags.pro3 = PI_P3_IPv6; + } + | peerparams NOIP6 ';' + { + if ((conf->cnf_flags.no_ip4) || (fddpi.config.pic_flags.pro3 == PI_P3_IPv6)) { + yyerror (&yylloc, conf, "No_IPv6 conflicts with a No_IP directive."); + YYERROR; + } + got_peer_noipv6++; + fddpi.config.pic_flags.pro3 = PI_P3_IP; + } + | peerparams NOTCP ';' + { + #ifdef DISABLE_SCTP + yyerror (&yylloc, conf, "No_TCP cannot be specified in daemon compiled with DISABLE_SCTP option."); + YYERROR; + #endif + if ((conf->cnf_flags.no_sctp) || (fddpi.config.pic_flags.pro4 == PI_P4_TCP)) { + yyerror (&yylloc, conf, "No_TCP conflicts with a No_SCTP directive."); + YYERROR; + } + got_peer_notcp++; + fddpi.config.pic_flags.pro4 = PI_P4_SCTP; + } + | peerparams NOSCTP ';' + { + if ((conf->cnf_flags.no_tcp) || (fddpi.config.pic_flags.pro4 == PI_P4_SCTP)) { + yyerror (&yylloc, conf, "No_SCTP conflicts with a No_TCP directive."); + YYERROR; + } + got_peer_nosctp++; + fddpi.config.pic_flags.pro4 = PI_P4_TCP; + } + | peerparams PREFERTCP ';' + { + fddpi.config.pic_flags.alg = PI_ALGPREF_TCP; + } + | peerparams OLDTLS ';' + { + fddpi.config.pic_flags.sec |= PI_SEC_TLS_OLD; + } + | peerparams NOTLS ';' + { + fddpi.config.pic_flags.sec |= PI_SEC_NONE; + } + | peerparams SEC3436 ';' + { + fddpi.config.pic_flags.sctpsec |= PI_SCTPSEC_3436; + } + | peerparams REALM '=' QSTRING ';' + { + fddpi.config.pic_realm = $4; + } + | peerparams PORT '=' INTEGER ';' + { + CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16), + { yyerror (&yylloc, conf, "Invalid port value"); YYERROR; } ); + fddpi.config.pic_port = (uint16_t)$4; + } + | peerparams TCTIMER '=' INTEGER ';' + { + fddpi.config.pic_tctimer = $4; + } + | peerparams TWTIMER '=' INTEGER ';' + { + fddpi.config.pic_twtimer = $4; + } + | peerparams TLS_PRIO '=' QSTRING ';' + { + fddpi.config.pic_priority = $4; + } + | peerparams CONNTO '=' QSTRING ';' + { + struct addrinfo hints, *ai; + int ret; + int disc = 0; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST; + ret = getaddrinfo($4, NULL, &hints, &ai); + if (ret == EAI_NONAME) { + /* The name was maybe not numeric, try again */ + disc = EP_FL_DISC; + hints.ai_flags &= ~ AI_NUMERICHOST; + ret = getaddrinfo($4, NULL, &hints, &ai); + } + if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; } + + CHECK_FCT_DO( fd_ep_add_merge( &fddpi.pi_endpoints, ai->ai_addr, ai->ai_addrlen, EP_FL_CONF | (disc ?: EP_ACCEPTALL) ), YYERROR ); + free($4); + freeaddrinfo(ai); + } + ; + +tls_cred: TLS_CRED '=' QSTRING ',' QSTRING ';' + { + FILE * fd; + fd = fopen($3, "r"); + if (fd == NULL) { + int ret = errno; + TRACE_ERROR("Unable to open certificate file %s for reading: %s", $3, strerror(ret)); + yyerror (&yylloc, conf, "Error on file name"); + YYERROR; + } + fclose(fd); + fd = fopen($5, "r"); + if (fd == NULL) { + int ret = errno; + TRACE_ERROR("Unable to open private key file %s for reading: %s", $5, strerror(ret)); + yyerror (&yylloc, conf, "Error on file name"); + YYERROR; + } + fclose(fd); + conf->cnf_sec_data.cert_file = $3; + conf->cnf_sec_data.key_file = $5; + + CHECK_GNUTLS_DO( gnutls_certificate_set_x509_key_file( + conf->cnf_sec_data.credentials, + conf->cnf_sec_data.cert_file, + conf->cnf_sec_data.key_file, + GNUTLS_X509_FMT_PEM), + { yyerror (&yylloc, conf, "Error opening certificate or private key file."); YYERROR; } ); + } + ; + +tls_ca: TLS_CA '=' QSTRING ';' + { + FILE * fd; + fd = fopen($3, "rb"); + if (fd == NULL) { + int ret = errno; + TRACE_ERROR("Unable to open CA file %s for reading: %s", $3, strerror(ret)); + yyerror (&yylloc, conf, "Error on file name"); + YYERROR; + } + #ifdef GNUTLS_VERSION_300 + { + /* We import these CA in the trust list */ + gnutls_x509_crt_t * calist; + unsigned int cacount; + gnutls_datum_t cafile; + + CHECK_FCT_DO( fd_conf_stream_to_gnutls_datum(fd, &cafile), + { yyerror (&yylloc, conf, "Error reading CA file."); YYERROR; } ); + + CHECK_GNUTLS_DO( gnutls_x509_crt_list_import2(&calist, &cacount, &cafile, GNUTLS_X509_FMT_PEM, + GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED), + { yyerror (&yylloc, conf, "Error importing CA file."); YYERROR; } ); + free(cafile.data); + + CHECK_GNUTLS_DO( gnutls_x509_trust_list_add_cas (fd_g_config->cnf_sec_data.trustlist, calist, cacount, 0), + { yyerror (&yylloc, conf, "Error saving CA in trust list."); YYERROR; } ); + } + #endif /* GNUTLS_VERSION_300 */ + fclose(fd); + conf->cnf_sec_data.ca_file = $3; + CHECK_GNUTLS_DO( conf->cnf_sec_data.ca_file_nr += gnutls_certificate_set_x509_trust_file( + conf->cnf_sec_data.credentials, + conf->cnf_sec_data.ca_file, + GNUTLS_X509_FMT_PEM), + { yyerror (&yylloc, conf, "Error setting CA parameters."); YYERROR; } ); + + } + ; + +tls_crl: TLS_CRL '=' QSTRING ';' + { + FILE * fd; + fd = fopen($3, "rb"); + if (fd == NULL) { + int ret = errno; + TRACE_ERROR("Unable to open CRL file %s for reading: %s", $3, strerror(ret)); + yyerror (&yylloc, conf, "Error on file name"); + YYERROR; + } + #ifdef GNUTLS_VERSION_300 + { + /* We import these CRL in the trust list */ + gnutls_x509_crl_t * crllist; + unsigned int crlcount; + gnutls_datum_t crlfile; + + CHECK_FCT_DO( fd_conf_stream_to_gnutls_datum(fd, &crlfile), + { yyerror (&yylloc, conf, "Error reading CRL file."); YYERROR; } ); + + CHECK_GNUTLS_DO( gnutls_x509_crl_list_import2(&crllist, &crlcount, &crlfile, GNUTLS_X509_FMT_PEM, 0), + { yyerror (&yylloc, conf, "Error importing CRL file."); YYERROR; } ); + free(crlfile.data); + + CHECK_GNUTLS_DO( gnutls_x509_trust_list_add_crls (fd_g_config->cnf_sec_data.trustlist, crllist, crlcount, + GNUTLS_TL_VERIFY_CRL, + 0), + { yyerror (&yylloc, conf, "Error importing CRL in trust list."); YYERROR; } ); + } + #endif /* GNUTLS_VERSION_300 */ + fclose(fd); + conf->cnf_sec_data.crl_file = $3; + CHECK_GNUTLS_DO( gnutls_certificate_set_x509_crl_file( + conf->cnf_sec_data.credentials, + conf->cnf_sec_data.crl_file, + GNUTLS_X509_FMT_PEM), + { yyerror (&yylloc, conf, "Error setting CRL parameters."); YYERROR; } ); + } + ; + +tls_prio: TLS_PRIO '=' QSTRING ';' + { + const char * err_pos = NULL; + conf->cnf_sec_data.prio_string = $3; + CHECK_GNUTLS_DO( gnutls_priority_init( + &conf->cnf_sec_data.prio_cache, + conf->cnf_sec_data.prio_string, + &err_pos), + { yyerror (&yylloc, conf, "Error setting Priority parameter."); + TRACE_ERROR("Error at position : %s", err_pos); + YYERROR; } ); + } + ; + +tls_dh: TLS_DH_BITS '=' INTEGER ';' + { + conf->cnf_sec_data.dh_bits = $3; + } + | TLS_DH_FILE '=' QSTRING ';' + { + FILE * fd; + free(conf->cnf_sec_data.dh_file); + conf->cnf_sec_data.dh_file = $3; + fd = fopen($3, "r"); + if (fd == NULL) { + int ret = errno; + TRACE_ERROR("Unable to open DH file %s for reading: %s", $3, strerror(ret)); + yyerror (&yylloc, conf, "Error on file name"); + YYERROR; + } + fclose(fd); + } + ; diff --git a/plat/diameter/libfdcore/fifo_stats.c b/plat/diameter/libfdcore/fifo_stats.c new file mode 100644 index 0000000..129c743 --- /dev/null +++ b/plat/diameter/libfdcore/fifo_stats.c @@ -0,0 +1,79 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* See include/freeDiameter/libfdcore.h for more information */ +int fd_stat_getstats(enum fd_stat_type stat, struct peer_hdr * peer, + int * current_count, int * limit_count, int * highest_count, long long * total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last) +{ + struct fd_peer * p = (struct fd_peer *)peer; + TRACE_ENTRY( "%d %p %p %p %p %p %p %p %p", stat, peer, current_count, limit_count, highest_count, total_count, total, blocking, last); + + switch (stat) { + case STAT_G_LOCAL: { + CHECK_FCT( fd_fifo_getstats(fd_g_local, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_G_INCOMING: { + CHECK_FCT( fd_fifo_getstats(fd_g_incoming, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_G_OUTGOING: { + CHECK_FCT( fd_fifo_getstats(fd_g_outgoing, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_P_PSM: { + CHECK_PARAMS( CHECK_PEER( peer ) ); + CHECK_FCT( fd_fifo_getstats(p->p_events, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_P_TOSEND: { + CHECK_PARAMS( CHECK_PEER( peer ) ); + CHECK_FCT( fd_fifo_getstats(p->p_tosend, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + default: + return EINVAL; + } + + return 0; +} diff --git a/plat/diameter/libfdcore/freeDiameter-host.h b/plat/diameter/libfdcore/freeDiameter-host.h new file mode 100644 index 0000000..c78f29b --- /dev/null +++ b/plat/diameter/libfdcore/freeDiameter-host.h @@ -0,0 +1,106 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Configuration from compile-time */ +#ifndef FD_IS_CONFIG +#define FD_IS_CONFIG + +#ifdef __cplusplus +extern "C" { +#endif + +/* #undef HAVE_NTOHLL */ +#define HAVE_MALLOC_H +/* #undef HAVE_SIGNALENT_H */ +#define HAVE_AI_ADDRCONFIG +#define HAVE_CLOCK_GETTIME +#define HAVE_STRNDUP +#define HAVE_PTHREAD_BAR + +/* #undef HOST_BIG_ENDIAN */ + +/* #undef DISABLE_SCTP */ +/* #undef DEBUG_SCTP */ +/* #undef DEBUG_WITH_META */ +/* #undef SCTP_USE_MAPPED_ADDRESSES */ +#define SCTP_CONNECTX_4_ARGS +/* #undef SKIP_DLCLOSE */ +/* #undef DIAMID_IDNA_IGNORE */ +/* #undef DIAMID_IDNA_REJECT */ +/* #undef DISABLE_PEER_EXPIRY */ +/* #undef WORKAROUND_ACCEPT_INVALID_VSAI */ +#define GNUTLS_VERSION_210 +#define GNUTLS_VERSION_212 +/* #undef GNUTLS_VERSION_300 */ +/* #undef GNUTLS_VERSION_310 */ + +/* #undef ERRORS_ON_TODO */ +/* #undef DEBUG */ + +#define FD_PROJECT_BINARY "freeDiameterd" +#define FD_PROJECT_NAME "freeDiameter" +#define FD_PROJECT_VERSION_MAJOR 1 +#ifndef FD_PROJECT_VERSION_MAJOR +# define FD_PROJECT_VERSION_MAJOR 0 +#endif /*FD_PROJECT_VERSION_MAJOR*/ +#define FD_PROJECT_VERSION_MINOR 2 +#ifndef FD_PROJECT_VERSION_MINOR +# define FD_PROJECT_VERSION_MINOR 0 +#endif /*FD_PROJECT_VERSION_MINOR*/ +#define FD_PROJECT_VERSION_REV 1 +#ifndef FD_PROJECT_VERSION_REV +# define FD_PROJECT_VERSION_REV 0 +#endif /*FD_PROJECT_VERSION_REV*/ +#define FD_PROJECT_VERSION_API 6 +#ifndef FD_PROJECT_VERSION_API +# define FD_PROJECT_VERSION_API 0 +#endif /*FD_PROJECT_VERSION_API*/ +#define FD_PROJECT_COPYRIGHT "Copyright (c) 2008-2015, WIDE Project (www.wide.ad.jp) and NICT (www.nict.go.jp)" + +#define DEFAULT_CONF_PATH "DEFAULT_CONF_PATH" +#define DEFAULT_EXTENSIONS_PATH "CMAKE_INSTALL_PREFIX/INSTALL_EXTENSIONS_SUFFIX" + +#ifndef FD_DEFAULT_CONF_FILENAME +#define FD_DEFAULT_CONF_FILENAME "freeDiameter.conf" +#endif /* FD_DEFAULT_CONF_FILENAME */ + +/* Maximum number of hooks handlers that can be registered. Make this compilation option if needed */ +#define FD_HOOK_HANDLE_LIMIT 5 + +#ifdef __cplusplus +} +#endif + +#endif /* FD_IS_CONFIG */ diff --git a/plat/diameter/libfdcore/hooks.c b/plat/diameter/libfdcore/hooks.c new file mode 100644 index 0000000..e93d249 --- /dev/null +++ b/plat/diameter/libfdcore/hooks.c @@ -0,0 +1,454 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Structures for the fd_hook_data_hdl management */ +static struct fd_hook_data_hdl { + size_t pmd_size; + void (*pmd_init_cb)(struct fd_hook_permsgdata *); + void (*pmd_fini_cb)(struct fd_hook_permsgdata *); +} HDH_array[FD_HOOK_HANDLE_LIMIT]; +static int max_index = 0; +static pthread_mutex_t HDH_lock = PTHREAD_MUTEX_INITIALIZER; + +/* The structure linked from the msg structure list */ +struct pmd_list_item { + struct fd_list chain; /* this list is ordered by hdl */ + struct fd_hook_data_hdl * hdl; + struct fd_hook_permsgdata { } pmd; /* this data belongs to the extension; we only know the size of it */ +}; + +#define sizeof_pmd(hdl) (((size_t)&((struct pmd_list_item *)0)->pmd) + hdl->pmd_size) + +/* Now a hook registered by an extension */ +struct fd_hook_hdl { + struct fd_list chain[HOOK_LAST+1]; + void (*fd_hook_cb)(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata); + void *regdata; + struct fd_hook_data_hdl *data_hdl; +}; + +/* Array of those hooks */ +struct { + struct fd_list sentinel; + pthread_rwlock_t rwlock; +} HS_array[HOOK_LAST+1]; + +/* Initialize the array of sentinels for the hooks */ +int fd_hooks_init(void) +{ + int i; + for (i=0; i <= HOOK_LAST; i++) { + fd_list_init(&HS_array[i].sentinel, NULL); + CHECK_POSIX( pthread_rwlock_init(&HS_array[i].rwlock, NULL) ); + } + return 0; +} + +/* Get a slot in the array */ +int fd_hook_data_register( + size_t permsgdata_size, + void (*permsgdata_init_cb) (struct fd_hook_permsgdata *), + void (*permsgdata_fini_cb) (struct fd_hook_permsgdata *), + struct fd_hook_data_hdl **new_handle) +{ + int ret = ENOSPC, idx; + TRACE_ENTRY("%zd %p %p %p", permsgdata_size, permsgdata_init_cb, permsgdata_fini_cb, new_handle); + + CHECK_PARAMS( permsgdata_size && new_handle ); + + CHECK_POSIX( pthread_mutex_lock(&HDH_lock) ); + if (max_index < FD_HOOK_HANDLE_LIMIT) { + idx = max_index++; + ret = 0; + } + CHECK_POSIX( pthread_mutex_unlock(&HDH_lock) ); + + if (ret == 0) { + HDH_array[idx].pmd_size = permsgdata_size; + HDH_array[idx].pmd_init_cb = permsgdata_init_cb; + HDH_array[idx].pmd_fini_cb = permsgdata_fini_cb; + *new_handle = &HDH_array[idx]; + } + + return ret; +} + +/* Register a new hook callback */ +int fd_hook_register ( uint32_t type_mask, + void (*fd_hook_cb)(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata), + void *regdata, + struct fd_hook_data_hdl *data_hdl, + struct fd_hook_hdl ** handler ) +{ + struct fd_hook_hdl * newhdl = NULL; + int i; + + TRACE_ENTRY("%x %p %p %p %p", type_mask, fd_hook_cb, regdata, data_hdl, handler); + + CHECK_PARAMS( fd_hook_cb && handler ); + + CHECK_MALLOC( newhdl = malloc(sizeof(struct fd_hook_hdl)) ); + memset(newhdl, 0, sizeof(struct fd_hook_hdl)); + + newhdl->fd_hook_cb = fd_hook_cb; + newhdl->regdata = regdata; + newhdl->data_hdl = data_hdl; + + for (i=0; i <= HOOK_LAST; i++) { + fd_list_init(&newhdl->chain[i], newhdl); + if (type_mask & (1<chain[i]); + CHECK_POSIX( pthread_rwlock_unlock(&HS_array[i].rwlock) ); + } + } + + *handler = newhdl; + return 0; +} + +/* free this hook callback */ +int fd_hook_unregister( struct fd_hook_hdl * handler ) +{ + int i; + TRACE_ENTRY("%p", handler); + CHECK_PARAMS( handler ); + + for (i=0; i <= HOOK_LAST; i++) { + if ( ! FD_IS_LIST_EMPTY(&handler->chain[i])) { + CHECK_POSIX( pthread_rwlock_wrlock(&HS_array[i].rwlock) ); + fd_list_unlink(&handler->chain[i]); + CHECK_POSIX( pthread_rwlock_unlock(&HS_array[i].rwlock) ); + } + } + + free(handler); + + return 0; +} + +/* callback for the libfdproto to free the data associated with a message */ +static void pmdl_free(struct fd_msg_pmdl *pmdl) +{ + /* destroy all the items in the list */ + while (!FD_IS_LIST_EMPTY(&pmdl->sentinel)) { + struct pmd_list_item * li = (struct pmd_list_item *)(pmdl->sentinel.next); + if (li->hdl->pmd_fini_cb) { + (*li->hdl->pmd_fini_cb)(&li->pmd); + } + fd_list_unlink(&li->chain); + free(li); + } + CHECK_POSIX_DO( pthread_mutex_destroy(&pmdl->lock), ); + pmdl->sentinel.o = NULL; +} + +/* Save the list of pmd into the message structure, as well as the callback to free this list */ +void fd_hook_associate(struct msg * msg, struct fd_msg_pmdl * pmdl) +{ + struct fd_msg_pmdl * in_msg; + + CHECK_PARAMS_DO( msg && pmdl, return ); + in_msg = fd_msg_pmdl_get(msg); + ASSERT(in_msg && (in_msg->sentinel.o == NULL)); /* error / already initialized ??? */ + in_msg->sentinel.o = pmdl_free; + /* Now move all items from the pmdl pointer into the initialized list */ + CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), ); + fd_list_move_end(&in_msg->sentinel, &pmdl->sentinel); + CHECK_POSIX_DO( pthread_mutex_unlock(&pmdl->lock), ); + pmdl_free(pmdl); + /* We're done */ +} + +/* Return the location of the permsgdata area corresponding to this handle, after eventually having created it. Return NULL in case of failure */ +static struct fd_hook_permsgdata * get_or_create_pmd(struct fd_msg_pmdl *pmdl, struct fd_hook_hdl * h) +{ + struct fd_hook_permsgdata * ret = NULL; + struct fd_list * li; + + CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), ); + + if (pmdl->sentinel.o == NULL) { + pmdl->sentinel.o = pmdl_free; + } + + /* Search in the list for an item with the same handle. The list is ordered by this handle */ + for (li=pmdl->sentinel.next; li != &pmdl->sentinel; li = li->next) { + struct pmd_list_item * pli = (struct pmd_list_item *) li; + if (pli->hdl == h->data_hdl) + ret = &pli->pmd; + if (pli->hdl >= h->data_hdl) + break; + } + if (!ret) { + /* we need to create a new one and insert before li */ + struct pmd_list_item * pli; + CHECK_MALLOC_DO( pli = malloc(sizeof_pmd(h->data_hdl)), ); + if (pli) { + memset(pli, 0, sizeof_pmd(h->data_hdl)); + fd_list_init(&pli->chain, pli); + pli->hdl = h->data_hdl; + ret = &pli->pmd; + if (h->data_hdl->pmd_init_cb) { + (*h->data_hdl->pmd_init_cb)(ret); + } + fd_list_insert_before(li, &pli->chain); + } + } + + CHECK_POSIX_DO( pthread_mutex_unlock(&pmdl->lock), ); + return ret; +} + +struct fd_hook_permsgdata * fd_hook_get_request_pmd(struct fd_hook_data_hdl *data_hdl, struct msg * answer) +{ + struct msg * qry; + struct fd_msg_pmdl *pmdl; + struct fd_hook_permsgdata * ret = NULL; + struct fd_list * li; + + CHECK_FCT_DO( fd_msg_answ_getq(answer, &qry), return NULL ); + if (!qry) + return NULL; + + pmdl = fd_msg_pmdl_get(qry); + if (!pmdl) + return NULL; + + CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), ); + /* Search in the list for an item with the same handle. The list is ordered by this handle */ + for (li=pmdl->sentinel.next; li != &pmdl->sentinel; li = li->next) { + struct pmd_list_item * pli = (struct pmd_list_item *) li; + if (pli->hdl == data_hdl) + ret = &pli->pmd; + if (pli->hdl >= data_hdl) + break; + } + CHECK_POSIX_DO( pthread_mutex_unlock(&pmdl->lock), ); + return ret; +} + +/* Create a mask */ +uint32_t fd_hook_mask_helper(int dummy, ...) +{ + va_list ap; + uint32_t ret = 0; + int next; + + va_start(ap, dummy); + while ((next = va_arg(ap, int)) >= 0) { + if (next > HOOK_LAST) + break; /* invalid parameter */ + ret |= (1<next) { + struct fd_hook_hdl * h = (struct fd_hook_hdl *)li->o; + struct fd_hook_permsgdata * pmd = NULL; + + /* do we need to handle pmd ? */ + if (h->data_hdl && pmdl) { + pmd = get_or_create_pmd(pmdl, h); + } + + /* Now, call this callback */ + (*h->fd_hook_cb)(type, msg, &peer->p_hdr, other, pmd, h->regdata); + } + } + + pthread_cleanup_pop(0); + + /* done */ + CHECK_POSIX_DO( pthread_rwlock_unlock(&HS_array[type].rwlock), ); + + if (call_default) { + CHECK_POSIX_DO( pthread_mutex_lock(&hook_default_mtx), ); + + pthread_cleanup_push( fd_cleanup_mutex, &hook_default_mtx ); + + /* There was no registered handler, default behavior for this hook */ + switch (type) { + case HOOK_DATA_RECEIVED: { + struct fd_cnx_rcvdata *rcv_data = other; + LOG_A("RCV: %zd bytes", rcv_data->length); + break; + } + + case HOOK_MESSAGE_RECEIVED: { + CHECK_MALLOC_DO(fd_msg_dump_summary(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_D("RCV from '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "", hook_default_buf); + break; + } + + case HOOK_MESSAGE_LOCAL: { + CHECK_MALLOC_DO(fd_msg_dump_full(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_A("Handled to framework for sending: %s", hook_default_buf); + break; + } + + case HOOK_MESSAGE_SENDING: { + LOG_A("SENDING message to '%s'", peer ? peer->p_hdr.info.pi_diamid : ""); + break; + } + + case HOOK_MESSAGE_SENT: { + CHECK_MALLOC_DO(fd_msg_dump_summary(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_D("SENT to '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "", hook_default_buf); + break; + } + + case HOOK_MESSAGE_FAILOVER: { + CHECK_MALLOC_DO(fd_msg_dump_summary(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_D("Failing over message sent to '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "", hook_default_buf); + break; + } + + case HOOK_MESSAGE_PARSING_ERROR: { + if (msg) { + DiamId_t id = NULL; + if (!fd_msg_source_get( msg, &id, NULL )) + id = (DiamId_t)""; + + if (!id) + id = (DiamId_t)""; + + CHECK_MALLOC_DO(fd_msg_dump_treeview(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + + LOG_E("Parsing error: '%s' for the following message received from '%s':", (char *)other, (char *)id); + LOG_SPLIT(FD_LOG_ERROR, " ", hook_default_buf, NULL); + } else { + struct fd_cnx_rcvdata *rcv_data = other; + CHECK_MALLOC_DO(fd_dump_extend_hexdump(&hook_default_buf, &hook_default_len, NULL, rcv_data->buffer, rcv_data->length, 0, 0), break); + LOG_E("Parsing error: cannot parse %zdB buffer from '%s': %s", rcv_data->length, peer ? peer->p_hdr.info.pi_diamid : "", hook_default_buf); + } + break; + } + + case HOOK_MESSAGE_PARSING_ERROR2: { + CHECK_MALLOC_DO(fd_msg_dump_treeview(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + + LOG_E("Returning following message after parsing error:"); + LOG_SPLIT(FD_LOG_ERROR, " ", hook_default_buf, NULL); + break; + } + + case HOOK_MESSAGE_ROUTING_ERROR: { + CHECK_MALLOC_DO(fd_msg_dump_treeview(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_E("Routing error: '%s' for the following message:", (char *)other); + LOG_SPLIT(FD_LOG_ERROR, " ", hook_default_buf, NULL); + break; + } + + case HOOK_MESSAGE_ROUTING_FORWARD: { + CHECK_MALLOC_DO(fd_msg_dump_summary(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_D("FORWARDING: %s", hook_default_buf); + break; + } + + case HOOK_MESSAGE_ROUTING_LOCAL: { + CHECK_MALLOC_DO(fd_msg_dump_summary(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_D("DISPATCHING: %s", hook_default_buf); + break; + } + + case HOOK_MESSAGE_DROPPED: { + CHECK_MALLOC_DO(fd_msg_dump_treeview(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_E("Message discarded ('%s'):", (char *)other); + LOG_SPLIT(FD_LOG_ERROR, " ", hook_default_buf, NULL); + break; + } + + case HOOK_PEER_CONNECT_FAILED: { + if (msg) { + CHECK_MALLOC_DO(fd_msg_dump_full(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + LOG_N("Connection to '%s' failed: '%s'; CER/CEA dump:", peer ? peer->p_hdr.info.pi_diamid : "", (char *)other); + LOG_SPLIT(FD_LOG_NOTICE, " ", hook_default_buf, NULL); + } else { + LOG_D("Connection to '%s' failed: %s", peer ? peer->p_hdr.info.pi_diamid : "", (char *)other); + } + break; + } + + case HOOK_PEER_CONNECT_SUCCESS: { + DiamId_t id = NULL; + if ((!fd_msg_source_get( msg, &id, NULL )) && (id == NULL)) { /* The CEA is locally issued */ + fd_msg_answ_getq(msg, &msg); /* We dump the CER in that case */ + } + CHECK_MALLOC_DO(fd_msg_dump_full(&hook_default_buf, &hook_default_len, NULL, msg, NULL, 0, 1), break); + char protobuf[40]; + if (peer) { + CHECK_FCT_DO(fd_peer_cnx_proto_info(&peer->p_hdr, protobuf, sizeof(protobuf)), break ); + } else { + protobuf[0] = '-'; + protobuf[1] = '\0'; + } + LOG_N("Connected to '%s' (%s), remote capabilities: ", peer ? peer->p_hdr.info.pi_diamid : "", protobuf); + LOG_SPLIT(FD_LOG_NOTICE, " ", hook_default_buf, NULL); + break; + } + + } + + pthread_cleanup_pop(0); + + CHECK_POSIX_DO( pthread_mutex_unlock(&hook_default_mtx), ); + } +} diff --git a/plat/diameter/libfdcore/messages.c b/plat/diameter/libfdcore/messages.c new file mode 100644 index 0000000..db0b518 --- /dev/null +++ b/plat/diameter/libfdcore/messages.c @@ -0,0 +1,452 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +static struct dict_object * dict_avp_SI = NULL; /* Session-Id */ +static struct dict_object * dict_avp_OH = NULL; /* Origin-Host */ +static struct dict_object * dict_avp_OR = NULL; /* Origin-Realm */ +static struct dict_object * dict_avp_EM = NULL; /* Error-Message */ +static struct dict_object * dict_avp_ERH = NULL; /* Error-Reporting-Host */ +static struct dict_object * dict_avp_FAVP= NULL; /* Failed-AVP */ +static struct dict_object * dict_avp_RC = NULL; /* Result-Code */ +struct dict_object * fd_dict_avp_OSI = NULL; /* Origin-State-Id */ +struct dict_object * fd_dict_cmd_CER = NULL; /* Capabilities-Exchange-Request */ +struct dict_object * fd_dict_cmd_DWR = NULL; /* Device-Watchdog-Request */ +struct dict_object * fd_dict_avp_DC = NULL; /* Disconnect-Cause */ +struct dict_object * fd_dict_cmd_DPR = NULL; /* Disconnect-Peer-Request */ + +/* Resolve the dictionary objects */ +int fd_msg_init(void) +{ + TRACE_ENTRY(""); + + /* Initialize the dictionary objects that we may use frequently */ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &dict_avp_SI , ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &dict_avp_OH , ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &dict_avp_OR , ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-State-Id", &fd_dict_avp_OSI , ENOENT) ); + + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &dict_avp_RC , ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Message", &dict_avp_EM , ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &dict_avp_ERH , ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP", &dict_avp_FAVP, ENOENT) ); + + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Disconnect-Cause", &fd_dict_avp_DC , ENOENT) ); + + CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Capabilities-Exchange-Request", &fd_dict_cmd_CER, ENOENT ) ); + CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Device-Watchdog-Request", &fd_dict_cmd_DWR, ENOENT ) ); + CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Disconnect-Peer-Request", &fd_dict_cmd_DPR, ENOENT ) ); + + + return 0; +} + +/* Add Origin-Host, Origin-Realm, Origin-State-Id AVPS at the end of the message */ +int fd_msg_add_origin ( struct msg * msg, int osi ) +{ + union avp_value val; + struct avp * avp_OH = NULL; + struct avp * avp_OR = NULL; + struct avp * avp_OSI = NULL; + + TRACE_ENTRY("%p", msg); + CHECK_PARAMS( msg ); + + /* Create the Origin-Host AVP */ + CHECK_FCT( fd_msg_avp_new( dict_avp_OH, 0, &avp_OH ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + val.os.data = (os0_t)fd_g_config->cnf_diamid; + val.os.len = fd_g_config->cnf_diamid_len; + CHECK_FCT( fd_msg_avp_setvalue( avp_OH, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_OH ) ); + + + /* Create the Origin-Realm AVP */ + CHECK_FCT( fd_msg_avp_new( dict_avp_OR, 0, &avp_OR ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + val.os.data = (os0_t)fd_g_config->cnf_diamrlm; + val.os.len = fd_g_config->cnf_diamrlm_len; + CHECK_FCT( fd_msg_avp_setvalue( avp_OR, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_OR ) ); + + if (osi) { + /* Create the Origin-State-Id AVP */ + CHECK_FCT( fd_msg_avp_new( fd_dict_avp_OSI, 0, &avp_OSI ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + val.u32 = fd_g_config->cnf_orstateid; + CHECK_FCT( fd_msg_avp_setvalue( avp_OSI, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_OSI ) ); + } + + return 0; +} + +/* Create a new Session-Id and add at the beginning of the message. */ +int fd_msg_new_session( struct msg * msg, os0_t opt, size_t optlen ) +{ + union avp_value val; + struct avp * avp = NULL; + struct session * sess = NULL; + os0_t sid; + size_t sidlen; + + TRACE_ENTRY("%p %p %zd", msg, opt, optlen); + CHECK_PARAMS( msg ); + + /* Check there is not already a session in the message */ + CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, msg, &sess, NULL) ); + CHECK_PARAMS( sess == NULL ); + + /* Ok, now create the session */ + CHECK_FCT( fd_sess_new ( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, opt, optlen ) ); + CHECK_FCT( fd_sess_getsid( sess, &sid, &sidlen) ); + + /* Create an AVP to hold it */ + CHECK_FCT( fd_msg_avp_new( dict_avp_SI, 0, &avp ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + val.os.data = sid; + val.os.len = sidlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_FIRST_CHILD, avp ) ); + + /* Save the session associated with the message */ + CHECK_FCT( fd_msg_sess_set( msg, sess) ); + + /* Done! */ + return 0; +} + + +/* Add Result-Code and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */ +int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id ) +{ + union avp_value val; + struct avp * avp_RC = NULL; + struct avp * avp_EM = NULL; + struct avp * avp_ERH = NULL; + struct avp * avp_FAVP= NULL; + uint32_t rc_val = 0; + int set_e_bit=0; + int std_err_msg=0; + + TRACE_ENTRY("%p %s %p %p %d", msg, rescode, errormsg, optavp, type_id); + + CHECK_PARAMS( msg && rescode ); + + /* Find the enum value corresponding to the rescode string, this will give the class of error */ + { + struct dict_object * enum_obj = NULL; + struct dict_enumval_request req; + memset(&req, 0, sizeof(struct dict_enumval_request)); + + /* First, get the enumerated type of the Result-Code AVP (this is fast, no need to cache the object) */ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &(req.type_obj), ENOENT ) ); + + /* Now search for the value given as parameter */ + req.search.enum_name = rescode; + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enum_obj, ENOTSUP) ); + + /* finally retrieve its data */ + CHECK_FCT_DO( fd_dict_getval( enum_obj, &(req.search) ), return EINVAL ); + + /* copy the found value, we're done */ + rc_val = req.search.enum_value.u32; + } + + if (type_id == 1) { + /* Add the Origin-Host and Origin-Realm AVP */ + CHECK_FCT( fd_msg_add_origin ( msg, 0 ) ); + } + + /* Create the Result-Code AVP */ + CHECK_FCT( fd_msg_avp_new( dict_avp_RC, 0, &avp_RC ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + val.u32 = rc_val; + CHECK_FCT( fd_msg_avp_setvalue( avp_RC, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_RC ) ); + + if (type_id == 2) { + /* Add the Error-Reporting-Host AVP */ + + CHECK_FCT( fd_msg_avp_new( dict_avp_ERH, 0, &avp_ERH ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + val.os.data = (uint8_t *)fd_g_config->cnf_diamid; + val.os.len = fd_g_config->cnf_diamid_len; + CHECK_FCT( fd_msg_avp_setvalue( avp_ERH, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ERH ) ); + + } + + /* Now add the optavp in a FailedAVP if provided */ + if (optavp) { + struct avp * optavp_cpy = NULL; + struct avp_hdr *opt_hdr, *optcpy_hdr; + struct dict_object * opt_model = NULL; + int is_grouped = 0; + + /* Create the Failed-AVP AVP */ + CHECK_FCT( fd_msg_avp_new( dict_avp_FAVP, 0, &avp_FAVP ) ); + + /* Was this AVP a grouped one? Best effort only here */ + if (!fd_msg_model ( optavp, &opt_model ) && (opt_model != NULL)) { + struct dict_avp_data dictdata; + CHECK_FCT( fd_dict_getval(opt_model, &dictdata) ); + if (dictdata.avp_basetype == AVP_TYPE_GROUPED) + is_grouped = 1; + } + + /* Create a new AVP with a copy of the data of the invalid or missing AVP */ + optavp_cpy = optavp; + + if (is_grouped) { + CHECK_FCT( fd_msg_avp_new( opt_model, 0, &optavp_cpy) ); + } else { + CHECK_FCT( fd_msg_avp_new( NULL, AVPFL_SET_BLANK_VALUE | AVPFL_SET_RAWDATA_FROM_AVP, &optavp_cpy) ); + + CHECK_FCT( fd_msg_avp_hdr(optavp, &opt_hdr) ); + CHECK_FCT( fd_msg_avp_hdr(optavp_cpy, &optcpy_hdr) ); + memcpy(optcpy_hdr, opt_hdr, sizeof(struct avp_hdr)); + } + + /* Add the passed AVP inside it */ + CHECK_FCT( fd_msg_avp_add( avp_FAVP, MSG_BRW_LAST_CHILD, optavp_cpy ) ); + + /* And add to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_FAVP ) ); + } + + + /* Deal with the 'E' bit and the error message */ + switch (rc_val / 1000) { + case 1: /* Informational */ + case 2: /* Success */ + /* Nothing special here: no E bit, no error message unless one is specified */ + break; + + case 3: /* Protocol Errors */ + set_e_bit = 1; + std_err_msg = 1; + break; + + case 4: /* Transcient Failure */ + case 5: /* Permanent Failure */ + default: + std_err_msg = 1; + break; + + } + + { + struct msg_hdr * hdr = NULL; + + CHECK_FCT( fd_msg_hdr( msg, &hdr ) ); + + if (set_e_bit) + hdr->msg_flags |= CMD_FLAG_ERROR; + else + hdr->msg_flags &= ~ CMD_FLAG_ERROR; + } + + if (std_err_msg || errormsg) { + /* Add the Error-Message AVP */ + + CHECK_FCT( fd_msg_avp_new( dict_avp_EM, 0, &avp_EM ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + + if (errormsg) { + val.os.data = (uint8_t *)errormsg; + val.os.len = strlen(errormsg); + } else { + val.os.data = (uint8_t *)rescode; + val.os.len = strlen(rescode); + } + CHECK_FCT( fd_msg_avp_setvalue( avp_EM, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_EM ) ); + } + + return 0; +} + +static int fd_msg_send_int( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ) +{ + struct msg_hdr *hdr; + DiamId_t diamid; + + /* Save the callback in the message, with the timeout */ + CHECK_FCT( fd_msg_anscb_associate( *pmsg, anscb, data, expirecb, timeout ) ); + + /* If this is a new request, call the HOOK_MESSAGE_LOCAL hook */ + if ( (fd_msg_hdr(*pmsg, &hdr) == 0) + && (hdr->msg_flags & CMD_FLAG_REQUEST) + && (fd_msg_source_get(*pmsg, &diamid, NULL) == 0) + && (diamid == NULL)) { + fd_hook_call(HOOK_MESSAGE_LOCAL, *pmsg, NULL, NULL, fd_msg_pmdl_get(*pmsg)); + } + + /* Post the message in the outgoing queue */ + CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) ); + + return 0; +} + +/* Send a message and optionally register a callback for an answer */ +int fd_msg_send ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data ) +{ + TRACE_ENTRY("%p %p %p", pmsg, anscb, data); + CHECK_PARAMS( pmsg ); + + return fd_msg_send_int(pmsg, anscb, data, NULL, NULL); +} + +/* The variation of the same function with a timeout callback */ +int fd_msg_send_timeout ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ) +{ + TRACE_ENTRY("%p %p %p %p %p", pmsg, anscb, data, expirecb, timeout); + CHECK_PARAMS( pmsg && expirecb && timeout ); + + return fd_msg_send_int(pmsg, anscb, data, expirecb, timeout); +} + + +/* Parse a message against our dictionary, and in case of error log and eventually build the error reply -- returns the parsing status */ +int fd_msg_parse_or_error( struct msg ** msg, struct msg **error) +{ + int ret = 0; + struct msg * m; + struct msg_hdr * hdr = NULL; + struct fd_pei pei; + + TRACE_ENTRY("%p", msg); + + CHECK_PARAMS(msg && *msg && error); + m = *msg; + *error = NULL; + + /* Parse the message against our dictionary */ + ret = fd_msg_parse_rules ( m, fd_g_config->cnf_dict, &pei); + if ((ret != EBADMSG) /* Parsing grouped AVP failed / Conflicting rule found */ + && (ret != ENOTSUP)) /* Command is not supported / Mandatory AVP is not supported */ + return ret; /* 0 or another error */ + + /* Log */ + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, m, NULL, pei.pei_message ?: pei.pei_errcode, fd_msg_pmdl_get(m)); + + CHECK_FCT( fd_msg_hdr(m, &hdr) ); + + /* Now create an answer error if the message is a query */ + if (hdr->msg_flags & CMD_FLAG_REQUEST) { + + /* Create the error message */ + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &m, pei.pei_protoerr ? MSGFL_ANSW_ERROR : 0 ) ); + + /* Set the error code */ + CHECK_FCT( fd_msg_rescode_set(m, pei.pei_errcode, pei.pei_message, pei.pei_avp, 1 ) ); + + /* free the pei AVP to avoid memory leak */ + if (pei.pei_avp_free) { + fd_msg_free(pei.pei_avp); + } + + *msg = NULL; + *error = m; + + } else { + do { /* Rescue error messages */ + struct avp * avp; + union avp_value * rc = NULL; + + /* Search the Result-Code AVP */ + CHECK_FCT_DO( fd_msg_browse(*msg, MSG_BRW_FIRST_CHILD, &avp, NULL), break ); + while (avp) { + struct avp_hdr * ahdr; + CHECK_FCT_DO( fd_msg_avp_hdr( avp, &ahdr ), break ); + + if ((ahdr->avp_code == AC_RESULT_CODE) && (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) ) { + /* Parse this AVP */ + ASSERT( ahdr->avp_value ); + rc = ahdr->avp_value; + break; + } + + /* Go to next AVP */ + CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), break ); + } + + if (rc) { + switch (rc->u32 / 1000) { + case 1: /* 1xxx : Informational */ + case 2: /* 2xxx : Sucess */ + /* In these cases, we want the message to validate the ABNF, so we will discard the bad message */ + break; + + default: /* Other errors */ + /* We let the application decide what to do with the message, we rescue it */ + *error = m; + } + } + } while (0); + } + + return EBADMSG; /* We convert ENOTSUP to EBADMSG as well */ +} diff --git a/plat/diameter/libfdcore/p_ce.c b/plat/diameter/libfdcore/p_ce.c new file mode 100644 index 0000000..807f649 --- /dev/null +++ b/plat/diameter/libfdcore/p_ce.c @@ -0,0 +1,1112 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* This file contains code to handle Capabilities Exchange messages (CER and CEA) and election process */ + +/* Save a connection as peer's principal */ +static int set_peer_cnx(struct fd_peer * peer, struct cnxctx **cnx) +{ + CHECK_PARAMS( peer->p_cnxctx == NULL ); + + /* Save the connection in peer */ + peer->p_cnxctx = *cnx; + *cnx = NULL; + + /* Set the events to be sent to the PSM */ + CHECK_FCT( fd_cnx_recv_setaltfifo(peer->p_cnxctx, peer->p_events) ); + + /* Read the credentials if possible */ + if (fd_cnx_getTLS(peer->p_cnxctx)) { + CHECK_FCT( fd_cnx_getcred(peer->p_cnxctx, &peer->p_hdr.info.runtime.pir_cert_list, &peer->p_hdr.info.runtime.pir_cert_list_size) ); + } + + /* Read the endpoints, maybe used to reconnect to the peer later */ + CHECK_FCT( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints) ); + + /* Read the protocol */ + peer->p_hdr.info.runtime.pir_proto = fd_cnx_getproto(peer->p_cnxctx); + + return 0; +} + +/* Delete the peer connection, and cleanup associated information */ +void fd_p_ce_clear_cnx(struct fd_peer * peer, struct cnxctx ** cnx_kept) +{ + peer->p_hdr.info.runtime.pir_cert_list = NULL; + peer->p_hdr.info.runtime.pir_cert_list_size = 0; + peer->p_hdr.info.runtime.pir_proto = 0; + + if (peer->p_cnxctx) { + if (cnx_kept != NULL) { + *cnx_kept = peer->p_cnxctx; + } else { + fd_cnx_destroy(peer->p_cnxctx); + } + peer->p_cnxctx = NULL; + } +} + +/* Election: compare the Diameter Ids by lexical order, return true if the election is won */ +static __inline__ int election_result(struct fd_peer * peer) +{ + int ret = (strcasecmp(peer->p_hdr.info.pi_diamid, fd_g_config->cnf_diamid) < 0); + if (ret) { + TRACE_DEBUG(INFO, "Election WON against peer '%s'", peer->p_hdr.info.pi_diamid); + } else { + TRACE_DEBUG(INFO, "Election LOST against peer '%s'", peer->p_hdr.info.pi_diamid); + } + return ret; +} + +/* Add AVPs about local information in a CER or CEA */ +static int add_CE_info(struct msg *msg, struct cnxctx * cnx, int isi_tls, int isi_none) +{ + struct dict_object * dictobj = NULL; + struct avp * avp = NULL; + union avp_value val; + struct fd_list *li; + + /* Add the Origin-* AVPs */ + CHECK_FCT( fd_msg_add_origin ( msg, 1 ) ); + + /* Find the model for Host-IP-Address AVP */ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Host-IP-Address", &dictobj, ENOENT ) ); + + /* Add the AVP(s) -- not sure what is the purpose... We could probably only add the primary one ? */ + for (li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp ) ); + CHECK_FCT( fd_msg_avp_value_encode ( &ep->ss, avp ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + } + + /* Vendor-Id, Product-Name, and Firmware-Revision AVPs */ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Vendor-Id", &dictobj, ENOENT ) ); + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp ) ); + val.u32 = MY_VENDOR_ID; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Product-Name", &dictobj, ENOENT ) ); + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp ) ); + val.os.data = (unsigned char *)FD_PROJECT_NAME; + val.os.len = strlen(FD_PROJECT_NAME); + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Firmware-Revision", &dictobj, ENOENT ) ); + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp ) ); + val.u32 = (uint32_t)(FD_PROJECT_VERSION_MAJOR * 10000 + FD_PROJECT_VERSION_MINOR * 100 + FD_PROJECT_VERSION_REV); + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + + + /* Add the Inband-Security-Id AVP if needed */ + if (isi_tls || isi_none) { + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Inband-Security-Id", &dictobj, ENOENT ) ); + + if (isi_none) { + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp ) ); + val.u32 = ACV_ISI_NO_INBAND_SECURITY; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + } + + if (isi_tls) { + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp ) ); + val.u32 = ACV_ISI_TLS; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + } + } + + /* List of local applications */ + { + struct dict_object * dictobj_auth = NULL; + struct dict_object * dictobj_acct = NULL; + struct dict_object * dictobj_vid = NULL; + + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Vendor-Specific-Application-Id", &dictobj, ENOENT ) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Vendor-Id", &dictobj_vid, ENOENT ) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &dictobj_auth, ENOENT ) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Application-Id", &dictobj_acct, ENOENT ) ); + + for (li = fd_g_config->cnf_apps.next; li != &fd_g_config->cnf_apps; li = li->next) { + struct fd_app * a = (struct fd_app *)(li); + + if (a->flags.auth) { + CHECK_FCT( fd_msg_avp_new ( dictobj_auth, 0, &avp ) ); + val.u32 = a->appid = 4; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + if (a->vndid != 0) { + struct avp * avp2 = NULL; + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp2 ) ); + CHECK_FCT( fd_msg_avp_add( avp2, MSG_BRW_LAST_CHILD, avp ) ); + avp = avp2; + CHECK_FCT( fd_msg_avp_new ( dictobj_vid, 0, &avp2 ) ); + val.u32 = a->vndid; + CHECK_FCT( fd_msg_avp_setvalue( avp2, &val ) ); + CHECK_FCT( fd_msg_avp_add( avp, MSG_BRW_LAST_CHILD, avp2 ) ); + } + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + } + if (a->flags.acct) { + CHECK_FCT( fd_msg_avp_new ( dictobj_acct, 0, &avp ) ); + val.u32 = a->appid; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + if (a->vndid != 0) { + struct avp * avp2 = NULL; + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp2 ) ); + CHECK_FCT( fd_msg_avp_add( avp2, MSG_BRW_LAST_CHILD, avp ) ); + avp = avp2; + CHECK_FCT( fd_msg_avp_new ( dictobj_vid, 0, &avp2 ) ); + val.u32 = a->vndid; + CHECK_FCT( fd_msg_avp_setvalue( avp2, &val ) ); + CHECK_FCT( fd_msg_avp_add( avp, MSG_BRW_LAST_CHILD, avp2 ) ); + } + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + } + } + + /* do not forget the relay application */ + if (! fd_g_config->cnf_flags.no_fwd) { + CHECK_FCT( fd_msg_avp_new ( dictobj_auth, 0, &avp ) ); + val.u32 = AI_RELAY; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + } + } + + /* Add the list of supported vendors */ + { + uint32_t * array = fd_dict_get_vendorid_list(fd_g_config->cnf_dict); + if (array) { + int i = 0; + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Supported-Vendor-Id", &dictobj, ENOENT ) ); + + while (array[i] != 0) { + CHECK_FCT( fd_msg_avp_new ( dictobj, 0, &avp ) ); + val.u32 = array[i]; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + i++; + } + + free(array); + } + } + + return 0; +} + +/* Remove any information saved from a previous CER/CEA exchange */ +static void cleanup_remote_CE_info(struct fd_peer * peer) +{ + /* free linked information */ + free(peer->p_hdr.info.runtime.pir_realm); + free(peer->p_hdr.info.runtime.pir_prodname); + while (!FD_IS_LIST_EMPTY(&peer->p_hdr.info.runtime.pir_apps)) { + struct fd_list * li = peer->p_hdr.info.runtime.pir_apps.next; + fd_list_unlink(li); + free(li); + } + /* note: pir_cert_list needs not be freed (belongs to gnutls) */ + + /* cleanup the area */ + memset(&peer->p_hdr.info.runtime, 0, sizeof(peer->p_hdr.info.runtime)); + + /* reinit the list */ + fd_list_init(&peer->p_hdr.info.runtime.pir_apps, peer); + + /* Remove previously advertised endpoints */ + fd_ep_clearflags( &peer->p_hdr.info.pi_endpoints, EP_FL_ADV ); +} + +/* Extract information sent by the remote peer and save it in our peer structure */ +static int save_remote_CE_info(struct msg * msg, struct fd_peer * peer, struct fd_pei * error, uint32_t *rc) +{ + struct avp * avp = NULL; + + cleanup_remote_CE_info(peer); + + CHECK_FCT( fd_msg_browse( msg, MSG_BRW_FIRST_CHILD, &avp, NULL) ); + + /* Loop on all AVPs and save what we are interrested into */ + while (avp) { + struct avp_hdr * hdr; + + CHECK_FCT( fd_msg_avp_hdr( avp, &hdr ) ); + + if (hdr->avp_flags & AVP_FLAG_VENDOR) { + /* Ignore all vendor-specific AVPs in CER/CEA because we don't support any currently */ + LOG_A("Ignored a vendor-specific AVP in CER / CEA"); + goto next; + } + + switch (hdr->avp_code) { + case AC_RESULT_CODE: /* Result-Code */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + if (rc) + *rc = hdr->avp_value->u32; + break; + + case AC_ORIGIN_HOST: /* Origin-Host */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + /* We check that the value matches what we know, otherwise disconnect the peer */ + if (fd_os_almostcasesrch(hdr->avp_value->os.data, hdr->avp_value->os.len, + peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, NULL)) { + TRACE_DEBUG(INFO, "Received a message with Origin-Host set to '%.*s' while expecting '%s'", + (int)hdr->avp_value->os.len, hdr->avp_value->os.data, peer->p_hdr.info.pi_diamid); + error->pei_errcode = "DIAMETER_AVP_NOT_ALLOWED"; + error->pei_message = "Your Origin-Host value does not match my configuration."; + error->pei_avp = avp; + return EINVAL; + } + + break; + + case AC_ORIGIN_REALM: /* Origin-Realm */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + /* In case of multiple AVPs */ + if (peer->p_hdr.info.runtime.pir_realm) { + TRACE_DEBUG(INFO, "Multiple instances of the Origin-Realm AVP"); + error->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; + error->pei_message = "I found several Origin-Realm AVPs"; + error->pei_avp = avp; + return EINVAL; + } + + /* If the octet string contains a \0 */ + if (!fd_os_is_valid_DiameterIdentity(hdr->avp_value->os.data, hdr->avp_value->os.len)) { + error->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; + error->pei_message = "Your Origin-Realm contains invalid characters."; + error->pei_avp = avp; + return EINVAL; + } + + /* Save the value */ + CHECK_MALLOC( peer->p_hdr.info.runtime.pir_realm = os0dup( hdr->avp_value->os.data, hdr->avp_value->os.len ) ); + peer->p_hdr.info.runtime.pir_realmlen = hdr->avp_value->os.len; + break; + + case AC_HOST_IP_ADDRESS: /* Host-IP-Address */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + { + sSS ss; + + /* Get the sockaddr value */ + memset(&ss, 0, sizeof(ss)); + CHECK_FCT_DO( fd_msg_avp_value_interpret( avp, &ss), + { + /* in case of error, assume the AVP value was wrong */ + error->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; + error->pei_avp = avp; + return EINVAL; + } ); + + /* Save this endpoint in the list as advertized */ + CHECK_FCT( fd_ep_add_merge( &peer->p_hdr.info.pi_endpoints, (sSA *)&ss, sizeof(sSS), EP_FL_ADV ) ); + } + break; + + case AC_VENDOR_ID: /* Vendor-Id */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + /* In case of multiple AVPs */ + if (peer->p_hdr.info.runtime.pir_vendorid) { + TRACE_DEBUG(INFO, "Multiple instances of the Vendor-Id AVP"); + error->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; + error->pei_message = "I found several Vendor-Id AVPs"; + error->pei_avp = avp; + return EINVAL; + } + + peer->p_hdr.info.runtime.pir_vendorid = hdr->avp_value->u32; + break; + + case AC_PRODUCT_NAME: /* Product-Name */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + /* In case of multiple AVPs */ + if (peer->p_hdr.info.runtime.pir_prodname) { + TRACE_DEBUG(INFO, "Multiple instances of the Product-Name AVP"); + error->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; + error->pei_message = "I found several Product-Name AVPs"; + error->pei_avp = avp; + return EINVAL; + } + + CHECK_MALLOC( peer->p_hdr.info.runtime.pir_prodname = calloc( hdr->avp_value->os.len + 1, 1 ) ); + memcpy(peer->p_hdr.info.runtime.pir_prodname, hdr->avp_value->os.data, hdr->avp_value->os.len); + break; + + case AC_ORIGIN_STATE_ID: /* Origin-State-Id */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + /* In case of multiple AVPs */ + if (peer->p_hdr.info.runtime.pir_orstate) { + TRACE_DEBUG(INFO, "Multiple instances of the Origin-State-Id AVP"); + error->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; + error->pei_message = "I found several Origin-State-Id AVPs"; + error->pei_avp = avp; + return EINVAL; + } + + peer->p_hdr.info.runtime.pir_orstate = hdr->avp_value->u32; + break; + + case AC_SUPPORTED_VENDOR_ID: /* Supported-Vendor-Id */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + TRACE_DEBUG(FULL, "'%s' claims support for a subset of vendor %d features.", peer->p_hdr.info.pi_diamid, hdr->avp_value->u32); + /* not that it makes a difference for us... + -- if an application actually needs this info, we could save it somewhere. + */ + break; + + case AC_VENDOR_SPECIFIC_APPLICATION_ID: /* Vendor-Specific-Application-Id (grouped)*/ + { + struct avp * inavp = NULL; + vendor_id_t vid = 0; + application_id_t auth_aid = 0; + application_id_t acct_aid = 0; + int invalid=0; + + /* get the first child AVP */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &inavp, NULL) ); + + while (inavp) { + struct avp_hdr * inhdr; + CHECK_FCT( fd_msg_avp_hdr( inavp, &inhdr ) ); + + if (inhdr->avp_flags & AVP_FLAG_VENDOR) { + LOG_A("Ignored a vendor AVP inside Vendor-Specific-Application-Id AVP"); + goto innext; + } + + if (inhdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto innext; + } + switch (inhdr->avp_code) { + case AC_VENDOR_ID: /* Vendor-Id */ +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + if (vid != 0) + invalid++; /* We already had one such AVP. This is invalid according to RFC6733 but not RFC3588 (but there is an erratum) */ +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + vid = inhdr->avp_value->u32; + break; + case AC_AUTH_APPLICATION_ID: /* Auth-Application-Id */ + if (auth_aid != 0) + invalid++; /* We already had one such AVP */ +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + if (acct_aid != 0) + invalid++; /* Only 1 *-Application-Id AVP is allowed */ +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + auth_aid = inhdr->avp_value->u32; + break; + case AC_ACCT_APPLICATION_ID: /* Acct-Application-Id */ + if (acct_aid != 0) + invalid++; /* We already had one such AVP */ +#ifndef WORKAROUND_ACCEPT_INVALID_VSAI + if (auth_aid != 0) + invalid++; /* Only 1 *-Application-Id AVP is allowed */ +#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */ + acct_aid = inhdr->avp_value->u32; + break; + /* ignore other AVPs */ + } + + if (invalid) { + TRACE_DEBUG(FULL, "Invalid Vendor-Specific-Application-Id AVP received"); + error->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; + error->pei_avp = avp; + return EINVAL; + } + + innext: + /* Go to next in AVP */ + CHECK_FCT( fd_msg_browse(inavp, MSG_BRW_NEXT, &inavp, NULL) ); + } + + /* Add entry in the list */ + if (auth_aid) { + CHECK_FCT( fd_app_merge(&peer->p_hdr.info.runtime.pir_apps, auth_aid, vid, 1, 0) ); + } + if (acct_aid) { + CHECK_FCT( fd_app_merge(&peer->p_hdr.info.runtime.pir_apps, acct_aid, vid, 0, 1) ); + } + } + break; + + case AC_AUTH_APPLICATION_ID: /* Auth-Application-Id */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + if (hdr->avp_value->u32 == AI_RELAY) { + peer->p_hdr.info.runtime.pir_relay = 1; + } else { + CHECK_FCT( fd_app_merge(&peer->p_hdr.info.runtime.pir_apps, hdr->avp_value->u32, 0, 1, 0) ); + } + break; + + case AC_ACCT_APPLICATION_ID: /* Acct-Application-Id */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + if (hdr->avp_value->u32 == AI_RELAY) { + /* Not clear if the relay application can be inside this AVP... */ + peer->p_hdr.info.runtime.pir_relay = 1; + } else { + CHECK_FCT( fd_app_merge(&peer->p_hdr.info.runtime.pir_apps, hdr->avp_value->u32, 0, 0, 1) ); + } + break; + + case AC_FIRMWARE_REVISION: /* Firmware-Revision */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + + peer->p_hdr.info.runtime.pir_firmrev = hdr->avp_value->u32; + break; + + case AC_INBAND_SECURITY_ID: /* Inband-Security-Id */ + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an AVP (code %x) with unset value in CER/CEA", hdr->avp_code); + ASSERT(0); /* To check if this really happens, and understand why... */ + goto next; + } + if (hdr->avp_value->u32 >= 32 ) { + error->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; + error->pei_message = "I don't support this Inband-Security-Id value (yet)."; + error->pei_avp = avp; + return EINVAL; + } + peer->p_hdr.info.runtime.pir_isi |= (1 << hdr->avp_value->u32); + break; + } + +next: + /* Go to next AVP */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); + } + + return 0; +} + +/* Create a CER message for sending */ +static int create_CER(struct fd_peer * peer, struct cnxctx * cnx, struct msg ** cer) +{ + int isi_tls = 0; + int isi_none = 0; + + /* Find CER dictionary object and create an instance */ + CHECK_FCT( fd_msg_new ( fd_dict_cmd_CER, MSGFL_ALLOC_ETEID, cer ) ); + + /* Do we need Inband-Security-Id AVPs ? If we're already using TLS, we don't... */ + if (!fd_cnx_getTLS(cnx)) { + isi_none = peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE; /* we add it even if the peer does not use the old mechanism, it is impossible to distinguish */ + + if (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD) { + if (fd_g_config->cnf_sec_data.tls_disabled) { + LOG_N("TLS disabled locally, so Inband-Security-Id (TLS) not included for peer %s", peer->p_hdr.info.pi_diamid); + } else { + isi_tls = 1; + } + } + } + + /* Add the information about the local peer */ + CHECK_FCT( add_CE_info(*cer, cnx, isi_tls, isi_none) ); + + /* Done! */ + return 0; +} + + +/* Continue with the initiator side */ +static int to_waitcea(struct fd_peer * peer, struct cnxctx * cnx) +{ + /* We sent a CER on the connection, set the event queue so that we receive the CEA */ + CHECK_FCT( set_peer_cnx(peer, &cnx) ); + + /* Change state and reset the timer */ + CHECK_FCT( fd_psm_change_state(peer, STATE_WAITCEA) ); + fd_psm_next_timeout(peer, 0, CEA_TIMEOUT); + + return 0; +} + +/* Reject an incoming connection attempt */ +static void receiver_reject(struct cnxctx ** recv_cnx, struct msg ** cer, struct fd_pei * error) +{ + struct msg_hdr * hdr = NULL; + + /* Create and send the CEA with appropriate error code */ + CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, cer, MSGFL_ANSW_ERROR ), goto destroy ); + CHECK_FCT_DO( fd_msg_rescode_set(*cer, error->pei_errcode, error->pei_message, error->pei_avp, 0 ), goto destroy ); + CHECK_FCT_DO( fd_msg_hdr( *cer, &hdr ), goto destroy ); + if (hdr->msg_flags & CMD_FLAG_ERROR) { + /* Generic error format, just add the origin AVPs */ + CHECK_FCT_DO( fd_msg_add_origin ( *cer, 1 ), goto destroy ); + } else { + /* Add other AVPs to be compliant with the ABNF */ + CHECK_FCT_DO( add_CE_info(*cer, *recv_cnx, 0, 0), goto destroy ); + } + CHECK_FCT_DO( fd_out_send(cer, *recv_cnx, NULL, 0), goto destroy ); + + if (error->pei_avp_free) { + fd_msg_free(error->pei_avp); + } + + /* And now destroy this connection */ +destroy: + fd_cnx_destroy(*recv_cnx); + *recv_cnx = NULL; + if (*cer) { + fd_hook_call(HOOK_MESSAGE_DROPPED, *cer, NULL, "An error occurred while rejecting this CER.", fd_msg_pmdl_get(*cer)); + fd_msg_free(*cer); + *cer = NULL; + } +} + +/* We have established a new connection to the remote peer, send CER and eventually process the election */ +int fd_p_ce_handle_newcnx(struct fd_peer * peer, struct cnxctx * initiator) +{ + struct msg * cer = NULL; + + /* Send CER on the new connection */ + CHECK_FCT( create_CER(peer, initiator, &cer) ); + CHECK_FCT( fd_out_send(&cer, initiator, peer, 0) ); + + /* Are we doing an election ? */ + if (fd_peer_getstate(peer) == STATE_WAITCNXACK_ELEC) { + if (election_result(peer)) { + /* Close initiator connection */ + fd_cnx_destroy(initiator); + + LOG_D("%s: Election lost on outgoing connection, closing and answering CEA on incoming connection.", peer->p_hdr.info.pi_diamid); + + /* Process with the receiver side */ + CHECK_FCT( fd_p_ce_process_receiver(peer) ); + + } else { + struct fd_pei pei; + memset(&pei, 0, sizeof(pei)); + pei.pei_errcode = "ELECTION_LOST"; + pei.pei_message = "Please answer my CER instead, you won the election."; + LOG_D("%s: Election lost on incoming connection, closing and waiting for CEA on outgoing connection.", peer->p_hdr.info.pi_diamid); + + /* Answer an ELECTION LOST to the receiver side */ + receiver_reject(&peer->p_receiver, &peer->p_cer, &pei); + CHECK_FCT( to_waitcea(peer, initiator) ); + } + } else { + /* No election (yet) */ + CHECK_FCT( to_waitcea(peer, initiator) ); + } + + return 0; +} + +/* We have received a Capabilities Exchange message on the peer connection */ +int fd_p_ce_msgrcv(struct msg ** msg, int req, struct fd_peer * peer) +{ + uint32_t rc = 0; + int st; + struct fd_pei pei; + + TRACE_ENTRY("%p %p", msg, peer); + CHECK_PARAMS( msg && *msg && CHECK_PEER(peer) ); + + /* The only valid situation where we are called is in WAITCEA and we receive a CEA (we may have won an election) */ + + /* Note : to implement Capabilities Update, we would need to change here */ + + /* If it is a CER, just reply an error */ + if (req) { + /* Create the error message */ + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, MSGFL_ANSW_ERROR ) ); + + /* Set the error code */ + CHECK_FCT( fd_msg_rescode_set(*msg, "DIAMETER_UNABLE_TO_COMPLY", "No CER allowed in current state", NULL, 1 ) ); + + /* msg now contains an answer message to send back */ + CHECK_FCT_DO( fd_out_send(msg, NULL, peer, 0), /* In case of error the message has already been dumped */ ); + } + + /* If the state is not WAITCEA, just discard the message */ + if (req || ((st = fd_peer_getstate(peer)) != STATE_WAITCEA)) { + if (*msg) { + /* In such case, just discard the message */ + char buf[128]; + snprintf(buf, sizeof(buf), "Received while peer state machine was in state %s.", STATE_STR(st)); + fd_hook_call(HOOK_MESSAGE_DROPPED, *msg, peer, buf, fd_msg_pmdl_get(*msg)); + + CHECK_FCT_DO( fd_msg_free(*msg), /* continue */); + *msg = NULL; + } + + return 0; + } + + memset(&pei, 0, sizeof(pei)); + + /* Save info from the CEA into the peer */ + CHECK_FCT_DO( save_remote_CE_info(*msg, peer, &pei, &rc), + { + fd_hook_call(HOOK_PEER_CONNECT_FAILED, *msg, peer, "An error occurred while processing incoming CEA.", NULL); + goto cleanup; + } ); + + /* Check the Result-Code */ + switch (rc) { + case ER_DIAMETER_SUCCESS: + /* Log success */ + fd_hook_call(HOOK_PEER_CONNECT_SUCCESS, *msg, peer, NULL, NULL); + + /* Dispose of the message, we don't need it anymore */ + CHECK_FCT_DO( fd_msg_free(*msg), /* continue */ ); + *msg = NULL; + + /* No problem, we can continue */ + break; + + case ER_DIAMETER_TOO_BUSY: + /* Retry later */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, *msg, peer, "Remote peer is too busy", NULL); + fd_psm_cleanup(peer, 0); + fd_psm_next_timeout(peer, 0, 300); + return 0; + + case ER_ELECTION_LOST: + /* Ok, just wait for a little while for the CER to be processed on the other connection. */ + TRACE_DEBUG(FULL, "Peer %s replied a CEA with Result-Code AVP ELECTION_LOST, waiting for events.", peer->p_hdr.info.pi_diamid); + return 0; + + default: + /* In any other case, we abort all attempts to connect to this peer */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, *msg, peer, "CEA with unexpected error code", NULL); + return EINVAL; + } + + + /* Handshake if needed, start clear otherwise */ + if ( ! fd_cnx_getTLS(peer->p_cnxctx) ) { + int todo = peer->p_hdr.info.config.pic_flags.sec & peer->p_hdr.info.runtime.pir_isi ; + /* Special case: if the peer did not send a ISI AVP */ + if (peer->p_hdr.info.runtime.pir_isi == 0) + todo = peer->p_hdr.info.config.pic_flags.sec; + + if (todo == PI_SEC_NONE) { + /* Ok for clear connection */ + TRACE_DEBUG(INFO, "%s: No TLS protection negotiated with peer '%s'.", __FUNCTION__, peer->p_hdr.info.pi_diamid); + CHECK_FCT( fd_cnx_start_clear(peer->p_cnxctx, 1) ); + + } else if (fd_g_config->cnf_sec_data.tls_disabled) { + LOG_E("Clear connection with remote peer '%s' is not (explicitly) allowed, and TLS is disabled. Giving up...", peer->p_hdr.info.pi_diamid); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "TLS is disabled and peer is not configured for IPsec", NULL); + goto cleanup; + + } else { + fd_psm_change_state(peer, STATE_OPEN_HANDSHAKE); + CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_CLIENT, ALGO_HANDSHAKE_3436, peer->p_hdr.info.config.pic_priority, NULL), + { + /* Handshake failed ... */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "TLS handshake failed after CER/CEA exchange", NULL); + goto cleanup; + } ); + + /* Retrieve the credentials */ + CHECK_FCT( fd_cnx_getcred(peer->p_cnxctx, &peer->p_hdr.info.runtime.pir_cert_list, &peer->p_hdr.info.runtime.pir_cert_list_size) ); + } + } + + /* Move to next state */ + if (peer->p_flags.pf_cnx_pb) { + fd_psm_change_state(peer, STATE_REOPEN ); + CHECK_FCT( fd_p_dw_reopen(peer) ); + } else { + fd_psm_change_state(peer, STATE_OPEN ); + fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw); + } + + return 0; + +cleanup: + fd_p_ce_clear_cnx(peer, NULL); + + /* Send the error to the peer */ + CHECK_FCT( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL) ); + + return 0; +} + +/* Handle the receiver side to go to OPEN or OPEN_NEW state (any election is resolved) */ +int fd_p_ce_process_receiver(struct fd_peer * peer) +{ + struct fd_pei pei; + struct msg * msg = NULL; + int isi = 0; + int fatal = 0; + int tls_sync=0; + + TRACE_ENTRY("%p", peer); + + CHECK_FCT_DO( set_peer_cnx(peer, &peer->p_receiver), + { + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Error saving the incoming connection in the peer structure", NULL); + return __ret__; + } ); + msg = peer->p_cer; + peer->p_cer = NULL; + + memset(&pei, 0, sizeof(pei)); + + /* Parse the content of the received CER */ + CHECK_FCT_DO( save_remote_CE_info(msg, peer, &pei, NULL), goto error_abort ); + + /* Validate the realm if needed */ + if (peer->p_hdr.info.config.pic_realm) { + size_t len = strlen(peer->p_hdr.info.config.pic_realm); + if (fd_os_almostcasesrch(peer->p_hdr.info.config.pic_realm, len, peer->p_hdr.info.runtime.pir_realm, peer->p_hdr.info.runtime.pir_realmlen, NULL)) { + TRACE_DEBUG(INFO, "Rejected CER from peer '%s', realm mismatch with configured value (returning DIAMETER_UNKNOWN_PEER).", peer->p_hdr.info.pi_diamid); + pei.pei_errcode = "DIAMETER_UNKNOWN_PEER"; /* maybe AVP_NOT_ALLOWED would be better fit? */ + goto error_abort; + } + } + + /* Save the credentials if handshake already occurred */ + if ( fd_cnx_getTLS(peer->p_cnxctx) ) { + CHECK_FCT( fd_cnx_getcred(peer->p_cnxctx, &peer->p_hdr.info.runtime.pir_cert_list, &peer->p_hdr.info.runtime.pir_cert_list_size) ); + } + + /* Validate the peer if needed */ + #if 0 + if (peer->p_flags.pf_responder) { + int res = fd_peer_validate( peer ); + if (res < 0) { + TRACE_DEBUG(INFO, "Rejected CER from peer '%s', validation failed (returning DIAMETER_UNKNOWN_PEER).", peer->p_hdr.info.pi_diamid); + pei.pei_errcode = "DIAMETER_UNKNOWN_PEER"; + goto error_abort; + } + CHECK_FCT( res ); + } + #endif + + /* Check if we have common applications */ + if ( fd_g_config->cnf_flags.no_fwd && (! peer->p_hdr.info.runtime.pir_relay) ) { + int got_common; + CHECK_FCT( fd_app_check_common( &fd_g_config->cnf_apps, &peer->p_hdr.info.runtime.pir_apps, &got_common) ); + if (!got_common) { + TRACE_DEBUG(INFO, "No common application with peer '%s', sending DIAMETER_NO_COMMON_APPLICATION", peer->p_hdr.info.pi_diamid); + pei.pei_errcode = "DIAMETER_NO_COMMON_APPLICATION"; + fatal = 1; + goto error_abort; + } + } + + /* Do we agree on ISI ? */ + if ( ! fd_cnx_getTLS(peer->p_cnxctx) ) { + + /* In case of responder, the validate callback must have set the config.pic_flags.sec value already */ + + /* First case: we are not using old mechanism: ISI are deprecated, we ignore it. */ + if ( ! (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD)) { + /* Just check then that the peer configuration allows for IPsec protection */ + if (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE) { + isi = PI_SEC_NONE; + } else { + /* otherwise, we should have already been protected. Reject */ + TRACE_DEBUG(INFO, "Non TLS-protected CER/CEA exchanges are not allowed with this peer, rejecting."); + #if 1 + isi = PI_SEC_NONE; + TRACE_DEBUG(INFO, "SET PI_SEC_NONE to accept all clients."); + #endif + } + } else { + /* The old mechanism is allowed with this peer. Now, look into the ISI AVP values */ + + /* In case no ISI was present anyway: */ + if (!peer->p_hdr.info.runtime.pir_isi) { + TRACE_DEBUG(INFO, "Inband-Security-Id AVP is missing in received CER."); + if (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE) { + isi = PI_SEC_NONE; + TRACE_DEBUG(INFO, "IPsec protection allowed by configuration, allowing this mechanism to be used."); + } else { + /* otherwise, we should have already been protected. Reject */ + TRACE_DEBUG(INFO, "Rejecting the peer connection (please allow IPsec here or configure TLS in the remote peer)."); + } + } else { + /* OK, the remote peer did send the ISI AVP. */ + if ((peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE) && (peer->p_hdr.info.runtime.pir_isi & PI_SEC_NONE)) { + /* We have allowed IPsec */ + isi = PI_SEC_NONE; + } else if (fd_g_config->cnf_sec_data.tls_disabled) { + /* We can agree on TLS */ + TRACE_DEBUG(INFO, "Remote peer is not allowed for IPsec and TLS is disabled.");; + } else if (peer->p_hdr.info.runtime.pir_isi & PI_SEC_TLS_OLD) { + /* We can agree on TLS */ + isi = PI_SEC_TLS_OLD; + } else { + TRACE_DEBUG(INFO, "Remote peer requested IPsec protection, but local configuration forbids it."); + } + } + } + + /* If we did not find an agreement */ + if (!isi) { + TRACE_DEBUG(INFO, "No common security mechanism with '%s', sending DIAMETER_NO_COMMON_SECURITY", peer->p_hdr.info.pi_diamid); + pei.pei_errcode = "DIAMETER_NO_COMMON_SECURITY"; + fatal = 1; + goto error_abort; + } + + /* Do not send the ISI IPsec if we are using the new mechanism */ + if ((isi == PI_SEC_NONE) && (! (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD))) + isi = 0; + } else if (peer->p_hdr.info.runtime.pir_isi & PI_SEC_TLS_OLD) { + /* Seem some weird peers are sending the Inband-Security-Id AVP on the secure port... No harm */ + isi = PI_SEC_TLS_OLD; + } + + /* Reply a CEA */ + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msg, 0 ) ); + CHECK_FCT( fd_msg_rescode_set(msg, "DIAMETER_SUCCESS", NULL, NULL, 0 ) ); + CHECK_FCT( add_CE_info(msg, peer->p_cnxctx, isi & PI_SEC_TLS_OLD, isi & PI_SEC_NONE) ); + + /* The connection is complete, but we may still need TLS handshake */ + fd_hook_call(HOOK_PEER_CONNECT_SUCCESS, msg, peer, NULL, NULL); + + CHECK_FCT( fd_out_send(&msg, peer->p_cnxctx, peer, 0 ) ); + + /* Handshake if needed */ + if (isi & PI_SEC_TLS_OLD) { + fd_psm_change_state(peer, STATE_OPEN_HANDSHAKE); + CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, peer->p_hdr.info.config.pic_priority, NULL), + { + /* Handshake failed ... */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "TLS handshake failed after CER/CEA exchange", NULL); + goto cleanup; + } ); + + /* Retrieve the credentials */ + CHECK_FCT_DO( fd_cnx_getcred(peer->p_cnxctx, &peer->p_hdr.info.runtime.pir_cert_list, &peer->p_hdr.info.runtime.pir_cert_list_size), + { + /* Error ... */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Unable to retrieve remote credentials after TLS handshake", NULL); + goto cleanup; + } ); + + + /* Call second validation callback if needed */ + if (peer->p_cb2) { + TRACE_DEBUG(FULL, "Calling second validation callback for %s", peer->p_hdr.info.pi_diamid); + CHECK_FCT_DO( (*peer->p_cb2)( &peer->p_hdr.info ), + { + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Validation callback rejected the peer after handshake", NULL); + CHECK_FCT( fd_psm_terminate( peer, "DO_NOT_WANT_TO_TALK_TO_YOU" ) ); + return 0; + } ); + } + tls_sync = 1; + } else { + if ( ! fd_cnx_getTLS(peer->p_cnxctx) ) { + TRACE_DEBUG(INFO, "%s: No TLS protection negotiated with peer '%s'.", __FUNCTION__, peer->p_hdr.info.pi_diamid); + CHECK_FCT( fd_cnx_start_clear(peer->p_cnxctx, 1) ); + } + } + + /* Move to OPEN or REOPEN state */ + if (peer->p_flags.pf_cnx_pb) { + fd_psm_change_state(peer, STATE_REOPEN ); + CHECK_FCT( fd_p_dw_reopen(peer) ); + } else { + if ((!tls_sync) && (fd_cnx_is_unordered_delivery_supported(peer->p_cnxctx))) { + fd_psm_change_state(peer, STATE_OPEN_NEW ); + /* send DWR */ + CHECK_FCT( fd_p_dw_timeout(peer) ); + } else { + + fd_psm_change_state(peer, STATE_OPEN ); + TRACE_DEBUG(INFO, "%s: state transit to _OPEN, timer=%d'.", __FUNCTION__, peer->p_hdr.info.config.pic_twtimer ); + if(peer->p_hdr.info.config.pic_twtimer <=5) + peer->p_hdr.info.config.pic_twtimer = 10; + fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw); + } + } + + return 0; + +error_abort: + if (pei.pei_errcode) { + /* Send the error */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, msg, peer, pei.pei_message ?: pei.pei_errcode, NULL); + receiver_reject(&peer->p_cnxctx, &msg, &pei); + } else { + char buf[1024]; + snprintf(buf, sizeof(buf), "Unexpected error occurred while processing incoming connection from '%s'.", peer->p_hdr.info.pi_diamid); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, msg, peer, buf, NULL); + } + +cleanup: + if (msg) { + fd_msg_free(msg); + } + fd_p_ce_clear_cnx(peer, NULL); + + /* Send the error to the peer */ + CHECK_FCT( fd_event_send(peer->p_events, fatal ? FDEVP_TERMINATE : FDEVP_CNX_ERROR, 0, NULL) ); + + return 0; +} + +/* We have received a CER on a new connection for this peer */ +int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid) +{ + struct fd_pei pei; + int cur_state = fd_peer_getstate(peer); + memset(&pei, 0, sizeof(pei)); + + switch (cur_state) { + case STATE_CLOSED: + peer->p_receiver = *cnx; + *cnx = NULL; + peer->p_cer = *msg; + *msg = NULL; + CHECK_FCT( fd_p_ce_process_receiver(peer) ); + break; + + case STATE_WAITCNXACK: + /* Save the parameters in the peer, move to STATE_WAITCNXACK_ELEC */ + peer->p_receiver = *cnx; + *cnx = NULL; + peer->p_cer = *msg; + *msg = NULL; + CHECK_FCT( fd_psm_change_state(peer, STATE_WAITCNXACK_ELEC) ); + break; + + case STATE_WAITCEA: + if (election_result(peer)) { + + /* Close initiator connection (was already set as principal) */ + LOG_D("%s: Election lost on outgoing connection, closing and answering CEA on incoming connection.", peer->p_hdr.info.pi_diamid); + fd_p_ce_clear_cnx(peer, NULL); + + /* and go on with the receiver side */ + peer->p_receiver = *cnx; + *cnx = NULL; + peer->p_cer = *msg; + *msg = NULL; + CHECK_FCT( fd_p_ce_process_receiver(peer) ); + + } else { + + /* Answer an ELECTION LOST to the receiver side and continue */ + pei.pei_errcode = "ELECTION_LOST"; + pei.pei_message = "Please answer my CER instead, you won the election."; + LOG_D("%s: Election lost on incoming connection, closing and waiting for CEA on outgoing connection.", peer->p_hdr.info.pi_diamid); + receiver_reject(cnx, msg, &pei); + } + break; + + default: + pei.pei_errcode = "DIAMETER_UNABLE_TO_COMPLY"; /* INVALID COMMAND? in case of Capabilities-Updates? */ + pei.pei_message = "Invalid state to receive a new connection attempt."; + LOG_E("%s: Rejecting new connection attempt while our state machine is in state '%s'", peer->p_hdr.info.pi_diamid, STATE_STR(cur_state)); + receiver_reject(cnx, msg, &pei); + } + + return 0; +} diff --git a/plat/diameter/libfdcore/p_cnx.c b/plat/diameter/libfdcore/p_cnx.c new file mode 100644 index 0000000..ee96ca8 --- /dev/null +++ b/plat/diameter/libfdcore/p_cnx.c @@ -0,0 +1,357 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + + +/* TODO: change the behavior to handle properly forced ordering at beginning & end of OPEN state */ + +/* This file contains code used by a peer state machine to initiate a connection to remote peer */ + +struct next_conn { + struct fd_list chain; + int proto; /* Protocol of the next attempt */ + union { + sSS ss; /* The address, only for TCP */ + sSA4 sin; + sSA6 sin6; + }; + uint16_t port; /* The port, for SCTP (included in ss for TCP) */ + int dotls; /* Handshake TLS after connection ? */ +}; + +static __inline__ void failed_connection_attempt(struct fd_peer * peer) +{ + /* Simply remove the first item in the list if not empty */ + if (! FD_IS_LIST_EMPTY(&peer->p_connparams) ) { + struct fd_list * li = peer->p_connparams.next; + fd_list_unlink(li); + free(li); + } +} + +static void empty_connection_list(struct fd_peer * peer) +{ + /* Remove all items */ + while (!FD_IS_LIST_EMPTY(&peer->p_connparams)) { + failed_connection_attempt(peer); + } +} + +static int prepare_connection_list(struct fd_peer * peer) +{ + struct fd_list * li, *last_prio; + struct next_conn * new; + + uint16_t port_no; /* network order */ + int dotls_immediate; + int count = 0; + + TRACE_ENTRY("%p", peer); + + /* Resolve peer address(es) if needed */ + if (FD_IS_LIST_EMPTY(&peer->p_hdr.info.pi_endpoints)) { + struct addrinfo hints, *ai, *aip; + int ret; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ADDRCONFIG; + ret = getaddrinfo(peer->p_hdr.info.pi_diamid, NULL, &hints, &ai); + if (ret) { + TRACE_DEBUG(INFO, "Unable to resolve address for peer '%s' (%s), aborting", peer->p_hdr.info.pi_diamid, gai_strerror(ret)); + if (ret != EAI_AGAIN) + fd_psm_terminate( peer, NULL ); + return 0; + } + + for (aip = ai; aip != NULL; aip = aip->ai_next) { + CHECK_FCT( fd_ep_add_merge( &peer->p_hdr.info.pi_endpoints, aip->ai_addr, aip->ai_addrlen, EP_FL_DISC ) ); + } + freeaddrinfo(ai); + } + + /* Remove addresses from unwanted family */ + if (peer->p_hdr.info.config.pic_flags.pro3) { + CHECK_FCT( fd_ep_filter_family( + &peer->p_hdr.info.pi_endpoints, + (peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP) ? + AF_INET + : AF_INET6)); + } + if (fd_g_config->cnf_flags.no_ip4) { + CHECK_FCT( fd_ep_filter_family( + &peer->p_hdr.info.pi_endpoints, + AF_INET6)); + } + if (fd_g_config->cnf_flags.no_ip6) { + CHECK_FCT( fd_ep_filter_family( + &peer->p_hdr.info.pi_endpoints, + AF_INET)); + } + + /* We don't use the alternate addresses that were sent by the remote peer */ + CHECK_FCT( fd_ep_clearflags(&peer->p_hdr.info.pi_endpoints, EP_FL_ADV) ); + + + /* Now check we have at least one address to attempt */ + if (FD_IS_LIST_EMPTY(&peer->p_hdr.info.pi_endpoints)) { + TRACE_DEBUG(INFO, "No address %savailable to connect to peer '%s', aborting", + peer->p_hdr.info.config.pic_flags.pro3 ? "in the configured family " : "", peer->p_hdr.info.pi_diamid); + fd_psm_terminate( peer, NULL ); + return 0; + } + + /* Check if we are able to communicate with this peer */ + if (fd_g_config->cnf_sec_data.tls_disabled && ( peer->p_hdr.info.config.pic_flags.sec != PI_SEC_NONE)) { + LOG_E("Peer '%s' not configured for No_TLS and TLS is locally disabled; giving up connection attempts", + peer->p_hdr.info.pi_diamid); + fd_psm_terminate( peer, NULL ); + return 0; + } + + /* Cleanup any previous list */ + empty_connection_list(peer); + + /* Prepare the parameters */ + if ((peer->p_hdr.info.config.pic_flags.sec != PI_SEC_DEFAULT) || (fd_g_config->cnf_flags.tls_alg)) { + dotls_immediate = 0; + port_no = htons(peer->p_hdr.info.config.pic_port ?: DIAMETER_PORT); + } else { + dotls_immediate = 1; + port_no = htons(peer->p_hdr.info.config.pic_port ?: DIAMETER_SECURE_PORT); + } + + last_prio = &peer->p_connparams; + + /* Create TCP parameters unless specified otherwise */ + if ((!fd_g_config->cnf_flags.no_tcp) && (peer->p_hdr.info.config.pic_flags.pro4 != PI_P4_SCTP)) { + for (li = peer->p_hdr.info.pi_endpoints.next; li != &peer->p_hdr.info.pi_endpoints; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + + CHECK_MALLOC( new = malloc(sizeof(struct next_conn)) ); + memset(new, 0, sizeof(struct next_conn)); + fd_list_init(&new->chain, new); + + new->proto = IPPROTO_TCP; + + memcpy( &new->ss, &ep->ss, sizeof(sSS) ); + switch (new->ss.ss_family) { + case AF_INET: + new->sin.sin_port = port_no; + break; + case AF_INET6: + new->sin6.sin6_port = port_no; + break; + default: + free(new); + continue; /* Move to the next endpoint */ + } + + new->dotls = dotls_immediate; + + /* Add the new entry to the appropriate position (conf and disc go first) */ + if (ep->flags & (EP_FL_CONF | EP_FL_DISC)) { + fd_list_insert_after(last_prio, &new->chain); + last_prio = &new->chain; + } else { + fd_list_insert_before(&peer->p_connparams, &new->chain); + } + count++; + } + } + + /* Now, add the SCTP entry, if not disabled */ +#ifndef DISABLE_SCTP + if ((!fd_g_config->cnf_flags.no_sctp) && (peer->p_hdr.info.config.pic_flags.pro4 != PI_P4_TCP)) { + struct next_conn * new; + + CHECK_MALLOC( new = malloc(sizeof(struct next_conn)) ); + memset(new, 0, sizeof(struct next_conn)); + fd_list_init(&new->chain, new); + + new->proto = IPPROTO_SCTP; + new->port = ntohs(port_no); /* back to host byte order... */ + new->dotls = dotls_immediate; + + /* Add the new entry to the appropriate position (depending on preferences) */ + if ((fd_g_config->cnf_flags.pr_tcp) || (peer->p_hdr.info.config.pic_flags.alg == PI_ALGPREF_TCP)) { + fd_list_insert_after(last_prio, &new->chain); + } else { + fd_list_insert_after(&peer->p_connparams, &new->chain); /* very first position */ + } + count++; + } +#endif /* DISABLE_SCTP */ + + LOG_D("Prepared %d sets of connection parameters to peer %s", count, peer->p_hdr.info.pi_diamid); + + return 0; +} + + +/* The thread that attempts the connection */ +static void * connect_thr(void * arg) +{ + struct fd_peer * peer = arg; + struct cnxctx * cnx = NULL; + struct next_conn * nc = NULL; + int rebuilt = 0; + int fatal_error=0; + + TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO( CHECK_PEER(peer), return NULL ); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "ConnTo:%s", peer->p_hdr.info.pi_diamid); + fd_log_threadname ( buf ); + } + + do { + /* Rebuild the list if needed, if it is empty -- but at most once */ + if (FD_IS_LIST_EMPTY(&peer->p_connparams)) { + if (! rebuilt) { + CHECK_FCT_DO( fatal_error = prepare_connection_list(peer), goto out ); + rebuilt ++; + } + if (FD_IS_LIST_EMPTY(&peer->p_connparams)) { + /* We encountered an error or we have looped over all the addresses of the peer. */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "All connection attempts failed, will retry later", NULL); + + CHECK_FCT_DO( fatal_error = fd_event_send(peer->p_events, FDEVP_CNX_FAILED, 0, NULL), goto out ); + return NULL; + } + } + + /* Attempt connection to the first entry */ + nc = (struct next_conn *)(peer->p_connparams.next); + + switch (nc->proto) { + case IPPROTO_TCP: + cnx = fd_cnx_cli_connect_tcp((sSA *)&nc->ss, sSAlen(&nc->ss)); + break; +#ifndef DISABLE_SCTP + case IPPROTO_SCTP: + cnx = fd_cnx_cli_connect_sctp((peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP) ? 1 : fd_g_config->cnf_flags.no_ip6, + nc->port, &peer->p_hdr.info.pi_endpoints); + break; +#endif /* DISABLE_SCTP */ + } + + if (cnx) + break; + + /* Pop these parameters and continue */ + failed_connection_attempt(peer); + + pthread_testcancel(); + + } while (!cnx); /* and until cancellation or all addresses attempted without success */ + + /* Now, we have an established connection in cnx */ + + pthread_cleanup_push((void *)fd_cnx_destroy, cnx); + + /* Set the hostname in the connection, so that handshake verifies the remote identity */ + fd_cnx_sethostname(cnx,peer->p_hdr.info.pi_diamid); + + /* Handshake if needed (secure port) */ + if (nc->dotls) { + CHECK_FCT_DO( fd_cnx_handshake(cnx, GNUTLS_CLIENT, + ALGO_HANDSHAKE_3436, + peer->p_hdr.info.config.pic_priority, NULL), + { + /* Handshake failed ... */ + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "TLS Handshake failed", NULL); + fd_cnx_destroy(cnx); + empty_connection_list(peer); + fd_ep_filter(&peer->p_hdr.info.pi_endpoints, EP_FL_CONF); + goto out_pop; + } ); + LOG_A("%s: TLS handshake successful.", peer->p_hdr.info.pi_diamid); + } else { + /* Prepare to receive the next message */ + CHECK_FCT_DO( fatal_error = fd_cnx_start_clear(cnx, 0), goto out_pop ); + } + + /* Upon success, generate FDEVP_CNX_ESTABLISHED */ + CHECK_FCT_DO( fatal_error = fd_event_send(peer->p_events, FDEVP_CNX_ESTABLISHED, 0, cnx), ); +out_pop: + ; + pthread_cleanup_pop(0); + +out: + + if (fatal_error) { + + /* Cleanup the connection */ + if (cnx) + fd_cnx_destroy(cnx); + + /* Generate a termination event */ + CHECK_FCT_DO(fd_core_shutdown(), ); + } + + return NULL; +} + + +/* Initiate a connection attempt to a remote peer */ +int fd_p_cnx_init(struct fd_peer * peer) +{ + TRACE_ENTRY("%p", peer); + + /* Start the connect thread */ + CHECK_FCT( pthread_create(&peer->p_ini_thr, NULL, connect_thr, peer) ); + return 0; +} + +/* Cancel a connection attempt */ +void fd_p_cnx_abort(struct fd_peer * peer, int cleanup_all) +{ + TRACE_ENTRY("%p %d", peer, cleanup_all); + CHECK_PARAMS_DO( CHECK_PEER(peer), return ); + + if (peer->p_ini_thr != (pthread_t)NULL) { + CHECK_FCT_DO( fd_thr_term(&peer->p_ini_thr), /* continue */); + failed_connection_attempt(peer); + } + + if (cleanup_all) { + empty_connection_list(peer); + } +} + diff --git a/plat/diameter/libfdcore/p_dp.c b/plat/diameter/libfdcore/p_dp.c new file mode 100644 index 0000000..1c9439a --- /dev/null +++ b/plat/diameter/libfdcore/p_dp.c @@ -0,0 +1,207 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* This file contains code to handle Disconnect Peer messages (DPR and DPA) */ + +/* Delay to use before next reconnect attempt */ +int fd_p_dp_newdelay(struct fd_peer * peer) +{ + int delay = peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc; + + switch (peer->p_hdr.info.runtime.pir_lastDC) { + case ACV_DC_REBOOTING: + default: + /* We use TcTimer to attempt reconnection */ + break; + case ACV_DC_BUSY: + /* No need to hammer the overloaded peer */ + delay *= 10; + break; + case ACV_DC_NOT_FRIEND: + /* He does not want to speak to us... let's retry a *lot* later maybe */ + delay *= 200; + break; + } + return delay; +} + +/* Handle a received message */ +int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer) +{ + long to_receive, to_send; + TRACE_ENTRY("%p %d %p", msg, req, peer); + + if (req) { + /* We received a DPR, save the Disconnect-Cause and go to CLOSING_GRACE or terminate the connection */ + struct avp * dc; + + CHECK_FCT( fd_msg_search_avp ( *msg, fd_dict_avp_DC, &dc )); + if (dc) { + struct avp_hdr * hdr; + CHECK_FCT( fd_msg_avp_hdr( dc, &hdr ) ); + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("BUG: Unset value in Disconnect-Cause in DPR"); + ASSERT(0); /* To check if this really happens, and understand why... */ + } + + /* save the cause */ + peer->p_hdr.info.runtime.pir_lastDC = hdr->avp_value->u32; + } + if (TRACE_BOOL(INFO)) { + if (dc) { + struct dict_object * dictobj; + struct dict_enumval_request er; + memset(&er, 0, sizeof(er)); + + /* prepare the request */ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, fd_dict_avp_DC, &er.type_obj, ENOENT ) ); + er.search.enum_value.u32 = peer->p_hdr.info.runtime.pir_lastDC; + + /* Search the enum value */ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &er, &dictobj, 0 ) ); + if (dictobj) { + CHECK_FCT( fd_dict_getval( dictobj, &er.search ) ); + TRACE_DEBUG(INFO, "Peer '%s' sent a DPR with cause: %s", peer->p_hdr.info.pi_diamid, er.search.enum_name); + } else { + TRACE_DEBUG(INFO, "Peer '%s' sent a DPR with unknown cause: %u", peer->p_hdr.info.pi_diamid, peer->p_hdr.info.runtime.pir_lastDC); + } + } else { + TRACE_DEBUG(INFO, "Peer '%s' sent a DPR without Disconnect-Cause AVP", peer->p_hdr.info.pi_diamid); + } + } + + /* Now reply with a DPA */ + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); + CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_SUCCESS", NULL, NULL, 1 ) ); + + /* Do we have pending exchanges with this peer? */ + CHECK_FCT( fd_peer_get_load_pending(&peer->p_hdr, &to_receive, &to_send) ); + + if ((to_receive == 0) && (to_send == 0)) { + /* No pending exchange, move to CLOSING directly */ + CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) ); + + /* Now send the DPA */ + CHECK_FCT( fd_out_send( msg, NULL, peer, 0) ); + + /* and move to CLOSED */ + fd_psm_cleanup(peer, 0); + + /* Reset the timer for next connection attempt -- we'll retry sooner or later depending on the disconnection cause */ + fd_psm_next_timeout(peer, 1, fd_p_dp_newdelay(peer)); + } else { + /* We have pending exchanges, we move to CLOSING_GRACE which allows exchanges of answers but + not new requests */ + CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING_GRACE) ); + fd_psm_next_timeout(peer, 0, GRACE_TIMEOUT); + + /* Now send the DPA */ + CHECK_FCT( fd_out_send( msg, NULL, peer, 0) ); + } + } else { + /* We received a DPA */ + int curstate = fd_peer_getstate(peer); + if (curstate != STATE_CLOSING_GRACE) { + TRACE_DEBUG(INFO, "Ignoring DPA received in state %s", STATE_STR(curstate)); + } + + /* In theory, we should control the Result-Code AVP. But since we will not go back to OPEN state here anyway, let's skip it */ + + /* TODO("Control Result-Code in the DPA") */ + CHECK_FCT_DO( fd_msg_free( *msg ), /* continue */ ); + *msg = NULL; + + /* Do we still have pending exchanges with this peer? */ + CHECK_FCT( fd_peer_get_load_pending(&peer->p_hdr, &to_receive, &to_send) ); + if ((to_receive != 0) || (to_send != 0)) { + TRACE_DEBUG(INFO, "Received DPA but pending load: [%ld, %ld], giving grace delay before closing", to_receive, to_send); + fd_psm_next_timeout(peer, 0, GRACE_TIMEOUT); + peer->p_flags.pf_localterm = 1; + } else { + /* otherwise, go to CLOSING state, the psm will handle terminating the connection */ + CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) ); + } + } + + return 0; +} + +/* Start disconnection of a peer: send DPR */ +int fd_p_dp_initiate(struct fd_peer * peer, char * reason) +{ + struct msg * msg = NULL; + struct dict_object * dictobj = NULL; + struct avp * avp = NULL; + struct dict_enumval_request er; + union avp_value val; + + TRACE_ENTRY("%p %p", peer, reason); + + /* Create a new DWR instance */ + CHECK_FCT( fd_msg_new ( fd_dict_cmd_DPR, MSGFL_ALLOC_ETEID, &msg ) ); + + /* Add the Origin information */ + CHECK_FCT( fd_msg_add_origin ( msg, 0 ) ); + + /* Add the Disconnect-Cause */ + CHECK_FCT( fd_msg_avp_new ( fd_dict_avp_DC, 0, &avp ) ); + + /* Search the value in the dictionary */ + memset(&er, 0, sizeof(er)); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, fd_dict_avp_DC, &er.type_obj, ENOENT ) ); + er.search.enum_name = reason ?: "REBOOTING"; + CHECK_FCT_DO( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &er, &dictobj, ENOENT ), { ASSERT(0); /* internal error: unknown reason */ } ); + CHECK_FCT( fd_dict_getval( dictobj, &er.search ) ); + + /* Set the value in the AVP */ + val.u32 = er.search.enum_value.u32; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + + /* Save the value also in the peer */ + peer->p_hdr.info.runtime.pir_lastDC = val.u32; + + /* Update the peer state and timer */ + CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING_GRACE) ); + fd_psm_next_timeout(peer, 0, DPR_TIMEOUT); + + /* Now send the DPR message */ + CHECK_FCT_DO( fd_out_send(&msg, NULL, peer, 0), /* ignore since we are on timeout anyway */ ); + + return 0; +} diff --git a/plat/diameter/libfdcore/p_dw.c b/plat/diameter/libfdcore/p_dw.c new file mode 100644 index 0000000..24b1c6d --- /dev/null +++ b/plat/diameter/libfdcore/p_dw.c @@ -0,0 +1,177 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* This file contains code to handle Device Watchdog messages (DWR and DWA) */ + +/* Check the value of Origin-State-Id is consistent in a DWR or DWA -- we return an error otherwise */ +static int check_state_id(struct msg * msg, struct fd_peer * peer) +{ + struct avp * osi; + + /* Check if the request contains the Origin-State-Id */ + CHECK_FCT( fd_msg_search_avp ( msg, fd_dict_avp_OSI, &osi ) ); + if (osi) { + /* Check the value is consistent with the saved one */ + struct avp_hdr * hdr; + CHECK_FCT( fd_msg_avp_hdr( osi, &hdr ) ); + if (hdr->avp_value == NULL) { + /* This is a sanity check */ + LOG_F("Ignored an Origin-State-Id AVP with unset value in DWR/DWA"); + ASSERT(0); /* To check if this really happens, and understand why... */ + } + + if (! peer->p_hdr.info.runtime.pir_orstate) { + /* It was not already received in CER/CEA, save it now */ + peer->p_hdr.info.runtime.pir_orstate = hdr->avp_value->u32; + } + + if (peer->p_hdr.info.runtime.pir_orstate != hdr->avp_value->u32) { + TRACE_DEBUG(INFO, "Received a new Origin-State-Id from peer '%s'! (%x -> %x); resetting the connection.", + peer->p_hdr.info.pi_diamid, + peer->p_hdr.info.runtime.pir_orstate, + hdr->avp_value->u32 ); + return EINVAL; + } + } + return 0; +} + +/* Create and send a DWR */ +static int send_DWR(struct fd_peer * peer) +{ + struct msg * msg = NULL; + + /* Create a new DWR instance */ + CHECK_FCT( fd_msg_new ( fd_dict_cmd_DWR, MSGFL_ALLOC_ETEID, &msg ) ); + + /* Add the content of the message (only the origin) */ + CHECK_FCT( fd_msg_add_origin ( msg, 1 ) ); + + /* Now send this message */ + CHECK_FCT( fd_out_send(&msg, NULL, peer, 0) ); + + /* And mark the pending DW */ + peer->p_flags.pf_dw_pending = 1; + + return 0; +} + +/* Handle an incoming message */ +int fd_p_dw_handle(struct msg ** msg, int req, struct fd_peer * peer) +{ + int reset_tmr = 0; + + TRACE_ENTRY("%p %d %p", msg, req, peer); + + /* Check the value of OSI for information */ + CHECK_FCT( check_state_id(*msg, peer) ); + + if (req) { + /* If we receive a DWR, send back a DWA */ + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); + CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_SUCCESS", NULL, NULL, 0 ) ); + CHECK_FCT( fd_msg_add_origin ( *msg, 1 ) ); + CHECK_FCT( fd_out_send( msg, peer->p_cnxctx, peer, 0) ); + + } else { + /* Discard the DWA */ + CHECK_FCT_DO( fd_msg_free(*msg), /* continue */ ); + *msg = NULL; + + /* And clear the pending DW flag */ + peer->p_flags.pf_dw_pending = 0; + } + + /* Now update timeout */ + if (req) { + /* Update timeout only if we did not already send a DWR ourselves */ + reset_tmr = !peer->p_flags.pf_dw_pending; + } else { + /* Reset the timer */ + reset_tmr = 1; + } + if (reset_tmr) { + fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw); + } + + /* If we are in REOPEN state, increment the counter */ + if (fd_peer_getstate(peer) == STATE_REOPEN) { + peer->p_flags.pf_reopen_cnt += 1; + + if (peer->p_flags.pf_reopen_cnt) { + /* Send a new DWR */ + CHECK_FCT( send_DWR(peer) ); + } else { + /* Move to OPEN state */ + CHECK_FCT( fd_psm_change_state(peer, STATE_OPEN) ); + } + } + + return 0; +} + +/* Handle a timeout in the PSM (OPEN or REOPEN state only) */ +int fd_p_dw_timeout(struct fd_peer * peer) +{ + TRACE_ENTRY("%p", peer); + + if (peer->p_flags.pf_dw_pending) { + /* We have sent a DWR and received no answer during TwTimer */ + CHECK_FCT( fd_psm_change_state(peer, STATE_SUSPECT) ); + fd_psm_next_timeout(peer, 0, 2 * (peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw) ); + } else { + /* The timeout has expired, send a DWR */ + CHECK_FCT( send_DWR(peer) ); + fd_psm_next_timeout(peer, 0, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw ); + } + + return 0; +} + +/* Handle DW exchanges after the peer has come alive again */ +int fd_p_dw_reopen(struct fd_peer * peer) +{ + TRACE_ENTRY("%p", peer); + + peer->p_flags.pf_reopen_cnt = 1; + peer->p_flags.pf_cnx_pb = 0; + CHECK_FCT( send_DWR(peer) ); + + return 0; +} + + diff --git a/plat/diameter/libfdcore/p_expiry.c b/plat/diameter/libfdcore/p_expiry.c new file mode 100644 index 0000000..9b91421 --- /dev/null +++ b/plat/diameter/libfdcore/p_expiry.c @@ -0,0 +1,205 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Delay for garbage collection of expired peers, in seconds */ +#define GC_TIME 120 + +static pthread_t exp_thr = (pthread_t)NULL; +static pthread_t gc_thr = (pthread_t)NULL; +static struct fd_list exp_list = FD_LIST_INITIALIZER( exp_list ); +static pthread_cond_t exp_cnd = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t exp_mtx = PTHREAD_MUTEX_INITIALIZER; + +static void * gc_th_fct(void * arg) +{ + fd_log_threadname ( "Peers/garb. col." ); + TRACE_ENTRY( "%p", arg ); + + do { + struct fd_list * li, purge = FD_LIST_INITIALIZER(purge); + + sleep(GC_TIME); /* sleep is a cancellation point */ + + /* Now check in the peers list if any peer can be deleted */ + CHECK_FCT_DO( pthread_rwlock_wrlock(&fd_g_peers_rw), goto error ); + + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct fd_peer * peer = (struct fd_peer *)li->o; + + if (fd_peer_getstate(peer) != STATE_ZOMBIE) + continue; + + if (peer->p_hdr.info.config.pic_flags.persist == PI_PRST_ALWAYS) + continue; /* This peer was not supposed to terminate, keep it in the list for debug */ + + /* Ok, the peer was expired, let's remove it */ + li = li->prev; /* to avoid breaking the loop */ + fd_list_unlink(&peer->p_hdr.chain); + fd_list_insert_before(&purge, &peer->p_hdr.chain); + } + + CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), goto error ); + + /* Now delete peers that are in the purge list */ + while (!FD_IS_LIST_EMPTY(&purge)) { + struct fd_peer * peer = (struct fd_peer *)(purge.next->o); + fd_list_unlink(&peer->p_hdr.chain); + TRACE_DEBUG(INFO, "Garbage Collect: delete zombie peer '%s'", peer->p_hdr.info.pi_diamid); + CHECK_FCT_DO( fd_peer_free(&peer), /* Continue... what else to do ? */ ); + } + } while (1); + +error: + TRACE_DEBUG(INFO, "An error occurred in peers module! GC thread is terminating..."); + ASSERT(0); + CHECK_FCT_DO(fd_core_shutdown(), ); + return NULL; +} + + +static void * exp_th_fct(void * arg) +{ + fd_log_threadname ( "Peers/expire" ); + TRACE_ENTRY( "%p", arg ); + + CHECK_POSIX_DO( pthread_mutex_lock(&exp_mtx), { ASSERT(0); } ); + pthread_cleanup_push( fd_cleanup_mutex, &exp_mtx ); + + do { + struct timespec now; + struct fd_peer * first; + + /* Check if there are expiring peers available */ + if (FD_IS_LIST_EMPTY(&exp_list)) { + /* Just wait for a change or cancelation */ + CHECK_POSIX_DO( pthread_cond_wait( &exp_cnd, &exp_mtx ), { ASSERT(0); } ); + /* Restart the loop on wakeup */ + continue; + } + + /* Get the pointer to the peer that expires first */ + first = (struct fd_peer *)(exp_list.next->o); + ASSERT( CHECK_PEER(first) ); + + /* Get the current time */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), { ASSERT(0); } ); + + /* If first peer is not expired, we just wait until it happens */ + if ( TS_IS_INFERIOR( &now, &first->p_exp_timer ) ) { + + CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cnd, &exp_mtx, &first->p_exp_timer ), + ETIMEDOUT, /* ETIMEDOUT is a normal return value, continue */, + /* on other error, */ { ASSERT(0); } ); + + /* on wakeup, loop */ + continue; + } + + /* Now, the first peer in the list is expired; signal it */ + fd_list_unlink( &first->p_expiry ); + CHECK_FCT_DO( fd_event_send(first->p_events, FDEVP_TERMINATE, 0, "DO_NOT_WANT_TO_TALK_TO_YOU"), break ); + + } while (1); + + pthread_cleanup_pop( 1 ); + + TRACE_DEBUG(INFO, "An error occurred in peers module! Expiry thread is terminating..."); + CHECK_FCT_DO(fd_core_shutdown(), ); + return NULL; +} + +/* Initialize peers expiry mechanism */ +int fd_p_expi_init(void) +{ + TRACE_ENTRY(); + CHECK_FCT( pthread_create( &exp_thr, NULL, exp_th_fct, NULL ) ); + CHECK_FCT( pthread_create( &gc_thr, NULL, gc_th_fct, NULL ) ); + return 0; +} + +/* Finish peers expiry mechanism */ +int fd_p_expi_fini(void) +{ + CHECK_FCT_DO( fd_thr_term(&exp_thr), ); + CHECK_POSIX( pthread_mutex_lock(&exp_mtx) ); + while (!FD_IS_LIST_EMPTY(&exp_list)) { + struct fd_peer * peer = (struct fd_peer *)(exp_list.next->o); + fd_list_unlink(&peer->p_expiry ); + } + CHECK_POSIX( pthread_mutex_unlock(&exp_mtx) ); + + CHECK_FCT_DO( fd_thr_term(&gc_thr), ); + return 0; +} + +/* Add / requeue a peer in the expiry list */ +int fd_p_expi_update(struct fd_peer * peer ) +{ + TRACE_ENTRY("%p", peer); + CHECK_PARAMS( CHECK_PEER(peer) ); + + CHECK_POSIX( pthread_mutex_lock(&exp_mtx) ); + + fd_list_unlink(&peer->p_expiry ); + + /* if peer expires */ + if (peer->p_hdr.info.config.pic_flags.exp) { + struct fd_list * li; + + /* update the p_exp_timer value */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &peer->p_exp_timer), { ASSERT(0); } ); + peer->p_exp_timer.tv_sec += peer->p_hdr.info.config.pic_lft; + + /* add to the expiry list in appropriate position (probably around the end) */ + for (li = exp_list.prev; li != &exp_list; li = li->prev) { + struct fd_peer * p = (struct fd_peer *)(li->o); + if (TS_IS_INFERIOR( &p->p_exp_timer, &peer->p_exp_timer ) ) + break; + } + + fd_list_insert_after(li, &peer->p_expiry); + + /* signal the expiry thread if we added in first position */ + if (li == &exp_list) { + CHECK_POSIX( pthread_cond_signal(&exp_cnd) ); + } + } + + CHECK_POSIX( pthread_mutex_unlock(&exp_mtx) ); + return 0; +} + diff --git a/plat/diameter/libfdcore/p_out.c b/plat/diameter/libfdcore/p_out.c new file mode 100644 index 0000000..3c0d0cd --- /dev/null +++ b/plat/diameter/libfdcore/p_out.c @@ -0,0 +1,237 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Alloc a new hbh for requests, bufferize the message and send on the connection, save in sentreq if provided */ +static int do_send(struct msg ** msg, struct cnxctx * cnx, uint32_t * hbh, struct fd_peer * peer) +{ + struct msg_hdr * hdr; + int msg_is_a_req; + uint8_t * buf; + size_t sz; + int ret; + uint32_t bkp_hbh = 0; + struct msg *cpy_for_logs_only; + + TRACE_ENTRY("%p %p %p %p", msg, cnx, hbh, peer); + + /* Retrieve the message header */ + CHECK_FCT( fd_msg_hdr(*msg, &hdr) ); + + msg_is_a_req = (hdr->msg_flags & CMD_FLAG_REQUEST); + if (msg_is_a_req) { + CHECK_PARAMS(hbh && peer); + /* Alloc the hop-by-hop id and increment the value for next message */ + bkp_hbh = hdr->msg_hbhid; + hdr->msg_hbhid = *hbh; + *hbh = hdr->msg_hbhid + 1; + } + + /* Create the message buffer */ + CHECK_FCT(fd_msg_bufferize( *msg, &buf, &sz )); + pthread_cleanup_push( free, buf ); + + cpy_for_logs_only = *msg; + + /* Save a request before sending so that there is no race condition with the answer */ + if (msg_is_a_req) { + CHECK_FCT_DO( ret = fd_p_sr_store(&peer->p_sr, msg, &hdr->msg_hbhid, bkp_hbh), goto out ); + } + + /* Log the message */ + fd_hook_call(HOOK_MESSAGE_SENT, cpy_for_logs_only, peer, NULL, fd_msg_pmdl_get(cpy_for_logs_only)); + + pthread_cleanup_push((void *)fd_msg_free, *msg /* might be NULL, no problem */); + + /* Send the message */ + CHECK_FCT_DO( ret = fd_cnx_send(cnx, buf, sz), ); + + pthread_cleanup_pop(0); + +out: + ; + pthread_cleanup_pop(1); + + if (ret) + return ret; + + /* Free remaining messages (i.e. answers) */ + if (*msg) { + CHECK_FCT( fd_msg_free(*msg) ); + *msg = NULL; + } + + return 0; +} + +/* The code of the "out" thread */ +static void * out_thr(void * arg) +{ + struct fd_peer * peer = arg; + int stop = 0; + struct msg * msg; + ASSERT( CHECK_PEER(peer) ); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "OUT/%s", peer->p_hdr.info.pi_diamid); + fd_log_threadname ( buf ); + } + + /* Loop until cancelation */ + while (!stop) { + int ret; + + /* Retrieve next message to send */ + CHECK_FCT_DO( fd_fifo_get(peer->p_tosend, &msg), goto error ); + + /* Send the message, log any error */ + CHECK_FCT_DO( ret = do_send(&msg, peer->p_cnxctx, &peer->p_hbh, peer), + { + if (msg) { + char buf[256]; + snprintf(buf, sizeof(buf), "Error while sending this message: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, buf, fd_msg_pmdl_get(msg)); + fd_msg_free(msg); + } + stop = 1; + } ); + + } + + /* If we're here it means there was an error on the socket. We need to continue to purge the fifo & until we are canceled */ + CHECK_FCT_DO( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL), /* What do we do if it fails? */ ); + + /* Requeue all routable messages in the global "out" queue, until we are canceled once the PSM deals with the CNX_ERROR sent above */ + while ( fd_fifo_get(peer->p_tosend, &msg) == 0 ) { + if (fd_msg_is_routable(msg)) { + CHECK_FCT_DO(fd_fifo_post_noblock(peer->p_tofailover, (void *)&msg), + { + /* fallback: destroy the message */ + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, "Internal error: unable to requeue this message during failover process", fd_msg_pmdl_get(msg)); + CHECK_FCT_DO(fd_msg_free(msg), /* What can we do more? */) + } ); + } else { + /* Just free it */ + /* fd_hook_call(HOOK_MESSAGE_DROPPED, m, NULL, "Non-routable message freed during handover", fd_msg_pmdl_get(m)); */ + CHECK_FCT_DO(fd_msg_free(msg), /* What can we do more? */) + } + } + +error: + /* It is not really a connection error, but the effect is the same, we are not able to send anymore message */ + CHECK_FCT_DO( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL), /* What do we do if it fails? */ ); + return NULL; +} + +/* Wrapper to sending a message either by out thread (peer in OPEN state) or directly; cnx or peer must be provided. Flags are valid only for direct sending, not through thread (unused) */ +int fd_out_send(struct msg ** msg, struct cnxctx * cnx, struct fd_peer * peer, int update_reqin_cnt) +{ + struct msg_hdr * hdr; + + TRACE_ENTRY("%p %p %p", msg, cnx, peer); + CHECK_PARAMS( msg && *msg && (cnx || (peer && peer->p_cnxctx))); + + fd_hook_call(HOOK_MESSAGE_SENDING, *msg, peer, NULL, fd_msg_pmdl_get(*msg)); + + if (update_reqin_cnt && peer) { + CHECK_FCT( fd_msg_hdr(*msg, &hdr) ); + if (!(hdr->msg_flags & CMD_FLAG_REQUEST)) { + /* Update the count of pending answers to send */ + CHECK_POSIX( pthread_mutex_lock(&peer->p_state_mtx) ); + peer->p_reqin_count--; + CHECK_POSIX( pthread_mutex_unlock(&peer->p_state_mtx) ); + } + } + + if (fd_peer_getstate(peer) == STATE_OPEN) { + /* Normal case: just queue for the out thread to pick it up */ + CHECK_FCT( fd_fifo_post(peer->p_tosend, msg) ); + + } else { + int ret; + uint32_t *hbh = NULL; + + /* In other cases, the thread is not running, so we handle the sending directly */ + if (peer) + hbh = &peer->p_hbh; + + if (!cnx) + cnx = peer->p_cnxctx; + + /* Do send the message */ + CHECK_FCT_DO( ret = do_send(msg, cnx, hbh, peer), + { + if (msg) { + char buf[256]; + snprintf(buf, sizeof(buf), "Error while sending this message: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_DROPPED, *msg, NULL, buf, fd_msg_pmdl_get(*msg)); + fd_msg_free(*msg); + *msg = NULL; + } + } ); + } + + return 0; +} + +/* Start the "out" thread that picks messages in p_tosend and send them on p_cnxctx */ +int fd_out_start(struct fd_peer * peer) +{ + TRACE_ENTRY("%p", peer); + CHECK_PARAMS( CHECK_PEER(peer) && (peer->p_outthr == (pthread_t)NULL) ); + + CHECK_POSIX( pthread_create(&peer->p_outthr, NULL, out_thr, peer) ); + + CHECK_FCT( fd_cnx_unordered_delivery(peer->p_cnxctx, 1) ); + + return 0; +} + +/* Stop that thread */ +int fd_out_stop(struct fd_peer * peer) +{ + TRACE_ENTRY("%p", peer); + CHECK_PARAMS( CHECK_PEER(peer) ); + + CHECK_FCT( fd_cnx_unordered_delivery(peer->p_cnxctx, 0) ); + + CHECK_FCT( fd_thr_term(&peer->p_outthr) ); + + return 0; +} + diff --git a/plat/diameter/libfdcore/p_psm.c b/plat/diameter/libfdcore/p_psm.c new file mode 100644 index 0000000..96210ec --- /dev/null +++ b/plat/diameter/libfdcore/p_psm.c @@ -0,0 +1,958 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* +This file implement a Peer State Machine which is a mix of: + - the state machine described in rfc3588bis + - the state machine described in rfc3539#section-3.4 + - the following observations. + +The delivery of Diameter messages must not always be unordered: order is important at +begining and end of a connection lifetime. It means we need agility to +switch between "ordering enforced" and "ordering not enforced to counter +Head of the Line Blocking" modes of operation. + +The connection state machine represented in RFC3588 (and RFC6733) is +incomplete, because it lacks the SUSPECT state and the 3 DWR/DWA +exchanges (section 5.1) when the peer recovers from this state. +Personnally I don't see the rationale for exchanging 3 messages (why 3?) +but, if we require at least 1 DWR/DWA exchange to be always performed +after the CER/CEA exchange (and initiated by the peer that sent the +CEA), we have a simple way to deal with our ordering problem, as resumed +below. Peers are: [i]nitiator, [r]esponder. + (1) [i] SCTP connection attempt. + (2) [r] accept the connection. + (3) [i,r] (if secure port) DTLS handshake, close on failure. + (4) [i] Send CER + (5) [r] Receive CER, send CEA using stream 0, flag "unordered" cleared. + [r] Immediately send a DWR after the CEA, also using stream 0, +flag "unordered" cleared. + [r] Move to STATE_OPEN_NEW state -- equivalent to OPEN except +that all messages are sent ordered at the moment. + (6) [i] receive CEA, move to OPEN state. All messages can be sent +unordered in OPEN state. + [i] As per normal operation, reply with DWA to the DWR. + (7) [r] Upon reception of the DWA, move to OPEN state, messages can be +sent unordered from this point. + +Note about (5) and (6): if the Diameter Identity received in CER or CEA +does not match the credentials from the certificate presented during +TLS handshake, we may need to specify a path of clean disconnection +(not blocking the remote peer waiting for something). + +This proposed mechanism removes the problem of application messages +received before the CEA by the initiator. Note that if the "old" inband +TLS handshake is used, this handshake plays the same synchronization +role than the new DWR/DWA, which becomes useless. + + +The other time where ordering is important is by the end of connection +lifetime, when one peer is shutting down the link for some reason +(reboot, overload, no activity, etc...). In case of unordered delivery, +we may have: +- peer A sends an application message followed by a DPR. Peer B receives +the DPR first and tears down the connection. Application message is lost. +- Peer B sends an application message, then receives a DPR and answers a +DPA. Peer A receives the DPA before the application message. The +application message is lost. + +This situation is actually happening easily because DPR/DPA messages are +very short, while application messages can be quite large. Therefore, +they require much more time to deliver. + +I really cannot see a way to counter this effect by using the ordering +of the messages, except by applying a timer (state STATE_CLOSING_GRACE). +This timer can be also useful when we detect that some messages has not +yet received an answer on this link, to give time to the application to +complete the exchange ongoing. + +However, this problem must be balanced with the fact that the message +that is lost will be in many cases sent again as the failover mechanism +specifies. +*/ + +/* The actual declaration of peer_state_str */ +DECLARE_STATE_STR(); + +/* Helper for next macro */ +#define case_str( _val ) \ + case _val : return #_val + +DECLARE_PEV_STR(); + +/************************************************************************/ +/* Delayed startup */ +/************************************************************************/ +static int started = 0; +static pthread_mutex_t started_mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t started_cnd = PTHREAD_COND_INITIALIZER; + +/* Wait for start signal */ +static int fd_psm_waitstart() +{ + int ret = 0; + TRACE_ENTRY(""); + CHECK_POSIX( pthread_mutex_lock(&started_mtx) ); +awake: + if (!ret && !started) { + pthread_cleanup_push( fd_cleanup_mutex, &started_mtx ); + CHECK_POSIX_DO( ret = pthread_cond_wait(&started_cnd, &started_mtx), ); + pthread_cleanup_pop( 0 ); + goto awake; + } + CHECK_POSIX( pthread_mutex_unlock(&started_mtx) ); + return ret; +} + +/* Allow the state machines to start */ +int fd_psm_start() +{ + TRACE_ENTRY(""); + CHECK_POSIX( pthread_mutex_lock(&started_mtx) ); + started = 1; + CHECK_POSIX( pthread_cond_broadcast(&started_cnd) ); + CHECK_POSIX( pthread_mutex_unlock(&started_mtx) ); + return 0; +} + + +/************************************************************************/ +/* Manage the list of active peers */ +/************************************************************************/ + +/* Enter/leave OPEN state */ +static int enter_open_state(struct fd_peer * peer) +{ + struct fd_list * li; + CHECK_PARAMS( FD_IS_LIST_EMPTY(&peer->p_actives) ); + + /* Callback registered by the credential validator (fd_peer_validate_register) */ + if (peer->p_cb2) { + CHECK_FCT_DO( (*peer->p_cb2)(&peer->p_hdr.info), + { + TRACE_DEBUG(FULL, "Validation failed, terminating the connection"); + fd_psm_terminate(peer, "DO_NOT_WANT_TO_TALK_TO_YOU" ); + } ); + peer->p_cb2 = NULL; + return 0; + } + + /* Insert in the active peers list */ + CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_activ_peers_rw) ); + for (li = fd_g_activ_peers.next; li != &fd_g_activ_peers; li = li->next) { + struct fd_peer * next_p = (struct fd_peer *)li->o; + int cmp = fd_os_cmp(peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, + next_p->p_hdr.info.pi_diamid, next_p->p_hdr.info.pi_diamidlen); + if (cmp < 0) + break; + } + fd_list_insert_before(li, &peer->p_actives); + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_activ_peers_rw) ); + + /* Callback registered when the peer was added, by fd_peer_add */ + if (peer->p_cb) { + LOG_N("Calling add callback for peer %s", peer->p_hdr.info.pi_diamid); + (*peer->p_cb)(&peer->p_hdr.info, peer->p_cb_data); /* TODO: do this in a separate detached thread? */ + // peer->p_cb = NULL; + // peer->p_cb_data = NULL; + } + + /* Start the thread to handle outgoing messages */ + CHECK_FCT( fd_out_start(peer) ); + + /* Update the expiry timer now */ + CHECK_FCT( fd_p_expi_update(peer) ); + + return 0; +} +static int leave_open_state(struct fd_peer * peer, int skip_failover) +{ + /* Remove from active peers list */ + CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_activ_peers_rw) ); + fd_list_unlink( &peer->p_actives ); + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_activ_peers_rw) ); + + /* Stop the "out" thread */ + CHECK_FCT( fd_out_stop(peer) ); + + /* Failover the messages */ + if (!skip_failover) { + fd_peer_failover_msg(peer); + } + + return 0; +} + + +/************************************************************************/ +/* Helpers for state changes */ +/************************************************************************/ + +/* Cleanup pending events in the peer */ +void fd_psm_events_free(struct fd_peer * peer) +{ + struct fd_event * ev; + /* Purge all events, and free the associated data if any */ + while (fd_fifo_tryget( peer->p_events, &ev ) == 0) { + switch (ev->code) { + case FDEVP_CNX_ESTABLISHED: { + fd_cnx_destroy(ev->data); + } + break; + + case FDEVP_TERMINATE: + /* Do not free the string since it is a constant */ + break; + + case FDEVP_CNX_INCOMING: { + struct cnx_incoming * evd = ev->data; + fd_hook_call(HOOK_MESSAGE_DROPPED, evd->cer, NULL, "Message discarded while cleaning peer state machine queue.", fd_msg_pmdl_get(evd->cer)); + CHECK_FCT_DO( fd_msg_free(evd->cer), /* continue */); + fd_cnx_destroy(evd->cnx); + } + default: + free(ev->data); + } + free(ev); + } +} + +/* Read state */ +int fd_peer_get_state(struct peer_hdr *peer) +{ + int ret; + + struct fd_peer * p = (struct fd_peer *)peer; + + if (!CHECK_PEER(p)) + return -1; + + CHECK_POSIX_DO( pthread_mutex_lock(&p->p_state_mtx), return -1 ); + ret = p->p_state; + CHECK_POSIX_DO( pthread_mutex_unlock(&p->p_state_mtx), return -1 ); + + return ret; +} + + +/* Change state */ +int fd_psm_change_state(struct fd_peer * peer, int new_state) +{ + int old; + + TRACE_ENTRY("%p %d(%s)", peer, new_state, STATE_STR(new_state)); + CHECK_PARAMS( CHECK_PEER(peer) ); + + old = fd_peer_getstate(peer); + if (old == new_state) + return 0; + + LOG(((old == STATE_OPEN) || (new_state == STATE_OPEN)) ? FD_LOG_NOTICE : FD_LOG_DEBUG, "'%s'\t-> '%s'\t'%s'", + STATE_STR(old), + STATE_STR(new_state), + peer->p_hdr.info.pi_diamid); + + + CHECK_POSIX( pthread_mutex_lock(&peer->p_state_mtx) ); + peer->p_state = new_state; + CHECK_POSIX( pthread_mutex_unlock(&peer->p_state_mtx) ); + + if (old == STATE_OPEN) { + CHECK_FCT( leave_open_state(peer, new_state == STATE_CLOSING_GRACE) ); + } + if (old == STATE_CLOSING_GRACE) { + fd_peer_failover_msg(peer); + } + + if (new_state == STATE_OPEN) { + CHECK_FCT( enter_open_state(peer) ); + } + + if (new_state == STATE_CLOSED) { + /* Purge event list */ + fd_psm_events_free(peer); + + /* Reset the counter of pending anwers to send */ + peer->p_reqin_count = 0; + + /* If the peer is not persistant, we destroy it */ + if (peer->p_hdr.info.config.pic_flags.persist == PI_PRST_NONE) { + CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, NULL) ); + } + } + + return 0; +} + +/* Set timeout timer of next event */ +void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay) +{ + TRACE_DEBUG(FULL, "Peer timeout reset to %d seconds%s", delay, add_random ? " (+/- 2)" : "" ); + + /* Initialize the timer */ + CHECK_POSIX_DO( clock_gettime( CLOCK_REALTIME, &peer->p_psm_timer ), ASSERT(0) ); + + if (add_random) { + if (delay > 2) + delay -= 2; + else + delay = 0; + + /* Add a random value between 0 and 4sec */ + peer->p_psm_timer.tv_sec += random() % 4; + peer->p_psm_timer.tv_nsec+= random() % 1000000000L; + if (peer->p_psm_timer.tv_nsec >= 1000000000L) { + peer->p_psm_timer.tv_nsec -= 1000000000L; + peer->p_psm_timer.tv_sec ++; + } + } + + peer->p_psm_timer.tv_sec += delay; + +#ifdef SLOW_PSM + /* temporary for debug */ + peer->p_psm_timer.tv_sec += 10; +#endif +} + +/* Cleanup the peer */ +void fd_psm_cleanup(struct fd_peer * peer, int terminate) +{ + /* Move to CLOSED state: failover messages, stop OUT thread, unlink peer from active list */ + if (fd_peer_getstate(peer) != STATE_ZOMBIE) { + CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), /* continue */ ); + } + + fd_p_cnx_abort(peer, terminate); + + fd_p_ce_clear_cnx(peer, NULL); + + if (peer->p_receiver) { + fd_cnx_destroy(peer->p_receiver); + peer->p_receiver = NULL; + } + + if (terminate) { + fd_psm_events_free(peer); + CHECK_FCT_DO( fd_fifo_del(&peer->p_events), /* continue */ ); + } + +} + + +/************************************************************************/ +/* The PSM thread */ +/************************************************************************/ +/* Cancelation cleanup : set ZOMBIE state in the peer */ +void cleanup_setstate(void * arg) +{ + struct fd_peer * peer = (struct fd_peer *)arg; + CHECK_PARAMS_DO( CHECK_PEER(peer), return ); + CHECK_POSIX_DO( pthread_mutex_lock(&peer->p_state_mtx), ); + peer->p_state = STATE_ZOMBIE; + CHECK_POSIX_DO( pthread_mutex_unlock(&peer->p_state_mtx), ); + return; +} + +/* The state machine thread (controler) */ +static void * p_psm_th( void * arg ) +{ + struct fd_peer * peer = (struct fd_peer *)arg; + int created_started = started ? 1 : 0; + int event; + size_t ev_sz; + void * ev_data; + int cur_state; + + CHECK_PARAMS_DO( CHECK_PEER(peer), ASSERT(0) ); + + pthread_cleanup_push( cleanup_setstate, arg ); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "PSM/%s", peer->p_hdr.info.pi_diamid); + fd_log_threadname ( buf ); + } + + /* The state machine starts in CLOSED state */ + CHECK_POSIX_DO( pthread_mutex_lock(&peer->p_state_mtx), goto psm_end ); + peer->p_state = STATE_CLOSED; + CHECK_POSIX_DO( pthread_mutex_unlock(&peer->p_state_mtx), goto psm_end ); + + /* Wait that the PSM are authorized to start in the daemon */ + CHECK_FCT_DO( fd_psm_waitstart(), goto psm_end ); + + /* Initialize the timer */ + if (peer->p_flags.pf_responder) { + fd_psm_next_timeout(peer, 0, INCNX_TIMEOUT); + } else { + fd_psm_next_timeout(peer, created_started, 0); + } + +psm_loop: + /* Get next event */ + TRACE_DEBUG(FULL, "'%s' in state '%s' waiting for next event.", + peer->p_hdr.info.pi_diamid, STATE_STR(fd_peer_getstate(peer))); + CHECK_FCT_DO( fd_event_timedget(peer->p_events, &peer->p_psm_timer, FDEVP_PSM_TIMEOUT, &event, &ev_sz, &ev_data), goto psm_end ); + + cur_state = fd_peer_getstate(peer); + if (cur_state == -1) + goto psm_end; + + TRACE_DEBUG(FULL, "'%s'\t<-- '%s'\t(%p,%zd)\t'%s'", + STATE_STR(cur_state), + fd_pev_str(event), ev_data, ev_sz, + peer->p_hdr.info.pi_diamid); + + /* Now, the action depends on the current state and the incoming event */ + + /* The following states are impossible */ + ASSERT( cur_state != STATE_NEW ); + ASSERT( cur_state != STATE_ZOMBIE ); + ASSERT( cur_state != STATE_OPEN_HANDSHAKE ); /* because it should exist only between two loops */ + + /* Purge invalid events */ + if (!CHECK_PEVENT(event)) { + TRACE_DEBUG(INFO, "Invalid event received in PSM '%s' : %d", peer->p_hdr.info.pi_diamid, event); + ASSERT(0); /* we should investigate this situation */ + goto psm_loop; + } + + /* Requests to terminate the peer object */ + if (event == FDEVP_TERMINATE) { + switch (cur_state) { + case STATE_OPEN: + case STATE_OPEN_NEW: + case STATE_REOPEN: + /* We cannot just close the connection, we have to send a DPR first */ + CHECK_FCT_DO( fd_p_dp_initiate(peer, ev_data), goto psm_end ); + goto psm_loop; + + /* + case STATE_CLOSING: + case STATE_CLOSING_GRACE: + case STATE_WAITCNXACK: + case STATE_WAITCNXACK_ELEC: + case STATE_WAITCEA: + case STATE_SUSPECT: + case STATE_CLOSED: + */ + default: + /* In these cases, we just cleanup the peer object (if needed) and terminate */ + goto psm_end; + } + } + + /* A message was received */ + if (event == FDEVP_CNX_MSG_RECV) { + struct msg * msg = NULL; + struct msg_hdr * hdr; + struct fd_cnx_rcvdata rcv_data; + struct fd_msg_pmdl * pmdl = NULL; + + rcv_data.buffer = ev_data; + rcv_data.length = ev_sz; + pmdl = fd_msg_pmdl_get_inbuf(rcv_data.buffer, rcv_data.length); + + /* Parse the received buffer */ + CHECK_FCT_DO( fd_msg_parse_buffer( (void *)&ev_data, ev_sz, &msg), + { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, NULL, peer, &rcv_data, pmdl ); + free(ev_data); + CHECK_FCT_DO( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL), goto psm_reset ); + goto psm_loop; + } ); + + fd_hook_associate(msg, pmdl); + CHECK_FCT_DO( fd_msg_source_set( msg, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen), goto psm_end); + + /* If the current state does not allow receiving messages, just drop it */ + if (cur_state == STATE_CLOSED) { + /* In such case, just discard the message */ + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, "Message purged from queue, peer in CLOSED state", fd_msg_pmdl_get(msg)); + fd_msg_free(msg); + goto psm_loop; + } + + /* Extract the header */ + CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto psm_end ); + + /* If it is an answer, associate with the request or drop */ + if (!(hdr->msg_flags & CMD_FLAG_REQUEST)) { + struct msg * req; + /* Search matching request (same hbhid) */ + CHECK_FCT_DO( fd_p_sr_fetch(&peer->p_sr, hdr->msg_hbhid, &req), goto psm_end ); + if (req == NULL) { + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, "Answer received with no corresponding sent request.", fd_msg_pmdl_get(msg)); + fd_msg_free(msg); + goto psm_loop; + } + + /* Associate */ + CHECK_FCT_DO( fd_msg_answ_associate( msg, req ), goto psm_end ); + + } + + /* Log incoming message */ + fd_hook_call(HOOK_MESSAGE_RECEIVED, msg, peer, NULL, fd_msg_pmdl_get(msg)); + + if (cur_state == STATE_OPEN_NEW) { + /* OK, we have received something, so the connection is supposedly now in OPEN state at the remote site */ + fd_psm_change_state(peer, STATE_OPEN ); + } + + /* Now handle non-link-local messages */ + if (fd_msg_is_routable(msg)) { + switch (cur_state) { + /* To maximize compatibility -- should not be a security issue here */ + case STATE_REOPEN: + case STATE_SUSPECT: + case STATE_CLOSING: + case STATE_CLOSING_GRACE: + TRACE_DEBUG(FULL, "Accepted a message while not in OPEN state... "); + /* The standard situation : */ + case STATE_OPEN_NEW: + case STATE_OPEN: + /* We received a valid routable message, update the expiry timer */ + CHECK_FCT_DO( fd_p_expi_update(peer), goto psm_end ); + + /* Set the message source and add the Route-Record */ + CHECK_FCT_DO( fd_msg_source_setrr( msg, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, fd_g_config->cnf_dict ), goto psm_end); + + if ((hdr->msg_flags & CMD_FLAG_REQUEST)) { + /* Mark the incoming request so that we know we have pending answers for this peer */ + CHECK_POSIX_DO( pthread_mutex_lock(&peer->p_state_mtx), goto psm_end ); + peer->p_reqin_count++; + CHECK_POSIX_DO( pthread_mutex_unlock(&peer->p_state_mtx), goto psm_end ); + } + + /* Requeue to the global incoming queue */ + CHECK_FCT_DO(fd_fifo_post(fd_g_incoming, &msg), goto psm_end ); + + /* Update the peer timer (only in OPEN state) */ + if ((cur_state == STATE_OPEN) && (!peer->p_flags.pf_dw_pending)) { + fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw); + } + break; + + /* In other states, we discard the message, it is either old or invalid to send it for the remote peer */ + case STATE_WAITCNXACK: + case STATE_WAITCNXACK_ELEC: + case STATE_WAITCEA: + case STATE_CLOSED: + default: { + /* In such case, just discard the message */ + char buf[128]; + snprintf(buf, sizeof(buf), "Received while peer state machine was in state %s.", STATE_STR(cur_state)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, buf, fd_msg_pmdl_get(msg)); + fd_msg_free(msg); + } + } + goto psm_loop; + } + + /* Link-local message: They must be understood by our dictionary, otherwise we return an error */ + { + struct msg * error = NULL; + int ret = fd_msg_parse_or_error( &msg, &error ); + if (ret != EBADMSG) { + CHECK_FCT_DO( ret, + { + char buf[256]; + snprintf(buf, sizeof(buf), "%s: An unexpected error occurred while parsing a link-local message", peer->p_hdr.info.pi_diamid); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, buf, fd_msg_pmdl_get(msg)); + fd_msg_free(msg); + goto psm_end; + } ); + } else { + if (msg == NULL) { + /* Send the error back to the peer */ + CHECK_FCT_DO( ret = fd_out_send(&error, NULL, peer, 0), ); + if (error) { + char buf[256]; + /* Only if an error occurred & the message was not saved / dumped */ + snprintf(buf, sizeof(buf), "%s: error sending a message", peer->p_hdr.info.pi_diamid); + fd_hook_call(HOOK_MESSAGE_DROPPED, error, peer, buf, fd_msg_pmdl_get(error)); + CHECK_FCT_DO( fd_msg_free(error), goto psm_end); + } + } else { + char buf[256]; + /* We received an invalid answer, let's disconnect */ + snprintf(buf, sizeof(buf), "%s: Received invalid answer to Base protocol message, disconnecting...", peer->p_hdr.info.pi_diamid); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, buf, fd_msg_pmdl_get(msg)); + CHECK_FCT_DO( fd_msg_free(msg), goto psm_end); + CHECK_FCT_DO( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL), goto psm_reset ); + } + goto psm_loop; + } + } + + /* Handle the LL message and update the expiry timer appropriately */ + switch (hdr->msg_code) { + case CC_CAPABILITIES_EXCHANGE: + CHECK_FCT_DO( fd_p_ce_msgrcv(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), + { + if (msg) + CHECK_FCT_DO( fd_msg_free(msg), ); + goto psm_reset; + } ); + break; + + case CC_DISCONNECT_PEER: + CHECK_FCT_DO( fd_p_dp_handle(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_reset ); + if (fd_peer_getstate(peer) == STATE_CLOSING) + goto psm_end; + + break; + + case CC_DEVICE_WATCHDOG: + /* We received a WDA message, update the expiry timer */ + if (!(hdr->msg_flags & CMD_FLAG_REQUEST)) + { + fd_p_expi_update(peer); + } + + CHECK_FCT_DO( fd_p_dw_handle(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_reset ); + break; + + default: + /* Unknown / unexpected / invalid message -- but validated by our dictionary */ + TRACE_DEBUG(INFO, "Invalid non-routable command received: %u.", hdr->msg_code); + if (hdr->msg_flags & CMD_FLAG_REQUEST) { + do { + /* Reply with an error code */ + CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msg, MSGFL_ANSW_ERROR ), break ); + + /* Set the error code */ + CHECK_FCT_DO( fd_msg_rescode_set(msg, "DIAMETER_COMMAND_UNSUPPORTED", "Or maybe the P-bit or application Id are erroneous.", NULL, 1 ), break ); + + /* Send the answer */ + CHECK_FCT_DO( fd_out_send(&msg, peer->p_cnxctx, peer, 0), break ); + } while (0); + } else { + /* We did ASK for it ??? */ + TRACE_DEBUG(INFO, "Received answer with erroneous 'is_routable' result..."); + } + + /* Cleanup the message if not done */ + if (msg) { + char buf[256]; + snprintf(buf, sizeof(buf), "Received un-handled non-routable command from peer '%s'.", peer->p_hdr.info.pi_diamid); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, buf, fd_msg_pmdl_get(msg)); + CHECK_FCT_DO( fd_msg_free(msg), /* continue */); + msg = NULL; + } + }; + + /* At this point the message must have been fully handled already */ + if (msg) { + char buf[256]; + snprintf(buf, sizeof(buf), "Internal error ('%s'): unhandled message.", peer->p_hdr.info.pi_diamid); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, buf, fd_msg_pmdl_get(msg)); + fd_msg_free(msg); + } + + goto psm_loop; + } + + /* The connection object is broken */ + if (event == FDEVP_CNX_ERROR) { + switch (cur_state) { + case STATE_WAITCNXACK_ELEC: + /* Abort the initiating side */ + fd_p_cnx_abort(peer, 0); + /* Process the receiver side */ + CHECK_FCT_DO( fd_p_ce_process_receiver(peer), goto psm_end ); + break; + + case STATE_WAITCEA: + case STATE_OPEN: + case STATE_OPEN_NEW: + case STATE_REOPEN: + case STATE_WAITCNXACK: + case STATE_SUSPECT: + default: + /* Mark the connection problem */ + peer->p_flags.pf_cnx_pb = 1; + + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "The connection was broken", NULL); + + /* Destroy the connection, restart the timer to a new connection attempt */ + fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); + + case STATE_CLOSED: + goto psm_reset; + + case STATE_CLOSING: + /* We sent a DPR so we are terminating, do not wait for DPA */ + goto psm_end; + + case STATE_CLOSING_GRACE: + if (peer->p_flags.pf_localterm) /* initiated here */ + goto psm_end; + + fd_psm_cleanup(peer, 0); + + /* Reset the timer for next connection attempt */ + fd_psm_next_timeout(peer, 1, fd_p_dp_newdelay(peer)); + goto psm_loop; + } + goto psm_loop; + } + + /* The connection notified a change in endpoints */ + if (event == FDEVP_CNX_EP_CHANGE) { + /* We actually don't care if we are in OPEN state here... */ + + /* Cleanup the remote LL and primary addresses */ + CHECK_FCT_DO( fd_ep_filter( &peer->p_hdr.info.pi_endpoints, EP_FL_CONF | EP_FL_DISC | EP_FL_ADV ), /* ignore the error */); + CHECK_FCT_DO( fd_ep_clearflags( &peer->p_hdr.info.pi_endpoints, EP_FL_PRIMARY ), /* ignore the error */); + + /* Get the new ones */ + CHECK_FCT_DO( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints), /* ignore the error */); + + /* We do not support local endpoints change currently, but it could be added here if needed (refresh fd_g_config->cnf_endpoints) */ + { + char * buf = NULL; + size_t len = 0; + LOG_D("Got low layer notification (IGNORED): remote endpoint(s) changed: %s", fd_ep_dump(&buf, &len, NULL, 0, 0, &peer->p_hdr.info.pi_endpoints) ?: "error"); + free(buf); + } + + /* Done */ + goto psm_loop; + } + + /* A new connection was established and CER containing this peer id was received */ + if (event == FDEVP_CNX_INCOMING) { + struct cnx_incoming * params = ev_data; + ASSERT(params); + + /* Handle the message */ + CHECK_FCT_DO( fd_p_ce_handle_newCER(¶ms->cer, peer, ¶ms->cnx, params->validate), goto psm_end ); + + /* Cleanup if needed */ + if (params->cnx) { + fd_cnx_destroy(params->cnx); + params->cnx = NULL; + } + if (params->cer) { + CHECK_FCT_DO( fd_msg_free(params->cer), ); + params->cer = NULL; + } + + /* Loop */ + free(ev_data); + goto psm_loop; + } + + /* A new connection has been established with the remote peer */ + if (event == FDEVP_CNX_ESTABLISHED) { + struct cnxctx * cnx = ev_data; + + /* Release the resources of the connecting thread */ + CHECK_POSIX_DO( pthread_join( peer->p_ini_thr, NULL), /* ignore, it is not a big deal */); + peer->p_ini_thr = (pthread_t)NULL; + + switch (cur_state) { + case STATE_WAITCNXACK_ELEC: + case STATE_WAITCNXACK: + LOG_D("%s: Connection established, %s", peer->p_hdr.info.pi_diamid, fd_cnx_getid(cnx)); + fd_p_ce_handle_newcnx(peer, cnx); + break; + + default: + /* Just abort the attempt and continue */ + TRACE_DEBUG(FULL, "Connection attempt successful but current state is %s, closing... (too slow?)", STATE_STR(cur_state)); + fd_cnx_destroy(cnx); + } + + goto psm_loop; + } + + /* A new connection has not been established with the remote peer */ + if (event == FDEVP_CNX_FAILED) { + + /* Release the resources of the connecting thread */ + CHECK_POSIX_DO( pthread_join( peer->p_ini_thr, NULL), /* ignore, it is not a big deal */); + peer->p_ini_thr = (pthread_t)NULL; + + switch (cur_state) { + case STATE_WAITCNXACK_ELEC: + /* Abort the initiating side */ + fd_p_cnx_abort(peer, 0); + /* Process the receiver side */ + CHECK_FCT_DO( fd_p_ce_process_receiver(peer), goto psm_end ); + break; + + case STATE_WAITCNXACK: + /* Go back to CLOSE */ + fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); + goto psm_reset; + + default: + /* Just ignore */ + TRACE_DEBUG(FULL, "Connection attempt failed but current state is %s, ignoring...", STATE_STR(cur_state)); + } + + goto psm_loop; + } + + /* The timeout for the current state has been reached */ + if (event == FDEVP_PSM_TIMEOUT) { + switch (cur_state) { + case STATE_OPEN: + case STATE_REOPEN: + case STATE_OPEN_NEW: + CHECK_FCT_DO( fd_p_dw_timeout(peer), goto psm_end ); + goto psm_loop; + + case STATE_CLOSED: + LOG_D("%s: Connecting...", peer->p_hdr.info.pi_diamid); + CHECK_FCT_DO( fd_psm_change_state(peer, STATE_WAITCNXACK), goto psm_end ); + fd_psm_next_timeout(peer, 0, CNX_TIMEOUT); + CHECK_FCT_DO( fd_p_cnx_init(peer), goto psm_end ); + goto psm_loop; + + case STATE_SUSPECT: + /* Mark the connection problem */ + peer->p_flags.pf_cnx_pb = 1; + case STATE_WAITCNXACK: + case STATE_WAITCEA: + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Timeout while waiting for remote peer", NULL); + case STATE_CLOSING: + /* Destroy the connection, restart the timer to a new connection attempt */ + fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); + goto psm_reset; + + case STATE_CLOSING_GRACE: + /* The grace period is completed, now close */ + if (peer->p_flags.pf_localterm) + goto psm_end; + + fd_psm_cleanup(peer, 0); + /* Reset the timer for next connection attempt */ + fd_psm_next_timeout(peer, 1, fd_p_dp_newdelay(peer)); + goto psm_loop; + + case STATE_WAITCNXACK_ELEC: + /* Abort the initiating side */ + fd_p_cnx_abort(peer, 0); + /* Process the receiver side */ + CHECK_FCT_DO( fd_p_ce_process_receiver(peer), goto psm_end ); + goto psm_loop; + + default: + ASSERT(0); /* implementation problem, we did not foresee this case? */ + } + } + + /* Default action : the handling has not yet been implemented. [for debug only] */ + TRACE_DEBUG(INFO, "Missing handler in PSM for '%s'\t<-- '%s'", STATE_STR(cur_state), fd_pev_str(event)); +psm_reset: + if (peer->p_flags.pf_delete) + goto psm_end; + fd_psm_cleanup(peer, 0); + goto psm_loop; + +psm_end: + LOG_N("%s: Going to ZOMBIE state (no more activity)", peer->p_hdr.info.pi_diamid); + fd_psm_cleanup(peer, 1); + TRACE_DEBUG(INFO, "'%s'\t-> STATE_ZOMBIE (terminated)\t'%s'", + STATE_STR(fd_peer_getstate(peer)), + peer->p_hdr.info.pi_diamid); + pthread_cleanup_pop(1); /* set STATE_ZOMBIE */ + peer->p_psm = (pthread_t)NULL; + pthread_detach(pthread_self()); + return NULL; +} + + +/************************************************************************/ +/* Functions to control the PSM */ +/************************************************************************/ +/* Create the PSM thread of one peer structure */ +int fd_psm_begin(struct fd_peer * peer ) +{ + TRACE_ENTRY("%p", peer); + + /* Check the peer and state are OK */ + CHECK_PARAMS( fd_peer_getstate(peer) == STATE_NEW ); + + /* Create the FIFO for events */ + CHECK_FCT( fd_fifo_new(&peer->p_events, 0) ); + + /* Create the PSM controler thread */ + CHECK_POSIX( pthread_create( &peer->p_psm, NULL, p_psm_th, peer ) ); + + /* We're done */ + return 0; +} + +/* End the PSM (clean ending) */ +int fd_psm_terminate(struct fd_peer * peer, char * reason ) +{ + TRACE_ENTRY("%p", peer); + CHECK_PARAMS( CHECK_PEER(peer) ); + + if (fd_peer_getstate(peer) != STATE_ZOMBIE) { + CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, reason) ); + } else { + TRACE_DEBUG(FULL, "Peer '%s' was already terminated", peer->p_hdr.info.pi_diamid); + } + return 0; +} + +/* End the PSM & cleanup the peer structure */ +void fd_psm_abord(struct fd_peer * peer ) +{ + TRACE_ENTRY("%p", peer); + + /* Cancel PSM thread */ + CHECK_FCT_DO( fd_thr_term(&peer->p_psm), /* continue */ ); + + /* Cleanup the data */ + fd_psm_cleanup(peer, 1); + + /* Destroy the event list */ + CHECK_FCT_DO( fd_fifo_del(&peer->p_events), /* continue */ ); + + /* Remaining cleanups are performed in fd_peer_free */ + return; +} + diff --git a/plat/diameter/libfdcore/p_sr.c b/plat/diameter/libfdcore/p_sr.c new file mode 100644 index 0000000..40d334f --- /dev/null +++ b/plat/diameter/libfdcore/p_sr.c @@ -0,0 +1,350 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Structure to store a sent request */ +struct sentreq { + struct fd_list chain; /* the "o" field points directly to the (new) hop-by-hop of the request (uint32_t *) */ + struct msg *req; /* A request that was sent and not yet answered. */ + uint32_t prevhbh;/* The value to set back in the hbh header when the message is retrieved */ + struct fd_list expire; /* the list of expiring requests */ + struct timespec timeout; /* Cache the expire date of the request so that the timeout thread does not need to get it each time. */ + struct timespec added_on; /* the time the request was added */ +}; + +/* Find an element in the hbh list, or the following one */ +static struct fd_list * find_or_next(struct fd_list * srlist, uint32_t hbh, int * match) +{ + struct fd_list * li; + *match = 0; + for (li = srlist->next; li != srlist; li = li->next) { + uint32_t * nexthbh = li->o; + if (*nexthbh < hbh) + continue; + if (*nexthbh == hbh) + *match = 1; + break; + } + return li; +} + +/* Similar but start from the end, since we add requests in growing hbh order usually */ +static struct fd_list * find_or_prev(struct fd_list * srlist, uint32_t hbh, int * match) +{ + struct fd_list * li; + *match = 0; + for (li = srlist->prev; li != srlist; li = li->prev) { + uint32_t * prevhbh = li->o; + if (*prevhbh > hbh) + continue; + if (*prevhbh == hbh) + *match = 1; + break; + } + return li; +} + +static void srl_dump(const char * text, struct fd_list * srlist) +{ + struct fd_list * li; + struct timespec now; + + LOG_D("%sSentReq list @%p:", text, srlist); + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), ); + + for (li = srlist->next; li != srlist; li = li->next) { + struct sentreq * sr = (struct sentreq *)li; + uint32_t * nexthbh = li->o; + + LOG_D(" - Next req (hbh:0x%x, prev:0x%x): [since %ld.%06ld sec]", *nexthbh, sr->prevhbh, + (long)((now.tv_nsec >= sr->added_on.tv_nsec) ? (now.tv_sec - sr->added_on.tv_sec) : (now.tv_sec - sr->added_on.tv_sec - 1)), + (long)((now.tv_nsec >= sr->added_on.tv_nsec) ? ((now.tv_nsec - sr->added_on.tv_nsec) / 1000) : ((now.tv_nsec - sr->added_on.tv_nsec + 1000000000) / 1000))); + } +} + +/* thread that handles messages expiring. The thread is started only when needed */ +static void * sr_expiry_th(void * arg) { + struct sr_list * srlist = arg; + + TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO( arg, return NULL ); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "ReqExp/%s", ((struct fd_peer *)(srlist->exp.o))->p_hdr.info.pi_diamid); + fd_log_threadname ( buf ); + } + + do { + struct timespec now; + struct sentreq * first; + struct msg * request; + struct fd_peer * sentto; + void (*expirecb)(void *, DiamId_t, size_t, struct msg **); + void * data; + int no_error; + + CHECK_POSIX_DO( pthread_mutex_lock(&srlist->mtx), return NULL ); + pthread_cleanup_push( fd_cleanup_mutex, &srlist->mtx ); + +loop: + no_error = 0; + + /* Check if there are expiring requests available */ + if (FD_IS_LIST_EMPTY(&srlist->exp)) { + /* Just wait for a change or cancelation */ + CHECK_POSIX_DO( pthread_cond_wait( &srlist->cnd, &srlist->mtx ), goto unlock ); + /* Restart the loop on wakeup */ + goto loop; + } + + /* Get the pointer to the request that expires first */ + first = (struct sentreq *)(srlist->exp.next->o); + + /* Get the current time */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), goto unlock ); + + /* If first request is not expired, we just wait until it happens */ + if ( TS_IS_INFERIOR( &now, &first->timeout ) ) { + + CHECK_POSIX_DO2( pthread_cond_timedwait( &srlist->cnd, &srlist->mtx, &first->timeout ), + ETIMEDOUT, /* ETIMEDOUT is a normal return value, continue */, + /* on other error, */ goto unlock ); + + /* on wakeup, loop */ + goto loop; + } + + /* Now, the first request in the list is expired; remove it and call the expirecb for it */ + request = first->req; + sentto = first->chain.head->o; + + TRACE_DEBUG(FULL, "Request %x was not answered by %s within the timer delay", *((uint32_t *)first->chain.o), sentto->p_hdr.info.pi_diamid); + + /* Restore the hbhid */ + *((uint32_t *)first->chain.o) = first->prevhbh; + + /* Free the sentreq information */ + fd_list_unlink(&first->chain); + srlist->cnt--; + srlist->cnt_lost++; /* We are not waiting for this answer anymore, but the remote peer may still be processing it. */ + fd_list_unlink(&first->expire); + free(first); + + no_error = 1; +unlock: + ; /* pthread_cleanup_pop sometimes expands as "} ..." and the label before this cause some compilers to complain... */ + pthread_cleanup_pop( 1 ); /* unlock the mutex */ + if (!no_error) + break; + + + /* Retrieve callback in the message */ + CHECK_FCT_DO( fd_msg_anscb_get( request, NULL, &expirecb, &data ), break); + ASSERT(expirecb); + + /* Clean up this expirecb from the message */ + CHECK_FCT_DO( fd_msg_anscb_reset( request, 0, 1 ), break); + + /* Call it */ + (*expirecb)(data, sentto->p_hdr.info.pi_diamid, sentto->p_hdr.info.pi_diamidlen, &request); + + /* If the callback did not dispose of the message, do it now */ + if (request) { + fd_hook_call(HOOK_MESSAGE_DROPPED, request, NULL, "Expiration period completed without an answer, and the expiry callback did not dispose of the message.", fd_msg_pmdl_get(request)); + CHECK_FCT_DO( fd_msg_free(request), /* ignore */ ); + } + + } while (1); + + ASSERT(0); /* we have encountered a problem, maybe time to signal the framework to terminate? */ + return NULL; +} + + +/* Store a new sent request */ +int fd_p_sr_store(struct sr_list * srlist, struct msg **req, uint32_t *hbhloc, uint32_t hbh_restore) +{ + struct sentreq * sr; + struct fd_list * prev; + int match; + struct timespec * ts; + + TRACE_ENTRY("%p %p %p %x", srlist, req, hbhloc, hbh_restore); + CHECK_PARAMS(srlist && req && *req && hbhloc); + + CHECK_MALLOC( sr = malloc(sizeof(struct sentreq)) ); + memset(sr, 0, sizeof(struct sentreq)); + fd_list_init(&sr->chain, hbhloc); + sr->req = *req; + sr->prevhbh = hbh_restore; + fd_list_init(&sr->expire, sr); + CHECK_SYS( clock_gettime(CLOCK_REALTIME, &sr->added_on) ); + + /* Search the place in the list */ + CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) ); + prev = find_or_prev(&srlist->srs, *hbhloc, &match); + if (match) { + TRACE_DEBUG(INFO, "A request with the same hop-by-hop Id (0x%x) was already sent: error", *hbhloc); + free(sr); + srl_dump("Current list of SR: ", &srlist->srs); + CHECK_POSIX_DO( pthread_mutex_unlock(&srlist->mtx), /* ignore */ ); + return EINVAL; + } + + /* Save in the list */ + *req = NULL; + fd_list_insert_after(prev, &sr->chain); + srlist->cnt++; + + /* In case of request with a timeout, also store in the timeout list */ + ts = fd_msg_anscb_gettimeout( sr->req ); + if (ts) { + struct fd_list * li; + + memcpy(&sr->timeout, ts, sizeof(struct timespec)); + + /* browse srlist->exp from the end */ + for (li = srlist->exp.prev; li != &srlist->exp; li = li->prev) { + struct sentreq * s = (struct sentreq *)(li->o); + if (TS_IS_INFERIOR(&s->timeout, ts)) + break; + } + + fd_list_insert_after(li, &sr->expire); + + /* if the thread does not exist yet, create it */ + if (srlist->thr == (pthread_t)NULL) { + CHECK_POSIX_DO( pthread_create(&srlist->thr, NULL, sr_expiry_th, srlist), /* continue anyway */); + } else { + /* or, if added in first position, signal the condvar to update the sleep time of the thread */ + if (li == &srlist->exp) { + CHECK_POSIX_DO( pthread_cond_signal(&srlist->cnd), /* continue anyway */); + } + } + } + + CHECK_POSIX( pthread_mutex_unlock(&srlist->mtx) ); + return 0; +} + +/* Fetch a request by hbh */ +int fd_p_sr_fetch(struct sr_list * srlist, uint32_t hbh, struct msg **req) +{ + struct sentreq * sr; + int match; + + TRACE_ENTRY("%p %x %p", srlist, hbh, req); + CHECK_PARAMS(srlist && req); + + /* Search the request in the list */ + CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) ); + sr = (struct sentreq *)find_or_next(&srlist->srs, hbh, &match); + if (!match) { + TRACE_DEBUG(INFO, "There is no saved request with this hop-by-hop id (%x)", hbh); + srl_dump("Current list of SR: ", &srlist->srs); + *req = NULL; + if (srlist->cnt_lost > 0) { + srlist->cnt_lost--; /* This is probably an answer for a request we already timedout. */ + } /* else, probably a bug in the remote peer */ + } else { + /* Restore hop-by-hop id */ + *((uint32_t *)sr->chain.o) = sr->prevhbh; + /* Unlink */ + fd_list_unlink(&sr->chain); + srlist->cnt--; + fd_list_unlink(&sr->expire); + *req = sr->req; + free(sr); + } + CHECK_POSIX( pthread_mutex_unlock(&srlist->mtx) ); + + /* do not stop the expire thread here, it might cause creating/destroying it very often otherwise */ + + /* Done */ + return 0; +} + +/* Failover requests (free or requeue routables) */ +void fd_p_sr_failover(struct sr_list * srlist) +{ + CHECK_POSIX_DO( pthread_mutex_lock(&srlist->mtx), /* continue anyway */ ); + while (!FD_IS_LIST_EMPTY(&srlist->srs)) { + struct sentreq * sr = (struct sentreq *)(srlist->srs.next); + fd_list_unlink(&sr->chain); + srlist->cnt--; + fd_list_unlink(&sr->expire); + if (fd_msg_is_routable(sr->req)) { + struct msg_hdr * hdr = NULL; + int ret; + + /* Set the 'T' flag */ + CHECK_FCT_DO(fd_msg_hdr(sr->req, &hdr), /* continue */); + if (hdr) + hdr->msg_flags |= CMD_FLAG_RETRANSMIT; + + /* Restore the original hop-by-hop id of the request */ + *((uint32_t *)sr->chain.o) = sr->prevhbh; + + fd_hook_call(HOOK_MESSAGE_FAILOVER, sr->req, (struct fd_peer *)srlist->srs.o, NULL, fd_msg_pmdl_get(sr->req)); + + /* Requeue for sending to another peer */ + CHECK_FCT_DO( ret = fd_fifo_post_noblock(fd_g_outgoing, (void *)&sr->req), + { + char buf[256]; + snprintf(buf, sizeof(buf), "Internal error: error while requeuing during failover: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_DROPPED, sr->req, NULL, buf, fd_msg_pmdl_get(sr->req)); + CHECK_FCT_DO(fd_msg_free(sr->req), /* What can we do more? */) + }); + } else { + /* Just free the request. */ + /* fd_hook_call(HOOK_MESSAGE_DROPPED, sr->req, NULL, "Sent & unanswered local message discarded during failover.", fd_msg_pmdl_get(sr->req)); */ + CHECK_FCT_DO(fd_msg_free(sr->req), /* Ignore */); + } + free(sr); + } + /* The list of expiring requests must be empty now */ + ASSERT( FD_IS_LIST_EMPTY(&srlist->exp) ); + ASSERT( srlist->cnt == 0 ); /* debug the counter management if needed */ + + CHECK_POSIX_DO( pthread_mutex_unlock(&srlist->mtx), /* continue anyway */ ); + + /* Terminate the expiry thread (must be done when the lock can be taken) */ + CHECK_FCT_DO( fd_thr_term(&srlist->thr), /* ignore error */ ); +} + diff --git a/plat/diameter/libfdcore/peers.c b/plat/diameter/libfdcore/peers.c new file mode 100644 index 0000000..af86da8 --- /dev/null +++ b/plat/diameter/libfdcore/peers.c @@ -0,0 +1,700 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Global list of peers */ +struct fd_list fd_g_peers = FD_LIST_INITIALIZER(fd_g_peers); +pthread_rwlock_t fd_g_peers_rw = PTHREAD_RWLOCK_INITIALIZER; + +/* List of active peers */ +struct fd_list fd_g_activ_peers = FD_LIST_INITIALIZER(fd_g_activ_peers); /* peers linked by their p_actives oredered by p_diamid */ +pthread_rwlock_t fd_g_activ_peers_rw = PTHREAD_RWLOCK_INITIALIZER; + +/* List of validation callbacks (registered with fd_peer_validate_register) */ +static struct fd_list validators = FD_LIST_INITIALIZER(validators); /* list items are simple fd_list with "o" pointing to the callback */ +static pthread_rwlock_t validators_rw = PTHREAD_RWLOCK_INITIALIZER; + + +/* Alloc / reinit a peer structure. if *ptr is not NULL, it must already point to a valid struct fd_peer. */ +int fd_peer_alloc(struct fd_peer ** ptr) +{ + struct fd_peer *p; + + TRACE_ENTRY("%p", ptr); + CHECK_PARAMS(ptr); + + if (*ptr) { + p = *ptr; + } else { + CHECK_MALLOC( p = malloc(sizeof(struct fd_peer)) ); + *ptr = p; + } + + /* Now initialize the content */ + memset(p, 0, sizeof(struct fd_peer)); + + fd_list_init(&p->p_hdr.chain, p); + + fd_list_init(&p->p_hdr.info.pi_endpoints, p); + fd_list_init(&p->p_hdr.info.runtime.pir_apps, p); + + p->p_eyec = EYEC_PEER; + CHECK_POSIX( pthread_mutex_init(&p->p_state_mtx, NULL) ); + + fd_list_init(&p->p_actives, p); + fd_list_init(&p->p_expiry, p); + CHECK_FCT( fd_fifo_new(&p->p_tosend, 1024) );// initial is 5 + CHECK_FCT( fd_fifo_new(&p->p_tofailover, 0) ); + p->p_hbh = lrand48(); + + fd_list_init(&p->p_sr.srs, p); + fd_list_init(&p->p_sr.exp, p); + CHECK_POSIX( pthread_mutex_init(&p->p_sr.mtx, NULL) ); + CHECK_POSIX( pthread_cond_init(&p->p_sr.cnd, NULL) ); + + fd_list_init(&p->p_connparams, p); + + return 0; +} + +/* Add a new peer entry */ +int fd_peer_add ( struct peer_info * info, const char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data ) +{ + struct fd_peer *p = NULL; + struct fd_list * li, *li_inf; + int ret = 0; + + TRACE_ENTRY("%p %p %p %p", info, orig_dbg, cb, cb_data); + CHECK_PARAMS(info && info->pi_diamid); + + if (info->config.pic_realm) { + if (!fd_os_is_valid_DiameterIdentity((os0_t)info->config.pic_realm, strlen(info->config.pic_realm))) { + TRACE_DEBUG(INFO, "'%s' is not a valid DiameterIdentity.", info->config.pic_realm); + return EINVAL; + } + } + + /* Create a structure to contain the new peer information */ + CHECK_FCT( fd_peer_alloc(&p) ); + + /* Copy the informations from the parameters received */ + p->p_hdr.info.pi_diamid = info->pi_diamid; + CHECK_FCT( fd_os_validate_DiameterIdentity(&p->p_hdr.info.pi_diamid, &p->p_hdr.info.pi_diamidlen, 1) ); + + memcpy( &p->p_hdr.info.config, &info->config, sizeof(p->p_hdr.info.config) ); + + /* Duplicate the strings if provided */ + if (info->config.pic_realm) { + CHECK_MALLOC( p->p_hdr.info.config.pic_realm = strdup(info->config.pic_realm) ); + } + if (info->config.pic_priority) { + CHECK_MALLOC( p->p_hdr.info.config.pic_priority = strdup(info->config.pic_priority) ); + } + + /* Move the list of endpoints into the peer */ + if (info->pi_endpoints.next) + while (!FD_IS_LIST_EMPTY( &info->pi_endpoints ) ) { + li = info->pi_endpoints.next; + fd_list_unlink(li); + fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li); + } + + /* The internal data */ + if (orig_dbg) { + CHECK_MALLOC( p->p_dbgorig = strdup(orig_dbg) ); + } else { + CHECK_MALLOC( p->p_dbgorig = strdup("unspecified") ); + } + p->p_cb = cb; + p->p_cb_data = cb_data; + + /* Ok, now check if we don't already have an entry with the same Diameter Id, and insert this one */ + CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); + li_inf = &fd_g_peers; + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct fd_peer * next = (struct fd_peer *)li; + int cont; + int cmp = fd_os_almostcasesrch( p->p_hdr.info.pi_diamid, p->p_hdr.info.pi_diamidlen, + next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen, + &cont ); + if (cmp > 0) + li_inf = li; /* it will come after this element, for sure */ + + if (cmp == 0) { + ret = EEXIST; /* we have a duplicate */ + break; + } + if (!cont) + break; + } + + /* We can insert the new peer object */ + if (! ret) + do { + /* Update expiry list */ + CHECK_FCT_DO( ret = fd_p_expi_update( p ), break ); + + /* Insert the new element in the list */ + fd_list_insert_after( li_inf, &p->p_hdr.chain ); + } while (0); + + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); + if (ret) { + CHECK_FCT( fd_peer_free(&p) ); + } else { + CHECK_FCT( fd_psm_begin(p) ); + } + return ret; +} + +/* Search for a peer */ +int fd_peer_getbyid( DiamId_t diamid, size_t diamidlen, int igncase, struct peer_hdr ** peer ) +{ + struct fd_list * li; + TRACE_ENTRY("%p %zd %d %p", diamid, diamidlen, igncase, peer); + CHECK_PARAMS( diamid && diamidlen && peer ); + + *peer = NULL; + + /* Search in the list */ + CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) ); + if (igncase) { + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct fd_peer * next = (struct fd_peer *)li; + int cmp, cont; + cmp = fd_os_almostcasesrch( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen, &cont ); + if (cmp == 0) { + *peer = &next->p_hdr; + break; + } + if (!cont) + break; + } + } else { + LOG_D("fd_peer_getbyid enter"); + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct fd_peer * next = (struct fd_peer *)li; + LOG_D("fd_peer_getbyid src[%u,%s] peer[%u,%s]", + (unsigned int)diamidlen, + diamid, + (unsigned int)( next->p_hdr.info.pi_diamidlen ), + next->p_hdr.info.pi_diamid); + int cmp = fd_os_cmp( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen ); + if (cmp > 0) + continue; + if (cmp == 0) + *peer = &next->p_hdr; + break; + } + } + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); + + return 0; +} + + +#define free_null( _v ) \ + if (_v) { \ + free(_v); \ + (_v) = NULL; \ + } + +#define free_list( _l ) \ + while (!FD_IS_LIST_EMPTY(_l)) { \ + struct fd_list * __li = ((struct fd_list *)(_l))->next; \ + fd_list_unlink(__li); \ + free(__li); \ + } + +/* Empty the lists of p_tosend, p_failover, and p_sentreq messages */ +void fd_peer_failover_msg(struct fd_peer * peer) +{ + struct msg *m; + TRACE_ENTRY("%p", peer); + CHECK_PARAMS_DO(CHECK_PEER(peer), return); + + /* Requeue all messages in the "out" queue */ + while ( fd_fifo_tryget(peer->p_tosend, &m) == 0 ) { + /* but only if they are routable */ + if (fd_msg_is_routable(m)) { + fd_hook_call(HOOK_MESSAGE_FAILOVER, m, peer, NULL, fd_msg_pmdl_get(m)); + CHECK_FCT_DO(fd_fifo_post_noblock(fd_g_outgoing, (void *)&m), + { + /* fallback: destroy the message */ + fd_hook_call(HOOK_MESSAGE_DROPPED, m, NULL, "Internal error: unable to requeue this message during failover process", fd_msg_pmdl_get(m)); + CHECK_FCT_DO(fd_msg_free(m), /* What can we do more? */) + } ); + } else { + /* Just free it */ + /* fd_hook_call(HOOK_MESSAGE_DROPPED, m, NULL, "Non-routable message freed during handover", fd_msg_pmdl_get(m)); */ + CHECK_FCT_DO(fd_msg_free(m), /* What can we do more? */) + } + } + + /* Requeue all messages in the "failover" queue */ + while ( fd_fifo_tryget(peer->p_tofailover, &m) == 0 ) { + fd_hook_call(HOOK_MESSAGE_FAILOVER, m, peer, NULL, fd_msg_pmdl_get(m)); + CHECK_FCT_DO(fd_fifo_post_noblock(fd_g_outgoing, (void *)&m), + { + /* fallback: destroy the message */ + fd_hook_call(HOOK_MESSAGE_DROPPED, m, NULL, "Internal error: unable to requeue this message during failover process", fd_msg_pmdl_get(m)); + CHECK_FCT_DO(fd_msg_free(m), /* What can we do more? */) + } ); + } + + /* Requeue all routable sent requests */ + fd_p_sr_failover(&peer->p_sr); + + /* Done */ + return; +} + +/* Describe the current connection */ +int fd_peer_cnx_proto_info(struct peer_hdr *peer, char * buf, size_t len) +{ + struct fd_peer * p = (struct fd_peer *)peer; + TRACE_ENTRY("%p %p %zd", peer, buf, len); + CHECK_PARAMS(CHECK_PEER(peer) && buf && len); + + if (p->p_cnxctx) { + CHECK_FCT(fd_cnx_proto_info(p->p_cnxctx, buf, len)); + } else if (p->p_receiver) { + CHECK_FCT(fd_cnx_proto_info(p->p_receiver, buf, len)); + } else { + snprintf(buf, len, "Not Connected"); + } + + return 0; +} + +/* Return the value of srlist->cnt */ +int fd_peer_get_load_pending(struct peer_hdr *peer, long * to_receive, long * to_send) +{ + struct fd_peer * p = (struct fd_peer *)peer; + TRACE_ENTRY("%p %p %p", peer, to_receive, to_send); + CHECK_PARAMS(CHECK_PEER(peer)); + + if (to_receive) { + CHECK_POSIX( pthread_mutex_lock(&p->p_sr.mtx) ); + *to_receive = p->p_sr.cnt; + CHECK_POSIX( pthread_mutex_unlock(&p->p_sr.mtx) ); + } + if (to_send) { + CHECK_POSIX( pthread_mutex_lock(&p->p_state_mtx) ); + *to_send = p->p_reqin_count; + CHECK_POSIX( pthread_mutex_unlock(&p->p_state_mtx) ); + } + + return 0; +} + + +/* Destroy a structure once cleanups have been performed (fd_psm_abord, ...) */ +int fd_peer_free(struct fd_peer ** ptr) +{ + struct fd_peer *p; + + TRACE_ENTRY("%p", ptr); + CHECK_PARAMS(ptr); + p = *ptr; + *ptr = NULL; + CHECK_PARAMS(p); + + CHECK_PARAMS( FD_IS_LIST_EMPTY(&p->p_hdr.chain) ); + + free_null(p->p_hdr.info.pi_diamid); + + free_null(p->p_hdr.info.config.pic_realm); + free_null(p->p_hdr.info.config.pic_priority); + + free_null(p->p_hdr.info.runtime.pir_realm); + free_null(p->p_hdr.info.runtime.pir_prodname); + free_list( &p->p_hdr.info.runtime.pir_apps ); + + free_list( &p->p_hdr.info.pi_endpoints ); + + free_null(p->p_dbgorig); + + fd_list_unlink(&p->p_expiry); + fd_list_unlink(&p->p_actives); + + CHECK_FCT_DO( fd_fifo_del(&p->p_tosend), /* continue */ ); + CHECK_FCT_DO( fd_fifo_del(&p->p_tofailover), /* continue */ ); + CHECK_POSIX_DO( pthread_mutex_destroy(&p->p_state_mtx), /* continue */); + CHECK_POSIX_DO( pthread_mutex_destroy(&p->p_sr.mtx), /* continue */); + CHECK_POSIX_DO( pthread_cond_destroy(&p->p_sr.cnd), /* continue */); + + /* If the callback is still around... */ + if (p->p_cb) + (*p->p_cb)(NULL, p->p_cb_data); + + /* Free the structure */ + free(p); + return 0; +} + +/* Terminate peer module (destroy all peers, first gently, then violently) */ +int fd_peer_fini() +{ + struct fd_list * li; + struct fd_list purge = FD_LIST_INITIALIZER(purge); /* Store zombie peers here */ + int list_empty; + struct timespec wait_until, now; + + TRACE_ENTRY(); + + CHECK_FCT_DO(fd_p_expi_fini(), /* continue */); + + TRACE_DEBUG(INFO, "Sending terminate signal to all peer connections"); + + CHECK_FCT_DO( pthread_rwlock_wrlock(&fd_g_peers_rw), /* continue */ ); + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct fd_peer * peer = (struct fd_peer *)li->o; + + if (fd_peer_getstate(peer) != STATE_ZOMBIE) { + CHECK_FCT_DO( fd_psm_terminate(peer, "REBOOTING"), /* continue */ ); + } else { + li = li->prev; /* to avoid breaking the loop */ + fd_list_unlink(&peer->p_hdr.chain); + fd_list_insert_before(&purge, &peer->p_hdr.chain); + } + } + list_empty = FD_IS_LIST_EMPTY(&fd_g_peers); + CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); + + if (!list_empty) { + CHECK_SYS( clock_gettime(CLOCK_REALTIME, &now) ); + fd_psm_start(); /* just in case */ + TRACE_DEBUG(INFO, "Waiting for connections shutdown... (%d sec max)", DPR_TIMEOUT + 1); + wait_until.tv_sec = now.tv_sec + DPR_TIMEOUT + 1; + wait_until.tv_nsec = now.tv_nsec; + } + + while ((!list_empty) && (TS_IS_INFERIOR(&now, &wait_until))) { + + /* Allow the PSM(s) to execute */ + usleep(100000); + + /* Remove zombie peers */ + CHECK_FCT_DO( pthread_rwlock_wrlock(&fd_g_peers_rw), /* continue */ ); + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct fd_peer * peer = (struct fd_peer *)li->o; + if (fd_peer_getstate(peer) == STATE_ZOMBIE) { + li = li->prev; /* to avoid breaking the loop */ + fd_list_unlink(&peer->p_hdr.chain); + fd_list_insert_before(&purge, &peer->p_hdr.chain); + } + } + list_empty = FD_IS_LIST_EMPTY(&fd_g_peers); + CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); + CHECK_SYS( clock_gettime(CLOCK_REALTIME, &now) ); + } + + if (!list_empty) { + TRACE_DEBUG(INFO, "Forcing connections shutdown"); + CHECK_FCT_DO( pthread_rwlock_wrlock(&fd_g_peers_rw), /* continue */ ); + while (!FD_IS_LIST_EMPTY(&fd_g_peers)) { + struct fd_peer * peer = (struct fd_peer *)(fd_g_peers.next->o); + fd_psm_abord(peer); + fd_list_unlink(&peer->p_hdr.chain); + fd_list_insert_before(&purge, &peer->p_hdr.chain); + } + CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); + } + + /* Free memory objects of all peers */ + while (!FD_IS_LIST_EMPTY(&purge)) { + struct fd_peer * peer = (struct fd_peer *)(purge.next->o); + fd_list_unlink(&peer->p_hdr.chain); + fd_peer_free(&peer); + } + + /* Now empty the validators list */ + CHECK_FCT_DO( pthread_rwlock_wrlock(&validators_rw), /* continue */ ); + while (!FD_IS_LIST_EMPTY( &validators )) { + struct fd_list * v = validators.next; + fd_list_unlink(v); + free(v); + } + CHECK_FCT_DO( pthread_rwlock_unlock(&validators_rw), /* continue */ ); + + return 0; +} + +/* Dump info of one peer */ +DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump, struct peer_hdr * p, int details) +{ + FD_DUMP_HANDLE_OFFSET(); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{peer}(@%p): ", p), return NULL); + + if (!CHECK_PEER(p)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); + } else { + struct fd_peer * peer = (struct fd_peer *)p; + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s [%s, cnt:%ldsr,%ldpa]", peer->p_hdr.info.pi_diamid, STATE_STR(fd_peer_getstate(peer)), peer->p_sr.cnt, peer->p_reqin_count), return NULL); + if (details > 0) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " rlm:%s", peer->p_hdr.info.runtime.pir_realm ?: ""), return NULL); + if (peer->p_hdr.info.runtime.pir_prodname) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " ['%s' %u]", peer->p_hdr.info.runtime.pir_prodname, peer->p_hdr.info.runtime.pir_firmrev), return NULL); + } + } + if (details > 1) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " [from:%s] flags:%s%s%s%s%s%s%s%s lft:%ds", + peer->p_dbgorig ?: "unset", + peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_DEFAULT ? "-" : + (peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP ? "4" : "6"), + peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_DEFAULT ? "-" : + (peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_TCP ? "T" : "S"), + peer->p_hdr.info.config.pic_flags.alg ? "P" : "-", + peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE ? "N" :"-", + peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD ? "O" :"-", + peer->p_hdr.info.config.pic_flags.sctpsec & PI_SCTPSEC_3436 ? "3" :"-", + peer->p_hdr.info.config.pic_flags.exp ? "E" : "-", + peer->p_hdr.info.config.pic_flags.persist ? "P" : "-", + peer->p_hdr.info.config.pic_lft), return NULL); + } + + } + + return *buf; +} + +/* Dump the list of peers */ +DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump_list, int details) +{ + struct fd_list * li; + FD_DUMP_HANDLE_OFFSET(); + + CHECK_FCT_DO( pthread_rwlock_rdlock(&fd_g_peers_rw), /* continue */ ); + + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + CHECK_MALLOC_DO( fd_peer_dump(FD_DUMP_STD_PARAMS, (struct peer_hdr *)li->o, details), break); + if (li->next != &fd_g_peers) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), break); + } + } + + CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); + return *buf; +} + +static struct dict_object *avp_oh_model = NULL; +static pthread_mutex_t cache_avp_lock = PTHREAD_MUTEX_INITIALIZER; + +/* Handle an incoming CER request on a new connection */ +int fd_peer_handle_newCER( struct msg ** cer, struct cnxctx ** cnx ) +{ + struct msg * msg; + struct avp *avp_oh; + struct avp_hdr * avp_hdr; + struct fd_list * li, *li_inf; + int found = 0; + int ret = 0; + struct fd_peer * peer; + struct cnx_incoming * ev_data; + + TRACE_ENTRY("%p %p", cer, cnx); + CHECK_PARAMS(cer && *cer && cnx && *cnx); + + msg = *cer; + + /* If needed, resolve the dictionary model for Origin-Host */ + CHECK_POSIX( pthread_mutex_lock(&cache_avp_lock) ); + if (!avp_oh_model) { + avp_code_t code = AC_ORIGIN_HOST; + CHECK_FCT_DO( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE, &code, &avp_oh_model, ENOENT), + { LOG_E("Cannot find Origin-Host AVP definition in the dictionary!"); (void) pthread_mutex_unlock(&cache_avp_lock); return __ret__; } ); + } + CHECK_POSIX( pthread_mutex_unlock(&cache_avp_lock) ); + + /* Find the Diameter Identity of the remote peer in the message */ + CHECK_FCT( fd_msg_search_avp ( msg, avp_oh_model, &avp_oh ) ); + ASSERT(avp_oh); /* otherwise it should not have passed rules validation, right? */ + CHECK_FCT( fd_msg_avp_hdr ( avp_oh, &avp_hdr ) ); + + /* First, check if the Origin-Host value is valid */ + if (!fd_os_is_valid_DiameterIdentity(avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len)) { + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, cer, MSGFL_ANSW_ERROR ) ); + CHECK_FCT( fd_msg_rescode_set(*cer, "DIAMETER_INVALID_AVP_VALUE", + "Your Origin-Host contains invalid characters.", avp_oh, 1 ) ); + + fd_hook_call(HOOK_PEER_CONNECT_FAILED, *cer, NULL, "Received CER with invalid Origin-Host AVP", NULL); + + CHECK_FCT( fd_out_send(cer, *cnx, NULL, 0) ); + return EINVAL; + } + + /* Search if we already have this peer id in our list. We take directly the write lock so that we don't need to upgrade if it is a new peer. + * There is space for a small optimization here if needed. + */ + CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); + + li_inf = &fd_g_peers; + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + int cmp, cont; + peer = (struct fd_peer *)li; + cmp = fd_os_almostcasesrch( avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, &cont ); + if (cmp > 0) { + li_inf = li; + } + if (cmp == 0) { + found = 1; + break; + } + if (!cont) + break; + } + + if (!found) { + /* Create a new peer entry for this new remote peer */ + peer = NULL; + CHECK_FCT_DO( ret = fd_peer_alloc(&peer), goto out ); + + /* Set the peer Diameter Id and the responder flag parameters */ + CHECK_MALLOC_DO( peer->p_hdr.info.pi_diamid = os0dup(avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len), + { ret = ENOMEM; goto out; } ); + peer->p_hdr.info.pi_diamidlen = avp_hdr->avp_value->os.len; + CHECK_MALLOC_DO( peer->p_dbgorig = strdup(fd_cnx_getid(*cnx)), { ret = ENOMEM; goto out; } ); + peer->p_flags.pf_responder = 1; + peer->p_flags.pf_delete = 1; + + LOG_D("Created new peer object for incoming CER: %s", peer->p_hdr.info.pi_diamid); + +#ifndef DISABLE_PEER_EXPIRY + /* Set this peer to expire on inactivity */ + peer->p_hdr.info.config.pic_flags.exp = PI_EXP_INACTIVE; + peer->p_hdr.info.config.pic_lft = 3600; /* 1 hour without any message + -- RFC3539 states that this must not be inferior to BRINGDOWN_INTERVAL = 5 minutes */ + + CHECK_FCT_DO( ret = fd_p_expi_update( peer ), goto out ); +#endif /* DISABLE_PEER_EXPIRY */ + + /* Insert the new peer in the list (the PSM will take care of setting the expiry after validation) */ + fd_list_insert_after( li_inf, &peer->p_hdr.chain ); + + /* Start the PSM, which will receive the event below */ + CHECK_FCT_DO( ret = fd_psm_begin(peer), goto out ); + } else { + /* Check if the peer is in zombie state */ + if (fd_peer_getstate(peer) == STATE_ZOMBIE) { + /* Re-activate the peer */ + if (peer->p_hdr.info.config.pic_flags.exp) + peer->p_flags.pf_responder = 1; + CHECK_POSIX_DO( pthread_mutex_lock(&peer->p_state_mtx), ); + peer->p_state = STATE_NEW; + CHECK_POSIX_DO( pthread_mutex_unlock(&peer->p_state_mtx), ); + peer->p_flags.pf_localterm = 0; + CHECK_FCT_DO( ret = fd_psm_begin(peer), goto out ); + } + } + + /* Send the new connection event to the PSM */ + CHECK_MALLOC_DO( ev_data = malloc(sizeof(struct cnx_incoming)), { ret = ENOMEM; goto out; } ); + memset(ev_data, 0, sizeof(*ev_data)); + + ev_data->cer = msg; + ev_data->cnx = *cnx; + ev_data->validate = !found; + + CHECK_FCT_DO( ret = fd_event_send(peer->p_events, FDEVP_CNX_INCOMING, sizeof(*ev_data), ev_data), goto out ); + +out: + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); + + if (ret == 0) { + /* Reset the "out" parameters, so that they are not cleanup on function return. */ + *cer = NULL; + *cnx = NULL; + } else { + char buf[1024]; + snprintf(buf, sizeof(buf), "An error occurred while processing new incoming CER: %s", strerror(ret)); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, *cer, NULL, buf, NULL); + } + + return ret; +} + +/* Save a callback to accept / reject incoming unknown peers */ +int fd_peer_validate_register ( int (*peer_validate)(struct peer_info * /* info */, int * /* auth */, int (**cb2)(struct peer_info *)) ) +{ + struct fd_list * v; + + TRACE_ENTRY("%p", peer_validate); + CHECK_PARAMS(peer_validate); + + /* Alloc a new entry */ + CHECK_MALLOC( v = malloc(sizeof(struct fd_list)) ); + fd_list_init( v, peer_validate ); + + /* Add at the beginning of the list */ + CHECK_FCT( pthread_rwlock_wrlock(&validators_rw) ); + fd_list_insert_after(&validators, v); + CHECK_FCT( pthread_rwlock_unlock(&validators_rw)); + + /* Done! */ + return 0; +} + +/* Validate a peer by calling the callbacks in turn -- return 0 if the peer is validated, ! 0 in case of error (>0) or if the peer is rejected (-1) */ +int fd_peer_validate( struct fd_peer * peer ) +{ + int ret = 0; + struct fd_list * v; + + CHECK_FCT( pthread_rwlock_rdlock(&validators_rw) ); + for (v = validators.next; v != &validators; v = v->next) { + int auth = 0; + pthread_cleanup_push(fd_cleanup_rwlock, &validators_rw); + CHECK_FCT_DO( ret = ((int(*)(struct peer_info *, int *, int (**)(struct peer_info *)))(v->o)) (&peer->p_hdr.info, &auth, &peer->p_cb2), ); + pthread_cleanup_pop(0); + if (ret) + goto out; + if (auth) { + ret = (auth > 0) ? 0 : -1; + goto out; + } + peer->p_cb2 = NULL; + } + + /* No callback has given a firm result, the default is to reject */ + ret = -1; + ret = 0; +out: + CHECK_FCT( pthread_rwlock_unlock(&validators_rw)); + return ret; +} diff --git a/plat/diameter/libfdcore/queues.c b/plat/diameter/libfdcore/queues.c new file mode 100644 index 0000000..0603b7b --- /dev/null +++ b/plat/diameter/libfdcore/queues.c @@ -0,0 +1,86 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* The global message queues */ +struct fifo * fd_g_incoming = NULL; +struct fifo * fd_g_outgoing = NULL; +struct fifo * fd_g_local = NULL; + +/* Initialize the message queues. */ +#define FD_MSG_QUEUE_SIZE 2048 + +int fd_queues_init(void) +{ + TRACE_ENTRY(); + CHECK_FCT( fd_fifo_new ( &fd_g_incoming, FD_MSG_QUEUE_SIZE ) ); + CHECK_FCT( fd_fifo_new ( &fd_g_outgoing, FD_MSG_QUEUE_SIZE ) ); + CHECK_FCT( fd_fifo_new ( &fd_g_local, FD_MSG_QUEUE_SIZE ) ); + return 0; +} + +/* Destroy a queue after emptying it (and dumping the content) */ +int fd_queues_fini(struct fifo ** queue) +{ + struct msg * msg; + int ret = 0; + + TRACE_ENTRY("%p", queue); + + /* Note : the threads that post into this queue should already been stopped before this !!! */ + + CHECK_PARAMS(queue); + if (*queue == NULL) + return 0; /* the queue was not already initialized */ + + /* Empty all contents */ + while (1) { + /* Check if there is a message in the queue */ + ret = fd_fifo_tryget(*queue, &msg); + if (ret == EWOULDBLOCK) + break; + CHECK_FCT(ret); + + /* We got one! */ + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, "Message lost because framework is terminating.", fd_msg_pmdl_get(msg)); + fd_msg_free(msg); + } + + /* Now, delete the empty queue */ + CHECK_FCT( fd_fifo_del ( queue ) ); + + return 0; +} diff --git a/plat/diameter/libfdcore/routing_dispatch.c b/plat/diameter/libfdcore/routing_dispatch.c new file mode 100644 index 0000000..014bae5 --- /dev/null +++ b/plat/diameter/libfdcore/routing_dispatch.c @@ -0,0 +1,1337 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/********************************************************************************/ +/* First part : handling the extensions callbacks */ +/********************************************************************************/ + +/* Lists of the callbacks, and locks to protect them */ +static pthread_rwlock_t rt_fwd_lock = PTHREAD_RWLOCK_INITIALIZER; +static struct fd_list rt_fwd_list = FD_LIST_INITIALIZER_O(rt_fwd_list, &rt_fwd_lock); + +static pthread_rwlock_t rt_out_lock = PTHREAD_RWLOCK_INITIALIZER; +static struct fd_list rt_out_list = FD_LIST_INITIALIZER_O(rt_out_list, &rt_out_lock); + +/* Items in the lists are the same */ +struct rt_hdl { + struct fd_list chain; /* link in the rt_fwd_list or rt_out_list */ + void * cbdata; /* the registered data */ + union { + int order; /* This value is used to sort the list */ + int dir; /* It is the direction for FWD handlers */ + int prio; /* and the priority for OUT handlers */ + }; + union { + int (*rt_fwd_cb)(void * cbdata, struct msg ** msg); + int (*rt_out_cb)(void * cbdata, struct msg ** msg, struct fd_list * candidates); + }; +}; + +/* Add a new entry in the list */ +static int add_ordered(struct rt_hdl * new, struct fd_list * list) +{ + /* The list is ordered by prio parameter */ + struct fd_list * li; + + CHECK_POSIX( pthread_rwlock_wrlock(list->o) ); + + for (li = list->next; li != list; li = li->next) { + struct rt_hdl * h = (struct rt_hdl *) li; + if (new->order <= h->order) + break; + } + + fd_list_insert_before(li, &new->chain); + + CHECK_POSIX( pthread_rwlock_unlock(list->o) ); + + return 0; +} + +/* Register a new FWD callback */ +int fd_rt_fwd_register ( int (*rt_fwd_cb)(void * cbdata, struct msg ** msg), void * cbdata, enum fd_rt_fwd_dir dir, struct fd_rt_fwd_hdl ** handler ) +{ + struct rt_hdl * new; + + TRACE_ENTRY("%p %p %d %p", rt_fwd_cb, cbdata, dir, handler); + CHECK_PARAMS( rt_fwd_cb ); + CHECK_PARAMS( (dir >= RT_FWD_REQ) && ( dir <= RT_FWD_ANS) ); + + /* Create a new container */ + CHECK_MALLOC(new = malloc(sizeof(struct rt_hdl))); + memset(new, 0, sizeof(struct rt_hdl)); + + /* Write the content */ + fd_list_init(&new->chain, NULL); + new->cbdata = cbdata; + new->dir = dir; + new->rt_fwd_cb = rt_fwd_cb; + + /* Save this in the list */ + CHECK_FCT( add_ordered(new, &rt_fwd_list) ); + + /* Give it back to the extension if needed */ + if (handler) + *handler = (void *)new; + + return 0; +} + +/* Remove it */ +int fd_rt_fwd_unregister ( struct fd_rt_fwd_hdl * handler, void ** cbdata ) +{ + struct rt_hdl * del; + TRACE_ENTRY( "%p %p", handler, cbdata); + CHECK_PARAMS( handler ); + + del = (struct rt_hdl *)handler; + CHECK_PARAMS( del->chain.head == &rt_fwd_list ); + + /* Unlink */ + CHECK_POSIX( pthread_rwlock_wrlock(&rt_fwd_lock) ); + fd_list_unlink(&del->chain); + CHECK_POSIX( pthread_rwlock_unlock(&rt_fwd_lock) ); + + if (cbdata) + *cbdata = del->cbdata; + + free(del); + return 0; +} + +/* Register a new OUT callback */ +int fd_rt_out_register ( int (*rt_out_cb)(void * cbdata, struct msg ** pmsg, struct fd_list * candidates), void * cbdata, int priority, struct fd_rt_out_hdl ** handler ) +{ + struct rt_hdl * new; + + TRACE_ENTRY("%p %p %d %p", rt_out_cb, cbdata, priority, handler); + CHECK_PARAMS( rt_out_cb ); + + /* Create a new container */ + CHECK_MALLOC(new = malloc(sizeof(struct rt_hdl))); + memset(new, 0, sizeof(struct rt_hdl)); + + /* Write the content */ + fd_list_init(&new->chain, NULL); + new->cbdata = cbdata; + new->prio = priority; + new->rt_out_cb = rt_out_cb; + + /* Save this in the list */ + CHECK_FCT( add_ordered(new, &rt_out_list) ); + + /* Give it back to the extension if needed */ + if (handler) + *handler = (void *)new; + + return 0; +} + +/* Remove it */ +int fd_rt_out_unregister ( struct fd_rt_out_hdl * handler, void ** cbdata ) +{ + struct rt_hdl * del; + TRACE_ENTRY( "%p %p", handler, cbdata); + CHECK_PARAMS( handler ); + + del = (struct rt_hdl *)handler; + CHECK_PARAMS( del->chain.head == &rt_out_list ); + + /* Unlink */ + CHECK_POSIX( pthread_rwlock_wrlock(&rt_out_lock) ); + fd_list_unlink(&del->chain); + CHECK_POSIX( pthread_rwlock_unlock(&rt_out_lock) ); + + if (cbdata) + *cbdata = del->cbdata; + + free(del); + return 0; +} + +/********************************************************************************/ +/* Some default OUT routing callbacks */ +/********************************************************************************/ + +/* Prevent sending to peers that do not support the message application */ +static int dont_send_if_no_common_app(void * cbdata, struct msg ** pmsg, struct fd_list * candidates) +{ + struct msg * msg = *pmsg; + struct fd_list * li; + struct msg_hdr * hdr; + + TRACE_ENTRY("%p %p %p", cbdata, msg, candidates); + CHECK_PARAMS(msg && candidates); + + CHECK_FCT( fd_msg_hdr(msg, &hdr) ); + + /* For Base Diameter Protocol, every peer is supposed to support it, so skip */ + if (hdr->msg_appl == 0) + return 0; + + /* Otherwise, check that the peers support the application */ + for (li = candidates->next; li != candidates; li = li->next) { + struct rtd_candidate *c = (struct rtd_candidate *) li; + struct fd_peer * peer; + struct fd_app *found; + CHECK_FCT( fd_peer_getbyid( c->diamid, c->diamidlen, 0, (void *)&peer ) ); + if (peer && !peer->p_hdr.info.runtime.pir_relay) { + /* Check if the remote peer advertised the message's appli */ + CHECK_FCT( fd_app_check(&peer->p_hdr.info.runtime.pir_apps, hdr->msg_appl, &found) ); + if (!found) + c->score += FD_SCORE_NO_DELIVERY; + } + } + + return 0; +} + +/* Detect if the Destination-Host and Destination-Realm match the peer */ +static int score_destination_avp(void * cbdata, struct msg ** pmsg, struct fd_list * candidates) +{ + struct msg * msg = *pmsg; + struct fd_list * li; + struct avp * avp; + union avp_value *dh = NULL, *dr = NULL; + + TRACE_ENTRY("%p %p %p", cbdata, msg, candidates); + CHECK_PARAMS(msg && candidates); + + /* Search the Destination-Host and Destination-Realm AVPs -- we could also use fd_msg_search_avp here, but this one is slightly more efficient */ + CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) ); + while (avp) { + struct avp_hdr * ahdr; + CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) ); + + if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) { + switch (ahdr->avp_code) { + case AC_DESTINATION_HOST: + /* Parse this AVP */ + CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) ); + ASSERT( ahdr->avp_value ); + dh = ahdr->avp_value; + break; + + case AC_DESTINATION_REALM: + /* Parse this AVP */ + CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) ); + ASSERT( ahdr->avp_value ); + dr = ahdr->avp_value; + break; + } + } + + if (dh && dr) + break; + + /* Go to next AVP */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); + } + + /* Now, check each candidate against these AVP values */ + for (li = candidates->next; li != candidates; li = li->next) { + struct rtd_candidate *c = (struct rtd_candidate *) li; + + #if 0 /* this is actually useless since the sending process will also ensure that the peer is still available */ + struct fd_peer * peer; + /* Since the candidates list comes from the peers list, we do not have any issue with upper/lower case to find the peer object */ + CHECK_FCT( fd_peer_getbyid( c->diamid, c->diamidlen, 0, (void *)&peer ) ); + if (!peer) + continue; /* it has been deleted since the candidate list was generated; avoid sending to this one in that case. */ + #endif /* 0 */ + + /* In the AVPs, the value comes from the network, so let's be case permissive */ + if (dh && !fd_os_almostcasesrch(dh->os.data, dh->os.len, c->diamid, c->diamidlen, NULL) ) { + /* The candidate is the Destination-Host */ + c->score += FD_SCORE_FINALDEST; + } else { + if (dr && !fd_os_almostcasesrch(dr->os.data, dr->os.len, c->realm, c->realmlen, NULL) ) { + /* The candidate's realm matchs the Destination-Realm */ + c->score += FD_SCORE_REALM; + } + } + } + + return 0; +} + +/********************************************************************************/ +/* Helper functions */ +/********************************************************************************/ + +/* Find (first) '!' and '@' positions in a UTF-8 encoded string (User-Name AVP value) */ +static void nai_get_indexes(union avp_value * un, int * excl_idx, int * at_idx) +{ + int i; + + TRACE_ENTRY("%p %p %p", un, excl_idx, at_idx); + CHECK_PARAMS_DO( un && excl_idx && at_idx, return ); + + *excl_idx = 0; + *at_idx = 0; + + /* Search if there is a '!' before any '@' -- do we need to check it contains a '.' ? */ + for (i = 0; i < un->os.len; i++) { + /* The '!' marks the decorated NAI */ + if ( un->os.data[i] == (unsigned char) '!' ) { + if (!*excl_idx) + *excl_idx = i; + continue; + } + /* If we reach the realm part, we can stop */ + if ( un->os.data[i] == (unsigned char) '@' ) { + *at_idx = i; + break; + } + /* Stop if we find a \0 in the middle */ + if ( un->os.data[i] == 0 ) { + return; + } + /* Skip escaped characters */ + if ( un->os.data[i] == (unsigned char) '\\' ) { + i++; + continue; + } + } + + return; +} + +/* Test if a User-Name AVP contains a Decorated NAI -- RFC4282, RFC5729 */ +/* Create new User-Name and Destination-Realm values */ +static int process_decorated_NAI(int * was_nai, union avp_value * un, union avp_value * dr) +{ + int at_idx, sep_idx; + unsigned char * old_un; + TRACE_ENTRY("%p %p %p", was_nai, un, dr); + CHECK_PARAMS(was_nai && un && dr); + + /* Save the decorated User-Name, for example 'homerealm.example.net!user@otherrealm.example.net' */ + old_un = un->os.data; + + /* Search the positions of the first '!' and the '@' in the string */ + nai_get_indexes(un, &sep_idx, &at_idx); + if ((!sep_idx) || (sep_idx > at_idx) || !fd_os_is_valid_DiameterIdentity(old_un, sep_idx /* this is the new realm part */)) { + *was_nai = 0; + return 0; + } + + *was_nai = 1; + + /* Create the new User-Name value */ + CHECK_MALLOC( un->os.data = malloc( at_idx ) ); + memcpy( un->os.data, old_un + sep_idx + 1, at_idx - sep_idx ); /* user@ */ + memcpy( un->os.data + at_idx - sep_idx, old_un, sep_idx ); /* homerealm.example.net */ + + /* Create the new Destination-Realm value */ + CHECK_MALLOC( dr->os.data = realloc(dr->os.data, sep_idx) ); + memcpy( dr->os.data, old_un, sep_idx ); + dr->os.len = sep_idx; + + TRACE_DEBUG(FULL, "Processed Decorated NAI : '%.*s' became '%.*s' (%.*s)", + (int)un->os.len, old_un, + (int)at_idx, un->os.data, + (int)dr->os.len, dr->os.data); + + un->os.len = at_idx; + free(old_un); + + return 0; +} + + +/* Function to return an error to an incoming request */ +static int return_error(struct msg ** pmsg, char * error_code, char * error_message, struct avp * failedavp) +{ + struct fd_peer * peer; + int is_loc = 0; + + /* Get the source of the message */ + { + DiamId_t id; + size_t idlen; + CHECK_FCT( fd_msg_source_get( *pmsg, &id, &idlen ) ); + + if (id == NULL) { + is_loc = 1; /* The message was issued locally */ + } else { + + /* Search the peer with this id */ + CHECK_FCT( fd_peer_getbyid( id, idlen, 0, (void *)&peer ) ); + + if (!peer) { + char buf[256]; + snprintf(buf, sizeof(buf), "Unable to send error '%s' to deleted peer '%s' in reply to this message.", error_code, id); + fd_hook_call(HOOK_MESSAGE_DROPPED, *pmsg, NULL, buf, fd_msg_pmdl_get(*pmsg)); + fd_msg_free(*pmsg); + *pmsg = NULL; + return 0; + } + } + } + + /* Create the error message */ + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, pmsg, MSGFL_ANSW_ERROR ) ); + + /* Set the error code */ + CHECK_FCT( fd_msg_rescode_set(*pmsg, error_code, error_message, failedavp, 1 ) ); + + /* Send the answer */ + if (is_loc) { + CHECK_FCT( fd_fifo_post(fd_g_incoming, pmsg) ); + } else { + CHECK_FCT( fd_out_send(pmsg, NULL, peer, 1) ); + } + + /* Done */ + return 0; +} + + +/****************************************************************************/ +/* Second part : threads moving messages in the daemon */ +/****************************************************************************/ + +/* The DISPATCH message processing */ +static int msg_dispatch(struct msg * msg) +{ + struct msg_hdr * hdr; + int is_req = 0; + struct session * sess; + enum disp_action action; + char * ec = NULL; + char * em = NULL; + struct msg *msgptr = msg, *error = NULL; + + /* Read the message header */ + CHECK_FCT( fd_msg_hdr(msg, &hdr) ); + is_req = hdr->msg_flags & CMD_FLAG_REQUEST; + + /* Note: if the message is for local delivery, we should test for duplicate + (draft-asveren-dime-dupcons-00). This may conflict with path validation decisions, no clear answer yet */ + + /* At this point, we need to understand the message content, so parse it */ + CHECK_FCT_DO( fd_msg_parse_or_error( &msgptr, &error ), + { + int rescue = 0; + if (__ret__ != EBADMSG) { + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, "Error while parsing received answer", fd_msg_pmdl_get(msgptr)); + fd_msg_free(msgptr); + } else { + if (!msgptr) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR2, error, NULL, NULL, fd_msg_pmdl_get(error)); + /* error now contains the answer message to send back */ + CHECK_FCT( fd_fifo_post(fd_g_outgoing, &error) ); + } else if (!error) { + /* We have received an invalid answer to our query */ + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, "Received answer failed the dictionary / rules parsing", fd_msg_pmdl_get(msgptr)); + fd_msg_free(msgptr); + } else { + /* We will pass the invalid received error to the application */ + rescue = 1; + } + } + if (!rescue) + return 0; /* We are done with this message, go to the next */ + } ); + + /* First, if the original request was registered with a callback and we receive the answer, call it. */ + if ( ! is_req ) { + struct msg * qry; + void (*anscb)(void *, struct msg **) = NULL; + void * data = NULL; + + /* Retrieve the corresponding query */ + CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) ); + + /* Retrieve any registered handler */ + CHECK_FCT( fd_msg_anscb_get( qry, &anscb, NULL, &data ) ); + + /* If a callback was registered, pass the message to it */ + if (anscb != NULL) { + + TRACE_DEBUG(FULL, "Calling callback registered when query was sent (%p, %p)", anscb, data); + (*anscb)(data, &msgptr); + + /* If the message is processed, we're done */ + if (msgptr == NULL) { + return 0; + } + + /* otherwise continue the dispatching --hoping that the anscb callback did not mess with our message :) */ + } + } + + /* Retrieve the session of the message */ + CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, msgptr, &sess, NULL) ); + + /* Now, call any callback registered for the message */ + CHECK_FCT( fd_msg_dispatch ( &msgptr, sess, &action, &ec, &em, &error) ); + + /* Now, act depending on msg and action and ec */ + if (msgptr) { + switch ( action ) { + case DISP_ACT_CONT: + /* No callback has handled the message, let's reply with a generic error or relay it */ + if (!fd_g_config->cnf_flags.no_fwd) { + /* requeue to fd_g_outgoing */ + fd_hook_call(HOOK_MESSAGE_ROUTING_FORWARD, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); + CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) ); + break; + } + /* We don't relay => reply error */ + em = "The message was not handled by any extension callback"; + ec = "DIAMETER_COMMAND_UNSUPPORTED"; + /* and continue as if an error occurred... */ + case DISP_ACT_ERROR: + /* We have a problem with delivering the message */ + if (ec == NULL) { + ec = "DIAMETER_UNABLE_TO_COMPLY"; + } + + if (!is_req) { + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, "Internal error: Answer received to locally issued request, but not handled by any handler.", fd_msg_pmdl_get(msgptr)); + fd_msg_free(msgptr); + break; + } + + /* Create an answer with the error code and message */ + CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msgptr, 0 ) ); + CHECK_FCT( fd_msg_rescode_set(msgptr, ec, em, NULL, 1 ) ); + + case DISP_ACT_SEND: + /* Now, send the message */ + CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) ); + } + } else if (em) { + fd_hook_call(HOOK_MESSAGE_DROPPED, error, NULL, em, fd_msg_pmdl_get(error)); + fd_msg_free(error); + } + + /* We're done with dispatching this message */ + return 0; +} + +/* The ROUTING-IN message processing */ +static int msg_rt_in(struct msg * msg) +{ + struct msg_hdr * hdr; + int is_req = 0; + int is_err = 0; + DiamId_t qry_src = NULL; + struct msg *msgptr = msg; + + /* Read the message header */ + CHECK_FCT( fd_msg_hdr(msg, &hdr) ); + is_req = hdr->msg_flags & CMD_FLAG_REQUEST; + is_err = hdr->msg_flags & CMD_FLAG_ERROR; + + /* Handle incorrect bits */ + if (is_req && is_err) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "R & E bits were set", fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_HDR_BITS", "R & E bits were set", NULL) ); + return 0; + } + + /* If it is a request, we must analyze its content to decide what we do with it */ + if (is_req) { + struct avp * avp, *un = NULL; + union avp_value * un_val = NULL, *dr_val = NULL; + enum status { UNKNOWN, YES, NO }; + /* Are we Destination-Host? */ + enum status is_dest_host = UNKNOWN; + /* Are we Destination-Realm? */ + enum status is_dest_realm = UNKNOWN; + /* Do we support the application of the message? */ + enum status is_local_app = UNKNOWN; + + /* Check if we have local support for the message application */ + if ( (hdr->msg_appl == 0) || (hdr->msg_appl == AI_RELAY) ) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Received a routable message with application id 0 or " _stringize(AI_RELAY) " (relay)", fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL) ); + return 0; + } else { + struct fd_app * app; + CHECK_FCT( fd_app_check(&fd_g_config->cnf_apps, hdr->msg_appl, &app) ); + is_local_app = (app ? YES : NO); + } + + /* Parse the message for Dest-Host, Dest-Realm, and Route-Record */ + CHECK_FCT( fd_msg_browse(msgptr, MSG_BRW_FIRST_CHILD, &avp, NULL) ); + while (avp) { + struct avp_hdr * ahdr; + struct fd_pei error_info; + int ret; + + memset(&error_info, 0, sizeof(struct fd_pei)); + + CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) ); + + if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) { + switch (ahdr->avp_code) { + case AC_DESTINATION_HOST: + /* Parse this AVP */ + CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), + { + if (error_info.pei_errcode) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); + if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); } + return 0; + } else { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Destination-Host AVP", fd_msg_pmdl_get(msgptr)); + return ret; + } + } ); + ASSERT( ahdr->avp_value ); + /* Compare the Destination-Host AVP of the message with our identity */ + if (!fd_os_almostcasesrch(ahdr->avp_value->os.data, ahdr->avp_value->os.len, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, NULL)) { + is_dest_host = YES; + } else { + is_dest_host = NO; + } + break; + + case AC_DESTINATION_REALM: + /* Parse this AVP */ + CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), + { + if (error_info.pei_errcode) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); + if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); } + return 0; + } else { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Destination-Realm AVP", fd_msg_pmdl_get(msgptr)); + return ret; + } + } ); + ASSERT( ahdr->avp_value ); + dr_val = ahdr->avp_value; + /* Compare the Destination-Realm AVP of the message with our identity */ + if (!fd_os_almostcasesrch(dr_val->os.data, dr_val->os.len, fd_g_config->cnf_diamrlm, fd_g_config->cnf_diamrlm_len, NULL)) { + is_dest_realm = YES; + } else { + is_dest_realm = NO; + } + break; + + /* we also use User-Name for decorated NAI */ + case AC_USER_NAME: + /* Parse this AVP */ + CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), + { + if (error_info.pei_errcode) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); + if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); } + return 0; + } else { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing User-Name AVP", fd_msg_pmdl_get(msgptr)); + return ret; + } + } ); + ASSERT( ahdr->avp_value ); + un = avp; + un_val = ahdr->avp_value; + break; + + case AC_ROUTE_RECORD: + /* Parse this AVP */ + CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), + { + if (error_info.pei_errcode) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); + if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); } + return 0; + } else { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Route-Record AVP", fd_msg_pmdl_get(msgptr)); + return ret; + } + } ); + ASSERT( ahdr->avp_value ); + /* Is this our own name ? */ + if (!fd_os_almostcasesrch(ahdr->avp_value->os.data, ahdr->avp_value->os.len, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, NULL)) { + /* Yes: then we must return DIAMETER_LOOP_DETECTED according to Diameter RFC */ + char * error = "DIAMETER_LOOP_DETECTED"; + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error, fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, error, NULL, NULL) ); + return 0; + } + break; + + + } + } + + /* Stop when we found all 3 AVPs -- they are supposed to be at the beginning of the message, so this should be fast */ + if ((is_dest_host != UNKNOWN) && (is_dest_realm != UNKNOWN) && un) + break; + + /* Go to next AVP */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); + } + + /* OK, now decide what we do with the request */ + + /* Handle the missing routing AVPs first */ + if ( is_dest_realm == UNKNOWN ) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL) ); + return 0; + } + + /* If we are listed as Destination-Host */ + if (is_dest_host == YES) { + if (is_local_app == YES) { + /* Ok, give the message to the dispatch thread */ + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); + CHECK_FCT( fd_fifo_post(fd_g_local, &msgptr) ); + } else { + /* We don't support the application, reply an error */ + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Application unsupported", fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) ); + } + return 0; + } + + /* If the message is explicitely for someone else */ + if ((is_dest_host == NO) && (is_dest_realm == NO)) { + if (fd_g_config->cnf_flags.no_fwd) { + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, "Message for another realm/host", fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "I am not a Diameter agent", NULL) ); + return 0; + } + } else { + /* Destination-Host was not set, and Destination-Realm is matching : we may handle or pass to a fellow peer */ + int is_nai = 0; + + /* test for decorated NAI (RFC5729 section 4.4) */ + /* Handle the decorated NAI */ + if (un_val) { + CHECK_FCT_DO( process_decorated_NAI(&is_nai, un_val, dr_val), + { + /* If the process failed, we assume it is because of the AVP format */ + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Failed to process decorated NAI", fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un) ); + return 0; + } ); + } + + if (is_nai) { + /* We have transformed the AVP, now submit it again in the queue */ + CHECK_FCT(fd_fifo_post(fd_g_incoming, &msgptr) ); + return 0; + } + + if (is_local_app == YES) { + /* Handle localy since we are able to */ + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); + CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); + return 0; + } + + if (fd_g_config->cnf_flags.no_fwd) { + /* We return an error */ + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, "Application unsupported", fd_msg_pmdl_get(msgptr)); + CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) ); + return 0; + } + } + + /* From that point, for requests, we will call the registered callbacks, then forward to another peer */ + + } else { + /* The message is an answer */ + struct msg * qry; + + /* Retrieve the corresponding query and its origin */ + CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) ); + CHECK_FCT( fd_msg_source_get( qry, &qry_src, NULL ) ); + + /* fj modified */ + if ((!qry_src) && (!is_err)) { + // if ((qry_src) && (!is_err)) { + /* The message is a normal answer to a request issued localy, we do not call the callbacks chain on it. */ + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); + CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); + return 0; + } + + /* From that point, for answers, we will call the registered callbacks, then pass it to the dispatch module or forward it */ + } + + /* Call all registered callbacks for this message */ + { + struct fd_list * li; + + CHECK_FCT( pthread_rwlock_rdlock( &rt_fwd_lock ) ); + pthread_cleanup_push( fd_cleanup_rwlock, &rt_fwd_lock ); + + /* requests: dir = 1 & 2 => in order; answers = 3 & 2 => in reverse order */ + for ( li = (is_req ? rt_fwd_list.next : rt_fwd_list.prev) ; msgptr && (li != &rt_fwd_list) ; li = (is_req ? li->next : li->prev) ) { + struct rt_hdl * rh = (struct rt_hdl *)li; + int ret; + + if (is_req && (rh->dir > RT_FWD_ALL)) + break; + if ((!is_req) && (rh->dir < RT_FWD_ALL)) + break; + + /* Ok, call this cb */ + LOG_D("Calling next FWD callback on %p : %p", msgptr, rh->rt_fwd_cb); + CHECK_FCT_DO( ret = (*rh->rt_fwd_cb)(rh->cbdata, &msgptr), + { + char buf[256]; + snprintf(buf, sizeof(buf), "A FWD routing callback returned an error: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_msg_free(msgptr); + msgptr = NULL; + break; + } ); + } + + pthread_cleanup_pop(0); + CHECK_FCT( pthread_rwlock_unlock( &rt_fwd_lock ) ); + + /* If a callback has handled the message, we stop now */ + if (!msgptr) + return 0; + } + + /* Now pass the message to the next step: either forward to another peer, or dispatch to local extensions */ + if (is_req || qry_src) { + fd_hook_call(HOOK_MESSAGE_ROUTING_FORWARD, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); + CHECK_FCT(fd_fifo_post(fd_g_outgoing, &msgptr) ); + } else { + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); + CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); + } + + /* We're done with this message */ + return 0; +} + + +/* The ROUTING-OUT message processing */ +static int msg_rt_out(struct msg * msg) +{ + struct rt_data * rtd = NULL; + struct msg_hdr * hdr; + int is_req = 0; + int ret; + struct fd_list * li, *candidates; + struct avp * avp; + struct rtd_candidate * c; + struct msg *msgptr = msg; + DiamId_t qry_src = NULL; + size_t qry_src_len = 0; + + /* Read the message header */ + CHECK_FCT( fd_msg_hdr(msgptr, &hdr) ); + is_req = hdr->msg_flags & CMD_FLAG_REQUEST; + + /* For answers, the routing is very easy */ + if ( ! is_req ) { + struct msg * qry; + struct msg_hdr * qry_hdr; + struct fd_peer * peer = NULL; + + /* Retrieve the corresponding query and its origin */ + CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) ); + CHECK_FCT( fd_msg_source_get( qry, &qry_src, &qry_src_len ) ); + + ASSERT( qry_src ); /* if it is NULL, the message should have been in the LOCAL queue! */ + + LOG_D("qry_src diamid:%s", qry_src); + + /* Find the peer corresponding to this name */ + CHECK_FCT( fd_peer_getbyid( qry_src, qry_src_len, 0, (void *) &peer ) ); + if (fd_peer_getstate(peer) != STATE_OPEN && fd_peer_getstate(peer) != STATE_CLOSING_GRACE) { + char buf[128]; + printf("cur state:%d\n", fd_peer_getstate(peer) ); + snprintf(buf, sizeof(buf), "Unable to forward answer to deleted / closed peer '%s'.", qry_src); + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_msg_free(msgptr); + return 0; + } + + /* We must restore the hop-by-hop id */ + CHECK_FCT( fd_msg_hdr(qry, &qry_hdr) ); + hdr->msg_hbhid = qry_hdr->msg_hbhid; + + /* Push the message into this peer */ + CHECK_FCT( fd_out_send(&msgptr, NULL, peer, 1) ); + + /* We're done with this answer */ + return 0; + } + + /* From that point, the message is a request */ + CHECK_FCT( fd_msg_source_get( msgptr, &qry_src, &qry_src_len ) ); + /* if qry_src != NULL, this message is relayed, otherwise it is locally issued */ + + /* Get the routing data out of the message if any (in case of re-transmit) */ + CHECK_FCT( fd_msg_rt_get ( msgptr, &rtd ) ); + + /* If there is no routing data already, let's create it */ + if (rtd == NULL) { + CHECK_FCT( fd_rtd_init(&rtd) ); + + /* Add all peers currently in OPEN state */ + CHECK_FCT( pthread_rwlock_rdlock(&fd_g_activ_peers_rw) ); + for (li = fd_g_activ_peers.next; li != &fd_g_activ_peers; li = li->next) { + struct fd_peer * p = (struct fd_peer *)li->o; + CHECK_FCT_DO( ret = fd_rtd_candidate_add(rtd, + p->p_hdr.info.pi_diamid, + p->p_hdr.info.pi_diamidlen, + p->p_hdr.info.runtime.pir_realm, + p->p_hdr.info.runtime.pir_realmlen), + { CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_activ_peers_rw), ); return ret; } ); + } + CHECK_FCT( pthread_rwlock_unlock(&fd_g_activ_peers_rw) ); + + /* Now let's remove all peers from the Route-Records */ + CHECK_FCT( fd_msg_browse(msgptr, MSG_BRW_FIRST_CHILD, &avp, NULL) ); + while (avp) { + struct avp_hdr * ahdr; + struct fd_pei error_info; + CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) ); + + if ((ahdr->avp_code == AC_ROUTE_RECORD) && (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) ) { + /* Parse this AVP */ + CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), + { + if (error_info.pei_errcode) { + CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); + if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); } + return 0; + } else { + return ret; + } + } ); + ASSERT( ahdr->avp_value ); + /* Remove this value from the list. We don't need to pay special attention to the contents here. */ + fd_rtd_candidate_del(rtd, ahdr->avp_value->os.data, ahdr->avp_value->os.len); + } + + /* Go to next AVP */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); + } + + /* Save the routing information in the message */ + CHECK_FCT( fd_msg_rt_associate ( msgptr, rtd ) ); + } + + /* Note: we reset the scores and pass the message to the callbacks, maybe we could re-use the saved scores when we have received an error ? -- TODO */ + + /* Ok, we have our list in rtd now, let's (re)initialize the scores */ + fd_rtd_candidate_extract(rtd, &candidates, FD_SCORE_INI); + + /* Pass the list to registered callbacks (even if it is empty list) */ + { + CHECK_FCT( pthread_rwlock_rdlock( &rt_out_lock ) ); + pthread_cleanup_push( fd_cleanup_rwlock, &rt_out_lock ); + + /* We call the cb by reverse priority order */ + for ( li = rt_out_list.prev ; (msgptr != NULL) && (li != &rt_out_list) ; li = li->prev ) { + struct rt_hdl * rh = (struct rt_hdl *)li; + + TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", msgptr, rh->rt_out_cb, rh->prio); + CHECK_FCT_DO( ret = (*rh->rt_out_cb)(rh->cbdata, &msgptr, candidates), + { + char buf[256]; + snprintf(buf, sizeof(buf), "An OUT routing callback returned an error: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_msg_free(msgptr); + msgptr = NULL; + } ); + } + + pthread_cleanup_pop(0); + CHECK_FCT( pthread_rwlock_unlock( &rt_out_lock ) ); + + /* If an error occurred or the callback disposed of the message, go to next message */ + if (! msgptr) { + return 0; + } + } + + /* Order the candidate peers by score attributed by the callbacks */ + CHECK_FCT( fd_rtd_candidate_reorder(candidates) ); + + /* Now try sending the message */ + for (li = candidates->prev; li != candidates; li = li->prev) { + struct fd_peer * peer; + + c = (struct rtd_candidate *) li; + + /* Stop when we have reached the end of valid candidates */ + if (c->score < 0) + break; + + /* Search for the peer */ + CHECK_FCT( fd_peer_getbyid( c->diamid, c->diamidlen, 0, (void *)&peer ) ); + + if (fd_peer_getstate(peer) == STATE_OPEN) { + /* Send to this one */ + CHECK_FCT_DO( fd_out_send(&msgptr, NULL, peer, 1), continue ); + + /* If the sending was successful */ + break; + } + } + + /* If the message has not been sent, return an error */ + if (msgptr) { + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, "No remaining suitable candidate to route the message to", fd_msg_pmdl_get(msgptr)); + return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL); + } + + /* We're done with this message */ + + return 0; +} + + +/********************************************************************************/ +/* Management of the threads */ +/********************************************************************************/ + +/* Note: in the first version, we only create one thread of each kind. + We could improve the scalability by using the threshold feature of the queues + to create additional threads if a queue is filling up, or at least giving a configurable + number of threads of each kind. + */ + +/* Control of the threads */ +static enum { RUN = 0, STOP = 1 } order_val = RUN; +static pthread_mutex_t order_state_lock = PTHREAD_MUTEX_INITIALIZER; + +/* Threads report their status */ +enum thread_state { NOTRUNNING = 0, RUNNING = 1 }; +static void cleanup_state(void * state_loc) +{ + CHECK_POSIX_DO( pthread_mutex_lock(&order_state_lock), ); + *(enum thread_state *)state_loc = NOTRUNNING; + CHECK_POSIX_DO( pthread_mutex_unlock(&order_state_lock), ); +} + +/* This is the common thread code (same for routing and dispatching) */ +static void * process_thr(void * arg, int (*action_cb)(struct msg * msg), struct fifo * queue, char * action_name) +{ + TRACE_ENTRY("%p %p %p %p", arg, action_cb, queue, action_name); + int ret; + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "%s (%p)", action_name, arg); + fd_log_threadname ( buf ); + } + + /* The thread reports its status when canceled */ + CHECK_PARAMS_DO(arg, return NULL); + pthread_cleanup_push( cleanup_state, arg ); + + /* Mark the thread running */ + CHECK_POSIX_DO( pthread_mutex_lock(&order_state_lock), ); + *(enum thread_state *)arg = RUNNING; + CHECK_POSIX_DO( pthread_mutex_unlock(&order_state_lock), ); + + do { + struct msg * msg; + + /* Test the current order */ + { + int must_stop; + CHECK_POSIX_DO( pthread_mutex_lock(&order_state_lock), { ASSERT(0); } ); /* we lock to flush the caches */ + must_stop = (order_val == STOP); + CHECK_POSIX_DO( pthread_mutex_unlock(&order_state_lock), { ASSERT(0); } ); + if (must_stop) + goto end; + + pthread_testcancel(); + } + + /* Ok, we are allowed to run */ + + /* Get the next message from the queue */ + { + + struct timespec ts; + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), goto fatal_error ); + ts.tv_sec += 1; + + ret = fd_fifo_timedget ( queue, &msg, &ts ); + if (ret == ETIMEDOUT) + /* loop, check if the thread must stop now */ + continue; + if (ret == EPIPE) + /* The queue was destroyed, we are probably exiting */ + goto end; + + /* check if another error occurred */ + CHECK_FCT_DO( ret, goto fatal_error ); + } + + LOG_A("%s: Picked next message", action_name); + + /* Now process the message */ + // CHECK_FCT_DO( (*action_cb)(msg), goto fatal_error); + ret = (*action_cb)(msg); + if(ret != 0) + { + goto fatal_error; + } + /* We're done with this message */ + + } while (1); + +fatal_error: + TRACE_DEBUG(INFO, "An unrecoverable error occurred, %s thread is terminating...", action_name); + CHECK_FCT_DO(fd_core_shutdown(), ); + +end: + ; /* noop so that we get rid of "label at end of compund statement" warning */ + /* Mark the thread as terminated */ + pthread_cleanup_pop(1); + return NULL; +} + +/* The dispatch thread */ +static void * dispatch_thr(void * arg) +{ + return process_thr(arg, msg_dispatch, fd_g_local, "Dispatch"); +} + +/* The (routing-in) thread -- see description in freeDiameter.h */ +static void * routing_in_thr(void * arg) +{ + return process_thr(arg, msg_rt_in, fd_g_incoming, "Routing-IN"); +} + +/* The (routing-out) thread -- see description in freeDiameter.h */ +static void * routing_out_thr(void * arg) +{ + return process_thr(arg, msg_rt_out, fd_g_outgoing, "Routing-OUT"); +} + + +/********************************************************************************/ +/* The functions for the other files */ +/********************************************************************************/ + +static pthread_t * dispatch = NULL; +static enum thread_state * disp_state = NULL; + +/* Later: make this more dynamic */ +static pthread_t rt_out = (pthread_t)NULL; +static enum thread_state out_state = NOTRUNNING; + +static pthread_t rt_in = (pthread_t)NULL; +static enum thread_state in_state = NOTRUNNING; + +/* Initialize the routing and dispatch threads */ +int fd_rtdisp_init(void) +{ + int i; + + /* Prepare the array for dispatch */ + CHECK_MALLOC( disp_state = calloc(fd_g_config->cnf_dispthr, sizeof(enum thread_state)) ); + CHECK_MALLOC( dispatch = calloc(fd_g_config->cnf_dispthr, sizeof(pthread_t)) ); + + /* Create the threads */ + for (i=0; i < fd_g_config->cnf_dispthr; i++) { + CHECK_POSIX( pthread_create( &dispatch[i], NULL, dispatch_thr, &disp_state[i] ) ); + } + CHECK_POSIX( pthread_create( &rt_out, NULL, routing_out_thr, &out_state) ); + CHECK_POSIX( pthread_create( &rt_in, NULL, routing_in_thr, &in_state) ); + + /* Later: TODO("Set the thresholds for the queues to create more threads as needed"); */ + + /* Register the built-in callbacks */ + CHECK_FCT( fd_rt_out_register( dont_send_if_no_common_app, NULL, 10, NULL ) ); + CHECK_FCT( fd_rt_out_register( score_destination_avp, NULL, 10, NULL ) ); + + return 0; +} + +/* Ask the thread to terminate after next iteration */ +int fd_rtdisp_cleanstop(void) +{ + CHECK_POSIX_DO( pthread_mutex_lock(&order_state_lock), ); + order_val = STOP; + CHECK_POSIX_DO( pthread_mutex_unlock(&order_state_lock), ); + + return 0; +} + +static void stop_thread_delayed(enum thread_state *st, pthread_t * thr, char * th_name) +{ + TRACE_ENTRY("%p %p", st, thr); + CHECK_PARAMS_DO(st && thr, return); + int terminated; + + CHECK_POSIX_DO( pthread_mutex_lock(&order_state_lock), ); + terminated = (*st == NOTRUNNING); + CHECK_POSIX_DO( pthread_mutex_unlock(&order_state_lock), ); + + + /* Wait for a second for the thread to complete, by monitoring my_state */ + if (!terminated) { + TRACE_DEBUG(INFO, "Waiting for the %s thread to have a chance to terminate", th_name); + do { + struct timespec ts, ts_final; + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), break ); + + ts_final.tv_sec = ts.tv_sec + 1; + ts_final.tv_nsec = ts.tv_nsec; + + while (TS_IS_INFERIOR( &ts, &ts_final )) { + + CHECK_POSIX_DO( pthread_mutex_lock(&order_state_lock), ); + terminated = (*st == NOTRUNNING); + CHECK_POSIX_DO( pthread_mutex_unlock(&order_state_lock), ); + if (terminated) + break; + + usleep(100000); + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), break ); + } + } while (0); + } + + /* Now stop the thread and reclaim its resources */ + CHECK_FCT_DO( fd_thr_term(thr ), /* continue */); + +} + +/* Stop the thread after up to one second of wait */ +int fd_rtdisp_fini(void) +{ + int i; + + /* Destroy the incoming queue */ + CHECK_FCT_DO( fd_queues_fini(&fd_g_incoming), /* ignore */); + + /* Stop the routing IN thread */ + stop_thread_delayed(&in_state, &rt_in, "IN routing"); + + /* Destroy the outgoing queue */ + CHECK_FCT_DO( fd_queues_fini(&fd_g_outgoing), /* ignore */); + + /* Stop the routing OUT thread */ + stop_thread_delayed(&out_state, &rt_out, "OUT routing"); + + /* Destroy the local queue */ + CHECK_FCT_DO( fd_queues_fini(&fd_g_local), /* ignore */); + + /* Stop the Dispatch threads */ + if (dispatch != NULL) { + for (i=0; i < fd_g_config->cnf_dispthr; i++) { + stop_thread_delayed(&disp_state[i], &dispatch[i], "Dispatching"); + } + free(dispatch); + dispatch = NULL; + } + if (disp_state != NULL) { + free(disp_state); + disp_state = NULL; + } + + return 0; +} + +/* Cleanup handlers */ +int fd_rtdisp_cleanup(void) +{ + /* Cleanup all remaining handlers */ + while (!FD_IS_LIST_EMPTY(&rt_fwd_list)) { + CHECK_FCT_DO( fd_rt_fwd_unregister ( (void *)rt_fwd_list.next, NULL ), /* continue */ ); + } + while (!FD_IS_LIST_EMPTY(&rt_out_list)) { + CHECK_FCT_DO( fd_rt_out_unregister ( (void *)rt_out_list.next, NULL ), /* continue */ ); + } + + fd_disp_unregister_all(); /* destroy remaining handlers */ + + return 0; +} + + +/********************************************************************************/ +/* For extensions to register a new appl */ +/********************************************************************************/ + +/* Add an application into the peer's supported apps */ +int fd_disp_app_support ( struct dict_object * app, struct dict_object * vendor, int auth, int acct ) +{ + application_id_t aid = 0; + vendor_id_t vid = 0; + + TRACE_ENTRY("%p %p %d %d", app, vendor, auth, acct); + CHECK_PARAMS( app && (auth || acct) ); + + { + enum dict_object_type type = 0; + struct dict_application_data data; + CHECK_FCT( fd_dict_gettype(app, &type) ); + CHECK_PARAMS( type == DICT_APPLICATION ); + CHECK_FCT( fd_dict_getval(app, &data) ); + aid = data.application_id; + } + + if (vendor) { + enum dict_object_type type = 0; + struct dict_vendor_data data; + CHECK_FCT( fd_dict_gettype(vendor, &type) ); + CHECK_PARAMS( type == DICT_VENDOR ); + CHECK_FCT( fd_dict_getval(vendor, &data) ); + vid = data.vendor_id; + } + + return fd_app_merge(&fd_g_config->cnf_apps, aid, vid, auth, acct); +} + + + diff --git a/plat/diameter/libfdcore/sctp.c b/plat/diameter/libfdcore/sctp.c new file mode 100644 index 0000000..4f9aaa9 --- /dev/null +++ b/plat/diameter/libfdcore/sctp.c @@ -0,0 +1,1355 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" +#include "cnxctx.h" + +#include +#include + +/* Size of buffer to receive ancilliary data. May need to be enlarged if more sockopt are set... */ +#ifndef CMSG_BUF_LEN +#define CMSG_BUF_LEN 1024 +#endif /* CMSG_BUF_LEN */ + +/* Use old draft-ietf-tsvwg-sctpsocket-17 API ? If not defined, RFC6458 API will be used */ +/* #define OLD_SCTP_SOCKET_API */ + +/* Automatically fallback to old API if some of the new symbols are not defined */ +//#if (!defined(SCTP_CONNECTX_4_ARGS) || (!defined(SCTP_RECVRCVINFO)) || (!defined(SCTP_SNDINFO))) +#if (!defined(SCTP_CONNECTX_4_ARGS) || (!defined(SCTP_RECVRCVINFO)) || (!defined(SCTP_SNDINFO)) || \ + (!defined(SCTP_SEND_FAILED_EVENT)) || (!defined(SCTP_NOTIFICATIONS_STOPPED_EVENT)) ) +# define OLD_SCTP_SOCKET_API +#endif + + +/* Temper with the retransmission timers to try and improve disconnection detection response? Undef this to keep the defaults of SCTP stack */ +#ifndef USE_DEFAULT_SCTP_RTX_PARAMS /* make this a configuration option if useful */ +#define ADJUST_RTX_PARAMS +#endif /* USE_DEFAULT_SCTP_RTX_PARAMS */ + +/* Pre-binding socket options -- # streams read in config */ +static int fd_setsockopt_prebind(int sk) +{ + socklen_t sz; + + TRACE_ENTRY( "%d", sk); + + CHECK_PARAMS( sk > 0 ); + + { + int reuse = 1; + CHECK_SYS( setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) ); + } + +#ifdef ADJUST_RTX_PARAMS + /* Set the retransmit parameters */ + #ifdef SCTP_RTOINFO + { + struct sctp_rtoinfo rtoinfo; + memset(&rtoinfo, 0, sizeof(rtoinfo)); + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(rtoinfo); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, &sz) ); + if (sz != sizeof(rtoinfo)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(rtoinfo)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_RTOINFO : srto_initial : %u", rtoinfo.srto_initial); + fd_log_debug( " srto_min : %u", rtoinfo.srto_min); + fd_log_debug( " srto_max : %u", rtoinfo.srto_max); + } + + /* rtoinfo.srto_initial: Estimate of the RTT before it can be measured; keep the default value */ + rtoinfo.srto_max = 5000; /* Maximum retransmit timer (in ms), we want fast retransmission time. */ + rtoinfo.srto_min = 1000; /* Value under which the RTO does not descend, we set this value to not conflict with srto_max */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, &sz) ); + fd_log_debug( "New SCTP_RTOINFO : srto_initial : %u", rtoinfo.srto_initial); + fd_log_debug( " srto_max : %u", rtoinfo.srto_max); + fd_log_debug( " srto_min : %u", rtoinfo.srto_min); + } + } + #else /* SCTP_RTOINFO */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_RTOINFO"); + #endif /* SCTP_RTOINFO */ + + /* Set the association parameters: max number of retransmits, ... */ + #ifdef SCTP_ASSOCINFO + { + struct sctp_assocparams assoc; + memset(&assoc, 0, sizeof(assoc)); + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(assoc); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, &sz) ); + if (sz != sizeof(assoc)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(assoc)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_ASSOCINFO : sasoc_asocmaxrxt : %hu", assoc.sasoc_asocmaxrxt); + fd_log_debug( " sasoc_number_peer_destinations : %hu", assoc.sasoc_number_peer_destinations); + fd_log_debug( " sasoc_peer_rwnd : %u" , assoc.sasoc_peer_rwnd); + fd_log_debug( " sasoc_local_rwnd : %u" , assoc.sasoc_local_rwnd); + fd_log_debug( " sasoc_cookie_life : %u" , assoc.sasoc_cookie_life); + } + + assoc.sasoc_asocmaxrxt = 4; /* Maximum number of retransmission attempts: we want fast detection of errors */ + /* Note that this must remain less than the sum of retransmission parameters of the different paths. */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, sizeof(assoc)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, &sz) ); + fd_log_debug( "New SCTP_ASSOCINFO : sasoc_asocmaxrxt : %hu", assoc.sasoc_asocmaxrxt); + fd_log_debug( " sasoc_number_peer_destinations : %hu", assoc.sasoc_number_peer_destinations); + fd_log_debug( " sasoc_peer_rwnd : %u" , assoc.sasoc_peer_rwnd); + fd_log_debug( " sasoc_local_rwnd : %u" , assoc.sasoc_local_rwnd); + fd_log_debug( " sasoc_cookie_life : %u" , assoc.sasoc_cookie_life); + } + } + #else /* SCTP_ASSOCINFO */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_ASSOCINFO"); + #endif /* SCTP_ASSOCINFO */ +#endif /* ADJUST_RTX_PARAMS */ + + /* Set the INIT parameters, such as number of streams */ + #ifdef SCTP_INITMSG + { + struct sctp_initmsg init; + memset(&init, 0, sizeof(init)); + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(init); + + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, &sz) ); + if (sz != sizeof(init)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(init)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_INITMSG : sinit_num_ostreams : %hu", init.sinit_num_ostreams); + fd_log_debug( " sinit_max_instreams : %hu", init.sinit_max_instreams); + fd_log_debug( " sinit_max_attempts : %hu", init.sinit_max_attempts); + fd_log_debug( " sinit_max_init_timeo : %hu", init.sinit_max_init_timeo); + } + + /* Set the init options -- need to receive SCTP_COMM_UP to confirm the requested parameters, but we don't care (best effort) */ + init.sinit_num_ostreams = fd_g_config->cnf_sctp_str; /* desired number of outgoing streams */ + init.sinit_max_init_timeo = CNX_TIMEOUT * 1000; + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, sizeof(init)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, &sz) ); + fd_log_debug( "New SCTP_INITMSG : sinit_num_ostreams : %hu", init.sinit_num_ostreams); + fd_log_debug( " sinit_max_instreams : %hu", init.sinit_max_instreams); + fd_log_debug( " sinit_max_attempts : %hu", init.sinit_max_attempts); + fd_log_debug( " sinit_max_init_timeo : %hu", init.sinit_max_init_timeo); + } + } + #else /* SCTP_INITMSG */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_INITMSG"); + #endif /* SCTP_INITMSG */ + + /* The SO_LINGER option will be reset if we want to perform SCTP ABORT */ + #ifdef SO_LINGER + { + struct linger linger; + memset(&linger, 0, sizeof(linger)); + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(linger); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, &sz) ); + if (sz != sizeof(linger)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(linger)); + return ENOTSUP; + } + fd_log_debug( "Def SO_LINGER : l_onoff : %d", linger.l_onoff); + fd_log_debug( " l_linger : %d", linger.l_linger); + } + + linger.l_onoff = 0; /* Do not activate the linger */ + linger.l_linger = 0; /* Ignored, but it would mean : Return immediately when closing (=> abort) (graceful shutdown in background) */ + + /* Set the option */ + CHECK_SYS( setsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, &sz) ); + fd_log_debug( "New SO_LINGER : l_onoff : %d", linger.l_onoff); + fd_log_debug( " l_linger : %d", linger.l_linger); + } + } + #else /* SO_LINGER */ + TRACE_DEBUG(ANNOYING, "Skipping SO_LINGER"); + #endif /* SO_LINGER */ + + /* Set the NODELAY option (Nagle-like algorithm) */ + #ifdef SCTP_NODELAY + { + int nodelay; + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(nodelay); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, &sz) ); + if (sz != sizeof(nodelay)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(nodelay)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_NODELAY value : %s", nodelay ? "true" : "false"); + } + + nodelay = 1; /* We turn ON to disable the Nagle algorithm, so that packets are sent ASAP. */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, sizeof(nodelay)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, &sz) ); + fd_log_debug( "New SCTP_NODELAY value : %s", nodelay ? "true" : "false"); + } + } + #else /* SCTP_NODELAY */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_NODELAY"); + #endif /* SCTP_NODELAY */ + + /* + SO_RCVBUF size of receiver window + SO_SNDBUF size of pending data to send + SCTP_AUTOCLOSE for one-to-many only + SCTP_PRIMARY_ADDR use this address as primary locally + SCTP_ADAPTATION_LAYER set adaptation layer indication, we don't use this + */ + + /* Set the SCTP_DISABLE_FRAGMENTS option, required for TLS */ + #ifdef SCTP_DISABLE_FRAGMENTS + { + int nofrag; + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(nofrag); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, &sz) ); + if (sz != sizeof(nofrag)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(nofrag)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_DISABLE_FRAGMENTS value : %s", nofrag ? "true" : "false"); + } + + nofrag = 0; /* We turn ON the fragmentation, since Diameter messages & TLS messages can be quite large. */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, sizeof(nofrag)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, &sz) ); + fd_log_debug( "New SCTP_DISABLE_FRAGMENTS value : %s", nofrag ? "true" : "false"); + } + } + #else /* SCTP_DISABLE_FRAGMENTS */ + # error "TLS requires support of SCTP_DISABLE_FRAGMENTS" + #endif /* SCTP_DISABLE_FRAGMENTS */ + + /* SCTP_PEER_ADDR_PARAMS control heartbeat per peer address. We set it as a default for all addresses in the association; not sure if it works ... */ + #ifdef SCTP_PEER_ADDR_PARAMS + { + struct sctp_paddrparams parms; + memset(&parms, 0, sizeof(parms)); + + /* Some kernel versions need this to be set */ + parms.spp_address.ss_family = AF_INET; + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(parms); + + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &parms, &sz) ); + if (sz != sizeof(parms)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(parms)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_PEER_ADDR_PARAMS : spp_hbinterval : %u", parms.spp_hbinterval); + fd_log_debug( " spp_pathmaxrxt : %hu", parms.spp_pathmaxrxt); + fd_log_debug( " spp_pathmtu : %u", parms.spp_pathmtu); + fd_log_debug( " spp_flags : %x", parms.spp_flags); + // fd_log_debug( " spp_ipv6_flowlabel: %u", parms.spp_ipv6_flowlabel); + // fd_log_debug( " spp_ipv4_tos : %hhu",parms.spp_ipv4_tos); + } + + parms.spp_flags = SPP_HB_ENABLE; /* Enable heartbeat for the association */ + #ifdef SPP_PMTUD_ENABLE + parms.spp_flags |= SPP_PMTUD_ENABLE; /* also enable path MTU discovery mechanism */ + #endif /* SPP_PMTUD_ENABLE */ + +#ifdef ADJUST_RTX_PARAMS + parms.spp_hbinterval = 6000; /* Send an heartbeat every 6 seconds to quickly start retransmissions */ + /* parms.spp_pathmaxrxt : max nbr of restransmissions on this address. There is a relationship with sasoc_asocmaxrxt, so we leave the default here */ +#endif /* ADJUST_RTX_PARAMS */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &parms, sizeof(parms)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &parms, &sz) ); + fd_log_debug( "New SCTP_PEER_ADDR_PARAMS : spp_hbinterval : %u", parms.spp_hbinterval); + fd_log_debug( " spp_pathmaxrxt : %hu", parms.spp_pathmaxrxt); + fd_log_debug( " spp_pathmtu : %u", parms.spp_pathmtu); + fd_log_debug( " spp_flags : %x", parms.spp_flags); + // fd_log_debug( " spp_ipv6_flowlabel: %u", parms.spp_ipv6_flowlabel); + // fd_log_debug( " spp_ipv4_tos : %hhu",parms.spp_ipv4_tos); + } + } + #else /* SCTP_PEER_ADDR_PARAMS */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_PEER_ADDR_PARAMS"); + #endif /* SCTP_PEER_ADDR_PARAMS */ + + /* + SCTP_DEFAULT_SEND_PARAM - DEPRECATED // parameters for the sendto() call, we don't use it. + */ + + /* Subscribe to some notifications */ +#ifdef OLD_SCTP_SOCKET_API + #ifdef SCTP_EVENTS /* DEPRECATED */ + { + struct sctp_event_subscribe event; + + memset(&event, 0, sizeof(event)); + event.sctp_data_io_event = 1; /* to receive the stream ID in SCTP_SNDRCV ancilliary data on message reception */ + event.sctp_association_event = 0; /* new or closed associations (mostly for one-to-many style sockets) */ + event.sctp_address_event = 1; /* address changes */ + event.sctp_send_failure_event = 1; /* delivery failures */ + event.sctp_peer_error_event = 1; /* remote peer sends an error */ + event.sctp_shutdown_event = 1; /* peer has sent a SHUTDOWN */ + event.sctp_partial_delivery_event = 1; /* a partial delivery is aborted, probably indicating the connection is being shutdown */ + // event.sctp_adaptation_layer_event = 0; /* adaptation layer notifications */ + // event.sctp_authentication_event = 0; /* when new key is made active */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) ); + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(event); + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_EVENTS, &event, &sz) ); + if (sz != sizeof(event)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(event)); + return ENOTSUP; + } + + fd_log_debug( "SCTP_EVENTS : sctp_data_io_event : %hhu", event.sctp_data_io_event); + fd_log_debug( " sctp_association_event : %hhu", event.sctp_association_event); + fd_log_debug( " sctp_address_event : %hhu", event.sctp_address_event); + fd_log_debug( " sctp_send_failure_event : %hhu", event.sctp_send_failure_event); + fd_log_debug( " sctp_peer_error_event : %hhu", event.sctp_peer_error_event); + fd_log_debug( " sctp_shutdown_event : %hhu", event.sctp_shutdown_event); + fd_log_debug( " sctp_partial_delivery_event : %hhu", event.sctp_partial_delivery_event); + fd_log_debug( " sctp_adaptation_layer_event : %hhu", event.sctp_adaptation_layer_event); + // fd_log_debug( " sctp_authentication_event : %hhu", event.sctp_authentication_event); + } + } + #else /* SCTP_EVENTS */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_EVENTS"); + #endif /* SCTP_EVENTS */ +#endif /* OLD_SCTP_SOCKET_API */ + + /* Set the v4 mapped addresses option */ + #ifdef SCTP_I_WANT_MAPPED_V4_ADDR + if (!fd_g_config->cnf_flags.no_ip6) { + int v4mapped; + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(v4mapped); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, &sz) ); + if (sz != sizeof(v4mapped)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(v4mapped)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_I_WANT_MAPPED_V4_ADDR value : %s", v4mapped ? "true" : "false"); + } + + #ifndef SCTP_USE_MAPPED_ADDRESSES + v4mapped = 0; /* We don't want v4 mapped addresses */ + #else /* SCTP_USE_MAPPED_ADDRESSES */ + v4mapped = 1; /* but we may have to, otherwise the bind fails in some environments */ + #endif /* SCTP_USE_MAPPED_ADDRESSES */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, sizeof(v4mapped)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, &sz) ); + fd_log_debug( "New SCTP_I_WANT_MAPPED_V4_ADDR value : %s", v4mapped ? "true" : "false"); + } + } else { + TRACE_DEBUG(ANNOYING, "Skipping SCTP_I_WANT_MAPPED_V4_ADDR, since IPv6 disabled."); + } + #else /* SCTP_I_WANT_MAPPED_V4_ADDR */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_I_WANT_MAPPED_V4_ADDR"); + #endif /* SCTP_I_WANT_MAPPED_V4_ADDR */ + + /* + SCTP_MAXSEG max size of fragmented segments -- bound to PMTU + SCTP_HMAC_IDENT authentication algorithms + SCTP_AUTH_ACTIVE_KEY set the active key + SCTP_DELAYED_SACK control delayed acks + */ + + + /* Set the interleaving option */ + #ifdef SCTP_FRAGMENT_INTERLEAVE + { + int interleave; + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(interleave); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, &sz) ); + if (sz != sizeof(interleave)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(interleave)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_FRAGMENT_INTERLEAVE value : %d", interleave); + } + + #if 0 + interleave = 2; /* Allow partial delivery on several streams at the same time, since we are stream-aware in our security modules */ + #else /* 0 */ + interleave = 1; /* hmmm actually, we are not yet capable of handling this, and we don t need it. */ + #endif /* 0 */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, sizeof(interleave)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, &sz) ); + fd_log_debug( "New SCTP_FRAGMENT_INTERLEAVE value : %d", interleave); + } + } + #else /* SCTP_FRAGMENT_INTERLEAVE */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_FRAGMENT_INTERLEAVE"); + #endif /* SCTP_FRAGMENT_INTERLEAVE */ + + /* + SCTP_PARTIAL_DELIVERY_POINT control partial delivery size + SCTP_USE_EXT_RCVINFO - DEPRECATED use extended receive info structure (information about the next message if available) + */ + /* SCTP_AUTO_ASCONF is set by the postbind function */ + /* + SCTP_MAX_BURST number of packets that can be burst emitted + SCTP_CONTEXT save a context information along with the association. + */ + + /* SCTP_EXPLICIT_EOR: we assume implicit EOR in freeDiameter, so let's ensure this is known by the stack */ + #ifdef SCTP_EXPLICIT_EOR + { + int bool; + + if (TRACE_BOOL(ANNOYING)) { + sz = sizeof(bool); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &bool, &sz) ); + if (sz != sizeof(bool)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(bool)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_EXPLICIT_EOR value : %s", bool ? "true" : "false"); + } + + bool = 0; + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &bool, sizeof(bool)) ); + + if (TRACE_BOOL(ANNOYING)) { + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &bool, &sz) ); + fd_log_debug( "New SCTP_EXPLICIT_EOR value : %s", bool ? "true" : "false"); + } + } + #else /* SCTP_EXPLICIT_EOR */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_EXPLICIT_EOR"); + #endif /* SCTP_EXPLICIT_EOR */ + + /* + SCTP_REUSE_PORT share one listening port with several sockets + */ + +#ifndef OLD_SCTP_SOCKET_API + #ifdef SCTP_EVENT + { + /* Subscribe to the following events */ + int events_I_want[] = { + #ifdef SCTP_ASSOC_CHANGE + /* SCTP_ASSOC_CHANGE, */ + #endif + #ifdef SCTP_PEER_ADDR_CHANGE + SCTP_PEER_ADDR_CHANGE, + #endif + #ifdef SCTP_REMOTE_ERROR + SCTP_REMOTE_ERROR, + #endif + #ifdef SCTP_SEND_FAILED_EVENT + SCTP_SEND_FAILED_EVENT, + #endif + #ifdef SCTP_SHUTDOWN_EVENT + SCTP_SHUTDOWN_EVENT, + #endif + #ifdef SCTP_ADAPTATION_INDICATION + /* SCTP_ADAPTATION_INDICATION, */ + #endif + #ifdef SCTP_PARTIAL_DELIVERY_EVENT + /* SCTP_PARTIAL_DELIVERY_EVENT, */ + #endif + #ifdef SCTP_AUTHENTICATION_EVENT + /* SCTP_AUTHENTICATION_EVENT, */ + #endif + #ifdef SCTP_SENDER_DRY_EVENT + /* SCTP_SENDER_DRY_EVENT, */ + #endif + 0 + }; + int i; + + struct sctp_event event; + + for (i = 0; i < (sizeof(events_I_want) / sizeof(events_I_want[0]) - 1); i++) { + memset(&event, 0, sizeof(event)); + event.se_type = events_I_want[i]; + event.se_on = 1; + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) ); + } + } + #else /* SCTP_EVENT */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_EVENT"); + #endif /* SCTP_EVENT */ + + + #ifdef SCTP_RECVRCVINFO /* Replaces SCTP_SNDRCV */ + { + int bool = 1; + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_RECVRCVINFO, &bool, sizeof(bool)) ); + + } + #else /* SCTP_RECVRCVINFO */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_RECVRCVINFO"); + #endif /* SCTP_RECVRCVINFO */ + + +#endif /* OLD_SCTP_SOCKET_API */ + + /* + SCTP_RECVNXTINFO + + SCTP_DEFAULT_SNDINFO : send defaults + SCTP_DEFAULT_PRINFO : default PR-SCTP + */ + + + /* In case of no_ip4, force the v6only option */ + #ifdef IPV6_V6ONLY + if (fd_g_config->cnf_flags.no_ip4) { + int opt = 1; + CHECK_SYS(setsockopt(sk, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt))); + } + #endif /* IPV6_V6ONLY */ + + return 0; +} + + +/* Post-binding socket options */ +static int fd_setsockopt_postbind(int sk, int bound_to_default) +{ + TRACE_ENTRY( "%d %d", sk, bound_to_default); + + CHECK_PARAMS( (sk > 0) ); + + /* Set the ASCONF option */ + #ifdef SCTP_AUTO_ASCONF + if (bound_to_default) { + int asconf; + + if (TRACE_BOOL(ANNOYING)) { + socklen_t sz; + + sz = sizeof(asconf); + /* Read socket defaults */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_AUTO_ASCONF, &asconf, &sz) ); + if (sz != sizeof(asconf)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(asconf)); + return ENOTSUP; + } + fd_log_debug( "Def SCTP_AUTO_ASCONF value : %s", asconf ? "true" : "false"); + } + + asconf = 1; /* allow automatic use of added or removed addresses in the association (for bound-all sockets) */ + + /* Set the option to the socket */ + CHECK_SYS( setsockopt(sk, IPPROTO_SCTP, SCTP_AUTO_ASCONF, &asconf, sizeof(asconf)) ); + + if (TRACE_BOOL(ANNOYING)) { + socklen_t sz = sizeof(asconf); + /* Check new values */ + CHECK_SYS( getsockopt(sk, IPPROTO_SCTP, SCTP_AUTO_ASCONF, &asconf, &sz) ); + fd_log_debug( "New SCTP_AUTO_ASCONF value : %s", asconf ? "true" : "false"); + } + } + #else /* SCTP_AUTO_ASCONF */ + TRACE_DEBUG(ANNOYING, "Skipping SCTP_AUTO_ASCONF"); + #endif /* SCTP_AUTO_ASCONF */ + + return 0; +} + +/* Add addresses from a list to an array, with filter on the flags */ +static int add_addresses_from_list_mask(uint8_t ** array, size_t * size, int * addr_count, int target_family, uint16_t port, struct fd_list * list, uint32_t mask, uint32_t val) +{ + struct fd_list * li; + int to_add4 = 0; + int to_add6 = 0; + union { + uint8_t *buf; + sSA4 *sin; + sSA6 *sin6; + } ptr; + size_t sz; + + /* First, count the number of addresses to add */ + for (li = list->next; li != list; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *) li; + + /* Do the flag match ? */ + if ((val & mask) != (ep->flags & mask)) + continue; + + if (ep->sa.sa_family == AF_INET) { + to_add4 ++; + } else { + to_add6 ++; + } + } + + if ((to_add4 + to_add6) == 0) + return 0; /* nothing to do */ + + /* The size to add */ + if (target_family == AF_INET) { + sz = to_add4 * sizeof(sSA4); + } else { + #ifndef SCTP_USE_MAPPED_ADDRESSES + sz = (to_add4 * sizeof(sSA4)) + (to_add6 * sizeof(sSA6)); + #else /* SCTP_USE_MAPPED_ADDRESSES */ + sz = (to_add4 + to_add6) * sizeof(sSA6); + #endif /* SCTP_USE_MAPPED_ADDRESSES */ + } + + /* Now, (re)alloc the array to store the new addresses */ + CHECK_MALLOC( *array = realloc(*array, *size + sz) ); + + /* Finally, add the addresses */ + for (li = list->next; li != list; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *) li; + + /* Skip v6 addresses for v4 socket */ + if ((target_family == AF_INET) && (ep->sa.sa_family == AF_INET6)) + continue; + + /* Are the flags matching ? */ + if ((val & mask) != (ep->flags & mask)) + continue; + + /* Size of the new SA we are adding (array may contain a mix of sockaddr_in and sockaddr_in6) */ + #ifndef SCTP_USE_MAPPED_ADDRESSES + if (ep->sa.sa_family == AF_INET6) + #else /* SCTP_USE_MAPPED_ADDRESSES */ + if (target_family == AF_INET6) + #endif /* SCTP_USE_MAPPED_ADDRESSES */ + sz = sizeof(sSA6); + else + sz = sizeof(sSA4); + + /* Place where we add the new address */ + ptr.buf = *array + *size; /* place of the new SA */ + + /* Update other information */ + *size += sz; + *addr_count += 1; + + /* And write the addr in the buffer */ + if (sz == sizeof(sSA4)) { + memcpy(ptr.buf, &ep->sin, sz); + ptr.sin->sin_port = port; + } else { + if (ep->sa.sa_family == AF_INET) { /* We must map the address */ + memset(ptr.buf, 0, sz); + ptr.sin6->sin6_family = AF_INET6; + IN6_ADDR_V4MAP( &ptr.sin6->sin6_addr.s6_addr, ep->sin.sin_addr.s_addr ); + } else { + memcpy(ptr.sin6, &ep->sin6, sz); + } + ptr.sin6->sin6_port = port; + } + } + + return 0; +} + +/* Create a socket server and bind it according to daemon s configuration */ +int fd_sctp_create_bind_server( int * sock, int family, struct fd_list * list, uint16_t port ) +{ + int bind_default; + + TRACE_ENTRY("%p %i %p %hu", sock, family, list, port); + CHECK_PARAMS(sock); + + /* Create the socket */ + CHECK_SYS( *sock = socket(family, SOCK_STREAM, IPPROTO_SCTP) ); + + /* Set pre-binding socket options, including number of streams etc... */ + CHECK_FCT( fd_setsockopt_prebind(*sock) ); + + bind_default = (! list) || (FD_IS_LIST_EMPTY(list)) ; +redo: + if ( bind_default ) { + /* Implicit endpoints : bind to default addresses */ + union { + sSS ss; + sSA sa; + sSA4 sin; + sSA6 sin6; + } s; + + /* 0.0.0.0 and [::] are all zeros */ + memset(&s, 0, sizeof(s)); + + s.sa.sa_family = family; + + if (family == AF_INET) + s.sin.sin_port = htons(port); + else + s.sin6.sin6_port = htons(port); + + CHECK_SYS( bind(*sock, &s.sa, sSAlen(&s)) ); + + } else { + /* Explicit endpoints to bind to from config */ + + sSA * sar = NULL; /* array of addresses */ + size_t sz = 0; /* size of the array */ + int count = 0; /* number of sock addr in the array */ + + /* Create the array of configured addresses */ + CHECK_FCT( add_addresses_from_list_mask((void *)&sar, &sz, &count, family, htons(port), list, EP_FL_CONF, EP_FL_CONF) ); + + if (!count) { + /* None of the addresses in the list came from configuration, we bind to default */ + bind_default = 1; + goto redo; + } + + #if 0 + union { + sSA *sa; + uint8_t *buf; + } ptr; + int i; + ptr.sa = sar; + fd_log_debug("Calling sctp_bindx with the following address array:"); + for (i = 0; i < count; i++) { + TRACE_sSA(FD_LOG_DEBUG, FULL, " - ", ptr.sa, NI_NUMERICHOST | NI_NUMERICSERV, "" ); + ptr.buf += (ptr.sa->sa_family == AF_INET) ? sizeof(sSA4) : sizeof(sSA6) ; + } + #endif + + /* Bind to this array */ + CHECK_SYS( sctp_bindx(*sock, sar, count, SCTP_BINDX_ADD_ADDR) ); + + /* We don't need sar anymore */ + free(sar); + } + + /* Now, the server is bound, set remaining sockopt */ + CHECK_FCT( fd_setsockopt_postbind(*sock, bind_default) ); + + /* Debug: show all local listening addresses */ + #if 0 + sSA *sar; + union { + sSA *sa; + uint8_t *buf; + } ptr; + int sz; + + CHECK_SYS( sz = sctp_getladdrs(*sock, 0, &sar) ); + + fd_log_debug("SCTP server bound on :"); + for (ptr.sa = sar; sz-- > 0; ptr.buf += (ptr.sa->sa_family == AF_INET) ? sizeof(sSA4) : sizeof(sSA6)) { + TRACE_sSA(FD_LOG_DEBUG, FULL, " - ", ptr.sa, NI_NUMERICHOST | NI_NUMERICSERV, "" ); + } + sctp_freeladdrs(sar); + #endif + + return 0; +} + +/* Allow clients connections on server sockets */ +int fd_sctp_listen( int sock ) +{ + TRACE_ENTRY("%d", sock); + CHECK_SYS( listen(sock, 5) ); + return 0; +} + +/* Create a client socket and connect to remote server */ +int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list ) +{ + int family; + union { + uint8_t *buf; + sSA *sa; + } sar; + size_t size = 0; + int count = 0; + int ret; + + sar.buf = NULL; + + TRACE_ENTRY("%p %i %hu %p", sock, no_ip6, port, list); + CHECK_PARAMS( sock && list && (!FD_IS_LIST_EMPTY(list)) ); + + if (no_ip6) { + family = AF_INET; + } else { + family = AF_INET6; + } + + /* Create the socket */ + CHECK_SYS( *sock = socket(family, SOCK_STREAM, IPPROTO_SCTP) ); + + /* Cleanup if we are cancelled */ + pthread_cleanup_push(fd_cleanup_socket, sock); + + /* Set the socket options */ + CHECK_FCT_DO( ret = fd_setsockopt_prebind(*sock), goto out ); + + /* Create the array of addresses, add first the configured addresses, then the discovered, then the other ones */ + CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF, EP_FL_CONF ), goto out ); + CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, EP_FL_DISC ), goto out ); + CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, 0 ), goto out ); + + /* Try connecting */ + LOG_A("Attempting SCTP connection (%d addresses attempted) ", count); + +#if 0 + /* Dump the SAs */ + union { + uint8_t *buf; + sSA *sa; + sSA4 *sin; + sSA6 *sin6; + } ptr; + int i; + ptr.buf = sar.buf; + for (i=0; i< count; i++) { + TRACE_sSA(FD_LOG_DEBUG, FULL, " - ", ptr.sa, NI_NUMERICHOST | NI_NUMERICSERV, "" ); + ptr.buf += (ptr.sa->sa_family == AF_INET) ? sizeof(sSA4) : sizeof(sSA6); + } +#endif + + /* Bug in some Linux kernel, the sctp_connectx is not a cancellation point. To avoid blocking freeDiameter, we allow async cancel here */ + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +#ifdef SCTP_CONNECTX_4_ARGS + ret = sctp_connectx(*sock, sar.sa, count, NULL); +#else /* SCTP_CONNECTX_4_ARGS */ + ret = sctp_connectx(*sock, sar.sa, count); +#endif /* SCTP_CONNECTX_4_ARGS */ + /* back to normal cancelation behabior */ + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); + + if (ret < 0) { + ret = errno; + /* Some errors are expected, we log at different level */ + LOG_A("sctp_connectx returned an error: %s", strerror(ret)); + goto out; + } + + free(sar.buf); sar.buf = NULL; + + /* Set the remaining sockopts */ + CHECK_FCT_DO( ret = fd_setsockopt_postbind(*sock, 1), + { + CHECK_SYS_DO( shutdown(*sock, SHUT_RDWR), /* continue */ ); + } ); + +out: + ; + pthread_cleanup_pop(0); + + if (ret) { + if (*sock > 0) { + CHECK_SYS_DO( close(*sock), /* continue */ ); + *sock = -1; + } + free(sar.buf); + } + return ret; +} + +/* Retrieve streams information from a connected association -- optionally provide the primary address */ +int fd_sctp_get_str_info( int sock, uint16_t *in, uint16_t *out, sSS *primary ) +{ + struct sctp_status status; + socklen_t sz = sizeof(status); + + TRACE_ENTRY("%d %p %p %p", sock, in, out, primary); + CHECK_PARAMS( (sock > 0) && in && out ); + + /* Read the association parameters */ + memset(&status, 0, sizeof(status)); + CHECK_SYS( getsockopt(sock, IPPROTO_SCTP, SCTP_STATUS, &status, &sz) ); + if (sz != sizeof(status)) + { + TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %zd", sz, sizeof(status)); + return ENOTSUP; + } +#if 0 + char sa_buf[sSA_DUMP_STRLEN]; + fd_sa_sdump_numeric(sa_buf, &status.sstat_primary.spinfo_address); + fd_log_debug( "SCTP_STATUS : sstat_state : %i" , status.sstat_state); + fd_log_debug( " sstat_rwnd : %u" , status.sstat_rwnd); + fd_log_debug( " sstat_unackdata : %hu", status.sstat_unackdata); + fd_log_debug( " sstat_penddata : %hu", status.sstat_penddata); + fd_log_debug( " sstat_instrms : %hu", status.sstat_instrms); + fd_log_debug( " sstat_outstrms : %hu", status.sstat_outstrms); + fd_log_debug( " sstat_fragmentation_point : %u" , status.sstat_fragmentation_point); + fd_log_debug( " sstat_primary.spinfo_address : %s" , sa_buf); + fd_log_debug( " sstat_primary.spinfo_state : %d" , status.sstat_primary.spinfo_state); + fd_log_debug( " sstat_primary.spinfo_cwnd : %u" , status.sstat_primary.spinfo_cwnd); + fd_log_debug( " sstat_primary.spinfo_srtt : %u" , status.sstat_primary.spinfo_srtt); + fd_log_debug( " sstat_primary.spinfo_rto : %u" , status.sstat_primary.spinfo_rto); + fd_log_debug( " sstat_primary.spinfo_mtu : %u" , status.sstat_primary.spinfo_mtu); +#endif /* 0 */ + + *in = status.sstat_instrms; + *out = status.sstat_outstrms; + + if (primary) + memcpy(primary, &status.sstat_primary.spinfo_address, sizeof(sSS)); + + return 0; +} + +/* Get the list of remote endpoints of the socket */ +int fd_sctp_get_remote_ep(int sock, struct fd_list * list) +{ + union { + sSA *sa; + uint8_t *buf; + } ptr; + + sSA * data = NULL; + int count; + + TRACE_ENTRY("%d %p", sock, list); + CHECK_PARAMS(list); + + /* Read the list on the socket */ + CHECK_SYS( count = sctp_getpaddrs(sock, 0, &data) ); + ptr.sa = data; + + while (count) { + socklen_t sl; + switch (ptr.sa->sa_family) { + case AF_INET: sl = sizeof(sSA4); break; + case AF_INET6: sl = sizeof(sSA6); break; + default: + TRACE_DEBUG(INFO, "Unknown address family returned in sctp_getpaddrs: %d, skip", ptr.sa->sa_family); + /* There is a bug in current Linux kernel: http://www.spinics.net/lists/linux-sctp/msg00760.html */ + goto stop; + } + + CHECK_FCT( fd_ep_add_merge( list, ptr.sa, sl, EP_FL_LL ) ); + ptr.buf += sl; + count --; + } +stop: + /* Free the list */ + sctp_freepaddrs(data); + + /* Now get the primary address, the add function will take care of merging with existing entry */ + { + + struct sctp_status status; + socklen_t sz = sizeof(status); + int ret; + + memset(&status, 0, sizeof(status)); + /* Attempt to use SCTP_STATUS message to retrieve the primary address */ + CHECK_SYS_DO( ret = getsockopt(sock, IPPROTO_SCTP, SCTP_STATUS, &status, &sz), /* continue */); + if (sz != sizeof(status)) + ret = -1; + sz = sizeof(sSS); + if (ret < 0) + { + /* Fallback to getsockname -- not recommended by draft-ietf-tsvwg-sctpsocket-19#section-7.4 */ + CHECK_SYS(getpeername(sock, (sSA *)&status.sstat_primary.spinfo_address, &sz)); + } + + CHECK_FCT( fd_ep_add_merge( list, (sSA *)&status.sstat_primary.spinfo_address, sz, EP_FL_PRIMARY ) ); + } + + /* Done! */ + return 0; +} + +/* Send a vector over a specified stream */ +ssize_t fd_sctp_sendstrv(struct cnxctx * conn, uint16_t strid, const struct iovec *iov, int iovcnt) +{ + struct msghdr mhdr; + struct cmsghdr *hdr; +#ifdef OLD_SCTP_SOCKET_API + struct sctp_sndrcvinfo *sndrcv; + uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; +#else /* OLD_SCTP_SOCKET_API */ + struct sctp_sndinfo *sndinf; + uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; +#endif /* OLD_SCTP_SOCKET_API */ + ssize_t ret; + struct timespec ts, now; + + TRACE_ENTRY("%p %hu %p %d", conn, strid, iov, iovcnt); + CHECK_PARAMS_DO(conn && iov && iovcnt, { errno = EINVAL; return -1; } ); + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return -1 ); + + memset(&mhdr, 0, sizeof(mhdr)); + memset(&anci, 0, sizeof(anci)); + + /* Anciliary data: specify SCTP stream */ + hdr = (struct cmsghdr *)anci; + hdr->cmsg_len = sizeof(anci); + hdr->cmsg_level = IPPROTO_SCTP; +#ifdef OLD_SCTP_SOCKET_API + hdr->cmsg_type = SCTP_SNDRCV; + sndrcv = (struct sctp_sndrcvinfo *)CMSG_DATA(hdr); + sndrcv->sinfo_stream = strid; +#else /* OLD_SCTP_SOCKET_API */ + hdr->cmsg_type = SCTP_SNDINFO; + sndinf = (struct sctp_sndinfo *)CMSG_DATA(hdr); + sndinf->snd_sid = strid; +#endif /* OLD_SCTP_SOCKET_API */ + /* note : we could store other data also, for example in .sinfo_ppid for remote peer or in .sinfo_context for errors. */ + + /* We don't use mhdr.msg_name here; it could be used to specify an address different from the primary */ + + mhdr.msg_iov = (struct iovec *)iov; + mhdr.msg_iovlen = iovcnt; + + mhdr.msg_control = anci; + mhdr.msg_controllen = sizeof(anci); + + TRACE_DEBUG(FULL, "Sending %d chunks of data (first:%zdb) on stream %hu of socket %d", iovcnt, iov[0].iov_len, strid, conn->cc_socket); +again: + ret = sendmsg(conn->cc_socket, &mhdr, 0); + /* Handle special case of timeout */ + if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { + pthread_testcancel(); + /* Check how much time we were blocked for this sending. */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), return -1 ); + if ( ((now.tv_sec - ts.tv_sec) * 1000 + ((now.tv_nsec - ts.tv_nsec) / 1000000L)) > MAX_HOTL_BLOCKING_TIME) { + LOG_D("Unable to send any data for %dms, closing the connection", MAX_HOTL_BLOCKING_TIME); + } else if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING )) { + goto again; /* don't care, just ignore */ + } + + /* propagate the error */ + errno = -ret; + ret = -1; + } + + CHECK_SYS_DO( ret, ); /* for tracing error only */ + + return ret; +} + +/* Receive the next data from the socket, or next notification */ +int fd_sctp_recvmeta(struct cnxctx * conn, uint16_t * strid, uint8_t ** buf, size_t * len, int *event) +{ + ssize_t ret = 0; + struct msghdr mhdr; + char ancidata[ CMSG_BUF_LEN ]; + struct iovec iov; + uint8_t *data = NULL; + size_t bufsz = 0, datasize = 0; + size_t mempagesz = sysconf(_SC_PAGESIZE); /* We alloc buffer by memory pages for efficiency */ + int timedout = 0; + + TRACE_ENTRY("%p %p %p %p %p", conn, strid, buf, len, event); + CHECK_PARAMS( conn && buf && len && event ); + + /* Cleanup out parameters */ + *buf = NULL; + *len = 0; + *event = 0; + + /* Prepare header for receiving message */ + memset(&mhdr, 0, sizeof(mhdr)); + mhdr.msg_iov = &iov; + mhdr.msg_iovlen = 1; + mhdr.msg_control = &ancidata; + mhdr.msg_controllen = sizeof(ancidata); + +next_message: + datasize = 0; + + /* We will loop while all data is not received. */ +incomplete: + while (datasize >= bufsz ) { + /* The buffer is full, enlarge it */ + bufsz += mempagesz; + CHECK_MALLOC( data = realloc(data, bufsz ) ); + } + /* the new data will be received following the preceding */ + memset(&iov, 0, sizeof(iov)); + iov.iov_base = data + datasize ; + iov.iov_len = bufsz - datasize; + + /* Receive data from the socket */ +again: + pthread_cleanup_push(free, data); + ret = recvmsg(conn->cc_socket, &mhdr, 0); + pthread_testcancel(); + pthread_cleanup_pop(0); + + /* First, handle timeouts (same as fd_cnx_s_recv) */ + if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { + if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING )) + goto again; /* don't care, just ignore */ + if (!timedout) { + timedout ++; /* allow for one timeout while closing */ + goto again; + } + /* fallback to normal handling */ + } + + /* Handle errors */ + if (ret <= 0) { /* Socket timedout, closed, or an error occurred */ + CHECK_SYS_DO(ret, /* to log in case of error */); + free(data); + *event = FDEVP_CNX_ERROR; + return 0; + } + + /* Update the size of data we received */ + datasize += ret; + + /* SCTP provides an indication when we received a full record; loop if it is not the case */ + if ( ! (mhdr.msg_flags & MSG_EOR) ) { + goto incomplete; + } + + /* Handle the case where the data received is a notification */ + if (mhdr.msg_flags & MSG_NOTIFICATION) { + union sctp_notification * notif = (union sctp_notification *) data; + + TRACE_DEBUG(FULL, "Received %zdb data of notification on socket %d", datasize, conn->cc_socket); + + switch (notif->sn_header.sn_type) { + + case SCTP_ASSOC_CHANGE: /* We should not receive these as we did not subscribe for it */ + TRACE_DEBUG(FULL, "Received SCTP_ASSOC_CHANGE notification"); + TRACE_DEBUG(ANNOYING, " state : %hu", notif->sn_assoc_change.sac_state); + TRACE_DEBUG(ANNOYING, " error : %hu", notif->sn_assoc_change.sac_error); + TRACE_DEBUG(ANNOYING, " instr : %hu", notif->sn_assoc_change.sac_inbound_streams); + TRACE_DEBUG(ANNOYING, " outstr : %hu", notif->sn_assoc_change.sac_outbound_streams); + + *event = FDEVP_CNX_EP_CHANGE; + break; + + case SCTP_PEER_ADDR_CHANGE: + TRACE_DEBUG(FULL, "Received SCTP_PEER_ADDR_CHANGE notification"); + /* TRACE_sSA(FD_LOG_DEBUG, ANNOYING, " intf_change : ", &(notif->sn_paddr_change.spc_aaddr), NI_NUMERICHOST | NI_NUMERICSERV, "" ); */ + TRACE_DEBUG(ANNOYING, " state : %d", notif->sn_paddr_change.spc_state); + TRACE_DEBUG(ANNOYING, " error : %d", notif->sn_paddr_change.spc_error); + + *event = FDEVP_CNX_EP_CHANGE; + break; + + case SCTP_REMOTE_ERROR: + TRACE_DEBUG(FULL, "Received SCTP_REMOTE_ERROR notification"); + TRACE_DEBUG(ANNOYING, " err : %hu", ntohs(notif->sn_remote_error.sre_error)); + TRACE_DEBUG(ANNOYING, " len : %hu", ntohs(notif->sn_remote_error.sre_length)); + + *event = FDEVP_CNX_ERROR; + break; + +#ifdef OLD_SCTP_SOCKET_API + case SCTP_SEND_FAILED: + TRACE_DEBUG(FULL, "Received SCTP_SEND_FAILED notification"); + TRACE_DEBUG(ANNOYING, " len : %hu", notif->sn_send_failed.ssf_length); + TRACE_DEBUG(ANNOYING, " err : %d", notif->sn_send_failed.ssf_error); + + *event = FDEVP_CNX_ERROR; + break; +#else /* OLD_SCTP_SOCKET_API */ + case SCTP_SEND_FAILED_EVENT: + TRACE_DEBUG(FULL, "Received SCTP_SEND_FAILED_EVENT notification"); + *event = FDEVP_CNX_ERROR; + break; +#endif /* OLD_SCTP_SOCKET_API */ + case SCTP_SHUTDOWN_EVENT: + TRACE_DEBUG(FULL, "Received SCTP_SHUTDOWN_EVENT notification"); + + *event = FDEVP_CNX_SHUTDOWN; + break; + +#ifndef OLD_SCTP_SOCKET_API + case SCTP_NOTIFICATIONS_STOPPED_EVENT: + TRACE_DEBUG(INFO, "Received SCTP_NOTIFICATIONS_STOPPED_EVENT notification, marking the association in error state"); + *event = FDEVP_CNX_ERROR; + break; +#endif /* OLD_SCTP_SOCKET_API */ + + default: + TRACE_DEBUG(FULL, "Received unknown notification %d, ignored", notif->sn_header.sn_type); + goto next_message; + } + + free(data); + return 0; + } + + /* From this point, we have received a message */ + *event = FDEVP_CNX_MSG_RECV; + *buf = data; + *len = datasize; + + if (strid) { + struct cmsghdr *hdr; +#ifdef OLD_SCTP_SOCKET_API + struct sctp_sndrcvinfo *sndrcv; +#else /* OLD_SCTP_SOCKET_API */ + struct sctp_rcvinfo *rcvinf; +#endif /* OLD_SCTP_SOCKET_API */ + + /* Handle the anciliary data */ + for (hdr = CMSG_FIRSTHDR(&mhdr); hdr; hdr = CMSG_NXTHDR(&mhdr, hdr)) { + + /* We deal only with anciliary data at SCTP level */ + if (hdr->cmsg_level != IPPROTO_SCTP) { + TRACE_DEBUG(FULL, "Received some anciliary data at level %d, skipped", hdr->cmsg_level); + continue; + } + +#ifdef OLD_SCTP_SOCKET_API + /* Also only interested in SCTP_SNDRCV message for the moment */ + if (hdr->cmsg_type != SCTP_SNDRCV) { + TRACE_DEBUG(FULL, "Anciliary block IPPROTO_SCTP / %d, skipped", hdr->cmsg_type); + continue; + } + + sndrcv = (struct sctp_sndrcvinfo *) CMSG_DATA(hdr); + if (TRACE_BOOL(ANNOYING)) { + fd_log_debug( "Anciliary block IPPROTO_SCTP / SCTP_SNDRCV"); + fd_log_debug( " sinfo_stream : %hu", sndrcv->sinfo_stream); + fd_log_debug( " sinfo_ssn : %hu", sndrcv->sinfo_ssn); + fd_log_debug( " sinfo_flags : %hu", sndrcv->sinfo_flags); + /* fd_log_debug( " sinfo_pr_policy : %hu", sndrcv->sinfo_pr_policy); */ + fd_log_debug( " sinfo_ppid : %u" , sndrcv->sinfo_ppid); + fd_log_debug( " sinfo_context : %u" , sndrcv->sinfo_context); + /* fd_log_debug( " sinfo_pr_value : %u" , sndrcv->sinfo_pr_value); */ + fd_log_debug( " sinfo_tsn : %u" , sndrcv->sinfo_tsn); + fd_log_debug( " sinfo_cumtsn : %u" , sndrcv->sinfo_cumtsn); + } + + *strid = sndrcv->sinfo_stream; +#else /* OLD_SCTP_SOCKET_API */ + /* Also only interested in SCTP_RCVINFO message for the moment */ + if (hdr->cmsg_type != SCTP_RCVINFO) { + TRACE_DEBUG(FULL, "Anciliary block IPPROTO_SCTP / %d, skipped", hdr->cmsg_type); + continue; + } + + rcvinf = (struct sctp_rcvinfo *) CMSG_DATA(hdr); + + *strid = rcvinf->rcv_sid; +#endif /* OLD_SCTP_SOCKET_API */ + + + } + TRACE_DEBUG(FULL, "Received %zdb data on socket %d, stream %hu", datasize, conn->cc_socket, *strid); + } else { + TRACE_DEBUG(FULL, "Received %zdb data on socket %d (stream ignored)", datasize, conn->cc_socket); + } + + return 0; +} diff --git a/plat/diameter/libfdcore/sctp3436.c b/plat/diameter/libfdcore/sctp3436.c new file mode 100644 index 0000000..e54e119 --- /dev/null +++ b/plat/diameter/libfdcore/sctp3436.c @@ -0,0 +1,793 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* This file contains code for TLS over multi-stream SCTP wrapper implementation (GnuTLS does not support this) */ +/* See http://aaa.koganei.wide.ad.jp/blogs/index.php/waaad/2008/08/18/tls-over-sctp for history */ + +#include "fdcore-internal.h" +#include "cnxctx.h" + +#include +#include + +/* + +Architecture of this wrapper: + - we have several fifo queues (1 per stream pairs). + GnuTLS is configured to use custom push / pull functions: + - the pull function retrieves the data from the fifo queue corresponding to a stream #. + - the push function sends the data on a certain stream. + We also have a demux thread that reads the socket and store received data in the appropriate fifo + + We have one gnutls_session per stream pair, and as many threads that read the gnutls records and save incoming data to the target queue. + +This complexity is required because we cannot read a socket for a given stream only; we can only get the next message and find its stream. +*/ + +/* Note that this mechanism is replaced by DTLS in RFC6733 */ + +/*************************************************************/ +/* threads */ +/*************************************************************/ + +/* Demux received data and store in the appropriate fifo */ +static void * demuxer(void * arg) +{ + struct cnxctx * conn = arg; + uint8_t * buf; + size_t bufsz; + int event; + uint16_t strid; + + TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Demuxer (%d:%s)", conn->cc_socket, conn->cc_remid); + fd_log_threadname ( buf ); + } + + ASSERT( conn->cc_proto == IPPROTO_SCTP ); + ASSERT( fd_cnx_target_queue(conn) ); + ASSERT( conn->cc_sctp3436_data.array ); + + do { + CHECK_FCT_DO( fd_sctp_recvmeta(conn, &strid, &buf, &bufsz, &event), goto fatal ); + switch (event) { + case FDEVP_CNX_MSG_RECV: + /* Demux this message to the appropriate fifo, another thread will pull, gnutls process, and send to target queue */ + if (strid < conn->cc_sctp_para.pairs) { + CHECK_FCT_DO(fd_event_send(conn->cc_sctp3436_data.array[strid].raw_recv, event, bufsz, buf), goto fatal ); + } else { + TRACE_DEBUG(INFO, "Received packet (%zd bytes) on out-of-range stream #%d from %s, discarded.", bufsz, strid, conn->cc_remid); + free(buf); + } + break; + + case FDEVP_CNX_EP_CHANGE: + /* Send this event to the target queue */ + CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), event, bufsz, buf), goto fatal ); + break; + + case FDEVP_CNX_ERROR: + goto out; + + case FDEVP_CNX_SHUTDOWN: + /* Just ignore the notification for now, we will get another error later anyway */ + continue; + + default: + goto fatal; + } + + } while (conn->cc_loop); + +out: + /* Signal termination of the connection to all decipher threads */ + for (strid = 0; strid < conn->cc_sctp_para.pairs; strid++) { + if (conn->cc_sctp3436_data.array[strid].raw_recv) { + CHECK_FCT_DO(fd_event_send(conn->cc_sctp3436_data.array[strid].raw_recv, FDEVP_CNX_ERROR, 0, NULL), goto fatal ); + } + } + fd_cnx_markerror(conn); + TRACE_DEBUG(FULL, "Thread terminated"); + return NULL; + +fatal: + /* An unrecoverable error occurred, stop the daemon */ + CHECK_FCT_DO(fd_core_shutdown(), ); + goto out; +} + +/* Decrypt the data received in this stream pair and store it in the target queue */ +static void * decipher(void * arg) +{ + struct sctp3436_ctx * ctx = arg; + struct cnxctx *cnx; + + TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO(ctx && ctx->raw_recv && ctx->parent, goto error); + cnx = ctx->parent; + ASSERT( fd_cnx_target_queue(cnx) ); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Decipher (%hu@%d:%s)", ctx->strid, cnx->cc_socket, cnx->cc_remid); + fd_log_threadname ( buf ); + } + + /* The next function loops while there is no error */ + CHECK_FCT_DO(fd_tls_rcvthr_core(cnx, ctx->strid ? ctx->session : cnx->cc_tls_para.session), /* continue */); +error: + fd_cnx_markerror(cnx); + TRACE_DEBUG(FULL, "Thread terminated"); + return NULL; +} + +/*************************************************************/ +/* push / pull */ +/*************************************************************/ + +#ifdef GNUTLS_VERSION_300 +/* Check if data is available for gnutls on a given context */ +static int sctp3436_pull_timeout(gnutls_transport_ptr_t tr, unsigned int ms) +{ + struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr; + struct timespec tsstore, *ts = NULL; + int ret; + + TRACE_ENTRY("%p %d", tr, ms); + + if (ctx->partial.buf) + return 1; /* data is already available for pull */ + + if (ms) { + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &tsstore), return -1 ); + tsstore.tv_nsec += (long)ms * 1000000; + tsstore.tv_sec += tsstore.tv_nsec / 1000000000L; + tsstore.tv_nsec %= 1000000000L; + ts = &tsstore; + } + + ret = fd_fifo_select ( ctx->raw_recv, ts ); + if (ret < 0) { + errno = -ret; + ret = -1; + } + + return ret; +} +#endif /* GNUTLS_VERSION_300 */ + +/* Send data over the connection, called by gnutls */ +#ifndef GNUTLS_VERSION_212 +static ssize_t sctp3436_push(gnutls_transport_ptr_t tr, const void * data, size_t len) +{ + struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr; + struct iovec iov; + + TRACE_ENTRY("%p %p %zd", tr, data, len); + CHECK_PARAMS_DO( tr && data, { errno = EINVAL; return -1; } ); + + iov.iov_base = (void *)data; + iov.iov_len = len; + + return fd_sctp_sendstrv(ctx->parent, ctx->strid, &iov, 1); +} +#else /* GNUTLS_VERSION_212 */ +static ssize_t sctp3436_pushv(gnutls_transport_ptr_t tr, const giovec_t * iov, int iovcnt) +{ + struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr; + + TRACE_ENTRY("%p %p %d", tr, iov, iovcnt); + CHECK_PARAMS_DO( tr && iov, { errno = EINVAL; return -1; } ); + + return fd_sctp_sendstrv(ctx->parent, ctx->strid, (const struct iovec *)iov, iovcnt); +} +#endif /* GNUTLS_VERSION_212 */ + +/* Retrieve data received on a stream and already demultiplexed */ +static ssize_t sctp3436_pull(gnutls_transport_ptr_t tr, void * buf, size_t len) +{ + struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr; + size_t pulled = 0; + int emptied; + + TRACE_ENTRY("%p %p %zd", tr, buf, len); + CHECK_PARAMS_DO( tr && buf, { errno = EINVAL; goto error; } ); + + /* If we don't have data available now, pull new message from the fifo -- this is blocking (until the queue is destroyed) */ + if (!ctx->partial.buf) { + int ev; + CHECK_FCT_DO( errno = fd_event_get(ctx->raw_recv, &ev, &ctx->partial.bufsz, (void *)&ctx->partial.buf), goto error ); + if (ev == FDEVP_CNX_ERROR) { + /* Documentations says to return 0 on connection closed, but it does hang within gnutls_handshake */ + return -1; + } + } + + pulled = ctx->partial.bufsz - ctx->partial.offset; + if (pulled <= len) { + emptied = 1; + } else { + /* limit to the capacity of destination buffer */ + emptied = 0; + pulled = len; + } + + /* Store the data in the destination buffer */ + memcpy(buf, ctx->partial.buf + ctx->partial.offset, pulled); + + /* Free the buffer if we read all its content, and reset the partial structure */ + if (emptied) { + free(ctx->partial.buf); + memset(&ctx->partial, 0, sizeof(ctx->partial)); + } else { + ctx->partial.offset += pulled; + } + + /* We are done */ + return pulled; + +error: + gnutls_transport_set_errno (ctx->session, errno); + return -1; +} + +/* Set the parameters of a session to use the appropriate fifo and stream information */ +#ifndef GNUTLS_VERSION_300 +GCC_DIAG_OFF("-Wdeprecated-declarations") +#endif /* !GNUTLS_VERSION_300 */ +static void set_sess_transport(gnutls_session_t session, struct sctp3436_ctx *ctx) +{ + /* Set the transport pointer passed to push & pull callbacks */ + GNUTLS_TRACE( gnutls_transport_set_ptr( session, (gnutls_transport_ptr_t) ctx ) ); + + /* Reset the low water value, since we don't use sockets */ +#ifndef GNUTLS_VERSION_300 + /* starting version 2.12, this call is not needed */ + //GNUTLS_TRACE( gnutls_transport_set_lowat( session, 0 ) ); +#else /* GNUTLS_VERSION_300 */ + /* but in 3.0 we have to provide the pull_timeout callback */ + GNUTLS_TRACE( gnutls_transport_set_pull_timeout_function( session, sctp3436_pull_timeout ) ); +#endif /* GNUTLS_VERSION_300 */ + + /* Set the push and pull callbacks */ + GNUTLS_TRACE( gnutls_transport_set_pull_function(session, sctp3436_pull) ); +#ifndef GNUTLS_VERSION_212 + GNUTLS_TRACE( gnutls_transport_set_push_function(session, sctp3436_push) ); +#else /* GNUTLS_VERSION_212 */ + GNUTLS_TRACE( gnutls_transport_set_vec_push_function(session, sctp3436_pushv) ); +#endif /* GNUTLS_VERSION_212 */ + + return; +} +#ifndef GNUTLS_VERSION_300 +GCC_DIAG_ON("-Wdeprecated-declarations") +#endif /* !GNUTLS_VERSION_300 */ + +/*************************************************************/ +/* Session resuming support */ +/*************************************************************/ + +struct sr_store { + struct fd_list list; /* list of sr_data, ordered by key.size then key.data */ + pthread_rwlock_t lock; + struct cnxctx *parent; + /* Add another list to chain in a global list to implement a garbage collector on sessions -- TODO if needed */ +}; + +/* Saved master session data for resuming sessions */ +struct sr_data { + struct fd_list chain; + gnutls_datum_t key; + gnutls_datum_t data; +}; + +/* Initialize the store area for a connection */ +static int store_init(struct cnxctx * conn) +{ + TRACE_ENTRY("%p", conn); + CHECK_PARAMS( conn && !conn->cc_sctp3436_data.sess_store ); + + CHECK_MALLOC( conn->cc_sctp3436_data.sess_store = malloc(sizeof(struct sr_store)) ); + memset(conn->cc_sctp3436_data.sess_store, 0, sizeof(struct sr_store)); + + fd_list_init(&conn->cc_sctp3436_data.sess_store->list, NULL); + CHECK_POSIX( pthread_rwlock_init(&conn->cc_sctp3436_data.sess_store->lock, NULL) ); + conn->cc_sctp3436_data.sess_store->parent = conn; + + return 0; +} + +/* Destroy the store area for a connection, and all its content */ +static void store_destroy(struct cnxctx * conn) +{ + /* Del all list entries */ + TRACE_ENTRY("%p", conn); + CHECK_PARAMS_DO( conn, return ); + + if (!conn->cc_sctp3436_data.sess_store) + return; + + CHECK_POSIX_DO( pthread_rwlock_destroy(&conn->cc_sctp3436_data.sess_store->lock), /* continue */ ); + + while (!FD_IS_LIST_EMPTY(&conn->cc_sctp3436_data.sess_store->list)) { + struct sr_data * sr = (struct sr_data *) conn->cc_sctp3436_data.sess_store->list.next; + fd_list_unlink( &sr->chain ); + free(sr->key.data); + free(sr->data.data); + free(sr); + } + + free(conn->cc_sctp3436_data.sess_store); + conn->cc_sctp3436_data.sess_store = NULL; + return; +} + +/* Search the position (or next if not found) of a key in a store */ +static struct fd_list * find_or_next(struct sr_store * sto, gnutls_datum_t key, int * match) +{ + struct fd_list * ret; + *match = 0; + + for (ret = sto->list.next; ret != &sto->list; ret = ret->next) { + int cmp = 0; + struct sr_data * sr = (struct sr_data *)ret; + + cmp = fd_os_cmp(key.data, key.size, sr->key.data, sr->key.size); + if (cmp > 0) + continue; + + if (cmp == 0) + *match = 1; + + break; + } + + return ret; +} + +/* Callbacks for the TLS server side of the connection, called during gnutls_handshake */ +static int sr_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data) +{ + struct sr_store * sto = (struct sr_store *)dbf; + struct fd_list * li; + struct sr_data * sr; + int match = 0; + int ret = 0; + + TRACE_DEBUG( GNUTLS_DBG_LEVEL, "GNUTLS Callback: %s", __PRETTY_FUNCTION__ ); + CHECK_PARAMS_DO( sto && key.data && data.data, return -1 ); + + CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 ); + TRACE_BUFFER(FD_LOG_DEBUG, GNUTLS_DBG_LEVEL, "Session store [key ", key.data, key.size, "]"); + + li = find_or_next(sto, key, &match); + if (match) { + sr = (struct sr_data *)li; + + /* Check the data is the same */ + if ((data.size != sr->data.size) || memcmp(data.data, sr->data.data, data.size)) { + TRACE_DEBUG(INFO, "GnuTLS tried to store a session with same key and different data!"); + TRACE_BUFFER(FD_LOG_DEBUG, INFO, "Session store [key ", key.data, key.size, "]"); + TRACE_BUFFER(FD_LOG_DEBUG, INFO, " -- old data [", sr->data.data, sr->data.size, "]"); + TRACE_BUFFER(FD_LOG_DEBUG, INFO, " -- new data [", data.data, data.size, "]"); + + ret = -1; + } else { + TRACE_DEBUG(GNUTLS_DBG_LEVEL, "GnuTLS tried to store a session with same key and same data, skipped."); + } + goto out; + } + + /* Create a new entry */ + CHECK_MALLOC_DO( sr = malloc(sizeof(struct sr_data)), { ret = -1; goto out; } ); + memset(sr, 0, sizeof(struct sr_data)); + + fd_list_init(&sr->chain, sr); + + CHECK_MALLOC_DO( sr->key.data = malloc(key.size), { ret = -1; goto out; } ); + sr->key.size = key.size; + memcpy(sr->key.data, key.data, key.size); + + CHECK_MALLOC_DO( sr->data.data = malloc(data.size), { ret = -1; goto out; } ); + sr->data.size = data.size; + memcpy(sr->data.data, data.data, data.size); + + /* Save this new entry in the list, we are done */ + fd_list_insert_before(li, &sr->chain); + +out: + CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return -1 ); + return ret; +} + +static int sr_remove (void *dbf, gnutls_datum_t key) +{ + struct sr_store * sto = (struct sr_store *)dbf; + struct fd_list * li; + struct sr_data * sr; + int match = 0; + int ret = 0; + + TRACE_DEBUG( GNUTLS_DBG_LEVEL, "GNUTLS Callback: %s", __PRETTY_FUNCTION__ ); + CHECK_PARAMS_DO( sto && key.data, return -1 ); + + CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 ); + TRACE_BUFFER(FD_LOG_DEBUG, GNUTLS_DBG_LEVEL, "Session delete [key ", key.data, key.size, "]"); + + li = find_or_next(sto, key, &match); + if (match) { + sr = (struct sr_data *)li; + + /* Destroy this data */ + fd_list_unlink(li); + free(sr->key.data); + free(sr->data.data); + free(sr); + } else { + /* It was not found */ + ret = -1; + } + + CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return -1 ); + return ret; +} + +static gnutls_datum_t sr_fetch (void *dbf, gnutls_datum_t key) +{ + struct sr_store * sto = (struct sr_store *)dbf; + struct fd_list * li; + struct sr_data * sr; + int match = 0; + gnutls_datum_t res = { NULL, 0 }; + gnutls_datum_t error = { NULL, 0 }; + + TRACE_DEBUG( GNUTLS_DBG_LEVEL, "GNUTLS Callback: %s", __PRETTY_FUNCTION__ ); + CHECK_PARAMS_DO( sto && key.data, return error ); + + CHECK_POSIX_DO( pthread_rwlock_rdlock(&sto->lock), return error ); + TRACE_BUFFER(FD_LOG_DEBUG, GNUTLS_DBG_LEVEL, "Session fetch [key ", key.data, key.size, "]"); + + li = find_or_next(sto, key, &match); + if (match) { + sr = (struct sr_data *)li; + GNUTLS_TRACE( CHECK_MALLOC_DO(res.data = gnutls_malloc(sr->data.size), goto out ) ); + res.size = sr->data.size; + memcpy(res.data, sr->data.data, res.size); + } +out: + TRACE_DEBUG(GNUTLS_DBG_LEVEL, "Fetched (%p, %d) from store %p", res.data, res.size, sto); + CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return error); + return res; +} + +/* Set the session pointer in a session object */ +static void set_resume_callbacks(gnutls_session_t session, struct cnxctx * conn) +{ + TRACE_ENTRY("%p", conn); + + GNUTLS_TRACE( gnutls_db_set_retrieve_function(session, sr_fetch)); + GNUTLS_TRACE( gnutls_db_set_remove_function (session, sr_remove)); + GNUTLS_TRACE( gnutls_db_set_store_function (session, sr_store)); + GNUTLS_TRACE( gnutls_db_set_ptr (session, conn->cc_sctp3436_data.sess_store)); + + return; +} + +/* The handshake is made in parallel in several threads to speed up */ +static void * handshake_resume_th(void * arg) +{ + struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) arg; + int resumed; + + TRACE_ENTRY("%p", arg); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Handshake resume (%hu@%d)", ctx->strid, ctx->parent->cc_socket); + fd_log_threadname ( buf ); + } + + TRACE_DEBUG(FULL, "Starting TLS resumed handshake on stream %hu", ctx->strid); + + CHECK_GNUTLS_DO( gnutls_handshake( ctx->session ), return NULL); + + GNUTLS_TRACE( resumed = gnutls_session_is_resumed(ctx->session) ); + #ifndef GNUTLS_VERSION_300 + if (!resumed) { + /* Check the credentials here also */ + CHECK_FCT_DO( fd_tls_verify_credentials(ctx->session, ctx->parent, 0), return NULL ); + } + #endif /* GNUTLS_VERSION_300 */ + if (TRACE_BOOL(FULL)) { + if (resumed) { + fd_log_debug("Session was resumed successfully on stream %hu (conn: '%s')", ctx->strid, fd_cnx_getid(ctx->parent)); + } else { + fd_log_debug("Session was NOT resumed on stream %hu (full handshake) (conn: '%s')", ctx->strid, fd_cnx_getid(ctx->parent)); + } + } + + /* Finished, OK */ + return arg; +} + + +/*************************************************************/ +/* Exported functions */ +/*************************************************************/ + +/* Initialize the wrapper for the connection */ +int fd_sctp3436_init(struct cnxctx * conn) +{ + uint16_t i; + + TRACE_ENTRY("%p", conn); + CHECK_PARAMS( conn && (conn->cc_sctp_para.pairs > 1) && (!conn->cc_sctp3436_data.array) ); + + /* First, alloc the array and initialize the non-TLS data */ + CHECK_MALLOC( conn->cc_sctp3436_data.array = calloc(conn->cc_sctp_para.pairs, sizeof(struct sctp3436_ctx)) ); + for (i = 0; i < conn->cc_sctp_para.pairs; i++) { + conn->cc_sctp3436_data.array[i].parent = conn; + conn->cc_sctp3436_data.array[i].strid = i; + CHECK_FCT( fd_fifo_new(&conn->cc_sctp3436_data.array[i].raw_recv, 10) ); + } + + /* Set push/pull functions in the master session, using fifo in array[0] */ + set_sess_transport(conn->cc_tls_para.session, &conn->cc_sctp3436_data.array[0]); + + /* For server side, we also initialize the resuming capabilities */ + if (conn->cc_tls_para.mode == GNUTLS_SERVER) { + + /* Prepare the store for sessions data */ + CHECK_FCT( store_init(conn) ); + + /* Set the callbacks for resuming in the master session */ + set_resume_callbacks(conn->cc_tls_para.session, conn); + } + + /* Start the demux thread */ + CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, demuxer, conn ) ); + + return 0; +} + +/* Handshake other streams, after full handshake on the master session */ +int fd_sctp3436_handshake_others(struct cnxctx * conn, char * priority, void * alt_creds) +{ + uint16_t i; + int errors = 0; + gnutls_datum_t master_data; + + TRACE_ENTRY("%p %p", conn, priority); + CHECK_PARAMS( conn && (conn->cc_sctp_para.pairs > 1) && conn->cc_sctp3436_data.array ); + + /* Server side: we set all the parameters, the resume callback will take care of resuming the session */ + /* Client side: we duplicate the parameters of the master session, then set the transport pointer */ + + /* For client side, retrieve the master session parameters */ + if (conn->cc_tls_para.mode == GNUTLS_CLIENT) { + CHECK_GNUTLS_DO( gnutls_session_get_data2(conn->cc_tls_para.session, &master_data), return ENOMEM ); + /* For debug: */ + if (TRACE_BOOL(GNUTLS_DBG_LEVEL)) { + uint8_t id[256]; + size_t ids = sizeof(id); + CHECK_GNUTLS_DO( gnutls_session_get_id(conn->cc_tls_para.session, id, &ids), /* continue */ ); + TRACE_BUFFER(FD_LOG_DEBUG, GNUTLS_DBG_LEVEL, "Master session id: [", id, ids, "]"); + } + } + + /* Initialize the session objects and start the handshake in a separate thread */ + for (i = 1; i < conn->cc_sctp_para.pairs; i++) { + /* Set credentials and priority */ + CHECK_FCT( fd_tls_prepare(&conn->cc_sctp3436_data.array[i].session, conn->cc_tls_para.mode, 0, priority, alt_creds) ); + + /* additional initialization for gnutls 3.x */ + #ifdef GNUTLS_VERSION_300 + /* the verify function has already been set in the global initialization in config.c */ + + /* fd_tls_verify_credentials_2 uses the connection */ + gnutls_session_set_ptr (conn->cc_sctp3436_data.array[i].session, (void *) conn); + + if ((conn->cc_tls_para.cn != NULL) && (conn->cc_tls_para.mode == GNUTLS_CLIENT)) { + /* this might allow virtual hosting on the remote peer */ + CHECK_GNUTLS_DO( gnutls_server_name_set (conn->cc_sctp3436_data.array[i].session, GNUTLS_NAME_DNS, conn->cc_tls_para.cn, strlen(conn->cc_tls_para.cn)), /* ignore failure */); + } + + #endif /* GNUTLS_VERSION_300 */ + + #ifdef GNUTLS_VERSION_310 + GNUTLS_TRACE( gnutls_handshake_set_timeout( conn->cc_sctp3436_data.array[i].session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT)); + #endif /* GNUTLS_VERSION_310 */ + + /* For the client, copy data from master session; for the server, set session resuming pointers */ + if (conn->cc_tls_para.mode == GNUTLS_CLIENT) { + CHECK_GNUTLS_DO( gnutls_session_set_data(conn->cc_sctp3436_data.array[i].session, master_data.data, master_data.size), return ENOMEM ); + } else { + set_resume_callbacks(conn->cc_sctp3436_data.array[i].session, conn); + } + + /* Set transport parameters */ + set_sess_transport(conn->cc_sctp3436_data.array[i].session, &conn->cc_sctp3436_data.array[i]); + + /* Start the handshake thread */ + CHECK_POSIX( pthread_create( &conn->cc_sctp3436_data.array[i].thr, NULL, handshake_resume_th, &conn->cc_sctp3436_data.array[i] ) ); + } + + /* We can now release the memory of master session data if any */ + if (conn->cc_tls_para.mode == GNUTLS_CLIENT) { + GNUTLS_TRACE( gnutls_free(master_data.data) ); + } + + /* Now wait for all handshakes to finish */ + for (i = 1; i < conn->cc_sctp_para.pairs; i++) { + void * ret; + CHECK_POSIX( pthread_join(conn->cc_sctp3436_data.array[i].thr, &ret) ); + conn->cc_sctp3436_data.array[i].thr = (pthread_t) NULL; + if (ret == NULL) { + errors++; /* Handshake failed on this stream */ + } + } + + if (errors) { + TRACE_DEBUG(INFO, "Handshake failed on %d/%hd stream pairs", errors, conn->cc_sctp_para.pairs); + fd_cnx_markerror(conn); + return ENOTCONN; + } + + return 0; +} + +/* Receive messages from others ? all other stream pairs : the master pair */ +int fd_sctp3436_startthreads(struct cnxctx * conn, int others) +{ + uint16_t i; + + TRACE_ENTRY("%p", conn); + CHECK_PARAMS( conn && conn->cc_sctp3436_data.array ); + + if (others) { + for (i = 1; i < conn->cc_sctp_para.pairs; i++) { + + /* Start the decipher thread */ + CHECK_POSIX( pthread_create( &conn->cc_sctp3436_data.array[i].thr, NULL, decipher, &conn->cc_sctp3436_data.array[i] ) ); + } + } else { + CHECK_POSIX( pthread_create( &conn->cc_sctp3436_data.array[0].thr, NULL, decipher, &conn->cc_sctp3436_data.array[0] ) ); + } + return 0; +} + +/* Initiate a "bye" on all stream pairs */ +void fd_sctp3436_bye(struct cnxctx * conn) +{ + uint16_t i; + + CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return ); + + /* End all TLS sessions, in series (not as efficient as paralel, but simpler) */ + for (i = 1; i < conn->cc_sctp_para.pairs; i++) { + if ( ! fd_cnx_teststate(conn, CC_STATUS_ERROR)) { + CHECK_GNUTLS_DO( gnutls_bye(conn->cc_sctp3436_data.array[i].session, GNUTLS_SHUT_WR), fd_cnx_markerror(conn) ); + } + } +} + +/* After "bye" was sent on all streams, read from sessions until an error is received */ +void fd_sctp3436_waitthreadsterm(struct cnxctx * conn) +{ + uint16_t i; + + TRACE_ENTRY("%p", conn); + CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return ); + + for (i = 0; i < conn->cc_sctp_para.pairs; i++) { + if (conn->cc_sctp3436_data.array[i].thr != (pthread_t)NULL) { + CHECK_POSIX_DO( pthread_join(conn->cc_sctp3436_data.array[i].thr, NULL), /* continue */ ); + conn->cc_sctp3436_data.array[i].thr = (pthread_t)NULL; + } + } + return; +} + +/* Free gnutls resources of all sessions */ +void fd_sctp3436_gnutls_deinit_others(struct cnxctx * conn) +{ + uint16_t i; + + TRACE_ENTRY("%p", conn); + CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return ); + + for (i = 1; i < conn->cc_sctp_para.pairs; i++) { + if (conn->cc_sctp3436_data.array[i].session) { + GNUTLS_TRACE( gnutls_deinit(conn->cc_sctp3436_data.array[i].session) ); + conn->cc_sctp3436_data.array[i].session = NULL; + } + } +} + + +/* Stop all receiver threads */ +void fd_sctp3436_stopthreads(struct cnxctx * conn) +{ + uint16_t i; + + TRACE_ENTRY("%p", conn); + CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return ); + + for (i = 0; i < conn->cc_sctp_para.pairs; i++) { + CHECK_FCT_DO( fd_thr_term(&conn->cc_sctp3436_data.array[i].thr), /* continue */ ); + } + return; +} + +/* Destroy a wrapper context */ +void fd_sctp3436_destroy(struct cnxctx * conn) +{ + uint16_t i; + + CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return ); + + /* Terminate all receiving threads in case we did not do it yet */ + fd_sctp3436_stopthreads(conn); + + /* Now, stop the demux thread */ + CHECK_FCT_DO( fd_thr_term(&conn->cc_rcvthr), /* continue */ ); + + /* Free remaining data in the array */ + for (i = 0; i < conn->cc_sctp_para.pairs; i++) { + if (conn->cc_sctp3436_data.array[i].raw_recv) + fd_event_destroy( &conn->cc_sctp3436_data.array[i].raw_recv, free ); + free(conn->cc_sctp3436_data.array[i].partial.buf); + if (conn->cc_sctp3436_data.array[i].session) { + GNUTLS_TRACE( gnutls_deinit(conn->cc_sctp3436_data.array[i].session) ); + conn->cc_sctp3436_data.array[i].session = NULL; + } + } + + /* Free the array itself now */ + free(conn->cc_sctp3436_data.array); + conn->cc_sctp3436_data.array = NULL; + + /* Delete the store of sessions */ + store_destroy(conn); + + return ; +} diff --git a/plat/diameter/libfdcore/server.c b/plat/diameter/libfdcore/server.c new file mode 100644 index 0000000..7f971a8 --- /dev/null +++ b/plat/diameter/libfdcore/server.c @@ -0,0 +1,509 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* Server (listening) part of the framework */ + +static struct fd_list FD_SERVERS = FD_LIST_INITIALIZER(FD_SERVERS); /* The list of all server objects */ +/* We don't need to protect this list, it is only accessed from the main framework thread. */ + +enum s_state { + NOT_CREATED=0, + RUNNING, + TERMINATED, + ERROR /* an error occurred, this is not a valid status */ +}; + +/* Servers information */ +struct server { + struct fd_list chain; /* link in the FD_SERVERS list */ + + struct cnxctx * conn; /* server connection context (listening socket) */ + int proto; /* IPPROTO_TCP or IPPROTO_SCTP */ + int secur; /* TLS is started immediatly after connection ? 0: no; 1: RFU; 2: yes (TLS/TCP or TLS/SCTP) */ + + pthread_t thr; /* The thread waiting for new connections (will store the data in the clients fifo) */ + enum s_state state; /* state of the thread */ + + struct fifo *pending; /* FIFO of struct cnxctx */ + struct pool_workers { + struct server * s; /* pointer to the parent server structure */ + int id; /* The worker id for logs */ + pthread_t worker; /* The thread */ + } *workers; /* array of cnf_thr_srv items */ +}; + + +/* Micro functions to read/change the status thread-safely */ +static pthread_mutex_t s_lock = PTHREAD_MUTEX_INITIALIZER; +static enum s_state get_status(struct server * s) +{ + enum s_state r; + CHECK_POSIX_DO( pthread_mutex_lock(&s_lock), return ERROR ); + r = s->state; + CHECK_POSIX_DO( pthread_mutex_unlock(&s_lock), return ERROR ); + return r; +} +static void set_status(struct server * s, enum s_state st) +{ + CHECK_POSIX_DO( pthread_mutex_lock(&s_lock), return ); + s->state = st; + CHECK_POSIX_DO( pthread_mutex_unlock(&s_lock), return ); +} + + +/* dump one item of the server->pending fifo */ +static DECLARE_FD_DUMP_PROTOTYPE(dump_cnx, void * item) { + struct cnxctx * c = item; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " '%s'", fd_cnx_getid(c)), return NULL); + return *buf; +} + +/* Dump all servers information */ +DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump, int details) +{ + struct fd_list * li; + + FD_DUMP_HANDLE_OFFSET(); + + for (li = FD_SERVERS.next; li != &FD_SERVERS; li = li->next) { + struct server * s = (struct server *)li; + enum s_state st = get_status(s); + + if (details) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s(%d), %s", s, fd_cnx_getid(s->conn), + IPPROTO_NAME( s->proto ), + s->secur ? "Secur" : "NotSecur", s->secur, + (st == NOT_CREATED) ? "Thread not created" : + ((st == RUNNING) ? "Thread running" : + ((st == TERMINATED) ? "Thread terminated" : + "Thread status unknown"))), return NULL); + /* Dump the client list of this server */ + CHECK_MALLOC_DO( fd_fifo_dump(FD_DUMP_STD_PARAMS, "pending connections", s->pending, dump_cnx), return NULL ); + + if (li->next != &FD_SERVERS) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); + } + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%s,%s) ", fd_cnx_getid(s->conn), + IPPROTO_NAME( s->proto ), s->secur ? "Secur" : "NotSecur"), return NULL); + } + } + + return *buf; +} + + +/* The thread in the pool for handling new clients connecting to a server */ +static void * client_worker(void * arg) +{ + struct pool_workers * pw = arg; + struct server * s = pw->s; + struct cnxctx * c = NULL; + int fatal = 0; + struct timespec ts; + struct fd_cnx_rcvdata rcv_data; + struct fd_msg_pmdl * pmdl = NULL; + struct msg * msg = NULL; + struct msg_hdr *hdr = NULL; + struct fd_pei pei; + + TRACE_ENTRY("%p", arg); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Worker#%d[%s%s]", pw->id, IPPROTO_NAME(s->proto), s->secur?", Sec" : ""); + fd_log_threadname ( buf ); + } + + /* Loop until canceled / error */ +next_client: + LOG_A("Ready to process next incoming connection"); + + memset(&rcv_data, 0, sizeof(rcv_data)); + + /* Get the next connection */ + CHECK_FCT_DO( fd_fifo_get( s->pending, &c ), { fatal = 1; goto cleanup; } ); + + /* Handshake if we are a secure server port, or start clear otherwise */ + if (s->secur) { + LOG_D("Starting handshake with %s", fd_cnx_getid(c)); + + int ret = fd_cnx_handshake(c, GNUTLS_SERVER, (s->secur == 1) ? ALGO_HANDSHAKE_DEFAULT : ALGO_HANDSHAKE_3436, NULL, NULL); + if (ret != 0) { + char buf[1024]; + snprintf(buf, sizeof(buf), "TLS handshake failed for connection '%s', connection closed.", fd_cnx_getid(c)); + + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); + + goto cleanup; + } + } else { + CHECK_FCT_DO( fd_cnx_start_clear(c, 0), goto cleanup ); + } + + /* Set the timeout to receive the first message */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), { fatal = 1; goto cleanup; } ); + ts.tv_sec += INCNX_TIMEOUT; + + /* Receive the first Diameter message on the connection -- cleanup in case of timeout */ + CHECK_FCT_DO( fd_cnx_receive(c, &ts, &rcv_data.buffer, &rcv_data.length), + { + char buf[1024]; + + switch (__ret__) { + case ETIMEDOUT: + snprintf(buf, sizeof(buf), "Client '%s' did not send CER within %ds, connection aborted.", fd_cnx_getid(c), INCNX_TIMEOUT); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); + break; + + case ENOTCONN: + snprintf(buf, sizeof(buf), "Connection from '%s' in error before CER was received.", fd_cnx_getid(c)); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); + break; + + default: + snprintf(buf, sizeof(buf), "Connection from '%s': unspecified error, connection aborted.", fd_cnx_getid(c)); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); + } + goto cleanup; + } ); + + TRACE_DEBUG(FULL, "Received %zdb from new client '%s'", rcv_data.length, fd_cnx_getid(c)); + + pmdl = fd_msg_pmdl_get_inbuf(rcv_data.buffer, rcv_data.length); + + /* Try parsing this message */ + CHECK_FCT_DO( fd_msg_parse_buffer( &rcv_data.buffer, rcv_data.length, &msg ), + { /* Parsing failed */ + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, NULL, NULL, &rcv_data, pmdl ); + goto cleanup; + } ); + + /* Log incoming message */ + fd_hook_associate(msg, pmdl); + fd_hook_call(HOOK_MESSAGE_RECEIVED, msg, NULL, fd_cnx_getid(c), fd_msg_pmdl_get(msg)); + + /* We expect a CER, it must parse with our dictionary and rules */ + CHECK_FCT_DO( fd_msg_parse_rules( msg, fd_g_config->cnf_dict, &pei ), + { /* Parsing failed -- trace details */ + char buf[1024]; + + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msg, NULL, pei.pei_message ?: pei.pei_errcode, fd_msg_pmdl_get(msg)); + + snprintf(buf, sizeof(buf), "Error parsing CER from '%s', connection aborted.", fd_cnx_getid(c)); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); + + goto cleanup; + } ); + + /* Now check we received a CER */ + CHECK_FCT_DO( fd_msg_hdr ( msg, &hdr ), { fatal = 1; goto cleanup; } ); + CHECK_PARAMS_DO( (hdr->msg_appl == 0) && (hdr->msg_flags & CMD_FLAG_REQUEST) && (hdr->msg_code == CC_CAPABILITIES_EXCHANGE), + { /* Parsing failed -- trace details */ + char buf[1024]; + snprintf(buf, sizeof(buf), "Expected CER from '%s', received a different message, connection aborted.", fd_cnx_getid(c)); + fd_hook_call(HOOK_PEER_CONNECT_FAILED, msg, NULL, buf, NULL); + goto cleanup; + } ); + + /* Finally, pass the information to the peers module which will handle it in a separate thread */ + pthread_cleanup_push((void *)fd_cnx_destroy, c); + pthread_cleanup_push((void *)fd_msg_free, msg); + CHECK_FCT_DO( fd_peer_handle_newCER( &msg, &c ), ); + pthread_cleanup_pop(0); + pthread_cleanup_pop(0); + +cleanup: + /* Cleanup the parsed message if any */ + if (msg) { + CHECK_FCT_DO( fd_msg_free(msg), /* continue */); + msg = NULL; + } + + /* Close the connection if needed */ + if (c != NULL) { + fd_cnx_destroy(c); + c = NULL; + } + + /* Cleanup the received buffer if any */ + free(rcv_data.buffer); + + + if (!fatal) + goto next_client; + + LOG_E("Worker thread exiting."); + return NULL; +} + +/* The thread managing a server */ +static void * serv_th(void * arg) +{ + struct server *s = (struct server *)arg; + + CHECK_PARAMS_DO(s, goto error); + fd_log_threadname ( fd_cnx_getid(s->conn) ); + + set_status(s, RUNNING); + + /* Accept incoming connections */ + CHECK_FCT_DO( fd_cnx_serv_listen(s->conn), goto error ); + + do { + struct cnxctx * conn = NULL; + + /* Wait for a new client or cancel */ + CHECK_MALLOC_DO( conn = fd_cnx_serv_accept(s->conn), break ); + + /* Store this connection in the fifo for processing by the worker pool. Will block when the fifo is full */ + pthread_cleanup_push((void *)fd_cnx_destroy, conn); + CHECK_FCT_DO( fd_fifo_post( s->pending, &conn ), break ); + pthread_cleanup_pop(0); + + } while (1); +error: + if (s) + set_status(s, TERMINATED); + + /* Send error signal to the core */ + LOG_F( "An error occurred in server module! Thread is terminating..."); + CHECK_FCT_DO(fd_core_shutdown(), ); + + return NULL; +} + + +/* Create a new server structure */ +static struct server * new_serv( int proto, int secur ) +{ + struct server * new; + int i; + + /* New server structure */ + CHECK_MALLOC_DO( new = malloc(sizeof(struct server)), return NULL ); + + memset(new, 0, sizeof(struct server)); + fd_list_init(&new->chain, new); + new->proto = proto; + new->secur = secur; + + CHECK_FCT_DO( fd_fifo_new(&new->pending, 5), return NULL); + CHECK_MALLOC_DO( new->workers = calloc( fd_g_config->cnf_thr_srv, sizeof(struct pool_workers) ), return NULL ); + + for (i = 0; i < fd_g_config->cnf_thr_srv; i++) { + /* Create the pool */ + new->workers[i].s = new; + new->workers[i].id = i; + CHECK_POSIX_DO( pthread_create( &new->workers[i].worker, NULL, client_worker, &new->workers[i]), return NULL ); + } + + return new; +} + +/* Start all the servers */ +int fd_servers_start() +{ + struct server * s; + + int empty_conf_ep = FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints); + + /* SCTP */ + if (!fd_g_config->cnf_flags.no_sctp) { +#ifdef DISABLE_SCTP + ASSERT(0); +#else /* DISABLE_SCTP */ + + /* Create the server on unsecure port */ + if (fd_g_config->cnf_port) { + CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 0) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port, empty_conf_ep ? NULL : &fd_g_config->cnf_endpoints) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + + /* Create the server on secure port */ + if (fd_g_config->cnf_port_tls) { + CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 2 /* Change when DTLS is introduced */) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_tls, empty_conf_ep ? NULL : &fd_g_config->cnf_endpoints) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + + /* Create the other server on 3436 secure port */ + /*if (fd_g_config->cnf_port_3436) { + CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 2) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_3436, empty_conf_ep ? NULL : &fd_g_config->cnf_endpoints) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + }*/ + +#endif /* DISABLE_SCTP */ + } + + /* TCP */ + if (!fd_g_config->cnf_flags.no_tcp) { + + if (empty_conf_ep) { + /* Bind TCP servers on [0.0.0.0] */ + if (!fd_g_config->cnf_flags.no_ip4) { + + if (fd_g_config->cnf_port) { + CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, AF_INET, NULL) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + + if (fd_g_config->cnf_port_tls) { + CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, AF_INET, NULL) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + } + + /* Bind TCP servers on [::] */ + if (!fd_g_config->cnf_flags.no_ip6) { + + if (fd_g_config->cnf_port) { + CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, AF_INET6, NULL) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + + if (fd_g_config->cnf_port_tls) { + CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, AF_INET6, NULL) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + } + } else { + /* Create all endpoints -- check flags */ + struct fd_list * li; + for (li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) { + struct fd_endpoint * ep = (struct fd_endpoint *)li; + sSA * sa = (sSA *) &ep->ss; + if (! (ep->flags & EP_FL_CONF)) + continue; + if (fd_g_config->cnf_flags.no_ip4 && (sa->sa_family == AF_INET)) + continue; + if (fd_g_config->cnf_flags.no_ip6 && (sa->sa_family == AF_INET6)) + continue; + + if (fd_g_config->cnf_port) { + CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, sa->sa_family, ep) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + + if (fd_g_config->cnf_port_tls) { + CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) ); + CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, sa->sa_family, ep) ); + fd_list_insert_before( &FD_SERVERS, &s->chain ); + CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); + } + } + } + } + + /* Now, if we had an empty list of local adresses (no address configured), try to read the real addresses from the kernel */ + if (empty_conf_ep) { + CHECK_FCT(fd_cnx_get_local_eps(&fd_g_config->cnf_endpoints)); + if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) { + TRACE_DEBUG(INFO, "Unable to find the address(es) of the local system. " + "Please use \"ListenOn\" parameter in the configuration. " + "This information is required to generate the CER/CEA messages."); + return EINVAL; + } + } + + { + char * buf = NULL; + size_t len = 0, offset = 0; + CHECK_MALLOC_DO( fd_dump_extend( &buf, &len, &offset , "Local server address(es): "), ); + CHECK_MALLOC_DO( fd_ep_dump( &buf, &len, &offset, 0, 0, &fd_g_config->cnf_endpoints ), ); + LOG_N("%s", buf ?: "Error dumping addresses"); + free(buf); + } + return 0; +} + +/* Terminate all the servers */ +int fd_servers_stop() +{ + TRACE_ENTRY(""); + + TRACE_DEBUG(INFO, "Shutting down server sockets..."); + + /* Loop on all servers */ + while (!FD_IS_LIST_EMPTY(&FD_SERVERS)) { + struct server * s = (struct server *)(FD_SERVERS.next); + int i; + struct cnxctx * c; + + /* cancel thread */ + CHECK_FCT_DO( fd_thr_term(&s->thr), /* continue */); + + /* destroy server connection context */ + fd_cnx_destroy(s->conn); + + /* cancel and destroy all worker threads */ + for (i = 0; i < fd_g_config->cnf_thr_srv; i++) { + /* Destroy worker thread */ + CHECK_FCT_DO( fd_thr_term(&s->workers[i].worker), /* continue */); + } + free(s->workers); + + /* Close any pending connection */ + while ( fd_fifo_tryget( s->pending, &c ) == 0 ) { + fd_cnx_destroy(c); + } + CHECK_FCT_DO( fd_fifo_del(&s->pending), ); + + /* Now destroy the server object */ + fd_list_unlink(&s->chain); + free(s); + } + + /* We're done! */ + return 0; +} diff --git a/plat/diameter/libfdcore/tcp.c b/plat/diameter/libfdcore/tcp.c new file mode 100644 index 0000000..266d05d --- /dev/null +++ b/plat/diameter/libfdcore/tcp.c @@ -0,0 +1,168 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" +#include "cnxctx.h" + +#include +#include +#include + +/* Set the socket options for TCP sockets, before bind is called */ +static int fd_tcp_setsockopt(int family, int sk) +{ + int ret = 0; + int opt; + + /* Clear the NODELAY option in case it was set, as requested by rfc3539#section-3.2 */ + /* Note that this is supposed to be the default, so we could probably remove this call ... */ + opt = 0; + ret = setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); + if (ret != 0) { + ret = errno; + TRACE_DEBUG(INFO, "Unable to set the socket TCP_NODELAY option: %s", strerror(ret)); + return ret; + } + + /* Under Linux, we may also set the TCP_CONGESTION option to one of the following strings: + - reno (default) + - bic + - cubic + - highspeed + - htcp + - hybla + - illinois + - lp + - scalable + - vegas + - veno + - westwood + - yeah + */ + + /* In case of v6 address, force the v6only option, we use a different socket for v4 */ + #ifdef IPV6_V6ONLY + if (family == AF_INET6) { + opt = 1; + CHECK_SYS(setsockopt(sk, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt))); + } + #endif /* IPV6_V6ONLY */ + + { + opt = 1; + CHECK_SYS( setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) ); + } + + /* There are also others sockopt that can be set, but nothing useful for us AFAICT */ + + return 0; +} + +/* Create a socket server and bind it */ +int fd_tcp_create_bind_server( int * sock, sSA * sa, socklen_t salen ) +{ + TRACE_ENTRY("%p %p %d", sock, sa, salen); + + CHECK_PARAMS( sock && sa ); + + /* Create the socket */ + CHECK_SYS( *sock = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP) ); + + /* Set the socket options */ + CHECK_FCT( fd_tcp_setsockopt(sa->sa_family, *sock) ); + + /* Bind the socket */ + CHECK_SYS( bind( *sock, sa, salen ) ); + + /* We're done */ + return 0; +} + +/* Allow clients connections on server sockets */ +int fd_tcp_listen( int sock ) +{ + TRACE_ENTRY("%d", sock); + CHECK_SYS( listen(sock, 5) ); + return 0; +} + +/* Create a client socket and connect to remote server */ +int fd_tcp_client( int *sock, sSA * sa, socklen_t salen ) +{ + int ret = 0; + int s; + + TRACE_ENTRY("%p %p %d", sock, sa, salen); + CHECK_PARAMS( sock && (*sock <= 0) && sa && salen ); + + /* Create the socket */ + CHECK_SYS( s = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP) ); + + /* Set the socket options */ + CHECK_FCT( fd_tcp_setsockopt(sa->sa_family, s) ); + + /* Cleanup if we are cancelled */ + pthread_cleanup_push(fd_cleanup_socket, &s); + + /* Try connecting to the remote address */ + ret = connect(s, sa, salen); + + pthread_cleanup_pop(0); + + if (ret < 0) { + ret = errno; + LOG_A( "connect returned an error: %s", strerror(ret)); + CHECK_SYS_DO( close(s), /* continue */ ); + *sock = -1; + return ret; + } + + /* Done! */ + *sock = s; + return ret; +} + +/* Get the remote name of a TCP socket */ +int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl) +{ + TRACE_ENTRY("%d %p %p", sock, ss, sl); + CHECK_PARAMS( ss && sl ); + + *sl = sizeof(sSS); + CHECK_SYS(getpeername(sock, (sSA *)ss, sl)); + + return 0; +} + diff --git a/plat/diameter/libfdcore/version.c b/plat/diameter/libfdcore/version.c new file mode 100644 index 0000000..ace6ea0 --- /dev/null +++ b/plat/diameter/libfdcore/version.c @@ -0,0 +1,47 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include +#include "version.h" + +#ifdef FD_PROJECT_VERSION_HG +# define FD_LIBFDCORE_VERSION \ + _stringize(FD_PROJECT_VERSION_MAJOR) "." _stringize(FD_PROJECT_VERSION_MINOR) "." _stringize(FD_PROJECT_VERSION_REV) "-" FD_PROJECT_VERSION_HG_VAL +#else +# define FD_LIBFDCORE_VERSION \ + _stringize(FD_PROJECT_VERSION_MAJOR) "." _stringize(FD_PROJECT_VERSION_MINOR) "." _stringize(FD_PROJECT_VERSION_REV) +#endif + +const char fd_core_version[] = FD_LIBFDCORE_VERSION; diff --git a/plat/diameter/libfdcore/version.h b/plat/diameter/libfdcore/version.h new file mode 100644 index 0000000..0e4acd8 --- /dev/null +++ b/plat/diameter/libfdcore/version.h @@ -0,0 +1,3 @@ +/* Following variable is expended at build time based on the result of "hg id" command */ +#define FD_PROJECT_VERSION_HG +#define FD_PROJECT_VERSION_HG_VAL "1304(5a505af0bba0)" diff --git a/plat/diameter/libfdproto/dictionary.c b/plat/diameter/libfdproto/dictionary.c new file mode 100644 index 0000000..b7d1e89 --- /dev/null +++ b/plat/diameter/libfdproto/dictionary.c @@ -0,0 +1,2347 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" +#include + +/* Names of the base types */ +const char * type_base_name[] = { /* must keep in sync with dict_avp_basetype */ + "GROUPED", /* AVP_TYPE_GROUPED */ + "OCTETSTRING", /* AVP_TYPE_OCTETSTRING */ + "INTEGER32", /* AVP_TYPE_INTEGER32 */ + "INTEGER64", /* AVP_TYPE_INTEGER64 */ + "UNSIGNED32", /* AVP_TYPE_UNSIGNED32 */ + "UNSIGNED64", /* AVP_TYPE_UNSIGNED64 */ + "FLOAT32", /* AVP_TYPE_FLOAT32 */ + "FLOAT64" /* AVP_TYPE_FLOAT64 */ + }; + +/* The number of lists in an object */ +#define NB_LISTS_PER_OBJ 3 + +/* Some eye catchers definitions */ +#define OBJECT_EYECATCHER (0x0b13c7) +#define DICT_EYECATCHER (0x00d1c7) + +/* Definition of the dictionary objects */ +struct dict_object { + enum dict_object_type type; /* What type of object is this? */ + int objeyec;/* eyecatcher for this object */ + int typeyec;/* eyecatcher for this type of object */ + struct dictionary *dico; /* The dictionary this object belongs to */ + + union { + struct dict_vendor_data vendor; /* datastr_len = strlen(vendor_name) */ + struct dict_application_data application; /* datastr_len = strlen(application_name) */ + struct dict_type_data type; /* datastr_len = strlen(type_name) */ + struct dict_enumval_data enumval; /* datastr_len = strlen(enum_name) */ + struct dict_avp_data avp; /* datastr_len = strlen(avp_name) */ + struct dict_cmd_data cmd; /* datastr_len = strlen(cmd_name) */ + struct dict_rule_data rule; /* datastr_len = 0 */ + } data; /* The data of this object */ + + size_t datastr_len; /* cached length of the string inside the data. Saved when the object is created. */ + + struct dict_object * parent; /* The parent of this object, if any */ + + struct fd_list list[NB_LISTS_PER_OBJ];/* used to chain objects.*/ + /* More information about the lists : + + - the use for each list depends on the type of object. See detail below. + + - a sentinel for a list has its 'o' field cleared. (this is the criteria to detect end of a loop) + + - The lists are always ordered. The criteria are described below. the functions to order them are referenced in dict_obj_info + + - The dict_lock must be held for any list operation. + + => VENDORS: + list[0]: list of the vendors, ordered by their id. The sentinel is g_dict_vendors (vendor with id 0) + list[1]: sentinel for the list of AVPs from this vendor, ordered by AVP code. + list[2]: sentinel for the list of AVPs from this vendor, ordered by AVP name (fd_os_cmp). + + => APPLICATIONS: + list[0]: list of the applications, ordered by their id. The sentinel is g_dict_applications (application with id 0) + list[1]: not used + list[2]: not used. + + => TYPES: + list[0]: list of the types, ordered by their names. The sentinel is g_list_types. + list[1]: sentinel for the type_enum list of this type, ordered by their constant name (fd_os_cmp). + list[2]: sentinel for the type_enum list of this type, ordered by their constant value. + + => TYPE_ENUMS: + list[0]: list of the contants for a given type, ordered by the constant name (fd_os_cmp). Sentinel is a (list[1]) element of a TYPE object. + list[1]: list of the contants for a given type, ordered by the constant value. Sentinel is a (list[2]) element of a TYPE object. + list[2]: not used + + => AVPS: + list[0]: list of the AVP from a given vendor, ordered by avp code. Sentinel is a list[1] element of a VENDOR object. + list[1]: list of the AVP from a given vendor, ordered by avp name (fd_os_cmp). Sentinel is a list[2] element of a VENDOR object. + list[2]: sentinel for the rule list that apply to this AVP. + + => COMMANDS: + list[0]: list of the commands, ordered by their names (fd_os_cmp). The sentinel is g_list_cmd_name. + list[1]: list of the commands, ordered by their command code and 'R' flag. The sentinel is g_list_cmd_code. + list[2]: sentinel for the rule list that apply to this command. + + => RULES: + list[0]: list of the rules for a given (grouped) AVP or Command, ordered by the AVP vendor & code to which they refer. sentinel is list[2] of a command or (grouped) avp. + list[1]: not used + list[2]: not used. + + */ + + /* Sentinel for the dispatch callbacks */ + struct fd_list disp_cbs; + +}; + +/* Definition of the dictionary structure */ +struct dictionary { + int dict_eyec; /* Eye-catcher for the dictionary (DICT_EYECATCHER) */ + + pthread_rwlock_t dict_lock; /* The global rwlock for the dictionary */ + + struct dict_object dict_vendors; /* Sentinel for the list of vendors, corresponding to vendor 0 */ + struct dict_object dict_applications; /* Sentinel for the list of applications, corresponding to app 0 */ + struct fd_list dict_types; /* Sentinel for the list of types */ + struct fd_list dict_cmd_name; /* Sentinel for the list of commands, ordered by names */ + struct fd_list dict_cmd_code; /* Sentinel for the list of commands, ordered by codes */ + + struct dict_object dict_cmd_error; /* Special command object for answers with the 'E' bit set */ + + int dict_count[DICT_TYPE_MAX + 1]; /* Number of objects of each type */ +}; + +/* Forward declarations of dump functions */ +static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ); +static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ); +static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ); + /* the dump function for enum has a different prototype since it need the datatype */ +static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ); +static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ); +static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ); + +/* Forward declarations of search functions */ +static int search_vendor ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); +static int search_application ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); +static int search_type ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); +static int search_enumval ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); +static int search_avp ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); +static int search_cmd ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); +static int search_rule ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); + +/* The following array contains lot of data about the different types of objects, for automated handling */ +static struct { + enum dict_object_type type; /* information for this type */ + char * name; /* string describing this object, for debug */ + size_t datasize; /* The size of the data structure */ + int parent; /* 0: never; 1: may; 2: must */ + enum dict_object_type parenttype; /* The type of the parent, when relevant */ + int eyecatcher; /* A kind of signature for this object */ + DECLARE_FD_DUMP_PROTOTYPE( (*dump_data), void * data ); /* The function to dump the data section */ + int (*search_fct)(struct dictionary * dict, int criteria, const void * what, struct dict_object **result );; /* The function to search an object of this type */ + int haslist[NB_LISTS_PER_OBJ]; /* Tell if this list is used */ +} dict_obj_info[] = { { 0, "(error)", 0, 0, 0, 0, NULL, NULL, {0, 0, 0} } + + /* type name datasize parent parenttype + eyecatcher dump_data search_fct, haslist[] */ + + ,{ DICT_VENDOR, "VENDOR", sizeof(struct dict_vendor_data), 0, 0, + OBJECT_EYECATCHER + 1, dump_vendor_data, search_vendor, { 1, 0, 0 } } + + ,{ DICT_APPLICATION, "APPLICATION", sizeof(struct dict_application_data), 1, DICT_VENDOR, + OBJECT_EYECATCHER + 2, dump_application_data, search_application, { 1, 0, 0 } } + + ,{ DICT_TYPE, "TYPE", sizeof(struct dict_type_data), 1, DICT_APPLICATION, + OBJECT_EYECATCHER + 3, dump_type_data, search_type, { 1, 0, 0 } } + + ,{ DICT_ENUMVAL, "ENUMVAL", sizeof(struct dict_enumval_data), 2, DICT_TYPE, + OBJECT_EYECATCHER + 4, NULL, search_enumval, { 1, 1, 0 } } + + ,{ DICT_AVP, "AVP", sizeof(struct dict_avp_data), 1, DICT_TYPE, + OBJECT_EYECATCHER + 5, dump_avp_data, search_avp, { 1, 1, 0 } } + + ,{ DICT_COMMAND, "COMMAND", sizeof(struct dict_cmd_data), 1, DICT_APPLICATION, + OBJECT_EYECATCHER + 6, dump_command_data, search_cmd, { 1, 1, 0 } } + + ,{ DICT_RULE, "RULE", sizeof(struct dict_rule_data), 2, -1 /* special case: grouped avp or command */, + OBJECT_EYECATCHER + 7, dump_rule_data, search_rule, { 1, 0, 0 } } + +}; + +/* Macro to verify a "type" value */ +#define CHECK_TYPE( type ) ( ((type) > 0) && ((type) <= DICT_TYPE_MAX) ) + +/* Cast macro */ +#define _O( object ) ((struct dict_object *) (object)) + +/* Get information line for a given object */ +#define _OBINFO(object) (dict_obj_info[CHECK_TYPE(_O(object)->type) ? _O(object)->type : 0]) + + + + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* */ +/* Objects management */ +/* */ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/* Functions to manage the objects creation and destruction. */ + +/* Duplicate a string inplace, save its length */ +#define DUP_string_len( str, plen ) { \ + *(plen) = strlen((str)); \ + str = os0dup( str, *(plen)); \ +} + +/* Initialize an object */ +static void init_object( struct dict_object * obj, enum dict_object_type type ) +{ + int i; + + TRACE_ENTRY("%p %d", obj, type); + + /* Clean the object first */ + memset ( obj, 0, sizeof(struct dict_object)); + + CHECK_PARAMS_DO( CHECK_TYPE(type), return ); + + obj->type = type; + obj->objeyec = OBJECT_EYECATCHER; + obj->typeyec = _OBINFO(obj).eyecatcher; + + /* We don't initialize the data nor the parent here */ + + /* Now init the lists */ + for (i=0; ilist[i], obj); + else + fd_list_init(&obj->list[i], NULL); + } + + fd_list_init(&obj->disp_cbs, NULL); +} + +/* Initialize the "data" part of an object */ +static int init_object_data(struct dict_object * dest, void * source, enum dict_object_type type) +{ + TRACE_ENTRY("%p %p %d", dest, source, type); + CHECK_PARAMS( dest && source && CHECK_TYPE(type) ); + + /* Generic: copy the full data structure */ + memcpy( &dest->data, source, dict_obj_info[type].datasize ); + + /* Then strings must be duplicated, not copied */ + /* This function might be simplified by always defining the "name" field as the first field of the structures, but... it's error-prone */ + switch (type) { + case DICT_VENDOR: + DUP_string_len( dest->data.vendor.vendor_name, &dest->datastr_len ); + break; + + case DICT_APPLICATION: + DUP_string_len( dest->data.application.application_name, &dest->datastr_len ); + break; + + case DICT_TYPE: + DUP_string_len( dest->data.type.type_name, &dest->datastr_len ); + break; + + case DICT_ENUMVAL: + DUP_string_len( dest->data.enumval.enum_name, &dest->datastr_len ); + break; + + case DICT_AVP: + DUP_string_len( dest->data.avp.avp_name, &dest->datastr_len ); + break; + + case DICT_COMMAND: + DUP_string_len( dest->data.cmd.cmd_name, &dest->datastr_len ); + break; + + default: + /* Nothing to do for RULES */ + ; + } + + return 0; +} + +/* Check that an object is valid (1: OK, 0: error) */ +static int verify_object( struct dict_object * obj ) +{ + TRACE_ENTRY("%p", obj); + + CHECK_PARAMS_DO( obj + && (obj->objeyec == OBJECT_EYECATCHER) + && CHECK_TYPE(obj->type) + && (obj->typeyec == dict_obj_info[obj->type].eyecatcher), + { + if (obj) { + TRACE_DEBUG(FULL, "Invalid object: %p, obj->objeyec: %x/%x, obj->type: %d, obj->objeyec: %x/%x, obj->typeyec: %x/%x", + obj, + obj->objeyec, OBJECT_EYECATCHER, + obj->type, + obj->objeyec, OBJECT_EYECATCHER, + obj->typeyec, _OBINFO(obj).eyecatcher); + } else { + TRACE_DEBUG(FULL, "Invalid object : NULL pointer"); + } + return 0; + } ); + + /* The object is probably valid. */ + return 1; +} + +/* Free the data associated to an object */ +static void destroy_object_data(struct dict_object * obj) +{ + /* TRACE_ENTRY("%p", obj); */ + + switch (obj->type) { + case DICT_VENDOR: + free( obj->data.vendor.vendor_name ); + break; + + case DICT_APPLICATION: + free( obj->data.application.application_name ); + break; + + case DICT_TYPE: + free( obj->data.type.type_name ); + break; + + case DICT_ENUMVAL: + free( obj->data.enumval.enum_name ); + break; + + case DICT_AVP: + free( obj->data.avp.avp_name ); + break; + + case DICT_COMMAND: + free( obj->data.cmd.cmd_name ); + break; + + default: + /* nothing to do */ + ; + } +} + +/* Forward declaration */ +static void destroy_object(struct dict_object * obj); + +/* Destroy all objects in a list - the lock must be held */ +static void destroy_list(struct fd_list * head) +{ + /* TRACE_ENTRY("%p", head); */ + + /* loop in the list */ + while (!FD_IS_LIST_EMPTY(head)) + { + /* When destroying the object, it is unlinked from the list */ + destroy_object(_O(head->next->o)); + } +} + +/* Free an object and its sublists */ +static void destroy_object(struct dict_object * obj) +{ + int i; + + /* TRACE_ENTRY("%p", obj); */ + + /* Update global count */ + if (obj->dico) + obj->dico->dict_count[obj->type]--; + + /* Mark the object as invalid */ + obj->objeyec = 0xdead; + + /* First, destroy the data associated to the object */ + destroy_object_data(obj); + + for (i=0; ilist[i] ); + else + /* This is either a sentinel or unused (=emtpy) list, let's destroy it */ + destroy_list( &obj->list[i] ); + } + + /* Unlink all elements from the dispatch list; they will be freed when callback is unregistered */ + CHECK_POSIX_DO( pthread_rwlock_wrlock(&fd_disp_lock), /* continue */ ); + while (!FD_IS_LIST_EMPTY(&obj->disp_cbs)) { + fd_list_unlink( obj->disp_cbs.next ); + } + CHECK_POSIX_DO( pthread_rwlock_unlock(&fd_disp_lock), /* continue */ ); + + /* Last, destroy the object */ + free(obj); +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* */ +/* Compare functions */ +/* */ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/* Compare two values */ +#define ORDER_scalar( i1, i2 ) \ + ((i1 < i2 ) ? -1 : ( i1 > i2 ? 1 : 0 )) + + +/* Compare two vendor objects by their id (checks already performed) */ +static int order_vendor_by_id ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + // LOG_D("O1O2Vend[ID]=[%d] [%d]", o1->data.vendor.vendor_id, o1->data.vendor.vendor_id); + + return ORDER_scalar( o1->data.vendor.vendor_id, o2->data.vendor.vendor_id ); +} + +/* Compare two application objects by their id (checks already performed) */ +static int order_appli_by_id ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + + return ORDER_scalar( o1->data.application.application_id, o2->data.application.application_id ); +} + +/* Compare two type objects by their name (checks already performed) */ +static int order_type_by_name ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + // LOG_D("order_type_by_name o1o2[%s,%s]", o1->data.type.type_name, o1->data.type.type_name); + return fd_os_cmp( o1->data.type.type_name, o1->datastr_len, o2->data.type.type_name, o2->datastr_len ); +} + +/* Compare two type_enum objects by their names (checks already performed) */ +static int order_enum_by_name ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + // LOG_D("order_enum o1o2[%s,%s]", o1->data.enumval.enum_name, o2->data.enumval.enum_name); + return fd_os_cmp( o1->data.enumval.enum_name, o1->datastr_len, o2->data.enumval.enum_name, o2->datastr_len ); +} + +/* Compare two type_enum objects by their values (checks already performed) */ +static int order_enum_by_val ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + + /* The comparison function depends on the type of data */ + switch ( o1->parent->data.type.type_base ) { + case AVP_TYPE_OCTETSTRING: + return fd_os_cmp( o1->data.enumval.enum_value.os.data, o1->data.enumval.enum_value.os.len, + o2->data.enumval.enum_value.os.data, o2->data.enumval.enum_value.os.len); + + case AVP_TYPE_INTEGER32: + return ORDER_scalar( o1->data.enumval.enum_value.i32, o2->data.enumval.enum_value.i32 ); + + case AVP_TYPE_INTEGER64: + return ORDER_scalar( o1->data.enumval.enum_value.i64, o2->data.enumval.enum_value.i64 ); + + case AVP_TYPE_UNSIGNED32: + return ORDER_scalar( o1->data.enumval.enum_value.u32, o2->data.enumval.enum_value.u32 ); + + case AVP_TYPE_UNSIGNED64: + return ORDER_scalar( o1->data.enumval.enum_value.u64, o2->data.enumval.enum_value.u64 ); + + case AVP_TYPE_FLOAT32: + return ORDER_scalar( o1->data.enumval.enum_value.f32, o2->data.enumval.enum_value.f32 ); + + case AVP_TYPE_FLOAT64: + return ORDER_scalar( o1->data.enumval.enum_value.f64, o2->data.enumval.enum_value.f64 ); + + case AVP_TYPE_GROUPED: + default: + ASSERT(0); + } + return 0; +} + +/* Compare two avp objects by their codes (checks already performed) */ +static int order_avp_by_code ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + + // LOG_D("O1O2AVP[Code]=[%d] [%d]", o1->data.avp.avp_code, o2->data.avp.avp_code); + + return ORDER_scalar( o1->data.avp.avp_code, o2->data.avp.avp_code ); +} + +/* Compare two avp objects by their names (checks already performed) */ +static int order_avp_by_name ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + + // LOG_D("O1O2AVP[Name]=[%s] [%s]", o1->data.avp.avp_name, o2->data.avp.avp_name); + + return fd_os_cmp( o1->data.avp.avp_name, o1->datastr_len, o2->data.avp.avp_name, o2->datastr_len ); +} + +/* Compare two command objects by their names (checks already performed) */ +static int order_cmd_by_name ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + + return fd_os_cmp( o1->data.cmd.cmd_name, o1->datastr_len, o2->data.cmd.cmd_name, o2->datastr_len ); +} + +/* Compare two command objects by their codes and flags (request or answer) (checks already performed) */ +static int order_cmd_by_codefl( struct dict_object *o1, struct dict_object *o2 ) +{ + uint8_t fl1, fl2; + int cmp = 0; + + TRACE_ENTRY("%p %p", o1, o2); + + cmp = ORDER_scalar( o1->data.cmd.cmd_code, o2->data.cmd.cmd_code ); + if (cmp) + return cmp; + + /* Same command code, we must compare the value of the 'R' flag */ + fl1 = o1->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST; + fl2 = o2->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST; + + /* We want requests first, so we reverse the operators here */ + return ORDER_scalar(fl2, fl1); + +} + +/* Compare two rule object by the AVP vendor & code that they refer (checks already performed) */ +static int order_rule_by_avpvc ( struct dict_object *o1, struct dict_object *o2 ) +{ + TRACE_ENTRY("%p %p", o1, o2); + + return ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_vendor, o2->data.rule.rule_avp->data.avp.avp_vendor) + ?: ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_code, o2->data.rule.rule_avp->data.avp.avp_code) ; +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* */ +/* Search functions */ +/* */ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/* Functions used to search for objects in the lists, according to some criteria */ + +/* On a general note, if result is not NULL, ENOENT is not returned but *result is NULL. */ + +/* The following macros assume that "what", "ret", "result" (variables), and "end" (label) exist +in the local context where they are called. They are meant to be called only from the functions that follow. */ + +/* For searchs of type "xxx_OF_xxx": children's parent or default parent */ +#define SEARCH_childs_parent( type_of_child, default_parent ) { \ + struct dict_object *__child = (struct dict_object *) what; \ + CHECK_PARAMS_DO( verify_object(__child) && \ + (__child->type == (type_of_child)), \ + { ret = EINVAL; goto end; } ); \ + ret = 0; \ + if (result) \ + *result = (__child->parent ? __child->parent :(default_parent));\ +} + +void SEARCH_os0_l_(struct fd_list* sentinel ) { + struct fd_list * __li; + for (__li = (sentinel)->next; __li != (sentinel); __li = __li->next) { + } +} + +/* For search of strings in lists. isindex= 1 if the string is the ordering key of the list */ +/* it is expected that object->datastr_len is the length of the datafield parameter */ +#define SEARCH_os0_l( str, len, sentinel, datafield, isindex ) { \ + char * __str = (char *) (str); \ + size_t __strlen = (size_t)(len); \ + int __cmp; \ + struct fd_list * __li; \ + ret = 0; \ + for (__li = (sentinel)->next; __li != (sentinel); __li = __li->next) { \ + __cmp = fd_os_cmp(__str, __strlen, \ + _O(__li->o)->data. datafield, _O(__li->o)->datastr_len);\ + if (__cmp == 0) { \ + if (result) \ + *result = _O(__li->o); \ + goto end; \ + } \ + if ((isindex) && (__cmp < 0)){ \ + SEARCH_os0_l_(sentinel); \ + break; \ + } \ + } \ + if (result) \ + *result = NULL; \ + else \ + ret = ENOENT; \ +} + +/* When len is not provided */ +#define SEARCH_os0( str, sentinel, datafield, isindex ) { \ + char * _str = (char *) (str); \ + size_t _strlen = strlen(_str); \ + SEARCH_os0_l( _str, _strlen, sentinel, datafield, isindex ); \ +} + + +/* For search of octetstrings in lists. */ +#define SEARCH_os( str, strlen, sentinel, osdatafield, isindex ) { \ + uint8_t * __str = (uint8_t *) (str); \ + size_t __strlen = (size_t)(strlen); \ + int __cmp; \ + struct fd_list * __li; \ + ret = 0; \ + for (__li = (sentinel)->next; __li != (sentinel); __li = __li->next) { \ + __cmp = fd_os_cmp(__str, __strlen, \ + _O(__li->o)->data. osdatafield .data, \ + _O(__li->o)->data. osdatafield .len); \ + if (__cmp == 0) { \ + if (result) \ + *result = _O(__li->o); \ + goto end; \ + } \ + if ((isindex) && (__cmp < 0)) \ + break; \ + } \ + if (result) \ + *result = NULL; \ + else \ + ret = ENOENT; \ +} + +/* For search of AVP name in rule lists -- the list is not ordered by AVP names! */ +#define SEARCH_ruleavpname( str, strlen, sentinel ) { \ + char * __str = (char *) (str); \ + size_t __strlen = (size_t) (strlen); \ + int __cmp; \ + struct fd_list * __li; \ + ret = 0; \ + for (__li = (sentinel)->next; __li != (sentinel); __li = __li->next) { \ + __cmp = fd_os_cmp(__str, __strlen, \ + _O(__li->o)->data.rule.rule_avp->data.avp.avp_name, \ + _O(__li->o)->data.rule.rule_avp->datastr_len); \ + if (__cmp == 0) { \ + if (result) \ + *result = _O(__li->o); \ + goto end; \ + } \ + } \ + if (result) \ + *result = NULL; \ + else \ + ret = ENOENT; \ +} + +/* For search of scalars in lists. isindex= 1 if the value is the ordering key of the list */ +#define SEARCH_scalar( value, sentinel, datafield, isindex, defaultobj ) { \ + int __cmp; \ + struct fd_list * __li; \ + ret = 0; \ + if ( ((defaultobj) != NULL) \ + && (_O(defaultobj)->data. datafield == value)) { \ + if (result) \ + *result = _O(defaultobj); \ + goto end; \ + } \ + for (__li = (sentinel)->next; __li != (sentinel); __li = __li->next) { \ + __cmp= ORDER_scalar(value, _O(__li->o)->data. datafield ); \ + if (__cmp == 0) { \ + if (result) \ + *result = _O(__li->o); \ + goto end; \ + } \ + if ((isindex) && (__cmp < 0)) \ + break; \ + } \ + if (result) \ + *result = NULL; \ + else \ + ret = ENOENT; \ +} +void print_vend_id( struct dictionary * dict) { + struct fd_list * __li; + + for (__li = (&dict->dict_vendors.list[0])->next; ; __li = __li->next) + { + LOG_D("print vendID addr:%p id:%d",_O(__li->o), _O(__li->o)->data.vendor.vendor_id); + + if(__li == (&dict->dict_vendors.list[0]) ) + break; + } +} + +/* For search of commands in lists by code and flag. R_flag_val = 0 or CMD_FLAG_REQUEST */ +#define SEARCH_codefl( value, R_flag_val, sentinel) { \ + int __cmp; \ + struct fd_list * __li; \ + ret = 0; \ + for (__li = (sentinel)->next; __li != (sentinel); __li = __li->next) { \ + __cmp = ORDER_scalar(value, \ + _O(__li->o)->data.cmd.cmd_code ); \ + if (__cmp == 0) { \ + uint8_t __mask, __val; \ + __mask = _O(__li->o)->data.cmd.cmd_flag_mask; \ + __val = _O(__li->o)->data.cmd.cmd_flag_val; \ + if ( ! (__mask & CMD_FLAG_REQUEST) ) \ + continue; \ + if ( ( __val & CMD_FLAG_REQUEST ) != R_flag_val ) \ + continue; \ + if (result) \ + *result = _O(__li->o); \ + goto end; \ + } \ + if (__cmp < 0) \ + break; \ + } \ + if (result) \ + *result = NULL; \ + else \ + ret = ENOENT; \ +} + +/* For searchs of type "xxx_OF_xxx": if the search object is sentinel list for the "what" object */ +#define SEARCH_sentinel( type_of_what, what_list_nr, sentinel_list_nr ) { \ + struct dict_object *__what = (struct dict_object *) what; \ + CHECK_PARAMS_DO( verify_object(__what) && \ + (__what->type == (type_of_what)), \ + { ret = EINVAL; goto end; } ); \ + ret = 0; \ + if (result) { \ + /* this is similar to the "container_of" */ \ + *result = (struct dict_object *)((char *)(__what->list[what_list_nr].head) - \ + (size_t)&(((struct dict_object *)0)->list[sentinel_list_nr])); \ + } \ +} + + +static int search_vendor ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ) +{ + int ret = 0; + vendor_id_t id; + + TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result); + + switch (criteria) { + case VENDOR_BY_ID: + id = *(vendor_id_t *) what; + SEARCH_scalar( id, &dict->dict_vendors.list[0], vendor.vendor_id, 1, &dict->dict_vendors ); + break; + + case VENDOR_BY_NAME: + /* "what" is a vendor name */ + SEARCH_os0( what, &dict->dict_vendors.list[0], vendor.vendor_name, 0); + break; + + case VENDOR_OF_APPLICATION: + /* "what" should be an application object */ + SEARCH_childs_parent( DICT_APPLICATION, &dict->dict_vendors ); + break; + + case VENDOR_OF_AVP: + /* "what" should be an avp object */ + SEARCH_sentinel( DICT_AVP, 0, 1 ); + break; + + default: + /* Invalid criteria */ + CHECK_PARAMS( criteria = 0 ); + } +end: + return ret; +} + +static int search_application ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ) +{ + int ret = 0; + application_id_t id; + + TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result); + + switch (criteria) { + case APPLICATION_BY_ID: + id = *(application_id_t *) what; + + SEARCH_scalar( id, &dict->dict_applications.list[0], application.application_id, 1, &dict->dict_applications ); + break; + + case APPLICATION_BY_NAME: + /* "what" is an application name */ + SEARCH_os0( what, &dict->dict_applications.list[0], application.application_name, 0); + break; + + case APPLICATION_OF_TYPE: + /* "what" should be a type object */ + SEARCH_childs_parent( DICT_TYPE, &dict->dict_applications ); + break; + + case APPLICATION_OF_COMMAND: + /* "what" should be a command object */ + SEARCH_childs_parent( DICT_COMMAND, &dict->dict_applications ); + break; + + default: + /* Invalid criteria */ + CHECK_PARAMS( criteria = 0 ); + } +end: + return ret; +} + +static int search_type ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ) +{ + int ret = 0; + + TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result); + + switch (criteria) { + case TYPE_BY_NAME: + /* "what" is a type name */ + SEARCH_os0( what, &dict->dict_types, type.type_name, 1); + break; + + case TYPE_OF_ENUMVAL: + /* "what" should be a type_enum object */ + SEARCH_childs_parent( DICT_ENUMVAL, NULL ); + break; + + case TYPE_OF_AVP: + /* "what" should be an avp object */ + SEARCH_childs_parent( DICT_AVP, NULL ); + break; + + + default: + /* Invalid criteria */ + CHECK_PARAMS( criteria = 0 ); + } +end: + return ret; +} + +static int search_enumval ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ) +{ + int ret = 0; + + TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result); + + switch (criteria) { + case ENUMVAL_BY_STRUCT: + { + struct dict_object * parent = NULL; + struct dict_enumval_request * _what = (struct dict_enumval_request *) what; + + CHECK_PARAMS( _what && ( _what->type_obj || _what->type_name ) ); + + if (_what->type_obj != NULL) { + parent = _what->type_obj; + CHECK_PARAMS( verify_object(parent) && (parent->type == DICT_TYPE) ); + } else { + /* We received only the type name, we must find it first */ + CHECK_FCT_DO( search_type( dict, TYPE_BY_NAME, _what->type_name, &parent ), + CHECK_PARAMS( 0 ) ); + } + + /* From here the "parent" object is valid */ + + if ( _what->search.enum_name != NULL ) { + /* We are looking for this string */ + SEARCH_os0( _what->search.enum_name, &parent->list[1], enumval.enum_name, 1 ); + } else { + /* We are looking for the value in enum_value */ + switch (parent->data.type.type_base) { + case AVP_TYPE_OCTETSTRING: + SEARCH_os( _what->search.enum_value.os.data, + _what->search.enum_value.os.len, + &parent->list[2], + enumval.enum_value.os , + 1 ); + break; + + case AVP_TYPE_INTEGER32: + SEARCH_scalar( _what->search.enum_value.i32, + &parent->list[2], + enumval.enum_value.i32, + 1, + (struct dict_object *)NULL); + break; + + case AVP_TYPE_INTEGER64: + SEARCH_scalar( _what->search.enum_value.i64, + &parent->list[2], + enumval.enum_value.i64, + 1, + (struct dict_object *)NULL); + break; + + case AVP_TYPE_UNSIGNED32: + SEARCH_scalar( _what->search.enum_value.u32, + &parent->list[2], + enumval.enum_value.u32, + 1, + (struct dict_object *)NULL); + break; + + case AVP_TYPE_UNSIGNED64: + SEARCH_scalar( _what->search.enum_value.u64, + &parent->list[2], + enumval.enum_value.u64, + 1, + (struct dict_object *)NULL); + break; + + case AVP_TYPE_FLOAT32: + SEARCH_scalar( _what->search.enum_value.f32, + &parent->list[2], + enumval.enum_value.f32, + 1, + (struct dict_object *)NULL); + break; + + case AVP_TYPE_FLOAT64: + SEARCH_scalar( _what->search.enum_value.f64, + &parent->list[2], + enumval.enum_value.f64, + 1, + (struct dict_object *)NULL); + break; + + default: + /* Invalid parent type basetype */ + CHECK_PARAMS( parent = NULL ); + } + } + + } + break; + + + default: + /* Invalid criteria */ + CHECK_PARAMS( criteria = 0 ); + } +end: + return ret; +} + +static int search_avp ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ) +{ + int ret = 0; + + TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result); + + switch (criteria) { + case AVP_BY_CODE: + { + avp_code_t code; + code = *(avp_code_t *) what; + + SEARCH_scalar( code, &dict->dict_vendors.list[1], avp.avp_code, 1, (struct dict_object *)NULL ); + } + break; + + case AVP_BY_NAME: + /* "what" is the AVP name, vendor 0 */ + SEARCH_os0( what, &dict->dict_vendors.list[2], avp.avp_name, 1); + break; + + case AVP_BY_CODE_AND_VENDOR: + case AVP_BY_NAME_AND_VENDOR: + { + struct dict_avp_request * _what = (struct dict_avp_request *) what; + struct dict_object * vendor = NULL; + + CHECK_PARAMS( (criteria != AVP_BY_NAME_AND_VENDOR) || _what->avp_name ); + + /* Now look for the vendor first */ + CHECK_FCT( search_vendor( dict, VENDOR_BY_ID, &_what->avp_vendor, &vendor ) ); + if (vendor == NULL) { + if (result) + *result = NULL; + else + ret = ENOENT; + goto end; + } + + /* We now have our vendor = head of the appropriate avp list */ + if (criteria == AVP_BY_NAME_AND_VENDOR) { + SEARCH_os0( _what->avp_name, &vendor->list[2], avp.avp_name, 1); + } else { + /* AVP_BY_CODE_AND_VENDOR */ + SEARCH_scalar( _what->avp_code, &vendor->list[1], avp.avp_code, 1, (struct dict_object *)NULL ); + } + } + break; + + case AVP_BY_STRUCT: + { + struct dict_avp_request_ex * _what = (struct dict_avp_request_ex *) what; + struct dict_object * vendor = NULL; + + /* + if(_what->avp_data.avp_code) + { + LOG_E("avp_code:%d avp_vendor_id:%d\n", _what->avp_data.avp_code, _what->avp_vendor.vendor_id); + } + if(_what->avp_data.avp_name) + { + LOG_E("avp_name:%s\n", _what->avp_data.avp_name); + } + */ + + // fj added + if(! ( _what->avp_vendor.vendor || _what->avp_vendor.vendor_id || _what->avp_vendor.vendor_name ) ) + { + if(_what->avp_vendor.vendor) + LOG_E("vendor_id:%d name:%s", _what->avp_vendor.vendor_id, _what->avp_vendor.vendor_name); + } + CHECK_PARAMS( _what->avp_vendor.vendor || _what->avp_vendor.vendor_id || _what->avp_vendor.vendor_name ); + CHECK_PARAMS( _what->avp_data.avp_code || _what->avp_data.avp_name ); + + /* Now look for the vendor first */ + if (_what->avp_vendor.vendor) { + CHECK_PARAMS( ! _what->avp_vendor.vendor_id && ! _what->avp_vendor.vendor_name ); + vendor = _what->avp_vendor.vendor; + } else if (_what->avp_vendor.vendor_id) { + CHECK_PARAMS( ! _what->avp_vendor.vendor_name ); + CHECK_FCT( search_vendor( dict, VENDOR_BY_ID, &_what->avp_vendor.vendor_id, &vendor ) ); + } else { + CHECK_FCT( search_vendor( dict, VENDOR_BY_NAME, _what->avp_vendor.vendor_name, &vendor ) ); + } + + if (vendor == NULL) { + if (result) + *result = NULL; + else + ret = ENOENT; + goto end; + } + + /* We now have our vendor = head of the appropriate avp list */ + if (_what->avp_data.avp_code) { + CHECK_PARAMS( ! _what->avp_data.avp_name ); + SEARCH_scalar( _what->avp_data.avp_code, &vendor->list[1], avp.avp_code, 1, (struct dict_object *)NULL ); + } else { + SEARCH_os0( _what->avp_data.avp_name, &vendor->list[2], avp.avp_name, 1); + } + } + break; + + case AVP_BY_NAME_ALL_VENDORS: + { + struct fd_list * li; + size_t wl = strlen((char *)what); + + /* First, search for vendor 0 */ + SEARCH_os0_l( what, wl, &dict->dict_vendors.list[2], avp.avp_name, 1); + + /* If not found, loop for all vendors, until found */ + for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) { + SEARCH_os0_l( what, wl, &_O(li->o)->list[2], avp.avp_name, 1); + } + } + break; + + default: + /* Invalid criteria */ + CHECK_PARAMS( criteria = 0 ); + } +end: + return ret; +} + +static int search_cmd ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ) +{ + int ret = 0; + + TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result); + + switch (criteria) { + case CMD_BY_NAME: + /* "what" is a command name */ + SEARCH_os0( what, &dict->dict_cmd_name, cmd.cmd_name, 1); + break; + + case CMD_BY_CODE_R: + case CMD_BY_CODE_A: + { + command_code_t code; + uint8_t searchfl = 0; + + /* The command code that we are searching */ + code = *(command_code_t *) what; + + /* The flag (request or answer) of the command we are searching */ + if (criteria == CMD_BY_CODE_R) { + searchfl = CMD_FLAG_REQUEST; + } + + /* perform the search */ + SEARCH_codefl( code, searchfl, &dict->dict_cmd_code ); + } + break; + + case CMD_ANSWER: + { + /* "what" is a command object of type "request" */ + struct dict_object * req = (struct dict_object *) what; + struct dict_object * ans = NULL; + + CHECK_PARAMS( verify_object(req) + && (req->type == DICT_COMMAND) + && (req->data.cmd.cmd_flag_mask & CMD_FLAG_REQUEST) + && (req->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST) ); + + /* The answer is supposed to be the next element in the list, if it exists */ + ans = req->list[1].next->o; + if ( ans == NULL ) { + TRACE_DEBUG( FULL, "the request was the last element in the list" ); + ret = ENOENT; + goto end; + } + + /* Now check that the ans element is really the correct one */ + if ( (ans->data.cmd.cmd_code != req->data.cmd.cmd_code) + || (!(ans->data.cmd.cmd_flag_mask & CMD_FLAG_REQUEST)) + || ( ans->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST ) ) { + TRACE_DEBUG( FULL, "the answer does not follow the request in the list" ); + ret = ENOENT; + goto end; + } + + if (result) + *result = ans; + ret = 0; + } + break; + + default: + /* Invalid criteria */ + CHECK_PARAMS( criteria = 0 ); + } +end: + return ret; +} + +static int search_rule ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ) +{ + int ret = 0; + + TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result); + + switch (criteria) { + case RULE_BY_AVP_AND_PARENT: + { + struct dict_object * parent = NULL; + struct dict_object * avp = NULL; + struct dict_rule_request * _what = (struct dict_rule_request *) what; + + CHECK_PARAMS( _what + && (parent = _what->rule_parent) + && (avp = _what->rule_avp ) ); + + CHECK_PARAMS( verify_object(parent) + && ((parent->type == DICT_COMMAND) + || ((parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED))) ); + + CHECK_PARAMS( verify_object(avp) && (avp->type == DICT_AVP) ); + + /* Perform the search */ + SEARCH_ruleavpname( avp->data.avp.avp_name, avp->datastr_len, &parent->list[2]); + + } + break; + + default: + /* Invalid criteria */ + CHECK_PARAMS( criteria = 0 ); + } +end: + return ret; +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* */ +/* Dump / debug functions */ +/* */ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* The following functions are used to debug the module, and allow to print out the content of the dictionary */ +static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ) +{ + struct dict_vendor_data * vendor = (struct dict_vendor_data *)data; + + return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name); +} +static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ) +{ + struct dict_application_data * appli = (struct dict_application_data *) data; + return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", appli->application_id, appli->application_name); +} +static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ) +{ + struct dict_type_data * type = ( struct dict_type_data * ) data; + + return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"", + type_base_name[type->type_base], + type->type_name); +} +static DECLARE_FD_DUMP_PROTOTYPE(dump_enumval_data, struct dict_enumval_data * enumval, enum dict_avp_basetype type ) +{ + const int LEN_MAX = 20; + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "data: (%-12s) \"%s\" -> ", type_base_name[type], enumval->enum_name), return NULL); + switch (type) { + case AVP_TYPE_OCTETSTRING: + { + int i, n=LEN_MAX; + if (enumval->enum_value.os.len < LEN_MAX) + n = enumval->enum_value.os.len; + for (i=0; i < n; i++) + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "0x%2hhX/'%c' ", enumval->enum_value.os.data[i], ASCII(enumval->enum_value.os.data[i])), return NULL); + if (n == LEN_MAX) + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "..."), return NULL); + } + break; + + case AVP_TYPE_INTEGER32: + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%i", enumval->enum_value.i32), return NULL); + break; + + case AVP_TYPE_INTEGER64: + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRId64, enumval->enum_value.i64), return NULL); + break; + + case AVP_TYPE_UNSIGNED32: + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%u", enumval->enum_value.u32), return NULL); + break; + + case AVP_TYPE_UNSIGNED64: + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRIu64, enumval->enum_value.u64), return NULL); + break; + + case AVP_TYPE_FLOAT32: + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", enumval->enum_value.f32), return NULL); + break; + + case AVP_TYPE_FLOAT64: + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", enumval->enum_value.f64), return NULL); + break; + + default: + CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "??? (ERROR unknown type %d)", type), return NULL); + } + return *buf; +} +static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ) +{ + struct dict_avp_data * avp = (struct dict_avp_data * ) data; + return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"", + DUMP_AVPFL_val(avp->avp_flag_val), + DUMP_AVPFL_val(avp->avp_flag_mask), + type_base_name[avp->avp_basetype], + avp->avp_code, + avp->avp_name ); +} +static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ) +{ + struct dict_cmd_data * cmd = (struct dict_cmd_data *) data; + return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"", + DUMP_CMDFL_val(cmd->cmd_flag_val), DUMP_CMDFL_val(cmd->cmd_flag_mask), cmd->cmd_code, cmd->cmd_name); +} +static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ) +{ + struct dict_rule_data * rule = (struct dict_rule_data * )data; + return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"", + rule->rule_position, + rule->rule_order, + rule->rule_min, + rule->rule_max, + rule->rule_avp->data.avp.avp_name); +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ); + +static DECLARE_FD_DUMP_PROTOTYPE(dump_list, struct fd_list * sentinel, int parents, int depth, int indent ) +{ + struct fd_list * li = sentinel; + /* We don't lock here, the caller must have taken the dictionary lock for reading already */ + if (FD_IS_LIST_EMPTY(sentinel)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n%*s{empty list}", indent, ""), return NULL); + } else { + while (li->next != sentinel) + { + li = li->next; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); + CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, _O(li->o), parents, depth, indent ), return NULL); + } + } + return *buf; +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ) +{ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{dictobj}(@%p): ", indent, "", obj), return NULL); + + if (!verify_object(obj)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); + return *buf; + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ", + _OBINFO(obj).name, + obj->parent), return NULL); + + if (obj->type == DICT_ENUMVAL) { + CHECK_MALLOC_DO( dump_enumval_data ( FD_DUMP_STD_PARAMS, &obj->data.enumval, obj->parent->data.type.type_base ), return NULL); + } else { + CHECK_MALLOC_DO( _OBINFO(obj).dump_data(FD_DUMP_STD_PARAMS, &obj->data), return NULL); + } + + if (parents) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n%*sparent:", indent + 1, ""), return NULL); + CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, obj->parent, parents-1, 0, 0 ), return NULL); + } + + if (depth) { + int i; + for (i=0; ilist[i].o == NULL) && (obj->list[i].next != &obj->list[i])) { + CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &obj->list[i], 0, depth - 1, indent + 2), return NULL); + break; /* we get duplicate information sorted by another criteria otherwise, which is not very useful */ + } + } + } + + return *buf; +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj) +{ + FD_DUMP_HANDLE_OFFSET(); + + CHECK_MALLOC_DO( dump_object(FD_DUMP_STD_PARAMS, obj, 1, 2, 0), return NULL); + + return *buf; +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict) +{ + int i; + struct fd_list * li; + + FD_DUMP_HANDLE_OFFSET(); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{dictionary}(@%p): ", dict), return NULL); + + if ((dict == NULL) || (dict->dict_eyec != DICT_EYECATCHER)) { + return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL"); + } + + CHECK_POSIX_DO( pthread_rwlock_rdlock( &dict->dict_lock ), /* ignore */ ); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict(%p) : VENDORS / AVP / RULES}\n", dict), goto error); + CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_vendors, 0, 3, 3 ), goto error); + for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); + CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 3, 3 ), goto error); + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict(%p) : APPLICATIONS}\n", dict), goto error); + CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_applications, 0, 1, 3 ), goto error); + for (li = dict->dict_applications.list[0].next; li != &dict->dict_applications.list[0]; li = li->next) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); + CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 1, 3 ), goto error); + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict(%p) : TYPES / ENUMVAL}", dict), goto error); + CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_types, 0, 2, 3 ), goto error); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict(%p) : COMMANDS / RULES}", dict), goto error); + CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_cmd_code, 0, 0, 3 ), goto error); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict(%p) : statistics}", dict), goto error); + for (i=1; i<=DICT_TYPE_MAX; i++) + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n %5d: %s", dict->dict_count[i], dict_obj_info[i].name), goto error); + + CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); + return *buf; +error: + /* Free the rwlock */ + CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); + return NULL; +} + +/**************************** Dump AVP values ********************************/ + +/* Default dump functions */ +static DECLARE_FD_DUMP_PROTOTYPE(dump_val_os, union avp_value * value) +{ + int i; + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<"), return NULL); + for (i = 0; i < value->os.len; i++) { + if (i == 1024) { /* Dump only up to 1024 bytes of the buffer */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "[...] (len=%zd)", value->os.len), return NULL); + break; + } + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s%02hhX", (i==0 ? "" : " "), value->os.data[i]), return NULL); + } + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ">"), return NULL); + return *buf; +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i32, union avp_value * value) +{ + return fd_dump_extend( FD_DUMP_STD_PARAMS, "%i (0x%x)", value->i32, value->i32); +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i64, union avp_value * value) +{ + return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRId64 " (0x%" PRIx64 ")", value->i64, value->i64); +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u32, union avp_value * value) +{ + return fd_dump_extend( FD_DUMP_STD_PARAMS, "%u (0x%x)", value->u32, value->u32); +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u64, union avp_value * value) +{ + return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRIu64 " (0x%" PRIx64 ")", value->u64, value->u64); +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f32, union avp_value * value) +{ + return fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", value->f32); +} + +static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f64, union avp_value * value) +{ + return fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", value->f64); +} + +/* Get the dump function for basic dict_avp_basetype */ +static DECLARE_FD_DUMP_PROTOTYPE((*get_default_dump_val_cb(enum dict_avp_basetype datatype)), union avp_value *) +{ + switch (datatype) { + case AVP_TYPE_OCTETSTRING: + return &dump_val_os; + + case AVP_TYPE_INTEGER32: + return &dump_val_i32; + + case AVP_TYPE_INTEGER64: + return &dump_val_i64; + + case AVP_TYPE_UNSIGNED32: + return &dump_val_u32; + + case AVP_TYPE_UNSIGNED64: + return &dump_val_u64; + + case AVP_TYPE_FLOAT32: + return &dump_val_f32; + + case AVP_TYPE_FLOAT64: + return &dump_val_f64; + + case AVP_TYPE_GROUPED: + TRACE_DEBUG(FULL, "error: grouped AVP with a value!"); + } + return NULL; +} + +/* indent inside an object (duplicate from messages.c) */ +#define INOBJHDR "%*s " +#define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|" + +typedef DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb_t), union avp_value *); + +/* Formatter for the AVP value dump line */ +static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_val, union avp_value *avp_value, + dump_val_cb_t def_dump_val_cb, + dump_val_cb_t dump_val_cb, + enum dict_avp_basetype datatype, + char * type_name, + char * const_name, + int indent, + int header) +{ + if (header) { + /* Header for all AVP values dumps: */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, INOBJHDR "value ", INOBJHDRVAL), return NULL); + + /* If the type is provided, write it */ + if (type_name) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "t: '%s' ", type_name), return NULL); + } + + /* Always give the base datatype anyway */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(%s) ", type_base_name[datatype]), return NULL); + + /* Now, the value */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "v: "), return NULL); + } + if (const_name) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s' (", const_name), return NULL); + } + if (dump_val_cb) { + CHECK_MALLOC_DO( (*dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), fd_dump_extend( FD_DUMP_STD_PARAMS, "(dump failed)")); + } else { + CHECK_MALLOC_DO( (*def_dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), return NULL); + } + if (const_name) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ")"), return NULL); + } + + /* Done! */ + return *buf; +} + +/* Dump the value of an AVP of known type into the returned str */ +DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_avp_value, union avp_value *avp_value, struct dict_object * model, int indent, int header) +{ + DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb), union avp_value *avp_value) = NULL; + struct dict_object * type = NULL; + char * type_name = NULL; + char * const_name = NULL; + + FD_DUMP_HANDLE_OFFSET(); + + /* Handle invalid parameters */ + if (!avp_value) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(avp value not set)"), return NULL); + return *buf; + } + + if (!model) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(model not set)"), return NULL); + return *buf; + } + + if (! ( verify_object(model) && (model->type == DICT_AVP) )) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model)"), return NULL); + return *buf; + } + + /* Get the type definition of this AVP */ + type = model->parent; + if (type) { + struct dict_enumval_request request; + struct dict_object * enumval = NULL; + + type_name = type->data.type.type_name; + + /* overwrite the dump function ? */ + if (type->data.type.type_dump) + dump_val_cb = type->data.type.type_dump; + + /* Now check if the AVP value matches a constant */ + memset(&request, 0, sizeof(request)); + request.type_obj = type; + memcpy(&request.search.enum_value, avp_value, sizeof(union avp_value)); + /* bypass checks */ + if ((search_enumval( type->dico, ENUMVAL_BY_STRUCT, &request, &enumval ) == 0) && (enumval)) { + /* We found a constant, get its name */ + const_name = enumval->data.enumval.enum_name; + } + } + + /* And finally, dump the value */ + CHECK_MALLOC_DO( dump_avp_val(FD_DUMP_STD_PARAMS, avp_value, get_default_dump_val_cb(model->data.avp.avp_basetype), dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent, header), return NULL ); + return *buf; +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* */ +/* Exported functions */ +/* */ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/* These are the functions exported outside libfreeDiameter. */ + +/* Get the data associated to an object */ +int fd_dict_gettype ( struct dict_object * object, enum dict_object_type * type) +{ + TRACE_ENTRY("%p %p", object, type); + + CHECK_PARAMS( type && verify_object(object) ); + + /* Copy the value and return */ + *type = object->type; + return 0; +} + +int fd_dict_getdict ( struct dict_object * object, struct dictionary ** dict) +{ + TRACE_ENTRY("%p %p", object, dict); + + CHECK_PARAMS( dict && verify_object(object) ); + + /* Copy the value and return */ + *dict = object->dico; + return 0; +} + + +/* Get the data associated to an object */ +int fd_dict_getval ( struct dict_object * object, void * val) +{ + TRACE_ENTRY("%p %p", object, val); + + CHECK_PARAMS( val && verify_object(object) ); + + /* Copy the value and return */ + memcpy(val, &object->data, _OBINFO(object).datasize);; + return 0; +} + +/* Add a new object in the dictionary */ +int fd_dict_new ( struct dictionary * dict, enum dict_object_type type, void * data, struct dict_object * parent, struct dict_object **ref ) +{ + int ret = 0; + struct dict_object * new = NULL; + struct dict_object * vendor = NULL; + struct dict_object * locref = NULL; + + TRACE_ENTRY("%p %d(%s) %p %p %p", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, data, parent, ref); + + /* Check parameters */ + CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) && data ); + + /* Check the "parent" parameter */ + switch (dict_obj_info[type].parent) { + case 0: /* parent is forbidden */ + CHECK_PARAMS_DO( parent == NULL, goto error_param ); + + case 1: /* parent is optional */ + if (parent == NULL) + break; + + case 2: /* parent is mandatory */ + CHECK_PARAMS_DO( verify_object(parent), goto error_param ); + + if (type == DICT_RULE ) { /* Special case : grouped AVP or Command parents are allowed */ + CHECK_PARAMS_DO( (parent->type == DICT_COMMAND ) + || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ), goto error_param ); + } else { + CHECK_PARAMS_DO( parent->type == dict_obj_info[type].parenttype, goto error_param ); + } + } + + /* For AVP object, we must also check that the "vendor" referenced exists */ + if (type == DICT_AVP) { + CHECK_FCT_DO( fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ), + { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); goto error_param; } ); + + /* Also check if a parent is provided, that the type are the same */ + if (parent) { + CHECK_PARAMS_DO( parent->data.type.type_base == ((struct dict_avp_data *)data)->avp_basetype, goto error_param ); + } + } + + /* For RULE object, we must also check that the "avp" referenced exists */ + if (type == DICT_RULE) { + CHECK_PARAMS_DO( verify_object(((struct dict_rule_data *)data)->rule_avp), goto error_param ); + CHECK_PARAMS_DO( ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP, goto error_param ); + } + + /* For COMMAND object, check that the 'R' flag is fixed */ + if (type == DICT_COMMAND) { + CHECK_PARAMS_DO( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST, goto error_param ); + } + + /* We have to check that the new values are not equal to the sentinels */ + /* + if (type == DICT_VENDOR) { + CHECK_PARAMS_DO( ((struct dict_vendor_data *)data)->vendor_id != 0, goto error_param ); + } + if (type == DICT_APPLICATION) { + CHECK_PARAMS_DO( ((struct dict_application_data *)data)->application_id != 0, goto error_param ); + } + */ + + /* Parameters are valid, create the new object */ + CHECK_MALLOC( new = malloc(sizeof(struct dict_object)) ); + + /* Initialize the data of the new object */ + init_object(new, type); + init_object_data(new, data, type); + new->dico = dict; + new->parent = parent; + + /* We will change the dictionary => acquire the write lock */ + CHECK_POSIX_DO( ret = pthread_rwlock_wrlock(&dict->dict_lock), goto error_free ); + + /* Now link the object -- this also checks that no object with same keys already exists */ + switch (type) { + case DICT_VENDOR: + + // LOG_E("fd_dict_new vendor addr:%p vendorID:%d", &new->list[0], ((struct dict_vendor_data *)data)->vendor_id); + /* A vendor object is linked in the g_dict_vendors.list[0], by their id */ + ret = fd_list_insert_ordered ( &dict->dict_vendors.list[0], &new->list[0], (int (*)(void*, void *))order_vendor_by_id, (void **)&locref ); + if (ret) + goto error_unlock; + print_vend_id(dict); + break; + + case DICT_APPLICATION: + /* An application object is linked in the g_dict_applciations.list[0], by their id */ + ret = fd_list_insert_ordered ( &dict->dict_applications.list[0], &new->list[0], (int (*)(void*, void *))order_appli_by_id, (void **)&locref ); + if (ret) + goto error_unlock; + break; + + case DICT_TYPE: + /* A type object is linked in g_list_types by its name */ + ret = fd_list_insert_ordered ( &dict->dict_types, &new->list[0], (int (*)(void*, void *))order_type_by_name, (void **)&locref ); + if (ret) + goto error_unlock; + break; + + case DICT_ENUMVAL: + /* A type_enum object is linked in it's parent 'type' object lists 1 and 2 by its name and values */ + ret = fd_list_insert_ordered ( &parent->list[1], &new->list[0], (int (*)(void*, void *))order_enum_by_name, (void **)&locref ); + if (ret) + goto error_unlock; + + ret = fd_list_insert_ordered ( &parent->list[2], &new->list[1], (int (*)(void*, void *))order_enum_by_val, (void **)&locref ); + if (ret) { + fd_list_unlink(&new->list[0]); + goto error_unlock; + } + break; + + case DICT_AVP: + /* An avp object is linked in lists 1 and 2 of its vendor, by code and name */ + ret = fd_list_insert_ordered ( &vendor->list[1], &new->list[0], (int (*)(void*, void *))order_avp_by_code, (void **)&locref ); + if (ret) + goto error_unlock; + + ret = fd_list_insert_ordered ( &vendor->list[2], &new->list[1], (int (*)(void*, void *))order_avp_by_name, (void **)&locref ); + if( !ret) + { + LOG_D("Fun:%s Line:%d insert addr:%p dictavp[code,name] [%d,%s]", + __FUNCTION__, + __LINE__, + &vendor->list[2], + (((struct dict_avp_data *)data)->avp_code), + (((struct dict_avp_data *)data)->avp_name) ); + } + if (ret) { + fd_list_unlink(&new->list[0]); + goto error_unlock; + } + break; + + case DICT_COMMAND: + /* A command object is linked in g_list_cmd_name and g_list_cmd_code by its name and code */ + ret = fd_list_insert_ordered ( &dict->dict_cmd_code, &new->list[1], (int (*)(void*, void *))order_cmd_by_codefl, (void **)&locref ); + if (ret) + goto error_unlock; + + ret = fd_list_insert_ordered ( &dict->dict_cmd_name, &new->list[0], (int (*)(void*, void *))order_cmd_by_name, (void **)&locref ); + if (ret) { + fd_list_unlink(&new->list[1]); + goto error_unlock; + } + break; + + case DICT_RULE: + /* A rule object is linked in list[2] of its parent command or AVP by the name of the AVP it refers */ + ret = fd_list_insert_ordered ( &parent->list[2], &new->list[0], (int (*)(void*, void *))order_rule_by_avpvc, (void **)&locref ); + if (ret) + goto error_unlock; + break; + + default: + ASSERT(0); + } + + /* A new object has been created, increment the global counter */ + dict->dict_count[type]++; + + /* Unlock the dictionary */ + CHECK_POSIX_DO( ret = pthread_rwlock_unlock(&dict->dict_lock), goto error_free ); + + /* Save the pointer to the new object */ + if (ref) + *ref = new; + + return 0; + +error_param: + ret = EINVAL; + goto all_errors; + +error_unlock: + CHECK_POSIX_DO( pthread_rwlock_unlock(&dict->dict_lock), /* continue */ ); + if (ret == EEXIST) { + /* We have a duplicate key in locref. Check if the pointed object is the same or not */ + switch (type) { + case DICT_VENDOR: + TRACE_DEBUG(FULL, "Vendor %s already in dictionary", new->data.vendor.vendor_name); + /* if we are here, it means the two vendors id are identical */ + if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len, + new->data.vendor.vendor_name, new->datastr_len)) { + TRACE_DEBUG(INFO, "Conflicting vendor name: %s", new->data.vendor.vendor_name); + break; + } + /* Otherwise (same name), we consider the function succeeded, since the (same) object is in the dictionary */ + ret = 0; + break; + + case DICT_APPLICATION: + TRACE_DEBUG(FULL, "Application %s already in dictionary", new->data.application.application_name); + /* got same id */ + if (fd_os_cmp(locref->data.application.application_name, locref->datastr_len, + new->data.application.application_name, new->datastr_len)) { + TRACE_DEBUG(FULL, "Conflicting application name"); + break; + } + ret = 0; + break; + + case DICT_TYPE: + TRACE_DEBUG(FULL, "Type %s already in dictionary", new->data.type.type_name); + /* got same name */ + if (locref->data.type.type_base != new->data.type.type_base) { + TRACE_DEBUG(FULL, "Conflicting base type"); + break; + } + /* discard new definition only it a callback is provided and different from the previous one */ + if ((new->data.type.type_interpret) && (locref->data.type.type_interpret != new->data.type.type_interpret)) { + TRACE_DEBUG(FULL, "Conflicting interpret cb"); + break; + } + if ((new->data.type.type_encode) && (locref->data.type.type_encode != new->data.type.type_encode)) { + TRACE_DEBUG(FULL, "Conflicting encode cb"); + break; + } + if ((new->data.type.type_dump) && (locref->data.type.type_dump != new->data.type.type_dump)) { + TRACE_DEBUG(FULL, "Conflicting dump cb"); + break; + } + ret = 0; + break; + + case DICT_ENUMVAL: + TRACE_DEBUG(FULL, "Enum %s already in dictionary", new->data.enumval.enum_name); + /* got either same name or same value. We check that both are true */ + if (order_enum_by_name(locref, new)) { + TRACE_DEBUG(FULL, "Conflicting enum name"); + break; + } + if (order_enum_by_val(locref, new)) { + TRACE_DEBUG(FULL, "Conflicting enum value"); + break; + } + ret = 0; + break; + + case DICT_AVP: + TRACE_DEBUG(FULL, "AVP %s already in dictionary", new->data.avp.avp_name); + /* got either same name or code */ + if (order_avp_by_code(locref, new)) { + TRACE_DEBUG(FULL, "Conflicting AVP code"); + break; + } + if (order_avp_by_name(locref, new)) { + TRACE_DEBUG(FULL, "Conflicting AVP name"); + break; + } + if (locref->data.avp.avp_vendor != new->data.avp.avp_vendor) { + TRACE_DEBUG(FULL, "Conflicting AVP vendor"); + break; + } + if (locref->data.avp.avp_flag_mask != new->data.avp.avp_flag_mask) { + TRACE_DEBUG(FULL, "Conflicting AVP flags mask"); + break; + } + if ((locref->data.avp.avp_flag_val & locref->data.avp.avp_flag_mask) != (new->data.avp.avp_flag_val & new->data.avp.avp_flag_mask)) { + TRACE_DEBUG(FULL, "Conflicting AVP flags value"); + break; + } + if (locref->data.avp.avp_basetype != new->data.avp.avp_basetype) { + TRACE_DEBUG(FULL, "Conflicting AVP base type"); + break; + } + ret = 0; + break; + + case DICT_COMMAND: + TRACE_DEBUG(FULL, "Command %s already in dictionary", new->data.cmd.cmd_name); + /* We got either same name, or same code + R flag */ + if (order_cmd_by_name(locref, new)) { + TRACE_DEBUG(FULL, "Conflicting command name"); + break; + } + if (locref->data.cmd.cmd_code != new->data.cmd.cmd_code) { + TRACE_DEBUG(FULL, "Conflicting command code"); + break; + } + if (locref->data.cmd.cmd_flag_mask != new->data.cmd.cmd_flag_mask) { + TRACE_DEBUG(FULL, "Conflicting command flags mask %hhx:%hhx", locref->data.cmd.cmd_flag_mask, new->data.cmd.cmd_flag_mask); + break; + } + if ((locref->data.cmd.cmd_flag_val & locref->data.cmd.cmd_flag_mask) != (new->data.cmd.cmd_flag_val & new->data.cmd.cmd_flag_mask)) { + TRACE_DEBUG(FULL, "Conflicting command flags value"); + break; + } + ret = 0; + break; + + case DICT_RULE: + /* Both rules point to the same AVPs (code & vendor) */ + if (locref->data.rule.rule_position != new->data.rule.rule_position) { + TRACE_DEBUG(FULL, "Conflicting rule position"); + break; + } + if ( ((locref->data.rule.rule_position == RULE_FIXED_HEAD) || + (locref->data.rule.rule_position == RULE_FIXED_TAIL)) + && (locref->data.rule.rule_order != new->data.rule.rule_order)) { + TRACE_DEBUG(FULL, "Conflicting rule order"); + break; + } + if (locref->data.rule.rule_min != new->data.rule.rule_min) { + int r1 = locref->data.rule.rule_min; + int r2 = new->data.rule.rule_min; + int p = locref->data.rule.rule_position; + if ( ((r1 != -1) && (r2 != -1)) /* none of the definitions contains the "default" value */ + || ((p == RULE_OPTIONAL) && (r1 != 0) && (r2 != 0)) /* the other value is not 0 for an optional rule */ + || ((r1 != 1) && (r2 != 1)) /* the other value is not 1 for another rule */ + ) { + TRACE_DEBUG(FULL, "Conflicting rule min"); + break; + } + } + if (locref->data.rule.rule_max != new->data.rule.rule_max) { + TRACE_DEBUG(FULL, "Conflicting rule max"); + break; + } + ret = 0; + break; + } + if (!ret) { + TRACE_DEBUG(FULL, "An existing object with the same data was found, ignoring the error..."); + } + if (ref) + *ref = locref; + } +all_errors: + if (ret != 0) { + char * buf = NULL; + size_t len = 0, offset=0; + + if (type == DICT_ENUMVAL) { + CHECK_MALLOC( dump_enumval_data ( &buf, &len, &offset, data, parent->data.type.type_base )); + } else { + CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, &offset, data) ); + } + + TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf); + + if (ret == EEXIST) { + offset=0; + CHECK_MALLOC( dump_object(&buf, &len, &offset, locref, 0, 0, 0) ); + TRACE_DEBUG(INFO, "Conflicting entry in the dictionary: %s", buf); + } + free(buf); + } +error_free: + free(new); + return ret; +} + + +int fd_dict_delete(struct dict_object * obj) +{ + int i; + struct dictionary * dict; + int ret=0; + + /* check params */ + CHECK_PARAMS( verify_object(obj) && obj->dico); + dict = obj->dico; + + /* Lock the dictionary for change */ + CHECK_POSIX( pthread_rwlock_wrlock(&dict->dict_lock) ); + + /* check the object is not sentinel for another list */ + for (i=0; ilist[i]))) { + /* There are children, this is not good */ + ret = EINVAL; + TRACE_DEBUG (FULL, "Cannot delete object, list %d not empty:", i); + #if 0 + dump_list(&obj->list[i], 0,0,0); + #endif + break; + } + } + + /* ok, now destroy the object */ + if (!ret) + destroy_object(obj); + + /* Unlock */ + CHECK_POSIX( pthread_rwlock_unlock(&dict->dict_lock) ); + + return ret; +} + + +int fd_dict_search ( struct dictionary * dict, enum dict_object_type type, int criteria, const void * what, struct dict_object **result, int retval ) +{ + int ret = 0; + + TRACE_ENTRY("%p %d(%s) %d %p %p %d", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, criteria, what, result, retval); + + /* Check param */ + CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) ); + + /* Lock the dictionary for reading */ + CHECK_POSIX( pthread_rwlock_rdlock(&dict->dict_lock) ); + + /* Now call the type-specific search function */ + ret = dict_obj_info[type].search_fct (dict, criteria, what, result); + + /* Unlock */ + CHECK_POSIX( pthread_rwlock_unlock(&dict->dict_lock) ); + + /* Update the return value as needed */ + if ((result != NULL) && (*result == NULL)) + ret = retval; + + return ret; +} + +/* Function to retrieve list of objects in the dictionary. Use with care (read only). + +All returned list must be accessed like this: + + for (li = sentinel->next; li != sentinel; li=li->next) { + struct dict_object * obj = li->o; + ... + } + +The following criteria are allowed, with corresponding parent. +The parent is either struct dictionary * or struct dict_object * + +VENDOR_BY_ID : (parent = dictionary) returns list of vendors ordered by ID +APPLICATION_BY_ID : (parent = dictionary) returns list of applications ordered by ID + ** for these two lists, the Vendor with id 0 and applciation with id 0 are excluded. + You must resolve them separatly with dict_search. + +TYPE_BY_NAME : (parent = dictionary) returns list of types ordered by name (osstring order) +ENUMVAL_BY_NAME : (parent = type object) return list of constants for this type ordered by name (osstring order) +ENUMVAL_BY_VALUE : (parent = type object) return list of constants for this type ordered by values +AVP_BY_NAME : (parent = vendor object) return list of AVP for this vendor ordered by name (osstring order) +AVP_BY_CODE : (parent = vendor object) return list of AVP for this vendor ordered by code +CMD_BY_NAME : (parent = dictionary) returns list of commands ordered by name (osstring order) +CMD_BY_CODE_R : (parent = dictionary) returns list of commands ordered by code +RULE_BY_AVP_AND_PARENT: (parent = command or grouped AVP object) return list of rules for this object ordered by AVP vendor/code + +All other criteria are rejected. + */ +int fd_dict_getlistof(int criteria, void * parent, struct fd_list ** sentinel) +{ + struct dictionary * dict = parent; + struct dict_object * obj_parent = parent; + + TRACE_ENTRY("%i %p %p", criteria, parent, sentinel); + + CHECK_PARAMS(sentinel && parent); + + switch(criteria) { + case VENDOR_BY_ID: /* parent must be the dictionary */ + CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER); + *sentinel = &dict->dict_vendors.list[0]; + break; + + case APPLICATION_BY_ID: /* parent must be the dictionary */ + CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER); + *sentinel = &dict->dict_applications.list[0]; + break; + + case TYPE_BY_NAME: /* parent must be the dictionary */ + CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER); + *sentinel = &dict->dict_types; + break; + + case ENUMVAL_BY_NAME: /* parent must be a type object */ + CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_TYPE)); + *sentinel = &obj_parent->list[1]; + break; + + case ENUMVAL_BY_VALUE: /* parent must be a type object */ + CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_TYPE)); + *sentinel = &obj_parent->list[2]; + break; + + case AVP_BY_NAME: /* parent must be a VENDOR object */ + CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_VENDOR)); + *sentinel = &obj_parent->list[2]; + break; + + case AVP_BY_CODE: /* parent must be a VENDOR object */ + CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_VENDOR)); + *sentinel = &obj_parent->list[1]; + break; + + case CMD_BY_NAME: /* parent must be the dictionary */ + CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER); + *sentinel = &dict->dict_cmd_name; + break; + + case CMD_BY_CODE_R: /* parent must be the dictionary */ + CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER); + *sentinel = &dict->dict_cmd_code; + break; + + case RULE_BY_AVP_AND_PARENT: /* parent must be command or grouped AVP */ + CHECK_PARAMS(verify_object(obj_parent)); + CHECK_PARAMS( (obj_parent->type == DICT_COMMAND) || + ((obj_parent->type == DICT_AVP) + && (obj_parent->data.avp.avp_basetype == AVP_TYPE_GROUPED)) ); + *sentinel = &obj_parent->list[2]; + break; + + default: + CHECK_PARAMS(0); + } + + return 0; +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* */ +/* The init/fini functions */ +/* */ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/* Initialize the dictionary */ +int fd_dict_init ( struct dictionary ** dict) +{ + struct dictionary * new = NULL; + + TRACE_ENTRY("%p", dict); + + /* Sanity checks */ + ASSERT( (sizeof(type_base_name) / sizeof(type_base_name[0])) == (AVP_TYPE_MAX + 1) ); + ASSERT( (sizeof(dict_obj_info) / sizeof(dict_obj_info[0])) == (DICT_TYPE_MAX + 1) ); + CHECK_PARAMS(dict); + + /* Allocate the memory for the dictionary */ + CHECK_MALLOC( new = malloc(sizeof(struct dictionary)) ); + memset(new, 0, sizeof(struct dictionary)); + + new->dict_eyec = DICT_EYECATCHER; + + /* Initialize the lock for the dictionary */ + CHECK_POSIX( pthread_rwlock_init(&new->dict_lock, NULL) ); + + /* Initialize the sentinel for vendors and AVP lists */ + init_object( &new->dict_vendors, DICT_VENDOR ); + #define NO_VENDOR_NAME "(no vendor)" + new->dict_vendors.data.vendor.vendor_name = NO_VENDOR_NAME; + new->dict_vendors.datastr_len = CONSTSTRLEN(NO_VENDOR_NAME); + /* new->dict_vendors.list[0].o = NULL; *//* overwrite since element is also sentinel for this list. */ + new->dict_vendors.dico = new; + + /* Initialize the sentinel for applications */ + init_object( &new->dict_applications, DICT_APPLICATION ); + #define APPLICATION_0_NAME "Diameter Common Messages" + new->dict_applications.data.application.application_name = APPLICATION_0_NAME; + new->dict_applications.datastr_len = CONSTSTRLEN(APPLICATION_0_NAME); + /* new->dict_applications.list[0].o = NULL; *//* overwrite since since element is also sentinel for this list. */ + new->dict_applications.dico = new; + + /* Initialize the sentinel for types */ + fd_list_init ( &new->dict_types, NULL ); + + /* Initialize the sentinels for commands */ + fd_list_init ( &new->dict_cmd_name, NULL ); + fd_list_init ( &new->dict_cmd_code, NULL ); + + /* Initialize the error command object */ + init_object( &new->dict_cmd_error, DICT_COMMAND ); + #define GENERIC_ERROR_NAME "(generic error format)" + new->dict_cmd_error.data.cmd.cmd_name = GENERIC_ERROR_NAME; + new->dict_cmd_error.datastr_len = CONSTSTRLEN(GENERIC_ERROR_NAME); + new->dict_cmd_error.data.cmd.cmd_flag_mask=CMD_FLAG_ERROR | CMD_FLAG_REQUEST | CMD_FLAG_RETRANSMIT; + new->dict_cmd_error.data.cmd.cmd_flag_val =CMD_FLAG_ERROR; + new->dict_cmd_error.dico = new; + + *dict = new; + + /* Done */ + return 0; +} + +/* Destroy a dictionary */ +int fd_dict_fini ( struct dictionary ** dict) +{ + int i; + + TRACE_ENTRY(""); + CHECK_PARAMS( dict && *dict && ((*dict)->dict_eyec == DICT_EYECATCHER) ); + + /* Acquire the write lock to make sure no other operation is ongoing */ + CHECK_POSIX( pthread_rwlock_wrlock(&(*dict)->dict_lock) ); + + /* Empty all the lists, free the elements */ + destroy_list ( &(*dict)->dict_cmd_error.list[2] ); + destroy_list ( &(*dict)->dict_cmd_code ); + destroy_list ( &(*dict)->dict_cmd_name ); + destroy_list ( &(*dict)->dict_types ); + for (i=0; i< NB_LISTS_PER_OBJ; i++) { + destroy_list ( &(*dict)->dict_applications.list[i] ); + destroy_list ( &(*dict)->dict_vendors.list[i] ); + } + + /* Dictionary is empty, now destroy the lock */ + CHECK_POSIX( pthread_rwlock_unlock(&(*dict)->dict_lock) ); + CHECK_POSIX( pthread_rwlock_destroy(&(*dict)->dict_lock) ); + + free(*dict); + *dict = NULL; + + return 0; +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/* */ +/* Other functions */ +/* */ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/* Iterate a callback on the rules for an object */ +int fd_dict_iterate_rules ( struct dict_object *parent, void * data, int (*cb)(void *, struct dict_rule_data *) ) +{ + int ret = 0; + struct fd_list * li; + + TRACE_ENTRY("%p %p %p", parent, data, cb); + + /* Check parameters */ + CHECK_PARAMS( verify_object(parent) ); + CHECK_PARAMS( (parent->type == DICT_COMMAND) + || ((parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED)) ); + TRACE_DEBUG (FULL, "Iterating on rules of %s: '%s'.", + _OBINFO(parent).name, + parent->type == DICT_COMMAND ? + parent->data.cmd.cmd_name + : parent->data.avp.avp_name); + + /* Acquire the read lock */ + CHECK_POSIX( pthread_rwlock_rdlock(&parent->dico->dict_lock) ); + + /* go through the list and call the cb on each rule data */ + for (li = &(parent->list[2]); li->next != &(parent->list[2]); li = li->next) { + ret = (*cb)(data, &(_O(li->next->o)->data.rule)); + if (ret != 0) + break; + } + + /* Release the lock */ + CHECK_POSIX( pthread_rwlock_unlock(&parent->dico->dict_lock) ); + + return ret; +} + +/* Create the list of vendors. Returns a 0-terminated array, that must be freed after use. Returns NULL on error. */ +uint32_t * fd_dict_get_vendorid_list(struct dictionary * dict) +{ + uint32_t * ret = NULL; + int i = 0; + struct fd_list * li; + + TRACE_ENTRY(); + + /* Acquire the read lock */ + CHECK_POSIX_DO( pthread_rwlock_rdlock(&dict->dict_lock), return NULL ); + + /* Allocate an array to contain all the elements */ + CHECK_MALLOC_DO( ret = calloc( dict->dict_count[DICT_VENDOR] + 1, sizeof(uint32_t) ), goto out ); + + /* Copy the vendors IDs */ + for (li = dict->dict_vendors.list[0].next; li != &(dict->dict_vendors.list[0]); li = li->next) { + ret[i] = _O(li->o)->data.vendor.vendor_id; + i++; + ASSERT( i <= dict->dict_count[DICT_VENDOR] ); + } +out: + /* Release the lock */ + CHECK_POSIX_DO( pthread_rwlock_unlock(&dict->dict_lock), return NULL ); + + return ret; +} + +/* Return the location of the cb list for an object, after checking its type */ +int fd_dict_disp_cb(enum dict_object_type type, struct dict_object *obj, struct fd_list ** cb_list) +{ + TRACE_ENTRY("%d %p %p", type, obj, cb_list); + CHECK_PARAMS( verify_object(obj) ); + CHECK_PARAMS( _OBINFO(obj).type == type ); + CHECK_PARAMS( cb_list ); + *cb_list = &obj->disp_cbs; + return 0; +} + +int fd_dict_get_error_cmd(struct dictionary * dict, struct dict_object **obj) +{ + TRACE_ENTRY("%p %p", dict, obj); + CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && obj ); + *obj = &dict->dict_cmd_error; + return 0; +} diff --git a/plat/diameter/libfdproto/dictionary_functions.c b/plat/diameter/libfdproto/dictionary_functions.c new file mode 100644 index 0000000..8eedf40 --- /dev/null +++ b/plat/diameter/libfdproto/dictionary_functions.c @@ -0,0 +1,405 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2015, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" +#include + +/* This file contains helpers functions to be reused as callbacks in the struct dict_type_data structure. +There are three callbacks there: + + - type_encode : + - type_interpret : + Those two callbacks allow to manipulate more natural structures of data in the code, and to + map transparently these natural structures with the AVP-encoded format by calling the functions + msg_avp_value_encode or msg_avp_value_interpret. + - type_dump : + This callback if provided gives a more human-readable debug information. + + */ + +/****************************/ +/* Address AVP type */ +/****************************/ + +/* The interpret and encode functions work with a "struct sockaddr_storage" pointer for mapping +the contents of the AVP */ + +int fd_dictfct_Address_encode(void * data, union avp_value * avp_value) +{ + sSS * ss = (sSS *) data; + uint16_t AddressType = 0; + size_t size = 0; + unsigned char * buf = NULL; + + TRACE_ENTRY("%p %p", data, avp_value); + CHECK_PARAMS( data && avp_value ); + + switch (ss->ss_family) { + case AF_INET: + { + /* We are encoding an IP address */ + sSA4 * sin = (sSA4 *)ss; + + AddressType = 1;/* see http://www.iana.org/assignments/address-family-numbers/ */ + size = 6; /* 2 for AddressType + 4 for data */ + + CHECK_MALLOC( buf = malloc(size) ); + + /* may not work because of alignment: *(uint32_t *)(buf+2) = htonl(sin->sin_addr.s_addr); */ + memcpy(buf + 2, &sin->sin_addr.s_addr, 4); + } + break; + + case AF_INET6: + { + /* We are encoding an IPv6 address */ + sSA6 * sin6 = (sSA6 *)ss; + + AddressType = 2;/* see http://www.iana.org/assignments/address-family-numbers/ */ + size = 18; /* 2 for AddressType + 16 for data */ + + CHECK_MALLOC( buf = malloc(size) ); + + /* The order is already good here */ + memcpy(buf + 2, &sin6->sin6_addr.s6_addr, 16); + + } + break; + + default: + CHECK_PARAMS( AddressType = 0 ); + } + + *(uint16_t *)buf = htons(AddressType); + + avp_value->os.len = size; + avp_value->os.data = buf; + + return 0; +} + +int fd_dictfct_Address_interpret(union avp_value * avp_value, void * interpreted) +{ + uint16_t AddressType = 0; + unsigned char * buf; + + TRACE_ENTRY("%p %p", avp_value, interpreted); + + CHECK_PARAMS( avp_value && interpreted && (avp_value->os.len >= 2) ); + + AddressType = ntohs(*(uint16_t *)avp_value->os.data); + buf = &avp_value->os.data[2]; + + switch (AddressType) { + case 1 /* IP */: + { + sSA4 * sin = (sSA4 *)interpreted; + + CHECK_PARAMS( avp_value->os.len == 6 ); + + sin->sin_family = AF_INET; + /* sin->sin_addr.s_addr = ntohl( * (uint32_t *) buf); -- may not work because of bad alignment */ + memcpy(&sin->sin_addr.s_addr, buf, 4); + } + break; + + case 2 /* IP6 */: + { + sSA6 * sin6 = (sSA6 *)interpreted; + + CHECK_PARAMS( avp_value->os.len == 18 ); + + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr.s6_addr, buf, 16); + + } + break; + + default: + CHECK_PARAMS( AddressType = 0 ); + } + + return 0; +} + +/* Dump the content of an Address AVP */ +DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Address_dump, union avp_value * avp_value) +{ + union { + sSA sa; + sSS ss; + sSA4 sin; + sSA6 sin6; + } s; + uint16_t fam; + + FD_DUMP_HANDLE_OFFSET(); + + memset(&s, 0, sizeof(s)); + + /* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */ + if (avp_value->os.len < 2) { + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); + return *buf; + } + + /* Following octets are the address in network byte order already */ + fam = avp_value->os.data[0] << 8 | avp_value->os.data[1]; + switch (fam) { + case 1: + /* IP */ + s.sa.sa_family = AF_INET; + if ((avp_value->os.len != 6) && (avp_value->os.len != 8)) { + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP length: %zd]", avp_value->os.len), return NULL); + return *buf; + } + memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4); + if (avp_value->os.len == 8) + memcpy(&s.sin.sin_port, avp_value->os.data + 6, 2); + break; + case 2: + /* IP6 */ + s.sa.sa_family = AF_INET6; + if ((avp_value->os.len != 18) && (avp_value->os.len != 20)) { + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP6 length: %zd]", avp_value->os.len), return NULL); + return *buf; + } + memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16); + if (avp_value->os.len == 20) + memcpy(&s.sin6.sin6_port, avp_value->os.data + 18, 2); + break; + case 8: + /* E.164 */ + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "%.*s", (int)(avp_value->os.len-2), avp_value->os.data+2), return NULL); + return *buf; + default: + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[unsupported family: 0x%hx]", fam), return NULL); + return *buf; + } + + return fd_sa_dump(FD_DUMP_STD_PARAMS, &s.sa, NI_NUMERICHOST); +} + + + +/*******************************/ +/* UTF8String AVP type */ +/*******************************/ + +/* Dump the AVP in a natural human-readable format. This dumps the complete length of the AVP, it is up to the caller to truncate if needed */ +DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_UTF8String_dump, union avp_value * avp_value) +{ + size_t l; + FD_DUMP_HANDLE_OFFSET(); + + l = avp_value->os.len; + /* Just in case the string ends in invalid UTF-8 chars, we shorten it */ + while ((l > 0) && (avp_value->os.data[l - 1] & 0x80)) { + /* this byte is start or cont. of multibyte sequence, as we do not know the next byte we need to delete it. */ + l--; + if (avp_value->os.data[l] & 0x40) + break; /* This was a start byte, we can stop the loop */ + } + + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "\"%.*s\"", (int)l, (char *)avp_value->os.data), return NULL); + + return *buf; +} + + +/*******************************/ +/* Time AVP type */ +/*******************************/ + +/* The interpret and encode functions work with a "time_t" pointer for mapping +the contents of the AVP */ + +/* Unix Epoch starts 1970-01-01, NTP 0 is at 1900-01-01 */ +#define DIFF_EPOCH_TO_NTP ((365*(1970-1900) + 17ul) * 24 * 60 * 60) + +static int diameter_string_to_time_t(const char *str, size_t len, time_t *result) { + time_t time_stamp; + CHECK_PARAMS(len == 4); + + time_stamp = (((unsigned long)(str[0]&0xff))<<24) + ((str[1]&0xff)<<16) + ((str[2]&0xff)<<8) + ((str[3]&0xff)); + time_stamp -= DIFF_EPOCH_TO_NTP; +#ifdef FIX__NEEDED_FOR_YEAR_2036_AND_LATER +/* NTP overflows in 2036; after that, values start at zero again */ +#define NTP_OVERFLOW_CORRECTION (0x100000000ull) + /* XXX: debug and find correct conversion */ + if (str[0] & 0x80 == 0x00) { + time_stamp += NTP_OVERFLOW_CORRECTION; + } +#endif + *result = time_stamp; + return 0; +} + +static int time_t_to_diameter_string(time_t time_stamp, char **result) { + uint64_t out = time_stamp; + char *conv; + /* XXX: 2036 fix */ + out += DIFF_EPOCH_TO_NTP; + CHECK_PARAMS( (out >> 32) == 0); + + CHECK_MALLOC(conv=(char *)malloc(5)); + + conv[0] = (out>>24) & 0xff; + conv[1] = (out>>16) & 0xff; + conv[2] = (out>> 8) & 0xff; + conv[3] = out & 0xff; + conv[4] = '\0'; + *result = conv; + return 0; +} + +int time_t_to_diameter_timestamp(char *strTime) +{ + time_t now; + int out; + + time(&now); + + out = now+DIFF_EPOCH_TO_NTP; + + strTime[0] = (out>>24) & 0xff; + strTime[1] = (out>>16) & 0xff; + strTime[2] = (out>> 8) & 0xff; + strTime[3] = out & 0xff; + strTime[4] = '\0'; + + return 1; +} + +int fd_dictfct_Time_encode(void * data, union avp_value * avp_value) +{ + char * buf; + size_t len; + + TRACE_ENTRY("%p %p", data, avp_value); + CHECK_PARAMS( data && avp_value ); + + CHECK_FCT( time_t_to_diameter_string( *((time_t *)data), &buf) ); + /* FIXME: return len from the function above? */ len = 4; + + avp_value->os.len = len; + avp_value->os.data = (uint8_t *)buf; + return 0; +} + +int fd_dictfct_Time_interpret(union avp_value * avp_value, void * interpreted) +{ + TRACE_ENTRY("%p %p", avp_value, interpreted); + + CHECK_PARAMS( avp_value && interpreted ); + + return diameter_string_to_time_t((const char *)avp_value->os.data, avp_value->os.len, interpreted); +} + +static void _format_offs (long offset, char *buf) { + int offs_hours, offs_minutes, sgn = 1; + if (offset < 0) { + offset = -offset; + sgn = 1; + } + offs_hours = (int)(offset/3600); + offs_minutes = (offset%3600)/60; + + char* s = buf; + + *(s++) = sgn == 1 ? '+' : '-'; + *(s++) = (char)(offs_hours/10) + '0'; + *(s++) = offs_hours%10 + '0'; + + if (offs_minutes == 0) { + *(s++) = '\0'; + } else { + *(s++) = (char)(offs_minutes/10) + '0'; + *(s++) = offs_minutes%10 + '0'; + *(s++) = '\0'; + } +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value) +{ + time_t val; + struct tm conv; + char tz_buf[7]; + + FD_DUMP_HANDLE_OFFSET(); + + if (avp_value->os.len != 4) { + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); + return *buf; + } + + if (diameter_string_to_time_t((char *)avp_value->os.data, avp_value->os.len, &val) != 0) { + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[time conversion error]"), return NULL); + return *buf; + } + + CHECK_MALLOC_DO( localtime_r(&val, &conv), return NULL); + _format_offs(conv.tm_gmtoff, tz_buf); + CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "%d%02d%02dT%02d%02d%02d%s", conv.tm_year+1900, conv.tm_mon+1, conv.tm_mday, conv.tm_hour, conv.tm_min, conv.tm_sec, tz_buf), return NULL); + return *buf; +} + +/* Check that a given AVP value contains all the characters from data in the same order */ +static char error_message[80]; +int fd_dictfct_CharInOS_check(void * data, union avp_value * val, char ** error_msg) +{ + char * inChar = data; + char * inData = (char *)val->os.data; + int i = 0; + CHECK_PARAMS(data); + while (*inChar != '\0') { + while (i < val->os.len) { + if (*inChar == inData[i++]) { + inChar++; + break; + } + } + if (i >= val->os.len) + break; + } + if (*inChar == '\0') + return 0; + + if (error_msg) { + snprintf(error_message, sizeof(error_message), "Could not find '%c' in AVP", *inChar); + *error_msg = error_message; + } + return EBADMSG; +} diff --git a/plat/diameter/libfdproto/dispatch.c b/plat/diameter/libfdproto/dispatch.c new file mode 100644 index 0000000..1d2dc34 --- /dev/null +++ b/plat/diameter/libfdproto/dispatch.c @@ -0,0 +1,228 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" + +/* The dispatch module in the library is quite simple: callbacks are saved in a global list + * in no particular order. In addition, they are also linked from the dictionary objects they + * refer to. */ + +/* Protection for the lists managed in this module. */ +pthread_rwlock_t fd_disp_lock = PTHREAD_RWLOCK_INITIALIZER; + +/* List of all registered handlers -- useful if we want to cleanup properly at some point... */ +static struct fd_list all_handlers = FD_LIST_INITIALIZER( all_handlers ); + +/* List of handlers registered for DISP_HOW_ANY. Other handlers are stored in the dictionary */ +static struct fd_list any_handlers = FD_LIST_INITIALIZER( any_handlers ); + +/* The structure to store a callback */ +struct disp_hdl { + int eyec; /* Eye catcher, DISP_EYEC */ + struct fd_list all; /* link in the all_handlers list */ + struct fd_list parent;/* link in dictionary cb_list or in any_handlers */ + enum disp_how how; /* Copy of registration parameter */ + struct disp_when when; /* Copy of registration parameter */ + int (*cb)( struct msg **, struct avp *, struct session *, void *, enum disp_action *); /* The callback itself */ + void *opaque; /* opaque data passed back to the callback */ +}; + +#define DISP_EYEC 0xD15241C1 +#define VALIDATE_HDL( _hdl ) \ + ( ( ( _hdl ) != NULL ) && ( ((struct disp_hdl *)( _hdl ))->eyec == DISP_EYEC ) ) + +/**************************************************************************************/ + +/* Call CBs from a given list (any_handlers if cb_list is NULL) -- must have locked fd_disp_lock before */ +int fd_disp_call_cb_int( struct fd_list * cb_list, struct msg ** msg, struct avp *avp, struct session *sess, enum disp_action *action, + struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu, + char ** drop_reason, struct msg ** drop_msg) +{ + struct fd_list * senti, *li; + int r; + TRACE_ENTRY("%p %p %p %p %p %p %p %p %p", cb_list, msg, avp, sess, action, obj_app, obj_cmd, obj_avp, obj_enu); + CHECK_PARAMS(msg && action); + + senti = cb_list; + if (!senti) + senti = &any_handlers; + + for (li = senti->next; li != senti; li = li->next) { + struct disp_hdl * hdl = (struct disp_hdl *)(li->o); + + TRACE_DEBUG(ANNOYING, "when: %p %p %p %p", hdl->when.app, hdl->when.command, hdl->when.avp, hdl->when.value); + + /* Check this handler matches this message / avp */ + if (hdl->when.app && (hdl->when.app != obj_app)) + continue; + if (hdl->when.command && (hdl->when.command != obj_cmd)) + continue; + if (hdl->when.avp && (hdl->when.avp != obj_avp)) + continue; + if (hdl->when.value && (hdl->when.value != obj_enu)) + continue; + + /* We have a match, the cb must be called. */ + CHECK_FCT_DO( (r = (*hdl->cb)(msg, avp, sess, hdl->opaque, action)), + { + *drop_reason = "Internal error: a DISPATCH callback returned an error"; + *drop_msg = *msg; + *msg = NULL; + } + ); + + if (*action != DISP_ACT_CONT) + break; + + if ( *msg == NULL ) + break; + } + + /* We're done on this list */ + return 0; +} + +/**************************************************************************************/ + +/* Create a new handler and link it */ +int fd_disp_register ( int (*cb)( struct msg **, struct avp *, struct session *, void *, enum disp_action *), + enum disp_how how, struct disp_when * when, void * opaque, struct disp_hdl ** handle ) +{ + struct fd_list * cb_list = NULL; + struct disp_hdl * new; + struct dict_object * type_enum = NULL, * type_avp; + struct dictionary * dict = NULL; + + TRACE_ENTRY("%p %d %p %p", cb, how, when, handle); + CHECK_PARAMS( cb && ( (how == DISP_HOW_ANY) || when )); + + switch (how) { + case DISP_HOW_ANY: + cb_list = &any_handlers; + break; + + case DISP_HOW_APPID: + CHECK_FCT( fd_dict_disp_cb(DICT_APPLICATION, when->app, &cb_list) ); + break; + + case DISP_HOW_CC: + CHECK_FCT( fd_dict_disp_cb(DICT_COMMAND, when->command, &cb_list) ); + break; + + case DISP_HOW_AVP_ENUMVAL: + CHECK_FCT( fd_dict_disp_cb(DICT_ENUMVAL, when->value, &cb_list) ); /* cb_list is then overwritten */ + CHECK_FCT( fd_dict_getdict(when->value, &dict) ); + CHECK_FCT( fd_dict_search(dict, DICT_TYPE, TYPE_OF_ENUMVAL, when->value, &type_enum, EINVAL) ); + case DISP_HOW_AVP: + CHECK_FCT( fd_dict_disp_cb(DICT_AVP, when->avp, &cb_list) ); + if (dict) { + CHECK_FCT( fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, when->avp, &type_avp, EINVAL) ); + if (type_enum) { + CHECK_PARAMS( type_enum == type_avp ); + } + } + break; + + default: + CHECK_PARAMS(how = 0); + } + /* We might further check optional fields, but we trust the caller ^^ */ + + /* Create the new handler */ + CHECK_MALLOC( new = malloc( sizeof(struct disp_hdl) ) ); + memset(new, 0, sizeof(struct disp_hdl)); + new->eyec = DISP_EYEC; + fd_list_init(&new->all, new); + fd_list_init(&new->parent, new); + new->how = how; + switch (how) { + case DISP_HOW_ANY: + /* there is no "when" in that case */ + break; + case DISP_HOW_AVP_ENUMVAL: + new->when.value = when->value; + case DISP_HOW_AVP: + new->when.avp = when->avp; + case DISP_HOW_CC: + new->when.command = when->command; + case DISP_HOW_APPID: + new->when.app = when->app; + } + new->cb = cb; + new->opaque = opaque; + + /* Now, link this new element in the appropriate lists */ + CHECK_POSIX( pthread_rwlock_wrlock(&fd_disp_lock) ); + fd_list_insert_before(&all_handlers, &new->all); + fd_list_insert_before(cb_list, &new->parent); + CHECK_POSIX( pthread_rwlock_unlock(&fd_disp_lock) ); + + /* We're done */ + if (handle) + *handle = new; + + return 0; +} + +/* Delete a handler */ +int fd_disp_unregister ( struct disp_hdl ** handle, void ** opaque ) +{ + struct disp_hdl * del; + TRACE_ENTRY("%p", handle); + CHECK_PARAMS( handle && VALIDATE_HDL(*handle) ); + del = *handle; + *handle = NULL; + + CHECK_POSIX( pthread_rwlock_wrlock(&fd_disp_lock) ); + fd_list_unlink(&del->all); + fd_list_unlink(&del->parent); + CHECK_POSIX( pthread_rwlock_unlock(&fd_disp_lock) ); + + if (opaque) + *opaque = del->opaque; + + free(del); + return 0; +} + +/* Delete all handlers */ +void fd_disp_unregister_all ( void ) +{ + TRACE_ENTRY(""); + while (!FD_IS_LIST_EMPTY(&all_handlers)) { + CHECK_FCT_DO( fd_disp_unregister((void *)&(all_handlers.next->o), NULL), /* continue */ ); + } + return; +} diff --git a/plat/diameter/libfdproto/fdproto-internal.h b/plat/diameter/libfdproto/fdproto-internal.h new file mode 100644 index 0000000..60bdc36 --- /dev/null +++ b/plat/diameter/libfdproto/fdproto-internal.h @@ -0,0 +1,65 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* This file contains the definitions for internal use in the freeDiameter protocol library */ + +#ifndef _LIBFDPROTO_INTERNAL_H +#define _LIBFDPROTO_INTERNAL_H + +#include "freeDiameter-host.h" +#include "libfdproto.h" + +/* Internal to the library */ +extern const char * type_base_name[]; +void fd_msg_eteid_init(void); +int fd_sess_init(void); +void fd_sess_fini(void); + +/* Iterator on the rules of a parent object */ +int fd_dict_iterate_rules ( struct dict_object *parent, void * data, int (*cb)(void *, struct dict_rule_data *) ); + +/* Dispatch / messages / dictionary API */ +int fd_dict_disp_cb(enum dict_object_type type, struct dict_object *obj, struct fd_list ** cb_list); +DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_avp_value, union avp_value *avp_value, struct dict_object * model, int indent, int header); +int fd_disp_call_cb_int( struct fd_list * cb_list, struct msg ** msg, struct avp *avp, struct session *sess, enum disp_action *action, + struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu, + char ** drop_reason, struct msg ** drop_msg); +extern pthread_rwlock_t fd_disp_lock; + +/* Messages / sessions API */ +int fd_sess_reclaim_msg ( struct session ** session ); + + +#endif /* _LIBFDPROTO_INTERNAL_H */ diff --git a/plat/diameter/libfdproto/fifo.c b/plat/diameter/libfdproto/fifo.c new file mode 100644 index 0000000..b22e1bf --- /dev/null +++ b/plat/diameter/libfdproto/fifo.c @@ -0,0 +1,700 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* FIFO queues module. + * + * The threads that call these functions must be in the cancellation state PTHREAD_CANCEL_ENABLE and type PTHREAD_CANCEL_DEFERRED. + * This is the default state and type on thread creation. + * + * In order to destroy properly a queue, the application must: + * -> shutdown any process that can add into the queue first. + * -> pthread_cancel any thread that could be waiting on the queue. + * -> consume any element that is in the queue, using fd_qu_tryget_int. + * -> then destroy the queue using fd_mq_del. + */ + +#include "fdproto-internal.h" + +/* Definition of a FIFO queue object */ +struct fifo { + int eyec; /* An eye catcher, also used to check a queue is valid. FIFO_EYEC */ + + pthread_mutex_t mtx; /* Mutex protecting this queue */ + pthread_cond_t cond_pull; /* condition variable for pulling threads */ + pthread_cond_t cond_push; /* condition variable for pushing threads */ + + struct fd_list list; /* sentinel for the list of elements */ + int count; /* number of objects in the list */ + int thrs; /* number of threads waiting for a new element (when count is 0) */ + + int max; /* maximum number of items to accept if not 0 */ + int thrs_push; /* number of threads waitnig to push an item */ + + uint16_t high; /* High level threshold (see libfreeDiameter.h for details) */ + uint16_t low; /* Low level threshhold */ + void *data; /* Opaque pointer for threshold callbacks */ + void (*h_cb)(struct fifo *, void **); /* The callbacks */ + void (*l_cb)(struct fifo *, void **); + int highest;/* The highest count value for which h_cb has been called */ + int highest_ever; /* The max count value this queue has reached (for tweaking) */ + + long long total_items; /* Cumulated number of items that went through this fifo (excluding current count), always increasing. */ + struct timespec total_time; /* Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring) */ + struct timespec blocking_time; /* Cumulated time threads trying to post new items were blocked (queue full). */ + struct timespec last_time; /* For the last element retrieved from the queue, how long it take between posting (including blocking) and poping */ + +}; + +struct fifo_item { + struct fd_list item; + struct timespec posted_on; +}; + +/* The eye catcher value */ +#define FIFO_EYEC 0xe7ec1130 + +/* Macro to check a pointer */ +#define CHECK_FIFO( _queue ) (( (_queue) != NULL) && ( (_queue)->eyec == FIFO_EYEC) ) + + +/* Create a new queue, with max number of items -- use 0 for no max */ +int fd_fifo_new ( struct fifo ** queue, int max ) +{ + struct fifo * new; + + TRACE_ENTRY( "%p", queue ); + + CHECK_PARAMS( queue ); + + /* Create a new object */ + CHECK_MALLOC( new = malloc (sizeof (struct fifo) ) ); + + /* Initialize the content */ + memset(new, 0, sizeof(struct fifo)); + + new->eyec = FIFO_EYEC; + CHECK_POSIX( pthread_mutex_init(&new->mtx, NULL) ); + CHECK_POSIX( pthread_cond_init(&new->cond_pull, NULL) ); + CHECK_POSIX( pthread_cond_init(&new->cond_push, NULL) ); + new->max = max; + + fd_list_init(&new->list, NULL); + + /* We're done */ + *queue = new; + return 0; +} + +/* Dump the content of a queue */ +DECLARE_FD_DUMP_PROTOTYPE(fd_fifo_dump, char * name, struct fifo * queue, fd_fifo_dump_item_cb dump_item) +{ + FD_DUMP_HANDLE_OFFSET(); + + if (name) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(@%p): ", name, queue), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{fifo}(@%p): ", queue), return NULL); + } + + if (!CHECK_FIFO( queue )) { + return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL"); + } + + CHECK_POSIX_DO( pthread_mutex_lock( &queue->mtx ), /* continue */ ); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "items:%d,%d,%d threads:%d,%d stats:%lld/%ld.%06ld,%ld.%06ld,%ld.%06ld thresholds:%d,%d,%d,%p,%p,%p", + queue->count, queue->highest_ever, queue->max, + queue->thrs, queue->thrs_push, + queue->total_items,(long)queue->total_time.tv_sec,(long)(queue->total_time.tv_nsec/1000),(long)queue->blocking_time.tv_sec,(long)(queue->blocking_time.tv_nsec/1000),(long)queue->last_time.tv_sec,(long)(queue->last_time.tv_nsec/1000), + queue->high, queue->low, queue->highest, queue->h_cb, queue->l_cb, queue->data), + goto error); + + if (dump_item) { + struct fd_list * li; + int i = 0; + for (li = queue->list.next; li != &queue->list; li = li->next) { + struct fifo_item * fi = (struct fifo_item *)li; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n [#%i](@%p)@%ld.%06ld: ", + i++, fi->item.o, (long)fi->posted_on.tv_sec,(long)(fi->posted_on.tv_nsec/1000)), + goto error); + CHECK_MALLOC_DO( (*dump_item)(FD_DUMP_STD_PARAMS, fi->item.o), goto error); + } + } + CHECK_POSIX_DO( pthread_mutex_unlock( &queue->mtx ), /* continue */ ); + + return *buf; +error: + CHECK_POSIX_DO( pthread_mutex_unlock( &queue->mtx ), /* continue */ ); + return NULL; +} + +/* Delete a queue. It must be empty. */ +int fd_fifo_del ( struct fifo ** queue ) +{ + struct fifo * q; + int loops = 0; + + TRACE_ENTRY( "%p", queue ); + + CHECK_PARAMS( queue && CHECK_FIFO( *queue ) ); + + q = *queue; + + CHECK_POSIX( pthread_mutex_lock( &q->mtx ) ); + + if ((q->count != 0) || (q->data != NULL)) { + TRACE_DEBUG(INFO, "The queue cannot be destroyed (%d, %p)", q->count, q->data); + CHECK_POSIX_DO( pthread_mutex_unlock( &q->mtx ), /* no fallback */ ); + return EINVAL; + } + + /* Ok, now invalidate the queue */ + q->eyec = 0xdead; + + /* Have all waiting threads return an error */ + while (q->thrs) { + CHECK_POSIX( pthread_mutex_unlock( &q->mtx )); + CHECK_POSIX( pthread_cond_signal(&q->cond_pull) ); + usleep(1000); + + CHECK_POSIX( pthread_mutex_lock( &q->mtx ) ); + ASSERT( ++loops < 20 ); /* detect infinite loops */ + } + + /* sanity check */ + ASSERT(FD_IS_LIST_EMPTY(&q->list)); + + /* And destroy it */ + CHECK_POSIX( pthread_mutex_unlock( &q->mtx ) ); + + CHECK_POSIX_DO( pthread_cond_destroy( &q->cond_pull ), ); + + CHECK_POSIX_DO( pthread_cond_destroy( &q->cond_push ), ); + + CHECK_POSIX_DO( pthread_mutex_destroy( &q->mtx ), ); + + free(q); + *queue = NULL; + + return 0; +} + +/* Move the content of old into new, and update loc_update atomically. We leave the old queue empty but valid */ +int fd_fifo_move ( struct fifo * old, struct fifo * new, struct fifo ** loc_update ) +{ + int loops = 0; + + TRACE_ENTRY("%p %p %p", old, new, loc_update); + CHECK_PARAMS( CHECK_FIFO( old ) && CHECK_FIFO( new )); + + CHECK_PARAMS( ! old->data ); + if (new->high) { + TODO("Implement support for thresholds in fd_fifo_move..."); + } + + /* Update loc_update */ + if (loc_update) + *loc_update = new; + + /* Lock the queues */ + CHECK_POSIX( pthread_mutex_lock( &old->mtx ) ); + + CHECK_PARAMS_DO( (! old->thrs_push), { + pthread_mutex_unlock( &old->mtx ); + return EINVAL; + } ); + + CHECK_POSIX( pthread_mutex_lock( &new->mtx ) ); + + /* Any waiting thread on the old queue returns an error */ + old->eyec = 0xdead; + while (old->thrs) { + CHECK_POSIX( pthread_mutex_unlock( &old->mtx )); + CHECK_POSIX( pthread_cond_signal( &old->cond_pull ) ); + usleep(1000); + + CHECK_POSIX( pthread_mutex_lock( &old->mtx ) ); + ASSERT( loops < 20 ); /* detect infinite loops */ + } + + /* Move all data from old to new */ + fd_list_move_end( &new->list, &old->list ); + if (old->count && (!new->count)) { + CHECK_POSIX( pthread_cond_signal(&new->cond_pull) ); + } + new->count += old->count; + + /* Reset old */ + old->count = 0; + old->eyec = FIFO_EYEC; + + /* Merge the stats in the new queue */ + new->total_items += old->total_items; + old->total_items = 0; + + new->total_time.tv_nsec += old->total_time.tv_nsec; + new->total_time.tv_sec += old->total_time.tv_sec + (new->total_time.tv_nsec / 1000000000); + new->total_time.tv_nsec %= 1000000000; + old->total_time.tv_nsec = 0; + old->total_time.tv_sec = 0; + + new->blocking_time.tv_nsec += old->blocking_time.tv_nsec; + new->blocking_time.tv_sec += old->blocking_time.tv_sec + (new->blocking_time.tv_nsec / 1000000000); + new->blocking_time.tv_nsec %= 1000000000; + old->blocking_time.tv_nsec = 0; + old->blocking_time.tv_sec = 0; + + /* Unlock, we're done */ + CHECK_POSIX( pthread_mutex_unlock( &new->mtx ) ); + CHECK_POSIX( pthread_mutex_unlock( &old->mtx ) ); + + return 0; +} + +/* Get the information on the queue */ +int fd_fifo_getstats( struct fifo * queue, int * current_count, int * limit_count, int * highest_count, long long * total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last) +{ + TRACE_ENTRY( "%p %p %p %p %p %p %p %p", queue, current_count, limit_count, highest_count, total_count, total, blocking, last); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_FIFO( queue ) ); + + /* lock the queue */ + CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); + + if (current_count) + *current_count = queue->count; + + if (limit_count) + *limit_count = queue->max; + + if (highest_count) + *highest_count = queue->highest_ever; + + if (total_count) + *total_count = queue->total_items; + + if (total) + memcpy(total, &queue->total_time, sizeof(struct timespec)); + + if (blocking) + memcpy(blocking, &queue->blocking_time, sizeof(struct timespec)); + + if (last) + memcpy(last, &queue->last_time, sizeof(struct timespec)); + + /* Unlock */ + CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); + + /* Done */ + return 0; +} + + +/* alternate version with no error checking */ +int fd_fifo_length ( struct fifo * queue ) +{ + if ( !CHECK_FIFO( queue ) ) + return 0; + + return queue->count; /* Let's hope it's read atomically, since we are not locking... */ +} + +/* Set the thresholds of the queue */ +int fd_fifo_setthrhd ( struct fifo * queue, void * data, uint16_t high, void (*h_cb)(struct fifo *, void **), uint16_t low, void (*l_cb)(struct fifo *, void **) ) +{ + TRACE_ENTRY( "%p %p %hu %p %hu %p", queue, data, high, h_cb, low, l_cb ); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_FIFO( queue ) && (high > low) && (queue->data == NULL) ); + + /* lock the queue */ + CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); + + /* Save the values */ + queue->high = high; + queue->low = low; + queue->data = data; + queue->h_cb = h_cb; + queue->l_cb = l_cb; + + /* Unlock */ + CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); + + /* Done */ + return 0; +} + + +/* This handler is called when a thread is blocked on a queue, and cancelled */ +static void fifo_cleanup_push(void * queue) +{ + struct fifo * q = (struct fifo *)queue; + TRACE_ENTRY( "%p", queue ); + + /* The thread has been cancelled, therefore it does not wait on the queue anymore */ + q->thrs_push--; + + /* Now unlock the queue, and we're done */ + CHECK_POSIX_DO( pthread_mutex_unlock( &q->mtx ), /* nothing */ ); + + /* End of cleanup handler */ + return; +} + + +/* Post a new item in the queue */ +int fd_fifo_post_internal ( struct fifo * queue, void ** item, int skip_max ) +{ + struct fifo_item * new; + int call_cb = 0; + struct timespec posted_on, queued_on; + + /* Get the timing of this call */ + CHECK_SYS( clock_gettime(CLOCK_REALTIME, &posted_on) ); + + /* lock the queue */ + CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); + + if ((!skip_max) && (queue->max)) { + while (queue->count >= queue->max) { + int ret = 0; + + /* We have to wait for an item to be pulled */ + queue->thrs_push++ ; + pthread_cleanup_push( fifo_cleanup_push, queue); + ret = pthread_cond_wait( &queue->cond_push, &queue->mtx ); + pthread_cleanup_pop(0); + queue->thrs_push-- ; + + ASSERT( ret == 0 ); + } + } + + /* Create a new list item */ + CHECK_MALLOC_DO( new = malloc (sizeof (struct fifo_item)) , { + pthread_mutex_unlock( &queue->mtx ); + return ENOMEM; + } ); + + fd_list_init(&new->item, *item); + *item = NULL; + + /* Add the new item at the end */ + fd_list_insert_before( &queue->list, &new->item); + queue->count++; + if (queue->highest_ever < queue->count) + queue->highest_ever = queue->count; + if (queue->high && ((queue->count % queue->high) == 0)) { + call_cb = 1; + queue->highest = queue->count; + } + + /* store timing */ + memcpy(&new->posted_on, &posted_on, sizeof(struct timespec)); + + /* update queue timing info "blocking time" */ + { + long long blocked_ns; + CHECK_SYS( clock_gettime(CLOCK_REALTIME, &queued_on) ); + blocked_ns = (queued_on.tv_sec - posted_on.tv_sec) * 1000000000; + blocked_ns += (queued_on.tv_nsec - posted_on.tv_nsec); + blocked_ns += queue->blocking_time.tv_nsec; + queue->blocking_time.tv_sec += blocked_ns / 1000000000; + queue->blocking_time.tv_nsec = blocked_ns % 1000000000; + } + + /* Signal if threads are asleep */ + if (queue->thrs > 0) { + CHECK_POSIX( pthread_cond_signal(&queue->cond_pull) ); + } + if (queue->thrs_push > 0) { + /* cascade */ + CHECK_POSIX( pthread_cond_signal(&queue->cond_push) ); + } + + /* Unlock */ + CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); + + /* Call high-watermark cb as needed */ + if (call_cb && queue->h_cb) + (*queue->h_cb)(queue, &queue->data); + + /* Done */ + return 0; +} + +/* Post a new item in the queue */ +int fd_fifo_post_int ( struct fifo * queue, void ** item ) +{ + TRACE_ENTRY( "%p %p", queue, item ); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_FIFO( queue ) && item && *item ); + + return fd_fifo_post_internal ( queue,item, 0 ); + +} + +/* Post a new item in the queue, not blocking */ +int fd_fifo_post_noblock ( struct fifo * queue, void ** item ) +{ + TRACE_ENTRY( "%p %p", queue, item ); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_FIFO( queue ) && item && *item ); + + return fd_fifo_post_internal ( queue,item, 1 ); + +} + +/* Pop the first item from the queue */ +static void * mq_pop(struct fifo * queue) +{ + void * ret = NULL; + struct fifo_item * fi; + struct timespec now; + + ASSERT( ! FD_IS_LIST_EMPTY(&queue->list) ); + + fi = (struct fifo_item *)(queue->list.next); + ret = fi->item.o; + fd_list_unlink(&fi->item); + queue->count--; + queue->total_items++; + + /* Update the timings */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), goto skip_timing ); + { + long long elapsed = (now.tv_sec - fi->posted_on.tv_sec) * 1000000000; + elapsed += now.tv_nsec - fi->posted_on.tv_nsec; + + queue->last_time.tv_sec = elapsed / 1000000000; + queue->last_time.tv_nsec = elapsed % 1000000000; + + elapsed += queue->total_time.tv_nsec; + queue->total_time.tv_sec += elapsed / 1000000000; + queue->total_time.tv_nsec = elapsed % 1000000000; + } +skip_timing: + free(fi); + + if (queue->thrs_push) { + CHECK_POSIX_DO( pthread_cond_signal( &queue->cond_push ), ); + } + + return ret; +} + +/* Check if the low watermark callback must be called. */ +static __inline__ int test_l_cb(struct fifo * queue) +{ + if ((queue->high == 0) || (queue->low == 0) || (queue->l_cb == 0)) + return 0; + + if (((queue->count % queue->high) == queue->low) && (queue->highest > queue->count)) { + queue->highest -= queue->high; + return 1; + } + + return 0; +} + +/* Try poping an item */ +int fd_fifo_tryget_int ( struct fifo * queue, void ** item ) +{ + int wouldblock = 0; + int call_cb = 0; + + TRACE_ENTRY( "%p %p", queue, item ); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_FIFO( queue ) && item ); + + /* lock the queue */ + CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); + + /* Check queue status */ + if (queue->count > 0) { +got_item: + /* There are elements in the queue, so pick the first one */ + *item = mq_pop(queue); + call_cb = test_l_cb(queue); + } else { + if (queue->thrs_push > 0) { + /* A thread is trying to push something, let's give it a chance */ + CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); + CHECK_POSIX( pthread_cond_signal( &queue->cond_push ) ); + usleep(1000); + CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); + if (queue->count > 0) + goto got_item; + } + + wouldblock = 1; + *item = NULL; + } + + /* Unlock */ + CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); + + /* Call low watermark callback as needed */ + if (call_cb) + (*queue->l_cb)(queue, &queue->data); + + /* Done */ + return wouldblock ? EWOULDBLOCK : 0; +} + +/* This handler is called when a thread is blocked on a queue, and cancelled */ +static void fifo_cleanup(void * queue) +{ + struct fifo * q = (struct fifo *)queue; + TRACE_ENTRY( "%p", queue ); + + /* The thread has been cancelled, therefore it does not wait on the queue anymore */ + q->thrs--; + + /* Now unlock the queue, and we're done */ + CHECK_POSIX_DO( pthread_mutex_unlock( &q->mtx ), /* nothing */ ); + + /* End of cleanup handler */ + return; +} + +/* The internal function for fd_fifo_timedget and fd_fifo_get */ +static int fifo_tget ( struct fifo * queue, void ** item, int istimed, const struct timespec *abstime) +{ + int call_cb = 0; + int ret = 0; + + /* Check the parameters */ + CHECK_PARAMS( CHECK_FIFO( queue ) && item && (abstime || !istimed) ); + + /* Initialize the return value */ + *item = NULL; + + /* lock the queue */ + CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); + +awaken: + /* Check queue status */ + if (!CHECK_FIFO( queue )) { + /* The queue is being destroyed */ + CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); + TRACE_DEBUG(FULL, "The queue is being destroyed -> EPIPE"); + return EPIPE; + } + + if (queue->count > 0) { + /* There are items in the queue, so pick the first one */ + *item = mq_pop(queue); + call_cb = test_l_cb(queue); + } else { + /* We have to wait for a new item */ + queue->thrs++ ; + pthread_cleanup_push( fifo_cleanup, queue); + if (istimed) { + ret = pthread_cond_timedwait( &queue->cond_pull, &queue->mtx, abstime ); + } else { + ret = pthread_cond_wait( &queue->cond_pull, &queue->mtx ); + } + pthread_cleanup_pop(0); + queue->thrs-- ; + if (ret == 0) + goto awaken; /* test for spurious wake-ups */ + + /* otherwise (ETIMEDOUT / other error) just continue */ + } + + /* Unlock */ + CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); + + /* Call low watermark callback as needed */ + if (call_cb) + (*queue->l_cb)(queue, &queue->data); + + /* Done */ + return ret; +} + +/* Get the next available item, block until there is one */ +int fd_fifo_get_int ( struct fifo * queue, void ** item ) +{ + TRACE_ENTRY( "%p %p", queue, item ); + return fifo_tget(queue, item, 0, NULL); +} + +/* Get the next available item, block until there is one, or the timeout expires */ +int fd_fifo_timedget_int ( struct fifo * queue, void ** item, const struct timespec *abstime ) +{ + TRACE_ENTRY( "%p %p %p", queue, item, abstime ); + return fifo_tget(queue, item, 1, abstime); +} + +/* Test if data is available in the queue, without pulling it */ +int fd_fifo_select ( struct fifo * queue, const struct timespec *abstime ) +{ + int ret = 0; + TRACE_ENTRY( "%p %p", queue, abstime ); + + CHECK_PARAMS_DO( CHECK_FIFO( queue ), return -EINVAL ); + + /* lock the queue */ + CHECK_POSIX_DO( pthread_mutex_lock( &queue->mtx ), return -__ret__ ); + +awaken: + ret = (queue->count > 0 ) ? queue->count : 0; + if ((ret == 0) && (abstime != NULL)) { + /* We have to wait for a new item */ + queue->thrs++ ; + pthread_cleanup_push( fifo_cleanup, queue); + ret = pthread_cond_timedwait( &queue->cond_pull, &queue->mtx, abstime ); + pthread_cleanup_pop(0); + queue->thrs-- ; + if (ret == 0) + goto awaken; /* test for spurious wake-ups */ + + if (ret == ETIMEDOUT) + ret = 0; + else + ret = -ret; + } + + /* Unlock */ + CHECK_POSIX_DO( pthread_mutex_unlock( &queue->mtx ), return -__ret__ ); + + return ret; +} diff --git a/plat/diameter/libfdproto/init.c b/plat/diameter/libfdproto/init.c new file mode 100644 index 0000000..5c9bc5a --- /dev/null +++ b/plat/diameter/libfdproto/init.c @@ -0,0 +1,71 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" + +/* function to free the threadnames */ +static void freelogstr(void * str) { + if (TRACE_BOOL(ANNOYING)) { + if (str) { + fd_log_debug("(Thread '%s' terminating)", (char *)str); + } + } + free(str); +} + +/* Initialize library variables and threads */ +int fd_libproto_init() +{ + int ret = 0; + + /* Create the thread key that contains thread name for debug messages */ + ret = pthread_key_create(&fd_log_thname, freelogstr); + if (ret != 0) { + fprintf(stderr, "Error initializing the libfreeDiameter library: %s\n", strerror(ret) ); + return ret; + } + + /* Initialize the modules that need it */ + fd_msg_eteid_init(); + CHECK_FCT( fd_sess_init() ); + + return 0; +} + +/* Stop all threads created in the library */ +void fd_libproto_fini(void) +{ + fd_sess_fini(); +} diff --git a/plat/diameter/libfdproto/lists.c b/plat/diameter/libfdproto/lists.c new file mode 100644 index 0000000..1f185c4 --- /dev/null +++ b/plat/diameter/libfdproto/lists.c @@ -0,0 +1,169 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" + +/* Initialize a list element */ +void fd_list_init ( struct fd_list * list, void * obj ) +{ + memset(list, 0, sizeof(struct fd_list)); + list->next = list; + list->prev = list; + list->head = list; + list->o = obj; +} + +#define CHECK_SINGLE( li ) { \ + ASSERT( ((struct fd_list *)(li))->next == (li) ); \ + ASSERT( ((struct fd_list *)(li))->prev == (li) ); \ + ASSERT( ((struct fd_list *)(li))->head == (li) ); \ +} + +/* insert after a reference, checks done */ +static void list_insert_after( struct fd_list * ref, struct fd_list * item ) +{ + item->prev = ref; + item->next = ref->next; + item->head = ref->head; + ref->next->prev = item; + ref->next = item; +} + +/* insert after a reference */ +void fd_list_insert_after ( struct fd_list * ref, struct fd_list * item ) +{ + ASSERT(item != NULL); + ASSERT(ref != NULL); + CHECK_SINGLE ( item ); + ASSERT(ref->head != item); + list_insert_after(ref, item); +} + +/* Move all elements of list senti at the end of list ref */ +void fd_list_move_end(struct fd_list * ref, struct fd_list * senti) +{ + struct fd_list * li; + ASSERT(ref->head == ref); + ASSERT(senti->head == senti); + + if (senti->next == senti) + return; + + for (li = senti->next; li != senti; li = li->next) + li->head = ref; + + senti->next->prev = ref->prev; + ref->prev->next = senti->next; + senti->prev->next = ref; + ref->prev = senti->prev; + senti->prev = senti; + senti->next = senti; +} + +/* insert before a reference, checks done */ +static void list_insert_before ( struct fd_list * ref, struct fd_list * item ) +{ + item->prev = ref->prev; + item->next = ref; + item->head = ref->head; + ref->prev->next = item; + ref->prev = item; +} + +/* insert before a reference */ +void fd_list_insert_before ( struct fd_list * ref, struct fd_list * item ) +{ + ASSERT(item != NULL); + ASSERT(ref != NULL); + CHECK_SINGLE ( item ); + ASSERT(ref->head != item); + list_insert_before(ref, item); +} + +/* Insert an item in an ordered list -- ordering function provided. If duplicate object found, it is returned in ref_duplicate */ +int fd_list_insert_ordered( struct fd_list * head, struct fd_list * item, int (*cmp_fct)(void *, void *), void ** ref_duplicate) +{ + struct fd_list * ptr = head; + int cmp; + + /* Some debug sanity checks */ + ASSERT(head != NULL); + ASSERT(item != NULL); + ASSERT(cmp_fct != NULL); + ASSERT(head->head == head); + CHECK_SINGLE ( item ); + + /* loop in the list */ + while (ptr->next != head) + { + /* Compare the object to insert with the next object in list */ + cmp = cmp_fct( item->o, ptr->next->o ); + if (!cmp) { + /* An element with the same key already exists */ + if (ref_duplicate != NULL) + *ref_duplicate = ptr->next->o; + return EEXIST; + } + + if (cmp < 0) + break; /* We must insert the element here */ + + ptr = ptr->next; + } + + /* Now insert the element between ptr and ptr->next */ + list_insert_after( ptr, item ); + + + /* Ok */ + return 0; +} + +/* Unlink an object */ +void fd_list_unlink ( struct fd_list * item ) +{ + ASSERT(item != NULL); + if (item->head == item) + return; + /* unlink */ + item->next->prev = item->prev; + item->prev->next = item->next; + /* sanitize */ + item->next = item; + item->prev = item; + item->head = item; +} + + diff --git a/plat/diameter/libfdproto/log.c b/plat/diameter/libfdproto/log.c new file mode 100644 index 0000000..a847486 --- /dev/null +++ b/plat/diameter/libfdproto/log.c @@ -0,0 +1,325 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" + +#include + +pthread_mutex_t fd_log_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_key_t fd_log_thname; +int fd_g_debug_lvl = FD_LOG_NOTICE; // FD_LOG_NOTICE; + +static void fd_internal_logger( int, const char *, va_list ); +static int use_colors = 0; /* 0: not init, 1: yes, 2: no */ + +/* These may be used to pass specific debug requests via the command-line parameters */ +char * fd_debug_one_function = NULL; +char * fd_debug_one_file = NULL; + +/* Useless function, only to ease setting up a breakpoint in gdb (break fd_breakhere) -- use TRACE_HERE */ +int fd_breaks = 0; +int fd_breakhere(void) { return ++fd_breaks; } + +/* Allow passing of the log and debug information from base stack to extensions */ +void (*fd_logger)( int loglevel, const char * format, va_list args ) = fd_internal_logger; + +/* Register an external call back for tracing and debug */ +int fd_log_handler_register( void (*logger)(int loglevel, const char * format, va_list args) ) +{ + CHECK_PARAMS( logger ); + + if ( fd_logger != fd_internal_logger ) + { + return EALREADY; /* only one registration allowed */ + } + else + { + fd_logger = logger; + } + + return 0; +} + +/* Implement a simple reset function here */ +int fd_log_handler_unregister ( void ) +{ + fd_logger = fd_internal_logger; + return 0; /* Successfull in all cases. */ +} + +static void fd_cleanup_mutex_silent( void * mutex ) +{ + (void)pthread_mutex_unlock((pthread_mutex_t *)mutex); +} + + +static void fd_internal_logger( int printlevel, const char *format, va_list ap ) +{ + char buf[25]; + + /* Do we need to trace this ? */ + if (printlevel < fd_g_debug_lvl) + return; + + /* add timestamp */ + printf("%s ", fd_log_time(NULL, buf, sizeof(buf), +#if (defined(DEBUG) && defined(DEBUG_WITH_META)) + 1, 1 +#else /* (defined(DEBUG) && defined(DEBUG_WITH_META)) */ + 0, 0 +#endif /* (defined(DEBUG) && defined(DEBUG_WITH_META)) */ + )); + /* Use colors on stdout ? */ + if (!use_colors) { + if (isatty(STDOUT_FILENO)) + use_colors = 1; + else + use_colors = 2; + } + + switch(printlevel) { + case FD_LOG_ANNOYING: printf("%s A ", (use_colors == 1) ? "\e[0;37m" : ""); break; + case FD_LOG_DEBUG: printf("%s DBG ", (use_colors == 1) ? "\e[0;37m" : ""); break; + case FD_LOG_NOTICE: printf("%sNOTI ", (use_colors == 1) ? "\e[1;37m" : ""); break; + case FD_LOG_ERROR: printf("%sERROR ", (use_colors == 1) ? "\e[0;31m" : ""); break; + case FD_LOG_FATAL: printf("%sFATAL! ", (use_colors == 1) ? "\e[0;31m" : ""); break; + default: printf("%s ??? ", (use_colors == 1) ? "\e[0;31m" : ""); + } + vprintf(format, ap); + if (use_colors == 1) + printf("\e[00m"); + printf("\n"); + + fflush(stdout); +} + +/* Log a debug message */ +void fd_log ( int loglevel, const char * format, ... ) +{ + va_list ap; + + (void)pthread_mutex_lock(&fd_log_lock); + + pthread_cleanup_push(fd_cleanup_mutex_silent, &fd_log_lock); + + va_start(ap, format); + fd_logger(loglevel, format, ap); + va_end(ap); + + pthread_cleanup_pop(0); + + (void)pthread_mutex_unlock(&fd_log_lock); +} + +/* Log a debug message */ +void fd_log_va ( int loglevel, const char * format, va_list args ) +{ + (void)pthread_mutex_lock(&fd_log_lock); + + pthread_cleanup_push(fd_cleanup_mutex_silent, &fd_log_lock); + fd_logger(loglevel, format, args); + pthread_cleanup_pop(0); + + (void)pthread_mutex_unlock(&fd_log_lock); +} + +/* Function to set the thread's friendly name */ +void fd_log_threadname ( const char * name ) +{ + void * val = NULL; + + TRACE_ENTRY("%p(%s)", name, name?:"/"); + + /* First, check if a value is already assigned to the current thread */ + val = pthread_getspecific(fd_log_thname); + if (TRACE_BOOL(ANNOYING)) { + if (val) { + fd_log_debug("(Thread '%s' renamed to '%s')", (char *)val, name?:"(nil)"); + } else { + fd_log_debug("(Thread %p named '%s')", (void *)pthread_self(), name?:"(nil)"); + } + } + if (val != NULL) { + free(val); + } + + /* Now create the new string */ + if (name == NULL) { + CHECK_POSIX_DO( pthread_setspecific(fd_log_thname, NULL), /* continue */); + return; + } + + CHECK_MALLOC_DO( val = strdup(name), return ); + + CHECK_POSIX_DO( pthread_setspecific(fd_log_thname, val), /* continue */); + return; +} + +/* Write time into a buffer */ +char * fd_log_time ( struct timespec * ts, char * buf, size_t len, int incl_date, int incl_ms ) +{ + int ret; + size_t offset = 0; + struct timespec tp; + struct tm tm; + + /* Get current time */ + if (!ts) { + ret = clock_gettime(CLOCK_REALTIME, &tp); + if (ret != 0) { + snprintf(buf, len, "%s", strerror(ret)); + return buf; + } + ts = &tp; + } + + offset += strftime(buf + offset, len - offset, incl_date?"%D,%T":"%T", localtime_r( &ts->tv_sec , &tm )); + if (incl_ms) + offset += snprintf(buf + offset, len - offset, ".%6.6ld", ts->tv_nsec / 1000); + + return buf; +} + + +static size_t sys_mempagesz = 0; + +static size_t get_mempagesz(void) { + if (!sys_mempagesz) { + sys_mempagesz = sysconf(_SC_PAGESIZE); /* We alloc buffer by memory pages for efficiency. This can be readjusted if too memory consuming */ + if (sys_mempagesz <= 0) + sys_mempagesz = 256; /* default size if above call failed */ + } + return sys_mempagesz; +} + + +/* Helper function for fd_*_dump. Prints the format string from 'offset' into '*buf', extends if needed. The location of buf can be updated by this function. */ +char * fd_dump_extend(char ** buf, size_t *len, size_t *offset, const char * format, ... ) +{ + va_list ap; + int to_write; + size_t o = 0; + size_t mempagesz = get_mempagesz(); + + /* we do not TRACE_ENTRY this one on purpose */ + + CHECK_PARAMS_DO(buf && len, return NULL); + + if (*buf == NULL) { + CHECK_MALLOC_DO(*buf = malloc(mempagesz), return NULL); + *len = mempagesz; + } + + if (offset) + o = *offset; + + va_start(ap, format); + to_write = vsnprintf(*buf + o, *len - o, format, ap); + va_end(ap); + + if (to_write + o >= *len) { + /* There was no room in the buffer, we extend and redo */ + size_t new_len = (((to_write + o) / mempagesz) + 1) * mempagesz; + CHECK_MALLOC_DO(*buf = realloc(*buf, new_len), return NULL); + *len = new_len; + + va_start(ap, format); + to_write = vsnprintf(*buf + o, *len - o, format, ap); + va_end(ap); + } + + if (offset) + *offset += to_write; + + return *buf; +} + +char * fd_dump_extend_hexdump(char ** buf, size_t *len, size_t *offset, uint8_t *data, size_t datalen, size_t trunc, size_t wrap ) +{ + int truncated = 0; + size_t towrite = 0; + size_t o = 0; + int i; + char * p; + size_t mempagesz = get_mempagesz(); +#define TRUNK_MARK "[...]" + + CHECK_PARAMS_DO(buf && len && data, return NULL); + + if (trunc && (datalen > trunc)) { + datalen = trunc; + truncated = 1; + } + + towrite = datalen * 2; + + if (wrap) + towrite += datalen / wrap; /* add 1 '\n' every wrap byte */ + + if (truncated) + towrite += CONSTSTRLEN(TRUNK_MARK); + + + if (offset) + o = *offset; + + if (*buf == NULL) { + /* Directly allocate the size we need */ + *len = (((towrite + o) / mempagesz) + 1 ) * mempagesz; + CHECK_MALLOC_DO(*buf = malloc(*len), return NULL); + } else if ((towrite + o) >= *len) { + /* There is no room in the buffer, we extend and redo */ + size_t new_len = (((towrite + o) / mempagesz) + 1) * mempagesz; + CHECK_MALLOC_DO(*buf = realloc(*buf, new_len), return NULL); + *len = new_len; + } + + p = *buf + o; + for (i = 0; i < datalen; i++) { + sprintf(p, "%02hhX", data[i]); + p+=2; + if ((wrap) && ((i+1) % wrap == 0)) { + *p++='\n'; *p ='\0'; /* we want to ensure the buffer is always 0-terminated */ + } + } + + if (truncated) + memcpy(p, TRUNK_MARK, CONSTSTRLEN(TRUNK_MARK)); + + if (offset) + *offset += towrite; + + return *buf; +} diff --git a/plat/diameter/libfdproto/messages.c b/plat/diameter/libfdproto/messages.c new file mode 100644 index 0000000..96cb2e9 --- /dev/null +++ b/plat/diameter/libfdproto/messages.c @@ -0,0 +1,2869 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Messages module. + * + * This module allows to manipulate the msg and avp structures that represents a Diameter message in memory. + */ + +#include "fdproto-internal.h" + +#include + +/* Type of object */ +enum msg_objtype { + MSG_MSG = 1, + MSG_AVP +}; + +/* Chaining of elements as a free hierarchy */ +struct msg_avp_chain { + struct fd_list chaining; /* Chaining information at this level. */ + struct fd_list children; /* sentinel for the children of this object */ + enum msg_objtype type; /* Type of this object, _MSG_MSG or _MSG_AVP */ +}; + +/* Return the chain information from an AVP or MSG. Since it's the first field, we just cast */ +#define _C(_x) ((struct msg_avp_chain *)(_x)) + +/* Some details about chaining: + * + * A message is made of a header ( msg ) and 0 or more AVPs ( avp ). + * The structure is a kind of tree, where some AVPs (grouped AVPs) can contain other AVPs. + * Example: + * msg + * |-avp + * |-gavp + * | |-avp + * | |-avp + * | \-avp + * |-avp + * \-avp + * + * Each item (msg or avp) structure begins with a msg_avp_chain structure. + * The element at the top of the hierarchy (msg in our example) has all the fields of its "chaining" equal to the same value. + * + * All elements at the same level are linked by their "chaining" list. + * The "children" list is the sentinel for the lists of children of this element. + */ + +/* The following definitions are used to recognize objects in memory. */ +#define MSG_MSG_EYEC (0x11355463) +#define MSG_AVP_EYEC (0x11355467) + +/* The following structure represents an AVP instance. */ +struct avp { + struct msg_avp_chain avp_chain; /* Chaining information of this AVP */ + int avp_eyec; /* Must be equal to MSG_AVP_EYEC */ + struct dict_object *avp_model; /* If not NULL, pointer to the dictionary object of this avp */ + struct { + avp_code_t mnf_code; + vendor_id_t mnf_vendor; + } avp_model_not_found; /* When model resolution has failed, store a copy of the data here to avoid searching again */ + struct avp_hdr avp_public; /* AVP data that can be managed by other modules */ + + uint8_t *avp_source; /* If the message was parsed from a buffer, pointer to the AVP data start in the buffer. */ + uint8_t *avp_rawdata; /* when the data can not be interpreted, the raw data is copied here. The header is not part of it. */ + size_t avp_rawlen; /* The length of the raw buffer. */ + union avp_value avp_storage; /* To avoid many alloc/free, store the integer values here and set avp_public.avp_data to &storage */ + int avp_mustfreeos; /* 1 if an octetstring is malloc'd in avp_storage and must be freed. */ +}; + +/* Macro to compute the AVP header size */ +#define AVPHDRSZ_NOVEND 8 +#define AVPHDRSZ_VENDOR 12 +#define GETAVPHDRSZ( _flag ) ((_flag & AVP_FLAG_VENDOR) ? AVPHDRSZ_VENDOR : AVPHDRSZ_NOVEND) + +/* Macro to cast a msg_avp_t */ +#define _A(_x) ((struct avp *)(_x)) +/* Check the type and eyecatcher */ +#define CHECK_AVP(_x) ((_x) && (_C(_x)->type == MSG_AVP) && (_A(_x)->avp_eyec == MSG_AVP_EYEC)) + +/* The following structure represents an instance of a message (command and children AVPs). */ +struct msg { + struct msg_avp_chain msg_chain; /* List of the AVPs in the message */ + int msg_eyec; /* Must be equal to MSG_MSG_EYEC */ + struct dict_object *msg_model; /* If not NULL, pointer to the dictionary object of this message */ + struct { + command_code_t mnf_code; + uint8_t mnf_flags; + } msg_model_not_found; /* When model resolution has failed, store a copy of the data here to avoid searching again */ + struct msg_hdr msg_public; /* Message data that can be managed by extensions. */ + + uint8_t *msg_rawbuffer; /* data buffer that was received, saved during fd_msg_parse_buffer and freed in fd_msg_parse_dict */ + int msg_routable; /* Is this a routable message? (0: undef, 1: routable, 2: non routable) */ + struct msg *msg_query; /* the associated query if the message is a received answer */ + int msg_associated; /* and the counter part information in the query, to avoid double free */ + struct rt_data *msg_rtdata; /* Routing list for the query */ + struct session *msg_sess; /* Cached message session if any */ + struct { + void (*anscb)(void *, struct msg **); + void (*expirecb)(void *, DiamId_t, size_t, struct msg **); + void * data; + struct timespec timeout; + } msg_cb; /* Callback to be called when an answer is received, or timeout expires, if not NULL */ + DiamId_t msg_src_id; /* Diameter Id of the peer this message was received from. This string is malloc'd and must be freed */ + size_t msg_src_id_len; /* cached length of this string */ + struct fd_msg_pmdl msg_pmdl; /* list of permessagedata structures. */ +}; + +/* Macro to compute the message header size */ +#define GETMSGHDRSZ() 20 + +/* Macro to cast a msg_avp_t */ +#define _M(_x) ((struct msg *)(_x)) +/* Check the type and eyecatcher */ +#define CHECK_MSG(_x) ((_x) && (_C(_x)->type == MSG_MSG) && (_M(_x)->msg_eyec == MSG_MSG_EYEC)) + +#define VALIDATE_OBJ(_x) ( (CHECK_MSG(_x)) || (CHECK_AVP(_x)) ) + + +/* Macro to validate a MSGFL_ value */ +#define CHECK_AVPFL(_fl) ( ((_fl) & (- (AVPFL_MAX << 1) )) == 0 ) +#define CHECK_MSGFL(_fl) ( ((_fl) & (- (MSGFL_MAX << 1) )) == 0 ) + + +/* initial sizes of AVP from their types, in bytes. */ +static int avp_value_sizes[] = { + 0, /* AVP_TYPE_GROUPED: size is dynamic */ + 0, /* AVP_TYPE_OCTETSTRING: size is dynamic */ + 4, /* AVP_TYPE_INTEGER32: size is 32 bits */ + 8, /* AVP_TYPE_INTEGER64: size is 64 bits */ + 4, /* AVP_TYPE_UNSIGNED32: size is 32 bits */ + 8, /* AVP_TYPE_UNSIGNED64: size is 64 bits */ + 4, /* AVP_TYPE_FLOAT32: size is 32 bits */ + 8 /* AVP_TYPE_FLOAT64: size is 64 bits */ +}; +#define CHECK_BASETYPE( _type ) ( ((_type) <= AVP_TYPE_MAX) && ((_type) >= 0) ) +#define GETINITIALSIZE( _type, _vend ) (avp_value_sizes[ CHECK_BASETYPE(_type) ? (_type) : 0] + GETAVPHDRSZ(_vend)) + +/* Forward declaration */ +static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info); + +/***************************************************************************************************************/ +/* Creating objects */ + +/* Initialize a msg_avp_chain structure */ +static void init_chain(struct msg_avp_chain * chain, int type) +{ + fd_list_init( &chain->chaining, (void *)chain); + fd_list_init( &chain->children, (void *)chain); + chain->type = type; +} + +/* Initialize a new AVP object */ +static void init_avp ( struct avp * avp ) +{ + TRACE_ENTRY("%p", avp); + + memset(avp, 0, sizeof(struct avp)); + init_chain( &avp->avp_chain, MSG_AVP); + avp->avp_eyec = MSG_AVP_EYEC; +} + +/* Initialize a new MSG object */ +static void init_msg ( struct msg * msg ) +{ + TRACE_ENTRY("%p", msg); + + memset(msg, 0, sizeof(struct msg)); + init_chain( &msg->msg_chain, MSG_MSG); + msg->msg_eyec = MSG_MSG_EYEC; + + fd_list_init(&msg->msg_pmdl.sentinel, NULL); + CHECK_POSIX_DO( pthread_mutex_init(&msg->msg_pmdl.lock, NULL), ); +} + + +/* Create a new AVP instance */ +int fd_msg_avp_new ( struct dict_object * model, int flags, struct avp ** avp ) +{ + struct avp *new = NULL; + + TRACE_ENTRY("%p %x %p", model, flags, avp); + + /* Check the parameters */ + CHECK_PARAMS( avp && CHECK_AVPFL(flags) ); + + if (model) { + enum dict_object_type dicttype; + CHECK_PARAMS( (fd_dict_gettype(model, &dicttype) == 0) && (dicttype == DICT_AVP) ); + } + + /* Create a new object */ + CHECK_MALLOC( new = malloc (sizeof(struct avp)) ); + + /* Initialize the fields */ + init_avp(new); + + if (model) { + struct dict_avp_data dictdata; + + CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } ); + + new->avp_model = model; + new->avp_public.avp_code = dictdata.avp_code; + new->avp_public.avp_flags = dictdata.avp_flag_val; + new->avp_public.avp_len = GETINITIALSIZE(dictdata.avp_basetype, dictdata.avp_flag_val ); + new->avp_public.avp_vendor = dictdata.avp_vendor; + } + + if (flags & AVPFL_SET_BLANK_VALUE) { + new->avp_public.avp_value = &new->avp_storage; + } + + if (flags & AVPFL_SET_RAWDATA_FROM_AVP) { + new->avp_rawlen = (*avp)->avp_public.avp_len - GETAVPHDRSZ( (*avp)->avp_public.avp_flags ); + if (new->avp_rawlen) { + CHECK_MALLOC_DO( new->avp_rawdata = malloc(new->avp_rawlen), { free(new); return __ret__; } ); + memset(new->avp_rawdata, 0x00, new->avp_rawlen); + } + } + + /* The new object is ready, return */ + *avp = new; + return 0; +} + +/* Create a new message instance */ +int fd_msg_new ( struct dict_object * model, int flags, struct msg ** msg ) +{ + struct msg * new = NULL; + + TRACE_ENTRY("%p %x %p", model, flags, msg); + + /* Check the parameters */ + CHECK_PARAMS( msg && CHECK_MSGFL(flags) ); + + if (model) { + enum dict_object_type dicttype; + CHECK_PARAMS( (fd_dict_gettype(model, &dicttype) == 0) && (dicttype == DICT_COMMAND) ); + } + + /* Create a new object */ + CHECK_MALLOC( new = malloc (sizeof(struct msg)) ); + + /* Initialize the fields */ + init_msg(new); + new->msg_public.msg_version = DIAMETER_VERSION; + new->msg_public.msg_length = GETMSGHDRSZ(); /* This will be updated later */ + + if (model) { + struct dictionary *dict; + struct dict_cmd_data dictdata; + struct dict_object *dictappl; + + CHECK_FCT_DO( fd_dict_getdict(model, &dict), { free(new); return __ret__; } ); + CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } ); + + new->msg_model = model; + new->msg_public.msg_flags = dictdata.cmd_flag_val; + new->msg_public.msg_code = dictdata.cmd_code; + + /* Initialize application from the parent, if any */ + CHECK_FCT_DO( fd_dict_search( dict, DICT_APPLICATION, APPLICATION_OF_COMMAND, model, &dictappl, 0), { free(new); return __ret__; } ); + if (dictappl != NULL) { + struct dict_application_data appdata; + CHECK_FCT_DO( fd_dict_getval(dictappl, &appdata), { free(new); return __ret__; } ); + new->msg_public.msg_appl = appdata.application_id; + + LOG_D("fd_msg_new found appid:%d", appdata.application_id); + } + else + { + LOG_D("fd_msg_new not found"); + } + } + + if (flags & MSGFL_ALLOC_ETEID) { + new->msg_public.msg_eteid = fd_msg_eteid_get(); + } + + /* The new object is ready, return */ + *msg = new; + return 0; +} + +static int bufferize_avp(unsigned char * buffer, size_t buflen, size_t * offset, struct avp * avp); +static int parsebuf_list(unsigned char * buf, size_t buflen, struct fd_list * head); +static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info); + + +/* Create answer from a request */ +int fd_msg_new_answer_from_req ( struct dictionary * dict, struct msg ** msg, int flags ) +{ + struct dict_object * model = NULL; + struct msg *qry, *ans; + struct session * sess = NULL; + + TRACE_ENTRY("%p %x", msg, flags); + + /* Check the parameters */ + CHECK_PARAMS( msg ); + qry = *msg; + CHECK_PARAMS( CHECK_MSG(qry) && (qry->msg_public.msg_flags & CMD_FLAG_REQUEST) ); + + if (! (flags & MSGFL_ANSW_NOSID)) { + /* Get the session of the message */ + CHECK_FCT_DO( fd_msg_sess_get(dict, qry, &sess, NULL), /* ignore an error */ ); + } + + /* Find the model for the answer */ + if (flags & MSGFL_ANSW_ERROR) { + /* The model is the generic error format */ + CHECK_FCT( fd_dict_get_error_cmd(dict, &model) ); + } else { + /* The model is the answer corresponding to the query. It supposes that these are defined in the dictionary */ + CHECK_FCT_DO( parsedict_do_msg( dict, qry, 1, NULL), /* continue */ ); + if (qry->msg_model) { + CHECK_FCT( fd_dict_search ( dict, DICT_COMMAND, CMD_ANSWER, qry->msg_model, &model, EINVAL ) ); + } + } + + /* Create the answer */ + CHECK_FCT( fd_msg_new( model, flags, &ans ) ); + + /* Set informations in the answer as in the query */ + ans->msg_public.msg_code = qry->msg_public.msg_code; /* useful for MSGFL_ANSW_ERROR */ + ans->msg_public.msg_appl = qry->msg_public.msg_appl; + ans->msg_public.msg_eteid = qry->msg_public.msg_eteid; + ans->msg_public.msg_hbhid = qry->msg_public.msg_hbhid; + + /* Add the Session-Id AVP if session is known */ + if (sess && dict) { + static struct dict_object * sess_id_avp = NULL; + os0_t sid; + size_t sidlen; + struct avp * avp; + union avp_value val; + + if (!sess_id_avp) { + CHECK_FCT_DO( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT), { free(ans); return __ret__; } ); + } + CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), { free(ans); return __ret__; } ); + CHECK_FCT_DO( fd_msg_avp_new ( sess_id_avp, 0, &avp ), { free(ans); return __ret__; } ); + val.os.data = sid; + val.os.len = sidlen; + CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), { free(avp); free(ans); return __ret__; } ); + CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_FIRST_CHILD, avp ), { free(avp); free(ans); return __ret__; } ); + ans->msg_sess = sess; + CHECK_FCT_DO( fd_sess_ref_msg(sess), { free(ans); return __ret__; } ); + } + + /* Add all Proxy-Info AVPs from the query if any */ + if (! (flags & MSGFL_ANSW_NOPROXYINFO)) { + struct avp * avp; + struct fd_pei pei; + struct fd_list avpcpylist = FD_LIST_INITIALIZER(avpcpylist); + + CHECK_FCT_DO( fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL) , { free(ans); return __ret__; } ); + while (avp) { + if ( (avp->avp_public.avp_code == AC_PROXY_INFO) + && (avp->avp_public.avp_vendor == 0) ) { + /* We found a Proxy-Info, need to duplicate it in the answer */ + + /* In order to avoid dealing with all different possibilities of states, we just create a buffer then parse it */ + unsigned char * buf = NULL; + size_t offset = 0; + + /* Create a buffer with the content of the AVP. This is easier than going through the list */ + CHECK_FCT_DO( fd_msg_update_length(avp), { free(ans); return __ret__; } ); + CHECK_MALLOC_DO( buf = malloc(avp->avp_public.avp_len), { free(ans); return __ret__; } ); + CHECK_FCT_DO( bufferize_avp(buf, avp->avp_public.avp_len, &offset, avp), { free(buf); free(ans); return __ret__; } ); + + /* Now we parse this buffer to create a copy AVP */ + CHECK_FCT_DO( parsebuf_list(buf, avp->avp_public.avp_len, &avpcpylist), { free(buf); free(ans); return __ret__; } ); + + /* Parse dictionary objects now to remove the dependency on the buffer */ + CHECK_FCT_DO( parsedict_do_chain(dict, &avpcpylist, 0, &pei), { /* leaking the avpcpylist -- this should never happen anyway */ free(buf); free(ans); return __ret__; } ); + + /* Done for this AVP */ + free(buf); + + /* We move this AVP now so that we do not parse again in next loop */ + fd_list_move_end(&ans->msg_chain.children, &avpcpylist); + } + /* move to next AVP in the message, we can have several Proxy-Info instances */ + CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), { free(ans); return __ret__; } ); + } + } + + /* associate with query */ + ans->msg_query = qry; + qry->msg_associated = 1; + + /* Done */ + *msg = ans; + return 0; +} + +/***************************************************************************************************************/ + +/* Explore a message */ +int fd_msg_browse_internal ( msg_or_avp * reference, enum msg_brw_dir dir, msg_or_avp ** found, int * depth ) +{ + struct msg_avp_chain *result = NULL; + int diff = 0; + struct fd_list *li = NULL; + + TRACE_ENTRY("%p %d %p %p", reference, dir, found, depth); + + /* Initialize the "found" result if any */ + if (found) + *found = NULL; + + /* Check the parameters */ + CHECK_PARAMS( VALIDATE_OBJ(reference) ); + + TRACE_DEBUG(FCTS, "chaining(%p): nxt:%p prv:%p hea:%p top:%p", + &_C(reference)->chaining, + _C(reference)->chaining.next, + _C(reference)->chaining.prev, + _C(reference)->chaining.head, + _C(reference)->chaining.o); + TRACE_DEBUG(FCTS, "children(%p): nxt:%p prv:%p hea:%p top:%p", + &_C(reference)->children, + _C(reference)->children.next, + _C(reference)->children.prev, + _C(reference)->children.head, + _C(reference)->children.o); + + /* Now search */ + switch (dir) { + case MSG_BRW_NEXT: + /* Check the reference is an AVP */ + CHECK_PARAMS( _C(reference)->type == MSG_AVP ); + + li = &_C(reference)->chaining; + + /* Check if the next element is not the sentinel ( ==> the parent) */ + if (li->next != li->head) + result = _C(li->next->o); + break; + + case MSG_BRW_PREV: + /* Check the reference is an AVP */ + CHECK_PARAMS( _C(reference)->type == MSG_AVP ); + + li = &_C(reference)->chaining; + + /* Check if the prev element is not the sentinel ( ==> the parent) */ + if (li->prev != li->head) + result = _C(li->prev->o); + break; + + case MSG_BRW_FIRST_CHILD: + li = &_C(reference)->children; + if (! FD_IS_LIST_EMPTY(li)) { + result = _C(li->next->o); + diff = 1; + } + break; + + case MSG_BRW_LAST_CHILD: + li = &_C(reference)->children; + if (! FD_IS_LIST_EMPTY(li)) { + result = _C(li->prev->o); + diff = 1; + } + break; + + case MSG_BRW_PARENT: + /* If the object is not chained, it has no parent */ + li = &_C(reference)->chaining; + if (li != li->head) { + /* The sentinel is the parent's children list */ + result = _C(li->head->o); + diff = -1; + } + break; + + case MSG_BRW_WALK: + /* First, try to find a child */ + li = &_C(reference)->children; + if ( ! FD_IS_LIST_EMPTY(li) ) { + result = _C(li->next->o); + diff = 1; + break; + } + + /* Then try to find a "next" at this level or one of the parent's */ + li = &_C(reference)->chaining; + do { + /* If this element has a "next" element, return it */ + if (li->next != li->head) { + result = _C(li->next->o); + break; + } + /* otherwise, check if we have a parent */ + if (li == li->head) { + /* no parent */ + break; + } + /* Go to the parent's chaining information and loop */ + diff -= 1; + li = &_C(li->head->o)->chaining; + } while (1); + break; + + default: + /* Other directions are invalid */ + CHECK_PARAMS( dir = 0 ); + } + + /* Save the found object, if any */ + if (found && result) + *found = (void *)result; + + /* Modify the depth according to the walk direction */ + if (depth && diff) + (*depth) += diff; + + /* Return ENOENT if found was NULL */ + if ((!found) && (!result)) + return ENOENT; + else + return 0; +} + +/* Add an AVP into a tree */ +int fd_msg_avp_add ( msg_or_avp * reference, enum msg_brw_dir dir, struct avp *avp) +{ + TRACE_ENTRY("%p %d %p", reference, dir, avp); + + /* Check the parameters */ + CHECK_PARAMS( VALIDATE_OBJ(reference) && CHECK_AVP(avp) && FD_IS_LIST_EMPTY(&avp->avp_chain.chaining) ); + + /* Now insert */ + switch (dir) { + case MSG_BRW_NEXT: + /* Check the reference is an AVP -- we do not chain AVPs at same level as msgs. */ + CHECK_PARAMS( _C(reference)->type == MSG_AVP ); + + /* Insert the new avp after the reference */ + fd_list_insert_after( &_A(reference)->avp_chain.chaining, &avp->avp_chain.chaining ); + break; + + case MSG_BRW_PREV: + /* Check the reference is an AVP */ + CHECK_PARAMS( _C(reference)->type == MSG_AVP ); + + /* Insert the new avp before the reference */ + fd_list_insert_before( &_A(reference)->avp_chain.chaining, &avp->avp_chain.chaining ); + break; + + case MSG_BRW_FIRST_CHILD: + /* Insert the new avp after the children sentinel */ + fd_list_insert_after( &_C(reference)->children, &avp->avp_chain.chaining ); + break; + + case MSG_BRW_LAST_CHILD: + /* Insert the new avp before the children sentinel */ + fd_list_insert_before( &_C(reference)->children, &avp->avp_chain.chaining ); + break; + + default: + /* Other directions are invalid */ + CHECK_PARAMS( dir = 0 ); + } + + return 0; +} + +/* Search a given AVP model in a message */ +int fd_msg_search_avp ( struct msg * msg, struct dict_object * what, struct avp ** avp ) +{ + struct avp * nextavp; + struct dict_avp_data dictdata; + enum dict_object_type dicttype; + + TRACE_ENTRY("%p %p %p", msg, what, avp); + + CHECK_PARAMS( CHECK_MSG(msg) && what ); + + CHECK_PARAMS( (fd_dict_gettype(what, &dicttype) == 0) && (dicttype == DICT_AVP) ); + CHECK_FCT( fd_dict_getval(what, &dictdata) ); + + /* Loop on all top AVPs */ + CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) ); + while (nextavp) { + + if ( (nextavp->avp_public.avp_code == dictdata.avp_code) + && (nextavp->avp_public.avp_vendor == dictdata.avp_vendor) ) /* always 0 if no V flag */ + break; + + /* Otherwise move to next AVP in the message */ + CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) ); + } + + if (avp) + *avp = nextavp; + + if (avp && nextavp) { + struct dictionary * dict; + CHECK_FCT( fd_dict_getdict( what, &dict) ); + CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), /* nothing */ ); + } + + if (avp || nextavp) + return 0; + else + return ENOENT; +} + + +/***************************************************************************************************************/ +/* Deleting objects */ + +/* Destroy and free an AVP or message */ +static int destroy_obj (struct msg_avp_chain * obj ) +{ + TRACE_ENTRY("%p", obj); + + /* Check the parameter is a valid object */ + CHECK_PARAMS( VALIDATE_OBJ(obj) && FD_IS_LIST_EMPTY( &obj->children ) ); + + /* Unlink this object if needed */ + fd_list_unlink( &obj->chaining ); + + /* Free the octetstring if needed */ + if ((obj->type == MSG_AVP) && (_A(obj)->avp_mustfreeos == 1)) { + free(_A(obj)->avp_storage.os.data); + } + /* Free the rawdata if needed */ + if ((obj->type == MSG_AVP) && (_A(obj)->avp_rawdata != NULL)) { + free(_A(obj)->avp_rawdata); + } + if ((obj->type == MSG_MSG) && (_M(obj)->msg_rawbuffer != NULL)) { + free(_M(obj)->msg_rawbuffer); + } + + if ((obj->type == MSG_MSG) && (_M(obj)->msg_src_id != NULL)) { + free(_M(obj)->msg_src_id); + } + + if ((obj->type == MSG_MSG) && (_M(obj)->msg_rtdata != NULL)) { + fd_rtd_free(&_M(obj)->msg_rtdata); + } + + if ((obj->type == MSG_MSG) && (_M(obj)->msg_sess != NULL)) { + CHECK_FCT_DO( fd_sess_reclaim_msg ( &_M(obj)->msg_sess ), /* continue */); + } + + if ((obj->type == MSG_MSG) && (_M(obj)->msg_pmdl.sentinel.o != NULL)) { + ((void (*)(struct fd_msg_pmdl *))_M(obj)->msg_pmdl.sentinel.o)(&_M(obj)->msg_pmdl); + } + + /* free the object */ + free(obj); + + return 0; +} + +/* Destroy an object and all its children */ +static void destroy_tree(struct msg_avp_chain * obj) +{ + struct fd_list *rem; + + TRACE_ENTRY("%p", obj); + + /* Destroy any subtree */ + while ( (rem = obj->children.next) != &obj->children) + destroy_tree(_C(rem->o)); + + /* Then unlink and destroy the object */ + CHECK_FCT_DO( destroy_obj(obj), /* nothing */ ); +} + +/* Free an object and its tree */ +int fd_msg_free ( msg_or_avp * object ) +{ + TRACE_ENTRY("%p", object); + + if (object == NULL) + return 0; + + if (CHECK_MSG(object)) { + if (_M(object)->msg_query) { + _M(_M(object)->msg_query)->msg_associated = 0; + CHECK_FCT( fd_msg_free( _M(object)->msg_query ) ); + _M(object)->msg_query = NULL; + } else { + if (_M(object)->msg_associated) { + TRACE_DEBUG(INFO, "Not freeing query %p referenced in an answer (will be freed along the answer).", object); + return 0; + } + } + } + + destroy_tree(_C(object)); + return 0; +} + + +/***************************************************************************************************************/ +/* Debug functions: dumping */ + +/* messages and AVP formatters */ +typedef DECLARE_FD_DUMP_PROTOTYPE( (*msg_dump_formatter_msg), struct msg * msg ); +typedef DECLARE_FD_DUMP_PROTOTYPE( (*msg_dump_formatter_avp), struct avp * avp, int level, int first, int last ); + +/* Core function to process the dumping */ +static DECLARE_FD_DUMP_PROTOTYPE( msg_dump_process, msg_dump_formatter_msg msg_format, msg_dump_formatter_avp avp_format, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) +{ + FD_DUMP_HANDLE_OFFSET(); + + if (!VALIDATE_OBJ(obj)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE OR AVP @%p", obj), return NULL); + return *buf; + } + + if (force_parsing) { + (void) fd_msg_parse_dict(obj, dict, NULL); + } + + switch (_C(obj)->type) { + case MSG_AVP: + CHECK_MALLOC_DO( (*avp_format)(FD_DUMP_STD_PARAMS, (struct avp *)obj, 0, 1, 1), return NULL); + break; + + case MSG_MSG: + CHECK_MALLOC_DO( (*msg_format)(FD_DUMP_STD_PARAMS, (struct msg *)obj), return NULL); + break; + + default: + ASSERT(0); + free(*buf); + *buf = NULL; + return NULL; + } + + if (recurse) { + struct avp * avp = NULL; + int first = 1; + CHECK_FCT_DO( fd_msg_browse ( obj, MSG_BRW_FIRST_CHILD, &avp, NULL ), avp = NULL ); + while (avp) { + struct avp * nextavp = NULL; + CHECK_FCT_DO( fd_msg_browse ( avp, MSG_BRW_NEXT, &nextavp, NULL ), nextavp = NULL ); + CHECK_MALLOC_DO( (*avp_format)(FD_DUMP_STD_PARAMS, avp, 1, first, nextavp ? 0 : 1), return NULL); + avp = nextavp; + first = 0; + }; + } + + return *buf; +} + +/* + * Tree View message dump + */ +static DECLARE_FD_DUMP_PROTOTYPE( msg_format_treeview, struct msg * msg ) +{ + if (!CHECK_MSG(msg)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE"), return NULL); + return *buf; + } + + if (!msg->msg_model) { + if (msg->msg_model_not_found.mnf_code) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not found in dictionary)\n"), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not searched in dictionary)\n"), return NULL); + } + } else { + enum dict_object_type dicttype; + struct dict_cmd_data dictdata; + if (fd_dict_gettype(msg->msg_model, &dicttype) || (dicttype != DICT_COMMAND)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model information)\n"), return NULL); + } else if (fd_dict_getval(msg->msg_model, &dictdata)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(error getting model information)\n"), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'\n", dictdata.cmd_name), return NULL); + } + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Version: 0x%02hhX\n", msg->msg_public.msg_version), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Length: %d\n", msg->msg_public.msg_length), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Flags: 0x%02hhX (" DUMP_CMDFL_str ")\n", msg->msg_public.msg_flags, DUMP_CMDFL_val(msg->msg_public.msg_flags)), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Command Code: %u\n", msg->msg_public.msg_code), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " ApplicationId: %d\n", msg->msg_public.msg_appl), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Hop-by-Hop Identifier: 0x%08X\n", msg->msg_public.msg_hbhid), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " End-to-End Identifier: 0x%08X\n", msg->msg_public.msg_eteid), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {internal data}: src:%s(%zd) rwb:%p rt:%d cb:%p,%p(%p) qry:%p asso:%d sess:%p", msg->msg_src_id?:"(nil)", msg->msg_src_id_len, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.anscb, msg->msg_cb.expirecb, msg->msg_cb.data, msg->msg_query, msg->msg_associated, msg->msg_sess), return NULL); + + return *buf; +} + +static DECLARE_FD_DUMP_PROTOTYPE( avp_format_treeview, struct avp * avp, int level, int first, int last ) +{ + char * name; + struct dict_avp_data dictdata; + struct dict_avp_data *dictinfo = NULL; + struct dict_vendor_data vendordata; + struct dict_vendor_data *vendorinfo = NULL; + + if (level) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); + } + + if (!CHECK_AVP(avp)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID AVP"), return NULL); + return *buf; + } + + if (level) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*sAVP: ", level * 3, ""), return NULL); + } + + if (!avp->avp_model) { + if (avp->avp_model_not_found.mnf_code) { + name = "(not found in dictionary)"; + } else { + name = "(not searched in dictionary)"; + } + } else { + enum dict_object_type dicttype; + if (fd_dict_gettype(avp->avp_model, &dicttype) || (dicttype != DICT_AVP)) { + name = "(invalid model information)"; + } else if (fd_dict_getval(avp->avp_model, &dictdata)) { + name = "(error getting model information)"; + } else { + name = dictdata.avp_name; + dictinfo = &dictdata; + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + struct dictionary * dict; + struct dict_object * vendor; + if ((!fd_dict_getdict(avp->avp_model, &dict)) + && (!fd_dict_search(dict, DICT_VENDOR, VENDOR_OF_AVP, avp->avp_model, &vendor, ENOENT)) + && (!fd_dict_getval(vendor, &vendordata))) { + vendorinfo = &vendordata; + } + } + } + } + + if (dictinfo) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%u)", name, avp->avp_public.avp_code), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u%s", avp->avp_public.avp_code, name), return NULL); + } + + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + if (vendorinfo) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " vend='%s'(%u)", vendorinfo->vendor_name, avp->avp_public.avp_vendor), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " vend=%u", avp->avp_public.avp_vendor), return NULL); + } + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " l=%d f=" DUMP_AVPFL_str " val=", avp->avp_public.avp_len, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); + + if (dictinfo && (dictinfo->avp_basetype == AVP_TYPE_GROUPED)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(grouped)"), return NULL); + if (level) { + struct avp * inavp = NULL; + int first = 1; + CHECK_FCT_DO( fd_msg_browse ( avp, MSG_BRW_FIRST_CHILD, &inavp, NULL ), inavp = NULL ); + while (inavp) { + struct avp * nextavp = NULL; + CHECK_FCT_DO( fd_msg_browse ( inavp, MSG_BRW_NEXT, &nextavp, NULL ), inavp = NULL ); + CHECK_MALLOC_DO( avp_format_treeview(FD_DUMP_STD_PARAMS, inavp, level + 1, first, nextavp ? 0 : 1), return NULL); + inavp = nextavp; + first = 0; + }; + } + } else { + if (avp->avp_public.avp_value) { + CHECK_MALLOC_DO( fd_dict_dump_avp_value(FD_DUMP_STD_PARAMS, avp->avp_public.avp_value, avp->avp_model, 0, 0), return NULL); + } else if (avp->avp_rawdata) { + CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, avp->avp_rawdata, avp->avp_rawlen, 0, 0), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not set)"), return NULL); + } + } + + return *buf; +} + +/* multi-line human-readable dump similar to wireshark output */ +DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_treeview, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) +{ + return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_treeview, avp_format_treeview, obj, dict, force_parsing, recurse); +} + + +/* + * One-line dumper for compact but complete traces + */ +static DECLARE_FD_DUMP_PROTOTYPE( msg_format_full, struct msg * msg ) +{ + int success = 0; + struct dict_cmd_data dictdata; + + if (!CHECK_MSG(msg)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE"), return NULL); + return *buf; + } + + if (!msg->msg_model) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(no model) "), return NULL); + } else { + enum dict_object_type dicttype=0; + if (fd_dict_gettype(msg->msg_model, &dicttype) || (dicttype != DICT_COMMAND)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model %d) ", dicttype), return NULL); + } else if (fd_dict_getval(msg->msg_model, &dictdata)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(error getting model data) "), return NULL); + } else { + success = 1; + } + } + if (msg->msg_public.msg_appl) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, + "%s(%u/%u)[" DUMP_CMDFL_str "], Length=%u, Hop-By-Hop-Id=0x%08x, End-to-End=0x%08x", + success ? dictdata.cmd_name : "unknown", msg->msg_public.msg_appl, msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags), + msg->msg_public.msg_length, msg->msg_public.msg_hbhid, msg->msg_public.msg_eteid), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, + "%s(%u)[" DUMP_CMDFL_str "], Length=%u, Hop-By-Hop-Id=0x%08x, End-to-End=0x%08x", + success ? dictdata.cmd_name : "unknown", msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags), + msg->msg_public.msg_length, msg->msg_public.msg_hbhid, msg->msg_public.msg_eteid), return NULL); + } + return *buf; +} + +static DECLARE_FD_DUMP_PROTOTYPE( avp_format_full, struct avp * avp, int level, int first, int last ) +{ + int success = 0; + struct dict_avp_data dictdata; + + if (level) { + if ((first) && ((*buf)[*offset - 1] == '=')) { + /* We are first AVP of a grouped AVP */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{ "), return NULL); + } else { + /* We follow another AVP, or a message header */ + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ", { "), return NULL); + } + } + + if (!CHECK_AVP(avp)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID AVP"), return NULL); + goto end; + } + + + if (avp->avp_model) { + enum dict_object_type dicttype; + if (fd_dict_gettype(avp->avp_model, &dicttype) || (dicttype != DICT_AVP)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model: %d) ", dicttype), return NULL); + } else if (fd_dict_getval(avp->avp_model, &dictdata)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(error getting model data) "), return NULL); + } else { + success = 1; + } + } + + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s(%u/%u)[" DUMP_AVPFL_str "]=", + success ? dictdata.avp_name : "unknown", avp->avp_public.avp_vendor, avp->avp_public.avp_code, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s(%u)[" DUMP_AVPFL_str "]=", + success ? dictdata.avp_name : "unknown", avp->avp_public.avp_code, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); + } + + + if (success && (dictdata.avp_basetype == AVP_TYPE_GROUPED)) { + if (level) { + struct avp * inavp = NULL; + int first = 1; + CHECK_FCT_DO( fd_msg_browse ( avp, MSG_BRW_FIRST_CHILD, &inavp, NULL ), inavp = NULL ); + while (inavp) { + struct avp * nextavp = NULL; + CHECK_FCT_DO( fd_msg_browse ( inavp, MSG_BRW_NEXT, &nextavp, NULL ), inavp = NULL ); + CHECK_MALLOC_DO( avp_format_full(FD_DUMP_STD_PARAMS, inavp, level + 1, first, nextavp ? 0 : 1), return NULL); + inavp = nextavp; + first = 0; + }; + } + } else { + if (avp->avp_public.avp_value) { + CHECK_MALLOC_DO( fd_dict_dump_avp_value(FD_DUMP_STD_PARAMS, avp->avp_public.avp_value, avp->avp_model, 0, 0), return NULL); + } else if (avp->avp_rawdata) { + CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, avp->avp_rawdata, avp->avp_rawlen, 0, 0), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not set)"), return NULL); + } + } + +end: + if (level) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " }"), return NULL); + } + + return *buf; +} + +/* one-line dump with all the contents of the message */ +DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) +{ + return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_full, avp_format_full, obj, dict, force_parsing, recurse); +} + + + +/* + * One-line dumper for compact but complete traces + */ +static DECLARE_FD_DUMP_PROTOTYPE( msg_format_summary, struct msg * msg ) +{ + if (!CHECK_MSG(msg)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE"), return NULL); + return *buf; + } + + if (!msg->msg_model) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(no model)"), return NULL); + } else { + enum dict_object_type dicttype; + struct dict_cmd_data dictdata; + if (fd_dict_gettype(msg->msg_model, &dicttype) || (dicttype != DICT_COMMAND) || (fd_dict_getval(msg->msg_model, &dictdata))) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(model error)"), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'", dictdata.cmd_name), return NULL); + } + } + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u/%u f:" DUMP_CMDFL_str " src:'%s' len:%d", + msg->msg_public.msg_appl, msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags), msg->msg_src_id?:"(nil)", msg->msg_public.msg_length), return NULL); + + return *buf; +} + +static DECLARE_FD_DUMP_PROTOTYPE( avp_format_summary, struct avp * avp, int level, int first, int last ) +{ + char * name; + struct dict_avp_data dictdata; + struct dict_avp_data *dictinfo = NULL; + struct dict_vendor_data vendordata; + struct dict_vendor_data *vendorinfo = NULL; + + if (level) { + if (first) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {"), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ","), return NULL); + } + } + + if (!CHECK_AVP(avp)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID AVP"), return NULL); + goto end; + } + + if (!level) { + /* We have been called to explicitely dump this AVP, so we parse its name if available */ + if (!avp->avp_model) { + name = "(no model)"; + } else { + enum dict_object_type dicttype; + if (fd_dict_gettype(avp->avp_model, &dicttype) || (dicttype != DICT_AVP) || (fd_dict_getval(avp->avp_model, &dictdata))) { + name = "(model error)"; + } else { + name = dictdata.avp_name; + dictinfo = &dictdata; + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + struct dictionary * dict; + struct dict_object * vendor; + if ((!fd_dict_getdict(avp->avp_model, &dict)) + && (!fd_dict_search(dict, DICT_VENDOR, VENDOR_OF_AVP, avp->avp_model, &vendor, ENOENT)) + && (!fd_dict_getval(vendor, &vendordata))) { + vendorinfo = &vendordata; + } + } + } + } + + if (dictinfo) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%u)", name, avp->avp_public.avp_code), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u%s", avp->avp_public.avp_code, name), return NULL); + } + + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + if (vendorinfo) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " V='%s'(%u)", vendorinfo->vendor_name, avp->avp_public.avp_vendor), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " V=%u", avp->avp_public.avp_vendor), return NULL); + } + } + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " L=%d F=" DUMP_AVPFL_str " V=", avp->avp_public.avp_len, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); + + if ((!dictinfo) || (dictinfo->avp_basetype != AVP_TYPE_GROUPED)) { + if (avp->avp_public.avp_value) { + CHECK_MALLOC_DO( fd_dict_dump_avp_value(FD_DUMP_STD_PARAMS, avp->avp_public.avp_value, avp->avp_model, 0, 0), return NULL); + } else if (avp->avp_rawdata) { + CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, avp->avp_rawdata, avp->avp_rawlen, 0, 0), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not set)"), return NULL); + } + } + } else { + /* For embedded AVPs, we only display (vendor,) code & length */ + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "V:%u/", avp->avp_public.avp_vendor), return NULL); + } + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "C:%u/l:%d", avp->avp_public.avp_code, avp->avp_public.avp_len), return NULL); + } + +end: + if ((level) && (last)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "}"), return NULL); + } + + return *buf; +} + +/* This one only prints a short display, does not go into the complete tree */ +DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) +{ + return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_summary, avp_format_summary, obj, dict, force_parsing, recurse); +} + +/***************************************************************************************************************/ +/* Simple meta-data management */ + +/* Retrieve the model of an object */ +int fd_msg_model ( msg_or_avp * reference, struct dict_object ** model ) +{ + TRACE_ENTRY("%p %p", reference, model); + + /* Check the parameters */ + CHECK_PARAMS( model && VALIDATE_OBJ(reference) ); + + /* copy the model reference */ + switch (_C(reference)->type) { + case MSG_AVP: + *model = _A(reference)->avp_model; + break; + + case MSG_MSG: + *model = _M(reference)->msg_model; + break; + + default: + CHECK_PARAMS(0); + } + + return 0; +} + +/* Retrieve the address of the msg_public field of a message */ +int fd_msg_hdr ( struct msg *msg, struct msg_hdr **pdata ) +{ + TRACE_ENTRY("%p %p", msg, pdata); + if( ! (CHECK_MSG(msg) && pdata ) ) + { + //int a = 0; + } + CHECK_PARAMS( CHECK_MSG(msg) && pdata ); + + *pdata = &msg->msg_public; + return 0; +} + +/* Retrieve the address of the avp_public field of an avp */ +int fd_msg_avp_hdr ( struct avp *avp, struct avp_hdr **pdata ) +{ + TRACE_ENTRY("%p %p", avp, pdata); + CHECK_PARAMS( CHECK_AVP(avp) && pdata ); + + *pdata = &avp->avp_public; + return 0; +} + +/* Associate answers and queries */ +int fd_msg_answ_associate( struct msg * answer, struct msg * query ) +{ + TRACE_ENTRY( "%p %p", answer, query ); + + CHECK_PARAMS( CHECK_MSG(answer) && CHECK_MSG(query) && (answer->msg_query == NULL ) ); + + answer->msg_query = query; + query->msg_associated = 1; + + return 0; +} + +int fd_msg_answ_getq( struct msg * answer, struct msg ** query ) +{ + TRACE_ENTRY( "%p %p", answer, query ); + + CHECK_PARAMS( CHECK_MSG(answer) && query ); + + *query = answer->msg_query; + + return 0; +} + +int fd_msg_answ_detach( struct msg * answer ) +{ + TRACE_ENTRY( "%p", answer ); + + CHECK_PARAMS( CHECK_MSG(answer) ); + + answer->msg_query->msg_associated = 0; + answer->msg_query = NULL; + + return 0; +} + +/* Associate / get answer callbacks */ +int fd_msg_anscb_associate( struct msg * msg, void ( *anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ) +{ + TRACE_ENTRY("%p %p %p %p", msg, anscb, expirecb, data); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_MSG(msg) ); + + if (! (msg->msg_public.msg_flags & CMD_FLAG_REQUEST )) + return anscb ? EINVAL : 0; /* we associate with requests only */ + + CHECK_PARAMS( (anscb == NULL) || (msg->msg_cb.anscb == NULL) ); /* We are not overwriting a cb */ + CHECK_PARAMS( (expirecb == NULL) || (msg->msg_cb.expirecb == NULL) ); /* We are not overwriting a cb */ + + /* Associate callback and data with the message, if any */ + if (anscb) { + msg->msg_cb.anscb = anscb; + msg->msg_cb.data = data; + } + if (expirecb) { + msg->msg_cb.expirecb = expirecb; + if (timeout) { + memcpy(&msg->msg_cb.timeout, timeout, sizeof(struct timespec)); + } + } + + return 0; +} + +/* Remove a callback */ +int fd_msg_anscb_reset(struct msg * msg, int clear_anscb, int clear_expirecb) +{ + TRACE_ENTRY("%p %d %d", msg, clear_anscb, clear_expirecb); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_MSG(msg) ); + + if (clear_anscb) { + msg->msg_cb.anscb = NULL; + msg->msg_cb.data = NULL; + } + if (clear_expirecb) { + msg->msg_cb.expirecb = NULL; + memset(&msg->msg_cb.timeout, 0, sizeof(struct timespec)); + } + + return 0; +} + + +int fd_msg_anscb_get( struct msg * msg, void (**anscb)(void *, struct msg **), void (**expirecb)(void *, DiamId_t, size_t, struct msg **), void ** data ) +{ + TRACE_ENTRY("%p %p %p %p", msg, anscb, expirecb, data); + + /* Check the parameters */ + CHECK_PARAMS( CHECK_MSG(msg) ); + + /* Copy the result */ + if (anscb) + *anscb = msg->msg_cb.anscb; + if (data) + *data = msg->msg_cb.data; + if (expirecb) + *expirecb = msg->msg_cb.expirecb; + + return 0; +} + +struct timespec *fd_msg_anscb_gettimeout( struct msg * msg ) +{ + TRACE_ENTRY("%p", msg); + + /* Check the parameters */ + CHECK_PARAMS_DO( CHECK_MSG(msg), return NULL ); + + if (!msg->msg_cb.timeout.tv_sec) { + return NULL; + } + + return &msg->msg_cb.timeout; +} + +/* Associate routing lists */ +int fd_msg_rt_associate( struct msg * msg, struct rt_data * rtd ) +{ + TRACE_ENTRY( "%p %p", msg, rtd ); + + CHECK_PARAMS( CHECK_MSG(msg) && rtd ); + + msg->msg_rtdata = rtd; + + return 0; +} + +int fd_msg_rt_get( struct msg * msg, struct rt_data ** rtd ) +{ + TRACE_ENTRY( "%p %p", msg, rtd ); + + CHECK_PARAMS( CHECK_MSG(msg) && rtd ); + + *rtd = msg->msg_rtdata; + + return 0; +} + +/* Find if a message is routable */ +int fd_msg_is_routable ( struct msg * msg ) +{ + TRACE_ENTRY("%p", msg); + + CHECK_PARAMS_DO( CHECK_MSG(msg), return 0 /* pretend the message is not routable */ ); + + if ( ! msg->msg_routable ) { + /* To define if a message is routable, we rely on the "PXY" flag (for application 0). */ + msg->msg_routable = ((msg->msg_public.msg_appl != 0) || (msg->msg_public.msg_flags & CMD_FLAG_PROXIABLE)) ? 1 : 2; + + /* Note : the 'real' criteria according to the Diameter I-D is that the message is + routable if and only if the "Destination-Realm" AVP is required by the command ABNF. + We could make a test for this here, but it's more computational work and our test + seems accurate (until proven otherwise...) */ + } + + return (msg->msg_routable == 1) ? 1 : 0; +} + +/* cache the dictionary model for next function to avoid re-searching at every incoming message */ +static struct dict_object *cached_avp_rr_model = NULL; +static struct dictionary *cached_avp_rr_dict = NULL; +static pthread_mutex_t cached_avp_rr_lock = PTHREAD_MUTEX_INITIALIZER; + +/* Associate source peer */ +int fd_msg_source_set( struct msg * msg, DiamId_t diamid, size_t diamidlen ) +{ + TRACE_ENTRY( "%p %p %zd", msg, diamid, diamidlen); + + /* Check we received a valid message */ + CHECK_PARAMS( CHECK_MSG(msg) ); + + /* Cleanup any previous source */ + free(msg->msg_src_id); msg->msg_src_id = NULL; msg->msg_src_id_len = 0; + + /* If the request is to cleanup the source, we are done */ + if (diamid == NULL) { + return 0; + } + + /* Otherwise save the new informations */ + CHECK_MALLOC( msg->msg_src_id = os0dup(diamid, diamidlen) ); + msg->msg_src_id_len = diamidlen; + /* done */ + return 0; +} + +/* Associate source peer */ +int fd_msg_source_setrr( struct msg * msg, DiamId_t diamid, size_t diamidlen, struct dictionary * dict ) +{ + struct dict_object *avp_rr_model = NULL; + avp_code_t code = AC_ROUTE_RECORD; + struct avp *avp; + union avp_value val; + + TRACE_ENTRY( "%p %p %zd %p", msg, diamid, diamidlen, dict); + + /* Check we received a valid message */ + CHECK_PARAMS( CHECK_MSG(msg) && dict ); + + /* Lock the cached values */ + CHECK_POSIX( pthread_mutex_lock(&cached_avp_rr_lock) ); + if (cached_avp_rr_dict == dict) { + avp_rr_model = cached_avp_rr_model; + } + CHECK_POSIX( pthread_mutex_unlock(&cached_avp_rr_lock) ); + + /* If it was not cached */ + if (!avp_rr_model) { + /* Find the model for Route-Record in the dictionary */ + CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE, &code, &avp_rr_model, ENOENT) ); + + /* Now cache this result */ + CHECK_POSIX( pthread_mutex_lock(&cached_avp_rr_lock) ); + cached_avp_rr_dict = dict; + cached_avp_rr_model = avp_rr_model; + CHECK_POSIX( pthread_mutex_unlock(&cached_avp_rr_lock) ); + } + + /* Create the AVP with this model */ + CHECK_FCT( fd_msg_avp_new ( avp_rr_model, 0, &avp ) ); + + /* Set the AVP value with the diameter id */ + memset(&val, 0, sizeof(val)); + val.os.data = (uint8_t *)diamid; + val.os.len = diamidlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + + /* Add the AVP in the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); + + /* done */ + return 0; +} + +int fd_msg_source_get( struct msg * msg, DiamId_t* diamid, size_t * diamidlen ) +{ + TRACE_ENTRY( "%p %p %p", msg, diamid, diamidlen); + + /* Check we received valid parameters */ + CHECK_PARAMS( CHECK_MSG(msg) ); + CHECK_PARAMS( diamid ); + + /* Copy the informations */ + *diamid = msg->msg_src_id; + + if (diamidlen) + *diamidlen = msg->msg_src_id_len; + + /* done */ + return 0; +} + +/* Associate a session with a message, use only when the session was just created */ +int fd_msg_sess_set(struct msg * msg, struct session * session) +{ + TRACE_ENTRY("%p %p", msg, session); + + /* Check we received valid parameters */ + CHECK_PARAMS( CHECK_MSG(msg) ); + CHECK_PARAMS( session ); + CHECK_PARAMS( msg->msg_sess == NULL ); + + msg->msg_sess = session; + return 0; +} + + +/* Retrieve the session of the message */ +int fd_msg_sess_get(struct dictionary * dict, struct msg * msg, struct session ** session, int * new) +{ + struct avp * avp; + + TRACE_ENTRY("%p %p %p", msg, session, new); + + /* Check we received valid parameters */ + CHECK_PARAMS( CHECK_MSG(msg) ); + CHECK_PARAMS( session ); + + /* If we already resolved the session, just send it back */ + if (msg->msg_sess) { + *session = msg->msg_sess; + if (new) + *new = 0; + return 0; + } + + /* OK, we have to search for Session-Id AVP -- it is usually the first AVP, but let's be permissive here */ + /* -- note: we accept messages that have not yet been dictionary parsed... */ + CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) ); + while (avp) { + if ( (avp->avp_public.avp_code == AC_SESSION_ID) + && (avp->avp_public.avp_vendor == 0) ) + break; + + /* Otherwise move to next AVP in the message */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); + } + + if (!avp) { + TRACE_DEBUG(FULL, "No Session-Id AVP found in message %p", msg); + *session = NULL; + return 0; + } + + if (!avp->avp_model) { + CHECK_FCT( fd_msg_parse_dict ( avp, dict, NULL ) ); + } + + ASSERT( avp->avp_public.avp_value ); + + /* Resolve the session and we are done */ + if (avp->avp_public.avp_value->os.len > 0) { + CHECK_FCT( fd_sess_fromsid_msg ( avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len, &msg->msg_sess, new) ); + *session = msg->msg_sess; + } else { + TRACE_DEBUG(FULL, "Session-Id AVP with 0-byte length found in message %p", msg); + *session = NULL; + } + + return 0; +} + +/* Retrieve the location of the pmd list for the message; return NULL if failed */ +struct fd_msg_pmdl * fd_msg_pmdl_get(struct msg * msg) +{ + CHECK_PARAMS_DO( CHECK_MSG(msg), return NULL ); + return &msg->msg_pmdl; +} + + +/******************* End-to-end counter *********************/ +static uint32_t fd_eteid; +static pthread_mutex_t fd_eteid_lck = PTHREAD_MUTEX_INITIALIZER; + +void fd_msg_eteid_init(void) +{ + uint32_t t = (uint32_t)time(NULL); + srand48(t); + fd_eteid = (t << 20) | ((uint32_t)lrand48() & ( (1 << 20) - 1 )); +} + +uint32_t fd_msg_eteid_get ( void ) +{ + uint32_t ret; + + CHECK_POSIX_DO( pthread_mutex_lock(&fd_eteid_lck), /* continue */ ); + + ret = fd_eteid ++; + + CHECK_POSIX_DO( pthread_mutex_unlock(&fd_eteid_lck), /* continue */ ); + + return ret; +} + +/***************************************************************************************************************/ +/* Manage AVPs values */ + +/* Set the value of an AVP */ +int fd_msg_avp_setvalue ( struct avp *avp, union avp_value *value ) +{ + enum dict_avp_basetype type = -1; + + TRACE_ENTRY("%p %p", avp, value); + + /* Check parameter */ + CHECK_PARAMS( CHECK_AVP(avp) && avp->avp_model ); + + /* Retrieve information from the AVP model */ + { + enum dict_object_type dicttype; + struct dict_avp_data dictdata; + + CHECK_PARAMS( (fd_dict_gettype(avp->avp_model, &dicttype) == 0) && (dicttype == DICT_AVP) ); + CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); + type = dictdata.avp_basetype; + CHECK_PARAMS( type != AVP_TYPE_GROUPED ); + } + + /* First, clean any previous value */ + if (avp->avp_mustfreeos != 0) { + free(avp->avp_storage.os.data); + avp->avp_mustfreeos = 0; + } + + memset(&avp->avp_storage, 0, sizeof(union avp_value)); + + /* If the request was to delete a value: */ + if (!value) { + avp->avp_public.avp_value = NULL; + return 0; + } + + /* Now we have to set the value */ + memcpy(&avp->avp_storage, value, sizeof(union avp_value)); + + /* Duplicate an octetstring if needed. */ + if (type == AVP_TYPE_OCTETSTRING && value->os.data != NULL) { + CHECK_MALLOC( avp->avp_storage.os.data = os0dup(value->os.data, value->os.len) ); + avp->avp_mustfreeos = 1; + } + + /* Set the data pointer of the public part */ + avp->avp_public.avp_value = &avp->avp_storage; + + return 0; +} + +/* Set the value of an AVP, using formatted data */ +int fd_msg_avp_value_encode ( void *data, struct avp *avp ) +{ + enum dict_avp_basetype type = -1; + struct dict_type_data type_data; + + TRACE_ENTRY("%p %p", data, avp); + + /* Check parameter */ + CHECK_PARAMS( CHECK_AVP(avp) && avp->avp_model ); + + /* Retrieve information from the AVP model and it's parent type */ + { + enum dict_object_type dicttype; + struct dict_avp_data dictdata; + struct dictionary * dict; + struct dict_object * parenttype = NULL; + + /* First check the base type of the AVP */ + CHECK_PARAMS( (fd_dict_gettype(avp->avp_model, &dicttype) == 0) && (dicttype == DICT_AVP) ); + CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); + type = dictdata.avp_basetype; + CHECK_PARAMS( type != AVP_TYPE_GROUPED ); + + /* Then retrieve information about the parent's type (= derived type) */ + CHECK_FCT( fd_dict_getdict( avp->avp_model, &dict ) ); + CHECK_FCT( fd_dict_search( dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &parenttype, EINVAL) ); + CHECK_FCT( fd_dict_getval(parenttype, &type_data) ); + if (type_data.type_encode == NULL) { + TRACE_DEBUG(INFO, "This AVP type does not provide a callback to encode formatted data. ENOTSUP."); + return ENOTSUP; + } + } + + /* Ok, now we can encode the value */ + + /* First, clean any previous value */ + if (avp->avp_mustfreeos != 0) { + free(avp->avp_storage.os.data); + avp->avp_mustfreeos = 0; + } + avp->avp_public.avp_value = NULL; + memset(&avp->avp_storage, 0, sizeof(union avp_value)); + + /* Now call the type's callback to encode the data */ + CHECK_FCT( (*type_data.type_encode)(data, &avp->avp_storage) ); + + /* If an octetstring has been allocated, let's mark it to be freed */ + if (type == AVP_TYPE_OCTETSTRING) + avp->avp_mustfreeos = 1; + + /* Set the data pointer of the public part */ + avp->avp_public.avp_value = &avp->avp_storage; + + return 0; +} + +/* Interpret the value of an AVP into formatted data */ +int fd_msg_avp_value_interpret ( struct avp *avp, void *data ) +{ + struct dict_type_data type_data; + + TRACE_ENTRY("%p %p", avp, data); + + /* Check parameter */ + CHECK_PARAMS( CHECK_AVP(avp) && avp->avp_model && avp->avp_public.avp_value ); + + /* Retrieve information about the AVP parent type */ + { + struct dictionary * dict; + struct dict_object * parenttype = NULL; + + CHECK_FCT( fd_dict_getdict( avp->avp_model, &dict ) ); + CHECK_FCT( fd_dict_search( dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &parenttype, EINVAL) ); + CHECK_FCT( fd_dict_getval(parenttype, &type_data) ); + if (type_data.type_interpret == NULL) { + TRACE_DEBUG(INFO, "This AVP type does not provide a callback to interpret value in formatted data. ENOTSUP."); + return ENOTSUP; + } + } + + /* Ok, now we can interpret the value */ + + CHECK_FCT( (*type_data.type_interpret)(avp->avp_public.avp_value, data) ); + + return 0; +} + +/***************************************************************************************************************/ +/* Creating a buffer from memory objects (bufferize a struct msg) */ + +/* Following macros are used to store 32 and 64 bit fields into a buffer in network byte order */ +#define PUT_in_buf_32( _u32data, _bufptr ) { \ + *(uint32_t *)(_bufptr) = htonl((uint32_t)(_u32data)); \ +} + +/* The location is not on 64b boundary, so we split the writing in two operations to avoid sigbus */ +#define PUT_in_buf_64( _u64data, _bufptr ) { \ + uint64_t __v = htonll((uint64_t)(_u64data)); \ + memcpy(_bufptr, &__v, sizeof(__v)); \ +} + +/* Write a message header in the buffer */ +static int bufferize_msg(unsigned char * buffer, size_t buflen, size_t * offset, struct msg * msg) +{ + TRACE_ENTRY("%p %zd %p %p", buffer, buflen, offset, msg); + + if ((buflen - *offset) < GETMSGHDRSZ()) + return ENOSPC; + + if (*offset & 0x3) + return EFAULT; /* We are supposed to start on 32 bit boundaries */ + + PUT_in_buf_32(msg->msg_public.msg_length, buffer + *offset); + buffer[*offset] = msg->msg_public.msg_version; + *offset += 4; + + PUT_in_buf_32(msg->msg_public.msg_code, buffer + *offset); + buffer[*offset] = msg->msg_public.msg_flags; + *offset += 4; + + PUT_in_buf_32(msg->msg_public.msg_appl, buffer + *offset); + *offset += 4; + + PUT_in_buf_32(msg->msg_public.msg_hbhid, buffer + *offset); + *offset += 4; + + PUT_in_buf_32(msg->msg_public.msg_eteid, buffer + *offset); + *offset += 4; + + return 0; +} + +static int bufferize_chain(unsigned char * buffer, size_t buflen, size_t * offset, struct fd_list * list); + +/* Write an AVP in the buffer */ +static int bufferize_avp(unsigned char * buffer, size_t buflen, size_t * offset, struct avp * avp) +{ + struct dict_avp_data dictdata; + + TRACE_ENTRY("%p %zd %p %p", buffer, buflen, offset, avp); + + if ((buflen - *offset) < avp->avp_public.avp_len) + return ENOSPC; + + /* Write the header */ + PUT_in_buf_32(avp->avp_public.avp_code, buffer + *offset); + *offset += 4; + + PUT_in_buf_32(avp->avp_public.avp_len, buffer + *offset); + buffer[*offset] = avp->avp_public.avp_flags; + *offset += 4; + + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + PUT_in_buf_32(avp->avp_public.avp_vendor, buffer + *offset); + *offset += 4; + } + + /* Then we must write the AVP value */ + + if (avp->avp_model == NULL) { + /* In the case where we don't know the type of AVP, just copy the raw data or source */ + CHECK_PARAMS( avp->avp_source || avp->avp_rawdata ); + + if ( avp->avp_rawdata != NULL ) { + /* the content was stored in rawdata */ + memcpy(&buffer[*offset], avp->avp_rawdata, avp->avp_rawlen); + *offset += PAD4(avp->avp_rawlen); + } else { + /* the message was not parsed completely */ + size_t datalen = avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags); + memcpy(&buffer[*offset], avp->avp_source, datalen); + *offset += PAD4(datalen); + } + + } else { + /* The AVP is defined in the dictionary */ + CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); + + CHECK_PARAMS( ( dictdata.avp_basetype == AVP_TYPE_GROUPED ) || avp->avp_public.avp_value ); + + switch (dictdata.avp_basetype) { + case AVP_TYPE_GROUPED: + return bufferize_chain(buffer, buflen, offset, &avp->avp_chain.children); + + case AVP_TYPE_OCTETSTRING: + if (avp->avp_public.avp_value->os.len) + memcpy(&buffer[*offset], avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len); + *offset += PAD4(avp->avp_public.avp_value->os.len); + break; + + case AVP_TYPE_INTEGER32: + PUT_in_buf_32(avp->avp_public.avp_value->i32, buffer + *offset); + *offset += 4; + break; + + case AVP_TYPE_INTEGER64: + PUT_in_buf_64(avp->avp_public.avp_value->i64, buffer + *offset); + *offset += 8; + break; + + case AVP_TYPE_UNSIGNED32: + PUT_in_buf_32(avp->avp_public.avp_value->u32, buffer + *offset); + *offset += 4; + break; + + case AVP_TYPE_UNSIGNED64: + PUT_in_buf_64(avp->avp_public.avp_value->u64, buffer + *offset); + *offset += 8; + break; + + case AVP_TYPE_FLOAT32: + /* We read the f32 as "u32" here to avoid casting to uint make decimals go away. + The alternative would be something like "*(uint32_t *)(& f32)" but + then the compiler complains about strict-aliasing rules. */ + PUT_in_buf_32(avp->avp_public.avp_value->u32, buffer + *offset); + *offset += 4; + break; + + case AVP_TYPE_FLOAT64: + /* Same remark as previously */ + PUT_in_buf_64(avp->avp_public.avp_value->u64, buffer + *offset); + *offset += 8; + break; + + default: + ASSERT(0); + } + } + return 0; +} + +/* Write a chain of AVPs in the buffer */ +static int bufferize_chain(unsigned char * buffer, size_t buflen, size_t * offset, struct fd_list * list) +{ + struct fd_list * avpch; + + TRACE_ENTRY("%p %zd %p %p", buffer, buflen, offset, list); + + for (avpch = list->next; avpch != list; avpch = avpch->next) { + /* Bufferize the AVP */ + CHECK_FCT( bufferize_avp(buffer, buflen, offset, _A(avpch->o)) ); + } + return 0; +} + +/* Create the message buffer, in network-byte order. We browse the tree twice, this could be probably improved if needed */ +int fd_msg_bufferize ( struct msg * msg, unsigned char ** buffer, size_t * len ) +{ + int ret = 0; + unsigned char * buf = NULL; + size_t offset = 0; + + TRACE_ENTRY("%p %p %p", msg, buffer, len); + + /* Check the parameters */ + CHECK_PARAMS( buffer && CHECK_MSG(msg) ); + + /* Update the length. This also checks that all AVP have their values set */ + CHECK_FCT( fd_msg_update_length(msg) ); + + /* Now allocate a buffer to store the message */ + CHECK_MALLOC( buf = malloc(msg->msg_public.msg_length) ); + + /* Clear the memory, so that the padding is always 0 (should not matter) */ + memset(buf, 0, msg->msg_public.msg_length); + + /* Write the message header in the buffer */ + CHECK_FCT_DO( ret = bufferize_msg(buf, msg->msg_public.msg_length, &offset, msg), + { + free(buf); + return ret; + } ); + + /* Write the list of AVPs */ + CHECK_FCT_DO( ret = bufferize_chain(buf, msg->msg_public.msg_length, &offset, &msg->msg_chain.children), + { + free(buf); + return ret; + } ); + + ASSERT(offset == msg->msg_public.msg_length); /* or the msg_update_length is buggy */ + + if (len) { + *len = offset; + } + + *buffer = buf; + return 0; +} + + +/***************************************************************************************************************/ +/* Parsing buffers and building AVP objects lists (not parsing the AVP values which requires dictionary knowledge) */ + +/* Parse a buffer containing a supposed list of AVPs */ +static int parsebuf_list(unsigned char * buf, size_t buflen, struct fd_list * head) +{ + size_t offset = 0; + + TRACE_ENTRY("%p %zd %p", buf, buflen, head); + + while (offset < buflen) { + struct avp * avp; + + if (buflen - offset < AVPHDRSZ_NOVEND) { + TRACE_DEBUG(INFO, "truncated buffer: remaining only %zd bytes", buflen - offset); + return EBADMSG; + } + + /* Create a new AVP object */ + CHECK_MALLOC( avp = malloc (sizeof(struct avp)) ); + + init_avp(avp); + + /* Initialize the header */ + avp->avp_public.avp_code = ntohl(*(uint32_t *)(buf + offset)); + avp->avp_public.avp_flags = buf[offset + 4]; + avp->avp_public.avp_len = ((uint32_t)buf[offset+5]) << 16 | ((uint32_t)buf[offset+6]) << 8 | ((uint32_t)buf[offset+7]) ; + + offset += 8; + + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + if (buflen - offset < 4) { + TRACE_DEBUG(INFO, "truncated buffer: remaining only %zd bytes for vendor and data", buflen - offset); + free(avp); + return EBADMSG; + } + avp->avp_public.avp_vendor = ntohl(*(uint32_t *)(buf + offset)); + offset += 4; + } + + /* Check there is enough remaining data in the buffer */ + if ( (avp->avp_public.avp_len > GETAVPHDRSZ(avp->avp_public.avp_flags)) + && (buflen - offset < avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags))) { + TRACE_DEBUG(INFO, "truncated buffer: remaining only %zd bytes for data, and avp data size is %d", + buflen - offset, + avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)); + free(avp); + return EBADMSG; + } + + /* buf[offset] is now the beginning of the data */ + avp->avp_source = &buf[offset]; + + /* Now eat the data and eventual padding */ + offset += PAD4(avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)); + + LOG_D("parse avp first level avp_code:%d flag:%d len:%d vendor_id:%d", + avp->avp_public.avp_code, + avp->avp_public.avp_flags, + avp->avp_public.avp_len, + avp->avp_public.avp_vendor); + + /* And insert this avp in the list, at the end */ + fd_list_insert_before( head, &avp->avp_chain.chaining ); + } + + return 0; +} + +/* Create a message object from a buffer. Dictionary objects are not resolved, AVP contents are not interpreted, buffer is saved in msg */ +int fd_msg_parse_buffer ( unsigned char ** buffer, size_t buflen, struct msg ** msg ) +{ + struct msg * new = NULL; + int ret = 0; + uint32_t msglen = 0; + unsigned char * buf; + + TRACE_ENTRY("%p %zd %p", buffer, buflen, msg); + + CHECK_PARAMS( buffer && *buffer && msg && (buflen >= GETMSGHDRSZ()) ); + buf = *buffer; + + if ( buf[0] != DIAMETER_VERSION) { + TRACE_DEBUG(INFO, "Invalid version in message: %d (supported: %d)", buf[0], DIAMETER_VERSION); + return EBADMSG; + } + + msglen = ntohl(*(uint32_t *)buf) & 0x00ffffff; + if ( buflen < msglen ) { + TRACE_DEBUG(INFO, "Truncated message (%zd / %d)", buflen, msglen ); + return EBADMSG; + } + + /* Create a new object */ + CHECK_MALLOC( new = malloc (sizeof(struct msg)) ); + + /* Initialize the fields */ + init_msg(new); + + /* Now read from the buffer */ + new->msg_public.msg_version = buf[0]; + new->msg_public.msg_length = msglen; + + new->msg_public.msg_flags = buf[4]; + new->msg_public.msg_code = ntohl(*(uint32_t *)(buf+4)) & 0x00ffffff; + + new->msg_public.msg_appl = ntohl(*(uint32_t *)(buf+8)); + new->msg_public.msg_hbhid = ntohl(*(uint32_t *)(buf+12)); + new->msg_public.msg_eteid = ntohl(*(uint32_t *)(buf+16)); + + /* Parse the AVP list */ + CHECK_FCT_DO( ret = parsebuf_list(buf + GETMSGHDRSZ(), buflen - GETMSGHDRSZ(), &new->msg_chain.children), { destroy_tree(_C(new)); return ret; } ); + + /* Parsing successful */ + new->msg_rawbuffer = buf; + *buffer = NULL; + *msg = new; + return 0; +} + + +/***************************************************************************************************************/ +/* Parsing messages and AVP with dictionary information */ + +/* Resolve dictionary objects of the cmd and avp instances, from their headers. + * When the model is found, the data is interpreted from the avp_source buffer and copied to avp_storage. + * When the model is not found, the data is copied as rawdata and saved (in case we FW the message). + * Therefore, after this function has been called, the source buffer can be freed. + * For command, if the dictionary model is not found, an error is returned. + */ + +static char error_message[256]; + +/* Process an AVP. If we are not in recheck, the avp_source must be set. */ +static int parsedict_do_avp(struct dictionary * dict, struct avp * avp, int mandatory, struct fd_pei *error_info) +{ + struct dict_avp_data dictdata; + struct dict_type_data derivedtypedata; + struct dict_object * avp_derived_type = NULL; + uint8_t * source; + + TRACE_ENTRY("%p %p %d %p", dict, avp, mandatory, error_info); + + /* First check we received an AVP as input */ + CHECK_PARAMS( CHECK_AVP(avp) ); + + if (avp->avp_model != NULL) { + /* the model has already been resolved. we do check it is still valid */ + + CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); + + if ( avp->avp_public.avp_code == dictdata.avp_code ) { + /* Ok then just process the children if any */ + return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY), error_info); + } else { + /* We just erase the old model */ + avp->avp_model = NULL; + } + } + + /* Check if we already searched for this model without success */ + if ((avp->avp_model_not_found.mnf_code != avp->avp_public.avp_code) + || (avp->avp_model_not_found.mnf_vendor != avp->avp_public.avp_vendor)) { + + /* Now try and resolve the model from the avp code and vendor */ + if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { + struct dict_avp_request_ex avpreq; + memset(&avpreq, 0, sizeof(avpreq)); + avpreq.avp_vendor.vendor_id = avp->avp_public.avp_vendor; + avpreq.avp_data.avp_code = avp->avp_public.avp_code; + + LOG_D("parsedict_do_avp by AVP_BY_STRUCT avp_code:%d vendor_id:%d", + avpreq.avp_data.avp_code, + avpreq.avp_vendor.vendor_id); + CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_STRUCT, &avpreq, &avp->avp_model, 0)); + } else { + LOG_D("parsedict_do_avp by AVP_BY_CODE avp_code:%d", + avp->avp_public.avp_code); + /* no vendor */ + CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE, &avp->avp_public.avp_code, &avp->avp_model, 0)); + } + + if (!avp->avp_model) { + avp->avp_model_not_found.mnf_code = avp->avp_public.avp_code; + avp->avp_model_not_found.mnf_vendor = avp->avp_public.avp_vendor; + + LOG_D("parsedict_do_avp avp_model_not_found mnf_code:%d mnf_vendor:%d", + avp->avp_public.avp_code, + avp->avp_public.avp_vendor); + + } + } + + /* First handle the case where we have not found this AVP in the dictionary */ + if (!avp->avp_model) { + + if (mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY)) { + TRACE_DEBUG(INFO, "Unsupported mandatory AVP found"); + if (error_info) { + error_info->pei_errcode = "DIAMETER_AVP_UNSUPPORTED"; + error_info->pei_avp = avp; + } else { + char * buf = NULL; + size_t buflen; + CHECK_MALLOC(fd_msg_dump_treeview(&buf, &buflen, NULL, avp, NULL, 0, 0)); + LOG_E("Unsupported AVP: %s", buf); + free(buf); + } + return ENOTSUP; + } + + if (avp->avp_source) { + /* we must copy the data from the source to the internal buffer area */ + CHECK_PARAMS( !avp->avp_rawdata ); + + avp->avp_rawlen = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ); + + if (avp->avp_rawlen) { + CHECK_MALLOC( avp->avp_rawdata = malloc(avp->avp_rawlen) ); + + memcpy(avp->avp_rawdata, avp->avp_source, avp->avp_rawlen); + } + + avp->avp_source = NULL; + + TRACE_DEBUG(FULL, "Unsupported optional AVP found, raw source data saved in avp_rawdata."); + } + + return 0; + } + + /* Ok we have resolved the object. Now we need to interpret its content. */ + + CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); + + if (avp->avp_rawdata) { + /* This happens if the dictionary object was defined after the first check */ + avp->avp_source = avp->avp_rawdata; + } + + /* A bit of sanity here... */ + ASSERT(CHECK_BASETYPE(dictdata.avp_basetype)); + + /* Check the size is valid */ + if ((avp_value_sizes[dictdata.avp_basetype] != 0) && + (avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ) != avp_value_sizes[dictdata.avp_basetype])) { + TRACE_DEBUG(INFO, "The AVP size is not suitable for the type"); + if (error_info) { + error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH"; + error_info->pei_avp = avp; + snprintf(error_message, sizeof(error_message), "I expected a size of %d for this AVP according to my dictionary", avp_value_sizes[dictdata.avp_basetype]); + error_info->pei_message = error_message; + } else { + char * buf = NULL; + size_t buflen; + CHECK_MALLOC(fd_msg_dump_treeview(&buf, &buflen, NULL, avp, NULL, 0, 0)); + LOG_E("Invalid length AVP: %s", buf); + free(buf); + } + avp->avp_model = NULL; + return EBADMSG; + } + + source = avp->avp_source; + avp->avp_source = NULL; + + /* Now get the value inside */ + switch (dictdata.avp_basetype) { + case AVP_TYPE_GROUPED: { + int ret; + + /* This is a grouped AVP, so let's parse the list of AVPs inside */ + CHECK_FCT_DO( ret = parsebuf_list(source, avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ), &avp->avp_chain.children), + { + if ((ret == EBADMSG) && (error_info)) { + error_info->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; + error_info->pei_avp = avp; + snprintf(error_message, sizeof(error_message), "I cannot parse this AVP as a Grouped AVP"); + error_info->pei_message = error_message; + } + avp->avp_source = source; + return ret; + } ); + + return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY), error_info); + } + + case AVP_TYPE_OCTETSTRING: + /* We just have to copy the string into the storage area */ + CHECK_PARAMS_DO( avp->avp_public.avp_len >= GETAVPHDRSZ( avp->avp_public.avp_flags ), + { + if (error_info) { + error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH"; + error_info->pei_avp = avp; + } + avp->avp_source = source; + return EBADMSG; + } ); + avp->avp_storage.os.len = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ); + CHECK_MALLOC( avp->avp_storage.os.data = os0dup(source, avp->avp_storage.os.len) ); + avp->avp_mustfreeos = 1; + break; + + case AVP_TYPE_INTEGER32: + avp->avp_storage.i32 = (int32_t)ntohl(*(uint32_t *)source); + break; + + case AVP_TYPE_INTEGER64: + /* the storage might not be aligned on 64b boundary, so no direct indirection here is possible */ + { + uint64_t __stor; + memcpy(&__stor, source, sizeof(__stor)); + avp->avp_storage.i64 = (int64_t)ntohll(__stor); + } + break; + + case AVP_TYPE_UNSIGNED32: + case AVP_TYPE_FLOAT32: /* For float, we must not cast, or the value is changed. Instead we use implicit cast by changing the member of the union */ + avp->avp_storage.u32 = (uint32_t)ntohl(*(uint32_t *)source); + break; + + case AVP_TYPE_UNSIGNED64: + case AVP_TYPE_FLOAT64: /* same as 32 bits */ + { + uint64_t __stor; + memcpy(&__stor, source, sizeof(__stor)); + avp->avp_storage.u64 = (uint64_t)ntohll(__stor); + } + break; + + } + + /* Is there a derived type check function ? */ + CHECK_FCT ( fd_dict_search ( dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &avp_derived_type, 0) ); + if (avp_derived_type) { + CHECK_FCT( fd_dict_getval(avp_derived_type, &derivedtypedata) ); + if (derivedtypedata.type_check != NULL) { + char * err; + int ret = (*derivedtypedata.type_check)( derivedtypedata.type_check_param, &avp->avp_storage, &err ); + + if (ret != 0) { + TRACE_DEBUG(INFO, "The AVP failed to pass the dictionary validation"); + if (error_info) { + error_info->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; + error_info->pei_avp = avp; + strncpy(error_message, err, sizeof(error_message)); + error_info->pei_message = error_message; + } else { + char * buf = NULL; + size_t buflen; + CHECK_MALLOC(fd_msg_dump_treeview(&buf, &buflen, NULL, avp, NULL, 0, 0)); + LOG_E("Invalid AVP: %s", buf); + free(buf); + } + return ret; /* should we just return EBADMSG? */ + } + } + } + + /* The value is now set, so set the data pointer and return 0 */ + avp->avp_public.avp_value = &avp->avp_storage; + return 0; +} + +/* Process a list of AVPs */ +static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info) +{ + struct fd_list * avpch; + + TRACE_ENTRY("%p %p %d %p", dict, head, mandatory, error_info); + + /* Sanity check */ + ASSERT ( head == head->head ); + + /* Now process the list */ + for (avpch=head->next; avpch != head; avpch = avpch->next) { + CHECK_FCT( parsedict_do_avp(dict, _A(avpch->o), mandatory, error_info) ); + } + + /* Done */ + return 0; +} + +/* Process a msg header. */ +static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info) +{ + int ret = 0; + + TRACE_ENTRY("%p %p %d %p", dict, msg, only_hdr, error_info); + + CHECK_PARAMS( CHECK_MSG(msg) ); + + /* First, check if we already have a model. */ + if (msg->msg_model != NULL) { + /* Check if this model is still valid for the message data */ + enum dict_object_type dicttype; + struct dict_cmd_data data; + ASSERT(((fd_dict_gettype(msg->msg_model, &dicttype) == 0) && (dicttype == DICT_COMMAND))); + (void)fd_dict_getval( msg->msg_model, &data); + if ((data.cmd_code != msg->msg_public.msg_code) + || ((data.cmd_flag_val & data.cmd_flag_mask) != (msg->msg_public.msg_flags && data.cmd_flag_mask))) { + msg->msg_model = NULL; + } else { + goto chain; + } + } + + /* Check if we already searched for this model without success */ + if ((msg->msg_model_not_found.mnf_code == msg->msg_public.msg_code) + && (msg->msg_model_not_found.mnf_flags == msg->msg_public.msg_flags)) { + goto no_model; + } else { + msg->msg_model_not_found.mnf_code = 0; + } + + /* Look for the model from the header */ + CHECK_FCT_DO( ret = fd_dict_search ( dict, DICT_COMMAND, + (msg->msg_public.msg_flags & CMD_FLAG_REQUEST) ? CMD_BY_CODE_R : CMD_BY_CODE_A, + &msg->msg_public.msg_code, + &msg->msg_model, ENOTSUP), + { + if (ret == ENOTSUP) { + /* update the model not found info */ + msg->msg_model_not_found.mnf_code = msg->msg_public.msg_code; + msg->msg_model_not_found.mnf_flags = msg->msg_public.msg_flags; + goto no_model; + } + return ret; + } ); +chain: + if (!only_hdr) { + /* Then process the children */ + ret = parsedict_do_chain(dict, &msg->msg_chain.children, 1, error_info); + + /* Free the raw buffer if any */ + if ((ret == 0) && (msg->msg_rawbuffer != NULL)) { + free(msg->msg_rawbuffer); + msg->msg_rawbuffer=NULL; + } + } + + return ret; +no_model: + if (error_info) { + error_info->pei_errcode = "DIAMETER_COMMAND_UNSUPPORTED"; + error_info->pei_protoerr = 1; + } + return ENOTSUP; +} + +int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict, struct fd_pei *error_info ) +{ + TRACE_ENTRY("%p %p %p", dict, object, error_info); + + CHECK_PARAMS( VALIDATE_OBJ(object) ); + + if (error_info) + memset(error_info, 0, sizeof(struct fd_pei)); + + switch (_C(object)->type) { + case MSG_MSG: + return parsedict_do_msg(dict, _M(object), 0, error_info); + + case MSG_AVP: + return parsedict_do_avp(dict, _A(object), 0, error_info); + + default: + ASSERT(0); + } + return EINVAL; +} + +/***************************************************************************************************************/ +/* Parsing messages and AVP for rules (ABNF) compliance */ + +/* This function is used to get stats (first occurence position, last occurence position, number of occurences) + of AVP instances of a given model in a chain of AVP */ +static void parserules_stat_avps( struct dict_object * model_avp, struct fd_list *list, int * count, int * firstpos, int * lastpos) +{ + struct fd_list * li; + int curpos = 0; /* The current position in the list */ + + TRACE_ENTRY("%p %p %p %p %p", model_avp, list, count, firstpos, lastpos); + + *count = 0; /* number of instances found */ + *firstpos = 0; /* position of the first instance */ + *lastpos = 0; /* position of the last instance, starting from the end */ + + for (li = list->next; li != list; li = li->next) { + /* Increment the current position counter */ + curpos++; + + /* If we previously saved a "lastpos" information, increment it */ + if (*lastpos != 0) + (*lastpos)++; + + /* Check the type of the next AVP. We can compare the references directly, it is safe. */ + if (_A(li->o)->avp_model == model_avp) { + + /* This AVP is of the type we are searching */ + (*count)++; + + /* If we don't have yet a "firstpos", save it */ + if (*firstpos == 0) + *firstpos = curpos; + + /* Reset the lastpos */ + (*lastpos) = 1; + } + } +} + +/* We use this structure as parameter for the next function */ +struct parserules_data { + struct fd_list * sentinel; /* Sentinel of the list of children AVP */ + struct fd_pei * pei; /* If the rule conflicts, save the error here */ +}; + +/* Create an empty AVP of a given model (to use in Failed-AVP) */ +static struct avp * empty_avp(struct dict_object * model_avp) +{ + struct avp * avp = NULL; + struct dict_avp_data avp_info; + union avp_value val; + unsigned char os[1] = { '\0' }; + + /* Create an instance */ + CHECK_FCT_DO( fd_msg_avp_new(model_avp, 0, &avp ), return NULL ); + + /* Type of the AVP */ + CHECK_FCT_DO( fd_dict_getval(model_avp, &avp_info), return NULL ); + + /* Set an initial size */ + avp->avp_public.avp_len = GETAVPHDRSZ( avp->avp_public.avp_flags ) + avp_value_sizes[avp_info.avp_basetype]; + + /* Prepare the empty value */ + memset(&val, 0, sizeof(val)); + switch (avp_info.avp_basetype) { + case AVP_TYPE_OCTETSTRING: + val.os.data = os; + val.os.len = sizeof(os); + avp->avp_public.avp_len += val.os.len; + case AVP_TYPE_INTEGER32: + case AVP_TYPE_INTEGER64: + case AVP_TYPE_UNSIGNED32: + case AVP_TYPE_UNSIGNED64: + case AVP_TYPE_FLOAT32: + case AVP_TYPE_FLOAT64: + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), return NULL ); + case AVP_TYPE_GROUPED: + /* For AVP_TYPE_GROUPED we don't do anything */ + break; + default: + ASSERT(0); /* not handled */ + } + + return avp; +} + +/* Check that a list of AVPs is compliant with a given rule -- will be iterated on the list of rules */ +static int parserules_check_one_rule(void * data, struct dict_rule_data *rule) +{ + int count, first, last, min; + struct parserules_data * pr_data = data; + char * avp_name = ""; + + LOG_A("%p %p", data, rule); + + /* Get statistics of the AVP concerned by this rule in the parent instance */ + parserules_stat_avps( rule->rule_avp, pr_data->sentinel, &count, &first, &last); + + // if (TRACE_BOOL(INFO)) + { + struct dict_avp_data avpdata; + int ret; + ret = fd_dict_getval(rule->rule_avp, &avpdata); + if (ret == 0) + avp_name = avpdata.avp_name; + + LOG_D("Checking rule: p:%d(%d) m/M:%2d/%2d. Counted %d (first: %d, last:%d) of AVP '%s'", + rule->rule_position, + rule->rule_order, + rule->rule_min, + rule->rule_max, + count, + first, + last, + avp_name + ); + } + + /* Now check the rule is not conflicting */ + + /* Check the "min" value */ + if ((min = rule->rule_min) == -1) { + if (rule->rule_position == RULE_OPTIONAL) + min = 0; + else + min = 1; + } + if (count < min) { + fd_log_error("Conflicting rule: the number of occurences (%d) is < the rule min (%d) for '%s'.", count, min, avp_name); + if (pr_data->pei) { + pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; + pr_data->pei->pei_avp = empty_avp(rule->rule_avp); + pr_data->pei->pei_avp_free = 1; + } + return EBADMSG; + } + + /* Check the "max" value */ + if ((rule->rule_max != -1) && (count > rule->rule_max)) { + fd_log_error("Conflicting rule: the number of occurences (%d) is > the rule max (%d) for '%s'.", count, rule->rule_max, avp_name); + if (pr_data->pei) { + if (rule->rule_max == 0) + pr_data->pei->pei_errcode = "DIAMETER_AVP_NOT_ALLOWED"; + else + pr_data->pei->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; + pr_data->pei->pei_avp = empty_avp(rule->rule_avp); /* Well we are supposed to return the (max + 1)th instance of the AVP instead... Pfff... */ TODO("Improve..."); + pr_data->pei->pei_avp_free = 1; + } + return EBADMSG; + } + + /* Check the position and order (if relevant) */ + switch (rule->rule_position) { + case RULE_OPTIONAL: + case RULE_REQUIRED: + /* No special position constraints */ + break; + + case RULE_FIXED_HEAD: + /* Since "0*1" is a valid rule specifier, we only reject cases where the AVP appears *after* its fixed position */ + if (first > rule->rule_order) { + fd_log_error("Conflicting rule: the FIXED_HEAD AVP appears first in (%d) position, the rule requires (%d) for '%s'.", first, rule->rule_order, avp_name); + if (pr_data->pei) { + pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; + pr_data->pei->pei_message = "AVP was not in its fixed position"; + pr_data->pei->pei_avp = empty_avp(rule->rule_avp); + pr_data->pei->pei_avp_free = 1; + } + return EBADMSG; + } + break; + + case RULE_FIXED_TAIL: + /* Since "0*1" is a valid rule specifier, we only reject cases where the AVP appears *before* its fixed position */ + if (last > rule->rule_order) { /* We have a ">" here because we count in reverse order (i.e. from the end) */ + fd_log_error("Conflicting rule: the FIXED_TAIL AVP appears last in (%d) position, the rule requires (%d) for '%s'.", last, rule->rule_order, avp_name); + if (pr_data->pei) { + pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; + pr_data->pei->pei_message = "AVP was not in its fixed position"; + pr_data->pei->pei_avp = empty_avp(rule->rule_avp); + pr_data->pei->pei_avp_free = 1; + } + return EBADMSG; + } + break; + + default: + /* What is this position ??? */ + ASSERT(0); + return ENOTSUP; + } + + /* We've checked all the parameters */ + return 0; +} + +/* Check the rules recursively */ +static int parserules_do ( struct dictionary * dict, msg_or_avp * object, struct fd_pei *error_info, int mandatory) +{ + struct parserules_data data; + struct dict_object * model = NULL; + + TRACE_ENTRY("%p %p %p %d", dict, object, error_info, mandatory); + + /* object has already been checked and dict-parsed when we are called. */ + + /* First, handle the cases where there is no model */ + { + if (CHECK_MSG(object)) { + if ( _M(object)->msg_public.msg_flags & CMD_FLAG_ERROR ) { + /* The case of error messages: the ABNF is different */ + CHECK_FCT( fd_dict_get_error_cmd(dict, &model) ); + } else { + model = _M(object)->msg_model; + } + /* Commands MUST be supported in the dictionary */ + if (model == NULL) { + TRACE_DEBUG(INFO, "Message with no dictionary model. EBADMSG"); + if (error_info) { + error_info->pei_errcode = "DIAMETER_COMMAND_UNSUPPORTED"; + error_info->pei_protoerr = 1; + } + return EBADMSG; + } + } + + /* AVP with the 'M' flag must also be recognized in the dictionary -- except inside an optional grouped AVP */ + if (CHECK_AVP(object) && ((model = _A(object)->avp_model) == NULL)) { + if ( mandatory && (_A(object)->avp_public.avp_flags & AVP_FLAG_MANDATORY)) { + /* Return an error in this case */ + TRACE_DEBUG(INFO, "Mandatory AVP with no dictionary model. EBADMSG"); + if (error_info) { + error_info->pei_errcode = "DIAMETER_AVP_UNSUPPORTED"; + error_info->pei_avp = object; + } + return EBADMSG; + } else { + /* We don't know any rule for this object, so assume OK */ + TRACE_DEBUG(FULL, "Unknown informational AVP, ignoring..."); + return 0; + } + } + } + + /* At this point we know "model" is set and points to the object's model */ + + /* If we are an AVP with no children, just return OK */ + if (CHECK_AVP(object)) { + struct dict_avp_data dictdata; + CHECK_FCT( fd_dict_getval(model, &dictdata) ); + if (dictdata.avp_basetype != AVP_TYPE_GROUPED) { + /* This object has no children and no rules */ + return 0; + } + } + + /* If this object has children, first check the rules for all its children */ + { + int is_child_mand = 0; + struct fd_list * ch = NULL; + if ( CHECK_MSG(object) + || (mandatory && (_A(object)->avp_public.avp_flags & AVP_FLAG_MANDATORY)) ) + is_child_mand = 1; + for (ch = _C(object)->children.next; ch != &_C(object)->children; ch = ch->next) { + CHECK_FCT( parserules_do ( dict, _C(ch->o), error_info, is_child_mand ) ); + } + } + + /* Now check all rules of this object */ + data.sentinel = &_C(object)->children; + data.pei = error_info; + CHECK_FCT( fd_dict_iterate_rules ( model, &data, parserules_check_one_rule ) ); + + return 0; +} + +int fd_msg_parse_rules ( msg_or_avp * object, struct dictionary * dict, struct fd_pei *error_info) +{ + TRACE_ENTRY("%p %p %p", object, dict, error_info); + + if (error_info) + memset(error_info, 0, sizeof(struct fd_pei)); + + /* Resolve the dictionary objects when missing. This also validates the object. */ + CHECK_FCT( fd_msg_parse_dict ( object, dict, error_info ) ); + + /* Call the recursive function */ + return parserules_do ( dict, object, error_info, 1 ) ; +} + +/***************************************************************************************************************/ + +/* Compute the lengh of an object and its subtree. */ +int fd_msg_update_length ( msg_or_avp * object ) +{ + size_t sz = 0; + struct dict_object * model; + union { + struct dict_cmd_data cmddata; + struct dict_avp_data avpdata; + } dictdata; + + TRACE_ENTRY("%p", object); + + /* Get the model of the object. This also validates the object */ + CHECK_FCT( fd_msg_model ( object, &model ) ); + + /* Get the information of the model */ + if (model) { + CHECK_FCT( fd_dict_getval(model, &dictdata) ); + } else { + /* For unknown AVP, just don't change the size */ + if (_C(object)->type == MSG_AVP) + return 0; + } + + /* Deal with easy cases: AVPs without children */ + if ((_C(object)->type == MSG_AVP) && (dictdata.avpdata.avp_basetype != AVP_TYPE_GROUPED)) { + /* Sanity check */ + ASSERT(FD_IS_LIST_EMPTY(&_A(object)->avp_chain.children)); + + /* Now check that the data is set in the AVP */ + CHECK_PARAMS( _A(object)->avp_public.avp_value ); + + sz = GETAVPHDRSZ( _A(object)->avp_public.avp_flags ); + + switch (dictdata.avpdata.avp_basetype) { + case AVP_TYPE_OCTETSTRING: + sz += _A(object)->avp_public.avp_value->os.len; + break; + + case AVP_TYPE_INTEGER32: + case AVP_TYPE_INTEGER64: + case AVP_TYPE_UNSIGNED32: + case AVP_TYPE_UNSIGNED64: + case AVP_TYPE_FLOAT32: + case AVP_TYPE_FLOAT64: + sz += avp_value_sizes[dictdata.avpdata.avp_basetype]; + break; + + default: + /* Something went wrong... */ + ASSERT(0); + } + } + else /* message or grouped AVP */ + { + struct fd_list * ch = NULL; + + /* First, compute the header size */ + if (_C(object)->type == MSG_AVP) { + sz = GETAVPHDRSZ( _A(object)->avp_public.avp_flags ); + } else { + sz = GETMSGHDRSZ( ); + } + + /* Recurse in all children and update the sz information */ + for (ch = _C(object)->children.next; ch != &_C(object)->children; ch = ch->next) { + CHECK_FCT( fd_msg_update_length ( ch->o ) ); + + /* Add the padded size to the parent */ + sz += PAD4( _A(ch->o)->avp_public.avp_len ); + } + } + + /* When we arrive here, the "sz" variable contains the size to write in the object */ + if (_C(object)->type == MSG_AVP) + _A(object)->avp_public.avp_len = sz; + else + _M(object)->msg_public.msg_length = sz; + + return 0; +} + +/***************************************************************************************************************/ +/* Macro to check if further callbacks must be called */ +#define TEST_ACTION_STOP() \ + if ((*msg == NULL) || (*action != DISP_ACT_CONT)) \ + goto out; + +/* Call all dispatch callbacks for a given message */ +int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code, char ** drop_reason, struct msg ** drop_msg) +{ + struct dictionary * dict; + struct dict_object * app; + struct dict_object * cmd; + struct avp * avp; + struct fd_list * cb_list; + int ret = 0, r2; + + TRACE_ENTRY("%p %p %p %p", msg, session, action, error_code); + CHECK_PARAMS( msg && CHECK_MSG(*msg) && action); + + if (error_code) + *error_code = NULL; + if (drop_reason) + *drop_reason = NULL; + *action = DISP_ACT_CONT; + + /* Take the dispatch lock */ + CHECK_FCT( pthread_rwlock_rdlock(&fd_disp_lock) ); + pthread_cleanup_push( fd_cleanup_rwlock, &fd_disp_lock ); + + /* First, call the DISP_HOW_ANY callbacks */ + CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL, drop_reason, drop_msg ), goto out ); + + TEST_ACTION_STOP(); + + /* If we don't know the model at this point, we stop cause we cannot get the dictionary. It's invalid: an error should already have been trigged by ANY callbacks */ + CHECK_PARAMS_DO(cmd = (*msg)->msg_model, { ret = EINVAL; goto out; } ); + + /* Now resolve message application */ + CHECK_FCT_DO( ret = fd_dict_getdict( cmd, &dict ), goto out ); + CHECK_FCT_DO( ret = fd_dict_search( dict, DICT_APPLICATION, APPLICATION_BY_ID, &(*msg)->msg_public.msg_appl, &app, 0 ), goto out ); + + if (app == NULL) { + if ((*msg)->msg_public.msg_flags & CMD_FLAG_REQUEST) { + if (error_code) + *error_code = "DIAMETER_APPLICATION_UNSUPPORTED"; + *action = DISP_ACT_ERROR; + } else { + *drop_reason = "Internal error: Received this answer to a local query with an unsupported application"; + *drop_msg = *msg; + *msg = NULL; + } + goto out; + } + + /* So start browsing the message */ + CHECK_FCT_DO( ret = fd_msg_browse( *msg, MSG_BRW_FIRST_CHILD, &avp, NULL ), goto out ); + while (avp != NULL) { + /* For unknown AVP, we don't have a callback registered, so just skip */ + if (avp->avp_model) { + struct dict_object * enumval = NULL; + + /* Get the list of callback for this AVP */ + CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_AVP, avp->avp_model, &cb_list), goto out ); + + /* We search enumerated values only in case of non-grouped AVP */ + if ( avp->avp_public.avp_value ) { + struct dict_object * type; + /* Check if the AVP has a constant value */ + CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &type, 0), goto out ); + if (type) { + struct dict_enumval_request req; + memset(&req, 0, sizeof(struct dict_enumval_request)); + req.type_obj = type; + memcpy( &req.search.enum_value, avp->avp_public.avp_value, sizeof(union avp_value) ); + CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enumval, 0), goto out ); + } + } + + /* Call the callbacks */ + CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval, drop_reason, drop_msg ), goto out ); + TEST_ACTION_STOP(); + } + /* Go to next AVP */ + CHECK_FCT_DO( ret = fd_msg_browse( avp, MSG_BRW_WALK, &avp, NULL ), goto out ); + } + + /* Now call command and application callbacks */ + CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto out ); + CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL, drop_reason, drop_msg ), goto out ); + TEST_ACTION_STOP(); + + if (app) { + CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto out ); + CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL, drop_reason, drop_msg ), goto out ); + TEST_ACTION_STOP(); + } +out: + ; /* some systems would complain without this */ + pthread_cleanup_pop(0); + + CHECK_POSIX_DO(r2 = pthread_rwlock_unlock(&fd_disp_lock), /* ignore */ ); + return ret ?: r2; +} + + diff --git a/plat/diameter/libfdproto/ostr.c b/plat/diameter/libfdproto/ostr.c new file mode 100644 index 0000000..7a9bbf7 --- /dev/null +++ b/plat/diameter/libfdproto/ostr.c @@ -0,0 +1,563 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" + +#if (!defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT)) +/* Process IDNA with stringprep -- See RFC5890 -- and libidn documentation... */ +#include /* idna_to_ascii_8z() */ +#endif /* !defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT) */ + +/* Similar to strdup with (must have been verified) os0_t */ +os0_t os0dup_int(os0_t s, size_t l) { + os0_t r; + CHECK_MALLOC_DO( r = malloc(l+1), return NULL ); + if (l) + memcpy(r, s, l); /* this might be faster than a strcpy or strdup because it can work with 32 or 64b blocks */ + r[l] = '\0'; + return r; +} + +/* case sensitive comparison, fast */ +int fd_os_cmp_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz) +{ + ASSERT( os1 && os2); + if (os1sz < os2sz) + return -1; + if (os1sz > os2sz) + return 1; + return os1sz ? memcmp(os1, os2, os1sz) : 0; +} + +/* a local version of tolower() that does not depend on LC_CTYPE locale */ +static uint8_t asciitolower(uint8_t a) +{ + if ((a >= 'A') && (a <= 'Z')) + return a + 32 /* == 'a' - 'A' */; + return a; +} + +/* less sensitive to case, slower. */ +/* the semantics of "maybefurther" assume you are searching for os1 in a list of elements ordered, each element passed as os2 */ +int fd_os_almostcasesrch_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz, int *maybefurther) +{ + int i; + int res = 0; + + ASSERT( os1 && os2); + if (maybefurther) + *maybefurther = 0; + + if (os1sz < os2sz) + return -1; + + if (maybefurther) + *maybefurther = 1; + + if (os1sz > os2sz) + return 1; + + for (i = 0; i < os1sz; i++) { + if (os1[i] == os2[i]) + continue; + + if (!res) + res = os1[i] < os2[i] ? -1 : 1; + + if (asciitolower(os1[i]) == asciitolower(os2[i])) + continue; + + return res; + } + + return 0; +} + +/* Check if the string contains only ASCII */ +int fd_os_is_valid_DiameterIdentity(uint8_t * os, size_t ossz) +{ +#ifdef DIAMID_IDNA_IGNORE + + /* Allow anything */ + +#else /* DIAMID_IDNA_IGNORE */ + + int i; + + /* Allow only letters, digits, hyphen, dot */ + for (i=0; i < ossz; i++) { + if (os[i] > 'z') + break; + if (os[i] >= 'a') + continue; + if ((os[i] >= 'A') && (os[i] <= 'Z')) + continue; + if ((os[i] == '-') || (os[i] == '.')) + continue; + if ((os[i] == '@') ) + continue; + if ((os[i] >= '0') && (os[i] <= '9')) + continue; + break; + } + if (i < ossz) { + int nb = 1; + /* To get a better display, check if the invalid char is UTF-8 */ + if ((os[i] & 0xE0) == 0xC0 /* 110xxxxx */) { + if ((i < ossz - 1) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */)) + nb = 2; + goto disp; + } + if ((os[i] & 0xF0) == 0xE0 /* 1110xxxx */) { + if ((i < ossz - 2) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */)) + nb = 3; + goto disp; + } + if ((os[i] & 0xF8) == 0xF0 /* 11110xxx */) { + if ((i < ossz - 3) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 3] & 0xC0) == 0x80 /* 10xxxxxx */)) + nb = 4; + goto disp; + } + if ((os[i] & 0xFC) == 0xF8 /* 111110xx */) { + if ((i < ossz - 4) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 3] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 4] & 0xC0) == 0x80 /* 10xxxxxx */)) + nb = 5; + goto disp; + } + if ((os[i] & 0xFE) == 0xFC /* 1111110x */) { + if ((i < ossz - 5) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 3] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 4] & 0xC0) == 0x80 /* 10xxxxxx */) + && ((os[i + 5] & 0xC0) == 0x80 /* 10xxxxxx */)) + nb = 6; + goto disp; + } + /* otherwise, we just display the hex code */ + TRACE_DEBUG(INFO, "Invalid character (0x%hhX) at offset %d in DiameterIdentity '%.*s'", os[i], i+1, (int)ossz, os); + return 0; +disp: + TRACE_DEBUG(INFO, "Invalid character '%.*s' at offset %d in DiameterIdentity '%.*s'", nb, os + i, i+1, (int)ossz, os); + return 0; + } + +#endif /* DIAMID_IDNA_IGNORE */ + + return 1; +} + +/* The following function validates a string as a Diameter Identity or applies the IDNA transformation on it + if *inoutsz is != 0 on entry, *id may not be \0-terminated. + memory has the following meaning: 0: *id can be realloc'd. 1: *id must be malloc'd on output (was static) +*/ +int fd_os_validate_DiameterIdentity(char ** id, size_t * inoutsz, int memory) +{ +#if !defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT) + int gotsize = 0; +#endif /* defined(DIAMID_IDNA_IGNORE) || defined(DIAMID_IDNA_REJECT) */ + + TRACE_ENTRY("%p %p", id, inoutsz); + CHECK_PARAMS( id && *id && inoutsz ); + + if (!*inoutsz) + *inoutsz = strlen(*id); +#if !defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT) + else + gotsize = 1; +#endif /* defined(DIAMID_IDNA_IGNORE) || defined(DIAMID_IDNA_REJECT) */ + +#ifndef DIAMID_IDNA_IGNORE + + if (!fd_os_is_valid_DiameterIdentity((os0_t)*id, *inoutsz)) { + +#ifdef DIAMID_IDNA_REJECT + + TRACE_DEBUG(INFO, "The string '%s' is not a valid DiameterIdentity!", *id); + TRACE_DEBUG(INFO, "Returning EINVAL since fD is compiled with option DIAMID_IDNA_REJECT."); + return EINVAL; + +#else /* DIAMID_IDNA_REJECT */ + + char *processed; + int ret; + + if (gotsize) { /* make it \0-terminated */ + if (memory) { + CHECK_MALLOC( *id = os0dup(*id, *inoutsz) ); + memory = 0; + } else { + CHECK_MALLOC( *id = realloc(*id, *inoutsz + 1) ); + (*id)[*inoutsz] = '0'; + } + } + + ret = idna_to_ascii_8z ( *id, &processed, IDNA_USE_STD3_ASCII_RULES ); + if (ret == IDNA_SUCCESS) { + TRACE_DEBUG(INFO, "The string '%s' is not a valid DiameterIdentity, it was changed to '%s'", *id, processed); + if (memory == 0) + free(*id); + *id = processed; + *inoutsz = strlen(processed); + /* Done! */ + } else { + TRACE_DEBUG(INFO, "The string '%s' is not a valid DiameterIdentity and cannot be sanitanized: %s", *id, idna_strerror (ret)); + return EINVAL; + } + +#endif /* DIAMID_IDNA_REJECT */ + } else +#endif /* ! DIAMID_IDNA_IGNORE */ + { + if (memory == 1) { + CHECK_MALLOC( *id = os0dup(*id, *inoutsz) ); + } + } + return 0; +} + +/* Analyze a DiameterURI and return its components. + Return EINVAL if the URI is not valid. + *diamid is malloc'd on function return and must be freed (it is processed by fd_os_validate_DiameterIdentity). + *secure is 0 (no security) or 1 (security enabled) on return. + *port is 0 (default) or a value in host byte order on return. + *transport is 0 (default) or IPPROTO_* on return. + *proto is 0 (default) or 'd' (diameter), 'r' (radius), or 't' (tacacs+) on return. + */ +int fd_os_parse_DiameterURI(uint8_t * uri, size_t urisz, DiamId_t * diamid, size_t * diamidlen, int * secure, uint16_t * port, int * transport, char *proto) +{ + size_t offset = 0; + DiamId_t fqdn = NULL; + size_t fqdnlen; + TRACE_ENTRY("%p %zd %p %p %p %p %p %p", uri, urisz, diamid, diamidlen, secure, port, transport, proto); + CHECK_PARAMS( uri && urisz ); + + CHECK_PARAMS( urisz > 7 ); /* "aaa" + "://" + something else at least */ + + /* Initialize values */ + if (secure) + *secure = 0; + if (port) + *port = 0; + if (transport) + *transport = 0; + if (proto) + *proto = 0; + + /* Check the beginning */ + if (memcmp( uri, "aaa", 3)) { + TRACE_DEBUG(INFO, "Invalid DiameterURI prefix: got '%.*s', expected 'aaa'", 3, uri); + return EINVAL; + } + offset += 3; + + /* Secure? */ + if (uri[offset] == (uint8_t)'s') { + if (secure) + *secure = 1; + offset += 1; + } + + /* Remaining of URI marker */ + if (memcmp( uri + offset, "://", 3)) { + TRACE_DEBUG(INFO, "Invalid DiameterURI prefix: got '%.*s', expected 'aaa://' or 'aaas://'", (int)offset + 3, uri); + return EINVAL; + } + offset += 3; + + /* This is the start of the FQDN */ + fqdn = (DiamId_t)uri + offset; + for ( ; offset < urisz ; offset++ ) { + /* Stop only when we find ':' or ';' */ + if ((uri[offset] == (uint8_t)':') || (uri[offset] == (uint8_t)';')) + break; + } + fqdnlen = offset - (fqdn - (DiamId_t)uri); + CHECK_FCT(fd_os_validate_DiameterIdentity(&fqdn, &fqdnlen, 1)); + if (diamid) + *diamid = fqdn; + else + free(fqdn); + if (diamidlen) + *diamidlen = fqdnlen; + + if (offset == urisz) + return 0; /* Finished */ + + /* Is there a port ? */ + if (uri[offset] == ':') { + uint16_t p = 0; + do { + offset++; + + if (offset == urisz) + break; + + uint32_t t = (uint32_t)((char)uri[offset] - '0'); + if (t > 9) + break; /* we did not get a digit */ + + t += p * 10; /* the port is specified in decimal base */ + + if (t >= (1<<16)) { + TRACE_DEBUG(INFO, "Invalid DiameterURI: port value is too big."); + return EINVAL; + } + + p = t; + } while (1); + + if (port) + *port = p; + } + + if (offset == urisz) + return 0; /* Finished */ + + /* Is there a transport? */ + if ( (urisz - offset > CONSTSTRLEN(";transport=")) + && !strncasecmp((char *)uri + offset, ";transport=", CONSTSTRLEN(";transport=")) ) { + + offset += CONSTSTRLEN(";transport="); + + if (urisz - offset < 3) { + TRACE_DEBUG(INFO, "Invalid DiameterURI: transport string is too short, ignored."); + return 0; + } + if (!strncasecmp((char *)uri + offset, "tcp", CONSTSTRLEN("tcp"))) { + if (transport) + *transport = IPPROTO_TCP; + offset += CONSTSTRLEN("tcp"); + goto after_transport; + } + if (!strncasecmp((char *)uri + offset, "udp", CONSTSTRLEN("udp"))) { + if (transport) + *transport = IPPROTO_UDP; + offset += CONSTSTRLEN("udp"); + goto after_transport; + } + if ((urisz - offset > 3) && !strncasecmp((char *)uri + offset, "sctp", CONSTSTRLEN("sctp"))) { + if (transport) { +#ifndef DISABLE_SCTP + *transport = IPPROTO_SCTP; +#else /* DISABLE_SCTP */ + TRACE_DEBUG(INFO, "Received DiameterURI with 'transport=sctp' but DISABLE_SCTP was selected"); + *transport = 0; +#endif /* DISABLE_SCTP */ + } + offset += CONSTSTRLEN("sctp"); + goto after_transport; + } + + TRACE_DEBUG(INFO, "Invalid DiameterURI: transport string is not recognized ('%.*s').", (int)(urisz - offset), uri + offset); + return EINVAL; + } +after_transport: + if (offset == urisz) + return 0; /* Finished */ + + /* Is there a protocol? */ + if ( ((urisz - offset) > CONSTSTRLEN(";protocol=")) + && (!strncasecmp((char *)uri + offset, ";protocol=", CONSTSTRLEN(";protocol="))) ) { + + offset += CONSTSTRLEN(";protocol="); + + if ( ((urisz - offset) >= CONSTSTRLEN("diameter")) + && (!strncasecmp((char *)uri + offset, "diameter", CONSTSTRLEN("diameter"))) ) { + if (proto) + *proto = 'd'; + offset += CONSTSTRLEN("diameter"); + goto after_proto; + } + + if ( ((urisz - offset) >= CONSTSTRLEN("radius")) + && (!strncasecmp((char *)uri + offset, "radius", CONSTSTRLEN("radius"))) ) { + if (proto) + *proto = 'r'; + offset += CONSTSTRLEN("radius"); + goto after_proto; + } + + if ( ((urisz - offset) >= CONSTSTRLEN("tacacs+")) + && (!strncasecmp((char *)uri + offset, "tacacs+", CONSTSTRLEN("tacacs+"))) ) { + if (proto) + *proto = 't'; + offset += CONSTSTRLEN("tacacs+"); + goto after_proto; + } + + TRACE_DEBUG(INFO, "Invalid DiameterURI: protocol string is not recognized ('%.*s').", (int)(urisz - offset), uri + offset); + return EINVAL; + + } +after_proto: + if (offset == urisz) + return 0; /* Finished */ + + TRACE_DEBUG(INFO, "Invalid DiameterURI: final part of string is not recognized ('%.*s').", (int)(urisz - offset), uri + offset); + return EINVAL; +} + + +/********************************************************************************************************/ +/* Hash function -- credits to Austin Appleby, thank you ^^ */ +/* See http://murmurhash.googlepages.com for more information on this function */ + +/* the strings are NOT always aligned properly (ex: received in RADIUS message), so we use the aligned MurmurHash2 function as needed */ +#define _HASH_MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; } +uint32_t fd_os_hash ( uint8_t * string, size_t len ) +{ + uint32_t hash = len; + uint8_t * data = string; + + const unsigned int m = 0x5bd1e995; + const int r = 24; + int align = (long)string & 3; + + if (!align || (len < 4)) { + /* In case data is aligned, MurmurHash2 function */ + while(len >= 4) + { + /* Mix 4 bytes at a time into the hash */ + uint32_t k = *(uint32_t *)data; /* We don't care about the byte order */ + + _HASH_MIX(hash, k, m); + + data += 4; + len -= 4; + } + + /* Handle the last few bytes of the input */ + switch(len) { + case 3: hash ^= data[2] << 16; + case 2: hash ^= data[1] << 8; + case 1: hash ^= data[0]; + hash *= m; + } + + } else { + /* Unaligned data, use alignment-safe slower version */ + + /* Pre-load the temp registers */ + uint32_t t = 0, d = 0; + switch(align) + { + case 1: t |= data[2] << 16; + case 2: t |= data[1] << 8; + case 3: t |= data[0]; + } + t <<= (8 * align); + + data += 4-align; + len -= 4-align; + + /* From this point, "data" can be read by chunks of 4 bytes */ + + int sl = 8 * (4-align); + int sr = 8 * align; + + /* Mix */ + while(len >= 4) + { + uint32_t k; + + d = *(unsigned int *)data; + k = (t >> sr) | (d << sl); + + _HASH_MIX(hash, k, m); + + t = d; + + data += 4; + len -= 4; + } + + /* Handle leftover data in temp registers */ + d = 0; + if(len >= align) + { + uint32_t k; + + switch(align) + { + case 3: d |= data[2] << 16; + case 2: d |= data[1] << 8; + case 1: d |= data[0]; + } + + k = (t >> sr) | (d << sl); + _HASH_MIX(hash, k, m); + + data += align; + len -= align; + + /* Handle tail bytes */ + + switch(len) + { + case 3: hash ^= data[2] << 16; + case 2: hash ^= data[1] << 8; + case 1: hash ^= data[0]; + hash *= m; + }; + } + else + { + switch(len) + { + case 3: d |= data[2] << 16; + case 2: d |= data[1] << 8; + case 1: d |= data[0]; + case 0: hash ^= (t >> sr) | (d << sl); + hash *= m; + } + } + + + } + + /* Do a few final mixes of the hash to ensure the last few + bytes are well-incorporated. */ + hash ^= hash >> 13; + hash *= m; + hash ^= hash >> 15; + + return hash; +} + diff --git a/plat/diameter/libfdproto/portability.c b/plat/diameter/libfdproto/portability.c new file mode 100644 index 0000000..8740483 --- /dev/null +++ b/plat/diameter/libfdproto/portability.c @@ -0,0 +1,70 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2012, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" + +/* Replacement for clock_gettime for the Mac OS */ +#ifndef HAVE_CLOCK_GETTIME +int clock_gettime(int clk_id, struct timespec* ts) +{ + struct timeval tv; + gettimeofday (&tv, NULL); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; + return 0; +} +#endif /* HAVE_CLOCK_GETTIME */ + +/* Replacement for strndup for the Mac OS */ +#ifndef HAVE_STRNDUP +char * strndup (char *str, size_t len) +{ + char * output; + size_t outlen; + + output = memchr(str, 0, len); + if (output == NULL) { + outlen = len; + } else { + outlen = output - str; + } + + CHECK_MALLOC_DO( output = malloc (outlen + 1), return NULL ); + + output[outlen] = '\0'; + memcpy (output, str, outlen); + return output; +} +#endif /* HAVE_STRNDUP */ diff --git a/plat/diameter/libfdproto/rt_data.c b/plat/diameter/libfdproto/rt_data.c new file mode 100644 index 0000000..c01ee37 --- /dev/null +++ b/plat/diameter/libfdproto/rt_data.c @@ -0,0 +1,338 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Routing module helpers. + * + * This file provides support for the rt_data structure manipulation. + */ + +#include "fdproto-internal.h" + +/* Structure that contains the routing data for a message */ +struct rt_data { + int extracted; /* if 0, candidates is ordered by diamid, otherwise the order is unspecified. This also counts the number of times the message was (re-)sent, as a side effect */ + struct fd_list candidates; /* All the candidates. Items are struct rtd_candidate. */ + struct fd_list errors; /* All errors received from other peers for this message */ +}; + +/* Items of the errors list */ +struct rtd_error { + struct fd_list chain; /* link in the list, ordered by nexthop (fd_os_cmp) */ + DiamId_t nexthop;/* the peer the message was sent to */ + size_t nexthoplen; /* cached string length */ + DiamId_t erh; /* the origin of the error */ + size_t erhlen; /* cached string length */ + uint32_t code; /* the error code */ +}; + +/* Create a new structure to store routing data */ +int fd_rtd_init(struct rt_data ** rtd) +{ + struct rt_data *new; + TRACE_ENTRY("%p", rtd); + CHECK_PARAMS(rtd); + + /* Alloc the structure */ + CHECK_MALLOC( new = malloc(sizeof(struct rt_data)) ); + memset(new, 0, sizeof(struct rt_data) ); + fd_list_init(&new->candidates, new); + fd_list_init(&new->errors, new); + + *rtd = new; + return 0; +} + +/* Destroy the routing data */ +void fd_rtd_free(struct rt_data ** rtd) +{ + struct rt_data *old; + + TRACE_ENTRY("%p", rtd); + CHECK_PARAMS_DO(rtd, return ); + + old = *rtd; + *rtd = NULL; + + while (!FD_IS_LIST_EMPTY(&old->candidates)) { + struct rtd_candidate * c = (struct rtd_candidate *) old->candidates.next; + + fd_list_unlink(&c->chain); + free(c->diamid); + free(c->realm); + free(c); + } + + while (!FD_IS_LIST_EMPTY(&old->errors)) { + struct rtd_error * c = (struct rtd_error *) old->errors.next; + + fd_list_unlink(&c->chain); + free(c->nexthop); + free(c->erh); + free(c); + } + + free(old); + + return; +} + +/* Add a peer to the candidates list. The source is our local peer list, so no need to care for the case here. */ +int fd_rtd_candidate_add(struct rt_data * rtd, DiamId_t peerid, size_t peeridlen, DiamId_t realm, size_t realmlen) +{ + struct fd_list * prev; + struct rtd_candidate * new; + + TRACE_ENTRY("%p %p %zd %p %zd", rtd, peerid, peeridlen, realm, realmlen); + CHECK_PARAMS(rtd && peerid && peeridlen); + + /* Since the peers are ordered when they are added (fd_g_activ_peers) we search for the position from the end -- this should be efficient */ + for (prev = rtd->candidates.prev; prev != &rtd->candidates; prev = prev->prev) { + struct rtd_candidate * cp = (struct rtd_candidate *) prev; + int cmp = fd_os_cmp(peerid, peeridlen, cp->diamid, cp->diamidlen); + if (cmp > 0) + break; + if (cmp == 0) + /* The candidate is already in the list */ + return 0; + } + + /* Create the new entry */ + CHECK_MALLOC( new = malloc(sizeof(struct rtd_candidate)) ); + memset(new, 0, sizeof(struct rtd_candidate) ); + fd_list_init(&new->chain, new); + CHECK_MALLOC( new->diamid = os0dup(peerid, peeridlen) ) + new->diamidlen = peeridlen; + if (realm) { + CHECK_MALLOC( new->realm = os0dup(realm, realmlen) ) + new->realmlen = realmlen; + } + + /* insert in the list at the correct position */ + fd_list_insert_after(prev, &new->chain); + + return 0; +} + +/* Remove a peer from the candidates (if it is found). Case insensitive search since the names are received from other peers */ +void fd_rtd_candidate_del(struct rt_data * rtd, uint8_t * id, size_t idsz) +{ + struct fd_list * li; + + TRACE_ENTRY("%p %p %zd", rtd, id, idsz); + CHECK_PARAMS_DO( rtd && id && idsz, return ); + + if (!fd_os_is_valid_DiameterIdentity(id, idsz)) + /* it cannot be in the list */ + return; + + for (li = rtd->candidates.next; li != &rtd->candidates; li = li->next) { + struct rtd_candidate * c = (struct rtd_candidate *) li; + int cont; + int cmp = fd_os_almostcasesrch(id, idsz, c->diamid, c->diamidlen, &cont); + + if (!cmp) { + /* Found it! Remove it */ + fd_list_unlink(&c->chain); + free(c->diamid); + free(c->realm); + free(c); + break; + } + + if (cont) + continue; + + /* The list is guaranteed to be ordered only if not extracted */ + if (! rtd->extracted) + break; + } + + return; +} + +/* If a peer returned a protocol error for this message, save it so that we don't try to send it there again. + Case insensitive search since the names are received from other peers*/ +int fd_rtd_error_add(struct rt_data * rtd, DiamId_t sentto, size_t senttolen, uint8_t * origin, size_t originsz, uint32_t rcode, struct fd_list ** candidates, int * sendingattemtps) +{ + struct fd_list * li; + int match = 0; + + TRACE_ENTRY("%p %p %zd %p %zd %u %p %p", rtd, sentto, senttolen, origin, originsz, rcode, candidates, sendingattemtps); + CHECK_PARAMS( rtd && sentto && senttolen ); /* origin may be NULL */ + + /* First add the new error entry */ + for (li = rtd->errors.next; li != &rtd->errors; li = li->next) { + struct rtd_error * e = (struct rtd_error *) li; + int cmp = fd_os_cmp(sentto, senttolen, e->nexthop, e->nexthoplen); + if (cmp > 0) + continue; + if (!cmp) + match = 1; + break; + } + + /* If we already had this entry, we should not have sent the message again to this peer... anyway, let's close our eyes. */ + /* in the normal case, we save the error */ + if (!match) { + /* Add a new entry in the error list */ + struct rtd_error * new; + CHECK_MALLOC( new = malloc(sizeof(struct rtd_error)) ); + memset(new, 0, sizeof(struct rtd_error)); + fd_list_init(&new->chain, NULL); + + CHECK_MALLOC(new->nexthop = os0dup(sentto, senttolen)); + new->nexthoplen = senttolen; + + if (origin) { + if (!originsz) { + originsz=strlen((char *)origin); + } else { + if (!fd_os_is_valid_DiameterIdentity(origin, originsz)){ + TRACE_DEBUG(FULL, "Received error %d from peer with invalid Origin-Host AVP, not saved", rcode); + origin = NULL; + goto after_origin; + } + } + CHECK_MALLOC( new->erh = (DiamId_t)os0dup(origin, originsz) ); + new->erhlen = originsz; + } +after_origin: + new->code = rcode; + fd_list_insert_before(li, &new->chain); + } + + /* Finally, remove this (these) peers from the candidate list */ + fd_rtd_candidate_del(rtd, (os0_t)sentto, senttolen); + if (origin) + fd_rtd_candidate_del(rtd, origin, originsz); + + if (candidates) + *candidates = &rtd->candidates; + + if (sendingattemtps) + *sendingattemtps = rtd->extracted; + + /* Done! */ + return 0; +} + +/* Only retrieve the number of times this message has been processed by the routing-out mechanism (i.e. number of times it was failed over) */ +int fd_rtd_get_nb_attempts(struct rt_data * rtd, int * sendingattemtps) +{ + TRACE_ENTRY("%p %p", rtd, sendingattemtps); + CHECK_PARAMS( rtd && sendingattemtps ); + + *sendingattemtps = rtd->extracted; + + /* Done! */ + return 0; +} + +/* Extract the list of valid candidates, and initialize their scores */ +void fd_rtd_candidate_extract(struct rt_data * rtd, struct fd_list ** candidates, int ini_score) +{ + struct fd_list * li; + + TRACE_ENTRY("%p %p", rtd, candidates); + CHECK_PARAMS_DO( candidates, return ); + CHECK_PARAMS_DO( rtd, { *candidates = NULL; return; } ); + + *candidates = &rtd->candidates; + + /* Reset all scores to INITIAL score */ + for (li = rtd->candidates.next; li != &rtd->candidates; li = li->next) { + struct rtd_candidate * c = (struct rtd_candidate *) li; + c->score = ini_score; + } + + rtd->extracted += 1; + return; +} + +/* Reorder the list of peers. If several peer have the same highest score, they are randomized. */ +int fd_rtd_candidate_reorder(struct fd_list * candidates) +{ + struct fd_list unordered = FD_LIST_INITIALIZER(unordered), *li; + struct fd_list highest = FD_LIST_INITIALIZER(highest); + int hs = -1; + + TRACE_ENTRY("%p", candidates); + CHECK_PARAMS( candidates ); + + /* First, move all items from candidates to the undordered list */ + fd_list_move_end(&unordered, candidates); + + /* Now extract each element from unordered and add it back to list ordered by score */ + while (!FD_IS_LIST_EMPTY(&unordered)) { + struct rtd_candidate * c = (struct rtd_candidate *) unordered.next; + + fd_list_unlink(&c->chain); + + /* If this candidate has a higher score than the previous ones */ + if (c->score > hs) { + /* Then we move the previous high score items at end of the list */ + fd_list_move_end(candidates, &highest); + + /* And the new high score is set */ + hs = c->score; + } + + /* If this candidate equals the higher score, add it into highest list at a random place */ + if (c->score == hs) { + if (rand() & 1) { + fd_list_insert_after(&highest, &c->chain); + } else { + fd_list_insert_before(&highest, &c->chain); + } + /* Otherwise, insert at normal place in the list */ + } else { + /* Find the position in ordered candidates list */ + for (li = candidates->next; li != candidates; li = li->next) { + struct rtd_candidate * cnext = (struct rtd_candidate *) li; + if (cnext->score >= c->score) + break; + } + + /* Add the element there */ + fd_list_insert_before(li, &c->chain); + } + } + + /* Now simply move back all the "highest" candidates at the end of the list */ + fd_list_move_end(candidates, &highest); + + return 0; +} + diff --git a/plat/diameter/libfdproto/sessions.c b/plat/diameter/libfdproto/sessions.c new file mode 100644 index 0000000..2f7a65b --- /dev/null +++ b/plat/diameter/libfdproto/sessions.c @@ -0,0 +1,940 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Sessions module. + * + * Basic functionalities to help implementing User sessions state machines from RFC3588. + */ + +#include "fdproto-internal.h" + +/*********************** Parameters **********************/ + +/* Size of the hash table containing the session objects (pow of 2. ex: 6 => 2^6 = 64). must be between 0 and 31. */ +#ifndef SESS_HASH_SIZE +#define SESS_HASH_SIZE 6 +#endif /* SESS_HASH_SIZE */ + +/* Default lifetime of a session, in seconds. (31 days = 2678400 seconds) */ +#ifndef SESS_DEFAULT_LIFETIME +#define SESS_DEFAULT_LIFETIME 2678400 +#endif /* SESS_DEFAULT_LIFETIME */ + +/********************** /Parameters **********************/ + +/* Eyescatchers definitions */ +#define SH_EYEC 0x53554AD1 +#define SD_EYEC 0x5355D474 +#define SI_EYEC 0x53551D + +/* Macro to check an object is valid */ +#define VALIDATE_SH( _obj ) ( ((_obj) != NULL) && ( ((struct session_handler *)(_obj))->eyec == SH_EYEC) ) +#define VALIDATE_SI( _obj ) ( ((_obj) != NULL) && ( ((struct session *)(_obj))->eyec == SI_EYEC) ) + + +/* Handlers registered by users of the session module */ +struct session_handler { + int eyec; /* An eye catcher also used to ensure the object is valid, must be SH_EYEC */ + int id; /* A unique integer to identify this handler */ + void (*cleanup)(struct sess_state *, os0_t, void *); /* The cleanup function to be called for cleaning a state */ + session_state_dump state_dump; /* dumper function */ + void *opaque; /* a value that is passed as is to the cleanup callback */ +}; + +static int hdl_id = 0; /* A global counter to initialize the id field */ +static pthread_mutex_t hdl_lock = PTHREAD_MUTEX_INITIALIZER; /* lock to protect hdl_id; we could use atomic operations otherwise (less portable) */ + + +/* Data structures linked from the sessions, containing the applications states */ +struct state { + int eyec; /* Must be SD_EYEC */ + struct sess_state *state; /* The state registered by the application, never NULL (or the whole object is deleted) */ + struct fd_list chain; /* Chaining in the list of session's states ordered by hdl->id */ + union { + struct session_handler *hdl; /* The handler for which this state was registered */ + os0_t sid; /* For deleted state, the sid of the session it belong to */ + }; +}; + +/* Session object, one for each value of Session-Id AVP */ +struct session { + int eyec; /* Eyecatcher, SI_EYEC */ + + os0_t sid; /* The \0-terminated Session-Id */ + size_t sidlen; /* cached length of sid */ + uint32_t hash; /* computed hash of sid */ + struct fd_list chain_h;/* chaining in the hash table of sessions. */ + + struct timespec timeout;/* Timeout date for the session */ + struct fd_list expire; /* List of expiring sessions, ordered by timeouts. */ + + pthread_mutex_t stlock; /* A lock to protect the list of states associated with this session */ + struct fd_list states; /* Sentinel for the list of states of this session. */ + int msg_cnt;/* Reference counter for the messages pointing to this session */ + int is_destroyed; /* boolean telling if fd_sess_detroy has been called on this */ +}; + +/* Sessions hash table, to allow fast sid to session retrieval */ +static struct { + struct fd_list sentinel; /* sentinel element for this sublist. The sublist is ordered by hash value, then fd_os_cmp(sid). */ + pthread_mutex_t lock; /* the mutex for this sublist -- we might probably change it to rwlock for a little optimization */ +} sess_hash [ 1 << SESS_HASH_SIZE ] ; +#define H_MASK( __hash ) ((__hash) & (( 1 << SESS_HASH_SIZE ) - 1)) +#define H_LIST( _hash ) (&(sess_hash[H_MASK(_hash)].sentinel)) +#define H_LOCK( _hash ) (&(sess_hash[H_MASK(_hash)].lock )) + +static uint32_t sess_cnt = 0; /* counts all active session (that are in the expiry list) */ + +/* The following are used to generate sid values that are eternaly unique */ +static uint32_t sid_h; /* initialized to the current time in fd_sess_init */ +static uint32_t sid_l; /* incremented each time a session id is created */ +static pthread_mutex_t sid_lock = PTHREAD_MUTEX_INITIALIZER; + +/* Expiring sessions management */ +static struct fd_list exp_sentinel = FD_LIST_INITIALIZER(exp_sentinel); /* list of sessions ordered by their timeout date */ +static pthread_mutex_t exp_lock = PTHREAD_MUTEX_INITIALIZER; /* lock protecting the list. */ +static pthread_cond_t exp_cond = PTHREAD_COND_INITIALIZER; /* condvar used by the expiry mecahinsm. */ +static pthread_t exp_thr = (pthread_t)NULL; /* The expiry thread that handles cleanup of expired sessions */ + +/* Hierarchy of the locks, to avoid deadlocks: + * hash lock > state lock > expiry lock + * i.e. state lock can be taken while holding the hash lock, but not while holding the expiry lock. + * As well, the hash lock cannot be taken while holding a state lock. + */ + +/********************************************************************************************************/ + +/* Initialize a session object. It is not linked now. sid must be already malloc'ed. The hash has already been computed. */ +static struct session * new_session(os0_t sid, size_t sidlen, uint32_t hash) +{ + struct session * sess; + + TRACE_ENTRY("%p %zd", sid, sidlen); + CHECK_PARAMS_DO( sid && sidlen, return NULL ); + + CHECK_MALLOC_DO( sess = malloc(sizeof(struct session)), return NULL ); + memset(sess, 0, sizeof(struct session)); + + sess->eyec = SI_EYEC; + + sess->sid = sid; + sess->sidlen = sidlen; + sess->hash = hash; + fd_list_init(&sess->chain_h, sess); + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &sess->timeout), return NULL ); + sess->timeout.tv_sec += SESS_DEFAULT_LIFETIME; + fd_list_init(&sess->expire, sess); + + CHECK_POSIX_DO( pthread_mutex_init(&sess->stlock, NULL), return NULL ); + fd_list_init(&sess->states, sess); + + return sess; +} + +/* destroy the session object. It should really be already unlinked... */ +static void del_session(struct session * s) +{ + ASSERT(FD_IS_LIST_EMPTY(&s->states)); + free(s->sid); + fd_list_unlink(&s->chain_h); + fd_list_unlink(&s->expire); + CHECK_POSIX_DO( pthread_mutex_destroy(&s->stlock), /* continue */ ); + free(s); +} + +/* The expiry thread */ +static void * exp_fct(void * arg) +{ + fd_log_threadname ( "Session/expire" ); + TRACE_ENTRY( "" ); + + + do { + struct timespec now; + struct session * first; + + CHECK_POSIX_DO( pthread_mutex_lock(&exp_lock), break ); + pthread_cleanup_push( fd_cleanup_mutex, &exp_lock ); +again: + /* Check if there are expiring sessions available */ + if (FD_IS_LIST_EMPTY(&exp_sentinel)) { + /* Just wait for a change or cancelation */ + CHECK_POSIX_DO( pthread_cond_wait( &exp_cond, &exp_lock ), break /* this might not pop the cleanup handler, but since we ASSERT(0), it is not the big issue... */ ); + /* Restart the loop on wakeup */ + goto again; + } + + /* Get the pointer to the session that expires first */ + first = (struct session *)(exp_sentinel.next->o); + ASSERT( VALIDATE_SI(first) ); + + /* Get the current time */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), break ); + + /* If first session is not expired, we just wait until it happens */ + if ( TS_IS_INFERIOR( &now, &first->timeout ) ) { + + CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cond, &exp_lock, &first->timeout ), + ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */, + /* on other error, */ break ); + + /* on wakeup, loop */ + goto again; + } + + /* Now, the first session in the list is expired; destroy it */ + pthread_cleanup_pop( 0 ); + CHECK_POSIX_DO( pthread_mutex_unlock(&exp_lock), break ); + + CHECK_FCT_DO( fd_sess_destroy( &first ), break ); + + } while (1); + + TRACE_DEBUG(INFO, "A system error occurred in session module! Expiry thread is terminating..."); + ASSERT(0); + return NULL; +} + + + +/********************************************************************************************************/ + +/* Initialize the session module */ +int fd_sess_init(void) +{ + int i; + + TRACE_ENTRY( "" ); + + /* Initialize the global counters */ + sid_h = (uint32_t) time(NULL); + sid_l = 0; + + /* Initialize the hash table */ + for (i = 0; i < sizeof(sess_hash) / sizeof(sess_hash[0]); i++) { + fd_list_init( &sess_hash[i].sentinel, NULL ); + CHECK_POSIX( pthread_mutex_init(&sess_hash[i].lock, NULL) ); + } + + return 0; +} + +/* Run this when initializations are complete. */ +int fd_sess_start(void) +{ + /* Start session garbage collector (expiry) */ + CHECK_POSIX( pthread_create(&exp_thr, NULL, exp_fct, NULL) ); + + return 0; +} + +/* Terminate */ +void fd_sess_fini(void) +{ + TRACE_ENTRY(""); + CHECK_FCT_DO( fd_thr_term(&exp_thr), /* continue */ ); + + /* Destroy all sessions in the hash table, and the hash table itself? -- How to do it without a race condition ? */ + + return; +} + +/* Create a new handler */ +int fd_sess_handler_create ( struct session_handler ** handler, void (*cleanup)(struct sess_state *, os0_t, void *), session_state_dump dumper, void * opaque ) +{ + struct session_handler *new; + + TRACE_ENTRY("%p %p", handler, cleanup); + + CHECK_PARAMS( handler && cleanup ); + + CHECK_MALLOC( new = malloc(sizeof(struct session_handler)) ); + memset(new, 0, sizeof(struct session_handler)); + + CHECK_POSIX( pthread_mutex_lock(&hdl_lock) ); + new->id = ++hdl_id; + CHECK_POSIX( pthread_mutex_unlock(&hdl_lock) ); + + new->eyec = SH_EYEC; + new->cleanup = cleanup; + new->state_dump = dumper; + new->opaque = opaque; + + *handler = new; + return 0; +} + +/* Destroy a handler, and all states attached to this handler. This operation is very slow but we don't care since it's rarely used. + * Note that it's better to call this function after all sessions have been deleted... */ +int fd_sess_handler_destroy ( struct session_handler ** handler, void ** opaque ) +{ + struct session_handler * del; + /* place to save the list of states to be cleaned up. We do it after finding them to avoid deadlocks. the "o" field becomes a copy of the sid. */ + struct fd_list deleted_states = FD_LIST_INITIALIZER( deleted_states ); + int i; + + TRACE_ENTRY("%p", handler); + CHECK_PARAMS( handler && VALIDATE_SH(*handler) ); + + del = *handler; + *handler = NULL; + + del->eyec = 0xdead; /* The handler is not valid anymore for any other operation */ + + /* Now find all sessions with data registered for this handler, and move this data to the deleted_states list. */ + for (i = 0; i < sizeof(sess_hash) / sizeof(sess_hash[0]); i++) { + struct fd_list * li_si; + CHECK_POSIX( pthread_mutex_lock(&sess_hash[i].lock) ); + + for (li_si = sess_hash[i].sentinel.next; li_si != &sess_hash[i].sentinel; li_si = li_si->next) { /* for each session in the hash line */ + struct fd_list * li_st; + struct session * sess = (struct session *)(li_si->o); + CHECK_POSIX( pthread_mutex_lock(&sess->stlock) ); + for (li_st = sess->states.next; li_st != &sess->states; li_st = li_st->next) { /* for each state in this session */ + struct state * st = (struct state *)(li_st->o); + /* The list is ordered */ + if (st->hdl->id < del->id) + continue; + if (st->hdl->id == del->id) { + /* This state belongs to the handler we are deleting, move the item to the deleted_states list */ + fd_list_unlink(&st->chain); + st->sid = sess->sid; + fd_list_insert_before(&deleted_states, &st->chain); + } + break; + } + CHECK_POSIX( pthread_mutex_unlock(&sess->stlock) ); + } + CHECK_POSIX( pthread_mutex_unlock(&sess_hash[i].lock) ); + } + + /* Now, delete all states after calling their cleanup handler */ + while (!FD_IS_LIST_EMPTY(&deleted_states)) { + struct state * st = (struct state *)(deleted_states.next->o); + TRACE_DEBUG(FULL, "Calling cleanup handler for session '%s' and data %p", st->sid, st->state); + (*del->cleanup)(st->state, st->sid, del->opaque); + fd_list_unlink(&st->chain); + free(st); + } + + if (opaque) + *opaque = del->opaque; + + /* Free the handler */ + free(del); + + return 0; +} + + + +/* Create a new session object with the default timeout value, and link it. The refcount is increased by 1, whether the session existed or not */ +int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen ) +{ + os0_t sid = NULL; + size_t sidlen; + uint32_t hash; + struct session * sess; + struct fd_list * li; + int found = 0; + int ret = 0; + + TRACE_ENTRY("%p %p %zd %p %zd", session, diamid, diamidlen, opt, optlen); + CHECK_PARAMS( session && (diamid || opt) ); + + if (diamid) { + if (!diamidlen) { + diamidlen = strlen(diamid); + } + /* We check if the string is a valid DiameterIdentity */ + CHECK_PARAMS( fd_os_is_valid_DiameterIdentity((uint8_t *)diamid, diamidlen) ); + } else { + diamidlen = 0; + } + if (opt) { + if (!optlen) { + optlen = strlen((char *)opt); + } else { + CHECK_PARAMS( fd_os_is_valid_os0(opt, optlen) ); + } + } else { + optlen = 0; + } + + /* Ok, first create the identifier for the string */ + if (diamid == NULL) { + /* opt is the full string */ + CHECK_MALLOC( sid = os0dup(opt, optlen) ); + sidlen = optlen; + } else { + uint32_t sid_h_cpy; + uint32_t sid_l_cpy; + /* ";;[;opt]" */ + sidlen = diamidlen; + sidlen += 22; /* max size of ';;' */ + if (opt) + sidlen += 1 + optlen; /* ';opt' */ + sidlen++; /* space for the final \0 also */ + CHECK_MALLOC( sid = malloc(sidlen) ); + + CHECK_POSIX( pthread_mutex_lock(&sid_lock) ); + if ( ++sid_l == 0 ) /* overflow */ + ++sid_h; + sid_h_cpy = sid_h; + sid_l_cpy = sid_l; + CHECK_POSIX( pthread_mutex_unlock(&sid_lock) ); + + if (opt) { + sidlen = snprintf((char*)sid, sidlen, "%.*s;%u;%u;%.*s", (int)diamidlen, diamid, sid_h_cpy, sid_l_cpy, (int)optlen, opt); + } else { + sidlen = snprintf((char*)sid, sidlen, "%.*s;%u;%u", (int)diamidlen, diamid, sid_h_cpy, sid_l_cpy); + } + } + + hash = fd_os_hash(sid, sidlen); + + /* Now find the place to add this object in the hash table. */ + CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash) ) ); + pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); + + for (li = H_LIST(hash)->next; li != H_LIST(hash); li = li->next) { + int cmp; + struct session * s = (struct session *)(li->o); + + /* The list is ordered by hash and sid (in case of collisions) */ + if (s->hash < hash) + continue; + if (s->hash > hash) + break; + + cmp = fd_os_cmp(s->sid, s->sidlen, sid, sidlen); + if (cmp < 0) + continue; + if (cmp > 0) + break; + + /* A session with the same sid was already in the hash table */ + found = 1; + *session = s; + break; + } + + /* If the session did not exist, we can create it & link it in global tables */ + if (!found) { + CHECK_MALLOC_DO(sess = new_session(sid, sidlen, hash), + { + ret = ENOMEM; + free(sid); + goto out; + } ); + + fd_list_insert_before(li, &sess->chain_h); /* hash table */ + sess->msg_cnt++; + } else { + free(sid); + + CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) ); + (*session)->msg_cnt++; + CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); + + /* it was found: was it previously destroyed? */ + if ((*session)->is_destroyed == 0) { + ret = EALREADY; + goto out; + } else { + /* the session was marked destroyed, let's re-activate it. */ + sess = *session; + sess->is_destroyed = 0; + + /* update the expiry time */ + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &sess->timeout), { ASSERT(0); } ); + sess->timeout.tv_sec += SESS_DEFAULT_LIFETIME; + } + } + + /* We must insert in the expiry list */ + CHECK_POSIX( pthread_mutex_lock( &exp_lock ) ); + pthread_cleanup_push( fd_cleanup_mutex, &exp_lock ); + + /* Find the position in that list. We take it in reverse order */ + for (li = exp_sentinel.prev; li != &exp_sentinel; li = li->prev) { + struct session * s = (struct session *)(li->o); + if (TS_IS_INFERIOR( &s->timeout, &sess->timeout ) ) + break; + } + fd_list_insert_after( li, &sess->expire ); + sess_cnt++; + + /* We added a new expiring element, we must signal */ + if (li == &exp_sentinel) { + CHECK_POSIX_DO( pthread_cond_signal(&exp_cond), { ASSERT(0); } ); /* if it fails, we might not pop the cleanup handlers, but this should not happen -- and we'd have a serious problem otherwise */ + } + + /* We're done with the locked part */ + pthread_cleanup_pop(0); + CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); } ); /* if it fails, we might not pop the cleanup handler, but this should not happen -- and we'd have a serious problem otherwise */ + +out: + ; + pthread_cleanup_pop(0); + CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) ); + + if (ret) /* in case of error */ + return ret; + + *session = sess; + return 0; +} + +/* Find or create a session -- the msg refcount is increased */ +int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new) +{ + int ret; + + TRACE_ENTRY("%p %zd %p %p", sid, len, session, new); + CHECK_PARAMS( sid && session ); + + if (!fd_os_is_valid_os0(sid,len)) { + TRACE_DEBUG(INFO, "Warning: a Session-Id value contains \\0 chars... (len:%zd, begin:'%.*s') => Debug messages may be truncated.", len, (int)len, sid); + } + + /* All the work is done in sess_new */ + ret = fd_sess_new ( session, NULL, 0, sid, len ); + switch (ret) { + case 0: + case EALREADY: + break; + + default: + CHECK_FCT(ret); + } + + if (new) + *new = ret ? 0 : 1; + + return 0; +} + +/* Get the sid of a session */ +int fd_sess_getsid ( struct session * session, os0_t * sid, size_t * sidlen ) +{ + TRACE_ENTRY("%p %p", session, sid); + + CHECK_PARAMS( VALIDATE_SI(session) && sid ); + + *sid = session->sid; + if (sidlen) + *sidlen = session->sidlen; + + return 0; +} + +/* Change the timeout value of a session */ +int fd_sess_settimeout( struct session * session, const struct timespec * timeout ) +{ + struct fd_list * li; + + TRACE_ENTRY("%p %p", session, timeout); + CHECK_PARAMS( VALIDATE_SI(session) && timeout ); + + /* Lock -- do we need to lock the hash table as well? I don't think so... */ + CHECK_POSIX( pthread_mutex_lock( &exp_lock ) ); + pthread_cleanup_push( fd_cleanup_mutex, &exp_lock ); + + /* Update the timeout */ + fd_list_unlink(&session->expire); + memcpy(&session->timeout, timeout, sizeof(struct timespec)); + + /* Find the new position in expire list. We take it in normal order */ + for (li = exp_sentinel.next; li != &exp_sentinel; li = li->next) { + struct session * s = (struct session *)(li->o); + + if (TS_IS_INFERIOR( &s->timeout, &session->timeout ) ) + continue; + + break; + } + fd_list_insert_before( li, &session->expire ); + + /* We added a new expiring element, we must signal if it was in first position */ + if (session->expire.prev == &exp_sentinel) { + CHECK_POSIX_DO( pthread_cond_signal(&exp_cond), { ASSERT(0); /* so that we don't have a pending cancellation handler */ } ); + } + + /* We're done */ + pthread_cleanup_pop(0); + CHECK_POSIX( pthread_mutex_unlock( &exp_lock ) ); + + return 0; +} + +/* Destroy the states associated to a session, and mark it destroyed. */ +int fd_sess_destroy ( struct session ** session ) +{ + struct session * sess; + int destroy_now; + os0_t sid; + int ret = 0; + + /* place to save the list of states to be cleaned up. We do it after finding them to avoid deadlocks. the "o" field becomes a copy of the sid. */ + struct fd_list deleted_states = FD_LIST_INITIALIZER( deleted_states ); + + TRACE_ENTRY("%p", session); + CHECK_PARAMS( session && VALIDATE_SI(*session) ); + + sess = *session; + *session = NULL; + + /* Lock the hash line */ + CHECK_POSIX( pthread_mutex_lock( H_LOCK(sess->hash) ) ); + pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(sess->hash) ); + + /* Unlink from the expiry list */ + CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); + if (!FD_IS_LIST_EMPTY(&sess->expire)) { + sess_cnt--; + fd_list_unlink( &sess->expire ); /* no need to signal the condition here */ + } + CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); + + /* Now move all states associated to this session into deleted_states */ + CHECK_POSIX_DO( pthread_mutex_lock( &sess->stlock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); + while (!FD_IS_LIST_EMPTY(&sess->states)) { + struct state * st = (struct state *)(sess->states.next->o); + fd_list_unlink(&st->chain); + fd_list_insert_before(&deleted_states, &st->chain); + } + CHECK_POSIX_DO( pthread_mutex_unlock( &sess->stlock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); + + /* Mark the session as destroyed */ + destroy_now = (sess->msg_cnt == 0); + if (destroy_now) { + fd_list_unlink( &sess->chain_h ); + sid = sess->sid; + } else { + sess->is_destroyed = 1; + CHECK_MALLOC_DO( sid = os0dup(sess->sid, sess->sidlen), ret = ENOMEM ); + } + pthread_cleanup_pop(0); + CHECK_POSIX( pthread_mutex_unlock( H_LOCK(sess->hash) ) ); + + if (ret) + return ret; + + /* Now, really delete the states */ + while (!FD_IS_LIST_EMPTY(&deleted_states)) { + struct state * st = (struct state *)(deleted_states.next->o); + fd_list_unlink(&st->chain); + TRACE_DEBUG(FULL, "Calling handler %p cleanup for state %p registered with session '%s'", st->hdl, st, sid); + (*st->hdl->cleanup)(st->state, sid, st->hdl->opaque); + free(st); + } + + /* Finally, destroy the session itself, if it is not referrenced by any message anymore */ + if (destroy_now) { + del_session(sess); + } else { + free(sid); + } + + return 0; +} + +/* Destroy a session if it is not used */ +int fd_sess_reclaim ( struct session ** session ) +{ + struct session * sess; + uint32_t hash; + int destroy_now = 0; + + TRACE_ENTRY("%p", session); + CHECK_PARAMS( session && VALIDATE_SI(*session) ); + + sess = *session; + hash = sess->hash; + *session = NULL; + + CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash) ) ); + pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); + CHECK_POSIX_DO( pthread_mutex_lock( &sess->stlock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } ); + pthread_cleanup_push( fd_cleanup_mutex, &sess->stlock ); + CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } ); + + /* We only do something if the states list is empty */ + if (FD_IS_LIST_EMPTY(&sess->states)) { + /* In this case, we do as in destroy */ + fd_list_unlink( &sess->expire ); + destroy_now = (sess->msg_cnt == 0); + if (destroy_now) { + fd_list_unlink(&sess->chain_h); + } else { + /* just mark it as destroyed, it will be freed when the last message stops referencing it */ + sess->is_destroyed = 1; + } + } + + CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } ); + pthread_cleanup_pop(0); + CHECK_POSIX_DO( pthread_mutex_unlock( &sess->stlock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } ); + pthread_cleanup_pop(0); + CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) ); + + if (destroy_now) + del_session(sess); + + return 0; +} + +/* Save a state information with a session */ +int fd_sess_state_store ( struct session_handler * handler, struct session * session, struct sess_state ** state ) +{ + struct state *new; + struct fd_list * li; + int already = 0; + int ret = 0; + + TRACE_ENTRY("%p %p %p", handler, session, state); + CHECK_PARAMS( handler && VALIDATE_SH(handler) && session && VALIDATE_SI(session) && (!session->is_destroyed) && state ); + + /* Lock the session state list */ + CHECK_POSIX( pthread_mutex_lock(&session->stlock) ); + pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); + + /* Create the new state object */ + CHECK_MALLOC_DO(new = malloc(sizeof(struct state)), { ret = ENOMEM; goto out; } ); + memset(new, 0, sizeof(struct state)); + + new->eyec = SD_EYEC; + new->state= *state; + fd_list_init(&new->chain, new); + new->hdl = handler; + + /* find place for this state in the list */ + for (li = session->states.next; li != &session->states; li = li->next) { + struct state * st = (struct state *)(li->o); + /* The list is ordered by handler's id */ + if (st->hdl->id < handler->id) + continue; + + if (st->hdl->id == handler->id) { + TRACE_DEBUG(INFO, "A state was already stored for session '%s' and handler '%p', at location %p", session->sid, st->hdl, st->state); + already = EALREADY; + } + + break; + } + + if (!already) { + fd_list_insert_before(li, &new->chain); + *state = NULL; + } else { + free(new); + } +out: + ; + pthread_cleanup_pop(0); + CHECK_POSIX( pthread_mutex_unlock(&session->stlock) ); + + return ret ?: already; +} + +/* Get the data back */ +int fd_sess_state_retrieve ( struct session_handler * handler, struct session * session, struct sess_state ** state ) +{ + struct fd_list * li; + struct state * st = NULL; + + TRACE_ENTRY("%p %p %p", handler, session, state); + CHECK_PARAMS( handler && VALIDATE_SH(handler) && session && VALIDATE_SI(session) && state ); + + *state = NULL; + + /* Lock the session state list */ + CHECK_POSIX( pthread_mutex_lock(&session->stlock) ); + pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); + + /* find the state in the list */ + for (li = session->states.next; li != &session->states; li = li->next) { + st = (struct state *)(li->o); + + /* The list is ordered by handler's id */ + if (st->hdl->id > handler->id) + break; + } + + /* If we found the state */ + if (st && (st->hdl == handler)) { + fd_list_unlink(&st->chain); + *state = st->state; + free(st); + } + + pthread_cleanup_pop(0); + CHECK_POSIX( pthread_mutex_unlock(&session->stlock) ); + + return 0; +} + +/* For the messages module */ +int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new) +{ + TRACE_ENTRY("%p %zd %p %p", sid, len, session, new); + CHECK_PARAMS( sid && len && session ); + + /* Get the session object */ + CHECK_FCT( fd_sess_fromsid_msg ( sid, len, session, new) ); + + /* Decrease the refcount */ + CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) ); + (*session)->msg_cnt--; /* was increased in fd_sess_new */ + CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); + + /* Done */ + return 0; +} + +int fd_sess_ref_msg ( struct session * session ) +{ + TRACE_ENTRY("%p", session); + CHECK_PARAMS( VALIDATE_SI(session) ); + + /* Update the msg refcount */ + CHECK_POSIX( pthread_mutex_lock(&session->stlock) ); + session->msg_cnt++; + CHECK_POSIX( pthread_mutex_unlock(&session->stlock) ); + + return 0; +} + +int fd_sess_reclaim_msg ( struct session ** session ) +{ + int reclaim; + uint32_t hash; + + TRACE_ENTRY("%p", session); + CHECK_PARAMS( session && VALIDATE_SI(*session) ); + + /* Lock the hash line to avoid possibility that session is freed while we are reclaiming */ + hash = (*session)->hash; + CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash)) ); + pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); + + /* Update the msg refcount */ + CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) ); + reclaim = (*session)->msg_cnt; + (*session)->msg_cnt = reclaim - 1; + CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); + + /* Ok, now unlock the hash line */ + pthread_cleanup_pop( 0 ); + CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) ); + + /* and reclaim if no message references the session anymore */ + if (reclaim == 1) { + CHECK_FCT(fd_sess_reclaim ( session )); + } else { + *session = NULL; + } + return 0; +} + + + +/* Dump functions */ +DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump, struct session * session, int with_states) +{ + FD_DUMP_HANDLE_OFFSET(); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{session}(@%p): ", session), return NULL); + + if (!VALIDATE_SI(session)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); + } else { + char timebuf[30]; + struct tm tm; + + strftime(timebuf, sizeof(timebuf), "%D,%T", localtime_r( &session->timeout.tv_sec , &tm )); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%zd) h:%x m:%d d:%d to:%s.%06ld", + session->sid, session->sidlen, session->hash, session->msg_cnt, session->is_destroyed, + timebuf, session->timeout.tv_nsec/1000), + return NULL); + + if (with_states) { + struct fd_list * li; + CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ ); + pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); + + for (li = session->states.next; li != &session->states; li = li->next) { + struct state * st = (struct state *)(li->o); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {state i:%d}(@%p): ", st->hdl->id, st), return NULL); + if (st->hdl->state_dump) { + CHECK_MALLOC_DO( (*st->hdl->state_dump)( FD_DUMP_STD_PARAMS, st->state), + fd_dump_extend( FD_DUMP_STD_PARAMS, "[dumper error]")); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<%p>", st->state), return NULL); + } + } + + pthread_cleanup_pop(0); + CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ ); + } + } + + return *buf; +} + +DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump_hdl, struct session_handler * handler) +{ + FD_DUMP_HANDLE_OFFSET(); + + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{sesshdl}(@%p): ", handler), return NULL); + + if (!VALIDATE_SH(handler)) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "i:%d cl:%p d:%p o:%p", handler->id, handler->cleanup, handler->state_dump, handler->opaque), return NULL); + } + return *buf; +} + +int fd_sess_getcount(uint32_t *cnt) +{ + CHECK_PARAMS(cnt); + CHECK_POSIX( pthread_mutex_lock( &exp_lock ) ); + *cnt = sess_cnt; + CHECK_POSIX( pthread_mutex_unlock( &exp_lock ) ); + return 0; +} diff --git a/plat/diameter/libfdproto/utils.c b/plat/diameter/libfdproto/utils.c new file mode 100644 index 0000000..fdcd8de --- /dev/null +++ b/plat/diameter/libfdproto/utils.c @@ -0,0 +1,84 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" + +DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump, sSA * sa, int flags) +{ + char addrbuf[INET6_ADDRSTRLEN]; + char servbuf[32]; + int rc; + FD_DUMP_HANDLE_OFFSET(); + + servbuf[0] = 0; + + if (sa) { + if (sSAport(sa)) { + rc = getnameinfo(sa, sSAlen( sa ), addrbuf, sizeof(addrbuf), servbuf, sizeof(servbuf), flags); + } else { + rc = getnameinfo(sa, sSAlen( sa ), addrbuf, sizeof(addrbuf), NULL, 0, flags); + } + if (rc) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", gai_strerror(rc)), return NULL); + } else { + if (servbuf[0]) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s(%s)", &addrbuf[0], &servbuf[0]), return NULL); + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", &addrbuf[0]), return NULL); + } + } + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(NULL / ANY)"), return NULL); + } + return *buf; +} + +void fd_sa_sdump_numeric(char * buf /* must be at least sSA_DUMP_STRLEN */, sSA * sa) +{ + char addrbuf[INET6_ADDRSTRLEN]; + char servbuf[32]; + + if (sa) { + int rc = getnameinfo(sa, sSAlen( sa ), addrbuf, sizeof(addrbuf), servbuf, sizeof(servbuf), NI_NUMERICHOST | NI_NUMERICSERV); + if (rc) { + snprintf(buf, sSA_DUMP_STRLEN, "%s", gai_strerror(rc)); + } else { + snprintf(buf, sSA_DUMP_STRLEN, "%s(%s)", addrbuf, servbuf); + } + } else { + snprintf(buf, sSA_DUMP_STRLEN, "(NULL / ANY)"); + } + +} diff --git a/plat/diameter/libfdproto/version.c b/plat/diameter/libfdproto/version.c new file mode 100644 index 0000000..3248a47 --- /dev/null +++ b/plat/diameter/libfdproto/version.c @@ -0,0 +1,47 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdproto-internal.h" +#include "version.h" + +#ifdef FD_PROJECT_VERSION_HG +# define FD_LIBFDPROTO_VERSION \ + _stringize(FD_PROJECT_VERSION_MAJOR) "." _stringize(FD_PROJECT_VERSION_MINOR) "." _stringize(FD_PROJECT_VERSION_REV) "-" FD_PROJECT_VERSION_HG_VAL +#else +# define FD_LIBFDPROTO_VERSION \ + _stringize(FD_PROJECT_VERSION_MAJOR) "." _stringize(FD_PROJECT_VERSION_MINOR) "." _stringize(FD_PROJECT_VERSION_REV) +#endif + +const char fd_libproto_version[] = FD_LIBFDPROTO_VERSION; diff --git a/plat/diameter/makefile b/plat/diameter/makefile new file mode 100644 index 0000000..b09decb --- /dev/null +++ b/plat/diameter/makefile @@ -0,0 +1,29 @@ +#make gnproto + +####################### IDC ######################################### +TOPDIR:=. +TGT:=./fdSHApp + +DIR=$(TOPDIR)/libfdcore $(TOPDIR)/libfdproto $(TOPDIR)/freeDiameterd $(TOPDIR)/extensions/sh_app $(TOPDIR)/include/freeDiameter +SRCS=$(foreach dir, $(DIR), $(wildcard $(dir)/*.c)) +OBJS:=$(patsubst %.c,%.o,$(SRCS)) +MAIN=$(TOPDIR)/daemon/daemon.c + +INCDIR=$(foreach dir, $(DIR), -I $(dir)/ ) +LIBS=-lpthread -ldl -lcrypt -lnsl -lm -lrt -lsctp -lgcrypt -lgnutls /usr/lib/x86_64-linux-gnu/libidn.a + +CFLAGS=-Wall -g -DDEBUG -DX86_64 -lm -lrt -ldl -lsctp -lgcrypt -lgnutls -lpthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -I/usr/local/lib/glib-2.0/include -L/usr/local/lib -lglib-2.0 + +#CFLAGS=-Wall -g -DDEBUG -DX86_64 -lm -lrt -ldl -lsctp -lgcrypt -lgnutls -lpthread + +CC=gcc + +$(TGT):$(OBJS) +# $(CC) -o $(TGT) $(CFLAGS) $(MAIN) $(SRCS) $(INCDIR) $(LIBS) +# chmod a+x $(TGT) + ar r ./lib/libdiameter.a $(OBJS) + +$(OBJS):%.o:%.c + $(CC) $(CFLAGS) -c -o $@ $< $(INCDIR) +clean: + rm -rf $(OBJS) $(TGT) diff --git a/plat/diameter/makefile.new b/plat/diameter/makefile.new new file mode 100644 index 0000000..ab70f8a --- /dev/null +++ b/plat/diameter/makefile.new @@ -0,0 +1,26 @@ +#make gnproto + +####################### IDC ######################################### +TOPDIR:=. +TGT:=./fdSHApp + +DIR=$(TOPDIR)/libfdcore $(TOPDIR)/libfdproto $(TOPDIR)/freeDiameterd $(TOPDIR)/extensions/sh_app $(TOPDIR)/include/freeDiameter +SRCS=$(foreach dir, $(DIR), $(wildcard $(dir)/*.c)) +OBJS:=$(patsubst %.c,%.o,$(SRCS)) +MAIN=$(TOPDIR)/daemon/daemon.c + +INCDIR=$(foreach dir, $(DIR), -I $(dir)/ ) +LIBS=-lpthread -ldl -lcrypt -lnsl -lm -lrt -lsctp -lgcrypt -lgnutls /usr/lib/x86_64-linux-gnu/libidn.a + +CFLAGS=-Wall -g -DDEBUG -DX86_64 -lm -lrt -ldl -lsctp -lgcrypt -lgnutls -lpthread + +CC=gcc + +$(TGT):$(OBJS) + $(CC) -o $(TGT) $(CFLAGS) $(MAIN) $(SRCS) $(INCDIR) $(LIBS) + chmod a+x $(TGT) + +$(OBJS):%.o:%.c + $(CC) $(CFLAGS) -c -o $@ $< $(INCDIR) +clean: + rm -rf $(OBJS) $(TGT) diff --git a/plat/iptrans/Makefile b/plat/iptrans/Makefile new file mode 100644 index 0000000..8fd1483 --- /dev/null +++ b/plat/iptrans/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = iptrans +TYPE = plat + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/iptrans/src/comfunc.c b/plat/iptrans/src/comfunc.c new file mode 100644 index 0000000..ef603c6 --- /dev/null +++ b/plat/iptrans/src/comfunc.c @@ -0,0 +1,81 @@ +/* +** CVS: $Id: comfunc.c,v 1.3 2001/01/20 19:58:49 zhangsz Exp $ +** +** Title: comfunc.c +** Author: Zhang Shuzhong +** Date: 2000.07.03 +** +** Description: Functions of comunication for PACS WLL. +** +*/ + +#include "../../public/src/include/includes.h" + +/* +** passivesock - allocate & bind a server socket using TCP or UDP +*/ + +/*@ignore@*/ +int +passivesock( const char * transport, u_short portbase, int qlen) +{ +struct sockaddr_in sin; +int s, type; + + memset(& sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(portbase); + sin.sin_addr.s_addr = INADDR_ANY; + bzero(&(sin.sin_zero), 8); + + if ( strcmp(transport, "UDP") == 0) + type = SOCK_DGRAM; + else + type = SOCK_STREAM; + s = socket(AF_INET, type, 0); + if (s < 0) { + perror("socket"); + return -3; + } + if (bind(s, (struct sockaddr *) & sin, sizeof(sin)) < 0) { + perror("bind"); + close(s); + return -4; + } + + if (type == SOCK_STREAM && listen(s, qlen) < 0) { + perror("listen"); + close(s); + return -5; + } + return s; +} + +/* +** passiveUDP - create a passive socket for use in a UDP server +*/ + +int +passiveUDP(u_short portbase) +{ + return (passivesock("UDP", portbase, 0) ); +} + +const char * +Inet_ntoa(const long addr) +{ + struct sockaddr_in sin; + + sin.sin_addr.s_addr = addr; + return ((char *) inet_ntoa(sin.sin_addr) ); +} + +const long +Inet_pton(const char *sp) +{ + struct in_addr i_addr; + + inet_pton(AF_INET, sp, &i_addr); + return i_addr.s_addr; +} +/*@end@*/ diff --git a/plat/iptrans/src/daemon.c b/plat/iptrans/src/daemon.c new file mode 100644 index 0000000..f46bf01 --- /dev/null +++ b/plat/iptrans/src/daemon.c @@ -0,0 +1,65 @@ +/* +** CVS: $Id: daemon.c,v 1.4 2001/01/11 04:03:57 zhangsz Exp $ +** daemon.c +** created at 2000/08/22 +** By Zhang Shuzhong. +** Functions of daemon process. +*/ +#include "./include/iptrans.h" +#include +#include + +#define MAXFD 64 + +/*@ignore@*/ +int +InitDaemon(void) +{ + pid_t pid; + + if ( (pid = fork()) < 0) + return FAILURE; + else if (pid != 0) + exit(0); /* parent goes bye-bye */ + /* child continues */ + setsid(); /* become session leader */ +// chdir("/"); /* change working direactory */ + umask(0); /* clear our file mode creation mask */ + return SUCCESS; +} + + +void +DaemonInit(const char *pname, int facility) +{ + int i; + pid_t pid; + + if ( (pid = fork()) < 0) /* parent terminates */ + err_sys("%s: %s: fork (%d)", + FILE_MACRO, FUNCTION_MACRO, LINE_MACRO); + else if (pid != 0) + exit(0); /* parent goes bye-bye */ + + /* 41st child continues */ + setsid(); /* become session leader */ + + signal(SIGHUP, SIG_IGN); + + if ( (pid = fork()) < 0) /* 1st child terminates */ + err_sys("%s: %s: fork (%d)", + FILE_MACRO, FUNCTION_MACRO, LINE_MACRO); + else if (pid != 0) + exit(0); /* 1st child goes bye-bye */ + + +// chdir("/"); /* change working directory */ + + umask(0); /* clear our file mode creation mask */ + + for (i = 0; i < MAXFD; i++) + close(i); + + openlog(pname, LOG_PID, facility); +} +/*@end@*/ diff --git a/plat/iptrans/src/error.c b/plat/iptrans/src/error.c new file mode 100644 index 0000000..432cb17 --- /dev/null +++ b/plat/iptrans/src/error.c @@ -0,0 +1,114 @@ +#include +#include /* for definition of errno */ +#include /* ANSI C header file */ +#include +#include "./include/iptrans.h" + +static void err_doit(int, const char *, va_list); + +char *pname = NULL; /* caller can set this from argv[0] */ + +/* +** Nonfatal error related to a system call. +** Print a message and return. +*/ + +/*@ignore@*/ +void +err_ret(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error related to a system call. +** Print a message and terminate. +*/ + +void +err_sys(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + exit(1); +} + +/* +** Fatal error related to a system call. +** Print a message, dump core, and terminate. +*/ + +void +err_dump(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + abort(); /* dump core and terminate */ + exit(1); /* shouldn't get here */ +} + +/* +** Nonfatal error unrelated to a system call. +** Print a message and return. +*/ + +void +err_msg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error unrelated to a system call. +** Print a message and terminate. +*/ + +void +err_quit(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, fmt, ap); + va_end(ap); + exit(1); +} + +/* +** Print a message and return to caller. +** Caller specifies "errnoflag". +*/ + +static void +err_doit(int errnoflag, const char *fmt, va_list ap) +{ + int errno_save; + char buf[MAXLINE]; + + errno_save = errno; /* value caller might want printed */ + vsprintf(buf, fmt, ap); + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcat(buf, "\n"); + fflush(stdout); /* in case stdout and stderr are the same */ + fputs(buf, stderr); + fflush(NULL); /* flushes all stdio output streams */ + return; +} +/*@end@*/ diff --git a/plat/iptrans/src/errorlog.c b/plat/iptrans/src/errorlog.c new file mode 100644 index 0000000..07526bc --- /dev/null +++ b/plat/iptrans/src/errorlog.c @@ -0,0 +1,131 @@ +/* Error routines for programs that can run as a daemon. */ + +#include /* for definition of errno */ +#include /* ANSI C header file */ +#include +#include "./include/iptrans.h" + +static void log_doit(int, int, const char *, va_list ap); + +int debug=1; /* caller must define and set this: + nonzero if interactive, zero if daemon */ + +int under_develop=1; /* caller must define and set this: + nonzero if under develop, zero if not */ + + +/*@ignore@*/ +/* Initialize syslog(), if running as daemon. */ +void +log_open(const char *ident, int option, int facility) +{ + if (debug == 0) + openlog(ident, option, facility); +} + +/* +** Nonfatal error related to a system call. +** Print a message with the system's errno value and return. +*/ + +void +log_ret(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + log_doit(1, LOG_ERR, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error related to a system call. +** Print a message and terminate. +*/ + +void +log_sys(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + log_doit(1, LOG_ERR, fmt, ap); + va_end(ap); + exit(2); +} + +/* +** Nonfatal error unrelated to a system call. +** Print a message and return. +*/ + +void +log_msg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + log_doit(0, LOG_ERR, fmt, ap); + va_end(ap); + return; +} + +/* +** Debug message unrelated to a system call. +** Print a message and return while . +*/ + +void +log_debug(const char *fmt, ...) +{ + va_list ap; + + if (!under_develop) return; + va_start(ap, fmt); + log_doit(0, LOG_ERR, fmt, ap); + va_end(ap); + return; +} + +/* +** Fatal error unrelated to a system call. +** Print a message and terminate. +*/ + +void +log_quit(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + log_doit(0, LOG_ERR, fmt, ap); + va_end(ap); + exit(2); +} + +/* +** Print a message and return to caller. +** Caller specifies "errnoflag" and "priority". +*/ + +static void +log_doit(int errnoflag, int priority, const char *fmt, va_list ap) +{ + int errno_save; + char buf[MAXLINE]; + + errno_save = errno; /* value caller might want printed */ + vsprintf(buf, fmt, ap); + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcat(buf, "\n"); + if (debug) { + fflush(stdout); + fputs(buf, stderr); + fflush(stderr); + } else + syslog(priority, "%s", buf); + return; +} +/*@end@*/ diff --git a/plat/iptrans/src/include/config.h b/plat/iptrans/src/include/config.h new file mode 100644 index 0000000..cbea268 --- /dev/null +++ b/plat/iptrans/src/include/config.h @@ -0,0 +1,23 @@ +/* +** PACS-WLL 2000 project, Prepaid System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** Written completely by Zhang Shuzhong at iCRD January, 2001 +** +** module name: config.h +** CVS $Id: config.h,v 1.2 2001/01/11 04:07:56 zhangsz Exp $ +** +** configuration of Prepaid System. +** +*/ + +#ifndef CONFIG__H +#define CONFIG__H + +#define HAVE_FUNCTION_MACRO 1 +#define HAVE_FILE_MACRO 1 +#define HAVE_TIME_MACRO 1 +#define HAVE_DATE_MACRO 1 +#define HAVE_LINE_MACRO 1 + +#endif /* endof CONFIG__H */ diff --git a/plat/iptrans/src/include/dbsync.h b/plat/iptrans/src/include/dbsync.h new file mode 100644 index 0000000..82601b1 --- /dev/null +++ b/plat/iptrans/src/include/dbsync.h @@ -0,0 +1,37 @@ +/* +** PACS-WLL 2000 project, Prepaid System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** Written completely by Zhang Shuzhong at iCRD January, 2001 +** +** file name: dbsync.h +** CVS $Id: dbsync.h,v 1.2 2001/02/08 10:53:33 zhangsz Exp $ +** +** Defination for Database Synchronization (dbsync.c). +*/ + +#ifndef DBSYNC__H +#define DBSYNC__H + +#include "iptrans.h" + +#define DS_PORT_NO 4959 /* Prepaid service port */ +#define DS_PORT_ID DS_PORT_NO - PORT_BASE_NUM + +#define DS_SHM_KEY 0x80000000 +#define DS_SHM_PERM 0664 +#define DS_MSG_TYPE "D0" +#define DS_DBNAME_MAX_LEN 14 +#define DS_SQLSCRIPT_MAX_LEN MAX_CONTENT_LEN-DS_DBNAME_MAX_LEN-2 + +typedef struct _dbsync_msg { + char type[2]; + char db_name[DS_DBNAME_MAX_LEN]; + char sql_script[DS_SQLSCRIPT_MAX_LEN]; +} _dbsync_msg; + +typedef struct ds_shm { + char time_created[15]; +} ds_shm; + +#endif /* DBSYNC__H */ diff --git a/plat/iptrans/src/include/debug.h b/plat/iptrans/src/include/debug.h new file mode 100644 index 0000000..2b6a548 --- /dev/null +++ b/plat/iptrans/src/include/debug.h @@ -0,0 +1,53 @@ +/* +** PACS-WLL 2000 project, Prepaid System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** +** Written completely by Zhang Shuzhong at iCRD January, 2001 +** +** file name: debug.h +** CVS $Id: debug.h,v 1.2 2001/01/20 19:58:49 zhangsz Exp $ +** +** The debug information defination. +** +*/ + +#ifndef DEBUG__H +#define DEBUG__H +#include "config.h" + +#define UNDER_DEVELOP 1 +#define DEBUG 1 + +/* If we have these macros, we can add additional info to the header. */ +#ifdef HAVE_FILE_MACRO +#define FILE_MACRO (__FILE__) +#else +#define FILE_MACRO ("") +#endif + +#ifdef HAVE_FUNCTION_MACRO +#define FUNCTION_MACRO (__FUNCTION__) +#else +#define FUNCTION_MACRO ("") +#endif + +#ifdef HAVE_DATE_MACRO +#define DATE_MACRO (__DATE__) +#else +#define DATE_MACRO ("") +#endif + +#ifdef HAVE_TIME_MACRO +#define TIME_MACRO (__TIME__) +#else +#define TIME_MACRO ("") +#endif + +#ifdef HAVE_LINE_MACRO +#define LINE_MACRO (__LINE__) +#else +#define LINE_MACRO ("") +#endif + +#endif /* DEBUG__H */ diff --git a/plat/iptrans/src/include/errlog.h b/plat/iptrans/src/include/errlog.h new file mode 100644 index 0000000..3d4bd76 --- /dev/null +++ b/plat/iptrans/src/include/errlog.h @@ -0,0 +1,39 @@ +/* +** Error and log proccess functions header file, +** to be included *after* all standard system headers +** +** CVS: $Id: errlog.h,v 1.2 2001/01/11 04:03:57 zhangsz Exp $ +*/ + +#ifndef ERRLOG__H +#define ERRLOG__H + +#include /* required for some of our prototypes */ +#include /* for convenience */ +#include /* for convenience */ +#include /* for convenience */ +#include /* for convenience */ + + /* default file access permissions for new files */ +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + + /* default permissions for new directories */ +#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH) + +#define log_flag() \ + log_debug("%s: %s: %d", FILE_MACRO, FUNCTION_MACRO, LINE_MACRO) + +void err_dump(const char *, ...); /* {App misc_source} */ +void err_msg(const char *, ...); +void err_quit(const char *, ...); +void err_ret(const char *, ...); +void err_sys(const char *, ...); + +void log_debug(const char *, ...); /* {App misc_source} */ +void log_msg(const char *, ...); /* {App misc_source} */ +void log_open(const char *, int, int); +void log_quit(const char *, ...); +void log_sys(const char *, ...); +void log_ret(const char *, ...); + +#endif /* ERRLOG__H */ diff --git a/plat/iptrans/src/include/function.h b/plat/iptrans/src/include/function.h new file mode 100644 index 0000000..c96ca37 --- /dev/null +++ b/plat/iptrans/src/include/function.h @@ -0,0 +1,127 @@ +/* +** CVS: $Id: function.h,v 1.6 2001/02/08 10:53:33 zhangsz Exp $ +** +** function.h +** Created at 2000/07/23 +** public domain code by Zhang Shuzhong +** +** Description: Header file of function definations. +*/ + +#ifndef FUNCTION__H +#define FUNCTION__H + +#define DisplayContent(buf, bcd_buf, nbytes) \ + BcdToAscii(buf, bcd_buf, 2 * nbytes); \ + FormatOutput(buf, 2*nbytes, 2, ' '); \ + log_debug("packets contains (%s):\n%s", FUNCTION_MACRO, buf); + +#define BzeroContent(content, length) \ + bzero(content+length, MAX_CONTENT_LEN-length); + +#define WriteOutBuffer WriteToOutBuffer + +#define WriteToOutBuffer(PROG_NAME, ip_semid, poutbuf, pbuf) \ + SemLock(PROG_NAME, ip_semid, PORT_NUM, 1, IPC_NOWAIT); \ + WriteMsg((in_buffer *) poutbuf, pbuf, OUT_LIST_NUM); \ + SemUnlock(PROG_NAME, ip_semid, PORT_NUM, 1, IPC_NOWAIT); \ + SemUnlock(PROG_NAME, ip_semid, SEM_NUM-1, 1, IPC_NOWAIT); + +#define ReadInBuffer ReadFromInBuffer + +#define ReadFromInBuffer(PROG_NAME, ip_semid, port_id, pinbuf, pbuf) \ + SemLock(PROG_NAME, ip_semid, port_id, 1, IPC_NOWAIT); \ + ReadMsg((in_buffer *) pinbuf, pbuf, IN_LIST_NUM); \ + SemUnlock(PROG_NAME, ip_semid, port_id, 1, IPC_NOWAIT); \ + +int InitDaemon(void); /* Initialize a daemon process */ + +void +SetTermSignal(struct termio *ptermio, void (*handler)(int)); + +/* Initialize a daemon process */ +void DaemonInit(const char *pname, int); + +/* passive a socket handler, from comfunc.c */ +int passivesock( const char * transport, u_short portbase, int qlen); + +/* passive a UDP socket handler, from comfunc.c */ +int passiveUDP(u_short portbase); + +/* Fill string 'c' into last area of 'str'. */ +void StringCat(char *str, char *c, int slen); + +int ByteLength(BYTE *bcd, int c); + +/* Cut string while match character c. */ +void StringCut(char *str, int c); + +void Bstr2Hstr(char *cptr); + +void bitstring(char *str, long byze, int biz, int strwid); + +/* Binary string convert to int. */ +unsigned int Bstr2Int(char *cptr); + +/* Hex string convert to int. */ +unsigned int Hstr2Int(char *cptr); + +/* Get current hour */ +int gethour(char * hour_buf); +int getweek(char * week_buf); + +/* Get current hour */ +int getmin(char * min_buf); + +/* Convert data from ASCII form to left-aligned compact BCD form. */ +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len); + +/* Convert data from left-aligned compact BCD form to ASCII form. */ +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len); + +/* Convert data from ASCII form to right-aligned compact BCD form. */ +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len); + +const char * +getdaytime(char *daytime_buf); + +char *GetASCTime(char *timep); + +void * +ShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg); + +int +SemInit(char *prog_name, key_t key, int sem_num, int sem_flg); + +BOOL +SemLock(char *prog_name, int sem_id, int sem_num, + unsigned nsops, int sem_flg); + +BOOL +SemUnlock(char *prog_name, int sem_id, int sem_num, + unsigned nsops, int sem_flg); + +BOOL +ReadMsg(void *pbuf, void *pmsg, int max_num); + +BOOL +WriteMsg(void *pbuf, void *pmsg, int max_num); + +const char * +Inet_ntoa(const long addr); + +const long +Inet_pton(const char *sp); + +char * +FormatOutput(char *sp, size_t, int, int); + +void +ByteReverse(BYTE *p1, BYTE *p2, size_t size); +void +SafeFree(void *pmem); + +void +GetAsciiField(char *dest, BYTE *src, size_t n); + +#endif diff --git a/plat/iptrans/src/include/includes.h b/plat/iptrans/src/include/includes.h new file mode 100644 index 0000000..0e54d43 --- /dev/null +++ b/plat/iptrans/src/include/includes.h @@ -0,0 +1,47 @@ +/* +** CVS $Id: includes.h,v 1.3 2001/02/08 10:53:33 zhangsz Exp $ +** includes.h +** Created at 2000-10-17 +** by Zhang SZ. +** Include all header files of PACS-WLL 2000 Project. +*/ + +#ifndef INCLUDES__H +#define INCLUDES__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "public.h" +#include "function.h" +#include "errlog.h" +#include "debug.h" + +#ifndef NO_CONFIG_H +#include "config.h" +#endif + +#endif /* INCLUDES__H */ + diff --git a/plat/iptrans/src/include/iptrans.h b/plat/iptrans/src/include/iptrans.h new file mode 100644 index 0000000..3c0c508 --- /dev/null +++ b/plat/iptrans/src/include/iptrans.h @@ -0,0 +1,206 @@ +/* +** +** +** file name: +** +** header file include by IP transceiver. +** defination of shared memory structure. +** +*/ + +#ifndef IPTRANS__H +#define IPTRANS__H + +#include "../../../public/src/include/includes.h" +#include "../../../public/src/include/public.h" +#include "../../../public/src/include/pub_fmt.h" +#include "errlog.h" +#include "debug.h" + +#ifndef NO_CONFIG_H +#include "config.h" +#endif + +#define IN_LIST_NUM 200 /* list number of in_buffer that + can store in the buffer space + */ +#define DS_LIST_NUM IN_LIST_NUM +#define OUT_LIST_NUM 1024 /* list number of out_buffer that + can store in the buffer space + */ +#define PORT_IN_NUM 24 /* number of in port defined */ +#define PORT_DS_NUM 1 /* number of port to database sync process */ +#define PORT_OUT_NUM 1 /* number of out port defined */ +#define PORT_NUM PORT_IN_NUM /* pre-defined port number */ + +/* Port service */ +#define PORT_BASE_NUM 4950 /* minimum port number */ +#define MAX_CONTENT_LEN 1514 + +/* IP transceiver shared memory ipc key and permission */ +#define IPTRANS_SHM_KEY 0x60000000 +#define IPTRANS_SHM_PERM 0777 +#define IPTRANS_DEBUG_SHM 0x61610000 +#define IPTRANS_DEBUG_PERM 0664 + +/* IP transceiver semaphore ipc key and permission */ +#define RELEASE 1 /* release semaphore */ +#define ACQUIRE -1 /* acquire semaphore */ +#define MAX_STATISTICS_SEG 96 + +#define _msg_list message_list +typedef struct message_list { + long msgSrcIP; /* ip number of source host */ + u_short msgSrcPort; /* port of source host */ + long msgDstIP; /* ip number of Destination host */ + u_short msgDstPort; /* port of Destination host */ + int msgBroadcast; /* message sent with broadcast mode, + 0(default)/1=no/yes. + */ + u_short msgLength; /* message's length */ + BYTE msgContent[MAX_CONTENT_LEN]; /* message of packet received */ +} message_list; + +typedef struct ds_msg { + long msgSrcIP; /* ip number of source host */ + u_short msgSrcPort; /* port of source host */ + long msgDstIP; /* ip number of Destination host */ + u_short msgDstPort; /* port of Destination host */ + int msgBroadcast; /* message sent with broadcast mode, + 0(default)/1=no/yes. + */ + u_short msgLength; /* message's length */ + char msgContent[MAX_CONTENT_LEN]; /* message of packet received */ +} db_msg; + +typedef struct ds_buffer { + u_short msgReadSub; /* subscript of array msgList for reader */ + u_short msgWriteSub; /* subscript of array msgList for writer */ + db_msg msgList[DS_LIST_NUM]; /* message list buffer */ +} ds_buffer; + +#define _in_buffer in_buffer +typedef struct in_buffer { + u_short msgReadSub; /* subscript of array msgList for reader */ + u_short msgWriteSub; /* subscript of array msgList for writer */ + message_list msgList[IN_LIST_NUM]; /* message list buffer */ +} in_buffer; + +#define _out_buffer out_buffer +typedef struct out_buffer { + u_short msgReadSub; /* subscript of array msgList for reader */ + u_short msgWriteSub; /* subscript of array msgList for writer */ + message_list msgList[OUT_LIST_NUM]; /* message list buffer */ +} out_buffer; + +#define _port_stat port_stat +typedef struct port_stat { + + short portStatus; /* port status: + 0=idle 1=normal -1=abnormal + */ + u_long inPackets; /* number of packets received */ + u_long inBytes; + u_long outPackets; /* number of packets sent */ + u_long outBytes; + u_long errorPackets; /* number of error packets received */ +} port_stat; + +/* +#define _port_stat port_stat +typedef struct port_stat{ + port_stat_15m port_stat_static[PORT_NUM]; +}port_stat; +*/ + +typedef struct debug_info +{ + DWORD debug_status_id[20]; + BYTE debug_status; + DWORD debug_ascin_id[20]; + DWORD debug_ascout_id[20]; + DWORD debug_name_id[20]; + DWORD debug_page_title[20]; + DWORD debug_page_line[20]; + BYTE title0_p[1024]; + BYTE title1_p[1024]; + BYTE title2_p[1024]; + BYTE title3_p[1020]; + char iptr_asciin_buf[4096]; + char iptr_asciout_buf[4096]; + BYTE port_onoff[PORT_NUM]; + BYTE port_status[PORT_NUM]; //overflow + BYTE resettimer[4]; + u_long logflag; + u_long srclog; + u_long dstlog; +}debug_info; + + +typedef struct port_configure +{ + BYTE port_config[PORT_NUM]; +}port_configure; + +typedef struct iptrans_cdr_rec +{ + u_long inPackets; + u_long inBytes; + u_long outPackets; + u_long outBytes; + u_long errorPackets; +}iptrans_cdr_rec; + +typedef struct iptrans_cdr_period +{ + iptrans_cdr_rec cdr_record[PORT_NUM]; +}iptrans_cdr_period; + +typedef struct snmp_info +{ + BYTE process_conf; + BYTE version[3]; + //port_configure port_conf; + //PORT STATUS ; debug_info.port_status + iptrans_cdr_period iptrans_cdr[96]; +}snmp_info; + +#define _iptrans_shm iptrans_shm +typedef struct iptrans_shm { /* type defination of IP transceiver + shared memory + */ + in_buffer msgPortIn[PORT_NUM]; /* message in_buffer defination, + a port buffer attach only a + application module. + */ + out_buffer msgPortOut; + out_buffer msgPlatPortOut; +} iptrans_shm; + +typedef struct _iptrans_status +{ + port_stat msgPortStat[PORT_NUM]; + debug_info debug_msg; + snmp_info snmp_data; +}iptrans_status; + +int iptrans_init(); +void iptrans_timer(); +int iptrMainInit(); +int iptrGetMessage(message_list *msgGet, u_short port); +int iptrDirectRecvMsg(message_list *msgGet, u_short port); +int iptrPutMessage(message_list msgPut); +int iptrDirectSendMsg(message_list msgPut); +int iptrPlatPutMessage(message_list msgPut); +int set_iptrans(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen); +int get_iptrans(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD *vartype); +int trap_iptrans(BYTE oidlen, DWORD *oid_ptr, BYTE *msg_ptr, BYTE msg_len); +int CloseTcpConn(); +BOOL iptrSemLock(char *prog_name, int sem_id, int sem_num, unsigned nsops, int sem_flg); +BOOL iptrWriteMsg(void *pbuf, void *pmsg, int max_num); +BOOL iptrSemUnlock(char *prog_name, int sem_id, int sem_num, unsigned nsops, int sem_flg); +BOOL iptrReadMsg(void *pbuf, void *pmsg, int max_num); +int InitSingleSocket(int portno); +int mcast_join(int sockfd, struct sockaddr *sa, socklen_t salen, const char *ifname, u_int ifindex); + +#endif /* IPTRANS__H */ diff --git a/plat/iptrans/src/include/iptrfunc.h b/plat/iptrans/src/include/iptrfunc.h new file mode 100644 index 0000000..00b56fe --- /dev/null +++ b/plat/iptrans/src/include/iptrfunc.h @@ -0,0 +1,9 @@ + +#ifndef _IPTR_FUNCTION +#define _IPTR_FUNCTION + +int init_iptrans(); +void iptr_timer_IRQ(); +void iptrans_close(); + +#endif diff --git a/plat/iptrans/src/ipcfunc.c b/plat/iptrans/src/ipcfunc.c new file mode 100644 index 0000000..8b1cf2b --- /dev/null +++ b/plat/iptrans/src/ipcfunc.c @@ -0,0 +1,87 @@ +/* +** CVS $Id: ipcfunc.c,v 1.4 2001/01/20 19:58:49 zhangsz Exp $ +** +** ipcfunc.c +** created at 2000/12/20 +** by Zhang SZ +** +** IPC functions for PACS-WLL project. +** +*/ + +#include "./include/iptrans.h" + +/*@ignore@*/ +void * +iptrShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg) +{ +void *retp; +char *func_name = "ShmInit"; + + shm_id = shmget(key, size, shmflg); + if (shm_id == -1) + log_sys("%s: %s: shmget(key: %x)", prog_name, func_name, key); + + retp = shmat(shm_id, (char *)0, 0); + if (retp == (void *) -1) + log_sys("%s: %s: shmat", prog_name, func_name); + + return retp; +} + +int +iptrSemInit(char *prog_name, key_t key, int sem_num, int sem_flg) +{ +int initarray[sem_num]; +int sem_id, retval, i; +char *func_name = "SemInit"; + + sem_id = semget(key, sem_num, sem_flg); + if (sem_id == -1) + log_sys("%s: %s: semget", prog_name, func_name); + for (i=0; i +#include "./include/iptrans.h" + +static iptrans_shm *IPTRANS_shm_ptr; +static int IPTRANS_shm_id; +extern void *ShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg); + +/*@ignore@*/ +int iptransCreate() +{ + IPTRANS_shm_ptr = (iptrans_shm *)ShmInit(IPTRANS_shm_id,"iptrans",IPTRANS_SHM_KEY, + sizeof(iptrans_shm),IPTRANS_SHM_PERM | IPC_CREAT); + return 0; +} + +int GetMessage(message_list *msgGet,int port_in) +{ + int port; + port=port_in-PORT_BASE_NUM; + if(IPTRANS_shm_ptr->msgPortIn[port].msgReadSub != + IPTRANS_shm_ptr->msgPortIn[port].msgWriteSub) + { + memcpy(msgGet, + &IPTRANS_shm_ptr->msgPortIn[port].msgList[IPTRANS_shm_ptr->msgPortIn[port].msgReadSub], + sizeof(struct message_list)); + IPTRANS_shm_ptr->msgPortIn[port].msgReadSub++; + if(IPTRANS_shm_ptr->msgPortIn[port].msgReadSub==IN_LIST_NUM) + IPTRANS_shm_ptr->msgPortIn[port].msgReadSub=0; + return 1; + } + return 0; +} + +int PutMessage(message_list msgPut) +{ + memcpy(&IPTRANS_shm_ptr->msgPortOut.msgList[IPTRANS_shm_ptr->msgPortOut.msgWriteSub], + &msgPut, sizeof(struct message_list)); + IPTRANS_shm_ptr->msgPortOut.msgWriteSub ++; + if(IPTRANS_shm_ptr->msgPortOut.msgWriteSub==OUT_LIST_NUM) + IPTRANS_shm_ptr->msgPortOut.msgWriteSub=0; + return 0; +} + +int clearPort(int port_in) +{ + int port; + port=port_in-PORT_BASE_NUM; + IPTRANS_shm_ptr->msgPortIn[port].msgReadSub=0; + IPTRANS_shm_ptr->msgPortIn[port].msgWriteSub=0; + return 1; +} +/*@end@*/ diff --git a/plat/iptrans/src/iptrans.c b/plat/iptrans/src/iptrans.c new file mode 100644 index 0000000..75b7474 --- /dev/null +++ b/plat/iptrans/src/iptrans.c @@ -0,0 +1,1913 @@ +/* +** PACS-WLL 2000 project, Prepaid System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** Written completely by Zhang Shuzhong at iCRD January, 2001 +** +** file name: iptrans.c +** CVS: $Id: iptrans.c,v 1.9 2001/02/09 08:53:43 zhangsz Exp $ +** +** Description: IP transceiver common module of PACS-WLL Project. +** +*/ +#include /* ANSI C header file */ +#include +//#include +#include +#include "../../debug/src/include/debug.h" +#include "./include/iptrans.h" +#include "./include/dbsync.h" + +/*@ignore@*/ +#define PROG_NAME "iptrans" +#define OID_IPTRANS 1 +#define IPTR_DEBUG_ID 0 +#define BASE_ID_LEN 15 +#define MAX_DEBUG_MESSAGES 1 +#define MAX_TELNET_TIME (10*100*3600) +#define MAX_MULTICAST_TIME (100*60*2000) //TWO MINUTES +#define TELNET_PORT 15 + +#define TYPE_UDP 0 +#define TYPE_TCP 1 + +#define ACCESS_BUFFERED 0 +#define ACCESS_DIRECT 1 + +int port_convert_flag = 0; + +typedef struct _PORT_STATUS +{ + unsigned short portno; + int sockfd; + unsigned char type; /*0/1/2/=UDP/TCP/MULITICAST*/ + unsigned char capability; /*0-6*/ + unsigned char buffered; /*whether buffered or not*/ + int connfd; + u_long peerip; + int peerport; + int recvcounter; + //int sendcounter; + unsigned char convert_flag; + unsigned short real_portno; +}PORT_STATUS; + +PORT_STATUS port_status[PORT_NUM]; +iptrans_status iptransInfo; +extern int debug; /* defined in errorlog.c */ +extern int under_develop; /* defined in errorlog.c */ +static int iptrans_shm_id; +static int iptrans_sem_id; +//static struct termio prev_termio; +static iptrans_shm *iptrans_shm_ptr; +static DWORD IPTRANS_OID_PREFIX[]={1,3,6,1,4,1,1373,1,3,2,2,1}; +static BYTE IPTRANS_VERSION[3]={0x01,0x00,0x01}; +static int nowPeriod,lstPeriod=0; +static u_long startTime[96]; +static int sendcounter; +extern int errno; + +u_char warningFlag = 0x01; +socklen_t clilen; +struct sockaddr_in cliaddr; +const BYTE IPTR_PAGE_POINT = 14; +const BYTE IPTR_LINE_POINT = 15; +static BYTE *disp_ptr ; + +//static u_short parportadd = 0x37a; +//static u_char iptr_led_bit = 2; +static int debug_messages=0; +u32 GetLocalIP1( ); +int ReadAsciin(); +int SendHeartbeat(); +int GetNowPeriod(); +int Init_UDPSocket(struct sockaddr_in saddr,int bFlag,int type); +int SetAsciioutMsg(int flag, const char *fmt, ...); +int Receive_TCP(int port,in_buffer *pbuf,port_stat *pstat); +static char *iptrGetASCTime(); +static char *iptrFormatOutput(); +int ClearStatistics(int pageno); +int ClearPortStatics(int index); +/*----------------------------------------------------*/ +int GetRealPortID(unsigned short port) +{ + int retval = -1; + int loop; + + for(loop=0;loop msgPortIn[loop]; + pstat=(port_stat *) &iptransInfo.msgPortStat[loop]; + + if(port_status[loop].type == TYPE_TCP) + { + Receive_TCP(loop,pbuf,pstat); + continue; + } + + nbytes = recvfrom(port_status[loop].sockfd, &bcd_buf, MAX_CONTENT_LEN, + 0, (struct sockaddr *) &sin, &len); + if (nbytes < 0) { + continue; + } + port=loop+PORT_BASE_NUM; + msgbuf.msgSrcIP = sin.sin_addr.s_addr; + msgbuf.msgSrcPort = ntohs(sin.sin_port); + srcport = msgbuf.msgSrcPort-PORT_BASE_NUM; + msgbuf.msgDstPort = port; + msgbuf.msgLength = nbytes; + msgbuf.msgBroadcast = NO; + memcpy(msgbuf.msgContent,bcd_buf,nbytes); + + iptrSemLock(PROG_NAME, iptrans_sem_id, 1, 1, IPC_NOWAIT); + /* write to buffer and statistics of packets. */ + if(! iptrWriteMsg(pbuf,&msgbuf,list_num)) + { + iptransInfo.debug_msg.port_status[loop] ++; + //SendHeartbeat(); + continue; + } + pstat->portStatus = 1; + pstat->inPackets ++; + pstat->inBytes += nbytes; + + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[loop].inPackets ++; + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[loop].inBytes +=nbytes; + iptrSemUnlock(PROG_NAME, iptrans_sem_id, 1, 1, IPC_NOWAIT); + + +#if UNDER_DEVELOP + if(debug_messages>=MAX_DEBUG_MESSAGES) continue; + if(iptransInfo.debug_msg.logflag == 0x00) + continue; + if(iptransInfo.debug_msg.logflag != 0xffffffff) + { + if(iptransInfo.debug_msg.srclog !=0) + { + flag = iptransInfo.debug_msg.srclog; + if((flag>>srcport) !=0x01) + continue; + } + if(iptransInfo.debug_msg.dstlog !=0) + { + flag = iptransInfo.debug_msg.dstlog; + if((flag>>loop) !=0x01) + continue; + } + } + showlen = nbytes; + if(showlen>256) showlen = 256; + debug_messages++; + SetAsciioutMsg(1, + "Read Subscript: %03d Write Subscript: %03d Port: %d\r\n", + pbuf->msgReadSub, pbuf->msgWriteSub, msgbuf.msgSrcPort); + if (ds_flag == NO) { + BcdToAscii(buf, msgbuf.msgContent, 2*showlen); + iptrFormatOutput(buf, 2*showlen, 2, ' '); + } else { + memcpy(buf, msgbuf.msgContent, nbytes); + buf[nbytes] = 0; + } + SetAsciioutMsg(0,"Current time: %s\r\n", iptrGetASCTime(NULL)); + SetAsciioutMsg(0, + "got packet from %s %d #%d\r\n", + (char *)inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), i); + SetAsciioutMsg(0, + "packet is %d bytes (chars) long, contains:\r\n%s\r\n", nbytes, buf); + i++; +#endif + + } /* loop */ + +} +/* end of RecvMessage -------------------*/ + +int Receive_TCP(int port,in_buffer *pbuf,port_stat *pstat) +{ + int nbytes; + struct sockaddr_in sin; + message_list msgbuf; + + socklen_t len = sizeof(struct sockaddr); + if(port_status[port].connfd<=0 ) return 0; + + nbytes = recvfrom(port_status[port].connfd, + msgbuf.msgContent, + MAX_CONTENT_LEN, + 0, + (struct sockaddr *) &sin, + &len); + if(nbytes<0){ + return 0; + } + if(nbytes==0){ + //if(errno==ENOTSOCK || errno==ENOTCONN) + { + CloseTcpConn(port); + } + return 0; + } +// fprintf(stderr,"connfd[%d]: Recv bytes:%d Client IP:%08x\n", +// port+BASE_PORT_NUM, nbytes,peerip[port]); + + msgbuf.msgSrcIP = sin.sin_addr.s_addr; + msgbuf.msgSrcPort = ntohs(sin.sin_port); + + msgbuf.msgDstPort = port+PORT_BASE_NUM; + msgbuf.msgLength = nbytes; + msgbuf.msgBroadcast = NO; + + iptrWriteMsg(pbuf, &msgbuf, IN_LIST_NUM); + pstat->portStatus = 1; + pstat->inPackets ++; + pstat->inBytes +=nbytes; + + if(strncasecmp((char *)msgbuf.msgContent,"exit",4)==0) + CloseTcpConn(port); + else if(msgbuf.msgContent[0]=='q' || + msgbuf.msgContent[0] =='Q') + CloseTcpConn(port); + +#if UNDER_DEVELOP1 + int i; + msgbuf.msgContent[nbytes] = 0; + for(i=0;imsgPortOut; + else + pbuf = (out_buffer *)&iptrans_shm_ptr->msgPlatPortOut; + if(pbuf->msgReadSub == pbuf->msgWriteSub) continue; + else{ + iptrReadMsg(pbuf, (message_list *) &msgbuf, OUT_LIST_NUM); + port_id = msgbuf.msgSrcPort - PORT_BASE_NUM; + if (port_id<0 || port_id>=PORT_NUM) + { + if(port_convert_flag) + { + port_id = GetRealPortID(msgbuf.msgSrcPort); + if(port_id<0) + continue; + } + continue; + } + + sin.sin_addr.s_addr = msgbuf.msgDstIP; + sin.sin_port = htons(msgbuf.msgDstPort); + dstport = msgbuf.msgDstPort - PORT_BASE_NUM; + len = msgbuf.msgLength; + memcpy(bcd_buf, msgbuf.msgContent, len); + + broadcast_message = msgbuf.msgBroadcast; + if (broadcast_message) { + ret = setsockopt(port_status[port_id].sockfd, SOL_SOCKET, + SO_BROADCAST, + &broadcast_message, sizeof(broadcast_message)); + if (ret < 0) + log_ret("%s: %s: setsockopt", PROG_NAME, FUNCTION_MACRO); + } + if(port_status[port_id].type == TYPE_TCP) + { + if(port_status[port_id].connfd<=0) continue; + ret = send(port_status[port_id].connfd, + &msgbuf.msgContent, len, MSG_NOSIGNAL); + } + else + { + ret = sendto(port_status[port_id].sockfd, &bcd_buf, len, 0, + (struct sockaddr *)&sin, sizeof(sin)); + + } + if (ret < 0) { + iptransInfo.msgPortStat[port_id].portStatus = -1; + iptransInfo.msgPortStat[port_id].errorPackets ++; + } + else if (port_id >= 0 && port_id < PORT_NUM) { + iptransInfo.msgPortStat[port_id].outPackets ++; + sendlen = iptransInfo.msgPortStat[port_id].outBytes; + iptransInfo.msgPortStat[port_id].outBytes = sendlen + len; + + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outPackets ++; + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outBytes +=len; + } + +#if UNDER_DEVELOP + if(debug_messages>=MAX_DEBUG_MESSAGES) continue; + if(iptransInfo.debug_msg.logflag == 0x00000000) + continue; + if(iptransInfo.debug_msg.logflag != 0xffffffff) + { + if(iptransInfo.debug_msg.srclog !=0) + { + flag = iptransInfo.debug_msg.srclog; + if((flag>>port_id) !=0x01) + continue; + } + if(iptransInfo.debug_msg.dstlog !=0) + { + flag = iptransInfo.debug_msg.dstlog; + if((flag>>dstport) !=0x01) + continue; + } + } + showlen = len; + if(showlen>256) showlen = 256; + debug_messages++; + SetAsciioutMsg(1, + "Read Subscript: %d Write Subscript: %d Port: %d\r\n", + pbuf->msgReadSub, pbuf->msgWriteSub, msgbuf.msgSrcPort); + if (msgbuf.msgDstPort != DS_PORT_NO) { + BcdToAscii(buf, bcd_buf, 2*(showlen)); + iptrFormatOutput(buf, 2*showlen, 2, ' '); + } else + memcpy(buf, bcd_buf, showlen); + SetAsciioutMsg(0,"Current time: %s\r\n", iptrGetASCTime(NULL)); + SetAsciioutMsg(0,"Sent packet to %s %d #%d\r\n", + (char *)inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), i); + SetAsciioutMsg(0, + "packet is %d bytes long, contains:\r\n%s\r\n", len, buf); + i ++; +#endif + } + } /* loop */ +} + +/* end of SendMessage() ----------------------*/ + +int CloseTcpConn(int index){ + close(port_status[index].connfd); + port_status[index].connfd = -1; + port_status[index].peerip = 0; + port_status[index].peerport = 0; + return 1; +} + +int CloseAllMulticastPort() +{ + int i; + for(i=28;i msgPortIn[TELNET_PORT]; + iptrWriteMsg(pbuf, &ipmsg, IN_LIST_NUM); +} + +int TcpConnectCheck(int index) +{ + int timeout=20; + int connfdtmp=0;// + char welcome[128]={"Welcome to enter debug world! (^_^) \n\r"}; + //char timeout_prompt[128]={"You have stayed too long\n\r telnet again please!\n\r"}; + + //if(port_status[index].connfd<=0 ) + { + memset(&cliaddr,0,(clilen=sizeof(struct sockaddr))); + connfdtmp = accept(port_status[index].sockfd, + //port_status[index].connfd = accept(port_status[index].sockfd, + (struct sockaddr *)&cliaddr,&clilen); + if(connfdtmp<=0) return 0;// + if(port_status[index].connfd>0)// + { + + sprintf(welcome, + "\n\rSorry! %s:%d has connected to the server\n\r", + (char *)inet_ntoa(cliaddr.sin_addr), + ntohs(cliaddr.sin_port)); + send(port_status[index].connfd,welcome,strlen(welcome),MSG_NOSIGNAL); + + sprintf(welcome, + "your connection is cut, bye bye!\n\r"); + send(port_status[index].connfd,welcome,strlen(welcome),MSG_NOSIGNAL); + + CloseTcpConn(index); + } +/* + if(port_status[index].connfd<=0){ + return 0; + } +*/ + port_status[index].connfd = connfdtmp; // + if(port_status[index].connfd>0) + { + port_status[index].peerip = cliaddr.sin_addr.s_addr; + port_status[index].peerport = ntohs(cliaddr.sin_port); + fcntl(port_status[index].connfd,F_SETFL,O_NONBLOCK); + if(setsockopt(port_status[index].connfd,SOL_SOCKET,SO_KEEPALIVE, + &timeout,sizeof(timeout)) !=0){ + fprintf(stderr,"set keepalive failed\n"); + } + if(setsockopt(port_status[index].connfd,SOL_SOCKET,SO_KEEPALIVE, + &timeout,sizeof(timeout)) !=0){ + fprintf(stderr,"set keepalive failed\n"); + } + send(port_status[index].connfd,welcome,strlen(welcome),MSG_NOSIGNAL); + if(index==TELNET_PORT) + PutEscToApp(); + } + } + + return 1; +} +/*--------------------------------------------*/ +int iptrDirectRecvMsg(message_list *msgbuf,unsigned short port) +{ + int index, nbytes; + //BYTE bcd_buf[MAX_CONTENT_LEN]; + struct sockaddr_in sin; + port_stat *pstat; + socklen_t len; + + index = port - PORT_BASE_NUM; + if(index<0 || index>=PORT_NUM) + { + return -1; + } + + if(port_status[index].buffered == ACCESS_BUFFERED) + { + return iptrGetMessage(msgbuf,port); + } + + pstat = &iptransInfo.msgPortStat[index]; + len = sizeof(struct sockaddr); + + if(port_status[index].type == TYPE_TCP) + { + if(port_status[index].connfd<=0) return-1; + + nbytes = recvfrom(port_status[index].connfd, + msgbuf->msgContent, + MAX_CONTENT_LEN, + 0, + (struct sockaddr *) &sin, + &len); + if(nbytes<0){ + return nbytes; + } + if(nbytes==0){ + //if(errno==ENOTSOCK || errno==ENOTCONN) + { + CloseTcpConn(port); + } + return -1; + } + + msgbuf->msgSrcIP = sin.sin_addr.s_addr; + msgbuf->msgSrcPort = ntohs(sin.sin_port); + + msgbuf->msgDstPort = index+PORT_BASE_NUM; + msgbuf->msgLength = nbytes; + msgbuf->msgBroadcast = NO; + + pstat->portStatus = 1; + pstat->inPackets ++; + pstat->inBytes +=nbytes; + + if(strncasecmp((char *)msgbuf->msgContent,"exit",4)==0) + CloseTcpConn(index); + else if(msgbuf->msgContent[0]=='q' || + msgbuf->msgContent[0] =='Q') + CloseTcpConn(index); + return nbytes; + }else{ + nbytes = recvfrom(port_status[index].sockfd, + msgbuf->msgContent, MAX_CONTENT_LEN, + 0, (struct sockaddr *) &sin, &len); + if (nbytes < 0) { + return nbytes; + } + msgbuf->msgSrcIP = sin.sin_addr.s_addr; + msgbuf->msgSrcPort = ntohs(sin.sin_port); + msgbuf->msgDstPort = port; + msgbuf->msgLength = nbytes; + msgbuf->msgBroadcast = NO; + + pstat->portStatus = 1; + pstat->inPackets ++; + pstat->inBytes += nbytes; + + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[index].inPackets ++; + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[index].inBytes +=nbytes; + return nbytes; + } + +} + +int iptrDirectSendMsg(message_list msgbuf) +{ + int len, port_id,ret,sendlen; + int broadcast_message=0; + struct sockaddr_in sin; + + //if(sendcounter++>128) return 0; + + port_id = msgbuf.msgSrcPort - PORT_BASE_NUM; + if (port_id<0 || port_id>=PORT_NUM) + { + if(port_convert_flag) + { + port_id = GetRealPortID(msgbuf.msgSrcPort); + if(port_id<0) + return 0; + } + else + return 0; + } + + if(port_status[port_id].buffered == ACCESS_BUFFERED) + { + return iptrPutMessage(msgbuf); + } + + len = 0; + bzero(&sin.sin_zero, sizeof(sin.sin_zero)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = msgbuf.msgDstIP; + sin.sin_port = htons(msgbuf.msgDstPort); + len = msgbuf.msgLength; + broadcast_message = msgbuf.msgBroadcast; + + if (broadcast_message && port_id != 0) { + ret = setsockopt(port_status[port_id].sockfd, SOL_SOCKET, + SO_BROADCAST, + &broadcast_message, sizeof(broadcast_message)); + if (ret < 0) + log_ret("%s: %s: setsockopt", PROG_NAME, FUNCTION_MACRO); + } + + if(port_status[port_id].type == TYPE_TCP) + { + if(port_status[port_id].connfd<=0) return 0; + ret = send(port_status[port_id].connfd, + &msgbuf.msgContent, len, MSG_NOSIGNAL); + }else{ + ret = sendto(port_status[port_id].sockfd, msgbuf.msgContent, len, 0, + (struct sockaddr *)&sin, sizeof(sin)); + + } + if (ret < 0) { + log_ret("%s: %s: port=%d, sendto(%08x.%d) failed, errno=%d (%s)", PROG_NAME, FUNCTION_MACRO, + msgbuf.msgSrcPort, msgbuf.msgDstIP, msgbuf.msgDstPort, errno, strerror(errno)); + SetAsciioutMsg(1, "%s: port=%d(fd=%d), sendto(%08x.%d) failed, errno=%d (%s)", FUNCTION_MACRO, + msgbuf.msgSrcPort, port_status[port_id].sockfd, msgbuf.msgDstIP, msgbuf.msgDstPort, errno, strerror(errno)); + close(port_status[port_id].sockfd); + InitSingleSocket(msgbuf.msgSrcPort); + + iptransInfo.msgPortStat[port_id].portStatus = -1; + iptransInfo.msgPortStat[port_id].errorPackets ++; + } + else if (port_id >= 0 && port_id < PORT_NUM) { + iptransInfo.msgPortStat[port_id].outPackets ++; + sendlen = iptransInfo.msgPortStat[port_id].outBytes; + iptransInfo.msgPortStat[port_id].outBytes = sendlen + len; + + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outPackets ++; + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outBytes +=len; + } + + return 1; +} + + +/*------------------------------------------------*/ +int iptrGetMessage(message_list *msgGet,unsigned short port_in) +{ + int port; + u_short readSub, writeSub; + in_buffer *pbuf; + + port=port_in-PORT_BASE_NUM; + + if(port<0 || port>=PORT_NUM) return 0; + + if(port_status[port].buffered == ACCESS_DIRECT) + { + if(iptrDirectRecvMsg(msgGet,port_in)>0) + return 1; + } + + pbuf = &iptrans_shm_ptr->msgPortIn[port]; + readSub = pbuf->msgReadSub%IN_LIST_NUM; + writeSub = pbuf->msgWriteSub; + + if(readSub == writeSub) return 0; + memcpy(msgGet, + &pbuf->msgList[readSub], + sizeof(struct message_list));//msgPut.msgLength+44); + pbuf->msgReadSub = (pbuf->msgReadSub+1) % IN_LIST_NUM; + + return 1; + +} +int iptrPutMessage(message_list msgPut) +{ + out_buffer *pbuf; + static int reflag=0; + + if(reflag == 1){ + iptransInfo.debug_msg.port_status[10] ++; + return 0; + } + reflag = 1; + pbuf = &iptrans_shm_ptr->msgPortOut; + + pbuf->msgWriteSub = (pbuf->msgWriteSub) % OUT_LIST_NUM; + memcpy(&pbuf->msgList[pbuf->msgWriteSub], + &msgPut, + sizeof(struct message_list));//msgPut.msgLength+44); + pbuf->msgWriteSub = (pbuf->msgWriteSub+1) % OUT_LIST_NUM; + reflag = 0; + return 1; +} + +int iptrPlatPutMessage(message_list msgPut) +{ + out_buffer *pbuf; + static int reflag = 0; + if(reflag == 1){ + iptransInfo.debug_msg.port_status[11] ++; + return 0; + } + reflag = 1; + pbuf = &iptrans_shm_ptr->msgPlatPortOut; + pbuf->msgWriteSub = (pbuf->msgWriteSub) % OUT_LIST_NUM; + + memcpy(&pbuf->msgList[pbuf->msgWriteSub], + &msgPut, + sizeof(struct message_list));//msgPut.msgLength+44); + pbuf->msgWriteSub = (pbuf->msgWriteSub+1) % OUT_LIST_NUM; + reflag = 0; + return 1; +} + +/*--------------------------------------------*/ +void iptrans_timer() +{ + int i; + static int count = 0; + struct timeval tmnow; + //message_list msgbuf; + + debug_messages = 0; + sendcounter = 0; + + for(i=0;i=0){ + msgbuf.msgSrcPort = 4966; + iptrDirectSendMsg(msgbuf); + } +*/ + ReadAsciin(); + + if(count++==1000) + { + count = 0; + SendHeartbeat(); + + nowPeriod = GetNowPeriod(); + if(nowPeriod != lstPeriod) + { + gettimeofday(&tmnow,NULL); + startTime[nowPeriod] = tmnow.tv_sec; + lstPeriod = nowPeriod; + memset(&iptransInfo.snmp_data.iptrans_cdr[nowPeriod],0,PORT_NUM*20); + } + + } + +} + +int InitMulticastPort() +{ + int i,port; + struct sockaddr_in sin_addr; + char ip3,ip[16]; + + for(i=28;i0) + { + if((mcast_join(sock,(struct sockaddr *)&saddr,sizeof(struct sockaddr),NULL,0))<0) + { + fprintf(stderr,"mcast_join failed\n"); + return -7; + } + } + return sock; + } + + +int iptr_disp_page(int page); +int init_monitor() +{ + BYTE page; + BYTE *ptr; + + iptransInfo.debug_msg.debug_status = 1; + iptransInfo.debug_msg.debug_status_id[0] =1; + iptransInfo.debug_msg.debug_status_id[1] = 3; + iptransInfo.debug_msg.debug_status_id[2] = 6; + iptransInfo.debug_msg.debug_status_id[3] = 1; + iptransInfo.debug_msg.debug_status_id[4] = 4; + iptransInfo.debug_msg.debug_status_id[5] = 1; + iptransInfo.debug_msg.debug_status_id[6] = 1373; + iptransInfo.debug_msg.debug_status_id[7] = 1; + iptransInfo.debug_msg.debug_status_id[8] = 1; + iptransInfo.debug_msg.debug_status_id[9] = 2; + iptransInfo.debug_msg.debug_status_id[10] = 3; + iptransInfo.debug_msg.debug_status_id[11] = 1; + iptransInfo.debug_msg.debug_status_id[12] = 2; + iptransInfo.debug_msg.debug_status_id[13] = 2; + iptransInfo.debug_msg.debug_status_id[14] = 1; + + iptransInfo.debug_msg.debug_name_id[0] =1; + iptransInfo.debug_msg.debug_name_id[1] = 3; + iptransInfo.debug_msg.debug_name_id[2] = 6; + iptransInfo.debug_msg.debug_name_id[3] = 1; + iptransInfo.debug_msg.debug_name_id[4] = 4; + iptransInfo.debug_msg.debug_name_id[5] = 1; + iptransInfo.debug_msg.debug_name_id[6] = 1373; + iptransInfo.debug_msg.debug_name_id[7] = 1; + iptransInfo.debug_msg.debug_name_id[8] = 1; + iptransInfo.debug_msg.debug_name_id[9] = 2; + iptransInfo.debug_msg.debug_name_id[10] = 3; + iptransInfo.debug_msg.debug_name_id[11] = 1; + iptransInfo.debug_msg.debug_name_id[12] = 2; + iptransInfo.debug_msg.debug_name_id[13] = 2; + iptransInfo.debug_msg.debug_name_id[14] = 2; + + iptransInfo.debug_msg.debug_ascin_id[0] =1; + iptransInfo.debug_msg.debug_ascin_id[1] = 3; + iptransInfo.debug_msg.debug_ascin_id[2] = 6; + iptransInfo.debug_msg.debug_ascin_id[3] = 1; + iptransInfo.debug_msg.debug_ascin_id[4] = 4; + iptransInfo.debug_msg.debug_ascin_id[5] = 1; + iptransInfo.debug_msg.debug_ascin_id[6] = 1373; + iptransInfo.debug_msg.debug_ascin_id[7] = 1; + iptransInfo.debug_msg.debug_ascin_id[8] = 1; + iptransInfo.debug_msg.debug_ascin_id[9] = 2; + iptransInfo.debug_msg.debug_ascin_id[10] = 3; + iptransInfo.debug_msg.debug_ascin_id[11] = 1; + iptransInfo.debug_msg.debug_ascin_id[12] = 2; + iptransInfo.debug_msg.debug_ascin_id[13] = 2; + iptransInfo.debug_msg.debug_ascin_id[14] = 3; + + iptransInfo.debug_msg.debug_ascout_id[0] =1; + iptransInfo.debug_msg.debug_ascout_id[1] = 3; + iptransInfo.debug_msg.debug_ascout_id[2] = 6; + iptransInfo.debug_msg.debug_ascout_id[3] = 1; + iptransInfo.debug_msg.debug_ascout_id[4] = 4; + iptransInfo.debug_msg.debug_ascout_id[5] = 1; + iptransInfo.debug_msg.debug_ascout_id[6] = 1373; + iptransInfo.debug_msg.debug_ascout_id[7] = 1; + iptransInfo.debug_msg.debug_ascout_id[8] = 1; + iptransInfo.debug_msg.debug_ascout_id[9] = 2; + iptransInfo.debug_msg.debug_ascout_id[10] = 3; + iptransInfo.debug_msg.debug_ascout_id[11] = 1; + iptransInfo.debug_msg.debug_ascout_id[12] = 2; + iptransInfo.debug_msg.debug_ascout_id[13] = 2; + iptransInfo.debug_msg.debug_ascout_id[14] = 4; + + iptransInfo.debug_msg.debug_page_title[0] =1; + iptransInfo.debug_msg.debug_page_title[1] = 3; + iptransInfo.debug_msg.debug_page_title[2] = 6; + iptransInfo.debug_msg.debug_page_title[3] = 1; + iptransInfo.debug_msg.debug_page_title[4] = 4; + iptransInfo.debug_msg.debug_page_title[5] = 1; + iptransInfo.debug_msg.debug_page_title[6] = 1373; + iptransInfo.debug_msg.debug_page_title[7] = 1; + iptransInfo.debug_msg.debug_page_title[8] = 1; + iptransInfo.debug_msg.debug_page_title[9] = 2; + iptransInfo.debug_msg.debug_page_title[10] = 3; + iptransInfo.debug_msg.debug_page_title[11] = 1; + iptransInfo.debug_msg.debug_page_title[12] = 2; + iptransInfo.debug_msg.debug_page_title[13] = 2; + iptransInfo.debug_msg.debug_page_title[14] = 5; + iptransInfo.debug_msg.debug_page_title[15] = 1; + + iptransInfo.debug_msg.debug_page_line[0] =1; + iptransInfo.debug_msg.debug_page_line[1] = 3; + iptransInfo.debug_msg.debug_page_line[2] = 6; + iptransInfo.debug_msg.debug_page_line[3] = 1; + iptransInfo.debug_msg.debug_page_line[4] = 4; + iptransInfo.debug_msg.debug_page_line[5] = 1; + iptransInfo.debug_msg.debug_page_line[6] = 1373; + iptransInfo.debug_msg.debug_page_line[7] = 1; + iptransInfo.debug_msg.debug_page_line[8] = 1; + iptransInfo.debug_msg.debug_page_line[9] = 2; + iptransInfo.debug_msg.debug_page_line[10] = 3; + iptransInfo.debug_msg.debug_page_line[11] = 1; + iptransInfo.debug_msg.debug_page_line[12] = 2; + iptransInfo.debug_msg.debug_page_line[13] = 2; + iptransInfo.debug_msg.debug_page_line[14] = 1; + iptransInfo.debug_msg.debug_page_line[15] = 2; + iptransInfo.debug_msg.debug_page_line[16] = 1; + +sprintf((char *)iptransInfo.debug_msg.title1_p,"%s", + " IPTRANS Version V1.0.01 Page 01\n\r\ + Port state \r\n\ + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n\ + Port Status\r\n\ + 4950-4965\r\n\ + 4966-4981\r\n\ +\ + Port Overflow\r\n\ + 4950-4965\r\n\ + 4966-4981\r\n\ + "); + +sprintf((char *)iptransInfo.debug_msg.title2_p,"%s", + " IPTRANS Version V1.0.01 Page 02\n\r\ + Flow Statistics (PORT 4950 - 4965)\r\n\ + PortNo Received Sent Error\r\n\ + Packets Bytes Pakcets Bytes Packets\r\n\ + 4950\r\n\ + 4951\r\n\ + 4952\r\n\ + 4953\r\n\ + 4954\r\n\ + 4955\r\n\ + 4956\r\n\ + 4957\r\n\ + 4958\r\n\ + 4959\r\n\ + 4960\r\n\ + 4961\r\n\ + 4962\r\n\ + 4963\r\n\ + 4964\r\n\ + 4965" +); + +sprintf((char *)iptransInfo.debug_msg.title3_p,"%s", + " IPTRANS Version V1.0.01 Page 03\n\r\ + Flow Statistics (PORT 4966 - 4981)\r\n\ + PortNo Received Sent Error\r\n\ + Packets Bytes Pakcets Bytes Packets\r\n\ + 4966\r\n\ + 4967\r\n\ + 4968\r\n\ + 4969\r\n\ + 4970\r\n\ + 4971\r\n\ + 4972\r\n\ + 4973\r\n\ + 4974\r\n\ + 4975\r\n\ + 4976\r\n\ + 4977\r\n\ + 4978\r\n\ + 4979\r\n\ + 4980\r\n\ + 4981" +); + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_status_id,&iptransInfo.debug_msg.debug_status,1); + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_name_id, (BYTE *)"V1.0.01",8);//module name + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_ascin_id, (BYTE *)iptransInfo.debug_msg.iptr_asciin_buf,4096);//ascii in buf + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_ascout_id, (BYTE *)iptransInfo.debug_msg.iptr_asciout_buf,4096);//ascii out buf + + for (page = 1; page < 4; page ++) + { + switch (page) + { + case 1: + ptr = iptransInfo.debug_msg.title1_p; + break; + case 2://page 1 + ptr = iptransInfo.debug_msg.title2_p; + break; + case 3://page 2; + ptr = iptransInfo.debug_msg.title3_p; + break; + default: + break; + } + iptransInfo.debug_msg.debug_page_title[IPTR_PAGE_POINT] = 5 + page; + debug_set_response(BASE_ID_LEN+1,iptransInfo.debug_msg.debug_page_title,ptr,strlen((char *)ptr)); + iptr_disp_page(page); + } + + return 1; +} + +int iptr_disp_line(int page, int line); +int iptr_disp_page(int page) +{ + BYTE disp_line; + BYTE disp_length; + + + iptransInfo.debug_msg.debug_page_line[IPTR_PAGE_POINT] = page + 5;//page + for (disp_line = 0; disp_line < 16; disp_line++) + { + disp_length = iptr_disp_line(page,disp_line); + iptransInfo.debug_msg.debug_page_line[IPTR_LINE_POINT] = disp_line + 5;//line + iptransInfo.debug_msg.debug_page_line[IPTR_LINE_POINT+1] = 2;//data pointer + debug_set_response(BASE_ID_LEN+2,iptransInfo.debug_msg.debug_page_line,disp_ptr,disp_length); + } + return 1; +} + +int iptrSaveParameter(); +int DecodeAsciin(int pageno, char *cmd); +int iptr_disp_line(int page, int line)//return display length,disp data ptr per line +{ + BYTE disp_length; + //int loop; + + disp_length = 16; + switch (page) + { + case 1: + switch(line) + { + case 0: + disp_ptr= (BYTE *)iptransInfo.debug_msg.port_onoff; + break; + case 1: + disp_ptr= (BYTE *)&iptransInfo.debug_msg.port_onoff[16]; + break; + case 2: + case 3: + disp_length = 0; + break; + case 4: + disp_ptr = (BYTE *)iptransInfo.debug_msg.port_status; + break; + case 5: + disp_ptr = (BYTE *)&iptransInfo.debug_msg.port_status[16]; + break; + default: + disp_length = 0; + break; + } + break; + case 2://page 2 + disp_ptr=(BYTE *) &iptransInfo.msgPortStat[line].inPackets; + disp_length =20; + break; + case 3://page 3 + disp_ptr=(BYTE *)&iptransInfo.msgPortStat[16+line].inPackets; + disp_length = 20; + break; + default: + disp_length = 0; + break; + } + + return disp_length; +} + +int ReadAsciin() +{ + int pageno,len; + char cmd[1024]={""}; + + len = strlen(iptransInfo.debug_msg.iptr_asciin_buf); + if(len==0) + { + return 0; + } + pageno = iptransInfo.debug_msg.iptr_asciin_buf[0]; + memcpy(cmd,&iptransInfo.debug_msg.iptr_asciin_buf[1],len-1); + + DecodeAsciin(pageno-1,cmd); + + memset(iptransInfo.debug_msg.iptr_asciin_buf,0,64); + return 1; +} + +int DecodeAsciin(int pageno, char *cmd) +{ + int res,port,no; + int srcport, dstport; + u_long flag=0x01; + + switch(pageno) + { + case 0: + if((res=strcasecmp(cmd,"HELP"))==0) + { + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, +"log help page\r\n\ +help : help for this page\r\n\ +set on portno=n: set port capability (n=0-6)\r\n\ +log all/none : log all message received or sent\r\n\ +log error on : if overflowed, point out which port overflowed\r\n\ +log error off : no message put, even port overflowed\r\n\ +log src portno : log message sent from port of portno\r\n\ +log dst portno : log message received from port of portno\r\n\ +log src portno1 and dst portno2 : log message from portno1 to portno2\r\n\ +"); + break; + } + else if((res=strcasecmp("LOG ALL",cmd))==0) + { + iptransInfo.debug_msg.logflag = 0xffffffff; + break; + } + else if((res=strcasecmp("LOG none",cmd))==0) + { + iptransInfo.debug_msg.logflag = 0x00; + break; + } + else if(strstr(cmd,"and dst 49") && strstr(cmd,"log src 49")) + { + srcport = atoi(&cmd[8]); + dstport = atoi(&cmd[21]); + if(srcport>=PORT_BASE_NUM+PORT_NUM || + dstport>=PORT_BASE_NUM+PORT_NUM) + break; + if(srcport=PORT_BASE_NUM+PORT_NUM) + break; + flag = 0x01; + iptransInfo.debug_msg.srclog = (flag<<(srcport-PORT_BASE_NUM)); + iptransInfo.debug_msg.logflag = 0xfffffffe; + break; + } + else if(strstr(cmd,"log dst 49")) + { + iptransInfo.debug_msg.srclog = 0x00; + dstport = atoi(&cmd[8]); + if(dstport=PORT_BASE_NUM+PORT_NUM) + break; + flag = 0x01; + iptransInfo.debug_msg.dstlog = (flag<<(dstport-PORT_BASE_NUM)); + iptransInfo.debug_msg.logflag = 0xfffffffe; + } + else if(strstr(cmd,"log error off")) + { + warningFlag = 0x00; + } + else if(strstr(cmd,"log error on")) + { + warningFlag = 0x01; + } + else if(strstr(cmd,"set on 49")) + { + dstport = atoi(&cmd[7]); + if(dstport=PORT_BASE_NUM+PORT_NUM) + { + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, + "error port number, should be : 4950-4972!"); + break; + } + dstport -=PORT_BASE_NUM; + no = atoi(&cmd[12]); + if(no>=6) no = 6; + if(dstport == TELNET_PORT && no == 0) + { + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, + "The WXC2 debug port cann't be closed!"); + break; + } + port_status[dstport].capability = no; + iptransInfo.debug_msg.port_onoff[dstport] = no; + + iptrSaveParameter(); + } + else{ + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, + "error comamnd!"); + } + break; + case 1: + break; + case 2: + case 3: + if(strcasecmp(cmd,"C")==0) + { + ClearStatistics(pageno); + break; + } + if(strstr(cmd,"C 49") || strstr(cmd,"c 49")) + { + port = atoi(&cmd[2]); + if(port>=PORT_BASE_NUM && porttm_hour * 4) + (tmnow->tm_min)/15; + return nowP; +} + +void *iptrShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg); +int iptrans_initshm() +{ + + iptrans_shm_ptr = (iptrans_shm *) iptrShmInit(iptrans_shm_id, PROG_NAME, + IPTRANS_SHM_KEY+wxc2_get_shm_offset(), + sizeof(iptrans_shm), IPTRANS_SHM_PERM|IPC_CREAT); + + + memset(iptrans_shm_ptr, 0, sizeof(iptrans_shm)); + + return 1; +} + +int StuffAllCSTA(char *pdata, int period); +int ConfigurePort() +{ + char confile[]={"./conf/iptrans.conf"}; + char s[80],s1[80],work[80]; + int loop,priority,len,type,direct=0; + unsigned char conf_state = 0xFF; + unsigned short port, realport; + //char *off; + FILE *fpConf; + + fpConf = fopen(confile,"rb"); + if(fpConf==NULL) + { + printf("%s not found!\n",confile); + for(loop=0;loopportStatus = 1; + pstat->inPackets ++; + pstat->inBytes +=nbytes; + + if(strncasecmp((char *)msgbuf.msgContent,"exit",4)==0) + CloseTcpConn(port); + else if(msgbuf.msgContent[0]=='q' || + msgbuf.msgContent[0] =='Q') + CloseTcpConn(port); + +#if UNDER_DEVELOP1 + int i; + msgbuf.msgContent[nbytes] = 0; + for(i=0;imsgPortOut; + else + pbuf = (out_buffer *)&iptrans_shm_ptr->msgPlatPortOut; + if(pbuf->msgReadSub == pbuf->msgWriteSub) continue; + else{ + iptrReadMsg(pbuf, (message_list *) &msgbuf, OUT_LIST_NUM); + port_id = msgbuf.msgSrcPort - PORT_BASE_NUM; + if (port_id<0 || port_id>=PORT_NUM) + { + if(port_convert_flag) + { + port_id = GetRealPortID(msgbuf.msgSrcPort); + if(port_id<0) + continue; + } + continue; + } + + sin.sin_addr.s_addr = msgbuf.msgDstIP; + sin.sin_port = htons(msgbuf.msgDstPort); + dstport = msgbuf.msgDstPort - PORT_BASE_NUM; + len = msgbuf.msgLength; + memcpy(bcd_buf, msgbuf.msgContent, len); + + broadcast_message = msgbuf.msgBroadcast; + if (broadcast_message) { + ret = setsockopt(port_status[port_id].sockfd, SOL_SOCKET, + SO_BROADCAST, + &broadcast_message, sizeof(broadcast_message)); + if (ret < 0) + log_ret("%s: %s: setsockopt", PROG_NAME, FUNCTION_MACRO); + } + if(port_status[port_id].type == TYPE_TCP) + { + if(port_status[port_id].connfd<=0) continue; + ret = send(port_status[port_id].connfd, + &msgbuf.msgContent, len, MSG_NOSIGNAL); + } + else + { + ret = sendto(port_status[port_id].sockfd, &bcd_buf, len, 0, + (struct sockaddr *)&sin, sizeof(sin)); + + } + if (ret < 0) { + iptransInfo.msgPortStat[port_id].portStatus = -1; + iptransInfo.msgPortStat[port_id].errorPackets ++; + } + else if (port_id >= 0 && port_id < PORT_NUM) { + iptransInfo.msgPortStat[port_id].outPackets ++; + sendlen = iptransInfo.msgPortStat[port_id].outBytes; + iptransInfo.msgPortStat[port_id].outBytes = sendlen + len; + + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outPackets ++; + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outBytes +=len; + } + +#if UNDER_DEVELOP + if(debug_messages>=MAX_DEBUG_MESSAGES) continue; + if(iptransInfo.debug_msg.logflag == 0x00000000) + continue; + if(iptransInfo.debug_msg.logflag != 0xffffffff) + { + if(iptransInfo.debug_msg.srclog !=0) + { + flag = iptransInfo.debug_msg.srclog; + if((flag>>port_id) !=0x01) + continue; + } + if(iptransInfo.debug_msg.dstlog !=0) + { + flag = iptransInfo.debug_msg.dstlog; + if((flag>>dstport) !=0x01) + continue; + } + } + showlen = len; + if(showlen>256) showlen = 256; + debug_messages++; + SetAsciioutMsg(1, + "Read Subscript: %d Write Subscript: %d Port: %d\r\n", + pbuf->msgReadSub, pbuf->msgWriteSub, msgbuf.msgSrcPort); + if (msgbuf.msgDstPort != DS_PORT_NO) { + BcdToAscii(buf, bcd_buf, 2*(showlen)); + iptrFormatOutput(buf, 2*showlen, 2, ' '); + } else + memcpy(buf, bcd_buf, showlen); + SetAsciioutMsg(0,"Current time: %s\r\n", iptrGetASCTime(NULL)); + SetAsciioutMsg(0,"Sent packet to %s %d #%d\r\n", + (char *)inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), i); + SetAsciioutMsg(0, + "packet is %d bytes long, contains:\r\n%s\r\n", len, buf); + i ++; +#endif + } + } /* loop */ +} + +/* end of SendMessage() ----------------------*/ + +int CloseTcpConn(int index){ + close(port_status[index].connfd); + port_status[index].connfd = -1; + port_status[index].peerip = 0; + port_status[index].peerport = 0; + return 1; +} + +int CloseAllMulticastPort() +{ + int i; + for(i=28;i msgPortIn[TELNET_PORT]; + iptrWriteMsg(pbuf, &ipmsg, IN_LIST_NUM); +} + +int TcpConnectCheck(int index) +{ + int timeout=20; + int connfdtmp=0;// + char welcome[128]={"Welcome to enter debug world! (^_^) \n\r"}; + //char timeout_prompt[128]={"You have stayed too long\n\r telnet again please!\n\r"}; + + //if(port_status[index].connfd<=0 ) + { + memset(&cliaddr,0,(clilen=sizeof(struct sockaddr))); + connfdtmp = accept(port_status[index].sockfd, + //port_status[index].connfd = accept(port_status[index].sockfd, + (struct sockaddr *)&cliaddr,&clilen); + if(connfdtmp<=0) return 0;// + if(port_status[index].connfd>0)// + { + + sprintf(welcome, + "\n\rSorry! %s:%d has connected to the server\n\r", + (char *)inet_ntoa(cliaddr.sin_addr), + ntohs(cliaddr.sin_port)); + send(port_status[index].connfd,welcome,strlen(welcome),MSG_NOSIGNAL); + + sprintf(welcome, + "your connection is cut, bye bye!\n\r"); + send(port_status[index].connfd,welcome,strlen(welcome),MSG_NOSIGNAL); + + CloseTcpConn(index); + } +/* + if(port_status[index].connfd<=0){ + return 0; + } +*/ + port_status[index].connfd = connfdtmp; // + if(port_status[index].connfd>0) + { + port_status[index].peerip = cliaddr.sin_addr.s_addr; + port_status[index].peerport = ntohs(cliaddr.sin_port); + fcntl(port_status[index].connfd,F_SETFL,O_NONBLOCK); + if(setsockopt(port_status[index].connfd,SOL_SOCKET,SO_KEEPALIVE, + &timeout,sizeof(timeout)) !=0){ + fprintf(stderr,"set keepalive failed\n"); + } + if(setsockopt(port_status[index].connfd,SOL_SOCKET,SO_KEEPALIVE, + &timeout,sizeof(timeout)) !=0){ + fprintf(stderr,"set keepalive failed\n"); + } + send(port_status[index].connfd,welcome,strlen(welcome),MSG_NOSIGNAL); + if(index==TELNET_PORT) + PutEscToApp(); + } + } + + return 1; +} +/*--------------------------------------------*/ +int iptrDirectRecvMsg(message_list *msgbuf,unsigned short port) +{ + int index, nbytes; + //BYTE bcd_buf[MAX_CONTENT_LEN]; + struct sockaddr_in sin; + port_stat *pstat; + socklen_t len; + + index = port - PORT_BASE_NUM; + if(index<0 || index>=PORT_NUM) + { + return -1; + } + + if(port_status[index].buffered == ACCESS_BUFFERED) + { + return iptrGetMessage(msgbuf,port); + } + + pstat = &iptransInfo.msgPortStat[index]; + len = sizeof(struct sockaddr); + + if(port_status[index].type == TYPE_TCP) + { + if(port_status[index].connfd<=0) return-1; + + nbytes = recvfrom(port_status[index].connfd, + msgbuf->msgContent, + MAX_CONTENT_LEN, + 0, + (struct sockaddr *) &sin, + &len); + if(nbytes<0){ + return nbytes; + } + if(nbytes==0){ + //if(errno==ENOTSOCK || errno==ENOTCONN) + { + CloseTcpConn(port); + } + return -1; + } + + msgbuf->msgSrcIP = sin.sin_addr.s_addr; + msgbuf->msgSrcPort = ntohs(sin.sin_port); + + msgbuf->msgDstPort = index+PORT_BASE_NUM; + msgbuf->msgLength = nbytes; + msgbuf->msgBroadcast = NO; + + pstat->portStatus = 1; + pstat->inPackets ++; + pstat->inBytes +=nbytes; + + if(strncasecmp((char *)msgbuf->msgContent,"exit",4)==0) + CloseTcpConn(index); + else if(msgbuf->msgContent[0]=='q' || + msgbuf->msgContent[0] =='Q') + CloseTcpConn(index); + return nbytes; + }else{ + nbytes = recvfrom(port_status[index].sockfd, + msgbuf->msgContent, MAX_CONTENT_LEN, + 0, (struct sockaddr *) &sin, &len); + if (nbytes < 0) { + return nbytes; + } + msgbuf->msgSrcIP = sin.sin_addr.s_addr; + msgbuf->msgSrcPort = ntohs(sin.sin_port); + msgbuf->msgDstPort = port; + msgbuf->msgLength = nbytes; + msgbuf->msgBroadcast = NO; + + pstat->portStatus = 1; + pstat->inPackets ++; + pstat->inBytes += nbytes; + + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[index].inPackets ++; + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[index].inBytes +=nbytes; + return nbytes; + } + +} + +int iptrDirectSendMsg(message_list msgbuf) +{ + int len, port_id,ret,sendlen; + int broadcast_message=0; + struct sockaddr_in sin; + + //if(sendcounter++>128) return 0; + + port_id = msgbuf.msgSrcPort - PORT_BASE_NUM; + if (port_id<0 || port_id>=PORT_NUM) + { + if(port_convert_flag) + { + port_id = GetRealPortID(msgbuf.msgSrcPort); + if(port_id<0) + return 0; + } + else + return 0; + } + + if(port_status[port_id].buffered == ACCESS_BUFFERED) + { + return iptrPutMessage(msgbuf); + } + + len = 0; + bzero(&sin.sin_zero, sizeof(sin.sin_zero)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = msgbuf.msgDstIP; + sin.sin_port = htons(msgbuf.msgDstPort); + len = msgbuf.msgLength; + broadcast_message = msgbuf.msgBroadcast; + + if (broadcast_message && port_id != 0) { + ret = setsockopt(port_status[port_id].sockfd, SOL_SOCKET, + SO_BROADCAST, + &broadcast_message, sizeof(broadcast_message)); + if (ret < 0) + log_ret("%s: %s: setsockopt", PROG_NAME, FUNCTION_MACRO); + } + + if(port_status[port_id].type == TYPE_TCP) + { + if(port_status[port_id].connfd<=0) return 0; + ret = send(port_status[port_id].connfd, + &msgbuf.msgContent, len, MSG_NOSIGNAL); + }else{ + ret = sendto(port_status[port_id].sockfd, msgbuf.msgContent, len, 0, + (struct sockaddr *)&sin, sizeof(sin)); + + } + if (ret < 0) { + log_ret("%s: %s: port=%d, sendto(%08x.%d) failed, errno=%d (%s)", PROG_NAME, FUNCTION_MACRO, + msgbuf.msgSrcPort, msgbuf.msgDstIP, msgbuf.msgDstPort, errno, strerror(errno)); + SetAsciioutMsg(1, "%s: port=%d(fd=%d), sendto(%08x.%d) failed, errno=%d (%s)", FUNCTION_MACRO, + msgbuf.msgSrcPort, port_status[port_id].sockfd, msgbuf.msgDstIP, msgbuf.msgDstPort, errno, strerror(errno)); + close(port_status[port_id].sockfd); + InitSingleSocket(msgbuf.msgSrcPort); + + iptransInfo.msgPortStat[port_id].portStatus = -1; + iptransInfo.msgPortStat[port_id].errorPackets ++; + } + else if (port_id >= 0 && port_id < PORT_NUM) { + iptransInfo.msgPortStat[port_id].outPackets ++; + sendlen = iptransInfo.msgPortStat[port_id].outBytes; + iptransInfo.msgPortStat[port_id].outBytes = sendlen + len; + + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outPackets ++; + iptransInfo.snmp_data.iptrans_cdr[nowPeriod].cdr_record[port_id].outBytes +=len; + } + + return 1; +} + + +/*------------------------------------------------*/ +int iptrGetMessage(message_list *msgGet,unsigned short port_in) +{ + int port; + u_short readSub, writeSub; + in_buffer *pbuf; + + port=port_in-PORT_BASE_NUM; + + if(port<0 || port>=PORT_NUM) return 0; + + if(port_status[port].buffered == ACCESS_DIRECT) + { + if(iptrDirectRecvMsg(msgGet,port_in)>0) + return 1; + } + + pbuf = &iptrans_shm_ptr->msgPortIn[port]; + readSub = pbuf->msgReadSub%IN_LIST_NUM; + writeSub = pbuf->msgWriteSub; + + if(readSub == writeSub) return 0; + memcpy(msgGet, + &pbuf->msgList[readSub], + sizeof(struct message_list));//msgPut.msgLength+44); + pbuf->msgReadSub = (pbuf->msgReadSub+1) % IN_LIST_NUM; + + return 1; + +} +int iptrPutMessage(message_list msgPut) +{ + out_buffer *pbuf; + static int reflag=0; + + if(reflag == 1){ + iptransInfo.debug_msg.port_status[10] ++; + return 0; + } + reflag = 1; + pbuf = &iptrans_shm_ptr->msgPortOut; + + pbuf->msgWriteSub = (pbuf->msgWriteSub) % OUT_LIST_NUM; + memcpy(&pbuf->msgList[pbuf->msgWriteSub], + &msgPut, + sizeof(struct message_list));//msgPut.msgLength+44); + pbuf->msgWriteSub = (pbuf->msgWriteSub+1) % OUT_LIST_NUM; + reflag = 0; + return 1; +} + +int iptrPlatPutMessage(message_list msgPut) +{ + out_buffer *pbuf; + static int reflag = 0; + if(reflag == 1){ + iptransInfo.debug_msg.port_status[11] ++; + return 0; + } + reflag = 1; + pbuf = &iptrans_shm_ptr->msgPlatPortOut; + pbuf->msgWriteSub = (pbuf->msgWriteSub) % OUT_LIST_NUM; + + memcpy(&pbuf->msgList[pbuf->msgWriteSub], + &msgPut, + sizeof(struct message_list));//msgPut.msgLength+44); + pbuf->msgWriteSub = (pbuf->msgWriteSub+1) % OUT_LIST_NUM; + reflag = 0; + return 1; +} + +/*--------------------------------------------*/ +void iptrans_timer() +{ + int i; + static int count = 0; + struct timeval tmnow; + //message_list msgbuf; + + debug_messages = 0; + sendcounter = 0; + + for(i=0;i=0){ + msgbuf.msgSrcPort = 4966; + iptrDirectSendMsg(msgbuf); + } +*/ + ReadAsciin(); + + if(count++==1000) + { + count = 0; + SendHeartbeat(); + + nowPeriod = GetNowPeriod(); + if(nowPeriod != lstPeriod) + { + gettimeofday(&tmnow,NULL); + startTime[nowPeriod] = tmnow.tv_sec; + lstPeriod = nowPeriod; + memset(&iptransInfo.snmp_data.iptrans_cdr[nowPeriod],0,PORT_NUM*20); + } + + } + +} + +int InitMulticastPort() +{ + int i,port; + struct sockaddr_in sin_addr; + char ip3,ip[16]; + + for(i=28;i0) + { + if((mcast_join(sock,(struct sockaddr *)&saddr,sizeof(struct sockaddr),NULL,0))<0) + { + fprintf(stderr,"mcast_join failed\n"); + return -7; + } + } + return sock; + } + + +int iptr_disp_page(int page); +int init_monitor() +{ + BYTE page; + BYTE *ptr; + + iptransInfo.debug_msg.debug_status = 1; + iptransInfo.debug_msg.debug_status_id[0] =1; + iptransInfo.debug_msg.debug_status_id[1] = 3; + iptransInfo.debug_msg.debug_status_id[2] = 6; + iptransInfo.debug_msg.debug_status_id[3] = 1; + iptransInfo.debug_msg.debug_status_id[4] = 4; + iptransInfo.debug_msg.debug_status_id[5] = 1; + iptransInfo.debug_msg.debug_status_id[6] = 1373; + iptransInfo.debug_msg.debug_status_id[7] = 1; + iptransInfo.debug_msg.debug_status_id[8] = 1; + iptransInfo.debug_msg.debug_status_id[9] = 2; + iptransInfo.debug_msg.debug_status_id[10] = 3; + iptransInfo.debug_msg.debug_status_id[11] = 1; + iptransInfo.debug_msg.debug_status_id[12] = 2; + iptransInfo.debug_msg.debug_status_id[13] = 2; + iptransInfo.debug_msg.debug_status_id[14] = 1; + + iptransInfo.debug_msg.debug_name_id[0] =1; + iptransInfo.debug_msg.debug_name_id[1] = 3; + iptransInfo.debug_msg.debug_name_id[2] = 6; + iptransInfo.debug_msg.debug_name_id[3] = 1; + iptransInfo.debug_msg.debug_name_id[4] = 4; + iptransInfo.debug_msg.debug_name_id[5] = 1; + iptransInfo.debug_msg.debug_name_id[6] = 1373; + iptransInfo.debug_msg.debug_name_id[7] = 1; + iptransInfo.debug_msg.debug_name_id[8] = 1; + iptransInfo.debug_msg.debug_name_id[9] = 2; + iptransInfo.debug_msg.debug_name_id[10] = 3; + iptransInfo.debug_msg.debug_name_id[11] = 1; + iptransInfo.debug_msg.debug_name_id[12] = 2; + iptransInfo.debug_msg.debug_name_id[13] = 2; + iptransInfo.debug_msg.debug_name_id[14] = 2; + + iptransInfo.debug_msg.debug_ascin_id[0] =1; + iptransInfo.debug_msg.debug_ascin_id[1] = 3; + iptransInfo.debug_msg.debug_ascin_id[2] = 6; + iptransInfo.debug_msg.debug_ascin_id[3] = 1; + iptransInfo.debug_msg.debug_ascin_id[4] = 4; + iptransInfo.debug_msg.debug_ascin_id[5] = 1; + iptransInfo.debug_msg.debug_ascin_id[6] = 1373; + iptransInfo.debug_msg.debug_ascin_id[7] = 1; + iptransInfo.debug_msg.debug_ascin_id[8] = 1; + iptransInfo.debug_msg.debug_ascin_id[9] = 2; + iptransInfo.debug_msg.debug_ascin_id[10] = 3; + iptransInfo.debug_msg.debug_ascin_id[11] = 1; + iptransInfo.debug_msg.debug_ascin_id[12] = 2; + iptransInfo.debug_msg.debug_ascin_id[13] = 2; + iptransInfo.debug_msg.debug_ascin_id[14] = 3; + + iptransInfo.debug_msg.debug_ascout_id[0] =1; + iptransInfo.debug_msg.debug_ascout_id[1] = 3; + iptransInfo.debug_msg.debug_ascout_id[2] = 6; + iptransInfo.debug_msg.debug_ascout_id[3] = 1; + iptransInfo.debug_msg.debug_ascout_id[4] = 4; + iptransInfo.debug_msg.debug_ascout_id[5] = 1; + iptransInfo.debug_msg.debug_ascout_id[6] = 1373; + iptransInfo.debug_msg.debug_ascout_id[7] = 1; + iptransInfo.debug_msg.debug_ascout_id[8] = 1; + iptransInfo.debug_msg.debug_ascout_id[9] = 2; + iptransInfo.debug_msg.debug_ascout_id[10] = 3; + iptransInfo.debug_msg.debug_ascout_id[11] = 1; + iptransInfo.debug_msg.debug_ascout_id[12] = 2; + iptransInfo.debug_msg.debug_ascout_id[13] = 2; + iptransInfo.debug_msg.debug_ascout_id[14] = 4; + + iptransInfo.debug_msg.debug_page_title[0] =1; + iptransInfo.debug_msg.debug_page_title[1] = 3; + iptransInfo.debug_msg.debug_page_title[2] = 6; + iptransInfo.debug_msg.debug_page_title[3] = 1; + iptransInfo.debug_msg.debug_page_title[4] = 4; + iptransInfo.debug_msg.debug_page_title[5] = 1; + iptransInfo.debug_msg.debug_page_title[6] = 1373; + iptransInfo.debug_msg.debug_page_title[7] = 1; + iptransInfo.debug_msg.debug_page_title[8] = 1; + iptransInfo.debug_msg.debug_page_title[9] = 2; + iptransInfo.debug_msg.debug_page_title[10] = 3; + iptransInfo.debug_msg.debug_page_title[11] = 1; + iptransInfo.debug_msg.debug_page_title[12] = 2; + iptransInfo.debug_msg.debug_page_title[13] = 2; + iptransInfo.debug_msg.debug_page_title[14] = 5; + iptransInfo.debug_msg.debug_page_title[15] = 1; + + iptransInfo.debug_msg.debug_page_line[0] =1; + iptransInfo.debug_msg.debug_page_line[1] = 3; + iptransInfo.debug_msg.debug_page_line[2] = 6; + iptransInfo.debug_msg.debug_page_line[3] = 1; + iptransInfo.debug_msg.debug_page_line[4] = 4; + iptransInfo.debug_msg.debug_page_line[5] = 1; + iptransInfo.debug_msg.debug_page_line[6] = 1373; + iptransInfo.debug_msg.debug_page_line[7] = 1; + iptransInfo.debug_msg.debug_page_line[8] = 1; + iptransInfo.debug_msg.debug_page_line[9] = 2; + iptransInfo.debug_msg.debug_page_line[10] = 3; + iptransInfo.debug_msg.debug_page_line[11] = 1; + iptransInfo.debug_msg.debug_page_line[12] = 2; + iptransInfo.debug_msg.debug_page_line[13] = 2; + iptransInfo.debug_msg.debug_page_line[14] = 1; + iptransInfo.debug_msg.debug_page_line[15] = 2; + iptransInfo.debug_msg.debug_page_line[16] = 1; + +sprintf((char *)iptransInfo.debug_msg.title1_p,"%s", + " IPTRANS Version V1.0.01 Page 01\n\r\ + Port state \r\n\ + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n\ + Port Status\r\n\ + 4950-4965\r\n\ + 4966-4981\r\n\ +\ + Port Overflow\r\n\ + 4950-4965\r\n\ + 4966-4981\r\n\ + "); + +sprintf((char *)iptransInfo.debug_msg.title2_p,"%s", + " IPTRANS Version V1.0.01 Page 02\n\r\ + Flow Statistics (PORT 4950 - 4965)\r\n\ + PortNo Received Sent Error\r\n\ + Packets Bytes Pakcets Bytes Packets\r\n\ + 4950\r\n\ + 4951\r\n\ + 4952\r\n\ + 4953\r\n\ + 4954\r\n\ + 4955\r\n\ + 4956\r\n\ + 4957\r\n\ + 4958\r\n\ + 4959\r\n\ + 4960\r\n\ + 4961\r\n\ + 4962\r\n\ + 4963\r\n\ + 4964\r\n\ + 4965" +); + +sprintf((char *)iptransInfo.debug_msg.title3_p,"%s", + " IPTRANS Version V1.0.01 Page 03\n\r\ + Flow Statistics (PORT 4966 - 4981)\r\n\ + PortNo Received Sent Error\r\n\ + Packets Bytes Pakcets Bytes Packets\r\n\ + 4966\r\n\ + 4967\r\n\ + 4968\r\n\ + 4969\r\n\ + 4970\r\n\ + 4971\r\n\ + 4972\r\n\ + 4973\r\n\ + 4974\r\n\ + 4975\r\n\ + 4976\r\n\ + 4977\r\n\ + 4978\r\n\ + 4979\r\n\ + 4980\r\n\ + 4981" +); + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_status_id,&iptransInfo.debug_msg.debug_status,1); + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_name_id, (BYTE *)"V1.0.01",8);//module name + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_ascin_id, (BYTE *)iptransInfo.debug_msg.iptr_asciin_buf,4096);//ascii in buf + debug_set_response(BASE_ID_LEN,iptransInfo.debug_msg.debug_ascout_id, (BYTE *)iptransInfo.debug_msg.iptr_asciout_buf,4096);//ascii out buf + + for (page = 1; page < 4; page ++) + { + switch (page) + { + case 1: + ptr = iptransInfo.debug_msg.title1_p; + break; + case 2://page 1 + ptr = iptransInfo.debug_msg.title2_p; + break; + case 3://page 2; + ptr = iptransInfo.debug_msg.title3_p; + break; + default: + break; + } + iptransInfo.debug_msg.debug_page_title[IPTR_PAGE_POINT] = 5 + page; + debug_set_response(BASE_ID_LEN+1,iptransInfo.debug_msg.debug_page_title,ptr,strlen((char *)ptr)); + iptr_disp_page(page); + } + + return 1; +} + +int iptr_disp_line(int page, int line); +int iptr_disp_page(int page) +{ + BYTE disp_line; + BYTE disp_length; + + + iptransInfo.debug_msg.debug_page_line[IPTR_PAGE_POINT] = page + 5;//page + for (disp_line = 0; disp_line < 16; disp_line++) + { + disp_length = iptr_disp_line(page,disp_line); + iptransInfo.debug_msg.debug_page_line[IPTR_LINE_POINT] = disp_line + 5;//line + iptransInfo.debug_msg.debug_page_line[IPTR_LINE_POINT+1] = 2;//data pointer + debug_set_response(BASE_ID_LEN+2,iptransInfo.debug_msg.debug_page_line,disp_ptr,disp_length); + } + return 1; +} + +int iptrSaveParameter(); +int DecodeAsciin(int pageno, char *cmd); +int iptr_disp_line(int page, int line)//return display length,disp data ptr per line +{ + BYTE disp_length; + //int loop; + + disp_length = 16; + switch (page) + { + case 1: + switch(line) + { + case 0: + disp_ptr= (BYTE *)iptransInfo.debug_msg.port_onoff; + break; + case 1: + disp_ptr= (BYTE *)&iptransInfo.debug_msg.port_onoff[16]; + break; + case 2: + case 3: + disp_length = 0; + break; + case 4: + disp_ptr = (BYTE *)iptransInfo.debug_msg.port_status; + break; + case 5: + disp_ptr = (BYTE *)&iptransInfo.debug_msg.port_status[16]; + break; + default: + disp_length = 0; + break; + } + break; + case 2://page 2 + disp_ptr=(BYTE *) &iptransInfo.msgPortStat[line].inPackets; + disp_length =20; + break; + case 3://page 3 + disp_ptr=(BYTE *)&iptransInfo.msgPortStat[16+line].inPackets; + disp_length = 20; + break; + default: + disp_length = 0; + break; + } + + return disp_length; +} + +int ReadAsciin() +{ + int pageno,len; + char cmd[1024]={""}; + + len = strlen(iptransInfo.debug_msg.iptr_asciin_buf); + if(len==0) + { + return 0; + } + pageno = iptransInfo.debug_msg.iptr_asciin_buf[0]; + memcpy(cmd,&iptransInfo.debug_msg.iptr_asciin_buf[1],len-1); + + DecodeAsciin(pageno-1,cmd); + + memset(iptransInfo.debug_msg.iptr_asciin_buf,0,64); + return 1; +} + +int DecodeAsciin(int pageno, char *cmd) +{ + int res,port,no; + int srcport, dstport; + u_long flag=0x01; + + switch(pageno) + { + case 0: + if((res=strcasecmp(cmd,"HELP"))==0) + { + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, +"log help page\r\n\ +help : help for this page\r\n\ +set on portno=n: set port capability (n=0-6)\r\n\ +log all/none : log all message received or sent\r\n\ +log error on : if overflowed, point out which port overflowed\r\n\ +log error off : no message put, even port overflowed\r\n\ +log src portno : log message sent from port of portno\r\n\ +log dst portno : log message received from port of portno\r\n\ +log src portno1 and dst portno2 : log message from portno1 to portno2\r\n\ +"); + break; + } + else if((res=strcasecmp("LOG ALL",cmd))==0) + { + iptransInfo.debug_msg.logflag = 0xffffffff; + break; + } + else if((res=strcasecmp("LOG none",cmd))==0) + { + iptransInfo.debug_msg.logflag = 0x00; + break; + } + else if(strstr(cmd,"and dst 49") && strstr(cmd,"log src 49")) + { + srcport = atoi(&cmd[8]); + dstport = atoi(&cmd[21]); + if(srcport>=PORT_BASE_NUM+PORT_NUM || + dstport>=PORT_BASE_NUM+PORT_NUM) + break; + if(srcport=PORT_BASE_NUM+PORT_NUM) + break; + flag = 0x01; + iptransInfo.debug_msg.srclog = (flag<<(srcport-PORT_BASE_NUM)); + iptransInfo.debug_msg.logflag = 0xfffffffe; + break; + } + else if(strstr(cmd,"log dst 49")) + { + iptransInfo.debug_msg.srclog = 0x00; + dstport = atoi(&cmd[8]); + if(dstport=PORT_BASE_NUM+PORT_NUM) + break; + flag = 0x01; + iptransInfo.debug_msg.dstlog = (flag<<(dstport-PORT_BASE_NUM)); + iptransInfo.debug_msg.logflag = 0xfffffffe; + } + else if(strstr(cmd,"log error off")) + { + warningFlag = 0x00; + } + else if(strstr(cmd,"log error on")) + { + warningFlag = 0x01; + } + else if(strstr(cmd,"set on 49")) + { + dstport = atoi(&cmd[7]); + if(dstport=PORT_BASE_NUM+PORT_NUM) + { + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, + "error port number, should be : 4950-4972!"); + break; + } + dstport -=PORT_BASE_NUM; + no = atoi(&cmd[12]); + if(no>=6) no = 6; + if(dstport == TELNET_PORT && no == 0) + { + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, + "The WXC2 debug port cann't be closed!"); + break; + } + port_status[dstport].capability = no; + iptransInfo.debug_msg.port_onoff[dstport] = no; + + iptrSaveParameter(); + } + else{ + sprintf(iptransInfo.debug_msg.iptr_asciout_buf, + "error comamnd!"); + } + break; + case 1: + break; + case 2: + case 3: + if(strcasecmp(cmd,"C")==0) + { + ClearStatistics(pageno); + break; + } + if(strstr(cmd,"C 49") || strstr(cmd,"c 49")) + { + port = atoi(&cmd[2]); + if(port>=PORT_BASE_NUM && porttm_hour * 4) + (tmnow->tm_min)/15; + return nowP; +} + +void *iptrShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg); +int iptrans_initshm() +{ + + iptrans_shm_ptr = (iptrans_shm *) iptrShmInit(iptrans_shm_id, PROG_NAME, + IPTRANS_SHM_KEY+wxc2_get_shm_offset(), + sizeof(iptrans_shm), IPTRANS_SHM_PERM|IPC_CREAT); + + + memset(iptrans_shm_ptr, 0, sizeof(iptrans_shm)); + + return 1; +} + +int StuffAllCSTA(char *pdata, int period); +int ConfigurePort() +{ + char confile[]={"./conf/iptrans.conf"}; + char s[80],s1[80],work[80]; + int loop,priority,len,type,direct=0; + unsigned char conf_state = 0xFF; + unsigned short port, realport; + //char *off; + FILE *fpConf; + + fpConf = fopen(confile,"rb"); + if(fpConf==NULL) + { + printf("%s not found!\n",confile); + for(loop=0;loopsa_family) + { + case AF_INET:{ + struct ip_mreq mreq; + struct ifreq ifreq; + memcpy(&mreq.imr_multiaddr, + &((struct sockaddr_in *)sa)->sin_addr, + sizeof(struct in_addr)); + if(ifindex>0){ + if(if_indextoname(ifindex,ifreq.ifr_name)==NULL){ + // errno=ENXIO; + return(-1); + } + goto doioctl; + } + else if(ifname !=NULL){ + strncpy(ifreq.ifr_name,ifname,IFNAMSIZ); + doioctl: + if(ioctl(sockfd,SIOCGIFADDR,&ifreq)<0) + return (-1); + memcpy(&mreq.imr_interface.s_addr, + &((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + return (setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP, + &mreq,sizeof(mreq))); + } + else + mreq.imr_interface.s_addr=htonl(INADDR_ANY);// inet_addr(name); +// setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_IF,&flag,sizeof(flag)); + return (setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP, + &mreq,sizeof(mreq))); + } + default: + // errno=EPROTONOSUPPORT; + return(-1); + } +} + +int +mcast_set_loop(int sockfd, int onoff) +{ + u_char flag; + flag=onoff; + return (setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_LOOP, + &flag,sizeof(flag))); +} +/*@end@*/ diff --git a/plat/iptrans/src/queuefunc.c b/plat/iptrans/src/queuefunc.c new file mode 100644 index 0000000..b14b957 --- /dev/null +++ b/plat/iptrans/src/queuefunc.c @@ -0,0 +1,133 @@ +/* +** CVS $Id: queuefunc.c,v 1.3 2001/02/08 10:53:33 zhangsz Exp $ +** +** filename: queuefunc.c +** created at 2000/12/29 +** by Zhang Shuzhong +** +** loop message queue operating functions. +** +*/ + +#include "./include/iptrans.h" + +extern u_char warningFlag; + +/*@ignore@*/ +/* Read a message from loop queue. */ +BOOL +iptrReadMsg(void *pbuf, void *pmsg, int max_num) +{ + in_buffer *p; + message_list *msg_ptr; + + p = (in_buffer *) pbuf; + msg_ptr = (message_list *) pmsg; +// memset(msg_ptr, EMPTY, sizeof(struct message_list)); + + /* + ** these are some messages not to be read + ** while subscript of read isn't equal to subscipt of write. + */ + if (p->msgReadSub == p->msgWriteSub) + return FAILURE; + + memcpy(msg_ptr, &p->msgList[p->msgReadSub], + p->msgList[p->msgReadSub].msgLength + 44); +/*message head length */ +// sizeof(struct message_list)); + /* + ** increase READ SUBSCRIPT after got a message, + ** set READ SUBSCRIPT to 0 while it equal to max_num. + */ + p->msgReadSub ++; + if (p->msgReadSub == max_num) + p->msgReadSub = 0; + return SUCCESS; +} + +extern int SetAsciioutMsg(int flag, const char *fmt, ...); +/* Write a message to loop queue. */ +BOOL +iptrWriteMsg(void *pbuf, void *pmsg, int max_num) +{ + in_buffer *p; + message_list *msg_ptr; + int port; + p = (in_buffer *) pbuf; + msg_ptr = (message_list *) pmsg; + memcpy(&p->msgList[p->msgWriteSub], msg_ptr, + msg_ptr->msgLength + 44);//sizeof(struct message_list)); + + p->msgWriteSub ++; + + /* + ** if write subscript more than max_num, + ** write subscript equal 0. + */ + if (p->msgWriteSub == max_num) + p->msgWriteSub = 0; + + /* + ** if message written successful, + ** Read subscript is same as Write subscript, + ** then Read subsrcipt add 1. + */ + if (p->msgReadSub == p->msgWriteSub) + { + (p->msgReadSub == max_num-1) ? + (p->msgReadSub = 0) : (p->msgReadSub ++); + if(warningFlag){ + port = msg_ptr->msgDstPort; + SetAsciioutMsg(1,"Warning! Port: %d overflowed!\r\n",port); + return 0; + } + } + return 1; +} + + +void +iptrByteRev(BYTE *pbuf, BYTE *p, size_t size) +{ + int i; + char ch; + + for (i=0; i> 4; + *pbuf <<= 4; + *pbuf &= ch; + } + memcpy(p, pbuf, size); +} + +void +iptrStrrev(char *sp) +{ + char ch; + ch = sp[0]; + sp[0] = sp[1]; + sp[1] = ch; +} + +void +iptrByteReverse(BYTE *pbuf, BYTE *p, size_t size) +{ + + int i; + char *sp=NULL, tmpbuf[3]; + + sp = (char *) malloc(4*size + 1); + bzero(p, size); + + for (i=0; i<2*size; i+=2) { + sprintf(tmpbuf, "%02x", *(pbuf++)); + tmpbuf[2]=0; + iptrStrrev(tmpbuf); + strncpy(sp+i, tmpbuf, 2); + } + AsciiToBcd(pbuf, sp, 4*size); + memcpy(p, pbuf, 2*size); + free(sp); +} +/*@end@*/ diff --git a/plat/iptrans/src/readmsg.c b/plat/iptrans/src/readmsg.c new file mode 100644 index 0000000..dc4c08c --- /dev/null +++ b/plat/iptrans/src/readmsg.c @@ -0,0 +1,190 @@ +/* +** PACS-WLL 2000 project, Prepaid System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** Written completely by Zhang Shuzhong at iCRD January, 2001 +** +** file name: iptrans.c +** CVS: $Id: iptrans.c,v 1.9 2001/02/09 08:53:43 zhangsz Exp $ +** +** Description: IP transceiver common module of PACS-WLL Project. +** +*/ + +#include "./include/iptrans.h" + +#define PROG_NAME "iptrans" + +extern int debug; /* defined in errorlog.c */ +extern int under_develop; /* defined in errorlog.c */ +static int iptrans_shm_id; +static int iptrans_sem_id; +static struct termio prev_termio; +static iptrans_shm *iptrans_shm_ptr; + +int GetMessage(message_list *msgGet,int port); +void PutMessage(message_list msgPut); + +/*@ignore@*/ +/* Set debug flag to control debug message print or not */ +void SetDebugFlag(void) +{ + debug = DEBUG; /* DEBUG defined in debug.h */ + under_develop = UNDER_DEVELOP; /* UNDER_DEVELOP defined in debug.h */ +} + +/* +** Handler of terminatation, +** process while received a signal from user. +*/ +static void Terminate(int sig) +{ + int retval; + + usleep(100000); + retval = (int) shmdt(0); + if (retval == -1) log_ret("%s: %s: shmdt", PROG_NAME, FUNCTION_MACRO); + retval = shmctl(iptrans_shm_id, IPC_RMID, NULL); + if (retval == -1) log_ret("%s: %s: shmctl", PROG_NAME, FUNCTION_MACRO); + retval = semctl(iptrans_sem_id, PORT_NUM, IPC_RMID, NULL); + if (retval == -1) log_ret("%s: %s: semctl", PROG_NAME, FUNCTION_MACRO); + exit(sig); +} + +int GetMessage(struct message_list *msgGet,int port) +{ + message_list msgSend; + if(iptrans_shm_ptr->msgPortIn[port].msgReadSub != iptrans_shm_ptr->msgPortIn[port].msgWriteSub) + { + memcpy(msgGet, + &iptrans_shm_ptr->msgPortIn[port].msgList[iptrans_shm_ptr->msgPortIn[port].msgReadSub], + sizeof(struct message_list)); + memcpy(&msgSend,msgGet,sizeof(struct message_list)); + PutMessage(msgSend); + fprintf(stderr,"Recv msg %d.\n",port+4951); + iptrans_shm_ptr->msgPortIn[port].msgReadSub ++; + if(iptrans_shm_ptr->msgPortIn[port].msgReadSub==IN_LIST_NUM) + iptrans_shm_ptr->msgPortIn[port].msgReadSub =0; + /* +fprintf(stderr,"iptrans state:\n port=%d\n packet in=%ld out=%ld errors=%ld %ld\n", + port, + iptrans_shm_ptr->msgPortStat[port].inPackets, + iptrans_shm_ptr->msgPortStat[port].outPackets, + iptrans_shm_ptr->msgPortStat[port].errorInPackets, + iptrans_shm_ptr->msgPortStat[port].errorOutPackets); +*/ + return 1; + } + else + { + return 0; + } +} + +void PutMessage(struct message_list msgPut) +{ + memcpy(&iptrans_shm_ptr->msgPortOut.msgList[iptrans_shm_ptr->msgPortOut.msgWriteSub], + &msgPut,sizeof(struct message_list)); + + iptrans_shm_ptr->msgPortOut.msgWriteSub ++; + if(iptrans_shm_ptr->msgPortOut.msgWriteSub==OUT_LIST_NUM) + iptrans_shm_ptr->msgPortOut.msgWriteSub=0; + +} + +void timer_IRQ() +{ + int i; + struct message_list msgList; + for(i=0;i<13;i++) + { + GetMessage(&msgList,i); + // PutMessage(msgList); + } + +} + + +void init_timer_interrupt(void) +{ + struct sigaction newact; + newact.sa_handler =timer_IRQ; + newact.sa_flags =0; + sigemptyset(&newact.sa_mask); + sigaction(SIGALRM,&newact,NULL); +} + +void setup_interval_timer(void) +{ + struct itimerval value; + value.it_interval.tv_sec =0; + value.it_interval.tv_usec =5*1000; + value.it_value =value.it_interval; + setitimer(ITIMER_REAL,&value,NULL); +} + +void init_timer() +{ + init_timer_interrupt(); + setup_interval_timer(); +} + +extern void DaemonInit(const char *pname, int facility); +extern void *ShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg); +extern void SetTermSignal(struct termio *ptermio, void (*handler)(int)); +int main(int argc, char *argv[]) +{ + int err_flag = FALSE; + int test_mode = FALSE; + int ret; + SetDebugFlag(); + + /* + ** Get option from command line. + ** option 'd' is enable to run program with daemon mode. + */ + while ((ret = getopt(argc, argv, "dt")) != -1) + switch (ret) + { + case 'd': + /* Set daemon mode and open a syslog */ + DaemonInit(PROG_NAME, LOG_USER); + break; + case 't': + test_mode = TRUE; /* test mode: bind port 4950 to recvfrom */ + break; + case '?': + err_flag = TRUE; + } + if (err_flag) { + log_msg("Usage: %s -d -t \n", argv[0]); + log_msg(" -d with daemon mode"); + log_msg(" -t with test mode"); + exit(1); + } + + /* + ** Get shared memory block, + ** IPTRANS_SHM_KEY to be defined in iptrans.h. + */ + iptrans_shm_ptr = (iptrans_shm *) ShmInit(iptrans_shm_id, PROG_NAME, + IPTRANS_SHM_KEY, sizeof(iptrans_shm), IPTRANS_SHM_PERM|IPC_CREAT); + memset(iptrans_shm_ptr, 0, sizeof(iptrans_shm)); + + /* + ** Get semaphores ID used by shared memory block, + ** IPTRANS_SEM_KEY to be defined in iptrans.h. + */ + + SetTermSignal(&prev_termio, Terminate); + /* + ** Open socket handler for IP transceiver. + ** maxinum number is PORT_NUM. + */ + init_timer(); + while(1){ + usleep(1); + } + exit(0); +} +/*@end@*/ diff --git a/plat/iptrans/src/signal.c b/plat/iptrans/src/signal.c new file mode 100644 index 0000000..8893720 --- /dev/null +++ b/plat/iptrans/src/signal.c @@ -0,0 +1,33 @@ +/* +** PACS-WLL 2000 project, Prepaid System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** +** Written completely by Zhang Shuzhong at iCRD January, 2001 +** +** module name: signal.c +** CVS $Id: signal.c,v 1.2 2001/01/11 04:07:56 zhangsz Exp $ +** +** Signal functions +** +*/ + +#include "./include/iptrans.h" + +/* +** Set termination signal in a loop program, +** handler of function mostly deal with something, +** e.g. closing file handler, socket handler or free allocatied memory. +*/ +/*@ignore@*/ +void +SetTermSignal(struct termio *ptermio, void (*handler)(int)) +{ + ioctl(0, TCGETA, ptermio); + ptermio->c_cc[VINTR] = '\x03'; + ioctl(0, TCSETA, ptermio); + + signal(SIGINT, handler); + signal(SIGTERM, handler); +} +/*@end@*/ diff --git a/plat/iptrans/src/simu_debug.c b/plat/iptrans/src/simu_debug.c new file mode 100644 index 0000000..88d9e7f --- /dev/null +++ b/plat/iptrans/src/simu_debug.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +extern void debug_init(); +extern int init_iptrans(); +extern void snmp_init(unsigned short nport); +extern void debug_rt(); +extern void snmp_timer(); + +/*@ignore@*/ +int main() +{ + debug_init(); + init_iptrans(); + snmp_init(4957); +// heartbeat_init(0); + while(1) + { + debug_rt(); + snmp_timer(); + // heartbeat_timer(); + usleep(1); + } + return 1; +} +/*@end@*/ diff --git a/plat/m2ua/Makefile b/plat/m2ua/Makefile new file mode 100644 index 0000000..6a781e9 --- /dev/null +++ b/plat/m2ua/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = m2ua +TYPE = plat + +DBUG_FLAGS_ADD = -D_LKSCTP +RELS_FLAGS_ADD = -D_LKSCTP + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/m2ua/src/include/m2ua.h b/plat/m2ua/src/include/m2ua.h new file mode 100644 index 0000000..3f050c0 --- /dev/null +++ b/plat/m2ua/src/include/m2ua.h @@ -0,0 +1,151 @@ +#ifndef _M2UA__H +#define _M2UA__H + +//#include "m2ua_struct.h" + + +#ifndef M2UA_MAX_MSG_LEN +#define M2UA_MAX_MSG_LEN 360 +#endif + + +typedef struct _m2ua_up_msg +{ + WORD link __attribute__((packed)); + WORD len __attribute__((packed)); + BYTE sio;// __attribute__((packed)); + + union + { + struct + { + BYTE content[M2UA_MAX_MSG_LEN];// __attribute__((packed)); + }mtp3;// __attribute__((packed)); + + struct + { + BYTE mtp3_ip;// __attribute__((packed)); + BYTE opercode;// __attribute__((packed)); + BYTE alarmcode;// __attribute__((packed)); + }lm;// __attribute__((packed)); + }msg;// __attribute__((packed)); + +}m2ua_up_msg_t; + +void m2ua_init(BYTE); +void m2ua_timer(void); + +int get_m2ua_msg(m2ua_up_msg_t **data_ptr); +int put_m2ua_msg(m2ua_up_msg_t *data_ptr); + + +int set_m2ua_link(WORD link, BYTE *data_ptr); +int set_m2ua_sg(WORD sg, BYTE *data_ptr); +int m2ua_restart(); + +typedef struct _xua_lm_lk +{ + WORD link __attribute__((packed)); + WORD len __attribute__((packed)); /* len = 3 */ + BYTE mtp3_ip;// __attribute__((packed)); + BYTE opercode;// __attribute__((packed)); + BYTE alarmcode;// __attribute__((packed)); +}xua_lm_lk; + +typedef struct _xua_iua_msg +{ + WORD link __attribute__((packed)); + WORD len __attribute__((packed)); /* len for content */ + BYTE content[M2UA_MAX_MSG_LEN];// __attribute__((packed)); +}xua_iua_msg; + +typedef struct _xua_m2ua_msg +{ + WORD link __attribute__((packed)); + WORD len __attribute__((packed)); /* len for content */ + BYTE content[M2UA_MAX_MSG_LEN];// __attribute__((packed)); +}xua_m2ua_msg; + +typedef struct _xua_m3ua_msg +{ + WORD link __attribute__((packed)); + WORD len __attribute__((packed)); /* len for content */ + DWORD rc __attribute__((packed)); + DWORD opc __attribute__((packed)); /* routing label*/ + DWORD dpc __attribute__((packed)); /* Big-Endian (WORD, DWORD) */ + BYTE si;// __attribute__((packed)); + BYTE ni;// __attribute__((packed)); + BYTE mp;// __attribute__((packed)); + BYTE sls;// __attribute__((packed)); + BYTE content[M2UA_MAX_MSG_LEN];// __attribute__((packed)); /* mtp3-user data */ +}xua_m3ua_msg; + + +typedef struct _xua_rc_cmd +{ + WORD link __attribute__((packed)); + WORD len __attribute__((packed)); /* len = 5 */ + DWORD rc __attribute__((packed)); //Routing_Context + BYTE opercode;// __attribute__((packed)); //Routing_Context statue +}xua_rc_cmd; + +typedef struct _xua_ssnm_cmd +{ + WORD link __attribute__((packed)); + WORD len __attribute__((packed)); /* len = 17 */ + BYTE type;// __attribute__((packed)); //message type + DWORD aff_pc __attribute__((packed)); //M3UA_Affected_PC + DWORD user_cause __attribute__((packed)); //M3UA_User_Cause + DWORD cong_ind __attribute__((packed)); //M3UA_Congestion_Indications + DWORD con_dpc __attribute__((packed)); //M3UA_Concerned_Destination +}xua_ssnm_cmd; + + +typedef struct _xua_up_msg +{ + BYTE msg_class;// __attribute__((packed)); + union + { + xua_lm_lk lm_lk;// __attribute__((packed)); + xua_m2ua_msg m2ua;// __attribute__((packed)); + xua_iua_msg iua;// __attribute__((packed)); + xua_m3ua_msg m3ua;// __attribute__((packed)); + xua_rc_cmd rc_cmd;// __attribute__((packed)); + xua_ssnm_cmd ssnm_cmd;// __attribute__((packed)); + }msg;// __attribute__((packed)); +}xua_up_msg_t; + + +int get_xua_msg(BYTE xUA_type, xua_up_msg_t **data_ptr); +int put_xua_msg(xua_up_msg_t *data_ptr); + +int get_m3ua_msg(xua_up_msg_t **data_ptr); +int put_m3ua_msg(xua_up_msg_t *data_ptr); + + +#define M2UAHEADOFFSET 4 //lk(2)+len(2) sio include to data +#define M2UARESERVEHEAD (20 - M2UAHEADOFFSET) + +#define XUAHEADOFFSET 5 //msg_class(1)+lk(2)+len(2) +#define RESERVE_FOR_IUAHEAD (28 - XUAHEADOFFSET) +#define RESERVE_FOR_M2UAHEAD (20 - XUAHEADOFFSET) +#define RESERVE_FOR_M3UAHEAD (20 - XUAHEADOFFSET -4) + + +#define IUA_QPTM_MSG 0x05 +#define M2UA_MAUP_MSG 0x06 +#define M3UA_MAUP_MSG 0x07 + +#define IUA_MGMT_CMD 0xA5 +#define M2UA_MGMT_CMD 0xA6 +#define M3UA_MGMT_CMD 0xA7 + +#define M3UA_RC_CMD 0xF5 +#define M3UA_SSNM_CMD 0xF6 + +#define M2UA_APP 0 +#define IUA_APP 1 +#define M3UA_APP 2 + + +#endif diff --git a/plat/m2ua/src/include/m2ua_const.h b/plat/m2ua/src/include/m2ua_const.h new file mode 100644 index 0000000..f7e05b2 --- /dev/null +++ b/plat/m2ua/src/include/m2ua_const.h @@ -0,0 +1,383 @@ +#ifndef _M2UA_CONST__H +#define _M2UA_CONST__H + +#define M2UA_MAX_LK_NUM 1024 +#define M2UA_MAX_MSG_LEN 360 + +#define M2UA_MAX_SG_NUM 512 + +#define M2UA_LISTEN_SG_NUM_0 512 +#define M2UA_LISTEN_SG_NUM_1 513 + +#define IUA_LISTEN_SG_NUM_0 514 +#define IUA_LISTEN_SG_NUM_1 515 + +#define M3UA_LISTEN_SG_NUM_0 516 +#define M3UA_LISTEN_SG_NUM_1 517 + +#define M2UA_PORT_0 2904 +#define M2UA_PORT_1 12904 + +#define IUA_PORT_0 9900 +#define IUA_PORT_1 19900 + +#define M3UA_PORT_0 2905 +#define M3UA_PORT_1 12905 + + +#define M2UA_MAX_SG_FSM_NUM (512+6)//for listen m2ua*2,iua*2,m3ua*2 + + +#define M2UA_MAX_M3MSG_NUM 2048 +#define M2UA_MAX_M3MSG_NUM_1 2047 + +#define M2UA_SCTP_CMD_BUFSIZE 5*1024 +#define M2UA_SCTP_DAT_BUFSIZE 5*1024 + +#define M2UA_FAILURE -1 +#define M2UA_SUCCESS 0 + +#define M2UA_CMD_IDLEW 0xEEEE + +// M2UA Message Class +#define M2UA_MCLASS_MGMT 0 +#define M2UA_MCLASS_ASPSM 3 +#define M2UA_MCLASS_ASPTM 4 +#define M2UA_MCLASS_MAUP 6 +#define M2UA_MCLASS_IIM 10 + + +#define xUA_MCLASS_MGMT 0 +#define xUA_MCLASS_TRMSG 1 +#define xUA_MCLASS_SSNM 2 +#define xUA_MCLASS_ASPSM 3 +#define xUA_MCLASS_ASPTM 4 +#define xUA_MCLASS_QPTM 5 +#define xUA_MCLASS_MAUP 6 +#define xUA_MCLASS_RKM 9 +#define xUA_MCLASS_IIM 10 + +// M2UA ASPSM Message Type +#define ASP_UP 1 +#define ASP_DOWN 2 +#define HEARTBEAT 3 +#define ASP_UP_ACK 4 +#define ASP_DOWN_ACK 5 +#define HEARTBEAT_ACK 6 + +// M2UA ASPSM Combined Message Type +#define M2UA_ASPSM_ASP_UP (M2UA_MCLASS_ASPSM << 8) + ASP_UP +#define M2UA_ASPSM_ASP_DOWN (M2UA_MCLASS_ASPSM << 8) + ASP_DOWN +#define M2UA_ASPSM_HEARTBEAT (M2UA_MCLASS_ASPSM << 8) + HEARTBEAT +#define M2UA_ASPSM_ASP_UP_ACK (M2UA_MCLASS_ASPSM << 8) + ASP_UP_ACK +#define M2UA_ASPSM_ASP_DOWN_ACK (M2UA_MCLASS_ASPSM << 8) + ASP_DOWN_ACK +#define M2UA_ASPSM_HEARTBEAT_ACK (M2UA_MCLASS_ASPSM << 8) + HEARTBEAT_ACK + +#define xUA_ASPSM_ASP_UP (xUA_MCLASS_ASPSM << 8) + ASP_UP +#define xUA_ASPSM_ASP_DOWN (xUA_MCLASS_ASPSM << 8) + ASP_DOWN +#define xUA_ASPSM_HEARTBEAT (xUA_MCLASS_ASPSM << 8) + HEARTBEAT +#define xUA_ASPSM_ASP_UP_ACK (xUA_MCLASS_ASPSM << 8) + ASP_UP_ACK +#define xUA_ASPSM_ASP_DOWN_ACK (xUA_MCLASS_ASPSM << 8) + ASP_DOWN_ACK +#define xUA_ASPSM_HEARTBEAT_ACK (xUA_MCLASS_ASPSM << 8) + HEARTBEAT_ACK + +#define ASP_ACTIVE 1 +#define ASP_INACTIVE 2 +#define ASP_ACTIVE_ACK 3 +#define ASP_INACTIVE_ACK 4 + +#define M2UA_ASPTM_ASP_ACTIVE (M2UA_MCLASS_ASPTM << 8) + ASP_ACTIVE +#define M2UA_ASPTM_ASP_INACTIVE (M2UA_MCLASS_ASPTM << 8) + ASP_INACTIVE +#define M2UA_ASPTM_ASP_ACTIVE_ACK (M2UA_MCLASS_ASPTM << 8) + ASP_ACTIVE_ACK +#define M2UA_ASPTM_ASP_INACTIVE_ACK (M2UA_MCLASS_ASPTM << 8) + ASP_INACTIVE_ACK + +#define xUA_ASPTM_ASP_ACTIVE (xUA_MCLASS_ASPTM << 8) + ASP_ACTIVE +#define xUA_ASPTM_ASP_INACTIVE (xUA_MCLASS_ASPTM << 8) + ASP_INACTIVE +#define xUA_ASPTM_ASP_ACTIVE_ACK (xUA_MCLASS_ASPTM << 8) + ASP_ACTIVE_ACK +#define xUA_ASPTM_ASP_INACTIVE_ACK (xUA_MCLASS_ASPTM << 8) + ASP_INACTIVE_ACK + +//for MAUP +#define DATA 1 +#define ESTABLISH_REQ 2 +#define ESTABLISH_CFM 3 +#define RELEASE_REQ 4 +#define RELEASE_CFM 5 +#define RELEASE_IND 6 +#define STATE_REQ 7 +#define STATE_CFM 8 +#define STATE_IND 9 +#define DATA_RETIEVE_REQ 10 +#define DATA_RETIEVE_CFM 11 +#define DATA_RETIEVE_IND 12 +#define DATA_RETIEVE_CMP 13 +#define CONGESTION_IND 14 +#define DATA_ACK 15 + +#define M2UA_MAUP_DATA (M2UA_MCLASS_MAUP << 8) + DATA +#define M2UA_MAUP_ESTABLISH_REQ (M2UA_MCLASS_MAUP << 8) + ESTABLISH_REQ +#define M2UA_MAUP_ESTABLISH_CFM (M2UA_MCLASS_MAUP << 8) + ESTABLISH_CFM +#define M2UA_MAUP_RELEASE_REQ (M2UA_MCLASS_MAUP << 8) + RELEASE_REQ +#define M2UA_MAUP_RELEASE_CFM (M2UA_MCLASS_MAUP << 8) + RELEASE_CFM +#define M2UA_MAUP_RELEASE_IND (M2UA_MCLASS_MAUP << 8) + RELEASE_IND +#define M2UA_MAUP_STATE_REQ (M2UA_MCLASS_MAUP << 8) + STATE_REQ +#define M2UA_MAUP_STATE_CFM (M2UA_MCLASS_MAUP << 8) + STATE_CFM +#define M2UA_MAUP_STATE_IND (M2UA_MCLASS_MAUP << 8) + STATE_IND +#define M2UA_MAUP_DATA_RETIEVE_REQ (M2UA_MCLASS_MAUP << 8) + DATA_RETIEVE_REQ +#define M2UA_MAUP_DATA_RETIEVE_CFM (M2UA_MCLASS_MAUP << 8) + DATA_RETIEVE_CFM +#define M2UA_MAUP_DATA_RETIEVE_IND (M2UA_MCLASS_MAUP << 8) + DATA_RETIEVE_IND +#define M2UA_MAUP_DATA_RETIEVE_CMP (M2UA_MCLASS_MAUP << 8) + DATA_RETIEVE_CMP +#define M2UA_MAUP_CONGESTION_IND (M2UA_MCLASS_MAUP << 8) + CONGESTION_IND +#define M2UA_MAUP_DATA_ACK (M2UA_MCLASS_MAUP << 8) + DATA_ACK + +//Transfer Messages +#define M3UA_DATA 1 +//SSNM +#define SSNM_DUNA 1 // 1 Destination Unavailable (DUNA) +#define SSNM_DAVA 2 // 2 Destination Available (DAVA) +#define SSNM_DAUD 3 // 3 Destination State Audit (DAUD) +#define SSNM_SCON 4 // 4 Signalling Congestion (SCON) +#define SSNM_DUPU 5 // 5 Destination User Part Unavailable (DUPU) +#define SSNM_DRST 6 // 6 Destination Restricted (DRST) + +#define M3UA_MAUP_DATA (xUA_MCLASS_TRMSG << 8) + M3UA_DATA + +#define M3UA_SSNM_DUNA (xUA_MCLASS_SSNM << 8) + SSNM_DUNA +#define M3UA_SSNM_DAVA (xUA_MCLASS_SSNM << 8) + SSNM_DAVA +#define M3UA_SSNM_DAUD (xUA_MCLASS_SSNM << 8) + SSNM_DAUD +#define M3UA_SSNM_SCON (xUA_MCLASS_SSNM << 8) + SSNM_SCON +#define M3UA_SSNM_DUPU (xUA_MCLASS_SSNM << 8) + SSNM_DUPU +#define M3UA_SSNM_DRST (xUA_MCLASS_SSNM << 8) + SSNM_DRST + + + +//QPTM +#define IUA_DATA_REQ 1 +#define IUA_DATA_IND 2 +#define IUA_UDATA_REQ 3 +#define IUA_UDATA_IND 4 +#define IUA_ESTABLISH_REQ 5 +#define IUA_ESTABLISH_CFM 6 +#define IUA_ESTABLISH_IND 7 +#define IUA_RELEASE_REQ 8 +#define IUA_RELEASE_CFM 9 +#define IUA_RELEASE_IND 10 + +#define IUA_QPTM_DATA_REQ (xUA_MCLASS_QPTM << 8) + IUA_DATA_REQ +#define IUA_QPTM_DATA_IND (xUA_MCLASS_QPTM << 8) + IUA_DATA_IND +#define IUA_QPTM_UDATA_REQ (xUA_MCLASS_QPTM << 8) + IUA_UDATA_REQ +#define IUA_QPTM_UDATA_IND (xUA_MCLASS_QPTM << 8) + IUA_UDATA_IND +#define IUA_QPTM_ESTABLISH_REQ (xUA_MCLASS_QPTM << 8) + IUA_ESTABLISH_REQ +#define IUA_QPTM_ESTABLISH_CFM (xUA_MCLASS_QPTM << 8) + IUA_ESTABLISH_CFM +#define IUA_QPTM_ESTABLISH_IND (xUA_MCLASS_QPTM << 8) + IUA_ESTABLISH_IND +#define IUA_QPTM_RELEASE_REQ (xUA_MCLASS_QPTM << 8) + IUA_RELEASE_REQ +#define IUA_QPTM_RELEASE_CFM (xUA_MCLASS_QPTM << 8) + IUA_RELEASE_CFM +#define IUA_QPTM_RELEASE_IND (xUA_MCLASS_QPTM << 8) + IUA_RELEASE_IND + + +#define xUA_ERROR 0 +#define xUA_NOTIFY 1 + + +#define TEI_S_REQ 2 +#define TEI_S_CFM 3 +#define TEI_S_IND 4 + + + +#define M2UA_MGMT_ERROR (M2UA_MCLASS_MGMT << 8) + xUA_ERROR +#define M2UA_MGMT_NOTIFY (M2UA_MCLASS_MGMT << 8) + xUA_NOTIFY + +#define xUA_MGMT_ERROR (xUA_MCLASS_MGMT << 8) + xUA_ERROR +#define xUA_MGMT_NOTIFY (xUA_MCLASS_MGMT << 8) + xUA_NOTIFY +#define xUA_MGMT_TEI_S_REQ (xUA_MCLASS_MGMT << 8) + TEI_S_REQ +#define xUA_MGMT_TEI_S_CFM (xUA_MCLASS_MGMT << 8) + TEI_S_CFM +#define xUA_MGMT_TEI_S_IND (xUA_MCLASS_MGMT << 8) + TEI_S_IND + +#define M2UA_IIM_REG_REQ 1 +#define M2UA_IIM_REG_RSP 2 +#define M2UA_IIM_DEREG_REQ 3 +#define M2UA_IIM_DEREG_RSP 4 + +#define M2UA_PAR_INTERFACE_ID_INT 0x0001 +#define M2UA_PAR_INTERFACE_ID_TXT 0x0003 +#define M2UA_PAR_TRAFFIC_MODE 0x000B +#define M2UA_PAR_CORRELATION_ID xUA_PAR_CORRELATION_ID +#define M2UA_PAR_ASP_IDENTIFIER 0x0011 +#define M2UA_PAR_PROTO_DATA_1 0x0300 + +#define M2UA_PAR_STATE 0x0302 +#define M2UA_PAR_STATUS 0x000D +#define M2UA_PAR_ERR_CODE 0x000C + +#define xUA_Routing_Context 0x0006 +#define xUA_PAR_DLCI 0x0005 +#define xUA_PAR_PROTOCOL_DATA 0x000E +#define xUA_PAR_REL_REASON 0x000F +#define xUA_PAR_TEI_STATUS 0x0010 +#define xUA_Affected_PC 0x0012 +#define xUA_PAR_CORRELATION_ID 0x0013 + +//M3UA-Specific parameters +#define M3UA_Network_Appearance 0x0200 +#define M3UA_User_Cause 0x0204 +#define M3UA_Congestion_Indications 0x0205 +#define M3UA_Concerned_Destination 0x0206 +#define M3UA_Routing_Key 0x0207 +#define M3UA_Registration_Result 0x0208 +#define M3UA_Deregistration_Result 0x0209 +#define M3UA_Local_Routing_Key_Identifier 0x020a +#define M3UA_Destination_Point_Code 0x020b +#define M3UA_Service_Indicators 0x020c +#define M3UA_Originating_Point_Code_List 0x020e +#define M3UA_Circuit_Range 0x020f +#define M3UA_Protocol_Data 0x0210 + + + +#define M2UA_STATUS_LPO_SET 0x0 +#define M2UA_STATUS_LPO_CLEAR 0x1 +#define M2UA_STATUS_EMER_SET 0x2 +#define M2UA_STATUS_EMER_CLEAR 0x3 +#define M2UA_STATUS_FLUSH_BUFFERS 0x4 +#define M2UA_STATUS_CONTINUE 0x5 +#define M2UA_STATUS_CLEAR_RTB 0x6 +#define M2UA_STATUS_AUDIT 0x7 +#define M2UA_STATUS_CONG_CLEAR 0x8 +#define M2UA_STATUS_CONG_ACCEPT 0x9 +#define M2UA_STATUS_CONG_DISCARD 0xa + +#define M2UA_STATUS_TYPE_AS_STATE_CHG 1 +#define M2UA_STATUS_TYPE_OTHER 2 + +#define M2UA_STATUS_INFO_AS_RESERVED 1 +#define M2UA_STATUS_INFO_AS_INACTIVE 2 +#define M2UA_STATUS_INFO_AS_ACTIVE 3 +#define M2UA_STATUS_INFO_AS_PENDING 4 + +#define M2UA_ERR_INVALID_VERSION 0x1 +#define M2UA_ERR_INVALID_IID 0x2 +#define M2UA_ERR_UNSUPPORTED_MSG_CLASS 0x3 +#define M2UA_ERR_UNSUPPORTED_MSG_TYPE 0x4 +#define M2UA_ERR_UNSUPPORTED_TRA_HDL_MODE 0x5 +#define M2UA_ERR_UNEXPECTED_MSG 0x6 +#define M2UA_ERR_PROTOCOL_ERROR 0x7 +#define M2UA_ERR_UNSUPPORTED_IIT 0x8 +#define M2UA_ERR_INVALID_SID 0x9 +#define M2UA_ERR_REFUSED_MGMT_BLOCK 0xd +#define M2UA_ERR_ASP_ID_REQUIRED 0xe +#define M2UA_ERR_INVALID_ASP_ID 0xf +#define M2UA_ERR_ASP_ACTIVE_FOR_IID 0x10 +#define M2UA_ERR_INVALID_PARA_VAL 0x11 +#define M2UA_ERR_PARA_FIELD_ERROR 0x12 +#define M2UA_ERR_UNEXPECTED_PARA 0x13 +#define M2UA_ERR_MISSING_PARA 0x16 +//m3ua error code +#define M3UA_ERR_INVALID_DSUN 0x14 //Destination Status Unknown +#define M3UA_ERR_INVALID_NETAPP 0x16 //Invalid Network Appearance +#define M3UA_ERR_INVALID_RC 0x19 + +#define IUA_TEI_ASSIGNED 0x0 +#define IUA_TEI_UNASSIGNED 0x1 + +#define IUA_RELEASE_MGMT 0x00 +#define IUA_RELEASE_PHYS 0x01 +#define IUA_RELEASE_DM 0x02 +#define IUA_RELEASE_OTHER 0x03 + + +#define M2UA_TRAFFIC_MODE_OVERRIDE 1 +#define M2UA_TRAFFIC_MODE_LOADSHARE 2 +#define M2UA_TRAFFIC_MODE_BROADCAST 3 + +#define M2UA_LK_IDLE 0 +#define M2UA_LK_DOWN 1 +#define M2UA_LK_UP 5 +#define M2UA_LK_PO 6 + +#define M3UA_RC_DOWN 1 +#define M3UA_RC_UP 5 + +#define M2UA_MCLASS_MTP3 1 +#define M2UA_MCLASS_LM 2 + +#define M2UA_MTP3_SIO_CMD 0xFF +#define M2UA_SIO_CMD 0xEF +#define M2UA_MTP3_SIO_MSG 0x80 + + +#define M2UA_LK_ATTR_SIGTRAN 1 +#define M2UA_MTP3_MAX_LS_NUM 512 + +#define M2UA_MTP3_CMD_ACTIVE_LK 1 +#define M2UA_MTP3_CMD_DEACTIVE_LK 2 +#define M2UA_MTP3_CMD_STOP_L2 3 +#define M2UA_MTP3_CMD_EMERG_ALIGN 4 + +#define xUA_MTP3_CMD_ACTIVE_RC 1 +#define xUA_MTP3_CMD_DEACTIVE_RC 2 + + + + +#define M2UA_T_ACK 100 // 2 seconds = 100 * 20ms +#define M2UA_T_R 100 // 2 seconds +#define M2UA_T_LK_ESTAB 4 // 10 seconds = 4 * 2.56s +#define M2UA_T_SG_ESTAB_1 500 // 10 seconds +#define M2UA_T_SG_ESTAB_2 6000 // 120 seconds +#define M2UA_T_SG_ESTAB_3 1000 // 20 seconds +#define M2UA_T_SG_WAIT 100 // 2 seconds + +#define M2UA_TIMER5S 250 // 5 seconds + +#define M2UA_CMD_IDLE 0 +#define M2UA_CMD_PARA_SAVE 1 +#define M2UA_CMD_PARA_INIT 2 +#define M2UA_CMD_STATUS_INIT 3 + +#define M2UA_MGMT_CMD_LK_LOCK 1 +#define IUA_MGMT_CMD_LK_LOCK 2 + +#define MAX_ASCIIIN_LEN 4096 +#define MAX_ASCIIOUT_LEN 4096 +#define MAX_ASCITMP_LEN 4096 + +#define MONITOR_NONE 0x0000 +#define MONITOR_MTP3 0x0001 +#define MONITOR_M2UA 0x0002 +#define MONITOR_MAUP 0x0004 +#define MONITOR_SCTP 0x0008 +#define MONITOR_ERROR 0x0010 +#define MONITOR_ALL 0xffff + +#define M2UA_MAX_RETRANS 10 + +#define M2UA_STOP_M2UA_LINK 6 +#define M2UA_ENABLE_M2UA_LINK 7 + +#define xUA_STOP_xUA_LINK 6 +#define xUA_ENABLE_xUA_LINK 7 + +#define M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP ((SCTP_ASSOC_CHANGE << 16) | (SCTP_COMM_UP & 0xFFFF)) +#define M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST ((SCTP_ASSOC_CHANGE << 16) | (SCTP_COMM_LOST & 0xFFFF)) +#define M2UA_LKSCTP_ASSOC_CHANGE_SHUTDOWN_COMP ((SCTP_ASSOC_CHANGE << 16) | (SCTP_SHUTDOWN_COMP & 0xFFFF)) +#define M2UA_LKSCTP_ASSOC_CHANGE_RESTART ((SCTP_ASSOC_CHANGE << 16) | (SCTP_RESTART & 0xFFFF)) +#define M2UA_LKSCTP_ASSOC_CHANGE_CANT_STR_ASSOC ((SCTP_ASSOC_CHANGE << 16) | (SCTP_CANT_STR_ASSOC & 0xFFFF)) + +#define M2UA_LKSCTP_SEND_FAILED (SCTP_SEND_FAILED << 16) +#define M2UA_LKSCTP_PEER_ADDR_CHANGE (SCTP_PEER_ADDR_CHANGE << 16) +#define M2UA_LKSCTP_REMOTE_ERROR (SCTP_REMOTE_ERROR << 16) +#define M2UA_LKSCTP_SHUTDOWN_EVENT (SCTP_SHUTDOWN_EVENT << 16) + +#define M2UA_LKSCTP_DATA_IND 0x7FFFFFFE +#define M2UA_LKSCTP_UNKNOWN_EVENT 0x7FFFFFFF + +#define M2UA_ALARM_CODE_NORMAL 0 +#define M2UA_ALARM_CODE_SCTP_FAILURE 1 +#define M2UA_ALARM_CODE_REMOTE_AS_DOWN 2 +#define M2UA_ALARM_CODE_REMOTE_LINK_RELEASE 3 +#define M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN 4 +#define M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE 5 +#define M2UA_ALARM_CODE_LOCAL_LINK_MAINTENANCE 6 +#define M3UA_ALARM_CODE_DEST_UNA 7 +#define M3UA_ALARM_CODE_DEST_AVA 8 + +#endif diff --git a/plat/m2ua/src/include/m2ua_debug.h b/plat/m2ua/src/include/m2ua_debug.h new file mode 100644 index 0000000..3bf6b18 --- /dev/null +++ b/plat/m2ua/src/include/m2ua_debug.h @@ -0,0 +1,10 @@ +#ifndef _M2UA_DEBUG__H +#define _M2UA_DEBUG__H + +void m2ua_mon(void); +int m2ua_debug_set(void); +int m2ua_asciout_proc(char *out_str); +int m2ua_hex_to_ascii(BYTE *from_hex, WORD from_len, BYTE *to_asc); +int m2ua_log_err(WORD sg_id, char *err_msg); + +#endif diff --git a/plat/m2ua/src/include/m2ua_def.h b/plat/m2ua/src/include/m2ua_def.h new file mode 100644 index 0000000..21a0f1d --- /dev/null +++ b/plat/m2ua/src/include/m2ua_def.h @@ -0,0 +1,69 @@ +#ifndef _M2UA_DEF__H +#define _M2UA_DEF__H + +#include "m2ua_pub.h" +#include "m2ua.h" +#include "m2ua_const.h" +#include "m2ua_struct.h" + +/*const BYTE m2ua_ver[3] = {10, 0, 6}; +BYTE m2ua_command = 0; + +m2ua_sg_info_t m2ua_sg_info[M2UA_MAX_SG_FSM_NUM]; +m2ua_lk_info_t m2ua_lk_info[M2UA_MAX_LK_NUM]; + +m2ua_sctp_addr_t m2ua_sctp_addr; + +m2ua_sctp_cmd_t m2ua_sctp_cmd; +BYTE m2ua_sctp_dat[M2UA_SCTP_DAT_BUFSIZE]; //receive +BYTE m2ua_sctp_dat_send[M2UA_SCTP_DAT_BUFSIZE]; //send +int m2ua_sctp_cmd_len; +int m2ua_sctp_dat_len; + +#ifndef _LKSCTP +struct strbuf m2ua_sctp_ctrl = {M2UA_SCTP_CMD_BUFSIZE, 0, m2ua_sctp_cmd.cbuf}; +struct strbuf m2ua_sctp_data = {M2UA_SCTP_DAT_BUFSIZE, 0, m2ua_sctp_dat}; +#else +m2ua_sctp_data_t m2ua_sctp_data = {M2UA_SCTP_DAT_BUFSIZE, 0, m2ua_sctp_dat}; +#endif + +m2ua_para_t m2ua_para; + +BYTE m2ua_mtp3_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +WORD m2ua_mtp3_sd_h; +WORD m2ua_mtp3_sd_t; + +BYTE m3ua_mtp3_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +WORD m3ua_mtp3_sd_h; +WORD m3ua_mtp3_sd_t; + +BYTE iua_q931_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +WORD iua_q931_sd_h; +WORD iua_q931_sd_t; + + + +DWORD x256[M2UA_MAX_M3MSG_NUM]; + +char hostip[20]; +char hostname[50]; +ulong host_ip; +BYTE plat_id; + +m2ua_sctp_addr_t m2ua_sctp_server_addr; +m2ua_csta_t m2ua_csta; + +char m2ua_asciin_buf[MAX_ASCIIIN_LEN]; +char m2ua_asciout_buf[MAX_ASCIIOUT_LEN]; +char m2ua_ascitemp_buf[MAX_ASCITMP_LEN]; +WORD moniter_fg; + +BYTE m2ua_sg_mon_fg[M2UA_MAX_SG_FSM_NUM]; +BYTE m2ua_lk_mon_fg[M2UA_MAX_LK_NUM]; +WORD m2ua_sg_mon_count; +WORD m2ua_lk_mon_count; + +DWORD err[64]; +BYTE init_flag;*/ + +#endif diff --git a/plat/m2ua/src/include/m2ua_ext.h b/plat/m2ua/src/include/m2ua_ext.h new file mode 100644 index 0000000..88c154a --- /dev/null +++ b/plat/m2ua/src/include/m2ua_ext.h @@ -0,0 +1,67 @@ +#ifndef _M2UA_EXT__H +#define _M2UA_EXT__H + +#include "m2ua_pub.h" +#include "m2ua.h" +#include "m2ua_const.h" +#include "m2ua_struct.h" + +extern const BYTE m2ua_ver[3]; +extern BYTE m2ua_command; + +extern m2ua_sg_info_t m2ua_sg_info[M2UA_MAX_SG_FSM_NUM]; +extern m2ua_lk_info_t m2ua_lk_info[M2UA_MAX_LK_NUM]; + +extern m2ua_sctp_addr_t m2ua_sctp_addr; + +extern m2ua_sctp_cmd_t m2ua_sctp_cmd; +extern BYTE m2ua_sctp_dat[M2UA_SCTP_DAT_BUFSIZE]; +extern BYTE m2ua_sctp_dat_send[M2UA_SCTP_DAT_BUFSIZE]; +extern int m2ua_sctp_cmd_len; +extern int m2ua_sctp_dat_len; + +#ifndef _LKSCTP +extern struct strbuf m2ua_sctp_ctrl; +extern struct strbuf m2ua_sctp_data; +#else +extern m2ua_sctp_data_t m2ua_sctp_data; +#endif + +extern m2ua_para_t m2ua_para; + +extern BYTE m2ua_mtp3_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +extern WORD m2ua_mtp3_sd_h; +extern WORD m2ua_mtp3_sd_t; + +extern BYTE m3ua_mtp3_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +extern WORD m3ua_mtp3_sd_h; +extern WORD m3ua_mtp3_sd_t; + +extern BYTE iua_q931_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +extern WORD iua_q931_sd_h; +extern WORD iua_q931_sd_t; + +extern DWORD x256[M2UA_MAX_M3MSG_NUM]; + +extern char hostip[20]; +extern char hostname[50]; +extern ulong host_ip; +extern BYTE plat_id; + +extern m2ua_sctp_addr_t m2ua_sctp_server_addr; +extern m2ua_csta_t m2ua_csta; + +extern char m2ua_asciin_buf[MAX_ASCIIIN_LEN]; +extern char m2ua_asciout_buf[MAX_ASCIIOUT_LEN]; +extern char m2ua_ascitemp_buf[MAX_ASCITMP_LEN]; +extern WORD moniter_fg; + +extern BYTE m2ua_sg_mon_fg[M2UA_MAX_SG_FSM_NUM]; +extern BYTE m2ua_lk_mon_fg[M2UA_MAX_LK_NUM]; +extern WORD m2ua_sg_mon_count; +extern WORD m2ua_lk_mon_count; + +extern DWORD err[64]; +extern BYTE init_flag; + +#endif diff --git a/plat/m2ua/src/include/m2ua_fsm.h b/plat/m2ua/src/include/m2ua_fsm.h new file mode 100644 index 0000000..23b92a8 --- /dev/null +++ b/plat/m2ua/src/include/m2ua_fsm.h @@ -0,0 +1,9 @@ +#ifndef _M2UA_FSM__H +#define _M2UA_FSM__H + +int m2ua_sg_fsm(WORD sg_id); +int m2ua_fsm(WORD sg_id); + +int rel_sid(WORD sg, BYTE lk); + +#endif diff --git a/plat/m2ua/src/include/m2ua_msg.h b/plat/m2ua/src/include/m2ua_msg.h new file mode 100644 index 0000000..8642173 --- /dev/null +++ b/plat/m2ua/src/include/m2ua_msg.h @@ -0,0 +1,59 @@ +#ifndef _M2UA_MSG__H +#define _M2UA_MSG__H + +#define COMBO_W(par_class,par_type) ((par_class << 8) + par_type) + +int m2ua_sctp_close(int fd, WORD sg_id); +int m2ua_dec_msg(WORD sg_id); +int m2ua_send_msg(WORD sg_id, WORD msg); + +int m2ua_sd_mtp3_primi(WORD lk, BYTE primi); +int m2ua_sd_mtp3_msg(WORD sg, WORD lk); + +int iua_sd_q931_primi(WORD lk, BYTE primi); +int iua_sd_q931_msg(WORD sg, WORD lk); + +int m3ua_sd_mtp3_user_primi(WORD lk, BYTE primi); +int m3ua_sd_mtp3_user_msg(WORD sg); +int m3ua_sd_mtp3_user_rc_cmd(WORD sg, BYTE primi); +int m3ua_sd_mtp3_user_ssnm_cmd(WORD sg, BYTE primi); + +int m2ua_sg_init(WORD id); +int m2ua_lk_init(WORD id); + + +int enable_sg(WORD sg); +int rm_sg_lk(WORD sg, WORD lk); + + +char *dec_sctp_primi(long sctp_primi); + +#ifndef _LKSCTP + +int m2ua_sctp_t_open(WORD sg); +int expect(int fd, int sg, int *msg, int want); + +int m2ua_sctp_optmgmt_req(int fd, int sg, ulong flags); +int m2ua_sctp_bind_req(int fd, int sg, m2ua_sctp_addr_t *addr, int coninds); +int m2ua_sctp_conn_res(int fd, int fd2, int sg, long seq); +int m2ua_sctp_ordrel_req(int fd, int sg); +int m2ua_sctp_discon_req(int fd, int sg, ulong seq); +int m2ua_sctp_conn_req(int fd, int sg, m2ua_sctp_addr_t *addr); +int m2ua_sctp_optdata_req(int fd, int sg, int len); + +#else + +int m2ua_sctp_optmgmt_req_lksctp(int fd, int sg); +int m2ua_sctp_optmgmt_req_lksctp_ext(int fd, int sg); +int m2ua_sctp_bind_req_lksctp(int fd, int sg, m2ua_sctp_addr_t *addr, int coninds); +int m2ua_sctp_open_lksctp(WORD sg); +int m2ua_sctp_conn_req_lksctp(int fd, int sg, m2ua_sctp_addr_t *addr); +int m2ua_sctp_get_msg_lksctp(int fd, WORD sg); +int expect_lksctp(int fd, int sg, int *msg, int want); +int m2ua_sctp_discon_req_lksctp(int fd, int sg, int flag); +int m2ua_sctp_put_msg_lksctp(int fd, int sg); +int m2ua_sctp_optdata_req_lksctp(int fd, int sg, int len); + +#endif + +#endif diff --git a/plat/m2ua/src/include/m2ua_pub.h b/plat/m2ua/src/include/m2ua_pub.h new file mode 100644 index 0000000..40dfc2b --- /dev/null +++ b/plat/m2ua/src/include/m2ua_pub.h @@ -0,0 +1,63 @@ +#ifndef _M2UA_PUB__H +#define _M2UA_PUB__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _LKSCTP +#include +#include +#include +#include +#else +#include +#endif + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned int DWORD; +#endif + +#endif diff --git a/plat/m2ua/src/include/m2ua_pub.h.bak b/plat/m2ua/src/include/m2ua_pub.h.bak new file mode 100644 index 0000000..03b19ee --- /dev/null +++ b/plat/m2ua/src/include/m2ua_pub.h.bak @@ -0,0 +1,63 @@ +#ifndef _M2UA_PUB__H +#define _M2UA_PUB__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _LKSCTP +#include +#include +#include +#include +#else +#include +#endif + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned int DWORD; +#endif + +#endif diff --git a/plat/m2ua/src/include/m2ua_struct.h b/plat/m2ua/src/include/m2ua_struct.h new file mode 100644 index 0000000..45cc0b6 --- /dev/null +++ b/plat/m2ua/src/include/m2ua_struct.h @@ -0,0 +1,260 @@ +#ifndef _M2UA_STRUCT__H +#define _M2UA_STRUCT__H + +#include "m2ua_const.h" + +#ifndef _LKSCTP + +typedef union _m2ua_sctp_cmd +{ + union T_primitives tpi; + BYTE cbuf[M2UA_SCTP_CMD_BUFSIZE]; +}m2ua_sctp_cmd_t; + +// Data Options +typedef struct _m2ua_sctp_opt_data +{ + struct t_opthdr sid_hdr __attribute__((packed)); + t_scalar_t sid_val __attribute__((packed)); +}m2ua_sctp_opt_data_t; + +// Connect Options +typedef struct _m2ua_sctp_opt_conn +{ + struct t_opthdr ist_hdr __attribute__((packed)); + t_scalar_t ist_val __attribute__((packed)); + struct t_opthdr ost_hdr __attribute__((packed)); + t_scalar_t ost_val __attribute__((packed)); +}m2ua_sctp_opt_conn_t; + +// Management Options +typedef struct _m2ua_sctp_opt_optm +{ + struct t_opthdr nod_hdr __attribute__((packed)); + t_scalar_t nod_val __attribute__((packed)); + struct t_opthdr crk_hdr __attribute__((packed)); + t_scalar_t crk_val __attribute__((packed)); + struct t_opthdr ppi_hdr __attribute__((packed)); + t_scalar_t ppi_val __attribute__((packed)); + struct t_opthdr sid_hdr __attribute__((packed)); + t_scalar_t sid_val __attribute__((packed)); + struct t_opthdr rcv_hdr __attribute__((packed)); + t_scalar_t rcv_val __attribute__((packed)); + struct t_opthdr ckl_hdr __attribute__((packed)); + t_scalar_t ckl_val __attribute__((packed)); + struct t_opthdr skd_hdr __attribute__((packed)); + t_scalar_t skd_val __attribute__((packed)); + struct t_opthdr prt_hdr __attribute__((packed)); + t_scalar_t prt_val __attribute__((packed)); + struct t_opthdr art_hdr __attribute__((packed)); + t_scalar_t art_val __attribute__((packed)); + struct t_opthdr irt_hdr __attribute__((packed)); + t_scalar_t irt_val __attribute__((packed)); + struct t_opthdr hbi_hdr __attribute__((packed)); + t_scalar_t hbi_val __attribute__((packed)); + struct t_opthdr rin_hdr __attribute__((packed)); + t_scalar_t rin_val __attribute__((packed)); + struct t_opthdr rmn_hdr __attribute__((packed)); + t_scalar_t rmn_val __attribute__((packed)); + struct t_opthdr rmx_hdr __attribute__((packed)); + t_scalar_t rmx_val __attribute__((packed)); + struct t_opthdr ist_hdr __attribute__((packed)); + t_scalar_t ist_val __attribute__((packed)); + struct t_opthdr ost_hdr __attribute__((packed)); + t_scalar_t ost_val __attribute__((packed)); + struct t_opthdr cin_hdr __attribute__((packed)); + t_scalar_t cin_val __attribute__((packed)); + struct t_opthdr tin_hdr __attribute__((packed)); + t_scalar_t tin_val __attribute__((packed)); + struct t_opthdr mac_hdr __attribute__((packed)); + t_scalar_t mac_val __attribute__((packed)); + struct t_opthdr dbg_hdr __attribute__((packed)); + t_scalar_t dbg_val __attribute__((packed)); +}m2ua_sctp_opt_optm_t; + +#else + +typedef union _m2ua_sctp_cmd +{ + struct cmsghdr cmsg __attribute__((packed)); + BYTE cbuf[M2UA_SCTP_CMD_BUFSIZE];// __attribute__((packed)); +}m2ua_sctp_cmd_t; + +typedef struct _m2ua_sctp_data +{ + int len __attribute__((packed)); + int sid __attribute__((packed)); + BYTE *buf __attribute__((packed)); +}m2ua_sctp_data_t; + +#endif + +typedef struct _m2ua_sctp_addr +{ + uint16_t port __attribute__((packed)); + struct in_addr addr __attribute__((packed)); +}m2ua_sctp_addr_t; + + +typedef struct _m2ua_lk_info +{ + BYTE enable;// __attribute__((packed)); + BYTE lk_st;// __attribute__((packed)); + WORD sid __attribute__((packed)); + DWORD lk_timer __attribute__((packed)); + BYTE alarm_code;// __attribute__((packed)); + BYTE lk_act;// __attribute__((packed)); +}m2ua_lk_info_t; + +typedef struct _m2ua_sg_info +{ + BYTE enable;// __attribute__((packed)); + BYTE sctp_state ;// __attribute__((packed)); + BYTE sctp_state_1;// __attribute__((packed)); + BYTE m2ua_state;// __attribute__((packed)); + DWORD sctp_cmd __attribute__((packed)); + WORD m2ua_cmd __attribute__((packed)); + WORD mtp3_cmd __attribute__((packed)); + WORD mgmt_cmd __attribute__((packed)); + WORD fd __attribute__((packed)); + WORD iid __attribute__((packed)); + DWORD sid_st[8] __attribute__((packed)); + BYTE *msg __attribute__((packed)); + WORD msg_len __attribute__((packed)); + WORD rem_ostrs __attribute__((packed)); + WORD T_ack __attribute__((packed)); + WORD T_r __attribute__((packed)); + BYTE con_sg;// __attribute__((packed)); + BYTE state;// __attribute__((packed)); + BYTE err_code;// __attribute__((packed)); + BYTE tra_hdl_mode;// __attribute__((packed)); + WORD act_lks __attribute__((packed)); + WORD istrs __attribute__((packed)); + WORD ostrs __attribute__((packed)); + DWORD status __attribute__((packed)); + DWORD seq __attribute__((packed)); + DWORD cor_id __attribute__((packed)); + WORD up_lks_pre __attribute__((packed)); + WORD up_lks_cur __attribute__((packed)); + DWORD sg_timer __attribute__((packed)); + BYTE retrans_times;// __attribute__((packed)); + WORD rem_port __attribute__((packed)); + BYTE alarm_code;// __attribute__((packed)); + //iua + BYTE rel_reason;// __attribute__((packed)); + BYTE tei_state;// __attribute__((packed)); + WORD dlci __attribute__((packed)); + //m3ua + DWORD dpc __attribute__((packed)); /*Routing Label*/ + DWORD opc __attribute__((packed)); + BYTE sls;// __attribute__((packed)); + BYTE mp;// __attribute__((packed)); + BYTE ni;// __attribute__((packed)); + BYTE si;// __attribute__((packed)); + + DWORD net_app __attribute__((packed));//Network_Appearance + DWORD rc __attribute__((packed));//Routing_Context + DWORD aff_pc __attribute__((packed));//xUA_Affected_PC + DWORD user_cause __attribute__((packed));//M3UA_User_Cause + DWORD cong_ind __attribute__((packed));//M3UA_Congestion_Indications + DWORD con_dpc __attribute__((packed));//M3UA_Concerned_Destination + DWORD asp_id __attribute__((packed));//ASP ID +}m2ua_sg_info_t; + +typedef struct _m2ua_comhdr +{ + BYTE version;// __attribute__((packed)); + BYTE spare;// __attribute__((packed)); + BYTE msg_class;// __attribute__((packed)); + BYTE msg_type;// __attribute__((packed)); + DWORD len __attribute__((packed)); +}m2ua_comhdr_t; + +typedef struct _m2ua_par_hdr +{ + WORD tag __attribute__((packed)); + WORD len __attribute__((packed)); +}m2ua_par_hdr_t; + +typedef struct _m2ua_var_par +{ + m2ua_par_hdr_t hdr;// __attribute__((packed)); + BYTE val[M2UA_MAX_MSG_LEN];// __attribute__((packed)); +}m2ua_var_par_t; + +typedef struct _m2ua_msg +{ + m2ua_comhdr_t comhdr;// __attribute__((packed)); + BYTE msg[M2UA_MAX_MSG_LEN];// __attribute__((packed)); +}m2ua_msg_t; + +typedef struct _sg_para +{ + BYTE enable;// __attribute__((packed)); + BYTE server;// __attribute__((packed)); + BYTE xUA_ack;// __attribute__((packed)); //BIT 1-7:xUA_type,0/1/2:M2UA/IUA/M3UA ,Bit 0: ACK + DWORD ip __attribute__((packed)); + DWORD source_ip; // client source ip, 0=getHostName, other=value + WORD source_port; // client source port, 0=Radom + WORD plat_port[2] __attribute__((packed)); +}sg_para_t; + +typedef struct _lk_para +{ + BYTE enable;// __attribute__((packed)); + WORD lk_sg __attribute__((packed)); + BYTE iid;// __attribute__((packed)); + WORD dlci __attribute__((packed)); +}lk_para_t; + +typedef struct _m2ua_para +{ + sg_para_t sg_para[M2UA_MAX_SG_NUM] __attribute__((packed)); + lk_para_t lk_para[M2UA_MAX_LK_NUM];// __attribute__((packed)); + BYTE cmd;// __attribute__((packed)); +}m2ua_para_t; + +typedef struct _m2ua_lk_pro +{ + WORD e1_to_linkset __attribute__((packed)); + BYTE e1_to_slc;// __attribute__((packed)); + ulong e1_to_mtp3 __attribute__((packed)); + BYTE e1_lk_type;// __attribute__((packed)); + WORD e1_to_sg __attribute__((packed)); + BYTE e1_to_iid;// __attribute__((packed)); + ulong remote_ip __attribute__((packed)); + BYTE inactive;// __attribute__((packed)); + BYTE inactive_tm;// __attribute__((packed)); + ulong e1_to_alterMTP3 __attribute__((packed)); + BYTE mtp3lite_apl_mode; + BYTE admin_state; + char title[16]; +}m2ua_lk_pro_t; + +typedef struct _m2ua_sg_csta +{ + DWORD timestamp __attribute__((packed)); + DWORD sg_out_msg __attribute__((packed)); + DWORD sg_in_msg __attribute__((packed)); + DWORD sg_out_bytes __attribute__((packed)); + DWORD sg_in_bytes __attribute__((packed)); + DWORD sg_asp_dn_times __attribute__((packed)); +}m2ua_sg_csta_t; + +typedef struct _m2ua_lk_csta +{ + DWORD timestamp __attribute__((packed)); + DWORD lk_out_msg __attribute__((packed)); + DWORD lk_in_msg __attribute__((packed)); + DWORD lk_out_bytes __attribute__((packed)); + DWORD lk_in_bytes __attribute__((packed)); + DWORD lk_dn_times __attribute__((packed)); +}m2ua_lk_csta_t; + +typedef struct _m2ua_csta +{ + m2ua_sg_csta_t sg_csta[M2UA_MAX_SG_NUM];// __attribute__((packed)); + m2ua_lk_csta_t lk_csta[M2UA_MAX_LK_NUM];// __attribute__((packed)); +}m2ua_csta_t; + +#endif diff --git a/plat/m2ua/src/include/sctp.h b/plat/m2ua/src/include/sctp.h new file mode 100644 index 0000000..fc618b7 --- /dev/null +++ b/plat/m2ua/src/include/sctp.h @@ -0,0 +1,655 @@ +/* SCTP kernel reference Implementation + * (C) Copyright IBM Corp. 2001, 2004 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * + * This file is part of the SCTP kernel reference Implementation + * + * This header represents the structures and constants needed to support + * the SCTP Extension to the Sockets API. + * + * The SCTP reference implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP reference implementation 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Written or modified by: + * La Monte H.P. Yarroll + * R. Stewart + * K. Morneau + * Q. Xie + * Karl Knutson + * Jon Grimm + * Daisy Chang + * Inaky Perez-Gonzalez + * Sridhar Samudrala + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + */ + +#ifndef __linux_sctp_h__ +#define __linux_sctp_h__ + +#include +#include +#include + +__BEGIN_DECLS + +typedef void * sctp_assoc_t; + +/* Socket option layer for SCTP */ +#ifndef SOL_SCTP +#define SOL_SCTP 132 +#endif + +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +/* 9. Preprocessor constants */ +#define HAVE_SCTP +#define HAVE_KERNEL_SCTP +#define HAVE_SCTP_MULTIBUF +#define HAVE_SCTP_NOCONNECT + +/* The following symbols come from the Sockets API Extensions for + * SCTP . + */ +enum sctp_optname { + SCTP_RTOINFO, +#define SCTP_RTOINFO SCTP_RTOINFO + SCTP_ASSOCINFO, +#define SCTP_ASSOCINFO SCTP_ASSOCINFO + SCTP_INITMSG, +#define SCTP_INITMSG SCTP_INITMSG + SCTP_NODELAY, /* Get/set nodelay option. */ +#define SCTP_NODELAY SCTP_NODELAY + SCTP_AUTOCLOSE, +#define SCTP_AUTOCLOSE SCTP_AUTOCLOSE + SCTP_SET_PEER_PRIMARY_ADDR, +#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR + SCTP_PRIMARY_ADDR, +#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR + SCTP_ADAPTION_LAYER, +#define SCTP_ADAPTION_LAYER SCTP_ADAPTION_LAYER + SCTP_DISABLE_FRAGMENTS, +#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS + SCTP_PEER_ADDR_PARAMS, +#define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS + SCTP_DEFAULT_SEND_PARAM, +#define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM + SCTP_EVENTS, +#define SCTP_EVENTS SCTP_EVENTS + SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */ +#define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR + SCTP_MAXSEG, /* Get/set maximum fragment. */ +#define SCTP_MAXSEG SCTP_MAXSEG + SCTP_STATUS, +#define SCTP_STATUS SCTP_STATUS + SCTP_GET_PEER_ADDR_INFO, +#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO + + /* Internal Socket Options. Some of the sctp library functions are + * implemented using these socket options. + */ + SCTP_SOCKOPT_BINDX_ADD = 100,/* BINDX requests for adding addresses. */ +#define SCTP_SOCKOPT_BINDX_ADD SCTP_SOCKOPT_BINDX_ADD + SCTP_SOCKOPT_BINDX_REM, /* BINDX requests for removing addresses. */ +#define SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_BINDX_REM + SCTP_SOCKOPT_PEELOFF, /* peel off association. */ +#define SCTP_SOCKOPT_PEELOFF SCTP_SOCKOPT_PEELOFF + SCTP_GET_PEER_ADDRS_NUM, /* Get number of peer addresss. */ +#define SCTP_GET_PEER_ADDRS_NUM SCTP_GET_PEER_ADDRS_NUM + SCTP_GET_PEER_ADDRS, /* Get all peer addresss. */ +#define SCTP_GET_PEER_ADDRS SCTP_GET_PEER_ADDRS + SCTP_GET_LOCAL_ADDRS_NUM, /* Get number of local addresss. */ +#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM + SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */ +#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS +}; + +/* + * 5.2.1 SCTP Initiation Structure (SCTP_INIT) + * + * This cmsghdr structure provides information for initializing new + * SCTP associations with sendmsg(). The SCTP_INITMSG socket option + * uses this same data structure. This structure is not used for + * recvmsg(). + * + * cmsg_level cmsg_type cmsg_data[] + * ------------ ------------ ---------------------- + * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg + * + */ +struct sctp_initmsg { + __u16 sinit_num_ostreams; + __u16 sinit_max_instreams; + __u16 sinit_max_attempts; + __u16 sinit_max_init_timeo; +}; + +/* + * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) + * + * This cmsghdr structure specifies SCTP options for sendmsg() and + * describes SCTP header information about a received message through + * recvmsg(). + * + * cmsg_level cmsg_type cmsg_data[] + * ------------ ------------ ---------------------- + * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo + * + */ +struct sctp_sndrcvinfo { + __u16 sinfo_stream; + __u16 sinfo_ssn; + __u16 sinfo_flags; + __u32 sinfo_ppid; + __u32 sinfo_context; + __u32 sinfo_timetolive; + __u32 sinfo_tsn; + __u32 sinfo_cumtsn; + sctp_assoc_t sinfo_assoc_id; +}; + +/* + * sinfo_flags: 16 bits (unsigned integer) + * + * This field may contain any of the following flags and is composed of + * a bitwise OR of these values. + */ + +enum sctp_sinfo_flags { + MSG_UNORDERED = 1, /* Send/receive message unordered. */ + MSG_ADDR_OVER = 2, /* Override the primary destination. */ + MSG_ABORT=4, /* Send an ABORT message to the peer. */ + MSG_EOF=MSG_FIN, /* Initiate graceful shutdown process. */ +}; + + +typedef union { + __u8 raw; + struct sctp_initmsg init; + struct sctp_sndrcvinfo sndrcv; +} sctp_cmsg_data_t; + +/* These are cmsg_types. */ +typedef enum sctp_cmsg_type { + SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */ + SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */ +} sctp_cmsg_t; + + +/* + * 5.3.1.1 SCTP_ASSOC_CHANGE + * + * Communication notifications inform the ULP that an SCTP association + * has either begun or ended. The identifier for a new association is + * provided by this notificaion. The notification information has the + * following format: + * + */ +struct sctp_assoc_change { + __u16 sac_type; + __u16 sac_flags; + __u32 sac_length; + __u16 sac_state; + __u16 sac_error; + __u16 sac_outbound_streams; + __u16 sac_inbound_streams; + sctp_assoc_t sac_assoc_id; +}; + +/* + * sac_state: 32 bits (signed integer) + * + * This field holds one of a number of values that communicate the + * event that happened to the association. They include: + * + * Note: The following state names deviate from the API draft as + * the names clash too easily with other kernel symbols. + */ +enum sctp_sac_state { + SCTP_COMM_UP, + SCTP_COMM_LOST, + SCTP_RESTART, + SCTP_SHUTDOWN_COMP, + SCTP_CANT_STR_ASSOC, +}; + +/* + * 5.3.1.2 SCTP_PEER_ADDR_CHANGE + * + * When a destination address on a multi-homed peer encounters a change + * an interface details event is sent. The information has the + * following structure: + */ +struct sctp_paddr_change { + __u16 spc_type; + __u16 spc_flags; + __u32 spc_length; + struct sockaddr_storage spc_aaddr; + int spc_state; + int spc_error; + sctp_assoc_t spc_assoc_id; +}; + +/* + * spc_state: 32 bits (signed integer) + * + * This field holds one of a number of values that communicate the + * event that happened to the address. They include: + */ +enum sctp_spc_state { + SCTP_ADDR_AVAILABLE, + SCTP_ADDR_UNREACHABLE, + SCTP_ADDR_REMOVED, + SCTP_ADDR_ADDED, + SCTP_ADDR_MADE_PRIM, +}; + + +/* + * 5.3.1.3 SCTP_REMOTE_ERROR + * + * A remote peer may send an Operational Error message to its peer. + * This message indicates a variety of error conditions on an + * association. The entire error TLV as it appears on the wire is + * included in a SCTP_REMOTE_ERROR event. Please refer to the SCTP + * specification [SCTP] and any extensions for a list of possible + * error formats. SCTP error TLVs have the format: + */ +struct sctp_remote_error { + __u16 sre_type; + __u16 sre_flags; + __u32 sre_length; + __u16 sre_error; + sctp_assoc_t sre_assoc_id; + __u8 sre_data[0]; +}; + + +/* + * 5.3.1.4 SCTP_SEND_FAILED + * + * If SCTP cannot deliver a message it may return the message as a + * notification. + */ +struct sctp_send_failed { + __u16 ssf_type; + __u16 ssf_flags; + __u32 ssf_length; + __u32 ssf_error; + struct sctp_sndrcvinfo ssf_info; + sctp_assoc_t ssf_assoc_id; + __u8 ssf_data[0]; +}; + +/* + * ssf_flags: 16 bits (unsigned integer) + * + * The flag value will take one of the following values + * + * SCTP_DATA_UNSENT - Indicates that the data was never put on + * the wire. + * + * SCTP_DATA_SENT - Indicates that the data was put on the wire. + * Note that this does not necessarily mean that the + * data was (or was not) successfully delivered. + */ +enum sctp_ssf_flags { + SCTP_DATA_UNSENT, + SCTP_DATA_SENT, +}; + +/* + * 5.3.1.5 SCTP_SHUTDOWN_EVENT + * + * When a peer sends a SHUTDOWN, SCTP delivers this notification to + * inform the application that it should cease sending data. + */ +struct sctp_shutdown_event { + __u16 sse_type; + __u16 sse_flags; + __u32 sse_length; + sctp_assoc_t sse_assoc_id; +}; + +/* + * 5.3.1.6 SCTP_ADAPTION_INDICATION + * + * When a peer sends a Adaption Layer Indication parameter , SCTP + * delivers this notification to inform the application + * that of the peers requested adaption layer. + */ +struct sctp_adaption_event { + __u16 sai_type; + __u16 sai_flags; + __u32 sai_length; + __u32 sai_adaption_ind; + sctp_assoc_t sai_assoc_id; +}; + +/* + * 5.3.1.7 SCTP_PARTIAL_DELIVERY_EVENT + * + * When a reciever is engaged in a partial delivery of a + * message this notification will be used to inidicate + * various events. + */ +struct sctp_pdapi_event { + __u16 pdapi_type; + __u16 pdapi_flags; + __u32 pdapi_length; + __u32 pdapi_indication; + sctp_assoc_t pdapi_assoc_id; +}; + +enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, }; + +/* + * Described in Section 7.3 + * Ancillary Data and Notification Interest Options + */ +struct sctp_event_subscribe { + __u8 sctp_data_io_event; + __u8 sctp_association_event; + __u8 sctp_address_event; + __u8 sctp_send_failure_event; + __u8 sctp_peer_error_event; + __u8 sctp_shutdown_event; + __u8 sctp_partial_delivery_event; + __u8 sctp_adaption_layer_event; +}; + +/* + * 5.3.1 SCTP Notification Structure + * + * The notification structure is defined as the union of all + * notification types. + * + */ +union sctp_notification { + struct { + __u16 sn_type; /* Notification type. */ + __u16 sn_flags; + __u32 sn_length; + } sn_header; + struct sctp_assoc_change sn_assoc_change; + struct sctp_paddr_change sn_paddr_change; + struct sctp_remote_error sn_remote_error; + struct sctp_send_failed sn_send_failed; + struct sctp_shutdown_event sn_shutdown_event; + struct sctp_adaption_event sn_adaption_event; + struct sctp_pdapi_event sn_pdapi_event; +}; + +/* Section 5.3.1 + * All standard values for sn_type flags are greater than 2^15. + * Values from 2^15 and down are reserved. + */ + +enum sctp_sn_type { + SCTP_SN_TYPE_BASE = (1<<15), + SCTP_ASSOC_CHANGE, + SCTP_PEER_ADDR_CHANGE, + SCTP_SEND_FAILED, + SCTP_REMOTE_ERROR, + SCTP_SHUTDOWN_EVENT, + SCTP_PARTIAL_DELIVERY_EVENT, + SCTP_ADAPTION_INDICATION, +}; + +/* Notification error codes used to fill up the error fields in some + * notifications. + * SCTP_PEER_ADDRESS_CHAGE : spc_error + * SCTP_ASSOC_CHANGE : sac_error + * These names should be potentially included in the draft 04 of the SCTP + * sockets API specification. + */ +typedef enum sctp_sn_error { + SCTP_FAILED_THRESHOLD, + SCTP_RECEIVED_SACK, + SCTP_HEARTBEAT_SUCCESS, + SCTP_RESPONSE_TO_USER_REQ, + SCTP_INTERNAL_ERROR, + SCTP_SHUTDOWN_GUARD_EXPIRES, + SCTP_PEER_FAULTY, +} sctp_sn_error_t; + +/* + * 7.1.1 Retransmission Timeout Parameters (SCTP_RTOINFO) + * + * The protocol parameters used to initialize and bound retransmission + * timeout (RTO) are tunable. See [SCTP] for more information on how + * these parameters are used in RTO calculation. + */ +struct sctp_rtoinfo { + sctp_assoc_t srto_assoc_id; + __u32 srto_initial; + __u32 srto_max; + __u32 srto_min; +}; + +/* + * 7.1.2 Association Parameters (SCTP_ASSOCINFO) + * + * This option is used to both examine and set various association and + * endpoint parameters. + */ +struct sctp_assocparams { + sctp_assoc_t sasoc_assoc_id; + __u16 sasoc_asocmaxrxt; + __u16 sasoc_number_peer_destinations; + __u32 sasoc_peer_rwnd; + __u32 sasoc_local_rwnd; + __u32 sasoc_cookie_life; +}; + +/* + * 7.1.9 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR) + * + * Requests that the peer mark the enclosed address as the association + * primary. The enclosed address must be one of the association's + * locally bound addresses. The following structure is used to make a + * set primary request: + */ +struct sctp_setpeerprim { + sctp_assoc_t sspp_assoc_id; + struct sockaddr_storage sspp_addr; +}; + +/* + * 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) + * + * Requests that the local SCTP stack use the enclosed peer address as + * the association primary. The enclosed address must be one of the + * association peer's addresses. The following structure is used to + * make a set peer primary request: + */ +struct sctp_prim { + sctp_assoc_t ssp_assoc_id; + struct sockaddr_storage ssp_addr; +}; + +/* + * 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER) + * + * Requests that the local endpoint set the specified Adaption Layer + * Indication parameter for all future INIT and INIT-ACK exchanges. + */ +struct sctp_setadaption { + __u32 ssb_adaption_ind; +}; + +/* + * 7.1.13 Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) + * + * Applications can enable or disable heartbeats for any peer address + * of an association, modify an address's heartbeat interval, force a + * heartbeat to be sent immediately, and adjust the address's maximum + * number of retransmissions sent before an address is considered + * unreachable. The following structure is used to access and modify an + * address's parameters: + */ +struct sctp_paddrparams { + sctp_assoc_t spp_assoc_id; + struct sockaddr_storage spp_address; + __u32 spp_hbinterval; + __u16 spp_pathmaxrxt; +}; + +/* + * 7.2.2 Peer Address Information + * + * Applications can retrieve information about a specific peer address + * of an association, including its reachability state, congestion + * window, and retransmission timer values. This information is + * read-only. The following structure is used to access this + * information: + */ +struct sctp_paddrinfo { + sctp_assoc_t spinfo_assoc_id; + struct sockaddr_storage spinfo_address; + __s32 spinfo_state; + __u32 spinfo_cwnd; + __u32 spinfo_srtt; + __u32 spinfo_rto; + __u32 spinfo_mtu; +}; + +/* Peer addresses's state. */ +enum sctp_spinfo_state { + SCTP_INACTIVE, + SCTP_ACTIVE, +}; + +/* + * 7.2.1 Association Status (SCTP_STATUS) + * + * Applications can retrieve current status information about an + * association, including association state, peer receiver window size, + * number of unacked data chunks, and number of data chunks pending + * receipt. This information is read-only. The following structure is + * used to access this information: + */ +struct sctp_status { + sctp_assoc_t sstat_assoc_id; + __s32 sstat_state; + __u32 sstat_rwnd; + __u16 sstat_unackdata; + __u16 sstat_penddata; + __u16 sstat_instrms; + __u16 sstat_outstrms; + __u32 sstat_fragmentation_point; + struct sctp_paddrinfo sstat_primary; +}; + +/* + * 8.3, 8.5 get all peer/local addresses on a socket + * This parameter struct is for getsockopt + */ +struct sctp_getaddrs { + sctp_assoc_t assoc_id; + int addr_num; + struct sockaddr *addrs; +}; + +/* These are bit fields for msghdr->msg_flags. See section 5.1. */ +/* On user space Linux, these live in as an enum. */ +enum sctp_msg_flags { + MSG_NOTIFICATION = 0x8000, +#define MSG_NOTIFICATION MSG_NOTIFICATION +}; + +/* + * 8.1 sctp_bindx() + * + * The flags parameter is formed from the bitwise OR of zero or more of the + * following currently defined flags: + */ +#define SCTP_BINDX_ADD_ADDR 0x01 +#define SCTP_BINDX_REM_ADDR 0x02 + +/* This is the structure that is passed as an argument(optval) to + * getsockopt(SCTP_SOCKOPT_PEELOFF). + */ +typedef struct { + sctp_assoc_t associd; + int sd; +} sctp_peeloff_arg_t; + + +int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags); + +int sctp_peeloff(int sd, sctp_assoc_t assoc_id); + +/* Prototype for the library function sctp_opt_info defined in + * API 7. Socket Options. + */ +int sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size); + +/* Get all peer address on a socket. This is a new SCTP API + * described in the section 8.3 of the Sockets API Extensions for SCTP. + * This is implemented using the getsockopt() interface. + */ +int sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **addrs); + +/* Frees all resources allocated by sctp_getpaddrs(). This is a new SCTP API + * described in the section 8.4 of the Sockets API Extensions for SCTP. + */ +int sctp_freepaddrs(struct sockaddr *addrs); + +/* Get all locally bound address on a socket. This is a new SCTP API + * described in the section 8.5 of the Sockets API Extensions for SCTP. + * This is implemented using the getsockopt() interface. + */ +int sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **addrs); + +/* Frees all resources allocated by sctp_getladdrs(). This is a new SCTP API + * described in the section 8.6 of the Sockets API Extensions for SCTP. + */ +int sctp_freeladdrs(struct sockaddr *addrs); + +/* This library function assists the user with the advanced features + * of SCTP. This is a new SCTP API described in the section 8.7 of the + * Sockets API Extensions for SCTP. This is implemented using the + * sendmsg() interface. + */ +int sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to, + socklen_t tolen, uint32_t ppid, uint32_t flags, + uint16_t stream_no, uint32_t timetolive, uint32_t context); + +/* This library function assists the user with the advanced features + * of SCTP. This is a new SCTP API described in the section 8.8 of the + * Sockets API Extensions for SCTP. This is implemented using the + * recvmsg() interface. + */ +int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from, + socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo, + int *msg_flags); + +__END_DECLS + +#endif /* __linux_sctp_h__ */ diff --git a/plat/m2ua/src/m2ua.c b/plat/m2ua/src/m2ua.c new file mode 100644 index 0000000..267f910 --- /dev/null +++ b/plat/m2ua/src/m2ua.c @@ -0,0 +1,486 @@ +/****************************************************************/ +/* M2UA Implementation Program */ +/* Version 10.0.3 */ +/* Designed By Ying Min */ +/* Last Update: 2006-2-14 */ +/****************************************************************/ + +#include "./include/m2ua_pub.h" +#include "./include/m2ua.h" +#include "./include/m2ua_const.h" +#include "./include/m2ua_def.h" +#include "./include/m2ua_struct.h" +#include "./include/m2ua_msg.h" +#include "./include/m2ua_fsm.h" +#include "./include/m2ua_debug.h" + +// fix multiple definition========================= +const BYTE m2ua_ver[3] = {10, 0, 6}; +BYTE m2ua_command = 0; + +m2ua_sg_info_t m2ua_sg_info[M2UA_MAX_SG_FSM_NUM]; +m2ua_lk_info_t m2ua_lk_info[M2UA_MAX_LK_NUM]; + +m2ua_sctp_addr_t m2ua_sctp_addr; + +m2ua_sctp_cmd_t m2ua_sctp_cmd; +BYTE m2ua_sctp_dat[M2UA_SCTP_DAT_BUFSIZE]; //receive +BYTE m2ua_sctp_dat_send[M2UA_SCTP_DAT_BUFSIZE]; //send +int m2ua_sctp_cmd_len; +int m2ua_sctp_dat_len; + +#ifndef _LKSCTP +struct strbuf m2ua_sctp_ctrl = {M2UA_SCTP_CMD_BUFSIZE, 0, m2ua_sctp_cmd.cbuf}; +struct strbuf m2ua_sctp_data = {M2UA_SCTP_DAT_BUFSIZE, 0, m2ua_sctp_dat}; +#else +m2ua_sctp_data_t m2ua_sctp_data = {M2UA_SCTP_DAT_BUFSIZE, 0, m2ua_sctp_dat}; +#endif + +m2ua_para_t m2ua_para; + +BYTE m2ua_mtp3_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +WORD m2ua_mtp3_sd_h; +WORD m2ua_mtp3_sd_t; + +BYTE m3ua_mtp3_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +WORD m3ua_mtp3_sd_h; +WORD m3ua_mtp3_sd_t; + +BYTE iua_q931_sd[M2UA_MAX_MSG_LEN * M2UA_MAX_M3MSG_NUM]; +WORD iua_q931_sd_h; +WORD iua_q931_sd_t; + + + +DWORD x256[M2UA_MAX_M3MSG_NUM]; + +char hostip[20]; +char hostname[50]; +ulong host_ip; +BYTE plat_id; + +m2ua_sctp_addr_t m2ua_sctp_server_addr; +m2ua_csta_t m2ua_csta; + +char m2ua_asciin_buf[MAX_ASCIIIN_LEN]; +char m2ua_asciout_buf[MAX_ASCIIOUT_LEN]; +char m2ua_ascitemp_buf[MAX_ASCITMP_LEN]; +WORD moniter_fg; + +BYTE m2ua_sg_mon_fg[M2UA_MAX_SG_FSM_NUM]; +BYTE m2ua_lk_mon_fg[M2UA_MAX_LK_NUM]; +WORD m2ua_sg_mon_count; +WORD m2ua_lk_mon_count; + +DWORD err[64]; +BYTE init_flag; +//============================================== + +extern DWORD GetLocalIP(); +extern int m2ua_read_param(); +int m2ua_get_local_ip(void) +{ + host_ip = GetLocalIP(); + return 0; + /* + struct hostent *host; + + if (gethostname(hostname, 50) == -1) + { + printf("M2UA gethostname fail!\n"); + exit(3); + } + + if ((host = gethostbyname(hostname)) == NULL) + { + printf("M2UA gethostbyname fail!\n"); + exit(4); + } + else + { + sprintf(hostip, "%d.%d.%d.%d", + (BYTE)host->h_addr_list[0][0], + (BYTE)host->h_addr_list[0][1], + (BYTE)host->h_addr_list[0][2], + (BYTE)host->h_addr_list[0][3]); + host_ip = inet_addr(hostip); // Network byte order host_ip, like 0xE60012AC + printf("hostip: %s (0x%lX)\n", hostip, host_ip); + } + + return 0; + */ +} + +/* +int m2ua_get_mtp3_para(void) +{ + DWORD oid[20] = {1,3,6,1,4,1,1373,1,3,2,2,2,2,9,1}; // SG Attributes + BYTE msg[64], vartype; + int i; + + printf("M2UA start to get MTP3 link_para!\n"); + + for (i = 0; i < M2UA_MAX_SG_NUM; i++) + { + oid[15] = i; + if (get_response(16, oid, msg, &vartype) < 0) + { + printf("M2UA get MTP3 sg_para failed, please set it from MTP3!\n"); + return -1; + } + else + set_m2ua_sg(i, msg); + } + + oid[14] = 5; // Link Attributes + for (i = 0; i < M2UA_MAX_LK_NUM; i++) + { + oid[15] = i; + if (get_response(16, oid, msg, &vartype) < 0) + { + printf("M2UA get MTP3 link_para failed, please set it from MTP3!\n"); + return -1; + } + else + set_m2ua_link(i, msg); + } + + return 0; +} +*/ + + +void m2ua_init(BYTE system_id) +{ + int id, fd; + //static DWORD init_times = 0; + + + plat_id = system_id%2; + + printf("M2UA Init Start, plat_id=%d!\n", plat_id); + + m2ua_get_local_ip(); + + for (id = 0; id < M2UA_MAX_SG_FSM_NUM; id++) + { + m2ua_sg_init(id); + m2ua_sg_mon_fg[id] = 0; + } + m2ua_sg_mon_count = 0; + +#ifndef _LKSCTP + if ((fd = m2ua_sctp_t_open(M2UA_LISTEN_SG_NUM_0)) <= 0) + { + printf("M2UA_LISTEN_SG_NUM_0 sctp_t open failure!\n"); + exit(2); + } +#else + if ((fd = m2ua_sctp_open_lksctp(M2UA_LISTEN_SG_NUM_0)) <= 0) + { + printf("M2UA_LISTEN_SG_NUM_0 lksctp open failure!\n"); + exit(2); + } +#endif + else + { + m2ua_sg_info[M2UA_LISTEN_SG_NUM_0].fd = fd; + m2ua_sg_info[M2UA_LISTEN_SG_NUM_0].enable = 1; + printf("M2UA_LISTEN_SG_NUM_0 listening fd open succeed!\n"); + } +#ifndef _LKSCTP + if ((fd = m2ua_sctp_t_open(M2UA_LISTEN_SG_NUM_1)) <= 0) + { + printf("M2UA_LISTEN_SG_NUM_1 sctp_t open failure!\n"); + exit(2); + } +#else + if ((fd = m2ua_sctp_open_lksctp(M2UA_LISTEN_SG_NUM_1)) <= 0) + { + printf("M2UA_LISTEN_SG_NUM_1 lksctp open failure!\n"); + exit(2); + } +#endif + else + { + m2ua_sg_info[M2UA_LISTEN_SG_NUM_1].fd = fd; + m2ua_sg_info[M2UA_LISTEN_SG_NUM_1].enable = 1; + printf("M2UA_LISTEN_SG_NUM_1 listening fd open succeed!\n"); + } + +#ifndef _LKSCTP + if ((fd = m2ua_sctp_t_open(IUA_LISTEN_SG_NUM_0)) <= 0) + { + printf("IUA_LISTEN_SG_NUM_0 sctp_t open failure!\n"); + exit(2); + } +#else + if ((fd = m2ua_sctp_open_lksctp(IUA_LISTEN_SG_NUM_0)) <= 0) + { + printf("IUA_LISTEN_SG_NUM_0 lksctp open failure!\n"); + exit(2); + } +#endif + else + { + m2ua_sg_info[IUA_LISTEN_SG_NUM_0].fd = fd; + m2ua_sg_info[IUA_LISTEN_SG_NUM_0].enable = 1; + printf("IUA_LISTEN_SG_NUM_0 listening fd open succeed!\n"); + } +#ifndef _LKSCTP + if ((fd = m2ua_sctp_t_open(IUA_LISTEN_SG_NUM_1)) <= 0) + { + printf("IUA_LISTEN_SG_NUM_1 sctp_t open failure!\n"); + exit(2); + } +#else + if ((fd = m2ua_sctp_open_lksctp(IUA_LISTEN_SG_NUM_1)) <= 0) + { + printf("IUA_LISTEN_SG_NUM_1 lksctp open failure!\n"); + exit(2); + } +#endif + else + { + m2ua_sg_info[IUA_LISTEN_SG_NUM_1].fd = fd; + m2ua_sg_info[IUA_LISTEN_SG_NUM_1].enable = 1; + printf("IUA_LISTEN_SG_NUM_1 listening fd open succeed!\n"); + } + +#ifndef _LKSCTP + if ((fd = m2ua_sctp_t_open(M3UA_LISTEN_SG_NUM_0)) <= 0) + { + printf("M3UA_LISTEN_SG_NUM_0 sctp_t open failure!\n"); + exit(2); + } +#else + if ((fd = m2ua_sctp_open_lksctp(M3UA_LISTEN_SG_NUM_0)) <= 0) + { + printf("M3UA_LISTEN_SG_NUM_0 lksctp open failure!\n"); + exit(2); + } +#endif + else + { + m2ua_sg_info[M3UA_LISTEN_SG_NUM_0].fd = fd; + m2ua_sg_info[M3UA_LISTEN_SG_NUM_0].enable = 1; + printf("M3UA_LISTEN_SG_NUM_0 listening fd open succeed!\n"); + } +#ifndef _LKSCTP + if ((fd = m2ua_sctp_t_open(M3UA_LISTEN_SG_NUM_1)) <= 0) + { + printf("M3UA_LISTEN_SG_NUM_1 sctp_t open failure!\n"); + exit(2); + } +#else + if ((fd = m2ua_sctp_open_lksctp(M3UA_LISTEN_SG_NUM_1)) <= 0) + { + printf("M3UA_LISTEN_SG_NUM_1 lksctp open failure!\n"); + exit(2); + } +#endif + else + { + m2ua_sg_info[M3UA_LISTEN_SG_NUM_1].fd = fd; + m2ua_sg_info[M3UA_LISTEN_SG_NUM_1].enable = 1; + printf("M3UA_LISTEN_SG_NUM_1 listening fd open succeed!\n"); + } + + + for (id = 0; id < M2UA_MAX_LK_NUM; id++) + { + m2ua_lk_init(id); + m2ua_lk_mon_fg[id] = 0; + } + m2ua_lk_mon_count = 0; + + for (id = 0; id < M2UA_MAX_M3MSG_NUM; id++) + x256[id] = M2UA_MAX_MSG_LEN * id; + + bzero(&m2ua_csta, sizeof(m2ua_csta_t)); + bzero(err, 256); + + m2ua_mtp3_sd_h = 0; + m2ua_mtp3_sd_t = 0; + + iua_q931_sd_h = 0; + iua_q931_sd_t = 0; + + m3ua_mtp3_sd_h = 0; + m3ua_mtp3_sd_t = 0; + + + m2ua_sctp_cmd_len = 0; + m2ua_sctp_dat_len = 0; + + m2ua_sctp_addr.port = htons(2904); + m2ua_sctp_server_addr.port = htons(2904); + //inet_aton(hostip, &m2ua_sctp_addr.addr); + + strcpy(m2ua_asciin_buf, "\0"); + strcpy(m2ua_asciout_buf, "\0"); + moniter_fg = MONITOR_NONE; + m2ua_debug_set(); + + init_flag = 0; + m2ua_command = M2UA_CMD_IDLE; + //if (init_times++); + //m2ua_get_mtp3_para(); + + m2ua_read_param(); + + printf("M2UA Init Complete!\n"); +} + +void m2ua_t10ms() +{ + static int cnt_10ms = 0; + static int ls_hb_flag = 0; + static int ls_hb_lk = 0; + WORD nsg; + WORD i, fd; + + if (ls_hb_flag) + { + if (ls_hb_lk < M2UA_MAX_LK_NUM) + { + if (m2ua_para.lk_para[ls_hb_lk].enable == 1) + { + nsg = m2ua_para.lk_para[ls_hb_lk].lk_sg; + if ((m2ua_para.sg_para[nsg].xUA_ack>>1) == M2UA_APP) + m2ua_sd_mtp3_primi(ls_hb_lk, m2ua_lk_info[ls_hb_lk].lk_st); + else if ((m2ua_para.sg_para[nsg].xUA_ack>>1) == IUA_APP) + iua_sd_q931_primi(ls_hb_lk, m2ua_lk_info[ls_hb_lk].lk_st); + else if ((m2ua_para.sg_para[nsg].xUA_ack>>1) == M3UA_APP) + m3ua_sd_mtp3_user_primi(ls_hb_lk, m2ua_lk_info[ls_hb_lk].lk_st); + } + ls_hb_lk++; + } + else + { + ls_hb_flag = 0; + ls_hb_lk = 0; + } + } + + if (!(++cnt_10ms % 10)) + { // 100 ms + m2ua_mon(); + + if (!(cnt_10ms % 100)) + { // 1 seconds + if (m2ua_command != M2UA_CMD_IDLE) + { + sprintf(m2ua_ascitemp_buf, "M2UA Restart! m2ua_command=%d\n\r", m2ua_command); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + + m2ua_command = M2UA_CMD_IDLE; + + for (i = 0; i < M2UA_MAX_SG_FSM_NUM; i++) + { + if ((fd = m2ua_sg_info[i].fd) > 0) + { + if ((m2ua_sg_info[i].sctp_state > 2) || + ((m2ua_sg_info[i].sctp_state == 2) && + (m2ua_sg_info[i].sctp_state_1 > 0))) + { +#ifndef _LKSCTP + if (i >= M2UA_MAX_SG_NUM) + m2ua_sctp_discon_req(fd, i, m2ua_sg_info[i].seq); + else + m2ua_sctp_discon_req(fd, i, 0); +#else + m2ua_sctp_discon_req_lksctp(fd, i, 0); +#endif + } +#ifndef _LKSCTP + m2ua_sctp_close(m2ua_sg_info[i].fd, i); +#endif + } + } + + m2ua_init(plat_id); + } + else if (cnt_10ms >= 1500) + { // 15 seconds + cnt_10ms = 0; + ls_hb_flag = 1; + } + } + } +} + +// Called every 10 ms +void m2ua_timer(void) +{ + WORD sg, sg_dual, i; + static BYTE sg_start = 0; + static BYTE lk_scan = 0; + + for (sg = sg_start; sg < sg_start + 128; sg++) + { + sg_dual = sg; + if (m2ua_sg_info[sg_dual].m2ua_state == 3) + { + for (i = 0; i < 32; i++) + { + if (m2ua_sg_fsm(sg_dual) < 0) + break; + } + } + else + m2ua_sg_fsm(sg_dual); + + sg_dual = sg + M2UA_MAX_SG_NUM/2; + + if (m2ua_sg_info[sg_dual].m2ua_state == 3) + { + for (i = 0; i < 32; i++) + { + if (m2ua_sg_fsm(sg_dual) < 0) + break; + } + } + else + m2ua_sg_fsm(sg_dual); + } + sg_start += 128; + + if (sg_start == 0) + { + m2ua_sg_fsm(M2UA_LISTEN_SG_NUM_0); + m2ua_sg_fsm(M2UA_LISTEN_SG_NUM_1); + m2ua_sg_fsm(IUA_LISTEN_SG_NUM_0); + m2ua_sg_fsm(IUA_LISTEN_SG_NUM_1); + m2ua_sg_fsm(M3UA_LISTEN_SG_NUM_0); + m2ua_sg_fsm(M3UA_LISTEN_SG_NUM_1); + } + + if (m2ua_lk_info[lk_scan].lk_timer > 0) + m2ua_lk_info[lk_scan].lk_timer--; + if (m2ua_lk_info[lk_scan+256].lk_timer > 0) + m2ua_lk_info[lk_scan+256].lk_timer--; + if (m2ua_lk_info[lk_scan+256*2].lk_timer > 0) + m2ua_lk_info[lk_scan+256*2].lk_timer--; + if (m2ua_lk_info[lk_scan+256*3].lk_timer > 0) + m2ua_lk_info[lk_scan+256*3].lk_timer--; + lk_scan ++; + + m2ua_t10ms(); +} + +int m2ua_restart() +{ + if (m2ua_command != M2UA_CMD_IDLE) + return 0; + else if (init_flag == 2) + { + m2ua_command = M2UA_CMD_STATUS_INIT; + return 0; + } + + return 1; +} + + diff --git a/plat/m2ua/src/m2ua_debug.c b/plat/m2ua/src/m2ua_debug.c new file mode 100644 index 0000000..a6823d2 --- /dev/null +++ b/plat/m2ua/src/m2ua_debug.c @@ -0,0 +1,537 @@ +#include "./include/m2ua_pub.h" +#include "./include/m2ua.h" +#include "./include/m2ua_const.h" +#include "./include/m2ua_struct.h" +#include "./include/m2ua_ext.h" +#include "../../debug/src/include/debug.h" + +#define M2UA_DEBUG_ID 16 +#define M2UA_VER_DEBUG "V1.0.01" +#define M2UA_PATCH 2 + +extern int m2ua_set_traffic_mode_type(int flag); +extern int set_asp_id_order(BYTE flag); + +static char ascii[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}; + +static BYTE log_help[] = { +"M2UA Debug Monitor Help:\n\r\ +\n\r\ +1.[help] display help menu\n\r\ +2.[log all/none] display all/none logs\n\r\ +3.[log error on/off] display error logs (sg only)\n\r\ +4.[log mtp3/maup on/off] display mtp3/maup logs (sg or link)\n\r\ +5.[log m2ua/sctp on/off] display m2ua/sctp logs (sg only)\n\r\ +6.[log sg-xxx/lk-xxx on/off] display sg/lk logs\n\r\n\r" +}; + +static WORD disp_page[10]; +static BYTE *disp_ptr = (BYTE *) disp_page; + +static DWORD debug_status_id[20] = + {1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,1}; + +static BYTE debug_status = 1; + +static DWORD debug_name_id[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,2 + }; + +static DWORD debug_ascin_id[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,3 + }; + +static DWORD debug_ascout_id[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,4 + }; + +static DWORD debug_page_title[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,1,1 + }; + +static DWORD debug_page_line[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,1,2,1 + }; + +const static BYTE PAGE_POINT = 14; +const static BYTE LINE_POINT = 15; +const static BYTE BASE_ID_LEN = 15; + +static BYTE title1_p[] = +{ + " M2UA Page 01 SG Para\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +Subpage\n\r\ +SG_Para\n\r" +}; + +static BYTE title2_p[] = +{ + " M2UA Page 02 Link Para\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +Subpage\n\r\ +LK_Para\n\r" +}; + +static BYTE title3_p[] = +{ + " M2UA Page 03 SG Info\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +Subpage\n\r\ +SG_Info\n\r" +}; + +static BYTE title4_p[] = +{ + " M2UA Page 04 Link Info\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +LK_Info\n\r" +}; + +static BYTE title5_p[] = +{ + " M2UA Page 05 SG CSTA\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +Subpage\n\r\ +SG_CSTA\n\r" +}; + +static BYTE title6_p[] = +{ + " M2UA Page 06 Link CSTA\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +LK_CSTA\n\r" +}; + +static BYTE title7_p[] = +{ + " M2UA Page 07 Watchdog\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +Watchdog\n\r" +}; + +BYTE m2ua_disp_line(BYTE page, BYTE line) +{ + BYTE disp_length; + + disp_length = 16; + disp_ptr = (BYTE *) disp_page; + + switch (page) + { + case 1: // Page 1: SG Para + if (line == 0) + { + disp_ptr = (BYTE *) &disp_page[page]; + disp_length = 2; + } + else if (line < 17) + { + disp_ptr = (BYTE *) m2ua_para.sg_para + ((line - 1) * sizeof(sg_para_t)) + (disp_page[page] * 16 * sizeof(sg_para_t)); + disp_length = sizeof(sg_para_t); + } + else + disp_length = 0; + break; + case 2: // Page 2: LK Para + if (line == 0) + { + disp_ptr = (BYTE *) &disp_page[page]; + disp_length = 2; + } + else if (line < 17) + { + disp_ptr = (BYTE *) m2ua_para.lk_para + ((line - 1) * sizeof(lk_para_t)) + disp_page[page] * 16 * sizeof(lk_para_t); + disp_length = sizeof(lk_para_t); + } + else + disp_length = 0; + break; + case 3: // Page 3: SG Info + if (line == 0) + { + disp_ptr = (BYTE *) &disp_page[page]; + disp_length = 2; + } + else if (line < 7) + disp_ptr = (BYTE *) &m2ua_sg_info[disp_page[page]] + ((line - 1) * 16); + else + disp_length = 0; + break; + case 4: // Page 4: LK Info + if (line == 0) + { + disp_ptr = (BYTE *) &disp_page[page]; + disp_length = 2; + } + else if (line < 17) + { + disp_ptr = (BYTE *) m2ua_lk_info + ((line - 1) * sizeof(m2ua_lk_info_t)) + disp_page[page] * 16 * sizeof(m2ua_lk_info_t); + disp_length = sizeof(m2ua_lk_info_t); + } + else + disp_length = 0; + break; + case 5: // Page 5: SG CSTA + if (line == 0) + { + disp_ptr = (BYTE *) &disp_page[page]; + disp_length = 2; + } + else if (line < 3) + disp_ptr = (BYTE *) &m2ua_csta.sg_csta[disp_page[page]] + ((line - 1) * 16); + else + disp_length = 0; + break; + case 6: // Page 6: LK CSTA + if (line == 0) + { + disp_ptr = (BYTE *) &disp_page[page]; + disp_length = 2; + } + else if (line < 3) + disp_ptr = (BYTE *) &m2ua_csta.lk_csta[disp_page[page]] + ((line - 1) * 16); + else + disp_length = 0; + break; + case 7: // Page 7: Err + if (line < 16) + disp_ptr = (BYTE *)err + (line * 16); + else + disp_length = 0; + break; + default: + disp_length = 0; + break; + } + + return disp_length; +} + +void m2ua_disp_page(BYTE page) +{ + BYTE disp_line; + BYTE disp_length; + + debug_page_line[PAGE_POINT] = page + 5; + + for (disp_line = 0; disp_line < 22; disp_line++) + { + disp_length = m2ua_disp_line(page, disp_line); + debug_page_line[LINE_POINT] = disp_line + 2; + debug_page_line[LINE_POINT + 1] = 2; // Data Pointer + debug_set_response(BASE_ID_LEN + 2, debug_page_line, disp_ptr, disp_length); + } +} + +int m2ua_debug_set(void) +{ + BYTE page; + BYTE data[10]; + BYTE *ptr; + + bzero(disp_page, 20); + ptr = data; + + debug_set_response(BASE_ID_LEN, debug_status_id, &debug_status, 1); + debug_set_response(BASE_ID_LEN, debug_name_id, (BYTE *)M2UA_VER_DEBUG, 10); + debug_set_response(BASE_ID_LEN, debug_ascin_id, (BYTE *)m2ua_asciin_buf, 4096); + debug_set_response(BASE_ID_LEN, debug_ascout_id, (BYTE *)m2ua_asciout_buf, 4096); + + for (page = 1; page < 8; page++) + { + switch (page) + { + case 1: //page 1 + ptr = title1_p; + break; + case 2: //page 2 + ptr = title2_p; + break; + case 3: //page 3 + ptr = title3_p; + break; + case 4: //page 4 + ptr = title4_p; + break; + case 5: //page 5 + ptr = title5_p; + break; + case 6: //page 6 + ptr = title6_p; + break; + case 7: //page 7 + ptr = title7_p; + break; + default: + break; + } + + debug_page_title[PAGE_POINT] = 5 + page; + debug_set_response(BASE_ID_LEN + 1, debug_page_title, ptr, strlen((char *)ptr)); + m2ua_disp_page(page); + } + + return 1; +} + +int m2ua_asciout_proc(char *out_str) +{ + int out_len; + + out_len = strlen(out_str); + + if (out_len + strlen(m2ua_asciout_buf) > MAX_ASCIIOUT_LEN - 2) + { + strcpy(m2ua_asciout_buf, out_str); + } + else + strcat(m2ua_asciout_buf, out_str); + + return 1; +} + +void m2ua_mon(void) +{ + BYTE in_page, err_fg = 0; + char *ascii_in_ptr = NULL; + char *str_start = NULL; + WORD str_len, num; + + if ((str_len = strlen(m2ua_asciin_buf)) > 0) + { + in_page = (BYTE)m2ua_asciin_buf[0] - 1; + ascii_in_ptr = m2ua_asciin_buf + 1; + + if (in_page > 7) + err_fg = 1; + else if (strcmp(ascii_in_ptr,"c") == 0) + { + bzero(&m2ua_csta, sizeof(m2ua_csta_t)); + bzero(err, 256); + } + else if (strcmp(ascii_in_ptr,"log mtp3 on") == 0) + { + moniter_fg = moniter_fg | MONITOR_MTP3; + } + else if (strcmp(ascii_in_ptr,"log mtp3 off") == 0) + { + moniter_fg = moniter_fg & (~MONITOR_MTP3); + } + else if (strcmp(ascii_in_ptr,"log m2ua on") == 0) + { + moniter_fg = moniter_fg | MONITOR_M2UA; + } + else if (strcmp(ascii_in_ptr,"log m2ua off") == 0) + { + moniter_fg = moniter_fg & (~MONITOR_M2UA); + } + else if (strcmp(ascii_in_ptr,"log maup on") == 0) + { + moniter_fg = moniter_fg | MONITOR_MAUP; + } + else if (strcmp(ascii_in_ptr,"log maup off") == 0) + { + moniter_fg = moniter_fg & (~MONITOR_MAUP); + } + else if (strcmp(ascii_in_ptr,"log sctp on") == 0) + { + moniter_fg = moniter_fg | MONITOR_SCTP; + } + else if (strcmp(ascii_in_ptr,"log sctp off") == 0) + { + moniter_fg = moniter_fg & (~MONITOR_SCTP); + } + else if (strcmp(ascii_in_ptr,"log error on") == 0) + { + moniter_fg = moniter_fg | MONITOR_ERROR; + } + else if (strcmp(ascii_in_ptr,"log error off") == 0) + { + moniter_fg = moniter_fg & (~MONITOR_ERROR); + } + else if (strcmp(ascii_in_ptr,"log all") == 0) + { + moniter_fg = MONITOR_ALL; + if (!m2ua_sg_mon_count && !m2ua_lk_mon_count) + { + memset(m2ua_sg_mon_fg, 1, M2UA_MAX_SG_FSM_NUM); + memset(m2ua_lk_mon_fg, 1, M2UA_MAX_LK_NUM); + } + else + err_fg = 2; + } + else if (strcmp(ascii_in_ptr,"log none") == 0) + { + moniter_fg = MONITOR_NONE; + memset(m2ua_sg_mon_fg, 0, M2UA_MAX_SG_FSM_NUM); + memset(m2ua_lk_mon_fg, 0, M2UA_MAX_LK_NUM); + m2ua_sg_mon_count = 0; + m2ua_lk_mon_count = 0; + } + else if (strcmp(ascii_in_ptr,"help") == 0) + { + m2ua_asciout_proc((char *)log_help); + sprintf(m2ua_ascitemp_buf, "Ver.%s T%03d\r\n",M2UA_VER_DEBUG,M2UA_PATCH); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + else if (strstr(ascii_in_ptr, "log sg") != NULL) + { + if ((moniter_fg == MONITOR_ALL) && + !m2ua_sg_mon_count && + !m2ua_lk_mon_count) + err_fg = 3; + else if ((str_start = strstr(ascii_in_ptr, "-")) != NULL) + { + num = strtoul(str_start + 1, NULL, 10); + if (num >= M2UA_MAX_SG_FSM_NUM) + err_fg = 1; + else if (strstr(ascii_in_ptr, "on") != NULL) + { + m2ua_sg_mon_fg[num] = 1; + if (m2ua_sg_mon_count < M2UA_MAX_SG_NUM+2) + m2ua_sg_mon_count++; + } + else if (strstr(ascii_in_ptr, "off") != NULL) + { + m2ua_sg_mon_fg[num] = 0; + if (m2ua_sg_mon_count > 0) + m2ua_sg_mon_count--; + } + else + err_fg = 1; + } + else + err_fg = 1; + } + else if (strcmp(ascii_in_ptr,"tmt=override") == 0) + { + m2ua_set_traffic_mode_type(0); + } + else if (strcmp(ascii_in_ptr,"tmt=loadshare") == 0) + { + m2ua_set_traffic_mode_type(1); + } + else if (strcmp(ascii_in_ptr,"asp id order0") == 0) + { + set_asp_id_order(0); + } + else if (strcmp(ascii_in_ptr,"asp id order1") == 0) + { + set_asp_id_order(1); + } + else if (strstr(ascii_in_ptr, "log lk") != NULL) + { + if ((moniter_fg == MONITOR_ALL) && + !m2ua_sg_mon_count && + !m2ua_lk_mon_count) + err_fg = 3; + else if ((str_start = strstr(ascii_in_ptr, "-")) != NULL) + { + num = strtoul(str_start + 1, NULL, 10); + if (num >= M2UA_MAX_LK_NUM) + err_fg = 1; + else if (strstr(ascii_in_ptr, "on") != NULL) + { + m2ua_lk_mon_fg[num] = 1; + if (m2ua_lk_mon_count < M2UA_MAX_LK_NUM) + m2ua_lk_mon_count++; + } + else if (strstr(ascii_in_ptr, "off") != NULL) + { + m2ua_lk_mon_fg[num] = 0; + if (m2ua_lk_mon_count > 0) + m2ua_lk_mon_count--; + } + else + err_fg = 1; + } + else + err_fg = 1; + } + else if (isdigit(ascii_in_ptr[0])) + { + num = strtoul(ascii_in_ptr, NULL, 10); + disp_page[in_page] = num; + m2ua_disp_page(in_page); + } + else if ((str_start = strstr(ascii_in_ptr, ">")) != NULL) + { + num = strtoul(str_start + 1, NULL, 10); + disp_page[in_page] += num; + m2ua_disp_page(in_page); + } + else if ((str_start = strstr(ascii_in_ptr, "<"))!= NULL) + { + num = strtoul(str_start + 1, NULL, 10); + disp_page[in_page] -= num; + m2ua_disp_page(in_page); + } + else + err_fg = 1; + + if (err_fg == 0) + m2ua_asciout_proc("Command OK!\n\r"); + else if (err_fg == 2) + m2ua_asciout_proc("Log all for some SGs or Links!\n\r"); + else if (err_fg == 3) + m2ua_asciout_proc("Log all already done for all SGs and Links, log none to clear!\n\r"); + else + m2ua_asciout_proc("Command Error!\n\r"); + + strcpy(m2ua_asciin_buf, "\0"); + } +} + +int m2ua_hex_to_ascii(BYTE *from_hex, WORD from_len, BYTE *to_asc) +{ + int i, j; + + j = 0; + if(from_len*3 > MAX_ASCITMP_LEN) + { + m2ua_asciout_proc("\33[31m"); + sprintf(m2ua_ascitemp_buf, "m2ua_hex_to_ascii log msg is too long: %d\n\r", from_len); + strcat(m2ua_ascitemp_buf, "\33[37m"); + m2ua_asciout_proc(m2ua_ascitemp_buf); + return 0; + } + + for (i = 0; i< from_len; i++) + { + to_asc[j] = ascii[from_hex[i] >> 4]; + j++; + to_asc[j] = ascii[from_hex[i] & 0x0F]; + j++; + to_asc[j] = ' '; + j++; + } + + to_asc[j] = '\0'; + + return 1; +} + +int m2ua_log_err(WORD sg_id, char *err_msg) +{ + if ((moniter_fg & MONITOR_ERROR) == MONITOR_ERROR) + { + if ((m2ua_sg_mon_fg[sg_id] == 0)) + return 0; + m2ua_asciout_proc("\33[31m"); + if (strlen(err_msg) >= MAX_ASCITMP_LEN) + sprintf(m2ua_ascitemp_buf, "SG[%d] log msg is too long: %zu\n\r", sg_id, strlen(err_msg)); + else + sprintf(m2ua_ascitemp_buf, "SG[%d]: %s\n\r", sg_id, err_msg); + strcat(m2ua_ascitemp_buf, "\33[37m"); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + + return 1; +} diff --git a/plat/m2ua/src/m2ua_fsm.c b/plat/m2ua/src/m2ua_fsm.c new file mode 100644 index 0000000..4e13a05 --- /dev/null +++ b/plat/m2ua/src/m2ua_fsm.c @@ -0,0 +1,1631 @@ +#include "./include/m2ua_pub.h" +#include "./include/m2ua.h" +#include "./include/m2ua_const.h" +#include "./include/m2ua_struct.h" +#include "./include/m2ua_ext.h" +#include "./include/m2ua_msg.h" +#include "./include/m2ua_debug.h" + +extern unsigned int GetLocalIP1(); + +int find_sg_by_ipv4(unsigned int ipv4,uint16_t sg_id) +{ + WORD sg; + BYTE type; + char ascitemp_buf[256]; + BYTE mask; + + if (sg_id == M2UA_LISTEN_SG_NUM_0 || + sg_id == M2UA_LISTEN_SG_NUM_1) + { + type = M2UA_APP; + mask = sg_id - M2UA_LISTEN_SG_NUM_0; + } + else if (sg_id == IUA_LISTEN_SG_NUM_0 || + sg_id == IUA_LISTEN_SG_NUM_1) + { + type = IUA_APP; + mask = sg_id - IUA_LISTEN_SG_NUM_0; + } + else if (sg_id == M3UA_LISTEN_SG_NUM_0 || + sg_id == M3UA_LISTEN_SG_NUM_1) + { + type = M3UA_APP; +// mask = sg_id - M3UA_LISTEN_SG_NUM_0; + mask = 0; + } + + for (sg = 0; sg < M2UA_MAX_SG_NUM; sg++) + { + if (m2ua_para.sg_para[sg].enable && + m2ua_sg_info[sg].enable && + m2ua_para.sg_para[sg].server && + ((m2ua_para.sg_para[sg].xUA_ack>>1)==type) && + (m2ua_para.sg_para[sg].ip == ipv4) + ) + return sg; + } + + sprintf(ascitemp_buf, "can't find sg by ipv4: %X\n\r", ipv4); + m2ua_log_err(sg_id, ascitemp_buf); + return -1; +} + +int rel_sid(WORD sg, WORD lk) +{ + WORD ostr; + BYTE dw_index, bit_index; + + if (m2ua_lk_info[lk].sid == 0) + return -1; + + ostr = m2ua_lk_info[lk].sid - 1; + m2ua_lk_info[lk].sid = 0; + + dw_index = ostr / 32; + bit_index = ostr % 32; + + m2ua_sg_info[sg].sid_st[dw_index] &= (~(0x00000001 << bit_index)); + m2ua_sg_info[sg].rem_ostrs++; + + return 0; +} + +int assign_sid(WORD sg, WORD lk) +{ + WORD i; + BYTE dw_index, bit_index; + + if ((m2ua_sg_info[sg].ostrs < 2) ||(m2ua_sg_info[sg].ostrs > 257) || + (m2ua_sg_info[sg].rem_ostrs == 0) || (m2ua_lk_info[lk].sid > 0)) + return -1; + + for (i = 0; i < m2ua_sg_info[sg].ostrs - 1; i++) + { + dw_index = i / 32; + bit_index = i % 32; + if ((m2ua_sg_info[sg].sid_st[dw_index] >> bit_index) & 1) + continue; + else + { + m2ua_sg_info[sg].sid_st[dw_index] |= (0x00000001 << bit_index); + m2ua_sg_info[sg].rem_ostrs--; + m2ua_lk_info[lk].sid = i + 1; + return 0; + } + } + + return -1; +} + +int rel_sg_lk(WORD sg_id) +{ + WORD lk; + BYTE flag = 0; + + if ((m2ua_para.sg_para[sg_id].enable == 0) || + (m2ua_para.sg_para[sg_id].enable == 2)) + flag = 1; + + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP) + { + ; + } + for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) + { + if ((m2ua_para.lk_para[lk].lk_sg == sg_id) && + m2ua_lk_info[lk].enable) + { + rel_sid(sg_id, lk); + if (m2ua_lk_info[lk].lk_st > M2UA_LK_DOWN) + { + m2ua_lk_info[lk].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[lk].alarm_code = m2ua_sg_info[sg_id].alarm_code; + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M2UA_APP) + m2ua_sd_mtp3_primi(lk, M2UA_LK_DOWN); + else if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == IUA_APP) + iua_sd_q931_primi(lk, M2UA_LK_DOWN); + else if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP) + m3ua_sd_mtp3_user_primi(lk, M2UA_LK_DOWN); + m2ua_csta.lk_csta[lk].lk_dn_times++; + } + if (flag) + { + m2ua_lk_info[lk].enable = 0; + m2ua_lk_info[lk].lk_st = M2UA_LK_IDLE; + } + } + } + + m2ua_sg_info[sg_id].up_lks_cur = 0; + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_NORMAL; + + return 0; +} + + +int chg_sg_lk_status(WORD sg_id, BYTE status) +{ + WORD lk; + + for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) + { + if ((m2ua_para.lk_para[lk].lk_sg == sg_id) && + m2ua_lk_info[lk].enable) + { + m2ua_lk_info[lk].lk_st = status; + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP) + m3ua_sd_mtp3_user_primi(lk, status); + } + } + + return 1; +} + + + +int m2ua_fsm(WORD sg_id) +{ + WORD iid,m2ua_cmd, mtp3_cmd, mgmt_cmd; + BYTE lk_enable; + BYTE server; + int ret_val; + + m2ua_cmd = m2ua_sg_info[sg_id].m2ua_cmd; + mtp3_cmd = m2ua_sg_info[sg_id].mtp3_cmd; + mgmt_cmd = m2ua_sg_info[sg_id].mgmt_cmd; + + if (m2ua_sg_info[sg_id].m2ua_state < 3) + { + if (mgmt_cmd != M2UA_CMD_IDLEW) + m2ua_sg_info[sg_id].mgmt_cmd = M2UA_CMD_IDLEW; + if (mtp3_cmd != M2UA_CMD_IDLEW) + m2ua_sg_info[sg_id].mtp3_cmd = M2UA_CMD_IDLEW; + if (m2ua_cmd != M2UA_CMD_IDLEW) + m2ua_sg_info[sg_id].m2ua_cmd = M2UA_CMD_IDLEW; + } + + server = m2ua_para.sg_para[sg_id].server; + iid = m2ua_sg_info[sg_id].iid; + lk_enable = m2ua_para.lk_para[iid].enable; + + switch (m2ua_sg_info[sg_id].m2ua_state) + { + case 0: // Wait For M2UA ASP Up, or send ASP Up + if (server) + { + if (m2ua_cmd != M2UA_CMD_IDLEW) + { + if (m2ua_cmd == M2UA_ASPSM_ASP_UP) + { + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP_ACK); + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_INACTIVE; + m2ua_sg_info[sg_id].rc = 0; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + m2ua_sg_info[sg_id].T_r = 0; + m2ua_sg_info[sg_id].m2ua_state = 1; + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP) + { + chg_sg_lk_status(sg_id, M2UA_LK_UP); + m2ua_sg_info[sg_id].T_ack = 0; + m2ua_sg_info[sg_id].m2ua_state = 3; + } + } + else if (m2ua_cmd == M2UA_ASPSM_ASP_DOWN) + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK); + else if ((m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE) || + (m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE)) + { + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK); + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + } + } + else + { + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP); + m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK; + m2ua_sg_info[sg_id].m2ua_state = 1; + m2ua_sg_info[sg_id].retrans_times = 0; + } + break; + case 1: // Wait For M2UA ASP Active, or wait for ASP Up Ack + if (server) + { + if (m2ua_cmd != M2UA_CMD_IDLEW) + { + if (m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE) + { + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE_ACK); + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_ACTIVE; + m2ua_sg_info[sg_id].rc = 0; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + m2ua_sg_info[sg_id].T_r = 0; + m2ua_sg_info[sg_id].m2ua_state = 3; + } + else if (m2ua_cmd == M2UA_ASPSM_ASP_UP) + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP_ACK); + else if (m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE) + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE_ACK); + else if (m2ua_cmd == M2UA_ASPSM_ASP_DOWN) + { + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK); + m2ua_sg_info[sg_id].T_r = 0; + m2ua_sg_info[sg_id].m2ua_state = 0; + } + } + + if (m2ua_sg_info[sg_id].T_r > 0) + { + if (--m2ua_sg_info[sg_id].T_r == 0) + { + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_INACTIVE; + m2ua_sg_info[sg_id].rc = 0; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + } + } + } + else + { + if (m2ua_cmd == M2UA_ASPSM_ASP_UP_ACK) + { + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP) + { + chg_sg_lk_status(sg_id, M2UA_LK_UP); + m2ua_sg_info[sg_id].T_ack = 0; + m2ua_sg_info[sg_id].m2ua_state = 3; + } + else //m2ua iua + { + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE); + m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK; + m2ua_sg_info[sg_id].m2ua_state = 2; + m2ua_sg_info[sg_id].retrans_times = 0; + } + } + else if (m2ua_sg_info[sg_id].T_ack > 0) + { + if (--m2ua_sg_info[sg_id].T_ack == 0) + { + if (++m2ua_sg_info[sg_id].retrans_times >= M2UA_MAX_RETRANS) + return -2; + else + { + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP); + m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK; + } + } + } + else + return -1; + } + break; + case 2: // Wait for ASP ACTIVE ACK, only client can come to this state + if (m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE_ACK) + { + m2ua_sg_info[sg_id].T_ack = 0; + m2ua_sg_info[sg_id].m2ua_state = 3; + chg_sg_lk_status(sg_id, M2UA_LK_DOWN); + m2ua_sg_info[sg_id].retrans_times = 0; + } + else if (m2ua_cmd == M2UA_MGMT_ERROR) + { + m2ua_sg_info[sg_id].T_ack = 0; + m2ua_sg_info[sg_id].retrans_times = 0; + m2ua_sg_info[sg_id].m2ua_state = 0; + return -2; + } + else if (m2ua_sg_info[sg_id].T_ack > 0) + { + if (--m2ua_sg_info[sg_id].T_ack == 0) + { + if (++m2ua_sg_info[sg_id].retrans_times >= M2UA_MAX_RETRANS) + return -2; + else + { + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE); + m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK; + } + } + } + break; + case 3: // M2UA ASP Active + if (mgmt_cmd != M2UA_CMD_IDLEW) + { + m2ua_sg_info[sg_id].mgmt_cmd = M2UA_CMD_IDLEW; + if (((mgmt_cmd == M2UA_MGMT_CMD_LK_LOCK) + ||(mgmt_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MGMT_CMD_LK_LOCK))) + &&(m2ua_lk_info[iid].lk_st >= M2UA_LK_UP)) + { + if (server) + m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_IND); + else + m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_REQ); + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_LINK_MAINTENANCE; + m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN); + rel_sid(sg_id, iid); + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + else if ((mgmt_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MGMT_CMD_LK_LOCK)) && + (m2ua_lk_info[iid].lk_st >= M2UA_LK_UP)) + { + if (server) + m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_IND); + else + m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_REQ); + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_LINK_MAINTENANCE; + iua_sd_q931_primi(iid, M2UA_LK_DOWN); + rel_sid(sg_id, iid); + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + else if ((mgmt_cmd == COMBO_W(M3UA_MGMT_CMD,M2UA_MGMT_CMD_LK_LOCK)) && + (m2ua_lk_info[iid].lk_st >= M2UA_LK_UP)) + { + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_LINK_MAINTENANCE; + m3ua_sd_mtp3_user_primi(iid, M2UA_LK_DOWN); + rel_sid(sg_id, iid); + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + return -1; + } + + if (server) + { + if (mtp3_cmd != M2UA_CMD_IDLEW) + { + m2ua_sg_info[sg_id].mtp3_cmd = M2UA_CMD_IDLEW; + if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) && + ( (mtp3_cmd == M2UA_MTP3_CMD_DEACTIVE_LK) || + (mtp3_cmd == M2UA_MTP3_CMD_STOP_L2) || + (mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) || + (mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2)) + )) + { + m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_IND); + rel_sid(sg_id, iid); + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN; + m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN); + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + else if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) && + ((mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) || + (mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2)))) + { + m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT; + m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_IND); + rel_sid(sg_id, iid); + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN; + iua_sd_q931_primi(iid, M2UA_LK_DOWN); + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + else if (mtp3_cmd == COMBO_W(M3UA_RC_CMD,xUA_MTP3_CMD_DEACTIVE_RC)) + { + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE); + } + } + else if (m2ua_cmd != M2UA_CMD_IDLEW) + { + m2ua_sg_info[sg_id].m2ua_cmd = M2UA_CMD_IDLEW; + if (m2ua_cmd == M2UA_MAUP_DATA) + { + if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP) + { + m2ua_sd_mtp3_msg(sg_id, iid); + err[13]++; + } + return 0; + } + else if (m2ua_cmd == M2UA_MAUP_ESTABLISH_REQ) + { + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + assign_sid(sg_id, iid); + if (m2ua_lk_info[iid].sid > 0) + { + m2ua_send_msg(sg_id, M2UA_MAUP_ESTABLISH_CFM); + if (m2ua_lk_info[iid].lk_st == M2UA_LK_DOWN) + { + m2ua_sg_info[sg_id].up_lks_pre++; + m2ua_sg_info[sg_id].up_lks_cur++; + } + m2ua_lk_info[iid].lk_st = M2UA_LK_UP; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL; + m2ua_sd_mtp3_primi(iid, M2UA_LK_UP); + } + } + } + else if (m2ua_cmd == M2UA_MAUP_RELEASE_REQ) + { + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + assign_sid(sg_id, iid); + if (m2ua_lk_info[iid].sid > 0) + { + m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_CFM); + rel_sid(sg_id, iid); + if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN) + { + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE; + m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN); + } + } + } + else if (m2ua_cmd == M2UA_MAUP_STATE_REQ) + { + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + ret_val = assign_sid(sg_id, iid); + if (m2ua_lk_info[iid].sid > 0) + { + if (m2ua_sg_info[sg_id].state == M2UA_STATUS_AUDIT) + { + if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP) + m2ua_send_msg(sg_id, M2UA_MAUP_ESTABLISH_CFM); + else + m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_IND); + } + m2ua_send_msg(sg_id, M2UA_MAUP_STATE_CFM); + if (ret_val != -1) + rel_sid(sg_id, iid); + } + } + } + else if (m2ua_cmd == IUA_QPTM_DATA_REQ ||m2ua_cmd == IUA_QPTM_UDATA_REQ || + m2ua_cmd == IUA_QPTM_DATA_IND ||m2ua_cmd == IUA_QPTM_UDATA_IND) + { + if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP) + { + iua_sd_q931_msg(sg_id, iid); + err[13]++; + } + return 0; + } + else if (m2ua_cmd == M3UA_MAUP_DATA) + { + m3ua_sd_mtp3_user_msg(sg_id); + return 0; + } + else if (m2ua_cmd == IUA_QPTM_ESTABLISH_REQ) + { + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + assign_sid(sg_id, iid); + if (m2ua_lk_info[iid].sid > 0) + { + m2ua_send_msg(sg_id, IUA_QPTM_ESTABLISH_CFM); + if (m2ua_lk_info[iid].lk_st == M2UA_LK_DOWN) + { + m2ua_sg_info[sg_id].up_lks_pre++; + m2ua_sg_info[sg_id].up_lks_cur++; + } + m2ua_lk_info[iid].lk_st = M2UA_LK_UP; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL; + iua_sd_q931_primi(iid, M2UA_LK_UP); + } + } + } + else if (m2ua_cmd == IUA_QPTM_RELEASE_REQ) + { + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + assign_sid(sg_id, iid); + if (m2ua_lk_info[iid].sid > 0) + { + m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT; + m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_CFM); + rel_sid(sg_id, iid); + if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN) + { + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE; + iua_sd_q931_primi(iid, M2UA_LK_DOWN); + } + } + } + else if (m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE) + { + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) != M3UA_APP) + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE_ACK); + } + else if ((m2ua_cmd == M2UA_ASPSM_ASP_DOWN) || + (m2ua_cmd == M2UA_ASPSM_ASP_UP) || + (m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE)) + { + if (m2ua_cmd == M2UA_ASPSM_ASP_UP) + { + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP_ACK); + if(m2ua_sg_info[sg_id].status == ((M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_ACTIVE)) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + m2ua_sg_info[sg_id].m2ua_state = 1; + } + else if (m2ua_cmd == M2UA_ASPSM_ASP_DOWN) + { + m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK); + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_PENDING; + m2ua_sg_info[sg_id].rc = 0; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + m2ua_sg_info[sg_id].m2ua_state = 0; + } + else if (m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE) + { + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) != M3UA_APP) + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE_ACK); + } + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) != M3UA_APP) + { + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_REMOTE_AS_DOWN; + rel_sg_lk(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + m2ua_csta.sg_csta[sg_id].sg_asp_dn_times++; + } + } + } + } + else + { + if (mtp3_cmd != M2UA_CMD_IDLEW) + { + m2ua_sg_info[sg_id].mtp3_cmd = M2UA_CMD_IDLEW; + if ((mtp3_cmd == M2UA_MTP3_CMD_ACTIVE_LK) || + (mtp3_cmd == M2UA_MTP3_CMD_EMERG_ALIGN) || + (mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_ACTIVE_LK)) || + (mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_EMERG_ALIGN)) + ) + { + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1) && + (!m2ua_lk_info[iid].lk_timer)) + { + assign_sid(sg_id, iid); + if (m2ua_lk_info[iid].sid > 0) + { + if (mtp3_cmd == M2UA_MTP3_CMD_EMERG_ALIGN) + { + m2ua_sg_info[sg_id].state = M2UA_STATUS_EMER_SET; + m2ua_send_msg(sg_id, M2UA_MAUP_STATE_REQ); + } + else if (mtp3_cmd == M2UA_MTP3_CMD_ACTIVE_LK) + { + m2ua_sg_info[sg_id].state = M2UA_STATUS_EMER_CLEAR; + m2ua_send_msg(sg_id, M2UA_MAUP_STATE_REQ); + } + if (m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) + { + m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_REQ); + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN; + m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN); + } + else + m2ua_send_msg(sg_id, M2UA_MAUP_ESTABLISH_REQ); + m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB; + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + } + } + } + else if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) && (!m2ua_lk_info[iid].lk_timer) && + ((mtp3_cmd == M2UA_MTP3_CMD_DEACTIVE_LK) || + (mtp3_cmd == M2UA_MTP3_CMD_STOP_L2) || + (mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) || + (mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2)) + )) + { + m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_REQ); + m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB; + rel_sid(sg_id, iid); + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN; + m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN); + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + else if ((mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_ACTIVE_LK)) || + (mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_EMERG_ALIGN))) + { + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1) && + (!m2ua_lk_info[iid].lk_timer)) + { + assign_sid(sg_id, iid); + if (m2ua_lk_info[iid].sid > 0) + { + /* + if (mtp3_cmd == M2UA_MTP3_CMD_EMERG_ALIGN) + { + m2ua_sg_info[sg_id].state = M2UA_STATUS_EMER_SET; + m2ua_send_msg(sg_id, M2UA_MAUP_STATE_REQ); + } + */ + m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT; +// if (m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) + if (m2ua_lk_info[iid].lk_st > M2UA_LK_UP) + { + m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_REQ); + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN; + iua_sd_q931_primi(iid, M2UA_LK_DOWN); + } + else + m2ua_send_msg(sg_id, IUA_QPTM_ESTABLISH_REQ); + m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB; + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + } + } + } + else if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) && (!m2ua_lk_info[iid].lk_timer) && + ((mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) || + (mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2)))) + { + m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT; + m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_REQ); + m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB; + rel_sid(sg_id, iid); + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN; + iua_sd_q931_primi(iid, M2UA_LK_DOWN); + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + else if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) && (!m2ua_lk_info[iid].lk_timer) && + ((mtp3_cmd == COMBO_W(M3UA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) || + (mtp3_cmd == COMBO_W(M3UA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2)))) + { + rel_sid(sg_id, iid); + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN; + m3ua_sd_mtp3_user_primi(iid, M2UA_LK_DOWN); + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + else if (mtp3_cmd == COMBO_W(M3UA_RC_CMD,xUA_MTP3_CMD_ACTIVE_RC)) + { + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE); + } + else if (mtp3_cmd == COMBO_W(M3UA_RC_CMD,xUA_MTP3_CMD_DEACTIVE_RC)) + { + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE); + } + } + else if (m2ua_cmd != M2UA_CMD_IDLEW) + { + m2ua_sg_info[sg_id].m2ua_cmd = M2UA_CMD_IDLEW; + if (m2ua_cmd == M2UA_MAUP_DATA) + { + if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP) + { + err[13]++; + m2ua_sd_mtp3_msg(sg_id, iid); +// if ((m2ua_para.sg_para[sg_id].data_ack == 1) && + if (((m2ua_para.sg_para[sg_id].xUA_ack&0x01) == 0x01) && + (m2ua_sg_info[sg_id].cor_id != 0)) + m2ua_send_msg(sg_id, M2UA_MAUP_DATA_ACK); + } + return 0; + } + else if (m2ua_cmd == M2UA_MAUP_ESTABLISH_CFM) + { + assign_sid(sg_id, iid); + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + m2ua_lk_info[iid].lk_st = M2UA_LK_UP; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL; + m2ua_sd_mtp3_primi(iid, M2UA_LK_UP); + m2ua_sg_info[sg_id].up_lks_pre++; + m2ua_sg_info[sg_id].up_lks_cur++; + } + } + else if (m2ua_cmd == M2UA_MAUP_RELEASE_IND) + { + rel_sid(sg_id, iid); + if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN) + { + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE; + m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN); + } + else if (m2ua_cmd == IUA_QPTM_DATA_IND ||m2ua_cmd == IUA_QPTM_UDATA_IND || + m2ua_cmd == IUA_QPTM_DATA_REQ ||m2ua_cmd == IUA_QPTM_UDATA_REQ) + { + if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP) + { + err[13]++; + iua_sd_q931_msg(sg_id, iid); + } + return 0; + } + else if (m2ua_cmd == IUA_QPTM_ESTABLISH_CFM) + { + assign_sid(sg_id, iid); + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + m2ua_lk_info[iid].lk_st = M2UA_LK_UP; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL; + iua_sd_q931_primi(iid, M2UA_LK_UP); + m2ua_sg_info[sg_id].up_lks_pre++; + m2ua_sg_info[sg_id].up_lks_cur++; + } + } + else if (m2ua_cmd == IUA_QPTM_ESTABLISH_IND) + { + assign_sid(sg_id, iid); + if ((lk_enable == 1) && + (m2ua_lk_info[iid].enable == 1)) + { + m2ua_lk_info[iid].lk_st = M2UA_LK_UP; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL; + iua_sd_q931_primi(iid, M2UA_LK_UP); + if (m2ua_lk_info[iid].lk_st == M2UA_LK_DOWN) + { + m2ua_sg_info[sg_id].up_lks_pre++; + m2ua_sg_info[sg_id].up_lks_cur++; + } + } + } + else if (m2ua_cmd == IUA_QPTM_RELEASE_IND) + { + rel_sid(sg_id, iid); + if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN) + { + m2ua_csta.lk_csta[iid].lk_dn_times++; + if (m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_cur--; + } + m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN; + m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE; + iua_sd_q931_primi(iid, M2UA_LK_DOWN); + } + else if (m2ua_cmd == M3UA_MAUP_DATA) + { + m3ua_sd_mtp3_user_msg(sg_id); + return 0; + } + } + } + break; + case 4: //takeover by other sap + return -3; + default: + m2ua_sg_info[sg_id].m2ua_state = 0; + break; + } + + return -1; +} + +int m2ua_sctp_down(WORD sg_id) +{ + if (m2ua_sg_info[sg_id].m2ua_state == 3) + m2ua_csta.sg_csta[sg_id].sg_asp_dn_times++; + + m2ua_sg_info[sg_id].m2ua_state = 0; + m2ua_sg_info[sg_id].T_ack = 0; + m2ua_sg_info[sg_id].T_r = 0; + + m2ua_sg_info[sg_id].sctp_cmd = M2UA_CMD_IDLEW; + + rel_sg_lk(sg_id); + + m2ua_sg_info[sg_id].up_lks_pre = m2ua_sg_info[sg_id].up_lks_cur = 0; + + return 0; +} + +int m2ua_sg_fsm(WORD sg_id) +{ + int fd; + int msg, con_sg, ret,res; + BYTE enable; + BYTE conn_id; + BYTE server; + DWORD sctp_cmd; +#ifndef _LKSCTP + struct t_opthdr *oh; + t_scalar_t *str_val; + m2ua_sctp_addr_t *addr; +#else + struct sctp_assoc_change *sac; + int new_fd; + socklen_t addr_len; + struct sockaddr_in sin[1]; + char ascitemp_buf[256]; + struct timeval TOut = {0, 0}; + fd_set ReadFds; +#endif + + if (((m2ua_sg_info[sg_id].enable == 0) ||(m2ua_sg_info[sg_id].fd == 0)) && + !((m2ua_sg_info[sg_id].sctp_state == 3) && (m2ua_sg_info[sg_id].sctp_state_1 == 1))) // Not Client at sctp 3-1 state + return -1; + else + { + fd = m2ua_sg_info[sg_id].fd; + sctp_cmd = m2ua_sg_info[sg_id].sctp_cmd; + if (sg_id < M2UA_MAX_SG_NUM) + { + enable = m2ua_para.sg_para[sg_id].enable; + server = m2ua_para.sg_para[sg_id].server; + } + else + { + con_sg = m2ua_sg_info[sg_id].con_sg; + enable = m2ua_para.sg_para[con_sg].enable; + server = m2ua_para.sg_para[con_sg].server; + } + } + + switch (m2ua_sg_info[sg_id].sctp_state) + { + case 0: // SCTP Option Negotiate + if (((enable == 0) || (enable == 2)) && + (sg_id < M2UA_MAX_SG_NUM)) + { +#ifndef _LKSCTP + m2ua_sctp_close(fd, sg_id); +#else + m2ua_sctp_discon_req_lksctp(fd, sg_id, 0); +#endif + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + return -1; + } + + switch (m2ua_sg_info[sg_id].sctp_state_1) + { + case 0: // Send optmgnt request +#ifndef _LKSCTP + m2ua_sctp_optmgmt_req(fd, sg_id, T_NEGOTIATE); + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + m2ua_sg_info[sg_id].sctp_state_1 = 1; +#else + if (m2ua_sctp_optmgmt_req_lksctp(fd, sg_id) == 0) + { + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + } + else + { + if ((sg_id >= M2UA_MAX_SG_NUM) || + ((sg_id < M2UA_MAX_SG_NUM) && !server)) + { // Client or Listener + /* + m2ua_sg_info[sg_id].sctp_state = 1; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + */ + + m2ua_sg_info[sg_id].sctp_state = 0; + m2ua_sg_info[sg_id].sctp_state_1 = 2; + m2ua_sg_info[sg_id].sg_timer = 100 * plat_id; // + /*2 seconds to avoiding both plat re-connect at the same time*/ + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg_id] == 1)) + { + sprintf(m2ua_ascitemp_buf, "%s to bind SCTP sg_id=%d, timer=%d\n\r", __FUNCTION__, sg_id, plat_id * 5); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + } + else + { // Server + m2ua_sg_info[sg_id].sctp_state = 2; + m2ua_sg_info[sg_id].sctp_state_1 = 5; + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + } + } +#endif + break; + case 1: // Receive optmgmt response +#ifndef _LKSCTP + if (expect(fd, sg_id, &msg, T_OPTMGMT_ACK) != M2UA_FAILURE) + { + m2ua_sg_info[sg_id].sctp_state = 1; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + } + else if (m2ua_sg_info[sg_id].sg_timer) +#else + if (m2ua_sg_info[sg_id].sg_timer) +#endif + m2ua_sg_info[sg_id].sg_timer--; + else + m2ua_sg_info[sg_id].sctp_state_1 = 0; + break; + case 2: + if(m2ua_sg_info[sg_id].sg_timer > 0) + { + m2ua_sg_info[sg_id].sg_timer --; + return 0; + } + if ((sg_id >= M2UA_MAX_SG_NUM) || + ((sg_id < M2UA_MAX_SG_NUM) && !server)) + { // Client or Listener + m2ua_sg_info[sg_id].sctp_state = 1; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + } + break; + default: + m2ua_sg_info[sg_id].sctp_state_1 = 0; + break; + } + break; + case 1: // SCTP Address Bind + if (((enable == 0) || (enable == 2)) && + (sg_id < M2UA_MAX_SG_NUM)) + { +#ifndef _LKSCTP + m2ua_sctp_close(fd, sg_id); +#else + m2ua_sctp_discon_req_lksctp(fd, sg_id, 0); +#endif + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + return -1; + } + + switch (m2ua_sg_info[sg_id].sctp_state_1) + { + case 0: // Send bind request + //if (sg_id == M2UA_MAX_SG_NUM) + if (sg_id >= M2UA_MAX_SG_NUM) + conn_id = 1; + else + conn_id = 0; + m2ua_sctp_addr.addr.s_addr = GetLocalIP1(); +#ifndef _LKSCTP + if (sg_id == M2UA_LISTEN_SG_NUM_0) + m2ua_sctp_addr.port = htons(M2UA_PORT_0); + else if (sg_id == M2UA_LISTEN_SG_NUM_1) + m2ua_sctp_addr.port = htons(M2UA_PORT_1); + else if (sg_id == IUA_LISTEN_SG_NUM_0) + m2ua_sctp_addr.port = htons(IUA_PORT_0); + else if (sg_id == IUA_LISTEN_SG_NUM_1) + m2ua_sctp_addr.port = htons(IUA_PORT_1); + else if (sg_id == M3UA_LISTEN_SG_NUM_0) + m2ua_sctp_addr.port = htons(M3UA_PORT_0); + else if (sg_id == M3UA_LISTEN_SG_NUM_1) + m2ua_sctp_addr.port = htons(M3UA_PORT_1); + else if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M2UA_APP) + m2ua_sctp_addr.port = htons(M2UA_PORT_0+20000); + else if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == IUA_APP) + m2ua_sctp_addr.port = htons(IUA_PORT_0+20000); + else if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP) + m2ua_sctp_addr.port = htons(M3UA_PORT_0+20000); + m2ua_sctp_bind_req(fd, sg_id, &m2ua_sctp_addr, conn_id); + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + m2ua_sg_info[sg_id].sctp_state_1 = 1; +#else + if ((sg_id >= M2UA_MAX_SG_NUM) || + ((sg_id < M2UA_MAX_SG_NUM) && !server)) + { // Client or Listener + if (sg_id == M2UA_LISTEN_SG_NUM_0) + m2ua_sctp_addr.port = htons(M2UA_PORT_0); + else if (sg_id == M2UA_LISTEN_SG_NUM_1) + m2ua_sctp_addr.port = htons(M2UA_PORT_1); + else if (sg_id == IUA_LISTEN_SG_NUM_0) + m2ua_sctp_addr.port = htons(IUA_PORT_0); + else if (sg_id == IUA_LISTEN_SG_NUM_1) + m2ua_sctp_addr.port = htons(IUA_PORT_1); + else if (sg_id == M3UA_LISTEN_SG_NUM_0) + m2ua_sctp_addr.port = htons(M3UA_PORT_0); + else if (sg_id == M3UA_LISTEN_SG_NUM_1) + m2ua_sctp_addr.port = htons(M3UA_PORT_1); + else + m2ua_sctp_addr.port = 0; + /*set SG source port & ip*/ + if(sg_id < M2UA_MAX_SG_NUM) + { + if(m2ua_para.sg_para[sg_id].source_port !=0) + { + m2ua_sctp_addr.port = htons(m2ua_para.sg_para[sg_id].source_port); + + } + if(m2ua_para.sg_para[sg_id].source_ip != 0 ) + { + m2ua_sctp_addr.addr.s_addr = m2ua_para.sg_para[sg_id].source_ip; + + } + } + if (m2ua_sctp_bind_req_lksctp(fd, sg_id, &m2ua_sctp_addr, conn_id) == 0) + { + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + m2ua_sg_info[sg_id].sctp_state_1 = 1; + break; + } + } + m2ua_sg_info[sg_id].sctp_state = 2; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; +#endif + break; + case 1: // Receive bind response +#ifndef _LKSCTP + if (expect(fd, sg_id, &msg, T_BIND_ACK) != M2UA_FAILURE) + { + m2ua_sg_info[sg_id].sctp_state = 2; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + } + else if (m2ua_sg_info[sg_id].sg_timer) +#else + if (m2ua_sg_info[sg_id].sg_timer) +#endif + m2ua_sg_info[sg_id].sg_timer--; + else + m2ua_sg_info[sg_id].sctp_state_1 = 0; + break; + default: + m2ua_sg_info[sg_id].sctp_state_1 = 0; + break; + } + break; + case 2: // Wait for SCTP Connection Request from peer or Send conn req to the peer + switch (m2ua_sg_info[sg_id].sctp_state_1) + { + case 0: // Wait for connection indication from peer or conn req to the peer + if (sg_id >= M2UA_MAX_SG_NUM) + { +#ifndef _LKSCTP + if (expect(fd, sg_id, &msg, T_CONN_IND) == M2UA_SUCCESS) + { + m2ua_sg_info[sg_id].seq = m2ua_sctp_cmd.tpi.conn_ind.SEQ_number; + addr = (m2ua_sctp_addr_t *) (m2ua_sctp_cmd.cbuf + m2ua_sctp_cmd.tpi.conn_ind.SRC_offset); + con_sg = find_sg_by_ipv4(addr->addr.s_addr,sg_id); + if (con_sg < 0) + m2ua_sctp_discon_req(fd, sg_id, m2ua_sg_info[sg_id].seq); + else + { + oh = (struct t_opthdr *) (m2ua_sctp_cmd.cbuf + m2ua_sctp_cmd.tpi.conn_ind.OPT_offset); + str_val = (t_uscalar_t *)(oh + 1); + if (oh->name == T_SCTP_ISTREAMS) + m2ua_sg_info[sg_id].istrs = *str_val; + oh = (struct t_opthdr *)((BYTE *)oh + oh->len); + str_val = (t_uscalar_t *)(oh + 1); + if (oh->name == T_SCTP_OSTREAMS) + m2ua_sg_info[sg_id].ostrs = *str_val; + m2ua_sg_info[sg_id].con_sg = con_sg; + m2ua_sg_info[sg_id].sctp_state_1 = 1; + } + } +#else + FD_ZERO(&ReadFds); + FD_SET(fd, &ReadFds); + if ((select(fd + 1, &ReadFds, NULL, NULL, &TOut) > 0) && + FD_ISSET(fd, &ReadFds)) + { + addr_len = sizeof(*sin); + if ((new_fd = accept(fd, (struct sockaddr *)sin, &addr_len)) > 0) + { + if (fcntl(new_fd, F_SETFL, O_NONBLOCK) < 0) + m2ua_log_err(sg_id, "got lksctp incoming connection, but set nonblock failure!"); + + con_sg = find_sg_by_ipv4(sin->sin_addr.s_addr,sg_id); + if ((con_sg < 0) || (m2ua_sg_info[con_sg].enable == 0)) + { + if (con_sg < 0) + sprintf(ascitemp_buf, "got lksctp incoming connection, but can't find sg by ipv4: %X\n\r", sin->sin_addr.s_addr); + else + sprintf(ascitemp_buf, "got lksctp incoming connection, but sg[%d] not enabled!\n\r", con_sg); + m2ua_log_err(sg_id, ascitemp_buf); +// m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_sctp_discon_req_lksctp(new_fd, sg_id, 0); + } + else if ((m2ua_sg_info[con_sg].sctp_state == 3) && + (m2ua_sg_info[con_sg].sctp_state_1 == 0)) + { +// m2ua_sg_info[con_sg].sctp_cmd = M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST; + sprintf(ascitemp_buf, "got lksctp incoming connection, but sg[%d] is still in ESTABLISHED state! Disconnect it!\n\r", con_sg); + m2ua_log_err(sg_id, ascitemp_buf); + m2ua_sctp_discon_req_lksctp(new_fd, sg_id, 0); + } + else + { + m2ua_sg_info[con_sg].fd = new_fd; + m2ua_sg_info[con_sg].rem_port = sin->sin_port; + } + } + } +#endif + } + else + { + if ((enable == 0) || (enable == 2)) + { +#ifndef _LKSCTP + m2ua_sctp_close(fd, sg_id); +#else + m2ua_sctp_discon_req_lksctp(fd, sg_id, 0); +#endif + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + return -1; + } + + if (sctp_cmd != M2UA_CMD_IDLEW) + m2ua_sg_info[sg_id].sctp_cmd = M2UA_CMD_IDLEW; + + if (!server && (enable == 1)) + { // M2UA Client + m2ua_sctp_server_addr.port = htons(m2ua_para.sg_para[sg_id].plat_port[0]); + m2ua_sctp_server_addr.addr.s_addr = m2ua_para.sg_para[sg_id].ip; + if (m2ua_sg_info[sg_id].sg_timer) + m2ua_sg_info[sg_id].sg_timer--; +#ifndef _LKSCTP + else if (m2ua_sctp_conn_req(fd, sg_id, &m2ua_sctp_server_addr) != M2UA_FAILURE) + { + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + m2ua_sg_info[sg_id].sctp_state_1 = 3; + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + } +#else + else if (m2ua_sctp_conn_req_lksctp(fd, sg_id, &m2ua_sctp_server_addr) != M2UA_FAILURE) + { + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_2; + m2ua_sg_info[sg_id].sctp_state_1 = 4; + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + } +#endif + else + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + } + } + break; +#ifndef _LKSCTP + case 1: // Only SG_ID = M2UA_MAX_SG_NUM can come to this state + if ((enable == 1) && server && + (m2ua_sg_info[con_sg].sctp_state == 2)) + { + m2ua_sg_info[con_sg].seq = m2ua_sg_info[sg_id].seq; + m2ua_sg_info[con_sg].istrs = m2ua_sg_info[sg_id].istrs; + m2ua_sg_info[con_sg].ostrs = m2ua_sg_info[sg_id].ostrs; + m2ua_sg_info[con_sg].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1; + + if (m2ua_sctp_conn_res(fd, m2ua_sg_info[con_sg].fd, sg_id, m2ua_sg_info[sg_id].seq) != M2UA_FAILURE) + { + m2ua_sg_info[sg_id].sctp_state_1 = 2; + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + chg_sg_lk_status(con_sg, M2UA_LK_IDLE); + break; + } + } + m2ua_sctp_discon_req(fd, sg_id, m2ua_sg_info[sg_id].seq); + m2ua_sg_info[sg_id].sctp_state_1 = 0; + if ((enable == 1) && server && + (m2ua_sg_info[con_sg].sctp_state == 3)) + m2ua_sg_info[con_sg].sctp_cmd = T_DISCON_IND; + break; + case 2: // Only SG_ID = M2UA_MAX_SG_NUM can come to this state + if (expect(fd, sg_id, &msg, T_OK_ACK) == M2UA_SUCCESS) + { + m2ua_sg_info[sg_id].sctp_state = 2; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + + m2ua_sg_info[con_sg].sctp_state = 3; + m2ua_sg_info[con_sg].sctp_state_1 = 0; + } + else if ((msg == T_ERROR_ACK) || (!m2ua_sg_info[sg_id].sg_timer)) + { + m2ua_sctp_discon_req(fd, sg_id, m2ua_sg_info[sg_id].seq); + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + if ((enable == 1) && server && + (m2ua_sg_info[con_sg].sctp_state == 3)) + m2ua_sg_info[con_sg].sctp_cmd = T_DISCON_IND; + } + else + m2ua_sg_info[sg_id].sg_timer--; + break; + case 3: // Only M2UA client can come to this state + if ((enable == 0) || (enable == 2)) + { + m2ua_sctp_discon_req(fd, sg_id, 0); + m2ua_sctp_close(fd, sg_id); + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + return -1; + } + + if (expect(fd, sg_id, &msg, T_OK_ACK) == M2UA_SUCCESS) + { + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_2; + m2ua_sg_info[sg_id].sctp_state_1 = 4; + } + else if (msg == T_ERROR_ACK) + { + m2ua_sctp_discon_req(fd, sg_id, 0); + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + } + else if (m2ua_sg_info[sg_id].sg_timer > 0) + m2ua_sg_info[sg_id].sg_timer--; + else + { + m2ua_sctp_discon_req(fd, sg_id, 0); + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + } + break; +#endif + case 4: // only M2UA client can come to this state + if ((enable == 0) || (enable == 2)) + { +#ifndef _LKSCTP + m2ua_sctp_discon_req(fd, sg_id, 0); + m2ua_sctp_close(fd, sg_id); +#else + m2ua_sctp_discon_req_lksctp(fd, sg_id, 0); +#endif + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + return -1; + } + +#ifndef _LKSCTP + if (expect(fd, sg_id, &msg, T_CONN_CON) == M2UA_SUCCESS) + { + m2ua_sg_info[sg_id].sg_timer = 0; + oh = (struct t_opthdr *) (m2ua_sctp_cmd.cbuf + m2ua_sctp_cmd.tpi.conn_con.OPT_offset); + str_val = (t_uscalar_t *)(oh + 1); + if (oh->name == T_SCTP_ISTREAMS) + m2ua_sg_info[sg_id].istrs = *str_val; + oh = (struct t_opthdr *)((BYTE *)oh + oh->len); + str_val = (t_uscalar_t *)(oh + 1); + if (oh->name == T_SCTP_OSTREAMS) + { + m2ua_sg_info[sg_id].ostrs = *str_val; + m2ua_sg_info[sg_id].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1; + } + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + } +#else + if (expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP) == M2UA_SUCCESS) + { + sac = (struct sctp_assoc_change *) m2ua_sctp_dat; + m2ua_sg_info[sg_id].istrs = sac->sac_inbound_streams; + m2ua_sg_info[sg_id].ostrs = sac->sac_outbound_streams; + m2ua_sg_info[sg_id].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1; + m2ua_sg_info[sg_id].sg_timer = 0; + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sctp_optmgmt_req_lksctp_ext(fd, sg_id); + } +#endif + else + { +#ifndef _LKSCTP + if (msg == T_DISCON_IND) + { + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3 + M2UA_TIMER5S * plat_id; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + } +#else + if (msg == M2UA_LKSCTP_ASSOC_CHANGE_CANT_STR_ASSOC) + { + m2ua_sctp_discon_req_lksctp(fd, sg_id, 1); + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3 + M2UA_TIMER5S * plat_id; + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 1; + } +#endif + else if (m2ua_sg_info[sg_id].sg_timer > 0) + m2ua_sg_info[sg_id].sg_timer--; + else + { +#ifndef _LKSCTP + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3 + M2UA_TIMER5S * plat_id; + m2ua_sg_info[sg_id].sctp_state_1 = 0; +#else + m2ua_sctp_discon_req_lksctp(fd, sg_id, 1); + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3 + M2UA_TIMER5S * plat_id; + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 1; +#endif + } + } + break; +#ifdef _LKSCTP + case 5: // only M2UA server_lksctp can come to this state + if ((enable == 0) || (enable == 2)) + { + m2ua_sctp_discon_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, 0); + + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + return -1; + } + + if (expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP) == M2UA_SUCCESS) + { + sac = (struct sctp_assoc_change *) m2ua_sctp_dat; + m2ua_sg_info[sg_id].istrs = sac->sac_inbound_streams; + m2ua_sg_info[sg_id].ostrs = sac->sac_outbound_streams; + m2ua_sg_info[sg_id].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1; + m2ua_sg_info[sg_id].sg_timer = 0; + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sctp_optmgmt_req_lksctp_ext(fd, sg_id); + } + else + { + if (msg == M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST) + { + m2ua_sctp_discon_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, 1);//fixed by zane + m2ua_sg_info[sg_id].sg_timer = 0; + m2ua_sg_info[sg_id].sctp_state = 0; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + } + else if (m2ua_sg_info[sg_id].sg_timer > 0) + m2ua_sg_info[sg_id].sg_timer--; + else + { + m2ua_sctp_discon_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, 1);//fixed by zane + m2ua_sg_info[sg_id].sg_timer = 0; + m2ua_sg_info[sg_id].sctp_state = 0; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + } + } + break; +#endif + default: + m2ua_sg_info[sg_id].sctp_state_1 = 0; + break; + }; + break; + case 3: // M2UA SCTP Link Established + switch (m2ua_sg_info[sg_id].sctp_state_1) + { + case 0: // Normal +#ifndef _LKSCTP + if ((enable == 0) || (enable == 2) || (sctp_cmd == T_DISCON_IND) || + (!server && !m2ua_sg_info[sg_id].up_lks_cur && m2ua_sg_info[sg_id].up_lks_pre)) + { + if ((enable == 0) || (enable == 2)) + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + else + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE; + m2ua_sctp_discon_req(fd, sg_id, 0); +#else + if ((enable == 0) || (enable == 2) || (sctp_cmd == M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST) || + (!server && !m2ua_sg_info[sg_id].up_lks_cur && m2ua_sg_info[sg_id].up_lks_pre)) + { + if ((enable == 0) || (enable == 2)) + { + m2ua_sctp_discon_req_lksctp(fd, sg_id, 0); + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + } + else + { + m2ua_sctp_discon_req_lksctp(fd, sg_id, 1); + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE; + } +#endif + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if ((enable == 0) || (enable == 2)) + { + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + } + else + { + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 1; + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3 + M2UA_TIMER5S * plat_id ; + m2ua_log_err(sg_id, "All links are down, to reestablish the SCTP link!"); + } + + return -1; + } + else if (m2ua_sg_info[sg_id].up_lks_pre != m2ua_sg_info[sg_id].up_lks_cur) + m2ua_sg_info[sg_id].up_lks_pre = m2ua_sg_info[sg_id].up_lks_cur; + +#ifndef _LKSCTP + if (expect(fd, sg_id, &msg, T_DATA_IND) == M2UA_FAILURE) + { // Handle SCTP Primitives + if ((msg == T_DISCON_IND) || (msg == T_ORDREL_IND)) + { + if (msg == T_ORDREL_IND) + m2ua_sctp_ordrel_req(fd, sg_id); +#else + if (expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_DATA_IND) == M2UA_FAILURE) + { // Handle SCTP Primitives + if ((msg == M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST) || + (msg == M2UA_LKSCTP_ASSOC_CHANGE_SHUTDOWN_COMP) || + (msg == M2UA_LKSCTP_SHUTDOWN_EVENT)) + { + m2ua_sctp_discon_req_lksctp(fd, sg_id, 1); +#endif + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 1; + if(server) + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_WAIT; + else + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3 + M2UA_TIMER5S * plat_id; + m2ua_log_err(sg_id, "Got discon_ind from SCTP, wait to reestablish the SCTP link!"); + + return -1; + } +#ifdef _LKSCTP + else if (msg == M2UA_LKSCTP_ASSOC_CHANGE_RESTART) + { + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + m2ua_log_err(sg_id, "Got M2UA_LKSCTP_ASSOC_CHANGE_RESTART from SCTP!"); + return -1; + } +#endif + ret = -1; + } + else + { + m2ua_dec_msg(sg_id); + ret = 0; + } + res = m2ua_fsm(sg_id); + if (( res <= -2) && (!server)) + { +#ifndef _LKSCTP + m2ua_sctp_discon_req(fd, sg_id, 0); +#else + m2ua_sctp_discon_req_lksctp(fd, sg_id, 1);//fixed by zane +#endif + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_REMOTE_AS_DOWN; + m2ua_sctp_down(sg_id); + m2ua_sg_info[sg_id].sctp_state = 3; + m2ua_sg_info[sg_id].sctp_state_1 = 1; + m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3 + M2UA_TIMER5S * plat_id; + if(res == -2) + m2ua_log_err(sg_id, "ASP UP/ACTIVE timeout, wait to reestablish the SCTP link!"); + else if(res == -3) + m2ua_log_err(sg_id, "SGP takeover,Alternate ASP Active, please check the configuration!"); + return res; + } + else + return ret; + break; + case 1: // Wait... + if ((enable == 0) || (enable == 2)) + { +#ifndef _LKSCTP + m2ua_sctp_close(fd, sg_id); +#else + m2ua_sctp_discon_req_lksctp(fd, sg_id, 0); +#endif + m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE; + m2ua_sctp_down(sg_id); + chg_sg_lk_status(sg_id, M2UA_LK_IDLE); + + if (enable == 2) + m2ua_para.sg_para[sg_id].enable = 0; + + m2ua_sg_init(sg_id); + m2ua_log_err(sg_id, "SG disabled!"); + return -1; + } +#ifndef _LKSCTP + if ((m2ua_sg_info[sg_id].sg_timer--) > 0) + expect(fd, sg_id, &msg, T_OK_ACK); + else + { + m2ua_sg_info[sg_id].sctp_state = 2; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + } +#else + if ((m2ua_sg_info[sg_id].sg_timer--) > 0); + //expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_DATA_IND); + else + { + m2ua_sg_info[sg_id].sctp_state = 0; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + m2ua_sg_info[sg_id].sg_timer = 0; + } +#endif + break; + default: + break; + } + break; + default: + m2ua_sg_info[sg_id].sctp_state = 0; + m2ua_sg_info[sg_id].sctp_state_1 = 0; + break; + } + + return -1; +} + + diff --git a/plat/m2ua/src/m2ua_msg.c b/plat/m2ua/src/m2ua_msg.c new file mode 100644 index 0000000..d858aea --- /dev/null +++ b/plat/m2ua/src/m2ua_msg.c @@ -0,0 +1,4008 @@ +#include "./include/m2ua_pub.h" +#include "./include/m2ua.h" +#include "./include/m2ua_const.h" +#include "./include/m2ua_struct.h" +#include "./include/m2ua_ext.h" +#include "./include/m2ua_fsm.h" +#include "./include/m2ua_debug.h" +#include "./include/m2ua_msg.h" + + +#ifndef _LKSCTP + +static struct strfdinsert m2ua_sctp_fdi = +{ + {M2UA_SCTP_CMD_BUFSIZE, 0, m2ua_sctp_cmd.cbuf}, + {M2UA_SCTP_DAT_BUFSIZE, 0, m2ua_sctp_dat}, + 0, + 0, + 0 +}; + +static m2ua_sctp_opt_data_t m2ua_sctp_opt_data = +{ + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_SID, + T_SUCCESS + }, + 0 +}; + +m2ua_sctp_opt_optm_t m2ua_sctp_opt_optm = +{ + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_NODELAY, + T_SUCCESS + }, + T_YES, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_CORK, + T_SUCCESS + }, + T_YES, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_PPI, + T_SUCCESS + }, + 2, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_SID, + T_SUCCESS + }, + 0, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_RECVOPT, + T_SUCCESS + }, + T_NO, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_COOKIE_LIFE, + T_SUCCESS + }, + 60000, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_SACK_DELAY, + T_SUCCESS + }, + 0, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_PATH_MAX_RETRANS, + T_SUCCESS + }, + 5, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_ASSOC_MAX_RETRANS, + T_SUCCESS + }, + 5, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_MAX_INIT_RETRIES, + T_SUCCESS + }, + 8, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_HEARTBEAT_ITVL, + T_SUCCESS + }, + 20000, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_RTO_INITIAL, + T_SUCCESS + }, + 1000, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_RTO_MIN, + T_SUCCESS + }, + 1000, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_RTO_MAX, + T_SUCCESS + }, + 5000, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_OSTREAMS, + T_SUCCESS + }, + 257, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_ISTREAMS, + T_SUCCESS + }, + 257, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_COOKIE_INC, + T_SUCCESS + }, + 0, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_THROTTLE_ITVL, + T_SUCCESS + }, + 50, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_MAC_TYPE, + T_SUCCESS + }, + SCTP_HMAC_NONE, + { + sizeof(struct t_opthdr) + sizeof(t_scalar_t), + T_INET_SCTP, + T_SCTP_DEBUG, + T_SUCCESS + }, + 0 +}; + +#endif +extern int check_m3ua_rc_verify(DWORD rc,WORD lk); + +int rc_verify(WORD sg) +{ + WORD lk; + + for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) + { + if ((m2ua_para.lk_para[lk].lk_sg == sg) && + m2ua_lk_info[lk].enable) + { + if(check_m3ua_rc_verify(m2ua_sg_info[sg].rc,lk)>0) + return 1; + } + } + return 0; +} + +char *dec_m2ua_msg(WORD m2ua_msg) +{ + switch (m2ua_msg) + { + case M2UA_MAUP_DATA: return("M2UA_MAUP_DATA"); + case M2UA_MAUP_ESTABLISH_REQ: return("M2UA_MAUP_ESTABLISH_REQ"); + case M2UA_MAUP_ESTABLISH_CFM: return("M2UA_MAUP_ESTABLISH_CFM"); + case M2UA_MAUP_RELEASE_REQ: return("M2UA_MAUP_RELEASE_REQ"); + case M2UA_MAUP_RELEASE_CFM: return("M2UA_MAUP_RELEASE_CFM"); + case M2UA_MAUP_RELEASE_IND: return("M2UA_MAUP_RELEASE_IND"); + case M2UA_MAUP_STATE_REQ: return("M2UA_MAUP_STATE_REQ"); + case M2UA_MAUP_STATE_CFM: return("M2UA_MAUP_STATE_CFM"); + case M2UA_MAUP_STATE_IND: return("M2UA_MAUP_STATE_IND"); + case M2UA_MAUP_DATA_RETIEVE_REQ: return("M2UA_MAUP_DATA_RETIEVE_REQ"); + case M2UA_MAUP_DATA_RETIEVE_CFM: return("M2UA_MAUP_DATA_RETIEVE_CFM"); + case M2UA_MAUP_DATA_RETIEVE_IND: return("M2UA_MAUP_DATA_RETIEVE_IND"); + case M2UA_MAUP_DATA_RETIEVE_CMP: return("M2UA_MAUP_DATA_RETIEVE_CMP"); + case M2UA_MAUP_CONGESTION_IND: return("M2UA_MAUP_CONGESTION_IND"); + case M2UA_MAUP_DATA_ACK: return("M2UA_MAUP_DATA_ACK"); + + case xUA_MGMT_ERROR: return("xUA_MGMT_ERROR"); + case xUA_MGMT_NOTIFY: return("xUA_MGMT_NOTIFY"); + case xUA_MGMT_TEI_S_REQ: return("xUA_MGMT_TEI_S_REQ"); + case xUA_MGMT_TEI_S_CFM: return("xUA_MGMT_TEI_S_CFM"); + case xUA_MGMT_TEI_S_IND: return("xUA_MGMT_TEI_S_IND"); + + case xUA_ASPSM_ASP_UP: return("xUA_ASPSM_ASP_UP"); + case xUA_ASPSM_ASP_DOWN: return("xUA_ASPSM_ASP_DOWN"); + case xUA_ASPSM_HEARTBEAT: return("xUA_ASPSM_HEARTBEAT"); + case xUA_ASPSM_ASP_UP_ACK: return("xUA_ASPSM_ASP_UP_ACK"); + case xUA_ASPSM_ASP_DOWN_ACK: return("xUA_ASPSM_ASP_DOWN_ACK"); + case xUA_ASPSM_HEARTBEAT_ACK: return("xUA_ASPSM_HEARTBEAT_ACK"); + + case xUA_ASPTM_ASP_ACTIVE: return("xUA_ASPTM_ASP_ACTIVE"); + case xUA_ASPTM_ASP_INACTIVE: return("xUA_ASPTM_ASP_INACTIVE"); + case xUA_ASPTM_ASP_ACTIVE_ACK: return("xUA_ASPTM_ASP_ACTIVE_ACK"); + case xUA_ASPTM_ASP_INACTIVE_ACK: return("xUA_ASPTM_ASP_INACTIVE_ACK"); + + case IUA_QPTM_DATA_REQ: return("IUA_QPTM_DATA_REQ"); + case IUA_QPTM_DATA_IND: return("IUA_QPTM_DATA_IND"); + case IUA_QPTM_UDATA_REQ: return("IUA_QPTM_UDATA_REQ"); + case IUA_QPTM_UDATA_IND: return("IUA_QPTM_UDATA_IND"); + case IUA_QPTM_ESTABLISH_REQ: return("IUA_QPTM_ESTABLISH_REQ"); + case IUA_QPTM_ESTABLISH_CFM: return("IUA_QPTM_ESTABLISH_CFM"); + case IUA_QPTM_ESTABLISH_IND: return("IUA_QPTM_ESTABLISH_IND"); + case IUA_QPTM_RELEASE_REQ: return("IUA_QPTM_RELEASE_REQ"); + case IUA_QPTM_RELEASE_CFM: return("IUA_QPTM_RELEASE_CFM"); + case IUA_QPTM_RELEASE_IND: return("IUA_QPTM_RELEASE_IND"); + + case M3UA_MAUP_DATA: return("M3UA_MAUP_DATA"); + + case M3UA_SSNM_DUNA: return("M3UA_SSNM_DUNA"); + case M3UA_SSNM_DAVA: return("M3UA_SSNM_DAVA"); + case M3UA_SSNM_DAUD: return("M3UA_SSNM_DAUD"); + case M3UA_SSNM_SCON: return("M3UA_SSNM_SCON"); + case M3UA_SSNM_DUPU: return("M3UA_SSNM_DUPU"); + case M3UA_SSNM_DRST: return("M3UA_SSNM_DRST"); + + default: return("Unexpected"); + } +} + +int m2ua_make_par(m2ua_var_par_t *par_ptr, WORD par_type, BYTE *par_addr, WORD par_len) +{ + WORD len = 0; + + if(par_len == 0) + { + return 0; + } + + par_ptr->hdr.tag = htons(par_type); + par_ptr->hdr.len = htons(sizeof(m2ua_par_hdr_t) + par_len); + + len = sizeof(m2ua_par_hdr_t) + ((par_len + 3) & 0xFFFC); + if (par_type == M2UA_PAR_PROTO_DATA_1 || + par_type == M3UA_Protocol_Data ) + bzero(par_ptr->val + par_len, len - par_len); + else + bcopy(par_addr, par_ptr->val, par_len); + + + return len; +} + +static BYTE asp_id_order = 1; +static int tariff_mode_type = 0; + +int m2ua_read_param() +{ + FILE *fp=NULL; + int len; + char param_name[32]; + + fp = fopen("./conf/xua_conf.txt","r"); + if(fp == NULL) + return 0; + + while ( fgets(param_name, 32, fp) != (char *)0 ) + { + if ( (int *)strchr(param_name,'#') != NULL ) continue; + if ( (len=strlen(param_name))<=1 ) continue; + if(param_name[0]=='\n')continue; + param_name[len-1] = 0; + + if(strncasecmp(param_name,"asp_id_order=", 13)==0) + { + asp_id_order = atoi(¶m_name[13]); + } + else if(strncasecmp(param_name,"tariff_mode_type=", 17)==0) + { + tariff_mode_type = atoi(¶m_name[17]); + } + } + + fclose(fp); + + return 1; +} + +int m2ua_save_param() +{ + FILE *fp=NULL; + //int len; + //char param_name[32]; + + fp = fopen("./conf/xua_conf.txt","w"); + if(fp == NULL) + return 0; + + fprintf(fp,"#asp_id_order=0/1, 0=normal order, 1=network order \r\n"); + fprintf(fp,"#tariff_mode_type=0/1, 0=override, 1=load-sharing \r\n"); + + fprintf(fp, "asp_id_order=%d\r\n", asp_id_order); + fprintf(fp,"tariff_mode_type=%d\r\n", tariff_mode_type); + + fclose(fp); + + return 1; +} + +int set_asp_id_order(BYTE flag) +{ + asp_id_order = flag; + + m2ua_save_param(); + + return asp_id_order; +} + +int xua_get_asp_id(WORD sg_id) +{ + DWORD asp_id; + + if(asp_id_order == 0) + asp_id = (1024 + sg_id); + else + asp_id = htonl(1024+sg_id); + + return asp_id; +} + + +int m2ua_get_traffic_mode_type() +{ + return tariff_mode_type; +} + +int m2ua_set_traffic_mode_type(int flag) +{ + + tariff_mode_type = flag; + + m2ua_save_param(); + + return tariff_mode_type; +} + + +int m2ua_send_msg(WORD sg_id, WORD msg) +{ + BYTE msg_class, msg_type; + WORD len = 0, msg_len; + WORD par_len = 0, par_start = 0; + WORD sid = 0, i; + DWORD dw; + BYTE iid, flag = 0; + WORD lk,dlci; + m2ua_msg_t *msg_ptr; + + msg_class = msg >> 8; + msg_type = msg & 0xFF; + + if (msg == M2UA_MAUP_DATA || msg == M3UA_MAUP_DATA || msg == M3UA_SSNM_DAVA || + msg == M3UA_SSNM_DUNA ||msg == M3UA_SSNM_DAUD || + msg == IUA_QPTM_DATA_REQ || msg == IUA_QPTM_UDATA_REQ || + msg == IUA_QPTM_DATA_IND || msg == IUA_QPTM_UDATA_IND ) + msg_ptr = (m2ua_msg_t *)m2ua_sg_info[sg_id].msg; + else + //msg_ptr = (m2ua_msg_t *)m2ua_sctp_dat; + msg_ptr = (m2ua_msg_t *)m2ua_sctp_dat_send; + + switch (msg_class) + { + case M2UA_MCLASS_MGMT: + { + switch (msg_type) + { + case xUA_ERROR: + dw = htonl(m2ua_sg_info[sg_id].err_code); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_ERR_CODE, (BYTE *)&dw, 4); + len += par_len; + if(m2ua_sg_info[sg_id].err_code == M3UA_ERR_INVALID_RC) + { + par_start += par_len; + dw = htonl(m2ua_sg_info[sg_id].rc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Routing_Context, (BYTE *)&dw, 4); + len += par_len; + } + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MGMT; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + case xUA_NOTIFY: + dw = htonl(m2ua_sg_info[sg_id].status); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_STATUS, (BYTE *)&dw, 4); + len += par_len; + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP && + m2ua_sg_info[sg_id].rc) + { + par_start += par_len; + dw = htonl(m2ua_sg_info[sg_id].rc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Routing_Context, (BYTE *)&dw, 4); + len += par_len; + } + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MGMT; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + case TEI_S_REQ: + case TEI_S_CFM: + case TEI_S_IND: + lk = m2ua_sg_info[sg_id].iid; + iid = m2ua_para.lk_para[lk].iid; + msg_len = m2ua_sg_info[sg_id].msg_len; + sid = m2ua_lk_info[lk].sid; + dw = htonl(iid); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_INTERFACE_ID_INT, (BYTE *) &dw, 4); + len += par_len; + //DLCI + par_start += par_len; + dlci = m2ua_para.lk_para[lk].dlci; + dw = htons(dlci) << 16; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_PAR_DLCI, (BYTE *) &dw, 4); + len += par_len; + if(msg_type != TEI_S_REQ) + { + dw = htonl(m2ua_sg_info[sg_id].tei_state); + par_start += par_len; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_PAR_TEI_STATUS, (BYTE *) &dw, 4); + len += par_len; + } + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MGMT; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + default: + break; + } + break; + } + case M2UA_MCLASS_ASPSM: + { + switch (msg_type) + { + case ASP_UP: + //dw = host_ip; + dw = xua_get_asp_id(sg_id); + m2ua_sg_info[sg_id].asp_id = dw; + if(m2ua_get_traffic_mode_type() == 0) + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_ASP_IDENTIFIER, (BYTE *)&dw, 4); + else + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_ASP_IDENTIFIER, (BYTE *)&dw, 0); + + len += par_len; + + msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; + msg_ptr->comhdr.msg_type = ASP_UP; + len += sizeof(m2ua_comhdr_t); + break; + case ASP_DOWN: + break; + case HEARTBEAT: + break; + case ASP_UP_ACK: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; + msg_ptr->comhdr.msg_type = ASP_UP_ACK; + len += sizeof(m2ua_comhdr_t); + break; + case ASP_DOWN_ACK: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; + msg_ptr->comhdr.msg_type = ASP_DOWN_ACK; + len += sizeof(m2ua_comhdr_t); + break; + case HEARTBEAT_ACK: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; + msg_ptr->comhdr.msg_type = HEARTBEAT_ACK; + len = m2ua_sg_info[sg_id].msg_len; + break; + default: + break; + } + break; + } + case M2UA_MCLASS_ASPTM: + { + sid = 1; + switch (msg_type) + { + case ASP_ACTIVE: + if(m2ua_get_traffic_mode_type() == 0) + dw = htonl(M2UA_TRAFFIC_MODE_OVERRIDE); + else + dw = htonl(M2UA_TRAFFIC_MODE_LOADSHARE); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_TRAFFIC_MODE, (BYTE *)&dw, 4); + len += par_len; + par_start += par_len; + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP) + { + if(m2ua_sg_info[sg_id].rc) + { + dw = htonl(m2ua_sg_info[sg_id].rc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Routing_Context, (BYTE *)&dw, 4); + len += par_len; + par_start += par_len; + } + } + else + { + for (i = 0; i < M2UA_MAX_LK_NUM; i++) + { + if (m2ua_lk_info[i].enable && (m2ua_para.lk_para[i].lk_sg == sg_id)) + { + dw = htonl(m2ua_para.lk_para[i].iid); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_INTERFACE_ID_INT, (BYTE *)&dw, 4); + len += par_len; + par_start += par_len; + } + } + } + msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPTM; + msg_ptr->comhdr.msg_type = ASP_ACTIVE; + len += sizeof(m2ua_comhdr_t); + break; + case ASP_INACTIVE: + break; + case ASP_ACTIVE_ACK: + //dw = htonl(M2UA_TRAFFIC_MODE_OVERRIDE); + dw = htonl(m2ua_sg_info[sg_id].tra_hdl_mode); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_TRAFFIC_MODE, (BYTE *)&dw, 4); + len += par_len; + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP && + m2ua_sg_info[sg_id].rc) + { + par_start += par_len; + dw = htonl(m2ua_sg_info[sg_id].rc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Routing_Context, (BYTE *)&dw, 4); + len += par_len; + } + msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPTM; + msg_ptr->comhdr.msg_type = ASP_ACTIVE_ACK; + len += sizeof(m2ua_comhdr_t); + break; + case ASP_INACTIVE_ACK: + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M3UA_APP && + m2ua_sg_info[sg_id].rc) + { + lk = m2ua_sg_info[sg_id].iid; + dw = htonl(m2ua_sg_info[sg_id].rc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Routing_Context, (BYTE *)&dw, 4); + len += par_len; + } + msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPTM; + msg_ptr->comhdr.msg_type = ASP_INACTIVE_ACK; + len += sizeof(m2ua_comhdr_t); + break; + default: + break; + } + break; + } + case M2UA_MCLASS_MAUP: + { + lk = m2ua_sg_info[sg_id].iid; + iid = m2ua_para.lk_para[lk].iid; + msg_len = m2ua_sg_info[sg_id].msg_len; + sid = m2ua_lk_info[lk].sid; + dw = htonl(iid); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_INTERFACE_ID_INT, (BYTE *) &dw, 4); + len += par_len; + switch (msg_type) + { + case DATA: + par_start += par_len; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_PROTO_DATA_1, m2ua_sg_info[sg_id].msg + 20, msg_len); + len += par_len; + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = DATA; + len += sizeof(m2ua_comhdr_t); + + m2ua_csta.sg_csta[sg_id].sg_out_msg++; + m2ua_csta.lk_csta[lk].lk_out_msg++; + m2ua_csta.sg_csta[sg_id].sg_out_bytes += msg_len; + m2ua_csta.lk_csta[lk].lk_out_bytes += msg_len; + err[3]++; + break; + case ESTABLISH_REQ: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = ESTABLISH_REQ; + len += sizeof(m2ua_comhdr_t); + break; + case ESTABLISH_CFM: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = ESTABLISH_CFM; + len += sizeof(m2ua_comhdr_t); + break; + case RELEASE_REQ: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = RELEASE_REQ; + len += sizeof(m2ua_comhdr_t); + break; + case RELEASE_CFM: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = RELEASE_CFM; + len += sizeof(m2ua_comhdr_t); + break; + case RELEASE_IND: + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = RELEASE_IND; + len += sizeof(m2ua_comhdr_t); + break; + case STATE_REQ: + dw = htonl(m2ua_sg_info[sg_id].state); + par_start += par_len; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_STATE, (BYTE *) &dw, 4); + len += par_len; + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = STATE_REQ; + len += sizeof(m2ua_comhdr_t); + break; + case STATE_CFM: + dw = htonl(m2ua_sg_info[sg_id].state); + par_start += par_len; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_STATE, (BYTE *) &dw, 4); + len += par_len; + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = STATE_CFM; + len += sizeof(m2ua_comhdr_t); + break; + case STATE_IND: + break; + case DATA_RETIEVE_REQ: + case DATA_RETIEVE_CFM: + case DATA_RETIEVE_IND: + case DATA_RETIEVE_CMP: + case CONGESTION_IND: + break; + case DATA_ACK: + dw = htonl(m2ua_sg_info[sg_id].cor_id); + par_start += par_len; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_CORRELATION_ID, (BYTE *) &dw, 4); + len += par_len; + msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; + msg_ptr->comhdr.msg_type = DATA_ACK; + len += sizeof(m2ua_comhdr_t); + break; + default: + break; + } + break; + } + case xUA_MCLASS_QPTM: + { + lk = m2ua_sg_info[sg_id].iid; + iid = m2ua_para.lk_para[lk].iid; + msg_len = m2ua_sg_info[sg_id].msg_len; + sid = m2ua_lk_info[lk].sid; + dw = htonl(iid); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M2UA_PAR_INTERFACE_ID_INT, (BYTE *) &dw, 4); + len += par_len; + //DLCI + par_start += par_len; + dlci = m2ua_para.lk_para[lk].dlci; + dw = htons(dlci) << 16; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_PAR_DLCI, (BYTE *) &dw, 4); + len += par_len; + switch (msg_type) + { + case IUA_UDATA_REQ: + case IUA_UDATA_IND: + break; + case IUA_DATA_REQ: + case IUA_DATA_IND: + par_start += par_len; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_PAR_PROTOCOL_DATA, m2ua_sg_info[sg_id].msg + 28, msg_len); + len += par_len; + msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + + m2ua_csta.sg_csta[sg_id].sg_out_msg++; + m2ua_csta.lk_csta[lk].lk_out_msg++; + m2ua_csta.sg_csta[sg_id].sg_out_bytes += msg_len; + m2ua_csta.lk_csta[lk].lk_out_bytes += msg_len; + err[3]++; + break; + case IUA_ESTABLISH_REQ: + case IUA_ESTABLISH_CFM: + case IUA_ESTABLISH_IND: + msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + case IUA_RELEASE_REQ: + case IUA_RELEASE_IND: + dw = htonl(m2ua_sg_info[sg_id].rel_reason); + par_start += par_len; + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_PAR_REL_REASON, (BYTE *) &dw, 4); + len += par_len; + msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + case IUA_RELEASE_CFM: + msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + default: + break; + } + break; + } + case xUA_MCLASS_TRMSG: + { + switch (msg_type) + { + case M3UA_DATA: + lk = m2ua_sg_info[sg_id].iid; + msg_len = m2ua_sg_info[sg_id].msg_len; + sid = m2ua_lk_info[lk].sid; + + if (m2ua_sg_info[sg_id].rc) + { + dw = htonl(m2ua_sg_info[sg_id].rc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Routing_Context, (BYTE *) &dw, 4); + len += par_len; + par_start += par_len; + } + + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M3UA_Protocol_Data, m2ua_sg_info[sg_id].msg + 20, msg_len+12); + len += par_len; + msg_ptr->comhdr.msg_class = xUA_MCLASS_TRMSG; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + default: + break; + } + break; + } + case xUA_MCLASS_SSNM: + { + switch (msg_type) + { + case SSNM_DAVA: + case SSNM_DUNA: + lk = m2ua_sg_info[sg_id].iid; + msg_len = m2ua_sg_info[sg_id].msg_len; + sid = m2ua_lk_info[lk].sid; + + if(m2ua_sg_info[sg_id].net_app) + { + dw = htonl(m2ua_sg_info[sg_id].net_app); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + M3UA_Network_Appearance, (BYTE *) &dw, 4); + len += par_len; + par_start += par_len; + } + if (m2ua_sg_info[sg_id].rc) + { + dw = htonl(m2ua_sg_info[sg_id].rc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Routing_Context, (BYTE *) &dw, 4); + len += par_len; + par_start += par_len; + } + { + dw = htonl(m2ua_sg_info[sg_id].aff_pc); + par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], + xUA_Affected_PC, (BYTE *) &dw, 4); + len += par_len; + par_start += par_len; + } + msg_ptr->comhdr.msg_class = xUA_MCLASS_SSNM; + msg_ptr->comhdr.msg_type = msg_type; + len += sizeof(m2ua_comhdr_t); + break; + default: + break; + } + break; + } + default: + break; + } + + if (len == 0) + return 0; + + msg_ptr->comhdr.version = 1; + msg_ptr->comhdr.spare = 0; + msg_ptr->comhdr.len = htonl(len); + + if ((moniter_fg & MONITOR_M2UA) == MONITOR_M2UA) + { + if (m2ua_sg_mon_fg[sg_id] == 1) + { + if (msg_class == M2UA_MCLASS_MAUP) + sprintf(m2ua_ascitemp_buf, "Send %s to The Peer, sg=%d, lk=%d, sid=%d, len=%d\n\r", dec_m2ua_msg(msg), sg_id, lk, sid, len); + else + sprintf(m2ua_ascitemp_buf, "Send %s to The Peer, sg=%d, sid=%d, len=%d\n\r", dec_m2ua_msg(msg), sg_id, sid, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)msg_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + flag = 1; + } + } + if ((msg_class == M2UA_MCLASS_MAUP ||msg_class == xUA_MCLASS_QPTM) && !flag) + { + if ((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) + { + if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[lk] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Send %s to The Peer, sg=%d, lk=%d, sid=%d, len=%d\n\r", dec_m2ua_msg(msg), sg_id, lk, sid, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)msg_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + } + +#ifndef _LKSCTP + m2ua_sctp_opt_data.sid_val = sid; + m2ua_sctp_data.buf = (BYTE *)msg_ptr; + m2ua_sctp_optdata_req(m2ua_sg_info[sg_id].fd, sg_id, len); +#else + m2ua_sctp_data.sid = sid; + m2ua_sctp_data.buf = (BYTE *)msg_ptr; + m2ua_sctp_optdata_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, len); +#endif + + return len; +} + +int m2ua_find_link_by_sg_iid(WORD sg_id, WORD iid) +{ + int i; + lk_para_t *lk_para; + + lk_para = &m2ua_para.lk_para[0]; + + for (i = 0; i < M2UA_MAX_LK_NUM; i++) + { + if (m2ua_lk_info[i].enable && (lk_para->lk_sg%256 == sg_id%256) && (lk_para->iid == iid)) + return i; + lk_para++; + } + + return -1; +} + + +int m2ua_dec_par(WORD sg_id, m2ua_var_par_t *par_ptr, WORD par_type) +{ + WORD len = 0, hdr_len; + DWORD *dw_ptr; + WORD *w_ptr; + int iid; + + hdr_len = ntohs(par_ptr->hdr.len); + + switch (par_type) + { + case M2UA_PAR_INTERFACE_ID_INT: + { + if ((par_ptr->hdr.tag != htons(M2UA_PAR_INTERFACE_ID_INT)) && + (par_ptr->hdr.tag != htons(M2UA_PAR_INTERFACE_ID_TXT))) + return 0; + else if (par_ptr->hdr.tag != htons(M2UA_PAR_INTERFACE_ID_INT)) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_IIT; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } +// else if (hdr_len % 4) +// { +// m2ua_sg_info[sg_id].err_code = M2UA_ERR_PARA_FIELD_ERROR; +// m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); +// return -1; +// } + else + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + iid = ntohl(*dw_ptr); + if ((iid = m2ua_find_link_by_sg_iid(sg_id, iid)) < 0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_IID; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + else + m2ua_sg_info[sg_id].iid = iid; + len = ((hdr_len + 3) & 0xFFFC); + } + break; + } + case M2UA_PAR_PROTO_DATA_1: + { + if (hdr_len <= (M2UA_MAX_MSG_LEN - 2)) + { + m2ua_sg_info[sg_id].msg = &par_ptr->val[0]; + m2ua_sg_info[sg_id].msg_len = hdr_len - sizeof(m2ua_par_hdr_t); + len = (hdr_len + 3) & 0xFFFC; + } + break; + } + case M2UA_PAR_CORRELATION_ID: + { + if (par_ptr->hdr.tag != htons(M2UA_PAR_CORRELATION_ID)) + m2ua_sg_info[sg_id].cor_id = 0; + else + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].cor_id = ntohl(*dw_ptr); + len = ((hdr_len + 3) & 0xFFFC); + } + break; + } + case M2UA_PAR_STATE: + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].state = ntohl(*dw_ptr); + if (m2ua_sg_info[sg_id].state > M2UA_STATUS_CONG_DISCARD) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_PARA_VAL; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + else + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case M2UA_PAR_STATUS: + { + WORD notify_state; + DWORD asp_id; + + w_ptr = (WORD *) &par_ptr->val[0]; + notify_state = ntohs(*w_ptr); + + dw_ptr = (DWORD *)&par_ptr->val[1]; + asp_id = ntohl(*dw_ptr); + + if (notify_state == M2UA_STATUS_TYPE_OTHER && asp_id == m2ua_sg_info[sg_id].asp_id) + { + + if (m2ua_sg_info[sg_id].m2ua_state == 3) + m2ua_csta.sg_csta[sg_id].sg_asp_dn_times++; + + m2ua_sg_info[sg_id].m2ua_state = 4;//takeover by other asp + m2ua_sg_info[sg_id].T_ack = 0; + m2ua_sg_info[sg_id].T_r = 0; + m2ua_sg_info[sg_id].up_lks_pre = m2ua_sg_info[sg_id].up_lks_cur = 0; + } + else + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case M2UA_PAR_TRAFFIC_MODE: + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].tra_hdl_mode = ntohl(*dw_ptr); + if(m2ua_sg_info[sg_id].tra_hdl_mode != m2ua_get_traffic_mode_type()+1) +// if (m2ua_sg_info[sg_id].tra_hdl_mode != M2UA_TRAFFIC_MODE_OVERRIDE && +// m2ua_sg_info[sg_id].tra_hdl_mode != M2UA_TRAFFIC_MODE_LOADSHARE ) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_TRA_HDL_MODE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return 0; + } + else + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case xUA_PAR_DLCI: + { + if (par_ptr->hdr.tag != htons(xUA_PAR_DLCI)) + m2ua_sg_info[sg_id].dlci = 0; + else + { + w_ptr = (WORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].dlci = ntohl(*w_ptr); + len = ((hdr_len + 3) & 0xFFFC); + } + break; + } + case xUA_PAR_REL_REASON: + { + if (par_ptr->hdr.tag != htons(xUA_PAR_REL_REASON)) + m2ua_sg_info[sg_id].rel_reason = 0; + else + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].rel_reason = ntohl(*dw_ptr); + len = ((hdr_len + 3) & 0xFFFC); + } + break; + } + case xUA_PAR_PROTOCOL_DATA: + { + if (hdr_len <= (M2UA_MAX_MSG_LEN - XUAHEADOFFSET)) + { + m2ua_sg_info[sg_id].msg = &par_ptr->val[0]; + m2ua_sg_info[sg_id].msg_len = hdr_len - sizeof(m2ua_par_hdr_t); + len = (hdr_len + 3) & 0xFFFC; + } + break; + } + + case M3UA_Network_Appearance: + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].net_app = ntohl(*dw_ptr); + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case xUA_Routing_Context: + { + int RCn,ii; + RCn = ((hdr_len- 4 + 3) & 0xFFFC) >> 2; + for(ii=0;iival[ii*4]; + m2ua_sg_info[sg_id].rc = ntohl(*dw_ptr); + if(rc_verify(sg_id)>0) + { + if (m2ua_sg_info[sg_id].m2ua_state == 3) + { + switch(m2ua_sg_info[sg_id].m2ua_cmd) + { + case M2UA_ASPTM_ASP_ACTIVE_ACK: + m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_UP); + break; + case M2UA_ASPTM_ASP_ACTIVE: + m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_UP); + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE_ACK); + if(m2ua_sg_info[sg_id].status != ((M2UA_STATUS_TYPE_AS_STATE_CHG << 16)|M2UA_STATUS_INFO_AS_ACTIVE)) + { + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16)|M2UA_STATUS_INFO_AS_ACTIVE; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + } + break; + case M2UA_ASPTM_ASP_INACTIVE: + m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_DOWN); + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE_ACK); + if(m2ua_sg_info[sg_id].status != ((M2UA_STATUS_TYPE_AS_STATE_CHG << 16)|M2UA_STATUS_INFO_AS_PENDING)) + { + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_PENDING; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + } + break; + case M3UA_SSNM_DUNA: + //m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_DOWN); + break; + case M3UA_SSNM_DAVA: + //m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_UP); + break; + case M3UA_MAUP_DATA: + break; + } + } + } + else + { + m2ua_sg_info[sg_id].err_code = M3UA_ERR_INVALID_RC; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + } + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case M3UA_Protocol_Data: + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].opc = ntohl(*dw_ptr); + + dw_ptr = (DWORD *) &par_ptr->val[4]; + m2ua_sg_info[sg_id].dpc = ntohl(*dw_ptr); + + m2ua_sg_info[sg_id].si = par_ptr->val[8]; + m2ua_sg_info[sg_id].ni = par_ptr->val[9]; + m2ua_sg_info[sg_id].mp = par_ptr->val[10]; + m2ua_sg_info[sg_id].sls = par_ptr->val[11]; + + m2ua_sg_info[sg_id].msg = &par_ptr->val[12]; + + if (hdr_len > (M2UA_MAX_MSG_LEN - 2)) + hdr_len = M2UA_MAX_MSG_LEN - 2; + if(hdr_len< 12 + sizeof(m2ua_par_hdr_t))//12==opc+dpc+SI+ NI + MP + SLS + m2ua_sg_info[sg_id].msg_len = 0; + else + m2ua_sg_info[sg_id].msg_len = hdr_len - 12 - sizeof(m2ua_par_hdr_t); + len = (hdr_len + 3) & 0xFFFC; + break; + } + case xUA_Affected_PC: + { + int PCn,ii; + BYTE type; + PCn = ((hdr_len- 4 + 3) & 0xFFFC) >> 2; + type = m2ua_sg_info[sg_id].m2ua_cmd &0xff; + for(ii=0;iival[ii*4]; + m2ua_sg_info[sg_id].aff_pc = ntohl(*dw_ptr); + if (m2ua_sg_info[sg_id].m2ua_state == 3) + { + m3ua_sd_mtp3_user_ssnm_cmd(sg_id, type); + } + } + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case M3UA_User_Cause: + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].user_cause = ntohl(*dw_ptr); + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case M3UA_Congestion_Indications: + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].cong_ind = ntohl(*dw_ptr); + len = ((hdr_len + 3) & 0xFFFC); + break; + } + case M3UA_Concerned_Destination: + { + dw_ptr = (DWORD *) &par_ptr->val[0]; + m2ua_sg_info[sg_id].con_dpc = ntohl(*dw_ptr); + len = ((hdr_len + 3) & 0xFFFC); + break; + } + default: + break; + } + + return len; +} + +int xua_get_par(WORD sg_id, BYTE *msg,WORD len, WORD par_type) +{ + WORD par_start,hdr_len,par_len; + int ret_len; + m2ua_var_par_t *par_ptr; + + if (len > sizeof(m2ua_comhdr_t)) + len -= sizeof(m2ua_comhdr_t); + else if(len == sizeof(m2ua_comhdr_t)) + return 0; + else + return -1; + + for(par_start=0;par_starthdr.tag == htons(par_type)) + { + if((ret_len=m2ua_dec_par(sg_id, par_ptr, par_type))) + return ret_len;//-1 or len non-zore + } + hdr_len = ntohs(par_ptr->hdr.len); + par_len = ((hdr_len + 3) & 0xFFFC); + if(par_lencomhdr.msg_class; + msg_type = msg_ptr->comhdr.msg_type; + comm_len = ntohl(msg_ptr->comhdr.len); + + server = m2ua_para.sg_para[sg_id].server; + m2ua_state = m2ua_sg_info[sg_id].m2ua_state; + + if ((moniter_fg & MONITOR_M2UA) == MONITOR_M2UA) + { + if (m2ua_sg_mon_fg[sg_id] == 1) + { + sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, msg_len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + flag = 1; + } + } + + if (msg_ptr->comhdr.version != 1) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_VERSION; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } +// else if (comm_len % 4) +// { +// m2ua_sg_info[sg_id].err_code = M2UA_ERR_PARA_FIELD_ERROR; +// m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); +// return -1; +// } + + err[6]++; + + switch (msg_class) + { + case M2UA_MCLASS_MGMT: + { + err[7]++; + //if ((msg_type != ERROR) && (msg_type != NOTIFY)) + if ((msg_type > TEI_S_IND)) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + else if ((msg_type == xUA_NOTIFY))// && server) + { + m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_STATUS); + //m2ua_sg_info[sg_id].err_code = M2UA_ERR_PROTOCOL_ERROR; + //m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + else if (msg_type == xUA_ERROR) + msg = M2UA_MGMT_ERROR; + break; + } + case M2UA_MCLASS_ASPSM: + { + err[8]++; + switch (msg_type) + { + case ASP_UP: + msg = M2UA_ASPSM_ASP_UP; + break; + case ASP_DOWN: + msg = M2UA_ASPSM_ASP_DOWN; + break; + case HEARTBEAT: + { + m2ua_msg_t *sendmsg_ptr; + sendmsg_ptr = (m2ua_msg_t *)m2ua_sctp_dat_send; + memcpy(sendmsg_ptr->msg,msg_ptr->msg,msg_len); + } + m2ua_sg_info[sg_id].msg_len = msg_len; + m2ua_send_msg(sg_id, M2UA_ASPSM_HEARTBEAT_ACK); + break; + case ASP_UP_ACK: + msg = M2UA_ASPSM_ASP_UP_ACK; + break; + case ASP_DOWN_ACK: + msg = M2UA_ASPSM_ASP_DOWN_ACK; + break; + case HEARTBEAT_ACK: + msg = M2UA_ASPSM_HEARTBEAT_ACK; + break; + default: + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + break; + } + break; + } + case M2UA_MCLASS_ASPTM: + { + err[9]++; + switch (msg_type) + { + case ASP_ACTIVE: + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, M2UA_PAR_TRAFFIC_MODE); + if(par_len <=0) + { + m2ua_sg_info[sg_id].m2ua_cmd = ASP_DOWN; + return -1; + + } + + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1)==M3UA_APP) + { + m2ua_sg_info[sg_id].m2ua_cmd = (msg_class << 8) + msg_type; + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Routing_Context); + if(par_len==0) + { + m2ua_sg_info[sg_id].rc = 0; + if(rc_verify(sg_id)>0) + { + if (m2ua_sg_info[sg_id].m2ua_state == 3) + { + m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_UP); + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE_ACK); + if(m2ua_sg_info[sg_id].status != ((M2UA_STATUS_TYPE_AS_STATE_CHG << 16)|M2UA_STATUS_INFO_AS_ACTIVE)) + { + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16)|M2UA_STATUS_INFO_AS_ACTIVE; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + } + } + } + else + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + } + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return 0; + } + msg = M2UA_ASPTM_ASP_ACTIVE; + break; + case ASP_INACTIVE: + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1)==M3UA_APP) + { + m2ua_sg_info[sg_id].m2ua_cmd = (msg_class << 8) + msg_type; + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Routing_Context); + if(par_len==0) + { + m2ua_sg_info[sg_id].rc = 0; + if(rc_verify(sg_id)>0) + { + if (m2ua_sg_info[sg_id].m2ua_state == 3) + { + m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_DOWN); + m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE_ACK); + if(m2ua_sg_info[sg_id].status != ((M2UA_STATUS_TYPE_AS_STATE_CHG << 16)|M2UA_STATUS_INFO_AS_PENDING)) + { + m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_PENDING; + m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY); + } + } + } + else + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + } + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return 0; + } + msg = M2UA_ASPTM_ASP_INACTIVE; + break; + case ASP_ACTIVE_ACK: + msg = M2UA_ASPTM_ASP_ACTIVE_ACK; + if ((m2ua_para.sg_para[sg_id].xUA_ack>>1)==M3UA_APP) + { + m2ua_sg_info[sg_id].m2ua_cmd = (msg_class << 8) + msg_type; + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Routing_Context); + if(par_len==0) + { + m2ua_sg_info[sg_id].rc = 0; + if(rc_verify(sg_id)>0) + { + if (m2ua_sg_info[sg_id].m2ua_state == 3) + m3ua_sd_mtp3_user_rc_cmd(sg_id, M3UA_RC_UP); + } + else + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + } + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return 0; + } + break; + case ASP_INACTIVE_ACK: + msg = M2UA_ASPTM_ASP_INACTIVE_ACK; + break; + default: + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + break; + } + break; + } + case M2UA_MCLASS_MAUP: + { + err[10]++; + if (m2ua_state != 3||(m2ua_para.sg_para[sg_id].xUA_ack>>1)!=M2UA_APP) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_INTERFACE_ID_INT); + if (par_len <= 0) + { + if (par_len == 0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + return -1; + } + + iid = m2ua_sg_info[sg_id].iid; + msg_sg = m2ua_para.lk_para[iid].lk_sg; + + if ((iid >= M2UA_MAX_LK_NUM) || + (msg_sg != sg_id)) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_IID; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + + err[11]++; + + if (((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) && !flag) + { + if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[iid] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, lk=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, iid, msg_len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + switch (msg_type) + { + case DATA: + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_PROTO_DATA_1); + if (par_len > 0) + { + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_CORRELATION_ID); + msg = M2UA_MAUP_DATA; + + mtp3_msg_len = m2ua_sg_info[sg_id].msg_len; + m2ua_csta.sg_csta[sg_id].sg_in_msg++; + m2ua_csta.lk_csta[iid].lk_in_msg++; + m2ua_csta.sg_csta[sg_id].sg_in_bytes += mtp3_msg_len; + m2ua_csta.lk_csta[iid].lk_in_bytes += mtp3_msg_len; + err[12]++; + } + break; + case ESTABLISH_REQ: + msg = M2UA_MAUP_ESTABLISH_REQ; + break; + case ESTABLISH_CFM: + msg = M2UA_MAUP_ESTABLISH_CFM; + break; + case RELEASE_REQ: + msg = M2UA_MAUP_RELEASE_REQ; + break; + case RELEASE_CFM: + msg = M2UA_MAUP_RELEASE_CFM; + break; + case RELEASE_IND: + msg = M2UA_MAUP_RELEASE_IND; + break; + case STATE_REQ: + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_STATE); + if (par_len) + msg = M2UA_MAUP_STATE_REQ; + break; + case STATE_CFM: + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_STATE); + break; + case STATE_IND: + case DATA_ACK: + break; + default: + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + break; + } + break; + } + case xUA_MCLASS_QPTM: + { + err[10]++; + if (m2ua_state != 3||(m2ua_para.sg_para[sg_id].xUA_ack>>1)!=IUA_APP) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_INTERFACE_ID_INT); + if (par_len <= 0) + { + if (par_len == 0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + return -1; + } + + iid = m2ua_sg_info[sg_id].iid; + msg_sg = m2ua_para.lk_para[iid].lk_sg; + + + if ((iid >= M2UA_MAX_LK_NUM) || + (msg_sg != sg_id)) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_IID; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_DLCI); + if (par_len <= 0) + { + if (par_len == 0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + } + return -1; + } + err[11]++; + + if (((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) && !flag) + { + if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[iid] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, lk=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, iid, msg_len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + switch (msg_type) + { + case IUA_DATA_REQ: + case IUA_DATA_IND: + case IUA_UDATA_REQ: + case IUA_UDATA_IND: + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_PROTOCOL_DATA); + if (par_len > 0) + { + msg = (xUA_MCLASS_QPTM << 8) + msg_type; + + mtp3_msg_len = m2ua_sg_info[sg_id].msg_len; + m2ua_csta.sg_csta[sg_id].sg_in_msg++; + m2ua_csta.lk_csta[iid].lk_in_msg++; + m2ua_csta.sg_csta[sg_id].sg_in_bytes += mtp3_msg_len; + m2ua_csta.lk_csta[iid].lk_in_bytes += mtp3_msg_len; + err[12]++; + } + break; + case IUA_ESTABLISH_REQ: + msg = IUA_QPTM_ESTABLISH_REQ; + break; + case IUA_ESTABLISH_CFM: + msg = IUA_QPTM_ESTABLISH_CFM; + break; + case IUA_ESTABLISH_IND: + msg = IUA_QPTM_ESTABLISH_IND; + break; + case IUA_RELEASE_REQ: + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_REL_REASON); + if (par_len) + msg = IUA_QPTM_RELEASE_REQ; + break; + case IUA_RELEASE_CFM: + par_start += par_len; + par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_REL_REASON); + if (par_len) + msg = IUA_QPTM_RELEASE_CFM; + break; + case IUA_RELEASE_IND: + msg = IUA_QPTM_RELEASE_IND; + break; + default: + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + break; + } + break; + } + case xUA_MCLASS_TRMSG: + { + err[10]++; + if (m2ua_state != 3||(m2ua_para.sg_para[sg_id].xUA_ack>>1)!=M3UA_APP) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + + iid = m2ua_sg_info[sg_id].iid; + if (((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) && !flag) + { + if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[iid] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, lk=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, iid, msg_len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + switch (msg_type) + { + case M3UA_DATA: + m2ua_sg_info[sg_id].m2ua_cmd = (msg_class << 8) + msg_type; + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, M3UA_Network_Appearance); + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Routing_Context); + if(par_len==0) + { + m2ua_sg_info[sg_id].rc = 0; + if(rc_verify(sg_id)>0) + { + ; + } + else + { + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + } + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, M3UA_Protocol_Data); + if (par_len > 0) + { + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_PAR_CORRELATION_ID);//for broadcast + msg = (msg_class << 8) + msg_type; + mtp3_msg_len = m2ua_sg_info[sg_id].msg_len; + m2ua_csta.sg_csta[sg_id].sg_in_msg++; + m2ua_csta.sg_csta[sg_id].sg_in_bytes += mtp3_msg_len; + err[12]++; + } + else + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + break; + default: + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + break; + } + break; + } + case xUA_MCLASS_SSNM: + { + err[10]++; + if (m2ua_state != 3||(m2ua_para.sg_para[sg_id].xUA_ack>>1)!=M3UA_APP) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + return -1; + } + + if (((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) && !flag) + { + if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[iid] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, lk=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, iid, msg_len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + m2ua_sg_info[sg_id].m2ua_cmd = (msg_class << 8) + msg_type; + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, M3UA_Network_Appearance); + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Routing_Context); + if(par_len==0) + { + m2ua_sg_info[sg_id].rc = 0; + if(rc_verify(sg_id)>0) + { + ; + } + else + { + if(msg_type != SSNM_DUNA && msg_type !=SSNM_DAVA)//RC is optional + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + } + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + + switch (msg_type) + { + case SSNM_DUNA: + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Affected_PC); + if (par_len==0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + msg = (msg_class << 8) + msg_type; + break; + case SSNM_DAVA: + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Affected_PC); + if (par_len==0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + msg = (msg_class << 8) + msg_type; + break; + case SSNM_DAUD: + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Affected_PC); + if (par_len==0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + msg = (msg_class << 8) + msg_type; + break; + case SSNM_SCON: + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Affected_PC); + if (par_len==0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + msg = (msg_class << 8) + msg_type; + break; + case SSNM_DUPU: + par_start += par_len; + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, M3UA_User_Cause); + if (par_len==0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Affected_PC); + if (par_len==0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + msg = (msg_class << 8) + msg_type; + break; + case SSNM_DRST: + msg = (msg_class << 8) + msg_type; + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, M3UA_Congestion_Indications); + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, M3UA_Concerned_Destination); + par_len = xua_get_par(sg_id, msg_ptr->msg,msg_len, xUA_Affected_PC); + if (par_len==0) + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + else if(par_len<0) + { + m2ua_sg_info[sg_id].m2ua_cmd = 0; + return -1; + } + break; + default: + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + break; + } + break; + } + default: + { + m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_CLASS; + m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); + m2ua_sg_info[sg_id].m2ua_cmd = 0; + break; + } + } + + if (msg != M2UA_CMD_IDLEW) + { + m2ua_sg_info[sg_id].m2ua_cmd = msg; + return 0; + } + else + return -1; +} + +int m2ua_sd_mtp3_primi(WORD lk, BYTE primi) +{ + m2ua_up_msg_t *up_ptr; + + if (((m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m2ua_mtp3_sd_t) + return -1; + + up_ptr = (m2ua_up_msg_t *) (m2ua_mtp3_sd + x256[m2ua_mtp3_sd_h]); + up_ptr->link = lk; + up_ptr->len = htons(4); + up_ptr->sio = M2UA_SIO_CMD; + up_ptr->msg.lm.mtp3_ip = 0; + up_ptr->msg.lm.opercode = primi; + + if ((m2ua_lk_info[lk].lk_st == M2UA_LK_UP) && + (m2ua_lk_info[lk].alarm_code != M2UA_ALARM_CODE_NORMAL)) + m2ua_lk_info[lk].alarm_code = M2UA_ALARM_CODE_NORMAL; + up_ptr->msg.lm.alarmcode = m2ua_lk_info[lk].alarm_code; + + m2ua_mtp3_sd_h = (m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + + err[15]++; + + return 0; +} + +int m2ua_sd_mtp3_msg(WORD sg, WORD lk) +{ + BYTE *msg; + int len; + m2ua_up_msg_t *up_ptr; + + if (((m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m2ua_mtp3_sd_t) + return -1; + + len = m2ua_sg_info[sg].msg_len; + msg = m2ua_sg_info[sg].msg; + + up_ptr = (m2ua_up_msg_t *) (m2ua_mtp3_sd + x256[m2ua_mtp3_sd_h]); + up_ptr->link = lk; + up_ptr->len = htons(len); + up_ptr->sio = *msg; + + bcopy(msg + 1, up_ptr->msg.mtp3.content, len); + + m2ua_mtp3_sd_h = (m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + + err[14]++; + + return 1; +} + +int iua_sd_q931_primi(WORD lk, BYTE primi) +{ + xua_up_msg_t *up_ptr; + + if (((iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == iua_q931_sd_t) + return -1; + + up_ptr = (xua_up_msg_t *) (iua_q931_sd + x256[iua_q931_sd_h]); + up_ptr->msg_class = IUA_MGMT_CMD; + + up_ptr->msg.lm_lk.link = lk; + up_ptr->msg.lm_lk.len = htons(3); + up_ptr->msg.lm_lk.mtp3_ip = 0; + up_ptr->msg.lm_lk.opercode = primi; + + if ((m2ua_lk_info[lk].lk_st == M2UA_LK_UP) && + (m2ua_lk_info[lk].alarm_code != M2UA_ALARM_CODE_NORMAL)) + m2ua_lk_info[lk].alarm_code = M2UA_ALARM_CODE_NORMAL; + + + iua_q931_sd_h = (iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + + err[15]++; + + return 0; +} + +int iua_sd_q931_msg(WORD sg, WORD lk) +{ + BYTE *msg; + int len; + xua_up_msg_t *up_ptr; + + if (((iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == iua_q931_sd_t) + return -1; + + len = m2ua_sg_info[sg].msg_len; + msg = m2ua_sg_info[sg].msg; + + up_ptr = (xua_up_msg_t *) (iua_q931_sd + x256[iua_q931_sd_h]); + up_ptr->msg_class = IUA_QPTM_MSG; + + up_ptr->msg.iua.link = lk; + up_ptr->msg.iua.len = htons(len); + bcopy(msg, up_ptr->msg.iua.content, len); + + iua_q931_sd_h = (iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + + err[14]++; + + return 1; +} + + +int m3ua_sd_mtp3_user_primi(WORD lk, BYTE primi) +{ + xua_up_msg_t *up_ptr; + + if (((m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m3ua_mtp3_sd_t) + return -1; + + up_ptr = (xua_up_msg_t *) (m3ua_mtp3_sd + x256[m3ua_mtp3_sd_h]); + up_ptr->msg_class = M3UA_MGMT_CMD; + + up_ptr->msg.lm_lk.link = lk; + up_ptr->msg.lm_lk.len = htons(3); + up_ptr->msg.lm_lk.mtp3_ip = 0; + up_ptr->msg.lm_lk.opercode = primi; + //up_ptr->msg.lm_lk.alarmcode = m2ua_lk_info[lk].alarm_code; + + m3ua_mtp3_sd_h = (m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + + return 0; +} + +int m3ua_sd_mtp3_user_ssnm_cmd(WORD sg, BYTE primi) +{ + xua_up_msg_t *up_ptr; + WORD lk; + + for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) + { + if ((m2ua_para.lk_para[lk].lk_sg == sg) && + m2ua_lk_info[lk].enable) + { + if (((m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m3ua_mtp3_sd_t) + return -1; + + up_ptr = (xua_up_msg_t *) (m3ua_mtp3_sd + x256[m3ua_mtp3_sd_h]); + up_ptr->msg_class = M3UA_SSNM_CMD; + + up_ptr->msg.ssnm_cmd.link = lk; + up_ptr->msg.ssnm_cmd.len = htons(17); + up_ptr->msg.ssnm_cmd.type = primi; + up_ptr->msg.ssnm_cmd.aff_pc = m2ua_sg_info[sg].aff_pc; + up_ptr->msg.ssnm_cmd.user_cause = m2ua_sg_info[sg].user_cause; + up_ptr->msg.ssnm_cmd.cong_ind = m2ua_sg_info[sg].cong_ind; + up_ptr->msg.ssnm_cmd.con_dpc = m2ua_sg_info[sg].con_dpc; + + m3ua_mtp3_sd_h = (m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + } + } + return 0; +} + +int m3ua_sd_mtp3_user_rc_cmd(WORD sg, BYTE primi) +{ + xua_up_msg_t *up_ptr; + WORD lk; + + for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) + { + if ((m2ua_para.lk_para[lk].lk_sg == sg) && + m2ua_lk_info[lk].enable) + { + if (((m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m3ua_mtp3_sd_t) + return -1; + + up_ptr = (xua_up_msg_t *) (m3ua_mtp3_sd + x256[m3ua_mtp3_sd_h]); + up_ptr->msg_class = M3UA_RC_CMD; + + up_ptr->msg.rc_cmd.link = lk; + up_ptr->msg.rc_cmd.len = htons(5); + up_ptr->msg.rc_cmd.opercode = primi; + up_ptr->msg.rc_cmd.rc = m2ua_sg_info[sg].rc; + + m3ua_mtp3_sd_h = (m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + } + } + return 0; +} + +int m3ua_sd_mtp3_user_msg(WORD sg) +{ + BYTE *msg; + int len; + xua_up_msg_t *up_ptr; + + if (((m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m3ua_mtp3_sd_t) + return -1; + + len = m2ua_sg_info[sg].msg_len; + msg = m2ua_sg_info[sg].msg; + up_ptr = (xua_up_msg_t *) (m3ua_mtp3_sd + x256[m3ua_mtp3_sd_h]); + up_ptr->msg_class = M3UA_MAUP_MSG; + + up_ptr->msg.m3ua.rc = m2ua_sg_info[sg].rc; + up_ptr->msg.m3ua.dpc = m2ua_sg_info[sg].dpc; + up_ptr->msg.m3ua.opc = m2ua_sg_info[sg].opc; + up_ptr->msg.m3ua.sls = m2ua_sg_info[sg].sls; + up_ptr->msg.m3ua.mp = m2ua_sg_info[sg].mp; + up_ptr->msg.m3ua.ni = m2ua_sg_info[sg].ni; + up_ptr->msg.m3ua.si = m2ua_sg_info[sg].si; + + up_ptr->msg.m3ua.len = htons(len); + bcopy(msg, up_ptr->msg.m3ua.content, len); + + m3ua_mtp3_sd_h = (m3ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; + return 0; +} + + +int m2ua_sg_init(WORD id) +{ + bzero((BYTE *)&m2ua_sg_info[id], sizeof(m2ua_sg_info_t)); + + m2ua_sg_info[id].m2ua_cmd = M2UA_CMD_IDLEW; + m2ua_sg_info[id].sctp_cmd = M2UA_CMD_IDLEW; + m2ua_sg_info[id].mtp3_cmd = M2UA_CMD_IDLEW; + m2ua_sg_info[id].mgmt_cmd = M2UA_CMD_IDLEW; + + return 0; +} + +int m2ua_lk_init(WORD id) +{ + WORD lk_sg; + + bzero(&m2ua_lk_info[id], sizeof(m2ua_lk_info_t)); + + lk_sg = m2ua_para.lk_para[id].lk_sg; + if (m2ua_sg_info[lk_sg].m2ua_state == 3) + m2ua_lk_info[id].lk_st = M2UA_LK_DOWN; + else + m2ua_lk_info[id].lk_st = M2UA_LK_IDLE; + + return 0; +} + +int enable_sg(WORD sg) +{ + int fd; + + if (m2ua_para.sg_para[sg].enable && + (m2ua_sg_info[sg].fd == 0)) + { +#ifndef _LKSCTP + if ((fd = m2ua_sctp_t_open(sg)) <= 0) + { + m2ua_log_err(sg, "enable sg, open sctp fail!"); + return -1; + } + else + { + m2ua_sg_init(sg); + m2ua_sg_info[sg].fd = fd; + m2ua_sg_info[sg].enable = 1; + } +#else + if (!m2ua_para.sg_para[sg].server) + { + if ((fd = m2ua_sctp_open_lksctp(sg)) <= 0) + { + m2ua_log_err(sg, "enable sg, open sctp fail!"); + return -1; + } + m2ua_sg_init(sg); + m2ua_sg_info[sg].fd = fd; + } + else if (!m2ua_sg_info[sg].enable) + m2ua_sg_init(sg); + m2ua_sg_info[sg].enable = 1; +#endif + } + + return 0; +} + +int rm_sg_lk(WORD sg, WORD lk) +{ + int fd; + + rel_sid(sg, lk); + + if (--m2ua_sg_info[sg].act_lks == 0) + { + fd = m2ua_sg_info[sg].fd; + if (fd > 0) + { +#ifndef _LKSCTP + if ((m2ua_sg_info[sg].sctp_state > 2) || + ((m2ua_sg_info[sg].sctp_state == 2) && + (m2ua_sg_info[sg].sctp_state_1 > 0))) + m2ua_sctp_discon_req(fd, sg, 0); + m2ua_sctp_close(fd, sg); +#else + if ((m2ua_sg_info[sg].sctp_state > 2) || + ((m2ua_sg_info[sg].sctp_state == 2) && + (m2ua_sg_info[sg].sctp_state_1 > 0))) + m2ua_sctp_discon_req_lksctp(fd, sg, 0); +#endif + } + m2ua_sg_init(sg); + } + + return 0; +} + +int get_m2ua_msg(m2ua_up_msg_t **data_ptr) +{ + m2ua_up_msg_t *up_ptr; + WORD lk; + int len; + WORD sg; + + if (m2ua_mtp3_sd_t == m2ua_mtp3_sd_h) + return -1; + + up_ptr = (m2ua_up_msg_t *)(m2ua_mtp3_sd + x256[m2ua_mtp3_sd_t]); + lk = up_ptr->link; + len = ntohs(up_ptr->len) + M2UAHEADOFFSET; + sg = m2ua_para.lk_para[lk].lk_sg; + *data_ptr = up_ptr; + + m2ua_mtp3_sd_t = (m2ua_mtp3_sd_t + 1) & M2UA_MAX_M3MSG_NUM_1; + + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Send MSG to MTP3, sg=%d, lk=%d, len=%d\n\r", sg, lk, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)up_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + err[16]++; + + return 0; +} + +int put_m2ua_msg(m2ua_up_msg_t *data_ptr) +{ + WORD lk; + int len; + WORD sg; + + lk = data_ptr->link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = ntohs(data_ptr->len); + err[0]++; + + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MSG from MTP3, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+M2UAHEADOFFSET); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len+M2UAHEADOFFSET, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + if ((m2ua_para.sg_para[sg].xUA_ack>>1) != M2UA_APP) + { + m2ua_log_err(sg, "ERROR: SG type is not m2ua!"); + return -1; + } + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + + if (data_ptr->sio == M2UA_MTP3_SIO_CMD) + { + err[1]++; + if ((data_ptr->msg.lm.opercode == M2UA_ENABLE_M2UA_LINK) && + (!m2ua_lk_info[lk].enable)) + { + if (enable_sg(sg) < 0) + return -1; + + m2ua_lk_init(lk); + m2ua_lk_info[lk].enable = 1; + m2ua_sg_info[sg].act_lks++; + } + else if ((data_ptr->msg.lm.opercode == M2UA_STOP_M2UA_LINK) && + m2ua_lk_info[lk].enable) + { + if (m2ua_sg_info[sg].m2ua_state == 3) + { + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].mgmt_cmd = M2UA_MGMT_CMD_LK_LOCK; + m2ua_fsm(sg); + } + + rm_sg_lk(sg, lk); + m2ua_lk_init(lk); + + m2ua_lk_info[lk].enable = 0; + } + else if ((m2ua_sg_info[sg].m2ua_state == 3) && m2ua_lk_info[lk].enable) + { + m2ua_sg_info[sg].mtp3_cmd = data_ptr->msg.lm.opercode; + m2ua_sg_info[sg].iid = lk; + m2ua_fsm(sg); + } + return 0; + } + else if (m2ua_lk_info[lk].lk_st == M2UA_LK_UP) + { + err[2]++; + if (len <= (M2UA_MAX_MSG_LEN - 2)) + { + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].msg = (BYTE *)data_ptr - M2UARESERVEHEAD; + m2ua_sg_info[sg].msg_len = len; + m2ua_send_msg(sg, M2UA_MAUP_DATA); + err[4]++; + return 0; + } + } + + return -1; +} + +int get_xua_msg(BYTE xUA_type, xua_up_msg_t **data_ptr) +{ + xua_up_msg_t *up_ptr; + WORD lk; + int len,msg_len; + BYTE *xua_msg_sd; + WORD sg, *xua_sd_h, *xua_sd_t; + + if(data_ptr == NULL) + return -1; + + switch (xUA_type) + { + case M2UA_APP: + return -1;//reserve + xua_msg_sd = m2ua_mtp3_sd; + xua_sd_t = &m2ua_mtp3_sd_t; + xua_sd_h = &m2ua_mtp3_sd_h; + break; + case IUA_APP: + xua_msg_sd = iua_q931_sd; + xua_sd_t = &iua_q931_sd_t; + xua_sd_h = &iua_q931_sd_h; + break; + case M3UA_APP: + xua_msg_sd = m3ua_mtp3_sd; + xua_sd_t = &m3ua_mtp3_sd_t; + xua_sd_h = &m3ua_mtp3_sd_h; + break; + default: + return -1; + } + if (*xua_sd_t == *xua_sd_h) + return -1; + + up_ptr = (xua_up_msg_t *)(xua_msg_sd + x256[*xua_sd_t]); + lk = up_ptr->msg.lm_lk.link; + len = ntohs(up_ptr->msg.lm_lk.len); + sg = m2ua_para.lk_para[lk].lk_sg; + *data_ptr = up_ptr; + + *xua_sd_t = (*xua_sd_t + 1) & M2UA_MAX_M3MSG_NUM_1; + + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Send MSG to UP LAYER, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+XUAHEADOFFSET); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)up_ptr, len+XUAHEADOFFSET, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + err[16]++; + msg_len = len+XUAHEADOFFSET; + return msg_len; +} + +int put_xua_msg(xua_up_msg_t *data_ptr) +{ + BYTE server; + int len; + WORD lk,sg; + if(data_ptr == NULL) + return -1; + + switch (data_ptr->msg_class) + { + case M2UA_MGMT_CMD: + case IUA_MGMT_CMD: + { + lk = data_ptr->msg.lm_lk.link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = ntohs(data_ptr->msg.lm_lk.len); + err[0]++; + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MSG from upper layer, sg=%d, lk=%d, len=%d\n\r", sg, lk, len + XUAHEADOFFSET); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len + XUAHEADOFFSET, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + + err[1]++; + if ((data_ptr->msg.lm_lk.opercode == xUA_ENABLE_xUA_LINK) && + (!m2ua_lk_info[lk].enable)) + { + if (enable_sg(sg) < 0) + return -1; + + m2ua_lk_init(lk); + m2ua_lk_info[lk].enable = 1; + m2ua_sg_info[sg].act_lks++; + } + else if ((data_ptr->msg.lm_lk.opercode == xUA_STOP_xUA_LINK) && + m2ua_lk_info[lk].enable) + { + if (m2ua_sg_info[sg].m2ua_state == 3) + { + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].mgmt_cmd = COMBO_W(data_ptr->msg_class,M2UA_MGMT_CMD_LK_LOCK); + m2ua_fsm(sg); + } + + rm_sg_lk(sg, lk); + m2ua_lk_init(lk); + + m2ua_lk_info[lk].enable = 0; + } + else if ((m2ua_sg_info[sg].m2ua_state == 3) && m2ua_lk_info[lk].enable) + { + m2ua_sg_info[sg].mtp3_cmd = COMBO_W(data_ptr->msg_class,data_ptr->msg.lm_lk.opercode); + m2ua_sg_info[sg].iid = lk; + m2ua_fsm(sg); + } + return 0; + } + case IUA_QPTM_MSG: + { + lk = data_ptr->msg.iua.link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = ntohs(data_ptr->msg.iua.len); + if ((m2ua_para.sg_para[sg].xUA_ack>>1) != IUA_APP) + { + m2ua_log_err(sg, "ERROR: SG type is not iua!"); + return -1; + } + err[0]++; + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MSG from Q931, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+XUAHEADOFFSET); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len+XUAHEADOFFSET, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + if (m2ua_lk_info[lk].lk_st == M2UA_LK_UP) + { + err[2]++; + if (len <= (M2UA_MAX_MSG_LEN - XUAHEADOFFSET)) + { + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].msg = (BYTE *)data_ptr - RESERVE_FOR_IUAHEAD; + m2ua_sg_info[sg].msg_len = len; + server = m2ua_para.sg_para[sg].server; + if(server) + m2ua_send_msg(sg, IUA_QPTM_DATA_IND); + else + m2ua_send_msg(sg, IUA_QPTM_DATA_REQ); + err[4]++; + return 0; + } + } + break; + } + case M2UA_MAUP_MSG: + { + lk = data_ptr->msg.m2ua.link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = ntohs(data_ptr->msg.m2ua.len); + if ((m2ua_para.sg_para[sg].xUA_ack>>1) != M2UA_APP) + { + m2ua_log_err(sg, "ERROR: SG type is not m2ua!"); + return -1; + } + err[0]++; + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MSG from Q931, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+XUAHEADOFFSET); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len+XUAHEADOFFSET, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + if (m2ua_lk_info[lk].lk_st == M2UA_LK_UP) + { + err[2]++; + if (len <= (M2UA_MAX_MSG_LEN - XUAHEADOFFSET)) + { + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].msg = (BYTE *)data_ptr - RESERVE_FOR_M2UAHEAD; + m2ua_sg_info[sg].msg_len = len; + m2ua_send_msg(sg, M2UA_MAUP_DATA); + err[4]++; + return 0; + } + } + break; + } + default: + return -1; + } + return -1; +} + +int get_m3ua_msg(xua_up_msg_t **data_ptr) +{ + xua_up_msg_t *up_ptr; + WORD lk; + int len; + BYTE *xua_msg_sd; + WORD sg, *xua_sd_h, *xua_sd_t; + + if(data_ptr == NULL) + return -1; + + xua_msg_sd = m3ua_mtp3_sd; + xua_sd_t = &m3ua_mtp3_sd_t; + xua_sd_h = &m3ua_mtp3_sd_h; + + if (*xua_sd_t == *xua_sd_h) + return -1; + + up_ptr = (xua_up_msg_t *)(xua_msg_sd + x256[*xua_sd_t]); + *xua_sd_t = (*xua_sd_t + 1) & M2UA_MAX_M3MSG_NUM_1; + + + lk = up_ptr->msg.m3ua.link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = ntohs(up_ptr->msg.m3ua.len); + + *data_ptr = up_ptr; + + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Send MSG to MTP3-User, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+XUAHEADOFFSET); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)up_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + return 0; +} + +int put_m3ua_msg(xua_up_msg_t *data_ptr) +{ + WORD lk; + int len; + WORD sg; + if(data_ptr == NULL) + return -1; + + switch (data_ptr->msg_class) + { + case M3UA_MGMT_CMD: + { + lk = data_ptr->msg.lm_lk.link; + sg = m2ua_para.lk_para[lk].lk_sg; + if ((m2ua_para.sg_para[sg].xUA_ack>>1) != M3UA_APP) + { + m2ua_log_err(sg, "ERROR: SG type is not m3ua!"); + return -1; + } + + len = 7; + + err[0]++; + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MSG from Mtp3-User, sg=%d, lk=%d, len=%d\n\r", sg, lk, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + + if ((data_ptr->msg.lm_lk.opercode == xUA_ENABLE_xUA_LINK) && + (!m2ua_lk_info[lk].enable)) + { + if (enable_sg(sg) < 0) + return -1; + + m2ua_lk_init(lk); + m2ua_lk_info[lk].enable = 1; + m2ua_sg_info[sg].act_lks++; + } + else if ((data_ptr->msg.lm_lk.opercode == xUA_STOP_xUA_LINK) && + m2ua_lk_info[lk].enable) + { + if (m2ua_sg_info[sg].m2ua_state == 3) + { + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].mgmt_cmd = COMBO_W(data_ptr->msg_class,M2UA_MGMT_CMD_LK_LOCK); + m2ua_fsm(sg); + } + + rm_sg_lk(sg, lk); + m2ua_lk_init(lk); + + m2ua_lk_info[lk].enable = 0; + } + else if ((m2ua_sg_info[sg].m2ua_state == 3) && m2ua_lk_info[lk].enable) + { + m2ua_sg_info[sg].mtp3_cmd = COMBO_W(data_ptr->msg_class,data_ptr->msg.lm_lk.opercode); + m2ua_sg_info[sg].iid = lk; + m2ua_fsm(sg); + } + return 0; + } + case M3UA_MAUP_MSG: + { + lk = data_ptr->msg.m3ua.link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = ntohs(data_ptr->msg.m3ua.len); + if ((m2ua_para.sg_para[sg].xUA_ack>>1) != M3UA_APP) + { + m2ua_log_err(sg, "ERROR: SG type is not m3ua!"); + return -1; + } + err[0]++; + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MSG from Mtp3-User, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+20); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len+20, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + if (m2ua_lk_info[lk].lk_st == M2UA_LK_UP) + { + if (len <= (M2UA_MAX_MSG_LEN - XUAHEADOFFSET)) + { + DWORD pc; + pc = ntohl(data_ptr->msg.m3ua.opc); + data_ptr->msg.m3ua.opc = pc; + pc = ntohl(data_ptr->msg.m3ua.dpc); + data_ptr->msg.m3ua.dpc = pc; + if(m2ua_sg_info[sg].ostrs>1) + m2ua_lk_info[lk].sid = data_ptr->msg.m3ua.sls%(m2ua_sg_info[sg].ostrs-1) +1; + else + m2ua_lk_info[lk].sid = 0; + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].rc = data_ptr->msg.m3ua.rc; + m2ua_sg_info[sg].msg = (BYTE *)data_ptr - RESERVE_FOR_M3UAHEAD; + if(m2ua_sg_info[sg].rc==0)//not send rc param + m2ua_sg_info[sg].msg = (BYTE *)data_ptr - RESERVE_FOR_M3UAHEAD + 8; + m2ua_sg_info[sg].msg_len = len; + m2ua_send_msg(sg, M3UA_MAUP_DATA); + return 0; + } + } + break; + } + case M3UA_RC_CMD: + { + lk = data_ptr->msg.rc_cmd.link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = 9; + if ((m2ua_para.sg_para[sg].xUA_ack>>1) != M3UA_APP) + { + m2ua_log_err(sg, "ERROR: SG type is not m3ua!"); + return -1; + } + err[0]++; + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MSG from Mtp3-User, sg=%d, lk=%d, len=%d\n\r", sg, lk, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + + if ((m2ua_sg_info[sg].m2ua_state == 3) && m2ua_lk_info[lk].enable) + { + m2ua_sg_info[sg].rc = data_ptr->msg.m3ua.rc; + m2ua_sg_info[sg].iid = lk; + m2ua_sg_info[sg].mtp3_cmd = COMBO_W(data_ptr->msg_class,data_ptr->msg.rc_cmd.opercode); + m2ua_fsm(sg); + } + return 0; + } + case M3UA_SSNM_CMD: + { + lk = data_ptr->msg.ssnm_cmd.link; + sg = m2ua_para.lk_para[lk].lk_sg; + len = 9; + if ((m2ua_para.sg_para[sg].xUA_ack>>1) != M3UA_APP) + { + m2ua_log_err(sg, "ERROR: SG type is not m3ua!"); + return -1; + } + err[0]++; + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv M3UA_SSNM_CMD from Mtp3-User, type=%d, sg=%d, lk=%d, len=%d\n\r",data_ptr->msg.ssnm_cmd.type, sg, lk, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)data_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + if (m2ua_para.lk_para[lk].enable == 0) + return -1; + if (m2ua_para.sg_para[sg].enable == 0) + return -1; + + if ((m2ua_lk_info[lk].lk_st == M2UA_LK_UP) && m2ua_lk_info[lk].enable) + { + m2ua_sg_info[sg].aff_pc = data_ptr->msg.ssnm_cmd.aff_pc; + m2ua_sg_info[sg].iid = lk; + // use receive m2ua_sg_info[sg].rc ; + m2ua_sg_info[sg].msg = (BYTE *)data_ptr - RESERVE_FOR_M3UAHEAD + 8; + m2ua_sg_info[sg].msg_len = 7; + + m2ua_send_msg(sg, (xUA_MCLASS_SSNM << 8) + data_ptr->msg.ssnm_cmd.type); + return 0; + } + break; + } + default: + return -1; + } + return -1; +} + +int set_m2ua_link(WORD link, BYTE *data_ptr) +{ + BYTE len; + WORD sg; + m2ua_lk_pro_t *m2ua_lk_pro = (m2ua_lk_pro_t *)data_ptr; + lk_para_t *lk_ptr; + + lk_ptr = (lk_para_t *) &m2ua_para.lk_para[link]; + sg = lk_ptr->lk_sg; + len = sizeof(m2ua_lk_pro_t); + + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[link] == 1)) + { + sprintf(m2ua_ascitemp_buf, "Recv MTP3 Set Link Attributes, sg=%d, lk=%d, len=%d\n\r", sg, link, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii((BYTE *)m2ua_lk_pro, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + /* + if (init_flag < 2) + { + lk_ptr->enable = (m2ua_lk_pro->e1_lk_type >> 1) & 0x01; + lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg; + lk_ptr->iid = m2ua_lk_pro->e1_to_iid; + if (link == 255) + init_flag++; + } + else + */ + { + if (lk_ptr->enable) + { +// if (m2ua_lk_pro->e1_lk_type & 0x01) // Bit 0: Link enable status, 0/1=disable/enable + if (m2ua_lk_pro->admin_state& 0x01) // Bit 0: Link enable status, 0/1=disable/enable + return -1; + //else if (m2ua_lk_pro->e1_to_sg != sg) + //return -1; + } + + /* + if (m2ua_lk_pro->e1_to_sg != sg) + { + if (!((m2ua_para.sg_para[sg].enable == 0) && + (m2ua_para.sg_para[m2ua_lk_pro->e1_to_sg].enable == 0))) + return -1; + if (((m2ua_lk_pro->e1_lk_type & 0x07) == 0x03) && // SIGTRAN | ENABLE | NOT MTP3LITE + ((m2ua_lk_pro->e1_to_mtp3 == host_ip) || + (m2ua_lk_pro->e1_to_alterMTP3 == host_ip)) && + (m2ua_lk_pro->e1_to_linkset < M2UA_MTP3_MAX_LS_NUM)) + { + lk_ptr->enable = (m2ua_lk_pro->e1_lk_type >> 1) & 0x01; + lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg; + lk_ptr->iid = m2ua_lk_pro->e1_to_iid; + } + if (m2ua_lk_info[link].enable == 1) + { + rm_sg_lk(sg, link); + m2ua_lk_info[link].enable = 0; + } + } + else + { + if (((m2ua_lk_pro->e1_lk_type & 0x07) == 0x03) && // SIGTRAN | ENABLE | NOT MTP3LITE + ((m2ua_lk_pro->e1_to_mtp3 == host_ip) || + (m2ua_lk_pro->e1_to_alterMTP3 == host_ip)) && + (m2ua_lk_pro->e1_to_linkset < M2UA_MTP3_MAX_LS_NUM)) + { + lk_ptr->enable = (m2ua_lk_pro->e1_lk_type >> 1) & 0x01; + lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg; + lk_ptr->iid = m2ua_lk_pro->e1_to_iid; + } + } + */ + } + + //typedef enum + //{ + // LKTYPE_NONE_SIGTRAN = 0, + // LKTYPE_SIGTRAN = 1, + // LKTYPE_MTP3_LITE = 2, + // LKTYPE_RESERVED1 = 3, + // LKTYPE_M3UA = 4, + // LKTYPE_RESERVED3 = 5, + // LKTYPE_RESERVED4 = 6, + // LKTYPE_RESERVED5 = 7, + //}MTP3_LKTYPE_LIST; + + sg = lk_ptr->lk_sg; + + if (m2ua_lk_info[link].enable == 0) + { + //if ((((m2ua_lk_pro->e1_lk_type & 0x0F) == 0x03 || (m2ua_lk_pro->e1_lk_type & 0x0F) == 0x09) && // M2UA|M3UA | ENABLE + // ((m2ua_lk_pro->e1_to_mtp3 == host_ip)||(m2ua_lk_pro->e1_to_alterMTP3 == host_ip)) && + // (m2ua_lk_pro->e1_to_linkset < M2UA_MTP3_MAX_LS_NUM)) + // || ((m2ua_lk_pro->e1_lk_type & 0x0F) == 0x07)) //No ss7 | ENABLE + // Bit 1-3: Link type, 0/1/2/3/4: non-sigtran/sigtran-m2ua/mtp3lite/iua/sigtran-m3ua + + if (((m2ua_lk_pro->admin_state&0x01)==1) && + (((m2ua_lk_pro->e1_lk_type == 1 || m2ua_lk_pro->e1_lk_type == 4 ) && // M2UA|M3UA | ENABLE + (m2ua_lk_pro->e1_to_mtp3 == host_ip ||m2ua_lk_pro->e1_to_alterMTP3 == host_ip) && + (m2ua_lk_pro->e1_to_linkset < M2UA_MTP3_MAX_LS_NUM)) + || (m2ua_lk_pro->e1_lk_type == 3))) //No ss7(iua) | ENABLE + { + lk_ptr->enable = 1; + lk_ptr->iid = m2ua_lk_pro->e1_to_iid; + lk_ptr->dlci = 0; + + if(link < 512) + lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg & 0xFF; + else + lk_ptr->lk_sg = (m2ua_lk_pro->e1_to_sg & 0xFF) + M2UA_MAX_SG_NUM/2; + + if(m2ua_lk_pro->e1_lk_type == 4) //m3ua + lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg & 0xFF; + //if (enable_sg(sg) < 0) + //return -1; + + m2ua_lk_init(link); + //m2ua_lk_info[link].enable = 1; + //m2ua_sg_info[sg].act_lks++; + } + else if (lk_ptr->enable) + { + lk_ptr->enable = 0; + lk_ptr->lk_sg = 0; + lk_ptr->iid = 0; + lk_ptr->dlci = 0; + } + } + else + { + //if ((((m2ua_lk_pro->e1_lk_type & 0x0F) != 0x03 || (m2ua_lk_pro->e1_lk_type & 0x0F) != 0x09) || + // ((m2ua_lk_pro->e1_to_mtp3 != host_ip) && (m2ua_lk_pro->e1_to_alterMTP3 != host_ip)) || + // (m2ua_lk_pro->e1_to_linkset >= M2UA_MTP3_MAX_LS_NUM)) + // && ((m2ua_lk_pro->e1_lk_type & 0x0F) != 0x07)) + if((m2ua_lk_pro->e1_to_mtp3 != host_ip) && (m2ua_lk_pro->e1_to_alterMTP3 != host_ip)) + return len; + + if ((m2ua_lk_pro->admin_state&0x01)==0) + { + if (m2ua_sg_info[sg].m2ua_state == 3) + { + m2ua_sg_info[sg].iid = link; + m2ua_sg_info[sg].mgmt_cmd = M2UA_MGMT_CMD_LK_LOCK; + m2ua_fsm(sg); + } + + rm_sg_lk(sg, link); + m2ua_lk_init(link); + + lk_ptr->enable = 0; + lk_ptr->lk_sg = 0; + lk_ptr->iid = 0; + lk_ptr->dlci = 0; + } + } + + return len; +} + + + +int set_m2ua_sg(WORD sg, BYTE *data_ptr) +{ + BYTE len; + sg_para_t *sg_ptr; + + len = sizeof(sg_para_t); + + if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) + { + if (m2ua_sg_mon_fg[sg] == 1) + { + sprintf(m2ua_ascitemp_buf, "Recv MTP3 Set SG Attributes, sg=%d, len=%d\n\r", sg, len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(data_ptr, len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + /* + if (init_flag < 2) + { + bcopy(data_ptr, (BYTE *) &m2ua_para.sg_para[sg], len); + if (sg == 255) + init_flag++; + } + else + */ + { + sg_ptr = (sg_para_t *) data_ptr; + + if (m2ua_para.sg_para[sg].enable && + m2ua_para.sg_para[sg+M2UA_MAX_SG_NUM/2].enable) + { + if (sg_ptr->enable) + return -1; +// else if ((sg_ptr->server != m2ua_para.sg_para[sg].server) || +// (sg_ptr->ip != m2ua_para.sg_para[sg].ip)) + else + { + if (((m2ua_sg_info[sg].enable == 0) ||(m2ua_sg_info[sg].fd == 0)) && + !((m2ua_sg_info[sg].sctp_state == 3) && (m2ua_sg_info[sg].sctp_state_1 == 1))) // Not Client at sctp 3-1 state + m2ua_para.sg_para[sg].enable = 0; + else + m2ua_para.sg_para[sg].enable = 2; + + sg = sg + M2UA_MAX_SG_NUM/2; + if (((m2ua_sg_info[sg].enable == 0) ||(m2ua_sg_info[sg].fd == 0)) && + !((m2ua_sg_info[sg].sctp_state == 3) && (m2ua_sg_info[sg].sctp_state_1 == 1))) // Not Client at sctp 3-1 state + m2ua_para.sg_para[sg].enable = 0; + else + m2ua_para.sg_para[sg].enable = 2; + return len; + } + } + + /* + if ((sg_ptr->server != m2ua_para.sg_para[sg].server) || + (sg_ptr->ip != m2ua_para.sg_para[sg].ip)) + m2ua_para.sg_para[sg].enable = 2; + else if (sg_ptr->enable >= 1) + m2ua_para.sg_para[sg].enable = 1; + else + m2ua_para.sg_para[sg].enable = 0; + bcopy(data_ptr + 1, (BYTE *) &m2ua_para.sg_para[sg] + 1, len - 1); + */ + + bcopy(data_ptr, (BYTE *) &m2ua_para.sg_para[sg], len); + if(m2ua_para.sg_para[sg].plat_port[0]==0 || m2ua_para.sg_para[sg].server) + { + if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M2UA_APP) + m2ua_para.sg_para[sg].plat_port[0] = M2UA_PORT_0; + else if ((m2ua_para.sg_para[sg].xUA_ack>>1) == IUA_APP) + { + m2ua_para.sg_para[sg].plat_port[0] = IUA_PORT_0; + } + else if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M3UA_APP) + { + m2ua_para.sg_para[sg].plat_port[0] = M3UA_PORT_0; + } + sg = sg + M2UA_MAX_SG_NUM/2; + bcopy(data_ptr, (BYTE *) &m2ua_para.sg_para[sg], len); + if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M2UA_APP) + { + + m2ua_para.sg_para[sg].plat_port[0] = M2UA_PORT_1; + } + else if ((m2ua_para.sg_para[sg].xUA_ack>>1) == IUA_APP) + m2ua_para.sg_para[sg].plat_port[0] = IUA_PORT_1; + else if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M3UA_APP) + { + m2ua_para.sg_para[sg].plat_port[0] = M3UA_PORT_1; + } + } + else + { // set client dst port + m2ua_para.sg_para[sg].plat_port[0]=m2ua_para.sg_para[sg].plat_port[0]; + sg = sg + M2UA_MAX_SG_NUM/2; + bcopy(data_ptr, (BYTE *) &m2ua_para.sg_para[sg], len); + m2ua_para.sg_para[sg].plat_port[0]=m2ua_para.sg_para[sg].plat_port[0]; + } + } + //m2ua_para.sg_para[sg].plat_port[1] = 0; + return len; +} + + +int m2ua_set_sg_rc(int linkno, int rc) +{ + int sg; + + sg = m2ua_para.lk_para[linkno].lk_sg; + m2ua_sg_info[sg].rc = rc; + + return 1; +} + + +int m2ua_sctp_close(int fd, WORD sg_id) +{ + int ret; + + if ((ret = close(fd)) < 0) + m2ua_log_err(sg_id, "ERROR: M2UA SCTP close!"); + + return ret; +} + +#ifndef _LKSCTP + +int m2ua_sctp_get_msg(int fd, WORD sg) +{ + int ret; + int flags = 0; + char err_text[128]; + //BYTE in_b; + + m2ua_sctp_data.buf = m2ua_sctp_dat; + + //in_b = inb(0x378); + //outb(in_b | 0x02, 0x378); + //20 us + + while ((ret = getmsg(fd, &m2ua_sctp_ctrl, &m2ua_sctp_data, &flags)) < 0) + { + switch (errno) + { + default: + case EPROTO: + case EINVAL: + sprintf(err_text, "ERROR: M2UA SCTP getmsg: [%d] %s", errno, strerror(errno)); + m2ua_log_err(sg, err_text); + case EINTR: + case ERESTART: + continue; + case EAGAIN: + break; + } + break; + } + + //outb(in_b & 0xFD, 0x378); + + if (!ret) + return (m2ua_sctp_cmd.tpi.type); + else + return (-1); +} + +char *dec_sctp_primi(unsigned int sctp_primi) +{ + switch (sctp_primi) + { + case T_CONN_REQ: return("T_CONN_REQ"); + case T_CONN_RES: return("T_CONN_RES"); + case T_DISCON_REQ: return("T_DISCON_REQ"); + case T_DATA_REQ: return("T_DATA_REQ"); + case T_EXDATA_REQ: return("T_EXDATA_REQ"); + case T_OPTDATA_REQ: return("T_OPTDATA_REQ"); + case T_INFO_REQ: return("T_INFO_REQ"); + case T_BIND_REQ: return("T_BIND_REQ"); + case T_UNBIND_REQ: return("T_UNBIND_REQ"); + case T_UNITDATA_REQ: return("T_UNITDATA_REQ"); + case T_OPTMGMT_REQ: return("T_OPTMGMT_REQ"); + case T_ORDREL_REQ: return("T_ORDREL_REQ"); + case T_CONN_IND: return("T_CONN_IND"); + case T_CONN_CON: return("T_CONN_CON"); + case T_DISCON_IND: return("T_DISCON_IND"); + case T_DATA_IND: return("T_DATA_IND"); + case T_EXDATA_IND: return("T_EXDATA_IND"); + case T_OPTDATA_IND: return("T_OPTDATA_IND"); + case T_INFO_ACK: return("T_INFO_ACK"); + case T_BIND_ACK: return("T_BIND_ACK"); + case T_ERROR_ACK: return("T_ERROR_ACK"); + case T_OK_ACK: return("T_OK_ACK"); + case T_UNITDATA_IND: return("T_UNITDATA_IND"); + case T_UDERROR_IND: return("T_UDERROR_IND"); + case T_OPTMGMT_ACK: return("T_OPTMGMT_ACK"); + case T_ORDREL_IND: return("T_ORDREL_IND"); + case T_ADDR_REQ: return("T_ADDR_REQ"); + case T_ADDR_ACK: return("T_ADDR_ACK"); + default: return("Unexpected"); + } +} + +char *dec_sctp_err(unsigned int sctp_err) +{ + switch (sctp_err) + { + case TBADADDR: return("TBADADDR"); + case TBADOPT: return("TBADOPT"); + case TACCES: return("TACCES"); + case TBADF: return("TBADF"); + case TNOADDR: return("TNOADDR"); + case TOUTSTATE: return("TOUTSTATE"); + case TBADSEQ: return("TBADSEQ"); + case TSYSERR: return("TSYSERR"); + case TLOOK: return("TLOOK"); + case TBADDATA: return("TBADDATA"); + case TBUFOVFLW: return("TBUFOVFLW"); + case TFLOW: return("TFLOW"); + case TNODATA: return("TNODATA"); + case TNODIS: return("TNODIS"); + case TNOUDERR: return("TNOUDERR"); + case TBADFLAG: return("TBADFLAG"); + case TNOREL: return("TNOREL"); + case TNOTSUPPORT: return("TNOTSUPPORT"); + case TSTATECHNG: return("TSTATECHNG"); + case TNOSTRUCTYPE: return("TNOSTRUCTTYPE"); + case TBADNAME: return("TBADNAME"); + case TBADQLEN: return("TBADQLEN"); + case TADDRBUSY: return("TADDRBUSY"); + case TINDOUT: return("TINDOUT"); + case TPROVMISMATCH: return("TPROVMISMATCH"); + case TRESQLEN: return("TRESQLEN"); + case TRESADDR: return("TRESADDR"); + case TQFULL: return("TQFULL"); + case TPROTO: return("TPROTO"); + default: return("(unknown)"); + } +} + +int expect(int fd, int sg, int *msg, int want) +{ + int got; + + got = m2ua_sctp_get_msg(fd, sg); + *msg = got; + + if (got >= 0) + { + if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) + { + if (m2ua_sg_mon_fg[sg] == 1) + { + sprintf(m2ua_ascitemp_buf, "Recv %s from SCTP, sg=%d, ctrl len=%d\n\r", dec_sctp_primi(m2ua_sctp_cmd.tpi.type), sg, m2ua_sctp_ctrl.len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + if (m2ua_sctp_cmd.tpi.type == T_ERROR_ACK) + { + sprintf(m2ua_ascitemp_buf, "Error Code: %s\n\r", dec_sctp_err(m2ua_sctp_cmd.tpi.error_ack.TLI_error)); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + m2ua_hex_to_ascii(m2ua_sctp_cmd.cbuf, m2ua_sctp_ctrl.len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + if (m2ua_sctp_data.len > 0) + { + if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) + { + if (m2ua_sg_mon_fg[sg] == 1) + { + sprintf(m2ua_ascitemp_buf, "Data len=%d\n\r", m2ua_sctp_data.len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, m2ua_sctp_data.len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + } + } + + if (got == want) + return M2UA_SUCCESS; + else + return M2UA_FAILURE; +} + +int m2ua_sctp_put_msg(int fd, int sg) +{ + int ret; + struct strbuf *mydata = m2ua_sctp_data.len ? &m2ua_sctp_data : NULL; + char err_text[128]; + //BYTE in_b; + + if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) + { + if (m2ua_sg_mon_fg[sg] == 1) + { + sprintf(m2ua_ascitemp_buf, "Send %s to SCTP, sg=%d, ctrl len=%d\n\r", dec_sctp_primi(m2ua_sctp_cmd.tpi.type), sg, m2ua_sctp_ctrl.len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_cmd.cbuf, m2ua_sctp_ctrl.len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + + if (m2ua_sctp_data.len > 0) + { + sprintf(m2ua_ascitemp_buf, "Data len=%d\n\r", m2ua_sctp_data.len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_data.buf, m2ua_sctp_data.len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + } + + //in_b = inb(0x378); + //outb(in_b | 0x04, 0x378); + //88 us + + while ((ret = putpmsg(fd, &m2ua_sctp_ctrl, mydata, 0, MSG_HIPRI)) < 0) + { + switch (errno) + { + default: + sprintf(err_text, "ERROR: M2UA SCTP putpmsg: [%d] %s", errno, strerror(errno)); + m2ua_log_err(sg, err_text); + break; + case EINTR: + case ERESTART: + continue; + case EAGAIN: + printf("m2ua put msg EAGAIN\n"); + break; + } + break; + } + + //outb(in_b & 0xFB, 0x378); + + if (!ret) + return(0); + else + return(-1); +} + +int m2ua_sctp_put_fdi(int fd, int fd2, int sg, int offset, int flags) +{ + char err_text[256]; + + m2ua_sctp_fdi.flags = flags; + m2ua_sctp_fdi.fildes = fd2; + m2ua_sctp_fdi.offset = offset; + + if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) + { + if (m2ua_sg_mon_fg[sg] == 1) + { + sprintf(m2ua_ascitemp_buf, "Send %s to SCTP, sg=%d, ctrl len=%d\n\r", dec_sctp_primi(m2ua_sctp_cmd.tpi.type), sg, m2ua_sctp_ctrl.len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_cmd.cbuf, m2ua_sctp_ctrl.len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + if (ioctl(fd, I_FDINSERT, &m2ua_sctp_fdi) < 0) + { + sprintf(err_text, "ERROR: M2UA SCTP ioctl: [%d] %s", errno, strerror(errno)); + m2ua_log_err(sg, err_text); + } + + return(0); +} + +int m2ua_sctp_t_open(WORD sg) +{ + int fd; + + if ((fd = open("/dev/sctp_t",O_NONBLOCK|O_RDWR)) < 0) + m2ua_log_err(sg, "ERROR: M2UA SCTP open"); + + return fd; +} + +int m2ua_sctp_optmgmt_req(int fd, int sg, unsigned int flags) +{ + m2ua_sctp_data.len = 0; + m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.optmgmt_req) + sizeof(m2ua_sctp_opt_optm); + m2ua_sctp_cmd.tpi.type = T_OPTMGMT_REQ; + m2ua_sctp_cmd.tpi.optmgmt_req.MGMT_flags = flags; + m2ua_sctp_cmd.tpi.optmgmt_req.OPT_length = sizeof(m2ua_sctp_opt_optm); + m2ua_sctp_cmd.tpi.optmgmt_req.OPT_offset = sizeof(m2ua_sctp_cmd.tpi.optmgmt_req); + + m2ua_sctp_opt_optm.ppi_val = m2ua_para.sg_para[sg].xUA_ack>>1; + bcopy(&m2ua_sctp_opt_optm, (m2ua_sctp_cmd.cbuf + sizeof(m2ua_sctp_cmd.tpi.optmgmt_req)), sizeof(m2ua_sctp_opt_optm)); + return m2ua_sctp_put_msg(fd, sg); +} + +int m2ua_sctp_bind_req(int fd, int sg, m2ua_sctp_addr_t *addr, int coninds) +{ + m2ua_sctp_data.len = 0; + m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.bind_req) + sizeof(*addr); + m2ua_sctp_cmd.tpi.type = T_BIND_REQ; + m2ua_sctp_cmd.tpi.bind_req.ADDR_length = sizeof(*addr); + m2ua_sctp_cmd.tpi.bind_req.ADDR_offset = sizeof(m2ua_sctp_cmd.tpi.bind_req); + m2ua_sctp_cmd.tpi.bind_req.CONIND_number = coninds; + bcopy(addr, (&m2ua_sctp_cmd.tpi.bind_req) + 1, sizeof(*addr)); + return m2ua_sctp_put_msg(fd, sg); +} + +int m2ua_sctp_conn_req(int fd, int sg, m2ua_sctp_addr_t *addr) +{ + m2ua_sctp_data.len = 0; + m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.conn_req)+sizeof(*addr); + m2ua_sctp_cmd.tpi.type = T_CONN_REQ; + m2ua_sctp_cmd.tpi.conn_req.DEST_length = sizeof(*addr); + m2ua_sctp_cmd.tpi.conn_req.DEST_offset = sizeof(m2ua_sctp_cmd.tpi.conn_req); + m2ua_sctp_cmd.tpi.conn_req.OPT_length = 0; + m2ua_sctp_cmd.tpi.conn_req.OPT_offset = sizeof(m2ua_sctp_cmd.tpi.conn_req)+sizeof(*addr); + bcopy(addr, (m2ua_sctp_cmd.cbuf + sizeof(m2ua_sctp_cmd.tpi.conn_req)), sizeof(*addr)); + return m2ua_sctp_put_msg(fd, sg); +} + +int m2ua_sctp_conn_res(int fd, int fd2, int sg, unsigned int seq) +{ + m2ua_sctp_fdi.databuf.len = 0; + m2ua_sctp_fdi.ctlbuf.len = sizeof(m2ua_sctp_cmd.tpi.conn_res); + m2ua_sctp_cmd.tpi.type = T_CONN_RES; + m2ua_sctp_cmd.tpi.conn_res.ACCEPTOR_id = 0; + m2ua_sctp_cmd.tpi.conn_res.SEQ_number = seq; + m2ua_sctp_cmd.tpi.conn_res.OPT_offset = 0; + m2ua_sctp_cmd.tpi.conn_res.OPT_length = 0; + return m2ua_sctp_put_fdi(fd, fd2, sg, 4, 0); +} + +int m2ua_sctp_discon_req(int fd, int sg, unsigned int seq) +{ + m2ua_sctp_data.len = 0; + m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.discon_req); + m2ua_sctp_cmd.tpi.type = T_DISCON_REQ; + m2ua_sctp_cmd.tpi.discon_req.SEQ_number = seq; + return m2ua_sctp_put_msg(fd, sg); +} + +int m2ua_sctp_ordrel_req(int fd, int sg) +{ + m2ua_sctp_data.len = 0; + m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.ordrel_req); + m2ua_sctp_cmd.tpi.type = T_ORDREL_REQ; + return m2ua_sctp_put_msg(fd, sg); +} + +int m2ua_sctp_optdata_req(int fd, int sg, int len) +{ + if (!len) + return (-1); + else + m2ua_sctp_data.len = len; + + m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.optdata_req) + sizeof(m2ua_sctp_opt_data); + m2ua_sctp_cmd.tpi.type = T_OPTDATA_REQ; + m2ua_sctp_cmd.tpi.optdata_req.DATA_flag = 0; + m2ua_sctp_cmd.tpi.optdata_req.OPT_length = sizeof(m2ua_sctp_opt_data); + m2ua_sctp_cmd.tpi.optdata_req.OPT_offset = sizeof(m2ua_sctp_cmd.tpi.optdata_req); + bcopy(&m2ua_sctp_opt_data, m2ua_sctp_cmd.cbuf + sizeof(m2ua_sctp_cmd.tpi.optdata_req), sizeof(m2ua_sctp_opt_data)); + return m2ua_sctp_put_msg(fd, sg); +} + +#else + +char *dec_sctp_primi_lksctp(unsigned int sctp_primi) +{ + switch (sctp_primi) + { + case M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP: return("M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP"); + case M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST: return("M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST"); + case M2UA_LKSCTP_ASSOC_CHANGE_SHUTDOWN_COMP: return("M2UA_LKSCTP_ASSOC_CHANGE_SHUTDOWN_COMP"); + case M2UA_LKSCTP_ASSOC_CHANGE_RESTART: return("M2UA_LKSCTP_ASSOC_CHANGE_RESTART"); + case M2UA_LKSCTP_ASSOC_CHANGE_CANT_STR_ASSOC: return("M2UA_LKSCTP_ASSOC_CHANGE_CANT_STR_ASSOC"); + case M2UA_LKSCTP_SEND_FAILED: return("M2UA_LKSCTP_SEND_FAILED"); + case M2UA_LKSCTP_PEER_ADDR_CHANGE: return("M2UA_LKSCTP_PEER_ADDR_CHANGE"); + case M2UA_LKSCTP_REMOTE_ERROR: return("M2UA_LKSCTP_REMOTE_ERROR"); + case M2UA_LKSCTP_SHUTDOWN_EVENT: return("M2UA_LKSCTP_SHUTDOWN_EVENT"); + case M2UA_LKSCTP_DATA_IND: return("M2UA_LKSCTP_DATA_IND"); + case M2UA_LKSCTP_UNKNOWN_EVENT: return("M2UA_LKSCTP_UNKNOWN_EVENT"); + default: return("Unexpected"); + } +} + +int m2ua_sctp_optmgmt_req_lksctp(int fd, int sg) +{ + struct linger lg; + struct sctp_event_subscribe event; + struct sctp_initmsg initopt; + struct sctp_rtoinfo rtoinfo; + struct sctp_assocparams assocparams; + + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + { + m2ua_log_err(sg, "M2UA set nonblock failure!"); + return 0; + } + + lg.l_onoff = 1; + lg.l_linger = 0; + + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lg, sizeof(lg)) != 0) + { + m2ua_log_err(sg, "set linger failed!"); + //return 0; + } + + if ((sg >= M2UA_MAX_SG_NUM) || + ((sg < M2UA_MAX_SG_NUM) && !m2ua_para.sg_para[sg].server)) + { + // Enable all events + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + event.sctp_partial_delivery_event = 1; + //event.sctp_adaption_layer_event = 1; + + if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) + { + m2ua_log_err(sg, "set event failed!"); + return 0; + } + + initopt.sinit_num_ostreams = 257; + initopt.sinit_max_instreams = 257; + initopt.sinit_max_attempts = 8; + initopt.sinit_max_init_timeo = 0; + + if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &initopt, sizeof(initopt)) != 0) + { + m2ua_log_err(sg, "set initopt failed!"); + return 0; + } + + rtoinfo.srto_assoc_id = 0; + rtoinfo.srto_initial = 1000; + rtoinfo.srto_max = 5000; + rtoinfo.srto_min = 1000; + + if (setsockopt(fd, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo)) != 0) + { + m2ua_log_err(sg, "set rtoinfo failed!"); + //return 0; + } + + memset((BYTE *)&assocparams, 0, sizeof(assocparams)); + assocparams.sasoc_asocmaxrxt = 5; + if (setsockopt(fd, IPPROTO_SCTP, SCTP_ASSOCINFO, &assocparams, sizeof(assocparams)) != 0) + { + m2ua_log_err(sg, "set assocparams failed!"); + //return 0; + } + } + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "m2ua_sctp_optmgmt_req_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + + return 1; +} + +int m2ua_sctp_optmgmt_req_lksctp_ext(int fd, int sg) +{ + struct sctp_paddrparams paddrparams; + struct sockaddr_in *paddr; + + if (sg < M2UA_MAX_SG_NUM) + { + memset((BYTE *)&paddrparams, 0, sizeof(paddrparams)); + paddr = (struct sockaddr_in *)&paddrparams.spp_address; + paddr->sin_family = AF_INET; + if (m2ua_para.sg_para[sg].server) + paddr->sin_port = m2ua_sg_info[sg].rem_port; + else + { + if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M2UA_APP) + paddr->sin_port = htons(M2UA_PORT_0); + else if ((m2ua_para.sg_para[sg].xUA_ack>>1) == IUA_APP) + paddr->sin_port = htons(IUA_PORT_0); + else if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M3UA_APP) + paddr->sin_port = htons(M3UA_PORT_0); + } + paddr->sin_addr.s_addr = m2ua_para.sg_para[sg].ip; + paddrparams.spp_hbinterval = 20000; + paddrparams.spp_pathmaxrxt = 5; + + /* + //ES5 sctp headfile changed + if (setsockopt(fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &paddrparams, sizeof(paddrparams)) != 0) + { + BYTE ascitemp_buf[256]; + sprintf(ascitemp_buf, "set paddrparams failed: %d(%s)", errno, strerror(errno)); + m2ua_log_err(sg, ascitemp_buf); + //return 0; + }*/ + } + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "m2ua_sctp_optmgmt_req_lksctp_ext succeed, sg=%d, fd=%d\n\r", sg, fd); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + + return 1; +} + +int m2ua_sctp_bind_req_lksctp(int fd, int sg, m2ua_sctp_addr_t *addr, int coninds) +{ + struct sockaddr_in sin[1]; + int n=1, ret=0; + + sin->sin_family = AF_INET; + sin->sin_port = addr->port; + sin->sin_addr.s_addr = addr->addr.s_addr; + + ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(int)); + if(ret < 0) + { + m2ua_log_err(sg, "setsockopt SO_REUSEADDR failed!"); + } + if (bind(fd, (struct sockaddr *)sin, sizeof (*sin)) == -1) + { + m2ua_log_err(sg, "bind failed!"); + return 0; + } + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "m2ua_sctp_bind_req_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + + if (coninds) + { + if (listen(fd, 1) == -1) + { + m2ua_log_err(sg, "listen failed!"); + return 0; + } + if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) + { + sprintf(m2ua_ascitemp_buf, "m2ua_sctp_listen_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + } + + return 1; +} + +int m2ua_sctp_open_lksctp(WORD sg) +{ + int fd; + + if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1) + m2ua_log_err(sg, "M2UA lksctp open failure!"); + + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + { + m2ua_log_err(sg, "M2UA set nonblock failure!"); + return 0; + } + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "m2ua_sctp_open_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + + return fd; +} + +int m2ua_sctp_conn_req_lksctp(int fd, int sg, m2ua_sctp_addr_t *addr) +{ + struct sockaddr_in sin[1]; + + sin->sin_family = AF_INET; + sin->sin_port = addr->port; + sin->sin_addr.s_addr = addr->addr.s_addr; + + connect(fd, (struct sockaddr *)sin, sizeof(sin)); + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "m2ua_sctp_conn_req_lksctp sent, sg=%d, fd=%d\n\r", sg, fd); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + + return 0; +} + +int m2ua_handle_event_lksctp(void *buf) +{ + struct sctp_assoc_change *sac; + //struct sctp_send_failed *ssf; + //struct sctp_paddr_change *spc; + //struct sctp_remote_error *sre; + union sctp_notification *snp; + //char addrbuf[8]; + //const char *ap; + //struct sockaddr_in *sin; + + snp = buf; + + switch (snp->sn_header.sn_type) + { + case SCTP_ASSOC_CHANGE: + sac = &snp->sn_assoc_change; + //printf("^^^ assoc_change: state=%hu, error=%hu, instr=%hu " + // "outstr=%hu\n", sac->sac_state, sac->sac_error, + // sac->sac_inbound_streams, sac->sac_outbound_streams); + return ((SCTP_ASSOC_CHANGE << 16) | (sac->sac_state & 0xFFFF)); + case SCTP_SEND_FAILED: + //ssf = &snp->sn_send_failed; + //printf("^^^ sendfailed: len=%hu err=%d\n", ssf->ssf_length, + // ssf->ssf_error); + return M2UA_LKSCTP_SEND_FAILED; + case SCTP_PEER_ADDR_CHANGE: + //spc = &snp->sn_paddr_change; + //if (spc->spc_aaddr.ss_family == AF_INET) { + // sin = (struct sockaddr_in *)&spc->spc_aaddr; + // ap = inet_ntop(AF_INET, &sin->sin_addr, + // addrbuf, 8); + //} + //printf("^^^ intf_change: %s state=%d, error=%d\n", ap, + // spc->spc_state, spc->spc_error); + return M2UA_LKSCTP_PEER_ADDR_CHANGE; + case SCTP_REMOTE_ERROR: + //sre = &snp->sn_remote_error; + //printf("^^^ remote_error: err=%hu len=%hu\n", + // ntohs(sre->sre_error), ntohs(sre->sre_length)); + return M2UA_LKSCTP_REMOTE_ERROR; + case SCTP_SHUTDOWN_EVENT: + //printf("^^^ shutdown event\n"); + return M2UA_LKSCTP_SHUTDOWN_EVENT; + default: + //printf("unknown type: %hu\n", snp->sn_header.sn_type); + return M2UA_LKSCTP_UNKNOWN_EVENT; + } + + return -1; +} + +void *m2ua_recvmsg_lksctp(WORD sg, int fd, struct msghdr *msg, void *data_buf, int *data_len, int cmsglen) +{ + int nr = 0, nnr = 0; + struct iovec iov[1]; + //BYTE tmp_buf[M2UA_SCTP_DAT_BUFSIZE]; + + *data_len = 0; + iov->iov_base = data_buf; + iov->iov_len = M2UA_SCTP_DAT_BUFSIZE; + + msg->msg_iov = iov; + msg->msg_iovlen = 1; + + //for (;;) + { +#ifndef MSG_XPG4_2 +#define MSG_XPG4_2 0 +#endif + msg->msg_flags = MSG_XPG4_2; + msg->msg_controllen = cmsglen; + + nnr = recvmsg(fd, msg, 0); + if (nnr <= 0) + { + /* EOF or error */ + *data_len = nr; + return (NULL); + } + nr += nnr; + + if ((msg->msg_flags & MSG_EOR) != 0) + { + *data_len = nr; + return (data_buf); + } + + //iov->iov_base = tmp_buf; + //iov->iov_len = M2UA_SCTP_DAT_BUFSIZE; + } + + m2ua_log_err(sg, "m2ua_recvmsg_lksctp MSG_EOR flag not set!"); + + return (NULL); +} + +int m2ua_sctp_get_msg_lksctp(int fd, WORD sg) +{ + int ret = -1; + //BYTE in_b; + struct sctp_sndrcvinfo *sri; + struct msghdr msg[1]; + struct cmsghdr *cmsg; + BYTE *cbuf; + BYTE *dbuf; + int cmsglen = sizeof(*cmsg) + sizeof(*sri); + + //in_b = inb(0x378); + //outb(in_b | 0x02, 0x378); + + /* Set up the msghdr structure for receiving */ + memset(msg, 0, sizeof (*msg)); + cbuf = m2ua_sctp_cmd.cbuf; + dbuf = m2ua_sctp_dat; + msg->msg_control = cbuf; + msg->msg_controllen = cmsglen; + msg->msg_flags = 0; + cmsg = (struct cmsghdr *)cbuf; + sri = (struct sctp_sndrcvinfo *)(cmsg + 1); + m2ua_sctp_dat_len = M2UA_SCTP_DAT_BUFSIZE; + + if ((dbuf = m2ua_recvmsg_lksctp(sg, fd, msg, dbuf, &m2ua_sctp_dat_len, cmsglen)) > 0) + { + /* Intercept notifications here */ + if (msg->msg_flags & MSG_NOTIFICATION) + ret = m2ua_handle_event_lksctp(dbuf); + else + ret = M2UA_LKSCTP_DATA_IND; + } + + //outb(in_b & 0xFD, 0x378); + + return ret; +} + +int expect_lksctp(int fd, int sg, int *msg, int want) +{ + int got; + + *msg = got = m2ua_sctp_get_msg_lksctp(fd, sg); + + if (got != -1) + { + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + if (m2ua_sctp_dat_len > 0) + { + sprintf(m2ua_ascitemp_buf, "Recv %s from SCTP, sg=%d, data len=%d\n\r", dec_sctp_primi_lksctp(got), sg, m2ua_sctp_dat_len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, m2ua_sctp_dat_len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + } + + if (got == want) + return M2UA_SUCCESS; + else + return M2UA_FAILURE; +} + +int m2ua_sctp_discon_req_lksctp(int fd, int sg, int flag) +{ + BYTE enable1, enable2, server; + WORD lk; + + m2ua_sctp_close(fd, sg); + if (sg < M2UA_MAX_SG_NUM) + { + //enable1 = m2ua_sg_info[sg].enable; + //m2ua_sg_init(sg); + //m2ua_sg_info[sg].enable = enable1; + m2ua_sg_info[sg].fd = 0; + } + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + sprintf(m2ua_ascitemp_buf, "m2ua_sctp_discon_req_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); + m2ua_asciout_proc(m2ua_ascitemp_buf); + } + + if ((flag == 0) || (sg >= M2UA_MAX_SG_NUM)) + return 0; + + enable1 = m2ua_sg_info[sg].enable; + enable2 = m2ua_para.sg_para[sg].enable; + server = m2ua_para.sg_para[sg].server; + + if (!server && enable1 && (enable2 == 1)) + { + if ((fd = m2ua_sctp_open_lksctp(sg)) <= 0) + { + m2ua_sg_info[sg].enable = 0; + for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) + { + if(m2ua_para.lk_para[lk].lk_sg == sg) + m2ua_lk_info[lk].enable = 0; + } + m2ua_log_err(sg, "M2UA lksctp open failure!"); + } + else + m2ua_sg_info[sg].fd = fd; + } + + return 1; +} + +int m2ua_sctp_put_msg_lksctp(int fd, int sg) +{ + //BYTE err_text[128]; + //BYTE in_b; + BYTE ppid; + struct sctp_sndrcvinfo *sri; + struct msghdr msg[1]; + struct cmsghdr *cmsg; + struct iovec iov[1]; + int cmsglen = sizeof(*cmsg) + sizeof(*sri); + int ret; + + if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && + (m2ua_sg_mon_fg[sg] == 1)) + { + if (m2ua_sctp_dat_len > 0) + { + sprintf(m2ua_ascitemp_buf, "Send M2UA_LKSCTP_DATA to SCTP, sg=%d, data len=%d\n\r", sg, m2ua_sctp_dat_len); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_hex_to_ascii(m2ua_sctp_dat, m2ua_sctp_dat_len, (BYTE *)m2ua_ascitemp_buf); + m2ua_asciout_proc(m2ua_ascitemp_buf); + m2ua_asciout_proc("\n\r"); + } + } + + //in_b = inb(0x378); + //outb(in_b | 0x04, 0x378); + //88 us + + /* Set up the msghdr structure for receiving */ + memset(msg, 0, sizeof (*msg)); + + iov->iov_base = m2ua_sctp_data.buf; + iov->iov_len = m2ua_sctp_data.len; + msg->msg_iov = iov; + msg->msg_iovlen = 1; + + msg->msg_control = m2ua_sctp_cmd.cbuf; + msg->msg_controllen = cmsglen; + msg->msg_flags = MSG_XPG4_2; + + cmsg = (struct cmsghdr *)m2ua_sctp_cmd.cbuf; + sri = (struct sctp_sndrcvinfo *)(cmsg + 1); + + cmsg->cmsg_len = cmsglen; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + + memset((BYTE *)sri, 0, sizeof(*sri)); + sri->sinfo_stream = m2ua_sctp_data.sid; + //sri->sinfo_ppid = htonl(2); //m2ua + switch(m2ua_para.sg_para[sg].xUA_ack>>1)//SCTP Payload Protocol Identifier + { + case M2UA_APP: + ppid = 2; + break; + case IUA_APP: + ppid = 1; + break; + case M3UA_APP: + ppid = 3; + break; + default: + ppid = 2; + break; + } + sri->sinfo_ppid = htonl(ppid); + + if ((ret = sendmsg(fd, msg, MSG_NOSIGNAL)) < 0) + { + char ascitemp_buf[256]; + sprintf(ascitemp_buf, "ret=%d,lksctp sendmsg failure: %d(%s)", ret,errno, strerror(errno)); + m2ua_log_err(sg, ascitemp_buf); + return -1; + } + + //outb(in_b & 0xFB, 0x378); + + return 0; +} + +int m2ua_sctp_optdata_req_lksctp(int fd, int sg, int len) +{ + if (!len) + return (-1); + else + { + if (len > M2UA_MAX_MSG_LEN) + return (-1); + else + m2ua_sctp_data.len = len; + } + + return m2ua_sctp_put_msg_lksctp(fd, sg); +} + +#endif diff --git a/plat/m2ua/ut/testcate/MGC(IUA)_Client.txt b/plat/m2ua/ut/testcate/MGC(IUA)_Client.txt new file mode 100644 index 0000000..1c84135 --- /dev/null +++ b/plat/m2ua/ut/testcate/MGC(IUA)_Client.txt @@ -0,0 +1,32 @@ +#include "headfile.txt" + +test 1 udp +UDP.Set remote_port=MSG_PORT +UDP.Set local_port=MSG_PORT +UDP.Set remote_ip=MSC_IP +//0 send +//A5 00 03 00 02 00 +// +//10 send +//A5 00 03 00 06 00 + +10 send +A5 00 03 00 07 00 + +100 send +A5 00 03 00 01 00 + +10 send +05 00 03 FF 01 F0 +1000 recv +?? +10 send +05 00 03 FF 01 F1 +1000 recv +?? + +100 send +A5 00 03 00 02 00 + +50 send +A5 00 03 00 06 00 diff --git a/plat/m2ua/ut/testcate/MGC(IUA)_Server.txt b/plat/m2ua/ut/testcate/MGC(IUA)_Server.txt new file mode 100644 index 0000000..5e10119 --- /dev/null +++ b/plat/m2ua/ut/testcate/MGC(IUA)_Server.txt @@ -0,0 +1,52 @@ +#include "headfile.txt" + +test 1 sctp +SCTP.SET REMOTE_IP=MSC_IP +SCTP.SET REMOTE_PORT=IUA_CPORT +SCTP.SET LOCAL_PORT=IUA_PORT +SCTP.SET STREAM_ID=1 +50 SCTP.SET server + +1000 SCTP.RECV +01 00 03 01 00 00 00 10 00 11 00 08 ?? ?? ?? ?? + + +0 SCTP.send +01 00 03 04 00 00 00 08 + +0 SCTP.send +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 02 + +1000 SCTP.FLTR +01 00 03 01 00 00 00 10 00 11 00 08 ?? ?? ?? ?? + +1000 SCTP.RECV +01 00 04 01 00 00 00 18 00 0B 00 08 00 00 00 01 00 01 00 08 00 00 00 00 + +0 SCTP.send +01 00 04 03 00 00 00 10 00 0B 00 08 00 00 00 01 + +0 SCTP.send +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 03 + +1000 SCTP.RECV +01 00 05 05 00 00 00 18 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 + +0 SCTP.send +01 00 05 06 00 00 00 18 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 + +1000 SCTP.RECV +?? +0 SCTP.SEND +01 00 05 02 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0E 00 07 FF 01 F1 00 + +1000 SCTP.RECV +?? +0 SCTP.SEND +01 00 05 02 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0E 00 07 FF 01 F0 00 + +//1 SCTP.SEND +//01 00 05 0A 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0F 00 08 00 00 00 00 + +1000 SCTP.RECV +01 00 05 08 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0F 00 08 00 00 00 00 diff --git a/plat/m2ua/ut/testcate/MGC(M2UA)_Client.txt b/plat/m2ua/ut/testcate/MGC(M2UA)_Client.txt new file mode 100644 index 0000000..b3dfcd4 --- /dev/null +++ b/plat/m2ua/ut/testcate/MGC(M2UA)_Client.txt @@ -0,0 +1,33 @@ +#include "headfile.txt" + +test 1 udp +UDP.Set remote_port=MSG_PORT +UDP.Set local_port=MSG_PORT +UDP.Set remote_ip=MSC_IP + +0 send +A6 02 03 00 02 00 + +10 send +A6 02 03 00 06 00 + +10 send +A6 02 03 00 07 00 + +100 send +A6 02 03 00 01 00 + +10 send +06 02 03 FF 01 F0 +1000 recv +?? +10 send +06 02 03 FF 01 F1 +1000 recv +?? + +100 send +A6 02 03 00 02 00 + +50 send +A6 02 03 00 06 00 diff --git a/plat/m2ua/ut/testcate/MGC(M2UA)_Server.txt b/plat/m2ua/ut/testcate/MGC(M2UA)_Server.txt new file mode 100644 index 0000000..21faa41 --- /dev/null +++ b/plat/m2ua/ut/testcate/MGC(M2UA)_Server.txt @@ -0,0 +1,61 @@ +#include "headfile.txt" + +test 1 sctp +SCTP.SET REMOTE_IP=MSC_IP +SCTP.SET REMOTE_PORT=M2UA_CPORT +SCTP.SET LOCAL_PORT=M2UA_PORT +SCTP.SET STREAM_ID=1 +50 SCTP.SET server + +1000 SCTP.RECV +01 00 03 01 00 00 00 10 00 11 00 08 ?? ?? ?? ?? +//ip + +0 SCTP.send +01 00 03 04 00 00 00 08 + +0 SCTP.send +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 02 + +1000 SCTP.FLTR +01 00 03 01 00 00 00 10 00 11 00 08 ?? ?? ?? ?? +//ip 3 + +1000 SCTP.RECV +01 00 04 01 00 00 00 18 00 0B 00 08 00 00 00 01 00 01 00 08 00 00 00 00 + +0 SCTP.send +01 00 04 03 00 00 00 10 00 0B 00 08 00 00 00 01 + +0 SCTP.send +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 03 + +1000 SCTP.RECV +01 00 06 02 00 00 00 10 00 01 00 08 00 00 00 00 + + +0 SCTP.send +01 00 06 03 00 00 00 10 00 01 00 08 00 00 00 00 + +1000 SCTP.RECV +?? +0 SCTP.SEND +01 00 06 01 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F0 00 + +1000 SCTP.RECV +?? +0 SCTP.SEND +01 00 06 01 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F1 00 + +// 1 SCTP.SEND +// 01 00 06 01 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F0 00 + + +1000 SCTP.RECV +01 00 06 04 00 00 00 10 00 01 00 08 00 00 00 00 +//stop +0 SCTP.send +01 00 06 05 00 00 00 10 00 01 00 08 00 00 00 00 + +1000 SCTP.RECV +? \ No newline at end of file diff --git a/plat/m2ua/ut/testcate/SG(IUA)_Client.txt b/plat/m2ua/ut/testcate/SG(IUA)_Client.txt new file mode 100644 index 0000000..de9c365 --- /dev/null +++ b/plat/m2ua/ut/testcate/SG(IUA)_Client.txt @@ -0,0 +1,80 @@ +#include "headfile.txt" + +test 1 udp +UDP.Set remote_port=MSG_PORT +UDP.Set local_port=MSG_PORT +UDP.Set remote_ip=MSC_IP + +0 send +A5 01 03 00 06 00 +10 send +A5 01 03 00 07 00 + +test 2 +SCTP.SET REMOTE_IP=MSC_IP +SCTP.SET REMOTE_PORT=IUA_PORT +SCTP.SET LOCAL_PORT=IUA_CPORT +SCTP.SET STREAM_ID=0 +5 SCTP.SET CLIENT +50 SCTP.SEND +01 00 03 01 00 00 00 10 00 11 00 08 AC 36 F0 A0 //ip +1000 SCTP.RECV +01 00 03 04 00 00 00 08 +1000 SCTP.RECV +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 02 +0 SCTP.SEND +01 00 04 01 00 00 00 10 00 0B 00 08 00 00 00 01 +1000 SCTP.RECV +01 00 04 03 00 00 00 10 00 0B 00 08 00 00 00 01 +1000 SCTP.RECV +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 03 +0 SCTP.SEND +01 00 05 05 00 00 00 18 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 +1000 SCTP.RECV +01 00 05 06 00 00 00 18 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 +1 SCTP.SEND +02 00 05 08 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0F 00 08 00 00 00 00 +1000 SCTP.RECV +01 00 00 00 00 00 00 10 00 0C 00 08 00 00 00 01 +1 SCTP.SEND +01 00 99 08 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0F 00 08 00 00 00 00 +1000 SCTP.RECV +01 00 00 00 00 00 00 10 00 0C 00 08 00 00 00 03 +1 SCTP.SEND +01 00 05 99 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0F 00 08 00 00 00 00 +1000 SCTP.RECV +01 00 00 00 00 00 00 10 00 0C 00 08 00 00 00 04 + + +0 SCTP.SEND +01 00 05 01 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0E 00 07 FF 01 F1 00 +1000 SCTP.RECV +?? + +0 SCTP.SEND +01 00 05 01 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0E 00 07 FF 01 F0 00 + 1000 SCTP.RECV +?? + +1 SCTP.SEND +01 00 05 08 00 00 00 20 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 00 0F 00 08 00 00 00 00 +1000 SCTP.RECV +01 00 05 09 00 00 00 18 00 01 00 08 00 00 00 00 00 05 00 08 00 00 00 00 + + +1 SCTP.SEND +01 00 04 02 00 00 00 10 +1000 SCTP.RECV +01 00 04 04 00 00 00 08 +1000 SCTP.RECV +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 04 + +1 SCTP.SEND +01 00 03 02 00 00 00 10 +1000 SCTP.RECV +01 00 03 05 00 00 00 08 + + +test 3 +100 SCTP.SET ABORT + diff --git a/plat/m2ua/ut/testcate/SG(IUA)_Server.txt b/plat/m2ua/ut/testcate/SG(IUA)_Server.txt new file mode 100644 index 0000000..27c5a7d --- /dev/null +++ b/plat/m2ua/ut/testcate/SG(IUA)_Server.txt @@ -0,0 +1,16 @@ +#include "headfile.txt" + +test 1 udp +UDP.Set remote_port=MSG_PORT +UDP.Set local_port=MSG_PORT +UDP.Set remote_ip=MSC_IP + +1000 recv +?? +10 send +05 01 03 FF 01 F0 + +1000 recv +?? +10 send +05 01 03 FF 01 F1 diff --git a/plat/m2ua/ut/testcate/SG(M2UA)_Client.txt b/plat/m2ua/ut/testcate/SG(M2UA)_Client.txt new file mode 100644 index 0000000..1e7a78d --- /dev/null +++ b/plat/m2ua/ut/testcate/SG(M2UA)_Client.txt @@ -0,0 +1,79 @@ +#include "headfile.txt" + +test 1 udp +UDP.Set remote_port=MSG_PORT +UDP.Set local_port=MSG_PORT +UDP.Set remote_ip=MSC_IP + +0 send +A6 03 03 00 06 00 +10 send +A6 03 03 00 07 00 + +test 2 +SCTP.SET REMOTE_IP=MSC_IP +SCTP.SET REMOTE_PORT=M2UA_PORT +SCTP.SET LOCAL_PORT=M2UA_CPORT +SCTP.SET STREAM_ID=0 +5 SCTP.SET CLIENT +100 SCTP.SEND +01 00 03 01 00 00 00 10 00 11 00 08 ?? ?? ?? ?? //ip +1000 SCTP.RECV +01 00 03 04 00 00 00 08 +1000 SCTP.RECV +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 02 +0 SCTP.SEND +01 00 04 01 00 00 00 10 00 0B 00 08 00 00 00 01 +1000 SCTP.RECV +01 00 04 03 00 00 00 10 00 0B 00 08 00 00 00 01 +1000 SCTP.RECV +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 03 +0 SCTP.SEND +01 00 06 02 00 00 00 10 00 01 00 08 00 00 00 00 +1000 SCTP.RECV +01 00 06 03 00 00 00 10 00 01 00 08 00 00 00 00 +1 SCTP.SEND +02 00 06 01 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F0 00 +1000 SCTP.RECV +01 00 00 00 00 00 00 10 00 0C 00 08 00 00 00 01 +1 SCTP.SEND +01 00 99 01 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F0 00 +1000 SCTP.RECV +01 00 00 00 00 00 00 10 00 0C 00 08 00 00 00 03 +1 SCTP.SEND +01 00 06 99 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F0 00 +1000 SCTP.RECV +01 00 00 00 00 00 00 10 00 0C 00 08 00 00 00 04 + + +0 SCTP.SEND +01 00 06 01 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F0 00 +1000 SCTP.RECV +?? +0 SCTP.SEND +01 00 06 01 00 00 00 18 00 01 00 08 00 00 00 00 03 00 00 07 FF 01 F1 00 +1000 SCTP.RECV +?? + +1 SCTP.SEND +01 00 06 04 00 00 00 10 00 01 00 08 00 00 00 00 +1000 SCTP.RECV +?? + + +1 SCTP.SEND +01 00 04 02 00 00 00 10 +1000 SCTP.RECV +01 00 04 04 00 00 00 08 +1000 SCTP.RECV +01 00 00 01 00 00 00 10 00 0D 00 08 00 01 00 04 + +1 SCTP.SEND +01 00 03 02 00 00 00 10 +1000 SCTP.RECV +01 00 03 05 00 00 00 08 + + +test 3 +100 SCTP.SET ABORT + diff --git a/plat/m2ua/ut/testcate/SG(M2UA)_Server.txt b/plat/m2ua/ut/testcate/SG(M2UA)_Server.txt new file mode 100644 index 0000000..12e7651 --- /dev/null +++ b/plat/m2ua/ut/testcate/SG(M2UA)_Server.txt @@ -0,0 +1,15 @@ +#include "headfile.txt" + +test 1 udp +UDP.Set remote_port=MSG_PORT +UDP.Set local_port=MSG_PORT +UDP.Set remote_ip=MSC_IP +1000 recv +?? +10 send +06 03 03 FF 01 F0 + +1000 recv +?? +10 send +06 03 03 FF 01 F1 diff --git a/plat/m2ua/ut/testcate/headfile.txt b/plat/m2ua/ut/testcate/headfile.txt new file mode 100644 index 0000000..70b2b6a --- /dev/null +++ b/plat/m2ua/ut/testcate/headfile.txt @@ -0,0 +1,6 @@ +#define MSC_IP 172.54.245.133 +#define MSG_PORT 4955 +#define IUA_PORT 9900 +#define IUA_CPORT 19900 +#define M2UA_PORT 2904 +#define M2UA_CPORT 12904 \ No newline at end of file diff --git a/plat/m2ua/ut/xua_test/Makefile b/plat/m2ua/ut/xua_test/Makefile new file mode 100644 index 0000000..2756f34 --- /dev/null +++ b/plat/m2ua/ut/xua_test/Makefile @@ -0,0 +1,21 @@ +#================================================== +#Makefile for xUA Test. +#Created by YiZane in 2006/5/17 +#================================================== + +CC=gcc -c -Wall -g +#CC=gcc -c -Wall -g -D_testISDN +LINK=gcc -Wall -g +LINK_FLAGS=-L../../m2ua -lm2ua -L../../snmp -lsnmp -L../../debug -ldebug -L../../sccp -lsccp -L../../iptrans -liptrans -L../../public -lpublic -lLiS -lm +OBJ=xuatest.o + +xuatest:xuatest.o $(OBJ) + @echo Linking $@ + $(LINK) -o $@ $(OBJ) $(LINK_FLAGS) + #./xuatest + +xuatest.o:xuatest.c + $(CC) xuatest.c +clean: + rm -rf *.o *.a xuatest + diff --git a/plat/m2ua/ut/xua_test/conf/.svn/all-wcprops b/plat/m2ua/ut/xua_test/conf/.svn/all-wcprops new file mode 100644 index 0000000..7e0d7ca --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/all-wcprops @@ -0,0 +1,185 @@ +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf +END +ppsCrdConf.txt +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/ppsCrdConf.txt +END +cc_table.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/cc_table.conf +END +map_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/map_operation.conf +END +map_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/map_acn.conf +END +EirSysPara +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/EirSysPara +END +mnpf.conf +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/mnpf.conf +END +help_page +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/help_page +END +ppsConf.txt +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/ppsConf.txt +END +msc_conf +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/msc_conf +END +smsc_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/smsc_sys.conf +END +vlr.conf +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/vlr.conf +END +hlr_parambit.conf +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/hlr_parambit.conf +END +HlrSysPara +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/HlrSysPara +END +sccp_omt.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/sccp_omt.conf +END +wxc2exit.txt +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/wxc2exit.txt +END +xap_sysparam.conf +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/xap_sysparam.conf +END +menu_page +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/menu_page +END +profile +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/profile +END +system.ini +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/system.ini +END +smsc_csta.conf +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/smsc_csta.conf +END +iptrans.conf +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/iptrans.conf +END +sccp_sts.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/sccp_sts.conf +END +wxc2_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/wxc2_sys.conf +END +conv_prefix.conf +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/conv_prefix.conf +END +mtp3.conf +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/mtp3.conf +END +cap_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/cap_operation.conf +END +cap_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/cap_acn.conf +END +smsc_parambit.conf +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/smsc_parambit.conf +END +AucSysPara +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/AucSysPara +END +sccp.conf +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/m2ua/ut/xua_test/conf/sccp.conf +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/entries b/plat/m2ua/ut/xua_test/conf/.svn/entries new file mode 100644 index 0000000..14fa120 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/entries @@ -0,0 +1,1048 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/m2ua/ut/xua_test/conf +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +ppsCrdConf.txt +file + + + + +2012-12-28T03:06:18.671875Z +0cab88e841719ad33282bcad137a4fe5 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +10289 + +cc_table.conf +file + + + + +2012-12-28T03:06:18.671875Z +905d40d223b5e03afbd513a0bb0d5468 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4653 + +map_operation.conf +file + + + + +2012-12-28T03:06:18.687500Z +c9aa259b5a6f55d48d4e9fb2b3216bf1 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +2749 + +map_acn.conf +file + + + + +2012-12-28T03:06:18.703125Z +3dda7f1d4cd73cf0add3efab19ba2120 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1549 + +EirSysPara +file + + + + +2012-12-28T03:06:18.687500Z +18e9e910ae2cf804b6b0884bc4b11715 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +17476 + +mnpf.conf +file + + + + +2012-12-28T03:06:18.718750Z +6c2e453912d39ed00739bdce82880f38 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +718 + +help_page +file + + + + +2012-12-28T03:06:18.703125Z +cf329064faeb00741b9a1390677c1b27 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +561 + +ppsConf.txt +file + + + + +2012-12-28T03:06:18.718750Z +4e67b3c817ea28311051ac85dac83246 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4524 + +msc_conf +file + + + + +2012-12-28T03:06:18.750000Z +375b8d0c67a630a3428e864b0886e0db +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +220944 + +smsc_sys.conf +file + + + + +2012-12-28T03:06:18.734375Z +45262142dacd28473e6340ddb355870d +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +91 + +vlr.conf +file + + + + +2012-12-28T03:06:18.734375Z +da8bc7a10ab44d270e9bfb3758aae608 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +128 + +hlr_parambit.conf +file + + + + +2012-12-28T03:06:18.765625Z +8c63d6cbc22edc75874555b19a2c8ff0 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +20740 + +HlrSysPara +file + + + + +2012-12-28T03:06:18.750000Z +1bba29616a485b74f30bd176366fc5e8 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +7244 + +wxc2exit.txt +file + + + + +2012-12-28T03:06:18.781250Z +f255c211e4942c6ffc60fac1064d056f +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +74 + +xap_sysparam.conf +file + + + + +2012-12-28T03:06:18.765625Z +c15d7567bab7fe4156b81ac8b877e79e +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +13 + +sccp_omt.conf +file + + + + +2012-12-28T03:06:18.781250Z +4ea336284837018923cd711c5522b449 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +5364 + +menu_page +file + + + + +2012-12-28T03:06:18.796875Z +13714d5858af7ea700f418ab91e1d896 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +535 + +profile +file + + + + +2012-12-28T03:06:18.796875Z +e90cba89c770b32882af087201d9f5d7 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +808 + +system.ini +file + + + + +2012-12-28T03:06:18.796875Z +c880be42b7b1eb11ac2f4e3c2bf94fcd +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +212 + +smsc_csta.conf +file + + + + +2012-12-28T03:06:18.812500Z +2cdf64fc3b3b54dfe244b701f519c33b +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +384 + +iptrans.conf +file + + + + +2012-12-28T03:06:18.812500Z +0e6e44b414c6088e99da9fa397814bce +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +305 + +sccp_sts.conf +file + + + + +2012-12-28T03:06:18.828125Z +ba9ca1ac19fb80842a9785faee1b4356 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4429 + +wxc2_sys.conf +file + + + + +2012-12-28T03:06:18.828125Z +3f2293aa3f46f09aa172904f4b9015c3 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +63 + +conv_prefix.conf +file + + + + +2012-12-28T03:06:18.843750Z +a67462c7bdfce34b67c9cb220c871aeb +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4096 + +mtp3.conf +file + + + + +2012-12-28T03:06:18.843750Z +0679baf83d35d74657bdc60bccf40c94 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +96720 + +cap_operation.conf +file + + + + +2012-12-28T03:06:18.859375Z +0af63c0a61bf7aba8c361e2cbaa80924 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1234 + +cap_acn.conf +file + + + + +2012-12-28T03:06:18.859375Z +0e00c0be5fe70364f9ff02738cb1e127 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +216 + +smsc_parambit.conf +file + + + + +2012-12-28T03:06:18.875000Z +2f5ed5643666bf56b315026f8bb91f7c +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +5812 + +AucSysPara +file + + + + +2012-12-28T03:06:18.875000Z +e82efa7d8380730f081c38e9d3ba84f8 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +56 + +sccp.conf +file + + + + +2012-12-28T03:06:18.890625Z +357da9ad9f3d46c16a2c9c7c22f724c6 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +5225 + diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/AucSysPara.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/AucSysPara.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/AucSysPara.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/EirSysPara.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/EirSysPara.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/EirSysPara.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/HlrSysPara.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/HlrSysPara.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/HlrSysPara.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_acn.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_acn.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_operation.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_operation.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cap_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cc_table.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cc_table.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/cc_table.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/conv_prefix.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/conv_prefix.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/conv_prefix.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/help_page.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/help_page.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/help_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/iptrans.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/iptrans.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/iptrans.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_acn.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_acn.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_operation.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_operation.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/map_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/menu_page.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/menu_page.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/menu_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/mnpf.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/mnpf.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/mnpf.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/msc_conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/msc_conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/msc_conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/mtp3.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/mtp3.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/mtp3.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsConf.txt.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsConf.txt.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsConf.txt.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsCrdConf.txt.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsCrdConf.txt.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/ppsCrdConf.txt.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/profile.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/profile.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/profile.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_omt.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_omt.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_omt.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_sts.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_sts.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/sccp_sts.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_csta.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_csta.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_csta.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_sys.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/smsc_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/system.ini.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/system.ini.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/system.ini.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/vlr.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/vlr.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/vlr.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2exit.txt.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2exit.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/wxc2exit.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/AucSysPara.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/AucSysPara.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..d36dbec692520e98870f9b202ae12f402eefe680 GIT binary patch literal 56 dcmZQ%fP;5X02dH~vR*L5g%}k4fNT~H1^`U92#pQm^L5Vr|= literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/HlrSysPara.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/HlrSysPara.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..5e6c09f762c380d5202ba4d9dab854611a54aa17 GIT binary patch literal 7244 zcmeI%M~vM>9LI6*u5ul5h&Yb2Zs=V`DVX>6VkHC~O&S?fePBel_cEs-}KPa2Z;$ibO>ZZ=?prP&Z2WErSs@~x_~aEi|AsylrE#o=?c1%uA-}H zC9R@0G)@z=mL_Q(t*2oz91rW^(q%4pg&VulRjzi8Te`K!JnjiE_N1pg?HRB3na_RU z$G-HHuYKc}ejTuY2O@|A8K^)9CMbhCWFZel7>6=cp$<)0hINBAc*8WxM!k?P;*08& z>xe}>5>XtYEi;z!Ok^@sna)gBW_8YTo{K!rWv+6ao4m~Hf)%_FMO?^26}m7* zS=6I^R4g|u>JICOPTWx)-7Ux1n66mGD^bOjtW>2dQuqd=-7>i77u1}RFXrCrgtWs0V0}NPakMI4i2>YeXNgN zW_N4>Tfi2u1#AIZz!tCtYyn%q7O(|u0b9Tp_+JzlnC+u%vlHz%pV|J9?f7f~Ti`ea zHg)lWU$%NE+3PqG&Vjin%s7NoE6%=T&Puozu7g$3fi7GRV{il92sgpauo_CZ1=heg zOu$;0gmq9s57t8;ZiU-m18jsEZih{92iysF!QF5V+za=?X1E_7fCu3rco-gmN8vGe z9Jas{@FYA1Ps1~?6}G{4*a17?S$Gb1!EV?C&%<7L0rtU*@DjWXufVJD8oUl~z?<+E z?1#7E9e5YsgZJSB_z*sVkKq&e6h4E`;S2Z@zJjme0DJ@A!gugJ`~U~xNB9YThF{=U zAovY_hdI#&j#eur%C56y--aCAt=-5deU CaJaSr literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_acn.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_acn.conf.svn-base new file mode 100644 index 0000000..6f600a4 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_acn.conf.svn-base @@ -0,0 +1,7 @@ +#application context name configure file for CAP +total data length=3 + +#application context name data +No.1:50 02 // gsmSSF to gsmSCF +No.2:51 02 // assist handoff gsmSSF to gsmSCF +No.3:52 02 // gsmSRF to gsmSCF diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_operation.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_operation.conf.svn-base new file mode 100644 index 0000000..849f4ac --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/cap_operation.conf.svn-base @@ -0,0 +1,34 @@ +# operation code configure file for CAP +total data length=30 + +#operation code +No.1:00 04 5 // initial DP +No.2:16 02 5 // assist request instructions +No.3:17 02 20 // establish temporary connection +No.4:18 04 5 // disconnect forward connection +No.5:19 04 5 // connect to resource +No.6:20 04 5 // connect +No.7:22 04 5 // release call +No.8:23 04 5 // request report BCSM event +No.9:24 04 5 // event report BCSM +No.10:31 04 5 // continue +No.11:33 04 5 // reset timer +No.12:34 04 5 // furnish charging information +No.13:35 04 5 // apply charging +No.14:36 04 5 // apply charging report +No.15:44 04 5 // call information report +No.16:45 04 5 // call information request +No.17:46 04 5 // send charging information +No.18:47 04 60 // play announcement +No.19:48 01 60 // prompt and collect user information +No.20:49 04 5 // specialized resource report +No.21:53 04 5 // cancel +No.22:55 04 5 // activity test +No.23:60 04 5 // initial DPSMS +No.24:61 04 5 // Furnishing charging info.SMS +No.25:62 04 5 // connect DPSMS +No.26:63 04 5 // request SMS event +No.27:64 04 5 // event report SMS +No.28:65 04 5 // continue SMS +No.29:66 04 5 // release DPSMS +No.30:67 04 5 // reset timer DPSMS diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/cc_table.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/cc_table.conf.svn-base new file mode 100644 index 0000000..8d264ed --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/cc_table.conf.svn-base @@ -0,0 +1,215 @@ +# Country code table configure file + +#List the country code +0086; // China +0001; // Canada & USA +0007; // Kazakhstan & Kirighzia & Kyrgyzstan & Russia & Sakhalin & Tajikistan & Uzbekistan +0020; // Egypt +0027; // South Africa +0030; // Greece +0031; // Netherlands +0036; // Hungary +0039; // Italy +0040; // Bomania +0041; // Switzerland +0042; // Czech Republic & Slovakia +0043; // Austria +0044; // United Kingdom +0045; // Denmark +0046; // Sweden +0047; // Norway +0048; // Poland +0049; // Germany +0051; // Peru +0052; // South Korea +0053; // Cuba +0054; // Argentina +0055; // Brazil +0056; // Chile +0057; // Colombia +0058; // Venezuela +0060; // Malaysia +0061; // Australia +0062; // Indonesia +0063; // Philippines +0064; // New Zealand +0065; // Singapore +0066; // Thailand +0081; // Japan +0084; // Vietnam +0090; // Turkey +0091; // India +0092; // Pakistan +0093; // Afghanistan +0094; // Sri Lanka +0095; // Myanmar (Burma) +0098; // Iran +0212; // Morocco +0213; // Algeria +0216; // Tunisia +0218; // Libya +0220; // Gambia +0221; // Senegal Republic +0222; // Mauritania +0223; // Mali Republic +0224; // Guinea +0225; // Ivory Coast +0226; // Burkina Faso +0227; // Niger +0228; // Togo +0229; // Benin +0230; // Mauritius +0231; // Liberia +0232; // Sierra Leone +0233; // Ghana +0234; // Nigeria +0235; // Chad Republic +0236; // Central Africa Republic +0237; // Cameroon +0239; // Sao Tome +0240; // Equatorial Guinea +0241; // Gabon +0242; // Congo +0243; // Zaire +0244; // Angola +0245; // Guinea Bissau +0246; // Diego Garcia +0247; // Ascension Islands +0248; // Seychelles +0249; // Sudan +0250; // Rwanda +0251; // Ethiopia +0252; // Somalia +0253; // Djibouti +0254; // Kenya +0255; // Tanzania +0256; // Uganda +0257; // Burundi +0258; // Mozambigue +0259; // Zanzibar +0260; // Zambia +0261; // Madagascar +0262; // Reunion Island +0263; // Zimbabwe +0264; // Namibia +0265; // Malawi +0266; // Lesotho +0267; // Botswana +0268; // Swaziland +0269; // Comoros +0290; // St.Helena +0291; // Eritrea +0297; // Aruba +0298; // Faeroe Islands +0299; // Greenland +#2696 // Mayotte Island +0321; // Belgium +0331; // France +0339; // Monaco +0349; // Spain +0350; // Gibraltar +0351; // Portugal +0352; // Luxembourg +0353; // Ireland +0354; // Iceland +0355; // Albania +0356; // Malta +0357; // Cyprus +0358; // Finland +0359; // Bulgaria +0370; // Lithuania +0371; // Latvia +0372; // Estonia +0373; // Moldova +0374; // Armenia +0375; // Belarus +0376; // Andorra +0380; // Ukraine +0381; // Yugoslavia +0385; // Croatia +0386; // Slovenia +0387; // Bosnia Herzegovina +0389; // Macedonia +0395; // San Marino +0396; // Vatican City +0417; // Liechtenstein +0500; // Falkland Islands +0501; // Belize +0502; // Guatemala +0503; // EI Salvador +0504; // Honduras +0505; // Nicaragua +0506; // Costa Rica +0507; // Panama +0508; // St.Pierre +0509; // Haiti +0521; // Mexico Band 1 +0522; // Mexico Band 2 +0523; // Mexico Band 3 +0524; // Mexico Band 4 +0525; // Mexico Band 5 +0526; // Mexico Band 6 +0527; // Mexico Band 7 +0528; // Mexico Band 8 +0590; // Guadeloupe +0591; // Bolivia +0592; // Ecuador & Guyana +0594; // French Guiana +0595; // Paraguay +0596; // French Antilles +0597; // Suriname +0598; // Uruguay +0599; // Netherlands Antilles +#5399 // Guantanamo Bay +0670; // Saipan +0671; // Guam +0672; // Antarctica(Casey) & Antarctica(Scott) & Christmas/Cocos +0673; // Brunei +0674; // Nauru +0675; // Papau New Guinea +0676; // Tonga +0677; // Solomon Islands +0678; // Vanuatu +0679; // Fiji Islands +0680; // Palau +0681; // Wallis/Futuna +0682; // Cook Island +0683; // Niue Island +0684; // American Samoa +0685; // West Samoa +0686; // Kiribati +0687; // New Caledonia +0688; // Tuvalu Islands +0689; // French Polynesia +0691; // Micronesia +0692; // Marshall Islands +#6723 // Norfolk Island +0787; // Puerto Rico +0809; // Anguilla & Antigua & Bahamas & Barbados & Bermuda...... +0850; // North Korea +0852; // Hong Kong +0853; // Macao +0855; // Cambodia +0856; // Laos +0868; // Trinidad/Tobago +0880; // Bangladesh +0886; // Taiwan +0960; // Maldives +0961; // Lebanon +0962; // Jordan +0963; // Syria +0964; // Iraq +0965; // Kuwait +0966; // Saudi Arabia +0967; // Yemen Arab Rep. +0968; // Oman +0971; // United Arab Emirates +0972; // Israel +0973; // Bahrain +0974; // Qatar +0975; // Bhutan +0976; // Mongolia +0977; // Nepal +0994; // Azerbaijan +0995; // Georgia + diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/conv_prefix.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/conv_prefix.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..246d4636c205c2c322a91ad387ddd749c7e0af6e GIT binary patch literal 4096 zcmeHHTMmOT3~N9_Lc2^?9%J{v*g~PmDMs);g|F0g?bMBsIDf|gpR|(&LJ-)#Dy5PM zf#}3&wVSirBd#`x6vL)Lx zujkWwJKy-8uYB#Ne&!qB`p$3sKJWq+=pYTUzyvmMK_7ad3U!!pu zojE`E*WCHJ!OR(NHqu50;>k3Mwg$5z`^zCLc$?#JF+Mx92$$e8EWrep;R>w4DqMwY za2;+y12Nh1GnHd+=08$!#%hU58xp@g2(U#p29PD4lm#(yn7C*1drhfJcVcQ9A3an zcm=!g8s5NLcn9x+!vZY80xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd75 z0xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xa-9 Y3rz99xDWG@EI7_&ZvRZ59NFLh14RLh?*IS* literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/iptrans.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/iptrans.conf.svn-base new file mode 100644 index 0000000..ad5e902 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/iptrans.conf.svn-base @@ -0,0 +1,16 @@ +#ipconfig for pps +#port=type,num,interface +#type=UDP/TCP +#num=0-6 +#interface=BUFFER/DIRECT +4950=UDP,6,DIRECT +4953=UDP,3,BUFFER +4954=UDP,3,BUFFER +4955=UDP,3,BUFFER +4957=UDP,4,BUFFER +4965=TCP,3,BUFFER +4960=UDP,2,BUFFER +4970=UDP,2,BUFFER +4971=UDP,2,BUFFER +4972=UDP,2,BUFFER +4973=UDP,2,BUFFER diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/map_acn.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/map_acn.conf.svn-base new file mode 100644 index 0000000..f4bcb1e --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/map_acn.conf.svn-base @@ -0,0 +1,40 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 02 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/map_operation.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/map_operation.conf.svn-base new file mode 100644 index 0000000..60a0f5c --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/map_operation.conf.svn-base @@ -0,0 +1,67 @@ +# operation code configure file +total data length=63 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:09 01 20 // send parameter diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/menu_page.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/menu_page.svn-base new file mode 100644 index 0000000..facf381 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/menu_page.svn-base @@ -0,0 +1,13 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- PPS + d -- TCAP l -- SNMP + e -- XAPP m -- + f -- MSC n -- DEBUG + g -- VLR o -- AUC + h -- p -- EIR diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/mnpf.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/mnpf.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..6dfc892655d3317cdcacff37a3b36be98dad55dc GIT binary patch literal 718 pcmZQzKnG?91|}v@K~qZ;GfNXg19UZ`{Lv5qg#a5Qfef0!007nk1MmO< literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/msc_conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/msc_conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..43b066b4c03288b7dc0f2af2851c8f15ceecb7c7 GIT binary patch literal 220944 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 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/mtp3.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/mtp3.conf.svn-base new file mode 100644 index 0000000..c6b727e --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/mtp3.conf.svn-base @@ -0,0 +1,1408 @@ +#MTP3 CONFIGURE FILE + +[SERVICE NETWORK SP LEN] +[08] + +[LOCAL SP] +[000001] [000000] [001fd3] [002ee0] +[000001] [000000] [000000] [000202] + +[LINK ATTRIBUTE] +[00.00.00] [03.04.62] [ff.00.62] [05.04.62] +[7e.00.62] [14.00.62] [00.00.00] [00.00.00] +[00.00.00] [03.02.62] [00.00.00] [05.02.62] +[00.00.00] [15.00.62] [00.00.00] [00.00.00] +[00.00.00] [03.00.62] [00.00.00] [05.00.62] +[00.00.00] [00.00.00] [00.00.00] [0a.00.62] +[01.00.62] [03.06.62] [07.00.62] [05.06.62] +[00.00.00] [00.00.00] [00.00.00] [0b.00.62] +[1e.01.62] [40.00.62] [08.00.62] [05.08.62] +[00.00.00] [00.00.00] [00.00.00] [0c.00.62] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.01.00] [03.01.63] [08.01.63] [05.01.63] +[7f.00.63] [14.01.63] [00.00.00] [00.00.00] +[00.00.00] [03.03.63] [00.00.00] [00.00.00] +[05.03.63] [15.01.63] [00.00.00] [00.00.00] +[00.00.00] [03.05.63] [00.00.00] [05.05.63] +[00.00.00] [00.00.00] [00.00.00] [0a.01.63] +[00.00.00] [03.07.63] [07.01.63] [05.07.63] +[00.00.00] [00.00.00] [00.00.00] [0b.01.63] +[00.00.00] [40.01.63] [00.00.00] [05.09.63] +[00.00.00] [00.00.00] [00.00.00] [0c.01.63] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] + +[LINKSET ATTRIBUTE] +[000000.00] [000b03.02] [000000.00] [002eea.02] +[000000.00] [002eeb.02] [000000.00] [001fe7.02] +[001fe8.02] [000000.00] [0032d2.02] [0032d3.02] +[0032d4.02] [000000.00] [0032dc.03] [0032dd.03] +[000000.00] [000000.00] [000000.00] [000000.00] +[000003.02] [000004.02] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [002024.02] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[002eec.02] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [00007e.0b] [00007f.0b] + +[NATIONAL NETWORK SP] +[0032d2.0a.7e] [000b03.01.7f] [002081.01.7f] [000000.80.80] +[000003.14.7e] [000004.15.7e] [000000.80.80] [002eea.03.7e] +[000000.80.80] [000000.80.80] [001fe7.07.7e] [001fe8.08.7e] +[000000.80.80] [000000.80.80] [0032d3.0b.7e] [0032d4.0c.7e] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [00001b.1b.80] +[00001c.1c.80] [00001d.1d.80] [000000.80.80] [00001f.1f.80] +[002eeb.05.7e] [000000.80.80] [00003c.22.00] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [002024.1e.7f] [002eec.40.7e] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[NATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [00007e.7e.7f] +[00007f.7f.7e] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[LOCAL ACN] +030303030202020202030302020202020202020203030303030303030303030302020202 + +[INTERNATIONAL NETWORK ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[INTERNATIONAL NETWORK SPARE ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[NATIONAL NETWORK ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +030303030202020202030302020202020202020203030303030303030303030302020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[NATIONAL NETWORK SPARE ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/ppsConf.txt.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/ppsConf.txt.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..dacce58760522e91d573035235afff7c8e8f22c0 GIT binary patch literal 4524 zcmeHJyH3L}6m^=GA3$QhpU|dFX}TfA#*D;hk_)wzmmH@8rcMk@j2#*I9adJvcYu>N zZQMsnTZjb8m6G^Ae0+R-m4uMZrZot8e$dDZCFJNV=9_0!6_o=2UjftVbghonYc^X( zvfG^BPJB&E?s+qeR^BD1X)1xHX?3mRwqck`*;>aiI%-a<>Gj4z7OU&z>2-XPx)*`q z2sTHD3BX8zgMG*f?tn zMNmxGi6{AM9(YBS4sxH#GoWFJE}+LEa52{z=T!E%O|M^X09dBx*je2+dS`Q1KP&8I YT`EofvnGT%qvicokxGF|fie{M0@z3QuK)l5 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/ppsCrdConf.txt.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/ppsCrdConf.txt.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..5d2c23c889e254c069117ac22b754b2175103b2c GIT binary patch literal 10289 zcmeIu0Sy2E0K%a6Pi+qe5hx58Fkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ P0|pEjFkrxdf%}00C@}y5 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/profile.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/profile.svn-base new file mode 100644 index 0000000..da7324f --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/profile.svn-base @@ -0,0 +1,37 @@ +# /etc/profile + +# System wide environment and startup programs +# Functions and aliases go in /etc/bashrc + +PATH=".:$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/etc/rc.d/init.d:/usr/local/wxc2/bin" +PATH=/usr/java/jdk1.3/bin:$PATH + +ulimit -c 80000 +if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then + umask 002 +else + umask 022 +fi + +USER=`id -un` +LOGNAME=$USER +MAIL="/var/spool/mail/$USER" + +HOSTNAME=`/bin/hostname` +HISTSIZE=1000 + +if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then + INPUTRC=/etc/inputrc +fi +JAVA_COMPILER=javacomp ; export JAVA_COMPILER +LD_LIBRARY_PATH=/usr/local/mysql/lib ; export LD_LIBRARY_PATH +export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC + +for i in /etc/profile.d/*.sh ; do + if [ -x $i ]; then + . $i + fi +done + +unset i +PATH=/usr/local/wxc2/bin:$PATH diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp.conf.svn-base new file mode 100644 index 0000000..05efd02 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp.conf.svn-base @@ -0,0 +1,85 @@ +#SCCP Config file (R8V2_02) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 0 - 172.18.128.136 - +6 0 8675557122002 172.18.133.1 172.18.99.1 +7 0 8675557123005 172.18.133.133 172.18.99.1 +8 2 594694000001 172.18.98.1 172.18.99.1 +9 2 594694000007 172.18.98.1 172.18.99.1 +11 2 594694000000 172.18.98.1 172.18.99.1 +19 2 594694000009 172.18.98.1 172.18.99.1 +20 2 594694000010 172.18.98.1 172.18.99.1 +21 2 594694000011 172.18.128.1 172.18.129.1 +22 2 594694980012 172.18.100.1 172.18.101.1 +146 2 594694000004 172.18.98.1 172.18.99.1 +147 2 594694000003 172.18.98.1 172.18.99.1 +254 2 - 172.18.98.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 460020000000000 460029999999999 0 000001 6 1 7 +2 1 594694001000 594694009998 2 001FD3 6 1 7 +3 1 594694460000 594694469998 2 001FD3 6 1 7 +4 1 594694471000 594694479998 2 001FD3 6 1 7 +5 1 594694980012 594694980012 2 000003 8 0 7 +6 1 594694980013 594694980013 2 000004 8 0 7 +7 1 338 338 2 000B03 0 0 6 +8 1 33609 33609 2 000B03 0 0 6 +9 1 33603 33608 2 000B03 0 0 6 1 1 1 3383 +10 1 33610 33629 2 000B03 0 0 6 1 1 1 3383 +11 1 5906900 5906902 2 000B03 0 0 6 1 1 1 3385 +12 1 262692 262692 2 000B03 0 0 6 1 1 1 3382 +13 1 352 352 2 000B03 0 0 6 1 1 1 3383 +14 1 33660 33660 2 000B03 0 0 6 +15 1 33662 33662 2 000B03 0 0 6 +16 6 208100000000000 208109999999999 2 000B03 6 0 6 1 5 7 33609 +26 1 594694000002 594694000002 2 001FD3 6 1 7 +28 1 5946941 5946941 2 000B03 0 0 6 1 1 1 3385 +29 1 594694480000 594694979999 2 000B03 0 0 6 1 1 1 3385 +31 7 594694000100000 594694000199999 2 001FD3 6 1 7 1 15 1 594694000002 +34 1 5966960 5966961 2 000B03 0 0 6 1 1 1 3385 +37 1 59035 59035 2 000B03 0 0 6 +38 1 59669690 59669690 2 000B03 0 0 6 +41 1 59669620 59669649 2 000B03 0 0 6 +42 1 59069037 59069041 2 000B03 0 0 6 +43 1 59069030 59069035 2 000B03 0 0 6 +44 1 59069036 59069036 2 000B03 0 0 6 1 1 1 3385 +45 1 59069047 59069065 2 000B03 0 0 6 +46 1 59069067 59069068 2 000B03 0 0 6 +47 1 59069071 59069076 2 000B03 0 0 6 +48 1 59469420 59469426 2 000B03 0 0 6 +49 1 59469438 59469438 2 000B03 0 0 6 +50 1 59469440 59469445 2 000B03 0 0 6 +51 1 59669680 59669686 2 000B03 0 0 6 +52 1 59069066 59069066 2 000B03 0 0 6 1 1 1 3385 +54 1 59669699 59669699 2 000B03 0 0 6 +56 1 59069042 59069046 2 000B03 0 0 6 1 1 1 3385 +57 1 59069069 59069070 2 000B03 0 0 6 1 1 1 3385 +58 1 59069077 59069099 2 000B03 0 0 6 1 1 1 3385 +60 1 59669650 59669679 2 000B03 0 0 6 +61 1 59669691 59669698 2 000B03 0 0 6 +62 1 59469427 59469437 2 000B03 0 0 6 1 1 1 3385 +63 1 59469439 59469439 2 000B03 0 0 6 1 1 1 3385 +65 1 594694401000 594694409999 2 0000B3 0 0 6 1 1 1 3385 +70 6 746020000000000 746029999999999 2 000B03 0 0 6 1 5 7 59785 +71 1 597 597 2 000B03 0 0 6 +75 6 250020000000000 250029999999999 2 000B03 0 0 6 1 5 7 781296 +76 1 78 79 2 000B03 0 0 6 +78 6 2509900000000000 250999999999999 2 000B03 0 0 6 1 5 7 79037 +80 6 222100000000000 222109999999999 2 000B03 0 0 6 1 5 7 39349 +81 1 39 39 2 000B03 0 0 6 +85 6 738002000000000 738002999999999 2 000B03 0 0 6 1 6 7 592640 +86 1 592 592 2 000B03 0 0 6 +87 1 5926400001 5926400001 2 000B03 7 0 6 +90 6 338050000000000 338050999999999 2 000B03 0 0 6 1 6 7 187638 +91 1 18 18 2 000B03 0 0 6 +95 6 362510000000000 362519999999999 2 000B03 0 0 6 1 5 7 59952 +96 1 599 599 2 000B03 0 0 6 +98 6 4600000000000000 460009999999999 2 000B03 0 0 6 1 5 7 86139 +100 1 86 86 2 000B03 0 0 6 +102 6 724160000000000 7241699999999990 2 000B03 0 0 6 1 5 7 55016 +104 1 55 55 2 000B03 0 0 6 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_omt.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_omt.conf.svn-base new file mode 100644 index 0000000..d0e3f83 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_omt.conf.svn-base @@ -0,0 +1,87 @@ +#SCCP Config file (R8V0_04) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 2 594694000006 172.18.128.1 172.18.129.1 +6 2 594694000002 172.18.98.1 172.18.99.1 +7 2 594694000005 172.18.98.1 172.18.99.1 +8 2 594694000001 172.18.98.1 172.18.99.1 +9 2 594694000007 172.18.98.1 172.18.99.1 +10 2 594694000008 172.18.98.1 172.18.99.1 +11 2 594694000000 172.18.98.1 172.18.99.1 +19 2 594694000009 172.18.98.1 172.18.99.1 +20 2 594694000010 172.18.98.1 172.18.99.1 +21 2 594694000011 172.18.128.1 172.18.129.1 +22 2 594694980012 172.18.100.1 172.18.101.1 +146 2 594694000004 172.18.98.1 172.18.99.1 +147 2 594694000003 172.18.98.1 172.18.99.1 +254 2 - 172.18.98.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 340020000000000 340029999999999 2 001FD3 6 1 7 +2 1 594694001000 594694009998 2 001FD3 6 1 7 +3 1 594694460000 594694469998 2 001FD3 6 1 7 +4 1 594694471000 594694479998 2 001FD3 6 1 7 +5 1 594694980012 594694980012 2 000003 8 0 7 +6 1 594694980013 594694980013 2 000004 8 0 7 +7 1 338 338 2 000B03 0 0 6 +8 1 33609 33609 2 000B03 0 0 6 +9 1 33603 33608 2 000B03 0 0 6 1 1 1 3383 +10 1 33610 33629 2 000B03 0 0 6 1 1 1 3383 +11 1 5906900 5906902 2 000B03 0 0 6 1 1 1 3385 +12 1 262692 262692 2 000B03 0 0 6 1 1 1 3382 +13 1 352 352 2 000B03 0 0 6 1 1 1 3383 +14 1 33660 33660 2 000B03 0 0 6 +15 1 33662 33662 2 000B03 0 0 6 +16 6 208100000000000 208109999999999 2 000B03 6 0 6 1 5 7 33609 +26 1 594694000002 594694000002 2 001FD3 6 1 7 +28 1 5946941 5946941 2 000B03 0 0 6 1 1 1 3385 +29 1 594694480000 594694979999 2 000B03 0 0 6 1 1 1 3385 +#30 7 5946940001000000 5946940001099999 2 001FD3 6 1 7 1 16 1 594694000002 +31 7 594694000100000 594694000199999 2 001FD3 6 1 7 1 15 1 594694000002 +34 1 5966960 5966961 2 000B03 0 0 6 1 1 1 3385 +37 1 59035 59035 2 000B03 0 0 6 +38 1 59669690 59669690 2 000B03 0 0 6 +41 1 59669620 59669649 2 000B03 0 0 6 +42 1 59069037 59069041 2 000B03 0 0 6 +43 1 59069030 59069035 2 000B03 0 0 6 +44 1 59069036 59069036 2 000B03 0 0 6 1 1 1 3385 +45 1 59069047 59069065 2 000B03 0 0 6 +46 1 59069067 59069068 2 000B03 0 0 6 +47 1 59069071 59069076 2 000B03 0 0 6 +48 1 59469420 59469426 2 000B03 0 0 6 +49 1 59469438 59469438 2 000B03 0 0 6 +50 1 59469440 59469445 2 000B03 0 0 6 +51 1 59669680 59669686 2 000B03 0 0 6 +52 1 59069066 59069066 2 000B03 0 0 6 1 1 1 3385 +54 1 59669699 59669699 2 000B03 0 0 6 +56 1 59069042 59069046 2 000B03 0 0 6 1 1 1 3385 +57 1 59069069 59069070 2 000B03 0 0 6 1 1 1 3385 +58 1 59069077 59069099 2 000B03 0 0 6 1 1 1 3385 +60 1 59669650 59669679 2 000B03 0 0 6 +61 1 59669691 59669698 2 000B03 0 0 6 +62 1 59469427 59469437 2 000B03 0 0 6 1 1 1 3385 +63 1 59469439 59469439 2 000B03 0 0 6 1 1 1 3385 +65 1 594694401000 594694409999 2 0000B3 0 0 6 1 1 1 3385 +70 6 746020000000000 746029999999999 2 000B03 0 0 6 1 5 7 59785 +71 1 597 597 2 000B03 0 0 6 +75 6 250020000000000 250029999999999 2 000B03 0 0 6 1 5 7 781296 +76 1 78 79 2 000B03 0 0 6 +78 6 2509900000000000 250999999999999 2 000B03 0 0 6 1 5 7 79037 +80 6 222100000000000 222109999999999 2 000B03 0 0 6 1 5 7 39349 +81 1 39 39 2 000B03 0 0 6 +85 6 738002000000000 738002999999999 2 000B03 0 0 6 1 6 7 592640 +86 1 592 592 2 000B03 0 0 6 +87 1 5926400001 5926400001 2 000B03 7 0 6 +90 6 338050000000000 338050999999999 2 000B03 0 0 6 1 6 7 187638 +91 1 18 18 2 000B03 0 0 6 +95 6 362510000000000 362519999999999 2 000B03 0 0 6 1 5 7 59952 +96 1 599 599 2 000B03 0 0 6 +98 6 4600000000000000 460009999999999 2 000B03 0 0 6 1 5 7 86139 +100 1 86 86 2 000B03 0 0 6 +102 6 724160000000000 7241699999999990 2 000B03 0 0 6 1 5 7 55016 +104 1 55 55 2 000B03 0 0 6 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_sts.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_sts.conf.svn-base new file mode 100644 index 0000000..e54b7fe --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/sccp_sts.conf.svn-base @@ -0,0 +1,74 @@ +#SCCP Config file (R8V0_04) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 3 - 172.18.128.1 172.18.129.1 +6 3 74113779892 172.18.98.1 172.18.99.1 +7 3 74113779891 172.18.98.1 172.18.99.1 +8 3 74113779890 172.18.98.1 172.18.99.1 +9 3 74113779895 172.18.98.1 172.18.99.1 +10 3 74113779894 172.18.98.1 172.18.99.1 +11 3 74113779896 172.18.98.1 172.18.99.1 +19 3 - 172.18.98.1 172.18.99.1 +20 3 - 172.18.98.1 172.18.99.1 +21 3 - 172.18.98.1 172.18.99.1 +22 0 - 172.18.98.1 172.18.99.1 +146 3 - 172.18.98.1 172.18.99.1 +147 3 74113779899 172.18.98.1 172.18.99.1 +254 3 - 172.18.98.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 250121300000000 250121300004999 2 000001 6 1 7 +1 1 74113770000 74113779899 2 000001 6 1 7 +3 1 74113779897 74113779897 3 000101 22 0 7 +4 1 74113779898 74113779898 3 000202 22 0 7 +5 1 74113779890 74113779890 3 003707 8 0 7 +6 1 74113779891 74113779891 3 003707 7 0 7 +7 1 74113779892 74113779892 3 003707 6 0 7 +8 1 74113779894 74113779894 3 003707 10 0 7 +11 7 7902541300000000 7902541300004999 3 003707 6 1 7 1 16 1 74113779892 +13 1 74113621997 74113621997 3 003708 8 0 7 +14 1 79025719995 79025719995 3 003708 11 0 7 +15 1 74113621998 74113621998 3 003708 7 0 7 +16 1 74113621999 74113621999 3 003708 6 0 7 +20 1 79025700999 79025700999 3 003708 6 0 7 +21 1 79025719000 79025719000 3 003708 7 0 7 +22 6 250123000049173 250123000049173 2 000001 6 0 7 +23 6 250123000548881 250123000548881 2 000001 6 1 7 +24 6 250123000548882 250123000548882 2 000001 6 1 7 +25 6 250121000109094 250121000109095 3 003708 6 0 6 1 5 7 790254 +26 6 250123000367371 250123000367371 2 000001 6 1 7 +27 6 250026510040021 250026510040021 3 003708 6 0 6 1 5 7 781296 +28 6 250121100011572 250121100011572 3 003708 6 0 6 1 5 7 790254 +30 6 250058899904676 250058899904676 3 003708 6 0 6 1 5 7 790298 +31 1 79139889999 79139889999 3 003708 7 0 7 +32 1 79029889998 79029889998 3 003708 6 0 7 +33 1 74113779896 74113779896 3 003707 11 0 7 +34 1 79025110001 79025110001 3 003708 6 0 7 +35 1 79025110002 79025110002 3 003708 7 0 7 +36 6 250121100008643 250121100008643 2 000001 6 1 7 +37 6 250123000016797 250123000016797 2 000001 6 1 7 +38 6 250123000003240 250123000003240 3 003708 6 0 6 1 5 7 790254 +39 6 250121000118255 250121000118255 2 000001 6 1 7 +41 6 250021020465012 250021020465012 3 003708 6 0 6 1 5 7 781296 +49 6 250018580019726 250018580019726 3 003708 6 0 6 1 5 7 7095 +50 6 250125067201454 250125067201454 3 003708 6 0 6 1 5 7 790254 +51 6 250121000118256 250121000118256 2 000001 6 1 7 +52 6 250121000118601 250121000118601 2 000001 6 1 7 +53 6 250121000070390 250121000070390 2 000001 6 1 7 +54 6 250121100006360 250121100006360 2 000001 6 1 7 +57 6 250010000000000 250019999999999 3 003708 6 0 6 1 5 7 7095 +58 6 250020000000000 250029999999999 3 003708 6 0 6 1 5 7 781296 +59 6 250030000000000 250039999999999 3 003708 6 0 6 1 5 7 7831 +60 6 250040000000000 250049999999999 3 003708 6 0 6 1 5 7 7902933 +62 6 250070000000000 250079999999999 3 003708 6 0 6 1 6 7 7902370 +63 6 250100000000000 250109999999999 3 003708 6 0 6 1 6 7 790245 +64 6 250130000000000 250139999999999 3 003708 6 0 6 1 5 7 79160 +65 6 250150000000000 250159999999999 3 003708 6 0 6 1 5 7 790237081 +66 6 250160000000000 250169999999999 3 003708 6 0 6 1 5 7 7902557 +67 6 250170000000000 250179999999999 3 003708 6 0 6 1 6 7 7346 +200 6 2500500000000000 250059999999999 3 003708 6 0 6 1 5 7 790298 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_csta.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_csta.conf.svn-base new file mode 100644 index 0000000..a9a11f0 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_csta.conf.svn-base @@ -0,0 +1,21 @@ +# This file defines the SMSC CSTA row +# The max number of row is 20 +# Attention: When you want to define the Entity name, the name of "MS" "All" and "Other" is reserved + +# define the entity who send short message to SMSC +Receive from: +MS +PPS +VMS +#VMS+PPS +Other +#All + +# define the entity who receive short message from SMSC +Send to: +MS +PPS +VMS +#VMS+PPS +Other +#All diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_parambit.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/smsc_parambit.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..3871a69a3664ce659da7d14dbda012bb4882b3f0 GIT binary patch literal 5812 zcmeH}zi-n(6vxj&w5o-wG-5`gGetC^9a&1L7#t!ZDs@8Tmt+YuP|Co7IyMW!r7i7$ zz>tXv#De&DK>h=mxbywU^UFK?>^hN?^hr`wr&x?2N z9W%y~gt4Dr7>jpaoU#UYQ=_SjIWa)=%xhzi8i~5%$r)lk3+HM+=V#KG)5g3u2B|T* zY3R(VUQJQ2Ua!w9XTNZKwcWYBw$8^dUz6!%wb_D5rmoAp_4zGYaf=J*k-ei|93OGI zr8p0QjZspVC&FiU)69oN@m1sA7 zH8x?{5k-4XVaWLLqFfO_%kc?&>4~b*q-B;Hep>pg@*z$-4D}&By)jT}v{?aNL}4 zvC>swANZdC&G!9p4V;d|`U!(^-0({3xEo+znt^lce%<2uh~1S{b<~g)8|yjE)Gdx1 zc1gWQu{EP~tM`(l2Ar|oD_obZt5WkxvZtjpsdZ0Fds6J0_2?g)9;MhW+OZCeT9plD znK{=;eQejQRoPIg<+JTtwkjLSw|ur;-%@OzYbu(zkPVBgjy|KWv0qXL7qVe-F$?=8 zwK2u+tgor8bR*Uc#~A-$QT~epJ#we_?uSh$QEZy%(5wHy0Xy%h89T2!j^63p2ffnMzAh#&^F)%D>V+3Om8ySP-EiKKB%`FT} MoebOz-Hcq!0mBvz761SM literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/vlr.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/vlr.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..9d07544eb297c454336e946254d89059a634837a GIT binary patch literal 128 zcmZQ$Wck0&<~Fls*#G})gg`i%F;+NMn2~{jVU190E0AI+{A}a0ppB8iftQ)VkRgeI zk&zLEnR(bU!lyE@K4f5EWM~KkiUHL=@og*X0@Ch&5SoE~Vo=ZoHpUMO3=q|iKqi88 GKmY)yy&Tm5 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2_sys.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2_sys.conf.svn-base new file mode 100644 index 0000000..5abf262 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2_sys.conf.svn-base @@ -0,0 +1,3 @@ +yizane=172.48.234.133; +pps-1=172.18.128.137; +heartbeat no=9 diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2exit.txt.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2exit.txt.svn-base new file mode 100644 index 0000000..50ffa42 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/.svn/text-base/wxc2exit.txt.svn-base @@ -0,0 +1,4 @@ +WXC2 procedure exit log + Time: Tue Jan 18 10:22:59 2005 + +Now module: MSC diff --git a/plat/m2ua/ut/xua_test/conf/.svn/text-base/xap_sysparam.conf.svn-base b/plat/m2ua/ut/xua_test/conf/.svn/text-base/xap_sysparam.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..e466c967f6985fd25e56e17a99934cfc623f84f8 GIT binary patch literal 13 UcmXrvV~X_4^n1tfj_=(&02@&SX#fBK literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/AucSysPara b/plat/m2ua/ut/xua_test/conf/AucSysPara new file mode 100644 index 0000000000000000000000000000000000000000..d36dbec692520e98870f9b202ae12f402eefe680 GIT binary patch literal 56 dcmZQ%fP;5X02dH~vR*L5g%}k4fNT~H1^`U92#pQm^L5Vr|= literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/HlrSysPara b/plat/m2ua/ut/xua_test/conf/HlrSysPara new file mode 100644 index 0000000000000000000000000000000000000000..5e6c09f762c380d5202ba4d9dab854611a54aa17 GIT binary patch literal 7244 zcmeI%M~vM>9LI6*u5ul5h&Yb2Zs=V`DVX>6VkHC~O&S?fePBel_cEs-}KPa2Z;$ibO>ZZ=?prP&Z2WErSs@~x_~aEi|AsylrE#o=?c1%uA-}H zC9R@0G)@z=mL_Q(t*2oz91rW^(q%4pg&VulRjzi8Te`K!JnjiE_N1pg?HRB3na_RU z$G-HHuYKc}ejTuY2O@|A8K^)9CMbhCWFZel7>6=cp$<)0hINBAc*8WxM!k?P;*08& z>xe}>5>XtYEi;z!Ok^@sna)gBW_8YTo{K!rWv+6ao4m~Hf)%_FMO?^26}m7* zS=6I^R4g|u>JICOPTWx)-7Ux1n66mGD^bOjtW>2dQuqd=-7>i77u1}RFXrCrgtWs0V0}NPakMI4i2>YeXNgN zW_N4>Tfi2u1#AIZz!tCtYyn%q7O(|u0b9Tp_+JzlnC+u%vlHz%pV|J9?f7f~Ti`ea zHg)lWU$%NE+3PqG&Vjin%s7NoE6%=T&Puozu7g$3fi7GRV{il92sgpauo_CZ1=heg zOu$;0gmq9s57t8;ZiU-m18jsEZih{92iysF!QF5V+za=?X1E_7fCu3rco-gmN8vGe z9Jas{@FYA1Ps1~?6}G{4*a17?S$Gb1!EV?C&%<7L0rtU*@DjWXufVJD8oUl~z?<+E z?1#7E9e5YsgZJSB_z*sVkKq&e6h4E`;S2Z@zJjme0DJ@A!gugJ`~U~xNB9YThF{=U zAovY_hdI#&j#eur%C56y--aCAt=-5deU CaJaSr literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/cap_acn.conf b/plat/m2ua/ut/xua_test/conf/cap_acn.conf new file mode 100644 index 0000000..6f600a4 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/cap_acn.conf @@ -0,0 +1,7 @@ +#application context name configure file for CAP +total data length=3 + +#application context name data +No.1:50 02 // gsmSSF to gsmSCF +No.2:51 02 // assist handoff gsmSSF to gsmSCF +No.3:52 02 // gsmSRF to gsmSCF diff --git a/plat/m2ua/ut/xua_test/conf/cap_operation.conf b/plat/m2ua/ut/xua_test/conf/cap_operation.conf new file mode 100644 index 0000000..849f4ac --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/cap_operation.conf @@ -0,0 +1,34 @@ +# operation code configure file for CAP +total data length=30 + +#operation code +No.1:00 04 5 // initial DP +No.2:16 02 5 // assist request instructions +No.3:17 02 20 // establish temporary connection +No.4:18 04 5 // disconnect forward connection +No.5:19 04 5 // connect to resource +No.6:20 04 5 // connect +No.7:22 04 5 // release call +No.8:23 04 5 // request report BCSM event +No.9:24 04 5 // event report BCSM +No.10:31 04 5 // continue +No.11:33 04 5 // reset timer +No.12:34 04 5 // furnish charging information +No.13:35 04 5 // apply charging +No.14:36 04 5 // apply charging report +No.15:44 04 5 // call information report +No.16:45 04 5 // call information request +No.17:46 04 5 // send charging information +No.18:47 04 60 // play announcement +No.19:48 01 60 // prompt and collect user information +No.20:49 04 5 // specialized resource report +No.21:53 04 5 // cancel +No.22:55 04 5 // activity test +No.23:60 04 5 // initial DPSMS +No.24:61 04 5 // Furnishing charging info.SMS +No.25:62 04 5 // connect DPSMS +No.26:63 04 5 // request SMS event +No.27:64 04 5 // event report SMS +No.28:65 04 5 // continue SMS +No.29:66 04 5 // release DPSMS +No.30:67 04 5 // reset timer DPSMS diff --git a/plat/m2ua/ut/xua_test/conf/cc_table.conf b/plat/m2ua/ut/xua_test/conf/cc_table.conf new file mode 100644 index 0000000..8d264ed --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/cc_table.conf @@ -0,0 +1,215 @@ +# Country code table configure file + +#List the country code +0086; // China +0001; // Canada & USA +0007; // Kazakhstan & Kirighzia & Kyrgyzstan & Russia & Sakhalin & Tajikistan & Uzbekistan +0020; // Egypt +0027; // South Africa +0030; // Greece +0031; // Netherlands +0036; // Hungary +0039; // Italy +0040; // Bomania +0041; // Switzerland +0042; // Czech Republic & Slovakia +0043; // Austria +0044; // United Kingdom +0045; // Denmark +0046; // Sweden +0047; // Norway +0048; // Poland +0049; // Germany +0051; // Peru +0052; // South Korea +0053; // Cuba +0054; // Argentina +0055; // Brazil +0056; // Chile +0057; // Colombia +0058; // Venezuela +0060; // Malaysia +0061; // Australia +0062; // Indonesia +0063; // Philippines +0064; // New Zealand +0065; // Singapore +0066; // Thailand +0081; // Japan +0084; // Vietnam +0090; // Turkey +0091; // India +0092; // Pakistan +0093; // Afghanistan +0094; // Sri Lanka +0095; // Myanmar (Burma) +0098; // Iran +0212; // Morocco +0213; // Algeria +0216; // Tunisia +0218; // Libya +0220; // Gambia +0221; // Senegal Republic +0222; // Mauritania +0223; // Mali Republic +0224; // Guinea +0225; // Ivory Coast +0226; // Burkina Faso +0227; // Niger +0228; // Togo +0229; // Benin +0230; // Mauritius +0231; // Liberia +0232; // Sierra Leone +0233; // Ghana +0234; // Nigeria +0235; // Chad Republic +0236; // Central Africa Republic +0237; // Cameroon +0239; // Sao Tome +0240; // Equatorial Guinea +0241; // Gabon +0242; // Congo +0243; // Zaire +0244; // Angola +0245; // Guinea Bissau +0246; // Diego Garcia +0247; // Ascension Islands +0248; // Seychelles +0249; // Sudan +0250; // Rwanda +0251; // Ethiopia +0252; // Somalia +0253; // Djibouti +0254; // Kenya +0255; // Tanzania +0256; // Uganda +0257; // Burundi +0258; // Mozambigue +0259; // Zanzibar +0260; // Zambia +0261; // Madagascar +0262; // Reunion Island +0263; // Zimbabwe +0264; // Namibia +0265; // Malawi +0266; // Lesotho +0267; // Botswana +0268; // Swaziland +0269; // Comoros +0290; // St.Helena +0291; // Eritrea +0297; // Aruba +0298; // Faeroe Islands +0299; // Greenland +#2696 // Mayotte Island +0321; // Belgium +0331; // France +0339; // Monaco +0349; // Spain +0350; // Gibraltar +0351; // Portugal +0352; // Luxembourg +0353; // Ireland +0354; // Iceland +0355; // Albania +0356; // Malta +0357; // Cyprus +0358; // Finland +0359; // Bulgaria +0370; // Lithuania +0371; // Latvia +0372; // Estonia +0373; // Moldova +0374; // Armenia +0375; // Belarus +0376; // Andorra +0380; // Ukraine +0381; // Yugoslavia +0385; // Croatia +0386; // Slovenia +0387; // Bosnia Herzegovina +0389; // Macedonia +0395; // San Marino +0396; // Vatican City +0417; // Liechtenstein +0500; // Falkland Islands +0501; // Belize +0502; // Guatemala +0503; // EI Salvador +0504; // Honduras +0505; // Nicaragua +0506; // Costa Rica +0507; // Panama +0508; // St.Pierre +0509; // Haiti +0521; // Mexico Band 1 +0522; // Mexico Band 2 +0523; // Mexico Band 3 +0524; // Mexico Band 4 +0525; // Mexico Band 5 +0526; // Mexico Band 6 +0527; // Mexico Band 7 +0528; // Mexico Band 8 +0590; // Guadeloupe +0591; // Bolivia +0592; // Ecuador & Guyana +0594; // French Guiana +0595; // Paraguay +0596; // French Antilles +0597; // Suriname +0598; // Uruguay +0599; // Netherlands Antilles +#5399 // Guantanamo Bay +0670; // Saipan +0671; // Guam +0672; // Antarctica(Casey) & Antarctica(Scott) & Christmas/Cocos +0673; // Brunei +0674; // Nauru +0675; // Papau New Guinea +0676; // Tonga +0677; // Solomon Islands +0678; // Vanuatu +0679; // Fiji Islands +0680; // Palau +0681; // Wallis/Futuna +0682; // Cook Island +0683; // Niue Island +0684; // American Samoa +0685; // West Samoa +0686; // Kiribati +0687; // New Caledonia +0688; // Tuvalu Islands +0689; // French Polynesia +0691; // Micronesia +0692; // Marshall Islands +#6723 // Norfolk Island +0787; // Puerto Rico +0809; // Anguilla & Antigua & Bahamas & Barbados & Bermuda...... +0850; // North Korea +0852; // Hong Kong +0853; // Macao +0855; // Cambodia +0856; // Laos +0868; // Trinidad/Tobago +0880; // Bangladesh +0886; // Taiwan +0960; // Maldives +0961; // Lebanon +0962; // Jordan +0963; // Syria +0964; // Iraq +0965; // Kuwait +0966; // Saudi Arabia +0967; // Yemen Arab Rep. +0968; // Oman +0971; // United Arab Emirates +0972; // Israel +0973; // Bahrain +0974; // Qatar +0975; // Bhutan +0976; // Mongolia +0977; // Nepal +0994; // Azerbaijan +0995; // Georgia + diff --git a/plat/m2ua/ut/xua_test/conf/conv_prefix.conf b/plat/m2ua/ut/xua_test/conf/conv_prefix.conf new file mode 100644 index 0000000000000000000000000000000000000000..246d4636c205c2c322a91ad387ddd749c7e0af6e GIT binary patch literal 4096 zcmeHHTMmOT3~N9_Lc2^?9%J{v*g~PmDMs);g|F0g?bMBsIDf|gpR|(&LJ-)#Dy5PM zf#}3&wVSirBd#`x6vL)Lx zujkWwJKy-8uYB#Ne&!qB`p$3sKJWq+=pYTUzyvmMK_7ad3U!!pu zojE`E*WCHJ!OR(NHqu50;>k3Mwg$5z`^zCLc$?#JF+Mx92$$e8EWrep;R>w4DqMwY za2;+y12Nh1GnHd+=08$!#%hU58xp@g2(U#p29PD4lm#(yn7C*1drhfJcVcQ9A3an zcm=!g8s5NLcn9x+!vZY80xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd75 z0xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xa-9 Y3rz99xDWG@EI7_&ZvRZ59NFLh14RLh?*IS* literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/iptrans.conf b/plat/m2ua/ut/xua_test/conf/iptrans.conf new file mode 100644 index 0000000..ad5e902 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/iptrans.conf @@ -0,0 +1,16 @@ +#ipconfig for pps +#port=type,num,interface +#type=UDP/TCP +#num=0-6 +#interface=BUFFER/DIRECT +4950=UDP,6,DIRECT +4953=UDP,3,BUFFER +4954=UDP,3,BUFFER +4955=UDP,3,BUFFER +4957=UDP,4,BUFFER +4965=TCP,3,BUFFER +4960=UDP,2,BUFFER +4970=UDP,2,BUFFER +4971=UDP,2,BUFFER +4972=UDP,2,BUFFER +4973=UDP,2,BUFFER diff --git a/plat/m2ua/ut/xua_test/conf/map_acn.conf b/plat/m2ua/ut/xua_test/conf/map_acn.conf new file mode 100644 index 0000000..f4bcb1e --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/map_acn.conf @@ -0,0 +1,40 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 02 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) diff --git a/plat/m2ua/ut/xua_test/conf/map_operation.conf b/plat/m2ua/ut/xua_test/conf/map_operation.conf new file mode 100644 index 0000000..60a0f5c --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/map_operation.conf @@ -0,0 +1,67 @@ +# operation code configure file +total data length=63 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:09 01 20 // send parameter diff --git a/plat/m2ua/ut/xua_test/conf/menu_page b/plat/m2ua/ut/xua_test/conf/menu_page new file mode 100644 index 0000000..facf381 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/menu_page @@ -0,0 +1,13 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- PPS + d -- TCAP l -- SNMP + e -- XAPP m -- + f -- MSC n -- DEBUG + g -- VLR o -- AUC + h -- p -- EIR diff --git a/plat/m2ua/ut/xua_test/conf/mnpf.conf b/plat/m2ua/ut/xua_test/conf/mnpf.conf new file mode 100644 index 0000000000000000000000000000000000000000..6dfc892655d3317cdcacff37a3b36be98dad55dc GIT binary patch literal 718 pcmZQzKnG?91|}v@K~qZ;GfNXg19UZ`{Lv5qg#a5Qfef0!007nk1MmO< literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/msc_conf b/plat/m2ua/ut/xua_test/conf/msc_conf new file mode 100644 index 0000000000000000000000000000000000000000..43b066b4c03288b7dc0f2af2851c8f15ceecb7c7 GIT binary patch literal 220944 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 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/mtp3.conf b/plat/m2ua/ut/xua_test/conf/mtp3.conf new file mode 100644 index 0000000..c6b727e --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/mtp3.conf @@ -0,0 +1,1408 @@ +#MTP3 CONFIGURE FILE + +[SERVICE NETWORK SP LEN] +[08] + +[LOCAL SP] +[000001] [000000] [001fd3] [002ee0] +[000001] [000000] [000000] [000202] + +[LINK ATTRIBUTE] +[00.00.00] [03.04.62] [ff.00.62] [05.04.62] +[7e.00.62] [14.00.62] [00.00.00] [00.00.00] +[00.00.00] [03.02.62] [00.00.00] [05.02.62] +[00.00.00] [15.00.62] [00.00.00] [00.00.00] +[00.00.00] [03.00.62] [00.00.00] [05.00.62] +[00.00.00] [00.00.00] [00.00.00] [0a.00.62] +[01.00.62] [03.06.62] [07.00.62] [05.06.62] +[00.00.00] [00.00.00] [00.00.00] [0b.00.62] +[1e.01.62] [40.00.62] [08.00.62] [05.08.62] +[00.00.00] [00.00.00] [00.00.00] [0c.00.62] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.01.00] [03.01.63] [08.01.63] [05.01.63] +[7f.00.63] [14.01.63] [00.00.00] [00.00.00] +[00.00.00] [03.03.63] [00.00.00] [00.00.00] +[05.03.63] [15.01.63] [00.00.00] [00.00.00] +[00.00.00] [03.05.63] [00.00.00] [05.05.63] +[00.00.00] [00.00.00] [00.00.00] [0a.01.63] +[00.00.00] [03.07.63] [07.01.63] [05.07.63] +[00.00.00] [00.00.00] [00.00.00] [0b.01.63] +[00.00.00] [40.01.63] [00.00.00] [05.09.63] +[00.00.00] [00.00.00] [00.00.00] [0c.01.63] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] + +[LINKSET ATTRIBUTE] +[000000.00] [000b03.02] [000000.00] [002eea.02] +[000000.00] [002eeb.02] [000000.00] [001fe7.02] +[001fe8.02] [000000.00] [0032d2.02] [0032d3.02] +[0032d4.02] [000000.00] [0032dc.03] [0032dd.03] +[000000.00] [000000.00] [000000.00] [000000.00] +[000003.02] [000004.02] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [002024.02] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[002eec.02] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [00007e.0b] [00007f.0b] + +[NATIONAL NETWORK SP] +[0032d2.0a.7e] [000b03.01.7f] [002081.01.7f] [000000.80.80] +[000003.14.7e] [000004.15.7e] [000000.80.80] [002eea.03.7e] +[000000.80.80] [000000.80.80] [001fe7.07.7e] [001fe8.08.7e] +[000000.80.80] [000000.80.80] [0032d3.0b.7e] [0032d4.0c.7e] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [00001b.1b.80] +[00001c.1c.80] [00001d.1d.80] [000000.80.80] [00001f.1f.80] +[002eeb.05.7e] [000000.80.80] [00003c.22.00] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [002024.1e.7f] [002eec.40.7e] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[NATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [00007e.7e.7f] +[00007f.7f.7e] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[LOCAL ACN] +030303030202020202030302020202020202020203030303030303030303030302020202 + +[INTERNATIONAL NETWORK ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[INTERNATIONAL NETWORK SPARE ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[NATIONAL NETWORK ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +030303030202020202030302020202020202020203030303030303030303030302020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[NATIONAL NETWORK SPARE ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + diff --git a/plat/m2ua/ut/xua_test/conf/ppsConf.txt b/plat/m2ua/ut/xua_test/conf/ppsConf.txt new file mode 100644 index 0000000000000000000000000000000000000000..dacce58760522e91d573035235afff7c8e8f22c0 GIT binary patch literal 4524 zcmeHJyH3L}6m^=GA3$QhpU|dFX}TfA#*D;hk_)wzmmH@8rcMk@j2#*I9adJvcYu>N zZQMsnTZjb8m6G^Ae0+R-m4uMZrZot8e$dDZCFJNV=9_0!6_o=2UjftVbghonYc^X( zvfG^BPJB&E?s+qeR^BD1X)1xHX?3mRwqck`*;>aiI%-a<>Gj4z7OU&z>2-XPx)*`q z2sTHD3BX8zgMG*f?tn zMNmxGi6{AM9(YBS4sxH#GoWFJE}+LEa52{z=T!E%O|M^X09dBx*je2+dS`Q1KP&8I YT`EofvnGT%qvicokxGF|fie{M0@z3QuK)l5 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/ppsCrdConf.txt b/plat/m2ua/ut/xua_test/conf/ppsCrdConf.txt new file mode 100644 index 0000000000000000000000000000000000000000..5d2c23c889e254c069117ac22b754b2175103b2c GIT binary patch literal 10289 zcmeIu0Sy2E0K%a6Pi+qe5hx58Fkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ P0|pEjFkrxdf%}00C@}y5 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/profile b/plat/m2ua/ut/xua_test/conf/profile new file mode 100644 index 0000000..da7324f --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/profile @@ -0,0 +1,37 @@ +# /etc/profile + +# System wide environment and startup programs +# Functions and aliases go in /etc/bashrc + +PATH=".:$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/etc/rc.d/init.d:/usr/local/wxc2/bin" +PATH=/usr/java/jdk1.3/bin:$PATH + +ulimit -c 80000 +if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then + umask 002 +else + umask 022 +fi + +USER=`id -un` +LOGNAME=$USER +MAIL="/var/spool/mail/$USER" + +HOSTNAME=`/bin/hostname` +HISTSIZE=1000 + +if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then + INPUTRC=/etc/inputrc +fi +JAVA_COMPILER=javacomp ; export JAVA_COMPILER +LD_LIBRARY_PATH=/usr/local/mysql/lib ; export LD_LIBRARY_PATH +export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC + +for i in /etc/profile.d/*.sh ; do + if [ -x $i ]; then + . $i + fi +done + +unset i +PATH=/usr/local/wxc2/bin:$PATH diff --git a/plat/m2ua/ut/xua_test/conf/sccp.conf b/plat/m2ua/ut/xua_test/conf/sccp.conf new file mode 100644 index 0000000..05efd02 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/sccp.conf @@ -0,0 +1,85 @@ +#SCCP Config file (R8V2_02) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 0 - 172.18.128.136 - +6 0 8675557122002 172.18.133.1 172.18.99.1 +7 0 8675557123005 172.18.133.133 172.18.99.1 +8 2 594694000001 172.18.98.1 172.18.99.1 +9 2 594694000007 172.18.98.1 172.18.99.1 +11 2 594694000000 172.18.98.1 172.18.99.1 +19 2 594694000009 172.18.98.1 172.18.99.1 +20 2 594694000010 172.18.98.1 172.18.99.1 +21 2 594694000011 172.18.128.1 172.18.129.1 +22 2 594694980012 172.18.100.1 172.18.101.1 +146 2 594694000004 172.18.98.1 172.18.99.1 +147 2 594694000003 172.18.98.1 172.18.99.1 +254 2 - 172.18.98.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 460020000000000 460029999999999 0 000001 6 1 7 +2 1 594694001000 594694009998 2 001FD3 6 1 7 +3 1 594694460000 594694469998 2 001FD3 6 1 7 +4 1 594694471000 594694479998 2 001FD3 6 1 7 +5 1 594694980012 594694980012 2 000003 8 0 7 +6 1 594694980013 594694980013 2 000004 8 0 7 +7 1 338 338 2 000B03 0 0 6 +8 1 33609 33609 2 000B03 0 0 6 +9 1 33603 33608 2 000B03 0 0 6 1 1 1 3383 +10 1 33610 33629 2 000B03 0 0 6 1 1 1 3383 +11 1 5906900 5906902 2 000B03 0 0 6 1 1 1 3385 +12 1 262692 262692 2 000B03 0 0 6 1 1 1 3382 +13 1 352 352 2 000B03 0 0 6 1 1 1 3383 +14 1 33660 33660 2 000B03 0 0 6 +15 1 33662 33662 2 000B03 0 0 6 +16 6 208100000000000 208109999999999 2 000B03 6 0 6 1 5 7 33609 +26 1 594694000002 594694000002 2 001FD3 6 1 7 +28 1 5946941 5946941 2 000B03 0 0 6 1 1 1 3385 +29 1 594694480000 594694979999 2 000B03 0 0 6 1 1 1 3385 +31 7 594694000100000 594694000199999 2 001FD3 6 1 7 1 15 1 594694000002 +34 1 5966960 5966961 2 000B03 0 0 6 1 1 1 3385 +37 1 59035 59035 2 000B03 0 0 6 +38 1 59669690 59669690 2 000B03 0 0 6 +41 1 59669620 59669649 2 000B03 0 0 6 +42 1 59069037 59069041 2 000B03 0 0 6 +43 1 59069030 59069035 2 000B03 0 0 6 +44 1 59069036 59069036 2 000B03 0 0 6 1 1 1 3385 +45 1 59069047 59069065 2 000B03 0 0 6 +46 1 59069067 59069068 2 000B03 0 0 6 +47 1 59069071 59069076 2 000B03 0 0 6 +48 1 59469420 59469426 2 000B03 0 0 6 +49 1 59469438 59469438 2 000B03 0 0 6 +50 1 59469440 59469445 2 000B03 0 0 6 +51 1 59669680 59669686 2 000B03 0 0 6 +52 1 59069066 59069066 2 000B03 0 0 6 1 1 1 3385 +54 1 59669699 59669699 2 000B03 0 0 6 +56 1 59069042 59069046 2 000B03 0 0 6 1 1 1 3385 +57 1 59069069 59069070 2 000B03 0 0 6 1 1 1 3385 +58 1 59069077 59069099 2 000B03 0 0 6 1 1 1 3385 +60 1 59669650 59669679 2 000B03 0 0 6 +61 1 59669691 59669698 2 000B03 0 0 6 +62 1 59469427 59469437 2 000B03 0 0 6 1 1 1 3385 +63 1 59469439 59469439 2 000B03 0 0 6 1 1 1 3385 +65 1 594694401000 594694409999 2 0000B3 0 0 6 1 1 1 3385 +70 6 746020000000000 746029999999999 2 000B03 0 0 6 1 5 7 59785 +71 1 597 597 2 000B03 0 0 6 +75 6 250020000000000 250029999999999 2 000B03 0 0 6 1 5 7 781296 +76 1 78 79 2 000B03 0 0 6 +78 6 2509900000000000 250999999999999 2 000B03 0 0 6 1 5 7 79037 +80 6 222100000000000 222109999999999 2 000B03 0 0 6 1 5 7 39349 +81 1 39 39 2 000B03 0 0 6 +85 6 738002000000000 738002999999999 2 000B03 0 0 6 1 6 7 592640 +86 1 592 592 2 000B03 0 0 6 +87 1 5926400001 5926400001 2 000B03 7 0 6 +90 6 338050000000000 338050999999999 2 000B03 0 0 6 1 6 7 187638 +91 1 18 18 2 000B03 0 0 6 +95 6 362510000000000 362519999999999 2 000B03 0 0 6 1 5 7 59952 +96 1 599 599 2 000B03 0 0 6 +98 6 4600000000000000 460009999999999 2 000B03 0 0 6 1 5 7 86139 +100 1 86 86 2 000B03 0 0 6 +102 6 724160000000000 7241699999999990 2 000B03 0 0 6 1 5 7 55016 +104 1 55 55 2 000B03 0 0 6 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/m2ua/ut/xua_test/conf/sccp_omt.conf b/plat/m2ua/ut/xua_test/conf/sccp_omt.conf new file mode 100644 index 0000000..d0e3f83 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/sccp_omt.conf @@ -0,0 +1,87 @@ +#SCCP Config file (R8V0_04) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 2 594694000006 172.18.128.1 172.18.129.1 +6 2 594694000002 172.18.98.1 172.18.99.1 +7 2 594694000005 172.18.98.1 172.18.99.1 +8 2 594694000001 172.18.98.1 172.18.99.1 +9 2 594694000007 172.18.98.1 172.18.99.1 +10 2 594694000008 172.18.98.1 172.18.99.1 +11 2 594694000000 172.18.98.1 172.18.99.1 +19 2 594694000009 172.18.98.1 172.18.99.1 +20 2 594694000010 172.18.98.1 172.18.99.1 +21 2 594694000011 172.18.128.1 172.18.129.1 +22 2 594694980012 172.18.100.1 172.18.101.1 +146 2 594694000004 172.18.98.1 172.18.99.1 +147 2 594694000003 172.18.98.1 172.18.99.1 +254 2 - 172.18.98.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 340020000000000 340029999999999 2 001FD3 6 1 7 +2 1 594694001000 594694009998 2 001FD3 6 1 7 +3 1 594694460000 594694469998 2 001FD3 6 1 7 +4 1 594694471000 594694479998 2 001FD3 6 1 7 +5 1 594694980012 594694980012 2 000003 8 0 7 +6 1 594694980013 594694980013 2 000004 8 0 7 +7 1 338 338 2 000B03 0 0 6 +8 1 33609 33609 2 000B03 0 0 6 +9 1 33603 33608 2 000B03 0 0 6 1 1 1 3383 +10 1 33610 33629 2 000B03 0 0 6 1 1 1 3383 +11 1 5906900 5906902 2 000B03 0 0 6 1 1 1 3385 +12 1 262692 262692 2 000B03 0 0 6 1 1 1 3382 +13 1 352 352 2 000B03 0 0 6 1 1 1 3383 +14 1 33660 33660 2 000B03 0 0 6 +15 1 33662 33662 2 000B03 0 0 6 +16 6 208100000000000 208109999999999 2 000B03 6 0 6 1 5 7 33609 +26 1 594694000002 594694000002 2 001FD3 6 1 7 +28 1 5946941 5946941 2 000B03 0 0 6 1 1 1 3385 +29 1 594694480000 594694979999 2 000B03 0 0 6 1 1 1 3385 +#30 7 5946940001000000 5946940001099999 2 001FD3 6 1 7 1 16 1 594694000002 +31 7 594694000100000 594694000199999 2 001FD3 6 1 7 1 15 1 594694000002 +34 1 5966960 5966961 2 000B03 0 0 6 1 1 1 3385 +37 1 59035 59035 2 000B03 0 0 6 +38 1 59669690 59669690 2 000B03 0 0 6 +41 1 59669620 59669649 2 000B03 0 0 6 +42 1 59069037 59069041 2 000B03 0 0 6 +43 1 59069030 59069035 2 000B03 0 0 6 +44 1 59069036 59069036 2 000B03 0 0 6 1 1 1 3385 +45 1 59069047 59069065 2 000B03 0 0 6 +46 1 59069067 59069068 2 000B03 0 0 6 +47 1 59069071 59069076 2 000B03 0 0 6 +48 1 59469420 59469426 2 000B03 0 0 6 +49 1 59469438 59469438 2 000B03 0 0 6 +50 1 59469440 59469445 2 000B03 0 0 6 +51 1 59669680 59669686 2 000B03 0 0 6 +52 1 59069066 59069066 2 000B03 0 0 6 1 1 1 3385 +54 1 59669699 59669699 2 000B03 0 0 6 +56 1 59069042 59069046 2 000B03 0 0 6 1 1 1 3385 +57 1 59069069 59069070 2 000B03 0 0 6 1 1 1 3385 +58 1 59069077 59069099 2 000B03 0 0 6 1 1 1 3385 +60 1 59669650 59669679 2 000B03 0 0 6 +61 1 59669691 59669698 2 000B03 0 0 6 +62 1 59469427 59469437 2 000B03 0 0 6 1 1 1 3385 +63 1 59469439 59469439 2 000B03 0 0 6 1 1 1 3385 +65 1 594694401000 594694409999 2 0000B3 0 0 6 1 1 1 3385 +70 6 746020000000000 746029999999999 2 000B03 0 0 6 1 5 7 59785 +71 1 597 597 2 000B03 0 0 6 +75 6 250020000000000 250029999999999 2 000B03 0 0 6 1 5 7 781296 +76 1 78 79 2 000B03 0 0 6 +78 6 2509900000000000 250999999999999 2 000B03 0 0 6 1 5 7 79037 +80 6 222100000000000 222109999999999 2 000B03 0 0 6 1 5 7 39349 +81 1 39 39 2 000B03 0 0 6 +85 6 738002000000000 738002999999999 2 000B03 0 0 6 1 6 7 592640 +86 1 592 592 2 000B03 0 0 6 +87 1 5926400001 5926400001 2 000B03 7 0 6 +90 6 338050000000000 338050999999999 2 000B03 0 0 6 1 6 7 187638 +91 1 18 18 2 000B03 0 0 6 +95 6 362510000000000 362519999999999 2 000B03 0 0 6 1 5 7 59952 +96 1 599 599 2 000B03 0 0 6 +98 6 4600000000000000 460009999999999 2 000B03 0 0 6 1 5 7 86139 +100 1 86 86 2 000B03 0 0 6 +102 6 724160000000000 7241699999999990 2 000B03 0 0 6 1 5 7 55016 +104 1 55 55 2 000B03 0 0 6 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/m2ua/ut/xua_test/conf/sccp_sts.conf b/plat/m2ua/ut/xua_test/conf/sccp_sts.conf new file mode 100644 index 0000000..e54b7fe --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/sccp_sts.conf @@ -0,0 +1,74 @@ +#SCCP Config file (R8V0_04) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 3 - 172.18.128.1 172.18.129.1 +6 3 74113779892 172.18.98.1 172.18.99.1 +7 3 74113779891 172.18.98.1 172.18.99.1 +8 3 74113779890 172.18.98.1 172.18.99.1 +9 3 74113779895 172.18.98.1 172.18.99.1 +10 3 74113779894 172.18.98.1 172.18.99.1 +11 3 74113779896 172.18.98.1 172.18.99.1 +19 3 - 172.18.98.1 172.18.99.1 +20 3 - 172.18.98.1 172.18.99.1 +21 3 - 172.18.98.1 172.18.99.1 +22 0 - 172.18.98.1 172.18.99.1 +146 3 - 172.18.98.1 172.18.99.1 +147 3 74113779899 172.18.98.1 172.18.99.1 +254 3 - 172.18.98.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 250121300000000 250121300004999 2 000001 6 1 7 +1 1 74113770000 74113779899 2 000001 6 1 7 +3 1 74113779897 74113779897 3 000101 22 0 7 +4 1 74113779898 74113779898 3 000202 22 0 7 +5 1 74113779890 74113779890 3 003707 8 0 7 +6 1 74113779891 74113779891 3 003707 7 0 7 +7 1 74113779892 74113779892 3 003707 6 0 7 +8 1 74113779894 74113779894 3 003707 10 0 7 +11 7 7902541300000000 7902541300004999 3 003707 6 1 7 1 16 1 74113779892 +13 1 74113621997 74113621997 3 003708 8 0 7 +14 1 79025719995 79025719995 3 003708 11 0 7 +15 1 74113621998 74113621998 3 003708 7 0 7 +16 1 74113621999 74113621999 3 003708 6 0 7 +20 1 79025700999 79025700999 3 003708 6 0 7 +21 1 79025719000 79025719000 3 003708 7 0 7 +22 6 250123000049173 250123000049173 2 000001 6 0 7 +23 6 250123000548881 250123000548881 2 000001 6 1 7 +24 6 250123000548882 250123000548882 2 000001 6 1 7 +25 6 250121000109094 250121000109095 3 003708 6 0 6 1 5 7 790254 +26 6 250123000367371 250123000367371 2 000001 6 1 7 +27 6 250026510040021 250026510040021 3 003708 6 0 6 1 5 7 781296 +28 6 250121100011572 250121100011572 3 003708 6 0 6 1 5 7 790254 +30 6 250058899904676 250058899904676 3 003708 6 0 6 1 5 7 790298 +31 1 79139889999 79139889999 3 003708 7 0 7 +32 1 79029889998 79029889998 3 003708 6 0 7 +33 1 74113779896 74113779896 3 003707 11 0 7 +34 1 79025110001 79025110001 3 003708 6 0 7 +35 1 79025110002 79025110002 3 003708 7 0 7 +36 6 250121100008643 250121100008643 2 000001 6 1 7 +37 6 250123000016797 250123000016797 2 000001 6 1 7 +38 6 250123000003240 250123000003240 3 003708 6 0 6 1 5 7 790254 +39 6 250121000118255 250121000118255 2 000001 6 1 7 +41 6 250021020465012 250021020465012 3 003708 6 0 6 1 5 7 781296 +49 6 250018580019726 250018580019726 3 003708 6 0 6 1 5 7 7095 +50 6 250125067201454 250125067201454 3 003708 6 0 6 1 5 7 790254 +51 6 250121000118256 250121000118256 2 000001 6 1 7 +52 6 250121000118601 250121000118601 2 000001 6 1 7 +53 6 250121000070390 250121000070390 2 000001 6 1 7 +54 6 250121100006360 250121100006360 2 000001 6 1 7 +57 6 250010000000000 250019999999999 3 003708 6 0 6 1 5 7 7095 +58 6 250020000000000 250029999999999 3 003708 6 0 6 1 5 7 781296 +59 6 250030000000000 250039999999999 3 003708 6 0 6 1 5 7 7831 +60 6 250040000000000 250049999999999 3 003708 6 0 6 1 5 7 7902933 +62 6 250070000000000 250079999999999 3 003708 6 0 6 1 6 7 7902370 +63 6 250100000000000 250109999999999 3 003708 6 0 6 1 6 7 790245 +64 6 250130000000000 250139999999999 3 003708 6 0 6 1 5 7 79160 +65 6 250150000000000 250159999999999 3 003708 6 0 6 1 5 7 790237081 +66 6 250160000000000 250169999999999 3 003708 6 0 6 1 5 7 7902557 +67 6 250170000000000 250179999999999 3 003708 6 0 6 1 6 7 7346 +200 6 2500500000000000 250059999999999 3 003708 6 0 6 1 5 7 790298 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/m2ua/ut/xua_test/conf/smsc_csta.conf b/plat/m2ua/ut/xua_test/conf/smsc_csta.conf new file mode 100644 index 0000000..a9a11f0 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/smsc_csta.conf @@ -0,0 +1,21 @@ +# This file defines the SMSC CSTA row +# The max number of row is 20 +# Attention: When you want to define the Entity name, the name of "MS" "All" and "Other" is reserved + +# define the entity who send short message to SMSC +Receive from: +MS +PPS +VMS +#VMS+PPS +Other +#All + +# define the entity who receive short message from SMSC +Send to: +MS +PPS +VMS +#VMS+PPS +Other +#All diff --git a/plat/m2ua/ut/xua_test/conf/smsc_parambit.conf b/plat/m2ua/ut/xua_test/conf/smsc_parambit.conf new file mode 100644 index 0000000000000000000000000000000000000000..3871a69a3664ce659da7d14dbda012bb4882b3f0 GIT binary patch literal 5812 zcmeH}zi-n(6vxj&w5o-wG-5`gGetC^9a&1L7#t!ZDs@8Tmt+YuP|Co7IyMW!r7i7$ zz>tXv#De&DK>h=mxbywU^UFK?>^hN?^hr`wr&x?2N z9W%y~gt4Dr7>jpaoU#UYQ=_SjIWa)=%xhzi8i~5%$r)lk3+HM+=V#KG)5g3u2B|T* zY3R(VUQJQ2Ua!w9XTNZKwcWYBw$8^dUz6!%wb_D5rmoAp_4zGYaf=J*k-ei|93OGI zr8p0QjZspVC&FiU)69oN@m1sA7 zH8x?{5k-4XVaWLLqFfO_%kc?&>4~b*q-B;Hep>pg@*z$-4D}&By)jT}v{?aNL}4 zvC>swANZdC&G!9p4V;d|`U!(^-0({3xEo+znt^lce%<2uh~1S{b<~g)8|yjE)Gdx1 zc1gWQu{EP~tM`(l2Ar|oD_obZt5WkxvZtjpsdZ0Fds6J0_2?g)9;MhW+OZCeT9plD znK{=;eQejQRoPIg<+JTtwkjLSw|ur;-%@OzYbu(zkPVBgjy|KWv0qXL7qVe-F$?=8 zwK2u+tgor8bR*Uc#~A-$QT~epJ#we_?uSh$QEZy%(5wHy0Xy%h89T2!j^63p2ffnMzAh#&^F)%D>V+3Om8ySP-EiKKB%`FT} MoebOz-Hcq!0mBvz761SM literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/vlr.conf b/plat/m2ua/ut/xua_test/conf/vlr.conf new file mode 100644 index 0000000000000000000000000000000000000000..9d07544eb297c454336e946254d89059a634837a GIT binary patch literal 128 zcmZQ$Wck0&<~Fls*#G})gg`i%F;+NMn2~{jVU190E0AI+{A}a0ppB8iftQ)VkRgeI zk&zLEnR(bU!lyE@K4f5EWM~KkiUHL=@og*X0@Ch&5SoE~Vo=ZoHpUMO3=q|iKqi88 GKmY)yy&Tm5 literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/conf/wxc2_sys.conf b/plat/m2ua/ut/xua_test/conf/wxc2_sys.conf new file mode 100644 index 0000000..5abf262 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/wxc2_sys.conf @@ -0,0 +1,3 @@ +yizane=172.48.234.133; +pps-1=172.18.128.137; +heartbeat no=9 diff --git a/plat/m2ua/ut/xua_test/conf/wxc2exit.txt b/plat/m2ua/ut/xua_test/conf/wxc2exit.txt new file mode 100644 index 0000000..50ffa42 --- /dev/null +++ b/plat/m2ua/ut/xua_test/conf/wxc2exit.txt @@ -0,0 +1,4 @@ +WXC2 procedure exit log + Time: Tue Jan 18 10:22:59 2005 + +Now module: MSC diff --git a/plat/m2ua/ut/xua_test/conf/xap_sysparam.conf b/plat/m2ua/ut/xua_test/conf/xap_sysparam.conf new file mode 100644 index 0000000000000000000000000000000000000000..e466c967f6985fd25e56e17a99934cfc623f84f8 GIT binary patch literal 13 UcmXrvV~X_4^n1tfj_=(&02@&SX#fBK literal 0 HcmV?d00001 diff --git a/plat/m2ua/ut/xua_test/xuatest.c b/plat/m2ua/ut/xua_test/xuatest.c new file mode 100644 index 0000000..cd34408 --- /dev/null +++ b/plat/m2ua/ut/xua_test/xuatest.c @@ -0,0 +1,293 @@ +/************************************************/ +/*Title: xuatest.c */ +/*Descr: Processor for xUA Unitest */ +/*Author: Yi Zane */ +/*Create: 2006-05-17 */ +/************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../public/includes.h" +#include "../../public/asn1.h" +#include "../../public/function.h" +#include "../../debug/debug.h" +#include "../../snmp/snmp.h" +#include "../../iptrans/iptrans.h" +#include "../m2ua.h" +#define TEST_PORT 4955 +#define xUA_HOST_IP pBYTE[0],pBYTE[1],pBYTE[2],pBYTE[3] +#define xUA_CLIENT_IP pBYTE[0],pBYTE[1],pBYTE[2],pBYTE[3] +static char clientip[20]; +static in_buffer *inbuf; +static out_buffer *outbuf; +struct itimerval itimer,old_itimer; + + +void QueryUP(); +void QueryIUA(); +void QueryM2UA(); +void On_Timer(); +void SetTimer(); +void init_shmPort_iptrans(WORD port,in_buffer ** inbuf,out_buffer **outbuf); +int recv_message(in_buffer *pbuf, message_list *pmsg); +int send_message(out_buffer *pbuf, message_list *pmsg); + +//-------------------------------------------------- +extern char hostip[20]; +extern char hostname[50]; +extern ulong host_ip; +extern int iptrMainInit(); +extern int m2ua_hex_to_ascii(BYTE *from_hex, BYTE from_len, BYTE *to_asc); + +int main(int argc, char *argv[]) +{ + pid_t pid; + BYTE* pBYTE; + + if(argc==2 && strstr(argv[1],"-d")) + { + if((pid=fork())!=0) + exit(0); + setsid(); + } + + init_shmPort_iptrans(TEST_PORT,&inbuf,&outbuf); + + debug_init(); + heartbeat_init(0x0400); + iptrMainInit(); + snmp_init(4957); + m2ua_init(); + + pBYTE = (BYTE*)&host_ip; + + { + //link param + //e1_to_linkset,e1_to_slc,e1_to_mtp3,e1_lk_type,e1_to_sg,e1_to_iid,remote_ip,inactive,inactive_tm,e1_to_alterMTP3 + BYTE linkparam0[]={0x00,0x00,xUA_HOST_IP,0x07,0x00,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP}; + BYTE linkparam1[]={0x01,0x01,xUA_HOST_IP,0x07,0x01,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP}; + BYTE linkparam2[]={0x02,0x02,xUA_HOST_IP,0x03,0x02,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP}; + BYTE linkparam3[]={0x03,0x03,xUA_HOST_IP,0x03,0x03,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP}; + set_m2ua_link(0,linkparam0); + set_m2ua_link(1,linkparam1); + set_m2ua_link(2,linkparam2); + set_m2ua_link(3,linkparam3); + } +#ifdef _testISDN + { + BYTE sgparam1[]={0x01,0x01,0x02,0xAC,0x36,0xF2,0x70}; //iua -server 172.54.242.112 + BYTE enable_lk[]={0xA5,0x01,0x03,0x00,0x07,0x00}; //iua A5 01 03 00 07 00 + set_m2ua_sg(1,sgparam1); //sg=1 iua -server + if(!put_xua_msg((xua_up_msg_t*)enable_lk)) + { + printf("Put message to xUA. Msg_Class = 0x%x\n", *enable_lk); + } + else + printf("Put message error\n"); + + } +#endif + + SetTimer(); + + while(1) + { + usleep(50); + } + return 1; +} + +void QueryUP() +{ + message_list msgbuf; + BYTE buf[256]; + BYTE *iua_msg; + BYTE *pBYTE; + static BYTE set_sgflag=1; + if(recv_message(inbuf, &msgbuf)==0) + return; + printf("Receive Message From User:%ld\n",msgbuf.msgSrcIP); + + + if(set_sgflag) + { + pBYTE = (BYTE*)&msgbuf.msgSrcIP; + sprintf(clientip,"%d.%d.%d.%d", xUA_CLIENT_IP); +#ifndef _testISDN + { + //enable,server,xUA_ack,ip + BYTE sgparam0[]={0x01,0x00,0x02,xUA_CLIENT_IP}; //iua -client + BYTE sgparam1[]={0x01,0x01,0x02,xUA_CLIENT_IP}; //iua -server + BYTE sgparam2[]={0x01,0x00,0x00,xUA_CLIENT_IP}; //m2ua -client + BYTE sgparam3[]={0x01,0x01,0x00,xUA_CLIENT_IP}; //m2ua -server + + set_m2ua_sg(0,sgparam0); //sg=0 iua -client + set_m2ua_sg(1,sgparam1); //sg=1 iua -server + set_m2ua_sg(2,sgparam2); //sg=2 m2ua -client + set_m2ua_sg(3,sgparam3); //sg=3 m2ua -server + } +#endif + set_sgflag = 0; + } + + + memset(buf,0,sizeof(buf)); + iua_msg = buf+RESERVE_FOR_IUAHEAD; + #ifndef _testISDN + memcpy(iua_msg, msgbuf.msgContent, msgbuf.msgLength); + #else + memcpy(iua_msg+3, msgbuf.msgContent, msgbuf.msgLength); + iua_msg[0]=IUA_QPTM_MSG;//msg_class + iua_msg[1]=1;//LINK + iua_msg[2]=msgbuf.msgLength+3;//len + #endif + + if(!put_xua_msg((xua_up_msg_t*)iua_msg)) + { + printf("Put message to xUA. Msg_Class = 0x%x\n", *iua_msg); + } + else + printf("Put message error\n"); +} + +void QueryIUA() +{ + message_list msgbuf; + xua_up_msg_t *msgToIUAup; + int msglen; + BYTE buf[256]; + + if((msglen=get_xua_msg(IUA_APP,&msgToIUAup)) < 0) + return; + if(msgToIUAup->msg_class==IUA_MGMT_CMD)//hreatbeat + return; + #ifndef _testISDN + memcpy(msgbuf.msgContent, msgToIUAup, msglen); + #else + memcpy(msgbuf.msgContent, msgToIUAup->msg.iua.content,msgToIUAup->msg.iua.len); + #endif + msgbuf.msgLength = msglen; + msgbuf.msgDstIP = inet_addr(clientip); + msgbuf.msgDstPort = TEST_PORT; + msgbuf.msgSrcPort = TEST_PORT; + m2ua_hex_to_ascii((BYTE *)msgToIUAup,msglen,buf); + printf("\33[31mQueryIUA:%s\33[37m\n",buf); + send_message(outbuf, &msgbuf); +} + +void QueryM2UA() +{ + message_list msgbuf; + m2ua_up_msg_t *msgToM2UAup; + int msglen; + BYTE buf[256]; + + if((msglen=get_m2ua_msg(&msgToM2UAup)) < 0) + return; + if(msgToM2UAup->sio==0xEF)//hreatbeat + return; + memcpy(msgbuf.msgContent, msgToM2UAup,msgToM2UAup->len+2); + msgbuf.msgLength = msgToM2UAup->len+2; + msgbuf.msgDstIP = inet_addr(clientip); + msgbuf.msgDstPort = TEST_PORT; + msgbuf.msgSrcPort = TEST_PORT; + m2ua_hex_to_ascii((BYTE *)msgToM2UAup,msgbuf.msgLength,buf); + printf("\33[31mQueryIUA:%s\33[37m\n",buf); + send_message(outbuf, &msgbuf); +} + + +void On_Timer() +{ + iptrans_timer(); + snmp_timer(); + debug_rt(); + m2ua_timer(); + + + QueryUP(); + QueryIUA(); + QueryM2UA(); +} + +void SetTimer() +{ + struct sigaction act; + act.sa_handler=On_Timer; + sigemptyset(&act.sa_mask); + act.sa_flags=0; + if(sigaction(SIGALRM,&act,NULL)<0) + { + perror("Produce Sigaction"); + exit(1); + } + + itimer.it_interval.tv_sec=0; + itimer.it_interval.tv_usec=10*1000; + itimer.it_value.tv_sec=0; + itimer.it_value.tv_usec=10*1000; + + if (setitimer(ITIMER_REAL,&itimer,&old_itimer) !=0 ) + { + printf("Setting Timer error! \n"); + exit(1); + } +} + + +void init_shmPort_iptrans(WORD port,in_buffer ** inbuf,out_buffer **outbuf) +{ + int shmid; + static iptrans_shm *pshm; + + if((shmid=shmget(IPTRANS_SHM_KEY,sizeof(iptrans_shm),IPTRANS_SHM_PERM))==-1) + { + if((shmid=shmget(IPTRANS_SHM_KEY,sizeof(iptrans_shm),IPTRANS_SHM_PERM|IPC_CREAT))==-1) + { + printf("fail to open share memory"); + exit(1); + } + } + if((pshm=(iptrans_shm *)shmat(shmid,0,0))==(iptrans_shm *)-1) + { + printf("fail to attach share memory"); + exit(1); + } + + *inbuf=&pshm->msgPortIn[port-PORT_BASE_NUM]; + (*inbuf)->msgReadSub = (*inbuf)->msgWriteSub=0; + *outbuf=&pshm->msgPortOut; + printf("init_shmPort_iptrans() complete...Port=%d\n",port); +} + +int recv_message(in_buffer *pbuf, message_list *pmsg) +{ + if (pbuf->msgReadSub == pbuf->msgWriteSub) + return 0; + memcpy(pmsg, &pbuf->msgList[pbuf->msgReadSub], sizeof(message_list)); + pbuf->msgReadSub=(pbuf->msgReadSub+1)%IN_LIST_NUM; + + return 1; +} + +int send_message(out_buffer *pbuf, message_list *pmsg) +{ + memcpy(&pbuf->msgList[pbuf->msgWriteSub], pmsg, sizeof(message_list)); + + pbuf->msgWriteSub=(pbuf->msgWriteSub+1)%OUT_LIST_NUM; + + if (pbuf->msgReadSub == pbuf->msgWriteSub) + pbuf->msgReadSub=(pbuf->msgReadSub+1)%OUT_LIST_NUM; + + return 1; +} + diff --git a/plat/mtp3/Makefile b/plat/mtp3/Makefile new file mode 100644 index 0000000..7663aa0 --- /dev/null +++ b/plat/mtp3/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = mtp3 +TYPE = plat + +DBUG_FLAGS_ADD = -DDEBUG -D_INCLUDE_M2UA -D_CDMA_SNMP +RELS_FLAGS_ADD = -D_INCLUDE_M2UA -D_CDMA_SNMP + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/mtp3/src/include/mtp3.h b/plat/mtp3/src/include/mtp3.h new file mode 100644 index 0000000..0157ddb --- /dev/null +++ b/plat/mtp3/src/include/mtp3.h @@ -0,0 +1,172 @@ +#include "../../../iptrans/src/include/iptrans.h" +#ifdef _INCLUDE_M2UA + #include "../../../m2ua/src/include/m2ua.h" +#endif +#ifndef _MTP3_HEAD_FILE +#define _MTP3_HEAD_FILE + +#define _up_message up_message +#define MAX_SS7_MSG_LEN 400 //272 + +typedef struct up_message{ + long dest_ip; + long dpc; + long opc; + BYTE cic[2]; + WORD link; + BYTE sio; +// BYTE len;/* len not include itself */ + WORD len;//long message + BYTE msgList[MAX_SS7_MSG_LEN]; +}up_message; + +typedef struct up_message_2{ + long dest_ip; + long dpc; + long opc; + BYTE cic[4]; + WORD link; + BYTE sio; // 13 for BICC +// BYTE len;/* len not include itself */ + WORD len;//long message + BYTE msgList[MAX_SS7_MSG_LEN]; +}up_message_2; + +typedef struct up_buffer /* user part buffer. user part:telephone user part, + isdn user part, and sccp part */ +{ + BYTE RSub; /* subscript of array msgList for reader */ + BYTE WSub; /* subscript of array msgList for writer */ + up_message msgNum[256];/* this buffer can storge up to 256 + messages */ +}up_buffer; + +typedef struct up_buffer_2 /* user part buffer. user part:telephone user part, + isdn user part, and sccp part */ +{ + BYTE RSub; /* subscript of array msgList for reader */ + BYTE WSub; /* subscript of array msgList for writer */ + up_message_2 msgNum[256];/* this buffer can storge up to 256 + messages */ +}up_buffer_2; + +#define _tup_shm tup_shm +typedef struct tup_shm { + up_buffer TM_Buf; + up_buffer MT_Buf; +} tup_shm; + +#define _isup_shm isup_shm +typedef struct isup_shm { + up_buffer IM_Buf; + up_buffer MI_Buf; +} isup_shm; + +#define _bicc_shm bicc_shm +typedef struct bicc_shm { + up_buffer_2 IM_Buf; + up_buffer_2 MI_Buf; +} bicc_shm; + +#define _sccp_shm sccp_shm +typedef struct sccp_shm { + up_buffer SM_Buf; + up_buffer MS_Buf; +} sccp_shm; + +typedef struct iprt1 +{ + BYTE pad[20];// __attribute__((packed)); + message_list io_msg __attribute__((packed)); +}iprt1; + +typedef struct mtp_primitive +{ + long pc; + BYTE nw_indicator; + BYTE availability; +}mtp_primitive; + +typedef struct primitive_to_tup +{ + mtp_primitive primitive[16]; + BYTE WSub; + BYTE RSub; +}primitive_to_tup; + +typedef struct primitive_to_isup +{ + mtp_primitive primitive[16]; + BYTE WSub; + BYTE RSub; +}primitive_to_isup; + +typedef struct primitive_to_bicc +{ + mtp_primitive primitive[16]; + BYTE WSub; + BYTE RSub; +}primitive_to_bicc; + +typedef struct primitive_to_sccp +{ + mtp_primitive primitive[16]; + BYTE WSub; + BYTE RSub; +}primitive_to_sccp; + +typedef struct mtp3_routing_result +{ + WORD tupMsgOutLink[256]; + WORD isupMsgOutLink[256]; + WORD biccMsgOutLink[256]; + WORD sccpMsgOutLink[256]; +}mtp3_routing_result; + +#define MTP3DB_CMD 0 +#define MTP3DB_SNMMSG 1 +#define MTP3DB_SCCPMSG 2 +#define MTP3DB_TUPMSG 3 +#define MTP3DB_ISUPMSG 4 +#define MTP3DB_ERROR 5 +#define MTP3DB_EVENT 6 +#define MTP3DB_ALLLKON 7 +#define MTP3DB_PFHB 8// platform heartbeat +#define MTP3DB_APP_APP_MSG 9// msg from app to app +#define MTP3DB_PRIMITIVE_MSG 10// msg from MTP3 to MTP2 +#define MTP3DB_BICCMSG 11 + +void mtp_shm_init(WORD moduleid_systemid, DWORD localip, DWORD peerip); +//moduleid = 8/9/11 vss/mss/aas +//void iptrans_init(); +void mtp3_proc(); +int tup_to_mtp3(up_message *msgptr); +int isup_to_mtp3(up_message *msgptr); +int bicc_to_mtp3(up_message_2 *msgptr); +int sccp_to_mtp3(up_message *msgptr); +int sccp_redirect(up_message *msgptr); +int bicc_redirect(up_message_2 *msgptr); +int isup_redirect(up_message *msgptr); +int tup_GetMsg(up_message *msgptr); +int isup_GetMsg(up_message *msgptr); +int bicc_GetMsg(up_message_2 *msgptr); +int sccp_GetMsg(up_message *msgptr); +int sccp_get_SPstate(mtp_primitive *ptr); +int isup_get_SPstate(mtp_primitive *ptr); +int bicc_get_SPstate(mtp_primitive *ptr); +int tup_get_SPstate(mtp_primitive *ptr); +BYTE *spc_to_acn(BYTE netID,ulong spc); +BYTE mtp3_ansiFlag(BYTE netID); +BYTE *check_MTP3LinkType(); +BYTE *check_MTP3LinkL2State(); +void MTP3_activate(ulong ip); +void MTP3_deactivate(ulong ip); +void MTP3_Enable_SubSystem(BYTE SubSystem); +void MTP3_Disable_SubSystem(BYTE SubSystem); +void mtp3_init_serial(char *Serial); +int mtp3_create_opc(BYTE nw, ulong opc); +int mtp3_delete_opc(BYTE nw, ulong opc); +int check_m3ua_rc_verify(DWORD rc, WORD link); +BYTE mtp3_check_dpc_equal_to_opc(BYTE nw, ulong dpc); + +#endif diff --git a/plat/mtp3/src/include/mtp3lite.h b/plat/mtp3/src/include/mtp3lite.h new file mode 100644 index 0000000..791202b --- /dev/null +++ b/plat/mtp3/src/include/mtp3lite.h @@ -0,0 +1,28 @@ +#ifndef _MTP3LITE_H +#define _MTP3LITE_H + +#include "mtp3lite_pub.h" + +typedef struct _mtp3lite_lk +{ + int connfd; + int cliSockfd; + WORD remote_port; + WORD local_inactive; + WORD local_reconnect; + WORD remote_inactive; + BYTE remote_inactive_timeouts; + WORD init_guard_timer; +}mtp3lite_lk; + +void mtp3lite_init(void); +void mtp3lite_timer(void); + +int put_mtp3lite_msg(BYTE *msg_ptr); + +#define MTP3LITE_TCP_FAILURE 16 +#define MTP3LITE_INACTIVITY_TIMEOUT 17 + +#define MTP3LITE_MSG_BUF_SIZE_PER_LINK 1024 + +#endif diff --git a/plat/mtp3/src/include/mtp3lite_pub.h b/plat/mtp3/src/include/mtp3lite_pub.h new file mode 100644 index 0000000..b5e604d --- /dev/null +++ b/plat/mtp3/src/include/mtp3lite_pub.h @@ -0,0 +1,53 @@ +#ifndef _MTP3LITE_PUB__H +#define _MTP3LITE_PUB__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned int DWORD; +#endif + +#endif diff --git a/plat/mtp3/src/include/mtpconst.h b/plat/mtp3/src/include/mtpconst.h new file mode 100644 index 0000000..693b2e0 --- /dev/null +++ b/plat/mtp3/src/include/mtpconst.h @@ -0,0 +1,579 @@ +#ifndef _T_ULL +#define _T_ULL + typedef unsigned long long ull; +#endif + + +#define SIGNAL_TFA 0x54 +#define SIGNAL_TFP 0x14 +#define SIGNAL_TRA 0x17 +#define SIGNAL_RST 0x15 +#define SIGNAL_COO 0x11 +#define SIGNAL_COA 0x21 +#define SIGNAL_CBD 0x51 +#define SIGNAL_CBA 0x61 +#define SIGNAL_ECO 0x12 +#define SIGNAL_ECA 0x22 +#define SIGNAL_LIN 0x16 +#define SIGNAL_LUN 0x26 +#define SIGNAL_LIA 0x36 +#define SIGNAL_LUA 0x46 +#define SIGNAL_LID 0x56 +#define SIGNAL_LFU 0x66 +#define SIGNAL_LLT 0x76 +#define SIGNAL_LRT 0x86 +#define SIGNAL_SLTM 0x11 +#define SIGNAL_SLTA 0x21 + + +#define MTP3_ISUP_IAM 0x01 +#define MTP3_ISUP_ACM 0x06 +#define MTP3_ISUP_CPG 0x2c +#define MTP3_ISUP_ANM 0x09 +#define MTP3_ISUP_REL 0x0c +#define MTP3_ISUP_RLC 0x10 +#define MTP3_ISUP_UBL 0x14 +#define MTP3_ISUP_UBA 0x16 +#define MTP3_ISUP_GRA 0x19 + + +#define MTP3_TUP_IAM 0x11 +#define MTP3_TUP_IAI 0x21 +#define MTP3_TUP_SAM 0x31 +#define MTP3_TUP_SAO 0x41 +#define MTP3_TUP_GSM 0x12 +#define MTP3_TUP_COT 0x32 +/*#define MTP3_TUP_CCF '0x42',*/ +#define MTP3_TUP_GRQ 0x13 +#define MTP3_TUP_ACM 0x14 +#define MTP3_TUP_SEC 0x15 +#define MTP3_TUP_CGC 0x25 +#define MTP3_TUP_CFL 0x55 +#define MTP3_TUP_SSB 0x65 +/*#define MTP3_TUP_SLB 0x1E, +#define MTP3_TUP_STB 0x2E,*/ +#define MTP3_TUP_UNN 0x75 +#define MTP3_TUP_LOS 0x85 +#define MTP3_TUP_SST 0x95 +#define MTP3_TUP_ACB 0xa5 +#define MTP3_TUP_DPN 0xb5 +#define MTP3_TUP_ANU 0x06 +#define MTP3_TUP_ANC 0x16 +#define MTP3_TUP_ANN 0x26 +#define MTP3_TUP_CBK 0x36 +#define MTP3_TUP_CLF 0x46 +#define MTP3_TUP_CCL 0x76 +#define MTP3_TUP_RLG 0x17 +#define MTP3_TUP_BLO 0x27 +#define MTP3_TUP_BLA 0x37 +#define MTP3_TUP_UBL 0x47 +#define MTP3_TUP_UBA 0x57 +#define MTP3_TUP_ADI 0x45 + + +#define MTP3_SCCP_CR 1 +#define MTP3_SCCP_CC 2 +#define MTP3_SCCP_CREF 3 +#define MTP3_SCCP_RLSD 4 +#define MTP3_SCCP_RLC 5 +#define MTP3_SCCP_DT1 6 +#define MTP3_SCCP_DT2 7 +#define MTP3_SCCP_AK 8 +#define MTP3_SCCP_UDT 9 +#define MTP3_SCCP_UDTS 10 +#define MTP3_SCCP_ED 11 +#define MTP3_SCCP_EA 12 +#define MTP3_SCCP_RSR 13 +#define MTP3_SCCP_RSC 14 +#define MTP3_SCCP_ERR 15 +#define MTP3_SCCP_IT 16 +#define MTP3_SCCP_XUDT 17 +#define MTP3_SCCP_XUDTS 18 +#define MTP3_SCCP_LUDT 19 +#define MTP3_SCCP_LUDTS 20 + + +#define BETWEEN_LS 0x00 +#define WITHIN_LS 0x01 + +#define NORMAL_LS 0x00 +#define ALTERNATIVE_LS 0x01 +#define NO_ROUTE 0x02 + +/**************************************TCOC INPUT**************************************/ +/* TCOC INPUT FROM L2 */ + +#define TCOC_L2_BSNT 1 +#define TCOC_L2_BSNT_CANNOT_RECOVER 2 +#define TCOC_L2_RETRIEVED_MSG 3 +#define TCOC_L2_RETRIEVAL_CMP 4 +#define TCOC_L2_RETRIEVAL_NOT_POSSIBLE 5 + +/* TCOC INPUT FROM TSRC */ +#define TCOC_ALTERATIVE_ROUTE_DT 1 + +/* TCOC INPUT FROM STM */ +#define TCOC_LINK_UNAVAILABLE 1 +#define TCOC_LINK_AVAILABLE 2 +#define TCOC_TLAC_COO_COMMAND 3 +#define TCOC_TLAC_ECO_COMMAND 4 + +/* TCOC INPUT FROM HMDT */ +#define TCOC_HMDT_COA_COMMAND 1 +#define TCOC_HMDT_ECA_COMMAND 2 + +/* TCOC INPUT FROM L2 */ +//#define TCOC_L2_RETRIEVED_MSG 1 +#define TCOC_L2_RETRIEVE_CMP 254 +#define TCOC_L2_RETRIEVE_NOT_POSSIBLE 255 +/**************************************TCOC INPUT**************************************/ + + +/**************************************TCBC INPUT**************************************/ +#define TCBC_LINK_UNAVAILABLE 1 +#define TCBC_LINK_AVAILABLE 2 +#define TCBC_HMDT_CBD_COMMAND 3 +#define TCBC_HMDT_CBA_COMMAND 4 + +/* TCBC INPUT FROM TSRC */ +#define TCBC_ALTERATIVE_ROUTE_DT 1 + +/**************************************TCBC INPUT**************************************/ + + +/**************************************TLAC INPUT**************************************/ +/* TLAC INPUT FROM HMDT*/ +#define TLAC_HMDT_INHIBIT_SIGLINK 1 +#define TLAC_HMDT_UINHIBIT_SIGLINK 2 +#define TLAC_HMDT_INHIBIT_ACK 3 +#define TLAC_HMDT_UNINHIBIT_ACK 4 +#define TLAC_HMDT_INHIBIT_DENIED 5 +#define TLAC_HMDT_FORCE_UNINHIBIT_SIGLINK 6 +#define TLAC_HMDT_CHANGEOVER_ORDER 7 +#define TLAC_HMDT_ECHANGEOVER_ORDER 8 +#define TLAC_HMDT_LOCAL_INHIBIT_TEST 9 +#define TLAC_HMDT_REMOTE_INHIBIT_TEST 10 + + +/* TLAC INPUT FROM MGMT */ +#define TLAC_MGMT_INHIBIT_SIGLINK 1 +#define TLAC_MGMT_UINHIBIT_SIGLINK 2 + +/* TLAC INPUT FROM SLM */ +#define TLAC_LSAC_SIGLINK_FAILED 1 +#define TLAC_LSAC_LINK_IN_SERVICE 2 +#define TLAC_LSAC_REMOTE_PROCESSOR_OUTAGE 3 +#define TLAC_LSAC_REMOTE_PROCESSOR_RECOVER 4 + +/* TLAC INPUT FROM STM */ +#define TLAC_TCBC_CHANGEBACK_TERMINATED 1 +#define TLAC_TCOC_CHANGEOVER_EXECUTED 2 +#define TLAC_TCOC_CHANGEOVER_NOT_REQ 3 +#define TLAC_LOCAL_INHIBIT_ALLOWED 4 +#define TLAC_REMOTE_INHIBIT_ALLOWED 5 +#define TLAC_LOCAL_INHIBIT_DENIED 6 +#define TLAC_REMOTE_INHIBIT_DENIED 7 +#define TLAC_UINHIBIT_SIGLINK_FROM_TSRC 8 +#define TLAC_UNINHIBIT_NOT_POSSIBLE 9 +#define TLAC_UNINHIBIT_POSSIBLE 10 +#define TLAC_ADJACENT_SP_RESTARTING 11 +#define TLAC_RESTART_BEGINS 12 +#define TLAC_RESTART_ENDS 13 +#define TLAC_ADJACENT_SP_RESTART_ENDS 14 + +/* TLAC INPUT FROM TIMER CONTROL */ +#define TLAC_T12_EXPIRED 1 +#define TLAC_T13_EXPIRED 2 +#define TLAC_T14_EXPIRED 3 +#define TLAC_T22_EXPIRED 4 +#define TLAC_T23_EXPIRED 5 +/**************************************TLAC INPUT**************************************/ + + +/**************************************TSRC INPUT**************************************/ +/* TSRC_INPUT_FROM_TCOC */ +#define TSRC_TCOC_ALTERNATIVE_ROUTING_DATA_REQUEST 1 +#define TSRC_TCOC_ACCESS_DATA_REQ 2 +#define TSRC_TCOC_CHANGEOVER_EXECUTED 3 +#define TSRC_TCOC_CHANGEOVER_NOT_REQ 4 + +/* TSRC_INPUT_FROM_TCBC */ +#define TSRC_TCBC_ALTERNATIVE_ROUTING_DATA_REQUEST 1 +#define TSRC_PROCEDURE_TERMINATED 2 + +/*TSRC_INPUT_FROM_STM*/ +#define TSRC_TFRC_ALTERNATIVE_ROUTING_DATA_REQUEST 1 +#define TSRC_TCRC_ALTERNATIVE_ROUTING_DATA_REQUEST 2 +#define TSRC_RESTART_BEGINS 3 +#define TSRC_RESTART_ENDS 4 +#define TSRC_TRAFFIC_RESTART_ALLOWED 5 +#define TSRC_SENDING_STATUS_PHASE 6 + +/*TSRC_INPUT_FROM_SRM*/ +#define TSRC_RTAC_ROUTE_AVAILABLE 1 +#define TSRC_RTPC_ROUTE_UNAVAILABLE 2 + +/* TSRC_INPUT_FROM_TLAC */ +#define TSRC_TLAC_LINK_UNAVAILABLE 1 +#define TSRC_TLAC_LINK_AVAILABLE 2 +#define TSRC_TLAC_LOCAL_INHIBIT_REQ 3 +#define TSRC_TLAC_REMOTE_INHIBIT_REQ 4 +#define TSRC_TLAC_LINK_INHIBITED 5 +#define TSRC_TLAC_CANCEL_LINK_INHIBITED 6 +#define TSRC_TLAC_UNINHIBIT_REQ 7 +/**************************************TSRC INPUT**************************************/ + + +/**************************************TFRC INPUT**************************************/ +#define TFRC_SIG_RT_UNAVAILABLE 0 +#define TFRC_SIG_RT_AVAILABLE 1 +#define TFRC_ALTERNATIVE_RT_DT 2 +/**************************************TFRC INPUT**************************************/ + + +/**************************************TCRC INPUT**************************************/ +#define TCRC_SIG_RT_AVAILABLE 0 +#define TCRC_ALTERNATIVE_RT_DT 1 +/**************************************TCRC INPUT**************************************/ + +/**************************************TPRC INPUT**************************************/ +#define TPRC_ADJACENT_SP_RESTARTING 1 +#define TPRC_TRA_MSG 2 +#define TPRC_RTPC_TFP_SENT 3 +/**************************************TPRC INPUT ABOUT dst**************************************/ +#define TPRC_LINK_AVAILABLE 1 +#define TPRC_LINK_UNAVAILABLE 2 +#define TPRC_SP_RESTART_INDICATION 3 +#define TPRC_STATUS_SENT 4 +/**************************************TPRC INPUT**************************************/ + +/**************************************RTPC INPUT**************************************/ +#define RTPC_MSGREV_FOR_INACCESS_SP 1 +#define RTPC_RSRT_SEND_TFP_MSG 2 +#define RTPC_TSRC_SEND_TFP_MSG 3 +#define RTPC_DEST_INACCESSIBLE 4 +#define RTPC_TFP_MSG 5 +#define RTPC_CTRL_RERT_TERMINATED 6 +#define RTPC_CONTROLLED_RERT 7 +#define RTPC_RESTART_BEGINS 8 +#define RTPC_RESTART_ENDS 9 +/**************************************RTPC INPUT**************************************/ + + +/**************************************RTAC INPUT**************************************/ +#define RTAC_TFA_MSG 1 +#define RTAC_DEST_ACCESSIBLE 2 +#define RTAC_STP_NOLONGER_FOR_DEST 3 +#define RTAC_SEND_TFA_MSG 4 +#define RTAC_FORCED_RERT 5 +#define RTAC_FORCED_RERT_TERMINATED 6 +#define RTAC_FORCED_RERT_NOT_REQ 7 +#define RTAC_RESTART_BEGINS 8 +#define RTAC_RESTART_ENDS 9 +/**************************************RTAC INPUT**************************************/ + +#define RSRT_RTPC_ROUTE_SET_TEST 1 +#define RSRT_TSRC_ROUTE_SET_TEST 2 +#define RSRT_RTAC_ROUTE_AVAILABLE 3 + +#define RSRT_IDLE_STATE 0 +#define RSRT_WAIT_STATE 1 +/**************************************LSAC INPUT**************************************/ +/* LSAC INPUT FROM L2*/ +#define LSAC_L2_IN_SERVICE 1 +#define LSAC_L2_OUT_OF_SERVICE 2 +#define LSAC_L2_REMOTE_PROCESSOR_RECOV 3 +#define LSAC_L2_REMOTE_PROCESSOR_OUTAGE 4 + +/* LSAC INPUT FROM SLTC */ +#define LSAC_SLTC_SLT_SUCCESSFUL 1 +#define LSAC_SLTC_SLT_FAILED 2 + +/* LSAC INPUT FROM TCOC */ +#define LSAC_TCOC_STM_READY 1 +#define LSAC_TCOC_STOP_L2 2 + +/* LSAC INPUT FROM STM */ +#define LSAC_TLAC_CHANGEOVER_ORDER_RECEIVED 1 + +/* LSAC INPUT FROM SLM */ +#define LSAC_ACTIVATE_LINK_FROM_LLSC 1 +#define LSAC_DEACTIVATE_LINK_FROM_LLSC 2 +#define LSAC_EMERGENCY 3 +#define LSAC_EMERGENCY_CEASES 4 + +/* LSAC INPUT FROM MGMT */ +#define LSAC_MGMT_ACTIVATE_LINK 1 +#define LSAC_MGMT_DEACTIVATE_LINK 0 +/**************************************LSAC INPUT**************************************/ +#define LLSC_MGMT_ACTIVATE_LINKSET 1 +#define LLSC_MGMT_DEACTIVATE_LINKSET 2 +#define LLSC_TPRC_RESTART_BEGINS 3 + +/* MGMT INPUT */ +#define MGMT_TLAC_LINK_INHIBITED 1 +#define MGMT_TLAC_LINK_UNINHIBITED 2 +#define MGMT_UNINHIBIT_NOT_POSSIBLE 3 +#define MGMT_INHIBIT_DENIED 4 + +#define TCOC_IDLE_STATE 0 +#define TCOC_WAIT01_STATE 1 +#define TCOC_WAIT02_STATE 2 +#define TCOC_WAIT05_STATE 3 +#define TCOC_WAIT06_STATE 4 +#define TCOC_WAIT07_STATE 5 +#define TCOC_WAITACK_STATE 6 +#define TCOC_RETRIEVING_STATE 7 +#define TCOC_SEND_BUFMSG_STATE 8 + +#define TLAC_UNAVAILABLE_STATE 0 +#define TLAC_AVAILABLE_STATE 1 +#define TLAC_SP_RESTARTING_STATE 2 + +#define LSAC_INACTIVE_STATE 0 +#define LSAC_RESTORING_STATE 1 +#define LSAC_ACTIVE_STATE 2 +#define LSAC_WAIT_STATE 3 +#define LSAC_FAILED_STATE 4 + +#define TSRC_IDLE_STATE 0 +#define TSRC_WAIT01_STATE 1 +#define TSRC_WAIT02_STATE 2 +#define TSRC_WAIT03_STATE 3 +#define TSRC_WAIT04_STATE 4 +#define TSRC_WAIT05_STATE 5 + +#define TCBC_IDLE_STATE 0 +#define TCBC_WAIT_FOR_ROUTING_DATA_STATE 1 +#define TCBC_TCTRL_DIVERSION_STATE 2 +#define TCBC_FIRST_ATTEMPT_STATE 3 +#define TCBC_SECOND_ATTEMPT_STATE 4 + +#define RTPC_IDLE_STATE 0 +#define RTPC_WAIT_STATE 1 + +#define TPRC_IDLE_STATE 0 +#define TPRC_WAIT01_STATE 1 +#define TPRC_WAIT02_STATE 2 +#define TPRC_WAIT03_STATE 3 +#define TPRC_RESTART_ENDS_STATE 4 + +#define SLTC_IDLE_STATE 0 +#define SLTC_FIRST_TRY_STATE 1 +#define SLTC_SECOND_TRY_STATE 2 +#define SLTC_THIRD_TRY_STATE 3 +#define SLTC_RUNNING_STATE 4 + +#define SLTC_START 1 +#define SLTA_MSG 2 +#define SLTC_SECOND_TRY 3 +#define SLTC_STOP 4 + +#ifndef IDLE +#define IDLE 0xee +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define COMMAND_START 1 +#define COMMAND_STOP 0 +#define TIMER_START 1 +#define TIMER_STOP 2 + +#define SP_ACCESSIBLE 1 +#define SP_INACCESSIBLE 0 +//#define LS_UNAVAILABLE 2 + +#define LOCAL_INHIBIT_REQ 0 +#define REMOTE_INHIBIT_REQ 1 + +#define UNAVAILABLE 0 +#define AVAILABLE 1 +#define INHIBITED 2 + +#define LOCAL_INHIBIT_REQ 0 +#define REMOTE_INHIBIT_REQ 1 + +#define MTP3_DEBUG_ID 1 + +//#define MTP3_OID {1,3,6,1,4,1,1373,1,3,2,2,2} +#define MTP3_OID {1,3,6,1,4,1,1373,2,3,2,2} +#define MTP3_OID_LEN 11 + +//#define MTP3_OMC_OID {1,3,6,1,4,1,1373,1,4} +#define MTP3_OMC_OID {1,3,6,1,4,1,1373,2,4} +#define MTP3_OMC_OID_LEN 9 + +//#define PLATFORM_HB_OID {1,3,6,1,4,1,1373,1,3,2,1} +#define PLATFORM_HB_OID {1,3,6,1,4,1,1373,2,3,2} +#define PLATFORM_HB_LEN 10 +#define MTP2_HB_OID {1,3,6,1,4,1,1373,1,3,1,1,3,4} +#define MTP2_HBOID_LEN 13 + +#define MTP2_ACTIVE_LINK 1 +#define MTP2_DEACTIVE_LINK 2 +#define MTP2_STOP_L2 3 +#define MTP2_EMERGEN_ALIGNMENT 4 +#define MTP2_RETRIEVE 5 +#define MTP3_M2UA_DISABLE 6 +#define MTP3_M2UA_ENABLE 7 +#define MTP3_M3UA_ENABLE 7 +#define MTP3_M3UA_DISABLE 6 + +#define ROUTE_AVAILABLE 0 +#define ROUTE_UNAVAILABLE 1 + +#define MTP_MAX_ASCIIOUT_LEN 2048 + +#define DISPLAY_SNM_MESSAGE 0 +#define DISPLAY_TM_MESSAGE 1 +#define DISPLAY_SCCP_MESSAGE 3 +#define DISPLAY_TUP_MESSAGE 4 +#define DISPLAY_ISUP_MESSAGE 5 +#define DISPLAY_MTP3_ERROR_LOG 6 +#define MTP3_MSGLOG_ON 1 +#define MTP3_MSGLOG_OFF 0 + +#define SNM_SIO 0 +#define TM_SIO 1/* T+M */ +#define SCCP_SIO 3 +#define TUP_SIO 4 +#define ISUP_SIO 5 +#define BICC_SIO 13 + +#define MTP2_STATE_IDLE 0 +#define MTP2_STATE_STOP 1 +#define MTP2_STATE_ASSIGN 2 +#define MTP2_STATE_READY 3 +#define MTP2_STATE_NOT_READY 4 +#define MTP2_STATE_WORKING 5 +#define MTP2_STATE_ERROR 6 +#define MTP2_STATE_WAITING 7 +#define MTP2_STATE_STATE_CONGEST 8 + +#define MTP3_TO_USERPART 0 +#define USERPART_TO_MTP3 1 +#define MTP_MSG_UP 0 +#define MTP_MSG_DOWN 1 +#define MTP_MSG_STP 2 +#define MTP_MSG_OTHER_SERVER 3 +#define MTP_SNM_MSG 4 +#define MTP_TO_LITE 5 +#define MTP_FROM_LITE 6 + +#define SS7_PORT 4950 +#define M2UA_PORT 2904 +#define MTP3_MULTICAST_PORT 4969 + +#define MTP3_IPTX_MSG 0 +#define MTP3_UP_MSG 1 + +#define E1CARD_BASE_IP 0x010012AC +#define E1CARD_BASE_IP_MASK 0xff00ffff + +#define PARA_CONFIGURED 1 +#define PARA_NOT_CONFIGURED 0 + + +#define LS_AVAILABLE 0 +#define LS_UNAVAILABLE 1 +#define NLS_AVAILABLE 0 +#define ALS_AVAILABLE 0 +#define NLS_UNAVAILABLE 2 +#define ALS_UNAVAILABLE 2 + +#define UPDATE_NLS 0 +#define UPDATE_ALS 1 + +#define LINK_TO_IP(link) (link >> 3) << 16 | 0x010012AC + +#define MAX_LS_DPC 128 +#define MAX_LS_DPC_ADD1 129 +#define MAX_LS_NUM 128 + +#define MTP3_14BIT_PC 14 +#define MTP3_24BIT_PC 24 + +#define MSG_FROM_MTP2 0 +#define MSG_FROM_MTP3 1 + +#define MAX_ACN_NUM 36 + +#define MAX_MTP3_NUM 64 + +#define MTP3_LINK_COMPONENT 23 +#define MTP3_LINKSET_COMPONENT 279 +#define MTP3_SG_COMPONENT 264 + +#define MTP3_VERSION {1, 0, 02} +//9,0,2 change ss7 format to "link-0, len -1-2, sio-3 " +//9,0,3 support m3ua msg + +#define MTP3_COMPONENT_ID 1 +#define ALARM_LINK_UNAVAILABLE 0 +#define ALARM_LINK_AVAILABLE 1 +#define ALARM_LINK_INHIBIT 2 +#define ALARM_LS_UNAVAILABLE 3 +#define ALARM_LS_AVAILABLE 4 +#define ALARM_LS_INHIBIT 5 +#define NORMAL_HEARTBEAT 6 + +#define M2UAALARM_SCTP_Failure 1 +#define M2UAALARM_SG_Maintenance 2 +#define M2UAALARM_Remote_MTP2_down 3 +#define M2UAALARM_Local_MTP3_Request_Link_Down 4 +#define M2UAALARM_Local_SGLink_Maintenance 5 +#define M2UAALARM_SCCPLite_TCP_Failure 16 +#define M2UAALARM_SCCPLite_Inactivity_Timeout 17 + +#define MTP3ALARM_LINK_TEST_FAILED 1 +#define MTP3ALARM_LINK_COO_RECEIVED 2 +#define MTP3ALARM_LINK_CHANGE_OVER 3 +#define MTP3ALARM_LINK_MGMT_REQUEST 4 +#define MTP3ALARM_LINK_CB_TO_NMTP3 5 +#define MTP3ALARM_LINK_LOCAL_INHIBITED 6 +#define MTP3ALARM_LINK_REMOTE_INHIBITED 7 + +//#define MTP3_HB_LEN 134 +#define MTP3_HB_LEN 422 +#define MTP3_SERNUM_LEN 4//4 bytes + +typedef enum +{ + LKTYPE_NONE_SIGTRAN = 0, + LKTYPE_SIGTRAN = 1, + LKTYPE_MTP3_LITE = 2, + LKTYPE_RESERVED1 = 3, + LKTYPE_M3UA = 4, + LKTYPE_RESERVED3 = 5, + LKTYPE_RESERVED4 = 6, + LKTYPE_RESERVED5 = 7, +}MTP3_LKTYPE_LIST; + +typedef enum +{ + MTP3_SUB_SNM = 0, + MTP3_SUB_STM = 1, + MTP3_SUB_STM2 = 2, + MTP3_SUB_SCCP = 3, + MTP3_SUB_TUP = 4, + MTP3_SUB_ISUP = 5, + MTP3_SUB_DUP1 = 6, + MTP3_SUB_DUP2 = 7, + MTP3_SUB_NONE2 = 8, + MTP3_SUB_BISUP = 9, + MTP3_SUB_SISUP = 10, + MTP3_SUB_NONE3 = 11, + MTP3_SUB_NONE4 = 12, + MTP3_SUB_BICC = 13 +}MTP3_SUB_NAME; + +#define MTP3_MAX_DYNAMIC_OPC_PER_NW 16 +#define MAX_LK 1024 +#define MAX_LK_INDEX 1023 +#define MAX_ROUTE 1024 +#define MAX_LS 512 diff --git a/plat/mtp3/src/include/mtpdef.h b/plat/mtp3/src/include/mtpdef.h new file mode 100644 index 0000000..8f60135 --- /dev/null +++ b/plat/mtp3/src/include/mtpdef.h @@ -0,0 +1,159 @@ +#if 0 +WORD ls_slc[MAX_LS*16]; +WORD ls_sls[MAX_LS*16]; +WORD sls_to_link[MAX_LS*16]; + +/** link mark **/ +BYTE link_available[MAX_LK]; +BYTE link_unavailable[MAX_LK]; +BYTE changeover_possible[MAX_LK]; +BYTE retrieval_required[MAX_LK]; +BYTE remote_bsnt_retrieved[MAX_LK]; +BYTE changeback_in_progress[MAX_LK]; +BYTE changeover_in_progress[MAX_LK]; +BYTE changeback_required[MAX_LK]; +BYTE changeover_required[MAX_LK]; +BYTE emergency_changeover_order[MAX_LK]; +BYTE changeover_order[MAX_LK]; +BYTE changeover_completed[MAX_LK]; +BYTE failed[MAX_LK]; +BYTE blocked_by[MAX_LK]; +BYTE local_blocked[MAX_LK]; +BYTE remote_blocked[MAX_LK]; +BYTE first_failure[MAX_LK]; +BYTE changeover_select[MAX_LK]; +BYTE changeback_select[MAX_LK]; +BYTE co_msg_can_exchange[MAX_LK]; +BYTE cb_msg_can_exchange[MAX_LK]; +BYTE local_bsnt_retrievable[MAX_LK]; +BYTE retrieved_bsnt[MAX_LK]; +BYTE fsnt[MAX_LK]; +BYTE fsnl[MAX_LK]; +BYTE fsnc[MAX_LK]; +BYTE bsnt[MAX_LK]; +BYTE tcbc_route_change[MAX_LK]; +BYTE command3[MAX_LK]; +BYTE cbd_cbc_r[MAX_LK]; +BYTE cba_cbc_r[MAX_LK]; +WORD cbc_s[MAX_LK]; +BYTE controlled_rerouting_in_progress[MAX_LK]; +BYTE transfer_prohibited[MAX_LK]; +BYTE own_sp_restarting; +BYTE link_remotely_inhibited[MAX_LK]; +BYTE link_locally_inhibited[MAX_LK]; +BYTE link_inhibited[MAX_LK]; +BYTE local_inhibit_in_progress[MAX_LK]; +BYTE uninhibit_in_progress[MAX_LK]; +BYTE management_req[MAX_LK]; +BYTE t12_expired_2nd_time[MAX_LK]; +BYTE t13_expired_2nd_time[MAX_LK]; +BYTE sending_phase_finished[MAX_LS]; + +WORD mtp3_timer[24]; + +BYTE sd_buf_h[256]; +BYTE sd_buf_t[256]; + +MTP3Parameter *mtp3_para; +MTP3Parameter mtp3_para_init; +mtp mtp3; +mtp3_csta mtp3_measure; +measure_of_mtp3 *current_measure; +BYTE current_mtime;/* current measure time */ +heartbeat_compoent_of_mtp3 mtp3_heartbeat; + +/** debug **/ + +BYTE mtp_asciout_buf[2048]; +char mtp_asciin_buf[80]; + +BYTE t1_delay_mtp3[MAX_LK]; +BYTE t2_delay_mtp3[MAX_LK]; +BYTE t3_delay_mtp3[MAX_LK]; +BYTE t4_delay_mtp3[MAX_LK]; +BYTE t5_delay_mtp3[MAX_LK]; +BYTE t6_delay_mtp3[MAX_LK]; +BYTE t7_delay_mtp3[MAX_LK]; +BYTE t8_delay_mtp3[MAX_LK]; +BYTE t9_delay_mtp3[MAX_LK]; +BYTE t10_delay_mtp3[MAX_LK]; +BYTE t11_delay_mtp3[MAX_LK]; +BYTE t12_delay_mtp3[MAX_LK]; +BYTE t13_delay_mtp3[MAX_LK]; +BYTE t14_delay_mtp3[MAX_LK]; +BYTE t15_delay_mtp3[MAX_LK]; +BYTE t16_delay_mtp3[MAX_LK]; +BYTE t17_delay_mtp3[MAX_LK]; +BYTE t18_delay_mtp3; +BYTE t19_delay_mtp3; +BYTE t20_delay_mtp3; +BYTE t21_delay_mtp3[MAX_LK]; +BYTE t22_delay_mtp3[MAX_LK]; +BYTE t23_delay_mtp3[MAX_LK]; +BYTE t24_delay_mtp3[MAX_LK]; +BYTE sltc_t1_delay[MAX_LK]; +BYTE sltc_t2_delay[MAX_LK]; + +BYTE mtp3_t21_flag[MAX_LS]; +BYTE mtp3_t22_flag[MAX_LK]; +BYTE mtp3_t23_flag[MAX_LK]; +BYTE mtp3_t12_flag[MAX_LK]; +BYTE mtp3_t13_flag[MAX_LK]; +BYTE mtp3_t14_flag[MAX_LK]; + +BYTE srm_nw; +BYTE active_ls_num; +BYTE current_active_ls_num; +BYTE rv_TRA_num; +BYTE tprc_nw; +//BYTE taprc_loop[128]; +BYTE taprc_loop[MAX_LS]; + +BYTE mtp_t1[256]; +BYTE mtp_t2[256]; +BYTE mtp_t3[256]; +BYTE mtp_t4[256]; +BYTE mtp_t5[256]; +BYTE mtp_t7[256]; +BYTE mtp_t12[256]; +BYTE mtp_t13[256]; +BYTE mtp_t14[256]; +BYTE mtp_t17[256]; +BYTE mtp_t22[256]; +BYTE mtp_t23[256]; +BYTE mtp_t24[256]; + +BYTE mtp2_flag_new[32]; +BYTE mtp2_flag_old[32]; + +ulong mtp3_localip; +ulong mtp3_alterip; + +WORD wx5[256]; +BYTE debug_link[MAX_LK]; + +long mtp3_timestamp; +long mtp3_csta_p; + +ulong mtp3_get_msg; + +BYTE local_change_over[MAX_LK]; + +BYTE mtp2_buf_full[MAX_LK]; +BYTE nld_cause_lkd[MAX_LK]; + +BYTE init_lsac_state[MAX_LK]; +BYTE init_tlac_state[MAX_LK]; + +ulong TFAmsg_OPC; +WORD TFAmsg_SrcLk; +ulong TFPmsg_OPC; +WORD TFPmsg_SrcLk; +WORD sdTFP_Ls; +WORD sdTFA_Ls; +BYTE mtp2_module; +BYTE mtp2_systemid; + +// mtp3 dynamic opc +mtp3_dynamic_opc mtp3_opc; +#endif diff --git a/plat/mtp3/src/include/mtpext.h b/plat/mtp3/src/include/mtpext.h new file mode 100644 index 0000000..ffa4fb8 --- /dev/null +++ b/plat/mtp3/src/include/mtpext.h @@ -0,0 +1,140 @@ +extern WORD ls_slc[MAX_LS*16]; +extern WORD ls_sls[MAX_LS*16]; +extern WORD sls_to_link[MAX_LS*16]; + +/** link mark **/ +extern BYTE link_available[MAX_LK]; +extern BYTE changeover_possible[MAX_LK]; +extern BYTE retrieval_required[MAX_LK]; +extern BYTE remote_bsnt_retrieved[MAX_LK]; +extern BYTE changeback_in_progress[MAX_LK]; +extern BYTE changeover_in_progress[MAX_LK]; +extern BYTE changeback_required[MAX_LK]; +extern BYTE changeover_required[MAX_LK]; +extern BYTE emergency_changeover_order[MAX_LK]; +extern BYTE changeover_order[MAX_LK]; +extern BYTE changeover_completed[MAX_LK]; +extern BYTE failed[MAX_LK]; +extern BYTE blocked_by[MAX_LK]; +extern BYTE local_blocked[MAX_LK]; +extern BYTE remote_blocked[MAX_LK]; +extern BYTE first_failure[MAX_LK]; +extern BYTE changeback_select[MAX_LK]; +extern BYTE changeover_select[MAX_LK]; +extern BYTE co_msg_can_exchange[MAX_LK]; +extern BYTE cb_msg_can_exchange[MAX_LK]; +extern BYTE local_bsnt_retrievable[MAX_LK]; +extern BYTE retrieved_bsnt[MAX_LK]; +extern BYTE fsnt[MAX_LK]; +extern BYTE fsnl[MAX_LK]; +extern BYTE fsnc[MAX_LK]; +extern BYTE bsnt[MAX_LK]; +extern BYTE tcbc_route_change[MAX_LK]; +extern BYTE command3[MAX_LK]; +extern BYTE cbd_cbc_r[MAX_LK]; +extern BYTE cba_cbc_r[MAX_LK]; +extern BYTE cbc_s[MAX_LK]; +extern BYTE controlled_rerouting_in_progress[MAX_LK]; +extern BYTE transfer_prohibited[MAX_LK]; +extern BYTE own_sp_restarting; +extern BYTE link_remotely_inhibited[MAX_LK]; +extern BYTE link_locally_inhibited[MAX_LK]; +extern BYTE link_inhibited[MAX_LK]; +extern BYTE local_inhibit_in_progress[MAX_LK]; +extern BYTE uninhibit_in_progress[MAX_LK]; +extern BYTE management_req[MAX_LK]; +extern BYTE t12_expired_2nd_time[MAX_LK]; +extern BYTE t13_expired_2nd_time[MAX_LK]; +extern BYTE sending_phase_finished[MAX_LS]; + +extern WORD mtp3_timer[24]; + +extern BYTE sd_buf_h[256]; +extern BYTE sd_buf_t[256]; + +extern MTP3Parameter *mtp3_para; +extern mtp mtp3; +extern mtp3_csta mtp3_measure; +extern measure_of_mtp3 *current_measure; +extern BYTE current_mtime;/* current measure time */ + +/** debug **/ + +extern BYTE mtp_asciout_buf[2048]; +extern char mtp_asciin_buf[80]; + +extern BYTE t1_delay_mtp3[MAX_LK]; +extern BYTE t2_delay_mtp3[MAX_LK]; +extern BYTE t3_delay_mtp3[MAX_LK]; +extern BYTE t4_delay_mtp3[MAX_LK]; +extern BYTE t5_delay_mtp3[MAX_LK]; +extern BYTE t6_delay_mtp3[MAX_LK]; +extern BYTE t7_delay_mtp3[MAX_LK]; +extern BYTE t8_delay_mtp3[MAX_LK]; +extern BYTE t9_delay_mtp3[MAX_LK]; +extern BYTE t10_delay_mtp3[MAX_LK]; +extern BYTE t11_delay_mtp3[MAX_LK]; +extern BYTE t12_delay_mtp3[MAX_LK]; +extern BYTE t13_delay_mtp3[MAX_LK]; +extern BYTE t14_delay_mtp3[MAX_LK]; +extern BYTE t15_delay_mtp3[MAX_LK]; +extern BYTE t16_delay_mtp3[MAX_LK]; +extern BYTE t17_delay_mtp3[MAX_LK]; +extern BYTE t18_delay_mtp3; +extern BYTE t19_delay_mtp3; +extern BYTE t20_delay_mtp3; +extern BYTE t21_delay_mtp3[MAX_LS]; +extern BYTE t22_delay_mtp3[MAX_LK]; +extern BYTE t23_delay_mtp3[MAX_LK]; +extern BYTE t24_delay_mtp3[MAX_LK]; +extern BYTE sltc_t1_delay[MAX_LK]; +extern BYTE sltc_t2_delay[MAX_LK]; + +extern BYTE mtp3_t21_flag[MAX_LS]; +extern BYTE mtp3_t22_flag[MAX_LK]; +extern BYTE mtp3_t23_flag[MAX_LK]; +extern BYTE mtp3_t12_flag[MAX_LK]; +extern BYTE mtp3_t13_flag[MAX_LK]; +extern BYTE mtp3_t14_flag[MAX_LK]; + +extern BYTE srm_nw; +extern BYTE active_ls_num; +extern BYTE current_active_ls_num; +extern BYTE rv_TRA_num; +extern BYTE tprc_nw; +extern BYTE taprc_loop[MAX_LS]; + +extern BYTE mtp2_flag_new[32]; +extern BYTE mtp2_flag_old[32]; + +extern heartbeat_compoent_of_mtp3 mtp3_heartbeat; + +extern ulong mtp3_localip; +extern ulong mtp3_alterip; +extern WORD wx5[256]; +extern BYTE debug_link[MAX_LK]; + +extern long mtp3_timestamp; +extern long mtp3_csta_p; + +extern ulong mtp3_get_msg; + +extern BYTE local_change_over[MAX_LK]; + +extern BYTE mtp2_buf_full[MAX_LK]; +extern BYTE nld_cause_lkd[MAX_LK]; + +extern BYTE init_lsac_state[MAX_LK]; +extern BYTE init_tlac_state[MAX_LK]; + +extern ulong TFAmsg_OPC; +extern BYTE TFAmsg_SrcLk; +extern ulong TFPmsg_OPC; +extern BYTE TFPmsg_SrcLk; +extern BYTE sdTFP_Ls; +extern BYTE sdTFA_Ls; +extern BYTE mtp2_module; +extern BYTE mtp2_systemid; + +// mtp3 opc +extern mtp3_dynamic_opc mtp3_opc; diff --git a/plat/mtp3/src/include/mtpfunc.h b/plat/mtp3/src/include/mtpfunc.h new file mode 100644 index 0000000..1ec8715 --- /dev/null +++ b/plat/mtp3/src/include/mtpfunc.h @@ -0,0 +1,102 @@ +int find_outbound_cclink(WORD chl);/* find outbound changeover link */ +int search_outbound_link(WORD ls); +int pc_length(BYTE nw); +void send_mtp_msg(int outlink, BYTE *msgptr); +void send_snm_msg(WORD ls,BYTE *msgptr); +void hmrt_srm_msg(WORD linkset, BYTE MsgType, long dst); +int check_outbound_route(BYTE sio, long dpc, WORD sls, long opc); +int send_to_tup(BYTE *msgptr);/* send tup msg to tele user part */ +int send_to_isup(BYTE *msgptr);/* send isup msg to tele user part */ +int send_to_bicc(BYTE *msgptr);/* send bicc msg to tele user part */ +int send_to_sccp(BYTE *msgptr);/* send sccp msg to tele user part */ +int send_to_sccp_lite(up_message *msgptr);/* send sccp-lite msg to sccp */ +int get_tup(up_message *GetTup); +int get_isup(up_message *GetIsup); +int get_bicc(up_message_2 *GetBicc); +int get_sccp(up_message *GetSccp); +int find_dst_place(long dst,WORD ls); +int find_direct_ls_to_dst(long dst, BYTE nw, long opc); +void mtp2_mtp3_internal_msg(BYTE *msgptr); +void hmdt_test_msg(BYTE *msgptr); +void hmrt_tra_msg(WORD linkset); +void sd_STM_msg(WORD chl, BYTE MsgType); +void hmrt_xxxx_adjacent_sp_restart(ls_info *ls); +void hmrt_hmdc_message_for_routing(ls_info *ls); +void hmrt_xxxx_signalling_link_management_message(ls_info *ls); +void hmrt_xxxx_signalling_route_management_message(ls_info *ls); +void hmrt_xxxx_mtp_testing_user_part_message(ls_info *ls); +void hmrt_tprc_restart_begins(ls_info *ls); +void hmrt_tprc_restart_ends(ls_info *ls); +void hmrt_tfrc_update_routing_tables(WORD dst, BYTE nw); +void hmrt_sltc_signalling_link_test_ack(WORD chl); +void hmrt_sltc_signalling_link_test_msg(WORD chl); +void hmrt_tcbc_changeback_ack(WORD chl); +void hmrt_tcbc_changeback_declaration(WORD chl); +void hmrt_tcoc_changeover_ack(WORD chl); +void hmrt_tcoc_changeover_order(WORD chl); +void hmrt_tcoc_emergency_changeover_ack(WORD chl); +void hmrt_tcoc_emergency_changeover_order(WORD chl); +void hmrt_tcbc_update_routing_tables(WORD chl); +void hmrt_tcoc_update_routing_tables(WORD chl); +void hmrt_tlac_emergency_changeover_ack(WORD chl); +void hmrt_tlac_force_uninhibit_signalling_link(WORD chl); +void hmrt_tlac_inhibit_ack(WORD chl); +void hmrt_tlac_inhibit_denied(WORD chl); +void hmrt_tlac_local_inhibit_test(WORD chl); +void hmrt_tlac_remote_inhibit_test(WORD chl); +void hmrt_tlac_uninhibit_ack(WORD chl); +void send_command_to_mtp2(WORD chl, BYTE command); +void update_nid_table(WORD ls, long dst, BYTE place); +void update_aid_table(WORD ls, long dst, BYTE place); +void get_para_from_disk(); +int mtp_setmib(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD datalen); +int mtp_getmib(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +void mtp_snmp_init(); +void tup_shm_init(); +void isup_shm_init(); +void sccp_shm_init(); +int GetMtp2Msg(ulong ip_port); +void m3ua_timer(); +int GetM3uaMsg(ulong port); +int tup_GetMsg(up_message *msgptr); +int isup_GetMsg(up_message *msgptr); +int sccp_GetMsg(up_message *msgptr); +int tup_to_mtp3(up_message *msgptr); +int isup_to_mtp3(up_message *msgptr); +int sccp_to_mtp3(up_message *msgptr); +void sltc_proc(WORD chl); +void lsac_proc(WORD chl); +void rtpc_proc(BYTE nw,WORD dst); +void rtac_proc(BYTE nw,WORD dst); +void tsrc_proc(WORD chl); +void tlac_proc(WORD chl); +void tcoc_proc(WORD chl); +void tcbc_proc(WORD chl); +void tprc_mgmt_signalling_point_restart_indication(); +void tprc_proc(); +void taprc_proc(WORD linkset);/* adjacent sp restart control */ +void mtp_send_error(char *object,int chl, char *err_str); +void mtp_send_error2(BYTE *msg,BYTE sio,ulong dpc,char *err_str,BYTE from); +int mtp_debug_set(); +void mtp_m_rt(); +void mtp_put_error(BYTE type,WORD chl); +void mtp3_readpara_from_disk(); +BOOL iptrans_msg_flow(BYTE *msg,BYTE pclen,int direction,ulong dest_ip); +BOOL iptrans_msg_flow_2(up_message *up_msg_ptr); +void mtp_prompt(char *object, BYTE value); +void set_heartbeat(BYTE reason,WORD object); +void mtp3_send_alarm(WORD component_id,BYTE alarm_code); +void update_sls_to_link_table(int ls); +int update_ls_slc_table(int link); +void mtp3_debug(int n,const char *fmt,...); +void reset_mtp3(); +void mtp3Timer_proc(WORD i); +int pc_length(BYTE nw); +void mtp3_showbuf(int n,BYTE *msg,int len); +int mtp3lite_updateStatus(WORD chl, BYTE new_l2_state,BYTE alarmCode); +void mtp3lite_upd_route_status(WORD chl, BYTE flag); +int Mtp3BinSearchValue(WORD low, WORD high,BYTE nw,ull key); +void mtp3_send_mtp2_alarm(WORD component,BYTE alarm); +BYTE MTP3_LINK_TYPE(WORD Link); +int Mtp3AddSortRec(BYTE nw,ulong dpc, ulong real_index, ulong opc); +void mtp3_send_mtp2_alarm(WORD component,BYTE alarm); diff --git a/plat/mtp3/src/include/mtpstm.h b/plat/mtp3/src/include/mtpstm.h new file mode 100644 index 0000000..e561bb4 --- /dev/null +++ b/plat/mtp3/src/include/mtpstm.h @@ -0,0 +1,296 @@ +#include "mtpconst.h" + +typedef struct ls_info{ + BYTE links_available; + BYTE links_available_t; + BYTE adjacentsp_acessible; + BYTE adjacentsp_restarting; + WORD adjacent_sp_place; + BYTE linksNum_configured; + + + WORD influ_dstnum_asNLS; + WORD influ_dstnum_asALS; + + WORD influ_dstplace_intable_asNLS[MAX_LS_DPC]; + WORD influ_dstplace_intable_asALS[MAX_LS_DPC]; + + BYTE links_nls_asp_ac_send_flag[MAX_ROUTE+1]; + BYTE links_als_asp_ac_send_flag[MAX_ROUTE+1]; + WORD send_asp_ac_link_id; + +}ls_info; + +typedef struct mtp3_flow{ + ulong UtoM[5]; + ulong MtoI[5]; + ulong ItoM[5]; + ulong MtoU[5]; + ulong stp[5]; + ulong UtoM_throwed[5]; + ulong MtoI_throwed[5]; + ulong ItoM_throwed[5]; + ulong MtoU_throwed[5]; + ulong stp_throwed[5]; + ulong stp_loop[5]; + ulong isup_detail[32]; +}mtp3_flow; + +typedef struct network{ + BYTE routine[MAX_ROUTE]; /* bit0-1: normal route available + bit2-3: alternative route available + bit4-5: acessible + bit6-7: current route */ + BYTE rtpc_state[MAX_ROUTE]; + BYTE rtpc_input[MAX_ROUTE]; + BYTE rtac_state[MAX_ROUTE]; + BYTE rtac_input[MAX_ROUTE]; + BYTE rsrt_state[MAX_ROUTE]; + BYTE rsrt_input[MAX_ROUTE]; + BYTE rsrt_t10[MAX_ROUTE]; + BYTE m3ua_rc_status[MAX_ROUTE]; + mtp3_flow flow; +}network; + +typedef struct _nw_route +{ + ulong dpc; + WORD normal_ls; + WORD alternative_ls; + BYTE mtp3_t8; + BYTE mtp3_t15; + BYTE mtp3_t16; + BYTE acn[MAX_ACN_NUM]; + BYTE ansi_remote; + ulong rc; + ulong opc; + char title[16+1]; +}nw_route; + +typedef struct nw_para{ + ulong opc24; + ulong opc14; + BYTE pc_len;//0=14bit, 1=24bit + BYTE pc_type;//0= itu, 1=ansi + + BYTE ansi_local14b; + BYTE ansi_local24b; + BYTE local_acn[MAX_ACN_NUM]; + nw_route routing[MAX_ROUTE]; +}nw_para; + +typedef struct lk_pro +{ + WORD e1_to_linkset __attribute__((packed)); + BYTE e1_to_slc;// __attribute__((packed)); + ulong e1_to_mtp3 __attribute__((packed)); + BYTE e1_lk_type;// __attribute__((packed));//( old struct mains Bit0:0=ss7,1=m2ua + //Bit1:1=reserved + //Bit2:0=MTP3,1=MTP3LITE + //BIT3:0=server,1=client) + WORD e1_to_sg __attribute__((packed)); + BYTE e1_to_iid;// __attribute__((packed)); + ulong remote_ip __attribute__((packed)); + BYTE inactive;// __attribute__((packed));// Inactivity timer + BYTE inactive_tm;// __attribute__((packed));// Allowed inactivity timeouts + ulong e1_to_alterMTP3 __attribute__((packed));//alternative MTP3 + BYTE mtp3lite_apl_mode; + BYTE admin_state; + char title[16+1]; +}lk_pro; + +typedef struct lk_timer +{ + BYTE t1;/* 500ms-1200ms */ + BYTE t2;/* 700ms-2000ms */ + BYTE t3;/* 500ms-1200ms */ + BYTE t4;/* 500ms-1200ms */ + BYTE t5;/* 500ms-1200ms */ + BYTE t7;/* 1s-2s */ + BYTE t8;/* 800ms-1200ms */ + BYTE t12;/* 800ms-1500ms */ + BYTE t13;/* 800ms-1500ms */ + BYTE t14;/* 2s-3s */ + BYTE t22; + BYTE t23; +}lk_timer; + +typedef struct sg_para +{ + BYTE enable;// __attribute__((packed)); + BYTE server;// __attribute__((packed)); + BYTE data_ack;// __attribute__((packed)); + u32 ip __attribute__((packed)); + u32 source_ip; // client source ip, 0=getHostName, other=value + WORD source_port; // client source port, 0=Radom + WORD dst_port; +}sg_para; + +typedef struct _ls_para +{ + int index; + char title[16+1]; + BYTE admin_state; + BYTE ls_state; + BYTE nw_id; + BYTE loopback_opt; + ulong ls_op_pc; + char ls_reserved[16]; + ulong ls_opc; + +}ls_para; + +typedef struct MTP3Parameter +{ + lk_pro lk[MAX_LK]; + lk_timer lt[MAX_LK]; + sg_para sg[256]; + BYTE nw_pro; +// ulong ls_op_pc[MAX_LS];/* for 128 linkset */ + ls_para ls_pro[MAX_LS]; + //char ls_reserved[MAX_LS][16];//each linkset reserved 16 bytes for omc + BYTE mtp3_t10; + BYTE mtp3_t18; + BYTE mtp3_t19; + BYTE mtp3_t20; + WORD mtp3_t21; + WORD mtp3lite_port; + nw_para nw[4]; + BYTE localAcn[MAX_ACN_NUM]; + ull MTP3SerialNum; + //ulong ls_opc[MAX_LS];/*for 128 linkset opc*/ +}MTP3Parameter; + +typedef struct mtp{ + ls_info ls[MAX_LS]; + network nw[4]; +}mtp; + +typedef struct measure_of_mtp3{ + long time_stamp; + ulong lk_measure1[MAX_LK][9];/* link measure oid=*.1 */ + ulong ls_measure[MAX_LS][8];/* linkset measure oid=*.3 */ +/*** traffic */ +// ulong tf_measure1[6][20];/* traffic octets */ + ulong tf_measure2[6][20];/* traffic MSUs */ + ulong tf_measure5[3]; +}measure_of_mtp3; + +typedef struct mtp3_csta{ + measure_of_mtp3 measure[96]; +}mtp3_csta; + +typedef struct heartbeat_compoent_of_mtp3 +{ + BYTE version[3]; + BYTE state; +// BYTE link_state[64]; + BYTE link_state[256]; + BYTE linkset_state[128]; + BYTE masterMTP3[32]; + BYTE SubState[2]; +}heartbeat_compoent_of_mtp3; + +typedef struct mtp2_heartbeat +{ + BYTE systemid; + BYTE moduleid; + BYTE timestamp[4]; + BYTE led_ctl_code[8]; + BYTE alarm_component; + BYTE alarm_code; + BYTE reserved; + BYTE l1_state; + BYTE l2_state[8]; + BYTE e1_dstip[8]; + BYTE retrieved_bsnt[8]; +}mtp2_heartbeat; + +typedef struct mtp3DPCIndex +{ + u_long sortedNum; +// u_long dpc[256]; + ull dpc[MAX_ROUTE];//dpc = (opc<<32) | dpc + u_long index[MAX_ROUTE]; +}mtp3DPCIndex; + +typedef struct mtp3_dpc_index +{ + mtp3DPCIndex nw[4]; +}mtp3_dpc_index; +extern mtp3_dpc_index mtp3SortRoutine; + +typedef struct _mtp3_state +{ + BYTE link_l1_state[MAX_LK]; + BYTE link_l2_state[MAX_LK]; + BYTE link_l3_state[MAX_LK]; + BYTE lk_configured[MAX_LK]; + BYTE lk_command[MAX_LK]; + BYTE link_type[MAX_LK]; + ulong lk_mtp3[MAX_LK]; + BYTE lk_NMTP3_ok[MAX_LK];//normal mtp3 ok + BYTE lk_AMTP3_ok[MAX_LK];//alternative mtp3 ok + + BYTE lk_SpecANSI_flag[MAX_LK]; + //special ANSI, use the Signalling network testing and maintenance special message + + BYTE lsac_state[MAX_LK]; + BYTE tlac_state[MAX_LK]; + BYTE tcoc_state[MAX_LK]; + BYTE tcbc_state[MAX_LK]; + BYTE tsrc_state[MAX_LK]; + BYTE sltc_state[MAX_LK]; + BYTE tprc_state; + + BYTE MTP3WatchDog[MAX_LK]; + + BYTE link_enable_sent_flag[MAX_LK]; +}_mtp3_state; +extern _mtp3_state mtp3ObjState; + +typedef struct _mtp3_input +{ + BYTE lsac_input_from_l2[MAX_LK]; + BYTE lsac_input_from_sltc[MAX_LK]; + BYTE lsac_input_from_stm[MAX_LK]; + BYTE lsac_input_from_tcoc[MAX_LK]; + BYTE lsac_input_from_mgmt[MAX_LK]; + BYTE tlac_input_from_slm[MAX_LK]; + BYTE tlac_input_from_mgmt[MAX_LK]; + BYTE tlac_input_from_stm[MAX_LK]; + BYTE tlac_input_from_hmdt[MAX_LK]; + BYTE tlac_input_from_Tctl[MAX_LK];/* input from timer control center*/ + BYTE tsrc_input_from_tcoc[MAX_LK]; + BYTE tsrc_input_from_tcbc[MAX_LK]; + BYTE tsrc_input_from_stm[MAX_LK]; + BYTE tsrc_input_from_tlac[MAX_LK]; + BYTE tcoc_input_from_tsrc[MAX_LK]; + BYTE tcoc_input_from_stm[MAX_LK]; + BYTE tcoc_input_from_hmdt[MAX_LK]; + BYTE tcbc_input[MAX_LK]; + BYTE tcbc_input_from_tsrc[MAX_LK]; + BYTE sltc_input[MAX_LK]; + BYTE tprc_input; + BYTE taprc_input[MAX_LS]; +}_mtp3_input; +extern _mtp3_input mtp3ObjInput; + +typedef struct _mtp3_IPMng +{ + BYTE mtp3_flag_new[MAX_MTP3_NUM]; + BYTE mtp3_flag_old[MAX_MTP3_NUM]; + ulong mtp3_flag_ip[MAX_MTP3_NUM]; + + BYTE LinkIPNum; + ulong LinkIP[MAX_MTP3_NUM]; + BYTE LinkIPSubSta[MAX_MTP3_NUM][2]; +}_mtp3_IPMng; + +typedef struct _mtp3_dynamic_opc +{ + BYTE opc_num[4]; + ulong opc[4][MTP3_MAX_DYNAMIC_OPC_PER_NW]; +}mtp3_dynamic_opc; + +extern _mtp3_IPMng MTP3IPMng; diff --git a/plat/mtp3/src/mtp3lite.c b/plat/mtp3/src/mtp3lite.c new file mode 100644 index 0000000..7dde2c2 --- /dev/null +++ b/plat/mtp3/src/mtp3lite.c @@ -0,0 +1,791 @@ +/****************************************************/ +/* MTP3LITE Implementation Program */ +/* Version 10.0.1 */ +/* Designed By Ying Min */ +/* Last Update: 2005-04-7 */ +/* Modify : Victor Luo, 2005-07-14 add TCP client for mtp3lite*/ +/****************************************************/ +#include +#include +#include "./include/mtp3.h" +#include "./include/mtpstm.h" +#include "./include/mtp3lite.h" +#include "./include/mtpext.h" +#include "./include/mtpfunc.h" + +BYTE mtp3lite_ka_msg[3]; +mtp3lite_lk mtp3lite_link[1024]; +int mtp3lite_listen_fd; +BYTE mtp3lite_msg_buf[1024][MTP3LITE_MSG_BUF_SIZE_PER_LINK]; +BYTE mtp3lite_rem_len[1024]; +BYTE mtp3lite_id_fg[1024]; + +extern u32 GetLocalIP(); +/*@ignore@*/ +void mtp3lite_print_msg(BYTE *ptr, WORD len) +{ + int i; + + for (i = 0; i < len; i++) + { + printf("%X ", ptr[i]); + } + printf("\n"); +} + +void mtp3lite_init_lk(WORD lk) +{ + mtp3lite_link[lk].connfd = -1; + mtp3lite_link[lk].cliSockfd = -1; + mtp3lite_link[lk].remote_port = 0; + mtp3lite_link[lk].local_inactive = 2000; // 20 seconds + mtp3lite_link[lk].local_reconnect = 10; // 10 * 2.56 seconds + mtp3lite_link[lk].remote_inactive = mtp3_para->lk[lk].inactive * 100; + mtp3lite_link[lk].remote_inactive_timeouts = mtp3_para->lk[lk].inactive_tm; + mtp3lite_link[lk].init_guard_timer = 2000; // 20 seconds + mtp3lite_msg_buf[lk][0] = 0; + mtp3lite_rem_len[lk] = 0; + mtp3lite_id_fg[lk] = 0; +} + +void mtp3lite_init_ka_msg(void) +{ + mtp3lite_ka_msg[0] = 2; + mtp3lite_ka_msg[1] = 0x4B; + mtp3lite_ka_msg[2] = 0x41; +} + +int mtp3lite_Init_TCPSocket(struct sockaddr_in saddr,int needBind) +{ //flag,0=client, 1=server + int sock; + long sockbuf = 40*1024; + int on = 1, timeout = 20; + + sock = socket(AF_INET, SOCK_STREAM, 0); + + if (sock < 0) + { + fprintf(stderr,"Socket() failed\n"); + return -3; + } + + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &sockbuf, sizeof(sockbuf)) != 0) + { + fprintf(stderr,"set socket buffer failed\n"); + return -4; + } + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + &on,sizeof(on)) != 0) + { + fprintf(stderr,"set addr reusable failed\n"); + return -5; + } + + if (setsockopt(sock,SOL_SOCKET, SO_KEEPALIVE, + &timeout, sizeof(timeout)) != 0) + { + fprintf(stderr,"set keepalive failed\n"); + return -6; + } + + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) + { + fprintf(stderr,"set nonblock failed\n"); + return -7; + } + + if(needBind) + { + if (bind(sock, (struct sockaddr*)&saddr, sizeof(struct sockaddr)) < 0) + { + fprintf(stderr,"MTP3LITE bind failed,port:%d\n",htons(saddr.sin_port)); + close(sock); + return -2; + } + } + return sock; +} + +int mtp3lite_InitServerSocket() +{ + struct sockaddr_in sin_addr; + + memset(&sin_addr, 0, sizeof(struct sockaddr)); + sin_addr.sin_family = AF_INET; + //sin_addr.sin_port = htons(mtp3lite_port); + sin_addr.sin_port = mtp3_para->mtp3lite_port; + sin_addr.sin_addr.s_addr = GetLocalIP(); + bzero(&(sin_addr.sin_zero),8); + + if ((mtp3lite_listen_fd = mtp3lite_Init_TCPSocket(sin_addr,1)) < 0) + { + printf("MTP3LITE TCP Socket(%X) Init Failed!\n", mtp3_para->mtp3lite_port); + exit(1); + } + else + listen(mtp3lite_listen_fd, 1); + + printf("mtp3lite_listen_fd: %d\n", mtp3lite_listen_fd); + + return 1; +} + +int isMtp3LiteClientLink(WORD lk) +{ + //4bits:none sigtran, link enable, mtp3lite enable,client + if(mtp3_para->lk[lk].admin_state && mtp3_para->lk[lk].mtp3lite_apl_mode && mtp3_para->lk[lk].e1_lk_type==LKTYPE_MTP3_LITE&& mtp3_para->lk[lk].remote_ip>0) + { + return 1; + } + return 0; +} + +int checkIfOveridesocket(WORD lk) +{ + int i; + for(i=0;ilk[lk].remote_ip==mtp3_para->lk[i].remote_ip) + { + printf("mtp3lite client, lk %d is overide with %d \n",lk,i); + return 1; + } + } + return 0; +} + + +int mtp3lite_InitClientSocket(WORD lk) +{ + struct sockaddr_in sin_addr; + int socketfd; + + bzero(&sin_addr,sizeof(struct sockaddr)); + sin_addr.sin_family = AF_INET; + //sin_addr.sin_port = htons(mtp3lite_port); + sin_addr.sin_addr.s_addr = GetLocalIP(); + + mtp3lite_link[lk].cliSockfd = -1; + if (isMtp3LiteClientLink(lk) && !checkIfOveridesocket(lk)) + { + //sin_addr.sin_port = mtp3_para->mtp3lite_port; //server port,tmp + //sin_addr.sin_addr.s_addr = mtp3_para->lk[lk].remote_ip; + //bzero(&(sin_addr.sin_zero),8); + if ((socketfd = mtp3lite_Init_TCPSocket(sin_addr,1)) < 0) + { + printf("MTP3LITE TCP Client Socket(%d) Init Failed!\n",mtp3_para->mtp3lite_port); + //exit(1); + return 0; + } + mtp3lite_link[lk].cliSockfd = socketfd; + printf("mtp3lite: init client socket link=%d\n",lk); + } + + return 1; +} + +int mtp3lite_CloseTcpConn(WORD link) +{ + if(mtp3lite_link[link].connfd>=0) + close(mtp3lite_link[link].connfd); + if(mtp3lite_link[link].cliSockfd>=0) + close(mtp3lite_link[link].cliSockfd); + mtp3lite_init_lk(link); + + return 1; +} + +int mtp3lite_get_lk_by_ip(struct sockaddr_in *client_addr) +{ + int lk; + + for (lk = 0; lk < MAX_LK; lk++) + { + if ((mtp3_para->lk[lk].remote_ip == client_addr->sin_addr.s_addr) && + (mtp3_para->lk[lk].e1_to_mtp3 == mtp3_localip) && + (mtp3_para->lk[lk].e1_lk_type ==LKTYPE_MTP3_LITE && mtp3_para->lk[lk].admin_state && mtp3_para->lk[lk].mtp3lite_apl_mode==0) && // Server & MTP3LITE & Enabled + (mtp3ObjState.lk_command[lk]!=0)) //Command enabled + { + if (mtp3lite_link[lk].connfd > 0) + { + mtp3lite_CloseTcpConn(lk); + mtp3lite_updateStatus(lk, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT); + } + else if (mtp3lite_link[lk].init_guard_timer == 0) + return lk; + return -1; + } + } + + return -1; +} + +int mtp3lite_DirectSendMsg(WORD link, int len, BYTE *msg_ptr) +{ + struct sockaddr_in sin; + + if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE + !(mtp3_para->lk[link].admin_state & 0x01) || // Not Enabled + (mtp3ObjState.lk_command[link] == 0) || // Command Disabled + (mtp3lite_link[link].connfd <= 0)) // Link Not Established + return -1; + + bzero(&sin.sin_zero, sizeof(sin.sin_zero)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = mtp3_para->lk[link].remote_ip; + sin.sin_port = mtp3lite_link[link].remote_port; + + return send(mtp3lite_link[link].connfd, msg_ptr, len, MSG_NOSIGNAL); +} + +int mtp3liteTcpConnect(int sock,struct sockaddr_in *sin_addr) +{ + if (connect(sock, (struct sockaddr *)sin_addr, sizeof(struct sockaddr)) < 0) + { + return 0; + } + else + { + printf("tcpConnect success, ip=%s\n",inet_ntoa(sin_addr->sin_addr)); + return 1; + } +} + +int mtp3lite_TcpConnectCheck() +{ + int keepAlive = 1, + keepIdle = 15, + keepInterval = 3, + keepCount = 3; + int connfdtmp = 0; + socklen_t clilen; + struct sockaddr_in cliaddr; + int link; + static BYTE cliLk=0; + + bzero(&cliaddr,(clilen = sizeof(struct sockaddr))); + + connfdtmp = accept(mtp3lite_listen_fd,(struct sockaddr *)&cliaddr,&clilen); + if (connfdtmp <= 0)//no connect request , check client socket + { + link = cliLk++; + if (!isMtp3LiteClientLink(link)) + return 0; + if (mtp3lite_link[link].connfd > 0) + return 0; + else if (mtp3lite_link[link].local_reconnect > 0) + { + mtp3lite_link[link].local_reconnect--; + return 0; + } + + if (mtp3lite_link[link].cliSockfd <= 0) + { + if (!mtp3lite_InitClientSocket(link)) + mtp3lite_init_lk(link); + } + cliaddr.sin_family = AF_INET; + cliaddr.sin_port = mtp3_para->mtp3lite_port; + cliaddr.sin_addr.s_addr = mtp3_para->lk[link].remote_ip; + bzero(&(cliaddr.sin_zero),8); + connfdtmp = mtp3lite_link[link].cliSockfd; + if (!mtp3liteTcpConnect(connfdtmp, &cliaddr)) + { + if ((errno != EINPROGRESS) && (errno != EALREADY)) + mtp3lite_CloseTcpConn(link); + return 0; + } + else + { + mtp3lite_link[link].connfd = connfdtmp; + mtp3lite_updateStatus(link, MTP2_STATE_WORKING, 0); + } + return 0; + } + else if ((link = mtp3lite_get_lk_by_ip(&cliaddr)) < 0) + { + close(connfdtmp); + return 0; + } + + mtp3lite_init_lk(link); + mtp3lite_link[link].init_guard_timer = 0; + mtp3lite_link[link].connfd = connfdtmp; + mtp3lite_link[link].cliSockfd = connfdtmp; + mtp3lite_link[link].remote_port = cliaddr.sin_port; + mtp3_debug(MTP3DB_EVENT,"link[%d] connfd: %d, rem_port: %d\n", link, connfdtmp, ntohs(mtp3lite_link[link].remote_port)); + + fcntl(mtp3lite_link[link].connfd,F_SETFL,O_NONBLOCK); + if (setsockopt(mtp3lite_link[link].connfd,SOL_SOCKET,SO_KEEPALIVE, &keepAlive,sizeof(keepAlive)) != 0) + fprintf(stderr,"set keepalive failed\n"); + + setsockopt(mtp3lite_link[link].connfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle)); + setsockopt(mtp3lite_link[link].connfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval)); + setsockopt(mtp3lite_link[link].connfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount)); + + + mtp3lite_updateStatus(link, MTP2_STATE_WORKING, 0); +// mtp3lite_DirectSendMsg(link, 3, mtp3lite_ka_msg); + + return 1; +} + +int send_mtp3lite_id_ack(WORD link) +{ + BYTE id_ack_msg[4]={0,0x1,0xfe, 0x6}; + + mtp3lite_DirectSendMsg(link, 4, id_ack_msg); + mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d send Inditify ACK",link); + return 1; +} + +int send_mtp3lite_ping(WORD link) +{ + BYTE id_ack_msg[4]={0x00,0x01,0xfe, 0x00}; + + mtp3lite_DirectSendMsg(link, 4, id_ack_msg); + mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d send PING",link); + return 1; +} + +int mtp3lite_DirectRecvMsg(WORD link) +{ + struct sockaddr_in sin; + int nbytes; + BYTE len1; + + socklen_t len = sizeof(struct sockaddr); + // if ((len1 = mtp3lite_rem_len[link])>0) + // printf("len1: %d\n", len1); + len1 = mtp3lite_rem_len[link]; + + if(len >= MTP3LITE_MSG_BUF_SIZE_PER_LINK) + { + mtp3_debug(MTP3DB_EVENT, "mtp3lite link[%d] buffer is full!\n", link); + return 0; + } + + nbytes = recvfrom(mtp3lite_link[link].connfd, mtp3lite_msg_buf[link] + len1, + MTP3LITE_MSG_BUF_SIZE_PER_LINK - len1, 0, (struct sockaddr *) &sin, &len); + + if (nbytes == 0 && errno != 11) + { + mtp3_debug(MTP3DB_EVENT, "mtp3lite tcp link[%d] error : %d\n", link, errno); + mtp3lite_CloseTcpConn(link); + mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_TCP_FAILURE); + mtp3lite_rem_len[link] = 0; + } + if(nbytes < 0 && errno == ETIMEDOUT) + { + mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT); + mtp3lite_CloseTcpConn(link); + mtp3lite_rem_len[link] = 0; + } + + if ((len1 > 0) && (nbytes > 0)) + nbytes += len1; + + return nbytes; +} +/* +int mtp3lite_decode_tcp_msg(WORD total_len, BYTE link) +{ + BYTE lk_set, *buf_ptr; + WORD sub_len, rem_len, total_hdl_len = 0; + up_message up_msg; + up_message *up_msg_ptr = &up_msg; + BYTE nw; + + if (total_len > MTP3LITE_MSG_BUF_SIZE_PER_LINK) + return -1; + + while (total_hdl_len < total_len) + { + buf_ptr = mtp3lite_msg_buf[link] + total_hdl_len; + rem_len = total_len - total_hdl_len; + sub_len = buf_ptr[0]; + + if (rem_len < (sub_len + 1)) + { + if (total_hdl_len > 0) + memcpy(mtp3lite_msg_buf[link], mtp3lite_msg_buf[link] + total_hdl_len, rem_len); + mtp3lite_rem_len[link] = rem_len; + //printf("Remain: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len); + return 1; + } + + if (sub_len < 2) + return -1; + else if (sub_len == 2) + { + if ((buf_ptr[1] == 0x4B) && (buf_ptr[2] == 0x41)) + { // Receive Keep Alive Message + mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 100; + mtp3lite_link[link].remote_inactive_timeouts = 0; + //mtp3lite_print_msg(buf_ptr, 3); + total_hdl_len += (sub_len + 1); + //printf("KeepAlive: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len); + continue; + } + else + return -1; + } + + if ((buf_ptr[1] > 9) || (buf_ptr[1] == 0)) + return -1; + + mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 100; + mtp3lite_link[link].remote_inactive_timeouts = 0; + + //mtp3lite_print_msg(buf_ptr, sub_len + 1); + + up_msg_ptr->len = sub_len; + up_msg_ptr->link = link; + lk_set = mtp3_para->lk[link].e1_to_linkset; + if (lk_set >= 128) + return -1; + nw = mtp3_para->ls_pro[lk_set] & 3; + up_msg_ptr->sio = 0x03 | (nw << 6) | 0x10;//sccp lite always ansi message + up_msg_ptr->opc = mtp3_para->ls_op_pc[lk_set]; + if (pc_length(up_msg_ptr->sio >> 6) == MTP3_24BIT_PC) + up_msg_ptr->dpc = mtp3_para->nw[nw].opc24; + else + up_msg_ptr->dpc = mtp3_para->nw[nw].opc14; + + memcpy(up_msg_ptr->msgList, buf_ptr + 1, sub_len); + + iptrans_msg_flow_2(up_msg_ptr); + send_to_sccp_lite(up_msg_ptr); + + total_hdl_len += (sub_len + 1); + //printf("Data: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len); + } + + mtp3lite_rem_len[link] = 0; + return 1; +} +*/ +/******change to struct: 00, len, 0xfd*****/ +int mtp3lite_decode_tcp_msg(WORD total_len, WORD link) +{ + BYTE *buf_ptr; + WORD lk_set, sub_len, rem_len, total_hdl_len = 0; + up_message up_msg; + up_message *up_msg_ptr = &up_msg; + BYTE nw; + + if (total_len > MTP3LITE_MSG_BUF_SIZE_PER_LINK) + return -1; + + while (total_hdl_len < total_len) + { + buf_ptr = mtp3lite_msg_buf[link] + total_hdl_len; + rem_len = total_len - total_hdl_len; + sub_len = (buf_ptr[0]<<8) + buf_ptr[1]; + + if (rem_len < (sub_len + 1)) + { + if (total_hdl_len > 0) + memcpy(mtp3lite_msg_buf[link], mtp3lite_msg_buf[link] + total_hdl_len, rem_len); + mtp3lite_rem_len[link] = rem_len; + //printf("Remain: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len); + return 1; + } + + if (sub_len < 1) + return -1; + else if (sub_len == 1) + { + if(buf_ptr[1+2] == 0x6) +// if(buf_ptr[1+2] == 0x6 || buf_ptr[2] == 0x06) + { // Receive Keep Alive Message + mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 200; + mtp3lite_link[link].remote_inactive_timeouts = 0; + //mtp3lite_print_msg(buf_ptr, 3); + total_hdl_len += (sub_len + 3); + mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d RECV Inditify ACK",link); + //printf("KeepAlive: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len); + continue; + } + else + { + //mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d RECV IPA Ping!",link); + //send_mtp3lite_ping(link); + return -1; + } + } + + // if ((buf_ptr[1+2] > 9) || (buf_ptr[1+2] == 0)) + // return -1; + + mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 200; + mtp3lite_link[link].remote_inactive_timeouts = 0; + + //mtp3lite_print_msg(buf_ptr, sub_len + 1); + + up_msg_ptr->len = sub_len; + up_msg_ptr->link = link; + lk_set = mtp3_para->lk[link].e1_to_linkset; + if (lk_set >= MAX_LS) + return -1; + //nw = mtp3_para->ls_pro[lk_set] & 3; + nw = mtp3_para->ls_pro[lk_set].nw_id ; + up_msg_ptr->sio = 0x03 | (nw << 6);//sccp lite always itu message + up_msg_ptr->sio |= (mtp3_para->nw[nw].pc_type & 1)<<4;//detect ansi or itu sccp, ansi=1,itu=0 + up_msg_ptr->opc = mtp3_para->ls_pro[lk_set].ls_op_pc; + if (pc_length(up_msg_ptr->sio >> 6) == MTP3_24BIT_PC) + up_msg_ptr->dpc = mtp3_para->nw[nw].opc24; + else + up_msg_ptr->dpc = mtp3_para->nw[nw].opc14; + + memcpy(up_msg_ptr->msgList, buf_ptr + 1 + 2, sub_len); + + iptrans_msg_flow_2(up_msg_ptr); + send_to_sccp_lite(up_msg_ptr); + + total_hdl_len += (sub_len + 1 + 2); + //printf("Data: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len); + } + + mtp3lite_rem_len[link] = 0; + return 1; +} + + +int get_mtp3lite_msg(WORD link) +{ + int nbytes; + + if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE + !(mtp3_para->lk[link].admin_state& 0x01) || // Not Enabled + (mtp3ObjState.lk_command[link]==0) || // command disabled + (mtp3lite_link[link].connfd <= 0)) // Link Not Established + { + return -1; + } + + if ((nbytes = mtp3lite_DirectRecvMsg(link)) <= 0) + return -1; + + //mtp3lite_print_msg(mtp3lite_msg_buf[link], nbytes); + + if (mtp3lite_decode_tcp_msg(nbytes, link) < 0) + { + mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d mtp3lite_decode_tcp_msg failed!",link); + /* + printf("tcp link[%d] decode error!\n", link); + mtp3lite_CloseTcpConn(link); + mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_TCP_FAILURE); + mtp3lite_rem_len[link] = 0; + */ + return -1; + } + + return 1; +} + +int put_mtp3lite_msg(BYTE *msg_ptr) +{ + BYTE nw, pclen, offset; + WORD ls, len, link; + + link = msg_ptr[1]*256+msg_ptr[0];//??? + len = (msg_ptr[2]<<8) + msg_ptr[3]; + + if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE + !(mtp3_para->lk[link].admin_state& 0x01) || // Not Enabled + (mtp3ObjState.lk_command[link]==0) || // Command disabled + (mtp3lite_link[link].connfd <= 0)) // Link Not Established + return -1; + + if ((ls = mtp3_para->lk[link].e1_to_linkset) >= MAX_LS) + return -1; + + nw = mtp3_para->ls_pro[ls].nw_id; //& 0x03; + pclen = (mtp3_para->nw[nw].pc_len) & 0x01; + + if (pclen) + { + if (len <= 8) + return -1; + offset = 9+1+1;//msg_ptr[offset+1] = sccp data + msg_ptr[offset-1] = (len - 8)%0xff; + msg_ptr[offset-2] = (len - 8)/0xff; + len = len - 7+2; + } + else + { + if (len <= 5) + return -1; + offset = 6+1+1; + msg_ptr[offset-1] = (len - 5)%0xff; + msg_ptr[offset-2] = (len - 5)/0xff; + len = len - 4+2; + } +/******change to struct: 00, len, 0xfd*****/ + msg_ptr[offset] = 0xfd; + +/******change to struct: 00, len, 0xfd*****/ + mtp3lite_DirectSendMsg(link, len, msg_ptr + offset - 2); + //mtp3lite_link[link].local_inactive = 2000; + + return 0; +} +/* +int put_mtp3lite_msg(BYTE *msg_ptr) +{ + BYTE link, len, ls, nw, pclen, offset; + + link = msg_ptr[0]; + len = msg_ptr[1]; + + if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE + !(mtp3_para->lk[link].e1_lk_type & 0x01) || // Not Enabled + (mtp3ObjState.lk_command[link]==0) || // Command disabled + (mtp3lite_link[link].connfd <= 0)) // Link Not Established + return -1; + + if ((ls = mtp3_para->lk[link].e1_to_linkset) >= 128) + return -1; + + nw = mtp3_para->ls_pro[ls] & 0x03; + pclen = (mtp3_para->nw_pro >> nw) & 0x01; + + if (pclen) + { + if (len <= 8) + return -1; + offset = 9; + msg_ptr[offset] = len - 8; + len = len - 7; + } + else + { + if (len <= 5) + return -1; + offset = 6; + msg_ptr[offset] = len - 5; + len = len - 4; + } + + mtp3lite_DirectSendMsg(link, len, msg_ptr + offset); + //mtp3lite_link[link].local_inactive = 2000; + + return 0; +} +*/ +int mtp3lite_chk_lk(WORD link) +{ +// char str[19]={7,0,0x11,0x83,0x71,0xab,0xdc,0x1a,0x06,0xf6, 0,0,0,1,5,1,3,2,9,4}; + if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE + !(mtp3_para->lk[link].admin_state& 0x01) || // Not Enabled + (mtp3ObjState.lk_command[link] == 0)) // Command disabled + return 0; + + if (mtp3lite_link[link].init_guard_timer > 0) + mtp3lite_link[link].init_guard_timer--; + + if (mtp3lite_link[link].connfd <= 0) // Link Not Established + return 0; + + if (mtp3lite_link[link].remote_inactive > 0) + { + if (--mtp3lite_link[link].remote_inactive == 0) + { + +// if (++mtp3lite_link[link].remote_inactive_timeouts >= mtp3_para->lk[link].inactive_tm) + if(0) + { + printf("link[%d] remote inactivity %d seconds timeout %d times!\n", link, mtp3_para->lk[link].inactive, mtp3_para->lk[link].inactive_tm); + mtp3lite_CloseTcpConn(link); + mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT); + } + else + { + mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 200; + } + } + } + + if (mtp3lite_link[link].local_inactive > 0) + { + if(mtp3lite_id_fg[link]==0) + { + mtp3lite_id_fg[link] = 1; + send_mtp3lite_id_ack(link); + //send_mtp3lite_ping(link); + } + if (--mtp3lite_link[link].local_inactive == 0) + { +// mtp3lite_DirectSendMsg(link, 3, mtp3lite_ka_msg); +// put_mtp3lite_msg(&str); + mtp3lite_link[link].local_inactive = 2000; + send_mtp3lite_id_ack(link); + } + } + + return 1; +} + +void deactive_mtp3lite_lk(WORD link) +{ + if ((MTP3_LINK_TYPE(link) == LKTYPE_MTP3_LITE) && // MTP3LITE + (mtp3_para->lk[link].admin_state & 0x01) && // Enabled + (mtp3lite_link[link].connfd > 0)) + {//sccp lite link + mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d Deactive by MNG",link); + mtp3lite_CloseTcpConn(link); + mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT); + } +} + +void mtp3lite_init(void) +{ + int i; + + printf("MTP3LITE Init Start!\n"); + + for (i = 0; i < 1024; i++) + { + mtp3lite_init_lk(i); + mtp3lite_InitClientSocket(i); + } + + mtp3lite_listen_fd = -1; + +// mtp3lite_InitServerSocket(); + + mtp3lite_init_ka_msg();//keep alive message + + printf("MTP3LITE Init Complete!\n"); +} + +void mtp3lite_reset(void) +{ + int link; + + for (link=0;link=0) + { + mtp3lite_CloseTcpConn(link); + mtp3lite_rem_len[link] = 0; + } + } +} + +void mtp3lite_timer(void) +{ + int link; + + mtp3lite_TcpConnectCheck(); + + for (link = 0; link < MAX_LK; link++) + { + get_mtp3lite_msg(link); + mtp3lite_chk_lk(link); + } +} +/*@end@*/ diff --git a/plat/mtp3/src/mtpinit.c b/plat/mtp3/src/mtpinit.c new file mode 100644 index 0000000..df6ee8a --- /dev/null +++ b/plat/mtp3/src/mtpinit.c @@ -0,0 +1,2223 @@ +#include "../../public/src/include/includes.h" +#include "../../debug/src/include/debug.h" +#include "./include/mtp3.h" +#include "./include/mtpstm.h" +#include "./include/mtpdef.h" +#include "./include/mtpfunc.h" +#include "./include/mtp3lite.h" + +// fix multiple definition======================================= +WORD ls_slc[MAX_LS*16]; +WORD ls_sls[MAX_LS*16]; +WORD sls_to_link[MAX_LS*16]; + +/** link mark **/ +BYTE link_available[MAX_LK]; +BYTE link_unavailable[MAX_LK]; +BYTE changeover_possible[MAX_LK]; +BYTE retrieval_required[MAX_LK]; +BYTE remote_bsnt_retrieved[MAX_LK]; +BYTE changeback_in_progress[MAX_LK]; +BYTE changeover_in_progress[MAX_LK]; +BYTE changeback_required[MAX_LK]; +BYTE changeover_required[MAX_LK]; +BYTE emergency_changeover_order[MAX_LK]; +BYTE changeover_order[MAX_LK]; +BYTE changeover_completed[MAX_LK]; +BYTE failed[MAX_LK]; +BYTE blocked_by[MAX_LK]; +BYTE local_blocked[MAX_LK]; +BYTE remote_blocked[MAX_LK]; +BYTE first_failure[MAX_LK]; +BYTE changeover_select[MAX_LK]; +BYTE changeback_select[MAX_LK]; +BYTE co_msg_can_exchange[MAX_LK]; +BYTE cb_msg_can_exchange[MAX_LK]; +BYTE local_bsnt_retrievable[MAX_LK]; +BYTE retrieved_bsnt[MAX_LK]; +BYTE fsnt[MAX_LK]; +BYTE fsnl[MAX_LK]; +BYTE fsnc[MAX_LK]; +BYTE bsnt[MAX_LK]; +BYTE tcbc_route_change[MAX_LK]; +BYTE command3[MAX_LK]; +BYTE cbd_cbc_r[MAX_LK]; +BYTE cba_cbc_r[MAX_LK]; +WORD cbc_s[MAX_LK]; +BYTE controlled_rerouting_in_progress[MAX_LK]; +BYTE transfer_prohibited[MAX_LK]; +BYTE own_sp_restarting; +BYTE link_remotely_inhibited[MAX_LK]; +BYTE link_locally_inhibited[MAX_LK]; +BYTE link_inhibited[MAX_LK]; +BYTE local_inhibit_in_progress[MAX_LK]; +BYTE uninhibit_in_progress[MAX_LK]; +BYTE management_req[MAX_LK]; +BYTE t12_expired_2nd_time[MAX_LK]; +BYTE t13_expired_2nd_time[MAX_LK]; +BYTE sending_phase_finished[MAX_LS]; + +WORD mtp3_timer[24]; + +BYTE sd_buf_h[256]; +BYTE sd_buf_t[256]; + +MTP3Parameter *mtp3_para; +MTP3Parameter mtp3_para_init; +mtp mtp3; +mtp3_csta mtp3_measure; +measure_of_mtp3 *current_measure; +BYTE current_mtime;/* current measure time */ +heartbeat_compoent_of_mtp3 mtp3_heartbeat; + +/** debug **/ + +BYTE mtp_asciout_buf[2048]; +char mtp_asciin_buf[80]; + +BYTE t1_delay_mtp3[MAX_LK]; +BYTE t2_delay_mtp3[MAX_LK]; +BYTE t3_delay_mtp3[MAX_LK]; +BYTE t4_delay_mtp3[MAX_LK]; +BYTE t5_delay_mtp3[MAX_LK]; +BYTE t6_delay_mtp3[MAX_LK]; +BYTE t7_delay_mtp3[MAX_LK]; +BYTE t8_delay_mtp3[MAX_LK]; +BYTE t9_delay_mtp3[MAX_LK]; +BYTE t10_delay_mtp3[MAX_LK]; +BYTE t11_delay_mtp3[MAX_LK]; +BYTE t12_delay_mtp3[MAX_LK]; +BYTE t13_delay_mtp3[MAX_LK]; +BYTE t14_delay_mtp3[MAX_LK]; +BYTE t15_delay_mtp3[MAX_LK]; +BYTE t16_delay_mtp3[MAX_LK]; +BYTE t17_delay_mtp3[MAX_LK]; +BYTE t18_delay_mtp3; +BYTE t19_delay_mtp3; +BYTE t20_delay_mtp3; +BYTE t21_delay_mtp3[MAX_LK]; +BYTE t22_delay_mtp3[MAX_LK]; +BYTE t23_delay_mtp3[MAX_LK]; +BYTE t24_delay_mtp3[MAX_LK]; +BYTE sltc_t1_delay[MAX_LK]; +BYTE sltc_t2_delay[MAX_LK]; + +BYTE mtp3_t21_flag[MAX_LS]; +BYTE mtp3_t22_flag[MAX_LK]; +BYTE mtp3_t23_flag[MAX_LK]; +BYTE mtp3_t12_flag[MAX_LK]; +BYTE mtp3_t13_flag[MAX_LK]; +BYTE mtp3_t14_flag[MAX_LK]; + +BYTE srm_nw; +BYTE active_ls_num; +BYTE current_active_ls_num; +BYTE rv_TRA_num; +BYTE tprc_nw; +//BYTE taprc_loop[128]; +BYTE taprc_loop[MAX_LS]; + +BYTE mtp_t1[256]; +BYTE mtp_t2[256]; +BYTE mtp_t3[256]; +BYTE mtp_t4[256]; +BYTE mtp_t5[256]; +BYTE mtp_t7[256]; +BYTE mtp_t12[256]; +BYTE mtp_t13[256]; +BYTE mtp_t14[256]; +BYTE mtp_t17[256]; +BYTE mtp_t22[256]; +BYTE mtp_t23[256]; +BYTE mtp_t24[256]; + +BYTE mtp2_flag_new[32]; +BYTE mtp2_flag_old[32]; + +ulong mtp3_localip; +ulong mtp3_alterip; + +WORD wx5[256]; +BYTE debug_link[MAX_LK]; + +long mtp3_timestamp; +long mtp3_csta_p; + +ulong mtp3_get_msg; + +BYTE local_change_over[MAX_LK]; + +BYTE mtp2_buf_full[MAX_LK]; +BYTE nld_cause_lkd[MAX_LK]; + +BYTE init_lsac_state[MAX_LK]; +BYTE init_tlac_state[MAX_LK]; + +ulong TFAmsg_OPC; +WORD TFAmsg_SrcLk; +ulong TFPmsg_OPC; +WORD TFPmsg_SrcLk; +WORD sdTFP_Ls; +WORD sdTFA_Ls; +BYTE mtp2_module; +BYTE mtp2_systemid; + +// mtp3 dynamic opc +mtp3_dynamic_opc mtp3_opc; +//======================================= + +/*@ignore@*/ +#define PROG_NAME "iptrans" + +extern iprt1 mtp3_iprt; +struct tm mtp3_tm; +struct tm *mtp3_time = &mtp3_tm; +iptrans_shm *IPTRANS_shm_ptr; +static int iptrans_shm_id; +tup_shm *T_shm_ptr; +isup_shm *I_shm_ptr; +bicc_shm *B_shm_ptr; +sccp_shm *S_shm_ptr; +primitive_to_isup *I_primitive; +primitive_to_bicc *B_primitive; +primitive_to_sccp *S_primitive; +primitive_to_tup *T_primitive; + +primitive_to_isup I_primitive_init; +primitive_to_bicc B_primitive_init; +primitive_to_sccp S_primitive_init; +primitive_to_tup T_primitive_init; +tup_shm tup_shm_ptr_init; +isup_shm isup_shm_ptr_init; +bicc_shm bicc_shm_ptr_init; +sccp_shm sccp_shm_ptr_init; + +BOOL mtp3DebugFull=0; +mtp3_routing_result routingResult; +void scan_conf_right_or_not(BYTE nw); +void rsrt_proc(BYTE netw,WORD dst); +void mtp3lite_reset(void); +void otherMTP3_managed_link_unavailable(WORD chl); + +int mtp3lite_InitServerSocket(); +extern int mtp3lite_listen_fd; +extern ull Str2Ull(char *pStr); +extern void send_to_mtp2(long dest_ip); +extern void send_to_mtp2_new_struct(long dest_ip);//link,len_high,len_low,sio... +extern void MTP3_send_isup_count(BYTE nw,BYTE type); +extern void get_routes_from_other_plat(); +extern void deactive_m3ua_lk(WORD link); +extern int checkMtp3SaveFlag(); +extern void mtp3DisableSaveFlag(); +extern int mtp3_write_para(); + +DWORD mtp_local_ip, mtp_peer_ip; + +void send_ip_to_mtp2(); + +void mtp3_init_dynamic_opc() +{ + memset((BYTE *)&mtp3_opc, 0, sizeof(mtp3_dynamic_opc)); +} + +int mtp3_create_opc(BYTE nw, ulong opc) +{ + BYTE i, pclen, num; + ulong para_opc; + + if ((nw > 3) || (opc == 0)) + return -1; + + pclen = pc_length(nw); + if (pclen == MTP3_24BIT_PC) + para_opc = mtp3_para->nw[nw].opc24; + else + para_opc = mtp3_para->nw[nw].opc14; + if (opc == para_opc) + return 0; + + num = mtp3_opc.opc_num[nw]; + for (i = 0; i < num; i++) + { + if (mtp3_opc.opc[nw][i] == opc) + return 0; + } + + if (num >= MTP3_MAX_DYNAMIC_OPC_PER_NW) + return -1; + + mtp3_opc.opc[nw][num] = opc; + mtp3_opc.opc_num[nw]++; + + return 0; +} + +int mtp3_delete_opc(BYTE nw, ulong opc) +{ + BYTE i, pclen, num, num_mv; + ulong para_opc; + + if ((nw > 3) || (opc == 0)) + return -1; + + pclen = pc_length(nw); + if (pclen == MTP3_24BIT_PC) + para_opc = mtp3_para->nw[nw].opc24; + else + para_opc = mtp3_para->nw[nw].opc14; + if (opc == para_opc) + return 0; + + num = mtp3_opc.opc_num[nw]; + if (num == 0) + return -1; + + for (i = 0; i < num; i++) + { + if (mtp3_opc.opc[nw][i] == opc) + { + num_mv = num - i - 1; + memcpy((BYTE *) &mtp3_opc.opc[nw][i], (BYTE *) &mtp3_opc.opc[nw][i+1], num_mv * sizeof(ulong)); + mtp3_opc.opc[nw][num-1] = 0; + mtp3_opc.opc_num[nw]--; + return 0; + } + } + + return -1; +} + +BYTE mtp3_check_dpc_equal_to_opc(BYTE nw, ulong dpc) +{ + BYTE i, pclen, num; + ulong para_opc; + + if ((nw > 3) || (dpc == 0)) + return 0; + + pclen = pc_length(nw); + if (pclen == MTP3_24BIT_PC) + para_opc = mtp3_para->nw[nw].opc24; + else + para_opc = mtp3_para->nw[nw].opc14; + if (dpc == para_opc) + return 1; + + num = mtp3_opc.opc_num[nw]; + for (i = 0; i < num; i++) + { + if (mtp3_opc.opc[nw][i] == dpc) + return 1; + } + + return 0; +} + +BYTE MTP3_LINK_TYPE(WORD Link) +{ + return mtp3_para->lk[Link].e1_lk_type;// >> 1) & 0x07; +} + +void MTP3_Enable_SubSystem(BYTE SubSystem) +{ + SubSystem &= 15; + + if (SubSystem < 8) + mtp3_heartbeat.SubState[0] |= (1 << SubSystem); + else + mtp3_heartbeat.SubState[1] |= (1 << (SubSystem & 7)); +} + +void MTP3_Disable_SubSystem(BYTE SubSystem) +{ + SubSystem &= 15; + + if (SubSystem < 8) + mtp3_heartbeat.SubState[0] |= (~(1 << SubSystem)); + else + mtp3_heartbeat.SubState[1] |= (~(1 << (SubSystem & 7))); + +} + +void scan_lk_state_quickly(WORD lk) +{ + if (mtp3ObjState.lk_configured[lk] != PARA_CONFIGURED) + { + lk = lk+1; + return; + } + if (mtp3ObjState.link_l3_state[lk] != AVAILABLE) + { + current_measure->lk_measure1[lk][3]++;//Duration of SL unavailability(for any reason + } + else if (mtp3ObjState.link_l3_state[lk] == UNAVAILABLE) + current_measure->lk_measure1[lk][6]++;//Duration of SL unavailability due to link fai + if (mtp3ObjState.link_l3_state[lk] == INHIBITED) + { + if (link_locally_inhibited[lk] == TRUE) + { + current_measure->lk_measure1[lk][4]++;//Duration of SL inhibition due to local management actions + } + else + current_measure->lk_measure1[lk][5]++;//Duration of SL inhibition due to remote management actions + } + + if (mtp3_para->lk[lk].e1_to_mtp3 == mtp3_localip) + {//this mtp3 is the normal mtp3 of this link + if (mtp3ObjState.lk_AMTP3_ok[lk] & 15)//Alternative MTP3 available + { +// mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_alterMTP3; + //do nothing, waiting for alternative unavailable + } + else if (mtp3ObjState.lk_NMTP3_ok[lk] >> 4)//if Alternative MTP3 not avilable and normal mtp3 is activated + { + mtp3_debug(MTP3DB_EVENT,"link %d host MTP3 change from backup to normal",lk); + mtp3ObjState.lk_NMTP3_ok[lk] &= 0x0f; + if (mtp3ObjState.lk_mtp3[lk] == mtp3_para->lk[lk].e1_to_alterMTP3) + { + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + if (mtp3ObjState.link_l3_state[lk] == AVAILABLE) + otherMTP3_managed_link_unavailable(lk); + } + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + else//other case normal is always the host + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + else if (mtp3_para->lk[lk].e1_to_alterMTP3 == mtp3_localip) + {//this mtp3 is the alternative mtp3 of this link + if (mtp3ObjState.lk_mtp3[lk] == mtp3_localip)//it is the current host + { + if ((mtp3ObjState.lk_AMTP3_ok[lk]>>4)==2)//only the deactivate command can make it abandon host + { + mtp3_debug(MTP3DB_EVENT,"link %d host MTP3 change back to normal",lk); + mtp3ObjState.lk_AMTP3_ok[lk] &= 0x0f; + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + +/* disable the link */ + mtp3_debug(MTP3DB_EVENT,"link %d L2 out of service (changing back to normal MTP3)",lk); + mtp3ObjInput.lsac_input_from_l2[lk] = LSAC_L2_OUT_OF_SERVICE; + mtp3ObjInput.sltc_input[lk] = SLTC_STOP; + sltc_proc(lk); + + /* send stop command to mtp2 */ + if (MTP3_LINK_TYPE(lk) == LKTYPE_SIGTRAN)//m2ua link + { + send_command_to_mtp2(lk,MTP2_DEACTIVE_LINK); + send_command_to_mtp2(lk,MTP3_M2UA_DISABLE); + } + else + send_command_to_mtp2(lk,MTP2_STOP_L2); + //mtp3_send_alarm(MTP3_LINK_COMPONENT+lk,MTP3ALARM_LINK_CB_TO_NMTP3); + } + } + else + { + if (mtp3ObjState.lk_NMTP3_ok[lk] & 15) + {//normal ok + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + + else if ((mtp3ObjState.lk_AMTP3_ok[lk]>>4)==1)//if normal MTP3 not avilable and alternative mtp3 is activated + { + mtp3_debug(MTP3DB_EVENT,"link %d host MTP3 change to alternative",lk); + mtp3ObjState.lk_AMTP3_ok[lk] &= 0x0f; + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_alterMTP3; + + } + } + } + + else + { + if (mtp3ObjState.lk_AMTP3_ok[lk] & 15) + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_alterMTP3; + + else if (mtp3ObjState.lk_NMTP3_ok[lk] & 15) + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + +/* + if (mtp3ObjState.lk_mtp3[lk]==mtp3_localip) + { + mtp3_heartbeat.masterMTP3[lk/8] |= (1<<(lk&7)); + } + else + mtp3_heartbeat.masterMTP3[lk/8] &= (~(1<<(lk&7))); +*/ + lk = lk+1; + + if (lk==255) + { + set_status(MTP3_COMPONENT_ID,MTP3_HB_LEN,(BYTE*)&mtp3_heartbeat.version); + } +} + + +void MTP3_activate(ulong ip) +{ + int chl; + + for (chl=0; chllk[chl].e1_to_mtp3 == ip ) + { + if ((mtp3_para->lk[chl].e1_to_alterMTP3 != 0) && (mtp3_para->lk[chl].e1_to_alterMTP3 != 0xffffffff)) + { + mtp3ObjState.lk_NMTP3_ok[chl] = 0x11;// activated and set ok + mtp3ObjInput.lsac_input_from_mgmt[chl] = LSAC_MGMT_ACTIVATE_LINK; + mtp3_debug(MTP3DB_EVENT,"Upper layer active link %d normal MTP3",chl); + } + } + else if ( mtp3_para->lk[chl].e1_to_alterMTP3 == ip ) + { + mtp3ObjState.lk_AMTP3_ok[chl] = 0x11;// activated and set ok + mtp3ObjInput.lsac_input_from_mgmt[chl] = LSAC_MGMT_ACTIVATE_LINK; + mtp3_debug(MTP3DB_EVENT,"Upper layer active link %d alternative MTP3",chl); + mtp3_alterip = ip;//take over altermtp3 + } + } +} + +void MTP3_deactivate(ulong ip) +{ + int chl; + + for (chl=0; chllk[chl].e1_to_mtp3 == ip ) + { + if ((mtp3_para->lk[chl].e1_to_alterMTP3 != 0) && (mtp3_para->lk[chl].e1_to_alterMTP3 != 0xffffffff)) + { + mtp3ObjState.lk_NMTP3_ok[chl] = 0x20;//deactive and set not ok + mtp3ObjInput.lsac_input_from_mgmt[chl] = LSAC_MGMT_DEACTIVATE_LINK; + mtp3_debug(MTP3DB_EVENT,"Upper layer deactive link %d normal MTP3",chl); + } + } +*/ + if ( mtp3_para->lk[chl].e1_to_alterMTP3 == ip ) + { + mtp3ObjState.lk_AMTP3_ok[chl] = 0x20;//deactive and set not ok + mtp3ObjInput.lsac_input_from_mgmt[chl] = LSAC_MGMT_DEACTIVATE_LINK; + mtp3_debug(MTP3DB_EVENT,"Upper layer deactive link %d alternative MTP3",chl); + deactive_m3ua_lk(chl); + if ((MTP3_LINK_TYPE(chl) == LKTYPE_M3UA) && // M3UA + (mtp3_para->lk[chl].admin_state)) + scan_lk_state_quickly(chl); + mtp3_alterip = 0;//take over altermtp3 + } +// mtp3_heartbeat.link_state[chl/8] = mtp3_heartbeat.link_state[chl/8] & (~(1<<(chl&7))); + } +} + +BYTE *check_MTP3LinkType() +{ + return mtp3ObjState.link_type; +} + +BYTE *check_MTP3LinkL2State() +{ + return mtp3ObjState.link_l2_state; +} + +int mtp3_get_time() +{ + long curr_time; + curr_time = time((long *)0); + mtp3_time = localtime(&curr_time); + return 1; +} + +void mtp3_set_csta_p() +{ + BYTE csta_p; + long timestamp; + + csta_p = (mtp3_time->tm_hour*4+(mtp3_time->tm_min/15))%96; + if (mtp3_csta_p != csta_p) + {/* clear csta_p buffer */ + timestamp = time((long *)0); + memset(&mtp3_measure.measure[csta_p],0,sizeof(struct measure_of_mtp3)); + mtp3_measure.measure[csta_p].time_stamp = timestamp; + } + mtp3_csta_p = csta_p; + current_measure = &mtp3_measure.measure[mtp3_csta_p]; +} + +void mtp_lgetlocalip() +{ + /* + struct hostent *host; + struct in_addr *hostip_addr; + char name[100]; + + gethostname(name,24); + if ( (host=gethostbyname(name)) == NULL ) + { + printf("MTP3 Get Host Name Failed!\n"); + exit(0); + } + hostip_addr = (struct in_addr*) (*host->h_addr_list); + mtp3_localip = hostip_addr->s_addr; +// return (unsigned char)host->h_addr_list[0][2]; + */ + mtp3_localip = GetLocalIP(); +} + +void * +mtp3_ShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg) +{ +void *retp; +//char *func_name = "ShmInit"; + + shm_id = shmget(key, size, shmflg); + + retp = shmat(shm_id, (char *)0, 0); + + return retp; +} + +/*******************************/ + +void tup_shm_init() +{ + T_shm_ptr = &tup_shm_ptr_init; + T_shm_ptr->TM_Buf.RSub = 0; + T_shm_ptr->TM_Buf.WSub = 0; + T_shm_ptr->MT_Buf.RSub = 0; + T_shm_ptr->MT_Buf.WSub = 0; + + T_primitive = &T_primitive_init; + T_primitive->WSub = 0; + T_primitive->RSub = 0; +} + +void isup_shm_init() +{ + I_shm_ptr = &isup_shm_ptr_init; + I_shm_ptr->IM_Buf.RSub = 0; + I_shm_ptr->IM_Buf.WSub = 0; + I_shm_ptr->MI_Buf.RSub = 0; + I_shm_ptr->MI_Buf.WSub = 0; + + I_primitive = &I_primitive_init; + I_primitive->WSub = 0; + I_primitive->RSub = 0; +} + +void bicc_shm_init() +{ + B_shm_ptr = &bicc_shm_ptr_init; + B_shm_ptr->IM_Buf.RSub = 0; + B_shm_ptr->IM_Buf.WSub = 0; + B_shm_ptr->MI_Buf.RSub = 0; + B_shm_ptr->MI_Buf.WSub = 0; + + B_primitive = &B_primitive_init; + B_primitive->WSub = 0; + B_primitive->RSub = 0; +} + +void sccp_shm_init() +{ + S_shm_ptr = &sccp_shm_ptr_init; + S_shm_ptr->SM_Buf.RSub = 0; + S_shm_ptr->SM_Buf.WSub = 0; + S_shm_ptr->MS_Buf.RSub = 0; + S_shm_ptr->MS_Buf.WSub = 0; + + S_primitive = &S_primitive_init; + S_primitive->WSub = 0; + S_primitive->RSub = 0; +} + +void iptransInit_mtp3() +{ + /* + * Get shared memory block, + * IPTRANS_SHM_KEY to be defined in iptrans.h + */ + IPTRANS_shm_ptr = (iptrans_shm *) mtp3_ShmInit(iptrans_shm_id, + PROG_NAME,IPTRANS_SHM_KEY+wxc2_get_shm_offset(), + sizeof(iptrans_shm), IPTRANS_SHM_PERM|IPC_CREAT); +// memset(IPTRANS_shm_ptr, 0, sizeof(iptrans_shm)); +} + +void init_mtp3para() +{ + int i,j; + mtp3_para = &mtp3_para_init; + for (i=0; ilk[i].e1_to_linkset = MAX_LS; + mtp3_para->lk[i].e1_to_slc = 0; + for (j=0; j<4; j++) + { + mtp3_para->nw[j].routing[i].normal_ls = MAX_LS; + mtp3_para->nw[j].routing[i].alternative_ls = MAX_LS; + } + } +} + + +int mtp3_set_flag_ip(WORD link, ulong mtp3_ip) +{ + int i; + + + for(i = 0; i <= MAX_MTP3_NUM; i++) + { + if(MTP3IPMng.mtp3_flag_ip[i] == mtp3_ip) + return 2; + + } + for(i = 0; i <= MAX_MTP3_NUM; i++) + { + if(MTP3IPMng.mtp3_flag_ip[i] == 0) + { + MTP3IPMng.mtp3_flag_new[i] = 1; + MTP3IPMng.mtp3_flag_ip[i] = mtp3_ip; + return 1; + } + } + return 0; +} + + +void mtp3_set_link_manager(WORD link) +{ + if (mtp3_para->lk[link].e1_to_mtp3 == mtp3_localip) + { + if (mtp3_para->lk[link].e1_to_alterMTP3 != 0 && mtp3_para->lk[link].e1_to_alterMTP3 != 0xffffffff) + { + mtp3ObjState.lk_mtp3[link] = mtp3_para->lk[link].e1_to_alterMTP3; + mtp3ObjState.lk_AMTP3_ok[link] = 1; +// MTP3IPMng.mtp3_flag_new[0] = 1; +// MTP3IPMng.mtp3_flag_ip[0] = mtp3_para->lk[link].e1_to_alterMTP3; + mtp3_set_flag_ip(link, mtp3_localip); + if(mtp3_set_flag_ip(link, mtp3_para->lk[link].e1_to_alterMTP3)<=0) + { + printf("\r\n mtp3 set flag ip error! link=%d, e1_to_alterMTP3=%ld\r\n", link, mtp3_para->lk[link].e1_to_alterMTP3 ); + } + } + else + { + mtp3ObjState.lk_mtp3[link] = mtp3_para->lk[link].e1_to_mtp3; + mtp3ObjState.lk_AMTP3_ok[link] = 0; + } + } + else if (mtp3_para->lk[link].e1_to_alterMTP3 == mtp3_localip) + { + if (mtp3_para->lk[link].e1_to_mtp3 != 0 && mtp3_para->lk[link].e1_to_mtp3 != 0xffffffff) + { + mtp3ObjState.lk_mtp3[link] = mtp3_para->lk[link].e1_to_mtp3; + mtp3ObjState.lk_NMTP3_ok[link] = 1; +// MTP3IPMng.mtp3_flag_new[1] = 1; +// MTP3IPMng.mtp3_flag_ip[1] = mtp3_para->lk[0].e1_to_mtp3; + if(mtp3_set_flag_ip(link, mtp3_para->lk[link].e1_to_mtp3)<=0) + { + printf("\r\n mtp3 set flag ip error! link=%d, e1_to_mtp3=%ld\r\n", link, mtp3_para->lk[link].e1_to_mtp3 ); + } + } +/* else + { + mtp3ObjState.lk_mtp3[link] = mtp3_para->lk[link].e1_to_alterMTP3; + mtp3ObjState.lk_NMTP3_ok[link] = 0; + }*/ + } + else + { + mtp3ObjState.lk_NMTP3_ok[link] = 0; + mtp3ObjState.lk_AMTP3_ok[link] = 0; + mtp3ObjState.lk_mtp3[link] = mtp3_para->lk[link].e1_to_mtp3; + } +} + +static void i_sys() +{ + int i; + BYTE version[3] = MTP3_VERSION; + + memset(&mtp3_heartbeat,0,sizeof(heartbeat_compoent_of_mtp3)); + memset(&mtp3SortRoutine,0,sizeof(mtp3_dpc_index)); + + for (i=0; i<32; i++) + { + mtp2_flag_new[i] = IDLE; + mtp2_flag_old[i] = IDLE; + } + for (i=0; ilk[i].e1_to_alterMTP3; + else if (mtp3ObjState.lk_NMTP3_ok[i]) + mtp3ObjState.lk_mtp3[i] = mtp3_para->lk[i].e1_to_MTP3; + else + mtp3ObjState.lk_mtp3[i] = 0;*/ + if (i<= 255) + wx5[i] = i*5; + debug_link[i] = MTP3_MSGLOG_OFF; + } + + mtp3_heartbeat.state = 0; + mtp3_heartbeat.SubState[0] = 0xff;//all subs system available + mtp3_heartbeat.SubState[1] = 0xff;//all subs system available + memcpy(mtp3_heartbeat.version,version,3); +} + +int MTP3_LinkIP_List(ulong IP,BYTE mode) +{//mode=0:query ip, mode=1:add ip, mode=2:del ip + int i; + + if (IP==0 || IP==0xffffffff) + return -1; + + for (i=0;i1)) + memcpy(&MTP3IPMng.LinkIP[i],&MTP3IPMng.LinkIP[i+1],MTP3IPMng.LinkIPNum-i-1); + MTP3IPMng.LinkIPNum--; + } + return i; + } + } + + if (MTP3IPMng.LinkIPNum >= MAX_MTP3_NUM) + return 0; + + if (mode==1) + { + MTP3IPMng.LinkIP[MTP3IPMng.LinkIPNum] = IP; + MTP3IPMng.LinkIPNum = (MTP3IPMng.LinkIPNum + 1) & (MAX_MTP3_NUM-1); + return MTP3IPMng.LinkIPNum-1; + } + + return -1; +} + +/* slc0 slc1 slc3 slc5 +sls 0 1 2 3 +sls 4 5 6 7 +sls 8 9 10 11 +sls 12 13 14 15 */ + + +void update_sls_to_link_table(int ls) +{ + int i=0,j; + BYTE sls=0; + int lknum; + int place; + int lsx16; + int link; + + lsx16 = ls*16; + lknum = mtp3.ls[ls].linksNum_configured; +// lknum = linknum_in_ls[ls]; + if (lknum > 0) + { + for (sls=0; sls<16; sls++) + { + place = sls % lknum; + j=0; + for (i=0; i<16; i++) + { + link = ls_slc[lsx16+i]; + if (mtp3ObjState.lk_configured[link] == PARA_CONFIGURED) + { + if (j == place) + { + sls_to_link[lsx16+sls] = link; + break; + } + else + j++; + } + } + } + } + else + { + for (sls=0; sls<16; sls++) + { + sls_to_link[lsx16+sls] = 0xFF; + } + } +} + +int update_ls_slc_table(int link) +{ + WORD ls; + int lsx16; + BYTE slc; + int temp; + int idiv4; + int idiv8; + + idiv4 = link/4; + idiv8 = link/8; + temp = 3<<((link%4)*2); + ls = mtp3_para->lk[link].e1_to_linkset;//??? + if (ls < MAX_LS) + { + lsx16 = ls << 4; + slc = mtp3_para->lk[link].e1_to_slc; + if ( (slc < 16) && + (mtp3_para->lk[link].admin_state& 1) &&//enabled + (mtp3ObjState.lk_configured[ls_slc[lsx16+slc]] != PARA_CONFIGURED)) + { + mtp3ObjState.lk_configured[link] = PARA_CONFIGURED; + mtp3ObjState.link_l3_state[link] = UNAVAILABLE; + mtp3ObjState.link_enable_sent_flag[link] = 0; + + mtp3.ls[ls].linksNum_configured++; + ls_slc[lsx16+slc] = link; +// linknum_in_ls[ls]++; + mtp3_heartbeat.link_state[idiv4] = mtp3_heartbeat.link_state[idiv4] & (~temp); + return 1; + } + else + { + mtp3ObjState.lk_configured[link] = PARA_NOT_CONFIGURED; + mtp3ObjState.link_l3_state[link] = UNAVAILABLE; + mtp3ObjState.link_enable_sent_flag[link] = 0; + + mtp3_heartbeat.link_state[idiv4] = mtp3_heartbeat.link_state[idiv4] | temp; + } + } + else + mtp3_heartbeat.link_state[idiv4] = mtp3_heartbeat.link_state[idiv4] | temp; + + return 0; +} + +void update_influence_table(BYTE nw_no) +{ + nw_para *routine; + int lsno; + BYTE dst_num; + int i; + ls_info *ls; + BOOL added=0; + + routine = &mtp3_para->nw[nw_no]; + for ( i=0; irouting[i].dpc == 0) + continue; + lsno = routine->routing[i].normal_ls; + if ( (lsno < MAX_LS) && + ((mtp3_para->ls_pro[lsno].nw_id) == nw_no) ) + { + added = 1; + Mtp3AddSortRec(nw_no,routine->routing[i].dpc,i, routine->routing[i].opc); + ls = &mtp3.ls[lsno]; + dst_num = ls->influ_dstnum_asNLS; + if ( dst_num < MAX_LS_DPC ) + { + ls->influ_dstplace_intable_asNLS[dst_num] = i; + ls->influ_dstnum_asNLS ++; + ls->links_nls_asp_ac_send_flag[i] = 0x00; + } + } + + lsno = routine->routing[i].alternative_ls; + if ( (lsno < MAX_LS) && + (routine->routing[i].normal_ls < MAX_LS) && + ((mtp3_para->ls_pro[lsno].nw_id) == nw_no) ) + { + if (!added) + Mtp3AddSortRec(nw_no,routine->routing[i].dpc,i, routine->routing[i].opc); + ls = &mtp3.ls[lsno]; + dst_num = ls->influ_dstnum_asALS; + if ( dst_num < MAX_LS_DPC ) + { + ls->influ_dstplace_intable_asALS[dst_num] = i; + ls->influ_dstnum_asALS ++; + ls->links_als_asp_ac_send_flag[i] = 0x00; + } + } + + added = 0; + } +} + +void update_ls_adjacent_sp_place(WORD ls)/*linkset adjacent sp's place in sp table */ +{ + BYTE lsnw;/* network that linkset belong to */ + long pc, opc; + int j; + + pc = mtp3_para->ls_pro[ls].ls_op_pc; + opc = mtp3_para->ls_pro[ls].ls_opc; + if ( pc != 0) + { + for (j=0; jls_pro[ls].nw_id); + if (mtp3_para->nw[lsnw].routing[j].dpc == pc && mtp3_para->nw[lsnw].routing[j].opc == opc) + { + mtp3.ls[ls].adjacent_sp_place = j; + return; + } + } + } +} + +void update_active_ls_num() +{ + int i; + + for (i=0; i 0) +// if ( linknum_in_ls[i] > 0 ) + { + active_ls_num ++; + } + else + { + mtp3_heartbeat.linkset_state[i/4] = mtp3_heartbeat.linkset_state[i/4] | (3<<((i%4)*2)); + } + } +} + +void update_timer(int link) +{ + lk_timer *lt; + +// mtp3_para->lt[i].t1 = 5;/* 800ms */ +// mtp3_para->lt[i].t2 = 8;/* 1280ms */ +// mtp3_para->lt[i].t3 = 5;/* 800ms */ +// mtp3_para->lt[i].t4 = 5;/* 800ms */ +// mtp3_para->lt[i].t5 = 5;/* 800ms */ +// mtp3_para->lt[i].t7 = 10;/* 1600ms */ +// mtp3_para->lt[i].t8 = 6;/* 960ms */ +// mtp3_para->lt[i].t12 = 7;/* 1120ms */ +// mtp3_para->lt[i].t13 = 7;/* 1120ms */ +// mtp3_para->lt[i].t14 = 15;/* 2400ms */ + + + lt = &mtp3_para->lt[link]; + if ( (lt->t1 > 7) || (lt->t1 < 4) ) + lt->t1 = 5; + if ( (lt->t2 > 7) || (lt->t2 < 5) ) + lt->t2 = 6; + if ( (lt->t3 > 7) || (lt->t3 < 4) ) + lt->t3 = 5; + if ( (lt->t4 > 7) || (lt->t4 < 4) ) + lt->t4 = 5; + if ( (lt->t5 > 7) || (lt->t5 < 4) ) + lt->t5 = 5; + if ( (lt->t7 > 12) || (lt->t7 < 6) ) + lt->t7 = 10; + if ( (lt->t8 > 7) || (lt->t8 < 5) ) + lt->t8 = 6; + if ( (lt->t12 > 10) || (lt->t12 < 5) ) + lt->t12 = 7; + if ( (lt->t13 > 10) || (lt->t13 < 5) ) + lt->t13 = 7; + if ( (lt->t14 > 19) || (lt->t14 < 12) ) + lt->t14 = 15; +} + +void init_mtp3table() +{ + int i; + + for (i=0; ilk[i].e1_to_mtp3,1);//addip + MTP3_LinkIP_List(mtp3_para->lk[i].e1_to_alterMTP3,1);//addip + } + for (i=0; imtp3_t10 = 126; //63;/* 40 SECOND, unit=640ms,for dpc */ + mtp3_para->mtp3_t18 = 40;//20; + mtp3_para->mtp3_t19 = 8;//4; + mtp3_para->mtp3_t20 = 8;//4; + mtp3_para->mtp3_t21 = 750; //375;/* 30 SECOND,unit=80ms, for linkset */ + mtp3ObjInput.tprc_input = TPRC_SP_RESTART_INDICATION; + own_sp_restarting = 1; + tprc_mgmt_signalling_point_restart_indication(); + mtp3_get_time(); + mtp3_set_csta_p(); + set_status(MTP3_COMPONENT_ID,MTP3_HB_LEN,(BYTE*)&mtp3_heartbeat.version); + get_routes_from_other_plat(); + mtp3_debug(MTP3DB_CMD,"MTP3 INIT COMPLETE(%08lx)",mtp3_localip); +} + +void reset_mtp3() +{ +// init_mtp3para(); + + mtp3lite_reset(); + i_sys(); + init_mtp3table(); + if(mtp3_alterip != 0)//take over altermtp3 + { + MTP3_activate(mtp3_alterip); + } +} + +void mtp3_reload_data() +{ + mtp3_readpara_from_disk(); +// recover_para(); + i_sys(); + init_mtp3table(); +} + +void mtp_shm_init(WORD moduleid_systemid, DWORD local_ip, DWORD peer_ip) +{ + printf("mtp3 start init\n"); + mtp_lgetlocalip(); + sccp_shm_init(); + tup_shm_init(); + isup_shm_init(); + bicc_shm_init(); + iptransInit_mtp3(); + init_mtp3para(); + mtp_debug_set(); + mtp_snmp_init(); + mtp3_reload_data(); + mtp3lite_init(); + mtp3_init_dynamic_opc(); + mtp2_module = moduleid_systemid>>8; + mtp2_systemid = moduleid_systemid & 0xff; + + mtp_local_ip = local_ip; + mtp_peer_ip = peer_ip; + + //mtp3_alterip = peer_ip; + printf("mtp3 complete init\n"); +} + +void mtp3_init_serial(char *Serial) +{ + mtp3_para->MTP3SerialNum = Str2Ull(Serial); +} + +int sccp_get_SPstate(mtp_primitive *ptr) +{ + BYTE RSub; + + RSub = S_primitive->RSub; + if (RSub != S_primitive->WSub) + { + memcpy(ptr,&S_primitive->primitive[RSub],sizeof (struct mtp_primitive)); + S_primitive->RSub = (RSub+1) & 0x0f; + return 1; + } + return 0; +} + +int isup_get_SPstate(mtp_primitive *ptr) +{ + BYTE RSub; + + RSub = I_primitive->RSub; + if (RSub != I_primitive->WSub) + { + memcpy(ptr,&I_primitive->primitive[RSub],sizeof (struct mtp_primitive)); + I_primitive->RSub = (RSub+1) & 0x0f; + return 1; + } + return 0; +} + +int bicc_get_SPstate(mtp_primitive *ptr) +{ + BYTE RSub; + + RSub = B_primitive->RSub; + if (RSub != B_primitive->WSub) + { + memcpy(ptr,&B_primitive->primitive[RSub],sizeof (struct mtp_primitive)); + B_primitive->RSub = (RSub+1) & 0x0f; + return 1; + } + return 0; +} + +int tup_get_SPstate(mtp_primitive *ptr) +{ + BYTE RSub; + + RSub = I_primitive->RSub; + if (RSub != I_primitive->WSub) + { + memcpy(ptr,&I_primitive->primitive[RSub],sizeof (struct mtp_primitive)); + I_primitive->RSub = (RSub+1) & 0x0f; + return 1; + } + return 0; +} + +int tup_GetMsg(up_message *msgptr) +{ + BYTE RSub; + + RSub = T_shm_ptr->MT_Buf.RSub; + if (RSub != T_shm_ptr->MT_Buf.WSub) + { + memcpy(msgptr,&T_shm_ptr->MT_Buf.msgNum[RSub],sizeof(up_message)); + + T_shm_ptr->MT_Buf.RSub++; + return 1; + } + return 0; +} + +int isup_GetMsg(up_message *msgptr) +{ + BYTE RSub; + + RSub = I_shm_ptr->MI_Buf.RSub; + if (RSub != I_shm_ptr->MI_Buf.WSub) + { + memcpy(msgptr,&I_shm_ptr->MI_Buf.msgNum[RSub],sizeof(up_message)); + + I_shm_ptr->MI_Buf.RSub++; + return 1; + } + return 0; +} + +int bicc_GetMsg(up_message_2 *msgptr) +{ + BYTE RSub; + + RSub = B_shm_ptr->MI_Buf.RSub; + if (RSub != B_shm_ptr->MI_Buf.WSub) + { + memcpy(msgptr,&B_shm_ptr->MI_Buf.msgNum[RSub],sizeof(up_message_2)); + + B_shm_ptr->MI_Buf.RSub++; + return 1; + } + return 0; +} + +int sccp_GetMsg(up_message *msgptr) +{ + BYTE RSub; + + RSub = S_shm_ptr->MS_Buf.RSub; + if (RSub != S_shm_ptr->MS_Buf.WSub) + { + memcpy(msgptr,&S_shm_ptr->MS_Buf.msgNum[RSub],sizeof(up_message)); + S_shm_ptr->MS_Buf.RSub++; + return 1; + } + return 0; +} + +int mtp3_perform_routing(up_message *msgptr,BYTE WriteSub) +{ + BYTE sls; + int returnValue; + BYTE sio; + + sio = msgptr->sio; + if (msgptr->dest_ip != 0xffffffff) + return 256;//??? + else + { + sls = msgptr->cic[0] & 0x0f; + returnValue = check_outbound_route((msgptr->sio>>6)&3,msgptr->dpc,sls, msgptr->opc);//??- + if (returnValue >= 0) + { + switch (sio & 7) + { + case 3: + routingResult.sccpMsgOutLink[WriteSub] = returnValue; + break; + case 4: + routingResult.tupMsgOutLink[WriteSub] = returnValue; + break; + case 5: + routingResult.isupMsgOutLink[WriteSub] = returnValue; + break; + case 13: + routingResult.biccMsgOutLink[WriteSub] = returnValue; + break; + } + } + else + { + mtp3_debug(MTP3DB_ERROR,"USER==>MTP3,SIO=%x,DPC=%lx,len=%d, OPC=%lx",msgptr->sio,msgptr->dpc,msgptr->len, msgptr->opc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + switch (returnValue) + { + case -1: + mtp3_debug(MTP3DB_ERROR,"Routing Failed,Reason:linkset unavailable"); + break; + case -2: + mtp3_debug(MTP3DB_ERROR,"Routing Failed,Reason:linkset not configured"); + break; + case -3: + mtp3_debug(MTP3DB_ERROR,"Routing Failed,Reason:dpc(dpc->linkset) not configured"); + break; + default: + break; + } + } + return returnValue; + } +} + +int mtp3_perform_routing_2(up_message_2 *msgptr,BYTE WriteSub) +{ + BYTE sls; + int returnValue; + BYTE sio; + + sio = msgptr->sio; + if (msgptr->dest_ip != 0xffffffff) + return 256;//??? + else + { + sls = msgptr->cic[0] & 0x0f; + returnValue = check_outbound_route((msgptr->sio>>6)&3,msgptr->dpc,sls, msgptr->opc);//??- + if (returnValue >= 0) + { + switch (sio & 15) + { + case 3: + routingResult.sccpMsgOutLink[WriteSub] = returnValue; + break; + case 4: + routingResult.tupMsgOutLink[WriteSub] = returnValue; + break; + case 5: + routingResult.isupMsgOutLink[WriteSub] = returnValue; + break; + case 13: + routingResult.biccMsgOutLink[WriteSub] = returnValue; + break; + } + } + else + { + mtp3_debug(MTP3DB_ERROR,"USER==>MTP3,SIO=%x,DPC=%lx,len=%d, OPC=%lx",msgptr->sio,msgptr->dpc,msgptr->len, msgptr->opc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + switch (returnValue) + { + case -1: + mtp3_debug(MTP3DB_ERROR,"Routing Failed,Reason:linkset unavailable"); + break; + case -2: + mtp3_debug(MTP3DB_ERROR,"Routing Failed,Reason:linkset not configured"); + break; + case -3: + mtp3_debug(MTP3DB_ERROR,"Routing Failed,Reason:dpc(dpc->linkset) not configured"); + break; + default: + break; + } + } + return returnValue; + } +} + +int sccp_to_mtp3(up_message *msgptr) +{ + BYTE ReadSub; + BYTE WriteSub; + BYTE nw; + int rtResult; + + nw = ((msgptr->sio) >> 6) & 3; + +// current_measure->tf_measure1[0][wx5[nw]+2]+=msgptr->len;/* octets */ + current_measure->tf_measure2[0][wx5[nw]+2]++;/* MSUs */ + + ReadSub = S_shm_ptr->SM_Buf.RSub; + WriteSub = S_shm_ptr->SM_Buf.WSub; + if(msgptr->dest_ip == 0 && msgptr->dpc == 0) + { + mtp3_debug(MTP3DB_ERROR,"receive message from SCCP,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:dst ip=0, dpc=0 "); + return -4; + } + if ( (WriteSub+1) == ReadSub)// buffer overflow + { + mtp3.nw[nw].flow.UtoM_throwed[2]++; + mtp3_debug(MTP3DB_ERROR,"receive message from UP,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:buffer overflow"); + return -4; + } + rtResult = mtp3_perform_routing(msgptr,WriteSub); + if (rtResult >= 0) + { + memcpy(&S_shm_ptr->SM_Buf.msgNum[WriteSub],msgptr,sizeof(struct up_message)); + S_shm_ptr->SM_Buf.WSub++; + mtp3.nw[nw].flow.UtoM[2]++; + } + else + { +// current_measure->tf_measure1[5][wx5[nw]+2]+=len;/* octets */ + current_measure->tf_measure2[5][wx5[nw]+2]++;/* MSUs */ + } + return rtResult; +} + +int tup_to_mtp3(up_message *msgptr) +{ + BYTE ReadSub; + BYTE WriteSub; + BYTE nw; + int rtResult; + + nw = ((msgptr->sio) >> 6) & 3; + ReadSub = T_shm_ptr->TM_Buf.RSub; + WriteSub = T_shm_ptr->TM_Buf.WSub; + +// current_measure->tf_measure1[0][wx5[nw]+3]+=msgptr->len;/* octets */ + current_measure->tf_measure2[0][wx5[nw]+3]++;/* MSUs */ + if(msgptr->dest_ip == 0 && msgptr->dpc == 0) + { + mtp3_debug(MTP3DB_ERROR,"receive message from TUP,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:dst ip=0, dpc=0 "); + return -4; + } + if ( (WriteSub+1) == ReadSub)// buffer overflow + { + mtp3.nw[nw].flow.UtoM_throwed[3]++; + mtp3_debug(MTP3DB_ERROR,"receive message from UP,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:buffer overflow"); + return -4; + } + rtResult = mtp3_perform_routing(msgptr,WriteSub); + if (rtResult >= 0) + { + memcpy(&T_shm_ptr->TM_Buf.msgNum[WriteSub],msgptr,sizeof(struct up_message)); + T_shm_ptr->TM_Buf.WSub++; + mtp3.nw[nw].flow.UtoM[3]++; + } + else + { +// current_measure->tf_measure1[5][wx5[nw]+3]+=len;/* octets */ + current_measure->tf_measure2[5][wx5[nw]+3]++;/* MSUs */ + } + return rtResult; +} + +int isup_to_mtp3(up_message *msgptr) +{ + BYTE ReadSub; + BYTE WriteSub; + BYTE nw; + int rtResult; + + nw = ((msgptr->sio) >> 6) & 3; + +// current_measure->tf_measure1[0][wx5[nw]+4]+=msgptr->len;/* octets */ + current_measure->tf_measure2[0][wx5[nw]+4]++;/* MSUs */ + if(msgptr->dest_ip == 0 && msgptr->dpc == 0) + { + mtp3_debug(MTP3DB_ERROR,"receive message from ISUP,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:dst ip=0, dpc=0 "); + return -4; + } + ReadSub = I_shm_ptr->IM_Buf.RSub; + WriteSub = I_shm_ptr->IM_Buf.WSub; + if ( (WriteSub+1) == ReadSub)// buffer overflow + { + mtp3.nw[nw].flow.UtoM_throwed[4]++; + mtp3_debug(MTP3DB_ERROR,"receive message from UP,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:buffer overflow"); + return -4; + } + rtResult = mtp3_perform_routing(msgptr,WriteSub); + if (rtResult >= 0) + { + memcpy(&I_shm_ptr->IM_Buf.msgNum[WriteSub],msgptr,sizeof(struct up_message)); + I_shm_ptr->IM_Buf.WSub++; + mtp3.nw[nw].flow.UtoM[4]++; + } + else + { +// current_measure->tf_measure1[5][wx5[nw]+4]+=len;/* octets */ + current_measure->tf_measure2[5][wx5[nw]+4]++;/* MSUs */ + } + return rtResult; +} + +int bicc_to_mtp3(up_message_2 *msgptr) +{ + BYTE ReadSub; + BYTE WriteSub; + BYTE nw; + int rtResult; + + nw = ((msgptr->sio) >> 6) & 3; + +// current_measure->tf_measure1[0][wx5[nw]+4]+=msgptr->len;/* octets */ + current_measure->tf_measure2[0][wx5[nw]+4]++;/* MSUs */ + + ReadSub = B_shm_ptr->IM_Buf.RSub; + WriteSub = B_shm_ptr->IM_Buf.WSub; + if(msgptr->dest_ip == 0 && msgptr->dpc == 0) + { + mtp3_debug(MTP3DB_ERROR,"receive message from BICC,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:dst ip=0, dpc=0 "); + return -4; + } + if ( (WriteSub+1) == ReadSub)// buffer overflow + { + mtp3.nw[nw].flow.UtoM_throwed[4]++; + mtp3_debug(MTP3DB_ERROR,"receive message from UP,sio=%x,dpc=%lx",msgptr->sio,msgptr->dpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr->msgList,msgptr->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:buffer overflow"); + return -4; + } + rtResult = mtp3_perform_routing_2(msgptr,WriteSub); + if (rtResult >= 0) + { + memcpy(&B_shm_ptr->IM_Buf.msgNum[WriteSub],msgptr,sizeof(struct up_message_2)); + B_shm_ptr->IM_Buf.WSub++; + mtp3.nw[nw].flow.UtoM[4]++; + } + else + { +// current_measure->tf_measure1[5][wx5[nw]+4]+=len;/* octets */ + current_measure->tf_measure2[5][wx5[nw]+4]++;/* MSUs */ + } + return rtResult; +} + +void scan_lk_state() +{ + static WORD lk=0; + + if (mtp3ObjState.lk_configured[lk] != PARA_CONFIGURED) + { + lk = (lk+1)%MAX_LK; + return; + } + if (mtp3ObjState.link_l3_state[lk] != AVAILABLE) + { + current_measure->lk_measure1[lk][3]++;//Duration of SL unavailability(for any reason + } + else if (mtp3ObjState.link_l3_state[lk] == UNAVAILABLE) + current_measure->lk_measure1[lk][6]++;//Duration of SL unavailability due to link fai + if (mtp3ObjState.link_l3_state[lk] == INHIBITED) + { + if (link_locally_inhibited[lk] == TRUE) + { + current_measure->lk_measure1[lk][4]++;//Duration of SL inhibition due to local management actions + } + else + current_measure->lk_measure1[lk][5]++;//Duration of SL inhibition due to remote management actions + } + + if (mtp3_para->lk[lk].e1_to_mtp3 == mtp3_localip) + {//this mtp3 is the normal mtp3 of this link + if (mtp3ObjState.lk_AMTP3_ok[lk] & 15)//Alternative MTP3 available + { +// mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_alterMTP3; + //do nothing, waiting for alternative unavailable + } + else if (mtp3ObjState.lk_NMTP3_ok[lk] >> 4)//if Alternative MTP3 not avilable and normal mtp3 is activated + { + mtp3_debug(MTP3DB_EVENT,"link %d host MTP3 change from backup to normal",lk); + mtp3ObjState.lk_NMTP3_ok[lk] &= 0x0f; + if (mtp3ObjState.lk_mtp3[lk] == mtp3_para->lk[lk].e1_to_alterMTP3) + { + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + if (mtp3ObjState.link_l3_state[lk] == AVAILABLE) + otherMTP3_managed_link_unavailable(lk); + } + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + else//other case normal is always the host + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + else if (mtp3_para->lk[lk].e1_to_alterMTP3 == mtp3_localip) + {//this mtp3 is the alternative mtp3 of this link + if (mtp3ObjState.lk_mtp3[lk] == mtp3_localip)//it is the current host + { + if ((mtp3ObjState.lk_AMTP3_ok[lk]>>4)==2)//only the deactivate command can make it abandon host + { + mtp3_debug(MTP3DB_EVENT,"link %d host MTP3 change back to normal",lk); + mtp3ObjState.lk_AMTP3_ok[lk] &= 0x0f; + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + +/* disable the link */ + mtp3_debug(MTP3DB_EVENT,"link %d L2 out of service (changing back to normal MTP3)",lk); + mtp3ObjInput.lsac_input_from_l2[lk] = LSAC_L2_OUT_OF_SERVICE; + mtp3ObjInput.sltc_input[lk] = SLTC_STOP; + sltc_proc(lk); + + /* send stop command to mtp2 */ + if (MTP3_LINK_TYPE(lk) == LKTYPE_SIGTRAN)//m2ua link + { + send_command_to_mtp2(lk,MTP2_DEACTIVE_LINK); + send_command_to_mtp2(lk,MTP3_M2UA_DISABLE); + } + else + send_command_to_mtp2(lk,MTP2_STOP_L2); + //mtp3_send_alarm(MTP3_LINK_COMPONENT+lk,MTP3ALARM_LINK_CB_TO_NMTP3); + } + } + else + { + if (mtp3ObjState.lk_NMTP3_ok[lk] & 15) + {//normal ok + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + + else if ((mtp3ObjState.lk_AMTP3_ok[lk]>>4)==1)//if normal MTP3 not avilable and alternative mtp3 is activated + { + mtp3_debug(MTP3DB_EVENT,"link %d host MTP3 change to alternative",lk); + mtp3ObjState.lk_AMTP3_ok[lk] &= 0x0f; + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_alterMTP3; + + } + } + } + + else + { + if (mtp3ObjState.lk_AMTP3_ok[lk] & 15) + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_alterMTP3; + + else if (mtp3ObjState.lk_NMTP3_ok[lk] & 15) + mtp3ObjState.lk_mtp3[lk] = mtp3_para->lk[lk].e1_to_mtp3; + } + +/* + if (mtp3ObjState.lk_mtp3[lk]==mtp3_localip) + { + mtp3_heartbeat.masterMTP3[lk/8] |= (1<<(lk&7)); + } + else + mtp3_heartbeat.masterMTP3[lk/8] &= (~(1<<(lk&7))); +*/ + lk = lk+1; + + if (lk==MAX_LK_INDEX) + { + set_status(MTP3_COMPONENT_ID,MTP3_HB_LEN,(BYTE*)&mtp3_heartbeat.version); + lk = 0; + } +} + + +void scan_ls_state() +{ + BYTE nw; + WORD adsp_place; + static WORD ls=0; + + adsp_place = mtp3.ls[ls].adjacent_sp_place; + if (adsp_place > MAX_ROUTE) + { + ls = (ls + 1) & 0x1FF; + return; + } + nw = mtp3_para->ls_pro[ls].nw_id; + if (mtp3.ls[ls].adjacentsp_acessible != TRUE) + { + current_measure->ls_measure[ls][6]++;/* duration_of_adjacent_sp_inaccessible */; + } + if ( (mtp3.ls[ls].links_available == 0) && + (mtp3.ls[ls].linksNum_configured) ) +// (linknum_in_ls[ls] > 0) ) + { + current_measure->ls_measure[ls][0]++;/* duration_of_unavailability */ + } + ls = (ls + 1) & 0x1FF; +} + +void scan_mtp2_activity()// check mtp2 exist or not +{ + int i,j; + int tmp; + int chl; + static BYTE mtp_t20s=0; + + mtp_t20s++; + if (mtp_t20s == 3) + { + mtp_t20s = 0; + for (i=0; i<32; i++)//??? 8ke1 + { + if ( (mtp2_flag_old[i] != mtp2_flag_new[i]) && + (mtp2_flag_new[i] == IDLE) ) + { + tmp = i << 3; + for (j=0; j<8; j++) + { + chl = tmp+j; + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + { + mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_OUT_OF_SERVICE; + mtp3ObjState.link_l2_state[chl] = MTP2_STATE_IDLE; + nld_cause_lkd[chl] ++;/* internet cable disconnect cause lk disconnect */ + mtp3ObjInput.sltc_input[chl] = SLTC_STOP; + sltc_proc(chl); + } + } + } + mtp2_flag_old[i] = mtp2_flag_new[i]; + mtp2_flag_new[i] = IDLE; + } + } +} + +int sys_mtp3_table(ulong ip); +void scan_mtp3_activity()// check other mtp3 can use or not +{ + int chl; + static BYTE mtp3ip=0; +/* WORD lsno; + ls_info *ls=NULL;*/ + + mtp3ip=(mtp3ip+1) % 127; + + if (mtp3ip >= MAX_MTP3_NUM) + return; + + if ( (MTP3IPMng.mtp3_flag_old[mtp3ip] != MTP3IPMng.mtp3_flag_new[mtp3ip]) && + (MTP3IPMng.mtp3_flag_new[mtp3ip] == IDLE) && + (MTP3IPMng.mtp3_flag_ip[mtp3ip] != mtp3_localip) ) + { + for (chl=0; chllk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno]; + ls->links_available--;*/ + mtp3_debug(MTP3DB_EVENT,"link %d MTP3 %08lx timeout",chl,mtp3ObjState.lk_mtp3[chl]); + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_UNAVAILABLE; + tsrc_proc(chl); + hmrt_tcoc_update_routing_tables(chl); + mtp3ObjState.tlac_state[chl] = TLAC_UNAVAILABLE_STATE; + } + + if (mtp3_para->lk[chl].e1_to_mtp3 == MTP3IPMng.mtp3_flag_ip[mtp3ip]) + mtp3ObjState.lk_NMTP3_ok[chl] = 0; + else if (mtp3_para->lk[chl].e1_to_alterMTP3 == MTP3IPMng.mtp3_flag_ip[mtp3ip]) + mtp3ObjState.lk_AMTP3_ok[chl] = 0; + + } + } + MTP3IPMng.mtp3_flag_old[mtp3ip] = MTP3IPMng.mtp3_flag_new[mtp3ip]; + MTP3IPMng.mtp3_flag_new[mtp3ip] = IDLE; +} + +void mtp3_proc() +{ + up_message getmsg; + up_message_2 getmsg_2; + up_message *msgptr = (up_message*)&getmsg; + up_message_2 *msgptr_2 = (up_message_2*)&getmsg_2; + WORD i; + WORD temp; +// BYTE ib_b; +// unsigned short addr; + static WORD sltc_loop=0; + static WORD dst_loop=0; + static BYTE mtp_t1s=0; + static BYTE mtp_t10s=0; + static BYTE mtp_10ms_tick=0; + static BYTE mtp_100ms_tick=0; + +// addr = 0x378; +// ib_b = inb(addr); +// outb(ib_b | 2,addr); + + mtp3DebugFull = 0; + + for (i = 0; i<128; i++) + { + GetMtp2Msg(SS7_PORT);// get mtp2 message by port 4950 + GetMtp2Msg(M2UA_PORT);// get m2ua message + GetM3uaMsg(M2UA_PORT);// get m3ua message + get_isup(msgptr);// check isup buffer message + get_bicc(msgptr_2);// check bicc buffer message + get_tup(msgptr);// check tup buffer message + get_sccp(msgptr);// check sccp buffer message + } + + mtp3lite_timer(); + m3ua_timer(); +/* Q.704 state machine */ +// for (i=0; i<16; i++) + for (i=0; i<64; i++) + { + temp = dst_loop + i; + if (MTP3_LINK_TYPE(temp) == LKTYPE_MTP3_LITE ||MTP3_LINK_TYPE(temp) == LKTYPE_M3UA) + continue; + lsac_proc(temp); + tlac_proc(temp); + tsrc_proc(temp); + tcoc_proc(temp); + tcbc_proc(temp); + rtpc_proc(srm_nw,temp); + rtac_proc(srm_nw,temp); + rsrt_proc(srm_nw,temp); + mtp3Timer_proc(temp); + taprc_proc(temp); + } + //dst_loop = dst_loop + 16; + dst_loop = dst_loop + 64; + if (dst_loop >= MAX_LK) + { + srm_nw = (srm_nw + 1) & 3; + dst_loop = 0; + } + for(i=0;i<4; i++) + { + if (MTP3_LINK_TYPE(sltc_loop) != LKTYPE_MTP3_LITE && MTP3_LINK_TYPE(sltc_loop) != LKTYPE_M3UA) + sltc_proc(sltc_loop); + sltc_loop++; + if (sltc_loop >= MAX_LK) + sltc_loop = 0; + } +/* Q.704 state machine */ + + for (i=0;i<4;i++) + { + scan_conf_right_or_not(i); + } + + switch (mtp_10ms_tick)/* every 160ms loop one times */ + { + case 0:/* 10ms */ + break; + case 1:/* 20ms */ + break; + case 2:/* 30ms */ + scan_lk_state(); + break; + case 3:/* 40ms */ + break; + case 4:/* 50ms */ + break; + case 5:/* 60ms */ + break; + case 6:/* 70ms */ + scan_lk_state(); + break; + case 7:/* 80ms */ + scan_ls_state(); + break; + case 8:/* 90ms */ + break; + case 9:/* 100ms */ + mtp_m_rt(); + break; + case 10:/* 110ms */ + scan_lk_state(); + break; + case 11:/* 120ms */ + break; + case 12:/* 130ms */ + break; + case 13:/* 140ms */ + scan_mtp3_activity(); + break; + case 14:/* 150ms */ + scan_lk_state(); + break; + case 15:/* 160ms */ + scan_ls_state(); + break; + default: + break; + } + mtp_10ms_tick = ((mtp_10ms_tick+1) & 15); + + if (mtp_100ms_tick == 9) + { + mtp_100ms_tick = 0; + mtp_t1s++; + if (mtp_t1s == 10)/* 1 second */ + { + mtp_t1s = 0; + tprc_proc(); + mtp_t10s++; + send_ip_to_mtp2(); + send_ip_to_mtp2(); + if (mtp_t10s == 10)/* 10 second */ + { + mtp3_heartbeat.state = 1; + set_status(MTP3_COMPONENT_ID,MTP3_HB_LEN,(BYTE*)&mtp3_heartbeat.version); + mtp3_get_time();// get current time + mtp3_set_csta_p();// set csta portion + scan_mtp2_activity(); + mtp_t10s = 0; + get_routes_from_other_plat(); + if (mtp3lite_listen_fd <= 0) + mtp3lite_InitServerSocket(); + if(checkMtp3SaveFlag()==1) + { + mtp3_write_para(); + mtp3DisableSaveFlag(); + } + } + } + } + mtp_100ms_tick ++; + +// outb(ib_b & 0xfd,addr); +} + +//These functions is added by Roy Jiang for supporting SCCP dual server redirect +int sccp_redirect(up_message *msgptr) +{ +// BYTE len; + WORD len;//long message + BYTE sio; + long route_mark;/* dpc opc sls */ + BYTE sls; + long dpc; + long opc; + BYTE pclen; + int outlink=0; + long dest_ip; + BYTE *pContent; + BYTE nw; + + assert (msgptr->dest_ip != 0xffffffff); + sio = msgptr->sio & 0xcf; + dpc = msgptr->dpc; + opc = msgptr->opc; + sls = msgptr->cic[0] & 0x0f; + nw = (sio >> 6) & 3; + pclen = pc_length(nw); + len = msgptr->len; + dest_ip = msgptr->dest_ip; + outlink = msgptr->link; + + pContent = &mtp3_iprt.io_msg.msgContent[0]; + len = msgptr->len; + if (pclen == MTP3_24BIT_PC) + { + mtp3_iprt.io_msg.msgLength = len + 10 + 1 + 1; + pContent[1] = outlink>>8; + pContent[0] = outlink&0xff; + pContent[2] = (len+8)>>8; + pContent[3] = (len+8)&0xff; + pContent[4] = sio; + memcpy(&pContent[5],&dpc,3); + memcpy(&pContent[8],&opc,3); + memcpy(&pContent[11],&msgptr->cic[0],1); + memcpy(&pContent[12],&msgptr->msgList,len); + } + else + { + route_mark = (msgptr->cic[0] << 28)+(opc << 14)+dpc; + pContent[1] = outlink>>8; + pContent[0] = outlink&0xff; + pContent[2] = (len+5)>>8; + pContent[3] = (len+5)&0xff; + pContent[4] = sio; + memcpy(&pContent[5],&route_mark,4); + memcpy(&pContent[9],&msgptr->msgList,len); + } + len = (pContent[2]<<8) +pContent[3]; + if (len < 5 || len >MAX_SS7_MSG_LEN) + { + mtp3ObjState.MTP3WatchDog[10]++; + mtp3_debug(MTP3DB_ERROR,"[SCCP]USER==>MTP3,LI over range and discarded! LI=%04d,Link=%d",len,outlink); + mtp3_showbuf(MTP3DB_ERROR,&pContent[0],len + 3); + S_shm_ptr->SM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[2]++; + return 0; + } + + mtp3.nw[nw].flow.MtoI[2]++; + + mtp3_iprt.io_msg.msgLength = len+2+1; + iptrans_msg_flow(pContent,pclen,MTP_MSG_OTHER_SERVER,dest_ip); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + return 1; +} + +int isup_redirect(up_message *msgptr) +{ + int outlink=0; + WORD len; + BYTE sio; + long route_mark; + long dpc; + BYTE sls; + BYTE pclen; + BYTE nw; + ulong dest_ip; +// BYTE rSub; + BYTE *pContent; + + assert (msgptr->dest_ip != 0xffffffff); + sio = msgptr->sio & 0xcf; + dpc = msgptr->dpc; + sls = msgptr->cic[0] & 0x0f; + nw = (sio >> 6) & 3; + pclen = pc_length(nw); + len = msgptr->len; + outlink = msgptr->link; + dest_ip = msgptr->dest_ip; + + pContent = &mtp3_iprt.io_msg.msgContent[0]; + if (pclen == MTP3_24BIT_PC) + { + pContent[1] = outlink>>8; + pContent[0] = outlink&0xff; + pContent[2] = (len + 10)>>8; + pContent[3] = (len + 10)&0xff; + pContent[4] = sio; + memcpy(&pContent[5],&dpc,3); + memcpy(&pContent[8],&msgptr->opc,3);//keep the UP filled opc + pContent[11] = msgptr->cic[0] & 0x0f; + memcpy(&pContent[12],&msgptr->cic[0],2); + memcpy(&pContent[14],&msgptr->msgList,len); + MTP3_send_isup_count(nw,pContent[14]); + } + else + { + route_mark = (msgptr->cic[0] << 28)+(msgptr->opc << 14)+dpc;//keep the UP filled opc + pContent[1] = outlink>>8; + pContent[0] = outlink&0xff; + pContent[2] = (len+7)>>8; + pContent[3] = (len+7)&0xff; + pContent[4] = sio; + memcpy(&pContent[5],&route_mark,4); + memcpy(&pContent[9],&msgptr->cic,2); + memcpy(&pContent[11],&msgptr->msgList,len); + MTP3_send_isup_count(nw,pContent[11]); + } + + len = (pContent[2]<<8) + pContent[3]; + if (len < 5 || len > MAX_SS7_MSG_LEN) + { + mtp3ObjState.MTP3WatchDog[14]++; + mtp3_debug(MTP3DB_ERROR,"[ISUP]USER==>MTP3,LI over range and discarded! LI=%04d,Link=%d",len,outlink); + mtp3_showbuf(MTP3DB_ERROR,&pContent[0],len + 3); + I_shm_ptr->IM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[4]++; + return 0; + } + + mtp3.nw[nw].flow.MtoI[4]++; + + mtp3_iprt.io_msg.msgLength = pContent[3]+2+1; + iptrans_msg_flow(pContent,pclen,MTP_MSG_OTHER_SERVER,dest_ip); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + return 1; +} + +int bicc_redirect(up_message_2 *msgptr) +{ + int outlink=0; + WORD len; + BYTE sio; + long route_mark; + long dpc; + BYTE sls; + BYTE pclen; + BYTE *pContent; + BYTE nw; + ulong dest_ip; +// BYTE rSub; + + assert(msgptr->dest_ip != 0xffffffff); + sio = msgptr->sio; + dpc = msgptr->dpc; + sls = msgptr->cic[0] & 0x0f; + nw = (sio >> 6) & 3; + pclen = pc_length(nw); + len = msgptr->len; + dest_ip = msgptr->dest_ip; + outlink = msgptr->link; + + pContent = &mtp3_iprt.io_msg.msgContent[0]; + if (pclen == MTP3_24BIT_PC) + { + pContent[1] = outlink>>8; + pContent[0] = outlink&0xff; + pContent[2] = (len + 12)>>8; + pContent[3] = (len + 12)&0xff; + pContent[4] = sio; + memcpy(&pContent[5],&dpc,3); + memcpy(&pContent[8],&msgptr->opc,3);//keep the UP filled opc + pContent[11] = msgptr->cic[0] & 0x0f; + memcpy(&pContent[12],&msgptr->cic[0],4); + memcpy(&pContent[16],&msgptr->msgList,len); + } + else + { + route_mark = (msgptr->cic[0] << 28)+(msgptr->opc << 14)+dpc;//keep the UP filled opc + pContent[1] = outlink>>8; + pContent[0] = outlink&0xff; + pContent[2] = (len+9)>>8; + pContent[3] = (len+9)&0xff; + pContent[4] = sio; + memcpy(&pContent[5],&route_mark,4); + memcpy(&pContent[9],&msgptr->cic,4); + memcpy(&pContent[13],&msgptr->msgList,len); + } + mtp3.nw[nw].flow.MtoI[4]++; + mtp3_iprt.io_msg.msgLength = pContent[3]+2+1; + iptrans_msg_flow(pContent,pclen,MTP_MSG_OTHER_SERVER,dest_ip); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + return 1; +} +/*@end@*/ diff --git a/plat/mtp3/src/mtpm.c b/plat/mtp3/src/mtpm.c new file mode 100644 index 0000000..f66314d --- /dev/null +++ b/plat/mtp3/src/mtpm.c @@ -0,0 +1,2502 @@ +#include "../../debug/src/include/debug.h" +#include "./include/mtp3.h" +#include "./include/mtpstm.h" +#include "./include/mtpext.h" +extern void mtp3_debug(int n,const char *fmt,...); +/*@ignore@*/ +int mtp3_send_netcap=0; + +void reset_mtp3(); +long atol(const char *nptr); +//int gettimeofday(struct timeval *tv,struct timezone *tz); +struct tm *localtime(const time_t *timep); +void mtp3_list_link(WORD i); + +static char ascii[16] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39, + 0x41,0x42,0x43,0x44,0x45,0x46}; +extern BOOL mtp3DebugFull; + +BYTE disp_flag; +BYTE disp_page[16]; + +static BYTE * disp_ptr; +static BYTE disp_length; + +static DWORD debug_mask=0; +void mtp3_show_routine_status(BYTE nw); +void mtp3_show_routine_status_sorted(BYTE nw); +void mtp3_list_log_status(); +void mtp3_reload_data(); +int mtp3_write_parameter(); +int mtp3_write_para(); + +static BYTE title1_p[] = +{ + " PAGE01 MTP3 Measure-TRAFFIC sub-page0:flow, sub-page1:throwed \n\r\ + [---SNM---] [---T+M---] [--SCCP---] [---TUP---] [--ISUP---]\n\r\ +--Page--\n\r\ + U (nw0)\n\r\ + t (nw1)\n\r\ + o (nw2)\n\r\ + M (nw3)\n\r\ + M (nw0)\n\r\ + t (nw1) E\n\r\ + o (nw2) 1\n\r\ + I (nw3)\n\r\ + I (nw0)\n\r\ + t (nw1)\n\r\ + o (nw2)\n\r\ + M (nw3)\n\r\ + M (nw0)\n\r\ + t (nw1)\n\r\ + o (nw2)\n\r\ + U (nw3)\n\r\ + M (nw0)\n\r\ + S (nw1)\n\r\ + T (nw2)\n\r\ + P (nw3)\n\r\ +" +}; + +static BYTE title2_p[] = +{ + " PAGE02 link mark \n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +--Page--\n\r\ +link_available\n\r\ +link_unavailable\n\r\ +failed\n\r\ +CB_in_progress\n\r\ +CO_in_progress\n\r\ +link_inhibited\n\r\ +locally_inhibited\n\r\ +remotely_inhibited\n\r\ +localInhibit_inPro\n\r\ +uninhibit_in_pro\n\r\ +local_blocked\n\r\ +remote_blocked\n\r\ +local_change_over\n\r\ +" +}; + +static BYTE title3_p[] = +{ + " PAGE03 MTP2 MTP3 flag \n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ + Page\n\r\ + mtp2 flag(old)\n\r\ + \n\r\ + mtp2 flag(new)\n\r\ + \n\r\ + \n\r\ + page\n\r\ + 0:mtp3 ip\n\r\ + 1:mtp3 flag old\n\r\ + 2:mtp3 flag new\n\r\ + 3:lk_configured\n\r\ +" +}; + +static BYTE title4_p[] = +{ + " PAGE09 MTP3 STATE MACHINE'S INPUT \n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +--Page--\n\r\ +LSAC L2\n\r\ +LSAC SLTC\n\r\ +LSAC SLM\n\r\ +LSAC STM\n\r\ +LSAC TCOC\n\r\ +LSAC MGMT\n\r\ +TLAC SLM\n\r\ +TLAC STM\n\r\ +TLAC HMDT\n\r\ +TSRC STM\n\r\ +TSRC TLAC\n\r\ +TSRC TCOC\n\r\ +TSRC TCBC\n\r\ +TSRC SRM\n\r\ +TCOC L2\n\r\ +TCOC STM\n\r\ +TCOC TSRC\n\r\ +TCOC HMDT\n\r\ +TCBC\n\r\ +TCBC_TSRC\n\r\ +T(A)PRC\n\r\ +" +}; + +static BYTE title5_p[] = +{ + " PAGE05 MTP3 Port state(16 port per sub page)\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +subPage\r\n\ +L1\r\n\ +L2\r\n\ +L3\r\n\ +lsac\r\n\ +sltc\r\n\ +tlac\r\n\ +tsrc\r\n\ +tcoc\r\n\ +tcbc\r\n\ +rtpc[nw0]\r\n\ +rtpc[nw1]\r\n\ +rtpc[nw2]\r\n\ +rtpc[nw3]\r\n\ +rtac[nw0]\r\n\ +rtac[nw1]\r\n\ +rtac[nw2]\r\n\ +rtac[nw3]\r\n\ +tprc" +}; + +static BYTE title6_p[] = +{ + " PAGE06 MTP3 ROUTINE TABLE(4) \n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +--PAGE--\n\r\ +0~3 INTERNATIONAL\n\r\ +4~7 INTERNATIONAL(S)\n\r\ +8~11 NATIONAL\n\r\ +12~15 NATIONAL(S)\n\r\ +\n\r\ +\n\r\ +value=\n\r\ +18:route:normal ls\n\r\ + nls:available\n\r\ + als:unavailable\n\r\ +10:route:normal ls\n\r\ + nls:available\n\r\ + als:available\n\r\ +52:route=alter ls\n\r\ + nls:unavailable\n\r\ + als:available\n\r\ +8A:no route\n\r\ +other:problem bug\n\r\ +" +}; + +static BYTE title7_p[] = +{ + " PAGE07 MTP3 LINKSET SLS TABLE \n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +--PAGE--\n\r\ +(16*page+00)ls\n\r\ +(16*page+01)ls\n\r\ +(16*page+02)ls\n\r\ +(16*page+03)ls\n\r\ +(16*page+04)ls\n\r\ +(16*page+05)ls\n\r\ +(16*page+06)ls\n\r\ +(16*page+07)ls\n\r\ +(16*page+08)ls\n\r\ +(16*page+09)ls\n\r\ +(16*page+10)ls\n\r\ +(16*page+11)ls\n\r\ +(16*page+12)ls\n\r\ +(16*page+13)ls\n\r\ +(16*page+14)ls\n\r\ +(16*page+15)ls\n\r\ +" +}; + +static BYTE title8_p[] = +{ + " PAGE08 MTP3 Version 1.0 linkset State \n\r\ + avail mark place cf influence dst number\n\r\ +--Page--\n\r\ +(16*page+00)ls\n\r\ +(16*page+01)ls\n\r\ +(16*page+02)ls\n\r\ +(16*page+03)ls\n\r\ +(16*page+04)ls\n\r\ +(16*page+05)ls\n\r\ +(16*page+06)ls\n\r\ +(16*page+07)ls\n\r\ +(16*page+08)ls\n\r\ +(16*page+09)ls\n\r\ +(16*page+10)ls\n\r\ +(16*page+11)ls\n\r\ +(16*page+12)ls\n\r\ +(16*page+13)ls\n\r\ +(16*page+14)ls\n\r\ +(16*page+15)ls\n\r\ +" +}; + +static BYTE title9_p[] = +{ + " PAGE9 MTP3 ls influence dst\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +--page--\n\r\ +page0-page127\n\r\ +ls0 -ls127\n\r\ +[NLS]\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +[ALS]\n\r\ +" +}; + +static BYTE title10_p[] = +{ + " PAGE10 MTP3 isup sd/rv count\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +--page--\n\r\ +RvISUP\n\r\ +\n\r\ +\n\r\ +\n\r\ +SdISUP\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +" +}; + +static BYTE title11_p[] = +{ + " PAGE11 MTP3 watch dog\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +Dog\n\r\ +" +}; + +void mtpi_m() +{ + memset(disp_page,0,16); +} + +BYTE mtp_disp_line(BYTE page, BYTE line)//return display length,disp data ptr per line +{ + BYTE disp_length; + BYTE subpage; + + disp_length = 16; + + page = page & 15; + disp_page[page] = disp_page[page] %64; + subpage = disp_page[page]; + + switch(page) + { + case 1: + if (subpage == 0) + { + disp_length = 20; + switch (line) + { + case 0: + disp_ptr = &disp_page[page]; + disp_length = 1; + break; + case 1: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.UtoM; + break; + case 2: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.UtoM; + break; + case 3: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.UtoM; + break; + case 4: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.UtoM; + break; + case 5: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.MtoI; + break; + case 6: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.MtoI; + break; + case 7: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.MtoI; + break; + case 8: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.MtoI; + break; + case 9: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.ItoM; + break; + case 10: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.ItoM; + break; + case 11: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.ItoM; + break; + case 12: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.ItoM; + break; + case 13: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.MtoU; + break; + case 14: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.MtoU; + break; + case 15: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.MtoU; + break; + case 16: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.MtoU; + break; + case 17: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.stp; + break; + case 18: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.stp; + break; + case 19: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.stp; + break; + case 20: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.stp; + break; + default: + disp_length = 0; + break; + } + } + else if (subpage == 1) + { + disp_length = 20; + switch (line) + { + case 0: + disp_ptr = &disp_page[page]; + disp_length = 1; + break; + case 1: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.UtoM_throwed; + break; + case 2: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.UtoM_throwed; + break; + case 3: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.UtoM_throwed; + break; + case 4: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.UtoM_throwed; + break; + case 5: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.MtoI_throwed; + break; + case 6: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.MtoI_throwed; + break; + case 7: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.MtoI_throwed; + break; + case 8: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.MtoI_throwed; + break; + case 9: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.ItoM_throwed; + break; + case 10: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.ItoM_throwed; + break; + case 11: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.ItoM_throwed; + break; + case 12: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.ItoM_throwed; + break; + case 13: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.MtoU_throwed; + break; + case 14: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.MtoU_throwed; + break; + case 15: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.MtoU_throwed; + break; + case 16: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.MtoU_throwed; + break; + case 17: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.stp_throwed; + break; + case 18: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.stp_throwed; + break; + case 19: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.stp_throwed; + break; + case 20: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.stp_throwed; + break; + default: + disp_length = 0; + break; + } + } + else if (subpage == 2) + { + disp_length = 20; + switch (line) + { + case 0: + disp_ptr = &disp_page[page]; + disp_length = 1; + break; + case 1: + disp_ptr = (BYTE*)&mtp3.nw[0].flow.stp_loop; + break; + case 2: + disp_ptr = (BYTE*)&mtp3.nw[1].flow.stp_loop; + break; + case 3: + disp_ptr = (BYTE*)&mtp3.nw[2].flow.stp_loop; + break; + case 4: + disp_ptr = (BYTE*)&mtp3.nw[3].flow.stp_loop; + break; + default: + disp_length = 0; + break; + } + } + else + disp_length = 0; + break; + case 2: + if (subpage >= 64) + return 0; + switch (line) + { + case 0: + disp_ptr = &disp_page[page]; + disp_length = 1; + break; + case 1: + disp_ptr = link_available + subpage*16; + break; + case 2: +/* disp_ptr = link_unavailable + subpage*16;*/ + break; + case 3: + disp_ptr = failed + subpage*16; + break; + case 4:/* l3 */ + disp_ptr = changeback_in_progress + subpage*16; + break; + case 5:/* l2 */ + disp_ptr = changeover_in_progress + subpage*16; + break; + case 6: + disp_ptr = link_inhibited + subpage*16; + break; + case 7: + disp_ptr = link_locally_inhibited + subpage*16; + break; + case 8: + disp_ptr = link_remotely_inhibited + subpage*16; + break; + case 9: + disp_ptr = local_inhibit_in_progress + subpage*16; + break; + case 10: + disp_ptr = uninhibit_in_progress + subpage*16; + break; + case 11: + disp_ptr = local_blocked + subpage*16; + break; + case 12: + disp_ptr = remote_blocked + subpage*16; + break; + case 13: + disp_ptr = local_change_over + subpage*16; + break; + default: + disp_length = 0; + + } + break; + case 3: + if (line == 0) + { + disp_ptr = &disp_page[page]; + disp_length = 1; + } + else if (line < 3) + { + disp_ptr = mtp2_flag_old+(line-1)*16; + } + else if (line < 5) + { + disp_ptr = mtp2_flag_new+(line-3)*16; + } + else if (line==5) + { + disp_ptr = &MTP3IPMng.LinkIPNum; + disp_length = 1; + } + else if (line < 24) + { + if (subpage == 0) + disp_ptr = (BYTE*)MTP3IPMng.mtp3_flag_ip+(line-6)*16; + else if (subpage == 1) + disp_ptr = MTP3IPMng.mtp3_flag_old+(line-6)*16; + else if (subpage == 2) + disp_ptr = MTP3IPMng.mtp3_flag_new+(line-6)*16; + else if (subpage == 3) + disp_ptr = mtp3ObjState.lk_configured+(line-6)*16; + else if (subpage == 4) + disp_ptr = mtp3ObjState.lk_NMTP3_ok+(line-6)*16; + else if (subpage == 5) + disp_ptr = mtp3ObjState.lk_AMTP3_ok+(line-6)*16; + else if (subpage == 6) + disp_ptr = (BYTE*)MTP3IPMng.LinkIP+(line-6)*16; + } + else + disp_length = 0; + break; + case 4:/* input of state machine */ + if (subpage >= 64) + return 0; + switch (line) + { + case 0: + disp_ptr = &disp_page[page]; + disp_length = 1; + break; + case 1:/* l3 */ + disp_ptr = mtp3ObjInput.lsac_input_from_l2 + subpage*16; + break; + case 2:/* l2 */ + disp_ptr = mtp3ObjInput.lsac_input_from_sltc + subpage*16; + break; + case 3:/* l1 */ + disp_length = 0; + break; + case 4: + disp_ptr = mtp3ObjInput.lsac_input_from_stm + subpage*16; + break; + case 5: + disp_ptr = mtp3ObjInput.lsac_input_from_tcoc + subpage*16; + break; + case 6: + disp_ptr = mtp3ObjInput.lsac_input_from_mgmt + subpage*16; + break; + case 7: + disp_ptr = mtp3ObjInput.tlac_input_from_slm + subpage*16; + break; + case 8: + disp_ptr = mtp3ObjInput.tlac_input_from_stm + subpage*16; + break; + case 9: + disp_ptr = mtp3ObjInput.tlac_input_from_hmdt + subpage*16; + break; + case 10: + disp_ptr = mtp3ObjInput.tsrc_input_from_stm + subpage*16; + break; + case 11: + disp_ptr = mtp3ObjInput.tsrc_input_from_tlac + subpage*16; + break; + case 12: + disp_ptr = mtp3ObjInput.tsrc_input_from_tcoc + subpage*16; + break; + case 13: + disp_ptr = mtp3ObjInput.tsrc_input_from_tcbc + subpage*16; + break; + case 14: + disp_length = 0; + break; + case 15: + disp_length = 0; + break; + case 16: + disp_ptr = mtp3ObjInput.tcoc_input_from_stm + subpage*16; + break; + case 17: + disp_ptr = mtp3ObjInput.tcoc_input_from_tsrc + subpage*16; + break; + case 18: + disp_ptr = mtp3ObjInput.tcoc_input_from_hmdt + subpage*16; + break; + case 19: + disp_ptr = mtp3ObjInput.tcbc_input + subpage*16; + break; + case 20: + disp_ptr = mtp3ObjInput.tcbc_input_from_tsrc + subpage*16; + break; +/* case 21: + disp_ptr = mtp3ObjInput.sltc_input + subpage*16; + break;*/ + case 21: + if(subpage >= 32) + return 0; + disp_ptr = mtp3ObjInput.taprc_input + subpage*16; + break; + case 22: + disp_ptr = &mtp3ObjInput.tprc_input; + disp_length = 1; + break; + default: + disp_length = 0; + break; + + } + break; + case 5: /* state machine */ + if (subpage >= 64) + return 0; + switch (line) + { + case 0: + disp_ptr = &disp_page[page]; + disp_length = 1; + break; + case 1: + disp_ptr = mtp3ObjState.link_l1_state+subpage*16; + break; + case 2: + disp_ptr = mtp3ObjState.link_l2_state+subpage*16; + break; + case 3: + disp_ptr = mtp3ObjState.link_l3_state+subpage*16; + break; + case 4: + disp_ptr = mtp3ObjState.lsac_state+subpage*16; + break; + case 5: + disp_ptr = mtp3ObjState.sltc_state+subpage*16; + break; + case 6: + disp_ptr = mtp3ObjState.tlac_state+subpage*16; + break; + case 7: + disp_ptr = mtp3ObjState.tsrc_state+subpage*16; + break; + case 8: + disp_ptr = mtp3ObjState.tcoc_state+subpage*16; + break; + case 9: + disp_ptr = mtp3ObjState.tcbc_state+subpage*16; + break; + case 10: + disp_ptr = mtp3.nw[0].rtpc_state+subpage*16; + break; + case 11: + disp_ptr = mtp3.nw[1].rtpc_state+subpage*16; + break; + case 12: + disp_ptr = mtp3.nw[2].rtpc_state+subpage*16; + break; + case 13: + disp_ptr = mtp3.nw[3].rtpc_state+subpage*16; + break; + case 14: + disp_ptr = mtp3.nw[0].rtac_state+subpage*16; + break; + case 15: + disp_ptr = mtp3.nw[1].rtac_state+subpage*16; + break; + case 16: + disp_ptr = mtp3.nw[2].rtac_state+subpage*16; + break; + case 17: + disp_ptr = mtp3.nw[3].rtac_state+subpage*16; + break; + case 18: + disp_ptr = &mtp3ObjState.tprc_state; + disp_length = 1; + break; + default: + disp_length = 0; + break; + } + + break; + case 6:/* routine */ + if (line == 0) + { + disp_ptr = &disp_page[page]; + disp_length = 1; + } + else if ( line <17 ) + { + if (subpage < 16) + { + int index=0; + index = subpage/4; + disp_ptr = mtp3.nw[index].routine+(line-1)*16+256*(subpage%4); + } + else + disp_length = 0; + } + else + disp_length = 0; + break; + + case 7:/* ls sls & ls slc table */ + if (line == 0) + { + disp_ptr = &disp_page[page]; + disp_length = 1; + } + else if ( line <17 ) + { + disp_length = 32; + if (subpage < 8*4) + { + disp_ptr = (BYTE *)(ls_sls + (line-1)*16 + subpage*256); + } + else if (subpage < 16*4) + { + disp_ptr = (BYTE *)(ls_slc + (line-1)*16 + (subpage-8)*256); + } + else if (subpage < 24*4) + { + disp_ptr = (BYTE *)(sls_to_link + (line-1)*16 + (subpage-16)*256); + } + else + disp_length = 0; + } + else + disp_length = 0; + break; + + case 8:/* E1 STATE */ + if (line == 0) + { + disp_ptr = &disp_page[page]; + disp_length = 1; + } + else if (line < 17) + { + if (subpage < 32) + { + disp_ptr = (BYTE*)&mtp3.ls[subpage*16+line-1]; + disp_length = 9+3; + } + else + disp_length = 0; + } + else + disp_length = 0; + break; + case 9:/* ls influence dstination table */ + if (line == 0) + { + disp_ptr = &disp_page[page]; + disp_length = 1; + } + else if (line < 18) + { + if (subpage < 128) + { + if (line < 9) + { + disp_ptr = (BYTE*)&mtp3.ls[subpage].influ_dstplace_intable_asNLS[(line-1)*16]; + disp_length = 16; + } + else if (line == 9) + { + disp_length = 0; + } + else + { + disp_ptr = (BYTE*)&mtp3.ls[subpage].influ_dstplace_intable_asALS[(line-10)*16]; + disp_length = 16; + } + } + else + disp_length = 0; + } + else if (line == 18) + disp_length = 0; + else if (line == 19) + { + disp_ptr = (BYTE*)&mtp3.ls[subpage]; + disp_length = 9; + } + else + disp_length = 0; + break; + + case 10:/* isup watch dog */ + if (line == 0) + { + disp_ptr = &disp_page[page]; + disp_length = 1; + } + else if (line < 9) + { + disp_ptr = (BYTE*)&mtp3.nw[page].flow.isup_detail[(line-1)*16]; + disp_length = 16; + } + else + disp_length = 0; + break; + case 11:/* watch dog */ + if (line < 16) + { + disp_ptr = (BYTE*)&mtp3ObjState.MTP3WatchDog[line*16]; + disp_length = 16; + } + else + disp_length = 0; + break; + default: + disp_length = 0; + break; + } + return disp_length; +} + +void mtp_disp_page(BYTE page) +{ + BYTE disp_line; + BYTE disp_length; + u32 object_id[20];//for test + +/* object_id head */ + object_id[0] = 1; + object_id[1] = 3; + object_id[2] = 6; + object_id[3] = 1; + object_id[4] = 4; + object_id[5] = 1; + object_id[6] = 1373; + object_id[7] = 1; + object_id[8] = 1; + object_id[9] = 2; +/* object_id head */ + + object_id[10] = 3; + object_id[11] = 1; + + object_id[12] = 2; + object_id[13] = MTP3_DEBUG_ID + 2; + object_id[14] = 5 + page;//page + //object_id[3] = 2;//line + object_id[16] = 0;//instance + + for (disp_line = 0; disp_line < 22; disp_line++) + { + disp_length = mtp_disp_line(page,disp_line); + object_id[15] = disp_line + 2;//line +// debug_set_response(17,object_id,&disp_length,10); + object_id[16] = 2;//data pointer + debug_set_response(17,object_id,disp_ptr,disp_length); + } +} + +int mtp_debug_set() +{ + BYTE page; + BYTE data[10]; + BYTE *ptr; + u32 object_id[20];//for test + char mtp3_ver[20] = MTP3_VERSION; + + sprintf(mtp3_ver,"V%d.%d.%02d",mtp3_ver[0],mtp3_ver[1],mtp3_ver[2]); + + mtpi_m(); + + ptr = data; + +/* object_id head */ + object_id[0] = 1; + object_id[1] = 3; + object_id[2] = 6; + object_id[3] = 1; + object_id[4] = 4; + object_id[5] = 1; + object_id[6] = 1373; + object_id[7] = 1; + object_id[8] = 1; + object_id[9] = 2; +/* object_id head */ + object_id[10] = 3; + object_id[11] = 1; + + object_id[12] = 2; + object_id[13] = MTP3_DEBUG_ID+2; + object_id[14] = 1; + object_id[15] = 0;//instance + + data[0] = 1;//active this module + + debug_set_response(16,object_id,data,1); + object_id[14] = 2; + debug_set_response(15,object_id, (BYTE *)mtp3_ver,strlen(mtp3_ver));//module name + object_id[14] = 3; + debug_set_response(15,object_id,(BYTE *)mtp_asciin_buf,80);//ascii in buf + object_id[14] = 4; + debug_set_response(15,object_id,mtp_asciout_buf,4096);//ascii out buf + + + object_id[15] = 1;//TITLE +// object_id[16] = 2;//instance + for (page = 1; page < 16; page ++) + { + switch (page) + { + case 1: + ptr = title1_p;/*measure*/ + break; + case 2: + ptr = title2_p; + break; + case 3: + ptr = title3_p;/* MIB1 */ + break; + case 4: + ptr = title4_p;/* MIB2 */ + break; + case 5://page 1 + ptr = title5_p; + break; + case 6: + ptr = title6_p; + break; + case 7: + ptr = title7_p; + break; + case 8: + ptr = title8_p; + break; + case 9: + ptr = title9_p; + break; + case 10: + ptr = title10_p; + break; + case 11: + ptr = title11_p; + break; + default: + continue; + } + object_id[14] = 5 + page; + debug_set_response(17,object_id,ptr,strlen((char *)ptr)); + mtp_disp_page(page); + } + + return 1; +} + +int mtp_send_ascout(char *out_str) +{ +#ifdef _WXC_TEST + if( strlen(out_str) < MTP_MAX_ASCIIOUT_LEN ) + printf("[MTP3]\n%s" ,out_str ); +#else + int out_len; + + out_len = strlen(out_str); + + if (out_len + strlen((char *)mtp_asciout_buf) > MTP_MAX_ASCIIOUT_LEN - 2) + { + mtp3DebugFull = 1; + return 0; +// strcpy(mtp_asciout_buf,out_str); + } + else + strcat((char *)mtp_asciout_buf, out_str); +#endif + return 1; +} + +void mtp3_type_command(BYTE *ascin_ptr,BYTE option) +{ + char info_str[80]; + char *tmp_ptr; + int link; + unsigned int one=1; + WORD inputValue; + int lsx16; + int i; + + if (strstr((char *)ascin_ptr,"link all") != NULL) + { + if (option == 0)/* off */ + { + debug_mask=debug_mask & (~(one< 0) + { + page = mtp_asciin_buf[0]; + if (( page < 11) && (page > 1)) + { + disp_page[page-1] = atoi(ascin_ptr); + mtp_disp_page((BYTE)page-1); + } + if (strcmp(ascin_ptr,"C") == 0) + { + memset(&mtp3.nw[0].flow,0,sizeof(struct mtp3_flow)); + memset(&mtp3.nw[1].flow,0,sizeof(struct mtp3_flow)); + memset(&mtp3.nw[2].flow,0,sizeof(struct mtp3_flow)); + memset(&mtp3.nw[3].flow,0,sizeof(struct mtp3_flow)); + memset(mtp3ObjState.MTP3WatchDog,0,256); + } + else if (strstr(ascin_ptr,"list") != NULL) + { + if (strncmp(ascin_ptr,"list par.opc",12) == 0) + { + mtp3_show_parameter(0,0); + } + else if (strncmp(ascin_ptr,"list par.link",13) == 0) + { + input = atol(&ascin_ptr[13]); + mtp3_show_parameter(1,input); + } + else if (strncmp(ascin_ptr,"list par.ls",11) == 0) + { + input = atol(&ascin_ptr[11]); + mtp3_show_parameter(2,input); + } + else if (strncmp(ascin_ptr,"list par.ints",13) == 0) + { + input = atol(&ascin_ptr[13]); + mtp3_show_parameter(4,input); + } + else if (strncmp(ascin_ptr,"list par.int",12) == 0) + { + input = atol(&ascin_ptr[12]); + mtp3_show_parameter(3,input); + } + else if (strncmp(ascin_ptr,"list par.nats",13) == 0) + { + input = atol(&ascin_ptr[13]); + mtp3_show_parameter(6,input); + } + else if (strncmp(ascin_ptr,"list par.nat",12) == 0) + { + input = atol(&ascin_ptr[12]); + mtp3_show_parameter(5,input); + } + else if (strncmp(ascin_ptr,"list par.sg",11) == 0) + { + input = atol(&ascin_ptr[12]); + mtp3_show_parameter(7,input); + } + else if (strncmp(ascin_ptr,"list route.",11) == 0) + { + input = atol(&ascin_ptr[11]); + mtp3_show_routine_status(input); + } + else if (strncmp(ascin_ptr,"list rt.",8) == 0) + { + input = atol(&ascin_ptr[8]); + mtp3_show_routine_status_sorted(input); + } + else if (strstr(ascin_ptr,"list log status") != NULL) + { + mtp3_list_log_status(); + } + if (strncmp(ascin_ptr,"list link.",10) == 0) + { + input = atol(&ascin_ptr[10]); + if(input MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"mtp_hex_to_ascii, length longer than 300, len=%d!", from_len); + from_len = MAX_SS7_MSG_LEN; + } + j = 0; + for (i = 0; i< from_len; i++) + { + to_asc[j] = ascii[from_hex[i] >> 4]; + j++; + to_asc[j] = ascii[from_hex[i] & 0x0f]; + j++; + to_asc[j] = 0x20; + j++; + } + to_asc[j] = '\0'; + return 1; +} + +void mtp3_showbuf(int n,BYTE *msg,int len) +{ + char info_str[1024]; + unsigned long one=1; + + if (mtp3DebugFull == 1) + return; + + if (((one << n) & debug_mask) == 0) + return; + + mtp_hex_to_ascii(msg,len, (BYTE *)info_str); + strcat(info_str,"\n\r"); + mtp_send_ascout(info_str); +} + +void slt_message_decode(BYTE code,char *c) +{ + switch (code) + { + case SIGNAL_SLTM: + sprintf(c,"SLTM"); + break; + case SIGNAL_SLTA: + sprintf(c,"SLTA"); + break; + default: + sprintf(c,"UNK"); + break; + } +} + +void snm_message_decode(BYTE code,char *c) +{ + switch (code) + { + case SIGNAL_TFA: + sprintf(c,"TFA"); + break; + case SIGNAL_TFP: + sprintf(c,"TFP"); + break; + case SIGNAL_TRA: + sprintf(c,"TRA"); + break; + case SIGNAL_RST: + sprintf(c,"RST"); + break; + case SIGNAL_COO: + sprintf(c,"COO"); + break; + case SIGNAL_COA: + sprintf(c,"COA"); + break; + case SIGNAL_CBD: + sprintf(c,"CBD"); + break; + case SIGNAL_CBA: + sprintf(c,"CBA"); + break; + case SIGNAL_ECO: + sprintf(c,"ECA"); + break; + case SIGNAL_ECA: + sprintf(c,"ECA"); + break; + case SIGNAL_LIN: + sprintf(c,"LIN"); + break; + case SIGNAL_LUN: + sprintf(c,"LUN"); + break; + case SIGNAL_LIA: + sprintf(c,"LIA"); + break; + case SIGNAL_LUA: + sprintf(c,"LUA"); + break; + case SIGNAL_LID: + sprintf(c,"LID"); + break; + case SIGNAL_LFU: + sprintf(c,"LFU"); + break; + case SIGNAL_LLT: + sprintf(c,"LLT"); + break; + case SIGNAL_LRT: + sprintf(c,"LRT"); + break; + default: + sprintf(c,"UNK"); + break; + + } +} + +void sccp_message_decode(BYTE code,char *c) +{ + switch (code) + { + case MTP3_SCCP_CR: + sprintf(c,"CR"); + break; + case MTP3_SCCP_CC: + sprintf(c,"CC"); + break; + case MTP3_SCCP_CREF: + sprintf(c,"CREF"); + break; + case MTP3_SCCP_RLSD: + sprintf(c,"RLSD"); + break; + case MTP3_SCCP_RLC: + sprintf(c,"RLC"); + break; + case MTP3_SCCP_DT1: + sprintf(c,"DT1"); + break; + case MTP3_SCCP_DT2: + sprintf(c,"DT2"); + break; + case MTP3_SCCP_AK: + sprintf(c,"AK"); + break; + case MTP3_SCCP_UDT: + sprintf(c,"UDT"); + break; + case MTP3_SCCP_UDTS: + sprintf(c,"UDTS"); + break; + case MTP3_SCCP_ED: + sprintf(c,"ED"); + break; + case MTP3_SCCP_EA: + sprintf(c,"EA"); + break; + case MTP3_SCCP_RSR: + sprintf(c,"RSR"); + break; + case MTP3_SCCP_RSC: + sprintf(c,"RSC"); + break; + case MTP3_SCCP_ERR: + sprintf(c,"ERR"); + break; + case MTP3_SCCP_IT: + sprintf(c,"IT"); + break; + case MTP3_SCCP_XUDT: + sprintf(c,"XUDT"); + break; + case MTP3_SCCP_XUDTS: + sprintf(c,"XUDTS"); + break; + case MTP3_SCCP_LUDT: + sprintf(c,"LUDT"); + break; + case MTP3_SCCP_LUDTS: + sprintf(c,"LUDTS"); + break; + default: + sprintf(c,"UNK"); + break; + } +} + +void tup_message_decode(BYTE code,char *c) +{ + switch (code) + { + case MTP3_TUP_IAM: + sprintf(c,"IAM"); + break; + case MTP3_TUP_IAI: + sprintf(c,"IAI"); + break; + case MTP3_TUP_SAM: + sprintf(c,"SAM"); + break; + case MTP3_TUP_SAO: + sprintf(c,"SAO"); + break; + case MTP3_TUP_GSM: + sprintf(c,"GSM"); + break; + case MTP3_TUP_COT: + sprintf(c,"COT"); + break; + case MTP3_TUP_GRQ: + sprintf(c,"GRQ"); + break; + case MTP3_TUP_ACM: + sprintf(c,"ACM"); + break; + case MTP3_TUP_SEC: + sprintf(c,"SEC"); + break; + case MTP3_TUP_CGC: + sprintf(c,"CGC"); + break; + case MTP3_TUP_CFL: + sprintf(c,"CFL"); + break; + case MTP3_TUP_SSB: + sprintf(c,"SSB"); + break; + case MTP3_TUP_UNN: + sprintf(c,"UNN"); + break; + case MTP3_TUP_LOS: + sprintf(c,"LOS"); + break; + case MTP3_TUP_SST: + sprintf(c,"SST"); + break; + case MTP3_TUP_ACB: + sprintf(c,"ACB"); + break; + case MTP3_TUP_DPN: + sprintf(c,"DPN"); + break; + case MTP3_TUP_ANU: + sprintf(c,"ANU"); + break; + case MTP3_TUP_ANC: + sprintf(c,"ANC"); + break; + case MTP3_TUP_ANN: + sprintf(c,"ANN"); + break; + case MTP3_TUP_CBK: + sprintf(c,"CBK"); + break; + case MTP3_TUP_CLF: + sprintf(c,"CLF"); + break; + case MTP3_TUP_CCL: + sprintf(c,"CCL"); + break; + case MTP3_TUP_RLG: + sprintf(c,"RLG"); + break; + case MTP3_TUP_BLO: + sprintf(c,"BLO"); + break; + case MTP3_TUP_BLA: + sprintf(c,"BLA"); + break; + case MTP3_TUP_UBL: + sprintf(c,"UBL"); + break; + case MTP3_TUP_UBA: + sprintf(c,"UBA"); + break; + case MTP3_TUP_ADI: + sprintf(c,"ADI"); + break; + default: + sprintf(c,"UNK"); + break; + } +} + +void isup_message_decode(BYTE code,char *c) +{ + switch (code) + { + case MTP3_ISUP_IAM: + sprintf(c,"IAM"); + break; + case MTP3_ISUP_ACM: + sprintf(c,"ACM"); + break; + case MTP3_ISUP_CPG: + sprintf(c,"CPG"); + break; + case MTP3_ISUP_ANM: + sprintf(c,"ANM"); + break; + case MTP3_ISUP_REL: + sprintf(c,"REL"); + break; + case MTP3_ISUP_RLC: + sprintf(c,"RLC"); + break; + case MTP3_ISUP_UBL: + sprintf(c,"UBL"); + break; + case MTP3_ISUP_UBA: + sprintf(c,"UBA"); + break; + case MTP3_ISUP_GRA: + sprintf(c,"GRA"); + break; + default: + sprintf(c,"UNK"); + break; + } +} + +BOOL iptrans_msg_flow(BYTE *msg,BYTE pclen,int direction,ulong dest_ip) +{ + char info_str[1024]; + long dpc=0; + long opc=0; + BYTE sls; + char tempbuf[1024]; + long route_mark; + BYTE sio; + struct timeval tv; + struct timezone tz; + struct tm *t; + BYTE ssf; + unsigned long one=1; + struct in_addr in; + BOOL msg2mtp2; + char type[10]; + BYTE nw; + char netID[10]; + char codeName[16]; + int msg_len, link; + + if (mtp3DebugFull == 1) + return 0; + + in.s_addr = dest_ip; + +/* if (((dest_ip & E1CARD_BASE_IP_MASK) == E1CARD_BASE_IP) && + (((dest_ip >> 16) & 0xff) < 32))*/ + link = (msg[1]<<8)+msg[0]; + if (msg[0] < 255)//??? + { + msg2mtp2 = TRUE; + } + else + msg2mtp2 = FALSE; + + sio = msg[3+1]; + nw = (sio >> 6) & 3; + + switch (nw) + { + case 0: + sprintf(netID,"INAT"); + break; + case 1: + sprintf(netID,"INATs"); + break; + case 2: + sprintf(netID,"NAT"); + break; + case 3: + sprintf(netID,"NATs"); + break; + } + + if (pclen == MTP3_24BIT_PC) + { + memcpy((BYTE *)&dpc,&msg[5],3); + memcpy((BYTE *)&opc,&msg[8],3); + sls = msg[11] & 0x0f; + } + else + { + memcpy((BYTE*)&route_mark,&msg[5],4); + dpc = route_mark & 0x3FFF; + opc = (route_mark & 0x0FFFFFFF) >> 14; + sls = (route_mark >> 28) & 0x0f; + } + + if (debug_link[link] != MTP3_MSGLOG_ON) + { + if (msg2mtp2 == TRUE) + return 0; + } + + { + msg_len = (msg[2]<<8) + msg[3]; + if(msg_len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"Get message in iptrans_msg_flow, length longer than 300!"); + msg[1]=0; + } + + } + ssf= sio & 0x0f; + switch (ssf) + { + case TUP_SIO: + if (((one << MTP3DB_TUPMSG) & debug_mask) == 0) + return 0; + sprintf(type,"TUP"); + if (pclen == MTP3_24BIT_PC) + tup_message_decode(msg[12+1],codeName); + else + tup_message_decode(msg[9+1],codeName); + break; + case ISUP_SIO: + if (((one << MTP3DB_ISUPMSG) & debug_mask) == 0) + return 0; + sprintf(type,"ISUP"); + if (pclen == MTP3_24BIT_PC) + isup_message_decode(msg[13+1],codeName); + else + isup_message_decode(msg[10+1],codeName); + break; + case BICC_SIO: + if (((one << MTP3DB_BICCMSG) & debug_mask) == 0) + return 0; + sprintf(type,"BICC"); + if (pclen == MTP3_24BIT_PC) + isup_message_decode(msg[13+1],codeName); + else + isup_message_decode(msg[10+1],codeName); + break; + case SCCP_SIO: + if (((one << MTP3DB_SCCPMSG) & debug_mask) == 0) + return 0; + sprintf(type,"SCCP"); + if (pclen == MTP3_24BIT_PC) + sccp_message_decode(msg[11+1],codeName); + else + sccp_message_decode(msg[8+1],codeName); + break; + case SNM_SIO: + if (((one << MTP3DB_SNMMSG) & debug_mask) == 0) + return 0; + sprintf(type,"SNM"); + if (pclen == MTP3_24BIT_PC) + snm_message_decode(msg[11+1],codeName); + else + snm_message_decode(msg[8+1],codeName); + break; + case TM_SIO: + if (((one << MTP3DB_SNMMSG) & debug_mask) == 0) + return 0; + sprintf(type,"SLT"); + if (pclen == MTP3_24BIT_PC) + slt_message_decode(msg[11+1],codeName); + else + slt_message_decode(msg[8+1],codeName); + break; + default: + return 0; + } + + gettimeofday(&tv,&tz); + t = localtime(&tv.tv_sec); + switch (direction) + { + case MTP_MSG_UP: + if (msg2mtp2 == TRUE) + sprintf(info_str,"%s-%s(%02d:%02d:%02d.%06ld):MTP3<==MTP2,%dB %s SPC(%lx->%lx) SLS=%x LI=%x srcLINK=%04d srcIP=%s\r\n", + type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,pclen,netID,opc,dpc,sls,msg_len,link,inet_ntoa(in)); + else + { + if (((one << MTP3DB_APP_APP_MSG) & debug_mask) != 0) + sprintf(info_str,"%s-%s(%02d:%02d:%02d.%06ld):MTP3<==MTP3,%dB %s SPC(%lx->%lx) SLS=%x LI=%x srcIP=%s\r\n", + type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,pclen,netID,opc,dpc,sls,msg_len,inet_ntoa(in)); + else + return 0; + } + mtp_hex_to_ascii(msg, (msg[2]<<8)+msg[3]+4, (BYTE *)tempbuf); + strcat(info_str,tempbuf); + strcat(info_str,"\n\r"); + mtp_send_ascout(info_str); + return 1; + break; + case MTP_MSG_DOWN: + sprintf(info_str,"%s-%s(%02d:%02d:%02d.%06ld):MTP3<==USER,%s DPC=%lx SLS=%x\n\rPerform routing:MTP3==>MTP2,%dB SPC(%lx->%lx) LI=%02x dstLINK=%04d dstIP=%s\r\n", + type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,netID,dpc,sls,pclen,opc,dpc,msg_len,link,inet_ntoa(in)); + break; + case MTP_MSG_STP: + sprintf(info_str,"%s-%s(%02d:%02d:%02d.%06ld)Perform STP:MTP3==>MTP2,SPC(%lx->%lx) dstLINK=%x dstIP=%s\r\n", + type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,opc,dpc,msg[0],inet_ntoa(in)); + break; + case MTP_MSG_OTHER_SERVER: + if (msg2mtp2 == TRUE) + sprintf(info_str,"%s%s(%02d:%02d:%02d.%06ld):MTP3<==USER, %s DPC=%lx SLS=%x\n\rRouting by UP:MTP3==>MTP2,%dB SPC(%lx->%lx) LI=%02x dstLINK=%04d dstIP=%s\r\n", + type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,netID,dpc,sls,pclen,opc,dpc,(msg[1]<<8)+msg[2],link,inet_ntoa(in)); + else + { + if (((one << MTP3DB_APP_APP_MSG) & debug_mask) != 0) + sprintf(info_str,"%s-%s(%02d:%02d:%02d.%06ld):MTP3<==USER, %s DPC=%lx SLS=%x\n\rRouting by UP:MTP3==>MTP3,%dB SPC(%lx->%lx) LI=%02x dstIP=%s\r\n", + type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,netID,dpc,sls,pclen,opc,dpc,msg_len,inet_ntoa(in)); + else + return 0; + } + break; + case MTP_SNM_MSG: + sprintf(info_str,"%s-%s(%02d:%02d:%02d.%06ld):MTP3==>MTP2,%dB %s SPC(%lx->%lx) SLS=%d LI=%02x dstLINK=%04d dstIP=%s\r\n", +type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,pclen,netID,opc,dpc,sls,msg_len,link,inet_ntoa(in)); + mtp_hex_to_ascii(msg,msg_len+4, (BYTE *)tempbuf); + strcat(info_str,tempbuf); + strcat(info_str,"\n\r"); + mtp_send_ascout(info_str); + return 1; + break; + } + mtp_hex_to_ascii(msg,msg_len+4, (BYTE *)tempbuf); + strcat(info_str,tempbuf); + strcat(info_str,"\n\r\n\r"); + mtp_send_ascout(info_str); + return 1; +} + +BOOL iptrans_msg_flow_2(up_message *up_msg_ptr) +{ + char info_str[1024]; + char tempbuf[1024]; + BYTE sio; + struct timeval tv; + struct timezone tz; + struct tm *t; + unsigned long one=1; + char type[10]; + BYTE nw; + char netID[10]; + char codeName[16]; + + if (mtp3DebugFull == 1) + return 0; + + if(up_msg_ptr->len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"Get message in iptrans_msg_flow_2, length longer than 300!"); + up_msg_ptr->len = MAX_SS7_MSG_LEN; + } + sio = up_msg_ptr->sio; + nw = (sio >> 6) & 3; + + switch (nw) + { + case 0: + sprintf(netID,"INAT"); + break; + case 1: + sprintf(netID,"INATs"); + break; + case 2: + sprintf(netID,"NAT"); + break; + case 3: + sprintf(netID,"NATs"); + break; + } + + if (((one << MTP3DB_SCCPMSG) & debug_mask) == 0) + return 0; + + sprintf(type,"SCCP"); + sccp_message_decode(up_msg_ptr->msgList[0],codeName); + + gettimeofday(&tv,&tz); + t = localtime(&tv.tv_sec); + sprintf(info_str,"%s-%s(%02d:%02d:%02d.%06ld):MTP3LITE==>USER,%s LI=%x srcLINK=%03d\r\n", + type,codeName,t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec,netID,up_msg_ptr->len,up_msg_ptr->link); + mtp_hex_to_ascii(&up_msg_ptr->msgList[0], up_msg_ptr->len, (BYTE *)tempbuf); + strcat(info_str,tempbuf); + strcat(info_str,"\n\r\n\r"); + mtp_send_ascout(info_str); + + return 1; +} + +void mtp3_debug(int n,const char *fmt,...) +{ + char info_str[1024]; + char tempbuf[1024]; + va_list ap; + unsigned long one=1; + struct timeval tv; + struct timezone tz; + struct tm *t; + + if (mtp3DebugFull == 1) + return; + + if(((one<tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\33[0m\n\r"); + mtp_send_ascout(tempbuf); + break; + case MTP3DB_SCCPMSG: + sprintf(tempbuf,"\33[36mSCCP(%d:%d:%d.%ld):",t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\33[0m\n\r\n\r"); + mtp_send_ascout(tempbuf); + break; + case MTP3DB_ISUPMSG: + sprintf(tempbuf,"\33[36mISUP(%d:%d:%d.%ld):",t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\33[0m\n\r"); + mtp_send_ascout(tempbuf); + break; + case MTP3DB_TUPMSG: + sprintf(tempbuf,"\33[36mTUP(%d:%d:%d.%ld):",t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\33[0m\n\r"); + mtp_send_ascout(tempbuf); + break; + case MTP3DB_ERROR: + sprintf(tempbuf,"\33[31m(%d:%d:%d.%ld)",t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\33[0m\n\r"); + mtp_send_ascout(tempbuf); + break; + case MTP3DB_PFHB: + sprintf(tempbuf,"(%d:%d:%d.%ld)",t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\n\r"); + mtp_send_ascout(tempbuf); + break; + case MTP3DB_PRIMITIVE_MSG: + sprintf(tempbuf,"(%d:%d:%d.%ld)",t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\n\r"); + mtp_send_ascout(tempbuf); + break; + case MTP3DB_CMD: + sprintf(tempbuf,"\33[1;33m(%d:%d:%d)",t->tm_hour,t->tm_min,t->tm_sec); + strcat(tempbuf,info_str); + strcat(tempbuf,"\33[0m\n\r"); + mtp_send_ascout(tempbuf); + break; + default: + break; + } +} + +void mtp3_list_log_status() +{ + int i; + char info_str[80]; + + mtp_send_ascout("\33[32mmtp3 log status-->\33[0m\n\r"); + if ((debug_mask & 2) != 0) + mtp_send_ascout("log snm \33[33mON\33[0m\n\r"); + if ((debug_mask & 4) != 0) + mtp_send_ascout("log sccp \33[33mON\33[0m\n\r"); + if ((debug_mask & 8) != 0) + mtp_send_ascout("log tup \33[33mON\33[0m\n\r"); + if ((debug_mask & 16) != 0) + mtp_send_ascout("log isup \33[33mON\33[0m\n\r"); + if ((debug_mask & 32) != 0) + mtp_send_ascout("log error \33[33mON\33[0m\n\r"); + if ((debug_mask & 64) != 0) + mtp_send_ascout("log event \33[33mON\33[0m\n\r"); + if ((debug_mask & 256) != 0) + mtp_send_ascout("log mtp3hb \33[33mON\33[0m\n\r"); + if ((debug_mask & 512) != 0) + mtp_send_ascout("log internal \33[33mON\33[0m\n\r"); + if ((debug_mask & 1024) != 0) + mtp_send_ascout("log primitive \33[33mON\33[0m\n\r"); + if ((debug_mask & 128) != 0) + { + mtp_send_ascout("log all link \33[33mON\33[0m\n\r"); + return; + } + for (i=0;i<256;i++) + { + if (debug_link[i] == MTP3_MSGLOG_ON) + { + sprintf(info_str,"log link=%d \33[33mON\33[0m\n\r",i); + mtp_send_ascout(info_str); + } + } +} + +void mtp3_show_routine_status(BYTE nw) +{ + int i; + char info_str[4096]; + char tempbuf[4096]; + nw_para *para; + network *sp; + BYTE current_rt; + WORD nls; + WORD als; + static BYTE last_show[4]={0}; + BYTE showCount=0; + + nw = nw & 3; + + para = &mtp3_para->nw[nw]; + sp = &mtp3.nw[nw]; + switch (nw) + { + case 0: + sprintf(info_str,"\33[33mInternational Network\n\rSPC\t\tOPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + case 1: + sprintf(info_str,"\33[33mInternational Network spare\n\rSPC\t\tOPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + case 2: + sprintf(info_str,"\33[33mNational Network\n\rSPC\t\tOPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + case 3: + sprintf(info_str,"\33[33mNational Network spare\n\rSPC\t\tOPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + default: + break; + } + mtp_send_ascout(info_str); + showCount=0; + for (i=last_show[nw];irouting[i].normal_ls; + als = para->routing[i].alternative_ls; + if ((para->routing[i].dpc != 0) && + (nls < MAX_LS) ) + { + current_rt = (sp->routine[i] >> 6) & 3; + switch (current_rt) + { + case 0: + if (als < MAX_LS) + sprintf(tempbuf,"%06lx\t\t%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t%02d\n\r",para->routing[i].dpc,para->routing[i].opc,nls,nls,als); + else + sprintf(tempbuf,"%06lx\t\t%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t--\n\r",para->routing[i].dpc,para->routing[i].opc,nls,nls); + mtp_send_ascout(tempbuf); + break; + case 1: + if (als < MAX_LS) + sprintf(tempbuf,"%06lx\t\t%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t%02d\n\r",para->routing[i].dpc,para->routing[i].opc,als,nls,als); + else + sprintf(tempbuf,"%06lx\t\t%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t--\n\r",para->routing[i].dpc,para->routing[i].opc,als,nls); + mtp_send_ascout(tempbuf); + break; + case 2: + if (als < MAX_LS) + sprintf(tempbuf,"%06lx\t\t%06lx\t\t\33[31mN\33[0m\t\tNo Path\t\t%02d\t%02d\n\r",para->routing[i].dpc,para->routing[i].opc,nls,als); + else + sprintf(tempbuf,"%06lx\t\t%06lx\t\t\33[31mN\33[0m\t\tNo Path\t\t%02d\t--\n\r",para->routing[i].dpc,para->routing[i].opc,nls); + mtp_send_ascout(tempbuf); + break; + default: + break; + } + showCount++; + } + if (showCount > 31) + { + last_show[nw] = i+1; + break; + } + } + if (i>=MAX_ROUTE) + { + last_show[nw] = 0; + } + +} + +void mtp3_show_routine_status_sorted(BYTE nw) +{ + int i; + char info_str[4096]; + char tempbuf[4096]; + nw_para *para; + network *sp; + mtp3DPCIndex *sort_rec; + BYTE current_rt; + WORD nls; + WORD als; + static BYTE last_show[4]={0}; + BYTE showCount=0; + int index; + + nw = nw & 3; + + para = &mtp3_para->nw[nw]; + sp = &mtp3.nw[nw]; + sort_rec = &mtp3SortRoutine.nw[nw]; + switch (nw) + { + case 0: + sprintf(info_str,"\33[33mInternational Network\n\rSPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + case 1: + sprintf(info_str,"\33[33mInternational Network spare\n\rSPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + case 2: + sprintf(info_str,"\33[33mNational Network\n\rSPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + case 3: + sprintf(info_str,"\33[33mNational Network spare\n\rSPC\t\tReachable\tPath\t\tNLS\tALS\n\r\33[0m"); + break; + default: + break; + } + mtp_send_ascout(info_str); + showCount=0; + for (i=last_show[nw];isortedNum;i++) + { + index = sort_rec->index[i]; + nls = para->routing[index].normal_ls; + als = para->routing[index].alternative_ls; + if ((para->routing[index].dpc != 0) && + (nls < MAX_LS) ) + { + current_rt = (sp->routine[index] >> 6) & 3; + switch (current_rt) + { + case 0: + if (als < MAX_LS) + sprintf(tempbuf,"%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t%02d\n\r",para->routing[index].dpc ,nls,nls,als); + else + sprintf(tempbuf,"%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t--\n\r",para->routing[index].dpc ,nls,nls); + mtp_send_ascout(tempbuf); + break; + case 1: + if (als < MAX_LS) + sprintf(tempbuf,"%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t%02d\n\r",para->routing[index].dpc ,als,nls,als); + else + sprintf(tempbuf,"%06lx\t\t\33[32mY\33[0m\t\tLinkset %02d\t%02d\t--\n\r",para->routing[index].dpc ,als,nls); + mtp_send_ascout(tempbuf); + break; + case 2: + if (als < MAX_LS) + sprintf(tempbuf,"%06lx\t\t\33[31mN\33[0m\t\tNo Path\t\t%02d\t%02d\n\r",para->routing[index].dpc ,nls,als); + else + sprintf(tempbuf,"%06lx\t\t\33[31mN\33[0m\t\tNo Path\t\t%02d\t--\n\r",para->routing[index].dpc ,nls); + mtp_send_ascout(tempbuf); + break; + default: + break; + } + showCount++; + } + if (showCount > 31) + { + last_show[nw] = i+1; + break; + } + } + if (i>=sort_rec->sortedNum-1) + { + last_show[nw] = 0; + } +} + +int pc_length(BYTE nw); +int mtp3_show_parameter(BYTE option,WORD index) +{ + int i; + char info_str[4096]; + int maxindex; + char nw[20]; + + switch (option) + { + case 0: + mtp_send_ascout("Network\t\t\tSPC Len\t\tOPC\n\r"); + if (pc_length(0) == MTP3_24BIT_PC) + sprintf(info_str,"International\t\t24BIT\t\t%06lx\n\r",mtp3_para->nw[0].opc24); + else + sprintf(info_str,"International\t\t14BIT\t\t%06lx\n\r",mtp3_para->nw[0].opc14); + mtp_send_ascout(info_str); + if (pc_length(1) == MTP3_24BIT_PC) + sprintf(info_str,"International(s)\t24BIT\t\t%06lx\n\r",mtp3_para->nw[1].opc24); + else + sprintf(info_str,"International(s)\t14BIT\t\t%06lx\n\r",mtp3_para->nw[1].opc14); + mtp_send_ascout(info_str); + if (pc_length(2) == MTP3_24BIT_PC) + sprintf(info_str,"National\t\t24BIT\t\t%06lx\n\r",mtp3_para->nw[2].opc24); + else + sprintf(info_str,"National\t\t14BIT\t\t%06lx\n\r",mtp3_para->nw[2].opc14); + mtp_send_ascout(info_str); + if (pc_length(3) == MTP3_24BIT_PC) + sprintf(info_str,"National(s)\t\t24BIT\t\t%06lx\n\r",mtp3_para->nw[3].opc24); + else + sprintf(info_str,"National(s)\t\t14BIT\t\t%06lx\n\r",mtp3_para->nw[3].opc14); + mtp_send_ascout(info_str); + sprintf(info_str, "International Dynamic (%d): %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld\r\n", + mtp3_opc.opc_num[0], mtp3_opc.opc[0][0], mtp3_opc.opc[0][1], mtp3_opc.opc[0][2], + mtp3_opc.opc[0][3], mtp3_opc.opc[0][4], mtp3_opc.opc[0][5], mtp3_opc.opc[0][6], mtp3_opc.opc[0][7], + mtp3_opc.opc[0][8], mtp3_opc.opc[0][9], mtp3_opc.opc[0][10], mtp3_opc.opc[0][11], mtp3_opc.opc[0][12], + mtp3_opc.opc[0][13], mtp3_opc.opc[0][14], mtp3_opc.opc[0][15]); + mtp_send_ascout(info_str); + sprintf(info_str, "International(s) Dynamic (%d): %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld\r\n", + mtp3_opc.opc_num[1], mtp3_opc.opc[1][0], mtp3_opc.opc[1][1], mtp3_opc.opc[1][2], + mtp3_opc.opc[1][3], mtp3_opc.opc[1][4], mtp3_opc.opc[1][5], mtp3_opc.opc[1][6], mtp3_opc.opc[1][7], + mtp3_opc.opc[1][8], mtp3_opc.opc[1][9], mtp3_opc.opc[1][10], mtp3_opc.opc[1][11], mtp3_opc.opc[1][12], + mtp3_opc.opc[1][13], mtp3_opc.opc[1][14], mtp3_opc.opc[1][15]); + mtp_send_ascout(info_str); + sprintf(info_str, "National Dynamic (%d): %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld\r\n", + mtp3_opc.opc_num[2], mtp3_opc.opc[2][0], mtp3_opc.opc[2][1], mtp3_opc.opc[2][2], + mtp3_opc.opc[2][3], mtp3_opc.opc[2][4], mtp3_opc.opc[2][5], mtp3_opc.opc[2][6], mtp3_opc.opc[2][7], + mtp3_opc.opc[2][8], mtp3_opc.opc[2][9], mtp3_opc.opc[2][10], mtp3_opc.opc[2][11], mtp3_opc.opc[2][12], + mtp3_opc.opc[2][13], mtp3_opc.opc[2][14], mtp3_opc.opc[2][15]); + mtp_send_ascout(info_str); + sprintf(info_str, "National(s) Dynamic (%d): %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld\r\n", + mtp3_opc.opc_num[3], mtp3_opc.opc[3][0], mtp3_opc.opc[3][1], mtp3_opc.opc[3][2], + mtp3_opc.opc[3][3], mtp3_opc.opc[3][4], mtp3_opc.opc[3][5], mtp3_opc.opc[3][6], mtp3_opc.opc[3][7], + mtp3_opc.opc[3][8], mtp3_opc.opc[3][9], mtp3_opc.opc[3][10], mtp3_opc.opc[3][11], mtp3_opc.opc[3][12], + mtp3_opc.opc[3][13], mtp3_opc.opc[3][14], mtp3_opc.opc[3][15]); + mtp_send_ascout(info_str); + break; + case 1: + sprintf(info_str," \33[32mLink Attribute-->\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str,"\33[32mLink\tLinkset\tSLC\tNormalMTP3\tAlterMTP3\tType\tSG\tCfg\n\r\33[0m"); + mtp_send_ascout(info_str); + if (index > (MAX_LK-32)) + maxindex = MAX_LK; + else + maxindex = index+32; + for (i=index; ilk[i].e1_to_linkset,mtp3_para->lk[i].e1_to_slc, + mtp3_para->lk[i].e1_to_mtp3,mtp3_para->lk[i].e1_to_alterMTP3,mtp3_para->lk[i].e1_lk_type,mtp3_para->lk[i].e1_to_sg,mtp3ObjState.lk_configured[i]); + mtp_send_ascout(info_str); + } + break; + case 2: + sprintf(info_str," \33[32mLinkset Attribute-->\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str,"\33[32mLinkset\tRemote_SPC\tNetwork\t\tLoopBack\n\r\33[0m"); + mtp_send_ascout(info_str); + index = index % MAX_LS; + if (index > (MAX_LS-32)) + maxindex = MAX_LS; + else + maxindex = index+32; + for (i=index; ils_pro[i].nw_id) + { + case 0: + sprintf(nw,"INT"); + break; + case 1: + sprintf(nw,"INT(s)"); + break; + case 2: + sprintf(nw,"NAT"); + break; + case 3: + sprintf(nw,"NAT(s)"); + break; + } + if ((mtp3_para->ls_pro[i].loopback_opt) == 0) + sprintf(info_str,"%03d\t%06lx\t\t%s\t\tN\n\r",i,mtp3_para->ls_pro[i].ls_op_pc,nw); + else + sprintf(info_str,"%03d\t%06lx\t\t%s\t\tY\n\r",i,mtp3_para->ls_pro[i].ls_op_pc,nw); + mtp_send_ascout(info_str); + } + break; + case 3:// international routine */ + sprintf(info_str," \33[32mInternational Routine\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str," \33[32m SPC\tNormal LS\tAlternative LS\n\r\33[0m"); + mtp_send_ascout(info_str); + if (index > (MAX_ROUTE-32)) + maxindex = MAX_ROUTE; + else + maxindex = index+32; + for (i=index; inw[0].routing[i].dpc,mtp3_para->nw[0].routing[i].normal_ls,mtp3_para->nw[0].routing[i].alternative_ls, mtp3_para->nw[0].routing[i].opc); + mtp_send_ascout(info_str); + } + break; + case 4:// international(s) routine + sprintf(info_str," \33[32mInternational(S) Routine\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str," \33[32m SPC\tNormal LS\tAlternative LS\n\r\33[0m"); + mtp_send_ascout(info_str); + if (index > (MAX_ROUTE-32)) + maxindex = MAX_ROUTE; + else + maxindex = index+32; + for (i=index; inw[1].routing[i].dpc ,mtp3_para->nw[1].routing[i].normal_ls ,mtp3_para->nw[1].routing[i].alternative_ls , mtp3_para->nw[1].routing[i].opc ); + mtp_send_ascout(info_str); + } + break; + case 5:// national routine + sprintf(info_str," \33[32mNational Routine\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str," \33[32m SPC\tNormal LS\tAlternative LS\n\r\33[0m"); + mtp_send_ascout(info_str); + if (index > (MAX_ROUTE-32)) + maxindex = MAX_ROUTE; + else + maxindex = index+32; + for (i=index; inw[2].routing[i].dpc ,mtp3_para->nw[2].routing[i].normal_ls ,mtp3_para->nw[2].routing[i].alternative_ls , mtp3_para->nw[2].routing[i].opc ); + mtp_send_ascout(info_str); + } + break; + case 6:// national(s) routine + sprintf(info_str," \33[32mNational(S) Routine\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str," \33[32m SPC\tNormal LS\tAlternative LS\n\r\33[0m"); + mtp_send_ascout(info_str); + if (index > (MAX_ROUTE-32)) + maxindex = MAX_ROUTE; + else + maxindex = index+32; + for (i=index; inw[3].routing[i].dpc ,mtp3_para->nw[3].routing[i].normal_ls ,mtp3_para->nw[3].routing[i].alternative_ls , mtp3_para->nw[3].routing[i].opc ); + mtp_send_ascout(info_str); + } + break; + case 7:// SG Attribute + sprintf(info_str," \33[32mSG Attribute-->\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str," \33[32mSG Enable\tServer\tACK\tRemoteIP\n\r\33[0m"); + mtp_send_ascout(info_str); + if (index > 224) + maxindex = 256; + else + maxindex = index+32; + for (i=index; isg[i].enable,mtp3_para->sg[i].server, + mtp3_para->sg[i].data_ack,mtp3_para->sg[i].ip); + mtp_send_ascout(info_str); + } + break; + } + + return 1; +} + + +void mtp3_list_link(WORD i) +{ + char info_str[4096]; + + sprintf(info_str," \33[32mLink Attribute-->\n\r\33[0m"); + mtp_send_ascout(info_str); + sprintf(info_str,"\33[32mLink\tE1_MTP3\t\tNMTP3\tAMTP3\n\r\33[0m"); + mtp_send_ascout(info_str); + + sprintf(info_str,"%03d\t%08lx\t%02x\t%02x\n\r",i, + mtp3ObjState.lk_mtp3[i],mtp3ObjState.lk_NMTP3_ok[i],mtp3ObjState.lk_AMTP3_ok[i]); + mtp_send_ascout(info_str); +} +/*@end@*/ diff --git a/plat/mtp3/src/mtpmib.c b/plat/mtp3/src/mtpmib.c new file mode 100644 index 0000000..8e92099 --- /dev/null +++ b/plat/mtp3/src/mtpmib.c @@ -0,0 +1,4537 @@ +#include "../../public/src/include/pub_include.h" +#include "../../snmp/src/include/snmp.h" +#include "../../snmp/src/include/macro.h" +#include "../../snmp/src/include/heartbeat.h" +#include "./include/mtp3.h" + +#ifdef _INCLUDE_M2UA + #include "../../m2ua/src/include/m2ua.h" +#endif +#include "./include/mtpstm.h" +#include "./include/mtpext.h" +#include "./include/mtpfunc.h" + +/*@ignore@*/ +char mtpconfile[] = {"./conf/mtp3.conf"}; +FILE *mtpfpConf; +char MTP_OBJECT_LKA[20]={"[LINK ATTRIBUTE]\n"}; +char MTP_OBJECT_NSP[80]={"[NATIONAL NETWORK SP]\n"}; +char MTP_OBJECT_NSSP[80]={"[NATIONAL NETWORK SPARE SP]\n"}; +char MTP_OBJECT_ISP[80]={"[INTERNATIONAL NETWORK SP]\n"}; +char MTP_OBJECT_ISSP[80]={"[INTERNATIONAL NETWORK SPARE SP]\n"}; +char MTP_OBJECT_LSA[40]={"[LINKSET ATTRIBUTE]\n"}; +char MTP_OBJECT_LSP[20]={"[LOCAL SP]\n"}; +char MTP_OBJECT_SNL[40]={"[SERVICE NETWORK SP LEN]\n"}; +char MTP_OBJECT_SG[40]={"[SG ATTRIBUTES]\n"}; +char MTP_OBJECT_MTP3LITE_PORT[40]={"[MTP3LITE TCP PORT]"}; + +long atol(const char *nptr); +void hmrt_tcoc_update_routing_tables(WORD chl); +void hmrt_tcbc_update_routing_tables(WORD chl); +void update_timer(int link); +BOOL Alinkset_status(BYTE routine); +BOOL Nlinkset_status(BYTE routine); +void mark_normal_linkset_available(BYTE *routine); +void mark_alternative_linkset_unavailable(BYTE *routine); +void mark_alternative_linkset_available(BYTE *routine); +void mark_normal_linkset_unavailable(BYTE *routine); +void mark_dstSP_inaccessible(BYTE *routine); +void hmrt_tfrc_update_routing_tables(WORD dst, BYTE nw); +void otherMTP3_managed_link_unavailable(WORD chl); +void mtp3_reload_data(); +int MTP3_LinkIP_List(ulong IP,BYTE mode); +void deactive_mtp3lite_lk(WORD link); +void mtp3_snmp_registration(void); + +//extern from sccp/sccpfun.c +extern ull Bcd2Ull(BYTE *pBcd, int BcdLen); +extern int ParseLine(char *str, char (*row)[128], int maxrow); +extern int Str2Bcd(BYTE *pBcd, char *pStr, int maxLen); +extern void deactive_m3ua_lk(WORD link); + +static u32 peer_hb_timer = 0; + +static u32 mtp3_primomcip=0; // primary omc ip address +static u32 mtp3_secdomcip=0; // secondary omc ip address + +static BYTE mtp3SaveFlag[]={0xaa,0,0xaa}; + +static u32 mtp2_object_id[] = {1,3,6,1,4,1,1373,1,3,1,1,3}; +#define MTP2_PREOID_LEN 12 + +int checkMtp3SaveFlag() +{ + if(mtp3SaveFlag[0]==0xaa && mtp3SaveFlag[2]==0xaa && mtp3SaveFlag[1]<2) + return mtp3SaveFlag[1]; + else + { + mtp3_debug(MTP3DB_ERROR,"WARNING, some stuff change mtp3SaveFlag= %x %x %x unexpectedly!!!",mtp3SaveFlag[0],mtp3SaveFlag[1],mtp3SaveFlag[2]); + return 0; + } +} + +void mtp3EnableSaveFlag() +{ + mtp3SaveFlag[1] = 1; +} + +void mtp3DisableSaveFlag() +{ + mtp3SaveFlag[1] = 0; +} + +void mtp3_send_mtp2_alarm(WORD component,BYTE alarm)//??? +{ + snmp_pdu snmp_buf; + snmp_addr snmp_addr; + time_t cur_time; + u8 *buf; + + snmp_addr.remote_port = 4957; + snmp_addr.local_port = 4957; + snmp_addr.broadcast = 0; + snmp_buf.pdu_type = 7; + snmp_buf.var_num = 1; + memcpy(snmp_buf.var[0].oid, mtp2_object_id, MTP2_PREOID_LEN*4); + snmp_buf.var[0].oid[MTP2_PREOID_LEN] = 4; + snmp_buf.var[0].oidlen = MTP2_PREOID_LEN + 1; + snmp_buf.var[0].vartype = 4; + buf = snmp_buf.var[0].msg; + buf[0] = mtp2_module; // system id + buf[1] = mtp2_systemid; + cur_time = time(NULL); + buf[2] = cur_time >> 24; // time stamp + buf[3] = cur_time >> 16; + buf[4] = cur_time >> 8; + buf[5] = cur_time; + // byte 6--13 16 LED status (green continuous: 0x09, yellow continuous: 0x0a) + buf[6] = 0x99; + if (alarm != 0) + buf[7] = 0xaf; + else + buf[7] = 0x9f; + memset(buf+8, 0xff, 6); + + buf[14] = component>>8; // first byte of component id + buf[15] = component&255; // second byte of component id + buf[16] = alarm; // alarm level + + buf[17] = 0; + buf[18] = 0;//length 1 + + buf[19] = 0;//component id + buf[20] = 0;//component id + + buf[21] = 0; + buf[22] = 20;//length 2 + +// memcpy(buf+30, hlr_vm_ptr->sys_param.hlr_seqnum, HLR_SEQNUM_LEN); +// snmp_buf.var[0].msglen = 37 + HLR_SEQNUM_LEN; + snmp_buf.var[0].msglen = 23; + +// snmp_addr.remote_ip = 0x81ea12ac; + + if (mtp3_primomcip != 0) + { + snmp_addr.remote_ip = mtp3_primomcip; + snmp_send(&snmp_buf, &snmp_addr); + } + + if (mtp3_secdomcip != 0) + { + snmp_addr.remote_ip = mtp3_secdomcip; + snmp_send(&snmp_buf, &snmp_addr); + } +} + +int Mtp3BinSearchIndex(WORD low, WORD high,ull key, BYTE nw) +{ + mtp3DPCIndex *sort_rec = &mtp3SortRoutine.nw[nw]; + static int mid; + static long long midvalue; + + if(low>high) + { +// LogErr("BinSearchIndex ERR,low=%d,high=%d,key=%lld",low,high,key); + return low; + } + + if(high == low+1 ) + { + if(key<=sort_rec->dpc[low]) + return low; + else if(key<=sort_rec->dpc[high]) + return high; + else + return high+1; + } + + if(low == high) + { + if(key<=sort_rec->dpc[low]) + return low; + else + return low+1; + } + + mid = (low + high)/2; + midvalue = sort_rec->dpc[mid]; + + if(key == midvalue) + { + return mid; + } + else if(keyhigh) + { +// LogErr("BinSearchIndex ERR,low=%d,high=%d,key=%lld",low,high,key); + return -1; + } + + if (sort_rec->sortedNum <= 0) + return -1; + + if (high > sort_rec->sortedNum-1) + high = sort_rec->sortedNum-1; + + if(high == low+1 ) + { + if(key==sort_rec->dpc[low]) + return low; + else if(key==sort_rec->dpc[high]) + return high; + else + return -1; + } + + if(low == high) + { + if(key==sort_rec->dpc[low]) + return low; + else + return -1; + } + + mid = (low + high)/2; + midvalue = sort_rec->dpc[mid]; + + if(key == midvalue) + { + return mid; + } + else if(keysortedNum > MAX_ROUTE - 1) + { + mtp3SortRoutine.nw[nw].sortedNum = MAX_ROUTE - 1; + return 0; + } + + if(opc == mtp3_para->nw[nw].opc14) + opc = 0; + opc_dpc = opc; + opc_dpc = (opc_dpc<<32)|dpc; + if(sort_rec->sortedNum == 0) + { + index1 = 0; + sort_rec->dpc[index1] = opc_dpc; + sort_rec->sortedNum = 1; + sort_rec->index[index1] = real_index; + return 1; + } + else + { + index1 = Mtp3BinSearchValue(0,MAX_ROUTE-1,nw,opc_dpc); + if (index1>=0 && index1 < sort_rec->sortedNum)//already has this record + return 0; + + + while(sort_rec->dpc[0] > sort_rec->dpc[sort_rec->sortedNum - 1]) + sort_rec->sortedNum = (sort_rec->sortedNum - 1) % MAX_ROUTE; + //LogErr("--AddSortRec,start BinSearchIndex key=%lld",key); + index1 = Mtp3BinSearchIndex(0,sort_rec->sortedNum-1,opc_dpc,nw); + if (index1 >= sort_rec->sortedNum) + { + if (sort_rec->sortedNum >= MAX_ROUTE-1) + { + return 0; + } + sort_rec->dpc[sort_rec->sortedNum] = opc_dpc; + sort_rec->index[sort_rec->sortedNum] = real_index; + sort_rec->sortedNum ++; + } + +// LogErr("---AddSortRec: index1=%d,store_i=%d,old_key=%lld",index1,index,sort_rec[index1].key); + } + + if (sort_rec->dpc[index1] != opc_dpc) + {// insert a item + int moveNum = (sort_rec->sortedNum-index1) % MAX_ROUTE; + + if (sort_rec->sortedNum >= MAX_ROUTE) + { + return 0; + } + memmove(&sort_rec->dpc[index1+1],&sort_rec->dpc[index1],moveNum*sizeof(ull)); + memmove(&sort_rec->index[index1+1],&sort_rec->index[index1],moveNum*sizeof(u_long)); + sort_rec->dpc[index1]=opc_dpc; + sort_rec->index[index1]=real_index; + sort_rec->sortedNum ++; + return 1; + } + + //LogErr("--rearrange:%lld,%lld,%lld",sort_rec[index1-1].key,key,sort_rec[index1+1].key); + + return 1; +} + +int Mtp3DeleteRecord(ull key,BYTE nw) //VLR_RECORD vlr_record) +{ + mtp3DPCIndex *sort_rec = &mtp3SortRoutine.nw[nw]; +// long long imsi=key; + ulong MoveNum; + int index=-1; + + if (sort_rec->sortedNum == 0) + { + return 0; + } + + index = Mtp3BinSearchValue(0,MAX_ROUTE-1,nw,key); + +// index = BinSearchIndex(1,vlr_record_number,key); + if(index<0 || index>=sort_rec->sortedNum) + { +// LogMsg("VLR--ERROR!Delete Record index=%ld",index); + return 0; + } + + MoveNum = (sort_rec->sortedNum-index) % MAX_ROUTE; + memmove(&sort_rec->dpc[index],&sort_rec->dpc[index+1],MoveNum*sizeof(ull)); + memmove(&sort_rec->index[index],&sort_rec->index[index+1],MoveNum*sizeof(u_long)); + + // LogErr("----After del %lld,%lld,%lld",sort_rec[index-1].key,sort_rec[index].key,sort_rec[index+1].key); + + sort_rec->dpc[sort_rec->sortedNum]=0; + sort_rec->index[sort_rec->sortedNum]=0; + + sort_rec->sortedNum--; + + return 1; +} + + +BYTE mtp_encode_integer(BYTE *buf,u_long val,BYTE value_len) +{ + if(val<128) + { + if (value_len == 4) + { + buf[0] = 0; + buf[1] = 0; + buf[2]=val; + return 3; + } + else + { + buf[0] = val; + return 1; + } + } + else if(val<0x8000) + { + if (value_len == 4) + { + buf[0] = 0; + buf[1]=val >>8; + buf[2]=val & 0xFF; + return 3; + } + else + { + buf[0]=val; + return 1; + } + } + else if(val <0x800000) + { + buf[0]=val >>16; + buf[1]=(val & 0xFF00)>>8; + buf[2]=val & 0xFF; + return 3; + } +// else if(val <0x80000000) + else + { + buf[0]=(val & 0xFF0000)>>16; + buf[1]=(val & 0xFF00)>>8; + buf[2]=val & 0xFF; + return 3; + } +} + +int mtp3_reset_sccp() +{ + DWORD oid[20] = {1,3,6,1,4,1,1373,2,3,2,3,3,2};//SCCP_OID + BYTE value=0; + return set_response(13,oid,&value,1); +} + +void del_1dst_from_table(ls_info *ls, WORD dpc_place, BYTE ud_select) +{ + WORD dst_num; + int i; + + switch (ud_select) + { + case UPDATE_NLS: + dst_num = ls->influ_dstnum_asNLS; + if (dst_num == 0) + return; + ls->influ_dstnum_asNLS --; + for (i=0; iinflu_dstplace_intable_asNLS[i] == dpc_place) + { + memcpy(&ls->influ_dstplace_intable_asNLS[i], + &ls->influ_dstplace_intable_asNLS[i+1],dst_num-i-1); + ls->influ_dstplace_intable_asNLS[dst_num-1] = 0; + ls->links_nls_asp_ac_send_flag[dpc_place] = 0x00; + + return; + } + } + break; + case 1: + dst_num = ls->influ_dstnum_asALS; + if (dst_num == 0) + return; + ls->influ_dstnum_asALS --; + for (i=0; iinflu_dstplace_intable_asALS[i] == dpc_place) + { + memcpy(&ls->influ_dstplace_intable_asALS[i], + &ls->influ_dstplace_intable_asALS[i+1],dst_num-i-1); + ls->influ_dstplace_intable_asALS[dst_num-1] = 0; + ls->links_als_asp_ac_send_flag[dpc_place] = 0x00; + + return; + } + } + break; + } +} + +void add_1dst_to_table(ls_info *ls, WORD place,BYTE ud_select) +{ + WORD dst_num; + + switch (ud_select) + { + case UPDATE_NLS: + dst_num = ls->influ_dstnum_asNLS; + ls->influ_dstplace_intable_asNLS[dst_num] = place; + ls->influ_dstnum_asNLS = dst_num + 1; + ls->links_nls_asp_ac_send_flag[place] = 0x00; + + break; + case UPDATE_ALS: + dst_num = ls->influ_dstnum_asALS; + ls->influ_dstplace_intable_asALS[dst_num] = place; + ls->influ_dstnum_asALS = dst_num + 1; + ls->links_als_asp_ac_send_flag[place] = 0x00; + + break; + } +} + +void scan_conf_right_or_not(BYTE nw) +{ + static BYTE index=0; + BYTE nls; + BYTE lsnw; + + return; + nls = mtp3_para->nw[nw].routing[index].normal_ls; + if (nls < 128) + { + lsnw = mtp3_para->ls_pro[nls].nw_id; + if ((lsnw != nw) && (mtp3_para->nw[nw].routing[index].dpc != 0)) + printf("configure error,nw %d,dpc=%lx normal linkset belong to network %d\n",nw,mtp3_para->nw[nw].routing[index].dpc ,lsnw); + } + index ++; +} + +void mtp3lite_upd_route_status(WORD chl, BYTE flag) +{ + ls_info *ls; + int i; + BYTE nw; + WORD dpc_index, lsno; + + lsno = mtp3_para->lk[chl].e1_to_linkset; + if (lsno >= MAX_LS) + return; + + ls = &mtp3.ls[lsno]; + nw = mtp3_para->ls_pro[lsno].nw_id; + + for (i = 0; i < ls->influ_dstnum_asNLS; i++) + { + dpc_index = ls->influ_dstplace_intable_asNLS[i]; + if (!flag) + mark_normal_linkset_unavailable(&mtp3.nw[nw].routine[dpc_index]); + else + mark_normal_linkset_available(&mtp3.nw[nw].routine[dpc_index]); + if ((mtp3.nw[nw].routine[dpc_index] & 0x0f) == 0x0a)// all road unavailable + mark_dstSP_inaccessible(&mtp3.nw[nw].routine[dpc_index]); + hmrt_tfrc_update_routing_tables(dpc_index,nw); + } +} + +void change_the_whole_ls(WORD lsno,BYTE oldnw,BYTE nw) +{ + ls_info *ls; + int i; + nw_para *nwpara; + BYTE *routine; + BYTE ls_available; + WORD dpc_index; + int added=0; + ull opc_dpc=0; + + ls = &mtp3.ls[lsno]; + +// printf("oldnw = %d,newnw=%d\n",oldnw,nw); + + for (i=0;iinflu_dstnum_asNLS;i++) + { + dpc_index = ls->influ_dstplace_intable_asNLS[i]; + mark_normal_linkset_unavailable(&mtp3.nw[oldnw].routine[dpc_index]); + if ((mtp3.nw[oldnw].routine[dpc_index] & 0x0f) == 0x0a)// all road unavailable + mark_dstSP_inaccessible(&mtp3.nw[oldnw].routine[dpc_index]); + hmrt_tfrc_update_routing_tables(dpc_index,oldnw); + ls->influ_dstplace_intable_asNLS[i] = 0xff; + opc_dpc = mtp3_para->nw[oldnw].routing[dpc_index].opc; + opc_dpc = (opc_dpc<<32)| mtp3_para->nw[oldnw].routing[dpc_index].dpc ; + Mtp3DeleteRecord(opc_dpc, oldnw); + } + for (i=0;iinflu_dstnum_asALS;i++) + { + dpc_index = ls->influ_dstplace_intable_asALS[i]; + mark_alternative_linkset_unavailable(&mtp3.nw[oldnw].routine[dpc_index]); + if ((mtp3.nw[oldnw].routine[dpc_index] & 0x0f) == 0x0a)// all road unavailable + mark_dstSP_inaccessible(&mtp3.nw[oldnw].routine[dpc_index]); + hmrt_tfrc_update_routing_tables(dpc_index,oldnw); + ls->influ_dstplace_intable_asALS[i] = 0xff; + opc_dpc = mtp3_para->nw[oldnw].routing[dpc_index].opc ; + opc_dpc = (opc_dpc<<32) | mtp3_para->nw[oldnw].routing[dpc_index].dpc ; + Mtp3DeleteRecord(opc_dpc,oldnw); + } + ls->influ_dstnum_asNLS = 0; + ls->influ_dstnum_asALS = 0; + + if (mtp3.ls[lsno].links_available_t > 0) + ls_available = TRUE; + else + ls_available = FALSE; + + nwpara = &mtp3_para->nw[nw]; + for (i=0;i<256;i++) + { + if (nwpara->routing[i].dpc == 0) + continue; + routine = &mtp3.nw[nw].routine[i]; + if (nwpara->routing[i].normal_ls == lsno) + { + if (ls_available == TRUE) + mark_normal_linkset_available(routine); + else + mark_normal_linkset_unavailable(routine); + add_1dst_to_table(&mtp3.ls[lsno],i,UPDATE_NLS); + Mtp3AddSortRec(nw,nwpara->routing[i].dpc, i, nwpara->routing[i].opc);//??- + added = 1; + } + if ((nwpara->routing[i].alternative_ls == lsno) && + (nwpara->routing[i].normal_ls < MAX_LS) ) + { + if (ls_available == TRUE) + mark_alternative_linkset_available(routine); + else + mark_alternative_linkset_unavailable(routine); + add_1dst_to_table(&mtp3.ls[lsno],i,UPDATE_ALS); + + if (!added) + Mtp3AddSortRec(nw,nwpara->routing[i].dpc, i, nwpara->routing[i].opc);//??- + } + hmrt_tfrc_update_routing_tables(i,nw); + + added=0; + } +} + +void update_ls_influence_dst_table(BYTE nw, long dst, WORD place, WORD nls, WORD als, DWORD rc, long opc)//??- +{ + BYTE *routine; + ulong pc_new, rc_new, opc_new; + WORD nls_old; + WORD als_old; + ulong pc_old; + WORD nlsnw; + WORD alsnw; + ull opc_dpc_new=0, opc_dpc_old=0; + + pc_new = dst;//decode_integer((BYTE*)&dst,4); + rc_new = rc;//decode_integer((BYTE*)&rc,4); + opc_new = opc;//decode_integer((BYTE*)&opc,4); + + routine = &mtp3.nw[nw].routine[place]; + + nls_old = mtp3_para->nw[nw].routing[place].normal_ls; + als_old = mtp3_para->nw[nw].routing[place].alternative_ls; + pc_old = mtp3_para->nw[nw].routing[place].dpc; + nlsnw = mtp3_para->ls_pro[nls].nw_id; + alsnw = mtp3_para->ls_pro[als].nw_id; + + if ((pc_old == pc_new) && + (nls_old == nls) && + (als_old == als) && + (mtp3_para->nw[nw].routing[place].rc == rc_new)&& + (mtp3_para->nw[nw].routing[place].opc == opc_new)) + return; +/* + if(opc_new == 0 && pc_new != 0) + { + if(pc_length(nw) == MTP3_24BIT_PC) + opc_new = mtp3_para->nw[nw].opc24; + else + opc_new = mtp3_para->nw[nw].opc14; + + } +*/ + opc_dpc_new = opc_new; + opc_dpc_new = (opc_dpc_new<<32)|pc_new; + opc_dpc_old = mtp3_para->nw[nw].routing[place].opc; + opc_dpc_old = (opc_dpc_old<<32)|pc_old; + if (pc_old > 0) + Mtp3DeleteRecord(opc_dpc_old,nw);//delect this pc from sort table //??- + if (pc_new > 0) + { + if ((nls 0) + mark_normal_linkset_available(routine); + else + mark_normal_linkset_unavailable(routine); + if (nls != nls_old) + add_1dst_to_table(&mtp3.ls[nls],place,UPDATE_NLS); + } + else + mark_normal_linkset_unavailable(routine); + if ((als < MAX_LS) && + (nls < MAX_LS) &&// if one spc doesn't has normal linkset,it can not has alternative linkset + (alsnw == nw)) + { + if (mtp3.ls[als].links_available_t > 0) + mark_alternative_linkset_available(routine); + else + mark_alternative_linkset_unavailable(routine); + if ((als != als_old) || (nls_old >= MAX_LS) ) + { +// printf("renew alternative linkset %d,num=%d\n",als,mtp3.ls[als].influ_dstnum_asALS); + add_1dst_to_table(&mtp3.ls[als],place,UPDATE_ALS); +// printf("renew alternative linkset %d,num=%d\n",als,mtp3.ls[als].influ_dstnum_asALS); + } + } + else + mark_alternative_linkset_unavailable(routine); + if ((mtp3.nw[nw].routine[place] & 0x0f) == 0x0a) + mark_dstSP_inaccessible(routine); + hmrt_tfrc_update_routing_tables(place,nw); + + mtp3_para->nw[nw].routing[place].dpc = pc_new; + mtp3_para->nw[nw].routing[place].opc = opc_new; + mtp3_para->nw[nw].routing[place].normal_ls = nls; + mtp3_para->nw[nw].routing[place].alternative_ls = als; + + if ( (nls_old < MAX_LS) && + (nls_old != nls) ) + del_1dst_from_table(&mtp3.ls[nls_old],place,UPDATE_NLS); + + if ( (als_old < MAX_LS) && + (als_old != als) ) + del_1dst_from_table(&mtp3.ls[als_old],place,UPDATE_ALS); + } + if (mtp3_para->ls_pro[nls].ls_op_pc == pc_new) + mtp3.ls[nls].adjacent_sp_place = place; + mtp3_para->nw[nw].routing[place].dpc = pc_new; + mtp3_para->nw[nw].routing[place].opc = opc_new; + mtp3_para->nw[nw].routing[place].rc = rc_new; +} + +int mtp3_write_para() +{ + int i; + nw_route *ptr=NULL; + ls_para *ls_ptr=NULL; + lk_pro *lk_ptr=NULL; + char tmp_buf[128]={0}; + + mtpfpConf = fopen(mtpconfile,"w"); + if (mtpfpConf == NULL) + return -1; + + fprintf(mtpfpConf,"#MTP3 CONFIGURE FILE\n"); + fprintf(mtpfpConf,"\n"); + fprintf(mtpfpConf,"[system]\n"); + fprintf(mtpfpConf,"mtp3litePort=%04x\n",mtp3_para->mtp3lite_port); + fprintf(mtpfpConf,"\n"); + + fprintf(mtpfpConf,"[internationalNetworkRouting]\n"); + fprintf(mtpfpConf,"opc=%06lx\n", mtp3_para->nw[0].opc14); + fprintf(mtpfpConf,"pclen=%d\n", mtp3_para->nw[0].pc_len); + fprintf(mtpfpConf,"pctype=%d\n", mtp3_para->nw[0].pc_type); + Bcd2Str(tmp_buf, mtp3_para->nw[0].local_acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"localACN=%s\n", tmp_buf); + fprintf(mtpfpConf,"#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn]\n"); + for(i=0; inw[0].routing[i].title[0]==0) + continue; + ptr = &mtp3_para->nw[0].routing[i]; + Bcd2Str(tmp_buf, ptr->acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"[%4d.%s.%06lx.%06lx.%04x.%04x.%08lx.%s]\t\n",i, ptr->title, ptr->dpc, ptr->opc, ptr->normal_ls, ptr->alternative_ls, ptr->rc, tmp_buf); + } + fprintf(mtpfpConf, "\n"); + + fprintf(mtpfpConf,"[internationalSpareNetworkRouting]\n"); + fprintf(mtpfpConf,"opc=%06lx\n", mtp3_para->nw[1].opc14); + fprintf(mtpfpConf,"pclen=%d\n", mtp3_para->nw[1].pc_len); + fprintf(mtpfpConf,"pctype=%d\n", mtp3_para->nw[1].pc_type); + Bcd2Str(tmp_buf, mtp3_para->nw[1].local_acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"localACN=%s\n", tmp_buf); + fprintf(mtpfpConf,"#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn]\n"); + for(i=0; inw[1].routing[i].title[0]==0) + continue; + ptr = &mtp3_para->nw[1].routing[i]; + Bcd2Str(tmp_buf, ptr->acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"[%4d.%s.%06lx.%06lx.%04x.%04x.%08lx.%s]\t\n",i, ptr->title, ptr->dpc, ptr->opc, ptr->normal_ls, ptr->alternative_ls, ptr->rc, tmp_buf); + } + fprintf(mtpfpConf, "\n"); + + fprintf(mtpfpConf,"[nationalNetworkRouting]\n"); + fprintf(mtpfpConf,"opc=%06lx\n", mtp3_para->nw[2].opc14); + fprintf(mtpfpConf,"pclen=%d\n", mtp3_para->nw[2].pc_len); + fprintf(mtpfpConf,"pctype=%d\n", mtp3_para->nw[2].pc_type); + Bcd2Str(tmp_buf, mtp3_para->nw[2].local_acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"localACN=%s\n", tmp_buf); + fprintf(mtpfpConf,"#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn]\n"); + for(i=0; inw[2].routing[i].title[0]==0) + continue; + ptr = &mtp3_para->nw[2].routing[i]; + Bcd2Str(tmp_buf, ptr->acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"[%4d.%s.%06lx.%06lx.%04x.%04x.%08lx.%s]\t\n",i, ptr->title, ptr->dpc, ptr->opc, ptr->normal_ls, ptr->alternative_ls, ptr->rc, tmp_buf); + } + fprintf(mtpfpConf, "\n"); + + fprintf(mtpfpConf,"[nationalSpareNetworkRouting]\n"); + fprintf(mtpfpConf,"opc=%06lx\n", mtp3_para->nw[3].opc14); + fprintf(mtpfpConf,"pclen=%d\n", mtp3_para->nw[3].pc_len); + fprintf(mtpfpConf,"pctype=%d\n", mtp3_para->nw[3].pc_type); + Bcd2Str(tmp_buf, mtp3_para->nw[3].local_acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"localACN=%s\n", tmp_buf); + fprintf(mtpfpConf,"#[index.title.dpc.opc.normal_ls.alter_ls.m3ua_rc.acn]\n"); + for(i=0; inw[3].routing[i].title[0]==0) + continue; + ptr = &mtp3_para->nw[3].routing[i]; + Bcd2Str(tmp_buf, ptr->acn, MAX_ACN_NUM); + fprintf(mtpfpConf,"[%4d.%s.%06lx.%06lx.%04x.%04x.%08lx.%s]\t\n",i, ptr->title, ptr->dpc, ptr->opc, ptr->normal_ls, ptr->alternative_ls, ptr->rc, tmp_buf); + } + fprintf(mtpfpConf, "\n"); + + fprintf(mtpfpConf,"[linkset]\n"); + fprintf(mtpfpConf,"#[index.title.admin.nw.dpc.loop_flag.opc]\n"); + for(i=0; ils_pro[i].title[0]==0) + continue; + ls_ptr = &mtp3_para->ls_pro[i]; + fprintf(mtpfpConf,"[%4d.%s.%02x.%02x.%06lx.%02x.%06lx]\t\n",i, ls_ptr->title, ls_ptr->admin_state, ls_ptr->nw_id, ls_ptr->ls_op_pc, ls_ptr->loopback_opt, ls_ptr->ls_opc); + } + fprintf(mtpfpConf, "\n"); + + fprintf(mtpfpConf,"[link]\n"); + fprintf(mtpfpConf,"#[index.title.admin.type.linkset.slc.hostIP.alterIP.sg.iid.mtp3lite_mode.mtp3lite_remoteIP.inactive.inactive_times]\n"); + for(i=0; ilk[i].title[0]==0) + continue; + lk_ptr = &mtp3_para->lk[i]; + fprintf(mtpfpConf,"[%4d.%s.%02x.%02x.%04x.%02x.%08lx.%08lx.%04x.%02x.%02x.%08lx.%02x.%02x]\t\n",i, lk_ptr->title, lk_ptr->admin_state,\ + lk_ptr->e1_lk_type, lk_ptr->e1_to_linkset, lk_ptr->e1_to_slc, lk_ptr->e1_to_mtp3, lk_ptr->e1_to_alterMTP3,\ + lk_ptr->e1_to_sg, lk_ptr->e1_to_iid, lk_ptr->mtp3lite_apl_mode, lk_ptr->remote_ip, lk_ptr->inactive, lk_ptr->inactive_tm);; + } + fprintf(mtpfpConf, "\n"); + + fprintf(mtpfpConf, "[signalingGateway]\n"); + fprintf(mtpfpConf,"#[index.admin.server.data_ack.sgIP.clientSourceIP.clientSourcePort]\n"); + for (i = 0; i < 256; i++) + { + if(mtp3_para->sg[i].ip==0&&mtp3_para->sg[i].enable==0) + continue; + + fprintf(mtpfpConf, "[%4d.%02X.%02X.%02X.%08X.%08X.%04X.%04X]\t\n",i, mtp3_para->sg[i].enable, mtp3_para->sg[i].server, + mtp3_para->sg[i].data_ack, mtp3_para->sg[i].ip, mtp3_para->sg[i].source_ip, mtp3_para->sg[i].source_port, mtp3_para->sg[i].dst_port); + } + fprintf(mtpfpConf, "\n"); + fclose(mtpfpConf); + return 1; +} + +int mtp3_write_parameter()//??? +{ + int i,j; + int ix4; + + mtpfpConf = fopen(mtpconfile,"w"); + if (mtpfpConf == NULL) + return -1; + + fprintf(mtpfpConf,"#MTP3 CONFIGURE FILE\n"); + fprintf(mtpfpConf,"\n"); + fprintf(mtpfpConf,"[SERVICE NETWORK SP LEN]\n"); + fprintf(mtpfpConf,"[%02x]\n",mtp3_para->nw_pro); + fprintf(mtpfpConf,"\n"); + fprintf(mtpfpConf,"[MTP3LITE TCP PORT]\n"); + fprintf(mtpfpConf,"[%04x]\n",mtp3_para->mtp3lite_port); + fprintf(mtpfpConf,"\n"); + fprintf(mtpfpConf,"[LOCAL SP]\n"); + fprintf(mtpfpConf,"[%06lx]\t[%06lx]\t[%06lx]\t[%06lx]\t\n",mtp3_para->nw[0].opc14, + mtp3_para->nw[1].opc14,mtp3_para->nw[2].opc14,mtp3_para->nw[3].opc14); + fprintf(mtpfpConf,"[%06lx]\t[%06lx]\t[%06lx]\t[%06lx]\t\n",mtp3_para->nw[0].opc24, + mtp3_para->nw[1].opc24,mtp3_para->nw[2].opc24,mtp3_para->nw[3].opc24); + fprintf(mtpfpConf,"\n"); + +/* e1 to linkset */ + fprintf(mtpfpConf,"[LINK ATTRIBUTE]\n"); + for (i=0; i<256; i++) + { + ix4 = i*4; + for (j=0; j<4; j++) + { + fprintf(mtpfpConf,"[%02x.%02x.%08lx.%02x.%02x.%02x.%08lx.%02x.%02x.%08lx]\t",mtp3_para->lk[ix4+j].e1_to_linkset, + mtp3_para->lk[ix4+j].e1_to_slc,mtp3_para->lk[ix4+j].e1_to_mtp3,mtp3_para->lk[ix4+j].e1_lk_type,mtp3_para->lk[ix4+j].e1_to_sg,mtp3_para->lk[ix4+j].e1_to_iid, + mtp3_para->lk[ix4+j].remote_ip,mtp3_para->lk[ix4+j].inactive,mtp3_para->lk[ix4+j].inactive_tm,mtp3_para->lk[ix4+j].e1_to_alterMTP3); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + +/* linkset remote sp */ + fprintf(mtpfpConf,"[LINKSET ATTRIBUTE]\n"); + for (i=0; i<128; i++) + { + ix4 = i*4; + for (j=0; j<4; j++) + { + if (1) + { + char ls_reserved[128]={0}; + char temp[16]; + int k; + for (k=0;k<16;k++) + { + sprintf(temp,"%02x",mtp3_para->ls_pro[ix4+j].ls_reserved[k]); + strcat(ls_reserved,temp); + } + fprintf(mtpfpConf,"[%06lx.%02x.%-16s.%08lx]\t",mtp3_para->ls_pro[ix4+j].ls_op_pc,mtp3_para->ls_pro[ix4+j].admin_state,ls_reserved, mtp3_para->ls_pro[ix4+j].ls_opc); + } + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + +/* SG */ + fprintf(mtpfpConf, "[SG ATTRIBUTES]\n"); + for (i = 0; i < 64; i++) + { + ix4 = i * 4; + + for (j = 0; j < 4; j++) + { + fprintf(mtpfpConf, "[%02X.%02X.%02X.%08X]\t", mtp3_para->sg[ix4+j].enable, mtp3_para->sg[ix4+j].server, + mtp3_para->sg[ix4+j].data_ack, mtp3_para->sg[ix4+j].ip); + } + + fprintf(mtpfpConf, "\n"); + } + fprintf(mtpfpConf, "\n"); + +/* NATIONAL NETWORK SP */ + fprintf(mtpfpConf,"[NATIONAL NETWORK SP]\n"); + for (i=0; i<256; i++) + { + ix4 = i*4; + for (j=0; j<4; j++) + { + fprintf(mtpfpConf,"[%06lx.%02x.%02x.%08lx.%08lx]\t",mtp3_para->nw[2].routing[ix4+j].dpc,mtp3_para->nw[2].routing[ix4+j].normal_ls, + mtp3_para->nw[2].routing[ix4+j].alternative_ls, mtp3_para->nw[2].routing[ix4+j].rc, mtp3_para->nw[2].routing[ix4+j].opc); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + +/* NATIONAL NETWORK SPARE SP */ + fprintf(mtpfpConf,"[NATIONAL NETWORK SPARE SP]\n"); + for (i=0; i<256; i++) + { + ix4 = i*4; + for (j=0; j<4; j++) + { + fprintf(mtpfpConf,"[%06lx.%02x.%02x.%08lx.%08lx]\t",mtp3_para->nw[3].routing[ix4+j].dpc,mtp3_para->nw[3].routing[ix4+j].normal_ls , + mtp3_para->nw[3].routing[ix4+j].alternative_ls , mtp3_para->nw[3].routing[ix4+j].rc, mtp3_para->nw[3].routing[ix4+j].opc); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + +/* INTERNATIONAL NETWORK SP */ + fprintf(mtpfpConf,"[INTERNATIONAL NETWORK SP]\n"); + for (i=0; i<256; i++) + { + ix4 = i*4; + for (j=0; j<4; j++) + { + fprintf(mtpfpConf,"[%06lx.%02x.%02x.%08lx.%08lx]\t",mtp3_para->nw[0].routing[ix4+j].dpc ,mtp3_para->nw[0].routing[ix4+j].normal_ls , + mtp3_para->nw[0].routing[ix4+j].alternative_ls , mtp3_para->nw[0].routing[ix4+j].rc , mtp3_para->nw[0].routing[ix4+j].opc ); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + +/* INTERNATIONAL NETWORK SP */ + fprintf(mtpfpConf,"[INTERNATIONAL NETWORK SPARE SP]\n"); + for (i=0; i<256; i++) + { + ix4 = i*4; + for (j=0; j<4; j++) + { + fprintf(mtpfpConf,"[%06lx.%02x.%02x.%08lx.%08lx]\t",mtp3_para->nw[1].routing[ix4+j].dpc ,mtp3_para->nw[1].routing[ix4+j].normal_ls , + mtp3_para->nw[1].routing[ix4+j].alternative_ls , mtp3_para->nw[1].routing[ix4+j].rc, mtp3_para->nw[1].routing[ix4+j].opc ); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + + fprintf(mtpfpConf,"[LOCAL ACN]\n"); + for(i=0;ilocalAcn[i]); + } + fprintf(mtpfpConf,"\n\n"); + + fprintf(mtpfpConf,"[INTERNATIONAL NETWORK ACN]\n"); + for (i=0; i<256; i++) + { + for (j=0;jnw[0].routing[i].acn[j]); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + + fprintf(mtpfpConf,"[INTERNATIONAL NETWORK SPARE ACN]\n"); + for (i=0; i<256; i++) + { + for (j=0;jnw[1].routing[i].acn[j]); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + + fprintf(mtpfpConf,"[NATIONAL NETWORK ACN]\n"); + for (i=0; i<256; i++) + { + for (j=0;jnw[2].routing[i].acn[j]); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + + fprintf(mtpfpConf,"[NATIONAL NETWORK SPARE ACN]\n"); + for (i=0; i<256; i++) + { + for (j=0;jnw[3].routing[i].acn[j]); + } + fprintf(mtpfpConf,"\n"); + } + fprintf(mtpfpConf,"\n"); + + fclose(mtpfpConf); + return 1; +} + +static int issquare(char c) +{ + if ((c=='[') || (c==']') || (c==' ') || (c=='\t')) + return 1; + return 0; +} + +static int isdot(char c) +{ + if ((c=='.')) + return 1; + return 0; +} + +int ParseLineWithSquare(char *str, char (*row)[128], int maxrow) +{ + char *pstr = str; + int len, index = 0, i; + BOOL black = 0; + + len = strlen(str); + for(i = 0; i < len && index < maxrow; i++) + { + if(issquare(str[i])) + { + if(black == 0) + pstr = str + i + 1; + else + { + str[i] = '\0'; + if(strlen(pstr) > 128) + pstr[127] = 0; + sprintf(row[index++], "%s", pstr); + pstr = str + i + 1; + } + black = 0; + } + else + black = 1; + } + if(black == 1) + { + if(strlen(pstr) > 128) + pstr[127] = 0; + sprintf(row[index++], "%s", pstr); + } + return index; +} + +int ParseLineWithDot(char *str, char (*row)[128], int maxrow) +{ + char *pstr = str; + int len, index = 0, i; + BOOL black = 0; + + len = strlen(str); + for(i = 0; i < len && index < maxrow; i++) + { + if(isdot(str[i])) + { +// if(black == 0) +// pstr = str + i + 1; +// else +// { + str[i] = '\0'; + if(strlen(pstr) > 128) + pstr[127] = 0; + sprintf(row[index++], "%s", pstr); + pstr = str + i + 1; +// } + black = 0; + } + else + black = 1; + } + if(black == 1) + { + if(strlen(pstr) > 128) + pstr[127] = 0; + sprintf(row[index++], "%s", pstr); + } + return index; +} + +int ReadMtp3NetworkPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + + rtn = ParseLineWithSquare(s, LineInfo, 1); + mtp3_para->nw_pro = strtoll(LineInfo[0],NULL,16); + mtp3_para->nw[0].pc_len = mtp3_para->nw_pro&1; + mtp3_para->nw[0].pc_type = (mtp3_para->nw_pro>>4)&1; + mtp3_para->nw[1].pc_len = (mtp3_para->nw_pro>>1)&1; + mtp3_para->nw[1].pc_type = (mtp3_para->nw_pro>>5)&1; + mtp3_para->nw[2].pc_len = (mtp3_para->nw_pro>>2)&1; + mtp3_para->nw[2].pc_type = (mtp3_para->nw_pro>>6)&1; + mtp3_para->nw[3].pc_len = (mtp3_para->nw_pro>>3)&1; + mtp3_para->nw[3].pc_type = (mtp3_para->nw_pro>>7)&1; + return 1; +} + +int ReadMtp3LitePortPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + + rtn = ParseLineWithSquare(s, LineInfo, 1); + mtp3_para->mtp3lite_port = strtoll(LineInfo[0],NULL,16); + + return 1; +} + +int ReadMtp3OPCPara(char *s) +{ + char LineInfo[8][128]; + int rtn; + int instance; + static int Base=0; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four links + if (Base==0) + { + for (instance=0;instance<4;instance++) + { + mtp3_para->nw[instance].opc14 = strtoll(LineInfo[instance],NULL,16); + mtp3_para->nw[instance].opc24 = mtp3_para->nw[instance].opc14; + } + } + else + { +/* for (instance=0;instance<4;instance++) + { + mtp3_para->nw[instance].opc24 = strtoll(LineInfo[instance],NULL,16); + } +*/ + } + + Base++; + + if (Base > 1) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3LinkPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + static int Base=0; + ulong mtp3ip; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four links + for (Instance=0;Instance<4;Instance++) + { + rtn = ParseLineWithDot(LineInfo[Instance],DetailInfo,10); + mtp3_para->lk[Base+Instance].e1_to_linkset = strtoll(DetailInfo[0],NULL,16); + mtp3_para->lk[Base+Instance].e1_to_slc = strtoll(DetailInfo[1],NULL,16); + mtp3ip = strtoll(DetailInfo[2],NULL,16); + if (rtn == 3) + { + if (mtp3ip == 0xff) + mtp3_para->lk[Base+Instance].e1_to_mtp3 = 0xffffffff; + else + mtp3_para->lk[Base+Instance].e1_to_mtp3 = 0x010012ac | ((mtp3ip & 0xff) << 16); + mtp3_para->lk[Base+Instance].e1_lk_type = 0x01; + mtp3_para->lk[Base+Instance].e1_to_alterMTP3 = 0xffffffff; + } + else + { + mtp3_para->lk[Base+Instance].e1_to_mtp3 = mtp3ip; + mtp3_para->lk[Base+Instance].e1_lk_type = strtoll(DetailInfo[3],NULL,16); + mtp3_para->lk[Base+Instance].admin_state = mtp3_para->lk[Base+Instance].e1_lk_type &0x1; + mtp3_para->lk[Base+Instance].e1_lk_type = mtp3_para->lk[Base+Instance].e1_lk_type>>1; + mtp3_para->lk[Base+Instance].e1_to_sg = strtoll(DetailInfo[4],NULL,16); + mtp3_para->lk[Base+Instance].e1_to_iid = strtoll(DetailInfo[5],NULL,16); + mtp3_para->lk[Base+Instance].remote_ip = strtoll(DetailInfo[6],NULL,16); + mtp3_para->lk[Base+Instance].inactive = strtoll(DetailInfo[7],NULL,16); + mtp3_para->lk[Base+Instance].inactive_tm = strtoll(DetailInfo[8],NULL,16); + mtp3_para->lk[Base+Instance].e1_to_alterMTP3 = strtoll(DetailInfo[9],NULL,16); + if(mtp3_para->lk[Base+Instance].e1_to_alterMTP3 == mtp3_para->lk[Base+Instance].e1_to_mtp3) + { + mtp3_para->lk[Base+Instance].e1_to_alterMTP3 = 0xffffffff; + } + if(mtp3_para->lk[Base+Instance].admin_state==1) + mtp3_para->lk[Base+Instance].title[0]='-'; + } +#ifdef _INCLUDE_M2UA + set_m2ua_link(Base+Instance, (BYTE *) &mtp3_para->lk[Base+Instance]); +#endif + } + + Base+=4; + + if (Base >= MAX_LK) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3LinksetPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + static int Base=0; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four linksets + for (Instance=0;Instance<4;Instance++) + { + rtn = ParseLineWithDot(LineInfo[Instance],DetailInfo,4); + mtp3_para->ls_pro[Base+Instance].ls_op_pc = strtoll(DetailInfo[0],NULL,16); + mtp3_para->ls_pro[Base+Instance].nw_id= strtoll(DetailInfo[1],NULL,16); + mtp3_para->ls_pro[Base+Instance].admin_state = (mtp3_para->ls_pro[Base+Instance].nw_id>>2) & 0x1; + mtp3_para->ls_pro[Base+Instance].nw_id = mtp3_para->ls_pro[Base+Instance].nw_id & 0x3; + mtp3_para->ls_pro[Base+Instance].loopback_opt = (mtp3_para->ls_pro[Base+Instance].nw_id>>3) & 0x1; + if (rtn == 3) + Str2Bcd((BYTE *)mtp3_para->ls_pro[Base+Instance].ls_reserved,DetailInfo[2],16); + mtp3_para->ls_pro[Base+Instance].ls_opc = strtoll(DetailInfo[3],NULL,16); + if(mtp3_para->ls_pro[Base+Instance].ls_op_pc != 0) + mtp3_para->ls_pro[Base+Instance].title[0] = '-'; + } + + Base+=4; + + if (Base >= MAX_LS) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3SGPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + static int Base=0; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four linksets + for (Instance=0;Instance<4;Instance++) + { + rtn = ParseLineWithDot(LineInfo[Instance],DetailInfo,4); + mtp3_para->sg[Base+Instance].enable = strtoll(DetailInfo[0],NULL,16); + mtp3_para->sg[Base+Instance].server = strtoll(DetailInfo[1],NULL,16); + mtp3_para->sg[Base+Instance].data_ack = strtoll(DetailInfo[2],NULL,16); + mtp3_para->sg[Base+Instance].ip = strtoll(DetailInfo[3],NULL,16); +#ifdef _INCLUDE_M2UA + set_m2ua_sg(Base+Instance, (BYTE *) &mtp3_para->sg[Base+Instance]); +#endif + } + + Base+=4; + + if (Base >= 256) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3NATPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + static int Base=0; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four linksets + for (Instance=0;Instance<4;Instance++) + { + rtn = ParseLineWithDot(LineInfo[Instance],DetailInfo,5);//4);//3); + mtp3_para->nw[2].routing[Base+Instance].dpc = strtoll(DetailInfo[0],NULL,16); + mtp3_para->nw[2].routing[Base+Instance].normal_ls = strtoll(DetailInfo[1],NULL,16); + mtp3_para->nw[2].routing[Base+Instance].alternative_ls = strtoll(DetailInfo[2],NULL,16); + mtp3_para->nw[2].routing[Base+Instance].rc = strtoll(DetailInfo[3],NULL,16); + mtp3_para->nw[2].routing[Base+Instance].opc = strtoll(DetailInfo[4],NULL,16); + if(mtp3_para->nw[2].routing[Base+Instance].dpc != 0) + mtp3_para->nw[2].routing[Base+Instance].title[0]='-'; + } + + Base+=4; + + if (Base >= MAX_ROUTE) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3NATsPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + static int Base=0; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four linksets + for (Instance=0;Instance<4;Instance++) + { + rtn = ParseLineWithDot(LineInfo[Instance],DetailInfo,5); + mtp3_para->nw[3].routing[Base+Instance].dpc = strtoll(DetailInfo[0],NULL,16); + mtp3_para->nw[3].routing[Base+Instance].normal_ls = strtoll(DetailInfo[1],NULL,16); + mtp3_para->nw[3].routing[Base+Instance].alternative_ls = strtoll(DetailInfo[2],NULL,16); + mtp3_para->nw[3].routing[Base+Instance].rc = strtoll(DetailInfo[3],NULL,16); + mtp3_para->nw[3].routing[Base+Instance].opc = strtoll(DetailInfo[4],NULL,16); + if(mtp3_para->nw[3].routing[Base+Instance].dpc != 0) + mtp3_para->nw[3].routing[Base+Instance].title[0]='-'; + } + + Base+=4; + + if (Base >= MAX_ROUTE) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3INTPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + static int Base=0; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four linksets + for (Instance=0;Instance<4;Instance++) + { + rtn = ParseLineWithDot(LineInfo[Instance],DetailInfo,5); + mtp3_para->nw[0].routing[Base+Instance].dpc = strtoll(DetailInfo[0],NULL,16); + mtp3_para->nw[0].routing[Base+Instance].normal_ls = strtoll(DetailInfo[1],NULL,16); + mtp3_para->nw[0].routing[Base+Instance].alternative_ls = strtoll(DetailInfo[2],NULL,16); + mtp3_para->nw[0].routing[Base+Instance].rc = strtoll(DetailInfo[3],NULL,16); + mtp3_para->nw[0].routing[Base+Instance].opc = strtoll(DetailInfo[4],NULL,16); + if(mtp3_para->nw[0].routing[Base+Instance].dpc != 0) + mtp3_para->nw[0].routing[Base+Instance].title[0]='-'; + } + + Base+=4; + + if (Base >= MAX_ROUTE) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3INTsPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + static int Base=0; + + rtn = ParseLineWithSquare(s, LineInfo, 4);//each line four linksets + for (Instance=0;Instance<4;Instance++) + { + rtn = ParseLineWithDot(LineInfo[Instance],DetailInfo,5); + mtp3_para->nw[1].routing[Base+Instance].dpc = strtoll(DetailInfo[0],NULL,16); + mtp3_para->nw[1].routing[Base+Instance].normal_ls = strtoll(DetailInfo[1],NULL,16); + mtp3_para->nw[1].routing[Base+Instance].alternative_ls = strtoll(DetailInfo[2],NULL,16); + mtp3_para->nw[1].routing[Base+Instance].rc = strtoll(DetailInfo[3],NULL,16); + mtp3_para->nw[1].routing[Base+Instance].opc = strtoll(DetailInfo[4],NULL,16); + if(mtp3_para->nw[1].routing[Base+Instance].dpc != 0) + mtp3_para->nw[1].routing[Base+Instance].title[0]='-'; + } + + Base+=4; + + if (Base >= MAX_ROUTE) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3LocalACNPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + + rtn = ParseLine(s, LineInfo, 1);//each line four linksets + AsciiToBcd(mtp3_para->localAcn,LineInfo[0],MAX_ACN_NUM*2); + memcpy(mtp3_para->nw[0].local_acn, mtp3_para->localAcn,MAX_ACN_NUM); + memcpy(mtp3_para->nw[1].local_acn, mtp3_para->localAcn,MAX_ACN_NUM); + memcpy(mtp3_para->nw[2].local_acn, mtp3_para->localAcn,MAX_ACN_NUM); + memcpy(mtp3_para->nw[3].local_acn, mtp3_para->localAcn,MAX_ACN_NUM); + return 1; +} + +int ReadMtp3INTACNPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + static int Base=0; + + rtn = ParseLine(s, LineInfo, 1);//each line four linksets + AsciiToBcd(mtp3_para->nw[0].routing[Base].acn,LineInfo[0],MAX_ACN_NUM*2); + + Base++; + + if (Base >= 256) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3INTsACNPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + static int Base=0; + + rtn = ParseLine(s, LineInfo, 1);//each line four linksets + AsciiToBcd(mtp3_para->nw[1].routing[Base].acn,LineInfo[0],MAX_ACN_NUM*2); + + Base++; + + if (Base >= 256) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3NATACNPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + static int Base=0; + + rtn = ParseLine(s, LineInfo, 1);//each line four linksets + AsciiToBcd(mtp3_para->nw[2].routing[Base].acn ,LineInfo[0],MAX_ACN_NUM*2); + + Base++; + + if (Base >= 256) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3NATSACNPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + static int Base=0; + + rtn = ParseLine(s, LineInfo, 1);//each line four linksets + AsciiToBcd(mtp3_para->nw[3].routing[Base].acn ,LineInfo[0],MAX_ACN_NUM*2); + + Base++; + + if (Base >= 256) + { + Base = 0; + return 1; + } + return 0; +} + +int ReadMtp3SystemPara(char *s) +{ + char LineInfo[1][128]; + int rtn; + + rtn = ParseLine(s, LineInfo, 1); + if(strstr(LineInfo[0], "mtp3litePort=")!=NULL) + mtp3_para->mtp3lite_port = strtol(&LineInfo[0][13],NULL,16); + + return 1; +} + +int ReadMtp3IntNWPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + u8 nw = 0; + nw_route *ptr; + + if(strstr(s, "opc=")!=NULL) + { + mtp3_para->nw[nw].opc14 = strtoll(s+4, NULL, 16); + mtp3_para->nw[nw].opc24 = mtp3_para->nw[nw].opc14; + return 0; + } + else if(strstr(s, "pclen=")!=NULL) + { + mtp3_para->nw[nw].pc_len = strtoll(s+6, NULL, 16); + return 0; + } + else if(strstr(s, "pctype=")!=NULL) + { + mtp3_para->nw[nw].pc_type = strtoll(s+7, NULL, 16); + return 0; + } + else if(strstr(s, "localACN=")!=NULL) + { + Str2Bcd(mtp3_para->nw[nw].local_acn, s+9, MAX_ACN_NUM); + return 0; + } + + //route unit + rtn = ParseLineWithSquare(s, LineInfo, 1);//each line four linksets + rtn = ParseLineWithDot(LineInfo[0],DetailInfo,8); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= MAX_ROUTE) + { + printf("mtp3 int nw route para index error!\n"); + return 0; + } + ptr = &mtp3_para->nw[nw].routing[Instance]; + strncpy(ptr->title, DetailInfo[1], 16); + ptr->dpc = strtoll(DetailInfo[2],NULL,16); + ptr->opc = strtoll(DetailInfo[3],NULL,16); + ptr->normal_ls = strtoll(DetailInfo[4],NULL,16); + ptr->alternative_ls = strtoll(DetailInfo[5],NULL,16); + ptr->rc = strtoll(DetailInfo[6],NULL,16); + AsciiToBcd(ptr->acn ,DetailInfo[7],MAX_ACN_NUM*2); + if(ptr->dpc != 0 && ptr->title[0]==0) + ptr->title[0]='-'; + return 0; +} + +int ReadMtp3IntsNWPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + u8 nw = 1; + nw_route *ptr; + + if(strstr(s, "opc=")!=NULL) + { + mtp3_para->nw[nw].opc14 = strtoll(s+4, NULL, 16); + mtp3_para->nw[nw].opc24 = mtp3_para->nw[nw].opc14; + return 0; + } + else if(strstr(s, "pclen=")!=NULL) + { + mtp3_para->nw[nw].pc_len = strtoll(s+6, NULL, 16); + return 0; + } + else if(strstr(s, "pctype=")!=NULL) + { + mtp3_para->nw[nw].pc_type = strtoll(s+7, NULL, 16); + return 0; + } + else if(strstr(s, "localACN=")!=NULL) + { + Str2Bcd(mtp3_para->nw[nw].local_acn, s+9, MAX_ACN_NUM); + return 0; + } + //route unit + rtn = ParseLineWithSquare(s, LineInfo, 1);//each line four linksets + rtn = ParseLineWithDot(LineInfo[0],DetailInfo,8); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= MAX_ROUTE) + { + printf("mtp3 ints nw route para index error!\n"); + return 0; + } + ptr = &mtp3_para->nw[nw].routing[Instance]; + strncpy(ptr->title, DetailInfo[1], 16); + ptr->dpc = strtoll(DetailInfo[2],NULL,16); + ptr->opc = strtoll(DetailInfo[3],NULL,16); + ptr->normal_ls = strtoll(DetailInfo[4],NULL,16); + ptr->alternative_ls = strtoll(DetailInfo[5],NULL,16); + ptr->rc = strtoll(DetailInfo[6],NULL,16); + AsciiToBcd(ptr->acn ,DetailInfo[7],MAX_ACN_NUM*2); + if(ptr->dpc != 0 && ptr->title[0]==0) + ptr->title[0]='-'; + return 0; +} + + +int ReadMtp3NaNWPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + u8 nw = 2; + nw_route *ptr; + + if(strstr(s, "opc=")!=NULL) + { + mtp3_para->nw[nw].opc14 = strtoll(s+4, NULL, 16); + mtp3_para->nw[nw].opc24 = mtp3_para->nw[nw].opc14; + return 0; + } + else if(strstr(s, "pclen=")!=NULL) + { + mtp3_para->nw[nw].pc_len = strtoll(s+6, NULL, 16); + return 0; + } + else if(strstr(s, "pctype=")!=NULL) + { + mtp3_para->nw[nw].pc_type = strtoll(s+7, NULL, 16); + return 0; + } + else if(strstr(s, "localACN=")!=NULL) + { + Str2Bcd(mtp3_para->nw[nw].local_acn, s+9, MAX_ACN_NUM); + return 0; + } + + //route unit + rtn = ParseLineWithSquare(s, LineInfo, 1);//each line four linksets + rtn = ParseLineWithDot(LineInfo[0],DetailInfo,8); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= MAX_ROUTE) + { + printf("mtp3 na nw route para index error!\n"); + return 0; + } + ptr = &mtp3_para->nw[nw].routing[Instance]; + strncpy(ptr->title, DetailInfo[1], 16); + ptr->dpc = strtoll(DetailInfo[2],NULL,16); + ptr->opc = strtoll(DetailInfo[3],NULL,16); + ptr->normal_ls = strtoll(DetailInfo[4],NULL,16); + ptr->alternative_ls = strtoll(DetailInfo[5],NULL,16); + ptr->rc = strtoll(DetailInfo[6],NULL,16); + AsciiToBcd(ptr->acn ,DetailInfo[7],MAX_ACN_NUM*2); + if(ptr->dpc != 0 && ptr->title[0]==0) + ptr->title[0]='-'; + return 0; +} + + +int ReadMtp3NasNWPara(char *s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + u8 nw = 3; + nw_route *ptr; + + if(strstr(s, "opc=")!=NULL) + { + mtp3_para->nw[nw].opc14 = strtoll(s+4, NULL, 16); + mtp3_para->nw[nw].opc24 = mtp3_para->nw[nw].opc14; + return 0; + } + else if(strstr(s, "pclen=")!=NULL) + { + mtp3_para->nw[nw].pc_len = strtoll(s+6, NULL, 16); + return 0; + } + else if(strstr(s, "pctype=")!=NULL) + { + mtp3_para->nw[nw].pc_type = strtoll(s+7, NULL, 16); + return 0; + } + else if(strstr(s, "localACN=")!=NULL) + { + Str2Bcd(mtp3_para->nw[nw].local_acn, s+9, MAX_ACN_NUM); + return 0; + } + + //route unit + rtn = ParseLineWithSquare(s, LineInfo, 1);//each line four linksets + rtn = ParseLineWithDot(LineInfo[0],DetailInfo,8); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= MAX_ROUTE) + { + printf("mtp3 na nw route para index error!\n"); + return 0; + } + ptr = &mtp3_para->nw[nw].routing[Instance]; + strncpy(ptr->title, DetailInfo[1], 16); + ptr->dpc = strtoll(DetailInfo[2],NULL,16); + ptr->opc = strtoll(DetailInfo[3],NULL,16); + ptr->normal_ls = strtoll(DetailInfo[4],NULL,16); + ptr->alternative_ls = strtoll(DetailInfo[5],NULL,16); + ptr->rc = strtoll(DetailInfo[6],NULL,16); + AsciiToBcd(ptr->acn ,DetailInfo[7],MAX_ACN_NUM*2); + if(ptr->dpc != 0 && ptr->title[0]==0) + ptr->title[0]='-'; + return 0; +} + +int ReadMtp3LsPara(char * s) +{ + char LineInfo[8][128]; + char DetailInfo[10][128]; + int rtn; + int Instance; + ls_para *ptr; + + rtn = ParseLineWithSquare(s, LineInfo, 1);//each line four linksets + rtn = ParseLineWithDot(LineInfo[0],DetailInfo, 7); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= MAX_LS) + { + printf("mtp3 na nw route para index error!\n"); + return 0; + } + ptr = &mtp3_para->ls_pro[Instance]; + strncpy(ptr->title, DetailInfo[1], 16); + ptr->admin_state = strtoll(DetailInfo[2],NULL,16); + ptr->nw_id = strtoll(DetailInfo[3],NULL,16); + ptr->ls_op_pc = strtoll(DetailInfo[4],NULL,16); + ptr->loopback_opt = strtoll(DetailInfo[5],NULL,16); + ptr->ls_opc = strtoll(DetailInfo[6],NULL,16); + if(ptr->title[0]==0 && ptr->ls_op_pc != 0) + ptr->title[0] = '-'; + return 0; +} + +int ReadMtp3LkPara(char * s) +{ + char LineInfo[8][128]; + char DetailInfo[15][128]; + int rtn; + int Instance; + lk_pro *ptr; + + rtn = ParseLineWithSquare(s, LineInfo, 1);//each line four linksets + rtn = ParseLineWithDot(LineInfo[0],DetailInfo, 14); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= MAX_LK) + { + printf("mtp3 na nw route para index error!\n"); + return 0; + } + ptr = &mtp3_para->lk[Instance]; + strncpy(ptr->title, DetailInfo[1], 16); + ptr->admin_state = strtoll(DetailInfo[2],NULL,16); + ptr->e1_lk_type = strtoll(DetailInfo[3],NULL,16); + ptr->e1_to_linkset = strtoll(DetailInfo[4],NULL,16); + ptr->e1_to_slc = strtoll(DetailInfo[5],NULL,16); + ptr->e1_to_mtp3 = strtoll(DetailInfo[6],NULL,16); + ptr->e1_to_alterMTP3 = strtoll(DetailInfo[7],NULL,16); + ptr->e1_to_sg = strtoll(DetailInfo[8],NULL,16); + ptr->e1_to_iid = strtoll(DetailInfo[9],NULL,16); + ptr->mtp3lite_apl_mode = strtoll(DetailInfo[10],NULL,16); + ptr->remote_ip = strtoll(DetailInfo[11],NULL,16); + ptr->inactive = strtoll(DetailInfo[12],NULL,16); + ptr->inactive_tm = strtoll(DetailInfo[13],NULL,16); +#ifdef _INCLUDE_M2UA + set_m2ua_link(Instance, (BYTE *) &mtp3_para->lk[Instance]); +#endif + if(ptr->admin_state != 0 && ptr->title[0]==0) + ptr->title[0]='-'; + + return 0; +} + +int ReadMtp3SgPara(char * s) +{ + char LineInfo[10][128]={{0}, {0}}; + char DetailInfo[10][128]={{0}, {0}}; + int rtn; + int Instance; + sg_para *ptr; + + rtn = ParseLineWithSquare(s, LineInfo, 1);//each line four linksets + rtn = ParseLineWithDot(LineInfo[0],DetailInfo, 8); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= 256) + { + printf("mtp3 na nw route para index error!\n"); + return 0; + } + ptr = &mtp3_para->sg[Instance]; + ptr->enable = strtoll(DetailInfo[1],NULL,16); + ptr->server = strtoll(DetailInfo[2],NULL,16); + ptr->data_ack = strtoll(DetailInfo[3],NULL,16); + ptr->ip = strtoll(DetailInfo[4],NULL,16); + ptr->source_ip = strtoll(DetailInfo[5],NULL,16); + ptr->source_port = strtoll(DetailInfo[6],NULL,16); + ptr->dst_port = strtoll(DetailInfo[7],NULL,16); +#ifdef _INCLUDE_M2UA + set_m2ua_sg(Instance, (BYTE *) &mtp3_para->sg[Instance]); +#endif + return 0; +} + +void mtp3_readpara_from_disk() +{ + char s[1024]={0}; + int len; + BYTE state = 0; + FILE *fp; + + fp = fopen(mtpconfile,"rb"); + + if (fp==NULL) + { + printf("mtp3 config file %s missed!!\n",mtpconfile); + return; + } + + s[0] = 0; + while ( fgets(s,1024,fp) != (char *)0 ) + { + if ( (int *)strchr(s,'#') != NULL ) continue; + if ( (len=strlen(s))==0 ) continue; + if(s[0]=='\n')continue; + + if(strstr(s,"[system]") != NULL) + { + state = 21; + continue; + } + else if(strstr(s,"[internationalNetworkRouting]") != NULL) + { + state = 22; + continue; + } + else if(strstr(s,"[internationalSpareNetworkRouting]") != NULL) + { + state = 23; + continue; + } + else if(strstr(s,"[nationalNetworkRouting]") != NULL) + { + state = 24; + continue; + } + else if(strstr(s,"[nationalSpareNetworkRouting]") != NULL) + { + state = 25; + continue; + } + else if(strstr(s,"[linkset]") != NULL) + { + state = 26; + continue; + } + else if(strstr(s,"[link]") != NULL) + { + state = 27; + continue; + } + else if(strstr(s,"[signalingGateway]") != NULL) + { + state = 28; + continue; + } + else if ( strstr(s,"[SERVICE NETWORK SP LEN]") != NULL ) + { + state = 1; + continue; + } + else if ( strstr(s,"[MTP3LITE TCP PORT]") != NULL ) + { + state = 2; + continue; + } + else if ( strstr(s,"[LOCAL SP]") != NULL ) + { + state = 3; + continue; + } + + else if ( strstr(s,"[LINK ATTRIBUTE]") != NULL ) + { + state = 4; + continue; + } + else if ( strstr(s,"[LINKSET ATTRIBUTE]") != NULL ) + { + state = 5; + continue; + } + else if ( strstr(s,"[SG ATTRIBUTES]") != NULL ) + { + state = 6; + continue; + } + else if ( strstr(s,"[NATIONAL NETWORK SP]") != NULL ) + { + state = 7; + continue; + } + else if ( strstr(s,"[NATIONAL NETWORK SPARE SP]") != NULL ) + { + state = 8; + continue; + } + else if ( strstr(s,"[INTERNATIONAL NETWORK SP]") != NULL ) + { + state = 9; + continue; + } + else if ( strstr(s,"[INTERNATIONAL NETWORK SPARE SP]") != NULL ) + { + state = 10; + continue; + } + else if ( strstr(s,"[LOCAL ACN]") != NULL ) + { + state = 11; + continue; + } + else if ( strstr(s,"[INTERNATIONAL NETWORK ACN]") != NULL ) + { + state = 12; + continue; + } + else if ( strstr(s,"[INTERNATIONAL NETWORK SPARE ACN]") != NULL ) + { + state = 13; + continue; + } + else if ( strstr(s,"[NATIONAL NETWORK ACN]") != NULL ) + { + state = 14; + continue; + } + else if ( strstr(s,"[NATIONAL NETWORK SPARE ACN]") != NULL ) + { + state = 15; + continue; + } + + + switch (state) + { + case 1: + if (ReadMtp3NetworkPara(s)) + state = 0; + break; + case 2: + if (ReadMtp3LitePortPara(s)) + state = 0; + break; + case 3: + if (ReadMtp3OPCPara(s)) + state = 0; + break; + case 4: + if (ReadMtp3LinkPara(s)) + state = 0; + break; + case 5: + if (ReadMtp3LinksetPara(s)) + state = 0; + break; + case 6: + if (ReadMtp3SGPara(s)) + state = 0; + break; + case 7: + if (ReadMtp3NATPara(s)) + state = 0; + break; + case 8: + if (ReadMtp3NATsPara(s)) + state = 0; + break; + case 9: + if (ReadMtp3INTPara(s)) + state = 0; + break; + case 10: + if (ReadMtp3INTsPara(s)) + state = 0; + break; + case 11: + if (ReadMtp3LocalACNPara(s)) + state = 0; + break; + case 12: + if (ReadMtp3INTACNPara(s)) + state = 0; + break; + case 13: + if (ReadMtp3INTsACNPara(s)) + state = 0; + break; + case 14: + if (ReadMtp3NATACNPara(s)) + state = 0; + break; + case 15: + if (ReadMtp3NATSACNPara(s)) + state = 0; + break; + case 21: + if(ReadMtp3SystemPara( s)) + state = 0; + break; + case 22: + if(ReadMtp3IntNWPara(s)) + state = 0; + break; + case 23: + if(ReadMtp3IntsNWPara(s)) + state = 0; + break; + case 24: + if(ReadMtp3NaNWPara(s)) + state = 0; + break; + case 25: + if(ReadMtp3NasNWPara(s)) + state = 0; + break; + case 26: + if(ReadMtp3LsPara(s)) + state = 0; + break; + case 27: + if(ReadMtp3LkPara(s)) + state = 0; + break; + case 28: + if(ReadMtp3SgPara(s)) + state = 0; + break; + default: + break; + } + } + + fclose(fp); +} + +void mtp3_setlink_to_IDLE(WORD link) +{ + WORD oldls; + BYTE oldslc; + ulong oldip; + BYTE oldtp; + + oldls = mtp3_para->lk[link].e1_to_linkset; + oldslc = mtp3_para->lk[link].e1_to_slc; + oldip = mtp3_para->lk[link].e1_to_mtp3; + oldtp = mtp3_para->lk[link].e1_lk_type; + + if (mtp3ObjState.link_l3_state[link] == AVAILABLE) + { + + if ((MTP3_LINK_TYPE(link) == LKTYPE_MTP3_LITE) && // Not MTP3LITE + (mtp3_para->lk[link].admin_state& 0x01)) // Enabled + {//sccp lite link + deactive_mtp3lite_lk(link); + } + else if((MTP3_LINK_TYPE(link) == LKTYPE_M3UA) && // Not M3UA + (mtp3_para->lk[link].admin_state& 0x01)) // Enabled + {//sccp lite link + deactive_m3ua_lk(link); + } + else + { + mtp3ObjInput.sltc_input[link] = SLTC_STOP; + sltc_proc(link); + init_lsac_state[link] = TRUE; + lsac_proc(link); + init_tlac_state[link] = TRUE; + tlac_proc(link); + + if (mtp3ObjState.link_l3_state[link] == AVAILABLE) + otherMTP3_managed_link_unavailable(link); + mtp3ObjState.link_l2_state[link] = UNAVAILABLE; + mtp3ObjState.link_l3_state[link] = UNAVAILABLE; + mtp3ObjState.link_enable_sent_flag[link] = 0; + } + } + + if (mtp3ObjState.lk_configured[link] == PARA_CONFIGURED) + { + mtp3.ls[oldls].linksNum_configured--; + ls_slc[oldls*16+oldslc] = 0xff; + update_sls_to_link_table(oldls); + } + mtp3ObjState.lk_configured[link] = PARA_NOT_CONFIGURED; + +// printf("link %d update para,new ls=%d,new slc = %d,new ip=%lx\n",link,newls,newslc,newip); +} + +int mtp_setmib(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD datalen) +{ + int instance; + ulong pc; + BYTE command; + int ls; + int slc; + ulong ip; + ulong ip1; + int tp; + int i; + ulong oldpc, opc; + WORD old_lsnw; + WORD new_lsnw; + ulong oldpar, rc; + BOOL para_changed=0; + + if ( oidlen < MTP3_OID_LEN) + { + printf("set failed,object id length not correct\n"); + return -1; + } + + mtp3EnableSaveFlag(); + + if ( oid[MTP3_OID_LEN] == 2 )/* configure */ + { + switch (oid[MTP3_OID_LEN+1]) + { + case 2: + case 3: + case 4: + case 5: + switch(oid[MTP3_OID_LEN+2]) + { + case 1: + oldpar = mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].opc14; + SET_INTEGER(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].opc14); + mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].opc24 = mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].opc14; + if (oldpar != mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].opc14) + { + mtp3_reset_sccp(); + mtp3_delete_opc(oid[MTP3_OID_LEN+1]-2,oldpar); + } + return datalen; + case 2: + SET_INTEGER(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].pc_len); + mtp3_reset_sccp(); + return datalen; + case 3: + SET_INTEGER(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].pc_type); + mtp3_reset_sccp(); + return datalen; + case 4: + SET_OPAQUE(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].local_acn, MAX_ACN_NUM); + return datalen; + default: + break; + } + break; + default: + break; + } + + switch (oid[MTP3_OID_LEN+1]) + { + case 1:/* sp/stp */ + break; + case 2:/* 14/24bit (for four service networks) */ + oldpar = mtp3_para->nw_pro; + mtp3_para->nw_pro = decode_integer(pdata,datalen); + if (oldpar != mtp3_para->nw_pro) + mtp3_reset_sccp(); + return 1; + case 3:/* opc */ + memcpy(&pc,pdata,4); + pc = pc << 8; + switch (oid[MTP3_OID_LEN+2]) + { + case 1: + oldpar = mtp3_para->nw[0].opc14; + mtp3_para->nw[0].opc14 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[0].opc14) + { + mtp3_reset_sccp(); + mtp3_delete_opc(0, mtp3_para->nw[0].opc14); + } + return 3; + case 2: + oldpar = mtp3_para->nw[1].opc14; + mtp3_para->nw[1].opc14 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[1].opc14) + { + mtp3_reset_sccp(); + mtp3_delete_opc(1, mtp3_para->nw[1].opc14); + } + return 3; + case 3: + oldpar = mtp3_para->nw[2].opc14; + mtp3_para->nw[2].opc14 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[2].opc14) + { + mtp3_reset_sccp(); + mtp3_delete_opc(2, mtp3_para->nw[2].opc14); + } + return 3; + case 4: + oldpar = mtp3_para->nw[3].opc14; + mtp3_para->nw[3].opc14 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[3].opc14) + { + mtp3_reset_sccp(); + mtp3_delete_opc(3, mtp3_para->nw[3].opc14); + } + return 3; + case 5: + oldpar = mtp3_para->nw[0].opc24; + mtp3_para->nw[0].opc24 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[0].opc24) + { + mtp3_reset_sccp(); + mtp3_delete_opc(0, mtp3_para->nw[0].opc24); + } + return 3; + case 6: + oldpar = mtp3_para->nw[1].opc24; + mtp3_para->nw[1].opc24 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[1].opc24) + { + mtp3_reset_sccp(); + mtp3_delete_opc(1, mtp3_para->nw[1].opc24); + } + return 3; + case 7: + oldpar = mtp3_para->nw[2].opc24; + mtp3_para->nw[2].opc24 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[2].opc24) + { + mtp3_reset_sccp(); + mtp3_delete_opc(2, mtp3_para->nw[2].opc24); + } + return 3; + case 8: + oldpar = mtp3_para->nw[3].opc24; + mtp3_para->nw[3].opc24 = decode_integer((BYTE*)&pc,4); + if (oldpar != mtp3_para->nw[3].opc24) + { + mtp3_reset_sccp(); + mtp3_delete_opc(3, mtp3_para->nw[3].opc24); + } + return 3; + default: + return -1; + } + break; + case 4:/* linkset */ + instance = oid[MTP3_OID_LEN+3]; + if (instance > 127) + return -1; + switch (oid[MTP3_OID_LEN+2]) + { + case 1: + oldpc = mtp3_para->ls_pro[instance].ls_op_pc; + old_lsnw = mtp3_para->ls_pro[instance].nw_id; + new_lsnw = pdata[3] & 3; + memcpy(&pc,pdata,4); + memcpy(&opc, &pdata[4], 4); + pc = pc << 8; + mtp3_para->ls_pro[instance].ls_op_pc = decode_integer((BYTE*)&pc,4); + /* linkset adjacent sp */ + mtp3_para->ls_pro[instance].nw_id= pdata[3]; + memcpy(&mtp3_para->ls_pro[instance].ls_reserved,&pdata[4],16); + if (old_lsnw != new_lsnw) + { + change_the_whole_ls(instance,old_lsnw,new_lsnw); + } + if ((oldpc != mtp3_para->ls_pro[instance].ls_op_pc) || + (old_lsnw != new_lsnw) ) + { + pc = mtp3_para->ls_pro[instance].ls_op_pc; + for (i=0;inw[new_lsnw].routing[i].dpc == pc && mtp3_para->nw[new_lsnw].routing[i].opc == opc)//??? + { + mtp3.ls[instance].adjacent_sp_place = i; + return 4; + } + } +// printf("not found pc in table\n"); + mtp3.ls[instance].adjacent_sp_place = 0xffff; + } + return 20; + default: + return -1; + } + break; + case 5:/* link */ + instance = oid[MTP3_OID_LEN+3]; + switch (oid[MTP3_OID_LEN+2]) + { + case 1:/* e1 to linkset */ + ls = pdata[0]; + slc = pdata[1]; + memcpy(&ip,&pdata[2],4); + memcpy(&ip1,&pdata[15],4); +// ip = pdata[2]; + tp = pdata[6]; + if(ip == ip1 && ip1 != 0xffffff) + {//ip can not be same as ip1 + ip1 = 0xffffffff; + memcpy(&pdata[15], &ip1, 4); + } + + if (ls!=mtp3_para->lk[instance].e1_to_linkset || slc!=mtp3_para->lk[instance].e1_to_slc + || ip!=mtp3_para->lk[instance].e1_to_mtp3 || ip1!=mtp3_para->lk[instance].e1_to_alterMTP3 + || tp != mtp3_para->lk[instance].e1_lk_type) + { + mtp3_setlink_to_IDLE(instance); + para_changed = 1; + } + if (datalen<19) + memcpy((BYTE *)&mtp3_para->lk[instance].e1_to_linkset, pdata, 15); + else + memcpy((BYTE *)&mtp3_para->lk[instance].e1_to_linkset, pdata, 19); + mtp3ObjState.link_type[instance] = mtp3_para->lk[instance].e1_lk_type; + if (para_changed) + { + if (update_ls_slc_table(instance) == 1) + { + update_sls_to_link_table(ls); + MTP3_LinkIP_List(mtp3_para->lk[instance].e1_to_mtp3,1); + MTP3_LinkIP_List(mtp3_para->lk[instance].e1_to_alterMTP3,1); + } + } +#ifdef _INCLUDE_M2UA + set_m2ua_link(instance & 0xff, pdata); +#endif + return 19; + case 2:/* link command */ + mtp3ObjState.lk_command[instance] = pdata[0]; + + if (mtp3ObjState.lk_mtp3[instance] != mtp3_localip) + return 1; + if (MTP3_LINK_TYPE(instance) == LKTYPE_MTP3_LITE) + { + if (pdata[0]==0)//disable + deactive_mtp3lite_lk(instance); + + return 1; + } + else if (MTP3_LINK_TYPE(instance) == LKTYPE_M3UA) + { + if (pdata[0]==0)//disable + deactive_m3ua_lk(instance); + + return 1; + } + else + { + command = pdata[0]; + if (command < 2) + { + mtp3ObjInput.lsac_input_from_mgmt[instance] = command; + return 1; + } + else if (command < 4) + { + mtp3ObjInput.tlac_input_from_mgmt[instance] = command - 1; + return 1; + } + else + return -1; + } + case 3:/* MTP3LITE TCP Port */ + mtp3_para->mtp3lite_port = pdata[1]; + mtp3_para->mtp3lite_port = (mtp3_para->mtp3lite_port << 8) | pdata[0]; + return 2; + default: + return -1; + } + break; + case 6:/* routine table */ + instance = oid[MTP3_OID_LEN+3]; + memcpy(&pc,pdata,4); + memcpy(&rc,&pdata[5],4); + pc = pc << 8; + memcpy(&opc, &pdata[9], 4); + if ((oid[MTP3_OID_LEN+2] > 4) || (oid[MTP3_OID_LEN+2] < 1)) + return -1; + update_ls_influence_dst_table((oid[MTP3_OID_LEN+2]-1),pc,instance,pdata[3],pdata[4], rc, opc); + return 13; + case 7:/* dpc->acn */ + instance = oid[MTP3_OID_LEN+3]; + + if (oid[MTP3_OID_LEN+2] == 1) + { + memcpy(mtp3_para->localAcn,pdata,MAX_ACN_NUM); + } + else if ((oid[MTP3_OID_LEN+2] > 1) && (oid[MTP3_OID_LEN+2] < 6)) + { + memcpy(mtp3_para->nw[oid[MTP3_OID_LEN+2]-2].routing[instance].acn,pdata,MAX_ACN_NUM); + } + else + return -1; + return MAX_ACN_NUM; + case 8:/* timer */ + instance = oid[MTP3_OID_LEN+3]; + switch (oid[MTP3_OID_LEN+2]) + { + case 1:/* link timer */ + memcpy(&mtp3_para->lt[instance].t1,pdata,10); + update_timer(instance); + return 10; + default: + return -1; + } + return -1; + case 9:/* sg */ + instance = oid[MTP3_OID_LEN+2]; + memcpy(&mtp3_para->sg[instance],pdata,7); +#ifdef _INCLUDE_M2UA + set_m2ua_sg(instance & 0xff, pdata); + return 7; +#else + return 7; +#endif + default: + return -1; + } + return -1; + } + else if (oid[MTP3_OID_LEN] == 3)/* status */ + { + switch (oid[MTP3_OID_LEN+1]) + { + case 7: + case 8:/* command */ + switch (pdata[0]) + { + case 1: + reset_mtp3(); + break; + case 2: + printf("save parameter\n"); + return mtp3_write_para(); + break; + case 3://load data + mtp3_reload_data(); + break; + default: + break; + } + return 1; + default: + return -1; + } + } + else + return -1; +} + +void mtp3_data_reverse(BYTE *pdata,BYTE *csta,BYTE len,BYTE data_type) +{ + int i; + int j=0; + + for (i=0; i 15) + temp = 15; + mtp3_measure.measure[portion_num].lk_measure1[instance][i] = temp; + } + break; + case 1: + temp = mtp3_measure.measure[portion_num].ls_measure[instance][0]; + temp = (temp + 3) / 6; + if (temp > 15) + temp = 15; + mtp3_measure.measure[portion_num].ls_measure[instance][0] = temp; + temp = mtp3_measure.measure[portion_num].ls_measure[instance][6]; + temp = (temp + 3) / 6; + if (temp > 15) + temp = 15; + mtp3_measure.measure[portion_num].ls_measure[instance][6] = temp; + break; + default: + break; + } +} + +int mtp_getmib(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype) +{ +/* 1.3.6.1.4.1.1373.1.1.2.2.2.2 */ + unsigned int instance; + BYTE portion_num=0; + ulong timestamp; + ulong get_rc=0; + int datalen=-1; + + if ( oidlen < 12 ) + { + printf("get fail,object id not correct\n"); + return -1; + } + if ( oid[MTP3_OID_LEN] == 2 )/* configure */ + { + switch (oid[MTP3_OID_LEN+1]) + { + case 2: + case 3: + case 4: + case 5: + switch(oid[MTP3_OID_LEN+2]) + { + case 1: + GET_INTEGER(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].opc14); + return datalen; + case 2: + GET_INTEGER(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].pc_len); + return datalen; + case 3: + GET_INTEGER(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].pc_type); + return datalen; + case 4: + GET_OPAQUE(mtp3_para->nw[oid[MTP3_OID_LEN+1]-2].local_acn, MAX_ACN_NUM); + return datalen; + default: + break; + } + break; + default: + break; + } + switch (oid[MTP3_OID_LEN+1]) + { + case 1:/* sp/stp */ + return -1; + case 2:/* 14/24bit (for four service networks) */ + *vartype = 4; + return mtp_encode_integer(pdata,mtp3_para->nw_pro,1); + case 3:/* opc */ + *vartype = 4; + switch (oid[MTP3_OID_LEN+2]) + { + case 1: + return mtp_encode_integer(pdata,mtp3_para->nw[0].opc14,4); + case 2: + return mtp_encode_integer(pdata,mtp3_para->nw[1].opc14,4); + case 3: + return mtp_encode_integer(pdata,mtp3_para->nw[2].opc14,4); + case 4: + return mtp_encode_integer(pdata,mtp3_para->nw[3].opc14,4); + case 5: + return mtp_encode_integer(pdata,mtp3_para->nw[0].opc24,4); + case 6: + return mtp_encode_integer(pdata,mtp3_para->nw[1].opc24,4); + case 7: + return mtp_encode_integer(pdata,mtp3_para->nw[2].opc24,4); + case 8: + return mtp_encode_integer(pdata,mtp3_para->nw[3].opc24,4); + default: + return -1; + } + return -1; + case 4:/* linkset */ + instance = oid[MTP3_OID_LEN+3]; + *vartype = 4; + switch (oid[MTP3_OID_LEN+2]) + { + case 1: + mtp_encode_integer(pdata,mtp3_para->ls_pro[instance].ls_op_pc,4); + pdata[3] = mtp3_para->ls_pro[instance].nw_id; + memcpy(&pdata[4],&mtp3_para->ls_pro[instance].ls_reserved,16); + return 20; + /* linkset adjacent sp */ + default: + return -1; + } + return -1; + case 5:/* link */ + instance = oid[MTP3_OID_LEN+3]; + *vartype = 4; + switch (oid[MTP3_OID_LEN+2]) + { + case 1:/* e1 to linkset */ + memcpy(pdata,&mtp3_para->lk[instance].e1_to_linkset,19); + return 19; + case 2: + memcpy(pdata,&mtp3ObjState.lk_command[instance],1); + return 1; + case 3: + pdata[0] = mtp3_para->mtp3lite_port; + pdata[1] = mtp3_para->mtp3lite_port >> 8; + return 2; + default: + return -1; + } + return -1; + case 6:/* internation network routine table */ + instance = oid[MTP3_OID_LEN+3]; + *vartype = 4; + switch (oid[MTP3_OID_LEN+2]) + { + case 1: + mtp_encode_integer(pdata,mtp3_para->nw[0].routing[instance].dpc,4); + memcpy(&pdata[3],&mtp3_para->nw[0].routing[instance].normal_ls,1); + memcpy(&pdata[4],&mtp3_para->nw[0].routing[instance].alternative_ls,1); + get_rc = htonl(mtp3_para->nw[0].routing[instance].rc); + memcpy(&pdata[5], &get_rc, 4); + get_rc = htonl(mtp3_para->nw[0].routing[instance].opc); + memcpy(&pdata[9], &get_rc, 4); + return 13; + case 2: + mtp_encode_integer(pdata,mtp3_para->nw[1].routing[instance].dpc,4); + memcpy(&pdata[3],&mtp3_para->nw[1].routing[instance].normal_ls,1); + memcpy(&pdata[4],&mtp3_para->nw[1].routing[instance].alternative_ls,1); + get_rc = htonl(mtp3_para->nw[1].routing[instance].rc); + memcpy(&pdata[5], &get_rc, 4); + get_rc = htonl(mtp3_para->nw[1].routing[instance].opc); + memcpy(&pdata[9], &get_rc, 4); + return 13; + case 3: + mtp_encode_integer(pdata,mtp3_para->nw[2].routing[instance].dpc, 4); + memcpy(&pdata[3],&mtp3_para->nw[2].routing[instance].normal_ls,1); + memcpy(&pdata[4],&mtp3_para->nw[2].routing[instance].alternative_ls,1); + get_rc = htonl(mtp3_para->nw[2].routing[instance].rc); + memcpy(&pdata[5], &get_rc, 4); + get_rc = htonl(mtp3_para->nw[2].routing[instance].opc); + memcpy(&pdata[9], &get_rc, 4); + return 13; + case 4: + mtp_encode_integer(pdata,mtp3_para->nw[3].routing[instance].dpc,4); + memcpy(&pdata[3],&mtp3_para->nw[3].routing[instance].normal_ls,1); + memcpy(&pdata[4],&mtp3_para->nw[3].routing[instance].alternative_ls,1); + get_rc = htonl(mtp3_para->nw[3].routing[instance].rc); + memcpy(&pdata[5], &get_rc, 4); + get_rc = htonl(mtp3_para->nw[3].routing[instance].opc); + memcpy(&pdata[9], &get_rc, 4); + return 13; + default: + return -1; + } + return -1; + case 7: + instance = oid[MTP3_OID_LEN+3]; + *vartype = 4; + if (oid[MTP3_OID_LEN+2] == 1) + { + memcpy(pdata,mtp3_para->localAcn,MAX_ACN_NUM); + } + else if ((oid[MTP3_OID_LEN+2] > 1) && (oid[MTP3_OID_LEN+2] < 6)) + { + memcpy(pdata,mtp3_para->nw[oid[MTP3_OID_LEN+2]-2].routing[instance].acn,MAX_ACN_NUM); + } + else + return -1; + return MAX_ACN_NUM; + case 8: + instance = oid[MTP3_OID_LEN+3]; + *vartype = 4; + switch (oid[MTP3_OID_LEN+2]) + { + case 1:/* link timer */ + memcpy(pdata,&mtp3_para->lt[instance].t1,10); + return 10; + default: + return -1; + } + return -1; + case 9:/* SG */ + instance = oid[MTP3_OID_LEN+2]; + *vartype = 4; + memcpy(pdata,&mtp3_para->sg[instance],7); + return 7; + default: + return -1; + } + return -1; + } + + else if (oid[MTP3_OID_LEN] == 3)/* status */ + { + *vartype = 4; + switch (oid[MTP3_OID_LEN+1]) + { + case 1:/* link status */ + return mtp_encode_integer(pdata,mtp3ObjState.link_l3_state[oid[MTP3_OID_LEN+2]],1); + case 2:/* linkset status */ + instance= oid[MTP3_OID_LEN+2]; + if (instance > 127) + return -1; + if (mtp3.ls[instance].links_available > 0) + pdata[0] = 1; + else + pdata[0] = 0; + return 1; + case 3:/* international network routine */ + return mtp_encode_integer(pdata,mtp3.nw[0].routine[oid[MTP3_OID_LEN+2]],1); + case 4:/* international network spare routine */ + return mtp_encode_integer(pdata,mtp3.nw[1].routine[oid[MTP3_OID_LEN+2]],1); + case 5:/* national network routine */ + return mtp_encode_integer(pdata,mtp3.nw[2].routine[oid[MTP3_OID_LEN+2]],1); + case 6:/* national network spare routine */ + return mtp_encode_integer(pdata,mtp3.nw[3].routine[oid[MTP3_OID_LEN+2]],1); + case 7:/* version */ + memcpy(pdata,mtp3_heartbeat.version,3); + return 3; + default: + return -1; + + } + } + + else if (oid[MTP3_OID_LEN] == 1)/* measurement */ + { + switch (oid[MTP3_OID_LEN+1]) + { + case 1:/* MTP signalling link faults and performance */ + *vartype = 4; + instance = oid[MTP3_OID_LEN+2]; + if (instance > 8) + return -1; + portion_num = oid[MTP3_OID_LEN+3]; + if ( (portion_num > 95) || + (portion_num == mtp3_csta_p) ) + return -1; + timestamp = mtp3_measure.measure[portion_num].time_stamp; + if (timestamp == 0) + return 0; + second_to_min(0,portion_num,instance); + mtp3_data_reverse(pdata,(BYTE*)×tamp,4,4); + mtp3_data_reverse(&pdata[4],(BYTE*)&mtp3_measure.measure[portion_num].lk_measure1[instance],36,4); + return 40; + case 2:/* Signalling link availability */ + return -1; + case 3:/* Signalling link set and route set availability */ + *vartype = 4; + instance = oid[MTP3_OID_LEN+2]; + if (instance > 127) + return -1; + portion_num = oid[MTP3_OID_LEN+3]; +/* if ( (portion_num > 95) || + (portion_num == mtp3_csta_p) ) + return -1;*/ + timestamp = mtp3_measure.measure[portion_num].time_stamp; +/* if (timestamp == 0) + return 0;*/ + second_to_min(1,portion_num,instance); + mtp3_data_reverse(pdata,(BYTE*)×tamp,4,4); + mtp3_data_reverse(&pdata[4],(BYTE*)&mtp3_measure.measure[portion_num].ls_measure[instance],32,4); + return 36; + case 5:/* Signalling traffic distribution */ + switch (oid[MTP3_OID_LEN+2]) + { + case 1:/* total traffic */ + *vartype = 4; + instance = oid[MTP3_OID_LEN+3]; + portion_num = oid[MTP3_OID_LEN+4]; + if ( (portion_num > 95) || + (portion_num == mtp3_csta_p) ) + return -1; +/* if (instance < 8) + { + timestamp = mtp3_measure.measure[portion_num].time_stamp; + if (timestamp == 0) + return 0; + mtp3_data_reverse(pdata,(BYTE*)×tamp,4,4); + mtp3_data_reverse(&pdata[4],(BYTE*)&mtp3_measure.measure[portion_num].tf_measure1[instance-1],80,4); + return 84; + }*/ + else if (instance < 14) + { + timestamp = mtp3_measure.measure[portion_num].time_stamp; + if (timestamp == 0) + return 0; + mtp3_data_reverse(pdata,(BYTE*)×tamp,4,4); + mtp3_data_reverse(&pdata[4],(BYTE*)&mtp3_measure.measure[portion_num].tf_measure2[instance-8],80,4); + return 84; + } + else + return -1; + default: + return -1; + } + return -1; + case 6:/* error */ + *vartype = 4; + portion_num = oid[MTP3_OID_LEN+2]; + if ( (portion_num > 95) || + (portion_num == mtp3_csta_p) ) + return -1; + timestamp = mtp3_measure.measure[portion_num].time_stamp; + if (timestamp == 0) + return 0; + mtp3_data_reverse(pdata,(BYTE*)×tamp,4,4); + mtp3_data_reverse(&pdata[4],(BYTE*)mtp3_measure.measure[portion_num].tf_measure5,12,4); + return 16; + default: + return -1; + } + } + else + return -1; +} + +void set_led(BYTE nled,BYTE ncolor); +//void set_alarm(BYTE component_id,BYTE alarm_code); +//void set_status(BYTE component_id,BYTE info_len,BYTE *info); + +void set_heartbeat(BYTE reason,WORD object) +{ + BYTE place; + BYTE temp; + + place = object/4; + temp = (object % 4)*2; + + switch (reason) + { + case ALARM_LINK_UNAVAILABLE: + mtp3_heartbeat.link_state[place] &= (~(3<lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno];*/ + + mtp3ObjState.link_l2_state[chl] = MTP2_STATE_WORKING; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_AVAILABLE; + mtp3_send_alarm(MTP3_LINK_COMPONENT+chl,0); + mtp3_send_mtp2_alarm(8+chl,0);//clear alarm + tsrc_proc(chl); +/* ls->links_available++;*/ + hmrt_tcbc_update_routing_tables(chl); +} + +void otherMTP3_managed_link_unavailable(WORD chl) +{ +/* WORD lsno; + ls_info *ls; + + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno];*/ + + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_UNAVAILABLE; + tsrc_proc(chl); +/* ls->links_available--;*/ + hmrt_tcoc_update_routing_tables(chl); +// mtp3ObjState.tlac_state[chl] = TLAC_UNAVAILABLE_STATE; +/*init init_tlac_state*/ + init_tlac_state[chl] = TRUE; + tlac_proc(chl); + + init_lsac_state[chl] = TRUE; + lsac_proc(chl); +} + +int sys_mtp3_table(ulong ip) +{ + int empty; + int i; + + if (ip==0) + return -1; + + empty = -1; + for (i=0;i= 0) + return empty; + return -1; +} + +void master_MTP3(WORD link,BYTE masterMTP3,ulong srcIP) +{ + ulong NMTP3; + ulong AMTP3; + + masterMTP3 = masterMTP3 & 1; + + NMTP3 = mtp3_para->lk[link].e1_to_mtp3; + AMTP3 = mtp3_para->lk[link].e1_to_alterMTP3; + + if (srcIP==NMTP3) + { + if (masterMTP3) + mtp3ObjState.lk_NMTP3_ok[link] |= 1; + else + mtp3ObjState.lk_NMTP3_ok[link] &= 0xf0; + } + else if (srcIP==AMTP3) + { + if (masterMTP3) + mtp3ObjState.lk_AMTP3_ok[link] |= 1; + else + mtp3ObjState.lk_AMTP3_ok[link] &= 0xf0; + } +} + +void trap_platform (BYTE oid_len,DWORD *oid_ptr,BYTE *msg_ptr,WORD msg_len,snmp_addr *addr) +{ + heartbeat_msg *phbmsg = (heartbeat_msg *)msg_ptr; + BYTE *pstatus = phbmsg->info; + heartbeat_compoent_of_mtp3 *phbmtp3 = NULL; + WORD mtp3len=0; + int i,j,pos = 2; //component_id=0:iptrans; + BYTE newHeartbeat=0; + int chl; + BYTE chl_state; + ulong remote_ip; + int temp; + struct in_addr in; + in.s_addr = addr->remote_ip; + + mtp3_debug(MTP3DB_PFHB,"get platform heartbeat from %s",inet_ntoa(in)); + if (msg_len > 128) + mtp3_showbuf(MTP3DB_PFHB,msg_ptr,128); + else + mtp3_showbuf(MTP3DB_PFHB,msg_ptr,msg_len); + + remote_ip = addr->remote_ip; + + if ((temp=sys_mtp3_table(remote_ip)) >= 0) + { + MTP3IPMng.mtp3_flag_new[temp] = 1; + MTP3IPMng.mtp3_flag_ip[temp] = remote_ip; + } + + if ( remote_ip == mtp3_localip )/* heartbeat from itself */ + return; + + if ((temp=MTP3_LinkIP_List(remote_ip,0))<0) + return; + + if (sizeof(struct heartbeat_msg) >= (INFO_LEN + 18)) + newHeartbeat = 1; + + peer_hb_timer = 1; //check peer heartbeat status + + if (!newHeartbeat) + {//old version heartbeat, length and component_id are one octet + pos = 1; + pos += pstatus[pos]+1; //length of iptrans status + pos++; //component_id=1:MTP3 + + mtp3len = pstatus[pos]; + pos++; //length of mtp3 hb + if (pstatus[pos-1] != 1)//not mtp3 component + return; + } + else + {//new version heartbeat, length and component_id are 2 octets + pos ++; //length is 2 octets + pos += pstatus[pos]+1; //length of iptrans status + pos ++; //component_id=1:mtp3 + pos ++; //component_id is 2 octets + + if (pstatus[pos-1] != 1)//not mtp3 component + return; + + mtp3len = pstatus[pos]*256+pstatus[pos+1]; + pos ++; //length of mtp3 hb + pos ++; //length is 2 octets + } + + phbmtp3 = (heartbeat_compoent_of_mtp3*)&pstatus[pos]; + + if (mtp3len > MTP3_HB_LEN || mtp3len < (MTP3_HB_LEN-34)) + return; + + for (i=0; i<256; i++) + { + temp = phbmtp3->link_state[i]; + for (j=0; j<4; j++) + { + chl = i*4+j; + chl_state = (temp >> (j*2)) & 3; + if ( (mtp3ObjState.lk_mtp3[chl] == remote_ip) && + (mtp3ObjState.link_l3_state[chl] != chl_state) ) + { + if ( mtp3ObjState.lk_configured[chl] != PARA_CONFIGURED ) + { + continue; + } + switch (chl_state) + { + case UNAVAILABLE: + if (mtp3ObjState.link_l3_state[chl] == INHIBITED) + { + mtp3_debug(MTP3DB_EVENT,"link %d L3 state changed from INHIBITED to UNAVAILABLE,invoke by %s",chl,inet_ntoa(in)); + mtp3ObjState.link_l3_state[chl] = UNAVAILABLE; + } + else + { + mtp3_debug(MTP3DB_EVENT,"link %d L3 out of service,invoke by %s",chl,inet_ntoa(in)); + otherMTP3_managed_link_unavailable(chl); + } + break; + case AVAILABLE: + mtp3_debug(MTP3DB_EVENT,"link %d L3 in service,invoke by %s",chl,inet_ntoa(in)); + otherMTP3_managed_link_available(chl); + break; + case INHIBITED: + mtp3_debug(MTP3DB_EVENT,"link %d L3 inhibited,invoke by %s",chl,inet_ntoa(in)); + if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + otherMTP3_managed_link_unavailable(chl); + mtp3ObjState.link_l3_state[chl] = INHIBITED; + break; + default: + break; + } + } + } + } + + if (mtp3len > 100) + { + for (i=0;i<32;i++) + { + for (j=0; j<8; j++) + { + chl = i*8+j; + master_MTP3(chl,(phbmtp3->masterMTP3[i]>>j),remote_ip); + master_MTP3(chl+256,0 , remote_ip); + master_MTP3(chl+512,0 , remote_ip); + master_MTP3(chl+768,0 , remote_ip); + } + } + if (mtp3len > 132) + { + MTP3IPMng.LinkIPSubSta[temp][0] = phbmtp3->SubState[0]; + MTP3IPMng.LinkIPSubSta[temp][1] = phbmtp3->SubState[1]; + } + else + { + MTP3IPMng.LinkIPSubSta[temp][0] = 0xff; + MTP3IPMng.LinkIPSubSta[temp][1] = 0xff; + } + } + else + { + MTP3IPMng.LinkIPSubSta[temp][0] = 0xff; + MTP3IPMng.LinkIPSubSta[temp][1] = 0xff; + } +} + +void trap_mtp2 (BYTE oid_len,DWORD *oid_ptr,BYTE *msg_ptr,WORD msg_len,snmp_addr *addr)//8KE1 +{ + int i; + mtp2_heartbeat *mtp2; + BYTE offset; + BYTE new_l2_state; + WORD chl; + WORD ls; + BYTE module_id; + struct in_addr in; + in.s_addr = addr->remote_ip; + + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"get MTP2 heartbeat from %s",inet_ntoa(in)); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,msg_ptr,msg_len); + + mtp2 = (mtp2_heartbeat*)msg_ptr; + module_id = (mtp2->systemid & 1)*16+mtp2->moduleid; + if (module_id > 31) + return; + mtp2_flag_new[module_id] = 1; + offset = module_id << 3; + for ( i=0; i<8; i++ ) + { + chl = offset + i; + mtp3ObjState.link_l1_state[chl] = (mtp2->l1_state >> i) & 1; + new_l2_state = mtp2->l2_state[i];/* e1 l2 state from mtp2 */ + if ( (mtp3ObjState.lk_configured[chl] == PARA_NOT_CONFIGURED) || + (mtp3ObjState.lk_mtp3[chl] != mtp3_localip) ) + continue; + if ( new_l2_state != mtp3ObjState.link_l2_state[chl] ) + { + ls = mtp3_para->lk[chl].e1_to_linkset; + if (new_l2_state == MTP2_STATE_WORKING)/* link from unavailable->available */ + { + current_measure->lk_measure1[chl][2]++;/* restoration */ + mtp3_debug(MTP3DB_EVENT,"link %d L2 in service",chl); + mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_IN_SERVICE; + } + else if (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING)/* link from available->unavailable */ + { + local_change_over[chl]++; + mtp3_debug(MTP3DB_EVENT,"link %d L2 out of service",chl); + mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_OUT_OF_SERVICE; + if ( mtp2->retrieved_bsnt[i] < 128 ) + local_bsnt_retrievable[chl] = TRUE; + else + { +// mtp3_debug(MTP3_DEBUG_LOG,"Link %d BSNT RETRIEVE FAILED",chl); + local_bsnt_retrievable[chl] = FALSE; + } + mtp3ObjInput.sltc_input[chl] = SLTC_STOP; + sltc_proc(chl); + } + } + mtp3ObjState.link_l2_state[chl] = new_l2_state; + if ( (mtp2->e1_dstip[i]+32 != ((mtp3ObjState.lk_mtp3[chl] >> 16) & 0xff)) && + (mtp3ObjState.lk_configured[chl] == PARA_CONFIGURED) ) + send_command_to_mtp2(chl,MTP2_ACTIVE_LINK);/* give this port a correct ip */ + retrieved_bsnt[chl] = mtp2->retrieved_bsnt[i]; + } + + if (mtp2->alarm_code == 3) + { + mtp2_buf_full[mtp2->alarm_component]++; + } +} + +void mtp3_dealtrap(BYTE oid_len,DWORD *oid_ptr,BYTE *msg_ptr,WORD msg_len,snmp_addr *addr) +{ + DWORD mtp2_oid[20] = MTP2_HB_OID; + DWORD platform_oid[20] = PLATFORM_HB_OID; + DWORD omc_oid[20] = MTP3_OMC_OID; + + if (memcmp(&oid_ptr[9],&mtp2_oid[9],16)==0) + { + trap_mtp2 (oid_len,oid_ptr,msg_ptr,msg_len,addr); + } + else if (memcmp(&oid_ptr[9],&platform_oid[9],8)==0) + { + trap_platform(oid_len,oid_ptr,msg_ptr,msg_len,addr); + } + else if (memcmp(oid_ptr,omc_oid,MTP3_OMC_OID_LEN*sizeof(DWORD))==0) + {//omc heartbeat + if ((mtp3_para->MTP3SerialNum==0) ||//support old version, do not have serial number + (Bcd2Ull(&msg_ptr[39],MTP3_SERNUM_LEN)==mtp3_para->MTP3SerialNum) ) + { + + if(peer_hb_timer>0) + { + if(++peer_hb_timer>4) + { + mtp3_clear_all_peer_link_status(); + peer_hb_timer = 0; + } + + } + + switch(msg_ptr[0]) + { + case 0: + mtp3_primomcip = addr->remote_ip; + break; + case 1: + mtp3_secdomcip = addr->remote_ip; + break; + default: + break; + } + } + } +} + +int mtp3_clear_all_peer_link_status() +{ + int link; + + for(link=0; linklk[link].admin_state& 1) && (mtp3ObjState.lk_mtp3[link] != mtp3_localip)) + { + if(mtp3ObjState.link_l3_state[link] == AVAILABLE) + { + mtp3ObjState.link_l3_state[link] = UNAVAILABLE; + mtp3ObjState.link_enable_sent_flag[link] = 0; + } + } + } + + return 1; +} + +void mtp_snmp_init() +{ +// DWORD mib_oid[20] = MTP3_OID; + + snmp_init(4957); + heartbeat_init(0xff); + +/* inquire_setmsg(MTP3_OID_LEN,mib_oid, mtp_setmib); + inquire_getmsg(MTP3_OID_LEN,mib_oid, mtp_getmib); +*/ + mtp3_snmp_registration(); + +// inquire_trapmsg(trapcall trap_mtp2)/* mtp2 heartbeat */ + inquire_trapmsg(mtp3_dealtrap); +// rob_trapmsg(MTP2_HBOID_LEN,mtp2_oid,trap_mtp2); +} + +int mtp3_getnext_link(u32 *instance) +{ + int i=0; + + for(i=instance[0]; ilk[i].e1_to_mtp3==0xffffffff ||mtp3_para->lk[i].e1_to_mtp3==0) && mtp3_para->lk[i].admin_state==0) + if((mtp3_para->lk[i].title[0]==0) && mtp3_para->lk[i].admin_state==0) + continue; + instance[0] = i; + return 1; + } + instance[0] = 0; + return 0; +} + +int mtp3_get_link(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + lk_pro *pLink; + + if (instance[0] >= MAX_LK) + return -2; + pLink = &mtp3_para->lk[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //link title + GET_STRING(pLink->title); + break; + case 3: //link admin_state + GET_U8(pLink->admin_state); + break; + case 4://state + GET_U8(mtp3ObjState.link_l3_state[*instance]); + break; + case 5: //server type + GET_U8(pLink->e1_lk_type); + break; + case 6: //linkset number + GET_INTEGER(pLink->e1_to_linkset); + break; + case 7: //link SLC + GET_U8(pLink->e1_to_slc); + break; + case 8: //host ip + GET_IP(&pLink->e1_to_mtp3); + break; + case 9: //alternavie host ip + GET_IP(&pLink->e1_to_alterMTP3); + break; + case 10: //SG ID + GET_INTEGER(pLink->e1_to_sg); + break; + case 11: //m2ua interface id + GET_U8(pLink->e1_to_iid); + break; + case 12: //mtp3lite mode + GET_U8(pLink->mtp3lite_apl_mode); + break; + case 13: //mtp3lite remote ip + GET_IP(&pLink->remote_ip); + break; + case 14: // + GET_U8(pLink->inactive); + break; + case 15: + GET_U8(pLink->inactive_tm); + break; + case 16://state + GET_U8(mtp3ObjState.link_l3_state[*instance]); + break; + default: + break; + } + return datalen; +} + +int mtp3_set_link(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + lk_pro *pLink; + int new_id; + u8 tmp=0; + int linkId = 0; + + if(*instance >=MAX_LK) + { + strcpy((char*)pdata,"MAX Link is 1023."); + return -2; + } + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(new_id >=MAX_LK) + strcpy((char*)pdata,"MAX Link is 1023."); + pLink = &mtp3_para->lk[new_id]; + if(pLink->admin_state==1) + { + strcpy((char*)pdata,"Link is unlocked."); + return -2; + } + pLink->title[0]='-'; + pLink->e1_lk_type = 1; + mtp3ObjState.link_type[new_id] = pLink->e1_lk_type; + mtp3EnableSaveFlag(); + + return datalen; + } + linkId = *instance; + pLink = &mtp3_para->lk[*instance]; + if(pLink->admin_state==1 && column>3) + { + strcpy((char*)pdata,"Link is unlocked."); + return -2; + } + + if(datalen == 0) + { + if(column == 12 || column == 2) + ; + else + return -2; + } + + + switch(column) + { + case 2: //link title + if(datalen >= 16) + return -2; + SET_STRING(pLink->title); + break; + case 3: //link admin_state + if(pLink->admin_state==1 && pdata[0]==0) + { + mtp3_setlink_to_IDLE(instance[0]); + } + else if(pLink->admin_state==0 && pdata[0]==1) + { + SET_U8(pLink->admin_state); + if (update_ls_slc_table(instance[0]) == 1) + { + update_sls_to_link_table(pLink->e1_to_linkset); + MTP3_LinkIP_List(pLink->e1_to_mtp3,1); + MTP3_LinkIP_List(pLink->e1_to_alterMTP3,1); + } + } + SET_U8(pLink->admin_state); +#ifdef _INCLUDE_M2UA + set_m2ua_link(instance[0]%MAX_LK, (u8 *)pLink); +#endif + break; + case 5: //server type + SET_U8(pLink->e1_lk_type); + mtp3ObjState.link_type[instance[0]] = pLink->e1_lk_type; + break; + case 6: //linkset number + SET_INTEGER(pLink->e1_to_linkset); + break; + case 7: //link SLC + SET_U8(pLink->e1_to_slc); + break; + case 8: //host ip + SET_IP(&pLink->e1_to_mtp3); + mtp3ObjState.lk_mtp3[linkId] = mtp3_para->lk[linkId].e1_to_mtp3; + break; + case 9: //alternative host ip + SET_IP(&pLink->e1_to_alterMTP3); + break; + case 10: //SG ID + SET_INTEGER(pLink->e1_to_sg); + break; + case 11: //m2ua interface id + SET_U8(pLink->e1_to_iid); + break; + case 12: //mtp3lite mode + SET_U8(pLink->mtp3lite_apl_mode); + break; + case 13: //mtp3lite remote ip + SET_IP(&pLink->remote_ip); + break; + case 14: // + SET_U8(pLink->inactive); + break; + case 15: + SET_U8(pLink->inactive_tm); + break; + case 16: + SET_U8(tmp); + if(tmp == 6) + { + memset(pLink, 0, sizeof(lk_pro)); +#ifdef _INCLUDE_M2UA + set_m2ua_link(instance[0]%MAX_LK, (u8 *)pLink); +#endif + } + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + + +int mtp3_getnext_linkset(u32 *instance) +{ + int i=0; + + for(i=instance[0]; ils_pro[i].title[0]==0&&mtp3_para->ls_pro[i].admin_state==0) + continue; + instance[0]= i; + return 1; + } + return 0; +} + +int mtp3_get_linkset(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + ls_para *pLs; + + if (instance[0] >= MAX_LS) + return -2; + pLs = &mtp3_para->ls_pro[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //ls title + GET_STRING(pLs->title); + break; + case 3: //ls admin_state + GET_U8(pLs->admin_state); + break; + case 4: //ls state + GET_U8(pLs->ls_state); + break; + case 5: //nw indicator + GET_U8(pLs->nw_id); + break; + case 6: //DPC + GET_INTEGER(pLs->ls_op_pc); + break; + case 7: //ls loopback option + GET_U8(pLs->loopback_opt); + break; + case 8: //ls opc if used multiple opc + GET_INTEGER(pLs->ls_opc); + break; + case 9: + GET_U8(1); + break; + default: + break; + } + return datalen; +} + +void reset_linkset(int ls_num ) +{ + int i=0; + u32 dpc=0, opc=0; + u8 nw=0; + + nw = mtp3_para->ls_pro[ls_num].nw_id; + dpc = mtp3_para->ls_pro[ls_num].ls_op_pc; + opc = mtp3_para->ls_pro[ls_num].ls_opc; + + if(dpc == 0) + { + mtp3.ls[ls_num].adjacent_sp_place = 0xffff; + return ; + } + for (i=0;inw[nw].routing[i].dpc == dpc && mtp3_para->nw[nw].routing[i].opc == opc)//??? + { + mtp3.ls[ls_num].adjacent_sp_place = i; + return; + } + } + mtp3.ls[ls_num].adjacent_sp_place = 0xffff; +} + +int mtp3_set_linkset(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + ls_para *ptr; + int new_id; + u8 tmp=0; + + if(*instance >=MAX_LS) + { + strcpy((char*)pdata,"MAX Linkset is 511."); + return -2; + } + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(new_id >=MAX_LS) + strcpy((char*)pdata,"MAX Linkset is 511."); + ptr = &mtp3_para->ls_pro[new_id]; + if(ptr->admin_state==1) + { + strcpy((char*)pdata,"Linkset is unlocked."); + return -2; + } + ptr->title[0]= '-'; + mtp3EnableSaveFlag(); + + return datalen; + } + + ptr = &mtp3_para->ls_pro[*instance]; + if(ptr->admin_state==1&&column>3) + { + strcpy((char*)pdata,"Linkset is unlocked."); + return -2; + } + + if(datalen == 0) + { + if(column == 12 || column == 2) + ; + else + return -2; + } + if(column == Create_Object_Cloumn) + { + new_id = *instance; + if(ptr->admin_state==1) + { + strcpy((char*)pdata,"Linkset is unlocked."); + return -2; + } + return datalen; + } + + switch(column) + { + case 2: //linkset title + if(datalen >= 16) + return -2; + SET_STRING(ptr->title); + break; + case 3: //ls admin_state + if(ptr->admin_state !=pdata[0] && pdata[0]==1) + reset_linkset(instance[0]); + + SET_U8(ptr->admin_state); + break; + case 4: //ls state + //SET_U8(ptr->ls_state); + break; + case 5: //nw indicator + if(ptr->nw_id != pdata[0]) + change_the_whole_ls(instance[0],ptr->nw_id,pdata[0]); + SET_U8(ptr->nw_id); + break; + case 6: //dpc + SET_INTEGER(ptr->ls_op_pc); + break; + case 7: //ls loopback option + SET_U8(ptr->loopback_opt); + break; + case 8: //ls opc if used multiple opc + SET_INTEGER(ptr->ls_opc); + break; + case 9: + SET_U8(tmp); + if(tmp == 6) + { + memset(ptr, 0, sizeof(ls_para)); + reset_linkset(instance[0]); + } + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + + +int mtp3_getnext_sg(u32 *instance) +{ + int i=0; + + for(i=instance[0]; i<256; i++) + { + if(mtp3_para->sg[i].ip==0&&mtp3_para->sg[i].enable==0) + continue; + instance[0] = i; + return 1; + } + return 0; +} + +int mtp3_get_sg(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + u8 type=0, data_ack=0; + sg_para *ptr; + + if (instance[0] >= 256) + return -2; + ptr = &mtp3_para->sg[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //sg admin_state + GET_U8(ptr->enable); + break; + case 3: //server or client + GET_U8(ptr->server); + break; + case 4: //data_ack + data_ack = ptr->data_ack&1; + GET_U8(data_ack); + break; + case 5: // type + type = ptr->data_ack>>1; + GET_U8(type); + break; + case 6: //remote ip + GET_IP(&ptr->ip); + break; + case 7: //client source ip + GET_IP(&ptr->source_ip); + break; + case 8: //client source port + GET_INTEGER(ptr->source_port); + break; + case 9: //dst port + GET_INTEGER(ptr->dst_port); + break; + case 10: + GET_U8(ptr->enable); + break; + default: + break; + } + return datalen; +} + +int check_sg_link_enable(int sg_id) +{ + int link; + + for(link=0; linklk[link].e1_to_sg == sg_id && mtp3_para->lk[link].admin_state==1&&mtp3_para->lk[link].e1_lk_type>0&&mtp3_para->lk[link].e1_lk_type!=LKTYPE_MTP3_LITE) + return 1; + } + return 0; + +} + +int mtp3_set_sg(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + sg_para *ptr; + int new_id; + u8 tmp=0; + + + if(*instance >=256) + { + strcpy((char*)pdata,"MAX SG is 255."); + return -2; + } + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(mtp3_para->sg[new_id].enable==1) + { + strcpy((char*)pdata,"SG is unlocked."); + return -2; + } + mtp3_para->sg[new_id].ip=0x016212ac; + mtp3EnableSaveFlag(); + + return datalen; + } + ptr = &mtp3_para->sg[*instance]; + if(check_sg_link_enable(*instance)) + { + strcpy((char*)pdata,"Links of SG are unlocked."); + return -2; + } + if(ptr->enable==1&&(column>2)) + { + strcpy((char*)pdata,"SG is unlocked."); + return -2; + } + + if(datalen == 0) + { + if(column == 3) + ; + else + return -2; + } + + + switch(column) + { + case 2: //sg admin_state + SET_U8(ptr->enable); +#ifdef _INCLUDE_M2UA + set_m2ua_sg(instance[0] & 0xff, (u8 *)ptr); +#endif + break; + case 3: //server or client + SET_U8(ptr->server); + break; + case 4: //data_ack + ptr->data_ack = (ptr->data_ack&0xfe)|pdata[0]; + break; + case 5: //type + ptr->data_ack = (ptr->data_ack&0x1)|(pdata[0]<<1); + break; + case 6: //remote ip + SET_IP(&ptr->ip); + break; + case 7: //client source ip + SET_IP(&ptr->source_ip); + break; + case 8: //client source port + SET_INTEGER(ptr->source_port); + break; + case 9: //dst port + SET_INTEGER(ptr->dst_port); + break; + case 10: //delete sg + SET_U8(tmp); + if(tmp == 6) + { + memset(ptr, 0, sizeof(sg_para)); +#ifdef _INCLUDE_M2UA + set_m2ua_sg(instance[0] & 0xff, (u8 *)ptr); +#endif + } + break; + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + +int mtp3_getnext_introute(u32 *instance) +{ + int i=0; + + for(i=instance[0]; inw[0].routing[i].title[0]==0) + continue; + instance[0] = i; + return 1; + } + return 0; +} + +int mtp3_get_introute(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + nw_route *ptr; + + if (instance[0] >= MAX_ROUTE) + return -2; + ptr = &mtp3_para->nw[0].routing[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //title + GET_STRING(ptr->title); + break; + case 3: //DPC + GET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + GET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + GET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + GET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + GET_INTEGER(ptr->rc); + break; + case 8://ACN + GET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + GET_U8(1); + break; + default: + break; + } + return datalen; +} + +int mtp3_set_introute(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + nw_route *ptr; + int new_id; + u8 tmp=0; + u32 temp=0; + + if(*instance >=MAX_ROUTE) + { + strcpy((char*)pdata,"MAX ROUTE is 1023."); + return -2; + } + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(mtp3_para->nw[0].routing[new_id].title[0]!=0) + { + strcpy((char*)pdata,"Route is already used."); + return -2; + } + mtp3_para->nw[0].routing[new_id].title[0]='-'; + memcpy(mtp3_para->nw[0].routing[new_id].acn, mtp3_para->nw[0].local_acn, MAX_ACN_NUM); + mtp3EnableSaveFlag(); + + return datalen; + } + ptr = &mtp3_para->nw[0].routing[*instance]; + + switch(column) + { + case 2: //title + SET_STRING(ptr->title); + break; + case 3: //DPC + SET_INTEGER(temp); + update_ls_influence_dst_table(0,temp,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + SET_INTEGER(temp); + update_ls_influence_dst_table(0,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, temp); + SET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(0,ptr->dpc,instance[0],temp, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(0,ptr->dpc,instance[0],ptr->normal_ls, temp, ptr->rc, ptr->opc); + SET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + SET_INTEGER(temp); + update_ls_influence_dst_table(0,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, temp, ptr->opc); + SET_INTEGER(ptr->rc); + break; + case 8://ACN + SET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + SET_U8(tmp); + if(tmp == 6) + { + update_ls_influence_dst_table(0,0,instance[0],0, 0, 0, 0); + memset(ptr, 0, sizeof(nw_route)); + } + break; + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + + +int mtp3_getnext_intsroute(u32 *instance) +{ + int i=0; + + for(i=instance[0]; inw[1].routing[i].title[0]==0) + continue; + instance[0] = i; + return 1; + } + return 0; +} + +int mtp3_get_intsroute(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + nw_route *ptr; + + if (instance[0] >= MAX_ROUTE) + return -2; + ptr = &mtp3_para->nw[1].routing[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //title + GET_STRING(ptr->title); + break; + case 3: //DPC + GET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + GET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + GET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + GET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + GET_INTEGER(ptr->rc); + break; + case 8://ACN + GET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + GET_U8(1); + break; + default: + break; + } + return datalen; +} + +int mtp3_set_intsroute(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + nw_route *ptr; + int new_id; + u8 tmp=0; + u32 temp=0; + + if(*instance >=MAX_ROUTE) + { + strcpy((char*)pdata,"MAX ROUTE is 1023."); + return -2; + } + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(mtp3_para->nw[1].routing[new_id].title[0]!=0) + { + strcpy((char*)pdata,"Route is already used."); + return -2; + } + mtp3_para->nw[1].routing[new_id].title[0]='-'; + memcpy(mtp3_para->nw[1].routing[new_id].acn, mtp3_para->nw[1].local_acn, MAX_ACN_NUM); + mtp3EnableSaveFlag(); + + return datalen; + } + ptr = &mtp3_para->nw[1].routing[*instance]; + + + switch(column) + { + case 2: //title + SET_STRING(ptr->title); + break; + case 3: //DPC + SET_INTEGER(temp); + update_ls_influence_dst_table(1,temp,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + SET_INTEGER(temp); + update_ls_influence_dst_table(1,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, temp); + SET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(1,ptr->dpc,instance[0],temp, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(1,ptr->dpc,instance[0],ptr->normal_ls, temp, ptr->rc, ptr->opc); + SET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + SET_INTEGER(temp); + update_ls_influence_dst_table(1,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, temp, ptr->opc); + SET_INTEGER(ptr->rc); + break; + case 8://ACN + SET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + SET_U8(tmp); + if(tmp == 6) + { + update_ls_influence_dst_table(1,0,instance[0],0, 0, 0, 0); + memset(ptr, 0, sizeof(nw_route)); + } + break; + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + +int mtp3_getnext_natroute(u32 *instance) +{ + int i=0; + + for(i=instance[0]; inw[2].routing[i].title[0]==0) + continue; + instance[0] = i; + return 1; + } + return 0; +} + +int mtp3_get_natroute(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + nw_route *ptr; + + if (instance[0] >= MAX_ROUTE) + return -2; + ptr = &mtp3_para->nw[2].routing[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //title + GET_STRING(ptr->title); + break; + case 3: //DPC + GET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + GET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + GET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + GET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + GET_INTEGER(ptr->rc); + break; + case 8://ACN + GET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + GET_U8(1); + break; + default: + break; + } + return datalen; +} + +int mtp3_set_natroute(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + nw_route *ptr; + int new_id; + u8 tmp=0; + u32 temp=0; + + if(*instance >=MAX_ROUTE) + { + strcpy((char*)pdata,"MAX ROUTE is 1023."); + return -2; + } + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(mtp3_para->nw[2].routing[new_id].title[0]!=0) + { + strcpy((char*)pdata,"Route is already used."); + return -2; + } + mtp3_para->nw[2].routing[new_id].title[0]='-'; + memcpy(mtp3_para->nw[2].routing[new_id].acn, mtp3_para->nw[2].local_acn, MAX_ACN_NUM); + mtp3EnableSaveFlag(); + + return datalen; + } + ptr = &mtp3_para->nw[2].routing[*instance]; + + + switch(column) + { + case 2: //title + SET_STRING(ptr->title); + break; + case 3: //DPC + SET_INTEGER(temp); + update_ls_influence_dst_table(2,temp,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + SET_INTEGER(temp); + update_ls_influence_dst_table(2,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, temp); + SET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(2,ptr->dpc,instance[0],temp, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(2,ptr->dpc,instance[0],ptr->normal_ls, temp, ptr->rc, ptr->opc); + SET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + SET_INTEGER(temp); + update_ls_influence_dst_table(2,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, temp, ptr->opc); + SET_INTEGER(ptr->rc); + break; + case 8://ACN + SET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + SET_U8(tmp); + if(tmp == 6) + { + update_ls_influence_dst_table(2,0,instance[0],0, 0, 0, 0); + memset(ptr, 0, sizeof(nw_route)); + } + break; + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + +int mtp3_getnext_natsroute(u32 *instance) +{ + int i=0; + + for(i=instance[0]; inw[3].routing[i].title[0]==0) + continue; + instance[0] = i; + return 1; + } + return 0; +} + +int mtp3_get_natsroute(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + nw_route *ptr; + + if (instance[0] >= MAX_ROUTE) + return -2; + ptr = &mtp3_para->nw[3].routing[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //title + GET_STRING(ptr->title); + break; + case 3: //DPC + GET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + GET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + GET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + GET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + GET_INTEGER(ptr->rc); + break; + case 8://ACN + GET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + GET_U8(1); + break; + default: + break; + } + return datalen; +} + +int mtp3_set_natsroute(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + nw_route *ptr; + int new_id; + u8 tmp=0; + u32 temp=0; + + if(*instance >=MAX_ROUTE) + { + strcpy((char*)pdata,"MAX ROUTE is 1023."); + return -2; + } + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(mtp3_para->nw[3].routing[new_id].title[0]!=0) + { + strcpy((char*)pdata,"Route is already used."); + return -2; + } + mtp3_para->nw[3].routing[new_id].title[0]='-'; + memcpy(mtp3_para->nw[3].routing[new_id].acn, mtp3_para->nw[3].local_acn, MAX_ACN_NUM); + mtp3EnableSaveFlag(); + + return datalen; + } + ptr = &mtp3_para->nw[3].routing[*instance]; + + + switch(column) + { + case 2: //title + SET_STRING(ptr->title); + break; + case 3: //DPC + SET_INTEGER(temp); + update_ls_influence_dst_table(3,temp,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->dpc); + break; + case 4: //OPC multiple + SET_INTEGER(temp); + update_ls_influence_dst_table(3,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, ptr->rc, temp); + SET_INTEGER(ptr->opc); + break; + case 5: // normal linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(3,ptr->dpc,instance[0],temp, ptr->alternative_ls, ptr->rc, ptr->opc); + SET_INTEGER(ptr->normal_ls); + break; + case 6: //alternative linkset + SET_INTEGER(temp); + update_ls_influence_dst_table(3,ptr->dpc,instance[0],ptr->normal_ls, temp, ptr->rc, ptr->opc); + SET_INTEGER(ptr->alternative_ls); + break; + case 7:// m3ua rc + SET_INTEGER(temp); + update_ls_influence_dst_table(3,ptr->dpc,instance[0],ptr->normal_ls, ptr->alternative_ls, temp, ptr->opc); + SET_INTEGER(ptr->rc); + break; + case 8://ACN + SET_OPAQUE(ptr->acn, MAX_ACN_NUM); + break; + case 9:// + SET_U8(tmp); + if(tmp == 6) + { + update_ls_influence_dst_table(3,0,instance[0],0, 0, 0, 0); + memset(ptr, 0, sizeof(nw_route)); + } + break; + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + +int mtp3_get_sysparam(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen=-1; + WORD tmp=0; + + switch(column) + { + case 1: //mtp3lite port + tmp = htons(mtp3_para->mtp3lite_port); + GET_INTEGER(tmp); + break; + case 2: //command + GET_U8(0); + break; + default: + break; + } + return datalen; +} + +int mtp3_set_sysparam(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + u8 command=0; + WORD tmp=0; + + switch(column) + { + case 1: //mtp3lite port + SET_INTEGER(tmp); + mtp3_para->mtp3lite_port = htons(tmp); + break; + case 2: //command + SET_U8(command); + if(command==1) + { + mtp3_write_para(); + reset_mtp3(); + } + else if(command ==2) + { + printf("save parameter\n"); + mtp3_write_para(); + } + break; + default: + break; + } + mtp3EnableSaveFlag(); + return datalen; +} + +//MTP3 OID Prefix: {1,3,6,1,4,1,1373,2,3,2,2} +static struct snmp_table_profile mtp3_tables[] = { + /****** Parameter table ******/ + { + .name = "system", + .index.len = 13, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,1}, + .column = {0,1,2,3}, + .level = 0, + .get_instance = NULL, + .get_resp = mtp3_get_sysparam, + .set_resp = mtp3_set_sysparam + }, + { + .name = "international network routing", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,2,5}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 1, + .get_instance = mtp3_getnext_introute, + .get_resp = mtp3_get_introute, + .set_resp = mtp3_set_introute + }, + { + .name = "international spare nw routing", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,3,5}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 1, + .get_instance = mtp3_getnext_intsroute, + .get_resp = mtp3_get_intsroute, + .set_resp = mtp3_set_intsroute + }, + { + .name = "national network routing", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,4,5}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 1, + .get_instance = mtp3_getnext_natroute, + .get_resp = mtp3_get_natroute, + .set_resp = mtp3_set_natroute + }, + { + .name = "national spare network routing", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,5,5}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 1, + .get_instance = mtp3_getnext_natsroute, + .get_resp = mtp3_get_natsroute, + .set_resp = mtp3_set_natsroute + }, + { + .name = "linkset", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,6,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 1, + .get_instance = mtp3_getnext_linkset, + .get_resp = mtp3_get_linkset, + .set_resp = mtp3_set_linkset + }, + { + .name = "link", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,7,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,15,16,0}, + .level = 1, + .get_instance = mtp3_getnext_link, + .get_resp = mtp3_get_link, + .set_resp = mtp3_set_link + }, + { + .name = "sg", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,2,2,8,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 1, + .get_instance = mtp3_getnext_sg, + .get_resp = mtp3_get_sg, + .set_resp = mtp3_set_sg + } + +}; + +static struct snmp_register mtp3_register = { + .name = "MTP3", + .prefix_len = 11, + .prefix_oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 2, 2}, + .num_of_table = sizeof(mtp3_tables)/sizeof(struct snmp_table_profile), + .table = mtp3_tables, + .default_get_resp = mtp_getmib, + .default_set_resp = mtp_setmib +}; + +void mtp3_snmp_registration(void) +{ + register_snmp_table(&mtp3_register); +} + +int mtp3_get_net_pclen(int netid) +{ + return mtp3_para->nw[netid%4].pc_len; +} +/*@end@*/ diff --git a/plat/mtp3/src/mtpslm.c b/plat/mtp3/src/mtpslm.c new file mode 100644 index 0000000..fbbf0fc --- /dev/null +++ b/plat/mtp3/src/mtpslm.c @@ -0,0 +1,405 @@ +#include "./include/mtp3.h" +#include "./include/mtpstm.h" +#include "./include/mtpext.h" +#include "./include/mtpfunc.h" + +/*@ignore@*/ +void sltc_proc(WORD chl) +{ + ls_info *ls; + ls = &mtp3.ls[mtp3_para->lk[chl].e1_to_linkset]; + + if (mtp3ObjInput.sltc_input[chl] == SLTC_STOP) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + mtp3ObjState.sltc_state[chl] = SLTC_IDLE_STATE; + } + + switch (mtp3ObjState.sltc_state[chl]) + { + case SLTC_IDLE_STATE: + if (mtp3ObjInput.sltc_input[chl] == SLTC_START) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + hmrt_sltc_signalling_link_test_msg(chl); + sltc_t1_delay[chl] = 4; + mtp3ObjState.sltc_state[chl] = SLTC_FIRST_TRY_STATE; + } + break; + + case SLTC_FIRST_TRY_STATE: + sltc_t1_delay[chl] --; + if ( mtp3ObjInput.sltc_input[chl] == SLTA_MSG ) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + mtp3ObjInput.lsac_input_from_sltc[chl] = LSAC_SLTC_SLT_SUCCESSFUL; + mtp3ObjState.sltc_state[chl] = SLTC_RUNNING_STATE; + sltc_t2_delay[chl] = 30; + } + else if ( sltc_t1_delay[chl] == 0 ) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + sltc_t1_delay[chl] = 4; + hmrt_sltc_signalling_link_test_msg(chl); + mtp3ObjState.sltc_state[chl] = SLTC_SECOND_TRY_STATE; + } + break; + + case SLTC_SECOND_TRY_STATE: + sltc_t1_delay[chl]--; + if ( mtp3ObjInput.sltc_input[chl] == SLTA_MSG ) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + mtp3ObjInput.lsac_input_from_sltc[chl] = LSAC_SLTC_SLT_SUCCESSFUL; + mtp3ObjState.sltc_state[chl] = SLTC_RUNNING_STATE; + sltc_t2_delay[chl] = 30; + } + else if ( sltc_t1_delay[chl] == 0 ) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + sltc_t1_delay[chl] = 4; + hmrt_sltc_signalling_link_test_msg(chl); + mtp3ObjState.sltc_state[chl] = SLTC_THIRD_TRY_STATE; + } + break; + + case SLTC_THIRD_TRY_STATE: + sltc_t1_delay[chl]--; + if ( mtp3ObjInput.sltc_input[chl] == SLTA_MSG ) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + mtp3ObjInput.lsac_input_from_sltc[chl] = LSAC_SLTC_SLT_SUCCESSFUL; + mtp3ObjState.sltc_state[chl] = SLTC_RUNNING_STATE; + sltc_t2_delay[chl] = 30; + } + else if ( sltc_t1_delay[chl] == 0 ) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + mtp3ObjInput.lsac_input_from_sltc[chl] = LSAC_SLTC_SLT_FAILED; + mtp3ObjState.sltc_state[chl] = SLTC_IDLE_STATE; + } + break; + + case SLTC_RUNNING_STATE: + sltc_t2_delay[chl] --; + if ( sltc_t2_delay[chl] == 0 ) + { + mtp3ObjInput.sltc_input[chl] = IDLE; + hmrt_sltc_signalling_link_test_msg(chl); + mtp3ObjState.sltc_state[chl] = SLTC_FIRST_TRY_STATE; + sltc_t1_delay[chl] = 4; + } + break; + + default: + break; + } +} + +int link_auc(WORD chl) +{ + WORD linkset; + + linkset = mtp3_para->lk[chl].e1_to_linkset; + if ( (mtp3ObjState.lk_configured[chl] != PARA_CONFIGURED) || + (mtp3ObjState.lk_mtp3[chl] != mtp3_localip) ) + return 3; + if (mtp3ObjState.link_l1_state[chl] != 1) + return 2; + if (mtp3.ls[linkset].links_available == 0) + return 1; + else + return 0; + +/* return value: + * 0=linkset not only one link available + * 1=linkset only one link available + * 2=send command to enable this link + * 3=no need to send command to this link */ +} + +void lsac_proc(WORD chl) +{ + int aucResult; + static BYTE timer[MAX_LK]; + + if (init_lsac_state[chl] == TRUE) + { + init_lsac_state[chl] = IDLE; + mtp3ObjState.lsac_state[chl] = LSAC_INACTIVE_STATE; + return; + } + + switch (mtp3ObjState.lsac_state[chl]) + { + case LSAC_INACTIVE_STATE: + switch (mtp3ObjInput.lsac_input_from_mgmt[chl]) + { + case LSAC_MGMT_ACTIVATE_LINK: + if (timer[chl]++>50) + { + timer[chl] = 0; + aucResult = link_auc(chl); + switch (aucResult) + { + case 0: + if (MTP3_LINK_TYPE(chl) == LKTYPE_SIGTRAN)//m2ua link + send_command_to_mtp2(chl,MTP3_M2UA_ENABLE); + send_command_to_mtp2(chl,MTP2_ACTIVE_LINK); + mtp3_debug(MTP3DB_EVENT,"[lsac]link %d normal alignment",chl); +// printf("chl %d normal alignment\n",chl); + mtp3ObjState.lsac_state[chl] = LSAC_RESTORING_STATE; + timer[chl] = 0; + break; + case 1: + if (MTP3_LINK_TYPE(chl) == LKTYPE_SIGTRAN)//m2ua link + send_command_to_mtp2(chl,MTP3_M2UA_ENABLE); + send_command_to_mtp2(chl,MTP2_EMERGEN_ALIGNMENT); + mtp3_debug(MTP3DB_EVENT,"[lsac]link %d emergent alignment",chl); +// printf("chl %d emergent alignment\n",chl); + mtp3ObjState.lsac_state[chl] = LSAC_RESTORING_STATE; + timer[chl] = 0; + break; + case 2: + if (MTP3_LINK_TYPE(chl) != LKTYPE_MTP3_LITE)//m2ua link + send_command_to_mtp2(chl,MTP3_M2UA_ENABLE); + break; + default: + break; + } + } + break; + + case LSAC_MGMT_DEACTIVATE_LINK: + break; + + default: + break; + } + + switch (mtp3ObjInput.lsac_input_from_l2[chl]) + { + case LSAC_L2_IN_SERVICE: + break; + + case LSAC_L2_OUT_OF_SERVICE: + mtp3ObjInput.lsac_input_from_l2[chl] = IDLE; + break; + + case LSAC_L2_REMOTE_PROCESSOR_RECOV: + break; + + default: + break; + } + break; + + case LSAC_RESTORING_STATE: + switch (mtp3ObjInput.lsac_input_from_mgmt[chl]) + { + case LSAC_MGMT_ACTIVATE_LINK: + if ( (mtp3ObjState.sltc_state[chl] == SLTC_IDLE_STATE) && + (timer[chl]++>60)) // change timer 8s to 9.6s + { + timer[chl] = 0; + aucResult = link_auc(chl); + switch (aucResult) + { + case 0: + if (MTP3_LINK_TYPE(chl) == LKTYPE_SIGTRAN)//m2ua link + send_command_to_mtp2(chl,MTP3_M2UA_ENABLE); + send_command_to_mtp2(chl,MTP2_ACTIVE_LINK); + break; + case 1: + if (MTP3_LINK_TYPE(chl) == LKTYPE_SIGTRAN)//m2ua link + send_command_to_mtp2(chl,MTP3_M2UA_ENABLE); + send_command_to_mtp2(chl,MTP2_EMERGEN_ALIGNMENT); + break; + default: + mtp3ObjState.lsac_state[chl] = LSAC_INACTIVE_STATE; + break; + } + } + break; + + case LSAC_MGMT_DEACTIVATE_LINK: + send_command_to_mtp2(chl,MTP2_DEACTIVE_LINK); + mtp3ObjState.lsac_state[chl] = LSAC_INACTIVE_STATE; + break; + + default: + break; + } + + switch (mtp3ObjInput.lsac_input_from_l2[chl]) + { + case LSAC_L2_IN_SERVICE: + mtp3ObjInput.lsac_input_from_l2[chl] = IDLE; + mtp3_debug(MTP3DB_EVENT,"[lsac]link %d L2 in service,start testing procedure",chl); + mtp3ObjInput.sltc_input[chl] = SLTC_START; + sltc_proc(chl);/* start to send sltm */ + break; + + case LSAC_L2_OUT_OF_SERVICE: + mtp3ObjInput.lsac_input_from_l2[chl] = IDLE; + break; + + case LSAC_L2_REMOTE_PROCESSOR_RECOV: + break; + + default: + break; + } + + switch (mtp3ObjInput.lsac_input_from_sltc[chl]) + { + case LSAC_SLTC_SLT_SUCCESSFUL: + mtp3ObjInput.lsac_input_from_sltc[chl] = IDLE; + mtp3ObjInput.tlac_input_from_slm[chl] = TLAC_LSAC_LINK_IN_SERVICE; + mtp3ObjState.lsac_state[chl] = LSAC_ACTIVE_STATE; + mtp3_debug(MTP3DB_EVENT,"[lsac]link %d complete test procedure,test pass",chl); + break; + + case LSAC_SLTC_SLT_FAILED: + mtp3ObjInput.lsac_input_from_sltc[chl] = IDLE; + mtp3ObjState.link_l2_state[chl] = UNAVAILABLE; + send_command_to_mtp2(chl,MTP2_STOP_L2); + mtp3ObjState.lsac_state[chl] = LSAC_INACTIVE_STATE; + mtp3_debug(MTP3DB_EVENT,"[lsac]link %d complete test procedure,test failed",chl); + break; + + default: + break; + } + break; + + case LSAC_ACTIVE_STATE: + switch (mtp3ObjInput.lsac_input_from_mgmt[chl]) + { + case LSAC_MGMT_ACTIVATE_LINK: + break; + + case LSAC_MGMT_DEACTIVATE_LINK: + mtp3ObjInput.tlac_input_from_slm[chl] = TLAC_LSAC_SIGLINK_FAILED; + mtp3ObjState.lsac_state[chl] = LSAC_WAIT_STATE; +// mtp3ObjState.lsac_state[chl] = LSAC_INACTIVE_STATE; + break; + + default: + break; + } + + switch (mtp3ObjInput.lsac_input_from_l2[chl]) + { + case LSAC_L2_IN_SERVICE: + mtp3ObjInput.lsac_input_from_l2[chl] = IDLE; + break; + + case LSAC_L2_OUT_OF_SERVICE: + mtp3_debug(MTP3DB_EVENT,"[lsac]link %d failed",chl); +// printf("lsac link %d failed\n",chl); + mtp3ObjInput.lsac_input_from_l2[chl] = IDLE; + if (link_inhibited[chl] != TRUE) + { + mtp3ObjInput.tlac_input_from_slm[chl] = TLAC_LSAC_SIGLINK_FAILED; + mtp3ObjState.lsac_state[chl] = LSAC_FAILED_STATE; + } + break; + + case LSAC_L2_REMOTE_PROCESSOR_RECOV: + break; + + default: + break; + } + + switch (mtp3ObjInput.lsac_input_from_sltc[chl]) + { + case LSAC_SLTC_SLT_SUCCESSFUL: + mtp3ObjInput.lsac_input_from_sltc[chl] = IDLE; + break; + + case LSAC_SLTC_SLT_FAILED: + mtp3ObjInput.lsac_input_from_sltc[chl] = IDLE; + mtp3ObjState.lsac_state[chl] = LSAC_INACTIVE_STATE; + send_command_to_mtp2(chl,MTP2_STOP_L2); + mtp3_debug(MTP3DB_EVENT,"[lsac]link %d test failed during active state",chl); + mtp3ObjState.link_l2_state[chl] = UNAVAILABLE; + mtp3_send_alarm(MTP3_LINK_COMPONENT+chl,MTP3ALARM_LINK_TEST_FAILED); + if (link_inhibited[chl] != TRUE) + { + mtp3ObjInput.tlac_input_from_slm[chl] = TLAC_LSAC_SIGLINK_FAILED; + mtp3ObjState.lsac_state[chl] = LSAC_FAILED_STATE; + } + break; + + default: + break; + } + + switch (mtp3ObjInput.lsac_input_from_tcoc[chl]) + { + case LSAC_TCOC_STM_READY: + mtp3ObjInput.lsac_input_from_tcoc[chl] = IDLE; + break; + + case LSAC_TCOC_STOP_L2: + mtp3ObjInput.lsac_input_from_tcoc[chl] = IDLE; + send_command_to_mtp2(chl,MTP2_STOP_L2); + mtp3_send_alarm(MTP3_LINK_COMPONENT+chl,MTP3ALARM_LINK_CHANGE_OVER); + if (link_inhibited[chl] != TRUE) + { + mtp3ObjState.lsac_state[chl] = LSAC_FAILED_STATE; + } + break; + + default: + break; + } + + switch (mtp3ObjInput.lsac_input_from_stm[chl]) + { + case LSAC_TLAC_CHANGEOVER_ORDER_RECEIVED: + mtp3ObjInput.lsac_input_from_stm[chl] = IDLE; + send_command_to_mtp2(chl,MTP2_STOP_L2); + mtp3_send_alarm(MTP3_LINK_COMPONENT+chl,MTP3ALARM_LINK_CHANGE_OVER); + mtp3_debug(MTP3DB_EVENT,"[lsac]receive coo"); +// printf("lsac receive coo\n"); + mtp3ObjState.lsac_state[chl] = LSAC_FAILED_STATE; + break; + + default: + break; + } + break; + + case LSAC_WAIT_STATE: + if ( mtp3ObjInput.lsac_input_from_tcoc[chl] == LSAC_TCOC_STM_READY) + { + mtp3ObjInput.lsac_input_from_tcoc[chl] = IDLE; + send_command_to_mtp2(chl,MTP2_STOP_L2); + mtp3_send_alarm(MTP3_LINK_COMPONENT+chl,MTP3ALARM_LINK_MGMT_REQUEST); + mtp3ObjState.lsac_state[chl] = LSAC_INACTIVE_STATE; + } + break; + + case LSAC_FAILED_STATE: + if (mtp3ObjInput.lsac_input_from_stm[chl] != IDLE) + { + mtp3ObjInput.lsac_input_from_stm[chl] = IDLE; + } + if ( mtp3ObjInput.lsac_input_from_tcoc[chl] == LSAC_TCOC_STM_READY ) + { + mtp3ObjInput.lsac_input_from_tcoc[chl] = IDLE; + changeover_in_progress[chl] = FALSE; + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + send_command_to_mtp2(chl,MTP2_ACTIVE_LINK); + mtp3ObjState.lsac_state[chl] = LSAC_RESTORING_STATE; + } + break; + + default: + break; + } +} +/*@end@*/ diff --git a/plat/mtp3/src/mtpsmh.c b/plat/mtp3/src/mtpsmh.c new file mode 100644 index 0000000..f3066e9 --- /dev/null +++ b/plat/mtp3/src/mtpsmh.c @@ -0,0 +1,5375 @@ +#include "./include/mtp3.h" +#include "./include/mtpstm.h" +#include "./include/mtpext.h" +#include "./include/mtpfunc.h" +#include "./include/mtp3lite.h" +#include "../../public/src/include/pub_netcap.h" + +/*@ignore@*/ +extern int mtp3_send_netcap; +#ifndef _M3UA_ +#define _M3UA_ +#endif +iprt1 mtp3_iprt; +#ifdef _INCLUDE_M2UA + static m2ua_up_msg_t *mtp3_m2ua_msg; +#endif +#ifdef _M3UA_ + static xua_up_msg_t *mtp3_m3ua_msg; +#endif +extern tup_shm *T_shm_ptr; +extern isup_shm *I_shm_ptr; +extern bicc_shm *B_shm_ptr; +extern sccp_shm *S_shm_ptr; +ulong msgSourceIP; +extern primitive_to_isup *I_primitive; +extern primitive_to_bicc *B_primitive; +extern primitive_to_sccp *S_primitive; +extern primitive_to_tup *T_primitive; +extern mtp3_routing_result routingResult; +extern void mtp3_debug(int n,const char *fmt,...); +extern BYTE mtp3_check_dpc_equal_to_opc(BYTE nw, ulong dpc); + +static int detail_debug_flag=0; +static int rc_timer=190; +extern DWORD mtp_local_ip, mtp_peer_ip; + +void tsrc_fun5(WORD linkset); +void stop_mtp3T21(WORD linkset); +BOOL Alinkset_status(BYTE routine); +BOOL Nlinkset_status(BYTE routine); +void send_to_host_mtp3(BYTE *msgptr,ulong dst_ip); +int MTP3_LinkIP_List(ulong IP,BYTE mode); +void sp_unaccessable(BYTE *routine); +void mark_normal_linkset_available(BYTE *routine); +void mark_normal_linkset_unavailable(BYTE *routine); +void mark_alternative_linkset_unavailable(BYTE * routine); +void mark_alternative_linkset_available(BYTE * routine); +void mark_dstSP_inaccessible(BYTE *routine); +BYTE get_route_value(u32 dpc, u8 nw, u32 opc); +int send_route_to_other_plat(u32 dpc, BYTE nw, BYTE routine, long dest_ip, WORD chl, u32 opc); +int update_route_by_other_plat(u32 dpc,BYTE nw, BYTE routine, WORD chl, u32 opc); +int scan_ls_link_available(WORD ls_no); +int find_rc_dst_place(DWORD rc, WORD lsno); +int send_command_to_m3ua(WORD link, BYTE command, BYTE xua_msg_class, DWORD rc, DWORD aff_pc); +extern int m2ua_get_traffic_mode_type(); + +void primitive_to_userpart(BYTE nw,long dst,BYTE state) +{ + BYTE I_WSub; + BYTE B_WSub; + BYTE S_WSub; + BYTE T_WSub; + mtp_primitive *I_ptr; + mtp_primitive *B_ptr; + mtp_primitive *S_ptr; + mtp_primitive *T_ptr; + + I_WSub = I_primitive->WSub; + B_WSub = B_primitive->WSub; + S_WSub = S_primitive->WSub; + T_WSub = T_primitive->WSub; + I_ptr = &I_primitive->primitive[I_WSub]; + B_ptr = &B_primitive->primitive[I_WSub]; + S_ptr = &S_primitive->primitive[I_WSub]; + T_ptr = &T_primitive->primitive[I_WSub]; + + I_ptr->pc = dst; + I_ptr->nw_indicator = nw; + I_ptr->availability = state; + + B_ptr->pc = dst; + B_ptr->nw_indicator = nw; + B_ptr->availability = state; + + S_ptr->pc = dst; + S_ptr->nw_indicator = nw; + S_ptr->availability = state; + + T_ptr->pc = dst; + T_ptr->nw_indicator = nw; + T_ptr->availability = state; + + I_primitive->WSub = (I_WSub + 1) & 0x0f; + B_primitive->WSub = (I_WSub + 1) & 0x0f; + S_primitive->WSub = (S_WSub + 1) & 0x0f; + T_primitive->WSub = (T_WSub + 1) & 0x0f; +} + +BYTE *spc_to_acn(BYTE netID,ulong spc)//??- +{ + nw_para *nw; + ulong index; + mtp3DPCIndex *sort_rec = &mtp3SortRoutine.nw[netID]; + ull opc_dpc=0; + + netID = netID % 4; + nw = &mtp3_para->nw[netID]; + + if (pc_length(netID) == MTP3_24BIT_PC) + { + opc_dpc = mtp3_para->nw[netID].opc24; + opc_dpc = (opc_dpc<<32) | spc; + if (nw->opc24 == spc) + return mtp3_para->nw[netID].local_acn; + } + else + { + opc_dpc = mtp3_para->nw[netID].opc14; + opc_dpc = (opc_dpc<<32) | spc; + if (nw->opc14 == spc) + return mtp3_para->nw[netID].local_acn; + } + + + index = Mtp3BinSearchValue(0,sort_rec->sortedNum-1,netID,spc);//??- + if (index>=0 && indexrouting[sort_rec->index[index]].acn; + return NULL; +} + +BYTE mtp3_ansiFlag(BYTE netID) +{ + netID = netID & 3; + return (mtp3_para->nw[netID].pc_type) & 1; +} + +int search_outbound_coLink(WORD chl)/* find outbound changeover link */ +{ + ls_info *ls; + int i; + int lsx16; + WORD adsp_place; + BYTE nw; + int outls; + int outlink; + int lsno; + + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno]; + lsx16 = lsno << 4; + if (ls->links_available > 0) + { + for (i=0; i<16; i++) + { + outlink = ls_slc[lsx16+i]; +/* if ( (mtp3ObjState.link_l3_state[outlink] == AVAILABLE) && + (outlink != chl) && + (mtp3ObjState.link_l2_state[outlink] == MTP2_STATE_WORKING) )*/ + if ( (mtp3ObjState.link_l3_state[outlink] == AVAILABLE) && + (outlink != chl) ) + { + return ls_slc[lsx16+i]; + } + } + return -1; + } + else + { + nw = mtp3_para->ls_pro[lsno].nw_id; + adsp_place = ls->adjacent_sp_place; + if (adsp_place >= MAX_ROUTE) + return -1; + if ( ((mtp3.nw[nw].routine[adsp_place] >> 2) & 3) == 0)/* alternative route available */ + { + outls = mtp3_para->nw[nw].routing[adsp_place].alternative_ls; + lsx16 = outls << 4; + for (i=0; i<16; i++) + { + outlink = ls_slc[lsx16+i]; +/* if ( (mtp3ObjState.link_l3_state[outlink] == AVAILABLE) && + (mtp3ObjState.link_l2_state[outlink] == MTP2_STATE_WORKING) )*/ + if ( (mtp3ObjState.link_l3_state[outlink] == AVAILABLE) ) + { + mtp3_debug(MTP3DB_EVENT,"outlink is %d",outlink); + return outlink; + } + } + return -1; + } + } + return -1; +} + +int pc_length(BYTE nw) +{ + if (((mtp3_para->nw[nw].pc_len) & 1) == 1) + return MTP3_24BIT_PC; + else + return MTP3_14BIT_PC; +} + +void send_to_mtp2(long dest_ip)// send to 8ke1 care +{ + mtp3_iprt.io_msg.msgSrcPort = 4950; + mtp3_iprt.io_msg.msgDstPort = 4950; + mtp3_iprt.io_msg.msgDstIP = dest_ip; +// iptrPutMessage(mtp3_iprt.io_msg); + {//delete one byte of len +// BYTE tmp[300]; + mtp3_iprt.io_msg.msgLength = mtp3_iprt.io_msg.msgContent[3]+2; + mtp3_iprt.io_msg.msgContent[0] = mtp3_iprt.io_msg.msgContent[0];//link + memcpy(&mtp3_iprt.io_msg.msgContent[1], &mtp3_iprt.io_msg.msgContent[3], mtp3_iprt.io_msg.msgContent[2]+1); +// memcpy(&mtp3_iprt.io_msg.msgContent[0], tmp, tmp[1]+2); + } + iptrDirectSendMsg(mtp3_iprt.io_msg); +} + +void send_to_mtp2_new_struct(long dest_ip)//link_high,link_low,len_high,len_low,sio... +{ + mtp3_iprt.io_msg.msgSrcPort = 4950; + mtp3_iprt.io_msg.msgDstPort = 4950; + mtp3_iprt.io_msg.msgDstIP = dest_ip; + + mtp3_iprt.io_msg.msgLength = (mtp3_iprt.io_msg.msgContent[2]<<8) + mtp3_iprt.io_msg.msgContent[3]+3+1; + if(mtp3_iprt.io_msg.msgLength >MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"Send message in SS7 port 4950, length longer than 300, len=%d!", mtp3_iprt.io_msg.msgLength); + return; + } + iptrDirectSendMsg(mtp3_iprt.io_msg); +} +#ifndef _M3UA_ +void send_mtp_msg(int outlink, BYTE *msgptr) +{ + int linkset; + ls_info *ls; + ls_para *ls_pro; + BYTE nw; + ulong dst_ip; + long opc; + long route_mark; + BYTE sls; + BYTE pclen; + WORD len; + BYTE ssf; + BYTE debugtype=0; + + if(msgptr == NULL) + { + return; + } + ssf = msgptr[3] & 0x0f; + linkset = mtp3_para->lk[outlink].e1_to_linkset; + ls = &mtp3.ls[linkset]; + ls_pro = &mtp3_para->ls_pro[linkset]; + nw = ls_pro->nw_id; + pclen = pc_length(nw); + if ( (ls_pro->loopback_opt) != 0 )/* this linkset is loop back linkset */ + { + if ( pclen == MTP3_24BIT_PC ) + { + opc = mtp3_para->nw[nw].opc24; + memcpy( &msgptr[3],&opc,3);/* change msg's dpc to opc */ + } + else + { + opc = mtp3_para->nw[nw].opc14; + memcpy( (BYTE*)&route_mark,&msgptr[3],4); + sls = (route_mark >> 28) & 0xf; + route_mark = (sls << 28)+(opc << 14)+opc; + memcpy(&msgptr[3],&route_mark,4); + } + } + + if (ssf > 1) + { + ssf--; + debugtype = MTP_MSG_DOWN; + } + else + debugtype = MTP_SNM_MSG; +// current_measure->tf_measure1[4][wx5[nw]+ssf]+=len;/* octets */ + current_measure->tf_measure2[4][wx5[nw]+ssf]++;/* MSUs */ + +// len = msgptr[1]+2; + len = (msgptr[1]<<8) + msgptr[2]+3; + if(len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"send_mtp_msg, length longer than 300, len=%d!", len); + msgptr[1] = 0; + len = MAX_SS7_MSG_LEN; + } + mtp3_iprt.io_msg.msgLength = len; + + if( mtp3_send_netcap && ( ( msgptr[3] & 0xF0) != 0xF0 ) ) + { + int pclen; + BYTE sio; + BYTE nw; + + sio = msgptr[3]; + nw = sio >> 6; + pclen = pc_length(nw); + + if ( pclen == MTP3_24BIT_PC ) //ansi + { + NcMtp3Send ( &msgptr[3], (msgptr[1]<<8) + msgptr[2], 1 ); + } + else if ( pclen == MTP3_14BIT_PC ) //ITU + { + NcMtp3Send ( &msgptr[3], (msgptr[1]<<8) + msgptr[2], 0 ); + } + } + +#if _INCLUDE_M2UA + if (mtp3ObjState.lk_mtp3[outlink] != mtp3_localip) + {//transfer to remote plat + dst_ip = mtp3ObjState.lk_mtp3[outlink]; + //dst_ip = (dst_ip << 16) | E1CARD_BASE_IP; + /* debug show message */ + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ +// send_to_mtp2(dst_ip); + send_to_mtp2_new_struct(dst_ip); + } + else if (MTP3_LINK_TYPE(outlink) == LKTYPE_NONE_SIGTRAN) +#endif + { + dst_ip = LINK_TO_IP(outlink); + /* debug show message */ + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ + send_to_mtp2(dst_ip);//use old struct send to 8k bload + } +#if _INCLUDE_M2UA + else + { + if (MTP3_LINK_TYPE(outlink) == LKTYPE_MTP3_LITE) + { + /* debug show message */ + dst_ip = mtp3_para->lk[outlink].remote_ip; + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ + if ((msgptr[4] & 0x0f) == 3) + put_mtp3lite_msg(msgptr); + return; + } + else + { + dst_ip = mtp3_para->sg[mtp3_para->lk[outlink].e1_to_sg].ip; + /* debug show message */ + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ + put_m2ua_msg((m2ua_up_msg_t *)msgptr); + return; + } + } +#endif + + +} +#endif +int check_snmmsg_route(WORD ls) +{ + WORD sp_place; + BYTE nw; + BYTE routine; + WORD outbound_ls=MAX_LS; + int outlink=MAX_LK_INDEX; + int lsx16; + int i; + + if (mtp3.ls[ls].links_available_t > 0) + { + outbound_ls = ls; + } + else + { + sp_place = mtp3.ls[ls].adjacent_sp_place; + if (sp_place >= MAX_ROUTE) + return -1; + nw = mtp3_para->ls_pro[ls].nw_id; + routine = mtp3.nw[nw].routine[sp_place]; + if ( (routine & 3) == NLS_AVAILABLE ) + outbound_ls = mtp3_para->nw[nw].routing[sp_place].normal_ls; + else if ( ((routine >> 2) & 3) == ALS_AVAILABLE ) + outbound_ls = mtp3_para->nw[nw].routing[sp_place].alternative_ls; + else + { +// mtp3_debug(MTP3DB_ERROR,"ls %d Can't find Outbound LS TO LS-Remote PC when SNM\n\r",ls); + return -1; + } + } + lsx16 = outbound_ls << 4; + for (i=0; i<16; i++) + { + outlink = ls_slc[lsx16+i]; + if ( mtp3ObjState.link_l3_state[outlink] == AVAILABLE ) + { + return outlink; + } + else if (mtp3ObjState.link_l2_state[outlink] == MTP2_STATE_WORKING) + { + if (changeback_in_progress[outlink] == TRUE) + { + return outlink; + } + } + } + return -1; +} + +void hmrt_srm_msg(WORD linkset, BYTE MsgType, long dst) +{ + ls_info *ls; + BYTE nw; + long route_mark; + BYTE *sd_tmp_buf; + int outlink; + + if (linkset >= MAX_LS) + return; + if (dst == mtp3_para->ls_pro[linkset].ls_op_pc) + return; + outlink = check_snmmsg_route(linkset); + if (outlink == -1) + return; + ls = &mtp3.ls[linkset]; + nw = mtp3_para->ls_pro[linkset].nw_id; + + sd_tmp_buf = &mtp3_iprt.io_msg.msgContent[0]; + if ( pc_length(nw) == MTP3_24BIT_PC ) + { + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 12; + sd_tmp_buf[4] = nw << 6; + memcpy(&sd_tmp_buf[5],&mtp3_para->ls_pro[linkset].ls_op_pc,3); + //memcpy(&sd_tmp_buf[7],&mtp3_para->nw[nw].opc24,3); + if(mtp3_para->ls_pro[linkset].ls_opc==0) + memcpy(&sd_tmp_buf[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&sd_tmp_buf[8],&mtp3_para->ls_pro[linkset].ls_opc,3); + sd_tmp_buf[11] = 0; + sd_tmp_buf[12] = MsgType; + memcpy(&sd_tmp_buf[13],&dst,3); + } + else + { + if(mtp3_para->ls_pro[linkset].ls_opc==0) + route_mark = (mtp3_para->nw[nw].opc14 << 14) + mtp3_para->ls_pro[linkset].ls_op_pc; + else + route_mark = (mtp3_para->ls_pro[linkset].ls_opc << 14) + mtp3_para->ls_pro[linkset].ls_op_pc; + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 8; + sd_tmp_buf[4] = nw << 6; + memcpy(&sd_tmp_buf[5],&route_mark,4); + sd_tmp_buf[9] = MsgType; + memcpy(&sd_tmp_buf[10],&dst,2); + } + sd_tmp_buf[1] = outlink>>8; + sd_tmp_buf[0] = outlink & 0xff; + send_mtp_msg(outlink,sd_tmp_buf); +} + +int priority_own_link(WORD lsno,WORD sls) +{ + ls_info *ls; + int i; + WORD link; + + if (lsno >= MAX_LS_NUM) + return -1; + + ls = &mtp3.ls[lsno]; + + if(detail_debug_flag) + { + if(1) + { + char buf[256]; + char strbuf[1024]; + + mtp3_debug(MTP3DB_EVENT, "%s, linkset=%d, sls=%d, linkconfigred=%d ", + __FUNCTION__, + lsno, + sls, + mtp3.ls[lsno].linksNum_configured); + memset(strbuf, 0x00, 16); + for(i=0;i<2; i++) + { + link = ls_sls[(lsno<<4)+i]; + sprintf(buf, "ls_sls[%02d]=%d, ip=%08x, state=%d", + i, + ls_sls[(lsno<<4)+i], + mtp3_para->lk[link].e1_to_mtp3, + mtp3ObjState.link_l3_state[link]); + strcat(strbuf, buf); + } + mtp3_debug(MTP3DB_EVENT, "%s, %s ", + __FUNCTION__, + strbuf); + } + } + + for (i=0;i<16;i++) +// for (i=0;ilk[link].e1_to_mtp3 == mtp3_localip && mtp3ObjState.link_l3_state[link] == AVAILABLE) + return link; + } + + for (i=0;i<16;i++) +// for (i=0;i= MAX_LS_NUM) + return -1; + + ls = &mtp3.ls[lsno]; + for (i=0;isend_asp_ac_link_id == link) + return link; + } + + for (i=0;ilk[link].e1_to_mtp3 != mtp3_localip && mtp3ObjState.link_l3_state[link] == AVAILABLE) + return link; + } + + for (i=0;ilk[link].e1_to_mtp3 == mtp3_localip && mtp3ObjState.link_l3_state[link] == AVAILABLE) + return link; + } + + return ls_sls[(lsno<<4)+(sls & 15)]; +} + +int check_outbound_route(BYTE nw, long dpc, WORD sls, long opc) +{ + network *sp; + BYTE outroute; + WORD ls; + WORD i; + BYTE routine; + WORD nls; + mtp3DPCIndex *sort_rec = &mtp3SortRoutine.nw[nw]; + int index; + WORD outlink; + ull opc_dpc=0; + + ls_info *ls_info; + + if (dpc==0) + return -3; + + sp = &mtp3.nw[nw]; + if(opc == mtp3_para->nw[nw].opc14) + { + opc =0; + } + opc_dpc = opc; + opc_dpc = (opc_dpc <<32)|dpc; + index = Mtp3BinSearchValue(0,sort_rec->sortedNum-1,nw,opc_dpc); + if ((index >= 0) && (index < MAX_ROUTE)) + i = sort_rec->index[index]; + else + return -3; + + routine = sp->routine[i]; + outroute = (routine >> 6) & 3; + if ( outroute == 2 )/* no outbound route */ + { + nls = mtp3_para->nw[nw].routing[i].normal_ls; + if (mtp3.ls[nls].linksNum_configured > 0) +// if (linknum_in_ls[nls] > 0) + return -1; + else + return -2; + } + else if ( (outroute == 0) && + ((routine & 3) == NLS_AVAILABLE) )/* current route is normal route */ + { + ls = mtp3_para->nw[nw].routing[i].normal_ls; + outlink = ls_sls[(ls<<4)+sls]; + + ls_info = &mtp3.ls[ls]; + + /* added for override link status -- start */ + /* + if(m2ua_get_traffic_mode_type()==0) + { + if(ls_info->send_asp_ac_link_id>0 && ls_info->send_asp_ac_link_id != 0xffff) + { + + return ls_info->send_asp_ac_link_id; + } + //if(ls_info->send_asp_ac_link_id != outlink) + { + int link_no = get_asp_ac_link(ls,sls); + + + return link_no; + } + } + */ + /* added for override link status -- end*/ + + if (mtp3_para->lk[outlink].e1_to_mtp3 == mtp3_localip && mtp3ObjState.link_l3_state[outlink] == AVAILABLE) + return outlink; + else + return priority_own_link(ls,sls); + } + else if ( ((routine >> 2) & 3) == ALS_AVAILABLE) + { + ls = mtp3_para->nw[nw].routing[i].alternative_ls; + outlink = ls_sls[(ls<<4)+sls]; + + ls_info = &mtp3.ls[ls]; + + /* added for override link status -- start */ + /* + if(m2ua_get_traffic_mode_type()==0) + { + if(ls_info->send_asp_ac_link_id>0 && ls_info->send_asp_ac_link_id != 0xffff) + { + + return ls_info->send_asp_ac_link_id; + } + //if(ls_info->send_asp_ac_link_id != outlink) + { + int link_no = get_asp_ac_link(ls,sls); + + + return link_no; + } + } + */ + /* added for override link status -- end*/ + + if (mtp3_para->lk[outlink].e1_to_mtp3 == mtp3_localip && mtp3ObjState.link_l3_state[outlink] == AVAILABLE) + return outlink; + else + return priority_own_link(ls,sls); + } + else + { + ls = mtp3_para->nw[nw].routing[i].alternative_ls; + outlink = ls_sls[(ls<<4)+sls]; + + ls_info = &mtp3.ls[ls]; + + if(mtp3_para->ls_pro[ls].ls_state == 1) + { + if (mtp3_para->lk[outlink].e1_to_mtp3 == mtp3_localip && mtp3ObjState.link_l3_state[outlink] == AVAILABLE) + return outlink; + else + return priority_own_link(ls,sls); + } + } + + return -3; +} + +/* pc_length:point code type + * ss7 network has two kind of point code,one is 14bits length, + * another is 24bits length */ + +int send_to_sccp(BYTE *msgptr)/* send sccp msg to tele user part */ +{ + up_message *ToSccp; + WORD len; + long route_mark;/* route mark */ + BYTE pclen; + BYTE nw; + BYTE sio; + WORD link; + + sio = msgptr[4]; + nw = sio >> 6; + sio = sio & 0xEF;//init spare bit + sio = sio | (mtp3_ansiFlag(nw) << 4); + ToSccp = &S_shm_ptr->MS_Buf.msgNum[S_shm_ptr->MS_Buf.WSub]; + link = msgptr[1]*256+msgptr[0]; + ToSccp->link = link; + ToSccp->dest_ip = msgSourceIP; + + pclen = pc_length(nw); + if (pclen == MTP3_24BIT_PC)/* for 24bit ss7 network */ + { + if (msgptr[2] == 0 && msgptr[3] < 9)//len < 9 + { + mtp3ObjState.MTP3WatchDog[3]++; + mtp3.nw[nw].flow.MtoU_throwed[0]++; + mtp3_debug(MTP3DB_ERROR,"[SCCP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr[3],link); + return 0; + } + + memcpy((BYTE *)&ToSccp->dpc,msgptr+5,3);/* message's dpc */ + memcpy((BYTE *)&ToSccp->opc,&msgptr[8],3);/* message's opc */ + ToSccp->sio = sio; + ToSccp->cic[0] = msgptr[11]; + len = (msgptr[2]<<8) + msgptr[3]-8; + ToSccp->len = len; + memcpy(&ToSccp->msgList,&msgptr[12],len); + } + else + { + if (msgptr[2] == 0 && msgptr[3] < 6) + { + mtp3ObjState.MTP3WatchDog[4]++; + mtp3.nw[nw].flow.MtoU_throwed[0]++; + mtp3_debug(MTP3DB_ERROR,"[SCCP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr[3],link); + return 0; + } + + memcpy((BYTE*)&route_mark,&msgptr[5],4);/* include message's dpc,opc,sls */ + ToSccp->cic[0] = (route_mark >> 28) & 0xf; + ToSccp->opc = (route_mark & 0x0FFFFFFF) >> 14; + ToSccp->dpc = (route_mark & 0x3FFF); + ToSccp->sio = sio; + len = (msgptr[2]<<8) + msgptr[3] -5; + ToSccp->len = len; + memcpy(&ToSccp->msgList,&msgptr[9],len); + } + S_shm_ptr->MS_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[2]++; + return 1; +} + +int send_to_sccp_lite(up_message *msgptr)/* send sccp-lite msg to sccp */ +{ + up_message *ToSccp; + BYTE nw; + + nw = msgptr->sio >> 6; + + ToSccp = &S_shm_ptr->MS_Buf.msgNum[S_shm_ptr->MS_Buf.WSub]; + memcpy((BYTE *)ToSccp, (BYTE *)msgptr, sizeof(up_message)); + + S_shm_ptr->MS_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[2]++; + + return 1; +} + +int send_to_tup(BYTE *msgptr)/* send tup msg to tele user part */ +{ + BYTE sio; + WORD len; + up_message *ToTup; + long route_mark; + BYTE pclen; + BYTE nw; + WORD link; + + sio = msgptr[4]; + + nw = sio >> 6; + sio = sio & 0xEF;//init spare bit + sio = sio | (mtp3_ansiFlag(nw) << 4); + link = msgptr[1]*256+msgptr[0]; + pclen = pc_length(nw); + ToTup = &T_shm_ptr->MT_Buf.msgNum[T_shm_ptr->MT_Buf.WSub]; + ToTup->link = link; + ToTup->dest_ip = msgSourceIP; + + if (pclen == MTP3_24BIT_PC)/* for 24bits network */ + { + if (msgptr[2] == 0 && msgptr[3] < 10) + { + mtp3ObjState.MTP3WatchDog[5]++; + mtp3.nw[nw].flow.MtoU_throwed[1]++; + mtp3_debug(MTP3DB_ERROR,"[TUP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr[3],link); + return 0; + } + + ToTup->sio = sio; + memcpy((BYTE*)&ToTup->dpc,&msgptr[5],3);/* message's dpc */ + memcpy((BYTE*)&ToTup->opc,&msgptr[8],3);/* message's opc */ + ToTup->cic[0] = msgptr[11]; + ToTup->cic[1] = msgptr[12]; + len = (msgptr[2]<<8) + msgptr[3] -9; + ToTup->len = len; + memcpy(&ToTup->msgList,&msgptr[13],len); + } + else/* for 14bits network */ + { + if (msgptr[2] == 0 && msgptr[3] < 7) + { + mtp3ObjState.MTP3WatchDog[6]++; + mtp3.nw[nw].flow.MtoU_throwed[1]++; + mtp3_debug(MTP3DB_ERROR,"[TUP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr[3],link); + return 0; + } + + memcpy((BYTE*)&route_mark,&msgptr[5],4);/* include message's dpc,opc,sls */ + ToTup->opc = (route_mark & 0x0FFFFFFF) >> 14; + ToTup->dpc = (route_mark & 0x3FFF); + ToTup->cic[0] = (msgptr[8] >> 4) + ((msgptr[9] & 0x0f) << 4); + ToTup->cic[1] = (msgptr[9] >> 4); + ToTup->sio = sio; + len = (msgptr[2]<<8) + msgptr[3] - 6; + ToTup->len = len; + memcpy(&ToTup->msgList,&msgptr[10],len); + } + T_shm_ptr->MT_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[3]++; + return 1; +} + +void MTP3_recv_isup_count(BYTE nw,BYTE type) +{ + switch (type) + { + case MTP3_ISUP_IAM: + mtp3.nw[nw].flow.isup_detail[0]++; + break; + case MTP3_ISUP_ACM: + mtp3.nw[nw].flow.isup_detail[1]++; + break; + case MTP3_ISUP_CPG: + mtp3.nw[nw].flow.isup_detail[2]++; + break; + case MTP3_ISUP_ANM: + mtp3.nw[nw].flow.isup_detail[3]++; + break; + case MTP3_ISUP_REL: + mtp3.nw[nw].flow.isup_detail[4]++; + break; + case MTP3_ISUP_RLC: + mtp3.nw[nw].flow.isup_detail[5]++; + break; + default: + break; + } +} + +int send_to_isup(BYTE *msgptr)/* send isup msg to tele user part */ +{ + BYTE sio; + WORD len; + up_message *ToIsup; + long route_mark; + BYTE pclen; + BYTE nw; + WORD link; + + sio = msgptr[4]; + nw = sio >> 6; + sio = sio & 0xEF;//init spare bit + sio = sio | (mtp3_ansiFlag(nw) << 4); + ToIsup = &I_shm_ptr->MI_Buf.msgNum[I_shm_ptr->MI_Buf.WSub]; + pclen = pc_length(nw); + link = msgptr[1]*256+msgptr[0]; + ToIsup->link = link; + ToIsup->dest_ip = msgSourceIP; + if (pclen == MTP3_24BIT_PC)/* for 24bit ss7 network */ + { + if (msgptr[2] == 0 && msgptr[3] < 11) + { + mtp3ObjState.MTP3WatchDog[7]++; + mtp3.nw[nw].flow.MtoU_throwed[2]++; + mtp3_debug(MTP3DB_ERROR,"[ISUP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr[3],link); + return 0; + } + + memcpy((BYTE*)&ToIsup->dpc,&msgptr[5],3); + memcpy((BYTE*)&ToIsup->opc,&msgptr[8],3); + ToIsup->sio = sio; + ToIsup->cic[0] = msgptr[12]; + ToIsup->cic[1] = msgptr[13]; + len = (msgptr[2]<<8) + msgptr[3] -10; + ToIsup->len = len; + memcpy(&ToIsup->msgList,&msgptr[14],len); + MTP3_recv_isup_count(nw,msgptr[14]); + } + else/* for 14bit ss7 network */ + { + if (msgptr[2] == 0 && msgptr[3] < 8) + { + mtp3ObjState.MTP3WatchDog[8]++; + mtp3.nw[nw].flow.MtoU_throwed[2]++; + mtp3_debug(MTP3DB_ERROR,"[ISUP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr[3],link); + return 0; + } + + memcpy((BYTE*)&route_mark,&msgptr[5],4);/* include message's dpc,opc,sls */ + ToIsup->opc = (route_mark & 0x0FFFFFFF) >> 14; + ToIsup->dpc = (route_mark & 0x3FFF); + ToIsup->sio = sio; + ToIsup->cic[0] = msgptr[9]; + ToIsup->cic[1] = msgptr[10]; + len = (msgptr[2]<<8) + msgptr[3] -7; + ToIsup->len = len; + memcpy(&ToIsup->msgList,&msgptr[11],len); + MTP3_recv_isup_count(nw,msgptr[11]); + } + I_shm_ptr->MI_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[4]++; + return 1; +} + +int send_to_bicc(BYTE *msgptr)/* send isup msg to tele user part */ +{ + BYTE sio; + WORD len; + up_message_2 *ToBicc; + long route_mark; + BYTE pclen; + BYTE nw; + WORD link; + + sio = msgptr[4]; + nw = sio >> 6; + sio = sio & 0xEF;//init spare bit + sio = sio | (mtp3_ansiFlag(nw) << 4); + ToBicc = &B_shm_ptr->MI_Buf.msgNum[B_shm_ptr->MI_Buf.WSub]; + pclen = pc_length(nw); + link = msgptr[1]*256+msgptr[0]; + ToBicc->link = link; + ToBicc->dest_ip = msgSourceIP; + if (pclen == MTP3_24BIT_PC)/* for 24bit ss7 network */ + { + memcpy((BYTE*)&ToBicc->dpc,&msgptr[5],3); + memcpy((BYTE*)&ToBicc->opc,&msgptr[8],3); + ToBicc->sio = sio; + ToBicc->cic[0] = msgptr[12]; + ToBicc->cic[1] = msgptr[13]; + ToBicc->cic[2] = msgptr[14]; + ToBicc->cic[3] = msgptr[15]; + len = (msgptr[2]<<8) + msgptr[3] -12; + ToBicc->len = len; + memcpy(&ToBicc->msgList,&msgptr[16],len); + } + else/* for 14bit ss7 network */ + { + memcpy((BYTE*)&route_mark,&msgptr[5],4);/* include message's dpc,opc,sls */ + ToBicc->opc = (route_mark & 0x0FFFFFFF) >> 14; + ToBicc->dpc = (route_mark & 0x3FFF); + ToBicc->sio = sio; + ToBicc->cic[0] = msgptr[9]; + ToBicc->cic[1] = msgptr[10]; + ToBicc->cic[2] = msgptr[11]; + ToBicc->cic[3] = msgptr[12]; + len = (msgptr[2]<<8) + msgptr[3] -9; + ToBicc->len = len; + memcpy(&ToBicc->msgList,&msgptr[13],len); + } + B_shm_ptr->MI_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[4]++; + return 1; +} + +int get_sccp(up_message *GetSccp) +{ + WORD len; + BYTE sio; + long route_mark;/* dpc opc sls */ + BYTE sls; + long dpc; + BYTE pclen; + int outlink=0; + long dest_ip; + BYTE *msgptr; + BYTE nw; + BYTE rSub; + + rSub = S_shm_ptr->SM_Buf.RSub; + if (rSub != S_shm_ptr->SM_Buf.WSub) + { + GetSccp = &S_shm_ptr->SM_Buf.msgNum[rSub]; + sio = GetSccp->sio & 0xcf; + dpc = GetSccp->dpc; + sls = GetSccp->cic[0] & 0x0f; + nw = (sio >> 6) & 3; + pclen = pc_length(nw); + len = GetSccp->len; + + dest_ip = GetSccp->dest_ip; + if (dest_ip == 0xffffffff) + { + outlink = routingResult.sccpMsgOutLink[rSub]; +// outlink = check_outbound_route(nw,dpc,sls); + if ( outlink < 0 ) + { + mtp3_debug(MTP3DB_ERROR,"USER==>MTP3,sio=%x,dpc=%lx",GetSccp->sio,GetSccp->dpc); + mtp3_showbuf(MTP3DB_ERROR,GetSccp->msgList,GetSccp->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:program bug"); + S_shm_ptr->SM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[2]++; + return 0; + } + } + else{ + outlink = GetSccp->link; + } + + msgptr = &mtp3_iprt.io_msg.msgContent[0]; + len = GetSccp->len; + if (pclen == MTP3_24BIT_PC) + { + mtp3_iprt.io_msg.msgLength = len + 10+1+1; + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (len+8)>>8; + msgptr[3] = (len+8) & 0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&dpc,3); + if(GetSccp->opc==0) + memcpy(&msgptr[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&msgptr[8],&GetSccp->opc,3); + memcpy(&msgptr[11],&GetSccp->cic[0],1); + memcpy(&msgptr[12],&GetSccp->msgList,len); + } + else + { + if(GetSccp->opc==0) + route_mark = (GetSccp->cic[0] << 28)+(mtp3_para->nw[nw].opc14 << 14)+dpc; + else + route_mark = (GetSccp->cic[0] << 28)+(GetSccp->opc << 14)+dpc; + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (len+5)>>8; + msgptr[3] = (len+5) & 0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&route_mark,4); + memcpy(&msgptr[9],&GetSccp->msgList,len); + } + len = (msgptr[2]<<8) | msgptr[3]; +// if ((msgptr[1] < 5) || (msgptr[1] > 0xfd)) + if ((len < 5) || (len > MAX_SS7_MSG_LEN)) + { + mtp3ObjState.MTP3WatchDog[10]++; + mtp3_debug(MTP3DB_ERROR,"[SCCP]USER==>MTP3,LI over range and discarded! LI=%04d,Link=%d",len,outlink); + mtp3_showbuf(MTP3DB_ERROR,&msgptr[0],len + 3+1); + S_shm_ptr->SM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[2]++; + return 0; + } + + mtp3.nw[nw].flow.MtoI[2]++; + if (dest_ip == 0xffffffff) + { + send_mtp_msg(outlink,msgptr); + } + else + { + mtp3_iprt.io_msg.msgLength = len + 3+1; + if (iptrans_msg_flow(msgptr,pclen,MTP_MSG_OTHER_SERVER,dest_ip)); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + +/* in.s_addr = dest_ip; + mtp3_debug(MTP3DB_SCCPMSG,"USER==>MTP3,sio=%x,dpc=%lx",GetSccp->sio,GetSccp->dpc); + mtp3_debug(MTP3DB_SCCPMSG,"perform routing:%dBIT LI=%x LINK=%x IP=%s",pclen,sio,sls,inet_ntoa(in)); + userpart_msg_flow(msgptr);*/ + + } + S_shm_ptr->SM_Buf.RSub ++; + } + return 1; +} + +int get_tup(up_message *GetTup) +{ + int outlink=0; + WORD len; + BYTE sio; + long route_mark; + long dpc; + BYTE sls; + BYTE pclen; + BYTE *msgptr; + BYTE nw; + ulong dest_ip; + BYTE rSub; + + rSub = T_shm_ptr->TM_Buf.RSub; + if (rSub != T_shm_ptr->TM_Buf.WSub) + { + + GetTup = &T_shm_ptr->TM_Buf.msgNum[rSub]; + sio = GetTup->sio & 0xcf; + dpc = GetTup->dpc; + sls = GetTup->cic[0] & 0x0f; + nw = (sio >> 6) & 3; + pclen = pc_length(nw); + len = GetTup->len; + + dest_ip = GetTup->dest_ip; + if (dest_ip == 0xffffffff) + { + outlink = routingResult.tupMsgOutLink[rSub]; +// outlink = check_outbound_route(nw,dpc,sls); + if ( outlink < 0 ) + { + mtp3_debug(MTP3DB_ERROR,"receive message from UP,sio=%x,dpc=%lx",GetTup->sio,GetTup->dpc); + mtp3_showbuf(MTP3DB_ERROR,GetTup->msgList,GetTup->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:program bug"); + T_shm_ptr->TM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[3]++; + return 0; + } + } + else + outlink = GetTup->link; + + msgptr = &mtp3_iprt.io_msg.msgContent[0]; + if (pclen == MTP3_24BIT_PC) + { + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (len+9)>>8; + msgptr[3] = (len+9) & 0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&dpc,3); + + //memcpy(&msgptr[6],&mtp3_para->nw[nw].opc24,3); + + if (dest_ip == 0xffffffff) + { + if (GetTup->opc == 0) + memcpy(&msgptr[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&msgptr[8],&GetTup->opc,3);//keep the UP filled opc + } + else + memcpy(&msgptr[8],&GetTup->opc,3);//keep the UP filled opc + + memcpy(&msgptr[11],&GetTup->cic[0],2); + memcpy(&msgptr[13],&GetTup->msgList,len); + } + else + { + //route_mark = (GetTup->cic[0] << 28)+(mtp3_para->nw[nw].opc14 << 14)+dpc; + + if (dest_ip == 0xffffffff) + { + if (GetTup->opc == 0) + route_mark = (GetTup->cic[0] << 28)+(mtp3_para->nw[nw].opc14 << 14)+dpc; + else + route_mark = (GetTup->cic[0] << 28)+(GetTup->opc << 14)+dpc;//keep the UP filled opc + } + else + route_mark = (GetTup->cic[0] << 28)+(GetTup->opc << 14)+dpc;//keep the UP filled opc + + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (GetTup->len+6)>>8; + msgptr[3] = (GetTup->len+6) & 0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&route_mark,4); + msgptr[9] = (GetTup->cic[0] >> 4) + (GetTup->cic[1] << 4); + memcpy(&msgptr[10],&GetTup->msgList,len); + } + + len = (msgptr[2]<<8) | msgptr[3]; +// if ((msgptr[1] < 5) || (msgptr[1] > 0xfd)) + if ((len < 5) || (len > MAX_SS7_MSG_LEN)) + { + mtp3ObjState.MTP3WatchDog[12]++; + mtp3_debug(MTP3DB_ERROR,"[TUP]USER==>MTP3,LI over range and discarded! LI=%04d,Link=%d",len,outlink); + mtp3_showbuf(MTP3DB_ERROR,&msgptr[0],len+3+1); + T_shm_ptr->TM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[3]++; + return 0; + } + + mtp3.nw[nw].flow.MtoI[3]++; + if (dest_ip == 0xffffffff) + { + send_mtp_msg(outlink,msgptr); + } + else + { + mtp3_iprt.io_msg.msgLength = len+3+1; + if (iptrans_msg_flow(msgptr,pclen,MTP_MSG_OTHER_SERVER,dest_ip)); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + } + T_shm_ptr->TM_Buf.RSub ++; + } + return 1; +} + +void MTP3_send_isup_count(BYTE nw,BYTE type) +{ + switch (type) + { + case MTP3_ISUP_IAM: + mtp3.nw[nw].flow.isup_detail[16]++; + break; + case MTP3_ISUP_ACM: + mtp3.nw[nw].flow.isup_detail[17]++; + break; + case MTP3_ISUP_CPG: + mtp3.nw[nw].flow.isup_detail[18]++; + break; + case MTP3_ISUP_ANM: + mtp3.nw[nw].flow.isup_detail[19]++; + break; + case MTP3_ISUP_REL: + mtp3.nw[nw].flow.isup_detail[20]++; + break; + case MTP3_ISUP_RLC: + mtp3.nw[nw].flow.isup_detail[21]++; + break; + default: + break; + } +} + +int get_isup(up_message *GetIsup) +{ + int outlink=0; + WORD len; + BYTE sio; + long route_mark; + long dpc; + BYTE sls; + BYTE pclen; + BYTE *msgptr; + BYTE nw; + ulong dest_ip; + BYTE rSub; + + rSub = I_shm_ptr->IM_Buf.RSub; + if (rSub != I_shm_ptr->IM_Buf.WSub) + { + + GetIsup = &I_shm_ptr->IM_Buf.msgNum[rSub]; + sio = GetIsup->sio & 0xcf; + dpc = GetIsup->dpc; + sls = GetIsup->cic[0] & 0x0f; + nw = (sio >> 6) & 3; + pclen = pc_length(nw); + len = GetIsup->len; + + dest_ip = GetIsup->dest_ip; + if (dest_ip == 0xffffffff) + { + outlink = routingResult.isupMsgOutLink[rSub]; +// outlink = check_outbound_route(nw,dpc,sls); + if ( outlink < 0 ) + { + mtp3_debug(MTP3DB_ERROR,"receive message from UP,sio=%x,dpc=%lx",GetIsup->sio,GetIsup->dpc); + mtp3_showbuf(MTP3DB_ERROR,GetIsup->msgList,GetIsup->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:program bug"); + I_shm_ptr->IM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[4]++; + return 0; + } + } + else + outlink = GetIsup->link; + msgptr = &mtp3_iprt.io_msg.msgContent[0]; + if (pclen == MTP3_24BIT_PC) + { + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (len + 10)/0xff; + msgptr[3] = (len + 10)&0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&dpc,3); + + if (dest_ip == 0xffffffff) + { + if (GetIsup->opc == 0) + memcpy(&msgptr[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&msgptr[8],&GetIsup->opc,3);//keep the UP filled opc + } + else + memcpy(&msgptr[8],&GetIsup->opc,3);//keep the UP filled opc + + msgptr[11] = GetIsup->cic[0] & 0x0f; + memcpy(&msgptr[12],&GetIsup->cic[0],2); + memcpy(&msgptr[14],&GetIsup->msgList,len); + MTP3_send_isup_count(nw,msgptr[14]); + } + else + { + if (dest_ip == 0xffffffff) + { + if (GetIsup->opc == 0) + route_mark = (GetIsup->cic[0] << 28)+(mtp3_para->nw[nw].opc14 << 14)+dpc; + else + route_mark = (GetIsup->cic[0] << 28)+(GetIsup->opc << 14)+dpc;//keep the UP filled opc + } + else + route_mark = (GetIsup->cic[0] << 28)+(GetIsup->opc << 14)+dpc;//keep the UP filled opc + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (len+7)/0xff; + msgptr[3] = (len+7)&0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&route_mark,4); + memcpy(&msgptr[9],&GetIsup->cic,2); + memcpy(&msgptr[11],&GetIsup->msgList,len); + MTP3_send_isup_count(nw,msgptr[11]); + } + + len = (msgptr[2]<<8) | msgptr[3]; +// if ((msgptr[1] < 5) || (msgptr[1] > 0xfd)) + if ((len < 5) || (len > MAX_SS7_MSG_LEN)) + { + mtp3ObjState.MTP3WatchDog[14]++; + mtp3_debug(MTP3DB_ERROR,"[ISUP]USER==>MTP3,LI over range and discarded! LI=%04d,Link=%d",len,outlink); + mtp3_showbuf(MTP3DB_ERROR,&msgptr[0],len+3+1); + I_shm_ptr->IM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[4]++; + return 0; + } + + mtp3.nw[nw].flow.MtoI[4]++; + if (dest_ip == 0xffffffff) + { + send_mtp_msg(outlink,msgptr); + } + else + { + mtp3_iprt.io_msg.msgLength = len+3+1; + if (iptrans_msg_flow(msgptr,pclen,MTP_MSG_OTHER_SERVER,dest_ip)); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + } + I_shm_ptr->IM_Buf.RSub ++; + } + return 1; +} + +int get_bicc(up_message_2 *GetBicc) +{ + int outlink=0; + WORD len; + BYTE sio; + long route_mark; + long dpc; + BYTE sls; + BYTE pclen; + BYTE *msgptr; + BYTE nw; + ulong dest_ip; + BYTE rSub; + + rSub = B_shm_ptr->IM_Buf.RSub; + if (rSub != B_shm_ptr->IM_Buf.WSub) + { + GetBicc = &B_shm_ptr->IM_Buf.msgNum[rSub]; + sio = GetBicc->sio; + dpc = GetBicc->dpc; + sls = GetBicc->cic[0] & 0x0f; + nw = (sio >> 6) & 3; + pclen = pc_length(nw); + len = GetBicc->len; + + dest_ip = GetBicc->dest_ip; + if (dest_ip == 0xffffffff) + { + outlink = routingResult.biccMsgOutLink[rSub]; +// outlink = check_outbound_route(nw,dpc,sls); + if ( outlink < 0 ) + { + mtp3_debug(MTP3DB_ERROR,"receive message from UP,sio=%x,dpc=%lx",GetBicc->sio,GetBicc->dpc); + mtp3_showbuf(MTP3DB_ERROR,GetBicc->msgList,GetBicc->len); + mtp3_debug(MTP3DB_ERROR,"perform routing:Route Failure,Reason:program bug"); + B_shm_ptr->IM_Buf.RSub ++; + mtp3.nw[nw].flow.MtoI_throwed[4]++; + return 0; + } + } + else + outlink = GetBicc->link; + msgptr = &mtp3_iprt.io_msg.msgContent[0]; + if (pclen == MTP3_24BIT_PC) + { + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (len + 12)/0xff; + msgptr[3] = (len + 12)&0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&dpc,3); + + //memcpy(&msgptr[6],&mtp3_para->nw[nw].opc24,3); + + if (dest_ip == 0xffffffff) + { + if (GetBicc->opc == 0) + memcpy(&msgptr[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&msgptr[8],&GetBicc->opc,3);//keep the UP filled opc + } + else + memcpy(&msgptr[8],&GetBicc->opc,3);//keep the UP filled opc + + msgptr[11] = GetBicc->cic[0] & 0x0f; + memcpy(&msgptr[12],&GetBicc->cic[0],4); + memcpy(&msgptr[16],&GetBicc->msgList,len); + } + else + { + //route_mark = (GetBicc->cic[0] << 28)+(mtp3_para->nw[nw].opc14 << 14)+dpc; + + if (dest_ip == 0xffffffff) + { + if (GetBicc->opc == 0) + route_mark = (GetBicc->cic[0] << 28)+(mtp3_para->nw[nw].opc14 << 14)+dpc; + else + route_mark = (GetBicc->cic[0] << 28)+(GetBicc->opc << 14)+dpc;//keep the UP filled opc + } + else + route_mark = (GetBicc->cic[0] << 28)+(GetBicc->opc << 14)+dpc;//keep the UP filled opc + + msgptr[1] = outlink>>8; + msgptr[0] = outlink&0xff; + msgptr[2] = (len + 9) / 0xff; + msgptr[3] = (len+9) & 0xff; + msgptr[4] = sio; + memcpy(&msgptr[5],&route_mark,4); + memcpy(&msgptr[9],&GetBicc->cic,4); + memcpy(&msgptr[13],&GetBicc->msgList,len); + } + mtp3.nw[nw].flow.MtoI[4]++; + if (dest_ip == 0xffffffff) + { + send_mtp_msg(outlink,msgptr); + } + else + { + mtp3_iprt.io_msg.msgLength = (msgptr[2]<<8) + msgptr[3]+3+1; + if (iptrans_msg_flow(msgptr,pclen,MTP_MSG_OTHER_SERVER,dest_ip)); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + } + B_shm_ptr->IM_Buf.RSub ++; + } + return 1; +} + +int find_dst_place(long dst,WORD lsno) +{ + BYTE i; + BYTE nw; + WORD dpc_place; + ls_info *ls; + + if (lsno >= MAX_LS) + return -1; + + ls = &mtp3.ls[lsno]; + nw = mtp3_para->ls_pro[lsno].nw_id; + + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + dpc_place = ls->influ_dstplace_intable_asNLS[i]; + if ( mtp3_para->nw[nw].routing[dpc_place].dpc == dst ) + return dpc_place; + } + + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + dpc_place = ls->influ_dstplace_intable_asALS[i]; + if ( mtp3_para->nw[nw].routing[dpc_place].dpc == dst ) + return dpc_place; + } + return -1; +} + +int find_direct_ls_to_dst(long dst, BYTE nw, long opc) +{ + WORD i, default_flag=0; + + if(pc_length(nw)==MTP3_14BIT_PC && opc == mtp3_para->nw[nw].opc14) + default_flag = 1; + else if(pc_length(nw)==MTP3_24BIT_PC && opc == mtp3_para->nw[nw].opc24) + default_flag = 1; + + for (i=0; ils_pro[i].ls_op_pc == dst && ( (mtp3_para->ls_pro[i].nw_id) == nw)) + { + if(mtp3_para->ls_pro[i].ls_opc == opc ) + return i; + else if(mtp3_para->ls_pro[i].ls_opc == 0 && default_flag) + return i; + } + } + + mtp3_debug(MTP3DB_EVENT,"dst %d opc %d Can't find direct linkset to destination",dst, opc); + return MAX_LS; +} + +int get_chl_via_slc(int linkset,BYTE slc,long msgopc, long msgdpc) +{ + ls_info *ls; + int lsx16; + BYTE nw; + int link; + + if (linkset >= MAX_LS) + return -1; + if (slc > 15) + return -1; + lsx16 = linkset << 4; + ls = &mtp3.ls[linkset]; + if (mtp3_para->ls_pro[linkset].ls_op_pc == msgopc) + { + link = ls_slc[lsx16+slc]; + if ( mtp3ObjState.lk_configured[link] == PARA_CONFIGURED ) + return ls_slc[lsx16+slc]; + } + else + { + nw = mtp3_para->ls_pro[linkset].nw_id; + linkset = find_direct_ls_to_dst(msgopc,nw, msgdpc); + if ( linkset < MAX_LS ) + { + lsx16 = linkset << 4; + return ls_slc[lsx16+slc]; + } + } + mtp3_debug(MTP3DB_EVENT,"slc %d Can't Find This slc",slc); + return -1; +} + +void send_to_host_mtp3(BYTE *msgptr,ulong dst_ip) +{ + mtp3_iprt.io_msg.msgSrcPort = SS7_PORT; + mtp3_iprt.io_msg.msgDstPort = SS7_PORT; + mtp3_iprt.io_msg.msgDstIP = dst_ip; + mtp3_iprt.io_msg.msgLength = (msgptr[2]<<8) + msgptr[3]+3+1; + memcpy(&mtp3_iprt.io_msg.msgContent, msgptr,mtp3_iprt.io_msg.msgLength); +// mtp3_iprt.io_msg.msgContent[0] = msgptr[0]; +// iptrPutMessage(mtp3_iprt.io_msg); + + iptrDirectSendMsg(mtp3_iprt.io_msg); +} + +void mtp3_multicast(BYTE *msgptr) +{ + int i; + ulong dst_ip; + + for (i=0;ilk[link].e1_to_linkset; + if (lsno >= MAX_LS) + return; + ls = &mtp3.ls[lsno]; + + nw = (msgptr[4] >> 6) & 3; + pc_len = pc_length(nw); + if (pc_len == MTP3_24BIT_PC) + { + msgtype_offset = 10+1+1; + memcpy(&MsgOpc,&msgptr[8],3); + memcpy(&MsgDpc, &msgptr[5],3); + slc = msgptr[11] & 0x0f; + } + else + { + memcpy(&MsgOpc,&msgptr[5],4); + slc = (MsgOpc >> 28) & 0x0f; + MsgDpc = MsgOpc & 0x3fff; + MsgOpc = (MsgOpc & 0x0fffffff) >> 14; + msgtype_offset = 7+1+1; + } + + msgtype = msgptr[msgtype_offset]; + h0 = msgtype & 0x0F; + h1 = (msgtype >> 4) & 0x0f; + switch (h0) + { + case 1:/* COO/COA/CBD/CBA */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + if (chl == -1) + return; + if ( (mtp3ObjState.lk_mtp3[chl] != mtp3_localip) && + (src_host == MSG_FROM_MTP2) ) + { + send_to_host_mtp3(msgptr, mtp3ObjState.lk_mtp3[chl]); //<< 16) | 0x010012ac); + return; + } + switch (h1) + { + case 1:/* COO */ + remote_bsnt = msgptr[msgtype_offset+1]; + if (remote_bsnt < 128) + { + mtp3_debug(MTP3DB_EVENT,"link %d RVed COO",chl); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_CHANGEOVER_ORDER; + fsnc[chl] = msgptr[msgtype_offset+1]; + } + else + { + mtp3_debug(MTP3DB_EVENT,"link %d RECEIVE COO WITH INVALID BSN",chl); + } + break; + case 2:/* COA */ + remote_bsnt = msgptr[msgtype_offset+1]; + if (remote_bsnt < 128) + { + mtp3ObjInput.tcoc_input_from_hmdt[chl] = TCOC_HMDT_COA_COMMAND; + mtp3_debug(MTP3DB_EVENT,"chl %d rv COA",chl); +// printf("chl %d rv COA\n",chl); + fsnc[chl] = msgptr[msgtype_offset+1]; + } + else + { + mtp3_debug(MTP3DB_EVENT,"link %d RECEIVE COA WITH INVALID BSN",chl); + } + break; + case 5:/* CBD */ + mtp3_debug(MTP3DB_EVENT,"chl %d rev cbd,tcbc state is %d",chl,mtp3ObjState.tcbc_state[chl]); +// printf("chl %d rev cbd,tcbc state is %d\n",chl,mtp3ObjState.tcbc_state[chl]); +// tcbc_input can cause this var override in some case +// tcbc_input[chl] = TCBC_HMDT_CBD_COMMAND; + cbd_cbc_r[chl] = msgptr[msgtype_offset+1]; + hmrt_tcbc_changeback_ack(chl); + break; + case 6:/* CBA */ + mtp3_debug(MTP3DB_EVENT,"chl %d rev cba",chl); +// printf("chl %d rev cba\n",chl); +// tcbc_input[chl] = TCBC_HMDT_CBA_COMMAND; + cba_cbc_r[chl] = msgptr[msgtype_offset+1]; + break; + default: + break; + } + break; + case 2:/* ECO/ECA */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + if (chl == -1) + return; + switch (h1) + { + case 1:/* ECO */ + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_ECHANGEOVER_ORDER; + break; + case 2:/* ECA */ + mtp3ObjInput.tcoc_input_from_hmdt[chl] = TCOC_HMDT_ECA_COMMAND; + break; + default: + break; + } + break; + case 4:/* TFP/TFA/ */ + switch (h1) + { + case 1:/* TFP */ + if (src_host == MSG_FROM_MTP2) + { + mtp3_multicast(msgptr); + return; + } + if ( pc_len == MTP3_24BIT_PC ) + { + memcpy(&tfdst,&msgptr[msgtype_offset+1],3); + } + else + { + memcpy(&tfdst,&msgptr[msgtype_offset+1],2); + tfdst = tfdst & 0x3fff; + } + if (mtp3_para->ls_pro[lsno].ls_op_pc == tfdst) + return; + sp_place = find_dst_place(tfdst,lsno); + if ( sp_place == -1 ) + return; + TFPmsg_OPC = MsgOpc; + TFPmsg_SrcLk = link; + mtp3.nw[nw].rtpc_input[sp_place] = RTPC_TFP_MSG; + rtpc_proc(nw,sp_place); + break; + + case 5:/* TFA */ + if (src_host == MSG_FROM_MTP2) + { + mtp3_multicast(msgptr); + return; + } + if ( pc_len == MTP3_24BIT_PC ) + memcpy(&tfdst,&msgptr[msgtype_offset+1],3); + else + { + memcpy(&tfdst,&msgptr[msgtype_offset+1],2); + tfdst = tfdst & 0x3fff; + } + if (mtp3_para->ls_pro[lsno].ls_op_pc == tfdst) + return; + sp_place = find_dst_place(tfdst,lsno); + if ( sp_place == -1 ) + return; + TFAmsg_OPC = MsgOpc; + TFAmsg_SrcLk = link; + mtp3.nw[nw].rtac_input[sp_place] = RTAC_TFA_MSG; + rtac_proc(nw,sp_place); + break; + + default: + break; + } + break; + case 5:/* RST */ + if ( pc_len == MTP3_24BIT_PC ) + memcpy(&tfdst,&msgptr[msgtype_offset+1],3); + else + { + memcpy(&tfdst,&msgptr[msgtype_offset+1],2); + tfdst = tfdst & 0x3fff; + } + sp_place = find_dst_place(tfdst,lsno); + if (sp_place == -1) + return; + if ( ((mtp3.nw[nw].routine[sp_place] >> 4) & 3) != 1 )/* inaccessable */ + { + mtp3.nw[nw].rtpc_input[sp_place] = RTPC_RSRT_SEND_TFP_MSG; + sdTFP_Ls = lsno;/* send TFP to this linkset's remote sp */ + rtpc_proc(nw,sp_place); + } + else + { + mtp3.nw[nw].rtac_input[sp_place] = RTAC_SEND_TFA_MSG; + sdTFA_Ls = lsno; + rtac_proc(nw,sp_place); + } + break; + case 6:/* inhibit message */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + if (chl == -1) + return; + if ( (mtp3ObjState.lk_mtp3[chl] != mtp3_localip) && + (src_host == MSG_FROM_MTP2) ) + { + send_to_host_mtp3(msgptr, mtp3ObjState.lk_mtp3[chl]);// << 16) | 0x010012ac); + return; + } + + switch (h1) + { + case 1:/* LIN */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_INHIBIT_SIGLINK; + break; + case 2:/* LUN */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_UINHIBIT_SIGLINK; + break; + case 3:/* LIA */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_INHIBIT_ACK; + break; + case 4:/* LUA */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_UNINHIBIT_ACK; + break; + case 5:/* LID */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_INHIBIT_DENIED; + break; + case 6:/* LFU */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_FORCE_UNINHIBIT_SIGLINK; + break; + case 7:/* LLT */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_LOCAL_INHIBIT_TEST; + break; + case 8:/* LRT */ + chl = get_chl_via_slc(lsno,slc,MsgOpc, MsgDpc); + mtp3ObjInput.tlac_input_from_hmdt[chl] = TLAC_HMDT_REMOTE_INHIBIT_TEST; + break; + default: + break; + } + break; + case 7:/* TRA */ + if (own_sp_restarting)/* sp restarting */ + { + rv_TRA_num++; + } + else + { + lsno=find_direct_ls_to_dst(MsgOpc,nw, MsgDpc); + if ( (lsno != -1) && + (mtp3.ls[lsno].adjacentsp_restarting==1) ) + {/* from an restarting adjacent sp? */ + if (sending_phase_finished[lsno] == TRUE) + { + sending_phase_finished[lsno] = FALSE; + stop_mtp3T21(lsno); + tsrc_fun5(lsno); + } + else + { + } + } + else + { + for (i=0; inw[nw].routing[i].normal_ls < MAX_LS) || + (mtp3_para->nw[nw].routing[i].alternative_ls < MAX_LS)) + { + mtp3.nw[nw].rtpc_input[i] = RTPC_TSRC_SEND_TFP_MSG; + sdTFP_Ls = lsno;/* send TFP to this linkset's remote sp */ + tprc_proc(nw,i); + } + } + } + } + } + break; + default: + break; + } +} + +void hmdt_test_msg(BYTE *msgptr) +{ + int i; + WORD chl; + WORD linkset; + WORD sp_place; + ls_info *ls=NULL; + BYTE nw; + long route_mark; + BYTE msg_LI; + BYTE len; + BYTE *sd_tmp_buf; + ulong opc,dpc; + BYTE slc=0; + + chl = msgptr[1]*256+msgptr[0]; + linkset = mtp3_para->lk[chl].e1_to_linkset; + nw = mtp3_para->ls_pro[linkset].nw_id; + ls = &mtp3.ls[linkset]; + sp_place = ls->adjacent_sp_place; + if (sp_place >= MAX_ROUTE) + return; + + if( msgptr[12] == 0x11 && !(mtp3_para->lk[chl].admin_state & 0x01 )) + { + mtp3_debug(MTP3DB_ERROR,"mtp3 link have been locked , discard sltm msg\r\n"); + return; + } + + sd_tmp_buf = &mtp3_iprt.io_msg.msgContent[0]; + if (pc_length(nw) == MTP3_24BIT_PC) + {/* For 24 Bit */ + if (msgptr[12] == 0x11 ) + { + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + slc = msgptr[13] & 0x0f; + else + slc = msgptr[11] & 0x0f; + if (slc != mtp3_para->lk[chl].e1_to_slc)//slc incorrect + { + mtp3_debug(MTP3DB_ERROR,"MTP3<==MTP2,24BIT,link=%d,slc=%d incorrect,should be %d",chl,slc,mtp3_para->lk[chl].e1_to_slc); + return; + } + memcpy(&dpc,&msgptr[5],3); + memcpy(&opc,&msgptr[8],3); + msg_LI = (msgptr[13] >> 4); + sd_tmp_buf[0] = msgptr[0]; + sd_tmp_buf[1] = msgptr[1]; + sd_tmp_buf[2] = msgptr[2]; + sd_tmp_buf[3] = msgptr[3]; + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + sd_tmp_buf[4] = (nw << 6)+2; + else + sd_tmp_buf[4] = (nw << 6)+1; + memcpy(&sd_tmp_buf[5],&mtp3_para->ls_pro[linkset].ls_op_pc,3); + //memcpy(&sd_tmp_buf[7],&mtp3_para->nw[nw].opc24,3);//?? + memcpy(&sd_tmp_buf[8],&dpc,3); + sd_tmp_buf[11] = msgptr[11]; + sd_tmp_buf[12]= SIGNAL_SLTA; + sd_tmp_buf[13] = msgptr[13]; + for (i=1; i<=msg_LI; i++) + { + len = i + 11+1; + sd_tmp_buf[len+1] = msgptr[len+1]; + } + send_mtp_msg(chl,sd_tmp_buf); + } + else + { + if (msgptr[14] == (chl&0xFF))//??? + { + + mtp3ObjInput.sltc_input[chl] = SLTA_MSG; + if (mtp3ObjState.sltc_state[chl] != 3) + sltc_proc(chl); + } + } + } + + else/* 14 bit */ + { + if (msgptr[9] == 0x11 ) + { + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + slc = msgptr[10] & 0x0f; + else + slc = (msgptr[8] >> 4) & 0x0f; + if (slc != mtp3_para->lk[chl].e1_to_slc)//slc incorrect + { + mtp3_debug(MTP3DB_ERROR,"MTP3<==MTP2,14BIT,link=%d,slc=%d incorrect,should be %d",chl,slc,mtp3_para->lk[chl].e1_to_slc); + return; + } + memcpy(&route_mark,&msgptr[5],4); + dpc = route_mark & 0x3FFF; + opc = (route_mark & 0x0FFFFFFF) >> 14; + //route_mark = (mtp3_para->lk[chl].e1_to_slc << 28) + (mtp3_para->nw[nw].opc14 << 14) + (mtp3_para->ls_op_pc[linkset]);//?? + route_mark = (mtp3_para->lk[chl].e1_to_slc << 28) + (dpc<< 14) + (mtp3_para->ls_pro[linkset].ls_op_pc); + msg_LI = (msgptr[10] >> 4); + sd_tmp_buf[1] = chl>>8; + sd_tmp_buf[0] = chl&0xff; + sd_tmp_buf[2] = msgptr[2]; + sd_tmp_buf[3] = msgptr[3]; + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + sd_tmp_buf[4] = (nw << 6) + 2; + else + sd_tmp_buf[4] = (nw << 6) + 1; + memcpy(&sd_tmp_buf[5],&route_mark,4); + sd_tmp_buf[9] = SIGNAL_SLTA; + for (i=0; i<=msg_LI; i++) + { + len = i+8+1; + sd_tmp_buf[len+1] = msgptr[len+1]; + } + send_mtp_msg(chl,sd_tmp_buf); + } + else + { + if (msgptr[11] == (chl&0xFF))//??? + { + mtp3ObjInput.sltc_input[chl] = SLTA_MSG; + if (mtp3ObjState.sltc_state[chl] != 3) + sltc_proc(chl); + } + } + } +} + +int mtp3_Trans_stpMsg(BYTE *msgptr,WORD outlink,BYTE pc_len) +{ + long dest_ip = 0x00; + BYTE nw=0; + BYTE ssf=0; + WORD len,link; + + link = msgptr[1]*256+msgptr[0]; + nw = (msgptr[4] >> 6) & 3; + ssf = msgptr[4] & 7; + len = (msgptr[2]<<8) + msgptr[3] + 3+1; + + if(len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"mtp3_Trans_stpMsg, length longer than 300, len=%d!", len); + msgptr[2] = 0; + len = MAX_SS7_MSG_LEN; + } + if (ssf>1) + ssf = ssf - 1; + + if (mtp3_para->lk[link].e1_to_linkset == mtp3_para->lk[outlink].e1_to_linkset) + {//to avoid stp back to the incoming linkset + mtp3.nw[nw].flow.stp_loop[ssf]++; + return 0; + } + +// current_measure->tf_measure1[3][wx5[nw]+ssf]+=len;/* octets */ + current_measure->tf_measure2[3][wx5[nw]+ssf]++;/* MSUs */ + mtp3.nw[nw].flow.stp[ssf]++; + + mtp3_iprt.io_msg.msgLength = len; + mtp3_iprt.io_msg.msgContent[1] = outlink>>8; + mtp3_iprt.io_msg.msgContent[0] = outlink&0xff; + if (mtp3ObjState.lk_mtp3[outlink] != mtp3_localip) + { + dest_ip = mtp3ObjState.lk_mtp3[outlink]; + //dest_ip = (dest_ip << 16) | E1CARD_BASE_IP; + if (iptrans_msg_flow(&mtp3_iprt.io_msg.msgContent[0],pc_len,MTP_MSG_STP,dest_ip)); +// send_to_mtp2(dest_ip); + send_to_mtp2_new_struct(dest_ip); + } + else if (MTP3_LINK_TYPE(outlink) == LKTYPE_NONE_SIGTRAN) + { + dest_ip = LINK_TO_IP(outlink); + if (iptrans_msg_flow(&mtp3_iprt.io_msg.msgContent[0],pc_len,MTP_MSG_STP,dest_ip)); + send_to_mtp2(dest_ip); + } + else + { +#if _INCLUDE_M2UA + if (MTP3_LINK_TYPE(outlink) == LKTYPE_MTP3_LITE) + { + if (iptrans_msg_flow(&mtp3_iprt.io_msg.msgContent[0],pc_len,MTP_MSG_STP,dest_ip)); + if ((msgptr[4] & 0x0f) == 3)//??? + put_mtp3lite_msg(msgptr); + + } + else + { + if (iptrans_msg_flow(&mtp3_iprt.io_msg.msgContent[0],pc_len,MTP_MSG_STP,dest_ip)); + put_m2ua_msg((m2ua_up_msg_t *)msgptr); + return 1; + } +#endif + } + + + + return 1; +} + +void mtp3_print_routeFailure(BYTE sio,BYTE reason) +{ + BYTE debug_type; + + switch(sio & 0x0f) + { + case 0x0: + break; + case 0x1: + debug_type = MTP3DB_SNMMSG; + break; + case 0x3: + debug_type = MTP3DB_SCCPMSG; + break; + case 0x4: + debug_type = MTP3DB_TUPMSG; + break; + case 0x5: + debug_type = MTP3DB_ISUPMSG; + break; + default: + break; + } + + switch (reason) + { + case 0: + mtp3_debug(debug_type,"Perform routing:\33[31mRoute Failure,Reason:no route\33[0m"); + break; + case 1: + mtp3_debug(debug_type,"Perform routing:\33[31mRoute Failure,Reason:buf overflow\33[0m"); + break; + case 2: + mtp3_debug(debug_type,"Perform routing:\33[31mRoute Failure,Reason:network conflict\33[0m"); + break; + default: + break; + } +} + +int mtp3lite_updateStatus(WORD chl, BYTE new_l2_state,BYTE alarmCode) +{ + WORD ls_t; + + if ((mtp3ObjState.lk_configured[chl] == PARA_NOT_CONFIGURED) || + (mtp3_para->lk[chl].e1_to_mtp3 != mtp3_localip)) + return 0; + + ls_t = mtp3_para->lk[chl].e1_to_linkset; + if(mtp3ObjState.link_l1_state[chl] == 0 && mtp3ObjState.link_l2_state[chl]!=0) + { + mtp3ObjState.link_l2_state[chl] = 0;//reset l2 state + } + if (new_l2_state != mtp3ObjState.link_l2_state[chl]) + { + if (new_l2_state == MTP2_STATE_WORKING) + { + current_measure->lk_measure1[chl][2]++; + mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d L2 in service",chl); + mtp3_send_mtp2_alarm(8+chl,0); + //mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_IN_SERVICE; + mtp3ObjState.link_l1_state[chl] = 1; + mtp3ObjState.link_l2_state[chl] = MTP2_STATE_WORKING; + mtp3ObjState.lsac_state[chl] = LSAC_ACTIVE_STATE; + mtp3ObjState.sltc_state[chl] = SLTC_RUNNING_STATE; + mtp3ObjState.tlac_state[chl] = TLAC_AVAILABLE_STATE; + if (mtp3.ls[ls_t].links_available == 0) + mtp3lite_upd_route_status(chl, 1); + mtp3.ls[ls_t].links_available ++; + hmrt_tcbc_update_routing_tables(chl); + mtp3ObjState.link_l3_state[chl] = AVAILABLE; + + mtp3ObjState.lk_mtp3[chl] = mtp3_localip; + } + else if (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING) + { + local_change_over[chl]++; + mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d L2 out of service",chl); + mtp3_send_mtp2_alarm(8+chl,alarmCode); + //mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_OUT_OF_SERVICE; + //mtp3ObjInput.sltc_input[chl] = SLTC_STOP; + //sltc_proc(chl); + mtp3ObjState.link_l1_state[chl] = 0; + mtp3ObjState.link_l2_state[chl] = 0; + mtp3ObjState.lsac_state[chl] = 0; + mtp3ObjState.sltc_state[chl] = 0; + mtp3ObjState.tlac_state[chl] = 0; + if (mtp3.ls[ls_t].links_available > 0) + mtp3.ls[ls_t].links_available --; + if (mtp3.ls[ls_t].links_available == 0) + mtp3lite_upd_route_status(chl, 0); + hmrt_tcoc_update_routing_tables(chl); + mtp3ObjState.link_l3_state[chl] = 0; + + } + } + + return 1; +} + +int Link_Alternative_Mtp3_SubSystem_State(WORD Link, BYTE SubSystem) +{ + ulong AlterMTP3=mtp3_para->lk[Link].e1_to_alterMTP3; + int Idx=-1; + + if ((Idx = MTP3_LinkIP_List(AlterMTP3,0)) >= 0) + { + if (SubSystem < 8) + { + return ((MTP3IPMng.LinkIPSubSta[Idx][0] >> SubSystem) & 1); + } + else + return ((MTP3IPMng.LinkIPSubSta[Idx][1] >> (SubSystem & 7)) & 1); + } + + return 0; +} + +int check_stp_route(BYTE nw, long dpc, BYTE sls) +{ + long opc=0; + int i=0, outlink=0; + int max_opc=mtp3_opc.opc_num[nw]; + + outlink = check_outbound_route(nw,dpc, sls, 0); + if(outlink>=0) + return outlink; + for(i=0; i=0) + return outlink; + } + return -1; +} + +int GetMtp2Msg(ulong ip_port)/* get ss7 message from iptrans via the 4950:ss7 port,4969:multicast port*/ +{ + BYTE module_id; + BYTE *msgptr=NULL; + BYTE sio; + ls_info *ls; + long route_mark; + WORD chl; + BYTE routine; + BYTE nw; + BYTE lsnw; + BYTE pc_len; + int outlink; + BYTE sls; + WORD lsno=0; + ls_para *ls_pro=NULL; + long opc=0; + long msgdpc=0; + long msgopc=0; + WORD len, tmp_len; + BYTE ssf; + BYTE printmsgsuccess; + BYTE src_host; + BYTE dpc_equal_to_opc; + BYTE tmp_up_message[MAX_SS7_MSG_LEN+10]; + +#if _INCLUDE_M2UA + BYTE new_l2_state; + WORD ls_t; +#endif + + printmsgsuccess = 0; + outlink = MAX_LK_INDEX; +// if (iptrGetMessage(&mtp3_iprt.io_msg,ip_port) > 0) +#if _INCLUDE_M2UA + if (((ip_port == SS7_PORT) && (iptrDirectRecvMsg(&mtp3_iprt.io_msg,ip_port) > 0)) || + ((ip_port == M2UA_PORT) && (!get_m2ua_msg(&mtp3_m2ua_msg)))) +#else + if (((ip_port == SS7_PORT) && (iptrDirectRecvMsg(&mtp3_iprt.io_msg,ip_port) > 0))) +#endif + { + if (ip_port == SS7_PORT) + { + msgSourceIP = mtp3_iprt.io_msg.msgSrcIP; + module_id = (msgSourceIP >> 16) & 0xff; + + + tmp_len = (mtp3_iprt.io_msg.msgContent[2]<<8 ) + mtp3_iprt.io_msg.msgContent[3]; + if ( ((msgSourceIP & E1CARD_BASE_IP) == E1CARD_BASE_IP) && (module_id < 32))//old structure: LINK,len,sio... + {//insert one byte len in msgContent, change to new structure: LINK_high, Link_low , len_high,len_low,sio + memcpy(tmp_up_message+3, &mtp3_iprt.io_msg.msgContent[1], mtp3_iprt.io_msg.msgContent[1] + 1); + tmp_up_message[1] = 0; + tmp_up_message[0] = mtp3_iprt.io_msg.msgContent[0];//link + tmp_up_message[2] = 0; + memcpy(&mtp3_iprt.io_msg.msgContent[0], tmp_up_message, tmp_up_message[2]+4); + } + else if(tmp_len > MAX_SS7_MSG_LEN)//max len = 300 + { + mtp3_debug(MTP3DB_ERROR,"Get message in SS7 port 4950, length longer than 300!"); + return 0; + } + } +#if _INCLUDE_M2UA + if(ip_port == M2UA_PORT) + { + if(1) + {//check len + len = ntohs(mtp3_m2ua_msg->len)+3; + if(len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"Get message in m2ua, length longer than 300!"); + return 0; + } + len = 0; + } + if( mtp3_send_netcap && ( (mtp3_m2ua_msg->sio & 0xF0 ) != 0xF0 ) ) + { + int pclen ; + sio = mtp3_m2ua_msg->sio; + nw = sio >> 6; + pclen = pc_length(nw); + + if ( pclen == MTP3_24BIT_PC ) //ansi + { + NcMtp3Send ( &mtp3_m2ua_msg->sio + , ntohs(mtp3_m2ua_msg->len), 1 ); + } + else if ( pclen == MTP3_14BIT_PC ) //ITU + { + NcMtp3Send ( &mtp3_m2ua_msg->sio + , ntohs(mtp3_m2ua_msg->len), 0 ); + } + } + + } + else +#endif + { + if( mtp3_send_netcap && ( ( mtp3_iprt.io_msg.msgContent[4] & 0xF0 ) != 0xF0 ) ) + { + int pclen ; + sio = mtp3_iprt.io_msg.msgContent[4]; + nw = sio >> 6; + pclen = pc_length(nw); + + if ( pclen == MTP3_24BIT_PC ) //ansi + { + NcMtp3Send ( &mtp3_iprt.io_msg.msgContent[4] + , (mtp3_iprt.io_msg.msgContent[2]<<8) + mtp3_iprt.io_msg.msgContent[3], 1 ); + } + else if ( pclen == MTP3_14BIT_PC ) //ITU + { + NcMtp3Send ( &mtp3_iprt.io_msg.msgContent[4] + , (mtp3_iprt.io_msg.msgContent[2]<<8) + mtp3_iprt.io_msg.msgContent[3], 0 ); + } + } + } + if (ip_port == SS7_PORT) + { + msgSourceIP = mtp3_iprt.io_msg.msgSrcIP; + module_id = (msgSourceIP >> 16) & 0xff; + msgptr = &mtp3_iprt.io_msg.msgContent[0]; + if ( ((msgSourceIP & E1CARD_BASE_IP) == E1CARD_BASE_IP) && + (module_id < 32) ) + { + src_host = MSG_FROM_MTP2; + } + else + src_host = MSG_FROM_MTP3; + } +#ifdef _INCLUDE_M2UA + else + { + src_host = MSG_FROM_MTP2; + if (mtp3_m2ua_msg->sio == 0xEF) + { + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"get M2UA heartbeat from %lx",msgSourceIP); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,(u8 *)&mtp3_m2ua_msg->link,ntohs(mtp3_m2ua_msg->len)+2); + + chl = mtp3_m2ua_msg->link; + new_l2_state = mtp3_m2ua_msg->msg.lm.opercode; + if(mtp3ObjState.link_l1_state[chl] == 0 && mtp3ObjState.link_l2_state[chl]!=0) + { + mtp3ObjState.link_l2_state[chl] = 0;//reset l2 state + } + if (new_l2_state == 0) + mtp3ObjState.link_l1_state[chl] = 0; + else + mtp3ObjState.link_l1_state[chl] = 1; + if ( (mtp3ObjState.lk_configured[chl] == PARA_NOT_CONFIGURED) || + (mtp3ObjState.lk_mtp3[chl] != mtp3_localip)) + return 0; + + if ( new_l2_state != mtp3ObjState.link_l2_state[chl] ) + { + ls_t = mtp3_para->lk[chl].e1_to_linkset; + if (new_l2_state == MTP2_STATE_WORKING) + { + current_measure->lk_measure1[chl][2]++; + mtp3_debug(MTP3DB_EVENT,"link %d L2 in service",chl); + mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_IN_SERVICE; + mtp3_send_mtp2_alarm(8+mtp3_m2ua_msg->link,0);//clear alarm + } + else if (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING) + { + local_change_over[chl]++; + mtp3_debug(MTP3DB_EVENT,"link %d L2 out of service",chl); + mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_OUT_OF_SERVICE; + /* + if ( mtp2->retrieved_bsnt[i] < 128 ) + local_bsnt_retrievable[chl] = TRUE; + else + { + mtp3_debug(MTP3_DEBUG_LOG,"Link %d BSNT RETRIEVE FAILED",chl); + local_bsnt_retrievable[chl] = FALSE; + } + */ + mtp3ObjInput.sltc_input[chl] = SLTC_STOP; + sltc_proc(chl); + + if (mtp3_m2ua_msg->msg.lm.alarmcode == 0) + mtp3_send_mtp2_alarm(8+mtp3_m2ua_msg->link,M2UAALARM_Remote_MTP2_down); + else + mtp3_send_mtp2_alarm(8+mtp3_m2ua_msg->link,mtp3_m2ua_msg->msg.lm.alarmcode); + } + } + mtp3ObjState.link_l2_state[chl] = new_l2_state; + return 1; + } + else if (mtp3_m2ua_msg->sio == 0xEE)//sg + { + mtp3_send_alarm(MTP3_SG_COMPONENT+mtp3_m2ua_msg->link,mtp3_m2ua_msg->msg.lm.alarmcode); + } + else + { + msgptr = (BYTE *)mtp3_m2ua_msg; + chl = msgptr[1]*256+msgptr[0]; + msgSourceIP = mtp3_para->sg[mtp3_para->lk[chl].e1_to_sg].ip; +/* module_id = chl >> 3; + msgSourceIP = module_id; + msgSourceIP = (msgSourceIP << 16) | E1CARD_BASE_IP;*/ + } + } +#endif + + chl = msgptr[1]*256+msgptr[0]; + len = (msgptr[2]<<8)+msgptr[3]+4; + sio = msgptr[4]; + nw = sio >> 6; + ssf = sio & 0x0f; + if (ssf > 1) + ssf--; +// current_measure->tf_measure2[1][wx5[nw]+ssf]++;/* MSUs */ +// mtp3.nw[nw].flow.ItoM[ssf]++; + + pc_len = pc_length(nw); + + printmsgsuccess = iptrans_msg_flow(msgptr,pc_len,MTP_MSG_UP,msgSourceIP); + if (src_host == MSG_FROM_MTP2) + { + + current_measure->tf_measure2[1][wx5[nw]+ssf]++;/* MSUs */ + mtp3.nw[nw].flow.ItoM[ssf]++; + src_host = MSG_FROM_MTP2; + lsno = mtp3_para->lk[chl].e1_to_linkset; + if (lsno >= MAX_LS) + { +// current_measure->tf_measure1[5][wx5[nw]+ssf]+=len;/* octets */ + current_measure->tf_measure2[5][wx5[nw]+ssf]++;/* MSUs */ + mtp3.nw[nw].flow.ItoM_throwed[ssf]++; + return 0; + } + + ls_pro = &mtp3_para->ls_pro[lsno]; + lsnw = ls_pro->nw_id; + if (lsnw != nw) + { + if (printmsgsuccess == 1) + mtp3_print_routeFailure(sio,2); + else + { + mtp3_debug(MTP3DB_ERROR,"MTP3<==mtp2,%dBIT,SIO=%x,SPC(%lx->%lx),link=%d,linkset=%d",pc_len,sio,msgopc,msgdpc,chl,lsno); + mtp3_showbuf(MTP3DB_ERROR,msgptr, (msgptr[2]<<8)+msgptr[3]+4); + mtp3_debug(MTP3DB_ERROR,"Perform routing:linkset belong to net %d,but sio=%d",lsnw,sio); + } + mtp3.nw[nw].flow.ItoM_throwed[ssf]++; + return 0; + } + + if (lsno >=MAX_LS) + { +// current_measure->tf_measure1[5][wx5[nw]+ssf]+=len;/* octets */ + current_measure->tf_measure2[5][wx5[nw]+ssf]++;/* MSUs */ + mtp3.nw[nw].flow.ItoM_throwed[ssf]++; + return 0; + } + ls = &mtp3.ls[lsno]; + + if ( ls_pro->loopback_opt!= 0 )/* this linkset is loop back linkset */ + { + nw = ls_pro->nw_id; + if ( pc_length(nw) == MTP3_24BIT_PC ) + { + opc = mtp3_para->ls_pro[lsno].ls_op_pc; + memcpy( &msgptr[8],&opc,3);/* change msg's dpc to opc */ + } + else + { + opc = mtp3_para->nw[nw].opc14; + memcpy( (BYTE*)&route_mark,&msgptr[5],4); + sls = (route_mark >> 28) & 0xf; + route_mark = (sls << 28)+(mtp3_para->ls_pro[lsno].ls_op_pc << 14)+opc; + memcpy(&msgptr[5],&route_mark,4); + } + } + else if(0)// ( ls_pro & 0x10 )//??? change opc equal to our nw opc + { + if ( pc_length(nw) == MTP3_24BIT_PC ) + { + memcpy( &msgptr[5], &mtp3_para->nw[nw].opc24, 3);/* change msg's dpc to opc */ + } + else + { + memcpy( (BYTE*)&route_mark,&msgptr[5],4); + route_mark = (route_mark & 0xFFFFC000) | (mtp3_para->nw[nw].opc14 & 0x3FFF); + memcpy(&msgptr[5],&route_mark,4); + } + } + + if (pc_len == MTP3_24BIT_PC) + { + memcpy(&msgdpc,&msgptr[5],3); + memcpy(&msgopc,&msgptr[8],3); + dpc_equal_to_opc = mtp3_check_dpc_equal_to_opc(nw, msgdpc); + + //if (msgdpc != mtp3_para->nw[nw].opc24)/* STP */ + if (!dpc_equal_to_opc) //STP + { + sls = msgptr[11] & 0x0f; + //outlink = check_outbound_route(nw,msgdpc,sls, 0);//?? + outlink = check_stp_route(nw,msgdpc,sls); + if (outlink >= 0) + { + if (ip_port == M2UA_PORT) + { + memcpy(mtp3_iprt.io_msg.msgContent, msgptr, len); + msgptr = mtp3_iprt.io_msg.msgContent; + } + mtp3_Trans_stpMsg(msgptr,outlink,pc_len); + return 1; + } + } + } + + else/* 14 bit network */ + { + memcpy(&route_mark,&msgptr[5],4); + msgdpc = route_mark & 0x3FFF; + msgopc = (route_mark & 0x0FFFFFFF) >> 14; + dpc_equal_to_opc = mtp3_check_dpc_equal_to_opc(nw, msgdpc); + + //if (msgdpc != mtp3_para->nw[nw].opc14)/* STP !!! */ + if (!dpc_equal_to_opc) + { + sls = (route_mark >> 28) & 0x0f; + //outlink = check_outbound_route(nw,msgdpc,sls, 0);//?? + outlink = check_stp_route(nw,msgdpc,sls); + if (outlink >= 0) + { + if (ip_port == M2UA_PORT) + { + memcpy(mtp3_iprt.io_msg.msgContent, msgptr, len); + msgptr = mtp3_iprt.io_msg.msgContent; + } + mtp3_Trans_stpMsg(msgptr,outlink,pc_len); + return 1; + } + } + } + } + else if (src_host == MSG_FROM_MTP3) + { +#ifdef _M3UA_ + switch(sio) + { + case 0x1f://get route table from other plat + chl = msgptr[1]*256+msgptr[0]; + nw = msgptr[5]; + memcpy(&msgdpc, msgptr+6, 4); + memcpy(&msgopc, msgptr+10, 4); + routine = get_route_value(msgdpc, nw, msgopc); + send_route_to_other_plat(msgdpc, nw, routine, mtp3_iprt.io_msg.msgSrcIP, chl, msgopc); + return 1; + case 0x2f: + chl = msgptr[1]*256+msgptr[0]; + nw = msgptr[5]; + memcpy(&msgdpc, msgptr+6, 4); + routine = msgptr[10]; + memcpy(&msgopc, msgptr+11, 4); + update_route_by_other_plat(msgdpc,nw, routine, chl, msgopc); + return 1; + default: + break; + } + + +#endif + if (pc_len == MTP3_24BIT_PC) + memcpy(&msgdpc,&msgptr[5],3); + else + { + memcpy(&route_mark,&msgptr[5],4); + msgdpc = route_mark & 0x3FFF; + } + dpc_equal_to_opc = mtp3_check_dpc_equal_to_opc(nw, msgdpc); + + if (!dpc_equal_to_opc) + { + if (mtp3ObjState.lk_mtp3[chl] != mtp3_localip) + return 0; + + if (MTP3_LINK_TYPE(chl) == LKTYPE_NONE_SIGTRAN) + send_to_mtp2(LINK_TO_IP(chl)); +#if _INCLUDE_M2UA + else if (MTP3_LINK_TYPE(chl) == LKTYPE_SIGTRAN) + { + tmp_len = (mtp3_iprt.io_msg.msgContent[2]<<8) + mtp3_iprt.io_msg.msgContent[3]; + if(tmp_len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"put_m2ua_msg, length longer than 300, len=%d!", tmp_len); + mtp3_iprt.io_msg.msgContent[2] = 0; + tmp_len= MAX_SS7_MSG_LEN; + } + put_m2ua_msg((m2ua_up_msg_t *) mtp3_iprt.io_msg.msgContent); + } + else if (MTP3_LINK_TYPE(chl) == LKTYPE_M3UA) + { + tmp_len = (mtp3_iprt.io_msg.msgContent[2]<<8) + mtp3_iprt.io_msg.msgContent[3]; + if(tmp_len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"put_m3ua_msg, length longer than 300, len=%d!", tmp_len); + mtp3_iprt.io_msg.msgContent[2] = 0; + tmp_len= MAX_SS7_MSG_LEN; + } + send_mtp_msg(chl, mtp3_iprt.io_msg.msgContent); + } + else if (MTP3_LINK_TYPE(chl) == LKTYPE_MTP3_LITE) + { + mtp3_debug(MTP3DB_EVENT,"link %d get MTP3LITE msg from other plat and send it",chl); + send_mtp_msg(chl, mtp3_iprt.io_msg.msgContent); + } +#endif + return 1; + } + } + + if (outlink < 0) + { + if (printmsgsuccess == 1) + mtp3_print_routeFailure(sio,0); + else + { + mtp3_debug(MTP3DB_ERROR,"MTP3<==MTP2,%dBIT,SIO=%x,SPC(%lx->%lx),link=%d",pc_len,sio,msgopc,msgdpc,chl); +// mtp3_debug(msgptr,MTP3_ERROR_LOG,"\33[31m[STP]Route Failed! SIO=%x,DPC=%lx\n\r\33[0m",sio,msgdpc); + mtp3_showbuf(MTP3DB_ERROR,msgptr, (msgptr[2]<<8)+msgptr[3] + 4); + mtp3_debug(MTP3DB_ERROR,"Perform routing:STP failed"); + } + hmrt_srm_msg(lsno,SIGNAL_TFP,msgdpc); +// current_measure->tf_measure1[5][wx5[nw]+ssf]+=len;/* octets */ + current_measure->tf_measure2[5][wx5[nw]+ssf]++;/* MSUs */ + mtp3.nw[nw].flow.stp_throwed[ssf]++; + return 0; + } + +// current_measure->tf_measure1[2][wx5[nw]+ssf]+=len;/* octets */ + current_measure->tf_measure2[2][wx5[nw]+ssf]++;/* MSUs */ + switch (sio & 0x0f) + { + case MTP3_SUB_SNM: + mtp3.nw[nw].flow.MtoU[0]++; + hmdt_SNM_message_for_distribution(msgptr,src_host); + return 1; + case MTP3_SUB_STM: + mtp3.nw[nw].flow.MtoU[1]++; + hmdt_test_msg(msgptr); + return 1; + case MTP3_SUB_STM2: + mtp3ObjState.lk_SpecANSI_flag[chl] = 1;//mark special T+M + mtp3.nw[nw].flow.MtoU[1]++; + hmdt_test_msg(msgptr); + return 1; + case MTP3_SUB_SCCP: + if ((mtp3_heartbeat.SubState[0] & 0x08) || (MSG_FROM_MTP3==src_host)) + { + if ( (S_shm_ptr->MS_Buf.WSub+1) == S_shm_ptr->MS_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[0]++; + break; + } + send_to_sccp(msgptr); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_SCCPMSG,"Perform routing:transfer to SCCP"); + } + else if (Link_Alternative_Mtp3_SubSystem_State(chl,MTP3_SUB_SCCP)) + { +// send_to_mtp2(mtp3_para->lk[chl].e1_to_alterMTP3); + send_to_mtp2_new_struct(mtp3_para->lk[chl].e1_to_alterMTP3); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_SCCPMSG,"Perform routing:SCCP UP is Locked,transfer to Alternative SCCP UP"); + } + else + { + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_ERROR,"Perform routing:No SCCP UP Available"); + } + + return 1; + case MTP3_SUB_TUP: + if ((mtp3_heartbeat.SubState[0] & 0x10) || (MSG_FROM_MTP3==src_host)) + { + if ( (T_shm_ptr->MT_Buf.WSub+1) == T_shm_ptr->MT_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[1]++; + break; + } + send_to_tup(msgptr); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_TUPMSG,"Perform routing:transfer to TUP"); + } + else if (Link_Alternative_Mtp3_SubSystem_State(chl,MTP3_SUB_TUP)) + { +// send_to_mtp2(mtp3_para->lk[chl].e1_to_alterMTP3); + send_to_mtp2_new_struct(mtp3_para->lk[chl].e1_to_alterMTP3); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_TUPMSG,"Perform routing:TUP UP is Locked,transfer to Alternative TUP UP"); + } + else + { + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_ERROR,"Perform routing:No TUP UP Available"); + } + return 1; + case MTP3_SUB_ISUP: + if ((mtp3_heartbeat.SubState[0] & 0x20) || (MSG_FROM_MTP3==src_host)) + { + if ( (I_shm_ptr->MI_Buf.WSub+1) == I_shm_ptr->MI_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[2]++; + break; + } + send_to_isup(msgptr); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_ISUPMSG,"Perform routing:transfer to ISUP"); + } + else if (Link_Alternative_Mtp3_SubSystem_State(chl,MTP3_SUB_ISUP)) + { +// send_to_mtp2(mtp3_para->lk[chl].e1_to_alterMTP3); + send_to_mtp2_new_struct(mtp3_para->lk[chl].e1_to_alterMTP3); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_ISUPMSG,"Perform routing:ISUP UP is Locked,transfer to Alternative ISUP UP"); + } + else + { + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_ERROR,"Perform routing:No ISUP UP Available"); + } + return 1; + case MTP3_SUB_BICC: // BICC + if ((mtp3_heartbeat.SubState[1] & 0x40) || (MSG_FROM_MTP3==src_host)) + { + if ( (B_shm_ptr->MI_Buf.WSub+1) == B_shm_ptr->MI_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[2]++; + break; + } + send_to_bicc(msgptr); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_BICCMSG,"Perform routing:transfer to BICC"); + } + else if (Link_Alternative_Mtp3_SubSystem_State(chl,MTP3_SUB_BICC)) + { +// send_to_mtp2(mtp3_para->lk[chl].e1_to_alterMTP3); + send_to_mtp2_new_struct(mtp3_para->lk[chl].e1_to_alterMTP3); + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_BICCMSG,"Perform routing:BICC UP is Locked,transfer to Alternative BICC UP"); + } + else + { + if (printmsgsuccess == 1) + mtp3_debug(MTP3DB_ERROR,"Perform routing:No BICC UP Available"); + } + return 1; + default: + break; + } + if (printmsgsuccess == 1) + mtp3_print_routeFailure(sio,1); + else + { + mtp3_debug(MTP3DB_ERROR,"MTP3<==MTP2,%dBIT,SIO=%x,SPC(%lx->%lx),link=%d",pc_len,sio,msgopc,msgdpc,chl); + mtp3_showbuf(MTP3DB_ERROR,msgptr, (msgptr[2]<<8)+msgptr[3]+4); + mtp3_debug(MTP3DB_ERROR,"Perform routing:buffer fulled"); + } + mtp3.nw[nw].flow.ItoM_throwed[ssf]++; + return 0; + } + return 1; +} + +#ifdef _M3UA_ +int m3ua_send_to_sccp(xua_m3ua_msg *msgptr)/* send sccp msg to tele user part */ +{ + up_message *ToSccp; + WORD len; + BYTE nw; + BYTE link; + +// sio = msgptr[3]; + ToSccp = &S_shm_ptr->MS_Buf.msgNum[S_shm_ptr->MS_Buf.WSub]; + nw = msgptr->ni; + ToSccp->sio = (nw <<6) | msgptr->si; + ToSccp->sio = ToSccp->sio & 0xEF;//init spare bit + ToSccp->sio = ToSccp->sio | (mtp3_ansiFlag(nw) << 4); +// sio = sio | (mtp3_ansiFlag(nw) << 4); + link = msgptr->link; + ToSccp->link = link; + ToSccp->dest_ip = msgSourceIP; + +// pclen = pc_length(nw); +// if (pclen == MTP3_24BIT_PC)/* for 24bit ss7 network */ +// { +// if (msgptr[1] == 0 && msgptr[2] < 9)//len < 9 +// { +// mtp3ObjState.MTP3WatchDog[3]++; +// mtp3.nw[nw].flow.MtoU_throwed[0]++; +// mtp3_debug(MTP3DB_ERROR,"[SCCP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr[2],link); +// return 0; +// } + +// memcpy((BYTE *)&ToSccp->dpc,msgptr+4,3);/* message's dpc */ +// memcpy((BYTE *)&ToSccp->opc,&msgptr[7],3);/* message's opc */ + ToSccp->dpc = msgptr->dpc; + ToSccp->opc = msgptr->opc; + + ToSccp->cic[0] = msgptr->sls; +// len = (msgptr[1]<<8) + msgptr[2]-8; + len = ntohs(msgptr->len); + ToSccp->len = len; + memcpy(&ToSccp->msgList,msgptr->content, len); + S_shm_ptr->MS_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[2]++; + return 1; +} + +int m3ua_send_to_bicc(xua_m3ua_msg *msgptr)/* send isup msg to tele user part */ +{ + WORD len; + up_message_2 *ToBicc; + BYTE nw; + + ToBicc = &B_shm_ptr->MI_Buf.msgNum[B_shm_ptr->MI_Buf.WSub]; + nw = msgptr->ni; + ToBicc->sio = (nw<<6) | msgptr->si; + ToBicc->sio = ToBicc->sio & 0xEF;//init spare bit + ToBicc->sio = ToBicc->sio | (mtp3_ansiFlag(nw) << 4); + ToBicc->link = msgptr->link; + ToBicc->dest_ip = msgSourceIP; + ToBicc->dpc = msgptr->dpc; + ToBicc->opc = msgptr->opc; + ToBicc->cic[0] = msgptr->content[0]; + ToBicc->cic[1] = msgptr->content[1]; + ToBicc->cic[2] = msgptr->content[2]; + ToBicc->cic[3] = msgptr->content[3]; + len = ntohs(msgptr->len); + ToBicc->len = len-4; + memcpy(&ToBicc->msgList,&msgptr->content[4],len); + B_shm_ptr->MI_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[4]++; + return 1; +} + +int m3ua_send_to_isup(xua_m3ua_msg *msgptr)/* send isup msg to tele user part */ +{ + WORD len; + up_message *ToIsup; + BYTE nw; + + ToIsup = &I_shm_ptr->MI_Buf.msgNum[I_shm_ptr->MI_Buf.WSub]; + nw = msgptr->ni; + ToIsup->sio = (nw<<6) | msgptr->si; + ToIsup->sio = ToIsup->sio & 0xEF;//init spare bit + ToIsup->sio = ToIsup->sio | (mtp3_ansiFlag(nw) << 4); + ToIsup->link = msgptr->link;//??? + ToIsup->dest_ip = msgSourceIP; + if (msgptr->len <= 0) + { + mtp3ObjState.MTP3WatchDog[7]++; + mtp3.nw[nw].flow.MtoU_throwed[2]++; + mtp3_debug(MTP3DB_ERROR,"[ISUP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr->len, msgptr->link); + return 0; + } + ToIsup->dpc = msgptr->dpc; + ToIsup->opc = msgptr->opc; + ToIsup->cic[0] = msgptr->content[0]; + ToIsup->cic[1] = msgptr->content[1]; + len = ntohs(msgptr->len) -2; + ToIsup->len = len; + memcpy(&ToIsup->msgList,&msgptr->content[2],len); + MTP3_recv_isup_count(nw,msgptr->content[2]); + I_shm_ptr->MI_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[4]++; + return 1; +} + +int m3ua_send_to_tup(xua_m3ua_msg *msgptr)/* send tup msg to tele user part */ +{ + WORD len; + up_message *ToTup; + BYTE nw; + + ToTup = &T_shm_ptr->MT_Buf.msgNum[T_shm_ptr->MT_Buf.WSub]; + nw = msgptr->ni; + ToTup->sio = (nw<<6) | msgptr->si; + ToTup->sio = ToTup->sio & 0xEF;//init spare bit + ToTup->sio = ToTup->sio | (mtp3_ansiFlag(nw) << 4); + ToTup->link = msgptr->link; + ToTup->dest_ip = msgSourceIP; + if (msgptr->len <= 0) + { + mtp3ObjState.MTP3WatchDog[5]++; + mtp3.nw[nw].flow.MtoU_throwed[1]++; + mtp3_debug(MTP3DB_ERROR,"[TUP]MTP3<==MTP2,LI over range and discarded! LI=%02d,Link=%d",msgptr->len,msgptr->link); + return 0; + } + ToTup->dpc = msgptr->dpc;/* message's dpc */ + ToTup->opc = msgptr->opc;/* message's opc */ + ToTup->cic[0] = msgptr->content[0]; + ToTup->cic[1] = msgptr->content[1]; + len = ntohs(msgptr->len) - 2; + ToTup->len = len; + memcpy(&ToTup->msgList,&msgptr->content[2],len); + T_shm_ptr->MT_Buf.WSub ++; + mtp3.nw[nw].flow.MtoU[3]++; + return 1; +} + +int check_m3ua_rc_verify(DWORD rc, WORD link) +{ + int dpc_index; + WORD ls_t; + + ls_t = mtp3_para->lk[link].e1_to_linkset; + dpc_index = find_rc_dst_place(rc, ls_t); + + if(dpc_index >=0 && dpc_index < 256) + return 1; + else + return -1; +} + +int get_m3ua_rc_by_dpc(BYTE nw, long dpc, long opc)//??- +{ + network *sp; + WORD i; + mtp3DPCIndex *sort_rec = &mtp3SortRoutine.nw[nw]; + int index; + ull opc_dpc=0; + + if (dpc==0) + return -3; + + sp = &mtp3.nw[nw]; + if(opc == mtp3_para->nw[nw].opc14 && (pc_length(nw)==MTP3_14BIT_PC)) + opc = 0; + else if(opc == mtp3_para->nw[nw].opc24 && (pc_length(nw)==MTP3_24BIT_PC)) + opc = 0; + opc_dpc = opc; + opc_dpc = (opc_dpc <<32)|dpc; + index = Mtp3BinSearchValue(0,sort_rec->sortedNum-1,nw,opc_dpc);//??- + if ((index >= 0) && (index < MAX_ROUTE)) + i = sort_rec->index[index]; + else + return -3; + return mtp3_para->nw[nw].routing[i].rc; +} + +int find_rc_dst_place(DWORD rc, WORD lsno) +{ + BYTE i; + BYTE nw; + BYTE dpc_place; + ls_info *ls; + + if (lsno >= MAX_LS) + return -1; + + ls = &mtp3.ls[lsno]; + nw = mtp3_para->ls_pro[lsno].nw_id; + + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + dpc_place = ls->influ_dstplace_intable_asNLS[i]; + if ( mtp3_para->nw[nw].routing[dpc_place].rc == rc ) + { + return dpc_place; + } + } + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + dpc_place = ls->influ_dstplace_intable_asALS[i]; + if ( mtp3_para->nw[nw].routing[dpc_place].rc == rc ) + { + return dpc_place; + } + } + + return -1; +} + +void m3ua_upd_route_status(WORD chl, DWORD rc, BYTE rc_status, BYTE ls_disable) +{ + ls_info *ls; + int i,j; + WORD lsno,spplace;//, als_spplace; + int dpc_index; + WORD lsx16; + ulong dpc,opc; + BYTE *routine, nw; + network *sp; + lsno = mtp3_para->lk[chl].e1_to_linkset; + + + if (lsno >= MAX_LS) + return; + + ls = &mtp3.ls[lsno]; + nw = mtp3_para->ls_pro[lsno].nw_id; + lsx16 = lsno << 4; + sp = &mtp3.nw[nw]; + + if(!ls_disable) + { + dpc_index = find_rc_dst_place(rc, lsno); + if(dpc_index == -1 || dpc_index > MAX_ROUTE) + return; + if(rc==0) + { + dpc = mtp3_para->ls_pro[lsno].ls_op_pc; + + } + else + { + dpc = mtp3_para->nw[nw].routing[dpc_index].dpc; + opc = mtp3_para->nw[nw].routing[dpc_index].opc; + + } + } + + if (rc_status!=5) + {// mark_normal_linkset_unavailable(&mtp3.nw[nw].routine[dpc_index]); + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + + // if(mtp3_para->nw[nw].routing[spplace].rc != rc && ls_disable==0) + // continue; + if( ls_disable == 0) + continue; + +// sp->m3ua_rc_status[spplace] = rc_status; + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s.%d> M3UA update route info, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, + __LINE__, + chl, + spplace, sp->routine[spplace]); + + mark_normal_linkset_unavailable(&sp->routine[spplace]); + + if ( ((sp->routine[spplace] >> 2) & 3) == 0 )/*alternative route available */ + sp->routine[spplace] = (sp->routine[spplace] & 0x3f) + 0x40;/* current route change from normal linkset to alternative linkset */ + else/* sp not accessible */ + { + sp_unaccessable((BYTE *)&sp->routine[spplace]); + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,UNAVAILABLE); + sp->m3ua_rc_status[spplace] = rc_status; + } + if(mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + { + if(1) + if(mtp_peer_ip != 0) + { + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, + nw, + sp->routine[spplace], + mtp_peer_ip, + chl, + mtp3_para->nw[nw].routing[spplace].opc); + } + + if( mtp3_para->lk[chl].e1_to_alterMTP3 !=0) + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, nw, sp->routine[spplace], mtp3_para->lk[chl].e1_to_alterMTP3, chl, mtp3_para->nw[nw].routing[spplace].opc); + else if(mtp3_alterip!=0) + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, nw, sp->routine[spplace], mtp3_alterip, chl, mtp3_para->nw[nw].routing[spplace].opc); + } + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s.%d> M3UA update route info, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, + __LINE__, + chl, + spplace, sp->routine[spplace]); + + } + + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asALS[i]; + //if(mtp3_para->nw[nw].routing[spplace].rc != rc && ls_disable==0) + // continue; + if(ls_disable == 0) + continue; + + + //sp->m3ua_rc_status[spplace] = rc_status; + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s.%d> M3UA ALS update route info, link=%d, sppace=%d, sp->routine=%d, rc_status=%d", + __FUNCTION__, + __LINE__, + chl, + spplace, sp->routine[spplace], + sp->m3ua_rc_status[spplace]); + + mark_alternative_linkset_unavailable(&sp->routine[spplace]); + + if ( (sp->routine[spplace] & 3) != 0 )/* normal route unavailable */ + { + sp_unaccessable((BYTE *)&sp->routine[spplace]); + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,UNAVAILABLE); + sp->m3ua_rc_status[spplace] = rc_status; + + } + if(mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + { + if(1) + if(mtp_peer_ip != 0) + { + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, + nw, + sp->routine[spplace], + mtp_peer_ip, + chl, + mtp3_para->nw[nw].routing[spplace].opc); + } + + if(mtp3_para->lk[chl].e1_to_alterMTP3 !=0) + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, nw, sp->routine[spplace], mtp3_para->lk[chl].e1_to_alterMTP3, chl, mtp3_para->nw[nw].routing[spplace].opc); + else if(mtp3_alterip!=0) + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, nw, sp->routine[spplace], mtp3_alterip, chl, mtp3_para->nw[nw].routing[spplace].opc); + } + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s.%d> M3UA ALS update route info, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, + __LINE__, + chl, + spplace, sp->routine[spplace]); + + } + if(ls_disable) + { + //memset(&ls_sls[lsx16],MAX_LK-1,16); + for(i=0; i<16; i++) + { + //if(sls_to_link[lsx16+i] == chl) + ls_sls[lsx16+i] = MAX_LK_INDEX; + } + set_heartbeat(ALARM_LS_UNAVAILABLE,lsno); + mtp3_para->ls_pro[lsno].ls_state = 0;//ALARM_LS_UNAVAILABLE; + } + + + } + else + { + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + //if(mtp3_para->nw[nw].routing[spplace].rc != rc && ls_disable==0) + // continue; + + routine = (BYTE *)&mtp3.nw[nw].routine[spplace]; + + /* + if(m2ua_get_traffic_mode_type()==0) + { + if(*routine != 24 ) + { + ls->send_asp_ac_link_id = chl; + + send_command_to_m3ua(chl, 1,M3UA_RC_CMD , rc, 0); + + mtp3_debug(MTP3DB_EVENT,"<%s:%d> M3UA send RC_CMD, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION, __LINE__, + chl, spplace, sp->routine[spplace]); + } + } + */ + + sp->m3ua_rc_status[spplace] = rc_status; + set_heartbeat(ALARM_LS_AVAILABLE,lsno); + mtp3_para->ls_pro[lsno].ls_state = 1;//ALARM_LS_AVAILABLE; + //memset(&ls_sls[lsx16],chl,16); + for(j=0; j<16; j++) + { + if(sls_to_link[lsx16+j] == chl) + ls_sls[lsx16+j] = chl; + } + + mark_normal_linkset_available(&mtp3.nw[nw].routine[spplace]); + routine = (BYTE *)&mtp3.nw[nw].routine[spplace]; + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s.%d> S5,M3UA update route info, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, + __LINE__, + chl, + spplace, sp->routine[spplace]); + + if (Nlinkset_status(*routine) == LS_AVAILABLE) + *routine = ((*routine) & 0x3f);// current route is normal linkset + else if (Alinkset_status(*routine) == LS_AVAILABLE) + (*routine) = ((*routine) & 0x3f) + 0x40; + else + { + (*routine) = ((*routine) & 0x3f) + 0x80; + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,AVAILABLE); + } + + if(1) + if(mtp3ObjState.lk_mtp3[chl] == mtp3_localip && mtp_peer_ip != 0) + { + send_route_to_other_plat(dpc, + nw, + sp->routine[spplace], + mtp_peer_ip, + chl, + opc); + } + + if(mtp3ObjState.lk_mtp3[chl] == mtp3_localip && mtp3_para->lk[chl].e1_to_alterMTP3 !=0) + send_route_to_other_plat(dpc, nw, sp->routine[spplace], mtp3_para->lk[chl].e1_to_alterMTP3, chl, opc); + + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s.%d> S5,M3UA update route info, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, + __LINE__, + chl, + spplace, sp->routine[spplace]); + + rc_timer = 100; //make sure 1 second later to send ASP_AC + + } + sp = &mtp3.nw[nw]; + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asALS[i]; + //if(mtp3_para->nw[nw].routing[spplace].rc != rc) + // continue; + sp->m3ua_rc_status[spplace] = rc_status; + routine = (BYTE*)&sp->routine[spplace]; + + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s:%d> S5 ALS,M3UA update route info, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, __LINE__, + chl, + spplace, *routine); + + mark_alternative_linkset_available(&mtp3.nw[nw].routine[spplace]); //17-11-07 + routine = (BYTE *)&mtp3.nw[nw].routine[spplace]; + + if ( (*routine) >> 6 == 2 )// no route + { + (*routine) = ((*routine) & 0x3f) + 0x40;// current route is alternative linkset + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,AVAILABLE); + } + { + if (Nlinkset_status(*routine) == LS_AVAILABLE) + (*routine) = ((*routine) & 0x3f); // current route is normal linkset + else if (Alinkset_status(*routine) == LS_AVAILABLE) + (*routine) = ((*routine) & 0x3f) + 0x40; + else + (*routine) = ((*routine) & 0x3f) + 0x80; + } + + if(0) + { + mark_alternative_linkset_available(&mtp3.nw[nw].routine[spplace]); + routine = (BYTE *)&mtp3.nw[nw].routine[spplace]; + } + + if(1) + if(mtp3ObjState.lk_mtp3[chl] == mtp3_localip && mtp_peer_ip != 0) + { + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, + nw, + sp->routine[spplace], + mtp_peer_ip, + chl, + opc); + } + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s:%d> S5 ALS,M3UA update route info, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, __LINE__, + chl, + spplace, sp->routine[spplace]); + + if(mtp3ObjState.lk_mtp3[chl] == mtp3_localip && mtp3_para->lk[chl].e1_to_alterMTP3 !=0) + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, nw, sp->routine[spplace], mtp3_para->lk[chl].e1_to_alterMTP3, chl, opc); + } + } +// if ((mtp3.nw[nw].routine[dpc_index] & 0x0f) == 0x0a)// all road unavailable +// mark_dstSP_inaccessible(&mtp3.nw[nw].routine[dpc_index]); +// hmrt_tfrc_update_routing_tables(dpc_index,nw); + +} + +int m3ua_ssnm_update_route(xua_ssnm_cmd *p_ssnm) +{ + BYTE ssnm_type,nw; + WORD link; + DWORD dpc; + network *sp; + WORD nls=MAX_LS; + WORD als=MAX_LS; + ls_info *ls; + int i; + WORD lsno,spplace; + + if(p_ssnm == NULL) + return -1; + + ssnm_type = p_ssnm->type; + link = p_ssnm->link; + lsno = mtp3_para->lk[link].e1_to_linkset; + if ( lsno >= MAX_LS ) + { + mtp3_debug(MTP3DB_EVENT,"m3ua link %d recv ssnm command, but linkset is error",link); + return -1; + } + nw = mtp3_para->ls_pro[lsno].nw_id; + ls = &mtp3.ls[lsno]; + sp = &mtp3.nw[nw]; + + dpc = p_ssnm->aff_pc; + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + if(mtp3_para->nw[nw].routing[spplace].dpc == dpc) + { + nls = lsno; + break; + } + spplace = MAX_ROUTE; + } + + if(nls != lsno) + { + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asALS[i]; + if(mtp3_para->nw[nw].routing[spplace].dpc == dpc) + { + nls = lsno; + break; + } + spplace = MAX_ROUTE; + } + } + + switch(ssnm_type) + { + case 1://SSNM_DUNA: + mtp3_debug(MTP3DB_EVENT,"m3ua link %d recv SSNM_DUNA dpc=%ld",link,dpc); + if(spplace >= MAX_ROUTE) + { + return -1; + } + if (nls == lsno) + mark_normal_linkset_unavailable(&sp->routine[spplace]); + else if (als == lsno) + mark_alternative_linkset_unavailable(&sp->routine[spplace]); + mtp3_debug(MTP3DB_EVENT,"\33[31mM3UA Link %d DPC=%ld out of service,linkset = %d \33[0m",link,dpc, lsno); + break; + case 2://SSNM_DAVA: + mtp3_debug(MTP3DB_EVENT,"m3ua link %d recv SSNM_DAVA dpc=%ld",link,dpc); + if(spplace >= MAX_ROUTE) + { + return -1; + } + if (nls == lsno) + mark_normal_linkset_available(&sp->routine[spplace]); + else if (als == lsno) + mark_alternative_linkset_available(&sp->routine[spplace]); + mtp3_debug(MTP3DB_EVENT,"\33[32mM3UA Link %d DPC=%ld in service,linkset = %d \33[0m",link,dpc, lsno); + break; + case 3://SSNM_DAUD: + mtp3_debug(MTP3DB_EVENT,"m3ua link %d recv SSNM_DAUD dpc=%ld",link,dpc); + if(mtp3_check_dpc_equal_to_opc(nw, dpc)) + { + mtp3_debug(MTP3DB_EVENT,"m3ua link %d send SSNM_DAVA dpc=%ld",link,dpc); + send_command_to_m3ua(link, 2, M3UA_SSNM_CMD, 0, dpc);//SSNM_DAVA + } + else + {// fix me to support M3UA STP + mtp3_debug(MTP3DB_EVENT,"m3ua link %d send SSNM_DUNA dpc=%ld",link,dpc); + send_command_to_m3ua(link, 1, M3UA_SSNM_CMD, 0, dpc);//SSNM_DUNA + } + break; + case 6://SSNM_DRST: + case 5://SSNM_DUPU: + case 4://SSNM_SCON: + default : + mtp3_debug(MTP3DB_EVENT,"m3ua link %d recv ssnm_type=%d",link,ssnm_type); + return -1; + } + + if(spplace >= MAX_ROUTE) + { + return -1; + } + hmrt_tfrc_update_routing_tables(spplace, nw); + if((sp->routine[spplace] & 0x80) == 0x80) + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,UNAVAILABLE); + else + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,AVAILABLE); + + if(1) + if(mtp3ObjState.lk_mtp3[link] == mtp3_localip && mtp_peer_ip != 0) + { + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, + nw, + sp->routine[spplace], + mtp_peer_ip, + link, + mtp3_para->nw[nw].routing[spplace].opc); + } + + if(mtp3ObjState.lk_mtp3[link] == mtp3_localip && mtp3_para->lk[link].e1_to_alterMTP3 !=0) + send_route_to_other_plat(mtp3_para->nw[nw].routing[spplace].dpc, nw, sp->routine[spplace], mtp3_para->lk[link].e1_to_alterMTP3, link, mtp3_para->nw[nw].routing[spplace].opc); + + return 1; +} + +int m3ua_updateStatus(WORD chl, BYTE new_l2_state,BYTE command, DWORD rc, BYTE rc_status) +{ + WORD ls_t; + BYTE nw; + int j, sls, lsx16; + ls_info *ls; + int set_unaccessable = 0 ; + + /* + if ((mtp3ObjState.lk_configured[chl] == PARA_NOT_CONFIGURED) || + (mtp3ObjState.lk_mtp3[chl] != mtp3_localip)) + return 0; + + */ + rc_timer = 195+(mtp2_systemid%2)*5; + + if (mtp3ObjState.lk_configured[chl] == PARA_NOT_CONFIGURED) + return 0; + + ls_t = mtp3_para->lk[chl].e1_to_linkset; + if(mtp3ObjState.link_l1_state[chl] == 0 && mtp3ObjState.link_l2_state[chl]!=0) + { + mtp3ObjState.link_l2_state[chl] = 0;//reset l2 state + } + if (ls_t >= MAX_LS) + return 0; + lsx16 = ls_t<<4; + ls = &mtp3.ls[ls_t]; + nw = mtp3_para->ls_pro[ls_t].nw_id&3; + ls->links_available_t = scan_ls_link_available(ls_t); + + + if(detail_debug_flag) + { + mtp3_debug(MTP3DB_ERROR,"m3ua_updateStatus, link=%d, l2_state=%d, command=%d, rc=%d, rc_status=%d", + chl, new_l2_state, command, rc, rc_status); + mtp3_debug(MTP3DB_ERROR,"old, l2 state=%d, l3_state=%d links available_t=%d", + mtp3ObjState.link_l2_state[chl], mtp3ObjState.link_l3_state[chl], ls->links_available_t); + } + + if (new_l2_state != mtp3ObjState.link_l2_state[chl]) + { + if(detail_debug_flag) + { + mtp3_debug(MTP3DB_ERROR,"m3ua_updateStatus, link=%d, l2_state=%d, command=%d, rc=%d, rc_status=%d", + chl, new_l2_state, command, rc, rc_status); + mtp3_debug(MTP3DB_ERROR,"old, l2 state=%d, l3_state=%d links available_t=%d", + mtp3ObjState.link_l2_state[chl], mtp3ObjState.link_l3_state[chl], ls->links_available_t); + } + + if (new_l2_state == MTP2_STATE_WORKING) + { + current_measure->lk_measure1[chl][2]++; + mtp3_debug(MTP3DB_EVENT,"m3ua link %d L2 in service",chl); + mtp3_debug(MTP3DB_EVENT,"\33[32mM3UA Link %d L3 in service,linkset = %d \33[0m",chl, ls_t); + if ( ls->links_available_t > 0 )/* WITHIN LS */ + { + for ( j=0; j<16; j++ ) + { + sls = lsx16+j; + if ( (ls_sls[sls] != chl) && + (sls_to_link[sls] == chl) ) + ls_sls[sls] = chl; + } + } + else + { + current_active_ls_num++; + current_measure->ls_measure[ls_t][2]++;/* STOP of link set failure */ + memset(&ls_sls[lsx16],chl,16); + } + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + { + mtp3_send_mtp2_alarm(8+chl,0); + } + set_heartbeat(ALARM_LINK_AVAILABLE, chl); + set_heartbeat(ALARM_LS_AVAILABLE,ls_t); + mtp3_send_alarm(ls_t+MTP3_LINKSET_COMPONENT,0); + //mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_IN_SERVICE; + + //hmrt_tcbc_update_routing_tables(chl); + + mtp3ObjState.link_l1_state[chl] = 1; + mtp3ObjState.link_l2_state[chl] = MTP2_STATE_WORKING; + mtp3ObjState.link_l3_state[chl] = AVAILABLE; + mtp3ObjState.lsac_state[chl] = LSAC_ACTIVE_STATE; + mtp3ObjState.sltc_state[chl] = SLTC_RUNNING_STATE; + mtp3ObjState.tlac_state[chl] = TLAC_AVAILABLE_STATE; + + //ls->links_available++; + /* + if (mtp3.ls[ls_t].links_available == 0) + m3ua_upd_route_status(chl, 1, rc, rc_status); + hmrt_tcbc_update_routing_tables(chl); + + */ + //if(ls->links_available_t == 0) + m3ua_upd_route_status(chl, rc, 5, 1); + + mtp3.ls[ls_t].links_available ++; + + ls->links_available_t = scan_ls_link_available(ls_t); + + if(ls->links_available_t == 1) + { + if (mtp3ObjState.lk_mtp3[chl] != mtp3_localip) + ls->send_asp_ac_link_id = chl; + } + + if(0) + { + if(ls->links_available_t== 1) + { + if(ls->send_asp_ac_link_id == 0x00 || ls->send_asp_ac_link_id == 0xffff ) + {//for override mode + ls->send_asp_ac_link_id = chl; + + m3ua_set_link_rc_to_m2ua(chl); + + send_command_to_m3ua(chl, 1,M3UA_RC_CMD , rc, 0); + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"<%s:%d> M3UA send RC_CMD, link=%d", + __FUNCTION__, __LINE__, + chl); + + } + } + } + + //mtp3ObjState.lk_mtp3[chl] = mtp3_localip; + } + else if (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING) + { + local_change_over[chl]++; + mtp3_debug(MTP3DB_EVENT,"m3ua link %d L2 out of service",chl); + mtp3_debug(MTP3DB_EVENT,"\33[31mM3UA Link %d L3 out of service,Linkset %d out of service\33[0m",chl,ls_t); + hmrt_tcoc_update_routing_tables(chl); + set_heartbeat(ALARM_LINK_UNAVAILABLE,chl); + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + { +// mtp3_send_alarm(ls_t+MTP3_LINKSET_COMPONENT,1); + mtp3_send_mtp2_alarm(8+chl,M2UAALARM_SCTP_Failure); + } + + //mtp3ObjInput.lsac_input_from_l2[chl] = LSAC_L2_OUT_OF_SERVICE; + //mtp3ObjInput.sltc_input[chl] = SLTC_STOP; + //sltc_proc(chl); + mtp3ObjState.link_l1_state[chl] = 0; + mtp3ObjState.link_l2_state[chl] = 0; + mtp3ObjState.link_l3_state[chl] = 0; + mtp3ObjState.lsac_state[chl] = 0; + mtp3ObjState.sltc_state[chl] = 0; + mtp3ObjState.tlac_state[chl] = 0; + + memset(mtp3.ls[ls_t].links_nls_asp_ac_send_flag, 0x00, sizeof(BYTE)*(MAX_ROUTE+1)); + memset(mtp3.ls[ls_t].links_als_asp_ac_send_flag, 0x00, sizeof(BYTE)*(MAX_ROUTE+1)); + + if (mtp3.ls[ls_t].links_available > 0) + mtp3.ls[ls_t].links_available --; + + if(ls->send_asp_ac_link_id == chl) + ls->send_asp_ac_link_id = 0xFFFF; + + ls->links_nls_asp_ac_send_flag[chl] = 0; + + ls->links_available_t = scan_ls_link_available(ls_t); + + if(mtp3.ls[ls_t].links_available_t == 0) + m3ua_upd_route_status(chl, rc, 0, 1); + + set_unaccessable = 1; + + /* + if (mtp3.ls[ls_t].links_available_t > 0) + mtp3.ls[ls_t].links_available_t --; + */ + + } + + } + if(new_l2_state==0)//fixed m3ua dual handling + { + mtp3ObjState.link_l3_state[chl] = 0; + mtp3ObjState.lsac_state[chl] = 0; + ls->links_available_t = scan_ls_link_available(ls_t); + + if(m2ua_get_traffic_mode_type()==0) + { + if(ls->send_asp_ac_link_id == chl) + ls->send_asp_ac_link_id = 0xFFFF; + } + + if( set_unaccessable == 0) + { + if(mtp3.ls[ls_t].links_available_t == 0) + m3ua_upd_route_status(chl, rc, 0, 1); + } + } + if(command==1)//rc status + { + m3ua_upd_route_status(chl, rc, rc_status, 0); + } + +// m3ua_check_route_status(chl); + + return 1; +} + +int GetM3uaMsg(ulong port) +{ + xua_m3ua_msg *msgptr = NULL; + xua_lm_lk *lm_lk_ptr = NULL; + xua_rc_cmd *rc_cmd_ptr = NULL; + xua_ssnm_cmd *ssnm_cmd_ptr = NULL; + BYTE nw,dpc_equal_to_opc,ssf; + BYTE new_l2_state; + BYTE rc_status, db_type; + DWORD rc, chl; + WORD m3ua_msg_len; + + if(!get_m3ua_msg(&mtp3_m3ua_msg)) + { + msgptr = &mtp3_m3ua_msg->msg.m3ua; + lm_lk_ptr = &mtp3_m3ua_msg->msg.lm_lk; + rc_cmd_ptr = &mtp3_m3ua_msg->msg.rc_cmd; + ssnm_cmd_ptr = &mtp3_m3ua_msg->msg.ssnm_cmd; +/* if( mtp3_send_netcap && ( (mtp3_m3ua_msg->sio & 0xF0 ) != 0xF0 ) ) + { + int pclen ; + sio = mtp3_m3ua_msg->sio; + nw = sio >> 6; + pclen = pc_length(nw); + + if ( pclen == MTP3_24BIT_PC ) //ansi + { + NcMtp3Send ( &mtp3_m3ua_msg->sio + , ntohs(mtp3_m3ua_msg->len), 1 ); + } + else if ( pclen == MTP3_14BIT_PC ) //ITU + { + NcMtp3Send ( &mtp3_m3ua_msg->sio + , ntohs(mtp3_m3ua_msg->len), 0 ); + } + } +*/ + + if(mtp3_m3ua_msg->msg_class == M3UA_MGMT_CMD) + { + + chl = lm_lk_ptr->link;//??? + new_l2_state = lm_lk_ptr->opercode; + if(new_l2_state) + m3ua_updateStatus(chl, new_l2_state, 0, 0 ,0); + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"get M3UA link[%d], state=%d, heartbeat from %lx", chl, new_l2_state, msgSourceIP); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,(BYTE *)mtp3_m3ua_msg,ntohs(lm_lk_ptr->len)+4); + + return 0; + + } + else if(mtp3_m3ua_msg->msg_class == M3UA_RC_CMD) + { + chl = rc_cmd_ptr->link;//??? + rc_status = rc_cmd_ptr->opercode; + rc = rc_cmd_ptr->rc; + m3ua_updateStatus(chl, 5, 1, rc, rc_status); + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"get M3UA rc heartbeat from %lx",msgSourceIP); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,(BYTE *)mtp3_m3ua_msg,ntohs(rc_cmd_ptr->len)+4); + return 0; + + } + else if(mtp3_m3ua_msg->msg_class == M3UA_SSNM_CMD) + { + m3ua_ssnm_update_route(ssnm_cmd_ptr); + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"get M3UA ssnm message from %lx",msgSourceIP); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,(BYTE *)mtp3_m3ua_msg,ntohs(ssnm_cmd_ptr->len)+4); + return 0; + + } + else if(mtp3_m3ua_msg->msg_class == M3UA_MAUP_MSG)// M3uaMsg + { + nw = msgptr->ni; + ssf = msgptr->si; + dpc_equal_to_opc = mtp3_check_dpc_equal_to_opc(msgptr->ni, msgptr->dpc); + m3ua_msg_len = ntohs(msgptr->len)+20+1; + //if (msgdpc != mtp3_para->nw[nw].opc24)/* STP */ + if (!dpc_equal_to_opc) //STP + { + mtp3_debug(MTP3DB_ERROR,"mtp3<==m3ua, dpc=%lx!=local opc, len=%d!", msgptr->dpc, m3ua_msg_len); + mtp3_showbuf(MTP3DB_ERROR,(BYTE *)mtp3_m3ua_msg, m3ua_msg_len); + return 1;//not support STP +/* + sls = msgprt->sls;//msgptr[10] & 0x0f; + outlink = check_outbound_route(nw,msgdpc,sls); + if (outlink >= 0) + { + if (ip_port == M2UA_PORT) + { + memcpy(mtp3_iprt.io_msg.msgContent, msgptr, len); + msgptr = mtp3_iprt.io_msg.msgContent; + } + mtp3_Trans_stpMsg(msgptr,outlink,pc_len); + return 1; + } +*/ + + } + else + { + switch(msgptr->si) + { + case SCCP_SIO: + if ( (S_shm_ptr->MS_Buf.WSub+1) == S_shm_ptr->MS_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[0]++; + break; + } + m3ua_send_to_sccp(msgptr); + db_type = MTP3DB_SCCPMSG; + mtp3_debug(db_type,"SCCP<==M3UA,NW=%x,SIO=%x,SPC(%lx->%lx),link=%d",msgptr->ni,msgptr->si,msgptr->opc,msgptr->dpc,msgptr->link); + break; + case BICC_SIO: + if ( (B_shm_ptr->MI_Buf.WSub+1) == B_shm_ptr->MI_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[2]++; + break; + } + m3ua_send_to_bicc(msgptr); + db_type = MTP3DB_BICCMSG; + mtp3_debug(db_type,"BICC<==M3UA,NW=%x,SIO=%x,SPC(%lx->%lx),link=%d",msgptr->ni,msgptr->si,msgptr->opc,msgptr->dpc,msgptr->link); + break; + case ISUP_SIO: + if ( (I_shm_ptr->MI_Buf.WSub+1) == I_shm_ptr->MI_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[2]++; + break; + } + m3ua_send_to_isup(msgptr); + db_type = MTP3DB_ISUPMSG; + mtp3_debug(db_type,"ISUP<==M3UA,NW=%x,SIO=%x,SPC(%lx->%lx),link=%d",msgptr->ni,msgptr->si,msgptr->opc,msgptr->dpc,msgptr->link); + break; + case TUP_SIO: + if ( (T_shm_ptr->MT_Buf.WSub+1) == T_shm_ptr->MT_Buf.RSub)// buffer overflow + { + mtp3.nw[nw].flow.MtoU_throwed[1]++; + break; + } + m3ua_send_to_tup(msgptr); + db_type = MTP3DB_TUPMSG; + mtp3_debug(db_type,"TUP<==M3UA,NW=%x,SIO=%x,SPC(%lx->%lx),link=%d",msgptr->ni,msgptr->si,msgptr->opc,msgptr->dpc,msgptr->link); + break; + + default: + db_type = MTP3DB_ERROR; + mtp3_debug(db_type,"MTP3<==M3UA,NW=%x,SIO=%x,SPC(%lx->%lx),link=%d",msgptr->ni,msgptr->si,msgptr->opc,msgptr->dpc,msgptr->link); + mtp3.nw[msgptr->ni].flow.ItoM_throwed[msgptr->si-1]++; + break; + + } + + mtp3_showbuf(db_type, (BYTE *)mtp3_m3ua_msg, m3ua_msg_len); + } + } + } + return 1; +} + + +int send_command_to_m3ua(WORD link, BYTE command, BYTE xua_msg_class, DWORD rc, DWORD aff_pc) +{ + char charCmd[32]; + static int rc_cmd_counter=0, total_cmd_counter=0; + + if(0) + { + if(rc_cmd_counter < 5 && total_cmd_counter++ < 100) + { + char buf[128]; + + sprintf(buf, "link=%d, cmd=%d, xmc=%d", link, command, xua_msg_class); + pub_print_traceback(buf); + } + } + + if(xua_msg_class == M3UA_RC_CMD) + { + rc_cmd_counter ++; + mtp3_iprt.io_msg.msgLength = 5+1+4+1; + mtp3_iprt.io_msg.msgContent[0] = xua_msg_class; + mtp3_iprt.io_msg.msgContent[2] = link>>8; + mtp3_iprt.io_msg.msgContent[1] = link&0xff; + mtp3_iprt.io_msg.msgContent[3] = 0; + mtp3_iprt.io_msg.msgContent[4] = 7; + mtp3_iprt.io_msg.msgContent[9] = command; + memcpy(&mtp3_iprt.io_msg.msgContent[5], &rc, 4); + + sprintf(charCmd,"M3UA_ASP_Active"); + + }else if(xua_msg_class == M3UA_MGMT_CMD) + { + mtp3_iprt.io_msg.msgLength = 5+1+1; + mtp3_iprt.io_msg.msgContent[0] = xua_msg_class; + mtp3_iprt.io_msg.msgContent[2] = link>>8; + mtp3_iprt.io_msg.msgContent[1] = link&0xff; + mtp3_iprt.io_msg.msgContent[3] = 0; + mtp3_iprt.io_msg.msgContent[4] = 3; + mtp3_iprt.io_msg.msgContent[5] = ((mtp3ObjState.lk_mtp3[link] >> 16) & 0xff)-32;// 172.18.x+32.1 + mtp3_iprt.io_msg.msgContent[6] = command; + + switch (command) + { + case MTP2_DEACTIVE_LINK: + sprintf(charCmd,"M3UA_DEACTIVE_LINK"); + break; + case MTP3_M3UA_ENABLE: + sprintf(charCmd,"M3UA_ACTIVE_LINK"); + break; + case MTP3_M3UA_DISABLE: + sprintf(charCmd,"M3UA_DISABLE_LINK"); + break; + default: + break; + } + } + else if(xua_msg_class == M3UA_SSNM_CMD) + { + mtp3_iprt.io_msg.msgLength = 10; + mtp3_iprt.io_msg.msgContent[0] = xua_msg_class; + mtp3_iprt.io_msg.msgContent[2] = link>>8; + mtp3_iprt.io_msg.msgContent[1] = link&0xff; + mtp3_iprt.io_msg.msgContent[3] = 0; + mtp3_iprt.io_msg.msgContent[4] = 7; + mtp3_iprt.io_msg.msgContent[5] = command; + memcpy(&mtp3_iprt.io_msg.msgContent[6], &aff_pc, 4); + } + else + return 0; + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"MTP3 send command %s to m3ua link %d",charCmd,link); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,&mtp3_iprt.io_msg.msgContent[0],mtp3_iprt.io_msg.msgLength); + put_m3ua_msg((xua_up_msg_t *) mtp3_iprt.io_msg.msgContent); + return 1; +} + +void deactive_m3ua_lk(WORD link) +{ + if ((MTP3_LINK_TYPE(link) == LKTYPE_M3UA) && // M3UA + (mtp3_para->lk[link].admin_state& 0x01)) + { + mtp3_debug(MTP3DB_EVENT,"m3ua link %d Deactive by MNG",link); + send_command_to_m3ua(link, MTP3_M3UA_DISABLE,M3UA_MGMT_CMD,0,0); + m3ua_updateStatus(link, 0, 0, 0 ,0); + + } +} + +void m3ua_set_link_rc_to_m2ua(int linkno) +{ + int i; + WORD lsno, spplace; + BYTE nw; + DWORD rc; + network *sp; + ls_info *ls; + + lsno = mtp3_para->lk[linkno].e1_to_linkset; + if (lsno >= MAX_LS) + return; + + ls = &mtp3.ls[lsno]; + nw = mtp3_para->ls_pro[lsno].nw_id; + sp = &mtp3.nw[nw]; + + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + rc = mtp3_para->nw[nw].routing[spplace].rc; + m2ua_set_sg_rc(linkno, rc); + } + +} + +void check_m3ua_link_status(int force_flag) +{ + int link,i; + WORD lsno, spplace; + BYTE nw; + DWORD rc; + network *sp; + ls_info *ls; + static int link_timer=0; + int check_timer = ( mtp2_systemid * 30 + 400); + int send_asp_ac_flag = 0; + + if(rc_timer >= check_timer || force_flag)//2s + { + rc_timer = 0; + for(link=0;linklk[link].admin_state& 1)&&(check_if_local_ip(mtp3ObjState.lk_mtp3[link] )) ) //mtp3_localip)) + if(MTP3_LINK_TYPE(link) == LKTYPE_M3UA && (mtp3_para->lk[link].admin_state& 1)&&(mtp3ObjState.lk_mtp3[link] == mtp3_localip)) + { + if(mtp3ObjState.link_l3_state[link] == AVAILABLE) + { + lsno = mtp3_para->lk[link].e1_to_linkset; + if (lsno >= MAX_LS) + return; + ls = &mtp3.ls[lsno]; + nw = mtp3_para->ls_pro[lsno].nw_id; + sp = &mtp3.nw[nw]; + ls->links_available_t = scan_ls_link_available(lsno); + + send_asp_ac_flag = 0; + + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + rc = mtp3_para->nw[nw].routing[spplace].rc; + + m2ua_set_sg_rc(link, rc); + + if(m2ua_get_traffic_mode_type()==0) + { + /* + if(ls->links_nls_asp_ac_send_flag[spplace] == 1 ) + { + if(ls->links_available_t == 1) + { + if(ls->send_asp_ac_link_id != link) + send_asp_ac_flag = 1; + } + else + break; + } + */ + if (sp->m3ua_rc_status[spplace]!=5)/*normal route unavailable */ + { + if(ls->links_nls_asp_ac_send_flag[spplace] != 1 ) + { + send_asp_ac_flag = 1; + } + if(ls->links_available_t >1) + { + send_asp_ac_flag = 0; + } + + } + else if(ls->links_available_t == 1) + { + if(ls->send_asp_ac_link_id != link) + { + send_asp_ac_flag = 1; + } + } + if(send_asp_ac_flag == 0) + { + //ls->send_asp_ac_link_id = link; // + if(0) + { + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"<%s:%d> M3UA send RC_CMD, link=%d, total links=%d, sppace=%d, sp->routine=%d, act link=%d", + __FUNCTION__, __LINE__, + link, + ls->links_available_t, + spplace, + sp->routine[spplace], + ls->send_asp_ac_link_id); + + } + + } + else + { + if(ls->links_nls_asp_ac_send_flag[link] == 1) + send_asp_ac_flag = 0; + } + } + else + { + if(0) + mtp3_debug(MTP3DB_EVENT,"<%s:%d> link=%d, sppace=%d, sp->routine=%d, rc_status=%d, lk_asp_ac=%d", + __FUNCTION__, __LINE__, + link, + spplace, + sp->routine[spplace], + sp->m3ua_rc_status[spplace], + ls->links_nls_asp_ac_send_flag[link]); + + + if(sp->m3ua_rc_status[spplace]!=5 || ls->links_nls_asp_ac_send_flag[link] == 0 ) + { + send_asp_ac_flag = 1; + /* + ls->links_nls_asp_ac_send_flag[spplace] = 0x01; + ls->send_asp_ac_link_id = link; + send_command_to_m3ua(link, 1,M3UA_RC_CMD , rc, 0); + */ + } + } + + if(send_asp_ac_flag) + { + ls->links_nls_asp_ac_send_flag[link] = 0x01; + ls->send_asp_ac_link_id = link; + + send_command_to_m3ua(link, 1,M3UA_RC_CMD , rc, 0); + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"<%s:%d> M3UA send RC_CMD, link=%d, total links=%d, sppace=%d, sp->routine=%d, rc=%d", + __FUNCTION__, __LINE__, + link, + ls->links_available_t, + spplace, + sp->routine[spplace], + sp->m3ua_rc_status[spplace]); + + break; + + } + + /* + if(m2ua_get_traffic_mode_type()==0) + { + + if (sp->m3ua_rc_status[spplace]!=5)//normal route unavailable + { + ls->links_nls_asp_ac_send_flag[spplace] = 0x01; + + send_command_to_m3ua(link, 1,M3UA_RC_CMD , rc, 0); + } + } + else + { + if(sp->m3ua_rc_status[spplace]!=5 || ls->links_nls_asp_ac_send_flag[spplace] == 0x00) + { + ls->links_nls_asp_ac_send_flag[spplace] = 0x01; + + send_command_to_m3ua(link, 1,M3UA_RC_CMD , rc, 0); + } + } + */ + } + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asALS[i]; + rc = mtp3_para->nw[nw].routing[spplace].rc; + + /* + if(m2ua_get_traffic_mode_type()==0) + { + + if (sp->m3ua_rc_status[spplace]!=5)//alter route unavailable + { + if(ls->links_als_asp_ac_send_flag[spplace] == 0x00) + { + ls->links_als_asp_ac_send_flag[spplace] = 0x01; + + send_command_to_m3ua(link, 1, M3UA_RC_CMD, rc, 0); + + mtp3_debug(MTP3DB_EVENT,"<%s:%d> M3UA send RC_CMD, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, __LINE__, + link, spplace, sp->routine[spplace]); + } + } + } + else + { + if(sp->m3ua_rc_status[spplace]!=5 || ls->links_als_asp_ac_send_flag[spplace] == 0x00) + { + ls->links_als_asp_ac_send_flag[spplace] = 0x01; + + send_command_to_m3ua(link, 1, M3UA_RC_CMD, rc, 0); + + mtp3_debug(MTP3DB_EVENT,"<%s:%d> M3UA send RC_CMD, link=%d, sppace=%d, sp->routine=%d", + __FUNCTION__, __LINE__, + link, spplace, sp->routine[spplace]); + + } + } + */ + } + } + else + { + lsno = mtp3_para->lk[link].e1_to_linkset; + if (lsno >= MAX_LS) + return; + ls = &mtp3.ls[lsno]; + + ls->links_nls_asp_ac_send_flag[link] = 0x00; + ls->send_asp_ac_link_id = 0x00; + + } + } + } + } + if(link_timer>=1000)//10s + { + link_timer = 0; + for(link=0;linklk[link].admin_state& 1) &&(mtp3ObjState.lk_mtp3[link] == mtp3_localip)) + { + if(mtp3ObjState.link_l3_state[link] == UNAVAILABLE || mtp3ObjState.link_enable_sent_flag[link] == 0) + { + mtp3ObjState.link_enable_sent_flag[link] = 1; + send_command_to_m3ua(link, MTP3_M3UA_ENABLE,M3UA_MGMT_CMD,0, 0); + + rc_timer = 100; + } + } +/* if(MTP3_LINK_TYPE(link) == LKTYPE_M3UA && mtp3ObjInput.lsac_input_from_mgmt[link] == LSAC_MGMT_DEACTIVATE_LINK) + { +// mtp3_debug(MTP3DB_EVENT,"m3ua link %d Deactive by other plat MNG",link); +// send_command_to_m3ua(link, MTP3_M3UA_DISABLE,M3UA_MGMT_CMD,0); + deactive_m3ua_lk(link); + mtp3ObjInput.lsac_input_from_mgmt[link] = LSAC_MGMT_ACTIVATE_LINK; + + } +*/ + } + } + link_timer++; + rc_timer++; +} + + +void m3ua_timer() +{ + check_m3ua_link_status(0); +} + +void send_mtp_msg(int outlink, BYTE *msgptr) +{ + int linkset; + ls_info *ls; + ls_para *ls_pro=NULL; + BYTE nw; + ulong dst_ip; + long opc,dpc; + long route_mark; + BYTE sls; + BYTE pclen; + WORD len; + BYTE ssf; + BYTE debugtype=0; + xua_up_msg_t *m3ua_ptr=NULL; + + if(msgptr == NULL) + { + return; + } + m3ua_ptr = (xua_up_msg_t *)msgptr; + ssf = msgptr[3] & 0x0f; + linkset = mtp3_para->lk[outlink].e1_to_linkset; + ls = &mtp3.ls[linkset]; + ls_pro = &mtp3_para->ls_pro[linkset]; + nw = ls_pro->nw_id; + pclen = pc_length(nw); + if ( ls_pro->loopback_opt != 0 )/* this linkset is loop back linkset */ + { + if ( pclen == MTP3_24BIT_PC ) + { + opc = mtp3_para->nw[nw].opc24; + memcpy( &msgptr[5],&opc,3);/* change msg's dpc to opc */ + } + else + { + opc = mtp3_para->nw[nw].opc14; + memcpy( (BYTE*)&route_mark,&msgptr[5],4); + sls = (route_mark >> 28) & 0xf; + route_mark = (sls << 28)+(opc << 14)+opc; + memcpy(&msgptr[5],&route_mark,4); + } + } + + if (ssf > 1) + { + ssf--; + debugtype = MTP_MSG_DOWN; + } + else + debugtype = MTP_SNM_MSG; +// current_measure->tf_measure1[4][wx5[nw]+ssf]+=len;/* octets */ + current_measure->tf_measure2[4][wx5[nw]+ssf]++;/* MSUs */ + +// len = msgptr[1]+2; + len = (msgptr[2]<<8) + msgptr[3]+4; + if(len > MAX_SS7_MSG_LEN) + { + mtp3_debug(MTP3DB_ERROR,"send_mtp_msg, length longer than %d, len=%d!", MAX_SS7_MSG_LEN, len); + msgptr[2] = 0; + len = MAX_SS7_MSG_LEN; + } + mtp3_iprt.io_msg.msgLength = len; + + if( mtp3_send_netcap && ( ( msgptr[4] & 0xF0) != 0xF0 ) ) + { + if ( pclen == MTP3_24BIT_PC ) //ansi + { + NcMtp3Send ( &msgptr[4], (msgptr[2]<<8) + msgptr[3], 1 ); + } + else if ( pclen == MTP3_14BIT_PC ) //ITU + { + NcMtp3Send ( &msgptr[4], (msgptr[2]<<8) + msgptr[3], 0 ); + } + } + +#if _INCLUDE_M2UA + if (mtp3ObjState.lk_mtp3[outlink] != mtp3_localip) + {//transfer to remote plat + dst_ip = mtp3ObjState.lk_mtp3[outlink]; + //dst_ip = (dst_ip << 16) | E1CARD_BASE_IP; + /* debug show message */ + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ +// send_to_mtp2(dst_ip); + send_to_mtp2_new_struct(dst_ip); + } + else if (MTP3_LINK_TYPE(outlink) == LKTYPE_NONE_SIGTRAN) +#endif + { + dst_ip = LINK_TO_IP(outlink); + /* debug show message */ + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ + send_to_mtp2(dst_ip);//use old struct send to 8k bload + } +#if _INCLUDE_M2UA + else + { + if (MTP3_LINK_TYPE(outlink) == LKTYPE_MTP3_LITE) + { + /* debug show message */ + dst_ip = mtp3_para->lk[outlink].remote_ip; + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ + if ((msgptr[4] & 0x0f) == 3) + put_mtp3lite_msg(msgptr); + return; + } + if (MTP3_LINK_TYPE(outlink) == LKTYPE_M3UA) + { + dst_ip = mtp3_para->sg[mtp3_para->lk[outlink].e1_to_sg].ip; + /* debug show message */ + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ + if(pclen == MTP3_24BIT_PC) + { +// memmove(m3ua_ptr->msg.m3ua.content, msgptr+11+1, len-8-1); + memmove(m3ua_ptr->msg.m3ua.content, msgptr+11+1, len-6-1); + + dpc = 0; + opc = 0; + sls = msgptr[11]; + memcpy(&dpc,&msgptr[5],3); + memcpy(&opc,&msgptr[8],3); + m3ua_ptr->msg.m3ua.dpc = dpc; + m3ua_ptr->msg.m3ua.opc = opc; + m3ua_ptr->msg_class = M3UA_MAUP_MSG; + m3ua_ptr->msg.m3ua.ni = nw; + m3ua_ptr->msg.m3ua.si = msgptr[4] & 0x0f; +// m3ua_ptr->msg.m3ua.len = ntohs(len - 8 - 1 - 4); //m3ua_ptr->msg.m3ua.len = ntohs(len - 8-1); //modify by Jink on 2012-11-01 + m3ua_ptr->msg.m3ua.len = ntohs(len - 6 - 1 - 4); //m3ua_ptr->msg.m3ua.len = ntohs(len - 8-1); //modify by Jink on 2012-11-01 + + m3ua_ptr->msg.m3ua.mp = 0; + m3ua_ptr->msg.m3ua.sls = sls; + m3ua_ptr->msg.m3ua.rc = get_m3ua_rc_by_dpc(nw, m3ua_ptr->msg.m3ua.dpc, m3ua_ptr->msg.m3ua.opc); + } + else + { + memmove(m3ua_ptr->msg.m3ua.content, msgptr+8+1, len-5-1); + memcpy( (BYTE*)&route_mark,&msgptr[5],4); + sls = (route_mark >> 28) & 0xf; + dpc = route_mark & 0x3fff; + opc = (route_mark >>14)&0x3fff; + m3ua_ptr->msg.m3ua.opc = opc; + m3ua_ptr->msg.m3ua.dpc = dpc; +// memcpy(&m3ua_ptr->msg.m3ua.opc,&msgptr[7],3); + m3ua_ptr->msg_class = M3UA_MAUP_MSG; + m3ua_ptr->msg.m3ua.ni = nw; + m3ua_ptr->msg.m3ua.si = msgptr[4] & 0x0f; + m3ua_ptr->msg.m3ua.len = ntohs(len - 5 - 4); //m3ua_ptr->msg.m3ua.len = ntohs(len - 5); //modify by Jink on 2012-11-01 + m3ua_ptr->msg.m3ua.mp = 0; + m3ua_ptr->msg.m3ua.sls = sls; + m3ua_ptr->msg.m3ua.rc = get_m3ua_rc_by_dpc(nw, m3ua_ptr->msg.m3ua.dpc, m3ua_ptr->msg.m3ua.opc); + } + m3ua_ptr->msg.m3ua.link = outlink;//??? + + put_m3ua_msg((xua_up_msg_t *)msgptr); + return; + } + else + { + dst_ip = mtp3_para->sg[mtp3_para->lk[outlink].e1_to_sg].ip; + /* debug show message */ + if (iptrans_msg_flow(msgptr,pclen,debugtype,dst_ip)); + /* debug show message */ + put_m2ua_msg((m2ua_up_msg_t *)msgptr); + return; + } + } +#endif + + +} + +int get_route_from_other_plat(u32 dpc, u8 nw, long dest_ip, WORD chl, u32 opc) +{ + mtp3_iprt.io_msg.msgSrcPort = 4950; + mtp3_iprt.io_msg.msgDstPort = 4950; + mtp3_iprt.io_msg.msgDstIP = dest_ip; + mtp3_iprt.io_msg.msgContent[4] = 0x1f; + mtp3_iprt.io_msg.msgContent[5] = nw; + memcpy(&mtp3_iprt.io_msg.msgContent[6], &dpc, 4); + memcpy(&mtp3_iprt.io_msg.msgContent[10], &opc, 4); + mtp3_iprt.io_msg.msgContent[1] = chl>>8; + mtp3_iprt.io_msg.msgContent[0] = chl&0xFF; + mtp3_iprt.io_msg.msgContent[2] = 0; + mtp3_iprt.io_msg.msgContent[3] = 11; + mtp3_iprt.io_msg.msgLength = (mtp3_iprt.io_msg.msgContent[2]<<8) + mtp3_iprt.io_msg.msgContent[3]+4; + iptrDirectSendMsg(mtp3_iprt.io_msg); + return 1; +} + +void get_routes_from_other_plat() +{ + WORD link,i; + WORD lsno, nw, spplace; + DWORD dpc, opc; + network *sp; + ls_info *ls; + + for(link=0; linklk[link].e1_lk_type== LKTYPE_M3UA) + { + if(mtp3_para->lk[link].e1_to_mtp3 != mtp3_localip) + { + lsno = mtp3_para->lk[link].e1_to_linkset; + if (lsno >= MAX_LS) + return; + ls = &mtp3.ls[lsno]; + nw = mtp3_para->ls_pro[lsno].nw_id; + sp = &mtp3.nw[nw]; + + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + dpc= mtp3_para->nw[nw].routing[spplace].dpc; + opc= mtp3_para->nw[nw].routing[spplace].opc; + get_route_from_other_plat(dpc, nw, mtp3_para->lk[link].e1_to_mtp3, link, opc); + } + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asALS[i]; + dpc= mtp3_para->nw[nw].routing[spplace].dpc; + opc= mtp3_para->nw[nw].routing[spplace].opc; + get_route_from_other_plat(dpc, nw, mtp3_para->lk[link].e1_to_mtp3, link, opc); + } + } + } + + } +} + +BYTE get_route_value(u32 dpc, u8 nw, u32 opc) +{ + network *sp; + WORD i; + mtp3DPCIndex *sort_rec = &mtp3SortRoutine.nw[nw]; + int index; + ull opc_dpc=0; + + if (dpc==0) + return 0; + if(opc == mtp3_para->nw[nw].opc14) + opc =0; + opc_dpc = opc; + opc_dpc = (opc_dpc <<32)|dpc; + sp = &mtp3.nw[nw]; + + index = Mtp3BinSearchValue(0,sort_rec->sortedNum-1,nw,opc_dpc);//?? + if ((index >= 0) && (index < MAX_ROUTE)) + i = sort_rec->index[index]; + else + return 0; + + return sp->routine[i]; +} + +int update_route_by_other_plat(u32 dpc,BYTE nw, BYTE routine, WORD chl, u32 opc) +{ + network *sp; + int i; + mtp3DPCIndex *sort_rec = &mtp3SortRoutine.nw[nw]; + int index; + ls_info *ls; + WORD lsno; + WORD lsx16; + BYTE outroute; + lsno = mtp3_para->lk[chl].e1_to_linkset; + ull opc_dpc=0; + + return 0; + + if (lsno >= MAX_LS) + return 0; + if (dpc==0) + return 0; + ls = &mtp3.ls[lsno]; + lsx16 = lsno << 4; + + sp = &mtp3.nw[nw]; + if(opc == mtp3_para->nw[nw].opc14) + opc =0; + opc_dpc = opc; + opc_dpc = (opc_dpc <<32)|dpc; + index = Mtp3BinSearchValue(0,sort_rec->sortedNum-1,nw,opc_dpc);//??- + if ((index >= 0) && (index < MAX_ROUTE)) + i = sort_rec->index[index]; + else + return 0; + + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT," <%s:%d> link=%d, linkset=%d, dpc=%d, sp->routine .local=%d,peer=%d", + __FUNCTION__, __LINE__, + chl, + lsno, + dpc, + sp->routine[i], + routine); + if(0) + if(sp->routine[i] != routine) + { + outroute = (sp->routine[i] >> 6) & 3; + if(outroute != 2) + return 0; + } + + sp->routine[i] = routine; + + outroute = (routine >> 6) & 3; + if ( outroute == 2 )/* no outbound route */ + { + //memset(&ls_sls[lsx16],0xff,16); + for(i=0; i<16; i++) + { + if(sls_to_link[lsx16+i] == chl) + ls_sls[lsx16+i] = MAX_LK_INDEX; + } + } + else if ( (outroute == 0) && + ((routine & 3) == NLS_AVAILABLE) )/* current route is normal route */ + { + //memset(&ls_sls[lsx16],chl,16); + for(i=0; i<16; i++) + { + if(sls_to_link[lsx16+i] == chl) + ls_sls[lsx16+i] = chl; + } + } + else if ( ((routine >> 2) & 3) == ALS_AVAILABLE) + { + //memset(&ls_sls[lsx16],chl,16); + for(i=0; i<16; i++) + { + if(sls_to_link[lsx16+i] == chl) + ls_sls[lsx16+i] = chl; + } + } + return 1; +} + +int send_route_to_other_plat(u32 dpc, BYTE nw, BYTE routine, long dest_ip, WORD chl, u32 opc) +{ + mtp3_iprt.io_msg.msgSrcPort = 4950; + mtp3_iprt.io_msg.msgDstPort = 4950; + mtp3_iprt.io_msg.msgDstIP = dest_ip; + mtp3_iprt.io_msg.msgContent[4] = 0x2f; + mtp3_iprt.io_msg.msgContent[5] = nw; + memcpy(&mtp3_iprt.io_msg.msgContent[6], &dpc, 4); + mtp3_iprt.io_msg.msgContent[10] = routine; + memcpy(&mtp3_iprt.io_msg.msgContent[11], &opc, 4); + mtp3_iprt.io_msg.msgContent[1] = chl>>8; + mtp3_iprt.io_msg.msgContent[0] = chl&0xFF; + mtp3_iprt.io_msg.msgContent[2] = 0; + mtp3_iprt.io_msg.msgContent[3] = 12; + mtp3_iprt.io_msg.msgLength = (mtp3_iprt.io_msg.msgContent[2]<<8) + mtp3_iprt.io_msg.msgContent[3]+4; + iptrDirectSendMsg(mtp3_iprt.io_msg); + return 1; + +} + +#endif +/* + * Referenced functions. + */ + +/* + * Forward declarations. + */ + +/* + * Consistent with link set and link functions of: + * + * Signalling Message Handling (SMH) + * Message Routing (HMRT) + * Figure 26/Q.704 + * + * Note:- the HMRT state machine is a single state state machine which is + * best organized as a series of function calls and the interrogation of the + * ls->statem.own_sp_restart flag. These link set and link functions are + * essentially subroutine calls made by the route set and route functions + * which are part of the MTPI. + */ + +void hmrt_tra_msg(WORD linkset) +{ + ls_info *ls; + BYTE nw; + long route_mark; + BYTE *sd_tmp_buf; + int outlink; + + outlink = check_snmmsg_route(linkset); + if (outlink == -1) + return; + + ls = &mtp3.ls[linkset]; + nw = mtp3_para->ls_pro[linkset].nw_id; + sd_tmp_buf = &mtp3_iprt.io_msg.msgContent[0]; + if ( pc_length(nw) == MTP3_24BIT_PC ) + { + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 9; + sd_tmp_buf[4] = nw << 6; + memcpy(&sd_tmp_buf[5],&mtp3_para->ls_pro[linkset].ls_op_pc,3); + //memcpy(&sd_tmp_buf[7],&mtp3_para->nw[nw].opc24,3); + if(mtp3_para->ls_pro[linkset].ls_opc==0) + memcpy(&sd_tmp_buf[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&sd_tmp_buf[8],&mtp3_para->ls_pro[linkset].ls_opc,3); + sd_tmp_buf[11] = 0; + sd_tmp_buf[12] = SIGNAL_TRA; + } + else + { + if(mtp3_para->ls_pro[linkset].ls_opc==0) + route_mark = (mtp3_para->nw[nw].opc14 << 14) + mtp3_para->ls_pro[linkset].ls_op_pc; + else + route_mark = (mtp3_para->ls_pro[linkset].ls_opc << 14) + mtp3_para->ls_pro[linkset].ls_op_pc; + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 6; + sd_tmp_buf[4] = nw << 6; + memcpy(&sd_tmp_buf[5],&route_mark,4); + sd_tmp_buf[9] = SIGNAL_TRA; + } + sd_tmp_buf[1] = outlink>>8; + sd_tmp_buf[0] = outlink&0xff; + send_mtp_msg(outlink,sd_tmp_buf); + mtp3.nw[nw].flow.MtoI[0]++; +} + +void sd_STM_msg(WORD chl, BYTE MsgType) +{ + ls_info *ls; + BYTE nw; + long route_mark; + BYTE H1; + BYTE H0; + BYTE supplymsg; + WORD ls_no; + int outlink=-1; + BYTE *sd_tmp_buf; + + ls_no = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[ls_no]; + nw = mtp3_para->ls_pro[ls_no].nw_id; + + sd_tmp_buf = &mtp3_iprt.io_msg.msgContent[0]; + if ( pc_length(nw) == MTP3_24BIT_PC ) + { + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 9; + sd_tmp_buf[4] = nw << 6; + memcpy(&sd_tmp_buf[5],&mtp3_para->ls_pro[ls_no].ls_op_pc,3); +// memcpy(&sd_tmp_buf[7],&mtp3_para->nw[nw].opc24,3); + if(mtp3_para->ls_pro[ls_no].ls_opc==0) + memcpy(&sd_tmp_buf[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&sd_tmp_buf[8],&mtp3_para->ls_pro[ls_no].ls_opc,3); + sd_tmp_buf[11] = mtp3_para->lk[chl].e1_to_slc; + sd_tmp_buf[12] = MsgType; + supplymsg = 11+1+1; + } + else + { + if(mtp3_para->ls_pro[ls_no].ls_opc==0) + route_mark = (mtp3_para->lk[chl].e1_to_slc << 28) + (mtp3_para->nw[nw].opc14 << 14) + mtp3_para->ls_pro[ls_no].ls_op_pc; + else + route_mark = (mtp3_para->lk[chl].e1_to_slc << 28) + (mtp3_para->ls_pro[ls_no].ls_opc << 14) + mtp3_para->ls_pro[ls_no].ls_op_pc; + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 6; + sd_tmp_buf[4] = nw << 6; + memcpy(&sd_tmp_buf[5],&route_mark,4); + sd_tmp_buf[9] = MsgType; + supplymsg = 8+1+1; + } + + H0 = MsgType & 0x0F; + H1 = MsgType >> 4; + + switch (H0) + { + case 1: + switch (H1) + { + case 1:/* COO */ + sd_tmp_buf[3] = sd_tmp_buf[3] + 1; + sd_tmp_buf[supplymsg] = retrieved_bsnt[chl]; + mtp3_debug(MTP3DB_EVENT,"Link %d SEND COO,SUP MSG=%d",chl,sd_tmp_buf[supplymsg]); + mtp3_debug(MTP3DB_EVENT,"Link %d SEND COO,BSNT=%d",chl,retrieved_bsnt[chl]); + outlink = search_outbound_coLink(chl); + break; + case 2:/* COA */ + sd_tmp_buf[3] = sd_tmp_buf[3] + 1; + sd_tmp_buf[supplymsg] = retrieved_bsnt[chl]; + mtp3_debug(MTP3DB_EVENT,"Link %d SEND COA,SUP MSG=%d",chl,sd_tmp_buf[supplymsg]); + mtp3_debug(MTP3DB_EVENT,"Link %d SEND COA,BSNT=%d",chl,retrieved_bsnt[chl]); + outlink = search_outbound_coLink(chl); + break; + case 5:/* CBD */ + sd_tmp_buf[3] = sd_tmp_buf[3] + 1; + sd_tmp_buf[supplymsg] = cbc_s[chl]; + outlink = search_outbound_coLink(chl); + break; + case 6:/* CBA */ + sd_tmp_buf[3] = sd_tmp_buf[3] + 1; + sd_tmp_buf[supplymsg] = cbd_cbc_r[chl]; + outlink = search_outbound_coLink(chl); + break; + default: + break; + } + break; + case 2: + switch (H1) + { + case 1:/* ECO */ + outlink = search_outbound_coLink(chl); + break; + case 2:/* ECA */ + outlink = search_outbound_coLink(chl); + break; + default: + break; + } + break; + case 6: + switch (H1) + { + case 1:// LIN + if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + outlink = chl; + else + outlink = search_outbound_coLink(chl); + break; + case 2:// LUN + if ((link_inhibited[chl] == TRUE) && (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING)) + { + outlink=chl; + } + else + outlink = search_outbound_coLink(chl); +/* if (outlink == -1) + outlink = chl;*/ + break; + case 3:// LIA + if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + outlink = chl; + else + outlink = search_outbound_coLink(chl); + break; + case 4:// LUA + if ((link_inhibited[chl] == TRUE) && (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING)) + { + outlink=chl; + } + else if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + outlink = chl; + else + outlink = search_outbound_coLink(chl); +/* if (outlink == -1) + outlink = chl;*/ + break; + case 5:// LID + if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + outlink = chl; + else + outlink = search_outbound_coLink(chl); + break; + case 6:// LFU + if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + outlink = chl; + else if ((link_inhibited[chl] == TRUE) && (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING)) + outlink=chl; + else + outlink = search_outbound_coLink(chl); +/* if (outlink == -1) + outlink = chl;*/ + break; + case 7:// LLT + if ((link_inhibited[chl] == TRUE) && (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING)) + { + outlink=chl; + } + else if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + outlink = chl; + else + outlink = search_outbound_coLink(chl); + break; + case 8:// LRT + if ((link_inhibited[chl] == TRUE) && (mtp3ObjState.link_l2_state[chl] == MTP2_STATE_WORKING)) + { + outlink=chl; + } + else if (mtp3ObjState.link_l3_state[chl] == AVAILABLE) + outlink = chl; + else + outlink = search_outbound_coLink(chl); + break; + default: + break; + } + break; + default: + break; + } + if (outlink != -1) + { + sd_tmp_buf[0] = outlink; + send_mtp_msg(outlink,sd_tmp_buf); + } +} + +void hmrt_xxxx_adjacent_sp_restart(ls_info *ls) +{ + if ( own_sp_restarting ) + { + ls->adjacentsp_restarting = 1; + hmrt_xxxx_adjacent_sp_restart(ls); + } +} + +void hmrt_hmdc_message_for_routing(ls_info *ls) +{ +// ls_prim_t *p = (ls_prim_t *)mp->b_rptr; +// chl = &ls->device[p->sig.mh.rl.sls]; + /* + * This function is called only by the MTP state machines (HMCG) to route + * a message once the link set has been selected. + */ +// hmcg_hmrt_message(ls, mp); +} + +void hmrt_tfrc_update_routing_tables(WORD dst, BYTE nw) +{ + network *sp; + BYTE routine; + + sp = &mtp3.nw[nw]; + routine = sp->routine[dst]; + + if (Nlinkset_status(routine) == LS_AVAILABLE) +// if ( Nls_state == 0 ) + sp->routine[dst] = sp->routine[dst] & 0x3f;/* current route is normal route */ + else if (Alinkset_status(routine) == LS_AVAILABLE) +// else if ( Als_state == 0 ) + sp->routine[dst] = ( sp->routine[dst] & 0x3f ) + 0x40;/* current route is Alternative route */ + else + sp->routine[dst] = ( sp->routine[dst] & 0x3f ) + 0x80;/* no route */ +} + +void hmrt_sltc_signalling_link_test_msg(WORD chl) +{ + WORD linkset; + ls_info *ls; + WORD sp_place; + BYTE nw; + long route_mark; + BYTE *sd_tmp_buf; + BYTE slc; + + linkset = mtp3_para->lk[chl].e1_to_linkset; + if (linkset >= MAX_LS) + { + mtp3_debug(MTP3DB_EVENT,"Warning!! link %d doesn't asign a linkset,stop test procedure",chl); + return; + } + nw = mtp3_para->ls_pro[linkset].nw_id; + ls = &mtp3.ls[linkset]; + sp_place = ls->adjacent_sp_place; + if (sp_place >= MAX_ROUTE) + { + mtp3_debug(MTP3DB_EVENT,"Warning!! linkset %d remote SPC doesn't config in the routine table,stop test procedure",linkset); + return; + } + slc = mtp3_para->lk[chl].e1_to_slc; + + sd_tmp_buf = &mtp3_iprt.io_msg.msgContent[0]; + if (pc_length(nw) == MTP3_24BIT_PC) + { + sd_tmp_buf[1] = chl>>8; + sd_tmp_buf[0] = chl &0xff; + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 12; + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + sd_tmp_buf[4] = (nw << 6) + 2; + else + sd_tmp_buf[4] = (nw << 6) + 1; + memcpy(&sd_tmp_buf[5],&mtp3_para->ls_pro[linkset].ls_op_pc,3); + //memcpy(&sd_tmp_buf[7],&mtp3_para->nw[nw].opc24,3); + if(mtp3_para->ls_pro[linkset].ls_opc==0) + memcpy(&sd_tmp_buf[8],&mtp3_para->nw[nw].opc24,3); + else + memcpy(&sd_tmp_buf[8],&mtp3_para->ls_pro[linkset].ls_opc,3); + sd_tmp_buf[11] = slc; + sd_tmp_buf[12] = SIGNAL_SLTM; + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + sd_tmp_buf[13] = 0x20+slc; + else + sd_tmp_buf[13] = 0x20; + sd_tmp_buf[14] = chl;//??? + sd_tmp_buf[15] = slc; + } + else + { + if(mtp3_para->ls_pro[linkset].ls_opc==0) + route_mark = (slc << 28) + (mtp3_para->nw[nw].opc14 << 14) + (mtp3_para->ls_pro[linkset].ls_op_pc); + else + route_mark = (slc << 28) + (mtp3_para->ls_pro[linkset].ls_opc << 14) + (mtp3_para->ls_pro[linkset].ls_op_pc); + sd_tmp_buf[1] = chl>>8; + sd_tmp_buf[0] = chl&0xFF; + sd_tmp_buf[2] = 0; + sd_tmp_buf[3] = 9; + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + sd_tmp_buf[4] = (nw << 6) + 2; + else + sd_tmp_buf[4] = (nw << 6) + 1; + memcpy(&sd_tmp_buf[5],&route_mark,4); + sd_tmp_buf[9] = SIGNAL_SLTM; + if (mtp3ObjState.lk_SpecANSI_flag[chl] == 1) + sd_tmp_buf[10] = 0x20+slc; + else + sd_tmp_buf[10] = 0x20; + sd_tmp_buf[11] = chl;//??? + sd_tmp_buf[12] = slc; + } + + send_mtp_msg(chl,sd_tmp_buf); +} + +void hmrt_tcbc_changeback_ack(WORD chl) +{ + sd_STM_msg(chl,SIGNAL_CBA); +} + +void hmrt_tcbc_changeback_declaration(WORD chl) +{ + +/* for ( i=0; i> 2) & 3) == 0 ) + return LS_AVAILABLE; + else + return LS_UNAVAILABLE; +} + +int scan_ls_link_available(WORD ls_no) +{ + int chl,lk_available; + + lk_available = 0; + for(chl=0; chl < MAX_LK; chl++) + { + if(mtp3ObjState.link_l3_state[chl] == AVAILABLE && mtp3_para->lk[chl].e1_to_linkset == ls_no) + lk_available++; + } + return lk_available; +} +void hmrt_tcbc_update_routing_tables(WORD chl) +{ + BYTE i,j; + ls_info *ls; + network *sp; + ulong nw; + unsigned int lsno; + WORD lsx16; + ulong spplace; + WORD link_num; + unsigned int sls; + BYTE *routine; + BYTE link_already_available; + + lsno = mtp3_para->lk[chl].e1_to_linkset; + if (lsno >= MAX_LS) + return; + ls = &mtp3.ls[lsno]; + lsx16 = lsno << 4; + nw = mtp3_para->ls_pro[lsno].nw_id; + link_num = ls->linksNum_configured; +// link_num = linknum_in_ls[lsno]; + if (link_num == 0) + { + mtp3_debug(MTP3DB_EVENT,"linkset %d havn't config active link",lsno); +// mtp_send_error("Linkset",lsno,"LINKSET HAVN'T CONFIG ACTIVE LINK"); + return; + } + + link_already_available = mtp3ObjState.link_l3_state[chl]; + ls->links_available_t = scan_ls_link_available(lsno); + + mtp3ObjState.link_l3_state[chl] = AVAILABLE; + set_heartbeat(ALARM_LINK_AVAILABLE,chl); + + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + mtp3_send_alarm(MTP3_LINK_COMPONENT+chl,0);//clear alarm + + if ( ls->links_available_t > 0 )/* WITHIN LS */ + { + for ( j=0; j<16; j++ ) + { + sls = lsx16+j; + if ( (ls_sls[sls] != chl) && + (sls_to_link[sls] == chl) ) + ls_sls[sls] = chl; + } + } + else + { + current_active_ls_num++; + current_measure->ls_measure[lsno][2]++;/* STOP of link set failure */ + sp = &mtp3.nw[nw]; + //memset(&ls_sls[lsx16],chl,16); + for(i=0; i<16; i++) + ls_sls[lsx16+i] = chl; + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + routine = (BYTE*)&sp->routine[spplace]; + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"\33[32m%s:%d : Link %d Linkset %d , routine: =%02x\33[0m",__FUNCTION__, __LINE__, chl, lsno, + *routine); + + mark_normal_linkset_available(routine); //117-11-07 + + if (Nlinkset_status(*routine) == LS_AVAILABLE) + { + *routine = ((*routine) & 0x3f);/* current route is normal linkset */ + if(1) + if(ls->links_nls_asp_ac_send_flag[spplace] == 0) + { + ls->links_nls_asp_ac_send_flag[spplace] = 1; + ls->send_asp_ac_link_id = chl; + } + } + else if (Alinkset_status(*routine) == LS_AVAILABLE) + { + (*routine) = ((*routine) & 0x3f) + 0x40; + if(1) + if(ls->links_als_asp_ac_send_flag[spplace] == 0) + { + ls->links_als_asp_ac_send_flag[spplace] = 1; + ls->send_asp_ac_link_id = chl; + } + } + else + { + //mark_normal_linkset_available(routine); + + (*routine) = ((*routine) & 0x3f) + 0x80; + + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,AVAILABLE); + } + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"\33[32m%s:%d : Link %d Linkset %d , routine: =%02x\33[0m",__FUNCTION__, __LINE__, chl, lsno, + *routine); + + } + + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asALS[i]; + routine = (BYTE*)&sp->routine[spplace]; + + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"\33[32m%s:%d : Link %d Linkset %d , ssplace=%d, routine: =%02x\33[0m",__FUNCTION__, __LINE__, chl, lsno, + spplace, *routine); + + mark_alternative_linkset_available(routine); //17-11-07 + + if ( (*routine) >> 6 == 2 )/* no route */ + { + (*routine) = ((*routine) & 0x3f) + 0x40;/* current route is alternative linkset */ + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,AVAILABLE); + } + + if (Nlinkset_status(*routine) == LS_AVAILABLE) + (*routine) = ((*routine) & 0x3f);/* current route is normal linkset */ + else if (Alinkset_status(*routine) == LS_AVAILABLE) + (*routine) = ((*routine) & 0x3f) + 0x40; + else + (*routine) = ((*routine) & 0x3f) + 0x80; + + if(1) + if(ls->links_als_asp_ac_send_flag[spplace] == 0) + { + ls->links_als_asp_ac_send_flag[spplace] = 1; + ls->send_asp_ac_link_id = chl; + } + + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"\33[32m%s:%d : Link %d Linkset %d , routine: =%02x\33[0m",__FUNCTION__, __LINE__, chl, lsno, + *routine); + + } + //if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) for dual alarm issue + mtp3_send_alarm(lsno+MTP3_LINKSET_COMPONENT,0); + set_heartbeat(ALARM_LS_AVAILABLE,lsno); + mtp3_para->ls_pro[lsno].ls_state = 1;//ALARM_LS_AVAILABLE; + } + + ls->links_available_t = scan_ls_link_available(lsno); + + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + mtp3_send_alarm(MTP3_LINK_COMPONENT+chl,0); + else + { + if(ls->links_available_t >= 1) + { + if(ls->send_asp_ac_link_id == 0 || ls->send_asp_ac_link_id == 0xffff) + ls->send_asp_ac_link_id = chl; + } + } + + if ( ls->links_available_t > 0 ) + { + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"\33[32m%s: Link %d L3 in service,links_available_t=%d\33[0m",__FUNCTION__, chl, ls->links_available_t); + } + else + { + if(detail_debug_flag) + mtp3_debug(MTP3DB_EVENT,"\33[32m%s: Link %d L3 in service,Linkset %d in service\33[0m",__FUNCTION__, chl,lsno); + } + + /* + if(link_already_available != AVAILABLE) + ls->links_available_t++; + else + mtp3_debug(MTP3DB_ERROR,"update routing table fail, links=%d have already available", chl); + */ + + current_measure->lk_measure1[chl][1]++;/* local changeback */ + +// printf("\r\n tcbc %d update routine cmp link_available = %d \n\r",chl, ls->links_available_t); +} + +void sp_unaccessable(BYTE *routine) +{ + (*routine) = ((*routine) & 0x3f) + 0x80; +} + +void hmrt_tcoc_update_routing_tables(WORD chl) +{ + BYTE i,j; + ls_info *ls; + network *sp; + ulong nw; + int lsno; + int lsx16; + BYTE select_slc; + WORD slc[16]; + ulong spplace; + int link; + BYTE lk_available; + + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno]; + lsx16 = lsno << 4; + + ls->links_available_t = scan_ls_link_available(lsno); + lk_available = mtp3ObjState.link_l3_state[chl]; + nw = mtp3_para->ls_pro[lsno].nw_id; + if (link_inhibited[chl] == TRUE) + mtp3ObjState.link_l3_state[chl] = INHIBITED; + else + { + mtp3ObjState.link_l3_state[chl] = UNAVAILABLE; + mtp3ObjState.link_enable_sent_flag[chl] = 0; + + } + + set_heartbeat(ALARM_LINK_UNAVAILABLE,chl); + + if (ls->links_available_t > 0 && lk_available == AVAILABLE) + ls->links_available_t--; + else + mtp3_debug(MTP3DB_ERROR,"hmrt_tcoc_update routing table fail, links=%d have already unavailable", chl); + + if ( ls->links_available_t > 0 )/* within ls */ + { + j = 0; + for ( i=0; i<16; i++ ) + { + link = ls_slc[lsx16+i]; + if ( (link != chl) && (mtp3ObjState.link_l3_state[link] == AVAILABLE) ) + { + slc[j] = link; + j++; + } + } + + for ( j=0; j<16; j++ ) + { + if (ls_sls[lsx16+j] == chl) + { + if (ls->links_available_t == 0) + { + mtp3_debug(MTP3DB_ERROR,"LINKSET %d ERROR,LINKS AVAILABLE = 0\n\r",lsno); + return; + } + select_slc = (j % ls->links_available_t); + ls_sls[lsx16+j] = slc[select_slc]; + } + } +/* if (mtp3_para->lk[chl].e1_to_mtp3 == mtp3_localip) + mtp3_send_alarm(0,0);*/ + } + else/* changeover between link set */ + { + current_measure->ls_measure[lsno][1]++;/* Start of link set failure */ + sp = &mtp3.nw[nw]; + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asNLS[i]; + if ( ((sp->routine[spplace] >> 2) & 3) == 0 )/*alternative route available */ + sp->routine[spplace] = (sp->routine[spplace] & 0x3f) + 0x40;/* current route change from normal linkset to alternative linkset */ + else/* sp not accessible */ + { + sp_unaccessable(&sp->routine[spplace]); + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,UNAVAILABLE); + sp->m3ua_rc_status[spplace] = 0; + } + if(detail_debug_flag) + mtp3_debug(MTP3DB_ERROR,"%s:%d, Link=%d, changeover DPC=%d, rc_status=%d", __FUNCTION__, __LINE__, + chl, mtp3_para->nw[nw].routing[spplace].dpc, sp->m3ua_rc_status[spplace]); + + } + + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + spplace = ls->influ_dstplace_intable_asALS[i]; + if ( (sp->routine[spplace] & 3) != 0 )/* normal route unavailable */ + { + sp_unaccessable(&sp->routine[spplace]); + primitive_to_userpart(nw,mtp3_para->nw[nw].routing[spplace].dpc,UNAVAILABLE); + sp->m3ua_rc_status[spplace] = 0; + } + if(detail_debug_flag) + mtp3_debug(MTP3DB_ERROR,"%s:%d, Link=%d, changeover DPC=%d, rc_status=%d", __FUNCTION__, __LINE__, + chl, mtp3_para->nw[nw].routing[spplace].dpc, sp->m3ua_rc_status[spplace]); + + } + + //memset(&ls_sls[lsx16],MAX_LK,16); + for(i=0; i<16; i++) + ls_sls[lsx16+i] = MAX_LK_INDEX; + + set_heartbeat(ALARM_LS_UNAVAILABLE,lsno); + mtp3_para->ls_pro[lsno].ls_state = 0;//ALARM_LS_UNAVAILABLE; + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + mtp3_send_alarm(lsno+MTP3_LINKSET_COMPONENT,1); + } + + ls->links_available_t = scan_ls_link_available(lsno); + + current_measure->lk_measure1[chl][0]++;/* local changeover */ + if ( ls->links_available_t > 0 )/* within ls */ + { + mtp3_debug(MTP3DB_EVENT,"\33[31m%s : Link %d L3 out of service, links_available_t=%d, asp_ac_link=%d\33[0m", + __FUNCTION__, chl, ls->links_available_t, ls->send_asp_ac_link_id); + rc_timer = 195+(mtp2_systemid%2)*5; + } + else + mtp3_debug(MTP3DB_EVENT,"\33[31m%s : Link %d L3 out of service,Linkset %d out of service\33[0m", + __FUNCTION__, chl, lsno); +// printf("/r/ntcoc %d update routine cmp link_available = %d \n",chl, ls->links_available_t); +} + +void send_ip_to_mtp2()/* send message to mtp2, tell mtp2 which is it's host mtp3 */ + /* this message send every 16 second */ +{ + static int mtp2_subsys = 0; + int i,j; + int basePort; + BYTE *msgContent; + BYTE e1_to_mtp3; + + basePort = mtp2_subsys*8; + for (i=0;i<8;i++) + { + if ((mtp3ObjState.lk_mtp3[basePort+i] == mtp3_localip) && + (mtp3ObjState.lk_configured[basePort+i] == PARA_CONFIGURED) && (mtp3_para->lk[basePort+i].e1_lk_type == LKTYPE_NONE_SIGTRAN)) + { + mtp3_iprt.io_msg.msgLength = 14+1+1; + mtp3_iprt.io_msg.msgContent[0] = 0; + mtp3_iprt.io_msg.msgContent[1] = 0; + mtp3_iprt.io_msg.msgContent[2] = 0; + mtp3_iprt.io_msg.msgContent[3] = 12; + mtp3_iprt.io_msg.msgContent[4] = 0xff; + mtp3_iprt.io_msg.msgContent[5] = 0xee; + mtp3_iprt.io_msg.msgContent[6] = 0xff; + msgContent = &mtp3_iprt.io_msg.msgContent[7]; + for (j=0;j<8;j++) + { + + e1_to_mtp3 = mtp3ObjState.lk_mtp3[basePort+j]; + if ((e1_to_mtp3 != mtp3_localip) || + (mtp3ObjState.lk_configured[basePort+j] != PARA_CONFIGURED) ) + msgContent[j] = 0xee; + else + msgContent[j] = ((e1_to_mtp3 >> 16) & 0xff)-32;// 172.18.x+32.1 + } + mtp3_para->nw_pro = mtp3_para->nw[0].pc_len+mtp3_para->nw[1].pc_len*2+mtp3_para->nw[2].pc_len*4+mtp3_para->nw[0].pc_len*8; + mtp3_para->nw_pro = mtp3_para->nw_pro + mtp3_para->nw[0].pc_type*16+mtp3_para->nw[1].pc_type*32+mtp3_para->nw[2].pc_type*64+mtp3_para->nw[0].pc_type*128; + msgContent[8] = mtp3_para->nw_pro; + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"MTP3 send IP to MTP2 %d",mtp2_subsys); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,&mtp3_iprt.io_msg.msgContent[0],14+2); + send_to_mtp2(LINK_TO_IP(basePort)); + break; + } + } + mtp2_subsys = (mtp2_subsys+1) & 0x1f; +} + +void send_command_to_mtp2(WORD chl, BYTE command) +{ + char charCmd[32]; + + mtp3_iprt.io_msg.msgLength = 5+1+1; + mtp3_iprt.io_msg.msgContent[1] = chl>>8; + mtp3_iprt.io_msg.msgContent[0] = chl&0xFF; + mtp3_iprt.io_msg.msgContent[2] = 0; + mtp3_iprt.io_msg.msgContent[3] = 3; + mtp3_iprt.io_msg.msgContent[4] = 0xff; + mtp3_iprt.io_msg.msgContent[5] = ((mtp3ObjState.lk_mtp3[chl] >> 16) & 0xff)-32;// 172.18.x+32.1 + mtp3_iprt.io_msg.msgContent[6] = command; + + switch (command) + { + case MTP2_ACTIVE_LINK: + command3[chl] = MTP2_ACTIVE_LINK; + sprintf(charCmd,"MTP2_ACTIVE_LINK"); + break; + case MTP2_DEACTIVE_LINK: + command3[chl] = MTP2_DEACTIVE_LINK; + sprintf(charCmd,"MTP2_DEACTIVE_LINK"); + break; + case MTP2_STOP_L2: + if (link_inhibited[chl] != TRUE) + { + command3[chl] = MTP2_STOP_L2; + } + else + return; + sprintf(charCmd,"MTP2_STOP_L2"); + break; + case MTP2_EMERGEN_ALIGNMENT: + command3[chl] = MTP2_EMERGEN_ALIGNMENT; + sprintf(charCmd,"MTP2_EMERGEN_ALIGNMENT"); + break; + case MTP2_RETRIEVE:/* not support */ +/* command3[chl] = MTP2_RETRIEVE; + iprt.io_msg.msgLength = 5; + iprt.io_msg.msgContent[1] = 3; + iprt.io_msg.msgContent[4] = fsnc[chl]; + break;*/ + return; + case MTP3_M2UA_ENABLE: + sprintf(charCmd,"ENABLE M2UA LINK"); + break; + default: + break; + } + if (MTP3_LINK_TYPE(chl) == LKTYPE_NONE_SIGTRAN ||MTP3_LINK_TYPE(chl) == LKTYPE_SIGTRAN) + { + mtp3_debug(MTP3DB_PRIMITIVE_MSG,"MTP3 send command %s to link %d",charCmd,chl); + mtp3_showbuf(MTP3DB_PRIMITIVE_MSG,&mtp3_iprt.io_msg.msgContent[0],5+1+1); + } + if (MTP3_LINK_TYPE(chl) == LKTYPE_NONE_SIGTRAN) + send_to_mtp2(LINK_TO_IP(chl)); +#if _INCLUDE_M2UA + else if (MTP3_LINK_TYPE(chl) == LKTYPE_SIGTRAN) + put_m2ua_msg((m2ua_up_msg_t *) mtp3_iprt.io_msg.msgContent); +#endif +} + +int set_m3ua_detail_debug_flag(int flag) +{ + detail_debug_flag = flag; + return 1; +} +/*@end@*/ diff --git a/plat/mtp3/src/mtpsrm.c b/plat/mtp3/src/mtpsrm.c new file mode 100644 index 0000000..74c98f8 --- /dev/null +++ b/plat/mtp3/src/mtpsrm.c @@ -0,0 +1,336 @@ +#include "./include/mtp3.h" +#include "./include/mtpstm.h" +#include "./include/mtpext.h" +#include "./include/mtpfunc.h" + +/*@ignore@*/ +void hmrt_srm_msg(WORD linkset, BYTE MsgType, long dst); +void hmrt_tfrc_update_routing_tables(WORD dst, BYTE nw); +void tsrc_fun6(WORD link,BYTE nw,WORD sp_place); +void tsrc_fun8(WORD ls,BYTE nw,WORD sp_place); +int find_dst_place(long dst,WORD ls); + +void mark_alternative_linkset_available(BYTE *routine) +{ + (*routine) = ( (*routine) & 0xc3 ) + 0x10;/* mark alternative route use and acessible*/ +} + +void mark_alternative_linkset_unavailable(BYTE *routine) +{ + (*routine) = ((*routine) & 0xf3 ) + 0x08;/* mark alternative route can't use */ +} + +void mark_normal_linkset_available(BYTE *routine) +{ + (*routine) = ((*routine) & 0xcc) + 0x10;/* mark normal route can use,and acessible */ +} + +void mark_normal_linkset_unavailable(BYTE *routine) +{ + (*routine) = ((*routine) & 0xfc) + 0x02;/* mark normal route unavailable */ +} + +void mark_dstSP_inaccessible(BYTE *routine) +{ + (*routine) = ((*routine) & 0xcf);/* mark destination sp inaccessible */ +} + +int find_directLS_to_dst(long dst) +{ + int i; + + for ( i=0; ils_pro[i].ls_op_pc == dst ) + return i; + } + return MAX_LS; +} + +void tsrc_rtpc_signalling_route_unavailable(WORD dst, BYTE nw) +{ + WORD ls; + network *sp; + BYTE msgopc; + WORD nls; + WORD als; + + nls = mtp3_para->nw[nw].routing[dst].normal_ls; + als = mtp3_para->nw[nw].routing[dst].alternative_ls; + sp = &mtp3.nw[nw]; + msgopc = TFPmsg_OPC; + ls = mtp3_para->lk[TFPmsg_SrcLk].e1_to_linkset; + + if ( ls >= MAX_LS )//??? + return; + if ( mtp3.ls[ls].adjacentsp_restarting == 1 )/* adjacent sp restarting */ + { + if (nls == ls) + mark_normal_linkset_unavailable(&sp->routine[dst]); + else if (als == ls) + mark_alternative_linkset_unavailable(&sp->routine[dst]); + } + else + { + if ( nls == ls ) + { + if ( (sp->routine[dst] >> 6) == 2 ) + return; + tsrc_fun6(TFPmsg_SrcLk,nw,dst); + hmrt_tfrc_update_routing_tables(dst,nw); + } + else if ( als == ls ) + { + tsrc_fun6(TFPmsg_SrcLk,nw,dst); + hmrt_tfrc_update_routing_tables(dst,nw); + } + } +} + +void tsrc_rtac_signalling_route_available(WORD dst, BYTE nw) +{ + int ls; + network *sp; + ulong msgopc; + WORD nls_t; + WORD als_t; + BYTE current_route; + WORD msgopc_place; + int lsnoRSP_is_msgOPC; + + sp = &mtp3.nw[nw]; + current_route = sp->routine[dst] >> 6; + msgopc = TFAmsg_OPC; + ls = mtp3_para->lk[TFAmsg_SrcLk].e1_to_linkset; + if ( ls >= MAX_LS ) + return; + lsnoRSP_is_msgOPC = find_directLS_to_dst(msgopc); + if ( lsnoRSP_is_msgOPC == MAX_LS ) + return;/* msg opc is not any linkset's remote sp */ + msgopc_place = mtp3.ls[lsnoRSP_is_msgOPC].adjacent_sp_place; + if (msgopc_place > MAX_ROUTE) + return; + + if ( !own_sp_restarting ) + { + if ( ((sp->routine[msgopc_place] >> 4) & 3) == SP_ACCESSIBLE )/* msg opc accessible */ + tsrc_fun8(ls,nw,dst); + + else/* msg opc inacessible */ + { +// mtp3_debug(MTP3_DEBUG_LOG,"msgopc inacessible\n\r"); + sp->rtac_input[msgopc_place] = RTAC_DEST_ACCESSIBLE;/* send tfa to all adjacent sp */ + + nls_t = mtp3_para->nw[nw].routing[msgopc_place].normal_ls; + als_t = mtp3_para->nw[nw].routing[msgopc_place].alternative_ls; + mtp3ObjInput.taprc_input[lsnoRSP_is_msgOPC] = TPRC_ADJACENT_SP_RESTARTING; + + if ( nls_t == ls ) + mark_normal_linkset_available(&sp->routine[msgopc_place]); + else if ( als_t == ls ) + mark_alternative_linkset_available(&sp->routine[msgopc_place]); + current_measure->ls_measure[ls][4]++;/* Broadcast TFA for recovery of measured linkset */ + } + } + hmrt_tfrc_update_routing_tables(msgopc_place,nw); + hmrt_tfrc_update_routing_tables(dst,nw); +} + +void rtpc_proc(BYTE netw,WORD dst) +{ + network *nw; + WORD ls; + + nw = &mtp3.nw[netw]; + switch ( nw->rtpc_state[dst] ) + { + case RTPC_IDLE_STATE: + switch ( nw->rtpc_input[dst] ) + { + case RTPC_RSRT_SEND_TFP_MSG:/* not supported */ + nw->rtpc_input[dst] = IDLE; + hmrt_srm_msg(sdTFP_Ls,SIGNAL_TFP,mtp3_para->nw[netw].routing[dst].dpc); + nw->rtpc_state[dst] = RTPC_WAIT_STATE; + break; + + case RTPC_TSRC_SEND_TFP_MSG:/* send tfp message to linkset opposit sp */ +// printf("send tfp message to linkset %d,TFDPC=%lx\n",sdTFP_Ls,mtp3_para->nw[netw].dpc[dst]); + nw->rtpc_input[dst] = IDLE; + hmrt_srm_msg(sdTFP_Ls,SIGNAL_TFP,mtp3_para->nw[netw].routing[dst].dpc); + nw->rtpc_state[dst] = RTPC_WAIT_STATE; + break; + + case RTPC_DEST_INACCESSIBLE:/*one dst inaccessible, send tfp to all adjacent sp about this dst */ + nw->rtpc_input[dst] = IDLE; + for ( ls=0; lsls_pro[ls].nw_id) == netw) + { +// printf("send tfp message to linkset %d,TFDPC=%lx\n",ls,mtp3_para->nw[netw].dpc[dst]); + hmrt_srm_msg(ls,SIGNAL_TFP,mtp3_para->nw[netw].routing[dst].dpc);/* send tfp to adjacent sp */ + } + } + if (own_sp_restarting == 1) + { +// hmrt_tra_msg(ls);//printf("send tra\n"); + mtp3ObjInput.tprc_input = TPRC_RTPC_TFP_SENT; + } + break; + + case RTPC_TFP_MSG:/* receive TFP from other sp */ +// printf("rtpc dst %d tfp\n",dst); + nw->rtpc_input[dst] = IDLE; + if ( controlled_rerouting_in_progress[dst] == TRUE ) + transfer_prohibited[dst] = TRUE; + else + { + tsrc_rtpc_signalling_route_unavailable(dst,netw); + if (!own_sp_restarting) + { + nw->rsrt_input[dst] = RSRT_RTPC_ROUTE_SET_TEST; + } + //if sp isn't restarting + //start route set test + } + break; + + case RTPC_CTRL_RERT_TERMINATED:/* not supported */ + nw->rtpc_input[dst] = IDLE; + controlled_rerouting_in_progress[dst] = FALSE; + if ( transfer_prohibited[dst] == TRUE ) + { + transfer_prohibited[dst] = FALSE; + //tsrc_rtpc_signalling_route_unavailable + //if sp isn't restarting + //start route set test + } + break; + + case RTPC_CONTROLLED_RERT:/* not supported */ + nw->rtpc_input[dst] = IDLE; + controlled_rerouting_in_progress[dst] = TRUE; + break; + + case RTPC_RESTART_BEGINS: + nw->rtpc_input[dst] = IDLE; + controlled_rerouting_in_progress[dst] = FALSE; + transfer_prohibited[dst] = FALSE; + /* mark sp restarting */ + break; + + case RTPC_RESTART_ENDS: + nw->rtpc_input[dst] = IDLE; + /* cancel sp restarting */ + break; + } + break; + + case RTPC_WAIT_STATE: + nw->rtpc_state[dst] = RTPC_IDLE_STATE; + break; + } +} + +void rtac_proc(BYTE netw,WORD dst) +{ + network *nw; + WORD ls; + + nw = &mtp3.nw[netw]; + switch ( nw->rtac_input[dst] ) + { + case RTAC_TFA_MSG: + nw->rtac_input[dst] = IDLE; + tsrc_rtac_signalling_route_available(dst,netw); + nw->rsrt_input[dst] = RSRT_RTAC_ROUTE_AVAILABLE; + break; + + case RTAC_DEST_ACCESSIBLE:// one dst become accessible, send tfa to all adjacent sp about this dst + nw->rtac_input[dst] = IDLE; + for ( ls=0; lsls_pro[ls].nw_id == netw) + { + hmrt_srm_msg(ls,SIGNAL_TFA,mtp3_para->nw[netw].routing[dst].dpc);/* send tfa to adjacent sp */ + } + } + break; + + case RTAC_STP_NOLONGER_FOR_DEST: + nw->rtac_input[dst] = IDLE; + hmrt_srm_msg(sdTFA_Ls,SIGNAL_TFA,mtp3_para->nw[netw].routing[dst].dpc); + break; + + case RTAC_SEND_TFA_MSG: + nw->rtac_input[dst] = IDLE; + hmrt_srm_msg(sdTFA_Ls,SIGNAL_TFA,mtp3_para->nw[netw].routing[dst].dpc); + break; + + case RTAC_FORCED_RERT: + break; + + case RTAC_FORCED_RERT_TERMINATED: + break; + + case RTAC_FORCED_RERT_NOT_REQ: + break; + + case RTAC_RESTART_BEGINS: + break; + + case RTAC_RESTART_ENDS: + break; + } +} + +void rsrt_proc(BYTE netw,WORD dst) +{ + network *nw; + + nw = &mtp3.nw[netw]; + switch (nw->rsrt_state[dst]) + { + case RSRT_IDLE_STATE: + switch (nw->rsrt_input[dst]) + { + case RSRT_RTPC_ROUTE_SET_TEST: + nw->rsrt_t10[dst] = 0; + nw->rsrt_state[dst] = RSRT_WAIT_STATE; + break; + case RSRT_TSRC_ROUTE_SET_TEST: + hmrt_srm_msg(mtp3_para->nw[netw].routing[dst].normal_ls,SIGNAL_RST,mtp3_para->nw[netw].routing[dst].dpc); + break; + default: + break; + } + break; + case RSRT_WAIT_STATE: + nw->rsrt_t10[dst] ++; + switch (nw->rsrt_input[dst]) + { + case RSRT_RTPC_ROUTE_SET_TEST: + break; + case RSRT_TSRC_ROUTE_SET_TEST: + break; + case RSRT_RTAC_ROUTE_AVAILABLE: + nw->rsrt_t10[dst] = 0; + nw->rsrt_state[dst] = RSRT_IDLE_STATE; + break; + default: + break; + } + if (nw->rsrt_t10[dst] >= mtp3_para->mtp3_t10) + { + hmrt_srm_msg(mtp3_para->nw[netw].routing[dst].normal_ls,SIGNAL_RST,mtp3_para->nw[netw].routing[dst].dpc); + //send route test message out + nw->rsrt_t10[dst] = 0; + } + break; + default: + break; + + } + nw->rsrt_input[dst] = IDLE; +} +/*@end@*/ + diff --git a/plat/mtp3/src/mtpstm.c b/plat/mtp3/src/mtpstm.c new file mode 100644 index 0000000..be32d14 --- /dev/null +++ b/plat/mtp3/src/mtpstm.c @@ -0,0 +1,2205 @@ +#include "./include/mtp3.h" +#include "./include/mtpstm.h" +#include "./include/mtpext.h" +#include "./include/mtpfunc.h" + +// fix multiple definition +mtp3_dpc_index mtp3SortRoutine; +_mtp3_state mtp3ObjState; +_mtp3_input mtp3ObjInput; +_mtp3_IPMng MTP3IPMng; + +/*@ignore@*/ +void hmrt_tcoc_changeover_order(WORD chl); +void hmrt_tcoc_emergency_changeover_order(WORD chl); +void hmrt_tcoc_emergency_changeover_ack(WORD chl); +void hmrt_tcoc_changeover_ack(WORD chl); +void hmrt_tcoc_update_routing_tables(WORD chl); +void mark_alternative_linkset_available(BYTE *routine); +void mark_alternative_linkset_unavailable(BYTE *routine); +void mark_normal_linkset_available(BYTE *routine); +void mark_normal_linkset_unavailable(BYTE *routine); +void mark_dstSP_inaccessible(BYTE *routine); +BOOL Alinkset_status(BYTE routine); +BOOL Nlinkset_status(BYTE routine); + +void start_mtp3T12(WORD link) +{ + t12_delay_mtp3[link] = mtp3_para->lt[link].t12; + mtp3_t12_flag[link] = TIMER_START; +} + +void stop_mtp3T12(WORD link) +{ + t12_delay_mtp3[link] = mtp3_para->lt[link].t12;//not decided + mtp3_t12_flag[link] = TIMER_STOP; +} + +void stop_mtp3T21(WORD linkset) +{ + t21_delay_mtp3[linkset] = mtp3_para->mtp3_t21; + mtp3_t21_flag[linkset] = TIMER_STOP; +} + +void start_mtp3T21(WORD linkset) +{ + t21_delay_mtp3[linkset] = mtp3_para->mtp3_t21; + mtp3_t21_flag[linkset] = TIMER_START; +} + +void tsrc_fun5(WORD linkset) +{ + int i; + BYTE nw; + network *sp; + WORD sp_place; + ls_info *ls; + BYTE rs_2;/* normal route and alternative route status */ + + if (linkset >= MAX_LS) + return; + nw = mtp3_para->ls_pro[linkset].nw_id; + ls = &mtp3.ls[linkset]; + ls->adjacentsp_restarting = 0;/* cancel adjacent sp restarting */ + + /* not support RSRT */ + sp = &mtp3.nw[nw]; + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asNLS[i]; + rs_2 = sp->routine[sp_place]; + if (((rs_2 >> 6) & 3) == 2)// spc unreachable + { + mtp3.nw[nw].rsrt_input[sp_place] = RSRT_TSRC_ROUTE_SET_TEST; + } + if ((Nlinkset_status(rs_2) == LS_AVAILABLE) && + (Alinkset_status(rs_2) == LS_UNAVAILABLE) ) +/* if ( ((rs_2 & 3) == NLS_AVAILABLE) && + (((rs_2 >> 2) & 3) == ALS_UNAVAILABLE) )*/ + {/* sp just accesible */ + mtp3.nw[nw].rtac_input[sp_place] = RTAC_DEST_ACCESSIBLE; + } + hmrt_tfrc_update_routing_tables(sp_place,nw); + } + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asALS[i]; + rs_2 = sp->routine[sp_place]; + if (((rs_2 >> 6) & 3) == 2)// spc unreachable + { + mtp3.nw[nw].rsrt_input[sp_place] = RSRT_TSRC_ROUTE_SET_TEST; + } + if ((Nlinkset_status(rs_2) == LS_UNAVAILABLE) && + (Alinkset_status(rs_2) == LS_AVAILABLE) ) +/* if ( ((rs_2 & 3) == NLS_UNAVAILABLE) && + (((rs_2 >> 2) & 3) == ALS_AVAILABLE) )*/ + {/* sp just accesible */ + mtp3.nw[nw].rtac_input[sp_place] = RTAC_DEST_ACCESSIBLE; + } + hmrt_tfrc_update_routing_tables(sp_place,nw); + } +} + +void mtp3T21_expired(WORD linkset) +{ + tsrc_fun5(linkset); +} + +void start_mtp3T22(WORD link) +{ + t22_delay_mtp3[link] = 20; + mtp3_t22_flag[link] = TIMER_START; +} + +void start_mtp3T23(WORD link) +{ + t23_delay_mtp3[link] = 20; + mtp3_t23_flag[link] = TIMER_START; +} + +void start_mtp3T13(WORD link) +{ + t13_delay_mtp3[link] = mtp3_para->lt[link].t13; + mtp3_t13_flag[link] = TIMER_START; +} + +void stop_mtp3T13(WORD link) +{ + t13_delay_mtp3[link] = mtp3_para->lt[link].t13; + mtp3_t13_flag[link] = TIMER_STOP; +} + +void stop_mtp3T14(WORD link) +{ + t14_delay_mtp3[link] = mtp3_para->lt[link].t14; + mtp3_t14_flag[link] = TIMER_STOP; +} + +void start_mtp3T14(WORD link) +{ + t14_delay_mtp3[link] = mtp3_para->lt[link].t14; + mtp3_t14_flag[link] = TIMER_START; +} + +void mtp3Timer_proc(WORD i) +{ + if (mtp3_t12_flag[i] == TIMER_START) + { + t12_delay_mtp3[i] --; + if (t12_delay_mtp3[i] == 0) + { + mtp3_t12_flag[i] = TIMER_STOP; + t12_delay_mtp3[i] = mtp3_para->lt[i].t12; + mtp3ObjInput.tlac_input_from_Tctl[i] = TLAC_T12_EXPIRED; + } + } + + if (mtp3_t13_flag[i] == TIMER_START) + { + t13_delay_mtp3[i] --; + if (t13_delay_mtp3[i] == 0) + { + mtp3_t13_flag[i] = TIMER_STOP; + t13_delay_mtp3[i] = mtp3_para->lt[i].t13; + mtp3ObjInput.tlac_input_from_Tctl[i] = TLAC_T13_EXPIRED; + } + } + + if (mtp3_t14_flag[i] == TIMER_START) + { + t14_delay_mtp3[i] --; + if (t14_delay_mtp3[i] == 0) + { + mtp3_t14_flag[i] = TIMER_STOP; + t14_delay_mtp3[i] = mtp3_para->lt[i].t14; + mtp3ObjInput.tlac_input_from_Tctl[i] = TLAC_T14_EXPIRED; + } + } + + if (mtp3_t22_flag[i] == TIMER_START) + { + t22_delay_mtp3[i] --; + if (t22_delay_mtp3[i] == 0) + { + mtp3_t22_flag[i] = TIMER_STOP; + t22_delay_mtp3[i] = mtp3_para->lt[i].t22; + mtp3ObjInput.tlac_input_from_Tctl[i] = TLAC_T22_EXPIRED; + } + } + + if (mtp3_t23_flag[i] == TIMER_START) + { + t23_delay_mtp3[i] --; + if (t23_delay_mtp3[i] == 0) + { + mtp3_t23_flag[i] = TIMER_STOP; + t23_delay_mtp3[i] = mtp3_para->lt[i].t23; + mtp3ObjInput.tlac_input_from_Tctl[i] = TLAC_T23_EXPIRED; + } + } + +// i = i & 127; + i = i%MAX_LS; + if (mtp3_t21_flag[i] == TIMER_START) + { + t21_delay_mtp3[i] --; + if (t21_delay_mtp3[i] == 0) + { + mtp3_t21_flag[i] = TIMER_STOP; + t21_delay_mtp3[i] = mtp3_para->mtp3_t21; + mtp3T21_expired(i); + } + } +} + +void mtp3_send_tfp(WORD link,BYTE nw,WORD index) +{ + if (mtp3ObjState.lk_mtp3[link] == mtp3_localip) + { + mtp3.nw[nw].rtpc_input[index] = RTPC_TSRC_SEND_TFP_MSG; + sdTFP_Ls = mtp3_para->lk[link].e1_to_linkset; + rtpc_proc(nw,index); + } +} + +void tsrc_fun6(WORD link,BYTE nw,WORD sp_place) +{ + WORD ls; + WORD nls; + WORD als; + BYTE *routine; + int lsx16; + int i; + + network *sp; + sp = &mtp3.nw[nw]; + ls = mtp3_para->lk[link].e1_to_linkset; + + + nls = mtp3_para->nw[nw].routing[sp_place].normal_ls; + als = mtp3_para->nw[nw].routing[sp_place].alternative_ls; + + routine = (BYTE*)&sp->routine[sp_place]; + + + if (ls == nls)/* normal route unavailable */ + { +// printf("link %d unavailable,Nls %d UNAVAILABLE\n",link,nls); + mark_normal_linkset_unavailable(&sp->routine[sp_place]); + if (Alinkset_status(*routine) == LS_AVAILABLE) +// if ( (((*routine) >> 2) & 3) == ALS_AVAILABLE )/* Alternative route available */ + /* this destination has alternative route */ + {/* new stp use for destination */ + if (mtp3ObjState.lk_mtp3[link] == mtp3_localip) + { +// printf("link %d send TFP via ALS\n",link); + mtp3.nw[nw].rtpc_input[sp_place] = RTPC_TSRC_SEND_TFP_MSG; + sdTFP_Ls = als; + rtpc_proc(nw,sp_place); + mtp3_debug(MTP3DB_EVENT,"[tsrc]net%d spc %lx normal linkset %d unavailable,send TFP to Als %d remote sp",nw,mtp3_para->nw[nw].routing[sp_place].dpc,ls,als); + } + //mark new stp used for destination + } + else + { + lsx16 = ls*16; + for (i=0; i<16; i++) + { + if (mtp3ObjState.link_l3_state[ls_slc[lsx16+i]] == INHIBITED) /* some link inhibited in alternative linkset */ + mtp3ObjInput.tlac_input_from_stm[ls_slc[lsx16+i]] = TLAC_UINHIBIT_SIGLINK_FROM_TSRC; + } + if (mtp3ObjState.lk_mtp3[link] == mtp3_localip) + { + sp->rtpc_input[sp_place] = RTPC_DEST_INACCESSIBLE;/* broadcast tfp */ + rtpc_proc(nw,sp_place); +// printf("mark send tfp to adjacent sp\n"); + current_measure->ls_measure[ls][3]++;/* Broadcast TFP due to failure of measured link set */ + mtp3_debug(MTP3DB_EVENT,"[tsrc]net%d,spc %lx normal linkset %d unavailable,Unreachable!!,broad cast TFP",nw,mtp3_para->nw[nw].routing[sp_place].dpc,ls); + } + else + mtp3_debug(MTP3DB_EVENT,"[tsrc]net%d,spc %lx normal linkset %d unavailable,Unreachable!!",nw,mtp3_para->nw[nw].routing[sp_place].dpc,ls); + //tsfc_tsrc_destination_inacessible + } + } + else if (ls == als)/* als unavailable */ + { + mark_alternative_linkset_unavailable(&sp->routine[sp_place]); + if (Nlinkset_status(*routine) == LS_AVAILABLE) +// if ( ((*routine) & 3) == NLS_AVAILABLE ) + { + } + else + { + lsx16 = ls*16; + for (i=0; i<16; i++) + { + if (mtp3ObjState.link_l3_state[ls_slc[lsx16+i]] == INHIBITED) /* some link inhibited in alternative linkset */ + mtp3ObjInput.tlac_input_from_stm[ls_slc[lsx16+i]] = TLAC_UINHIBIT_SIGLINK_FROM_TSRC; + } + if (mtp3ObjState.lk_mtp3[link] == mtp3_localip) + { + mtp3_debug(MTP3DB_EVENT,"[tsrc]net%d,spc %lx alternative linkset %d unavailable,broadcast TFP",nw,mtp3_para->nw[nw].routing[sp_place].dpc,ls); + sp->rtpc_input[sp_place] = RTPC_DEST_INACCESSIBLE;/* broadcast tfp */ + rtpc_proc(nw,sp_place); +// printf("mark send tfp to adjacent sp,because als unavailable\n"); + current_measure->ls_measure[ls][3]++;/* Broadcast TFP due to failure of measured link set */ + } + else + mtp3_debug(MTP3DB_EVENT,"[tsrc]net%d,spc %lx alternative linkset %d unavailable,Unreachable!!",nw,mtp3_para->nw[nw].routing[sp_place].dpc,ls); + //tsfc_tsrc_destination_inacessible + } + } + if ( (sp->routine[sp_place] & 0x0f) == 0x0a) + { + mark_dstSP_inaccessible(&sp->routine[sp_place]); + } +} + + +void tsrc_fun8(WORD ls,BYTE nw,WORD sp_place) +{ + WORD nls; + WORD als; + BYTE *routine; + + network *sp; + sp = &mtp3.nw[nw]; + + nls = mtp3_para->nw[nw].routing[sp_place].normal_ls; + als = mtp3_para->nw[nw].routing[sp_place].alternative_ls; + + routine = (BYTE*)&sp->routine[sp_place]; + + if ( ((*routine) >> 4) & 3 )/* dst acessible */ + { + if (nls == ls) + { + if (Nlinkset_status(*routine) == LS_UNAVAILABLE) +// if ( ((*routine) & 3) == NLS_UNAVAILABLE) + { + if ( ((*routine) & 0x0C) == ALS_UNAVAILABLE) + {/* new stp use for destination */ + } + else/* als available,route change back to normal route + * stp no longer use for destination */ + { + mtp3.nw[nw].rtac_input[sp_place] = RTAC_STP_NOLONGER_FOR_DEST; + sdTFA_Ls = als; + rtac_proc(nw,sp_place); + mtp3_debug(MTP3DB_EVENT,"[tsrc]net%d,spc%lx normal linkset %d available,no long use als %d for routing,send TFA to als RSP",nw,mtp3_para->nw[nw].routing[sp_place].dpc,ls,als); + {/* tsrc->rtac stp no longer use for destination */ + } + {/* new stp use for destination */ + } + } + mtp3.nw[nw].rtpc_input[sp_place] = RTPC_TSRC_SEND_TFP_MSG; + sdTFP_Ls = ls; + rtpc_proc(nw,sp_place); + } + mark_normal_linkset_available(routine); + } + else if (als == ls) + {/* mark als available */ + mark_alternative_linkset_available(routine); + } + } + else/* dst not accessible */ + { + mtp3.nw[nw].rtac_input[sp_place] = RTAC_DEST_ACCESSIBLE; + //tsfc_tsrc_destination_accessible(ls); + if (nls == ls) + { + mark_normal_linkset_available(routine); + if (Nlinkset_status(*routine) == LS_UNAVAILABLE) +// if ( ((*routine) & 3) == NLS_UNAVAILABLE) + {/* new stp use for destination */ + } + } + else if (als == ls) + {/* new stp use for destination */ + mark_alternative_linkset_available(routine); + } + } +} + +void tsrc_fun7(WORD chl, BYTE nw) +{ + WORD lsx8; + WORD sp_place; + int i; + network *sp; + ls_info *ls; + WORD lsno; + + lsno = mtp3_para->lk[chl].e1_to_linkset; + lsx8 = lsno<<3; + + ls = &mtp3.ls[lsno]; + sp = &mtp3.nw[nw]; + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asNLS[i]; + if ( !own_sp_restarting ) + { + tsrc_fun8(lsno,nw,sp_place); + } + else + mark_normal_linkset_available(&sp->routine[sp_place]); + } + + /* select sp that use this linkset for alternative route */ + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asALS[i]; + if ( !own_sp_restarting ) + { + tsrc_fun8(lsno,nw,sp_place); + } + else + mark_alternative_linkset_available(&sp->routine[sp_place]); + } +} + +void tsrc_tsrc_signalling_link_set_available(WORD chl) +{ + int i; + BYTE nw; + network *sp; + WORD lsx8; + WORD sp_place; + WORD adsp_place; + WORD lsno; + WORD lsx16; + BYTE adsp_acessible; + BYTE owner_of_link; + + ls_info *ls; + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno]; + lsx8 = lsno << 3; + + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + owner_of_link = 1; + else + owner_of_link = 0; + + nw = mtp3_para->ls_pro[lsno].nw_id; + adsp_place = ls->adjacent_sp_place; + if (adsp_place >= MAX_ROUTE) + return; + adsp_acessible = (mtp3.nw[nw].routine[adsp_place] >> 4) & 3; + + ls->adjacentsp_acessible = TRUE; + current_measure->ls_measure[lsno][7]++;/* Stop of adjacent SP inaccessible */ + + if ( own_sp_restarting )/* local restarting */ + { + if (adsp_acessible == 1) + cb_msg_can_exchange[chl] = TRUE; + else + cb_msg_can_exchange[chl] = FALSE; + tsrc_fun7(chl,nw); + } + else + { + if ( adsp_acessible == 1 )/* adjacent sp acessible */ + { + if (adsp_acessible == 1) + cb_msg_can_exchange[chl] = TRUE; + else + cb_msg_can_exchange[chl] = FALSE; + tsrc_fun7(chl,nw); + } + else/* adjacent sp inacessible */ + { + lsx16 = lsno << 4; + ls->adjacentsp_restarting = 1; + start_mtp3T21(lsno); + sp = &mtp3.nw[nw]; +/*** mark all route available ***/ + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asNLS[i]; + mark_normal_linkset_available(&sp->routine[sp_place]); + if (Alinkset_status(sp->routine[sp_place]) == LS_AVAILABLE) +// if ( ((sp->routine[sp_place] >> 2) & 3) == ALS_AVAILABLE) + { + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + { +// printf("link %d send TFA via ALS\n",chl); + mtp3.nw[nw].rtpc_input[sp_place] = RTPC_TSRC_SEND_TFP_MSG; + sdTFA_Ls = mtp3_para->nw[nw].routing[lsno].alternative_ls; + rtac_proc(nw,sp_place); + } + } + } + + /* select sp that use this linkset for alternative route */ + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asALS[i]; + mark_alternative_linkset_available(&sp->routine[sp_place]); + } +/*** mark all route can available ***/ +// tsfc_tsrc_adjacent_sp_restarting(ls); +// tprc_tsrc_adjacent_sp_restarting(ls); + mtp3.ls[lsno].adjacentsp_restarting = 1;/* mark adjacent sp restarting */ + if (owner_of_link == 1) + mtp3ObjInput.taprc_input[lsno] = TPRC_ADJACENT_SP_RESTARTING; +// mtp3_debug(MTP3DB_EVENT,"chl %d,linkset %d adjacent sp restarting",chl,lsno); + } + } +} + +void tsrc_tsrc_signalling_link_set_unavailable(WORD chl) +{ + BYTE i; + BYTE nw; + network *sp; + WORD lsx8; + WORD sp_place; + WORD lsno; + WORD adsp_place; + BYTE owner_of_link; + + ls_info *ls; + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno]; + lsx8 = lsno << 3; + + if (mtp3ObjState.lk_mtp3[chl] == mtp3_localip) + owner_of_link = 1; + else + owner_of_link = 0; + + nw = mtp3_para->ls_pro[lsno].nw_id; + adsp_place = ls->adjacent_sp_place; + if (adsp_place >= MAX_ROUTE) + return; + + if ( (mtp3.nw[nw].routine[adsp_place] & 0x0f) == 0 )/* normal and alternative route are available before */ + co_msg_can_exchange[chl] = TRUE; + else + { + ls->adjacentsp_acessible = FALSE; + current_measure->ls_measure[lsno][5]++;/* Adjacent SP inaccessible */ + co_msg_can_exchange[chl] = FALSE; + } + + sp = &mtp3.nw[nw]; + /* select sp that use this linkset as normal route */ + for ( i=0; i<(ls->influ_dstnum_asNLS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asNLS[i]; + if ( own_sp_restarting ) + { + mark_normal_linkset_unavailable(&sp->routine[sp_place]); + if (Alinkset_status(sp->routine[sp_place]) != LS_AVAILABLE) + { +// if ( ((sp->routine[sp_place] >> 2) & 3) != ALS_AVAILABLE )/* Alternative route available */ + mark_dstSP_inaccessible(&sp->routine[sp_place]); + printf("mark inaccessible\n"); + } + } + else + tsrc_fun6(chl,nw,sp_place); + } + + /* select sp that use this linkset as alternative route */ + for ( i=0; i<(ls->influ_dstnum_asALS % MAX_LS_DPC_ADD1); i++ ) + { + sp_place = ls->influ_dstplace_intable_asALS[i]; + if ( own_sp_restarting ) + { + mark_alternative_linkset_unavailable(&sp->routine[sp_place]); + if (Nlinkset_status(sp->routine[sp_place]) != LS_AVAILABLE) +// if ( (sp->routine[sp_place] & 3) != NLS_AVAILABLE )/* normal route unavailable */ + mark_dstSP_inaccessible(&sp->routine[sp_place]); + } + else + tsrc_fun6(chl,nw,sp_place); + } +} + +int inhibit_allow_or_not(WORD ls,BYTE nw) +{ + int dpc; + BYTE routine; + + for (dpc=0; dpcnw[nw].routing[dpc].normal_ls == ls) && + (Alinkset_status(routine) == LS_UNAVAILABLE) ) +// (((routine >> 2) & 3) == ALS_UNAVAILABLE) ) + return FALSE; + else if ( (mtp3_para->nw[nw].routing[dpc].alternative_ls == ls) && + (Nlinkset_status(routine) == LS_UNAVAILABLE) ) +// ((routine & 3) == NLS_UNAVAILABLE) ) + return FALSE; + } + return TRUE; +} + +void tsrc_fun15(WORD chl,BYTE inhibit_req_by) +{ + switch (inhibit_req_by) + { + case LOCAL_INHIBIT_REQ: + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_LOCAL_INHIBIT_DENIED; + break; + case REMOTE_INHIBIT_REQ: + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_REMOTE_INHIBIT_DENIED; + break; + } +} + +void tsrc_inhibit_allow(WORD chl,BYTE inhibit_req_by) +{ + switch (inhibit_req_by) + { + case LOCAL_INHIBIT_REQ: + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_LOCAL_INHIBIT_ALLOWED; + break; + case REMOTE_INHIBIT_REQ: + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_REMOTE_INHIBIT_ALLOWED; + link_inhibited[chl] = TRUE;/* mark link inhibited */ + break; + } +} + +void tsrc_fun13(WORD chl,BYTE inhibit_req_by) +{ + WORD ls; + BYTE nw; + BYTE route_st; + int inhibit; + WORD sp_place; + + mtp3_debug(MTP3DB_EVENT,"[tsrc]link %d rv inhibit request from tlac",chl); + + ls = mtp3_para->lk[chl].e1_to_linkset; + nw = mtp3_para->ls_pro[ls].nw_id; + if (mtp3ObjState.link_l3_state[chl] == UNAVAILABLE)/* link l3 state unavailable */ + { + sp_place = mtp3.ls[ls].adjacent_sp_place; + if (sp_place >= MAX_ROUTE) + return; + route_st = (mtp3.nw[nw].routine[sp_place] >> 4) & 3; + if (route_st == SP_ACCESSIBLE)/* remote sp can access */ + { + tsrc_inhibit_allow(chl,inhibit_req_by); + } + else/* remote sp can't access */ + { + tsrc_fun15(chl,inhibit_req_by);/* [inhibit dennid] */ + } + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + } + else/* link l3 state available */ + { + if (mtp3.ls[ls].links_available == 1)/* there is only one link left available in this linkset */ + { + inhibit = inhibit_allow_or_not(ls,nw); + if (inhibit == FALSE)/* inhibit this link maybe can cause one dpc not accessable */ + tsrc_fun15(chl,inhibit_req_by);/* [inhibit dennid] */ + else/* inhibit this link will not cause any dpc not accessable */ + tsrc_inhibit_allow(chl,inhibit_req_by); + } + else/* there is another available link in this linkset */ + tsrc_inhibit_allow(chl,inhibit_req_by); + } +} + +void tsrc_proc(WORD chl) +{ + BYTE cc_lk_num; + WORD lsno; + BYTE rmSP_routine;/* remote sp routine */ + WORD rmSP_place; + + ls_info *ls; + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno]; + + switch (mtp3ObjState.tsrc_state[chl]) + { + case TSRC_IDLE_STATE: + switch (mtp3ObjInput.tsrc_input_from_tlac[chl]) + { + case TSRC_TLAC_LINK_UNAVAILABLE: +// printf("tsrc link %d unavailable\n",chl); + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + if (ls->links_available > 0) + ls->links_available--; + // if ( /* emergency see 12.2.4 */ ) +// lk_llsc_tsrc_emergency(lk); + if ( ls->links_available == 0 ) + { + changeover_select[chl] = BETWEEN_LS; + mtp3_debug(MTP3DB_EVENT,"[tsrc]link %d unavailable,linkset %d unavailable",chl,lsno); + tsrc_tsrc_signalling_link_set_unavailable(chl); + } + else + { + mtp3_debug(MTP3DB_EVENT,"[tsrc]link %d unavailable",chl); + co_msg_can_exchange[chl] = TRUE; + changeover_select[chl] = WITHIN_LS; + } + break; + + case TSRC_TLAC_LINK_AVAILABLE: +// printf("tsrc link %d available\n",chl); + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + link_available[chl] = AVAILABLE; + ls->links_available++; + // if ( /* not emergency see 12.2.4 */ ) + // lk_llsc_tsrc_emergency_ceases(lk); + if ( ls->links_available == 1 )/* no other links available in linkset */ + { + mtp3_debug(MTP3DB_EVENT,"[tsrc]link %d available,linkset available",chl); + tsrc_tsrc_signalling_link_set_available(chl); + changeback_select[chl] = BETWEEN_LS; + } + else + { + mtp3_debug(MTP3DB_EVENT,"[tsrc]link %d available",chl); + changeback_select[chl] = WITHIN_LS; + cb_msg_can_exchange[chl] = TRUE; + } + break; + + case TSRC_TLAC_LOCAL_INHIBIT_REQ: + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + tsrc_fun13(chl,LOCAL_INHIBIT_REQ); + break; + + case TSRC_TLAC_REMOTE_INHIBIT_REQ: + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + tsrc_fun13(chl,REMOTE_INHIBIT_REQ); + break; + + case TSRC_TLAC_LINK_INHIBITED: + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + link_inhibited[chl] = TRUE; + break; + + case TSRC_TLAC_CANCEL_LINK_INHIBITED: + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + link_inhibited[chl] = FALSE; + break; + + case TSRC_TLAC_UNINHIBIT_REQ: + mtp3ObjInput.tsrc_input_from_tlac[chl] = IDLE; + rmSP_place = mtp3.ls[lsno].adjacent_sp_place; + if (rmSP_place > 255) + return; + rmSP_routine = mtp3.nw[mtp3_para->ls_pro[lsno].nw_id].routine[rmSP_place]; + if ( ((rmSP_routine >> 4) & 1) == SP_INACCESSIBLE)/* no route */ + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_UNINHIBIT_NOT_POSSIBLE; + else + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_UNINHIBIT_POSSIBLE; + break; + + default: + break; + } + + switch (mtp3ObjInput.tsrc_input_from_tcoc[chl]) + { + case TSRC_TCOC_ALTERNATIVE_ROUTING_DATA_REQUEST: + mtp3ObjInput.tsrc_input_from_tcoc[chl] = IDLE; + /* obtain alternative routing data according to rules specified in Q.704 4.4 */ + /* during SP restart the adjacent SP is considered inaccessible */ + /* locally or request from MTP level state machine */ +/********/ +/********/ changeover_required[chl] = TRUE; + mtp3ObjInput.tcoc_input_from_tsrc[chl] = TCOC_ALTERATIVE_ROUTE_DT; + mtp3ObjState.tsrc_state[chl] = TSRC_WAIT01_STATE; + mtp3_debug(MTP3DB_EVENT,"[tsrc]link %d tcoc asking for alternative route date",chl); + break; + + default: + break; + } + + switch (mtp3ObjInput.tsrc_input_from_tcbc[chl]) + { + case TSRC_TCBC_ALTERNATIVE_ROUTING_DATA_REQUEST: + mtp3ObjInput.tsrc_input_from_tcbc[chl] = IDLE; + cc_lk_num = 0; + + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[lsno]; + /* obtain alternative routing data */ + /* during SP restart the adjacent SP is considered inaccessible */ + /* locally or request from MTP level state machine */ + if ( changeback_select[chl] == BETWEEN_LS )/* this is the first link */ + { +// mtp3_debug(MTP3DB_EVENT,"link %d changeback_select BETWEEN_LS",chl); + /* but change back message will not exchange between link set */ + } + else + { + } +// printf("tsrc link %d tcbc alter data cmp\n",chl); + mtp3ObjInput.tcbc_input_from_tsrc[chl] = TCBC_ALTERATIVE_ROUTE_DT; + mtp3ObjState.tsrc_state[chl] = TSRC_WAIT02_STATE; + tcbc_route_change[chl] = TRUE; + mtp3_debug(MTP3DB_EVENT,"[tsrc]link %d tcbc asking for alternative route date",chl); + break; + + default: + break; + } + + switch (mtp3ObjInput.tsrc_input_from_stm[chl]) + { + default: + break; + } + + case TSRC_WAIT01_STATE:/* 1 TSRC_WAIT1_STATE */ + if (mtp3ObjInput.tsrc_input_from_tcoc[chl] == TSRC_TCOC_CHANGEOVER_EXECUTED) + { + mtp3ObjInput.tsrc_input_from_tcoc[chl] = IDLE; + changeover_completed[chl] = 1; + mtp3ObjState.tsrc_state[chl] = TSRC_IDLE_STATE; + } + else if (mtp3ObjInput.tsrc_input_from_tcoc[chl] == TSRC_TCOC_CHANGEOVER_NOT_REQ) + { + mtp3ObjInput.tsrc_input_from_tcoc[chl] = IDLE; + mtp3ObjState.tsrc_state[chl] = TSRC_IDLE_STATE; + } + break; + + case TSRC_WAIT02_STATE:/* 2 TSRC_WAIT2_STATE */ + if ( mtp3ObjInput.tsrc_input_from_tcbc[chl] == TSRC_PROCEDURE_TERMINATED ) + { + mtp3ObjInput.tsrc_input_from_tcbc[chl] = IDLE; + changeover_completed[chl] = 0; + mtp3ObjState.tsrc_state[chl] = TSRC_IDLE_STATE; + } + break; + + case TSRC_WAIT03_STATE: + break; + case TSRC_WAIT04_STATE: + break; + case TSRC_WAIT05_STATE: + /* this state's function put in the tprc state machine */ + break; + default: + break; + } +} + +void tlac_fun5(WORD link) +{ + mtp3ObjInput.tcbc_input[link] = TCBC_LINK_AVAILABLE; + changeback_in_progress[link] = TRUE; + mtp3ObjInput.tsrc_input_from_tlac[link] = TSRC_TLAC_LINK_AVAILABLE; + mtp3ObjState.tlac_state[link] = TLAC_AVAILABLE_STATE; +} + +void tlac_fun6(WORD link) +{ + if (changeover_in_progress[link] == TRUE) + { + mtp3ObjInput.tcoc_input_from_stm[link] = TCOC_LINK_AVAILABLE; + } + else + tlac_fun5(link); +} + +void tlac_fun7(WORD link) +{ + sd_STM_msg(link,SIGNAL_LUN); + uninhibit_in_progress[link] = TRUE; + start_mtp3T12(link); +} + +void tlac_fun1(WORD link) +{ + if (changeback_in_progress[link] == TRUE) + { +// mtp3_debug(MTP3DB_EVENT,"changeback in progress"); + link_available[link] = FALSE; + } + else + { + changeover_in_progress[link] = TRUE; + mtp3ObjInput.tcoc_input_from_stm[link] = TCOC_LINK_UNAVAILABLE; + } + mtp3ObjInput.tsrc_input_from_tlac[link] = TSRC_TLAC_LINK_UNAVAILABLE; + mtp3ObjState.tlac_state[link] = TLAC_UNAVAILABLE_STATE; +} + +void mgmt_tlac_proc(WORD link,BYTE input) +{ + switch (input) + { + case 0: + break; + case 1: + break; + } +} + +void tlac_proc(WORD chl) +{ + ls_info *ls; + int lsno; + + if (init_tlac_state[chl] == TRUE) + { + init_tlac_state[chl] = IDLE; + mtp3ObjState.tlac_state[chl] = TLAC_UNAVAILABLE_STATE; + changeover_in_progress[chl] = FALSE; + changeback_in_progress[chl] = FALSE; + failed[chl] = TRUE; + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + return; + } + + lsno = mtp3_para->lk[chl].e1_to_linkset; + ls = &mtp3.ls[mtp3_para->lk[chl].e1_to_linkset]; + + switch (mtp3ObjState.tlac_state[chl]) + { + case TLAC_UNAVAILABLE_STATE: + switch (mtp3ObjInput.tlac_input_from_mgmt[chl]) + { + case TLAC_MGMT_INHIBIT_SIGLINK: + mtp3ObjInput.tlac_input_from_mgmt[chl] = IDLE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LOCAL_INHIBIT_REQ; + current_measure->lk_measure1[chl][7]++;//Local management inhibit + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv local MGMT inhibit request in unavailable state",chl); + break; + case TLAC_MGMT_UINHIBIT_SIGLINK: + mtp3ObjInput.tlac_input_from_mgmt[chl] = IDLE; + management_req[chl] = TRUE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_UNINHIBIT_REQ; + current_measure->lk_measure1[chl][8]++;//Local management uninhibit + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv local MGMT uninhibit request in unavailable state",chl); + break; + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_hmdt[chl]) + { + case TLAC_HMDT_INHIBIT_SIGLINK: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (link_remotely_inhibited[chl] == TRUE) + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv LIN,send LIA",chl); + sd_STM_msg(chl,SIGNAL_LIA);/* send inhibit ack signal */ + } + else + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv LIN,send LIA,mark Inhibited",chl); + link_remotely_inhibited[chl] = TRUE; + link_locally_inhibited[chl] = FALSE; + sd_STM_msg(chl,SIGNAL_LIA); + mtp3ObjState.link_l3_state[chl] = INHIBITED; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_INHIBITED; + start_mtp3T22(chl); + } + break; + + case TLAC_HMDT_UINHIBIT_SIGLINK: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (link_inhibited[chl] == TRUE) + { + mtp3_debug(MTP3DB_EVENT,"[tlac(unavai)]link %d (inhibited) rv LUN,send LUA",chl); + link_remotely_inhibited[chl] = FALSE; + sd_STM_msg(chl,SIGNAL_LUA); + stop_mtp3T13(chl); + if (link_locally_inhibited[chl] != TRUE) + { + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_CANCEL_LINK_INHIBITED; + link_inhibited[chl] = FALSE; + if ( (blocked_by[chl] == IDLE) && + (failed[chl] != TRUE) ) + tlac_fun6(chl); + else + mtp3ObjState.link_l3_state[chl] = UNAVAILABLE; + } + } + else + { + mtp3_debug(MTP3DB_EVENT,"[tlac(unavai)]link %d (unavailable) rv LUN,send LUA",chl); + sd_STM_msg(chl,SIGNAL_LUA); + } + break; + + case TLAC_HMDT_INHIBIT_ACK: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (local_inhibit_in_progress[chl] == TRUE) + { + link_locally_inhibited[chl] = TRUE; + link_remotely_inhibited[chl] = FALSE; + link_inhibited[chl] = TRUE; + mtp3ObjState.link_l3_state[chl] = INHIBITED; + local_inhibit_in_progress[chl] = FALSE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_INHIBITED; + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv LIA,TLAC->TSRC:LINK INHIBITED",chl); + stop_mtp3T14(chl); + } + start_mtp3T22(chl); + break; + + case TLAC_HMDT_UNINHIBIT_ACK: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv LUA",chl); + if (uninhibit_in_progress[chl] == TRUE) + { + management_req[chl] = FALSE; + uninhibit_in_progress[chl] = FALSE; + mtp3ObjState.link_l3_state[chl] = UNAVAILABLE; + stop_mtp3T12(chl); + if (link_remotely_inhibited[chl] != TRUE) + { + link_inhibited[chl] = FALSE; + link_locally_inhibited[chl] = FALSE; +// mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_CANCEL_LINK_INHIBITED; + if ( (blocked_by[chl] == IDLE) && + (failed[chl] != TRUE) ) + tlac_fun6(chl); + } + } + break; + + case TLAC_HMDT_INHIBIT_DENIED: + break; + + case TLAC_HMDT_FORCE_UNINHIBIT_SIGLINK: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (link_inhibited[chl] == TRUE) + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d (inhibited) rv LFU",chl); + sd_STM_msg(chl,SIGNAL_LUN); + uninhibit_in_progress[chl] = TRUE; + start_mtp3T12(chl); + } + else + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv LFU",chl); + sd_STM_msg(chl,SIGNAL_LUN); + } + break; + + case TLAC_HMDT_CHANGEOVER_ORDER: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if ( changeover_in_progress[chl] == TRUE ) + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv COO,TLAC->TCOC:COO COMMAND",chl); + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_COO_COMMAND; + } + else + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv COO,send ECA",chl); + hmrt_tcoc_emergency_changeover_ack(chl); + } + break; + + case TLAC_HMDT_ECHANGEOVER_ORDER: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if ( changeover_in_progress[chl] == TRUE) /*changeover is executing */ + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv ECO,TLAC->TCOC:ECO COMMAND",chl); + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_ECO_COMMAND; + } + else + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv ECO,send ECA",chl); + sd_STM_msg(chl,SIGNAL_ECA); + } + break; + + case TLAC_HMDT_LOCAL_INHIBIT_TEST: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (link_remotely_inhibited[chl] != TRUE) + { + sd_STM_msg(chl,SIGNAL_LFU); + start_mtp3T13(chl); + } + break; + case TLAC_HMDT_REMOTE_INHIBIT_TEST: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (link_locally_inhibited[chl] != TRUE) + { + sd_STM_msg(chl,SIGNAL_LUN); + start_mtp3T12(chl); + } + break; + + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_stm[chl]) + { + case TLAC_TCBC_CHANGEBACK_TERMINATED: + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + changeback_in_progress[chl] = FALSE; + if ( changeover_order[chl] == TRUE) + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_COO_COMMAND; + else if ( emergency_changeover_order[chl] == TRUE) + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_ECO_COMMAND; + else if ( link_available[chl] != TRUE ) + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_LINK_UNAVAILABLE; + link_available[chl] = IDLE; + changeover_order[chl] = IDLE; + emergency_changeover_order[chl] = IDLE; + changeover_in_progress[chl] = TRUE;/* mark change over in progress */ + break; + + case TLAC_TCOC_CHANGEOVER_EXECUTED: + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + changeover_in_progress[chl] = IDLE;/* cancel mark */ + if (link_inhibited[chl] != TRUE) + { + if ( failed[chl] != TRUE ) + { + tlac_fun5(chl); + } + } + break; + + case TLAC_LOCAL_INHIBIT_ALLOWED: + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d local inhibit allow",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LIN); + local_inhibit_in_progress[chl] = TRUE; + start_mtp3T14(chl); + break; + + case TLAC_REMOTE_INHIBIT_ALLOWED: + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d remote inhibit allow",chl); + break; + case TLAC_LOCAL_INHIBIT_DENIED: + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d local inhibit denied",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + break; + + case TLAC_REMOTE_INHIBIT_DENIED: + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d remote inhibit denied",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + break; + + case TLAC_UINHIBIT_SIGLINK_FROM_TSRC: + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d rv uninhibit sig from TSRC",chl); + if (uninhibit_in_progress[chl] != TRUE) + { + uninhibit_in_progress[chl] = TRUE; + if ( (blocked_by[chl] != IDLE) || + (failed[chl] == TRUE) ) + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d uninhibit no success, blocked or failed",chl); + } + else + { + if (link_locally_inhibited[chl] == TRUE) + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d send LUN",chl); + sd_STM_msg(chl,SIGNAL_LUN); + start_mtp3T12(chl); + } + else if (link_remotely_inhibited[chl] == TRUE) + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d send LFU",chl); + sd_STM_msg(chl,SIGNAL_LFU); + start_mtp3T13(chl); + } + else + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d is not being local or remotely inhibited",chl); + } + } + } + else + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d uninhibit in progress",chl); + break; + + case TLAC_UNINHIBIT_NOT_POSSIBLE: + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d uninhibit not possible",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + if ( (blocked_by[chl] != IDLE) && + (failed[chl] == TRUE) ) + { + mgmt_tlac_proc(chl,MGMT_UNINHIBIT_NOT_POSSIBLE); + management_req[chl] = FALSE; + } + else + { + sd_STM_msg(chl,SIGNAL_LUN); + uninhibit_in_progress[chl] = TRUE; + start_mtp3T12(chl); + } + break; + + case TLAC_UNINHIBIT_POSSIBLE: + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d uninhibit possible",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LUN); + uninhibit_in_progress[chl] = TRUE; + start_mtp3T12(chl); + break; + + case TLAC_RESTART_BEGINS: + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + mtp3ObjState.tlac_state[chl] = TLAC_SP_RESTARTING_STATE; + break; + + case TLAC_TCOC_CHANGEOVER_NOT_REQ: + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + changeover_in_progress[chl] = IDLE;/* cancel mark */ + if ( failed[chl] != TRUE ) + { + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_AVAILABLE; + mtp3ObjState.tlac_state[chl] = TLAC_AVAILABLE_STATE; + } + break; + + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_slm[chl]) + { + case TLAC_LSAC_SIGLINK_FAILED: + mtp3ObjInput.tlac_input_from_slm[chl] = IDLE; + failed[chl] = TRUE;/* mark link fail */ + break; + + case TLAC_LSAC_LINK_IN_SERVICE: + mtp3ObjInput.tlac_input_from_slm[chl] = IDLE; + failed[chl] = FALSE;/* cancel mark link fail */ + if (link_inhibited[chl] != TRUE) + { + if (changeover_in_progress[chl] == TRUE) + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d in service,changeover in progress,TLAC->TCOC:LINK AVAILABLE",chl); + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_LINK_AVAILABLE; + } + else + { + mtp3_debug(MTP3DB_EVENT,"[TLAC(unavai)]link %d in service,TLAC->TSRC(TCBC):LINK AVAILABLE",chl); + tlac_fun5(chl); + } + } + break; + + case TLAC_LSAC_REMOTE_PROCESSOR_OUTAGE: + break; + + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_Tctl[chl]) + { + case TLAC_T12_EXPIRED: + mtp3ObjInput.tlac_input_from_Tctl[chl] = IDLE; + uninhibit_in_progress[chl] = FALSE;/* cancel uninhibit in progress */ + if (t12_expired_2nd_time[chl] == TRUE) + { + t12_expired_2nd_time[chl] = FALSE; + mgmt_tlac_proc(chl,MGMT_UNINHIBIT_NOT_POSSIBLE); + } + else + { + t12_expired_2nd_time[chl] = TRUE; + if (management_req[chl] == TRUE) + { + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_UNINHIBIT_REQ; + } + else + tlac_fun7(chl); + } + break; + case TLAC_T13_EXPIRED: + mtp3ObjInput.tlac_input_from_Tctl[chl] = IDLE; + if (t13_expired_2nd_time[chl] == TRUE) + { + mgmt_tlac_proc(chl,MGMT_UNINHIBIT_NOT_POSSIBLE); + } + else + { + sd_STM_msg(chl,SIGNAL_LFU); + start_mtp3T13(chl); + } + break; + case TLAC_T14_EXPIRED: + mtp3ObjInput.tlac_input_from_Tctl[chl] = IDLE; + local_inhibit_in_progress[chl] = FALSE;/* cancel local inhibit in progress */ + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LOCAL_INHIBIT_REQ;/* local inhibit request */ + break; + case TLAC_T22_EXPIRED: + mtp3ObjInput.tlac_input_from_Tctl[chl] = IDLE; + if (link_locally_inhibited[chl] == TRUE) + { + sd_STM_msg(chl,SIGNAL_LLT); + start_mtp3T22(chl); + } + break; + case TLAC_T23_EXPIRED: + mtp3ObjInput.tlac_input_from_Tctl[chl] = IDLE; + if (link_remotely_inhibited[chl] == TRUE) + { + sd_STM_msg(chl,SIGNAL_LRT); + start_mtp3T23(chl); + } + break; + default: + break; + } + + break; + + case TLAC_AVAILABLE_STATE: + switch (mtp3ObjInput.tlac_input_from_mgmt[chl]) + { + case TLAC_MGMT_INHIBIT_SIGLINK: + mtp3ObjInput.tlac_input_from_mgmt[chl] = IDLE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LOCAL_INHIBIT_REQ; + current_measure->lk_measure1[chl][7]++;//Local management inhibit + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d rv local MGMT uninhibit request",chl); + break; + case TLAC_MGMT_UINHIBIT_SIGLINK: + mtp3ObjInput.tlac_input_from_mgmt[chl] = IDLE; + current_measure->lk_measure1[chl][8]++;//Local management uninhibit + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d rv local MGMT uninhibit request",chl); + break; + default: + break; + } + + switch ( mtp3ObjInput.tlac_input_from_hmdt[chl]) + { + case TLAC_HMDT_INHIBIT_SIGLINK: + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d rv LIN",chl); + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_REMOTE_INHIBIT_REQ; + break; + + case TLAC_HMDT_UINHIBIT_SIGLINK: + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d rv LUN",chl); + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LUA); + break; + + case TLAC_HMDT_INHIBIT_ACK: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (local_inhibit_in_progress[chl] == TRUE) + { + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d rv LIA,inhibit in progress",chl); + link_locally_inhibited[chl] = TRUE; + link_remotely_inhibited[chl] = FALSE; + local_inhibit_in_progress[chl] = FALSE; + stop_mtp3T14(chl); + link_inhibited[chl] = TRUE; +// mtp3ObjInput.tsrc_input_from_stm[chl] = TSRC_TLAC_LINK_INHIBITED; + mgmt_tlac_proc(chl,MGMT_TLAC_LINK_INHIBITED); + start_mtp3T22(chl); + tlac_fun1(chl); + } + else + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d rv LIA",chl); + break; + + case TLAC_HMDT_UNINHIBIT_ACK: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + break; + + case TLAC_HMDT_INHIBIT_DENIED: + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d rv LID",chl); + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + mgmt_tlac_proc(chl,MGMT_INHIBIT_DENIED); + local_inhibit_in_progress[chl] = FALSE; + stop_mtp3T14(chl); + break; + + case TLAC_HMDT_FORCE_UNINHIBIT_SIGLINK: + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d rv LFU",chl); + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LUN); + break; + + case TLAC_HMDT_CHANGEOVER_ORDER: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + mtp3ObjInput.lsac_input_from_stm[chl] = LSAC_TLAC_CHANGEOVER_ORDER_RECEIVED; + failed[chl] = TRUE;/* mark failed */ + if ( changeback_in_progress[chl] == TRUE ) + { + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d rv COO command,changeback in progress",chl); + changeover_order[chl] = TRUE;/* mark received coo command */ + } + else + { + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d rv COO command,TLAC->TCOC:COO COMMAND",chl); + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_COO_COMMAND; + changeover_in_progress[chl] = TRUE; + } + mtp3ObjState.tlac_state[chl] = TLAC_UNAVAILABLE_STATE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_UNAVAILABLE; + break; + + case TLAC_HMDT_ECHANGEOVER_ORDER: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + mtp3ObjInput.lsac_input_from_stm[chl] = LSAC_TLAC_CHANGEOVER_ORDER_RECEIVED; + failed[chl] = TRUE; + if ( changeback_in_progress[chl] == TRUE ) + { + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d rv ECO command,changeback in progress",chl); + emergency_changeover_order[chl] = TRUE; + } + else + { + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d rv EOO command,TLAC->TCOC:EOO COMMAND",chl); + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_ECO_COMMAND; + changeover_in_progress[chl] = TRUE; + } + mtp3ObjState.tlac_state[chl] = TLAC_UNAVAILABLE_STATE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_UNAVAILABLE; + break; + + case TLAC_HMDT_LOCAL_INHIBIT_TEST: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LFU); + start_mtp3T13(chl); + break; + case TLAC_HMDT_REMOTE_INHIBIT_TEST: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LUN); + start_mtp3T12(chl); + break; + + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_stm[chl]) + { + case TLAC_TCBC_CHANGEBACK_TERMINATED: + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + changeback_in_progress[chl] = FALSE; + break; + + case TLAC_TCOC_CHANGEOVER_EXECUTED: + break; + + case TLAC_TCOC_CHANGEOVER_NOT_REQ: + break; + + case TLAC_LOCAL_INHIBIT_ALLOWED: + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d local inhibit allow",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LIN); + local_inhibit_in_progress[chl] = TRUE; + start_mtp3T14(chl); + break; + + case TLAC_REMOTE_INHIBIT_ALLOWED: + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d remote inhibit allow",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + link_remotely_inhibited[chl] = TRUE; + link_locally_inhibited[chl] = FALSE; + sd_STM_msg(chl,SIGNAL_LIA); +// mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_INHIBITED; + link_inhibited[chl] = TRUE; + start_mtp3T23(chl); + tlac_fun1(chl); + break; + + case TLAC_LOCAL_INHIBIT_DENIED: + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d local inhibit denied",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + mgmt_tlac_proc(chl,MGMT_INHIBIT_DENIED); + break; + + case TLAC_REMOTE_INHIBIT_DENIED: + mtp3_debug(MTP3DB_EVENT,"[tlac(avai)]link %d remote inhibit denied",chl); + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + sd_STM_msg(chl,SIGNAL_LID); + break; + + case TLAC_RESTART_BEGINS: + link_available[chl] = AVAILABLE; + mtp3ObjState.tlac_state[chl] = TLAC_SP_RESTARTING_STATE; + break; + + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_slm[chl]) + { + case TLAC_LSAC_SIGLINK_FAILED: + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d outof service",chl); + mtp3ObjInput.tlac_input_from_slm[chl] = IDLE; + failed[chl] = TRUE;/* mark link fail */ + tlac_fun1(chl); + break; + + case TLAC_LSAC_LINK_IN_SERVICE: + mtp3ObjInput.tlac_input_from_slm[chl] = IDLE; + mtp3_debug(MTP3DB_EVENT,"[TLAC(avai)]link %d in service",chl); + break; + + case TLAC_LSAC_REMOTE_PROCESSOR_OUTAGE: + break; + + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_Tctl[chl]) + { + case TLAC_T12_EXPIRED: + break; + case TLAC_T13_EXPIRED: + break; + case TLAC_T14_EXPIRED: + mtp3ObjInput.tlac_input_from_Tctl[chl] = IDLE; + local_inhibit_in_progress[chl] = FALSE;/* cancel local inhibit in progress */ + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LOCAL_INHIBIT_REQ;/* local inhibit request */ + break; + default: + break; + } + + break; + + case TLAC_SP_RESTARTING_STATE: + switch (mtp3ObjInput.tlac_input_from_slm[chl]) + { + case TLAC_LSAC_SIGLINK_FAILED: + mtp3_debug(MTP3DB_EVENT,"[TLAC(rest)]link %d unavailable in restarting state",chl); +// printf("tlac link %d failed\n",chl); + mtp3ObjInput.tlac_input_from_slm[chl] = IDLE; + failed[chl] = TRUE;/* mark link fail */ + link_available[chl] = FALSE; + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_LINK_UNAVAILABLE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_UNAVAILABLE; + break; + + case TLAC_LSAC_LINK_IN_SERVICE: + mtp3ObjInput.tlac_input_from_slm[chl] = IDLE; + failed[chl] = FALSE; + link_available[chl] = TRUE; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_AVAILABLE; + mtp3ObjInput.tcbc_input[chl] = TCBC_LINK_AVAILABLE; + if ( (ls->links_available - 1) == mtp3.ls[lsno].linksNum_configured ) + current_active_ls_num ++; + mtp3_debug(MTP3DB_EVENT,"[TLAC(rest)]link %d in service in restarting state",chl); + break; + + case TLAC_LSAC_REMOTE_PROCESSOR_OUTAGE: + break; + + default: + break; + } + + switch (mtp3ObjInput.tlac_input_from_hmdt[chl]) + { + case TLAC_HMDT_CHANGEOVER_ORDER: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (failed[chl] == FALSE)/* link available */ + { + failed[chl] = TRUE;/* mark failed */ + mtp3ObjInput.lsac_input_from_stm[chl] = LSAC_TLAC_CHANGEOVER_ORDER_RECEIVED; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_UNAVAILABLE; + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_COO_COMMAND; + mtp3_debug(MTP3DB_ERROR,"[TLAC(rest)]link %d RECEIVE COO(link active)\n\r",chl); + } + else + { + mtp3_debug(MTP3DB_ERROR,"[TLAC(rest)]link %d RECEIVE COO(link fail)\n\r",chl); + } + break; + + case TLAC_HMDT_ECHANGEOVER_ORDER: + mtp3ObjInput.tlac_input_from_hmdt[chl] = IDLE; + if (failed[chl] == FALSE) + { + failed[chl] = TRUE;/* mark failed */ + mtp3ObjInput.lsac_input_from_stm[chl] = LSAC_TLAC_CHANGEOVER_ORDER_RECEIVED; + mtp3ObjInput.tsrc_input_from_tlac[chl] = TSRC_TLAC_LINK_UNAVAILABLE; + mtp3ObjInput.tcoc_input_from_stm[chl] = TCOC_TLAC_ECO_COMMAND; + mtp3_debug(MTP3DB_ERROR,"[TLAC(rest)]link %d RECEIVE ECO IN RESTART STATE(link active)\n\r",chl); + } + else + { + mtp3_debug(MTP3DB_ERROR,"[TLAC(rest)]link %d RECEIVE ECO IN RESTART STATE(link fail)\n\r",chl); + } + break; + } + + switch (mtp3ObjInput.tlac_input_from_stm[chl]) + { + case TLAC_RESTART_ENDS: + mtp3ObjInput.tlac_input_from_stm[chl] = IDLE; + if ( link_available[chl] == TRUE ) + mtp3ObjState.tlac_state[chl] = TLAC_AVAILABLE_STATE; + else + mtp3ObjState.tlac_state[chl] = TLAC_UNAVAILABLE_STATE; + break; + + case TLAC_ADJACENT_SP_RESTART_ENDS: + break; + } + break; + + default: + break; + } +} + +void changeover_not_req(WORD chl) +{ + mtp3ObjState.tcoc_state[chl] = TCOC_IDLE_STATE; + mtp3ObjInput.lsac_input_from_tcoc[chl] = LSAC_TCOC_STM_READY; + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_TCOC_CHANGEOVER_NOT_REQ; + mtp3ObjInput.tsrc_input_from_tcoc[chl] = TSRC_TCOC_CHANGEOVER_NOT_REQ; +} + +void tcoc_proc(WORD chl) +{ + ls_info *ls; + int l2_input; + + ls = &mtp3.ls[mtp3_para->lk[chl].e1_to_linkset]; + + + switch (mtp3ObjState.tcoc_state[chl]) + { + case TCOC_IDLE_STATE: + switch (mtp3ObjInput.tcoc_input_from_stm[chl]) + { + case TCOC_LINK_UNAVAILABLE: + mtp3_debug(MTP3DB_EVENT,"[tcoc]link %d unavailable",chl); + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + mtp3ObjState.tcoc_state[chl] = TCOC_WAIT01_STATE; + mtp3ObjInput.tsrc_input_from_tcoc[chl] = TSRC_TCOC_ALTERNATIVE_ROUTING_DATA_REQUEST; + break; + + case TCOC_LINK_AVAILABLE: + break; + + case TCOC_TLAC_COO_COMMAND: +// mtp3_debug(MTP3DB_EVENT,"link %d rev coo",chl); + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + remote_bsnt_retrieved[chl] = TRUE; + mtp3ObjState.tcoc_state[chl] = TCOC_WAIT05_STATE; + break; + + case TCOC_TLAC_ECO_COMMAND: + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + remote_bsnt_retrieved[chl] = FALSE; + mtp3ObjState.tcoc_state[chl] = TCOC_WAIT05_STATE; + break; + + default: + break; + } + + switch (mtp3ObjInput.tcoc_input_from_hmdt[chl]) + { + case TCOC_HMDT_COA_COMMAND: + remote_bsnt_retrieved[chl] = TRUE; + mtp3ObjInput.tcoc_input_from_hmdt[chl] = IDLE; + mtp3_debug(MTP3DB_ERROR,"[tcoc]link %d RV COA IN IDLE STATE\n\r",chl); + break; + + case TCOC_HMDT_ECA_COMMAND: + remote_bsnt_retrieved[chl] = FALSE; + mtp3ObjInput.tcoc_input_from_hmdt[chl] = IDLE; + mtp3_debug(MTP3DB_ERROR,"[tcoc]link %d RV ECA IN IDLE STATE\n\r",chl); + break; + + default: + break; + } + break; + + case TCOC_WAIT01_STATE: + if (mtp3ObjInput.tcoc_input_from_stm[chl] == TCOC_LINK_AVAILABLE) + { + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + mtp3ObjInput.tcoc_input_from_tsrc[chl] = IDLE; + mtp3_debug(MTP3DB_ERROR,"[tcoc]link %d AVAILABLE AT WAIT1 STATE\n\r",chl); + changeover_not_req(chl); + } + else if ( mtp3ObjInput.tcoc_input_from_tsrc[chl] == TCOC_ALTERATIVE_ROUTE_DT ) + { + mtp3_debug(MTP3DB_EVENT,"[tcoc]link %d get routing data from tsrc",chl); +// printf("tcoc link %d route data\n",chl); + mtp3ObjInput.tcoc_input_from_tsrc[chl] = IDLE; + if ( changeover_required[chl] == TRUE ) + { + if ( co_msg_can_exchange[chl] == TRUE ) + { + co_msg_can_exchange[chl] = IDLE; +// mtp3_debug(MTP3DB_EVENT,"chl %d cc msg can exchange",chl); + if ( local_bsnt_retrievable[chl] == TRUE) + hmrt_tcoc_changeover_order(chl);/* send coo */ + else + { + hmrt_tcoc_emergency_changeover_order(chl); + mtp3ObjInput.lsac_input_from_tcoc[chl] = LSAC_TCOC_STOP_L2; + } + t2_delay_mtp3[chl] = mtp3_para->lt[chl].t2; + mtp3ObjState.tcoc_state[chl] = TCOC_WAITACK_STATE; + } + else if ( co_msg_can_exchange[chl] == FALSE ) + { + co_msg_can_exchange[chl] = IDLE; + t1_delay_mtp3[chl] = mtp3_para->lt[chl].t1; + mtp3ObjState.tcoc_state[chl] = TCOC_WAIT07_STATE; + } + } + else/* changeover not required */ + { + mtp3_debug(MTP3DB_EVENT,"[tcoc]link %d changeover not required,update routing table",chl); + hmrt_tcoc_update_routing_tables(chl); + } + } + break; + + case TCOC_WAIT05_STATE:/* wait for e1 l1 state change to unavailable */ + if (mtp3ObjInput.tcoc_input_from_stm[chl] == TCOC_LINK_AVAILABLE) + { + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + changeover_not_req(chl); +// mtp3_debug(MTP3DB_EVENT,"TCOC LINK %d AVAILABLE AT WAIT5 STATE",chl); + mtp3ObjState.tcoc_state[chl] = TCOC_IDLE_STATE; + } + else + { +/* if ( local_bsnt_retrievable[chl] == TRUE ) + hmrt_tcoc_changeover_ack(chl); + else*/ + hmrt_tcoc_emergency_changeover_ack(chl); + mtp3ObjInput.tsrc_input_from_tcoc[chl] = TSRC_TCOC_ALTERNATIVE_ROUTING_DATA_REQUEST; + mtp3ObjState.tcoc_state[chl] = TCOC_WAIT06_STATE; + send_command_to_mtp2(chl,MTP2_DEACTIVE_LINK); + } + break; + + case TCOC_WAIT06_STATE: + if (mtp3ObjInput.tcoc_input_from_stm[chl] == TCOC_LINK_AVAILABLE) + { + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + mtp3ObjInput.tcoc_input_from_tsrc[chl] = IDLE; + mtp3_debug(MTP3DB_ERROR,"[tcoc]link %d AVAILABLE AT WAIT6 STATE\n\r",chl); + changeover_not_req(chl); + } + else if ( mtp3ObjInput.tcoc_input_from_tsrc[chl] == TCOC_ALTERATIVE_ROUTE_DT ) + { + mtp3ObjInput.tcoc_input_from_tsrc[chl] = IDLE; +// mtp3_debug(MTP3DB_EVENT,"tcoc link %d get data",chl); + if ( remote_bsnt_retrieved[chl] == TRUE ) + { +// mtp3_debug(MTP3DB_EVENT,"chl %d retrieve begins in WAIT6",chl); + send_command_to_mtp2(chl,MTP2_RETRIEVE); + mtp3ObjState.tcoc_state[chl] = TCOC_RETRIEVING_STATE; + } + else + { + mtp3ObjState.tcoc_state[chl] = TCOC_SEND_BUFMSG_STATE; + } + } + break; + + case TCOC_WAIT07_STATE: + if (mtp3ObjInput.tcoc_input_from_stm[chl] == TCOC_LINK_AVAILABLE) + { + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + mtp3ObjInput.tcoc_input_from_tsrc[chl] = IDLE; + mtp3_debug(MTP3DB_ERROR,"[tcoc]link %d AVAILABLE AT WAIT07 STATE\n\r",chl); + changeover_not_req(chl); + } + else + { + + t1_delay_mtp3[chl] = t1_delay_mtp3[chl] - 1; + if ( t1_delay_mtp3[chl] == 0 ) + { + changeover_not_req(chl); + mtp3_debug(MTP3DB_EVENT,"[tcoc]link %d update routing table after T1 expired",chl); + hmrt_tcoc_update_routing_tables(chl); + } + } + break; + + case TCOC_WAITACK_STATE: + switch (mtp3ObjInput.tcoc_input_from_stm[chl]) + { + case TCOC_LINK_UNAVAILABLE: + break; + + case TCOC_LINK_AVAILABLE: + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + changeover_not_req(chl); + break; + + case TCOC_TLAC_COO_COMMAND: + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + if ( local_bsnt_retrievable[chl] == TRUE ) + hmrt_tcoc_changeover_ack(chl);/* send COA */ + else + hmrt_tcoc_emergency_changeover_ack(chl); + send_command_to_mtp2(chl,MTP2_RETRIEVE); +// mtp3_debug(MTP3DB_EVENT,"chl %d retrieve begins in WAITACK",chl); + mtp3ObjState.tcoc_state[chl] = TCOC_RETRIEVING_STATE; + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + break; + + case TCOC_TLAC_ECO_COMMAND: + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + if ( local_bsnt_retrievable[chl] == TRUE ) + hmrt_tcoc_changeover_ack(chl); + else + hmrt_tcoc_emergency_changeover_ack(chl); + mtp3ObjState.tcoc_state[chl] = TCOC_SEND_BUFMSG_STATE; + mtp3ObjInput.tcoc_input_from_hmdt[chl] = IDLE; + break; + + default: + break; + } + + switch (mtp3ObjInput.tcoc_input_from_hmdt[chl]) + { + case TCOC_HMDT_COA_COMMAND: + mtp3ObjInput.tcoc_input_from_hmdt[chl] = IDLE; + if (mtp3ObjState.tcoc_state[chl] == TCOC_WAITACK_STATE) + { +// mtp3_debug(MTP3DB_EVENT,"chl %d rv coa at waitack state",chl); + send_command_to_mtp2(chl,MTP2_RETRIEVE); + mtp3ObjState.tcoc_state[chl] = TCOC_RETRIEVING_STATE; + } + break; + + case TCOC_HMDT_ECA_COMMAND: + mtp3ObjInput.tcoc_input_from_hmdt[chl] = IDLE; + if (mtp3ObjState.tcoc_state[chl] == TCOC_WAITACK_STATE) + { + mtp3ObjState.tcoc_state[chl] = TCOC_SEND_BUFMSG_STATE; + } + break; + + default: + break; + } + + t2_delay_mtp3[chl] = t2_delay_mtp3[chl] - 1; + if ( t2_delay_mtp3[chl] == 0 ) + { +// mtp3_debug(MTP3DB_EVENT,"chl %d rv coa timeout waitack state",chl); + if (mtp3ObjState.tcoc_state[chl] == TCOC_WAITACK_STATE) + { + mtp3ObjInput.lsac_input_from_tcoc[chl] = LSAC_TCOC_STOP_L2; + mtp3ObjState.tcoc_state[chl] = TCOC_SEND_BUFMSG_STATE; + } + } + break; + + case TCOC_RETRIEVING_STATE: + l2_input = retrieved_bsnt[chl]; +/* if (l2_input == TCOC_L2_RETRIEVE_CMP) + {*/ + mtp3ObjState.tcoc_state[chl] = TCOC_SEND_BUFMSG_STATE; +/* } + else if (l2_input == TCOC_L2_RETRIEVE_NOT_POSSIBLE) + { + mtp3ObjState.tcoc_state[chl] = TCOC_SEND_BUFMSG_STATE; + }*/ + break; + + case TCOC_SEND_BUFMSG_STATE: + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_TCOC_CHANGEOVER_EXECUTED; + mtp3ObjInput.tsrc_input_from_tcoc[chl] = TSRC_TCOC_CHANGEOVER_EXECUTED; + mtp3ObjInput.tcoc_input_from_stm[chl] = IDLE; + mtp3ObjInput.tcoc_input_from_hmdt[chl] = IDLE; + mtp3ObjState.tcoc_state[chl] = TCOC_IDLE_STATE; /* IDLE STATE */ + mtp3ObjInput.lsac_input_from_tcoc[chl] = LSAC_TCOC_STM_READY; + hmrt_tcoc_update_routing_tables(chl); + mtp3_debug(MTP3DB_EVENT,"[tcoc]link %d update routing table after retrieved msg",chl); + break; + + default: + break; + } +} + +void changeback_terminated(WORD chl) +{ + mtp3ObjInput.tlac_input_from_stm[chl] = TLAC_TCBC_CHANGEBACK_TERMINATED; + mtp3ObjInput.tsrc_input_from_tcbc[chl] = TSRC_PROCEDURE_TERMINATED; + mtp3ObjState.tcbc_state[chl] = TCBC_IDLE_STATE; + mtp3_debug(MTP3DB_EVENT,"[tcbc]link %d change back complete,update routing table",chl); + hmrt_tcbc_update_routing_tables(chl); +} + +void tcbc_proc(WORD chl) +{ + ls_info *ls; + WORD lsno; + + ls = &mtp3.ls[mtp3_para->lk[chl].e1_to_linkset]; + + switch (mtp3ObjState.tcbc_state[chl]) + { + case TCBC_IDLE_STATE: + switch (mtp3ObjInput.tcbc_input[chl]) + { + case TCBC_LINK_UNAVAILABLE: + break; + + case TCBC_LINK_AVAILABLE: + mtp3_debug(MTP3DB_EVENT,"[tcbc]link %d available",chl); + mtp3ObjInput.tcbc_input[chl] = IDLE; + mtp3ObjInput.tsrc_input_from_tcbc[chl] = TSRC_TCBC_ALTERNATIVE_ROUTING_DATA_REQUEST; + mtp3ObjState.tcbc_state[chl] = TCBC_WAIT_FOR_ROUTING_DATA_STATE; + break; + + case TCBC_HMDT_CBD_COMMAND: + mtp3ObjInput.tcbc_input[chl] = IDLE; + hmrt_tcbc_changeback_ack(chl); + break; + + case TCBC_HMDT_CBA_COMMAND: + mtp3ObjInput.tcbc_input[chl] = IDLE; + break; + + default: + break; + } + break; + + case TCBC_WAIT_FOR_ROUTING_DATA_STATE: + if ( mtp3ObjInput.tcbc_input_from_tsrc[chl] == TCBC_ALTERATIVE_ROUTE_DT ) + { + mtp3_debug(MTP3DB_EVENT,"[tcbc]link %d get routing data from tsrc",chl); +// printf("tcbc link %d get data complete\n",chl); + mtp3ObjInput.tcbc_input_from_tsrc[chl] = IDLE; + lsno = mtp3_para->lk[chl].e1_to_linkset; + if ( tcbc_route_change[chl] == TRUE ) + { + if ( cb_msg_can_exchange[chl] == TRUE ) + /* adjacent sp acessible */ + { + hmrt_tcbc_changeback_declaration(chl); + t4_delay_mtp3[chl] = mtp3_para->lt[chl].t4; + mtp3ObjState.tcbc_state[chl] = TCBC_FIRST_ATTEMPT_STATE; + } + else + { +// mtp3_debug(MTP3DB_EVENT,"start t3"); + t3_delay_mtp3[chl] = mtp3_para->lt[chl].t3; + mtp3ObjState.tcbc_state[chl] = TCBC_TCTRL_DIVERSION_STATE; + } + } + else + { +// mtp3_debug(MTP3DB_EVENT,"error"); + mtp3ObjState.tcbc_state[chl] = TCBC_IDLE_STATE; + changeback_terminated(chl); + } + } + break; + + case TCBC_TCTRL_DIVERSION_STATE: + t3_delay_mtp3[chl] = t3_delay_mtp3[chl] - 1; + if ( t3_delay_mtp3[chl] == 0 ) + changeback_terminated(chl); + break; + + case TCBC_FIRST_ATTEMPT_STATE: + if ( mtp3ObjInput.tcbc_input[chl] == TCBC_HMDT_CBA_COMMAND ) + { +// mtp3_debug(MTP3DB_EVENT,"tcbc receive cba"); + mtp3ObjInput.tcbc_input[chl] = IDLE; + changeback_terminated(chl); + } + + t4_delay_mtp3[chl] = t4_delay_mtp3[chl] - 1; + if ( t4_delay_mtp3[chl] == 0 ) + { + if (mtp3ObjState.tcbc_state[chl] == TCBC_FIRST_ATTEMPT_STATE) + { + hmrt_tcbc_changeback_declaration(chl); + t5_delay_mtp3[chl] = mtp3_para->lt[chl].t5; + mtp3ObjState.tcbc_state[chl] = TCBC_SECOND_ATTEMPT_STATE; + } + } + break; + + case TCBC_SECOND_ATTEMPT_STATE: + t5_delay_mtp3[chl] = t5_delay_mtp3[chl] - 1; + if ( t5_delay_mtp3[chl] == 0 || + mtp3ObjInput.tcbc_input[chl] == TCBC_HMDT_CBA_COMMAND ) + { + mtp3ObjInput.tcbc_input[chl] = IDLE; + changeback_terminated(chl); + } + break; + + default: + break; + } +} + +void tprc_mgmt_signalling_point_restart_indication() +{ + int i,j; + // tprc to llsc restart begins + + for ( i=0; i> 6) == 2 ) + { + if ( (mtp3_para->nw[nw].routing[dst].normal_ls < 128) && + (mtp3_para->nw[nw].routing[dst].dpc != 0) ) + mtp3.nw[nw].rtpc_input[dst] = RTPC_DEST_INACCESSIBLE; + hmrt_tfrc_update_routing_tables(dst,tprc_nw); + } + } +} + +void tprc_fun2() +{ + tsrc_send_state_proc(tprc_nw); + tprc_nw++; + mtp3ObjState.tprc_state = TPRC_WAIT03_STATE; + t20_delay_mtp3 = mtp3_para->mtp3_t20; +} + +void tprc_proc()/* we always have stp function */ +{ + int i; + + switch (mtp3ObjState.tprc_state) + { + case TPRC_IDLE_STATE: + switch (mtp3ObjInput.tprc_input) + { + case TPRC_SP_RESTART_INDICATION: + mtp3ObjInput.tprc_input = IDLE; + mtp3ObjState.tprc_state = TPRC_WAIT01_STATE; + t18_delay_mtp3 = mtp3_para->mtp3_t18; + break; + + default: + break; + } + break; + + case TPRC_WAIT01_STATE: + t18_delay_mtp3 = t18_delay_mtp3 - 1; + if ( t18_delay_mtp3 == 0 )/* t18 expired */ + { + if (rv_TRA_num == active_ls_num) + tprc_fun2(); + else + { + t19_delay_mtp3 = mtp3_para->mtp3_t19;//start t19 + mtp3ObjState.tprc_state = TPRC_WAIT02_STATE; + } + } + else + { + if ( current_active_ls_num == active_ls_num) + { + if (rv_TRA_num == active_ls_num) + tprc_fun2(); + else + { + mtp3ObjState.tprc_state = TPRC_WAIT02_STATE; + t19_delay_mtp3 = mtp3_para->mtp3_t19; + } + } + } + break; + + case TPRC_WAIT02_STATE: + t19_delay_mtp3 = t19_delay_mtp3 - 1; + if ( t19_delay_mtp3 == 0 ) + { + tprc_fun2(); + } + break; + + case TPRC_WAIT03_STATE: + t20_delay_mtp3 = t20_delay_mtp3 - 1; + if ( t20_delay_mtp3 == 0 ) + { + for ( i=0; i= MAX_LS) + return; + nw = mtp3_para->ls_pro[linkset].nw_id; + sp = &mtp3.nw[nw]; + + switch (mtp3ObjInput.taprc_input[linkset]) + { + case TPRC_ADJACENT_SP_RESTARTING: + for (i=taprc_loop[linkset]; i<=taprc_loop[linkset]+7; i++) + { + if ((sp->routine[i] & 0x30) == 0)/* dst inaccessible */ + { + if ( (mtp3_para->nw[nw].routing[i].normal_ls < 128) && + (mtp3_para->nw[nw].routing[i].dpc != 0) ) + { + mtp3.nw[nw].rtpc_input[i] = RTPC_TSRC_SEND_TFP_MSG; + sdTFP_Ls = linkset;/* send TFP to this linkset's remote sp */ + rtpc_proc(nw,i); + } + } + } + taprc_loop[linkset] = taprc_loop[linkset] + 8; + if ( taprc_loop[linkset] == 0 ) + { + mtp3ObjInput.taprc_input[linkset] = IDLE; + sending_phase_finished[linkset] = TRUE; + hmrt_tra_msg(linkset); +// mtp3_debug(MTP3DB_EVENT,"Sd TFA to linkset %d remote sp",linkset); + } + break; + default: + break; + + } +} +/*@end@*/ diff --git a/plat/public/Makefile b/plat/public/Makefile new file mode 100644 index 0000000..373be1b --- /dev/null +++ b/plat/public/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = public +TYPE = plat + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = -DDEBUG + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/public/src/asn1.c b/plat/public/src/asn1.c new file mode 100644 index 0000000..d730d38 --- /dev/null +++ b/plat/public/src/asn1.c @@ -0,0 +1,943 @@ +/********************************************************************/ +/*Title: asn1.c */ +/*Descr: ASN.1 Encoding/Decoding Module */ +/*Author: Liang Hanxi */ +/*Create: 2002-1-15 */ +/*Version: */ +/*Modify: 2002-10-22 */ +/********************************************************************/ + + +#include "./include/asn1.h" +#include +#include +#include + +/*@ignore@*/ +void AsnEncode(u_char *msg_buf,u_int maxlen,ASN_BUF *asnbuf) +{ + asnbuf->msgbuf=msg_buf; + memset(msg_buf,0,2); + asnbuf->msglen=0; + asnbuf->maxlen=maxlen; +} + +void asn_encode(u_char *msg_buf,ASN_BUF *asnbuf) +{ + AsnEncode(msg_buf,256,asnbuf); +} + +void asn_encode_v3(u_char *msg_buf,u_int maxlen,ASN_BUF *asnbuf) +{ + AsnEncode(msg_buf,maxlen,asnbuf); +} + +int add_tlv(const char *tag_seq,u_int length,u_char *pvalue,u_char tlv_type,ASN_BUF *asnbuf) +{ + return AddTLV(tag_seq,length,pvalue,tlv_type,asnbuf); +} + +int AddTLV(const char *tag_seq,u_int length,u_char *pvalue,u_char tlv_type,ASN_BUF *asnbuf) +{ + u_short tags[100][2]; + int level; + int rest,swaplen=0,oldlen=0; + int ntag,nlen; + int addval,temp,i,rtn; //temp variable + u_char flag; //temp variable + u_char *ptlv,*pt,*ptr[100],asn_swap[1024]; + + if(asnbuf->msglen+length+5>asnbuf->maxlen) + { + printf("No room for new tlv.maxlen=%d,msglen=%d,addlen=%d\n",asnbuf->maxlen,asnbuf->msglen,length); + return -1; + } + /*search position for new data--->*/ + level = parse_tags(tag_seq,tags); + pt = asnbuf->msgbuf; //start pointer + rest = asnbuf->msglen % 1024; //remain length + for(i = 1; i < level; i++) + { + if(tags[i][1] == 0) //according to tagcode + rtn = findtlv(pt, tags[i][0], &ptlv, rest); + else //according to order + rtn = findtlv2(pt, tags[i][1], &ptlv, rest); + + if(rtn == -1) //length check error + return -1; + else if(rtn == 1) //not found,create it + { + swaplen = asnbuf->msglen - (ptlv - asnbuf->msgbuf); + if(swaplen > 0) + memcpy(asn_swap, ptlv, swaplen); + pt = ptlv; + while(i < level) + { + //printf("create level=%d\n",i); + ntag = addtagcode(pt, tags[i][0], 0xA0); + nlen = addlength(pt + ntag, 0); + ptr[i] = pt + ntag; + addval = modifylength(ptr, i - 1, ntag + nlen); + if(addval==(ntag+nlen+1)) + ptr[i]=pt+ntag+1;//reasigned ptr[i] + pt += addval; + asnbuf->msglen += addval; + i ++; + } + rest = 0; + } + else //found,continue + { + if((rtn & 0x20) == 0) + return -1; + + ntag=gettagcode(ptlv, (u_int *)&temp,&flag); + nlen=getlength(ptlv+ntag,&rest); + ptr[i]=ptlv+ntag; + pt=ptlv+ntag+nlen; + } + } + //insert new data + if(tags[level][1]==0) + { + rtn=findtlv(pt,tags[level][0],&ptlv,rest); + + if(rtn<0) + return -1; + else if(rtn!=1) + { + oldlen=0; + oldlen=gettagcode(ptlv, (u_int *)&temp,&flag); + oldlen+=getlength(ptlv+oldlen,&temp); + oldlen+=temp; + } + if(swaplen==0) + { + swaplen=asnbuf->msglen-(ptlv+oldlen-asnbuf->msgbuf); + if(swaplen>0) + memcpy(asn_swap,ptlv+oldlen,swaplen); + } + + ntag=addtagcode(ptlv,tags[level][0],tlv_type); + nlen=addlength(ptlv+ntag,length); + + memcpy(ptlv+ntag+nlen,pvalue,length); + //modify parent's length + addval=modifylength(ptr,level-1,ntag+nlen+length); + asnbuf->msglen+=addval; + ptlv+=addval; + + } + else + { + rtn=findtlv2(pt,tags[level][1],&ptlv,rest); + if(rtn<0) + return -1; + if(swaplen==0) + { + swaplen=asnbuf->msglen-(ptlv-asnbuf->msgbuf); + if(swaplen>0) + memcpy(asn_swap,ptlv,swaplen); + + } + ntag=addtagcode(ptlv,tags[level][0],tlv_type); + nlen=addlength(ptlv+ntag,length); + memcpy(ptlv+ntag+nlen,pvalue,length); + //modify parent's length + addval=modifylength(ptr,level-1,ntag+nlen+length); + asnbuf->msglen+=addval; + ptlv+=addval; + } + if(swaplen>0) + memcpy(ptlv,asn_swap,swaplen); + return asnbuf->msglen; +} + + +int asn_decode(u_char *msg_buf,int ntlv,ASN_BUF *asnbuf) +{ + return AsnDecode(msg_buf,256,ntlv,NULL,asnbuf); +} + +int asn_decode_v2(u_char *msg_buf,int ntlv,int *errpos,ASN_BUF *asnbuf) +{ + return AsnDecode(msg_buf,256,ntlv,errpos,asnbuf); +} + +int asn_decode_v3(u_char *msg_buf,int msglen,int *errpos,ASN_BUF *asnbuf) +{ + return AsnDecode(msg_buf,msglen,100,errpos,asnbuf); +} + +int AsnDecode(u_char *msg_buf,int msglen,int maxtlv,int *errpos,ASN_BUF *asnbuf) +{ + ASN_TLV *p1=NULL,*p2; + int ntlv=0,retval,sublen=0; + + asnbuf->msgbuf = msg_buf; + asnbuf->tlvcount=0; + asnbuf->pos = 0; + asnbuf->msglen = msglen; + asnbuf->errmsg[0]='\0'; + + while(asnbuf->pos < msglen && ntlvpos; + + retval=parse_tlv(&p2,asnbuf); + + if(retval<0) + { + return -1; + } + else if(retval==0) + { + return sublen; + } + else + { + if(p1!=NULL) + p1->pnext = p2; + p1 = p2; + sublen+=retval; + } + ntlv++; + } + if(errpos!=NULL) + *errpos = asnbuf->pos; + + return sublen; +} + +int get_tlv(const char *tag_seq,u_char *pvalue,ASN_BUF *asnbuf) +{ + return get_tlv_v2(tag_seq,pvalue,NULL,asnbuf); +} + +int get_tlv_v2(const char *tag_seq,u_char *pvalue,u_char *flag,ASN_BUF *asnbuf) +{ + u_short tags[30][2]; + int depth=1,order=1; + ASN_TLV *p1=&asnbuf->heap[0]; + parse_tags(tag_seq,tags); + + if(asnbuf->tlvcount < 1) + return -1; + + while(depthtagcode,tags[depth][0]); + if((p1->tagcode == tags[depth][0] || tags[depth][0]==0xFFFF) && (tags[depth][1]==0 || order==tags[depth][1])) + { + if(depth==tags[0][0]) + { + if(flag!=NULL) + *flag=p1->tagtype; + + if(p1->length < 0) + return -1; + else if(p1->length <= 256) + { + memcpy(pvalue,p1->pvalue,p1->length); + return p1->length; + } + else + { + memcpy(pvalue,p1->pvalue,256); + return 256; + } + } + else + { + if(p1->psub==NULL) + return -1; + p1=p1->psub; + depth++; + order=1; + } + } + else + { + if(p1->pnext == NULL) + return -1; + p1=p1->pnext; + order++; + } + } + return -1; +} + +int GetTLV(const char *tag_seq,int maxlen,u_char *pvalue,u_char flag,ASN_BUF *asnbuf) +{ + u_short tags[30][2]; + int depth=1,order=1; + ASN_TLV *p1=&asnbuf->heap[0]; + parse_tags(tag_seq,tags); + + if(asnbuf->tlvcount < 1) + return -1; + + while(depthtagcode,tags[depth][0]); + //printf("flag:%02X/%02X\n",p1->tagtype,flag); + if((p1->tagcode == tags[depth][0] || tags[depth][0]==0xFFFF) && (depthtagtype == flag) && (tags[depth][1]==0 || order==tags[depth][1])) + { + if(depth==tags[0][0]) + { + if(p1->length < 0) + return -1; + else if(p1->length <= maxlen) + { + memcpy(pvalue,p1->pvalue,p1->length); + return p1->length; + } + else + { + memcpy(pvalue,p1->pvalue,maxlen); + return maxlen; + } + } + else + { + if(p1->psub==NULL) + return -1; + p1=p1->psub; + depth++; + order=1; + } + } + else + { + if(p1->pnext == NULL) + return -1; + p1=p1->pnext; + order++; + } + } + return -1; +} + +int GetAnyTLV(const char *tag_seq,int maxlen,u_char *pvalue,u_char *pflag,u_short *ptagcode,ASN_BUF *asnbuf) +{ + u_short tags[30][2]; + int depth=1,order=1; + ASN_TLV *p1=&asnbuf->heap[0]; + parse_tags(tag_seq,tags); + + if(asnbuf->tlvcount < 1) + return -1; + + while(depthtagcode,tags[depth][0]); + //printf("flag:%02X/%02X\n",p1->tagtype,flag); + if((p1->tagcode == tags[depth][0] || tags[depth][0]==0xFFFF) && (tags[depth][1]==0 || order==tags[depth][1])) + { + if(depth==tags[0][0]) + { + if(pflag!=NULL) + *pflag = p1->tagtype; + if(ptagcode != NULL) + *ptagcode = p1->tagcode; + + if(p1->length < 0) + return -1; + else if(p1->length <= maxlen) + { + memcpy(pvalue,p1->pvalue,p1->length); + return p1->length; + } + else + { + memcpy(pvalue,p1->pvalue,maxlen); + return maxlen; + } + } + else + { + if(p1->psub==NULL) + return -1; + p1=p1->psub; + depth++; + order=1; + } + } + else + { + if(p1->pnext == NULL) + return -1; + p1=p1->pnext; + order++; + } + } + return -1; +} + +int parse_tlv(ASN_TLV **pnode,ASN_BUF *asnbuf) +//idefinite length +{ + int ntag,nlen,length,sublen=0,retval; + u_int tagcode; + u_char tagtype; + u_char *msgbuf=asnbuf->msgbuf; + ASN_TLV *ptlv,*p1=NULL,*p2; + + if(asnbuf->pos == asnbuf->msglen) + { + *pnode=NULL; + return 0; + } + + if(asnbuf->pos+2 > asnbuf->msglen || asnbuf->tlvcount >=256) + { + sprintf(asnbuf->errmsg,"Length check error(rest=%d)/exceed limit(tlvcount=%d)\n",asnbuf->msglen-asnbuf->pos,asnbuf->tlvcount); + return -1; + } + //printf("tlvcount=%d\n",asnbuf->tlvcount); + *pnode = ptlv = &asnbuf->heap[asnbuf->tlvcount++]; + ptlv->psub = ptlv->pnext = NULL; + ptlv->length = -1; + + if((ntag=gettagcode(msgbuf+asnbuf->pos,&tagcode,&tagtype))<1) + { + sprintf(asnbuf->errmsg,"Wrong encoding of tag(pos=%d:%02X %02X %02X)\n",asnbuf->pos,msgbuf[asnbuf->pos],msgbuf[asnbuf->pos+1],msgbuf[asnbuf->pos+2]); + return -1; + } + else + asnbuf->pos+=ntag; + + if((nlen=getlength(msgbuf+asnbuf->pos,&length))<1) + { + sprintf(asnbuf->errmsg,"Wrong encoding of Length(pos=%d:%02X %02X %02X)\n",asnbuf->pos,msgbuf[asnbuf->pos],msgbuf[asnbuf->pos+1],msgbuf[asnbuf->pos+2]); + return -1; + } + else + asnbuf->pos+=nlen; + + if(asnbuf->pos + length >asnbuf->msglen) + { + sprintf(asnbuf->errmsg,"Length Check error.length=%d,rest=%d(pos=%d:%02X %02X %02X)\n",length,asnbuf->msglen-asnbuf->pos,asnbuf->pos,msgbuf[asnbuf->pos],msgbuf[asnbuf->pos+1],msgbuf[asnbuf->pos+2]); + return -1; + } + + ptlv->tagtype=tagtype; + ptlv->tagcode=tagcode; + ptlv->pvalue=msgbuf+asnbuf->pos; + + if((tagtype & 0x20)==0) //primitive + { + if(length==-1) + { + sprintf(asnbuf->errmsg,"Wrong Encoding of Length:primitive form with indefinite length\n(pos=%d)",asnbuf->pos); + return -1; + } + else + { + ptlv->length = length; + asnbuf->pos += length; + return length+ntag+nlen; + } + } + else //constructor + { + if(length >=0) //short/long definite length + { + ptlv->length = length; + while(sublenerrmsg,"Length Check error.length=%d,sublen=%d(pos=%d:%02X %02X %02X)\n",length,sublen,asnbuf->pos,msgbuf[asnbuf->pos],msgbuf[asnbuf->pos+1],msgbuf[asnbuf->pos+2]); + return -1; + } + else + { + if(p1==NULL) + p1=ptlv->psub = p2; + else + { + p1->pnext = p2; + p1 = p2; + } + sublen+=retval; + } + } + if(sublen>length) + { + sprintf(asnbuf->errmsg,"Length Check error.length=%d,sublen=%d(pos=%d:%02X %02X %02X)\n",length,sublen,asnbuf->pos,msgbuf[asnbuf->pos],msgbuf[asnbuf->pos+1],msgbuf[asnbuf->pos+2]); + return -1; + } + ptlv->length = sublen; + return sublen+ntag+nlen; + } + else //indefinite length + { + while(msgbuf[asnbuf->pos]!=0 || msgbuf[asnbuf->pos+1]!=0) + { + retval=parse_tlv(&p2,asnbuf); + if(retval<0) + { + return -1; + } + else if(retval==0) + { + ptlv->length = sublen; + return sublen+ntag+nlen; + } + else + { + if(p1==NULL) + p1=ptlv->psub = p2; + else + { + p1->pnext = p2; + p1 = p2; + } + sublen+=retval; + } + } + asnbuf->pos += 2; + ptlv->length = sublen; + return sublen+ntag+nlen+2; + } + } + + +} + + +int findtlv(u_char *pasn,u_int tagcode,u_char **pnext,int rest) +//according to tagcode +{ + int ntag,nlen,nvalue,pos=0; + u_int curtag; + u_char type; + //printf("findtlv rest=%d\n",rest); + if(rest==0) + { + *pnext=pasn; + return 1; + } + else if(rest<0) + return -1; + ntag=gettagcode(pasn,&curtag,&type); + if((nlen=getlength(pasn+ntag,&nvalue)) < 0 || nvalue < 0) + return -1; + //printf("ntag=%d,nlen=%d,nvalue=%d\n",ntag,nlen,nvalue); + if(curtag0 && rest>0) + { + ntag=gettagcode((*pnext),&curtag,&type); + nlen=getlength((*pnext)+ntag, (int *)&nvalue); + (*pnext)+=(ntag+nlen+nvalue); + rest-=(ntag+nlen+nvalue); + } + + if(index==0 && rest>0) //found + { + ntag=gettagcode((*pnext),&curtag,&type); + return type; + } + else if(rest==0) //seek to end(not found) + return 1; + else + return -1; +} + +int gettagcode(u_char *asnbuf,u_int *tagcode,u_char *type) +{ + u_int pos=0; + *type=asnbuf[pos] & 0xE0; + *tagcode=asnbuf[pos] & 0x1F; + pos++; + if(*tagcode==0x1F) + { + *tagcode=0; + while((asnbuf[pos] & 0x80)==0x80 && pos<3) + { + *tagcode=(*tagcode) * 0x80 + (asnbuf[pos++] & 0x7F); + } + *tagcode=(*tagcode) * 0x80 + (asnbuf[pos++] & 0x7F); + } + return pos; +} + +int getlength(u_char *asnbuf,int *len) +{ + u_int pos=0,lenbyte; + + if((asnbuf[pos] & 0x80)==0) + *len=asnbuf[pos++] & 0x7F; + else + { + *len=0; + lenbyte=asnbuf[pos++] & 0x7F; + if(lenbyte>3 || lenbyte<0) + return -1; + + if(lenbyte==0) + { + *len=-1; + return 1; + } + else + { + while(lenbyte-->0) + *len=(*len)*0x100 + asnbuf[pos++]; + } + + } + + return pos; +} + +int addtagcode(u_char *msg_buf,u_int tagcode,u_char type) +{ + u_int tagbyte=0,pos=0; + int i=3; + u_char buf[4]; + msg_buf[pos]=type & 0xE0; + if(tagcode<31) + msg_buf[pos++]+=tagcode; + else + { + msg_buf[pos++]+=0x1F; + while(i>=0 && tagcode>0) + { + buf[i]=tagcode & 0x7F; + buf[i]|=0x80; + tagcode=tagcode >> 7; + i--; + } + buf[3]&=0x7F; + tagbyte=3-i; + memcpy(msg_buf+pos,buf+i+1,tagbyte); + pos+=tagbyte; + } + return pos; +} +int addlength(u_char *msg_buf,u_int len) +{ + u_int lenbyte=0,pos=0; + int i=3; + u_char buf[4]; + + if(len>=0 && len<=127) + msg_buf[pos++]=len; + else if(len>0) + { + while(i>=0 && len>0) + { + buf[i]=len & 0xFF; + len=len>>8; + i--; + } + lenbyte=3-i; + msg_buf[pos++]=lenbyte | 0x80; + memcpy(msg_buf+pos,buf+i+1,lenbyte); + pos+=lenbyte; + } + return pos; +} + +int parse_tags(const char *tag_seq,u_short (*tags)[2]) +{ + u_short i,j=0,level=1,len; + len=strlen(tag_seq); + + tags[1][0]=0xFFFF; + tags[1][1]=0; + for(i=0;ilenbyte1) + { + memcpy(swapbuf+2,ptr[level]+lenbyte1+2,len+addval-2); + memcpy(ptr[level]+lenbyte2,swapbuf,len+addval); + } + return modifylength(ptr,level-1,addval+lenbyte2-lenbyte1); +} + +void showbuf(u_char *buf,int len) +{ + int i; + for(i=0;i*/ +///////////////////////////////////////////////// +int add_bool(const char *tag_seq,u_char value,u_char tlv_type,ASN_BUF *asnbuf) +{ + return add_tlv(tag_seq,1,&value,tlv_type,asnbuf); +} + +u_char get_bool(const char *tag_seq,ASN_BUF *asnbuf) +{ + u_char pvalue[10]; + get_tlv(tag_seq,pvalue,asnbuf); + return pvalue[0]; +} + +int add_int(const char *tag_seq,int value,u_char tlv_type,ASN_BUF *asnbuf) +{ + return AddInteger(tag_seq,value,tlv_type,asnbuf); +} + +int AddInteger(const char *tag_seq,int value,u_char tlv_type,ASN_BUF *asnbuf) +{ + u_char buf[4]; + u_int *p_uint=(u_int *)buf; + int i; + + *p_uint=htonl(value); + + if(value<0) + { + for(i=0;i<4;i++) + { + if(buf[i]!=0xFF) + { + if((buf[i] & 0x80)==0) + i--; + break; + } + } + } + else + { + for(i=0;i<4;i++) + { + if(buf[i]!=0) + { + if((buf[i] & 0x80)==0x80) + i--; + break; + } + } + } + + if(i>=4) + i=3; + + return add_tlv(tag_seq,4-i,buf+i,tlv_type,asnbuf); +} + +int GetInteger(const char *tag_seq,int *rtn,u_char flag,ASN_BUF *asnbuf) +{ + u_char pvalue[10]; + int length,i; + length=GetTLV(tag_seq,5,pvalue,flag,asnbuf); + if(length==-1) + return -1; + + if((pvalue[0] & 0x80)==0x80) + *rtn=-1; + else + *rtn=0; + + for(i=0;i=0) + return 1; + else + return -1; +} +int add_oid(const char *tag_seq,const char *oidstr,u_char tlv_type,ASN_BUF *asnbuf) +{ + u_char pvalue[50],buf[4]; + int oid[20],len,i,j,level=0,pos=0; + len=strlen(oidstr); + memset(oid,0,sizeof(oid)); + for(i=0;i>7; + j--; + }while(oid[i]>0 && j>=0); + buf[3]&=0x7F; + len=3-j; + memcpy(pvalue+pos,buf+j+1,len); + pos+=len; + } + return add_tlv(tag_seq,pos,pvalue,tlv_type,asnbuf); +} + +int get_oid(const char *tag_seq,char *oid,ASN_BUF *asnbuf) +{ + u_char pvalue[50]; + char tempstr[50],firstoctet=1; + int length,i,temp=0; + length=get_tlv(tag_seq,pvalue,asnbuf); + + if(length<=0) + return -1; + + for(i=0;i 0) + { + len--; + ptr[i] = buf[len]; + } + else + ptr[i] = pad; + } + return ret; +} +/*@end@*/ diff --git a/plat/public/src/asn1per.c b/plat/public/src/asn1per.c new file mode 100644 index 0000000..e22cbdc --- /dev/null +++ b/plat/public/src/asn1per.c @@ -0,0 +1,444 @@ +/* + * asn1per.c + * + * Copyright (C) 2010 Altobridge, Inc + * Written by: Xiaohua Chen + * + * Specs: ITU-T X.691 + */ + +#include +#include "./include/asn1per.h" + +const unsigned char NB[256] = {0,1,1, + 2,2, + 3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + +const unsigned char MB[9] = {0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; + +static int pe_bit(unsigned char *pdst, bool value, unsigned char *offset_bit) +{ + int offset = 0; + pdst[offset]|= (value << (7- (*offset_bit))); + (*offset_bit)++; + if((*offset_bit) == 8){offset++;*offset_bit=0;} + return offset; +} + +static int pd_bit(unsigned char *psrc, bool *value, unsigned char *offset_bit) +{ + int offset = 0; + *value = (psrc[offset] >> (7-(*offset_bit))) & 0x01; + (*offset_bit)++; + if((*offset_bit) == 8){offset++;*offset_bit=0;} + return offset; +} + +/************************************************************** + * + * Length determinant + * + **************************************************************/ +int per_decode_Length(unsigned int *plen, unsigned char *psrc) +{ + int offset = 0, m = 0; + + if((psrc[offset] & 0xc0) == 0xc0){ + m = psrc[offset] & 0x3F; + *plen = m * 16384; + offset++; + } + else if((psrc[offset] & 0x80) == 0x80){ + *plen = ((psrc[offset] & 0x3F) << 8)+psrc[offset+1]; + offset+=2; + } + else{ + *plen = psrc[offset]; + offset++; + } + return offset; +} + +int per_encode_Length(unsigned char *pdst, int len) +{ + int offset = 0; + + if(len > 0x7F){ + pdst[offset++] = 0x80|((len >> 8) & 0x7F); + pdst[offset++] = len & 0xff; + } + else{ + pdst[offset++] = len; + } + return offset; +} + +/************************************************************** + * + * Open type fields + * + **************************************************************/ + +int per_decode_OpenType(ASN1OpenType *popen, unsigned char *psrc) +{ + int offset = 0; + + offset = per_decode_Length(&popen->len, psrc); + popen->pdata = psrc+offset; + offset+=popen->len; + + return offset; +} + +int per_encode_OpenType(unsigned char *pdst, ASN1OpenType *popen) +{ + int offset = 0; + offset = per_encode_Length(pdst, popen->len); + memcpy(pdst+offset, popen->pdata, popen->len); + offset+=popen->len; + + return offset; +} + +/************************************************************** + * + * The Boolean type + * + **************************************************************/ + +int per_encode_Boolean(unsigned char *pdst, bool value, unsigned char *offset_bit) +{ + int offset = 0; + + value &= 0x01; + pdst[offset]|= (value << (7- (*offset_bit))); + (*offset_bit)++; + if((*offset_bit) == 8){offset++;*offset_bit=0;} + return offset; +} + +int per_decode_Boolean(unsigned char *psrc, bool *value, unsigned char *offset_bit) +{ + int offset = 0; + + *value = (psrc[offset] >> (7-(*offset_bit))) & 0x01; + (*offset_bit)++; + if((*offset_bit) == 8){offset++;*offset_bit=0;} + return offset; +} + +/************************************************************** + * + * Constrained Interger (Note: it only handles integers that fit inside a 32 bit integer) + * + **************************************************************/ + +int per_encode_Constrained_Integer(unsigned char *pdst, unsigned int value, + unsigned int lower, unsigned int upper, unsigned char *offset_bit) +{ + int offset = 0, nbs = 0, m = 0, i, j; + unsigned char bl[16]; + unsigned int r, tmp = 0; + + r = upper - lower + 1; + + if((upper-lower) == 4294967295UL) + r = 4294967295UL; + + //if r=0 then return; + if(r == 1){ + nbs = 1; + offset+=pe_bit(pdst+offset, 0, offset_bit); + } + else if (r < 256) + { + nbs = NB[r]; + m = MB[nbs]; + + j = 0; + tmp = (value - lower) & m; + for(i = nbs-1; i >=0; i--){ + bl[j++] = (tmp >> i) & 0x01; + } + for (i = 0; i < nbs; i++){ + offset+=pe_bit(pdst+offset, bl[i], offset_bit); + } + } + else if (r == 256) + { + nbs = 8; + if((*offset_bit) > 0) {offset++; *offset_bit = 0;} + tmp = (value - lower) & 0xff; + pdst[offset++] = tmp; + } + else if (r<=65536) + { + nbs = 16; + if((*offset_bit) > 0) {offset++; *offset_bit = 0;} + tmp = (value - lower) & 0xffff; + + pdst[offset++] = (tmp >> 8) & 0xff; + pdst[offset++] = tmp & 0xff; + } + else { + int on; + bool b0, b1; + + tmp = value - lower; + if(tmp < 0x100) {on = 1; b0 = 0; b1 = 0;} + else if(tmp < 0x10000) {on = 2; b0 = 0; b1 = 1;} + else if(tmp < 0x1000000) {on = 3; b0 = 1; b1 = 0;} + else {on = 4; b0 = 1; b1 = 1;} + + offset+=pe_bit(pdst+offset, b0, offset_bit); + offset+=pe_bit(pdst+offset, b1, offset_bit); + if((*offset_bit) > 0) {offset++; *offset_bit = 0;} + + if(on == 1) {pdst[offset] = tmp & 0xff; offset++;} + else if(on == 2) {pdst[offset] = (tmp >> 8) & 0xff; pdst[offset+1] = tmp & 0xff;offset+=2;} + else if(on == 3) {pdst[offset] = (tmp >> 16) & 0xff; pdst[offset+1] = (tmp >> 8) & 0xff; pdst[offset+2] = tmp & 0xff;offset+=3;} + else {pdst[offset] = (tmp >> 24) & 0xff;pdst[offset+1] = (tmp >> 16) & 0xff; pdst[offset+2] = (tmp >> 8) & 0xff; pdst[offset+3] = tmp & 0xff;offset+=4;} + } + + return offset; +} + +int per_decode_Constrained_Integer(unsigned char *psrc, unsigned int *value, + unsigned int lower, unsigned int upper, unsigned char *offset_bit) +{ + int offset = 0, nbs = 0, m = 0, i, j; + unsigned char bl[16]; + unsigned int r, tmp = 0; + + r = upper - lower + 1; + + if((upper-lower) == 4294967295UL) + r = 4294967295UL; + + if(r==1){ + nbs = 1; + offset+=pd_bit(psrc+offset, &bl[0], offset_bit); + *value = bl[0]; + } + else if (r < 256) + { + nbs = NB[r]; + m = MB[nbs]; + + j = 0; + for (i = 0; i < nbs; i++){ + offset+=pd_bit(psrc+offset, &bl[i], offset_bit); + } + for(i = nbs-1; i >=0; i--){ + tmp += (bl[j++] << i); + } + *value = tmp + lower; + } + else if (r == 256) + { + nbs = 8; + if((*offset_bit) > 0) {offset++; *offset_bit = 0;} + tmp = psrc[offset++]; + *value = tmp + lower; + } + else if (r<=65536) + { + nbs = 16; + if((*offset_bit) > 0) {offset++; *offset_bit = 0;} + tmp = (psrc[offset] << 8) + psrc[offset+1]; + *value = tmp + lower; + offset+=2; + } + else { + int on; + bool b0, b1; + + offset+=pd_bit(psrc+offset, &b0, offset_bit); + offset+=pd_bit(psrc+offset, &b1, offset_bit); + if((*offset_bit) > 0) {offset++; *offset_bit = 0;} + + if((b0 == 0)&&(b1 == 0)){on = 1;} + else if((b0 == 0)&&(b1 == 1)) {on = 2;} + else if((b0 == 1)&&(b1 == 0)) {on = 3;} + else {on = 4;} + + if(on == 1) {tmp = psrc[offset]; offset++;} + else if(on == 2) { tmp = (psrc[offset] << 8) + psrc[offset+1]; offset+=2;} + else if(on == 3) { tmp = (psrc[offset] << 16) + (psrc[offset+1] << 8)+psrc[offset+2];offset+=3;} + else {tmp = (psrc[offset] << 24) + (psrc[offset+1] << 16) + (psrc[offset+2] << 8) + psrc[offset+3];offset+=4;} + *value = tmp + lower; + } + return offset; +} + +/************************************************************** + * + * BIT STRING + * + **************************************************************/ + +int per_encode_BitString(unsigned char *pdst, unsigned int numbits, unsigned char *pdata) +{ + int offset = 0, octlen = 0; + + octlen = numbits >> 3; + if(numbits % 8) + octlen++; + memcpy(pdst, pdata, octlen); + offset+=octlen; + return offset; +} + +int per_decode_BitString(unsigned char *psrc, unsigned int numbits, unsigned char *pdata) +{ + int offset = 0, octlen = 0; + octlen = numbits >> 3; + if(numbits % 8) + octlen++; + memcpy(pdata, psrc, octlen); + offset+=octlen; + return offset; +} + +int per_encode_BitStr16(unsigned char *pdst, unsigned char *value, unsigned int lbits, unsigned int ubits, unsigned char *offset_bit) +{ + int offset = 0, i, j; + unsigned char b1[16]; + unsigned int tmp; + + if((ubits == lbits) && (ubits <=16)){ + j = 0; + if(ubits > 8) + tmp = (value[0] << 8)+value[1]; + else + tmp = value[0]; + for(i = ubits-1; i >=0; i--){ + b1[j++] = (tmp >> i) & 0x01; + } + for (i = 0; i < ubits; i++){ + offset+=pe_bit(pdst+offset, b1[i], offset_bit); + } + } + return offset; +} + +int per_decode_BitStr16(unsigned char *psrc, unsigned char *value, unsigned int lbits, unsigned int ubits, unsigned char *offset_bit) +{ + int offset = 0, i, j; + unsigned char b1[16]; + unsigned int tmp = 0; + + if((ubits == lbits) && (ubits <=16)){ + j = 0; + for (i = 0; i < ubits; i++){ + offset+=pd_bit(psrc+offset, &b1[i], offset_bit); + } + for(i = ubits-1; i >=0; i--){ + tmp += (b1[j++] << i); + } + if(ubits > 8){value[0] = (tmp >> 8) & 0xff; value[1] = tmp & 0xff;} + else {value[0] = tmp & 0xff;} + } + return offset; +} + +/************************************************************** + * + * OCTET STRING + * + **************************************************************/ + +int per_encode_OctetString(unsigned char *pdst, unsigned int numocts, unsigned char *pdata) +{ + int offset = 0; + + memcpy(pdst, pdata, numocts); + offset+=numocts; + return offset; +} + +int per_decode_OctetString(unsigned char *psrc, unsigned int numocts, unsigned char *pdata) +{ + int offset = 0; + + memcpy(pdata, psrc, numocts); + offset+=numocts; + return offset; +} + +/************************************************************** + * + * Normally Small Non-Negative Whole Number + * + **************************************************************/ + +int per_encode_SmallNonNegWholeNumber(unsigned char *pdst, unsigned int value, unsigned char *offset_bit) +{ + int offset = 0, i, j; + bool sn = 0; + unsigned char b1[8]; + + if(value > 63) + sn = 1; + + offset+=pe_bit(pdst+offset, sn, offset_bit); + if(!sn){ + j = 0; + for(i = 5; i >=0; i--){ + b1[j++] = (value >> i) & 0x01; + } + for (i = 0; i < 6; i++){ + offset+=pe_bit(pdst+offset, b1[i], offset_bit); + } + } + else{ + if((*offset_bit) > 0) offset++; + if(value > 0x7f){pdst[offset++] = 0x80|((value << 8) & 0x7f); pdst[offset++] = value & 0xff;} + else {pdst[offset++] = value & 0xff;} + } + return offset; +} + +int per_decode_SmallNonNegWholeNumber(unsigned char *psrc, unsigned int *value, unsigned char *offset_bit) +{ + int offset = 0, i, j; + bool sn = 0; + unsigned char b1[8]; + unsigned int tmp = 0; + + offset+=pd_bit(psrc+offset, &sn, offset_bit); + + if(!sn){ + j = 0; + + for (i = 0; i < 6; i++){ + offset+=pd_bit(psrc+offset, &b1[i], offset_bit); + } + for(i = 5; i >=0; i--){ + tmp += (b1[j++] << i); + } + *value = tmp; + } + else{ + if((*offset_bit) > 0) offset++; + if((psrc[offset] & 0x80) == 0x80){ + *value = ((psrc[offset] & 0x3F) << 8)+psrc[offset+1]; + offset+=2; + } + else{ + *value = psrc[offset]; + offset++; + } + } + return offset; +} + diff --git a/plat/public/src/bisearch.c b/plat/public/src/bisearch.c new file mode 100644 index 0000000..85f6231 --- /dev/null +++ b/plat/public/src/bisearch.c @@ -0,0 +1,199 @@ + +/******************************************/ +/*Title : bisearch.h */ +/*Descr : BiSearch arithmetic implement */ +/*Author : Liu Wei */ +/*Create : 2006-12-13 */ +/*Version : R1V00_01 */ +/*Modify : 2006-12-13 */ +/******************************************/ +#include "memory.h" +#include "malloc.h" +#include "stdlib.h" +#include "./include/bisearch.h" + +/*@ignore@*/ + +int BISearchReg ( BiSearchArray *pBSA, int nTotalSize , void *GetIdleNodeFunc ) +{ + if( pBSA == NULL ) + exit(0); + memset( pBSA , 0 , sizeof(BiSearchArray) ); + pBSA->nArrayCount = 0; + pBSA->nArrayTotalLen = nTotalSize; + pBSA->pBiArray = malloc( sizeof(BiSearch)*nTotalSize ); + memset ( pBSA->pBiArray, 0, BS_SIZE * nTotalSize ); + pBSA->GetIdleNodeFunc = (int (*)(int *))GetIdleNodeFunc; + return 1; +} + +int BISearchUnReg ( BiSearchArray * pBSA) +{ + if( pBSA !=NULL && pBSA->pBiArray != NULL ) + { + free(pBSA->pBiArray); + return 1; + } + return 0; +} + +int BSearch ( BiSearchArray * pBSA, int nStart, int nEnd, LL llKey, int * nPosResult ) +{ + BiSearch *pArray ; + int nPos = -1; + + if( pBSA == NULL ) + + return 0; + if( nStart < 0 || nEnd < 0 || nStart > nEnd || pBSA->nArrayCount < nStart ) + { + return 0; + } + + pArray = pBSA->pBiArray; + if( !pBSA->nArrayCount ) + return (*nPosResult = 0); + if( nEnd > pBSA->nArrayCount-1 ) + nEnd = pBSA->nArrayCount-1; + + for ( nPos = nStart; nStart <= nEnd; nPos = ( nStart + nEnd ) / 2 ) + { + if( pArray[nPos].llKey == llKey ) + { + *nPosResult = nPos; + return 1; + } + if( pArray[nPos].llKey > llKey ) + { + nEnd = nPos - 1; + } + if( pArray[nPos].llKey < llKey ) + { + nStart = nPos + 1; + } + } + if( nPos != -1 && pArray[nPos].llKey < llKey ) + nPos++; + *nPosResult = nPos; + return 0; +} + +int BSearchArray ( BiSearchArray * pBSA, LL llKey, int *nPosResult ) +{ + if( pBSA == NULL ) + return 0; + + return BSearch ( pBSA, 0, (pBSA->nArrayCount > 0 ? pBSA->nArrayCount-1 : 0), llKey, nPosResult ); +} + +int BISInsert ( BiSearchArray * pBSA, LL llKey, int nDUPosIndex ) +{ + int nPos = -1; + + if( pBSA == NULL ) + return 0; + + //memery protect: Data Unit Index exceed Data Unit Array Length + if( nDUPosIndex > pBSA->nArrayTotalLen || nDUPosIndex < 0) + return 0; + + if( pBSA->nArrayCount >= pBSA->nArrayTotalLen ) //Array Full + return 0; + + if( !BSearchArray ( pBSA , llKey, &nPos ) && nPos != -1 ) + { + BiSearch *pBS = pBSA->pBiArray + nPos ; + + memmove ( pBS + 1, pBS , BS_SIZE * ( pBSA->nArrayCount - nPos ) ); + pBS->llKey = llKey; + pBS->nDUPosIndex = nDUPosIndex; + pBSA->nArrayCount++; + return 1; + + } + //The Key is existed, insert fail. + return 0; +} + +int BISDelete ( BiSearchArray * pBSA, LL llKey ) +{ + int nPos = -1; + + if( pBSA == NULL ) + return 0; + + if( pBSA->nArrayCount <= 0 ) + return 0; + + if( BSearchArray ( pBSA ,llKey, &nPos ) ) + { + BiSearch *pBS = pBSA->pBiArray + nPos; + + memmove ( pBS, pBS + 1, BS_SIZE * ( pBSA->nArrayCount - nPos ) ); + memset ( pBSA->pBiArray + pBSA->nArrayCount, 0, BS_SIZE ); + pBSA->nArrayCount--; + return 1; + } + return 0; +} + +int BISSearch ( BiSearchArray * pBSA, LL llKey , int* nDUPosIndex) +{ + int nPos = -1; + + if( pBSA == NULL ) + return 0; + + if( BSearchArray ( pBSA ,llKey, &nPos ) ) + { + *nDUPosIndex = pBSA->pBiArray[nPos].nDUPosIndex; + if( *nDUPosIndex > pBSA->nArrayTotalLen ) + return 0; + return 1; + } + return 0; +} + + +int GetBISearchCount ( BiSearchArray * pBSA) +{ + if( pBSA == NULL ) + return 0; + + return pBSA->nArrayCount; +} + +int GetDUIndex ( BiSearchArray * pBSA, int nBIIndex) +{ + if( pBSA == NULL ) + return 0; + + if( nBIIndex >= pBSA->nArrayCount ) + return -1; + else + return pBSA->pBiArray[nBIIndex].nDUPosIndex; +} + +int BISSearchMng( BiSearchArray * pBSA, BIS_OP mng_type,LL llkey, int* nDUIndex ) +{ + switch( mng_type ) + { + case BIS_INIT: + return BISInsert( pBSA , llkey , *nDUIndex ); + case BIS_SEARCH: + return BISSearch( pBSA , llkey , nDUIndex ); + case BIS_INSERT: + if( pBSA->GetIdleNodeFunc != NULL && pBSA->GetIdleNodeFunc( nDUIndex ) ) + return BISInsert( pBSA , llkey , *nDUIndex ); + break; + case BIS_DELETE: + return BISDelete( pBSA, llkey); + break; + default: + return 0; + } + return 1; +} + +/*@end@*/ + diff --git a/plat/public/src/cdr.c b/plat/public/src/cdr.c new file mode 100644 index 0000000..8720bab --- /dev/null +++ b/plat/public/src/cdr.c @@ -0,0 +1,453 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./include/cdr.h" +#include "./include/pub_time.h" + +static _cdr_vm_struct *cdr_vm_ptr; +static int cdr_sem_id; +static _cdr_param cdr_param; +static unsigned char cdr_time[8]; +static int cdr_counter0=0,cdr_counter1=0; +static int ssn_counter[256]; + +int cdr_config(); +int cdr_open_all_new_fd(); +int clean_expired_backup_file(); +int cdr_backup(); +extern void *shm_init(int shm_id, char *prog_name, key_t key, int size, int shmflg); +extern int sem_init(char *prog_name, key_t key, int sem_num, int sem_flg); +extern void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len); +int cdr_init(char plane_id, char type_flag) /* type=0/1: slave(MSS), master */ +{ + int cdr_shm_id = 0; + + GetCurrentTime(cdr_time); + + cdr_vm_ptr = (_cdr_vm_struct *)shm_init(cdr_shm_id, + "cdr_init", + CDR_SHM_KEY, + sizeof(_cdr_vm_struct), + CDR_SHM_PERM|IPC_CREAT); + cdr_sem_id = sem_init("cdr_init", CDR_SEM_KEY, 1, CDR_SEM_PERM|IPC_CREAT ); + + if(type_flag == 0) + { + memset(cdr_vm_ptr, 0x00, sizeof(_cdr_vm_struct)); + cdr_vm_ptr->plane_id = plane_id; + } + else + { + cdr_config(); + cdr_vm_ptr->plane_id = cdr_param.system_id; + } + + return 0; +} + +int cdr_timer() +{ + static int cdr_timer_counter = 0; + + if(cdr_timer_counter++%200 == 0) /*every 2 seconds */ + { + GetCurrentTime(cdr_time); + if(cdr_time[4] == 0 && cdr_time[5]>0 && cdr_time[5] <= 2) + { + cdr_open_all_new_fd(); + } + if(cdr_time[3] == 0 && cdr_time[4] ==0 && cdr_time[5] <= 2) + { + clean_expired_backup_file(); + } + } + + cdr_backup(); + return 1; +} + +/* -------- initialisation functions *---------- */ +_cdr_param default_param= +{ + 0, + "/usr/local/backup/cdr", + ".csv", + 0, + 7, +}; + +int cdr_open_ssn_file(int index) +{ + char *file_name, file_name0[128],file_name_new[128]; + + if(!cdr_param.ssn_param[index].ssn) + return 0; + file_name = &file_name0[0]; + + if(cdr_param.max_records_per_file == 0) + { + sprintf(file_name,"%s/cdrFrom%s%d_%d_%02d_%02d_%02d%s", + cdr_param.base_dir, + cdr_param.ssn_param[index].name, + cdr_vm_ptr->plane_id, + cdr_time[0]+2000, + cdr_time[1], + cdr_time[2], + cdr_time[3], + cdr_param.file_suffix); + } + else + { + if(cdr_param.init_flag == 0) + { + DIR *dp; + struct dirent *dirp; + int no=0; + + if((dp=opendir(cdr_param.base_dir))==NULL) + printf("can't open %s",cdr_param.base_dir); + + while (((dirp=readdir(dp))!=NULL)) + { + sprintf(file_name_new,"cdrFrom%s%d_%d_%02d_%02d_%02d", + cdr_param.ssn_param[index].name, + cdr_vm_ptr->plane_id, + cdr_time[0]+2000, + cdr_time[1], + cdr_time[2], + cdr_time[3]); + no = 0; + if(!strncasecmp(dirp->d_name,file_name_new,strlen((char *)file_name_new))) + { + while(1) + { + sprintf(file_name,"%s_%d%s", + file_name_new, + no, + cdr_param.file_suffix); + if(strncasecmp(dirp->d_name,file_name,strlen((char *)file_name)<0)) + break; + else if(!strncasecmp(dirp->d_name,file_name,strlen((char *)file_name))) + { + if((no+1)>cdr_param.ssn_param[index].file_sn) /* a new file */ + cdr_param.ssn_param[index].file_sn = no+1; + break; + } + no++; + } //while + } //if + }//while + + closedir(dp); + + sprintf(file_name,"%s/cdrFrom%s%d_%d_%02d_%02d_%02d_%d%s", + cdr_param.base_dir, + cdr_param.ssn_param[index].name, + cdr_vm_ptr->plane_id, + cdr_time[0]+2000, + cdr_time[1], + cdr_time[2], + cdr_time[3], + cdr_param.ssn_param[index].file_sn++, + cdr_param.file_suffix); + } + else + { + sprintf(file_name,"%s/cdrFrom%s%d_%d_%02d_%02d_%02d_%d%s", + cdr_param.base_dir, + cdr_param.ssn_param[index].name, + cdr_vm_ptr->plane_id, + cdr_time[0]+2000, + cdr_time[1], + cdr_time[2], + cdr_time[3], + cdr_param.ssn_param[index].file_sn++, + cdr_param.file_suffix); + } + } + + strcpy(cdr_param.ssn_param[index].file_name,file_name); + + if(cdr_param.ssn_param[index].fd != NULL) + fclose(cdr_param.ssn_param[index].fd); + + cdr_param.ssn_param[index].fd = fopen(file_name,"a+b"); + cdr_param.ssn_param[index].total_records = 0; + + return 1; +} + +int cdr_open_all_new_fd() +{ + int index; + + for(index=0;index=MAX_CDR_APP_NUM) continue; + + if(!strncasecmp(s,"ssn=",4)) + { + cdr_param.ssn_param[index].ssn = atoi(&s[4]); + continue; + } + if(!strncasecmp(s,"name=",5)) + { + strcpy(cdr_param.ssn_param[index].name,&s[5]); + } + } + fclose(fp); + + for(index=0;indexd_name); + stat(name,&fileinfo); + + if(time(NULL)>=(fileinfo.st_mtime+cdr_param.max_days*3600*24) ) + { + remove(name); + } + } + closedir(dp); + + return 1; +} +/* -------- END of initialisation functions *----*/ + +/* ------- CDR submit & write file--------------*/ + +int cdr_submit1(unsigned char ssn, unsigned short length, char *data) +{ + int head, tail; + _cdr_record *ptr=NULL; + + head = cdr_vm_ptr->head_ptr; + tail = cdr_vm_ptr->tail_ptr; + + ptr = &cdr_vm_ptr->cdr_data[head]; + ptr->ssn = ssn; + ptr->length = length%CDR_RECORD_SIZE; + memcpy(ptr->data, data , ptr->length); + + // sem_lock(cdr_sem_id, 1, 1, IPC_NOWAIT); + cdr_vm_ptr->head_ptr ++; + if(cdr_vm_ptr->head_ptr>=MAX_CDR_RECORDS) + cdr_vm_ptr->head_ptr = 0; +/* + if(cdr_vm_ptr->head_ptr == tail) + { + cdr_vm_ptr->tail_ptr ++; + if(cdr_vm_ptr->tail_ptr>=MAX_CDR_RECORDS) + cdr_vm_ptr->tail_ptr = 0; + } +*/ + // sem_unlock(cdr_sem_id, 1, 1, IPC_NOWAIT); + + cdr_counter0++; + ssn_counter[ssn]++; + return 1; +} + +int cdr_submit(unsigned char ssn, unsigned short length, char *data) +{ + int head, tail; + _cdr_record *ptr=NULL; + + head = cdr_vm_ptr->head_ptr; + tail = cdr_vm_ptr->tail_ptr; + + ptr = &cdr_vm_ptr->cdr_data[head]; + ptr->ssn = ssn; + ptr->length = length%CDR_RECORD_SIZE; + memcpy(ptr->data, data , ptr->length); + + // sem_lock(cdr_sem_id, 1, 1, IPC_NOWAIT); + cdr_vm_ptr->head_ptr ++; + if(cdr_vm_ptr->head_ptr>=MAX_CDR_RECORDS) + cdr_vm_ptr->head_ptr = 0; +/* + if(cdr_vm_ptr->head_ptr == tail) + { + cdr_vm_ptr->tail_ptr ++; + if(cdr_vm_ptr->tail_ptr>=MAX_CDR_RECORDS) + cdr_vm_ptr->tail_ptr = 0; + } +*/ + // sem_unlock(cdr_sem_id, 1, 1, IPC_NOWAIT); + + cdr_counter1++; + ssn_counter[ssn]++; + return 1; +} + +int cdr_get_ssn_index(unsigned char ssn) +{ + int i; + + for(i=0;issn))<0) + return 0; + if(index >= MAX_CDR_APP_NUM) + return 0; + + if(cdr_param.ssn_param[index].fd == NULL) + return 0; + + BcdToAscii(data, (BYTE *)ptr->data,(ptr->length%CDR_RECORD_SIZE)*2); + + fprintf(cdr_param.ssn_param[index].fd,"%s\n",data); + cdr_param.ssn_param[index].total_records++; + + if(cdr_param.max_records_per_file>0) + { + if(cdr_param.ssn_param[index].total_records>=cdr_param.max_records_per_file) + cdr_open_ssn_file(index); + } + + return 1; +} + +int cdr_backup() +{ + int head, tail; + _cdr_record *ptr=NULL; + register int loop; + + head = cdr_vm_ptr->head_ptr; + + for(loop=0;looptail_ptr; + if(head == tail) + break; + + ptr = &cdr_vm_ptr->cdr_data[tail]; + //memcpy(ptr, &cdr_vm_ptr->cdr_data, sizeof(_cdr_record)); + + cdr_back_record(ptr); + + // sem_lock(cdr_sem_id, 1, 1, IPC_NOWAIT); + cdr_vm_ptr->tail_ptr ++; + if(cdr_vm_ptr->tail_ptr>=MAX_CDR_RECORDS) + cdr_vm_ptr->tail_ptr = 0; + // sem_unlock(cdr_sem_id, 1, 1, IPC_NOWAIT); + + // if(cdr_vm_ptr->tail_ptr == head) + // { + // break; + // } + } + return 1; +} diff --git a/plat/public/src/crypt.c b/plat/public/src/crypt.c new file mode 100644 index 0000000..8fdb1d4 --- /dev/null +++ b/plat/public/src/crypt.c @@ -0,0 +1,493 @@ +/* +** PACS-WLL 2000 project, Prepaid System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** Written completely by Zhang Shuzhong at iCRD February, 2001 +** +** file name: crypt.c +** CVS $Id: crypt.c,v 1.1 2001/06/28 07:21:15 zhangsz Exp $ +** +** Crypt functions +** +*/ + +#include +#include +#include +#include + +/*@ignore@*/ + +#define DES_KEY "N2r3T5B0" + +static unsigned char T1[] = +{ + 57,49,41,33,25,17, 9, 1, + 59,51,43,35,27,19,11, 3, + 61,53,45,37,29,21,13, 5, + 63,55,47,39,31,23,15, 7, + 56,48,40,32,24,16, 8, 0, + 58,50,42,34,26,18,10, 2, + 60,52,44,36,28,20,12, 4, + 62,54,46,38,30,22,14, 6 +}; + +static unsigned char T2[] = +{ + 39, 7,47,15,55,23,63,31, + 38, 6,46,14,54,22,62,30, + 37, 5,45,13,53,21,61,29, + 36, 4,44,12,52,20,60,28, + 35, 3,43,11,51,19,59,27, + 34, 2,42,10,50,18,58,26, + 33, 1,41, 9,49,17,57,25, + 32, 0,40, 8,48,16,56,24 +}; + +static unsigned char T3[] = +{ + 31, 0, 1, 2, 3, 4, + 3, 4, 5, 6, 7, 8, + 7, 8, 9,10,11,12, + 11,12,13,14,15,16, + 15,16,17,18,19,20, + 19,20,21,22,23,24, + 23,24,25,26,27,28, + 27,28,29,30,31, 0 +}; + +static unsigned char T5[] = +{ + 15, 6,19,20, + 28,11,27,16, + 0,14,22,25, + 4,17,30, 9, + 1, 7,23,13, + 31,26, 2, 8, + 18,12,29, 5, + 21,10, 3,24 +}; + +static unsigned char T7_1_2[] = +{ + 56,48,40,32,24,16, 8, + 0,57,49,41,33,25,17, + 9, 1,58,50,42,34,26, + 18,10, 2,59,51,43,35, + 62,54,46,38,30,22,14, + 6,61,53,45,37,29,21, + 13, 5,60,52,44,36,28, + 20,12, 4,27,19,11, 3 +}; + +static unsigned char T8[] = +{ + 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 +}; + +static unsigned char T9[] = +{ + 13,16,10,23, 0, 4, + 2,27,14, 5,20, 9, + 22,18,11, 3,25, 7, + 15, 6,26,19,12, 1, + 40,51,30,36,46,54, + 29,39,50,44,32,47, + 43,48,38,55,33,52, + 45,41,49,35,28,31 +}; + +static unsigned char T6[][64] = +{ + {/* S1 */ + 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, + 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, + 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, + 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13 + }, + {/* S2 */ + 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, + 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, + 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, + 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9 + }, + {/* S3 */ + 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, + 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, + 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12 + }, + {/* S4 */ + 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, + 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, + 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, + 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14 + }, + {/* S5 */ + 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9, + 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, + 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, + 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3 + }, + {/* S6 */ + 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, + 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, + 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, + 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13 + }, + {/* S7 */ + 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, + 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, + 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, + 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12 + }, + {/* S8 */ + 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, + 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, + 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, + 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11 + } +}; + +unsigned char TE[][4] = +{ + {0,0,0,0}, + {0,0,0,1}, + {0,0,1,0}, + {0,0,1,1}, + {0,1,0,0}, + {0,1,0,1}, + {0,1,1,0}, + {0,1,1,1}, + {1,0,0,0}, + {1,0,0,1}, + {1,0,1,0}, + {1,0,1,1}, + {1,1,0,0}, + {1,1,0,1}, + {1,1,1,0}, + {1,1,1,1} +}; + +void Ks (unsigned char *Key, unsigned char Kn[16][48]) +{ + unsigned char cd[56]; + unsigned char zt[60]; + int n, i; + unsigned char tmp11, tmp12, tmp21, tmp22; + unsigned char *Knn; + + /* choix 1 */ + for (i = 0; i < 56; i++) + { + cd[i] = Key[T7_1_2[i]]; + } + + for (n = 0; n < 16; n++) + { + if (T8[n] == 0) + { + tmp11 = cd[0]; + tmp21 = cd[28]; + memcpy( zt , &cd[1] , 55 ); + memcpy( cd , zt , 55 ); + cd[27] = tmp11; + cd[55] = tmp21; + } + else + { + tmp11 = cd[0]; + tmp12 = cd[1]; + tmp21= cd[28]; + tmp22 = cd[29]; + + memcpy( zt , &cd[2] , 54 ); + memcpy( cd , zt , 54 ); + + cd[26] = tmp11; + cd[27] = tmp12; + cd[54] = tmp21; + cd[55] = tmp22; + } + Knn = Kn[n]; + for (i = 0; i < 48; i++) + { + Knn[i] = cd[T9[i]]; + } + } +} + +void fonction(unsigned char *Knn, unsigned char *r, unsigned char *s) +{ + + unsigned char x[32]; + unsigned int *px; + int i, l; + unsigned char c; + unsigned char t; + + for (i = 0, l = 0, px = (unsigned int *) x; i < 8;) + { + c = 32 * (r[T3[l]] ^ Knn[l]); + l++; + c += 8 * (r[T3[l]] ^ Knn[l]); + l++; + c += 4 * (r[T3[l]] ^ Knn[l]); + l++; + c += 2 * (r[T3[l]] ^ Knn[l]); + l++; + c += 1 * (r[T3[l]] ^ Knn[l]); + l++; + c += 16 * (r[T3[l]] ^ Knn[l]); + l++; + t = T6[i][c]; + i++; + *px = *(int *)TE[t]; + px++; + } + for (i = 0; i < 32; i++) + { + s[i] = x[T5[i]]; + } +} + +void permutation(unsigned char *org, unsigned char *tab) +{ + unsigned char tmp[64]; + int i; + + + memcpy(tmp, org, 64); + for (i = 0; i < 64; i++) + { + org[i] = tmp[tab[i]]; + } +} + +void chiffrement(unsigned char *xi, unsigned char *xo, unsigned char Kn[16][48]) +{ + unsigned char r[32], l[32]; + unsigned char rp[32], lp[32]; + + int i; + int n; + + memcpy(l, &xi[0], 32); + memcpy(r, &xi[32], 32); + + for (n = 0; n < 16; n++) + { + memcpy(lp, r, 32); + + fonction(Kn[n], r, rp); + for (i = 0; i < 32; i++) + { + r[i] =( ( l[i]) ^ (rp[i] ) ) ; + } + memcpy(l, lp, 32); + } + memcpy(&xo[0], r, 32); + memcpy(&xo[32], l, 32); + +} + +void dechiffrement(unsigned char *xi, unsigned char *xo, unsigned char Kn[16][48]) +{ + unsigned char r[32], l[32], rp[32], lp[32]; + + int i; + int n; + + memcpy(l, &xi[0], 32); + memcpy(r, &xi[32], 32); + + for (n = 0; n < 16; n++) + { + memcpy(lp, r, 32); + fonction(Kn[15 - n], r, rp); + for (i = 0; i < 32; i++) + { + r[i] =( ( l[i] ) ^ ( rp[i] )) ; + } + memcpy(l, lp, 32); + } + + memcpy(&xo[0], r, 32); + memcpy(&xo[32], l, 32); +} + +void eclater(const unsigned char *buf_bit, unsigned char *byte) +{ + int i; + unsigned char m; + + for (i = 0; i < 8; i++) + { + for (m = 0x80; m != 0; ) + { + if ((buf_bit[i] & m) != 0) + *byte = 1; + else + *byte = 0; + byte++; + m=m/2 ; + } + } +} + +void compacter(unsigned char *byte, unsigned char *buf_bit) +{ + int i; + unsigned char m, n; + + for (i = 0; i < 8; i++) + { + n = 0; + for (m = 0x80; m != 0; ) + { + if (*byte++) + n = n | m; + m=m/2 ; + + } + buf_bit[i] = n; + } +} + +// direction 0/1=Encryption/Decryption +// binput,boutput,bkey = 8bytes +// direction: 0/1=Encryt/Decrypt +void des(unsigned char *boutput, const unsigned char *binput, const unsigned char *bkey, int direction) +{ + unsigned char input[64]; /* data input */ + unsigned char output[64]; /* data output */ + unsigned char Key[64]; + unsigned char Kn[16][48]; + + eclater(binput, input); + eclater(bkey, Key); + Ks(Key, Kn); + permutation(input, T1); + + if (direction) dechiffrement(input, output, Kn); + else chiffrement(input, output, Kn); + + permutation(output, T2); + compacter(output, boutput); +} + +void atob (unsigned char *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if (i & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} + +void btoa (char *ascii_buf, const unsigned char *bcd_buf, int len) +{ + int i; + char ch; + + for (i=0; i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} + +void EncryptPIN (unsigned char cipher[], const char plain[], const char pan[], const unsigned char pin_key[]) +{ + char pin[20]; + unsigned char buf1[8], buf2[8]; + int i; + + i = strlen(plain); + buf1[0] = i; + strcpy(pin, plain); + for (; i<14; ++i) pin[i] = 'F'; + atob(buf1+1, pin, 14); + buf2[0] = buf2[1] = 0x00; + atob(buf2+2, pan+strlen(pan)-13, 12); + for (i=0; i<8; ++i) buf1[i] ^= buf2[i]; + des(cipher, buf1, pin_key, 0); +} + +/* length of pan more than 13, and length of pin key more than 8 */ +void DecryptPIN (char plain[], const unsigned char cipher[], const char pan[], const unsigned char pin_key[]) +{ + unsigned char buf1[8], buf2[8]; + int i; + + des(buf1, cipher, pin_key, 1); + buf2[0] = buf2[1] = 0x00; + atob(buf2+2, pan+strlen(pan)-13, 12); + for (i=0; i<8; i++) buf1[i] ^= buf2[i]; + i = buf1[0]; + if (i <= 14) btoa(plain, buf1+1, i); + else plain[0] = '\0'; +} + +void CalcMAC (char mac[], const char data[], const unsigned char mac_key[]) +{ + int i; + unsigned char m[8]; + + memset(m, 0, 8); + for (i=0; data[i];) + { + m[i&7] ^= data[i]; + ++i; + if (!((i&7) && data[i])) des(m, m, mac_key, 0); + } + btoa(mac, m, 8); +} + +void CalcMAC1 (unsigned char mac[], const unsigned char data[], int len, const unsigned char mac_key[]) +{ + int i; + + memset(mac, 0, 8); + for (i=0; i +#include + +typedef struct ASN_TLV +{ + u_char tagtype; + u_short tagcode; + int length; + u_char *pvalue; + struct ASN_TLV *pnext; + struct ASN_TLV *psub; +}ASN_TLV; + +typedef struct _ASN_BUFFER +{ + u_char *msgbuf; //store pointer of buffer + int maxlen; + int msglen; //totallength of message + int pos; + + ASN_TLV heap[256]; + char errmsg[1024]; + short tlvcount; +}ASN_BUF; + +//interface======> +void AsnEncode(u_char *msg_buf,u_int maxlen,ASN_BUF *asnbuf); +int AsnDecode(u_char *msg_buf,int msglen,int maxtlv,int *errpos,ASN_BUF *asnbuf); +int GetTLV(const char *tag_seq,int maxlen,u_char *pvalue,u_char flag,ASN_BUF *asnbuf); +int GetAnyTLV(const char *tag_seq,int maxlen,u_char *pvalue,u_char *pflag,u_short *ptagcode,ASN_BUF *asnbuf); +int AddTLV(const char *tag_seq,u_int length,u_char *pvalue,u_char tlv_type,ASN_BUF *asnbuf); +int GetInteger(const char *tag_seq,int *rtn,u_char flag,ASN_BUF *asnbuf); +int AddInteger(const char *tag_seq,int value,u_char tlv_type,ASN_BUF *asnbuf); + +void asn_encode(u_char *asn_buf,ASN_BUF *asnbuf); +void asn_encode_v3(u_char *msg_buf,u_int maxlen,ASN_BUF *asnbuf); +int add_tlv(const char *tag_seq,u_int length,u_char *pvalue,u_char tlv_type,ASN_BUF *asnbuf); +int asn_decode(u_char *asn_buf,int ntlv,ASN_BUF *asnbuf); +int asn_decode_v2(u_char *msg_buf,int ntlv,int *plen,ASN_BUF *asnbuf); +int asn_decode_v3(u_char *msg_buf,int msglen,int *errpos,ASN_BUF *asnbuf); +int get_tlv(const char *tag_seq,u_char *pvalue,ASN_BUF *asnbuf); +int get_tlv_v2(const char *tag_seq,u_char *pvalue,u_char *flag,ASN_BUF *asnbuf); +int parse_tlv(ASN_TLV **pnode,ASN_BUF *asnbuf); +//int parse_tlv2(u_char *asn_buf,int rest,u_short (*tags)[2],int order,ASN_BUF *asnbuf); +int findtlv(u_char *pasn,u_int tagcode,u_char **pnext,int rest); +int findtlv2(u_char *pasn,int index,u_char **pnext,int rest); +int gettagcode(u_char *asnbuf,u_int *tagcode,u_char *type); +int getlength(u_char *asnbuf,int *len); +int addtagcode(u_char *asn_buf,u_int tagcode,u_char type); +int addlength(u_char *asn_buf,u_int len); +int parse_tags(const char *tag_seq,u_short (*tags)[2]); +int modifylength(u_char *ptr[],int level,int addval); +void showbuf(u_char *buf,int len); + +int add_bool(const char *tag_seq,u_char value,u_char tlv_type,ASN_BUF *asnbuf); +u_char get_bool(const char *tag_seq,ASN_BUF *asnbuf); +int add_int(const char *tag_seq,int value,u_char tlv_type,ASN_BUF *asnbuf); +int get_int(const char *tag_seq,ASN_BUF *asnbuf); +int get_int_v2(const char *tag_seq,int *rtn,ASN_BUF *asnbuf); +int add_oid(const char *tag_seq,const char *oidstr,u_char tlv_type,ASN_BUF *asnbuf); +int get_oid(const char *tag_seq,char *oid,ASN_BUF *asnbuf); +int add_null(const char *tag_seq,u_char tlv_type,ASN_BUF *asnbuf); +int get_null(const char *tag_seq,ASN_BUF *asnbuf); +int DecodeInteger(u_char *buf, u_char len); +#endif diff --git a/plat/public/src/include/asn1per.h b/plat/public/src/include/asn1per.h new file mode 100644 index 0000000..bf44741 --- /dev/null +++ b/plat/public/src/include/asn1per.h @@ -0,0 +1,64 @@ + +typedef unsigned char bool; + +/** + * A generic open type structure. This structure contains a number of + * octets and the data that compose the open type information. + */ +typedef struct { /* generic open type data structure */ + unsigned int len; + unsigned char *pdata; +} ASN1OpenType; + +typedef struct { + unsigned char len; + unsigned char data[4]; +}octstring_4bytes; + +typedef struct { + unsigned char len; + unsigned char data[8]; +}octstring_8bytes; + +typedef struct { + unsigned char len; + unsigned char data[16]; +}octstring_16bytes; + +typedef struct { + unsigned char len; + unsigned char data[32]; +}octstring_32bytes; + +typedef struct { + unsigned char len; + unsigned char data[64]; +}octstring_64bytes; + +typedef struct { + unsigned char len; + unsigned char data[128]; +}octstring_128bytes; + +typedef struct { + unsigned char len; + unsigned char data[256]; +}octstring_256bytes; + +extern int per_decode_Length(unsigned int *plen, unsigned char *psrc); +extern int per_encode_Length(unsigned char *pdst, int len); +extern int per_decode_OpenType(ASN1OpenType *popen, unsigned char *psrc); +extern int per_encode_OpenType(unsigned char *pdst, ASN1OpenType *popen); +extern int per_encode_Boolean(unsigned char *pdst, bool value, unsigned char *offset_bit); +extern int per_decode_Boolean(unsigned char *psrc, bool *value, unsigned char *offset_bit); +extern int per_encode_Constrained_Integer(unsigned char *pdst, unsigned int value,unsigned int lower, unsigned int upper, unsigned char *offset_bit); +extern int per_decode_Constrained_Integer(unsigned char * psrc, unsigned int * value, unsigned int lower, unsigned int upper, unsigned char * offset_bit); +extern int per_encode_BitString(unsigned char *pdst, unsigned int numbits, unsigned char *pdata); +extern int per_decode_BitString(unsigned char *psrc, unsigned int numbits, unsigned char *pdata); +extern int per_encode_BitStr16(unsigned char *pdst, unsigned char *value, unsigned int lbits, unsigned int ubits, unsigned char *offset_bit); +extern int per_decode_BitStr16(unsigned char *psrc, unsigned char *value, unsigned int lbits, unsigned int ubits, unsigned char *offset_bit); +extern int per_encode_OctetString(unsigned char *pdst, unsigned int numocts, unsigned char *pdata); +extern int per_decode_OctetString(unsigned char *psrc, unsigned int numocts, unsigned char *pdata); +extern int per_encode_SmallNonNegWholeNumber(unsigned char *pdst, unsigned int value, unsigned char *offset_bit); +extern int per_decode_SmallNonNegWholeNumber(unsigned char *psrc, unsigned int *value, unsigned char *offset_bit); + diff --git a/plat/public/src/include/bisearch.h b/plat/public/src/include/bisearch.h new file mode 100644 index 0000000..fa89262 --- /dev/null +++ b/plat/public/src/include/bisearch.h @@ -0,0 +1,123 @@ + +/******************************************/ +/*Title : bisearch.h */ +/*Descr : BiSearch arithmetic Structure */ +/*Author : Liu Wei */ +/*Create : 2006-12-13 */ +/*Version : R1V00_01 */ +/*Modify : 2006-12-13 */ +/******************************************/ + +#ifndef _BISEARCH_H_ +#define _BISEARCH_H_ + +#define LL long long +#define u8 unsigned char + +typedef struct BiSearch +{ + LL llKey; //BiSearch Array Node Key + int nDUPosIndex; //Data Unit array Position Index +} +BiSearch; + +#define BS_SIZE sizeof(BiSearch) + +typedef struct BiSearchArray +{ + int nArrayCount; + int nArrayTotalLen; + BiSearch *pBiArray; //SearchArray pointer + int (*GetIdleNodeFunc)(int* nDUIndex); +} +BiSearchArray; + +/*********************************************************************/ +/*BiSearchReg : Init BiSearch Struct, Alloc BiSearch Memery */ +/*Return : [0]:BiSearchReg fail [1] :BiSearchReg Success */ +/*********************************************************************/ +extern int BISearchReg ( BiSearchArray * pBSA, int nTotalSize ,void *GetIdleNodeFunc ); + + +/*********************************************************************/ +/*BiSearchUnReg : Release BiSearch Memery */ +/*Return : [0]:BiSearchUnReg fail [1] :BiSearchUnReg Success */ +/*********************************************************************/ +int BISearchUnReg ( BiSearchArray * pBSA); + + +/*********************************************************************/ +/*BSearch : BiSearch from nStart to nEnd with the llKey */ +/* Search Result save in the val "nPosResult" */ +/*Return : [0]:BSearch fail [1] :BSearch Success */ +/*********************************************************************/ +int BSearch ( BiSearchArray * pBSA, int nStart, int nEnd, LL llKey, int *nPosResult ); + + +/*********************************************************************/ +/*BSearchArray : BiSearch from 0 to ArrayEndIndex with the llKey */ +/* Search nPos Result save in the val "nPosResult" */ +/*Return : [0]:BSearchArray fail [1] :BSearchArray Success */ +/*********************************************************************/ +int BSearchArray ( BiSearchArray * pBSA, LL llKey, int *nPosResult ); + + +/*********************************************************************/ +/*BISInsert : Insert a BiSearch Array Element with the llKey */ +/* return Data Unit Array Index Get by GetIdleNodeFunc*/ +/*Return : [0]:BISInsert fail [1]:BISInsert Success */ +/*********************************************************************/ +int BISInsert ( BiSearchArray * pBSA, LL llKey, int nDUPosIndex ); + +/*********************************************************************/ +/*BISDelete : Delete a BiSearch Array Element with the llKey */ +/*Return : [0]:BISDelete fail [1]:BISDelete Success */ +/*********************************************************************/ +int BISDelete ( BiSearchArray * pBSA, LL llKey ); + + +/*********************************************************************/ +/*BISSearch : BiSearch from 0 to ArrayEndIndex with the llKey */ +/* Search DUIndex Result save in the val "nDUPosIndex"*/ +/*Return : [0]:BISSearch fail [1]:BISSearch Success */ +/*********************************************************************/ +int BISSearch ( BiSearchArray * pBSA, LL llKey , int* nDUPosIndex); + +/*********************************************************************/ +/*GetBISearchCount : Get The BiSearch struct counter */ +/*Return : return The BiSearch struct counter */ +/*********************************************************************/ +int GetBISearchCount ( BiSearchArray * pBSA); + +/*********************************************************************/ +/*GetDUIndex : Get The Data Unit Index by bisearch struct index */ +/*Return : return the BiSearch struct dataunit index */ +/*********************************************************************/ +int GetDUIndex ( BiSearchArray * pBSA, int nBIIndex); + +//BiSearch ManageMent Operation +typedef enum _BIS_OP +{ + BIS_INIT = 0, + BIS_SEARCH, + BIS_INSERT, + BIS_DELETE, +}BIS_OP; + +/*********************************************************************/ +/*BISSearchMng : BiSearch Management Opertion fuction */ +/* Init : use BIS_OP [BIS_INIT] Insert the elment */ +/* with the key_str and nDUIndex */ +/* Search : use BIS_OP [BIS_SEARCH] search the elemnt */ +/* with the key_str ,return nDUIndex */ +/* Insert : se BIS_OP [BIS_Insert] Insert a BiSearch */ +/* Array Element with the llKey ,return Data */ +/* Unit Array Index Get by GetIdleNodeFunc() */ +/* by GetIdleNodeFunc() */ +/* Delete : use BIS_OP [BIS_DELETE] Delete the elment */ +/* with the key_str */ +/*Return : [0] fail [1] success */ +/*********************************************************************/ +int BISSearchMng( BiSearchArray * pBSA, BIS_OP mng_type,LL llkey, int* nDUIndex ); + +#endif diff --git a/plat/public/src/include/cdr.h b/plat/public/src/include/cdr.h new file mode 100644 index 0000000..7b9140f --- /dev/null +++ b/plat/public/src/include/cdr.h @@ -0,0 +1,60 @@ +#ifndef _CDR_H +#define _CDR_H + +#include +#include + +#define CDR_SHM_KEY 0x60000006 +#define CDR_SHM_PERM 0777 +#define CDR_SEM_KEY 0x60000007 +#define CDR_SEM_PERM 0777 + +#define MAX_CDR_RECORDS 8192 +#define CDR_RECORD_SIZE 256 + +#define MAX_CDR_PER_CYCLE 256 +#define MAX_CDR_APP_NUM 4 + +typedef struct cdr_record +{ + char ssn; + unsigned short length; + char data[CDR_RECORD_SIZE]; +}_cdr_record; + +typedef struct cdr_vm_struct +{ + char plane_id; /* 0/1=mss0,mss1*/ + unsigned short head_ptr; + unsigned short tail_ptr; + _cdr_record cdr_data[MAX_CDR_RECORDS]; +}_cdr_vm_struct; + +typedef struct cdr_ssn_param +{ + unsigned char ssn; + char name[32]; + char file_name[128]; + int total_records; + int file_sn; + FILE *fd; +}_cdr_ssn_param; + +typedef struct cdr_param +{ + char system_id; + char base_dir[128]; + char file_suffix[32]; + int max_records_per_file; + char max_days; + char init_flag; + char now_time[8]; + _cdr_ssn_param ssn_param[MAX_CDR_APP_NUM]; +}_cdr_param; + +int cdr_init(char plane_id, char memset_flag); +int cdr_timer(); + +int cdr_bakcup(); + +#endif diff --git a/plat/public/src/include/crypt.h b/plat/public/src/include/crypt.h new file mode 100644 index 0000000..fdf0bd9 --- /dev/null +++ b/plat/public/src/include/crypt.h @@ -0,0 +1,28 @@ +/* + * crypt.h ---- Key management and data encryption/decryption. + */ + +#ifndef CRYPT__H +#define CRYPT__H + +void des(unsigned char *output, const unsigned char *input, const unsigned char *key, int direction); +void atob (unsigned char *bcd_buf, const char *ascii_buf, int len); +void btoa (char *ascii_buf, const unsigned char *bcd_buf, int len); +void EncryptPIN (unsigned char cipher[], const char plain[], const char pan[], const unsigned char pin_key[]); +void DecryptPIN (char plain[], const unsigned char cipher[], const char pan[], const unsigned char pin_key[]); +void CalcMAC (char mac[], const char data[], const unsigned char mac_key[]); +void CalcMAC1 (unsigned char mac[], const unsigned char data[], int len, const unsigned char mac_key[]); +void EncryptKey (char cipher[], const unsigned char plain[]); +void DecryptKey (unsigned char plain[], const char cipher[]); + +typedef enum _des_crypt_mode{ + _DES_ENCRYPT_ = 0, + _DES_DECRYPT_ +}_DesMode; + +void DesCrypt( +unsigned char *Output /*8 bytes*/, +unsigned char *Input /*8 bytes*/, +unsigned char *DesKey/*default=NULL.While using for user licenses control,can keep the default value*/, +unsigned char DesMode/*encrpt or decrypt,refer to enum _DesMode*/); +#endif diff --git a/plat/public/src/include/includes.h b/plat/public/src/include/includes.h new file mode 100644 index 0000000..bcc6f44 --- /dev/null +++ b/plat/public/src/include/includes.h @@ -0,0 +1,47 @@ +/* public include head file */ +/* written by Liu Zhiguo 2002-03-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#ifndef _PUBLIC_INCLUDES_H_ +#define _PUBLIC_INCLUDES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif diff --git a/plat/public/src/include/includes.h.bak b/plat/public/src/include/includes.h.bak new file mode 100644 index 0000000..75445bb --- /dev/null +++ b/plat/public/src/include/includes.h.bak @@ -0,0 +1,47 @@ +/* public include head file */ +/* written by Liu Zhiguo 2002-03-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#ifndef _PUBLIC_INCLUDES_H_ +#define _PUBLIC_INCLUDES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif diff --git a/plat/public/src/include/license_id.h b/plat/public/src/include/license_id.h new file mode 100644 index 0000000..081ba9e --- /dev/null +++ b/plat/public/src/include/license_id.h @@ -0,0 +1,37 @@ +#ifndef _LICENCE_ID__H +#define _LICENCE_ID__H + +typedef enum _WXC2_LICENSE_ID +{ + LIC_MSC_TRUNK=0, + LIC_HLR_USERS, + LIC_VLR_USERS, + LIC_AUC_USERS, + LIC_EIR_USERS, + LIC_PPS_USERS, + LIC_SMSC_USERS, + LIC_MNP_USERS, + LIC_SMEG_USERS, + LIC_OPPS_USERS, + LIC_PALIM_USERS, + + LIC_GPRS=16, + LIC_USSD, + LIC_ISUP, + LIC_BICC, + LIC_AIF, + LIC_MGC, + LIC_CAP, + LIC_OPPS_OPR, + LIC_OPPS_IMDM, + LIC_ISDN, + LIC_SIP, + LIC_RLS, + LIC_MAX_ID, +}WXC2_LICENSE_ID; + +/* functionID: listed above, + if functionID doesn't exist, return -1, else return license value +*/ +int wxc2_get_license(int functionID); +#endif diff --git a/plat/public/src/include/memwatch.h b/plat/public/src/include/memwatch.h new file mode 100644 index 0000000..c60d31b --- /dev/null +++ b/plat/public/src/include/memwatch.h @@ -0,0 +1,707 @@ +/* +** MEMWATCH.H +** Nonintrusive ANSI C memory leak / overwrite detection +** Copyright (C) 1992-2002 Johan Lindh +** All rights reserved. +** Version 2.71 +** +************************************************************************ +** +** PURPOSE: +** +** MEMWATCH has been written to allow guys and gals that like to +** program in C a public-domain memory error control product. +** I hope you'll find it's as advanced as most commercial packages. +** The idea is that you use it during the development phase and +** then remove the MEMWATCH define to produce your final product. +** MEMWATCH is distributed in source code form in order to allow +** you to compile it for your platform with your own compiler. +** It's aim is to be 100% ANSI C, but some compilers are more stingy +** than others. If it doesn't compile without warnings, please mail +** me the configuration of operating system and compiler you are using +** along with a description of how to modify the source, and the version +** number of MEMWATCH that you are using. +** +************************************************************************ + + This file is part of MEMWATCH. + + MEMWATCH is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + MEMWATCH 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with MEMWATCH; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +************************************************************************ +** +** REVISION HISTORY: +** +** 920810 JLI [1.00] +** 920830 JLI [1.10 double-free detection] +** 920912 JLI [1.15 mwPuts, mwGrab/Drop, mwLimit] +** 921022 JLI [1.20 ASSERT and VERIFY] +** 921105 JLI [1.30 C++ support and TRACE] +** 921116 JLI [1.40 mwSetOutFunc] +** 930215 JLI [1.50 modified ASSERT/VERIFY] +** 930327 JLI [1.51 better auto-init & PC-lint support] +** 930506 JLI [1.55 MemWatch class, improved C++ support] +** 930507 JLI [1.60 mwTest & CHECK()] +** 930809 JLI [1.65 Abort/Retry/Ignore] +** 930820 JLI [1.70 data dump when unfreed] +** 931016 JLI [1.72 modified C++ new/delete handling] +** 931108 JLI [1.77 mwSetAssertAction() & some small changes] +** 940110 JLI [1.80 no-mans-land alloc/checking] +** 940328 JLI [2.00 version 2.0 rewrite] +** Improved NML (no-mans-land) support. +** Improved performance (especially for free()ing!). +** Support for 'read-only' buffers (checksums) +** ^^ NOTE: I never did this... maybe I should? +** FBI (free'd block info) tagged before freed blocks +** Exporting of the mwCounter variable +** mwBreakOut() localizes debugger support +** Allocation statistics (global, per-module, per-line) +** Self-repair ability with relinking +** 950913 JLI [2.10 improved garbage handling] +** 951201 JLI [2.11 improved auto-free in emergencies] +** 960125 JLI [X.01 implemented auto-checking using mwAutoCheck()] +** 960514 JLI [2.12 undefining of existing macros] +** 960515 JLI [2.13 possibility to use default new() & delete()] +** 960516 JLI [2.20 suppression of file flushing on unfreed msgs] +** 960516 JLI [2.21 better support for using MEMWATCH with DLL's] +** 960710 JLI [X.02 multiple logs and mwFlushNow()] +** 960801 JLI [2.22 merged X.01 version with current] +** 960805 JLI [2.30 mwIsXXXXAddr() to avoid unneeded GP's] +** 960805 JLI [2.31 merged X.02 version with current] +** 961002 JLI [2.32 support for realloc() + fixed STDERR bug] +** 961222 JLI [2.40 added mwMark() & mwUnmark()] +** 970101 JLI [2.41 added over/underflow checking after failed ASSERT/VERIFY] +** 970113 JLI [2.42 added support for PC-Lint 7.00g] +** 970207 JLI [2.43 added support for strdup()] +** 970209 JLI [2.44 changed default filename to lowercase] +** 970405 JLI [2.45 fixed bug related with atexit() and some C++ compilers] +** 970723 JLI [2.46 added MW_ARI_NULLREAD flag] +** 970813 JLI [2.47 stabilized marker handling] +** 980317 JLI [2.48 ripped out C++ support; wasn't working good anyway] +** 980318 JLI [2.50 improved self-repair facilities & SIGSEGV support] +** 980417 JLI [2.51 more checks for invalid addresses] +** 980512 JLI [2.52 moved MW_ARI_NULLREAD to occur before aborting] +** 990112 JLI [2.53 added check for empty heap to mwIsOwned] +** 990217 JLI [2.55 improved the emergency repairs diagnostics and NML] +** 990224 JLI [2.56 changed ordering of members in structures] +** 990303 JLI [2.57 first maybe-fixit-for-hpux test] +** 990516 JLI [2.58 added 'static' to the definition of mwAutoInit] +** 990517 JLI [2.59 fixed some high-sensitivity warnings] +** 990610 JLI [2.60 fixed some more high-sensitivity warnings] +** 990715 JLI [2.61 changed TRACE/ASSERT/VERIFY macro names] +** 991001 JLI [2.62 added CHECK_BUFFER() and mwTestBuffer()] +** 991007 JLI [2.63 first shot at a 64-bit compatible version] +** 991009 JLI [2.64 undef's strdup() if defined, mwStrdup made const] +** 000704 JLI [2.65 added some more detection for 64-bits] +** 010502 JLI [2.66 incorporated some user fixes] +** [mwRelink() could print out garbage pointer (thanks mac@phobos.ca)] +** [added array destructor for C++ (thanks rdasilva@connecttel.com)] +** [added mutex support (thanks rdasilva@connecttel.com)] +** 010531 JLI [2.67 fix: mwMutexXXX() was declared even if MW_HAVE_MUTEX was not defined] +** 010619 JLI [2.68 fix: mwRealloc() could leave the mutex locked] +** 020918 JLI [2.69 changed to GPL, added C++ array allocation by Howard Cohen] +** 030212 JLI [2.70 mwMalloc() bug for very large allocations (4GB on 32bits)] +** 030520 JLI [2.71 added ULONG_LONG_MAX as a 64-bit detector (thanks Sami Salonen)] +** +** To use, simply include 'MEMWATCH.H' as a header file, +** and add MEMWATCH.C to your list of files, and define the macro +** 'MEMWATCH'. If this is not defined, MEMWATCH will disable itself. +** +** To call the standard C malloc / realloc / calloc / free; use mwMalloc_(), +** mwCalloc_() and mwFree_(). Note that mwFree_() will correctly +** free both malloc()'d memory as well as mwMalloc()'d. +** +** 980317: C++ support has been disabled. +** The code remains, but is not compiled. +** +** For use with C++, which allows use of inlining in header files +** and class specific new/delete, you must also define 'new' as +** 'mwNew' and 'delete' as 'mwDelete'. Do this *after* you include +** C++ header files from libraries, otherwise you can mess up their +** class definitions. If you don't define these, the C++ allocations +** will not have source file and line number information. Also note, +** most C++ class libraries implement their own C++ memory management, +** and don't allow anyone to override them. MFC belongs to this crew. +** In these cases, the only thing to do is to use MEMWATCH_NOCPP. +** +** You can capture output from MEMWATCH using mwSetOutFunc(). +** Just give it the adress of a "void myOutFunc(int c)" function, +** and all characters to be output will be redirected there. +** +** A failing ASSERT() or VERIFY() will normally always abort your +** program. This can be changed using mwSetAriFunc(). Give it a +** pointer to a "int myAriFunc(const char *)" function. Your function +** must ask the user whether to Abort, Retry or Ignore the trap. +** Return 2 to Abort, 1 to Retry or 0 to Ignore. Beware retry; it +** causes the expression to be evaluated again! MEMWATCH has a +** default ARI handler. It's disabled by default, but you can enable +** it by calling 'mwDefaultAri()'. Note that this will STILL abort +** your program unless you define MEMWATCH_STDIO to allow MEMWATCH +** to use the standard C I/O streams. Also, setting the ARI function +** will cause MEMWATCH *NOT* to write the ARI error to stderr. The +** error string is passed to the ARI function instead, as the +** 'const char *' parameter. +** +** You can disable MEMWATCH's ASSERT/VERIFY and/or TRACE implementations. +** This can be useful if you're using a debug terminal or smart debugger. +** Disable them by defining MW_NOASSERT, MW_NOVERIFY or MW_NOTRACE. +** +** MEMWATCH fills all allocated memory with the byte 0xFE, so if +** you're looking at erroneous data which are all 0xFE:s, the +** data probably was not initialized by you. The exception is +** calloc(), which will fill with zero's. All freed buffers are +** zapped with 0xFD. If this is what you look at, you're using +** data that has been freed. If this is the case, be aware that +** MEMWATCH places a 'free'd block info' structure immediately +** before the freed data. This block contains info about where +** the block was freed. The information is in readable text, +** in the format "FBIfilename(line)", for example: +** "FBI<267>test.c(12)". Using FBI's slows down free(), so it's +** disabled by default. Use mwFreeBufferInfo(1) to enable it. +** +** To aid in tracking down wild pointer writes, MEMWATCH can perform +** no-mans-land allocations. No-mans-land will contain the byte 0xFC. +** MEMWATCH will, when this is enabled, convert recently free'd memory +** into NML allocations. +** +** MEMWATCH protects it's own data buffers with checksums. If you +** get an internal error, it means you're overwriting wildly, +** or using an uninitialized pointer. +** +************************************************************************ +** +** Note when compiling with Microsoft C: +** - MSC ignores fflush() by default. This is overridden, so that +** the disk log will always be current. +** +** This utility has been tested with: +** PC-lint 7.0k, passed as 100% ANSI C compatible +** Microsoft Visual C++ on Win16 and Win32 +** Microsoft C on DOS +** SAS C on an Amiga 500 +** Gnu C on a PC running Red Hat Linux +** ...and using an (to me) unknown compiler on an Atari machine. +** +************************************************************************ +** +** Format of error messages in MEMWATCH.LOG: +** message: filename(linenumber), information +** +** Errors caught by MemWatch, when they are detected, and any +** actions taken besides writing to the log file MEMWATCH.LOG: +** +** Double-freeing: +** A pointer that was recently freed and has not since been +** reused was freed again. The place where the previous free() +** was executed is displayed. +** Detect: delete or free() using the offending pointer. +** Action: The delete or free() is cancelled, execution continues. +** Underflow: +** You have written just ahead of the allocated memory. +** The size and place of the allocation is displayed. +** Detect: delete or free() of the damaged buffer. +** Action: The buffer is freed, but there may be secondary damage. +** Overflow: +** Like underflow, but you've written after the end of the buffer. +** Detect: see Underflow. +** Action: see Underflow. +** WILD free: +** An unrecognized pointer was passed to delete or free(). +** The pointer may have been returned from a library function; +** in that case, use mwFree_() to force free() of it. +** Also, this may be a double-free, but the previous free was +** too long ago, causing MEMWATCH to 'forget' it. +** Detect: delete or free() of the offending pointer. +** Action: The delete or free() is cancelled, execution continues. +** NULL free: +** It's unclear to me whether or not freeing of NULL pointers +** is legal in ANSI C, therefore a warning is written to the log file, +** but the error counter remains the same. This is legal using C++, +** so the warning does not appear with delete. +** Detect: When you free(NULL). +** Action: The free() is cancelled. +** Failed: +** A request to allocate memory failed. If the allocation is +** small, this may be due to memory depletion, but is more likely +** to be memory fragmentation problems. The amount of memory +** allocated so far is displayed also. +** Detect: When you new, malloc(), realloc() or calloc() memory. +** Action: NULL is returned. +** Realloc: +** A request to re-allocate a memory buffer failed for reasons +** other than out-of-memory. The specific reason is shown. +** Detect: When you realloc() +** Action: realloc() is cancelled, NULL is returned +** Limit fail: +** A request to allocate memory failed since it would violate +** the limit set using mwLimit(). mwLimit() is used to stress-test +** your code under simulated low memory conditions. +** Detect: At new, malloc(), realloc() or calloc(). +** Action: NULL is returned. +** Assert trap: +** An ASSERT() failed. The ASSERT() macro works like C's assert() +** macro/function, except that it's interactive. See your C manual. +** Detect: On the ASSERT(). +** Action: Program ends with an advisory message to stderr, OR +** Program writes the ASSERT to the log and continues, OR +** Program asks Abort/Retry/Ignore? and takes that action. +** Verify trap: +** A VERIFY() failed. The VERIFY() macro works like ASSERT(), +** but if MEMWATCH is not defined, it still evaluates the +** expression, but it does not act upon the result. +** Detect: On the VERIFY(). +** Action: Program ends with an advisory message to stderr, OR +** Program writes the VERIFY to the log and continues, OR +** Program asks Abort/Retry/Ignore? and takes that action. +** Wild pointer: +** A no-mans-land buffer has been written into. MEMWATCH can +** allocate and distribute chunks of memory solely for the +** purpose of trying to catch random writes into memory. +** Detect: Always on CHECK(), but can be detected in several places. +** Action: The error is logged, and if an ARI handler is installed, +** it is executed, otherwise, execution continues. +** Unfreed: +** A memory buffer you allocated has not been freed. +** You are informed where it was allocated, and whether any +** over or underflow has occured. MemWatch also displays up to +** 16 bytes of the data, as much as it can, in hex and text. +** Detect: When MemWatch terminates. +** Action: The buffer is freed. +** Check: +** An error was detected during a CHECK() operation. +** The associated pointer is displayed along with +** the file and line where the CHECK() was executed. +** Followed immediately by a normal error message. +** Detect: When you CHECK() +** Action: Depends on the error +** Relink: +** After a MEMWATCH internal control block has been trashed, +** MEMWATCH tries to repair the damage. If successful, program +** execution will continue instead of aborting. Some information +** about the block may be gone permanently, though. +** Detect: N/A +** Action: Relink successful: program continues. +** Relink fails: program aborts. +** Internal: +** An internal error is flagged by MEMWATCH when it's control +** structures have been damaged. You are likely using an uninitialized +** pointer somewhere in your program, or are zapping memory all over. +** The message may give you additional diagnostic information. +** If possible, MEMWATCH will recover and continue execution. +** Detect: Various actions. +** Action: Whatever is needed +** Mark: +** The program terminated without umarking all marked pointers. Marking +** can be used to track resources other than memory. mwMark(pointer,text,...) +** when the resource is allocated, and mwUnmark(pointer) when it's freed. +** The 'text' is displayed for still marked pointers when the program +** ends. +** Detect: When MemWatch terminates. +** Action: The error is logged. +** +** +************************************************************************ +** +** The author may be reached by e-mail at the address below. If you +** mail me about source code changes in MEMWATCH, remember to include +** MW's version number. +** +** Johan Lindh +** johan@linkdata.se +** +** The latest version of MEMWATCH may be downloaded from +** http://www.linkdata.se/ +*/ + +#ifndef __MEMWATCH_H +#define __MEMWATCH_H + +/* Make sure that malloc(), realloc(), calloc() and free() are declared. */ +/*lint -save -e537 */ +#include +/*lint -restore */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** Constants used +** All MEMWATCH constants start with the prefix MW_, followed by +** a short mnemonic which indicates where the constant is used, +** followed by a descriptive text about it. +*/ + +#define MW_ARI_NULLREAD 0x10 /* Null read (to start debugger) */ +#define MW_ARI_ABORT 0x04 /* ARI handler says: abort program! */ +#define MW_ARI_RETRY 0x02 /* ARI handler says: retry action! */ +#define MW_ARI_IGNORE 0x01 /* ARI handler says: ignore error! */ + +#define MW_VAL_NEW 0xFE /* value in newly allocated memory */ +#define MW_VAL_DEL 0xFD /* value in newly deleted memory */ +#define MW_VAL_NML 0xFC /* value in no-mans-land */ +#define MW_VAL_GRB 0xFB /* value in grabbed memory */ + +#define MW_TEST_ALL 0xFFFF /* perform all tests */ +#define MW_TEST_CHAIN 0x0001 /* walk the heap chain */ +#define MW_TEST_ALLOC 0x0002 /* test allocations & NML guards */ +#define MW_TEST_NML 0x0004 /* test all-NML areas for modifications */ + +#define MW_NML_NONE 0 /* no NML */ +#define MW_NML_FREE 1 /* turn FREE'd memory into NML */ +#define MW_NML_ALL 2 /* all unused memory is NML */ +#define MW_NML_DEFAULT 0 /* the default NML setting */ + +#define MW_STAT_GLOBAL 0 /* only global statistics collected */ +#define MW_STAT_MODULE 1 /* collect statistics on a module basis */ +#define MW_STAT_LINE 2 /* collect statistics on a line basis */ +#define MW_STAT_DEFAULT 0 /* the default statistics setting */ + +/* +** MemWatch internal constants +** You may change these and recompile MemWatch to change the limits +** of some parameters. Respect the recommended minimums! +*/ +#define MW_TRACE_BUFFER 2048 /* (min 160) size of TRACE()'s output buffer */ +#define MW_FREE_LIST 64 /* (min 4) number of free()'s to track */ + +/* +** Exported variables +** In case you have to remove the 'const' keyword because your compiler +** doesn't support it, be aware that changing the values may cause +** unpredictable behaviour. +** - mwCounter contains the current action count. You can use this to +** place breakpoints using a debugger, if you want. +*/ +#ifndef __MEMWATCH_C +extern const unsigned long mwCounter; +#endif + +/* +** System functions +** Normally, it is not nessecary to call any of these. MEMWATCH will +** automatically initialize itself on the first MEMWATCH function call, +** and set up a call to mwAbort() using atexit(). Some C++ implementations +** run the atexit() chain before the program has terminated, so you +** may have to use mwInit() or the MemWatch C++ class to get good +** behaviour. +** - mwInit() can be called to disable the atexit() usage. If mwInit() +** is called directly, you must call mwTerm() to end MemWatch, or +** mwAbort(). +** - mwTerm() is usually not nessecary to call; but if called, it will +** call mwAbort() if it finds that it is cancelling the 'topmost' +** mwInit() call. +** - mwAbort() cleans up after MEMWATCH, reports unfreed buffers, etc. +*/ +void mwInit( void ); +void mwTerm( void ); +void mwAbort( void ); + +/* +** Setup functions +** These functions control the operation of MEMWATCH's protective features. +** - mwFlushNow() causes MEMWATCH to flush it's buffers. +** - mwDoFlush() controls whether MEMWATCH flushes the disk buffers after +** writes. The default is smart flushing: MEMWATCH will not flush buffers +** explicitly until memory errors are detected. Then, all writes are +** flushed until program end or mwDoFlush(0) is called. +** - mwLimit() sets the allocation limit, an arbitrary limit on how much +** memory your program may allocate in bytes. Used to stress-test app. +** Also, in virtual-memory or multitasking environs, puts a limit on +** how much MW_NML_ALL can eat up. +** - mwGrab() grabs up X kilobytes of memory. Allocates actual memory, +** can be used to stress test app & OS both. +** - mwDrop() drops X kilobytes of grabbed memory. +** - mwNoMansLand() sets the behaviour of the NML logic. See the +** MW_NML_xxx for more information. The default is MW_NML_DEFAULT. +** - mwStatistics() sets the behaviour of the statistics collector. See +** the MW_STAT_xxx defines for more information. Default MW_STAT_DEFAULT. +** - mwFreeBufferInfo() enables or disables the tagging of free'd buffers +** with freeing information. This information is written in text form, +** using sprintf(), so it's pretty slow. Disabled by default. +** - mwAutoCheck() performs a CHECK() operation whenever a MemWatch function +** is used. Slows down performance, of course. +** - mwCalcCheck() calculates checksums for all data buffers. Slow! +** - mwDumpCheck() logs buffers where stored & calc'd checksums differ. Slow!! +** - mwMark() sets a generic marker. Returns the pointer given. +** - mwUnmark() removes a generic marker. If, at the end of execution, some +** markers are still in existence, these will be reported as leakage. +** returns the pointer given. +*/ +void mwFlushNow( void ); +void mwDoFlush( int onoff ); +void mwLimit( long bytes ); +unsigned mwGrab( unsigned kilobytes ); +unsigned mwDrop( unsigned kilobytes ); +void mwNoMansLand( int mw_nml_level ); +void mwStatistics( int level ); +void mwFreeBufferInfo( int onoff ); +void mwAutoCheck( int onoff ); +void mwCalcCheck( void ); +void mwDumpCheck( void ); +void * mwMark( void *p, const char *description, const char *file, unsigned line ); +void * mwUnmark( void *p, const char *file, unsigned line ); + +/* +** Testing/verification/tracing +** All of these macros except VERIFY() evaluates to a null statement +** if MEMWATCH is not defined during compilation. +** - mwIsReadAddr() checks a memory area for read privilige. +** - mwIsSafeAddr() checks a memory area for both read & write privilige. +** This function and mwIsReadAddr() is highly system-specific and +** may not be implemented. If this is the case, they will default +** to returning nonzero for any non-NULL pointer. +** - CHECK() does a complete memory integrity test. Slow! +** - CHECK_THIS() checks only selected components. +** - CHECK_BUFFER() checks the indicated buffer for errors. +** - mwASSERT() or ASSERT() If the expression evaluates to nonzero, execution continues. +** Otherwise, the ARI handler is called, if present. If not present, +** the default ARI action is taken (set with mwSetAriAction()). +** ASSERT() can be disabled by defining MW_NOASSERT. +** - mwVERIFY() or VERIFY() works just like ASSERT(), but when compiling without +** MEMWATCH the macro evaluates to the expression. +** VERIFY() can be disabled by defining MW_NOVERIFY. +** - mwTRACE() or TRACE() writes some text and data to the log. Use like printf(). +** TRACE() can be disabled by defining MW_NOTRACE. +*/ +int mwIsReadAddr( const void *p, unsigned len ); +int mwIsSafeAddr( void *p, unsigned len ); +int mwTest( const char *file, int line, int mw_test_flags ); +int mwTestBuffer( const char *file, int line, void *p ); +int mwAssert( int, const char*, const char*, int ); +int mwVerify( int, const char*, const char*, int ); + +/* +** User I/O functions +** - mwTrace() works like printf(), but dumps output either to the +** function specified with mwSetOutFunc(), or the log file. +** - mwPuts() works like puts(), dumps output like mwTrace(). +** - mwSetOutFunc() allows you to give the adress of a function +** where all user output will go. (exeption: see mwSetAriFunc) +** Specifying NULL will direct output to the log file. +** - mwSetAriFunc() gives MEMWATCH the adress of a function to call +** when an 'Abort, Retry, Ignore' question is called for. The +** actual error message is NOT printed when you've set this adress, +** but instead it is passed as an argument. If you call with NULL +** for an argument, the ARI handler is disabled again. When the +** handler is disabled, MEMWATCH will automatically take the +** action specified by mwSetAriAction(). +** - mwSetAriAction() sets the default ARI return value MEMWATCH should +** use if no ARI handler is specified. Defaults to MW_ARI_ABORT. +** - mwAriHandler() is an ANSI ARI handler you can use if you like. It +** dumps output to stderr, and expects input from stdin. +** - mwBreakOut() is called in certain cases when MEMWATCH feels it would +** be nice to break into a debugger. If you feel like MEMWATCH, place +** an execution breakpoint on this function. +*/ +void mwTrace( const char* format_string, ... ); +void mwPuts( const char* text ); +void mwSetOutFunc( void (*func)(int) ); +void mwSetAriFunc( int (*func)(const char*) ); +void mwSetAriAction( int mw_ari_value ); +int mwAriHandler( const char* cause ); +void mwBreakOut( const char* cause ); + +/* +** Allocation/deallocation functions +** These functions are the ones actually to perform allocations +** when running MEMWATCH, for both C and C++ calls. +** - mwMalloc() debugging allocator +** - mwMalloc_() always resolves to a clean call of malloc() +** - mwRealloc() debugging re-allocator +** - mwRealloc_() always resolves to a clean call of realloc() +** - mwCalloc() debugging allocator, fills with zeros +** - mwCalloc_() always resolves to a clean call of calloc() +** - mwFree() debugging free. Can only free memory which has +** been allocated by MEMWATCH. +** - mwFree_() resolves to a) normal free() or b) debugging free. +** Can free memory allocated by MEMWATCH and malloc() both. +** Does not generate any runtime errors. +*/ +void* mwMalloc( size_t, const char*, int ); +void* mwMalloc_( size_t ); +void* mwRealloc( void *, size_t, const char*, int ); +void* mwRealloc_( void *, size_t ); +void* mwCalloc( size_t, size_t, const char*, int ); +void* mwCalloc_( size_t, size_t ); +void mwFree( void*, const char*, int ); +void mwFree_( void* ); +char* mwStrdup( const char *, const char*, int ); + +/* +** Enable/disable precompiler block +** This block of defines and if(n)defs make sure that references +** to MEMWATCH is completely removed from the code if the MEMWATCH +** manifest constant is not defined. +*/ +#ifndef __MEMWATCH_C +#ifdef MEMWATCH + +#define mwASSERT(exp) while(mwAssert((int)(exp),#exp,__FILE__,__LINE__)) +#ifndef MW_NOASSERT +#ifndef ASSERT +#define ASSERT mwASSERT +#endif /* !ASSERT */ +#endif /* !MW_NOASSERT */ +#define mwVERIFY(exp) while(mwVerify((int)(exp),#exp,__FILE__,__LINE__)) +#ifndef MW_NOVERIFY +#ifndef VERIFY +#define VERIFY mwVERIFY +#endif /* !VERIFY */ +#endif /* !MW_NOVERIFY */ +#define mwTRACE mwTrace +#ifndef MW_NOTRACE +#ifndef TRACE +#define TRACE mwTRACE +#endif /* !TRACE */ +#endif /* !MW_NOTRACE */ + +/* some compilers use a define and not a function */ +/* for strdup(). */ +#ifdef strdup +#undef strdup +#endif + +#define malloc(n) mwMalloc(n,__FILE__,__LINE__) +#define strdup(p) mwStrdup(p,__FILE__,__LINE__) +#define realloc(p,n) mwRealloc(p,n,__FILE__,__LINE__) +#define calloc(n,m) mwCalloc(n,m,__FILE__,__LINE__) +#define free(p) mwFree(p,__FILE__,__LINE__) +#define CHECK() mwTest(__FILE__,__LINE__,MW_TEST_ALL) +#define CHECK_THIS(n) mwTest(__FILE__,__LINE__,n) +#define CHECK_BUFFER(b) mwTestBuffer(__FILE__,__LINE__,b) +#define MARK(p) mwMark(p,#p,__FILE__,__LINE__) +#define UNMARK(p) mwUnmark(p,__FILE__,__LINE__) + +#else /* MEMWATCH */ + +#define mwASSERT(exp) +#ifndef MW_NOASSERT +#ifndef ASSERT +#define ASSERT mwASSERT +#endif /* !ASSERT */ +#endif /* !MW_NOASSERT */ + +#define mwVERIFY(exp) exp +#ifndef MW_NOVERIFY +#ifndef VERIFY +#define VERIFY mwVERIFY +#endif /* !VERIFY */ +#endif /* !MW_NOVERIFY */ + +/*lint -esym(773,mwTRACE) */ +#define mwTRACE /*lint -save -e506 */ 1?(void)0:mwDummyTraceFunction /*lint -restore */ +#ifndef MW_NOTRACE +#ifndef TRACE +/*lint -esym(773,TRACE) */ +#define TRACE mwTRACE +#endif /* !TRACE */ +#endif /* !MW_NOTRACE */ + +extern void mwDummyTraceFunction(const char *,...); +/*lint -save -e652 */ +#define mwDoFlush(n) +#define mwPuts(s) +#define mwInit() +#define mwGrab(n) +#define mwDrop(n) +#define mwLimit(n) +#define mwTest(f,l) +#define mwSetOutFunc(f) +#define mwSetAriFunc(f) +#define mwDefaultAri() +#define mwNomansland() +#define mwStatistics(f) +#define mwMark(p,t,f,n) (p) +#define mwUnmark(p,f,n) (p) +#define mwMalloc(n,f,l) malloc(n) +#define mwStrdup(p,f,l) strdup(p) +#define mwRealloc(p,n,f,l) realloc(p,n) +#define mwCalloc(n,m,f,l) calloc(n,m) +#define mwFree(p) free(p) +#define mwMalloc_(n) malloc(n) +#define mwRealloc_(p,n) realloc(p,n) +#define mwCalloc_(n,m) calloc(n,m) +#define mwFree_(p) free(p) +#define mwAssert(e,es,f,l) +#define mwVerify(e,es,f,l) (e) +#define mwTrace mwDummyTrace +#define mwTestBuffer(f,l,b) (0) +#define CHECK() +#define CHECK_THIS(n) +#define CHECK_BUFFER(b) +#define MARK(p) (p) +#define UNMARK(p) (p) +/*lint -restore */ + +#endif /* MEMWATCH */ +#endif /* !__MEMWATCH_C */ + +#ifdef __cplusplus + } +#endif + +#if 0 /* 980317: disabled C++ */ + +/* +** C++ support section +** Implements the C++ support. Please note that in order to avoid +** messing up library classes, C++ support is disabled by default. +** You must NOT enable it until AFTER the inclusion of all header +** files belonging to code that are not compiled with MEMWATCH, and +** possibly for some that are! The reason for this is that a C++ +** class may implement it's own new() function, and the preprocessor +** would substitute this crucial declaration for MEMWATCH new(). +** You can forcibly deny C++ support by defining MEMWATCH_NOCPP. +** To enble C++ support, you must be compiling C++, MEMWATCH must +** be defined, MEMWATCH_NOCPP must not be defined, and finally, +** you must define 'new' to be 'mwNew', and 'delete' to be 'mwDelete'. +** Unlike C, C++ code can begin executing *way* before main(), for +** example if a global variable is created. For this reason, you can +** declare a global variable of the class 'MemWatch'. If this is +** is the first variable created, it will then check ALL C++ allocations +** and deallocations. Unfortunately, this evaluation order is not +** guaranteed by C++, though the compilers I've tried evaluates them +** in the order encountered. +*/ +#ifdef __cplusplus +#ifndef __MEMWATCH_C +#ifdef MEMWATCH +#ifndef MEMWATCH_NOCPP +extern int mwNCur; +extern const char *mwNFile; +extern int mwNLine; +class MemWatch { +public: + MemWatch(); + ~MemWatch(); + }; +void * operator new(size_t); +void * operator new(size_t,const char *,int); +void * operator new[] (size_t,const char *,int); // hjc 07/16/02 +void operator delete(void *); +#define mwNew new(__FILE__,__LINE__) +#define mwDelete (mwNCur=1,mwNFile=__FILE__,mwNLine=__LINE__),delete +#endif /* MEMWATCH_NOCPP */ +#endif /* MEMWATCH */ +#endif /* !__MEMWATCH_C */ +#endif /* __cplusplus */ + +#endif /* 980317: disabled C++ */ + +#endif /* __MEMWATCH_H */ + +/* EOF MEMWATCH.H */ diff --git a/plat/public/src/include/omc_public.h b/plat/public/src/include/omc_public.h new file mode 100644 index 0000000..0e334cd --- /dev/null +++ b/plat/public/src/include/omc_public.h @@ -0,0 +1,643 @@ + +/************************************************************************/ +/* Title: omc_public.h */ +/* Desc: Public variables def for PACS OMC Project. */ +/* Author: Meng Xiaozhen */ +/* CrtDate: 2000-08-16 */ +/* AltDate: 2001-06-21 */ +/* CVS: $Id: omc_public.h,v 1.1 2000/08/03 01:09:33 mengxz Exp $ */ +/************************************************************************/ +#ifndef OMC_PUBLIC__H +#define OMC_PUBLIC__H + +#ifndef PUBLIC__H + #include "public.h" +#endif + +#ifndef IPTRANS__H + #include "iptrans.h" +#endif + +#define DEBUG 1 + +/***************************************************/ +/* Macro define for Server's system number */ +#define GRP_NUM 32 + +#define TS_NUM 32 +#define TS_SUB 16 +#define TS_E1 8 + +#define PW_NUM 32 +#define PW_SUB 3 + +#define ETH_NUM 32 +#define ETH_SUB 16 + +#define RDEV_NUM 32 +#define RDEV_SUB 8 +#define RDEV_E1 1 + +#define BSS_NUM 48 + +#define BSC_NUM 12 +#define BSC_SUB 9 +#define BSC_E1 2 + +#define BTS_NUM 24 //BTS system include 12 BTS subsystem +#define BTSSITE_NUM 48 //BTS site include 6 BTS subsystem +#define BTS_SUB 12 +#define BTS_E1 2 + +#define SVR_NUM 36 + +#define CONN_NUM 128 +#define CLIENT_NUM 50 +#define BTN_NUM 66 + +#define ALARM_NUM 20 +#define CACHE_BUF 512 +/***************************************************/ + +/***************************************************/ +/* Macro definition of start ID for applet's button used by system device */ +#define TS_START_BTN 0 +#define RDEV_START_BTN 18 +#define SVR_START_BTN 34 +#define BSC_START_BTN 54 +/***************************************************/ + + +/***************************************************/ +/* Macro define for Server's IP Address */ +#define OMC_0 "172.18.128.1" +#define OMC_1 "172.18.129.1" +#define HLR_0 "172.18.132.1" +#define HLR_1 "172.18.133.1" +#define PPS_0 "172.18.136.1" +#define PPS_1 "172.18.137.1" +#define CDR_0 "172.18.160.1" +#define CDR_1 "172.18.161.1" +/***************************************************/ + +/***************************************************/ +/* Macro define for Mysql Database */ +#define HOST_NAME "localhost" +#define DB_NAME1 "mysql" +#define DB_PORT_NUM 0 +#define SOCKET_NAME NULL +#define FLAGS 0 +#define USER_NAME "root" +#define PASSWORD "rootaa" +/***************************************************/ + +/***************************************************/ +/* Macro def for (UDP)Communication port used by OMC */ +#define PORT_OUT 4951 //for sending message to ts +#define PORT_BASE 4951 +#define PORT_REALSTAT 3 /* 4951 + 3 = 4954 */ +#define PORT_CSTA 4 /* 4951 + 4 = 4955 */ +#define PORT_COMM 5 /* 4951 + 5 = 4956 */ +#define PORT_HEARTBEAT 6 /* 4951 + 6 = 4957 */ +#define PORT_CLUSTER 27 /* 4951 + 27 =4978 */ +#define BROADCAST_IP "172.18.255.255" +#define CLUSTER_IP "239.255.10.1" +#define BROADCAST 0 //if broadcast message + +/***************************************************/ +/* Macro def for shm key and sem key used by OMC */ +#define COMM_FLAG_SHM_KEY 0x6a000000 +#define COMM_FLAG_SHM_PERM 0666 +#define COMM_FLAG_SEM_KEY 300 +#define COMM_FLAG_SEM_PERM 0666 +#define COMM_FLAG_SEM_NUM 1 +#define COMM_FLAG_SIZE 1024 + +#define COMM_LIST_SHM_KEY 0x6a100000 +#define COMM_LIST_SHM_PERM 0666 +#define COMM_LIST_SEM_KEY 310 +#define COMM_LIST_SEM_PERM 0666 +#define COMM_LIST_SEM_NUM 1 + +#define STATUS_SHM_KEY 0x6a200000 +#define STATUS_SHM_PERM 0666 +#define STATUS_SEM_KEY 320 +#define STATUS_SEM_PERM 0666 +#define STATUS_SEM_NUM 1 + +#define CACHE_SHM_KEY 0x6a400000 +#define CACHE_SHM_PERM 0666 +#define CACHE_SEM_KEY 340 +#define CACHE_SEM_PERM 0666 +#define CACHE_SEM_NUM 1 + +#define BSS_SHM_KEY 0x6a600000 +#define BSS_SHM_PERM 0666 +#define BSS_SEM_KEY 360 +#define BSS_SEM_PERM 0666 +#define BSS_SEM_NUM 1 + +#define LED_SHM_KEY 0x6a800000 +#define LED_SHM_PERM 0666 +#define LED_SEM_KEY 380 +#define LED_SEM_PERM 0666 +#define LED_SEM_NUM 1 + +#define CLUSTER_SHM_KEY 0x6a900000 +#define CLUSTER_SHM_PERM 0666 +#define CLUSTER_SEM_KEY 390 +#define CLUSTER_SEM_PERM 0666 +#define CLUSTER_SEM_NUM 1 +/***************************************************/ + +/*############################################################################ + * shm structure + * between heartbeat transceiver and heartbeat processor + * & + * between heartbeat transceiver and svr cluster processor + *###########################################################################*/ + typedef struct cache_list{ + long msgSrcIP; + u_short msgLength; + BYTE msgContent[CACHE_BUF]; + }cache_list; + + typedef struct status_cahce{ + //int send_flag; + /*this flag is only for server cluster funciton + *0/1/2=ignore cluster FSM influence,directly send heartbeat/cluster permit *to send heartbeat/can't send heartbeat,waiting cluster's info + */ + u_short msgReadSub; + u_short msgWriteSub; + cache_list msgcache[CACHE_BUF]; + }status_cache; + +/*############################################################################ + * shm structure between real status processor and heartbeat processor + *###########################################################################*/ + +typedef struct clientinfo { + BYTE used_flag; // 0/1=not used/used + BYTE grp_id; // group which is requested by client now + BYTE is_responsed; // 0/1/2=not response/responsing/responsed + long ip; + unsigned int waittime; //if waittime>60seconds,timeout + BYTE updatetime[16]; //last time when client request info +} client_info; + +typedef struct conninfo { + BYTE avail_flag; // 0/1=unavailable/available + BYTE disp_name; // 0/1=not display/display + char name[16]; + char remark[44]; + BYTE lsys_type;// local device system type + BYTE lsys_id; //local device system id + BYTE lsub_id; //local device subsystem id + BYTE rsys_type; //remote device system type + BYTE rsys_id; //remote device system id + BYTE rsub_id; //remote device subsystem id +} conn_info; + +typedef struct btninfo { + BYTE used_flag; // 0/1=not use/used + BYTE sys_type; // device system type + BYTE sys_id; // device system id + BYTE sub_id; // device subsystem id +} btn_info; + +typedef struct grp_simple_stat { + btn_info btn[BTN_NUM]; // relationship between button and device + unsigned int coord[2]; // X,Y coord for group icon + int critical; // critical counter + int alarm; // alarm counter + BYTE isinstalled; // 0/1=not install/install + BYTE ts_id[2]; // Transit switch id(default=99,no ts) + BYTE disp_name; // 0/1=not display/display + BYTE grp_name[17]; // Group name + BYTE grp_remark[45]; // remark about group + BYTE stat_amount; // number of status for group icon + BYTE stat_direct; // direction of display status (0/1=h/v) + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3= uninstalled + */ +}grpsimple_stat; + +typedef struct subts_detail_stat { + BYTE subtype; //subsystem status + BYTE timeout; //if the subsystem is timeout(0/1=timeout/not) + BYTE substat0[8];// simple status of this subsystem + /* substat0[0] -- if subsys is installed(0/1=not/yes) + * substat0[1] -- if subsys is normal(0/1=abnormal/normal) + * substat0[2] -- if subsys send master clock(0/1=not/sending) + * substat0[3] -- locking clock(0-7:2=normal,7=idle,other=abnormal) + */ + BYTE substat1[8]; // performance or status data of subsystem + /* substat1[0-1] -- CPU Load ('00'-'45') + * substat1[2-4] -- Clock frequency('000'-'255') + */ + + BYTE e1stat0[TS_E1][8]; //simple status of all E1 + /* e1[i][0] -- e1[i] installed/not installed (0/1=not/yes) + * e1[i][1] -- e1[i] layer 2 installed/not installed (0/1=not/yes) + * e1[i][2] -- e1[i] layer 1 connected/disconnected (0/1=not/yes) + * e1[i][3] -- e1[i] layer 2 connected/disconnected (0/1=not/yes) + * e1[i][4] -- e1[i] without/with ECHO CANCELLER (0/1=not/yes) + */ + BYTE e1stat1[TS_E1][8]; // performance or status data of all E1 + /* e1[i][0-1] -- e1[i] idle channels('00'/'30') + */ + + long lock_alarmtime; + /*last time inserting alarm log into db because of clock locking error + */ + long e1_alarmtime[TS_E1][2]; + /*last time inserting alarm log into db because of e1 1,2th error + */ + BYTE version_info[16]; + /*version information for the application + */ + BYTE updatetime[16]; //last time refreshing subsystem status +}subtsdetail_stat; + +typedef struct subpw_detail_stat { + BYTE timeout; //if the subsystem is timeout(0/1=timeout/not) + BYTE substat[2]; // status of this subsystem(0/1=abnomal/normal) + /* substat[0] -- if subsys is installed(0/1=not/yes) + * substat[1] -- if subsys is normal(0/1=abnormal/normal) + */ + + long pcard_alarmtime; + /*last time inserting alarm log into db because of power card error + */ + BYTE updatetime[16]; //last time refreshing subsystem status +}subpwdetail_stat; + +typedef struct ts_detail_stat { + BYTE grp_id; + BYTE clock_status;//if master clock is normal(0/1=N/Y) + long clock_alarmtime;//master clock status + /*last time inserting alarm log into db because of master clock error + */ + subtsdetail_stat sub_detail[TS_SUB]; + subpwdetail_stat subpw_detail[PW_SUB]; +}tsdetail_stat; + +typedef struct subts_simple_stat { + BYTE isinstalled; + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + int waittime; // if TS subsystem is timeout + BYTE issent ; // if sending get request to timeout ts subsystem +} subtssimple_stat; + + +typedef struct ts_simple_stat { + BYTE isinstalled; // 0/1=N/Y + BYTE location; // 0/1=local/remote + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + BYTE grp_id; + BYTE disp_name; // 0/1=not display/display + BYTE name[16]; + BYTE remark[44]; + int coord[2]; + BYTE stat_amount; // number of status for ts icon + BYTE stat_direct; // direction of display status (0/1=h/v) + subtssimple_stat sub_simple[TS_SUB]; + subtssimple_stat subpw_simple[PW_SUB]; +} tssimple_stat; + +typedef struct subeth_detail_stat { + BYTE timeout; //if the subsystem is timeout(0/1=timeout/not) + long self_ip; //ip address of LAN Module self + BYTE mac[6]; //physical address of LAN Module + + BYTE substat[6]; + /* substat[0] -- if LAN Module is installed(0/1) + * substat[1] -- if LAN Module is normal(0/1) + * substat[2] -- if there is unreachable ip(0/1) + * substat[3] -- if LAN Module upload program to csu(0/1) + * substat[4] -- if csu is availabe (0/1) + */ + + BYTE cpu_load[2]; //CPU load of LAN module(hex value) + BYTE unreachable_ip[4]; //ip Can't be found by LAN Module (hex value) + long unreach_time; + + long alarmtime[2]; + /*CSU Upload program status + *alarmtime[0] -- can't reach target ip address + *alarmtime[1] -- uploading program + */ + BYTE version_info[16]; + /*version information for the application + */ + char updatetime[16]; +}subethdetail_stat; + +typedef struct eth_detail_stat { + BYTE grp_id; + subethdetail_stat sub_detail[ETH_SUB]; +}ethdetail_stat; + +typedef struct subeth_simple_stat { + BYTE isinstalled; + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + int waittime; // if TS subsystem is timeout + BYTE issent ; // if sending get request to timeout ts subsystem +} subethsimple_stat; + +typedef struct eth_simple_stat { + BYTE isinstalled; // 0/1=N/Y + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + BYTE grp_id; + subethsimple_stat sub_simple[ETH_SUB]; +} ethsimple_stat; + +typedef struct subrdev_detail_stat { + BYTE subtype; //0-4 + + BYTE timeout; //if the subsystem is timeout(0/1=timeout/not) + BYTE substat0[6]; + /* substat[0] -- if subsys is installed(0/1=N/Y) + * substat[1] -- if subsys is normal(0/1=N/Y) + * sysstat[2] -- if send master clock(0/1=N/Y) + */ + BYTE substat1[6]; + /* substat[0-1] -- used CPU(00/30) + */ + + BYTE e1stat0[RDEV_E1][8]; + /* e1[0] -- e1 installed/not installed (0/1=N/Y) + * e1[1] -- e1 layer 1 connected/disconnected (0/1=N/Y) + * e1[2] -- e1 layer 2 connected/disconnected (0/1=N/Y) + */ + BYTE e1stat1[RDEV_E1][8]; + /* e1[i][0-1] -- e1 idle channels('00'--'30') + */ + + long e1_alarmtime[RDEV_E1][2]; + /* alarmtime[i][0] -- e1[i] layer 1 + * alarmtime[i][1] -- e1[i] layer 2 + */ + BYTE version_info[16]; + /*version information for the application + */ + char updatetime[16]; +}subrdevdetail_stat; + +typedef struct rdev_detail_stat { + BYTE grp_id; + BYTE systype; //05=VPS;06=PCR + BYTE clock_status;//if master clock is normal(0/1=N/Y) + long clock_alarmtime;//master clock status + /*last time inserting alarm log into db because of master clock error + */ + subrdevdetail_stat sub_detail[RDEV_SUB]; +}rdevdetail_stat; + +typedef struct subrdev_simple_stat { + BYTE isinstalled; + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + int waittime; // if Rdev subsystem is timeout + BYTE issent ; // if sending get request to timeout ts subsystem +} subrdevsimple_stat; + +typedef struct rdev_simple_stat { + BYTE isinstalled; // 0/1=N/Y + BYTE location; // 0/1=local/remote + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + BYTE grp_id; + BYTE disp_name; // 0/1=not display/display + BYTE name[16]; + BYTE remark[44]; + int coord[2]; + BYTE stat_amount; // number of status for rdev icon + BYTE stat_direct; // direction of display status (0/1=h/v) + subrdevsimple_stat sub_simple[RDEV_SUB]; +} rdevsimple_stat; + +typedef struct bts_simple_stat { + BYTE isinstalled; // 0/1=not/installed + BYTE bts_site_id; + BYTE bts_link_id; + BYTE location; // 0/1=local/remote + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + BYTE grp_id; + BYTE disp_name; // 0/1=not display/display + BYTE name[16]; + BYTE remark[44]; + int coord[2]; + BYTE stat_amount; // number of status for bts site icon + BYTE stat_direct; // direction of display status (0/1=h/v) +} btssimple_stat; + +typedef struct bsc_simple_stat { + BYTE isinstalled; // 0/1=not/installed + BYTE location; // 0/1=local/remote + BYTE timeout; // 0/1=timeout/not timeout + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + BYTE grp_id; + BYTE disp_name; // 0/1=not display/display + BYTE name[16]; + BYTE remark[44]; + int coord[2]; + BYTE stat_amount; // number of status for bsc icon + BYTE stat_direct; // direction of display status (0/1=h/v) +} bscsimple_stat; + + +/* structure for server detail status in heartbeat processor + ************************************/ +typedef struct svr_detail_stat { + BYTE timeout; //if the subsystem is timeout(0/1=not/timeout) + BYTE grp_id; + BYTE systype; + BYTE sys_id; + int cpuused; + int viravail; + int virfree; + int memavail; + int memfree; + int hdavail; + int hdfree; + BYTE init_progress[3]; + BYTE proc_id[16]; + BYTE proc_status[16]; + BYTE subproc_num[16]; + BYTE sysstat[16]; // 0/1=abnormal/normal + /* + * 0=Normal,1=abnormal + *sysstat[0]: system status + * sysstat[1]:cpu status sysstat[2]:swap status + * sysstat[3]:memory status sysstat[4]:disk status + * sysstat[5]:proc_status sysstat[6]:server working status + * sysstat[7]:database status + */ + long alarmtime[6]; + + BYTE version_info[16]; + /*version information for the application + */ + BYTE updatetime[16]; +} svrdetail_stat; + +typedef struct svr_simple_stat { + BYTE grp_id; + BYTE location; + BYTE isinstalled; + int waittime; + BYTE ischanged; + /* 0/1=N/Y,process will send message to client if status is changed + */ + BYTE status; + /*0=critical ; 1=normal ; 2=alarm ; 3=uninstalled + */ + int critical; // critical counter + int alarm; // alarm counter + BYTE disp_name; // 0/1=not display/display + BYTE name[16]; + BYTE remark[44]; + int coord[2]; + BYTE stat_amount; // number of status for bts site icon + BYTE stat_direct; // direction of display status (0/1=h/v) +} svrsimple_stat; + +struct alarm_log { + BYTE systype; + BYTE sys_id; + BYTE sub_id; + BYTE e1no; + BYTE alarmnum; + BYTE occurtime[16]; +}; + +typedef struct ts_alarm_log { + int readSub; + int writeSub; + struct alarm_log alrlist[ALARM_NUM]; +} tsalarm_log; + +typedef struct ask_alarm_log { + long client_ip; //ip address where the request is sent from + int init_Req_Flag; + int readSub; + int writeSub; + struct alarm_log alrlist[ALARM_NUM]; +} askalarm_log; + +/* + * shared memory structure + *************************/ +typedef struct shm_ts_stat { + BYTE init_flag; + BYTE sys_struct;//0/1=single/double plane system structure + grpsimple_stat grp_simple[GRP_NUM]; + tsdetail_stat ts_detail[TS_NUM]; + tssimple_stat ts_simple[TS_NUM]; + ethdetail_stat eth_detail[ETH_NUM]; + ethsimple_stat eth_simple[ETH_NUM]; + rdevdetail_stat vps_detail[RDEV_NUM]; + rdevsimple_stat vps_simple[RDEV_NUM]; + rdevdetail_stat pcr_detail[RDEV_NUM]; + rdevsimple_stat pcr_simple[RDEV_NUM]; + svrdetail_stat svr_detail[SVR_NUM]; + svrsimple_stat svr_simple[SVR_NUM]; + /* + sysnum=systype*2+sys_id + svr_simple[0]=OMC-0 + svr_simple[1]=OMC-1 + svr_simple[2]=HLR-0 + svr_simple[3]=HLR-1 + svr_simple[4]=PRP-0 + svr_simple[5]=PRP-1 + svr_simple[6]=CDR-0 + svr_simple[7]=CDR-1 + */ + bscsimple_stat bsc_simple[BSC_NUM]; + + BYTE global_status[ETH_NUM]; + conn_info connection[CONN_NUM]; + client_info client[CLIENT_NUM]; + /*global_status[0]= if normal ;global_status[1]= if changed*/ + tsalarm_log alarmlog; +} shm_stat; + +/*****************************************************************************/ +/* Lan Module's global status*/ +typedef struct global_status{ + BYTE eth_mac[ETH_NUM][ETH_SUB][7]; + long update_time[ETH_NUM][ETH_SUB]; + long alarm_time[ETH_NUM][ETH_SUB]; +}eth_global; +/***************************************************/ + +/*****************************************************************************/ +/* structure for BSS simple status in heartbeat processor + ************************************/ +typedef struct bss_simple_stat { + BYTE isinstalled[BSS_NUM]; + BYTE ischanged[BSS_NUM]; + BYTE isnormal[BSS_NUM]; + unsigned int waittime[BSS_NUM]; +} bsssimple_stat; +/***************************************************/ + +#endif /*OMC_PUBLIC__H */ diff --git a/plat/public/src/include/pub_base.h b/plat/public/src/include/pub_base.h new file mode 100644 index 0000000..a3c9709 --- /dev/null +++ b/plat/public/src/include/pub_base.h @@ -0,0 +1,127 @@ +////////////////////////////////////////////////// +//Title : pub_basic.c +//Auhtor : Liu Wei +//Desc : public basic function +//Created : 2007-06-23 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_BASE_H_ +#define _PUB_BASE_H_ + +typedef struct VALUE_STRING +{ + u32 dValue; + char *pStr; //u8 *pStr; modify by gxchen +} StringVal; + +#define ALPHA_TABLE_LOWER "abcdefghijklmnopqrstuvwsyz" +#define ALPHA_TABLE_UPPER "ABCDEFGHIJKLMNOPQRSTUVWSYZ" + +#define NOTSO(n) ( !(n) ) +#define IsNull(n) ( ((n) == NULL) ) +#define CNULL '\0' +#define IsChNull(ch) ( ch==CNULL ) +#define STR_CHECK_LAST(str,ch) ( str[strlen(str)-1] == ch ) +#define STR_CHECK_FIRST(str,ch) ( str[0] == ch ) +#define STR_CUT_LAST(str) ( str[strlen(str)-1] = CNULL ) + + +#define BitSet(arg,posn) ((arg) | (1L << (posn))) +#define BitClr(arg,posn) ((arg) & ~(1L << (posn))) +#define BitFlp(arg,posn) ((arg) ^ (1L << (posn))) +#define BitTst(arg,posn) (!(!((arg) & (1L << (posn))))) + + +#define HexToChar(ch) ( (ch) + ( ((ch) > 9)? 'A'-10 : '0') ) + +/////////////////////////////////////////////////////////////////////////// +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef MAX +#define MAX(a, b) ( (a) > (b) ? (a) : (b) ) +#define MIN(a, b) ( (a) < (b) ? (a) : (b) ) +#endif + +/////////////////////////////////////////////////////////////////////////// +// +// Name : GET_U8 GET_U16 GET_U32 +// Function : Return the u8 /u16 / u32 value of the pointer memery +// Parameter: x : pointer +// +/////////////////////////////////////////////////////////////////////////// +#define GET_U8( x ) ( *( (u8 *) (x) ) ) +#define GET_U16( x ) ( *( (u16 *) (x) ) ) +#define GET_U32( x ) ( *( (u32 *) (x) ) ) + +/////////////////////////////////////////////////////////////////////////// +// +/////////////////////////////////////////////////////////////////////////// +#define U16_LOW_BYTE ( x ) ( (u8 )( ((u16) (x) ) & 0xFF ) ) +#define U16_HIG_BYTE ( x ) ( (u8 )( ((u16) (x) ) >> 8 ) ) + +#define LSB_BYTE2WORD( uVal ) ( (((u16) (uVal)[0]) * 256) + (uVal)[1] ) +#define MSB_BYTE2WORD( uVal ) ( (((u16) (uVal)[1]) * 256) + (uVal)[0] ) + +#define LSB_WORD2BYTE( wVal , uVal ) \ + (uVal)[0] = ((wVal) / 256); \ + (uVal)[1] = ((wVal) & 0xFF ) + +#define MSB_WORD2BYTE( wVal , uVal ) \ + (uVal)[1] = ((wVal) / 256 ); \ + (uVal)[0] = ((wVal) & 0xFF) + +/////////////////////////////////////////////////////////////////////////// +// +// Name : ARR_SIZE +// Function : Return array size of a +// Parameter: a : array +// +/////////////////////////////////////////////////////////////////////////// +#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) ) + +/////////////////////////////////////////////////////////////////////////// +// +// Name : STR +// Function : Convert the s to string +// Parameter: a : a value you want to Convert to string but no need "" +// e.g. : printf(STR(if(NOTSO(a)) return 0)); +/////////////////////////////////////////////////////////////////////////// +#define STR(s) #s +#define FILL_VALSTR(n) {n,#n} +#define GET_FILE_NAME(fn) \ + { \ + static char fn[] = STR(_FILE_); \ + } + +#define GetValueString(i,p,Maxtrix,IdMax) \ + { \ + if( (i) >= (IdMax) ) \ + { \ + (p) = (u8 *)Maxtrix[(IdMax)].pStr; \ + } \ + else \ + { \ + (p) = (u8 *)Maxtrix[(i)].pStr; \ + } \ + } + +#define GET_MODULE_VER(x) (x##_VERSION) + +#define FPOS( type, field ) \ +/*lint -e545 */ ( ( dword ) & ( ( type * ) 0 )->field ) /*lint +e545 */ + +#define FSIZ( type, field ) sizeof( ((type *) 0)->field ) + +/////////////////////////////////////////////////////////////////////////// +// DivRndUp: Divide and Round Up /// +/////////////////////////////////////////////////////////////////////////// + +#define DivRndUp(Num,Div) ( ((Num) % (Div))?((Num)/(Div) + 1):((Num)/(Div)) ) + + +#endif diff --git a/plat/public/src/include/pub_debug.h b/plat/public/src/include/pub_debug.h new file mode 100644 index 0000000..ce7bafd --- /dev/null +++ b/plat/public/src/include/pub_debug.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////// +//Title : pub_debug.h +//Auhtor : Liu Wei +//Desc : public debug api header +//Created : 2007-05-01 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_DEBUG_H_ +#define _PUB_DEBUG_H_ + +#include "stdio.h" +#include "assert.h" +#include "string.h" +#include "stdlib.h" +#include +#include + + +extern void WxcDump(int nSigno); + +extern void WxcBackTrace(); + +#ifdef DEBUG +#define WxcAssert(Expression,pStr) \ + { \ + int nVal = (Expression); \ + if(!nVal) \ + { \ + WxcBackTrace(); \ + } \ + assert( nVal && pStr ); \ + } + +#else +#define WxcAssert(uVal,pStr) +#endif + +#endif + diff --git a/plat/public/src/include/pub_file.h b/plat/public/src/include/pub_file.h new file mode 100644 index 0000000..0db0864 --- /dev/null +++ b/plat/public/src/include/pub_file.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////// +//Title : wxc_file.h +//Auhtor : Liu Wei +//Desc : wxc file handle header +//Created : 2007-06-04 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_FILE_H_ +#define _PUB_FILE_H_ + +#include "./public.h" +#include "./includes.h" +#include "./pub_base.h" + + + + +#endif diff --git a/plat/public/src/include/pub_fmt.h b/plat/public/src/include/pub_fmt.h new file mode 100644 index 0000000..0248901 --- /dev/null +++ b/plat/public/src/include/pub_fmt.h @@ -0,0 +1,132 @@ +////////////////////////////////////////////////// +//Title : pub_convert.h +//Auhtor : Liu Wei +//Desc : public type fomat convert inplementation +//Created : 2007-06-24 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// lCRD software network data type assumpsit +// +// Memery Low <<============[Little Endian]===========>> Memery High +// Type abbr. e.g. Remark +// const value CVal 0x12345678 +// Host BCD HBcd/BCd 0x78 0x56 0x34 0x12 +// Anti BCD ABcd 0x87 0x65 0x43 0x21 +// NetBCD NBcd 0x12 0x34 0x56 0x78 +// String Str 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 "12345678" +// U64 U64 0x4E 0x61 0xBC 0x00 0x00 0x00 0x00 0x00 12345678=0xBC614E +// Digit Dig 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _PUB_FMT_H_ +#define _PUB_FMT_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" +#include "pub_debug.h" + +extern char HexToCh ( u8 uHex ); +extern u8 ChToHex ( char ch ); + + +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len); +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len); + +/////////////////////////////////////////////////////////////////////////// +// ReverseByte : 0010 1010 =>> 0101 0100 +// +/////////////////////////////////////////////////////////////////////////// +extern u8 ReverseByte(u8 uByteIn ); + +/////////////////////////////////////////////////////////////////////////// +// ReverseBCD : 0x12 0x34 0x56 0x78 =>> 0x21 0x43 0x65 0x87 +// +/////////////////////////////////////////////////////////////////////////// +extern void ReverseBCD( u8 *pDst , const u8 *pSrc , int nBcdLen ); + +/////////////////////////////////////////////////////////////////////////// +// ReverseArray : 0x12 0x34 0x56 0x78 =>> 0x78 0x56 0x34 0x12 +// +/////////////////////////////////////////////////////////////////////////// +extern void ReverseArray( u8 *pDst , const u8 *pSrc , int nBcdLen ); + +/////////////////////////////////////////////////////////////////////////// +// BcdToStr : 0x12 0x34 0x56 0x78 =>> "12345678" +// +/////////////////////////////////////////////////////////////////////////// +extern void BcdToStr( char *pStr , const u8 *pBcd , int nBcdLen ); + +/////////////////////////////////////////////////////////////////////////// +// BcdToU64 : 0x12 0x34 0x56 0x78 =>> 12345678 +// +////////////////////////////////////////////////////////////////////////// +extern u64 BcdToU64( const u8 *pBcd , int nBcdLen ); + +/////////////////////////////////////////////////////////////////////////// +// BcdToDig : 0x12 0x34 0x56 =>>0x01 0x02 0x03 0x04 0x05 0x06 +// +/////////////////////////////////////////////////////////////////////////// +extern int BcdToDig( u8 *pDig , int nDigBuffLen, u8 *pBcd , int nBcdLen ); + +/////////////////////////////////////////////////////////////////////////// +// StrToBcd : "123456" =>> 0x12 0x34 0x56 +// +/////////////////////////////////////////////////////////////////////////// +extern int StrToBcd( u8 *pBcd , char *pStr , int nBcdBuffLen ); + +/////////////////////////////////////////////////////////////////////////// +// U64ToBcd : 1234567 => 0x01 0x23 0x45 0x67 +// +/////////////////////////////////////////////////////////////////////////// +extern int U64ToBcd( u8 *pBcd ,u64 llInput , int nBcdBuffLen ); + +/////////////////////////////////////////////////////////////////////////// +// DigToBcd : 0x01 0x02 0x03 x04 0x05 0x06 0x07 => 0x01 0x23 0x45 0x67 +// +/////////////////////////////////////////////////////////////////////////// +extern int DigToBcd( u8* pBcd , int nBcdBuffLen , u8 *pDig , int nDigLen ); +extern int DigToBcdE( u8* pBcd , int nBcdBuffLen , u8 *pDig , int nDigLen , int nEnd ); + + +int Str2Bcd ( BYTE * pBcd, char *pStr, int maxLen ); +int Bcd2Str ( char *pStr, const BYTE * pBcd, int len ); +int DigitsLen(BYTE *pDigits, int maxLen); +int BcdLen(BYTE *pBcd, int maxLen); +int Digits2Str(char *pStr, BYTE *pDigits, int DigitsLen); +ull Digits2Ull(BYTE *pDigits, int DigitsLen); +int Ull2Digits(BYTE *pDigits, ull value, int DigitsLen); +int Str2Digits(BYTE *pDigits, char *pStr, int DigitsLen); +int Ull2Digits_Ralign(BYTE *pDigits, ull value, int DigitsLen); +ull Bcd2Ull(BYTE *pBcd, int BcdLen); +int Ull2Bcd(BYTE *pBcd, ull value, int BcdLen); +int Digits2Bcd(BYTE *pBcd, BYTE *pDigits, int maxLen); +int Bcd2Digits(BYTE *pDigits, BYTE *pBcd, int maxLen); +int Bcd2Digits_dLen(BYTE *pDigits, BYTE *pBcd, int maxLen); +int Str2Oid(DWORD *pOid, char *pStr, BYTE maxLen); +int TrimLeft(char *pStr); +int TrimRight(char *pStr); +int Array2Digits(BYTE *pDigits, BYTE *pArray, int ArrayLen); +ull Str2Ull(char *pStr); +int Digits2Array(BYTE *pArray, BYTE *pDigits, int DigitsLen); +int Bcd2Array(BYTE *pArray, BYTE *pBcd, int BcdLen); +int Str2Array(BYTE *pArray, char *str, int ArrayLen); +BYTE EditDigits(BYTE *digits_out, BYTE len_max, BYTE *digits_in, BYTE len_in, BYTE len_del, BYTE *digits_ins, BYTE len_ins, BYTE filler); +BYTE DelDigits(BYTE *in_digit, BYTE in_len, BYTE *out_digit, BYTE count, BYTE filler); +void DWORD2BYTE(BYTE *pdword, BYTE *pbyte, int len); +void u32tobyte(u8 *str, u32 data); +u8 u16tobcd(u8 *bcd_string, u16 data); +u16 bcdtou16(u8 *bcd_string, u8 bcd_len); +u8 u32tobcd(u8 *bcd_string, u32 data); +u32 bcdtou32(u8 *bcd_string, u8 bcd_len); +void AsciiToRbcd(BYTE *bcd_buf, const char *ascii_buf, int len); + + +#endif + diff --git a/plat/public/src/include/pub_include.h b/plat/public/src/include/pub_include.h new file mode 100644 index 0000000..94d23fd --- /dev/null +++ b/plat/public/src/include/pub_include.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////// +//Title : pub_incudes.h +//Auhtor : Liu Wei +//Desc : public header includes +//Created : 2007-07-13 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + + +#ifndef _PUB_INCLUDE_H_ +#define _PUB_INCLUDE_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" +#include "asn1.h" +#include "crypt.h" +#include "bisearch.h" +#include "pub_base.h" +#include "pub_debug.h" +#include "pub_log.h" +#include "pub_file.h" +#include "pub_list.h" +#include "pub_malloc.h" +#include "pub_fmt.h" +#include "pub_base.h" +#include "pub_time.h" +#include "pub_timer.h" +#include "pub_sys.h" +#include "pub_str.h" +#include "pub_inet.h" +#include "pub_wnet.h" +#include "pub_netcap.h" +#include "pub_sdp.h" + +#endif diff --git a/plat/public/src/include/pub_inet.h b/plat/public/src/include/pub_inet.h new file mode 100644 index 0000000..bd63cdc --- /dev/null +++ b/plat/public/src/include/pub_inet.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////// +//Title : pub_inet.h +//Auhtor : Liu Wei +//Desc : public inet function header +//Created : 2007-06-22 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_INET_H_ +#define _PUB_INET_H_ + +#include "public.h" +#include "includes.h" +#include "pub_debug.h" + +/////////////////////////////////////////////////////////////////////////// +// Inet If Address infomation interface +/////////////////////////////////////////////////////////////////////////// + +#define MAXINTERFACES 16 + +typedef struct IF_ADDR +{ + u8 uIfNum; + struct + { + u32 dIfIP; + u8 uIfState; + } + tIfEntity[MAXINTERFACES]; +} +IfAddr; + +extern int GetNetIfInfo ( IfAddr * pIfAddr ); + +extern u32 GetLocalIP(); + +/////////////////////////////////////////////////////////////////////////// +// Ping Interface +/////////////////////////////////////////////////////////////////////////// + +#define PACKET_SIZE 4096 +#define MAX_NO_PACKETS 3 + +typedef void PingCallBack( int nPingResult ); + +typedef struct ICMP_SERVICE +{ + u8 uSrvState; + u8 uIcmpState; + u8 uPackNo; + u8 uDataLen; + u8 nPackNumSend; + u8 nPackNumRecv; + u8 aSendBuff[PACKET_SIZE]; + u8 aRecvBuff[PACKET_SIZE]; + u32 wSockfd; + pid_t tPid; + struct sockaddr_in tToAddr; + struct sockaddr_in tFromAddr; + struct protoent *pProtoent; + PingCallBack *fCallBack; +} +IcmpSrv; + +extern int PingInit ( IcmpSrv *pIS , int nDataLen ); + +extern int PingStart( IcmpSrv *pIS , char *sIP , PingCallBack fCallBack ); + +extern int PingTimer ( IcmpSrv *pIS ); + +DWORD GetLocalIP(); +DWORD wxc2_get_shm_offset(); +#endif diff --git a/plat/public/src/include/pub_list.h b/plat/public/src/include/pub_list.h new file mode 100644 index 0000000..99948a3 --- /dev/null +++ b/plat/public/src/include/pub_list.h @@ -0,0 +1,501 @@ +////////////////////////////////////////////////// +//Title : pool.c +//Auhtor : Liu Wei +//Desc : List and Pool Queue struct implement +//Created : 2007-05-01 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_LIST_H_ +#define _PUB_LIST_H_ + +//LIFO Queue + +#define LIFOQ_HEAD( name , type ) \ + struct name \ + { \ + struct type *pLqFirst;/*First elment*/ \ + } + +#define LIFOQ_ENTRY(type) \ + struct \ + { \ + struct type *pLqNext; \ + } + +#define LIFOQ_EMPTY(head) \ + ((head)->pLqFirst == NULL) + +#define LIFOQ_FIRST(head) \ + ((head)->pLqFirst) + +#define LIFOQ_FOREACH(var, head, field) \ + for((var) = (head)->pLqFirst; (var); (var) = (var)->field.pLqNext) + +#define LIFOQ_INIT(head) \ + { \ + (head)->pLqFirst = NULL; \ + } + +#define LIFOQ_INSERT_AFTER(lifoq_elm, elm, field) \ + do \ + { \ + (elm)->field.pLqNext = (lifoq_elm)->field.pLqNext; \ + (lifoq_elm)->field.pLqNext = (elm); \ + } while (0) + +#define LIFOQ_INSERT_HEAD(head, elm, field) \ + do \ + { \ + (elm)->field.pLqNext = (head)->pLqFirst; \ + (head)->pLqFirst = (elm); \ + } while (0) + +#define LIFOQ_NEXT(elm, field) ((elm)->field.pLqNext) + +#define LIFOQ_REMOVE_HEAD(head, field) \ + do \ + { \ + (head)->pLqFirst = (head)->pLqFirst->field.pLqNext; \ + } while (0) + +#define LIFOQ_REMOVE(head, elm, type, field) \ + do \ + { \ + if ((head)->pLqFirst == (elm)) \ + { \ + LIFOQ_REMOVE_HEAD((head), field); \ + } \ + else \ + { \ + struct type *curelm = (head)->pLqFirst; \ + \ + while( curelm->field.pLqNext != (elm) ) \ + { \ + curelm = curelm->field.pLqNext; \ + } \ + curelm->field.pLqNext = \ + curelm->field.pLqNext->field.pLqNext; \ + } \ + } while (0) + +//FIFO Quence + +#define FIFOQ_HEAD(name, type) \ + struct name \ + { \ + struct type *pFqFirst;/* first element */ \ + struct type **pFqLast;/* addr of last next element */ \ + } + +#define FIFOQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).pFqFirst } + +#define FIFOQ_ENTRY(type) \ + struct \ + { \ + struct type *pFqNext; /* next element */ \ + } + +#define FIFOQ_EMPTY(head) ((head)->pFqFirst == NULL) + +#define FIFOQ_INIT(head) \ + do \ + { \ + (head)->pFqFirst = NULL; \ + (head)->spTQLast = &(head)->pFqFirst; \ + } while (0) + +#define FIFOQ_FIRST(head) ((head)->pFqFirst) + +#define FIFOQ_LAST(head, type, field) \ + (FIFOQ_EMPTY(head) ? NULL : ((struct type *) \ + ((char *)((head)->spTQLast) - __offsetof(struct type, field)))) + +#define FIFOQ_FOREACH(var, head, field) \ + for((var) = (head)->pFqFirst; (var); (var) = (var)->field.pFqNext) + +#define FIFOQ_INSERT_HEAD(head, elm, field) \ + do \ + { \ + if (((elm)->field.pFqNext = (head)->pFqFirst) == NULL) \ + (head)->spTQLast = &(elm)->field.pFqNext; \ + (head)->pFqFirst = (elm); \ + } while (0) + +#define FIFOQ_INSERT_TAIL(head, elm, field) \ + do \ + { \ + (elm)->field.pFqNext = NULL; \ + *(head)->spTQLast = (elm); \ + (head)->spTQLast = &(elm)->field.pFqNext; \ + } while (0) + +#define FIFOQ_INSERT_AFTER(head, tqelm, elm, field) \ + do \ + { \ + if (((elm)->field.pFqNext = (tqelm)->field.pFqNext) == NULL)\ + (head)->spTQLast = &(elm)->field.pFqNext; \ + (tqelm)->field.pFqNext = (elm); \ + } while (0) + +#define FIFOQ_NEXT(elm, field) ((elm)->field.pFqNext) + +#define FIFOQ_REMOVE_HEAD(head, field) \ + do \ + { \ + if (((head)->pFqFirst = (head)->pFqFirst->field.pFqNext) == NULL) \ + (head)->spTQLast = &(head)->pFqFirst; \ + } while (0) + +#define FIFOQ_REMOVE_HEAD_UNTIL(head, elm, field) \ + do \ + { \ + if (((head)->pFqFirst = (elm)->field.pFqNext) == NULL) \ + (head)->spTQLast = &(head)->pFqFirst; \ + } while (0) + +#define FIFOQ_REMOVE(head, elm, type, field) \ + do \ + { \ + if ((head)->pFqFirst == (elm)) \ + { \ + FIFOQ_REMOVE_HEAD(head, field); \ + } \ + else \ + { \ + struct type *curelm = (head)->pFqFirst; \ + while( curelm->field.pFqNext != (elm) ) \ + curelm = curelm->field.pFqNext; \ + \ + if((curelm->field.pFqNext = \ + curelm->field.pFqNext->field.pFqNext) == NULL)\ + (head)->spTQLast = &(curelm)->field.pFqNext; \ + } \ + } while (0) + +// List + +#define LIST_HEAD(name, type) \ + struct name \ + { \ + struct type *pListFirst; /* first element */ \ + } + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ + struct \ + { \ + struct type *pListNext; /* next element */ \ + struct type **pListPrev; /* address of previous next element */ \ + } + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->pListFirst == NULL) + +#define LIST_FIRST(head) ((head)->pListFirst) + +#define LIST_FOREACH(var, head, field) \ + for((var) = (head)->pListFirst; (var); (var) = (var)->field.pListNext) + +#define LIST_INIT(head) \ + do \ + { \ + (head)->pListFirst = NULL; \ + } while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) \ + do \ + { \ + if (((elm)->field.pListNext = (listelm)->field.pListNext) != NULL) \ + { \ + (listelm)->field.pListNext->field.pListPrev = \ + &(elm)->field.pListNext; \ + } \ + (listelm)->field.pListNext = (elm); \ + (elm)->field.pListPrev = &(listelm)->field.pListNext; \ + } while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) \ + do \ + { \ + (elm)->field.pListPrev = (listelm)->field.pListPrev; \ + (elm)->field.pListNext = (listelm); \ + *(listelm)->field.pListPrev = (elm); \ + (listelm)->field.pListPrev = &(elm)->field.pListNext; \ + } while (0) + +#define LIST_INSERT_HEAD(head, elm, field) \ + do \ + { \ + if (((elm)->field.pListNext = (head)->pListFirst) != NULL) \ + (head)->pListFirst->field.pListPrev = &(elm)->field.pListNext; \ + (head)->pListFirst = (elm); \ + (elm)->field.pListPrev = &(head)->pListFirst; \ + } while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.pListNext) + +#define LIST_REMOVE(elm, field) \ + do \ + { \ + if ((elm)->field.pListNext != NULL) \ + (elm)->field.pListNext->field.pListPrev = \ + (elm)->field.pListPrev; \ + *(elm)->field.pListPrev = (elm)->field.pListNext; \ + } while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ + struct name \ + { \ + struct type *pTQFirst; /* first element */ \ + struct type **pTQLast; /* addr of last next element */ \ + } + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).pTQFirst } + +#define TAILQ_ENTRY(type) \ + struct \ + { \ + struct type *pTQNext; /* next element */ \ + struct type **pTQPrev; /* address of previous next element */ \ + } + +/* + * Tail queue functions. + */ +#define TAILQ_EMPTY(head) ((head)->pTQFirst == NULL) + +#define TAILQ_FOREACH(var, head, field) \ + for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FIRST(head) ((head)->pTQFirst) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->pTQLast))->pTQLast)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.pTQNext) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.pTQPrev))->pTQLast)) + +#define TAILQ_INIT(head) \ + do \ + { \ + (head)->pTQFirst = NULL; \ + (head)->pTQLast = &(head)->pTQFirst; \ + } while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) \ + do \ + { \ + if (((elm)->field.pTQNext = (head)->pTQFirst) != NULL) \ + (head)->pTQFirst->field.pTQPrev = \ + &(elm)->field.pTQNext; \ + else \ + (head)->pTQLast = &(elm)->field.pTQNext; \ + (head)->pTQFirst = (elm); \ + (elm)->field.pTQPrev = &(head)->pTQFirst; \ + } while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) \ + do \ + { \ + (elm)->field.pTQNext = NULL; \ + (elm)->field.pTQPrev = (head)->pTQLast; \ + *(head)->pTQLast = (elm); \ + (head)->pTQLast = &(elm)->field.pTQNext; \ + } while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) \ + do \ + { \ + if (((elm)->field.pTQNext = (listelm)->field.pTQNext) != NULL) \ + (elm)->field.pTQNext->field.pTQPrev = &(elm)->field.pTQNext; \ + else \ + (head)->pTQLast = &(elm)->field.pTQNext; \ + (listelm)->field.pTQNext = (elm); \ + (elm)->field.pTQPrev = &(listelm)->field.pTQNext; \ + } while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) \ + do { \ + (elm)->field.pTQPrev = (listelm)->field.pTQPrev; \ + (elm)->field.pTQNext = (listelm); \ + *(listelm)->field.pTQPrev = (elm); \ + (listelm)->field.pTQPrev = &(elm)->field.pTQNext; \ + } while (0) + +#define TAILQ_REMOVE(head, elm, field) \ + do { \ + if (((elm)->field.pTQNext) != NULL) \ + (elm)->field.pTQNext->field.pTQPrev = (elm)->field.pTQPrev; \ + else \ + (head)->pTQLast = (elm)->field.pTQPrev; \ + *(elm)->field.pTQPrev = (elm)->field.pTQNext; \ + } while (0) + +/* + * Pool -- Circular queue definitions. + */ +#define POOL_HEAD(name, type) \ + struct name \ + { \ + struct type *pPoolFirst; /* first element */ \ + struct type *pPoolLast; /* last element */ \ + } + +#define POOL_ENTRY(type) \ + struct \ + { \ + struct type *pPoolNext; /* next element */ \ + struct type *pPoolPrev; /* previous element */ \ + } + +/* + * Pool -- Circular queue functions. + */ + +#define POOL_EMPTY(head) ((head)->pPoolFirst == (void *)(head)) + +#define POOL_FIRST(head) ((head)->pPoolFirst) + +#define POOL_FOREACH(var, head, field) \ + for((var) = (head)->pPoolFirst; \ + (var) != (void *)(head); \ + (var) = (var)->field.pPoolNext) + +#define POOL_FOREACH_REVERSE(var, head, field) \ + for((var) = (head)->pPoolLast; \ + (var) != (void *)(head); \ + (var) = (var)->field.pPoolPrev) + +#define POOL_INIT(head) \ + do \ + { \ + (head)->pPoolFirst = (void *)(head); \ + (head)->pPoolLast = (void *)(head); \ + } while (0) + +#define POOL_INSERT_AFTER(head, listelm, elm, field) \ + do { \ + (elm)->field.pPoolNext = (listelm)->field.pPoolNext; \ + (elm)->field.pPoolPrev = (listelm); \ + if ((listelm)->field.pPoolNext == (void *)(head)) \ + (head)->pPoolLast = (elm); \ + else \ + (listelm)->field.pPoolNext->field.pPoolPrev = (elm); \ + (listelm)->field.pPoolNext = (elm); \ + } while (0) + +#define POOL_INSERT_BEFORE(head, listelm, elm, field) \ + do { \ + (elm)->field.pPoolNext = (listelm); \ + (elm)->field.pPoolPrev = (listelm)->field.pPoolPrev; \ + if ((listelm)->field.pPoolPrev == (void *)(head)) \ + (head)->pPoolFirst = (elm); \ + else \ + (listelm)->field.pPoolPrev->field.pPoolNext = (elm); \ + (listelm)->field.pPoolPrev = (elm); \ + } while (0) + +#define POOL_INSERT_HEAD(head, elm, field) \ + do { \ + (elm)->field.pPoolNext = (head)->pPoolFirst; \ + (elm)->field.pPoolPrev = (void *)(head); \ + if ((head)->pPoolLast == (void *)(head)) \ + (head)->pPoolLast = (elm); \ + else \ + (head)->pPoolFirst->field.pPoolPrev = (elm); \ + (head)->pPoolFirst = (elm); \ + } while (0) + +#define POOL_INSERT_TAIL(head, elm, field) \ + do { \ + (elm)->field.pPoolNext = (void *)(head); \ + (elm)->field.pPoolPrev = (head)->pPoolLast; \ + if ((head)->pPoolFirst == (void *)(head)) \ + (head)->pPoolFirst = (elm); \ + else \ + (head)->pPoolLast->field.pPoolNext = (elm); \ + (head)->pPoolLast = (elm); \ + } while (0) + +#define POOL_LAST(head) ((head)->pPoolLast) + +#define POOL_NEXT(elm,field) ((elm)->field.pPoolNext) + +#define POOL_PREV(elm,field) ((elm)->field.pPoolPrev) + +#define POOL_REMOVE(head, elm, field) \ + do { \ + if ((elm)->field.pPoolNext == (void *)(head)) \ + (head)->pPoolLast = (elm)->field.pPoolPrev; \ + else \ + (elm)->field.pPoolNext->field.pPoolPrev = (elm)->field.pPoolPrev; \ + \ + if ((elm)->field.pPoolPrev == (void *)(head)) \ + (head)->pPoolFirst = (elm)->field.pPoolNext; \ + else \ + (elm)->field.pPoolPrev->field.pPoolNext =(elm)->field.pPoolNext; \ + } while (0) + +#ifdef _KERNEL +/* + * XXX insque() and remque() are an old way of handling certain queues. + * They bogusly assumes that all queue heads look alike. + */ + +struct quehead +{ + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +#ifdef __GNUC__ + +static __inline void insque ( void *a, void *b ) +{ + struct quehead *element = a, *head = b; + + element->qh_link = head->qh_link; + element->qh_rlink = head; + head->qh_link = element; + element->qh_link->qh_rlink = element; +} + +static __inline void remque ( void *a ) +{ + struct quehead *element = a; + + element->qh_link->qh_rlink = element->qh_rlink; + element->qh_rlink->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +#else /* !__GNUC__ */ + +void insque __P ( ( void *a, void *b ) ); +void remque __P ( ( void *a ) ); + +#endif /* __GNUC__ */ + +#endif /* _KERNEL */ +#endif diff --git a/plat/public/src/include/pub_log.h b/plat/public/src/include/pub_log.h new file mode 100644 index 0000000..8b42e14 --- /dev/null +++ b/plat/public/src/include/pub_log.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////// +//Title : pub_log.h +//Auhtor : Liu Wei +//Desc : public log function header +//Created : 2007-05-21 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + + +#ifndef _PUB_LOG_H_ +#define _PUB_LOG_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" +#include "pub_debug.h" +#include "pub_fmt.h" +#include + +#define RESET 0 +#define BRIGHT 1 +#define DIM 2 +#define UNDERLINE 3 +#define BLINK 4 +#define REVERSE 7 +#define HIDDEN 8 +#define BLACK 0 +#define RED 1 +#define GREEN 2 +#define YELLOW 3 +#define BLUE 4 +#define MAGENTA 5 +#define CYAN 6 +#define WHITE 7 + + +///////////////////////////////////////////////////////////////////////// +// Public print information +///////////////////////////////////////////////////////////////////////// + +#define PIF_INFO 0x01 // Normal Information +#define PIF_WARN 0x02 // Warnings +#define PIF_GERR 0x04 // General errors +#define PIF_CERR 0x10 // Critical errors +#define PIF_DBG 0x20 // Debugging +#define PIF_UNKN 0x40 // Things that are unknown + +// Default SIM output +#define PIF_DEFAULT (PIF_INFO|PIF_WARN|PIF_CERR) +// Everything, but DBG +#define PIF_ALL (PIF_INFO|PIF_WARN|PIF_GERR|PIF_CERR|PIF_UNKN) + +#define SYSERR strerror(errno) + +extern char *ByteBinToStr( char *pDst , const u8 *pSrc , int nByte ); +extern char *TxtColor ( int nAttr, int nFg, int nBg, char *pStr ); +extern int MsgToFmtLog ( const BYTE * pBcd, int nBcdLen, char *pStr, int nStrBuffSize ); + +#ifdef DEBUG +#define WxcDebugLog printf +#else +#define WxcDebugLog +#endif + +#endif diff --git a/plat/public/src/include/pub_malloc.h b/plat/public/src/include/pub_malloc.h new file mode 100644 index 0000000..99d3c39 --- /dev/null +++ b/plat/public/src/include/pub_malloc.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////// +//Title : pub_malloc.h +//Auhtor : Liu Wei +//Desc : Public heap memery management +//Created : 2007-05-01 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_MALLOC_H_ +#define _PUB_MALLOC_H_ + +#include "public.h" +#include "includes.h" +//#ifdef _USE_SYS_MALLOC_ + +#define WxcMalloc malloc +#define WxcFree free + +//#endif + +#endif + + diff --git a/plat/public/src/include/pub_netcap.h b/plat/public/src/include/pub_netcap.h new file mode 100644 index 0000000..7b9097b --- /dev/null +++ b/plat/public/src/include/pub_netcap.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////// +//Title : pub_netcap.h +//Auhtor : Liu Wei +//Desc : public netcap header +//Created : 2007-06-05 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_NETCAP_H_ +#define _PUB_NETCAP_H_ + +#include "public.h" +#include "includes.h" + +typedef struct NET_CAPTURE +{ + u8 uState; + u32 nSock; + u32 nPort; + u32 nDstIp; +} +NetCap; + +int NcInit(); +int NcStart( u32 wIP , u32 wPort ); +int NcStop( ); +void NcSetPort( u32 port ); +void NcSetIP( u32 ip ); +void NcMtp3Send( u8 *pMtp3Msg , u32 wMtp3Len , u8 uAnsiFlag ); +int NcSccpSend( u8 *pSccpMsg , u32 wSccpLen , u8 *pIntraMsg , u8 uAnsiFlag ); + +#endif diff --git a/plat/public/src/include/pub_sdp.h b/plat/public/src/include/pub_sdp.h new file mode 100644 index 0000000..d02bf72 --- /dev/null +++ b/plat/public/src/include/pub_sdp.h @@ -0,0 +1,205 @@ +#ifndef _PUB_SDP__H +#define _PUB_SDP__H + +#define PUB_SDP_MAX_USER_NAME_LEN 64 +#define PUB_SDP_MAX_SESS_ID_LEN 32 +#define PUB_SDP_MAX_SESS_VER_LEN 16 +#define PUB_SDP_MAX_ADDR_LEN 64 +#define PUB_SDP_MAX_SESS_NAME_LEN 64 +#define PUB_SDP_MAX_SESS_INFO_LEN 64 +#define PUB_SDP_MAX_PAYLOAD_NUM 8 +#define PUB_SDP_MAX_MEDIA_NUM 2//8 +#define PUB_SDP_MAX_ATTR_NUM 16 +#define PUB_SDP_MAX_ATTR_LEN 32 + +#define PUB_SDP_FLAG_V 0x00000001 +#define PUB_SDP_FLAG_O 0x00000002 +#define PUB_SDP_FLAG_S 0x00000004 +#define PUB_SDP_FLAG_I 0x00000008 +#define PUB_SDP_FLAG_U 0x00000010 +#define PUB_SDP_FLAG_E 0x00000020 +#define PUB_SDP_FLAG_P 0x00000040 +#define PUB_SDP_FLAG_C 0x00000080 +#define PUB_SDP_FLAG_B 0x00000100 +#define PUB_SDP_FLAG_Z 0x00000200 +#define PUB_SDP_FLAG_K 0x00000400 +#define PUB_SDP_FLAG_A 0x00000800 +#define PUB_SDP_FLAG_T 0x00001000 +#define PUB_SDP_FLAG_R 0x00002000 +#define PUB_SDP_FLAG_M 0x00004000 + +#define PUB_MGCP_PARA_FLAG_TFO 0x00000800 + +#define PUB_SDP_STR_TO_API 1 +#define PUB_SDP_API_TO_STR 2 + +#define PUB_SDP_NET_TYPE_IN 1 + +#define PUB_SDP_ADDR_TYPE_IPV4 1 +#define PUB_SDP_ADDR_TYPE_IPV6 2 + +#define PUB_SDP_ATTR_TYPE_RTPMAP 1 +#define PUB_SDP_ATTR_TYPE_PTIME 2 +#define PUB_SDP_ATTR_TYPE_FMTP 3 +#define PUB_SDP_ATTR_TYPE_RECVONLY 4 +#define PUB_SDP_ATTR_TYPE_SENDONLY 5 +#define PUB_SDP_ATTR_TYPE_SENDRECV 6 +#define PUB_SDP_ATTR_TYPE_T38VER 7 +#define PUB_SDP_ATTR_TYPE_T38MBR 8 +#define PUB_SDP_ATTR_TYPE_IPBCP 9 + +#define PUB_SDP_MEDIA_TYPE_AUDIO 1 +#define PUB_SDP_MEDIA_TYPE_VIDEO 2 +#define PUB_SDP_MEDIA_TYPE_IMAGE 3 + +#define PUB_SDP_PROTO_TYPE_RTP_AVP 1 +#define PUB_SDP_PROTO_TYPE_IMAGE_UDPTL 2 + +#define PUB_SDP_M_PORT_CHOOSE 0 + +typedef struct _PUB_SDP_V +{ + BYTE value; +}PUB_SDP_V; + +typedef struct _PUB_SDP_O +{ + char userName[PUB_SDP_MAX_USER_NAME_LEN]; + char sessId[PUB_SDP_MAX_SESS_ID_LEN]; + char sessVer[PUB_SDP_MAX_SESS_VER_LEN]; + BYTE netType; + BYTE addrType; + char addr[PUB_SDP_MAX_ADDR_LEN]; +}PUB_SDP_O; + +typedef struct _PUB_SDP_S +{ + char sessName[PUB_SDP_MAX_SESS_NAME_LEN]; +}PUB_SDP_S; + +typedef struct _PUB_SDP_I +{ + char info[PUB_SDP_MAX_SESS_INFO_LEN]; +}PUB_SDP_I; + +typedef struct _PUB_SDP_U +{ +}PUB_SDP_U; + +typedef struct _PUB_SDP_E +{ +}PUB_SDP_E; + +typedef struct _PUB_SDP_P +{ +}PUB_SDP_P; + +typedef struct _PUB_SDP_C +{ + BYTE netType; + BYTE addrType; + char addr[PUB_SDP_MAX_ADDR_LEN]; +}PUB_SDP_C; + +typedef struct _PUB_SDP_B +{ +}PUB_SDP_B; + +typedef struct _PUB_SDP_Z +{ +}PUB_SDP_Z; + +typedef struct _PUB_SDP_K +{ +}PUB_SDP_K; + +typedef struct _PUB_SDP_T +{ + DWORD startTime; + DWORD stopTime; +}PUB_SDP_T; + +typedef struct _PUB_SDP_R +{ +}PUB_SDP_R; + +typedef struct _PUB_SDP_M +{ + BYTE media; + WORD port; + BYTE portNum; + BYTE proto; + BYTE plNum; + BYTE payloads[PUB_SDP_MAX_PAYLOAD_NUM]; +}PUB_SDP_M; + +typedef struct _PUB_SDP_A +{ + BYTE aType; + char aValue[PUB_SDP_MAX_ATTR_LEN]; +}PUB_SDP_A; + +typedef struct _PUB_SDP_ATTRS +{ + BYTE num; + PUB_SDP_A attrs[PUB_SDP_MAX_ATTR_NUM]; +}PUB_SDP_ATTRS; + +typedef struct _PUB_SDP_MEDIA +{ + DWORD flag; + + PUB_SDP_M m; + PUB_SDP_I i; + PUB_SDP_C c; + PUB_SDP_B b; + PUB_SDP_K k; + PUB_SDP_ATTRS attrs; +}PUB_SDP_MEDIA; + +typedef struct _PUB_SDP_MEDIAS +{ + BYTE num; + PUB_SDP_MEDIA medias[PUB_SDP_MAX_MEDIA_NUM]; +}PUB_SDP_MEDIAS; + +typedef struct _PUB_SDP_MSG +{ + DWORD flag; + + PUB_SDP_V v; + PUB_SDP_O o; + PUB_SDP_S s; + PUB_SDP_I i; + PUB_SDP_U u; + PUB_SDP_E e; + PUB_SDP_P p; + PUB_SDP_C c; + PUB_SDP_B b; + PUB_SDP_Z z; + PUB_SDP_K k; + PUB_SDP_A a; + PUB_SDP_T t; + PUB_SDP_R r; + + PUB_SDP_MEDIAS medias; +}PUB_SDP_MSG; + +void pub_replace_all_lws(char *msg); +char *pub_strncpy(char *dest, const char *src, WORD length); +int pub_set_next_token(char *dest, char *buf, int endSeparator, char **next); + +int pub_sdp_msg_init(PUB_SDP_MSG *sdp); +int pub_sdp_parse(PUB_SDP_MSG *sdp, char *buf, char **nextMsg, DWORD flag); +int pub_sdp_encode(PUB_SDP_MSG *sdp, char *dest, WORD flag); + +int pub_sdp_net_type_conv(char *str, BYTE *netType, BYTE flag); +int pub_sdp_addr_type_conv(char *str, BYTE *addrType, BYTE flag); +int pub_sdp_attr_type_conv(char *str, BYTE *attrType, BYTE flag); +int pub_sdp_media_type_conv(char *str, BYTE *mediaType, BYTE flag); +int pub_sdp_proto_type_conv(char *str, BYTE *protoType, BYTE flag); + +int pub_sdp_parse_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **nextMsg, DWORD flag); +int pub_sdp_encode_for_megaco(PUB_SDP_MSG *sdp, char *dest, WORD flag); + +#endif diff --git a/plat/public/src/include/pub_str.h b/plat/public/src/include/pub_str.h new file mode 100644 index 0000000..f823ab3 --- /dev/null +++ b/plat/public/src/include/pub_str.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////// +//Title : pub_str.h +//Auhtor : Liu Wei +//Desc : wxc2 string library +//Created : 2007-06-02 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_STR_H_ +#define _PUB_STR_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" + +#endif + + + + + + + diff --git a/plat/public/src/include/pub_sys.h b/plat/public/src/include/pub_sys.h new file mode 100644 index 0000000..d1e84b8 --- /dev/null +++ b/plat/public/src/include/pub_sys.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////// +//Title : pub_sys.c +//Auhtor : Liu Wei +//Desc : Public Linux system infomation +//Created : 2007-06-02 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_SYS_H_ +#define _PUB_SYS_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" +#include "pub_time.h" +#include +#include +#include +#include +#include +#include +#include +//#include + +#define SIM_NONL 0x1000 // Don't add newline to output +#define SIM_NOLBL 0x2000 // Don't print "Public: Error:" + + +#define MHERTZ 1000000 // MegaHertz +#define BYTES ((u32)1) // Bytes +#define KBYTES ((u32)1024) // Kilo bytes +#define MBYTES ((u32)(1024*1024)) // Mega bytes +#define GBYTES ((u32)(1024*1024*1024)) // Giga bytes + +#define BytesToGBytes(N) ( (float) N / (float) GBYTES ) +#define BytesToMBytes(N) ( (float) N / (float) MBYTES ) +#define BytesToKBytes(N) ( (float) (N / (float) KBYTES) ) +#define MBytesToBytes(N) ( (float) ( (float) N * (float) MBYTES ) ) +#define KBytesToMbytes(N) ( (float) ( (float) N / (float) KBYTES ) ) +#define KBytesToGbytes(N) ( (float) ( (float) N / (float) MBYTES ) ) +#define MbytesToGbytes(N) ( (float) ( (float) N / (float) KBYTES ) ) + +#define EQ(a,b) (a && b && strcasecmp(a,b)==0) +#define EQN(a,b,n) (a && b && strncasecmp(a,b,n)==0) +#define eq(a,b) (a && b && strcmp(a,b)==0) +#define eqn(a,b,n) (a && b && strncmp(a,b,n)==0) +#define ARG(s) ((s) ? s : "") +#define PRTS(s) ( ( s && *s ) ? s : "" ) + +#endif diff --git a/plat/public/src/include/pub_time.h b/plat/public/src/include/pub_time.h new file mode 100644 index 0000000..8aeee6d --- /dev/null +++ b/plat/public/src/include/pub_time.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////// +//Title : pub_time.h +//Auhtor : Liu Wei +//Desc : Linux time function +//Created : 2007-06-02 +//Revision : +// +//Revision : +// +///////////////////////////////////////////////// + +#ifndef _PUB_TIME_H_ +#define _PUB_TIME_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" +#include "pub_log.h" +#include + +/* pub_time.c */ +long GetTickCount(void); +int GetCurrentTime(u8 *pNowTime); +char *GetAsciiTime(void); +char *TimeToStr(time_t TimeVal, char *Format); +char *GetTimeHMS(char *pTimeBuf); + + +#endif diff --git a/plat/public/src/include/pub_timer.h b/plat/public/src/include/pub_timer.h new file mode 100644 index 0000000..dfe93c4 --- /dev/null +++ b/plat/public/src/include/pub_timer.h @@ -0,0 +1,96 @@ +////////////////////////////////////////////////// +//Title : wxc_timer.h +//Auhtor : Liu Wei +//Desc : WXC2 Public Timer Managemnet +//Created : 2007-04-27 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _PUB_TIMER_H_ +#define _PUB_TIMER_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" +#include "pub_malloc.h" + +/////////////////////////////////////////////////////////////////////////// + +typedef void ( *TimerCallBack ) ( u16 dSuitId, u16 dData ); + +#define TM_CLOCK_MAX (24*60*60*100) //one day based on wxc2 base timer 10ms + +typedef struct WXC_TIMER +{ + u32 dExpires; //dExpires : Timer expired number + u32 dSuitNumber; //dSuitNumber : Timer suit size of member + TimerCallBack pFunc; //pFunc : Timer call back function + u16 dData; //dData : Pointer for parameter of callback + void *pTimerNode; //pTimerNode : Reserved for timer Managemnet +} +WxcTimer; + +/////////////////////////////////////////////////////////////////////////// + +typedef struct WXC_TIMER_NODE +{ + u32 *dClockArray; //dClockArray : Timer set member clock array + WxcTimer *pTimer; + struct WXC_TIMER_NODE *pNext; + struct WXC_TIMER_NODE *pPrev; +} +WxcTimerNode; + +/////////////////////////////////////////////////////////////////////////// + +#define MAX_TM_MODE 512 + +#define TIMER_NODE_SIZE ( sizeof( WxcTimerNode ) + sizeof( WxcTimer ) ) + +#define CLOCK_SZIE ( sizeof ( u32 ) ) + +#define TMHEAP_MM_SIZE ( MAX_TM_MODE * TIMER_NODE_SIZE ) + +#define GET_TNODE_SIZE(n) ( TIMER_NODE_SIZE + ( n ) *( CLOCK_SZIE )) + +/////////////////////////////////////////////////////////////////////////// + +//u8 TMHeap[TMHEAP_MM_SIZE]; + +/*WxcTimerNode tTimerListHead; +WxcTimerNode *pTLHead; +WxcTimerNode *pTLCur;*/ + +/////////////////////////////////////////////////////////////////////////// + +#ifndef _LINUX_TIMER_H +#define time_after(a,b) ((long)(b) - (long)(a) < 0) +#define time_before(a,b) time_after(b,a) + +#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) +#define time_before_eq(a,b) time_after_eq(b,a) +#endif + +/////////////////////////////////////////////////////////////////////////// + +#define TimerAfter(a,b) time_after(a,b) +#define TimerBefore(a,b) time_before(a,b) +#define TimerAfterEq(a,b) time_after_eq(a,b) +#define TimerBeforeEq(a,b) time_before_eq(a,b) + + +extern void TimerAdd ( WxcTimer * pTimer ); +extern void TimerMod ( WxcTimer * pTimer, u16 dExpires ); +extern void TimerDel ( WxcTimer * pTimer ); + + +void TimerStart ( WxcTimer * pTimer, u16 dSuitId ); +void TimerStop ( WxcTimer * pTimer, u16 dSuitId ); +void TM_Init ( ); + + + +#endif diff --git a/plat/public/src/include/pub_wnet.h b/plat/public/src/include/pub_wnet.h new file mode 100644 index 0000000..0be123d --- /dev/null +++ b/plat/public/src/include/pub_wnet.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////// +//Title : pub_wnet.h +//Auhtor : Liu Wei +//Desc : wireless network publice function +//Created : 2007-06-05 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + + +#ifndef _WXC_WNET_H_ +#define _WXC_WNET_H_ + +#include "public.h" +#include "includes.h" +#include "pub_base.h" +#include "pub_fmt.h" + +#define ISDN_LEN 9 +#define IMSI_LEN 8 + +/* ./src/pub_wnet.c */ +u8 GetBcdStr(char *str, u8 *bcd, u8 bcd_len); +void ImsiNtoA(u8 *pAntiImsi, u8 *pNormalImsi); +void ImsiAToN(u8 *pNormalImsi, u8 *pAntiImsi); +void ImsiNToS(u8 *pImsiStr, u8 *pNormalImsi); +void ImsiSToN(u8 *pNormalImsi, u8 *pImsiStr); +void IsdnNToA(u8 *pAntiIsdn, u8 *pNormalIsdn); +void IsdnAToN(u8 *pNormalIsdn, u8 *pAntiIsdn); +void IsdnNToS(u8 *pIsdnStr, u8 *pNormalIsdn); +u8 IsdnSToN(u8 *pNormalIsdn, u8 *pIsdnStr); +void GttToIsdn(u8 *pIsdn, u8 *pGtt); +u8 IsdnToGtai(u8 *pGtai, u8 *pIsdn); +void GtaiToIsdn(u8 *pIsdn, u8 *pGtai, u8 len); +u8 BcdToStrPE(char *str, u8 *bcd, u8 bcd_len); +void AddCcToIsdn(u8 *isdn_str, u8 *cc); +void AddNdcToIsdn(u8 *isdn_str, u8 *ndc); + +#endif diff --git a/plat/public/src/include/public.h b/plat/public/src/include/public.h new file mode 100644 index 0000000..f0e1539 --- /dev/null +++ b/plat/public/src/include/public.h @@ -0,0 +1,102 @@ +/* +** PACS WLL 2000 project, Prepaid System. +** +** File name: public.h +** Written completely by Zhang Shuzhong at 2000-10-17 +** CVS $Id: public.h,v 1.4 2001/01/20 19:58:49 zhangsz Exp $ +** +** Public type definitions for PACS-WLL Project. +** +*/ + +#ifndef PUBLIC__H +#define PUBLIC__H + +#include +#include "memwatch.h" + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned int DWORD; +#endif + +#ifndef _T_ULL +#define _T_ULL +typedef unsigned long long ull; +#endif + +#ifndef _T_U8 +#define _T_U8 +typedef unsigned char u8; +#endif + +#ifndef _T_U16 +#define _T_U16 +typedef unsigned short u16; +#endif + +#ifndef _T_U32 +#define _T_U32 +typedef unsigned int u32; +#endif + +#ifndef _T_U64 +#define _T_U64 +typedef unsigned long long u64; +#endif + +#ifndef _T_BOOL +#define _T_BOOL +typedef int BOOL; +#endif + +#ifndef SUCCESS +#define SUCCESS (0) +#endif + +#ifndef FAILURE +#define FAILURE (-1) +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef YES +#define YES (1) +#endif + +#ifndef NO +#define NO (0) +#endif + +#ifndef ERROR +#define ERROR (-1) +#endif + +#ifndef EMPTY +#define EMPTY (0) +#endif + +#define BUFSIZE 8192 +#define MAXBUFLEN 8192 +#define MAXLINE 8192 + +//#define MAX(a, b) ((a) > (b) ? (a) : (b)) +//#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#endif /* PUBLIC__H */ diff --git a/plat/public/src/include/svrstat.h b/plat/public/src/include/svrstat.h new file mode 100644 index 0000000..e115e98 --- /dev/null +++ b/plat/public/src/include/svrstat.h @@ -0,0 +1,100 @@ +/* +** PACS-WLL 2000 project, WAVEloop System. +** +** The module Copyright (C) 2000-2001 interWAVE Inc. +** Written completely by Zhang Shuzhong at iCRD Sep, 2001 +** +** file name: svrstat.h +** CVS $Id: $ +** +** The header file is defination about shared memory +** of server state information. +** +*/ + + +#ifndef SVRSTAT__H +#define SVRSTAT__H + +#define SVRSTAT_SHM_KEY 0x00010000 +#define SVRSTAT_SHM_PERM 0666 +#define SVRSTAT_SEM_KEY 0x00010000 +#define SVRSTAT_SEM_PERM 0666 +#define SVRSTAT_SEM_NUM 1 + +enum _server_state_enum { + SS_IDLE, + SS_INITIATE, + SS_NORMAL, + SS_SERVICE_SUSPEND, + SS_SERVICE_HALT, + SS_SHM_REINITIATE, + SS_SERVICE_RESTART, + SS_SYSTEM_RESTART, + SS_SYSTEM_HALT, +}; + +enum _oper_state_enum { + OS_NO_COMMAND, + OS_SET_COMMAND, + OS_GOT_COMMAND, + OS_FINISHED_COMMAND, + OS_REFUSED_COMMAND, +}; + +typedef struct { + u_char component_type; + u_char component_id; + u_char alarm_level; + u_char alarm_code; + u_long timestamp; +} _alarm_log; + +typedef struct { + u_short read_sub; + u_short write_sub; + _alarm_log alarm_log[16]; +} _alarm_buffer; + +typedef struct { + u_char version[3]; + u_long distrib_date; + u_char current_state; // Please view server's state enum. + // The server's current state. + u_char received_state; // State received from OMC. + // Please view server's state enum + // for detail. + u_char oper_state; /* 0: No command. + ** 1: Agent set command. + ** 2: Function server got the command. + ** 3: Function server finished. + ** 4: Function server refused. + ** refer to enum of _oper_state_enum + */ + u_char net_status; // 0/1=normal/abnormal, + // status of network + u_char rate_progress; // Rate of progress. + u_long time_updated; + _alarm_buffer alarm_buffer; // Alarm code +} _server_state; + +typedef struct { + u_long time_created; // Heartbeating module set the field + u_long server_list; /* Bit0-15: + ** Server exist if set '1' in bit + ** Bit16-31: + ** 0/1 = Primary/Secondary server. + ** that base server object id. + */ + u_char led_state[16]; /* Led's state: + ** 0: Idle/Disable/Suspend/Halt + ** 1: Enable/Normal + ** 2: Initiating/Activated + */ + u_char port_stat[3]; + _server_state server_state[16]; /* Subscript of array + ** base on server object ID + */ +} _ss_buffer; + +#endif diff --git a/plat/public/src/memwatch.c b/plat/public/src/memwatch.c new file mode 100644 index 0000000..b3a263f --- /dev/null +++ b/plat/public/src/memwatch.c @@ -0,0 +1,2669 @@ +/* +** MEMWATCH.C +** Nonintrusive ANSI C memory leak / overwrite detection +** Copyright (C) 1992-2003 Johan Lindh +** All rights reserved. +** Version 2.71 + + This file is part of MEMWATCH. + + MEMWATCH is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + MEMWATCH 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with MEMWATCH; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +** +** 920810 JLI [1.00] +** 920830 JLI [1.10 double-free detection] +** 920912 JLI [1.15 mwPuts, mwGrab/Drop, mwLimit] +** 921022 JLI [1.20 ASSERT and VERIFY] +** 921105 JLI [1.30 C++ support and TRACE] +** 921116 JLI [1.40 mwSetOutFunc] +** 930215 JLI [1.50 modified ASSERT/VERIFY] +** 930327 JLI [1.51 better auto-init & PC-lint support] +** 930506 JLI [1.55 MemWatch class, improved C++ support] +** 930507 JLI [1.60 mwTest & CHECK()] +** 930809 JLI [1.65 Abort/Retry/Ignore] +** 930820 JLI [1.70 data dump when unfreed] +** 931016 JLI [1.72 modified C++ new/delete handling] +** 931108 JLI [1.77 mwSetAssertAction() & some small changes] +** 940110 JLI [1.80 no-mans-land alloc/checking] +** 940328 JLI [2.00 version 2.0 rewrite] +** Improved NML (no-mans-land) support. +** Improved performance (especially for free()ing!). +** Support for 'read-only' buffers (checksums) +** ^^ NOTE: I never did this... maybe I should? +** FBI (free'd block info) tagged before freed blocks +** Exporting of the mwCounter variable +** mwBreakOut() localizes debugger support +** Allocation statistics (global, per-module, per-line) +** Self-repair ability with relinking +** 950913 JLI [2.10 improved garbage handling] +** 951201 JLI [2.11 improved auto-free in emergencies] +** 960125 JLI [X.01 implemented auto-checking using mwAutoCheck()] +** 960514 JLI [2.12 undefining of existing macros] +** 960515 JLI [2.13 possibility to use default new() & delete()] +** 960516 JLI [2.20 suppression of file flushing on unfreed msgs] +** 960516 JLI [2.21 better support for using MEMWATCH with DLL's] +** 960710 JLI [X.02 multiple logs and mwFlushNow()] +** 960801 JLI [2.22 merged X.01 version with current] +** 960805 JLI [2.30 mwIsXXXXAddr() to avoid unneeded GP's] +** 960805 JLI [2.31 merged X.02 version with current] +** 961002 JLI [2.32 support for realloc() + fixed STDERR bug] +** 961222 JLI [2.40 added mwMark() & mwUnmark()] +** 970101 JLI [2.41 added over/underflow checking after failed ASSERT/VERIFY] +** 970113 JLI [2.42 added support for PC-Lint 7.00g] +** 970207 JLI [2.43 added support for strdup()] +** 970209 JLI [2.44 changed default filename to lowercase] +** 970405 JLI [2.45 fixed bug related with atexit() and some C++ compilers] +** 970723 JLI [2.46 added MW_ARI_NULLREAD flag] +** 970813 JLI [2.47 stabilized marker handling] +** 980317 JLI [2.48 ripped out C++ support; wasn't working good anyway] +** 980318 JLI [2.50 improved self-repair facilities & SIGSEGV support] +** 980417 JLI [2.51 more checks for invalid addresses] +** 980512 JLI [2.52 moved MW_ARI_NULLREAD to occur before aborting] +** 990112 JLI [2.53 added check for empty heap to mwIsOwned] +** 990217 JLI [2.55 improved the emergency repairs diagnostics and NML] +** 990224 JLI [2.56 changed ordering of members in structures] +** 990303 JLI [2.57 first maybe-fixit-for-hpux test] +** 990516 JLI [2.58 added 'static' to the definition of mwAutoInit] +** 990517 JLI [2.59 fixed some high-sensitivity warnings] +** 990610 JLI [2.60 fixed some more high-sensitivity warnings] +** 990715 JLI [2.61 changed TRACE/ASSERT/VERIFY macro names] +** 991001 JLI [2.62 added CHECK_BUFFER() and mwTestBuffer()] +** 991007 JLI [2.63 first shot at a 64-bit compatible version] +** 991009 JLI [2.64 undef's strdup() if defined, mwStrdup made const] +** 000704 JLI [2.65 added some more detection for 64-bits] +** 010502 JLI [2.66 incorporated some user fixes] +** [mwRelink() could print out garbage pointer (thanks mac@phobos.ca)] +** [added array destructor for C++ (thanks rdasilva@connecttel.com)] +** [added mutex support (thanks rdasilva@connecttel.com)] +** 010531 JLI [2.67 fix: mwMutexXXX() was declared even if MW_HAVE_MUTEX was not defined] +** 010619 JLI [2.68 fix: mwRealloc() could leave the mutex locked] +** 020918 JLI [2.69 changed to GPL, added C++ array allocation by Howard Cohen] +** 030212 JLI [2.70 mwMalloc() bug for very large allocations (4GB on 32bits)] +** 030520 JLI [2.71 added ULONG_LONG_MAX as a 64-bit detector (thanks Sami Salonen)] +*/ + +/*@ignore@*/ + +#define __MEMWATCH_C 1 + +#ifdef MW_NOCPP +#define MEMWATCH_NOCPP +#endif +#ifdef MW_STDIO +#define MEMWATCH_STDIO +#endif + +/*********************************************************************** +** Include files +***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "./include/memwatch.h" + +#ifndef toupper +#include +#endif + +#if defined(WIN32) || defined(__WIN32__) +#define MW_HAVE_MUTEX 1 +#include +#endif + +#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H) +#define MW_HAVE_MUTEX 1 +#include +#endif + +/*********************************************************************** +** Defines & other weird stuff +***********************************************************************/ + +/*lint -save -e767 */ +#define VERSION "2.71" /* the current version number */ +#define CHKVAL(mw) (0xFE0180L^(long)mw->count^(long)mw->size^(long)mw->line) +#define FLUSH() mwFlush() +#define TESTS(f,l) if(mwTestAlways) (void)mwTestNow(f,l,1) +#define PRECHK 0x01234567L +#define POSTCHK 0x76543210L +#define mwBUFFER_TO_MW(p) ( (mwData*) (void*) ( ((char*)p)-mwDataSize-mwOverflowZoneSize ) ) +/*lint -restore */ + +#define MW_NML 0x0001 + +#ifdef _MSC_VER +#define COMMIT "c" /* Microsoft C requires the 'c' to perform as desired */ +#else +#define COMMIT "" /* Normal ANSI */ +#endif /* _MSC_VER */ + +#ifdef __cplusplus +#define CPPTEXT "++" +#else +#define CPPTEXT "" +#endif /* __cplusplus */ + +#ifdef MEMWATCH_STDIO +#define mwSTDERR stderr +#else +#define mwSTDERR mwLog +#endif + +#ifdef MW_HAVE_MUTEX +#define MW_MUTEX_INIT() mwMutexInit() +#define MW_MUTEX_TERM() mwMutexTerm() +#define MW_MUTEX_LOCK() mwMutexLock() +#define MW_MUTEX_UNLOCK() mwMutexUnlock() +#else +#define MW_MUTEX_INIT() +#define MW_MUTEX_TERM() +#define MW_MUTEX_LOCK() +#define MW_MUTEX_UNLOCK() +#endif + +/*********************************************************************** +** If you really, really know what you're doing, +** you can predefine these things yourself. +***********************************************************************/ + +#ifndef mwBYTE_DEFINED +# if CHAR_BIT != 8 +# error need CHAR_BIT to be 8! +# else +typedef unsigned char mwBYTE; +# define mwBYTE_DEFINED 1 +# endif +#endif + +#if defined(ULONGLONG_MAX) || defined(ULLONG_MAX) || defined(_UI64_MAX) || defined(ULONG_LONG_MAX) +# define mw64BIT 1 +# define mwROUNDALLOC_DEFAULT 8 +#else +# if UINT_MAX <= 0xFFFFUL +# define mw16BIT 1 +# define mwROUNDALLOC_DEFAULT 2 +# else +# if ULONG_MAX > 0xFFFFFFFFUL +# define mw64BIT 1 +# define mwROUNDALLOC_DEFAULT 8 +# else +# define mw32BIT 1 +# define mwROUNDALLOC_DEFAULT 4 +# endif +# endif +#endif + +/* mwROUNDALLOC is the number of bytes to */ +/* round up to, to ensure that the end of */ +/* the buffer is suitable for storage of */ +/* any kind of object */ +#ifndef mwROUNDALLOC +# define mwROUNDALLOC mwROUNDALLOC_DEFAULT +#endif + +#ifndef mwDWORD_DEFINED +#if ULONG_MAX == 0xFFFFFFFFUL +typedef unsigned int mwDWORD; +#define mwDWORD_DEFINED "unsigned long" +#endif +#endif + +#ifndef mwDWORD_DEFINED +#if UINT_MAX == 0xFFFFFFFFUL +typedef unsigned int mwDWORD; +#define mwDWORD_DEFINED "unsigned int" +#endif +#endif + +#ifndef mwDWORD_DEFINED +#if USHRT_MAX == 0xFFFFFFFFUL +typedef unsigned short mwDWORD; +#define mwDWORD_DEFINED "unsigned short" +#endif +#endif + +#ifndef mwBYTE_DEFINED +#error "can't find out the correct type for a 8 bit scalar" +#endif + +#ifndef mwDWORD_DEFINED +#error "can't find out the correct type for a 32 bit scalar" +#endif + +/*********************************************************************** +** Typedefs & structures +***********************************************************************/ + +/* main data holding area, precedes actual allocation */ +typedef struct mwData_ mwData; +struct mwData_ { + mwData* prev; /* previous allocation in chain */ + mwData* next; /* next allocation in chain */ + const char* file; /* file name where allocated */ + long count; /* action count */ + long check; /* integrity check value */ +#if 0 + long crc; /* data crc value */ +#endif + size_t size; /* size of allocation */ + int line; /* line number where allocated */ + unsigned flag; /* flag word */ + }; + +/* statistics structure */ +typedef struct mwStat_ mwStat; +struct mwStat_ { + mwStat* next; /* next statistic buffer */ + const char* file; + long total; /* total bytes allocated */ + long num; /* total number of allocations */ + long max; /* max allocated at one time */ + long curr; /* current allocations */ + int line; + }; + +/* grabbing structure, 1K in size */ +typedef struct mwGrabData_ mwGrabData; +struct mwGrabData_ { + mwGrabData* next; + int type; + char blob[ 1024 - sizeof(mwGrabData*) - sizeof(int) ]; + }; + +typedef struct mwMarker_ mwMarker; +struct mwMarker_ { + void *host; + char *text; + mwMarker *next; + int level; + }; + +#if defined(WIN32) || defined(__WIN32__) +typedef HANDLE mwMutex; +#endif + +#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H) +typedef pthread_mutex_t mwMutex; +#endif + +/*********************************************************************** +** Static variables +***********************************************************************/ + +static int mwInited = 0; +static int mwInfoWritten = 0; +static int mwUseAtexit = 0; +static FILE* mwLog = NULL; +static int mwFlushing = 0; +static int mwStatLevel = MW_STAT_DEFAULT; +static int mwNML = MW_NML_DEFAULT; +static int mwFBI = 0; +static long mwAllocLimit = 0L; +static int mwUseLimit = 0; + +static long mwNumCurAlloc = 0L; +static mwData* mwHead = NULL; +static mwData* mwTail = NULL; +static int mwDataSize = 0; +static unsigned char mwOverflowZoneTemplate[] = "mEmwAtch"; +static int mwOverflowZoneSize = mwROUNDALLOC; + +static void (*mwOutFunction)(int) = NULL; +static int (*mwAriFunction)(const char*) = NULL; +static int mwAriAction = MW_ARI_ABORT; + +static char mwPrintBuf[MW_TRACE_BUFFER+8]; + +static unsigned long mwCounter = 0L; +static long mwErrors = 0L; + +static int mwTestFlags = 0; +static int mwTestAlways = 0; + +static FILE* mwLogB1 = NULL; +static int mwFlushingB1 = 0; + +static mwStat* mwStatList = NULL; +static long mwStatTotAlloc = 0L; +static long mwStatMaxAlloc = 0L; +static long mwStatNumAlloc = 0L; +static long mwStatCurAlloc = 0L; +static long mwNmlNumAlloc = 0L; +static long mwNmlCurAlloc = 0L; + +static mwGrabData* mwGrabList = NULL; +static long mwGrabSize = 0L; + +static void * mwLastFree[MW_FREE_LIST]; +static const char *mwLFfile[MW_FREE_LIST]; +static int mwLFline[MW_FREE_LIST]; +static int mwLFcur = 0; + +static mwMarker* mwFirstMark = NULL; + +static FILE* mwLogB2 = NULL; +static int mwFlushingB2 = 0; + +#ifdef MW_HAVE_MUTEX +static mwMutex mwGlobalMutex; +#endif + +/*********************************************************************** +** Static function declarations +***********************************************************************/ + +static void mwAutoInit( void ); +static FILE* mwLogR( void ); +static void mwLogW( FILE* ); +static int mwFlushR( void ); +static void mwFlushW( int ); +static void mwFlush( void ); +static void mwIncErr( void ); +static void mwUnlink( mwData*, const char* file, int line ); +static int mwRelink( mwData*, const char* file, int line ); +static int mwIsHeapOK( mwData *mw ); +static int mwIsOwned( mwData* mw, const char* file, int line ); +static int mwTestBuf( mwData* mw, const char* file, int line ); +static void mwDefaultOutFunc( int ); +static void mwWrite( const char* format, ... ); +static void mwLogFile( const char* name ); +static size_t mwFreeUp( size_t, int ); +static const void *mwTestMem( const void *, unsigned, int ); +static int mwStrCmpI( const char *s1, const char *s2 ); +static int mwTestNow( const char *file, int line, int always_invoked ); +static void mwDropAll( void ); +static const char *mwGrabType( int type ); +static unsigned mwGrab_( unsigned kb, int type, int silent ); +static unsigned mwDrop_( unsigned kb, int type, int silent ); +static int mwARI( const char* text ); +static void mwStatReport( void ); +static mwStat* mwStatGet( const char*, int, int ); +static void mwStatAlloc( size_t, const char*, int ); +static void mwStatFree( size_t, const char*, int ); +static int mwCheckOF( const void * p ); +static void mwWriteOF( void * p ); +static char mwDummy( char c ); +#ifdef MW_HAVE_MUTEX +static void mwMutexInit( void ); +static void mwMutexTerm( void ); +static void mwMutexLock( void ); +static void mwMutexUnlock( void ); +#endif + +/*********************************************************************** +** System functions +***********************************************************************/ + +void mwInit( void ) { + time_t tid; + + if( mwInited++ > 0 ) return; + + MW_MUTEX_INIT(); + + /* start a log if none is running */ + if( mwLogR() == NULL ) mwLogFile( "memwatch.log" ); + if( mwLogR() == NULL ) { + int i; + char buf[32]; + /* oops, could not open it! */ + /* probably because it's already open */ + /* so we try some other names */ + for( i=1; i<100; i++ ) { + sprintf( buf, "memwat%02d.log", i ); + mwLogFile( buf ); + if( mwLogR() != NULL ) break; + } + } + + /* initialize the statistics */ + mwStatList = NULL; + mwStatTotAlloc = 0L; + mwStatCurAlloc = 0L; + mwStatMaxAlloc = 0L; + mwStatNumAlloc = 0L; + mwNmlCurAlloc = 0L; + mwNmlNumAlloc = 0L; + + /* calculate the buffer size to use for a mwData */ + mwDataSize = sizeof(mwData); + while( mwDataSize % mwROUNDALLOC ) mwDataSize ++; + + /* write informational header if needed */ + if( !mwInfoWritten ) { + mwInfoWritten = 1; + (void) time( &tid ); + mwWrite( + "\n=============" + " MEMWATCH " VERSION " Copyright (C) 1992-1999 Johan Lindh " + "=============\n"); + mwWrite( "\nStarted at %s\n", ctime( &tid ) ); + +/**************************************************************** Generic */ + mwWrite( "Modes: " ); +#ifdef mwNew + mwWrite( "C++ " ); +#endif /* mwNew */ +#ifdef __STDC__ + mwWrite( "__STDC__ " ); +#endif /* __STDC__ */ +#ifdef mw16BIT + mwWrite( "16-bit " ); +#endif +#ifdef mw32BIT + mwWrite( "32-bit " ); +#endif +#ifdef mw64BIT + mwWrite( "64-bit " ); +#endif + mwWrite( "mwDWORD==(\" mwDWORD_DEFINED \")\n" ); + mwWrite( "mwROUNDALLOC==%d sizeof(mwData)==%d mwDataSize==%d\n", + mwROUNDALLOC, sizeof(mwData), mwDataSize ); +/**************************************************************** Generic */ + +/************************************************************ Microsoft C */ +#ifdef _MSC_VER + mwWrite( "Compiled using Microsoft C" CPPTEXT + " %d.%02d\n", _MSC_VER / 100, _MSC_VER % 100 ); +#endif /* _MSC_VER */ +/************************************************************ Microsoft C */ + +/************************************************************** Borland C */ +#ifdef __BORLANDC__ + mwWrite( "Compiled using Borland C" +#ifdef __cplusplus + "++ %d.%01d\n", __BCPLUSPLUS__/0x100, (__BCPLUSPLUS__%0x100)/0x10 ); +#else + " %d.%01d\n", __BORLANDC__/0x100, (__BORLANDC__%0x100)/0x10 ); +#endif /* __cplusplus */ +#endif /* __BORLANDC__ */ +/************************************************************** Borland C */ + +/************************************************************** Watcom C */ +#ifdef __WATCOMC__ + mwWrite( "Compiled using Watcom C %d.%02d ", + __WATCOMC__/100, __WATCOMC__%100 ); +#ifdef __FLAT__ + mwWrite( "(32-bit flat model)" ); +#endif /* __FLAT__ */ + mwWrite( "\n" ); +#endif /* __WATCOMC__ */ +/************************************************************** Watcom C */ + + mwWrite( "\n" ); + FLUSH(); + } + + if( mwUseAtexit ) (void) atexit( mwAbort ); + return; + } + +void mwAbort( void ) { + mwData *mw; + mwMarker *mrk; + char *data; + time_t tid; + int c, i, j; + int errors; + + tid = time( NULL ); + mwWrite( "\nStopped at %s\n", ctime( &tid) ); + + if( !mwInited ) + mwWrite( "internal: mwAbort(): MEMWATCH not initialized!\n" ); + + /* release the grab list */ + mwDropAll(); + + /* report mwMarked items */ + while( mwFirstMark ) { + mrk = mwFirstMark->next; + mwWrite( "mark: %p: %s\n", mwFirstMark->host, mwFirstMark->text ); + free( mwFirstMark->text ); + free( mwFirstMark ); + mwFirstMark = mrk; + mwErrors ++; + } + + /* release all still allocated memory */ + errors = 0; + while( mwHead != NULL && errors < 3 ) { + if( !mwIsOwned(mwHead, __FILE__, __LINE__ ) ) { + if( errors < 3 ) + { + errors ++; + mwWrite( "internal: NML/unfreed scan restarting\n" ); + FLUSH(); + mwHead = mwHead; + continue; + } + mwWrite( "internal: NML/unfreed scan aborted, heap too damaged\n" ); + FLUSH(); + break; + } + mwFlushW(0); + if( !(mwHead->flag & MW_NML) ) { + mwErrors++; + data = ((char*)mwHead)+mwDataSize; + mwWrite( "unfreed: <%ld> %s(%d), %ld bytes at %p ", + mwHead->count, mwHead->file, mwHead->line, (long)mwHead->size, data+mwOverflowZoneSize ); + if( mwCheckOF( data ) ) { + mwWrite( "[underflowed] "); + FLUSH(); + } + if( mwCheckOF( (data+mwOverflowZoneSize+mwHead->size) ) ) { + mwWrite( "[overflowed] "); + FLUSH(); + } + mwWrite( " \t{" ); + j = 16; if( mwHead->size < 16 ) j = (int) mwHead->size; + for( i=0;i<16;i++ ) { + if( i 126 ) c = '.'; + mwWrite( "%c", c ); + } + mwWrite( "}\n" ); + mw = mwHead; + mwUnlink( mw, __FILE__, __LINE__ ); + free( mw ); + } + else { + data = ((char*)mwHead) + mwDataSize + mwOverflowZoneSize; + if( mwTestMem( data, mwHead->size, MW_VAL_NML ) ) { + mwErrors++; + mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n", + mwHead->count, data + mwOverflowZoneSize, mwHead->file, mwHead->line ); + FLUSH(); + } + mwNmlNumAlloc --; + mwNmlCurAlloc -= mwHead->size; + mw = mwHead; + mwUnlink( mw, __FILE__, __LINE__ ); + free( mw ); + } + } + + if( mwNmlNumAlloc ) mwWrite("internal: NoMansLand block counter %ld, not zero\n", mwNmlNumAlloc ); + if( mwNmlCurAlloc ) mwWrite("internal: NoMansLand byte counter %ld, not zero\n", mwNmlCurAlloc ); + + /* report statistics */ + mwStatReport(); + FLUSH(); + + mwInited = 0; + mwHead = mwTail = NULL; + if( mwErrors ) + fprintf(mwSTDERR,"MEMWATCH detected %ld anomalies\n",mwErrors); + mwLogFile( NULL ); + mwErrors = 0; + + MW_MUTEX_TERM(); + + } + +void mwTerm( void ) { + if( mwInited == 1 ) + { + mwAbort(); + return; + } + if( !mwInited ) + mwWrite("internal: mwTerm(): MEMWATCH has not been started!\n"); + else + mwInited --; + } + +void mwStatistics( int level ) +{ + mwAutoInit(); + if( level<0 ) level=0; + if( mwStatLevel != level ) + { + mwWrite( "statistics: now collecting on a %s basis\n", + level<1?"global":(level<2?"module":"line") ); + mwStatLevel = level; + } +} + +void mwAutoCheck( int onoff ) { + mwAutoInit(); + mwTestAlways = onoff; + if( onoff ) mwTestFlags = MW_TEST_ALL; + } + +void mwSetOutFunc( void (*func)(int) ) { + mwAutoInit(); + mwOutFunction = func; + } + +static void mwWriteOF( void *p ) +{ + int i; + unsigned char *ptr; + ptr = (unsigned char*) p; + for( i=0; inext is not always set? +*/ +void * mwMark( void *p, const char *desc, const char *file, unsigned line ) { + mwMarker *mrk; + unsigned n, isnew; + char *buf; + int tot, oflow = 0; + char wherebuf[128]; + + mwAutoInit(); + TESTS(NULL,0); + + if( desc == NULL ) desc = "unknown"; + if( file == NULL ) file = "unknown"; + + tot = sprintf( wherebuf, "%.48s called from %s(%d)", desc, file, line ); + if( tot >= (int)sizeof(wherebuf) ) { wherebuf[sizeof(wherebuf)-1] = 0; oflow = 1; } + + if( p == NULL ) { + mwWrite("mark: %s(%d), no mark for NULL:'%s' may be set\n", file, line, desc ); + return p; + } + + if( mwFirstMark != NULL && !mwIsReadAddr( mwFirstMark, sizeof( mwMarker ) ) ) + { + mwWrite("mark: %s(%d), mwFirstMark (%p) is trashed, can't mark for %s\n", + file, line, mwFirstMark, desc ); + return p; + } + + for( mrk=mwFirstMark; mrk; mrk=mrk->next ) + { + if( mrk->next != NULL && !mwIsReadAddr( mrk->next, sizeof( mwMarker ) ) ) + { + mwWrite("mark: %s(%d), mark(%p)->next(%p) is trashed, can't mark for %s\n", + file, line, mrk, mrk->next, desc ); + return p; + } + if( mrk->host == p ) break; + } + + if( mrk == NULL ) { + isnew = 1; + mrk = (mwMarker*) malloc( sizeof( mwMarker ) ); + if( mrk == NULL ) { + mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc ); + return p; + } + mrk->next = NULL; + n = 0; + } + else { + isnew = 0; + n = strlen( mrk->text ); + } + + n += strlen( wherebuf ); + buf = (char*) malloc( n+3 ); + if( buf == NULL ) { + if( isnew ) free( mrk ); + mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc ); + return p; + } + + if( isnew ) { + memcpy( buf, wherebuf, n+1 ); + mrk->next = mwFirstMark; + mrk->host = p; + mrk->text = buf; + mrk->level = 1; + mwFirstMark = mrk; + } + else { + strcpy( buf, mrk->text ); + strcat( buf, ", " ); + strcat( buf, wherebuf ); + free( mrk->text ); + mrk->text = buf; + mrk->level ++; + } + + if( oflow ) { + mwIncErr(); + mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" ); + } + return p; + } + +void* mwUnmark( void *p, const char *file, unsigned line ) { + mwMarker *mrk, *prv; + mrk = mwFirstMark; + prv = NULL; + while( mrk ) { + if( mrk->host == p ) { + if( mrk->level < 2 ) { + if( prv ) prv->next = mrk->next; + else mwFirstMark = mrk->next; + free( mrk->text ); + free( mrk ); + return p; + } + mrk->level --; + return p; + } + prv = mrk; + mrk = mrk->next; + } + mwWrite("mark: %s(%d), no mark found for %p\n", file, line, p ); + return p; + } + + +/*********************************************************************** +** Abort/Retry/Ignore handlers +***********************************************************************/ + +static int mwARI( const char *estr ) { + char inbuf[81]; + int c; + fprintf(mwSTDERR, "\n%s\nMEMWATCH: Abort, Retry or Ignore? ", estr); + (void) fgets(inbuf,sizeof(inbuf),stdin); + for( c=0; inbuf[c] && inbuf[c] <= ' '; c++ ) ; + c = inbuf[c]; + if( c == 'R' || c == 'r' ) { + mwBreakOut( estr ); + return MW_ARI_RETRY; + } + if( c == 'I' || c == 'i' ) return MW_ARI_IGNORE; + return MW_ARI_ABORT; + } + +/* standard ARI handler (exported) */ +int mwAriHandler( const char *estr ) { + mwAutoInit(); + return mwARI( estr ); + } + +/* used to set the ARI function */ +void mwSetAriFunc( int (*func)(const char *) ) { + mwAutoInit(); + mwAriFunction = func; + } + +/*********************************************************************** +** Allocation handlers +***********************************************************************/ + +void* mwMalloc( size_t size, const char* file, int line) { + size_t needed; + mwData *mw; + char *ptr; + void *p; + + mwAutoInit(); + + MW_MUTEX_LOCK(); + + TESTS(file,line); + + mwCounter ++; + needed = mwDataSize + mwOverflowZoneSize*2 + size; + if( needed < size ) + { + /* theoretical case: req size + mw overhead exceeded size_t limits */ + return NULL; + } + + /* if this allocation would violate the limit, fail it */ + if( mwUseLimit && ((long)size + mwStatCurAlloc > mwAllocLimit) ) { + mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n", + mwCounter, file, line, (long)size, mwAllocLimit - mwStatCurAlloc ); + mwIncErr(); + FLUSH(); + MW_MUTEX_UNLOCK(); + return NULL; + } + + mw = (mwData*) malloc( needed ); + if( mw == NULL ) { + if( mwFreeUp(needed,0) >= needed ) { + mw = (mwData*) malloc(needed); + if( mw == NULL ) { + mwWrite( "internal: mwFreeUp(%u) reported success, but malloc() fails\n", needed ); + mwIncErr(); + FLUSH(); + } + } + if( mw == NULL ) { + mwWrite( "fail: <%ld> %s(%d), %ld wanted %ld allocated\n", + mwCounter, file, line, (long)size, mwStatCurAlloc ); + mwIncErr(); + FLUSH(); + MW_MUTEX_UNLOCK(); + return NULL; + } + } + + mw->count = mwCounter; + mw->prev = NULL; + mw->next = mwHead; + mw->file = file; + mw->size = size; + mw->line = line; + mw->flag = 0; + mw->check = CHKVAL(mw); + + if( mwHead ) mwHead->prev = mw; + mwHead = mw; + if( mwTail == NULL ) mwTail = mw; + + ptr = ((char*)mw) + mwDataSize; + mwWriteOF( ptr ); /* '*(long*)ptr = PRECHK;' */ + ptr += mwOverflowZoneSize; + p = ptr; + memset( ptr, MW_VAL_NEW, size ); + ptr += size; + mwWriteOF( ptr ); /* '*(long*)ptr = POSTCHK;' */ + + mwNumCurAlloc ++; + mwStatCurAlloc += (long) size; + mwStatTotAlloc += (long) size; + if( mwStatCurAlloc > mwStatMaxAlloc ) + mwStatMaxAlloc = mwStatCurAlloc; + mwStatNumAlloc ++; + + if( mwStatLevel ) mwStatAlloc( size, file, line ); + + MW_MUTEX_UNLOCK(); + return p; + } + +void* mwRealloc( void *p, size_t size, const char* file, int line) { + int oldUseLimit, i; + mwData *mw; + char *ptr; + + mwAutoInit(); + + if( p == NULL ) return mwMalloc( size, file, line ); + if( size == 0 ) { mwFree( p, file, line ); return NULL; } + + MW_MUTEX_LOCK(); + + /* do the quick ownership test */ + mw = (mwData*) mwBUFFER_TO_MW( p ); + if( mwIsOwned( mw, file, line ) ) { + + /* if the buffer is an NML, treat this as a double-free */ + if( mw->flag & MW_NML ) + { + mwIncErr(); + if( *((unsigned char*)(mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML ) + { + mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n", + mwCounter, file, line, mw ); + } + goto check_dbl_free; + } + + /* if this allocation would violate the limit, fail it */ + if( mwUseLimit && ((long)size + mwStatCurAlloc - (long)mw->size > mwAllocLimit) ) { + TESTS(file,line); + mwCounter ++; + mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n", + mwCounter, file, line, (unsigned long)size - mw->size, mwAllocLimit - mwStatCurAlloc ); + mwIncErr(); + FLUSH(); + MW_MUTEX_UNLOCK(); + return NULL; + } + + /* fake realloc operation */ + oldUseLimit = mwUseLimit; + mwUseLimit = 0; + ptr = (char*) mwMalloc( size, file, line ); + if( ptr != NULL ) { + if( size < mw->size ) + memcpy( ptr, p, size ); + else + memcpy( ptr, p, mw->size ); + mwFree( p, file, line ); + } + mwUseLimit = oldUseLimit; + MW_MUTEX_UNLOCK(); + return (void*) ptr; + } + + /* Unknown pointer! */ + + /* using free'd pointer? */ +check_dbl_free: + for(i=0;i %s(%d), %p was" + " freed from %s(%d)\n", + mwCounter, file, line, p, + mwLFfile[i], mwLFline[i] ); + FLUSH(); + MW_MUTEX_UNLOCK(); + return NULL; + } + } + + /* some weird pointer */ + mwIncErr(); + mwWrite( "realloc: <%ld> %s(%d), unknown pointer %p\n", + mwCounter, file, line, p ); + FLUSH(); + MW_MUTEX_UNLOCK(); + return NULL; + } + +char *mwStrdup( const char* str, const char* file, int line ) { + size_t len; + char *newstring; + + MW_MUTEX_LOCK(); + + if( str == NULL ) { + mwIncErr(); + mwWrite( "strdup: <%ld> %s(%d), strdup(NULL) called\n", + mwCounter, file, line ); + FLUSH(); + MW_MUTEX_UNLOCK(); + return NULL; + } + + len = strlen( str ) + 1; + newstring = (char*) mwMalloc( len, file, line ); + if( newstring != NULL ) memcpy( newstring, str, len ); + MW_MUTEX_UNLOCK(); + return newstring; + } + +void mwFree( void* p, const char* file, int line ) { + int i; + mwData* mw; + char buffer[ sizeof(mwData) + (mwROUNDALLOC*3) + 64 ]; + + /* this code is in support of C++ delete */ + if( file == NULL ) { + mwFree_( p ); + MW_MUTEX_UNLOCK(); + return; + } + + mwAutoInit(); + + MW_MUTEX_LOCK(); + TESTS(file,line); + mwCounter ++; + + /* on NULL free, write a warning and return */ + if( p == NULL ) { + mwWrite( "NULL free: <%ld> %s(%d), NULL pointer free'd\n", + mwCounter, file, line ); + FLUSH(); + MW_MUTEX_UNLOCK(); + return; + } + + /* do the quick ownership test */ + mw = (mwData*) mwBUFFER_TO_MW( p ); + + if( mwIsOwned( mw, file, line ) ) { + (void) mwTestBuf( mw, file, line ); + + /* if the buffer is an NML, treat this as a double-free */ + if( mw->flag & MW_NML ) + { + if( *(((unsigned char*)mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML ) + { + mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n", + mwCounter, file, line, mw ); + } + goto check_dbl_free; + } + + /* update the statistics */ + mwNumCurAlloc --; + mwStatCurAlloc -= (long) mw->size; + if( mwStatLevel ) mwStatFree( mw->size, mw->file, mw->line ); + + /* we should either free the allocation or keep it as NML */ + if( mwNML ) { + mw->flag |= MW_NML; + mwNmlNumAlloc ++; + mwNmlCurAlloc += (long) mw->size; + memset( ((char*)mw)+mwDataSize+mwOverflowZoneSize, MW_VAL_NML, mw->size ); + } + else { + /* unlink the allocation, and enter the post-free data */ + mwUnlink( mw, file, line ); + memset( mw, MW_VAL_DEL, + mw->size + mwDataSize+mwOverflowZoneSize+mwOverflowZoneSize ); + if( mwFBI ) { + memset( mw, '.', mwDataSize + mwOverflowZoneSize ); + sprintf( buffer, "FBI<%ld>%s(%d)", mwCounter, file, line ); + strncpy( (char*)(void*)mw, buffer, mwDataSize + mwOverflowZoneSize ); + } + free( mw ); + } + + /* add the pointer to the last-free track */ + mwLFfile[ mwLFcur ] = file; + mwLFline[ mwLFcur ] = line; + mwLastFree[ mwLFcur++ ] = p; + if( mwLFcur == MW_FREE_LIST ) mwLFcur = 0; + + MW_MUTEX_UNLOCK(); + return; + } + + /* check for double-freeing */ +check_dbl_free: + for(i=0;i %s(%d), %p was" + " freed from %s(%d)\n", + mwCounter, file, line, p, + mwLFfile[i], mwLFline[i] ); + FLUSH(); + MW_MUTEX_UNLOCK(); + return; + } + } + + /* some weird pointer... block the free */ + mwIncErr(); + mwWrite( "WILD free: <%ld> %s(%d), unknown pointer %p\n", + mwCounter, file, line, p ); + FLUSH(); + MW_MUTEX_UNLOCK(); + return; + } + +void* mwCalloc( size_t a, size_t b, const char *file, int line ) { + void *p; + size_t size = a * b; + p = mwMalloc( size, file, line ); + if( p == NULL ) return NULL; + memset( p, 0, size ); + return p; + } + +void mwFree_( void *p ) { + MW_MUTEX_LOCK(); + TESTS(NULL,0); + MW_MUTEX_UNLOCK(); + free(p); + } + +void* mwMalloc_( size_t size ) { + MW_MUTEX_LOCK(); + TESTS(NULL,0); + MW_MUTEX_UNLOCK(); + return malloc( size ); + } + +void* mwRealloc_( void *p, size_t size ) { + MW_MUTEX_LOCK(); + TESTS(NULL,0); + MW_MUTEX_UNLOCK(); + return realloc( p, size ); + } + +void* mwCalloc_( size_t a, size_t b ) { + MW_MUTEX_LOCK(); + TESTS(NULL,0); + MW_MUTEX_UNLOCK(); + return calloc( a, b ); + } + +void mwFlushNow( void ) { + if( mwLogR() ) fflush( mwLogR() ); + return; + } + +void mwDoFlush( int onoff ) { + mwFlushW( onoff<1?0:onoff ); + if( onoff ) if( mwLogR() ) fflush( mwLogR() ); + return; + } + +void mwLimit( long lim ) { + TESTS(NULL,0); + mwWrite("limit: old limit = "); + if( !mwAllocLimit ) mwWrite( "none" ); + else mwWrite( "%ld bytes", mwAllocLimit ); + mwWrite( ", new limit = "); + if( !lim ) { + mwWrite( "none\n" ); + mwUseLimit = 0; + } + else { + mwWrite( "%ld bytes\n", lim ); + mwUseLimit = 1; + } + mwAllocLimit = lim; + FLUSH(); + } + +void mwSetAriAction( int action ) { + MW_MUTEX_LOCK(); + TESTS(NULL,0); + mwAriAction = action; + MW_MUTEX_UNLOCK(); + return; + } + +int mwAssert( int exp, const char *exps, const char *fn, int ln ) { + int i; + char buffer[MW_TRACE_BUFFER+8]; + if( exp ) { + return 0; + } + mwAutoInit(); + MW_MUTEX_LOCK(); + TESTS(fn,ln); + mwIncErr(); + mwCounter++; + mwWrite( "assert trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps ); + if( mwAriFunction != NULL ) { + sprintf( buffer, "MEMWATCH: assert trap: %s(%d), %s", fn, ln, exps ); + i = (*mwAriFunction)(buffer); + switch( i ) { + case MW_ARI_IGNORE: + mwWrite( "assert trap: <%ld> IGNORED - execution continues\n", mwCounter ); + MW_MUTEX_UNLOCK(); + return 0; + case MW_ARI_RETRY: + mwWrite( "assert trap: <%ld> RETRY - executing again\n", mwCounter ); + MW_MUTEX_UNLOCK(); + return 1; + } + } + else { + if( mwAriAction & MW_ARI_IGNORE ) { + mwWrite( "assert trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter ); + MW_MUTEX_UNLOCK(); + return 0; + } + fprintf(mwSTDERR,"\nMEMWATCH: assert trap: %s(%d), %s\n", fn, ln, exps ); + } + + FLUSH(); + (void) mwTestNow( fn, ln, 1 ); + FLUSH(); + + if( mwAriAction & MW_ARI_NULLREAD ) { + /* This is made in an attempt to kick in */ + /* any debuggers or OS stack traces */ + FLUSH(); + /*lint -save -e413 */ + i = *((int*)NULL); + mwDummy( (char)i ); + /*lint -restore */ + } + + MW_MUTEX_UNLOCK(); + exit(255); + /* NOT REACHED - the return statement is in to keep */ + /* stupid compilers from squeaking about differing return modes. */ + /* Smart compilers instead say 'code unreachable...' */ + /*lint -save -e527 */ + return 0; + /*lint -restore */ + } + +int mwVerify( int exp, const char *exps, const char *fn, int ln ) { + int i; + char buffer[MW_TRACE_BUFFER+8]; + if( exp ) { + return 0; + } + mwAutoInit(); + MW_MUTEX_LOCK(); + TESTS(fn,ln); + mwIncErr(); + mwCounter++; + mwWrite( "verify trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps ); + if( mwAriFunction != NULL ) { + sprintf( buffer, "MEMWATCH: verify trap: %s(%d), %s", fn, ln, exps ); + i = (*mwAriFunction)(buffer); + if( i == 0 ) { + mwWrite( "verify trap: <%ld> IGNORED - execution continues\n", mwCounter ); + MW_MUTEX_UNLOCK(); + return 0; + } + if( i == 1 ) { + mwWrite( "verify trap: <%ld> RETRY - executing again\n", mwCounter ); + MW_MUTEX_UNLOCK(); + return 1; + } + } + else { + if( mwAriAction & MW_ARI_NULLREAD ) { + /* This is made in an attempt to kick in */ + /* any debuggers or OS stack traces */ + FLUSH(); + /*lint -save -e413 */ + i = *((int*)NULL); + mwDummy( (char)i ); + /*lint -restore */ + } + if( mwAriAction & MW_ARI_IGNORE ) { + mwWrite( "verify trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter ); + MW_MUTEX_UNLOCK(); + return 0; + } + fprintf(mwSTDERR,"\nMEMWATCH: verify trap: %s(%d), %s\n", fn, ln, exps ); + } + FLUSH(); + (void) mwTestNow( fn, ln, 1 ); + FLUSH(); + MW_MUTEX_UNLOCK(); + exit(255); + /* NOT REACHED - the return statement is in to keep */ + /* stupid compilers from squeaking about differing return modes. */ + /* Smart compilers instead say 'code unreachable...' */ + /*lint -save -e527 */ + return 0; + /*lint -restore */ + } + +void mwTrace( const char *format, ... ) { + int tot, oflow = 0; + va_list mark; + + mwAutoInit(); + MW_MUTEX_LOCK(); + TESTS(NULL,0); + if( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc; + + va_start( mark, format ); + tot = vsprintf( mwPrintBuf, format, mark ); + va_end( mark ); + if( tot >= MW_TRACE_BUFFER ) { mwPrintBuf[MW_TRACE_BUFFER] = 0; oflow = 1; } + for(tot=0;mwPrintBuf[tot];tot++) + (*mwOutFunction)( mwPrintBuf[tot] ); + if( oflow ) { + mwIncErr(); + mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" ); + } + + FLUSH(); + MW_MUTEX_UNLOCK(); + } + + +/*********************************************************************** +** Grab & Drop +***********************************************************************/ + +unsigned mwGrab( unsigned kb ) { + TESTS(NULL,0); + return mwGrab_( kb, MW_VAL_GRB, 0 ); + } + +unsigned mwDrop( unsigned kb ) { + TESTS(NULL,0); + return mwDrop_( kb, MW_VAL_GRB, 0 ); + } + +static void mwDropAll() { + TESTS(NULL,0); + (void) mwDrop_( 0, MW_VAL_GRB, 0 ); + (void) mwDrop_( 0, MW_VAL_NML, 0 ); + if( mwGrabList != NULL ) + mwWrite( "internal: the grab list is not empty after mwDropAll()\n"); + } + +static const char *mwGrabType( int type ) { + switch( type ) { + case MW_VAL_GRB: + return "grabbed"; + case MW_VAL_NML: + return "no-mans-land"; + default: + /* do nothing */ + ; + } + return ""; + } + +static unsigned mwGrab_( unsigned kb, int type, int silent ) { + unsigned i = kb; + mwGrabData *gd; + if( !kb ) i = kb = 65000U; + + for(;kb;kb--) { + if( mwUseLimit && + (mwStatCurAlloc + mwGrabSize + (long)sizeof(mwGrabData) > mwAllocLimit) ) { + if( !silent ) { + mwWrite("grabbed: all allowed memory to %s (%u kb)\n", + mwGrabType(type), i-kb); + FLUSH(); + } + return i-kb; + } + gd = (mwGrabData*) malloc( sizeof(mwGrabData) ); + if( gd == NULL ) { + if( !silent ) { + mwWrite("grabbed: all available memory to %s (%u kb)\n", + mwGrabType(type), i-kb); + FLUSH(); + } + return i-kb; + } + mwGrabSize += (long) sizeof(mwGrabData); + gd->next = mwGrabList; + memset( gd->blob, type, sizeof(gd->blob) ); + gd->type = type; + mwGrabList = gd; + } + if( !silent ) { + mwWrite("grabbed: %u kilobytes of %s memory\n", i, mwGrabType(type) ); + FLUSH(); + } + return i; + } + +static unsigned mwDrop_( unsigned kb, int type, int silent ) { + unsigned i = kb; + mwGrabData *gd,*tmp,*pr; + const void *p; + + if( mwGrabList == NULL && kb == 0 ) return 0; + if( !kb ) i = kb = 60000U; + + pr = NULL; + gd = mwGrabList; + for(;kb;) { + if( gd == NULL ) { + if( i-kb > 0 && !silent ) { + mwWrite("dropped: all %s memory (%u kb)\n", mwGrabType(type), i-kb); + FLUSH(); + } + return i-kb; + } + if( gd->type == type ) { + if( pr ) pr->next = gd->next; + kb --; + tmp = gd; + if( mwGrabList == gd ) mwGrabList = gd->next; + gd = gd->next; + p = mwTestMem( tmp->blob, sizeof( tmp->blob ), type ); + if( p != NULL ) { + mwWrite( "wild pointer: <%ld> %s memory hit at %p\n", + mwCounter, mwGrabType(type), p ); + FLUSH(); + } + mwGrabSize -= (long) sizeof(mwGrabData); + free( tmp ); + } + else { + pr = gd; + gd = gd->next; + } + } + if( !silent ) { + mwWrite("dropped: %u kilobytes of %s memory\n", i, mwGrabType(type) ); + FLUSH(); + } + return i; + } + +/*********************************************************************** +** No-Mans-Land +***********************************************************************/ + +void mwNoMansLand( int level ) { + mwAutoInit(); + TESTS(NULL,0); + switch( level ) { + case MW_NML_NONE: + (void) mwDrop_( 0, MW_VAL_NML, 0 ); + break; + case MW_NML_FREE: + break; + case MW_NML_ALL: + (void) mwGrab_( 0, MW_VAL_NML, 0 ); + break; + default: + return; + } + mwNML = level; + } + +/*********************************************************************** +** Static functions +***********************************************************************/ + +static void mwAutoInit( void ) +{ + if( mwInited ) return; + mwUseAtexit = 1; + mwInit(); + return; +} + +static FILE *mwLogR() { + if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) return mwLog; + if( mwLog == mwLogB1 ) mwLogB2 = mwLog; + if( mwLog == mwLogB2 ) mwLogB1 = mwLog; + if( mwLogB1 == mwLogB2 ) mwLog = mwLogB1; + if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) { + mwWrite("internal: log file handle damaged and recovered\n"); + FLUSH(); + return mwLog; + } + fprintf(mwSTDERR,"\nMEMWATCH: log file handle destroyed, using mwSTDERR\n" ); + mwLog = mwLogB1 = mwLogB2 = mwSTDERR; + return mwSTDERR; + } + +static void mwLogW( FILE *p ) { + mwLog = mwLogB1 = mwLogB2 = p; + } + +static int mwFlushR() { + if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) return mwFlushing; + if( mwFlushing == mwFlushingB1 ) mwFlushingB2 = mwFlushing; + if( mwFlushing == mwFlushingB2 ) mwFlushingB1 = mwFlushing; + if( mwFlushingB1 == mwFlushingB2 ) mwFlushing = mwFlushingB1; + if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) { + mwWrite("internal: flushing flag damaged and recovered\n"); + FLUSH(); + return mwFlushing; + } + mwWrite("internal: flushing flag destroyed, so set to true\n"); + mwFlushing = mwFlushingB1 = mwFlushingB2 = 1; + return 1; + } + +static void mwFlushW( int n ) { + mwFlushing = mwFlushingB1 = mwFlushingB2 = n; + } + +static void mwIncErr() { + mwErrors++; + mwFlushW( mwFlushR()+1 ); + FLUSH(); + } + +static void mwFlush() { + if( mwLogR() == NULL ) return; +#ifdef MW_FLUSH + fflush( mwLogR() ); +#else + if( mwFlushR() ) fflush( mwLogR() ); +#endif + return; + } + +static void mwUnlink( mwData* mw, const char* file, int line ) { + if( mw->prev == NULL ) { + if( mwHead != mw ) + mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 NULL, but not head\n", + mwCounter, file, line, mw ); + mwHead = mw->next; + } + else { + if( mw->prev->next != mw ) + mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 failure\n", + mwCounter, file, line, mw ); + else mw->prev->next = mw->next; + } + if( mw->next == NULL ) { + if( mwTail != mw ) + mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 NULL, but not tail\n", + mwCounter, file, line, mw ); + mwTail = mw->prev; + } + else { + if( mw->next->prev != mw ) + mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 failure\n", + mwCounter, file, line, mw ); + else mw->next->prev = mw->prev; + } + } + +/* +** Relinking tries to repair a damaged mw block. +** Returns nonzero if it thinks it successfully +** repaired the heap chain. +*/ +static int mwRelink( mwData* mw, const char* file, int line ) { + int fails; + mwData *mw1, *mw2; + long count, size; + mwStat *ms; + + if( file == NULL ) file = "unknown"; + + if( mw == NULL ) { + mwWrite("relink: cannot repair MW at NULL\n"); + FLUSH(); + goto emergency; + } + + if( !mwIsSafeAddr(mw, mwDataSize) ) { + mwWrite("relink: MW-%p is a garbage pointer\n", mw); + FLUSH(); + goto emergency; + } + + mwWrite("relink: <%ld> %s(%d) attempting to repair MW-%p...\n", mwCounter, file, line, mw ); + FLUSH(); + fails = 0; + + /* Repair from head */ + if( mwHead != mw ) { + if( !mwIsSafeAddr( mwHead, mwDataSize ) ) { + mwWrite("relink: failed for MW-%p; head pointer destroyed\n", mw ); + FLUSH(); + goto emergency; + } + for( mw1=mwHead; mw1; mw1=mw1->next ) { + if( mw1->next == mw ) { + mw->prev = mw1; + break; + } + if( mw1->next && + ( !mwIsSafeAddr(mw1->next, mwDataSize ) || mw1->next->prev != mw1) ) { + mwWrite("relink: failed for MW-%p; forward chain fragmented at MW-%p: 'next' is %p\n", mw, mw1, mw1->next ); + FLUSH(); + goto emergency; + } + } + if( mw1 == NULL ) { + mwWrite("relink: MW-%p not found in forward chain search\n", mw ); + FLUSH(); + fails ++; + } + } + else + { + mwWrite( "relink: MW-%p is the head (first) allocation\n", mw ); + if( mw->prev != NULL ) + { + mwWrite( "relink: MW-%p prev pointer is non-NULL, you have a wild pointer\n", mw ); + mw->prev = NULL; + } + } + + /* Repair from tail */ + if( mwTail != mw ) { + if( !mwIsSafeAddr( mwTail, mwDataSize ) ) { + mwWrite("relink: failed for MW-%p; tail pointer destroyed\n", mw ); + FLUSH(); + goto emergency; + } + for( mw1=mwTail; mw1; mw1=mw1->prev ) { + if( mw1->prev == mw ) { + mw->next = mw1; + break; + } + if( mw1->prev && (!mwIsSafeAddr(mw1->prev, mwDataSize ) || mw1->prev->next != mw1) ) { + mwWrite("relink: failed for MW-%p; reverse chain fragmented at MW-%p, 'prev' is %p\n", mw, mw1, mw1->prev ); + FLUSH(); + goto emergency; + } + } + if( mw1 == NULL ) { + mwWrite("relink: MW-%p not found in reverse chain search\n", mw ); + FLUSH(); + fails ++; + } + } + else + { + mwWrite( "relink: MW-%p is the tail (last) allocation\n", mw ); + if( mw->next != NULL ) + { + mwWrite( "relink: MW-%p next pointer is non-NULL, you have a wild pointer\n", mw ); + mw->next = NULL; + } + } + + if( fails > 1 ) { + mwWrite("relink: heap appears intact, MW-%p probably garbage pointer\n", mw ); + FLUSH(); + goto verifyok; + } + + /* restore MW info where possible */ + if( mwIsReadAddr( mw->file, 1 ) ) { + ms = mwStatGet( mw->file, -1, 0 ); + if( ms == NULL ) mw->file = ""; + } + mw->check = CHKVAL(mw); + goto verifyok; + + /* Emergency repair */ + emergency: + + if( mwHead == NULL && mwTail == NULL ) + { + if( mwStatCurAlloc == 0 ) + mwWrite("relink: <%ld> %s(%d) heap is empty, nothing to repair\n", mwCounter, file, line ); + else + mwWrite("relink: <%ld> %s(%d) heap damaged beyond repair\n", mwCounter, file, line ); + FLUSH(); + return 0; + } + + mwWrite("relink: <%ld> %s(%d) attempting emergency repairs...\n", mwCounter, file, line ); + FLUSH(); + + if( mwHead == NULL || mwTail == NULL ) + { + if( mwHead == NULL ) mwWrite("relink: mwHead is NULL, but mwTail is %p\n", mwTail ); + else mwWrite("relink: mwTail is NULL, but mwHead is %p\n", mwHead ); + } + + mw1=NULL; + if( mwHead != NULL ) + { + if( !mwIsReadAddr( mwHead, mwDataSize ) || mwHead->check != CHKVAL(mwHead) ) + { + mwWrite("relink: mwHead (MW-%p) is damaged, skipping forward scan\n", mwHead ); + mwHead = NULL; + goto scan_reverse; + } + if( mwHead->prev != NULL ) + { + mwWrite("relink: the mwHead pointer's 'prev' member is %p, not NULL\n", mwHead->prev ); + } + for( mw1=mwHead; mw1; mw1=mw1->next ) + { + if( mw1->next ) + { + if( !mwIsReadAddr(mw1->next,mwDataSize) || + !mw1->next->check != CHKVAL(mw1) || + mw1->next->prev != mw1 ) + { + mwWrite("relink: forward chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n", + mw1, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw1->file, mw1->line ); + if( mwIsReadAddr(mw1->next,mwDataSize ) ) + { + mwWrite("relink: forward chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n", + mw1->next, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"", + mwIsReadAddr(mw1->file,16)?mw1->file:"", mw1->line ); + } + else + { + mwWrite("relink: the 'next' pointer of this MW points to %p, which is out-of-legal-access\n", + mw1->next ); + } + break; + } + } + } + } + + +scan_reverse: + mw2=NULL; + if( mwTail != NULL ) + { + if( !mwIsReadAddr(mwTail,mwDataSize) || mwTail->check != CHKVAL(mwTail) ) + { + mwWrite("relink: mwTail (%p) is damaged, skipping reverse scan\n", mwTail ); + mwTail = NULL; + goto analyze; + } + if( mwTail->next != NULL ) + { + mwWrite("relink: the mwTail pointer's 'next' member is %p, not NULL\n", mwTail->next ); + } + for( mw2=mwTail; mw2; mw2=mw2->prev ) + { + if( mw2->prev ) + { + if( !mwIsReadAddr(mw2->prev,mwDataSize) || + !mw2->prev->check != CHKVAL(mw2) || + mw2->prev->next != mw2 ) + { + mwWrite("relink: reverse chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n", + mw2, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw2->file, mw2->line ); + if( mwIsReadAddr(mw2->prev,mwDataSize ) ) + { + mwWrite("relink: reverse chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n", + mw2->prev, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"", + mwIsReadAddr(mw2->file,16)?mw2->file:"", mw2->line ); + } + else + { + mwWrite("relink: the 'prev' pointer of this MW points to %p, which is out-of-legal-access\n", + mw2->prev ); + } + break; + } + } + } + } + +analyze: + if( mwHead == NULL && mwTail == NULL ) + { + mwWrite("relink: both head and tail pointers damaged, aborting program\n"); + mwFlushW(1); + FLUSH(); + abort(); + } + if( mwHead == NULL ) + { + mwHead = mw2; + mwWrite("relink: heap truncated, MW-%p designated as new mwHead\n", mw2 ); + mw2->prev = NULL; + mw1 = mw2 = NULL; + } + if( mwTail == NULL ) + { + mwTail = mw1; + mwWrite("relink: heap truncated, MW-%p designated as new mwTail\n", mw1 ); + mw1->next = NULL; + mw1 = mw2 = NULL; + } + if( mw1 == NULL && mw2 == NULL && + mwHead->prev == NULL && mwTail->next == NULL ) { + mwWrite("relink: verifying heap integrity...\n" ); + FLUSH(); + goto verifyok; + } + if( mw1 && mw2 && mw1 != mw2 ) { + mw1->next = mw2; + mw2->prev = mw1; + mwWrite("relink: emergency repairs successful, assessing damage...\n"); + FLUSH(); + } + else { + mwWrite("relink: heap totally destroyed, aborting program\n"); + mwFlushW(1); + FLUSH(); + abort(); + } + + /* Verify by checking that the number of active allocations */ + /* match the number of entries in the chain */ +verifyok: + if( !mwIsHeapOK( NULL ) ) { + mwWrite("relink: heap verification FAILS - aborting program\n"); + mwFlushW(1); + FLUSH(); + abort(); + } + for( size=count=0, mw1=mwHead; mw1; mw1=mw1->next ) { + count ++; + size += (long) mw1->size; + } + if( count == mwNumCurAlloc ) { + mwWrite("relink: successful, "); + if( size == mwStatCurAlloc ) { + mwWrite("no allocations lost\n"); + } + else { + if( mw != NULL ) { + mwWrite("size information lost for MW-%p\n", mw); + mw->size = 0; + } + } + } + else { + mwWrite("relink: partial, %ld MW-blocks of %ld bytes lost\n", + mwNmlNumAlloc+mwNumCurAlloc-count, mwNmlCurAlloc+mwStatCurAlloc-size ); + return 0; + } + + return 1; + } + +/* +** If mwData* is NULL: +** Returns 0 if heap chain is broken. +** Returns 1 if heap chain is intact. +** If mwData* is not NULL: +** Returns 0 if mwData* is missing or if chain is broken. +** Returns 1 if chain is intact and mwData* is found. +*/ +static int mwIsHeapOK( mwData *includes_mw ) { + int found = 0; + mwData *mw; + + for( mw = mwHead; mw; mw=mw->next ) { + if( includes_mw == mw ) found++; + if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0; + if( mw->prev ) { + if( !mwIsSafeAddr( mw->prev, mwDataSize ) ) return 0; + if( mw==mwHead || mw->prev->next != mw ) return 0; + } + if( mw->next ) { + if( !mwIsSafeAddr( mw->next, mwDataSize ) ) return 0; + if( mw==mwTail || mw->next->prev != mw ) return 0; + } + else if( mw!=mwTail ) return 0; + } + + if( includes_mw != NULL && !found ) return 0; + + return 1; + } + +static int mwIsOwned( mwData* mw, const char *file, int line ) { + int retv; + mwStat *ms; + + /* see if the address is legal according to OS */ + if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0; + + /* make sure we have _anything_ allocated */ + if( mwHead == NULL && mwTail == NULL && mwStatCurAlloc == 0 ) + return 0; + + /* calculate checksum */ + if( mw->check != CHKVAL(mw) ) { + /* may be damaged checksum, see if block is in heap */ + if( mwIsHeapOK( mw ) ) { + /* damaged checksum, repair it */ + mwWrite( "internal: <%ld> %s(%d), checksum for MW-%p is incorrect\n", + mwCounter, file, line, mw ); + mwIncErr(); + if( mwIsReadAddr( mw->file, 1 ) ) { + ms = mwStatGet( mw->file, -1, 0 ); + if( ms == NULL ) mw->file = ""; + } + else mw->file = ""; + mw->size = 0; + mw->check = CHKVAL(mw); + return 1; + } + /* no, it's just some garbage data */ + return 0; + } + + /* check that the non-NULL pointers are safe */ + if( mw->prev && !mwIsSafeAddr( mw->prev, mwDataSize ) ) mwRelink( mw, file, line ); + if( mw->next && !mwIsSafeAddr( mw->next, mwDataSize ) ) mwRelink( mw, file, line ); + + /* safe address, checksum OK, proceed with heap checks */ + + /* see if the block is in the heap */ + retv = 0; + if( mw->prev ) { if( mw->prev->next == mw ) retv ++; } + else { if( mwHead == mw ) retv++; } + if( mw->next ) { if( mw->next->prev == mw ) retv ++; } + else { if( mwTail == mw ) retv++; } + if( mw->check == CHKVAL(mw) ) retv ++; + if( retv > 2 ) return 1; + + /* block not in heap, check heap for corruption */ + + if( !mwIsHeapOK( mw ) ) { + if( mwRelink( mw, file, line ) ) + return 1; + } + + /* unable to repair */ + mwWrite( "internal: <%ld> %s(%d), mwIsOwned fails for MW-%p\n", + mwCounter, file, line, mw ); + mwIncErr(); + + return 0; + } + +/* +** mwTestBuf: +** Checks a buffers links and pre/postfixes. +** Writes errors found to the log. +** Returns zero if no errors found. +*/ +static int mwTestBuf( mwData* mw, const char* file, int line ) { + int retv = 0; + char *p; + + if( file == NULL ) file = "unknown"; + + if( !mwIsSafeAddr( mw, mwDataSize + mwOverflowZoneSize ) ) { + mwWrite( "internal: <%ld> %s(%d): pointer MW-%p is invalid\n", + mwCounter, file, line, mw ); + mwIncErr(); + return 2; + } + + if( mw->check != CHKVAL(mw) ) { + mwWrite( "internal: <%ld> %s(%d), info trashed; relinking\n", + mwCounter, file, line ); + mwIncErr(); + if( !mwRelink( mw, file, line ) ) return 2; + } + + if( mw->prev && mw->prev->next != mw ) { + mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link1 broken\n", + mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); + mwIncErr(); + if( !mwRelink( mw, file, line ) ) retv = 2; + } + if( mw->next && mw->next->prev != mw ) { + mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link2 broken\n", + mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); + mwIncErr(); + if( !mwRelink( mw, file, line ) ) retv = 2; + } + + p = ((char*)mw) + mwDataSize; + if( mwCheckOF( p ) ) { + mwWrite( "underflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n", + mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); + mwIncErr(); + retv = 1; + } + p += mwOverflowZoneSize + mw->size; + if( mwIsReadAddr( p, mwOverflowZoneSize ) && mwCheckOF( p ) ) { + mwWrite( "overflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n", + mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); + mwIncErr(); + retv = 1; + } + + return retv; + } + +static void mwDefaultOutFunc( int c ) { + if( mwLogR() ) fputc( c, mwLogR() ); + } + +static void mwWrite( const char *format, ... ) { + int tot, oflow = 0; + va_list mark; + mwAutoInit(); + if( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc; + va_start( mark, format ); + tot = vsprintf( mwPrintBuf, format, mark ); + va_end( mark ); + if( tot >= MW_TRACE_BUFFER ) { mwPrintBuf[MW_TRACE_BUFFER] = 0; oflow = 1; } + for(tot=0;mwPrintBuf[tot];tot++) + (*mwOutFunction)( mwPrintBuf[tot] ); + if( oflow ) { + mwWrite( "\ninternal: mwWrite(): WARNING! OUTPUT EXCEEDED %u CHARS: SYSTEM UNSTABLE\n", MW_TRACE_BUFFER-1 ); + FLUSH(); + } + return; + } + +static void mwLogFile( const char *name ) { + time_t tid; + (void) time( &tid ); + if( mwLogR() != NULL ) { + fclose( mwLogR() ); + mwLogW( NULL ); + } + if( name == NULL ) return; + mwLogW( fopen( name, "a" COMMIT ) ); + if( mwLogR() == NULL ) + mwWrite( "logfile: failed to open/create file '%s'\n", name ); + } + +/* +** Try to free NML memory until a contiguous allocation of +** 'needed' bytes can be satisfied. If this is not enough +** and the 'urgent' parameter is nonzero, grabbed memory is +** also freed. +*/ +static size_t mwFreeUp( size_t needed, int urgent ) { + void *p; + mwData *mw, *mw2; + char *data; + + /* free grabbed NML memory */ + for(;;) { + if( mwDrop_( 1, MW_VAL_NML, 1 ) == 0 ) break; + p = malloc( needed ); + if( p == NULL ) continue; + free( p ); + return needed; + } + + /* free normal NML memory */ + mw = mwHead; + while( mw != NULL ) { + if( !(mw->flag & MW_NML) ) mw = mw->next; + else { + data = ((char*)mw)+mwDataSize+mwOverflowZoneSize; + if( mwTestMem( data, mw->size, MW_VAL_NML ) ) { + mwIncErr(); + mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n", + mw->count, data + mwOverflowZoneSize, mw->file, mw->line ); + } + mw2 = mw->next; + mwUnlink( mw, "mwFreeUp", 0 ); + free( mw ); + mw = mw2; + p = malloc( needed ); + if( p == NULL ) continue; + free( p ); + return needed; + } + } + + /* if not urgent (for internal purposes), fail */ + if( !urgent ) return 0; + + /* free grabbed memory */ + for(;;) { + if( mwDrop_( 1, MW_VAL_GRB, 1 ) == 0 ) break; + p = malloc( needed ); + if( p == NULL ) continue; + free( p ); + return needed; + } + + return 0; + } + +static const void * mwTestMem( const void *p, unsigned len, int c ) { + const unsigned char *ptr; + ptr = (const unsigned char *) p; + while( len-- ) { + if( *ptr != (unsigned char)c ) return (const void*)ptr; + ptr ++; + } + return NULL; + } + +static int mwStrCmpI( const char *s1, const char *s2 ) { + if( s1 == NULL || s2 == NULL ) return 0; + while( *s1 ) { + if( toupper(*s2) == toupper(*s1) ) { s1++; s2++; continue; } + return 1; + } + return 0; + } + +#define AIPH() if( always_invoked ) { mwWrite("autocheck: <%ld> %s(%d) ", mwCounter, file, line ); always_invoked = 0; } + +static int mwTestNow( const char *file, int line, int always_invoked ) { + int retv = 0; + mwData *mw; + char *data; + + if( file && !always_invoked ) + mwWrite("check: <%ld> %s(%d), checking %s%s%s\n", + mwCounter, file, line, + (mwTestFlags & MW_TEST_CHAIN) ? "chain ": "", + (mwTestFlags & MW_TEST_ALLOC) ? "alloc ": "", + (mwTestFlags & MW_TEST_NML) ? "nomansland ": "" + ); + + if( mwTestFlags & MW_TEST_CHAIN ) { + for( mw = mwHead; mw; mw=mw->next ) { + if( !mwIsSafeAddr(mw, mwDataSize) ) { + AIPH(); + mwWrite("check: heap corruption detected\n"); + mwIncErr(); + return retv + 1; + } + if( mw->prev ) { + if( !mwIsSafeAddr(mw->prev, mwDataSize) ) { + AIPH(); + mwWrite("check: heap corruption detected\n"); + mwIncErr(); + return retv + 1; + } + if( mw==mwHead || mw->prev->next != mw ) { + AIPH(); + mwWrite("check: heap chain broken, prev link incorrect\n"); + mwIncErr(); + retv ++; + } + } + if( mw->next ) { + if( !mwIsSafeAddr(mw->next, mwDataSize) ) { + AIPH(); + mwWrite("check: heap corruption detected\n"); + mwIncErr(); + return retv + 1; + } + if( mw==mwTail || mw->next->prev != mw ) { + AIPH(); + mwWrite("check: heap chain broken, next link incorrect\n"); + mwIncErr(); + retv ++; + } + } + else if( mw!=mwTail ) { + AIPH(); + mwWrite("check: heap chain broken, tail incorrect\n"); + mwIncErr(); + retv ++; + } + } + } + if( mwTestFlags & MW_TEST_ALLOC ) { + for( mw = mwHead; mw; mw=mw->next ) { + if( mwTestBuf( mw, file, line ) ) retv ++; + } + } + if( mwTestFlags & MW_TEST_NML ) { + for( mw = mwHead; mw; mw=mw->next ) { + if( (mw->flag & MW_NML) ) { + data = ((char*)mw)+mwDataSize+mwOverflowZoneSize; + if( mwTestMem( data, mw->size, MW_VAL_NML ) ) { + mwIncErr(); + mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n", + mw->count, data + mwOverflowZoneSize, mw->file, mw->line ); + } + } + } + } + + + if( file && !always_invoked && !retv ) + mwWrite("check: <%ld> %s(%d), complete; no errors\n", + mwCounter, file, line ); + return retv; + } + +/********************************************************************** +** Statistics +**********************************************************************/ + +static void mwStatReport() +{ + mwStat* ms, *ms2; + const char *modname; + int modnamelen; + + /* global statistics report */ + mwWrite( "\nMemory usage statistics (global):\n" ); + mwWrite( " N)umber of allocations made: %ld\n", mwStatNumAlloc ); + mwWrite( " L)argest memory usage : %ld\n", mwStatMaxAlloc ); + mwWrite( " T)otal of all alloc() calls: %ld\n", mwStatTotAlloc ); + mwWrite( " U)nfreed bytes totals : %ld\n", mwStatCurAlloc ); + FLUSH(); + + if( mwStatLevel < 1 ) return; + + /* on a per-module basis */ + mwWrite( "\nMemory usage statistics (detailed):\n"); + mwWrite( " Module/Line Number Largest Total Unfreed \n"); + for( ms=mwStatList; ms; ms=ms->next ) + { + if( ms->line == -1 ) + { + if( ms->file == NULL || !mwIsReadAddr(ms->file,22) ) modname = ""; + else modname = ms->file; + modnamelen = strlen(modname); + if( modnamelen > 42 ) + { + modname = modname + modnamelen - 42; + } + + mwWrite(" %-42s %-8ld %-8ld %-8ld %-8ld\n", + modname, ms->num, ms->max, ms->total, ms->curr ); + if( ms->file && mwStatLevel > 1 ) + { + for( ms2=mwStatList; ms2; ms2=ms2->next ) + { + if( ms2->line!=-1 && ms2->file!=NULL && !mwStrCmpI( ms2->file, ms->file ) ) + { + mwWrite( " %-8d %-8ld %-8ld %-8ld %-8ld\n", + ms2->line, ms2->num, ms2->max, ms2->total, ms2->curr ); + } + } + } + } + } +} + +static mwStat* mwStatGet( const char *file, int line, int makenew ) { + mwStat* ms; + + if( mwStatLevel < 2 ) line = -1; + + for( ms=mwStatList; ms!=NULL; ms=ms->next ) { + if( line != ms->line ) continue; + if( file==NULL ) { + if( ms->file == NULL ) break; + continue; + } + if( ms->file == NULL ) continue; + if( !strcmp( ms->file, file ) ) break; + } + + if( ms != NULL ) return ms; + + if( !makenew ) return NULL; + + ms = (mwStat*) malloc( sizeof(mwStat) ); + if( ms == NULL ) { + if( mwFreeUp( sizeof(mwStat), 0 ) < sizeof(mwStat) || + (ms=(mwStat*)malloc(sizeof(mwStat))) == NULL ) { + mwWrite("internal: memory low, statistics incomplete for '%s'\n", file ); + return NULL; + } + } + ms->file = file; + ms->line = line; + ms->total = 0L; + ms->max = 0L; + ms->num = 0L; + ms->curr = 0L; + ms->next = mwStatList; + mwStatList = ms; + return ms; + } + +static void mwStatAlloc( size_t size, const char* file, int line ) { + mwStat* ms; + + /* update the module statistics */ + ms = mwStatGet( file, -1, 1 ); + if( ms != NULL ) { + ms->total += (long) size; + ms->curr += (long) size; + ms->num ++; + if( ms->curr > ms->max ) ms->max = ms->curr; + } + + /* update the line statistics */ + if( mwStatLevel > 1 && line != -1 && file ) { + ms = mwStatGet( file, line, 1 ); + if( ms != NULL ) { + ms->total += (long) size; + ms->curr += (long) size; + ms->num ++; + if( ms->curr > ms->max ) ms->max = ms->curr; + } + } + + } + +static void mwStatFree( size_t size, const char* file, int line ) { + mwStat* ms; + + /* update the module statistics */ + ms = mwStatGet( file, -1, 1 ); + if( ms != NULL ) ms->curr -= (long) size; + + /* update the line statistics */ + if( mwStatLevel > 1 && line != -1 && file ) { + ms = mwStatGet( file, line, 1 ); + if( ms != NULL ) ms->curr -= (long) size; + } + } + +/*********************************************************************** +** Safe memory checkers +** +** Using ifdefs, implement the operating-system specific mechanism +** of identifying a piece of memory as legal to access with read +** and write priviliges. Default: return nonzero for non-NULL pointers. +***********************************************************************/ + +static char mwDummy( char c ) +{ + return c; +} + +#ifndef MW_SAFEADDR +#ifdef WIN32 +#define MW_SAFEADDR +#define WIN32_LEAN_AND_MEAN +#include +int mwIsReadAddr( const void *p, unsigned len ) +{ + if( p == NULL ) return 0; + if( IsBadReadPtr(p,len) ) return 0; + return 1; +} +int mwIsSafeAddr( void *p, unsigned len ) +{ + /* NOTE: For some reason, under Win95 the IsBad... */ + /* can return false for invalid pointers. */ + if( p == NULL ) return 0; + if( IsBadReadPtr(p,len) || IsBadWritePtr(p,len) ) return 0; + return 1; +} +#endif /* WIN32 */ +#endif /* MW_SAFEADDR */ + +#ifndef MW_SAFEADDR +#ifdef SIGSEGV +#define MW_SAFEADDR + +typedef void (*mwSignalHandlerPtr)( int ); +mwSignalHandlerPtr mwOldSIGSEGV = (mwSignalHandlerPtr) 0; +jmp_buf mwSIGSEGVjump; +static void mwSIGSEGV( int n ); + +static void mwSIGSEGV( int n ) +{ + n = n; + longjmp( mwSIGSEGVjump, 1 ); +} + +int mwIsReadAddr( const void *p, unsigned len ) +{ + const char *ptr; + + if( p == NULL ) return 0; + if( !len ) return 1; + + /* set up to catch the SIGSEGV signal */ + mwOldSIGSEGV = signal( SIGSEGV, mwSIGSEGV ); + + if( setjmp( mwSIGSEGVjump ) ) + { + signal( SIGSEGV, mwOldSIGSEGV ); + return 0; + } + + /* read all the bytes in the range */ + ptr = (const char *)p; + ptr += len; + + /* the reason for this rather strange construct is that */ + /* we want to keep the number of used parameters and locals */ + /* to a minimum. if we use len for a counter gcc will complain */ + /* it may get clobbered by longjmp() at high warning levels. */ + /* it's a harmless warning, but this way we don't have to see it. */ + do + { + ptr --; + if( *ptr == 0x7C ) (void) mwDummy( (char)0 ); + } while( (const void*) ptr != p ); + + /* remove the handler */ + signal( SIGSEGV, mwOldSIGSEGV ); + + return 1; +} +int mwIsSafeAddr( void *p, unsigned len ) +{ + char *ptr; + + if( p == NULL ) return 0; + if( !len ) return 1; + + /* set up to catch the SIGSEGV signal */ + mwOldSIGSEGV = signal( SIGSEGV, mwSIGSEGV ); + + if( setjmp( mwSIGSEGVjump ) ) + { + signal( SIGSEGV, mwOldSIGSEGV ); + return 0; + } + + /* read and write-back all the bytes in the range */ + ptr = (char *)p; + ptr += len; + + /* the reason for this rather strange construct is that */ + /* we want to keep the number of used parameters and locals */ + /* to a minimum. if we use len for a counter gcc will complain */ + /* it may get clobbered by longjmp() at high warning levels. */ + /* it's a harmless warning, but this way we don't have to see it. */ + do + { + ptr --; + *ptr = mwDummy( *ptr ); + } while( (void*) ptr != p ); + + /* remove the handler */ + signal( SIGSEGV, mwOldSIGSEGV ); + + return 1; +} +#endif /* SIGSEGV */ +#endif /* MW_SAFEADDR */ + +#ifndef MW_SAFEADDR +int mwIsReadAddr( const void *p, unsigned len ) +{ + if( p == NULL ) return 0; + if( len == 0 ) return 1; + return 1; +} +int mwIsSafeAddr( void *p, unsigned len ) +{ + if( p == NULL ) return 0; + if( len == 0 ) return 1; + return 1; +} +#endif + +/********************************************************************** +** Mutex handling +**********************************************************************/ + +#if defined(WIN32) || defined(__WIN32__) + +static void mwMutexInit( void ) +{ + mwGlobalMutex = CreateMutex( NULL, FALSE, NULL); + return; +} + +static void mwMutexTerm( void ) +{ + CloseHandle( mwGlobalMutex ); + return; +} + +static void mwMutexLock( void ) +{ + if( WaitForSingleObject(mwGlobalMutex, 1000 ) == WAIT_TIMEOUT ) + { + mwWrite( "mwMutexLock: timed out, possible deadlock\n" ); + } + return; +} + +static void mwMutexUnlock( void ) +{ + ReleaseMutex( mwGlobalMutex ); + return; +} + +#endif + +#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H) + +static void mwMutexInit( void ) +{ + pthread_mutex_init( &mwGlobalMutex, NULL ); + return; +} + +static void mwMutexTerm( void ) +{ + pthread_mutex_destroy( &mwGlobalMutex ); + return; +} + +static void mwMutexLock( void ) +{ + pthread_mutex_lock(&mwGlobalMutex); + return; +} + +static void mwMutexUnlock( void ) +{ + pthread_mutex_unlock(&mwGlobalMutex); + return; +} + +#endif + +/********************************************************************** +** C++ new & delete +**********************************************************************/ + +#if 0 /* 980317: disabled C++ */ + +#ifdef __cplusplus +#ifndef MEMWATCH_NOCPP + +int mwNCur = 0; +const char *mwNFile = NULL; +int mwNLine = 0; + +class MemWatch { +public: + MemWatch(); + ~MemWatch(); + }; + +MemWatch::MemWatch() { + if( mwInited ) return; + mwUseAtexit = 0; + mwInit(); + } + +MemWatch::~MemWatch() { + if( mwUseAtexit ) return; + mwTerm(); + } + +/* +** This global new will catch all 'new' calls where MEMWATCH is +** not active. +*/ +void* operator new( unsigned size ) { + mwNCur = 0; + return mwMalloc( size, "", 0 ); + } + +/* +** This is the new operator that's called when a module uses mwNew. +*/ +void* operator new( unsigned size, const char *file, int line ) { + mwNCur = 0; + return mwMalloc( size, file, line ); + } + +/* +** This is the new operator that's called when a module uses mwNew[]. +** -- hjc 07/16/02 +*/ +void* operator new[] ( unsigned size, const char *file, int line ) { + mwNCur = 0; + return mwMalloc( size, file, line ); + } + +/* +** Since this delete operator will recieve ALL delete's +** even those from within libraries, we must accept +** delete's before we've been initialized. Nor can we +** reliably check for wild free's if the mwNCur variable +** is not set. +*/ +void operator delete( void *p ) { + if( p == NULL ) return; + if( !mwInited ) { + free( p ); + return; + } + if( mwNCur ) { + mwFree( p, mwNFile, mwNLine ); + mwNCur = 0; + return; + } + mwFree_( p ); + } + +void operator delete[]( void *p ) { + if( p == NULL ) return; + if( !mwInited ) { + free( p ); + return; + } + if( mwNCur ) { + mwFree( p, mwNFile, mwNLine ); + mwNCur = 0; + return; + } + mwFree_( p ); + } + +#endif /* MEMWATCH_NOCPP */ +#endif /* __cplusplus */ + +#endif /* 980317: disabled C++ */ + +/* MEMWATCH.C */ + +/*@end@*/ + diff --git a/plat/public/src/pub_conf.c b/plat/public/src/pub_conf.c new file mode 100644 index 0000000..be05541 --- /dev/null +++ b/plat/public/src/pub_conf.c @@ -0,0 +1,12 @@ +////////////////////////////////////////////////// +//Title : pub_conf.c +//Auhtor : Liu Wei +//Desc : public conf file handle inplementation +//Created : 2007-06-04 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + + diff --git a/plat/public/src/pub_debug.c b/plat/public/src/pub_debug.c new file mode 100644 index 0000000..6ead802 --- /dev/null +++ b/plat/public/src/pub_debug.c @@ -0,0 +1,52 @@ +////////////////////////////////////////////////// +//Title : wxc_debug.c +//Auhtor : Liu Wei +//Desc : wxc debug api implemetation +//Created : 2007-05-01 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// +#include +#include "./include/pub_debug.h" + +/*@ignore@*/ + +void WxcDump( int nSigno ) +{ + char buf[1024]; + char cmd[1024]; + FILE *fh; + + snprintf ( buf, sizeof ( buf ), "/proc/%d/cmdline", getpid ( ) ); + fh = fopen ( buf, "r" ); + if ( fh == NULL ) + exit ( 0 ); + if ( NULL == (fgets ( buf, sizeof ( buf ), fh ) )) + exit ( 0 ); + fclose ( fh ); + if ( buf[strlen ( buf ) - 1] == '\n' ) + buf[strlen ( buf ) - 1] = '\0'; + snprintf ( cmd, sizeof ( cmd ), "gdb %s %d", buf, getpid ( ) ); + system ( cmd ); + + exit ( 0 ); +} + +void WxcBackTrace( ) +{ + int i; + void *array[25]; + int nSize = backtrace ( array, 25 ); + char **symbols = backtrace_symbols ( array, nSize ); + + for ( i = 0; i < nSize; i++ ) + { + printf ( "%s \n", symbols[i] ); + } + free ( symbols ); +} + +/*@end@*/ + diff --git a/plat/public/src/pub_file.c b/plat/public/src/pub_file.c new file mode 100644 index 0000000..e258324 --- /dev/null +++ b/plat/public/src/pub_file.c @@ -0,0 +1,44 @@ +////////////////////////////////////////////////// +//Title : wxc_file.c +//Auhtor : Liu Wei +//Desc : wxc file handle inplementation +//Created : 2007-06-04 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_file.h" + +/*@ignore@*/ + +/////////////////////////////////////////////////////////////////////////// +// GetOneLine: Read one line of a file +/////////////////////////////////////////////////////////////////////////// + +extern char *GetOneLine ( char *pFileName ) +{ + FILE *pFile; + static char sBuff[1024]; + char *pCh; + + pFile = fopen ( pFileName, "r" ); + if ( pFile != NULL ) + { + if ( fgets ( sBuff, sizeof ( sBuff ), pFile ) != NULL ) + { + if ( NULL != (pCh = strchr ( sBuff, '\n' )) ) + { + *pCh = CNULL; + } + return sBuff; + } + ( void ) fclose ( pFile ); + } + + return ( char * ) NULL; +} + + +/*@end@*/ diff --git a/plat/public/src/pub_fmt.c b/plat/public/src/pub_fmt.c new file mode 100644 index 0000000..8b9f892 --- /dev/null +++ b/plat/public/src/pub_fmt.c @@ -0,0 +1,1264 @@ +////////////////////////////////////////////////// +//Title : pub_convert.c +//Auhtor : Liu Wei +//Desc : public format type convert inplementation +//Created : 2007-06-24 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// lCRD software network data type assumpsit +// +// Memery Low <<============[Little Endian]===========>> Memery High +// Type abbr. e.g. Remark +// const value CVal U32 dVal= 0x12345678 +// Host BCD HBcd/Bcd 0x78 0x56 0x34 0x12 +// Anti BCD ABcd 0x87 0x65 0x43 0x21 +// NetBCD NBcd 0x12 0x34 0x56 0x78 +// String Str 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 "12345678" +// U64 U64 0x4E 0x61 0xBC 0x00 0x00 0x00 0x00 0x00 12345678=0xBC614E +// Digit Dig 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 +// +//////////////////////////////////////////////////////////////////////////////// + +/** @defgroup format pub_fmt.c + ** @{ + **/ + +#include "./include/pub_fmt.h" + +/////////////////////////////////////////////////////////////////////////// +// For test +// +/////////////////////////////////////////////////////////////////////////// +/* +//define in pub_base.h +#define u8 unsigned char +#define u64 unsigned long long +#define CNULL '\0' + +#define BitSet(arg,posn) ((arg) | (1L << (posn))) +#define BitClr(arg,posn) ((arg) & ~(1L << (posn))) +#define BitFlp(arg,posn) ((arg) ^ (1L << (posn))) +#define BitTst(arg,posn) (!(!((arg) & (1L << (posn))))) + +//define in pub_debug.h +#define WxcAssert +*/ + +/** + ** @note HexToCh : 0 - > '0' + ** + **/ +char HexToCh( u8 uHex ) +{ + return ( (uHex) + ( ((uHex) > 9)? 'A'-10 : '0') ); +} + +/** + ** @note ChToHex : '0' - > 0 + ** + **/ +u8 ChToHex( char ch) +{ + static char digits[] = "0123456789abcdef"; + u8 uRel = 0; + int s; + + for(s = 0; s < 16; ++s) + { + if( digits[s] == tolower(ch) ) + { + uRel = s; + return(uRel); + } + } + + return(uRel); +} + + +/** + ** @note ReverseByte : 0010 1010 =>> 0101 0100 + ** + **/ +u8 ReverseByte(u8 uByteIn ) +{ + u8 i ; + u8 uByteOut = 0; + + for( i = 0 ; i < 8 ; i ++ ) + { + if( BitTst( uByteIn , i ) ) + { + uByteOut = (u8) ( BitSet( uByteOut , 7-i ) ); + } + } + + return uByteOut; +} + +/** + ** @note ReverseBCD : 0x12 0x34 0x56 0x78 =>> 0x21 0x43 0x65 0x87 + ** + **/ +void ReverseBCD( u8 *pDst , const u8 *pSrc , int nBcdLen ) +{ + int i; + + for( i = 0 ; i < nBcdLen ; i ++ ) + { + pDst[i] = (pSrc[i] >> 4) + (pSrc[i] << 4) ; + } +} + +/** + ** ReverseArray : 0x12 0x34 0x56 0x78 =>> 0x78 0x56 0x34 0x12 + ** + **/ +void ReverseArray( u8 *pDst , const u8 *pSrc , int nBcdLen ) +{ + int i; + + for( i = 0 ; i < nBcdLen ; i ++ ) + { + pDst[i] = pSrc[nBcdLen-i-1]; + } +} + +/** + ** @note BcdToStr : 0x12 0x34 0x56 0x78 =>> "12345678" + ** + **/ +void BcdToStr( char *pStr , const u8 *pBcd , int nBcdLen ) +{ + int i , j ; + int nStrLen = nBcdLen * 2 + 1; + + memset( pStr , 0 , nStrLen ); + + j = 0; + for( i = 0 ; i < nBcdLen ; i ++ ) + { + pStr[j++] = HexToCh(pBcd[i] >> 4 ); + pStr[j++] = HexToCh(pBcd[i] & 0x0F); + } + pStr[j] = CNULL; +} + +/** + ** @note BcdToU64 : 0x12 0x34 0x56 0x78 =>> 12345678 + ** + **/ +u64 BcdToU64( const u8 *pBcd , int nBcdLen ) +{ + u64 llResult = 0; + u64 llMulti = 1; + int i; + + for( i = nBcdLen*2 -1 ; i >= 0 ; i -- ) + { + u8 uByte = pBcd[i/2] >> (4*((i+1)%2)); + + llResult += ( uByte & 0x0F ) * llMulti; + llMulti *= 10; + } + + return llResult; +} + +/** + ** @note BcdToDig : 0x12 0x34 0x56 =>>0x01 0x02 0x03 0x04 0x05 0x06 + ** + **/ +int BcdToDig( u8 *pDig , int nDigBuffLen, u8 *pBcd , int nBcdLen ) +{ + int i , j ; + + i = j = 0; + if( nDigBuffLen < 2*nBcdLen ) + { + return 0; + } + for( i = 0 ; i > 4 ; + pDig[j++] = pBcd[i] & 0x0F; + } + return j; +} + +/** + ** @note StrToBcd : "123456" =>> 0x12 0x34 0x56 + ** + **/ +int StrToBcd( u8 *pBcd , char *pStr , int nBcdBuffLen ) +{ + int i , j , k; + int nLen = strlen(pStr); + + i = j = k = 0; + j = (nLen + nLen%2) /2; + if( nBcdBuffLen < j ) + { + return 0; + } + memset( pBcd , 0 , j); + for( i = 0 ; i 0x01 0x23 0x45 0x67 + ** + **/ +int U64ToBcd( u8 *pBcd ,u64 llInput , int nBcdBuffLen ) +{ + u64 llDiv = 10; + int nDigNum = 1; + int nBcdLen = 0; + int i; + + while( llDiv < llInput ) + { + nDigNum++; + llDiv *= 10; + } + llDiv = ( nDigNum % 2 ) ? llDiv : llDiv/10; + + nDigNum += nDigNum % 2; + nBcdLen = nDigNum/2; + if( nBcdBuffLen < nBcdLen ) + { + return 0; + } + memset(pBcd , 0 , nBcdLen ); + for(i = 0; i < nBcdLen; i++) + { + pBcd[i] |= (((llInput / llDiv) %10) << 4); + llDiv /= 10; + pBcd[i] |= ((llInput / llDiv) % 10) ; + llDiv /= 10; + } + + return nBcdLen; +} + +/** + ** @note DigToBcd : 0x01 0x02 0x03 x04 0x05 0x06 0x07 => 0x01 0x23 0x45 0x67 + ** + **/ +int DigToBcd( u8* pBcd , int nBcdBuffLen , u8 *pDig , int nDigLen ) +{ + //u64 llDiv = 10; + //int nDigNum = 1; + int nBcdLen = (nDigLen + nDigLen %2)/2; + int i , j; + + j=0; + if( nBcdLen > nBcdBuffLen ) + { + return 0; + } + memset( pBcd , 0 , nBcdLen ); + + for(i = 0; i < nBcdLen; i++) + { + if( nDigLen %2 && !i ) + { + pBcd[i] &= 0x0F; + } + else + { + pBcd[i] |= pDig[j++] <<4; + } + pBcd[i] |= pDig[j++] & 0x0F; + } + return nBcdLen; +} + +/** + ** @note DigToBcd : 0x08 0x06 0x07 x05 0x05 0x00 0x01 => 0x86 0x75 0x50 0x1E + ** + **/ +int DigToBcdE( u8* pBcd , int nBcdBuffLen , u8 *pDig , int nDigLen , int nEnd ) +{ + //u64 llDiv = 10; + //int nDigNum = 1; + int nBcdLen = (nDigLen + nDigLen %2)/2; + int i , j; + + j=0; + WxcAssert( nEnd <= 0x0F ,"DigToBcdE end code > 0x0F" ); + if( nBcdLen > nBcdBuffLen ) + { + WxcAssert( 0 , "DigToBcdE buffer overflow!"); + return 0; + } + memset( pBcd , 0 , nBcdLen ); + + for(i = 0; i < nBcdLen; i++) + { + pBcd[i] |= pDig[j++] <<4; + if( nDigLen %2 && i == (nBcdLen-1) ) + { + pBcd[i] |= nEnd; + } + else + { + pBcd[i] |= pDig[j++] & 0x0F; + } + + } + return nBcdLen; +} + +void _______________un_fmt______________() +{ + +} + +/* ++++++++++++++++++++++++++++++++++++++ */ +/* transfer ascii code to bcd code */ +/* ++++++++++++++++++++++++++++++++++++++ */ +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + char flag=0; + + if (ascii_buf == NULL) + { + for (i=0;i='a') + ch -= 'a' - 10; + else if (ch>='A') + ch -= 'A' - 10; + else + ch -= '0'; + if (flag) + { + if (i & 1) + *bcd_buf = ch << 4; + else + *(bcd_buf++) |= ch & 0x0f; + } + else + { + if (i & 1) + *(bcd_buf++) |= ch & 0x0f; + else + *bcd_buf = ch << 4; + } + } +} + +/* ++++++++++++++++++++++++++++++++++++++ */ +/* transfer bcd code to ascii code */ +/* ++++++++++++++++++++++++++++++++++++++ */ +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + if (bcd_buf == NULL) + { + for (i=0;i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} + +int Str2Bcd ( BYTE * pBcd, char *pStr, int maxLen ) +{ + int iBcd = 0, iStr = 0, len; + BYTE flag = 0; + char val[3]; + + len = strlen ( pStr ); + val[1] = val[2] = 0; + strcat ( pStr, "F" ); + len++; + do + { + if( !isxdigit ( pStr[iStr] ) ) + continue; + + val[flag] = pStr[iStr]; + if( flag ) + { + pBcd[iBcd++] = strtoul ( val, NULL, 16 ); + } + flag = flag ? 0 : 1; + } + while ( iBcd < maxLen && ++iStr < len ); + + memset ( pBcd + iBcd, 0xFF, maxLen - iBcd ); + return iBcd; +} + +int Bcd2Str ( char *pStr, const BYTE * pBcd, int len ) +{ + int i; + + for ( i = 0; i < len; i++ ) + sprintf ( pStr + 2 * i, "%02X", pBcd[i] ); + + pStr[2 * len] = 0; + return len; +} + +int DigitsLen ( BYTE * pDigits, int maxLen ) +{ + int i = 0; + + for ( i = 0; i < maxLen; i++ ) + { + if( ( pDigits[i] & 0x0F ) > 0x0A ) + return 2 * i; + if( ( pDigits[i] & 0xF0 ) > 0xA0 ) + return 2 * i + 1; + } + return maxLen * 2; +} + +int BcdLen ( BYTE * pBcd, int maxLen ) +{ + int i = 0; + + for ( i = 0; i < maxLen; i++ ) + { + if( ( pBcd[i] & 0xF0 ) > 0xA0 ) + return 2 * i; + if( ( pBcd[i] & 0x0F ) > 0x0A ) + return 2 * i + 1; + } + return maxLen * 2; +} + +int Digits2Str ( char *pStr, BYTE * pDigits, int DigitsLen ) +{ + int i = 0; + char low = '0', high = '0'; + + for ( i = 0; i < DigitsLen; i++ ) + { + low = pDigits[i] & 0xF; + if( low < 0x0A ) + { + pStr[2 * i] = low + '0'; + } + else if( low < 0x0E ) + { + pStr[2 * i] = low + 'A' - 10; + } + else + { + pStr[2 * i] = 0; + break; + } + + high = ( pDigits[i] >> 4 ); + if( high < 0x0A ) + { + pStr[2 * i + 1] = high + '0'; + } + else if( high < 0x0E ) + { + pStr[2 * i + 1] = high + 'A' - 10; + } + else + { + pStr[2 * i + 1] = 0; + break; + } + } + pStr[2 * DigitsLen] = '\0'; + return 1; +} + +ull Digits2Ull ( BYTE * pDigits, int DigitsLen ) +{ + ull result = 0; + int i; + BYTE digit; + + if( DigitsLen > 9 ) + DigitsLen = 9; + + for ( i = 0; i < DigitsLen; i++ ) + { + digit = pDigits[i] & 0x0F; + if( digit > 9 ) + return result; + result = result * 10 + digit; + + digit = pDigits[i] >> 4; + if( digit > 9 ) + return result; + result = result * 10 + digit; + } + return result; +} + +//only called by VLR to change IMSI to digits +int Ull2Digits ( BYTE * pDigits, ull value, int DigitsLen ) +{ + char tempStr[64]; + + if((value < 100000000000000LL) && (DigitsLen < 16))//IMSI pad 15 digits + { + sprintf ( tempStr, "%015lld", value ); + } + else + { + sprintf ( tempStr, "%lld", value ); + } + return Str2Digits ( pDigits, tempStr, DigitsLen ); +} + +int Str2Digits ( BYTE * pDigits, char *pStr, int DigitsLen ) +{ + int i = 0, strLen = strlen ( pStr ), len = 0; + char valstr[3]; + + len = strLen / 2; + if( len * 2 < strLen ) + { + strcat ( pStr, "F" ); + len++; + } + if( len > DigitsLen ) + len = DigitsLen; + + valstr[2] = 0; + for ( i = 0; i < len; i++ ) + { + valstr[0] = pStr[2 * i + 1]; + valstr[1] = pStr[2 * i]; + pDigits[i] = strtol ( valstr, NULL, 16 ); + } + return len; +} + +int Ull2Digits_Ralign ( BYTE * pDigits, ull value, int DigitsLen ) //right align +{ + char tempStr[64]; + char printStr[64]; + + sprintf ( printStr, "%%0%dlld", DigitsLen ); + sprintf ( tempStr, printStr, value ); + return Str2Digits ( pDigits, tempStr, ( DigitsLen + 1 ) / 2 ); +} + +ull Bcd2Ull ( BYTE * pBcd, int BcdLen ) +{ + ull result = 0; + int i; + BYTE digit; + + if( BcdLen > 9 ) + BcdLen = 9; + for ( i = 0; i < BcdLen; i++ ) + { + digit = pBcd[i] >> 4; + if( digit > 9 ) + return result; + result = result * 10 + digit; + + digit = pBcd[i] & 0x0F; + if( digit > 9 ) + return result; + result = result * 10 + digit; + } + return result; +} + +int Ull2Bcd ( BYTE * pBcd, ull value, int BcdLen ) +{ + char tempStr[64]; + + sprintf ( tempStr, "%lld", value ); + return Str2Bcd ( pBcd, tempStr, BcdLen ); +} + +int Digits2Bcd ( BYTE * pBcd, BYTE * pDigits, int maxLen ) +//return length +{ + int i = 0; + + for ( i = 0; i < maxLen; i++ ) + { + if( ( pDigits[i] & 0x0F ) > 0x0C ) + return i; + + pBcd[i] = ( pDigits[i] << 4 ) | ( pDigits[i] >> 4 ); + + if( ( pDigits[i] & 0xF0 ) > 0xC0 ) + return i + 1; + + } + return maxLen; +} + +int Bcd2Digits ( BYTE * pDigits, BYTE * pBcd, int maxLen ) +{ + int i = 0; + + for ( i = 0; i < maxLen; i++ ) + { + if( ( pBcd[i] & 0xF0 ) > 0xC0 ) + return i; + + pDigits[i] = ( pBcd[i] << 4 ) | ( pBcd[i] >> 4 ); + + if( ( pBcd[i] & 0x0F ) > 0x0C ) + return i + 1; + } + return maxLen; +} + +int Bcd2Digits_dLen ( BYTE * pDigits, BYTE * pBcd, int maxLen ) //return digits len +{ + int i = 0; + + for ( i = 0; i < maxLen; i++ ) + { + if( ( pBcd[i] & 0xF0 ) > 0xC0 ) + return i * 2; + + pDigits[i] = ( pBcd[i] << 4 ) | ( pBcd[i] >> 4 ); + + if( ( pBcd[i] & 0x0F ) > 0x0C ) + return i * 2 + 1; + } + return maxLen * 2; +} + +int Str2Oid ( DWORD * pOid, char *pStr, BYTE maxLen ) +{ + BYTE sub = 0; + short len, i; + char *pvar; + + len = strlen ( pStr ); + pvar = pStr; + for ( i = 0; i < len && sub < maxLen; i++ ) + { + if( pStr[i] == '.' ) + { + pStr[i] = '\0'; + if( strlen ( pvar ) == 0 ) + continue; + pOid[sub++] = atoi ( pvar ); + pvar = pStr + i + 1; + } + } + if( strlen ( pvar ) == 0 ) + return sub; + pOid[sub++] = atoi ( pvar ); + return sub; +} + +//string===> +int TrimLeft ( char *pStr ) +{ + int i = 0; + + while ( ( pStr[i] == ' ' || pStr[i] == '\t' ) && i < 16 ) + i++; + + strcpy ( pStr, pStr + i ); + return 1; +} + +int TrimRight ( char *pStr ) +{ + int len = strlen ( pStr ); + + if( len > 1024 ) + return 0; + + while ( pStr[len - 1] == ' ' || pStr[len - 1] == '\t' ) + { + pStr[len - 1] = 0; + len--; + } + return 1; +} + +int Array2Digits ( BYTE * pDigits, BYTE * pArray, int ArrayLen ) +{ + int i; + + pArray[ArrayLen] = 0xEE; + for ( i = 0; i < ( ArrayLen + 1 ) / 2; i++ ) + pDigits[i] = ( pArray[2 * i + 1] << 4 ) | ( pArray[2 * i] & 0x0F ); + + return i; +} + +ull Str2Ull ( char *pStr ) +{ + ull result, intHigh, intLow; + u_char len; + char strHigh[16] = "\0", *strLow; + + len = strlen ( pStr ); + if( len > 18 ) + return 0xFFFFFFFFFFFFFFFFll; + if( len > 9 ) + { + strLow = pStr + ( len - 9 ); + intLow = strtoul ( strLow, NULL, 10 ); + + strncpy ( strHigh, pStr, len - 9 ); + intHigh = strtoul ( strHigh, NULL, 10 ); + result = intHigh * 1000000000 + intLow; + return result; + } + else + { + intLow = strtoul ( pStr, NULL, 10 ); + return intLow; + } +} + +int Digits2Array ( BYTE * pArray, BYTE * pDigits, int DigitsLen ) +{ + int i, len = 0; + + for ( i = 0; i < DigitsLen; i++ ) + { + pArray[len] = pDigits[i] & 0x0F; + if( pArray[len] > 13 ) + return len; + len++; + + pArray[len] = pDigits[i] >> 4; + if( pArray[len] > 13 ) + return len; + len++; + } + + return len; +} + +int Bcd2Array ( BYTE * pArray, BYTE * pBcd, int BcdLen ) +{ + int i, len = 0; + + for ( i = 0; i < BcdLen; i++ ) + { + pArray[len] = pBcd[i] >> 4; + if( pArray[len] > 13 ) + return len; + len++; + + pArray[len] = pBcd[i] & 0x0F; + if( pArray[len] > 13 ) + return len; + len++; + } + + return len; +} + +int Str2Array ( BYTE * pArray, char *str, int ArrayLen ) +{ + int i, len; + char mystr[2]; + + mystr[1] = '\0'; + len = strlen ( str ); + if( len > ArrayLen ) + len = ArrayLen; + + for ( i = 0; i < len; i++ ) + { + mystr[0] = str[i]; + if( !isxdigit ( mystr[0] ) ) + return i; + pArray[i] = ( BYTE ) strtol ( mystr, NULL, 16 ); + } + return len; +} + +BYTE EditDigits ( BYTE * digits_out, BYTE len_max, BYTE * digits_in, BYTE len_in, BYTE len_del, BYTE * digits_ins, BYTE len_ins, BYTE filler ) +{ + BYTE len = 0, tmpbuf[64], pos1 = 0, pos2 = 0; + + if( len_ins > len_max ) //invalid insert length + { + memcpy ( digits_out, digits_in, ( len_in + 1 ) / 2 ); + return len_in; + } + else if( len_ins > 0 ) + { + memcpy ( digits_out, digits_ins, ( len_ins + 1 ) / 2 ); + len += len_ins; + } + + if( len_del > len_in ) //invalid delete length + { + memcpy ( digits_out, digits_in, ( len_in + 1 ) / 2 ); + return len_in; + } + else if( len_del == len_in ) + { + return len; + } + + if( ( len & 0x01 ) == ( len_del & 0x01 ) ) + { + if( len & 0x01 ) //odd + { + len_del++; + len_ins++; + pos1 = ( len + 1 ) / 2; + pos2 = ( len_del + 1 ) / 2; + digits_out[pos1 - 1] = ( digits_out[pos1 - 1] & 0x0F ) | ( digits_in[pos2 - 1] & 0xF0 ); + memcpy ( &digits_out[pos1], &digits_in[pos2], ( len_in - len_del + 1 ) / 2 ); + } + else //even + { + pos1 = len / 2; + pos2 = len_del / 2; + memcpy ( &digits_out[pos1], &digits_in[pos2], ( len_in - len_del + 1 ) / 2 ); + } + + /* daniel added this on 2006-04-18 */ + if( ( len_in + len_ins - len_del ) & 0x01 ) //odd + { + pos1 = ( len_in + len_ins - len_del + 1 ) / 2 - 1; + digits_out[pos1] &= 0x0f; + digits_out[pos1] |= ( filler & 0xf0 ); + } + else + { //even + //will not fill the filler + } + return len_in + len_ins - len_del; + /* daniel added this on 2006-04-18 */ + + } + else + { + Digits2Array ( tmpbuf, digits_in, ( len_in + 1 ) / 2 ); + if( len & 0x01 ) + { + pos1 = ( len + 1 ) / 2; + digits_out[pos1 - 1] = ( digits_out[pos1 - 1] & 0x0F ) | ( tmpbuf[len_del] << 4 ); + len_del++; + len_ins++; + } + else + pos1 = len / 2; //victor 2004-10 + tmpbuf[len_in] = filler >> 4; + Array2Digits ( digits_out + pos1, tmpbuf + len_del, len_in - len_del + 1 ); + len = len_in + len_ins - len_del; + + return len_in + len_ins - len_del; + } +} + +BYTE DelDigits ( BYTE * in_digit, BYTE in_len, BYTE * out_digit, BYTE count, BYTE filler ) +{ + return EditDigits ( out_digit, 32, in_digit, in_len, count, NULL, 0, filler ); +} + +void DWORD2BYTE ( BYTE * pdword, BYTE * pbyte, int len ) +{ + int i; + DWORD *p1, *p2; + + for ( i = 0; i < len / 4; i++ ) + { + p1 = ( DWORD * ) ( pdword + 4 * i ); + p2 = ( DWORD * ) ( pbyte + 4 * i ); + *p2 = htonl ( *p1 ); + } +} + +/** + ** @note transfer u32 to byte format\n + ** 0x9872 to 00 00 98 72 + **/ +void u32tobyte(u8 *str,u32 data) +{ + str[0] = data >> 24; + str[1] = data >> 16; + str[2] = data >> 8; + str[3] = data; +} + +/** + ** @note transfer u16 to bcd string format + **/ +u8 u16tobcd(u8 *bcd_string,u16 data) +{ + u8 bcd_len=0; + u8 ii; + u8 flag = 0; + + if (data == 0) + { + bcd_string[0] = 0; + return 1; + } + for (ii = 0;ii < 2;ii ++) + { + bcd_string[bcd_len] = data >> ((1-ii) * 8); + if (bcd_string[bcd_len] != 0 || flag == 1) + { + bcd_len ++; + flag = 1; + } + } + return bcd_len; +} + +/** + ** @note transfer bcd string to u16 format + **/ +u16 bcdtou16(u8 *bcd_string,u8 bcd_len) +{ + u8 ii; + u16 data=0; + + if (bcd_len > 2) + return 0; + data = 0; + for (ii = 0;ii < bcd_len;ii ++) + data += bcd_string[ii] << ((bcd_len-ii-1) * 8); + return data; +} + +/** + ** @note transfer u32 to bcd string format\n + ** 0x9872 to 98 72 and return len=2 + **/ +u8 u32tobcd(u8 *bcd_string,u32 data) +{ + u8 ii; + u8 bcd_len = 0; + u8 temp_data; + + if (data == 0) + { + bcd_string[0] = 0; + return 1; + } + for (ii = 0;ii < 4;ii ++) + { + temp_data = data >> ((3-ii) * 8); +// if (temp_data != 0 || flag == 1) + { + bcd_string[bcd_len++] = temp_data; +// flag = 1; + } + } + return bcd_len; +} + +/** + ** @note transfer bcd string to u32 format + **/ +u32 bcdtou32(u8 *bcd_string,u8 bcd_len) +{ + u8 ii; + u32 data=0; + + if (bcd_len > 4) + return 0; + data = 0; + for (ii = 0;ii < bcd_len;ii ++) + data += bcd_string[ii] << ((bcd_len-ii-1) * 8); + return data; +} +/** @} **/ + + +/* Convert data from ASCII form to right-aligned compact BCD form. */ +void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + + if (len > 0) *bcd_buf = 0x00; + for (i=0; i='a') ch -= 'a' - 10; + else if (ch>='A') ch -= 'A' - 10; + else ch -= '0'; + if ((len - i) & 1) *(bcd_buf++) |= ch & 0x0f; + else *bcd_buf = ch << 4; + } +} + +int ValidateAsciiMSISDN(char *msisdn, int len) +{ + int i; + + if(len>16) return 0; + if(msisdn == NULL) return 0; + + for(i=0;i= 0 ; j --) + { + sprintf( tmpStr , "%d" , pSrc[i] >>j & 0x01); + strcat( pDst , tmpStr) ; + } + } +} + +int main() +{ + u8 aBcd1[] = { 0x12 , 0x34 , 0x56 , 0x78 }; + u8 aBcd2[] = { 0x01 , 0x23 , 0x45 , 0x67 }; + u8 aBcd1Cp[256]; + u8 aBcd2Cp[256]; + u8 aStr[256]; + char tmpStr1[] = "01234567899876543210"; + char tmpStr2[] = "123456789"; + u64 llTmp1 = 1234567890; + u64 llTmp2 = 123456789; + u8 aDig1[] = { 0x01 , 0x09 , 0x08 , 0x07 , 0x06 }; + u8 aDig2[] = { 0x01 , 0x09 , 0x08 , 0x07 }; + u8 uByte; + int nLen = 0; + + uByte = ReverseByte(aBcd1[1]); + ByteBinToStr( aBcd1Cp , &uByte , 1 ); + ByteBinToStr( aBcd2Cp , &aBcd1[1] , 1 ); + printf("ReverseByte : aBcd1[1] : 0x%x [%s], Result : 0x%x[%s]\n" + , aBcd1[1] , aBcd2Cp , uByte , aBcd1Cp ); + + uByte = ReverseByte(aBcd2[1]); + ByteBinToStr( aBcd1Cp , &uByte , 1 ); + ByteBinToStr( aBcd2Cp , &aBcd2[1], 1 ); + printf("ReverseByte : aBcd2[1] : 0x%x [%s], Result : 0x%x[%s]\n\n" + , aBcd2[1] , aBcd2Cp , uByte , aBcd1Cp ); + + MsgToFmtLog(aBcd1 , 4 , aStr , 256 ); + printf("ReverseBcd : aBcd1: %s " , aStr ); + ReverseBCD(aBcd1Cp, aBcd1 , 4); + MsgToFmtLog(aBcd1Cp , 4 , aStr , 256 ); + printf("Result : %s \n" , aStr ); + + MsgToFmtLog(aBcd2 , 4 , aStr , 256 ); + printf("ReverseBcd : aBcd2: %s " , aStr ); + ReverseBCD(aBcd2Cp, aBcd2 , 4); + MsgToFmtLog(aBcd2Cp , 4 , aStr , 256 ); + printf("Result : %s \n\n" , aStr ); + + + MsgToFmtLog(aBcd1 , 4 , aStr , 256 ); + printf("ReverseArray : aBcd1: %s " , aStr ); + ReverseArray(aBcd1Cp, aBcd1 , 4); + MsgToFmtLog(aBcd1Cp , 4 , aStr , 256 ); + printf("Result : %s \n" , aStr ); + + MsgToFmtLog(aBcd2 , 4 , aStr , 256 ); + printf("ReverseArray : aBcd2: %s " , aStr ); + ReverseArray(aBcd2Cp, aBcd2 , 4); + MsgToFmtLog(aBcd2Cp , 4 , aStr , 256 ); + printf("Result : %s \n\n" , aStr ); + + BcdToStr( aStr , aBcd1 , 4); + MsgToFmtLog(aBcd1 , sizeof(aBcd1) , aBcd2Cp , 256 ); + printf("BcdToStr : aBcd1 : %s result : %s\n", aBcd2Cp , aStr); + BcdToStr( aStr , aBcd2 , 4); + MsgToFmtLog(aBcd2 , sizeof(aBcd2) , aBcd2Cp , 256 ); + printf("BcdToStr : aBcd2 : %s result : %s\n\n",aBcd2Cp , aStr); + + MsgToFmtLog(aBcd1 , sizeof(aBcd1) , aBcd2Cp , 256 ); + printf( "BcdToU64 aBcd1 : %s result: %lld \n" , aBcd2Cp , BcdToU64( aBcd1, 4 ) ); + MsgToFmtLog(aBcd2 , sizeof(aBcd2) , aBcd2Cp , 256 ); + printf( "BcdToU64 aBcd2 : %s result: %lld \n\n" , aBcd2Cp ,BcdToU64( aBcd2, 4 ) ); + + nLen = BcdToDig( aBcd1Cp , 256 ,aBcd1 , 4 ); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + MsgToFmtLog(aBcd1 , sizeof(aBcd1) , aBcd2Cp , 256 ); + printf("BcdToDig :aBcd1 : %s result : %s\n" , aBcd2Cp, aStr ); + + nLen = BcdToDig( aBcd1Cp , 256 , aBcd2 ,sizeof(aBcd2)); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + MsgToFmtLog(aBcd2 , sizeof(aBcd2) , aBcd2Cp , 256 ); + printf("BcdToDig :aBcd2 : %s result : %s\n\n" , aBcd2Cp,aStr ); + + + nLen = StrToBcd( aBcd1Cp , tmpStr1 , 256); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + printf("StrToBcd :tmpStr1 : %s result : %s\n" ,tmpStr1 , aStr); + + nLen = StrToBcd( aBcd1Cp , tmpStr2 , 256); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + printf("StrToBcd :tmpStr2 : %s result : %s\n\n" ,tmpStr2 , aStr); + + nLen = U64ToBcd(aBcd1Cp ,llTmp1 ,256); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + printf("U64ToBcd :llTmp1 : %lld , result: %s \n" ,llTmp1, aStr ); + + nLen = U64ToBcd(aBcd1Cp ,llTmp2 ,256); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + printf("U64ToBcd :llTmp2 : %lld , result: %s \n\n" ,llTmp2, aStr ); + + nLen = DigToBcd(aBcd1Cp, 256 , aDig1 , sizeof(aDig1)); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + MsgToFmtLog(aDig1 , sizeof(aDig1) , aBcd2Cp , 256 ); + printf("DigToBcd :aDig1 : %s result: %s \n" ,aBcd2Cp ,aStr ); + + nLen = DigToBcd(aBcd1Cp, 256, aDig2 , sizeof(aDig2) ); + MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 ); + MsgToFmtLog(aDig2 , sizeof(aDig2) , aBcd2Cp , 256 ); + printf("DigToBcd :aDig2 : %s result: %s \n" ,aBcd2Cp , aStr ); + + return 0; +} +*/ + +/////////////////////////////////////////////////////////////////////////// +// Test result +// +/////////////////////////////////////////////////////////////////////////// + +/* +ReverseByte : aBcd1[1] : 0x34 [00110100], Result : 0x2c[00101100] +ReverseByte : aBcd2[1] : 0x23 [00100011], Result : 0xc4[11000100] + +ReverseBcd : aBcd1: 12 34 56 78 + Result : 21 43 65 87 + +ReverseBcd : aBcd2: 01 23 45 67 + Result : 10 32 54 76 + + +ReverseArray : aBcd1: 12 34 56 78 + Result : 78 56 34 12 + +ReverseArray : aBcd2: 01 23 45 67 + Result : 67 45 23 01 + + +BcdToStr : aBcd1 : 12 34 56 78 + result : 12345678 +BcdToStr : aBcd2 : 01 23 45 67 + result : 01234567 + +BcdToU64 aBcd1 : 12 34 56 78 + result: 12345678 +BcdToU64 aBcd2 : 01 23 45 67 + result: 1234567 + +BcdToDig :aBcd1 : 12 34 56 78 + result : 01 02 03 04 05 06 07 08 + +BcdToDig :aBcd2 : 01 23 45 67 + result : 00 01 02 03 04 05 06 07 + + +StrToBcd :tmpStr1 : 01234567899876543210 result : 01 23 45 67 89 98 76 54 32 10 + +StrToBcd :tmpStr2 : 123456789 result : 01 23 45 67 89 + + +U64ToBcd :llTmp1 : 1234567890 , result: 12 34 56 78 90 + +U64ToBcd :llTmp2 : 123456789 , result: 01 23 45 67 89 + + +DigToBcd :aDig1 : 01 09 08 07 06 + result: 01 98 76 + +DigToBcd :aDig2 : 01 09 08 07 + result: 19 87 + +*/ diff --git a/plat/public/src/pub_inet.c b/plat/public/src/pub_inet.c new file mode 100644 index 0000000..d90cecf --- /dev/null +++ b/plat/public/src/pub_inet.c @@ -0,0 +1,409 @@ +////////////////////////////////////////////////// +//Title : pub_inet.c +//Auhtor : Liu Wei +//Desc : public inet function implementation +//Created : 2007-06-22 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_inet.h" +/*@ignore@*/ +/////////////////////////////////////////////////////////////////////////// +// Inet If Address infomation interface +/////////////////////////////////////////////////////////////////////////// +extern int GetNetIfInfo ( IfAddr * pIfAddr ) +{ + int fd; + struct ifreq buf[MAXINTERFACES]; + //struct arpreq arp; + struct ifconf ifc; + + pIfAddr->uIfNum = 0; + + if ( ( fd = socket ( AF_INET, SOCK_DGRAM, 0 ) ) >= 0 ) + { + ifc.ifc_len = sizeof buf; + ifc.ifc_buf = ( caddr_t ) buf; + if ( !ioctl ( fd, SIOCGIFCONF, ( char * ) &ifc ) ) + { + int i; + + pIfAddr->uIfNum = ifc.ifc_len / sizeof ( struct ifreq ); + pIfAddr->uIfNum = pIfAddr->uIfNum % MAXINTERFACES; + for ( i = 0; i < pIfAddr->uIfNum; i++ ) + { + ioctl ( fd, SIOCGIFFLAGS, ( char * ) &buf[i] ); + pIfAddr->tIfEntity[i].uIfState = buf[i].ifr_flags & IFF_UP; + if ( !( ioctl ( fd, SIOCGIFADDR, ( char * ) &buf[i] ) ) ) + { + pIfAddr->tIfEntity[i].dIfIP = ( ( struct sockaddr_in * ) + ( &buf[i].ifr_addr ) )-> + sin_addr.s_addr; + } + } + } + + } + close ( fd ); + return pIfAddr->uIfNum; +} + +static u32 wxc2_bind_ip=0xFFFFFFFF, wxc2_shm_shift; + +void ReadMCMSParam() +{ + char cnf_file[]="./conf/mcms_conf.txt"; + char info_str[256], *buf_ptr;; + FILE *fp=NULL; + + fp = fopen(cnf_file,"r"); + + wxc2_bind_ip = 0; + wxc2_shm_shift = 0; + + if(fp == NULL) + return; + + while (!feof(fp)) + { + info_str[0] = '\n'; + fgets(info_str,250,fp); + if (info_str[0] == '#' || info_str[0] == '\n') + continue; + buf_ptr = info_str; + + if(!strncasecmp(info_str,"bind ip=",8)) + { + + wxc2_bind_ip = inet_addr(&info_str[8]); + continue; + } + if(!strncasecmp(info_str,"shm key shift=",14)) + { + wxc2_shm_shift = atoi(&info_str[14]); + continue; + } + } + + fclose(fp); + return; +} + +u32 GetLocalIP( ) +{ + struct hostent *host; + struct in_addr *hostip_addr; + char name[100]; + + if(wxc2_bind_ip == 0xFFFFFFFF) + ReadMCMSParam(); + + if(wxc2_bind_ip == 0) + { + gethostname ( name, 64 ); + host = gethostbyname ( name ); + + hostip_addr = ( struct in_addr * ) ( *host->h_addr_list ); + return hostip_addr->s_addr; + } + return wxc2_bind_ip; +} + +u32 GetLocalIP1( ) +{ + if(wxc2_bind_ip == 0xFFFFFFFF) + ReadMCMSParam(); + + if(wxc2_bind_ip == 0) + { + return INADDR_ANY; + + } + return wxc2_bind_ip; +} + +u32 wxc2_get_shm_offset() +{ + if(wxc2_bind_ip == 0xFFFFFFFF) + ReadMCMSParam(); + return wxc2_shm_shift; +} +/////////////////////////////////////////////////////////////////////////// +// Inet If Address infomation interface +/////////////////////////////////////////////////////////////////////////// + +//УÑéºÍËã·¨ +static u16 IcmpCheckSum ( u16 * addr, int len ) +{ + int nleft = len; + int sum = 0; + u16 *w = addr; + u16 answer = 0; + + //°ÑICMP±¨Í·¶þ½øÖÆÊý¾ÝÒÔ2×Ö½ÚΪµ¥Î»ÀÛ¼ÓÆðÀ´ + while ( nleft > 1 ) + { + sum += *w++; + nleft -= 2; + } + + //ÈôICMP±¨Í·ÎªÆæÊý¸ö×Ö½Ú£¬»áÊ£ÏÂ×îºóÒ»×Ö½Ú¡£ + //°Ñ×îºóÒ»¸ö×Ö½ÚÊÓΪһ¸ö2×Ö½ÚÊý¾ÝµÄ¸ß×Ö½Ú£¬Õâ¸ö2×Ö½ÚÊý¾ÝµÄµÍ×Ö½ÚΪ0£¬¼ÌÐøÀÛ¼Ó + if ( nleft == 1 ) + { + *( unsigned char * ) ( &answer ) = *( unsigned char * ) w; + sum += answer; + } + + sum = ( sum >> 16 ) + ( sum & 0xffff ); + sum += ( sum >> 16 ); + answer = ~sum; + + return answer; +} + +//ÉèÖÃICMP±¨Í· +static int IcmpPacking ( IcmpSrv * pIS ) +{ + int packsize; + struct icmp *icmp; + struct timeval *tval; + + icmp = ( struct icmp * ) pIS->aSendBuff; + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_code = 0; + icmp->icmp_cksum = 0; + icmp->icmp_seq = pIS->nPackNumSend; + icmp->icmp_id = pIS->tPid; + packsize = 8 + pIS->uDataLen; + + //¼Ç¼·¢ËÍʱ¼ä + tval = ( struct timeval * ) icmp->icmp_data; + gettimeofday ( tval, NULL ); + + icmp->icmp_cksum = IcmpCheckSum ( ( u16 * ) icmp, packsize ); + + return packsize; +} + +//°þÈ¥ICMP±¨Í· +static int IcmpUnPack ( u8 * buf, int len, IcmpSrv * pIS ) +{ + int nIpHdrLen; + struct ip *pIP; + struct icmp *icmp; + struct timeval *tvSend; + struct timeval tvRecv; + double rtt; + + gettimeofday ( &tvRecv, NULL ); + pIP = ( struct ip * ) buf; + //Çóip±¨Í·³¤¶È,¼´ip±¨Í·µÄ³¤¶È±êÖ¾³Ë4 + nIpHdrLen = pIP->ip_hl << 2; + + //Ô½¹ýip±¨Í·,Ö¸ÏòICMP±¨Í· + icmp = ( struct icmp * ) ( buf + nIpHdrLen ); + + //ICMP±¨Í·¼°ICMPÊý¾Ý±¨µÄ×ܳ¤¶È + len -= nIpHdrLen; + + if ( len < 8 ) + //СÓÚICMP±¨Í·³¤¶ÈÔò²»ºÏÀí + { + printf ( "ICMP packets's length is less than 8 " ); + return 0; + } + + //È·±£Ëù½ÓÊÕµÄÊÇÎÒËù·¢µÄµÄICMPµÄ»ØÓ¦ + if ( ( icmp->icmp_type == ICMP_ECHOREPLY ) + && ( icmp->icmp_id == pIS->tPid ) ) + { + tvSend = ( struct timeval * ) icmp->icmp_data; + + rtt = ( tvRecv.tv_sec * 1000 + tvRecv.tv_usec / 1000 ) - + ( tvSend->tv_sec * 1000 + tvSend->tv_usec / 1000 ); + + printf ( "%d byte from %s: icmp_seq=%u ttl=%d rtt=%.3f ms \n", len, + inet_ntoa ( pIS->tFromAddr.sin_addr ), icmp->icmp_seq, + pIP->ip_ttl, rtt ); + return 1; + } + return 0; +} + +static void IcmpStatis ( IcmpSrv * pIS ) +{ + int nSend, nRecv; + + nSend = pIS->nPackNumSend; + nRecv = pIS->nPackNumRecv; + + printf ( " --------------------PING statistics------------------- \n" ); + printf ( "%d packets transmitted, %d received , %%%d lost \n\n", nSend, + nRecv, ( nSend - nRecv ) / nSend * 100 ); + close ( pIS->wSockfd ); + pIS->uSrvState = 0; +} + +//·¢ËÍÈý¸öICMP±¨ÎÄ +static int IcmpSend ( IcmpSrv * pIS ) +{ + int nSize; + + if ( pIS->nPackNumSend < MAX_NO_PACKETS ) + { + pIS->nPackNumSend++; + nSize = IcmpPacking ( pIS ); + + //ÉèÖÃICMP±¨Í· + if ( sendto ( pIS->wSockfd, pIS->aSendBuff, nSize, 0, + ( struct sockaddr * ) &pIS->tToAddr, + sizeof ( pIS->tToAddr ) ) < 0 ) + { + perror ( "sendto error" ); + return 0; + } + printf ( "[IcmpSend] : Send icmp Pack %d \n", pIS->nPackNumSend ); + return 1; + } + return 0; +} + +//½ÓÊÕËùÓÐICMP±¨ÎÄ +static void IcmpRecv ( IcmpSrv * pIS ) +{ + int n; + extern int errno; + + socklen_t fromlen = sizeof ( pIS->tFromAddr ); + while ( pIS->nPackNumRecv < pIS->nPackNumSend ) + { + if ( ( n = + recvfrom ( pIS->wSockfd, pIS->aRecvBuff, + sizeof ( pIS->aRecvBuff ), 0, + ( struct sockaddr * ) &pIS->tFromAddr, + &fromlen ) ) < 0 ) + + { + if ( errno == EINTR ) + continue; + perror ( "recvfrom error" ); + continue; + } + if ( IcmpUnPack ( pIS->aRecvBuff, n, pIS ) == -1 ) + continue; + pIS->nPackNumRecv++; + } +} + +extern int PingInit ( IcmpSrv * pIS, int nDataLen ) +{ + memset ( pIS, 0, sizeof ( IcmpSrv ) ); + pIS->uSrvState = 0; + + pIS->uDataLen = 56; + + if ( ( pIS->pProtoent = getprotobyname ( "icmp" ) ) == NULL ) + { + perror ( "getprotobyname" ); + exit ( 1 ); + } + + // »ØÊÕrootȨÏÞ,ÉèÖõ±Ç°Óû§È¨ÏÞ + setuid ( getuid ( ) ); + + //»ñÈ¡mainµÄ½ø³Ìid,ÓÃÓÚÉèÖÃICMPµÄ±êÖ¾·û + pIS->tPid = getpid ( ); + return 0; +} + +extern int PingStart ( IcmpSrv * pIS, char *sIP, PingCallBack fCallBack ) +{ + int nSize; + struct hostent *pHost; + + //struct in_addr *pInAddr; + u32 nInetAddr; + + if ( pIS->uSrvState ) + { + return 0; + } + + pIS->fCallBack = fCallBack; + + //Éú³ÉʹÓÃICMPµÄԭʼÌ×½Ó×Ö,ÕâÖÖÌ×½Ó×ÖÖ»ÓÐroot²ÅÄÜÉú³É + if ( ( pIS->wSockfd = + socket ( AF_INET, SOCK_RAW, pIS->pProtoent->p_proto ) ) < 0 ) + { + perror ( "socket error" ); + exit ( 1 ); + } + + //À©´óÌ×½Ó×Ö½ÓÊÕ»º³åÇøµ½50KÕâÑù×öÖ÷ҪΪÁ˼õС½ÓÊÕ»º³åÇøÒç³öµÄ + //µÄ¿ÉÄÜÐÔ, ÈôÎÞÒâÖÐping»áÒýÀ´´óÁ¿Ó¦´ð + setsockopt ( pIS->wSockfd, SOL_SOCKET, SO_RCVBUF, &nSize, + sizeof ( nSize ) ); + bzero ( &pIS->tToAddr, sizeof ( pIS->tToAddr ) ); + pIS->tToAddr.sin_family = AF_INET; + + //ÅжÏÊÇÖ÷»úÃû»¹ÊÇipµØÖ· + nInetAddr = inet_addr ( sIP ); + if ( nInetAddr == INADDR_NONE ) + { + if ( ( pHost = gethostbyname ( sIP ) ) == NULL ) //ÊÇÖ÷»úÃû + { + perror ( "gethostbyname error" ); + exit ( 1 ); + } + memcpy ( ( char * ) &pIS->tToAddr.sin_addr, pHost->h_addr, + pHost->h_length ); + } + else //ÊÇipµØÖ· + { + pIS->tToAddr.sin_addr.s_addr = nInetAddr; + //memcpy( (char *)&pIS->tToAddr,(char *)&nInetAddr,host->h_length); + } + printf ( "PING %s(%s): %d bytes data in ICMP packets. \n", sIP, + inet_ntoa ( pIS->tToAddr.sin_addr ), pIS->uDataLen ); + + pIS->uSrvState = 1; + pIS->uIcmpState = 1; + return 0; +} + +extern int PingTimer ( IcmpSrv * pIS ) +{ + if ( pIS->uSrvState ) + { + IcmpRecv ( pIS ); + switch ( pIS->uIcmpState ) + { + case 1: + case 2: + case 3: + IcmpSend ( pIS ); + pIS->uIcmpState++; + break; + default: + if ( pIS->nPackNumRecv >= 3 ) + { + IcmpStatis ( pIS ); + pIS->fCallBack ( 1 ); + } + if ( pIS->uIcmpState++ > 200 ) + { + IcmpStatis ( pIS ); + pIS->fCallBack ( 0 ); + } + break; + } + } + + return 0; +} +/*@end@*/ + diff --git a/plat/public/src/pub_license.c b/plat/public/src/pub_license.c new file mode 100644 index 0000000..d183863 --- /dev/null +++ b/plat/public/src/pub_license.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include "include/crypt.h" + +#define LICENSE_HD_INFO_LIST_SIZE 32 + +typedef struct _license_hd_info +{ + int used_flag; + unsigned char HDSerialNumber[256]; +}license_hd_info; + +typedef struct _license_hd_info_list +{ + char system_created_time[128+1]; + license_hd_info list[LICENSE_HD_INFO_LIST_SIZE]; +}license_hd_info_list; + +license_hd_info_list hd_info_list; +static unsigned char system_created_time[128+1]; + +static int GetSysCreatedTime() +{ + FILE *fpConf=NULL; + int i,j=0,k,len; + char created_time[128] = {0}; + char buf[128] = {0}; + unsigned char created_time_des[128] = {0}, TmpStr[64]= {0}; + + memset(created_time, 0, 64); + //sprintf(buf,"tune2fs -l /dev/sda1 | grep create >../log/created_time.txt"); + sprintf(buf,"ls -lact --full-time /etc | tail -1 | awk '{print $6,$7}' >../log/created_time.txt"); + system(buf); + fpConf = fopen("../log/created_time.txt","r"); + if(fpConf != NULL) + { + len = fread(created_time,128,1,fpConf); + //if(created_time[len-1] == '\r' || created_time[len-1] == '\n') + // created_time[len - 2] = 0; + fclose(fpConf); + } + else + return 0; + + j = strlen(created_time); + if (j == 0) + { + return 0; + } + + k = (j + 7) / 8; + memset(created_time + j, '0', 128 - j); + + memset(created_time_des, 0, 128); + for (i = 0; i < k; i++) + { + memset(TmpStr, 0, 64); + DesCrypt(TmpStr, (unsigned char *)created_time + 8 * i, NULL, 0); + memcpy(created_time_des + 8 * i, TmpStr, 8); + } + system_created_time[0] = k*8; + memcpy(&system_created_time[1], created_time_des, 8*k); + + return 1; +} + +int ReadHDInfoList() +{ + char name[32]={"/etc/lhdlist"}; + FILE *fp = NULL; + + GetSysCreatedTime(); + + fp = fopen(name, "r"); + if(fp == NULL) + return 0; + + memset(&hd_info_list, 0x00, sizeof(license_hd_info_list)); + fread(&hd_info_list,sizeof(license_hd_info_list),1,fp); + + fclose(fp); + return 1; +} + +int SaveHDInfoList(unsigned char *new_hd_info) +{ + char name[32]={"/etc/lhdlist"}; + FILE *fp = NULL; + int i; + license_hd_info *info_ptr = NULL; + + + for(i=0; iused_flag == 1) + { + if(memcmp(info_ptr->HDSerialNumber, new_hd_info, 256) == 0) + return 1; + } + } + + fp = fopen(name, "w"); + if(fp == NULL || new_hd_info == NULL) + return 0; + + memcpy(hd_info_list.system_created_time, system_created_time, 128+1); + + for(i=0; iused_flag == 0) + { + info_ptr->used_flag = 1; + memcpy(info_ptr->HDSerialNumber, new_hd_info, 256); + break; + } + } + + fwrite(&hd_info_list,sizeof(license_hd_info_list),1,fp); + + fclose(fp); + return 1; + +} + +int CheckIfHDInfoBackup(unsigned char *license_info) +{ + int length; + int i; + license_hd_info *info_ptr = NULL; + + length = system_created_time[0]; + if(memcmp(&system_created_time[1], &hd_info_list.system_created_time[1], length)) + return 0; + + for(i=0; iHDSerialNumber[0]; + if (memcmp(&info_ptr->HDSerialNumber[1], license_info, length) == 0) + return 1; + } + } + + return 0; +} diff --git a/plat/public/src/pub_log.c b/plat/public/src/pub_log.c new file mode 100644 index 0000000..21492da --- /dev/null +++ b/plat/public/src/pub_log.c @@ -0,0 +1,135 @@ +////////////////////////////////////////////////// +//Title : pub_log.c +//Auhtor : Liu Wei +//Desc : public output log implementation +//Created : 2007-05-21 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + + +#include "./include/pub_log.h" + +void FLogMsg( u8 LogMask , const char *pFmt, ...) +{ + va_list ap; + + va_start(ap, pFmt); + switch( LogMask ) + { + case PIF_INFO: + break; + case PIF_WARN: + break; + case PIF_GERR: + break; + case PIF_CERR: + break; + case PIF_DBG: + break; + case PIF_UNKN: + break; + case PIF_DEFAULT: + break; + case PIF_ALL: + break; + default: + break; + } + printf(pFmt, ap); + va_end(ap); + return; +} + +char *ByteBinToStr( char *pDst , const u8 *pSrc , int nByte ) +{ + register int i , j , k = 0; + + for( i =0 ; i < nByte ; i++ ) + { + for( j = 7 ; j >= 0 ; j --) + { + pDst[k++] = (pSrc[i] >>j & 0x01) + '0'; + } + } + pDst[k++] = CNULL; + return pDst; +} + +char *TxtColor ( int nAttr, int nFg, int nBg, char *pStr ) +{ + register int nPos ; + int nLen = strlen(pStr); + char *p = strdup (pStr); + + nPos = 0; + pStr[nPos++] = 27; + pStr[nPos++] = '['; + pStr[nPos++] = nAttr + '0'; + pStr[nPos++] = ';'; + pStr[nPos++] = 3 + '0'; + pStr[nPos++] = nFg + '0'; + pStr[nPos++] = ';'; + pStr[nPos++] = 4 + '0'; + pStr[nPos++] = nBg + '0'; + pStr[nPos++] = 'm'; + strcpy( pStr + nPos , p); + nPos += nLen; + pStr[nPos++] = 27; + pStr[nPos++] = '['; + pStr[nPos++] = RESET + '0'; + pStr[nPos++] = ';'; + pStr[nPos++] = 3 + '0'; + pStr[nPos++] = WHITE + '0'; + pStr[nPos++] = ';'; + pStr[nPos++] = 4 + '0'; + pStr[nPos++] = BLACK + '0'; + pStr[nPos++] = 'm'; + pStr[nPos] = CNULL; + + free(p); + return pStr; +} + + + +int MsgToFmtLog ( const BYTE * pBcd, int nBcdLen, char *pStr, int nStrBuffSize ) +{ + register int i, len = 0; + int nChar; + + nChar = ( nBcdLen / 16 ) * 49; + if( (nBcdLen %16) > 8 ) + { + nChar+=8*3 +1; + + } + nChar += (nBcdLen %8)*3 +1 + 2 ; //add "\r\n" at end + + WxcAssert ( ( nChar < nStrBuffSize ), "sprint bcd string buffer flow" ); + + for ( i = 0; i <= nBcdLen-1; i++ ) + { + pStr[len++] = HexToCh(pBcd[i] >> 4 ); + pStr[len++] = HexToCh(pBcd[i] & 0x0F); + pStr[len++] = ' '; + if ( 0 == ( (i+1) % 16 ) && i) + { + pStr[len++] = '\n'; + } + else if ( 0 == ( (i+1) % 8 ) ) + { + pStr[len++] = ' '; + } + } + if ( 0 != ( len % 49 ) ) + { + pStr[len++] = ' '; + } + pStr[len++] = '\r'; + pStr[len++] = '\n'; + pStr[len++] = CNULL; + return len; +} diff --git a/plat/public/src/pub_malloc.c b/plat/public/src/pub_malloc.c new file mode 100644 index 0000000..cd89ec7 --- /dev/null +++ b/plat/public/src/pub_malloc.c @@ -0,0 +1,23 @@ +////////////////////////////////////////////////// +//Title : wxc_malloc.c +//Auhtor : Liu Wei +//Desc : WXC2 Public heap memery management +//Created : 2007-05-01 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_malloc.h" +/* +void *WxcMalloc ( ) +{ + return (void*)NULL; +} + +void WxcFree ( ) +{ + +} +*/ diff --git a/plat/public/src/pub_netcap.c b/plat/public/src/pub_netcap.c new file mode 100644 index 0000000..3626867 --- /dev/null +++ b/plat/public/src/pub_netcap.c @@ -0,0 +1,371 @@ +////////////////////////////////////////////////// +//Title : wxc_netcap.c +//Auhtor : Liu Wei +//Desc : wxc2 netcap implementation +//Created : 2007-06-05 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_netcap.h" + +/*@ignore@*/ +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +static NetCap tNC; + +#define BASE 65521 +extern u32 GetLocalIP(); + +static u32 NcAd32 ( u32 ad, u8 * buf, int len ) +{ + u32 s1 = ad & 0xffff; + u32 s2 = ( ad >> 16 ) & 0xffff; + int n; + + for ( n = 0; n < len; n++, buf++ ) + { + s1 = ( s1 + *buf ); + + if ( s1 >= BASE ) + s1 -= BASE; + + s2 = ( s2 + s1 ); + + if ( s2 >= BASE ) + { + + s2 -= BASE; + } + } + return ( s2 << 16 ) + s1; +} + +#define HEADER_LEN 12 + +static u32 NcCS ( u8 * ptr, u16 count ) +{ + + u32 ad = 1L; + u32 zero = 0L; + + ad = NcAd32 ( ad, ptr, sizeof ( HEADER_LEN - sizeof ( u32 ) ) ); + ad = NcAd32 ( ad, ( u8 * ) & zero, sizeof ( u32 ) ); + ptr += HEADER_LEN; + count -= HEADER_LEN; + + ad = NcAd32 ( ad, ptr, count ); + return ad; +} + +static int NcGetSocket ( u32 port ) +{ + int nSock; + int nOn = 1; + unsigned long cmdarg = 1; + struct sockaddr_in sin_addr; + + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = htons ( port ); + sin_addr.sin_addr.s_addr = GetLocalIP(); //htonl ( INADDR_ANY ); + + if ( ( nSock = socket ( AF_INET, SOCK_RAW, IPPROTO_SCTP ) ) < 0 ) + { + perror ( "Get SCTP socket error " ); + return -1; + } + + setsockopt ( nSock, SOL_SOCKET, SO_REUSEADDR, &nOn, sizeof ( nOn ) ); + + ioctl ( nSock, FIONBIO, &cmdarg ); + + return ( nSock ); +} + +extern void NcSetPort ( u32 port ) +{ + tNC.nPort = port; +} + +extern void NcSetIP ( u32 ip ) +{ + tNC.nDstIp = ip; +} + +extern int NcInit ( ) +{ + memset ( &tNC, 0, sizeof ( NetCap ) ); + tNC.nPort = 8000; + tNC.nDstIp = inet_addr ( "172.54.240.3" ); + return 1; +} + +extern int NcStart ( u32 wIP, u32 wPort ) +{ + if ( tNC.uState ) + return 0; + tNC.nDstIp = wIP ? wIP : tNC.nDstIp; + tNC.nPort = wPort ? wPort : tNC.nPort; + tNC.nSock = NcGetSocket ( tNC.nPort ); + tNC.uState = 1; + return 1; +} + +extern int NcStop ( ) +{ + shutdown ( tNC.nSock, 2 ); + tNC.uState = 0; + return 1; +} + +#define SCTP_HEADER_LEN 0x1C + +#define SCCTP_CS_POS 0x08 + +#define SCTP_CHUNKLEN_POS 15 + +static u8 SCTP_HEADER[] = { + 0x13, 0x56, 0x13, 0x56, 0x00, 0x00, 0x2d, 0xd1, + 0x05, 0x67, 0x59, 0x7a, 0x00, 0x00, 0x00, 0x3c, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x02 +}; + +static int NcStuffSCTP ( u8 * pIPBuff ) +{ + memcpy ( pIPBuff, SCTP_HEADER, SCTP_HEADER_LEN ); + pIPBuff[0] = 4950 >> 8; + pIPBuff[1] = 4950 & 0xFF; + pIPBuff[2] = tNC.nPort >> 8; + pIPBuff[3] = tNC.nPort & 0xFF; + return SCTP_HEADER_LEN; +} + +#define M2UA_HEADER_LEN 0x14 + +#define M2UA_MSGLEN_POS 0x07 + +#define M2UA_PARALEN_POS 0x13 + +static int NcGetM2uaParaLen ( u32 wMtp3Len ) +{ + return ( wMtp3Len + 4 ); +} + +static int NcGetM2uaMsgLen ( u32 wMtp3Len ) +{ + return ( NcGetM2uaParaLen ( wMtp3Len ) + 16 ); +} + +static u8 M2UA_HEADER[] = { + 0x01, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x1c +}; + +int NcStuffM2UA ( u8 * pIPBuff, u32 wMtp3Len ) +{ + memcpy ( pIPBuff, M2UA_HEADER, M2UA_HEADER_LEN ); + *( pIPBuff + M2UA_PARALEN_POS ) = NcGetM2uaParaLen ( wMtp3Len ); + *( pIPBuff + M2UA_MSGLEN_POS ) = NcGetM2uaMsgLen ( wMtp3Len ); + return M2UA_HEADER_LEN; +} + +#define MTP3_HAEDER_ANSI_LEN 0x08 + +static u8 MTP3_HEADER_ANSI[] = { + 0x83, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 +}; + +#define MTP3_HAEDER_ITU_LEN 0x05 + +static u8 MTP3_HEADER_ITU[] = { + 0x83, 0x20, 0x00, 0x08, 0x00 +}; + +static int NcStuffMtp3 ( u8 * pIPBuff, u32 wDPC, u32 wOPC, u8 uSLS, + u8 uAnsiFlag ) +{ + u32 MTP3_HAEDER_LEN; + u8 *MTP3_HEADER; + + //printf ( "stuff mtp3 : dpc :%ld opc :%ld sls: %d , ansi :%d \n", wDPC, wOPC, + // uSLS, uAnsiFlag ); + if ( uAnsiFlag ) + { + MTP3_HEADER_ANSI[1] = wDPC ? MTP3_HEADER_ANSI[1] : wDPC; + MTP3_HEADER_ANSI[4] = wOPC ? MTP3_HEADER_ANSI[4] : wOPC; + MTP3_HEADER_ANSI[7] = uSLS ? MTP3_HEADER_ANSI[7] : uSLS; + } + else + { + if ( wDPC ) + { + MTP3_HEADER_ITU[1] = wDPC & 0xFF; + MTP3_HEADER_ITU[2] &= 0xC0; + MTP3_HEADER_ITU[2] |= ( wDPC >> 8 ) & 0x3F; + } + if ( wOPC ) + { + MTP3_HEADER_ITU[2] &= 0x3F; + MTP3_HEADER_ITU[2] |= ( wDPC & 0x03 ) << 6; + MTP3_HEADER_ITU[3] = wDPC >> 2; + MTP3_HEADER_ITU[4] &= 0xF0; + MTP3_HEADER_ITU[4] |= wOPC >> 10; + } + + MTP3_HEADER_ITU[4] &= 0x0F; + MTP3_HEADER_ITU[4] |= uSLS << 4; + } + + MTP3_HEADER = uAnsiFlag ? MTP3_HEADER_ANSI : MTP3_HEADER_ITU; + MTP3_HAEDER_LEN = uAnsiFlag ? MTP3_HAEDER_ANSI_LEN : MTP3_HAEDER_ITU_LEN; + + memcpy ( pIPBuff, MTP3_HEADER, MTP3_HAEDER_LEN ); + return MTP3_HAEDER_LEN; +} + +extern void NcMtp3Send ( u8 * pMtp3Msg, u32 wMtp3Len, u8 uAnsiFlag ) +{ + u8 IPBuff[512]; + u32 wPackLen = 0; + u32 wM2uaLen = 0; + u32 ad = 0; + u32 MTP3_HAEDER_LEN; + u8 uPad = 0; + struct sockaddr_in sin_addr; + + memset ( IPBuff, 0, 512 * sizeof ( u8 ) ); + wPackLen += NcStuffSCTP ( IPBuff + wPackLen ); + MTP3_HAEDER_LEN = uAnsiFlag ? MTP3_HAEDER_ANSI_LEN : MTP3_HAEDER_ITU_LEN; + wM2uaLen = NcStuffM2UA ( IPBuff + wPackLen, wMtp3Len ); + wPackLen += wM2uaLen; + memcpy ( IPBuff + wPackLen, pMtp3Msg, wMtp3Len ); + wPackLen += wMtp3Len; + + uPad = ( IPBuff[SCTP_HEADER_LEN + 7] ) % 4; + uPad = uPad ? ( 4 - uPad ) : 0; + + for ( ; uPad > 0; uPad-- ) + { + IPBuff[SCTP_HEADER_LEN + 7]++; //m2ua msg len + IPBuff[wPackLen++] = 0x00; + } + + IPBuff[SCTP_CHUNKLEN_POS] = 0x10 + IPBuff[SCTP_HEADER_LEN + 7]; + + ad = NcCS ( IPBuff, wPackLen ); + IPBuff[SCCTP_CS_POS] = ad & 0xFF; + IPBuff[SCCTP_CS_POS + 1] = ad / ( 256 ); + IPBuff[SCCTP_CS_POS + 2] = ad / ( 256 * 256 ); + IPBuff[SCCTP_CS_POS + 3] = ad / ( 256 * 256 * 256 ); + + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = htons ( tNC.nPort ); + sin_addr.sin_addr.s_addr = tNC.nDstIp; + + sendto ( tNC.nSock, ( char * ) IPBuff, wPackLen, 0, + ( struct sockaddr * ) &sin_addr, sizeof ( struct sockaddr ) ); + //printf ( "\nMTP3 Send Net cap message!\n " ); +} + +typedef struct WXC_NETCAP_SCCP_INTRA_MESSAGE +{ + u8 msgsource; + u8 msgtype; + u8 msgclass; + u8 msgMNP; + int OPC; + int DPC; + u8 SLS; +} +Wxc_NCSccpIntra; + +extern int NcSccpSend ( u8 * pSccpMsg, u32 wSccpLen, u8 * pIntraMsg, + BYTE uAnsiFlag ) +{ + u8 IPBuff[512]; + u32 wPackLen = 0; + u32 wM2uaLen = 0; + u32 ad = 0; + u8 uPad = 0; + u32 MTP3_HAEDER_LEN; + struct sockaddr_in sin_addr; + Wxc_NCSccpIntra *pIntra = ( Wxc_NCSccpIntra * ) pIntraMsg; + + memset ( IPBuff, 0, 512 * sizeof ( u8 ) ); + wPackLen += NcStuffSCTP ( IPBuff + wPackLen ); + MTP3_HAEDER_LEN = uAnsiFlag ? MTP3_HAEDER_ANSI_LEN : MTP3_HAEDER_ITU_LEN; + wM2uaLen = NcStuffM2UA ( IPBuff + wPackLen, wSccpLen + MTP3_HAEDER_LEN ); + wPackLen += wM2uaLen; + + wPackLen += + NcStuffMtp3 ( IPBuff + wPackLen, pIntra->DPC, pIntra->DPC, pIntra->SLS, + uAnsiFlag ); + memcpy ( IPBuff + wPackLen, pSccpMsg, wSccpLen ); + wPackLen += wSccpLen; + + uPad = ( IPBuff[SCTP_HEADER_LEN + 7] ) % 4; + uPad = uPad ? ( 4 - uPad ) : 0; + + for ( ; uPad > 0; uPad-- ) + { + IPBuff[SCTP_HEADER_LEN + 7]++; //m2ua msg len + IPBuff[wPackLen++] = 0x00; + } + + IPBuff[SCTP_CHUNKLEN_POS] = 0x10 + IPBuff[SCTP_HEADER_LEN + 7]; + + ad = NcCS ( IPBuff, wPackLen ); + + IPBuff[SCCTP_CS_POS] = ad & 0xFF; + IPBuff[SCCTP_CS_POS + 1] = ad / ( 256 ); + IPBuff[SCCTP_CS_POS + 2] = ad / ( 256 * 256 ); + IPBuff[SCCTP_CS_POS + 3] = ad / ( 256 * 256 * 256 ); + + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = htons ( tNC.nPort ); + sin_addr.sin_addr.s_addr = tNC.nDstIp; + + if ( sendto + ( tNC.nSock, ( char * ) IPBuff, wPackLen, 0, + ( struct sockaddr * ) &sin_addr, sizeof ( struct sockaddr ) ) < 0 ) + { + perror ( "SCCP send tNC error!\n" ); + return 0; + } + + //printf ( "\nSCCP Send Net cap message!\n " ); + //write(nSock, IPBuff, wPackLen); + return 1; +} + +/* + #define SCCP_RLSE_LEN 0x0a + + static u8 SCCP_RLSD[ ] = + { + 0x04, 0x01, 0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x01, + 0x00 + }; + + void main() + { + int i; + + NcInit(); + NcStart(inet_addr("10.167.144.35") , 8000 ); + for( i = 0 ; i < 5000 ; i ++ ) + { + sleep(1); + NcSccpSend( SCCP_RLSD , SCCP_RLSE_LEN ); + } + NcStop(); + return ; + } + */ +/*@end@*/ diff --git a/plat/public/src/pub_sdp.c b/plat/public/src/pub_sdp.c new file mode 100644 index 0000000..0a3a643 --- /dev/null +++ b/plat/public/src/pub_sdp.c @@ -0,0 +1,3560 @@ +#include +#include +#include "./include/public.h" +#include "./include/pub_sdp.h" + +/*@ignore@*/ +void pub_replace_all_lws(char *msg) +{ + char *tmp; + + if (msg == NULL) + return; + tmp = msg; + + for (; tmp[0] != '\0'; tmp++) + { + if (('\0' == tmp[0]) || ('\0' == tmp[1]) || + ('\0' == tmp[2]) || ('\0' == tmp[3])) + return; + + if ((('\r' == tmp[0]) && ('\n' == tmp[1]) && + ('\r' == tmp[2]) && ('\n' == tmp[3])) || + (('\r' == tmp[0]) && ('\r' == tmp[1])) || + (('\n' == tmp[0]) && ('\n' == tmp[1]))) + return; + + if ((('\r' == tmp[0]) && ('\n' == tmp[1]) && + ((' ' == tmp[2]) || ('\t' == tmp[2]))) || + (('\r' == tmp[0]) && + ((' ' == tmp[1]) || ('\t' == tmp[1]))) || + (('\n' == tmp[0]) && + ((' ' == tmp[1]) || ('\t' == tmp[1])))) + { + // Replace line end and TAB symbols by SP + tmp[0] = ' '; + tmp[1] = ' '; + tmp = tmp + 2; + // Replace all following TAB symbols + for (; ('\t' == tmp[0] || ' ' == tmp[0]); ) + { + tmp[0] = ' '; + tmp++; + } + } + } +} + +char *pub_strncpy(char *dest, const char *src, WORD length) +{ + strncpy(dest, src, length); + dest[length] = '\0'; + return dest; +} + +int pub_set_next_token(char *dest, char *buf, int endSeparator, char **next) +{ + char *sep; // separator + + *next = NULL; + + sep = buf; + while ((*sep != endSeparator) && (*sep != '\0') && (*sep != '\r') + && (*sep != '\n')) + sep++; + if ((*sep == '\r') || (*sep == '\n')) + { // we should continue normally only if this is the separator asked! + if (*sep != endSeparator) + return -1; + } + if ((*sep == '\0') && (*sep != endSeparator)) // modify by megaco + return -1; // value must not end with this separator! + if (sep == buf) + return -1; // empty value (or several space!) + + pub_strncpy(dest, buf, sep - buf); + + *next = sep + 1; // return the position right after the separator + + return 0; +} + +int pub_sdp_msg_init(PUB_SDP_MSG *sdp) +{ + if (sdp == NULL) + return -1; + + memset((BYTE *)sdp, 0, sizeof(PUB_SDP_MSG)); + + return 0; +} + +int pub_sdp_net_type_conv(char *str, BYTE *netType, BYTE flag) +{ + if (flag == PUB_SDP_STR_TO_API) + { + if (strncmp(str, "IN", 2) == 0) + *netType = PUB_SDP_NET_TYPE_IN; + return 0; + } + else + { + switch (*netType) + { + case PUB_SDP_NET_TYPE_IN: + strcpy(str, "IN"); + break; + default: + return -1; + } + return 0; + } + + return -1; +} + +int pub_sdp_addr_type_conv(char *str, BYTE *addrType, BYTE flag) +{ + if (flag == PUB_SDP_STR_TO_API) + { + if (strncmp(str, "IP4", 3) == 0) + *addrType = PUB_SDP_ADDR_TYPE_IPV4; + return 0; + } + else + { + switch (*addrType) + { + case PUB_SDP_ADDR_TYPE_IPV4: + strcpy(str, "IP4"); + break; + default: + return -1; + } + return 0; + } + + return -1; +} + +int pub_sdp_attr_type_conv(char *str, BYTE *attrType, BYTE flag) +{ + int ret = 0; + + if (flag == PUB_SDP_STR_TO_API) + { + if (strncmp(str, "rtpmap", 6) == 0) + *attrType = PUB_SDP_ATTR_TYPE_RTPMAP; + else if (strncmp(str, "ptime", 5) == 0) + *attrType = PUB_SDP_ATTR_TYPE_PTIME; + else if (strncmp(str, "fmtp", 4) == 0) + *attrType = PUB_SDP_ATTR_TYPE_FMTP; + else if (strncmp(str, "T38FaxVersion", 13) == 0) + *attrType = PUB_SDP_ATTR_TYPE_T38VER; + else if (strncmp(str, "T38MaxBitRate", 13) == 0) + *attrType = PUB_SDP_ATTR_TYPE_T38MBR; + else if (strncmp(str, "ipbcp", 5) == 0) + *attrType = PUB_SDP_ATTR_TYPE_IPBCP; + else + { + ret = -2; + } + return ret; + } + else + { + switch (*attrType) + { + case PUB_SDP_ATTR_TYPE_RTPMAP: + strcpy(str, "rtpmap"); + break; + case PUB_SDP_ATTR_TYPE_PTIME: + strcpy(str, "ptime"); + break; + case PUB_SDP_ATTR_TYPE_FMTP: + strcpy(str, "fmtp"); + break; + case PUB_SDP_ATTR_TYPE_T38VER: + strcpy(str, "T38FaxVersion"); + break; + case PUB_SDP_ATTR_TYPE_T38MBR: + strcpy(str, "T38MaxBitRate"); + break; + case PUB_SDP_ATTR_TYPE_IPBCP: + strcpy(str, "ipbcp"); + break; + default: + return -2; + } + return 0; + } + + return -1; +} + +int pub_sdp_media_type_conv(char *str, BYTE *mediaType, BYTE flag) +{ + if (flag == PUB_SDP_STR_TO_API) + { + if (strncmp(str, "audio", 6) == 0) + { + *mediaType = PUB_SDP_MEDIA_TYPE_AUDIO; + return 0; + } + else if (strncmp(str, "video", 6) == 0) + { + *mediaType = PUB_SDP_MEDIA_TYPE_VIDEO; + return 0; + } + else if (strncmp(str, "image", 6) == 0) + { + *mediaType = PUB_SDP_MEDIA_TYPE_IMAGE; + return 0; + } + else + return -2; + } + else + { + switch (*mediaType) + { + case PUB_SDP_MEDIA_TYPE_AUDIO: + strcpy(str, "audio"); + break; + case PUB_SDP_MEDIA_TYPE_VIDEO: + strcpy(str, "video"); + break; + case PUB_SDP_MEDIA_TYPE_IMAGE: + strcpy(str, "image"); + break; + default: + return -1; + } + return 0; + } + + return -1; +} + +int pub_sdp_proto_type_conv(char *str, BYTE *protoType, BYTE flag) +{ + if (flag == PUB_SDP_STR_TO_API) + { + if (strncmp(str, "RTP/AVP", 7) == 0) + *protoType = PUB_SDP_PROTO_TYPE_RTP_AVP; + else if (strncmp(str, "udptl", 5) == 0) + { + *protoType = PUB_SDP_PROTO_TYPE_IMAGE_UDPTL; + return -2; + } + + return 0; + } + else + { + switch (*protoType) + { + case PUB_SDP_PROTO_TYPE_RTP_AVP: + strcpy(str, "RTP/AVP"); + break; + case PUB_SDP_PROTO_TYPE_IMAGE_UDPTL: + strcpy(str, "udptl t38"); + break; + default: + return -1; + } + return 0; + } + + return -1; +} + +int pub_sdp_parse_v(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char value[8]; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + if (equal == buf) + return -1; + + // check if header is "v" + if (equal[-1] != 'v') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V) + { + pub_strncpy(value, equal + 1, crlf - (equal + 1)); + sdp->v.value = atoi(value); + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("v: %d\n", sdp->v.value); + + sdp->flag |= PUB_SDP_FLAG_V; + + return 0; +} + +int pub_sdp_parse_o(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + int i; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "o" + if (equal[-1] != 'o') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; /* o=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V) + { + tmp = equal + 1; + // o=username sess-id sess-version nettype addrtype addr + // useranme can contain any char (ascii) except "space" and CRLF + if (pub_set_next_token(sdp->o.userName, tmp, ' ', &tmpNext) < 0) + return -1; + tmp = tmpNext; + + // sess_id contains only numeric characters + if (pub_set_next_token(sdp->o.sessId, tmp, ' ', &tmpNext) < 0) + return -1; + tmp = tmpNext; + + // sess_version contains only numeric characters + if (pub_set_next_token (sdp->o.sessVer, tmp, ' ', &tmpNext) < 0) + return -1; + tmp = tmpNext; + + // nettype is "IN" but will surely be extented!!! assume it's some alpha-char + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_net_type_conv(value, &sdp->o.netType, PUB_SDP_STR_TO_API) < 0) + return -1; + tmp = tmpNext; + + // addrtype is "IP4" or "IP6" but will surely be extented!!! + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_addr_type_conv(value, &sdp->o.addrType, PUB_SDP_STR_TO_API) < 0) + return -1; + tmp = tmpNext; + + // addr is "IP4" or "IP6" but will surely be extented!!! + i = pub_set_next_token(sdp->o.addr, tmp, '\r', &tmpNext); + if (i != 0) + { /* could it be "\n" only??? rfc says to accept CR or LF instead of CRLF */ + if (pub_set_next_token(sdp->o.addr, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("o: %s, %s, %s, %d, %d, %s\n", sdp->o.userName, sdp->o.sessId, sdp->o.sessVer, sdp->o.netType, sdp->o.addrType, sdp->o.addr); + + sdp->flag |= PUB_SDP_FLAG_O; + + return 0; +} + +int pub_sdp_parse_s(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "s" + if (equal[-1] != 's') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // o=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_S) == PUB_SDP_FLAG_S) + pub_strncpy(sdp->s.sessName, equal + 1, crlf - (equal + 1)); + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("s: %s\n", sdp->s.sessName); + + sdp->flag |= PUB_SDP_FLAG_S; + + return 0; +} + +int pub_sdp_parse_i(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "i" + if (equal[-1] != 'i') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // o=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_I) == PUB_SDP_FLAG_I) + pub_strncpy(sdp->i.info, equal + 1, crlf - (equal + 1)); + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("i: %s\n", sdp->i.info); + + if (sdp->medias.num == 0) + sdp->flag |= PUB_SDP_FLAG_I; + else + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_I; + + return 0; +} + +int pub_sdp_parse_u(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "u" + if (equal[-1] != 'u') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_e(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "e" + if (equal[-1] != 'e') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_p(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "p" + if (equal[-1] != 'p') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_c(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + char *slash; + PUB_SDP_C *cHeader; + int i; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "c" + if (equal[-1] != 'c') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // c=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C) + { + tmp = equal + 1; + + // c=nettype addrtype (multicastaddr | addr) + + // nettype is "IN" and will be extended + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_net_type_conv(value, &sdp->c.netType, PUB_SDP_STR_TO_API) < 0) + return -1; + tmp = tmpNext; + + // nettype is "IP4" or "IP6" and will be extended + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_addr_type_conv(value, &sdp->c.addrType, PUB_SDP_STR_TO_API) < 0) + return -1; + tmp = tmpNext; + + /* there we have a multicast or unicast address */ + /* multicast can be ip/ttl [/integer] */ + /* unicast is FQDN or ip (no ttl, no integer) */ + + slash = strchr (tmp, '/'); + cHeader = &sdp->c; + + if (slash != NULL && slash < crlf) // it's a multicast address! + { + // Not supported for the moment + } + else + { + // in this case, we have a unicast address + i = pub_set_next_token(cHeader->addr, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(cHeader->addr, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("c: %d, %d, %s\n", sdp->c.netType, sdp->c.addrType, sdp->c.addr); + + if (sdp->medias.num == 0) + sdp->flag |= PUB_SDP_FLAG_C; + else + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_C; + + return 0; +} + +int pub_sdp_parse_m_c(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + char *slash; + PUB_SDP_C *cHeader; + int i; + + *next = buf; + equal = buf; + + if (sdp->medias.num == 0) + return -1; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "c" + if (equal[-1] != 'c') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // c=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C) + { + tmp = equal + 1; + + // c=nettype addrtype (multicastaddr | addr) + + // nettype is "IN" and will be extended + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_net_type_conv(value, &sdp->medias.medias[sdp->medias.num - 1].c.netType, PUB_SDP_STR_TO_API) < 0) + return -1; + tmp = tmpNext; + + // nettype is "IP4" or "IP6" and will be extended + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_addr_type_conv(value, &sdp->medias.medias[sdp->medias.num - 1].c.addrType, PUB_SDP_STR_TO_API) < 0) + return -1; + tmp = tmpNext; + + /* there we have a multicast or unicast address */ + /* multicast can be ip/ttl [/integer] */ + /* unicast is FQDN or ip (no ttl, no integer) */ + + slash = strchr (tmp, '/'); + cHeader = &sdp->medias.medias[sdp->medias.num - 1].c; + + if (slash != NULL && slash < crlf) // it's a multicast address! + { + // Not supported for the moment + } + else + { + // in this case, we have a unicast address + i = pub_set_next_token(cHeader->addr, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(cHeader->addr, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("c: %d, %d, %s\n", sdp->c.netType, sdp->c.addrType, sdp->c.addr); + + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_C; + + return 0; +} + +int pub_sdp_parse_b(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "b" + if (equal[-1] != 'b') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_t(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + int i; + PUB_SDP_T *tHeader; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "t" + if (equal[-1] != 't') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; /* t=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_T) == PUB_SDP_FLAG_T) + { + tmp = equal + 1; + // t = start_time stop_time + tHeader = &sdp->t; + + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + tHeader->startTime = atoi(value); + tmp = tmpNext; + + i = pub_set_next_token(value, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(value, tmp, '\n', &tmpNext) < 0) + return -1; + tHeader->stopTime = atoi(value); + } + else + { + tHeader->stopTime = atoi(value); + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("t: %ld, %ld\n", sdp->t.startTime, sdp->t.stopTime); + + sdp->flag |= PUB_SDP_FLAG_T; + + return 0; +} + +int pub_sdp_parse_r(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "r" + if (equal[-1] != 'r') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_z(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "z" + if (equal[-1] != 'z') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_k(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "k" + if (equal[-1] != 'k') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_a(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[32]; + int i, ret; + //BYTE num, mediaNum; + PUB_SDP_A *a; + char *colon; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "a" + if (equal[-1] != 'a') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; /* a=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + tmp = equal + 1; + a = &sdp->a; + // a=att-field[:att-value] + + // is there any att-value? + colon = strchr (equal + 1, ':'); + if ((colon != NULL) && (colon < crlf)) + { + // att-field is alpha-numeric + if (pub_set_next_token(value, tmp, ':', &tmpNext) < 0) + return -1; + if ((ret = pub_sdp_attr_type_conv(value, &a->aType, PUB_SDP_STR_TO_API)) == -1) + return -1; + else if (ret == -2) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + return 0; + } + tmp = tmpNext; + + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + else + { + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + sdp->medias.medias[sdp->medias.num - 1].attrs.num++; + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("a: %d, %s\n", a->aType, a->aValue); + + sdp->flag |= PUB_SDP_FLAG_A; + + return 0; +} + +int pub_sdp_parse_m(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[32]; + int i; + PUB_SDP_M *mHeader; + BYTE num; + char *slash; + char *space; + int moreSpace; + int ret; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "m" + if (equal[-1] != 'm') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; /* a=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_M) == PUB_SDP_FLAG_M) + { + tmp = equal + 1; + num = sdp->medias.num; + mHeader = &sdp->medias.medias[num].m; + // m=media port ["/"integer] proto *(payload_number) + // media is "audio" "video" "application" "data" or other... + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + if ((ret = pub_sdp_media_type_conv(value, &mHeader->media, PUB_SDP_STR_TO_API)) < 0) + { + if (-2 == ret) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; + } + + return -1; + } + tmp = tmpNext; + + slash = strchr (tmp, '/'); + space = strchr (tmp, ' '); + if ((slash != NULL) && (slash < space)) + { /* a number of port is specified! */ + if (pub_set_next_token(value, tmp, '/', &tmpNext) < 0) + return -1; + mHeader->port = atoi(value); + tmp = tmpNext; + + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + mHeader->portNum = atoi(value); + tmp = tmpNext; + } + else + { + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + mHeader->port = atoi(value); + tmp = tmpNext; + } + + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + if ((ret = pub_sdp_proto_type_conv(value, &mHeader->proto, PUB_SDP_STR_TO_API)) < 0) + { + if (ret == -2) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + sdp->medias.medias[sdp->medias.num].flag |= PUB_SDP_FLAG_M; + sdp->flag |= PUB_SDP_FLAG_M; + sdp->medias.num++; + + return 0; + } + + return -1; + } + + tmp = tmpNext; + + space = strchr(tmp + 1, ' '); + if (space == NULL) + moreSpace = 1; + else if ((space != NULL) && (space > crlf)) + moreSpace = 1; + else + moreSpace = 0; + while(moreSpace == 0) + { + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + mHeader->payloads[mHeader->plNum++] = atoi(value); + tmp = tmpNext; + + space = strchr(tmp + 1, ' '); + if (space == NULL) + moreSpace = 1; + else if ((space != NULL) && (space > crlf)) + moreSpace = 1; + else + moreSpace = 0; + } + if (tmpNext < crlf) + { // tmpNext is still less than clrf: no space + i = pub_set_next_token(value, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(value, tmp, '\n', &tmpNext) < 0) + return -1; + } + mHeader->payloads[mHeader->plNum++] = atoi(value); + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("m: %d, %d, %d, %d, %d, %d, %d\n", mHeader->media, mHeader->port, mHeader->portNum, mHeader->proto, mHeader->plNum, mHeader->payloads[0], mHeader->payloads[1]); + + sdp->medias.medias[sdp->medias.num].flag |= PUB_SDP_FLAG_M; + sdp->flag |= PUB_SDP_FLAG_M; + sdp->medias.num++; + + return 0; +} + +int pub_sdp_parse_m_a(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[32]; + int i, ret; + BYTE num, mediaNum; + PUB_SDP_A *a; + char *colon; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "a" + if (equal[-1] != 'a') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + if (crlf == equal + 1) + return -1; /* a=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + tmp = equal + 1; + mediaNum = sdp->medias.num; + num = sdp->medias.medias[mediaNum - 1].attrs.num; + a = &sdp->medias.medias[mediaNum - 1].attrs.attrs[num]; + + // a=att-field[:att-value] + + // is there any att-value? + colon = strchr (equal + 1, ':'); + if ((colon != NULL) && (colon < crlf)) + { + // att-field is alpha-numeric + if (pub_set_next_token(value, tmp, ':', &tmpNext) < 0) + return -1; + if ((ret = pub_sdp_attr_type_conv(value, &a->aType, PUB_SDP_STR_TO_API)) == -1) + return -1; + else if (ret == -2) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + return 0; + } + tmp = tmpNext; + + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + else + { + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + sdp->medias.medias[sdp->medias.num - 1].attrs.num++; + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("a: %d, %s\n", a->aType, a->aValue); + + if (sdp->medias.num == 0) + sdp->flag |= PUB_SDP_FLAG_A; + else + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_A; + + return 0; +} + +int pub_sdp_check_ending(char *ptr, char **nextbuf) +{ + *nextbuf = ptr; + + if ((*ptr == '\0') || (*ptr == '\r') || (*ptr == '\n')) + { + return 0; + } + else if (((ptr[0] == '.') && (ptr[1] == '\r') && (ptr[2] == '\n'))) + { + *nextbuf = ptr + 3; + return 1; + } + else + return -1; +} + +int pub_sdp_parse(PUB_SDP_MSG *sdp, char *buf, char **nextMsg, DWORD flag) +{ + // In SDP, headers must be in the right order + /* This is a simple example + v=0 + o=user1 53655765 2353687637 IN IP4 128.3.4.5 + s=Mbone Audio + i=Discussion of Mbone Engineering Issues + e=mbone@somewhere.com + c=IN IP4 224.2.0.1/127 + t=0 0 + m=audio 3456 RTP/AVP 0 + a=rtpmap:0 PCMU/8000 + */ + + char *nextBuf; + char *ptr; + int i; + int ret; + int moreHeader = 1; + + pub_sdp_msg_init(sdp); + + ptr = (char *) buf; + + // mandatory + if (pub_sdp_parse_v(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // mandatory + if (pub_sdp_parse_o(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // mandatory + if (pub_sdp_parse_s(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + if (pub_sdp_parse_i(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + if (pub_sdp_parse_u(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_e(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + ptr = nextBuf; + } + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_p(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_c(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_b(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + ptr = nextBuf; + } + + // mandatory + if (pub_sdp_parse_t(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + + ptr = nextBuf; + + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_r(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_t(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + while (moreHeader == 1) + { + i = 0; + while (i == 0) // is a "r" header + { + if ((i = pub_sdp_parse_r(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + if ((i = pub_sdp_parse_t(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + else if (i == -2) + moreHeader = 0; // no more "t" headers + else + moreHeader = 1; + + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_z(sdp, ptr, &nextBuf, flag) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + if (pub_sdp_parse_k(sdp, ptr, &nextBuf, flag) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + // 0 or more "a" header + i = 0; + while (i == 0) // no more "a" header + { + if ((i = pub_sdp_parse_a(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + moreHeader = 0; + while (moreHeader == 0) + { + // optional + if ((moreHeader = pub_sdp_parse_m(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + else if (moreHeader == -2) + break; + + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + if (pub_sdp_parse_i (sdp, ptr, &nextBuf, flag) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_m_c(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_b(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_k(sdp, ptr, &nextBuf, flag) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_m_a(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + } + + return 0; +} + + +//parse sdp for megaco + +int pub_sdp_parse_find_end_for_megaco(char *start, char **end) +{ + int get_char_times = 0; + char *temp = start; + char *ending; + char *equal; + + if ((equal = strchr(temp, '=')) == NULL) + { + while (*temp != '\0') + temp++; + + do + { + temp--; + } + while (*temp == ' '); + + *end = temp + 1; + } + else + { + if (*(equal - 2) != ' ') + { + if ((equal = strchr(equal + 1, '=')) == NULL) + { + while (*equal!= '\0') + equal++; + + do + { + equal--; + } + while (*equal == ' '); + + *end = equal + 1; + + return 0; + } + } + + ending = equal; + + for (;;) + { + ending--; + + if (*ending != ' ') + { + get_char_times++; + + if (get_char_times == 1) + ending--; + } + + if (get_char_times == 2) + break; + + if (ending < start) + break; + + } + + if (ending < start) + return -1; + else + *end = ending + 1; + } + + return 0; +} + +int pub_sdp_parse_v_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char value[8]; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + if (equal == buf) + return -1; + + // check if header is "v" + if (equal[-1] != 'v') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V) + { + pub_strncpy(value, equal + 1, crlf - (equal + 1)); + sdp->v.value = atoi(value); + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("v: %d\n", sdp->v.value); + + sdp->flag |= PUB_SDP_FLAG_V; + + return 0; +} + +int pub_sdp_parse_o_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + int i; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + if (*equal == '\0') + return -1; + + // check if header is "o" + if (equal[-1] != 'o') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; /* o=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V) + { + tmp = equal + 1; + // o=username sess-id sess-version nettype addrtype addr + // useranme can contain any char (ascii) except "space" and CRLF + if (pub_set_next_token(sdp->o.userName, tmp, ' ', &tmpNext) < 0) + return -1; + + tmp = tmpNext; + + // sess_id contains only numeric characters + if (pub_set_next_token(sdp->o.sessId, tmp, ' ', &tmpNext) < 0) + return -1; + + tmp = tmpNext; + + // sess_version contains only numeric characters + if (pub_set_next_token (sdp->o.sessVer, tmp, ' ', &tmpNext) < 0) + return -1; + + tmp = tmpNext; + + // nettype is "IN" but will surely be extented!!! assume it's some alpha-char + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_net_type_conv(value, &sdp->o.netType, PUB_SDP_STR_TO_API) < 0) + return -1; + + tmp = tmpNext; + + // addrtype is "IP4" or "IP6" but will surely be extented!!! + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + if (pub_sdp_addr_type_conv(value, &sdp->o.addrType, PUB_SDP_STR_TO_API) < 0) + return -1; + + tmp = tmpNext; + + // addr is "IP4" or "IP6" but will surely be extented!!! + i = pub_set_next_token(sdp->o.addr, tmp, '\r', &tmpNext); + if (i != 0) + { /* could it be "\n" only??? rfc says to accept CR or LF instead of CRLF */ + if (pub_set_next_token(sdp->o.addr, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("o: %s, %s, %s, %d, %d, %s\n", sdp->o.userName, sdp->o.sessId, sdp->o.sessVer, sdp->o.netType, sdp->o.addrType, sdp->o.addr); + + sdp->flag |= PUB_SDP_FLAG_O; + + return 0; +} + +int pub_sdp_parse_s_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "s" + if (equal[-1] != 's') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // o=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_S) == PUB_SDP_FLAG_S) + pub_strncpy(sdp->s.sessName, equal + 1, crlf - (equal + 1)); + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("s: %s\n", sdp->s.sessName); + + sdp->flag |= PUB_SDP_FLAG_S; + + return 0; +} + +int pub_sdp_parse_i_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "i" + if (equal[-1] != 'i') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // o=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_I) == PUB_SDP_FLAG_I) + pub_strncpy(sdp->i.info, equal + 1, crlf - (equal + 1)); + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("i: %s\n", sdp->i.info); + + if (sdp->medias.num == 0) + sdp->flag |= PUB_SDP_FLAG_I; + else + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_I; + + + return 0; +} + +int pub_sdp_parse_u_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "u" + if (equal[-1] != 'u') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_e_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "e" + if (equal[-1] != 'e') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_p_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "p" + if (equal[-1] != 'p') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_c_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + char *slash; + PUB_SDP_C *cHeader; + int i; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "c" + if (equal[-1] != 'c') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // c=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C) + { + tmp = equal + 1; + + // c=nettype addrtype (multicastaddr | addr) + // nettype is "IN" and will be extended + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + + if (pub_sdp_net_type_conv(value, &sdp->c.netType, PUB_SDP_STR_TO_API) < 0) + return -1; + + tmp = tmpNext; + + // nettype is "IP4" or "IP6" and will be extended + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + if (pub_sdp_addr_type_conv(value, &sdp->c.addrType, PUB_SDP_STR_TO_API) < 0) + return -1; + + tmp = tmpNext; + + /* there we have a multicast or unicast address */ + /* multicast can be ip/ttl [/integer] */ + /* unicast is FQDN or ip (no ttl, no integer) */ + + slash = strchr (tmp, '/'); + cHeader = &sdp->c; + + if (slash != NULL && slash < crlf) // it's a multicast address! + { + // Not supported for the moment + } + else + { + // in this case, we have a unicast address + i = pub_set_next_token(cHeader->addr, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(cHeader->addr, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("c: %d, %d, %s\n", sdp->c.netType, sdp->c.addrType, sdp->c.addr); + + if (sdp->medias.num == 0) + sdp->flag |= PUB_SDP_FLAG_C; + else + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_C; + + return 0; +} + +int pub_sdp_parse_m_c_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + char *slash; + PUB_SDP_C *cHeader; + int i; + + *next = buf; + equal = buf; + + if (sdp->medias.num == 0) + return -1; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "c" + if (equal[-1] != 'c') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // c=\r ?? bad header + + if ((flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C) + { + tmp = equal + 1; + + // c=nettype addrtype (multicastaddr | addr) + + // nettype is "IN" and will be extended + if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0) + return -1; + + if (pub_sdp_net_type_conv(value, &sdp->medias.medias[sdp->medias.num - 1].c.netType, PUB_SDP_STR_TO_API) < 0) + return -1; + + tmp = tmpNext; + + // nettype is "IP4" or "IP6" and will be extended + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + if (pub_sdp_addr_type_conv(value, &sdp->medias.medias[sdp->medias.num - 1].c.addrType, PUB_SDP_STR_TO_API) < 0) + return -1; + + tmp = tmpNext; + + /* there we have a multicast or unicast address */ + /* multicast can be ip/ttl [/integer] */ + /* unicast is FQDN or ip (no ttl, no integer) */ + + slash = strchr (tmp, '/'); + cHeader = &sdp->medias.medias[sdp->medias.num - 1].c; + + if (slash != NULL && slash < crlf) // it's a multicast address! + { + // Not supported for the moment + } + else + { + // in this case, we have a unicast address + i = pub_set_next_token(cHeader->addr, tmp, '\r', &tmpNext); + if (i != 0) + { + if (pub_set_next_token(cHeader->addr, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("c: %d, %d, %s\n", sdp->c.netType, sdp->c.addrType, sdp->c.addr); + + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_C; + + return 0; +} + +int pub_sdp_parse_b_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "b" + if (equal[-1] != 'b') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_t_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[16]; + int i; + PUB_SDP_T *tHeader; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "t" + if (equal[-1] != 't') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; /* t=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_T) == PUB_SDP_FLAG_T) + { + tmp = equal + 1; + // t = start_time stop_time + tHeader = &sdp->t; + + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + tHeader->startTime = atoi(value); + tmp = tmpNext; + + i = pub_set_next_token(value, tmp, '\r', &tmpNext); + + if (i != 0) + { + if (pub_set_next_token(value, tmp, '\n', &tmpNext) < 0) + return -1; + + tHeader->stopTime = atoi(value); + } + else + { + tHeader->stopTime = atoi(value); + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("t: %ld, %ld\n", sdp->t.startTime, sdp->t.stopTime); + + sdp->flag |= PUB_SDP_FLAG_T; + + return 0; +} + +int pub_sdp_parse_r_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "r" + if (equal[-1] != 'r') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_z_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "z" + if (equal[-1] != 'z') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_k_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "k" + if (equal[-1] != 'k') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; // v=\r ?? bad header + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; +} + +int pub_sdp_parse_a_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[32]; + int i, ret; + PUB_SDP_A *a; + char *colon; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "a" + if (equal[-1] != 'a') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; /* a=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + tmp = equal + 1; + a = &sdp->a; + // a=att-field[:att-value] + + // is there any att-value? + colon = strchr (equal + 1, ':'); + + if ((colon != NULL) && (colon < crlf)) + { + // att-field is alpha-numeric + if (pub_set_next_token(value, tmp, ':', &tmpNext) < 0) + return -1; + + if ((ret = pub_sdp_attr_type_conv(value, &a->aType, PUB_SDP_STR_TO_API)) == -1) + return -1; + else if (ret == -2) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; + } + + tmp = tmpNext; + + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + else + { + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + + sdp->medias.medias[sdp->medias.num - 1].attrs.num++; + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("a: %d, %s\n", a->aType, a->aValue); + + sdp->flag |= PUB_SDP_FLAG_A; + + return 0; +} + +int pub_sdp_parse_m_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[32]; + int i; + PUB_SDP_M *mHeader; + BYTE num; + char *slash; + char *space; + int moreSpace; + int ret; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "m" + if (equal[-1] != 'm') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; /* a=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_M) == PUB_SDP_FLAG_M) + { + tmp = equal + 1; + num = sdp->medias.num; + mHeader = &sdp->medias.medias[num].m; + // m=media port ["/"integer] proto *(payload_number) + // media is "audio" "video" "application" "data" or other... + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + if ((ret = pub_sdp_media_type_conv(value, &mHeader->media, PUB_SDP_STR_TO_API)) < 0) + { + if (-2 == ret) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; + } + + return -1; + } + tmp = tmpNext; + + slash = strchr (tmp, '/'); + space = strchr (tmp, ' '); + + if ((slash != NULL) && (slash < space)) + { /* a number of port is specified! */ + if (pub_set_next_token(value, tmp, '/', &tmpNext) < 0) + return -1; + + if (strcmp(value, "$") == 0) + { + mHeader->port = PUB_SDP_M_PORT_CHOOSE; + } + else + { + mHeader->port = atoi(value); + } + + tmp = tmpNext; + + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + mHeader->portNum = atoi(value); + + tmp = tmpNext; + } + else + { + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + if (strcmp(value, "$") == 0) + { + mHeader->port = PUB_SDP_M_PORT_CHOOSE; + } + else + { + mHeader->port = atoi(value); + } + + tmp = tmpNext; + } + + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + if ((ret = pub_sdp_proto_type_conv(value, &mHeader->proto, PUB_SDP_STR_TO_API)) < 0) + { + if (ret == -2) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + sdp->medias.medias[sdp->medias.num].flag |= PUB_SDP_FLAG_M; + sdp->flag |= PUB_SDP_FLAG_M; + sdp->medias.num++; + + return 0; + } + + return -1; + } + + tmp = tmpNext; + + space = strchr(tmp + 1, ' '); + + if (space == NULL) + moreSpace = 1; + else if ((space != NULL) && (space > crlf)) + moreSpace = 1; + else + moreSpace = 0; + + while(moreSpace == 0) + { + if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0) + return -1; + + mHeader->payloads[mHeader->plNum++] = atoi(value); + tmp = tmpNext; + + space = strchr(tmp + 1, ' '); + + if (space == NULL) + moreSpace = 1; + else if ((space != NULL) && (space > crlf)) + moreSpace = 1; + else + moreSpace = 0; + } + + if (tmpNext < crlf) + { // tmpNext is still less than clrf: no space + i = pub_set_next_token(value, tmp, '\r', &tmpNext); + + if (i != 0) + { + if (pub_set_next_token(value, tmp, '\n', &tmpNext) < 0) + return -1; + } + mHeader->payloads[mHeader->plNum++] = atoi(value); + } + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("m: %d, %d, %d, %d, %d, %d, %d\n", mHeader->media, mHeader->port, mHeader->portNum, mHeader->proto, mHeader->plNum, mHeader->payloads[0], mHeader->payloads[1]); + + sdp->medias.medias[sdp->medias.num].flag |= PUB_SDP_FLAG_M; + sdp->flag |= PUB_SDP_FLAG_M; + sdp->medias.num++; + + return 0;} + +int pub_sdp_parse_m_a_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag) +{ + char *equal; + char *crlf; + char *tmp; + char *tmpNext; + char value[32]; + int i, ret; + BYTE num, mediaNum; + PUB_SDP_A *a; + char *colon; + + *next = buf; + equal = buf; + + while ((*equal != '=') && (*equal != '\0')) + equal++; + + if (*equal == '\0') + return -1; + + // check if header is "a" + if (equal[-1] != 'a') + return -2; + + crlf = equal + 1; + + while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) + crlf++; + + if (*crlf == '\0') + return -1; + + if (crlf == equal + 1) + return -1; /* a=\r ?? bad header */ + + if ((flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + tmp = equal + 1; + mediaNum = sdp->medias.num; + num = sdp->medias.medias[mediaNum - 1].attrs.num; + a = &sdp->medias.medias[mediaNum - 1].attrs.attrs[num]; + + // a=att-field[:att-value] + + // is there any att-value? + colon = strchr (equal + 1, ':'); + + if ((colon != NULL) && (colon < crlf)) + { + // att-field is alpha-numeric + if (pub_set_next_token(value, tmp, ':', &tmpNext) < 0) + return -1; + + if ((ret = pub_sdp_attr_type_conv(value, &a->aType, PUB_SDP_STR_TO_API)) == -1) + return -1; + else if (ret == -2) + { + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + + return 0; + } + + tmp = tmpNext; + + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + else + { + i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext); + + if (i != 0) + { + if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0) + return -1; + } + } + + sdp->medias.medias[sdp->medias.num - 1].attrs.num++; + } + + if (crlf[1] == '\n') + *next = crlf + 2; + else + *next = crlf + 1; + +// printf("a: %d, %s\n", a->aType, a->aValue); + + if (sdp->medias.num == 0) + sdp->flag |= PUB_SDP_FLAG_A; + else + sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_A; + + return 0; +} + +int pub_sdp_check_ending_for_megaco(char *ptr, char **nextbuf) +{ + *nextbuf = ptr; + + if ((*ptr == '\0') || (*ptr == '\r') || (*ptr == '\n')) + { + return 0; + } + else if (((ptr[0] == '.') && (ptr[1] == '\r') && (ptr[2] == '\n'))) + { + *nextbuf = ptr + 3; + return 1; + } + else + return -1; +} + +int pub_sdp_parse_for_megaco(PUB_SDP_MSG *sdp, char *buf, char **nextMsg, DWORD flag) +{ + // In SDP, headers must be in the right order + /* This is a simple example + v=0 + o=user1 53655765 2353687637 IN IP4 128.3.4.5 + s=Mbone Audio + i=Discussion of Mbone Engineering Issues + e=mbone@somewhere.com + c=IN IP4 224.2.0.1/127 + t=0 0 + m=audio 3456 RTP/AVP 0 + a=rtpmap:0 PCMU/8000 + */ + + char *nextBuf; + char *ptr; + int i; + int ret; + int moreHeader = 1; + + pub_sdp_msg_init(sdp); + + ptr = (char *)buf; + + // mandatory + if (pub_sdp_parse_v_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // mandatory + if (pub_sdp_parse_o_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // mandatory + if (pub_sdp_parse_s_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + if (pub_sdp_parse_i_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + if (pub_sdp_parse_u_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_e_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + ptr = nextBuf; + } + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_p_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_c_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + ptr = nextBuf; + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_b_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + ptr = nextBuf; + } + + // mandatory + if (pub_sdp_parse_t_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + + ptr = nextBuf; + + // optional + i = 0; + while (i == 0) + { + if ((i = pub_sdp_parse_r_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_t_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + while (moreHeader == 1) + { + i = 0; + while (i == 0) // is a "r" header + { + if ((i = pub_sdp_parse_r_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + if ((i = pub_sdp_parse_t_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + else if (i == -2) + moreHeader = 0; // no more "t" headers + else + moreHeader = 1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_z_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + if (pub_sdp_parse_k_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + // 0 or more "a" header + i = 0; + while (i == 0) // no more "a" header + { + if ((i = pub_sdp_parse_a_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + moreHeader = 0; + while (moreHeader == 0) + { + // optional + if ((moreHeader = pub_sdp_parse_m_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + else if (moreHeader == -2) + break; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + if (pub_sdp_parse_i_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + i = 0; + + while (i == 0) + { + if ((i = pub_sdp_parse_m_c_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + i = 0; + + while (i == 0) + { + if ((i = pub_sdp_parse_b_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + + // optional + if (pub_sdp_parse_k_for_megaco(sdp, ptr, &nextBuf, flag) == -1) + return -1; + + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + + // optional + i = 0; + + while (i == 0) + { + if ((i = pub_sdp_parse_m_a_for_megaco(sdp, ptr, &nextBuf, flag)) == -1) + return -1; + if ((ret = pub_sdp_check_ending_for_megaco(nextBuf, &nextBuf)) >= 0) + { + *nextMsg = nextBuf; + return ret; + } + ptr = nextBuf; + } + } + + return 0; +} + +// SDP Encode + +int pub_sdp_encode_v(PUB_SDP_V *v, char *dest) +{ + sprintf(dest, "v=%d\r\n", v->value); + + return 0; +} + +int pub_sdp_encode_o(PUB_SDP_O *o, char *dest) +{ + char origin[128]; + char netType[8]; + char addrType[8]; + + if (pub_sdp_net_type_conv(netType, &o->netType, PUB_SDP_API_TO_STR) < 0) + return -1; + + if (pub_sdp_addr_type_conv(addrType, &o->addrType, PUB_SDP_API_TO_STR) < 0) + return -1; + + sprintf(origin, "o=%s %s %s %s %s %s\r\n", o->userName, o->sessId, o->sessVer, netType, addrType, o->addr); + + strcat(dest, origin); + + return 0; +} + +int pub_sdp_encode_s(PUB_SDP_S *s, char *dest) +{ + char sess[64]; + + sprintf(sess, "s=%s\r\n", s->sessName); + + strcat(dest, sess); + + return 0; +} + +int pub_sdp_encode_i(PUB_SDP_I *i, char *dest) +{ + char info[64]; + + sprintf(info, "i=%s\r\n", i->info); + + strcat(dest, info); + + return 0; +} + +int pub_sdp_encode_c(PUB_SDP_C *c, char *dest) +{ + char conn[128]; + char netType[8]; + char addrType[8]; + + if (pub_sdp_net_type_conv(netType, &c->netType, PUB_SDP_API_TO_STR) < 0) + return -1; + + if (pub_sdp_addr_type_conv(addrType, &c->addrType, PUB_SDP_API_TO_STR) < 0) + return -1; + + sprintf(conn, "c=%s %s %s\r\n", netType, addrType, c->addr); + + strcat(dest, conn); + + return 0; +} + +int pub_sdp_encode_t(PUB_SDP_T *t, char *dest) +{ + char time[64]; + + sprintf(time, "t=%u %u\r\n", t->startTime, t->stopTime); + + strcat(dest, time); + + return 0; +} + +int pub_sdp_encode_m(PUB_SDP_M *m, char *dest, WORD flag) +{ + char media[128]; + char mediaType[8] = ""; + char proto[32]; + char payload[64]; + BYTE i; + + if (pub_sdp_media_type_conv(mediaType, &m->media, PUB_SDP_API_TO_STR) < 0) + return -1; + + if (pub_sdp_proto_type_conv(proto, &m->proto, PUB_SDP_API_TO_STR) < 0) + return -1; + + sprintf(media, "m=%s %d %s", mediaType, m->port, proto); + + if (m->proto == PUB_SDP_PROTO_TYPE_RTP_AVP) + { + if ((flag & PUB_MGCP_PARA_FLAG_TFO) == PUB_MGCP_PARA_FLAG_TFO) + { + sprintf(payload, " %d", 8); + strcat(media, payload); + } + + for (i = 0; i < m->plNum; i++) + { + if (i >= PUB_SDP_MAX_PAYLOAD_NUM) + break; + + sprintf(payload, " %d", m->payloads[i]); + strcat(media, payload); + } + } + strcat(media, "\r\n"); + + strcat(dest, media); + + return 0; +} + +int pub_sdp_encode_a(PUB_SDP_A *a, char *dest) +{ + char attr[128]; + char attrType[32]; + int ret; + + if ((ret = pub_sdp_attr_type_conv(attrType, &a->aType, PUB_SDP_API_TO_STR)) == -1) + return -1; + + if (ret == -2) + { + sprintf(attr, "a=%s\r\n", a->aValue); + } + else + { + sprintf(attr, "a=%s:%s\r\n", attrType, a->aValue); + } + + strcat(dest, attr); + + return 0; +} + +int pub_sdp_encode(PUB_SDP_MSG *sdp, char *dest, WORD flag) +{ + BYTE i, j; + BYTE mediaNum, attrNum; + PUB_SDP_MEDIA *media; + PUB_SDP_A *a; + + if ((sdp->flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V) + { + if (pub_sdp_encode_v(&sdp->v, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_O) == PUB_SDP_FLAG_O) + { + if (pub_sdp_encode_o(&sdp->o, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_S) == PUB_SDP_FLAG_S) + { + if (pub_sdp_encode_s(&sdp->s, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_I) == PUB_SDP_FLAG_I) + { + if (pub_sdp_encode_i(&sdp->i, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C) + { + if (pub_sdp_encode_c(&sdp->c, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_T) == PUB_SDP_FLAG_T) + { + if (pub_sdp_encode_t(&sdp->t, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + if (pub_sdp_encode_a(&sdp->a, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_M) == PUB_SDP_FLAG_M) + { + mediaNum = sdp->medias.num; + for (i = 0; i < mediaNum; i++) + { + media = &sdp->medias.medias[i]; + if (pub_sdp_encode_m(&media->m, dest, flag) < 0) + return -1; + + if ((media->flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + attrNum = media->attrs.num; + for (j = 0; j < attrNum; j++) + { + a = &media->attrs.attrs[j]; + if (pub_sdp_encode_a(a, dest) < 0) + return -1; + } + } + } + } + + return 0; +} + +//SDP encode for megaco + +int pub_sdp_encode_v_for_megaco(PUB_SDP_V *v, char *dest) +{ + sprintf(dest, "v=%d\r\n", v->value); + + return 0; +} + +int pub_sdp_encode_o_for_megaco(PUB_SDP_O *o, char *dest) +{ + char origin[128]; + char netType[8]; + char addrType[8]; + + if (pub_sdp_net_type_conv(netType, &o->netType, PUB_SDP_API_TO_STR) < 0) + return -1; + + if (pub_sdp_addr_type_conv(addrType, &o->addrType, PUB_SDP_API_TO_STR) < 0) + return -1; + + sprintf(origin, "o=%s %s %s %s %s %s\r\n", o->userName, o->sessId, o->sessVer, netType, addrType, o->addr); + + strcat(dest, origin); + + return 0; +} + +int pub_sdp_encode_s_for_megaco(PUB_SDP_S *s, char *dest) +{ + char sess[64]; + + sprintf(sess, "s=%s\r\n", s->sessName); + + strcat(dest, sess); + + return 0; +} + +int pub_sdp_encode_i_for_megaco(PUB_SDP_I *i, char *dest) +{ + char info[64]; + + sprintf(info, "i=%s\r\n", i->info); + + strcat(dest, info); + + return 0; +} + +int pub_sdp_encode_c_for_megaco(PUB_SDP_C *c, char *dest) +{ + char conn[128]; + char netType[8]; + char addrType[8]; + + if (pub_sdp_net_type_conv(netType, &c->netType, PUB_SDP_API_TO_STR) < 0) + return -1; + + if (pub_sdp_addr_type_conv(addrType, &c->addrType, PUB_SDP_API_TO_STR) < 0) + return -1; + + sprintf(conn, "c=%s %s %s\r\n", netType, addrType, c->addr); + + strcat(dest, conn); + + return 0; +} + +int pub_sdp_encode_t_for_megaco(PUB_SDP_T *t, char *dest) +{ + char time[64]; + + sprintf(time, "t=%u %u\r\n", t->startTime, t->stopTime); + + strcat(dest, time); + + return 0; +} + +int pub_sdp_encode_m_for_megaco(PUB_SDP_M *m, char *dest, WORD flag) +{ + char media[128]; + char mediaType[8] = ""; + char proto[32]; + char payload[64]; + BYTE i; + char port[8] = ""; + + if (pub_sdp_media_type_conv(mediaType, &m->media, PUB_SDP_API_TO_STR) < 0) + return -1; + + if (pub_sdp_proto_type_conv(proto, &m->proto, PUB_SDP_API_TO_STR) < 0) + return -1; + + if (m->port == PUB_SDP_M_PORT_CHOOSE) + { + strcpy(port, "$"); + } + else + { + sprintf(port, "%d", m->port); + } + + sprintf(media, "m=%s %s %s", mediaType, port, proto); + + if (m->proto == PUB_SDP_PROTO_TYPE_RTP_AVP) + { + if ((flag & PUB_MGCP_PARA_FLAG_TFO) == PUB_MGCP_PARA_FLAG_TFO) + { + sprintf(payload, " %d", 8); + strcat(media, payload); + } + + for (i = 0; i < m->plNum; i++) + { + if (i >= PUB_SDP_MAX_PAYLOAD_NUM) + break; + + sprintf(payload, " %d", m->payloads[i]); + strcat(media, payload); + } + } + + strcat(media, "\r\n"); + + strcat(dest, media); + + return 0; +} + +int pub_sdp_encode_a_for_megaco(PUB_SDP_A *a, char *dest) +{ + char attr[128]; + char attrType[32]; + int ret; + + if ((ret = pub_sdp_attr_type_conv(attrType, &a->aType, PUB_SDP_API_TO_STR)) == -1) + return -1; + + if (ret == -2) + { + sprintf(attr, "a=%s\r\n", a->aValue); + } + else + { + sprintf(attr, "a=%s:%s\r\n", attrType, a->aValue); + } + + strcat(dest, attr); + + return 0; +} + + +int pub_sdp_encode_for_megaco(PUB_SDP_MSG *sdp, char *dest, WORD flag) +{ + BYTE i, j; + BYTE mediaNum, attrNum; + PUB_SDP_MEDIA *media; + PUB_SDP_A *a; + + if ((sdp->flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V) + { + if (pub_sdp_encode_v_for_megaco(&sdp->v, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_O) == PUB_SDP_FLAG_O) + { + if (pub_sdp_encode_o_for_megaco(&sdp->o, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_S) == PUB_SDP_FLAG_S) + { + if (pub_sdp_encode_s_for_megaco(&sdp->s, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_I) == PUB_SDP_FLAG_I) + { + if (pub_sdp_encode_i_for_megaco(&sdp->i, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C) + { + if (pub_sdp_encode_c_for_megaco(&sdp->c, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_T) == PUB_SDP_FLAG_T) + { + if (pub_sdp_encode_t_for_megaco(&sdp->t, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + if (pub_sdp_encode_a_for_megaco(&sdp->a, dest) < 0) + return -1; + } + + if ((sdp->flag & PUB_SDP_FLAG_M) == PUB_SDP_FLAG_M) + { + mediaNum = sdp->medias.num; + for (i = 0; i < mediaNum; i++) + { + media = &sdp->medias.medias[i]; + if (pub_sdp_encode_m_for_megaco(&media->m, dest, flag) < 0) + return -1; + + if ((media->flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A) + { + attrNum = media->attrs.num; + for (j = 0; j < attrNum; j++) + { + a = &media->attrs.attrs[j]; + if (pub_sdp_encode_a_for_megaco(a, dest) < 0) + return -1; + } + } + } + } + + return 0; +} + +/*@end@*/ diff --git a/plat/public/src/pub_str.c b/plat/public/src/pub_str.c new file mode 100644 index 0000000..9319349 --- /dev/null +++ b/plat/public/src/pub_str.c @@ -0,0 +1,999 @@ +////////////////////////////////////////////////// +//Title : wxc_str.c +//Auhtor : Liu Wei +//Desc : wxc2 string library +//Created : 2007-06-20 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_str.h" + +/*@ignore@*/ +/////////////////////////////////////////////////////////////////////////// +// Name : StrInc +// Function : test string is included in string "pStr"or not +////////////////////////////////////////////////////////////////////////// + char *StrInc ( char *pIncStr, char *pStr ) +{ + int m; + register char *pCh; + register int n; + + m = strlen ( pIncStr ); + n = strlen ( pStr ); + for ( pCh = pStr; !IsChNull(*pCh) && ( n >= m ); pCh++, n-- ) + { + if ( !strncmp ( pIncStr, pCh, m ) ) + { + return ( pCh ); + } + } + return ( NULL ); +} + + +/////////////////////////////////////////////////////////////////////////// +// Name : StrIns +// Function : Insert string "pStrIns" to string "pSrc" , at the position of +// nPos, the nBufLen of string "pSrc" , is not enought , rerurn +// NULL, nor return pSrc +/////////////////////////////////////////////////////////////////////////// + char *StrIns ( int nPos, const char *pStrIns, char *pSrc, int nBufLen ) +{ + register int i; + int nLen; + + nLen = strlen ( pStrIns ); + + if ( nBufLen < nLen + strlen ( pSrc ) ) + { + return NULL; + } + + *(pSrc+nLen+strlen ( pSrc )) = CNULL; + + for ( i = strlen ( pSrc ); i >= nPos; i-- ) + { + *( pSrc + nLen + i ) = *( pSrc + i ); + } + + for ( i = 0; i < nLen; i++ ) + { + *( pSrc + nPos + i ) = *( pStrIns + i ); + } + + return ( pSrc ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrDel +// Function : Delete string "pStrDel" in string "pStr" , If pStrDel is not +// exist, rerurn NULL, nor return pSrc +/////////////////////////////////////////////////////////////////////////// + char *StrDel ( char *pStrDel, char *pStr ) +{ + char *pCh, *pPos; + + pCh = strstr ( pStr, pStrDel ); + if ( !pCh ) + { + return ( NULL ); + } + pPos = pCh + strlen ( pStrDel ); + strcpy ( pCh, pPos ); + return ( pStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrRepCh +// Function : Replace char cSrc in the string pStr with cDst +// Return : return the replace counter +/////////////////////////////////////////////////////////////////////////// + int StrRepCh ( char *pStr, char cSrc, char cDst ) +{ + int nReplaced = 0; + register char *pCh; + + for ( pCh = pStr; !IsChNull ( *pCh ); pCh++ ) + { + if ( cSrc == *pCh ) + { + *pCh = cDst; + nReplaced++; + } + } + return ( nReplaced ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrRepStr +// Function : Replace the first string "pSrc" in string "pStr" with "pDst" , +// If pSrc is not exist or the nBuffLen of pStr is not enought +// to insert pDst , rerurn NULL, nor return new pSrc +/////////////////////////////////////////////////////////////////////////// + char *StrRepStr ( char *pStr, char *pSrc, char *pDst, int nBuffLen ) +{ + char *pCh = NULL; + int nPos; + + pCh = strstr ( pSrc, pStr); + if ( !IsNull(pCh) ) + { + StrDel ( pSrc, pStr ); + nPos = pCh - pStr; + if (NULL == StrIns ( nPos, pDst, pStr, nBuffLen )) + pCh = NULL; + else + pCh = pStr; + } + return ( pCh ); +} + +/* +inline char *StrRepStr ( char *pStr, char *pSrc, char *pDst, int nBuffLen ) +{ + char *pCh = NULL; + int nPos; + int SrcLen; + int DstLen; + + SrcLen = strlen(pSrc); + DstLen = strlen(pDst); + + pCh = strstr ( pStr, pSrc); + + if ( (!IsNull(pCh)) && (nBuffLen >DstLen + strlen ( pStr ) - SrcLen)) + { + StrDel ( pSrc, pStr ); + nPos = pCh - pStr; + if (NULL == StrIns ( nPos, pDst, pStr, nBuffLen )) + pCh =NULL; + else + pCh = pStr; + } + else + pCh =NULL; + + return ( pCh ); +} +*/ + +/////////////////////////////////////////////////////////////////////////// +// Name : StrChg +// Function : Replace all the string "pSrc" in string "pStr" with "pDst" , +// If pSrc is not exist or the nBuffLen of pStr is not enought +// to insert pDst , rerurn NULL, nor return new pSrc +/////////////////////////////////////////////////////////////////////////// +/* +inline char *StrChg ( char *pStr, char *pSrc, char *pDst , int nBuffLen ) +{ + int n = 0; + char *pCh = pStr; + int i; + + i = strlen ( pDst ); + for ( ;; ) + { + if ( IsNull( StrRepStr ( pCh, pSrc, pDst, nBuffLen ) ) ) + { + break; + } + pCh += i; + n++; + } + return ( n ? pStr : NULL ); +} +*/ + +/* +inline char *StrChg ( char *pStr, char *pSrc, char *pDst , int nBuffLen ) +{ + int n = 0; + char *pCh = pStr; + char *pCounter = pStr; + int DstLen; + int SrcLen; + int counter = 0; + + SrcLen = strlen(pSrc); + DstLen = strlen(pDst); + + + pCounter = strstr(pCounter, pSrc); + + while (NULL != pCounter) + { + counter++; + pCounter = strstr(pCounter+SrcLen, pSrc); + } + + if ((0 != counter) && (nBuffLen > strlen(pStr)+DstLen*counter-SrcLen*counter)) + { + for ( ;; ) + { + if ( IsNull( StrRepStr ( pCh, pSrc, pDst, nBuffLen ) ) ) + { + break; + } + nBuffLen = nBuffLen - DstLen; + pCh += DstLen; + n++; + } + } + return ( n ? pStr : NULL ); +} +*/ + +/////////////////////////////////////////////////////////////////////////// +// Name : StriInc +// Function : test string is included in string "pStr"or not +// Note : No matter Upper or Lower +/////////////////////////////////////////////////////////////////////////// +char *StriInc ( char *pIncStr, char *pStr ) +{ + int m; + register char *pCh; + register int n; + + m = strlen ( pIncStr ); + n = strlen ( pStr ); + for ( pCh = pStr; !IsChNull(*pCh) && ( n >= m ); pCh++, n-- ) + { + if ( !strncasecmp ( pIncStr, pCh, m ) ) + { + return ( pCh ); + } + } + return ( NULL ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StriDel +// Function : Delete string "pStrDel" in string "pStr" , If pStrDel is not +// exist, rerurn NULL, nor return pSrc +// Note : No matter Upper or Lower +////////////////////////////////////////////////////////////////////////// + +char *StriDel ( char *pStrDel, char *pStr ) +{ + char *pCh, *pPos; + + pCh = StriInc ( pStrDel, pStr ); + if ( !pCh ) + { + return ( NULL ); + } + pPos = pCh + strlen ( pStrDel ); + strcpy ( pCh, pPos ); + return ( pStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrRepCh +// Function : Replace char cSrc in the string pStr with cDst +// Return : return the replace counter +/////////////////////////////////////////////////////////////////////////// +int StriRepCh ( char *pStr, char cSrc, char cDst ) +{ + int nReplaced = 0; + register char *pCh; + + cSrc = toupper ( cSrc ); + for ( pCh = pStr; !IsChNull( *pCh ); pCh++ ) + { + if ( cSrc == toupper ( *pCh ) ) + { + *pCh = cDst; + nReplaced++; + } + } + return ( nReplaced ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StriRepStr +// Function : Replace the first string "pSrc" in string "pStr" with "pDst" , +// If pSrc is not exist or the nBuffLen of pStr is not enought +// to insert pDst , rerurn NULL, nor return new pSrc +/////////////////////////////////////////////////////////////////////////// +char *StriRepStr ( char *pStr, char *pSrc, char *pDst, int nBuffLen ) +{ + char *pCh = NULL; + int nPos; + + pCh = StriInc ( pSrc, pStr); + if ( !IsNull(pCh) ) + { + StriDel ( pSrc, pStr ); + nPos = pCh - pStr; + + if (NULL == StrIns ( nPos, pDst, pStr, nBuffLen )) + pCh = NULL; + else + pCh = pStr; + } + return ( pCh ); +} + +/* +inline char *StriRepStr ( char *pStr, char *pSrc, char *pDst, int nBuffLen ) +{ + char *pCh = NULL; + int nPos; + int SrcLen; + int DstLen; + + SrcLen = strlen(pSrc); + DstLen = strlen(pDst); + + pCh = StriInc ( pSrc, pStr); + + if (( !IsNull(pCh) ) && (nBuffLen >DstLen + strlen ( pStr ) - SrcLen)) + { + StriDel ( pSrc, pStr ); + nPos = pCh - pStr; + if (NULL == StrIns ( nPos, pDst, pStr, nBuffLen )) + pCh = NULL; + else + pCh = pStr; + } + else + pCh = NULL; + + return ( pCh ); +} +*/ + +/////////////////////////////////////////////////////////////////////////// +// Name : StrChg +// Function : Replace all the string "pSrc" in string "pStr" with "pDst" , +// If pSrc is not exist or the nBuffLen of pStr is not enought +// to insert pDst , rerurn NULL, nor return new pSrc +// Note : No matter Upper or Lower +/////////////////////////////////////////////////////////////////////////// +/* +inline char *StriChg ( char *pStr, char *pSrc, char *pDst , int nBuffLen ) +{ + int n = 0; + char *pCh = pStr; + int i; + int nSrc , nDst ; + + + i = strlen ( pDst ); + for ( ;; ) + { + if ( IsNull( StriRepStr ( pCh, pSrc, pDst, nBuffLen ) ) ) + { + break; + } + pCh += i; + n++; + } + return ( n ? pStr : NULL ); +} +*/ + +/* +inline char *StriChg ( char *pStr, char *pSrc, char *pDst , int nBuffLen ) +{ + int n = 0; + char *pCh = pStr; + char *pCounter = pStr; + int DstLen; + int SrcLen; + int counter = 0; + + SrcLen = strlen(pSrc); + DstLen = strlen(pDst); + + + pCounter = StriInc(pSrc, pCounter); + + while (NULL != pCounter) + { + counter++; + pCounter = StriInc(pSrc, pCounter + SrcLen); + } + + if ((0 != counter) && (nBuffLen > strlen(pStr)+DstLen*counter-SrcLen*counter)) + { + for ( ;; ) + { + if ( IsNull( StriRepStr ( pCh, pSrc, pDst, nBuffLen ) ) ) + { + break; + } + + nBuffLen = nBuffLen - DstLen; + pCh += DstLen; + n++; + } + } + + return ( n ? pStr : NULL ); +} +*/ + +/////////////////////////////////////////////////////////////////////////// +// Name : StrCode +// Function : Xor the pStr with pSecCode , used in security coding +/////////////////////////////////////////////////////////////////////////// +char *StrCode ( char *pStr, char *pSecCode ) +{ + char *q = pSecCode; + register char *pCh; + + for ( pCh = pStr; !IsChNull(*pCh); pCh++ ) + { + if ( *pCh != *q ) + { + *pCh = *pCh ^ *q; + } + q++; + if ( IsChNull(*q) ) + { + q = pSecCode; + } + } + return ( pStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrFinis +// Function : cut the string with '\0', if nPos > the len of pStr , fill +// the string end with ' ' and set the pStr end positon at nPos +/////////////////////////////////////////////////////////////////////////// + char *StrFinis ( char *pStr, int nPos ) +{ + int i; + int nLen; + + nLen = strlen ( pStr ); + if ( nPos < nLen ) + { + *( pStr + nPos ) = CNULL; + } + else + { + for ( i = nLen; i < nPos; i++ ) + { + *( pStr + i ) = ' '; + } + *( pStr + i ) = CNULL; + } + return ( pStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrEnding +// Function : set the string end with the pEnd string till nPos position +////////////////////////////////////////////////////////////////////////// + char *StrEnding( char *pDst, char *pEnd , int nPos ) +{ + register int nLen = strlen(pDst); + int nEndLen = strlen(pEnd); + + if( nPos < nLen + nEndLen ) + { + return NULL; + } + for( ; nPos > nLen + nEndLen ; nLen += nEndLen ) + { + strcat( pDst , pEnd); + } + return (char*)pDst; +} + +/////////////////////////////////////////////////////////////////////////// +// StrSuff: checks whether suffix is a suffix of src. If it is not, +// the result is NULL. If it is, the result is a pointer +// to the character of src. +/////////////////////////////////////////////////////////////////////////// + char *StrSuff(const char *pSrc, const char *pSuffix ) +{ + register int nLen; + + for ( nLen = 0; *pSuffix++; nLen++ ) + if(!*pSrc++) return NULL; + + while (*pSrc++); + + for ( --pSrc, --pSuffix; --nLen >= 0; ) + if ( *--pSrc != *--pSuffix ) return NULL; + return (char*)pSrc; +} + +/* Fill string 'c' into last area of 'str'. */ +void StringCat(char *str, char *c, int slen) +{ + if (strlen(str) >= slen) + return; + while (strlen(str) < slen) + strcat(str, c); + str[slen] = 0; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrLeftShit +// Function : String left shit , delete first n chars +/////////////////////////////////////////////////////////////////////////// + char *StrLeftShit ( char *pStr, int n ) +{ + int i; + int len; + + len = strlen(pStr); + + if( n > len ) + { + return StrFinis(pStr , 0); + } + + len -= n; + + for ( i = 0; i < len; i++ ) + { + *( pStr + i ) = *( pStr + n + i ); + } + StrFinis( pStr , len ); + return ( pStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrRLeftShit +// Function : String round left shit +/////////////////////////////////////////////////////////////////////////// + char *StrRLeftShit ( char *pStr, int n ) +{ + int i, j; + char t; + + if ( !IsChNull(*pStr) ) + { + for ( j = 0; j < n; j++ ) + { + t = *( pStr ); + for ( i = 0; *( pStr + i ); i++ ) + { + *( pStr + i ) = *( pStr + i + 1 ); + } + *( pStr + i - 1 ) = t; + } + } + return ( pStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// StrToLower: String all lower case. +/////////////////////////////////////////////////////////////////////////// +char *StrToLower ( char *pStr ) +{ + register char *pCh; + + for ( pCh = pStr; pCh && *pCh; ++pCh ) + { + if ( isupper ( *pCh ) ) + { + *pCh = tolower ( *pCh ); + } + } + return pStr; +} + +/////////////////////////////////////////////////////////////////////////// +// StrToUpper: String all upper case. +/////////////////////////////////////////////////////////////////////////// +char *StrToUpper ( char *pStr ) +{ + register char *pCh; + + for ( pCh = pStr; pCh && *pCh; ++pCh ) + { + if ( islower ( *pCh ) ) + { + *pCh = toupper ( *pCh ); + } + } + return pStr; +} + +/////////////////////////////////////////////////////////////////////////// +// StrDupLower: Return an all lower case version of String +// you can free the return pointer +/////////////////////////////////////////////////////////////////////////// + char *StrDupLower ( char *pStr ) +{ + static char *pBuffer = NULL; + register char *pCh; + + if ( pBuffer ) + { + free ( pBuffer ); + } + + pBuffer = strdup ( pStr ); + + for ( pCh = pBuffer; pCh && *pCh; ++pCh ) + { + if ( isupper ( *pCh ) ) + { + *pCh = tolower ( *pCh ); + } + } + return ( pBuffer ); +} + +/////////////////////////////////////////////////////////////////////////// +// StrDupUpper: Return an all upper case version of String // you can free the return pointer +/////////////////////////////////////////////////////////////////////////// + char *StrDupUpper ( char *pStr ) +{ + static char *pBuffer = NULL; + register char *pCh; + + if ( pBuffer ) + { + free ( pBuffer ); + } + + pBuffer = strdup ( pStr ); + + for ( pCh = pBuffer; pCh && *pCh; ++pCh ) + { + if ( islower ( *pCh ) ) + { + *pCh = toupper ( *pCh ); + } + } + + return ( pBuffer ); +} + +/////////////////////////////////////////////////////////////////////////// +// IsExistCh : Is the char exist in the string +/////////////////////////////////////////////////////////////////////////// + int IsExistCh ( char ch, char *pStr ) +{ + register char *pCh; + + for ( pCh = pStr; !IsChNull(*pCh); ++pCh ) + { + if ( ch == *pCh ) + { + return ( 1 ); + } + } + + return ( 0 ); +} + +/////////////////////////////////////////////////////////////////////////// +// FindSep: Find the first char in char set in String +/////////////////////////////////////////////////////////////////////////// + char *StrChSet ( char *pChSet, char *pStr ) +{ + register char *pCh; + + for ( pCh = pChSet; !IsChNull(*pCh); ++pCh ) + { + if ( IsExistCh ( *pCh, pStr ) ) + { + return ( pCh ); + } + } + return ( ( char * ) NULL ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : StrChNum +// Function : return the char number in the string +/////////////////////////////////////////////////////////////////////////// + int StrChNum ( char *pStr, char ch ) +{ + int n = 0; + char *pCh = pStr; + + for( ; !IsChNull(*pCh); pCh++ ) + { + if (ch == *pCh) + n++; + } + + return ( n ); +} + +/* +inline int StrChNum ( char *pStr, char ch ) +{ + int n = 0; + char *pCh = pStr; + + for( ; !IsChNull(*pCh) && (ch == *pCh) ; pCh++ ) + n++; + + return ( n ); +} +*/ +/////////////////////////////////////////////////////////////////////////// +// StrTrimCh: trim the char in the string +/////////////////////////////////////////////////////////////////////////// + char *StrTrimCh ( char *pSrc , char cTrim ) +{ + register char *pCh; + char *p,*q; + + q = pSrc; + p = pCh = strdup(pSrc); + + if (NULL == pCh) + { + return NULL; + } + + for( ; !IsChNull(*pCh) ; pCh++ ) + { + if(*pCh != cTrim) + { + *pSrc++ = *(pCh); + } + } + *pSrc = '\0'; + free(p); + + return q; +} + +/////////////////////////////////////////////////////////////////////////// +// StrTrimCh: trim the char of the set in the string +/////////////////////////////////////////////////////////////////////////// + char *StrTrimChSet ( char *pSrc , char *pTrimSet ) +{ + register char *pCh; + char *p , *q , *m; + + p = pSrc; + m = pCh = strdup(pSrc); + + if (NULL == pCh) + { + return NULL; + } + + for( ; !IsChNull(*pCh) ; pCh++ ) + { + for( q = pTrimSet; *q && *pCh != *q ; q++ ) + { + ; + } + if( IsChNull(*q) ) + { + *pSrc++ = *(pCh); + } + } + + *pSrc = CNULL; + pSrc = p; + free(m); + + return pSrc; +} + +/////////////////////////////////////////////////////////////////////////// +// StrTrimLeftSpace: trim left space of string +/////////////////////////////////////////////////////////////////////////// + char *StrTrimLeftSpace( const char *pStr ) +{ + const char *p = pStr; + + for ( ; !IsChNull(*p) && isspace(*p) ; ) + { + p++; + } + return (char*) p; +} + +/////////////////////////////////////////////////////////////////////////// +// StrTrimMoreSpace: trim more than one space +/////////////////////////////////////////////////////////////////////////// + char *StrTrimMoreSpace ( char *pSrc ) +{ + char *pCh , *q; + register char *p; + + pCh = p = strdup(pSrc); + q = pSrc; + for ( ; *p; p++ ) + { + if ( !( isspace ( *p ) && isspace ( *(p+1) ) ) ) + { + *pSrc++ = *p; + } + } + *pSrc = CNULL; + free(pCh); + return pSrc; +} + +/////////////////////////////////////////////////////////////////////////// +// StrPickWord: pick a word from the string +/////////////////////////////////////////////////////////////////////////// + char *StrPickWord ( const char *pSrc, char *pDst ) +{ + char *pCh , *q = pDst; + + pCh = StrTrimLeftSpace(pSrc); + for( ; !isspace(*pCh) && !IsChNull(*pCh) ; pCh++) + { + *q++ = *pCh; + } + return (char *)pDst; +} + + +/////////////////////////////////////////////////////////////////////////// +// Name : StrEqTok +// Function: Parse the string and return the expression name and value +// Return : NULL, parse over or string expression error , nor while to call +// StrEqTok at odd times , return the name ; and return the value +// while even times +// Note : use it like strtok +// e.g. : +// { +// char *p = NULL; +// u8 uFlag = 0; +// +// p = StrEqTok(tmpStr); +// printf( "Name: %-20s " , p); +// for( ; p = StrEqTok(NULL); ) +// { +// uFlag = uFlag ? 0 : 1; +// if( uFlag ) +// { +// printf( "Valu: %-20s \n" , p); +// } +// else +// { +// printf( "Name: %-20s " , p); +// } +// } +// } +////////////////////////////////////////////////////////////////////////// +static char *pStrEqTok = NULL; +static u8 uStrEqState = 0; + +char *StrEqTok ( char *pStr ) +{ + char *p, *q, *pCh; + char *pDel = " "; + + pCh = pStr; + if ( pCh == NULL ) + { //last position + pCh = pStrEqTok; + } + else + { + StrTrimLeftSpace ( pCh ); + StrTrimMoreSpace ( pCh ); + } + + if ( pCh == NULL ) + { + return NULL; + } + + uStrEqState = uStrEqState > 2 ? 0 : uStrEqState; + q = strpbrk ( pCh, pDel ); + if ( q == NULL ) + { //over , one word + pStrEqTok = NULL; + q = pCh; + } + else + { //save position + pStrEqTok = q + 1; + *q = CNULL; + } + + p = strchr ( pCh, '=' ); //parse word + if ( p == NULL ) + { //simple word exclude '=' + if ( pStrEqTok == NULL || uStrEqState == 1 ) + { //miss '=' + goto STREQTOK_CLEAN_UP; + } + if ( uStrEqState == 0 || uStrEqState == 2 ) + { //wating expres left or right, recieved + uStrEqState++; + return pCh; + } + } + else + { + if ( uStrEqState == 0 && STR_CHECK_LAST( pCh, '=' ) ) + { //wating expres left , revied left and '=' + uStrEqState += 2; + STR_CUT_LAST( pCh ); + return pCh; + } + else if ( uStrEqState == 1 && STR_CHECK_FIRST( pCh,'=') ) + { //wating '=' , revied + if ( pCh[1] == CNULL ) + { //just '=' + if ( pStrEqTok == NULL ) + { + goto STREQTOK_CLEAN_UP; + } + pCh = pStrEqTok; + p = strpbrk ( pCh, pDel ); + if ( p == NULL ) + { + pStrEqTok = NULL; + p = pCh; + } + else + { + pStrEqTok = p + 1; + *p = CNULL; + } + uStrEqState = 3; + return pCh; + } + else + { //expres '=' and right + uStrEqState = 3; //all meet + return ++pCh; + } + } + else if ( uStrEqState == 0 ) + { //expres left and '=' and right + if ( pStrEqTok != NULL ) + { + *( pStrEqTok - 1 ) = ' '; + } + pStrEqTok = p + 1; + *p = CNULL; + uStrEqState = 2; + return pCh; + } + else + { + goto STREQTOK_CLEAN_UP; + } + } + + STREQTOK_CLEAN_UP: + pStrEqTok = NULL; + uStrEqState = 0; + return NULL; +} + + +int ReplaceStr(char *sSrc, char *sMatchStr, char *sReplaceStr) +{ + int StringLen; + char caNewString[1024]; + char *FindPos = strstr(sSrc, sMatchStr); + + if( (!FindPos) || (!sMatchStr) ) + return -1; + + while( FindPos ) + { + memset(caNewString, 0, sizeof(caNewString)); + StringLen = FindPos - sSrc; + strncpy(caNewString, sSrc, StringLen); + strcat(caNewString, sReplaceStr); + strcat(caNewString, FindPos + strlen(sMatchStr)); + strcpy(sSrc, caNewString); + FindPos = strstr(sSrc+StringLen+strlen(sMatchStr), sMatchStr); + } + return 0; +} + +/*@end@*/ + diff --git a/plat/public/src/pub_sys.c b/plat/public/src/pub_sys.c new file mode 100644 index 0000000..fab691e --- /dev/null +++ b/plat/public/src/pub_sys.c @@ -0,0 +1,555 @@ +////////////////////////////////////////////////// +//Title : linux_sys.c +//Auhtor : Liu Wei +//Desc : Linux system infomation +//Created : 2007-06-02 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// +#include "./include/pub_sys.h" + +extern void FLogMsg( u8 LogMask , const char *pFmt, ...); +/*@ignore@*/ +/////////////////////////////////////////////////////////////////////////// +// InitParalPort:Init parallel port data . +/////////////////////////////////////////////////////////////////////////// +extern void InitParalPort(void) +{ + ioperm(0x37a,3,1); + ioperm(0x378,3,1); + ioperm(0x379,3,1); + outb(0,0x37a); + outb(0,0x378); +} + + +/////////////////////////////////////////////////////////////////////////// +// Name : WriteParalPort +// Function : Write parallel port data +// Node : Parallel port address: +// : flag=0,address=0x37a B1;flag=1,address=0x37a B2 +// : flag=2--9,address=0x378 B0--B7 +/////////////////////////////////////////////////////////////////////////// + +extern void WriteParalPort(u8 uFlag,u8 uData) +{ + u8 ii,jj; + + if (uFlag > 9) + return; + if (uData != 0 && uData != 1) + return; + if (uFlag == 0 || uFlag == 1) // read or write 0x37a + { + ii = inb(0x37a); + jj = 1 << (uFlag + 1); + ii = ii & (~jj); + if (uFlag == 0) + jj = (~uData & 0x01) << (uFlag + 1); + else + jj = uData << (uFlag + 1); + ii = ii | jj; + outb(ii,0x37a); + } + else + { + ii = inb(0x378); + jj = 1 << (uFlag - 2); + ii = ii & (~jj); + jj = uData << (uFlag - 2); + ii = ii | jj; + outb(ii,0x378); + } +} + +/////////////////////////////////////////////////////////////////////////// +// GetMemoryStr: Get memery string +////////////////////////////////////////////////////////////////////////// +extern char *GetMemoryStr(u32 Amount) +{ + static char Buff[64]; + + if (Amount > 0) { + (void) snprintf(Buff, sizeof(Buff), "%d", Amount/MBYTES); + return(Buff); + } + + return((char *) NULL); +} + +/////////////////////////////////////////////////////////////////////////// +// GetBootTimeProc: Get System Model using the /proc/cpuinfo file. +/////////////////////////////////////////////////////////////////////////// + +#define PROC_FILE_UPTIME "/proc/uptime" + +extern char *GetBootTimeProc ( ) +{ + FILE *pFile; + static char sBuff[64]; + char *pCh; + char *DateStr; + time_t tmUptime; + time_t tmBootTime; + + pFile = fopen ( PROC_FILE_UPTIME, "r" ); + if ( !pFile ) + { + FLogMsg ( PIF_GERR, "%s: open readonly failed: %s", PROC_FILE_UPTIME, + SYSERR ); + return ( ( char * ) NULL ); + } + + if ( !fgets ( sBuff, sizeof ( sBuff ), pFile ) ) + { + FLogMsg ( PIF_GERR, "%s: Read uptime failed: %s", PROC_FILE_UPTIME, + SYSERR ); + ( void ) fclose ( pFile ); + return ( ( char * ) NULL ); + } + + if ( (pCh = strchr ( sBuff, ' ' )) != NULL ) + { + *pCh = CNULL; + } + + tmUptime = ( time_t ) strtol ( sBuff, NULL, 0 ); + if ( tmUptime <= 0 ) + { + FLogMsg ( PIF_GERR, "Convert `%s' to long failed", sBuff ); + ( void ) fclose ( pFile ); + return ( ( char * ) NULL ); + } + + tmBootTime = time ( NULL ); + tmBootTime -= tmUptime; + + DateStr = TimeToStr ( tmBootTime, NULL ); + + ( void ) fclose ( pFile ); + + return ( DateStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// Get System Model using the /proc/cpuinfo file. +/////////////////////////////////////////////////////////////////////////// + +#define PROC_FILE_CPUINFO "/proc/cpuinfo" +/* +extern char *GetModelProc ( ) +{ + FILE *pFile; + static char sBuff[256]; + char *Cpu = NULL; + char *Vendor = NULL; + char *Model = NULL; + char Speed[64]; + float sp = 0; + char **Argv; + int Argc; + int Cleanup; + + if ( sBuff[0] ) + { + return ( sBuff ); + } + + pFile = fopen ( PROC_FILE_CPUINFO, "r" ); + if ( !pFile ) + { + FLogMsg ( PIF_GERR, "%s: open readonly failed: %s", PROC_FILE_CPUINFO, + SYSERR ); + return ( ( char * ) NULL ); + } + + Speed[0] = CNULL; + while ( fgets ( sBuff, sizeof ( sBuff ), pFile ) ) + { + Cleanup = TRUE; + Argc = StrToArgv ( sBuff, ":", &Argv, NULL, 0 ); + if ( Argc < 2 ) + { + continue; + } + if ( EQ ( Argv[0], "cpu" ) ) + { + Cpu = Argv[1]; + } + else if ( EQ ( Argv[0], "vendor_id" ) ) + { + Vendor = Argv[1]; + } + else if ( EQ ( Argv[0], "model name" ) ) + { + Model = Argv[1]; + } + else if ( EQ ( Argv[0], "cpu MHz" ) ) + { + + // This value is not always perfectly accurate as Linux estimates + // the actual Mhz by doing a loop test at boot. + + if ( sscanf ( Argv[1], "%f", &sp ) ) + { + ( void ) sprintf ( Speed, "%.0f Mhz", rint ( ( double ) sp ) ); + } + } + else + { + DestroyArgv ( &Argv, Argc ); + Cleanup = FALSE; + } + + if ( Cleanup ) + { + ( void ) free ( Argv[0] ); + } + } + + sBuff[0] = CNULL; + if ( Vendor ) + { + ( void ) strcpy ( sBuff, Vendor ); + ( void ) free ( Vendor ); + } + if ( Speed[0] ) + { + if ( sBuff[0] ) + { + ( void ) strcat ( sBuff, " " ); + } + ( void ) strcat ( sBuff, Speed ); + } + if ( Model ) + { + if ( sBuff[0] ) + { + strcat ( sBuff, " " ); + } + strcat ( sBuff, Model ); + ( void ) free ( Model ); + } + if ( Cpu ) + { + if ( sBuff[0] ) + { + strcat ( sBuff, " " ); + } + strcat ( sBuff, Cpu ); + ( void ) free ( Cpu ); + } + + ( void ) fclose ( pFile ); + + return ( sBuff ); +} +*/ +/////////////////////////////////////////////////////////////////////////// +// GetMBytesStr: Get the string of Mbytes +/////////////////////////////////////////////////////////////////////////// + +extern char *GetMBytesStr ( u32 wAmount ) +{ + static char sBuff[64]; + + if ( !wAmount ) + { + return ( ( char * ) NULL ); + } + + if ( wAmount > KBYTES ) + { + ( void ) snprintf ( sBuff, sizeof ( sBuff ), "%.1f GB", + ( float ) MbytesToGbytes ( wAmount ) ); + } + else + { + ( void ) snprintf ( sBuff, sizeof ( sBuff ), "%.0f MB", + ( float ) wAmount ); + } + + return sBuff; +} + +/////////////////////////////////////////////////////////////////////////// +// GetMemoryKcore: Get System Memory using size of /proc/kcore +/////////////////////////////////////////////////////////////////////////// + +#define PROC_FILE_KCORE "/proc/kcore" + +extern char *GetMemoryKcore ( ) +{ + static char *pMemStr = NULL; + u32 wMemBytes = 0; + u32 wAmount = 0; + struct stat tStatBuf; + + if ( pMemStr ) + { + return ( pMemStr ); + } + + if ( stat ( PROC_FILE_KCORE, &tStatBuf ) != 0 ) + { + FLogMsg ( PIF_GERR, "%s: stat failed: %s", PROC_FILE_KCORE, SYSERR ); + return ( ( char * ) NULL ); + } + + wMemBytes = ( u32 ) ( tStatBuf.st_size - 4096 ); + wAmount = DivRndUp( wMemBytes, ( u32 ) MBYTES ); + pMemStr = GetMBytesStr ( wAmount ); + + return ( pMemStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// GetMemorySysinfo: Get System Memory using sysinfo() system call +/////////////////////////////////////////////////////////////////////////// + +extern char *GetMemorySysinfo ( ) +{ + struct sysinfo tSysInfo; + static char *pMemStr = NULL; + u32 wMemBytes = 0; + u32 wAmount = 0; + + if ( pMemStr ) + { + return ( pMemStr ); + } + + if ( sysinfo ( &tSysInfo ) != 0 ) + { + FLogMsg ( PIF_GERR, "sysinfo() system call failed: %s", SYSERR ); + return ( ( char * ) NULL ); + } + + // sysinfo.totalram represents total USABLE physical memory. Memory + // reserved by the kernel is not included. So this is as close as we + // can get for now. + + wMemBytes = ( u32 ) tSysInfo.totalram; + wAmount = DivRndUp( wMemBytes, ( u32 ) MBYTES ); + pMemStr = GetMemoryStr ( wAmount ); + + return ( pMemStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// GetVirtMemLinux:Get Virtual Memory using sysinfo() system call +/////////////////////////////////////////////////////////////////////////// + +extern char *GetVirtMemLinux ( ) +{ + struct sysinfo tSysInfo; + static char *pMemStr = NULL; + u32 wMemBytes = 0; + u32 wAmount = 0; + + if ( pMemStr ) + { + return ( pMemStr ); + } + + if ( sysinfo ( &tSysInfo ) != 0 ) + { + FLogMsg ( PIF_GERR, "sysinfo() system call failed: %s", SYSERR ); + return ( ( char * ) NULL ); + } + + wMemBytes = ( u32 ) ( tSysInfo.totalram + tSysInfo.totalswap ); + wAmount = DivRndUp( wMemBytes, ( u32 ) MBYTES ); + pMemStr = GetMemoryStr ( wAmount ); + + return ( pMemStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// GetCpuTypeProc:Get CPU Type from /proc/cpuinfo +/////////////////////////////////////////////////////////////////////////// + +#define PROC_FILE_CPUINFO "/proc/cpuinfo" +/* +extern char *GetCpuTypeProc ( ) +{ + FILE *pFile; + static char sBuff[256]; + static char *Cpu = NULL; + char **Argv; + char *pCh; + int Argc; + + if ( Cpu ) + { + return ( Cpu ); + } + + pFile = fopen ( PROC_FILE_CPUINFO, "r" ); + if ( !pFile ) + { + FLogMsg ( PIF_GERR, "%s: open readonly failed: %s", PROC_FILE_CPUINFO, + SYSERR ); + return ( ( char * ) NULL ); + } + + while ( fgets ( sBuff, sizeof ( sBuff ), pFile ) ) + { + Argc = StrToArgv ( sBuff, ":", &Argv, NULL, 0 ); + if ( Argc < 2 ) + { + continue; + } + if ( EQ ( Argv[0], "cpu" ) ) + { + // Linux 2.0 + Cpu = Argv[1]; + break; + } + else if ( EQ ( Argv[0], "model name" ) ) + { + // Linux 2.2 + Cpu = Argv[1]; + if ( pCh = strchr ( Cpu, ' ' ) ) + { + *pCh = CNULL; + } + break; + } + } + + ( void ) fclose ( pFile ); + + return ( Cpu ); + +} +*/ + +/////////////////////////////////////////////////////////////////////////// +// GetKernVerProc: Get Kernel Version string using /proc/version +/////////////////////////////////////////////////////////////////////////// + +#define PROC_FILE_VERSION "/proc/version" + +extern char *GetKernVerProc ( ) +{ + FILE *pFile; + static char sBuff[512]; + + if ( sBuff[0] ) + { + return ( sBuff ); + } + + pFile = fopen ( PROC_FILE_VERSION, "r" ); + if ( !pFile ) + { + FLogMsg ( PIF_GERR, "%s: open readonly failed: %s", PROC_FILE_VERSION, + SYSERR ); + return ( ( char * ) NULL ); + } + + if ( !fgets ( sBuff, sizeof ( sBuff ), pFile ) ) + { + FLogMsg ( PIF_GERR, "%s: read failed: %s", PROC_FILE_VERSION, SYSERR ); + return ( ( char * ) NULL ); + } + + ( void ) fclose ( pFile ); + + return ( sBuff ); + +} + +/////////////////////////////////////////////////////////////////////////// +// GetKernVerLinux: Get Kernel Version string using uname() +/////////////////////////////////////////////////////////////////////////// + +extern char *GetKernVerLinux ( ) +{ + static struct utsname tName; + static char *pVerStr = NULL; + + if ( uname ( &tName ) != 0 ) + { + FLogMsg ( PIF_GERR, "uname() system call failed: %s", SYSERR ); + return ( ( char * ) NULL ); + } + + pVerStr = tName.version; + + return ( pVerStr ); +} + +/////////////////////////////////////////////////////////////////////////// +// GetOSDistLinux: Get linux distribution (vendor) +/////////////////////////////////////////////////////////////////////////// +/* +extern char *GetOSDistLinux ( ) +{ + static char sBuff[256]; + register char *pCh; + register char *End; + char IssueFile[] = "/etc/issue"; + char Welcome[] = "Welcome to "; + FILE *pFile; + int Found = FALSE; + + if ( !( pFile = fopen ( IssueFile, "r" ) ) ) + { + FLogMsg ( PIF_GERR, "%s: Cannot open to get OS Dist: %s", IssueFile, + SYSERR ); + return ( ( char * ) NULL ); + } + + while ( fgets ( sBuff, sizeof ( sBuff ), pFile ) ) + { + // Some distributions have VGA control chars in them + if ( !isalpha ( sBuff[0] ) ) + { + continue; + } + for ( pCh = sBuff; pCh && *pCh && *pCh != '\n' && !isalpha ( *pCh ); + ++pCh ) + ; + if ( *pCh == '\n' || !strlen ( pCh ) ) + { + continue; + } + // Found first nonblank line + Found = TRUE; + break; + } + + ( void ) fclose ( pFile ); + + if ( !Found ) + { + return ( ( char * ) NULL ); + } + + if ( EQN ( pCh, Welcome, sizeof ( Welcome ) - 1 ) ) + { + pCh += sizeof ( Welcome ) - 1; + } + else if ( EQN ( pCh, "Linux ", 6 ) ) + { + pCh += 6; + } + + if ( End = strchr ( pCh, '-' ) ) + { + --End; + while ( *End && isspace ( *End ) ) + { + --End; + } + *++End = CNULL; + } + + return ( pCh ); +}*/ + +/*@end@*/ diff --git a/plat/public/src/pub_time.c b/plat/public/src/pub_time.c new file mode 100644 index 0000000..58fc331 --- /dev/null +++ b/plat/public/src/pub_time.c @@ -0,0 +1,152 @@ +////////////////////////////////////////////////// +//Title : pub_time.c +//Auhtor : Liu Wei +//Desc : Linux time function +//Created : 2007-06-02 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_time.h" + +/*@ignore@*/ +extern void FLogMsg( u8 LogMask , const char *pFmt, ...); +/////////////////////////////////////////////////////////////////////////// +// Name : GetTickCount +// Function: return the ms value of the time +// Note : +/////////////////////////////////////////////////////////////////////////// +extern long GetTickCount() +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : GetCurrentTime +// Function: get current system time(BcdFormate) +// Note : now_time's length is 6: year,month,day,hour,minute,second +// Return : 1 successful 0 fail +/////////////////////////////////////////////////////////////////////////// +extern int GetCurrentTime( u8 *pNowTime ) +{ + struct tm *pTMNowTime; + time_t tTemptime; + + tTemptime = time(NULL); + pTMNowTime = localtime(&tTemptime); + if( pTMNowTime == NULL ) + return 0; + pNowTime[0] = pTMNowTime->tm_year-100; + pNowTime[1] = pTMNowTime->tm_mon+1; + pNowTime[2] = pTMNowTime->tm_mday; + pNowTime[3] = pTMNowTime->tm_hour; + pNowTime[4] = pTMNowTime->tm_min; + pNowTime[5] = pTMNowTime->tm_sec; + + return 1; +} + +extern long timezone; + +extern int GetFDCurrentTime( u8 *strTime ) +{ + time_t now; + struct tm *local; + unsigned int iTime; + + time(&now); + local = gmtime(&now); + iTime = mktime(local) + 0; //timezone; //DIFF_EPOCH_TO_NTP; + + strTime[0] = (iTime >> 24)&0xff; + strTime[1] = (iTime >> 16) & 0xff; + strTime[2] = (iTime >> 8) & 0xff; + strTime[3] = (iTime >> 0) & 0xff; + strTime[4] = '\0'; + + return 1; +} + + + +/////////////////////////////////////////////////////////////////////////// +// Name : GetCurrentTime +// Function: get current system time in ASCII format +// Note : +/////////////////////////////////////////////////////////////////////////// +extern char *GetAsciiTime() +{ + char *pAscTime; + time_t tCurTime; + + tCurTime = time(NULL); + pAscTime = ctime(&tCurTime); + + return (char *)pAscTime; +} + +char *TimeToStr ( time_t TimeVal, char *Format ) +{ + struct tm *tm; + //static char sBuff[128]; + char *String; + char *pCh; + char *Fmt; + + if ( Format != NULL) + { + Fmt = Format; + } + else + { + //Use %H instead of %k as %H is more portable + Fmt = "%a %b %e %H:%M:%S %Y %Z"; + } + tm = localtime ( &TimeVal ); + if ( NULL != tm ) + { + String = asctime ( tm ); + if ( NULL != String ) + { + pCh = strchr ( String, '\n' ); + if ( NULL != pCh ) + { + *pCh = CNULL; + } + return String; + } + } + + FLogMsg ( PIF_DBG, "TimeToStr() failed - No conversion func defined?" ); + + return ( char * ) NULL; +} + + + +/////////////////////////////////////////////////////////////////////////// +// Name : GetTimeHMS +// Function: get current system time string of hour mininute and second +// Note : +/////////////////////////////////////////////////////////////////////////// +extern char *GetTimeHMS(char *pTimeBuf) +{ + struct tm *pTM,tTM; + long lCurTime; + + pTM = &tTM; + lCurTime = time((long *)0); + pTM = localtime(&lCurTime); + sprintf(pTimeBuf,"%02d:%02d:%02d",pTM->tm_hour,pTM->tm_min,pTM->tm_sec); + pTimeBuf[8] = CNULL; + + return pTimeBuf; +} + +/*@end@*/ diff --git a/plat/public/src/pub_timer.c b/plat/public/src/pub_timer.c new file mode 100644 index 0000000..7548b5f --- /dev/null +++ b/plat/public/src/pub_timer.c @@ -0,0 +1,182 @@ +////////////////////////////////////////////////// +//Title : wxc_timer.c +//Auhtor : Liu Wei +//Desc : WXC2 Public Timer Managemnet +//Created : 2007-04-27 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_timer.h" + +// fix multiple definition==================================== +WxcTimerNode tTimerListHead; +WxcTimerNode *pTLHead; +WxcTimerNode *pTLCur; +// + +/*@ignore@*/ +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +extern void TimerAdd ( WxcTimer * pTimer ) +{ + WxcTimerNode *pTNode; + + assert ( NULL != pTimer && NULL != pTimer->pFunc ); + assert ( pTimer->dExpires && pTimer->dSuitNumber < TM_CLOCK_MAX ); + + //pTimer->dSuitNumber = ? : 1; + + pTNode = + ( WxcTimerNode * ) WxcMalloc ( GET_TNODE_SIZE ( pTimer->dSuitNumber ) ); + if( NULL == pTNode ) + { + return ; + } + pTNode->pNext = NULL; + pTNode->pPrev = pTLCur; + pTNode->pTimer = ( WxcTimer * ) ( pTNode + 4 * sizeof ( void * ) ); + pTimer->pTimerNode = ( void * ) pTNode; + memcpy ( pTNode->pTimer, pTimer, sizeof ( WxcTimer ) ); + pTNode->dClockArray = ( u32 * ) ( pTNode->pTimer + sizeof ( WxcTimer ) ); + pTLCur = pTNode; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void TimerStart ( WxcTimer * pTimer, u16 dSuitId ) +{ + assert ( pTimer && pTimer->pTimerNode ); + assert ( dSuitId < pTimer->dSuitNumber ); + + ( ( WxcTimerNode * ) pTimer->pTimerNode )->dClockArray[dSuitId] = 1; +} + +extern void TimerMod ( WxcTimer * pTimer, u16 dExpires ) +{ + int i; + + assert ( NULL != pTimer && dExpires ); + + pTimer->dExpires = dExpires; + for ( i = 0; i < pTimer->dSuitNumber; i++ ) + { + TimerStart ( pTimer, i ); + } +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +extern void TimerDel ( WxcTimer * pTimer ) +{ + assert ( pTimer && pTimer->pTimerNode ); + + WxcFree ( pTimer->pTimerNode ); + pTimer->pTimerNode = NULL; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +extern void TimerStop ( WxcTimer * pTimer, u16 dSuitId ) +{ + assert ( NULL != pTimer && dSuitId < pTimer->dSuitNumber ); + + ( ( WxcTimerNode * ) pTimer->pTimerNode )->dClockArray[dSuitId] = 0; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +#define TimerRestart(pTimer) TimerStart(pTimer) + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// +#if 0 +static void *TM_Alloc ( u16 dSize ) +{ + +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +static void TM_Free ( void *p ) +{ + +} +#endif +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +static int TM_Pending ( WxcTimerNode * pTNode, u16 dSuitId ) +{ + return ( pTNode->dClockArray[dSuitId] ? 1 : 0 ); +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +static int TM_Expiring ( WxcTimerNode * pTNode, u16 dSuitId ) +{ + return ( TimerAfter + ( pTNode->dClockArray[dSuitId], pTNode->pTimer->dExpires ) ); +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +extern void TM_Init ( ) +{ + pTLCur = pTLHead = &tTimerListHead; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +extern void TM_RT ( ) +{ + u16 sid; + WxcTimer *pTimer; + WxcTimerNode *pTNode; + + pTNode = pTLHead; + + for ( ; NULL != pTNode; pTNode = pTNode->pNext ) + { + pTimer = pTNode->pTimer; + for ( sid = 0; sid <= pTimer->dSuitNumber; sid++ ) + { + if ( !TM_Pending ( pTNode, sid ) ) + { + pTNode->dClockArray[sid]++; + if ( TM_Expiring ( pTNode, sid ) ) + { + pTimer->pFunc ( pTimer->dData, sid ); + } + } + } + } +} + +/*@end@*/ diff --git a/plat/public/src/pub_wnet.c b/plat/public/src/pub_wnet.c new file mode 100644 index 0000000..f306e8d --- /dev/null +++ b/plat/public/src/pub_wnet.c @@ -0,0 +1,425 @@ +////////////////////////////////////////////////// +//Title : wxc_netfunc.c +//Auhtor : Liu Wei +//Desc : wxc2 network convert function +//Created : 2007-06-20 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/pub_wnet.h" + +u8 GetBcdStr ( char *str, u8 * bcd, u8 bcd_len ) +{ + u8 ii = 0; + + Bcd2Str ( str, bcd, bcd_len * 2 ); + for ( ii = 0; ii < bcd_len * 2; ii++ ) + { + if( str[ii] == 'e' || str[ii] == 'E' ) + break; + } + str[ii] = '\0'; + return ii; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : ImsiNToA +// Function: transfer IMSI format from normal to anti sequence +// Note : 0460022157127001 --> 64002251177200f1 +////////////////////////////////////////////////////////////////////////// + +void ImsiNtoA( u8 *pAntiImsi , u8 *pNormalImsi ) +{ + u8 ii; + u8 aa, bb = 0; + + for ( ii = 1; ii <= IMSI_LEN * 2; ii++ ) + { + if ( ( ii % 2 ) == 1 ) + { + bb = pNormalImsi[ii / 2] & 0x0f; + } + else + { + aa = (ii == IMSI_LEN * 2) ? 0x0f0 : (pNormalImsi[ii / 2] & 0x0f0); + pAntiImsi[ii / 2 - 1] = aa | bb; + } + } + +} + +/////////////////////////////////////////////////////////////////////////// +// Name : ImsiAToN +// Function: transfer IMSI format from anti to normal sequence +// Note : 64002251177200f1 --> 0460022157127001 +////////////////////////////////////////////////////////////////////////// + +void ImsiAToN ( u8 * pNormalImsi, u8 * pAntiImsi ) +{ // the IMSI must 15 digits + u8 ii; + u8 aa, bb = 0; + + pNormalImsi[0] = 0; + for ( ii = 0; ii < IMSI_LEN * 2; ii++ ) + { + if ( ( ii % 2 ) == 1 ) + { + aa = pAntiImsi[ii / 2] & 0x0f; + pNormalImsi[ii / 2] |= aa; + } + else + { + if ( ii / 2 != IMSI_LEN - 1 ) + { + bb = pAntiImsi[ii / 2] & 0x0f0; + pNormalImsi[ii / 2 + 1] = bb; + } + } + } +} + +/////////////////////////////////////////////////////////////////////////// +// Name : ImsiNToS +// Function: transfer IMSI format from normal to ascii string +// Note : 0460022157127001 --> "460022157127001" +/////////////////////////////////////////////////////////////////////////// + +void ImsiNToS ( u8 * pImsiStr, u8 * pNormalImsi ) +{ + u8 len; + u8 ii, jj; + + pImsiStr[0] = ( pNormalImsi[0] & 0x0f ) + '0'; + len = 1; + for ( ii = 1; ii < IMSI_LEN; ii++ ) + { + jj = ( pNormalImsi[ii] >> 4 ) & 0x0f; + pImsiStr[len++] = jj + '0'; + jj = pNormalImsi[ii] & 0x0f; + pImsiStr[len++] = jj + '0'; + } + pImsiStr[len] = '\0'; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : ImsiSToN +// Function: transfer IMSI format from ascii string to normal +// Note : "460022157127001" --> 0460022157127001 +/////////////////////////////////////////////////////////////////////////// + +void ImsiSToN ( u8 * pNormalImsi, u8 * pImsiStr ) +{ + if ( strlen ( (char *)pImsiStr ) != IMSI_LEN * 2 - 1 ) + return; + pNormalImsi[0] = pImsiStr[0] - '0'; + Str2Bcd ( pNormalImsi + 1, (char *)pImsiStr + 1, IMSI_LEN * 2 - 2 ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : IsdnNToA +// Function: transfer ISDN format from normal to anti sequence +// Note : 918675557127001EEE --> 08916857551700E1 +/////////////////////////////////////////////////////////////////////////// + +void IsdnNToA ( u8 * pAntiIsdn, u8 * pNormalIsdn ) +{ + u8 ii; + u8 aa = 0, bb = 0; + u8 len; + + // nature of address and numbering plan indicator + pAntiIsdn[1] = pNormalIsdn[0]; + len = 1; + for ( ii = 1; ii < ISDN_LEN; ii++ ) + { + if ( pNormalIsdn[ii] == 0xee ) + { + break; + } + else + { + aa = ( pNormalIsdn[ii] & 0x0f0 ) >> 4; + bb = pNormalIsdn[ii] & 0x0f; + if ( bb > 0x0c ) + { + bb = 0x0f; + } + pAntiIsdn[ii + 1] = ( bb << 4 ) + aa; + len++; + } + } + pAntiIsdn[0] = len; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : IsdnAToN +// Function: transfer ISDN format from anti to normal sequence +// Note : 08916857551700E1 --> 918675557127001EEE +/////////////////////////////////////////////////////////////////////////// + +void IsdnAToN ( u8 * pNormalIsdn, u8 * pAntiIsdn ) +{ + u8 ii; + u8 aa = 0, bb = 0; + u8 uIsdnLen; + + uIsdnLen = pAntiIsdn[0]; + if ( uIsdnLen > ISDN_LEN ) + uIsdnLen = ISDN_LEN; + pNormalIsdn[0] = pAntiIsdn[1]; + for ( ii = 1; ii < uIsdnLen; ii++ ) + { + if ( ( pAntiIsdn[ii + 1] & 0x0f ) >= 0x0e ) + break; + aa = ( pAntiIsdn[ii + 1] & 0x0f0 ) >> 4; + if ( aa > 0x0c ) + aa = 0x0e; + bb = pAntiIsdn[ii + 1] & 0x0f; + pNormalIsdn[ii] = ( bb << 4 ) + aa; + } + for ( ; ii < ISDN_LEN; ii++ ) + pNormalIsdn[ii] = 0x0ee; +} + + +/////////////////////////////////////////////////////////////////////////// +// Name : IsdnNToS +// Function: transfer ISDN format from normal to ascii string +// Note : 918675557127001EEE --> "8675557127001" +/////////////////////////////////////////////////////////////////////////// + +void IsdnNToS ( u8 * pIsdnStr, u8 * pNormalIsdn ) +{ + u8 len = 0; + u8 ii, jj; + + for ( ii = 1; ii < ISDN_LEN; ii++ ) + { + jj = ( pNormalIsdn[ii] >> 4 ) & 0x0f; + if ( jj > 0x0c ) + break; + pIsdnStr[len++] = jj + '0'; + jj = pNormalIsdn[ii] & 0x0f; + if ( jj > 0x0c ) + break; + pIsdnStr[len++] = jj + '0'; + } + pIsdnStr[len] = '\0'; +} + + +/////////////////////////////////////////////////////////////////////////// +// Name : IsdnAToS +// Function: transfer ISDN format from anti to ascii string +// Note : 08916857551700E1 --> "8675557127001" +/////////////////////////////////////////////////////////////////////////// + +void IsdnAToS ( u8 * pAntiIsdn, u8 * pIsdnStr ) +{ + u8 ii; + u8 aa = 0, bb = 0; + u8 len = 0; + u8 uIsdnLen; + + + uIsdnLen = pAntiIsdn[0]; + if ( uIsdnLen > ISDN_LEN ) + uIsdnLen = ISDN_LEN; + + for ( ii = 1; ii < uIsdnLen; ii++ ) + { + if ((bb = ( pAntiIsdn[ii + 1] & 0x0f )) >= 0x0c) + break; + + pIsdnStr[len++] = bb + '0'; + + if ((aa = ( pAntiIsdn[ii + 1] & 0x0f0 ) >> 4) >= 0x0c) + break; + + pIsdnStr[len++] = aa + '0'; + } + + pIsdnStr[len] = '\0'; +} + + +/////////////////////////////////////////////////////////////////////////// +// Name : IsdnSToN +// Function: transfer ISDN format from ascii string to normal +// Note : "8675557127001" --> 918675557127001EEE +// Return : 0--string has error; 1--success +/////////////////////////////////////////////////////////////////////////// + +u8 IsdnSToN ( u8 * pNormalIsdn, u8 * pIsdnStr ) +{ + u8 ii; + u8 len; + + len = strlen ( (char *)pIsdnStr ); + if ( len > ISDN_LEN * 2 - 2 ) + return 0; + if ( ( len % 2 ) == 1 ) // odd number + { + Str2Bcd ( pNormalIsdn + 1, (char *)pIsdnStr, len - 1 ); + ii = len / 2 + 1; + pNormalIsdn[ii] = ( pIsdnStr[len - 1] - '0' ) << 4; + pNormalIsdn[ii] |= 0x0E; + } + else + { + Str2Bcd ( pNormalIsdn + 1, (char *)pIsdnStr, len ); + ii = len / 2; + } + memset ( pNormalIsdn + ii + 1, 0xEE, ISDN_LEN - ii - 1 ); + pNormalIsdn[0] = 0x91; // default value + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : GttToIsdn +// Function: +// Note : +/////////////////////////////////////////////////////////////////////////// + +void GttToIsdn ( u8 *pIsdn, u8 *pGtt ) +{ + u8 ii, jj; + + pIsdn[0] = 0x91; + for ( ii = 1; ii < ISDN_LEN; ii++ ) + { + jj = pGtt[ii - 1] & 0x0f; + if ( jj > 0x0c ) + break; + pIsdn[ii] = jj << 4; + jj = ( pGtt[ii - 1] & 0xf0 ) >> 4; + if ( jj > 0x0c ) + jj = 0x0e; + pIsdn[ii] |= jj; + if ( jj == 0x0e ) + { + ii++; + break; + } + } + for ( ; ii < ISDN_LEN; ii++ ) + pIsdn[ii] = 0xee; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : IsdnToGtai +// Function: +// Note : +/////////////////////////////////////////////////////////////////////////// + +u8 IsdnToGtai ( u8 * pGtai, u8 * pIsdn ) +{ + u8 tmpBuf[32]; + u8 ii; + u8 len; + + IsdnNToA ( tmpBuf, pIsdn ); + ii = tmpBuf[0]; + memcpy ( pGtai, tmpBuf + 2, ii - 1 ); + if ( ( tmpBuf[ii] & 0x0f0 ) == 0x0f0 ) + len = ii * 2 - 3; + else + len = ii * 2 - 2; + return len; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : GtaiToIsdn +// Function: +// Note : +/////////////////////////////////////////////////////////////////////////// + +void GtaiToIsdn ( u8 * pIsdn, u8 * pGtai, u8 len ) +{ + u8 tmpBuf[32]; + + tmpBuf[0] = ( len + 1 ) / 2; + tmpBuf[1] = 0x91; + memcpy ( tmpBuf + 2, pGtai, tmpBuf[0]++ ); + IsdnAToN ( pIsdn, tmpBuf ); +} + +/////////////////////////////////////////////////////////////////////////// +// Name : BcdToStrPE +// Function: +// Note : +/////////////////////////////////////////////////////////////////////////// + +u8 BcdToStrPE ( char *str, u8 * bcd, u8 bcd_len ) +{ + u8 ii = 0; + + Bcd2Str ( str, bcd, bcd_len * 2 ); + for ( ii = 0; ii < bcd_len * 2; ii++ ) + { + if ( str[ii] == 'e' || str[ii] == 'E' ) + break; + } + str[ii] = '\0'; + return ii; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : AddCcToIsdn +// Function: +// Note : +/////////////////////////////////////////////////////////////////////////// + +void AddCcToIsdn ( u8 * isdn_str, u8 * cc ) +{ + char str1[32], str2[32]; + u8 len, len1, len2; + + len1 = BcdToStrPE ( str1, isdn_str + 1, ISDN_LEN - 1 ); + len2 = BcdToStrPE ( str2, cc, 2 ); + memcpy ( str2 + len2, str1, len1 ); + len = len1 + len2; + if ( ( len % 2 ) != 0 ) + str2[len++] = 'E'; + str2[len] = '\0'; + Str2Bcd ( isdn_str + 1, str2, len ); + isdn_str[0] = 0x91; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : AddNdcToIsdn +// Function: +// Note : +/////////////////////////////////////////////////////////////////////////// + +void AddNdcToIsdn ( u8 * isdn_str, u8 * ndc ) +{ + char str1[32], str2[32]; + u8 len, len1, len2; + + len1 = GetBcdStr ( str1, isdn_str + 1, ISDN_LEN - 1 ); + len2 = GetBcdStr ( str2, ndc, 3 ); //6 digit ndc + memcpy ( str2 + len2, str1, len1 ); + len = len1 + len2; + if ( ( len % 2 ) != 0 ) + str2[len++] = 'E'; + Str2Bcd ( isdn_str + 1, str2, len ); + isdn_str[0] = 0xa1; +} + +void BcdToAsciiR(char *ascii_buf, const unsigned char *bcd_buf, int len) +{ + char ch; + int i; + for(i=0;i +#include +#include +#include + +void * shm_init(int shm_id, char *prog_name, key_t key, int size, int shmflg) +{ + void *retp; + char *func_name = "shm_init"; + + shm_id = shmget(key, size, shmflg); + if (shm_id == -1) + printf("%s: %s: shmget(key: %x)", prog_name, func_name, key); + + retp = shmat(shm_id, (char *)0, 0); + if (retp == (void *) -1) + printf("%s: %s: shmat", prog_name, func_name); + + return retp; +} + +int sem_init(char *prog_name, key_t key, int sem_num, int sem_flg) +{ + int initarray[sem_num]; + int sem_id, retval, i; + char *func_name = "sem_init"; + + sem_id = semget(key, sem_num, sem_flg); + if (sem_id == -1) + printf("%s: %s: semget", prog_name, func_name); + for (i=0; i + * + */ +#include +#include "./number.h" + +/* +ITU: + 0-spare + 1-subscriber + 2-unknown + 3-NDD + 4-IDD + +GSM 09.02: +-- bits 765: nature of address indicator +-- 000 unknown +-- 001 international number +-- 010 national significant number +-- 011 network specific number +-- 100 subscriber number +-- 101 reserved +-- 110 abbreviated number +-- 111 reserved for extension +*/ + +static const u8 NAI_GSM2ITU[8] = {0x02, 0x04, 0x03, 0x03, 0x01, 0x02, 0x02, 0x02}; +static const u8 NAI_ITU2GSM[8] = {0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00}; +extern void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len); +u8 nai_gsm_to_itu(u8 nai) +{ + return NAI_GSM2ITU[nai & 0x07]; +} + +u8 nai_itu_to_gsm(u8 nai) +{ + return NAI_ITU2GSM[nai & 0x07]; +} + +void num_itu_to_gsm(num32_t *gsm_num, const num32_t *itu_num) +{ + int i; + + gsm_num->num_of_digit = itu_num->num_of_digit; + + for(i = 0; i < itu_num->num_of_digit; i++) + { + if(itu_num->digit[i] == 0x0b) + gsm_num->digit[i] = 0x0a; + else if(itu_num->digit[i] == 0x0c) + gsm_num->digit[i] = 0x0b; + else + gsm_num->digit[i] = itu_num->digit[i]; + } +} + +u8 *msc_isdn_to_bcd(u8 *bcd, const isdn_t *isdn) +{ + int i; + const num32_t *num = &isdn->num; + u8 *bcdptr; + + bcd[0] = (num->num_of_digit+1)/2 + 1; + bcd[1] = 0x81 | (nai_itu_to_gsm(isdn->nai) << 4); + bcdptr = bcd + 2; + for(i = 0; ((i < 32) && (i < num->num_of_digit)); i++) + { + if((i & 1) == 0) + *bcdptr = (num->digit[i] << 4) | 0x0f; + else + { + *bcdptr = (*bcdptr & 0xf0) + num->digit[i]; + bcdptr++; + } + } + return bcd; +} + +isdn_t *netbcd_to_isdn(isdn_t *isdn, const u8 *bcd) +{ + u8 bcd_digits; + u8 digit; + num32_t *num = &isdn->num; + + if(bcd[0] < 1) + { + num->num_of_digit = 0; + return isdn; + } + bcd_digits = (bcd[0]-1) * 2; + isdn->nai = nai_gsm_to_itu((bcd[1] >> 4) & 0x07); + bcd += 2; + for(num->num_of_digit = 0; (num->num_of_digit<32)&&(num->num_of_digitnum_of_digit++) + { + if((num->num_of_digit & 1) == 0) + digit = *bcd & 0x0f; + else + digit = *(bcd++) >> 4; + if(is_dail_digit(digit)) + num->digit[num->num_of_digit] = digit; + else + break; + } + return isdn; +} + +u8 *isdn_to_netbcd(u8 *bcd, const isdn_t *isdn) +{ + int i; + const num32_t *num = &isdn->num; + u8 *bcdptr; + + bcd[0] = (num->num_of_digit+1)/2 + 1; + bcd[1] = 0x81 | (nai_itu_to_gsm(isdn->nai) << 4); + bcdptr = bcd + 2; + for(i = 0; ((i < 32) && (i < num->num_of_digit)); i++) + { + if((i & 1) == 0) + *bcdptr = 0xf0 + (num->digit[i] & 0x0f); + else + { + *bcdptr = (num->digit[i] << 4) | (*bcdptr & 0x0f); + bcdptr++; + } + } + return bcd; +} + +/* TBCD: Telephony Binary Coded Decimal (GSM 09.02) */ +int tbcd_to_string(char *str, const u8 *tbcd, u8 tbcd_len) +{ + int i; + u8 max_digits; + u8 digit; + + max_digits = tbcd_len * 2; + for(i = 0; i < max_digits; i++) + { + if((i & 1) == 0) + digit = *tbcd & 0x0f; + else + digit = *(tbcd++) >> 4; + if(is_dail_digit(digit)) + digit_to_char(str[i], digit); + else + break; + } + str[i] = 0; + return i; +} + +isdn_t *tpaddr_to_isdn(isdn_t *isdn, const u8 *tpaddr) +{ + u8 bcd_digits; + u8 digit; + num32_t *num = &isdn->num; + + bcd_digits = tpaddr[0]; + isdn->nai = nai_gsm_to_itu((tpaddr[1] >> 4) & 0x07); + tpaddr += 2; + for(num->num_of_digit = 0; (num->num_of_digit<32)&&(num->num_of_digitnum_of_digit++) + { + if((num->num_of_digit & 1) == 0) + digit = *tpaddr & 0x0f; + else + digit = *(tpaddr++) >> 4; + if(is_dail_digit(digit)) + num->digit[num->num_of_digit] = digit; + else + break; + } + return isdn; +} + +int string_to_num32(num32_t *num, const char *str) +{ + u8 digit; + + for(num->num_of_digit = 0; num->num_of_digit < 32; num->num_of_digit++, str++) + { + if((*str >= '0') && (*str <= '9')) + digit = *str - '0'; + else if(*str == '*') + digit = 0x0b; + else if(*str == '#') + digit = 0x0c; + else + break; + num->digit[num->num_of_digit] = digit; + } + return num->num_of_digit; +} + +int num32_to_string(char *str, const num32_t *num) +{ + int i; + + for(i = 0; ((i < 32) && (i < num->num_of_digit)); i++) + { + if(num->digit[i] <= 9) + str[i] = num->digit[i] + '0'; + else if(num->digit[i] == 0x0b) + str[i] = '*'; + else if(num->digit[i] == 0x0c) + str[i] = '#'; + } + str[i] = 0; + return i; +} + +int string_to_num16(num16_t *num, const char *str) +{ + u8 digit; + + for(num->num_of_digit = 0; num->num_of_digit < 16; num->num_of_digit++, str++) + { + if((*str >= '0') && (*str <= '9')) + digit = *str - '0'; + else if(*str == '*') + digit = 0x0b; + else if(*str == '#') + digit = 0x0c; + else + break; + num->digit[num->num_of_digit] = digit; + } + return num->num_of_digit; +} + +int num16_to_string(char *str, const num16_t *num) +{ + int i; + + for(i = 0; ((i < 16) && (i < num->num_of_digit)); i++) + { + if(num->digit[i] <= 9) + str[i] = num->digit[i] + '0'; + else if(num->digit[i] == 0x0b) + str[i] = '*'; + else if(num->digit[i] == 0x0c) + str[i] = '#'; + } + str[i] = 0; + return i; +} + +int string_to_num8(num8_t *num, const char *str) +{ + u8 digit; + + for(num->num_of_digit = 0; num->num_of_digit < 8; num->num_of_digit++, str++) + { + if((*str >= '0') && (*str <= '9')) + digit = *str - '0'; + else if(*str == '*') + digit = 0x0b; + else if(*str == '#') + digit = 0x0c; + else + break; + num->digit[num->num_of_digit] = digit; + } + return num->num_of_digit; +} + +int num8_to_string(char *str, const num8_t *num) +{ + int i; + + for(i = 0; ((i < 8) && (i < num->num_of_digit)); i++) + { + if(num->digit[i] <= 9) + str[i] = num->digit[i] + '0'; + else if(num->digit[i] == 0x0b) + str[i] = '*'; + else if(num->digit[i] == 0x0c) + str[i] = '#'; + } + str[i] = 0; + return i; +} + +int digit2netbcd(u8 *netbcd, u8 *digit, u8 max_digit) +{ + int i; + + for(i = max_digit-1; i >= 0; i--) + { + if((i & 1) == 0) + { + *netbcd = (*netbcd & 0xf0) | (digit[i] & 0x0f); + netbcd++; + } + else + { + *netbcd = (digit[i] << 4) + 0x0f; + } + } + return (max_digit+1)/2; +} + +int netbcd2digit(u8 *digit, u8 *netbcd, u8 max_digit) +{ + int i; + u8 d; + + //for(i = 0; i < max_digit; i++) + //{ + // if((i & 1) == 0) + // d = *netbcd & 0x0f; + // else + // d = *(netbcd++) >> 4; + // + // digit[i] = d; + //} + for(i = 0; i < max_digit; i++) + { + if((i & 1) == 0) + d = *netbcd >> 4; + else + d = *(netbcd++) & 0x0f; + + digit[max_digit-1-i] = d; + } + + return i; +} + +int digit_to_netbcd(u8 *netbcd, u8 *digit, u8 max_digit) +{ + int i; + + for(i = 0; i < max_digit; i++) + { + if((i & 1) == 0) + *netbcd = 0xf0 + (digit[i] & 0x0f); + else + { + *netbcd = (digit[i] << 4) | (*netbcd & 0x0f); + netbcd++; + } + } + return (max_digit+1)/2; +} + +int netbcd_to_digit(u8 *digit, u8 *netbcd, u8 max_digit) +{ + int i; + u8 d; + + for(i = 0; i < max_digit; i++) + { + if((i & 1) == 0) + d = *netbcd & 0x0f; + else + d = *(netbcd++) >> 4; + + if(d != 0x0f) + digit[i] = d; + else + break; + } + return i; +} + +void msc_save_lai(u8 *lai, u8 *mcc, u8 *mnc, int lac) +{ + lai[0] = (mcc[1] << 4) + (mcc[0] & 0x0f); + lai[1] = (mnc[2] << 4) | mcc[2]; + lai[2] = (mnc[1] << 4) + (mnc[0] & 0x0f); + lai[3] = lac >> 8; + lai[4] = lac; +} + +void msc_load_lai(u8 *mcc, u8 *mnc, int *lac, u8 *lai) +{ + mcc[0] = lai[0] & 0x0f; + mcc[1] = lai[0] >> 4; + mcc[2] = lai[1] & 0x0f; + mnc[0] = lai[2] & 0x0f; + mnc[1] = lai[2] >> 4; + mnc[2] = lai[1] >> 4; + *lac = (lai[3] << 8) + lai[4]; +} + + +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* transfer ISDN format from ascii string to normal */ +/* "8675557127001" --> 918675557127001EEE */ +/* return value: 0--string has error; 1--success */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +#define ISDN_LEN 9 + +u8 isdn_ston(u8 *normal_isdn,u8 *str_isdn) +{ + u8 ii; + u8 len; + + len = strlen((char *)str_isdn); + if (len > ISDN_LEN*2-2) + return 0; + if ((len % 2) == 1) // odd number + { + AsciiToBcd(normal_isdn+1, (char *)str_isdn,len-1); + ii = len/2 + 1; + normal_isdn[ii] = (str_isdn[len-1] - '0') << 4; + normal_isdn[ii] |= 0x0E; + } + else + { + AsciiToBcd(normal_isdn+1, (char *)str_isdn,len); + ii = len/2; + } + memset(normal_isdn+ii+1,0xEE,ISDN_LEN-ii-1); + normal_isdn[0] = 0x91; // default value + return 1; +} + +void isdn_ntoa(u8 * anti_isdn, u8 * normal_isdn) +{ + u8 ii; + u8 aa = 0, bb = 0; + u8 len; + + anti_isdn[1] = normal_isdn[0]; // nature of address and numbering plan indicator + len = 1; + for(ii = 1; ii < ISDN_LEN; ii++) + { + if(normal_isdn[ii] == 0xee) + break; + else + { + aa = (normal_isdn[ii] & 0x0f0) >> 4; + bb = normal_isdn[ii] & 0x0f; + if(bb > 0x0c) + bb = 0x0f; + anti_isdn[ii + 1] = (bb << 4) + aa; + len++; + } + } + anti_isdn[0] = len; +} + +#if 0 +/* return the digit counts of number */ +static int bcd_to_num16(num16_t *num, const u8 *bcd) +{ + u8 digit; + + for(num->num_of_digit = 0; num->num_of_digit < 16; num->num_of_digit++) + { + if((num->num_of_digit & 1) == 0) + digit = *bcd >> 4; + else + digit = *(bcd++) & 0x0f; + if(is_dail_digit(digit)) + num->digit[num->num_of_digit] = digit; + else + break; + } + return num->num_of_digit ; +} + +/* return the length of bcd */ +static int num16_to_bcd(u8 *bcd, const num16_t *num) +{ + int i; + + for(i = 0; ((i < 16) && (i < num->num_of_digit)); i++) + { + if((i & 1) == 0) + *bcd = (num->digit[i] << 4) | 0x0f; + else + *(bcd++) = (*bcd & 0xf0) + num->digit[i]; + } + return (i+1)/2; +} +#endif + diff --git a/plat/public/src/uwav/number.h b/plat/public/src/uwav/number.h new file mode 100644 index 0000000..ee41637 --- /dev/null +++ b/plat/public/src/uwav/number.h @@ -0,0 +1,82 @@ +#ifndef _UWAV_NUMBER_H +#define _UWAV_NUMBER_H + +#include "../include/public.h" + +/* + * Number type definition: + * 32 digits number is used for party number handling + * 16 digits number is used for prefix parameter + * 8 digits number is used for short number parameter, i.e. cc, ndc + */ +typedef struct number32 { + u8 num_of_digit; + u8 digit[32]; +} num32_t; + +typedef struct number16 { + u8 num_of_digit; + u8 digit[16]; +} num16_t; + +typedef struct number8 { + u8 num_of_digit; + u8 digit[8]; +} num8_t; + +typedef struct isdn_num { + u8 nai; /* Nature of Address Indicator */ +// u8 npi; /* Number Plan Indicator */ + u8 pi; + u8 si; /* Screen Indicator */ + num32_t num; +} isdn_t; + +struct number_change { + u8 nai; + u8 del_count; + num16_t insert; +}; + +#define is_dail_digit(digit) (digit < 0x0e) +#define char_to_digit(digit, ch) do { \ + if((ch >= '0') && (ch <= '9')) \ + digit = ch - '0'; \ + else if(ch == '*') \ + digit = 0x0b; \ + else if(ch == '#') \ + digit = 0x0c; \ + else \ + break; \ +} while(0) +#define digit_to_char(ch, digit) do { \ + if(digit <= 9) \ + ch = digit + '0'; \ + else if(digit == 0x0b) \ + ch = '*'; \ + else if(digit == 0x0c) \ + ch = '#'; \ +} while(0) + +extern u8 nai_gsm_to_itu(u8 nai); +extern u8 nai_itu_to_gsm(u8 nai); +extern u8 *msc_isdn_to_bcd(u8 *bcd, const isdn_t *isdn); +extern isdn_t *netbcd_to_isdn(isdn_t *isdn, const u8 *bcd); +extern u8 *isdn_to_netbcd(u8 *bcd, const isdn_t *isdn); +extern int tbcd_to_string(char *str, const u8 *tbcd, u8 tbcd_len); +extern isdn_t *tpaddr_to_isdn(isdn_t *isdn, const u8 *tpaddr); +extern int string_to_num32(num32_t *num, const char *str); +extern int num32_to_string(char *str, const num32_t *num); +extern int string_to_num16(num16_t *num, const char *str); +extern int num16_to_string(char *str, const num16_t *num); +extern int string_to_num8(num8_t *num, const char *str); +extern int num8_to_string(char *str, const num8_t *num); +extern int digit2netbcd(u8 *netbcd, u8 *digit, u8 max_digit); +extern int netbcd2digit(u8 *digit, u8 *netbcd, u8 max_digit); +extern int digit_to_netbcd(u8 *netbcd, u8 *digit, u8 max_digit); +extern int netbcd_to_digit(u8 *digit, u8 *netbcd, u8 max_digit); +extern void msc_save_lai(u8 *lai, u8 *mcc, u8 *mnc, int lac); +extern void msc_load_lai(u8 *mcc, u8 *mnc, int *lac, u8 *lai); + +#endif + diff --git a/plat/public/src/uwav/numgrp.c b/plat/public/src/uwav/numgrp.c new file mode 100644 index 0000000..74d91a3 --- /dev/null +++ b/plat/public/src/uwav/numgrp.c @@ -0,0 +1,176 @@ +/* + * public/uwav/numgrp.c + * + * Copyright (C) 2008 ADC, Inc + * Written by: Xinyu Yan + * + * Description: number group lookup algorithm + */ + +#include +#include +#include +#include +#include "numgrp.h" + +static struct numgrp_table group_table[MAX_NUMBER_GROUP_TABLE]; + +struct numgrp_table *assign_numgrp_table(char *name, int size) +{ + int i; + + assert(size <= MAX_NUMBER_GROUP_TABLE_SIZE); + + for(i = 0; i < MAX_NUMBER_GROUP_TABLE; i++) + { + if(group_table[i].size == 0) + { + strncpy(group_table[i].name, name, 32); + group_table[i].size = size; + group_table[i].len = 0; + group_table[i].item = malloc(sizeof(struct number_group) * size); + return &group_table[i]; + } + } + return NULL; +} + +int delete_numgrp_table(struct numgrp_table *table) +{ + int i; + + for(i = 0; i < MAX_NUMBER_GROUP_TABLE; i++) + { + if(&group_table[i] == table) + { + free(group_table[i].item); + memset(&group_table[i], 0, sizeof(struct numgrp_table)); + return 1; + } + } + return 0; +} + +/*Return an integer greater than, equal to, or less than 0, if the number pointed to + by n1 is greater than, equal to, or less than the number pointed to by n2, respectively*/ +static int numcmp(const num16_t *n1, const num16_t *n2) +{ + int i; + + if(n1->num_of_digit > n2->num_of_digit) + return 1; + else if(n1->num_of_digit < n2->num_of_digit) + return -1; + for(i = 0; i < n1->num_of_digit; i++) + { + if(n1->digit[i] > n2->digit[i]) + return 1; + else if(n1->digit[i] < n2->digit[i]) + return -1; + } + return 0; +} + +/*Return an integer greater than, equal to, or less than 0, if the number pointed to + by n is greater than, equal to, or less than the group pointed to by start and end, respectively*/ +static int numgrpcmp(const num16_t *start, const num16_t *end, const num16_t *n) +{ + int ret1, ret2; + + ret1 = numcmp(n, start); + ret2 = numcmp(n, end); + if((ret1 >= 0) && (ret2 <= 0)) + return 0; + else if(ret2 > 0) + return 1; + else + return -1; +} + +/* n: max items of table + * num: number being searched + * m: the position of value which is found or will be inserted + * ret: return 1 if found, otherwise 0 +*/ +static int bisearch(struct number_group *item, int n, num16_t *num, int *m) +{ + int i = 0; + int j = n - 1; + int ret; + + *m = 0; + while(i <= j) + { + *m = (i+j) / 2; + ret = numgrpcmp(&item[*m].start, &item[*m].end, num); + if(ret == 0) + return 1; + else if(ret > 0) + i = *m + 1; + else + j = *m - 1; + } + *m = i; + return 0; +} + +int numgrp_search(int *index, struct numgrp_table *table, num16_t *num) +{ + int m; + + if(table == NULL) + return 0; + if(bisearch(table->item, table->len, num, &m)) + { + *index = table->item[m].index; + return 1; + } + return 0; +} + +int numgrp_insert(struct numgrp_table *table, num16_t *start, num16_t *end, int index) +{ + int m, m2; + + if(numcmp(start, end) > 0) + { + //printf("Start number > end number\n"); + return 0; + } + if(bisearch(table->item, table->len, start, &m)) + { + //printf("Start number in exist group\n"); + return 0; + } + if(bisearch(table->item, table->len, end, &m2)) + { + //printf("End number in exist group\n"); + return 0; + } + if(m != m2) + { + //printf("Start-end contains other group\n"); + return 0; + } + memmove(&table->item[m+1], &table->item[m], sizeof(struct number_group)*(table->len-m)); + memcpy(&table->item[m].start, start, sizeof(num16_t)); + memcpy(&table->item[m].end, end, sizeof(num16_t)); + table->item[m].index = index; + table->len++; + return 1; +} + +int numgrp_delete(struct numgrp_table *table, num16_t *num) +{ + int m; + + if(bisearch(table->item, table->len, num, &m)) + { + memmove(&table->item[m], &table->item[m+1], sizeof(struct number_group)*(table->len-m-1)); + memset(&table->item[table->len-1], 0, sizeof(struct number_group)); + table->len--; + return 1; + } + return 0; +} + diff --git a/plat/public/src/uwav/numgrp.h b/plat/public/src/uwav/numgrp.h new file mode 100644 index 0000000..93da8c4 --- /dev/null +++ b/plat/public/src/uwav/numgrp.h @@ -0,0 +1,29 @@ +#ifndef _UWAV_NUMGRP_H_ +#define _UWAV_NUMGRP_H_ + +#include "number.h" + +#define MAX_NUMBER_GROUP_TABLE 32 +#define MAX_NUMBER_GROUP_TABLE_SIZE 1024 + +struct number_group { + num16_t start; + num16_t end; + int index; +}; + +struct numgrp_table { + char name[32]; + int size; + int len; + struct number_group *item; +}; + +extern struct numgrp_table *assign_numgrp_table(char *name, int size);/* size: capability of table in unit of records */ +extern int delete_numgrp_table(struct numgrp_table *table); +extern int numgrp_search(int *index, struct numgrp_table *table, num16_t *num); +extern int numgrp_insert(struct numgrp_table *table, num16_t *start, num16_t *end, int index); +extern int numgrp_delete(struct numgrp_table *table, num16_t *num); + +#endif + diff --git a/plat/public/ut/asn.1/asntest.c b/plat/public/ut/asn.1/asntest.c new file mode 100644 index 0000000..c0f4bc9 --- /dev/null +++ b/plat/public/ut/asn.1/asntest.c @@ -0,0 +1,429 @@ +#include "./include/asn1.h" +#include +#include +#include +int test1(); +int test2(); +int test3(); +int test4(); +int test5(); +int test6(); +int test7(); +int test8(); +int test9(); +int test10(); +int test11(); +int test12(); +int showtlv(const char *tag_seq,ASN_BUF *asnbuf); +int main(int argc,char *argv[]) +{ + if(argc==2) + { + switch(atoi(argv[1])) + { + case 1: + test1(); + break; + case 2: + test2(); + break; + case 3: + test3(); + break; + case 4: + test4(); + break; + case 5: + test5(); + break; + case 6: + test6(); + break; + case 7: + test7(); + break; + case 8: + test8(); + break; + case 9: + test9(); + break; + case 10: + test10(); + break; + case 11: + test11(); + break; + case 12: + test12(); + break; + default: + printf("Out of range!\n"); + } + } + else + printf("Usage:asntest number\n"); + return 0; +} + +int test1() //Tag encoding/decoding test +{ + u_char msg_buf[50]; + int len; + ASN_BUF asnbuf; + + asn_encode(msg_buf,&asnbuf); + + len=add_null("2",0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + if(get_null("2",&asnbuf)==1) + printf("decoding correctly\n"); + + asn_encode(msg_buf,&asnbuf); + + len=add_null("32",0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + if(get_null("32",&asnbuf)==1) + printf("decoding correctly\n"); + + asn_encode(msg_buf,&asnbuf); + + len=add_null("129",0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + if(get_null("129",&asnbuf)==1) + printf("decoding correctly\n"); + + asn_encode(msg_buf,&asnbuf); + + len=add_null("2",0x80,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + if(get_null("2",&asnbuf)==1) + printf("decoding correctly\n"); + + asn_encode(msg_buf,&asnbuf); + + len=add_null("32",0xC0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + if(get_null("32",&asnbuf)==1) + printf("decoding correctly\n"); + + return 1; +} + +int test2() +{ + u_char msg_buf[1024],pvalue[1024]; + ASN_BUF asnbuf; + + memset(pvalue,0xFF,1024); + + asn_encode(msg_buf,&asnbuf); + add_tlv("1",0,pvalue,0,&asnbuf); + showbuf(msg_buf,5); + asn_decode(msg_buf,1,&asnbuf); + printf("len=%d\n",get_tlv("1",pvalue,&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + add_tlv("1",2,pvalue,0,&asnbuf); + showbuf(msg_buf,5); + asn_decode(msg_buf,1,&asnbuf); + printf("len=%d\n",get_tlv("1",pvalue,&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + add_tlv("1",128,pvalue,0,&asnbuf); + showbuf(msg_buf,5); + asn_decode(msg_buf,1,&asnbuf); + printf("len=%d\n",get_tlv("1",pvalue,&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + add_tlv("1",129,pvalue,0,&asnbuf); + showbuf(msg_buf,5); + asn_decode(msg_buf,1,&asnbuf); + printf("len=%d\n",get_tlv("1",pvalue,&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + add_tlv("1",257,pvalue,0,&asnbuf); + showbuf(msg_buf,5); + asn_decode(msg_buf,1,&asnbuf); + printf("len=%d\n",get_tlv("1",pvalue,&asnbuf)); + return 1; +} +int test3() +{ + u_char msg_buf[256]; + ASN_BUF asnbuf; + char oid[20]; + int len; + + //Boolean-----> + asn_encode(msg_buf,&asnbuf); + len=add_bool("1",0,0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + printf("decoded value:%d\n",get_bool("1",&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + len=add_bool("1",1,0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + printf("decoded value:%d\n",get_bool("1",&asnbuf)); + //Integer-----> + asn_encode(msg_buf,&asnbuf); + len=add_int("1",2,0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + printf("decoded value:%d\n",get_int("1",&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + len=add_int("1",257,0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + printf("decoded value:%d\n",get_int("1",&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + len=add_int("1",-2,0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + printf("decoded value:%d\n",get_int("1",&asnbuf)); + + asn_encode(msg_buf,&asnbuf); + len=add_int("1",-259,0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + printf("decoded value:%d\n",get_int("1",&asnbuf)); + + //Object Identifier-----> + asn_encode(msg_buf,&asnbuf); + len=add_oid("1","2.100.6",0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + get_oid("1",oid,&asnbuf); + printf("decoded value:%s\n",oid); + + asn_encode(msg_buf,&asnbuf); + len=add_oid("1","0.39.6",0,&asnbuf); + showbuf(msg_buf,len); + asn_decode(msg_buf,1,&asnbuf); + get_oid("1",oid,&asnbuf); + printf("decoded value:%s\n",oid); + return 1; +} +int test4() //encoding test +{ + u_char msg_buf[256]; + int c1=0,c2=1; + u_char d1[2]={0x22,0x22}; + u_char d2[2]={0x33,0x33}; + u_char b3[2]={0x44,0x44}; + u_char a2[2]={0x55,0x55}; + u_char a3[2]={0x66,0x66}; + int len; + ASN_BUF asnbuf; + + asn_encode_v3(msg_buf,128,&asnbuf); + len=add_int("1.0.2-1",c1,0,&asnbuf); + len=add_int("1.0.2-2",c2,0,&asnbuf); + len=add_tlv("1.0.1-3.0",2,d1,0x80,&asnbuf); + len=add_tlv("1.0.1-3.1",2,d2,0x80,&asnbuf); + len=add_tlv("1.1",2,b3,0x80,&asnbuf); + len=add_tlv("2",2,a2,0x80,&asnbuf); + len=add_tlv("3",2,a3,0x80,&asnbuf); + showbuf(msg_buf,len); + printf("decode......\n"); + asn_decode(msg_buf,3,&asnbuf); + showtlv("1.0.2-1",&asnbuf); + showtlv("1.0.2-2",&asnbuf); + showtlv("1.0.1-3.0",&asnbuf); + showtlv("1.0.1-3.1",&asnbuf); + showtlv("1.1",&asnbuf); + showtlv("2",&asnbuf); + showtlv("3",&asnbuf); + return 1; +} + +int test5() //decoding test(long length) +{ + u_char msg_buf[256]={0xA5,0x80, + 0x82,0x80, + 0x83,0x02,0x00,0x00, + 0x00,0x00, + 0x00,0x00, + 0xA6,0x80,0x82,0x02,0x11,0x11,0x00,0x00}; + ASN_BUF asnbuf; + asn_decode(msg_buf,2,&asnbuf); + showtlv("5.2.3",&asnbuf); + showtlv("6.2",&asnbuf); + showtlv("5.2",&asnbuf); + showtlv("6",&asnbuf); + return 1; +} + +int test6() //decoding test(indefinite length) +{ + u_char msg_buf[256]={0xA5,0x80, + 0xA2,0x81,0x82, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, + 0xA3,0x02,0x01,0x01, + 0x00,0x00, + 0xA6,0x80,0x82,0x02,0x11,0x11,0x00,0x00}; + ASN_BUF asnbuf; + int temp; + asn_decode_v3(msg_buf,256,&temp,&asnbuf); + + showtlv("5.2",&asnbuf); + showtlv("5.3",&asnbuf); + showtlv("5",&asnbuf); + showtlv("6.2",&asnbuf); + return 1; +} + + + +int showtlv(const char *tag_seq,ASN_BUF *asnbuf) +{ + u_char tlvbuf[256]; + int len; + len=get_tlv(tag_seq,tlvbuf,asnbuf); + showbuf(tlvbuf,len); + return 1; +} + +int test7() //decoding test(long length) +{ + u_char msg_buf[256]={0x60,0x80, + 0x80,0x02,0x07,0x80, + 0xa1,0x80, + 0x06,0x07,0x04,0x00,0x00,0x01,0x00,0x01,0x02, + 0x00,0x00, + 0x00,0x00}; + ASN_BUF asnbuf; + asn_decode(msg_buf,1,&asnbuf); + showtlv("0",&asnbuf); + showtlv("0.0",&asnbuf); + showtlv("0.1",&asnbuf); + showtlv("0.1.6",&asnbuf); + return 1; +} + +int test8() //decoding test(long length) +{ + u_char msg_buf[256]={0x10,0x03,0xaa,0xbb,0xcc}; + ASN_BUF asnbuf; + asn_decode(msg_buf,1,&asnbuf); + printf("tlvcount=%d\n",asnbuf.tlvcount); + showtlv("16",&asnbuf); + return 1; +} + +int test9() +{ + u_char msg_buf[256]={0x02,0x01,0xaa, + 0x04,0x02,0xbb,0xbb, + 0x04,0x02,0xcc,0xcc, + 0x04,0x02,0xdd,0xdd, + 0x02,0x01,0xaa, + 0x05,0x02,0x55,0xbb, + 0x05,0x02,0x55,0xcc, + 0x05,0x02,0x55,0xdd}; +// u_char mybuf[64]; +// int len; + int temp; + ASN_BUF asnbuf; + asn_decode_v3(msg_buf,30,&temp,&asnbuf); + + showtlv("2",&asnbuf); + showtlv("4-2",&asnbuf); + showtlv("4-3",&asnbuf); + showtlv("4-4",&asnbuf); + return 1; +} + +int test10() +{ + u_char msg_buf[256]={0xA0,0x80, + 0x04,0x01,0x21, + 0x30,0x80, + 0x30,0x80, + 0x83,0x01,0x11, + 0x84,0x01,0x07, + 0x85,0x05,0x81,0x21,0x84,0x00,0x94, + 0x86,0x01,0x00, + 0x00,0x00, + 0x00,0x00, + 0x00,0x00}; + u_char mybuf[64]; + int len; + ASN_BUF asnbuf; + if(asn_decode(msg_buf,1,&asnbuf)==-1) + printf("decode error\n"); + + len=get_tlv("0",mybuf,&asnbuf); + printf("0:"); + showbuf(mybuf,len); + + len=get_tlv("0.4",mybuf,&asnbuf); + printf("0.4:"); + showbuf(mybuf,len); + + len=get_tlv("0.16",mybuf,&asnbuf); + printf("0.16:"); + showbuf(mybuf,len); + + len=get_tlv("0.16.16.5",mybuf,&asnbuf); + printf("0.16.5:"); + showbuf(mybuf,len); + return 1; +} + +int test11() +{ + u_char msg_buf[256]={0x64,0x6A,0x49 + ,0x04,0x01,0x62,0x00,0x60,0x6B,0x80,0x28,0x80,0x06,0x07,0x00,0x11 + ,0x86,0x05,0x01,0x01,0x01,0xA0,0x80,0x61,0x80,0x80,0x02,0x07,0x80 + ,0xA1,0x80,0x06,0x07,0x04,0x00,0x00,0x01,0x00,0x05,0x02,0x00,0x00 + ,0xA2,0x80,0x02,0x01,0x00,0x00,0x00,0xA3,0x80,0xA1,0x80,0x02,0x01 + ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + ,0x6C,0x26,0xA2,0x80,0x02,0x01,0x00,0x30,0x80,0x02,0x01,0x16,0x30 + ,0x80,0x04,0x08,0x64,0x00,0x92,0x00,0x00,0x00,0x00,0xF1,0x04,0x08 + ,0x91,0x44,0x57,0x25,0x31,0x06,0x20,0xF0,0x00,0x00,0x00,0x00,0x00,0x00 + }; +// u_char mybuf[64]; +// int len; + ASN_BUF asnbuf; + if(asn_decode(msg_buf,1,&asnbuf)==-1) + printf("decode error\n"); + return 1; +} + +int test12() +{ + u_char msg_buf[256]={0xA1,0x0E, + 0x01,0x01,0x01, + 0x02,0x80,0x02,0x01,0x01,0x00,0x00, + 0x02,0x02,0x01,0x02 + }; +// u_char mybuf[64]; +// int len; + ASN_BUF asnbuf; + if(asn_decode(msg_buf,1,&asnbuf)==-1) + printf("decode error\n"); + return 1; +} + diff --git a/plat/public/ut/bisearch/bisearch_test.c b/plat/public/ut/bisearch/bisearch_test.c new file mode 100644 index 0000000..4a7cbd0 --- /dev/null +++ b/plat/public/ut/bisearch/bisearch_test.c @@ -0,0 +1,149 @@ + +/******************************************/ +/*Title : bisearch.h */ +/*Descr : BiSearch arithmetic Tester */ +/*Author : Liu Wei */ +/*Create : 2006-12-13 */ +/*Version : R1V00_01 */ +/*Modify : 2006-12-13 */ +/******************************************/ +#include "../../iptrans/src/include/iptrans.h" +#include "./include/bisearch.h" + +FILE *fp = NULL; +BiSearchArray bsearch_array; + + +int GetIdleNode(int *nDUIndex) +{ + if( bsearch_array.nArrayCount >= bsearch_array.nArrayTotalLen ) + return 0; + *nDUIndex = (rand()*19)%bsearch_array.nArrayTotalLen; + return 1; +} + +void logarray ( BiSearchArray * pBiArray, char *op ) +{ + BiSearch *pBS; + LL lastkey = 0; + int nPos = -1; + char buf[4096]; + char tmp_str[512]; + int i; + buf[0] = '\0'; + + sprintf ( buf, "Array Contents:[total :%d]\n" , pBiArray->nArrayCount); + for ( i = 0; i < pBiArray->nArrayTotalLen; i++ ) + { + pBS = pBiArray->pBiArray + i; + sprintf ( tmp_str, "{%-3u,(%-3llu,%-3u)} ", i, pBS->llKey, pBS->nDUPosIndex ); + strcat ( buf, tmp_str ); + if( i % 6 == 5 ) + { + strcat ( buf, "\n" ); + } + if( lastkey > pBS->llKey && i < pBiArray->nArrayCount ) + nPos = i; + lastkey = pBS->llKey; + } + //if( nPos != -1 ) + { + sprintf ( tmp_str, "\nERR Pos: %d\n\n", nPos ); + strcat ( buf, tmp_str ); + fprintf ( fp, buf ); + } +} + +#define log() logarray( &bsearch_array , op) + +int main ( int argc, char *argv[] ) +{ + + char op[32]; + char buff[64]; + int i; + srand((int)time(0)); + + if( ( fp = fopen ( "./log.txt", "w" ) ) == NULL ) + { + printf ( "Open File Fail\n" ); + return 0; + } + fprintf ( fp, "======================\n" ); + fprintf ( fp, "|| BiSearch Test ||\n" ); + fprintf ( fp, "======================\n\n\n" ); + + for ( i = 0; i < 32; i++ ) + { + op[i] = 'A' + ( i * 3 + 11 ) % 26; + buff[i] = op[i] + ( i * 7 + 19 ) % 26; + } + + BISearchReg ( &bsearch_array, 64 ,GetIdleNode ); + + for ( i = 0; i < 30; i++ ) + { + int key = ( ( i * 11 ) % 5 ) * ( i % 5 ) - 3 * ( i % 11 ) + 39; + int value = (3 * i + 1)%bsearch_array.nArrayTotalLen; + + fprintf ( fp, "Insert(%-3d, %-3d)\n", key, value ); + BISInsert ( &bsearch_array, key, value ); + log(); + } + log(); + + for ( i = 0; i < 128; i++ ) + { + int k = ( ( i * 11 ) % 7 ) * ( i % 9 ) - 3 * ( i % 13 ) + i * ( rand ( ) % 13 * 19 ) + 61; + + k = k % 999; + fprintf ( fp, "=====>>Insert(%d, %d)\n", k, 2 * i ); + BISInsert ( &bsearch_array, k, (2 * i+rand() % 13 * 19 + i*19)%bsearch_array.nArrayTotalLen); + fprintf ( fp, "\n" ); + log(); + + k = ( ( 20 - i ) % 3 ) * 9 - ( 3 * ( 20 - i ) ) + 9*128; + k = k % 999; + fprintf ( fp, "search index: %d" , k ); + if( -1 != GetDUIndex( &bsearch_array ,k ) ) + { + fprintf ( fp, "<<=====Delete Key %d\n", k ); + BISDelete ( &bsearch_array , k ); + } + else + fprintf ( fp, "<<=====Delete Fail , not found [%d]", k ); + fprintf ( fp, "\n" ); + log(); + + } + + for( i = 0 ; i < 128 ; i++ ) + { + int nDUIndex = 0; + int k = ( ( i * 11 ) % 7 ) * ( i % 9 ) - 3 * ( i % 13 ) + i * ( rand ( ) % 13 * 19 ) + 61; + + k = k % 999; + BISSearchMng( &bsearch_array , BIS_INSERT , k , &nDUIndex ); + fprintf ( fp, "=====>>Insert(%d, %d)\n", k, nDUIndex ); + fprintf ( fp, "\n" ); + log(); + + k = ( ( i * 11 ) % 7 ) * ( i % 9 ) - 3 * ( i % 13 ) + i * ( rand ( ) % 13 * 19 ) + 61; + k = k % 999; + fprintf ( fp, "search index: %d" , k ); + if( -1 != GetDUIndex( &bsearch_array ,k ) ) + { + fprintf ( fp, "<<=====Delete Key %d\n", k ); + BISSearchMng( &bsearch_array , BIS_DELETE , k ,&nDUIndex); + } + else + fprintf ( fp, "<<=====Delete Fail , not found [%d]", k ); + + fprintf ( fp, "\n" ); + log(); + + } + //fclose ( fp ); + BISearchUnReg ( &bsearch_array); + return 0; +} diff --git a/plat/public/ut/debug_api/debug b/plat/public/ut/debug_api/debug new file mode 100644 index 0000000000000000000000000000000000000000..53d4011ae6cf2bc5728e8ce1083b6fc21b93e097 GIT binary patch literal 11872 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 +#include + +void dump(int signo) +{ + char buf[1024]; + char cmd[1024]; + FILE *fh; + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getpid()); + if(!(fh = fopen(buf, "r"))) + exit(0); + if(!fgets(buf, sizeof(buf), fh)) + exit(0); + fclose(fh); + if(buf[strlen(buf) - 1] == '\n') + buf[strlen(buf) - 1] = '\0'; + snprintf(cmd, sizeof(cmd), "gdb %s %d", buf, getpid()); + system(cmd); + + exit(0); +} + +void WxcBackTrace() +{ + int i; + void * array[25]; + int nSize = backtrace(array, 25); + char ** symbols = backtrace_symbols(array, nSize); + + for (i = 0; i < nSize; i++) + { + printf("%s \n" , symbols[i]); + } + free(symbols); +} + +typedef unsigned char BYTE; + +#define WxcAssert(uVal,pStr) \ + if(!(uVal)) \ + { \ + WxcBackTrace(); \ + } \ + assert( uVal && pStr ); \ + +void sprintf_bcd( const BYTE *pBcdBuff , int nBcdLen , char *pStrBuff , int nStrBuffSize ) +{ + int i ,len = 0; + int nChar; + + nChar = ( nBcdLen % 8 )* 3 + ( nBcdLen / 8 ) * 25 + 1 ; + + WxcAssert((nChar < nStrBuffSize),"sprint bcd string buffer flow"); + + for( i = 1 ; i <= nBcdLen; i ++ ) + { + sprintf ( pStrBuff + len , "%02X ", pBcdBuff[i-1] ); + len += 3; + if( 0 == (i % 16) ) + { + strcat ( pStrBuff , "\n"); + len++; + } + else if( 0 == (i % 8) ) + { + strcat ( pStrBuff , " "); + len++; + } + } + if( 0 != (len % 50) ) + { + strcat ( pStrBuff , "\n"); + } +} + +void testdump(char *p) +{ + *p =0; +} + +void main() +{ + BYTE aBCDBuff[128]; + char temp[256] ; + int i , j; + char *p ; + + p = NULL; + + signal(SIGSEGV, &dump); + + for( i = 0 ; i < 128 ; i ++ ) + { + if( i < 80 ) + aBCDBuff[i] = (BYTE)(1 + i) ; + else + aBCDBuff[i] = (BYTE)(256 - i*2) ; + } + + for( j = 30 ; j < 100 ; j+=7 ) + { + sprintf_bcd(aBCDBuff , j , temp , 256 ); + printf("BCD:\r\n%s\r\n", temp); + } + + testdump(p); + getchar(); +} diff --git a/plat/public/ut/function.c b/plat/public/ut/function.c new file mode 100644 index 0000000..54a4b8a --- /dev/null +++ b/plat/public/ut/function.c @@ -0,0 +1,87 @@ +/* public function c file */ +/* written by Liu Zhiguo 2002-03-26 */ +/* version 1.0 */ +/* -------------------------------- */ + +#include "./include/includes.h" +#include "./include/public.h" +#include "./include/pub_debug.h" + +# ifndef S_SPLINT_S +/*@ignore@*/ +/* ++++++++++++++++++++++++++++++++++++++ */ +/* transfer ascii code to bcd code */ +/* ++++++++++++++++++++++++++++++++++++++ */ +/* +void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len) +{ + int i; + char ch; + char flag=0; + + if (ascii_buf == NULL) + { + for (i=0;i='a') + ch -= 'a' - 10; + else if (ch>='A') + ch -= 'A' - 10; + else + ch -= '0'; + if (flag) + { + if (i & 1) + *bcd_buf = ch << 4; + else + *(bcd_buf++) |= ch & 0x0f; + } + else + { + if (i & 1) + *(bcd_buf++) |= ch & 0x0f; + else + *bcd_buf = ch << 4; + } + } +} +*/ +/* ++++++++++++++++++++++++++++++++++++++ */ +/* transfer bcd code to ascii code */ +/* ++++++++++++++++++++++++++++++++++++++ */ +/* +void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len) +{ + int i; + char ch; + + if (bcd_buf == NULL) + { + for (i=0;i> 4; + ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0'); + } + ascii_buf[i] = '\0'; +} +*/ + +/*@end@*/ +#endif diff --git a/plat/public/ut/inet/pub_inet_test.c b/plat/public/ut/inet/pub_inet_test.c new file mode 100644 index 0000000..24148de --- /dev/null +++ b/plat/public/ut/inet/pub_inet_test.c @@ -0,0 +1,648 @@ +////////////////////////////////////////////////// +//Title : pub_inet_test.c +//Auhtor : Liu Wei +//Desc : public ipnet function test +//Created : 2007-06-22 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned char u8; +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned long long u64; + + +#define MAXINTERFACES 16 + +typedef struct EIF +{ + u32 dIfIP; + u8 uIfState; +} +EIF; + +typedef struct IF_ADDR +{ + EIF tIfEntity[MAXINTERFACES]; + u8 uIfNum; +} +IfAddr; + +int GetNetIfInfo ( IfAddr * pIfAddr ) +{ + int fd; + struct ifreq buf[MAXINTERFACES]; + struct arpreq arp; + struct ifconf ifc; + + pIfAddr->uIfNum = 0; + + if( ( fd = socket ( AF_INET, SOCK_DGRAM, 0 ) ) >= 0 ) + { + ifc.ifc_len = sizeof buf; + ifc.ifc_buf = ( caddr_t ) buf; + if( !ioctl ( fd, SIOCGIFCONF, ( char * ) &ifc ) ) + { + int i; + + pIfAddr->uIfNum = ifc.ifc_len / sizeof ( struct ifreq ); + pIfAddr->uIfNum = pIfAddr->uIfNum % MAXINTERFACES; + for ( i = 0; i < pIfAddr->uIfNum; i++ ) + { + ioctl ( fd, SIOCGIFFLAGS, ( char * ) &buf[i] ); + pIfAddr->tIfEntity[i].uIfState = buf[i].ifr_flags & IFF_UP; + if( !( ioctl ( fd, SIOCGIFADDR, ( char * ) &buf[i] ) ) ) + { + pIfAddr->tIfEntity[i].dIfIP = ( ( struct sockaddr_in * ) + ( &buf[i].ifr_addr ) )->sin_addr.s_addr; + } + } + } + + } + close ( fd ); + return pIfAddr->uIfNum; +} + + +#define PACKET_SIZE 4096 +#define MAX_NO_PACKETS 3 + +struct sockaddr_in dest_addr; +struct sockaddr_in from; +struct timeval tvrecv; + +typedef void PingCallBack( int nPingResult ); + +typedef struct ICMP_SERVICE +{ + u8 uSrvState; + u8 uPingResult; + u8 uIcmpState; + u8 uPackNo; + u8 uDataLen; + u8 nPackNumSend; + u8 nPackNumRecv; + u8 aSendBuff[PACKET_SIZE]; + u8 aRecvBuff[PACKET_SIZE]; + u32 wSockfd; + pid_t tPid; + struct protoent *pProtoent; + PingCallBack *fCallBack; +} +IcmpSrv; + +IcmpSrv tIcmpSrvEntity; + +//УÑéºÍËã·¨ +u16 IcmpCheckSum ( u16 *addr, int len ) +{ + int nleft = len; + int sum = 0; + u16 *w = addr; + u16 answer = 0; + + //°ÑICMP±¨Í·¶þ½øÖÆÊý¾ÝÒÔ2×Ö½ÚΪµ¥Î»ÀÛ¼ÓÆðÀ´ + while ( nleft > 1 ) + { + sum += *w++; + nleft -= 2; + } + + //ÈôICMP±¨Í·ÎªÆæÊý¸ö×Ö½Ú£¬»áÊ£ÏÂ×îºóÒ»×Ö½Ú¡£ + //°Ñ×îºóÒ»¸ö×Ö½ÚÊÓΪһ¸ö2×Ö½ÚÊý¾ÝµÄ¸ß×Ö½Ú£¬Õâ¸ö2×Ö½ÚÊý¾ÝµÄµÍ×Ö½ÚΪ0£¬¼ÌÐøÀÛ¼Ó + if( nleft == 1 ) + { + *( unsigned char * ) ( &answer ) = *( unsigned char * ) w; + sum += answer; + } + + sum = ( sum >> 16 ) + ( sum & 0xffff ); + sum += ( sum >> 16 ); + answer = ~sum; + + return answer; +} + +//ÉèÖÃICMP±¨Í· +int IcmpPacking ( IcmpSrv *pIS ) +{ + int i, packsize; + struct icmp *icmp; + struct timeval *tval; + + icmp = ( struct icmp * ) pIS->aSendBuff; + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_code = 0; + icmp->icmp_cksum = 0; + icmp->icmp_seq = pIS->nPackNumSend; + icmp->icmp_id = pIS->tPid; + packsize = 8 + pIS->uDataLen; + + //¼Ç¼·¢ËÍʱ¼ä + tval = ( struct timeval * ) icmp->icmp_data; + gettimeofday ( tval, NULL ); + + icmp->icmp_cksum = IcmpCheckSum ( (u16 *)icmp, packsize ); + + return packsize; +} + +//°þÈ¥ICMP±¨Í· +int IcmpUnPack ( u8 *buf, int len , IcmpSrv *pIS ) +{ + int i, nIpHdrLen; + struct ip *pIP; + struct icmp *icmp; + struct timeval *tvSend; + struct timeval tvRecv; + double rtt; + + + gettimeofday ( &tvRecv, NULL ); + pIP = ( struct ip * ) buf; + //Çóip±¨Í·³¤¶È,¼´ip±¨Í·µÄ³¤¶È±êÖ¾³Ë4 + nIpHdrLen = pIP->ip_hl << 2; + + //Ô½¹ýip±¨Í·,Ö¸ÏòICMP±¨Í· + icmp = ( struct icmp * ) ( buf + nIpHdrLen ); + + //ICMP±¨Í·¼°ICMPÊý¾Ý±¨µÄ×ܳ¤¶È + len -= nIpHdrLen; + + if( len < 8 ) + //СÓÚICMP±¨Í·³¤¶ÈÔò²»ºÏÀí + { + printf ( "ICMP packets's length is less than 8 " ); + return 0; + } + + //È·±£Ëù½ÓÊÕµÄÊÇÎÒËù·¢µÄµÄICMPµÄ»ØÓ¦ + if( ( icmp->icmp_type == ICMP_ECHOREPLY ) && ( icmp->icmp_id == pIS->tPid ) ) + { + tvSend = ( struct timeval * ) icmp->icmp_data; + + rtt = ( tvRecv.tv_sec * 1000 + tvRecv.tv_usec / 1000 ) - + ( tvSend->tv_sec * 1000 + tvSend->tv_usec / 1000 ); + + printf ( "%d byte from %s: icmp_seq=%u ttl=%d rtt=%.3f ms \n" + , len, inet_ntoa ( from.sin_addr ) + , icmp->icmp_seq, pIP->ip_ttl, rtt + ); + return 1; + } + return 0; +} + +void IcmpStatis ( IcmpSrv *pIS ) +{ + int nSend , nRecv ; + + nSend = pIS->nPackNumSend; + nRecv = pIS->nPackNumRecv; + + printf ( " --------------------PING statistics------------------- \n" ); + printf ( "%d packets transmitted, %d received , %%%d lost \n\n" + , nSend, nRecv, ( nSend - nRecv ) / nSend * 100 ); + close ( pIS->wSockfd ); + pIS->uSrvState = 0; +} + +//·¢ËÍÈý¸öICMP±¨ÎÄ +int IcmpSend ( IcmpSrv *pIS ) +{ + int nSize; + + if ( pIS->nPackNumSend < MAX_NO_PACKETS ) + { + pIS->nPackNumSend++; + nSize = IcmpPacking ( pIS ); + + //ÉèÖÃICMP±¨Í· + if( sendto ( pIS->wSockfd, pIS->aSendBuff, nSize, 0, + ( struct sockaddr * ) &dest_addr, sizeof ( dest_addr ) ) < 0 ) + { + perror ( "sendto error" ); + return 0; + } + printf("[IcmpSend] : Send icmp Pack %d \n" , pIS->nPackNumSend); + return 1; + } + return 0; +} + +//½ÓÊÕËùÓÐICMP±¨ÎÄ +void IcmpRecv ( IcmpSrv *pIS ) +{ + int n, fromlen; + extern int errno; + + + fromlen = sizeof ( from ); + while ( pIS->nPackNumRecv < pIS->nPackNumSend ) + { + if( ( n = recvfrom ( pIS->wSockfd, pIS->aRecvBuff, sizeof ( pIS->aRecvBuff ), + 0, ( struct sockaddr * ) &from, &fromlen ) ) < 0 ) + + { + if( errno == EINTR ) + continue; + perror ( "recvfrom error" ); + continue; + } + if( IcmpUnPack ( pIS->aRecvBuff, n , pIS ) == -1 ) + continue; + pIS->nPackNumRecv++; + } +} + +int PingInit ( IcmpSrv *pIS , int nDataLen ) +{ + memset( pIS , 0 , sizeof(IcmpSrv) ); + pIS->uSrvState = 0; + + pIS->uDataLen = 56; + + + if( ( pIS->pProtoent = getprotobyname ( "icmp" ) ) == NULL ) + { + perror ( "getprotobyname" ); + exit ( 1 ); + } + + // »ØÊÕrootȨÏÞ,ÉèÖõ±Ç°Óû§È¨ÏÞ + setuid ( getuid ( ) ); + + //»ñÈ¡mainµÄ½ø³Ìid,ÓÃÓÚÉèÖÃICMPµÄ±êÖ¾·û + pIS->tPid = getpid ( ); + +} + + +int PingTimer ( IcmpSrv *pIS ) +{ + if( pIS->uSrvState ) + { + IcmpRecv( pIS ); + switch( pIS->uIcmpState ) + { + case 1: + case 2: + case 3: + IcmpSend( pIS ); + pIS->uIcmpState++; + break; + default: + if( pIS->nPackNumRecv >= 3 ) + { + IcmpStatis( pIS ); + pIS->fCallBack( 1 ); + } + if( pIS->uIcmpState++ > 200 ) + { + IcmpStatis( pIS ); + pIS->fCallBack( 0 ); + } + break; + } + } +} + +int PingStart( IcmpSrv *pIS , char *sIP , PingCallBack fCallBack ) +{ + int nSize; + struct hostent *pHost; + //struct in_addr *pInAddr; + u32 nInetAddr; + + + if( pIS->uSrvState ) + { + return 0; + } + + pIS->fCallBack = fCallBack; + + //Éú³ÉʹÓÃICMPµÄԭʼÌ×½Ó×Ö,ÕâÖÖÌ×½Ó×ÖÖ»ÓÐroot²ÅÄÜÉú³É + if( ( pIS->wSockfd = socket ( AF_INET, SOCK_RAW, pIS->pProtoent->p_proto ) ) < 0 ) + { + perror ( "socket error" ); + exit ( 1 ); + } + + //À©´óÌ×½Ó×Ö½ÓÊÕ»º³åÇøµ½50KÕâÑù×öÖ÷ҪΪÁ˼õС½ÓÊÕ»º³åÇøÒç³öµÄ + //µÄ¿ÉÄÜÐÔ, ÈôÎÞÒâÖÐping»áÒýÀ´´óÁ¿Ó¦´ð + setsockopt ( pIS->wSockfd, SOL_SOCKET, SO_RCVBUF, &nSize, sizeof ( nSize ) ); + bzero ( &dest_addr, sizeof ( dest_addr ) ); + dest_addr.sin_family = AF_INET; + + //ÅжÏÊÇÖ÷»úÃû»¹ÊÇipµØÖ· + nInetAddr = inet_addr ( sIP ) ; + if( nInetAddr == INADDR_NONE ) + { + if( ( pHost = gethostbyname ( sIP ) ) == NULL ) //ÊÇÖ÷»úÃû + { + perror ( "gethostbyname error" ); + exit ( 1 ); + } + memcpy ( ( char * ) &dest_addr.sin_addr, pHost->h_addr, pHost->h_length ); + } + else //ÊÇipµØÖ· + { + dest_addr.sin_addr.s_addr = nInetAddr; + //memcpy( (char *)&dest_addr,(char *)&nInetAddr,host->h_length); + } + printf ( "PING %s(%s): %d bytes data in ICMP packets. \n", sIP + , inet_ntoa ( dest_addr.sin_addr ) , pIS->uDataLen ); + + pIS->uSrvState = 1 ; + pIS->uIcmpState = 1; + +} + +//´òÓ¡ip±¨ÎĵÄÐÅÏ¢ +void printIP ( char *packet, int len ) +{ + struct sockaddr_in addr_src, addr_dst; + struct ip *pip = ( struct ip * ) packet; + + printf ( "ip head len:%d ", pip->ip_hl << 2 ); + printf ( "ip len:%d ", ntohs ( pip->ip_len ) ); + printf ( "ip pro id:%d ", pip->ip_p ); + printf ( "ip ttl:%d ", pip->ip_ttl ); + printf ( "ip offset:%d ", ntohs ( pip->ip_off ) & IP_OFFMASK ); + + memset ( &addr_src, 0, sizeof ( struct sockaddr_in ) ); + memset ( &addr_dst, 0, sizeof ( struct sockaddr_in ) ); + memcpy ( &addr_src, &pip->ip_src, sizeof ( struct sockaddr_in ) ); + memcpy ( &addr_dst, &pip->ip_dst, sizeof ( struct sockaddr_in ) ); + printf ( "src ip:%x ", addr_src.sin_addr ); + printf ( "dst ip:%x ", addr_dst.sin_addr ); +} + +void NetCapPing( int nRet ) +{ + if( nRet ) + { + printf("Host is rearchable\n"); + } + else + { + printf("Host is not rearchable\n"); + } +} + +static char *pStrEqTok = NULL; +static u8 uStrEqState = 0; + +#define CNULL '\0' +#define STR_CHECK_END(str,ch) ( str[strlen(str)-1] == ch ) +#define STR_CUT_LAST(str) ( str[strlen(str)-1] = CNULL ) + +void StrTrimMoreSpace(char *pStr ) +{ + char *pSrc , *pDst , *pCh; + + pDst = pStr; + pCh = pSrc = strdup( pStr ); + + for( ; *pSrc ; pSrc++ ) + { + if( !( isspace(*pSrc) && isspace( *(pSrc+1) ) ) ) + { + *pDst++ = *pSrc; + } + } + *pDst = CNULL; +} + +char *StrEqTok( char *pStr ) +{ + char *p, *pCh; + char *pDel = " "; + + pCh = NULL; + + if( pStr == NULL ) + { + pStr = pStrEqTok; + } + else + { + pStr += strspn (pStr, pDel); + if (*pStr == '\0') + { + pStrEqTok = NULL; + return NULL; + } + StrTrimMoreSpace( pStr ); + } + + if( pStr == NULL ) + { + return NULL; + } + + uStrEqState = uStrEqState > 2 ? 0 : uStrEqState; + + pCh = strpbrk (pStr, pDel ); + if( pCh == NULL ) + { + pStrEqTok = NULL; + pCh = pStr; + } + else + { + pStrEqTok = pCh + 1; + *pCh = CNULL; + pCh = pStr; + } + + p = strchr( pCh , '='); + if( p == NULL ) + { + if( pStrEqTok == NULL ) + { + goto STREQTOK_CLEAN_UP; + } + + if( uStrEqState == 0 || uStrEqState == 2 ) + { //expres left and right + uStrEqState++; + return pCh; + } + else + { //Miss '=' + goto STREQTOK_CLEAN_UP; + } + } + else + { + if( uStrEqState == 0 && STR_CHECK_END( pCh , '=') ) + { //expres left and '=' + uStrEqState+=2; + STR_CUT_LAST(pCh); + return pCh; + } + else if( uStrEqState == 1 && pCh[0] == '=') + { //'=' meet + if( pCh[1] == CNULL ) + { + if( pStrEqTok == NULL ) + { + goto STREQTOK_CLEAN_UP; + } + pStr = pStrEqTok; + pCh = strpbrk (pStr, pDel); + if( pCh == NULL ) + { + pStrEqTok = NULL; + pCh = pStr; + } + else + { + pStrEqTok = pCh + 1; + *pCh = CNULL; + pCh = pStr; + } + uStrEqState = 3; + return pCh; + + } + else + { //expres '=' and right + uStrEqState = 3; //all meet + return ++pCh; + } + } + else if( uStrEqState == 0 ) + { //expres left and '=' and right + if( pStrEqTok != NULL ) + { + *(pStrEqTok -1) = ' '; + } + pStrEqTok = p + 1; + *p = CNULL; + uStrEqState = 2; + return pCh; + } + else + { + goto STREQTOK_CLEAN_UP; + } + } +STREQTOK_CLEAN_UP: + pStrEqTok = NULL; + uStrEqState = 0; + return NULL; +} + + +int main ( ) +{ + int i, ret = 0; + IfAddr tIfAddr; + IcmpSrv tIcmpSrv; + char tmpStr[80]; + + ret = GetNetIfInfo ( &tIfAddr ); + + printf ( "Interface num :%d \n\n", ret ); + for ( i = 0; i < ret; i++ ) + { + printf ( "If %d : state : %d ip : %s \n\n" + , i, tIfAddr.tIfEntity[i].uIfState + , inet_ntoa ( *((struct in_addr* )&tIfAddr.tIfEntity[i].dIfIP )) + ); + } + + #define STR(s) #s + printf(STR(if(NOTSO(a)) return 0\n)); + + #define FPOS( type, field ) /*lint -e545 */ ( (u32) &(( type *) 0)-> field ) /*lint +e545 */ + + + #define FSIZ( type, field ) sizeof( ((type *) 0)->field ) + + printf("Pos : %ld \n" , FPOS(IfAddr ,uIfNum ) ); + printf("Size : %ld \n" , FSIZ(IfAddr ,uIfNum ) ); + printf("Pos : %ld \n" , FPOS(IfAddr ,tIfEntity ) ); + printf("Size : %ld \n" , FSIZ(IfAddr ,tIfEntity ) ); + printf("Pos : %ld \n" , FPOS(EIF ,dIfIP ) ); + printf("Size : %ld \n" , FSIZ(EIF ,dIfIP ) ); + printf("Pos : %ld \n" , FPOS(EIF ,uIfState ) ); + printf("Size : %ld \n" , FSIZ(EIF ,uIfState ) ); + printf("Pos : %ld \n" , FPOS(IcmpSrv ,nPackNumSend ) ); + printf("Size : %ld \n" , FSIZ(IcmpSrv ,nPackNumSend ) ); + printf("Pos : %ld \n" , FPOS(IcmpSrv ,aSendBuff ) ); + printf("Size : %ld \n" , FSIZ(IcmpSrv ,aSendBuff ) ); + + printf("Please input ip and port : "); + + fgets( tmpStr, 80 ,stdin ); + + printf("%s\n", tmpStr); + if( STR_CHECK_END(tmpStr , '\n' ) ) + { + STR_CUT_LAST(tmpStr ); + } + //StrTrimMoreSpace(tmpStr); + //printf("trim space : \n%s\n" ,tmpStr ); + + { + char *p = NULL; + u8 uFlag = 0; + + p = StrEqTok(tmpStr); + printf( "Name: %-20s " , p); + for( ; p = StrEqTok(NULL); ) + { + uFlag = uFlag ? 0 : 1; + if( uFlag ) + { + printf( "Valu: %-20s \n" , p); + } + else + { + printf( "Name: %-20s " , p); + } + } + } + printf("\n\n"); + PingInit( &tIcmpSrv , 56 ); + + ret = PingStart( &tIcmpSrv , "172.18.99.1" , NetCapPing ); + if( !ret ) + { + printf("ping is processing\n"); + } + + while(1) + { + PingTimer( &tIcmpSrv ); + sleep ( 1 ); + //ÿ¸ôÒ»Ãë·¢ËÍÒ»¸öICMP±¨ÎÄ + } + return 1; +} diff --git a/plat/public/ut/main/Makefile b/plat/public/ut/main/Makefile new file mode 100644 index 0000000..8accec4 --- /dev/null +++ b/plat/public/ut/main/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module Version : V1.4 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/06/18 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + + + +MODULE = publictest +TYPE = plat + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = exef +CFG = debug + +PLT_LIB = public +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../../../plat +APP_PATH = ../../../../mss + +OBJ_ADD = +TEST_OBJ_PATH = ../../obj + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = on +COVER_NEED = +COVER_REPORT_PATH = ./ut/ut_doc/output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules + + + diff --git a/plat/public/ut/main/bin/.svn/all-wcprops b/plat/public/ut/main/bin/.svn/all-wcprops new file mode 100644 index 0000000..8678e91 --- /dev/null +++ b/plat/public/ut/main/bin/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/public/ut/main/bin +END diff --git a/plat/public/ut/main/bin/.svn/entries b/plat/public/ut/main/bin/.svn/entries new file mode 100644 index 0000000..42ed560 --- /dev/null +++ b/plat/public/ut/main/bin/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/public/ut/main/bin +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + diff --git a/plat/public/ut/main/obj/.svn/all-wcprops b/plat/public/ut/main/obj/.svn/all-wcprops new file mode 100644 index 0000000..16eec1c --- /dev/null +++ b/plat/public/ut/main/obj/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/public/ut/main/obj +END diff --git a/plat/public/ut/main/obj/.svn/entries b/plat/public/ut/main/obj/.svn/entries new file mode 100644 index 0000000..d10ba2d --- /dev/null +++ b/plat/public/ut/main/obj/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/public/ut/main/obj +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + diff --git a/plat/public/ut/main/src/.svn/all-wcprops b/plat/public/ut/main/src/.svn/all-wcprops new file mode 100644 index 0000000..70b822e --- /dev/null +++ b/plat/public/ut/main/src/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/public/ut/main/src +END +main.c +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/public/ut/main/src/main.c +END diff --git a/plat/public/ut/main/src/.svn/entries b/plat/public/ut/main/src/.svn/entries new file mode 100644 index 0000000..35639b9 --- /dev/null +++ b/plat/public/ut/main/src/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/public/ut/main/src +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +main.c +file + + + + +2012-12-28T03:06:27.578125Z +4a3e0b7b095c32b64c152c36991fc15d +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +399 + diff --git a/plat/public/ut/main/src/.svn/prop-base/main.c.svn-base b/plat/public/ut/main/src/.svn/prop-base/main.c.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/public/ut/main/src/.svn/prop-base/main.c.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/public/ut/main/src/.svn/text-base/main.c.svn-base b/plat/public/ut/main/src/.svn/text-base/main.c.svn-base new file mode 100644 index 0000000..d0e59bf --- /dev/null +++ b/plat/public/ut/main/src/.svn/text-base/main.c.svn-base @@ -0,0 +1,19 @@ +////////////////////////////////////////////////// +//Title : main.c +//Auhtor : Liu Wei +//Desc : public function test +//Created : 2007-06-24 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "../../src/include/includes.h" +#include "../../src/include/public.h" +#include "../../src/include/function.h" + +int main() +{ + return 1; +} diff --git a/plat/public/ut/main/src/main.c b/plat/public/ut/main/src/main.c new file mode 100644 index 0000000..d0e59bf --- /dev/null +++ b/plat/public/ut/main/src/main.c @@ -0,0 +1,19 @@ +////////////////////////////////////////////////// +//Title : main.c +//Auhtor : Liu Wei +//Desc : public function test +//Created : 2007-06-24 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "../../src/include/includes.h" +#include "../../src/include/public.h" +#include "../../src/include/function.h" + +int main() +{ + return 1; +} diff --git a/plat/public/ut/public_test/public_test.c b/plat/public/ut/public_test/public_test.c new file mode 100644 index 0000000..1f92579 --- /dev/null +++ b/plat/public/ut/public_test/public_test.c @@ -0,0 +1,15 @@ +/* public test c file */ +/* Written by Liu Zhiguo 2002-03-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#include "./include/includes.h" +#include "./include/public.h" +#include "./include/function.h" + + + +int main() +{ + return 1; +} diff --git a/plat/public/ut/timer/Makefile b/plat/public/ut/timer/Makefile new file mode 100644 index 0000000..2ceeb9e --- /dev/null +++ b/plat/public/ut/timer/Makefile @@ -0,0 +1,72 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for wxc2 module ## +## --By Wei Liu 2007/04/11 ## +## ## +##----------------------------------------------------------## + + +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +##Module Name +MODULE = tmtest + +#BUILD = lib/exef +BUILD = exef + +#CFG = debug / release +CFG = debug + +#Source file path +SRC_PATH= ./ + +#include file path +INC_PATH= ./ + +#extend wxc2plat module lib need +WXC2_PLT_LIB= public + +#extend wxc2plat module lib need +WXC2_APP_LIB= + +#extend wxc2plat path default to ./wxc2plat +WXC2_PLT_PATH = ../../../../wxc2plat + +#extend wxc2plat path default to ./wxc2app +WXC2_APP_PATH = + +#extend obj needed +CFG_OBJ = + +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +#gcc flag show on/off +CCFLAG_SWITCH = on + +#customer debug version flag add for compile +DEBUG_CFLAGS_ADD = -D_MSCR83 -D_DEVELOPER + +#customer release version flag add for compile +RELEASE_CFLAGS_ADD = -D_MSCR83 + +#need cover fucntion of PTF for test = YES/NO +COVER_NEED = + +#cover fucntion output path of PTF for test +COVER_REPORT_PATH = ./ut/ut_doc/output + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/public/ut/timer/bin/.svn/all-wcprops b/plat/public/ut/timer/bin/.svn/all-wcprops new file mode 100644 index 0000000..0583222 --- /dev/null +++ b/plat/public/ut/timer/bin/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/public/ut/timer/bin +END diff --git a/plat/public/ut/timer/bin/.svn/entries b/plat/public/ut/timer/bin/.svn/entries new file mode 100644 index 0000000..34327c8 --- /dev/null +++ b/plat/public/ut/timer/bin/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/public/ut/timer/bin +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + diff --git a/plat/public/ut/timer/ut/.svn/all-wcprops b/plat/public/ut/timer/ut/.svn/all-wcprops new file mode 100644 index 0000000..313b658 --- /dev/null +++ b/plat/public/ut/timer/ut/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/public/ut/timer/ut +END diff --git a/plat/public/ut/timer/ut/.svn/entries b/plat/public/ut/timer/ut/.svn/entries new file mode 100644 index 0000000..969021e --- /dev/null +++ b/plat/public/ut/timer/ut/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/public/ut/timer/ut +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + diff --git a/plat/public/ut/timer/wxc_tmtest.c b/plat/public/ut/timer/wxc_tmtest.c new file mode 100644 index 0000000..9827845 --- /dev/null +++ b/plat/public/ut/timer/wxc_tmtest.c @@ -0,0 +1,155 @@ + +#include "assert.h" +#include "../../src/include/includes.h" +#include "../../src/include/public.h" +#include "../../src/include/wxc_timer.h" + + +u32 hlr_timer_flag; +u32 hlr_20ms_flag; + +void system_init ( void ) +{ + sleep ( 3 ); + hlr_timer_flag = 0; + hlr_20ms_flag = 0; +} + +void timer_callback ( ) +{ + hlr_20ms_flag++; + hlr_timer_flag++; + printf("10 ms call back : %d\n" , hlr_timer_flag); +} + +void set_timer ( ) +{ + struct sigaction act; + struct itimerval value; + struct itimerval old_value; + + value.it_interval.tv_sec = 0; + value.it_interval.tv_usec = 10000; // 10 ms + value.it_value.tv_sec = 0; + value.it_value.tv_usec = 10000; // 10 ms + act.sa_handler = timer_callback; + sigemptyset ( &act.sa_mask ); + act.sa_flags = 0; + if( sigaction ( SIGALRM, &act, NULL ) == -1 ) + { + printf ( "Timer error\n" ); + exit ( 0 ); + } + setitimer ( ITIMER_REAL, &value, &old_value ); + iopl ( 3 ); +} + +void tm_app_callback_10ms ( u16 dSuitId, u16 dData ) +{ + printf("10 ms call back\n"); +} + +void tm_app_callback_1s ( u16 dSuitId, u16 dData ) +{ + printf("10 ms call back\n"); +} + +void tm_app_callback_50s ( u16 dSuitId, u16 dData ) +{ + printf("10 ms call back\n"); +} + +void tm_app_callback_5000s ( u16 dSuitId, u16 dData ) +{ + printf("10 ms call back\n"); +} + + +void tm_app_init ( ) +{ + +} + +int app_state; +WxcTimer tTimer10ms; +WxcTimer tTimer1s; +WxcTimer tTimer50s; +WxcTimer tTimer5000s; + +typedef enum TMTEST_STATE +{ + APP_REGSITER, + APP_START, + APP_TIMEROUT, + APP_STOP, +} +TM_STATE; + + +void tm_app_test ( ) +{ + + + switch ( app_state ) + { + case APP_REGSITER: + tTimer10ms.dExpires = 1; + tTimer10ms.dSuitNumber = 1; + tTimer10ms.pFunc = &tm_app_callback_10ms; + tTimer10ms.dData = 0; + TimerAdd ( &tTimer10ms ); + + tTimer1s.dExpires = 100; + tTimer1s.dSuitNumber = 10; + tTimer1s.pFunc = &tm_app_callback_1s; + tTimer1s.dData = 0; + TimerAdd ( &tTimer1s ); + + tTimer50s.dExpires = 5000; + tTimer50s.dSuitNumber = 100; + tTimer50s.pFunc = &tm_app_callback_50s; + tTimer50s.dData = 0; + TimerAdd ( &tTimer50s ); + + tTimer5000s.dExpires = 5000000; + tTimer5000s.dSuitNumber = 10; + tTimer5000s.pFunc = &tm_app_callback_5000s; + tTimer5000s.dData = 0; + TimerAdd ( &tTimer5000s ); + app_state++; + break; + + case APP_START: + app_state++; + break; + + case APP_TIMEROUT: + + TimerAdd ( &tTimer50s ); + app_state++; + break; + case APP_STOP: + + TimerAdd ( &tTimer50s ); + app_state++; + break; + default: + break; + } +} + + +int main ( int argc, char *argv[] ) +{ + + system_init ( ); + + set_timer ( ); + + while ( 1 ) + { + usleep ( 1 ); + tm_app_test ( ); + } + return 1; +} diff --git a/plat/radius/Makefile b/plat/radius/Makefile new file mode 100644 index 0000000..b5ed5ea --- /dev/null +++ b/plat/radius/Makefile @@ -0,0 +1,95 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module Version : V1.4 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/06/18 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + + + +MODULE = radius +TYPE = plat + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + +PLT_LIB = +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../app + +OBJ_ADD = +TEST_OBJ_PATH = ../../obj + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/radius/src/include/radius.h b/plat/radius/src/include/radius.h new file mode 100644 index 0000000..981c17b --- /dev/null +++ b/plat/radius/src/include/radius.h @@ -0,0 +1,11 @@ +#ifndef _RADIUS_H +#define _RADIUS_H + +#include "./radius_pub.h" + +int radius_init(void); +void radius_timer(void); +int radius_bind(RADIUS_SAP *sap); + +#endif + diff --git a/plat/radius/src/include/radius_const.h b/plat/radius/src/include/radius_const.h new file mode 100644 index 0000000..7e947df --- /dev/null +++ b/plat/radius/src/include/radius_const.h @@ -0,0 +1,346 @@ +#ifndef _RADIUS_CONST_H +#define _RADIUS_CONST_H + +#define RADIUS_MAX_LEN_OF_SHARE_KEY 128 +#define RADIUS_MAX_LEN_OF_PASSWORD 128 + +#define RADIUS_MAX_NUM_OF_NAS 64 + +#define RADIUS_ACCESS_PORT 1812 +#define RADIUS_ACCOUNTING_PORT 1813 +#define RADIUS_DISCONNECT_PORT 3799 + +#define RADIUS_MAX_NUM_OF_SAP 1 + +#define RADIUS_MAX_LEN_OF_USER_NAME 16 + +#define RADIUS_MAX_LEN_OF_IMSI 16 + +#define RADIUS_RECV_MSG_FLAG 0 +#define RADIUS_SEND_MSG_FLAG 1 + +#define RADIUS_PID_TYPE_IND 1 +#define RADIUS_PID_TYPE_REQ 2 + +#define RADIUS_MAX_NUM_OF_ATTRIBUTE 256 + +#define RADIUS_MAX_LEN_OF_MSG_TYEP 32 + +#define RADIUS_MAX_UDP_MSG_GET_TIMES 32 + +#define RADIUS_MAX_LEN_OF_ATTR 255 +#define RADIUS_TS_VALUE_LEN 253 +#define RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED 250 +#define RADIUS_VALUE_LEN 4 + +#define RADIUS_MAX_LEN_OF_TEMP_BUF 256 + +#define RADIUS_MAX_LEN_OF_MSG 1500 + +#define RADIUS_MAX_LEN_OF_UDP_MSG 1500 + +#define RADIUS_MAX_LEN_FOR_OCTET_STR 4 + +#define RADIUS_MAX_LEN_OF_AUTH 16 + +#define RADIUS_MAX_NUM_OF_PID 8192 + +#define RADIUS_MAX_ASCITMP_LEN 4096 +#define RADIUS_MAX_ASCIIOUT_LEN 4096 +#define RADIUS_MAX_ASCIIIN_LEN 4096 + +#define RADIUS_MONITOR_NONE 0x0000 +#define RADIUS_MONITOR_ERROR 0x0001 +#define RADIUS_MONITOR_WARN 0x0002 +#define RADIUS_MONITOR_EVENT 0x0004 +#define RADIUS_MONITOR_ACCESS_MSG 0x0008 +#define RADIUS_MONITOR_ACCT_MSG 0x0010 +#define RADIUS_MONITOR_DISC_MSG 0x0020 +#define RADIUS_MONITOR_ALL 0xFFFF +#define RADIUS_MONITOR_SDRV_MSG (RADIUS_MONITOR_ACCESS_MSG | RADIUS_MONITOR_ACCT_MSG | RADIUS_MONITOR_DISC_MSG) + +#define RADIUS_REQUEST_MSG 1 +#define RADIUS_RESPONSE_MSG 2 + +#define RADIUS_MSG_TYPE_ACCESS_REQUEST 1 +#define RADIUS_MSG_TYPE_ACCESS_ACCEPT 2 +#define RADIUS_MSG_TYPE_ACCESS_REJECT 3 +#define RADIUS_MSG_TYPE_ACCOUNTING_REQUEST 4 +#define RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE 5 +#define RADIUS_MSG_TYPE_ACCESS_CHALLENGE 11 +#define RADIUS_MSG_TYPE_STATUS_SERVER 12 +#define RADIUS_MSG_TYPE_STATUS_CLIENT 13 +#define RADIUS_MSG_TYPE_DISCONNECT_REQUEST 40 +#define RADIUS_MSG_TYPE_DISCONNECT_ACK 41 +#define RADIUS_MSG_TYPE_DISCONNECT_NAK 42 +#define RADIUS_MSG_TYPE_COA_REQUEST 43 +#define RADIUS_MSG_TYPE_COA_ACK 44 +#define RADIUS_MSG_TYPE_COA_NAK 45 + +#define RADIUS_ATTRIBUTE_TYPE_USER_NAME 1 +#define RADIUS_ATTRIBUTE_TYPE_USER_PASSWORD 2 +#define RADIUS_ATTRIBUTE_TYPE_CHAP_PASSWORD 3 +#define RADIUS_ATTRIBUTE_TYPE_NAS_IP_ADDRESS 4 +#define RADIUS_ATTRIBUTE_TYPE_NAS_PORT 5 +#define RADIUS_ATTRIBUTE_TYPE_SERVICE_TYPE 6 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_PROTOCOL 7 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_ADDR 8 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_NETMASK 9 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTING 10 +#define RADIUS_ATTRIBUTE_TYPE_FILTER_ID 11 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_MTU 12 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_COMPRESSION 13 +#define RADIUS_ATTRIBUTE_TYPE_LOGIN_IP_HOST 14 +#define RADIUS_ATTRIBUTE_TYPE_LOGIN_SERVICE 15 +#define RADIUS_ATTRIBUTE_TYPE_LOGIN_TCP_PORT 16 +#define RADIUS_ATTRIBUTE_TYPE_17 17 +#define RADIUS_ATTRIBUTE_TYPE_REPLY_MESSAGE 18 +#define RADIUS_ATTRIBUTE_TYPE_CALLBACK_NUMBER 19 +#define RADIUS_ATTRIBUTE_TYPE_CALLBACK_ID 20 +#define RADIUS_ATTRIBUTE_TYPE_21 21 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTE 22 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_IPX_NETWORK 23 +#define RADIUS_ATTRIBUTE_TYPE_STATE 24 +#define RADIUS_ATTRIBUTE_TYPE_CLASS 25 +#define RADIUS_ATTRIBUTE_TYPE_VENDOR_SPECIFIC 26 +#define RADIUS_ATTRIBUTE_TYPE_SESSION_TIMEOUT 27 +#define RADIUS_ATTRIBUTE_TYPE_IDLE_TIMEOUT 28 +#define RADIUS_ATTRIBUTE_TYPE_TERMINATION_ACTION 29 +#define RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID 30 +#define RADIUS_ATTRIBUTE_TYPE_CALLING_STATION_ID 31 +#define RADIUS_ATTRIBUTE_TYPE_NAS_IDENTIFIER 32 +#define RADIUS_ATTRIBUTE_TYPE_PROXY_STATE 33 +#define RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_SERVICE 34 +#define RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_NODE 35 +#define RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_GROUP 36 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_LINK 37 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_NETWORK 38 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_ZONE 39 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_STATUS_TYPE 40 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_DELAY_TIME 41 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_OCTETS 42 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_OCTETS 43 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_ID 44 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_AUTHENTIC 45 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_TIME 46 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_PACKETS 47 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_PACKETS 48 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_TERMINATE_CAUSE 49 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_MULTI_SESSION_ID 50 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_LINK_COUNT 51 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_GIGAWORDS 52 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_GIGAWORDS 53 +#define RADIUS_ATTRIBUTE_TYPE_EVENT_TIMESTAMP 55 +#define RADIUS_ATTRIBUTE_TYPE_CHAP_CHALLENGE 60 +#define RADIUS_ATTRIBUTE_TYPE_NAS_PORT_TYPE 61 +#define RADIUS_ATTRIBUTE_TYPE_PORT_LIMIT 62 +#define RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_PORT 63 +#define RADIUS_ATTRIBUTE_TYPE_ARAP_PASSWORD 70 +#define RADIUS_ATTRIBUTE_TYPE_ARAP_FEATURES 71 +#define RADIUS_ATTRIBUTE_TYPE_ARAP_ZONE_ACCESS 72 +#define RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY 73 +#define RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY_DATA 74 +#define RADIUS_ATTRIBUTE_TYPE_PASSWORD_RETRY 75 +#define RADIUS_ATTRIBUTE_TYPE_PROMPT 76 +#define RADIUS_ATTRIBUTE_TYPE_CONNECT_INFO 77 +#define RADIUS_ATTRIBUTE_TYPE_CONFIGURATION_TOKEN 78 +#define RADIUS_ATTRIBUTE_TYPE_EAP_MESSAGE 79 +#define RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR 80 +#define RADIUS_ATTRIBUTE_TYPE_ARAP_CHALLENGE_RESPONSE 84 +#define RADIUS_ATTRIBUTE_TYPE_ACCT_INTERIM_INTERVAL 85 +#define RADIUS_ATTRIBUTE_TYPE_NAS_PORT_ID 87 +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_POOL 88 +#define RADIUS_ATTRIBUTE_TYPE_ORIGINATING_LINE_INFO 94//not support now +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_INTERFACE_ID 96//not support now +#define RADIUS_ATTRIBUTE_TYPE_FRAMED_IPV6_PREFIX 97//not support now +#define RADIUS_ATTRIBUTE_TYPE_ERROR_CAUSE 101 +//non-standard support NOWSMS +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_PREAUTH_TYPE RADIUS_ATTRIBUTE_TYPE_17 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_COUNT_ID_SIZE RADIUS_ATTRIBUTE_TYPE_21 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_SMS 1 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_ACCOUNT_SMS 2 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_MMS 3 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_CHARGE_MMS_SEND 4 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_ACCOUNT_MMS_RETRIEVE 5 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_AUTH_MMSE 6 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_TYPE_VALUE_CHARGE_MMSE 7 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGCOUNT 1 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGID 2 +#define RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_SIZE 3 + +#define RADIUS_VENDOR_ID_WIMAX 24757 + +#define RADIUS_VENDOR_ID_3GPP 10415 +#define RADIUS_VENDOR_ID_3GPP2 5535 + +#define RADIUS_VENDOR_TYPE_3GPP_IMSI 1 +#define RADIUS_VENDOR_TYPE_3GPP_CHARGING_ID 2 +#define RADIUS_VENDOR_TYPE_3GPP_PDP_TYPE 3 +#define RADIUS_VENDOR_TYPE_3GPP_CG_ADDR 4//charging gateway address +#define RADIUS_VENDOR_TYPE_3GPP_NQP 5//negotiated qos profile +#define RADIUS_VENDOR_TYPE_3GPP_SGSN_ADDR 6 +#define RADIUS_VENDOR_TYPE_3GPP_GGSN_ADDR 7 +#define RADIUS_VENDOR_TYPE_3GPP_IMSI_MCC_MNC 8 +#define RADIUS_VENDOR_TYPE_3GPP_GGSN_MCC_MNC 9 +#define RADIUS_VENDOR_TYPE_3GPP_NSAPI 10 +#define RADIUS_VENDOR_TYPE_3GPP_SSI 11//session stop indicator +#define RADIUS_VENDOR_TYPE_3GPP_SM 12//selection mode +#define RADIUS_VENDOR_TYPE_3GPP_CC 13//charging characteristics +#define RADIUS_VENDOR_TYPE_3GPP_CG_IPV6 14//charging gateway ipv6 not support +#define RADIUS_VENDOR_TYPE_3GPP_SGSN_IPV6 15//sgsn ipv6 not support +#define RADIUS_VENDOR_TYPE_3GPP_GGSN_IPV6 16//ggsn ipv6 not support +#define RADIUS_VENDOR_TYPE_3GPP_IPV6_DNS 17//ipv6 DNS servers not support +#define RADIUS_VENDOR_TYPE_3GPP_SGSN_MCC_MNC 18 +#define RADIUS_VENDOR_TYPE_3GPP_TI 19//teardown indicator + +#define RADIUS_VENDOR_TYPE_3GPP2_STC 88 +#define RADIUS_VENDOR_TYPE_3GPP2_PPAQ 90 +#define RADIUS_VENDOR_TYPE_3GPP2_PPAC 91 +#define RADIUS_VENDOR_TYPE_3GPP2_PTS 98 + +#define RADIUS_3GPP2_PPAC_SUBTYPE_AIC 1 +#define RADIUS_3GPP2_PPAC_SUBTYPE_SFS 2 + +#define RADIUS_3GPP2_PPAQ_SUBTYPE_QID 1//quota identifier; access request, access accept +#define RADIUS_3GPP2_PPAQ_SUBTYPE_VQ 2//volume quota; access request, access accept +#define RADIUS_3GPP2_PPAQ_SUBTYPE_VQO 3//volume quota overflow +#define RADIUS_3GPP2_PPAQ_SUBTYPE_VT 4//volume threshold; access accept +#define RADIUS_3GPP2_PPAQ_SUBTYPE_VTO 5//volume threshold overflow +#define RADIUS_3GPP2_PPAQ_SUBTYPE_DQ 6//duration quota; access request, access accept +#define RADIUS_3GPP2_PPAQ_SUBTYPE_DT 7//duration threshold; access accept +#define RADIUS_3GPP2_PPAQ_SUBTYPE_UR 8//update reason; access request +#define RADIUS_3GPP2_PPAQ_SUBTYPE_PS 9//prepaid server; access request, access accept + +#define RADIUS_3GPP2_PTS_SUBTYPE_QID 1 +#define RADIUS_3GPP2_PTS_SUBTYPE_VUATS 2 +#define RADIUS_3GPP2_PTS_SUBTYPE_VUATSO 3 +#define RADIUS_3GPP2_PTS_SUBTYPE_TSI 4 +#define RADIUS_3GPP2_PTS_SUBTYPE_TITSU 5 + +#define RADIUS_VENDOR_TYPE_PPAC 35//prepaid accounting capability +#define RADIUS_VENDOR_TYPE_STC 36//session termination capability +#define RADIUS_VENDOR_TYPE_PPAQ 37//prepaid accouting operate +#define RADIUS_VENDOR_TYPE_PTS 38//prepaid tariff switch + +#define RADIUS_PPAC_SUBTYPE_AIC 1 + +#define RADIUS_PPAC_AIC_VM 0x00000001//Volume metering supported +#define RADIUS_PPAC_AIC_DM 0x00000010//Duration metering supported +#define RADIUS_PPAC_AIC_RM 0x00000100//Resource metering supported +#define RADIUS_PPAC_AIC_PS 0x00001000//Pools supported +#define RADIUS_PPAC_AIC_RGS 0x00010000//Rating groups supported +#define RADIUS_PPAC_AIC_MSS 0x00100000//Multi-Services supported +#define RADIUS_PPAC_AIC_TSS 0x01000000//Tariff Switch supported +#define RADIUS_PPAC_AIC_RESERVED 0x10000000//Reserved*/ + +#define RADIUS_PPAQ_SUBTYPE_QID 1//quota identifier; access request, access accept +#define RADIUS_PPAQ_SUBTYPE_VQ 2//volume quota; access request, access accept +#define RADIUS_PPAQ_SUBTYPE_VT 3//volume threshold; access accept +#define RADIUS_PPAQ_SUBTYPE_DQ 4//duration quota; access request, access accept +#define RADIUS_PPAQ_SUBTYPE_DT 5//duration threshold; access accept +#define RADIUS_PPAQ_SUBTYPE_RQ 6//resource quota; access request, access accept +#define RADIUS_PPAQ_SUBTYPE_RT 7//resource threshold; access accept +#define RADIUS_PPAQ_SUBTYPE_UR 8//update reason; access request +#define RADIUS_PPAQ_SUBTYPE_PS 9//prepaid server; access request, access accept +#define RADIUS_PPAQ_SUBTYPE_SID 10//service id; access request, access accept +#define RADIUS_PPAQ_SUBTYPE_RGID 11//rating group id; access request, access accept +#define RADIUS_PPAQ_SUBTYPE_TA 12//termination action; access accept +#define RADIUS_PPAQ_SUBTYPE_PLID 13//pool id; access accept +#define RADIUS_PPAQ_SUBTYPE_PM 14//pool multiplier; access accept +#define RADIUS_PPAQ_SUBTYPE_RA 15//requested action; access request +#define RADIUS_PPAQ_SUBTYPE_CBR 16//check balance result; access accept +#define RADIUS_PPAQ_SUBTYPE_CI 17//cost information; access accept + +#define RADIUS_PTS_SUBTYPE_VUATS 23//volume used after tariff switch +#define RADIUS_PTS_SUBTYPE_TSI 24//tariff switch interval +#define RADIUS_PTS_SUBTYPE_TITSU 25//time interval after tariff switch update + +#define RADIUS_PPAQ_UR_PRE_INIT 1 +#define RADIUS_PPAQ_UR_INIT_REQUEST 2 +#define RADIUS_PPAQ_UR_THRESHOLD_REACHED 3 +#define RADIUS_PPAQ_UR_QUOTA_REACHED 4 +#define RADIUS_PPAQ_UR_TITSU_APPROACHING 5 +#define RADIUS_PPAQ_UR_REMOTE_DISC 6 +#define RADIUS_PPAQ_UR_CLIENT_SERVICE_TER 7 +#define RADIUS_PPAQ_UR_ACCESS_SERVICE_TER 8 +#define RADIUS_PPAQ_UR_SERVICE_NOT_EST 9 +#define RADIUS_PPAQ_UR_ONE_TIME_CHARGING 10 + +#define RADIUS_PPAQ_TA_TERMINATE 1 +#define RADIUS_PPAQ_TA_REQUEST_MORE_QUOTA 2 +#define RADIUS_PPAQ_TA_REDIRCT_FILTER 3 + +#define RADIUS_PPAQ_RA_BALANCE_CHECK 1 +#define RADIUS_PPAQ_RA_PRICE_ENQUIRY 2 + +#define RADIUS_PPAQ_CBR_SUCCESS 0 +#define RADIUS_PPAQ_CBR_FAILURE 1 + +#define RADIUS_MAX_NUM_OF_FRAMED_COMPRESSION 4 +#define RADIUS_MAX_NUM_OF_LOGIN_IP_HOST 4 +#define RADIUS_MAX_NUM_OF_VENDOR_SPECIFIC 32 +#define RADIUS_MAX_NUM_OF_FILTER_ID 4 +#define RADIUS_MAX_NUM_OF_REPLY_MESSAGE 4 +#define RADIUS_MAX_NUM_OF_FRAMED_ROUTE 4 +#define RADIUS_MAX_NUM_OF_CLASS 4 +#define RADIUS_MAX_NUM_OF_FRAMED_APPLETALK_NETWORK 4 +#define RADIUS_MAX_NUM_OF_ACCT_MULTI_SESSION_ID 4 +#define RADIUS_MAX_NUM_OF_ACCT_LINK_COUNT 4 +#define RADIUS_MAX_NUM_OF_PROXY_STATE 4 +#define RADIUS_MAX_NUM_OF_EAP_MESSAGE 4 +#define RADIUS_MAX_NUM_OF_ARAP_SECURITY_DATA 4 +#define RADIUS_MAX_NUM_OF_CONFIGURATION_TOKEN 4 +#define RADIUS_MAX_NUM_OF_ERROR_CAUSE 4 +#define RADIUS_MAX_NUM_OF_NOWSMS_CALLED_ID 100 +#define RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST 1300 + +#define RADIUS_TIMER_ONE_SECOND 100 +#define RADIUS_TIMER_16S (16 * RADIUS_TIMER_ONE_SECOND) +#define RADIUS_TIMER_32S (32 * RADIUS_TIMER_ONE_SECOND) +#define RADIUS_RETRANS_TIMER (8 * RADIUS_TIMER_ONE_SECOND) + +#define RADIUS_PID_REQ_STATE_IDLE 0 +#define RADIUS_PID_REQ_STATE_WAIT_FOR_PEER_RESP 1 +#define RADIUS_PID_REQ_STATE_TERMINATE 2 + +#define RADIUS_PID_IND_STATE_IDLE 0 +#define RADIUS_PID_IND_STATE_WAIT_FOR_USER_RESP 1 +#define RADIUS_PID_IND_STATE_WAIT_FOR_TERMINATE 2 +#define RADIUS_PID_IND_STATE_TERMINATE 3 + +#define RADIUS_MAX_LEN_OF_RESULT 128 +#define RADIUS_MAX_LEN_OF_IN 16 + +#define RADIUS_MAX_LEN_MD5 16 + +#define RADIUS_MAX_LEN_OF_ENCRYPT_PASSWORD 128 + +#define RADIUS_SERVICE_TYPE_LOGIN 1 +#define RADIUS_SERVICE_TYPE_FRAMED 2 +#define RADIUS_SERVICE_TYPE_CALLBACK_LOGIN 3 +#define RADIUS_SERVICE_TYPE_CALLBACK_FRAMED 4 +#define RADIUS_SERVICE_TYPE_OUTBOUND 5 +#define RADIUS_SERVICE_TYPE_ADMIN 6 +#define RADIUS_SERVICE_TYPE_NAS_PROMPT 7 +#define RADIUS_SERVICE_TYPE_AUTHENTICATE_ONLY 8 +#define RADIUS_SERVICE_TYPE_CALLBACK_NAS_PROMPT 9 +#define RADIUS_SERVICE_TYPE_CALL_CHECK 10 +#define RADIUS_SERVICE_TYPE_CALLBACK_ADMIN 11 +#define RADIUS_SERVICE_TYPE_AUTHORIZE_ONLY 17 + +#define RADIUS_ACCT_STATUS_TYPE_START 1 +#define RADIUS_ACCT_STATUS_TYPE_STOP 2 +#define RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE 3 +#define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON 7 +#define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF 8 + +#define RADIUS_MAX_LEN_OF_MCC 3 +#define RADIUS_MAX_LEN_OF_MNC 3 + +#define RADIUS_ARICENT_VOLUME_INT 1 +#define RADIUS_ARICENT_VOLUME_EXP 2 + +#define RADIUS_MAX_LEN_OF_MESSAGE_AUTH_ATTR 16 + +#endif + diff --git a/plat/radius/src/include/radius_debug.h b/plat/radius/src/include/radius_debug.h new file mode 100644 index 0000000..0fbdca0 --- /dev/null +++ b/plat/radius/src/include/radius_debug.h @@ -0,0 +1,14 @@ +#ifndef _RADIUS_DEBUG_H +#define _RADIUS_DEBUG_H + +int radius_debug_set(void); + +void radius_mon(void); + +int radius_log_err(const char *fmt, ...); +int radius_log_event(const char *fmt, ...); +int radius_log_warn(const char *fmt, ...); +int radius_log_send_recv_msg(BYTE *msg, int len, RADIUS_ADDR *addr, BYTE msg_type, BYTE flag); + +#endif + diff --git a/plat/radius/src/include/radius_def.h b/plat/radius/src/include/radius_def.h new file mode 100644 index 0000000..c64bd03 --- /dev/null +++ b/plat/radius/src/include/radius_def.h @@ -0,0 +1,42 @@ +#ifndef _RADIUS_DEF_H +#define _RADIUS_DEF_H +/* +BYTE RADIUS_Version[4] = {1, 0, 0, 2}; + +int radius_udp_access_socket_fd; + +int radius_udp_account_socket_fd; + +int radius_udp_disconnect_socket_fd; + +int radius_pid_select; + +BYTE radius_access_id_select; +BYTE radius_accounting_id_select; +BYTE radius_disconnect_id_select; + +RADIUS_MSG radius_msg_pdu; + +RADIUS_PID radius_pid[RADIUS_MAX_NUM_OF_PID]; + +BYTE radius_udp_msg_recv_buf[RADIUS_MAX_LEN_OF_UDP_MSG]; + +WORD radius_mon_flag; + +BYTE radius_asci_tmp_buf[RADIUS_MAX_ASCITMP_LEN]; +BYTE radius_asci_out_buf[RADIUS_MAX_ASCIIOUT_LEN]; +BYTE radius_asci_in_buf[RADIUS_MAX_ASCIIIN_LEN]; + +char radius_msg_type_str[RADIUS_MAX_LEN_OF_MSG_TYEP]; + +RADIUS_ATTR_PARSE_FUNCTION radius_attr_parse_function[RADIUS_MAX_NUM_OF_ATTRIBUTE]; + +RADIUS_SAP radius_sap[RADIUS_MAX_NUM_OF_SAP]; + +RADIUS_NAS_INFO radius_nas_info[RADIUS_MAX_NUM_OF_NAS];*/ + +//BYTE radius_nas_share_key[RADIUS_MAX_NUM_OF_SAP][RADIUS_MAX_LEN_OF_SHARE_KEY]; +//BYTE radius_nas_password[RADIUS_MAX_NUM_OF_SAP][RADIUS_MAX_LEN_OF_PASSWORD]; + +#endif + diff --git a/plat/radius/src/include/radius_ext.h b/plat/radius/src/include/radius_ext.h new file mode 100644 index 0000000..b38bf1e --- /dev/null +++ b/plat/radius/src/include/radius_ext.h @@ -0,0 +1,41 @@ +#ifndef _RADIUS_EXT_H +#define _RADIUS_EXT_H + +extern BYTE RADIUS_Version[4]; + +extern int radius_udp_access_socket_fd; + +extern int radius_udp_account_socket_fd; + +extern int radius_udp_disconnect_socket_fd; + +extern int radius_pid_select; + +extern BYTE radius_access_id_select; +extern BYTE radius_accounting_id_select; +extern BYTE radius_disconnect_id_select; + +extern RADIUS_MSG radius_msg_pdu; + +extern RADIUS_PID radius_pid[RADIUS_MAX_NUM_OF_PID]; + +extern BYTE radius_udp_msg_recv_buf[RADIUS_MAX_LEN_OF_UDP_MSG]; + +extern WORD radius_mon_flag; + +extern BYTE radius_asci_tmp_buf[RADIUS_MAX_ASCITMP_LEN]; +extern BYTE radius_asci_out_buf[RADIUS_MAX_ASCIIOUT_LEN]; +extern BYTE radius_asci_in_buf[RADIUS_MAX_ASCIIIN_LEN]; + +extern char radius_msg_type_str[RADIUS_MAX_LEN_OF_MSG_TYEP]; + +extern RADIUS_ATTR_PARSE_FUNCTION radius_attr_parse_function[RADIUS_MAX_NUM_OF_ATTRIBUTE]; + +extern RADIUS_SAP radius_sap[RADIUS_MAX_NUM_OF_SAP]; + +extern RADIUS_NAS_INFO radius_nas_info[RADIUS_MAX_NUM_OF_NAS]; + +//extern BYTE radius_nas_share_key[RADIUS_MAX_NUM_OF_SAP][RADIUS_MAX_LEN_OF_SHARE_KEY]; +//extern BYTE radius_nas_password[RADIUS_MAX_NUM_OF_SAP][RADIUS_MAX_LEN_OF_PASSWORD]; + +#endif diff --git a/plat/radius/src/include/radius_fsm.h b/plat/radius/src/include/radius_fsm.h new file mode 100644 index 0000000..c03f390 --- /dev/null +++ b/plat/radius/src/include/radius_fsm.h @@ -0,0 +1,8 @@ +#ifndef _RADIUS_FSM_H +#define _RADIUS_FSM_H + +int radius_fsm(void); +int radius_p_fsm(int pid); + +#endif + diff --git a/plat/radius/src/include/radius_function.h b/plat/radius/src/include/radius_function.h new file mode 100644 index 0000000..4aa0bf3 --- /dev/null +++ b/plat/radius/src/include/radius_function.h @@ -0,0 +1,33 @@ +#ifndef _RADIUS_FUNCTION_H +#define _RADIUS_FUNCTION_H + +RADIUS_PID *radius_get_pid_ptr(int pid); +int radius_init_pid(int pid); +int radius_init_socket(void); + +int radius_attr_parse_init(); +int radius_send_msg(int pid); + +int radius_set_udp_dest_addr(struct sockaddr_in *dst_addr, RADIUS_ADDR *addr); +int radius_get_sock_fd_according_msg_type(BYTE msg_type); + +int radius_msg_to_fmt(const BYTE *bcd, int bcd_len, char *str, int str_buff_size); + +int radius_authenticate_nas(BYTE *authenticator, RADIUS_NAS_INFO *nas_info_ptr, RADIUS_ACCESS_REQUEST * access_request, BYTE *msg, int msg_len, int msg_auth_attr_offset); +int radius_calculate_authenticator(BYTE *rep_auth, const BYTE *msg, int msg_len, BYTE *share_key); + +RADIUS_NAS_INFO *radius_get_nas_info_ptr(int id); +int radius_accord_ip_search_nas_info(DWORD nas_ip); + +int radius_udp_msg_handling(BYTE *msg, int len, RADIUS_ADDR *addr, int nas_id); + +int radius_encode_access_request(BYTE sap_index, BYTE *identifier, BYTE *authenticator, BYTE *msg, RADIUS_ACCESS_REQUEST *access_request, int nas_id); +int radius_encode_access_accept(BYTE identifier, BYTE *request_authenticator, BYTE *msg, RADIUS_ACCESS_ACCEPT *access_accept, int nas_id); +int radius_encode_access_reject(BYTE identifier, BYTE *request_authenticator, BYTE *msg, RADIUS_ACCESS_REJECT *access_reject, int nas_id); +int radius_encode_accounting_response(BYTE identifier, BYTE *request_authenticator, BYTE *msg, RADIUS_ACCOUNTING_RESPONSE *accounting_response, int nas_id); +int radius_encode_disconnect_request(BYTE *identifier, BYTE *authenticator, BYTE *msg, RADIUS_DISCONNECT_REQUEST *disconnect_request, int nas_id); + +int radius_get_pid(); + +#endif + diff --git a/plat/radius/src/include/radius_if.h b/plat/radius/src/include/radius_if.h new file mode 100644 index 0000000..4120cf9 --- /dev/null +++ b/plat/radius/src/include/radius_if.h @@ -0,0 +1,26 @@ +#ifndef _RADIUS_IF_H +#define _RADIUS_IF_H + +#include "./radius_pub.h" + +typedef struct _RADIUS_NAS_INFORMATION +{ + DWORD nas_ip; + BYTE share_key[RADIUS_MAX_LEN_OF_SHARE_KEY]; + BYTE password[RADIUS_MAX_LEN_OF_PASSWORD]; +}__attribute__((packed)) RADIUS_NAS_INFORMATION;//be used for up layer interface struct + +int radius_set_nas_info(BYTE sap_index, BYTE id, RADIUS_NAS_INFORMATION *nas_information); +int radius_delet_nas_info(BYTE sap_index, BYTE id); + +int radius_send_access_request(BYTE sap_index, WORD usr_pid, RADIUS_MSG *msg_pdu, RADIUS_ADDR *addr); +int radius_send_access_accept(BYTE sap_index, WORD pid, WORD usr_pid, RADIUS_MSG *msg_pdu); +int radius_send_access_reject(BYTE sap_index, WORD pid, WORD usr_pid, RADIUS_MSG *msg_pdu); +int radius_send_accounting_response(BYTE sap_index, WORD pid, WORD usr_pid, RADIUS_MSG *msg_pdu); +int radius_send_disconnect_request(BYTE sap_index, WORD usr_pid, RADIUS_MSG *msg_pdu, RADIUS_ADDR *addr); + +int radius_calculate_chap_password(BYTE *auth, BYTE chap_id, const BYTE *password, const BYTE *chap_challenge, int chap_len); +int radius_encrypt_user_password(BYTE *encrypt_password, BYTE *password, BYTE *authenticator, BYTE *share_key); + +#endif + diff --git a/plat/radius/src/include/radius_inc.h b/plat/radius/src/include/radius_inc.h new file mode 100644 index 0000000..902b851 --- /dev/null +++ b/plat/radius/src/include/radius_inc.h @@ -0,0 +1,6 @@ +#ifndef _RADIUS_INC_H +#define _RADIUS_INC_H +#include "../../../debug/src/include/debug.h" +#include "../../../public/src/include/pub_inet.h" + +#endif diff --git a/plat/radius/src/include/radius_md5.h b/plat/radius/src/include/radius_md5.h new file mode 100644 index 0000000..0becafc --- /dev/null +++ b/plat/radius/src/include/radius_md5.h @@ -0,0 +1,85 @@ +//md5.h +/***********************************************************************/ +/** md5.h -- header file for implementation of MD5 **/ +/** RSA Data Security, Inc. MD5 Message-Digest Algorithm **/ +/** Created: 2/17/90 RLR **/ +/** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **/ +/** Revised (for MD5): RLR 4/27/91 **/ +/** -- G modified to have y&~z instead of y&z **/ +/** -- FF, GG, HH modified to add in last register done **/ +/** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **/ +/** -- distinct additive constant for each step **/ +/** -- round 4 added, working mod 7 **/ +/***********************************************************************/ + +/***********************************************************************/ +/** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **/ +/** **/ +/** License to copy and use this software is granted provided that **/ +/** it is identified as the "RSA Data Security, Inc. MD5 Message- **/ +/** Digest Algorithm" in all material mentioning or referencing this **/ +/** software or this function. **/ +/** **/ +/** License is also granted to make and use derivative works **/ +/** provided that such works are identified as "derived from the RSA **/ +/** Data Security, Inc. MD5 Message-Digest Algorithm" in all **/ +/** material mentioning or referencing the derived work. **/ +/** **/ +/** RSA Data Security, Inc. makes no representations concerning **/ +/** either the merchantability of this software or the suitability **/ +/** of this software for any particular purpose. It is provided "as **/ +/** is" without express or implied warranty of any kind. **/ +/** **/ +/** These notices must be retained in any copies of any part of this **/ +/** documentation and/or software. **/ +/***********************************************************************/ + +#ifndef _RADIUS_MD5_H +#define _RADIUS_MD5_H + +/* typedef a 32-bit type */ +//typedef unsigned long int UINT4; +typedef unsigned int UINT4; + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct _MD5_CTX +{ + UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +void radius_MD5Init (MD5_CTX *); +void radius_MD5Update (MD5_CTX *,unsigned char *,unsigned int); +void radius_MD5Final (MD5_CTX *); +void radius_MD5Transform(UINT4 *,UINT4 *); +void radius_get_md5_str(char *dest, char *org, int len); +void radius_get_md5_hex(char *dest, char *org, int len); +void radius_get_hmac_md5_hex(BYTE *dest, BYTE *org, int org_len, BYTE *key, int key_len); + +#endif +/***********************************************************************/ +/** End of md5.h **/ +/***********************************************************************/ + diff --git a/plat/radius/src/include/radius_pub.h b/plat/radius/src/include/radius_pub.h new file mode 100644 index 0000000..c46cfb6 --- /dev/null +++ b/plat/radius/src/include/radius_pub.h @@ -0,0 +1,66 @@ +#ifndef _RADIUS_PUB__H +#define _RADIUS_PUB__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned int DWORD; +#endif + +#include "./radius_const.h" +#include "./radius_struct.h" +#include "./radius_ext.h" +#include "./radius.h" +#include "./radius_md5.h" +#include "./radius_function.h" +#include "./radius_fsm.h" +#include "./radius_transport.h" +#include "./radius_debug.h" +#include "./radius_if.h" + +#endif + diff --git a/plat/radius/src/include/radius_struct.h b/plat/radius/src/include/radius_struct.h new file mode 100644 index 0000000..57911bd --- /dev/null +++ b/plat/radius/src/include/radius_struct.h @@ -0,0 +1,1433 @@ +#ifndef _RADIUS_STRUCT_H +#define _RADIUS_STRUCT_H + +#include "./radius_pub.h" + +typedef struct _RADIUS_TLV_TS +{ + BYTE type; + BYTE length; + BYTE value[RADIUS_TS_VALUE_LEN]; +}__attribute__((packed)) RADIUS_TLV_TS;// text or string + +typedef struct _RADIUS_TLV_AIT +{ + BYTE type; + BYTE length; + DWORD value; +}__attribute__((packed)) RADIUS_TLV_AIT;//address, integer or time + +typedef struct _RADIUS_ATTRIBUTE_USER_NAME +{ + BYTE flag; + RADIUS_TLV_TS user_name; +}__attribute__((packed)) RADIUS_ATTRIBUTE_USER_NAME; + +typedef struct _RADIUS_ATTRIBUTE_USER_PASSWORD +{ + BYTE flag; + RADIUS_TLV_TS user_password; +}__attribute__((packed)) RADIUS_ATTRIBUTE_USER_PASSWORD; + +typedef struct _RADIUS_ATTRIBUTE_CHAP_PASSWORD +{ + BYTE flag; + RADIUS_TLV_TS chap_password; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CHAP_PASSWORD; + +typedef struct _RADIUS_ATTRIBUTE_NAS_IP_ADDRESS +{ + BYTE flag; + RADIUS_TLV_AIT nas_ip_addr; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NAS_IP_ADDRESS; + +typedef struct _RADIUS_ATTRIBUTE_NAS_PORT +{ + BYTE flag; + RADIUS_TLV_AIT nas_port; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NAS_PORT; + +typedef struct _RADIUS_ATTRIBUTE_SERVICE_TYPE +{ + BYTE flag; + RADIUS_TLV_AIT service_type; +}__attribute__((packed)) RADIUS_ATTRIBUTE_SERVICE_TYPE; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_PROTOCOL +{ + BYTE flag; + RADIUS_TLV_AIT framed_protocol; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_PROTOCOL; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_IP_ADDR +{ + BYTE flag; + RADIUS_TLV_AIT framed_ip_addr; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_IP_ADDR; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_IP_NETMASK +{ + BYTE flag; + RADIUS_TLV_AIT framed_ip_netmask; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_IP_NETMASK; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_ROUTING +{ + BYTE flag; + RADIUS_TLV_AIT framed_routing; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_ROUTING; + +typedef struct _RADIUS_ATTRIBUTE_FILTER_ID +{ + BYTE flag; + RADIUS_TLV_TS filter_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FILTER_ID; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_MTU +{ + BYTE flag; + RADIUS_TLV_AIT framed_mtu; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_MTU; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_COMPRESSION +{ + BYTE flag; + RADIUS_TLV_AIT framed_compression; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_COMPRESSION; + +typedef struct _RADIUS_ATTRIBUTE_LOGIN_IP_HOST +{ + BYTE flag; + RADIUS_TLV_AIT login_ip_host; +}__attribute__((packed)) RADIUS_ATTRIBUTE_LOGIN_IP_HOST; + +typedef struct _RADIUS_ATTRIBUTE_LOGIN_SERVICE +{ + BYTE flag; + RADIUS_TLV_AIT login_service; +}__attribute__((packed)) RADIUS_ATTRIBUTE_LOGIN_SERVICE; + +typedef struct _RADIUS_ATTRIBUTE_LOGIN_TCP_PORT +{ + BYTE flag; + RADIUS_TLV_AIT login_tcp_port; +}__attribute__((packed)) RADIUS_ATTRIBUTE_LOGIN_TCP_PORT; + +typedef struct _RADIUS_ATTRIBUTE_REPLY_MESSAGE +{ + BYTE flag; + RADIUS_TLV_TS reply_message; +}__attribute__((packed)) RADIUS_ATTRIBUTE_REPLY_MESSAGE; + +typedef struct _RADIUS_ATTRIBUTE_CALLBACK_NUMBER +{ + BYTE flag; + RADIUS_TLV_TS callback_number; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CALLBACK_NUMBER; + +typedef struct _RADIUS_ATTRIBUTE_CALLBACK_ID +{ + BYTE flag; + RADIUS_TLV_TS callback_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CALLBACK_ID; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_ROUTE +{ + BYTE flag; + RADIUS_TLV_TS framed_route; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_ROUTE; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_IPX_NETWORK +{ + BYTE flag; + RADIUS_TLV_AIT framed_ipx_network; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_IPX_NETWORK; + +typedef struct _RADIUS_ATTRIBUTE_STATE +{ + BYTE flag; + RADIUS_TLV_TS state; +}__attribute__((packed)) RADIUS_ATTRIBUTE_STATE; + +typedef struct _RADIUS_ATTRIBUTE_CLASS +{ + BYTE flag; + RADIUS_TLV_TS radius_class; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CLASS; + +typedef struct _RADIUS_VENDOR_PPAC_SUB_ATTR_AIC +{ + BYTE flag; + DWORD aic; /* subtype=1 + sub_type + length + aic = 1 + 1 + 4 + AvailableInClient value + 0x00000001 | Volume metering supported + 0x00000010 | Duration metering supported + 0x00000100 | Resource metering supported + 0x00001000 | Pools supported + 0x00010000 | Rating groups supported + 0x00100000 | Multi-Services supported + 0x01000000 | Tariff Switch supported + 0x10000000 | Reserved*/ +}__attribute__((packed)) RADIUS_VENDOR_PPAC_SUB_ATTR_AIC; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_PPAC//perpaid accounting capability +{ + BYTE continuation;//continuation = 0xxxxxxx + RADIUS_VENDOR_PPAC_SUB_ATTR_AIC aic; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_PPAC; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_STC//session termination capability +{ + BYTE continuation;//continuation = 0xxxxxxx + DWORD stc;/*session termination capability + 0x00000000 | Reserved + 0x00000001 | Dynamic Authorization Extensions (RFC 3576) is supported. + ... | All further values are reserved.*/ + +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_STC; + +typedef struct _RADIUS_TLV_DECIMAL +{ + BYTE type; + long long integer; + DWORD exponent; //int +}__attribute__((packed)) RADIUS_TLV_DECIMAL; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_QID +{ + BYTE flag; + RADIUS_TLV_TS qid; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_QID;//quota identifier + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_VQ +{ + BYTE flag; + RADIUS_TLV_DECIMAL vq;//length = 2 + (8 or 12); value contian value-digits field 8 octets or value-digits field plus the exponent field 12 octets +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_VQ;//volume quota + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_VT +{ + BYTE flag; + RADIUS_TLV_DECIMAL vt; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_VT;//volume threshold + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_DQ +{ + BYTE flag; + RADIUS_TLV_AIT dq; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_DQ;//duration quota + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_DT +{ + BYTE flag; + RADIUS_TLV_AIT dt; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_DT;//duration threshold + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_RQ +{ + BYTE flag; + RADIUS_TLV_DECIMAL rq; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_RQ;//resource quota + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_RT +{ + BYTE flag; + RADIUS_TLV_DECIMAL rt; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_RT;//resource threshold + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_UR +{ + BYTE flag; + RADIUS_TLV_AIT ur;/* 0 | Reserved + 1 | Pre-initialization + 2 | Initial Request + 3 | Threshold Reached + 4 | Quota Reached + 5 | TITSU Approaching + 6 | Remote Forced Disconnect + 7 | Client Service Termination + 8 | "Access Service" Terminated + 9 | Service not established + 10 | One-Time Charging + 11...255 | **Available for IANA registration***///length = 2 + 1 +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_UR;//update reason + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_PS +{ + BYTE flag; + RADIUS_TLV_AIT ps; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_PS;//prepaid server + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_SID +{ + BYTE flag; + RADIUS_TLV_TS sid; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_SID; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_RGID +{ + BYTE flag; + RADIUS_TLV_AIT rgid;//two octets +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_RGID; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_TA +{ + BYTE flag; + RADIUS_TLV_AIT ta;/* 0 | Reserved + 1 | Terminate + 2 | Request More Quota + 3 | Redirect/Filter + 4..255 | **Available for IANA registration***///one octet +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_TA; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_PLID +{ + BYTE flag; + RADIUS_TLV_AIT plid;//one octet +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_PLID; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_PM +{ + BYTE flag; + RADIUS_TLV_DECIMAL pm; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_PM; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_RA +{ + BYTE flag; + RADIUS_TLV_AIT ra;/* 0 | Reserved + 1 | Balance Check + 2 | Price Enquiry + 3..255 | **Available for IANA registration***///one octet +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_RA; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_CBR +{ + BYTE flag; + RADIUS_TLV_AIT cbr;/* 0 | Success; Sufficient funds available in the user's prepaid account + 1 | Failure; Insufficient funds available + 2..255 | **Available for IANA registration***///one octet +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_CBR; + +typedef struct _RADIUS_VENDOR_PPAQ_SUB_ATTR_CI +{ + BYTE flag; + BYTE type; + long long integer; + int exponent; + DWORD currency_code; + BYTE cost_unit[RADIUS_TS_VALUE_LEN]; +}__attribute__((packed)) RADIUS_VENDOR_PPAQ_SUB_ATTR_CI; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_PPAQ +{ + BYTE continuation; + RADIUS_VENDOR_PPAQ_SUB_ATTR_QID qid;//quota id type = 1 + RADIUS_VENDOR_PPAQ_SUB_ATTR_VQ vq;//type = 2 + RADIUS_VENDOR_PPAQ_SUB_ATTR_VT vt;//type=3 + RADIUS_VENDOR_PPAQ_SUB_ATTR_DQ dq;//type=4 + RADIUS_VENDOR_PPAQ_SUB_ATTR_DT dt;//type=5 + RADIUS_VENDOR_PPAQ_SUB_ATTR_RQ rq;//type=6 + RADIUS_VENDOR_PPAQ_SUB_ATTR_RT rt;//tyep=7 + RADIUS_VENDOR_PPAQ_SUB_ATTR_UR ur;//type=8 + RADIUS_VENDOR_PPAQ_SUB_ATTR_PS ps;//type=9 + RADIUS_VENDOR_PPAQ_SUB_ATTR_SID sid;//service id type=10 + RADIUS_VENDOR_PPAQ_SUB_ATTR_RGID rgid;//type=11 + RADIUS_VENDOR_PPAQ_SUB_ATTR_TA ta;//type=12 + RADIUS_VENDOR_PPAQ_SUB_ATTR_PLID plid;//pool id type=13 + RADIUS_VENDOR_PPAQ_SUB_ATTR_PM pm;//type=14 + RADIUS_VENDOR_PPAQ_SUB_ATTR_RA ra;//type=15 + RADIUS_VENDOR_PPAQ_SUB_ATTR_CBR cbr;//type=16 + RADIUS_VENDOR_PPAQ_SUB_ATTR_CI ci;//type=17 +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_PPAQ; + +typedef struct _RADIUS_VENDOR_PTS_SUB_ATTR_VUATS +{ + BYTE flag; + RADIUS_TLV_DECIMAL vuats; +}__attribute__((packed)) RADIUS_VENDOR_PTS_SUB_ATTR_VUATS; + +typedef struct _RADIUS_VENDOR_PTS_SUB_ATTR_TSI +{ + BYTE flag; + RADIUS_TLV_AIT tsi; +}__attribute__((packed)) RADIUS_VENDOR_PTS_SUB_ATTR_TSI; + +typedef struct _RADIUS_VENDOR_PTS_SUB_ATTR_TITSU +{ + BYTE flag; + RADIUS_TLV_AIT titsu; +}__attribute__((packed)) RADIUS_VENDOR_PTS_SUB_ATTR_TITSU; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_PTS +{ + BYTE continuation; + RADIUS_VENDOR_PTS_SUB_ATTR_VUATS vuats;//volume used afer tariff switch + RADIUS_VENDOR_PTS_SUB_ATTR_TSI tsi;//tariff switch interval + RADIUS_VENDOR_PTS_SUB_ATTR_TITSU titsu; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_PTS; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_IMSI +{ + BYTE imsi[RADIUS_MAX_LEN_OF_IMSI]; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_IMSI; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_CID +{ + DWORD cid; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_CID; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_PDP_TYPE +{ + DWORD pdp_type; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_PDP_TYPE; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_CG_ADDR +{ + DWORD cg_addr; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_CG_ADDR; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_NQP +{ + BYTE nqp[RADIUS_TS_VALUE_LEN]; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_NQP; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR +{ + DWORD sgsn_addr; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_ADDR +{ + DWORD ggsn_addr; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_ADDR; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_MCC_MNC +{ + BYTE mcc[RADIUS_MAX_LEN_OF_MCC]; + BYTE mnc[RADIUS_MAX_LEN_OF_MNC]; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_MCC_MNC; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_MCC_MNC +{ + BYTE mcc[RADIUS_MAX_LEN_OF_MCC]; + BYTE mnc[RADIUS_MAX_LEN_OF_MNC]; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_MCC_MNC; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_NSAPI +{ + BYTE nsapi; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_NSAPI; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_SSI +{ + BYTE ssi;//length=1, value=0xFF; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_SSI; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_SM +{ + BYTE sm; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_SM; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_CC +{ + BYTE cc[RADIUS_TS_VALUE_LEN]; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_CC; + +/*typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_CG_IPV6 +{ + BYTE flag; + +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_CG_IPV6;*/ + +/*typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_IPV6 +{ + BYTE flag; + +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_IPV6;*/ + +/*typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_IPV6 +{ + BYTE flag; + +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_IPV6;*/ + +/*typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_IPV6_DNS +{ + BYTE flag; + +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_IPV6_DNS;*/ + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_MCC_MNC +{ + BYTE mcc[RADIUS_MAX_LEN_OF_MCC]; + BYTE mnc[RADIUS_MAX_LEN_OF_MNC]; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_MCC_MNC; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP2_IKE +{ + DWORD ike; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP2_IKE; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP2_SL +{ + DWORD sl; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP2_SL; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP2_STC +{ + DWORD stc; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP2_STC; + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_QID +{ + BYTE flag; + RADIUS_TLV_AIT qid; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_QID;//quota identifier + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQ +{ + BYTE flag; + RADIUS_TLV_DECIMAL vq;//for aricent +// RADIUS_TLV_AIT vq;//length = 2 + 4, 3gpp2 +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQ;//volume quota + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQO +{ + BYTE flag; +// RADIUS_TLV_DECIMAL vqo;//for aricent + RADIUS_TLV_AIT vqo;//length = 2 + 2, 3gpp2 +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQO;//volume quota overflow + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VT +{ + BYTE flag; + RADIUS_TLV_DECIMAL vt;//for aricent +// RADIUS_TLV_AIT vt;//length = 2 + 4, 3gpp2 +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VT;//volume threshold + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VTO +{ + BYTE flag; +// RADIUS_TLV_DECIMAL vto;//for aricent + RADIUS_TLV_AIT vto;//length = 2 + 2, 3gpp2 +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VTO;//volume threshold + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DQ +{ + BYTE flag; + RADIUS_TLV_AIT dq; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DQ;//duration quota + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DT +{ + BYTE flag; + RADIUS_TLV_AIT dt; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DT;//duration threshold + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_UR +{ + BYTE flag; + RADIUS_TLV_AIT ur;/* 0 | Reserved + 1 | Pre-initialization + 2 | Initial Request + 3 | Threshold Reached + 4 | Quota Reached + 5 | Remote Forced Disconnect + 6 | Client Service Termination + 7 | Main SC released + 8 | Service Connection not established + 9 | Tariff Switch Update + 10 | Incorrect Quota type Received + 11 | Poorly Formed Quota Attribute*///length = 2 + 2 +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_UR;//update reason + +typedef struct _RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_PS +{ + BYTE flag; + RADIUS_TLV_AIT ps;//only support ipv4 +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_PS;//prepaid server + + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ +{ + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_QID qid;//quota id type = 1 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQ vq;//type = 2 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQO vqo;//type = 3 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VT vt;//type=4 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VTO vto;//type = 5 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DQ dq;//type=6 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DT dt;//type=7 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_UR ur;//type=8 + RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_PS ps;//type=9 +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ; + +typedef struct _RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_AIC +{ + BYTE flag; + DWORD aic;/* 0x00000001 PrePaid Accounting for Volume supported + 0x00000002 PrePaid Accounting for Duration supported + 0x00000003 PrePaid Accounting for Volume and Duration supported (non concurrently) + Others Reserved, treat like Not Capable of PrePaid Accounting (=0).*/ +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_AIC; + +typedef struct _RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_SFS +{ + BYTE flag; + DWORD sfs;/* 0x00000000 PrePaid Accounting not used + 0x00000001 Usage of PrePaid Accounting for Volume. (only possible if the AvailableInClient supports PrePaid Accounting for Volume) + 0x00000002 Usage of PrePaid Accounting for Duration. (only possible if the AvailableInClient supports PrePaid Accounting for Duration) + 0x00000003 Usage of PrePaid Accounting for Volume and Duration (non concurrent) (only possible if the AvailableInClient supports PrePaid Accounting for Volume and duration) + Others Reserved, treat like PrePaid Accounting not used (=0).*/ +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_SFS; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC +{ + RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_AIC aic;//available in client + RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_SFS sfs;//select for session +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC; + +typedef struct _RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_QID +{ + BYTE flag; + RADIUS_TLV_AIT qid; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_QID;//quota identifier + +typedef struct _RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATS +{ + BYTE flag; + RADIUS_TLV_AIT vuats; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATS; + +typedef struct _RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATSO +{ + BYTE flag; + RADIUS_TLV_AIT vuatso; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATSO; + +typedef struct _RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TSI +{ + BYTE flag; + RADIUS_TLV_AIT tsi; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TSI; + +typedef struct _RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TITSU +{ + BYTE flag; + RADIUS_TLV_AIT titsu; +}__attribute__((packed)) RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TITSU; + +typedef struct _RADIUS_VENDOR_ATTRIBUTE_3GPP2_PTS +{ + RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_QID qid; + RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATS vuats; + RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATSO vuatso; + RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TSI tsi; + RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TITSU titsu; +}__attribute__((packed)) RADIUS_VENDOR_ATTRIBUTE_3GPP2_PTS; + +typedef struct _RADIUS_ATTRIBUTE_VENDOR_SPECIFIC +{ + BYTE flag; + DWORD vendor_id;//24757 for wimax; 10415 for 3GPP; 5535 + BYTE vendor_type;//(vendor id=24757 wimax :35 for PPAC; 36 for Session Termination Capability;37 for PPAQ;38 for pts) + BYTE vendor_length; + + union + { + RADIUS_VENDOR_ATTRIBUTE_PPAC ppac; + RADIUS_VENDOR_ATTRIBUTE_STC stc; + RADIUS_VENDOR_ATTRIBUTE_PPAQ ppaq; + RADIUS_VENDOR_ATTRIBUTE_PTS pts; + }attribute; + + union + { + RADIUS_VENDOR_ATTRIBUTE_3GPP_IMSI imsi; + RADIUS_VENDOR_ATTRIBUTE_3GPP_CID charging_id; + RADIUS_VENDOR_ATTRIBUTE_3GPP_PDP_TYPE pdp_type; + RADIUS_VENDOR_ATTRIBUTE_3GPP_CG_ADDR cg_addr; + RADIUS_VENDOR_ATTRIBUTE_3GPP_NQP negotiated_qos; + RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR sgsn_addr; + RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_ADDR ggsn_addr; + RADIUS_VENDOR_ATTRIBUTE_3GPP_MCC_MNC mcc_mnc; + RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_MCC_MNC ggsn_mcc_mnc; + RADIUS_VENDOR_ATTRIBUTE_3GPP_NSAPI nsapi; + RADIUS_VENDOR_ATTRIBUTE_3GPP_SSI ssi; + RADIUS_VENDOR_ATTRIBUTE_3GPP_SM sm; + RADIUS_VENDOR_ATTRIBUTE_3GPP_CC cc; + RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_MCC_MNC sgsn_mcc_mnc; + }attribute_3gpp; + + union + { +// RADIUS_VENDOR_ATTRIBUTE_3GPP2_IKE ike; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_STC stc; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ ppaq; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC ppac; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PTS pts; + }attribute_3gpp2; +}__attribute__((packed)) RADIUS_ATTRIBUTE_VENDOR_SPECIFIC; + +typedef struct _RADIUS_ATTRIBUTE_SESSION_TIMEOUT +{ + BYTE flag; + RADIUS_TLV_AIT session_timeout; +}__attribute__((packed)) RADIUS_ATTRIBUTE_SESSION_TIMEOUT; + +typedef struct _RADIUS_ATTRIBUTE_IDLE_TIMEOUT +{ + BYTE flag; + RADIUS_TLV_AIT idle_timeout; +}__attribute__((packed)) RADIUS_ATTRIBUTE_IDLE_TIMEOUT; + +typedef struct _RADIUS_ATTRIBUTE_TERMINATION_ACTION +{ + BYTE flag; + RADIUS_TLV_AIT termination_action; +}__attribute__((packed)) RADIUS_ATTRIBUTE_TERMINATION_ACTION; +/* +typedef struct _RADIUS_ATTRIBUTE_CALLED_STATION_ID +{ + BYTE flag; + RADIUS_TLV_TS called_station_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CALLED_STATION_ID;*/ + +typedef struct _RADIUS_ATTRIBUTE_CALLED_STATION_ID // expand +{ + BYTE option; // 1, server; 2, client + union + { + struct + { + BYTE num; + RADIUS_TLV_TS called_station_id[RADIUS_MAX_NUM_OF_NOWSMS_CALLED_ID]; //RADIUS_ATTRIBUTE_CALLED_STATION_ID + }server; + struct + { + // WORD len; + BYTE called_list[RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST]; + }client; + }called; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CALLED_STATION_ID; + +typedef struct _RADIUS_ATTRIBUTE_CALLING_STATION_ID +{ + BYTE flag; + RADIUS_TLV_TS calling_station_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CALLING_STATION_ID; + +typedef struct _RADIUS_ATTRIBUTE_NAS_IDENTIFIER +{ + BYTE flag; + RADIUS_TLV_TS nas_identifier; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NAS_IDENTIFIER; + +typedef struct _RADIUS_ATTRIBUTE_PROXY_STATE +{ + BYTE flag; + RADIUS_TLV_TS proxy_state; +}__attribute__((packed)) RADIUS_ATTRIBUTE_PROXY_STATE; + +typedef struct _RADIUS_ATTRIBUTE_LOGIN_LAT_SERVICE +{ + BYTE flag; + RADIUS_TLV_TS login_lat_service; +}__attribute__((packed)) RADIUS_ATTRIBUTE_LOGIN_LAT_SERVICE; + +typedef struct _RADIUS_ATTRIBUTE_LOGIN_LAT_NODE +{ + BYTE flag; + RADIUS_TLV_TS login_lat_node; +}__attribute__((packed)) RADIUS_ATTRIBUTE_LOGIN_LAT_NODE; + +typedef struct _RADIUS_ATTRIBUTE_LOGIN_LAT_GROUP +{ + BYTE flag; + RADIUS_TLV_TS login_lat_group; +}__attribute__((packed)) RADIUS_ATTRIBUTE_LOGIN_LAT_GROUP; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_APPLETALK_LINK +{ + BYTE flag; + RADIUS_TLV_AIT framed_appletalk_link; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_APPLETALK_LINK; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_APPLETAKL_NETWORK +{ + BYTE flag; + RADIUS_TLV_AIT framed_appletalk_network; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_APPLETALK_NETWORK; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_APPLETALK_ZONE +{ + BYTE flag; + RADIUS_TLV_TS framed_appletalk_zone; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_APPLETALK_ZONE; + +typedef struct _RADIUS_ATTRIBUTE_CHAP_CHALLENGE +{ + BYTE flag; + RADIUS_TLV_TS chap_challenge; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CHAP_CHALLENGE; + +typedef struct _RADIUS_ATTRIBUTE_NAS_PORT_TYPE +{ + BYTE flag; + RADIUS_TLV_AIT nas_port_type; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NAS_PORT_TYPE; + +typedef struct _RADIUS_ATTRIBUTE_PORT_LIMIT +{ + BYTE flag; + RADIUS_TLV_AIT port_limit; +}__attribute__((packed)) RADIUS_ATTRIBUTE_PORT_LIMIT; + +typedef struct _RADIUS_ATTRIBUTE_LOGIN_LAT_PORT +{ + BYTE flag; + RADIUS_TLV_TS login_lat_port; +}__attribute__((packed)) RADIUS_ATTRIBUTE_LOGIN_LAT_PORT; + +typedef struct _RADIUS_ATTRIBUTE_EAP_MESSAGE +{ + BYTE flag; + RADIUS_TLV_TS eap_message; +}__attribute__((packed)) RADIUS_ATTRIBUTE_EAP_MESSAGE; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_STATUS_TYPE +{ + BYTE flag; + RADIUS_TLV_AIT acct_status_type; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_STATUS_TYPE; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_DELAY_TIME +{ + BYTE flag; + RADIUS_TLV_AIT acct_delay_time; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_DELAY_TIME; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_INPUT_OCTETS +{ + BYTE flag; + RADIUS_TLV_AIT acct_input_octets; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_INPUT_OCTETS; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_OUTPUT_OCTETS +{ + BYTE flag; + RADIUS_TLV_AIT acct_output_octets; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_OUTPUT_OCTETS; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_SESSION_ID +{ + BYTE flag; + RADIUS_TLV_TS acct_session_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_SESSION_ID; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_AUTHENTIC +{ + BYTE flag; + RADIUS_TLV_AIT acct_authentic; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_AUTHENTIC; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_SESSION_TIME +{ + BYTE flag; + RADIUS_TLV_AIT acct_session_time; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_SESSION_TIME; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_INPUT_PACKETS +{ + BYTE flag; + RADIUS_TLV_AIT acct_input_packets; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_INPUT_PACKETS; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_OUTPUT_PACKETS +{ + BYTE flag; + RADIUS_TLV_AIT acct_output_packets; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_OUTPUT_PACKETS; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_TERMINATE_CAUSE +{ + BYTE flag; + RADIUS_TLV_AIT acct_terminate_cause; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_TERMINATE_CAUSE; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_MULTI_SESSION_ID +{ + BYTE flag; + RADIUS_TLV_TS acct_multi_session_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_MULTI_SESSION_ID; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_LINK_COUNT +{ + BYTE flag; + RADIUS_TLV_AIT acct_link_count; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_LINK_COUNT; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_INPUT_GIGAWORDS +{ + BYTE flag; + RADIUS_TLV_AIT acct_input_gigawords; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_INPUT_GIGAWORDS; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_OUTPUT_GIGAWORDS +{ + BYTE flag; + RADIUS_TLV_AIT acct_output_gigawords; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_OUTPUT_GIGAWORDS; + +typedef struct _RADIUS_ATTRIBUTE_EVENT_TIMESTAMP +{ + BYTE flag; + RADIUS_TLV_AIT event_timestamp; +}__attribute__((packed)) RADIUS_ATTRIBUTE_EVENT_TIMESTAMP; + +typedef struct _RADIUS_ATTRIBUTE_ARAP_PASSWORD +{ + BYTE flag; + RADIUS_TLV_TS arap_password; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ARAP_PASSWORD; + +typedef struct _RADIUS_ATTRIBUTE_ARAP_FEATURES +{ + BYTE flag; + RADIUS_TLV_TS arap_features; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ARAP_FEATURES; + +typedef struct _RADIUS_ATTRIBUTE_ARAP_ZONE_ACCESS +{ + BYTE flag; + RADIUS_TLV_AIT arap_zone_access; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ARAP_ZONE_ACCESS; + +typedef struct _RADIUS_ATTRIBUTE_ARAP_SECURITY +{ + BYTE flag; + RADIUS_TLV_AIT arap_security; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ARAP_SECURITY; + +typedef struct _RADIUS_ATTRIBUTE_ARAP_SECURITY_DATA +{ + BYTE flag; + RADIUS_TLV_TS arap_security_data; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ARAP_SECURITY_DATA; + +typedef struct _RADIUS_ATTRIBUTE_PASSWORD_RETRY +{ + BYTE flag; + RADIUS_TLV_AIT password_retry; +}__attribute__((packed)) RADIUS_ATTRIBUTE_PASSWORD_RETRY; + +typedef struct _RADIUS_ATTRIBUTE_PROMPT +{ + BYTE flag; + RADIUS_TLV_AIT prompt; +}__attribute__((packed)) RADIUS_ATTRIBUTE_PROMPT; + +typedef struct _RADIUS_ATTRIBUTE_CONNECT_INFO +{ + BYTE flag; + RADIUS_TLV_TS connect_info; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CONNECT_INFO; + +typedef struct _RADIUS_ATTRIBUTE_CONFIGURATION_TOKEN +{ + BYTE flag; + RADIUS_TLV_TS configuration_token; +}__attribute__((packed)) RADIUS_ATTRIBUTE_CONFIGURATION_TOKEN; + +typedef struct _RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR +{ + BYTE flag; + RADIUS_TLV_TS message_authenticator; +}__attribute__((packed)) RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR; + +typedef struct _RADIUS_ATTRIBUTE_ARAP_CHALLENGE_RESPONSE +{ + BYTE flag; + RADIUS_TLV_TS arap_challenge_response; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ARAP_CHALLENGE_RESPONSE; + +typedef struct _RADIUS_ATTRIBUTE_ACCT_INTERIM_INTERVAL +{ + BYTE flag; + RADIUS_TLV_AIT acct_interim_interval; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ACCT_INTERIM_INTERVAL; + +typedef struct _RADIUS_ATTRIBUTE_NAS_PORT_ID +{ + BYTE flag; + RADIUS_TLV_TS nas_port_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NAS_PORT_ID; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_POOL +{ + BYTE flag; + RADIUS_TLV_TS framed_pool; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_POOL; + +typedef struct _RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID +{ + BYTE flag; + RADIUS_TLV_TS framed_interface_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID; + +typedef struct _RADIUS_ATTRIBUTE_ORIGINATION_LINE_INFO +{ + BYTE flag; + RADIUS_TLV_TS origination_line_info; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ORIGINATING_LINE_INFO; + +typedef struct _RADIUS_ATTRIBUTE_ERROR_CAUSE +{ + BYTE flag; + RADIUS_TLV_AIT error_cause; +}__attribute__((packed)) RADIUS_ATTRIBUTE_ERROR_CAUSE; + + +typedef struct _RADIUS_ATTRIBUTE_NOWSMS_PREAUTH_TYPE +{ + BYTE flag; +// BYTE type; +// RADIUS_TLV_TS pre_auth_type; + RADIUS_TLV_AIT pre_auth_type; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NOWSMS_PREAUTH_TYPE; + +typedef struct _RADIUS_ATTRIBUTE_NOWSMS_MSG_COUNT +{ + BYTE flag; + RADIUS_TLV_AIT msg_count; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NOWSMS_MSG_COUNT; +typedef struct _RADIUS_ATTRIBUTE_NOWSMS_MSG_ID +{ + BYTE flag; + RADIUS_TLV_AIT msg_id; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NOWSMS_MSG_ID; +typedef struct _RADIUS_ATTRIBUTE_NOWSMS_SIZE +{ + BYTE flag; + RADIUS_TLV_AIT size; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NOWSMS_SIZE; +typedef struct _RADIUS_ATTRIBUTE_NOWSMS_COUNT_ID_SIZE //nowsms +{ + BYTE flag; + BYTE type; +// BYTE length; + RADIUS_ATTRIBUTE_NOWSMS_MSG_COUNT msg_count; + RADIUS_ATTRIBUTE_NOWSMS_MSG_ID msg_id; + RADIUS_ATTRIBUTE_NOWSMS_SIZE size; +}__attribute__((packed)) RADIUS_ATTRIBUTE_NOWSMS_COUNT_ID_SIZE; + + +typedef struct _RADIUS_FRAMED_COMPRESSION +{ + BYTE num; + RADIUS_ATTRIBUTE_FRAMED_COMPRESSION framed_compression[RADIUS_MAX_NUM_OF_FRAMED_COMPRESSION]; +}__attribute__((packed)) RADIUS_FRAMED_COMPRESSION; + +typedef struct _RADIUS_LOGIN_IP_HOST +{ + BYTE num; + RADIUS_ATTRIBUTE_LOGIN_IP_HOST login_ip_host[RADIUS_MAX_NUM_OF_LOGIN_IP_HOST]; +}__attribute__((packed)) RADIUS_LOGIN_IP_HOST; + +typedef struct _RADIUS_VENDOR_SPECIFIC +{ + BYTE num; + RADIUS_ATTRIBUTE_VENDOR_SPECIFIC vendor_specific[RADIUS_MAX_NUM_OF_VENDOR_SPECIFIC]; +}__attribute__((packed)) RADIUS_VENDOR_SPECIFIC; + +typedef struct _RADIUS_PROXY_STATE +{ + BYTE num; + RADIUS_ATTRIBUTE_PROXY_STATE proxy_state[RADIUS_MAX_NUM_OF_PROXY_STATE]; +}__attribute__((packed)) RADIUS_PROXY_STATE; + +typedef struct _RADIUS_FILTER_ID +{ + BYTE num; + RADIUS_ATTRIBUTE_FILTER_ID filter_id[RADIUS_MAX_NUM_OF_FILTER_ID]; +}__attribute__((packed)) RADIUS_FILTER_ID; + +typedef struct _RADIUS_REPLY_MESSAGE +{ + BYTE num; + RADIUS_ATTRIBUTE_REPLY_MESSAGE reply_message[RADIUS_MAX_NUM_OF_REPLY_MESSAGE]; +}__attribute__((packed)) RADIUS_REPLY_MESSAGE; + +typedef struct _RADIUS_FRAMED_ROUTE +{ + BYTE num; + RADIUS_ATTRIBUTE_FRAMED_ROUTE framed_route[RADIUS_MAX_NUM_OF_FRAMED_ROUTE]; +}__attribute__((packed)) RADIUS_FRAMED_ROUTE; + +typedef struct _RADIUS_CLASS +{ + BYTE num; + RADIUS_ATTRIBUTE_CLASS radius_class[RADIUS_MAX_NUM_OF_CLASS]; +}__attribute__((packed)) RADIUS_CLASS; + +typedef struct _RADIUS_FRAMED_APPLETALK_NETWORK +{ + BYTE num; + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_NETWORK framed_appletalk_network[RADIUS_MAX_NUM_OF_FRAMED_APPLETALK_NETWORK]; +}__attribute__((packed)) RADIUS_FRAMED_APPLETALK_NETWORK; + +typedef struct _RADIUS_ACCT_MULTI_SESSION_ID +{ + BYTE num; + RADIUS_ATTRIBUTE_ACCT_MULTI_SESSION_ID acct_multi_session_id[RADIUS_MAX_NUM_OF_ACCT_MULTI_SESSION_ID]; +}__attribute__((packed)) RADIUS_ACCT_MULTI_SESSION_ID; + +typedef struct _RADIUS_ACCT_LINK_COUNT +{ + BYTE num; + RADIUS_ATTRIBUTE_ACCT_LINK_COUNT acct_link_count[RADIUS_MAX_NUM_OF_ACCT_LINK_COUNT]; +}__attribute__((packed)) RADIUS_ACCT_LINK_COUNT; + +typedef struct _RADIUS_EAP_MESSAGE +{ + BYTE num; + RADIUS_ATTRIBUTE_EAP_MESSAGE eap_message[RADIUS_MAX_NUM_OF_EAP_MESSAGE]; +}__attribute__((packed)) RADIUS_EAP_MESSAGE; + +typedef struct _RADIUS_ARAP_SECURITY_DATA +{ + BYTE num; + RADIUS_ATTRIBUTE_ARAP_SECURITY_DATA arap_security_data[RADIUS_MAX_NUM_OF_ARAP_SECURITY_DATA]; +}__attribute__((packed)) RADIUS_ARAP_SECURITY_DATA; + +typedef struct _RADIUS_CONFIGURATION_TOKEN +{ + BYTE num; + RADIUS_ATTRIBUTE_CONFIGURATION_TOKEN configuration_token[RADIUS_MAX_NUM_OF_CONFIGURATION_TOKEN]; +}__attribute__((packed)) RADIUS_CONFIGURATION_TOKEN; + +typedef struct _RADIUS_ERROR_CAUSE +{ + BYTE num; + RADIUS_ATTRIBUTE_ERROR_CAUSE error_cause[RADIUS_MAX_NUM_OF_ERROR_CAUSE]; +}__attribute__((packed)) RADIUS_ERROR_CAUSE; + + +typedef struct _RADIUS_ACCESS_REQUEST +{ + BYTE secret[RADIUS_MAX_LEN_OF_SHARE_KEY]; + + RADIUS_ATTRIBUTE_USER_NAME user_name; + RADIUS_ATTRIBUTE_USER_PASSWORD user_password;//An Access-Request MUST NOT contain both a User-Password and a CHAP-Password + RADIUS_ATTRIBUTE_CHAP_PASSWORD chap_password;//An Access-Request MUST NOT contain both a User-Password and a CHAP-Password + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS nas_ip_addr;//An Access-Request MUST contain either a NAS-IP-Address or a NAS-Identifier (or both) + RADIUS_ATTRIBUTE_NAS_PORT nas_port; + RADIUS_ATTRIBUTE_SERVICE_TYPE service_type; + RADIUS_ATTRIBUTE_FRAMED_PROTOCOL framed_protocol; + RADIUS_ATTRIBUTE_FRAMED_IP_ADDR framed_ip_addr; + RADIUS_ATTRIBUTE_FRAMED_IP_NETMASK framed_ip_netmask; + RADIUS_ATTRIBUTE_FRAMED_MTU framed_mtu; + RADIUS_FRAMED_COMPRESSION framed_compression; + RADIUS_LOGIN_IP_HOST login_ip_host; + RADIUS_ATTRIBUTE_CALLBACK_NUMBER callback_number; + RADIUS_ATTRIBUTE_STATE state; + RADIUS_VENDOR_SPECIFIC vendor_specific; + RADIUS_ATTRIBUTE_CALLED_STATION_ID called_station_id; + RADIUS_ATTRIBUTE_CALLING_STATION_ID calling_station_id; + RADIUS_ATTRIBUTE_NAS_IDENTIFIER nas_identifier;//An Access-Request MUST contain either a NAS-IP-Address or a NAS-Identifier (or both) + RADIUS_PROXY_STATE proxy_state; + RADIUS_ATTRIBUTE_LOGIN_LAT_SERVICE login_lat_service; + RADIUS_ATTRIBUTE_LOGIN_LAT_NODE login_lat_node; + RADIUS_ATTRIBUTE_LOGIN_LAT_GROUP login_lat_group; + RADIUS_ATTRIBUTE_CHAP_CHALLENGE chap_challenge;//not support to encode + RADIUS_ATTRIBUTE_NAS_PORT_TYPE nas_port_type; + RADIUS_ATTRIBUTE_PORT_LIMIT port_limit; + RADIUS_ATTRIBUTE_LOGIN_LAT_PORT login_lat_port; + RADIUS_ATTRIBUTE_ACCT_SESSION_ID acct_session_id; + RADIUS_ATTRIBUTE_ARAP_PASSWORD arap_password;//not support to encode + RADIUS_ATTRIBUTE_ARAP_SECURITY arap_security;//not support to encode + RADIUS_ARAP_SECURITY_DATA arap_security_data;//not support to encode + RADIUS_ATTRIBUTE_CONNECT_INFO connect_info; + RADIUS_EAP_MESSAGE eap_message; + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR message_authenticator; + RADIUS_ATTRIBUTE_NAS_PORT_ID nas_port_id; + RADIUS_ATTRIBUTE_NOWSMS_PREAUTH_TYPE pre_auth_type; //nowsms + RADIUS_ATTRIBUTE_NOWSMS_COUNT_ID_SIZE count_id_size; //nowsms +}__attribute__((packed)) RADIUS_ACCESS_REQUEST; + +typedef struct _RADIUS_ACCESS_ACCEPT +{ + RADIUS_ATTRIBUTE_USER_NAME user_name; + RADIUS_ATTRIBUTE_SERVICE_TYPE service_type; + RADIUS_ATTRIBUTE_FRAMED_PROTOCOL framed_protocol; + RADIUS_ATTRIBUTE_FRAMED_IP_ADDR framed_ip_addr; + RADIUS_ATTRIBUTE_FRAMED_IP_NETMASK framed_ip_netmask; + RADIUS_ATTRIBUTE_FRAMED_ROUTING framed_routing; + RADIUS_FILTER_ID filter_id; + RADIUS_ATTRIBUTE_FRAMED_MTU framed_mtu; + RADIUS_FRAMED_COMPRESSION framed_compression; + RADIUS_LOGIN_IP_HOST login_ip_host; + RADIUS_ATTRIBUTE_LOGIN_SERVICE login_service; + RADIUS_ATTRIBUTE_LOGIN_TCP_PORT login_tcp_port; + RADIUS_REPLY_MESSAGE reply_message; + RADIUS_ATTRIBUTE_CALLBACK_NUMBER callback_number; + RADIUS_ATTRIBUTE_CALLBACK_ID callback_id; + RADIUS_FRAMED_ROUTE framed_route; + RADIUS_ATTRIBUTE_FRAMED_IPX_NETWORK framed_ipx_network; + RADIUS_ATTRIBUTE_STATE state; + RADIUS_CLASS radius_class; + RADIUS_VENDOR_SPECIFIC vendor_specific; + RADIUS_ATTRIBUTE_SESSION_TIMEOUT session_timeout; + RADIUS_ATTRIBUTE_IDLE_TIMEOUT idle_timeout; + RADIUS_ATTRIBUTE_TERMINATION_ACTION termination_action; + RADIUS_PROXY_STATE proxy_state; + RADIUS_ATTRIBUTE_LOGIN_LAT_SERVICE login_lat_service; + RADIUS_ATTRIBUTE_LOGIN_LAT_NODE login_lat_node; + RADIUS_ATTRIBUTE_LOGIN_LAT_GROUP login_lat_group; + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_LINK framed_appletalk_link; + RADIUS_FRAMED_APPLETALK_NETWORK framed_appletalk_network; + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_ZONE framed_appletalk_zone; + RADIUS_ATTRIBUTE_PORT_LIMIT port_limit; + RADIUS_ATTRIBUTE_LOGIN_LAT_PORT login_lat_port; + RADIUS_ATTRIBUTE_ARAP_FEATURES arap_features;//not support to encode + RADIUS_ATTRIBUTE_ARAP_ZONE_ACCESS arap_zone_access;//not support to encode + RADIUS_CONFIGURATION_TOKEN configuration_token; + RADIUS_EAP_MESSAGE eap_message; + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR message_authenticator; + RADIUS_ATTRIBUTE_ARAP_CHALLENGE_RESPONSE arap_challenge_response;//not support to encode + RADIUS_ATTRIBUTE_ACCT_INTERIM_INTERVAL acct_interim_interval; + RADIUS_ATTRIBUTE_FRAMED_POOL framed_pool; +}__attribute__((packed)) RADIUS_ACCESS_ACCEPT; + +typedef struct _RADIUS_ACCESS_REJECT +{ + RADIUS_REPLY_MESSAGE reply_message; + RADIUS_PROXY_STATE proxy_state; + RADIUS_ATTRIBUTE_PASSWORD_RETRY password_retry; + RADIUS_EAP_MESSAGE eap_message; + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR message_authenticator; +}__attribute__((packed)) RADIUS_ACCESS_REJECT; + +typedef struct _RADIUS_ACCESS_CHALLENGE +{ + RADIUS_REPLY_MESSAGE reply_message; + RADIUS_ATTRIBUTE_STATE state; + RADIUS_VENDOR_SPECIFIC vendor_specific; + RADIUS_ATTRIBUTE_SESSION_TIMEOUT session_timeout; + RADIUS_ATTRIBUTE_IDLE_TIMEOUT idle_timeout; + RADIUS_PROXY_STATE proxy_state; + RADIUS_ATTRIBUTE_ARAP_FEATURES arap_features; + RADIUS_ATTRIBUTE_ARAP_SECURITY arap_security;//not support to encode + RADIUS_ARAP_SECURITY_DATA arap_security_data;//not support to encode + RADIUS_ATTRIBUTE_PROMPT prompt; + RADIUS_EAP_MESSAGE eap_message; + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR message_authenticator; + RADIUS_ATTRIBUTE_ARAP_CHALLENGE_RESPONSE arap_challenge_response; +}__attribute__((packed)) RADIUS_ACCESS_CHALLENGE; + +typedef struct _RADIUS_ACCOUNTING_REQUEST +{ + RADIUS_ATTRIBUTE_USER_NAME user_name; + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS nas_ip_addr;//An Access-Request MUST contain either a NAS-IP-Address or a NAS-Identifier (or both) + RADIUS_ATTRIBUTE_NAS_PORT nas_port; + RADIUS_ATTRIBUTE_SERVICE_TYPE service_type; + RADIUS_ATTRIBUTE_FRAMED_PROTOCOL framed_protocol; + RADIUS_ATTRIBUTE_FRAMED_IP_ADDR framed_ip_addr; + RADIUS_ATTRIBUTE_FRAMED_IP_NETMASK framed_ip_netmask; + RADIUS_ATTRIBUTE_FRAMED_ROUTING framed_routing; + RADIUS_FILTER_ID filter_id; + RADIUS_ATTRIBUTE_FRAMED_MTU framed_mtu; + RADIUS_FRAMED_COMPRESSION framed_compression; + RADIUS_LOGIN_IP_HOST login_ip_host; + RADIUS_ATTRIBUTE_LOGIN_SERVICE login_service; + RADIUS_ATTRIBUTE_LOGIN_TCP_PORT login_tcp_port; + RADIUS_ATTRIBUTE_CALLBACK_NUMBER callback_number; + RADIUS_ATTRIBUTE_CALLBACK_ID callback_id; + RADIUS_FRAMED_ROUTE framed_route; + RADIUS_ATTRIBUTE_FRAMED_IPX_NETWORK framed_ipx_network; + RADIUS_CLASS radius_class; + RADIUS_VENDOR_SPECIFIC vendor_specific; + RADIUS_ATTRIBUTE_SESSION_TIMEOUT session_timeout; + RADIUS_ATTRIBUTE_IDLE_TIMEOUT idle_timeout; + RADIUS_ATTRIBUTE_TERMINATION_ACTION termination_action; + RADIUS_ATTRIBUTE_CALLED_STATION_ID called_station_id; + RADIUS_ATTRIBUTE_CALLING_STATION_ID calling_station_id; + RADIUS_ATTRIBUTE_NAS_IDENTIFIER nas_identifier;//An Access-Request MUST contain either a NAS-IP-Address or a NAS-Identifier (or both) + RADIUS_PROXY_STATE proxy_state; + RADIUS_ATTRIBUTE_LOGIN_LAT_SERVICE login_lat_service; + RADIUS_ATTRIBUTE_LOGIN_LAT_NODE login_lat_node; + RADIUS_ATTRIBUTE_LOGIN_LAT_GROUP login_lat_group; + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_LINK framed_appletalk_link; + RADIUS_FRAMED_APPLETALK_NETWORK framed_appletalk_network; + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_ZONE framed_appletalk_zone; + RADIUS_ATTRIBUTE_ACCT_STATUS_TYPE acct_status_type; + RADIUS_ATTRIBUTE_ACCT_DELAY_TIME acct_delay_time; + RADIUS_ATTRIBUTE_ACCT_INPUT_OCTETS acct_input_octets; + RADIUS_ATTRIBUTE_ACCT_OUTPUT_OCTETS acct_output_octets; + RADIUS_ATTRIBUTE_ACCT_SESSION_ID acct_session_id; + RADIUS_ATTRIBUTE_ACCT_AUTHENTIC acct_authentic; + RADIUS_ATTRIBUTE_ACCT_SESSION_TIME acct_session_time; + RADIUS_ATTRIBUTE_ACCT_INPUT_PACKETS acct_input_packets; + RADIUS_ATTRIBUTE_ACCT_OUTPUT_PACKETS acct_output_packets; + RADIUS_ATTRIBUTE_ACCT_TERMINATE_CAUSE acct_terminate_cause; + RADIUS_ACCT_MULTI_SESSION_ID acct_multi_session_id; + RADIUS_ACCT_LINK_COUNT acct_link_count; + RADIUS_ATTRIBUTE_NAS_PORT_TYPE nas_port_type; + RADIUS_ATTRIBUTE_PORT_LIMIT port_limit; + RADIUS_ATTRIBUTE_LOGIN_LAT_PORT login_lat_port; +}__attribute__((packed)) RADIUS_ACCOUNTING_REQUEST; + +typedef struct _RADIUS_ACCOUNTING_RESPONSE +{ + RADIUS_VENDOR_SPECIFIC vendor_specific; + RADIUS_PROXY_STATE proxy_state; +}__attribute__((packed)) RADIUS_ACCOUNTING_RESPONSE; + +typedef struct _RADIUS_DISCONNECT_REQUEST +{ + RADIUS_ATTRIBUTE_USER_NAME user_name; + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS nas_ip_addr; + RADIUS_ATTRIBUTE_NAS_PORT nas_port; + RADIUS_ATTRIBUTE_SERVICE_TYPE service_type; + RADIUS_ATTRIBUTE_FRAMED_IP_ADDR framed_ip_addr; + RADIUS_REPLY_MESSAGE reply_message; + RADIUS_ATTRIBUTE_STATE state; + RADIUS_CLASS radius_class; + RADIUS_VENDOR_SPECIFIC vendor_specific; + RADIUS_ATTRIBUTE_CALLED_STATION_ID called_station_id; + RADIUS_ATTRIBUTE_CALLING_STATION_ID calling_station_id; + RADIUS_ATTRIBUTE_NAS_IDENTIFIER nas_identifier; + RADIUS_PROXY_STATE prxoy_state; + RADIUS_ATTRIBUTE_ACCT_SESSION_ID acct_session_id; + RADIUS_ATTRIBUTE_ACCT_TERMINATE_CAUSE acct_terminate_cause; + RADIUS_ATTRIBUTE_ACCT_MULTI_SESSION_ID acct_multi_session_id; + RADIUS_ATTRIBUTE_EVENT_TIMESTAMP event_timestamp; + RADIUS_ATTRIBUTE_NAS_PORT_TYPE nas_port_type; + RADIUS_EAP_MESSAGE eap_message; + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR message_authenticator; + RADIUS_ATTRIBUTE_NAS_PORT_ID nas_port_id; + RADIUS_ATTRIBUTE_ORIGINATING_LINE_INFO originating_line_info;//not support to encode + RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID framed_interface_id;//not support to encode +// RADIUS_ATTRIBUTE_NAS_IPV6_ADDR nas_ipv6_addr;//not support to encode +// RADIUS_ATTRIBUTE_FRAMED_IPV6_PREFIX framed_ipv6_prefix;//not support to encode +}__attribute__((packed)) RADIUS_DISCONNECT_REQUEST; + +typedef struct _RADIUS_DISCONNECT_ACK +{ + RADIUS_ATTRIBUTE_STATE state; + RADIUS_PROXY_STATE proxy_state; + RADIUS_ATTRIBUTE_ACCT_TERMINATE_CAUSE acct_terminate_cause; + RADIUS_ATTRIBUTE_EVENT_TIMESTAMP event_timestamp; + RADIUS_ATTRIBUTE_EAP_MESSAGE eap_message; + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR message_authenticator; + RADIUS_ERROR_CAUSE error_cause; +}__attribute__((packed)) RADIUS_DISCONNECT_ACK; + +typedef struct _RADIUS_DISCONNECT_NAK +{ + RADIUS_ATTRIBUTE_SERVICE_TYPE service_type; + RADIUS_ATTRIBUTE_STATE state; + RADIUS_PROXY_STATE proxy_state; + RADIUS_ATTRIBUTE_EVENT_TIMESTAMP event_timestamp; + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR message_authenticator; + RADIUS_ERROR_CAUSE error_cause; +}__attribute__((packed)) RADIUS_DISCONNECT_NAK; + +typedef struct _RADIUS_ADDR +{ + WORD port; + union + { + DWORD ipV4; + DWORD ipV6[4]; + }addr; +}__attribute__((packed)) RADIUS_ADDR; + +typedef struct _RADIUS_PID +{ + BYTE flag; + + BYTE sap_index; + + BYTE type;//indcation or request + BYTE state; + + BYTE rv_msg_flag;//recv msg or not + + BYTE trans_req_msg_type;//request msg type of process transaction + + BYTE identifier; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH];//store request or indication authenticator + + BYTE sd_msg_flag; + + BYTE nas_id; + RADIUS_ADDR peer_addr; + + BYTE sd_msg_type; + WORD msg_len; + BYTE msg[RADIUS_MAX_LEN_OF_MSG]; + + WORD usr_pid; + + WORD timer; +}__attribute__((packed)) RADIUS_PID; + +typedef struct _RADIUS_MSG +{ + BYTE msg_type; + + union + { + RADIUS_ACCESS_REQUEST access_request; + RADIUS_ACCESS_ACCEPT access_accept; + RADIUS_ACCESS_REJECT access_reject; + RADIUS_ACCESS_CHALLENGE access_challenge; + RADIUS_ACCOUNTING_REQUEST accounting_request; + RADIUS_ACCOUNTING_RESPONSE accounting_response; + RADIUS_DISCONNECT_REQUEST disconnect_request; + RADIUS_DISCONNECT_ACK disconnect_ack; + RADIUS_DISCONNECT_NAK disconnect_nak; + }msg; +}__attribute__((packed)) RADIUS_MSG; + +typedef struct _RADIUS_ATTR_PARSE_FUNCTION +{ + int (*parse_function)(RADIUS_MSG *, const BYTE *, BYTE); +}__attribute__((packed)) RADIUS_ATTR_PARSE_FUNCTION; + +typedef struct _RADIUS_SAP +{ + char name[RADIUS_MAX_LEN_OF_USER_NAME]; + + int (*radius_ind)(WORD *usr_pid, WORD pid, RADIUS_MSG *msg_pdu); + + int (*radius_cnf)(WORD usr_pid, WORD pid, RADIUS_MSG *msg_pdu); +}__attribute__((packed)) RADIUS_SAP; + +typedef struct _RADIUS_ENCRYPT_USER_PASSWORD_CONTEXT +{ + DWORD i[2]; + + BYTE result[RADIUS_MAX_LEN_OF_RESULT]; + + BYTE in[RADIUS_MAX_LEN_OF_IN]; + + BYTE count; + int result_len; +}__attribute__((packed)) RADIUS_ENCRYPT_USER_PASSWORD_CONTEXT; + +typedef struct _RADIUS_NAS_INFO +{ + BYTE flag; + + BYTE sap_index; + + DWORD nas_ip; + BYTE share_key[RADIUS_MAX_LEN_OF_SHARE_KEY]; + BYTE password[RADIUS_MAX_LEN_OF_PASSWORD]; +}__attribute__((packed)) RADIUS_NAS_INFO; + +#endif + diff --git a/plat/radius/src/include/radius_transport.h b/plat/radius/src/include/radius_transport.h new file mode 100644 index 0000000..42667aa --- /dev/null +++ b/plat/radius/src/include/radius_transport.h @@ -0,0 +1,8 @@ +#ifndef _RADIUS_TRANSPORT_H +#define _RADIUS_TRANSPORT_H + +int radius_recv_udp_msg(void); +int radius_send_udp_msg(int pid); + +#endif + diff --git a/plat/radius/src/radius.c b/plat/radius/src/radius.c new file mode 100644 index 0000000..e144bb5 --- /dev/null +++ b/plat/radius/src/radius.c @@ -0,0 +1,121 @@ +#include "./include/radius_pub.h" +#include "./include/radius_def.h" + +// fix multiple definition==================================== +BYTE RADIUS_Version[4] = {1, 0, 0, 2}; + +int radius_udp_access_socket_fd; + +int radius_udp_account_socket_fd; + +int radius_udp_disconnect_socket_fd; + +int radius_pid_select; + +BYTE radius_access_id_select; +BYTE radius_accounting_id_select; +BYTE radius_disconnect_id_select; + +RADIUS_MSG radius_msg_pdu; + +RADIUS_PID radius_pid[RADIUS_MAX_NUM_OF_PID]; + +BYTE radius_udp_msg_recv_buf[RADIUS_MAX_LEN_OF_UDP_MSG]; + +WORD radius_mon_flag; + +BYTE radius_asci_tmp_buf[RADIUS_MAX_ASCITMP_LEN]; +BYTE radius_asci_out_buf[RADIUS_MAX_ASCIIOUT_LEN]; +BYTE radius_asci_in_buf[RADIUS_MAX_ASCIIIN_LEN]; + +char radius_msg_type_str[RADIUS_MAX_LEN_OF_MSG_TYEP]; + +RADIUS_ATTR_PARSE_FUNCTION radius_attr_parse_function[RADIUS_MAX_NUM_OF_ATTRIBUTE]; + +RADIUS_SAP radius_sap[RADIUS_MAX_NUM_OF_SAP]; + +RADIUS_NAS_INFO radius_nas_info[RADIUS_MAX_NUM_OF_NAS]; +//============================================================== + +int radius_init(void) +{ + int i; + + radius_init_socket(); + + for (i = 0; i < RADIUS_MAX_NUM_OF_PID; i++) + { + radius_init_pid(i); + } + + radius_attr_parse_init(); + + memset(&radius_msg_pdu, 0, sizeof(RADIUS_MSG)); + + memset(&radius_nas_info, 0, sizeof(RADIUS_NAS_INFO) * RADIUS_MAX_NUM_OF_NAS); +/* + for (i = 0; i < RADIUS_MAX_NUM_OF_SAP; i++) + { + strcpy(radius_nas_share_key[i], ""); + strcpy(radius_nas_password[i], ""); + }*/ + + radius_pid_select = 0; + + radius_access_id_select = 0; + radius_accounting_id_select = 0; + radius_disconnect_id_select = 0; + + strcpy((char *)radius_asci_in_buf, "\0"); + strcpy((char *)radius_asci_out_buf, "\0"); + strcpy((char *)radius_asci_tmp_buf, "\0"); + strcpy((char *)radius_udp_msg_recv_buf, "\0"); + strcpy(radius_msg_type_str, "\0"); + radius_mon_flag = RADIUS_MONITOR_NONE; + radius_debug_set(); + + return 0; +} + +void radius_t10ms(void) +{ + static DWORD cnt_100ms = 0; + + if (!(++cnt_100ms % 10)) + { + radius_mon(); + cnt_100ms = 0; + } +} + +void radius_timer(void) +{ + radius_recv_udp_msg(); + + radius_t10ms(); + + radius_fsm(); +} + +int radius_bind(RADIUS_SAP *sap) +{ + int i; + + if ((sap == NULL) || (sap->radius_ind == NULL) || (sap->radius_cnf == NULL)) + return -1; + + for (i = 0; i < RADIUS_MAX_NUM_OF_SAP; i++) + { + if ((radius_sap[i].radius_ind != NULL) || (radius_sap[i].radius_cnf != NULL)) + continue; + + memcpy(&radius_sap[i], sap, sizeof(RADIUS_SAP)); + + radius_sap[i].name[RADIUS_MAX_LEN_OF_USER_NAME - 1] = '\0'; + + return i; + } + + return -1; +} + diff --git a/plat/radius/src/radius_debug.c b/plat/radius/src/radius_debug.c new file mode 100644 index 0000000..ebd654b --- /dev/null +++ b/plat/radius/src/radius_debug.c @@ -0,0 +1,495 @@ +#include "./include/radius_pub.h" +#include "./include/radius_inc.h" + +#define RADIUS_DEBUG_ID 31 + +static char ascii[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}; + +static BYTE log_help[] = { +"RADIUS Debug Monitor Help:\n\r\ +\n\r\ +1.[help] display help menu\n\r\ +2.[log all/none] display all/none logs\n\r\ +3.[log error on/off] display error logs\n\r\ +4.[log warn on/off] display warn logs\n\r\ +5.[log radius msg on/off] display radius msg logs\n\r\ +6.[list nas] display nas information\n\r\n\r" +}; + +static WORD disp_page[10]; +static BYTE *disp_ptr = (BYTE *) disp_page; + +static DWORD radius_debug_status_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,RADIUS_DEBUG_ID + 2,1 +}; + +static BYTE radius_debug_status = 1; + +static DWORD radius_debug_name_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,RADIUS_DEBUG_ID + 2,2 +}; + +static DWORD radius_debug_ascin_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,RADIUS_DEBUG_ID + 2,3 +}; + +static DWORD radius_debug_ascout_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,RADIUS_DEBUG_ID + 2,4 +}; + +static DWORD radius_debug_page_title[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,RADIUS_DEBUG_ID + 2,1,1 +}; + +static DWORD radius_debug_page_line[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,RADIUS_DEBUG_ID + 2,1,2,1 +}; + +const static BYTE RADIUS_BASE_ID_LEN = 15; +const static BYTE RADIUS_PAGE_POINT = 14; +const static BYTE RADIUS_LINE_POINT = 15; + +static BYTE radius_title1_p[] = +{ + " RADIUS Page 02 \n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +Subpage\n\r\ +RADIUS_PID\n\r" +}; + +BYTE radius_disp_line(BYTE page, BYTE line) +{ + BYTE disp_length; + + disp_length = 16; + disp_ptr = (BYTE *) disp_page; + + switch (page) + { + case 1: // Page 1: pid Info + if (line == 0) + { + disp_ptr = (BYTE *) &disp_page[page]; + disp_length = 2; + } + else + disp_ptr = (BYTE *) radius_pid + disp_page[page] * sizeof(RADIUS_PID) + (line - 1) * 16; + break; + default: + disp_length = 0; + break; + } + + return disp_length; +} + +void radius_disp_page(BYTE page) +{ + BYTE disp_line; + BYTE disp_length; + + radius_debug_page_line[RADIUS_PAGE_POINT] = page + 5; + + for (disp_line = 0; disp_line < 20; disp_line++) + { + disp_length = radius_disp_line(page, disp_line); + radius_debug_page_line[RADIUS_LINE_POINT] = disp_line + 2; + radius_debug_page_line[RADIUS_LINE_POINT + 1] = 2; // Data Pointer + debug_set_response(RADIUS_BASE_ID_LEN + 2, radius_debug_page_line, disp_ptr, disp_length); + } +} + +int radius_debug_set(void) +{ + BYTE page; + BYTE data[10]; + BYTE *ptr; + BYTE version[16]; + + bzero(disp_page, 20); + + ptr = data; + + sprintf((char*)version, "V%d.%d.%d%d", RADIUS_Version[0], RADIUS_Version[1], RADIUS_Version[2], RADIUS_Version[3]); + debug_set_response(RADIUS_BASE_ID_LEN, radius_debug_status_id, (BYTE *)&radius_debug_status, 1); + debug_set_response(RADIUS_BASE_ID_LEN, radius_debug_name_id, version, 10); + debug_set_response(RADIUS_BASE_ID_LEN, radius_debug_ascin_id, radius_asci_in_buf, 4096); + debug_set_response(RADIUS_BASE_ID_LEN, radius_debug_ascout_id, radius_asci_out_buf, 4096); + + for (page = 1; page < 4; page++) + { + switch (page) + { + case 1: //page 1 + ptr = radius_title1_p; + break; + default: + break; + } + + radius_debug_page_title[RADIUS_PAGE_POINT] = 5 + page; + debug_set_response(RADIUS_BASE_ID_LEN + 1, radius_debug_page_title, ptr, strlen((char *)ptr)); + radius_disp_page(page); + } + + return 1; +} + +int radius_asciout_proc(char *out_str) +{ + int out_len; + + out_len = strlen(out_str); + + radius_asci_out_buf[RADIUS_MAX_ASCIIOUT_LEN - 1] = '\0'; + + if (out_len + strlen((char *)radius_asci_out_buf) > RADIUS_MAX_ASCIIOUT_LEN - 2) + { + strcpy((char *)radius_asci_out_buf, out_str); + } + else + { + strcat((char *)radius_asci_out_buf, out_str); + } + + radius_asci_out_buf[RADIUS_MAX_ASCIIOUT_LEN - 1] = '\0'; + + return 1; +} + +void radius_list_nas() +{ + int i; + BYTE tmp_buf[256] = ""; + BYTE out_buf[2048] = ""; + struct in_addr nas_addr; + RADIUS_NAS_INFO *nas_info_ptr; + + sprintf((char*)out_buf, "NAS id\tip address\t\tpassword\t\t\tshare key\r\n"); + + for (i = 0; i < RADIUS_MAX_NUM_OF_NAS; i++) + { + nas_info_ptr = radius_get_nas_info_ptr(i); + + if (nas_info_ptr->flag != 1) + continue; + + nas_addr.s_addr = nas_info_ptr->nas_ip; + + sprintf((char*)tmp_buf, "%d\t%s\t\t%s\t\t\t%s\r\n", i, inet_ntoa(nas_addr), nas_info_ptr->password, nas_info_ptr->share_key); + strcat((char*)out_buf, (char*)tmp_buf); + } + + radius_asciout_proc((char*)out_buf); +} + +void radius_mon(void) +{ + BYTE in_page, err_fg = 0; + BYTE *ascii_in_ptr = NULL; + BYTE *str_start = NULL; + WORD str_len; + WORD num; + + if ((str_len = strlen((char *)radius_asci_in_buf)) > 0) + { + in_page = radius_asci_in_buf[0] - 1; + ascii_in_ptr = radius_asci_in_buf + 1; + + if (in_page > 3) + err_fg = 1; + else if (strcmp((char *)ascii_in_ptr,"log error on") == 0) + { + radius_mon_flag = radius_mon_flag | RADIUS_MONITOR_ERROR; + } + else if (strcmp((char *)ascii_in_ptr,"log error off") == 0) + { + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_ERROR); + } + else if (strcmp((char *)ascii_in_ptr,"log warn on") == 0) + { + radius_mon_flag = radius_mon_flag | RADIUS_MONITOR_WARN; + } + else if (strcmp((char *)ascii_in_ptr,"log warn off") == 0) + { + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_WARN); + } + else if (strcmp((char *)ascii_in_ptr,"log radius msg on") == 0) + { + radius_mon_flag = radius_mon_flag | RADIUS_MONITOR_SDRV_MSG; + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_ACCESS_MSG); + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_ACCT_MSG); + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_DISC_MSG); + } + else if (strcmp((char *)ascii_in_ptr,"log radius msg off") == 0) + { + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_SDRV_MSG); + } + else if (strcmp((char *)ascii_in_ptr,"log access msg on") == 0) + { + radius_mon_flag = radius_mon_flag | RADIUS_MONITOR_ACCESS_MSG; + } + else if (strcmp((char *)ascii_in_ptr,"log access msg off") == 0) + { + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_ACCESS_MSG); + } + else if (strcmp((char *)ascii_in_ptr,"log acct msg on") == 0) + { + radius_mon_flag = radius_mon_flag | RADIUS_MONITOR_ACCT_MSG; + } + else if (strcmp((char *)ascii_in_ptr,"log acct msg off") == 0) + { + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_ACCT_MSG); + } + else if (strcmp((char *)ascii_in_ptr,"log disc msg on") == 0) + { + radius_mon_flag = radius_mon_flag | RADIUS_MONITOR_DISC_MSG; + } + else if (strcmp((char *)ascii_in_ptr,"log disc msg off") == 0) + { + radius_mon_flag = radius_mon_flag & (~RADIUS_MONITOR_DISC_MSG); + } + else if (strcmp((char *)ascii_in_ptr,"log all") == 0) + { + radius_mon_flag = RADIUS_MONITOR_ALL; + } + else if (strcmp((char *)ascii_in_ptr,"log none") == 0) + { + radius_mon_flag = RADIUS_MONITOR_NONE; + } + else if (strcmp((char *)ascii_in_ptr, "list nas") == 0) + { + radius_list_nas(); + } + else if (strcmp((char *)ascii_in_ptr,"help") == 0) + { + radius_asciout_proc((char*)log_help); + } + else if (isdigit(ascii_in_ptr[0])) + { + num = strtoul((char *)ascii_in_ptr, NULL, 10); + disp_page[in_page] = num; + radius_disp_page(in_page); + } + else if ((str_start = (BYTE *)strstr((char *)ascii_in_ptr, ">")) != NULL) + { + num = strtoul((char *)(str_start + 1), NULL, 10); + disp_page[in_page] += num; + radius_disp_page(in_page); + } + else if ((str_start = (BYTE *)strstr((char *)ascii_in_ptr, "<"))!= NULL) + { + num = strtoul((char *)(str_start + 1), NULL, 10); + disp_page[in_page] -= num; + radius_disp_page(in_page); + } + else + err_fg = 1; + + if (err_fg == 0) + radius_asciout_proc("Command OK!\n\r"); + else + radius_asciout_proc("Command Error!\n\r"); + + strcpy((char *)radius_asci_in_buf, "\0"); + } +} + +int radius_hex_to_ascii(BYTE *from_hex, BYTE from_len, BYTE *to_asc) +{ + int i, j; + + j = 0; + + for (i = 0; i< from_len; i++) + { + to_asc[j] = ascii[from_hex[i] >> 4]; + j++; + to_asc[j] = ascii[from_hex[i] & 0x0F]; + j++; + to_asc[j] = ' '; + j++; + } + + to_asc[j] = '\0'; + + return 1; +} + +int radius_log_err(const char *fmt, ...) +{ + va_list ap; + char err_msg[2048]; + char time_str[1024]; + struct tm *t; + struct timeval tv; + struct timezone tz; + + if ((radius_mon_flag & RADIUS_MONITOR_ERROR) == RADIUS_MONITOR_ERROR) + { + gettimeofday(&tv, &tz); + t = localtime(&tv.tv_sec); + sprintf(time_str, "[%d:%d:%d.%ld]:", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec); + + va_start(ap, fmt); + vsprintf(err_msg, fmt, ap); + + if (strlen((char *)err_msg) >= RADIUS_MAX_ASCITMP_LEN) + sprintf((char *)radius_asci_tmp_buf, "\33[31m%slog msg is too long: %zu\r\n", time_str, strlen((char *)err_msg)); + else + sprintf((char *)radius_asci_tmp_buf, "\33[31m%s%s\r\n", time_str, err_msg); + + strcat((char *)radius_asci_tmp_buf, "\33[37m"); + + radius_asciout_proc((char*)radius_asci_tmp_buf); + va_end(ap); + } + + return 0; +} + + +int radius_log_event(const char *fmt, ...) +{ + char time_str[1024]; + char msg[2048]; + va_list ap; + struct tm *t; + struct timeval tv; + struct timezone tz; + + if ((radius_mon_flag & RADIUS_MONITOR_EVENT) == RADIUS_MONITOR_EVENT) + { + gettimeofday(&tv, &tz); + t = localtime(&tv.tv_sec); + sprintf(time_str, "[%d:%d:%d.%ld]:", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec); + + va_start(ap, fmt); + vsprintf(msg, fmt, ap); + + radius_asciout_proc("\33[34m"); + + if ((strlen((char *)msg) + strlen(time_str)) >= RADIUS_MAX_ASCITMP_LEN) + sprintf((char *)radius_asci_tmp_buf, "%s log msg is too long: %zu\n\r", time_str, (strlen((char *)msg) + strlen(time_str))); + else + sprintf((char *)radius_asci_tmp_buf, "%s%s\n\r", time_str, msg); + + strcat((char *)radius_asci_tmp_buf, "\33[37m"); + radius_asciout_proc((char *)radius_asci_tmp_buf); + + va_end(ap); + } + + return 0; +} + +int radius_log_warn(const char *fmt, ...) +{ + + char timestr[1024]; + char msg[2048]; + va_list ap; + struct tm *t; + struct timeval tv; + struct timezone tz; + + if ((radius_mon_flag & RADIUS_MONITOR_WARN) == RADIUS_MONITOR_WARN) + { + gettimeofday(&tv, &tz); + t = localtime(&tv.tv_sec); + sprintf(timestr, "[%d:%d:%d.%ld]:", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec); + + va_start(ap, fmt); + vsprintf(msg, fmt, ap); + + radius_asciout_proc("\33[33m"); + + if ((strlen((char *)msg) + strlen(timestr)) >= RADIUS_MAX_ASCITMP_LEN) + sprintf((char *)radius_asci_tmp_buf, "%s log msg is too long: %zu\n\r", timestr, (strlen((char *)msg) + strlen(timestr))); + else + sprintf((char *)radius_asci_tmp_buf, "%s%s\n\r", timestr, msg); + + strcat((char *)radius_asci_tmp_buf, "\33[37m"); + radius_asciout_proc((char *)radius_asci_tmp_buf); + + va_end(ap); + } + + return 0; +} + +int radius_log_send_recv_msg(BYTE *msg, int len, RADIUS_ADDR *addr, BYTE msg_type, BYTE flag) +{ + struct tm *t; + struct timeval tv; + struct timezone tz; + char str[RADIUS_MAX_LEN_OF_MSG] = ""; + char time_str[1024]; + struct sockaddr_in src_addr; + BYTE log_flag = 0; + + switch (msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + case RADIUS_MSG_TYPE_ACCESS_REJECT: + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + if ((radius_mon_flag & RADIUS_MONITOR_ACCESS_MSG) == RADIUS_MONITOR_ACCESS_MSG) + log_flag = 1; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + if ((radius_mon_flag & RADIUS_MONITOR_ACCT_MSG) == RADIUS_MONITOR_ACCT_MSG) + log_flag = 1; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + if ((radius_mon_flag & RADIUS_MONITOR_DISC_MSG) == RADIUS_MONITOR_DISC_MSG) + log_flag = 1; + break; + default: + if ((radius_mon_flag & RADIUS_MONITOR_SDRV_MSG) == RADIUS_MONITOR_SDRV_MSG) + log_flag = 1; + break; + } + + if (log_flag == 1) + { + gettimeofday(&tv, &tz); + t = localtime(&tv.tv_sec); + sprintf(time_str, "[%d:%d:%d.%ld]:", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec); + + radius_msg_to_fmt(msg, len, str, RADIUS_MAX_LEN_OF_MSG); + + radius_asciout_proc("\33[34m"); + + if ((strlen(str) + strlen(time_str) + 64) >= RADIUS_MAX_ASCITMP_LEN) + sprintf((char *)radius_asci_tmp_buf, "%s log msg is too long: %zu\n\r", time_str, (strlen(str) + strlen(time_str))); + else + { + src_addr.sin_addr.s_addr = addr->addr.ipV4; + if (flag == RADIUS_RECV_MSG_FLAG) + { + sprintf((char *)radius_asci_tmp_buf, "%sRecieve Msg<===src port: %d, src ip: %s\r\n%s\n\r", time_str, addr->port, inet_ntoa(src_addr.sin_addr), str); + } + else + { + sprintf((char *)radius_asci_tmp_buf, "%sSend Msg===>dest port: %d, dest ip: %s\r\n%s\n\r", time_str, addr->port, inet_ntoa(src_addr.sin_addr), str); + } + } + + strcat((char *)radius_asci_tmp_buf, "\33[37m"); + radius_asciout_proc((char *)radius_asci_tmp_buf); + } + + return 0; +} + diff --git a/plat/radius/src/radius_fsm.c b/plat/radius/src/radius_fsm.c new file mode 100644 index 0000000..c5f78c6 --- /dev/null +++ b/plat/radius/src/radius_fsm.c @@ -0,0 +1,340 @@ +#include "./include/radius_pub.h" + +#define test_nowsms_enable 0 +#define test_css_enable 0 + +#define radius_set_pid_state(val) do { \ + pid_ptr->state = val; \ + radius_log_event("[%05d] \33[32m%s\33[0m transfer to state \33[36m%s\33[0m\r\n", pid, __FUNCTION__, #val); \ +} while(0) + +#define radius_set_pid_timer(val) do { \ + pid_ptr->timer = val; \ +} while(0) + +#if(test_nowsms_enable) +static void radius_test(int pid, BYTE sap_index, WORD *usr_pid, RADIUS_MSG *ptr_radius) +{ + RADIUS_MSG pdu; + + if(usr_pid == NULL || ptr_radius == NULL) + return; + memset(&pdu, 0, sizeof(RADIUS_MSG)); + pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT; + pdu.msg.access_accept.message_authenticator.flag = 1; + radius_send_access_accept(sap_index, pid, *usr_pid, &pdu); + return; +} +#elif(test_css_enable) +static void radius_test(int pid, BYTE sap_index, WORD *usr_pid, RADIUS_MSG *ptr_radius) +{ + static BYTE user_id = 0; + BYTE count = 0; + int num, i; + RADIUS_MSG pdu; + RADIUS_ACCESS_ACCEPT *access_accept; + RADIUS_VENDOR_SPECIFIC *vendor_specific; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC *ppac; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq; + + if(usr_pid == NULL || ptr_radius == NULL) + return; + if(ptr_radius->msg.access_request.user_password.flag == 1) + { + count = 1; + *usr_pid = user_id; + user_id++; + } + else if((num = ptr_radius->msg.access_request.vendor_specific.num) > 0) + { + for(i = 0; i < num; i++) + { + vendor_specific = &ptr_radius->msg.access_request.vendor_specific; + ppaq = &vendor_specific->vendor_specific[i].attribute_3gpp2.ppaq; + if((vendor_specific->vendor_specific[i].vendor_type == RADIUS_VENDOR_TYPE_3GPP2_PPAQ) && (ppaq->qid.flag == 1)) + { + *usr_pid = (ppaq->qid.qid.value >> 16) & 0xFF; + count = (ppaq->qid.qid.value & 0xFF) + 1; + } + } + } + + memset(&pdu, 0, sizeof(RADIUS_MSG)); + pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT; + access_accept = &pdu.msg.access_accept; + vendor_specific = &access_accept->vendor_specific; + num = vendor_specific->num; + vendor_specific->vendor_specific[num].flag = 1; + vendor_specific->vendor_specific[num].vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAC; + ppac = &vendor_specific->vendor_specific[num].attribute_3gpp2.ppac; + ppac->sfs.flag = 1; + //ppac->sfs.sfs = 2; //dt && dq + ppac->sfs.sfs = 1; //vt && vq + vendor_specific->num++; + num = vendor_specific->num; + vendor_specific->vendor_specific[num].vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAQ; + ppaq = &vendor_specific->vendor_specific[num].attribute_3gpp2.ppaq; + ppaq->qid.flag = 1; + ppaq->qid.qid.value = ((*usr_pid) << 16) | (count * 1); + + if(ppac->sfs.sfs == 1) + { + ppaq->vq.flag = 1; + ppaq->vq.vq.integer = (count + 1) * 1024 * 20; + ppaq->vq.vq.exponent = 1; + ppaq->vt.flag = 1; + ppaq->vt.vt.integer = (count + 1) * 1024 * 20 - 1024 * 2; + ppaq->vt.vt.exponent = 1; + } + else if(ppac->sfs.sfs == 2) + { + ppaq->dq.flag = 1; + ppaq->dq.dq.value = count * 20; + ppaq->dt.flag = 1; + ppaq->dt.dt.value = count * 20 - 2; + } + + vendor_specific->num++; + access_accept->message_authenticator.flag = 1; + radius_send_access_accept(sap_index, pid, *usr_pid, &pdu); + return; +} +#endif + +int radius_pid_indication_process(int pid) +{ + BYTE sap_index; + RADIUS_PID *pid_ptr; + + pid_ptr = radius_get_pid_ptr(pid); + + sap_index = pid_ptr->sap_index; + + switch (pid_ptr->state) + { + case RADIUS_PID_IND_STATE_IDLE: + if (pid_ptr->rv_msg_flag != 0) + { + pid_ptr->rv_msg_flag = 0; + + if (radius_sap[sap_index].radius_ind == NULL) + return 1; +#if(test_nowsms_enable || test_css_enable) +{ + radius_test(pid, sap_index, &pid_ptr->usr_pid, &radius_msg_pdu); +} +#else + if (radius_sap[sap_index].radius_ind(&pid_ptr->usr_pid, pid, &radius_msg_pdu) < 0) + { + radius_log_err("[%04d] %s: radius_ind error! usr_pid=%d\r\n", pid, __FUNCTION__, pid_ptr->usr_pid); + return 1; + } +#endif + radius_log_event("[%04d] %s: recv indication and send it to up layer\r\n", pid, __FUNCTION__); + + radius_set_pid_state(RADIUS_PID_IND_STATE_WAIT_FOR_USER_RESP); + radius_set_pid_timer(RADIUS_TIMER_16S); + } + else + { + return 1; + } + break; + case RADIUS_PID_IND_STATE_WAIT_FOR_USER_RESP: + if (pid_ptr->sd_msg_flag == 1) + { + pid_ptr->sd_msg_flag = 0; + + radius_send_msg(pid); + + radius_set_pid_timer(RADIUS_TIMER_16S); + + radius_set_pid_state(RADIUS_PID_IND_STATE_WAIT_FOR_TERMINATE); + + break; + } + + if (pid_ptr->timer > 0) + { + if (--pid_ptr->timer == 0) + { + radius_log_warn("[%04d] %s: wait user response time out\r\n", pid, __FUNCTION__); + radius_set_pid_state(RADIUS_PID_IND_STATE_TERMINATE); + + return 1; + } + } + break; + case RADIUS_PID_IND_STATE_WAIT_FOR_TERMINATE: + if (pid_ptr->rv_msg_flag != 0) + { + radius_send_msg(pid); + + pid_ptr->rv_msg_flag = 0; + } + + if (pid_ptr->timer > 0) + { + if (--pid_ptr->timer == 0) + { + radius_set_pid_state(RADIUS_PID_IND_STATE_TERMINATE); + return 1; + } + } + break; + } + + return 0; +} + +int radius_pid_indication_fsm(int pid) +{ + switch (radius_pid_indication_process(pid)) + { + case 0: + break; + case 1: + radius_init_pid(pid); + break; + } + + return 0; +} + +int radius_pid_request_process(int pid) +{ + BYTE sap_index; + RADIUS_PID *pid_ptr; + + pid_ptr = radius_get_pid_ptr(pid); + sap_index = pid_ptr->sap_index; + + switch (pid_ptr->state) + { + case RADIUS_PID_REQ_STATE_IDLE: + if (pid_ptr->sd_msg_flag == 1) + { + pid_ptr->sd_msg_flag = 0; + + radius_send_msg(pid); + + radius_set_pid_state(RADIUS_PID_REQ_STATE_WAIT_FOR_PEER_RESP); + + radius_set_pid_timer(RADIUS_TIMER_16S); + + break; + } + + if (pid_ptr->timer > 0) + { + if (--pid_ptr->timer == 0) + { + return 1; + } + } + else + { + return 1; + } + + break; + case RADIUS_PID_REQ_STATE_WAIT_FOR_PEER_RESP: + if (pid_ptr->rv_msg_flag != 0) + { + radius_log_event("[%04d]%s: recv peer response and send it to up layer\r\n", pid, __FUNCTION__); + + radius_set_pid_state(RADIUS_PID_REQ_STATE_TERMINATE); + + if (radius_sap[sap_index].radius_cnf == NULL) + { + radius_log_err("[%04d] %s: radius_cnf error! usr_pid=%d\r\n", pid, __FUNCTION__, pid_ptr->usr_pid); + return 1; + } + + radius_sap[sap_index].radius_cnf(pid_ptr->usr_pid, pid, &radius_msg_pdu); + + return 1; + } + + if (pid_ptr->timer > 0) + { + if (--pid_ptr->timer == 0) + { + radius_log_warn("[%04d] %s: wait peer response time out\r\n", pid, __FUNCTION__); + radius_set_pid_state(RADIUS_PID_REQ_STATE_TERMINATE); + + return 1; + } + else + { + if ((pid_ptr->timer % RADIUS_RETRANS_TIMER) == 0) + { + radius_send_msg(pid); + } + } + } + + break; + default: + return 1; + } + + return 0; +} + +int radius_pid_request_fsm(int pid) +{ + switch (radius_pid_request_process(pid)) + { + case 0: + break; + case 1: + radius_init_pid(pid); + break; + } + + return 0; +} + +int radius_p_fsm(int pid) +{ + RADIUS_PID *pid_ptr; + + if ((pid_ptr = radius_get_pid_ptr(pid)) == NULL) + return -1; + + switch (pid_ptr->type) + { + case RADIUS_PID_TYPE_IND: + radius_pid_indication_fsm(pid); + break; + case RADIUS_PID_TYPE_REQ: + radius_pid_request_fsm(pid); + break; + default: + radius_init_pid(pid); + break; + } + + return 0; +} + +int radius_fsm(void) +{ + int i; + RADIUS_PID *pid_ptr; + + for (i = 0; i < RADIUS_MAX_NUM_OF_PID; i++) + { + pid_ptr = radius_get_pid_ptr(i); + + if (pid_ptr->flag != 1) + continue; + + radius_p_fsm(i); + } + + return 0; +} + + diff --git a/plat/radius/src/radius_function.c b/plat/radius/src/radius_function.c new file mode 100644 index 0000000..c9f2e92 --- /dev/null +++ b/plat/radius/src/radius_function.c @@ -0,0 +1,9794 @@ +#include "./include/radius_pub.h" +#include "./include/radius_inc.h" + +static unsigned char USER_PASSWORD_PADDING[16] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +RADIUS_PID *radius_get_pid_ptr(int pid) +{ + if ((pid < 0) || (pid >= RADIUS_MAX_NUM_OF_PID)) + return NULL; + + return &radius_pid[pid]; +} + +int radius_init_pid(int pid) +{ + RADIUS_PID *pid_pt; + + if ((pid_pt = radius_get_pid_ptr(pid)) == NULL) + return -1; + + memset(pid_pt, 0, sizeof(RADIUS_PID)); + + return 0; +} + +int radius_init_udp_socket(struct sockaddr_in saddr, int multicast) +{ + int sock; + long sockBuf = 40*1024; + int on = 1, timeout = 20; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + + if (sock < 0) + { + fprintf(stderr, "Socket() failed\n"); + return -1; + } + + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &sockBuf, sizeof(sockBuf)) != 0) + { + fprintf(stderr, "RADIUS set socket buffer failed\n"); + close(sock); + return -1; + } + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,sizeof(on)) != 0) + { + fprintf(stderr, "RADIUS set addr reusable failed\n"); + close(sock); + return -1; + } + + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &timeout, sizeof(timeout)) != 0) + { + fprintf(stderr, "RADIUS set keepalive failed\n"); + close(sock); + return -1; + } + + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) + { + fprintf(stderr, "RADIUS set nonblock failed\n"); + close(sock); + return -1; + } + + if (bind(sock, (struct sockaddr *) &saddr, sizeof(struct sockaddr)) < 0) + { + fprintf(stderr, "RADIUS binding failed, port: %d\n", htons(saddr.sin_port)); + close(sock); + return -1; + } + + return sock; +} + + +int radius_init_socket(void) +{ + WORD access_port = RADIUS_ACCESS_PORT; + WORD account_port = RADIUS_ACCOUNTING_PORT; + WORD disconnect_port = RADIUS_DISCONNECT_PORT; + struct sockaddr_in sinAddr; + + memset(&sinAddr, 0, sizeof(struct sockaddr)); + sinAddr.sin_family = AF_INET; + sinAddr.sin_port = htons(access_port); + sinAddr.sin_addr.s_addr = GetLocalIP(); + memset(&(sinAddr.sin_zero), 0, 8); + + radius_udp_access_socket_fd = radius_init_udp_socket(sinAddr, 0); + + if (radius_udp_access_socket_fd < 0) + { + printf("RADIUS get ACCESS UDP Socket(%d) failed\n", access_port); + return -1; + } + + memset(&sinAddr, 0, sizeof(struct sockaddr)); + sinAddr.sin_family = AF_INET; + sinAddr.sin_port = htons(account_port); + sinAddr.sin_addr.s_addr = GetLocalIP(); + memset(&(sinAddr.sin_zero), 0, 8); + + radius_udp_account_socket_fd = radius_init_udp_socket(sinAddr, 0); + + if (radius_udp_account_socket_fd < 0) + { + printf("RADIUS get ACCOUNT UDP Socket(%d) failed\n", account_port); + return -1; + } + + memset(&sinAddr, 0, sizeof(struct sockaddr)); + sinAddr.sin_family = AF_INET; + sinAddr.sin_port = htons(disconnect_port); + sinAddr.sin_addr.s_addr = GetLocalIP(); + memset(&(sinAddr.sin_zero), 0, 8); + + radius_udp_disconnect_socket_fd = radius_init_udp_socket(sinAddr, 0); + + if (radius_udp_disconnect_socket_fd < 0) + { + printf("RADIUS get DISCONNECT UDP Socket(%d) failed\n", disconnect_port); + return -1; + } + + return 0; +} + +int radius_get_sock_fd_according_msg_type(BYTE msg_type) +{ + switch (msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + case RADIUS_MSG_TYPE_ACCESS_REJECT: + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + return radius_udp_access_socket_fd; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + return radius_udp_account_socket_fd; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + return radius_udp_disconnect_socket_fd; + default: + return -1; + } +} + +int radius_set_udp_dest_addr(struct sockaddr_in *dst_addr, RADIUS_ADDR *addr) +{ + if ((addr->addr.ipV4 == 0) || (addr->port == 0)) + { + radius_log_err("%s: ip=0x%X, port=%d\r\n", __FUNCTION__, addr->addr.ipV4, addr->port); + return -1; + } + + memset(dst_addr, 0, sizeof(struct sockaddr)); + + dst_addr->sin_family = AF_INET; + + dst_addr->sin_port = htons(addr->port); + + dst_addr->sin_addr.s_addr = addr->addr.ipV4; + + memset(&(dst_addr->sin_zero), 0, 8); + + return 0; +} + + +char radius_hex_to_ch(char uHex) +{ + return ((uHex) + (((uHex) > 9)? 'A'-10 : '0')); +} + +char *radius_get_msg_str(BYTE msg_type) +{ + switch (msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + sprintf(radius_msg_type_str, "ACCESS REQUEST"); + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + sprintf(radius_msg_type_str, "ACCESS ACCEPT"); + break; + case RADIUS_MSG_TYPE_ACCESS_REJECT: + sprintf(radius_msg_type_str, "ACCESS REJECT"); + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + sprintf(radius_msg_type_str, "ACCESS CHALLENGE"); + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + sprintf(radius_msg_type_str, "ACCOUNTING REQUEST"); + break; + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + sprintf(radius_msg_type_str, "ACCOUNTING RESPONSE"); + break; + case RADIUS_MSG_TYPE_STATUS_SERVER: + sprintf(radius_msg_type_str, "STATUS SERVER"); + break; + case RADIUS_MSG_TYPE_STATUS_CLIENT: + sprintf(radius_msg_type_str, "STATUS CLIENT"); + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + sprintf(radius_msg_type_str, "DISCONNECT REQUEST"); + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + sprintf(radius_msg_type_str, "DISCONNECT ACK"); + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + sprintf(radius_msg_type_str, "DISCONNECT NAK"); + break; + case RADIUS_MSG_TYPE_COA_REQUEST: + sprintf(radius_msg_type_str, "COA REQUEST"); + break; + case RADIUS_MSG_TYPE_COA_ACK: + sprintf(radius_msg_type_str, "COA ACK"); + break; + case RADIUS_MSG_TYPE_COA_NAK: + sprintf(radius_msg_type_str, "COA NAK"); + break; + default: + sprintf(radius_msg_type_str, "Unknown msg type=%d", msg_type); + break; + } + + return radius_msg_type_str; +} + +int radius_msg_to_fmt(const BYTE *bcd, int bcd_len, char *str, int str_buff_size) +{ + register int i, len = 0; + int str_len; + + str_len = (bcd_len / 16) * 49; + + if( (bcd_len % 16) > 8) + { + str_len +=8*3 +1; + } + + str_len += (bcd_len % 8) * 3 +1 + 2 ; //add "\r\n" at end + + if (str_len >= str_buff_size ) + { + radius_log_err("%s:sprint bcd string buffer flow\r\n", __FUNCTION__); + return -1; + } + + for (i = 0; i <= bcd_len-1; i++) + { + str[len++] = radius_hex_to_ch((bcd[i] & 0xF0) >> 4 ); + str[len++] = radius_hex_to_ch(bcd[i] & 0x0F); + str[len++] = ' '; + + if ( 0 == ( (i+1) % 16 ) && i) + { + str[len++] = '\n'; + } + else if ( 0 == ( (i+1) % 8 ) ) + { + str[len++] = ' '; + } + } + + if ( 0 != ( len % 49 ) ) + { + str[len++] = ' '; + } + + str[len++] = '\r'; + str[len++] = '\n'; + str[len++] = '\0'; + + return len; +} + +RADIUS_NAS_INFO *radius_get_nas_info_ptr(int id) +{ + if ((id < 0) || (id >= RADIUS_MAX_NUM_OF_NAS)) + return NULL; + + return &radius_nas_info[id]; +} + +int radius_accord_ip_search_nas_info(DWORD nas_ip) +{ + int i; + RADIUS_NAS_INFO *nas_info_ptr; + + for (i = 0; i < RADIUS_MAX_NUM_OF_NAS; i++) + { + nas_info_ptr = radius_get_nas_info_ptr(i); + + if ((nas_info_ptr->flag != 1) || (nas_info_ptr->nas_ip != nas_ip)) + continue; + + return i; + } + + return -1; +} + +int radius_get_pid() +{ + int i; + int pid = radius_pid_select; + RADIUS_PID *pid_ptr; + + if (pid >= RADIUS_MAX_NUM_OF_PID) + { + pid = 0; + } + + for (i = 0; i < RADIUS_MAX_NUM_OF_PID; i++) + { + pid_ptr = radius_get_pid_ptr(pid); + + if (pid_ptr->flag == 1) + { + pid = (pid + 1) % RADIUS_MAX_NUM_OF_PID; + + continue; + } + + radius_init_pid(pid); + + pid_ptr->flag = 1; + + radius_pid_select = (pid + 1) % RADIUS_MAX_NUM_OF_PID; + + return pid; + } + + return -1; +} + +int radius_match_response_pid(BYTE msg_type, BYTE identifier, BYTE *authenticator) +{ + int i; + RADIUS_PID *pid_ptr; + + for (i = 0; i < RADIUS_MAX_NUM_OF_PID; i++) + { + pid_ptr = radius_get_pid_ptr(i); + + if ((pid_ptr->flag != 1) || (pid_ptr->type != RADIUS_PID_TYPE_IND)) + { + continue; + } + + if ((pid_ptr->identifier != identifier) || (pid_ptr->trans_req_msg_type != msg_type) || (memcmp(pid_ptr->authenticator, authenticator, RADIUS_MAX_LEN_OF_AUTH) != 0)) + { + continue; + } + + pid_ptr->rv_msg_flag = msg_type; + + radius_p_fsm(i); + + return i; + } + + return -1; +} + +int radius_calculate_authenticator(BYTE *auth, const BYTE *msg, int msg_len, BYTE *share_key) +{ + int len; + BYTE raw[RADIUS_MAX_LEN_OF_MSG] = ""; + + memcpy(raw, msg, msg_len); + + memcpy(raw + msg_len, share_key, strlen((char*)share_key)); + + len = msg_len + strlen((char*)share_key); + + radius_get_md5_hex((char*)auth, (char*)raw, len); + + return 0; +} + +int radius_calculate_chap_password(BYTE *auth, BYTE chap_id, const BYTE *password, const BYTE *chap_challenge, int chap_len) +{ + int len; + BYTE raw[RADIUS_MAX_LEN_OF_MSG] = ""; + + raw[0] = chap_id; + len = 1; + + memcpy(raw + len, password, strlen((char*)password)); + len += strlen((char*)password); + + memcpy(raw + len, chap_challenge, chap_len); + len += chap_len; + + radius_get_md5_hex((char*)auth, (char*)raw, len); + + return 0; +} + +int radius_match_response_authenticator_with_request(BYTE *request_auth, BYTE *response_auth, BYTE *msg, int msg_len, BYTE *share_key) +{ + BYTE tmp_ptr[RADIUS_MAX_LEN_OF_MSG] = ""; + BYTE rep_auth[RADIUS_MAX_LEN_OF_AUTH] = ""; + + memcpy(tmp_ptr, msg, msg_len); + + memcpy(tmp_ptr + 4, request_auth, RADIUS_MAX_LEN_OF_AUTH); + + radius_calculate_authenticator(rep_auth, tmp_ptr, msg_len, share_key); + + if (memcmp(rep_auth, response_auth, RADIUS_MAX_LEN_OF_AUTH) != 0) + return -1; + + return 0; +} + +int radius_match_request_pid(BYTE msg_type, BYTE identifier, BYTE *authenticator, BYTE *msg, int msg_len, BYTE *share_key) +{ + int i; + RADIUS_PID *pid_ptr; + BYTE corresponsd_msg; + + switch (msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + case RADIUS_MSG_TYPE_ACCESS_REJECT: + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + corresponsd_msg = RADIUS_MSG_TYPE_ACCESS_REQUEST; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + corresponsd_msg = RADIUS_MSG_TYPE_ACCOUNTING_REQUEST; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + corresponsd_msg = RADIUS_MSG_TYPE_DISCONNECT_REQUEST; + break; + default: + return -1; + } + + for (i = 0; i < RADIUS_MAX_NUM_OF_PID; i++) + { + pid_ptr = radius_get_pid_ptr(i); + + if ((pid_ptr->flag != 1) || (pid_ptr->type != RADIUS_PID_TYPE_REQ)) + { + continue; + } + if (pid_ptr->identifier != identifier) + { + continue; + } + if (pid_ptr->sd_msg_type != corresponsd_msg) + { + radius_log_warn("%s: sd_msg_type = %s, type = %s\r\n", __FUNCTION__, \ + radius_get_msg_str(pid_ptr->sd_msg_type), radius_get_msg_str(corresponsd_msg)); + continue; + } + if (radius_match_response_authenticator_with_request(pid_ptr->authenticator, authenticator, msg, msg_len, share_key) < 0) + { + radius_log_warn("%s: match authenticator err!\r\n", __FUNCTION__); + continue; + } + + //(pid_ptr->trans_req_msg_type != corresponsd_msg) + /*if ((pid_ptr->identifier != identifier) || (pid_ptr->sd_msg_type != corresponsd_msg) || \ + (radius_match_response_authenticator_with_request(pid_ptr->authenticator, authenticator, msg, msg_len, share_key) < 0)) + { + continue; + }*/ + + return i; + } + + return -1; +} + +int radius_parse_attr_user_name(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_USER_NAME *user_name; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_warn("%s: msg type=%s user name length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return 0; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + user_name = &msg_pdu->msg.access_request.user_name; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + user_name = &msg_pdu->msg.access_accept.user_name; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + user_name = &msg_pdu->msg.accounting_request.user_name; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + user_name = &msg_pdu->msg.disconnect_request.user_name; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with user name\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(user_name->user_name.value, flw_ptr, length); + + user_name->user_name.type = RADIUS_ATTRIBUTE_TYPE_USER_NAME; + + user_name->user_name.length = length; + + user_name->flag = 1; + + return 0; +} + +int radius_parse_attr_user_password(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_USER_PASSWORD *user_password; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s user password length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + user_password = &msg_pdu->msg.access_request.user_password; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with user password\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(user_password->user_password.value, flw_ptr, length); + + user_password->user_password.type = RADIUS_ATTRIBUTE_TYPE_USER_PASSWORD; + + user_password->user_password.length = length; + + user_password->flag = 1; + + return 0; +} + +int radius_parse_attr_chap_password(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_CHAP_PASSWORD *chap_password; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s chap password length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + chap_password = &msg_pdu->msg.access_request.chap_password; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with chap password\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(chap_password->chap_password.value, flw_ptr, length); + + chap_password->chap_password.type = RADIUS_ATTRIBUTE_TYPE_CHAP_PASSWORD; + + chap_password->chap_password.length = length; + + chap_password->flag = 1; + + return 0; +} + +int radius_parse_attr_nas_ip_addr(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_NAS_IP_ADDRESS *nas_ip_addr; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s nas ip addr length=%d", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + nas_ip_addr = &msg_pdu->msg.access_request.nas_ip_addr; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + nas_ip_addr = &msg_pdu->msg.accounting_request.nas_ip_addr; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + nas_ip_addr = &msg_pdu->msg.disconnect_request.nas_ip_addr; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with nas ip addr\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + nas_ip_addr->nas_ip_addr.value = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + nas_ip_addr->nas_ip_addr.type = RADIUS_ATTRIBUTE_TYPE_NAS_IP_ADDRESS; + + nas_ip_addr->nas_ip_addr.length = length; + + nas_ip_addr->flag = 1; + + return 0; +} + +int radius_parse_attr_nas_port(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_NAS_PORT *nas_port; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s nas port length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + nas_port = &msg_pdu->msg.access_request.nas_port; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + nas_port = &msg_pdu->msg.accounting_request.nas_port; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + nas_port = &msg_pdu->msg.disconnect_request.nas_port; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with nas port\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + nas_port->nas_port.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + nas_port->nas_port.type = RADIUS_ATTRIBUTE_TYPE_NAS_PORT; + + nas_port->nas_port.length = length; + + nas_port->flag = 1; + + return 0; +} + +int radius_parse_attr_service_type(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_SERVICE_TYPE *service_type; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s service type length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + service_type = &msg_pdu->msg.access_request.service_type; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + service_type = &msg_pdu->msg.access_accept.service_type; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + service_type = &msg_pdu->msg.accounting_request.service_type; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + service_type = &msg_pdu->msg.disconnect_request.service_type; + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + service_type = &msg_pdu->msg.disconnect_nak.service_type; + break; + default: + radius_log_warn("%s: msg type=%s recv msg withc service type\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + service_type->service_type.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + service_type->service_type.type = RADIUS_ATTRIBUTE_TYPE_SERVICE_TYPE; + + service_type->service_type.length = length; + + service_type->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_protocol(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_PROTOCOL *framed_protocol; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed protocol length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + framed_protocol = &msg_pdu->msg.access_request.framed_protocol; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_protocol = &msg_pdu->msg.access_accept.framed_protocol; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_protocol = &msg_pdu->msg.accounting_request.framed_protocol; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed protocol\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_protocol->framed_protocol.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + framed_protocol->framed_protocol.type =RADIUS_ATTRIBUTE_TYPE_FRAMED_PROTOCOL; + + framed_protocol->framed_protocol.length = length; + + framed_protocol->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_ip_addr(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_IP_ADDR *framed_ip_addr; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed ip addr length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + framed_ip_addr = &msg_pdu->msg.access_request.framed_ip_addr; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_ip_addr = &msg_pdu->msg.access_accept.framed_ip_addr; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_ip_addr = &msg_pdu->msg.accounting_request.framed_ip_addr; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + framed_ip_addr = &msg_pdu->msg.disconnect_request.framed_ip_addr; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed ip addr\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_ip_addr->framed_ip_addr.value = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + framed_ip_addr->framed_ip_addr.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_ADDR; + + framed_ip_addr->framed_ip_addr.length = length; + + framed_ip_addr->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_ip_netmask(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_IP_NETMASK *framed_ip_netmask; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed ip netmask length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + framed_ip_netmask = &msg_pdu->msg.access_request.framed_ip_netmask; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_ip_netmask = &msg_pdu->msg.access_accept.framed_ip_netmask; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_ip_netmask = &msg_pdu->msg.accounting_request.framed_ip_netmask; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed ip netmask\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_ip_netmask->framed_ip_netmask.value = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + framed_ip_netmask->framed_ip_netmask.length = length; + + framed_ip_netmask->framed_ip_netmask.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_NETMASK; + + framed_ip_netmask->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_routing(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_ROUTING *framed_routing; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed routing length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_routing = &msg_pdu->msg.access_accept.framed_routing; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_routing = &msg_pdu->msg.accounting_request.framed_routing; + default: + radius_log_warn("%s: msg type=%s recv msg with framed routing\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_routing->framed_routing.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + framed_routing->framed_routing.length = length; + + framed_routing->framed_routing.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTING; + + framed_routing->flag = 1; + + return 0; +} + +int radius_parse_attr_filter_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_FILTER_ID *filter_id; + RADIUS_ATTRIBUTE_FILTER_ID *filter_id_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s:msg type=%s filter id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + filter_id = &msg_pdu->msg.access_accept.filter_id; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + filter_id = &msg_pdu->msg.accounting_request.filter_id; + default: + radius_log_warn("%s: msg type=%s recv msg with filter id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = filter_id->num) >= RADIUS_MAX_NUM_OF_FILTER_ID) + { + radius_log_warn("%s: recv msg type=%s, no resource for filter id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + filter_id_attr = &filter_id->filter_id[num]; + + memcpy(filter_id_attr->filter_id.value, flw_ptr, length); + + filter_id_attr->filter_id.length = length; + + filter_id_attr->filter_id.type = RADIUS_ATTRIBUTE_TYPE_FILTER_ID; + + filter_id_attr->flag = 1; + + filter_id->num++; + + return 0; +} + +int radius_parse_attr_framed_mtu(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_MTU *framed_mtu; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed mtu length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + framed_mtu = &msg_pdu->msg.access_request.framed_mtu; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_mtu = &msg_pdu->msg.access_accept.framed_mtu; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_mtu = &msg_pdu->msg.accounting_request.framed_mtu; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed mtu\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_mtu->framed_mtu.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + framed_mtu->framed_mtu.length = length; + + framed_mtu->framed_mtu.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_MTU; + + framed_mtu->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_compression(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_FRAMED_COMPRESSION *framed_compression; + RADIUS_ATTRIBUTE_FRAMED_COMPRESSION *framed_compression_attr; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed compression length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + framed_compression = &msg_pdu->msg.access_request.framed_compression; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_compression = &msg_pdu->msg.access_accept.framed_compression; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_compression = &msg_pdu->msg.accounting_request.framed_compression; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed compression\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = framed_compression->num) >= RADIUS_MAX_NUM_OF_FRAMED_COMPRESSION) + { + radius_log_warn("%s: recv msg type=%s, no resource for framed compression\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_compression_attr = &framed_compression->framed_compression[num]; + + framed_compression_attr->framed_compression.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + framed_compression_attr->framed_compression.length = length; + + framed_compression_attr->framed_compression.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_COMPRESSION; + + framed_compression_attr->flag = 1; + + framed_compression->num++; + + return 0; +} + +int radius_parse_attr_login_ip_host(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_LOGIN_IP_HOST *login_ip_host; + RADIUS_ATTRIBUTE_LOGIN_IP_HOST *login_ip_host_attr; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s login ip host length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + login_ip_host = &msg_pdu->msg.access_request.login_ip_host; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + login_ip_host = &msg_pdu->msg.access_accept.login_ip_host; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + login_ip_host = &msg_pdu->msg.accounting_request.login_ip_host; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with login ip host\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = login_ip_host->num) >= RADIUS_MAX_NUM_OF_LOGIN_IP_HOST) + { + radius_log_warn("%s: recv msg type=%s, no resource for login ip host\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + login_ip_host_attr = &login_ip_host->login_ip_host[num]; + + login_ip_host_attr->login_ip_host.value = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + login_ip_host_attr->login_ip_host.length = length; + + login_ip_host_attr->login_ip_host.type = RADIUS_ATTRIBUTE_TYPE_LOGIN_IP_HOST; + + login_ip_host_attr->flag = 1; + + login_ip_host->num++; + + return 0; +} + +int radius_parse_attr_login_service(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_LOGIN_SERVICE *login_service; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s login service length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + login_service = &msg_pdu->msg.access_accept.login_service; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + login_service = &msg_pdu->msg.accounting_request.login_service; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with login service\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + login_service->login_service.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + login_service->login_service.length = length; + + login_service->login_service.type = RADIUS_ATTRIBUTE_TYPE_LOGIN_SERVICE; + + login_service->flag = 1; + + return 0; +} + +int radius_parse_attr_login_tcp_port(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_LOGIN_TCP_PORT *login_tcp_port; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s login tcp port length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + login_tcp_port = &msg_pdu->msg.access_accept.login_tcp_port; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + login_tcp_port = &msg_pdu->msg.accounting_request.login_tcp_port; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with login tcp port\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + login_tcp_port->login_tcp_port.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + login_tcp_port->login_tcp_port.length = length; + + login_tcp_port->login_tcp_port.type = RADIUS_ATTRIBUTE_TYPE_LOGIN_TCP_PORT; + + login_tcp_port->flag = 1; + + return 0; +} + +int radius_parse_attr_reply_message(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_REPLY_MESSAGE *reply_message; + RADIUS_ATTRIBUTE_REPLY_MESSAGE *reply_message_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s reply message length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + reply_message = &msg_pdu->msg.access_accept.reply_message; + break; + case RADIUS_MSG_TYPE_ACCESS_REJECT: + reply_message = &msg_pdu->msg.access_reject.reply_message; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + reply_message = &msg_pdu->msg.access_challenge.reply_message; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + reply_message = &msg_pdu->msg.disconnect_request.reply_message; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with reply message\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = reply_message->num) >= RADIUS_MAX_NUM_OF_REPLY_MESSAGE) + { + radius_log_warn("%s: recv msg type=%s, no resource for reply message\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + reply_message_attr = &reply_message->reply_message[num]; + + memcpy(reply_message_attr->reply_message.value, flw_ptr, length); + + reply_message_attr->reply_message.length = length; + + reply_message_attr->reply_message.type = RADIUS_ATTRIBUTE_TYPE_REPLY_MESSAGE; + + reply_message_attr->flag = 1; + + reply_message->num++; + + return 0; +} + +int radius_parse_attr_callback_number(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_CALLBACK_NUMBER *callback_num; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s callback number length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + callback_num = &msg_pdu->msg.access_request.callback_number; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + callback_num = &msg_pdu->msg.access_accept.callback_number; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + callback_num = &msg_pdu->msg.accounting_request.callback_number; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with callback num\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(callback_num->callback_number.value, flw_ptr, length); + + callback_num->callback_number.length = length; + + callback_num->callback_number.type = RADIUS_ATTRIBUTE_TYPE_CALLBACK_NUMBER; + + callback_num->flag = 1; + + return 0; +} + +int radius_parse_attr_callback_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_CALLBACK_ID *callback_id; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s callback id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + callback_id = &msg_pdu->msg.access_accept.callback_id; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + callback_id = &msg_pdu->msg.accounting_request.callback_id; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with callback id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(callback_id->callback_id.value, flw_ptr, length); + + callback_id->callback_id.length = length; + + callback_id->callback_id.type = RADIUS_ATTRIBUTE_TYPE_CALLBACK_ID; + + callback_id->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_route(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_FRAMED_ROUTE *framed_route; + RADIUS_ATTRIBUTE_FRAMED_ROUTE *framed_route_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s framed route length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_route = &msg_pdu->msg.access_accept.framed_route; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_route = &msg_pdu->msg.accounting_request.framed_route; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed route\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = framed_route->num) >= RADIUS_MAX_NUM_OF_FRAMED_ROUTE) + { + radius_log_warn("%s: recv msg type=%s, no resource for framed route\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_route_attr = &framed_route->framed_route[num]; + + memcpy(framed_route_attr->framed_route.value, flw_ptr, length); + + framed_route_attr->framed_route.length = length; + + framed_route_attr->framed_route.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTE; + + framed_route_attr->flag = 1; + + framed_route->num++; + + return 0; +} + +int radius_parse_attr_framed_ipx_network(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_IPX_NETWORK *framed_ipx_network; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed ipx network length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_ipx_network = &msg_pdu->msg.access_accept.framed_ipx_network; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_ipx_network = &msg_pdu->msg.accounting_request.framed_ipx_network; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed ipx network\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_ipx_network->framed_ipx_network.value = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + framed_ipx_network->framed_ipx_network.length = length; + + framed_ipx_network->framed_ipx_network.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_IPX_NETWORK; + + framed_ipx_network->flag = 1; + + return 0; +} + +int radius_parse_attr_state(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_STATE *state; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s state length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + state = &msg_pdu->msg.access_request.state; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + state = &msg_pdu->msg.access_accept.state; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + state = &msg_pdu->msg.access_challenge.state; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + state = &msg_pdu->msg.disconnect_request.state; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + state = &msg_pdu->msg.disconnect_ack.state; + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + state = &msg_pdu->msg.disconnect_nak.state; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with state\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(state->state.value, flw_ptr, length); + + state->state.length = length; + + state->state.type = RADIUS_ATTRIBUTE_TYPE_STATE; + + state->flag = 1; + + return 0; +} + +int radius_parse_attr_class(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_CLASS *radius_class; + RADIUS_ATTRIBUTE_CLASS *radius_class_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s class length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + radius_class = &msg_pdu->msg.access_accept.radius_class; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + radius_class = &msg_pdu->msg.accounting_request.radius_class; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + radius_class = &msg_pdu->msg.disconnect_request.radius_class; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with class\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = radius_class->num) >= RADIUS_MAX_NUM_OF_CLASS) + { + radius_log_warn("%s: recv msg type=%s, no resource for class\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + radius_class_attr = &radius_class->radius_class[num]; + + memcpy(radius_class_attr->radius_class.value, flw_ptr, length); + + radius_class_attr->radius_class.length = length; + + radius_class_attr->radius_class.type = RADIUS_ATTRIBUTE_TYPE_CLASS; + + radius_class_attr->flag = 1; + + radius_class->num++; + + return 0; +} + +int radius_parse_vendor_ppac_sub_attr_aic(RADIUS_VENDOR_PPAC_SUB_ATTR_AIC *aic, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: aic length=%d\r\n", __FUNCTION__, length); + return -1; + } + + aic->aic = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + aic->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppac_sub_attr(RADIUS_VENDOR_ATTRIBUTE_PPAC *ppac, const BYTE *flw_ptr, BYTE length) +{ + BYTE subtype; + BYTE continuation; + + continuation = flw_ptr[0]; + + subtype = flw_ptr[1]; + + if ((continuation & 0x80) != 0) + { + radius_log_warn("%s: ppac continuation=%x\r\n", __FUNCTION__, continuation); + } + + switch (subtype) + { + case RADIUS_PPAC_SUBTYPE_AIC: + if (radius_parse_vendor_ppac_sub_attr_aic(&ppac->aic, flw_ptr + 3, flw_ptr[2] - 2) < 0) + { + radius_log_err("%s: ppac sub attribute aic parse fail\r\n", __FUNCTION__); + return -1; + } + break; + default: + radius_log_warn("%s: ppac unknow subtype=%d\r\n", __FUNCTION__, subtype); + return 0; + } + + ppac->continuation = continuation & 0x7F; + + return 0; +} + +int radius_parse_vendor_stc_sub_attr(RADIUS_VENDOR_ATTRIBUTE_STC *stc, const BYTE *flw_ptr, BYTE length) +{ + BYTE continuation; + + if (length != 5) + { + radius_log_err("%s: stc length=%d\r\n", __FUNCTION__, length); + return -1; + } + + continuation = flw_ptr[0]; + + if ((continuation & 0x80) != 0) + { + radius_log_warn("%s: stc continuation=%x\r\n", __FUNCTION__, continuation); + } + + stc->stc = flw_ptr[1] << 24 | flw_ptr[2] << 16 | flw_ptr[3] << 8 | flw_ptr[4]; + + stc->continuation = continuation & 0x7F; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_qid(RADIUS_VENDOR_PPAQ_SUB_ATTR_QID *qid, const BYTE *flw_ptr, BYTE length) +{ + if (length > RADIUS_TS_VALUE_LEN) + { + radius_log_err("%s: qid length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(qid->qid.value, flw_ptr, length); + + qid->qid.length = length; + + qid->qid.type = RADIUS_PPAQ_SUBTYPE_QID; + + qid->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_vq(RADIUS_VENDOR_PPAQ_SUB_ATTR_VQ *vq, const BYTE *flw_ptr, BYTE length) +{ + long long i = 0; + + if ((length != 8) && (length != 12)) + { + radius_log_err("%s: volume quota length=%d\r\n", __FUNCTION__, length); + return -1; + } + + i = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + vq->vq.integer = i << 32 | flw_ptr[4] << 24 | flw_ptr[5] << 16 | flw_ptr[6] << 8 | flw_ptr[7]; + + vq->vq.exponent = 0; + + if (length == 12) + { + vq->vq.exponent = flw_ptr[8] << 24 | flw_ptr[9] << 16 | flw_ptr[10] << 8 | flw_ptr[11]; + } + + vq->vq.type = RADIUS_PPAQ_SUBTYPE_VQ; + + vq->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_vt(RADIUS_VENDOR_PPAQ_SUB_ATTR_VT *vt, const BYTE *flw_ptr, BYTE length) +{ + long long i = 0; + + if ((length != 8) && (length != 12)) + { + radius_log_err("%s: volume threshold length=%d\r\n", __FUNCTION__, length); + return -1; + } + + i = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + vt->vt.integer = i << 32 | flw_ptr[4] << 24 | flw_ptr[5] << 16 | flw_ptr[6] << 8 | flw_ptr[7]; + + vt->vt.exponent= 0; + + if (length == 12) + { + vt->vt.exponent = flw_ptr[8] << 24 | flw_ptr[9] << 16 | flw_ptr[10] << 8 | flw_ptr[11]; + } + + vt->vt.type = RADIUS_PPAQ_SUBTYPE_VT; + + vt->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_dq(RADIUS_VENDOR_PPAQ_SUB_ATTR_DQ *dq, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: duration quato length=%d\r\n", __FUNCTION__, length); + return -1; + } + + dq->dq.length = length; + + dq->dq.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + dq->dq.type = RADIUS_PPAQ_SUBTYPE_DQ; + + dq->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_dt(RADIUS_VENDOR_PPAQ_SUB_ATTR_DT *dt, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: duration threshold length=%d\r\n", __FUNCTION__, length); + return -1; + } + + dt->dt.length = length; + + dt->dt.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + dt->dt.type = RADIUS_PPAQ_SUBTYPE_DT; + + dt->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_rq(RADIUS_VENDOR_PPAQ_SUB_ATTR_RQ *rq, const BYTE *flw_ptr, BYTE length) +{ + long long i = 0; + + if ((length != 8) && (length != 12)) + { + radius_log_err("%s: resource quota length=%d\r\n", __FUNCTION__, length); + return -1; + } + + i = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + rq->rq.integer = i << 32 | flw_ptr[4] << 24 | flw_ptr[5] << 16 | flw_ptr[6] << 8 | flw_ptr[7]; + + rq->rq.exponent = 0; + + if (length == 12) + { + rq->rq.exponent = flw_ptr[8] << 24 | flw_ptr[9] << 16 | flw_ptr[10] << 8 | flw_ptr[11]; + } + + rq->rq.type = RADIUS_PPAQ_SUBTYPE_RQ; + + rq->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_rt(RADIUS_VENDOR_PPAQ_SUB_ATTR_RT *rt, const BYTE *flw_ptr, BYTE length) +{ + long long i = 0; + + if ((length != 8) && (length != 12)) + { + radius_log_err("%s: resource threshold length=%d\r\n", __FUNCTION__, length); + return -1; + } + + i = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + rt->rt.integer = i << 32 | flw_ptr[4] << 24 | flw_ptr[5] << 16 | flw_ptr[6] << 8 | flw_ptr[7]; + + rt->rt.exponent= 0; + + if (length == 12) + { + rt->rt.exponent = flw_ptr[8] << 24 | flw_ptr[9] << 16 | flw_ptr[10] << 8 | flw_ptr[11]; + } + + rt->rt.type = RADIUS_PPAQ_SUBTYPE_RQ; + + rt->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_ur(RADIUS_VENDOR_PPAQ_SUB_ATTR_UR *ur, const BYTE *flw_ptr, BYTE length) +{ + if (length != 1) + { + radius_log_err("%s: update reason length=%d\r\n", __FUNCTION__, length); + return -1; + } + + ur->ur.value = flw_ptr[0]; + + ur->ur.length = length; + + ur->ur.type = RADIUS_PPAQ_SUBTYPE_UR; + + ur->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_ps(RADIUS_VENDOR_PPAQ_SUB_ATTR_PS *ps, const BYTE *flw_ptr, BYTE length) +{ + if ((length != 4) && (length != 16)) + { + radius_log_err("%s: prepaid server addr length=%d\r\n", __FUNCTION__, length); + return -1; + } + + if (length == 4) + { + ps->ps.value = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + } + else + { + radius_log_warn("%s: prepaid server addr is ipv6 not support\r\n", __FUNCTION__); + return 0; + } + + ps->ps.length = length; + + ps->ps.type = RADIUS_PPAQ_SUBTYPE_PS; + + ps->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_sid(RADIUS_VENDOR_PPAQ_SUB_ATTR_SID *sid, const BYTE *flw_ptr, BYTE length) +{ + if (length> RADIUS_TS_VALUE_LEN) + { + radius_log_err("%s: service id length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(sid->sid.value, flw_ptr, length); + + sid->sid.length = length; + + sid->sid.type = RADIUS_PPAQ_SUBTYPE_SID; + + sid->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_rgid(RADIUS_VENDOR_PPAQ_SUB_ATTR_RGID *rgid, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: rating group id length=%d\r\n", __FUNCTION__, length); + return -1; + } + + rgid->rgid.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + rgid->rgid.length = length; + + rgid->rgid.type = RADIUS_PPAQ_SUBTYPE_RGID; + + rgid->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_ta(RADIUS_VENDOR_PPAQ_SUB_ATTR_TA *ta, const BYTE *flw_ptr, BYTE length) +{ + if (length != 1) + { + radius_log_err("%s: termination action length=%d\r\n", __FUNCTION__, length); + return -1; + } + + ta->ta.value = flw_ptr[0]; + + ta->ta.length = length; + + ta->ta.type = RADIUS_PPAQ_SUBTYPE_TA; + + ta->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_plid(RADIUS_VENDOR_PPAQ_SUB_ATTR_PLID *plid, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: pool id length=%d\r\n", __FUNCTION__, length); + return -1; + } + + plid->plid.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + plid->plid.length = length; + + plid->plid.type = RADIUS_PPAQ_SUBTYPE_PLID; + + plid->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_pm(RADIUS_VENDOR_PPAQ_SUB_ATTR_PM *pm, const BYTE *flw_ptr, BYTE length) +{ + long long i = 0; + + if ((length != 8) && (length != 12)) + { + radius_log_err("%s: pool multiplier length=%d\r\n", __FUNCTION__, length); + return -1; + } + + i = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + pm->pm.integer = i << 32 | flw_ptr[4] << 24 | flw_ptr[5] << 16 | flw_ptr[6] << 8 | flw_ptr[7]; + + pm->pm.exponent = 0; + + if (length == 12) + { + pm->pm.exponent = flw_ptr[8] << 24 | flw_ptr[9] << 16 | flw_ptr[10] << 8 | flw_ptr[11]; + } + + pm->pm.type = RADIUS_PPAQ_SUBTYPE_PM; + + pm->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_ra(RADIUS_VENDOR_PPAQ_SUB_ATTR_RA *ra, const BYTE *flw_ptr, BYTE length) +{ + if (length != 1) + { + radius_log_err("%s: requested action length=%d\r\n", __FUNCTION__, length); + return -1; + } + + ra->ra.value = flw_ptr[0]; + + ra->ra.length = length; + + ra->ra.type = RADIUS_PPAQ_SUBTYPE_RA; + + ra->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_cbr(RADIUS_VENDOR_PPAQ_SUB_ATTR_CBR *cbr, const BYTE *flw_ptr, BYTE length) +{ + if (length != 1) + { + radius_log_err("%s: check balance result length=%d\r\n", __FUNCTION__, length); + return -1; + } + + cbr->cbr.value = flw_ptr[0]; + + cbr->cbr.length = length; + + cbr->cbr.type = RADIUS_PPAQ_SUBTYPE_CBR; + + cbr->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr_ci(RADIUS_VENDOR_PPAQ_SUB_ATTR_CI *ci, const BYTE *flw_ptr, BYTE length) +{ + long long i = 0; + + if (length < 17)// value-digits 8 bytes exponent 4 bytes currency-code 4 bytes cost unit >= 1 byte + { + radius_log_err("%s: cost information length=%d\r\n", __FUNCTION__, length); + return -1; + } + + i = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + ci->integer = i << 32 | flw_ptr[4] << 24 | flw_ptr[5] << 16 | flw_ptr[6] << 8 | flw_ptr[7]; + + ci->exponent = flw_ptr[8] << 24 | flw_ptr[9] << 16 | flw_ptr[10] << 8 | flw_ptr[11]; + + ci->currency_code = flw_ptr[12] << 24 | flw_ptr[13] << 16 | flw_ptr[14] << 8 | flw_ptr[15]; + + memcpy(ci->cost_unit, flw_ptr + 16, length - 16); + + ci->type = RADIUS_PPAQ_SUBTYPE_CI; + + ci->flag = 1; + + return 0; +} + +int radius_parse_vendor_ppaq_sub_attr(RADIUS_VENDOR_ATTRIBUTE_PPAQ *ppaq, const BYTE *flw_ptr, BYTE length) +{ + BYTE *tmp_ptr = (BYTE *)flw_ptr + 1; + + for (;;) + { + if ((tmp_ptr - flw_ptr) >= length) + break; + + switch (tmp_ptr[0]) + { + case RADIUS_PPAQ_SUBTYPE_QID: + if (radius_parse_vendor_ppaq_sub_attr_qid(&ppaq->qid, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute qid parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_VQ: + if (radius_parse_vendor_ppaq_sub_attr_vq(&ppaq->vq, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute volume quota parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_VT: + if (radius_parse_vendor_ppaq_sub_attr_vt(&ppaq->vt, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute volume threshold parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_DQ: + if (radius_parse_vendor_ppaq_sub_attr_dq(&ppaq->dq, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute duration quota parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_DT: + if (radius_parse_vendor_ppaq_sub_attr_dt(&ppaq->dt, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute duration threshold parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_RQ: + if (radius_parse_vendor_ppaq_sub_attr_rq(&ppaq->rq, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute resource quota parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_RT: + if (radius_parse_vendor_ppaq_sub_attr_rt(&ppaq->rt, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute resource threshold parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_UR: + if (radius_parse_vendor_ppaq_sub_attr_ur(&ppaq->ur, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute update reason parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_PS: + if (radius_parse_vendor_ppaq_sub_attr_ps(&ppaq->ps, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute prepaid server parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_SID: + if (radius_parse_vendor_ppaq_sub_attr_sid(&ppaq->sid, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute service id parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_RGID: + if (radius_parse_vendor_ppaq_sub_attr_rgid(&ppaq->rgid, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute rating group id parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_TA: + if (radius_parse_vendor_ppaq_sub_attr_ta(&ppaq->ta, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute terminate action parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_PLID: + if (radius_parse_vendor_ppaq_sub_attr_plid(&ppaq->plid, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute pool id parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_PM: + if (radius_parse_vendor_ppaq_sub_attr_pm(&ppaq->pm, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute pool multiplier parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_RA: + if (radius_parse_vendor_ppaq_sub_attr_ra(&ppaq->ra, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute requested action parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_CBR: + if (radius_parse_vendor_ppaq_sub_attr_cbr(&ppaq->cbr, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute check balance result parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_PPAQ_SUBTYPE_CI: + if (radius_parse_vendor_ppaq_sub_attr_ci(&ppaq->ci, tmp_ptr + 2, tmp_ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute cost infromation parse fail\r\n", __FUNCTION__); + return -1; + } + break; + default: + radius_log_warn("%s: ppaq unknow subtype=%d\r\n", __FUNCTION__, tmp_ptr[0]); + break;; + } + + tmp_ptr += tmp_ptr[1]; + } + + ppaq->continuation = flw_ptr[0]; + + return 0; +} + +int radius_parse_vendor_pts_sub_attr_vuats(RADIUS_VENDOR_PTS_SUB_ATTR_VUATS * vuats, const BYTE * flw_ptr, BYTE length) +{ + long long i = 0; + + if ((length != 8) && (length != 12)) + { + radius_log_err("%s: volume used after tariff switch length=%d\r\n", __FUNCTION__, length); + return -1; + } + + i = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + vuats->vuats.integer = i << 32 | flw_ptr[4] << 24 | flw_ptr[5] << 16 | flw_ptr[6] << 8 | flw_ptr[7]; + + vuats->vuats.exponent = 0; + + if (length == 12) + { + vuats->vuats.exponent = flw_ptr[8] << 24 | flw_ptr[9] << 16 | flw_ptr[10] << 8 | flw_ptr[11]; + } + + vuats->vuats.type = RADIUS_PTS_SUBTYPE_VUATS; + + vuats->flag = 1; + + return 0; +} + +int radius_parse_vendor_pts_sub_attr_tsi(RADIUS_VENDOR_PTS_SUB_ATTR_TSI * tsi, const BYTE * flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: tariff switch interval length=%d\r\n", __FUNCTION__, length); + return -1; + } + + tsi->tsi.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + tsi->tsi.length = length; + + tsi->tsi.type = RADIUS_PTS_SUBTYPE_TSI; + + tsi->flag = 1; + + return 0; +} + +int radius_parse_vendor_pts_sub_attr_titsu(RADIUS_VENDOR_PTS_SUB_ATTR_TITSU * titsu, const BYTE * flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: time interval after tariff switch updatel length=%d\r\n", __FUNCTION__, length); + return -1; + } + + titsu->titsu.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + titsu->titsu.length = length; + + titsu->titsu.type = RADIUS_PTS_SUBTYPE_TSI; + + titsu->flag = 1; + + return 0; +} + +int radius_parse_vendor_pts_sub_attr(RADIUS_VENDOR_ATTRIBUTE_PTS *pts, const BYTE *flw_ptr, BYTE length) +{ + BYTE *ptr = (BYTE *)flw_ptr + 1; + + for (;;) + { + if ((ptr - flw_ptr) >= length) + break; + + switch (ptr[0]) + { + case RADIUS_PTS_SUBTYPE_VUATS: + if (radius_parse_vendor_pts_sub_attr_vuats(&pts->vuats, ptr + 2, ptr[1] -2) < 0) + return -1; + break; + case RADIUS_PTS_SUBTYPE_TSI: + if (radius_parse_vendor_pts_sub_attr_tsi(&pts->tsi, ptr + 2, ptr[1] - 2) < 0) + return -1; + break; + case RADIUS_PTS_SUBTYPE_TITSU: + if (radius_parse_vendor_pts_sub_attr_titsu(&pts->titsu, ptr + 2, ptr[1] - 2) < 0) + return -1; + break; + default: + radius_log_warn("%s: pst unknow subtype=%d\r\n", __FUNCTION__, ptr[0]); + break; + } + + ptr += ptr[1]; + } + + pts->continuation = flw_ptr[0]; + + return 0; +} + +int radius_parse_vendor_3gpp_imsi(RADIUS_VENDOR_ATTRIBUTE_3GPP_IMSI *imsi, const BYTE *flw_ptr, BYTE length) +{ + if ((length < 3) || (length >= RADIUS_MAX_LEN_OF_IMSI)) + { + radius_log_err("%s: imsi length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(imsi->imsi, flw_ptr, length); + + return 0; +} + +int radius_parse_vendor_3gpp_charging_id(RADIUS_VENDOR_ATTRIBUTE_3GPP_CID *charging_id, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: charging id length=%d\r\n", __FUNCTION__, length); + return -1; + } + + charging_id->cid = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + return 0; +} + +int radius_parse_vendor_3gpp_pdp_type(RADIUS_VENDOR_ATTRIBUTE_3GPP_PDP_TYPE *pdp_type, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: pdp type length=%d\r\n", __FUNCTION__, length); + return -1; + } + + pdp_type->pdp_type = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 |flw_ptr[3]; + + return 0; +} + +int radius_parse_vendor_3gpp_cg_addr(RADIUS_VENDOR_ATTRIBUTE_3GPP_CG_ADDR *cg_addr, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: cg addr length=%d\r\n", __FUNCTION__, length); + return -1; + } + + cg_addr->cg_addr = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + return 0; +} + +int radius_parse_vendor_3gpp_nqp(RADIUS_VENDOR_ATTRIBUTE_3GPP_NQP *nqp, const BYTE *flw_ptr, BYTE length) +{ + if (length > RADIUS_TS_VALUE_LEN) + { + radius_log_err("%s: negatiated qos profile length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(nqp->nqp, flw_ptr, length); + + return 0; +} + +int radius_parse_vendor_3gpp_sgsn_addr(RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR *sgsn_addr, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: sgsn addr length=%d\r\n", __FUNCTION__, length); + return -1; + } + + sgsn_addr->sgsn_addr = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + return 0; +} + +int radius_parse_vendor_3gpp_ggsn_addr(RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_ADDR *ggsn_addr, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: ggsn addr length=%d\r\n", __FUNCTION__, length); + return -1; + } + + ggsn_addr->ggsn_addr = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + + return 0; +} + +int radius_parse_vendor_3gpp_imsi_mcc_mnc(RADIUS_VENDOR_ATTRIBUTE_3GPP_MCC_MNC *mcc_mnc, const BYTE *flw_ptr, BYTE length) +{ + if ((length < 5) || (length > 6)) + { + radius_log_err("%s: imsi mcc mnc length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(mcc_mnc->mcc, flw_ptr, 3); + + memcpy(mcc_mnc->mnc, flw_ptr + 3, length - 3); + + return 0; +} + +int radius_parse_vendor_3gpp_ggsn_mcc_mnc(RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_MCC_MNC *ggsn_mcc_mnc, const BYTE *flw_ptr, BYTE length) +{ + if ((length < 5) || (length > 6)) + { + radius_log_err("%s: ggsn mcc mnc length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(ggsn_mcc_mnc->mcc, flw_ptr, 3); + + memcpy(ggsn_mcc_mnc->mnc, flw_ptr + 3, length - 3); + + return 0; +} + +int radius_parse_vendor_3gpp_nsapi(RADIUS_VENDOR_ATTRIBUTE_3GPP_NSAPI *nsapi, const BYTE *flw_ptr, BYTE length) +{ + char tmp[RADIUS_MAX_LEN_OF_TEMP_BUF] = ""; + + if (length != 1) + { + radius_log_err("%s: nsapi length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(tmp, flw_ptr, 1); + + nsapi->nsapi = strtol(tmp, NULL, 16); + + return 0; +} + +int radius_parse_vendor_3gpp_ssi(RADIUS_VENDOR_ATTRIBUTE_3GPP_SSI *ssi, const BYTE *flw_ptr, BYTE length) +{ + if ((length != 1) || (flw_ptr[0] != 0xFF)) + { + radius_log_err("%s: ssi length=%d, ssi=0x%X\r\n", __FUNCTION__, length, flw_ptr[0]); + return -1; + } + + ssi->ssi = flw_ptr[0]; + + return 0; +} + +int radius_parse_vendor_3gpp_sm(RADIUS_VENDOR_ATTRIBUTE_3GPP_SM *sm, const BYTE *flw_ptr, BYTE length) +{ + char tmp[RADIUS_MAX_LEN_OF_TEMP_BUF] = ""; + + if (length != 1) + { + radius_log_err("%s: selection mode length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(tmp, flw_ptr, 1); + + sm->sm = strtol(tmp, NULL, 16); + + return 0; +} + +int radius_parse_vendor_3gpp_cc(RADIUS_VENDOR_ATTRIBUTE_3GPP_CC *cc, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: cc length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(cc->cc, flw_ptr, length); + + return 0; +} + +int radius_parse_vendor_3gpp_sgsn_mcc_mnc(RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_MCC_MNC *sgsn_mcc_mnc, const BYTE *flw_ptr, BYTE length) +{ + if ((length < 5) || (length > 6)) + { + radius_log_err("%s: sgsn mcc mnc length=%d\r\n", __FUNCTION__, length); + return -1; + } + + memcpy(sgsn_mcc_mnc->mcc, flw_ptr, 3); + + memcpy(sgsn_mcc_mnc->mnc, flw_ptr + 3, length - 3); + + return 0; +} + +int radius_parse_vendor_3gpp2_stc(RADIUS_VENDOR_ATTRIBUTE_3GPP2_STC *stc, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: stc length=%d\r\n", __FUNCTION__, length); + return -1; + } + + stc->stc = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppac_sub_attr_aic(RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_AIC *aic, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: ppac aic length=%d\r\n", __FUNCTION__, length); + return -1; + } + + aic->aic = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + aic->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppac_sub_attr_sfs(RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_SFS *sfs, const BYTE *flw_ptr, BYTE length) +{ + if (length != 4) + { + radius_log_err("%s: ppac sfs length=%d\r\n", __FUNCTION__, length); + return -1; + } + + sfs->sfs = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + sfs->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppac(RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC *ppac, const BYTE *flw_ptr, BYTE length) +{ + BYTE *ptr = (BYTE *)flw_ptr; + + for (;;) + { + if ((ptr - flw_ptr) >= length) + break; + + switch (ptr[0]) + { + case RADIUS_3GPP2_PPAC_SUBTYPE_AIC: + if (radius_parse_vendor_3gpp2_ppac_sub_attr_aic(&ppac->aic, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppac sub attribute aic parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAC_SUBTYPE_SFS: + if (radius_parse_vendor_3gpp2_ppac_sub_attr_sfs(&ppac->sfs, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppac sub attribute sfs parse fail\r\n", __FUNCTION__); + return -1; + } + break; + default: + radius_log_warn("%s: ppac unknow subtype=%d\r\n", __FUNCTION__, ptr[0]); + return 0; + } + + ptr += ptr[1]; + } + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_qid(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_QID *qid, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: qid length=%d\r\n", __FUNCTION__, length); + return -1; + } + + qid->qid.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + qid->qid.length = length; + + qid->qid.type = RADIUS_3GPP2_PPAQ_SUBTYPE_QID; + + qid->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_vq(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQ *vq, const BYTE *flw_ptr, BYTE length) +{ + long long i = 0; +/* if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: vq length=%d\r\n", __FUNCTION__, length); + return -1; + }*///for 3gpp2 + + if ((length != 10) && (length != 16)) + { + radius_log_err("%s: vq length=%d\r\n", __FUNCTION__, length); + return -1; + }//for aricent + + + if (flw_ptr[0] != RADIUS_ARICENT_VOLUME_INT) + { + radius_log_err("%s: vq subtype first=%d\r\n", flw_ptr[0]); + return -1; + } + + i = flw_ptr[2] << 24 | flw_ptr[3] << 16 | flw_ptr[4] << 8 | flw_ptr[5]; + + vq->vq.integer = i << 32 | flw_ptr[6] << 24 | flw_ptr[7] << 16 | flw_ptr[8] << 8 | flw_ptr[9]; + + if (length == 16) + { + if (flw_ptr[10] != RADIUS_ARICENT_VOLUME_EXP) + { + radius_log_err("%s: vq subtype second=%d\r\n", flw_ptr[10]); + return -1; + } + + vq->vq.exponent = flw_ptr[12] << 24 | flw_ptr[13] << 16 | flw_ptr[14] << 8 | flw_ptr[15]; + } + +// vq->vq.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3];//for 3gpp2 + +// vq->vq.length = length; + + vq->vq.type = RADIUS_3GPP2_PPAQ_SUBTYPE_VQ; + + vq->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_vqo(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQO *vqo, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN - 2) + { + radius_log_err("%s: vqo length=%d\r\n", __FUNCTION__, length); + return -1; + } + + vqo->vqo.value = flw_ptr[0] << 8 | flw_ptr[1]; + + vqo->vqo.length = length; + + vqo->vqo.type = RADIUS_3GPP2_PPAQ_SUBTYPE_VQO; + + vqo->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_vt(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VT *vt, const BYTE *flw_ptr, BYTE length) +{ + long long i; +/* if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: vt length=%d\r\n", __FUNCTION__, length); + return -1; + }*/ + + if ((length != 10) && (length != 16)) + { + radius_log_err("%s: vq length=%d\r\n", __FUNCTION__, length); + return -1; + }//for aricent + + + if (flw_ptr[0] != RADIUS_ARICENT_VOLUME_INT) + { + radius_log_err("%s: vt subtype first=%d\r\n", flw_ptr[0]); + return -1; + } + + i = flw_ptr[2] << 24 | flw_ptr[3] << 16 | flw_ptr[4] << 8 | flw_ptr[5]; + + vt->vt.integer = i << 32 | flw_ptr[6] << 24 | flw_ptr[7] << 16 | flw_ptr[8] << 8 | flw_ptr[9]; + + if (length == 16) + { + if (flw_ptr[10] != RADIUS_ARICENT_VOLUME_EXP) + { + radius_log_err("%s: vt subtype second=%d\r\n", flw_ptr[10]); + return -1; + } + + vt->vt.exponent = flw_ptr[12] << 24 | flw_ptr[13] << 16 | flw_ptr[14] << 8 | flw_ptr[15]; + } + +// vt->vt.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + +// vt->vt.length = length; + + vt->vt.type = RADIUS_3GPP2_PPAQ_SUBTYPE_VT; + + vt->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_vto(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VTO *vto, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN - 2) + { + radius_log_err("%s: vqo length=%d\r\n", __FUNCTION__, length); + return -1; + } + + vto->vto.value = flw_ptr[0] << 8 | flw_ptr[1]; + + vto->vto.length = length; + + vto->vto.type = RADIUS_3GPP2_PPAQ_SUBTYPE_VTO; + + vto->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_dq(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DQ *dq, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: dq length=%d\r\n", __FUNCTION__, length); + return -1; + } + + dq->dq.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + dq->dq.length = length; + + dq->dq.type = RADIUS_3GPP2_PPAQ_SUBTYPE_DQ; + + dq->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_dt(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DT *dt, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: dt length=%d\r\n", __FUNCTION__, length); + return -1; + } + + dt->dt.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + dt->dt.length = length; + + dt->dt.type = RADIUS_3GPP2_PPAQ_SUBTYPE_VT; + + dt->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_ur(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_UR *ur, const BYTE *flw_ptr, BYTE length) +{ + if (length != 2) + { + radius_log_err("%s: update reason length=%d\r\n", __FUNCTION__, length); + return -1; + } + + ur->ur.value = flw_ptr[0] << 8 | flw_ptr[1]; + + ur->ur.length = length; + + ur->ur.type = RADIUS_3GPP2_PPAQ_SUBTYPE_UR; + + ur->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq_sub_attr_ps(RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_PS *ps, const BYTE *flw_ptr, BYTE length) +{ + if ((length != 4) && (length != 16)) + { + radius_log_err("%s: prepaid server addr length=%d\r\n", __FUNCTION__, length); + return -1; + } + + if (length == 4) + { + ps->ps.value = flw_ptr[3] << 24 | flw_ptr[2] << 16 | flw_ptr[1] << 8 | flw_ptr[0]; + } + else + { + radius_log_warn("%s: prepaid server addr is ipv6 not support\r\n", __FUNCTION__); + return 0; + } + + ps->ps.length = length; + + ps->ps.type = RADIUS_3GPP2_PPAQ_SUBTYPE_PS; + + ps->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_ppaq(RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq, const BYTE *flw_ptr, BYTE length) +{ + BYTE *ptr = (BYTE *)flw_ptr; + + for (;;) + { + if ((ptr - flw_ptr) >= length) + break; + + switch (ptr[0]) + { + case RADIUS_3GPP2_PPAQ_SUBTYPE_QID: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_qid(&ppaq->qid, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute qid parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_VQ: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_vq(&ppaq->vq, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute volume quota parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_VQO: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_vqo(&ppaq->vqo, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute volume quota overflow parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_VT: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_vt(&ppaq->vt, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute volume threshold parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_VTO: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_vto(&ppaq->vto, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute volume threshold overflow parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_DQ: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_dq(&ppaq->dq, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute duration quota parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_DT: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_dt(&ppaq->dt, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute duration threshold parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_UR: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_ur(&ppaq->ur, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute update reason parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PPAQ_SUBTYPE_PS: + if (radius_parse_vendor_3gpp2_ppaq_sub_attr_ps(&ppaq->ps, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: ppaq sub attribute prepaid server parse fail\r\n", __FUNCTION__); + return -1; + } + break; + default: + radius_log_warn("%s: ppaq unknow subtype=%d\r\n", __FUNCTION__, ptr[0]); + break; + } + + ptr += ptr[1]; + } + + return 0; +} + +int radius_parse_vendor_3gpp2_pts_sub_attr_qid(RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_QID *qid, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: qid length=%d\r\n", __FUNCTION__, length); + return -1; + } + + qid->qid.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + qid->qid.length = length; + + qid->qid.type = RADIUS_3GPP2_PTS_SUBTYPE_QID; + + qid->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_pts_sub_attr_vuats(RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATS *vuats, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: vuats length=%d\r\n", __FUNCTION__, length); + return -1; + } + + vuats->vuats.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + vuats->vuats.length = length; + + vuats->vuats.type = RADIUS_3GPP2_PTS_SUBTYPE_VUATS; + + vuats->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_pts_sub_attr_vuatso(RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_VUATSO *vuatso, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: vuats length=%d\r\n", __FUNCTION__, length); + return -1; + } + + vuatso->vuatso.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + vuatso->vuatso.length = length; + + vuatso->vuatso.type = RADIUS_3GPP2_PTS_SUBTYPE_VUATSO; + + vuatso->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_pts_sub_attr_tsi(RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TSI *tsi, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: tsi length=%d\r\n", __FUNCTION__, length); + return -1; + } + + tsi->tsi.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + tsi->tsi.length = length; + + tsi->tsi.type = RADIUS_3GPP2_PTS_SUBTYPE_TSI; + + tsi->flag = 1; + + return 0; +} + +int radius_parse_vendor_3gpp2_pts_sub_attr_titus(RADIUS_VENDOR_3GPP2_PTS_SUB_ATTR_TITSU *titus, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: titus length=%d\r\n", __FUNCTION__, length); + return -1; + } + + titus->titsu.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + titus->titsu.length = length; + + titus->titsu.type = RADIUS_3GPP2_PTS_SUBTYPE_TITSU; + + titus->flag = 1; + + return 0; +} + + +int radius_parse_vendor_3gpp2_pts(RADIUS_VENDOR_ATTRIBUTE_3GPP2_PTS *pts, const BYTE *flw_ptr, BYTE length) +{ + BYTE *ptr = (BYTE *)flw_ptr; + + for (;;) + { + if ((ptr - flw_ptr) >= length) + break; + + switch (ptr[0]) + { + case RADIUS_3GPP2_PTS_SUBTYPE_QID: + if (radius_parse_vendor_3gpp2_pts_sub_attr_qid(&pts->qid, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: pts sub attribute qid parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PTS_SUBTYPE_VUATS: + if (radius_parse_vendor_3gpp2_pts_sub_attr_vuats(&pts->vuats, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: pts sub attribute vuats parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PTS_SUBTYPE_VUATSO: + if (radius_parse_vendor_3gpp2_pts_sub_attr_vuatso(&pts->vuatso, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: pts sub attribute vuatso parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PTS_SUBTYPE_TSI: + if (radius_parse_vendor_3gpp2_pts_sub_attr_tsi(&pts->tsi, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: pts sub attribute tsi parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_3GPP2_PTS_SUBTYPE_TITSU: + if (radius_parse_vendor_3gpp2_pts_sub_attr_titus(&pts->titsu, ptr + 2, ptr[1] - 2) < 0) + { + radius_log_err("%s: pts sub attribute titus parse fail\r\n", __FUNCTION__); + return -1; + } + break; + default: + radius_log_warn("%s: ppaq unknow subtype=%d\r\n", __FUNCTION__, ptr[0]); + break; + } + + ptr += ptr[1]; + } + + return 0; +} + +int radius_parse_attr_vendor_specific_value(RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *vendor_specific, const BYTE *flw_ptr, BYTE length) +{ + DWORD vendor_id; + BYTE vendor_type; + BYTE vendor_length; + + vendor_id = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + vendor_type = flw_ptr[4]; + + vendor_length = flw_ptr[5]; + + switch (vendor_id) + { + case RADIUS_VENDOR_ID_3GPP2: + switch (vendor_type) + { + case RADIUS_VENDOR_TYPE_3GPP2_STC: + if (radius_parse_vendor_3gpp2_stc(&vendor_specific->attribute_3gpp2.stc, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP2_PPAC: + if (radius_parse_vendor_3gpp2_ppac(&vendor_specific->attribute_3gpp2.ppac, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP2_PPAQ: + if (radius_parse_vendor_3gpp2_ppaq(&vendor_specific->attribute_3gpp2.ppaq, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP2_PTS: + if (radius_parse_vendor_3gpp2_pts(&vendor_specific->attribute_3gpp2.pts, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + default: + radius_log_warn("%s: vendor specific type=%d not support\r\n", __FUNCTION__, vendor_type); + return 0; + } + break; + case RADIUS_VENDOR_ID_3GPP: + switch (vendor_type) + { + case RADIUS_VENDOR_TYPE_3GPP_IMSI: + if (radius_parse_vendor_3gpp_imsi(&vendor_specific->attribute_3gpp.imsi, flw_ptr + 6, vendor_length -2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_CHARGING_ID: + if (radius_parse_vendor_3gpp_charging_id(&vendor_specific->attribute_3gpp.charging_id, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_PDP_TYPE: + if (radius_parse_vendor_3gpp_pdp_type(&vendor_specific->attribute_3gpp.pdp_type, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_CG_ADDR: + if (radius_parse_vendor_3gpp_cg_addr(&vendor_specific->attribute_3gpp.cg_addr, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_NQP: + if (radius_parse_vendor_3gpp_nqp(&vendor_specific->attribute_3gpp.negotiated_qos, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_SGSN_ADDR: + if (radius_parse_vendor_3gpp_sgsn_addr(&vendor_specific->attribute_3gpp.sgsn_addr, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_GGSN_ADDR: + if (radius_parse_vendor_3gpp_ggsn_addr(&vendor_specific->attribute_3gpp.ggsn_addr, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_IMSI_MCC_MNC: + if (radius_parse_vendor_3gpp_imsi_mcc_mnc(&vendor_specific->attribute_3gpp.mcc_mnc, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_GGSN_MCC_MNC: + if (radius_parse_vendor_3gpp_ggsn_mcc_mnc(&vendor_specific->attribute_3gpp.ggsn_mcc_mnc, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_NSAPI: + if (radius_parse_vendor_3gpp_nsapi(&vendor_specific->attribute_3gpp.nsapi, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_SSI: + if (radius_parse_vendor_3gpp_ssi(&vendor_specific->attribute_3gpp.ssi, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_SM: + if (radius_parse_vendor_3gpp_sm(&vendor_specific->attribute_3gpp.sm, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_CC: + if (radius_parse_vendor_3gpp_cc(&vendor_specific->attribute_3gpp.cc, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_3GPP_SGSN_MCC_MNC: + if (radius_parse_vendor_3gpp_sgsn_mcc_mnc(&vendor_specific->attribute_3gpp.sgsn_mcc_mnc, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + default: + radius_log_warn("%s: vendor specific type=%d not support\r\n", __FUNCTION__, vendor_type); + return 0; + } + break; + case RADIUS_VENDOR_ID_WIMAX: + switch (vendor_type) + { + case RADIUS_VENDOR_TYPE_PPAC: + if (radius_parse_vendor_ppac_sub_attr(&vendor_specific->attribute.ppac, flw_ptr + 6, vendor_length - 2) < 0)//flw_ptr: vendor_id 4 bytes vendor type 1 byte vendor length 1 byte + return -1; + break; + case RADIUS_VENDOR_TYPE_STC: + if (radius_parse_vendor_stc_sub_attr(&vendor_specific->attribute.stc, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_PPAQ: + if (radius_parse_vendor_ppaq_sub_attr(&vendor_specific->attribute.ppaq, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + case RADIUS_VENDOR_TYPE_PTS: + if (radius_parse_vendor_pts_sub_attr(&vendor_specific->attribute.pts, flw_ptr + 6, vendor_length - 2) < 0) + return -1; + break; + default: + radius_log_err("%s: vendor specific type=%d unknow\r\n", __FUNCTION__, vendor_type); + return -1; + } + break; + default: + radius_log_err("%s: vendor specific type=%d unknow\r\n", __FUNCTION__, vendor_type); + return -1; + } + vendor_specific->vendor_type = vendor_type; + + vendor_specific->vendor_id = vendor_id; + + vendor_specific->flag = 1; + + return 0; +} + +int radius_parse_attr_vendor_specific(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_VENDOR_SPECIFIC *vendor_specific; + RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *vendor_specific_attr; + + if ((length < 5) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s vendor specific length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + vendor_specific = &msg_pdu->msg.access_request.vendor_specific; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + vendor_specific = &msg_pdu->msg.access_accept.vendor_specific; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + vendor_specific = &msg_pdu->msg.access_challenge.vendor_specific; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + vendor_specific = &msg_pdu->msg.accounting_request.vendor_specific; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + vendor_specific = &msg_pdu->msg.accounting_response.vendor_specific; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + vendor_specific = &msg_pdu->msg.disconnect_request.vendor_specific; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with vendor specific\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = vendor_specific->num) >= RADIUS_MAX_NUM_OF_VENDOR_SPECIFIC) + { + radius_log_warn("%s: recv msg type=%s, no resource for vendor specific\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + vendor_specific_attr = &vendor_specific->vendor_specific[num]; + + if (radius_parse_attr_vendor_specific_value(vendor_specific_attr, flw_ptr, length) < 0) + { + radius_log_err("%s: parse vendor specific value error\r\n", __FUNCTION__); + return -1; + } + + vendor_specific->num++; + + return 0; +} + +int radius_parse_attr_session_timeout(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_SESSION_TIMEOUT *session_timeout; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s session timeout length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + session_timeout = &msg_pdu->msg.access_accept.session_timeout; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + session_timeout = &msg_pdu->msg.access_challenge.session_timeout; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + session_timeout = &msg_pdu->msg.accounting_request.session_timeout; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with session timeout\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + session_timeout->session_timeout.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + session_timeout->session_timeout.length = length; + + session_timeout->session_timeout.type = RADIUS_ATTRIBUTE_TYPE_SESSION_TIMEOUT; + + session_timeout->flag = 1; + + return 0; +} + +int radius_parse_attr_idle_timeout(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_IDLE_TIMEOUT *idle_timeout; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s idle timeout length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + idle_timeout = &msg_pdu->msg.access_accept.idle_timeout; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + idle_timeout = &msg_pdu->msg.access_challenge.idle_timeout; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + idle_timeout = &msg_pdu->msg.accounting_request.idle_timeout; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with idle timeout\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + idle_timeout->idle_timeout.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + idle_timeout->idle_timeout.length = length; + + idle_timeout->idle_timeout.type = RADIUS_ATTRIBUTE_TYPE_IDLE_TIMEOUT; + + idle_timeout->flag = 1; + + return 0; +} + +int radius_parse_attr_termination_action(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_TERMINATION_ACTION *termination_action; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s termination action length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + termination_action = &msg_pdu->msg.access_accept.termination_action; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + termination_action = &msg_pdu->msg.accounting_request.termination_action; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with idle timeout\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + termination_action->termination_action.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + termination_action->termination_action.length = length; + + termination_action->termination_action.type = RADIUS_ATTRIBUTE_TYPE_TERMINATION_ACTION; + + termination_action->flag = 1; + + return 0; +} +/* +int radius_parse_attr_called_station_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_CALLED_STATION_ID *called_station_id; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s called station id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + called_station_id = &msg_pdu->msg.access_request.called_station_id; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + called_station_id = &msg_pdu->msg.accounting_request.called_station_id; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + called_station_id = &msg_pdu->msg.disconnect_request.called_station_id; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with called station id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(called_station_id->called_station_id.value, flw_ptr, length); + + called_station_id->called_station_id.length = length; + + called_station_id->called_station_id.type = RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID; + + called_station_id->flag = 1; + + return 0; +}*/ +static int radius_parse_attr_called_station_id_spit_num(RADIUS_ATTRIBUTE_CALLED_STATION_ID *called_station_id, BYTE *ptr, int length) +{ + //split called list + int num = 0, tmp_len = 0, len; + char *buf = (char *)ptr; + char *tmp; + + while((tmp = strstr(buf, ",")) != NULL) + { + tmp[0] = '\0'; + if((len = strlen(buf)) != 0 && len == (tmp - buf)) + { + called_station_id->called.server.called_station_id[num].length = len; + memcpy(called_station_id->called.server.called_station_id[num].value, buf, len); + num++; + } + tmp_len += (tmp - buf + 1); + buf = tmp + 1; + if(num >= RADIUS_MAX_NUM_OF_NOWSMS_CALLED_ID) + { + called_station_id->called.server.num = RADIUS_MAX_NUM_OF_NOWSMS_CALLED_ID; + radius_log_warn("%s: called count overpass the max\r\n", __FUNCTION__); + return 0; + } + } + if((len = strlen(buf)) != 0) + { + called_station_id->called.server.called_station_id[num].length = len; + memcpy(called_station_id->called.server.called_station_id[num].value, buf, len); + num++; + tmp_len += len; + } + if(tmp_len != length) + { + radius_log_err("%s: split len=%d, length=%d\r\n", __FUNCTION__, tmp_len, length); + return -1; + } + called_station_id->called.server.num = num; + radius_log_event("%s: success! length=%d\r\n", __FUNCTION__, length); + + return 0; +} +int radius_parse_attr_called_station_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + int num = 0, index, len; + int last_2, last_3; + RADIUS_ATTRIBUTE_CALLED_STATION_ID *called_station_id; + char *tmp_ptr; + BYTE buf[RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST]; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + + if(msg_pdu == NULL || flw_ptr == NULL) + return -1; + if((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s called station id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + called_station_id = &msg_pdu->msg.access_request.called_station_id; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + called_station_id = &msg_pdu->msg.accounting_request.called_station_id; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + called_station_id = &msg_pdu->msg.disconnect_request.called_station_id; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with called station id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + if(length == (tmp_flw_ptr[1]+1) && 0xFF == tmp_flw_ptr[0]) + { + num++; + if((tmp_ptr = strstr((char*)tmp_flw_ptr, ",")) == NULL) + { + if(tmp_flw_ptr[length-1] != 0xFF) + num = 0; + } + } + if(num == 0) + { + memcpy(called_station_id->called.server.called_station_id[0].value, flw_ptr, length); + called_station_id->called.server.called_station_id[0].length = length; + called_station_id->called.server.called_station_id[0].type = RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID; + called_station_id->called.server.num = 0; + called_station_id->option = 1; + } + else //nowsms + { + memset(buf, 0, RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST); + last_2 = RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST - 2; // 1298 + last_3 = RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST - 3; // 1297 + if(tmp_flw_ptr[length-1] == 0xFF) //end indicator + { + if(called_station_id->option == 0) + { + memcpy(called_station_id->called.client.called_list, tmp_flw_ptr+2, length-3); + len = length - 3; + } + else if(called_station_id->option == 2) + { + index = called_station_id->called.client.called_list[last_2]; + num = called_station_id->called.client.called_list[last_3]; + called_station_id->called.client.called_list[last_2] = 0; + called_station_id->called.client.called_list[last_3] = 0; + memcpy(called_station_id->called.client.called_list+RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED*(num-1), \ + tmp_flw_ptr+2, length-3); + len = RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED*(num-1) + length - 3; + index |= (1 << (num - 1)); + num = (1 << num) - 1; + if(index != num) + radius_log_warn("%s: split num(%x), index= %x error!\r\n", __FUNCTION__, num, index); + } + memcpy(buf, called_station_id->called.client.called_list, len); + memset(called_station_id, 0, sizeof(RADIUS_ATTRIBUTE_CALLED_STATION_ID)); + radius_parse_attr_called_station_id_spit_num(called_station_id, buf, len); + called_station_id->option = 1; + } + else + { + index = tmp_flw_ptr[length-1] & 0x0F; + num = (tmp_flw_ptr[length-1] & 0xF0) >> 4; + if(num > (RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST / RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED + 1)) + { + num = RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST / RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED + 1; + radius_log_warn("%s: split num(%d) error!\r\n", __FUNCTION__, num); + } + buf[last_3] = num; + buf[last_2] = 1 << (index - 1); + if(called_station_id->option == 0) + { + memcpy(buf+RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED*(index-1), tmp_flw_ptr+2, length-3); + called_station_id->option = 2; + memcpy(called_station_id->called.client.called_list, buf, RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST); + } + else if(called_station_id->option == 2) + { + if((buf[last_3] == called_station_id->called.client.called_list[last_3]) && \ + ((called_station_id->called.client.called_list[last_2] & buf[last_2]) != 0x1)) + { + called_station_id->called.client.called_list[last_2] |= buf[last_2]; + memcpy(called_station_id->called.client.called_list+RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED*(index-1), \ + tmp_flw_ptr+2, length-3); + } + } + } + } + + return 0; +} + +int radius_parse_attr_calling_station_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_CALLING_STATION_ID *calling_station_id; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s calling station id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + calling_station_id = &msg_pdu->msg.access_request.calling_station_id; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + calling_station_id = &msg_pdu->msg.accounting_request.calling_station_id; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + calling_station_id = &msg_pdu->msg.disconnect_request.calling_station_id; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with calling station id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(calling_station_id->calling_station_id.value, flw_ptr, length); + + calling_station_id->calling_station_id.length = length; + + calling_station_id->calling_station_id.type = RADIUS_ATTRIBUTE_TYPE_CALLING_STATION_ID; + + calling_station_id->flag = 1; + + return 0; +} + +int radius_parse_attr_nas_identifier(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_NAS_IDENTIFIER *nas_identifier; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s nas identifier length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + nas_identifier = &msg_pdu->msg.access_request.nas_identifier; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + nas_identifier = &msg_pdu->msg.accounting_request.nas_identifier; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + nas_identifier = &msg_pdu->msg.disconnect_request.nas_identifier; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with nas identifier\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(nas_identifier->nas_identifier.value, flw_ptr, length); + + nas_identifier->nas_identifier.length = length; + + nas_identifier->nas_identifier.type = RADIUS_ATTRIBUTE_TYPE_NAS_IDENTIFIER; + + nas_identifier->flag = 1; + + return 0; +} + +int radius_parse_attr_proxy_state(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_PROXY_STATE *proxy_state; + RADIUS_ATTRIBUTE_PROXY_STATE *proxy_state_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s proxy state length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + proxy_state = &msg_pdu->msg.access_request.proxy_state; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + proxy_state = &msg_pdu->msg.access_accept.proxy_state; + break; + case RADIUS_MSG_TYPE_ACCESS_REJECT: + proxy_state = &msg_pdu->msg.access_reject.proxy_state; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + proxy_state = &msg_pdu->msg.access_challenge.proxy_state; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + proxy_state = &msg_pdu->msg.accounting_request.proxy_state; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + proxy_state = &msg_pdu->msg.accounting_response.proxy_state; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + proxy_state = &msg_pdu->msg.disconnect_ack.proxy_state; + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + proxy_state = &msg_pdu->msg.disconnect_nak.proxy_state; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with proxy state\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = proxy_state->num) >= RADIUS_MAX_NUM_OF_PROXY_STATE) + { + radius_log_warn("%s: recv msg type=%s, no resource for proxy state\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + proxy_state_attr = &proxy_state->proxy_state[num]; + + memcpy(proxy_state_attr->proxy_state.value, flw_ptr, length); + + proxy_state_attr->proxy_state.length = length; + + proxy_state_attr->proxy_state.type = RADIUS_ATTRIBUTE_TYPE_PROXY_STATE; + + proxy_state_attr->flag = 1; + + proxy_state->num++; + + return 0; +} + +int radius_parse_attr_login_lat_service(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_LOGIN_LAT_SERVICE *login_lat_service; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s login lat service length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + login_lat_service = &msg_pdu->msg.access_request.login_lat_service; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + login_lat_service = &msg_pdu->msg.access_accept.login_lat_service; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + login_lat_service = &msg_pdu->msg.accounting_request.login_lat_service; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with login lat servicer\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(login_lat_service->login_lat_service.value, flw_ptr, length); + + login_lat_service->login_lat_service.length = length; + + login_lat_service->login_lat_service.type = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_SERVICE; + + login_lat_service->flag = 1; + + return 0; +} + +int radius_parse_attr_login_lat_node(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_LOGIN_LAT_NODE *login_lat_node; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s login lat node length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + login_lat_node = &msg_pdu->msg.access_request.login_lat_node; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + login_lat_node = &msg_pdu->msg.access_accept.login_lat_node; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + login_lat_node = &msg_pdu->msg.accounting_request.login_lat_node; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with login lat node\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(login_lat_node->login_lat_node.value, flw_ptr, length); + + login_lat_node->login_lat_node.length = length; + + login_lat_node->login_lat_node.type = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_NODE; + + login_lat_node->flag = 1; + + return 0; +} + +int radius_parse_attr_login_lat_group(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_LOGIN_LAT_GROUP *login_lat_group; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s login lat group length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + login_lat_group = &msg_pdu->msg.access_request.login_lat_group; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + login_lat_group = &msg_pdu->msg.access_accept.login_lat_group; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + login_lat_group = &msg_pdu->msg.accounting_request.login_lat_group; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with login lat group\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(login_lat_group->login_lat_group.value, flw_ptr, length); + + login_lat_group->login_lat_group.length = length; + + login_lat_group->login_lat_group.type = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_GROUP; + + login_lat_group->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_appletalk_link(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_LINK *framed_appletalk_link; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed appletalk link length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_appletalk_link = &msg_pdu->msg.access_accept.framed_appletalk_link; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_appletalk_link = &msg_pdu->msg.accounting_request.framed_appletalk_link; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed appletalk link\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_appletalk_link->framed_appletalk_link.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + framed_appletalk_link->framed_appletalk_link.length = length; + + framed_appletalk_link->framed_appletalk_link.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_LINK; + + framed_appletalk_link->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_appletalk_network(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_FRAMED_APPLETALK_NETWORK *framed_appletalk_network; + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_NETWORK *framed_appletalk_network_attr; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s framed appletalk network length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_appletalk_network = &msg_pdu->msg.access_accept.framed_appletalk_network; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_appletalk_network = &msg_pdu->msg.accounting_request.framed_appletalk_network; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed appletalk network\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = framed_appletalk_network->num) >= RADIUS_MAX_NUM_OF_FRAMED_APPLETALK_NETWORK) + { + radius_log_warn("%s: recv msg type=%s, no resource for framed appletalk network\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + framed_appletalk_network_attr = &framed_appletalk_network->framed_appletalk_network[num]; + + framed_appletalk_network_attr->framed_appletalk_network.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + framed_appletalk_network_attr->framed_appletalk_network.length = length; + + framed_appletalk_network_attr->framed_appletalk_network.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_NETWORK; + + framed_appletalk_network_attr->flag = 1; + + framed_appletalk_network->num++; + + return 0; +} + +int radius_parse_attr_framed_appletalk_zone(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_APPLETALK_ZONE *framed_appletalk_zone; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s framed appletalk zone length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_appletalk_zone = &msg_pdu->msg.access_accept.framed_appletalk_zone; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + framed_appletalk_zone = &msg_pdu->msg.accounting_request.framed_appletalk_zone; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed appletalk zone\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(framed_appletalk_zone->framed_appletalk_zone.value, flw_ptr, length); + + framed_appletalk_zone->framed_appletalk_zone.length = length; + + framed_appletalk_zone->framed_appletalk_zone.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_ZONE; + + framed_appletalk_zone->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_status_type(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_STATUS_TYPE *acct_status_type; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct status type length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_status_type = &msg_pdu->msg.accounting_request.acct_status_type; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct status type\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_status_type->acct_status_type.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_status_type->acct_status_type.length = length; + + acct_status_type->acct_status_type.type = RADIUS_ATTRIBUTE_TYPE_ACCT_STATUS_TYPE; + + acct_status_type->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_delay_time(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_DELAY_TIME *acct_delay_time; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct delay time length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_delay_time = &msg_pdu->msg.accounting_request.acct_delay_time; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct delay time\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_delay_time->acct_delay_time.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_delay_time->acct_delay_time.length = length; + + acct_delay_time->acct_delay_time.type = RADIUS_ATTRIBUTE_TYPE_ACCT_DELAY_TIME; + + acct_delay_time->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_input_octets(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_INPUT_OCTETS *acct_input_octets; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct input octets length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_input_octets = &msg_pdu->msg.accounting_request.acct_input_octets; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct input octets\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_input_octets->acct_input_octets.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_input_octets->acct_input_octets.length = length; + + acct_input_octets->acct_input_octets.type = RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_OCTETS; + + acct_input_octets->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_output_octets(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_OUTPUT_OCTETS *acct_output_octets; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct output octets length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_output_octets= &msg_pdu->msg.accounting_request.acct_output_octets; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct output octets\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_output_octets->acct_output_octets.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_output_octets->acct_output_octets.length = length; + + acct_output_octets->acct_output_octets.type = RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_OCTETS; + + acct_output_octets->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_session_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_SESSION_ID *acct_session_id; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s acct session id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + acct_session_id= &msg_pdu->msg.access_request.acct_session_id; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_session_id= &msg_pdu->msg.accounting_request.acct_session_id; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + acct_session_id = &msg_pdu->msg.disconnect_request.acct_session_id; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct session id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(acct_session_id->acct_session_id.value, flw_ptr, length); + + acct_session_id->acct_session_id.length = length; + + acct_session_id->acct_session_id.type = RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_ID; + + acct_session_id->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_authentic(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_AUTHENTIC *acct_authentic; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct authentic length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_authentic = &msg_pdu->msg.accounting_request.acct_authentic; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct authentic\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_authentic->acct_authentic.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_authentic->acct_authentic.length = length; + + acct_authentic->acct_authentic.type = RADIUS_ATTRIBUTE_TYPE_ACCT_AUTHENTIC; + + acct_authentic->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_session_time(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_SESSION_TIME *acct_session_time; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct session time length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_session_time = &msg_pdu->msg.accounting_request.acct_session_time; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct session time\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_session_time->acct_session_time.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_session_time->acct_session_time.length = length; + + acct_session_time->acct_session_time.type = RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_TIME; + + acct_session_time->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_input_packets(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_INPUT_PACKETS *acct_input_packets; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct input packets length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_input_packets = &msg_pdu->msg.accounting_request.acct_input_packets; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct input packets\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_input_packets->acct_input_packets.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_input_packets->acct_input_packets.length = length; + + acct_input_packets->acct_input_packets.type = RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_PACKETS; + + acct_input_packets->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_output_packets(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_OUTPUT_PACKETS *acct_output_packets; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct output packets length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_output_packets= &msg_pdu->msg.accounting_request.acct_output_packets; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct output packets\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_output_packets->acct_output_packets.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_output_packets->acct_output_packets.length = length; + + acct_output_packets->acct_output_packets.type = RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_PACKETS; + + acct_output_packets->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_terminate_cause(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_TERMINATE_CAUSE *acct_terminate_cause; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct terminate cause length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_terminate_cause= &msg_pdu->msg.accounting_request.acct_terminate_cause; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + acct_terminate_cause = &msg_pdu->msg.disconnect_request.acct_terminate_cause; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + acct_terminate_cause = &msg_pdu->msg.disconnect_ack.acct_terminate_cause; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct input packets\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_terminate_cause->acct_terminate_cause.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_terminate_cause->acct_terminate_cause.length = length; + + acct_terminate_cause->acct_terminate_cause.type = RADIUS_ATTRIBUTE_TYPE_ACCT_TERMINATE_CAUSE; + + acct_terminate_cause->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_multi_session_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_ACCT_MULTI_SESSION_ID *acct_multi_session_id; + RADIUS_ATTRIBUTE_ACCT_MULTI_SESSION_ID *acct_multi_session_id_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s acct session id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_multi_session_id = &msg_pdu->msg.accounting_request.acct_multi_session_id; + + if ((num = acct_multi_session_id->num) >= RADIUS_MAX_NUM_OF_ACCT_MULTI_SESSION_ID) + { + radius_log_warn("%s: accounting request acct multi session id num=%d, no resource for acct multi session id\r\n", __FUNCTION__, num); + return 0; + } + + acct_multi_session_id_attr = &acct_multi_session_id->acct_multi_session_id[num]; + + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + acct_multi_session_id_attr = &msg_pdu->msg.disconnect_request.acct_multi_session_id; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct multi session id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(acct_multi_session_id_attr->acct_multi_session_id.value, flw_ptr, length); + + acct_multi_session_id_attr->acct_multi_session_id.length = length; + + acct_multi_session_id_attr->acct_multi_session_id.type = RADIUS_ATTRIBUTE_TYPE_ACCT_MULTI_SESSION_ID; + + acct_multi_session_id_attr->flag = 1; + + if (msg_pdu->msg_type == RADIUS_MSG_TYPE_ACCOUNTING_REQUEST) + { + acct_multi_session_id->num++; + } + + return 0; +} + +int radius_parse_attr_acct_link_count(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_ACCT_LINK_COUNT *acct_link_count; + RADIUS_ATTRIBUTE_ACCT_LINK_COUNT *acct_link_count_attr; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct link count length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + acct_link_count = &msg_pdu->msg.accounting_request.acct_link_count; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct link count\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = acct_link_count->num) >= RADIUS_MAX_NUM_OF_ACCT_LINK_COUNT) + { + radius_log_warn("%s: msg type=%s acct link cout num=%d, no resource for acct link count\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), num); + return 0; + } + + acct_link_count_attr = &acct_link_count->acct_link_count[num]; + + acct_link_count_attr->acct_link_count.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_link_count_attr->acct_link_count.length = length; + + acct_link_count_attr->acct_link_count.type = RADIUS_ATTRIBUTE_TYPE_ACCT_LINK_COUNT; + + acct_link_count_attr->flag = 1; + + acct_link_count->num++; + + return 0; +} + +int radius_parse_attr_event_timestamp(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_EVENT_TIMESTAMP *event_timestamp; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s event timestamp length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + event_timestamp = &msg_pdu->msg.disconnect_request.event_timestamp; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + event_timestamp = &msg_pdu->msg.disconnect_ack.event_timestamp; + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + event_timestamp = &msg_pdu->msg.disconnect_nak.event_timestamp; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with event timestamp\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + event_timestamp->event_timestamp.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + event_timestamp->event_timestamp.length = length; + + event_timestamp->event_timestamp.type = RADIUS_ATTRIBUTE_TYPE_EVENT_TIMESTAMP; + + event_timestamp->flag = 1; + + return 0; +} + +int radius_parse_attr_chap_challenge(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_CHAP_CHALLENGE *chap_challenge; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s chap challenge length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + chap_challenge = &msg_pdu->msg.access_request.chap_challenge; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with chap challenge\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(chap_challenge->chap_challenge.value, flw_ptr, length); + + chap_challenge->chap_challenge.length = length; + + chap_challenge->chap_challenge.type = RADIUS_ATTRIBUTE_TYPE_CHAP_CHALLENGE; + + chap_challenge->flag = 1; + + return 0; +} + +int radius_parse_attr_nas_port_type(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_NAS_PORT_TYPE *nas_port_type; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s nas port type length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + nas_port_type = &msg_pdu->msg.access_request.nas_port_type; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + nas_port_type = &msg_pdu->msg.accounting_request.nas_port_type; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + nas_port_type = &msg_pdu->msg.disconnect_request.nas_port_type; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with nas port type\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + nas_port_type->nas_port_type.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + nas_port_type->nas_port_type.length = length; + + nas_port_type->nas_port_type.type = RADIUS_ATTRIBUTE_TYPE_NAS_PORT_TYPE; + + nas_port_type->flag = 1; + + return 0; +} + +int radius_parse_attr_port_limit(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_PORT_LIMIT *port_limit; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s port limit length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + port_limit = &msg_pdu->msg.access_request.port_limit; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + port_limit = &msg_pdu->msg.access_accept.port_limit; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + port_limit= &msg_pdu->msg.accounting_request.port_limit; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with port limit\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + port_limit->port_limit.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + port_limit->port_limit.length = length; + + port_limit->port_limit.type = RADIUS_ATTRIBUTE_TYPE_PORT_LIMIT; + + port_limit->flag = 1; + + return 0; +} + +int radius_parse_attr_login_lat_port(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_LOGIN_LAT_PORT *login_lat_port; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s login lat port length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + login_lat_port = &msg_pdu->msg.access_request.login_lat_port; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + login_lat_port = &msg_pdu->msg.access_accept.login_lat_port; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + login_lat_port = &msg_pdu->msg.accounting_request.login_lat_port; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with login lat port\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(login_lat_port->login_lat_port.value, flw_ptr, length); + + login_lat_port->login_lat_port.length = length; + + login_lat_port->login_lat_port.type = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_PORT; + + login_lat_port->flag = 1; + + return 0; +} + +int radius_parse_attr_arap_password(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ARAP_PASSWORD *arap_password; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s arap password length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + arap_password = &msg_pdu->msg.access_request.arap_password; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with arap password\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(arap_password->arap_password.value, flw_ptr, length); + + arap_password->arap_password.length = length; + + arap_password->arap_password.type = RADIUS_ATTRIBUTE_TYPE_ARAP_PASSWORD; + + arap_password->flag = 1; + + return 0; +} + +int radius_parse_attr_arap_features(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ARAP_FEATURES *arap_features; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s arap feature length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + arap_features = &msg_pdu->msg.access_accept.arap_features; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + arap_features = &msg_pdu->msg.access_challenge.arap_features; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with arap feature\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(arap_features->arap_features.value, flw_ptr, length); + + arap_features->arap_features.length = length; + + arap_features->arap_features.type = RADIUS_ATTRIBUTE_TYPE_ARAP_FEATURES; + + arap_features->flag = 1; + + return 0; +} + +int radius_parse_attr_arap_zone_access(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ARAP_ZONE_ACCESS *arap_zone_access; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s arap zone access length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + arap_zone_access = &msg_pdu->msg.access_accept.arap_zone_access; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with arap zone access\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + arap_zone_access->arap_zone_access.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + arap_zone_access->arap_zone_access.length = length; + + arap_zone_access->arap_zone_access.type = RADIUS_ATTRIBUTE_TYPE_ARAP_ZONE_ACCESS; + + arap_zone_access->flag = 1; + + return 0; +} + +int radius_parse_attr_arap_security(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ARAP_SECURITY *arap_security; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s arap security access length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + arap_security = &msg_pdu->msg.access_request.arap_security; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + arap_security = &msg_pdu->msg.access_challenge.arap_security; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with arap security access\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + arap_security->arap_security.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + arap_security->arap_security.length = length; + + arap_security->arap_security.type = RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY; + + arap_security->flag = 1; + + return 0; +} + +int radius_parse_attr_arap_security_data(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_ARAP_SECURITY_DATA *arap_security_data; + RADIUS_ATTRIBUTE_ARAP_SECURITY_DATA *arap_security_data_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s arap security data length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + arap_security_data = &msg_pdu->msg.access_request.arap_security_data; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + arap_security_data = &msg_pdu->msg.access_challenge.arap_security_data; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with arap security data\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = arap_security_data->num) >= RADIUS_MAX_NUM_OF_ARAP_SECURITY_DATA) + { + radius_log_warn("%s: recv msg type=%s, no resource for arap security data\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + arap_security_data_attr = &arap_security_data->arap_security_data[num]; + + memcpy(arap_security_data_attr->arap_security_data.value, flw_ptr, length); + + arap_security_data_attr->arap_security_data.length = length; + + arap_security_data_attr->arap_security_data.type = RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY_DATA; + + arap_security_data_attr->flag = 1; + + arap_security_data->num++; + + return 0; +} + +int radius_parse_attr_password_retry(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_PASSWORD_RETRY *password_retry; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s password retry length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REJECT: + password_retry = &msg_pdu->msg.access_reject.password_retry; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with password retry\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + password_retry->password_retry.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + password_retry->password_retry.length = length; + + password_retry->password_retry.type = RADIUS_ATTRIBUTE_TYPE_PASSWORD_RETRY; + + password_retry->flag = 1; + + return 0; +} + +int radius_parse_attr_prompt(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_PROMPT *prompt; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s password retry length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + prompt = &msg_pdu->msg.access_challenge.prompt; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with prompt\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + prompt->prompt.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + prompt->prompt.length = length; + + prompt->prompt.type = RADIUS_ATTRIBUTE_TYPE_PROMPT; + + prompt->flag = 1; + + return 0; +} + +int radius_parse_attr_connect_info(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_CONNECT_INFO *connect_info; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s connect info length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + connect_info = &msg_pdu->msg.access_request.connect_info; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with connect info\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(connect_info->connect_info.value, flw_ptr, length); + + connect_info->connect_info.length = length; + + connect_info->connect_info.type = RADIUS_ATTRIBUTE_TYPE_CONNECT_INFO; + + connect_info->flag = 1; + + return 0; +} + +int radius_parse_attr_configuration_token(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_CONFIGURATION_TOKEN *configuration_token; + RADIUS_ATTRIBUTE_CONFIGURATION_TOKEN *configuration_token_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s configuration token length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + configuration_token = &msg_pdu->msg.access_accept.configuration_token; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with configuration token\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = configuration_token->num) >= RADIUS_MAX_NUM_OF_CONFIGURATION_TOKEN) + { + radius_log_warn("%s: msg type=%s configuration token num=%d, no resource for configuration token\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), num); + return 0; + } + + configuration_token_attr = &configuration_token->configuration_token[num]; + + memcpy(configuration_token_attr->configuration_token.value, flw_ptr, length); + + configuration_token_attr->configuration_token.length = length; + + configuration_token_attr->configuration_token.type = RADIUS_ATTRIBUTE_TYPE_CONFIGURATION_TOKEN; + + configuration_token_attr->flag = 1; + + configuration_token->num++; + + return 0; +} + +int radius_parse_attr_eap_message(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE num; + RADIUS_EAP_MESSAGE *eap_message; + RADIUS_ATTRIBUTE_EAP_MESSAGE *eap_message_attr; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s eap message length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + eap_message = &msg_pdu->msg.access_request.eap_message; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + eap_message = &msg_pdu->msg.access_accept.eap_message; + break; + case RADIUS_MSG_TYPE_ACCESS_REJECT: + eap_message = &msg_pdu->msg.access_reject.eap_message; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + eap_message = &msg_pdu->msg.access_challenge.eap_message; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + eap_message = &msg_pdu->msg.disconnect_request.eap_message; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + eap_message_attr = &msg_pdu->msg.disconnect_ack.eap_message; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with eap message\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if (msg_pdu->msg_type != RADIUS_MSG_TYPE_DISCONNECT_ACK) + { + if ((num = eap_message->num) >= RADIUS_MAX_NUM_OF_EAP_MESSAGE) + { + radius_log_warn("%s: msg type=%s eap message num=%d, no resource for eap message\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), num); + return 0; + } + + eap_message_attr = &eap_message->eap_message[num]; + } + + memcpy(eap_message_attr->eap_message.value, flw_ptr, length); + + eap_message_attr->eap_message.length = length; + + eap_message_attr->eap_message.type = RADIUS_ATTRIBUTE_TYPE_EAP_MESSAGE; + + eap_message_attr->flag = 1; + + eap_message->num++; + + return 0; +} + +int radius_parse_attr_message_authenticator(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR *message_authenticator; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s message authenticator length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + message_authenticator = &msg_pdu->msg.access_request.message_authenticator; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + message_authenticator = &msg_pdu->msg.access_accept.message_authenticator; + break; + case RADIUS_MSG_TYPE_ACCESS_REJECT: + message_authenticator = &msg_pdu->msg.access_reject.message_authenticator; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + message_authenticator = &msg_pdu->msg.access_challenge.message_authenticator; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + message_authenticator = &msg_pdu->msg.disconnect_request.message_authenticator; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + message_authenticator = &msg_pdu->msg.disconnect_ack.message_authenticator; + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + message_authenticator = &msg_pdu->msg.disconnect_nak.message_authenticator; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with message authenticator\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(message_authenticator->message_authenticator.value, flw_ptr, length); + + message_authenticator->message_authenticator.length = length; + + message_authenticator->message_authenticator.type = RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR; + + message_authenticator->flag = 1; + + return 0; +} + +int radius_parse_attr_arap_challenge_response(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ARAP_CHALLENGE_RESPONSE *arap_challenge_response; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s arap challenge response length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + arap_challenge_response = &msg_pdu->msg.access_accept.arap_challenge_response; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + arap_challenge_response = &msg_pdu->msg.access_challenge.arap_challenge_response; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with arap challenge response\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(arap_challenge_response->arap_challenge_response.value, flw_ptr, length); + + arap_challenge_response->arap_challenge_response.length = length; + + arap_challenge_response->arap_challenge_response.type = RADIUS_ATTRIBUTE_TYPE_ARAP_CHALLENGE_RESPONSE; + + arap_challenge_response->flag = 1; + + return 0; +} + +int radius_parse_attr_acct_interim_interval(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_ACCT_INTERIM_INTERVAL *acct_interim_interval; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s acct interim interval length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + acct_interim_interval = &msg_pdu->msg.access_accept.acct_interim_interval; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with acct interim interval\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + acct_interim_interval->acct_interim_interval.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + acct_interim_interval->acct_interim_interval.length = length; + + acct_interim_interval->acct_interim_interval.type = RADIUS_ATTRIBUTE_TYPE_ACCT_INTERIM_INTERVAL; + + acct_interim_interval->flag = 1; + + return 0; +} + +int radius_parse_attr_nas_port_id(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_NAS_PORT_ID *nas_port_id; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s nas port id length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + nas_port_id = &msg_pdu->msg.access_request.nas_port_id; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + nas_port_id = &msg_pdu->msg.disconnect_request.nas_port_id; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with nas port id\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(nas_port_id->nas_port_id.value, flw_ptr, length); + + nas_port_id->nas_port_id.length = length; + + nas_port_id->nas_port_id.type = RADIUS_ATTRIBUTE_TYPE_NAS_PORT_ID; + + nas_port_id->flag = 1; + + return 0; +} + +int radius_parse_attr_framed_pool(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_FRAMED_POOL *framed_pool; + + if ((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s framed pool length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + framed_pool = &msg_pdu->msg.access_accept.framed_pool; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with framed pool\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(framed_pool->framed_pool.value, flw_ptr, length); + + framed_pool->framed_pool.length = length; + + framed_pool->framed_pool.type = RADIUS_ATTRIBUTE_TYPE_FRAMED_POOL; + + framed_pool->flag = 1; + + return 0; +} + +int radius_parse_attr_error_cause(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + int num; + RADIUS_ERROR_CAUSE *error_cause; + RADIUS_ATTRIBUTE_ERROR_CAUSE *error_cause_attr; + + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: msg type=%s error cause length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + error_cause = &msg_pdu->msg.disconnect_ack.error_cause; + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + error_cause = &msg_pdu->msg.disconnect_nak.error_cause; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with error cause\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + if ((num = error_cause->num) >= RADIUS_MAX_NUM_OF_ERROR_CAUSE) + { + radius_log_warn("%s: msg type=%s error cause num=%d, no resource for error cause\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), num); + return 0; + } + + error_cause_attr = &error_cause->error_cause[num]; + + error_cause_attr->error_cause.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + + error_cause_attr->error_cause.length = length; + + error_cause_attr->error_cause.type = RADIUS_ATTRIBUTE_TYPE_ERROR_CAUSE; + + error_cause_attr->flag = 1; + + error_cause->num++; + + return 0; +} + +/* +int radius_parse_attr_nowsms_preauth_type(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_NOWSMS_PREAUTH_TYPE *pre_auth_type; + + if((length == 0) || (length > RADIUS_TS_VALUE_LEN)) + { + radius_log_err("%s: msg type=%s nowsms preauth type length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + pre_auth_type = &msg_pdu->msg.access_request.pre_auth_type; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with pre auth type for nowsms\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + memcpy(pre_auth_type->pre_auth_type.value, flw_ptr+2, length); + pre_auth_type->pre_auth_type.length = length-2; + pre_auth_type->pre_auth_type.type = flw_ptr[0]; + pre_auth_type->flag = 1; + pre_auth_type->type = RADIUS_ATTRIBUTE_TYPE_NOWSMS_PREAUTH_TYPE; + + return 0; +}*/ +int radius_parse_attr_nowsms_preauth_type(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + RADIUS_ATTRIBUTE_NOWSMS_PREAUTH_TYPE *pre_auth_type; + + if(length != 1) + { + radius_log_err("%s: msg type=%s nowsms preauth type length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + pre_auth_type = &msg_pdu->msg.access_request.pre_auth_type; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with pre auth type for nowsms\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + pre_auth_type->pre_auth_type.value = flw_ptr[0]; + pre_auth_type->pre_auth_type.length = length; + pre_auth_type->pre_auth_type.type = RADIUS_ATTRIBUTE_TYPE_NOWSMS_PREAUTH_TYPE; + pre_auth_type->flag = 1; + + return 0; +} + +static int radius_parse_attr_nowsms_msg_count(RADIUS_ATTRIBUTE_NOWSMS_MSG_COUNT *msg_count, const BYTE *flw_ptr, BYTE length) +{ + if (length != 1) + { + radius_log_err("%s: nowsms msg count length=%d\r\n", __FUNCTION__, length); + return -1; + } + msg_count->flag = 1; + msg_count->msg_count.value = flw_ptr[0]; + msg_count->msg_count.length = length; + msg_count->msg_count.type = RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGCOUNT; + + return 0; +} +static int radius_parse_attr_nowsms_msg_id(RADIUS_ATTRIBUTE_NOWSMS_MSG_ID *msg_id, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: nowsms msg id length=%d\r\n", __FUNCTION__, length); + return -1; + } + msg_id->flag = 1; + msg_id->msg_id.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + msg_id->msg_id.length = length; + msg_id->msg_id.type = RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGID; + + return 0; +} +static int radius_parse_attr_nowsms_size(RADIUS_ATTRIBUTE_NOWSMS_SIZE *size, const BYTE *flw_ptr, BYTE length) +{ + if (length != RADIUS_VALUE_LEN) + { + radius_log_err("%s: nowsms size length=%d\r\n", __FUNCTION__, length); + return -1; + } + size->flag = 1; + size->size.value = flw_ptr[0] << 24 | flw_ptr[1] << 16 | flw_ptr[2] << 8 | flw_ptr[3]; + size->size.length = length; + size->size.type = RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_SIZE; + + return 0; +} +int radius_parse_attr_nowsms_count_id_size(RADIUS_MSG *msg_pdu, const BYTE *flw_ptr, BYTE length) +{ + BYTE *sub_ptr; + RADIUS_ATTRIBUTE_NOWSMS_COUNT_ID_SIZE *count_id_size; + + if (length < 3 || length > 15) + { + radius_log_err("%s: msg type=%s nowsms count id size length=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type), length); + return -1; + } + + switch (msg_pdu->msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + count_id_size = &msg_pdu->msg.access_request.count_id_size; + break; + default: + radius_log_warn("%s: msg type=%s recv msg with nowsms count id size for nowsms\r\n", __FUNCTION__, radius_get_msg_str(msg_pdu->msg_type)); + return 0; + } + + count_id_size->type = RADIUS_ATTRIBUTE_TYPE_NOWSMS_COUNT_ID_SIZE; + + count_id_size->flag = 1; + + sub_ptr = (BYTE*)flw_ptr; + for(;;) + { + if((sub_ptr - flw_ptr) >= length) + break; + switch(sub_ptr[0]) + { + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGCOUNT: + if(radius_parse_attr_nowsms_msg_count(&count_id_size->msg_count, sub_ptr+2, sub_ptr[1]-2) < 0) + { + radius_log_err("%s: nowsms sub attribute msg_count parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGID: + if(radius_parse_attr_nowsms_msg_id(&count_id_size->msg_id, sub_ptr+2, sub_ptr[1]-2) < 0) + { + radius_log_err("%s: nowsms sub attribute msg_id parse fail\r\n", __FUNCTION__); + return -1; + } + break; + case RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_SIZE: + if(radius_parse_attr_nowsms_size(&count_id_size->size, sub_ptr+2, sub_ptr[1]-2) < 0) + { + radius_log_err("%s: nowsms sub attribute size parse fail\r\n", __FUNCTION__); + return -1; + } + break; + default: + radius_log_warn("%s: nowsms unknow subtype=%d\r\n", __FUNCTION__, sub_ptr[0]); + return 0; + } + sub_ptr += sub_ptr[1]; + } + + return 0; +} + + +int radius_parse_access_request_attr(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_REQUEST; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + if (attr_type == RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR) + { + *msg_auth_attr_offset = flw_pt - msg; + } + + flw_pt += flw_pt[1]; + } + + if ((radius_msg_pdu.msg.access_request.nas_identifier.flag != 1) && (radius_msg_pdu.msg.access_request.nas_ip_addr.flag != 1)) + { + radius_log_err("%s: Either NAS-IP-Address or NAS-Identifier MUST be present in an Access-Request\r\n", __FUNCTION__); + return -1; + } + + return 0; +} + +int radius_parse_access_accept_attr(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + if (attr_type == RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR) + { + *msg_auth_attr_offset = flw_pt - msg; + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + +int radius_parse_access_reject_attr(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_REJECT; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + if (attr_type == RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR) + { + *msg_auth_attr_offset = flw_pt - msg; + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + +int radius_parse_access_challenge_attr(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_CHALLENGE; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + if (attr_type == RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR) + { + *msg_auth_attr_offset = flw_pt - msg; + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + +int radius_parse_accounting_request_attr(BYTE *msg, int msg_len) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_ACCOUNTING_REQUEST; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + +int radius_parse_accounting_response_attr(BYTE *msg, int msg_len) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + +int radius_parse_disconnect_request_attr(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_DISCONNECT_REQUEST; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + if (attr_type == RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR) + { + *msg_auth_attr_offset = flw_pt - msg; + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + +int radius_parse_disconnect_ack_attr(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_DISCONNECT_ACK; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + if (attr_type == RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR) + { + *msg_auth_attr_offset = flw_pt - msg; + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + +int radius_parse_disconnect_nak_attr(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE attr_type; + BYTE *flw_pt = msg + 20;//attribute begin from the 20th byte of the msg + + radius_msg_pdu.msg_type = RADIUS_MSG_TYPE_DISCONNECT_NAK; + + for (;;) + { + if (flw_pt - msg >= msg_len) + break; + + attr_type = flw_pt[0]; + + if (radius_attr_parse_function[attr_type].parse_function != NULL) + { + if (radius_attr_parse_function[attr_type].parse_function(&radius_msg_pdu, flw_pt + 2, flw_pt[1] - 2) < 0) + { + radius_log_err("%s: parse attribute=%d fail\r\n", __FUNCTION__, attr_type); + return -1; + } + } + else + { + radius_log_warn("%s: no parse function for attribute=%d\r\n", __FUNCTION__, attr_type); + } + + if (attr_type == RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR) + { + *msg_auth_attr_offset = flw_pt - msg; + } + + flw_pt += flw_pt[1]; + } + + return 0; +} + + +int radius_parse_attribute(BYTE *msg, int msg_len, int *msg_auth_attr_offset) +{ + BYTE msg_type; + + memset(&radius_msg_pdu, 0, sizeof(RADIUS_MSG)); + + msg_type = msg[0]; + + switch (msg_type) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + if (radius_parse_access_request_attr(msg, msg_len, msg_auth_attr_offset) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + if (radius_parse_access_accept_attr(msg, msg_len, msg_auth_attr_offset) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_ACCESS_REJECT: + if (radius_parse_access_reject_attr(msg, msg_len, msg_auth_attr_offset) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + if (radius_parse_access_challenge_attr(msg, msg_len, msg_auth_attr_offset) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + if (radius_parse_accounting_request_attr(msg, msg_len) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + if (radius_parse_accounting_response_attr(msg, msg_len) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + if (radius_parse_disconnect_request_attr(msg, msg_len, msg_auth_attr_offset) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + if (radius_parse_disconnect_ack_attr(msg, msg_len, msg_auth_attr_offset) < 0) + return -1; + break; + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + if (radius_parse_disconnect_nak_attr(msg, msg_len, msg_auth_attr_offset) < 0) + return -1; + break; + default: + radius_log_warn("%s: recv msg type=%d, not support\r\n", __FUNCTION__, msg[0]); + return -2; + } + + return 0; +} + +int radius_udp_msg_handling(BYTE *msg, int len, RADIUS_ADDR *addr, int nas_id) +{ + int i; + int pid; + int ret; + BYTE msg_code; + BYTE msg_type; + int msg_len; + BYTE identifier; + char auth_str[2] = ""; + char tmp_str[RADIUS_MAX_LEN_OF_TEMP_BUF] = ""; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH] = ""; + RADIUS_PID *pid_ptr; + RADIUS_NAS_INFO *nas_info_ptr; + int msg_auth_attr_offset = 0; + + msg_code = msg[0]; + + identifier = msg[1]; + + radius_log_send_recv_msg(msg, len, addr, msg_code, RADIUS_RECV_MSG_FLAG); + + if ((nas_info_ptr = radius_get_nas_info_ptr(nas_id)) == NULL) + { + radius_log_err("%s: nas id=%d\r\n", __FUNCTION__, nas_id); + return -1; + } + + if ((msg_len = ((msg[2] << 8) | msg[3])) > len) + { + radius_log_err("%s:msg=%s length is incorrect, recv msg len=%d, length in msg=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_code), len, msg_len); + return -1; + } + + if ((ret = radius_parse_attribute(msg, msg_len, &msg_auth_attr_offset)) < 0) + { + if (ret == -1) + radius_log_err("%s: parse msg=%s fail\r\n", __FUNCTION__, radius_get_msg_str( msg_code)); + + return -1; + } + + memcpy(authenticator, msg + 4, RADIUS_MAX_LEN_OF_AUTH);//authenticator begin from the 4th byte of msg + + if (msg_code == RADIUS_MSG_TYPE_ACCESS_REQUEST) + { + if (radius_authenticate_nas(authenticator, nas_info_ptr, &radius_msg_pdu.msg.access_request, msg, msg_len, msg_auth_attr_offset) < 0) + { + radius_log_err("%s: authenticate nas fail\r\n", __FUNCTION__); + return 0; + } + strcpy((char *)radius_msg_pdu.msg.access_request.secret, (char *)nas_info_ptr->share_key); + + // update chap authenticator + if (radius_msg_pdu.msg.access_request.chap_challenge.flag != 1) + { + memcpy(radius_msg_pdu.msg.access_request.chap_challenge.chap_challenge.value, + authenticator, RADIUS_MAX_LEN_OF_AUTH); + radius_msg_pdu.msg.access_request.chap_challenge.chap_challenge.length = RADIUS_MAX_LEN_OF_AUTH; + radius_msg_pdu.msg.access_request.chap_challenge.flag = 1; + } + } + + switch (msg_code) + { + case RADIUS_MSG_TYPE_ACCESS_REQUEST: + case RADIUS_MSG_TYPE_ACCOUNTING_REQUEST: + case RADIUS_MSG_TYPE_DISCONNECT_REQUEST: + msg_type = RADIUS_REQUEST_MSG; + + if ((pid = radius_match_response_pid(msg_code, identifier, authenticator)) >= 0) + { + radius_log_warn("%s: recv msg=%s, identifier=%d, already process by pid=%d\r\n", __FUNCTION__, radius_get_msg_str(msg_type), identifier, pid); + return 0; + } + break; + case RADIUS_MSG_TYPE_ACCESS_ACCEPT: + case RADIUS_MSG_TYPE_ACCESS_REJECT: + case RADIUS_MSG_TYPE_ACCESS_CHALLENGE: + case RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE: + case RADIUS_MSG_TYPE_DISCONNECT_ACK: + case RADIUS_MSG_TYPE_DISCONNECT_NAK: + msg_type = RADIUS_RESPONSE_MSG; + + if ((pid = radius_match_request_pid(msg_code, identifier, authenticator, msg, msg_len, nas_info_ptr->share_key)) < 0) + { + for (i = 0; i < RADIUS_MAX_LEN_OF_AUTH; i++) + { + sprintf(auth_str, "%02x", authenticator[i]); + strcat(tmp_str, auth_str); + } + radius_log_err("%s: identifier=%d, authenticator=%s\r\n", __FUNCTION__, identifier, tmp_str); + return -1; + } + break; + default: + radius_log_warn("%s: not support msg code=%d\r\n", __FUNCTION__, msg_code); + return -1; + } + + if (msg_type == RADIUS_REQUEST_MSG) + { + if ((pid = radius_get_pid()) < 0) + { + radius_log_err("%s: get pid fail\r\n", __FUNCTION__); + return -1; + } + } + + pid_ptr = radius_get_pid_ptr(pid); + + switch (msg_type) + { + case RADIUS_REQUEST_MSG: + pid_ptr->type = RADIUS_PID_TYPE_IND; + pid_ptr->trans_req_msg_type = msg_code; + memcpy(&pid_ptr->authenticator, authenticator, RADIUS_MAX_LEN_OF_AUTH); + pid_ptr->identifier = identifier; + pid_ptr->sap_index = nas_info_ptr->sap_index; + pid_ptr->nas_id = nas_id; + break; + } + + memcpy(&pid_ptr->peer_addr, addr, sizeof(RADIUS_ADDR)); + + pid_ptr->rv_msg_flag = msg_code; + + radius_log_event("%s: success! usr_pid=%d, pid=%d\r\n", __FUNCTION__, pid_ptr->usr_pid, pid); + + radius_p_fsm(pid); + + return 0; +} + +int radius_attr_parse_init() +{ + memset(radius_attr_parse_function, 0, sizeof(RADIUS_ATTR_PARSE_FUNCTION) * RADIUS_MAX_NUM_OF_ATTRIBUTE); + + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_USER_NAME].parse_function = radius_parse_attr_user_name; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_USER_PASSWORD].parse_function = radius_parse_attr_user_password; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CHAP_PASSWORD].parse_function = radius_parse_attr_chap_password; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_NAS_IP_ADDRESS].parse_function = radius_parse_attr_nas_ip_addr; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_NAS_PORT].parse_function = radius_parse_attr_nas_port; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_SERVICE_TYPE].parse_function = radius_parse_attr_service_type; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_PROTOCOL].parse_function = radius_parse_attr_framed_protocol; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_ADDR].parse_function = radius_parse_attr_framed_ip_addr; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_NETMASK].parse_function = radius_parse_attr_framed_ip_netmask; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTING].parse_function = radius_parse_attr_framed_routing; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FILTER_ID].parse_function = radius_parse_attr_filter_id; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_MTU].parse_function = radius_parse_attr_framed_mtu; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_COMPRESSION].parse_function = radius_parse_attr_framed_compression; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_LOGIN_IP_HOST].parse_function = radius_parse_attr_login_ip_host; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_LOGIN_SERVICE].parse_function = radius_parse_attr_login_service; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_LOGIN_TCP_PORT].parse_function = radius_parse_attr_login_tcp_port; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_REPLY_MESSAGE].parse_function = radius_parse_attr_reply_message; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CALLBACK_NUMBER].parse_function = radius_parse_attr_callback_number; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CALLBACK_ID].parse_function = radius_parse_attr_callback_id; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTE].parse_function = radius_parse_attr_framed_route; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_IPX_NETWORK].parse_function = radius_parse_attr_framed_ipx_network; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_STATE].parse_function = radius_parse_attr_state; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CLASS].parse_function = radius_parse_attr_class; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_VENDOR_SPECIFIC].parse_function = radius_parse_attr_vendor_specific; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_SESSION_TIMEOUT].parse_function = radius_parse_attr_session_timeout; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_IDLE_TIMEOUT].parse_function = radius_parse_attr_idle_timeout; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_TERMINATION_ACTION].parse_function = radius_parse_attr_termination_action; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID].parse_function = radius_parse_attr_called_station_id; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CALLING_STATION_ID].parse_function = radius_parse_attr_calling_station_id; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_NAS_IDENTIFIER].parse_function = radius_parse_attr_nas_identifier; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_PROXY_STATE].parse_function = radius_parse_attr_proxy_state; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_SERVICE].parse_function = radius_parse_attr_login_lat_service; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_NODE].parse_function = radius_parse_attr_login_lat_node; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_GROUP].parse_function = radius_parse_attr_login_lat_group; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_LINK].parse_function = radius_parse_attr_framed_appletalk_link; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_NETWORK].parse_function = radius_parse_attr_framed_appletalk_network; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_ZONE].parse_function = radius_parse_attr_framed_appletalk_zone; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_STATUS_TYPE].parse_function = radius_parse_attr_acct_status_type; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_DELAY_TIME].parse_function = radius_parse_attr_acct_delay_time; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_OCTETS].parse_function = radius_parse_attr_acct_input_octets; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_OCTETS].parse_function = radius_parse_attr_acct_output_octets; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_ID].parse_function = radius_parse_attr_acct_session_id; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_AUTHENTIC].parse_function = radius_parse_attr_acct_authentic; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_TIME].parse_function = radius_parse_attr_acct_session_time; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_PACKETS].parse_function = radius_parse_attr_acct_input_packets; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_PACKETS].parse_function = radius_parse_attr_acct_output_packets; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_TERMINATE_CAUSE].parse_function = radius_parse_attr_acct_terminate_cause; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_MULTI_SESSION_ID].parse_function = radius_parse_attr_acct_multi_session_id; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_LINK_COUNT].parse_function = radius_parse_attr_acct_link_count; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_EVENT_TIMESTAMP].parse_function = radius_parse_attr_event_timestamp; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CHAP_CHALLENGE].parse_function = radius_parse_attr_chap_challenge; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_NAS_PORT_TYPE].parse_function = radius_parse_attr_nas_port_type; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_PORT_LIMIT].parse_function = radius_parse_attr_port_limit; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_PORT].parse_function = radius_parse_attr_login_lat_port; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ARAP_PASSWORD].parse_function = radius_parse_attr_arap_password; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ARAP_FEATURES].parse_function = radius_parse_attr_arap_features; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ARAP_ZONE_ACCESS].parse_function = radius_parse_attr_arap_zone_access; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY].parse_function = radius_parse_attr_arap_security; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY_DATA].parse_function = radius_parse_attr_arap_security_data; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_PASSWORD_RETRY].parse_function = radius_parse_attr_password_retry; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_PROMPT].parse_function = radius_parse_attr_prompt; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CONNECT_INFO].parse_function = radius_parse_attr_connect_info; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_CONFIGURATION_TOKEN].parse_function = radius_parse_attr_configuration_token; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_EAP_MESSAGE].parse_function = radius_parse_attr_eap_message; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR].parse_function = radius_parse_attr_message_authenticator; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ARAP_CHALLENGE_RESPONSE].parse_function = radius_parse_attr_arap_challenge_response; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ACCT_INTERIM_INTERVAL].parse_function = radius_parse_attr_acct_interim_interval; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_NAS_PORT_ID].parse_function = radius_parse_attr_nas_port_id; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_FRAMED_POOL].parse_function = radius_parse_attr_framed_pool; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_ERROR_CAUSE].parse_function = radius_parse_attr_error_cause; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_NOWSMS_PREAUTH_TYPE].parse_function = radius_parse_attr_nowsms_preauth_type; + radius_attr_parse_function[RADIUS_ATTRIBUTE_TYPE_NOWSMS_COUNT_ID_SIZE].parse_function = radius_parse_attr_nowsms_count_id_size; + + return 0; +} + +int radius_generate_access_request_authenticator(BYTE *authenticator) +{ + struct timeval tv; + char tmp_str[RADIUS_MAX_LEN_OF_TEMP_BUF] = ""; + + gettimeofday(&tv, NULL); + + sprintf(tmp_str, "%lX%lX", tv.tv_sec, tv.tv_usec); + + radius_get_md5_hex((char*)authenticator, tmp_str, strlen(tmp_str)); + + return 0; +} + +int radius_encode_attr_user_name(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_USER_NAME *user_name) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)user_name->user_name.value)) == 0) + { + radius_log_err("%s: user name is null\r\n", __FUNCTION__); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_USER_NAME; + + memcpy(&tmp_flw_ptr[2], user_name->user_name.value, len); + + tmp_flw_ptr[1] = len + 2; + + return 0; +} + +void radius_update (RADIUS_ENCRYPT_USER_PASSWORD_CONTEXT *context, BYTE *inBuf, unsigned int inLen, BYTE *share_key) +{ + int i; + int mdi; + BYTE md5_result[RADIUS_MAX_LEN_MD5] = ""; + int share_key_len; + int in_len; + BYTE in[RADIUS_MAX_LEN_OF_TEMP_BUF] = ""; + BYTE md5[RADIUS_MAX_LEN_MD5]; + + share_key_len = strlen((char*)share_key); + + memcpy(in, share_key, share_key_len); + + in_len = share_key_len +RADIUS_MAX_LEN_MD5; + + /*compute number of bytes mod 16*/ + mdi = (int)((context->i[0] >> 3) & 0x0F); + + /*update number of bits*/ + if ((context->i[0] + ((DWORD)inLen << 3)) < context->i[0]) + context->i[1]++; + + context->i[0] += ((DWORD)inLen << 3); + context->i[1] += ((DWORD)inLen >> 29); + + while (inLen--) + { + /* add new character to buffer, increment mdi */ + context->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x10) + { + if (context->count == 0) + memcpy(in + share_key_len, context->result, RADIUS_MAX_LEN_MD5); + else + memcpy(in + share_key_len, &context->result[(context->count - 1) * RADIUS_MAX_LEN_MD5], RADIUS_MAX_LEN_MD5); + + if (++context->count > 8) + return; + + radius_get_md5_hex((char*)md5, (char*)in, in_len); + + for (i = 0; i < RADIUS_MAX_LEN_MD5; i++) + { + md5_result[i] = md5[i] ^ context->in[i]; + } + + memcpy(&context->result[(context->count - 1) * RADIUS_MAX_LEN_MD5], md5_result, RADIUS_MAX_LEN_MD5); + + context->result_len = context->count * RADIUS_MAX_LEN_MD5; + + mdi = 0; + } + } +} + +void radius_final (RADIUS_ENCRYPT_USER_PASSWORD_CONTEXT *context, BYTE *share_key) +{ + DWORD in[16]; + int mdi; + unsigned int padLen; + + /* save number of bits */ + in[14] = context->i[0]; + in[15] = context->i[1]; + + /* compute number of bytes mod 16 */ + mdi = (int)((context->i[0] >> 3) & 0x0F); + + if (mdi == 0) + return; + + /* pad out to 56 mod 64 */ + padLen = 16 - mdi; + + radius_update(context, USER_PASSWORD_PADDING, padLen, share_key); +} + +int radius_init_user_password_context(RADIUS_ENCRYPT_USER_PASSWORD_CONTEXT *context, BYTE *authenticator) +{ + memset(context, 0, sizeof(RADIUS_ENCRYPT_USER_PASSWORD_CONTEXT)); + + memcpy(context->result, authenticator, RADIUS_MAX_LEN_OF_AUTH); + + context->result_len = RADIUS_MAX_LEN_OF_AUTH; + + return 0; +} + +int radius_encrypt_user_password(BYTE *encrypt_password, BYTE *password, BYTE *authenticator, BYTE *share_key) +{ + int password_len; + RADIUS_ENCRYPT_USER_PASSWORD_CONTEXT encrypt_password_context; + + radius_init_user_password_context(&encrypt_password_context, authenticator); + + password_len = strlen((char*)password); + + radius_update(&encrypt_password_context, password, password_len, share_key); + + radius_final(&encrypt_password_context, share_key); + + memcpy(encrypt_password, encrypt_password_context.result, encrypt_password_context.result_len); + + return encrypt_password_context.result_len; +} + +int radius_encode_attr_user_password(const BYTE *flw_ptr, BYTE *user_password, BYTE *share_key, BYTE *authenticator) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + BYTE encrypt_password[RADIUS_MAX_LEN_OF_ENCRYPT_PASSWORD] = ""; + + if ((len = radius_encrypt_user_password(encrypt_password, user_password, authenticator, share_key)) < 0) + { + radius_log_err("%s: encrypt user password fail\r\n", __FUNCTION__); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_USER_PASSWORD; + + memcpy(&tmp_flw_ptr[2], encrypt_password, len); + + tmp_flw_ptr[1] = len + 2; + + return 0; +} + +int radius_encode_attr_chap_password(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CHAP_PASSWORD *chap_password) +{ + return 0; +} + +int radius_encode_attr_nas_ip_address(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NAS_IP_ADDRESS *nas_ip_address) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NAS_IP_ADDRESS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[5] = (nas_ip_address->nas_ip_addr.value >> 24) & 0xFF; + tmp_flw_ptr[4] = (nas_ip_address->nas_ip_addr.value >> 16) & 0xFF; + tmp_flw_ptr[3] = (nas_ip_address->nas_ip_addr.value >> 8) & 0xFF; + tmp_flw_ptr[2] = (nas_ip_address->nas_ip_addr.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_nas_port(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NAS_PORT *nas_port) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NAS_PORT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (nas_port->nas_port.value>> 24) & 0xFF; + tmp_flw_ptr[3] = (nas_port->nas_port.value>> 16) & 0xFF; + tmp_flw_ptr[4] = (nas_port->nas_port.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (nas_port->nas_port.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_service_type(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_SERVICE_TYPE *service_type) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_SERVICE_TYPE; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (service_type->service_type.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (service_type->service_type.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (service_type->service_type.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (service_type->service_type.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_framed_protocol(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_PROTOCOL *framed_protocol) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_PROTOCOL; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (framed_protocol->framed_protocol.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (framed_protocol->framed_protocol.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (framed_protocol->framed_protocol.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (framed_protocol->framed_protocol.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_framed_ip_addr(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_IP_ADDR *framed_ip_addr) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_ADDR; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[5] = (framed_ip_addr->framed_ip_addr.value >> 24) & 0xFF; + tmp_flw_ptr[4] = (framed_ip_addr->framed_ip_addr.value >> 16) & 0xFF; + tmp_flw_ptr[3] = (framed_ip_addr->framed_ip_addr.value >> 8) & 0xFF; + tmp_flw_ptr[2] = (framed_ip_addr->framed_ip_addr.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_framed_ip_netmask(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_IP_NETMASK *framed_ip_netmask) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_IP_NETMASK; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[5] = (framed_ip_netmask->framed_ip_netmask.value >> 24) & 0xFF; + tmp_flw_ptr[4] = (framed_ip_netmask->framed_ip_netmask.value >> 16) & 0xFF; + tmp_flw_ptr[3] = (framed_ip_netmask->framed_ip_netmask.value >> 8) & 0xFF; + tmp_flw_ptr[2] = (framed_ip_netmask->framed_ip_netmask.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_framed_routing(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_ROUTING *framed_routing) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTING; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (framed_routing->framed_routing.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (framed_routing->framed_routing.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (framed_routing->framed_routing.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (framed_routing->framed_routing.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_filter_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FILTER_ID *filter_id) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)filter_id->filter_id.value)) == 0) + { + radius_log_err("%s: filter id=%s is NULL\r\n", __FUNCTION__, filter_id->filter_id.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FILTER_ID; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], filter_id->filter_id.value, len); + + return 0; +} + +int radius_encode_filter_id(const BYTE *flw_ptr, RADIUS_FILTER_ID *filter_id) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((filter_id->num == 0) || (filter_id->num > RADIUS_MAX_NUM_OF_FILTER_ID)) + { + radius_log_err("%s: filter id num=%d\r\n", __FUNCTION__, filter_id->num); + return -1; + } + + for (i = 0; i < filter_id->num; i++) + { + if (radius_encode_attr_filter_id(tmp_flw_ptr, &filter_id->filter_id[i]) < 0) + { + radius_log_err("%s: encode attr filter id fail, filter num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_framed_mtu(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_MTU *framed_mtu) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_MTU; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (framed_mtu->framed_mtu.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (framed_mtu->framed_mtu.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (framed_mtu->framed_mtu.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (framed_mtu->framed_mtu.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_framed_compression(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_COMPRESSION *compression) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_COMPRESSION; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (compression->framed_compression.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (compression->framed_compression.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (compression->framed_compression.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (compression->framed_compression.value) & 0xFF; + + return 0; +} + +int radius_encode_framed_compression(const BYTE *flw_ptr, RADIUS_FRAMED_COMPRESSION *compression) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((compression->num == 0) || (compression->num > RADIUS_MAX_NUM_OF_FRAMED_COMPRESSION)) + { + radius_log_err("%s: framed compression num=%d\r\n", __FUNCTION__, compression->num); + return -1; + } + + for (i = 0; i < compression->num; i++) + { + if (radius_encode_attr_framed_compression(tmp_flw_ptr, &compression->framed_compression[i]) < 0) + { + radius_log_err("%s: encode attr framed compression fail, compression num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_login_ip_host(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_LOGIN_IP_HOST *login_ip_host) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_LOGIN_IP_HOST; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[5] = (login_ip_host->login_ip_host.value >> 24) & 0xFF; + tmp_flw_ptr[4] = (login_ip_host->login_ip_host.value >> 16) & 0xFF; + tmp_flw_ptr[3] = (login_ip_host->login_ip_host.value >> 8) & 0xFF; + tmp_flw_ptr[2] = (login_ip_host->login_ip_host.value) & 0xFF; + + return 0; +} + +int radius_encode_login_ip_host(const BYTE *flw_ptr, RADIUS_LOGIN_IP_HOST *login_ip_host) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((login_ip_host->num == 0) || (login_ip_host->num > RADIUS_MAX_NUM_OF_LOGIN_IP_HOST)) + { + radius_log_err("%s: login ip host num=%d\r\n", __FUNCTION__, login_ip_host->num); + return -1; + } + + for (i = 0; i < login_ip_host->num; i++) + { + if (radius_encode_attr_login_ip_host(tmp_flw_ptr, &login_ip_host->login_ip_host[i]) < 0) + { + radius_log_err("%s: encode attr login ip host fail, login ip host num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_login_service(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_LOGIN_SERVICE *login_service) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_LOGIN_SERVICE; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (login_service->login_service.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (login_service->login_service.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (login_service->login_service.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (login_service->login_service.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_login_tcp_port(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_LOGIN_TCP_PORT *login_tcp_port) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_LOGIN_TCP_PORT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (login_tcp_port->login_tcp_port.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (login_tcp_port->login_tcp_port.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (login_tcp_port->login_tcp_port.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (login_tcp_port->login_tcp_port.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_reply_message(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_REPLY_MESSAGE *reply_message) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)reply_message->reply_message.value)) == 0) + { + radius_log_err("%s: reply message=%s is NULL\r\n", __FUNCTION__, reply_message->reply_message.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_REPLY_MESSAGE; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], reply_message->reply_message.value, len); + + return 0; +} + +int radius_encode_reply_message(const BYTE *flw_ptr, RADIUS_REPLY_MESSAGE *reply_message) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((reply_message->num == 0) || (reply_message->num > RADIUS_MAX_NUM_OF_REPLY_MESSAGE)) + { + radius_log_err("%s: reply message num=%d\r\n", __FUNCTION__, reply_message->num); + return -1; + } + + for (i = 0; i < reply_message->num; i++) + { + if (radius_encode_attr_reply_message(tmp_flw_ptr, &reply_message->reply_message[i]) < 0) + { + radius_log_err("%s: encode attr reply message fail, reply message num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_callback_num(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CALLBACK_NUMBER *callback_num) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)callback_num->callback_number.value)) == 0) + { + radius_log_err("%s: callback num=%s is NULL\r\n", __FUNCTION__, callback_num->callback_number.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CALLBACK_NUMBER; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], callback_num->callback_number.value, len); + + return 0; +} + +int radius_encode_attr_callback_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CALLBACK_ID *callback_id) +{ + int len; + BYTE *tmp_flw_pt = (BYTE *)flw_ptr; + + if ((len = strlen((char*)callback_id->callback_id.value)) == 0) + { + radius_log_err("%s: callback id=%s is NULL\r\n", __FUNCTION__, callback_id->callback_id.value); + return -1; + } + + tmp_flw_pt[0] = RADIUS_ATTRIBUTE_TYPE_CALLBACK_ID; + + tmp_flw_pt[1] = len + 2; + + memcpy(&tmp_flw_pt[2], callback_id->callback_id.value, len); + + return 0; +} + +int radius_encode_attr_framed_route(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_ROUTE *route) +{ + int len; + BYTE *tmp_flw_pt = (BYTE *)flw_ptr; + + if ((len = strlen((char*)route->framed_route.value)) == 0) + { + radius_log_err("%s: framed rout=%s is NULL\r\n", __FUNCTION__, route->framed_route.value); + return -1; + } + + tmp_flw_pt[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_ROUTE; + + tmp_flw_pt[1] = len + 2; + + memcpy(&tmp_flw_pt[2], route->framed_route.value, len); + + return 0; +} + +int radius_encode_framed_route(const BYTE *flw_ptr, RADIUS_FRAMED_ROUTE *route) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((route->num == 0) || (route->num > RADIUS_MAX_NUM_OF_FRAMED_ROUTE)) + { + radius_log_err("%s: framed route num=%d\r\n", __FUNCTION__, route->num); + return -1; + } + + for (i = 0; i < route->num; i++) + { + if (radius_encode_attr_framed_route(tmp_flw_ptr, &route->framed_route[i]) < 0) + { + radius_log_err("%s: encode attr framed route fail, framed route num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_framed_ipx_network(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_IPX_NETWORK *framed_ipx_network) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_IPX_NETWORK; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (framed_ipx_network->framed_ipx_network.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (framed_ipx_network->framed_ipx_network.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (framed_ipx_network->framed_ipx_network.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (framed_ipx_network->framed_ipx_network.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_state(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_STATE *state) +{ + int len; + BYTE *tmp_flw_pt = (BYTE *)flw_ptr; + + if ((len = strlen((char*)state->state.value)) == 0) + { + radius_log_err("%s: state =%s is NULL\r\n", __FUNCTION__, state->state.value); + return -1; + } + + tmp_flw_pt[0] = RADIUS_ATTRIBUTE_TYPE_STATE; + + tmp_flw_pt[1] = len + 2; + + memcpy(&tmp_flw_pt[2], state->state.value, len); + + return 0; +} + +int radius_encode_attr_class(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CLASS *radius_class) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)radius_class->radius_class.value)) == 0) + { + radius_log_err("%s: radius class=%s is NULL", __FUNCTION__, radius_class->radius_class.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CLASS; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], radius_class->radius_class.value, len); + + return 0; +} + +int radius_encode_class(const BYTE *flw_ptr, RADIUS_CLASS *radius_class) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((radius_class->num == 0) || (radius_class->num > RADIUS_MAX_NUM_OF_CLASS)) + { + radius_log_err("%s: radius class num=%d\r\n", __FUNCTION__, radius_class->num); + return -1; + } + + for (i = 0; i < radius_class->num; i++) + { + if (radius_encode_attr_class(tmp_flw_ptr, &radius_class->radius_class[i]) < 0) + { + radius_log_err("%s: encode attr class fail, class num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_vendor_3gpp2_ppac_aic(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_AIC *aic) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAC_SUBTYPE_AIC; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (aic->aic >> 24) & 0xFF; + tmp_flw_ptr[3] = (aic->aic >> 16) & 0xFF; + tmp_flw_ptr[4] = (aic->aic >> 8) & 0xFF; + tmp_flw_ptr[5] = (aic->aic) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppac_sfs(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAC_SUB_ATTR_SFS *sfs) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAC_SUBTYPE_SFS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (sfs->sfs >> 24) & 0xFF; + tmp_flw_ptr[3] = (sfs->sfs >> 16) & 0xFF; + tmp_flw_ptr[4] = (sfs->sfs >> 8) & 0xFF; + tmp_flw_ptr[5] = (sfs->sfs) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppac(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC *ppac) +{ + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr + 2; + BYTE *tmp_flw_ptr1 = (BYTE *)flw_ptr; + + if (ppac->aic.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppac_aic(tmp_flw_ptr, &ppac->aic); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppac->sfs.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppac_sfs(tmp_flw_ptr, &ppac->sfs); + + len += tmp_flw_ptr[1]; + } + + tmp_flw_ptr1[0] = RADIUS_VENDOR_TYPE_3GPP2_PPAC; + + tmp_flw_ptr1[1] = len + 2; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_stc(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP2_STC *stc) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP2_STC; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (stc->stc >> 24) & 0xFF; + tmp_flw_ptr[3] = (stc->stc >> 16) & 0xFF; + tmp_flw_ptr[4] = (stc->stc >> 8) & 0xFF; + tmp_flw_ptr[5] = (stc->stc) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_qid(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_QID *qid) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_QID; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (qid->qid.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (qid->qid.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (qid->qid.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (qid->qid.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_vq(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQ *vq) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_VQ; + +/* tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (vq->vq.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (vq->vq.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (vq->vq.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (vq->vq.value) & 0xFF;*///for 3gpp2 + + tmp_flw_ptr[2] = RADIUS_ARICENT_VOLUME_INT; + tmp_flw_ptr[3] = 10; + tmp_flw_ptr[4] = (vq->vq.integer >> 56) & 0xFF; + tmp_flw_ptr[5] = (vq->vq.integer >> 48) & 0xFF; + tmp_flw_ptr[6] = (vq->vq.integer >> 40) & 0xFF; + tmp_flw_ptr[7] = (vq->vq.integer >> 32) & 0xFF; + tmp_flw_ptr[8] = (vq->vq.integer >> 24) & 0xFF; + tmp_flw_ptr[9] = (vq->vq.integer >> 16) & 0xFF; + tmp_flw_ptr[10] = (vq->vq.integer >> 8) & 0xFF; + tmp_flw_ptr[11] = (vq->vq.integer) & 0xFF; + + if (vq->vq.exponent == 0) + { + tmp_flw_ptr[1] = 12; + } + else + { + tmp_flw_ptr[12] = RADIUS_ARICENT_VOLUME_EXP; + tmp_flw_ptr[13] = 6; + tmp_flw_ptr[14] = (vq->vq.exponent >> 24) & 0xFF; + tmp_flw_ptr[15] = (vq->vq.exponent >> 16) & 0xFF; + tmp_flw_ptr[16] = (vq->vq.exponent >> 8) & 0xFF; + tmp_flw_ptr[17] = (vq->vq.exponent) & 0xFF; + + tmp_flw_ptr[1] = 18; + } + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_vqo(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VQO *vqo) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_VQO; + + tmp_flw_ptr[1] = 4; + + tmp_flw_ptr[2] = (vqo->vqo.value >> 8) & 0xFF; + tmp_flw_ptr[3] = (vqo->vqo.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_vt(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VT *vt) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_VT; + +/* tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (vt->vt.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (vt->vt.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (vt->vt.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (vt->vt.value) & 0xFF;*/ + + tmp_flw_ptr[2] = RADIUS_ARICENT_VOLUME_INT; + tmp_flw_ptr[3] = 10; + tmp_flw_ptr[4] = (vt->vt.integer >> 56) & 0xFF; + tmp_flw_ptr[5] = (vt->vt.integer >> 48) & 0xFF; + tmp_flw_ptr[6] = (vt->vt.integer >> 40) & 0xFF; + tmp_flw_ptr[7] = (vt->vt.integer >> 32) & 0xFF; + tmp_flw_ptr[8] = (vt->vt.integer >> 24) & 0xFF; + tmp_flw_ptr[9] = (vt->vt.integer >> 16) & 0xFF; + tmp_flw_ptr[10] = (vt->vt.integer >> 8) & 0xFF; + tmp_flw_ptr[11] = (vt->vt.integer) & 0xFF; + + if (vt->vt.exponent == 0) + { + tmp_flw_ptr[1] = 12; + } + else + { + tmp_flw_ptr[12] = RADIUS_ARICENT_VOLUME_EXP; + tmp_flw_ptr[13] = 6; + tmp_flw_ptr[14] = (vt->vt.exponent >> 24) & 0xFF; + tmp_flw_ptr[15] = (vt->vt.exponent >> 16) & 0xFF; + tmp_flw_ptr[16] = (vt->vt.exponent >> 8) & 0xFF; + tmp_flw_ptr[17] = (vt->vt.exponent) & 0xFF; + + tmp_flw_ptr[1] = 18; + } + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_vto(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_VTO *vto) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_VTO; + + tmp_flw_ptr[1] = 4; + + tmp_flw_ptr[2] = (vto->vto.value >> 8) & 0xFF; + tmp_flw_ptr[3] = (vto->vto.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_dq(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DQ *dq) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_DQ; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (dq->dq.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (dq->dq.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (dq->dq.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (dq->dq.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_dt(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_DT *dt) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_DT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (dt->dt.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (dt->dt.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (dt->dt.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (dt->dt.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_ur(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_UR *ur) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_UR; + + tmp_flw_ptr[1] = 4; + + tmp_flw_ptr[2] = (ur->ur.value >> 8) & 0xFF; + tmp_flw_ptr[3] = (ur->ur.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq_ps(const BYTE *flw_ptr, RADIUS_VENDOR_3GPP2_PPAQ_SUB_ATTR_PS *ps) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_3GPP2_PPAQ_SUBTYPE_PS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[5] = (ps->ps.value >> 24) & 0xFF; + tmp_flw_ptr[4] = (ps->ps.value >> 16) & 0xFF; + tmp_flw_ptr[3] = (ps->ps.value >> 8) & 0xFF; + tmp_flw_ptr[2] = (ps->ps.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_vendor_3gpp2_ppaq(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq) +{ + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr + 2; + BYTE *tmp_flw_ptr1 = (BYTE *)flw_ptr; + + if (ppaq->qid.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_qid(tmp_flw_ptr, &ppaq->qid); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->vq.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_vq(tmp_flw_ptr, &ppaq->vq); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->vqo.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_vqo(tmp_flw_ptr, &ppaq->vqo); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->vt.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_vt(tmp_flw_ptr, &ppaq->vt); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->vto.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_vto(tmp_flw_ptr, &ppaq->vto); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->dq.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_dq(tmp_flw_ptr, &ppaq->dq); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->dt.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_dt(tmp_flw_ptr, &ppaq->dt); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->ur.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_ur(tmp_flw_ptr, &ppaq->ur); + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (ppaq->ps.flag == 1) + { + radius_encode_attr_vendor_3gpp2_ppaq_ps(tmp_flw_ptr, &ppaq->ps); + + len += tmp_flw_ptr[1]; + } + + tmp_flw_ptr1[0] = RADIUS_VENDOR_TYPE_3GPP2_PPAQ; + + tmp_flw_ptr1[1] = len + 2; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_imsi(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_IMSI *imsi) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if (((len = strlen((char*)imsi->imsi)) < 3) || (len > 15)) + { + radius_log_err("%s:imsi=%s\r\n", __FUNCTION__, imsi->imsi); + return -1; + } + + memcpy(&tmp_flw_ptr[2], imsi->imsi, len); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_IMSI; + + tmp_flw_ptr[1] = len + 2; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_cid(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_CID *charing_id) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[2] = (charing_id->cid >> 24) & 0xFF; + tmp_flw_ptr[3] = (charing_id->cid >> 16) & 0xFF; + tmp_flw_ptr[4] = (charing_id->cid >> 8) & 0xFF; + tmp_flw_ptr[5] = (charing_id->cid) & 0xFF; + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_CHARGING_ID; + + tmp_flw_ptr[1] = 6; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_pdp_type(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_PDP_TYPE *pdp_type) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[2] = (pdp_type->pdp_type>> 24) & 0xFF; + tmp_flw_ptr[3] = (pdp_type->pdp_type>> 16) & 0xFF; + tmp_flw_ptr[4] = (pdp_type->pdp_type>> 8) & 0xFF; + tmp_flw_ptr[5] = (pdp_type->pdp_type) & 0xFF; + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_PDP_TYPE; + + tmp_flw_ptr[1] = 6; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_cg_addr(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_CG_ADDR *cg_addr) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[5] = (cg_addr->cg_addr>> 24) & 0xFF; + tmp_flw_ptr[4] = (cg_addr->cg_addr>> 16) & 0xFF; + tmp_flw_ptr[3] = (cg_addr->cg_addr>> 8) & 0xFF; + tmp_flw_ptr[2] = (cg_addr->cg_addr) & 0xFF; + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_CG_ADDR; + + tmp_flw_ptr[1] = 6; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_nqp(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_NQP *nqp) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if (((len = strlen((char*)nqp->nqp)) < 3) || (len > 25)) + { + radius_log_err("%s:nqp=%s\r\n", __FUNCTION__, nqp->nqp); + return -1; + } + + memcpy(&tmp_flw_ptr[2], nqp->nqp, len); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_NQP; + + tmp_flw_ptr[1] = len + 2; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_sgsn_addr(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_ADDR *sgsn_addr) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[5] = (sgsn_addr->sgsn_addr >> 24) & 0xFF; + tmp_flw_ptr[4] = (sgsn_addr->sgsn_addr >> 16) & 0xFF; + tmp_flw_ptr[3] = (sgsn_addr->sgsn_addr >> 8) & 0xFF; + tmp_flw_ptr[2] = (sgsn_addr->sgsn_addr) & 0xFF; + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_SGSN_ADDR; + + tmp_flw_ptr[1] = 6; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_ggsn_addr(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_ADDR *ggsn_addr) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[5] = (ggsn_addr->ggsn_addr >> 24) & 0xFF; + tmp_flw_ptr[4] = (ggsn_addr->ggsn_addr >> 16) & 0xFF; + tmp_flw_ptr[3] = (ggsn_addr->ggsn_addr>> 8) & 0xFF; + tmp_flw_ptr[2] = (ggsn_addr->ggsn_addr) & 0xFF; + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_GGSN_ADDR; + + tmp_flw_ptr[1] = 6; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_mcc_mnc(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_MCC_MNC *mcc_mnc) +{ + int mcc_len; + int mnc_len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((mcc_len = strlen((char*)mcc_mnc->mcc)) != RADIUS_MAX_LEN_OF_MCC) + { + radius_log_err("%s:mcc=%s\r\n", __FUNCTION__, mcc_mnc->mcc); + return -1; + } + + if (((mnc_len = strlen((char*)mcc_mnc->mnc)) < 2) || (mnc_len > RADIUS_MAX_LEN_OF_MNC)) + { + radius_log_err("%s:mnc=%s\r\n", __FUNCTION__, mcc_mnc->mnc); + return -1; + } + + memcpy(&tmp_flw_ptr[2], mcc_mnc->mcc, mcc_len); + + memcpy(&tmp_flw_ptr[2 + mcc_len], mcc_mnc->mnc, mnc_len); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_IMSI_MCC_MNC; + + tmp_flw_ptr[1] = mcc_len + mnc_len + 2; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_ggsn_mcc_mnc(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_GGSN_MCC_MNC *ggsn_mcc_mnc) +{ + int mcc_len; + int mnc_len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((mcc_len = strlen((char*)ggsn_mcc_mnc->mcc)) != RADIUS_MAX_LEN_OF_MCC) + { + radius_log_err("%s:mcc=%s\r\n", __FUNCTION__, ggsn_mcc_mnc->mcc); + return -1; + } + + if (((mnc_len = strlen((char*)ggsn_mcc_mnc->mnc)) < 2) || (mnc_len > RADIUS_MAX_LEN_OF_MNC)) + { + radius_log_err("%s:mnc=%s\r\n", __FUNCTION__, ggsn_mcc_mnc->mnc); + return -1; + } + + memcpy(&tmp_flw_ptr[2], ggsn_mcc_mnc->mcc, mcc_len); + + memcpy(&tmp_flw_ptr[2 + mcc_len], ggsn_mcc_mnc->mnc, mnc_len); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_GGSN_MCC_MNC; + + tmp_flw_ptr[1] = mcc_len + mnc_len + 2; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_nsapi(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_NSAPI *nsapi) +{ + BYTE ptr[1] = ""; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if (nsapi->nsapi > 15) + { + radius_log_err("%s: nsapi=%d\r\n", __FUNCTION__, nsapi->nsapi); + return -1; + } + + sprintf((char*)ptr, "%X", nsapi->nsapi); + + memcpy(&tmp_flw_ptr[2], ptr, 1); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_NSAPI; + + tmp_flw_ptr[1] = 3; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_ssi(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_SSI *ssi) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[2] = 0xFF; + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_SSI; + + tmp_flw_ptr[1] = 3; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_sm(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_SM *sm) +{ + BYTE ptr[1] = ""; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if (sm->sm > 15) + { + radius_log_err("%s: selection mode=%d\r\n", __FUNCTION__, sm->sm); + return -1; + } + + sprintf((char*)ptr, "%X", sm->sm); + + memcpy(&tmp_flw_ptr[2], ptr, 1); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_SM; + + tmp_flw_ptr[1] = 3; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_cc(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_CC *cc) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)cc->cc)) != 4) + { + radius_log_err("%s: cc=%s\r\n", __FUNCTION__, cc->cc); + return -1; + } + + memcpy(&tmp_flw_ptr[2], cc->cc, len); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_CC; + + tmp_flw_ptr[1] = len + 2; + + return 0; +} + +int radius_encode_attr_vendor_3gpp_sgsn_mcc_mnc(const BYTE *flw_ptr, RADIUS_VENDOR_ATTRIBUTE_3GPP_SGSN_MCC_MNC *sgsn_mcc_mnc) +{ + int mcc_len; + int mnc_len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((mcc_len = strlen((char*)sgsn_mcc_mnc->mcc)) != RADIUS_MAX_LEN_OF_MCC) + { + radius_log_err("%s:mcc=%s\r\n", __FUNCTION__, sgsn_mcc_mnc->mcc); + return -1; + } + + if (((mnc_len = strlen((char*)sgsn_mcc_mnc->mnc)) < 2) || (mnc_len > RADIUS_MAX_LEN_OF_MNC)) + { + radius_log_err("%s:mnc=%s\r\n", __FUNCTION__, sgsn_mcc_mnc->mnc); + return -1; + } + + memcpy(&tmp_flw_ptr[2], sgsn_mcc_mnc->mcc, mcc_len); + + memcpy(&tmp_flw_ptr[2 + mcc_len], sgsn_mcc_mnc->mnc, mnc_len); + + tmp_flw_ptr[0] = RADIUS_VENDOR_TYPE_3GPP_SGSN_MCC_MNC; + + tmp_flw_ptr[1] = mcc_len + mnc_len + 2; + + return 0; +} + +int radius_encode_attr_vendor_specific(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC *vendor_specific) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + DWORD vendor_id; + + switch (vendor_specific->vendor_type) + { + case RADIUS_VENDOR_TYPE_3GPP2_PPAC: + if (radius_encode_attr_vendor_3gpp2_ppac(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp2.ppac) < 0) + { + radius_log_err("%s: encode 3gpp2 ppac fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP2; + break; + case RADIUS_VENDOR_TYPE_3GPP2_STC: + if (radius_encode_attr_vendor_3gpp2_stc(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp2.stc) < 0) + { + radius_log_err("%s: encode 3gpp2 stc fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP2; + break; + case RADIUS_VENDOR_TYPE_3GPP2_PPAQ: + if (radius_encode_attr_vendor_3gpp2_ppaq(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp2.ppaq) < 0) + { + radius_log_err("%s: encode 3gpp2 ppaq fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP2; + break; + case RADIUS_VENDOR_TYPE_3GPP_IMSI: + if (radius_encode_attr_vendor_3gpp_imsi(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.imsi) < 0) + { + radius_log_err("%s: encode 3gpp imsi fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_CHARGING_ID: + if (radius_encode_attr_vendor_3gpp_cid(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.charging_id) < 0) + { + radius_log_err("%s: encode 3gpp charging id fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_PDP_TYPE: + if (radius_encode_attr_vendor_3gpp_pdp_type(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.pdp_type) < 0) + { + radius_log_err("%s: encode 3gpp pdp type fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_CG_ADDR: + if (radius_encode_attr_vendor_3gpp_cg_addr(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.cg_addr) < 0) + { + radius_log_err("%s: encode 3gpp cg addr fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_NQP: + if (radius_encode_attr_vendor_3gpp_nqp(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.negotiated_qos) < 0) + { + radius_log_err("%s: encode 3gpp negotiated qos profile fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_SGSN_ADDR: + if (radius_encode_attr_vendor_3gpp_sgsn_addr(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.sgsn_addr) < 0) + { + radius_log_err("%s: encode 3gpp sgsn addr fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_GGSN_ADDR: + if (radius_encode_attr_vendor_3gpp_ggsn_addr(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.ggsn_addr) < 0) + { + radius_log_err("%s: encode 3gpp ggsn addr fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_IMSI_MCC_MNC: + if (radius_encode_attr_vendor_3gpp_mcc_mnc(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.mcc_mnc) < 0) + { + radius_log_err("%s: encode 3gpp imsi mcc mnc fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_GGSN_MCC_MNC: + if (radius_encode_attr_vendor_3gpp_ggsn_mcc_mnc(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.ggsn_mcc_mnc) < 0) + { + radius_log_err("%s: encode 3gpp ggsn mcc mnc fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_NSAPI: + if (radius_encode_attr_vendor_3gpp_nsapi(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.nsapi) < 0) + { + radius_log_err("%s: encode 3gpp nsapi fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_SSI: + if (radius_encode_attr_vendor_3gpp_ssi(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.ssi) < 0) + { + radius_log_err("%s: encode 3gpp ssi fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_SM: + if (radius_encode_attr_vendor_3gpp_sm(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.sm) < 0) + { + radius_log_err("%s: encode 3gpp sm fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_CC: + if (radius_encode_attr_vendor_3gpp_cc(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.cc) < 0) + { + radius_log_err("%s: encode 3gpp cc fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + case RADIUS_VENDOR_TYPE_3GPP_SGSN_MCC_MNC: + if (radius_encode_attr_vendor_3gpp_sgsn_mcc_mnc(tmp_flw_ptr + 6, &vendor_specific->attribute_3gpp.sgsn_mcc_mnc) < 0) + { + radius_log_err("%s: encode 3gpp sgsn mcc mnc fail\r\n", __FUNCTION__); + return -1; + } + + vendor_id = RADIUS_VENDOR_ID_3GPP; + break; + default: + radius_log_err("%s: not support vendor type=%d\r\n", __FUNCTION__, vendor_specific->vendor_type); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_VENDOR_SPECIFIC; + + tmp_flw_ptr[1] = tmp_flw_ptr[7] + 6; + + tmp_flw_ptr[2] = (vendor_id >> 24) & 0xFF; + tmp_flw_ptr[3] = (vendor_id >> 16) & 0xFF; + tmp_flw_ptr[4] = (vendor_id >> 8) & 0xFF; + tmp_flw_ptr[5] = (vendor_id) & 0xFF; + + return 0; +} + +int radius_encode_vendor_specific(const BYTE *flw_ptr, RADIUS_VENDOR_SPECIFIC *vendor_specific) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((vendor_specific->num == 0) || (vendor_specific->num > RADIUS_MAX_NUM_OF_VENDOR_SPECIFIC)) + { + radius_log_err("%s: vendor specific num=%d\r\n", __FUNCTION__, vendor_specific->num); + return -1; + } + + for (i = 0; i < vendor_specific->num; i++) + { + if (radius_encode_attr_vendor_specific(tmp_flw_ptr, &vendor_specific->vendor_specific[i]) < 0) + { + radius_log_err("%s: encode vendor specific fail, vendor specific num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_session_timeout(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_SESSION_TIMEOUT *session_timeout) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_SESSION_TIMEOUT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (session_timeout->session_timeout.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (session_timeout->session_timeout.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (session_timeout->session_timeout.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (session_timeout->session_timeout.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_idle_timeout(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_IDLE_TIMEOUT *idle_timeout) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_IDLE_TIMEOUT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (idle_timeout->idle_timeout.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (idle_timeout->idle_timeout.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (idle_timeout->idle_timeout.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (idle_timeout->idle_timeout.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_termination_action(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_TERMINATION_ACTION *termiantion_action) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_TERMINATION_ACTION; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (termiantion_action->termination_action.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (termiantion_action->termination_action.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (termiantion_action->termination_action.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (termiantion_action->termination_action.value) & 0xFF; + + return 0; +} +/* +int radius_encode_attr_called_station_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CALLED_STATION_ID *called_station_id) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen(called_station_id->called_station_id.value)) == 0) + { + radius_log_err("%s: radius called station id=%s is NULL\r\n", __FUNCTION__, called_station_id->called_station_id.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], called_station_id->called_station_id.value, len); + + return 0; +} +int radius_encode_attr_nowsms_called_station_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NOWSMS_CALLED_STATION_ID *called_station_id) +{ + int i, num, offset; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr+2; + + if ((called_station_id->client.len == 0) || (called_station_id->client.len > 1300)) + { + radius_log_err("%s: client called station id len=%d\r\n", __FUNCTION__, called_station_id->client.len); + return -1; + } + num = called_station_id->client.len / 250; + offset = called_station_id->client.len % 250 + if(offset != 0) + num++; + + for (i = 0; i < num; i++) + { + if(i+1 == num) + { + tmp_flw_ptr[1] = offset; + } + else + tmp_flw_ptr[1] = 250; + memcpy(tmp_flw_ptr+2, &called_station_id->client.called_list[i*250], tmp_flw_ptr[1]); + tmp_flw_ptr[0] = i + 1; + len += tmp_flw_ptr[1]+2; + tmp_flw_ptr += tmp_flw_ptr[1]+2; + } + flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID; + flw_ptr[1] = len + 2; + + return len; +}*/ + +static int radius_encode_attr_called_list(const BYTE *flw_ptr, BYTE *called_list, BYTE length) +{ + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if(length == 0 || length > RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED) + { + radius_log_err("%s: radius called list split length = %d, max length is 250!\r\n", __FUNCTION__, length); + return -1; + } + memcpy(&tmp_flw_ptr[2], called_list, length); + len = length + 2; + tmp_flw_ptr[1] = len; + tmp_flw_ptr[0] = 0xFF; + + return len; +} +int radius_encode_attr_called_station_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CALLED_STATION_ID *called_station_id) +{ + int i, num, offset; + int len = 0, tmp_len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + BYTE *tmp_flw_ptr1, *called_list; + + if(called_station_id->option == 1) + { + if(called_station_id->called.server.num != 1) + { + radius_log_err("%s: radius server called station id max num=%d\r\n", __FUNCTION__, called_station_id->called.server.num); + return -1; + } + if((len = strlen((char*)called_station_id->called.server.called_station_id[0].value)) == 0) + { + radius_log_err("%s: radius server called station id=%s is NULL\r\n", __FUNCTION__, called_station_id->called.server.called_station_id[0].value); + return -1; + } + memcpy(&tmp_flw_ptr[2], called_station_id->called.server.called_station_id[0].value, len); + len += 2; + tmp_flw_ptr[1] = len; + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID; + } + else + { + called_list = called_station_id->called.client.called_list; + num = strlen((char*)called_list); + if((num <= 0) || (num > RADIUS_MAX_NUM_OF_NOWSMS_CALLED_LIST)) + { + radius_log_err("%s: radius called station id len=%d\r\n", __FUNCTION__, num); + return -1; + } + offset = num % RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED; + num = num / RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED; + if(offset != 0) + num++; + for(i = 0; i < num; i ++) + { + tmp_flw_ptr1 = tmp_flw_ptr + 2; + if((i+1) == num && offset != 0) + tmp_len = offset; + else + tmp_len = RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED; + if((tmp_len = radius_encode_attr_called_list(tmp_flw_ptr1, \ + called_list+i*RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED, tmp_len)) <= 0) + { + radius_log_err("%s: radius called list length err! i=%d\r\n", __FUNCTION__, i); + continue; + } + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CALLED_STATION_ID; + tmp_flw_ptr[1] = tmp_len + 3; + tmp_flw_ptr[tmp_len+2] = ((num<<4)&0xF0) | ((i+1)&0x0F); + len += tmp_flw_ptr[1]; + tmp_flw_ptr += tmp_flw_ptr[1]; +/* memcpy(tmp_flw_ptr1+2, &called_station_id->called.client.called_list[i*RADIUS_NOWSMS_MAX_LEN_OF_PER_CALLED], tmp_flw_ptr1[1]); + tmp_flw_ptr1[0] = 0xFF - i; //i + 1 + tmp_flw_ptr[1] = tmp_flw_ptr1[1] + 4; + len += tmp_flw_ptr1[1]+2; + tmp_flw_ptr1 += tmp_flw_ptr1[1]+2;*/ + } + if(tmp_flw_ptr1[1] == tmp_len) + { + tmp_flw_ptr1[tmp_len] = 0xFF; //end indicator + } + } + + return len; +} + + +int radius_encode_attr_calling_station_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CALLING_STATION_ID *calling_station_id) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)calling_station_id->calling_station_id.value)) == 0) + { + radius_log_err("%s: radius calling station id=%s is NULL\r\n", __FUNCTION__, calling_station_id->calling_station_id.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CALLING_STATION_ID; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], calling_station_id->calling_station_id.value, len); + + return 0; +} + +int radius_encode_attr_nas_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NAS_IDENTIFIER *nas_id) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)nas_id->nas_identifier.value)) == 0) + { + radius_log_err("%s: radius nas id=%s is NULL\r\n", __FUNCTION__, nas_id->nas_identifier.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NAS_IDENTIFIER; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], nas_id->nas_identifier.value, len); + + return 0; +} + +int radius_encode_attr_proxy_state(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_PROXY_STATE *proxy_state) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)proxy_state->proxy_state.value)) == 0) + { + radius_log_err("%s: radius proxy state=%s is NULL\r\n", __FUNCTION__, proxy_state->proxy_state.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_PROXY_STATE; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], proxy_state->proxy_state.value, len); + + return 0; +} + +int radius_encode_proxy_state(const BYTE *flw_ptr, RADIUS_PROXY_STATE *proxy_state) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((proxy_state->num == 0) || (proxy_state->num > RADIUS_MAX_NUM_OF_PROXY_STATE)) + { + radius_log_err("%s: proxy state num=%d\r\n", __FUNCTION__, proxy_state->num); + return -1; + } + + for (i = 0; i < proxy_state->num; i++) + { + if (radius_encode_attr_proxy_state(tmp_flw_ptr, &proxy_state->proxy_state[i]) < 0) + { + radius_log_err("%s: encode attr proxy state fail, proxy state num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_login_lat_service(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_LOGIN_LAT_SERVICE *login_lat_service) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)login_lat_service->login_lat_service.value)) == 0) + { + radius_log_err("%s: radius login lat service=%s is NULL\r\n", __FUNCTION__, login_lat_service->login_lat_service.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_SERVICE; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], login_lat_service->login_lat_service.value, len); + + return 0; +} + +int radius_encode_attr_login_lat_node(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_LOGIN_LAT_NODE *login_lat_node) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)login_lat_node->login_lat_node.value)) == 0) + { + radius_log_err("%s: radius login lat node=%s is NULL\r\n", __FUNCTION__, login_lat_node->login_lat_node.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_NODE; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], login_lat_node->login_lat_node.value, len); + + return 0; +} + +int radius_encode_attr_login_lat_group(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_LOGIN_LAT_GROUP *login_lat_group) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)login_lat_group->login_lat_group.value)) == 0) + { + radius_log_err("%s: radius login lat service=%s is NULL\r\n", __FUNCTION__, login_lat_group->login_lat_group.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_GROUP; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], login_lat_group->login_lat_group.value, len); + + return 0; +} + +int radius_encode_attr_framed_appletalk_link(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_APPLETALK_LINK *framed_appletalk_link) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_LINK; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (framed_appletalk_link->framed_appletalk_link.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (framed_appletalk_link->framed_appletalk_link.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (framed_appletalk_link->framed_appletalk_link.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (framed_appletalk_link->framed_appletalk_link.value) & 0xFF; + + return 0; +} +int radius_encode_attr_framed_appletalk_network(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_APPLETALK_NETWORK *framed_appletalk_network) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_NETWORK; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (framed_appletalk_network->framed_appletalk_network.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (framed_appletalk_network->framed_appletalk_network.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (framed_appletalk_network->framed_appletalk_network.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (framed_appletalk_network->framed_appletalk_network.value) & 0xFF; + + return 0; +} + +int radius_encode_framed_appletalk_network(const BYTE *flw_ptr, RADIUS_FRAMED_APPLETALK_NETWORK *framed_appletalk_network) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((framed_appletalk_network->num == 0) || (framed_appletalk_network->num > RADIUS_MAX_NUM_OF_FRAMED_APPLETALK_NETWORK)) + { + radius_log_err("%s: framed appletalk network num=%d\r\n", __FUNCTION__, framed_appletalk_network->num); + return -1; + } + + for (i = 0; i < framed_appletalk_network->num; i++) + { + if (radius_encode_attr_framed_appletalk_network(tmp_flw_ptr, &framed_appletalk_network->framed_appletalk_network[i]) < 0) + { + radius_log_err("%s: encode attr framed appletalk network fail, framed appletalk network num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_framed_appletalk_zone(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_FRAMED_APPLETALK_ZONE *framed_appletalk_zone) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)framed_appletalk_zone->framed_appletalk_zone.value)) == 0) + { + radius_log_err("%s: radius framed appletalk zone=%s is NULL\r\n", __FUNCTION__, framed_appletalk_zone->framed_appletalk_zone.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_FRAMED_APPLETALK_ZONE; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], framed_appletalk_zone->framed_appletalk_zone.value, len); + + return 0; +} + +int radius_encode_attr_acct_status_type(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_STATUS_TYPE *acct_status_type) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_STATUS_TYPE; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_status_type->acct_status_type.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_status_type->acct_status_type.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_status_type->acct_status_type.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_status_type->acct_status_type.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_delay_time(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_DELAY_TIME *acct_delay_time) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_DELAY_TIME; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_delay_time->acct_delay_time.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_delay_time->acct_delay_time.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_delay_time->acct_delay_time.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_delay_time->acct_delay_time.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_input_octets(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_INPUT_OCTETS *acct_input_octets) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_OCTETS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_input_octets->acct_input_octets.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_input_octets->acct_input_octets.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_input_octets->acct_input_octets.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_input_octets->acct_input_octets.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_output_octets(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_OUTPUT_OCTETS *acct_output_octets) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_OCTETS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_output_octets->acct_output_octets.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_output_octets->acct_output_octets.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_output_octets->acct_output_octets.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_output_octets->acct_output_octets.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_session_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_SESSION_ID *acct_session_id) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)acct_session_id->acct_session_id.value)) == 0) + { + radius_log_err("%s: radius acct seesion id=%s is NULL\r\n", __FUNCTION__, acct_session_id->acct_session_id.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_ID; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], acct_session_id->acct_session_id.value, len); + + return 0; +} + +int radius_encode_attr_acct_authentic(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_AUTHENTIC *acct_authentic) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_AUTHENTIC; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_authentic->acct_authentic.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_authentic->acct_authentic.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_authentic->acct_authentic.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_authentic->acct_authentic.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_session_time(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_SESSION_TIME *acct_session_time) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_SESSION_TIME; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_session_time->acct_session_time.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_session_time->acct_session_time.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_session_time->acct_session_time.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_session_time->acct_session_time.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_input_packets(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_INPUT_PACKETS *acct_input_packets) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_INPUT_PACKETS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_input_packets->acct_input_packets.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_input_packets->acct_input_packets.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_input_packets->acct_input_packets.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_input_packets->acct_input_packets.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_output_packets(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_OUTPUT_PACKETS *acct_output_packets) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_OUTPUT_PACKETS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_output_packets->acct_output_packets.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_output_packets->acct_output_packets.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_output_packets->acct_output_packets.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_output_packets->acct_output_packets.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_terminate_cause(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_TERMINATE_CAUSE *acct_terminate_cause) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_TERMINATE_CAUSE; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_terminate_cause->acct_terminate_cause.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_terminate_cause->acct_terminate_cause.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_terminate_cause->acct_terminate_cause.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_terminate_cause->acct_terminate_cause.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_acct_multi_session_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_MULTI_SESSION_ID *acct_multi_session_id) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)acct_multi_session_id->acct_multi_session_id.value)) == 0) + { + radius_log_err("%s: radius acct multi seesion id=%s is NULL\r\n", __FUNCTION__, acct_multi_session_id->acct_multi_session_id.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_MULTI_SESSION_ID; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], acct_multi_session_id->acct_multi_session_id.value, len); + + return 0; +} + +int radius_encode_acct_multi_session_id(const BYTE *flw_ptr, RADIUS_ACCT_MULTI_SESSION_ID *acct_multi_session_id) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((acct_multi_session_id->num == 0) || (acct_multi_session_id->num > RADIUS_MAX_NUM_OF_ACCT_MULTI_SESSION_ID)) + { + radius_log_err("%s: acct multi session id num=%d\r\n", __FUNCTION__, acct_multi_session_id->num); + return -1; + } + + for (i = 0; i < acct_multi_session_id->num; i++) + { + if (radius_encode_attr_acct_multi_session_id(tmp_flw_ptr, &acct_multi_session_id->acct_multi_session_id[i]) < 0) + { + radius_log_err("%s: encode attr acct multi session id fail, acct multi session id num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_acct_link_count(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_LINK_COUNT *acct_link_count) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_LINK_COUNT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_link_count->acct_link_count.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_link_count->acct_link_count.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_link_count->acct_link_count.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_link_count->acct_link_count.value) & 0xFF; + + return 0; +} + +int radius_encode_acct_link_count(const BYTE *flw_ptr, RADIUS_ACCT_LINK_COUNT *acct_link_count) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((acct_link_count->num == 0) || (acct_link_count->num > RADIUS_MAX_NUM_OF_ACCT_LINK_COUNT)) + { + radius_log_err("%s: acct link count num=%d\r\n", __FUNCTION__, acct_link_count->num); + return -1; + } + + for (i = 0; i < acct_link_count->num; i++) + { + if (radius_encode_attr_acct_link_count(tmp_flw_ptr, &acct_link_count->acct_link_count[i]) < 0) + { + radius_log_err("%s: encode attr acct link count fail, acct link count num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_event_timestamp(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_EVENT_TIMESTAMP *event_timestamp) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_EVENT_TIMESTAMP; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (event_timestamp->event_timestamp.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (event_timestamp->event_timestamp.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (event_timestamp->event_timestamp.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (event_timestamp->event_timestamp.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_chap_challenge(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CHAP_CHALLENGE *chap_challenge) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)chap_challenge->chap_challenge.value)) == 0) + { + radius_log_err("%s: radius chap challenge=%s is NULL\r\n", __FUNCTION__, chap_challenge->chap_challenge.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CHAP_CHALLENGE; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], chap_challenge->chap_challenge.value, len); + + return 0; +} + +int radius_encode_attr_nas_port_type(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NAS_PORT_TYPE *nas_port_type) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NAS_PORT_TYPE; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (nas_port_type->nas_port_type.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (nas_port_type->nas_port_type.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (nas_port_type->nas_port_type.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (nas_port_type->nas_port_type.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_port_limit(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_PORT_LIMIT *port_limit) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_PORT_LIMIT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (port_limit->port_limit.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (port_limit->port_limit.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (port_limit->port_limit.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (port_limit->port_limit.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_login_lat_port(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_LOGIN_LAT_PORT *login_lat_port) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)login_lat_port->login_lat_port.value)) == 0) + { + radius_log_err("%s: radius login lat port=%s is NULL\r\n", __FUNCTION__, login_lat_port->login_lat_port.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_LOGIN_LAT_PORT; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], login_lat_port->login_lat_port.value, len); + + return 0; +} + +int radius_encode_attr_arap_password(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ARAP_PASSWORD *arap_password) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)arap_password->arap_password.value)) == 0) + { + radius_log_err("%s: radius arap_password=%s is NULL\r\n", __FUNCTION__, arap_password->arap_password.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ARAP_PASSWORD; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], arap_password->arap_password.value, len); + + return 0; +} + +int radius_encode_attr_arap_feature(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ARAP_FEATURES *arap_feature) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)arap_feature->arap_features.value)) == 0) + { + radius_log_err("%s: radius arap_features=%s is NULL\r\n", __FUNCTION__, arap_feature->arap_features.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ARAP_FEATURES; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], arap_feature->arap_features.value, len); + + return 0; +} + +int radius_encode_attr_arap_zone_access(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ARAP_ZONE_ACCESS *arap_zone_access) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ARAP_ZONE_ACCESS; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (arap_zone_access->arap_zone_access.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (arap_zone_access->arap_zone_access.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (arap_zone_access->arap_zone_access.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (arap_zone_access->arap_zone_access.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_arap_security(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ARAP_SECURITY *arap_security) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (arap_security->arap_security.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (arap_security->arap_security.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (arap_security->arap_security.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (arap_security->arap_security.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_arap_security_data(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ARAP_SECURITY_DATA *arap_security_data) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = arap_security_data->arap_security_data.length) == 0) + { + radius_log_err("%s: radius arap security data length=%d is NULL\r\n", __FUNCTION__, arap_security_data->arap_security_data.length); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ARAP_SECURITY_DATA; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], arap_security_data->arap_security_data.value, len); + + return 0; +} + +int radius_encode_arap_security_data(const BYTE *flw_ptr, RADIUS_ARAP_SECURITY_DATA *arap_security_data) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((arap_security_data->num == 0) || (arap_security_data->num > RADIUS_MAX_NUM_OF_ARAP_SECURITY_DATA)) + { + radius_log_err("%s: arap security data num=%d\r\n", __FUNCTION__, arap_security_data->num); + return -1; + } + + for (i = 0; i < arap_security_data->num; i++) + { + if (radius_encode_attr_arap_security_data(tmp_flw_ptr, &arap_security_data->arap_security_data[i]) < 0) + { + radius_log_err("%s: encode attr arap security data fail, arap security data num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_password_retry(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_PASSWORD_RETRY *password_retry) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_PASSWORD_RETRY; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (password_retry->password_retry.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (password_retry->password_retry.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (password_retry->password_retry.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (password_retry->password_retry.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_prompt(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_PROMPT *prompt) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_PROMPT; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (prompt->prompt.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (prompt->prompt.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (prompt->prompt.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (prompt->prompt.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_connect_info(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CONNECT_INFO *connect_info) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)connect_info->connect_info.value)) == 0) + { + radius_log_err("%s: radius connect info=%s is NULL\r\n", __FUNCTION__, connect_info->connect_info.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CONNECT_INFO; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], connect_info->connect_info.value, len); + + return 0; +} + +int radius_encode_attr_configuration_token(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_CONFIGURATION_TOKEN *configuration_token) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)configuration_token->configuration_token.value)) == 0) + { + radius_log_err("%s: radius configuration token=%s is NULL\r\n", __FUNCTION__, configuration_token->configuration_token.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_CONFIGURATION_TOKEN; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], configuration_token->configuration_token.value, len); + + return 0; +} + +int radius_encode_configuration_token(const BYTE *flw_ptr, RADIUS_CONFIGURATION_TOKEN *configuration_token) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((configuration_token->num == 0) || (configuration_token->num > RADIUS_MAX_NUM_OF_CONFIGURATION_TOKEN)) + { + radius_log_err("%s: configuration token num=%d\r\n", __FUNCTION__, configuration_token->num); + return -1; + } + + for (i = 0; i < configuration_token->num; i++) + { + if (radius_encode_attr_configuration_token(tmp_flw_ptr, &configuration_token->configuration_token[i]) < 0) + { + radius_log_err("%s: encode attr configuration token fail, configuration token num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +/*int radius_encode_attr_message_authenticator(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_MESSAGE_AUTHENTICATOR *message_authenticator) +{ + int len; + BYTE *tmp_flw_ptr = flw_ptr; + + if ((len = strlen(configuration_token->configuration_token.value)) == 0) + { + radius_log_err("%s: radius configuration token=%s is NULL\r\n", __FUNCTION__, configuration_token->configuration_token.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], message_authenticator->configuration_token.value, len); + + return 0; +}*/ + +int radius_encode_attr_acct_interim_interval(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ACCT_INTERIM_INTERVAL *acct_interim_interval) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ACCT_INTERIM_INTERVAL; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (acct_interim_interval->acct_interim_interval.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (acct_interim_interval->acct_interim_interval.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (acct_interim_interval->acct_interim_interval.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (acct_interim_interval->acct_interim_interval.value) & 0xFF; + + return 0; +} + +int radius_encode_attr_nas_port_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NAS_PORT_ID *nas_port_id) +{ + int len; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((len = strlen((char*)nas_port_id->nas_port_id.value)) == 0) + { + radius_log_err("%s: radius nas port id=%s is NULL\r\n", __FUNCTION__, nas_port_id->nas_port_id.value); + return -1; + } + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NAS_PORT_ID; + + tmp_flw_ptr[1] = len + 2; + + memcpy(&tmp_flw_ptr[2], nas_port_id->nas_port_id.value, len); + + return 0; +} + +int radius_encode_attr_error_cause(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_ERROR_CAUSE *error_cause) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_ERROR_CAUSE; + + tmp_flw_ptr[1] = 6; + + tmp_flw_ptr[2] = (error_cause->error_cause.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (error_cause->error_cause.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (error_cause->error_cause.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (error_cause->error_cause.value) & 0xFF; + + return 0; +} + +int radius_encode_error_cause(const BYTE *flw_ptr, RADIUS_ERROR_CAUSE *error_cause) +{ + int i; + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + if ((error_cause->num == 0) || (error_cause->num > RADIUS_MAX_NUM_OF_ARAP_SECURITY_DATA)) + { + radius_log_err("%s: error cause num=%d\r\n", __FUNCTION__, error_cause->num); + return -1; + } + + for (i = 0; i < error_cause->num; i++) + { + if (radius_encode_attr_error_cause(tmp_flw_ptr, &error_cause->error_cause[i]) < 0) + { + radius_log_err("%s: encode attr error cause fail, error cause num=%d\r\n", __FUNCTION__, i); + return -1; + } + + len += tmp_flw_ptr[1]; + + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + return len; +} + +int radius_encode_attr_message_authenticator(BYTE *msg, const BYTE *flw_ptr, BYTE *share_key) +{ + int len = 0; + BYTE message_auth[16] = ""; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_MESSAGE_AUTHENTICATOR; + + tmp_flw_ptr[1] = RADIUS_MAX_LEN_OF_MESSAGE_AUTH_ATTR + 2; + + memset(tmp_flw_ptr + 2, 0, RADIUS_MAX_LEN_OF_MESSAGE_AUTH_ATTR); + + len = tmp_flw_ptr + 18 - msg; + + msg[2] = (len >> 8) & 0xFF; + msg[3] = (len) & 0xFF; + + radius_get_hmac_md5_hex(message_auth, msg, len, share_key, strlen((char*)share_key)); + + memcpy(tmp_flw_ptr + 2, message_auth, RADIUS_MAX_LEN_OF_MESSAGE_AUTH_ATTR); + + return 0; +} + +/* +int radius_encode_attr_nowsms_preauth_type(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NOWSMS_PREAUTH_TYPE *pre_auth_type) +{ + int len = 0; + BYTE *tmp_flw_ptr = (BYTE*)flw_ptr; + + if((len = strlen(pre_auth_type->pre_auth_type.value)) == 0) + { + radius_log_err("%s: radius nowsms pre auth type=%s is NULL\r\n", __FUNCTION__, pre_auth_type->pre_auth_type.value); + return -1; + } + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NOWSMS_PREAUTH_TYPE; + tmp_flw_ptr[1] = len + 4; + tmp_flw_ptr[2] = pre_auth_type->pre_auth_type.type; + tmp_flw_ptr[3] = len + 2; + + memcpy(&tmp_flw_ptr[4], pre_auth_type->pre_auth_type.value, len); + + return 0; +}*/ +int radius_encode_attr_nowsms_preauth_type(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NOWSMS_PREAUTH_TYPE *pre_auth_type) +{ +// int len = 0; + BYTE *tmp_flw_ptr = (BYTE*)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NOWSMS_PREAUTH_TYPE; + tmp_flw_ptr[1] = 3; + tmp_flw_ptr[2] = pre_auth_type->pre_auth_type.value & 0xFF; + + return 0; +} + +static int radius_encode_attr_nowsms_msg_count(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NOWSMS_MSG_COUNT *msg_count) +{ + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGCOUNT; + tmp_flw_ptr[1] = 3; + tmp_flw_ptr[2] = msg_count->msg_count.value & 0xFF; + + return 0; +} +static int radius_encode_attr_nowsms_msg_id(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NOWSMS_MSG_ID *msg_id) +{ + BYTE *tmp_flw_ptr= (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_MSGID; + tmp_flw_ptr[1] = 6; + tmp_flw_ptr[2] = (msg_id->msg_id.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (msg_id->msg_id.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (msg_id->msg_id.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (msg_id->msg_id.value) & 0xFF; + + return 0; +} +static int radius_encode_attr_nowsms_size(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NOWSMS_SIZE *size) +{ + BYTE *tmp_flw_ptr= (BYTE *)flw_ptr; + + tmp_flw_ptr[0] = RADIUS_ATTRIBUTE_TYPE_NOWSMS_SUB_SIZE; + tmp_flw_ptr[1] = 6; + tmp_flw_ptr[2] = (size->size.value >> 24) & 0xFF; + tmp_flw_ptr[3] = (size->size.value >> 16) & 0xFF; + tmp_flw_ptr[4] = (size->size.value >> 8) & 0xFF; + tmp_flw_ptr[5] = (size->size.value) & 0xFF; + + return 0; +} +int radius_encode_attr_nowsms_count_id_size(const BYTE *flw_ptr, RADIUS_ATTRIBUTE_NOWSMS_COUNT_ID_SIZE *count_id_size) +{ + int len = 0; + BYTE *tmp_flw_ptr = (BYTE *)flw_ptr + 2; + BYTE *tmp_flw_ptr1 = (BYTE *)flw_ptr; + + if(count_id_size->msg_count.flag == 1) + { + radius_encode_attr_nowsms_msg_count(tmp_flw_ptr, &count_id_size->msg_count); + len += tmp_flw_ptr[1]; + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if (count_id_size->msg_id.flag == 1) + { + radius_encode_attr_nowsms_msg_id(tmp_flw_ptr, &count_id_size->msg_id); + len += tmp_flw_ptr[1]; + tmp_flw_ptr += tmp_flw_ptr[1]; + } + + if(count_id_size->size.flag == 1) + { + radius_encode_attr_nowsms_size(tmp_flw_ptr, &count_id_size->size); + len += tmp_flw_ptr[1]; + } + + tmp_flw_ptr1[0] = RADIUS_ATTRIBUTE_TYPE_NOWSMS_COUNT_ID_SIZE; + tmp_flw_ptr1[1] = len + 2; + + return 0; +} + +int radius_encode_access_request(BYTE sap_index, BYTE *identifier, BYTE *authenticator, BYTE *msg, RADIUS_ACCESS_REQUEST *access_request, int nas_id) +{ + int msg_len = 0; + int len; + BYTE id = radius_access_id_select; + BYTE *flw_ptr = msg; + RADIUS_NAS_INFO *nas_info_ptr; + + if ((identifier == NULL) || (authenticator == NULL) || (msg == NULL) || (access_request == NULL)) + { + radius_log_err("%s: pointer error\r\n", __FUNCTION__); + return -1; + } + + if (((access_request->user_password.flag != 1) && (access_request->message_authenticator.flag != 1) \ + && (access_request->chap_password.flag != 1) && (access_request->state.flag != 1)) + || ((access_request->user_password.flag == 1) && (access_request->message_authenticator.flag == 1) \ + && (access_request->chap_password.flag == 1))) + { + radius_log_err("%s: attribute error\r\n", __FUNCTION__); + return -1; + } + + if (((nas_info_ptr = radius_get_nas_info_ptr(nas_id)) == NULL) || (nas_info_ptr->flag != 1)) + { + radius_log_err("%s: nas id=%d error\r\n", __FUNCTION__, nas_id); + return -1; + } + + flw_ptr[0] = RADIUS_MSG_TYPE_ACCESS_REQUEST; + + *identifier = id; + + flw_ptr[1] = id; + + flw_ptr += 4; + + radius_generate_access_request_authenticator(authenticator); + + memcpy(flw_ptr, authenticator, RADIUS_MAX_LEN_OF_AUTH); + + flw_ptr += RADIUS_MAX_LEN_OF_AUTH; + + if (access_request->user_name.flag == 1) + { + if (radius_encode_attr_user_name(flw_ptr, &access_request->user_name) < 0) + { + radius_log_err("%s: encode user name fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->user_password.flag == 1) + { + //if (radius_encode_attr_user_password(flw_ptr, radius_nas_password[sap_index], radius_nas_share_key[sap_index], authenticator) < 0)//&access_request->user_password + if (radius_encode_attr_user_password(flw_ptr, nas_info_ptr->password, nas_info_ptr->share_key, authenticator) < 0) + { + radius_log_err("%s: encode user password fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + +/* if (access_request->chap_password.flag == 1) + { + if ((radius_encode_attr_chap_password(flw_ptr, &access_request->chap_password) < 0) + { + radius_log_err("%s: encode chap password fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + }*/ + + if (access_request->nas_ip_addr.flag == 1) + { + if (radius_encode_attr_nas_ip_address(flw_ptr, &access_request->nas_ip_addr) < 0) + { + radius_log_err("%s: encode nas ip address fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->nas_port.flag == 1) + { + if (radius_encode_attr_nas_port(flw_ptr, &access_request->nas_port) < 0) + { + radius_log_err("%s: encode nas port fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->service_type.flag == 1) + { + if (radius_encode_attr_service_type(flw_ptr, &access_request->service_type) < 0) + { + radius_log_err("%s: encode service type fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->framed_protocol.flag == 1) + { + if (radius_encode_attr_framed_protocol(flw_ptr, &access_request->framed_protocol) < 0) + { + radius_log_err("%s: encode framed protocol fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->framed_ip_addr.flag == 1) + { + if (radius_encode_attr_framed_ip_addr(flw_ptr, &access_request->framed_ip_addr) < 0) + { + radius_log_err("%s: encode framed ip addr fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->framed_ip_netmask.flag == 1) + { + if (radius_encode_attr_framed_ip_netmask(flw_ptr, &access_request->framed_ip_netmask) < 0) + { + radius_log_err("%s: encode framed ip netmask fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->framed_mtu.flag == 1) + { + if (radius_encode_attr_framed_mtu(flw_ptr, &access_request->framed_mtu) < 0) + { + radius_log_err("%s: encode framed ip mtu fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->framed_compression.num != 0) + { + if ((len = radius_encode_framed_compression(flw_ptr, &access_request->framed_compression)) < 0) + { + radius_log_err("%s: encode framed compression fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_request->login_ip_host.num != 0) + { + if ((len = radius_encode_login_ip_host(flw_ptr, &access_request->login_ip_host)) < 0) + { + radius_log_err("%s: encode login ip host fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_request->callback_number.flag == 1) + { + if (radius_encode_attr_callback_num(flw_ptr, &access_request->callback_number) < 0) + { + radius_log_err("%s: encode framed ip mtu fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->state.flag == 1) + { + if (radius_encode_attr_state(flw_ptr, &access_request->state) < 0) + { + radius_log_err("%s: encode state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->vendor_specific.num != 0) + { + if ((len = radius_encode_vendor_specific(flw_ptr, &access_request->vendor_specific)) < 0) + { + radius_log_err("%s: encode vendor specific fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + //if (access_request->called_station_id.flag == 1) + if (access_request->called_station_id.option == 1 || access_request->called_station_id.option == 2) + { + if ((len = radius_encode_attr_called_station_id(flw_ptr, &access_request->called_station_id)) < 0) + { + radius_log_err("%s: encode called station id fail\r\n", __FUNCTION__); + return -1; + } + + //flw_ptr += flw_ptr[1]; + flw_ptr += len; + } + + if (access_request->calling_station_id.flag == 1) + { + if (radius_encode_attr_calling_station_id(flw_ptr, &access_request->calling_station_id) < 0) + { + radius_log_err("%s: encode calling station id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->nas_identifier.flag == 1) + { + if (radius_encode_attr_nas_id(flw_ptr, &access_request->nas_identifier) < 0) + { + radius_log_err("%s: encode nas id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->proxy_state.num != 0) + { + if ((len = radius_encode_proxy_state(flw_ptr, &access_request->proxy_state)) < 0) + { + radius_log_err("%s: encode proxy state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_request->login_lat_service.flag == 1) + { + if (radius_encode_attr_login_lat_service(flw_ptr, &access_request->login_lat_service) < 0) + { + radius_log_err("%s: encode login lat service fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->login_lat_node.flag == 1) + { + if (radius_encode_attr_login_lat_node(flw_ptr, &access_request->login_lat_node) < 0) + { + radius_log_err("%s: encode login lat node fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->login_lat_group.flag == 1) + { + if (radius_encode_attr_login_lat_group(flw_ptr, &access_request->login_lat_group) < 0) + { + radius_log_err("%s: encode login lat group fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->nas_port_type.flag == 1) + { + if (radius_encode_attr_nas_port_type(flw_ptr, &access_request->nas_port_type) < 0) + { + radius_log_err("%s: encode nas port type fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->port_limit.flag == 1) + { + if (radius_encode_attr_port_limit(flw_ptr, &access_request->port_limit) < 0) + { + radius_log_err("%s: encode port limit fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->login_lat_port.flag == 1) + { + if (radius_encode_attr_login_lat_port(flw_ptr, &access_request->login_lat_port) < 0) + { + radius_log_err("%s: encode login lat port fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->connect_info.flag == 1) + { + if (radius_encode_attr_connect_info(flw_ptr, &access_request->connect_info) < 0) + { + radius_log_err("%s: encode connect info fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_request->nas_port_id.flag == 1) + { + if (radius_encode_attr_nas_port_id(flw_ptr, &access_request->nas_port_id) < 0) + { + radius_log_err("%s: encode nas port id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if(access_request->pre_auth_type.flag == 1) + { + if(radius_encode_attr_nowsms_preauth_type(flw_ptr, &access_request->pre_auth_type) < 0) + { + radius_log_err("%s: encode nowsms pre auth type fail\r\n", __FUNCTION__); + return -1; + } + flw_ptr += flw_ptr[1]; + } + + if(access_request->count_id_size.flag == 1) + { + if(radius_encode_attr_nowsms_count_id_size(flw_ptr, &access_request->count_id_size) < 0) + { + radius_log_err("%s: encode nowsms count id size fail\r\n", __FUNCTION__); + return -1; + } + flw_ptr += flw_ptr[1]; + } + + if (access_request->message_authenticator.flag == 1) + { + //if (radius_encode_attr_message_authenticator(msg, flw_ptr, radius_nas_share_key[sap_index]) < 0) + if (radius_encode_attr_message_authenticator(msg, flw_ptr, nas_info_ptr->share_key) < 0) + { + radius_log_err("%s: encode message authenticator fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if(access_request->acct_session_id.flag == 1) + { + if(radius_encode_attr_acct_session_id(flw_ptr, &access_request->acct_session_id) < 0) + { + radius_log_err("%s: encode acct session id fail\r\n", __FUNCTION__); + return -1; + } + flw_ptr += flw_ptr[1]; + } + + msg_len = flw_ptr - msg; + + msg[2] = (msg_len >> 8) & 0xFF; + msg[3] = (msg_len) & 0xFF; + + ++radius_access_id_select; + + return msg_len; +} + +int radius_encode_access_accept(BYTE identifier, BYTE *request_authenticator, BYTE *msg, RADIUS_ACCESS_ACCEPT *access_accept, int nas_id) +{ + int len; + int msg_len = 0; + BYTE *flw_ptr = msg; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH] = ""; + RADIUS_NAS_INFO *nas_info_ptr; + + if ((request_authenticator == NULL) || (msg == NULL) || (access_accept == NULL)) + { + radius_log_err("%s: pointer error\r\n", __FUNCTION__); + return -1; + } + + if (((nas_info_ptr = radius_get_nas_info_ptr(nas_id)) == NULL) || (nas_info_ptr->flag != 1)) + { + radius_log_err("%s: nas id=%d error\r\n", __FUNCTION__, nas_id); + return -1; + } + + flw_ptr[0] = RADIUS_MSG_TYPE_ACCESS_ACCEPT; + + flw_ptr[1] = identifier; + + flw_ptr += 4; + + memcpy(flw_ptr, request_authenticator, RADIUS_MAX_LEN_OF_AUTH); + + flw_ptr += RADIUS_MAX_LEN_OF_AUTH; + + if (access_accept->user_name.flag == 1) + { + if (radius_encode_attr_user_name(flw_ptr, &access_accept->user_name) < 0) + { + radius_log_err("%s: encode user name fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->service_type.flag == 1) + { + if (radius_encode_attr_service_type(flw_ptr, &access_accept->service_type) < 0) + { + radius_log_err("%s: encode service type fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_protocol.flag == 1) + { + if (radius_encode_attr_framed_protocol(flw_ptr, &access_accept->framed_protocol) < 0) + { + radius_log_err("%s: encode framed protocol fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_ip_addr.flag == 1) + { + if (radius_encode_attr_framed_ip_addr(flw_ptr, &access_accept->framed_ip_addr) < 0) + { + radius_log_err("%s: encode framed ip addr fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_ip_netmask.flag == 1) + { + if (radius_encode_attr_framed_ip_netmask(flw_ptr, &access_accept->framed_ip_netmask) < 0) + { + radius_log_err("%s: encode framed ip netmask fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_routing.flag == 1) + { + if (radius_encode_attr_framed_routing(flw_ptr, &access_accept->framed_routing) < 0) + { + radius_log_err("%s: encode framed routing fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->filter_id.num != 0) + { + if ((len = radius_encode_filter_id(flw_ptr, &access_accept->filter_id)) < 0) + { + radius_log_err("%s: encode filter id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->framed_mtu.flag == 1) + { + if (radius_encode_attr_framed_mtu(flw_ptr, &access_accept->framed_mtu) < 0) + { + radius_log_err("%s: encode framed mtu fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_compression.num != 0) + { + if ((len = radius_encode_framed_compression(flw_ptr, &access_accept->framed_compression)) < 0) + { + radius_log_err("%s: encode framed compression fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->login_ip_host.num != 0) + { + if ((len = radius_encode_login_ip_host(flw_ptr, &access_accept->login_ip_host)) < 0) + { + radius_log_err("%s: encode login ip host fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->login_service.flag == 1) + { + if (radius_encode_attr_login_service(flw_ptr, &access_accept->login_service) < 0) + { + radius_log_err("%s: encode framed login service fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->login_tcp_port.flag == 1) + { + if (radius_encode_attr_login_tcp_port(flw_ptr, &access_accept->login_tcp_port) < 0) + { + radius_log_err("%s: encode framed login tcp port fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->reply_message.num != 0) + { + if ((len = radius_encode_reply_message(flw_ptr, &access_accept->reply_message)) < 0) + { + radius_log_err("%s: encode reply message fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->callback_number.flag == 1) + { + if (radius_encode_attr_callback_num(flw_ptr, &access_accept->callback_number) < 0) + { + radius_log_err("%s: encode callback number fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->callback_id.flag == 1) + { + if (radius_encode_attr_callback_id(flw_ptr, &access_accept->callback_id) < 0) + { + radius_log_err("%s: encode callback id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_route.num != 0) + { + if ((len = radius_encode_framed_route(flw_ptr, &access_accept->framed_route)) < 0) + { + radius_log_err("%s: encode framed route fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->framed_ipx_network.flag == 1) + { + if (radius_encode_attr_framed_ipx_network(flw_ptr, &access_accept->framed_ipx_network) < 0) + { + radius_log_err("%s: encode framed ipx network fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->state.flag == 1) + { + if (radius_encode_attr_state(flw_ptr, &access_accept->state) < 0) + { + radius_log_err("%s: encode state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->radius_class.num != 0) + { + if ((len = radius_encode_class(flw_ptr, &access_accept->radius_class)) < 0) + { + radius_log_err("%s: encode class fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->vendor_specific.num != 0) + { + if ((len = radius_encode_vendor_specific(flw_ptr, &access_accept->vendor_specific)) < 0) + { + radius_log_err("%s: encode vendor specific fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->session_timeout.flag == 1) + { + if (radius_encode_attr_session_timeout(flw_ptr, &access_accept->session_timeout) < 0) + { + radius_log_err("%s: encode session timeout fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->idle_timeout.flag == 1) + { + if (radius_encode_attr_idle_timeout(flw_ptr, &access_accept->idle_timeout) < 0) + { + radius_log_err("%s: encode idle timeout fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->termination_action.flag == 1) + { + if (radius_encode_attr_termination_action(flw_ptr, &access_accept->termination_action) < 0) + { + radius_log_err("%s: encode termination action fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->proxy_state.num != 0) + { + if ((len = radius_encode_proxy_state(flw_ptr, &access_accept->proxy_state)) < 0) + { + radius_log_err("%s: encode proxy state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->login_lat_service.flag == 1) + { + if (radius_encode_attr_login_lat_service(flw_ptr, &access_accept->login_lat_service) < 0) + { + radius_log_err("%s: encode login lat service fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->login_lat_node.flag == 1) + { + if (radius_encode_attr_login_lat_node(flw_ptr, &access_accept->login_lat_node) < 0) + { + radius_log_err("%s: encode login lat node fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->login_lat_group.flag == 1) + { + if (radius_encode_attr_login_lat_group(flw_ptr, &access_accept->login_lat_group) < 0) + { + radius_log_err("%s: encode login lat group fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_appletalk_link.flag == 1) + { + if (radius_encode_attr_framed_appletalk_link(flw_ptr, &access_accept->framed_appletalk_link) < 0) + { + radius_log_err("%s: encode framed appletalk link fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->framed_appletalk_network.num != 0) + { + if ((len = radius_encode_framed_appletalk_network(flw_ptr, &access_accept->framed_appletalk_network)) < 0) + { + radius_log_err("%s: encode framed appletalk network fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->framed_appletalk_zone.flag == 1) + { + if (radius_encode_attr_framed_appletalk_zone(flw_ptr, &access_accept->framed_appletalk_zone) < 0) + { + radius_log_err("%s: encode framed appletalk zone fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->port_limit.flag == 1) + { + if (radius_encode_attr_port_limit(flw_ptr, &access_accept->port_limit) < 0) + { + radius_log_err("%s: encode port limit fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->login_lat_port.flag == 1) + { + if (radius_encode_attr_login_lat_port(flw_ptr, &access_accept->login_lat_port) < 0) + { + radius_log_err("%s: encode login lat port fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (access_accept->configuration_token.num != 0) + { + if ((len = radius_encode_configuration_token(flw_ptr, &access_accept->configuration_token)) < 0) + { + radius_log_err("%s: encode configuration token fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_accept->acct_interim_interval.flag == 1) + { + if (radius_encode_attr_acct_interim_interval(flw_ptr, &access_accept->acct_interim_interval) < 0) + { + radius_log_err("%s: encode acct interim interval fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + +// if (access_accept->message_authenticator.flag == 1) + { + radius_encode_attr_message_authenticator(msg, flw_ptr, nas_info_ptr->share_key); + + flw_ptr += flw_ptr[1]; + } + + msg_len = flw_ptr - msg; + + msg[2] = (msg_len >> 8) & 0xFF; + msg[3] = (msg_len) & 0xFF; + + radius_calculate_authenticator(authenticator, msg, msg_len, nas_info_ptr->share_key); + + memcpy(&msg[4], authenticator, RADIUS_MAX_LEN_OF_AUTH); + + return msg_len; +} + +int radius_encode_access_reject(BYTE identifier, BYTE *request_authenticator, BYTE *msg, RADIUS_ACCESS_REJECT *access_reject, int nas_id) +{ + int len; + int msg_len = 0; + BYTE *flw_ptr = msg; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH] = ""; + RADIUS_NAS_INFO *nas_info_ptr; + + if ((request_authenticator == NULL) || (msg == NULL) || (access_reject == NULL)) + { + radius_log_err("%s: pointer error\r\n", __FUNCTION__); + return -1; + } + + if (((nas_info_ptr = radius_get_nas_info_ptr(nas_id)) == NULL) || (nas_info_ptr->flag != 1)) + { + radius_log_err("%s: nas id=%d error\r\n", __FUNCTION__, nas_id); + return -1; + } + + flw_ptr[0] = RADIUS_MSG_TYPE_ACCESS_REJECT; + + flw_ptr[1] = identifier; + + flw_ptr += 4; + + memcpy(flw_ptr, request_authenticator, RADIUS_MAX_LEN_OF_AUTH); + + flw_ptr += RADIUS_MAX_LEN_OF_AUTH; + + if (access_reject->reply_message.num != 0) + { + if ((len = radius_encode_reply_message(flw_ptr, &access_reject->reply_message)) < 0) + { + radius_log_err("%s: encode reply message fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_reject->proxy_state.num != 0) + { + if ((len = radius_encode_proxy_state(flw_ptr, &access_reject->proxy_state)) < 0) + { + radius_log_err("%s: encode proxy state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (access_reject->password_retry.flag == 1) + { + if (radius_encode_attr_password_retry(flw_ptr, &access_reject->password_retry) < 0) + { + radius_log_err("%s: encode password retry fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + +// if (access_reject->message_authenticator.flag == 1) + { + radius_encode_attr_message_authenticator(msg, flw_ptr, nas_info_ptr->share_key); + + flw_ptr += flw_ptr[1]; + } + + msg_len = flw_ptr - msg; + + msg[2] = (msg_len >> 8) & 0xFF; + msg[3] = (msg_len) & 0xFF; + + radius_calculate_authenticator(authenticator, msg, msg_len, nas_info_ptr->share_key); + + memcpy(&msg[4], authenticator, RADIUS_MAX_LEN_OF_AUTH); + + return msg_len; +} + +/*int radius_encode_accounting_request(BYTE *identifier, BYTE *authenticator, BYTE *msg, RADIUS_ACCOUNTING_REQUEST *accounting_request) +{ + int len; + int msg_len = 0; + BYTE *flw_ptr = msg; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH] = ""; + BYTE id = radius_accounting_id_select; + + if ((identifier == NULL) || (authenticator == NULL) || (msg == NULL) || (accounting_request == NULL)) + { + radius_log_err("%s: pointer error\r\n", __FUNCTION__); + return -1; + } + + flw_ptr[0] = RADIUS_MSG_TYPE_ACCOUNTING_REQUEST; + + *identifier = id; + + flw_ptr[1] = id; + + flw_ptr += 4; + + for (i = 0; i < RADIUS_MAX_LEN_OF_AUTH; i++) + { + flw_ptr[4 + i] = 0x00; + } + + + flw_ptr += RADIUS_MAX_LEN_OF_AUTH; + + if (accounting_request->user_name.flag == 1) + { + if (radius_encode_attr_user_name(flw_ptr, &accounting_request->user_name) < 0) + { + radius_log_err("%s: encode user name fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->nas_ip_addr.flag == 1) + { + if (radius_encode_attr_nas_ip_address(flw_ptr, &accounting_request->nas_ip_addr) < 0) + { + radius_log_err("%s: encode nas ip addr fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->nas_port.flag == 1) + { + if (radius_encode_attr_nas_port(flw_ptr, &accounting_request->nas_port) < 0) + { + radius_log_err("%s: encode nas port fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->service_type.flag == 1) + { + if (radius_encode_attr_service_type(flw_ptr, &accounting_request->service_type)< 0) + { + radius_log_err("%s: encode service type fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->framed_protocol.flag == 1) + { + if (radius_encode_attr_framed_protocol(flw_ptr, &accounting_request->framed_protocol)< 0) + { + radius_log_err("%s: encode framed protocol fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->framed_ip_addr.flag == 1) + { + if (radius_encode_attr_framed_ip_addr(flw_ptr, &accounting_request->framed_ip_addr)< 0) + { + radius_log_err("%s: encode framed ip addr fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->framed_ip_netmask.flag == 1) + { + if (radius_encode_attr_framed_ip_netmask(flw_ptr, &accounting_request->framed_ip_netmask)< 0) + { + radius_log_err("%s: encode framed ip netmask fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->framed_routing.flag == 1) + { + if (radius_encode_attr_framed_routing(flw_ptr, &accounting_request->framed_routing)< 0) + { + radius_log_err("%s: encode framed routing fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (accounting_request->filter_id.num != 0) + { + if ((len = radius_encode_filter_id(flw_ptr, &accounting_request->filter_id)) < 0) + { + radius_log_err("%s: encode filter id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (accounting_request->vendor_specific.num != 0) + { + if ((len = radius_encode_vendor_specific(flw_ptr, &accounting_request->vendor_specific)) < 0) + { + radius_log_err("%s: encode vendor specific fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (accounting_request->proxy_state.num != 0) + { + if ((len = radius_encode_proxy_state(flw_ptr, &accounting_request->proxy_state)) < 0) + { + radius_log_err("%s: encode proxy state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + msg_len = flw_ptr - msg; + + msg[2] = (msg_len >> 8) & 0xFF; + msg[3] = (msg_len) & 0xFF; + + radius_calculate_authenticator(authenticator, msg, msg_len); + + memcpy(&msg[4], authenticator, RADIUS_MAX_LEN_OF_AUTH); + + ++radius_accounting_id_select; + + return msg_len; +}*/ + +int radius_encode_accounting_response(BYTE identifier, BYTE *request_authenticator, BYTE *msg, RADIUS_ACCOUNTING_RESPONSE *accounting_response, int nas_id) +{ + int len; + int msg_len = 0; + BYTE *flw_ptr = msg; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH] = ""; + RADIUS_NAS_INFO *nas_info_ptr; + + if ((request_authenticator == NULL) || (msg == NULL) || (accounting_response == NULL)) + { + radius_log_err("%s: pointer error\r\n", __FUNCTION__); + return -1; + } + + if (((nas_info_ptr = radius_get_nas_info_ptr(nas_id)) == NULL) || (nas_info_ptr->flag != 1)) + { + radius_log_err("%s: nas id=%d error\r\n", __FUNCTION__, nas_id); + return -1; + } + + flw_ptr[0] = RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE; + + flw_ptr[1] = identifier; + + flw_ptr += 4; + + memcpy(flw_ptr, request_authenticator, RADIUS_MAX_LEN_OF_AUTH); + + flw_ptr += RADIUS_MAX_LEN_OF_AUTH; + + if (accounting_response->vendor_specific.num != 0) + { + if ((len = radius_encode_vendor_specific(flw_ptr, &accounting_response->vendor_specific)) < 0) + { + radius_log_err("%s: encode vendor specific fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (accounting_response->proxy_state.num != 0) + { + if ((len = radius_encode_proxy_state(flw_ptr, &accounting_response->proxy_state)) < 0) + { + radius_log_err("%s: encode proxy state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + msg_len = flw_ptr - msg; + + msg[2] = (msg_len >> 8) & 0xFF; + msg[3] = (msg_len) & 0xFF; + + radius_calculate_authenticator(authenticator, msg, msg_len, nas_info_ptr->share_key); + + memcpy(&msg[4], authenticator, RADIUS_MAX_LEN_OF_AUTH); + + return msg_len; +} + +int radius_encode_disconnect_request(BYTE *identifier, BYTE *authenticator, BYTE *msg, RADIUS_DISCONNECT_REQUEST *disconnect_request, int nas_id) +{ + int msg_len = 0; + int len; + BYTE id = radius_disconnect_id_select; + BYTE *flw_ptr = msg; + RADIUS_NAS_INFO *nas_info_ptr; + + if ((identifier == NULL) || (authenticator == NULL) || (msg == NULL) || (disconnect_request == NULL)) + { + radius_log_err("%s: pointer error\r\n", __FUNCTION__); + return -1; + } + + if (((nas_info_ptr = radius_get_nas_info_ptr(nas_id)) == NULL) || (nas_info_ptr->flag != 1)) + { + radius_log_err("%s: nas id=%d error\r\n", __FUNCTION__, nas_id); + return -1; + } + + flw_ptr[0] = RADIUS_MSG_TYPE_DISCONNECT_REQUEST; + + *identifier = id; + + flw_ptr[1] = id; + + flw_ptr += 4; + +// radius_generate_access_request_authenticator(authenticator); + + memset(flw_ptr, 0, RADIUS_MAX_LEN_OF_AUTH); + + flw_ptr += RADIUS_MAX_LEN_OF_AUTH; + + if (disconnect_request->user_name.flag == 1) + { + if (radius_encode_attr_user_name(flw_ptr, &disconnect_request->user_name) < 0) + { + radius_log_err("%s: encode user name fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->nas_ip_addr.flag == 1) + { + if (radius_encode_attr_nas_ip_address(flw_ptr, &disconnect_request->nas_ip_addr) < 0) + { + radius_log_err("%s: encode nas ip address fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->nas_port.flag == 1) + { + if (radius_encode_attr_nas_port(flw_ptr, &disconnect_request->nas_port) < 0) + { + radius_log_err("%s: encode nas port fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->service_type.flag == 1) + { + disconnect_request->service_type.service_type.value = RADIUS_SERVICE_TYPE_AUTHORIZE_ONLY; + + if (radius_encode_attr_service_type(flw_ptr, &disconnect_request->service_type) < 0) + { + radius_log_err("%s: encode service type fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->framed_ip_addr.flag == 1) + { + if (radius_encode_attr_framed_ip_addr(flw_ptr, &disconnect_request->framed_ip_addr) < 0) + { + radius_log_err("%s: encode framed ip addr fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->reply_message.num != 0) + { + if ((len = radius_encode_reply_message(flw_ptr, &disconnect_request->reply_message)) < 0) + { + radius_log_err("%s: encode reply message fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (disconnect_request->state.flag == 1) + { + if (radius_encode_attr_state(flw_ptr, &disconnect_request->state) < 0) + { + radius_log_err("%s: encode state fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->radius_class.num != 0) + { + if ((len = radius_encode_class(flw_ptr, &disconnect_request->radius_class)) < 0) + { + radius_log_err("%s: encode class fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (disconnect_request->vendor_specific.num != 0) + { + if ((len = radius_encode_vendor_specific(flw_ptr, &disconnect_request->vendor_specific)) < 0) + { + radius_log_err("%s: encode vendor specific fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + +// if (disconnect_request->called_station_id.flag == 1) + if (disconnect_request->called_station_id.option == 1 || disconnect_request->called_station_id.option == 2) + { + if ((len = radius_encode_attr_called_station_id(flw_ptr, &disconnect_request->called_station_id)) < 0) + { + radius_log_err("%s: encode called station id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += len; + } + + if (disconnect_request->calling_station_id.flag == 1) + { + if (radius_encode_attr_calling_station_id(flw_ptr, &disconnect_request->calling_station_id) < 0) + { + radius_log_err("%s: encode calling station id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->nas_identifier.flag == 1) + { + if (radius_encode_attr_nas_id(flw_ptr, &disconnect_request->nas_identifier) < 0) + { + radius_log_err("%s: encode nas id fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if (disconnect_request->message_authenticator.flag == 1) + { + if (radius_encode_attr_message_authenticator(msg, flw_ptr, nas_info_ptr->share_key) < 0) + { + radius_log_err("%s: encode message authenticator fail\r\n", __FUNCTION__); + return -1; + } + + flw_ptr += flw_ptr[1]; + } + + if(disconnect_request->acct_session_id.flag == 1) + { + if(radius_encode_attr_acct_session_id(flw_ptr, &disconnect_request->acct_session_id) < 0) + { + radius_log_err("%s: encode acct session id fail\r\n", __FUNCTION__); + return -1; + } + flw_ptr += flw_ptr[1]; + } + + msg_len = flw_ptr - msg; + + msg[2] = (msg_len >> 8) & 0xFF; + msg[3] = (msg_len) & 0xFF; + + radius_calculate_authenticator(authenticator, msg, msg_len, nas_info_ptr->share_key); + + memcpy(&msg[4], authenticator, RADIUS_MAX_LEN_OF_AUTH); + + ++radius_disconnect_id_select; + + return msg_len; +} + + +int radius_send_msg(int pid) +{ + radius_send_udp_msg(pid); + + return 0; +} + + +int radius_authenticate_nas(BYTE *authenticator, RADIUS_NAS_INFO *nas_info_ptr, RADIUS_ACCESS_REQUEST * access_request, BYTE *msg, int msg_len, int msg_auth_attr_offset) +{ + struct in_addr ip_addr; + BYTE encrypt_password[RADIUS_MAX_LEN_OF_ENCRYPT_PASSWORD] = ""; + BYTE tmp_buf[RADIUS_MAX_LEN_OF_MSG] = ""; + BYTE message_authenticator[RADIUS_MAX_LEN_OF_AUTH] = ""; + + if (access_request->service_type.service_type.value == RADIUS_SERVICE_TYPE_AUTHENTICATE_ONLY) + { + if (access_request->user_password.flag != 1) + { + return -1; + } + + radius_encrypt_user_password(encrypt_password, nas_info_ptr->password, authenticator, nas_info_ptr->share_key); + + if (memcmp(access_request->user_password.user_password.value, encrypt_password, access_request->user_password.user_password.length) != 0) + { + ip_addr.s_addr = nas_info_ptr->nas_ip; + radius_log_err("%s: user password error, nas ip=%s\r\n", __FUNCTION__, inet_ntoa(ip_addr)); + return -1; + } + } + else if (access_request->service_type.service_type.value == RADIUS_SERVICE_TYPE_AUTHORIZE_ONLY) + { + if (access_request->message_authenticator.flag != 1) + return -1; + + memcpy(tmp_buf, msg, msg_len); + + memset(tmp_buf + msg_auth_attr_offset + 2, 0, RADIUS_MAX_LEN_OF_MESSAGE_AUTH_ATTR); + + radius_get_hmac_md5_hex(message_authenticator, tmp_buf, msg_len, nas_info_ptr->share_key, strlen((char*)nas_info_ptr->share_key)); + + if (memcmp(access_request->message_authenticator.message_authenticator.value, message_authenticator, RADIUS_MAX_LEN_OF_MESSAGE_AUTH_ATTR) != 0) + { + ip_addr.s_addr = nas_info_ptr->nas_ip; + radius_log_err("%s: message authenticator error, nas ip=%s\r\n", __FUNCTION__, inet_ntoa(ip_addr)); + return -1; + } + } + + return 0; +} + diff --git a/plat/radius/src/radius_if.c b/plat/radius/src/radius_if.c new file mode 100644 index 0000000..5dbb666 --- /dev/null +++ b/plat/radius/src/radius_if.c @@ -0,0 +1,277 @@ +#include "./include/radius_pub.h" + +int radius_set_nas_info(BYTE sap_index, BYTE id, RADIUS_NAS_INFORMATION *nas_information) +{ + RADIUS_NAS_INFO *nas_info_ptr; + + if ((sap_index >= RADIUS_MAX_NUM_OF_SAP) || ((nas_info_ptr = radius_get_nas_info_ptr(id)) == NULL)) + { + radius_log_err("%s: sap_index=%d, nas id=%d\r\n", __FUNCTION__, sap_index, id); + return -1; + } + + nas_info_ptr->flag = 1; + + nas_info_ptr->sap_index = sap_index; + + nas_info_ptr->nas_ip = nas_information->nas_ip; + strcpy((char*)nas_info_ptr->share_key, (char*)nas_information->share_key); + strcpy((char*)nas_info_ptr->password, (char*)nas_information->password); + + return 0; +} + +int radius_delet_nas_info(BYTE sap_index, BYTE id) +{ + RADIUS_NAS_INFO *nas_info_pt; + + if (((nas_info_pt = radius_get_nas_info_ptr(id)) == NULL) || (nas_info_pt->flag != 1) || (nas_info_pt->sap_index != sap_index)) + { + radius_log_err("%s: sap_index=%d, nas id=%d\r\n", __FUNCTION__, sap_index, id); + return -1; + } + + memset(nas_info_pt, 0, sizeof(RADIUS_NAS_INFO)); + + return 0; +} +/* +int radius_set_local_nas(BYTE sap_index, char *nas_password, char *nas_share_key) +{ + if (sap_index >= RADIUS_MAX_NUM_OF_SAP) + { + radius_log_err("%s: sap_index=%d\r\n", __FUNCTION__, sap_index); + return -1; + } + + strcpy(radius_nas_password[sap_index], nas_password); + strcpy(radius_nas_share_key[sap_index], nas_share_key); + + return 0; +}*/ + +int radius_send_access_request(BYTE sap_index, WORD usr_pid, RADIUS_MSG *msg_pdu, RADIUS_ADDR *addr) +{ + int pid; + BYTE identifier; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH]; + int msg_len, nas_id; + BYTE msg[RADIUS_MAX_LEN_OF_MSG] = ""; + RADIUS_PID *pid_ptr; + struct in_addr ip_addr; +// int server_id; +// struct in_addr ip_addr; + + if ((sap_index >= RADIUS_MAX_NUM_OF_SAP) || (msg_pdu == NULL) || (addr == NULL)) + { + radius_log_err("%s: sap_index=%d, msg_pdu=0x%X, addr=ox%X\r\n", __FUNCTION__, sap_index, msg_pdu, addr); + return -1; + } + radius_log_event("%s: enter! usr_pid=%d\r\n", __FUNCTION__, usr_pid); + +/* if ((server_id = radius_accord_ip_search_server_info(addr->addr.ipV4)) < 0) + { + ip_addr.s_addr = addr->addr.ipV4; + radius_log_err("%s: server ip=%s, no such nas\r\n", __FUNCTION__, inet_ntoa(ip_addr)); + return -1; + }*/ + if ((nas_id = radius_accord_ip_search_nas_info(addr->addr.ipV4)) < 0) + { + ip_addr.s_addr = addr->addr.ipV4; + radius_log_warn("%s: nas ip = %s, no such nas ip\r\n", __FUNCTION__, inet_ntoa(ip_addr)); + return -1; + } + + if ((msg_len = radius_encode_access_request(sap_index, &identifier, authenticator, msg, &msg_pdu->msg.access_request, nas_id)) < 0) + { + radius_log_err("%s: encode access request fail\r\n", __FUNCTION__); + return -1; + } + + if ((pid = radius_get_pid()) < 0) + { + radius_log_err("%s: get pid fail\r\n", __FUNCTION__); + return -1; + } + + pid_ptr = radius_get_pid_ptr(pid); + + pid_ptr->type = RADIUS_PID_TYPE_REQ; + + pid_ptr->identifier = identifier; + memcpy(pid_ptr->authenticator, authenticator, RADIUS_MAX_LEN_OF_AUTH); + + pid_ptr->sd_msg_flag = 1; + pid_ptr->sd_msg_type = RADIUS_MSG_TYPE_ACCESS_REQUEST; + + memcpy(&pid_ptr->peer_addr, addr, sizeof(RADIUS_ADDR)); + pid_ptr->peer_addr.port = RADIUS_ACCESS_PORT; + + memcpy(pid_ptr->msg, msg, msg_len); + pid_ptr->msg_len = msg_len; + + pid_ptr->timer = RADIUS_TIMER_16S; + + pid_ptr->sap_index = sap_index; + pid_ptr->usr_pid = usr_pid; + + radius_log_event("%s: success! usr_pid=%d, pid=%d\r\n", __FUNCTION__, usr_pid, pid); +// radius_p_fsm(pid); + + return pid; +} + +int radius_send_access_accept(BYTE sap_index, WORD pid, WORD usr_pid, RADIUS_MSG *msg_pdu) +{ + int msg_len; + BYTE msg[RADIUS_MAX_LEN_OF_MSG] = ""; + RADIUS_PID *pid_ptr; + + if ((sap_index >= RADIUS_MAX_NUM_OF_SAP) || (msg_pdu == NULL) + || ((pid_ptr = radius_get_pid_ptr(pid)) == NULL) || (pid_ptr->sap_index != sap_index) + || (pid_ptr->usr_pid != usr_pid) + || (pid_ptr->trans_req_msg_type != RADIUS_MSG_TYPE_ACCESS_REQUEST)) + { + radius_log_err("%s: sap_index=%d, msg_pdu=0x%X, pid=%d, usr_pid=%d\r\n", __FUNCTION__, sap_index, msg_pdu, pid, usr_pid); + return -1; + } + + if ((msg_len = radius_encode_access_accept(pid_ptr->identifier, pid_ptr->authenticator, msg, &msg_pdu->msg.access_accept, pid_ptr->nas_id)) < 0) + { + radius_log_err("%s: encode access accept fail\r\n", __FUNCTION__); + return -1; + } + + pid_ptr->sd_msg_flag = 1; + pid_ptr->sd_msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT; + + memcpy(pid_ptr->msg, msg, msg_len); + pid_ptr->msg_len = msg_len; + radius_log_event("%s: success! usr_pid=%d, pid=%d\r\n", __FUNCTION__, usr_pid, pid); + + return 0; +} + +int radius_send_access_reject(BYTE sap_index, WORD pid, WORD usr_pid, RADIUS_MSG *msg_pdu) +{ + int msg_len; + BYTE msg[RADIUS_MAX_LEN_OF_MSG] = ""; + RADIUS_PID *pid_ptr; + + if ((sap_index >= RADIUS_MAX_NUM_OF_SAP) || (msg_pdu == NULL) + || ((pid_ptr = radius_get_pid_ptr(pid)) == NULL) || (pid_ptr->sap_index != sap_index) + || (pid_ptr->usr_pid != usr_pid) + || (pid_ptr->trans_req_msg_type != RADIUS_MSG_TYPE_ACCESS_REQUEST)) + { + radius_log_err("%s: sap_index=%d, msg_pdu=0x%X, pid=%d, usr_pid=%d\r\n", __FUNCTION__, sap_index, msg_pdu, pid, usr_pid); + return -1; + } + + if ((msg_len = radius_encode_access_reject(pid_ptr->identifier, pid_ptr->authenticator, msg, &msg_pdu->msg.access_reject, pid_ptr->nas_id)) < 0) + { + radius_log_err("%s: encode access reject fail\r\n", __FUNCTION__); + return -1; + } + + pid_ptr->sd_msg_flag = 1; + pid_ptr->sd_msg_type = RADIUS_MSG_TYPE_ACCESS_REJECT; + + memcpy(pid_ptr->msg, msg, msg_len); + pid_ptr->msg_len = msg_len; + radius_log_event("%s: success! usr_pid=%d, pid=%d\r\n", __FUNCTION__, usr_pid, pid); + + return 0; +} + +int radius_send_accounting_response(BYTE sap_index, WORD pid, WORD usr_pid, RADIUS_MSG *msg_pdu) +{ + int msg_len; + BYTE msg[RADIUS_MAX_LEN_OF_MSG] = ""; + RADIUS_PID *pid_ptr; + + if ((sap_index >= RADIUS_MAX_NUM_OF_SAP) || (msg_pdu == NULL) + || ((pid_ptr = radius_get_pid_ptr(pid)) == NULL) || (pid_ptr->sap_index != sap_index) || (pid_ptr->usr_pid != usr_pid) || (pid_ptr->trans_req_msg_type != RADIUS_MSG_TYPE_ACCOUNTING_REQUEST)) + { + radius_log_err("%s: sap_index=%d, msg_pdu=0x%X, pid=%d, usr_pid=%d\r\n", __FUNCTION__, sap_index, msg_pdu, pid, usr_pid); + return -1; + } + + if ((msg_len = radius_encode_accounting_response(pid_ptr->identifier, pid_ptr->authenticator, msg, &msg_pdu->msg.accounting_response, pid_ptr->nas_id)) < 0) + { + radius_log_err("%s: encode accounting response fail\r\n", __FUNCTION__); + return -1; + } + + pid_ptr->sd_msg_flag = 1; + pid_ptr->sd_msg_type = RADIUS_MSG_TYPE_ACCOUNTING_RESPONSE; + + memcpy(pid_ptr->msg, msg, msg_len); + pid_ptr->msg_len = msg_len; + radius_log_event("%s: success! usr_pid=%d, pid=%d\r\n", __FUNCTION__, usr_pid, pid); + + return 0; +} + +int radius_send_disconnect_request(BYTE sap_index, WORD usr_pid, RADIUS_MSG *msg_pdu, RADIUS_ADDR *addr) +{ + int pid; + BYTE identifier; + BYTE authenticator[RADIUS_MAX_LEN_OF_AUTH]; + int msg_len; + BYTE msg[RADIUS_MAX_LEN_OF_MSG] = ""; + RADIUS_PID *pid_ptr; + int nas_id; + struct in_addr ip_addr; + + if ((sap_index >= RADIUS_MAX_NUM_OF_SAP) || (msg_pdu == NULL) || (addr == NULL)) + { + radius_log_err("%s: sap_index=%d, msg_pdu=0x%X, addr=ox%X\r\n", __FUNCTION__, sap_index, msg_pdu, addr); + return -1; + } + + if ((nas_id = radius_accord_ip_search_nas_info(addr->addr.ipV4)) < 0) + { + ip_addr.s_addr = addr->addr.ipV4; + radius_log_err("%s: nas ip=%s, no such nas\r\n", __FUNCTION__, inet_ntoa(ip_addr)); + return -1; + } + + if ((msg_len = radius_encode_disconnect_request(&identifier, authenticator, msg, &msg_pdu->msg.disconnect_request, nas_id)) < 0) + { + radius_log_err("%s: encode disconnect request fail\r\n", __FUNCTION__); + return -1; + } + + if ((pid = radius_get_pid()) < 0) + { + radius_log_err("%s: get pid fail\r\n", __FUNCTION__); + return -1; + } + + pid_ptr = radius_get_pid_ptr(pid); + + pid_ptr->type = RADIUS_PID_TYPE_REQ; + + pid_ptr->identifier = identifier; + memcpy(pid_ptr->authenticator, authenticator, RADIUS_MAX_LEN_OF_AUTH); + + pid_ptr->sd_msg_flag = 1; + pid_ptr->sd_msg_type = RADIUS_MSG_TYPE_DISCONNECT_REQUEST; + + memcpy(&pid_ptr->peer_addr, addr, sizeof(RADIUS_ADDR)); + pid_ptr->peer_addr.port = RADIUS_DISCONNECT_PORT; + + memcpy(pid_ptr->msg, msg, msg_len); + pid_ptr->msg_len = msg_len; + + pid_ptr->timer = RADIUS_TIMER_16S; + + pid_ptr->sap_index = sap_index; + pid_ptr->nas_id = nas_id; + radius_log_event("%s: success! usr_pid=%d, pid=%d\r\n", __FUNCTION__, usr_pid, pid); + +// radius_p_fsm(pid); + + return pid; +} + diff --git a/plat/radius/src/radius_md5.c b/plat/radius/src/radius_md5.c new file mode 100644 index 0000000..f3ba6f3 --- /dev/null +++ b/plat/radius/src/radius_md5.c @@ -0,0 +1,848 @@ +/***********************************************************************/ +/** md5.c -- the source code for MD5 routines **/ +/** RSA Data Security, Inc. MD5 Message-Digest Algorithm **/ +/** Created: 2/17/90 RLR **/ +/** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **/ +/** 1992.2.13 Jouko Holopainen, 80x86 version **/ +/***********************************************************************/ + +/***********************************************************************/ +/** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **/ +/** **/ +/** License to copy and use this software is granted provided that **/ +/** it is identified as the "RSA Data Security, Inc. MD5 Message- **/ +/** Digest Algorithm" in all material mentioning or referencing this **/ +/** software or this function. **/ +/** **/ +/** License is also granted to make and use derivative works **/ +/** provided that such works are identified as "derived from the RSA **/ +/** Data Security, Inc. MD5 Message-Digest Algorithm" in all **/ +/** material mentioning or referencing the derived work. **/ +/** **/ +/** RSA Data Security, Inc. makes no representations concerning **/ +/** either the merchantability of this software or the suitability **/ +/** of this software for any particular purpose. It is provided "as **/ +/** is" without express or implied warranty of any kind. **/ +/** **/ +/** These notices must be retained in any copies of any part of this **/ +/** documentation and/or software. **/ +/***********************************************************************/ + +#include "./include/radius_pub.h" +#include "./include/radius_md5.h" + +/***********************************************************************/ +/** Message-digest routines: **/ +/** To form the message digest for a message M **/ +/** (1) Initialize a context buffer mdContext using MD5Init **/ +/** (2) Call MD5Update on mdContext and M **/ +/** (3) Call MD5Final on mdContext **/ +/** The message digest is now in mdContext->digest[0...15] **/ +/***********************************************************************/ + +static unsigned char PADDING[64] = +{ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ + +#define FF(a, b, c, d, x, s, ac) \ +{\ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +#define GG(a, b, c, d, x, s, ac) \ +{\ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +#define HH(a, b, c, d, x, s, ac) \ +{\ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + +#define II(a, b, c, d, x, s, ac) \ +{\ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + +/* The routine MD5Init initializes the message-digest context + mdContext. All fields are set to zero. +*/ + +void radius_MD5Init (MD5_CTX *mdContext) +{ + mdContext->i[0] = mdContext->i[1] = (UINT4)0; + + /* Load magic initialization constants.*/ + mdContext->buf[0] = (UINT4)0x67452301; + mdContext->buf[1] = (UINT4)0xefcdab89; + mdContext->buf[2] = (UINT4)0x98badcfe; + mdContext->buf[3] = (UINT4)0x10325476; +} + +/* The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. +*/ + +void radius_MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + + /*compute number of bytes mod 64*/ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /*update number of bits*/ + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) + mdContext->i[1]++; + + mdContext->i[0] += ((UINT4)inLen << 3); + mdContext->i[1] += ((UINT4)inLen >> 29); + + #ifdef LITTLE_ENDIAN + /* Speedup for little-endian machines suggested in MD5 report --P Karn */ + if(mdi == 0 && ((unsigned long)inBuf & 0x03) == 0) + { + while(inLen >= 64) + { + radius_MD5Transform(mdContext->buf,(UINT4 *)inBuf); + inLen -= 64; + inBuf += 64; + } + } + #endif /* LITTLE_ENDIAN */ + + while (inLen--) + { + /* add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x40) + { + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) + | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); + + radius_MD5Transform (mdContext->buf, in); + mdi = 0; + } + } +} + +/* The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. +*/ +void radius_MD5Final (MD5_CTX *mdContext) +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + /* save number of bits */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + + radius_MD5Update(mdContext, PADDING, padLen); + + /* append length in bits and transform */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) + | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); + + radius_MD5Transform (mdContext->buf, in); + + /* store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) + { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } +} + +#ifndef CPU386 /* Fast assembler version exists for 386/486 */ +/* Basic MD5 step. Transforms buf based on in.*/ +void radius_MD5Transform (UINT4 *buf, UINT4 *in) +{ + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + /* Round 1 */ + FF ( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */ + FF ( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */ + FF ( c, d, a, b, in[ 2], S13, 606105819UL); /* 3 */ + FF ( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */ + FF ( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */ + FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */ // not bigger than 2147483647 + FF ( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */ + FF ( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */ + FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */ + FF ( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */ + FF ( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */ + FF ( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */ + FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */ + FF ( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */ + FF ( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */ + FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */ + + /* Round 2 */ + GG ( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */ + GG ( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */ + GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */ + GG ( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */ + GG ( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */ + GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */ + GG ( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */ + GG ( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */ + GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */ + GG ( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */ + GG ( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */ + GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */ + GG ( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */ + GG ( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */ + GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */ + GG ( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */ + + /* Round 3 */ + HH ( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */ + HH ( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */ + HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */ + HH ( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */ + HH ( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */ + HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */ + HH ( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */ + HH ( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */ + HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */ + HH ( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */ + HH ( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */ + HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */ + HH ( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */ + HH ( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */ + HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */ + HH ( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */ + + /* Round 4 */ + II ( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */ + II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */ + II ( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */ + II ( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */ + II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */ + II ( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */ + II ( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */ + II ( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */ + II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */ + II ( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */ + II ( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */ + II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */ + II ( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */ + II ( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */ + II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */ + II ( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} +#else /* CPU386 */ +/* Fast 386 Borland C inline assembler version of the MD5Transform() function + * from the RSA Data Security, Inc, MD5 Message Digest Algorithm. + * + * This version uses native 32 bit registers, so it needs a 386 or 486 CPU. + * + * Because this function does *lots* of 32-bit operations, this version is + * MUCH faster than the reference C version compiled with a garden- + * variety 16-bit MS-DOS C compiler. + * + * Written and placed into the public domain on + * 22 February 1992 by Phil Karn, KA9Q + */ + +/* I really shouldn't have to do this explicitly... */ +#ifdef __COMPACT__ + + asm .MODEL COMPACT + +#elif __HUGE__ + + asm .MODEL HUGE + +#elif __LARGE__ + + asm .MODEL LARGE + +#elif __MEDIUM__ + + asm .MODEL MEDIUM + +#elif __SMALL__ + + asm .MODEL SMALL + +#elif __TINY__ + + asm .MODEL TINY + +#endif + +/* Code sequence common to all four rounds. + + * evaluates a = b + (a + edi + x + t) <<< s + + * Assumes a,b are registers, s,t are immediate constants + + * The 'lea' instruction is just a fast way to compute "a = a+t+edi" + + */ + +#define COM(a,b,x,s,t)\ + + asm lea a,t[a+edi];\ + + asm add a,x;\ + + asm rol a,s;\ + + asm add a,b; + + + +/* Round 1 functions */ + +/* edi = F(x,y,z) = (x & y) | (~x & z) */ + +#define F(x,y,z)\ + + asm mov edi,x;\ + + asm and edi,y;\ + + asm mov esi,x;\ + + asm not esi;\ + + asm and esi,z;\ + + asm or edi,esi + + + +/* a = b + ((a + F(x,y,z) + x + t) <<< s); */ + +#define FF(a,b,c,d,x,s,t)\ + + F(b,c,d);\ + + COM(a,b,x,s,t) + + + +/* Round 2 functions */ + +/* edi = G(x,y,z) = F(z,x,y) = (x & z) | (y & ~z) */ + +#define G(x,y,z) F(z,x,y) + + + +/* a = b + ((a + G(b,c,d) + x + t) <<< s) */ + +#define GG(a,b,c,d,x,s,t)\ + + G(b,c,d);\ + + COM(a,b,x,s,t) + + + +/* Round 3 functions */ + +/* edi = H(x,y,z) = x ^ y ^ z */ + +#define H(x,y,z)\ + + asm mov edi,x;\ + + asm xor edi,y;\ + + asm xor edi,z + + + +/* a = b + ((a + H(b,c,d) + x + t) <<< s) */ + +#define HH(a,b,c,d,x,s,t)\ + + H(b,c,d);\ + + COM(a,b,x,s,t) + + + +/* Round 4 functions */ + +/* edi = I(x,y,z) = y ^ (x | ~z) */ + +#define I(x,y,z)\ + + asm mov edi,z;\ + + asm not edi;\ + + asm or edi,x;\ + + asm xor edi,y + + + +/* a = b + ((a + I(b,c,d) + x + t) <<< s) */ + +#define II(a,b,c,d,x,s,t)\ + + I(b,c,d);\ + + COM(a,b,x,s,t) + + + +#define A eax + +#define B ebx + +#define C ecx + +#define D edx + + + +void radius_MD5Transform(UINT4 *buf,UINT4 *input) +{ + asm .386; /* Allow use of 32-bit general registers */ + + /* Save caller's registers */ + + asm push si; + + asm push di; + + asm push es; + + asm if @DataSize NE 0 + + asm push ds; + + asm endif + + + + /* Get buf argument */ + + asm if @DataSize NE 0 + + asm lds si,buf; + + asm else + + asm mov si,buf; + + asm endif + + asm mov A,dword ptr si[0*4]; /* A = buf[0] */ + + asm mov B,dword ptr si[1*4]; /* B = buf[1] */ + + asm mov C,dword ptr si[2*4]; /* C = buf[2] */ + + asm mov D,dword ptr si[3*4]; /* D = buf[3] */ + + /* Warning: This makes our other args inaccessible until bp + * is restored! + */ + asm push bp; + + asm les bp,input + +/* Round 1. The *4 factors in the subscripts to bp account for the + * byte offsets of each long element in the input array. + */ + +#define S11 7 + +#define S12 12 + +#define S13 17 + +#define S14 22 + + FF(A,B,C,D,es:bp[ 0*4],S11,3614090360); /* 1 */ + + FF(D,A,B,C,es:bp[ 1*4],S12,3905402710); /* 2 */ + + FF(C,D,A,B,es:bp[ 2*4],S13, 606105819); /* 3 */ + + FF(B,C,D,A,es:bp[ 3*4],S14,3250441966); /* 4 */ + + FF(A,B,C,D,es:bp[ 4*4],S11,4118548399); /* 5 */ + + FF(D,A,B,C,es:bp[ 5*4],S12,1200080426); /* 6 */ + + FF(C,D,A,B,es:bp[ 6*4],S13,2821735955); /* 7 */ + + FF(B,C,D,A,es:bp[ 7*4],S14,4249261313); /* 8 */ + + FF(A,B,C,D,es:bp[ 8*4],S11,1770035416); /* 9 */ + + FF(D,A,B,C,es:bp[ 9*4],S12,2336552879); /* 10 */ + + FF(C,D,A,B,es:bp[10*4],S13,4294925233); /* 11 */ + + FF(B,C,D,A,es:bp[11*4],S14,2304563134); /* 12 */ + + FF(A,B,C,D,es:bp[12*4],S11,1804603682); /* 13 */ + + FF(D,A,B,C,es:bp[13*4],S12,4254626195); /* 14 */ + + FF(C,D,A,B,es:bp[14*4],S13,2792965006); /* 15 */ + + FF(B,C,D,A,es:bp[15*4],S14,1236535329); /* 16 */ + + + +/* Round 2 */ + +#define S21 5 + +#define S22 9 + +#define S23 14 + +#define S24 20 + + GG(A,B,C,D,es:bp[ 1*4],S21,4129170786); /* 17 */ + + GG(D,A,B,C,es:bp[ 6*4],S22,3225465664); /* 18 */ + + GG(C,D,A,B,es:bp[11*4],S23, 643717713); /* 19 */ + + GG(B,C,D,A,es:bp[ 0*4],S24,3921069994); /* 20 */ + + GG(A,B,C,D,es:bp[ 5*4],S21,3593408605); /* 21 */ + + GG(D,A,B,C,es:bp[10*4],S22, 38016083); /* 22 */ + + GG(C,D,A,B,es:bp[15*4],S23,3634488961); /* 23 */ + + GG(B,C,D,A,es:bp[ 4*4],S24,3889429448); /* 24 */ + + GG(A,B,C,D,es:bp[ 9*4],S21, 568446438); /* 25 */ + + GG(D,A,B,C,es:bp[14*4],S22,3275163606); /* 26 */ + + GG(C,D,A,B,es:bp[ 3*4],S23,4107603335); /* 27 */ + + GG(B,C,D,A,es:bp[ 8*4],S24,1163531501); /* 28 */ + + GG(A,B,C,D,es:bp[13*4],S21,2850285829); /* 29 */ + + GG(D,A,B,C,es:bp[ 2*4],S22,4243563512); /* 30 */ + + GG(C,D,A,B,es:bp[ 7*4],S23,1735328473); /* 31 */ + + GG(B,C,D,A,es:bp[12*4],S24,2368359562); /* 32 */ + + + +/* Round 3 */ + +#define S31 4 + +#define S32 11 + +#define S33 16 + +#define S34 23 + + HH(A,B,C,D,es:bp[ 5*4],S31,4294588738); /* 33 */ + + HH(D,A,B,C,es:bp[ 8*4],S32,2272392833); /* 34 */ + + HH(C,D,A,B,es:bp[11*4],S33,1839030562); /* 35 */ + + HH(B,C,D,A,es:bp[14*4],S34,4259657740); /* 36 */ + + HH(A,B,C,D,es:bp[ 1*4],S31,2763975236); /* 37 */ + + HH(D,A,B,C,es:bp[ 4*4],S32,1272893353); /* 38 */ + + HH(C,D,A,B,es:bp[ 7*4],S33,4139469664); /* 39 */ + + HH(B,C,D,A,es:bp[10*4],S34,3200236656); /* 40 */ + + HH(A,B,C,D,es:bp[13*4],S31, 681279174); /* 41 */ + + HH(D,A,B,C,es:bp[ 0*4],S32,3936430074); /* 42 */ + + HH(C,D,A,B,es:bp[ 3*4],S33,3572445317); /* 43 */ + + HH(B,C,D,A,es:bp[ 6*4],S34, 76029189); /* 44 */ + + HH(A,B,C,D,es:bp[ 9*4],S31,3654602809); /* 45 */ + + HH(D,A,B,C,es:bp[12*4],S32,3873151461); /* 46 */ + + HH(C,D,A,B,es:bp[15*4],S33, 530742520); /* 47 */ + + HH(B,C,D,A,es:bp[ 2*4],S34,3299628645); /* 48 */ + + + +/* Round 4 */ + +#define S41 6 + +#define S42 10 + +#define S43 15 + +#define S44 21 + + II(A,B,C,D,es:bp[ 0*4],S41,4096336452); /* 49 */ + + II(D,A,B,C,es:bp[ 7*4],S42,1126891415); /* 50 */ + + II(C,D,A,B,es:bp[14*4],S43,2878612391); /* 51 */ + + II(B,C,D,A,es:bp[ 5*4],S44,4237533241); /* 52 */ + + II(A,B,C,D,es:bp[12*4],S41,1700485571); /* 53 */ + + II(D,A,B,C,es:bp[ 3*4],S42,2399980690); /* 54 */ + + II(C,D,A,B,es:bp[10*4],S43,4293915773); /* 55 */ + + II(B,C,D,A,es:bp[ 1*4],S44,2240044497); /* 56 */ + + II(A,B,C,D,es:bp[ 8*4],S41,1873313359); /* 57 */ + + II(D,A,B,C,es:bp[15*4],S42,4264355552); /* 58 */ + + II(C,D,A,B,es:bp[ 6*4],S43,2734768916); /* 59 */ + + II(B,C,D,A,es:bp[13*4],S44,1309151649); /* 60 */ + + II(A,B,C,D,es:bp[ 4*4],S41,4149444226); /* 61 */ + + II(D,A,B,C,es:bp[11*4],S42,3174756917); /* 62 */ + + II(C,D,A,B,es:bp[ 2*4],S43, 718787259); /* 63 */ + + II(B,C,D,A,es:bp[ 9*4],S44,3951481745); /* 64 */ + + + + asm pop bp; /* We can address our args again */ + + asm if @DataSize NE 0 + + asm lds si,buf + + asm else + + asm mov si,buf; + + asm endif + + asm add dword ptr si[0*4],A; /* buf[0] += A */ + + asm add dword ptr si[1*4],B; /* buf[1] += B */ + + asm add dword ptr si[2*4],C; /* buf[2] += C */ + + asm add dword ptr si[3*4],D; /* buf[3] += D */ + + + + /* Restore caller's registers */ + + asm if @DataSize NE 0 + + asm pop ds + + asm endif + + + + asm pop es; + + asm pop di; + + asm pop si; + +} + +#endif /* CPU386 */ + +static void radius_MDPrint (char *dest, unsigned char digest[16]) +{ + unsigned int i; + char tmp[4]; + + for (i = 0; i < 16; i++) + { + sprintf (tmp, "%02x", digest[i]); + strcat(dest, tmp); + } +} + +static void radius_MDPrint_Hex(char *dest, unsigned char digest[16]) +{ + memcpy(dest, digest, 16); +} + +void radius_get_md5_str(char *dest, char *org, int len) +{ + MD5_CTX context; + + strcpy(dest, ""); + + radius_MD5Init (&context); + + radius_MD5Update (&context, (unsigned char*)org, (unsigned int)len); + + radius_MD5Final (&context);// MD5Final (digest, &context); + + radius_MDPrint (dest, context.digest); +} + +void radius_get_md5_hex(char *dest, char *org, int len) +{ + MD5_CTX context; + + bzero(dest, 16); + + radius_MD5Init (&context); + + radius_MD5Update (&context, (unsigned char*)org, (unsigned int)len); + + radius_MD5Final (&context);// MD5Final (digest, &context); + + radius_MDPrint_Hex (dest, context.digest); +} + +void radius_hmac_md5_calc(char *dest, char *org, int len, BYTE *pad) +{ + MD5_CTX context; + + bzero(dest, 16); + + radius_MD5Init (&context); + + radius_MD5Update(&context, pad, 64);/* start with inner pad */ + + radius_MD5Update (&context, (unsigned char*)org, (unsigned int)len); + + radius_MD5Final (&context);// MD5Final (digest, &context); + + radius_MDPrint_Hex (dest, context.digest); +} + +void radius_get_hmac_md5_hex(BYTE *dest, BYTE *org, int org_len, BYTE *key, int key_len) +{ + int i; + BYTE k_ipad[65] = ""; /* inner padding-key XORd with ipad*/ + BYTE k_opad[65] = ""; /* outer padding-key XORd with opad*/ + BYTE tk[16]; + BYTE calc_key[65] = ""; + int calc_key_len = 0; + + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) + { + radius_get_md5_hex((char*)tk, (char*)key, key_len); + + memcpy(calc_key, tk, 16); + calc_key_len = 16; + } + else + { + memcpy(calc_key, key, key_len); + calc_key_len = key_len; + } + + /* the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, org)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + bzero(k_ipad, sizeof k_ipad); + bzero(k_opad, sizeof k_opad); + + bcopy(calc_key, k_ipad, calc_key_len); + bcopy(calc_key, k_opad, calc_key_len); + + /* XOR key with ipad and opad values */ + for (i = 0; i < 64; i++) + { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + /*perform inner MD5*/ + radius_hmac_md5_calc((char*)tk, (char*)org, org_len, k_ipad); + + /* perform outer MD5*/ + radius_hmac_md5_calc((char*)dest, (char*)tk, 16, k_opad); +} + +/* + + *********************************************************************** + + ** End of md5.c ** + + ******************************** (cut) ******************************** + + */ + diff --git a/plat/radius/src/radius_transport.c b/plat/radius/src/radius_transport.c new file mode 100644 index 0000000..f6e037b --- /dev/null +++ b/plat/radius/src/radius_transport.c @@ -0,0 +1,126 @@ +#include "./include/radius_pub.h" + +int radius_recv_udp_msg(void) +{ + struct sockaddr_in radius_src_addr; + int i, len, addr_len = sizeof(struct sockaddr); + RADIUS_ADDR addr; + int nas_id; + + for (i = 0; i < RADIUS_MAX_UDP_MSG_GET_TIMES; i++) + { + len = recvfrom(radius_udp_access_socket_fd, radius_udp_msg_recv_buf, RADIUS_MAX_LEN_OF_UDP_MSG, \ + 0, (struct sockaddr *)&radius_src_addr, (socklen_t*)&addr_len); + if (len < 0) + break; + + if (len >= RADIUS_MAX_LEN_OF_UDP_MSG) + continue; + + memset(radius_udp_msg_recv_buf + len, 0, RADIUS_MAX_LEN_OF_UDP_MSG - len); + + addr.port = ntohs(radius_src_addr.sin_port); + addr.addr.ipV4 = radius_src_addr.sin_addr.s_addr; + + if ((nas_id = radius_accord_ip_search_nas_info(radius_src_addr.sin_addr.s_addr)) < 0) + { + radius_log_warn("%s: recv msg from %s, no such nas ip\r\n", __FUNCTION__, inet_ntoa(radius_src_addr.sin_addr)); + continue; + } + + radius_udp_msg_handling(radius_udp_msg_recv_buf, len, &addr, nas_id); + } + + for (i = 0; i < RADIUS_MAX_UDP_MSG_GET_TIMES; i++) + { + len = recvfrom(radius_udp_account_socket_fd, radius_udp_msg_recv_buf, RADIUS_MAX_LEN_OF_UDP_MSG, \ + 0, (struct sockaddr *)&radius_src_addr, (socklen_t*)&addr_len); + if (len < 0) + break; + + if (len >= RADIUS_MAX_LEN_OF_UDP_MSG) + continue; + + memset(radius_udp_msg_recv_buf + len, 0, RADIUS_MAX_LEN_OF_UDP_MSG - len); + + addr.port = ntohs(radius_src_addr.sin_port); + addr.addr.ipV4 = radius_src_addr.sin_addr.s_addr; + + if ((nas_id = radius_accord_ip_search_nas_info(radius_src_addr.sin_addr.s_addr)) < 0) + { + radius_log_warn("%s: recv msg from %s, no such nas ip\r\n", __FUNCTION__, inet_ntoa(radius_src_addr.sin_addr)); + continue; + } + + radius_udp_msg_handling(radius_udp_msg_recv_buf, len, &addr, nas_id); + } + + for (i = 0; i < RADIUS_MAX_UDP_MSG_GET_TIMES; i++) + { + len = recvfrom(radius_udp_disconnect_socket_fd, radius_udp_msg_recv_buf, RADIUS_MAX_LEN_OF_UDP_MSG, \ + 0, (struct sockaddr *)&radius_src_addr, (socklen_t*)&addr_len); + if (len < 0) + break; + + if (len >= RADIUS_MAX_LEN_OF_UDP_MSG) + continue; + + memset(radius_udp_msg_recv_buf + len, 0, RADIUS_MAX_LEN_OF_UDP_MSG - len); + + addr.port = ntohs(radius_src_addr.sin_port); + addr.addr.ipV4 = radius_src_addr.sin_addr.s_addr; + + if ((nas_id = radius_accord_ip_search_nas_info(radius_src_addr.sin_addr.s_addr)) < 0) + { + radius_log_warn("%s: recv msg from %s, no such nas ip\r\n", __FUNCTION__, inet_ntoa(radius_src_addr.sin_addr)); + continue; + } + + radius_udp_msg_handling(radius_udp_msg_recv_buf, len, &addr, nas_id); + } + + return 0; +} + +int radius_send_udp_msg(int pid) +{ + int ret; + int len; + RADIUS_PID *pid_ptr; + struct sockaddr_in radius_dst_addr; + int socket_fd; + + pid_ptr = radius_get_pid_ptr(pid); + + len = pid_ptr->msg_len; + + if (len >= RADIUS_MAX_LEN_OF_MSG) + { + radius_log_err("%s: msg len=%d\r\n", __FUNCTION__, pid_ptr->msg_len); + return -1; + } + + if (radius_set_udp_dest_addr(&radius_dst_addr, &pid_ptr->peer_addr) < 0) + { + radius_log_err("%s: set destination address fail, pid=%d, dest_port=%d, dest_ip=0x%X\r\n", __FUNCTION__, pid, pid_ptr->peer_addr.port, pid_ptr->peer_addr.addr.ipV4); + return -1; + } + + if ((socket_fd = radius_get_sock_fd_according_msg_type(pid_ptr->sd_msg_type)) < 0) + { + radius_log_err("%s: msg type=%d get sock fd fail\r\n", __FUNCTION__, pid_ptr->sd_msg_type); + return -1; + } + + ret = sendto(socket_fd, pid_ptr->msg, len, 0, (struct sockaddr *)&radius_dst_addr, sizeof(struct sockaddr_in)); + + radius_log_send_recv_msg(pid_ptr->msg, len, &pid_ptr->peer_addr, pid_ptr->sd_msg_type, RADIUS_SEND_MSG_FLAG); + + if (ret < 0) + { + radius_log_err("%s: send msg fail\r\n", __FUNCTION__); + } + + return ret; +} + diff --git a/plat/radius/ut/Makefile b/plat/radius/ut/Makefile new file mode 100644 index 0000000..aaff0c8 --- /dev/null +++ b/plat/radius/ut/Makefile @@ -0,0 +1,101 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = radiustest +TYPE = app + +DBUG_FLAGS_ADD = -D_LKSCTP +RELS_FLAGS_ADD = -D_LKSCTP + +##Default commonly as below + +BUILD = exef +CFG = debug + +APP_LIB = mnp vlr hlr msc vlr smsc ssf ae pps aas opr iif + +PLT_LIB = radius megaco scf sccp haepub aif mgc_v2 mgcp rtp \ + 8ecp isup bicc smpp xapp tcap sccp mtp3 m2ua \ + debug snmp iptrans public pal isdn + +LIB_ADD = -L../../../mss/ae/src/lib -lpubfunc \ + -la3a8 -ldl -lpopt -lncurses -L/usr/lib -lsrfvar -L/usr/local/lib -lcunit + +SRC_PATH = ./ +INC_PATH = ./ +PLT_PATH = ../../../plat +APP_PATH = ../../../mss + +OBJ_ADD = +TEST_OBJ_PATH = ./obj + +PREPROC_CMD = cd ../;make rebuild; cd ./ut ;##cd ../../../plat;make rebuild CCFLAG_SWITCH=on DBUG_FLAGS_ADD+=-DEBUG_TEST;cd -; cd ../;make rebuild; cd ./ut +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/radius/ut/radius_test_main.c b/plat/radius/ut/radius_test_main.c new file mode 100644 index 0000000..271dfd2 --- /dev/null +++ b/plat/radius/ut/radius_test_main.c @@ -0,0 +1,49 @@ +#include +#include + +//#include "../src/include/megaco_pub.h" +#include "radius_unit_test.h" + +#include "/usr/local/include/CUnit/Basic.h" +#include "/usr/local/include/CUnit/Automated.h" + +#include +#include + +int main() +{ +// signal(SIGSEGV, &dump); + CU_pSuite pSuite1 = NULL; + CU_pSuite pSuite2 = NULL; + CU_pSuite pSuite3 = NULL; + + /* initialize the CUnit test registry */ + if (CUE_SUCCESS != CU_initialize_registry()) + return CU_get_error(); + + /* add a suite to the registry */ + pSuite1 = CU_add_suite("function test of radius", test_radius_init, NULL); + + if (NULL == pSuite1) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + /* add the tests to the suite */ + if ((NULL == CU_add_test(pSuite1, "code test of radius", test_radius)) + ) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + /* Run all tests using the CUnit Basic interface */ + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); +// CU_automated_run_tests(); + CU_list_tests_to_file(); + + CU_cleanup_registry(); + return CU_get_error(); +} diff --git a/plat/radius/ut/radius_unit_test.c b/plat/radius/ut/radius_unit_test.c new file mode 100644 index 0000000..6b0de76 --- /dev/null +++ b/plat/radius/ut/radius_unit_test.c @@ -0,0 +1,157 @@ +#include +#include + +#include "../src/include/radius_if.h" + +#include "/usr/local/include/CUnit/CUnit.h" + +int test_radius_ind(WORD *usr_pid, WORD pid, RADIUS_MSG *msg_pdu) +{ + static int count = 0; + int i; + int num; + BYTE str[64] = ""; + BYTE tmp[4] = ""; + RADIUS_MSG pdu; + RADIUS_ACCESS_REQUEST *access_request; + RADIUS_ACCESS_ACCEPT *access_accept; + RADIUS_VENDOR_SPECIFIC *vendor_specific; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC *ppac; + RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq; + RADIUS_DISCONNECT_REQUEST *disconnect_request; + RADIUS_ADDR addr; + RADIUS_ATTRIBUTE_REPLY_MESSAGE *reply_message; + + *usr_pid = 0; + + if (msg_pdu->msg_type != RADIUS_MSG_TYPE_ACCESS_REQUEST) + { + return -1; + } + + access_request = &msg_pdu->msg.access_request; + + if (access_request->user_password.flag == 1) + { + for (i = 0; i < 16; i++) + { + sprintf(tmp, "%02x", access_request->user_password.user_password.value[i]); + strcat(str, tmp); + } + + printf("user password=%s\r\n", str); + } + + memset(&pdu, 0, sizeof(RADIUS_MSG)); + + pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT; + + access_accept = &pdu.msg.access_accept; + + vendor_specific = &access_accept->vendor_specific; + + num = vendor_specific->num; + + vendor_specific->vendor_specific[num].flag = 1; + + vendor_specific->vendor_specific[num].vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAC; + + ppac = &vendor_specific->vendor_specific[num].attribute_3gpp2.ppac; + + ppac->sfs.flag = 1; + ppac->sfs.sfs = 2;//ppac->sfs.sfs = 1;// + + vendor_specific->num++; + + num = vendor_specific->num; + + vendor_specific->vendor_specific[num].vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAQ; + + ppaq = &vendor_specific->vendor_specific[num].attribute_3gpp2.ppaq; + + ppaq->qid.flag = 1; + ppaq->qid.qid.value = 9; + +/* ppaq->vq.flag = 1; + ppaq->vq.vq.integer = (count + 1) * 102400; + ppaq->vq.vq.exponent = 1; + + ppaq->vt.flag = 1; + ppaq->vt.vt.integer = (count + 1) * 102400 - 10240; + ppaq->vt.vt.exponent = 1;*/ + + ppaq->dq.flag = 1; + ppaq->dq.dq.value = (count + 1) * 25; + + ppaq->dt.flag = 1; + ppaq->dt.dt.value = (count + 1) * 25 - 7; + + vendor_specific->num++; + + access_accept->message_authenticator.flag = 1; + + radius_send_access_accept(0, pid, 0, &pdu); + + count++; + + if (count == 3) + { + memset(&pdu, 0, sizeof(RADIUS_MSG)); + + disconnect_request = &pdu.msg.disconnect_request; + + num = disconnect_request->reply_message.num; + + reply_message = &disconnect_request->reply_message.reply_message[num]; + + reply_message->flag = 1; + + strcpy(reply_message->reply_message.value,"Radius disconnect"); + + disconnect_request->reply_message.num++; + + addr.addr.ipV4 = inet_addr("155.226.202.45"); + + radius_send_disconnect_request(0, 0, &pdu, &addr); + } + + return 0; +} + +int test_radius_cnf(WORD usr_pid, WORD pid, RADIUS_MSG *msg_pdu) +{ + return 0; +} + +void test_radius_init() +{ + int sap_index; + RADIUS_SAP sap; + RADIUS_NAS_INFORMATION nas; + + strcpy(sap.name, "test_radius"); + + sap.radius_ind = test_radius_ind; + sap.radius_cnf = test_radius_cnf; + + radius_init(); + + sap_index = radius_bind(&sap); + + nas.nas_ip = inet_addr("155.226.202.45"); + strcpy(nas.share_key, "topsecret"); + strcpy(nas.password, "test"); + + radius_set_nas_info(sap_index, 0, &nas); +} + +void test_radius(void) +{ + for(;;) + { + radius_timer(); + + usleep(1000); + } +} + diff --git a/plat/radius/ut/radius_unit_test.h b/plat/radius/ut/radius_unit_test.h new file mode 100644 index 0000000..8579dab --- /dev/null +++ b/plat/radius/ut/radius_unit_test.h @@ -0,0 +1,7 @@ +#ifndef _MGC_TEST_CASE_H +#define _MGC_TEST_CASE_H + +void test_radius_init(); +void test_radius(); + +#endif diff --git a/plat/sccp/Makefile b/plat/sccp/Makefile new file mode 100644 index 0000000..545ff31 --- /dev/null +++ b/plat/sccp/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = sccp +TYPE = plat + +DBUG_FLAGS_ADD = -D_CDMA_SNMP -DDEBUG ##-DMEMWATCH -DMEMWATCH_STDIO ##-D_WXC_FSM_TEST +RELS_FLAGS_ADD = -D_CDMA_SNMP -DDEBUG + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../app + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/sccp/src/include/sccp.h b/plat/sccp/src/include/sccp.h new file mode 100644 index 0000000..e9dc1a2 --- /dev/null +++ b/plat/sccp/src/include/sccp.h @@ -0,0 +1,399 @@ + +/******************************************************/ +/*Title: sccp.h */ +/*Descr: Definition of SCCP */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/******************************************************/ + +#ifndef _SCCP_HEAD_FILE +#define _SCCP_HEAD_FILE + +#include "../../../public/src/include/pub_wnet.h" +#include "../../../snmp/src/include/heartbeat.h" +#include "../../../snmp/src/include/snmp.h" +#include "../../../debug/src/include/debug.h" +#include "../../../mtp3/src/include/mtp3.h" +#include "sccpconst.h" + +#ifdef _WXC_FSM_TEST +#define spLogFsm printf +#define spWxcBackTrace() WxcBackTrace() +#else +#define spLogFsm +#define spWxcBackTrace() +#endif + +#define MAX_SCLC_BUF 6 + +#define SCCP_VERSION { 1,0,01} + +////////////////////////////////////////////////////////////////// +#define SEG_RS_LEN 3 + +typedef struct SCCP_Segmnt +{ + unsigned RSBits:4; + unsigned SpaceBits:2; + unsigned CBit:1; + unsigned FBit:1; + u8 SegLR[SEG_RS_LEN]; +} +SCCP_Segmnt; + +typedef struct SCCP_SegUnID +{ + int OPC; + int DPC; + u8 SLS; + SCCP_ADDR CGA; + u8 SegLR[SEG_RS_LEN]; +} +SCCP_SegUnID; + +#define MAX_SEGBLOCK_LEN 256 + +typedef struct SCCP_SegStream +{ + u8 SegDataLen; + u8 SegDataBlock[MAX_SEGBLOCK_LEN]; +} +SCCP_SegStream; + +#define MAX_SEGSTREAM_SIZE 10 +#define MAX_SEGMSG_TIMER 2000 +#define SEGSTREAM_IDLE 0x00 +#define SEGSTREAM_BUSY 0x01 + +typedef struct SCCP_SegMsgBuf +{ + u8 MsgState; + u8 MsgClass; + u8 MsgTotal; + u_long SegMsgTimer; + u8 RSE; + + SCCP_SegUnID SegID; + SCCP_SegStream SegStream[MAX_SEGSTREAM_SIZE]; + +} +SCCP_SegMsgBuf; + +#define MAX_SEGMSG_BUF 256 +extern SCCP_SegMsgBuf sccp_segmsgbuf[MAX_SEGMSG_BUF]; + +typedef struct Intra_Message +{ + u8 msgsource; //FROM_MTP:0£¬FROM_SCLC:1,FROM_SCOC:2,FROM_SCMG:3 + u8 msgtype; + u8 msgclass; + + u8 msgMNP; /* mnp flag , added by pierre , 11-07 */ + int OPC; + int DPC; + u8 SLS; + u16 link; + u8 NetID; + SCCP_ADDR CGA; + SCCP_ADDR CDA; + BOOL EOD; + u8 aSLR[SP_REF_LEN]; + u8 aDLR[SP_REF_LEN]; + u_short msglen; + u8 data[SCCP_MSG_MAXLEN]; + u8 PS; + u8 PR; + u8 RO; + u8 cause; + u8 Hop; + SCCP_Segmnt Segmnt; // + u8 SegPresent; + u8 redirectFlag; + u8 sequenceFlag; +} +Intra_Msg; + +//Intra_Msg CurMsg; + +typedef struct SCCP_OPT +{ + DWORD ip; + long spc[4]; + u8 spclen[4]; + u8 version[3]; + u8 status; + u8 RegSSN[32]; + u8 RegNum; + u8 CO_SSN[SP_POOL_SIZE]; //extend for more Upper layers + long T_reset; + DWORD OMCIP[2]; +} +SCCP_OPT; + +extern SCCP_OPT SCCP_Param; + +typedef struct _SCOC_BUF +{ + short rcvsub[2]; + short sndsub[2]; + up_message msgin[SS_MSG_NUM]; + up_message msgout[SS_MSG_NUM]; +} +SCOC_BUF; + +extern SCOC_BUF ScocBuf; + +#define MAX_SCLCMSG_LEN 256 + +typedef struct SCLC_MSG +{ + u8 primitive; + u8 msg[MAX_SCLCMSG_LEN]; + u_short msglen; + u8 sls; + u8 sequence_control; //Class 0: The basic connectionless class without guaranteed in-sequence delivery + //Class 1: The in-sequence delivery connectionless class with guaranteed in-sequence delivery + u8 ret_reason; + SCCP_ADDR src_addr; + SCCP_ADDR dst_addr; +} +SCLC_MSG; + +typedef struct _SCLC_BUF +{ + short readsub; + short writesub; + SCLC_MSG msglist[SS_MSG_NUM]; +} +SCLC_BUF; + +typedef struct LOCAL_SSN +{ + u8 msisdn[MAX_DIGITS]; + u8 status[2]; //0:no 1:equipped(disable) 2:congest 3:enable 4:local&equipped(disable) 5:local&congest 6:local&enable + u8 nbuf; + u8 local; + u8 NetID; + u8 RegFlag; + DWORD ip[2]; + short timeout[2]; + u8 msisdn_len; + u8 title[16]; + int acn_index; +} +LOCAL_SSN; + +extern LOCAL_SSN LocalSSN[256]; +extern u8 ExistSSN[64]; +extern u8 ExistSSNNum; + +extern u8 MNP_Flag[2]; + +typedef struct _dpc2sls +{ + int dpc; + u8 sls; +}_dpc2sls; +extern _dpc2sls dpc2sls[256]; //used for sequence control, add by Roy Jiang, 2007-09-17 + +/* u80:0/1/2=not support MNP/IN_based/MNP_SRF */ +/* u81:0-1/2=direct/indirect routing */ +/* added by Pierre, 2005-11-07 for MNP */ + +/*===================================*/ +//MIB===================> + +/*===================================*/ + +typedef struct SCCP_ROUTE +{ + u8 avail; + u8 NP; + u8 TT; + u8 StartDigits[MAX_DIGITS]; + u8 EndDigits[MAX_DIGITS]; + u8 NetID; + u8 DPC[3]; + u8 SSN; + u8 RI; + u8 AI; //Address indicator,indicate the Address include GT,DPC,SSN or not,BIT0:point code, bit1:ssn, bit2:GT + u8 ReplaceStart; + u8 ReplaceEnd; + u8 OutNP; + u8 ReplaceDigits[MAX_DIGITS]; + u8 acn_ver[48]; + u8 convert; + u8 len; + u8 replace_len; + u16 acn_index;//point to acn_ver_table +} +SCCP_ROUTE; + +extern SCCP_ROUTE RouteList[SCCP_ROUTE_NUM]; + +typedef struct _SCCP_ACN_VER_TABLE +{ + u8 avail; + u8 LocationUpdating; + u8 LocationCancellation; + u8 RoamingNumberEnquiry; + u8 LocationInfoRetrieval; + u8 ResetContext; + u8 HandoverControl; + u8 EquipmentManagement; + u8 InfoRetrieval; + u8 InterVLRInfoRetrieval; + u8 SubscriberDataManagement; + u8 Tracing; + u8 NetworkFunctionalSS; + u8 NetworkUnstructuredSS; + u8 ShortMessageGateway; + u8 MOShortMessageRelay; + u8 ShortMessageAlert; + u8 ShortMessageWDM;//waiting Data Management + u8 MTShortMessageRelay; + u8 IMSIRetrieval; + u8 MSPurging; + u8 SubscriberInfoEnquiry; + u8 AnyTimeInfoEnquiry; + u8 CallControlTransfer; + u8 SSInvocationNotification; + u8 GroupCallControl; + u8 GPRSLocationUpdating; + u8 GPRSLocationInfoRetrieval; + u8 FailureReporting; + u8 GPRSNotifying; + u8 Reporting; + u8 CallCompletion; + u8 InternalSIWFSAllocation; + u8 InternalSecurityTriplets; + u8 InternalSubscriberInterrogating; + u8 InternalHLRSubscriberManagement; + u8 InternalHLRPingAUC; + u8 VLRCamelPhase; +}SCCP_ACN_VER_TABLE; + +extern SCCP_ACN_VER_TABLE acn_ver_table[SCCP_ROUTE_NUM]; + +typedef struct SCCP_ROUTE_NODE +{ + u_short nItem; + struct SCCP_ROUTE_NODE *psub[10]; +} +SCCP_ROUTE_NODE; + +typedef struct RL_SSN +{ + BOOL status; //0 NULL + u8 SST; + u8 NetID; + u8 SSN; + int DPC; + int timeout; +} +RL_SSN; + +extern int RelatedSSNNum; +extern RL_SSN RelatedSSN[SCCP_RLSSN_NUM]; + +typedef struct RL_SPC +{ + int DPC; + u8 NetID; + BOOL status; //0 NULL +} +RL_SPC; + +extern int RelatedSPCNum; +extern RL_SPC RelatedSPC[SCCP_RLSPC_NUM]; + +#define SCCP_MAX_GTT_ATTRIBUTE 16 +typedef struct GTTATT_OMC +{ + u8 attribute[SCCP_MAX_GTT_ATTRIBUTE]; +} +GTTATT_OMC; +extern GTTATT_OMC GTTAttribute[SCCP_ROUTE_NUM]; + +typedef struct SCCP_FILTER +{ + u8 flag; + u8 src_ssn; + u8 dst_ssn; + int opc; + int dpc; +} +SCCP_FILTER; + +typedef struct SCCP_CSTA +{ + DWORD timestamp; + DWORD error[21]; //.1.1.? + DWORD avail[12]; //.1.2.? + DWORD utilization[12]; //.1.3.? + DWORD quality[20]; //.1.4.? +} +SCCP_CSTA; + +extern SCCP_CSTA SccpCsta[96]; +extern u_long SccpCstaInd; + +typedef struct sccp_msg_statistic +{ + u_long msg_mtp_scoc; + u_long msg_scoc_up; + u_long mnp_send; + u_long mnp_route; +}sccp_msg_statistic; +extern sccp_msg_statistic sccpmsg_st; + +typedef struct sccp_msg_rv_snd_statistic +{ + u_long r_cr; + u_long s_cr; + + u_long r_cc; + u_long s_cc; + + u_long r_cref; + u_long s_cref; + + u_long r_udt; + u_long s_udt; + + u_long r_udts; + u_long s_udts; + + u_long r_xudt; + u_long s_xudt; + + u_long r_dt1; + u_long s_dt1; + + u_long r_dt2; + u_long s_dt2; + + u_long r_it; + u_long s_it; + + u_long r_rlsd; + u_long s_rlsd; + + u_long r_rlc; + u_long s_rlc; +}sccp_msg_rv_snd_statistic; +extern sccp_msg_rv_snd_statistic sccpmsg_rs_st; + + + +typedef struct SCCP_Capture_Buf +{ + u8 Pointer; + u8 Buffer[2560]; + u8 watch_dog[256]; +} +SCCP_Capture_Buf; +extern SCCP_Capture_Buf SCCPCapBuf; + + +#endif diff --git a/plat/sccp/src/include/sccp_func.h b/plat/sccp/src/include/sccp_func.h new file mode 100644 index 0000000..0fca1f4 --- /dev/null +++ b/plat/sccp/src/include/sccp_func.h @@ -0,0 +1,166 @@ +////////////////////////////////////////////////// +//Title : sccp_func.h +//Auhtor : Liu Wei +//Desc : SCCP function decl +//Created : 2007-04-22 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +/* sccp.c */ +void sccp_init(void); +void sccp_init_serial_number(BYTE *Serial); +void sccp_timer(void); +void sccp_reset(void); +int AddToIpList(DWORD ip, BYTE ssn); +int CollectLocalInfo(void); +int sccp_mnp_register(BYTE flag, BYTE routing_method, BYTE usertype); +int spSetGttAddr(u8 uGtType, u8 uSSN, u8 *uGtNum, struct SCCP_ADDRESS *pSpAddr); + +/* sccp_debug.c */ +void spLogDebug_setup(void); +void spLogDebug_timer(void); +int parsecmd(char *cmdstr); +int sccp_filter_msg(SCCP_ADDR *pSrcAddr, SCCP_ADDR *pDstAddr); +void spLogDebug_info(BYTE npage, BYTE nline, BYTE *pt, BYTE len); +void spLogDebug_csta(BYTE npage, int instance); +void spLogDebug_local(BYTE npage, BYTE nline); +void spLogDebug_related(BYTE npage, BYTE nline); +void spLogDebug_buffer(BYTE npage); +void spLogDebug_errorCapture(BYTE npage, BYTE nline); +void spLogDebug_WatchDog(BYTE npage); +void sccp_list_route(void); +void sccp_put_capture_logs(BYTE person, BYTE *pictures, int len); + +/* sccp_func.c */ +int ParseLine(char *str, char (*row)[128], int maxrow); +int GetEnt(FILE *fp, char *key, char *str); +BOOL isco(Intra_Msg *intramsg); +BOOL iscl(Intra_Msg *intramsg); +BOOL iscr(Intra_Msg *intramsg); + +/* sccp_gtt.c */ +int BuildRouteIndex(void); +u_short SelectRoute(BYTE *pDigits, BYTE DigitsLen); +int GetACNInfo(SCCP_ADDR *pAddr, BYTE **pAcnInfo); +void TranslateGT(SCCP_ADDR *pAddr, SCCP_ROUTE *pRoute); +int AddRoute(BYTE *pStartDigits, BYTE *pEndDigits, BYTE DigitsLen, u_short index); +int AddLargerNode(SCCP_ROUTE_NODE *pNode, BYTE *pDigits, BYTE DigitsLen, u_short index); +int AddLessNode(SCCP_ROUTE_NODE *pNode, BYTE *pDigits, BYTE DigitsLen, u_short index); +SCCP_ROUTE_NODE *NewNode(void); +int CheckGT(BYTE np, BYTE tt, BYTE *gt, BYTE gt_len); + +/* sccp_mib.c */ +void sccpmib_init(void); +void sccp_sethb(void); +int sccp_setmib(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen); +int sccp_getmib(BYTE oidlen, DWORD *oid, BYTE *pdata, BYTE *vartype); +void sccp_OMCIP_detect(DWORD ip); +void sccp_trapcallback(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD len, snmp_addr *addr); + +/* sccp_msg.c */ +int build_msg(BYTE *buf, Intra_Msg *intramsg, BYTE NetID, BYTE ansi_flag); +int parse_msg(BYTE *buf, Intra_Msg *intramsg, int len, BYTE NetID, BYTE ansi_flag); +int parse_oparam(BYTE *buf, int len, Intra_Msg *intramsg, BYTE NetID, BYTE ansi_flag); +int encode_int(BYTE *buf, unsigned int val, BYTE len); +unsigned int decode_int(BYTE *buf, BYTE len); +int encode_addr(BYTE *buf, SCCP_ADDR *addr, BYTE NetID); +int decode_addr(BYTE *buf, SCCP_ADDR *addr, BYTE NetID); +int encode_addr_Ansi(BYTE *buf, SCCP_ADDR *addr); +int decode_addr_Ansi(BYTE *buf, SCCP_ADDR *addr); + +/* sclc.c */ +int scrc2sclc(Intra_Msg *pIntraMsg); +int sclc_rf(Intra_Msg *pIntraMsg); +int scmg2sclc(Intra_Msg *pIntraMsg); +int sclc_send(SCLC_MSG *pmsg); +int sclc_receive(SCLC_MSG *pmsg, BYTE usertype); +void sclc_timer(void); +int sclc_mnp_send(SCLC_MSG *pmsg); +int SegmentingMsg(Intra_Msg *pIntraMsg); +int RecvXUDTMsg(Intra_Msg *pIntraMsg, BYTE nbuf); +int CheckSegUnID(Intra_Msg *pIntraMsg); +int RsmRegMsg(SCLC_MSG *pmsg, SCCP_SegMsgBuf *pSegMsgbuf, Intra_Msg *pIntraMsg); + +/* sccp_param.c */ +int GetMSISDNOfSSN(BYTE ssn, BYTE *msisdn); +int sccp_GetSSNType(BYTE ssn); +int sccp_loadparam(void); +void sccp_saveparam(void); +int sccp_setparam(DWORD *oid, BYTE *pdata, WORD datalen); +int sccp_getparam(DWORD *oid, BYTE *pdata, BYTE *vartype); +int SccpGetLocalIP(void); +int ParseLocalNode(char *str); +void ParseRouteInfo(char *str); +void ParseRLSSN(char *str); + +/* scmg.c */ +void localssn_timer(void); +int sclc2scmg(Intra_Msg *intramsg); +BOOL CheckAvail(SCCP_ADDR *addr); +BYTE ssn_status(int spc, BYTE ssn, BYTE NetID); +void spac(int spc, BYTE NetID); +void sppc(int spc, BYTE NetID); +void spcc(int spc, BYTE NetID); +int register_ssn(BYTE ssn, BYTE usertype); +void ssac(int spc, BYTE ssn, BYTE NetID, BOOL relay); +void sscc(int spc, BYTE ssn, BYTE NetID); +int stop_ssn(BYTE ssn); +void sspc(int spc, BYTE ssn, BYTE NetID, BOOL relay); +void sst_timer(void); +void lcst(int spc, BYTE ssn, BYTE ntype, BYTE NetID); +void bcst(BYTE ssn, BYTE ntype); +void bcst_relay(int spc, BYTE ssn, BYTE ntype, BYTE NetID); +int build_scmgmsg(BYTE *data, BYTE type, int spc, BYTE ssn, BYTE NetID); +int parse_scmgmsg(BYTE *data, BYTE *type, int *spc, BYTE *ssn, BYTE NetID); + +/* scrc.c */ +void scrc_timer(void); +int scrc_route(Intra_Msg *pIntraMsg, BOOL ForceAnsi); +int scrc_mnp_route(Intra_Msg *pIntraMsg, BOOL ForceAnsi); +int send_msg(Intra_Msg *pIntraMsg, BYTE ansi_flag); +int scrc_rf(Intra_Msg *pIntraMsg, BYTE AnsiFlag); +DWORD SelectIPOfSSN(BYTE ssn, BYTE sls, BOOL from_mtp); + +/* scoc_fsm.c */ +void coFsm ( ); + +/* scoc_func.c */ +void coInit ( u32 sysID, u32 localIP, u32 alterIP ); +void cr2coFailHandle(Intra_Msg *pIntraMsg, u8 uAnsiFlag, u8 uMsgtype); +int cr2co(Intra_Msg *pIntraMsg, u8 uAnsiFlag); +void co2cr(u16 wConnId, u8 uMsgType); +void co2ul(u16 wConnId, u8 uPri); +void co2scmg(void); +void co2co(u16 wConnId, u8 uPri); +int spCheckAudit(void); +int coNewCS(u16 wConnId, SCCP_ADDR *pAddr); +void coFreeCS(u16 wConnId); +void coFillCS(SP_PriPoolEle *pPri); +int coCheckCS(u16 wConnId, u8 uCState, u8 uSide); +void coTimerOut(u16 wConnId, u8 uPri); +void coTimerMng(void); +int coNewConnId(u8 uPri); +int coGetConnId(u8 *pSLR); +extern int coCheckResource ( ); +void spWatchDogStatic(u8 uDebugStaticMask); + +/* sccp_log.c */ +void spLog(char *info); +void spShowAddr(SCCP_ADDR *pAddr, const char *sAddrName); +void spLogDebug(DWORD mask, const char *fmt, ...); +void spShowErr(int checkFlag, char * str); +void spShowBCD(DWORD mask, BYTE *buf, int len); +void spLogSeg(SCCP_SegMsgBuf *pSegMsgbuf); +void spShowMsg(DWORD mask, const char *pDesc, Intra_Msg *pIntraMsg); +void spShowPrimitive(SP_UiPriPara *pUiPriParam, u8 uDirection); +void spLogStateError(u16 wConnId, u8 uErrCode); +void spLogTimerOut(u16 wConnId, u8 uTimerID); +void spShowUserData(SP_UiPriPara *pPri); + +/* scoc_pool.c */ +void spPoolInit(void); +int spPoolGet(SP_PriPoolEle *pPri, CO_Pool *pCoPool); +int spPoolPut(SP_PriPoolEle *pPri, CO_Pool *pCoPool); diff --git a/plat/sccp/src/include/sccp_pub.h b/plat/sccp/src/include/sccp_pub.h new file mode 100644 index 0000000..9f79c00 --- /dev/null +++ b/plat/sccp/src/include/sccp_pub.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////// +//Title : sccp_pub.h +//Auhtor : Liu Wei +//Desc : SCCP public header +//Created : 2007-05-07 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _SCCP_PUB_H_ +#define _SCCP_PUB_H_ + +#include "../../../public/src/include/includes.h" +#include "../../../public/src/include/public.h" +#include "../../../public/src/include/pub_debug.h" +#include "../../../public/src/include/pub_wnet.h" +#include "../../../public/src/include/pub_fmt.h" +#include "sccp.h" +#include "scoc.h" +#include "sccp_func.h" + +// fix multiple definition==================================== +extern SP_Entity tSpEntity; +extern SP_Entity *pSp; +extern SCCP_OPT SCCP_Param; +extern SCOC_BUF ScocBuf; +extern LOCAL_SSN LocalSSN[256]; +extern u8 ExistSSN[64]; +extern u8 ExistSSNNum; + +extern u8 MNP_Flag[2]; +extern SCCP_ROUTE RouteList[SCCP_ROUTE_NUM]; +extern SCCP_ACN_VER_TABLE acn_ver_table[SCCP_ROUTE_NUM]; +extern int RelatedSSNNum; +extern RL_SSN RelatedSSN[SCCP_RLSSN_NUM]; +extern int RelatedSPCNum; +extern RL_SPC RelatedSPC[SCCP_RLSPC_NUM]; +extern GTTATT_OMC GTTAttribute[SCCP_ROUTE_NUM]; +extern SCCP_CSTA SccpCsta[96]; +extern u_long SccpCstaInd; +extern sccp_msg_statistic sccpmsg_st; +extern sccp_msg_rv_snd_statistic sccpmsg_rs_st; +extern SCCP_Capture_Buf SCCPCapBuf; +extern _dpc2sls dpc2sls[256]; +// + +#endif + + + diff --git a/plat/sccp/src/include/sccpconst.h b/plat/sccp/src/include/sccpconst.h new file mode 100644 index 0000000..af6bf6b --- /dev/null +++ b/plat/sccp/src/include/sccpconst.h @@ -0,0 +1,503 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include "scoc_if.h" +#include "../../../public/src/include/includes.h" + +#ifndef _SCCP_CONST_DEF +#define _SCCP_CONST_DEF + +#define SCCP_CONF_FILE "./conf/sccp.conf" +#define SINGLE_MODE 1 +#define spLogDebug_MASK 0xFFFFFFFF + + +#define GetValueString(i,p,Maxtrix,IdMax) \ + { \ + if( (i) >= (IdMax) ) \ + { \ + (p) = (u8 *)Maxtrix[(IdMax)].pStr; \ + } \ + else \ + { \ + (p) = (u8 *)Maxtrix[(i)].pStr; \ + } \ + } + + +typedef enum SCCP_WATCH_DOG +{ + WDS_RECV_PRI, + +} +SP_WatchDog; + +#define SCCP_SHM_KEY 0x00116688 +#define SCCP_SHM_PERM 0666 +//#define SCCP_OID {1,3,6,1,4,1,1373,1,3,2,2,3} +#define SCCP_OID {1,3,6,1,4,1,1373,2,3,2,3} +#define SCCP_OIDLEN 11 +#define SCCP_SERNUM_LEN 4 + +/*Message type-----> */ +#define CR_MSG 1 +#define CC_MSG 2 +#define CREF_MSG 3 +#define RLSD_MSG 4 +#define RLC_MSG 5 +#define DT1_MSG 6 +#define DT2_MSG 7 +#define AK_MSG 8 +#define UDT_MSG 9 +#define UDTS_MSG 10 +#define ED_MSG 11 +#define EA_MSG 12 +#define RSR_MSG 13 +#define RSC_MSG 14 +#define ERR_MSG 15 +#define IT_MSG 16 +#define XUDT_MSG 17 +#define XUDTS_MSG 18 +#define LUDT_MSG 19 +#define LUDTS_MSG 20 +//Intra message type +#define RF_MSG 100 +/*SCMG Message */ +#define SSA_MSG 1 //subsystem allowed +#define SSP_MSG 2 //subsystem prohibited +#define SST_MSG 3 //subsystem status test +#define SOR_MSG 4 //subsystem out of service request +#define SOG_MSG 5 //subsystem out of service grant +#define SSC_MSG 6 //SCCP/subsystem congested +/*SCCP parameter name codes */ +#define P_EOP 0 +#define P_DLR 1 +#define P_SLR 2 +#define P_CDA 3 +#define P_CGA 4 +#define P_PLC 5 +#define P_EOD 6 +#define P_PR 7 +#define P_SEQ 8 +#define P_Credit 9 +#define P_RLC 10 +#define P_RTC 11 +#define P_RSC 12 +#define P_ERC 13 +#define P_RFC 14 +#define P_Data 15 +#define P_SEG 16 +#define P_HC 17 +#define P_Importance 18 +#define P_Ldata 19 +////////////////////////////////////////////////// +#define SCCP_SSN_NUM 256 +#define SCCP_RLSSN_NUM 128 +#define SCCP_RLSPC_NUM 64 +#define SCCP_ROUTE_NUM 1024 +#define SCCP_ROUTE_NODE_NUM 65535 + +#define LR_NUM 1024 +#define LR_MSG_NUM 50 +#define SS_MSG_NUM 1024 +#define SLS_NUM 16 +#define SCCP_MSG_MAXLEN 256 +#define MAX_HC 15 +#define SCOC_SSN 10 + +#define Unrestricted 1 +#define Restricted 0 + +#define RI_GT 0 //Route on GT +#define RI_SSN 1 //Route on SSN + +#define NP_IMSI 6 +#define NP_MSISDN 1 +#define NP_GT 7 + +#define TT_0 0 +#define TT_1 1 +#define TT_4 4 +//message source----> +#define FROM_MTP 1 +#define FROM_SCLC 2 +#define FROM_SCOC 3 +#define FROM_SCMG 4 +//subsystem number +#define SSN_NOTUSE 0 +#define SSN_SCMG 1 +#define SSN_ITU 2 //reserved for ITU-T allocation +#define SSN_ISUP 3 +#define SSN_OMC 4 +#define SSN_MAP 5 +#define SSN_HLR 6 +#define SSN_VLR 7 +#define SSN_MSC 8 +#define SSN_EIC 9 //Equipment Identifier Certer +#define SSN_RANAP 142 +#define SSN_AIF 254 + +//pool size +#define SP_POOL_SIZE 3 + +//scoc state +#define SCOC_IDLE 0 +#define SCOC_CPO 1 //connection pending outgoing +#define SCOC_CPI 2 //connection pending incoming +#define SCOC_CPMID 3 //connection pending(intermediate node) +#define SCOC_WCC 4 //Wait connection confirm +#define SCOC_ACTIVE 5 //Active +#define SCOC_MID 6 //Active(intermediate node) +#define SCOC_DP 7 //disconnect pending +#define SCOC_DPMID 8 //disconnect pending(intermediate node) + +#define SCOC_Interval 20*1000 //20ms +//Timer (SCMG) +#define T_idle 30 //(s) +#define T_sst 2 //20s interval = 10s +#define T_hbrecv 3 //30s interval = 10s + +//#define SST_Start 0 +//#define SST_Pend 1 +//#define SST_Stop 2 + +//SP/SCCP/SS status +#define ST_Disable 1 +#define ST_Congest 2 +#define ST_Enable 3 + +#define SCCPDB_TCAP 0x01 +#define SCCPDB_UDT 0x02 +#define SCCPDB_AIF 0x04 +#define SCCPDB_ERR 0x08 +#define SCCPDB_SCMG 0x10 +#define SCCPDB_TIME 0x20 +#define SCCPDB_SNMP 0x40 +#define SCCPDB_MSG 0x80 +#define SCCPDB_ADDR 0x100 +#define SCCPDB_STP 0x1000 +#define SCCPDB_USER 0x2000 +#define SCCPDB_MTP3 0x4000 +#define SCCPDB_XUDT 0x8000 + +/*******************Release cause*******************/ +#define RL_EUO 0 //end user originated +#define RL_EUC 1 //end user congestion +#define RL_EUF 2 //end user failure +#define RL_SUO 3 //SCCP user originated +#define RL_RPL 4 //remote procedure error +#define RL_ICD 5 //inconsistent connection data +#define RL_AF 6 //access failure +#define RL_AC 7 //access congestion +#define RL_SF 8 //subsystem failure +#define RL_SC 9 //subsystem congestion +#define RL_MF 10 //MTP failure +#define RL_NC 11 //network congestion +#define RL_EORT 12 //expiration of reset timer +#define RL_EORIT 13 //expriation of receive inactivity timer +#define RL_R 14 //reserved +#define RL_U 15 //unqualified +#define RL_SCCPF 16 //SCCP failure + +/*******************return cause*******************/ +#define RT_NTFN 0 //no translation for an address of such nature +#define RT_NTFA 1 //no translation for this specific address +#define RT_SC 2 //subsystem congestion +#define RT_SF 3 //subsystem failure +#define RT_UU 4 //unequipped user +#define RT_MF 5 //MTP failure +#define RT_NF 6 //network congestion +#define RT_U 7 //unqulified +#define RT_EIMT 8 //error in message transport +#define RT_EILP 9 //error in local processing +#define RT_DCPR 10 //destination cannot perform reassembly +#define RT_SCCPF 11 //SCCP failure +#define RT_HCV 12 //hop counter violation +#define RT_SNS 13 //segmentation not supported +#define RT_SMTF 14 //segmentation failure + +/*******************reset cause*******************/ +#define RS_EUO 0 //end user originated +#define RS_SUO 1 //SCCP user originated +#define RS_IPS 2 //incorrect P(S) +#define RS_IPR 3 //incorrect P(R) +#define RS_OFW 4 //remote procedure error-message out of window +#define RS_IPSAI 5 //remote procedure error-incorrect P(S) after initialization +#define RS_G 6 //remote procedure error-general +#define RS_REUO 7 //remote end user operational +#define RS_NO 8 //network operational +#define RS_AO 9 //access operational +#define RS_NC 10 //network congestion +#define RS_R 11 //reserved +#define RS_U 12 //unqualified + +#endif + +static const StringVal spUlPrimitiveStr[] = +{ + {N_UNITDATA_REQ , "N-Unit Data Request "}, + {N_UNITDATA_IND , "N-Unit Data Indicate "}, + {N_NOTICE_IND , "N-Notice Indicate "}, + {N_CONNECT_REQ , "N-Connect Request "}, + {N_CONNECT_IND , "N-Connect Indicate "}, + {N_CONNECT_RSP , "N-Connect Response "}, + {N_CONNECT_CFM , "N-Connect Confirm "}, + {N_DISCONNECT_REQ, "N-Disconnect Request "}, + {N_DISCONNECT_IND, "N-Disconnect Indicate"}, + {N_DATA_REQ , "N-DATA Request "}, + {N_DATA_IND , "N-DATA Indicate "}, + {N_DATAAK_REQ , "N-DataAk Request "}, + {N_DATAAK_IND , "N-DataAk Indicate "}, + {N_EDATA_REQ , "N-EData Request "}, + {N_EDATA_IND , "N-EData Indicate "}, + {N_RESET_REQ , "N-Reset Request "}, + {N_RESET_IND , "N-Reset Indicate "}, + {N_RESET_RSP , "N-Reset Response "}, + {N_RESET_CFM , "N-Reset Confirm "}, + {N_INFORM_REQ , "N-Inform Request "}, + {N_INFORM_IND , "N-Inform Indicate "}, + {SPUI_PRI_MAX , "Unknow SCCP Primitive"}, +}; + +#define spGetUlPrimitiveStr(e,p)\ + GetValueString(e,p,spUlPrimitiveStr,SPUI_PRI_MAX) + +typedef enum SCOC_MESSAGE_TYPE +{ + SP_MSG0_RESERVED, /* Reserved */ + SP_MSG_CR = 1, /* connection request */ + SP_MSG_CC = 2, /* connection confirm */ + SP_MSG_CREF = 3, /* connection refused */ + SP_MSG_RLSD = 4, /* release request */ + SP_MSG_RLC = 5, /* release confirm */ + SP_MSG_DT1 = 6, /* Data Form 1 */ + SP_MSG_DT2 = 7, /* Data Form 2 */ + SP_MSG_AK = 8, /* Data acknowledge */ + SP_MSG_UDT = 9, /* Unit data */ + SP_MSG_UDTS = 10, /* Unit data */ + SP_MSG_ED = 11, /* Expedited data */ + SP_MSG_EA = 12, /* Expedited data acknowledge */ + SP_MSG_RSR = 13, /* Reset request */ + SP_MSG_RSC = 14, /* Reset confirm */ + SP_MSG_ERR = 15, /* PDU error */ + SP_MSG_IT = 16, /* Inactivity test */ + SP_MSG_XUDT = 17, /* XUDT */ + SP_MSG_XUDTS= 18, /* XUDTS */ + SP_MSG_LUDT = 19, /* LUDT */ + SP_MSG_LUDTS= 20, /* LUDTS */ + SP_MSG_RF = 21, /* Routing Fail */ + SP_MSG_MAX , /* MAX message type undefine */ +} +CO_MsgType; + +static const StringVal sp_messagetype_str[] = +{ + {SP_MSG0_RESERVED, " Message Reserved" }, + {SP_MSG_CR, " Connection request" }, + {SP_MSG_CC, " Connection confirm" }, + {SP_MSG_CREF, " Connection refused" }, + {SP_MSG_RLSD, " Release request" }, + {SP_MSG_RLC, " Release confirm" }, + {SP_MSG_DT1, " Data Form 1" }, + {SP_MSG_DT2, " Data Form 2" }, + {SP_MSG_AK, " Data acknowledge" }, + {SP_MSG_UDT, " Unit data" }, + {SP_MSG_UDTS, " Unit data service" }, + {SP_MSG_ED, " Data acknowledge" }, + {SP_MSG_EA, " EData acknowledge" }, + {SP_MSG_RSR, " Reset request" }, + {SP_MSG_RSC, " Reset confirm" }, + {SP_MSG_ERR, " PDU error" }, + {SP_MSG_IT, " Inactivity test" }, + {SP_MSG_XUDT, " XUDT" }, + {SP_MSG_XUDTS, " XUDTS" }, + {SP_MSG_LUDT, " LUDT" }, + {SP_MSG_LUDTS, " LUDTS" }, + {SP_MSG_RF , " Routing Fail" }, + {SP_MSG_MAX, " Undefine" }, +}; + +#define spGetMsgStr(MsgId,pStr)\ + GetValueString(MsgId,pStr,sp_messagetype_str,SP_MSG_MAX) + +//temp define , define in pub_base.h +#define STR(s) #s +#define FILL_VALSTR(n) {n,#n} + +static const StringVal spTimerOutStr[] = +{ + FILL_VALSTR(T_CONNEST_OUT), + FILL_VALSTR(T_IAS_OUT), + FILL_VALSTR(T_IAR_OUT), + FILL_VALSTR(T_REPEATE_RLS_OUT), + FILL_VALSTR(T_RLS_OUT), + FILL_VALSTR(T_RESET_OUT), + FILL_VALSTR(T_GUARD_OUT), + FILL_VALSTR(T_INTERNAL_OUT), + FILL_VALSTR(SPTM_PRI_MAX), +}; + +#define spGetTimerOutStr(MsgId,pStr)\ + GetValueString(((MsgId)-SPCR_PRI_MAX-1),pStr,spTimerOutStr,SPTM_PRI_MAX) + + +#define T_UNDEFINE 100000 + +#define T_SP_10ms 1 +#define T_SP_1s T_SP_10ms*100 +#define T_SP_1MIN T_SP_1s*60 +#define T_CONNEST_MAX T_SP_1s*2 //1~2 sec +#define T_IAS_MAX T_SP_1MIN*5 //5~10 mins +#define T_IAR_MAX T_SP_1MIN*11 //11~21 mins +#define T_RLS_MAX T_SP_1s*15 //10~20 sec +#define T_REPEATE_RLS_MAX T_SP_1s*15 //10~20 sec +#define T_RESET_MAX T_SP_1s*15 //10~20 sec +#define T_GUARD_MAX T_SP_1MIN*24 //23~25 mins +#define T_INTERNAL_MAX T_SP_1MIN //1 mins + +typedef enum SCOC_TRANSITION_STATUS +{ + CO_STATUS_INIT, //Transtion initialed + CO_STATUS_IDLE, //status Idle + CO_STATUS_WTCC, //Wait Connection confirm + CO_STATUS_ACTV, //Active + CO_STATUS_CONP, //Connection pending + CO_STATUS_CPIC, //Connection pending incoming + CO_STATUS_CPOG, //Connection pending outgoing + CO_STATUS_DSCP, //Disconnect pending + CO_STATUS_DPIC, //Disconnect pending incoming + CO_STATUS_DPOG, //Disconnect pending outgoing + CO_STATUS_DPBH, //Disconnect pending both + CO_STATUS_NMOP, //Normal operation + CO_STATUS_WSEA, //Wait for sending EA Message + CO_STATUS_RSIC, //Reset outgoing + CO_STATUS_RSOG, //Reset incoming + CO_STATUS_RSBH, //Reset both + CO_STATUS_MTBK, //Maintenance blocking + CO_STATUS_RSTA, //Restart + CO_STATUS_MAX, +} +CO_Status; + +static const StringVal sp_co_state_str[] = +{ + {CO_STATUS_INIT, "Transtion initialed" }, + {CO_STATUS_IDLE, "status Idle" }, + {CO_STATUS_WTCC, "Wait Connection confirm" }, + {CO_STATUS_ACTV, "Active" }, + {CO_STATUS_CONP, "Connection pending " }, + {CO_STATUS_CPIC, "Connection pending incoming"}, + {CO_STATUS_CPOG, "Connection pending outgoing"}, + {CO_STATUS_DSCP, "Disconnect pending" }, + {CO_STATUS_DPIC, "Disconnect pending incoming"}, + {CO_STATUS_DPOG, "Disconnect pending outgoing"}, + {CO_STATUS_DPBH, "Disconnect pending both" }, + {CO_STATUS_NMOP, "Normal operation" }, + {CO_STATUS_WSEA, "Wait for sending EA Message"}, + {CO_STATUS_RSIC, "Reset outgoing" }, + {CO_STATUS_RSOG, "Reset incoming" }, + {CO_STATUS_RSBH, "Reset both" }, + {CO_STATUS_MTBK, "Maintenance blocking" }, + {CO_STATUS_RSTA, "Restart" }, + {CO_STATUS_MAX, "Error Transtion state" }, +}; + +#define spGetCoStateStr(s,p)\ + GetValueString(s,p,sp_co_state_str,CO_STATUS_MAX) + +typedef enum CO_INSTANCE_SIDE +{ + CO_INST_SIDE_ORG, + CO_INST_SIDE_DST, + CO_INST_SIDE_MID, + CO_INST_SIDE_MAX, +} +CO_InstSide; + +static const StringVal sp_co_instanceside_str[] = +{ + {CO_INST_SIDE_ORG, "Originating node side" }, + {CO_INST_SIDE_DST, "Destination node side" }, + {CO_INST_SIDE_MID, "intermidediate node side"}, + {CO_INST_SIDE_MAX, "Undefine Node Side" }, +}; + +#define spGetCoInstanceSide(s,p)\ + GetValueString(s,p,sp_co_instanceside_str,CO_INST_SIDE_MAX) + +static const StringVal co_reason_str[] = { + //reason : originated network serice provider + {REA_PDISC_ACNN, + "disconnection ¨Cabnormal condition(non-transient nature)" }, + {REA_PDISC_ACTN, "disconnection ¨Cabnormal condition of transient nature"}, + {REA_PDISC_IS, "disconnection ¨Cinvalid state1" }, + {REA_PDISC_RIP, "disconnection ¨Crelease in progress1" }, + {REA_PCREF_DAU, "CREF2 ¨Cdestination address unknown " }, + {REA_PCREF_DINC, + "CREF2 ¨Cdestination inaccessible/non-transient condition" }, + {REA_PCREF_DITCs, "CREF2 ¨Cdestination inaccessible/transient condition" }, + {REA_PCREF_QNANC, "CREF2 ¨CQOS not available/non-transient condition" }, + {REA_PCREF_QNATC, "CREF2 ¨CQOS not available/transient condition" }, + {REA_PCREF_RUNC, "CREF2 ¨Creason unspecified/non-transient condition" }, + {REA_PCREF_RUTC, "CREF2 ¨Creason unspecified/transient condition" }, + {REA_PCREF_LE, "CREF2 ¨Clocal error1" }, + {REA_PCREF_IS, "CREF2 ¨Cinvalid state1" }, + {REA_PCREF_NT, "CREF2 ¨Cno translation1" }, + {REA_PCREF_IRP, "CREF2 ¨Cin restart phase1" }, + {REA_PCREF_HCV, "CREF2 ¨Chop counter violation" }, + + //reason : originated network serice user + {REA_UDISC_NC, "disconnection ¨Cnormal condition" }, + {REA_UDISC_ABC, "disconnection ¨Cabnormal condition" }, + {REA_UDISC_EUC, "disconnection ¨Cend user congestion" }, + {REA_UDISC_EUF, "disconnection ¨Cend user failure" }, + {REA_UDISC_SUO, "disconnection ¨CSCCP user originated" }, + {REA_UDISC_ACC, "disconnection ¨Caccess congestion" }, + {REA_UDISC_AF, "disconnection ¨Caccess failure" }, + {REA_UDISC_SC, "disconnection ¨Csubsystem congestion" }, + {REA_UCREF_NTC, "CREF2¨Cnon-transient condition" }, + {REA_UCREF_TC, "CREF2¨Ctransient condition" }, + {REA_UCREF_IIIN, "CREF2¨Cincompatible information in NSDUs" }, + {REA_UCREF_EUO, "CREF2¨Cend user originated" }, + {REA_UCREF_EUC, "CREF2¨Cend user congestion" }, + {REA_UCREF_EUF, "CREF2¨Cend user failure" }, + {REA_UCREF_SUO, "CREF2 ¨CSCCP user originated" }, + {REA_UCREF_ACC, "CREF2 ¨Caccess congestion" }, + {REA_UCREF_AF, "CREF2 ¨Caccess failure" }, + {REA_UCREF_SC, "CREF2 ¨Csubsystem congestion" }, + + //Notice service reason : N-inform values + {REA_NINFO_FAIL, "work service provider failure" }, + {REA_NINFO_CONG, "work service congestion" }, + {REA_NINFO_PQC, "work service provider QOS change" }, + {REA_UINFO_FAIL, "work service user failure" }, + {REA_UINFO_CONG, "work service user congestion" }, + {REA_UINFO_PQC, "work service user QOS change" }, + {REA_INFO_USPC, "reason unspecified" }, + + {REA_UNDEFINED, "Undefined" }, +}; + +#define coGetReasonStr(r,p)\ + GetValueString(r,p,co_reason_str,REA_UNDEFINED) + + +typedef enum SCOC_INTERNAL_ERROR +{ + CO_FATAL_STATE, + CO_FATAL_SIDE, +} +CO_InterErr; + diff --git a/plat/sccp/src/include/sccpconst.h.bak b/plat/sccp/src/include/sccpconst.h.bak new file mode 100644 index 0000000..dc65092 --- /dev/null +++ b/plat/sccp/src/include/sccpconst.h.bak @@ -0,0 +1,503 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scoc_if.h" +#include "../../../public/src/include/includes.h" + +#ifndef _SCCP_CONST_DEF +#define _SCCP_CONST_DEF + +#define SCCP_CONF_FILE "./conf/sccp.conf" +#define SINGLE_MODE 1 +#define spLogDebug_MASK 0xFFFFFFFF + + +#define GetValueString(i,p,Maxtrix,IdMax) \ + { \ + if( (i) >= (IdMax) ) \ + { \ + (p) = (u8 *)Maxtrix[(IdMax)].pStr; \ + } \ + else \ + { \ + (p) = (u8 *)Maxtrix[(i)].pStr; \ + } \ + } + + +typedef enum SCCP_WATCH_DOG +{ + WDS_RECV_PRI, + +} +SP_WatchDog; + +#define SCCP_SHM_KEY 0x00116688 +#define SCCP_SHM_PERM 0666 +//#define SCCP_OID {1,3,6,1,4,1,1373,1,3,2,2,3} +#define SCCP_OID {1,3,6,1,4,1,1373,2,3,2,3} +#define SCCP_OIDLEN 11 +#define SCCP_SERNUM_LEN 4 + +/*Message type-----> */ +#define CR_MSG 1 +#define CC_MSG 2 +#define CREF_MSG 3 +#define RLSD_MSG 4 +#define RLC_MSG 5 +#define DT1_MSG 6 +#define DT2_MSG 7 +#define AK_MSG 8 +#define UDT_MSG 9 +#define UDTS_MSG 10 +#define ED_MSG 11 +#define EA_MSG 12 +#define RSR_MSG 13 +#define RSC_MSG 14 +#define ERR_MSG 15 +#define IT_MSG 16 +#define XUDT_MSG 17 +#define XUDTS_MSG 18 +#define LUDT_MSG 19 +#define LUDTS_MSG 20 +//Intra message type +#define RF_MSG 100 +/*SCMG Message */ +#define SSA_MSG 1 //subsystem allowed +#define SSP_MSG 2 //subsystem prohibited +#define SST_MSG 3 //subsystem status test +#define SOR_MSG 4 //subsystem out of service request +#define SOG_MSG 5 //subsystem out of service grant +#define SSC_MSG 6 //SCCP/subsystem congested +/*SCCP parameter name codes */ +#define P_EOP 0 +#define P_DLR 1 +#define P_SLR 2 +#define P_CDA 3 +#define P_CGA 4 +#define P_PLC 5 +#define P_EOD 6 +#define P_PR 7 +#define P_SEQ 8 +#define P_Credit 9 +#define P_RLC 10 +#define P_RTC 11 +#define P_RSC 12 +#define P_ERC 13 +#define P_RFC 14 +#define P_Data 15 +#define P_SEG 16 +#define P_HC 17 +#define P_Importance 18 +#define P_Ldata 19 +////////////////////////////////////////////////// +#define SCCP_SSN_NUM 256 +#define SCCP_RLSSN_NUM 128 +#define SCCP_RLSPC_NUM 64 +#define SCCP_ROUTE_NUM 1024 +#define SCCP_ROUTE_NODE_NUM 65535 + +#define LR_NUM 1024 +#define LR_MSG_NUM 50 +#define SS_MSG_NUM 1024 +#define SLS_NUM 16 +#define SCCP_MSG_MAXLEN 256 +#define MAX_HC 15 +#define SCOC_SSN 10 + +#define Unrestricted 1 +#define Restricted 0 + +#define RI_GT 0 //Route on GT +#define RI_SSN 1 //Route on SSN + +#define NP_IMSI 6 +#define NP_MSISDN 1 +#define NP_GT 7 + +#define TT_0 0 +#define TT_1 1 +#define TT_4 4 +//message source----> +#define FROM_MTP 1 +#define FROM_SCLC 2 +#define FROM_SCOC 3 +#define FROM_SCMG 4 +//subsystem number +#define SSN_NOTUSE 0 +#define SSN_SCMG 1 +#define SSN_ITU 2 //reserved for ITU-T allocation +#define SSN_ISUP 3 +#define SSN_OMC 4 +#define SSN_MAP 5 +#define SSN_HLR 6 +#define SSN_VLR 7 +#define SSN_MSC 8 +#define SSN_EIC 9 //Equipment Identifier Certer +#define SSN_RANAP 142 +#define SSN_AIF 254 + +//pool size +#define SP_POOL_SIZE 3 + +//scoc state +#define SCOC_IDLE 0 +#define SCOC_CPO 1 //connection pending outgoing +#define SCOC_CPI 2 //connection pending incoming +#define SCOC_CPMID 3 //connection pending(intermediate node) +#define SCOC_WCC 4 //Wait connection confirm +#define SCOC_ACTIVE 5 //Active +#define SCOC_MID 6 //Active(intermediate node) +#define SCOC_DP 7 //disconnect pending +#define SCOC_DPMID 8 //disconnect pending(intermediate node) + +#define SCOC_Interval 20*1000 //20ms +//Timer (SCMG) +#define T_idle 30 //(s) +#define T_sst 2 //20s interval = 10s +#define T_hbrecv 3 //30s interval = 10s + +//#define SST_Start 0 +//#define SST_Pend 1 +//#define SST_Stop 2 + +//SP/SCCP/SS status +#define ST_Disable 1 +#define ST_Congest 2 +#define ST_Enable 3 + +#define SCCPDB_TCAP 0x01 +#define SCCPDB_UDT 0x02 +#define SCCPDB_AIF 0x04 +#define SCCPDB_ERR 0x08 +#define SCCPDB_SCMG 0x10 +#define SCCPDB_TIME 0x20 +#define SCCPDB_SNMP 0x40 +#define SCCPDB_MSG 0x80 +#define SCCPDB_ADDR 0x100 +#define SCCPDB_STP 0x1000 +#define SCCPDB_USER 0x2000 +#define SCCPDB_MTP3 0x4000 +#define SCCPDB_XUDT 0x8000 + +/*******************Release cause*******************/ +#define RL_EUO 0 //end user originated +#define RL_EUC 1 //end user congestion +#define RL_EUF 2 //end user failure +#define RL_SUO 3 //SCCP user originated +#define RL_RPL 4 //remote procedure error +#define RL_ICD 5 //inconsistent connection data +#define RL_AF 6 //access failure +#define RL_AC 7 //access congestion +#define RL_SF 8 //subsystem failure +#define RL_SC 9 //subsystem congestion +#define RL_MF 10 //MTP failure +#define RL_NC 11 //network congestion +#define RL_EORT 12 //expiration of reset timer +#define RL_EORIT 13 //expriation of receive inactivity timer +#define RL_R 14 //reserved +#define RL_U 15 //unqualified +#define RL_SCCPF 16 //SCCP failure + +/*******************return cause*******************/ +#define RT_NTFN 0 //no translation for an address of such nature +#define RT_NTFA 1 //no translation for this specific address +#define RT_SC 2 //subsystem congestion +#define RT_SF 3 //subsystem failure +#define RT_UU 4 //unequipped user +#define RT_MF 5 //MTP failure +#define RT_NF 6 //network congestion +#define RT_U 7 //unqulified +#define RT_EIMT 8 //error in message transport +#define RT_EILP 9 //error in local processing +#define RT_DCPR 10 //destination cannot perform reassembly +#define RT_SCCPF 11 //SCCP failure +#define RT_HCV 12 //hop counter violation +#define RT_SNS 13 //segmentation not supported +#define RT_SMTF 14 //segmentation failure + +/*******************reset cause*******************/ +#define RS_EUO 0 //end user originated +#define RS_SUO 1 //SCCP user originated +#define RS_IPS 2 //incorrect P(S) +#define RS_IPR 3 //incorrect P(R) +#define RS_OFW 4 //remote procedure error-message out of window +#define RS_IPSAI 5 //remote procedure error-incorrect P(S) after initialization +#define RS_G 6 //remote procedure error-general +#define RS_REUO 7 //remote end user operational +#define RS_NO 8 //network operational +#define RS_AO 9 //access operational +#define RS_NC 10 //network congestion +#define RS_R 11 //reserved +#define RS_U 12 //unqualified + +#endif + +static const StringVal spUlPrimitiveStr[] = +{ + {N_UNITDATA_REQ , "N-Unit Data Request "}, + {N_UNITDATA_IND , "N-Unit Data Indicate "}, + {N_NOTICE_IND , "N-Notice Indicate "}, + {N_CONNECT_REQ , "N-Connect Request "}, + {N_CONNECT_IND , "N-Connect Indicate "}, + {N_CONNECT_RSP , "N-Connect Response "}, + {N_CONNECT_CFM , "N-Connect Confirm "}, + {N_DISCONNECT_REQ, "N-Disconnect Request "}, + {N_DISCONNECT_IND, "N-Disconnect Indicate"}, + {N_DATA_REQ , "N-DATA Request "}, + {N_DATA_IND , "N-DATA Indicate "}, + {N_DATAAK_REQ , "N-DataAk Request "}, + {N_DATAAK_IND , "N-DataAk Indicate "}, + {N_EDATA_REQ , "N-EData Request "}, + {N_EDATA_IND , "N-EData Indicate "}, + {N_RESET_REQ , "N-Reset Request "}, + {N_RESET_IND , "N-Reset Indicate "}, + {N_RESET_RSP , "N-Reset Response "}, + {N_RESET_CFM , "N-Reset Confirm "}, + {N_INFORM_REQ , "N-Inform Request "}, + {N_INFORM_IND , "N-Inform Indicate "}, + {SPUI_PRI_MAX , "Unknow SCCP Primitive"}, +}; + +#define spGetUlPrimitiveStr(e,p)\ + GetValueString(e,p,spUlPrimitiveStr,SPUI_PRI_MAX) + +typedef enum SCOC_MESSAGE_TYPE +{ + SP_MSG0_RESERVED, /* Reserved */ + SP_MSG_CR = 1, /* connection request */ + SP_MSG_CC = 2, /* connection confirm */ + SP_MSG_CREF = 3, /* connection refused */ + SP_MSG_RLSD = 4, /* release request */ + SP_MSG_RLC = 5, /* release confirm */ + SP_MSG_DT1 = 6, /* Data Form 1 */ + SP_MSG_DT2 = 7, /* Data Form 2 */ + SP_MSG_AK = 8, /* Data acknowledge */ + SP_MSG_UDT = 9, /* Unit data */ + SP_MSG_UDTS = 10, /* Unit data */ + SP_MSG_ED = 11, /* Expedited data */ + SP_MSG_EA = 12, /* Expedited data acknowledge */ + SP_MSG_RSR = 13, /* Reset request */ + SP_MSG_RSC = 14, /* Reset confirm */ + SP_MSG_ERR = 15, /* PDU error */ + SP_MSG_IT = 16, /* Inactivity test */ + SP_MSG_XUDT = 17, /* XUDT */ + SP_MSG_XUDTS= 18, /* XUDTS */ + SP_MSG_LUDT = 19, /* LUDT */ + SP_MSG_LUDTS= 20, /* LUDTS */ + SP_MSG_RF = 21, /* Routing Fail */ + SP_MSG_MAX , /* MAX message type undefine */ +} +CO_MsgType; + +static const StringVal sp_messagetype_str[] = +{ + {SP_MSG0_RESERVED, " Message Reserved" }, + {SP_MSG_CR, " Connection request" }, + {SP_MSG_CC, " Connection confirm" }, + {SP_MSG_CREF, " Connection refused" }, + {SP_MSG_RLSD, " Release request" }, + {SP_MSG_RLC, " Release confirm" }, + {SP_MSG_DT1, " Data Form 1" }, + {SP_MSG_DT2, " Data Form 2" }, + {SP_MSG_AK, " Data acknowledge" }, + {SP_MSG_UDT, " Unit data" }, + {SP_MSG_UDTS, " Unit data service" }, + {SP_MSG_ED, " Data acknowledge" }, + {SP_MSG_EA, " EData acknowledge" }, + {SP_MSG_RSR, " Reset request" }, + {SP_MSG_RSC, " Reset confirm" }, + {SP_MSG_ERR, " PDU error" }, + {SP_MSG_IT, " Inactivity test" }, + {SP_MSG_XUDT, " XUDT" }, + {SP_MSG_XUDTS, " XUDTS" }, + {SP_MSG_LUDT, " LUDT" }, + {SP_MSG_LUDTS, " LUDTS" }, + {SP_MSG_RF , " Routing Fail" }, + {SP_MSG_MAX, " Undefine" }, +}; + +#define spGetMsgStr(MsgId,pStr)\ + GetValueString(MsgId,pStr,sp_messagetype_str,SP_MSG_MAX) + +//temp define , define in pub_base.h +#define STR(s) #s +#define FILL_VALSTR(n) {n,#n} + +static const StringVal spTimerOutStr[] = +{ + FILL_VALSTR(T_CONNEST_OUT), + FILL_VALSTR(T_IAS_OUT), + FILL_VALSTR(T_IAR_OUT), + FILL_VALSTR(T_REPEATE_RLS_OUT), + FILL_VALSTR(T_RLS_OUT), + FILL_VALSTR(T_RESET_OUT), + FILL_VALSTR(T_GUARD_OUT), + FILL_VALSTR(T_INTERNAL_OUT), + FILL_VALSTR(SPTM_PRI_MAX), +}; + +#define spGetTimerOutStr(MsgId,pStr)\ + GetValueString(((MsgId)-SPCR_PRI_MAX-1),pStr,spTimerOutStr,SPTM_PRI_MAX) + + +#define T_UNDEFINE 100000 + +#define T_SP_10ms 1 +#define T_SP_1s T_SP_10ms*100 +#define T_SP_1MIN T_SP_1s*60 +#define T_CONNEST_MAX T_SP_1s*2 //1~2 sec +#define T_IAS_MAX T_SP_1MIN*5 //5~10 mins +#define T_IAR_MAX T_SP_1MIN*11 //11~21 mins +#define T_RLS_MAX T_SP_1s*15 //10~20 sec +#define T_REPEATE_RLS_MAX T_SP_1s*15 //10~20 sec +#define T_RESET_MAX T_SP_1s*15 //10~20 sec +#define T_GUARD_MAX T_SP_1MIN*24 //23~25 mins +#define T_INTERNAL_MAX T_SP_1MIN //1 mins + +typedef enum SCOC_TRANSITION_STATUS +{ + CO_STATUS_INIT, //Transtion initialed + CO_STATUS_IDLE, //status Idle + CO_STATUS_WTCC, //Wait Connection confirm + CO_STATUS_ACTV, //Active + CO_STATUS_CONP, //Connection pending + CO_STATUS_CPIC, //Connection pending incoming + CO_STATUS_CPOG, //Connection pending outgoing + CO_STATUS_DSCP, //Disconnect pending + CO_STATUS_DPIC, //Disconnect pending incoming + CO_STATUS_DPOG, //Disconnect pending outgoing + CO_STATUS_DPBH, //Disconnect pending both + CO_STATUS_NMOP, //Normal operation + CO_STATUS_WSEA, //Wait for sending EA Message + CO_STATUS_RSIC, //Reset outgoing + CO_STATUS_RSOG, //Reset incoming + CO_STATUS_RSBH, //Reset both + CO_STATUS_MTBK, //Maintenance blocking + CO_STATUS_RSTA, //Restart + CO_STATUS_MAX, +} +CO_Status; + +static const StringVal sp_co_state_str[] = +{ + {CO_STATUS_INIT, "Transtion initialed" }, + {CO_STATUS_IDLE, "status Idle" }, + {CO_STATUS_WTCC, "Wait Connection confirm" }, + {CO_STATUS_ACTV, "Active" }, + {CO_STATUS_CONP, "Connection pending " }, + {CO_STATUS_CPIC, "Connection pending incoming"}, + {CO_STATUS_CPOG, "Connection pending outgoing"}, + {CO_STATUS_DSCP, "Disconnect pending" }, + {CO_STATUS_DPIC, "Disconnect pending incoming"}, + {CO_STATUS_DPOG, "Disconnect pending outgoing"}, + {CO_STATUS_DPBH, "Disconnect pending both" }, + {CO_STATUS_NMOP, "Normal operation" }, + {CO_STATUS_WSEA, "Wait for sending EA Message"}, + {CO_STATUS_RSIC, "Reset outgoing" }, + {CO_STATUS_RSOG, "Reset incoming" }, + {CO_STATUS_RSBH, "Reset both" }, + {CO_STATUS_MTBK, "Maintenance blocking" }, + {CO_STATUS_RSTA, "Restart" }, + {CO_STATUS_MAX, "Error Transtion state" }, +}; + +#define spGetCoStateStr(s,p)\ + GetValueString(s,p,sp_co_state_str,CO_STATUS_MAX) + +typedef enum CO_INSTANCE_SIDE +{ + CO_INST_SIDE_ORG, + CO_INST_SIDE_DST, + CO_INST_SIDE_MID, + CO_INST_SIDE_MAX, +} +CO_InstSide; + +static const StringVal sp_co_instanceside_str[] = +{ + {CO_INST_SIDE_ORG, "Originating node side" }, + {CO_INST_SIDE_DST, "Destination node side" }, + {CO_INST_SIDE_MID, "intermidediate node side"}, + {CO_INST_SIDE_MAX, "Undefine Node Side" }, +}; + +#define spGetCoInstanceSide(s,p)\ + GetValueString(s,p,sp_co_instanceside_str,CO_INST_SIDE_MAX) + +static const StringVal co_reason_str[] = { + //reason : originated network serice provider + {REA_PDISC_ACNN, + "disconnection ¨Cabnormal condition(non-transient nature)" }, + {REA_PDISC_ACTN, "disconnection ¨Cabnormal condition of transient nature"}, + {REA_PDISC_IS, "disconnection ¨Cinvalid state1" }, + {REA_PDISC_RIP, "disconnection ¨Crelease in progress1" }, + {REA_PCREF_DAU, "CREF2 ¨Cdestination address unknown " }, + {REA_PCREF_DINC, + "CREF2 ¨Cdestination inaccessible/non-transient condition" }, + {REA_PCREF_DITCs, "CREF2 ¨Cdestination inaccessible/transient condition" }, + {REA_PCREF_QNANC, "CREF2 ¨CQOS not available/non-transient condition" }, + {REA_PCREF_QNATC, "CREF2 ¨CQOS not available/transient condition" }, + {REA_PCREF_RUNC, "CREF2 ¨Creason unspecified/non-transient condition" }, + {REA_PCREF_RUTC, "CREF2 ¨Creason unspecified/transient condition" }, + {REA_PCREF_LE, "CREF2 ¨Clocal error1" }, + {REA_PCREF_IS, "CREF2 ¨Cinvalid state1" }, + {REA_PCREF_NT, "CREF2 ¨Cno translation1" }, + {REA_PCREF_IRP, "CREF2 ¨Cin restart phase1" }, + {REA_PCREF_HCV, "CREF2 ¨Chop counter violation" }, + + //reason : originated network serice user + {REA_UDISC_NC, "disconnection ¨Cnormal condition" }, + {REA_UDISC_ABC, "disconnection ¨Cabnormal condition" }, + {REA_UDISC_EUC, "disconnection ¨Cend user congestion" }, + {REA_UDISC_EUF, "disconnection ¨Cend user failure" }, + {REA_UDISC_SUO, "disconnection ¨CSCCP user originated" }, + {REA_UDISC_ACC, "disconnection ¨Caccess congestion" }, + {REA_UDISC_AF, "disconnection ¨Caccess failure" }, + {REA_UDISC_SC, "disconnection ¨Csubsystem congestion" }, + {REA_UCREF_NTC, "CREF2¨Cnon-transient condition" }, + {REA_UCREF_TC, "CREF2¨Ctransient condition" }, + {REA_UCREF_IIIN, "CREF2¨Cincompatible information in NSDUs" }, + {REA_UCREF_EUO, "CREF2¨Cend user originated" }, + {REA_UCREF_EUC, "CREF2¨Cend user congestion" }, + {REA_UCREF_EUF, "CREF2¨Cend user failure" }, + {REA_UCREF_SUO, "CREF2 ¨CSCCP user originated" }, + {REA_UCREF_ACC, "CREF2 ¨Caccess congestion" }, + {REA_UCREF_AF, "CREF2 ¨Caccess failure" }, + {REA_UCREF_SC, "CREF2 ¨Csubsystem congestion" }, + + //Notice service reason : N-inform values + {REA_NINFO_FAIL, "work service provider failure" }, + {REA_NINFO_CONG, "work service congestion" }, + {REA_NINFO_PQC, "work service provider QOS change" }, + {REA_UINFO_FAIL, "work service user failure" }, + {REA_UINFO_CONG, "work service user congestion" }, + {REA_UINFO_PQC, "work service user QOS change" }, + {REA_INFO_USPC, "reason unspecified" }, + + {REA_UNDEFINED, "Undefined" }, +}; + +#define coGetReasonStr(r,p)\ + GetValueString(r,p,co_reason_str,REA_UNDEFINED) + + +typedef enum SCOC_INTERNAL_ERROR +{ + CO_FATAL_STATE, + CO_FATAL_SIDE, +} +CO_InterErr; + diff --git a/plat/sccp/src/include/scoc.h b/plat/sccp/src/include/scoc.h new file mode 100644 index 0000000..59978e3 --- /dev/null +++ b/plat/sccp/src/include/scoc.h @@ -0,0 +1,274 @@ +////////////////////////////////////////////////// +//Title : scoc.h +//Auhtor : Liu Wei +//Desc : SCCP Connection-Oriented Control +//Created : 2007-04-22 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _SCOC_H_ +#define _SCOC_H_ + +#include "scoc_if.h" +#include "../../../public/src/include/pub_list.h" + +#define spLogDebug_STATIC + +typedef struct SCCP_PRIMITIVE_CR_PRIMITIVE +{ + u8 uUiPri; + u8 uAnsiFlag; + u16 wConnId; + Intra_Msg tIntraMsg; +} +SP_CrPriPara; + +typedef union SCCP_PRIMITVE_POOL_Elemnet +{ + SP_UiPriPara tUiPri; + SP_CrPriPara tCrPri; +} +SP_PriPoolEle; + +typedef enum SCOC_FSM_ERROR +{ + ERR_NONE, //show state string + ERR_FSM_DISCARD, + ERR_FSM_ERROR, + ERR_FSM_FATAL, + ERR_FSM_UNEXPECT_SIDE, + ERR_FSM_RESERVED, + ERR_FSM_UNEXPECT_PRI, + ERR_FSM_UNKOWN_ERROR_CODE, + ERR_TIMER_OUT, +} +CO_FsmErr; + +typedef struct SCOC_QOS +{ + u8 uInSequence; + u8 uReturnOnErr; + u8 uImportance; + u8 uHopcount; + u8 uMbit; + u8 uRecvSequnce; + u8 uSendSequnce; +} +CO_Qos; + +typedef struct SCOC_CAUSE +{ + u8 uRelCause; + u8 uReturnCause; + u8 uResetCause; + u8 uErrorCause; + u8 uRejectCause; +} +CO_Cause; + +#define MAX_SCCP_MSG 256 + +typedef struct SCOC_Message +{ + u8 uMsgType; + u8 uMsgClass; + u8 uMsgFlag; + u8 aSLR[SP_REF_LEN]; // 0x01 SLR present + u8 aDLR[SP_REF_LEN]; // 0x02 DLR present + SCCP_ADDR tCDA; // 0x04 CDA present + SCCP_ADDR tCGA; // 0x08 CGA present + CO_Qos tQos; // 0x10 QOS present + CO_Cause tCause; // 0x20 CAUSE present + u8 aMsgConent[MAX_SCCP_MSG]; // 0x40 DATA present +} +CO_Msg; + +typedef struct CO_TIMER +{ + u32 tmConnEst; + u32 tmIas; + u32 tmIar; + u32 tmRepeatRel; + u32 tmRel; + u32 tmReset; //unsupportted now + u32 tmGuard; //unsupportted now + //u32 tmIas; + //u32 tmIar; + //u32 tmIT; + u32 tmInternal; +} +CO_Timer; + +typedef struct CO_CONNECTION_Section +{ + CO_Status uCState; + SP_Pri uPri; + u8 uAnsiFlag; + CO_InstSide uSide; + + u8 uSLS; + + u8 uNetId; + int nDPC; + int nOPC; + u8 aSLR[SP_REF_LEN]; + u8 aDLR[SP_REF_LEN]; + u8 uClass; + u8 uCredit; + u8 eREA; + u8 eOR; + + SCCP_ADDR tCDA; + SCCP_ADDR tCGA; + SCCP_ADDR tSPA; + + SP_UD tUD; + + CO_Timer tmSCOC; +} +CO_ConnSection; + +typedef struct SCOC_POOL_PRIMITIVE_IN +{ + +} +CO_PoolPriIn; + + +typedef struct SCLC_DATA_BLOCK +{ + +} +CL_DataBlock; + +typedef struct SCRC_DATA_BLOCK +{ + +} +CR_DataBlock; + +typedef struct SCMG_DATA_BLOCK +{ + +} +CM_DataBlock; + +#define CO_CS_MPORT 8192 + +#ifdef DEBUG + +typedef enum SCOC_DEBUG_STATIC_VALUE +{ + GET_IN_POOL = 30, + PUT_IN_POOL, + READ_IN_POOL, + WRITE_IN_POOL, + GET_OUT_POOL, + PUT_OUT_POOL, + PUT_ELE_APT, + PUT_ELE_SUC, + UL_POST_CO_APT, + UL_POST_CO, + CO_SUBMIT_UL_APT, + CO_SUBMIT_UL, + CO_TO_CR_APT, + CO_TO_CR, + CR_TO_CO_APT, + CR_TO_CO, + SP_TIMER_OUT, +} +CO_DebugStaticVal; + + +typedef struct SCOC_DEBUG_STATIC +{ + u32 dGetInPool; + u32 dPutInPool; + u32 dReadInPool; + u32 dWriteInPool; + + u32 dGetOutPool; + u32 dPutOutPool; + u32 dPutEleApt; + u32 dPutEleSuc; + + u32 dCoSubmitUlApt; + u32 dCoSubmitUl; + u32 dUlPostCoApt; + u32 dUlPostCo; + + u32 dCo2CrApt; + u32 dCo2Cr; + u32 dCr2CoApt; + u32 dCr2Co; + + u32 dTimerOut; + u32 dbusyElem; +} +CO_DebugStatic; +#endif + + + +typedef struct SCOC_DATA_BLOCK +{ + u32 wConnIdCount; + CO_ConnSection tCSInst[CO_CS_MPORT]; + CO_DebugStatic tCoDebugStatic; +} +CO_DataBlock; + +typedef struct SCCP_ENTITY +{ + u32 dLocalIP; + u32 dAlterIP; + u32 dSysID; + CL_DataBlock tCl; + CO_DataBlock tCo; + CR_DataBlock tCr; + CM_DataBlock tCm; +} +SP_Entity; + +//SP_Entity tSpEntity; +//SP_Entity *pSp; + + +typedef enum SCOC_POOL_OP +{ + CO_GET_POOL, + CO_READ_POOL, + CO_PUT_POOL, + CO_WRITE_POOL, +} +CO_PoolOp; + +typedef struct SCOC_POOL_ELEMENT +{ + POOL_ENTRY ( SCOC_POOL_ELEMENT ) tPointer; + SP_PriPoolEle tPri; + BYTE flag; +} +CO_PoolEle; + +typedef struct SCOC_POOL +{ + POOL_HEAD ( CO_PriPool, SCOC_POOL_ELEMENT ) tPoolHead; + struct CO_PriPool *pPoolHead; + int uMaxPoolSize; + int uPoolCount; +} +CO_Pool; + +#define MAX_IN_POOL 1024 +#define MAX_OUT_POOL 512 + +extern CO_Pool *pInCoPool; +extern CO_Pool *pOutCoPool[SP_POOL_SIZE]; + + + +#endif diff --git a/plat/sccp/src/include/scoc_if.h b/plat/sccp/src/include/scoc_if.h new file mode 100644 index 0000000..8e4a5e5 --- /dev/null +++ b/plat/sccp/src/include/scoc_if.h @@ -0,0 +1,560 @@ +////////////////////////////////////////////////// +//Title : SCCP_if.h +//Auhtor : Liu Wei +//Desc : SCOC interface header +//Created : 2007-05-07 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#ifndef _SCCP_IF_H_ +#define _SCCP_IF_H_ + +#include "../../../public/src/include/public.h" + +#define MAX_DIGITS 10 +#define SP_REF_LEN 3 + +/////////////////////////////////////////////////// +typedef struct SCCP_ADDRESS +{ + DWORD ip; + int DPC; + BYTE NetID; + BYTE SSN; + BYTE RI; + BYTE GTI; + BYTE TT; + BYTE NP; + BYTE ES; + BYTE NAI; + BYTE len; + BYTE GTAI[MAX_DIGITS]; + BYTE AI; +} +SCCP_ADDR; + +typedef enum SCCP_LI_MTP_PRIMITIVE +{ + MTP_TARNSFER, + MTP_RESUME, + MTP_STATUS, + MTP_UPU, +} +SP_LiMTPPri; + +typedef enum SCCP_UI_N_PRIMITIVE +{ + N_UNITDATA_REQ, + N_UNITDATA_IND, + N_NOTICE_IND, + N_CONNECT_REQ, + N_CONNECT_IND, + N_CONNECT_RSP, + N_CONNECT_CFM, + N_DISCONNECT_REQ, + N_DISCONNECT_IND, + N_DATA_REQ, + N_DATA_IND, + N_DATAAK_REQ, + N_DATAAK_IND, + N_EDATA_REQ, + N_EDATA_IND, + N_RESET_REQ, + N_RESET_IND, + N_RESET_RSP, + N_RESET_CFM, + N_INFORM_REQ, + N_INFORM_IND, + SPUI_PRI_MAX, + + R_CR , /* connection request */ + R_CC , /* connection confirm */ + R_CREF , /* connection refused */ + R_RLSD , /* release request */ + R_RLC , /* release confirm */ + R_DT1 , /* Data Form 1 */ + R_DT2 , /* Data Form 2 */ + R_AK , /* Data acknowledge */ + R_UDT , /* Unit data */ + R_UDTS , /* Unit data */ + R_ED , /* Expedited data */ + R_EA , /* Expedited data acknowledge */ + R_RSR , /* Reset request */ + R_RSC , /* Reset confirm */ + R_ERR , /* PDU error */ + R_IT , /* Inactivity test */ + R_XUDT , /* XUDT */ + R_XUDTS, /* XUDTS */ + R_LUDT , /* LUDT */ + R_LUDTS, /* LUDTS */ + R_RF , /* Routing Fail */ + R_RLS_ERR, /* Release err */ + R_CR2 , /* connection request type 2 */ + SPCR_PRI_MAX , /* MAX CR2CO Primitive */ + + T_CONNEST_OUT, + T_IAS_OUT, + T_IAR_OUT, + T_REPEATE_RLS_OUT, + T_RLS_OUT, + T_RESET_OUT, + T_GUARD_OUT, + T_INTERNAL_OUT, + SPTM_PRI_MAX, + + N_CONNECT_T1, + RELAY, + TRAFFIC, + NO_TRAFFIC, + I_DISCONNECT, + I_RESET, + I_CONGESTED, + I_UNCONGESTED, + I_RESET_REQ, + SP_PRI_MAX, +} +SP_Pri; + +/* + * /SCOC upper layer primitive parameters + * + * /CDA : Called address CGA : Calling address + * /CI : Connection identification + * /CRS : Confirm request slecttion + * /EDS : Expedited data selection + * /QOS : Quality of service parameter set + * /OR : Originator RA : Responding address + * /RCS : Receipt confirmation selection + * /REA : Reason OR : Originator + * /RR : Return Resaon SEQ : Sequence Control + * /UD : User data RO : Return Optinal selection + * + */ + +typedef struct SCCP_QUALITY_OF_SERVICE +{ + //reserved + u8 uQOS; +} +SP_QOS; //Quality of service parameter set + +typedef enum SCCP_ORIGINATOR +{ + NSP, //the network service provider + NSU, //the network service user + UNDEFINED, //undefined +} +SP_OR; //Originator + +typedef struct SCCP_REQUEST_CONFIRM_SELECTION +{ + //reserved + u8 uRCS; +} +SP_RCS; //Confirm request slecttion + +/* + * Reason parameter + * + * Note: coGetReasonStr(u8 Reason , char *pReasonStr) + * + */ + +typedef enum SCCP_REASON +{ + //reason : originated network serice provider + REA_PDISC_ACNN, //Disconn ¨Cabnormal condition of non-transient nature + REA_PDISC_ACTN, //Disconn ¨Cabnormal condition of transient nature + REA_PDISC_IS, //Disconn ¨Cinvalid state1 + REA_PDISC_RIP, //Disconn -release in progress1 + REA_PCREF_DAU, //CREF ¨Cdestination address unknown(non-transient condition) + REA_PCREF_DINC, //CREF2 ¨Cdestination inaccessible/non-transient condition + REA_PCREF_DITCs, //CREF2 ¨Cdestination inaccessible/transient condition + REA_PCREF_QNANC, //CREF2 ¨CQOS not available/non-transient condition + REA_PCREF_QNATC, //CREF2 ¨CQOS not available/transient condition; + REA_PCREF_RUNC, //CREF2 ¨Creason unspecified/non-transient condition + REA_PCREF_RUTC, //CREF2 ¨Creason unspecified/transient condition; + REA_PCREF_LE, //CREF2 ¨Clocal error1; + REA_PCREF_IS, //CREF2 ¨Cinvalid state1; + REA_PCREF_NT, //CREF2 ¨Cno translation1; + REA_PCREF_IRP, //CREF2 ¨Cin restart phase1; + REA_PCREF_HCV, //CREF2 ¨Chop counter violation. + + //reason : originated network serice user + REA_UDISC_NC, //Disconn ¨Cnormal condition; + REA_UDISC_ABC, //Disconn ¨Cabnormal condition; + REA_UDISC_EUC, //Disconn ¨Cend user congestion; + REA_UDISC_EUF, //Disconn ¨Cend user failure; + REA_UDISC_SUO, //Disconn ¨CSCCP user originated; + REA_UDISC_ACC, //Disconn ¨Caccess congestion; + REA_UDISC_AF, //Disconn ¨Caccess failure; + REA_UDISC_SC, //Disconn ¨Csubsystem congestion; + REA_UCREF_NTC, //CREF2 -non-transient condition; + REA_UCREF_TC, //CREF2 -transient condition; + REA_UCREF_IIIN, //CREF2 -incompatible information in NSDUs; + REA_UCREF_EUO, //CREF2 -end user originated; + REA_UCREF_EUC, //CREF2 -end user congestion; + REA_UCREF_EUF, //CREF2 -end user failure; + REA_UCREF_SUO, //CREF2 ¨CSCCP user originated; + REA_UCREF_ACC, //CREF2 ¨Caccess congestion; + REA_UCREF_AF, //CREF2 ¨Caccess failure; + REA_UCREF_SC, //CREF2 ¨Csubsystem congestion. + + //Notice service reason : N-inform values + REA_NINFO_FAIL, //N-Inform ¨C network service provider failure; + REA_NINFO_CONG, //N-Inform ¨C network service congestion; + REA_NINFO_PQC, //N-Inform ¨C network service provider QOS change; + REA_UINFO_FAIL, //N-Inform ¨C network service user failure; + REA_UINFO_CONG, //N-Inform ¨C network service user congestion; + REA_UINFO_PQC, //N-Inform ¨C network service user QOS change; + REA_INFO_USPC, //N-Inform ¨C reason unspecified. + + REA_UNDEFINED, //undefined +} +SP_REA; //Reason + +typedef struct SCCP_RETURN_OPTINAL +{ + //reserved + u8 uRO; +} +SP_RO; //return Optinal + +typedef struct SCCP_RETURN_REASON +{ + //reserved + u8 uRR; +} +SP_RR; //Return Reason + +typedef struct SCCP_SEQUENCE +{ + //reserved + u8 uSEQ; +} +SP_SEQ; //Sequence control + +#define SP_MAX_UD 256 + +typedef struct SCCP_USER_DATA +{ + u8 uDataLen; + u8 aUserData[SP_MAX_UD]; +} +SP_UD; //User data + +typedef union SCCP_UI_PRIMITIVE_UNION +{ + struct PriNUnitDataReq //reserved for sclc ,not used now + { + u8 uSLS; + SP_SEQ tSEQ; + SCCP_ADDR tCDA; + SCCP_ADDR tCGA; + SP_RO tRO; + SP_UD tUD; + } + tPriNUDataReq; + + struct PriNUnitDataInd //reserved for sclc ,not used now + { + u8 uSLS; + SP_UD tUD; + SCCP_ADDR tCDA; + SCCP_ADDR tCGA; + } + tPriNUDataInd; + + struct PriNNoticeInd //reserved for sclc ,not used now + { + SP_RR tRR; + SP_UD tUD; + SCCP_ADDR tCDA; + SCCP_ADDR tCGA; + } + tPriNNoticeInd; + + struct PriNConnectReq + { + //Mandatory + SCCP_ADDR tCDA; + SP_QOS tQOS; + //Optianal + u8 uOptFlag; + u8 tEDS; + u8 uImp; + SCCP_ADDR tCGA; + SP_UD tUD; + } + tPriNConnReq; + + struct PriNConnectInd + { + //Mandatory + SCCP_ADDR tCDA; + SP_QOS tQOS; + u8 aSLR[SP_REF_LEN]; + u8 uSLS; + u32 OPC; + u8 NetID; + + //Optianal + u8 uOptFlag; + u8 uImp; + SCCP_ADDR tCGA; + SP_UD tUD; + } + tPriNConnInd; + + struct PriNConnectRsp + { + //Mandatory + SP_QOS tQOS; + + //Optianal + u8 uOptFlag; + u8 tEDS; + u8 uImp; + SCCP_ADDR tRA; + SP_UD tUD; + } + tPriNConnRsp; + + struct PriNConnectCfm + { + //Mandatory + SP_QOS tQOS; + + //Optianal + u8 uOptFlag; + u8 uImp; + SCCP_ADDR tRA; + SP_UD tUD; + } + tPriNConnCfm; + + struct PriNDisconnectReq + { + //Mandatory + //SP_OR eOR; //always NSU + SP_REA eREA; + + //Optianal + u8 uOptFlag; + u8 uImp; + SCCP_ADDR tRA; + SP_UD tUD; + } + tPriNDisconnReq; + + struct PriNDisconnectInd + { + //Mandatory + SP_OR eOR; + SP_REA eREA; + + //Optianal + u8 uOptFlag; + u8 uImp; + SCCP_ADDR tRA; + SP_UD tUD; + } + tPriNDisconnInd; + + struct PriNDataReq + { + //Mandatory + SP_UD tUD; + + //Optianal + u8 uImp; + } + tPriNDataReq; + + struct PriNDataInd + { + //Mandatory + SP_UD tUD; + + //Optianal + u8 uImp; + } + tPriNDataInd; + + struct PriNDataAkReq + { + } + tPriNDataAkReq; + + struct PriNDataAkInd + { + } + tPriNDataAkInd; + + struct PriNEDataReq + { + SP_UD tUD; + } + tPriNEDataReq; + + struct PriNEDataInd + { + SP_UD tUD; + } + tPriNEDataInd; + + struct PriNResetReq + { + //SP_OR tOR; //always NSU + SP_REA eREA; + } + tPriNResetReq; + + struct PriNResetInd + { + SP_REA eREA; + SP_OR tOR; + } + tPriNResetInd; + + struct PriNResetRsp + { + } + tPriNResetRsp; + + struct PriNResetCfm + { + } + tPriNResetCfm; + + struct PriNInformReq + { + SP_SEQ tQOS; + SP_REA eREA; + } + tPriNInformRsp; + + struct PriNInformInd + { + SP_SEQ tQOS; + SP_REA eREA; + } + tPriNInformInd; +} +SP_UiPriUnion; + +typedef struct SCCP_UI_PRIMITIVE_PARAMETERS +{ + u8 uUiPri; + u8 uAnsiFlag; + u16 wConnId; //return by SCCP while PostSp for N_CONN_REQ + SP_UiPriUnion tPriUnion; +} +SP_UiPriPara; + +/////////////////////////////////////////////////////////////////////////// +// +// Name : PostSp +// Function : Upper layer post request/response primitive to sccp +// Parameter: pUiPriParam [sccp UL primitive buffer pointer] +// Note : Sccp Connid is implicit returned in "pUiPriParam" buffer +// : while N-Connect requesing +// Return : 0 Post Fail 1 Post Successful +// +/////////////////////////////////////////////////////////////////////////// +int PostSp ( SP_UiPriPara * pUiPriParam ); + +/////////////////////////////////////////////////////////////////////////// +// +// Name : SpSubmit +// Function : Upper layer fetch indicate/confirm primitive submited from sccp +// Parameter: pUiPriParam [sccp UL primitive buffer pointer] +// uUlSapId [upper layer sap id [0 tcap 1 pps 2 smsc 3 aif 4 ranap 5 reserved] ] +// Return : 0 Fetch Fail 1 Fetch Successful +// +/////////////////////////////////////////////////////////////////////////// +int SpSubmit ( SP_UiPriPara * pUiPriParam, u8 uUlSapId ); + +/////////////////////Below is reserved, do not need to read///////////////////// + +/* + * \Inter-Layer Communication interface mode + * \ + * \Loose coupling mode : + * interface implementation based on message pool engine + * \Tight coupling mode : + * interface implementation based on function call and callback + * + * \Note : In order to be compatible with old user , use Loose coupling mode now + * + */ + +#define LOOSE_COUPLING_MODE 0 //Loose coupling mode +//#define TIGHT_COUPING_MODE + +#ifdef LOOSE_COUPLING_MODE //Loose coupling mode + +#else + +#ifdef TIGHT_COUPING_MODE //Tight coupling mode + +#error "Do not support Tight coupling mode ,please use \"LOOSE_COUPLING_MODE\" flag \n" + +/* + * \CFS(CallBack function Set) for SCCP sumbit primitives to SCCP user + * + * \The following Callback Fucntion set define the mapping of the primitives + * \which is submited to SCCP serivce user(s). It is used in tight coupling mode. + * + * \User A : Reserved for ISUP + * \User B : Q.711 Page 2 user part B not define + * \User C : Other SCCCP user e.g. AIF + */ + +typedef struct SCCP_SUBMIT_USERA_CFS +{ + //For Isup ,Not supported now +} +SP_UserA_CFS; + +typedef struct SCCP_SUBMIT_USERB_CFS +{ + //NULL Undefined in Q.711 +} +SP_UserB_CFS; + +typedef struct SCCP_SUBMIT_USERC_CFS +{ + void ( *spCBUi_N_UnitDataInd ) ( SCCP_ADDR * pCDA, SCCP_ADDR * pCGA, SP_UD * pUD ); + + void ( *spCBUi_N_NoticeInd ) ( SCCP_ADDR * pCDA, SCCP_ADDR * pCGA, SP_RR * pRR, SP_UD * pUD ); + + void ( *spCBUi_N_ConnectInd ) ( SP_QOS * pQOS, SP_UD * pUD, u8 uCI ); + + void ( *spCBUi_N_ConnectCfm ) ( SP_QOS * pQOS, SP_UD * pUD, u8 uCI ); + + void ( *spCBUi_N_DisconnectInd ) ( SP_OR * pOR, SP_OR * pRA, SP_REA * pREA, SP_UD * pUD, u8 uCI ); + + void ( *spCBUi_N_DataInd ) ( ); + + void ( *spCBUi_N_DataAkInd ) ( ); + + void ( *spCBUi_N_EDataInd ) ( ); + + void ( *spCBUi_N_ResetInd ) ( SP_OR * pOR, SP_REA * pREA, u8 uCI ); + + void ( *spCBUi_N_ResetCfm ) ( ); + + void ( *spCBUi_N_InformInd ) ( ); +} +SP_UserC_CFS; + +#endif + +#endif +/////////////////////Above is reserved, do not need to read///////////////////// + +#endif diff --git a/plat/sccp/src/sccp.c b/plat/sccp/src/sccp.c new file mode 100644 index 0000000..87dd8b5 --- /dev/null +++ b/plat/sccp/src/sccp.c @@ -0,0 +1,399 @@ + +/**********************************************/ +/*Title: sccp.c */ +/*Descr: SCCP common procedure */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/*Modify: 2002-7-18 */ + +/**********************************************/ + +#include "./include/sccp.h" + +// fix multiple definition==================================== +SCCP_OPT SCCP_Param; +SCOC_BUF ScocBuf; +LOCAL_SSN LocalSSN[256]; +u8 ExistSSN[64]; +u8 ExistSSNNum; + +u8 MNP_Flag[2]; +SCCP_ROUTE RouteList[SCCP_ROUTE_NUM]; +SCCP_ACN_VER_TABLE acn_ver_table[SCCP_ROUTE_NUM]; +int RelatedSSNNum; +RL_SSN RelatedSSN[SCCP_RLSSN_NUM]; +int RelatedSPCNum; +RL_SPC RelatedSPC[SCCP_RLSPC_NUM]; +GTTATT_OMC GTTAttribute[SCCP_ROUTE_NUM]; +SCCP_CSTA SccpCsta[96]; +u_long SccpCstaInd; +sccp_msg_statistic sccpmsg_st; +sccp_msg_rv_snd_statistic sccpmsg_rs_st; +SCCP_Capture_Buf SCCPCapBuf; +_dpc2sls dpc2sls[256]; //used for sequence control, add by Roy Jiang, 2007-09-17 +// + +extern BYTE sccpDebugFull; + +ull SCCPSerialNumber; + +/*===========export================*/ +void sccp_reset ( ); + +/*===========import================*/ +extern void scrc_timer ( void ); +extern void sclc_timer ( void ); +extern void sccpmib_init ( void ); //sccpmib.c +extern void sccp_sethb ( void ); //sccpmib.c +extern void spLogDebug_setup ( void ); //sccpdebug.c +extern void spLogDebug_timer ( void ); //sccpdebug.c +extern void spLogDebug_csta ( BYTE npage, int instance ); //sccpdebug.c +extern void spLogDebug_local ( BYTE npage, BYTE nline ); +extern void localssn_timer ( void ); //scmg.c +extern void sst_timer ( void ); //scmg.c +extern int sccp_loadparam ( void ); //sccpparam.c +extern int BuildRouteIndex ( void ); +extern int GetMSISDNOfSSN(BYTE ssn, BYTE *msisdn); +extern int sccp_GetSSNType(BYTE ssn); +extern void coInit( ); +extern void coFsm( ); +extern void coTimerMng ( ); +extern int checkSccpSaveFlag(); +extern void sccpDisableSaveFlag(); +extern void sccp_saveparam(); + +/*===========private================*/ +int CollectLocalInfo ( ); +extern u32 dAlterIpBackup; //for protection +void sccp_init ( u32 sysID, u32 localIP, u32 alterIP ) +{ + long l_time; + struct tm *t; + static BYTE initonce = 0; + int i; + BYTE version[3] = SCCP_VERSION; + + if( initonce == 1 ) + return; + memcpy ( SCCP_Param.version, version, 3 ); + SCCPSerialNumber = 0; + sccp_reset ( ); + + /*initialize global parameter */ + memset(dpc2sls, 0xFF, sizeof(dpc2sls)); + + LocalSSN[1].ip[0] = INADDR_NONE; + LocalSSN[1].status[0] = ST_Enable; + + for ( i = 0; i < 256; i++ ) + LocalSSN[i].RegFlag = 0; + + l_time = time ( NULL ); + t = localtime ( (time_t *)&l_time ); + if( t == NULL ) + { + assert( 0 && "syscall: localtime fail "); + exit(0); + } + SccpCstaInd = t->tm_hour * 4 + t->tm_min / 15; + SccpCsta[SccpCstaInd].timestamp = l_time; + + coInit ( sysID, localIP, alterIP ); + dAlterIpBackup = alterIP; + sccpmib_init ( ); + + spLogDebug_setup ( ); + spLogDebug_csta ( 1, SccpCstaInd ); + + printf ( "%ld-%d-%d %d:%d:%d\n", l_time, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec ); + printf ( "SCCP Version V%d.%d.%02d ...... Finish initialization!\n", SCCP_Param.version[0], SCCP_Param.version[1], SCCP_Param.version[2] ); + initonce = 1; +} + +void sccp_init_serial_number ( BYTE * Serial ) +{ + SCCPSerialNumber = Str2Ull ( (char *)Serial ); +} + +void sccp_timer ( ) //called per 10ms +{ + static WORD m_state = 0, seconds10=0,ch = 0; + struct tm *t; + long l_time; + + // BYTE flag; + + // flag = inb(0x0378); + // outb((flag | 0x04), 0x0378); + + //20ms task===> + sccpDebugFull = 0; + sclc_timer ( ); + scrc_timer ( ); + + coFsm ( ); + + spLogDebug_timer ( ); + + + coTimerMng(); + + if( SCCP_Param.T_reset > 0 ) + SCCP_Param.T_reset--; + else if( SCCP_Param.T_reset == 0 ) + { + spLogDebug_local ( 2, 1 ); + BuildRouteIndex ( ); + CollectLocalInfo ( ); + + SCCP_Param.T_reset = -1; + } + //10s task===> + switch ( ( m_state++ ) % 500 ) + { + case 0: //switch csta buffer + l_time = time ( NULL ); + t = localtime ( (time_t *)&l_time ); + if( t == NULL ) + { + assert( 0 && "syscall: localtime fail "); + exit(0); + } + if( ch == 0 && t->tm_min % 15 == 0 ) + { + SccpCstaInd = t->tm_hour * 4 + t->tm_min / 15; + + memset ( &SccpCsta[SccpCstaInd], 0, sizeof ( SCCP_CSTA ) ); + SccpCsta[SccpCstaInd].timestamp = l_time; + + spLogDebug_csta ( 1, SccpCstaInd ); + ch = 1; + } + if( t->tm_min % 15 != 0 ) + ch = 0; + break; + case 100: //SST + sst_timer ( ); + break; + case 200: + sccp_sethb ( ); + break; + case 300: + localssn_timer ( ); + break; + case 400: + break; + } + if(seconds10++>1000) + { + seconds10 = 0; + if(checkSccpSaveFlag()) + { + sccp_saveparam ( ); + sccpDisableSaveFlag(); + } + } + // outb(flag & 0xFB,0x0378); +} + +void sccp_reset ( ) +{ + DWORD oid[20] = { 1, 3, 6, 1, 4, 1, 1373, 2, 3, 2, 2, 2, 2, 1, 0 };//MTP3_OID + BYTE msg[64]; + BYTE spclen, temp; + int i, len; + + //get parameter from mtp3 + SCCP_Param.status = 2; + + if( get_response ( 14, oid, msg, &temp ) < 0 ) + { + SCCP_Param.status = 0; + return; + } + spclen = msg[0]; + SCCP_Param.spclen[0] = ( spclen & 0x01 ) == 0x01 ? 3 : 2; + SCCP_Param.spclen[1] = ( spclen & 0x02 ) == 0x02 ? 3 : 2; + SCCP_Param.spclen[2] = ( spclen & 0x04 ) == 0x04 ? 3 : 2; + SCCP_Param.spclen[3] = ( spclen & 0x08 ) == 0x08 ? 3 : 2; + + oid[12] = 3; + + for ( i = 0; i < 4; i++ ) + { + oid[13] = 1; + oid[12] = 2+i; + if( ( len = get_response ( 14, oid, msg, &temp ) ) < 0 ) + { + SCCP_Param.status = 0; + return; + } + SCCP_Param.spc[i] = decode_integer ( msg, len ); + oid[13] = 2; + if( ( len = get_response ( 14, oid, msg, &temp ) ) < 0 ) + { + SCCP_Param.status = 0; + return; + } + SCCP_Param.spclen[i] = msg[0] == 0x01 ? 3 : 2;; + } + + SCCP_Param.OMCIP[0] = 0; + SCCP_Param.OMCIP[1] = 0; + + sccp_loadparam ( ); + + CollectLocalInfo ( ); + + spLogDebug_local ( 2, 1 ); + BuildRouteIndex ( ); + SCCP_Param.T_reset = -1; +} + +int AddToIpList ( DWORD ip, BYTE ssn ) +{ + int i; + + if( ip == SCCP_Param.ip && ssn != 4 ) + return 0; + for ( i = 0; i < ExistIPNum; i++ ) + { + if( ExistIP[i] == ip ) + return 0; + } + ExistIP[ExistIPNum] = ip; + ExistIPNum = ( ExistIPNum + 1 ) % 64; + return 1; +} + +int CollectLocalInfo ( ) +{ + int i; + BYTE RegNum = 0; + + SCCP_Param.OMCIP[0] = 0; + SCCP_Param.OMCIP[1] = 0; + ExistSSNNum = 0; + ExistIPNum = 0; + + for ( i = 2; i < 256; i++ ) + { + if( i != 4 ) + { + if( LocalSSN[i].status[0] ) + AddToIpList ( LocalSSN[i].ip[0], i ); + else if( LocalSSN[i].status[1] == 0 ) + continue; + if( LocalSSN[i].status[1] ) + AddToIpList ( LocalSSN[i].ip[1], i ); + } + + if( LocalSSN[i].RegFlag && LocalSSN[i].local ) + { + LocalSSN[i].status[( LocalSSN[i].local - 1 ) % 2] = 3; + SCCP_Param.RegSSN[RegNum] = i; + RegNum = ( RegNum + 1 ) % 32; + } + ExistSSN[ExistSSNNum++] = i; + } + + SCCP_Param.RegNum = RegNum; + return 1; +} + +/*int LocalSSN_ANSIFlag(BYTE SSN) + { + return LocalSSN[SSN].ANSIFlag; + } */ + +int sccp_mnp_register ( BYTE flag, BYTE routing_method, BYTE usertype ) +{ + MNP_Flag[0] = flag % 3; + MNP_Flag[1] = routing_method % 3; + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +// spSetGttAddr /// +// uGtType : 0 Setting by SSN /// +// 1 Setting by GtNum [MSISDN] /// +// 2 Setting by GtNum [IMSI ] /// +// /// +/////////////////////////////////////////////////////////////////////////// + +int spSetGttAddr ( u8 uGtType , u8 uSSN, u8 *uGtNum , struct SCCP_ADDRESS *pSpAddr ) +{ + int nFlag; + + pSpAddr->SSN = uSSN; + pSpAddr->DPC = 0; // set SCCP address + pSpAddr->NetID = 4; // dedicate by GT table + pSpAddr->RI = RI_GT; // Routing by GT + if(uSSN == 247) + pSpAddr->RI = RI_SSN; //For IN-MNP + pSpAddr->NAI = 4; // + pSpAddr->ip = 0; + + nFlag = sccp_GetSSNType ( uSSN ); //0=ITU,1=ANSI + pSpAddr->ip = 0; + + if( nFlag == 1 ) //ANSI SCCP + { + if( uGtType < 2 ) + { + pSpAddr->NP = 0; // MSISDN + if(uSSN == 6) + pSpAddr->TT = 14; + else + pSpAddr->TT = 10; + } + else + { + pSpAddr->NP = 6; // IMSI + pSpAddr->TT = 9; + } + pSpAddr->GTI = 0x02; + } + else if( nFlag == 0 ) //ITU SCCP + { + pSpAddr->TT = 0; + if( uGtType < 2 ) + { + pSpAddr->NP = 1; // MSISDN + } + else + { + pSpAddr->NP = 6; // IMSI + } + pSpAddr->GTI = 0x04; + } + + + if( 0 == uGtType ) + { + u8 aGTT[ISDN_LEN]; + + if( GetMSISDNOfSSN ( uSSN, aGTT ) ) + { + u8 aISDN[ISDN_LEN]; + + GttToIsdn ( aISDN, aGTT ); + pSpAddr->len = IsdnToGtai( pSpAddr->GTAI ,aISDN ); + return pSpAddr->len; + } + } + else if( 1 == uGtType ) + { + pSpAddr->len = IsdnToGtai ( pSpAddr->GTAI, uGtNum ); + return pSpAddr->len; + } + else if( 2 == uGtType ) + { + ImsiNtoA( pSpAddr->GTAI , uGtNum); + pSpAddr->len = IMSI_LEN; + return pSpAddr->len; + } + return 0; +} + diff --git a/plat/sccp/src/sccp_debug.c b/plat/sccp/src/sccp_debug.c new file mode 100644 index 0000000..06c7e4a --- /dev/null +++ b/plat/sccp/src/sccp_debug.c @@ -0,0 +1,683 @@ + +/**************************************************/ +/*Title: sccpdebug.c */ +/*Descr: SCCP Debug Tool */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/*Modify: 2003-5-9 */ + +/**************************************************/ +#include "./include/sccp.h" +#include "./include/scoc.h" + +// fix multiple definition==================================== +extern SP_Entity *pSp; +// + +int sccp_send_netcap = 0; +char sccp_debug_buf[5120]; +static char asc_in[256]; +static DWORD title_id[20] = { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 2, 3, 1, 2, 4, 8, 1 }; +unsigned long spLogDebug_mask = 0; +static char sccp_ver[16]; + +extern void spLog ( char *info ); + +void spLogDebug_WatchDog ( BYTE npage ); +SCCP_FILTER sccpFilter[8]; +BYTE sccpFilterIndex = 0; +int spLog_fd = -1; +static char help_info[] = "Commands provided now:\r\n\ +help T001\r\n\ +log all Output all debug information\r\n\ +log none Turn off all information\r\n\ +log error on/off Show error information\r\n\ +log addr on/off Show address of sccp message\r\n\ +log data on/off Show data party of sccp message\r\n\ +log time on/off Show time when generate log\r\n\ +log udt on/off Show UDT message\r\n\ +log user on/off Show (UDT) message from user\r\n\ +log mtp3 on/off Show (UDT) message from mtp3\r\n\ +log aif on/off Show AIF message\r\n\ +log scmg on/of Show SCMG message\r\n\ +log snmp on/off Show SNMP message\r\n\ +log cond1 (and cond2...) Show message due to specified condition\r\n\ + One or more conditions could be taken:\r\n\ + src ssn=xx/dst ssn=xx/opc=xx/dpc=xx.\r\n\ + For example:log src ssn=7 and dst ssn=6\r\n\ +list route.x Print GTT Table, start from x, default 0 if not specified\r\n\ +list spc Print SPC of local node\r\n\ +save Save parameter\r\n\ +reset Reset SCCP Module\ +"; + +/*===========export===============*/ +void spLogDebug_setup ( ); +void spLogDebug_timer ( ); +void spLogDebug_csta ( BYTE npage, int instance ); +void spLogDebug_local ( BYTE npage, BYTE nline ); + +/*===========import================*/ +extern void sccp_saveparam ( ); +extern void sccp_reset ( ); +extern int ParseLine ( char *str, char ( *row )[128], int maxrow ); +//extern int Bcd2Str ( char *pStr, const BYTE * pBcd, int len ); +extern int Digits2Str ( char *pStr, BYTE * pDigits, int DigitsLen ); + +/*===========private===============*/ +static int parsecmd ( char *cmdstr ); +static void spLogDebug_info ( BYTE npage, BYTE nline, BYTE * pt, BYTE len ); +static void spLogDebug_related ( BYTE npage, BYTE nline ); +static void spLogDebug_buffer ( BYTE npage ); +static void spLogDebug_errorCapture ( BYTE npage, BYTE nline ); +static void sccp_list_route ( int pos ); + +void spLogDebug_setup ( ) +{ + DWORD ascout_id[20] = { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 2, 3, 1, 2, 4, 4 }; + DWORD ascin_id[20] = { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 2, 3, 1, 2, 4, 3 }; + DWORD status_id[20] = { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 2, 3, 1, 2, 4, 1 }; + DWORD name_id[20] = { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 2, 3, 1, 2, 4, 2 }; + BYTE debug_status = 1; + + sprintf ( sccp_ver, "V%d.%d.%02d", SCCP_Param.version[0], SCCP_Param.version[1], SCCP_Param.version[2] ); + debug_set_response ( 15, ascout_id, (BYTE *)sccp_debug_buf, 4096 ); + debug_set_response ( 15, ascin_id, (BYTE *)asc_in, 1 ); + debug_set_response ( 15, status_id, &debug_status, 1 ); + debug_set_response ( 15, name_id, (BYTE *)sccp_ver, strlen ( sccp_ver ) ); + + spLogDebug_local ( 2, 1 ); + spLogDebug_related ( 3, 0 ); + spLogDebug_buffer ( 4 ); + spLogDebug_errorCapture ( 5, 0 ); + spLogDebug_WatchDog ( 6 ); +} + +void spLogDebug_timer ( ) +{ + BYTE npage, nline; + + if( strlen ( asc_in ) <= 1 ) + return; + sccp_debug_buf[0] = '\0'; + npage = asc_in[0] - 1; + if( npage == 0 ) + { + parsecmd ( asc_in + 1 ); + asc_in[0] = '\0'; + return; + } + else if( asc_in[1] == 'c' || asc_in[1] == 'C' ) + { + memset ( &sccpmsg_st, 0, sizeof ( sccpmsg_st ) ); + memset ( &sccpmsg_rs_st, 0, sizeof ( sccpmsg_rs_st ) ); + memset ( &SCCPCapBuf, 0, sizeof ( SCCP_Capture_Buf ) ); + } + else + nline = atoi ( asc_in + 1 ); + + switch ( npage ) + { + case 1: //csta + spLogDebug_csta ( npage, nline ); + break; + case 2: //local subsystem + spLogDebug_local ( npage, nline ); + break; + case 3: //related subsystem + spLogDebug_related ( npage, nline ); + break; + case 5: //capture buffer + spLogDebug_errorCapture ( npage, nline ); + break; + } + asc_in[0] = '\0'; +} + +static int str2value ( char *str ) +{ + BYTE i = 0; + char *pHead = str, xstr[8] = "0"; + + while ( !isxdigit ( *pHead ) ) //8 lead-space max + { + if( i++ >= 8 ) + return -1; + pHead++; + } + i = 0; + while ( isxdigit ( pHead[i] ) && i < 6 ) + { + xstr[i] = pHead[i]; + i++; + } + xstr[6] = 0; + + return strtoul ( xstr, NULL, 16 ); +} + +static int parsecond ( char *cmdstr ) +{ + char *pKey = cmdstr, *pEQ, info[256] = "log ", tmpStr[64]; + + sccpFilter[sccpFilterIndex].flag = 0; + + if( ( pKey = strstr ( cmdstr, "opc" ) ) != NULL && ( pEQ = strchr ( pKey, '=' ) ) != NULL ) + { + sccpFilter[sccpFilterIndex].opc = str2value ( pEQ + 1 ); + if( sccpFilter[sccpFilterIndex].flag > 0 ) + strcat ( info, " and " ); + sprintf ( tmpStr, "opc = 0x%06x", sccpFilter[sccpFilterIndex].opc ); + strcat ( info, tmpStr ); + sccpFilter[sccpFilterIndex].flag |= 0x01; + } + if( ( pKey = strstr ( cmdstr, "dpc" ) ) != NULL && ( pEQ = strchr ( pKey, '=' ) ) != NULL ) + { + sccpFilter[sccpFilterIndex].dpc = str2value ( pEQ + 1 ); + if( sccpFilter[sccpFilterIndex].flag > 0 ) + strcat ( info, " and " ); + sprintf ( tmpStr, "dpc = 0x%06x", sccpFilter[sccpFilterIndex].opc ); + strcat ( info, tmpStr ); + sccpFilter[sccpFilterIndex].flag |= 0x02; + } + if( ( pKey = strstr ( cmdstr, "src ssn" ) ) != NULL && ( pEQ = strchr ( pKey, '=' ) ) != NULL ) + { + sccpFilter[sccpFilterIndex].src_ssn = str2value ( pEQ + 1 ); + if( sccpFilter[sccpFilterIndex].flag > 0 ) + strcat ( info, " and " ); + sprintf ( tmpStr, "src ssn = 0x%02x", sccpFilter[sccpFilterIndex].src_ssn ); + strcat ( info, tmpStr ); + sccpFilter[sccpFilterIndex].flag |= 0x04; + } + if( ( pKey = strstr ( cmdstr, "dst ssn" ) ) != NULL && ( pEQ = strchr ( pKey, '=' ) ) != NULL ) + { + sccpFilter[sccpFilterIndex].dst_ssn = str2value ( pEQ + 1 ); + if( sccpFilter[sccpFilterIndex].flag > 0 ) + strcat ( info, " and " ); + sprintf ( tmpStr, "dst ssn = 0x%02x", sccpFilter[sccpFilterIndex].dst_ssn ); + strcat ( info, tmpStr ); + sccpFilter[sccpFilterIndex].flag |= 0x08; + } + + if( sccpFilter[sccpFilterIndex].flag == 0 ) + { + spLog ( "Wrong condition" ); + return 0; + } + + sccpFilterIndex++; + spLog ( info ); + spLog ( "command OK" ); + return 1; +} + +int parsecmd ( char *cmdstr ) +{ + int i; + char info[256], *pCh; + + if( strstr ( cmdstr, "list route" ) != NULL ){ + int i = 0; + const int start_pos = 11; + while(isdigit(cmdstr[start_pos+i++])){ + if(i > 3){ + break; + } + } + + if (i > 0) + { + cmdstr[start_pos + i] = '\0'; + i = strtoul(cmdstr+start_pos, NULL, 10); + if (i > SCCP_ROUTE_NUM){ + char tmp_str[128]; + sprintf(tmp_str, "Invalid parameter value %d, max %d. replace with default 0", i, SCCP_ROUTE_NUM); + spLog ( tmp_str ); + i = 0; + } + } + sccp_list_route ( i ); + } + else if( strstr ( cmdstr, "help" ) != NULL || strstr ( cmdstr, "?" ) != NULL ) + spLog ( help_info ); + else if( strstr ( cmdstr, "save" ) != NULL ) + sccp_saveparam ( ); + else if( strstr ( cmdstr, "reset" ) != NULL ) + sccp_reset ( ); + else if( strstr ( cmdstr, "log all" ) != NULL ) + { + sccpFilterIndex = 0; + spLogDebug_mask = 0xFFFFFFFF; + } + else if( strstr ( cmdstr, "log none" ) != NULL ) + { + sccpFilterIndex = 0; + spLogDebug_mask = 0; + } + else if( strstr ( cmdstr, "log error on" ) != NULL ) + spLogDebug_mask |= SCCPDB_ERR; + else if( strstr ( cmdstr, "log error off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_ERR ); + else if( strstr ( cmdstr, "log udt on" ) != NULL ) + spLogDebug_mask |= SCCPDB_UDT; + else if( strstr ( cmdstr, "log udt off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_UDT ); + else if( strstr ( cmdstr, "log aif on" ) != NULL ) + spLogDebug_mask |= SCCPDB_AIF; + else if( strstr ( cmdstr, "log aif off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_AIF ); + else if( strstr ( cmdstr, "log mtp3 on" ) != NULL ) + spLogDebug_mask |= SCCPDB_MTP3; + else if( strstr ( cmdstr, "log mtp3 off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_MTP3 ); + else if( strstr ( cmdstr, "log user on" ) != NULL ) + spLogDebug_mask |= SCCPDB_USER; + else if( strstr ( cmdstr, "log user off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_USER ); + + else if( strstr ( cmdstr, "log scmg on" ) != NULL ) + spLogDebug_mask |= SCCPDB_SCMG; + else if( strstr ( cmdstr, "log scmg off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_SCMG ); + else if( strstr ( cmdstr, "log snmp on" ) != NULL ) + spLogDebug_mask |= SCCPDB_SNMP; + else if( strstr ( cmdstr, "log snmp off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_SNMP ); + else if( strstr ( cmdstr, "log data on" ) != NULL ) + spLogDebug_mask |= SCCPDB_MSG; + else if( strstr ( cmdstr, "log data off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_MSG ); + else if( strstr ( cmdstr, "log addr on" ) != NULL ) + spLogDebug_mask |= SCCPDB_ADDR; + else if( strstr ( cmdstr, "log addr off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_ADDR ); + else if( strstr ( cmdstr, "log time on" ) != NULL ) + spLogDebug_mask |= SCCPDB_TIME; + else if( strstr ( cmdstr, "log time off" ) != NULL ) + spLogDebug_mask &= ( ~SCCPDB_TIME ); + else if( strstr(cmdstr, "net cap start") !=NULL ) + { + sccp_send_netcap = 1; + spLog("sccp send netcap start"); + } + else if( strstr(cmdstr, "net cap stop") !=NULL ) + { + sccp_send_netcap = 0; + spLog("sccp send netcap end"); + } + else if( strncasecmp ( cmdstr, "log file on", 11 ) == 0 ) + { + if( spLog_fd != -1 ) + { + close ( spLog_fd ); + } + spLog_fd = open ( "./sccp.log", O_WRONLY | O_CREAT | O_TRUNC ); + } + else if( strncasecmp ( cmdstr, "log file off", 12 ) == 0 ) + { + if( spLog_fd != -1 ) + { + close ( spLog_fd ); + spLog_fd = -1; + } + } + else if( ( pCh = strstr ( cmdstr, "log" ) ) != NULL && strstr ( cmdstr, "=" ) != NULL ) + { + if( sccpFilterIndex >= 8 ) + { + spLog ( "Only 8 conditions can be set" ); + return 0; + } + return parsecond ( pCh + 4 ); + } + else if( strstr ( cmdstr, "list spc" ) != NULL ) + { + spLog ( "NI SPC_Len SPC" ); + for ( i = 0; i < 4; i++ ) + { + sprintf ( info, "%d %d %06lx", i, SCCP_Param.spclen[i], SCCP_Param.spc[i] ); + spLog ( info ); + } + } + else + { + spLog ( "Invalid command/parameter(s)." ); + return 0; + } + spLog ( "Command OK." ); + return 1; +} + +int sccp_filter_msg ( SCCP_ADDR * pSrcAddr, SCCP_ADDR * pDstAddr ) +{ + int i; + + for ( i = 0; i < sccpFilterIndex % 9; i++ ) + { + if( sccpFilter[i].flag & 0x01 ) + { + if( sccpFilter[i].opc != pSrcAddr->DPC ) + continue; + } + if( sccpFilter[i].flag & 0x02 ) + { + if( sccpFilter[i].dpc != pDstAddr->DPC ) + continue; + } + if( sccpFilter[i].flag & 0x04 ) + { + if( sccpFilter[i].src_ssn != pSrcAddr->SSN ) + continue; + } + if( sccpFilter[i].flag & 0x08 ) + { + if( sccpFilter[i].dst_ssn != pDstAddr->SSN ) + continue; + } + return 1; + } + return 0; +} + +void spLogDebug_info ( BYTE npage, BYTE nline, BYTE * pt, BYTE len ) +{ + DWORD oid[20] = { 1, 3, 6, 1, 4, 1, 1373, 1, 3, 2, 3, 1, 2, 4, 5, 2, 2 }; + + oid[14] = 5 + npage; + oid[15] = 2 + nline; + debug_set_response ( 17, oid, pt, len ); +} + +/*-----------------------------------------------*/ + +/*-------------------CSTA------------------------*/ + +/*-----------------------------------------------*/ +void spLogDebug_csta ( BYTE npage, int instance ) +{ + char title[256]; + SCCP_CSTA *pcsta = &SccpCsta[SccpCstaInd % 96]; + + sprintf ( title, "\tSCCP-%s\tPage %02d\t\tMIB-CSTA(ID:1 Instance:%d)\r\n" + " [----1----] [----2----] [----3----] [----4----] [----5----]\r\n" + "Error(1)\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "availability(2)\r\n" "\r\n" "\r\n" "Utilization(3)\r\n" "\r\n" "\r\n" "Quality(4)\r\n" "\r\n" "\r\n" "\r\n", sccp_ver, npage, instance ); + + title_id[14] = 5 + npage; + debug_set_response ( 16, title_id, (BYTE *)title, strlen ( title ) ); + + spLogDebug_info ( npage, 0, ( BYTE * ) pcsta->error, 20 ); + spLogDebug_info ( npage, 1, ( BYTE * ) pcsta->error + 20, 20 ); + spLogDebug_info ( npage, 2, ( BYTE * ) pcsta->error + 40, 20 ); + spLogDebug_info ( npage, 3, ( BYTE * ) pcsta->error + 60, 20 ); + spLogDebug_info ( npage, 4, ( BYTE * ) pcsta->error + 80, 4 ); + spLogDebug_info ( npage, 5, ( BYTE * ) pcsta->avail, 20 ); + spLogDebug_info ( npage, 6, ( BYTE * ) pcsta->avail + 20, 20 ); + spLogDebug_info ( npage, 7, ( BYTE * ) pcsta->avail + 40, 8 ); + spLogDebug_info ( npage, 8, ( BYTE * ) pcsta->utilization, 20 ); + spLogDebug_info ( npage, 9, ( BYTE * ) pcsta->utilization + 20, 20 ); + spLogDebug_info ( npage, 10, ( BYTE * ) pcsta->utilization + 40, 16 ); + spLogDebug_info ( npage, 11, ( BYTE * ) pcsta->quality, 20 ); + spLogDebug_info ( npage, 12, ( BYTE * ) pcsta->quality + 20, 20 ); + spLogDebug_info ( npage, 13, ( BYTE * ) pcsta->quality + 40, 20 ); + spLogDebug_info ( npage, 14, ( BYTE * ) pcsta->quality + 60, 20 ); +} + +/*-----------------------------------------------*/ + +/*-------------------Local subsystem-------------*/ + +/*-----------------------------------------------*/ +void spLogDebug_local ( BYTE npage, BYTE nline ) +{ + short loop, ssnindex = 0; + char str[256], digits[24]; + char title[1024], *pCh = NULL; + + nline = nline % 256; + if( nline < 2 ) + nline = 2; + + spLog ( "Refresh Local Node List..." ); + sprintf ( title, "\tSCCP-%s\tPage %02d\tMIB-Status Of Local Subsystem\r\n\ +[ SSN ] S1 S2 N Lc NI RG [ IP1 ] [ IP2 ] F\r\n", sccp_ver, npage ); + + for ( loop = nline; ssnindex < 22 && loop < 256; loop++ ) + { + if( LocalSSN[loop].status[0] == 0 && LocalSSN[loop].status[1] == 0 ) + continue; + + Bcd2Str ( digits, LocalSSN[loop].msisdn, LocalSSN[loop].msisdn_len % ( MAX_DIGITS + 1 ) ); + if( ( pCh = strchr ( digits, 'F' ) ) != NULL ) + *pCh = 0; + if( strlen ( digits ) == 0 ) + strcpy ( digits, " " ); + + sprintf ( str, "%02X-%-18s\n\r", loop, digits ); + strcat ( title, str ); + + spLogDebug_info ( npage, ssnindex++, LocalSSN[loop].status, 14 ); + } + + while ( ssnindex < 22 ) + spLogDebug_info ( npage, ssnindex++, LocalSSN[0].status, 0 ); + + title_id[14] = 5 + npage; + debug_set_response ( 16, title_id, (BYTE *)title, strlen ( title ) ); + + return; +} + +void spLogDebug_related ( BYTE npage, BYTE nline ) +{ + short loop; + char str[64]; + char title[500]; + + nline = nline % SCCP_RLSSN_NUM; + + sprintf ( title, "\tSCCP-%s\tPage %02d\tMIB-Status Of Related Subsystem(Num=%d)\r\n" " S SST ID SN [ SPC ] [Timeoute]\r\n", sccp_ver, npage, RelatedSSNNum ); + for ( loop = nline; loop < nline + 20 && loop < SCCP_RLSSN_NUM; loop++ ) + { + sprintf ( str, "Instance=%d\r\n", loop ); + strcat ( title, str ); + } + + title_id[14] = 5 + npage; + debug_set_response ( 16, title_id, (BYTE *)title, strlen ( title ) ); + + for ( loop = nline; loop < nline + 20 && loop < RelatedSSNNum; loop++ ) + spLogDebug_info ( npage, loop - nline, ( BYTE * ) & RelatedSSN[loop], 12 ); +} + +void spLogDebug_buffer ( BYTE npage ) +{ + char title[500]; + + sprintf ( title, "\tSCCP-%s\tPage %02d\t\tBuffer\r\n" + " [ R ] [ W ]\r\n" "SCLC(in-0)\r\n" "SCLC(in-1)\r\n" "SCLC(in-2)\r\n" "SCLC(out)\r\n" "SCOC\r\n" "AIF Msg\r\n" "\r\n" \ + "OMCIP\r\n" "R_S CR\r\n" "R_S CC\r\n" "R_S CREF\r\n" "R_S UDT\r\n" "R_S UDTS\r\n" "R_S XUDT\r\n" \ + "R_S DT1\r\n" "R_S DT2\r\n" "R_S IT\r\n" "R_S RLSD\r\n" "R_S RLC\r\n", sccp_ver, npage ); + + title_id[14] = 5 + npage; + debug_set_response ( 16, title_id, (BYTE *)title, strlen ( title ) ); + + // spLogDebug_info(npage,0,(BYTE *)&SCLC_InBuf[0].readsub, 4); + // spLogDebug_info(npage,1,(BYTE *)&SCLC_InBuf[1].readsub, 4); + // spLogDebug_info(npage,2,(BYTE *)&SCLC_InBuf[2].readsub, 4); + // spLogDebug_info(npage,3,(BYTE *)&SCLC_OutBuf.readsub, 4); + spLogDebug_info ( npage, 4, ( BYTE * ) ScocBuf.rcvsub, 4 ); + spLogDebug_info ( npage, 5, ( BYTE * ) & sccpmsg_st.msg_mtp_scoc, 8 ); + spLogDebug_info ( npage, 6, NULL, 0 ); + spLogDebug_info ( npage, 7, ( BYTE * ) & SCCP_Param.OMCIP, 8 ); + spLogDebug_info ( npage, 8, ( BYTE * ) & sccpmsg_rs_st.r_cr, 8 ); + spLogDebug_info ( npage, 9, ( BYTE * ) & sccpmsg_rs_st.r_cc, 8 ); + spLogDebug_info ( npage, 10, ( BYTE * ) & sccpmsg_rs_st.r_cref, 8 ); + spLogDebug_info ( npage, 11, ( BYTE * ) & sccpmsg_rs_st.r_udt, 8 ); + spLogDebug_info ( npage, 12, ( BYTE * ) & sccpmsg_rs_st.r_udts, 8 ); + spLogDebug_info ( npage, 13, ( BYTE * ) & sccpmsg_rs_st.r_xudt, 8 ); + spLogDebug_info ( npage, 14, ( BYTE * ) & sccpmsg_rs_st.r_dt1, 8 ); + spLogDebug_info ( npage, 15, ( BYTE * ) & sccpmsg_rs_st.r_dt2, 8 ); + spLogDebug_info ( npage, 16, ( BYTE * ) & sccpmsg_rs_st.r_it, 8 ); + spLogDebug_info ( npage, 17, ( BYTE * ) & sccpmsg_rs_st.r_rlsd, 8 ); + spLogDebug_info ( npage, 18, ( BYTE * ) & sccpmsg_rs_st.r_rlc, 8 ); +} + +void spLogDebug_errorCapture ( BYTE npage, BYTE nline ) +{ + char title[500]; + int i; + static BYTE subpage; + int base; + + subpage = nline % 10; + + sprintf ( title, "\tSCCP-%s\tPage %02d\tSubPage %02d\tErrCap\r\n" + " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r" + "Pointer\n\r" + "ErrCap\r\n" "01\r\n" "02\r\n" "03\r\n" "04\r\n" "05\r\n" "06\r\n" "07\r\n" "08\r\n" "09\r\n" "10\r\n" "11\r\n" "12\r\n" "13\r\n" "14\r\n" "15\r\n" "Dog\r\n", sccp_ver, npage, subpage ); + + title_id[14] = 5 + npage; + debug_set_response ( 16, title_id, (BYTE *)title, strlen ( title ) ); + + spLogDebug_info ( npage, 0, ( BYTE * ) & SCCPCapBuf.Pointer, 1 ); + base = subpage * 256; + for ( i = 1; i < 17; i++ ) + { + spLogDebug_info ( npage, i, ( BYTE * ) & SCCPCapBuf.Buffer[base + ( i - 1 ) * 16], 16 ); + } + for ( i = 17; i < 22; i++ ) + { + spLogDebug_info ( npage, i, ( BYTE * ) & SCCPCapBuf.watch_dog[( i - 17 ) * 16], 16 ); + } +} + +void spLogDebug_WatchDog ( BYTE npage ) +{ + char title[500]; + CO_DebugStatic *pDs = &pSp->tCo.tCoDebugStatic; + + sprintf ( title, "\tSCCP-%s\tPage %02d\t\tDebug watchdog\r\n\r\n" + "Get InPool\r\n" + "Put InPool\r\n" + "Read InPool\r\n" + "Write InPool\r\n" + "Get OutPool\r\n" + "Put OutPool\r\n" + "Put element atp\r\n" + "Put element suc\r\n" + "CoSubmitUl attempt\r\n" + "CoSubmitUl \r\n" + "UlPostCo attempt\r\n" + "UlPostCo \r\n" + "Co2Cr attempt\r\n" + "Co2Cr \r\n" + "Cr2Co attempt\r\n" + "Cr2Co \r\n" + "Timer Out\r\n" + "Busy element\r\n" + "Busy connection\r\n", sccp_ver, npage ); + + title_id[14] = 5 + npage; + debug_set_response ( 17, title_id, (BYTE *)title, strlen ( title ) ); + + spLogDebug_info ( npage, 0, ( BYTE * ) & pDs->dGetInPool, 4 ); + spLogDebug_info ( npage, 1, ( BYTE * ) & pDs->dPutInPool, 4 ); + spLogDebug_info ( npage, 2, ( BYTE * ) & pDs->dReadInPool, 4 ); + spLogDebug_info ( npage, 3, ( BYTE * ) & pDs->dWriteInPool, 4 ); + spLogDebug_info ( npage, 4, ( BYTE * ) & pDs->dGetOutPool, 4 ); + spLogDebug_info ( npage, 5, ( BYTE * ) & pDs->dPutOutPool, 4 ); + spLogDebug_info ( npage, 6, ( BYTE * ) & pDs->dPutEleApt, 4 ); + spLogDebug_info ( npage, 7, ( BYTE * ) & pDs->dPutEleSuc, 4 ); + spLogDebug_info ( npage, 8, ( BYTE * ) & pDs->dCoSubmitUlApt, 4 ); + spLogDebug_info ( npage, 9, ( BYTE * ) & pDs->dCoSubmitUl, 4 ); + spLogDebug_info ( npage, 10, ( BYTE * ) & pDs->dUlPostCoApt, 4 ); + spLogDebug_info ( npage, 11, ( BYTE * ) & pDs->dUlPostCo, 4 ); + spLogDebug_info ( npage, 12, ( BYTE * ) & pDs->dCo2CrApt, 4 ); + spLogDebug_info ( npage, 13, ( BYTE * ) & pDs->dCo2Cr, 4 ); + spLogDebug_info ( npage, 14, ( BYTE * ) & pDs->dCr2CoApt, 4 ); + spLogDebug_info ( npage, 15, ( BYTE * ) & pDs->dCr2Co, 4 ); + spLogDebug_info ( npage, 16, ( BYTE * ) & pDs->dTimerOut, 4 ); + spLogDebug_info ( npage, 17, ( BYTE * ) & pDs->dbusyElem, 4 ); + spLogDebug_info ( npage, 18, ( BYTE * ) & pSp->tCo.wConnIdCount, 4 ); +} + +void sccp_list_route ( int pos ) +{ + SCCP_ROUTE *pRoute; + int i; + char tempstr[1024], str1[64], str2[256], *pCh = NULL; + char cNP[8], cTT[8]; + if(pos >= SCCP_ROUTE_NUM) + return; + + spLog ( "#No NP TT StartDigits EndDigits NI SPC SSN RI AI S E N Rep" ); + for ( i = pos; i < SCCP_ROUTE_NUM; i++ ) + { + if( RouteList[i].avail == 0 ) + continue; + pRoute = &RouteList[i]; + if( pRoute->len > 0 ) + { + Bcd2Str ( str1, pRoute->StartDigits, pRoute->len % MAX_DIGITS ); + if( ( pCh = strchr ( str1, 'F' ) ) != NULL ) + *pCh = 0; + Bcd2Str ( str2, pRoute->EndDigits, pRoute->len % MAX_DIGITS ); + if( ( pCh = strchr ( str2, 'F' ) ) != NULL ) + *pCh = 0; + } + else + { + strcpy ( str1, "-" ); + strcpy ( str2, "-" ); + } + + if( pRoute->NP == 0 ) + sprintf ( cNP, "-" ); + else + sprintf ( cNP, "%d", pRoute->NP ); + + if( pRoute->TT == 0 ) + sprintf ( cTT, "-" ); + else + sprintf ( cTT, "%d", pRoute->TT ); + + sprintf ( tempstr, "%-3d %s %s %-15s %-15s %d %02X %02X %02X %d %d %d ", i, cNP, cTT, str1, str2, pRoute->NetID, pRoute->DPC[0], pRoute->DPC[1], pRoute->DPC[2], pRoute->SSN, pRoute->RI, + pRoute->AI ); + if( pRoute->convert ) + { + Bcd2Str ( str1, pRoute->ReplaceDigits, pRoute->replace_len % MAX_DIGITS ); + if( ( pCh = strchr ( str1, 'F' ) ) != NULL ) + *pCh = 0; + sprintf ( str2, "%-1d% -1d %-1d %-15s", pRoute->ReplaceStart, pRoute->ReplaceEnd, pRoute->OutNP, str1 ); + strcat ( tempstr, str2 ); + } + spLog ( tempstr ); + } + +} + +void sccp_put_capture_logs ( BYTE person, BYTE * pictures, int len ) +{ + int base; + + if( len >= 512 ) + return; + + base = SCCPCapBuf.Pointer * 16; + + SCCPCapBuf.Buffer[base + 0] = person; + SCCPCapBuf.Buffer[base + 1] = len; + base = base + 16; + SCCPCapBuf.Pointer = SCCPCapBuf.Pointer + 1; + + if( SCCPCapBuf.Pointer >= 128 ) + SCCPCapBuf.Pointer = 0; + + memcpy ( &SCCPCapBuf.Buffer[base], pictures, len ); + + SCCPCapBuf.Pointer = ( SCCPCapBuf.Pointer ) + ( ( len + 15 ) / 16 ); + + if( SCCPCapBuf.Pointer >= 128 ) + SCCPCapBuf.Pointer = 0; + +} diff --git a/plat/sccp/src/sccp_func.c b/plat/sccp/src/sccp_func.c new file mode 100644 index 0000000..59efcdc --- /dev/null +++ b/plat/sccp/src/sccp_func.c @@ -0,0 +1,113 @@ + +/******************************************************/ +/*Title: sccpfun.c */ +/*Descr: Common Function */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/*Modify: 2003-5-9 */ + +/******************************************************/ +//All the funtions base on following assuming: +//BCD: 0x123456 +//Digits: 0x214356 +//Str: "123456" +//Ull: 123456 +//Array: {0x01,0x02,0x03,0x04,0x05,0x06}; +#include "./include/sccp.h" + +int ParseLine ( char *str, char ( *row )[128], int maxrow ) +{ + char *pstr = str; + int len, index = 0, i; + BOOL black = 0; + + len = strlen ( str ); + for ( i = 0; i < len && index < maxrow; i++ ) + { + if( isspace ( str[i] ) ) + { + if( black == 0 ) + pstr = str + i + 1; + else + { + str[i] = '\0'; + if( strlen ( pstr ) > 128 ) + pstr[127] = 0; + sprintf ( row[index++], "%s", pstr ); + pstr = str + i + 1; + } + black = 0; + } + else + black = 1; + } + if( black == 1 ) + { + if( strlen ( pstr ) > 128 ) + pstr[127] = 0; + sprintf ( row[index++], "%s", pstr ); + } + return index; +} + +int GetEnt ( FILE * fp, char *key, char *str ) +{ + char *pval, *pkey, *pchr; + int i = 1, len; + + fseek ( fp, 0, SEEK_SET ); + pval = NULL; + while ( fgets ( str, 200, fp ) != NULL ) + { + if( ( pchr = strchr ( str, '#' ) ) != NULL ) + pchr[0] = '\0'; + if( ( pkey = strstr ( str, key ) ) != NULL ) + { + if( ( pval = strchr ( str, '=' ) ) == NULL || pkey >= pval ) + continue; + else + break; + } + } + if( pval == NULL ) + return -1; + pval++; + len = strlen ( pval ); + + while ( isspace ( pval[len - i] ) && i <= len ) + { + pval[len - i] = '\n'; + pval[len - i + 1] = '\0'; + i++; + } + + i = 0; + while ( isspace ( pval[i++] ) && i < len ); + sprintf ( str, "%s", pval + i - 1 ); + return 1; +} + +BOOL isco ( Intra_Msg * intramsg ) +{ + if( intramsg->msgtype == 9 || intramsg->msgtype == 10 || intramsg->msgtype == 17 || intramsg->msgtype == 18 || intramsg->msgtype == 19 || intramsg->msgtype == 20 ) + return 0; + else if( intramsg->msgtype > 0 && intramsg->msgtype <= 20 ) + return 1; + return 0; +} + +BOOL iscl ( Intra_Msg * intramsg ) +{ + if( intramsg->msgtype == 9 || intramsg->msgtype == 10 || intramsg->msgtype == 17 || intramsg->msgtype == 18 || intramsg->msgtype == 19 || intramsg->msgtype == 20 ) + return 1; + else + return 0; +} + +BOOL iscr ( Intra_Msg * intramsg ) +{ + if( intramsg->msgtype == 1 || intramsg->msgtype == 2 ) + return 1; + else + return 0; +} diff --git a/plat/sccp/src/sccp_gtt.c b/plat/sccp/src/sccp_gtt.c new file mode 100644 index 0000000..d1c418f --- /dev/null +++ b/plat/sccp/src/sccp_gtt.c @@ -0,0 +1,441 @@ +/****************************************************/ +/*Title: gtt.c */ +/*Descr: GTT Table Management */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/*Modify: 2003-4-30 */ +/****************************************************/ +#include "./include/sccp.h" + +/*===========export================*/ +int BuildRouteIndex ( ); +u_short SelectRoute ( BYTE * pDigits, BYTE DigitsLen ); +void TranslateGT ( SCCP_ADDR * addr, SCCP_ROUTE * pRoute ); + +/*===========import================*/ +extern void spLog ( char *info ); +extern void spShowErr(int checkFlag, char * str); +extern int ParseLine ( char *str, char ( *row )[128], int maxrow ); +extern int Digits2Array ( BYTE * pArray, BYTE * pDigits, int DigitsLen ); +extern int Bcd2Array ( BYTE * pArray, BYTE * pBcd, int BcdLen ); +extern int Array2Digits ( BYTE * pDigits, BYTE * pArray, int ArrayLen ); +extern void spLogDebug ( DWORD mask, const char *fmt, ... ); + +/*===========private================*/ +static int AddRoute ( BYTE * pStartDigits, BYTE * pEndDigits, BYTE DigitsLen, u_short index ); +static int AddLargerNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index ); +static int AddLessNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index ); +static SCCP_ROUTE_NODE *NewNode ( ); + +static SCCP_ROUTE_NODE RouteNode[SCCP_ROUTE_NODE_NUM]; +static SCCP_ROUTE_NODE *pHead = &RouteNode[0]; +static u_short heap_index = 1, item_index = 0; + +int BuildRouteIndex ( ) +{ + int i; + BYTE StartNum[32], EndNum[32], NumLen; + BYTE TTmod10, TTdiv10, TTdiv100; + BYTE field = 0; + + TTmod10 = TTdiv10 = TTdiv100 = 0; + spLog ( "Build GTT Index..." ); + memset ( &RouteNode[0], 0, SCCP_ROUTE_NODE_NUM * sizeof ( SCCP_ROUTE_NODE ) ); + heap_index = 1; + item_index = 0; + + for ( i = 2; i < 256; i++ ) + { + field = 0; + if( LocalSSN[i].status[0] == 0 && LocalSSN[i].status[1] == 0 ) + continue; + if( LocalSSN[i].msisdn_len < 1 ) + continue; + // if (mtp3_ansiFlag(LocalSSN[i].NetID) != 1)/* ITU */ + StartNum[field++] = NP_MSISDN; + // else + { //ANSI + StartNum[field++] = TT_0; + StartNum[field++] = TT_1; + //StartNum[field++] = TT_4; + StartNum[field++] = TT_0; + } + NumLen = Bcd2Array ( StartNum + field, LocalSSN[i].msisdn, LocalSSN[i].msisdn_len % MAX_DIGITS ) + field; + if( NumLen < 2 || NumLen > 26 ) + continue; + if( StartNum[NumLen - 1] > 9 ) + NumLen--; + + if( AddRoute ( StartNum, StartNum, NumLen, 1024 + i ) == 0 ) + spLog ( "Error: Fail to add local node, resource limit..." ); + } + + field = 0; + for ( i = 0; i < SCCP_ROUTE_NUM; i++ ) + { + if( RouteList[i].avail == 0 ) + continue; + + TTmod10 = RouteList[i].TT % 10; + TTdiv10 = ( RouteList[i].TT / 10 ) % 10; + TTdiv100 = RouteList[i].TT / 100; + + field = 0; + if( RouteList[i].NP != 0 ) + StartNum[field++] = RouteList[i].NP; + else + StartNum[field++] = NP_MSISDN; + if( RouteList[i].TT != 0 ) + { + StartNum[field++] = TTdiv100; + StartNum[field++] = TTdiv10; + StartNum[field++] = TTmod10; + } + else + { + StartNum[field++] = TT_0; + StartNum[field++] = TT_1; + //StartNum[field++] = TT_4; + StartNum[field++] = TT_0; + } + + field = 0; + if( RouteList[i].NP != 0 ) + EndNum[field++] = RouteList[i].NP; + else + EndNum[field++] = NP_MSISDN; + if( RouteList[i].TT != 0 ) + { + EndNum[field++] = TTdiv100; + EndNum[field++] = TTdiv10; + EndNum[field++] = TTmod10; + } + else + { + EndNum[field++] = TT_0; + EndNum[field++] = TT_1; + //EndNum[field++] = TT_4; + EndNum[field++] = TT_0; + } + + NumLen = Bcd2Array ( StartNum + field, RouteList[i].StartDigits, RouteList[i].len % MAX_DIGITS ) + field; + if( NumLen < 2 || NumLen > 26 ) + continue; + if( StartNum[NumLen - 1] > 9 ) + NumLen--; + Bcd2Array ( EndNum + field, RouteList[i].EndDigits, RouteList[i].len ); + + if( AddRoute ( StartNum, EndNum, NumLen, i ) == 0 ){ + spLog ( "Error: Fail to add route, resource limit..." ); + break; + } + } + return 1; +} + +u_short SelectRoute ( BYTE * pDigits, BYTE DigitsLen ) +{ + SCCP_ROUTE_NODE *pNode = pHead; + int i; + u_short result = 0xFFFF; + BYTE num; + + for ( i = 0; i < DigitsLen; i++ ) + { + num = pDigits[i]; + if( pNode->psub[num] >= &RouteNode[0] && pNode->psub[num] <= &RouteNode[SCCP_ROUTE_NODE_NUM-1] ) + { + pNode = pNode->psub[num]; + if( pNode->nItem != 0xFFFF ) + result = pNode->nItem; + } + else + { + return result; + } + } + return result; +} + +int GetACNInfo ( SCCP_ADDR * pAddr, BYTE ** pAcnInfo ) +{ + u_long spc; + u_short nRoute = 0xFFFF; + BYTE Num[MAX_DIGITS * 2], NumLen; + BYTE NetID; + BYTE field = 0; + u16 acn_index=0; + char str[128]={0}; + + if( pAddr->NP > 0 ) + Num[field++] = pAddr->NP; + else + Num[field++] = NP_MSISDN; + if( pAddr->TT > 0 ) + { + Num[field++] = pAddr->TT / 100; + Num[field++] = ( pAddr->TT / 10 ) % 10; + Num[field++] = pAddr->TT % 10; + } + else + { + Num[field++] = TT_0; + Num[field++] = TT_1; + //Num[field++] = TT_4; + Num[field++] = TT_0; + } + NumLen = pAddr->len % ( MAX_DIGITS * 2 ); + Digits2Array ( Num + field, pAddr->GTAI, ( NumLen + 1 ) / 2 ); + if( pAddr->GTI ) + { + nRoute = SelectRoute ( Num, NumLen + field ); + if( nRoute < SCCP_ROUTE_NUM ) + { + if( pAddr->NetID > 3 ) + NetID = RouteList[nRoute].NetID; + else + NetID = pAddr->NetID; + + spc = RouteList[nRoute].DPC[0] * 0x10000 + RouteList[nRoute].DPC[1] * 0x100 + RouteList[nRoute].DPC[2]; + acn_index = RouteList[nRoute]. acn_index; + } + else if( nRoute >= 1024 && nRoute < 1024 + 256 ) + { + if( pAddr->NetID > 3 ) + NetID = LocalSSN[nRoute - 1024].NetID % 4; + else + NetID = pAddr->NetID; + + acn_index = LocalSSN[nRoute - 1024].acn_index; + spc = SCCP_Param.spc[NetID]; + } + else + return 0; + } + else + { + NetID = pAddr->NetID; + spc = pAddr->DPC; + } + + if(acn_index >=SCCP_ROUTE_NUM) + return 0; + *pAcnInfo = &acn_ver_table[acn_index].LocationUpdating; + Bcd2Str ( str, &acn_ver_table[acn_index].LocationUpdating, sizeof(SCCP_ACN_VER_TABLE)-1); + spLogDebug(SCCPDB_MSG, "GetACNInfo (gtt)route num=%d, acn index=%d\r\n %s \r\n", nRoute, acn_index, str); +/* + *pAcnInfo = spc_to_acn ( NetID, spc ); + if( *pAcnInfo == NULL ) + return 0; +*/ + return 37; +} + +void TranslateGT ( SCCP_ADDR * pAddr, SCCP_ROUTE * pRoute ) +{ + BYTE swap[MAX_DIGITS * 2], temp[MAX_DIGITS * 2]; + BYTE ReplaceNum[MAX_DIGITS * 2], len; + BYTE ReplaceEnd; + + len = Bcd2Array ( ReplaceNum, pRoute->ReplaceDigits, pRoute->replace_len % MAX_DIGITS ); + + Digits2Array ( temp, pAddr->GTAI, ( ( pAddr->len + 1 ) / 2 ) % MAX_DIGITS ); + + pAddr->NP = NP_GT; + if( pRoute->ReplaceStart > 1 ) + { + memcpy ( swap, temp, pRoute->ReplaceStart - 1 ); + } + + memcpy ( swap + pRoute->ReplaceStart - 1, ReplaceNum, len ); + + ReplaceEnd = pRoute->ReplaceEnd; + if( pAddr->len < ReplaceEnd ) + ReplaceEnd = pAddr->len; + + memcpy ( swap + pRoute->ReplaceStart - 1 + len, temp + ReplaceEnd, ( pAddr->len - ReplaceEnd ) % 16 ); + + pAddr->len = pRoute->ReplaceStart - 1 + len + pAddr->len - ReplaceEnd; + if(pAddr->len>15) pAddr->len = 15; + pAddr->NP = pRoute->OutNP; + Array2Digits ( pAddr->GTAI, swap, pAddr->len ); +} + +int AddRoute ( BYTE * pStartDigits, BYTE * pEndDigits, BYTE DigitsLen, u_short index ) +{ + SCCP_ROUTE_NODE *pNode = pHead; + int i, j; + BYTE startNum, endNum; + + for ( i = 0; i < DigitsLen; i++ ) + { + startNum = pStartDigits[i] % 10; + endNum = pEndDigits[i] % 10; + if( startNum < endNum ) + { + for ( j = startNum + 1; j < endNum; j++ ) + { + if( pNode->psub[j] == NULL && ( pNode->psub[j] = NewNode ( ) ) == NULL ) + return 0; + + /* add by daniel on 2006-5-15 */ + if( pNode->psub[j]->nItem == 0xFFFF ) //if this node has empty index then mark it with the new index, else do nothing + /* add by daniel on 2006-5-15 */ + pNode->psub[j]->nItem = index; + } + if( pNode->psub[startNum] == NULL && ( pNode->psub[startNum] = NewNode ( ) ) == NULL ) + return 0; + if( pNode->psub[endNum] == NULL && ( pNode->psub[endNum] = NewNode ( ) ) == NULL ) + return 0; + if( AddLargerNode ( pNode->psub[startNum], pStartDigits + i + 1, DigitsLen - i - 1, index ) == 0 ) + return 0; + + if( AddLessNode ( pNode->psub[endNum], pEndDigits + i + 1, DigitsLen - i - 1, index ) == 0 ) + return 0; + return 1; + } + else if( startNum == endNum ) + { + if( pNode->psub[startNum] == NULL && ( pNode->psub[startNum] = NewNode ( ) ) == NULL ) + { + //send alarm here + pNode = NULL; + return 0; + } + pNode = pNode->psub[startNum]; + + if( i >= DigitsLen - 1 ) + { + pNode->nItem = index; + return 1; + } + continue; + } + else if( startNum > endNum ) + return 0; + } + return 1; +} + +int AddLargerNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index ) +{ + int i, j; + BYTE startNum; + + for ( i = 0; i < DigitsLen; i++ ) + { + startNum = pDigits[i] % 10; + for ( j = startNum + 1; j <= 9; j++ ) + { + if( pNode->psub[j] == NULL && ( pNode->psub[j] = NewNode ( ) ) == NULL ) + return 0; + /* add by daniel on 2006-5-15 */ + if( pNode->psub[j]->nItem == 0xFFFF ) //if this node has empty index then mark it with the new index, else do nothing + /* add by daniel on 2006-5-15 */ + pNode->psub[j]->nItem = index; + } + if( pNode->psub[startNum] == NULL && ( pNode->psub[startNum] = NewNode ( ) ) == NULL ) + return 0; + pNode = pNode->psub[startNum]; + } + + pNode->nItem = index; + return 1; +} + +int AddLessNode ( SCCP_ROUTE_NODE * pNode, BYTE * pDigits, BYTE DigitsLen, u_short index ) +{ + int i, j; + BYTE endNum; + + for ( i = 0; i < DigitsLen; i++ ) + { + endNum = pDigits[i] % 10; + for ( j = 0; j < endNum; j++ ) + { + if( pNode->psub[j] == NULL && ( pNode->psub[j] = NewNode ( ) ) == NULL ) + return 0; + /* add by daniel on 2006-5-15 */ + if( pNode->psub[j]->nItem == 0xFFFF ) //if this node has empty index then mark it with the new index, else do nothing + /* add by daniel on 2006-5-15 */ + pNode->psub[j]->nItem = index; + } + if( pNode->psub[endNum] == NULL && ( pNode->psub[endNum] = NewNode ( ) ) == NULL ) + return 0; + + pNode = pNode->psub[endNum]; + } + pNode->nItem = index; + return 1; +} + +SCCP_ROUTE_NODE *NewNode ( ) +{ + if( heap_index >= SCCP_ROUTE_NODE_NUM ){ + spLog ( "Fatal Error: Fail to add GT node, no resource" ); + return NULL; + } + + RouteNode[heap_index].nItem = 0xFFFF; + return &RouteNode[heap_index++]; +} + +/* +*Purpose: check whether a GT is in the SCCP GT table +*Param: np: Number Plan (0x01 MSISDN) +* tt: Translation Type(0x00 ITU) +* gt: Global title (Digits ) +* gt_len: length of gt(number of GT Digits) +*Return: 0 - the GT is not in SCCP GTT +* Others ¨C the length of the GT in SCCP GTT +*/ + +int CheckGT(BYTE np, BYTE tt, BYTE *gt, BYTE gt_len) +{ + BYTE Num[32], NumLen; + BYTE field = 0; + int nRoute; + +// assert(gt_len < 32); + if(gt_len >= 32) + { + spShowErr(1, "gt_len >= 32"); + return 0; + } +// assert(gt != NULL); + if(gt == NULL) + { + spShowErr(1, "gt == NULL"); + return 0; + } + + if( np > 0 ) + Num[field++] = np; + else + Num[field++] = NP_MSISDN; + + if( tt > 0 ) + { + Num[field++] = tt / 100; + Num[field++] = ( tt / 10 ) % 10; + Num[field++] = tt % 10; + } + else + { + Num[field++] = TT_0; + Num[field++] = TT_1; + //Num[field++] = TT_4; + Num[field++] = TT_0; + } + NumLen = gt_len % ( MAX_DIGITS * 2 ); + Digits2Array ( Num + field, gt, ( NumLen + 1 ) / 2 ); + + nRoute = SelectRoute ( Num, NumLen + field ); + if( nRoute < SCCP_ROUTE_NUM ) + { + NumLen = Bcd2Array( Num, RouteList[nRoute].EndDigits, RouteList[nRoute].len); + return NumLen; + } + else + return 0; +} diff --git a/plat/sccp/src/sccp_log.c b/plat/sccp/src/sccp_log.c new file mode 100644 index 0000000..6a3f173 --- /dev/null +++ b/plat/sccp/src/sccp_log.c @@ -0,0 +1,432 @@ +////////////////////////////////////////////////// +//Title : spLog.c +//Auhtor : Liu Wei +//Desc : sccp log implementation +//Created : 2007-05-19 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/sccp.h" +#include "./include/sccp_pub.h" +#include "./include/sccp_func.h" + +BYTE sccpDebugFull = 0; + +extern void spWatchDogStatic ( u8 uDebugStaticMask ); +extern char sccp_debug_buf[5120]; +extern int spLog_fd; +extern unsigned long spLogDebug_mask; + +void spLog ( char *info ) +{ +#ifdef DEBUG_TEST + if( strlen ( info ) < 2048 ) + { + printf ( "[SCCP]: %s\n", info ); + } +#else + if( strlen ( sccp_debug_buf ) + strlen ( info ) > 2048 ) + { + sccpDebugFull = 1; + return; + } + strncat ( sccp_debug_buf, info, 2048 ); + strcat ( sccp_debug_buf, "\r\n" ); + + if( spLog_fd != -1 ) + { + write ( spLog_fd, info, strlen ( info ) ); + write ( spLog_fd, "\r\n", 2 ); + } + + if( strlen ( sccp_debug_buf ) > 2050 ) + { + printf ( "sccp debug buffer overflow, len=%zu\n", strlen ( sccp_debug_buf ) ); + } +#endif + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spShowAddr ( SCCP_ADDR * pAddr, const char *sAddrName ) +{ + char srcAddr[128], digits[24]; + + Digits2Str ( digits, pAddr->GTAI, ( ( pAddr->len + 1 ) / 2 ) % MAX_DIGITS ); + digits[pAddr->len] = 0; + sprintf ( srcAddr, "%s: SPC=%06X SSN=%d RI=%d GTI=%d NP=%d TT=%d GT=%s", sAddrName, pAddr->DPC, pAddr->SSN, pAddr->RI, pAddr->GTI, pAddr->NP, pAddr->TT, digits ); + spLog ( srcAddr ); +} + +/////////////////////////////////////////////////////////////////////////// +// +/////////////////////////////////////////////////////////////////////////// +void spLogDebug ( DWORD mask, const char *fmt, ... ) +{ + va_list ap; + char buf[1024]; + + if( ( mask & spLogDebug_mask ) == 0 || sccpDebugFull ) + { + return; + } + + if( spLogDebug_mask & SCCPDB_TIME ) + { + struct timeval tv; + struct timezone tz; + struct tm *t; + char timestr[32]; + + gettimeofday ( &tv, &tz ); + t = localtime ( &tv.tv_sec ); + if( t == NULL ) + { + assert( 0 && "syscall : localtime fail"); + exit(0); + } + sprintf ( timestr, "(%d:%d:%d.%ld):", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec ); + spLog ( timestr ); + } + + if( ( mask & SCCPDB_ERR ) && ( strlen ( sccp_debug_buf ) + 5 < 2048 ) ) + { + strcat ( sccp_debug_buf, "\33[31m" ); + } + + va_start ( ap, fmt ); + vsnprintf ( buf, 1024, fmt, ap ); + va_end ( ap ); + strcat ( buf, "\33[37m" ); + spLog ( buf ); +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spShowErr(int checkFlag, char *str) +{ + if(checkFlag) + { + spLogDebug(SCCPDB_ERR, str); + } + +} + + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spShowBCD ( DWORD mask, BYTE * buf, int len ) +{ +// int i = 0, j = 0, linemax = 24; + char info[1024]; + + if( ( spLogDebug_mask & SCCPDB_MSG ) == 0 || ( spLogDebug_mask & mask ) == 0 || sccpDebugFull ) + { + return; + } + + if( len >= 256 ) + { + len = 256; + } + + MsgToFmtLog ( buf, len, info, 1024 ); + spLog ( info ); +} + +void spLogSeg ( SCCP_SegMsgBuf * pSegMsgbuf ) +{ + char digits[24], info[256]; + + if( ( spLogDebug_mask & 2) == 0 || sccpDebugFull )//SCCPDB_UDT + { + return; + } + spShowAddr ( &pSegMsgbuf->SegID.CGA, "spShowAddr" ); + + BcdToAscii ( digits, pSegMsgbuf->SegID.SegLR, 6 ); + digits[6] = 0; + sprintf ( info, "Seginfo: Total=%d RSE=%d DPC=%06X SLS=%d Class=%d SegLR=0x%s", pSegMsgbuf->MsgTotal, pSegMsgbuf->RSE, pSegMsgbuf->SegID.DPC, pSegMsgbuf->SegID.SLS, pSegMsgbuf->MsgClass, digits ); + spLog ( info ); + +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spShowMsg ( DWORD mask, const char *pDesc, Intra_Msg * pIntraMsg ) +{ +// int i = 0, j = 0, linemax = 24; + int len; +// char srcAddr[128], dstAddr[128]; + char digits[24], info[1024]; + u8 *pStr; + + if( ( mask & spLogDebug_mask ) == 0 && ( sccp_filter_msg ( &pIntraMsg->CGA, &pIntraMsg->CDA ) == 0 || mask >= SCCPDB_STP ) ) + { + return; + } + if( sccpDebugFull ) + { + return; + } + if( strlen ( sccp_debug_buf ) + 2 < 2048 ) + { + strcat ( sccp_debug_buf, "\r\n" ); + } + if( spLogDebug_mask & SCCPDB_TIME ) + { + struct timeval tv; + struct timezone tz; + struct tm *t; + char timestr[32]; + + gettimeofday ( &tv, &tz ); + t = localtime ( &tv.tv_sec ); + if( t == NULL ) + { + assert( 0 && "syscall : localtime fail"); + exit(0); + } + sprintf ( timestr, "(%d:%d:%d.%ld):", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec ); + spLog ( timestr ); + } + + if( mask & SCCPDB_ERR && ( strlen ( sccp_debug_buf ) + 5 < 2048 ) ) + { + strcat ( sccp_debug_buf, "\33[31m" ); + } + + spGetMsgStr ( pIntraMsg->msgtype, pStr ); + sprintf ( info, "%s %s[%d->%d], SLS=%02x, NetID=%d, msglen=%d\33[37m", pDesc, pStr, pIntraMsg->CGA.SSN, pIntraMsg->CDA.SSN, pIntraMsg->SLS, pIntraMsg->NetID, pIntraMsg->msglen ); + + spLog ( info ); + + if( ( spLogDebug_mask & SCCPDB_ADDR ) || ( mask & SCCPDB_ERR ) ) + { + spShowAddr ( &pIntraMsg->CGA, "SrcAddr" ); + spShowAddr ( &pIntraMsg->CDA, "DstAddr" ); + } + + if( mask & SCCPDB_AIF ) + { + char digits1[24], digits2[24]; + + BcdToAscii ( digits1, pIntraMsg->aSLR, 6 ); + digits1[6] = 0; + BcdToAscii ( digits2, pIntraMsg->aDLR, 6 ); + digits2[6] = 0; + sprintf ( info, "SLR = %s DLR = %s ", digits1, digits2 ); + spLog ( info ); + } + + if( mask & SCCPDB_XUDT ) + { + BcdToAscii ( digits, pIntraMsg->Segmnt.SegLR, 6 ); + digits[6] = 0; + sprintf ( info, "Seginfo: RS=%d SegLR=0x%s", pIntraMsg->Segmnt.RSBits, digits ); + spLog ( info ); + } + + if( ( spLogDebug_mask & SCCPDB_MSG ) == 0 ) + { + return; + } + + len = pIntraMsg->msglen % 256; + MsgToFmtLog ( pIntraMsg->data, len, info, 1024 ); + spLog ( info ); +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spShowPrimitive ( SP_UiPriPara * pUiPriParam, u8 uDirection ) +{ + u8 *pStr; + + spGetUlPrimitiveStr ( pUiPriParam->uUiPri, pStr ); + if( uDirection ) + { + spLogDebug ( SCCPDB_TIME, "AIF ==> SCCP : %s", pStr ); + } + else + { + spLogDebug ( SCCPDB_TIME, "SCCP ==> AIF : %s", pStr ); + } + + spShowUserData ( pUiPriParam ); +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spLogStateError ( u16 wConnId, u8 uErrCode ) +{ + CO_ConnSection *pCS; + u8 *pStateStr; + u8 *pPriStr; + u8 *pSideStr; + +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP spLogStateError unexpected connection id" ); + if(!( wConnId < CO_CS_MPORT)) + spShowErr(1, "SCCP spLogStateError unexpected connection id" ); + pCS = &pSp->tCo.tCSInst[wConnId]; + + spGetCoStateStr ( pCS->uCState, pStateStr ); + spGetUlPrimitiveStr ( pCS->uPri, pPriStr ); + spGetCoInstanceSide ( pCS->uSide, pSideStr ); + + switch ( uErrCode ) + { + case ERR_NONE: + { +#ifdef _WXC_FSM_TEST + char str[512]; + + sprintf ( str, "]coFsm[: call back state %s , side :%s \n", pStateStr, pSideStr ); + spLog ( str ); +#endif + } + break; + case ERR_FSM_UNEXPECT_SIDE: + spLogDebug ( SCCPDB_ERR, "Recieve unexpected side: %s ", pSideStr ); + spWatchDogStatic ( ERR_FSM_UNEXPECT_SIDE ); + break; + case ERR_FSM_UNEXPECT_PRI: + spLogDebug ( SCCPDB_ERR, "Recieve unexpected primitive in the state machine ," "Discard the primtive . \nstate: %s primtive :%s side :%s\n", pStateStr, pPriStr, pSideStr ); + spWatchDogStatic ( ERR_FSM_UNEXPECT_PRI ); + break; + case ERR_FSM_DISCARD: + spLogDebug ( SCCPDB_ERR, "Unexpected state machine ,Discard the state : %s side :%s", pStateStr, pSideStr ); + spWatchDogStatic ( ERR_FSM_DISCARD ); + break; + case ERR_FSM_ERROR: + spLogDebug ( SCCPDB_ERR, "Unexpected state machine ,error state : %s side :%s", pStateStr, pSideStr ); + spWatchDogStatic ( ERR_FSM_ERROR ); + break; + case ERR_FSM_FATAL: + spLogDebug ( SCCPDB_ERR, "Unexpected state machine ,fatal error : %s side :%s", pStateStr, pSideStr ); + spWatchDogStatic ( ERR_FSM_FATAL ); + case ERR_FSM_RESERVED: + spLogDebug ( SCCPDB_ERR, "Unexpected reserved state machine, unsupported now state : %s side :%s", pStateStr, pSideStr ); + spWatchDogStatic ( ERR_FSM_RESERVED ); + break; + default: + spLogDebug ( SCCPDB_ERR, "SCCP log state error , but unkonw eror code" ); + spWatchDogStatic ( ERR_FSM_UNKOWN_ERROR_CODE ); + break; + } +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spLogTimerOut ( u16 wConnId, u8 uTimerID ) +{ + u8 *pTimerStr; + + spGetTimerOutStr ( uTimerID, pTimerStr ); + spLogDebug ( SCCPDB_ERR, "SCCP Timer Out Timer ID : %s ConnID : %d ", pTimerStr, wConnId ); + spWatchDogStatic ( SP_TIMER_OUT ); +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spShowUserData ( SP_UiPriPara * pPri ) +{ + SP_UD *pUd; + SP_UiPriUnion *pPriUn; + + pPriUn = &pPri->tPriUnion; + + switch ( pPri->uUiPri ) + { + case N_CONNECT_REQ: + if( !( pPriUn->tPriNConnReq.uOptFlag & 0x08 ) ) + { + return; + } + spLogDebug ( SCCPDB_AIF, "Connect Req primitive Flag :0x%X ", pPriUn->tPriNConnReq.uOptFlag ); + pUd = &pPriUn->tPriNConnReq.tUD; + break; + case N_CONNECT_IND: + if( !( pPriUn->tPriNConnInd.uOptFlag & 0x04 ) ) + { + return; + } + spLogDebug ( SCCPDB_AIF, "Connect Ind primitive Flag :0x%X NetID : %d " + "RI : %d SSN : %d" , pPriUn->tPriNConnInd.uOptFlag + ,pPriUn->tPriNConnInd.tCDA.NetID + ,pPriUn->tPriNConnInd.tCDA.RI + ,pPriUn->tPriNConnInd.tCDA.SSN ); + pUd = &pPriUn->tPriNConnInd.tUD; + break; + case N_CONNECT_CFM: + if( !( pPriUn->tPriNConnCfm.uOptFlag & 0x04 ) ) + { + return; + } + spLogDebug ( SCCPDB_AIF, "Connect Cfm primitive Flag :0x%X ", pPriUn->tPriNConnCfm.uOptFlag ); + pUd = &pPriUn->tPriNConnCfm.tUD; + break; + case N_CONNECT_RSP: + if( !( pPriUn->tPriNConnRsp.uOptFlag & 0x04 ) ) + { + return; + } + spLogDebug ( SCCPDB_AIF, "Connect Rsp primitive Flag :0x%X ", pPriUn->tPriNConnRsp.uOptFlag ); + pUd = &pPriUn->tPriNConnRsp.tUD; + break; + case N_DISCONNECT_REQ: + if( !( pPriUn->tPriNDisconnReq.uOptFlag & 0x04 ) ) + { + return; + } + spLogDebug ( SCCPDB_AIF, "Disconnect Req primitive Flag :0x%X ", pPriUn->tPriNDisconnReq.uOptFlag ); + pUd = &pPriUn->tPriNDisconnReq.tUD; + break; + case N_DISCONNECT_IND: + if( !( pPriUn->tPriNDisconnInd.uOptFlag & 0x04 ) ) + { + return; + } + spLogDebug ( SCCPDB_AIF, "Disconnect Ind primitive Flag :0x%X ", pPriUn->tPriNDisconnInd.uOptFlag ); + pUd = &pPriUn->tPriNDisconnInd.tUD; + break; + case N_DATA_REQ: + pUd = &pPriUn->tPriNDataReq.tUD; + break; + case N_DATA_IND: + pUd = &pPriUn->tPriNDataInd.tUD; + break; + case N_DATAAK_REQ: + case N_EDATA_REQ: + case N_RESET_REQ: + case N_RESET_RSP: + case N_INFORM_REQ: + return; + default: + return; + } + if( pUd->uDataLen > 0 ) + { + spShowBCD ( SCCPDB_AIF, pUd->aUserData, ( pUd->uDataLen ) % 256 ); + } +} diff --git a/plat/sccp/src/sccp_mib.c b/plat/sccp/src/sccp_mib.c new file mode 100644 index 0000000..aea3c7e --- /dev/null +++ b/plat/sccp/src/sccp_mib.c @@ -0,0 +1,1188 @@ + +/*********************************************************/ +/*Title: sccpmib.c */ +/*Descr: SCCP Management information Base Interface */ +/*Author: Liang Hanxi */ +/*Create: 2002-4-16 */ +/*Modify: */ + +/*********************************************************/ + +#include "./include/sccp.h" +#include "../../snmp/src/include/macro.h" + +/*===========import================*/ +extern int BuildRouteIndex ( ); //gtt.c +extern int sccp_loadparam ( ); //sccpparam.c +extern void sccp_saveparam ( ); +extern int sccp_setparam ( DWORD * oid, BYTE * pdata, WORD datalen ); +extern int sccp_getparam ( DWORD * oid, BYTE * pdata, BYTE * vartype ); +extern void sccp_reset ( ); //sccp.c +extern void DWORD2BYTE ( BYTE * pdword, BYTE * pbyte, int len ); //sccpfun.c +extern void spLogDebug ( DWORD mask, const char *fmt, ... ); + +/*===========export================*/ +void sccpmib_init ( ); +void sccp_sethb ( ); + +/*===========private===============*/ +int sccp_setmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD datalen ); +int sccp_getmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, BYTE * vartype ); +void sccp_snmp_registration(void); +int set_localnode_title(void); +void sccp_trapcallback ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD len, snmp_addr * addr ); + +static BYTE sccpSaveFlag=0; + +int checkSccpSaveFlag() +{ + return sccpSaveFlag; +} + +void sccpEnableSaveFlag() +{ + sccpSaveFlag = 1; +} + +void sccpDisableSaveFlag() +{ + sccpSaveFlag = 0; +} + +void sccpmib_init ( ) +{ +// DWORD oid[20] = SCCP_OID; + +// inquire_setmsg ( SCCP_OIDLEN, oid, sccp_setmib ); +// inquire_getmsg ( SCCP_OIDLEN, oid, sccp_getmib ); + set_localnode_title(); + sccp_snmp_registration(); + inquire_trapmsg ( sccp_trapcallback ); +} + +void sccp_sethb ( ) +{ + set_status ( 2, 4 + SCCP_Param.RegNum, SCCP_Param.version ); + set_led ( 4, 9 ); +} + +/************************************************/ +//MIB Interface=================================> + +/************************************************/ +int sccp_setmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD datalen ) +{ + + sccpEnableSaveFlag(); + switch ( oid[SCCP_OIDLEN] ) + { + case 1: //CSTA, read only + return -1; + case 2: //Paramter + return sccp_setparam ( &oid[SCCP_OIDLEN + 1], pdata, datalen ); + case 3: //Status + switch ( oid[SCCP_OIDLEN + 1] ) + { + case 1: //version, read only + return -1; + case 2: //command + switch ( pdata[0] ) + { + case 0: //reset + spLogDebug ( SCCPDB_SNMP, "Reset SCCP..." ); + sccp_saveparam ( ); + sccp_reset ( ); + break; + case 1: //load + return -1; + case 2: //save + spLogDebug ( SCCPDB_SNMP, "Save Parameter..." ); + sccp_saveparam ( ); + break; + } + return 1; + case 3: //status, read only + return -1; + } + break; + } + return -1; +} + +int sccp_getmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, BYTE * vartype ) +{ + DWORD instance; + SCCP_CSTA *pcsta; + + spLogDebug ( SCCPDB_SNMP, "get sccp mib..." ); + switch ( oid[SCCP_OIDLEN] ) + { + case 1: //CSTA + instance = oid[SCCP_OIDLEN + 1]; + if( instance == SccpCstaInd || instance > 95 ) + { + *vartype = NosuchInstance; + spLogDebug ( SCCPDB_SNMP, "csta message not ready. instance=%d", instance ); + return 0; + } + pcsta = &SccpCsta[instance]; + if( pcsta->timestamp == 0 ) + { + spLogDebug ( SCCPDB_SNMP, "csta message is expired" ); + *vartype = 5; + return 0; + } + *vartype = 4; + spLogDebug ( SCCPDB_SNMP, "Respond csta message" ); + DWORD2BYTE ( ( BYTE * ) & pcsta->timestamp, pdata, sizeof ( SCCP_CSTA ) ); + return sizeof ( SCCP_CSTA ); + case 2: //Config + return sccp_getparam ( &oid[SCCP_OIDLEN + 1], pdata, vartype ); + case 3: //Status + switch ( oid[SCCP_OIDLEN + 1] ) + { + case 1: //version + spLogDebug ( SCCPDB_SNMP, "Get SCCP Version" ); + memcpy ( pdata, SCCP_Param.version, 3 ); + *vartype = 4; + return 3; + case 2: //command, write only + return -1; + case 3: //status + pdata[0] = SCCP_Param.status; + *vartype = 2; + return 1; + } + break; + } + return -1; +} + +//#define OMC_HB_OID {1,3,6,1,4,1,1373,1,4,1,1} +#define OMC_HB_OID {1,3,6,1,4,1,1373,2,4,1} +#define OMC_HB_OIDLEN 10 +int AddToIpList ( DWORD ip, BYTE ssn ); + +void sccp_OMCIP_detect ( DWORD ip ) +{ + int i; + BYTE index = 0; + + for ( i = 0; i <= 1; i++ ) + { + if( SCCP_Param.OMCIP[i] == ip ) + return; + else if( SCCP_Param.OMCIP[i] == 0 ) + index = i; + } + SCCP_Param.OMCIP[index] = ip; + AddToIpList ( ip, 4 ); +} + +extern ull SCCPSerialNumber; + +void sccp_trapcallback ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD len, snmp_addr * addr ) +{ + DWORD ObjID[20] = FLATFORM_HB_OID; + BYTE ssn; + short infolen, i, pos = 2; //component_id=0:iptrans + heartbeat_msg *phbmsg = ( heartbeat_msg * ) pdata; + BYTE *pstatus = phbmsg->info; + DWORD OMCHLObjID[20] = OMC_HB_OID; + BYTE newHeartbeat = 0; + + if( memcmp ( &oid[7], &OMCHLObjID[7], ( OMC_HB_OIDLEN - 7 ) * 4 ) == 0 ) //omc heartbeat + { //automatic add omc ip into ip list, + //if receive omc heartbeat and the omc serial number is equial to the local serial number, + //then the platform will send heartbeat if received omc heartbeat + if( ( SCCPSerialNumber == 0 ) || //support old version, do not have serial number + ( Bcd2Ull ( &pdata[39], SCCP_SERNUM_LEN ) == SCCPSerialNumber ) ) + sccp_OMCIP_detect ( addr->remote_ip ); + } + + if( memcmp ( &oid[9], &ObjID[9], ( FLATFORM_HB_OIDLEN - 9 ) * 4 ) != 0 || addr->remote_ip == SCCP_Param.ip ) + return; + + if( sizeof ( struct heartbeat_msg ) > ( INFO_LEN + 18 ) ) + newHeartbeat = 1; + + if( !newHeartbeat ) + { //old version heartbeat, length and component_id are one octet + pos = 1; + pos += pstatus[pos] + 1; //length of iptrans status + pos++; //component_id=1:mtp3 + pos += pstatus[pos] + 1; //length of mtp3 + pos++; //component_id=2:sccp + } + else + { //new version heartbeat, length and component_id are 2 octets + pos++; //length is 2 octets + pos += pstatus[pos] + 1; //length of iptrans status + pos++; //component_id=1:mtp3 + pos++; //component_id is 2 octets + + // pos++; //length is 2 octets + // pos += pstatus[pos] + 1; //length of mtp3 + pos += pstatus[pos]*256 + pstatus[pos+1] + 2; //mtp3 length is more than 255 + + pos++; //component_id=2:sccp + pos++; //component_id is 2 octets + + pos++; //sccp length 1 + } + infolen = pstatus[pos++]; + + if( infolen <= 4 || infolen > 32 ) + return; + + for ( i = pos + 4; i < pos + infolen; i++ ) + { + ssn = pstatus[i]; + // printf("beat recieve,ssn=%d\n",ssn); + if( ssn <= 1 ) + continue; + if( addr->remote_ip == LocalSSN[ssn].ip[0] ) + { + LocalSSN[ssn].status[0] = ST_Enable; + LocalSSN[ssn].timeout[0] = T_hbrecv; + } + else if( addr->remote_ip == LocalSSN[ssn].ip[1] ) + { + LocalSSN[ssn].status[1] = ST_Enable; + LocalSSN[ssn].timeout[1] = T_hbrecv; + } + } + +} + + +int sccp_get_sysparam(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen=-1; + char ver[32]={0}; + + switch(column) + { + case 1: + sprintf(ver, "%02d.%02d.%02d", SCCP_Param.version[0], SCCP_Param.version[1], SCCP_Param.version[2]); + GET_OCTETSTRING(ver, strlen(ver)); + break; + case 2: //command + GET_U8(0); + break; + default: + break; + } + return datalen; +} + +int sccp_set_sysparam(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + u8 command=0; + + switch(column) + { + case 1: //version + break; + case 2: //command + SET_U8(command); + if(command==1) + { + spLogDebug ( SCCPDB_SNMP, "Reset SCCP..." ); + sccp_reset ( ); + } + else if(command ==2) + { + + spLogDebug ( SCCPDB_SNMP, "Save Parameter..." ); + sccp_saveparam ( ); + } + break; + default: + break; + } + sccpEnableSaveFlag(); + return datalen; +} + +int sccp_getnext_localNode(u32 *instance) +{ + static u8 ssn=0; + + for(ssn=instance[0]; ssn<=254;ssn++) + { + switch(ssn) + { + case 4: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 32: + case 33: + case 34: + case 142: + case 146: + case 147: + case 153: + case 254: + instance[0]=ssn; + return 1; + default: + break; + } + } + return 0; +} + +int set_localnode_title(void) +{ + LOCAL_SSN *ptr=NULL; + + ptr = &LocalSSN[4]; + strcpy((char *)ptr->title, "OMC"); + ptr = &LocalSSN[6]; + strcpy((char *)ptr->title, "HLR"); + ptr = &LocalSSN[7]; + strcpy((char *)ptr->title, "VLR"); + ptr = &LocalSSN[8]; + strcpy((char *)ptr->title, "MSC"); + ptr = &LocalSSN[9]; + strcpy((char *)ptr->title, "EIR"); + ptr = &LocalSSN[10]; + strcpy((char *)ptr->title, "AUC"); + ptr = &LocalSSN[11]; + strcpy((char *)ptr->title, "SMSC"); + ptr = &LocalSSN[19]; + strcpy((char *)ptr->title, "SMPP-EMSE"); + ptr = &LocalSSN[20]; + strcpy((char *)ptr->title, "SMPP-SMSC"); + ptr = &LocalSSN[21]; + strcpy((char *)ptr->title, "SMPP-OMC"); + ptr = &LocalSSN[22]; + strcpy((char *)ptr->title, "SRF-0"); + ptr = &LocalSSN[23]; + strcpy((char *)ptr->title, "SRF-1"); + ptr = &LocalSSN[24]; + strcpy((char *)ptr->title, "SRF-2"); + ptr = &LocalSSN[25]; + strcpy((char *)ptr->title, "SRF-3"); + ptr = &LocalSSN[32]; + strcpy((char *)ptr->title, "NPLR"); + ptr = &LocalSSN[33]; + strcpy((char *)ptr->title, "OPPS"); + ptr = &LocalSSN[34]; + strcpy((char *)ptr->title, "MNP"); + ptr = &LocalSSN[146]; + strcpy((char *)ptr->title, "SSF"); + ptr = &LocalSSN[147]; + strcpy((char *)ptr->title, "SCF-CAP"); + ptr = &LocalSSN[153]; + strcpy((char *)ptr->title, "SCF-MAP"); + ptr = &LocalSSN[254]; + strcpy((char *)ptr->title, "AIF"); + return 1; +} + +int sccp_get_localNode(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + LOCAL_SSN *ptr=NULL; + char msisdn_str[32]={0}; + + if (instance[0] >= 256) + return -1; + ptr = &LocalSSN[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //title + GET_STRING((char *)ptr->title); + break; + case 3: // + GET_U8(ptr->NetID); + break; + case 4: // + Bcd2Str(msisdn_str, ptr->msisdn, ptr->msisdn_len); + if(msisdn_str[ptr->msisdn_len*2-1]=='F' ||msisdn_str[ptr->msisdn_len*2-1]=='f') + GET_OCTETSTRING(msisdn_str, ptr->msisdn_len*2-1); + else + GET_OCTETSTRING(msisdn_str, ptr->msisdn_len*2); + break; + case 5: + GET_IP(&ptr->ip[0]); + break; + case 6: + GET_IP(&ptr->ip[1]); + break; + case 7: + GET_INTEGER(ptr->acn_index); + break; + case 8: + GET_U8(0); + break; + default: + break; + } + return datalen; +} + +int sccp_set_localNode(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + LOCAL_SSN *ptr=NULL; + char msisdn_str[32] = {0}; + LOCAL_SSN *pLocalSSN; + LOCAL_SSN OldLocalSSN; + + if (instance[0] >= 256) + return -1; + + pLocalSSN = &LocalSSN[instance[0]]; + + /* copy the old important parameter */ + OldLocalSSN.NetID = pLocalSSN->NetID; + OldLocalSSN.ip[0] = pLocalSSN->ip[0]; + OldLocalSSN.ip[1] = pLocalSSN->ip[1]; + /* copy the old important parameter */ + + ptr = &LocalSSN[instance[0]]; + switch(column) + { + case 3: // + SET_U8(ptr->NetID); + break; + case 4: // + if(datalen >=16) + return -2; + SET_OCTETSTRING(msisdn_str, datalen); + Str2Bcd(ptr->msisdn, msisdn_str, MAX_DIGITS); + ptr->msisdn_len = (datalen+1)/2; + break; + case 5: + SET_IP(&ptr->ip[0]); + break; + case 6: + SET_IP(&ptr->ip[1]); + break; + case 7: + SET_INTEGER(ptr->acn_index); + if(ptr->acn_index >=SCCP_ROUTE_NUM) + ptr->acn_index = 0; + break; + case 8: + break; + default: + break; + } + + /* if old and new important parameter are same then return */ + if( OldLocalSSN.NetID == pLocalSSN->NetID && OldLocalSSN.ip[0] == pLocalSSN->ip[0] && OldLocalSSN.ip[1] == pLocalSSN->ip[1] ) + return datalen; + /* if old and new important parameter are same then return */ + + LocalSSN[instance[0]].local = 0; + LocalSSN[instance[0]].status[0] = LocalSSN[instance[0]].status[1] = 0; + if( LocalSSN[instance[0]].ip[0] > 0 && LocalSSN[instance[0]].ip[0] != 0xFFFFFFFF ) + { + if( LocalSSN[instance[0]].ip[0] == SCCP_Param.ip ) + { + LocalSSN[instance[0]].status[0] = 1; + LocalSSN[instance[0]].local = 1; + } + else + { + LocalSSN[instance[0]].status[0] = 3; + LocalSSN[instance[0]].timeout[0] = T_hbrecv; + } + } + if( LocalSSN[instance[0]].ip[1] > 0 && LocalSSN[instance[0]].ip[1] != 0xFFFFFFFF ) + { + if( LocalSSN[instance[0]].ip[1] == SCCP_Param.ip ) + { + LocalSSN[instance[0]].status[1] = 1; + LocalSSN[instance[0]].local = 2; + } + else + { + LocalSSN[instance[0]].status[1] = 3; + LocalSSN[instance[0]].timeout[1] = T_hbrecv; + } + } + + SCCP_Param.T_reset = 100; + + sccpEnableSaveFlag(); + return datalen; +} + + +int sccp_getnext_gtt(u32 *instance) +{ + int i; + SCCP_ROUTE *pRoute=NULL; + + pRoute = &RouteList[instance[0]]; + + for(i=instance[0];iavail==0 && (pRoute->StartDigits[0]&0xf0)==0xf0) + continue; + instance[0] = i; + return 1; + } + return 0; +} + + +int sccp_get_gtt(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + SCCP_ROUTE *ptr=NULL; + u32 dpc; + char msisdn_str[32]={0}; + + if (instance[0] >= SCCP_ROUTE_NUM) + return -1; + ptr = &RouteList[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //admin + GET_U8(ptr->avail); + break; + case 3: // + GET_U8(ptr->NP); + break; + case 4: // + GET_U8(ptr->TT); + break; + case 5: + Bcd2Str(msisdn_str, ptr->StartDigits, ptr->len); + GET_OCTETSTRING(msisdn_str, BcdLen ( ptr->StartDigits, MAX_DIGITS )); + break; + case 6: + Bcd2Str(msisdn_str, ptr->EndDigits, ptr->len); + GET_OCTETSTRING(msisdn_str, BcdLen ( ptr->EndDigits, MAX_DIGITS )); + break; + case 7: + GET_U8(ptr->NetID); + break; + case 8: + dpc = ptr->DPC[2]+ptr->DPC[1]*0x100+ptr->DPC[0]*0x10000; + GET_INTEGER(dpc); + break; + case 9: + GET_U8(ptr->SSN); + break; + case 10: + GET_U8(ptr->RI); + break; + case 11: + GET_U8(ptr->AI); + break; + case 12: + GET_U8(ptr->ReplaceStart); + break; + case 13: + GET_U8(ptr->ReplaceEnd); + break; + case 14: + GET_U8(ptr->OutNP); + break; + case 15: + Bcd2Str(msisdn_str, ptr->ReplaceDigits, ptr->replace_len); + GET_OCTETSTRING(msisdn_str, BcdLen ( ptr->ReplaceDigits, MAX_DIGITS )); + break; + case 16: + GET_INTEGER(ptr->acn_index); + break; + case 17: + GET_U8(1); + break; + default: + break; + } + return datalen; +} + +int sccp_set_gtt(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + SCCP_ROUTE *ptr=NULL; + u32 DPC=0; + u8 tmp=0; + int new_id=0; + char msisdn_str[32] = {0}; + + + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(new_id >=SCCP_ROUTE_NUM) + strcpy((char*)pdata,"MAX ROUTE is 1023."); + ptr = &RouteList[new_id]; + if(ptr->avail ==1) + { + strcpy((char*)pdata,"ROUTE is unlocked."); + return -2; + } + ptr->avail = 1; + sccpEnableSaveFlag(); + return datalen; + } + spLogDebug ( SCCPDB_SNMP, "Set GTT Table.instance=%d", instance[0] ); + if( instance[0] >= SCCP_ROUTE_NUM ) + return -1; + ptr = &RouteList[instance[0]]; + + SCCP_Param.T_reset = 100; //2s + switch(column) + { + case 2: //admin + SET_U8(ptr->avail); + break; + case 3: // + SET_U8(ptr->NP); + break; + case 4: // + SET_U8(ptr->TT); + break; + case 5: + if(datalen >=16) + return -2; + SET_OCTETSTRING(msisdn_str, datalen); + Str2Bcd(ptr->StartDigits, msisdn_str, MAX_DIGITS); + ptr->len = ( BcdLen ( ptr->StartDigits, MAX_DIGITS ) + 1 ) / 2; + break; + case 6: + if(datalen >=16) + return -2; + SET_OCTETSTRING(msisdn_str, datalen); + Str2Bcd(ptr->EndDigits, msisdn_str, MAX_DIGITS); + break; + case 7: + SET_U8(ptr->NetID); + break; + case 8: + SET_INTEGER(DPC); + ptr->DPC[2] = DPC&0xff; + ptr->DPC[1] = (DPC>>8)&0xff; + ptr->DPC[0] = (DPC>>16)&0xff; + break; + case 9: + SET_U8(ptr->SSN); + break; + case 10: + SET_U8(ptr->RI); + break; + case 11: + SET_U8(ptr->AI); + break; + case 12: + SET_U8(ptr->ReplaceStart); + break; + case 13: + SET_U8(ptr->ReplaceEnd); + break; + case 14: + SET_U8(ptr->OutNP); + break; + case 15: + if(datalen >=16) + return -2; + SET_OCTETSTRING(msisdn_str, datalen); + Str2Bcd(ptr->ReplaceDigits, msisdn_str, MAX_DIGITS); + ptr->replace_len = ( BcdLen ( ptr->ReplaceDigits, MAX_DIGITS ) + 1 ) / 2; + break; + case 16: + SET_INTEGER(ptr->acn_index); + if(ptr->acn_index >=SCCP_ROUTE_NUM) + ptr->acn_index = 0; + break; + case 17: + SET_U8(tmp); + if(tmp==6) + { + memset(ptr, 0, sizeof(SCCP_ROUTE)); + memset(ptr->StartDigits, 0xff, MAX_DIGITS*2); + } + break; + default: + break; + } + if( ptr->ReplaceStart >= 1 && ptr->ReplaceStart <= ptr->ReplaceEnd ) + ptr->convert = 1; + else + ptr->convert = 0; + sccpEnableSaveFlag(); + return datalen; +} + +int sccp_getnext_acn(u32 *instance) +{ + int i; + SCCP_ACN_VER_TABLE *pACN=NULL; + + pACN = &acn_ver_table[instance[0]]; + + for(i=instance[0];iavail==0 && pACN->LocationUpdating ==0) + continue; + instance[0] = i; + return 1; + } + return 0; +} + +int sccp_get_acn(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + SCCP_ACN_VER_TABLE *ptr=NULL; + + if (instance[0] >= SCCP_ROUTE_NUM) + return -1; + ptr = &acn_ver_table[instance[0]]; + + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //admin + GET_U8(ptr->avail); + break; + case 3: // + GET_U8(ptr->LocationUpdating); + break; + case 4: // + GET_U8(ptr->LocationCancellation); + break; + case 5: + GET_U8(ptr->RoamingNumberEnquiry); + break; + case 6: + GET_U8(ptr->LocationInfoRetrieval); + break; + case 7: + GET_U8(ptr->ResetContext); + break; + case 8: + GET_U8(ptr->HandoverControl); + break; + case 9: + GET_U8(ptr->EquipmentManagement); + break; + case 10: + GET_U8(ptr->InfoRetrieval); + break; + case 11: + GET_U8(ptr->InterVLRInfoRetrieval); + break; + case 12: + GET_U8(ptr->SubscriberDataManagement); + break; + case 13: + GET_U8(ptr->Tracing); + break; + case 14: + GET_U8(ptr->NetworkFunctionalSS); + break; + case 15: + GET_U8(ptr->NetworkUnstructuredSS); + break; + case 16: + GET_U8(ptr->ShortMessageGateway); + break; + case 17: + GET_U8(ptr->MOShortMessageRelay); + break; + case 18: + GET_U8(ptr->ShortMessageAlert); + break; + case 19: + GET_U8(ptr->ShortMessageWDM); + break; + case 20: + GET_U8(ptr->MTShortMessageRelay); + break; + case 21: + GET_U8(ptr->IMSIRetrieval); + break; + case 22: + GET_U8(ptr->MSPurging); + break; + case 23: + GET_U8(ptr->SubscriberInfoEnquiry); + break; + case 24: + GET_U8(ptr->AnyTimeInfoEnquiry); + break; + case 25: + GET_U8(ptr->CallControlTransfer); + break; + case 26: + GET_U8(ptr->SSInvocationNotification); + break; + case 27: + GET_U8(ptr->GroupCallControl); + break; + case 28: + GET_U8(ptr->GPRSLocationUpdating); + break; + case 29: + GET_U8(ptr->GPRSLocationInfoRetrieval); + break; + case 30: + GET_U8(ptr->FailureReporting); + break; + case 31: + GET_U8(ptr->GPRSNotifying); + break; + case 32: + GET_U8(ptr->Reporting); + break; + case 33: + GET_U8(ptr->CallCompletion); + break; + case 34: + GET_U8(ptr->InternalSIWFSAllocation); + break; + case 35: + GET_U8(ptr->InternalSecurityTriplets); + break; + case 36: + GET_U8(ptr->InternalSubscriberInterrogating); + break; + case 37: + GET_U8(ptr->InternalHLRSubscriberManagement); + break; + case 38: + GET_U8(ptr->InternalHLRPingAUC); + break; + case 39: + GET_U8(ptr->VLRCamelPhase); + break; + case 40: + GET_U8(1); + break; + default: + break; + } + return datalen; + +} + +struct _SCCP_ACN_VER_TABLE acn_ver_def= +{ + .avail = 0, + .LocationUpdating = 3, + .LocationCancellation = 3, + .RoamingNumberEnquiry =3, + .LocationInfoRetrieval = 3, + .ResetContext = 2, + .HandoverControl = 2, + .EquipmentManagement = 2, + .InfoRetrieval = 2, + .InterVLRInfoRetrieval = 2, + .SubscriberDataManagement = 3, + .Tracing = 3, + .NetworkFunctionalSS = 2, + .NetworkUnstructuredSS = 2, + .ShortMessageGateway = 2, + .MOShortMessageRelay = 2, + .ShortMessageAlert = 2, + .ShortMessageWDM = 2,//waiting Data Management + .MTShortMessageRelay = 2, + .IMSIRetrieval = 2, + .MSPurging = 3, + .SubscriberInfoEnquiry = 3, + .AnyTimeInfoEnquiry = 3, + .CallControlTransfer = 3, + .SSInvocationNotification = 3, + .GroupCallControl = 3, + .GPRSLocationUpdating = 3, + .GPRSLocationInfoRetrieval = 3, + .FailureReporting = 3, + .GPRSNotifying = 3, + .Reporting = 3, + .CallCompletion = 3, + .InternalSIWFSAllocation = 3, + .InternalSecurityTriplets = 2, + .InternalSubscriberInterrogating = 2, + .InternalHLRSubscriberManagement = 2, + .InternalHLRPingAUC = 2, + .VLRCamelPhase = 7 +}; + +int sccp_set_acn(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + SCCP_ACN_VER_TABLE *ptr=NULL; + u8 tmp=0; + int new_id=0; + + if(column == Create_Object_Cloumn) + { + SET_INTEGER(new_id); + if(new_id >=SCCP_ROUTE_NUM) + strcpy((char*)pdata,"MAX ACN is 1023."); + ptr = &acn_ver_table[new_id]; + if(ptr->avail ==1) + { + strcpy((char*)pdata,"ACN is unlocked."); + return -2; + } + memcpy(ptr, &acn_ver_def, sizeof(SCCP_ACN_VER_TABLE)); + ptr->avail = 1; + sccpEnableSaveFlag(); + return datalen; + } + spLogDebug ( SCCPDB_SNMP, "Set ACN Table.instance=%d", instance[0] ); + if( instance[0] >= SCCP_ROUTE_NUM ) + return -1; + ptr = &acn_ver_table[instance[0]]; + + SCCP_Param.T_reset = 100; //2s + switch(column) + { + case 2: //admin + SET_U8(ptr->avail); + break; + case 3: // + SET_U8(ptr->LocationUpdating); + break; + case 4: // + SET_U8(ptr->LocationCancellation); + break; + case 5: + SET_U8(ptr->RoamingNumberEnquiry); + break; + case 6: + SET_U8(ptr->LocationInfoRetrieval); + break; + case 7: + SET_U8(ptr->ResetContext); + break; + case 8: + SET_U8(ptr->HandoverControl); + break; + case 9: + SET_U8(ptr->EquipmentManagement); + break; + case 10: + SET_U8(ptr->InfoRetrieval); + break; + case 11: + SET_U8(ptr->InterVLRInfoRetrieval); + break; + case 12: + SET_U8(ptr->SubscriberDataManagement); + break; + case 13: + SET_U8(ptr->Tracing); + break; + case 14: + SET_U8(ptr->NetworkFunctionalSS); + break; + case 15: + SET_U8(ptr->NetworkUnstructuredSS); + break; + case 16: + SET_U8(ptr->ShortMessageGateway); + break; + case 17: + SET_U8(ptr->MOShortMessageRelay); + break; + case 18: + SET_U8(ptr->ShortMessageAlert); + break; + case 19: + SET_U8(ptr->ShortMessageWDM); + break; + case 20: + SET_U8(ptr->MTShortMessageRelay); + break; + case 21: + SET_U8(ptr->IMSIRetrieval); + break; + case 22: + SET_U8(ptr->MSPurging); + break; + case 23: + SET_U8(ptr->SubscriberInfoEnquiry); + break; + case 24: + SET_U8(ptr->AnyTimeInfoEnquiry); + break; + case 25: + SET_U8(ptr->CallControlTransfer); + break; + case 26: + SET_U8(ptr->SSInvocationNotification); + break; + case 27: + SET_U8(ptr->GroupCallControl); + break; + case 28: + SET_U8(ptr->GPRSLocationUpdating); + break; + case 29: + SET_U8(ptr->GPRSLocationInfoRetrieval); + break; + case 30: + SET_U8(ptr->FailureReporting); + break; + case 31: + SET_U8(ptr->GPRSNotifying); + break; + case 32: + SET_U8(ptr->Reporting); + break; + case 33: + SET_U8(ptr->CallCompletion); + break; + case 34: + SET_U8(ptr->InternalSIWFSAllocation); + break; + case 35: + SET_U8(ptr->InternalSecurityTriplets); + break; + case 36: + SET_U8(ptr->InternalSubscriberInterrogating); + break; + case 37: + SET_U8(ptr->InternalHLRSubscriberManagement); + break; + case 38: + SET_U8(ptr->InternalHLRPingAUC); + break; + case 39: + SET_U8(ptr->VLRCamelPhase); + break; + case 40: + SET_U8(tmp); + if(tmp==6) + { + memset(ptr, 0, sizeof(SCCP_ACN_VER_TABLE)); + } + break; + default: + break; + } + + sccpEnableSaveFlag(); + return datalen; +} + +int move_acn_from_mtp3(u8 NetID, DWORD spc) +{ + int i,index=0; + u8 *pAcnInfo=NULL; + pAcnInfo = spc_to_acn ( NetID, spc ); + if( pAcnInfo == NULL ) + return 0; + for(i = 0; i < SCCP_ROUTE_NUM; i++) + { + if(acn_ver_table[i].avail == 0) + continue; + if(memcmp(pAcnInfo, &acn_ver_table[i].LocationUpdating, 36)==0)//check acn table + { + index = i; + printf( "already has acn info in the table index=%d\r\n", index ); + return index; + } + } + + for(i = 0; i < SCCP_ROUTE_NUM; i++)// create an acn + { + if(acn_ver_table[i].avail == 1) + continue; + memcpy(&acn_ver_table[i].LocationUpdating, pAcnInfo, 36); + acn_ver_table[i].avail = 1; + index = i; + printf( "create acn info in the table index=%d\r\n", index ); + return index; + } + + return index; +} + + +//MTP3 OID Prefix: {1,3,6,1,4,1,1373,2,3,2,2} +static struct snmp_table_profile sccp_tables[] = { + /****** Parameter table ******/ + { + .name = "system", + .index.len = 13, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,1}, + .column = {0,1,2,3}, + .level = 0, + .get_instance = NULL, + .get_resp = sccp_get_sysparam, + .set_resp = sccp_set_sysparam + }, + { + .name = "local node", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,2,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, + .level = 1, + .get_instance = sccp_getnext_localNode, + .get_resp = sccp_get_localNode, + .set_resp = sccp_set_localNode + }, + { + .name = "gtt table", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,3,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0}, + .level = 1, + .get_instance = sccp_getnext_gtt, + .get_resp = sccp_get_gtt, + .set_resp = sccp_set_gtt + }, + { + .name = "acn version table", + .index.len = 14, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,4,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\ + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 0}, + .level = 1, + .get_instance = sccp_getnext_acn, + .get_resp = sccp_get_acn, + .set_resp = sccp_set_acn + } + +}; + +static struct snmp_register sccp_register = { + .name = "SCCP", + .prefix_len = 11, + .prefix_oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 2, 3}, + .num_of_table = sizeof(sccp_tables)/sizeof(struct snmp_table_profile), + .table = sccp_tables, + .default_get_resp = sccp_getmib, + .default_set_resp = sccp_setmib +}; + +void sccp_snmp_registration(void) +{ + register_snmp_table(&sccp_register); +} + diff --git a/plat/sccp/src/sccp_msg.c b/plat/sccp/src/sccp_msg.c new file mode 100644 index 0000000..d91eaa3 --- /dev/null +++ b/plat/sccp/src/sccp_msg.c @@ -0,0 +1,820 @@ + +/*****************************************/ +/*Title:sccpmsg.c */ +/*Descr:SCCP message Procedure */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/*Modify: 2003-5-9 */ + +/*****************************************/ +#include "./include/sccp.h" +/* =========== export ================ */ +int build_msg ( BYTE * buf, Intra_Msg * intramsg, BYTE NetID, BYTE ansi_flag ); +int parse_msg ( BYTE * buf, Intra_Msg * intramsg, int len, BYTE NetID, BYTE ansi_flag ); + +/* =========== private ================ */ +static int parse_oparam ( BYTE * buf, int len, Intra_Msg * intramsg, BYTE NetID, BYTE ansi_flag ); +static int encode_addr ( BYTE * buf, SCCP_ADDR * addr, BYTE NetID ); +static int decode_addr ( BYTE * buf, SCCP_ADDR * addr, BYTE NetID ); + +/* ansi */ +static int encode_addr_Ansi ( BYTE * buf, SCCP_ADDR * addr ); +static int decode_addr_Ansi ( BYTE * buf, SCCP_ADDR * addr ); + +/* ansi */ +//static int encode_int ( BYTE * buf, unsigned int val, BYTE len ); +//static unsigned int decode_int ( BYTE * buf, BYTE len ); + +extern void spLogDebug ( DWORD mask, const char *fmt, ... ); + +//////////////////////////////////////////////////////////// + +int build_msg ( BYTE * buf, Intra_Msg * intramsg, BYTE NetID, BYTE ansi_flag ) +{ + int msglen = 0, vnum = 0, vlen = 0; + + buf[msglen++] = intramsg->msgtype; + + if( intramsg->msglen > 256 ) + { + intramsg->msglen = 256; + } + + switch ( intramsg->msgtype ) + { + case CR_MSG: + sccpmsg_rs_st.s_cr++; + + vnum = 1 + 1; + memcpy ( buf + msglen, &intramsg->aSLR, 3 ); //SLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aSLR, 3 ); //SLR + buf[msglen++] = intramsg->msgclass; //protocol class + /*Mandatory variable part */ + buf[msglen++] = vnum--; //pointer of CDA + if( !ansi_flag ) + vlen += encode_addr ( buf + msglen + vnum + vlen, &( intramsg->CDA ), NetID ); + else + vlen += encode_addr_Ansi ( buf + msglen + vnum + vlen, &( intramsg->CDA ) ); + + buf[msglen++] = ( vnum-- ) + vlen; //Pointer of optional part + msglen += vlen; + /*optional part */ + /* + buf[msglen++] = P_CGA; //codes of CGA + msglen += encode_addr(buf + msglen, &(intramsg->CGA), NetID); + */ + buf[msglen++] = P_Data; + if( intramsg->msglen > 0 && (msglen+intramsg->msglen)msglen; + memcpy ( buf + msglen, intramsg->data, intramsg->msglen ); + msglen += intramsg->msglen; + } + buf[msglen++] = P_EOP; + break; + case CC_MSG: + sccpmsg_rs_st.s_cc++; + + memcpy ( buf + msglen, &intramsg->aDLR, 3 ); //DLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aDLR, 3 ); + memcpy ( buf + msglen, &intramsg->aSLR, 3 ); //SLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aSLR, 3 ); + buf[msglen++] = intramsg->msgclass; + buf[msglen++] = 1; // pointer ot end of optional + buf[msglen++] = 0; // end of optional + break; + case CREF_MSG: + sccpmsg_rs_st.s_cref++; + + memcpy ( buf + msglen, &intramsg->aDLR, 3 ); //DLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aDLR, 3 ); + buf[msglen++] = intramsg->cause; + buf[msglen++] = 1; // pointer ot end of optional + buf[msglen++] = 0; // end of optional + break; + case UDT_MSG: + sccpmsg_rs_st.s_udt++; + + vnum = 3; + buf[msglen++] = intramsg->msgclass; + /*mandatory variable part */ + buf[msglen++] = vnum--; //pointer of CDA + if( !ansi_flag ) + vlen += ( encode_addr ( buf + msglen + vnum + vlen, &( intramsg->CDA ), NetID ) % 64 ); + else + vlen += ( encode_addr_Ansi ( buf + msglen + vnum + vlen, &( intramsg->CDA ) ) % 64 ); + + buf[msglen++] = ( vnum-- ) + vlen; //Pointer of CGA + if( !ansi_flag ) + vlen += ( encode_addr ( buf + msglen + vnum + vlen, &( intramsg->CGA ), NetID ) % 64 ); + else + vlen += ( encode_addr_Ansi ( buf + msglen + vnum + vlen, &( intramsg->CGA ) ) % 64 ); + + buf[msglen++] = ( vnum-- ) + vlen; //Pointer of Data + + if((msglen+vlen+vnum+intramsg->msglen)msglen; //Length of Data + memcpy ( buf + msglen + vnum + vlen + 1, intramsg->data, intramsg->msglen ); + vlen = vlen + intramsg->msglen + 1; + + msglen += vlen; + } + break; + case UDTS_MSG: + sccpmsg_rs_st.s_udts++; + + vnum = 3; + buf[msglen++] = intramsg->cause; + /*mandatory variable part */ + buf[msglen++] = vnum--; //pointer of CDA + if( !ansi_flag ) + vlen += ( encode_addr ( buf + msglen + vnum + vlen, &( intramsg->CDA ), NetID ) % 64 ); + else + vlen += ( encode_addr_Ansi ( buf + msglen + vnum + vlen, &( intramsg->CDA ) ) % 64 ); + + buf[msglen++] = ( vnum-- ) + vlen; //Pointer of CGA + if( !ansi_flag ) + vlen += ( encode_addr ( buf + msglen + vnum + vlen, &( intramsg->CGA ), NetID ) % 64 ); + else + vlen += ( encode_addr_Ansi ( buf + msglen + vnum + vlen, &( intramsg->CGA ) ) % 64 ); + + buf[msglen++] = ( vnum-- ) + vlen; //Pointer of Data + if((msglen+vlen+vnum+intramsg->msglen)msglen; //Length of Data + memcpy ( buf + msglen + vnum + vlen + 1, intramsg->data, intramsg->msglen ); + vlen = vlen + intramsg->msglen + 1; + + msglen += vlen; + } + break; + case XUDT_MSG: + sccpmsg_rs_st.s_xudt++; + + vnum = intramsg->SegPresent ? 4 : 3; + buf[msglen++] = intramsg->msgclass; + buf[msglen++] = intramsg->Hop; + /*mandatory variable part */ + buf[msglen++] = vnum--; //pointer of CDA + vlen += ( encode_addr ( buf + msglen + vnum + vlen, &( intramsg->CDA ), NetID ) % 64 ); + + buf[msglen++] = ( vnum-- ) + vlen; //Pointer of CGA + vlen += ( encode_addr ( buf + msglen + vnum + vlen, &( intramsg->CGA ), NetID ) % 64 ); + + buf[msglen++] = ( vnum-- ) + vlen; //Pointer of Data + if((msglen+vlen+vnum+intramsg->msglen)msglen; //Length of Data + memcpy ( buf + msglen + vnum + vlen + 1, intramsg->data, intramsg->msglen ); + vlen = vlen + intramsg->msglen + 1; + } + if( intramsg->SegPresent && (msglen + vnum + vlen+6)Segmnt, 4 ); + msglen += 6; + } + msglen += vlen; + break; + case DT1_MSG: + sccpmsg_rs_st.s_dt1++; + + memcpy ( buf + msglen, &intramsg->aDLR, 3 ); //DLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aDLR, 3 ); + buf[msglen++] = intramsg->EOD; + + buf[msglen++] = 1; //Pointer of Data + buf[msglen++] = intramsg->msglen; //Length of Data + if((msglen+intramsg->msglen)data, intramsg->msglen ); + msglen += intramsg->msglen; + } + break; + case DT2_MSG: + sccpmsg_rs_st.s_dt2++; + + memcpy ( buf + msglen, &intramsg->aDLR, 3 ); //DLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aDLR, 3 ); + buf[msglen++] = 2 * intramsg->PS; + buf[msglen++] = 2 * intramsg->PR + intramsg->EOD; + + buf[msglen++] = 1; //Pointer of Data + buf[msglen++] = intramsg->msglen; //Length of Data + if((msglen+intramsg->msglen)data, intramsg->msglen ); + msglen += intramsg->msglen; + } + break; + case RLSD_MSG: + sccpmsg_rs_st.s_rlsd++; + + memcpy ( buf + msglen, &intramsg->aDLR, 3 ); //DLR + msglen += 3; + memcpy ( buf + msglen, &intramsg->aSLR, 3 ); //SLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aDLR, 3 ); + //msglen += encode_int ( buf + msglen, intramsg->aSLR, 3 ); + buf[msglen++] = intramsg->cause; + buf[msglen++] = 1; // pointer ot end of optional + buf[msglen++] = 0; // end of optional + break; + case RLC_MSG: + sccpmsg_rs_st.s_rlc++; + + memcpy ( buf + msglen, &intramsg->aDLR, 3 ); //DLR + msglen += 3; + memcpy ( buf + msglen, &intramsg->aSLR, 3 ); //SLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aDLR, 3 ); + //msglen += encode_int ( buf + msglen, intramsg->aSLR, 3 ); + break; + case IT_MSG: + sccpmsg_rs_st.s_it++; + + memcpy ( buf + msglen, &intramsg->aDLR, 3 ); //DLR + msglen += 3; + memcpy ( buf + msglen, &intramsg->aSLR, 3 ); //SLR + msglen += 3; + //msglen += encode_int ( buf + msglen, intramsg->aDLR, 3 ); + //msglen += encode_int ( buf + msglen, intramsg->aSLR, 3 ); + buf[msglen++] = 2; //class = 2 + buf[msglen++] = 0; //Sequencing/segmenting octet 0 + buf[msglen++] = 0; //Sequencing/segmenting octet 1 + buf[msglen++] = 0; //Credit + break; + } + //buf[0] = msglen-1; + return msglen; +} + +int parse_msg ( BYTE * buf, Intra_Msg * intramsg, int len, BYTE NetID, BYTE ansi_flag ) +{ + int pos = 0; + BYTE ptv, vlen; + + intramsg->msgtype = buf[pos++]; + switch ( intramsg->msgtype ) + { + case CR_MSG: + if( len < 4 ) + SCCPCapBuf.watch_dog[2]++; //invalid CR message + + sccpmsg_rs_st.r_cr++; + memcpy ( &intramsg->aSLR, buf + pos, 3 ); //SLR + pos += 3; + //intramsg->aSLR = decode_int ( buf + pos, 3 ); + intramsg->msgclass = buf[pos++]; + + ptv = pos + buf[pos]; + pos++; + if( !ansi_flag ) + vlen = decode_addr ( buf + ptv, &( intramsg->CDA ), NetID ); + else + vlen = decode_addr_Ansi ( buf + ptv, &( intramsg->CDA ) ); + + if( vlen + ptv >= len ) + return 1; + ptv = pos + buf[pos]; + pos++; + parse_oparam ( buf + ptv, len - ptv, intramsg, NetID, ansi_flag ); + break; + case CC_MSG: + if( len < 8 ) + SCCPCapBuf.watch_dog[3]++; //invalid CC message + + sccpmsg_rs_st.r_cc++; + memcpy ( &intramsg->aDLR, buf + pos, 3 ); //DLR + pos += 3; + memcpy ( &intramsg->aSLR, buf + pos, 3 ); //SLR + pos += 3; + //intramsg->aDLR = decode_int ( buf + pos, 3 ); + //pos += 3; + //intramsg->aSLR = decode_int ( buf + pos, 3 ); + //pos += 3; + intramsg->msgclass = buf[pos++]; + + ptv = pos + buf[pos]; +/* if (buf[ptv++] == 0x0F) + { + intramsg->msglen = buf[ptv++]; + memcpy ( intramsg->data, buf + ptv, intramsg->msglen ); + } +*/ + parse_oparam ( buf + ptv, len - ptv, intramsg, NetID, ansi_flag ); + break; + case CREF_MSG: + if( len < 5 ) + SCCPCapBuf.watch_dog[4]++; //invalid CREF message + sccpmsg_rs_st.r_cref++; + memcpy ( &intramsg->aDLR, buf + pos, 3 ); //DLR + pos += 3; + //intramsg->aDLR = decode_int ( buf + pos, 3 ); + //pos += 3; + intramsg->cause = buf[pos++]; + ptv = pos + buf[pos]; + parse_oparam ( buf + ptv, len - ptv, intramsg, NetID, ansi_flag ); + break; + case UDT_MSG: + if( len < 2 ) + SCCPCapBuf.watch_dog[5]++; //invalid UDT message + + sccpmsg_rs_st.r_udt++; + intramsg->msgclass = buf[pos++]; + ptv = pos + buf[pos]; + pos++; + if( !ansi_flag ) + vlen = decode_addr ( buf + ptv, &( intramsg->CDA ), NetID ); + else + vlen = decode_addr_Ansi ( buf + ptv, &( intramsg->CDA ) ); + ptv = pos + buf[pos]; + pos++; + if( !ansi_flag ) + vlen = decode_addr ( buf + ptv, &( intramsg->CGA ), NetID ); + else + vlen = decode_addr_Ansi ( buf + ptv, &( intramsg->CGA ) ); + + ptv = pos + buf[pos]; + pos++; + intramsg->msglen = buf[ptv]; + memcpy ( intramsg->data, buf + ptv + 1, intramsg->msglen ); + break; + case UDTS_MSG: + if( len < 2 ) + SCCPCapBuf.watch_dog[6]++; //invalid UDTs message + + sccpmsg_rs_st.r_udts++; + + intramsg->cause = buf[pos++]; + ptv = pos + buf[pos]; + pos++; + if( !ansi_flag ) + vlen = decode_addr ( buf + ptv, &( intramsg->CDA ), NetID ); + else + vlen = decode_addr_Ansi ( buf + ptv, &( intramsg->CDA ) ); + ptv = pos + buf[pos]; + pos++; + if( !ansi_flag ) + vlen = decode_addr ( buf + ptv, &( intramsg->CGA ), NetID ); + else + vlen = decode_addr_Ansi ( buf + ptv, &( intramsg->CGA ) ); + + ptv = pos + buf[pos]; + pos++; + intramsg->msglen = buf[ptv]; + memcpy ( intramsg->data, buf + ptv + 1, intramsg->msglen ); + break; + case XUDT_MSG: + //if (len < 2) + // SCCPCapBuf.watch_dog[5]++;//invalid XUDT message + sccpmsg_rs_st.r_xudt++; + + intramsg->msgclass = buf[pos++]; + intramsg->Hop = buf[pos++]; + ptv = pos + buf[pos]; + pos++; + vlen = decode_addr ( buf + ptv, &( intramsg->CDA ), NetID ); + ptv = pos + buf[pos]; + pos++; + vlen = decode_addr ( buf + ptv, &( intramsg->CGA ), NetID ); + + if( vlen + ptv >= len ) + return 1; + ptv = pos + buf[pos]; + pos = ptv; + intramsg->msglen = buf[pos++]; + memcpy ( intramsg->data, buf + pos, intramsg->msglen ); + pos += intramsg->msglen; + parse_oparam ( buf + pos, len - pos, intramsg, NetID, ansi_flag ); + break; + case DT1_MSG: + if( len < 5 ) + SCCPCapBuf.watch_dog[7]++; //invalid DT1 message + sccpmsg_rs_st.r_dt1++; + + memcpy ( &intramsg->aDLR, buf + pos, 3 ); //DLR + pos += 3; + //intramsg->aDLR = decode_int ( buf + pos, 3 ); + //pos += 3; + intramsg->EOD = buf[pos++]; + + ptv = pos + buf[pos]; + pos++; + intramsg->msglen = buf[ptv]; + memcpy ( intramsg->data, buf + ptv + 1, intramsg->msglen ); + break; + case DT2_MSG: + if( len < 7 ) + SCCPCapBuf.watch_dog[8]++; //invalid DT2 message + sccpmsg_rs_st.r_dt2++; + memcpy ( &intramsg->aDLR, buf + pos, 3 ); //DLR + pos += 3; + //intramsg->aDLR = decode_int ( buf + pos, 3 ); + //pos += 3; + intramsg->PS = buf[pos++] / 2; + intramsg->PR = buf[pos] / 2; + intramsg->EOD = buf[pos++] % 2; + + ptv = pos + buf[pos]; + pos++; + intramsg->msglen = buf[ptv]; + memcpy ( intramsg->data, buf + ptv + 1, intramsg->msglen ); + break; + case RLSD_MSG: + if( len < 8 ) + SCCPCapBuf.watch_dog[9]++; //invalid RLSD message + sccpmsg_rs_st.r_rlsd++; + + memcpy ( &intramsg->aDLR, buf + pos, 3 ); //DLR + pos += 3; + memcpy ( &intramsg->aSLR, buf + pos, 3 ); //SLR + pos += 3; + //intramsg->aDLR = decode_int ( buf + pos, 3 ); + //pos += 3; + //intramsg->aSLR = decode_int ( buf + pos, 3 ); + //pos += 3; + intramsg->cause = buf[pos++]; + break; + case RLC_MSG: + if( len < 7 ) + SCCPCapBuf.watch_dog[10]++; //invalid RLC message + sccpmsg_rs_st.r_rlc++; + + memcpy ( &intramsg->aDLR, buf + pos, 3 ); //DLR + pos += 3; + memcpy ( &intramsg->aSLR, buf + pos, 3 ); //SLR + pos += 3; + //intramsg->aDLR = decode_int ( buf + pos, 3 ); + //pos += 3; + //intramsg->aSLR = decode_int ( buf + pos, 3 ); + //pos += 3; + break; + case IT_MSG: + if( len < 8 ) + SCCPCapBuf.watch_dog[11]++; //invalid IT message + + sccpmsg_rs_st.r_it++; + + memcpy ( &intramsg->aDLR, buf + pos, 3 ); //DLR + pos += 3; + memcpy ( &intramsg->aSLR, buf + pos, 3 ); //SLR + pos += 3; + //intramsg->aDLR = decode_int ( buf + pos, 3 ); + //pos += 3; + //intramsg->aSLR = decode_int ( buf + pos, 3 ); + //pos += 3; + intramsg->msgclass = buf[pos++]; + break; + } + return 1; +} + +int parse_oparam ( BYTE * buf, int len, Intra_Msg * intramsg, BYTE NetID, BYTE ansi_flag ) +{ + int pos = 0; + BYTE nparam; + + while ( pos < len ) + { + nparam = buf[pos++]; + switch ( nparam ) + { + case P_EOP: + return 1; + case P_CDA: + /* if (!ansi_flag) + pos += decode_addr(buf + pos, &(intramsg->CDA), NetID); + else + pos += decode_addr_Ansi(buf + pos, &(intramsg->CDA)); */ + break; + case P_CGA: + if( !ansi_flag ) + pos += decode_addr ( buf + pos, &( intramsg->CGA ), NetID ); + else + pos += decode_addr_Ansi ( buf + pos, &( intramsg->CGA ) ); + break; + case P_Data: + intramsg->msglen = buf[pos++]; + memcpy ( intramsg->data, buf + pos, intramsg->msglen ); + pos += intramsg->msglen; + break; + case P_SEG: + if( buf[pos] != 4 ) + { + spLogDebug ( SCCPDB_USER, "SCCP XUDT Msg Segmentaion Parameters length error!" ); + } + pos++; + memcpy ( &intramsg->Segmnt, &buf[pos], 4 ); + intramsg->SegPresent = 1; + pos += 4; + break; + case P_DLR: + case P_SLR: + case P_PLC: + case P_EOD: + case P_PR: + case P_SEQ: + case P_Credit: + case P_RLC: + case P_RTC: + case P_RSC: + case P_ERC: + case P_RFC: + case P_HC: + case P_Importance: + case P_Ldata: + break; + } + } + return 1; +} +/* +int encode_int ( BYTE * buf, unsigned int val, BYTE len ) +{ + BYTE temp[4]; + + temp[0] = ( BYTE ) ( ( val & 0xFF000000 ) >> 24 ); + temp[1] = ( BYTE ) ( ( val & 0xFF0000 ) >> 16 ); + temp[2] = ( BYTE ) ( ( val & 0xFF00 ) >> 8 ); + temp[3] = ( BYTE ) ( val & 0xFF ); + memcpy ( buf, temp + 4 - len, len ); + + return len; +} + +unsigned int decode_int ( BYTE * buf, BYTE len ) +{ + unsigned int rtn = 0, i; + + for ( i = 0; i < len; i++ ) + rtn = rtn << 8 | buf[i]; + return rtn; +} +*/ +int encode_addr ( BYTE * buf, SCCP_ADDR * addr, BYTE NetID ) +{ + BYTE len = 0, cp_len; + BYTE RI_MASK = 0x40, SSN_MASK = 0x02, DPC_MASK = 0x01, GT_MASK = 0x04; + + /*GTI*/ len = 2; + //if(addr->RI == RI_SSN && addr->SSN > 0) + // addr->GTI = 0; + + buf[1] = ( RI_MASK * addr->RI ) | ( SSN_MASK ) | ( DPC_MASK & ( addr->DPC > 0 ? 1 : 0 ) & ( addr->AI & 1 ) ) | ( GT_MASK * addr->GTI ); + + if( ( addr->DPC > 0 ) & ( addr->AI & 1 ) ) + { + memcpy ( buf + len, ( BYTE * ) & addr->DPC, SCCP_Param.spclen[NetID] ); + len += SCCP_Param.spclen[NetID]; + } + buf[len++] = addr->SSN; + switch ( addr->GTI ) + { + case 0: //no global title included + break; + case 1: //global title includes nature of address indicator only + buf[len++] = addr->NAI; + memcpy ( buf + len, addr->GTAI, ( addr->len + 1 ) / 2 ); + len += ( addr->len + 1 ) / 2; + + break; + case 2: //global title includes translation type only + buf[len++] = addr->TT; + memcpy ( buf + len, addr->GTAI, ( addr->len + 1 ) / 2 ); + len += ( addr->len + 1 ) / 2; + break; + case 3: //global title includes translation type, NP, EC + buf[len++] = addr->TT; + cp_len = ( addr->len + 1 ) / 2; + if( addr->len & 1 ) //odd number of address signals + { + addr->ES = 1; + addr->GTAI[cp_len - 1] = addr->GTAI[cp_len - 1] & 0x0F; + } + else + addr->ES = 2; + + buf[len++] = addr->NP * 16 + addr->ES; + addr->GTAI[len] = 0; + memcpy ( buf + len, addr->GTAI, cp_len ); + len += cp_len; + break; + case 4: //global title includes translation type, NP, EC, NAI + buf[len++] = addr->TT; + + addr->len %= 18; + cp_len = ( addr->len + 1 ) / 2; + if( addr->len & 1 ) //odd number of address signals + { + addr->ES = 1; + addr->GTAI[cp_len - 1] = addr->GTAI[cp_len - 1] & 0x0F; + } + else + addr->ES = 2; + + buf[len++] = addr->NP * 16 + addr->ES; + buf[len++] = addr->NAI; + memcpy ( buf + len, addr->GTAI, cp_len ); + len += cp_len; + break; + } + buf[0] = len - 1; + return len; +} + +int decode_addr ( BYTE * buf, SCCP_ADDR * addr, BYTE NetID ) +{ + BYTE len, pos, nbyte; + BYTE RI_MASK = 0x40, SSN_MASK = 0x02, DPC_MASK = 0x01, GT_MASK = 0x3C; + BYTE DPCI; + + len = buf[0] + 1; + addr->RI = ( buf[1] & RI_MASK ) >> 6; + addr->GTI = ( buf[1] & GT_MASK ) >> 2; + DPCI = ( buf[1] & DPC_MASK ); + addr->SSN = ( buf[1] & SSN_MASK ) >> 1; + pos = 2; + if( DPCI ) + { + memcpy ( ( BYTE * ) & addr->DPC, buf + pos, SCCP_Param.spclen[NetID] ); + pos += SCCP_Param.spclen[NetID]; + } + if( addr->SSN ) + addr->SSN = buf[pos++]; + + switch ( addr->GTI ) + { + case 0: //no global title included + break; + case 1: //global title includes nature of address indicator only + addr->NAI = buf[pos++] & 0x7F; + nbyte = len - pos; + addr->len = 2 * nbyte; + if( ( buf[pos - 1] & 0x80 ) == 0x80 ) //odd number of address signals + addr->len--; + + memcpy ( addr->GTAI, buf + pos, nbyte % ( MAX_DIGITS + 1 ) ); + break; + case 2: //global title includes translation type only + addr->TT = buf[pos++]; + nbyte = len - pos; + addr->len = 2 * nbyte; + memcpy ( addr->GTAI, buf + pos, nbyte % ( MAX_DIGITS + 1 ) ); + break; + case 3: //global title includes translation type, NP, EC + addr->TT = buf[pos++]; + addr->NP = buf[pos] / 16; + addr->ES = buf[pos++] % 16; + nbyte = len - pos; + addr->len = 2 * nbyte; + if( addr->ES == 1 ) + addr->len--; + memcpy ( addr->GTAI, buf + pos, nbyte % ( MAX_DIGITS + 1 ) ); + break; + case 4: //global title includes translation type, NP, EC, NAI + addr->TT = buf[pos++]; + addr->NP = buf[pos] / 16; + addr->ES = buf[pos++] % 16; + addr->NAI = buf[pos++] & 0x7F; + nbyte = len - pos; + addr->len = 2 * nbyte; + if( addr->ES == 1 ) + addr->len--; + memcpy ( addr->GTAI, buf + pos, nbyte % ( MAX_DIGITS + 1 ) ); + break; + } + return len; +} + +//----->ansi + +int encode_addr_Ansi ( BYTE * buf, SCCP_ADDR * addr ) +{ + BYTE len = 0, cp_len; + BYTE NAT_MASK = 0x80, RI_MASK = 0x40, DPC_MASK = 0x02, SSN_MASK = 0x01, GT_MASK = 0x04; + BYTE spclen = 3; //ansi is always 24 bit,3 bytes + + /*GTI*/ len = 2; + //if(addr->RI == RI_SSN && addr->SSN > 0) + // addr->GTI = 0; + + switch ( addr->GTI ) + { + case 4: + addr->GTI = 2; + break; + default: + break; + } + + buf[1] = NAT_MASK | ( RI_MASK * addr->RI ) | ( SSN_MASK ) | ( DPC_MASK & ( ( addr->DPC > 0 ? 1 : 0 ) * 2 ) & ( ( addr->AI & 1 ) * 2 ) ) | ( GT_MASK * addr->GTI ); + + buf[len++] = addr->SSN; + + if( addr->DPC > 0 && ( addr->AI & 1 ) ) + { + /* memcpy(buf + len, (BYTE *)&addr->DPC, SCCP_Param.spclen[NetID]); + len += SCCP_Param.spclen[NetID]; */ + memcpy ( buf + len, ( BYTE * ) & addr->DPC, spclen ); + len += spclen; + } + + switch ( addr->GTI ) + { + case 0: //no global title included + break; + case 1: //global title includes translation type, NP, EC + buf[len++] = addr->TT; + cp_len = ( addr->len + 1 ) / 2; + if( addr->len & 1 ) //odd number of address signals + { + addr->ES = 1; + addr->GTAI[cp_len - 1] = addr->GTAI[cp_len - 1] & 0x0F; + } + else + addr->ES = 2; + + buf[len++] = addr->NP * 16 + addr->ES; + addr->GTAI[len] = 0; + memcpy ( buf + len, addr->GTAI, cp_len ); + len += cp_len; + break; + case 2: //global title includes translation type only + buf[len++] = addr->TT; + /* added by Pierre, 2006-09-30 for the filler */ + cp_len = ( addr->len + 1 ) / 2; + if( addr->len & 1 ) //odd number of address signals + { + addr->GTAI[cp_len - 1] = addr->GTAI[cp_len - 1] & 0x0F; + } + /* above lines added by Pierre */ + + memcpy ( buf + len, addr->GTAI, ( addr->len + 1 ) / 2 ); + len += ( addr->len + 1 ) / 2; + break; + default: + break; + } + buf[0] = len - 1; + return len; +} + +int decode_addr_Ansi ( BYTE * buf, SCCP_ADDR * addr ) +{ + BYTE len, pos, nbyte; + BYTE RI_MASK = 0x40, DPC_MASK = 0x02, SSN_MASK = 0x01, GT_MASK = 0x3C; + BYTE DPCI; + BYTE spclen = 3; //ansi is always 24 bit,3 bytes + + len = buf[0] + 1; + addr->RI = ( buf[1] & RI_MASK ) >> 6; + addr->GTI = ( buf[1] & GT_MASK ) >> 2; + DPCI = ( buf[1] & DPC_MASK ) >> 1; + addr->SSN = ( buf[1] & SSN_MASK ); + pos = 2; + + if( addr->SSN ) + addr->SSN = buf[pos++]; + if( DPCI ) + { + /* memcpy((BYTE *)&addr->DPC, buf + pos, SCCP_Param.spclen[NetID]); + pos += SCCP_Param.spclen[NetID]; */ + memcpy ( ( BYTE * ) & addr->DPC, buf + pos, spclen ); + pos += spclen; + } + + switch ( addr->GTI ) + { + case 0: //no global title included + break; + case 1: //global title includes translation type, NP, EC + addr->TT = buf[pos++]; + addr->NP = buf[pos] / 16; + addr->ES = buf[pos++] % 16; + nbyte = len - pos; + addr->len = 2 * nbyte; + if( addr->ES == 1 ) + addr->len--; + memcpy ( addr->GTAI, buf + pos, nbyte % ( MAX_DIGITS + 1 ) ); + break; + case 2: //global title includes translation type only + addr->TT = buf[pos++]; + nbyte = len - pos; + addr->len = 2 * nbyte; + memcpy ( addr->GTAI, buf + pos, nbyte % ( MAX_DIGITS + 1 ) ); + break; + default: + break; + } + return len; +} diff --git a/plat/sccp/src/sccp_param.c b/plat/sccp/src/sccp_param.c new file mode 100644 index 0000000..619ab6a --- /dev/null +++ b/plat/sccp/src/sccp_param.c @@ -0,0 +1,775 @@ + +/**************************************************/ +/*Title: sccpparam.c */ +/*Descr: sccp parameter management */ +/*Author: Liang Hanxi */ +/*Create: 2002-5-7 */ + +/**************************************************/ +#include "./include/sccp.h" + +/*===========export================*/ +int sccp_loadparam ( ); +void sccp_saveparam ( ); +int sccp_setparam ( DWORD * oid, BYTE * pdata, WORD datalen ); +int sccp_getparam ( DWORD * oid, BYTE * pdata, BYTE * vartype ); + +/*===========import================*/ +extern int Str2Digits ( BYTE * pDigits, char *pStr, int DigitsLen ); +extern int Str2Bcd ( BYTE * pBcd, char *pStr, int maxLen ); +extern int Str2Array ( BYTE * pArray, char *str, int ArrayLen ); +extern int Bcd2Digits ( BYTE * pDigits, BYTE * pBcd, int maxLen ); +extern int BcdLen ( BYTE * pBcd, int maxLen ); +extern int ParseLine ( char *str, char ( *row )[128], int maxrow ); +extern int move_acn_from_mtp3(u8 NetID, DWORD spc); +extern void sccpEnableSaveFlag(); + +extern void spLogDebug ( DWORD mask, const char *fmt, ... ); + +/*===========private================*/ +static int SccpGetLocalIP ( ); +int ParseLocalNode ( char *str ); +static void ParseRouteInfo ( char *str ); +static void ParseRLSSN ( char *str ); +static void ParseGTTAttributeOMC ( char *str ); +static void ParseACNVerion(char *str); + +int GetMSISDNOfSSN ( BYTE ssn, BYTE * msisdn ) +{ + int len; + +// len = Bcd2Digits ( msisdn, LocalSSN[ssn].msisdn, MAX_DIGITS ) % ( MAX_DIGITS + 1 ); +// memset ( msisdn + len, 0xFF, MAX_DIGITS - len ); + len = Bcd2Digits ( msisdn, LocalSSN[ssn].msisdn, ISDN_LEN - 1 ) % ( ISDN_LEN );// ISDN_LEN==9 + memset ( msisdn + len, 0xFF, ISDN_LEN - 1 - len ); + memset ( msisdn + len, 0xFF, 8 - len ); + return len; +} + +int sccp_GetSSNType ( BYTE ssn ) +{ + return mtp3_ansiFlag ( LocalSSN[ssn].NetID ); +} + +int sccp_loadparam ( ) +{ + FILE *fp; + int i, j; + char str[200] = "\0", *pChr, *pKey; + BYTE state = 0; + + SccpGetLocalIP ( ); + for ( i = 0; i < 256; i++ ) + { + LocalSSN[i].status[0] = LocalSSN[i].status[1] = 0; + LocalSSN[i].ip[0] = LocalSSN[i].ip[1] = 0xFFFFFFFF; + LocalSSN[i].local = 0; + LocalSSN[i].NetID = 0; + memset ( LocalSSN[i].msisdn, 0xFF, MAX_DIGITS ); + } + for ( i = 0; i < SCCP_ROUTE_NUM; i++) + { + memset ( &RouteList[i], 0, sizeof ( SCCP_ROUTE ) ); + memset ( RouteList[i].StartDigits, 0xFF, MAX_DIGITS * 2 ); + memset ( RouteList[i].ReplaceDigits, 0xFF, MAX_DIGITS ); + memset ( RouteList[i].acn_ver, 0x02, 48 ); + } + + RelatedSSNNum = 0; + + fp = fopen ( SCCP_CONF_FILE, "r" ); + if( fp == NULL ) + { + printf ( "GTT Initializing: Config File %s not found\n", SCCP_CONF_FILE ); + return -1; + } + + while ( fgets ( str, 200, fp ) != NULL ) + { + if( ( pChr = strchr ( str, '#' ) ) != NULL ) + pChr[0] = '\0'; + + if( ( pKey = strstr ( str, "[" ) ) != NULL ) + { + if( ( pKey = strstr ( str, "[Local Node]" ) ) != NULL ) + state = 1; + else if( ( pKey = strstr ( str, "[GTT_Table]" ) ) != NULL ) + state = 2; + else if( ( pKey = strstr ( str, "[RL_SSN]" ) ) != NULL ) + state = 3; + else if( ( pKey = strstr ( str, "[GTT_ATTRIBUTE]" ) ) != NULL ) + state = 4; + else if( ( pKey = strstr ( str, "[ACN_VERSION]" ) ) != NULL ) + state = 5; + continue; + } + switch ( state ) + { + case 0: + continue; + case 1: + if( strlen ( str ) < 8 ) + continue; + ParseLocalNode ( str ); + break; + case 2: + if( strlen ( str ) < 15 ) + continue; + ParseRouteInfo ( str ); + break; + case 3: + if( strlen ( str ) < 3 ) + continue; + ParseRLSSN ( str ); + break; + case 4: + ParseGTTAttributeOMC ( str ); + break; + case 5: + ParseACNVerion(str); + break; + } + } + fclose ( fp ); + + //Load Related SPC===========> + RelatedSPCNum = 0; + for ( i = 0; i < RelatedSSNNum; i++ ) + { + for ( j = 0; j < RelatedSPCNum && j < SCCP_RLSPC_NUM; j++ ) + { + if( RelatedSPC[j].DPC == RelatedSSN[i].DPC && RelatedSPC[j].NetID == RelatedSSN[i].NetID ) + continue; + + RelatedSPC[RelatedSPCNum].DPC = RelatedSSN[i].DPC; + RelatedSPC[RelatedSPCNum].NetID = RelatedSSN[i].NetID; + RelatedSPC[RelatedSPCNum].status = 1; + RelatedSPCNum++; + } + } + + return 1; +} + +void sccp_saveparam ( ) +{ + struct in_addr addr; + SCCP_ROUTE *pRoute; + FILE *fp; + int i; + char str1[128], str2[64], host0[24], host1[24], *pCh = NULL; + char cNP[8], cTT[8]; + + if( ( fp = fopen ( SCCP_CONF_FILE, "w" ) ) == NULL ) + return; + + fprintf ( fp, "#SCCP Config file (R%dV%d_%02d)\r\n\r\n", SCCP_Param.version[0], SCCP_Param.version[1], SCCP_Param.version[2] ); + + fprintf ( fp, "[Local Node]\r\n\ +#ssn NetID msisdn ip0 ip1 acn_index\r\n" ); + for ( i = 2; i < 256; i++ ) + { + if( LocalSSN[i].status[0] == 0 && LocalSSN[i].status[1] == 0 ) + continue; + + if( LocalSSN[i].ip[0] > 0 && LocalSSN[i].ip[0] != 0xFFFFFFFF ) + { + /* if (LocalSSN[i].ip[0] == SCCP_Param.ip) + { + sprintf(host0,"localhost"); + } + else */ + { + addr.s_addr = LocalSSN[i].ip[0]; + strcpy ( host0, inet_ntoa ( addr ) ); + } + } + else + strcpy ( host0, "-" ); + if( LocalSSN[i].ip[1] > 0 && LocalSSN[i].ip[1] != 0xFFFFFFFF ) + { + /* if (LocalSSN[i].ip[1] == SCCP_Param.ip) + { + sprintf(host1,"localhost"); + } + else */ + { + addr.s_addr = LocalSSN[i].ip[1]; + strcpy ( host1, inet_ntoa ( addr ) ); + } + } + else + strcpy ( host1, "-" ); + + Bcd2Str ( str1, LocalSSN[i].msisdn, LocalSSN[i].msisdn_len % MAX_DIGITS ); + if( ( pCh = strchr ( str1, 'F' ) ) != NULL ) + *pCh = 0; + + if( strlen ( str1 ) == 0 ) + strcpy ( str1, "-" ); + + fprintf ( fp, "%-4d %-5d %-15s %-15s %-15s %d\r\n", i, LocalSSN[i].NetID, str1, host0, host1, LocalSSN[i].acn_index); + } + + fprintf ( fp, "[GTT_Table]\r\n" "#No EN NP TT StartDigits EndDigits NI SPC SSN RI AI S E N Rep ACN_index\r\n" ); + for ( i = 0; i < SCCP_ROUTE_NUM; i++ ) + { +//Commented by Roy Jiang for the disabled GTT entries +// if( RouteList[i].avail == 0 ) + + pRoute = &RouteList[i]; + if(pRoute->avail==0 && (pRoute->StartDigits[0]&0xf0)==0xf0) + continue; + if( pRoute->len > 0 ) + { + + Bcd2Str ( str1, pRoute->StartDigits, pRoute->len % MAX_DIGITS ); + if( ( pCh = strchr ( str1, 'F' ) ) != NULL ) + *pCh = 0; + Bcd2Str ( str2, pRoute->EndDigits, pRoute->len % MAX_DIGITS ); + if( ( pCh = strchr ( str2, 'F' ) ) != NULL ) + *pCh = 0; + } + else + { + strcpy ( str1, "-" ); + strcpy ( str2, "-" ); + } + + if( pRoute->NP == 0 ) + sprintf ( cNP, "-" ); + else + sprintf ( cNP, "%d", pRoute->NP ); + + if( pRoute->TT == 0 ) + sprintf ( cTT, "-" ); + else + sprintf ( cTT, "%d", pRoute->TT ); + + fprintf ( fp, "%-4d %d %s %s %-15s %-15s %d %02X%02X%02X %d %d %d ", i, RouteList[i].avail, cNP, cTT, str1, str2, pRoute->NetID, pRoute->DPC[0], pRoute->DPC[1], pRoute->DPC[2], pRoute->SSN, pRoute->RI, + pRoute->AI); + if( pRoute->convert ) + { + Bcd2Str ( str1, pRoute->ReplaceDigits, pRoute->replace_len % MAX_DIGITS ); + if( ( pCh = strchr ( str1, 'F' ) ) != NULL ) + *pCh = 0; + fprintf ( fp, "%-1d% -1d %-1d %-15s %d\r\n", pRoute->ReplaceStart, pRoute->ReplaceEnd, pRoute->OutNP, str1, pRoute->acn_index ); + } + else + fprintf ( fp, "%d\r\n", pRoute->acn_index ); + } + + fprintf ( fp, "\r\n[RL_SSN]\r\n#NetID DPC SSN\r\n " ); + for ( i = 0; i < RelatedSSNNum; i++ ) + { + if( RelatedSSN[i].status == 0 ) + continue; + fprintf ( fp, "%-5d 0x%-6X %-d\r\n", RelatedSSN[i].NetID, RelatedSSN[i].DPC, RelatedSSN[i].SSN ); + } + + fprintf ( fp, "\r\n[GTT_ATTRIBUTE]\r\nIdx\r\n " ); + for ( i = 0; i < 256; i++ ) + { + if( RouteList[i].avail == 0 ) + continue; + Bcd2Str ( str1, GTTAttribute[i].attribute, SCCP_MAX_GTT_ATTRIBUTE * 2 ); + fprintf ( fp, "%-3d %s\r\n", i, str1 ); + } + + fprintf ( fp, "\r\n[ACN_VERSION]\r\n " "#No avail 37bytes\r\n"); + for(i = 0; i < SCCP_ROUTE_NUM; i++) + { + if( acn_ver_table[i].avail == 0 && acn_ver_table[i].LocationUpdating==0) + continue; + Bcd2Str ( str1, &acn_ver_table[i].LocationUpdating, sizeof(SCCP_ACN_VER_TABLE)-1); + fprintf ( fp, "%-4d %-2d %s\r\n", i, acn_ver_table[i].avail, str1 ); + } + + + fclose ( fp ); + +} + +int sccp_setparam ( DWORD * oid, BYTE * pdata, WORD datalen ) +{ + SCCP_ROUTE *pRoute; + RL_SSN *pRLSSN; + LOCAL_SSN *pLocalSSN; + LOCAL_SSN OldLocalSSN; + u_short instance, i; + + instance = oid[1]; + switch ( oid[0] ) + { + case 1: + spLogDebug ( SCCPDB_SNMP, "Set Local Node. ssn = %d", instance ); + if( instance >= 256 ) + return -1; + + pLocalSSN = &LocalSSN[instance]; + + /* copy the old important parameter */ + OldLocalSSN.NetID = pLocalSSN->NetID; + OldLocalSSN.ip[0] = pLocalSSN->ip[0]; + OldLocalSSN.ip[1] = pLocalSSN->ip[1]; + /* copy the old important parameter */ + + pLocalSSN->NetID = pdata[0]; + memcpy ( &pLocalSSN->msisdn, pdata + 1, MAX_DIGITS ); + memcpy ( &pLocalSSN->ip[0], pdata + MAX_DIGITS + 1, 8 ); + LocalSSN[instance].msisdn_len = ( BcdLen ( LocalSSN[instance].msisdn, MAX_DIGITS ) + 1 ) / 2; + + /* if old and new important parameter are same then return */ + if( OldLocalSSN.NetID == pLocalSSN->NetID && OldLocalSSN.ip[0] == pLocalSSN->ip[0] && OldLocalSSN.ip[1] == pLocalSSN->ip[1] ) + return 19; + /* if old and new important parameter are same then return */ + + LocalSSN[instance].local = 0; + LocalSSN[instance].status[0] = LocalSSN[instance].status[1] = 0; + if( LocalSSN[instance].ip[0] > 0 && LocalSSN[instance].ip[0] != 0xFFFFFFFF ) + { + if( LocalSSN[instance].ip[0] == SCCP_Param.ip ) + { + LocalSSN[instance].status[0] = 1; + LocalSSN[instance].local = 1; + } + else + { + LocalSSN[instance].status[0] = 3; + LocalSSN[instance].timeout[0] = T_hbrecv; + } + } + if( LocalSSN[instance].ip[1] > 0 && LocalSSN[instance].ip[1] != 0xFFFFFFFF ) + { + if( LocalSSN[instance].ip[1] == SCCP_Param.ip ) + { + LocalSSN[instance].status[1] = 1; + LocalSSN[instance].local = 2; + } + else + { + LocalSSN[instance].status[1] = 3; + LocalSSN[instance].timeout[1] = T_hbrecv; + } + } + + SCCP_Param.T_reset = 100; + return 19; + case 2: //GTT Table + spLogDebug ( SCCPDB_SNMP, "Set GTT Table.instance=%d", instance ); + if( instance >= SCCP_ROUTE_NUM ) + return -1; + + SCCP_Param.T_reset = 100; //2s + + pRoute = &RouteList[instance]; + memcpy ( pRoute, pdata, 43 ); + + pRoute->len = ( BcdLen ( pRoute->StartDigits, MAX_DIGITS ) + 1 ) / 2; + pRoute->replace_len = ( BcdLen ( pRoute->ReplaceDigits, MAX_DIGITS ) + 1 ) / 2; + if( pRoute->ReplaceStart >= 1 && pRoute->ReplaceStart <= pRoute->ReplaceEnd ) + pRoute->convert = 1; + else + pRoute->convert = 0; + SCCP_Param.T_reset = 100; + return 43; + case 3: + spLogDebug ( SCCPDB_SNMP, "Set related subsystem.instance=%d", instance ); + if( instance >= SCCP_RLSSN_NUM ) + return -1; + pRLSSN = &RelatedSSN[instance]; + if( pdata[0] > 0 ) + { + pRLSSN->status = 1; + pRLSSN->NetID = pdata[1]; + pRLSSN->DPC = pdata[2] * 0x10000 + pdata[3] * 0x100 + pdata[4]; + pRLSSN->SSN = pdata[5]; + + for ( i = 0; i < RelatedSPCNum; i++ ) + { + if( RelatedSPC[i].DPC == pRLSSN->DPC && RelatedSPC[i].NetID == pRLSSN->NetID ) + continue; + + RelatedSPC[RelatedSPCNum].DPC = pRLSSN->DPC; + RelatedSPC[RelatedSPCNum].NetID = pRLSSN->NetID; + RelatedSPC[RelatedSPCNum].status = 1; + RelatedSPCNum++; + } + + if( instance + 1 > RelatedSSNNum ) + RelatedSSNNum = instance + 1; + } + else + { + pRLSSN->status = 0; + if( instance == RelatedSSNNum - 1 ) + while ( RelatedSSN[RelatedSSNNum - 1].status == 0 && RelatedSSNNum > 0 ) + RelatedSSNNum--; + } + return 6; + case 4: //GTT Attribute for omc + if( instance >= SCCP_ROUTE_NUM ) + return -1; + memcpy ( >TAttribute[instance], pdata, SCCP_MAX_GTT_ATTRIBUTE ); + return SCCP_MAX_GTT_ATTRIBUTE; + default: + break; + } + return -1; +} + +int sccp_getparam ( DWORD * oid, BYTE * pdata, BYTE * vartype ) +{ + SCCP_ROUTE *pRoute; + RL_SSN *pRLSSN; + LOCAL_SSN *pLocalSSN; + int instance; + + instance = oid[1]; + switch ( oid[0] ) + { + case 1: + spLogDebug ( SCCPDB_SNMP, "get Local Node.ssn=%ld\n", instance ); + if( instance >= 256 ) + return -1; + pLocalSSN = &LocalSSN[instance]; + pdata[0] = pLocalSSN->NetID; + memcpy ( pdata + 1, &pLocalSSN->msisdn, MAX_DIGITS ); + memcpy ( pdata + MAX_DIGITS + 1, &pLocalSSN->ip[0], 8 ); + *vartype = 4; + return 19; + case 2: //GTT Table + spLogDebug ( SCCPDB_SNMP, "get gtt table.instance=%ld\n", instance ); + if( instance >= SCCP_ROUTE_NUM ) + return -1; + *vartype = 4; + + pRoute = &RouteList[instance]; + memcpy ( pdata, pRoute, 43 ); + return 43; + case 3: + spLogDebug ( SCCPDB_SNMP, "Get related subsystem.instance=%d", instance ); + if( instance > RelatedSSNNum ) + return -1; + pRLSSN = &RelatedSSN[instance]; + *vartype = 4; + if( pRLSSN->status == 0 ) + return -1; + pdata[0] = 1; + pdata[1] = pRLSSN->NetID; + pdata[2] = ( pRLSSN->DPC >> 16 ) & 0xFF; + pdata[3] = ( pRLSSN->DPC >> 8 ) & 0xFF; + pdata[4] = pRLSSN->DPC & 0xFF; + pdata[5] = pRLSSN->SSN; + return 6; + case 4: //GTT Attribute + spLogDebug ( SCCPDB_SNMP, "get gtt attribute table.instance=%ld\n", instance ); + if( instance >= SCCP_ROUTE_NUM ) + return -1; + *vartype = 4; + + memcpy ( pdata, >TAttribute[instance], SCCP_MAX_GTT_ATTRIBUTE ); + return SCCP_MAX_GTT_ATTRIBUTE; + default: + break; + } + return -1; +} + +/*+++++++++++++++++++++++++++++++++++++++ */ +//Private function========================> +/*+++++++++++++++++++++++++++++++++++++++ */ +int SccpGetLocalIP ( ) +{ + struct hostent *hptr; + struct in_addr *inaddr; + char hostname[40] = "\0"; + + if( ( gethostname ( hostname, -1 ) ) != 0 ) + return -1; + + if( ( hptr = gethostbyname ( hostname ) ) == NULL ) + return -1; + ((struct in_addr *)(*hptr->h_addr_list))->s_addr = GetLocalIP(); + if( hptr->h_addr_list[0] != NULL ) + { + inaddr = ( struct in_addr * ) hptr->h_addr_list[0]; + SCCP_Param.ip = inaddr->s_addr; + } + return 1; +} + +int ParseLocalNode ( char *str ) +{ + char info[6][128]; + int rtn; + BYTE ssn; + + rtn = ParseLine ( str, info, 6 ); + if( rtn < 3 ) + { + spLogDebug ( SCCPDB_ERR, "<001>Invalid line in Local_Node Table, field count = %d", rtn ); + return 0; + } + + ssn = atoi ( info[0] ); + LocalSSN[ssn].NetID = atoi ( info[1] ) % 4; + LocalSSN[ssn].msisdn_len = Str2Bcd ( LocalSSN[ssn].msisdn, info[2], MAX_DIGITS ); + + if(rtn < 6) + LocalSSN[ssn].acn_index = move_acn_from_mtp3(LocalSSN[ssn].NetID, SCCP_Param.spc[LocalSSN[ssn].NetID]); + else + LocalSSN[ssn].acn_index = atoi(info[5]); + if( rtn < 4 || strstr ( info[3], "-" ) != NULL ) + LocalSSN[ssn].ip[0] = 0xFFFFFFFF; + /* else if (strstr(info[3],"localhost") != NULL) + LocalSSN[ssn].ip[0] = SCCP_Param.ip; */ + else + LocalSSN[ssn].ip[0] = inet_addr ( info[3] ); + + if( rtn < 5 || strstr ( info[4], "-" ) != NULL ) + LocalSSN[ssn].ip[1] = 0xFFFFFFFF; + /* else if (strstr(info[4],"localhost") != NULL) + LocalSSN[ssn].ip[1] = SCCP_Param.ip; */ + else + LocalSSN[ssn].ip[1] = inet_addr ( info[4] ); + + /* if (rtn >= 5) + LocalSSN[ssn].ANSIFlag = atoi(info[5]); */ + + LocalSSN[ssn].local = 0; + LocalSSN[ssn].status[0] = LocalSSN[ssn].status[1] = 0; + if( LocalSSN[ssn].ip[0] > 0 && LocalSSN[ssn].ip[0] != 0xFFFFFFFF ) + { + if( LocalSSN[ssn].ip[0] == SCCP_Param.ip ) + { + LocalSSN[ssn].status[0] = 1; + LocalSSN[ssn].local = 1; + } + else + { + LocalSSN[ssn].status[0] = 3; + LocalSSN[ssn].timeout[0] = T_hbrecv; + } + } + + if( LocalSSN[ssn].ip[1] > 0 && LocalSSN[ssn].ip[1] != 0xFFFFFFFF ) + { + if( LocalSSN[ssn].ip[1] == SCCP_Param.ip ) + { + LocalSSN[ssn].status[1] = 1; + LocalSSN[ssn].local = 2; + } + else + { + LocalSSN[ssn].status[1] = 3; + LocalSSN[ssn].timeout[1] = T_hbrecv; + } + } + else + { + LocalSSN[ssn].status[1] = 0; + } + + return 1; +} + +void ParseRouteInfo ( char *str ) +{ + int spc; + char info[16][128]; + u_short index, rtn; + BYTE offset = 0; + BYTE ConfVer; //configure file version + + SCCP_ROUTE *pRoute; + + rtn = ParseLine ( str, info, 16 ); + if( rtn < 8 ) + { + spLogDebug ( SCCPDB_ERR, "<002>Invalid line in GTT Table, field count = %d", rtn ); + return; + } + if(rtn == 16 || rtn == 12) + ConfVer = 4;//has acn index + else if ( (rtn == 11 ) || ( rtn == 15 ) ) + ConfVer = 3; //has EN + else if( ( rtn == 10 ) || ( rtn == 14 ) ) + ConfVer = 2; //has TT and AI + else if( ( rtn == 9 ) || ( rtn == 13 ) ) + ConfVer = 1; //has AI + else + ConfVer = 0; //without TT and AI + + index = atoi ( info[offset++] ); //0 + if( index >= SCCP_ROUTE_NUM ) + { + spLogDebug ( SCCPDB_ERR, "<003>invalid index in GTT Table, index = %d", index ); + return; + } + pRoute = &RouteList[index]; + if ( ConfVer >= 3 ) + pRoute->avail = atoi ( info[offset++] ); // 1 + else + pRoute->avail = 1; + + if( strstr ( info[offset], "-" ) != NULL ) // 2 + pRoute->NP = 0; + else + pRoute->NP = atoi ( info[offset] ); //2 + offset++; + if( ConfVer >= 2 ) + { + if( strstr ( info[offset], "-" ) != NULL ) //3 + pRoute->TT = 0; + else + pRoute->TT = atoi ( info[offset] ); //3 + offset++; + } + else + pRoute->TT = 0; + + memset ( pRoute->StartDigits, 0xFF, MAX_DIGITS * 2 ); + Str2Bcd ( pRoute->StartDigits, info[offset++], MAX_DIGITS ); //4 + pRoute->len = Str2Bcd ( pRoute->EndDigits, info[offset++], MAX_DIGITS ); //5 + + pRoute->NetID = atoi ( info[offset++] ) % 4; //6 + spc = strtol ( info[offset++], NULL, 16 ); //7 + pRoute->DPC[0] = spc >> 16; + pRoute->DPC[1] = spc >> 8; + pRoute->DPC[2] = spc; + + pRoute->SSN = atoi ( info[offset++] ); //8 + pRoute->RI = atoi ( info[offset++] ); //9 + + /* daniel */ + if( ConfVer > 0 ) + pRoute->AI = atoi ( info[offset++] ) & 7; //10 + else + pRoute->AI = 7; + + if( rtn < 13 ) + { + pRoute->convert = 0; + if(ConfVer < 4)// move acn from mtp3 + { + pRoute->acn_index = move_acn_from_mtp3(pRoute->NetID, spc); + sccpEnableSaveFlag(); + + } + else + { + pRoute->acn_index = atoi ( info[offset++] );// 11 + } + return; + } + + /* daniel */ + pRoute->ReplaceStart = atoi ( info[offset++] ); //11 + pRoute->ReplaceEnd = atoi ( info[offset++] ); //12 + pRoute->OutNP = atoi ( info[offset++] ); //13 + if( pRoute->ReplaceStart < 1 || pRoute->ReplaceStart > pRoute->ReplaceEnd ) + { + pRoute->convert = 0; + offset++; + } + else + { + memset ( pRoute->ReplaceDigits, 0xFF, MAX_DIGITS ); + pRoute->replace_len = Str2Bcd ( pRoute->ReplaceDigits, info[offset++], MAX_DIGITS ); //14 + pRoute->convert = 1; + } + if(ConfVer < 4)// move acn from mtp3 + { + pRoute->acn_index = move_acn_from_mtp3(pRoute->NetID, spc); + sccpEnableSaveFlag(); + + } + else + { + pRoute->acn_index = atoi ( info[offset++] );// 15 + } + + return; +} + +void ParseACNVerion(char *str) +{ + SCCP_ACN_VER_TABLE *pAcn = NULL; + char info[3][128]; + u_short index, rtn; + BYTE offset = 0; + + rtn = ParseLine ( str, info, 3 ); + if( rtn < 3 ) + { + spLogDebug ( SCCPDB_ERR, "<004>Invalid line in ACN Table, field count = %d", rtn ); + return; + } + + index = atoi ( info[offset++] ); //0 + if( index >= SCCP_ROUTE_NUM ) + { + spLogDebug ( SCCPDB_ERR, "<003>invalid index in ACN Table, index = %d", index ); + return; + } + + pAcn = &acn_ver_table[index]; + pAcn->avail = atoi ( info[offset++] ); + if( strlen( info[offset] ) < 74 ) + { + Str2Bcd ( &pAcn->LocationUpdating , info[offset], sizeof(SCCP_ACN_VER_TABLE)-2); + pAcn->VLRCamelPhase = 7; + } + else + Str2Bcd ( &pAcn->LocationUpdating , info[offset], sizeof(SCCP_ACN_VER_TABLE)-1); + + return; +} + +void ParseRLSSN ( char *str ) +{ + RL_SSN *pRLSSN = NULL; + char info[3][128]; + int rtn; + BYTE NetID; + int spc; + + rtn = ParseLine ( str, info, 3 ); + if( rtn < 3 ) + { + spLogDebug ( SCCPDB_ERR, "<004>Invalid line in RL_SSN Table, field count = %d", rtn ); + return; + } + + pRLSSN = &RelatedSSN[RelatedSSNNum]; + + pRLSSN->status = 0; + NetID = pRLSSN->NetID = atoi ( info[0] ) % 4; + spc = pRLSSN->DPC = strtol ( info[1], NULL, 16 ); + pRLSSN->SSN = atoi ( info[2] ); + pRLSSN->SST = 1; + pRLSSN->timeout = T_sst; + if( SCCP_Param.spc[NetID] == spc ) + return; + pRLSSN->status = ST_Disable; + RelatedSSNNum = ( RelatedSSNNum + 1 ) % SCCP_RLSSN_NUM; +} + +static void ParseGTTAttributeOMC ( char *str ) +{ + GTTATT_OMC *pGTTAtt = NULL; + char info[3][128]; + int rtn; + BYTE index; + + rtn = ParseLine ( str, info, 3 ); + if( rtn < 2 ) + { + spLogDebug ( SCCPDB_ERR, "<004>Invalid line in GTT Attribute Table, field count = %d", rtn ); + return; + } + index = atoi ( info[0] ); + pGTTAtt = >TAttribute[index]; + Str2Bcd ( pGTTAtt->attribute, info[1], SCCP_MAX_GTT_ATTRIBUTE * 2 ); +} diff --git a/plat/sccp/src/sclc.c b/plat/sccp/src/sclc.c new file mode 100644 index 0000000..3c32fcc --- /dev/null +++ b/plat/sccp/src/sclc.c @@ -0,0 +1,638 @@ + +/*******************************************/ +/*Title: sclc.c */ +/*Descr: SCCP Connectionless Control */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ + +/*******************************************/ + +#include "./include/sccp.h" + +// fix multiple definition==================================== +SCCP_SegMsgBuf sccp_segmsgbuf[MAX_SEGMSG_BUF]; +// + +/*===========export================*/ +int scrc2sclc ( Intra_Msg * pIntraMsg ); +int sclc_rf ( Intra_Msg * pIntraMsg ); + +/*===========import================*/ +extern int sclc2scmg ( Intra_Msg * intramsg ); //scmg.c +extern int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); //scrc.c +extern int scrc_mnp_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); //scrc.c +extern int send_msg ( Intra_Msg * pIntraMsg ); //scrc.c +extern void spLogDebug ( DWORD mask, const char *fmt, ... ); +extern void spShowBCD(DWORD mask, BYTE *buf, int len); +extern void spShowMsg(DWORD mask, const char *pDesc, Intra_Msg *pIntraMsg); +extern void spLog ( char *info ); +extern int GetMSISDNOfSSN(BYTE ssn, BYTE *msisdn); + +static SCLC_BUF SCLC_OutBuf; +static SCLC_BUF SCLC_InBuf[MAX_SCLC_BUF]; + +/* buffer changed from 3 to 4, Pierre , 11-07 */ + +int RecvXUDTMsg ( Intra_Msg * pIntraMsg, BYTE nbuf ); +int CheckSegUnID ( Intra_Msg * pIntraMsg ); +int RsmRegMsg ( SCLC_MSG * pmsg, SCCP_SegMsgBuf * pSegMsgbuf, Intra_Msg * pIntraMsg ); +extern void spLogSeg ( SCCP_SegMsgBuf * pSegMsgbuf ); + +int scrc2sclc ( Intra_Msg * pIntraMsg ) +{ + SCLC_MSG *pmsg; + short writesub, readsub; + BYTE nbuf; + + SccpCsta[SccpCstaInd].utilization[4 - 3]++; + if( pIntraMsg->msgMNP ) + { + nbuf = 1; + sccpmsg_st.mnp_route++; + if(pIntraMsg->msgsource == FROM_MTP) + { + pIntraMsg->SLS = LocalSSN[pIntraMsg->CDA.SSN].local+1; + } + } /* added by pierre for MNP , 2005-11-07 */ + else + { + nbuf = LocalSSN[pIntraMsg->CDA.SSN].nbuf % MAX_SCLC_BUF; + } + + switch ( pIntraMsg->msgtype ) + { + case UDT_MSG: + break; + case XUDT_MSG: + switch ( RecvXUDTMsg ( pIntraMsg, nbuf ) ) + { + case 0: + break; + case 1: + break; + case 2: + break; + case 3: + break; + + } + return 0; + case LUDT_MSG: + spLogDebug ( SCCPDB_UDT | SCCPDB_ERR, "<005>LUDT/XUDT message is not supported" ); + return 0; + case UDTS_MSG: + break; + case XUDTS_MSG: + case LUDTS_MSG: + spLogDebug ( SCCPDB_UDT | SCCPDB_ERR, "<005>LUDTS/XUDTS message is not supported" ); + return 0; + } + if( pIntraMsg->CDA.SSN == SSN_SCMG ) + return sclc2scmg ( pIntraMsg ); + else + { + writesub = SCLC_InBuf[nbuf].writesub; + readsub = SCLC_InBuf[nbuf].readsub; + pmsg = &SCLC_InBuf[nbuf].msglist[writesub]; + + pmsg->msglen = pIntraMsg->msglen % SCCP_MSG_MAXLEN; + memcpy ( pmsg->msg, pIntraMsg->data, pmsg->msglen ); + memcpy ( &( pmsg->src_addr ), &( pIntraMsg->CGA ), sizeof ( SCCP_ADDR ) ); + memcpy ( &( pmsg->dst_addr ), &( pIntraMsg->CDA ), sizeof ( SCCP_ADDR ) ); + pmsg->sls = pIntraMsg->SLS; + + if( ( SCLC_InBuf[nbuf].writesub + 1 ) == SCLC_InBuf[nbuf].readsub ) + spShowMsg ( SCCPDB_UDT, "USER <== SCCP: buf overflow!!!!!!!", pIntraMsg ); + + SCLC_InBuf[nbuf].writesub = ( writesub + 1 ) % SS_MSG_NUM; + if( SCLC_InBuf[nbuf].writesub == readsub ) + SCLC_InBuf[nbuf].readsub = ( readsub + 1 ) % SS_MSG_NUM; + + if (pIntraMsg->msgtype == UDTS_MSG) + { + pmsg->primitive = N_NOTICE_IND; + spShowMsg ( SCCPDB_UDT, "USER <== SCCP: N-NOTICE", pIntraMsg ); + } + else + { + pmsg->primitive = N_UNITDATA_IND; + spShowMsg ( SCCPDB_UDT, "USER <== SCCP: UDT Message", pIntraMsg ); + } + } + return 1; +} + +int sclc_rf ( Intra_Msg * pIntraMsg ) +{ + SCCP_ADDR swapaddr; + + spShowMsg ( SCCPDB_UDT | SCCPDB_ERR, "<006>Route Failure", pIntraMsg ); + switch ( pIntraMsg->msgtype ) + { + case UDT_MSG: + if( pIntraMsg->msgsource == FROM_MTP || pIntraMsg->msgsource == FROM_SCLC ) + { + memcpy ( &swapaddr, &( pIntraMsg->CDA ), sizeof ( SCCP_ADDR ) ); + memcpy ( &( pIntraMsg->CDA ), &( pIntraMsg->CGA ), sizeof ( SCCP_ADDR ) ); + memcpy ( &( pIntraMsg->CGA ), &swapaddr, sizeof ( SCCP_ADDR ) ); + pIntraMsg->CDA.ip = 0xFFFFFFFF; + if( pIntraMsg->CDA.RI == RI_SSN ) + { + if( pIntraMsg->CDA.DPC == 0 ) + pIntraMsg->CDA.DPC = pIntraMsg->CGA.DPC; + } + pIntraMsg->msgsource = FROM_SCLC; + pIntraMsg->msgtype = UDTS_MSG; + return scrc_route ( pIntraMsg, 0 ); + } + break; + case XUDT_MSG: + case LUDT_MSG: + //unsupported now + break; + case UDTS_MSG: + break; + case XUDTS_MSG: + case LUDTS_MSG: + //unsupported now + break; + } + return -1; +} + +int scmg2sclc ( Intra_Msg * pIntraMsg ) +{ + return scrc_route ( pIntraMsg, 0 ); +} + +/******************************************************************/ + +/*================== User Interface-----> ================*/ + +/******************************************************************/ +int sclc_send ( SCLC_MSG * pmsg ) +{ + if( pmsg->msglen > 256 ) + { + spLogDebug ( SCCPDB_ERR | SCCPDB_UDT, "<007>User ==> SCCP: Message's Length exceed 256" ); + spShowBCD ( SCCPDB_ERR, pmsg->msg, pmsg->msglen % 256 ); + return 0; + } + SccpCsta[SccpCstaInd].utilization[0]++; + + memcpy ( &SCLC_OutBuf.msglist[SCLC_OutBuf.writesub], pmsg, sizeof ( SCLC_MSG ) ); + SCLC_OutBuf.writesub = ( SCLC_OutBuf.writesub + 1 ) % SS_MSG_NUM; + if( SCLC_OutBuf.writesub == SCLC_OutBuf.readsub ) + { + spLogDebug ( SCCPDB_ERR | SCCPDB_UDT, "<008>SCLC Out Buffer Overflow" ); + SCLC_OutBuf.readsub = ( SCLC_OutBuf.readsub + 1 ) % SS_MSG_NUM; + } + + return 1; +} + +int sclc_receive ( SCLC_MSG * pmsg, BYTE usertype ) +{ + short readsub; + + usertype %= MAX_SCLC_BUF; /* revised by pierre */ + readsub = SCLC_InBuf[usertype].readsub % SS_MSG_NUM; + if( SCLC_InBuf[usertype].writesub == readsub ) + return 0; + + memcpy ( pmsg, &SCLC_InBuf[usertype].msglist[readsub], sizeof ( SCLC_MSG ) ); + SCLC_InBuf[usertype].readsub = ( readsub + 1 ) % SS_MSG_NUM; + + return 1; +} + +int need_mnp(u8 mnp_type, u8 src_ssn, u8 dst_ssn, u8 *src_digits, u8 digits_len, u8 msg_begin) +{ + u8 msc_digit[10]; + + switch(mnp_type) + { + case 0: + return 0; + break; + case 1://Ansi IN + if(dst_ssn==6 && (src_ssn ==8 || src_ssn==147 ||src_ssn==11) && msg_begin==0x62) + { + GetMSISDNOfSSN(8, msc_digit); + + if(src_ssn ==8 && !memcmp(msc_digit, src_digits, (digits_len+1)/2))//msc sri + return 0; + else + return 1;//smsc pps sri + } + break; + case 2://SRF + if(dst_ssn==6 && (src_ssn ==8 || src_ssn==147 ||src_ssn==11) && msg_begin==0x62) + return 1; + break; + default : + break; + + } + return 0; +} +void sclc_timer ( ) +{ + Intra_Msg outmsg; + SCLC_MSG *pmsg; + int loop = 128; + short readsub; + u8 msc_digit[10]; + + int SegMsgIndex; + outmsg.OPC = 0; + for ( SegMsgIndex = 0; SegMsgIndex < MAX_SEGMSG_BUF; SegMsgIndex++ ) + { + if( sccp_segmsgbuf[SegMsgIndex].SegMsgTimer && sccp_segmsgbuf[SegMsgIndex].SegMsgTimer++ > MAX_SEGMSG_TIMER ) + { + spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg Timer Out. " ); + spLogSeg ( &sccp_segmsgbuf[SegMsgIndex] ); + memset ( &sccp_segmsgbuf[SegMsgIndex], 0, sizeof ( SCCP_SegMsgBuf ) ); + } + } + + while ( loop-- > 0 ) + { + if( SCLC_OutBuf.readsub == SCLC_OutBuf.writesub ) + return; + + readsub = SCLC_OutBuf.readsub % SS_MSG_NUM; + pmsg = &SCLC_OutBuf.msglist[readsub]; + SCLC_OutBuf.readsub = ( readsub + 1 ) % SS_MSG_NUM; + + outmsg.msgsource = FROM_SCLC; + outmsg.msgtype = UDT_MSG; + outmsg.msgclass = 0; + outmsg.SLS = pmsg->sls; + outmsg.sequenceFlag = pmsg->sequence_control; + + memcpy ( &( outmsg.CDA ), &pmsg->dst_addr, sizeof ( SCCP_ADDR ) ); + memcpy ( &( outmsg.CGA ), &pmsg->src_addr, sizeof ( SCCP_ADDR ) ); + + outmsg.NetID = outmsg.CGA.NetID = outmsg.CDA.NetID; + // outmsg.CDA.TT = 0; + outmsg.CDA.ip = 0xFFFFFFFF; + outmsg.msglen = pmsg->msglen % 256; + memcpy ( outmsg.data, pmsg->msg, pmsg->msglen % 256 ); + +// if( MNP_Flag[0] != 0 && outmsg.CDA.NP == 1 && outmsg.CDA.SSN == 6 && pmsg->msg[0] == 0x62 ) + if(need_mnp(MNP_Flag[0], outmsg.CGA.SSN, outmsg.CDA.SSN, outmsg.CGA.GTAI, outmsg.CGA.len, pmsg->msg[0])) + { + /* MNP supported */ + if( MNP_Flag[1] != 2 ) /* Direct routing */ + { + GetMSISDNOfSSN(8, msc_digit); + if( MNP_Flag[0] == 1 && outmsg.CDA.TT != 0 && outmsg.CGA.SSN != 10) + { + /* IN_based call related message */ + spLogDebug ( SCCPDB_UDT, "User ==> SCCP ==> MNP_SRF: IN_based MNP and Call_related message, routed to MNP" ); + //spShowMsg(SCCPDB_USER, "User ==> SCCP: UDT Message", &outmsg); + //scrc_route(&outmsg); + outmsg.msgMNP = 1; + scrc2sclc ( &outmsg ); + continue; + } + else if( outmsg.CGA.SSN != 10 )//&& (!(!memcmp(msc_digit, outmsg.CGA.GTAI, (outmsg.CGA.GTAI+1)/2) && MNP_Flag[0] == 1 ) )) + { + spShowMsg ( SCCPDB_USER, "User ==> SCCP ==> MNP_SRF : UDT Message", &outmsg ); + + outmsg.msgMNP = 1; + scrc2sclc ( &outmsg ); + continue; + } + } + } + + spShowMsg ( SCCPDB_USER, "User ==> SCCP: UDT Message", &outmsg ); + scrc_route ( &outmsg, 0 ); + } + return; +} + +/* added by Pierre for MNP, 2005-11-07 */ +int sclc_mnp_send ( SCLC_MSG * pmsg ) +{ + Intra_Msg outmsg; + + if( pmsg->msglen > 256 ) + { + spLogDebug ( SCCPDB_ERR | SCCPDB_UDT, "<007>User ==> SCCP: Message's Length exceed 256" ); + spShowBCD ( SCCPDB_ERR, pmsg->msg, pmsg->msglen % 256 ); + return 0; + } + SccpCsta[SccpCstaInd].utilization[0]++; + + sccpmsg_st.mnp_send++; + outmsg.msgsource = FROM_SCLC; + outmsg.msgtype = UDT_MSG; + outmsg.msgclass = 0; + outmsg.SLS = pmsg->sls; + + memcpy ( &( outmsg.CDA ), &pmsg->dst_addr, sizeof ( SCCP_ADDR ) ); + memcpy ( &( outmsg.CGA ), &pmsg->src_addr, sizeof ( SCCP_ADDR ) ); + + outmsg.NetID = outmsg.CGA.NetID = outmsg.CDA.NetID; + //outmsg.CDA.TT = 0; + outmsg.CDA.ip = 0xFFFFFFFF; + outmsg.msglen = pmsg->msglen % 256; + memcpy ( outmsg.data, pmsg->msg, pmsg->msglen % 256 ); + + spShowMsg ( SCCPDB_USER, "User ==> SCCP: UDT Message", &outmsg ); + + return scrc_mnp_route ( &outmsg, 0 ); + +} + +//add for UDT SegmentingMsg to XUDT --lw 2007/03/20 +int SegmentingMsg ( Intra_Msg * pIntraMsg ) +{ + Intra_Msg pIntraMsgSeg1, pIntraMsgSeg2; + int ret1, ret2; + BYTE sSegLR[4]; + + ret1 = ret2 = 0; + + memcpy ( &pIntraMsgSeg1, pIntraMsg, sizeof ( Intra_Msg ) ); + memcpy ( &pIntraMsgSeg2, pIntraMsg, sizeof ( Intra_Msg ) ); + + pIntraMsgSeg1.msglen = pIntraMsg->msglen / 2; + pIntraMsgSeg2.msglen = pIntraMsg->msglen - pIntraMsgSeg1.msglen; + + memset ( &pIntraMsgSeg1.data[pIntraMsgSeg1.msglen], 0, SCCP_MSG_MAXLEN - pIntraMsgSeg1.msglen ); + memcpy ( &pIntraMsgSeg2.data[0], &pIntraMsg->data[pIntraMsgSeg1.msglen], pIntraMsgSeg2.msglen ); + memset ( &pIntraMsgSeg2.data[pIntraMsgSeg2.msglen], 0, SCCP_MSG_MAXLEN - pIntraMsgSeg2.msglen ); + + pIntraMsgSeg1.msgtype = pIntraMsgSeg2.msgtype = XUDT_MSG; + pIntraMsgSeg1.SegPresent = pIntraMsgSeg2.SegPresent = 1; + pIntraMsgSeg1.Segmnt.CBit = pIntraMsgSeg2.Segmnt.CBit = 1; //sequence + pIntraMsgSeg1.Segmnt.FBit = 1; + pIntraMsgSeg2.Segmnt.FBit = 0; + pIntraMsgSeg1.Segmnt.RSBits = 1; + pIntraMsgSeg2.Segmnt.RSBits = 0; + pIntraMsgSeg1.Hop = pIntraMsgSeg1.Hop = 0; + sSegLR[0] = ( SCCP_Param.ip >> 16 ) & 0x0001; //plant number + sSegLR[1] = pIntraMsg->SLS; + sSegLR[2] = SCCPCapBuf.watch_dog[128]++; + memcpy ( pIntraMsgSeg1.Segmnt.SegLR, sSegLR, SEG_RS_LEN ); + memcpy ( pIntraMsgSeg2.Segmnt.SegLR, sSegLR, SEG_RS_LEN ); + + spLogDebug ( SCCPDB_UDT, "SCCP =>SCCP_RegProc=> SCCP : Length [%d Bytes] [%d Bytes]\r\n", pIntraMsgSeg1.msglen, pIntraMsgSeg2.msglen ); + + ret1 = send_msg ( &pIntraMsgSeg1 ); + + ret2 = send_msg ( &pIntraMsgSeg2 ); + + return ( ret1 > 0 && ret2 > 0 ); +} + +int RecvXUDTMsg ( Intra_Msg * pIntraMsg, BYTE nbuf ) +{ + SCLC_MSG *pmsg; + short writesub, readsub; + int SegMsgIndex; + + if( !pIntraMsg->SegPresent ) //Not Include Segmentation Paramenters + { + return -1; + } + + if( pIntraMsg->Segmnt.FBit == 1 && pIntraMsg->Segmnt.RSBits == 0 ) //Single Segmetaion + { + return -1; + } + + SegMsgIndex = CheckSegUnID ( pIntraMsg ); + + if( SegMsgIndex == MAX_SEGMSG_BUF + 1 ) //check CGA SLR MTP3 routing lable is idle + { + return 0; + } + + else if( SegMsgIndex == MAX_SEGMSG_BUF ) //first Segmentation + { + if( pIntraMsg->Segmnt.FBit != 1 ) + { + spLogDebug ( SCCPDB_ERR, "SCCP Recv new XUDT Msg but the Fbit is not 1." ); + return 0; + } + + for ( SegMsgIndex = 0; SegMsgIndex < MAX_SEGMSG_BUF; SegMsgIndex++ ) + { + if( sccp_segmsgbuf[SegMsgIndex].MsgState == SEGSTREAM_IDLE ) + { + int SegBlockIndex; + SCCP_SegStream *pSegStream; + SCCP_SegMsgBuf *pSegMsgbuf = &sccp_segmsgbuf[SegMsgIndex]; + + pSegMsgbuf->MsgClass = pIntraMsg->Segmnt.CBit; + pSegMsgbuf->MsgTotal = pIntraMsg->Segmnt.RSBits + 1; + pSegMsgbuf->RSE = pIntraMsg->Segmnt.RSBits - 1; + + pSegMsgbuf->SegID.DPC = pIntraMsg->DPC; + pSegMsgbuf->SegID.OPC = pIntraMsg->OPC; + pSegMsgbuf->SegID.SLS = pIntraMsg->SLS; + memcpy ( &pSegMsgbuf->SegID.CGA, &pIntraMsg->CGA, sizeof ( SCCP_ADDR ) ); + memcpy ( &pSegMsgbuf->SegID.SegLR, &pIntraMsg->Segmnt.SegLR, SEG_RS_LEN ); + + SegBlockIndex = pSegMsgbuf->MsgTotal - ( pIntraMsg->Segmnt.RSBits + 1 ); + pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex]; + pSegStream->SegDataLen = pIntraMsg->msglen; + memcpy ( &pSegStream->SegDataBlock, &pIntraMsg->data, pIntraMsg->msglen ); + + pSegMsgbuf->SegMsgTimer = 1; + pSegMsgbuf->MsgState = SEGSTREAM_BUSY; + + return 1; + } + } + + if( SegMsgIndex == MAX_SEGMSG_BUF ) + { + spLogDebug ( SCCPDB_ERR, "SCCP Recv new XUDT but SCCP SegMsg buf is not enough" ); + return 0; + } + } + else //not first Segmentation + { + int SegBlockIndex; + int i, j, linemax; + char info[2560 * 3 + 512], temp_str[128]; + SCCP_SegStream *pSegStream; + SCCP_SegMsgBuf *pSegMsgbuf = &sccp_segmsgbuf[SegMsgIndex]; + + if( pIntraMsg->Segmnt.RSBits != pSegMsgbuf->RSE ) + { + spLogDebug ( SCCPDB_ERR, "SCCP Recv unexpect RS XUDT Msg , discard it" ); + return 0; + } + + if( pIntraMsg->Segmnt.FBit == 1 ) + { + spLogDebug ( SCCPDB_ERR, "SCCP Recv XUDT Msg dupulicate first segment. discard it" ); + return 0; + } + + SegBlockIndex = pSegMsgbuf->MsgTotal - ( pIntraMsg->Segmnt.RSBits + 1 ); + pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex]; + + if( pSegStream->SegDataLen ) + { + spLogDebug ( SCCPDB_ERR, "SCCP Recv XUDT Msg dupulicate segment, discard it[RS :%d]", pIntraMsg->Segmnt.RSBits ); + return 0; + } + pSegStream->SegDataLen = pIntraMsg->msglen; + memcpy ( &pSegStream->SegDataBlock, &pIntraMsg->data, pIntraMsg->msglen ); + + if( pSegMsgbuf->RSE ) + { + pSegMsgbuf->RSE--; + return 1; + } + + //last segment + pSegMsgbuf->SegMsgTimer = 0; + writesub = SCLC_InBuf[nbuf].writesub; + readsub = SCLC_InBuf[nbuf].readsub; + pmsg = &SCLC_InBuf[nbuf].msglist[writesub]; + + if( !RsmRegMsg ( pmsg, pSegMsgbuf, pIntraMsg ) ) + { + return 0; + } + + if( ( SCLC_InBuf[nbuf].writesub + 1 ) == SCLC_InBuf[nbuf].readsub ) + spShowMsg ( SCCPDB_UDT, "USER <== SCCP: buf overflow!!!!!!!", pIntraMsg ); + + SCLC_InBuf[nbuf].writesub = ( writesub + 1 ) % SS_MSG_NUM; + if( SCLC_InBuf[nbuf].writesub == readsub ) + SCLC_InBuf[nbuf].readsub = ( readsub + 1 ) % SS_MSG_NUM; + + spLogDebug ( SCCPDB_UDT, "\r\n\r\nUser <== SCCP_RegProc. XUDT Message" ); + spLogSeg ( pSegMsgbuf ); + info[0] = '\0'; + sprintf ( temp_str, "Segmentaion Length info: \r\n" ); + strcat ( info, temp_str ); + for ( i = 0; i < pSegMsgbuf->MsgTotal; i++ ) + { + sprintf ( temp_str, "[%02d]:%d ", i, pSegMsgbuf->SegStream[i].SegDataLen ); + strcat ( info, temp_str ); + if( i == 7 ) + { + strcat ( info, "\r\n" ); + } + } + spLogDebug ( SCCPDB_UDT, info ); + + memset ( info, 0, 2560 * 3 + 512 ); + i = j = linemax = 0; + while ( i * 16 < pmsg->msglen ) + { + if( ( linemax = pmsg->msglen - 16 * i ) > 16 ) + linemax = 16; + for ( j = 0; j < linemax; j++ ) + { + sprintf ( info + 3 * j + ( j > 7 ? 1 : 0 ), "%02X ", pmsg->msg[16 * i + j] ); + if( j == 7 ) + { + sprintf ( info + 3 * 8, " " ); + } + } + spLogDebug ( SCCPDB_UDT,info ); + i++; + } + + memset ( pSegMsgbuf, 0, sizeof ( SCCP_SegMsgBuf ) ); + return 1; + } + + return 0; +} + +int CheckSegUnID ( Intra_Msg * pIntraMsg ) +{ + int SegMsgIndex, nCheckFlag; + SCCP_SegUnID *pSegId; + + nCheckFlag = 0; + for ( SegMsgIndex = 0; SegMsgIndex < MAX_SEGMSG_BUF; SegMsgIndex++ ) + { + pSegId = &sccp_segmsgbuf[SegMsgIndex].SegID; + if( memcmp ( &pSegId->SegLR, &pIntraMsg->Segmnt.SegLR, SEG_RS_LEN ) ) + { + continue; + } + + if( pSegId->DPC != pIntraMsg->DPC ) //have routed , equal of course + { + spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , DPC is not matched!" ); + nCheckFlag = 1;; + } + if( pSegId->OPC != pIntraMsg->OPC ) + { + spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , OPC is not matched!" ); + nCheckFlag = 1; + } + if( pSegId->SLS != pIntraMsg->SLS ) + { + spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , SLS is not matched!" ); + nCheckFlag = 1; + } + if( memcmp ( &pSegId->CGA, &pIntraMsg->CGA, sizeof ( SCCP_ADDR ) ) ) + { + spLogDebug ( SCCPDB_ERR, "SCCP XUDT Msg check MTP3 routing lable fail , CGA is not matched!" ); + nCheckFlag = 1; + } + + if( nCheckFlag ) //act as a new segmention start + { + if( pIntraMsg->Segmnt.FBit == 1 && pIntraMsg->Segmnt.RSBits != 0 ) + { + return MAX_SEGMSG_BUF; + } + return MAX_SEGMSG_BUF + 1; + } + + return SegMsgIndex; + } + return SegMsgIndex; +} + +int RsmRegMsg ( SCLC_MSG * pmsg, SCCP_SegMsgBuf * pSegMsgbuf, Intra_Msg * pIntraMsg ) +{ + int SegBlockIndex, XUDTMsgLen; + SCCP_SegStream *pSegStream; + + XUDTMsgLen = 0; + for ( SegBlockIndex = 0; SegBlockIndex < pSegMsgbuf->MsgTotal; SegBlockIndex++ ) + { + pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex]; + XUDTMsgLen += pSegStream->SegDataLen; + } + + if( XUDTMsgLen > MAX_SCLCMSG_LEN ) + { + spLogDebug ( SCCPDB_ERR, "SCCP Reassemble XUDT Msg is too long ,discard it" ); + return 0; + } + + XUDTMsgLen = 0; + for ( SegBlockIndex = 0; SegBlockIndex < pSegMsgbuf->MsgTotal; SegBlockIndex++ ) + { + pSegStream = &pSegMsgbuf->SegStream[SegBlockIndex]; + if((XUDTMsgLen+ pSegStream->SegDataLen)>MAX_SCLCMSG_LEN) + break; + memcpy ( pmsg->msg + XUDTMsgLen, pSegStream->SegDataBlock, pSegStream->SegDataLen ); + XUDTMsgLen += pSegStream->SegDataLen; + } + pmsg->msglen = XUDTMsgLen; + memcpy ( &( pmsg->src_addr ), &( pIntraMsg->CGA ), sizeof ( SCCP_ADDR ) ); + memcpy ( &( pmsg->dst_addr ), &( pIntraMsg->CDA ), sizeof ( SCCP_ADDR ) ); + + return 1; +} + diff --git a/plat/sccp/src/scmg.c b/plat/sccp/src/scmg.c new file mode 100644 index 0000000..2dd85bd --- /dev/null +++ b/plat/sccp/src/scmg.c @@ -0,0 +1,556 @@ + +/************************************************************/ +/*Title: scmg.c */ +/*Descr: SCCP Management */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/*Modify: 2002-5-7 */ + +/************************************************************/ + +#include "./include/sccp.h" + +/*===========export================*/ +void localssn_timer ( ); +void sst_timer ( ); +int sclc2scmg ( Intra_Msg * intramsg ); +BOOL CheckAvail ( SCCP_ADDR * addr ); + +/*===========import================*/ +extern int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); +extern int send_msg ( Intra_Msg * pIntraMsg, BYTE ansi_flag ); +extern void sccp_sethb ( ); +extern int CollectLocalInfo ( ); +extern int AddToIpList ( DWORD ip, BYTE ssn ); +extern void snmpLogInfo ( char *logInfo ); +extern void spLogDebug ( DWORD mask, const char *fmt, ... ); +/*===========private================*/ +static BYTE ssn_status ( int spc, BYTE ssn, BYTE NetID ); +void spac ( int spc, BYTE NetID ); +void sppc ( int spc, BYTE NetID ); +void spcc ( int spc, BYTE NetID ); +static void ssac ( int spc, BYTE ssn, BYTE NetID, BOOL relay ); +static void sscc ( int spc, BYTE ssn, BYTE NetID ); +static void sspc ( int spc, BYTE ssn, BYTE NetID, BOOL relay ); +static void lcst ( int spc, BYTE ssn, BYTE ntype, BYTE NetID ); +static void bcst ( BYTE ssn, BYTE ntype ); +static void bcst_relay ( int spc, BYTE ssn, BYTE ntype, BYTE NetID ); +static int build_scmgmsg ( BYTE * intramsg, BYTE type, int spc, BYTE ssn, BYTE NetID ); +static int parse_scmgmsg ( BYTE * data, BYTE * type, int *spc, BYTE * ssn, BYTE NetID ); + +void localssn_timer ( ) //called per 1s +{ + int i; + LOCAL_SSN *pSSN; + + for ( i = 0; i < ExistSSNNum; i++ ) + { + pSSN = &LocalSSN[ExistSSN[i]]; + if( pSSN->status[0] == ST_Enable && pSSN->local != 1 && pSSN->timeout[0]-- <= 0 ) + pSSN->status[0] = ST_Disable; + if( pSSN->status[1] == ST_Enable && pSSN->local != 2 && pSSN->timeout[1]-- <= 0 ) + pSSN->status[1] = ST_Disable; + } +} + +int sclc2scmg ( Intra_Msg * intramsg ) +{ + BYTE *pmsg; + BYTE ntype, ssn; + int spc; + BOOL relay = 0; + + intramsg->msgsource = FROM_SCMG; + pmsg = intramsg->data; + parse_scmgmsg ( intramsg->data, &ntype, &spc, &ssn, intramsg->NetID ); + + snmpLogInfo ( "sclc2scmg (): start..." ); + + spLogDebug ( SCCPDB_SCMG, "Receive %s Message.ssn=%d,src_spc=%X", ntype == SSA_MSG ? "SSA" : ( ntype == SSP_MSG ? "SSP" : ( ntype == SST_MSG ? "SST" : "SCMG" ) ), ssn, spc ); + switch ( ntype ) + { + case SSA_MSG: + //to enable subsystem + SccpCsta[SccpCstaInd].avail[11]++; + if( intramsg->OPC != SCCP_Param.spc[intramsg->NetID] && intramsg->CGA.DPC != SCCP_Param.spc[intramsg->NetID] ) + { + lcst ( spc, ssn, SSA_MSG, intramsg->NetID ); + if( spc == intramsg->CGA.DPC ) + relay = 1; + } + ssac ( spc, ssn, intramsg->NetID, relay ); + + break; + case SSC_MSG: + SccpCsta[SccpCstaInd].avail[7]++; + sscc ( spc, ssn, intramsg->NetID ); + break; + case SSP_MSG: + SccpCsta[SccpCstaInd].avail[10]++; + if( intramsg->OPC != SCCP_Param.spc[intramsg->NetID] && intramsg->CGA.DPC != SCCP_Param.spc[intramsg->NetID] ) + { + lcst ( spc, ssn, SSP_MSG, intramsg->NetID ); + if( spc == intramsg->CGA.DPC ) + relay = 1; + } + sspc ( spc, ssn, intramsg->NetID, relay ); + + break; + case SST_MSG: + if( LocalSSN[ssn].status[0] == ST_Enable || LocalSSN[ssn].status[1] == ST_Enable ) + pmsg[0] = SSA_MSG; + else + return 1; + intramsg->OPC=intramsg->CDA.DPC; + memcpy ( &intramsg->CDA, &intramsg->CGA, sizeof ( SCCP_ADDR ) ); + intramsg->CGA.DPC = SCCP_Param.spc[intramsg->NetID]; + intramsg->CGA.GTI = 0; + intramsg->CGA.SSN = 1; + intramsg->CGA.RI = RI_SSN; + intramsg->CGA.len = 0; + + spLogDebug ( SCCPDB_SCMG, "Send %s Message.ssn=%d,dst_spc=%X", ( pmsg[0] == SSA_MSG ) ? "SSA" : ( ( pmsg[0] == SSP_MSG ) ? "SSP" : "SSC" ), ssn, intramsg->CDA.DPC ); + send_msg ( intramsg, mtp3_ansiFlag ( intramsg->NetID ) ); + break; + case SOR_MSG: + //to send SOG + pmsg[0] = SOG_MSG; //to send SOG + intramsg->OPC = intramsg->CDA.DPC; + memcpy ( &intramsg->CDA, &intramsg->CGA, sizeof ( SCCP_ADDR ) ); + scrc_route ( intramsg, 0 ); + break; + case SOG_MSG: + //to disable local subsystem + break; + } + snmpLogInfo ( "sclc2scmg (): end..." ); + return 1; +} + +BOOL CheckAvail ( SCCP_ADDR * addr ) +{ + BYTE status; + + status = ssn_status ( addr->DPC, addr->SSN, addr->NetID ); + if( status == ST_Disable ) + { + spLogDebug ( SCCPDB_ERR, "<009>Subsystem Failure.NetID=%d,SPC=%x,SSN=%d", addr->NetID, addr->DPC, addr->SSN ); + SccpCsta[SccpCstaInd].error[4]++; + return 0; + } + else if( status == ST_Congest ) + { + spLogDebug ( SCCPDB_ERR, "<010>Subsystem Congest.NetID=%d,SPC=%x,SSN=%d", addr->NetID, addr->DPC, addr->SSN ); + SccpCsta[SccpCstaInd].error[5]++; + return 0; + } + //else if(sccp_status(addr->DPC,addr->NetID)==ST_Disable) + // return 0; + else + return 1; +} + +BYTE ssn_status ( int spc, BYTE ssn, BYTE NetID ) +//related subsystem +{ + int i; + + for ( i = 0; i < RelatedSSNNum; i++ ) + { + if( RelatedSSN[i].status == 0 ) + continue; + if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID ) + continue; + + return RelatedSSN[i].status; + } + return ST_Enable; +} + +///////////////////////// +/*SPAC Module----------> */ +///////////////////////// +void spac ( int spc, BYTE NetID ) +{ + int i, j; + + for ( i = 0; i < RelatedSPCNum; i++ ) + { + if( spc == RelatedSPC[i].DPC && NetID == RelatedSPC[i].NetID ) + { + RelatedSPC[i].status = ST_Enable; + for ( j = 0; j < RelatedSSNNum; j++ ) + { + if( RelatedSSN[j].status == 0 ) + continue; + if( spc == RelatedSSN[j].DPC && NetID == RelatedSSN[j].NetID ) + { + if( RelatedSPC[i].status == ST_Disable ) + RelatedSSN[j].SST = 1; + RelatedSSN[j].status = ST_Enable; + } + } + } + } + +} + +///////////////////////// +/*SPPC Module----------> */ +///////////////////////// +void sppc ( int spc, BYTE NetID ) +{ + int i, j; + + for ( i = 0; i < RelatedSPCNum; i++ ) + { + if( spc == RelatedSPC[i].DPC && NetID == RelatedSPC[i].NetID ) + { + RelatedSPC[i].status = ST_Disable; + for ( j = 0; j < RelatedSSNNum; j++ ) + { + if( RelatedSSN[j].status == 0 ) + continue; + if( spc == RelatedSSN[j].DPC && NetID == RelatedSSN[j].NetID ) + { + RelatedSSN[j].SST = 0; + RelatedSSN[j].status = ST_Disable; + } + } + } + } + +} + +///////////////////////// +/*SPCC Module----------> */ +///////////////////////// +void spcc ( int spc, BYTE NetID ) +{ + int i; + + for ( i = 0; i < RelatedSPCNum; i++ ) + { + if( spc == RelatedSSN[i].DPC && NetID == RelatedSSN[i].NetID ) + RelatedSSN[i].status = ST_Congest; + } +} + +///////////////////////// +/*SSAC Module----------> */ +///////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// Name : register_ssn +// Function : Enable local subsystem +// Parameter: ssn [upper layer ssn] +// usertype [upper layer user type [3 aif 4 ranap 5 reserved for future] ] +// Return : 0 Register Fail 1 Register Successful +////////////////////////////////////////////////////////////////////////// +int register_ssn ( BYTE ssn, BYTE usertype ) +{ + BYTE localindex = LocalSSN[ssn].local % 3; + + LocalSSN[ssn].RegFlag = 1; + if( localindex > 0 ) + { + CollectLocalInfo ( ); + LocalSSN[ssn].status[localindex - 1] = ST_Enable; + } + else + { + printf ( "Subsystem %d not equiped.check your GTT Table.\n", ssn ); + return 0; + } + + //modified to support more upper layers + if( usertype >= 3 && usertype <= SP_POOL_SIZE + 2 ) + { + //aif: SCCP_Param.CO_SSN[0] ranap: SCCP_Param.CO_SSN[1] + + SCCP_Param.CO_SSN[usertype - 3] = ssn; + spLogDebug ( SCCPDB_USER, "UL register SSN : %d success", ssn ); + } + + SccpCsta[SccpCstaInd].avail[8]++; + LocalSSN[ssn].nbuf = usertype % ( SP_POOL_SIZE + 3 ); + if( LocalSSN[ssn].nbuf >= 3 && LocalSSN[ssn].nbuf <= SP_POOL_SIZE + 2 ) + { + //aif: SCCP_Param.CO_SSN[0] ranap: SCCP_Param.CO_SSN[1] + + SCCP_Param.CO_SSN[usertype - 3] = ssn; + spLogDebug ( SCCPDB_USER, "UL register SSN : %d success", ssn ); + } + + bcst ( ssn, SSA_MSG ); + + return 1; +} + +void ssac ( int spc, BYTE ssn, BYTE NetID, BOOL relay ) //enable remote subsystem +{ + int i; + + for ( i = 0; i < RelatedSSNNum; i++ ) + { + if( RelatedSSN[i].status == 0 ) + continue; + if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID ) + continue; + + if( RelatedSSN[i].status == ST_Disable && relay ) //Disable->Enable + bcst_relay ( spc, ssn, SSA_MSG, NetID ); + RelatedSSN[i].SST = 0; + RelatedSSN[i].status = ST_Enable; + + } +} + +void sscc ( int spc, BYTE ssn, BYTE NetID ) //enable remote subsystem +{ + int i; + + for ( i = 0; i < RelatedSSNNum; i++ ) + { + if( RelatedSSN[i].status == 0 ) + continue; + if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID ) + continue; + + RelatedSSN[i].status = ST_Congest; + } +} + +///////////////////////// +/*SSPC Module----------> */ +///////////////////////// +int stop_ssn ( BYTE ssn ) //disable local subsystem +{ + BYTE localindex = LocalSSN[ssn].local % 3; + int i; + + LocalSSN[ssn].RegFlag = 0; + spLogDebug ( SCCPDB_SCMG, "Disable local subsystem. ssn=%d", ssn ); + + if( localindex > 0 ) + { + CollectLocalInfo ( ); + /* add by daniel on 2005-9-15 */ + for ( i = 0; i <= 1; i++ ) + { + if( SCCP_Param.OMCIP[i] > 0 ) + AddToIpList ( SCCP_Param.OMCIP[i], ssn ); + } + /* add by daniel on 2005-9-15 */ + LocalSSN[ssn].status[localindex - 1] = ST_Disable; + } + else + return -1; + + sccp_sethb ( ); + SccpCsta[SccpCstaInd].avail[9]++; + bcst ( ssn, SSP_MSG ); + return 1; +} + +void sspc ( int spc, BYTE ssn, BYTE NetID, BOOL relay ) //disable remote subsystem +{ + int i; + + for ( i = 0; i < RelatedSSNNum; i++ ) + { + if( RelatedSSN[i].status == 0 ) + continue; + if( RelatedSSN[i].DPC != spc || RelatedSSN[i].SSN != ssn || RelatedSSN[i].NetID != NetID ) + continue; + + if( RelatedSSN[i].status == ST_Enable ) //Enable->Disable + { + RelatedSSN[i].timeout = T_sst; + RelatedSSN[i].SST = 1; + if( relay ) + bcst_relay ( spc, ssn, SSP_MSG, NetID ); + } + + RelatedSSN[i].status = ST_Disable; + } +} + +///////////////////////// +/*SSTC Module----------> */ +///////////////////////// +void sst_timer ( ) +{ + Intra_Msg outmsg; + RL_SSN *pSSN; + int i; + + for ( i = 0; i < RelatedSSNNum; i++ ) + { + pSSN = &RelatedSSN[i]; + if( !pSSN->SST ) + continue; + if( pSSN->timeout-- > 0 ) + continue; + if( pSSN->DPC == SCCP_Param.spc[pSSN->NetID] ) + continue; + + outmsg.msgtype = UDT_MSG; + outmsg.msgsource = FROM_SCMG; + + outmsg.CGA.DPC = SCCP_Param.spc[pSSN->NetID]; + outmsg.CGA.SSN = 1; + outmsg.CGA.GTI = 0; + outmsg.CGA.RI = RI_SSN; + outmsg.CGA.len = 0; + + outmsg.CDA.DPC = pSSN->DPC; + outmsg.CDA.SSN = 1; //SCMG + outmsg.CDA.GTI = 0; //No GT + outmsg.CDA.RI = 1; + outmsg.CDA.len = 0; + + outmsg.NetID = pSSN->NetID; + + outmsg.CDA.ip = INADDR_NONE; + + outmsg.msglen = build_scmgmsg ( outmsg.data, SST_MSG, pSSN->DPC, pSSN->SSN, pSSN->NetID ); + spLogDebug ( SCCPDB_SCMG, "SST spc=%X,ssn=%d", pSSN->DPC, pSSN->SSN ); + send_msg ( &outmsg, mtp3_ansiFlag ( pSSN->NetID ) ); + pSSN->timeout = T_sst; + } +} + +///////////////////////// +/*LCST Module----------> */ +///////////////////////// + +void lcst ( int spc, BYTE ssn, BYTE ntype, BYTE NetID ) +{ + Intra_Msg outmsg; + int i; + + spLogDebug ( SCCPDB_SCMG, "Start Local Broatcast.spc=%X,ssn=%d,ntype=%d", spc, ssn, ntype ); + outmsg.msgtype = UDT_MSG; + outmsg.msgsource = FROM_SCMG; + outmsg.CGA.SSN = 1; + outmsg.CGA.GTI = 0; + outmsg.CGA.len = 0; + outmsg.CGA.RI = 1; + outmsg.CGA.DPC = SCCP_Param.spc[NetID]; + outmsg.CDA.GTI = 0; + outmsg.NetID = outmsg.CDA.NetID = outmsg.CGA.NetID = NetID; + + outmsg.CDA.DPC = SCCP_Param.spc[NetID]; + outmsg.CDA.SSN = 1; + outmsg.CDA.RI = 1; + outmsg.CDA.len = 0; + + outmsg.msglen = build_scmgmsg ( outmsg.data, ntype, spc, ssn, NetID ); + + for ( i = 2; i < 256; i++ ) + { + if( LocalSSN[i].status[0] > 0 && LocalSSN[i].local != 1 ) + { + outmsg.CDA.ip = LocalSSN[i].ip[0]; + send_msg ( &outmsg, mtp3_ansiFlag ( NetID ) ); + } + if( LocalSSN[i].status[1] > 0 && LocalSSN[i].local != 2 ) + { + outmsg.CDA.ip = LocalSSN[i].ip[1]; + send_msg ( &outmsg, mtp3_ansiFlag ( NetID ) ); + } + } +} + +///////////////////////// +/*BCST Module----------> */ +///////////////////////// +void bcst ( BYTE ssn, BYTE ntype ) +{ + Intra_Msg outmsg; + int i; + + spLogDebug ( SCCPDB_SCMG, "Start Remote Broadcase ssn=%d,ntype=%d", ssn, ntype ); + outmsg.msgtype = UDT_MSG; + outmsg.msgsource = FROM_SCMG; + outmsg.CDA.GTI = 0; + for ( i = 0; i < RelatedSPCNum; i++ ) + { + if( RelatedSPC[i].status != ST_Enable ) + continue; + outmsg.CGA.SSN = 1; + outmsg.CGA.GTI = 0; + outmsg.CGA.len = 0; + outmsg.CGA.RI = 1; + outmsg.CGA.DPC = SCCP_Param.spc[RelatedSPC[i].NetID]; + outmsg.CDA.ip = INADDR_NONE; + outmsg.CDA.DPC = RelatedSPC[i].DPC; + outmsg.CDA.SSN = 1; + outmsg.CDA.RI = 1; + outmsg.CDA.len = 0; + outmsg.NetID = outmsg.CDA.NetID = outmsg.CGA.NetID = RelatedSPC[i].NetID; + + outmsg.msglen = build_scmgmsg ( outmsg.data, ntype, SCCP_Param.spc[outmsg.NetID], ssn, outmsg.NetID ); + send_msg ( &outmsg, mtp3_ansiFlag ( outmsg.NetID ) ); + } +} + +void bcst_relay ( int spc, BYTE ssn, BYTE ntype, BYTE NetID ) +{ + Intra_Msg outmsg; + int i; + + spLogDebug ( SCCPDB_SCMG, "relay Broadcase spc:%X,ssn%d,ntype:%d", spc, ssn, ntype ); + outmsg.msgtype = UDT_MSG; + outmsg.msgsource = FROM_SCMG; + outmsg.CDA.GTI = 0; + outmsg.CGA.SSN = 1; + outmsg.CGA.GTI = 0; + outmsg.CGA.len = 0; + outmsg.CGA.RI = 1; + outmsg.NetID = outmsg.CGA.NetID = outmsg.CDA.NetID = NetID; + for ( i = 0; i < RelatedSPCNum; i++ ) + { + if( NetID != RelatedSPC[i].NetID ) + return; + if( RelatedSPC[i].status == ST_Disable || spc == RelatedSPC[i].DPC ) + continue; + + outmsg.CGA.DPC = SCCP_Param.spc[RelatedSPC[i].NetID]; + outmsg.CDA.ip = INADDR_NONE; + outmsg.CDA.DPC = RelatedSPC[i].DPC; + outmsg.CDA.SSN = 1; + outmsg.CDA.RI = 1; + outmsg.CDA.len = 0; + + outmsg.msglen = build_scmgmsg ( outmsg.data, ntype, spc, ssn, NetID ); + send_msg ( &outmsg, mtp3_ansiFlag ( NetID ) ); + } +} + +int build_scmgmsg ( BYTE * data, BYTE type, int spc, BYTE ssn, BYTE NetID ) +{ + int pos = 0; + + data[pos++] = type; + data[pos++] = ssn; + memcpy ( data + pos, ( BYTE * ) & spc, SCCP_Param.spclen[NetID] ); + pos += SCCP_Param.spclen[NetID]; + data[pos++] = 0; + if( type == SSC_MSG ) + data[pos++] = 0; + return pos; +} + +int parse_scmgmsg ( BYTE * data, BYTE * type, int *spc, BYTE * ssn, BYTE NetID ) +{ + int pos = 0; + + *type = data[pos++]; + *ssn = data[pos++]; + *spc = 0; + memcpy ( ( BYTE * ) spc, data + pos, SCCP_Param.spclen[NetID] ); + pos += SCCP_Param.spclen[NetID]; + return 1; +} diff --git a/plat/sccp/src/scoc.c b/plat/sccp/src/scoc.c new file mode 100644 index 0000000..78e564f --- /dev/null +++ b/plat/sccp/src/scoc.c @@ -0,0 +1,126 @@ + +/********************************************************************/ +/*Title: scoc.c */ +/*Descr: SCCP Connection-Oriented Control */ +/*Author: Liang Hanxi */ +/*Create: 2002-2-19 */ +/*Modify: 2003-5-9 */ + +/********************************************************************/ +#include "./include/sccp.h" + +/*===========import================*/ +extern int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); +extern int build_msg ( BYTE * buf, Intra_Msg * intramsg, BYTE NetID, BYTE ansi_flag ); //sccpmsg.c +extern int parse_msg ( BYTE * buf, Intra_Msg * intramsg, int len, BYTE NetID, BYTE ansi_flag ); //sccpmsg.c + +/*===========export================*/ +int scrc2scoc ( Intra_Msg * intramsg, BYTE AnsiFlag ); +int scoc_store ( up_message * sccpmsg ); + +/* +int scrc2scoc ( Intra_Msg * intramsg, BYTE AnsiFlag ) +{ + up_message mtp3msg; + + mtp3msg.len = build_msg ( mtp3msg.msgList, intramsg, intramsg->NetID, AnsiFlag ); + mtp3msg.dest_ip = intramsg->CDA.ip; + mtp3msg.dpc = intramsg->DPC; + mtp3msg.opc = intramsg->OPC; + mtp3msg.sio = intramsg->NetID * 0x40 + 3; + mtp3msg.cic[0] = intramsg->SLS; + mtp3msg.link = intramsg->link; + + scoc_store ( &mtp3msg ); + return 1; +} +*/ +/* + int scoc_store ( up_message * sccpmsg ) + { + up_message *pmsg; + + SccpCsta[SccpCstaInd].utilization[4 - 3]++; + spLogDebug ( SCCPDB_AIF, "MSC <== SCCP: CO Message. opc=%x,sio=%02x", sccpmsg->opc, sccpmsg->sio ); + spShowBCD ( SCCPDB_AIF, ( BYTE * ) sccpmsg, ( sccpmsg->len + 17 ) % 256 ); + + pmsg = &ScocBuf.msgin[ScocBuf.rcvsub[0]]; + memcpy ( pmsg, sccpmsg, sizeof ( up_message ) ); + + ScocBuf.rcvsub[0] = ( ScocBuf.rcvsub[0] + 1 ) % SS_MSG_NUM; + if( ScocBuf.rcvsub[0] == ScocBuf.rcvsub[1] ) + ScocBuf.rcvsub[1] = ( ScocBuf.rcvsub[1] + 1 ) % SS_MSG_NUM; + + sccpmsg_st.msg_mtp_scoc++; + return 1; + } + */ + +/******************************************************************/ + +/*================== User Interface-----> ================*/ + +/******************************************************************/ +/* + int scoc_send ( up_message * pmsg ) + { + BYTE ntype; + BOOL ForceAnsi = 0; + + ntype = pmsg->msgList[0]; + + spLogDebug ( SCCPDB_AIF, "MSC ==> SCCP: CO/UDT Message. opc=%x,sio=%02x,type=%d", pmsg->opc, pmsg->sio, ntype ); + spShowBCD ( SCCPDB_AIF, ( BYTE * ) pmsg, ( pmsg->len + 17 ) % 256 ); + SccpCsta[SccpCstaInd].utilization[0]++; + switch ( ntype ) + { + case CR_MSG: + SccpCsta[SccpCstaInd].quality[4]++; + break; + case CC_MSG: + break; + case DT1_MSG: + SccpCsta[SccpCstaInd].utilization[10 - 3]++; + break; + case DT2_MSG: + SccpCsta[SccpCstaInd].utilization[12 - 3]++; + break; + } + if( ntype == CR_MSG || ntype == UDT_MSG ) + { + Intra_Msg outmsg; + BYTE NetID = pmsg->sio / 0x40; + + memset ( &outmsg, 0, sizeof ( Intra_Msg ) ); + + ForceAnsi = ( pmsg->sio >> 4 ) & 1; + parse_msg ( pmsg->msgList, &outmsg, pmsg->len, NetID, ForceAnsi ); + + outmsg.CDA.ip = INADDR_NONE; + outmsg.OPC = pmsg->opc; + outmsg.DPC = pmsg->dpc; + outmsg.SLS = pmsg->cic[0]; + + outmsg.NetID = outmsg.CGA.NetID = outmsg.CDA.NetID = NetID; + return scrc_route ( &outmsg, ForceAnsi ); + } + else + { + return sccp_to_mtp3 ( pmsg ); + } + + } + + int scoc_receive ( up_message * sccpmsg ) + { + up_message *pmsg; + + if( ScocBuf.rcvsub[0] == ScocBuf.rcvsub[1] ) + return 0; + pmsg = &ScocBuf.msgin[ScocBuf.rcvsub[1]]; + memcpy ( sccpmsg, pmsg, sizeof ( up_message ) ); + ScocBuf.rcvsub[1] = ( ScocBuf.rcvsub[1] + 1 ) % SS_MSG_NUM; + sccpmsg_st.msg_scoc_up++; + return 1; + } + */ diff --git a/plat/sccp/src/scoc_fsm.c b/plat/sccp/src/scoc_fsm.c new file mode 100644 index 0000000..07e94b2 --- /dev/null +++ b/plat/sccp/src/scoc_fsm.c @@ -0,0 +1,1109 @@ +////////////////////////////////////////////////// +//Title : scoc_fsm.c +//Auhtor : Liu Wei +//Desc : SCOC fsm implementation +//Created : 2007-04-22 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/sccp_pub.h" +#include "./include/sccp_func.h" + +/////////////////////////////////////////////////////////////////////////// +// SCOC special State Machine +/////////////////////////////////////////////////////////////////////////// + +extern void spLogStateError ( u16 wConnId, u8 uErrCode ); + +void coFsmDiscard ( u16 wConnId ) +{ + spLogStateError ( wConnId, ERR_FSM_DISCARD ); +} + +void coFsmError ( u16 wConnId ) +{ + spLogStateError ( wConnId, ERR_FSM_ERROR ); +} + +void coFsmFatal ( u16 wConnId ) +{ + spLogStateError ( wConnId, ERR_FSM_FATAL ); +} + +void coFsmReserved ( u16 wConnId ) +{ + spLogStateError ( wConnId, ERR_FSM_RESERVED ); +} + +/////////////////////////////////////////////////////////////////////////// +// SCOC State Machine declare --Q.714 Page 85 - Page 127 +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// SCOC State Machine implementation --Q.714 Page 85 - Page 127 +/////////////////////////////////////////////////////////////////////////// + +void _Below_fsm_is_supported_ ( ) +{ + +} + +/////////////////////////////////////////////////////////////////////////// +// origination node connection establishment procedures +// -- IDLE State +/////////////////////////////////////////////////////////////////////////// + +void coOCEP_IDLE ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case N_CONNECT_REQ: + if( !coNewCS ( wConnId, &pCS->tCDA ) ) + { + //have check resource in coNewConnId + goto Err_Resource_Limited; + } + pCS->tmSCOC.tmConnEst = 1; + co2cr ( wConnId, SP_MSG_CR ); + pCS->uCState = CO_STATUS_CPOG; + return; + case N_CONNECT_T1: + //not supported now for ISUP +// WxcAssert ( 0, "coOCEP_IDLE unexpected event, not supported now" ); + if( !coNewCS ( wConnId, &pCS->tCDA ) ) + { + goto Err_Resource_Limited; + } + co2ul ( wConnId, RELAY ); + pCS->tmSCOC.tmConnEst = 1; + pCS->uCState = CO_STATUS_CPOG; + return; + case R_RLSD: + //have handled in cr2co + //co2cr ( wConnId, SP_MSG_RLC ); + //pCS->uCState = CO_STATUS_INIT; +// WxcAssert ( 0, "coOCEP_IDLE unexpected event" ); + return; + case R_RLC: + case R_IT: + //have handled in cr2co + //pCS->uCState = CO_STATUS_INIT; +// WxcAssert ( 0, "coOCEP_IDLE unexpected event" ); + return; + default: + //have handled in cr2co + //if( coGetConnId ( pCS->aSLR ) < 0 ) + //{ + // co2cr ( wConnId, SP_MSG_ERR ); + //} + //pCS->uCState = CO_STATUS_INIT; +// WxcAssert ( 0, "coOCEP_IDLE unexpected event" ); + return; + } + Err_Resource_Limited: + { + pCS->eREA = REA_PDISC_ACNN; + co2ul ( wConnId, N_DISCONNECT_IND ); + pCS->uCState = CO_STATUS_INIT; + pSp->tCo.wConnIdCount--; + } + return; +} + +/////////////////////////////////////////////////////////////////////////// +// origination node connection establishment procedures +// -- Connection pending outgoing state +/////////////////////////////////////////////////////////////////////////// + +void coOCEP_CPOG ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case N_DISCONNECT_REQ: + pCS->uCState = CO_STATUS_WTCC; + return; + case T_CONNEST_OUT: + goto Release_Resource_1; + case R_RF: + goto Release_Resource_0; + case R_RLSD: + co2cr ( wConnId, SP_MSG_RLC ); + goto Release_Resource_0; + case R_CC: + pCS->tmSCOC.tmConnEst = 0; + pCS->tmSCOC.tmIas = 1; + pCS->tmSCOC.tmIar = 1; + //class credit dlr fill in coFillCS + + co2ul ( wConnId, N_CONNECT_CFM ); + pCS->uCState = CO_STATUS_ACTV; + return; + case R_CREF: + pCS->tmSCOC.tmConnEst = 0; + goto Release_Resource_1; + default: + goto Release_Resource_0; + } + Release_Resource_0: + { + pCS->tmSCOC.tmConnEst = 0; + } + Release_Resource_1: + //freeze local reference P86 + { + co2ul ( wConnId, N_DISCONNECT_IND ); + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + } + + return; +} + +/////////////////////////////////////////////////////////////////////////// +// origination node connection establishment procedures +// -- Wait Connection confirm state +/////////////////////////////////////////////////////////////////////////// + +void coOCEP_WTCC ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case R_RLSD: + co2cr ( wConnId, SP_MSG_RLC ); + goto Early_Release; + case R_CC: + pCS->tmSCOC.tmConnEst = 0; + //dlr fill in coFillCS + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmRel = 1; + pCS->uCState = CO_STATUS_DSCP; + return; + case R_CREF: + case R_RF: + goto Early_Release; + case T_CONNEST_OUT: + //freeze local reference P87 + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + default: + //freeze local reference P87 + goto Early_Release; + } + Early_Release: + { + pCS->tmSCOC.tmConnEst = 0; + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + } + return; +} + +/////////////////////////////////////////////////////////////////////////// +// origination node connection release procedures +// -- active state +/////////////////////////////////////////////////////////////////////////// + +void coOCRP_ACTV ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case I_DISCONNECT: + goto Disconnect_Pending_0; + case N_DISCONNECT_REQ: + goto Disconnect_Pending_1; + case R_CC: + case R_CREF: + case R_RLC: + return; + case R_RLSD: + co2ul ( wConnId, N_DISCONNECT_IND ); + //Freeze local reference P89 + pCS->tmSCOC.tmIar = 0; + co2cr ( wConnId, SP_MSG_RLC ); + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + case R_ERR: + if( pCS->uClass == 2 ) + { + goto Disconnect_Pending_0; + } + //Freeze local reference P89 + + co2ul ( wConnId, N_DISCONNECT_IND ); + pCS->tmSCOC.tmIar = 0; + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + case T_IAR_OUT: + goto Disconnect_Pending_1; + case R_RF: + co2ul ( wConnId, N_DISCONNECT_IND ); + pCS->tmSCOC.tmIar = 0; + pCS->tmSCOC.tmRel = 1; + pCS->uCState = CO_STATUS_DSCP; + return; + default: + return; + } + Disconnect_Pending_0: + { + co2ul ( wConnId, N_DISCONNECT_IND ); + } + Disconnect_Pending_1: + { + pCS->tmSCOC.tmIar = 0; + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmRel = 1; + pCS->uCState = CO_STATUS_DSCP; + } + return; +} + +/////////////////////////////////////////////////////////////////////////// +// origination node connection release procedures +// -- disconnection pending state +/////////////////////////////////////////////////////////////////////////// + +void coOCRP_DSCP ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case R_RLC: + case R_RLS_ERR: + goto Release; + case R_RF: + return; + case T_RLS_OUT: + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmInternal = 1; + pCS->tmSCOC.tmRepeatRel = 1; + return; + case T_INTERNAL_OUT: + //unsupported now + co2scmg ( ); + goto Release; + case T_REPEATE_RLS_OUT: + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmRepeatRel = 1; + return; + case R_RLSD: + pCS->tmSCOC.tmIar = 0; + co2cr ( wConnId, SP_MSG_RLC ); + return; + default: + //discard message + return; + } + Release: + { + //Freeze local reference P90 + pCS->tmSCOC.tmRel = 0; + pCS->tmSCOC.tmInternal = 0; + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + } + return; + +} + +/////////////////////////////////////////////////////////////////////////// +// distination node connection establishment procedures +// -- idle state +/////////////////////////////////////////////////////////////////////////// + +void coDCEP_IDLE ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case R_CR: + if( !coCheckResource ( ) ) + { + goto Refuse_Connection; + } + goto Connecting; + case R_RF: + goto Refuse_Connection; + case R_CR2: + //not supported now +// WxcAssert ( 0, "coDCEP_IDLE unexpected event, not supported now" ); + //if( set CREF ind ) + if( 1 ) + { + goto Refuse_Connection; + } + if( coCheckResource ( ) ) + { + goto Connecting; + } + co2ul ( wConnId, N_DISCONNECT_IND ); + goto Refuse_Connection; + case R_RLSD: + //have handled in cr2co + //co2cr ( wConnId, SP_MSG_RLSD ); + pSp->tCo.wConnIdCount--; + pCS->uCState = CO_STATUS_INIT; + // WxcAssert ( 0, "coDCEP_IDLE unexpected event" ); + return; + case R_RLC: + case R_IT: + //have handled in cr2co + pSp->tCo.wConnIdCount--; + pCS->uCState = CO_STATUS_INIT; + // WxcAssert ( 0, "coDCEP_IDLE unexpected event" ); + return; + default: + //have handled in cr2co +// WxcAssert ( 0, "coDCEP_IDLE unexpected event" ); + //if( coGetConnId ( pCS->aSLR ) < 0 ) + //{ + // co2cr ( wConnId, SP_MSG_ERR ); + //} + pSp->tCo.wConnIdCount--; + pCS->uCState = CO_STATUS_INIT; + return; + + } + Refuse_Connection: + { + pCS->eREA = REA_PDISC_ACNN; + co2cr ( wConnId, SP_MSG_CREF ); + pCS->uCState = CO_STATUS_INIT; + pSp->tCo.wConnIdCount--; + return; + } + Connecting: + { + coNewCS ( wConnId, &pCS->tCDA ); + co2ul ( wConnId, N_CONNECT_IND ); + pCS->uCState = CO_STATUS_CPIC; + pCS->tmSCOC.tmConnEst = 1; + } + return; +} + +/////////////////////////////////////////////////////////////////////////// +// destination node connection establishment procedures +// -- connection pending incoming state +/////////////////////////////////////////////////////////////////////////// + +void coDCEP_CPIC ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case N_CONNECT_RSP: + //coNewCS ( wConnId , &pCS->tCDA ); + co2cr ( wConnId, SP_MSG_CC ); + pCS->tmSCOC.tmIas = 1; + pCS->tmSCOC.tmIar = 1; + pCS->uCState = CO_STATUS_ACTV; + pCS->tmSCOC.tmConnEst = 0; + return; + case N_DISCONNECT_REQ: + //P93 + co2cr ( wConnId, SP_MSG_CREF ); + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + case T_CONNEST_OUT: + //freeze local reference P87 + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + default: + //discard message + return; + } + +} + +/////////////////////////////////////////////////////////////////////////// +// distination node connection release procedures +// -- active state +/////////////////////////////////////////////////////////////////////////// + +void coDCRP_ACTV ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case N_DISCONNECT_REQ: + goto Disconnect_1; + case I_DISCONNECT: + goto Disconnect_0; + case R_CC: + case R_CREF: + case R_RLC: + return; + case R_RLSD: + co2ul ( wConnId, N_DISCONNECT_IND ); + pCS->tmSCOC.tmIar = 0; + co2cr ( wConnId, SP_MSG_RLC ); + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + case R_ERR: + if( pCS->uClass == 2 ) + { + goto Disconnect_0; + } + co2ul ( wConnId, N_DISCONNECT_IND ); + pCS->tmSCOC.tmIar = 0; + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + case R_RF: + goto Disconnect_0; + case T_IAR_OUT: + co2ul ( wConnId, N_DISCONNECT_IND ); + pCS->tmSCOC.tmIar = 0; + pCS->tmSCOC.tmRel = 1; + pCS->uCState = CO_STATUS_DSCP; + return; + default: + return; + } + Disconnect_0: + { + co2ul ( wConnId, N_DISCONNECT_IND ); + } + Disconnect_1: + { + pCS->tmSCOC.tmIar = 0; + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmRel = 1; + pCS->uCState = CO_STATUS_DSCP; + } + + return; +} + +/////////////////////////////////////////////////////////////////////////// +// distination node connection release procedures +// -- disconnect pending state +/////////////////////////////////////////////////////////////////////////// + +void coDCRP_DSCP ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case R_RLC: + case R_ERR: + pCS->tmSCOC.tmRel= 0; + pCS->tmSCOC.tmInternal = 0; + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + case R_RF: + return; + case T_INTERNAL_OUT: + //notify management + //inform maintaenance + co2scmg ( ); + + pCS->tmSCOC.tmRel = 0; + pCS->tmSCOC.tmInternal= 0; + coFreeCS ( wConnId ); + pCS->uCState = CO_STATUS_INIT; + return; + case T_RLS_OUT: + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmRepeatRel = 1; + pCS->tmSCOC.tmInternal = 1; + return; + case T_REPEATE_RLS_OUT: + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmRepeatRel = 1; + return; + case R_RLSD: + pCS->tmSCOC.tmIar = 0; + co2cr ( wConnId, SP_MSG_RLC ); + return; + default: + //discare message + return; + } + +} + +/////////////////////////////////////////////////////////////////////////// +// origination and distination node data transfer procedures +// -- active state +/////////////////////////////////////////////////////////////////////////// + +void coODDT_ACTV ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + switch ( pCS->uPri ) + { + case N_DATA_REQ: + co2cr ( wConnId, SP_MSG_DT1 ); + pCS->tmSCOC.tmIas = 1; + return; + case R_DT1: + pCS->tmSCOC.tmIar = 1; + co2ul ( wConnId, N_DATA_IND ); + return; + case R_DT2: +// WxcAssert ( 0, "coODDT_ACTV unsupport R_DT2 now" ); + //do not supported now + return; + case R_AK: +// WxcAssert ( 0, "coODDT_ACTV unsupport R_AK now" ); + //do not supported now + return; + case T_IAS_OUT: + co2cr ( wConnId, SP_MSG_IT ); + pCS->tmSCOC.tmIas = 1; + return; + case R_IT: + //P101 + if( !( pCS->uClass < 3 && coGetConnId ( pCS->aSLR ) >= 0 ) ) + { + co2ul ( wConnId, N_DISCONNECT_IND ); + pCS->tmSCOC.tmIar = 0; + co2cr ( wConnId, SP_MSG_RLSD ); + pCS->tmSCOC.tmRel = 1; + pCS->uCState = CO_STATUS_DSCP; + return; + } + else if( pCS->uClass == 2 ) + { + pCS->tmSCOC.tmIar = 1; + } + else if( spCheckAudit ( ) ) + { + pCS->tmSCOC.tmIar = 1; + } + else + { + co2co ( wConnId, I_RESET_REQ ); + } + return; + case I_CONGESTED: + case I_UNCONGESTED: +// WxcAssert ( 0, "coODDT_ACTV unsupport I_CONGESTED/I_UNCONGESTED now" ); + //do not supported now + return; + default: +// WxcAssert ( 0, "coODDT_ACTV unexpected primitive now" ); + return; + } + +} + +static void coODED_ACTV ( u16 wConnId ); +static void coODRS_ACTV ( u16 wConnId ); + +/////////////////////////////////////////////////////////////////////////// +// Active FSM on origination , distination and intermedia node +// -- include establishment, data transfer , release procedures +/////////////////////////////////////////////////////////////////////////// + +void coODMP_ACTV ( u16 wConnId ) +{ + CO_ConnSection *pCS; + + pCS = &pSp->tCo.tCSInst[wConnId]; + switch ( pCS->uPri ) + { + case N_DISCONNECT_REQ: //User->SCOC : N-DISCONNECT Request + case I_DISCONNECT: //internal disconnect + case R_CREF: //SCRC->SCOC Connection refused + case R_CC: //SCRC->SCOC Connection confirm + case R_RLC: //SCRC->SCOC Release complete + case R_RLSD: //SCRC->SCOC Released + case R_ERR: //SCRC->SCOC Error + case T_IAR_OUT: //Recieve inactivity timer expires + case R_RF: //Routing Fail + switch ( pCS->uSide ) + { + case CO_INST_SIDE_ORG: + coOCRP_ACTV ( wConnId ); + return; + case CO_INST_SIDE_DST: + coDCRP_ACTV ( wConnId ); + return; + //case CO_INST_SDIE_MID: //do not supported middle node side now + default: + coFsmReserved ( wConnId ); + return; + } + case N_DATA_REQ: //User->SCOC : N-Data Request + case R_DT1: //SCRC->SCOC DT1 + case R_DT2: //SCRC->SCOC DT2 + case R_AK: //SCRC->SCOC Data acknowledg + case T_IAS_OUT: //Send inactivity timer expires + case R_IT: //SCRC->SCOC IT + case I_CONGESTED: //Congested + case I_UNCONGESTED: //Uncongested + switch ( pCS->uSide ) + { + case CO_INST_SIDE_ORG: + case CO_INST_SIDE_DST: + coODDT_ACTV ( wConnId ); + return; + //case CO_INST_SDIE_MID: //do not supported middle node side now + default: + coFsmReserved ( wConnId ); + return; + } + case N_EDATA_REQ: //User->SCOC : N-Data Request + case R_EA: //SCRC->SCOC EData acknowledg + case R_ED: //SCRC->SCOC ED + switch ( pCS->uSide ) + { + case CO_INST_SIDE_ORG: + case CO_INST_SIDE_DST: + coODED_ACTV ( wConnId ); + return; + //case CO_INST_SDIE_MID: //do not supported middle node side now + default: + coFsmReserved ( wConnId ); + return; + } + + case N_RESET_REQ: //User->SCOC : N-Reset Request + case I_RESET_REQ: //SCRC->SCOC Reset Request + case R_RSC: //SCRC->SCOC Reset confirm + case R_RSR: //internal reset Request + switch ( pCS->uSide ) + { + case CO_INST_SIDE_ORG: + case CO_INST_SIDE_DST: + coODRS_ACTV ( wConnId ); + return; + //case CO_INST_SDIE_MID: //do not supported middle node side now + default: + coFsmReserved ( wConnId ); + return; + } + //coODRS_ACTV ( wConnId ); + default: + coFsmDiscard ( wConnId ); + return; + } + +} + +void _Above_fsm_is_supported_ ( ) +{ + +} + +void _Below_fsm_is_Unsupported_ ( ) +{ + +} + +/////////////////////////////////////////////////////////////////////////// +// The Fsm below is not supporte now(SCCP R9.0.0) +/////////////////////////////////////////////////////////////////////////// + +void coODED_ACTV ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coODED_WSEA ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coODRS_ACTV ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coODRS_RSIC ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coODRS_RSOG ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coODRS_RSBH ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMCEP_ACTV ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMCEP_CONP ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMCRP_ACTV ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMCRP_DPOG ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMCRP_DPIC ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMCRP_DPBH ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMDTP_ACTV ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMEDP_ACTV ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMEDP_WSEA ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMRSP_ACTV ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMRSP_RSOG ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMRSP_RSIC ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coMRSP_RSBH ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coODMP_RSTA ( u16 wConnId ) +{ + coFsmReserved ( wConnId ); + return; +} + +void _Above_fsm_is_Unsupported_ ( ) +{ + +} + +/////////////////////////////////////////////////////////////////////////// +// SCOC State Machine Matricies +/////////////////////////////////////////////////////////////////////////// + +typedef void ( *coFsmFunc ) ( u16 wConnId ); + +#define CO_NODE_STYLE_MAX 3 //node type : origination,destination,intermediate + +static const coFsmFunc coFsmFuncSuit[][CO_STATUS_MAX + 1] = { + { //origination node stat machine + coFsmDiscard, //CO_STATUS_INIT : Transtion initialed + coOCEP_IDLE, //CO_STATUS_IDLE : status Idle + coOCEP_WTCC, //CO_STATUS_WTCC : Wait Connection confirm + coODMP_ACTV, //CO_STATUS_ACTV : Active + coFsmError, //CO_STATUS_CONP : Connection pending + coFsmError, //CO_STATUS_CPIC : Connection pending incoming + coOCEP_CPOG, //CO_STATUS_CPOG : Connection pending outgoing + coOCRP_DSCP, //CO_STATUS_DSCP : Disconnect pending + coFsmError, //CO_STATUS_DPIC : Disconnect pending incoming + coFsmError, //CO_STATUS_DPOG : Disconnect pending outgoing + coFsmError, //CO_STATUS_DPBH : Disconnect pending both + coFsmError, //CO_STATUS_NMOP : Normal operation + coODED_WSEA, //CO_STATUS_WSEA : Wait for sending EA Message + coODRS_RSOG, //CO_STATUS_RSIC : Reset outgoing + coODRS_RSIC, //CO_STATUS_RSOG : Reset incoming + coODRS_RSBH, //CO_STATUS_RSBH : Reset both + coFsmError, //CO_STATUS_MTBK : Maintenance blocking + coODMP_RSTA, //CO_STATUS_RSTA : Restart + coFsmFatal, //CO_STATUS_MAX + }, + { //destination node stat machine + coFsmDiscard, //CO_STATUS_INIT : Transtion initialed + coDCEP_IDLE, //CO_STATUS_IDLE : status Idle + coFsmError, //CO_STATUS_WTCC : Wait Connection confirm + coODMP_ACTV, //CO_STATUS_ACTV : Active + coFsmError, //CO_STATUS_CONP : Connection pending + coDCEP_CPIC, //CO_STATUS_CPIC : Connection pending incoming + coFsmError, //CO_STATUS_CPOG : Connection pending outgoing + coDCRP_DSCP, //CO_STATUS_DSCP : Disconnect pending + coFsmError, //CO_STATUS_DPIC : Disconnect pending incoming + coFsmError, //CO_STATUS_DPOG : Disconnect pending outgoing + coFsmError, //CO_STATUS_DPBH : Disconnect pending both + coFsmError, //CO_STATUS_NMOP : Normal operation + coODED_WSEA, //CO_STATUS_WSEA : Wait for sending EA Message + coODRS_RSOG, //CO_STATUS_RSIC : Reset outgoing + coODRS_RSIC, //CO_STATUS_RSOG : Reset incoming + coODRS_RSBH, //CO_STATUS_RSBH : Reset both + coFsmError, //CO_STATUS_MTBK : Maintenance blocking + coODMP_RSTA, //CO_STATUS_RSTA : Restart + coFsmFatal, //CO_STATUS_MAX + }, + { //intermedia node stat machine + coFsmDiscard, //CO_STATUS_INIT : Transtion initialed + coFsmError, //CO_STATUS_IDLE : status Idle + coFsmError, //CO_STATUS_WTCC : Wait Connection confirm + coODMP_ACTV, //CO_STATUS_ACTV : Active + coMCEP_CONP, //CO_STATUS_CONP : Connection pending + coFsmError, //CO_STATUS_CPIC : Connection pending incoming + coFsmError, //CO_STATUS_CPOG : Connection pending outgoing + coFsmError, //CO_STATUS_DSCP : Disconnect pending + coFsmError, //CO_STATUS_DPIC : Disconnect pending incoming + //coMCEP_DPIC, //CO_STATUS_DPIC : Disconnect pending incoming + coFsmError, //CO_STATUS_DPOG : Disconnect pending outgoing + //coMCEP_DPOG, //CO_STATUS_DPOG : Disconnect pending outgoing + coFsmError, //CO_STATUS_DPBH : Disconnect pending both + //coMCEP_DPBH, //CO_STATUS_DPBH : Disconnect pending both + coFsmError, //CO_STATUS_NMOP : Normal operation + coMEDP_WSEA, //CO_STATUS_WSEA : Wait for sending EA Message + coMRSP_RSOG, //CO_STATUS_RSIC : Reset outgoing + coMRSP_RSIC, //CO_STATUS_RSOG : Reset incoming + coMRSP_RSBH, //CO_STATUS_RSBH : Reset both + coFsmError, //CO_STATUS_MTBK : Maintenance blocking + coODMP_RSTA, //CO_STATUS_RSTA : Restart + coFsmFatal, //CO_STATUS_MAX + }, +}; + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// +int coCheckStatus( u32 wConnId) +{ + int stat = pSp->tCo.tCSInst[wConnId].uCState; + +// WxcAssert(stat < CO_STATUS_MAX, "SCOC Fatal error, unexpected status"); + if(stat >= CO_STATUS_MAX) + spShowErr(1, "SCOC Fatal error, unexpected status"); + return (stat < CO_STATUS_MAX); +} + +void coFsm ( ) +{ +// u8 nLoop; + u16 wConnId; + SP_PriPoolEle tPri; + CO_ConnSection *pCS; + +// for ( nLoop = 0; nLoop < 16; nLoop++ ) + while ( spPoolGet ( &tPri, pInCoPool ) ) + { +// if( !spPoolGet ( &tPri, pInCoPool ) ) +// { +// break; +// } + + coFillCS ( &tPri ); + + pCS = &pSp->tCo.tCSInst[tPri.tCrPri.wConnId]; + + if( CO_STATUS_INIT == pCS->uCState || + !coCheckCS ( tPri.tCrPri.wConnId, pCS->uCState, pCS->uSide ) ) + { + continue; + } + + if( pCS->uPri ) + { + if ( coCheckStatus(tPri.tCrPri.wConnId) ) + ( *coFsmFuncSuit[pCS->uSide][pCS->uCState] ) ( tPri.tCrPri.wConnId ); + else{ + coFreeCS(tPri.tCrPri.wConnId); + } + } + pCS->uPri = 0; + } + + for ( wConnId = 0; wConnId < CO_CS_MPORT; wConnId++ ) + { + pCS = &pSp->tCo.tCSInst[wConnId]; + + if( CO_STATUS_INIT == pCS->uCState || !coCheckCS ( wConnId, pCS->uCState, pCS->uSide ) ) + { + continue; + } + + if( pCS->uPri ) + { + if ( coCheckStatus(tPri.tCrPri.wConnId) ) + ( *coFsmFuncSuit[pCS->uSide][pCS->uCState] ) ( wConnId ); + else{ + coFreeCS(tPri.tCrPri.wConnId); + } + } + pCS->uPri = 0; + } + + ///////////////////////Below is used for test//////////////////////// +/* register_ssn ( 142, 4 ); + int i; + SP_UiPriPara tmp; + for ( i = 3; i < 5; i++ ) + { + while ( SpSubmit ( &tmp, i ) ) + { + printf ( "uUiPri: %d\n", tmp.uUiPri); + printf ( "uAnsiFlag: 0x%X\n", tmp.uAnsiFlag); + printf ( "wConnId: %d\n", tmp.wConnId); + printf ( "NetID : %d RI : %d SSN : %d\n", tmp.tPriUnion.tPriNConnInd.tCDA.NetID + , tmp.tPriUnion.tPriNConnInd.tCDA.RI, tmp.tPriUnion.tPriNConnInd.tCDA.SSN ); + printf ( "PriNConnectInd: 0x%X\n", tmp.tPriUnion.tPriNConnInd); + } + }*/ +} diff --git a/plat/sccp/src/scoc_func.c b/plat/sccp/src/scoc_func.c new file mode 100644 index 0000000..10c893a --- /dev/null +++ b/plat/sccp/src/scoc_func.c @@ -0,0 +1,974 @@ +////////////////////////////////////////////////// +//Title : scoc_if.c +//Auhtor : Liu Wei +//Desc : SCOC interface implementation +//Created : 2007-05-07 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/sccp_pub.h" +#include "./include/scoc_if.h" +#include "./include/sccp_func.h" + +// fix multiple definition==================================== +SP_Entity tSpEntity; +SP_Entity *pSp; +// + +void spWatchDogStatic ( u8 uDebugStaticMask ); + +void coInit ( u32 sysID, u32 localIP, u32 alterIP ) +{ + pSp = &tSpEntity; + + memset ( pSp, 0, sizeof ( SP_Entity ) ); + spPoolInit ( ); + pSp->dLocalIP = localIP; + pSp->dAlterIP = alterIP; + pSp->dSysID = sysID + 1; +} + +void cr2coFailHandle ( Intra_Msg * pIntraMsg, u8 uAnsiFlag, u8 uMsgtype ) +{ + Intra_Msg tCo2CrMsg; + + memset ( &tCo2CrMsg, 0, sizeof ( Intra_Msg ) ); + switch ( uMsgtype ) + { + case SP_MSG_RLSD: + pIntraMsg->cause = REA_PCREF_IS; + case SP_MSG_RLC: + memcpy ( &tCo2CrMsg.aDLR, &pIntraMsg->aSLR, SP_REF_LEN ); + memcpy ( &tCo2CrMsg.aSLR, &pIntraMsg->aDLR, SP_REF_LEN ); + break; + case SP_MSG_ERR: + tCo2CrMsg.cause = REA_PDISC_IS; + break; + case SP_MSG_CREF: + tCo2CrMsg.cause = REA_PCREF_LE; + break; + default: +// WxcAssert ( 0, "cr2coFailHandle internal error" ); + break; + } + + tCo2CrMsg.msgsource = FROM_SCOC; + tCo2CrMsg.msgtype = uMsgtype; + tCo2CrMsg.msgclass = pIntraMsg->msgclass; + tCo2CrMsg.NetID = pIntraMsg->CDA.NetID; + tCo2CrMsg.OPC = SCCP_Param.spc[tCo2CrMsg.NetID]; + + //scrc_route ( &tCo2CrMsg, uAnsiFlag ); + + tCo2CrMsg.CDA.DPC = tCo2CrMsg.DPC = pIntraMsg->OPC; + + tCo2CrMsg.SLS = pIntraMsg->SLS; + tCo2CrMsg.CDA.ip = 0xffffffff; + send_msg ( &tCo2CrMsg, uAnsiFlag); + spWatchDogStatic ( CO_TO_CR ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int cr2co ( Intra_Msg * pIntraMsg, u8 uAnsiFlag ) +{ + int nRet; + u8 *pStr; + SP_PriPoolEle pPri; + + spWatchDogStatic ( CR_TO_CO_APT ); + +// WxcAssert ( pIntraMsg->msgtype < SP_MSG_MAX, "SCCP cr2co unexpected msgtype" ); + if(pIntraMsg->msgtype >= SP_MSG_MAX) + spShowErr(1, "SCCP cr2co unexpected msgtype" ); + + spGetMsgStr ( pIntraMsg->msgtype, pStr ); + + switch ( pIntraMsg->msgtype ) + { + case SP_MSG_CR: +// if( ( coGetConnId ( pIntraMsg->aSLR ) >= 0 ) || ( ( nRet = coNewConnId ( R_CR ) ) < 0 ) ) + if( (nRet = coNewConnId ( R_CR )) < 0 ) + { + spLogDebug ( SCCPDB_ERR, "[cr2co]No resourece for %s", pStr ); + cr2coFailHandle ( pIntraMsg, uAnsiFlag, SP_MSG_CREF ); + return 0 ; + } + break; + case SP_MSG_RLSD: + nRet = coGetConnId ( pIntraMsg->aDLR ); + if( nRet < 0 ) + { + spLogDebug ( SCCPDB_ERR, "[sr2co]recv %s msg in init state, cr2co return error ", pStr ); + cr2coFailHandle ( pIntraMsg, uAnsiFlag, SP_MSG_RLC ); + return 0 ; + } + break; + case SP_MSG_RF: + nRet = coGetConnId ( pIntraMsg->aDLR ); + if( nRet < 0 ) + { + spLogDebug ( SCCPDB_ERR, "[sr2co]recv RF msg in init state, co2cr return cref ", pStr ); + cr2coFailHandle ( pIntraMsg, uAnsiFlag, SP_MSG_CREF ); + return 0 ; + } + break; + case SP_MSG_IT: + nRet = coGetConnId ( pIntraMsg->aDLR ); + if( nRet < 0 ) + { + spLogDebug ( SCCPDB_ERR, "[sr2co]recv IT msg in init state,discard " ); + cr2coFailHandle ( pIntraMsg, uAnsiFlag, SP_MSG_RLSD ); + return 0 ; + } + break; + case SP_MSG_RLC: + nRet = coGetConnId ( pIntraMsg->aDLR ); + if( nRet < 0 ) + return 0 ; + break; + default: + nRet = coGetConnId ( pIntraMsg->aDLR ); + if( nRet < 0 ) + { + spLogDebug ( SCCPDB_ERR, "[sr2co]recv %s msg in init state", pStr ); + if( memcmp ( pIntraMsg->aSLR, "/0/0/0", SP_REF_LEN ) ) + { + spLogDebug ( SCCPDB_ERR, "[sr2co]recv %s msg in init state, co2cr return error ", pStr ); +// cr2coFailHandle ( pIntraMsg, uAnsiFlag, SP_MSG_RLSD ); + } + return 0 ; + } + break; + } + pPri.tCrPri.wConnId = nRet; + pPri.tCrPri.uUiPri = pIntraMsg->msgtype + SPUI_PRI_MAX; + pPri.tCrPri.uAnsiFlag = uAnsiFlag; + memcpy ( &pPri.tCrPri.tIntraMsg, pIntraMsg, sizeof ( Intra_Msg ) ); + + spPoolPut ( &pPri, pInCoPool ); + spWatchDogStatic ( CR_TO_CO ); + return 1; + +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void co2cr ( u16 wConnId, u8 uMsgType ) +{ + CO_ConnSection *pCS; + Intra_Msg tCo2CrMsg; + + spWatchDogStatic ( CO_TO_CR_APT ); + +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP co2cr unexpected connection id" ); + if(wConnId >= CO_CS_MPORT) + spShowErr(1, "SCCP co2cr unexpected connection id" ); +// WxcAssert ( uMsgType < SP_MSG_MAX, "SCCP cr2co unexpected msgtype" ); + if(uMsgType >= SP_MSG_MAX) + spShowErr(1, "SCCP cr2co unexpected msgtype" ); + + pCS = &pSp->tCo.tCSInst[wConnId]; + + memset ( &tCo2CrMsg, 0, sizeof ( Intra_Msg ) ); + tCo2CrMsg.msgsource = FROM_SCOC; + tCo2CrMsg.msgtype = uMsgType; + tCo2CrMsg.msgclass = pCS->uClass; + tCo2CrMsg.NetID = pCS->uNetId; + + switch ( uMsgType ) + { + case SP_MSG_CR: + + tCo2CrMsg.msglen = 0; + + if( pCS->tUD.uDataLen ) + { + tCo2CrMsg.msglen = pCS->tUD.uDataLen % 256; + memcpy ( &tCo2CrMsg.data, pCS->tUD.aUserData, tCo2CrMsg.msglen ); + } + memcpy( &tCo2CrMsg.CDA , &pCS->tCDA , sizeof(SCCP_ADDR) ); + tCo2CrMsg.CGA.NetID = tCo2CrMsg.CDA.NetID = tCo2CrMsg.NetID ; + // WxcAssert ( tCo2CrMsg.NetID <= 3, "co2cr: NetID is error " ); + if(tCo2CrMsg.NetID > 3) + spShowErr(1, "co2cr: NetID is error " ); + tCo2CrMsg.OPC = SCCP_Param.spc[tCo2CrMsg.NetID]; + tCo2CrMsg.CDA.DPC = tCo2CrMsg.DPC = pCS->nDPC; + memcpy ( &tCo2CrMsg.aSLR, &pCS->aSLR, SP_REF_LEN ); + tCo2CrMsg.SLS = pCS->uSLS; + scrc_route ( &tCo2CrMsg, pCS->uAnsiFlag ); + spWatchDogStatic ( CO_TO_CR ); + return; + case SP_MSG_CC: + memcpy ( &tCo2CrMsg.aSLR, &pCS->aSLR, SP_REF_LEN ); + memcpy ( &tCo2CrMsg.aDLR, &pCS->aDLR, SP_REF_LEN ); + break; + case SP_MSG_CREF: + memcpy ( &tCo2CrMsg.aDLR, &pCS->aDLR, SP_REF_LEN ); + tCo2CrMsg.cause = pCS->eREA; + break; + case SP_MSG_RLSD: + memcpy ( &tCo2CrMsg.aSLR, &pCS->aSLR, SP_REF_LEN ); + memcpy ( &tCo2CrMsg.aDLR, &pCS->aDLR, SP_REF_LEN ); + //tCo2CrMsg.cause = pCS->eREA; + tCo2CrMsg.cause = 0;//sometime get unexpect value 0x0c, so change it to 0 + break; + case SP_MSG_RLC: + memcpy ( &tCo2CrMsg.aSLR, &pCS->aSLR, SP_REF_LEN ); + memcpy ( &tCo2CrMsg.aDLR, &pCS->aDLR, SP_REF_LEN ); + break; + case SP_MSG_DT1: + memcpy ( &tCo2CrMsg.aDLR, &pCS->aDLR, SP_REF_LEN ); + memcpy ( &tCo2CrMsg.aSLR, &pCS->aSLR, SP_REF_LEN ); + tCo2CrMsg.EOD = 0; + tCo2CrMsg.msglen = 0; + if( pCS->tUD.uDataLen ) + { + tCo2CrMsg.msglen = pCS->tUD.uDataLen % 256; + memcpy ( &tCo2CrMsg.data, pCS->tUD.aUserData, tCo2CrMsg.msglen ); + } + break; + case SP_MSG_IT: + memcpy ( &tCo2CrMsg.aSLR, &pCS->aSLR, SP_REF_LEN ); + memcpy ( &tCo2CrMsg.aDLR, &pCS->aDLR, SP_REF_LEN ); + break; + case SP_MSG_ERR: + spLogDebug ( SCCPDB_ERR, "Need to supported SP_MSG_ERR now!" ); + break; + case SP_MSG_DT2: + case SP_MSG_AK: + case SP_MSG_ED: + case SP_MSG_EA: + case SP_MSG_RSR: + case SP_MSG_RSC: + spLogDebug ( SCCPDB_ERR, "do not supported now!" ); + break; + } + + tCo2CrMsg.CGA.NetID = tCo2CrMsg.CDA.NetID = tCo2CrMsg.NetID ; + tCo2CrMsg.OPC = SCCP_Param.spc[tCo2CrMsg.NetID]; + if( pCS->uSide == CO_INST_SIDE_ORG ) + tCo2CrMsg.CDA.DPC = tCo2CrMsg.DPC = pCS->nDPC; + else if( pCS->uSide == CO_INST_SIDE_DST ) + tCo2CrMsg.CDA.DPC = tCo2CrMsg.DPC = pCS->nOPC; + + tCo2CrMsg.SLS = pCS->uSLS; +// WxcAssert ( tCo2CrMsg.NetID <= 3, "co2cr: NetID is error " ); + if(tCo2CrMsg.NetID > 3) + spShowErr(1, "co2cr: NetID is error " ); + tCo2CrMsg.OPC = SCCP_Param.spc[tCo2CrMsg.NetID]; + if( pCS->uSide == CO_INST_SIDE_DST && pCS->nDPC) + tCo2CrMsg.OPC = pCS->nDPC; + else if(pCS->uSide == CO_INST_SIDE_ORG && pCS->nOPC) + tCo2CrMsg.OPC = pCS->nOPC; + tCo2CrMsg.CDA.ip = 0xffffffff; + send_msg ( &tCo2CrMsg, pCS->uAnsiFlag); + spWatchDogStatic ( CO_TO_CR ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void co2ul ( u16 wConnId, u8 uPri ) +{ + u8 *pStr; + CO_ConnSection *pCS; + SP_UiPriUnion *pUnPri; + SP_PriPoolEle tPoolEle, *pPri; + + spWatchDogStatic ( CO_SUBMIT_UL_APT ); +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP co2cr unexpected connection id" ); + if(wConnId >= CO_CS_MPORT) + spShowErr(1, "SCCP co2cr unexpected connection id" ); + + pPri = &tPoolEle; + pUnPri = ( SP_UiPriUnion * ) & pPri->tUiPri.tPriUnion; + + pCS = &pSp->tCo.tCSInst[wConnId]; + pPri->tUiPri.uUiPri = uPri; + pPri->tUiPri.uAnsiFlag = pCS->uAnsiFlag; + pPri->tUiPri.wConnId = wConnId; + + spGetUlPrimitiveStr ( uPri, pStr ); + + switch ( uPri ) + { + case N_UNITDATA_IND: + case N_NOTICE_IND: + spLogDebug ( SCCPDB_ERR, "SP=>UL: Unsupported UDT primitive now :%s", pStr ); + break; + case N_CONNECT_IND: + pUnPri->tPriNConnInd.tUD.uDataLen = 0; + if( pCS->tUD.uDataLen ) + { + pUnPri->tPriNConnInd.uOptFlag = 0x04; + memcpy ( &pUnPri->tPriNConnInd.tUD, &pCS->tUD, sizeof ( SP_UD ) ); + } + else + pUnPri->tPriNConnInd.uOptFlag = 0; + memcpy ( &pUnPri->tPriNConnInd.tCDA, &pCS->tCDA, sizeof ( SCCP_ADDR ) ); + memcpy ( &pUnPri->tPriNConnInd.aSLR, &pCS->aDLR, SP_REF_LEN ); + pUnPri->tPriNConnInd.uSLS = pCS->uSLS; + pUnPri->tPriNConnInd.OPC = pCS->nOPC; + pUnPri->tPriNConnInd.NetID = pCS->uNetId; + break; + case N_CONNECT_CFM: + pUnPri->tPriNConnCfm.tUD.uDataLen = 0; + if( pCS->tUD.uDataLen ) + { + pUnPri->tPriNConnCfm.uOptFlag = 0x04; + memcpy ( &pUnPri->tPriNConnCfm.tUD, &pCS->tUD, sizeof ( SP_UD ) ); + } + else + pUnPri->tPriNConnCfm.uOptFlag = 0; + break; + case N_DISCONNECT_IND: + pUnPri->tPriNDisconnInd.tUD.uDataLen = 0; + if( pCS->tUD.uDataLen ) + { + pUnPri->tPriNDisconnInd.uOptFlag = 0x04; + memcpy ( &pUnPri->tPriNDisconnInd.tUD, &pCS->tUD, sizeof ( SP_UD ) ); + } + else + pUnPri->tPriNDisconnInd.uOptFlag = 0; + pUnPri->tPriNDisconnInd.eOR = pCS->eOR; + pUnPri->tPriNDisconnInd.eREA = pCS->eREA; + break; + case N_DATA_IND: + memcpy ( &pUnPri->tPriNDataInd.tUD, &pCS->tUD, sizeof ( SP_UD ) ); + break; + case N_DATAAK_IND: + case N_EDATA_IND: + case N_RESET_IND: + case N_RESET_CFM: + case N_INFORM_IND: + case RELAY: + spLogDebug ( SCCPDB_ERR, "SP=>UL: Unsupported the primitive now :%s", pStr ); + break; + default: + spLogDebug ( SCCPDB_ERR, "SP=>UL: Unknow primtive :%s", pStr ); + break; + } + + spShowPrimitive ( &pPri->tUiPri, 0 ); + spWatchDogStatic ( WDS_RECV_PRI ); + + //add to put messages into corresponding pool for Upper lyaer to get + switch ( pCS->tCDA.SSN ) + { + case SSN_AIF: //AIF + spPoolPut ( &tPoolEle, pOutCoPool[0] ); + spLogDebug ( SCCPDB_USER, "co2ul put AIF message into OutCoPool[0]" ); + break; + case SSN_RANAP: //RANAP + spPoolPut ( &tPoolEle, pOutCoPool[1] ); + spLogDebug ( SCCPDB_USER, "co2ul put RANAP message into OutCoPool[1]" ); + break; + default: + spLogDebug ( SCCPDB_ERR, "SP=>UL: Unexpected SSN :%d", pCS->tCDA.SSN ); + break; + } + spWatchDogStatic ( CO_SUBMIT_UL ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void co2scmg ( ) +{ + +} + +void co2co ( u16 wConnId, u8 uPri ) +{ + SP_PriPoolEle pPri; + + memset ( &pPri, 0, sizeof ( SP_PriPoolEle ) ); + +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP coTimerOut unexpected connection id" ); + if(wConnId >= CO_CS_MPORT) + spShowErr(1, "SCCP coTimerOut unexpected connection id" ); +// WxcAssert ( ( uPri > SPCR_PRI_MAX && uPri < SPTM_PRI_MAX ), "SCCP coTimerOut unexpected msgtype" ); + if(!( uPri > SPCR_PRI_MAX && uPri < SPTM_PRI_MAX )) + spShowErr(1, "SCCP coTimerOut unexpected msgtype" ); + pPri.tUiPri.uUiPri = uPri; + pPri.tUiPri.wConnId = wConnId; + + spPoolPut ( &pPri, pInCoPool ); +} + +int spCheckAudit ( ) +{ + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int coAssignSLS ( u8 wConnId ) +{ + return ( wConnId & 0x0F ); +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coAssignLR ( u16 wConnId, u8 * pLR ) +{ +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP coNewCS unexpected connection id" ); + if(wConnId >= CO_CS_MPORT) + spShowErr(1, "SCCP coNewCS unexpected connection id" ); + + *( pLR ) = pSp->dSysID; + *( pLR + 1 ) = wConnId >> 8; + *( pLR + 2 ) = wConnId & 0xFF; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int coAssignClass ( u8 wConnId ) +{ + //do not support class 3 now + return 2; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int coAssignCredit ( u8 wConnId ) +{ + //credit not supported now + return 0; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int coNewCS ( u16 wConnId, SCCP_ADDR * pAddr ) +{ + CO_ConnSection *pCS; + +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP coNewCS unexpected connection id" ); + if(wConnId >= CO_CS_MPORT) + spShowErr(1, "SCCP coNewCS unexpected connection id" ); + + pCS = &pSp->tCo.tCSInst[wConnId]; + pCS->uSLS = coAssignSLS ( wConnId ); + coAssignLR ( wConnId, pCS->aSLR ); + memcpy ( &pCS->tCDA, pAddr, sizeof ( SCCP_ADDR ) ); + pCS->uClass = coAssignClass ( wConnId ); + pCS->uCredit = coAssignCredit ( wConnId ); + + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coFreeCS ( u16 wConnId ) +{ + CO_DataBlock *pCo; + CO_ConnSection *pCS = &pSp->tCo.tCSInst[wConnId]; + + pCo = &pSp->tCo; + +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP coNewCS un expected connection id" ); + if(wConnId >= CO_CS_MPORT) + spShowErr(1, "SCCP coNewCS un expected connection id" ); + memset ( pCS, 0, sizeof ( CO_ConnSection ) ); + pCo->wConnIdCount--; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// +void coFillCS ( SP_PriPoolEle * pPri ) +{ + SP_CrPriPara *pCrPri; + CO_ConnSection *pCS; + + pCrPri = ( SP_CrPriPara * ) & pPri->tCrPri; + +// WxcAssert ( ( pCrPri->wConnId < CO_CS_MPORT ), "SCCP coFillCS unexpect connection id" ); + if(! ( pCrPri->wConnId < CO_CS_MPORT )) + spShowErr(1, "SCCP coFillCS unexpect connection id" ); +// WxcAssert ( ( pCrPri->uUiPri < SPTM_PRI_MAX ), "SCCP coFillCS unexpect primitive" ); + if(! ( pCrPri->uUiPri < SPTM_PRI_MAX )) + spShowErr(1, "SCCP coFillCS unexpect primitive" ); + + pCS = &pSp->tCo.tCSInst[pCrPri->wConnId]; + + pCS->uPri = pCrPri->uUiPri; + pCS->uAnsiFlag = pCrPri->uAnsiFlag; + + if( pCS->uPri > SPCR_PRI_MAX ) //Internal primitive + { + return; + } + else if( pCS->uPri > SPUI_PRI_MAX ) //CR/SCMG message primitive + { + Intra_Msg *pMsg; + + pMsg = &pCrPri->tIntraMsg; + if( pMsg->msglen ) + { +// WxcAssert ( pMsg->msglen < 255, "coFillCS Message length overflow" ); + if(pMsg->msglen >= 255) + spShowErr(1, "coFillCS Message length overflow" ); + pCS->tUD.uDataLen = pMsg->msglen % 256; + memcpy ( &pCS->tUD.aUserData, &pMsg->data, pCS->tUD.uDataLen ); + } + else + pCS->tUD.uDataLen = 0; + + switch ( pCS->uPri ) + { + case R_CR: /* connection request */ + memcpy ( &pCS->tCDA, &pMsg->CDA, sizeof ( SCCP_ADDR ) ); + //memcpy ( &pCS->tCGA, &pMsg->CGA, sizeof ( SCCP_ADDR ) ); + pCS->nDPC = pMsg->DPC; + pCS->nOPC = pMsg->OPC; + pCS->uNetId = pMsg->NetID; + pCS->uSLS = pMsg->SLS; + memcpy ( &pCS->aDLR, &pMsg->aSLR, SP_REF_LEN ); + break; + case R_CR2: /* connection request type 2 */ + break; + case R_CC: /* connection confirm */ + pCS->uClass = pMsg->msgclass; + memcpy ( &pCS->aDLR, &pMsg->aSLR, SP_REF_LEN ); + break; + case R_CREF: /* connection refused */ + pCS->eREA = pMsg->cause; + break; + case R_RLSD: /* release request */ + pCS->eREA = pMsg->cause; + break; + case R_RLC: /* release confirm */ + break; + case R_DT1: /* Data Form 1 */ + break; + case R_DT2: /* Data Form 2 */ + break; + case R_AK: /* Data acknowledge */ + break; + case R_ED: /* Expedited data */ + break; + case R_EA: /* Expedited data acknowledge */ + break; + case R_RSR: /* Reset request */ + break; + case R_RSC: /* Reset confirm */ + break; + case R_ERR: /* PDU error */ + break; + case R_IT: /* Inactivity test */ + break; + case R_RF: /* Routing Fail */ + break; + case R_RLS_ERR: /* Release err */ + break; + default: + break; + } + } + else //upper layer primitive + { + SP_UiPriUnion *pUnPri; + + pUnPri = ( SP_UiPriUnion * ) & pPri->tUiPri.tPriUnion; + switch ( pCS->uPri ) + { + case N_CONNECT_REQ: + memcpy ( &pCS->tCDA, &pUnPri->tPriNConnReq.tCDA, sizeof ( SCCP_ADDR ) ); + if( pUnPri->tPriNConnReq.uOptFlag & 0x08 ) + { + memcpy ( &pCS->tUD, &pUnPri->tPriNConnReq.tUD, sizeof ( SP_UD ) ); + } + pCS->nDPC = pCS->tCDA.DPC; + pCS->uNetId = pUnPri->tPriNConnReq.tCDA.NetID; + break; + case N_CONNECT_RSP: + break; + case N_DISCONNECT_REQ: + pCS->eREA = pUnPri->tPriNDisconnReq.eREA; + pCS->eOR = NSU; + break; + case N_DATA_REQ: + memcpy ( &pCS->tUD, &pUnPri->tPriNDataReq.tUD, sizeof ( SP_UD ) ); + break; + case N_DATAAK_REQ: + case N_EDATA_REQ: + case N_RESET_REQ: + case N_RESET_RSP: + case N_INFORM_REQ: + break; + default: + break; + } + } +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// +int coCheckCS ( u16 wConnId, u8 uCState, u8 uSide ) +{ +#ifdef DEBUG +// WxcAssert ( ( uCState < CO_STATUS_MAX ), "SCCP coFsm unexpect connection section state" ); + if(!( uCState < CO_STATUS_MAX )) + spShowErr(1, "SCCP coFsm unexpect connection section state" ); + +// WxcAssert ( ( uSide < CO_INST_SIDE_MAX ), "SCCP coFsm unexpect connection section state" ); + if(!( uSide < CO_INST_SIDE_MAX )) + spShowErr(1, "SCCP coFsm unexpect connection section state" ); +#else + if( uCState >= CO_STATUS_MAX ) + { + spLogStateError ( wConnId, ERR_FSM_DISCARD ); + //spCoRecover ( wConnId, CO_FATAL_STATE ); + return 0; + } + + if( uSide >= CO_INST_SIDE_MAX ) + { + spLogStateError ( wConnId, ERR_FSM_UNEXPECT_SIDE ); + //spCoRecover ( wConnId, CO_FATAL_SIDE ); + return 0; + } +#endif + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coTimerOut ( u16 wConnId, u8 uPri ) +{ + SP_PriPoolEle pPri; + +// WxcAssert ( wConnId < CO_CS_MPORT, "SCCP coTimerOut unexpected connection id" ); + if(wConnId >= CO_CS_MPORT) + spShowErr(1, "SCCP coTimerOut unexpected connection id" ); +// WxcAssert ( ( uPri > SPCR_PRI_MAX && uPri < SPTM_PRI_MAX ), "SCCP coTimerOut unexpected msgtype" ); + if(!( uPri > SPCR_PRI_MAX && uPri < SPTM_PRI_MAX )) + spShowErr(1, "SCCP coTimerOut unexpected msgtype" ); + + + spLogTimerOut( wConnId , uPri ); + memset ( &pPri, 0, sizeof ( SP_PriPoolEle ) ); + + pPri.tUiPri.uUiPri = uPri; + pPri.tUiPri.wConnId = wConnId; + + spPoolPut ( &pPri, pInCoPool ); + +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void coTimerMng ( ) +{ + u16 wConnId; + CO_ConnSection *pCS; + CO_Timer *pTmSet; + // u8 uPri; + + + for ( wConnId = 0; wConnId < CO_CS_MPORT; wConnId++ ) + { + pCS = &pSp->tCo.tCSInst[wConnId]; + + if( CO_STATUS_INIT == pCS->uCState ) + { + continue; + } + + pTmSet = &pCS->tmSCOC; + + if( pTmSet->tmConnEst && ++pTmSet->tmConnEst > T_CONNEST_MAX ) + { + pTmSet->tmConnEst = 0; + coTimerOut ( wConnId, T_CONNEST_OUT ); + } + if( pTmSet->tmIas && ++pTmSet->tmIas > T_IAS_MAX ) + { + pTmSet->tmIas = 0; + coTimerOut ( wConnId, T_IAS_OUT ); + } + if( pTmSet->tmIar && ++pTmSet->tmIar > T_IAR_MAX ) + { + pTmSet->tmIar = 0; + coTimerOut ( wConnId, T_IAR_OUT ); + } + if( pTmSet->tmRepeatRel && ++pTmSet->tmRepeatRel > T_REPEATE_RLS_MAX ) + { + pTmSet->tmRepeatRel = 0; + coTimerOut ( wConnId, T_REPEATE_RLS_OUT ); + } + if( pTmSet->tmRel && ++pTmSet->tmRel > T_RLS_MAX ) + { + pTmSet->tmRel = 0; + coTimerOut ( wConnId, T_RLS_OUT ); + } + if( pTmSet->tmReset && ++pTmSet->tmReset > T_RESET_MAX ) + { + pTmSet->tmReset = 0; + coTimerOut ( wConnId, T_RESET_OUT ); + } + if( pTmSet->tmGuard && ++pTmSet->tmGuard > T_GUARD_MAX ) + { + pTmSet->tmGuard = 0; + coTimerOut ( wConnId, T_GUARD_OUT ); + } + if( pTmSet->tmInternal && ++pTmSet->tmInternal > T_INTERNAL_MAX ) + { + pTmSet->tmInternal = 0; + coTimerOut ( wConnId, T_INTERNAL_OUT ); + } + } +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int coNewConnId ( u8 uPri ) +{ + static u16 wConnId = 0; + CO_DataBlock *pCo; + CO_ConnSection *pCS; + u16 tmpConnId = wConnId; + + pCo = &pSp->tCo; + + if( pCo->wConnIdCount >= CO_CS_MPORT ) + { + spLogDebug ( SCCPDB_ERR, "No resource for new connection" ); + return -1; + } + +// WxcAssert ( ( uPri == N_CONNECT_REQ || uPri == R_CR ), "Unexpect primitive while allocating new connection" ); + if(!( uPri == N_CONNECT_REQ || uPri == R_CR )) + spShowErr(1, "Unexpect primitive while allocating new connection" ); + + // for ( wConnId = 0; wConnId < CO_CS_MPORT; wConnId++ ) + while (++wConnId != tmpConnId) + { + if (wConnId >= CO_CS_MPORT) + wConnId = 0; + + pCS = &pSp->tCo.tCSInst[wConnId]; + + if( CO_STATUS_INIT == pCS->uCState ) + { + memset ( pCS, 0, sizeof ( CO_ConnSection ) ); + pCS->uCState = CO_STATUS_IDLE; + + if( R_CR == uPri ) + { + pCS->uSide = CO_INST_SIDE_DST; + } + else if( N_CONNECT_REQ == uPri ) + { + pCS->uSide = CO_INST_SIDE_ORG; + } + pCo->wConnIdCount++; + return wConnId; + } + } + + spLogDebug ( SCCPDB_ERR, "No resource for new connection" ); + return -1; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int coGetConnId ( u8 *pSLR ) +{ + u16 wConnId; +// CO_ConnSection *pCS; + +// for ( wConnId = 0; wConnId < CO_CS_MPORT; wConnId++ ) +// { +// pCS = &pSp->tCo.tCSInst[wConnId]; + if( memcmp ( pSLR, "\0\0\0", SP_REF_LEN )) + { + wConnId = (pSLR[1]<<8)+pSLR[2]; + if(wConnId >= CO_CS_MPORT) + return -1; + else + return wConnId; + } +// } + return -1; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +int coCheckConnId ( SP_UiPriPara * pUiPriParam ) +{ +// WxcAssert ( ( pUiPriParam->wConnId < CO_CS_MPORT ), "SCCP coCheckConnId unexpect connection id" ); + if(! ( pUiPriParam->wConnId < CO_CS_MPORT )) + spShowErr(1, "SCCP coCheckConnId unexpect connection id" ); + if( pSp->tCo.tCSInst[pUiPriParam->wConnId].uCState > 0 ) + { + return 1; + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////// +// Name : coCheckResource /// +// Function : Check Resouce for a coming connection /// +// Return : Have been check in cr2co function, so always return 1 /// +/////////////////////////////////////////////////////////////////////////// +int coCheckResource ( ) +{ + //Have been check in cr2co function, so always return 1 + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spWatchDogStatic ( u8 uDebugStaticMask ) +{ + CO_DebugStatic *pDs = &pSp->tCo.tCoDebugStatic; + + switch ( uDebugStaticMask ) + { + case GET_IN_POOL: + pDs->dGetInPool++; + break; + case PUT_IN_POOL: + pDs->dPutInPool++; + break; + case READ_IN_POOL: + pDs->dReadInPool++; + break; + case WRITE_IN_POOL: + pDs->dWriteInPool++; + break; + case GET_OUT_POOL: + pDs->dGetOutPool++; + break; + case PUT_OUT_POOL: + pDs->dPutOutPool++; + break; + case PUT_ELE_APT: + pDs->dPutEleApt++; + break; + case PUT_ELE_SUC: + pDs->dPutEleSuc++; + break; + case UL_POST_CO_APT: + pDs->dUlPostCoApt++; + break; + case UL_POST_CO: + pDs->dUlPostCo++; + break; + case CO_SUBMIT_UL_APT: + pDs->dCoSubmitUlApt++; + break; + case CO_SUBMIT_UL: + pDs->dCoSubmitUl++; + break; + case CO_TO_CR_APT: + pDs->dCo2CrApt++; + break; + case CO_TO_CR: + pDs->dCo2Cr++; + break; + case CR_TO_CO_APT: + pDs->dCr2CoApt++; + break; + case CR_TO_CO: + pDs->dCr2Co++; + break; + case SP_TIMER_OUT: + pDs->dTimerOut++; + break; + default: + break; + } +} + +//add by Roy for dual server message redirect +void coRedirect(SP_UiPriPara * pUiPriParam) +{ + Intra_Msg tmpMsg; + + memset (&tmpMsg, 0, sizeof(Intra_Msg)); + tmpMsg.msglen = 0; + + if (pUiPriParam->uUiPri == N_UNITDATA_IND) + { + if( pUiPriParam->tPriUnion.tPriNUDataInd.tUD.uDataLen ) + { + tmpMsg.msglen = pUiPriParam->tPriUnion.tPriNUDataInd.tUD.uDataLen % 256; + memcpy ( &tmpMsg.data, pUiPriParam->tPriUnion.tPriNUDataInd.tUD.aUserData, tmpMsg.msglen ); + } + memcpy( &tmpMsg.CDA , &pUiPriParam->tPriUnion.tPriNUDataInd.tCDA , sizeof(SCCP_ADDR) ); + memcpy( &tmpMsg.CGA , &pUiPriParam->tPriUnion.tPriNUDataInd.tCGA , sizeof(SCCP_ADDR) ); +// WxcAssert ( tmpMsg.NetID <= 3, "co2cr: NetID is error " ); + if(tmpMsg.NetID > 3) + spShowErr(1, "co2cr: NetID is error " ); + tmpMsg.OPC = pUiPriParam->tPriUnion.tPriNUDataInd.tCGA.DPC; + tmpMsg.SLS = pUiPriParam->tPriUnion.tPriNUDataInd.uSLS; + tmpMsg.msgtype = UDT_MSG; + } + else{ + if( pUiPriParam->tPriUnion.tPriNConnInd.tUD.uDataLen ) + { + tmpMsg.msglen = pUiPriParam->tPriUnion.tPriNConnInd.tUD.uDataLen % 256; + memcpy ( &tmpMsg.data, pUiPriParam->tPriUnion.tPriNConnInd.tUD.aUserData, tmpMsg.msglen ); + } + memcpy( &tmpMsg.CDA , &pUiPriParam->tPriUnion.tPriNConnInd.tCDA , sizeof(SCCP_ADDR) ); + memcpy ( &tmpMsg.aSLR, &pUiPriParam->tPriUnion.tPriNConnInd.aSLR, SP_REF_LEN ); +// WxcAssert ( tmpMsg.NetID <= 3, "co2cr: NetID is error " ); + if(tmpMsg.NetID > 3) + spShowErr(1, "co2cr: NetID is error " ); + tmpMsg.OPC = pUiPriParam->tPriUnion.tPriNConnInd.OPC; + tmpMsg.SLS = pUiPriParam->tPriUnion.tPriNConnInd.uSLS; + tmpMsg.msgtype = CR_MSG; + + //remove the connection + memset(&pSp->tCo.tCSInst[pUiPriParam->wConnId], 0, sizeof(CO_ConnSection)); + pSp->tCo.wConnIdCount--; + } + tmpMsg.NetID = tmpMsg.CDA.NetID; + tmpMsg.CDA.ip = pSp->dAlterIP; + tmpMsg.msgsource = FROM_MTP; + tmpMsg.redirectFlag = 1; + + spLogDebug ( SCCPDB_TIME, "AIF ==> SCCP : Message redirect request" ); + send_msg ( &tmpMsg, pUiPriParam->uAnsiFlag); +} diff --git a/plat/sccp/src/scoc_if.c b/plat/sccp/src/scoc_if.c new file mode 100644 index 0000000..7194966 --- /dev/null +++ b/plat/sccp/src/scoc_if.c @@ -0,0 +1,292 @@ +////////////////////////////////////////////////// +//Title : scoc_if.c +//Auhtor : Liu Wei +//Desc : SCOC interface implementation +//Created : 2007-05-07 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/sccp_pub.h" + +#ifdef LOOSE_COUPLING_MODE //Loose coupling mode + +extern int coCheckConnId ( SP_UiPriPara * pUiPriParam ); +extern void coRedirect(SP_UiPriPara * pUiPriParam); + +/////////////////////////////////////////////////////////////////////////// +// +// Name : PostSp +// Function : Upper layer post request/response primitive to sccp +// Parameter: pUiPriParam [sccp UL primitive buffer pointer] +// Note : Sccp Connid is implicit returned in "pUiPriParam" buffer +// : while N-Connect requesing +// Return : 0 Post Fail 1 Post Successful +// +/////////////////////////////////////////////////////////////////////////// + +int PostSp ( SP_UiPriPara * pUiPriParam ) +{ + int nRet; + u8 *pPriStr; + + spShowPrimitive ( pUiPriParam, 1 ); + + spWatchDogStatic ( UL_POST_CO_APT ); + + switch ( pUiPriParam->uUiPri ) + { + case N_UNITDATA_REQ: + { + SCLC_MSG tClMsg; + + tClMsg.msglen = pUiPriParam->tPriUnion.tPriNUDataReq.tUD.uDataLen; + memcpy ( &tClMsg.msg, &pUiPriParam->tPriUnion.tPriNUDataReq.tUD.aUserData, tClMsg.msglen ); + memcpy ( &tClMsg.src_addr, &pUiPriParam->tPriUnion.tPriNUDataReq.tCGA, sizeof ( SCCP_ADDR ) ); + memcpy ( &tClMsg.dst_addr, &pUiPriParam->tPriUnion.tPriNUDataReq.tCDA, sizeof ( SCCP_ADDR ) ); + if(tClMsg.src_addr.DPC == 0) + tClMsg.src_addr.DPC = SCCP_Param.spc[tClMsg.src_addr.NetID]; + tClMsg.sequence_control = 0; + sclc_send ( &tClMsg ); + spWatchDogStatic ( UL_POST_CO ); + return 1; + } + //break; + case N_UNITDATA_IND: + case N_CONNECT_IND: + //redirect to alternative server, add by Roy + coRedirect(pUiPriParam); + spWatchDogStatic ( UL_POST_CO ); + return 1; + break; + case N_CONNECT_REQ: + nRet = coNewConnId ( N_CONNECT_REQ ); + if( nRet < 0 ) + { + spLogDebug ( SCCPDB_ERR, "No resouces available !\n" ); + return 0; + } + pUiPriParam->wConnId = nRet; + break; + case N_CONNECT_RSP: + case N_DISCONNECT_REQ: + case N_DATA_REQ: + if( !coCheckConnId ( pUiPriParam ) ) + { + spLogDebug ( SCCPDB_ERR, "Invalid SCCP connection ID : %d", pUiPriParam->wConnId ); + return 0; + } + break; + case N_DATAAK_REQ: + case N_EDATA_REQ: + case N_RESET_REQ: + case N_RESET_RSP: + case N_INFORM_REQ: + spGetUlPrimitiveStr ( pUiPriParam->uUiPri, pPriStr ); + spLogDebug ( SCCPDB_ERR, "Unsupported the primitive now :%s", pPriStr ); + return 0; + default: + spGetUlPrimitiveStr ( pUiPriParam->uUiPri, pPriStr ); + spLogDebug ( SCCPDB_ERR, "Invalid primivtive recieved :%s ", pPriStr ); + return 0; + } + + spWatchDogStatic ( UL_POST_CO ); + + { + SP_PriPoolEle tPoolEle; + + memset ( &tPoolEle, 0, sizeof ( SP_PriPoolEle ) ); + memcpy ( &tPoolEle.tUiPri, pUiPriParam, sizeof ( SP_UiPriPara ) ); + spPoolPut ( &tPoolEle, pInCoPool ); + } + + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// +// Name : SpSubmit +// Function : Upper layer fetch indicate/confirm primitive submited from sccp +// Parameter: pUiPriParam [sccp UL primitive buffer pointer] +// uUlSapId [upper layer sap id [0 tcap 1 pps 2 smsc 3 aif 4 ranap 5 reserved] ] +// Return : 0 Fetch Fail 1 Fetch Successful +// +/////////////////////////////////////////////////////////////////////////// + +int SpSubmit ( SP_UiPriPara * pUiPriParam, u8 uUlSapId ) +{ + int nRet = 0; + + SCLC_MSG tClMsg; + + nRet = sclc_receive ( &tClMsg, uUlSapId ); + if( nRet ) + { + pUiPriParam->tPriUnion.tPriNUDataInd.uSLS = tClMsg.sls; + pUiPriParam->wConnId = 0xFFFF; + pUiPriParam->uUiPri = N_UNITDATA_IND; + pUiPriParam->tPriUnion.tPriNUDataInd.tUD.uDataLen = tClMsg.msglen; + memcpy ( &pUiPriParam->tPriUnion.tPriNUDataInd.tUD.aUserData, &tClMsg.msg, tClMsg.msglen ); + memcpy ( &pUiPriParam->tPriUnion.tPriNUDataInd.tCGA, &tClMsg.src_addr, sizeof ( SCCP_ADDR ) ); + memcpy ( &pUiPriParam->tPriUnion.tPriNUDataInd.tCDA, &tClMsg.dst_addr, sizeof ( SCCP_ADDR ) ); + return nRet; + } + + if( uUlSapId >= 3 && uUlSapId <= SP_POOL_SIZE + 2 ) + { + SP_PriPoolEle tPoolEle; + + //aif: pOutCoPool[0] ranap: pOutCoPool[1] + if( (nRet = spPoolGet ( &tPoolEle, pOutCoPool[uUlSapId-3] )) ) + { + memcpy ( pUiPriParam, &tPoolEle.tUiPri, sizeof ( SP_UiPriPara ) ); + spLogDebug ( SCCPDB_USER, "UL get message from OutCoPool[%d]", uUlSapId-3 ); + } + + return nRet; + } + else + { + spLogDebug ( SCCPDB_ERR, "UL : Unexpected SapId :%d ", uUlSapId); + return 0; + } + return nRet; +} + +#else + +/////////////////////Below is reserved, do not need to read///////////////////// + +#ifdef TIGHT_COUPING_MODE //Tight coupling mode + +#error "Do not support Tight coupling mode ,please use \"LOOSE_COUPLING_MODE\" flag \n" + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void Ul_Post_Sp ( SP_UiPriPara * pUiPriParam ) +{ + SP_UiPriUnion *pPriUn; + + pPriUn = &pUlPri->tPriUnion; + + switch ( pUiPriParam->uUi_Pri ) + { + case N_UNITDATA_REQ: //reserved for sclc + spUi_N_UnitDataReq ( &pPriUn->tPriNUDataReq.tCDA, &pPriUn->tPriNUDataReq.tCGA, &pPriUn->tPriNUDataReq.tSEQ, &pPriUn->tPriNUDataReq.tRO, &pPriUn->tPriNUDataReq.tUD ); + break; + + case N_CONNECT_REQ: + spUi_N_ConnectReq ( &pPriUn->tPriNConnReq.tCDA, &pPriUn->tPriNConnReq.tCGA, &pPriUn->tPriNConnReq.tRCS, &pPriUn->tPriNConnReq.tEDS ); + break; + + case N_CONNECT_RSP: + spUi_N_ConnectRsp ( &pPriUn->tPriNConnRsp.tRA, &pPriUn->tPriNConnRsp.tRCS, &pPriUn->tPriNConnRsp.tEDS ); + break; + + case N_DISCONNECT_REQ: + spUi_N_DisconnectReq ( &pPriUn->tPriNDisconnReq.tRA, &pPriUn->tPriNDisconnReq.tREA, &pPriUn->tPriNDisconnReq.tUC, pPriUn->tPriNDisconnReq.tCI ); + break; + + case N_DATA_REQ: + spUi_N_DataReq ( &pPriUn->tPriNDataReq.tCR, &pPriUn->tPriNDataReq.tUD, pPriUn->tPriNDataReq.tCI ); + break; + + case N_DATAAK_REQ: + spUi_N_DataAkReq ( pPriUn->tPriNDataAkReq.tCI ); + break; + + case N_EDATA_REQ: + spUi_N_EDataReq ( pPriUn->tPriNEDataReq.tCI, &pPriUn->tPriNEDataReq.tUD ); + break; + + case N_RESET_REQ: + spUi_N_ResetReq ( &pPriUn->tPriNResetReq.tREA, pPriUn->tPriNResetReq.tCI ); + break; + + case N_RESET_RSP: + spUi_N_ResetRsp ( pPriUn->tPriNResetRsp.tCI ); + break; + + case N_INFORM_REQ: + spUi_N_InformReq ( &pPriUn->tPriNInformReq.tREA, &pPriUn->tPriNInformReq.tQOS, pPriUn->tPriNInformReq.tCI ); + break; + + default: + spShowMsg ( SCCPDB_ERR, "SCCP <== AIF. UnKnow Primitive %s", GetUiPriStr ( pPriUn->uUi_Pri ) ); + return; + break; + + } + spShowMsg ( SCCPDB_AIF, "SCCP <== AIF. Primitive %s", GetUiPriStr ( pPriUn->uUi_Pri ) ); + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void Sp_Submit_Ul ( SP_UiPriPara * pUiPriParam ) +{ + switch ( Ui_Pri ) + { + case N_UNITDATA_IND: //reserved for sclc + + break; + + case N_NOTICE_IND: + + break; + + case N_CONNECT_IND: + + break; + + case N_CONNECT_CFM: + + break; + + case N_DISCONNECT_IND: + + break; + + case N_DATA_IND: + + break; + + case N_DATAAK_IND: + + break; + + case N_EDATA_IND: + + break; + + case N_RESET_IND: + + break; + + case N_RESET_CFM: + + break; + + case N_INFORM_IND: + + break; + + default: + + break; + + } + return 0; +} +#endif + +/////////////////////Above is reserved, do not need to read///////////////////// + +#endif diff --git a/plat/sccp/src/scoc_pool.c b/plat/sccp/src/scoc_pool.c new file mode 100644 index 0000000..2f64b21 --- /dev/null +++ b/plat/sccp/src/scoc_pool.c @@ -0,0 +1,231 @@ +////////////////////////////////////////////////// +//Title : pool.c +//Auhtor : Liu Wei +//Desc : List and Pool Queue struct implement +//Created : 2007-05-01 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "./include/sccp_pub.h" + +/*@ignore@*/ +/////////////////////////////////////////////////////////////////////////// +// Reserved for Pool Test -- Start +/////////////////////////////////////////////////////////////////////////// +/* + #include "stdio.h" + #include "string.h" + #include "malloc.h" + + typedef struct SP_PriPoolEle + { + char ch; + } + SP_PriPoolEle; + */ +/////////////////////////////////////////////////////////////////////////// +// Reserved for Pool Test -- End +/////////////////////////////////////////////////////////////////////////// +#define SP_MAX_ELEMENT 512 + +CO_Pool tInCoPool; +CO_Pool *pInCoPool; +CO_Pool tOutCoPool[SP_POOL_SIZE]; +CO_Pool *pOutCoPool[SP_POOL_SIZE]; + + +//add by roy jiang for a replacement of dynamic memory allocation +CO_PoolEle SpEleBuf[SP_MAX_ELEMENT]; + +void spPoolInit ( ) +{ + int i; + pInCoPool = &tInCoPool; + for (i = 0; i < SP_POOL_SIZE; i++) + pOutCoPool[i] = &tOutCoPool[i]; + memset ( pInCoPool, 0, sizeof ( CO_Pool ) ); + memset ( tOutCoPool, 0, sizeof ( CO_Pool ) * SP_POOL_SIZE ); + memset ( SpEleBuf, 0, sizeof ( CO_PoolEle ) * SP_MAX_ELEMENT ); + POOL_INIT ( &pInCoPool->tPoolHead ); + pInCoPool->pPoolHead = &pInCoPool->tPoolHead; + pInCoPool->uMaxPoolSize = MAX_IN_POOL; + for (i = 0; i < SP_POOL_SIZE; i++) + { + POOL_INIT ( &pOutCoPool[i]->tPoolHead ); + pOutCoPool[i]->pPoolHead = &pOutCoPool[i]->tPoolHead; + pOutCoPool[i]->uMaxPoolSize = MAX_OUT_POOL; + } +} + +static int busyCount = 0; +CO_PoolEle *spMallocEle() +{ + static int i = 0; + int j = i; + + if (busyCount >= SP_MAX_ELEMENT) + return NULL; + + while (++i != j) + { + if (i >= SP_MAX_ELEMENT) + i = 0; + + if (SpEleBuf[i].flag == 0) + { + busyCount++; + SpEleBuf[i].flag = 1; + pSp->tCo.tCoDebugStatic.dbusyElem = busyCount; + return &SpEleBuf[i]; + } + } + + return NULL; +} + +void spFreeEle(CO_PoolEle *elem) +{ + if (elem->flag != 0) + { + busyCount--; + pSp->tCo.tCoDebugStatic.dbusyElem = busyCount; + memset ( elem, 0, sizeof ( CO_PoolEle ) ); + } + return; +} + +int spPoolGet ( SP_PriPoolEle *pPri, CO_Pool *pCoPool ) +{ + CO_PoolEle *pPoolEle; + + spWatchDogStatic ( CO_GET_POOL ); + + if( pCoPool->uPoolCount <= 0 || ( POOL_EMPTY ( pCoPool->pPoolHead ) ) ) + { + //spLogDebug ( SCCPDB_ERR ,"SCCP get primitive pool fail ,empty" ); + return 0; + } + + memcpy ( pPri, &pCoPool->pPoolHead->pPoolFirst->tPri, sizeof ( SP_PriPoolEle ) ); + pPoolEle = pCoPool->pPoolHead->pPoolFirst; + POOL_REMOVE ( pCoPool->pPoolHead, pPoolEle, tPointer ); + pCoPool->uPoolCount--; + // free ( pPoolEle ); + spFreeEle (pPoolEle); + spWatchDogStatic ( CO_READ_POOL ); + + return 1; +} + +int spPoolPut ( SP_PriPoolEle * pPri, CO_Pool * pCoPool ) +{ + CO_PoolEle *pPoolEle; + + spWatchDogStatic ( PUT_ELE_APT ); + + if( pCoPool->uPoolCount > pCoPool->uMaxPoolSize ) + { + spLogDebug ( SCCPDB_ERR, "SCCP put Primitive Pool fail , pool full" ); + return 0; + } + +//commentted by roy jiang to disable dynamic memory allocation, 07-11-16 +// pPoolEle = ( CO_PoolEle * ) malloc ( sizeof ( CO_PoolEle ) ); + pPoolEle = spMallocEle(); + if( NULL == pPoolEle ) + { + spLogDebug ( SCCPDB_ERR, "SCCP put Primitive Pool fail ,allocate memery fail" ); + return 0; + } + + memcpy ( &pPoolEle->tPri, pPri, sizeof ( SP_PriPoolEle ) ); + POOL_INSERT_TAIL ( pCoPool->pPoolHead, pPoolEle, tPointer ); + pCoPool->uPoolCount++; + + spWatchDogStatic ( PUT_ELE_SUC ); + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// Reserved for Pool Test -- Start +/////////////////////////////////////////////////////////////////////////// +/* + FILE *fp; + + int main() + { + int nCh; + CO_PoolEle pOutGetPri; + CO_PoolEle pInGetPri; + CO_PoolEle pOutPutPri; + CO_PoolEle pInPutPri; + CO_PoolEle *pPri; + + fp = fopen("log.txt" ,"w+"); + if( NULL ==fp ) + { + return 0; + } + spPoolInit(); + + pOutGetPri.tPri.ch = pInGetPri.tPri.ch = '0'; + + for( nCh = 0 ; nCh < 32 ; nCh ++ ) + { + memset(&pOutGetPri , 0 , sizeof(CO_PoolEle)); + memset(&pInGetPri , 0 , sizeof(CO_PoolEle)); + memset(&pOutPutPri , 0 , sizeof(CO_PoolEle)); + memset(&pInPutPri , 0 , sizeof(CO_PoolEle)); + + pOutPutPri.tPri.ch = 'A' + nCh; + spPoolPut( &pOutPutPri.tPri , pOutCoPool); + + pInPutPri.tPri.ch = 'Z' - nCh; + spPoolPut( &pInPutPri.tPri , pInCoPool); + + if( nCh && (nCh % 4 == 0) ) + { + spPoolGet( &pOutGetPri.tPri , pOutCoPool); + } + + if( nCh && (nCh % 6 == 0 ) ) + { + spPoolGet( &pInGetPri.tPri , pInCoPool); + } + + fprintf( fp ,"\npOutPoolHead: [%d]\n" , pOutCoPool->uPoolCount); + fprintf( fp ," Out Put : %c\n" , pOutPutPri.tPri.ch); + fprintf( fp ," Out Get : %c\n" , pOutGetPri.tPri.ch); + fprintf( fp ," List :"); + + POOL_FOREACH( pPri , pOutCoPool->pPoolHead , tPointer ) + { + fprintf( fp ,"%c " ,pPri->tPri.ch ); + } + fprintf( fp ,"\n"); + + fprintf( fp ,"\npInPoolHead: [%d]\n" , pInCoPool->uPoolCount); + fprintf( fp ," Put : %c\n" , pInPutPri.tPri.ch); + fprintf( fp ," Get : %c\n" , pInGetPri.tPri.ch); + fprintf( fp ," List :"); + POOL_FOREACH( pPri , pInCoPool->pPoolHead , tPointer ) + { + fprintf( fp ,"%c " ,pPri->tPri.ch ); + } + fprintf( fp ,"\n\n\n"); + + } + fclose(fp); + getchar(); + return 1; + + } + */ +/////////////////////////////////////////////////////////////////////////// +// Reserved for Pool Test -- End +/////////////////////////////////////////////////////////////////////////// + +/*@end@*/ diff --git a/plat/sccp/src/scoc_pri.c b/plat/sccp/src/scoc_pri.c new file mode 100644 index 0000000..103d9f9 --- /dev/null +++ b/plat/sccp/src/scoc_pri.c @@ -0,0 +1,283 @@ +////////////////////////////////////////////////// +//Title : scoc_pri.c +//Auhtor : Liu Wei +//Desc : SCOC Primitive implemetation +//Created : 2007-05-07 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// Note: The file is reserved , discard in Loose coupling mode now +/////////////////////////////////////////////////////////////////////////// + +#include "./include/sccp_pub.h" + +#ifdef LOOSE_COUPLING_MODE //Loose coupling mode + +#else + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_UnitDataReq ( SCCP_ADDR * pCDA, SCCP_ADDR * pCGA, SP_SEQ * pSEQ, SP_RO * pRO, SP_UD * pUD ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_UnitDataInd ( SCCP_ADDR * pCDA, SCCP_ADDR * pCGA, SP_UD * pUD ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_NoticeInd ( SCCP_ADDR * pCDA, SCCP_ADDR * pCGA, SP_RR * pRR, SP_UD * pUD ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ConnectReq ( SCCP_ADDR * pCDA, SCCP_ADDR * pCGA, SP_RCS * pRCS, SP_EDS * pEDS ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ConnectInd ( SP_QOS * pQOS, SP_UD * pUD, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ConnectRsp ( SP_RA * pRA, SP_RCS * pRCS, SP_EDS * pEDS ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ConnectCfm ( SP_QOS * pQOS, SP_UD * pUD, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_DisconnectReq ( SP_RA * pRA, SP_REA * pREA, SP_UD * pUD, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_DisconnectInd ( SP_OR * pOR, SP_RA * pRA, SP_REA * pREA, SP_UD * pUD, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_DataReq ( CR SP_UD * pUD, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_DataInd ( ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_DataAkReq ( u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_DataAkInd ( ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_EDataReq ( SP_UD * pUD, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_EDataInd ( ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ResetReq ( SP_REA * pREA, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ResetInd ( SP_OR * pOR, SP_REA * pREA, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ResetRsp ( u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_ResetCfm ( ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_InformReq ( SP_REA * pREA, SP_QOS * pQOS, u8 uCI ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_N_InformInd ( ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spLi_MTP_TransferReq ( sccpmsg ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spLi_MTP_TransferInd ( sccpmsg ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spLi_MTP_ResumeInd ( PC ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spLi_MTP_StatusInd ( PC ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spLi_MTP_UPUInd ( PC ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_ISUP_ReqType1 ( ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_ISUP_ReqType2 ( ) +{ + return; +} + +/////////////////////////////////////////////////////////////////////////// +// /// +/////////////////////////////////////////////////////////////////////////// + +void spUi_ISUP_Relay ( ) +{ + return; +} + +#endif diff --git a/plat/sccp/src/scrc.c b/plat/sccp/src/scrc.c new file mode 100644 index 0000000..011f5aa --- /dev/null +++ b/plat/sccp/src/scrc.c @@ -0,0 +1,1974 @@ + + +/***************************************************************/ + +/*Title: scrc.c */ + +/*Descr: SCCP Routing Control Procedure */ + +/*Author: Liang Hanxi */ + +/*Create: 2002-2-19 */ + +/*Modify: 2003-5-9 */ + + + +/***************************************************************/ + +#include "./include/sccp.h" + +#include "./include/sccp_pub.h" + +#include "../../public/src/include/pub_netcap.h" + + + +extern int sccp_send_netcap ; + + + +/*===========export================*/ + +void scrc_timer ( ); + +int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); + +int scrc_mnp_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ); + +int send_msg ( Intra_Msg * pIntraMsg, BYTE ansi_flag ); + +int scrc_rf ( Intra_Msg * pIntraMsg, BYTE AnsiFlag ); + +DWORD SelectIPOfSSN ( BYTE ssn, BYTE sls, BOOL from_mtp ); + + + +/*===========import================*/ + +extern int SegmentingMsg ( Intra_Msg * pIntraMsg ); //sclc.c + +extern int build_msg ( BYTE * buf, Intra_Msg * intramsg, BYTE NetID, BYTE ansi_flag ); + +extern int parse_msg ( BYTE * buf, Intra_Msg * intramsg, int len, BYTE NetID, BYTE ansi_flag ); //sccpmsg.c + +extern int scrc2scoc ( Intra_Msg * intramsg, BYTE AnsiFlag ); + +extern int scoc_store ( up_message * sccpmsg ); + +extern int Digits2Array ( BYTE * pArray, BYTE * pDigits, int DigitsLen ); + +extern u_short SelectRoute ( BYTE * pDigits, BYTE DigitsLen ); + +extern void TranslateGT ( SCCP_ADDR * addr, SCCP_ROUTE * pRoute ); + +extern int sclc2scmg ( Intra_Msg * intramsg ); + +extern BOOL CheckAvail ( SCCP_ADDR * addr ); + +extern int scrc2sclc ( Intra_Msg * pIntraMsg ); + +extern int sclc_rf ( Intra_Msg * pIntraMsg ); + +extern BOOL isco ( Intra_Msg * intramsg ); + +extern void snmpLogInfo ( char *logInfo ); + +extern int need_mnp(u8 mnp_type, u8 src_ssn, u8 dst_ssn, u8 *src_digits, u8 digits_len, u8 msg_begin); + + + +/*===========private================*/ + +static int mtp2scrc ( up_message * pMsgFromMTP ); + +void sccp_put_capture_logs ( BYTE person, BYTE * pictures, int len ); + +int get_sls(int dpc); + +/******************************************************************/ + + + +/*==================Interface function----->================*/ + + + +/******************************************************************/ + +void scrc_timer ( ) //called per 20ms + +//read messge from mtp buffer + +{ + + up_message MsgFromMTP3; + + BYTE loop = 128; + + + + while ( loop-- > 0 ) + + { + + if( sccp_GetMsg ( &MsgFromMTP3 ) > 0 ) + + mtp2scrc ( &MsgFromMTP3 ); + + else + + break; + + } + +} + + + +u32 dAlterIpBackup; //for protection + +int mtp2scrc ( up_message * pMsgFromMTP ) + +{ + + Intra_Msg msgin; + + BOOL ForceAnsi = 0; + + int mask; + + u8 *pStr; + + + + SccpCsta[SccpCstaInd].utilization[0]++; + + + + memset ( &msgin, 0, sizeof ( Intra_Msg ) ); + + msgin.NetID = msgin.CGA.NetID = msgin.CDA.NetID = pMsgFromMTP->sio >> 6; + + msgin.DPC = pMsgFromMTP->dpc; + + msgin.OPC = pMsgFromMTP->opc; + + msgin.SLS = pMsgFromMTP->cic[0] & 0x0F; + + msgin.link = pMsgFromMTP->link; + + + + ForceAnsi = ( pMsgFromMTP->sio >> 4 ) & 1; + + parse_msg ( pMsgFromMTP->msgList, &msgin, pMsgFromMTP->len, msgin.NetID, ForceAnsi ); + + + + if( msgin.CDA.len > ( MAX_DIGITS * 2 ) ) + + { + + SCCPCapBuf.watch_dog[14]++; + + sccp_put_capture_logs ( 03, ( BYTE * ) pMsgFromMTP, sizeof ( up_message ) ); + + spLogDebug ( SCCPDB_ERR, "SCCP RV Invalid Message from MTP3,CDA.len=%d, len is over range, the Message was captured", msgin.CDA.len ); + + } + + + + msgin.msgsource = FROM_MTP; + + + + // if( msgin.CGA.DPC == SCCP_Param.spc[msgin.NetID] ) + if(mtp3_check_dpc_equal_to_opc(msgin.NetID, msgin.CGA.DPC)) + + msgin.CGA.ip = pMsgFromMTP->dest_ip; + + else + + msgin.CGA.ip = INADDR_NONE; + + msgin.CDA.ip = INADDR_NONE; + + + + switch ( msgin.msgtype ) + + { + + case UDT_MSG: + + SccpCsta[SccpCstaInd].quality[2]++; + + spShowMsg ( SCCPDB_MTP3, "SCCP <== MTP3. UDT Message", &msgin ); + + return scrc_route ( &msgin, ForceAnsi ); + + case UDTS_MSG: + + SccpCsta[SccpCstaInd].quality[3]++; + + spShowMsg ( SCCPDB_MTP3, "SCCP <== MTP3. UDTS Message", &msgin ); + + return scrc_route ( &msgin, ForceAnsi ); + + case XUDT_MSG: + + //SccpCsta[SccpCstaInd].quality[3]++; + + mask = 0; + + if( msgin.SegPresent == 1 ) + + { + + mask |= SCCPDB_XUDT; + + } + + + + spShowMsg ( SCCPDB_MTP3 | mask, "SCCP_RegProc <== SCCP <== MTP3. XUDT Message", &msgin ); + + return scrc_route ( &msgin, ForceAnsi ); + + case XUDTS_MSG: + + //SccpCsta[SccpCstaInd].quality[3]++; + + spShowMsg ( SCCPDB_MTP3, "SCCP <== MTP3. XUDTS Message", &msgin ); + + return scrc_route ( &msgin, ForceAnsi ); + + case CR_MSG: + + SccpCsta[SccpCstaInd].quality[6]++; + + spShowMsg ( SCCPDB_AIF, "SCCP <== MTP3. CR Message", &msgin ); + + return scrc_route ( &msgin, ForceAnsi ); + + case DT1_MSG: + + case CC_MSG: + + case DT2_MSG: + + case RLSD_MSG: + + case RLC_MSG: + + case CREF_MSG: + + case AK_MSG: + + case IT_MSG: + + //message redirect, add by Roy Jiang + + if (msgin.aDLR[0] != pSp->dSysID //not local system + + && msgin.aDLR[0] <= 2 && msgin.aDLR[0] != 0) //only system 1 & system 2 + + { + + //dual server mode and the message is to the other server + + if(pSp->dAlterIP == 0) + + { + + if (dAlterIpBackup != 0){ + + spLogDebug ( SCCPDB_ERR, "Fatal error, memory corrupted, pSp->dAlterIp = 0."); + + pSp->dAlterIP = dAlterIpBackup; + + } + + else + + return 0; + + } + + msgin.CDA.ip = pSp->dAlterIP; + + msgin.msgsource = FROM_MTP; + + msgin.redirectFlag = 1; + + //send_msg ( &msgin, 0 ); //uAnsiFlag = 0; + + pMsgFromMTP->dest_ip = pSp->dAlterIP; + + pMsgFromMTP->link = 0xff; + + sccp_redirect(pMsgFromMTP); + + spGetMsgStr ( msgin.msgtype, pStr ); + + spShowMsg(SCCPDB_MTP3, "Message redirected. SCCP ==> MTP3.", &msgin); + +// spLogDebug ( SCCPDB_AIF, "Message redirected. CO-%s, NetID=%d, msglen=%d", pStr, msgin.NetID, msgin.msglen ); + + return 0; + + } + + if( msgin.msgtype == DT1_MSG ) + + SccpCsta[SccpCstaInd].utilization[9 - 3]++; + + else if( msgin.msgtype == DT1_MSG ) + + SccpCsta[SccpCstaInd].utilization[11 - 3]++; + + + + spGetMsgStr ( msgin.msgtype, pStr ); + + spLogDebug ( SCCPDB_AIF, "SCCP <== MTP3. CO-%s, NetID=%d, msglen=%d ", pStr, msgin.NetID, msgin.msglen ); + + + + { + + char digits1[24], digits2[24]; //, info[256]; + + + + BcdToAscii ( digits1, msgin.aSLR, 6 ); + + digits1[6] = 0; + + BcdToAscii ( digits2, msgin.aDLR, 6 ); + + digits2[6] = 0; + + spLogDebug ( SCCPDB_AIF,"SLR = %s DLR = %s ", digits1, digits2 ); + + } + + spShowBCD ( SCCPDB_AIF, ( BYTE * ) pMsgFromMTP, ( pMsgFromMTP->len + 17 ) % 256 ); + + + +#ifndef _WXC_TEST + +/* + + if( SCCP_Param.CO_SSN <= 1 ) + + return scrc_rf ( &msgin, ForceAnsi ); + + + + msgin.CDA.ip = SelectIPOfSSN ( SCCP_Param.CO_SSN, msgin.SLS, 1 ); + + + + if( msgin.CDA.ip == SCCP_Param.ip ) + + { + + return scoc_store ( pMsgFromMTP ); + + } + + else if( msgin.CDA.ip == 0 ) + + return scrc_rf ( &msgin, ForceAnsi ); + + else + + return send_msg ( &msgin, ForceAnsi ); + +*/ + +#endif + + //need to modify + + cr2co ( &msgin, ForceAnsi ); + + return 1; + + //break; + + default: + + spLogDebug ( SCCPDB_ERR, "SCCP <== MTP3. Not support Message(type=%02x), NetID=%d, msglen=%d", msgin.msgtype, msgin.NetID, msgin.msglen ); + + spShowBCD ( SCCPDB_ERR, ( BYTE * ) pMsgFromMTP, ( pMsgFromMTP->len + 17 ) % 256 ); + + SCCPCapBuf.watch_dog[12]++; //invalid message + + SCCPCapBuf.watch_dog[13] = msgin.msgtype; //invalid message + + + + } + + return 0; + +} + + + +/******************************************************************/ + + + +/*========== Routing Control Procedure-----> ===========*/ + + + +/******************************************************************/ + +int scrc_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ) + +{ + + SCCP_ADDR *pAddr = NULL, DstAddr; + + SCCP_ROUTE *pRoute = NULL; + + int LocalSPC; + + u_short nRoute = 0xFFFF; + + BYTE Num[32], NumLen; + + BYTE routeAI; + + BYTE field = 0; + + + SccpCsta[SccpCstaInd].utilization[0]++; + + pIntraMsg->msgMNP = 0; + + + + pAddr = &pIntraMsg->CDA; + + /* daniel */ + + pAddr->AI = 1; //default to include DPC + + pIntraMsg->CGA.AI = 1; //default to include DPC + + /* daniel */ + + memcpy ( &DstAddr, pAddr, sizeof ( SCCP_ADDR ) ); + + + + if( pAddr->RI == RI_SSN && pAddr->DPC == 0 ) + + { + + if( pAddr->NetID > 3 ) + + { + + spLogDebug ( SCCPDB_ERR, "<011>SCCP Translation:SPC not available" ); + + SccpCsta[SccpCstaInd].error[0]++; + + return -1; + + } + + DstAddr.DPC = SCCP_Param.spc[pAddr->NetID]; + + } + + //Route On GT + + if( DstAddr.RI == RI_GT || DstAddr.DPC == 0 || DstAddr.SSN == 0 || DstAddr.NetID > 3 ) + + { + + SccpCsta[SccpCstaInd].utilization[5 - 3]++; + + if( pIntraMsg->CDA.GTI == 0 ) + + { + + pIntraMsg->cause = RT_NTFN; + + spLogDebug ( SCCPDB_ERR, "<011>SCCP Translation:GTI == 0 (4 is recommended)" ); + + SccpCsta[SccpCstaInd].error[1]++; + + return -1; + + } + + /* if(pIntraMsg->CDA.TT != 0) + + { + + spLogDebug(SCCPDB_ERR, "<012>SCCP Translation:no translation for an address of such nature(TT=%d)", pIntraMsg->CDA.TT); + + pIntraMsg->cause = RT_NTFN; + + SccpCsta[SccpCstaInd].error[0] ++; + + return -1; + + } */ + + + + if( pAddr->len > ( MAX_DIGITS * 2 ) ) + + { + + SCCPCapBuf.watch_dog[0]++; + + sccp_put_capture_logs ( 01, ( BYTE * ) pIntraMsg, sizeof ( Intra_Msg ) ); + + spLogDebug ( SCCPDB_ERR, "<014>SCCP Receive Invalid Message,GTT len=%d, the Message was discarded and captured", pAddr->len ); + + return -2; + + } + + + + if( pAddr->NP > 0 ) + + Num[field++] = pAddr->NP; + + else + + Num[field++] = NP_MSISDN; + + if( pAddr->TT > 0 ) + + { + + Num[field++] = pAddr->TT / 100; + + Num[field++] = ( pAddr->TT / 10 ) % 10; + + Num[field++] = pAddr->TT % 10; + + } + + else + + { + + Num[field++] = TT_0; + + Num[field++] = TT_1; + + //Num[field++] = TT_4; + Num[field++] = TT_0; + + } + + NumLen = pAddr->len % ( MAX_DIGITS * 2 ); + + Digits2Array ( Num + field, pAddr->GTAI, ( NumLen + 1 ) / 2 ); + + nRoute = SelectRoute ( Num, NumLen + field ); + + + + if( nRoute < SCCP_ROUTE_NUM ) + + { + + pRoute = &RouteList[nRoute]; + + + + if( (DstAddr.NetID != pRoute->NetID) && (pIntraMsg->msgsource == FROM_MTP) ) + pIntraMsg->CGA.RI = RI_GT; + //else if( pIntraMsg->msgsource != FROM_MTP ) + // pIntraMsg->CGA.RI = pRoute->RI; + + /* Pierre 2009-08-07, for IN-MNP */ +/* + if( pIntraMsg->msgsource != FROM_MTP ) + pIntraMsg->CGA.RI = pRoute->RI; + else if( DstAddr.NetID != pRoute->NetID ) + pIntraMsg->CGA.RI = RI_GT; +*/ + /* daniel */ + + DstAddr.NetID = pRoute->NetID; + + + + if( pRoute->SSN > 0 ) + + pAddr->SSN = DstAddr.SSN = pRoute->SSN; + + + + pAddr->RI = pRoute->RI; + + DstAddr.DPC = pRoute->DPC[0] * 0x10000 + pRoute->DPC[1] * 0x100 + pRoute->DPC[2]; + + + + if(( pIntraMsg->CGA.SSN != 10 ) && ( DstAddr.SSN == 6 && DstAddr.NP == 1 && pIntraMsg->data[0] == 0x62 ) && (MNP_Flag[0] != 0)) + + {// MNP neednot convert GT + + if(!((pRoute->ReplaceStart == 1) && (pRoute->ReplaceEnd == pAddr->len))) + + { + + if( pRoute->convert ) + + { + + DstAddr.RI = pAddr->RI; + + TranslateGT ( &DstAddr, pRoute ); + + memcpy ( pAddr, &DstAddr, sizeof ( SCCP_ADDR ) ); + + } + + } + + } + + else if( pRoute->convert ) + + { + + DstAddr.RI = pAddr->RI; + + TranslateGT ( &DstAddr, pRoute ); + + memcpy ( pAddr, &DstAddr, sizeof ( SCCP_ADDR ) ); + + } + + + + /* daniel */ + + routeAI = pRoute->AI; + + //set calling address + + if( pIntraMsg->CGA.RI == 0 ) //route on GT + + { + + if( ( routeAI & 1 ) == 0 ) //point code no need + + pIntraMsg->CGA.AI &= ~1; //set dpc=0 + + } + + else //route on DPC+SSN + + { + + if( ( routeAI & 4 ) == 0 ) //GT no need + + pIntraMsg->CGA.GTI = 0; //set GT=0 + + } + + + + //set called address + + if( pAddr->RI == 0 ) //route on GT + + { + + if( ( routeAI & 1 ) == 0 ) //point code no need + + pAddr->AI &= ~1; //set dpc=0 + + } + + else //route on DPC+SSN + + { + + if( ( routeAI & 4 ) == 0 ) //GT no need + + pAddr->GTI = 0; //set GTI=0 + + } + + /* daniel */ + + + + } + + else if( nRoute >= 1024 && nRoute < 1024 + 256 ) //local Node + { + /* + if(pAddr->SSN == 0) + pAddr->SSN = DstAddr.SSN = nRoute - 1024; + else + DstAddr.SSN = pAddr->SSN; + */ + pAddr->SSN = DstAddr.SSN = nRoute - 1024; + + if( DstAddr.NetID > 3 ) + DstAddr.NetID = LocalSSN[DstAddr.SSN].NetID; + + pAddr->RI = RI_SSN; + + DstAddr.DPC = SCCP_Param.spc[DstAddr.NetID & 3]; + + } + else + + { + + pIntraMsg->cause = RT_NTFA; + + SccpCsta[SccpCstaInd].avail[1]++; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + } + + if( !CheckAvail ( &DstAddr ) ) + + { + + pIntraMsg->cause = RT_SF; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + + + pIntraMsg->NetID = DstAddr.NetID % 4; //0~3 + + pIntraMsg->DPC = pAddr->DPC = DstAddr.DPC; + + LocalSPC = SCCP_Param.spc[pIntraMsg->NetID]; + + + + if (pIntraMsg->CGA.RI == RI_SSN) + + { + + if (pIntraMsg->CGA.DPC == 0) + + { + + pIntraMsg->CGA.DPC = pIntraMsg->OPC; + + } + + } + + + + if (pIntraMsg->CGA.RI == RI_SSN) + + { + + if (pIntraMsg->CGA.DPC == 0) + + { + + pIntraMsg->CGA.DPC = pIntraMsg->OPC; + + } + + } + + if( DstAddr.DPC != SCCP_Param.spc[DstAddr.NetID & 3]) + { + pIntraMsg->CGA.DPC = SCCP_Param.spc[DstAddr.NetID & 3];// GTT opc issue + pIntraMsg->OPC = SCCP_Param.spc[DstAddr.NetID & 3];// GTT opc issue + } + + +// if( DstAddr.DPC != LocalSPC ) + if(!mtp3_check_dpc_equal_to_opc(DstAddr.NetID, DstAddr.DPC)) + + { + + snmpLogInfo ( "scrc_route(): start.... 266" ); + + + + if (pIntraMsg->sequenceFlag == 1 && pIntraMsg->msgtype == UDT_MSG){ + + pIntraMsg->SLS = get_sls(pIntraMsg->DPC); //in-sequence delivery, add by Roy Jiang, 07-09-26 + + pIntraMsg->msgclass = 1; + + } + + if( ForceAnsi ) + + return send_msg ( pIntraMsg, 1 ); + + else + + return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + else if( pIntraMsg->msgtype == UDTS_MSG && pIntraMsg->msgsource == FROM_MTP) //discast UDTS message to local node + + return 1; + + + + if( DstAddr.SSN == 0 ) + + { + + pIntraMsg->cause = RT_UU; + + spLogDebug ( SCCPDB_ERR, "<013>Invalid SSN(0)" ); + + SccpCsta[SccpCstaInd].error[2]++; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + + + if( DstAddr.SSN == 1 ) //scmg message + + return sclc2scmg ( pIntraMsg ); + + + +#ifdef _WXC_SPTEST_TEMP + + //just for test , delete it for normal + + if( pAddr->ip == INADDR_NONE && pIntraMsg->msgsource == FROM_MTP ) + + { + + if( ( pIntraMsg->msgtype >= CR_MSG && pIntraMsg->msgtype <= AK_MSG ) ) + + { + + if( ForceAnsi ) + + return cr2co ( pIntraMsg, 1 ); + + else + + return cr2co ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + else + + { + +// if( MNP_Flag[0] == 0 || pIntraMsg->msgsource != FROM_MTP || (MNP_Flag==1 && pIntraMsg->CGA.SSN == 8 ) /* MNP not supported or msc already sent AIN*/ + + if(pIntraMsg->msgsource != FROM_MTP || !need_mnp(MNP_Flag[0], pIntraMsg->CGA.SSN, pIntraMsg->CDA.SSN, pIntraMsg->CGA.GTAI, pIntraMsg->CGA.len, 0x62) || pIntraMsg->CGA.DPC==pIntraMsg->CDA.DPC) + + return scrc2sclc ( pIntraMsg ); + + + + /* SCCP Steering Function */ + + /* message received or sent */ + + /* MNP supported */ + + /* routing method */ + + pIntraMsg->msgMNP = 0; + + + + if( DstAddr.SSN == 6 && DstAddr.NP == 1 && pIntraMsg->data[0] == 0x62 ) + + { + + /* IN_Based and SRI for voice call */ + + if( MNP_Flag[0] == 1 && DstAddr.TT != 0 ) + + { + + pIntraMsg->msgMNP = 0; + + } + + else if( pIntraMsg->CGA.SSN != 10 ) + + { + + pIntraMsg->msgMNP = 1; + + } + + return scrc2sclc ( pIntraMsg ); + + } + + else + + { + + return scrc2sclc ( pIntraMsg ); + + } + + } + + } + +#endif + + + + pAddr->ip = SelectIPOfSSN ( DstAddr.SSN, pIntraMsg->SLS, ( pIntraMsg->msgsource == FROM_MTP ) ); + + + + if( pAddr->ip == SCCP_Param.ip ) //local Node + { + if( ( pIntraMsg->msgtype >= CR_MSG && pIntraMsg->msgtype <= AK_MSG ) ) + + { + + if( ForceAnsi ) + + return cr2co ( pIntraMsg, 1 ); + + else + + return cr2co ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + else + + { + + if( sccp_send_netcap) + + { + + int len; + + up_message MsgToMTP; + + int ansi_flag ; + + if( ForceAnsi ) + + ansi_flag = 1; + + else + + ansi_flag = mtp3_ansiFlag(DstAddr.NetID); + + + + len = build_msg ( MsgToMTP.msgList, pIntraMsg, pIntraMsg->NetID ,ansi_flag ); + + MsgToMTP.len = len%256; + + NcSccpSend( MsgToMTP.msgList , MsgToMTP.len , (u8 *)pIntraMsg , ansi_flag); + + } + + + + + + if( MNP_Flag[0] == 0 || pIntraMsg->msgsource != FROM_MTP || (MNP_Flag[0]==1 && pIntraMsg->CGA.SSN == 8 )) /* MNP not supported or msc already sent AIN*/ + + return scrc2sclc ( pIntraMsg ); + + + + /* SCCP Steering Function */ + + /* message received or sent */ + + /* MNP supported */ + + /* routing method */ + + pIntraMsg->msgMNP = 0; + + + + if( DstAddr.SSN == 6 && DstAddr.NP == 1 && pIntraMsg->data[0] == 0x62 ) + + { + + /* IN_Based and SRI for voice call */ + + if( MNP_Flag[0] == 1 && DstAddr.TT != 0 ) + + { + + pIntraMsg->msgMNP = 0; + + } + + else if( pIntraMsg->CGA.SSN != 10 ) + + { + + pIntraMsg->msgMNP = 1; + + } + + return scrc2sclc ( pIntraMsg ); + + } + + else + + { + + return scrc2sclc ( pIntraMsg ); + + } + + } + + } + + else if( pAddr->ip == 0 ) //none subsystem is reachable + { + + pIntraMsg->cause = RT_SF; + + SccpCsta[SccpCstaInd].error[3]++; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + else //relay to specify subsystem + { + + snmpLogInfo ( "scrc_route(): start... 327" ); + + if( ForceAnsi ) + + return send_msg ( pIntraMsg, 1 ); + + else + + return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + +} + + + +int scrc_mnp_route ( Intra_Msg * pIntraMsg, BOOL ForceAnsi ) + +{ + + SCCP_ADDR *pAddr = NULL, DstAddr; + + SCCP_ROUTE *pRoute = NULL; + + int LocalSPC, i; + + u_short nRoute = 0xFFFF; + + BYTE Num[32], NumLen; + + BYTE routeAI; + + BYTE field = 0; + + + + SccpCsta[SccpCstaInd].utilization[0]++; + + + + pAddr = &pIntraMsg->CDA; + + /* daniel */ + + pAddr->AI = 1; //default to include DPC + + pIntraMsg->CGA.AI = 1; //default to include DPC + + /* daniel */ + + memcpy ( &DstAddr, pAddr, sizeof ( SCCP_ADDR ) ); + + + + if( pAddr->RI == RI_SSN && pAddr->DPC == 0 ) + + { + + if( pAddr->NetID > 3 ) + + { + + spLogDebug ( SCCPDB_ERR, "<021>SCCP Translation:SPC not available" ); + + SccpCsta[SccpCstaInd].error[0]++; + + return -1; + + } + + DstAddr.DPC = SCCP_Param.spc[pAddr->NetID]; + + } + + //Route On GT + + if( DstAddr.RI == RI_GT || DstAddr.DPC == 0 || DstAddr.SSN == 0 || DstAddr.NetID > 3 ) + + { + + SccpCsta[SccpCstaInd].utilization[5 - 3]++; + + if( pIntraMsg->CDA.GTI == 0 ) + + { + + pIntraMsg->cause = RT_NTFN; + + spLogDebug ( SCCPDB_ERR, "<021>SCCP Translation:GTI == 0 (4 is recommended)" ); + + SccpCsta[SccpCstaInd].error[1]++; + + return -1; + + } + + /* if(pIntraMsg->CDA.TT != 0) + + { + + spLogDebug(SCCPDB_ERR, "<012>SCCP Translation:no translation for an address of such nature(TT=%d)", pIntraMsg->CDA.TT); + + pIntraMsg->cause = RT_NTFN; + + SccpCsta[SccpCstaInd].error[0] ++; + + return -1; + + } */ + + + + if( pAddr->len > ( MAX_DIGITS * 2 ) ) + + { + + SCCPCapBuf.watch_dog[0]++; + + sccp_put_capture_logs ( 01, ( BYTE * ) pIntraMsg, sizeof ( Intra_Msg ) ); + + spLogDebug ( SCCPDB_ERR, "<024>SCCP Receive Invalid Message,GTT len=%d, the Message was discarded and captured", pAddr->len ); + + return -2; + + } + + + + if( pAddr->NP > 0 ) + + Num[field++] = pAddr->NP; + + else + + Num[field++] = NP_MSISDN; + + if( pAddr->TT > 0 ) + + { + + Num[field++] = pAddr->TT / 100; + + Num[field++] = ( pAddr->TT / 10 ) % 10; + + Num[field++] = pAddr->TT % 10; + + } + + else + + { + + Num[field++] = TT_0; + + Num[field++] = TT_1; + + //Num[field++] = TT_4; + Num[field++] = TT_0; + + } + + NumLen = pAddr->len % ( MAX_DIGITS * 2 ); + + Digits2Array ( Num + field, pAddr->GTAI, ( NumLen + 1 ) / 2 ); + + nRoute = SelectRoute ( Num, NumLen + field ); + + + + if( nRoute < SCCP_ROUTE_NUM ) + + { + + pRoute = &RouteList[nRoute]; + + + + if( (DstAddr.NetID != pRoute->NetID) && (pIntraMsg->msgsource == FROM_MTP) ) + pIntraMsg->CGA.RI = RI_GT; + //else if( pIntraMsg->msgsource != FROM_MTP ) + // pIntraMsg->CGA.RI = pRoute->RI; + + /* Pierre 2009-08-07, for IN-MNP */ +/* + if( pIntraMsg->msgsource != FROM_MTP ) + pIntraMsg->CGA.RI = pRoute->RI; + else if( DstAddr.NetID != pRoute->NetID ) + pIntraMsg->CGA.RI = RI_GT; +*/ + + DstAddr.NetID = pRoute->NetID; + + + + if( pRoute->SSN > 0 ) + + pAddr->SSN = DstAddr.SSN = pRoute->SSN; + + + + pAddr->RI = pRoute->RI; + + DstAddr.DPC = pRoute->DPC[0] * 0x10000 + pRoute->DPC[1] * 0x100 + pRoute->DPC[2]; + + + + if( pRoute->convert ) + + { + + DstAddr.RI = pAddr->RI; + + TranslateGT ( &DstAddr, pRoute ); + + memcpy ( pAddr, &DstAddr, sizeof ( SCCP_ADDR ) ); + + } + + + + /* daniel */ + + routeAI = pRoute->AI; + + //set calling address + + if( pIntraMsg->CGA.RI == 0 ) //route on GT + + { + + if( ( routeAI & 1 ) == 0 ) //point code no need + + pIntraMsg->CGA.AI &= ~1; //set dpc=0 + + } + + else //route on DPC+SSN + + { + + if( ( routeAI & 4 ) == 0 ) //GT no need + + pIntraMsg->CGA.GTI = 0; //set GT=0 + + } + + + + //set called address + + if( pAddr->RI == 0 ) //route on GT + + { + + if( ( routeAI & 1 ) == 0 ) //point code no need + + pAddr->AI &= ~1; //set dpc=0 + + } + + else //route on DPC+SSN + + { + + if( ( routeAI & 4 ) == 0 ) //GT no need + + pAddr->GTI = 0; //set GTI=0 + + } + + /* daniel */ + + + + } + + else if( nRoute >= 1024 && nRoute < 1024 + 256 ) //local Node + + { + + pAddr->SSN = DstAddr.SSN = nRoute - 1024; + + if( DstAddr.NetID > 3 ) + + DstAddr.NetID = LocalSSN[DstAddr.SSN].NetID; + + + + pAddr->RI = RI_SSN; + + DstAddr.DPC = SCCP_Param.spc[DstAddr.NetID & 3]; + + } + + else + + { + + pIntraMsg->cause = RT_NTFA; + + SccpCsta[SccpCstaInd].avail[1]++; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + } + + if( !CheckAvail ( &DstAddr ) ) + + { + + pIntraMsg->cause = RT_SF; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + + + pIntraMsg->NetID = DstAddr.NetID % 4; //0~3 + + pIntraMsg->DPC = pAddr->DPC = DstAddr.DPC; + + LocalSPC = SCCP_Param.spc[pIntraMsg->NetID]; + + + +// if( DstAddr.DPC != LocalSPC ) + if(!mtp3_check_dpc_equal_to_opc(pIntraMsg->NetID, DstAddr.DPC)) + { + + snmpLogInfo ( "mnp_scrc_route(): start... 471" ); + + + + if (pIntraMsg->sequenceFlag == 1 && pIntraMsg->msgtype == UDT_MSG){ + + pIntraMsg->SLS = get_sls(pIntraMsg->DPC); //in-sequence delivery, add by Roy Jiang, 07-09-26 + + } + + + + if( ForceAnsi ) + + return send_msg ( pIntraMsg, 1 ); + + else + + return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + //snmpLogInfo ( "mnp_scrc_route(): end... 471" ); + + } + + else if( pIntraMsg->msgtype == UDTS_MSG ) //discast UDTS message to local node + + return 1; + + + + if( DstAddr.SSN == 0 ) + + { + + pIntraMsg->cause = RT_UU; + + spLogDebug ( SCCPDB_ERR, "<023>Invalid SSN(0)" ); + + SccpCsta[SccpCstaInd].error[2]++; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + + + if( DstAddr.SSN == 1 ) //scmg message + + return sclc2scmg ( pIntraMsg ); + + + + pAddr->ip = SelectIPOfSSN ( DstAddr.SSN, pIntraMsg->SLS, ( pIntraMsg->msgsource == FROM_MTP ) ); + + + + pIntraMsg->msgMNP = 0; + + if( pAddr->ip == 0 ) //none subsystem is reachable + + { + + pIntraMsg->cause = RT_SF; + + SccpCsta[SccpCstaInd].error[3]++; + + if( ForceAnsi ) + + return scrc_rf ( pIntraMsg, 1 ); + + else + + return scrc_rf ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + + else if( pAddr->ip == SCCP_Param.ip ) //local Node + + { + for ( i = 0; i < SP_POOL_SIZE; i++ ) + { + if( pIntraMsg->msgtype == CR_MSG || ( DstAddr.SSN == SCCP_Param.CO_SSN[i] && SCCP_Param.CO_SSN[i] > 1 ) ) + + { + + if( ForceAnsi ) + + return cr2co ( pIntraMsg, 1 ); + + else + + return cr2co ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + } + + + return scrc2sclc ( pIntraMsg ); + + } + + else //relay to specify subsystem + + { + + snmpLogInfo ( "scrc_route(): start... 327" ); + + if( ForceAnsi ) + + return send_msg ( pIntraMsg, 1 ); + + else + + return send_msg ( pIntraMsg, mtp3_ansiFlag ( DstAddr.NetID ) ); + + } + +} + + + +int send_msg ( Intra_Msg * pIntraMsg, BYTE ansi_flag ) + +//pass message to mtp module + +{ + + int retval = 0; + + int len = 0; + + up_message MsgToMTP; + + + + pIntraMsg->DPC = pIntraMsg->CDA.DPC; + + + + if( pIntraMsg->msgsource != FROM_MTP && ( pIntraMsg->SLS & 0x80 ) == 0 ) + + { + + if( pIntraMsg->NetID > 3 ) + + { + + return 0; + + } + + pIntraMsg->CGA.DPC = SCCP_Param.spc[pIntraMsg->NetID]; + if(!pIntraMsg->OPC) + { + if(pIntraMsg->CGA.DPC!=0) + pIntraMsg->OPC = pIntraMsg->CGA.DPC; + else + pIntraMsg->OPC = SCCP_Param.spc[pIntraMsg->NetID]; + } + } + + + + snmpLogInfo ( "send_msg(), build_msg: start..." ); + + + + if( pIntraMsg->msglen > 256 ) + + return 0; + + len = build_msg ( MsgToMTP.msgList, pIntraMsg, pIntraMsg->NetID, ansi_flag ); + + + + /* + + MsgToMTP.len = build_msg ( MsgToMTP.msgList, pIntraMsg, pIntraMsg->NetID ); + + if( MsgToMTP.len > 256 ) MsgToMTP.len is a BYTE + + { + + return 0; //added by Pierre, 01-19-05 for core at following line + + } + + + + */ + + + + //add for UDT SegmentingMsg to XUDT + + if( len < 272 && ( len + 8 ) > 0xfd && pIntraMsg->msgtype == UDT_MSG && pIntraMsg->msgsource == FROM_SCLC + + && pIntraMsg->CDA.ip != 0 && pIntraMsg->CDA.ip != SCCP_Param.ip && pIntraMsg->CDA.ip != INADDR_NONE ) + + { //relay to special system msg too long ,need cut to segment -- add by lw 2007/03/20 + + spLogDebug ( SCCPDB_UDT, "UDT Message form upper layer is too long, [ %d Bytes(len=%d if include MTP3)]! " "Need to be segmented!\r\n ", pIntraMsg->msglen, len ); + + retval = SegmentingMsg ( pIntraMsg ); + + return retval; + + } + + + + if( len > 272)//256 ) + + { + + spLogDebug ( SCCPDB_ERR, "Build SCCP Message too long! " ); + + return 0; + + } + + MsgToMTP.len = len % 273;//256; + + snmpLogInfo ( "send_msg(), type message: start..." ); + + switch ( pIntraMsg->msgsource ) + + { + + case FROM_MTP: + + spShowMsg ( SCCPDB_STP, "SCCP ==> MTP3: STP", pIntraMsg ); + + break; + + case FROM_SCLC: + + switch ( pIntraMsg->msgtype ) + + { + + case UDT_MSG: + + SccpCsta[SccpCstaInd].quality[0]++; + + spShowMsg ( SCCPDB_UDT, "SCCP ==> MTP3:", pIntraMsg ); + + break; + + case UDTS_MSG: + + SccpCsta[SccpCstaInd].quality[1]++; + + spShowMsg ( SCCPDB_UDT, "SCCP ==> MTP3:", pIntraMsg ); + + break; + + case XUDT_MSG: //add for UDT SegmentingMsg to XUDT + + spShowMsg ( SCCPDB_XUDT, "SCCP ==> MTP3:", pIntraMsg ); + + break; + + case XUDTS_MSG: //add for UDT SegmentingMsg to XUDT + + spShowMsg ( SCCPDB_XUDT, "SCCP ==> MTP3:", pIntraMsg ); + + break; + + } + + break; + + case FROM_SCOC: + + spShowMsg ( SCCPDB_AIF, "SCCP ==> MTP3: AIF", pIntraMsg ); + + break; + + case FROM_SCMG: + + spShowMsg ( SCCPDB_SCMG, "SCCP ==> MTP3: SCMG", pIntraMsg ); + + break; + + } + + + + MsgToMTP.dest_ip = pIntraMsg->CDA.ip; + + MsgToMTP.dpc = pIntraMsg->DPC; + + MsgToMTP.opc = pIntraMsg->OPC; + + MsgToMTP.sio = pIntraMsg->NetID * 0x40 + 3; + + MsgToMTP.cic[0] = pIntraMsg->SLS & 0x0F; + + MsgToMTP.link = 0xff; + + + + if(pIntraMsg->redirectFlag == 1 && pIntraMsg->CDA.ip != 0xFFFFFFFF) //add by Roy to support sccp dual server message redirect, 07-09-12 + + retval = sccp_redirect ( &MsgToMTP ); + + else + + retval = sccp_to_mtp3 ( &MsgToMTP ); + + + + if( sccp_send_netcap) + + { + + NcSccpSend( MsgToMTP.msgList , MsgToMTP.len , (u8 *)pIntraMsg , ansi_flag ); + + } + + + + return retval; + + // return sccp_to_mtp3(&MsgToMTP); //depend on mtp module + +} + + + +int scrc_rf ( Intra_Msg * pIntraMsg, BYTE AnsiFlag ) + +{ + +#ifdef _WXC_TEST + + WxcAssert ( 0, "routing fail" ); + +#endif + + if( isco ( pIntraMsg ) ) + + { + + + + pIntraMsg->msgtype = SP_MSG_RF; + + cr2co ( pIntraMsg, AnsiFlag ); + + spShowMsg ( SCCPDB_ERR, "<006>Route Failure", pIntraMsg ); + + return -1; + + } + + else + + return sclc_rf ( pIntraMsg ); + +} + + + +DWORD SelectIPOfSSN ( BYTE ssn, BYTE sls, BOOL from_mtp ) + +{ + + LOCAL_SSN *pssn = &LocalSSN[ssn]; + + + + switch ( pssn->status[0] ) + + { + + case ST_Enable: + + switch ( pssn->status[1] ) + + { + + case ST_Enable: + + if( pssn->local == 0 ) + + return pssn->ip[sls & 0x01]; + + else if( from_mtp ) + + return pssn->ip[( pssn->local - 1 ) & 0x01]; + + else if( ( sls & 0x80 ) == 0x80 ) + + return pssn->ip[pssn->local & 0x01]; + + else + + return pssn->ip[sls & 0x01]; + + //break; + + default: + + if( ( sls & 0x80 ) == 0x80 && pssn->local == 1 ) + + { + + spLogDebug ( SCCPDB_ERR, "<014>Message was refused by subsystem_%d_0 and subsystem_%d_1 inaccessible", ssn, ssn ); + + return 0; + + } + + else + + return pssn->ip[0]; + + //break; + + } + + //break; + + default: + + switch ( pssn->status[1] ) + + { + + case ST_Enable: + + if( ( sls & 0x80 ) == 0x80 && pssn->local == 2 ) + + { + + spLogDebug ( SCCPDB_ERR, "<015>Message was refused by subsystem_%d_1 and subsystem_%d_0 inaccessible", ssn, ssn ); + + return 0; + + } + + else + + return pssn->ip[1]; + + //break; + + default: + + spLogDebug ( SCCPDB_ERR, "<016>Subsystem_%d is inaccessible", ssn ); + + + + } + + } + + + + return 0; + + + +} + + + + + +//sequence control functions -- add by Roy Jiang 2007-09-17 + +int get_sls(int dpc) + +{ + + static int pos = 0; //end position of dpc2sls array + + static u8 next_sls = 0; //sls for new dpc + + int i; + + + + for(i=0; i= 256) + + return next_sls; + + + + dpc2sls[i].dpc = dpc; + + dpc2sls[i].sls = next_sls; + + next_sls = (next_sls + 1) & 0x0F; + + pos++; + + + + return dpc2sls[i].sls; + +} + +//end of sequence control functions -- add by Roy Jiang 2007-09-17 + + + diff --git a/plat/sccp/ut/fsmtest/Makefile b/plat/sccp/ut/fsmtest/Makefile new file mode 100644 index 0000000..2bff29e --- /dev/null +++ b/plat/sccp/ut/fsmtest/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module Version : V1.4 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/06/18 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + + + +MODULE = sccptest +TYPE = app + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = exef +CFG = debug + +PLT_LIB = sccp mtp3 m2ua \ + snmp iptrans debug sccp public + +APP_LIB = + +LIB_ADD = + +SRC_PATH = . +INC_PATH = . +PLT_PATH = ../../../../plat +APP_PATH = ../../../../app + +OBJ_ADD = +TEST_OBJ_PATH = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = on +COVER_NEED = +COVER_REPORT_PATH = ./ut/ut_doc/output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/sccp/ut/fsmtest/bin/.svn/all-wcprops b/plat/sccp/ut/fsmtest/bin/.svn/all-wcprops new file mode 100644 index 0000000..c1a4593 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin +END diff --git a/plat/sccp/ut/fsmtest/bin/.svn/entries b/plat/sccp/ut/fsmtest/bin/.svn/entries new file mode 100644 index 0000000..8327da3 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/sccp/ut/fsmtest/bin +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +conf +dir + diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/all-wcprops b/plat/sccp/ut/fsmtest/bin/conf/.svn/all-wcprops new file mode 100644 index 0000000..9fa4cf7 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/all-wcprops @@ -0,0 +1,149 @@ +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf +END +hae_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/hae_sys.conf +END +cc_table.conf +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/cc_table.conf +END +map_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/map_operation.conf +END +map_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/map_acn.conf +END +help_page +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/help_page +END +ppsConf.txt +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/ppsConf.txt +END +smsc_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/smsc_sys.conf +END +hlr_parambit.conf +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/hlr_parambit.conf +END +HlrSysPara +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/HlrSysPara +END +wxc2exit.txt +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/wxc2exit.txt +END +xap_sysparam.conf +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/xap_sysparam.conf +END +profile +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/profile +END +menu_page +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/menu_page +END +system.ini +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/system.ini +END +smsc_csta.conf +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/smsc_csta.conf +END +iptrans.conf +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/iptrans.conf +END +wxc2_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/wxc2_sys.conf +END +conv_prefix.conf +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/conv_prefix.conf +END +mtp3.conf +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/mtp3.conf +END +cap_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/cap_operation.conf +END +cap_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/cap_acn.conf +END +smsc_parambit.conf +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/smsc_parambit.conf +END +sccp_test.conf +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/sccp_test.conf +END +sccp.conf +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf/sccp.conf +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/entries b/plat/sccp/ut/fsmtest/bin/conf/.svn/entries new file mode 100644 index 0000000..718f4fc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/entries @@ -0,0 +1,844 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/sccp/ut/fsmtest/bin/conf +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +hae_sys.conf +file + + + + +2012-12-28T03:06:11.250000Z +649d3fce3992c1c1b43fc30172a7f2a7 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +116 + +cc_table.conf +file + + + + +2012-12-28T03:06:11.265625Z +9f0aa5dca95acac37a68fe54438fa684 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4438 + +map_operation.conf +file + + + + +2012-12-28T03:06:11.265625Z +63cb6cdc86026f84ed0b86942c18579a +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +3089 + +map_acn.conf +file + + + + +2012-12-28T03:06:11.281250Z +ba98ac6b009e2c7e570ced416edb5508 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1541 + +help_page +file + + + + +2012-12-28T03:06:11.296875Z +cf329064faeb00741b9a1390677c1b27 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +561 + +ppsConf.txt +file + + + + +2012-12-28T03:06:11.390625Z +2fe53e393703da5db021ba122df651da +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +28340 + +smsc_sys.conf +file + + + + +2012-12-28T03:06:11.406250Z +8a5c1de60a79d7149ea3aae56ad6ee4d +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +86 + +hlr_parambit.conf +file + + + + +2012-12-28T03:06:11.421875Z +8c63d6cbc22edc75874555b19a2c8ff0 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +20740 + +HlrSysPara +file + + + + +2012-12-28T03:06:11.406250Z +3698e8bf4de04c7bf65dcf683c1c8fc5 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +7244 + +wxc2exit.txt +file + + + + +2012-12-28T03:06:11.453125Z +36b3f4a9e9ff77055c211efac6de9013 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +74 + +xap_sysparam.conf +file + + + + +2012-12-28T03:06:11.453125Z +adb6e10944b332812a04e892e71d565f +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +13 + +profile +file + + + + +2012-12-28T03:06:11.468750Z +0049e7048c766e13ddec943a200ae608 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +771 + +menu_page +file + + + + +2012-12-28T03:06:11.468750Z +ddfee824a6ab26cb8e64368669f38b71 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +730 + +system.ini +file + + + + +2012-12-28T03:06:11.562500Z +cc73dc3aa5b3d6d39d2f07b15dfdcab5 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +212 + +smsc_csta.conf +file + + + + +2012-12-28T03:06:11.562500Z +ecf8d97315dfb7401a6ff8cd615aab08 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +363 + +iptrans.conf +file + + + + +2012-12-28T03:06:11.578125Z +79dc403fc14953d2f0656c6cc386b5e9 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +450 + +wxc2_sys.conf +file + + + + +2012-12-28T03:06:11.578125Z +c59a016f57ed632c76316173b7f560e1 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +19 + +conv_prefix.conf +file + + + + +2012-12-28T03:06:11.671875Z +e844a4aa6315c4ad71e8089422f675dc +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4608 + +mtp3.conf +file + + + + +2012-12-28T03:06:11.703125Z +b44ca5c82a007cf88940026003aa780d +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +95312 + +cap_operation.conf +file + + + + +2012-12-28T03:06:11.703125Z +a59a993208c55239da80a0a85c1cbd35 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1260 + +cap_acn.conf +file + + + + +2012-12-28T03:06:11.718750Z +3f1c2ad8d1adbad97fa79e63b0e40aee +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +244 + +smsc_parambit.conf +file + + + + +2012-12-28T03:06:11.718750Z +c596c5d249e717db67ab93e6f0a4f7f2 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +2836 + +sccp_test.conf +file + + + + +2012-12-28T03:06:11.734375Z +ed2e690b7eab94c05345db2220bbec57 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +18 + +sccp.conf +file + + + + +2012-12-28T03:06:11.734375Z +1268f52b8405289bc7e55db63ec2e481 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1116 + diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/HlrSysPara.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/HlrSysPara.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/HlrSysPara.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_acn.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_acn.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_operation.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_operation.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cap_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cc_table.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cc_table.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/cc_table.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/conv_prefix.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/conv_prefix.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/conv_prefix.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hae_sys.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hae_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hae_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/help_page.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/help_page.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/help_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hlr_parambit.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hlr_parambit.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/hlr_parambit.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/iptrans.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/iptrans.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/iptrans.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_acn.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_acn.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_operation.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_operation.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/map_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/menu_page.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/menu_page.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/menu_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/mtp3.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/mtp3.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/mtp3.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/ppsConf.txt.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/ppsConf.txt.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/ppsConf.txt.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/profile.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/profile.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/profile.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp_test.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp_test.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/sccp_test.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_csta.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_csta.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_csta.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_parambit.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_parambit.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_parambit.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_sys.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/smsc_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/system.ini.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/system.ini.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/system.ini.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2_sys.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2exit.txt.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2exit.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/wxc2exit.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/xap_sysparam.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/xap_sysparam.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/prop-base/xap_sysparam.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/HlrSysPara.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/HlrSysPara.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..610468884f41c7f2e8b0e720cf80bc884fd22b3d GIT binary patch literal 7244 zcmeI%X|L5p9LMnixw4f8-1BcRk8G@CnW&pXnrR(&XDFO{OOpV_gzt zXprX85Y3~jX_yw$BD#ha)3vmOuA}Se2D*`Mp_Fc=+h{2*quc2YT0wWw-L#Tc(LJ=9 zHqd4or7;?(ZM2nyO<0C?i?>8ewxU+tQZ3!)ZP8Y3-8SudSPkn%CgF)lWD+HDq7t2$ zq)h5mq%w`tI8~`mO)hmJUKhL&g)E{XE>xil zQHp|VGGy-wty}0KPk}vobB#TVeHir*D9bun9Ip2fDBYM&N#U03L*gU@MgHFpR<&jKenA4m+TN9_)k( zcmy7WUGNyx@Hp&-C*VnV3Z8~%;8}PMo`*fK7hZrD;U#z(UV&HPHFzD~fHz?u?1#7D zZ8!k$z(F_!@4|cVK70U&;X^nAN8uQJ1RujE@F{!-pTigMB^-yZ-~@aP-@v!<9h`(y z@ICwhKf-A^183nU_!)kIU*R|S9sYoUo0m_Y0W;x3xCkzWOW;zt3}(S>xE!v4IUwLl o7=#8m;DQGObMd@KSF*|Dl39!`hE)T7Qz!qT4Bgp(AJeD%`<1@wk z>T@hFt}&b`F&!;$Ja_JY_g6kUOAK#l^bV=0vyUt&*@slr*+&+X>_aN*>>~?G_8}E@ m_K^i8`;dw{`^bWleMm)}ePlt&KBS_~KC+->A5u~Gm(K-CiUoH7 literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/hae_sys.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/hae_sys.conf.svn-base new file mode 100644 index 0000000..2e830a6 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/hae_sys.conf.svn-base @@ -0,0 +1,6 @@ +#HLR/AUC/EIR system configure file + +#IP info of SMSC +hlr-0=172.18.234.1; +#hlr-1=172.18.133.1; +hlr-1=172.54.240.147; diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/help_page.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/help_page.svn-base new file mode 100644 index 0000000..0746e55 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/help_page.svn-base @@ -0,0 +1,20 @@ + + ****************** + * HELP PAGE * + ****************** + + Welcome to DEBUG MONITOR. + + Press 's' or 'S' to enter "SUB MODULE SELECTION PAGE". + + In "SUB MODULE SELECTION PAGE", + Press 'x' or 'X' to return "HELP PAGE", + Press 'a-p' or 'A-P' to select sub module. + + In each sub module, Press '0-9' and 'a-f' to select pages. + + There are two methods to use Debug, + 1. Serial Port, use PC-to-PC serial line. + 2. Telnet, use "telnet dst_host_ip 4965". + +$ diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/hlr_parambit.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/hlr_parambit.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..8497c6f601155f75ff3c392b591bfca0b7623c67 GIT binary patch literal 20740 zcmeI)xo+J?6vpu@!8H+B{UG9I+-Be<%)M%eII*3$A!uf0;X!uNDW*;}uxwpf@#`x6vL)Lx zujkWwJKy-8uYB#Ne&!qB`p$3sKJWq+=pYTUzyvmMK_7ad3U!!pu zojE`E*WCHJ!OR(NHqu50;>k3Mwg$5z`^zCLc$?#JF+Mx92$$e8EWrep;R>w4DqMwY za2;+y12Nh1GnHd+=08$!#%hU58xp@g2(U#p29PD4lm#(yn7C*1drhfJcVcQ9A3an zcm=!g8s5NLcn9x+!vZY80xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd75 z0xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xa-9 Y3rz99xDWG@EI7_&ZvRZ59NFLh14RLh?*IS* literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/iptrans.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/iptrans.conf.svn-base new file mode 100644 index 0000000..64ee756 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/iptrans.conf.svn-base @@ -0,0 +1,25 @@ +#ipconfig for pps +4950=UDP,6,DIRECT +4951=UDP,0,BUFFER +4952=UDP,0,BUFFER +4953=UDP,0,BUFFER +4954=UDP,0,BUFFER +4955=UDP,3,BUFFER +4956=UDP,3,BUFFER +4957=UDP,4,BUFFER +4958=UDP,0,BUFFER +4959=UDP,0,BUFFER +4960=UDP,4,BUFFER +4961=UDP,0,BUFFER +4962=UDP,0,BUFFER +4963=UDP,0,BUFFER +4964=UDP,0,BUFFER +4965=TCP,6,BUFFER +4966=UDP,2,DIRECT +4967=UDP,4,DIRECT +4968=UDP,0,BUFFER +4969=UDP,0,BUFFER +4970=UDP,0,BUFFER +4971=UDP,0,BUFFER +4972=UDP,0,BUFFER +4973=UDP,0,BUFFER diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_acn.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_acn.conf.svn-base new file mode 100644 index 0000000..7c3094e --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_acn.conf.svn-base @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 02 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_operation.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_operation.conf.svn-base new file mode 100644 index 0000000..4c08ef0 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/map_operation.conf.svn-base @@ -0,0 +1,76 @@ +# operation code configure file +total data length=72 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:09 01 20 // send parameters +No.64:48 01 20 // not subscriber present +No.65:19 01 20 // process unstructure SS data +No.66:54 01 20 // beging subscriber activity +No.67:28 01 20 // perform handover +No.68:30 01 20 // perform subsequence handvoer +No.69:35 01 20 // note internal handover +No.70:54 01 20 // beging subscriber activity +No.71:49 01 20 // alert service center without result +No.72:52 01 20 // trace subscriber activity \ No newline at end of file diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/menu_page.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/menu_page.svn-base new file mode 100644 index 0000000..ac677e8 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/menu_page.svn-base @@ -0,0 +1,17 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- IPTR m -- MNP + b -- MTP3 n -- DEBUG + c -- SCCP o -- AUC + d -- TCAP p -- SMPP + e -- XAPP r -- M2UA + f -- MSC s -- BICC + g -- VLR t -- SIP + h -- EIR u -- ISUP + i -- HLR v -- Reserved + j -- SMSC w -- SCTP + k -- PPS y -- ISDN + l -- SNMP z -- Reserved diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/mtp3.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/mtp3.conf.svn-base new file mode 100644 index 0000000..dd315c0 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/mtp3.conf.svn-base @@ -0,0 +1,1408 @@ +#MTP3 CONFIGURE FILE + +[SERVICE NETWORK SP LEN] +[00] + +[LOCAL SP] +[000000] [000000] [000028] [000000] +[000000] [000000] [000000] [000000] + +[LINK ATTRIBUTE] +[00.00.ea] [11.00.62] [80.10.ff] [10.00.62] +[14.00.62] [08.00.62] [4e.00.62] [80.10.ff] +[80.10.ff] [12.00.62] [80.10.ff] [0a.00.62] +[0b.00.62] [0c.00.62] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [11.01.63] [80.10.ff] [10.01.63] +[14.01.63] [08.02.63] [4f.00.63] [80.10.ff] +[80.10.ff] [12.01.63] [80.10.ff] [0a.01.63] +[0b.01.63] [0c.01.63] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] + +[LINKSET ATTRIBUTE] +[000028.02] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] + +[NATIONAL NETWORK SP] +[000028.00.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000008.08.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[NATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[LOCAL ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +010303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/ppsConf.txt.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/ppsConf.txt.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..b556699c6ff5344e6c9e9f74f686c509576fda12 GIT binary patch literal 28340 zcmeI5y>1gh5PV~Yowt>l)M2Q zQV`I=&hFX!W1_PnCkoQHl5;zI&y*vC-yg9U)6Z;aSD~@A5X+*!4Olu81ets-+ ze2nw!bNeh)>Qiz(xrUVe`!%vDKPP4GP5ikN1o~=Fud6|jowHeIHYRoX?JAL1nI@?s z#*-WgrB;v5maCWDQXM^Ao;^&l=~Ps@D15cb%Gct_>T7xG>Yq}V zs#+KC>Db%0)-LyCF_^hs+s4e&Z^b)CEy>+eFB_X8IlRlCZ!-O6K)=oO+X4M9)9(iK zr`mKs+JpABevZk0st1`iJX}mz3hSaku;1IM
vl8pnb3dO4ea@%fNB;f5 z2R@d-ras~ynLp6}2oU_k{V$g7{*CrCt1tA=X?>ynNO|BNDG&T3<$-^sJn)Z{2mX=r KxEcSj*Z2#4+qSC! literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/profile.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/profile.svn-base new file mode 100644 index 0000000..da7324f --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/profile.svn-base @@ -0,0 +1,37 @@ +# /etc/profile + +# System wide environment and startup programs +# Functions and aliases go in /etc/bashrc + +PATH=".:$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/etc/rc.d/init.d:/usr/local/wxc2/bin" +PATH=/usr/java/jdk1.3/bin:$PATH + +ulimit -c 80000 +if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then + umask 002 +else + umask 022 +fi + +USER=`id -un` +LOGNAME=$USER +MAIL="/var/spool/mail/$USER" + +HOSTNAME=`/bin/hostname` +HISTSIZE=1000 + +if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then + INPUTRC=/etc/inputrc +fi +JAVA_COMPILER=javacomp ; export JAVA_COMPILER +LD_LIBRARY_PATH=/usr/local/mysql/lib ; export LD_LIBRARY_PATH +export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC + +for i in /etc/profile.d/*.sh ; do + if [ -x $i ]; then + . $i + fi +done + +unset i +PATH=/usr/local/wxc2/bin:$PATH diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp.conf.svn-base new file mode 100644 index 0000000..6f4a9a7 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp.conf.svn-base @@ -0,0 +1,26 @@ +#SCCP Config file (R8V0_03) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 2 - 172.18.128.1 172.18.129.1 +6 2 8675557122002 172.18.199.1 - +7 2 8675557122001 172.18.198.1 - +8 2 8675599999999 172.18.234.3 172.18.99.1 +9 2 86755920005 172.18.132.1 172.18.99.1 +10 2 86755920004 172.18.132.1 172.18.99.1 +11 2 86755920006 172.18.132.1 172.18.99.1 +19 2 86755920007 172.18.132.1 172.18.99.1 +20 2 86755920008 172.18.132.1 172.18.99.1 +21 2 86755920009 172.18.132.1 172.18.99.1 +22 2 867559000213 172.18.132.1 - +146 2 86755920011 172.18.132.1 172.18.99.1 +147 2 86755920010 172.18.132.1 172.18.99.1 +254 2 - 172.18.132.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 460020000000000 460029999999999 2 000028 6 0 7 +#1 1 8675590000000 8675599999998 2 000028 6 0 7 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp_test.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp_test.conf.svn-base new file mode 100644 index 0000000..668a293 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/sccp_test.conf.svn-base @@ -0,0 +1,2 @@ +172.18.199.1 +2000 diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_csta.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_csta.conf.svn-base new file mode 100644 index 0000000..a9a11f0 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_csta.conf.svn-base @@ -0,0 +1,21 @@ +# This file defines the SMSC CSTA row +# The max number of row is 20 +# Attention: When you want to define the Entity name, the name of "MS" "All" and "Other" is reserved + +# define the entity who send short message to SMSC +Receive from: +MS +PPS +VMS +#VMS+PPS +Other +#All + +# define the entity who receive short message from SMSC +Send to: +MS +PPS +VMS +#VMS+PPS +Other +#All diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_parambit.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_parambit.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..cc4473d3930958eb4c721128deefdb0d14fe7117 GIT binary patch literal 2836 zcmeHHy-or_5Z*0lC@8M8G1pmX0L2$j%2Sd<6BDi|nQw2g)=skM+8S7Bt(!a!Vsq!cG2dUt;MSOi_vq}*X6(df z3eI_Qf@#LlbJ+oW0cy1mk2?6q<8nYjWbPBm^7Iex@LFHaA6$mY5a2vD*e1XCs zhdTxgIzfCt$T7g-I>hnp9qTpqKDK$UQfJ9( zob;eNF*FJbr@MIA1NDns?6D3%=^KH|gfu~Sy+ze+LwL}WRmLOdD>2$?yqKq$;&1b` zhiQ`Xr=%%pukn62?Gvz)$B|xIx6F$YQ@tx3x-^2G4o2=+(;ES33_kQuRDC zZW&LSbcgBLse~+9jjQkN%G19Xr)ACi_bhUx-3`1F4H1R=zMo%c4pvW%2Rwt1UAU(q z51fzi=<~rkEmb?*YJ7p`V9tZRXVKeAp0MUdKFlNMA^EZobrWo33p}Ec)ToL__gy8A i%!0Nmo{(e9qt#fk5ALZ%Y|lrO_{IKH-LmL~CjSBF9jD9y literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_sys.conf.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_sys.conf.svn-base new file mode 100644 index 0000000..a36c5f3 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/smsc_sys.conf.svn-base @@ -0,0 +1,5 @@ +#SMSC system configure file + +#IP info of SMSC +wxc2-0=172.18.98.1; +wxc2-1=172.18.99.1; diff --git a/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/system.ini.svn-base b/plat/sccp/ut/fsmtest/bin/conf/.svn/text-base/system.ini.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..775a1a33efc5d5ae6d752e86370eb923443ee529 GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffm9r%x+}9f*%9Jf;L7l2C8uyOj9pAfm03>Y&WB>pF literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/HlrSysPara b/plat/sccp/ut/fsmtest/bin/conf/HlrSysPara new file mode 100644 index 0000000000000000000000000000000000000000..610468884f41c7f2e8b0e720cf80bc884fd22b3d GIT binary patch literal 7244 zcmeI%X|L5p9LMnixw4f8-1BcRk8G@CnW&pXnrR(&XDFO{OOpV_gzt zXprX85Y3~jX_yw$BD#ha)3vmOuA}Se2D*`Mp_Fc=+h{2*quc2YT0wWw-L#Tc(LJ=9 zHqd4or7;?(ZM2nyO<0C?i?>8ewxU+tQZ3!)ZP8Y3-8SudSPkn%CgF)lWD+HDq7t2$ zq)h5mq%w`tI8~`mO)hmJUKhL&g)E{XE>xil zQHp|VGGy-wty}0KPk}vobB#TVeHir*D9bun9Ip2fDBYM&N#U03L*gU@MgHFpR<&jKenA4m+TN9_)k( zcmy7WUGNyx@Hp&-C*VnV3Z8~%;8}PMo`*fK7hZrD;U#z(UV&HPHFzD~fHz?u?1#7D zZ8!k$z(F_!@4|cVK70U&;X^nAN8uQJ1RujE@F{!-pTigMB^-yZ-~@aP-@v!<9h`(y z@ICwhKf-A^183nU_!)kIU*R|S9sYoUo0m_Y0W;x3xCkzWOW;zt3}(S>xE!v4IUwLl o7=#8m;DQGObMd@KSF*|Dl39!`hE)T7Qz!qT4Bgp(AJeD%`<1@wk z>T@hFt}&b`F&!;$Ja_JY_g6kUOAK#l^bV=0vyUt&*@slr*+&+X>_aN*>>~?G_8}E@ m_K^i8`;dw{`^bWleMm)}ePlt&KBS_~KC+->A5u~Gm(K-CiUoH7 literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/hae_sys.conf b/plat/sccp/ut/fsmtest/bin/conf/hae_sys.conf new file mode 100644 index 0000000..2e830a6 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/hae_sys.conf @@ -0,0 +1,6 @@ +#HLR/AUC/EIR system configure file + +#IP info of SMSC +hlr-0=172.18.234.1; +#hlr-1=172.18.133.1; +hlr-1=172.54.240.147; diff --git a/plat/sccp/ut/fsmtest/bin/conf/help_page b/plat/sccp/ut/fsmtest/bin/conf/help_page new file mode 100644 index 0000000..0746e55 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/help_page @@ -0,0 +1,20 @@ + + ****************** + * HELP PAGE * + ****************** + + Welcome to DEBUG MONITOR. + + Press 's' or 'S' to enter "SUB MODULE SELECTION PAGE". + + In "SUB MODULE SELECTION PAGE", + Press 'x' or 'X' to return "HELP PAGE", + Press 'a-p' or 'A-P' to select sub module. + + In each sub module, Press '0-9' and 'a-f' to select pages. + + There are two methods to use Debug, + 1. Serial Port, use PC-to-PC serial line. + 2. Telnet, use "telnet dst_host_ip 4965". + +$ diff --git a/plat/sccp/ut/fsmtest/bin/conf/hlr_parambit.conf b/plat/sccp/ut/fsmtest/bin/conf/hlr_parambit.conf new file mode 100644 index 0000000000000000000000000000000000000000..8497c6f601155f75ff3c392b591bfca0b7623c67 GIT binary patch literal 20740 zcmeI)xo+J?6vpu@!8H+B{UG9I+-Be<%)M%eII*3$A!uf0;X!uNDW*;}uxwpf@#`x6vL)Lx zujkWwJKy-8uYB#Ne&!qB`p$3sKJWq+=pYTUzyvmMK_7ad3U!!pu zojE`E*WCHJ!OR(NHqu50;>k3Mwg$5z`^zCLc$?#JF+Mx92$$e8EWrep;R>w4DqMwY za2;+y12Nh1GnHd+=08$!#%hU58xp@g2(U#p29PD4lm#(yn7C*1drhfJcVcQ9A3an zcm=!g8s5NLcn9x+!vZY80xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd75 z0xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xa-9 Y3rz99xDWG@EI7_&ZvRZ59NFLh14RLh?*IS* literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/iptrans.conf b/plat/sccp/ut/fsmtest/bin/conf/iptrans.conf new file mode 100644 index 0000000..64ee756 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/iptrans.conf @@ -0,0 +1,25 @@ +#ipconfig for pps +4950=UDP,6,DIRECT +4951=UDP,0,BUFFER +4952=UDP,0,BUFFER +4953=UDP,0,BUFFER +4954=UDP,0,BUFFER +4955=UDP,3,BUFFER +4956=UDP,3,BUFFER +4957=UDP,4,BUFFER +4958=UDP,0,BUFFER +4959=UDP,0,BUFFER +4960=UDP,4,BUFFER +4961=UDP,0,BUFFER +4962=UDP,0,BUFFER +4963=UDP,0,BUFFER +4964=UDP,0,BUFFER +4965=TCP,6,BUFFER +4966=UDP,2,DIRECT +4967=UDP,4,DIRECT +4968=UDP,0,BUFFER +4969=UDP,0,BUFFER +4970=UDP,0,BUFFER +4971=UDP,0,BUFFER +4972=UDP,0,BUFFER +4973=UDP,0,BUFFER diff --git a/plat/sccp/ut/fsmtest/bin/conf/map_acn.conf b/plat/sccp/ut/fsmtest/bin/conf/map_acn.conf new file mode 100644 index 0000000..7c3094e --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/map_acn.conf @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 02 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/plat/sccp/ut/fsmtest/bin/conf/map_operation.conf b/plat/sccp/ut/fsmtest/bin/conf/map_operation.conf new file mode 100644 index 0000000..4c08ef0 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/map_operation.conf @@ -0,0 +1,76 @@ +# operation code configure file +total data length=72 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:09 01 20 // send parameters +No.64:48 01 20 // not subscriber present +No.65:19 01 20 // process unstructure SS data +No.66:54 01 20 // beging subscriber activity +No.67:28 01 20 // perform handover +No.68:30 01 20 // perform subsequence handvoer +No.69:35 01 20 // note internal handover +No.70:54 01 20 // beging subscriber activity +No.71:49 01 20 // alert service center without result +No.72:52 01 20 // trace subscriber activity \ No newline at end of file diff --git a/plat/sccp/ut/fsmtest/bin/conf/menu_page b/plat/sccp/ut/fsmtest/bin/conf/menu_page new file mode 100644 index 0000000..ac677e8 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/menu_page @@ -0,0 +1,17 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- IPTR m -- MNP + b -- MTP3 n -- DEBUG + c -- SCCP o -- AUC + d -- TCAP p -- SMPP + e -- XAPP r -- M2UA + f -- MSC s -- BICC + g -- VLR t -- SIP + h -- EIR u -- ISUP + i -- HLR v -- Reserved + j -- SMSC w -- SCTP + k -- PPS y -- ISDN + l -- SNMP z -- Reserved diff --git a/plat/sccp/ut/fsmtest/bin/conf/mtp3.conf b/plat/sccp/ut/fsmtest/bin/conf/mtp3.conf new file mode 100644 index 0000000..dd315c0 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/mtp3.conf @@ -0,0 +1,1408 @@ +#MTP3 CONFIGURE FILE + +[SERVICE NETWORK SP LEN] +[00] + +[LOCAL SP] +[000000] [000000] [000028] [000000] +[000000] [000000] [000000] [000000] + +[LINK ATTRIBUTE] +[00.00.ea] [11.00.62] [80.10.ff] [10.00.62] +[14.00.62] [08.00.62] [4e.00.62] [80.10.ff] +[80.10.ff] [12.00.62] [80.10.ff] [0a.00.62] +[0b.00.62] [0c.00.62] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [11.01.63] [80.10.ff] [10.01.63] +[14.01.63] [08.02.63] [4f.00.63] [80.10.ff] +[80.10.ff] [12.01.63] [80.10.ff] [0a.01.63] +[0b.01.63] [0c.01.63] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] + +[LINKSET ATTRIBUTE] +[000028.02] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] + +[NATIONAL NETWORK SP] +[000028.00.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000008.08.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[NATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[LOCAL ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +010303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + diff --git a/plat/sccp/ut/fsmtest/bin/conf/ppsConf.txt b/plat/sccp/ut/fsmtest/bin/conf/ppsConf.txt new file mode 100644 index 0000000000000000000000000000000000000000..b556699c6ff5344e6c9e9f74f686c509576fda12 GIT binary patch literal 28340 zcmeI5y>1gh5PV~Yowt>l)M2Q zQV`I=&hFX!W1_PnCkoQHl5;zI&y*vC-yg9U)6Z;aSD~@A5X+*!4Olu81ets-+ ze2nw!bNeh)>Qiz(xrUVe`!%vDKPP4GP5ikN1o~=Fud6|jowHeIHYRoX?JAL1nI@?s z#*-WgrB;v5maCWDQXM^Ao;^&l=~Ps@D15cb%Gct_>T7xG>Yq}V zs#+KC>Db%0)-LyCF_^hs+s4e&Z^b)CEy>+eFB_X8IlRlCZ!-O6K)=oO+X4M9)9(iK zr`mKs+JpABevZk0st1`iJX}mz3hSaku;1IM
vl8pnb3dO4ea@%fNB;f5 z2R@d-ras~ynLp6}2oU_k{V$g7{*CrCt1tA=X?>ynNO|BNDG&T3<$-^sJn)Z{2mX=r KxEcSj*Z2#4+qSC! literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/profile b/plat/sccp/ut/fsmtest/bin/conf/profile new file mode 100644 index 0000000..da7324f --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/profile @@ -0,0 +1,37 @@ +# /etc/profile + +# System wide environment and startup programs +# Functions and aliases go in /etc/bashrc + +PATH=".:$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/etc/rc.d/init.d:/usr/local/wxc2/bin" +PATH=/usr/java/jdk1.3/bin:$PATH + +ulimit -c 80000 +if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then + umask 002 +else + umask 022 +fi + +USER=`id -un` +LOGNAME=$USER +MAIL="/var/spool/mail/$USER" + +HOSTNAME=`/bin/hostname` +HISTSIZE=1000 + +if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then + INPUTRC=/etc/inputrc +fi +JAVA_COMPILER=javacomp ; export JAVA_COMPILER +LD_LIBRARY_PATH=/usr/local/mysql/lib ; export LD_LIBRARY_PATH +export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC + +for i in /etc/profile.d/*.sh ; do + if [ -x $i ]; then + . $i + fi +done + +unset i +PATH=/usr/local/wxc2/bin:$PATH diff --git a/plat/sccp/ut/fsmtest/bin/conf/sccp.conf b/plat/sccp/ut/fsmtest/bin/conf/sccp.conf new file mode 100644 index 0000000..6f4a9a7 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/sccp.conf @@ -0,0 +1,26 @@ +#SCCP Config file (R8V0_03) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 2 - 172.18.128.1 172.18.129.1 +6 2 8675557122002 172.18.199.1 - +7 2 8675557122001 172.18.198.1 - +8 2 8675599999999 172.18.234.3 172.18.99.1 +9 2 86755920005 172.18.132.1 172.18.99.1 +10 2 86755920004 172.18.132.1 172.18.99.1 +11 2 86755920006 172.18.132.1 172.18.99.1 +19 2 86755920007 172.18.132.1 172.18.99.1 +20 2 86755920008 172.18.132.1 172.18.99.1 +21 2 86755920009 172.18.132.1 172.18.99.1 +22 2 867559000213 172.18.132.1 - +146 2 86755920011 172.18.132.1 172.18.99.1 +147 2 86755920010 172.18.132.1 172.18.99.1 +254 2 - 172.18.132.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 460020000000000 460029999999999 2 000028 6 0 7 +#1 1 8675590000000 8675599999998 2 000028 6 0 7 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/sccp/ut/fsmtest/bin/conf/sccp_test.conf b/plat/sccp/ut/fsmtest/bin/conf/sccp_test.conf new file mode 100644 index 0000000..668a293 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/sccp_test.conf @@ -0,0 +1,2 @@ +172.18.199.1 +2000 diff --git a/plat/sccp/ut/fsmtest/bin/conf/smsc_csta.conf b/plat/sccp/ut/fsmtest/bin/conf/smsc_csta.conf new file mode 100644 index 0000000..a9a11f0 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/smsc_csta.conf @@ -0,0 +1,21 @@ +# This file defines the SMSC CSTA row +# The max number of row is 20 +# Attention: When you want to define the Entity name, the name of "MS" "All" and "Other" is reserved + +# define the entity who send short message to SMSC +Receive from: +MS +PPS +VMS +#VMS+PPS +Other +#All + +# define the entity who receive short message from SMSC +Send to: +MS +PPS +VMS +#VMS+PPS +Other +#All diff --git a/plat/sccp/ut/fsmtest/bin/conf/smsc_parambit.conf b/plat/sccp/ut/fsmtest/bin/conf/smsc_parambit.conf new file mode 100644 index 0000000000000000000000000000000000000000..cc4473d3930958eb4c721128deefdb0d14fe7117 GIT binary patch literal 2836 zcmeHHy-or_5Z*0lC@8M8G1pmX0L2$j%2Sd<6BDi|nQw2g)=skM+8S7Bt(!a!Vsq!cG2dUt;MSOi_vq}*X6(df z3eI_Qf@#LlbJ+oW0cy1mk2?6q<8nYjWbPBm^7Iex@LFHaA6$mY5a2vD*e1XCs zhdTxgIzfCt$T7g-I>hnp9qTpqKDK$UQfJ9( zob;eNF*FJbr@MIA1NDns?6D3%=^KH|gfu~Sy+ze+LwL}WRmLOdD>2$?yqKq$;&1b` zhiQ`Xr=%%pukn62?Gvz)$B|xIx6F$YQ@tx3x-^2G4o2=+(;ES33_kQuRDC zZW&LSbcgBLse~+9jjQkN%G19Xr)ACi_bhUx-3`1F4H1R=zMo%c4pvW%2Rwt1UAU(q z51fzi=<~rkEmb?*YJ7p`V9tZRXVKeAp0MUdKFlNMA^EZobrWo33p}Ec)ToL__gy8A i%!0Nmo{(e9qt#fk5ALZ%Y|lrO_{IKH-LmL~CjSBF9jD9y literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/bin/conf/smsc_sys.conf b/plat/sccp/ut/fsmtest/bin/conf/smsc_sys.conf new file mode 100644 index 0000000..a36c5f3 --- /dev/null +++ b/plat/sccp/ut/fsmtest/bin/conf/smsc_sys.conf @@ -0,0 +1,5 @@ +#SMSC system configure file + +#IP info of SMSC +wxc2-0=172.18.98.1; +wxc2-1=172.18.99.1; diff --git a/plat/sccp/ut/fsmtest/bin/conf/system.ini b/plat/sccp/ut/fsmtest/bin/conf/system.ini new file mode 100644 index 0000000000000000000000000000000000000000..775a1a33efc5d5ae6d752e86370eb923443ee529 GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffm9r%x+}9f*%9Jf;L7l2C8uyOj9pAfm03>Y&WB>pF literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/obj/.svn/all-wcprops b/plat/sccp/ut/fsmtest/obj/.svn/all-wcprops new file mode 100644 index 0000000..7e8b838 --- /dev/null +++ b/plat/sccp/ut/fsmtest/obj/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/obj +END +scoc_test.gcno +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/obj/scoc_test.gcno +END +sccp_test.gcno +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/sccp/ut/fsmtest/obj/sccp_test.gcno +END diff --git a/plat/sccp/ut/fsmtest/obj/.svn/entries b/plat/sccp/ut/fsmtest/obj/.svn/entries new file mode 100644 index 0000000..dea76f8 --- /dev/null +++ b/plat/sccp/ut/fsmtest/obj/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/sccp/ut/fsmtest/obj +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +scoc_test.gcno +file + + + + +2012-12-28T03:06:12.062500Z +db15c6007fcfe043ccb48659e7e53e2c +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +13992 + +sccp_test.gcno +file + + + + +2012-12-28T03:06:12.078125Z +9b738365b4bab3e3aabcdde79de69310 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +5000 + diff --git a/plat/sccp/ut/fsmtest/obj/.svn/prop-base/sccp_test.gcno.svn-base b/plat/sccp/ut/fsmtest/obj/.svn/prop-base/sccp_test.gcno.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/obj/.svn/prop-base/sccp_test.gcno.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/obj/.svn/prop-base/scoc_test.gcno.svn-base b/plat/sccp/ut/fsmtest/obj/.svn/prop-base/scoc_test.gcno.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/sccp/ut/fsmtest/obj/.svn/prop-base/scoc_test.gcno.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/sccp/ut/fsmtest/obj/.svn/text-base/sccp_test.gcno.svn-base b/plat/sccp/ut/fsmtest/obj/.svn/text-base/sccp_test.gcno.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..e233aef9006fc2a5eac97cd7f7e5cab3a058f5f0 GIT binary patch literal 5000 zcmd^?*{@So6vlg;5#dRqCJq-+#1M&ciE)lMq$o}(pmMp8=Gqo+qqnWJN{GDpV&Z`F zgJX;uH7bwJL!61m2VeXLd^P$%`2Ehht84dgTEWC<;!3`DukTxXT4(Lu(@wj-XUqCa zCVyS}+!K{bB|B9gXAAA^-Ra}>-J9#|yZip#mE&pG>)l$v+3T;ZS5B8-sZ3?3BmI){3E#vT+$2q?7i9cb$t5MmIp~0WL@Ey91g->5Ii>HsrpQJW1jKw(kXf}5> zTdX$g!O)BQT_)}f#DP^a#v}I30Y}4lw6b{SJBzTeeC~7PPcEBTna^!`Uq?uBEyVqw za?gIx6()qR$o=vl)r#Ctl8X?Sb#9S8# zNh?49=c)0_bq60t@3d=;+5YSi`@fWE?VsHJJsY2&(=;f1_I&vH$M?L%d5ycl`;j-# z9r>c|n)^N`zH8|n0gvw*cSSlTzH8irsfNF3fh(>P-urRiGLPR$_{95I>=mDQiyQyk zc`jTUlfru8G9fI^%;iC<6=&v(5}tXlEaAz`RV6%mxw?cWC)bqlyI^!sz2Af4!w@>UE}%rGbDes{hK`4xsBf_ z?^jlTu9elFYia$l4zItXsTuNjgRn`sQMgG6tLAqc=k8|VmJrl3jrndBZY$B)_wB;g zg2p~s+nvH)!ge9d#wBK2*b#zSrjd&oVP`>OKK8zAh_`y;cVg$^18=ZiUG5|6sh;

XF2Q%rYn1-Zk;8Nze6OQ8OEwR@ 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 S)8yH0^E#!S^9u1pUjG21t}A!| literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/obj/sccp_test.gcno b/plat/sccp/ut/fsmtest/obj/sccp_test.gcno new file mode 100644 index 0000000000000000000000000000000000000000..e233aef9006fc2a5eac97cd7f7e5cab3a058f5f0 GIT binary patch literal 5000 zcmd^?*{@So6vlg;5#dRqCJq-+#1M&ciE)lMq$o}(pmMp8=Gqo+qqnWJN{GDpV&Z`F zgJX;uH7bwJL!61m2VeXLd^P$%`2Ehht84dgTEWC<;!3`DukTxXT4(Lu(@wj-XUqCa zCVyS}+!K{bB|B9gXAAA^-Ra}>-J9#|yZip#mE&pG>)l$v+3T;ZS5B8-sZ3?3BmI){3E#vT+$2q?7i9cb$t5MmIp~0WL@Ey91g->5Ii>HsrpQJW1jKw(kXf}5> zTdX$g!O)BQT_)}f#DP^a#v}I30Y}4lw6b{SJBzTeeC~7PPcEBTna^!`Uq?uBEyVqw za?gIx6()qR$o=vl)r#Ctl8X?Sb#9S8# zNh?49=c)0_bq60t@3d=;+5YSi`@fWE?VsHJJsY2&(=;f1_I&vH$M?L%d5ycl`;j-# z9r>c|n)^N`zH8|n0gvw*cSSlTzH8irsfNF3fh(>P-urRiGLPR$_{95I>=mDQiyQyk zc`jTUlfru8G9fI^%;iC<6=&v(5}tXlEaAz`RV6%mxw?cWC)bqlyI^!sz2Af4!w@>UE}%rGbDes{hK`4xsBf_ z?^jlTu9elFYia$l4zItXsTuNjgRn`sQMgG6tLAqc=k8|VmJrl3jrndBZY$B)_wB;g zg2p~s+nvH)!ge9d#wBK2*b#zSrjd&oVP`>OKK8zAh_`y;cVg$^18=ZiUG5|6sh;

XF2Q%rYn1-Zk;8Nze6OQ8OEwR@ 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 S)8yH0^E#!S^9u1pUjG21t}A!| literal 0 HcmV?d00001 diff --git a/plat/sccp/ut/fsmtest/sccp_test.c b/plat/sccp/ut/fsmtest/sccp_test.c new file mode 100644 index 0000000..595ec28 --- /dev/null +++ b/plat/sccp/ut/fsmtest/sccp_test.c @@ -0,0 +1,192 @@ + +#include "../../src/include/sccp.h" +#include "signal.h" +#include + +#ifdef _WXC_FSM_TEST +#define spLogFsm printf +#else +#define spLogFsm +#endif + +static struct itimerval itimer, old_itimer; + +u8 sccp_timer_flag; + +void mtp3_timer ( ); +void send_data ( ); + +void showbuf ( BYTE * buf, int len ) +{ + int i; + + for ( i = 0; i < len; i++ ) + printf ( "%X", buf[i] ); + printf ( "\n" ); +} + +void showbuf2 ( BYTE * buf, int len ) +{ + int i; + + for ( i = 0; i < len; i++ ) + printf ( "%02X", buf[i] ); + printf ( "\n" ); +} + +void on_data ( ) +{ + SCLC_MSG clmsg; + SCCP_ADDR addr; + int len, len2; + + if( ( len = sclc_receive ( &clmsg, 0 ) ) > 0 ) + { + showbuf2 ( clmsg.msg, clmsg.msglen ); + memcpy ( &addr, &clmsg.src_addr, sizeof ( SCCP_ADDR ) ); + memcpy ( &clmsg.src_addr, &clmsg.dst_addr, sizeof ( SCCP_ADDR ) ); + memcpy ( &clmsg.dst_addr, &addr, sizeof ( SCCP_ADDR ) ); + len2 = sclc_send ( &clmsg ); + if( len2 == -1 ) + printf ( "fail to send message" ); + } +} + + +u8 sccp_20ms_flag = 0; + +void On_Timer ( ) +{ + //on_data ( ); + sccp_20ms_flag++; + sccp_timer_flag++; + spLogFsm("pos plat iprtans start \r\n"); + iptrans_timer ( ); + spLogFsm("pos plat mpt3 start \r\n"); + mtp3_proc ( ); + spLogFsm("pos plat sccp start \r\n"); + spWxcBackTrace(); + sccp_timer ( ); + spLogFsm("pos plat sccp over \r\n"); + spWxcBackTrace(); + if( sccp_20ms_flag >= 2 ) + { + spWxcBackTrace(); + sccp_20ms_flag = 0; + spLogFsm("pos plat debug start \r\n"); + debug_rt ( ); + spLogFsm("pos plat snmp start \r\n"); + snmp_timer ( ); + spLogFsm("pos plat heartbeat start \r\n"); + heartbeat_timer ( ); + spLogFsm("pos plat end start \r\n"); + spWxcBackTrace(); + } +} + +void SetTimer ( ) +{ + struct sigaction act; + + act.sa_handler = On_Timer; + sigemptyset ( &act.sa_mask ); + act.sa_flags = 0; + if( sigaction ( SIGALRM, &act, NULL ) < 0 ) + { + perror ( "Produce Sigaction" ); + exit ( 1 ); + } + + itimer.it_interval.tv_sec = 0; + itimer.it_interval.tv_usec = 10 * 1000; + itimer.it_value.tv_sec = 0; + itimer.it_value.tv_usec = 10 * 1000; + + if( setitimer ( ITIMER_REAL, &itimer, &old_itimer ) != 0 ) + { + printf ( "Setting Timer error! \n" ); + exit ( 1 ); + } +} + +void spUserInit( ) +{ + +} + +void spUserFsm( ) +{ + +} + +u8 delay = 5; +u8 main_state = 0; + +void system_init ( ) +{ + sleep ( 3 ); + debug_init ( ); + iptrMainInit ( ); + snmp_init ( 4957 ); + heartbeat_init ( 0x0188 ); + mtp_shm_init ( ); + sccp_init ( ); + + sccp_20ms_flag = 0; + sccp_timer_flag = 0; + +} + +int main ( ) +{ + system_init(); + SetTimer ( ); + while ( 1 ) + { + usleep ( 1 ); + + if( sccp_timer_flag >= delay ) + { + sccp_timer_flag = 0; + switch ( main_state ) + { + case 0: + ulInit( ); + main_state = 1; + break; + case 1: + spLogFsm("sccp_test.c: main->ulsapfsm in \n"); + ulSapFsm( ); + spLogFsm("sccp_test.c: main->ulsapfsm out \n"); + break; + } + } + } + return 1; +} + +void send_data ( ) +{ + SCLC_MSG clmsg; + BYTE value[100] = { 1, 2, 3, 4, 5, 6 }; + BYTE number[20] = { 0x68, 0x57, 0x55, 0x17, 0x32, 0x00, 0xF3 }; + + clmsg.msglen = 6; + memcpy ( clmsg.msg, value, clmsg.msglen ); + clmsg.src_addr.DPC = 0x111111; + clmsg.src_addr.SSN = 8; + clmsg.src_addr.GTI = 0; + + clmsg.dst_addr.DPC = 0; + clmsg.dst_addr.SSN = 8; + clmsg.dst_addr.GTI = 4; + clmsg.dst_addr.NP = 1; + clmsg.dst_addr.NAI = 4; + clmsg.dst_addr.len = 13; + clmsg.dst_addr.NetID = 0; + memcpy ( clmsg.dst_addr.GTAI, number, 7 ); + + if( sclc_send ( &clmsg ) == -1 ) + printf ( "fail to send message\n" ); +} + diff --git a/plat/sccp/ut/fsmtest/scoc_test.c b/plat/sccp/ut/fsmtest/scoc_test.c new file mode 100644 index 0000000..5392a5f --- /dev/null +++ b/plat/sccp/ut/fsmtest/scoc_test.c @@ -0,0 +1,616 @@ +////////////////////////////////////////////////// +//Title : fsm_test.c +//Auhtor : Liu Wei +//Desc : sccp fsm testing +//Created : 2007-05-25 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + +#include "../../src/include/sccp.h" +#include "../../src/include/sccp_pub.h" +#include "../../src/include/scoc_if.h" + +extern unsigned long spLogDebug_mask ; +extern BYTE sccpFilterIndex ; +extern BYTE mtp_asciin_buf[80]; + +#ifdef _WXC_FSM_TEST +#define spLogFsm printf +#else +#define spLogFsm +#endif + +typedef enum UL_ORG_STATE +{ + ORG_IDLE = 1, + ORG_CR, //CM LU + ORG_CC, //CC + ORG_LUR, //lu reject + ORG_CLCD, //clean command + ORG_CLCE, //clean complete + ORG_DISCONN, + ORG_SEND_UDT, //PRN + ORG_RECV_UDT, //PRN ack +} +UL_OrgState; + +typedef enum UL_DST_STATE +{ + DST_IDLE = 1, + DST_CR, //CM LU + DST_CC, //CC + DST_LUR, //lu reject + DST_CLCD, //clean command + DST_CLCE, //clean complete + DST_DISCONN, + DST_RECV_UDT, //PRN + DST_SEND_UDT, //PRN ack +} +UL_DstState; + +typedef struct SCCP_UL +{ + u8 uUlSide; + u8 uUlState; + u32 uUlTestStartTimer; + u32 uUlStateInterval; + u32 uWaitTimer; + u32 wConnId; + int nPort; + int nRemoteIP; + int nSock; +} +SP_UL; + +SP_UL tUl; + +#define aifprn_udt_msg_len 0x52 + +static u8 aifprn_udt_msg[] = { + 0x51, 0x62, 0x4f, +0x48, 0x04, 0x01, 0x62, 0x00, 0x35, 0x6b, 0x1e, +0x28, 0x1c, 0x06, 0x07, 0x00, 0x11, 0x86, 0x05, +0x01, 0x01, 0x01, 0xa0, 0x11, 0x60, 0x0f, 0x80, +0x02, 0x07, 0x80, 0xa1, 0x09, 0x06, 0x07, 0x04, +0x00, 0x00, 0x01, 0x00, 0x03, 0x02, 0x6c, 0x27, +0xa1, 0x25, 0x02, 0x01, 0x80, 0x02, 0x01, 0x04, +0x30, 0x1d, 0x80, 0x08, 0x64, 0x00, 0x92, 0x00, +0x00, 0x00, 0x83, 0xf4, 0x81, 0x08, 0x91, 0x44, +0x57, 0x55, 0x06, 0x00, 0x00, 0xf0, 0x82, 0x07, +0x91, 0x68, 0x57, 0x95, 0x00, 0x83, 0xf4, +}; + +#define aifprnak_udt_msg_len 0x4b + +static u8 aifprnak_udt_msg[] = { + 0x4a, 0x64, 0x48, +0x49, 0x04, 0x01, 0x62, 0x00, 0x35, 0x6b, 0x2a, +0x28, 0x28, 0x06, 0x07, 0x00, 0x11, 0x86, 0x05, +0x01, 0x01, 0x01, 0xa0, 0x1d, 0x61, 0x1b, 0x80, +0x02, 0x07, 0x80, 0xa1, 0x09, 0x06, 0x07, 0x04, +0x00, 0x00, 0x01, 0x00, 0x03, 0x02, 0xa2, 0x03, +0x02, 0x01, 0x00, 0xa3, 0x05, 0xa1, 0x03, 0x02, +0x01, 0x00, 0x6c, 0x14, 0xa2, 0x12, 0x02, 0x01, +0x80, 0x30, 0x0d, 0x02, 0x01, 0x04, 0x04, 0x08, +0x91, 0x44, 0x57, 0x25, 0x31, 0x06, 0x00, 0xf6 +}; + +#define aiflu_cr_msg_len 0x25 + +static u8 aiflu_cr_msg[] = { + 0x0f, 0x23, 0x00, 0x21, 0x57, +0x05, 0x08, 0x00, 0x57, 0xf0, 0x10, 0x0b, 0xb9, +0x0a, 0xfb, 0x17, 0x12, 0x05, 0x08, 0x70, 0x45, +0xf0, 0x10, 0x00, 0x01, 0x30, 0x08, 0x59, 0x04, +0x10, 0x25, 0x00, 0x20, 0x30, 0x62, 0x21, 0x01, +}; + +#define aifcc_dt1_msg_len 0x00 + +static u8 aifcc_dt1_msg[] = { + +}; + +#define aiflurj_dt1_msg_len 0x07 + +static u8 aiflurj_dt1_msg[] = { + 0x06, 0x01, 0x00 , 0x03, 0x05, 0x04, 0x0b +}; + +#define aifclcd_dt1_msg_len 0x07 + +static u8 aifclcd_dt1_msg[] = { + 0x06, 0x00, 0x04 , 0x20, 0x04, 0x01, 0x09 +}; + +#define aifclce_dt1_msg_len 0x05 + +static u8 aifclce_dt1_msg[] = { + 0x03, 0x00, 0x01 , 0x21, 0x00 +}; + +#define aiflu_rlsd_msg_len 0x00 + +static u8 aiflu_rlsd_msg[] = { + +}; + +#define aiflu_rlc_msg_len 0x00 + +static u8 aiflu_rlc_msg[] = { + +}; + +int get_socket(u_int32_t ip, int port) +{ + int sock; + int on = 1; + u_long cmdarg = 1; + struct sockaddr_in sin_addr; + + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = htons(port); + sin_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if(!(sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + perror("Get socket"); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if(bind(sock, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr_in)) != 0) + { + perror("bind"); + return 0; + } + ioctl(sock, FIONBIO, &cmdarg); + return (sock); +} + +int ulRecv( u8 *pBuff ) +{ + struct sockaddr_in sin_addr; + int addr_len; + + return recvfrom(tUl.nSock, (char *)pBuff, 256, 0, (struct sockaddr *)&sin_addr, &addr_len); +} + +void ulSend( u8 *pBuff , u8 uLen ) +{ + struct sockaddr_in sin_addr; + + WxcAssert( uLen < 255 , "ulSend too long msg"); + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = htons(tUl.nPort); + sin_addr.sin_addr.s_addr = tUl.nRemoteIP; + + sendto(tUl.nSock, (char *)pBuff, 256, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); +} + +int ulSpecPeer() +{ + char msg[256]; + + memset(msg, 0, 256); + ulRecv(msg); + if( msg[0] ) + { + printf("Recv test msg: %s\r\n", msg); + if( !strcmp(msg, "SCCP_TEST") ) + { + tUl.uUlSide = 0; + printf("slave mode\r\n"); + ulSend("SCCP_OK" , 7); + tUl.uUlStateInterval=0; + return 1; + } + else if( !strcmp(msg, "SCCP_OK") ) + { + tUl.uUlSide = 1; + printf("master mode\r\n"); + tUl.uUlStateInterval=0; + return 1; + } + + } + if( tUl.uUlStateInterval++ % 200 ) + { + ulSend("SCCP_TEST" , 9); + + } + return 0; +} + +void ulInit() +{ + int ip; + struct in_addr sin_addr; + + + sin_addr.s_addr = tUl.nRemoteIP; + + memset(&tUl, 0, sizeof(SP_UL)); + tUl.uUlSide = 1; + tUl.nPort = 6999; + + ip = GetLocalIP(); + tUl.nRemoteIP = ( ip ^ 0x00010000 ); + + tUl.uWaitTimer = 20; + memcpy( &sin_addr , &tUl.nRemoteIP , 4); + printf("Remote ip : %s Start timer :%d \n" , inet_ntoa(sin_addr) ,tUl.uWaitTimer ); + tUl.nSock = get_socket(tUl.nRemoteIP, tUl.nPort); + printf("get sock :%d \r\n",tUl.nSock); + register_ssn ( 0xfe, 3 ); + mtp_asciin_buf[0] = 1; + + strcpy( &mtp_asciin_buf[1] , "log all" ); + printf("sizeof[sizeof(CO_ConnSection)* 4096]=%d\n", sizeof(CO_ConnSection)* 4096); + +} + +void ulLogMsg ( SP_UiPriPara * pSpPri, u8 uDirection , SP_UD *pUD ) +{ + char *pStr; + + spGetUlPrimitiveStr ( pSpPri->uUiPri, pStr ); + + if( uDirection ) + { + spLogDebug ( SCCPDB_AIF , "UL=>SP : %s ", pStr ); + } + else + { + spLogDebug ( SCCPDB_AIF , "UL<=SP : %s ", pStr ); + } + if( NULL != pUD ) + { + spShowBCD ( 1, pUD->aUserData, pUD->uDataLen ); + } +} + +extern void spLog ( char *info ); + +void ulLogState ( u8 uSide , u8 *pStr ) +{ + char aStr[256]; + if( uSide ) + sprintf(aStr ,"]Org Node[: %s state \n" , pStr); + else + sprintf(aStr ,"]Dst Node[: %s state \n" , pStr); + + spLog(aStr); +} + +void ul_sccp_addr( SCCP_ADDR *pAddr ) +{ + memset( pAddr , 0 , sizeof(SCCP_ADDR) ); + + pAddr->ip = tUl.nRemoteIP; + pAddr->DPC = 40; + pAddr->NetID = 2; + pAddr->SSN = 254; + pAddr->RI = RI_SSN; + pAddr->GTI = 0; + pAddr->AI = 3; + + return; +} + +void ulSapFsm ( ) +{ + SP_UiPriPara tSpPri; + SP_UiPriUnion *pUPri; + + pUPri = &tSpPri.tPriUnion; + + if( !tUl.uUlState ) + { + if( ulSpecPeer() ) + { + printf("----------------------OK------------------\r\n"); + tUl.uUlState++; + }else + { + return; + } + } + + sccpFilterIndex = 0; + spLogDebug_mask = 0xFFFFFFFF; + + //printf("Side : %d state : %d \n",tUl.uUlSide ,tUl.uUlState ); + if( tUl.uUlSide ) + { + switch ( tUl.uUlState ) + { + case ORG_IDLE: + + break; + case ORG_SEND_UDT: //PRN + tSpPri.uUiPri = N_UNITDATA_REQ; + ul_sccp_addr ( &pUPri->tPriNUDataReq.tCDA ); + ul_sccp_addr ( &pUPri->tPriNUDataReq.tCGA ); + pUPri->tPriNUDataReq.tRO.uRO = 1; + pUPri->tPriNUDataReq.tUD.uDataLen = aifprn_udt_msg_len; + memcpy ( &pUPri->tPriNUDataReq.tUD.aUserData, aifprn_udt_msg, pUPri->tPriNUDataReq.tUD.uDataLen ); + ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNUDataReq.tUD); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while ORG_SEND_UDT state" ); + ulLogState( tUl.uUlSide ,"ORG_SEND_UDT" ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + return; + case ORG_RECV_UDT: //PRN ack + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( tSpPri.uUiPri == N_UNITDATA_IND, "ul recv pri error while ORG_RECV_UDT state" ); + ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNUDataInd.tUD); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"ORG_RECV_UDT" ); + return ; + } + break; + case ORG_CR: //CM LU + tSpPri.uUiPri = N_CONNECT_REQ; + ul_sccp_addr ( &pUPri->tPriNConnReq.tCDA ); + pUPri->tPriNConnReq.uOptFlag = 0x08; + + pUPri->tPriNConnReq.tUD.uDataLen = aiflu_cr_msg_len; + memcpy ( &pUPri->tPriNConnReq.tUD.aUserData, aiflu_cr_msg, pUPri->tPriNConnReq.tUD.uDataLen ); + ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNConnReq.tUD); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while ORG_CR state" ); + tUl.wConnId = tSpPri.wConnId; + WxcAssert ( tUl.wConnId < CO_CS_MPORT, "wConnId error " ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"ORG_CR" ); + return; + case ORG_CC: //CC + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( tSpPri.uUiPri == N_CONNECT_CFM, "ul recv pri error while ORG_CC state" ); + ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNConnCfm.tUD); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"ORG_CC" ); + return ; + } + break; + case ORG_LUR: //lu reject + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( tSpPri.uUiPri == N_DATA_IND, "ul recv pri error while ORG_LUR state" ); + ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNDataInd.tUD); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"ORG_LUR" ); + return ; + } + break; + case ORG_CLCD: //clean command + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( tSpPri.uUiPri == N_DATA_IND, "ul recv pri error while ORG_CLCD state" ); + ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNDataInd.tUD); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"ORG_CLCD" ); + return ; + } + break; + case ORG_CLCE: //clean complete + tSpPri.uUiPri = N_DATA_REQ; + + pUPri->tPriNDataReq.tUD.uDataLen = aifclce_dt1_msg_len; + memcpy ( &pUPri->tPriNDataReq.tUD.aUserData, aifclce_dt1_msg, pUPri->tPriNDataReq.tUD.uDataLen ); + ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNDataReq.tUD); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while ORG_CLCE state" ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"ORG_CLCE" ); + return; + case ORG_DISCONN: + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( tSpPri.uUiPri == N_DISCONNECT_IND, "ul recv pri error while ORG_RLSD state" ); + ulLogMsg ( &tSpPri, 0 , NULL ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"ORG_CLCE" ); + return ; + } + break; + default: + printf ( "\n\n\n======================SP Org Test End=================\n\n\n" ); + exit(1); + break; + } + if( ORG_IDLE == tUl.uUlState ) + { + if( tUl.uUlTestStartTimer++ >= tUl.uWaitTimer ) + { + printf ( "\n\n\n======================SP Org Test Start=================\n\n\n" ); + tUl.uUlState++; + + } + } + else + { + if( tUl.uUlStateInterval++ >= 200 ) + { + //WxcAssert ( tUl.uUlState != ORG_RECV_UDT, "ORG_RECV_UDT state timer out" ); + //WxcAssert ( tUl.uUlState != ORG_CC, "ORG_CC state timer out" ); + //WxcAssert ( tUl.uUlState != ORG_LUR, "ORG_LUR state timer out" ); + //WxcAssert ( tUl.uUlState != ORG_CLCD, "ORG_CLCD state timer out" ); + //WxcAssert ( tUl.uUlState != ORG_DISCONN, "ORG_DISCONN state timer out" ); + tUl.uUlStateInterval = 0; + } + } + } + else + { + switch ( tUl.uUlState ) + { + case DST_IDLE: + + break; + case DST_RECV_UDT: //PRN + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( tSpPri.uUiPri == N_UNITDATA_IND, "ul recv pri error while DST_RECV_UDT state" ); + ulLogMsg ( &tSpPri, 0 ,&pUPri->tPriNUDataInd.tUD); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_RECV_UDT" ); + return ; + } + break; + case DST_SEND_UDT: //PRN ack + tSpPri.uUiPri = N_UNITDATA_REQ; + ul_sccp_addr ( &pUPri->tPriNUDataReq.tCDA ); + ul_sccp_addr ( &pUPri->tPriNUDataReq.tCGA ); + pUPri->tPriNUDataReq.tRO.uRO = 1; + pUPri->tPriNUDataReq.tUD.uDataLen = aifprnak_udt_msg_len; + memcpy ( &pUPri->tPriNUDataReq.tUD.aUserData, aifprnak_udt_msg, pUPri->tPriNUDataReq.tUD.uDataLen ); + ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNUDataReq.tUD); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_SEND_UDT state" ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_SEND_UDT" ); + return; + case DST_CR: //CM LU + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( (tSpPri.uUiPri == N_CONNECT_IND), "ul recv pri error while DST_CR state" ); + ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNConnInd.tUD); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_CR" ); + return ; + } + break; + case DST_CC: //CC + tSpPri.uUiPri = N_CONNECT_RSP; + tSpPri.wConnId = tUl.wConnId; + pUPri->tPriNConnRsp.tUD.uDataLen = aifcc_dt1_msg_len; + pUPri->tPriNConnRsp.uOptFlag = 0x00; + ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNConnRsp.tUD ); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_CC state" ); + WxcAssert ( tUl.wConnId < CO_CS_MPORT, "wConnId error " ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_CC" ); + return; + case DST_LUR: //lu reject + tSpPri.uUiPri = N_DATA_REQ; + tSpPri.wConnId = tUl.wConnId; + pUPri->tPriNDataReq.tUD.uDataLen = aiflurj_dt1_msg_len; + memcpy ( &pUPri->tPriNDataReq.tUD.aUserData, aiflurj_dt1_msg, pUPri->tPriNDataReq.tUD.uDataLen ); + ulLogMsg ( &tSpPri, 1 , &pUPri->tPriNDataReq.tUD); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_LUR state" ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_LUR" ); + return; + case DST_CLCD: //clean command + tSpPri.uUiPri = N_DATA_REQ; + tSpPri.wConnId = tUl.wConnId; + pUPri->tPriNDataReq.tUD.uDataLen = aifclcd_dt1_msg_len; + memcpy ( &pUPri->tPriNDataReq.tUD.aUserData, aifclcd_dt1_msg, pUPri->tPriNDataReq.tUD.uDataLen ); + ulLogMsg ( &tSpPri, 1 ,&pUPri->tPriNDataReq.tUD); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_CLCD state" ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_CLCD" ); + return; + case DST_CLCE: //clean complete + if( SpSubmit ( &tSpPri , 3) ) + { + WxcAssert ( tSpPri.uUiPri == N_DATA_IND, "ul recv pri error while DST_CLCE state" ); + ulLogMsg ( &tSpPri, 0 , &pUPri->tPriNDataInd.tUD); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_CLCE" ); + return ; + } + break; + case DST_DISCONN: + tSpPri.uUiPri = N_DISCONNECT_REQ; + tSpPri.wConnId = tUl.wConnId; + + pUPri->tPriNDisconnReq.eREA = REA_UDISC_EUF; + pUPri->tPriNDisconnReq.tUD.uDataLen = aiflu_rlsd_msg_len; + pUPri->tPriNDisconnReq.uOptFlag = 0x00; + ulLogMsg ( &tSpPri, 1 , NULL); + WxcAssert ( PostSp ( &tSpPri ), "ul post pri error while DST_DISCONN state" ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + ulLogState( tUl.uUlSide ,"DST_DISCONN" ); + return; + default: + printf ( "\n\n\n======================SP Dst Test End=================\n\n\n" ); + exit(1); + break; + } + if( DST_IDLE == tUl.uUlState ) + { + if( tUl.uUlTestStartTimer++ >= tUl.uWaitTimer ) + { + printf ( "\n\n\n======================SP Dst Test Start=================\n\n\n" ); + tUl.uUlState++; + tUl.uUlStateInterval = 0; + } + } + else + { + if( tUl.uUlStateInterval++ >= 200 ) + { + //WxcAssert ( tUl.uUlState != DST_RECV_UDT, "DST_RECV_UDT state timer out" ); + //WxcAssert ( tUl.uUlState != DST_CR, "DST_CR state timer out" ); + //WxcAssert ( tUl.uUlState != DST_CLCE, "DST_CLCE state timer out" ); + tUl.uUlStateInterval = 0; + } + } + } +} + +void ll_cr ( ) +{ + +} + +void ll_cc ( ) +{ + +} + +void ll_cref ( ) +{ + +} + +void ll_rlsd ( ) +{ + +} + +void ll_rlc ( ) +{ + +} + +void ll_udt ( ) +{ + +} + +void ll_dt1 ( ) +{ + +} + +void ll_sap ( ) +{ + +} diff --git a/plat/scf/Makefile b/plat/scf/Makefile new file mode 100644 index 0000000..b6c697f --- /dev/null +++ b/plat/scf/Makefile @@ -0,0 +1,92 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module Version : V1.4 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/06/18 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## +MODULE = scf +TYPE = plat + +DBUG_FLAGS_ADD = -D_REENTRANT +RELS_FLAGS_ADD = -D_REENTRANT + +##Default commonly as below + +BUILD = lib +CFG = debug + +PLT_LIB = +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = ../../obj + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = /ut/ut_doc/output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/scf/src/include/scfdef.h b/plat/scf/src/include/scfdef.h new file mode 100644 index 0000000..5fac52f --- /dev/null +++ b/plat/scf/src/include/scfdef.h @@ -0,0 +1,12 @@ +#ifndef _SCF_HEAD +#define _SCF_HEAD + +#define TB_SCF 100 /* timer basis is 10ms */ +#define TIMER_INIT (TB_SCF*2) +/*2s timer after tcap_begin , the first operation should be received or sent*/ +#define TIMER_SHORT (TB_SCF*10) +#define TIMER_MEDIUM (TB_SCF*30) +#define TIMER_LONG (TB_SCF*600) + +#define SSN_SCF 0x93 +#endif diff --git a/plat/scf/src/include/scfmsg.h b/plat/scf/src/include/scfmsg.h new file mode 100644 index 0000000..b42afcb --- /dev/null +++ b/plat/scf/src/include/scfmsg.h @@ -0,0 +1,105 @@ +/************************************************/ +/*Title: scfmsg.h */ +/*Descr: WXC2R7.0-XAP Specification */ +/*Author: Liang Hongbin */ +/*Create: 2003-9-17 */ +/*Modify: */ +/************************************************/ + +#include "../../../xapp/src/capp/cap_head.h" +#include "../../../tcap/src/include/tcap_public.h" + +#ifndef _SCF_MESSAGE +#define _SCF_MESSAGE + +#define SCF_MAX_DLG_NUM MAX_DIALOGUEID +#define SCF_OPEN_LEN 128 +#define SCF_PORT_LEN 4 +#define CAP_CONTENT_LEN 256 +/*************************************/ +/*Macro----------------------------->*/ +/*************************************/ + +typedef struct _CAP_Message +{ + unsigned char msgLength[2]; /* unsigned char0 is the higher part */ + unsigned char msgServiceCode; /* fixed as 0xAF */ + unsigned char port_id[3]; /* unsigned char 0 is the higher part,unsigned char 1 is the lower part ,and unsigned char 2 is reserved */ + unsigned char dialogue_id[3]; + unsigned char msgOperaCode; /* message type code ,e.g , InitialDP = 0x00 */ + unsigned char msgOperaType; /* 1/2/3/4 = request, indicate, response, confirm */ + unsigned char msgContent[CAP_CONTENT_LEN]; + /* if the message if cap operation ,then the first unsigned char of msgContent is invoke id */ +}CAP_Message, *PCAP_Message; + +typedef struct _SCF_Open_Buffer +{ + unsigned char msgReadSub; + unsigned char msgWriteSub; + CAP_Message msgList[SCF_OPEN_LEN]; +}SCF_Open_Buffer, *PSCF_Open_Buffer; + +typedef struct _SCF_HPort_Buffer +{ + unsigned char msgReadSub; + unsigned char msgWriteSub; + CAP_Message msgList[SCF_PORT_LEN]; +}SCF_HPort_Buffer, *PSCF_HPort_Buffer; + +typedef struct _SCF_Port_Buffer +{ + SCF_HPort_Buffer inBuffer; /* PPS-SCSM */ + SCF_HPort_Buffer outBuffer; /* SCSM-PPS */ +}SCF_Port_Buffer, *PSCF_Port_Buffer; + +typedef struct _SCF_Buffer +{ + SCF_Open_Buffer openBuffer; + SCF_Port_Buffer portBuffer[SCF_MAX_DLG_NUM]; +}SCF_Buffer, *PSCF_Buffer; + + +typedef enum _SCSM_STATE +{ + SCF_IDLE=0, + SCF_INIT, + SCF_PREPARING_SSF_INSTRUCTIONS, + SCF_QUEUING_FSM, + SCF_WAITING_NOTIFICATION_OR_REQUEST, + SCF_DETERMINE_MODE, + SCF_WAITING_DISCONNECT_FORWARD_CONNECT, + SCF_WAITING_PLAYANNOUNCEMENT, + SCF_VPS_PROC, + SCF_SEND_END, +}_SCSM_STATE; + +//#define MAX_EDP_NUM 19 + +typedef struct _SCSM_DATA +{ + unsigned char State; + unsigned short portid; /* PPS port id */ + unsigned int Tinit; /* Timer waiting for InitialDP */ + unsigned int Twm; /* Timer waiting for message */ + unsigned int Tscf_ssf; + unsigned int Tassist; + unsigned char FirstResponse; + unsigned char endFlag; + unsigned char acn; + unsigned char acn_v; + unsigned char Tscf_ssfExpiryTimes; + unsigned char Pending; + unsigned char EDPs; + unsigned char EDP_flag[MAX_EDP_NUM]; + unsigned char invokeid; +}SCSM_DATA; + +/*** functions provided by SCSM ***/ +int PutScfOpen(CAP_Message cap_message); +int GetScfOpen(PCAP_Message pcap_message); +int PutScfMsg(CAP_Message cap_message); /* SCSM -> PPS */ +int GetScfMsg(PCAP_Message pcap_message, unsigned short dlgid); /* SCSM <- PPS*/ +int WriteScfMsg(CAP_Message cap_message); /* PPS -> SCSM */ +int ReadScfMsg(PCAP_Message pcap_message, unsigned short dlgid); /* PPS <- SCSM */ +int ClearPortSub(unsigned short dlgid); +#endif diff --git a/plat/scf/src/include/scfpub.h b/plat/scf/src/include/scfpub.h new file mode 100644 index 0000000..5b3f7b4 --- /dev/null +++ b/plat/scf/src/include/scfpub.h @@ -0,0 +1,5 @@ +#ifndef _SCF_PUBLIC_H +#define _SCF_PUBLIC_H +int scsm_init(); +int scsm(); +#endif diff --git a/plat/scf/src/scfmsg.c b/plat/scf/src/scfmsg.c new file mode 100644 index 0000000..b387ac6 --- /dev/null +++ b/plat/scf/src/scfmsg.c @@ -0,0 +1,170 @@ +/* Title: SCF msgfunction c file */ +/* Writer: Liang Hongbin */ +/* Version: 1.0 */ +/* Date: 2003-09-18 */ +/* ------------------------------ */ +#include +//#include "scfdef.h" +#include "./include/scfmsg.h" + +_SCSM_STATE SCSM_STATE; + +SCF_Buffer scf_buffer; +/*-----------------------------------------------------------*/ +/* Functions invoked by SCSM to put/get message from/to buffer for PPS */ +int PutScfOpen(CAP_Message cap_message) +{ + unsigned char msgWriteSub; + PSCF_Open_Buffer popen_ptr; + + popen_ptr = &scf_buffer.openBuffer; + msgWriteSub = popen_ptr->msgWriteSub%SCF_OPEN_LEN; + memcpy(&popen_ptr->msgList[msgWriteSub], + &cap_message, + sizeof(CAP_Message)); + popen_ptr->msgWriteSub = + (popen_ptr->msgWriteSub+1)%SCF_OPEN_LEN; + if(popen_ptr->msgWriteSub == popen_ptr->msgReadSub){ + popen_ptr->msgReadSub = + (popen_ptr->msgReadSub+1)%SCF_OPEN_LEN; + + } + return 1; +} + +int GetScfOpen(PCAP_Message pcap_message) +{ + unsigned char msgReadSub, msgWriteSub; + PSCF_Open_Buffer popen_ptr; + + popen_ptr = &scf_buffer.openBuffer; + msgReadSub = popen_ptr->msgReadSub%SCF_OPEN_LEN; + msgWriteSub = popen_ptr->msgWriteSub; + + if(msgReadSub == msgWriteSub) + return 0; + memcpy(pcap_message, + &popen_ptr->msgList[msgReadSub], + sizeof(CAP_Message)); + popen_ptr->msgReadSub = + (popen_ptr->msgReadSub + 1)%SCF_OPEN_LEN; + return 1; +} + +int PutScfMsg(CAP_Message cap_message) +{ + int writesub,readsub; + int did; + PSCF_HPort_Buffer pOutBuf; + + did = (cap_message.dialogue_id[0] *256) + + cap_message.dialogue_id[1]; + if(did >= SCF_MAX_DLG_NUM) + return 0; + if (cap_message.msgOperaCode == CAP_O_OPEN + && cap_message.msgOperaType == 0x02)//INDICATE + { + // + } + pOutBuf = &scf_buffer.portBuffer[did].outBuffer; + writesub = pOutBuf->msgWriteSub%SCF_PORT_LEN; + readsub = pOutBuf->msgReadSub; + memcpy(&pOutBuf->msgList[writesub], + &cap_message, + sizeof(CAP_Message)); + pOutBuf->msgWriteSub = + (pOutBuf->msgWriteSub + 1) % SCF_PORT_LEN; + if (pOutBuf->msgReadSub == pOutBuf->msgWriteSub) + pOutBuf->msgReadSub = + (pOutBuf->msgReadSub + 1) % SCF_PORT_LEN; + return 1; +} + +int GetScfMsg(PCAP_Message pcap_message,unsigned short dlgid) +{ + int readsub,writesub; + PSCF_HPort_Buffer pInBuf; + + if(dlgid>=SCF_MAX_DLG_NUM) return 0; + pInBuf = &scf_buffer.portBuffer[dlgid].inBuffer; + readsub = pInBuf->msgReadSub % SCF_PORT_LEN; + writesub = pInBuf->msgWriteSub; + + if(readsub == writesub) + return 0; + memcpy(pcap_message, + &pInBuf->msgList[readsub], + sizeof(CAP_Message)); + pInBuf->msgReadSub = + (pInBuf->msgReadSub + 1) % SCF_PORT_LEN; + return 1; +} +/* Functions invoked by SCSM to put/get message from/to buffer for PPS */ +int ReadScfMsg(PCAP_Message pcap_message, unsigned short dlgid) +{ + PSCF_HPort_Buffer pOutBuf; + + if(dlgid>=SCF_MAX_DLG_NUM) return 0; + pOutBuf = &scf_buffer.portBuffer[dlgid].outBuffer; + if (pOutBuf->msgReadSub == pOutBuf->msgWriteSub) + return 0; + memcpy(pcap_message, + &pOutBuf->msgList[pOutBuf->msgReadSub%SCF_PORT_LEN], + sizeof(CAP_Message)); + pOutBuf->msgReadSub = + (pOutBuf->msgReadSub + 1) % SCF_PORT_LEN; + + return 1; +} + +int WriteScfOpen(CAP_Message cap_message) +{ + unsigned char msgReadSub, msgWriteSub; + PSCF_Open_Buffer popen_ptr; + + popen_ptr = &scf_buffer.openBuffer; + msgReadSub = popen_ptr->msgReadSub; + msgWriteSub = popen_ptr->msgWriteSub%SCF_OPEN_LEN; + + memcpy(&popen_ptr->msgList[msgWriteSub], + &cap_message, + sizeof(CAP_Message)); + popen_ptr->msgWriteSub = + (popen_ptr->msgWriteSub + 1)%SCF_OPEN_LEN; + return 1; +} + +int WriteScfMsg(CAP_Message cap_message) +{ + unsigned int did; + PSCF_HPort_Buffer pInBuf; + + did = cap_message.dialogue_id[0]*256 + + cap_message.dialogue_id[1]; + + if(did >= SCF_MAX_DLG_NUM) + return 0; + + pInBuf = &scf_buffer.portBuffer[did].inBuffer; + + memcpy(&pInBuf->msgList[pInBuf->msgWriteSub%SCF_PORT_LEN], + &cap_message, + sizeof(CAP_Message)); + pInBuf->msgWriteSub = + (pInBuf->msgWriteSub + 1) % SCF_PORT_LEN; + if (pInBuf->msgReadSub == pInBuf->msgWriteSub) + pInBuf->msgReadSub = + (pInBuf->msgReadSub + 1) % SCF_PORT_LEN; + return 1; +} + +int ClearPortSub(unsigned short dlgid) +{ + if(dlgid>=SCF_MAX_DLG_NUM) return 0; + scf_buffer.portBuffer[dlgid].inBuffer.msgWriteSub = 0; + scf_buffer.portBuffer[dlgid].inBuffer.msgReadSub = 0; + scf_buffer.portBuffer[dlgid].outBuffer.msgWriteSub = 0; + scf_buffer.portBuffer[dlgid].outBuffer.msgReadSub = 0; + return 1; +} +/*-----------------------------------------------------------*/ diff --git a/plat/scf/src/scsm.c b/plat/scf/src/scsm.c new file mode 100644 index 0000000..304b701 --- /dev/null +++ b/plat/scf/src/scsm.c @@ -0,0 +1,976 @@ +/* Title: SCF fsm c file */ +/* Writter: Liang Hongbin */ +/* Version: 1.0 */ +/* Date: 2003-09-18 */ +/* ------------------------------ */ +#include "../../public/src/include/includes.h" +#include "../../xapp/src/ixap.h" +#include "../../xapp/src/capp/cap_msg.h" +#include "./include/scfdef.h" +#include "./include/scfmsg.h" +#include "./include/scfpub.h" + +// fix multiple definition==================================== +extern _SCSM_STATE SCSM_STATE; +// + +extern SCF_Buffer scf_buffer; +SCSM_DATA scsm_data[SCF_MAX_DLG_NUM]; + +CAP_Message scfOpenResponse={ + {0,16}, + CAP_FLAG, + {0,0,0}, + {0,0,0}, + 0xff,//CAP_O_OPEN, + 0x03,//RESPONSE, + {2, //RESULT=accept + 1, // + 1, //acn tag + 2, //len + 50, //acn + 2, //acn version + 0,} //end flag +}; + +CAP_Message scfEnd={ + {0,12}, + CAP_FLAG, + {0,0,0}, + {0,0,0}, + 0xfe,//CAP_O_END, + 0x01,//REQUEST, + {1, //release method + 0, //optional part + 0,} +}; + +CAP_Message scfPAbort={ + {0,11}, + CAP_FLAG, + {0,0,0}, + {0,0,0}, + CAP_O_PABORT, + 0x02,//INDICATE, + {0, //provider reason + 0,} // +}; + +CAP_Message scfUAbort={ + {0,12}, + CAP_FLAG, + {0,0,0}, + {0,0,0}, + CAP_O_UABORT, + 0x01,//request, + {1, //user error + 0,0,} // +}; +/*---------------------------------------------------------*/ +void scfSendOpenResponse(unsigned char acn,unsigned char acn_v,unsigned short dlgid) +{ + CAP_Message capmsg; + + //tcap_change_local_ssn(dlgid,147,146); + memcpy(&capmsg,&scfOpenResponse,18); + capmsg.dialogue_id[0] = dlgid>>8; + capmsg.dialogue_id[1] = dlgid; + capmsg.msgContent[4] = acn; + capmsg.msgContent[5] = acn_v; + cap_send_comdata((unsigned char *)&capmsg); +} + +void scfSendOprDataToXAP(unsigned short dlgid,unsigned char *dataflow) +{ + SCSM_DATA *scf_ptr; + + if(dlgid >= SCF_MAX_DLG_NUM) + return; + scf_ptr = &scsm_data[dlgid]; + if(!scf_ptr->FirstResponse){ + scfSendOpenResponse(scf_ptr->acn,scf_ptr->acn_v,dlgid); + scf_ptr->FirstResponse = 1; + } + if(scf_ptr->endFlag) + { + + } + cap_send_oprdata(dataflow); +} +/*---------------------------------------------------------*/ +void ResetTscf_ssf(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + + if(dlgid >= SCF_MAX_DLG_NUM) + return; + scf_ptr = &scsm_data[dlgid]; + scf_ptr->Tscf_ssf = 0; +} + +void ResetTscf_ssfExpiryTime(unsigned int dlgid) +{ + SCSM_DATA *scf_ptr; + + if(dlgid >= SCF_MAX_DLG_NUM) + return; + scf_ptr = &scsm_data[dlgid]; + scf_ptr->Tscf_ssfExpiryTimes = 0; +} + +void SendPAbortToSL(unsigned short dlgid) +{ + CAP_Message capmsg; + + memcpy(&capmsg,&scfPAbort, 14); + capmsg.dialogue_id[0] = dlgid>>8; + capmsg.dialogue_id[1] = dlgid; + PutScfMsg(capmsg); +} + +void SendUAbortToXAP(unsigned short dlgid,u_char u_error) +{ + CAP_Message capmsg; + + memcpy(&capmsg,&scfUAbort, 14); + capmsg.dialogue_id[0] = dlgid>>8; + capmsg.dialogue_id[1] = dlgid; + capmsg.msgContent[0] = u_error; +// capmsg.msgContent[0] = 1; + cap_send_comdata((unsigned char *)&capmsg); +} + +void SendEndToXAP(unsigned short dlgid) +{ + CAP_Message capmsg; + + memcpy(&capmsg,&scfEnd,14); + capmsg.dialogue_id[0] = dlgid>>8; + capmsg.dialogue_id[1] = dlgid; + cap_send_comdata((unsigned char *)&capmsg); +} +/*-------------------------------------------------*/ +int scfWaitingNotificationOrRequest(unsigned short dlgid) +{ + int edp,endflag=0; + int retval,msglen,ocode=0; + SCSM_DATA *scf_ptr; + CAP_Message capmsg; + CapArg capArg; + + if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE; + + scf_ptr = &scsm_data[dlgid]; + retval = scf_ptr->State; + if (cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode !=0xFA) + { + PutScfMsg(capmsg); + return SCF_IDLE; + } + } + + if (GetScfMsg(&capmsg,dlgid)) + { + switch(capmsg.msgOperaCode) + { + case CAP_OC_ActivityTest: + case CAP_OC_Connect: + break; + case CAP_OC_ApplyCharging: + scf_ptr->Pending ++; + break; + case CAP_OC_ReleaseCall: + case CAP_OC_ReleaseSMS: + endflag = 1; + retval = SCF_IDLE; + break; + default: //release call ,,, + break; + //scfDebugMsg("Received error operation in WaitingNotificationOrRequest"); + //SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return SCF_IDLE; + break; + } + capmsg.msgContent[0] = cap_get_invokeid(dlgid); + scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg); + if (endflag) + { + SendEndToXAP(dlgid); + retval = SCF_IDLE; + } + } + if(cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode != 0xFA) + { + PutScfMsg(capmsg); + retval = SCF_IDLE; + } + }else if(cap_get_oprdata((unsigned char *)&capmsg,dlgid)) + { + + PutScfMsg(capmsg); + ocode = capmsg.msgOperaCode; + msglen = capmsg.msgContent[3]*256+capmsg.msgContent[4]; + /* + if(msglen>256){ + retval = SCF_IDLE; + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return retval; + } + */ + switch(ocode) + { + case CAP_OC_ApplyChargingReport: + scf_ptr->Pending --; + if (scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){ + endflag = 1; + retval = SCF_IDLE; + } + break; + case CAP_OC_EventReportBCSM: + //revised later, liang hongbin 2002-09-26 + // if more EDP requested more EDPs should be taken into account + if(decode_capmsg((char *)&capmsg.msgContent[5],msglen,ocode,3,&capArg)<=0) + break; + edp = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM; + scf_ptr->EDPs --; + + if(scf_ptr->EDP_flag[edp] == (0xF0 | capp_interrupted)) + { + ResetTscf_ssf(dlgid); + ResetTscf_ssfExpiryTime(dlgid); + retval = SCF_PREPARING_SSF_INSTRUCTIONS; + } + else + { + if(scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){ + endflag = 1; + retval = SCF_IDLE; + } + } + + break; + case CAP_OC_EventReportSMS: + if(decode_capmsg((char *)&capmsg.msgContent[5],msglen,ocode,3,&capArg)<=0) + break; + edp = capArg.msg_list.eventReportSMSArg.eventTypeSMS; + + scf_ptr->EDPs --; + if(scf_ptr->EDP_flag[edp] == (0xF0 | capp_interrupted)) + { + ResetTscf_ssf(dlgid); + ResetTscf_ssfExpiryTime(dlgid); + retval = SCF_PREPARING_SSF_INSTRUCTIONS; + } + else + { + if(scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){ + endflag = 1; + retval = SCF_IDLE; + } + + } + + break; + case CAP_OC_ActivityTest: + break; + default: + endflag = 1; + retval = SCF_IDLE; + //scfDebugMsg("Receive error operation in capWaitingNotificationOrRequest"); + break; + } + if(endflag){ + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + } + } + return retval; +} + +int scfPreparingSsfInstructions(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + CAP_Message capmsg,*pcapmsg; + CapArg capArg; + int retval,len,i,endflag=0, + edp,edp_flag=0x00,edpnum=0x00; + CapRequestReportBCSMEvent *capRRE; + CapRequestReportSMSEvent *capRRSE; + + if(dlgid>=SCF_MAX_DLG_NUM) return 0; + scf_ptr = &scsm_data[dlgid]; + retval = scf_ptr->State; + + if (scf_ptr->Tscf_ssf ++ > TIMER_SHORT) + { + ResetTscf_ssf(dlgid); + if (scf_ptr->Tscf_ssfExpiryTimes ++ >= 2) + { + //scfDebugMsg("SCF timer expires while preparing ssf instructions!"); + //send cap_p_about to PPS + //send cap_p_about to XAP + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return SCF_IDLE; //end + } + } + if(cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode != 0xFA) + { + PutScfMsg(capmsg); + return SCF_IDLE; + } + } + if(!cap_check_sendopr(dlgid)) return retval; + pcapmsg = &capmsg; + if(GetScfMsg(pcapmsg,dlgid)) + { + switch (pcapmsg->msgOperaCode) + { + case CAP_OC_ApplyCharging: + scf_ptr->Pending ++; + break; + case CAP_OC_RequestReportBCSMEvent: + len = pcapmsg->msgContent[3]*256 + pcapmsg->msgContent[4]; + if(decode_capmsg((char *)&pcapmsg->msgContent[5], + len, + CAP_OC_RequestReportBCSMEvent, + 3, + &capArg)<=0) + break; + capRRE = &capArg.msg_list.requestReportBCSMEventArg; + edpnum = capRRE->bcsmEvents_num; + + for (i = 0;i < edpnum;i ++) + { + edp = capRRE->bcsmEvents[i].eventTypeBCSM; + switch(edp) + { + case capp_oAnswer: + case capp_tAnswer: + scf_ptr->EDPs ++; + break; + default: + edp_flag = 0x01; + break; + } + if (edp == capp_oDisconnect || edp == capp_tDisconnect) + scf_ptr->EDP_flag[edp] = 0xF0 | capp_interrupted; + else + scf_ptr->EDP_flag[edp] = 0xF0 | capRRE->bcsmEvents[i].monitorMode; + } + scf_ptr->EDPs += edp_flag; + + break; + case CAP_OC_RequestReportSMSEvent: + len = pcapmsg->msgContent[3]*256 + pcapmsg->msgContent[4]; + if(decode_capmsg((char *)&pcapmsg->msgContent[5], + len, + CAP_OC_RequestReportSMSEvent, + 3, + &capArg)<=0) + break; + capRRSE = &capArg.msg_list.requestReportSMSEventArg; + edpnum = capRRSE->sMSEvents_num; + + for (i = 0;i < edpnum;i ++) + { + edp = capRRSE->sMSEvents[i].eventTypeSMS; + switch(edp) + { + case capp_osmsFailure: + case capp_osmsSubmitted: + scf_ptr->EDPs = 1; + break; + } + scf_ptr->EDP_flag[edp] = + 0xF0 | capRRSE->sMSEvents[i].monitorMode; + } + + break; + case CAP_OC_Continue: + case CAP_OC_ContinueSMS: + if (scf_ptr->EDPs > 0 || scf_ptr->Pending > 0) + retval = SCF_WAITING_NOTIFICATION_OR_REQUEST; + else + { + endflag = 1; + retval = SCF_IDLE; + } + break; + case CAP_OC_ReleaseCall: + case CAP_OC_ReleaseSMS: + //if (scf_ptr->EDPs > 0 || scf_ptr->Pending > 0) + // retval = SCF_WAITING_NOTIFICATION_OR_REQUEST; + //else{ + endflag = 1; + retval = SCF_IDLE; + //} + break; + case CAP_OC_Cancel: + retval = SCF_IDLE; + break; + case CAP_OC_ActivityTest: + break; + case CAP_OC_EstablishTemporaryConnection: + retval = SCF_WAITING_DISCONNECT_FORWARD_CONNECT; + break; + case CAP_O_UABORT: + SendUAbortToXAP(dlgid,pcapmsg->msgContent[0]); + return SCF_IDLE; + break; + case CAP_OC_InitialDP: + endflag = 1; + retval = SCF_IDLE; + break; + case CAP_OC_Connect: + if (scf_ptr->EDPs > 0 || scf_ptr->Pending > 0) + retval = SCF_WAITING_NOTIFICATION_OR_REQUEST; + else + { + endflag = 1; + retval = SCF_IDLE; + } + break; + case CAP_O_END: + SendEndToXAP(dlgid); + return (retval = SCF_IDLE); + break; + default: + // SendEndToXAP(dlgid); + // return (retval = SCF_IDLE); + break; + } + if (endflag) + { + if(pcapmsg->msgContent[2] == 0x02) + pcapmsg->msgContent[0]=scf_ptr->invokeid; + else + pcapmsg->msgContent[0]=cap_get_invokeid(dlgid); + scf_ptr->endFlag = 1; + scfSendOprDataToXAP(dlgid,(unsigned char *)pcapmsg); +// SendEndToXAP(dlgid); + // retval = SCF_IDLE; + retval = SCF_SEND_END; + } + else + { + if(pcapmsg->msgContent[2] == 0x02) + pcapmsg->msgContent[0]=scf_ptr->invokeid; + else + pcapmsg->msgContent[0]=cap_get_invokeid(dlgid); + scfSendOprDataToXAP(dlgid,(unsigned char *)pcapmsg); + } + + ResetTscf_ssf(dlgid); + //ResetTimer(dlgid); + } + return retval; +} + +int scfVPSProc(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + CAP_Message *pcapmsg,capmsg; + + if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE; + scf_ptr = &scsm_data[dlgid]; + + if (scf_ptr->Tinit++ >= TIMER_INIT) + { + //scfDebugMsg("SCF timer expires while waiting + //send cap_p_about to PPS + //send cap_p_about to XAP + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return SCF_IDLE; //end + } + if(cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode !=0xFA){ + PutScfMsg(capmsg); + return SCF_IDLE; + } + } + pcapmsg = &capmsg; + if(GetScfMsg(pcapmsg,dlgid)) + { + if (pcapmsg->msgOperaCode != CAP_OC_PlayAnnouncement + && pcapmsg->msgOperaCode != 0xb1) + { + //scfDebugMsg("Receive error msg from uplayer in VPS proc"); + return SCF_IDLE; + } + pcapmsg->msgContent[0] = cap_get_invokeid(dlgid); + scfSendOprDataToXAP(dlgid,(unsigned char *)pcapmsg); + return SCF_SEND_END; + } + return SCF_VPS_PROC; +} + +int scfInitProc(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + CAP_Message capmsg; + int retval; + + + scf_ptr = &scsm_data[dlgid]; + + retval = scf_ptr->State; + if (scf_ptr->Tinit++ >= TIMER_INIT) + { + //scfDebugMsg("SCF timer expires while waiting for Initial Message!"); + //send cap_p_about to PPS + //send cap_p_about to XAP + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return SCF_IDLE; //end + } + + if(cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode !=0xFA){ + PutScfMsg(capmsg); + return SCF_IDLE; + } + }else if(cap_get_oprdata((unsigned char *)&capmsg,dlgid)) + { + scf_ptr->invokeid = capmsg.msgContent[0]; + switch(capmsg.msgOperaCode) + { + case CAP_OC_InitialDP: + case CAP_OC_InitialDPSMS: + PutScfMsg(capmsg); + ResetTscf_ssf(dlgid); + retval = SCF_PREPARING_SSF_INSTRUCTIONS; + break; + case CAP_OC_VPSOprRequest: + PutScfMsg(capmsg); + retval = SCF_VPS_PROC; + break; + case CAP_OC_AssistRequestInstructions: + PutScfMsg(capmsg); + retval = SCF_WAITING_PLAYANNOUNCEMENT;//??? + break; + default: + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + retval = SCF_IDLE; + break; + } + }else if(GetScfMsg(&capmsg,dlgid)) + { + capmsg.msgContent[0] = cap_get_invokeid(dlgid); + cap_send_comdata((unsigned char *)&capmsg); + return SCF_IDLE; + } + return retval; +} + +/* +int scfDetermineMode(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + int retval, len; + int invokeid, DisconnectFromSRF=0; + CAP_Message capmsg; + CapArg capArg; + CapPlayAnnouncement *capPA; + CapPromptAndCollectUserInformation *capPCUI; + + if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE; + scf_ptr = &scsm_data[dlgid]; + retval = scf_ptr->State; + + if(scf_ptr->Twm++>TIMER_SHORT){ + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return SCF_IDLE; + } + if(cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode !=0xFA){ + PutScfMsg(capmsg); + return SCF_IDLE; + } + } + if(GetScfMsg(&capmsg,dlgid)) + { + switch(capmsg.msgOperaCode) + { + case CAP_OC_ConnectToResource: + break; + case CAP_OC_PlayAnnouncement: + len = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + decode_capmsg(&capmsg.msgContent[5], + len, + CAP_OC_PlayAnnouncement, + 3, + &capArg); + capPA = &capArg.msg_list.playAnnouncementArg; + if(capPA->optional_flag & 0x01) + { + DisconnectFromSRF = + 1 - capPA->disconnectFromIPForbidden; + }else{ + DisconnectFromSRF = 0; + } + break; + case CAP_OC_PromptAndCollectUserInformation: + len = capmsg.msgContent[3]*256 + capmsg.msgContent[4]; + decode_capmsg(&capmsg.msgContent[5], + len, + CAP_OC_PromptAndCollectUserInformation, + 3, + &capArg); + capPCUI = &capArg.msg_list.promptAndCollectUserInformationArg; + if(capPCUI->optional_flag & 0x01) + { + DisconnectFromSRF = + 1 - capPCUI->disconnectFromIPForbidden; + }else{ + DisconnectFromSRF = 0; + } + +// retval = SCF_WAITING_RESPONSE_FROM_SRF; + break; + case CAP_OC_EstablishTemporaryConnection: + scf_ptr->Twm = 0; + scf_ptr->Tassist = 0; + //correlationID = dlgid; + retval = SCF_WAITING_DISCONNECT_FORWARD_CONNECT; + break; + case CAP_OC_Connect: + break; + default: + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return SCF_IDLE; + break; + } + invokeid = cap_get_invokeid(dlgid); + capmsg.msgContent[0] = invokeid; + scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg); + + if(DisconnectFromSRF) + { + scf_ptr->DisconnectFromSRF = 1; + scf_ptr->DisconnectLinkID = invokeid; + } + } + + return retval; +} +*/ +int scfWaitinDisconnectForwardConnection(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + int retval, + invokeid; + int ocode,endflag=0; + CAP_Message capmsg; + + + if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE; + scf_ptr = &scsm_data[dlgid]; + retval = scf_ptr->State; + + if(scf_ptr->Tassist++>(TIMER_SHORT*8)){ + return SCF_PREPARING_SSF_INSTRUCTIONS; + } + + if(cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode !=0xFA) + { + PutScfMsg(capmsg); + return SCF_IDLE; + } + } + + if(GetScfMsg(&capmsg,dlgid)) + { + switch(capmsg.msgOperaCode) + { + case CAP_OC_DisconnectForwardConnection: + retval = SCF_PREPARING_SSF_INSTRUCTIONS; + break; + case CAP_OC_ActivityTest: + scf_ptr->Tassist=0; + break; + case CAP_OC_ReleaseCall: + endflag = 1; + retval = SCF_IDLE; + break; + case CAP_O_UABORT: + SendUAbortToXAP(dlgid,capmsg.msgContent[0]); + return SCF_IDLE; + break; + default: + break; + //SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + return SCF_IDLE; + break; + } + invokeid = cap_get_invokeid(dlgid); +// capmsg.dialogue_id[0] = dlgid>>8; +// capmsg.dialogue_id[1] = dlgid; + capmsg.msgContent[0] = invokeid; + if(endflag){ + scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg); + SendEndToXAP(dlgid); + retval = SCF_IDLE; + }else{ + scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg); + } + } + endflag = 0; + if(cap_get_oprdata((unsigned char *)&capmsg,dlgid)) + { + + PutScfMsg(capmsg); + ocode = capmsg.msgOperaCode; + switch(ocode) + { + case CAP_OC_EventReportBCSM: + //revised later, liang hongbin 2002-09-26 + // if more EDP requested more EDPs should be taken into account + /* + decode_capmsg(&capmsg.msgContent[5],msglen,ocode,3,&capArg); + edp = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM; + scf_ptr->EDPs --; + if(scf_ptr->EDP_flag[edp] == (0xF0 | capp_interrupted)) + { + ResetTscf_ssf(dlgid); + ResetTscf_ssfExpiryTime(dlgid); + retval = SCF_PREPARING_SSF_INSTRUCTIONS; + } + else + { + if(scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){ + endflag = 1; + retval = SCF_IDLE; + } + } + */ + break; + case CAP_OC_ActivityTest: + case CAP_OC_EstablishTemporaryConnection: + scf_ptr->Tassist=0; + break; + default: + endflag = 1; + retval = SCF_IDLE; + break; + } + if(endflag){ + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + } + } + return retval; +} + +/*-----------------------------------------------------*/ +int scfWaitingPlayAnnouncement(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + int retval; + int invokeid; + CAP_Message capmsg; + + if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE; + scf_ptr = &scsm_data[dlgid]; + retval = scf_ptr->State; + + if(scf_ptr->Tassist++>TIMER_LONG) + { + SendPAbortToSL(dlgid); + SendEndToXAP(dlgid); + scf_ptr->endFlag = 1; + return SCF_IDLE; + } + if(cap_get_comdata((unsigned char *)&capmsg,dlgid)) + { + if(capmsg.msgOperaCode !=0xFA) + { + PutScfMsg(capmsg); + return SCF_IDLE; + } + } + + + if(cap_get_oprdata((unsigned char *)&capmsg,dlgid)) + { + scf_ptr->Tassist = 0; + switch(capmsg.msgOperaCode) + { + case CAP_OC_SpecializedResourceReport: + break; + case CAP_OC_PromptAndCollectUserInformation: + break; + default: + return retval; + break; + } + capmsg.dialogue_id[0] = dlgid>>8; + capmsg.dialogue_id[1] = dlgid; + PutScfMsg(capmsg); + }else if(GetScfMsg(&capmsg,dlgid)) + { + scf_ptr->Tassist = 0; + switch(capmsg.msgOperaCode) + { + case CAP_O_UABORT: + SendUAbortToXAP(dlgid,capmsg.msgContent[0]); + scf_ptr->endFlag = 1; + return SCF_IDLE; + break; + case CAP_O_END: + SendEndToXAP(dlgid); + scf_ptr->endFlag = 1; + return SCF_IDLE; + break; + default: + break; + } + if(capmsg.msgContent[2] == 0x02) //u_error + { + invokeid = scf_ptr->invokeid; + } + else + invokeid = cap_get_invokeid(dlgid); + capmsg.dialogue_id[0] = dlgid>>8; + capmsg.dialogue_id[1] = dlgid; + capmsg.msgContent[0] = invokeid; + scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg); + } + + return retval; +} + +int scfSendTCEnd(u_short dlgid) +{ + int retval = 0; + CAP_Message *pcapmsg,capmsg; + + if(cap_check_sendcom(dlgid)) + { + pcapmsg = &capmsg; + memcpy(pcapmsg,&scfEnd,14); + pcapmsg->dialogue_id[0] = dlgid>>8; + pcapmsg->dialogue_id[1] = dlgid; + cap_send_comdata((unsigned char *)pcapmsg); + retval = 1; + } + return retval; +} +/*-----------------------------------------------------*/ + +int scsm_init() +{ + icap_reg_ssn(SSN_SCF); + return 1; +} + +int ClearThreadData(unsigned short dlgid) +{ + if(dlgid>=SCF_MAX_DLG_NUM) return 0; + memset(&scsm_data[dlgid],0,sizeof(SCSM_DATA)); + return 1; +} + + +int scsmGetOpen() +{ + register int id; + unsigned short dlgid; + CAP_Message capmsg; + + for(id=0;id<64;id++) + { + if(!cap_get_open((unsigned char *)&capmsg,SSN_SCF)) + return 1; +/* + if(capmsg.msgOperaCode != CAP_O_OPEN) + continue; +*/ + dlgid = capmsg.dialogue_id[0]*256+capmsg.dialogue_id[1]; + if(dlgid>=SCF_MAX_DLG_NUM) + continue; + if(scsm_data[dlgid].State != SCF_IDLE) + continue; + + ClearPortSub(dlgid); + ClearThreadData(dlgid); + + PutScfOpen(capmsg); + + scsm_data[dlgid].State = SCF_INIT; + scsm_data[dlgid].acn = capmsg.msgContent[0]; + scsm_data[dlgid].acn_v = capmsg.msgContent[1]; + } + return 1; +} + + +int scf_fsm(unsigned short dlgid) +{ + SCSM_DATA *scf_ptr; + + scf_ptr = &scsm_data[dlgid]; + + switch (scf_ptr->State) + { + case SCF_IDLE: + break; + case SCF_INIT: + scf_ptr->State = scfInitProc(dlgid); + break; + case SCF_PREPARING_SSF_INSTRUCTIONS: + scf_ptr->State = scfPreparingSsfInstructions(dlgid); + break; + case SCF_WAITING_NOTIFICATION_OR_REQUEST: + scf_ptr->State = scfWaitingNotificationOrRequest(dlgid); + break; + case SCF_WAITING_DISCONNECT_FORWARD_CONNECT: + scf_ptr->State = scfWaitinDisconnectForwardConnection(dlgid); + break; + case SCF_WAITING_PLAYANNOUNCEMENT: + scf_ptr->State = scfWaitingPlayAnnouncement(dlgid); + break; + case SCF_VPS_PROC: + scf_ptr->State = scfVPSProc(dlgid); + break; + case SCF_SEND_END: + scfSendTCEnd(dlgid); + scf_ptr->State = SCF_IDLE; + break; + default: + scf_ptr->State = SCF_IDLE; + break; + } + return 0; +} + +int scsm() +{ + register int id; + + scsmGetOpen(); + + for(id=0;id Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = smpp +TYPE = plat + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/smpp/src/include/smpp.h b/plat/smpp/src/include/smpp.h new file mode 100644 index 0000000..549ec98 --- /dev/null +++ b/plat/smpp/src/include/smpp.h @@ -0,0 +1,187 @@ +/* +** CDMA 2000 project, SMPP module +** +** File name: smpp.h +** Written by Li Long at 2004-11-25 +** CVS $Id: smpp.h,v0.1 2004/11/25 17:03:14 lilong Exp $ +** +*/ +#ifndef _SMPP_h +#define _SMPP_h + + +#include "smpp_public.h" +#include "smpp_const.h" +#include "../../../debug/src/include/debug.h" +#include "../../../sccp/src/include/sccp.h" +#include "../../../iptrans/src/include/iptrans.h" +#include "../../../mtp3/src/include/mtp3.h" +#include "../../../snmp/src/include/snmp.h" +#include "../../../public/src/include/public.h" + +#include "smpp_msg.h" + +enum SMPP_State_Constant {INIT, IDLE, WAITING, ESTABLISHED, SUSPEND}; +enum SMPP_APIEvent {APIEventReversed, Register, Setup, Close}; +enum SMPP_InterEvent {InterEventReserved, Outbind, Unbind, UnbindResp, + BindTransmitter, BindReceiver, BindTransceiver, //4 + BindTransmitterResp, BindReceiverResp, BindTransceiverResp, //7 + EnquireLink, EnquireLinkResp, //10 + SubmitSM, SubmitSMResp, //12 + SubmitMulti, SubmitMultiResp, //14 + DeliverSM, DeliverSMResp, //16 + DataSM, DataSMResp, //18 + GenericNak, //20 + SessionInitTimeout, EnquireLinkTimeout, InactivityTimeout, ResponseTimeOut, //21 + QuerySM, QuerySMResp, //25 + CancelSM, CancelSMResp, //27 + ReplaceSM, ReplaceSMResp, //29 + AlertNotification, //31 + UnknownCommandID}; //32 + +typedef struct SMPP_LINK +{ + DWORD seq_num; + DWORD command_status; +}SMPP_LINK; + +typedef struct SMPP_DEBUG_STRUCT +{ + BYTE debug_switch; + BYTE link_switch[MAX_SMPP_LINK]; +}SMPP_DEBUG_STRUCT; + +typedef struct SMPP_PARAM +{ + BYTE link_no; //0~31 + BYTE link_enable; //0-Disable, 1-Enable + BYTE link_type; //0-UDP 1-TCP + BYTE server_type; //0-SMPP_CLIENT; 1-SMPP_SERVER + BYTE session_type; //0-BIND_TX; 1-BIND_RX; 2-BIND_TRX + char sys_id[16]; + char password[9]; + char system_type[13]; + char localGTT[16]; + char remoteGTT[16]; + DWORD local_ip; + DWORD remote_ip; + DWORD session_init_timer; + DWORD enquire_link_timer; + DWORD inactivity_timer; + DWORD response_timer; + char service_number[8]; + BYTE localSSN; + BYTE remoteSSN; + BYTE message_mode; +} SMPP_PARAM; + +// Inter-Function define +int smpp_Register(BYTE); +void smpp_PrimitiveSend(int linkNo, int command_id); + +void smpp_initTCPClient(); +void smpp_initTCPServer(); +void smpp_tcp_connect(int link); +void smpp_debugInit(); +void smpp_stateInit(); +void smpp_msgInit(); +void smpp_debugTimer(); +char *smpp_getLocalIP(); +void smpp_setupTCPLink(int); +void smpp_rvMsgOverSCCP(BYTE sccp_usertype); +void smpp_rvMsgOverTCP(); +WORD smpp_getServerPort(); +DWORD smpp_getSequenceNumber(int); +int smpp_decode_msg(int, SMPP_GENERAL*, int); +int smpp_closeTCPConnection(int); +int smpp_encode_msg(int, SMPP_MSG *, int); +void smpp_setSccpAddr(int, SCCP_ADDR *, SCCP_ADDR *); +BYTE smpp_ascii2GTAI(BYTE *pGTAI, char *pGTT); +void smpp_GTAI2ascii(char *, BYTE *, BYTE); +void smpp_send_ascout(char *); +void smpp_send_error(char *); +void smpp_display_hex_msg(BYTE* disp_ptr, int len); +void smpp_command_id_to_string(char *comm_str, DWORD command_id); +void smpp_command_status_to_string(char* status_str, DWORD command_status); +void smpp_ton_to_string(char* ton_str, BYTE ton); +void smpp_npi_to_string(char* npi_str, BYTE npi); + +void smpp_sendBindResp(int, int, DWORD command_status); +void smpp_sendUnbind(int); +void smpp_sendUnbindResp(int); +void smpp_sendEnquireLink(int); +void smpp_sendEnquireLinkResp(int); +void smpp_sendOutbind(int); +void smpp_sendBind(int, int); +void smpp_sendGenericNack(int, DWORD, DWORD); +void smpp_sendResponse(int , DWORD , DWORD , DWORD ); + +void smpp_addTLV(BYTE *, WORD, BYTE *, WORD); + +int smpp_loadParam(); +int smpp_writeParam(); +void smpp_checkParam(); +int smpp_setParam(DWORD *oid, BYTE *pdata, WORD datalen); +void smpp_reset(); +void smpp_debug(DWORD mask, const char *fmt, ...); +void smpp_close(BYTE linkNo); +void smpp_mibInit(); +int smpp_decode_optional_parameter(SMPP_OPTIONAL_PARAMETER* opt_ptr, BYTE* msg_ptr, int t_len); +int smpp_check_sysid_route(char* sysid_rv, BYTE sysidlen_rv, BYTE server_type, BYTE session_type); +int smpp_decode_setup(BYTE link_type, int tcp_linkNo, BYTE src_ref, SMPP_GENERAL *pData, int len); + +/* TCP connection */ +typedef struct SocketsMsg +{ + int AcceptNum; + int ReadNum; + int ReadQueue[MAX_SMPP_LINK]; + int WriteNum; + int WriteQueue[MAX_SMPP_LINK]; + int ExceptNum; + int ExceptQueue[MAX_SMPP_LINK]; +}SocketsMsg; + +typedef struct SocketsInUse +{ + int DaemonSock; + int SockNum; + int Sockets[MAX_SMPP_LINK]; + int client_sock[MAX_SMPP_LINK]; + int server_sock[MAX_SMPP_LINK]; + u32 remote_ip[MAX_SMPP_LINK]; + fd_set readfds,writefds,exceptfds; + int Port; +}SocketsInUse; + +//SocketsMsg SockMsg; +int QuerySocketsMsg(); + +// Call back function define +//param1:linkNo; param2:msg mode; param3: pData; param4:pDataLen +typedef int (*smpp_callBack_dataProc) (BYTE, SMPP_MSG*, WORD); +//param1:linkNo; param2:link status +typedef int (*smpp_callBack_linkProc) (BYTE, BYTE); + +typedef struct SMPP_CALLBACK +{ + smpp_callBack_dataProc data_proc; + smpp_callBack_linkProc link_proc; +} SMPP_CALLBACK; + +// API +int smpp_init_new(u8 sys_id); //call in main program. +void smpp_fsm_new(); +BYTE smpp_registerLink(BYTE server_type, BYTE session_type, char* service_number_ptr, BYTE message_mode); +void smpp_attach_link(BYTE linkNo, + smpp_callBack_dataProc onDataRecv, + smpp_callBack_linkProc onLinkStateChange); + +/* return sequence number */ +WORD smpp_send(BYTE linkNo, SMPP_MSG* pMsg, WORD dataLen); + +void init_link(u32 link); + +#endif + + diff --git a/plat/smpp/src/include/smpp_const.h b/plat/smpp/src/include/smpp_const.h new file mode 100644 index 0000000..fc5c887 --- /dev/null +++ b/plat/smpp/src/include/smpp_const.h @@ -0,0 +1,240 @@ +//public constant define +#ifndef _SMPP_CONST_h +#define _SMPP_CONST_h + + +#define MAX_SMPP_LINK 32 +#define SMPP_LINK_QUEUE_NUM 32 //queue number per link +#define MAX_PACKET_SIZE 1500 +#define MAX_MSG_SIZE 1300 +#define SMPP_MSG_LEN 512 +#define MAX_ASCOUT_BUF_LEN 4096 +#define MAX_ASCIN_BUF_LEN 1024 +#define SMPP_MAX_MULTI_ADDRESS 5 +#define CMD_BUF_SIZE 8 +#define SMPP_PORT 2775 +#define SMPP_MODULE_VERSION "V1.0.01"//merge R9v0_02 p4 ot R90v0_12 p4 +#define SMPP_MODULE_PATCH 2 +#define TITLE_CHAR 2048 +#define SMPP_PPS_SSN 19 +#define SMPP_SMSC_SSN 20 +#define SMPP_PPS_USERTYPE 1 +#define SMPP_SMSC_USERTYPE 2 +#define SMPP_CONF_FILE "./conf/smpp.conf" +#define SMPP_CONF_FILE_w "./conf/smpp_w.conf" +#define SMPP_UDP 0 +#define SMPP_TCP 1 +#define SMPP_OID {1,3,6,1,4,1,1373,1,3,2,3,4} +#define SMPP_OIDLEN 12 +#define MAX_SME 1 +#define SMPP_VERSION 0x34 +#define SMPP_OPT_PARAM_NUM 64 + +#define SMPP_SYSID_LEN 16 +#define SMPP_PASSWD_LEN 9 +#define SMPP_SYSTYPE_LEN 13 +#define SMPP_GTT_LEN 16 + +/* time interval */ +#define SESSION_INIT_INTERVAL (50*5) /* 5s */ + +/* debug id */ +#define SMPP_DEBUG_ID 15 +#define SMPP_HEARTBEAT_COMPONENT_ID 9 + +// define if print screen and debug needed. +//#define SMPP_PRINT_SCREEN TRUE +#define SMPP_DEBUG true + +/* Define server mode */ +#define SMPP_CLIENT 0 +#define SMPP_SERVER 1 + +/* Define session type */ +#define BIND_TX 0 +#define BIND_RX 1 +#define BIND_TRX 2 + +/* Define message mode */ +#define STORE_AND_FORWARD 0 +#define DATAGRAM 1 +#define TRANSACTION 2 + +//command ID define +#define GENERIC_NAK 0x80000000 +#define BIND_RECEIVER 0x00000001 +#define BIND_RECEIVER_RESP 0x80000001 +#define BIND_TRANSMITTER 0x00000002 +#define BIND_TRANSMITTER_RESP 0x80000002 +#define QUERY_SM 0x00000003 +#define QUERY_SM_RESP 0x80000003 +#define SUBMIT_SM 0x00000004 +#define SUBMIT_SM_RESP 0x80000004 +#define DELIVER_SM 0x00000005 +#define DELIVER_SM_RESP 0x80000005 +#define UNBIND 0x00000006 +#define UNBIND_RESP 0x80000006 +#define REPLACE_SM 0x00000007 +#define REPLACE_SM_RESP 0x80000007 +#define CANCEL_SM 0x00000008 +#define CANCEL_SM_RESP 0x80000008 +#define BIND_TRANSCEIVER 0x00000009 +#define BIND_TRANSCEIVER_RESP 0x80000009 +#define OUTBIND 0x0000000B +#define ENQUIRE_LINK 0x00000015 +#define ENQUIRE_LINK_RESP 0x80000015 +#define SUBMIT_MULTI 0x00000021 +#define SUBMIT_MULTI_RESP 0x80000021 +#define ALERT_NOTIFICATION 0x00000102 +#define DATA_SM 0x00000103 +#define DATA_SM_RESP 0x80000103 + +/* Optional parameter tag definitions */ +#define DEST_ADDR_SUBUNIT 0x0005 +#define DEST_NETWORK_TYPE 0x0006 +#define DEST_BEARER_TYPE 0x0007 +#define DEST_TELEMATICS_ID 0x0008 +#define SOURCE_ADDR_SUBUNIT 0x000D +#define SOURCE_NETWORK_TYPE 0x000E +#define SOURCE_BEARER_TYPE 0x000F +#define SOURCE_TELEMATICS_ID 0x0010 +#define QOS_TIME_TO_LIVE 0x0017 +#define PAYLOAD_TYPE 0x0019 +#define ADDITIONAL_STATUS_INFO_TEXT 0x001D +#define RECEIPTED_MESSAGE_ID 0x001E +#define MS_MSG_WAIT_FACILITIES 0x0030 +#define PRIVACY_INDICATOR 0x0201 +#define SOURCE_SUBADDRESS 0x0202 +#define DEST_SUBADDRESS 0x0203 +#define USER_MESSAGE_REFERENCE 0x0204 +#define USER_RESPONSE_CODE 0x0205 +#define SOURCE_PORT 0x020A +#define DESTINATION_PORT 0x020B +#define SAR_MSG_REF_NUM 0x020C +#define LANGUAGE_INDICATOR 0x020D +#define SAR_TOTAL_SEGMENTS 0x020E +#define SAR_SEGMENT_SEQNUM 0x020F +#define SC_INTERFACE_VERSION 0x0210 +#define CALLBACK_NUM_PRES_IND 0x0302 +#define CALLBACK_NUM_ATAG 0x0303 +#define NUMBER_OF_MESSAGES 0x0304 +#define CALLBACK_NUM 0x0381 +#define DPF_RESULT 0x0420 +#define SET_DPF 0x0421 +#define MS_AVAILABILITY_STATUS 0x0422 +#define NETWORK_ERROR_CODE 0x0423 +#define MESSAGE_PAYLOAD 0x0424 +#define DELIVERY_FAILURE_REASON 0x0425 +#define MORE_MESSAGES_TO_SEND 0x0426 +#define MESSAGE_STATE 0x0427 +#define USSD_SERVICE_OP 0x0501 +#define DISPLAY_TIME 0x1201 +#define SMS_SIGNAL 0x1203 +#define MS_VALIDITY 0x1204 +#define ALERT_ON_MESSAGE_DELIVERY 0x130C +#define ITS_REPLY_TYPE 0x1380 +#define ITS_SESSION_INFO 0x1383 + +/* Command status definition. */ +#define ESME_ROK 0x00000000 +#define ESME_RINVMSGLEN 0x00000001 +#define ESME_RINVCMDLEN 0x00000002 +#define ESME_RINVCMDID 0x00000003 +#define ESME_RINVBNDSTS 0x00000004 +#define ESME_RALYBND 0x00000005 +#define ESME_RINVPRTFLG 0x00000006 +#define ESME_RINVREGDLVFLG 0x00000007 +#define ESME_RSYSERR 0x00000008 +/* #define Reserved 0x00000009 */ +#define ESME_RINVSRCADR 0x0000000A +#define ESME_RINVDSTADR 0x0000000B +#define ESME_RINVMSGID 0x0000000C +#define ESME_RBINDFAIL 0x0000000D +#define ESME_RINVPASWD 0x0000000E +#define ESME_RINVSYSID 0x0000000F +/* #define Reserved 0x00000010 */ +#define ESME_RCANCELFAIL 0x00000011 +/*#define Reserved 0x00000012 */ +#define ESME_RREPLACEFAIL 0x00000013 +#define ESME_RMSGQFUL 0x00000014 +#define ESME_RINVSERTYP 0x00000015 +/* #define Reserved 0x00000016-0x00000032 */ +#define ESME_RINVNUMDESTS 0x00000033 +#define ESME_RINVDLNAME 0x00000034 +/* #define Reserved 0x00000035-0x0000003F */ +#define ESME_RINVDESTFLAG 0x00000040 +/* #define Reserved 0x00000041 */ +#define ESME_RINVSUBREP 0x00000042 +#define ESME_RINVESMCLASS 0x00000043 +#define ESME_RCNTSUBDL 0x00000044 +#define ESME_RSUBMITFAIL 0x00000045 +/* #define Reserved 0x00000046-0x00000047 */ +#define ESME_RINVSRCTON 0x00000048 +#define ESME_RINVSRCNPI 0x00000049 +/* #define Reserved 0x0000004A-0x0000004F */ +#define ESME_RINVDSTTON 0x00000050 +#define ESME_RINVDSTNPI 0x00000051 +/* #define Reserved 0x00000052 */ +#define ESME_RINVSYSTYP 0x00000053 +#define ESME_RINVREPFLAG 0x00000054 +#define ESME_RINVNUMMSGS 0x00000055 +/* #define Reserved 0x00000056-0x00000057 */ +#define ESME_RTHROTTLED 0x00000058 +/* #define Reserved 0x00000059-0x00000060 */ +#define ESME_RINVSCHED 0x00000061 +#define ESME_RINVEXPIRY 0x00000062 +#define ESME_RINVDFTMSGID 0x00000063 +#define ESME_RX_T_APPN 0x00000064 +#define ESME_RX_P_APPN 0x00000065 +#define ESME_RX_R_APPN 0x00000066 +#define ESME_RQUERYFAIL 0x00000067 +/* #define Reserved 0x00000068-0x000000BF */ +#define ESME_RINVOPTPARSTREAM 0x000000C0 +#define ESME_ROPTPARNOTALLWD 0x000000C1 +#define ESME_RINVPARSLEN 0x000000C2 +#define ESME_RMISSINGOPTPARAM 0x000000C3 +#define ESME_RINVOPTPARAMVAL 0x000000C4 +/* #define Reserved 0x000000C5-0x000000FD */ +#define ESME_RDELIVERYFAILURE 0x000000FE +#define ESME_RUNKNOWNERR 0x000000FF +/* #define Reserved_for_SMPP_extention 0x00000100-0x000003FF */ +/* #define Reserved_for_SMSC_vendor_specific_errors 0x00000100-0x000003FF */ +/* #define Reserved 0x00000500-0xFFFFFFFF */ + +/* define dest_network_type optional parameters */ +#define DEST_NETWORK_TYPE_UNKNOWN 0x00 +#define DEST_NETWORK_TYPE_GSM 0x01 +#define DEST_NETWORK_TYPE_ANSI136_TDMA 0x02 +#define DEST_NETWORK_TYPE_IS95_CDMA 0x03 +#define DEST_NETWORK_TYPE_PDC 0x04 +#define DEST_NETWORK_TYPE_PHS 0x05 +#define DEST_NETWORK_TYPE_IDEN 0x06 +#define DEST_NETWORK_TYPE_AMPS 0x07 +#define DEST_NETWORK_TYPE_PAGING_NETWORK 0x08 + +/* define destination address type */ +#define DESTINATION_ADDRESS_SME_ADDRESS 0x01 +#define DESTINATION_ADDRESS_DISTRIBUTION_LIST_NAME 0x02 + +/* define Type of Number(TON) */ +#define TON_UNKNOWN 0x0 +#define TON_INTERNATIONAL 0x1 +#define TON_NATIONAL 0x2 +#define TON_NETWORK_SPECIFIC 0x3 +#define TON_SUBSCRIBER_NUMBER 0x4 +#define TON_ALPHANUMERIC 0x5 +#define TON_ABBREVIATE 0x6 + +/* define Numeric Plan Indicator(NPI) */ +#define NPI_UNKNOWN 0x0 +#define NPI_ISDN 0x1 +#define NPI_DATA 0x3 +#define NPI_TELEX 0x4 +#define NPI_LAND_MOBILE 0x6 +#define NPI_NATIONAL 0x8 +#define NPI_PRIVATE 0x9 +#define NPI_ERMES 0xa +#define NPI_INTERNET 0xe + +#endif + diff --git a/plat/smpp/src/include/smpp_def.h b/plat/smpp/src/include/smpp_def.h new file mode 100644 index 0000000..c4551b2 --- /dev/null +++ b/plat/smpp/src/include/smpp_def.h @@ -0,0 +1,39 @@ + +#ifndef _SMPP_DEF_h +#define _SMPP_DEF_h + +/*SMPP_CALLBACK callBackFunc[MAX_SMPP_LINK]; +SMPP_PARAM smpp_param[MAX_SMPP_LINK]; +SMPP_LINK smpp_link[MAX_SMPP_LINK]; +struct SocketsInUse Mysock; +SMPP_DEBUG_STRUCT smppDebug; + +BYTE exterEvent[MAX_SMPP_LINK][CMD_BUF_SIZE]; +BYTE interEvent[MAX_SMPP_LINK][CMD_BUF_SIZE]; +BYTE exter_head[MAX_SMPP_LINK]; +BYTE exter_tail[MAX_SMPP_LINK]; +BYTE inter_head[MAX_SMPP_LINK]; +BYTE inter_tail[MAX_SMPP_LINK]; + +BYTE smpp_state[MAX_SMPP_LINK]; +BYTE smpp_hearbeat_status[MAX_SMPP_LINK/4]; +BYTE interface_mode[MAX_SMPP_LINK]; +BYTE data_mode[MAX_SMPP_LINK]; + +BYTE linkAttachFlag[MAX_SMPP_LINK]; +BYTE smpp_TCPClientFlag[MAX_SMPP_LINK]; +char smpp_debug_asciiIn[MAX_ASCIN_BUF_LEN]; +char smpp_debug_asciiOut[MAX_ASCOUT_BUF_LEN]; +BYTE smppDebugFull = 0; + +BYTE src_ref[MAX_SMPP_LINK]; +BYTE dst_ref[MAX_SMPP_LINK]; + +BYTE smpp_msg[MAX_PACKET_SIZE]; + +BYTE smpp_system_no;*/ + +#endif + + + diff --git a/plat/smpp/src/include/smpp_ext.h b/plat/smpp/src/include/smpp_ext.h new file mode 100644 index 0000000..4699b97 --- /dev/null +++ b/plat/smpp/src/include/smpp_ext.h @@ -0,0 +1,38 @@ +#ifndef _SMPP_EXT_h +#define _SMPP_EXT_h + +extern SMPP_CALLBACK callBackFunc[MAX_SMPP_LINK]; +extern SMPP_PARAM smpp_param[MAX_SMPP_LINK]; +extern SMPP_LINK smpp_link[MAX_SMPP_LINK]; +extern struct SocketsInUse Mysock; +extern SMPP_DEBUG_STRUCT smppDebug; + +extern BYTE exterEvent[MAX_SMPP_LINK][CMD_BUF_SIZE]; +extern BYTE interEvent[MAX_SMPP_LINK][CMD_BUF_SIZE]; +extern BYTE exter_head[MAX_SMPP_LINK]; +extern BYTE exter_tail[MAX_SMPP_LINK]; +extern BYTE inter_head[MAX_SMPP_LINK]; +extern BYTE inter_tail[MAX_SMPP_LINK]; + +extern BYTE smpp_state[MAX_SMPP_LINK]; +extern BYTE smpp_hearbeat_status[MAX_SMPP_LINK/4]; +extern BYTE interface_mode[MAX_SMPP_LINK]; +extern BYTE data_mode[MAX_SMPP_LINK]; + +extern BYTE linkAttachFlag[MAX_SMPP_LINK]; +extern BYTE smpp_TCPClientFlag[MAX_SMPP_LINK]; +extern char smpp_debug_asciiIn[MAX_ASCIN_BUF_LEN]; +extern char smpp_debug_asciiOut[MAX_ASCOUT_BUF_LEN]; +extern BYTE smppDebugFull; + +extern BYTE src_ref[MAX_SMPP_LINK]; +extern BYTE dst_ref[MAX_SMPP_LINK]; + +extern BYTE smpp_msg[MAX_PACKET_SIZE]; + +extern BYTE smpp_system_no; + +#endif + + + diff --git a/plat/smpp/src/include/smpp_msg.h b/plat/smpp/src/include/smpp_msg.h new file mode 100644 index 0000000..b3454be --- /dev/null +++ b/plat/smpp/src/include/smpp_msg.h @@ -0,0 +1,465 @@ + +#ifndef _SMPP_MSG_h +#define _SMPP_MSG_h + + +typedef struct SMPP_HEAD +{ + DWORD command_length; + DWORD command_id; + DWORD command_status; + DWORD sequence_number; +}SMPP_HEAD; + +typedef struct SMPP_GENERAL +{ + SMPP_HEAD head; + BYTE msg[SMPP_MSG_LEN]; +}SMPP_GENERAL; + +typedef struct PDU_BIND +{ + SMPP_HEAD head; + char system_id[16]; + char password[9]; + char system_type[13]; + BYTE interface_version; + BYTE addr_ton; + BYTE addr_npi; + char address_range[41]; +}PDU_BIND; + +typedef struct PDU_BIND_RESP +{ + SMPP_HEAD head; + char system_id[16]; + /* optional parameter */ + BYTE sc_interface_version; +}PDU_BIND_RESP; + +typedef struct PDU_OUTBIND +{ + SMPP_HEAD head; + char system_id[16]; + char password[9]; +}PDU_OUTBIND; + +typedef struct PDU_UNBIND +{ + SMPP_HEAD head; +}PDU_UNBIND; + +typedef struct PDU_UNBIND_RESP +{ + SMPP_HEAD head; +}PDU_UNBIND_RESP; + +typedef struct PDU_GENERIC_NACK +{ + SMPP_HEAD head; +}PDU_GENERIC_NACK; + +typedef struct PDU_SUBMIT_SM +{ + SMPP_HEAD head; + + /* define mandatory parameters */ + char service_type[6]; + BYTE source_addr_ton; + BYTE source_addr_npi; + char source_addr[21]; + BYTE dest_addr_ton; + BYTE dest_addr_npi; + char destination_addr[21]; + BYTE esm_class; + BYTE protocol_id; + BYTE priority_flag; + char schedule_delivery_time[17]; + char validity_period[17]; + BYTE registered_delivery; + BYTE replace_if_present_flag; + BYTE data_coding; + BYTE sm_default_msg_id; + BYTE sm_length; + BYTE short_message[254]; + + /* define optional parameters */ + /* total: 28 parameters. */ /* param_flag1 */ + WORD user_message_reference; /* 0x0000 0001 */ + WORD source_port; /* 0x0000 0002 */ + BYTE source_addr_subunit; /* 0x0000 0004 */ + WORD destination_port; /* 0x0000 0008 */ + BYTE dest_addr_subunit; /* 0x0000 0010 */ + WORD sar_msg_ref_num; /* 0x0000 0020 */ + BYTE sar_total_segments; /* 0x0000 0040 */ + BYTE sar_segment_seqnum; /* 0x0000 0080 */ + BYTE more_messages_to_send; /* 0x0000 0100 */ + BYTE payload_type; /* 0x0000 0200 */ + char message_payload[MAX_MSG_SIZE]; /* 0x0000 0400 */ + BYTE privacy_indicator; /* 0x0000 0800 */ + char callback_num[19]; /* 0x0000 1000 */ + BYTE callback_num_pres_ind; /* 0x0000 2000 */ + char callback_num_atag[65]; /* 0x0000 4000 */ + char source_subaddress[23]; /* 0x0000 8000 */ + char dest_subaddress[23]; /* 0x0001 0000 */ + BYTE user_response_code; /* 0x0002 0000 */ + BYTE display_time; /* 0x0004 0000 */ + WORD sms_signal; /* 0x0008 0000 */ + BYTE ms_validity; /* 0x0010 0000 */ + BYTE ms_msg_wait_facilities; /* 0x0020 0000 */ + BYTE number_of_messages; /* 0x0040 0000 */ + BYTE alert_on_message_delivery; /* 0 byte. */ /* 0x0080 0000 */ + BYTE language_indicator; /* 0x0100 0000 */ + BYTE its_reply_type; /* 0x0200 0000 */ + BYTE its_session_info[2]; /* 0x0400 0000 */ + BYTE ussd_service_op; /* 0x0800 0000 */ + BYTE dest_network_type; /* 0x1000 0000 */ /* smpp v5.0 */ +}PDU_SUBMIT_SM; + +typedef struct PDU_SUBMIT_SM_RESP +{ + SMPP_HEAD head; + char message_id[65]; +}PDU_SUBMIT_SM_RESP; + +typedef struct SME_DEST_ADDRESS +{ + BYTE dest_addr_ton; + BYTE dest_addr_npi; + char destination_addr[21]; +}SME_DEST_ADDRESS; + +typedef struct DL_NAME +{ + char dl_name[21]; +}DL_NAME; + +typedef union DEST_ADDR +{ + SME_DEST_ADDRESS sme_dest_address; + DL_NAME dl_name; +}DEST_ADDR; + +typedef struct DESTINATION_ADDRESS_DEFINITION +{ + BYTE dest_flag; + DEST_ADDR dest_addr; +}DESTINATION_ADDRESS_DEFINITIAON; + +typedef struct PDU_SUBMIT_MULTI +{ + SMPP_HEAD head; + + /* define mandatory parameters */ + char service_type[6]; + BYTE source_addr_ton; + BYTE source_addr_npi; + char source_addr[21]; + BYTE number_of_dests; + DESTINATION_ADDRESS_DEFINITIAON dest_address[SMPP_MAX_MULTI_ADDRESS]; + BYTE esm_class; + BYTE protocol_id; + BYTE priority_flag; + char schedule_delivery_time[17]; + char validity_period[17]; + BYTE registered_delivery; + BYTE replace_if_present_flag; /* set to NULL */ + BYTE data_coding; + BYTE sm_default_msg_id; + BYTE sm_length; + BYTE short_message[254]; + + /* define optional parameters */ + /* total: 22 parameters. */ /* param_flag1 */ + WORD user_message_reference; /* 0x0000 0001 */ + WORD source_port; /* 0x0000 0002 */ + BYTE source_addr_subunit; /* 0x0000 0004 */ + WORD destination_port; /* 0x0000 0008 */ + BYTE dest_addr_subunit; /* 0x0000 0010 */ + WORD sar_msg_ref_num; /* 0x0000 0020 */ + BYTE sar_total_segments; /* 0x0000 0040 */ + BYTE sar_segment_seqnum; /* 0x0000 0080 */ + BYTE payload_type; /* 0x0000 0100 */ + char message_payload[MAX_MSG_SIZE]; /* 0x0000 0200 */ + BYTE privacy_indicator; /* 0x0000 0400 */ + char callback_num[19]; /* 0x0000 0800 */ + BYTE callback_num_pres_ind; /* 0x0000 1000 */ + char callback_num_atag[65]; /* 0x0000 2000 */ + char source_subaddress[23]; /* 0x0000 4000 */ + char dest_subaddress[23]; /* 0x0000 8000 */ + BYTE display_time; /* 0x0001 0000 */ + WORD sms_signal; /* 0x0002 0000 */ + BYTE ms_validity; /* 0x0004 0000 */ + BYTE ms_msg_wait_facilities; /* 0x0008 0000 */ + BYTE alert_on_message_delivery;/* 0byte */ /* 0x0010 0000 */ + BYTE language_indicator; /* 0x0020 0000 */ + BYTE dest_network_type; /* 0x0040 0000 */ +}PDU_SUBMIT_MULTI; + +typedef struct UNSUCCESS_SME +{ + BYTE dest_addr_ton; + BYTE dest_addr_npi; + char destination_addr[21]; + DWORD error_status_code; +}UNSUCCESS_SME; + +typedef struct PDU_SUBMIT_MULTI_RESP +{ + SMPP_HEAD head; + char message_id[65]; + BYTE no_unsuccess; + UNSUCCESS_SME unsuccess_sme[MAX_SME]; +}PDU_SUBMIT_MULTI_RESP; + +typedef struct PDU_DELIVER_SM +{ + SMPP_HEAD head; + + /* define mandatory parameter. */ + char service_type[6]; + BYTE source_addr_ton; + BYTE source_addr_npi; + char source_addr[21]; + BYTE dest_addr_ton; + BYTE dest_addr_npi; + char destination_addr[21]; + BYTE esm_class; + BYTE protocol_id; + BYTE priority_flag; + char schedule_delivery_time; /* set to NULL */ + char validity_period; /* set to NULL */ + BYTE registered_delivery; + BYTE replace_if_present_flag; /* set to NULL */ + BYTE data_coding; + BYTE sm_default_msg_id; /* set to NULL */ + BYTE sm_length; + BYTE short_message[254]; + + /* define optional parameter. */ + /* total: 19 parameters. */ /* param_flag1 */ + WORD user_message_reference; /* 0x0000 0001 */ + WORD source_port; /* 0x0000 0002 */ + WORD destination_port; /* 0x0000 0004 */ + WORD sar_msg_ref_num; /* 0x0000 0008 */ + BYTE sar_total_segments; /* 0x0000 0010 */ + BYTE sar_segment_seqnum; /* 0x0000 0020 */ + BYTE user_response_code; /* 0x0000 0040 */ + BYTE privacy_indicator; /* 0x0000 0080 */ + BYTE payload_type; /* 0x0000 0100 */ + char message_payload[MAX_MSG_SIZE]; /* 0x0000 0200 */ + char callback_num[49]; /* 0x0000 0400 */ + char source_subaddress[23]; /* 0x0000 0800 */ + char dest_subaddress[23]; /* 0x0000 1000 */ + BYTE language_indicator; /* 0x0000 2000 */ + BYTE its_session_info[2]; /* 0x0000 4000 */ + char network_error_code[3]; /* 0x0000 8000 */ + BYTE message_state; /* 0x0001 0000 */ + char receipted_message_id[65]; /* 0x0002 0000 */ + BYTE ussd_service_op; /* 0x0004 0000 */ /* smpp v5.0 */ +}PDU_DELIVER_SM; + +typedef struct PDU_DELIVER_SM_RESP +{ + SMPP_HEAD head; + char message_id; +}PDU_DELIVER_SM_RESP; + +typedef struct PDU_DATA_SM +{ + SMPP_HEAD head; + + /* define mandatory paramter. */ + char service_type[6]; + BYTE source_addr_ton; + BYTE source_addr_npi; + char source_addr[65]; + BYTE dest_addr_ton; + BYTE dest_addr_npi; + char destination_addr[65]; + BYTE esm_class; + BYTE registered_delivery; + BYTE data_coding; + + /* define optional parameter. */ + /* total: 38 paramters. */ /* param_flag */ + WORD source_port; /* 0x0000 0001 */ /* param_flag1 start. */ + BYTE source_addr_subunit; /* 0x0000 0002 */ + BYTE source_network_type; /* 0x0000 0004 */ + BYTE source_bearer_type; /* 0x0000 0008 */ + WORD source_telematics_id; /* 0x0000 0010 */ + WORD destination_port; /* 0x0000 0020 */ + BYTE dest_addr_subunit; /* 0x0000 0040 */ + BYTE dest_network_type; /* 0x0000 0080 */ + BYTE dest_bearer_type; /* 0x0000 0100 */ + WORD dest_telematics_id; /* 0x0000 0200 */ + WORD sar_msg_ref_num; /* 0x0000 0400 */ + BYTE sar_total_segments; /* 0x0000 0800 */ + BYTE sar_segment_seqnum; /* 0x0000 1000 */ + BYTE more_messages_to_send; /* 0x0000 2000 */ + DWORD qos_time_to_live; /* 0x0000 4000 */ + BYTE payload_type; /* 0x0000 8000 */ + char message_payload[MAX_MSG_SIZE]; /* 0x0001 0000 */ + BYTE set_dpf; /* 0x0002 0000 */ + char receipted_message_id[65]; /* 0x0004 0000 */ + BYTE message_state; /* 0x0008 0000 */ + char network_error_code[3]; /* 0x0010 0000 */ + WORD user_message_reference; /* 0x0020 0000 */ + BYTE privacy_indicator; /* 0x0040 0000 */ + char callback_num[19]; /* 0x0080 0000 */ + BYTE callback_num_pres_ind; /* 0x0100 0000 */ + char callback_num_atag[65]; /* 0x0200 0000 */ + char source_subaddress[23]; /* 0x0400 0000 */ + char dest_subaddress[23]; /* 0x0800 0000 */ + BYTE user_response_code; /* 0x1000 0000 */ + BYTE display_time; /* 0x2000 0000 */ + WORD sms_signal; /* 0x4000 0000 */ + BYTE ms_validity; /* 0x8000 0000 */ /* param_flag1 end. */ + BYTE ms_msg_wait_facilities; /* 0x0000 0001 */ /* param_flag2 start. */ + BYTE number_of_messages; /* 0x0000 0002 */ + BYTE alert_on_message_delivery;/* 0byte */ /* 0x0000 0004 */ + BYTE language_indicator; /* 0x0000 0008 */ + BYTE its_reply_type; /* 0x0000 0010 */ + BYTE its_session_info[2]; /* 0x0000 0020 */ +}PDU_DATA_SM; + +typedef struct PDU_DATA_SM_RESP +{ + SMPP_HEAD head; + char message_id[65]; +}PDU_DATA_SM_RESP; + +typedef struct PDU_QUERY_SM +{ + SMPP_HEAD head; + char message_id[65]; + BYTE source_addr_ton; + BYTE source_addr_npi; + char source_addr[21]; +}PDU_QUERY_SM; + +typedef struct PDU_QUERY_SM_RESP +{ + SMPP_HEAD head; + char message_id[65]; + char final_date[17]; + BYTE message_state; + BYTE error_code; +}PDU_QUERY_SM_RESP; + +typedef struct PDU_CANCEL_SM +{ + SMPP_HEAD head; + char service_type[6]; + char message_id[65]; + BYTE source_addr_ton; + BYTE source_addr_npi; + char source_addr[21]; + BYTE dest_addr_ton; + BYTE dest_addr_npi; + char destination_addr[21]; +}PDU_CANCEL_SM; + +typedef struct PDU_CANCEL_SM_RESP +{ + SMPP_HEAD head; +}PDU_CANCEL_SM_RESP; + +typedef struct PDU_REPLACE_SM +{ + SMPP_HEAD head; + + /* define mandatory parameter */ + char message_id[65]; + BYTE source_addr_ton; + BYTE source_addr_npi; + char source_addr[21]; + char schedule_delivery_time[17]; + char validity_period[17]; + BYTE registered_delivery; + BYTE sm_default_msg_id; + BYTE sm_length; + BYTE short_message[254]; +}PDU_REPLACE_SM; + +typedef struct PDU_REPLACE_SM_RESP +{ + SMPP_HEAD head; +}PDU_REPLACE_SM_RESP; + +typedef struct PDU_ENQUIRE_LINK +{ + SMPP_HEAD head; +}PDU_ENQUIRE_LINK; + +typedef struct PDU_ENQUIRE_LINK_RESP +{ + SMPP_HEAD head; +}PDU_ENQUIRE_LINK_RESP; + +typedef struct PDU_ALERT_NOTIFICATION +{ + SMPP_HEAD head; + BYTE source_addr_ton; + BYTE source_addr_npi; + BYTE source_addr[65]; + BYTE esme_addr_ton; + BYTE esme_addr_npi; + BYTE esme_addr[65]; + BYTE ms_availability_status; +}PDU_ALERT_NOTIFICATION; + +typedef union SMPP_PDU +{ + PDU_BIND bind_transmitter; /* message_type = 0x01 */ + PDU_BIND_RESP bind_transmitter_resp; /* message_type = 0x02 */ + PDU_BIND bind_receiver; /* message_type = 0x03 */ + PDU_BIND_RESP bind_receiver_resp; /* message_type = 0x04 */ + PDU_BIND bind_transceiver; /* message_type = 0x05 */ + PDU_BIND_RESP bind_transceiver_resp; /* message_type = 0x06 */ + PDU_OUTBIND outbind; /* message_type = 0x07 */ + PDU_UNBIND unbind; /* message_type = 0x08 */ + PDU_UNBIND_RESP unbind_resp; /* message_type = 0x09 */ + PDU_GENERIC_NACK generic_nack; /* message_type = 0x0A */ + PDU_SUBMIT_SM submit_sm; /* message_type = 0x0B */ + PDU_SUBMIT_SM_RESP submit_sm_resp; /* message_type = 0x0C */ + PDU_SUBMIT_MULTI submit_multi; /* message_type = 0x0D */ + PDU_SUBMIT_MULTI_RESP submit_multi_resp; /* message_type = 0x0E */ + PDU_DELIVER_SM deliver_sm; /* message_type = 0x0F */ + PDU_DELIVER_SM_RESP deliver_sm_resp; /* message_type = 0x10 */ + PDU_DATA_SM data_sm; /* message_type = 0x11 */ + PDU_DATA_SM_RESP data_sm_resp; /* message_type = 0x12 */ + PDU_QUERY_SM query_sm; /* message_type = 0x13 */ + PDU_QUERY_SM_RESP query_sm_resp; /* message_type = 0x14 */ + PDU_CANCEL_SM cancel_sm; /* message_type = 0x15 */ + PDU_CANCEL_SM_RESP cancel_sm_resp; /* message_type = 0x16 */ + PDU_REPLACE_SM replace_sm; /* message_type = 0x17 */ + PDU_REPLACE_SM_RESP replace_sm_resp; /* message_type = 0x18 */ + PDU_ENQUIRE_LINK enquire_link; /* message_type = 0x19 */ + PDU_ENQUIRE_LINK_RESP enquire_link_resp; /* message_type = 0x1A */ + PDU_ALERT_NOTIFICATION alert_notification; /* message_type = 0x1B */ +}SMPP_PDU; + +typedef struct SMPP_MSG +{ + BYTE message_type; + DWORD optional_param_flag1; /* for optional parameter 1~32 */ + DWORD optional_param_flag2; /* for optional parameter 33~64 */ + SMPP_PDU pdu; +}SMPP_MSG; + +typedef struct SMPP_OPTIONAL_PARAMETER +{ + WORD tag; + WORD len; + BYTE value[MAX_MSG_SIZE]; +}SMPP_OPTIONAL_PARAMETER; + +//BYTE smpp_msg_buf[MAX_SMPP_LINK][MAX_PACKET_SIZE]; +//int smpp_msg_buf_len[MAX_SMPP_LINK]; + +#endif + + + + diff --git a/plat/smpp/src/include/smpp_public.h b/plat/smpp/src/include/smpp_public.h new file mode 100644 index 0000000..1ff4bf9 --- /dev/null +++ b/plat/smpp/src/include/smpp_public.h @@ -0,0 +1,62 @@ +/* +** CDMA 2000 project, SMPP module +** +** File name: public.h +** Written by Li Long at 2004-11-25 +** CVS $Id: public.h,v0.1 2004/11/25 17:03:14 lilong Exp $ +** +*/ +#ifndef _SMPP_PUBLIC_h +#define _SMPP_PUBLIC_h + + +#include +#include +#include +#include +#include +#include + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned int DWORD; +#endif + +#ifndef _T_BOOL +#define _T_BOOL +typedef int BOOL; +#endif + +#ifndef SUCCESS +#define SUCCESS (0) +#endif + +#ifndef FAILURE +#define FAILURE (-1) +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#endif + + diff --git a/plat/smpp/src/smpp_debug.c b/plat/smpp/src/smpp_debug.c new file mode 100644 index 0000000..cc0d0ec --- /dev/null +++ b/plat/smpp/src/smpp_debug.c @@ -0,0 +1,471 @@ +/* +** CDMA 2000 project, smpp module +** +** File name: smpp_debug.c +** Written by Li Long at 2004-11-25 +** CVS $Id: smpp_debug.c,v0.1 2004/11/25 17:03:14 lilong Exp $ +** +*/ + +#include "./include/smpp.h" +#include "./include/smpp_ext.h" + +static char smpp_debug_status = 1; +static WORD disp_page[10]; +static char *disp_ptr = (char *) disp_page; + +static DWORD smpp_status_id[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,SMPP_DEBUG_ID+2,1 + }; + +static DWORD smpp_version_id[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,SMPP_DEBUG_ID+2,2 + }; + +static DWORD smpp_ascii_in_id[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,SMPP_DEBUG_ID+2,3 + }; + +static DWORD smpp_ascii_out_id[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,SMPP_DEBUG_ID+2,4 + }; + +static DWORD smpp_page_title[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,SMPP_DEBUG_ID+2,1,1 + }; + +static DWORD smpp_page_line[20] = + { + 1,3,6,1,4,1,1373,1,1,2,3,1,2,SMPP_DEBUG_ID+2,1,2,1 + }; + +const static BYTE PAGE_POINT = 14; +const static BYTE LINE_POINT = 15; +const static BYTE BASE_ID_LEN = 15; + +static char title1_p[] = +{ + " SMPP R9 Page 01 link status (32 links)\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +link_status\n\r\ +\n\r\ +daemon sock\r\n\ +tcp_client_flag\r\n\ +\r\n\ +sock_fd\r\n\ +\r\n\ +\r\n\ +\r\n\ +\r\n\ +\r\n\ +\r\n\ +\r\n\ +\r\n\ +\tLink status:\r\n\ +\t\t00 -- Not init\r\n\ +\t\t01 -- IDLE\r\n\ +\t\t02 -- WAITING\r\n\ +\t\t03 -- ESTABLISHED\r\n\ +\t\t04 -- SUSPEND" +}; + +static char title2_p[] = +{ + " SMPP R9 Page 02 debug struct (32 links)\n\r\ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n\r\ +debug_switch\n\r\ +link_switch\n\r" +}; + +static char title3_p[] = +{ + " SMPP R9 Page 03 link type (link 0~21)\n\r\ + type\t\t00 -- UDP,\t01 -- TCP\n\r\ +link 0\n\r\ +link 1\n\r\ +link 2\n\r\ +link 3\n\r\ +link 4\n\r\ +link 5\n\r\ +link 6\n\r\ +link 7\n\r\ +link 8\n\r\ +link 9\n\r\ +link 10\n\r\ +link 11\n\r\ +link 12\n\r\ +link 13\n\r\ +link 14\n\r\ +link 15\n\r\ +link 16\n\r\ +link 17\n\r\ +link 18\n\r\ +link 19\n\r\ +link 20\n\r\ +link 21\n\r" +}; + +static char title4_p[] = +{ + " SMPP R9 Page 04 link type (link 22~31)\n\r\ + type\t\t00 -- UDP,\t01 -- TCP\n\r\ +link 22\n\r\ +link 23\n\r\ +link 24\n\r\ +link 25\n\r\ +link 26\n\r\ +link 27\n\r\ +link 28\n\r\ +link 29\n\r\ +link 30\n\r\ +link 31\n\r" +}; + +static char title5_p[] = +{ + " SMPP R9 Page 05 server_sock & client_sock\n\r\ + \r\n\ +server_sock\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +\n\r\ +client_sock\n\r\ +\n\r" +}; + +BYTE smpp_disp_line(BYTE page, BYTE line) +{ + BYTE disp_length; + + disp_length = 16; + disp_ptr = (char *) disp_page; + + switch (page) + { + case 1: + switch (line) + { + case 0: + case 1: + disp_ptr = (char *) &smpp_state[disp_page[page]] + (line * 16); + break; + case 2: + disp_ptr = (char *) &(Mysock.DaemonSock); + disp_length = 1; + break; + case 3: + case 4: + disp_ptr = (char *) &smpp_TCPClientFlag[disp_page[page]]+(line-3)*16; + break; + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + disp_ptr = (char *) &(Mysock.Sockets[disp_page[page]]) + ((line-5)*16); + break; + default: + disp_length = 0; + break; + } + break; + case 2: // Page 2: link debug status + if (line == 0) + { + disp_ptr = (char *) &smppDebug.debug_switch; + disp_length = 1; + } + else if (line < 3) + disp_ptr = (char *) &smppDebug.link_switch[disp_page[page]] + ((line - 1) * 16); + else + disp_length = 0; + break; + case 3: //page 3: link type + if (line<22) + { + disp_ptr = (char *) &smpp_param[line].link_type; + disp_length = 1; + } + break; + case 4: //page 3: link type(0~21) + if (line<10) + { + disp_ptr = (char *) &smpp_param[line+22].link_type; + disp_length = 1; + }else + disp_length = 0; + break; + case 5: //page 5: server_socket and client_sockets + switch (line) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + disp_ptr = (char *) &Mysock.server_sock[disp_page[page]] + line*16; + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + disp_ptr = (char *) &Mysock.client_sock[disp_page[page]] + (line-8)*16; + break; + default: + disp_length = 0; + break; + } + break; + default: + disp_length = 0; + break; + } + + return disp_length; +} + +void smpp_disp_page(BYTE page) +{ + BYTE disp_line; + BYTE disp_length; + + smpp_page_line[PAGE_POINT] = page + 5; + + for (disp_line = 0; disp_line < 22; disp_line++) + { + disp_length = smpp_disp_line(page, disp_line); + smpp_page_line[LINE_POINT] = disp_line + 2; + smpp_page_line[LINE_POINT + 1] = 2; // Data Pointer + debug_set_response(BASE_ID_LEN + 2, smpp_page_line, (BYTE *)disp_ptr, disp_length); + } +} + +void smpp_debugInit() +{ + int page; + char* ptr; + + smppDebug.debug_switch = 0; + + debug_set_response(15, smpp_status_id, (BYTE *)&smpp_debug_status, 1);//smpp status + debug_set_response(15, smpp_version_id, (BYTE *)SMPP_MODULE_VERSION, strlen(SMPP_MODULE_VERSION)); + debug_set_response(15, smpp_ascii_in_id, (BYTE *)smpp_debug_asciiIn, MAX_ASCIN_BUF_LEN); + debug_set_response(15, smpp_ascii_out_id, (BYTE *)smpp_debug_asciiOut, MAX_ASCOUT_BUF_LEN); + + for (page=1; page<=5; page++) + { + switch (page) + { + case 1: + ptr = title1_p; + break; + case 2: + ptr = title2_p; + break; + case 3: + ptr = title3_p; + break; + case 4: + ptr = title4_p; + break; + case 5: + ptr = title5_p; + break; + default: + break; + } + smpp_page_title[PAGE_POINT] = 5 + page; + debug_set_response(BASE_ID_LEN + 1, smpp_page_title, (BYTE *)ptr, strlen(ptr)); + smpp_disp_page(page); + } + + #ifdef SMPP_DEBUG + printf("smpp debug init.\n"); + #endif //end ifdef SMPP_DEBUG +} + +void smpp_list_linkparam(int linkNo) { + char debug_str[256]; + struct in_addr addr; + + if (linkNo >= MAX_SMPP_LINK) + { + smpp_send_error("Link number is too big.\n\r"); + return; + } + + sprintf(debug_str, "\r\nLink %d parameter:\r\n", linkNo); + smpp_send_ascout(debug_str); + sprintf(debug_str, "link_enable: %d\r\n", smpp_param[linkNo].link_enable); + smpp_send_ascout(debug_str); + sprintf(debug_str, "link_type: %d\r\n", smpp_param[linkNo].link_type); + smpp_send_ascout(debug_str); + sprintf(debug_str, "server_type: %d\r\n", smpp_param[linkNo].server_type); + smpp_send_ascout(debug_str); + sprintf(debug_str, "session_type: %d\r\n", smpp_param[linkNo].session_type); + smpp_send_ascout(debug_str); + sprintf(debug_str, "system_id: %s\r\n", smpp_param[linkNo].sys_id); + smpp_send_ascout(debug_str); + sprintf(debug_str, "password: %s\r\n", smpp_param[linkNo].password); + smpp_send_ascout(debug_str); + sprintf(debug_str, "system_type: %s\r\n", smpp_param[linkNo].system_type); + smpp_send_ascout(debug_str); + sprintf(debug_str, "localGTT: %s\r\n", smpp_param[linkNo].localGTT); + smpp_send_ascout(debug_str); + sprintf(debug_str, "remoteGTT: %s\r\n", smpp_param[linkNo].remoteGTT); + smpp_send_ascout(debug_str); + addr.s_addr = smpp_param[linkNo].local_ip; + sprintf(debug_str, "local_ip: %s\r\n", inet_ntoa(addr)); + smpp_send_ascout(debug_str); + addr.s_addr = smpp_param[linkNo].remote_ip; + sprintf(debug_str, "remote_ip: %s\r\n", inet_ntoa(addr)); + smpp_send_ascout(debug_str); + sprintf(debug_str, "session_init_timer: %u\r\n", smpp_param[linkNo].session_init_timer); + smpp_send_ascout(debug_str); + sprintf(debug_str, "enquire_link_timer: %u\r\n", smpp_param[linkNo].enquire_link_timer); + smpp_send_ascout(debug_str); + sprintf(debug_str, "inactivity_timer: %u\r\n", smpp_param[linkNo].inactivity_timer); + smpp_send_ascout(debug_str); + sprintf(debug_str, "response_timer: %u\r\n", smpp_param[linkNo].response_timer); + smpp_send_ascout(debug_str); + sprintf(debug_str, "service_number: %s\r\n", smpp_param[linkNo].service_number); + smpp_send_ascout(debug_str); + sprintf(debug_str, "localSSN: %d\r\n", smpp_param[linkNo].localSSN); + smpp_send_ascout(debug_str); + sprintf(debug_str, "remoteSSN: %d\r\n", smpp_param[linkNo].remoteSSN); + smpp_send_ascout(debug_str); +} + +void smpp_debugTimer() +{ + int i, linkNo = 0; + char debugBuf[1024]; + + if (strlen(smpp_debug_asciiIn) > 0) + { + if (strcmp(smpp_debug_asciiIn+1, "help") == 0) + { + smpp_send_ascout("SMPP Debug Monitor Help:\n\r\n\r"); + smpp_send_ascout("log none Turn off all log items\n\r"); + smpp_send_ascout("log all Turn on all log items\n\r"); + smpp_send_ascout("log link=\x1b[34mxx\x1b[0m on/off Turn on/off link x messages\n\r"); + smpp_send_ascout("list par.\x1b[34mxx\x1b[0m List link x parameter\r\n"); + sprintf(debugBuf, "ver. %s T%03d\r\n",SMPP_MODULE_VERSION,SMPP_MODULE_PATCH); + smpp_send_ascout(debugBuf); + }else if (strcmp(smpp_debug_asciiIn+1, "log none") == 0) + { + smppDebug.debug_switch = 0; + for (i=0; i= '0') && (smpp_debug_asciiIn[10] <= '9')) { + linkNo = smpp_debug_asciiIn[10] - '0'; + if ((smpp_debug_asciiIn[11] >= '0') && (smpp_debug_asciiIn[11] <= '9')) { + linkNo = linkNo*10+(smpp_debug_asciiIn[11]-'0'); +// if (linkNo > MAX_SMPP_LINK) +// smpp_send_error("Link number is too big.\n\r"); + smpp_list_linkparam(linkNo); + } + else + smpp_list_linkparam(linkNo); + } + else + smpp_send_error("Link number is error"); + } + else if (strncmp(smpp_debug_asciiIn+1, "save", 4) == 0) { + smpp_writeParam(); + } + else if (strncmp(smpp_debug_asciiIn+1, "log link=", 9) == 0) { + if ((smpp_debug_asciiIn[10] >= '0') && (smpp_debug_asciiIn[10] <= '9')) + { + linkNo = smpp_debug_asciiIn[10] - '0'; + if ((smpp_debug_asciiIn[11] >= '0') && (smpp_debug_asciiIn[11] <= '9')) + { + linkNo = linkNo*10+(smpp_debug_asciiIn[11]-'0'); + if (linkNo > MAX_SMPP_LINK) + { + smpp_send_error("Link number is too big.\n\r"); + } + else if (strncmp(smpp_debug_asciiIn+13, "on", 2) == 0) + { + smppDebug.link_switch[linkNo] = 1; + sprintf(debugBuf, "Link %d debug on.\n\r", linkNo); + smpp_send_ascout(debugBuf); + }else if (strncmp(smpp_debug_asciiIn+13, "off", 3) == 0) + { + smppDebug.link_switch[linkNo] = 0; + sprintf(debugBuf, "Link %d debug off.\n\r", linkNo); + smpp_send_ascout(debugBuf); + }else + { + smpp_send_error("Command Error.\n\r"); + } + }else if (strncmp(smpp_debug_asciiIn+12, "on", 2) == 0) + { + smppDebug.link_switch[linkNo] = 1; + sprintf(debugBuf, "Link %d debug on.\n\r", linkNo); + smpp_send_ascout(debugBuf); + }else if (strncmp(smpp_debug_asciiIn+12, "off", 3) == 0) + { + smppDebug.link_switch[linkNo] = 0; + sprintf(debugBuf, "Link %d debug off.\n\r", linkNo); + smpp_send_ascout(debugBuf); + }else + { + smpp_send_error("Command Error.\n\r"); + } + } + else + smpp_send_error("Link number error.\n\r"); + }else + { + smpp_send_error("Command Error.\n\r"); + } + + smpp_debug_asciiIn[0] = '\0'; + } +} + +void smpp_send_ascout(char *sdBuf) +{ + if (strlen(sdBuf)+strlen(smpp_debug_asciiOut) < MAX_ASCOUT_BUF_LEN) + { + strcat(smpp_debug_asciiOut, sdBuf); + } +} + +void smpp_send_error(char *sdBuf) +{ + if (smppDebug.debug_switch == 1) + { + smpp_send_ascout("\x1b[31m"); + smpp_send_ascout(sdBuf); + smpp_send_ascout("\x1b[0m"); + } +} diff --git a/plat/smpp/src/smpp_fsm.c b/plat/smpp/src/smpp_fsm.c new file mode 100644 index 0000000..32f8a1f --- /dev/null +++ b/plat/smpp/src/smpp_fsm.c @@ -0,0 +1,676 @@ +/* +** CDMA 2000 project, SMPP module +** +** File name: smpp_fsm.c +** Written by Li Long at 2004-11-25 +** CVS $Id: smpp_fsm.c,v0.1 2004/11/25 17:03:14 lilong Exp $ +** +*/ + +#include "./include/smpp.h" +#include "./include/smpp_ext.h" + +// fix multiple definition==================================== +extern int smpp_msg_buf_len[MAX_SMPP_LINK]; +// + +static int smpp_timerCount = 0; +//static int flag=-1; + +/* Timer variable definitions. */ +static BYTE session_init_flag[MAX_SMPP_LINK]; +static WORD session_init_timer[MAX_SMPP_LINK]; +static BYTE enquire_link_flag[MAX_SMPP_LINK]; +static WORD enquire_link_timer[MAX_SMPP_LINK]; +static BYTE inactivity_flag[MAX_SMPP_LINK]; +static WORD inactivity_timer[MAX_SMPP_LINK]; +static BYTE response_flag[MAX_SMPP_LINK]; +static WORD response_timer[MAX_SMPP_LINK]; +static BYTE init_tcp_client_timeout[MAX_SMPP_LINK]={0}; +static WORD suspend_timer = 0; + +void smpp_stateInit() +{ + int i; + + for (i=0; i1000)//1000*10ms=10s + { + smpp_checkParam(); + smpp_timerCount = 0; + } + + smpp_rvMsgOverTCP(); +// smpp_rvMsgOverSCCP(SMPP_PPS_USERTYPE); + smpp_rvMsgOverSCCP(SMPP_SMSC_USERTYPE); + smpp_debugTimer(); + for(link=0; link 0) init_tcp_client_timeout[link]--; + + /* Session init timer */ + if (TRUE == session_init_flag[link]) + { + session_init_timer[link]++; + if (session_init_timer[link] > 100*smpp_param[link].session_init_timer) + { + session_init_timer[link] = 0; + inter_head[link] = (inter_head[link]+1)&0x7; + interEvent[link][inter_head[link]] = SessionInitTimeout; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[link] == 1)) + { + sprintf(debugBuf, "link %d session_init_timer TIMEOUT.\n", link); + smpp_send_ascout(debugBuf); + } + #endif + } + } + /* Enquire link timer */ + if (TRUE == enquire_link_flag[link]) + { + enquire_link_timer[link]++; + if (enquire_link_timer[link] > 100*smpp_param[link].enquire_link_timer) + { + enquire_link_timer[link] = 0; + inter_head[link] = (inter_head[link]+1)&0x7; + interEvent[link][inter_head[link]] = EnquireLinkTimeout; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[link] == 1)) + { + sprintf(debugBuf, "link %d T1 (Enquire link timer) TIMEOUT.\n", link); + smpp_send_ascout(debugBuf); + } + #endif + } + } + /* Inactivity timer */ + if (TRUE == inactivity_flag[link]) + { + inactivity_timer[link]++; + if (inactivity_timer[link] > 100*smpp_param[link].inactivity_timer) + { + inactivity_timer[link] = 0; + inter_head[link] = (inter_head[link]+1)&0x7; + interEvent[link][inter_head[link]] = InactivityTimeout; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[link] == 1)) + { + sprintf(debugBuf, "link %d T2 (Inactivity timer) TIMEOUT.\n", link); + smpp_send_ascout(debugBuf); + } + #endif + } + } + } + + for(link=0; link 0) + { + if (TRUE == linkUseFlag[link]) + smpp_state[link] = IDLE; + } + */ + break; + case IDLE: + //IDLE state:: external event start. + switch (exterEvent[link][exter_tail[link]]) { + case Setup: + switch (smpp_param[link].server_type) { + case SMPP_SERVER: + switch (smpp_param[link].session_type) { + case BIND_RX: + smpp_state[link] = WAITING; + smpp_PrimitiveSend(link, Outbind); + session_init_flag[link] = TRUE; + //flag = 2; + //smpp_state[link] = WAITING;//ch:if smpp_PrimitiveSend failed,that would be error + temp_status = WAITING;//ch:if smpp_PrimitiveSend failed,that would be error + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + /* + case BIND_TRX: + smpp_PrimitiveSend(link, BindTransceiver); + session_init_flag[link] = TRUE; + flag = 1; + smpp_state[link] = WAITING; + temp_status = WAITING; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + */ + default: + break; + } + break; + case SMPP_CLIENT: + switch (smpp_param[link].session_type) { + case BIND_TX: + smpp_state[link] = WAITING; + smpp_PrimitiveSend(link, BindTransmitter); + session_init_flag[link] = TRUE; + //flag = 1; + //smpp_state[link] = WAITING; + temp_status = WAITING; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + /* + case BIND_RX: + smpp_PrimitiveSend(link, BindReceiver); + session_init_flag[link] = TRUE; + flag = 0; + smpp_state[link] = WAITING; + temp_status = WAITING; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + */ + case BIND_TRX: + smpp_state[link] = WAITING; + smpp_PrimitiveSend(link, BindTransceiver); + session_init_flag[link] = TRUE; + //flag = 1; + //smpp_state[link] = WAITING; + temp_status = WAITING; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + exterEvent[link][exter_tail[link]] = 0; + exter_tail[link] = (exter_tail[link]+1)&0x7; + //IDLE state:: external event end. + //IDLE state:: internal event start. + switch (interEvent[link][inter_tail[link]]) { + case Outbind: + smpp_state[link] = WAITING; + smpp_PrimitiveSend(link, BindReceiver); + session_init_flag[link] = TRUE; + //flag = 0; + //smpp_state[link] = WAITING; + temp_status = WAITING; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case BindTransmitter: + smpp_state[link] = ESTABLISHED; + smpp_PrimitiveSend(link, BindTransmitterResp); + enquire_link_flag[link] = TRUE; + //smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,TRUE); + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + return; + + break; + case BindTransceiver: + smpp_state[link] = ESTABLISHED; + smpp_PrimitiveSend(link, BindTransceiverResp); + enquire_link_flag[link] = TRUE; + //smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,TRUE); + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + return; + + break;//fixed 2008-1-11 + case BindReceiver: + smpp_state[link] = ESTABLISHED; + smpp_PrimitiveSend(link, BindReceiverResp); + session_init_flag[link] = FALSE; + enquire_link_flag[link] = TRUE; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,TRUE); + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + return; + + break; + default: + break; + } + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + //IDLE state:: internal event end. + break; + case WAITING: + switch (exterEvent[link][exter_tail[link]]) { + case Close: + smpp_state[link] = IDLE; + temp_status = IDLE; + dst_ref[link] = 0; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + default: + break; + } + exterEvent[link][exter_tail[link]] = 0; + exter_tail[link] = (exter_tail[link]+1)&0x7; + //WAITING state:: external event end. + //WAITING state:: Internal event start. + switch (interEvent[link][inter_tail[link]]) + { + case SessionInitTimeout: + session_init_flag[link] = FALSE; + smpp_state[link] = IDLE; + temp_status = IDLE; + dst_ref[link] = 0; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case BindReceiverResp: + //if (0 == flag) { + session_init_flag[link] = FALSE; + enquire_link_flag[link] = TRUE; + smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,TRUE); + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + return; + + /* + } + else + smpp_state[link] = WAITING; + */ + break; + case BindTransmitterResp: + case BindTransceiverResp: + //if (1 == flag) { + session_init_flag[link] = FALSE; + enquire_link_flag[link] = TRUE; + smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,TRUE); + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + return; + + /* + } + else + smpp_state[link] = WAITING; + */ + break; + case BindReceiver: + //if (2 == flag) { + smpp_PrimitiveSend(link, BindReceiverResp); + session_init_flag[link] = FALSE; + enquire_link_flag[link] = TRUE; + smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,TRUE); + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + return; + /* + } + else + smpp_state[link] = WAITING; + */ + break; + default: + break; + } + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + //WAITING state:: internal event end. + break; + case ESTABLISHED: + switch (exterEvent[link][exter_tail[link]]) + { + case Close: + smpp_state[link] = SUSPEND; + smpp_PrimitiveSend(link, Unbind); + //smpp_state[link] = SUSPEND; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + default: + break; + } + exterEvent[link][exter_tail[link]] = 0; + exter_tail[link] = (exter_tail[link]+1)&0x7; + //ESTABLISHED state:: external event end. + //ESTABLISHED state:: internal event start. + switch (interEvent[link][inter_tail[link]]) + { + //normal messages + case Unbind: + smpp_PrimitiveSend(link, UnbindResp); + dst_ref[link] = 0; + smpp_closeTCPConnection(link); + enquire_link_flag[link] = FALSE; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,FALSE); + return; + break; + case SubmitSM: + case SubmitSMResp: + case SubmitMulti: + case SubmitMultiResp: + case DeliverSM: + case DeliverSMResp: + case DataSM: + case DataSMResp: + case QuerySM: + case QuerySMResp: + case CancelSM: + case CancelSMResp: + case ReplaceSM: + case ReplaceSMResp: + enquire_link_timer[link] = 0; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case EnquireLinkTimeout: + smpp_state[link] = ESTABLISHED; + smpp_PrimitiveSend(link, EnquireLink); + inactivity_flag[link] = TRUE; + //smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case EnquireLink: + smpp_state[link] = ESTABLISHED; + smpp_PrimitiveSend(link, EnquireLinkResp); + enquire_link_timer[link] = 0; + //smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case EnquireLinkResp: + enquire_link_timer[link] = 0; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case InactivityTimeout: + //smpp_PrimitiveSend(link, Unbind); + //smpp_state[link] = SUSPEND; + dst_ref[link] = 0; + if (smpp_param[link].link_type == SMPP_TCP) + { + smpp_closeTCPConnection(link); + } + enquire_link_flag[link] = FALSE; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,FALSE); + return; + break; + /* error handing messages */ + case BindTransmitter: + smpp_state[link] = ESTABLISHED; +// smpp_sendBindResp(link, BindTransmitterResp, ESME_RALYBND); + smpp_sendBindResp(link, BindTransmitterResp, 0); + enquire_link_timer[link] = 0; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + //smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case BindReceiver: + smpp_state[link] = ESTABLISHED; +// smpp_sendBindResp(link, BindReceiverResp, ESME_RALYBND); + smpp_sendBindResp(link, BindReceiverResp, 0); + enquire_link_timer[link] = 0; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + //smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case BindTransceiver: + smpp_state[link] = ESTABLISHED; +// smpp_sendBindResp(link, BindTransceiverResp, ESME_RALYBND); + smpp_sendBindResp(link, BindTransceiverResp, 0); + enquire_link_timer[link] = 0; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + //smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + default: + smpp_state[link] = ESTABLISHED; + temp_status = ESTABLISHED; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + } + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + //ESTABLISHED state:: internal event end. + break; + case SUSPEND: + //SUSPEND state:: internal event start. + suspend_timer ++; + switch (interEvent[link][inter_tail[link]]) + { + case UnbindResp: + suspend_timer = 0; + dst_ref[link] = 0; + smpp_closeTCPConnection(link); + enquire_link_flag[link] = FALSE; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,FALSE); + return; + break; +/* case InactivityTimeout://ch + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,FALSE); + dst_ref[link] = 0; + if (smpp_param[link].link_type == SMPP_TCP) + smpp_closeTCPConnection(link); + enquire_link_flag[link] = FALSE; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; + case SessionInitTimeout://ch + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,FALSE); + dst_ref[link] = 0; + if (smpp_param[link].link_type == SMPP_TCP) + smpp_closeTCPConnection(link); + enquire_link_flag[link] = FALSE; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + break; */ + default: + break; + } + interEvent[link][inter_tail[link]] = 0; + inter_tail[link] = (inter_tail[link]+1)&0x7; + if( suspend_timer++ > smpp_param[link].inactivity_timer) + { + suspend_timer = 0; + dst_ref[link] = 0; + if (smpp_param[link].link_type == SMPP_TCP) + smpp_closeTCPConnection(link); + enquire_link_flag[link] = FALSE; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,FALSE); + return; + } + //SUSPEND state:: internal event end. + break; + default: + break; + } //end switch(state) + } //end for(froc... + + //platform heartbeat + platform_heartbeat_len = (MAX_SMPP_LINK%4)?(MAX_SMPP_LINK/4+1):(MAX_SMPP_LINK/4); + set_status(SMPP_HEARTBEAT_COMPONENT_ID, platform_heartbeat_len, smpp_hearbeat_status); +} + +void init_link(u32 link) +{ + BYTE temp_status; + dst_ref[link] = 0; + smpp_closeTCPConnection(link); + enquire_link_flag[link] = FALSE; + inactivity_flag[link] = FALSE; + inactivity_timer[link] = 0; + smpp_state[link] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((link%4)*2); + smpp_hearbeat_status[link/4] |= temp_status; + if(callBackFunc[link].link_proc!= NULL) + callBackFunc[link].link_proc(link,FALSE); + return; +} + diff --git a/plat/smpp/src/smpp_func.c b/plat/smpp/src/smpp_func.c new file mode 100644 index 0000000..574ff2d --- /dev/null +++ b/plat/smpp/src/smpp_func.c @@ -0,0 +1,1204 @@ +/* +** CDMA 2000 project, SMPP module +** +** File name: smpp_func.c +** Written by Li Long at 2004-11-25 +** CVS $Id: smpp_func.c,v0.1 2004/11/25 17:03:14 lilong Exp $ +** +*/ + +#include "./include/smpp.h" +#include "./include/smpp_def.h" + +// fix multiple definition==================================== +SMPP_CALLBACK callBackFunc[MAX_SMPP_LINK]; +SMPP_PARAM smpp_param[MAX_SMPP_LINK]; +SMPP_LINK smpp_link[MAX_SMPP_LINK]; +struct SocketsInUse Mysock; +SMPP_DEBUG_STRUCT smppDebug; + +BYTE exterEvent[MAX_SMPP_LINK][CMD_BUF_SIZE]; +BYTE interEvent[MAX_SMPP_LINK][CMD_BUF_SIZE]; +BYTE exter_head[MAX_SMPP_LINK]; +BYTE exter_tail[MAX_SMPP_LINK]; +BYTE inter_head[MAX_SMPP_LINK]; +BYTE inter_tail[MAX_SMPP_LINK]; + +BYTE smpp_state[MAX_SMPP_LINK]; +BYTE smpp_hearbeat_status[MAX_SMPP_LINK/4]; +BYTE interface_mode[MAX_SMPP_LINK]; +BYTE data_mode[MAX_SMPP_LINK]; + +BYTE linkAttachFlag[MAX_SMPP_LINK]; +BYTE smpp_TCPClientFlag[MAX_SMPP_LINK]; +char smpp_debug_asciiIn[MAX_ASCIN_BUF_LEN]; +char smpp_debug_asciiOut[MAX_ASCOUT_BUF_LEN]; +BYTE smppDebugFull = 0; + +BYTE src_ref[MAX_SMPP_LINK]; +BYTE dst_ref[MAX_SMPP_LINK]; + +BYTE smpp_msg[MAX_PACKET_SIZE]; + +BYTE smpp_system_no; +// + +extern int register_ssn(BYTE ssn, BYTE usertype); +extern u_long wxc2_get_localip(char *ip_str); +int smpp_init_new(u8 sys_id) +{ + smpp_system_no = sys_id & 0x01; + #ifdef SMPP_DEBUG + smpp_debugInit(); + #endif //end ifdef SMPP_DEBUG + smpp_mibInit(); + smpp_loadParam(); + smpp_writeParam(); + + heartbeat_init(0xffff); + + smpp_initTCPClient(); + smpp_initTCPServer(); + smpp_stateInit(); + smpp_msgInit(); + +// if (FALSE == register_ssn(SMPP_PPS_SSN, SMPP_PPS_USERTYPE)) + if (FALSE == register_ssn(SMPP_PPS_SSN, SMPP_SMSC_USERTYPE)) + printf("SMPP register PPS SSN %d fail!\n", SMPP_PPS_SSN); + if (FALSE == register_ssn(SMPP_SMSC_SSN, SMPP_SMSC_USERTYPE)) + printf("SMPP register SMSC SSN %d fail!\n", SMPP_SMSC_SSN); + printf("SMPP init........ Complete.\n"); + + return TRUE; +} + +void smpp_reset() +{ + int i; + for (i=0; i0x00 && smpp_param[i].local_ip != wxc2_get_localip(NULL)) continue; + + len_get = strlen(service_number_ptr); + if (len_get > 8) { + service_number_ptr[8] = 0; + len_get = 8; + } + len_in_para = strlen(smpp_param[i].service_number); + if (len_in_para < len_get) { + if (strncmp(service_number_ptr, smpp_param[i].service_number, len_in_para) == 0) { + smpp_param[i].message_mode = message_mode; + return (BYTE)((i&0x7F)|0x80); + } + } + else { + if (strcmp(service_number_ptr, smpp_param[i].service_number) == 0) { + smpp_param[i].message_mode = message_mode; + return (BYTE)((i&0x7F)|0x80); + } + } + } + + sprintf(debugBuf,"smpp_registerLink(server_type:%d,session_type:%d,service_number:%s,message_mode:%d) fail\r\n\r\n",server_type,session_type,service_number_ptr,message_mode); + smpp_send_error(debugBuf); + return 0; +} + +void smpp_attach_link(BYTE linkNo, smpp_callBack_dataProc onDataRecv, + smpp_callBack_linkProc onLinkStateChange) +{ + BYTE temp_status; + + if(linkNo>=MAX_SMPP_LINK) return; + + printf("[smpp]link %d attached.\n", linkNo); + if(smpp_state[linkNo] == ESTABLISHED || + smpp_state[linkNo] == SUSPEND) + { + if(callBackFunc[linkNo].link_proc!= NULL) + callBackFunc[linkNo].link_proc(linkNo,TRUE); + return; + } + else if(smpp_state[linkNo] == WAITING) + { + if(callBackFunc[linkNo].link_proc!= NULL) + callBackFunc[linkNo].link_proc(linkNo,FALSE); + return; + } + + linkAttachFlag[linkNo] = TRUE; + smpp_state[linkNo] = IDLE; + temp_status = IDLE; + temp_status = temp_status<<((linkNo%4)*2); + smpp_hearbeat_status[linkNo/4] |= temp_status; + callBackFunc[linkNo].data_proc = onDataRecv; + callBackFunc[linkNo].link_proc = onLinkStateChange; + exterEvent[linkNo][exter_head[linkNo]] = Setup; + exter_head[linkNo] = (exter_head[linkNo]+1)&0x7; + + if(SMPP_TCP == smpp_param[linkNo].link_type) + { + switch (smpp_param[linkNo].session_type) { + case BIND_TX: + case BIND_TRX: + if (smpp_param[linkNo].server_type == SMPP_CLIENT) + smpp_TCPClientFlag[linkNo] = 1; + break; + case BIND_RX: + if (smpp_param[linkNo].server_type == SMPP_SERVER) + smpp_TCPClientFlag[linkNo] = 1; + break; + } + } +} + +WORD smpp_send(BYTE linkNo, SMPP_MSG* pMsg, WORD dataLen) +{ + PDU_SUBMIT_SM *pSubmitSM; + PDU_SUBMIT_MULTI *pSubmitMulti; + PDU_DELIVER_SM *pDeliverSM; + PDU_DATA_SM *pDataSM; + PDU_QUERY_SM *pQuerySM; + PDU_CANCEL_SM *pCancelSM; + PDU_REPLACE_SM *pReplaceSM; + DWORD seqNum; + +// printf("\33[32mlink %d call smpp_send, message_type=%d\33[0m\n", linkNo, pMsg->message_type); + switch (pMsg->message_type) + { + case 0x0B: /* SUBMIT SM */ + pSubmitSM = &pMsg->pdu.submit_sm; + pSubmitSM->head.command_id = htonl(SUBMIT_SM); + pSubmitSM->head.command_status = 0x0; + //seqNum = smpp_getSequenceNumber(linkNo); + //pSubmitSM->head.sequence_number = htonl(seqNum); + pSubmitSM->head.sequence_number = htonl(pSubmitSM->head.sequence_number); + + smpp_encode_msg(linkNo, pMsg, SubmitSM); + break; + case 0x0C: /* SUBMIT SM RESP */ + pMsg->pdu.submit_sm_resp.head.command_id = htonl(SUBMIT_SM_RESP); + seqNum = ntohl(pMsg->pdu.submit_sm_resp.head.sequence_number); + smpp_encode_msg(linkNo, pMsg, SubmitSMResp); + break; + case 0x0D: /* SUBMIT MULTI */ + pSubmitMulti = &pMsg->pdu.submit_multi; + pMsg->pdu.submit_multi.head.command_id = htonl(SUBMIT_MULTI); + pMsg->pdu.submit_multi.head.command_status = 0x0; + //seqNum = smpp_getSequenceNumber(linkNo); + //pMsg->pdu.submit_multi.head.sequence_number = htonl(seqNum); + pSubmitMulti->head.sequence_number = htonl(pSubmitMulti->head.sequence_number); + + smpp_encode_msg(linkNo, pMsg, SubmitMulti); + break; + case 0x0E: /* SUBMIT MULTI RESP */ + pMsg->pdu.submit_multi_resp.head.command_id = htonl(SUBMIT_MULTI_RESP); + seqNum = ntohl(pMsg->pdu.submit_multi_resp.head.sequence_number); + smpp_encode_msg(linkNo, pMsg, SubmitMultiResp); + break; + case 0x0F: /* DELIVER SM */ + pDeliverSM = &pMsg->pdu.deliver_sm; + pDeliverSM->head.command_id = htonl(DELIVER_SM); + pDeliverSM->head.command_status = 0x0; + //seqNum = smpp_getSequenceNumber(linkNo); + //pDeliverSM->head.sequence_number = htonl(seqNum); + pDeliverSM->head.sequence_number = htonl(pDeliverSM->head.sequence_number); + + pDeliverSM->schedule_delivery_time = 0; + pDeliverSM->validity_period = 0; + pDeliverSM->replace_if_present_flag = 0; + pDeliverSM->sm_default_msg_id = 0; + + smpp_encode_msg(linkNo, pMsg, DeliverSM); + break; + case 0x10: /* DELIVER SM RESP */ + pMsg->pdu.deliver_sm.head.command_id = htonl(DELIVER_SM_RESP); + seqNum = ntohl(pMsg->pdu.deliver_sm.head.sequence_number); + smpp_encode_msg(linkNo, pMsg, DeliverSMResp); + break; + case 0x11: /* DATA SM */ + pDataSM = &pMsg->pdu.data_sm; + pDataSM->head.command_id = htonl(DATA_SM); + pDataSM->head.command_status = 0x0; + //seqNum = smpp_getSequenceNumber(linkNo); + //pDataSM->head.sequence_number = htonl(seqNum); + pDataSM->head.sequence_number = htonl(pDataSM->head.sequence_number); + + smpp_encode_msg(linkNo, pMsg, DataSM); + break; + case 0x12: /* DATA SM RESP */ + pMsg->pdu.data_sm_resp.head.command_id = htonl(DATA_SM_RESP); + seqNum = ntohl(pMsg->pdu.data_sm_resp.head.sequence_number); + smpp_encode_msg(linkNo, pMsg, DataSMResp); + break; + case 0x13: /* QUERY SM */ + pQuerySM = &pMsg->pdu.query_sm; + pMsg->pdu.query_sm.head.command_id = htonl(QUERY_SM); + pMsg->pdu.query_sm.head.command_status = 0x0; + //seqNum = smpp_getSequenceNumber(linkNo); + //pMsg->pdu.query_sm.head.sequence_number = htonl(seqNum); + pQuerySM->head.sequence_number = htonl(pQuerySM->head.sequence_number); + + smpp_encode_msg(linkNo, pMsg, QuerySM); + break; + case 0x14: /* QUERY SM RESP */ + pMsg->pdu.query_sm_resp.head.command_id = htonl(QUERY_SM_RESP); + seqNum = ntohl(pMsg->pdu.query_sm_resp.head.sequence_number); + smpp_encode_msg(linkNo, pMsg, QuerySMResp); + break; + case 0x15: /* CANCEL SM */ + pCancelSM = &pMsg->pdu.cancel_sm; + pMsg->pdu.cancel_sm.head.command_id = htonl(CANCEL_SM); + pMsg->pdu.cancel_sm.head.command_status = 0x0; + //seqNum = smpp_getSequenceNumber(linkNo); + //pMsg->pdu.cancel_sm.head.sequence_number = htonl(seqNum); + pCancelSM->head.sequence_number = htonl(pCancelSM->head.sequence_number); + + smpp_encode_msg(linkNo, pMsg, CancelSM); + break; + case 0x16: /* CANCEL SM RESP */ + pMsg->pdu.cancel_sm_resp.head.command_id = htonl(CANCEL_SM_RESP); + seqNum = ntohl(pMsg->pdu.cancel_sm_resp.head.sequence_number); + smpp_encode_msg(linkNo, pMsg, CancelSMResp); + break; + case 0x17: /* REPLACE SM */ + pReplaceSM = &pMsg->pdu.replace_sm; + pMsg->pdu.replace_sm.head.command_id = htonl(REPLACE_SM); + pMsg->pdu.replace_sm.head.command_status = 0x0; + //seqNum = smpp_getSequenceNumber(linkNo); + //pMsg->pdu.replace_sm.head.sequence_number = htonl(seqNum); + pReplaceSM->head.sequence_number = htonl(pReplaceSM->head.sequence_number); + smpp_encode_msg(linkNo, pMsg, ReplaceSM); + break; + case 0x18: /* REPLACE SM RESP */ + pMsg->pdu.replace_sm_resp.head.command_id = htonl(REPLACE_SM_RESP); + seqNum = ntohl(pMsg->pdu.replace_sm_resp.head.sequence_number); + smpp_encode_msg(linkNo, pMsg, ReplaceSMResp); + break; + default: +// printf("[ERROR]link %d no such message type!(=%02x)\n", linkNo, pMsg->message_type); + return 0; + } + + return seqNum; +} + +void smpp_close(BYTE linkNo) +{ + exterEvent[linkNo][exter_head[linkNo]] = Close; + exter_head[linkNo] = (exter_head[linkNo]+1)&0x7; +} + +void smpp_PrimitiveSend(int linkNo, int event_id) +{ + switch (event_id) + { + case BindTransmitter: + smpp_sendBind(linkNo, BindTransmitter); + break; + case BindTransmitterResp: + smpp_sendBindResp(linkNo, BindTransmitterResp, 0); + break; + case BindReceiver: + smpp_sendBind(linkNo, BindReceiver); + break; + case BindReceiverResp: + smpp_sendBindResp(linkNo, BindReceiverResp, 0); + break; + case BindTransceiver: + smpp_sendBind(linkNo, BindTransceiver); + break; + case BindTransceiverResp: + smpp_sendBindResp(linkNo, BindTransceiverResp, 0); + break; + case Unbind: + smpp_sendUnbind(linkNo); + break; + case UnbindResp: + smpp_sendUnbindResp(linkNo); + break; + case EnquireLink: + smpp_sendEnquireLink(linkNo); + break; + case EnquireLinkResp: + smpp_sendEnquireLinkResp(linkNo); + break; + case Outbind: + smpp_sendOutbind(linkNo); + break; + default: + break; + } +} + +void smpp_initTCPClintByLink(unsigned int linkNo) +{ + int on=1, flag=1; + struct sockaddr_in local_addr; + + if(linkNo>=MAX_SMPP_LINK) return; + + if (((smpp_param[linkNo].link_enable & 0x01) == 0) || (smpp_param[linkNo].link_type == SMPP_UDP)) + { + return; + } + if ((Mysock.client_sock[linkNo] = socket(AF_INET, SOCK_STREAM, 0))<0) + { + return; + } + if (setsockopt(Mysock.client_sock[linkNo], SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) + { + close(Mysock.client_sock[linkNo]); + return; + } + if (setsockopt(Mysock.client_sock[linkNo], SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) + { + close(Mysock.client_sock[linkNo]); + return; + } + if (fcntl(Mysock.client_sock[linkNo], F_SETFL, O_NONBLOCK) == -1) + { + close(Mysock.client_sock[linkNo]); + return; + } + /* Set this sockets as a Non-blocking sockets. */ + if (ioctl(Mysock.client_sock[linkNo], FIONBIO, &flag) == -1) + { + close(Mysock.client_sock[linkNo]); + return; + } + + bzero(&local_addr, sizeof(local_addr)); + local_addr.sin_family = AF_INET; + local_addr.sin_addr.s_addr = GetLocalIP();//htonl(INADDR_ANY); + local_addr.sin_port = 0; + memset(local_addr.sin_zero, 0, sizeof(local_addr.sin_zero)); + if (bind(Mysock.client_sock[linkNo], (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) + { + perror("init TCP Client By Link: bind error"); + exit(1); + } +} + +void smpp_initTCPClient() +{ + int i; + + for (i=0; ih_addr_list))->s_addr = GetLocalIP(); + host_ip = inet_ntoa(*(struct in_addr *)(*host->h_addr_list)); + } + else + { + perror("[smpp] gethostbyname"); + exit(2); + } + } + + return host_ip; +} + +int smpp_closeTCPConnection(int linkNo) +{ + int retcode; + + if ( (linkNo>=MAX_SMPP_LINK) || (linkNo<0) || (Mysock.Sockets[linkNo]<=0) ) + return (0); + retcode = close(Mysock.Sockets[linkNo]); + + FD_CLR(Mysock.Sockets[linkNo], &Mysock.readfds); + FD_CLR(Mysock.Sockets[linkNo], &Mysock.writefds); + FD_CLR(Mysock.Sockets[linkNo], &Mysock.exceptfds); + Mysock.Sockets[linkNo] = 0; + + #ifdef SMPP_PRINT_SCREEN +// printf("link %d close TCP connection.\n", linkNo); + #endif + return (retcode); +} + +// fix multiple definition==================================== +SocketsMsg SockMsg; +// +int QuerySocketsMsg() +{ + fd_set rfds,wfds,efds; + int retcode,i; + struct timeval TimeOut; + + rfds = Mysock.readfds; + wfds = Mysock.writefds; + efds = Mysock.exceptfds; + TimeOut.tv_sec = 0; + TimeOut.tv_usec = 0; + bzero((char *)&SockMsg, sizeof(SockMsg)); + if ((retcode = select(MAX_SMPP_LINK, &rfds, &wfds, &efds, &TimeOut)) == 0) + { + return (0); + } + if (FD_ISSET(Mysock.DaemonSock, &rfds)) + { + SockMsg.AcceptNum = 1; + } + for (i=0; i0) && (FD_ISSET(Mysock.Sockets[i],&rfds))) + { + SockMsg.ReadQueue[SockMsg.ReadNum++] = i; + } + } + for (i=0; i0) && (FD_ISSET(Mysock.Sockets[i],&wfds))) + { + SockMsg.WriteQueue[SockMsg.WriteNum++] = i; + } + } + if (FD_ISSET(Mysock.DaemonSock, &efds)) + { + SockMsg.AcceptNum = -1; + } + for (i=0; i0) && (FD_ISSET(Mysock.Sockets[i],&efds))) + { + SockMsg.WriteQueue[SockMsg.ExceptNum++] = i; + } + } + + return (retcode); +} + +int smpp_check_sysid_route(char* sysid_rv, BYTE sysidlen_rv, BYTE server_type, BYTE session_type) +{ + int i; + char debugBuf[256]; + + for (i=0; iRI = 0; + pSrcAddr->GTI = 4; + pSrcAddr->TT = 0; + pSrcAddr->NP = 1; /* MSISDN */ + pSrcAddr->NAI = 4; + pDstAddr->SSN = smpp_param[linkNo].localSSN; + pSrcAddr->len = smpp_ascii2GTAI(pSrcAddr->GTAI, smpp_param[linkNo].localGTT); + + /* set SCCP destination address. */ + pDstAddr->RI = 0; + pDstAddr->GTI = 4; + pDstAddr->TT = 0; + pDstAddr->NP = 1; /* MSISDN */ + pDstAddr->NAI = 4; + pDstAddr->SSN = smpp_param[linkNo].remoteSSN; + pDstAddr->len = smpp_ascii2GTAI(pDstAddr->GTAI, smpp_param[linkNo].remoteGTT); +} + +BYTE smpp_ascii2GTAI(BYTE *pGTAI, char *pGTT) +{ + BYTE len, bcd; + int i; + char debugBuf[1024]; + + len = strlen(pGTT); + if (len < 1) return 0; + if (len==16) len = 15;//last BYTE is ssn + for (i=0; i>4) == 0xf) + { + pGTT[i*2+1] = '\0'; + } + else + { + pGTT[i*2+1] = ((pGTAI[i]>>4)&0xf) + '0'; + } + } + pGTT[len] = '\0'; +} + +void smpp_addTLV(BYTE *smpp_msg, WORD optionTag, BYTE *pMsg, WORD len) +{ + WORD ns_optionTag; + WORD ns_len; + + ns_optionTag = htons(optionTag); + switch (optionTag) + { + /* value 0 byte */ + case ALERT_ON_MESSAGE_DELIVERY: + memcpy(smpp_msg, &ns_optionTag, 2); + len = 0; + memcpy(smpp_msg+2, &len, 2); + break; + /* value 1 byte for integer. */ + case DEST_ADDR_SUBUNIT: + case SOURCE_ADDR_SUBUNIT: + case DEST_NETWORK_TYPE: + case SOURCE_NETWORK_TYPE: + case DEST_BEARER_TYPE: + case SOURCE_BEARER_TYPE: + case PRIVACY_INDICATOR: + case PAYLOAD_TYPE: + case LANGUAGE_INDICATOR: + case USER_RESPONSE_CODE: + case MS_MSG_WAIT_FACILITIES: + case SAR_TOTAL_SEGMENTS: + case SAR_SEGMENT_SEQNUM: + case SC_INTERFACE_VERSION: + case DISPLAY_TIME: + case MS_VALIDITY: + case DPF_RESULT: + case SET_DPF: + case MS_AVAILABILITY_STATUS: + case DELIVERY_FAILURE_REASON: + case MORE_MESSAGES_TO_SEND: + case MESSAGE_STATE: + case CALLBACK_NUM_PRES_IND: + case NUMBER_OF_MESSAGES: + case ITS_REPLY_TYPE: + case USSD_SERVICE_OP: + memcpy(smpp_msg, &ns_optionTag, 2); + len = 1; + ns_len = htons(len); + memcpy(smpp_msg+2, &ns_len, 2); + *(smpp_msg+4) = *pMsg; + break; + /* value 2 bytes for integer */ + case DEST_TELEMATICS_ID: + case SOURCE_TELEMATICS_ID: + case USER_MESSAGE_REFERENCE: + case SOURCE_PORT: + case DESTINATION_PORT: + case SAR_MSG_REF_NUM: + case SMS_SIGNAL: + case ITS_SESSION_INFO: + memcpy(smpp_msg, &ns_optionTag, 2); + len = 2; + ns_len = htons(len); + memcpy(smpp_msg+2, &ns_len, 2); + memcpy(smpp_msg+4, pMsg, 2); + break; + /* value 3 bytes for octet string */ + case NETWORK_ERROR_CODE: + memcpy(smpp_msg, &ns_optionTag, 2); + len = 3; + ns_len = htons(len); + memcpy(smpp_msg+2, &ns_len, 2); + memcpy(smpp_msg+4, pMsg, 3); + break; + /* value 4 bytes for integer */ + case QOS_TIME_TO_LIVE: + memcpy(smpp_msg, &ns_optionTag, 2); + len = 4; + ns_len = htons(len); + memcpy(smpp_msg+2, &ns_len, 2); + memcpy(smpp_msg+4, pMsg, 4); + break; + /* variable length */ + case ADDITIONAL_STATUS_INFO_TEXT: + case RECEIPTED_MESSAGE_ID: + case SOURCE_SUBADDRESS: + case DEST_SUBADDRESS: + case MESSAGE_PAYLOAD: + case CALLBACK_NUM: + case CALLBACK_NUM_ATAG: + memcpy(smpp_msg, &ns_optionTag, 2); + ns_len = htons(len); + memcpy(smpp_msg+2, &ns_len, 2); + memcpy(smpp_msg+4, pMsg, len+1); + break; + } +} + +void smpp_display_hex_msg(BYTE* disp_ptr, int len) +{ + int i; + char debugBuf[4096]; + + for (i=0; i MAX_SMPP_LINK) return -1; + pParam = &smpp_param[instance]; + switch(oid[SMPP_OIDLEN+1]) { + case 1: + pParam->link_enable = pData[0]; + len = 1; + //link type + pParam->link_type = pData[1]; + len += 1; + //server type + pParam->server_type = pData[2]; + len += 1; + //session type + pParam->session_type = pData[3]; + len += 1; + //system id + memset(pParam->sys_id, 0, SMPP_SYSID_LEN); //16 + memcpy(pParam->sys_id, pData+len, SMPP_SYSID_LEN); + pParam->sys_id[SMPP_SYSID_LEN] = '\0'; + len += SMPP_SYSID_LEN; + //password + memset(pParam->password, 0, SMPP_PASSWD_LEN); //9 + memcpy(pParam->password, pData+len, SMPP_PASSWD_LEN); + pParam->password[SMPP_PASSWD_LEN] = '\0'; + len += SMPP_PASSWD_LEN; + //system type + memset(pParam->system_type, 0, SMPP_SYSTYPE_LEN); //13 + memcpy(pParam->system_type, pData+len, SMPP_SYSTYPE_LEN); + pParam->system_type[SMPP_SYSTYPE_LEN] = '\0'; + len += SMPP_SYSTYPE_LEN; + //local gtt + memset(pParam->localGTT, 0, SMPP_GTT_LEN); //16 + memcpy(pParam->localGTT, pData+len, SMPP_GTT_LEN); + pParam->localGTT[SMPP_GTT_LEN] = '\0'; + len += SMPP_GTT_LEN; + //remote gtt + memset(pParam->remoteGTT, 0, SMPP_GTT_LEN); + memcpy(pParam->remoteGTT, pData+len, SMPP_GTT_LEN); + pParam->remoteGTT[SMPP_GTT_LEN] = '\0'; + len += SMPP_GTT_LEN; + //local ip + memcpy(&pParam->local_ip, pData+len, 4); + len += 4; + //remote ip + memcpy(&pParam->remote_ip, pData+len, 4); + len += 4; + //session init timer + pParam->session_init_timer = bcdtou32(pData+len, 4); + len += 4; + // enquire link timer + pParam->enquire_link_timer = bcdtou32(pData+len, 4); + len += 4; + //inactivity timer + pParam->inactivity_timer = bcdtou32(pData+len, 4); + len += 4; + //response timer + pParam->response_timer = bcdtou32(pData+len, 4); + len += 4; + //remote service number + memset(pParam->service_number, 0, 8); + memcpy(pParam->service_number, pData+len, 8); + len += 8; + pParam->localSSN = pData[len]; + len += 1; + pParam->remoteSSN = pData[len]; + len += 1; + break; + default: + return (-1); + } + break; + case 3: //Status + switch (oid[SMPP_OIDLEN + 1]) { + case 1: //version, read only + return -1; + case 2: //command + switch (pData[0]) { + case 0: //reset + smpp_reset(); + break; + case 1: //load + smpp_loadParam(); + break; + case 2: //save + smpp_writeParam(); + break; + } + return 1; + case 3: //status, read only + return -1; + } + break; + default: + break; + } + return datalen; +} + +int smpp_getMib(BYTE oidlen, DWORD *oid, BYTE *pData, BYTE *vartype) +{ + int len=0, datalen = -1; + DWORD instance; + SMPP_PARAM *pParam; + + switch(oid[SMPP_OIDLEN]) + { + case 1: //Measurement + break; + case 2: //Configuration + instance = oid[SMPP_OIDLEN+2]; + if (instance > MAX_SMPP_LINK) return -1; + pParam = &smpp_param[instance]; + switch(oid[SMPP_OIDLEN+1]) + { + case 1: //smpp parameter + //link enable + pData[0] = pParam->link_enable; + len = 1; + //link type + pData[1] = pParam->link_type; + len += 1; + //server type + pData[2] = pParam->server_type; + len += 1; + //session type + pData[3] = pParam->session_type; + len += 1; + //system id + memcpy(pData+len, pParam->sys_id, SMPP_SYSID_LEN); + len += SMPP_SYSID_LEN; + //password + memcpy(pData+len, pParam->password, SMPP_PASSWD_LEN); + len += SMPP_PASSWD_LEN; + //system type + memcpy(pData+len, pParam->system_type, SMPP_SYSTYPE_LEN); + len += SMPP_SYSTYPE_LEN; + //local gtt + memcpy(pData+len, pParam->localGTT, SMPP_GTT_LEN); + len += SMPP_GTT_LEN; + //remote gtt + memcpy(pData+len, pParam->remoteGTT, SMPP_GTT_LEN); + len += SMPP_GTT_LEN; + //local ip + memcpy(pData+len, &pParam->local_ip, 4); + len += 4; + //remote ip + memcpy(pData+len, &pParam->remote_ip, 4); + len += 4; + //session init timer + u32tobyte(pData+len, pParam->session_init_timer); + len += 4; + //enquire link timer + u32tobyte(pData+len, pParam->enquire_link_timer); + len += 4; + //inactivity timer + u32tobyte(pData+len, pParam->inactivity_timer); + len += 4; + //response timer + u32tobyte(pData+len, pParam->response_timer); + len += 4; + //remote service number + memcpy(pData+len, &pParam->service_number, 8); + len += 8; + pData[len] = pParam->localSSN; + len += 1; + pData[len] = pParam->remoteSSN; + len += 1; + *vartype = 4; + datalen = len; + break; + default: + break; + } + break; + case 3: //Status + break; + default: + break; + } + + return datalen; +} + +int smpp_parseLine(char *str, char (*row)[128], int maxrow) +{ + char *pstr = str; + int len, index = 0, i; + BOOL black = 0; + + len = strlen(str); + for(i = 0; i < len && index < maxrow; i++) + { + if(isspace(str[i])) + { + if(black == 0) + pstr = str + i + 1; + else + { + str[i] = '\0'; + if(strlen(pstr) > 128) + pstr[127] = 0; + sprintf(row[index++], "%s", pstr); + pstr = str + i + 1; + } + black = 0; + } + else + black = 1; + } + if(black == 1) + { + if(strlen(pstr) > 128) + pstr[127] = 0; + sprintf(row[index++], "%s", pstr); + } + return index; +} + +int smpp_loadParam() +{ + FILE *fp; + char str[512] = "\0", *pChr; + char info[19][128]; + int rtn; + int ver[3]; + BYTE linkNo; + + fp = fopen(SMPP_CONF_FILE, "r"); + if (fp == NULL) + { + printf("SMPP init parameters....search %s FAILED\n",SMPP_CONF_FILE); + return FAILURE; + } + + while (fgets(str, 512, fp) != NULL) { + if ((pChr = strchr(str, '#')) != NULL) { + if((pChr = strstr(pChr,"SMPP Config file"))!=NULL) + { + if ((pChr = strchr(pChr, 'R')) != NULL) + { + ver[0] = atoi(pChr+1); + ver[1] = atoi(pChr+3); + ver[2] = atoi(pChr+5); + } + } + continue; + } + + rtn = smpp_parseLine(str, info, 19); + if (rtn < 17) { + //smpp_debug(SCCPDB_ERR, "<001>Invalid line in Local_Node Table, field count = %d", rtn); + printf("Invalid line in ./conf/smpp.conf table, field count = %d\n", rtn); + return FALSE; + } + else if(rtn < 19) + { + sprintf(info[17],"0"); + sprintf(info[18],"0"); + } + + linkNo = atoi(info[0]); + smpp_param[linkNo].link_enable = atoi(info[1]); + smpp_param[linkNo].link_type = atoi(info[2]); + smpp_param[linkNo].server_type = atoi(info[3]); + smpp_param[linkNo].session_type = atoi(info[4]); + + if (strncmp(info[5], "--", 2) == 0) + strcpy(smpp_param[linkNo].sys_id, ""); + else + sprintf(smpp_param[linkNo].sys_id, "%s", info[5]); + + if (strncmp(info[6], "--", 2) == 0) + strcpy(smpp_param[linkNo].password, ""); + else + sprintf(smpp_param[linkNo].password, "%s", info[6]); + + if (strncmp(info[7], "--", 2) == 0) + strcpy(smpp_param[linkNo].system_type, ""); + else + sprintf(smpp_param[linkNo].system_type, "%s", info[7]); + + if (strncmp(info[8], "--", 2) == 0) + strcpy(smpp_param[linkNo].localGTT, ""); + else + sprintf(smpp_param[linkNo].localGTT, "%s", info[8]); + + if (strncmp(info[9], "--", 2) == 0) + strcpy(smpp_param[linkNo].remoteGTT, ""); + else + sprintf(smpp_param[linkNo].remoteGTT, "%s", info[9]); + + smpp_param[linkNo].local_ip = inet_addr(info[10]); + smpp_param[linkNo].remote_ip = inet_addr(info[11]); + smpp_param[linkNo].session_init_timer = atol(info[12]); + smpp_param[linkNo].enquire_link_timer = atol(info[13]); + smpp_param[linkNo].inactivity_timer = atol(info[14]); + smpp_param[linkNo].response_timer = atol(info[15]); + + if (strncmp(info[16], "--", 2) == 0) + strcpy(smpp_param[linkNo].service_number, ""); + else + sprintf(smpp_param[linkNo].service_number, "%s", info[16]); + + smpp_param[linkNo].localSSN = atoi(info[17]); + smpp_param[linkNo].remoteSSN = atoi(info[18]); + + if(ver[2] == 1) + if(smpp_param[linkNo].link_enable & 0x01) + smpp_param[linkNo].link_enable = 0x81; + /* + printf("link %d: link_enable=%d, link_type=%d; session_type=%d; sys_id=%s; password=%s; \ + system_type=%s; localGTT=%s; retmoteGTT=%s; local_ip=%s; remote ip=%s; \ + session init timer=%d; enquire link timer=%d; inactivity timer=%d; response timer=%d \ + remote service number: %s\n", + linkNo, smpp_param[linkNo].link_enable, smpp_param[linkNo].link_type, smpp_param[linkNo].session_type, smpp_param[linkNo].sys_id, smpp_param[linkNo].password, + smpp_param[linkNo].system_type, smpp_param[linkNo].localGTT, smpp_param[linkNo].remoteGTT, info[8], info[9], + smpp_param[linkNo].session_init_timer, smpp_param[linkNo].enquire_link_timer, smpp_param[linkNo].inactivity_timer, smpp_param[linkNo].response_timer, + smpp_param[linkNo].service_number + ); + */ + } + fclose(fp); + return TRUE; +} + +int smpp_writeParam() +{ + FILE *fp; + int i; + struct in_addr addr; + + if((fp = fopen(SMPP_CONF_FILE,"w")) == NULL) + return FAILURE; + + fprintf(fp,"#SMPP Config file (%s)\n",SMPP_MODULE_VERSION); + fprintf(fp,"#Copy this file to ./conf/smpp.conf to set global options\n"); + fprintf(fp,"#No lkEn lkType serverType sessionType sysID pwd sysType LGTT RGTT LIP RIP sessionTimer enqTimer inactTimer rspTimer ServiceNum localSSN remoteSSN\n"); + for(i=0; i< MAX_SMPP_LINK; i++) + { + fprintf(fp,"%d ", i); + fprintf(fp,"%d ", smpp_param[i].link_enable); + fprintf(fp,"%d ", smpp_param[i].link_type); + fprintf(fp,"%d ", smpp_param[i].server_type); + fprintf(fp,"%d ", smpp_param[i].session_type); + + if (smpp_param[i].sys_id[0] == 0) + strcpy(smpp_param[i].sys_id, "--"); + + fprintf(fp,"%s ", smpp_param[i].sys_id); + + if (smpp_param[i].password[0] == 0) + strcpy(smpp_param[i].password, "--"); + + fprintf(fp,"%s ", smpp_param[i].password); + + if (smpp_param[i].system_type[0] == 0) + fprintf(fp,"%s ", "--"); + else + fprintf(fp,"%s ", smpp_param[i].system_type); + + if (smpp_param[i].localGTT[0] == 0) + strcpy(smpp_param[i].localGTT, "--"); + fprintf(fp,"%s ", smpp_param[i].localGTT); + + if (smpp_param[i].remoteGTT[0] == 0) + strcpy(smpp_param[i].remoteGTT, "--"); + fprintf(fp,"%s ", smpp_param[i].remoteGTT); + + addr.s_addr = smpp_param[i].local_ip; + fprintf(fp,"%s ", inet_ntoa(addr)); + + addr.s_addr = smpp_param[i].remote_ip; + fprintf(fp,"%s ", inet_ntoa(addr)); + + fprintf(fp,"%u ", smpp_param[i].session_init_timer); + fprintf(fp,"%u ", smpp_param[i].enquire_link_timer); + fprintf(fp,"%u ", smpp_param[i].inactivity_timer); + fprintf(fp,"%u ", smpp_param[i].response_timer); + + if (smpp_param[i].service_number[0] == 0) + strcpy(smpp_param[i].service_number, "--"); + fprintf(fp, "%s ", smpp_param[i].service_number); + + fprintf(fp,"%d ", smpp_param[i].localSSN); + fprintf(fp,"%d\n", smpp_param[i].remoteSSN); + } + fclose(fp); + + return TRUE; +} + +void smpp_checkParam() +{ + if(smpp_param_flag) + { + smpp_writeParam(); + smpp_param_flag=0; + } +} + + +int smpp_enable_link() +{ + int i; + for (i=0; i= MAX_SMPP_LINK) + return -1; + pParam = &smpp_param[instance[0]]; + + switch(column) + { + case 2: //remote service number + if (datalen > 8) + return -1; + memset(pParam->service_number,0,8); + SET_OCTETSTRING(pParam->service_number, datalen); + break; + case 3: //link type + SET_INTEGER(pParam->link_type); + break; + case 4: //server type + SET_INTEGER(pParam->server_type); + break; + case 5: //session type + SET_INTEGER(pParam->session_type); + break; + case 6: //system id + if (datalen > SMPP_SYSID_LEN) + return -1; + memset(pParam->sys_id,0,SMPP_SYSID_LEN); + SET_OCTETSTRING(pParam->sys_id, datalen); + break; + case 7: //password + if (datalen > SMPP_PASSWD_LEN) + return -1; + memset(pParam->password,0,SMPP_PASSWD_LEN); + SET_OCTETSTRING(pParam->password, datalen); + break; + case 8: //system type + if (datalen > SMPP_SYSTYPE_LEN) + return -1; + memset(pParam->system_type,0,SMPP_SYSTYPE_LEN); + SET_OCTETSTRING(pParam->system_type, datalen); + break; + case 9: //local gtt + if (datalen > SMPP_GTT_LEN) + return -1; + memset(pParam->localGTT,0,SMPP_GTT_LEN); + SET_OCTETSTRING(pParam->localGTT, datalen); + break; + case 10: //remote gtt + if (datalen > SMPP_GTT_LEN) + return -1; + memset(pParam->remoteGTT,0,SMPP_GTT_LEN); + SET_OCTETSTRING(pParam->remoteGTT, datalen); + break; + case 11: //local ip + SET_IP(&pParam->local_ip); + break; + case 12: //remote ip + SET_IP(&pParam->remote_ip); + break; + case 13: //session init timer + SET_INTEGER(pParam->session_init_timer); + break; + case 14: // enquire link timer + SET_INTEGER(pParam->enquire_link_timer); + break; + case 15: //inactivity timer + SET_INTEGER(pParam->inactivity_timer); + break; + case 16: //response timer + SET_INTEGER(pParam->response_timer); + break; + case 17: + SET_INTEGER(pParam->localSSN); + break; + case 18: + SET_INTEGER(pParam->remoteSSN); + break; + case 19://enable/disable flag + { + u8 temp8; + SET_U8(temp8); + temp8 &= 0x01; + if(temp8 == 1)//enable + pParam->link_enable |= 0x01; + else + { + pParam->link_enable &= ~0x01; + init_link(instance[0]); + } + break; + } + case 20://delete + { + u8 temp8; + SET_U8(temp8); + if(temp8 == 6)//delete + { + pParam->link_enable = 0; + init_link(instance[0]); + } + break; + } + default: + break; + } + return datalen; +} + +int smpp_get_link(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + SMPP_PARAM *pParam; + + if (instance[0] >= MAX_SMPP_LINK) + return -1; + pParam = &smpp_param[instance[0]]; + switch(column) + { + case 1: //index + GET_INTEGER(instance[0]); + break; + case 2: //remote service number (LinkAlias) + if((datalen = strlen(pParam->service_number)) > 8) + datalen = 8; + GET_OCTETSTRING(pParam->service_number, datalen); + break; + case 3: //link type + GET_INTEGER(pParam->link_type); + break; + case 4: //server type + GET_INTEGER(pParam->server_type); + break; + case 5: //session type + GET_INTEGER(pParam->session_type); + break; + case 6: //system id + if((datalen = strlen(pParam->sys_id)) > SMPP_SYSID_LEN) + datalen = SMPP_SYSID_LEN; + GET_OCTETSTRING(pParam->sys_id, datalen); + break; + case 7: //password + if((datalen = strlen(pParam->password)) > SMPP_PASSWD_LEN) + datalen = SMPP_PASSWD_LEN; + GET_OCTETSTRING(pParam->password, datalen); + break; + case 8: //system type + if((datalen = strlen(pParam->system_type)) > SMPP_SYSTYPE_LEN) + datalen = SMPP_SYSTYPE_LEN; + GET_OCTETSTRING(pParam->system_type, datalen); + break; + case 9: //local gtt + if((datalen = strlen(pParam->localGTT)) > SMPP_GTT_LEN) + datalen = SMPP_GTT_LEN; + GET_OCTETSTRING(pParam->localGTT, datalen); + break; + case 10: //remote gtt + if((datalen = strlen(pParam->remoteGTT)) > SMPP_GTT_LEN) + datalen = SMPP_GTT_LEN; + GET_OCTETSTRING(pParam->remoteGTT, datalen); + break; + case 11: //local ip + GET_IP(&pParam->local_ip); + break; + case 12: //remote ip + GET_IP(&pParam->remote_ip); + break; + case 13: //session init timer + GET_INTEGER(pParam->session_init_timer); + break; + case 14: //enquire link timer + GET_INTEGER(pParam->enquire_link_timer); + break; + case 15: //inactivity timer + GET_INTEGER(pParam->inactivity_timer); + break; + case 16: //response timer + GET_INTEGER(pParam->response_timer); + break; + case 17: + GET_INTEGER(pParam->localSSN); + break; + case 18: + GET_INTEGER(pParam->remoteSSN); + break; + case 19: //enable flag + GET_U8(pParam->link_enable&0x01); + break; + case 20: //link enable + GET_U8(1); + break; + default: + break; + } + return datalen; +} +int smpp_get_system(u32 column, u32 *instance, u8 *pdata, u8 *vartype) +{ + int datalen = -1; + + GET_OCTETSTRING(" ",1); + return datalen; +} + +int smpp_set_system(u32 column, u32 *instance, u8 *pdata, u16 datalen) +{ + switch(column) + { + case 1: + switch (pdata[0]) + { + case 0: //reset + smpp_reset(); + break; + case 1: //load + smpp_loadParam(); + break; + case 2: //save + smpp_writeParam(); + break; + } + } + return datalen; +} + +static struct snmp_table_profile smpp_tables[] = { + /****** Parameter table ******/ + { + .name = "system", + .index.len = 13, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 2, 18, 2, 1},//1.3.6.1.4.1.1373.2.3.2.18.2.1 + .column = {0}, + .level = 0, + .get_instance = NULL, + .get_resp = smpp_get_system, + .set_resp = smpp_set_system + }, + { + .name = "smpp link", + .index.len = 14, + .index.oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 2, 18, 2, 2, 1},//1.3.6.1.4.1.1373.2.3.2.18.2.2.1 + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0}, + .level = 1, + .get_instance = smpp_getnext_link, + .get_resp = smpp_get_link, + .set_resp = smpp_set_link + }, +}; + +static struct snmp_register smpp_register = { + .name = "SMPP", + .prefix_len = 11, + .prefix_oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 2, 18}, + .num_of_table = sizeof(smpp_tables)/sizeof(struct snmp_table_profile), + .table = smpp_tables, + .default_get_resp = smpp_getMib, + .default_set_resp = smpp_setMib +}; + + +void smpp_mibInit() +{ + int i; +// DWORD oid[20] = SMPP_OID; + + for (i=0; i 0) { + //printf("Mysock.server_sock[%d]=%d.\n", i, Mysock.server_sock[i]); + len = recv(Mysock.server_sock[i], smpp_msg, sizeof(smpp_msg), 0); + if (len > 0) { +// printf("TCP link receive setup SMPP link.\n"); + if ((retcode = smpp_decode_setup(SMPP_TCP, i, 0, (SMPP_GENERAL *)smpp_msg, len)) != -1) { +// printf("[smpp] tcp link %d find smpp link %d\n", i, retcode); + } + } + else if(len == 0 ) + { + close(Mysock.server_sock[i]); + Mysock.server_sock[i] = 0; + } + } + + // i = physical smpp link. + if (Mysock.Sockets[i] > 0) + { +/* len = recv(Mysock.Sockets[i], smpp_msg, sizeof(smpp_msg), 0); + if (len > 0) + { + printf("[TCP received packets]linkNo = %d, len = %d\n", i, len); + retcode = smpp_decode_msg(i, (SMPP_GENERAL *)smpp_msg, len); + }*/ + if(smpp_msg_buf_len[i] < 4) //recv command_length in smpp msg + { + len = recv(Mysock.Sockets[i], smpp_msg_buf[i]+smpp_msg_buf_len[i], 4-smpp_msg_buf_len[i],MSG_NOSIGNAL|MSG_DONTWAIT); + if (len == -1 && errno != EAGAIN) + { + sprintf(temp_buf,"SMPP receive 4 BYTE from tcp socket error:%s",strerror(errno)); + smpp_send_error(temp_buf); + continue; + } + else if(len >0) + { + smpp_msg_buf_len[i] += len; + } + } + if(smpp_msg_buf_len[i] >= 4) //recv remain of smpp msg + { + cmd_len = bcdtou32(smpp_msg_buf[i],4); + if ( cmd_len > MAX_PACKET_SIZE ) + { + recv(Mysock.Sockets[i], temp_buf, 4096,MSG_NOSIGNAL|MSG_DONTWAIT); + sprintf(temp_buf,"SMPP MSG CMD_LEN Error,Clear TCP Socket Buffer."); + smpp_send_error(temp_buf); + smpp_msg_buf_len[i] = 0; + continue; + } + if (smpp_msg_buf_len[i]0) + { + smpp_msg_buf_len[i] += len; + if(smpp_msg_buf_len[i] >= cmd_len) + { + //printf("[TCP received packets]linkNo = %d, len = %d\n", i, cmd_len); + retcode = smpp_decode_msg(i, (SMPP_GENERAL *)smpp_msg_buf[i], cmd_len); + smpp_msg_buf_len[i] = 0; + } + } + } + } + /*else if (len > 0) + { + cmd_len = bcdtou32(smpp_msg,4); + if ( cmd_len > sizeof(smpp_msg) ) + { + recv(Mysock.Sockets[i], temp_buf, 4096,MSG_NOSIGNAL|MSG_DONTWAIT); + sprintf(temp_buf,"SMPP MSG CMD_LEN Error,Clear TCP Socket Buffer."); + smpp_send_error(temp_buf); + fp = fopen("smpp_log","a"); + if (fp != NULL) + { + fprintf(fp,"%s\n",temp_buf); + fclose(fp); + } + continue; + } + else + { + len = recv(Mysock.Sockets[i], smpp_msg+4, cmd_len-4 ,MSG_NOSIGNAL|MSG_DONTWAIT); + if (len == -1) + { + sprintf(temp_buf,"SMPP receive cmd_len(%d)-4 BYTE from tcp socket error:%s",cmd_len,strerror(errno)); + smpp_send_error(temp_buf); + fp = fopen("smpp_log","a"); + if (fp != NULL) + { + fprintf(fp,"%s\n",temp_buf); + fclose(fp); + } + continue; + } + else + { + printf("[TCP received packets]linkNo = %d, len = %d\n", i, cmd_len); + retcode = smpp_decode_msg(i, (SMPP_GENERAL *)smpp_msg, cmd_len); + } + } + }*/ + } + } + + len = sizeof(remote_addr); + bzero((char *)&remote_addr, len); + newsock = accept(Mysock.DaemonSock, (struct sockaddr *)&remote_addr, (socklen_t *)&len); + if (newsock == -1) return; + ioctl(newsock, FIONBIO, &flag); + for (i=0; i 0) { + //printf("Mysock.server_sock[%d] = %d > 0, CONTINUE.\n", i, Mysock.server_sock[i]); + continue; + } + else { + Mysock.server_sock[i] = newsock; + Mysock.remote_ip[i] = remote_addr.sin_addr.s_addr; +// printf("link %d accept %d.\n", i, newsock); + return; + } + } + close(newsock); + return; +} + +//void smpp_rvMsgOverSCCP(BYTE sccp_usertype) +//{ +// int i, linkNo; +// SCLC_MSG sclcMsg; +// +// if (sclc_receive(&sclcMsg, sccp_usertype) != FALSE) { +// /* +// if (sccp_usertype == SMPP_PPS_USERTYPE) +// printf("receive to PPS sclc message.\n"); +// else if (sccp_usertype == SMPP_SMSC_USERTYPE) +// printf("receive to SMSC sclc message.\n"); +// */ +// for (i=0; ipdu.bind_transmitter.head.command_id); + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { +// if(command_id!=ENQUIRE_LINK && command_id!=ENQUIRE_LINK_RESP) + { + smpp_command_id_to_string(comm_str, ntohl(pMsg->pdu.bind_transmitter.head.command_id)); + sprintf(debugBuf, "\nSMPP==> %s\tlink: %d\n", comm_str, linkNo); + smpp_send_ascout(debugBuf); + } + } + #endif + + if (smpp_param[linkNo].link_type == SMPP_UDP) + { + offset = 2; + tLen = tLen + offset; + smpp_msg[0] = dst_ref[linkNo]; + smpp_msg[1] = src_ref[linkNo]; + } + switch (event_id) + { + case SubmitSM: + /* mandatory parameter. */ + pSubmitSM = (PDU_SUBMIT_SM *)&pMsg->pdu; + memcpy(smpp_msg+offset, pSubmitSM, 16); + len = strlen(pSubmitSM->service_type); + memcpy(smpp_msg+tLen, pSubmitSM->service_type, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitSM->source_addr_ton; + *(smpp_msg+tLen++) = pSubmitSM->source_addr_npi; + len = strlen(pSubmitSM->source_addr); + memcpy(smpp_msg+tLen, pSubmitSM->source_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitSM->dest_addr_ton; + *(smpp_msg+tLen++) = pSubmitSM->dest_addr_npi; + len = strlen(pSubmitSM->destination_addr); + memcpy(smpp_msg+tLen, pSubmitSM->destination_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitSM->esm_class; + *(smpp_msg+tLen++) = pSubmitSM->protocol_id; + *(smpp_msg+tLen++) = pSubmitSM->priority_flag; + len = strlen(pSubmitSM->schedule_delivery_time); + if (len > 0) { len = 16; } + memcpy(smpp_msg+tLen, pSubmitSM->schedule_delivery_time, len+1); + tLen = tLen+len+1; + len = strlen(pSubmitSM->validity_period); + if (len > 0) { len = 16; } + memcpy(smpp_msg+tLen, pSubmitSM->validity_period, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitSM->registered_delivery; + *(smpp_msg+tLen++) = pSubmitSM->replace_if_present_flag; + *(smpp_msg+tLen++) = pSubmitSM->data_coding; + *(smpp_msg+tLen++) = pSubmitSM->sm_default_msg_id; +// len = strlen(pSubmitSM->short_message); + len = pSubmitSM->sm_length; + *(smpp_msg+tLen++) = len; + if (len > 0) + { + memcpy(smpp_msg+tLen, pSubmitSM->short_message, len); + tLen = tLen+len; + } + /* optional paramter */ + optionalParamFlag = pMsg->optional_param_flag1; + #ifdef SMPP_PRINT_SCREEN +// printf("param_flag in SUBMIT SM = 0x%08x\n", optionalParamFlag); + #endif /* endif ifdef SMPP_PRINT_SCREEN */ + if ((optionalParamFlag&0x0001) == 0x0001) + { + smpp_addTLV(smpp_msg+tLen, USER_MESSAGE_REFERENCE, + (BYTE *)&(pSubmitSM->user_message_reference), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0002) == 0x0002) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_PORT, + (BYTE *)&(pSubmitSM->source_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0004) == 0x0004) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_ADDR_SUBUNIT, + (BYTE *)&(pSubmitSM->source_addr_subunit), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, DESTINATION_PORT, + (BYTE *)&(pSubmitSM->destination_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0010) == 0x0010) + { + smpp_addTLV(smpp_msg+tLen, DEST_ADDR_SUBUNIT, + (BYTE *)&(pSubmitSM->dest_addr_subunit), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0020) == 0x0020) + { + smpp_addTLV(smpp_msg+tLen, SAR_MSG_REF_NUM, + (BYTE *)&(pSubmitSM->sar_msg_ref_num), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0040) == 0x0040) + { + smpp_addTLV(smpp_msg+tLen, SAR_TOTAL_SEGMENTS, + (BYTE *)&(pSubmitSM->sar_total_segments), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, SAR_SEGMENT_SEQNUM, + (BYTE *)&(pSubmitSM->sar_segment_seqnum), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0100) == 0x0100) + { + smpp_addTLV(smpp_msg+tLen, MORE_MESSAGES_TO_SEND, + (BYTE *)&(pSubmitSM->more_messages_to_send), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0200) == 0x0200) + { + smpp_addTLV(smpp_msg+tLen, PAYLOAD_TYPE, + (BYTE *)&(pSubmitSM->payload_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0400) == 0x0400) + { + us_valueLen = strlen(pSubmitSM->message_payload); + smpp_addTLV(smpp_msg+tLen, MESSAGE_PAYLOAD, + (BYTE *)&(pSubmitSM->message_payload), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x0800) == 0x0800) + { + smpp_addTLV(smpp_msg+tLen, PRIVACY_INDICATOR, + (BYTE *)&(pSubmitSM->privacy_indicator), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x1000) == 0x1000) + { + us_valueLen = strlen(pSubmitSM->callback_num); + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM, + (BYTE *)&(pSubmitSM->callback_num), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x2000) == 0x2000) + { + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM_PRES_IND, + (BYTE *)&(pSubmitSM->callback_num_pres_ind), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x4000) == 0x4000) + { + us_valueLen = strlen(pSubmitSM->callback_num_atag); + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM_ATAG, + (BYTE *)&(pSubmitSM->callback_num_atag), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x8000) == 0x8000) + { + us_valueLen = strlen(pSubmitSM->source_subaddress); + smpp_addTLV(smpp_msg+tLen, SOURCE_SUBADDRESS, + (BYTE *)&(pSubmitSM->source_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x00010000) == 0x00010000) + { + us_valueLen = strlen(pSubmitSM->dest_subaddress); + smpp_addTLV(smpp_msg+tLen, DEST_SUBADDRESS, + (BYTE *)&(pSubmitSM->dest_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x00020000) == 0x00020000) + { + smpp_addTLV(smpp_msg+tLen, USER_RESPONSE_CODE, + (BYTE *)&(pSubmitSM->user_response_code), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00040000) == 0x00040000) + { + smpp_addTLV(smpp_msg+tLen, DISPLAY_TIME, + (BYTE *)&(pSubmitSM->display_time), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00080000) == 0x00080000) + { + smpp_addTLV(smpp_msg+tLen, SMS_SIGNAL, + (BYTE *)&(pSubmitSM->sms_signal), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x00100000) == 0x00100000) + { + smpp_addTLV(smpp_msg+tLen, MS_VALIDITY, + (BYTE *)&(pSubmitSM->ms_validity), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00200000) == 0x00200000) + { + smpp_addTLV(smpp_msg+tLen, MS_MSG_WAIT_FACILITIES, + (BYTE *)&(pSubmitSM->ms_msg_wait_facilities), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00400000) == 0x00400000) + { + smpp_addTLV(smpp_msg+tLen, NUMBER_OF_MESSAGES, + (BYTE *)&(pSubmitSM->number_of_messages), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00800000) == 0x00800000) + { + smpp_addTLV(smpp_msg+tLen, ALERT_ON_MESSAGE_DELIVERY, + (BYTE *)&(pSubmitSM->alert_on_message_delivery), 1); + tLen = tLen+4; + } + if ((optionalParamFlag&0x01000000) == 0x01000000) + { + smpp_addTLV(smpp_msg+tLen, LANGUAGE_INDICATOR, + (BYTE *)&(pSubmitSM->language_indicator), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x02000000) == 0x02000000) + { + smpp_addTLV(smpp_msg+tLen, ITS_REPLY_TYPE, + (BYTE *)&(pSubmitSM->its_reply_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x04000000) == 0x04000000) + { + smpp_addTLV(smpp_msg+tLen, ITS_SESSION_INFO, + (BYTE *)pSubmitSM->its_session_info, 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x08000000) == 0x08000000) + { + smpp_addTLV(smpp_msg+tLen, USSD_SERVICE_OP, + (BYTE *)&(pSubmitSM->ussd_service_op), 1); + tLen = tLen+5; + } + /* all the other param_flag values reserved. */ + /* command_length */ + pSubmitSM->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pSubmitSM->head.command_length, 4); + break; + case SubmitSMResp: + pSubmitSMResp = (PDU_SUBMIT_SM_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pSubmitSMResp, 16); + len = strlen(pSubmitSMResp->message_id); + memcpy(smpp_msg+tLen, pSubmitSMResp->message_id, len+1); + tLen = tLen+len+1; + pSubmitSMResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pSubmitSMResp->head.command_length, 4); + break; + case SubmitMulti: + pSubmitMulti = (PDU_SUBMIT_MULTI *)&pMsg->pdu; + memcpy(smpp_msg+offset, pSubmitMulti, 16); + /* mandatory parameters. */ + len = strlen(pSubmitMulti->service_type); + memcpy(smpp_msg+tLen, pSubmitMulti->service_type, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitMulti->source_addr_ton; + *(smpp_msg+tLen++) = pSubmitMulti->source_addr_npi; + len = strlen(pSubmitMulti->source_addr); + memcpy(smpp_msg+tLen, pSubmitMulti->source_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitMulti->number_of_dests; + for (i=0; inumber_of_dests; i++) + { + switch(pSubmitMulti->dest_address[i].dest_flag) + { + case 1: //SME address + *(smpp_msg+tLen++) = pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_ton; + *(smpp_msg+tLen++) = pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_npi; + len = strlen(pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.destination_addr); + memcpy(smpp_msg+tLen, + pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.destination_addr, len+1); + tLen = tLen+len+1; + break; + case 2: //Distribution List Name + len = strlen(pSubmitMulti->dest_address[i].dest_addr.dl_name.dl_name); + memcpy(smpp_msg+tLen, + pSubmitMulti->dest_address[i].dest_addr.dl_name.dl_name, len+1); + tLen = tLen+len+1; + break; + default: + break; + } + } + *(smpp_msg+tLen++) = pSubmitMulti->esm_class; + *(smpp_msg+tLen++) = pSubmitMulti->protocol_id; + *(smpp_msg+tLen++) = pSubmitMulti->priority_flag; + len = strlen(pSubmitMulti->schedule_delivery_time); + if (len > 0) { len = 16; } + memcpy(smpp_msg+tLen, pSubmitMulti->schedule_delivery_time, len+1); + tLen = tLen+len+1; + len = strlen(pSubmitMulti->validity_period); + if (len > 0) { len = 16; } + memcpy(smpp_msg+tLen, pSubmitMulti->validity_period, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitMulti->registered_delivery; + *(smpp_msg+tLen++) = pSubmitMulti->replace_if_present_flag; + *(smpp_msg+tLen++) = pSubmitMulti->data_coding; + *(smpp_msg+tLen++) = pSubmitMulti->sm_default_msg_id; + *(smpp_msg+tLen++) = pSubmitMulti->sm_length; +// len = strlen(pSubmitMulti->short_message); + len = pSubmitMulti->sm_length; + memcpy(smpp_msg+tLen, pSubmitMulti->short_message, len+1); + tLen = tLen+len+1; + /* optional parameters. */ + optionalParamFlag = pMsg->optional_param_flag1; + #ifdef SMPP_PRINT_SCREEN +// printf("param_flag in SUBMIT MULTI = 0x%08x\n", optionalParamFlag); + #endif /* endif ifdef SMPP_PRINT_SCREEN */ + if ((optionalParamFlag&0x0001) == 0x0001) + { + smpp_addTLV(smpp_msg+tLen, USER_MESSAGE_REFERENCE, + (BYTE *)&(pSubmitMulti->user_message_reference), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0002) == 0x0002) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_PORT, + (BYTE *)&(pSubmitMulti->source_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0004) == 0x0004) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_ADDR_SUBUNIT, + (BYTE *)&(pSubmitMulti->source_addr_subunit), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, DESTINATION_PORT, + (BYTE *)&(pSubmitMulti->destination_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0010) == 0x0010) + { + smpp_addTLV(smpp_msg+tLen, DEST_ADDR_SUBUNIT, + (BYTE *)&(pSubmitMulti->dest_addr_subunit), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0020) == 0x0020) + { + smpp_addTLV(smpp_msg+tLen, SAR_MSG_REF_NUM, + (BYTE *)&(pSubmitMulti->sar_msg_ref_num), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0040) == 0x0040) + { + smpp_addTLV(smpp_msg+tLen, SAR_TOTAL_SEGMENTS, + (BYTE *)&(pSubmitMulti->sar_total_segments), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, SAR_SEGMENT_SEQNUM, + (BYTE *)&(pSubmitMulti->sar_segment_seqnum), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0100) == 0x0100) + { + smpp_addTLV(smpp_msg+tLen, PAYLOAD_TYPE, + (BYTE *)&(pSubmitMulti->payload_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0200) == 0x0200) + { + us_valueLen = strlen(pSubmitMulti->message_payload); + smpp_addTLV(smpp_msg+tLen, MESSAGE_PAYLOAD, + (BYTE *)&(pSubmitMulti->message_payload), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x0400) == 0x0400) + { + smpp_addTLV(smpp_msg+tLen, PRIVACY_INDICATOR, + (BYTE *)&(pSubmitMulti->privacy_indicator), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0800) == 0x0800) + { + us_valueLen = strlen(pSubmitMulti->callback_num); + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM, + (BYTE *)&(pSubmitMulti->callback_num), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x1000) == 0x1000) + { + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM_PRES_IND, + (BYTE *)&(pSubmitMulti->callback_num_pres_ind), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x2000) == 0x2000) + { + us_valueLen = strlen(pSubmitMulti->callback_num_atag); + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM_ATAG, + (BYTE *)&(pSubmitMulti->callback_num_atag), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x4000) == 0x4000) + { + us_valueLen = strlen(pSubmitMulti->source_subaddress); + smpp_addTLV(smpp_msg+tLen, SOURCE_SUBADDRESS, + (BYTE *)&(pSubmitMulti->source_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x8000) == 0x8000) + { + us_valueLen = strlen(pSubmitMulti->dest_subaddress); + smpp_addTLV(smpp_msg+tLen, DEST_SUBADDRESS, + (BYTE *)&(pSubmitMulti->dest_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x00010000) == 0x00010000) + { + smpp_addTLV(smpp_msg+tLen, DISPLAY_TIME, + (BYTE *)&(pSubmitMulti->display_time), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00020000) == 0x00020000) + { + smpp_addTLV(smpp_msg+tLen, SMS_SIGNAL, + (BYTE *)&(pSubmitMulti->sms_signal), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x00040000) == 0x00040000) + { + smpp_addTLV(smpp_msg+tLen, MS_VALIDITY, + (BYTE *)&(pSubmitMulti->ms_validity), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00080000) == 0x00080000) + { + smpp_addTLV(smpp_msg+tLen, MS_MSG_WAIT_FACILITIES, + (BYTE *)&(pSubmitMulti->ms_msg_wait_facilities), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00100000) == 0x00100000) + { + smpp_addTLV(smpp_msg+tLen, ALERT_ON_MESSAGE_DELIVERY, + (BYTE *)&(pSubmitMulti->alert_on_message_delivery), 1); + tLen = tLen+4; + } + if ((optionalParamFlag&0x00200000) == 0x00200000) + { + smpp_addTLV(smpp_msg+tLen, LANGUAGE_INDICATOR, + (BYTE *)&(pSubmitMulti->language_indicator), 1); + tLen = tLen+5; + } + /* all the other param_flag values reserved. */ + /* command_length */ + pSubmitMulti->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pSubmitMulti->head.command_length, 4); + break; + case SubmitMultiResp: + pSubmitMultiResp = (PDU_SUBMIT_MULTI_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pSubmitMultiResp, 16); + /* body */ + len = strlen(pSubmitMultiResp->message_id); + memcpy(smpp_msg+tLen, pSubmitMultiResp->message_id, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pSubmitMultiResp->no_unsuccess; + num = pSubmitMultiResp->no_unsuccess; + for (i=0; iunsuccess_sme[i].dest_addr_ton; + *(smpp_msg+tLen++) = pSubmitMultiResp->unsuccess_sme[i].dest_addr_npi; + len = strlen(pSubmitMultiResp->unsuccess_sme[i].destination_addr); + memcpy(smpp_msg+tLen, pSubmitMultiResp->unsuccess_sme[i].destination_addr, len+1); + tLen = tLen+len+1; + memcpy(smpp_msg+tLen, &(pSubmitMultiResp->unsuccess_sme[i].error_status_code), 4); + tLen = tLen+4; + } + /* command_length */ + pSubmitMultiResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pSubmitMultiResp->head.command_length, 4); + break; + case DeliverSM: + pDeliverSM = (PDU_DELIVER_SM *)&pMsg->pdu; + memcpy(smpp_msg+offset, pDeliverSM, 16); + len = strlen(pDeliverSM->service_type); + memcpy(smpp_msg+tLen, pDeliverSM->service_type, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pDeliverSM->source_addr_ton; + *(smpp_msg+tLen++) = pDeliverSM->source_addr_npi; + len = strlen(pDeliverSM->source_addr); + memcpy(smpp_msg+tLen, pDeliverSM->source_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pDeliverSM->dest_addr_ton; + *(smpp_msg+tLen++) = pDeliverSM->dest_addr_npi; + len = strlen(pDeliverSM->destination_addr); + memcpy(smpp_msg+tLen, pDeliverSM->destination_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pDeliverSM->esm_class; + *(smpp_msg+tLen++) = pDeliverSM->protocol_id; + *(smpp_msg+tLen++) = pDeliverSM->priority_flag; + *(smpp_msg+tLen++) = pDeliverSM->schedule_delivery_time; + *(smpp_msg+tLen++) = pDeliverSM->validity_period; + *(smpp_msg+tLen++) = pDeliverSM->registered_delivery; + *(smpp_msg+tLen++) = pDeliverSM->replace_if_present_flag; + *(smpp_msg+tLen++) = pDeliverSM->data_coding; + *(smpp_msg+tLen++) = pDeliverSM->sm_default_msg_id; +// len = strlen(pDeliverSM->short_message); + len = pDeliverSM->sm_length; + *(smpp_msg+tLen++) = len; + memcpy(smpp_msg+tLen, pDeliverSM->short_message, len); + tLen = tLen+len; + /* optional parameters */ + optionalParamFlag = pMsg->optional_param_flag1; + #ifdef SMPP_PRINT_SCREEN +// printf("param_flag in DELIVER SM = 0x%08x\n", optionalParamFlag); + #endif /* endif ifdef SMPP_PRINT_SCREEN */ + if ((optionalParamFlag&0x0001) == 0x0001) + { + smpp_addTLV(smpp_msg+tLen, USER_MESSAGE_REFERENCE, + (BYTE *)&(pDeliverSM->user_message_reference), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0002) == 0x0002) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_PORT, + (BYTE *)&(pDeliverSM->source_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0004) == 0x0004) + { + smpp_addTLV(smpp_msg+tLen, DESTINATION_PORT, + (BYTE *)&(pDeliverSM->destination_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, SAR_MSG_REF_NUM, + (BYTE *)&(pDeliverSM->sar_msg_ref_num), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0010) == 0x0010) + { + smpp_addTLV(smpp_msg+tLen, SAR_TOTAL_SEGMENTS, + (BYTE *)&(pDeliverSM->sar_total_segments), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0020) == 0x0020) + { + smpp_addTLV(smpp_msg+tLen, SAR_SEGMENT_SEQNUM, + (BYTE *)&(pDeliverSM->sar_segment_seqnum), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0040) == 0x0040) + { + smpp_addTLV(smpp_msg+tLen, USER_RESPONSE_CODE, + (BYTE *)&(pDeliverSM->user_response_code), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, PRIVACY_INDICATOR, + (BYTE *)&(pDeliverSM->privacy_indicator), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0100) == 0x0100) + { + smpp_addTLV(smpp_msg+tLen, PAYLOAD_TYPE, + (BYTE *)&(pDeliverSM->payload_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0200) == 0x0200) { + us_valueLen = strlen(pDeliverSM->message_payload); + smpp_addTLV(smpp_msg+tLen, MESSAGE_PAYLOAD, + (BYTE *)&(pDeliverSM->message_payload), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x0400) == 0x0400) + { + us_valueLen = strlen(pDeliverSM->callback_num); + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM, + (BYTE *)&(pDeliverSM->callback_num), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x0800) == 0x0800) + { + us_valueLen = strlen(pDeliverSM->source_subaddress); + smpp_addTLV(smpp_msg+tLen, SOURCE_SUBADDRESS, + (BYTE *)&(pDeliverSM->source_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x1000) == 0x1000) + { + us_valueLen = strlen(pDeliverSM->dest_subaddress); + smpp_addTLV(smpp_msg+tLen, DEST_SUBADDRESS, + (BYTE *)&(pDeliverSM->dest_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x2000) == 0x2000) + { + smpp_addTLV(smpp_msg+tLen, LANGUAGE_INDICATOR, + (BYTE *)&(pDeliverSM->language_indicator), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x4000) == 0x4000) + { + smpp_addTLV(smpp_msg+tLen, ITS_SESSION_INFO, + (BYTE *)pDeliverSM->its_session_info, 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x8000) == 0x8000) + { + us_valueLen = strlen(pDeliverSM->network_error_code); + smpp_addTLV(smpp_msg+tLen, NETWORK_ERROR_CODE, + (BYTE *)&(pDeliverSM->network_error_code), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x00010000) == 0x00010000) + { + smpp_addTLV(smpp_msg+tLen, MESSAGE_STATE, + (BYTE *)&(pDeliverSM->message_state), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00020000) == 0x00020000) + { + us_valueLen = strlen(pDeliverSM->receipted_message_id); + smpp_addTLV(smpp_msg+tLen, RECEIPTED_MESSAGE_ID, + (BYTE *)&(pDeliverSM->receipted_message_id), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x00040000) == 0x00040000) + { + smpp_addTLV(smpp_msg+tLen, USSD_SERVICE_OP, + (BYTE *)&(pDeliverSM->ussd_service_op), 1); + tLen = tLen+5; + } + /* all the other param_flag values reserved. */ + /* command_length */ + pDeliverSM->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pDeliverSM->head.command_length, 4); + break; + case DeliverSMResp: + pDeliverSMResp = (PDU_DELIVER_SM_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pDeliverSMResp, 16); + *(smpp_msg+tLen++) = pDeliverSMResp->message_id; + pDeliverSMResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pDeliverSMResp->head.command_length, 4); + break; + case DataSM: + pDataSM = (PDU_DATA_SM *)&pMsg->pdu; + memcpy(smpp_msg+offset, pDataSM, 16); + /* mandatory parameter. */ + len = strlen(pDataSM->service_type); + memcpy(smpp_msg+tLen, pDataSM->service_type, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pDataSM->source_addr_ton; + *(smpp_msg+tLen++) = pDataSM->source_addr_npi; + len = strlen(pDataSM->source_addr); + memcpy(smpp_msg+tLen, pDataSM->source_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pDataSM->dest_addr_ton; + *(smpp_msg+tLen++) = pDataSM->dest_addr_npi; + len = strlen(pDataSM->destination_addr); + memcpy(smpp_msg+tLen, pDataSM->destination_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pDataSM->esm_class; + *(smpp_msg+tLen++) = pDataSM->registered_delivery; + *(smpp_msg+tLen++) = pDataSM->data_coding; + /* Optional parameter */ + optionalParamFlag = pMsg->optional_param_flag1; + #ifdef SMPP_PRINT_SCREEN +// printf("optional_param_flag1 in DATA SM = 0x%08x\n", optionalParamFlag); + #endif /* endif ifdef SMPP_PRINT_SCREEN */ + if ((optionalParamFlag&0x0001) == 0x0001) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_PORT, + (BYTE *)&(pDataSM->source_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0002) == 0x0002) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_ADDR_SUBUNIT, + (BYTE *)&(pDataSM->source_addr_subunit), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0004) == 0x0004) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_NETWORK_TYPE, + (BYTE *)&(pDataSM->source_network_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_BEARER_TYPE, + (BYTE *)&(pDataSM->source_bearer_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0010) == 0x0010) + { + smpp_addTLV(smpp_msg+tLen, SOURCE_TELEMATICS_ID, + (BYTE *)&(pDataSM->source_telematics_id), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0020) == 0x0020) + { + smpp_addTLV(smpp_msg+tLen, DESTINATION_PORT, + (BYTE *)&(pDataSM->destination_port), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0040) == 0x0040) + { + smpp_addTLV(smpp_msg+tLen, DEST_ADDR_SUBUNIT, + (BYTE *)&(pDataSM->dest_addr_subunit), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0080) == 0x0080) + { + smpp_addTLV(smpp_msg+tLen, DEST_NETWORK_TYPE, + (BYTE *)&(pDataSM->dest_network_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0100) == 0x0100) + { + smpp_addTLV(smpp_msg+tLen, DEST_BEARER_TYPE, + (BYTE *)&(pDataSM->dest_bearer_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0200) == 0x0200) + { + smpp_addTLV(smpp_msg+tLen, DEST_TELEMATICS_ID, + (BYTE *)&(pDataSM->dest_telematics_id), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0400) == 0x0400) + { + smpp_addTLV(smpp_msg+tLen, SAR_MSG_REF_NUM, + (BYTE *)&(pDataSM->sar_msg_ref_num), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x0800) == 0x0800) + { + smpp_addTLV(smpp_msg+tLen, SAR_TOTAL_SEGMENTS, + (BYTE *)&(pDataSM->sar_total_segments), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x1000) == 0x1000) + { + smpp_addTLV(smpp_msg+tLen, SAR_SEGMENT_SEQNUM, + (BYTE *)&(pDataSM->sar_segment_seqnum), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x2000) == 0x2000) + { + smpp_addTLV(smpp_msg+tLen, MORE_MESSAGES_TO_SEND, + (BYTE *)&(pDataSM->more_messages_to_send), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x4000) == 0x4000) + { + smpp_addTLV(smpp_msg+tLen, QOS_TIME_TO_LIVE, + (BYTE *)&(pDataSM->qos_time_to_live), 4); + tLen = tLen+8; + } + if ((optionalParamFlag&0x8000) == 0x8000) + { + smpp_addTLV(smpp_msg+tLen, PAYLOAD_TYPE, + (BYTE *)&(pDataSM->payload_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00010000) == 0x00010000) + { + us_valueLen = strlen(pDataSM->message_payload); + smpp_addTLV(smpp_msg+tLen, MESSAGE_PAYLOAD, + (BYTE *)&(pDataSM->message_payload), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x00020000) == 0x00020000) + { + smpp_addTLV(smpp_msg+tLen, SET_DPF, + (BYTE *)&(pDataSM->set_dpf), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00040000) == 0x00040000) + { + us_valueLen = strlen(pDataSM->receipted_message_id); + smpp_addTLV(smpp_msg+tLen, RECEIPTED_MESSAGE_ID, + (BYTE *)&(pDataSM->receipted_message_id), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x00080000) == 0x00080000) + { + smpp_addTLV(smpp_msg+tLen, MESSAGE_STATE, + (BYTE *)&(pDataSM->message_state), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00100000) == 0x00100000) + { + smpp_addTLV(smpp_msg+tLen, NETWORK_ERROR_CODE, + (BYTE *)&(pDataSM->network_error_code), 3); + tLen = tLen+7; + } + if ((optionalParamFlag&0x00200000) == 0x00200000) + { + smpp_addTLV(smpp_msg+tLen, USER_MESSAGE_REFERENCE, + (BYTE *)&(pDataSM->user_message_reference), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x00400000) == 0x00400000) + { + smpp_addTLV(smpp_msg+tLen, PRIVACY_INDICATOR, + (BYTE *)&(pDataSM->privacy_indicator), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x00800000) == 0x00800000) + { + us_valueLen = strlen(pDataSM->callback_num); + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM, + (BYTE *)&(pDataSM->callback_num), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x01000000) == 0x01000000) + { + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM_PRES_IND, + (BYTE *)&(pDataSM->callback_num_pres_ind), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x02000000) == 0x02000000) + { + us_valueLen = strlen(pDataSM->callback_num_atag); + smpp_addTLV(smpp_msg+tLen, CALLBACK_NUM_ATAG, + (BYTE *)&(pDataSM->callback_num_atag), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x04000000) == 0x04000000) + { + us_valueLen = strlen(pDataSM->source_subaddress); + smpp_addTLV(smpp_msg+tLen, SOURCE_SUBADDRESS, + (BYTE *)&(pDataSM->source_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x08000000) == 0x08000000) + { + us_valueLen = strlen(pDataSM->dest_subaddress); +// printf("dest subaddress len = %d\n", us_valueLen); + smpp_addTLV(smpp_msg+tLen, DEST_SUBADDRESS, + (BYTE *)&(pDataSM->dest_subaddress), us_valueLen); + tLen = tLen+4+us_valueLen; + } + if ((optionalParamFlag&0x10000000) == 0x10000000) + { + smpp_addTLV(smpp_msg+tLen, USER_RESPONSE_CODE, + (BYTE *)&(pDataSM->user_response_code), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x20000000) == 0x20000000) + { + smpp_addTLV(smpp_msg+tLen, DISPLAY_TIME, + (BYTE *)&(pDataSM->display_time), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x40000000) == 0x40000000) + { + smpp_addTLV(smpp_msg+tLen, SMS_SIGNAL, + (BYTE *)&(pDataSM->sms_signal), 2); + tLen = tLen+6; + } + if ((optionalParamFlag&0x80000000) == 0x80000000) + { + smpp_addTLV(smpp_msg+tLen, MS_VALIDITY, + (BYTE *)&(pDataSM->ms_validity), 1); + tLen = tLen+5; + } + optionalParamFlag = pMsg->optional_param_flag2; + #ifdef SMPP_PRINT_SCREEN +// printf("optional_param_flag2 in DATA SM = 0x%08x\n", optionalParamFlag); + #endif /* endif ifdef SMPP_PRINT_SCREEN */ + if ((optionalParamFlag&0x0001) == 0x0001) + { + smpp_addTLV(smpp_msg+tLen, MS_MSG_WAIT_FACILITIES, + (BYTE *)&(pDataSM->ms_msg_wait_facilities), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0002) == 0x0002) + { + smpp_addTLV(smpp_msg+tLen, NUMBER_OF_MESSAGES, + (BYTE *)&(pDataSM->number_of_messages), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0004) == 0x0004) + { + smpp_addTLV(smpp_msg+tLen, ALERT_ON_MESSAGE_DELIVERY, + (BYTE *)&(pDataSM->alert_on_message_delivery), 1); + tLen = tLen+4; + } + if ((optionalParamFlag&0x0008) == 0x0008) + { + smpp_addTLV(smpp_msg+tLen, LANGUAGE_INDICATOR, + (BYTE *)&(pDataSM->language_indicator), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0010) == 0x0010) + { + smpp_addTLV(smpp_msg+tLen, ITS_REPLY_TYPE, + (BYTE *)&(pDataSM->its_reply_type), 1); + tLen = tLen+5; + } + if ((optionalParamFlag&0x0020) == 0x0020) + { + smpp_addTLV(smpp_msg+tLen, ITS_SESSION_INFO, + (BYTE *)pDataSM->its_session_info, 2); + tLen = tLen+6; + } + /* all the other param_flag values reserved. */ + /* command_length */ + pDataSM->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pDataSM->head.command_length, 4); + break; + case DataSMResp: + pDataSMResp = (PDU_DATA_SM_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pDataSMResp, 16); + len = strlen(pDataSMResp->message_id); + memcpy(smpp_msg+tLen, pDataSMResp->message_id, len+1); + tLen = tLen+len+1; + pDataSMResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pDataSMResp->head.command_length, 4); + break; + case QuerySM: + pQuerySM = (PDU_QUERY_SM *)&pMsg->pdu; + memcpy(smpp_msg+offset, pQuerySM, 16); + /* mandatory parameter. */ + len = strlen(pQuerySM->message_id); + memcpy(smpp_msg+tLen, pQuerySM->message_id, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pQuerySM->source_addr_ton; + *(smpp_msg+tLen++) = pQuerySM->source_addr_npi; + len = strlen(pQuerySM->source_addr); + memcpy(smpp_msg+tLen, pQuerySM->source_addr, len+1); + tLen = tLen+len+1; + /* command_length */ + pQuerySM->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pQuerySM->head.command_length, 4); + break; + case QuerySMResp: + pQuerySMResp = (PDU_QUERY_SM_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pQuerySMResp, 16); + /* mandatory parameter. */ + len = strlen(pQuerySMResp->message_id); + memcpy(smpp_msg+tLen, pQuerySMResp->message_id, len+1); + tLen = tLen+len+1; + len = strlen(pQuerySMResp->final_date); + if (len > 0) { len = 16;} + memcpy(smpp_msg+tLen, pQuerySMResp->final_date, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pQuerySMResp->message_state; + *(smpp_msg+tLen++) = pQuerySMResp->error_code; + /* command_length */ + pQuerySMResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pQuerySMResp->head.command_length, 4); + break; + case CancelSM: + pCancelSM = (PDU_CANCEL_SM *)&pMsg->pdu; + memcpy(smpp_msg+offset, pCancelSM, 16); + /* mandatory parameter. */ + len = strlen(pCancelSM->service_type); + memcpy(smpp_msg+tLen, pCancelSM->service_type, len+1); + tLen = tLen+len+1; + len = strlen(pCancelSM->message_id); + memcpy(smpp_msg+tLen, pCancelSM->message_id, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pCancelSM->source_addr_ton; + *(smpp_msg+tLen++) = pCancelSM->source_addr_npi; + len = strlen(pCancelSM->source_addr); + memcpy(smpp_msg+tLen, pCancelSM->source_addr, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pCancelSM->dest_addr_ton; + *(smpp_msg+tLen++) = pCancelSM->dest_addr_npi; + len = strlen(pCancelSM->destination_addr); + memcpy(smpp_msg+tLen, pCancelSM->destination_addr, len+1); + tLen = tLen+len+1; + /* command_length */ + pCancelSM->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pCancelSM->head.command_length, 4); + break; + case CancelSMResp: + pCancelSMResp = (PDU_CANCEL_SM_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pCancelSMResp, 16); + pCancelSMResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pCancelSMResp->head.command_length, 4); + break; + case ReplaceSM: + pReplaceSM = (PDU_REPLACE_SM *)&pMsg->pdu; + memcpy(smpp_msg+offset, pReplaceSM, 16); + /* mandatory parameter. */ + len = strlen(pReplaceSM->message_id); + memcpy(smpp_msg+tLen, pReplaceSM->message_id, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pReplaceSM->source_addr_ton; + *(smpp_msg+tLen++) = pReplaceSM->source_addr_npi; + len = strlen(pReplaceSM->source_addr); + memcpy(smpp_msg+tLen, pReplaceSM->source_addr, len+1); + tLen = tLen+len+1; + len = strlen(pReplaceSM->schedule_delivery_time); + memcpy(smpp_msg+tLen, pReplaceSM->schedule_delivery_time, len+1); + tLen = tLen+len+1; + len = strlen(pReplaceSM->validity_period); + memcpy(smpp_msg+tLen, pReplaceSM->validity_period, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pReplaceSM->registered_delivery; + *(smpp_msg+tLen++) = pReplaceSM->sm_default_msg_id; + *(smpp_msg+tLen++) = pReplaceSM->sm_length; +// len = strlen(pReplaceSM->short_message); + len = pReplaceSM->sm_length; + memcpy(smpp_msg+tLen, pReplaceSM->short_message, len+1); + tLen = tLen+len+1; + /* command_length */ + pReplaceSM->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pReplaceSM->head.command_length, 4); + break; + case ReplaceSMResp: + pReplaceSMResp = (PDU_REPLACE_SM_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pReplaceSMResp, 16); + pReplaceSMResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pReplaceSMResp->head.command_length, 4); + break; + case Outbind: + pOutbind = (PDU_OUTBIND *)&pMsg->pdu; + memcpy(smpp_msg+offset, pOutbind, 16); + len = strlen(pOutbind->system_id); + memcpy(smpp_msg+tLen, pOutbind->system_id, len+1); + tLen = tLen+len+1; + len = strlen(pOutbind->password); + memcpy(smpp_msg+tLen, pOutbind->password, len+1); + tLen = tLen+len+1; + pOutbind->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pOutbind->head.command_length, 4); + break; + case BindTransmitter: + case BindReceiver: + case BindTransceiver: + pBind = (PDU_BIND *)&pMsg->pdu; + memcpy(smpp_msg+offset, pBind, 16); + len = strlen(pBind->system_id); + memcpy(smpp_msg+tLen, pBind->system_id, len+1); + tLen = tLen+len+1; + len = strlen(pBind->password); + memcpy(smpp_msg+tLen, pBind->password, len+1); + tLen = tLen+len+1; + len = strlen(pBind->system_type); + memcpy(smpp_msg+tLen, pBind->system_type, len+1); + tLen = tLen+len+1; + *(smpp_msg+tLen++) = pBind->interface_version; + *(smpp_msg+tLen++) = pBind->addr_ton; + *(smpp_msg+tLen++) = pBind->addr_npi; + len = strlen(pBind->address_range); + memcpy(smpp_msg+tLen, pBind->address_range, len+1); + tLen = tLen+len+1; + pBind->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pBind->head.command_length, 4); + break; + case BindTransmitterResp: + case BindReceiverResp: + case BindTransceiverResp: + pBindResp = (PDU_BIND_RESP *)&pMsg->pdu; + memcpy(smpp_msg+offset, pBindResp, 16); + + len = strlen(pBindResp->system_id); + memcpy(smpp_msg+tLen, pBindResp->system_id, len+1); + tLen = tLen+len+1; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory Parameters]\n"); + sprintf(debugBuf, "system_id: %s\n", pBindResp->system_id); + smpp_send_ascout(debugBuf); + } + #endif + + /* sc_interface_version */ + smpp_addTLV(smpp_msg+tLen, SC_INTERFACE_VERSION, + &pBindResp->sc_interface_version, 1); + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional Parameters]\n"); + sprintf(debugBuf, "sc_interface_version: 0x%02X\n", pBindResp->sc_interface_version); + smpp_send_ascout(debugBuf); + } + #endif + + tLen = tLen + 5; + pBindResp->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pBindResp->head.command_length, 4); + break; + case Unbind: + case UnbindResp: + case EnquireLink: + case EnquireLinkResp: + pUnbind = (PDU_UNBIND *)&pMsg->pdu; + memcpy(smpp_msg+offset, pUnbind, 16); + pUnbind->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pUnbind->head.command_length, 4); + break; + case UnknownCommandID: + pGenericNack = (PDU_GENERIC_NACK *)&pMsg->pdu; + memcpy(smpp_msg+offset, pGenericNack, 16); + pGenericNack->head.command_length = htonl(tLen-offset); + memcpy(smpp_msg+offset, &pGenericNack->head.command_length, 4); + break; + default: + break; + } + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("ENCODE:\n"); + smpp_display_hex_msg((BYTE*) smpp_msg+offset, tLen); + } + #endif + + if (smpp_param[linkNo].link_type == 0) //send message over SCCP + { +// printf("link %d send sccp message. dst_ref=%d, src_ref=%d\n", linkNo, smpp_msg[0], smpp_msg[1]); + memset(&sclcMsg,0,sizeof(sclcMsg)); + smpp_setSccpAddr(linkNo, &sclcMsg.src_addr, &sclcMsg.dst_addr); + sclcMsg.msglen = tLen; + memcpy(sclcMsg.msg, smpp_msg, tLen); + sclcMsg.sls = smpp_system_no; + //sclcMsg.sls += 1; + //sclcMsg.sls &= 0x0f; + + sclc_send(&sclcMsg); + } + else if (smpp_param[linkNo].link_type == 1) //send message over TCP + { + if (Mysock.Sockets[linkNo] < 0) + { +// printf("[FAIL]socket %d number = %d\n", linkNo, Mysock.Sockets[linkNo]); + return (-1); + } + if ((actlen = send(Mysock.Sockets[linkNo], smpp_msg, tLen, MSG_NOSIGNAL)) < 0) + { + smpp_state[linkNo] = SUSPEND;//ch + sprintf(debugBuf, "link %d Socket Send Error: %s\n",linkNo,strerror(errno)); + smpp_send_error(debugBuf); + return (-2); + } + } + + return tLen; +} + +//return smpp link no. (-1) -- error +//link_type: 0-UDP, 1-TCP +int smpp_decode_setup(BYTE link_type, int tcp_linkNo, BYTE src_ref, SMPP_GENERAL *pData, int len) +{ + int i, linkNo; + int current_len, c_octet_string_len=0; + struct in_addr addr; + + BYTE *pMsg; + char ton_str[32], npi_str[32], debugBuf[512]; + DWORD command_length, command_id, command_status, sequence_number; + + SMPP_MSG smppMsg; + PDU_BIND *pBind; + PDU_OUTBIND *pOutbind; + + command_length = ntohl(pData->head.command_length); + command_id = ntohl(pData->head.command_id); + command_status = ntohl(pData->head.command_status); + sequence_number = ntohl(pData->head.sequence_number); + memset(&smppMsg,0,sizeof(smppMsg)); + switch (command_id) + { + case BIND_TRANSMITTER: + pMsg = pData->msg; + pBind = &smppMsg.pdu.bind_transmitter; + +// printf("receive bind_transmitter.\n"); + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + // find out link no + linkNo = smpp_check_sysid_route(pBind->system_id, c_octet_string_len, SMPP_CLIENT, BIND_TX); + if (linkNo == -1) + { + sprintf(debugBuf, "[smpp BIND_TRANSMITTER]can't not find system id %s in smpp parameter table.\r\n", pBind->system_id); + smpp_send_error(debugBuf); + if (link_type == SMPP_TCP) + { + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } + return (-1); + } + if (link_type == SMPP_TCP) + { + if (smpp_param[linkNo].remote_ip != Mysock.remote_ip[tcp_linkNo]) + { + addr.s_addr = Mysock.remote_ip[tcp_linkNo]; + sprintf(debugBuf, "[Remote ip error]remote_ip is: %s\r\n", inet_ntoa(addr)); + smpp_send_error(debugBuf); + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } +// if(smpp_state[linkNo] != IDLE) +// { +// close(Mysock.server_sock[tcp_linkNo]); +// Mysock.server_sock[tcp_linkNo] = -1; +// return (-1); +// } + if(Mysock.Sockets[linkNo] > 0) + close(Mysock.Sockets[linkNo]); + Mysock.Sockets[linkNo] = Mysock.server_sock[tcp_linkNo]; + Mysock.server_sock[tcp_linkNo] = -1; + } + else if (link_type == SMPP_UDP) + dst_ref[linkNo] = src_ref; + smpp_link[linkNo].seq_num = sequence_number; + + /* password */ + c_octet_string_len = 1; + for (i=0; i<9; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->password, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* system type */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* interface version */ + pBind->interface_version = *(pMsg+current_len); + current_len += 1; + + /* addr_ton */ + pBind->addr_ton = *(pMsg+current_len); + current_len += 1; + + /* addr_npi */ + pBind->addr_npi = *(pMsg+current_len); + current_len += 1; + + /* address_range */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->address_range, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive BIND_TRANSMITTER: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return (-1); + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive BIND_TRANSMITTER: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return (-1); + } + + if (strcmp(pBind->system_id, smpp_param[linkNo].sys_id) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive BIND_TRANSMITTER: system_id = %s, sys_id in param=%s\n", + linkNo, + pBind->system_id, + smpp_param[linkNo].sys_id); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindTransmitterResp, ESME_RINVSYSID); + return (-1); + } + + if (strcmp(pBind->password, smpp_param[linkNo].password) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup]link %d receive BIND_TRANSMITTER: password = %s, password in param=%s\n", + linkNo, + pBind->password, + smpp_param[linkNo].password); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindTransmitterResp, ESME_RINVPASWD); + return (-1); + } + + if (strcmp(pBind->system_type, smpp_param[linkNo].system_type) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup]link %d receive BIND_TRANSMITTER: system_type = %s, system_type in param=%s\n", + linkNo, + pBind->system_type, + smpp_param[linkNo].system_type); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindTransmitterResp, ESME_RINVSYSTYP); + return (-1); + } + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_ton_to_string(ton_str, pBind->addr_ton); + smpp_npi_to_string(npi_str, pBind->addr_npi); + sprintf(debugBuf, "[Mandatory parameters]\nsystem_id:%s, password:%s, system_type:%s, interface_version:0x%x, addr_ton: 0x%x - %s, addr_npi: 0x%x - %s\n", + pBind->system_id, + pBind->password, + pBind->system_type, + pBind->interface_version, + pBind->addr_ton, ton_str, + pBind->addr_npi, npi_str + ); + smpp_send_ascout(debugBuf); + } + #endif + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = BindTransmitter; +// printf("link %d receive bind_transmitter.\n", linkNo); + break; + case BIND_TRANSCEIVER: + pMsg = pData->msg; + pBind = &smppMsg.pdu.bind_transmitter; + + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + // find out link no + linkNo = smpp_check_sysid_route(pBind->system_id, c_octet_string_len, SMPP_CLIENT, BIND_TRX); + if (linkNo == -1) + { + sprintf(debugBuf, "[smpp BIND_TRANSCEIVER]can't not find system id %s in smpp parameter table.\r\n", pBind->system_id); + smpp_send_error(debugBuf); + if (link_type == SMPP_TCP) + { + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } + return (-1); + } + if (link_type == SMPP_TCP) + { + if (smpp_param[linkNo].remote_ip != Mysock.remote_ip[tcp_linkNo]) + { + addr.s_addr = Mysock.remote_ip[tcp_linkNo]; + sprintf(debugBuf, "[smpp BIND_TRANSCEIVER]Remote ip error,remote_ip is: %s\r\n", inet_ntoa(addr)); + smpp_send_error(debugBuf); + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } +// if(smpp_state[linkNo] != IDLE) +// { +// close(Mysock.server_sock[tcp_linkNo]); +// Mysock.server_sock[tcp_linkNo] = -1; +// return (-1); +// } + if(Mysock.Sockets[linkNo] > 0) + close(Mysock.Sockets[linkNo]); + Mysock.Sockets[linkNo] = Mysock.server_sock[tcp_linkNo]; + Mysock.server_sock[tcp_linkNo] = -1; + } + if (link_type == SMPP_UDP) dst_ref[linkNo] = src_ref; + smpp_link[linkNo].seq_num = sequence_number; + + /* password */ + c_octet_string_len = 1; + for (i=0; i<9; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->password, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* system type */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* interface version */ + pBind->interface_version = *(pMsg+current_len); + current_len += 1; + + /* addr_ton */ + pBind->addr_ton = *(pMsg+current_len); + current_len += 1; + + /* addr_npi */ + pBind->addr_npi = *(pMsg+current_len); + current_len += 1; + + /* address_range */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->address_range, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive BIND_TRANSCEIVER: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return (-1); + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive BIND_TRANSCEIVER: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return (-1); + } + + if (strcmp(pBind->system_id, smpp_param[linkNo].sys_id) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive BIND_TRANSCEIVER: system_id = %s, sys_id in param=%s\n", + linkNo, + pBind->system_id, + smpp_param[linkNo].sys_id); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindTransceiverResp, ESME_RINVSYSID); + return (-1); + } + + if (strcmp(pBind->password, smpp_param[linkNo].password) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup]link %d receive BIND_TRANSCEIVER: password = %s, password in param=%s\n", + linkNo, + pBind->password, + smpp_param[linkNo].password); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindTransceiverResp, ESME_RINVPASWD); + return (-1); + } + + if (strcmp(pBind->system_type, smpp_param[linkNo].system_type) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup]link %d receive BIND_TRANSCEIVER: system_type = %s, system_type in param=%s\n", + linkNo, + pBind->system_type, + smpp_param[linkNo].system_type); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindTransceiverResp, ESME_RINVSYSTYP); + return (-1); + } + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_ton_to_string(ton_str, pBind->addr_ton); + smpp_npi_to_string(npi_str, pBind->addr_npi); + sprintf(debugBuf, "[Mandatory parameters]\nsystem_id:%s, password:%s, system_type:%s, interface_version:0x%x, addr_ton: 0x%x - %s, addr_npi: 0x%x - %s\n", + pBind->system_id, + pBind->password, + pBind->system_type, + pBind->interface_version, + pBind->addr_ton, ton_str, + pBind->addr_npi, npi_str + ); + smpp_send_ascout(debugBuf); + } + #endif + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = BindTransceiver; +// printf("link %d receive BIND_TRANCEIVER", linkNo); + break; + case OUTBIND: + pMsg = pData->msg; + pOutbind = &smppMsg.pdu.outbind; + + /* mandatory parameter */ + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pOutbind->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + // find out link no + linkNo = smpp_check_sysid_route(pOutbind->system_id, c_octet_string_len, SMPP_SERVER, BIND_RX); + if (linkNo == -1) + { + addr.s_addr = Mysock.remote_ip[tcp_linkNo]; + sprintf(debugBuf, "remote_ip: %s\r\n", inet_ntoa(addr)); + smpp_send_error(debugBuf); + sprintf(debugBuf, "[smpp OUTBIND]can't not find system id %s in smpp parameter table.\r\n", pOutbind->system_id); + smpp_send_error(debugBuf); + if (link_type == SMPP_TCP) + { + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } + return (-1); + } + if (link_type == SMPP_TCP) + { + if (smpp_param[linkNo].remote_ip != Mysock.remote_ip[tcp_linkNo]) + { + addr.s_addr = Mysock.remote_ip[tcp_linkNo]; + sprintf(debugBuf, "[smpp OUTBIND]Remote ip error,remote_ip is: %s\r\n", inet_ntoa(addr)); + smpp_send_error(debugBuf); + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } +// if(smpp_state[linkNo] != IDLE) +// { +// close(Mysock.server_sock[tcp_linkNo]); +// Mysock.server_sock[tcp_linkNo] = -1; +// return (-1); +// } + if(Mysock.Sockets[linkNo] > 0) + close(Mysock.Sockets[linkNo]); + Mysock.Sockets[linkNo] = Mysock.server_sock[tcp_linkNo]; + Mysock.server_sock[tcp_linkNo] = -1; + } + if (link_type == SMPP_UDP) dst_ref[linkNo] = src_ref; + smpp_link[linkNo].seq_num = sequence_number; + + /* password */ + c_octet_string_len = 1; + for (i=0; i<9; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pOutbind->password, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive OUTBIND: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return (-1); + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive OUTBIND: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return (-1); + } + + if (strcmp(pOutbind->system_id, smpp_param[linkNo].sys_id) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive OUTBIND: system_id = %s, sys_id in param=%s\n", + linkNo, + pOutbind->system_id, + smpp_param[linkNo].sys_id); + smpp_send_error(debugBuf); + } + #endif +// smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVSYSID); + return (-1); + } + + if (strcmp(pOutbind->password, smpp_param[linkNo].password) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup]link %d receive OUTBIND: password = %s, password in param=%s\n", + linkNo, + pOutbind->password, + smpp_param[linkNo].password); + smpp_send_error(debugBuf); + } + #endif + return (-1); + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = Outbind; +// printf("link %d receive OUTBIND, inter_head=%d.\n", linkNo, inter_head[linkNo]); + break; + case BIND_RECEIVER: + pMsg = pData->msg; + pBind = &smppMsg.pdu.bind_receiver; + +// printf("receive bind_receiver.\n"); + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + // find out link no + linkNo = smpp_check_sysid_route(pBind->system_id, c_octet_string_len, SMPP_CLIENT, BIND_RX); + if (linkNo == -1) + { + sprintf(debugBuf, "[smpp bind_receiver]can't not find system id %s in smpp parameter table.\r\n", pBind->system_id); + smpp_send_error(debugBuf); + if (link_type == SMPP_TCP) + { + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } + return (-1); + } + if (link_type == SMPP_TCP) + { + if (smpp_param[linkNo].remote_ip != Mysock.remote_ip[tcp_linkNo]) + { + addr.s_addr = Mysock.remote_ip[tcp_linkNo]; + sprintf(debugBuf, "[smpp bind_receiver]Remote ip error,remote_ip is: %s\r\n", inet_ntoa(addr)); + smpp_send_error(debugBuf); + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + } + if(smpp_state[linkNo]!=IDLE && smpp_state[linkNo]!=WAITING)//send out bind wating state + { + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = -1; + return (-1); + } + if(Mysock.Sockets[linkNo] > 0) + close(Mysock.Sockets[linkNo]); + Mysock.Sockets[linkNo] = Mysock.server_sock[tcp_linkNo]; + Mysock.server_sock[tcp_linkNo] = -1; + } + else if (link_type == SMPP_UDP) + dst_ref[linkNo] = src_ref; + smpp_link[linkNo].seq_num = sequence_number; + + /* password */ + c_octet_string_len = 1; + for (i=0; i<9; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->password, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* system type */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* interface version */ + pBind->interface_version = *(pMsg+current_len); + current_len += 1; + + /* addr_ton */ + pBind->addr_ton = *(pMsg+current_len); + current_len += 1; + + /* addr_npi */ + pBind->addr_npi = *(pMsg+current_len); + current_len += 1; + + /* address_range */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->address_range, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive bind_receiver: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return (-1); + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive bind_receiver: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return (-1); + } + + if (strcmp(pBind->system_id, smpp_param[linkNo].sys_id) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup] link %d receive bind_receiver: system_id = %s, sys_id in param=%s\n", + linkNo, + pBind->system_id, + smpp_param[linkNo].sys_id); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVSYSID); + return (-1); + } + + if (strcmp(pBind->password, smpp_param[linkNo].password) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup]link %d receive bind_receiver: password = %s, password in param=%s\n", + linkNo, + pBind->password, + smpp_param[linkNo].password); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVPASWD); + return (-1); + } + + if (strcmp(pBind->system_type, smpp_param[linkNo].system_type) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_setup]link %d receive bind_receiver: system_type = %s, system_type in param=%s\n", + linkNo, + pBind->system_type, + smpp_param[linkNo].system_type); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVSYSTYP); + return (-1); + } + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_ton_to_string(ton_str, pBind->addr_ton); + smpp_npi_to_string(npi_str, pBind->addr_npi); + sprintf(debugBuf, "[Mandatory parameters]\nsystem_id:%s, password:%s, system_type:%s, interface_version:0x%x, addr_ton: 0x%x - %s, addr_npi: 0x%x - %s\n", + pBind->system_id, + pBind->password, + pBind->system_type, + pBind->interface_version, + pBind->addr_ton, ton_str, + pBind->addr_npi, npi_str + ); + smpp_send_ascout(debugBuf); + } + #endif + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = BindReceiver; +// printf("link %d receive bind_transmitter.\n", linkNo); + break; + default: + sprintf(debugBuf, "receive error command:%u",command_id); + smpp_send_error(debugBuf); + if (link_type == SMPP_TCP) + { + close(Mysock.server_sock[tcp_linkNo]); + Mysock.server_sock[tcp_linkNo] = 0; + } + return (-1); + } + return linkNo; +} + +int smpp_decode_msg(int linkNo, SMPP_GENERAL *pData, int len) +{ + DWORD command_length, command_id, command_status, sequence_number; + char debugBuf[1024]; + int i, j, current_len = 0, c_octet_string_len=0; + SMPP_MSG smppMsg; + PDU_BIND *pBind; + PDU_BIND_RESP *pBindResp; + PDU_OUTBIND *pOutbind; + PDU_SUBMIT_SM *pSubmitSM; + PDU_SUBMIT_SM_RESP *pSubmitSMResp; + PDU_SUBMIT_MULTI *pSubmitMulti; + PDU_SUBMIT_MULTI_RESP *pSubmitMultiResp; + PDU_DELIVER_SM *pDeliverSM; + PDU_DELIVER_SM_RESP *pDeliverSMResp; + PDU_DATA_SM *pDataSM; + PDU_DATA_SM_RESP *pDataSMResp; + PDU_QUERY_SM *pQuerySM; + PDU_QUERY_SM_RESP *pQuerySMResp; + PDU_CANCEL_SM *pCancelSM; + PDU_CANCEL_SM_RESP *pCancelSMResp; + PDU_REPLACE_SM *pReplaceSM; + PDU_REPLACE_SM_RESP *pReplaceSMResp; + PDU_ALERT_NOTIFICATION *pAlertNotification; + BYTE *pMsg; + char comm_str[32], status_str[128], ton_str[32], npi_str[32]; + BYTE opt_num; + + command_length = ntohl(pData->head.command_length); + command_id = ntohl(pData->head.command_id); + command_status = ntohl(pData->head.command_status); + sequence_number = ntohl(pData->head.sequence_number); + memset(&smppMsg,0,sizeof(smppMsg)); + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { +// if(command_id!=ENQUIRE_LINK && command_id!=ENQUIRE_LINK_RESP) + { + smpp_command_id_to_string(comm_str, command_id); + sprintf(debugBuf, "\n==>SMPP %s\tlink: %d\n", comm_str, linkNo); + smpp_send_ascout(debugBuf); + smpp_display_hex_msg((BYTE*) pData, len); + smpp_command_status_to_string(status_str, command_status); + sprintf(debugBuf, "DECODE:\n[Header]\ncommand_length=0x%x(hex), command_id=0x%x(hex), command_status=0x%x(%s), sequence_number=%u(dec)\n", + command_length, + command_id, + command_status, status_str, + sequence_number); + smpp_send_ascout(debugBuf); + // printf("%s\n",debugBuf); + } + } + #endif + + switch (command_id) + { + case BIND_TRANSMITTER: + break; + case BIND_TRANSMITTER_RESP: + pMsg = pData->msg; + pBindResp = &smppMsg.pdu.bind_transmitter_resp; + smpp_link[linkNo].seq_num = sequence_number; + + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBindResp->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[Mandatory Parameters]\nsystem_id: %s\n", + pBindResp->system_id); + smpp_send_ascout(debugBuf); + } + #endif + + /* Optional parameter */ + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; isc_interface_version, &opt_param[i].value, opt_param[i].len); + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sc_interface_version: 0x%02X\n", pBindResp->sc_interface_version); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in BIND_TRANSMITTER_RESP. tag=0x%02X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + return 0; + } + } + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = BindTransmitterResp; + break; + case BIND_RECEIVER: + pMsg = pData->msg; + pBind = &smppMsg.pdu.bind_transmitter; + smpp_link[linkNo].seq_num = sequence_number; + + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* password */ + c_octet_string_len = 1; + for (i=0; i<9; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->password, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* system type */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->system_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* interface version */ + pBind->interface_version = *(pMsg+current_len); + current_len += 1; + + /* addr_ton */ + pBind->addr_ton = *(pMsg+current_len); + current_len += 1; + + /* addr_npi */ + pBind->addr_npi = *(pMsg+current_len); + current_len += 1; + + /* address_range */ + c_octet_string_len = 1; + for (i=0; i<13; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBind->address_range, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive BIND_RECEIVER: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive BIND_RECEIVER: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + if (strcmp(pBind->system_id, smpp_param[linkNo].sys_id) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive BIND_RECEIVER: system_id = %s, sys_id in param=%s\n", + linkNo, + pBind->system_id, + smpp_param[linkNo].sys_id); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVSYSID); + return 0; + } + + if (strcmp(pBind->password, smpp_param[linkNo].password) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg]link %d receive BIND_RECEIVER: password = %s, password in param=%s\n", + linkNo, + pBind->password, + smpp_param[linkNo].password); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVPASWD); + return 0; + } + + if (strcmp(pBind->system_type, smpp_param[linkNo].system_type) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg]link %d receive BIND_RECEIVER: system_type = %s, system_type in param=%s\n", + linkNo, + pBind->system_type, + smpp_param[linkNo].system_type); + smpp_send_error(debugBuf); + } + #endif + smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVSYSTYP); + return 0; + } + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_ton_to_string(ton_str, pBind->addr_ton); + smpp_npi_to_string(npi_str, pBind->addr_npi); + sprintf(debugBuf, "[Mandatory parameters]\nsystem_id:%s, password:%s, system_type:%s, interface_version:0x%x, addr_ton: 0x%x - %s, addr_npi: 0x%x - %s\n", + pBind->system_id, + pBind->password, + pBind->system_type, + pBind->interface_version, + pBind->addr_ton, ton_str, + pBind->addr_npi, npi_str + ); + smpp_send_ascout(debugBuf); + } + #endif + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = BindReceiver; +// printf("[smpp] link %d receiver BindReceiver. inter_head=%d\n", linkNo, inter_head[linkNo]); + break; + case BIND_RECEIVER_RESP: + pMsg = pData->msg; + pBindResp = &smppMsg.pdu.bind_receiver_resp; + smpp_link[linkNo].seq_num = sequence_number; + + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBindResp->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[Mandatory Parameters]\nsystem_id: %s\n", + pBindResp->system_id); + smpp_send_ascout(debugBuf); + } + #endif + + /* Optional parameter */ + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; isc_interface_version, &opt_param[i].value, opt_param[i].len); + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sc_interface_version: 0x%02X\n", pBindResp->sc_interface_version); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in BIND_RECEIVER_RESP. tag=0x%02X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + return 0; + } + } + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = BindReceiverResp; + break; + case BIND_TRANSCEIVER: + break; + case BIND_TRANSCEIVER_RESP: + pMsg = pData->msg; + pBindResp = &smppMsg.pdu.bind_receiver_resp; + smpp_link[linkNo].seq_num = sequence_number; + + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pBindResp->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[Mandatory Parameters]\nsystem_id: %s\n", + pBindResp->system_id); + smpp_send_ascout(debugBuf); + } + #endif + + /* Optional parameter */ + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; isc_interface_version, &opt_param[i].value, opt_param[i].len); + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sc_interface_version: 0x%02X\n", pBindResp->sc_interface_version); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in BIND_TRANSCEIVER_RESP. tag=0x%02X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + return 0; + } + } + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = BindTransceiverResp; + break; + case ENQUIRE_LINK: + if (16 != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive ENQUIRE_LINK: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (16 != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive ENQUIRE_LINK: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + smpp_link[linkNo].seq_num = sequence_number; + interEvent[linkNo][inter_head[linkNo]] = EnquireLink; + break; + case ENQUIRE_LINK_RESP: + if (16 != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive ENQUIRE_LINK_RESP: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (16 != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive ENQUIRE_LINK_RESP: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = EnquireLinkResp; + break; + case SUBMIT_SM: +// printf("\33[32mlink %d receive SUBMIT_SM.\33[0m\n", linkNo); + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = SubmitSM; + smpp_link[linkNo].seq_num = sequence_number; + /* fill with SMPP_MSG data structure. */ + pMsg = pData->msg; + pSubmitSM = &smppMsg.pdu.submit_sm; + smppMsg.message_type = 0x0B; + /* head */ + memcpy(&pSubmitSM->head, &pData->head, 16); + /* mandatory parameter */ + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<6; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitSM->service_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitSM->source_addr_ton = *(pMsg+current_len); + current_len += 1; + pSubmitSM->source_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitSM->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitSM->dest_addr_ton = *(pMsg+current_len); + current_len += 1; + pSubmitSM->dest_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitSM->destination_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitSM->esm_class = *(pMsg+current_len); + current_len += 1; + pSubmitSM->protocol_id = *(pMsg+current_len); + current_len += 1; + pSubmitSM->priority_flag = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<17; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitSM->schedule_delivery_time, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + c_octet_string_len = 1; + for (i=0; i<17; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitSM->validity_period, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitSM->registered_delivery = *(pMsg+current_len); + current_len += 1; + pSubmitSM->replace_if_present_flag = *(pMsg+current_len); + current_len += 1; + pSubmitSM->data_coding = *(pMsg+current_len); + current_len += 1; + pSubmitSM->sm_default_msg_id = *(pMsg+current_len); + current_len += 1; + pSubmitSM->sm_length = *(pMsg+current_len); + current_len += 1; + memcpy(pSubmitSM->short_message, pMsg+current_len, pSubmitSM->sm_length); + current_len += pSubmitSM->sm_length; + pSubmitSM->short_message[pSubmitSM->sm_length] = 0; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + smpp_ton_to_string(ton_str, pSubmitSM->source_addr_ton); + smpp_npi_to_string(npi_str, pSubmitSM->source_addr_npi); + sprintf(debugBuf, "service_type: %s,\tsource_addr_ton: 0x%x - %s,\tsource_addr_npi: 0x%x - %s,\tsource_addr: %s\t", + pSubmitSM->service_type, + pSubmitSM->source_addr_ton, ton_str, + pSubmitSM->source_addr_npi, npi_str, + pSubmitSM->source_addr); + smpp_send_ascout(debugBuf); + smpp_ton_to_string(ton_str, pSubmitSM->dest_addr_ton); + smpp_npi_to_string(npi_str, pSubmitSM->dest_addr_npi); + sprintf(debugBuf, "dest_addr_ton: 0x%x - %s,\tdest_addr_npi: 0x%x - %s,\tdestination_addr: %s\t", + pSubmitSM->dest_addr_ton, ton_str, + pSubmitSM->dest_addr_npi, npi_str, + pSubmitSM->destination_addr); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "esm_class: 0x%x,\tprotocol_id: 0x%x,\tpriority_flag: 0x%x,\tschedule_delivery_time: %s,\tvalidity_period: %s,\tregistered_delivery: 0x%x\t", + pSubmitSM->esm_class, + pSubmitSM->protocol_id, + pSubmitSM->priority_flag, + pSubmitSM->schedule_delivery_time, + pSubmitSM->validity_period, + pSubmitSM->registered_delivery); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "replace_if_present_flag: 0x%x,\tdata_coding: 0x%x,\tsm_default_msg_id: 0x%x,\tsm_length: 0x%x,\tshort_message: %s\n", + pSubmitSM->replace_if_present_flag, + pSubmitSM->data_coding, + pSubmitSM->sm_default_msg_id, + pSubmitSM->sm_length, + pSubmitSM->short_message); + smpp_send_ascout(debugBuf); + } + #endif + + /* optional parameter */ + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; iuser_message_reference, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "user_message_reference: 0x%04X\n", pSubmitSM->user_message_reference); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_PORT: + memcpy(&pSubmitSM->source_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_port: 0x%04X\n", pSubmitSM->source_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_ADDR_SUBUNIT: + memcpy(&pSubmitSM->source_addr_subunit, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_addr_subunit: 0x%02X\n", pSubmitSM->source_addr_subunit); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DESTINATION_PORT: + memcpy(&pSubmitSM->destination_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "destination_port: 0x%04X\n", pSubmitSM->destination_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_ADDR_SUBUNIT: + memcpy(&pSubmitSM->dest_addr_subunit, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_addr_subunit: 0x%02X\n", pSubmitSM->dest_addr_subunit); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_MSG_REF_NUM: + memcpy(&pSubmitSM->sar_msg_ref_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_msg_ref_num: 0x%04X\n", pSubmitSM->sar_msg_ref_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_TOTAL_SEGMENTS: + memcpy(&pSubmitSM->sar_total_segments, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_total_segments: 0x%02X\n", pSubmitSM->sar_total_segments); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_SEGMENT_SEQNUM: + memcpy(&pSubmitSM->sar_segment_seqnum, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_segment_seqnum: 0x%02X\n", pSubmitSM->sar_segment_seqnum); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MORE_MESSAGES_TO_SEND: + memcpy(&pSubmitSM->more_messages_to_send, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "more_messages_to_send: 0x%02X\n", pSubmitSM->more_messages_to_send); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PAYLOAD_TYPE: + memcpy(&pSubmitSM->payload_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "payload_type: 0x%02X\n", pSubmitSM->payload_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MESSAGE_PAYLOAD: + memcpy(pSubmitSM->message_payload, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "message_payload: %s\n", pSubmitSM->message_payload); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PRIVACY_INDICATOR: + memcpy(&pSubmitSM->privacy_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "privacy_indicator: 0x%02X\n", pSubmitSM->privacy_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM: + memcpy(pSubmitSM->callback_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num: %s\n", pSubmitSM->callback_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM_PRES_IND: + memcpy(&pSubmitSM->callback_num_pres_ind, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num_pres_ind: 0x%02X\n", pSubmitSM->callback_num_pres_ind); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM_ATAG: + memcpy(pSubmitSM->callback_num_atag, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num_atag: %s\n", pSubmitSM->callback_num_atag); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_SUBADDRESS: + memcpy(pSubmitSM->source_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_subaddress: %s\n", pSubmitSM->source_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_SUBADDRESS: + memcpy(pSubmitSM->dest_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_subaddress: %s\n", pSubmitSM->dest_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case USER_RESPONSE_CODE: + memcpy(&pSubmitSM->user_response_code, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "user_response_code: 0x%02X\n", pSubmitSM->user_response_code); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DISPLAY_TIME: + memcpy(&pSubmitSM->display_time, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "display_time: 0x%02X\n", pSubmitSM->display_time); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SMS_SIGNAL: + memcpy(&pSubmitSM->sms_signal, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sms_signal: 0x%04X\n", pSubmitSM->sms_signal); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MS_VALIDITY: + memcpy(&pSubmitSM->ms_validity, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ms_validity: 0x%02X\n", pSubmitSM->ms_validity); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MS_MSG_WAIT_FACILITIES: + memcpy(&pSubmitSM->ms_msg_wait_facilities, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ms_msg_wait_facilities: 0x%02X\n", pSubmitSM->ms_msg_wait_facilities); + smpp_send_ascout(debugBuf); + } + #endif + break; + case NUMBER_OF_MESSAGES: + memcpy(&pSubmitSM->number_of_messages, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "number_of_messages: 0x%02X\n", pSubmitSM->number_of_messages); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ALERT_ON_MESSAGE_DELIVERY: + current_len = current_len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "alert_on_message_delivery: 0x%02X\n", pSubmitSM->alert_on_message_delivery); + smpp_send_ascout(debugBuf); + } + #endif + break; + case LANGUAGE_INDICATOR: + memcpy(&pSubmitSM->language_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "language_indicator: 0x%02X\n", pSubmitSM->language_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ITS_REPLY_TYPE: + memcpy(&pSubmitSM->its_reply_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "its_reply_type: 0x%02X\n", pSubmitSM->its_reply_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ITS_SESSION_INFO: + memcpy(pSubmitSM->its_session_info, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "its_session_info: 0x%02X%02X\n", + pSubmitSM->its_session_info[0], pSubmitSM->its_session_info[1]); + smpp_send_ascout(debugBuf); + } + #endif + break; + case USSD_SERVICE_OP: + memcpy(&pSubmitSM->ussd_service_op, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ussd_service_op: 0x%04X\n", pSubmitSM->ussd_service_op); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_NETWORK_TYPE: + memcpy(&pSubmitSM->dest_network_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_network_type: 0x%04X\n", pSubmitSM->dest_network_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in SUBMIT_SM. tag=0x%04X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + return 0; + } + } + } + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive SUBMIT_SM: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive SUBMIT_SM: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_SUBMIT_SM)); + break; + case SUBMIT_SM_RESP: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = SubmitSMResp; + + pMsg = pData->msg; + pSubmitSMResp = &smppMsg.pdu.submit_sm_resp; + smppMsg.message_type = 0x0C; + + memcpy(&pSubmitSMResp->head, &pData->head, 16); + + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitSMResp->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[Mandatory Parameters]\nmessage_id: %s\n", + pSubmitSMResp->message_id); + smpp_send_ascout(debugBuf); + } + #endif + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive SUBMIT_SM_RESP: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive SUBMIT_SM_RESP: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_SUBMIT_SM_RESP)); + break; + case SUBMIT_MULTI: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = SubmitMulti; + smpp_link[linkNo].seq_num = sequence_number; + + pMsg = pData->msg; + pSubmitMulti = &smppMsg.pdu.submit_multi; + smppMsg.message_type = 0x0D; + + memcpy(&pSubmitMulti->head, &pData->head, 16); + + /* mandatory parameter */ + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<6; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMulti->service_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitMulti->source_addr_ton = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->source_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMulti->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitMulti->number_of_dests = *(pMsg+current_len); + current_len += 1; + for (i=0; inumber_of_dests; i++) + { + switch(*(pMsg+current_len)) + { + case 1: //SME address + pSubmitMulti->dest_address[i].dest_flag = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_ton = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (j=0; j<21; j++) + { + if (*(pMsg+current_len+j) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.destination_addr, + pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + break; + case 2: //Distribution List Name + pSubmitMulti->dest_address[i].dest_flag = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (j=0; j<21; j++) + { + if (*(pMsg+current_len+j) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMulti->dest_address[i].dest_addr.dl_name.dl_name, + pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + break; + default: + break; + } + } + pSubmitMulti->esm_class = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->protocol_id = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->priority_flag = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<17; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMulti->schedule_delivery_time, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + c_octet_string_len = 1; + for (i=0; i<17; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMulti->validity_period, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitMulti->registered_delivery = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->replace_if_present_flag= *(pMsg+current_len); + current_len += 1; + pSubmitMulti->data_coding = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->sm_default_msg_id = *(pMsg+current_len); + current_len += 1; + pSubmitMulti->sm_length = *(pMsg+current_len); + current_len += 1; + memcpy(pSubmitMulti->short_message, pMsg+current_len, pSubmitMulti->sm_length); + pSubmitMulti->short_message[pSubmitMulti->sm_length] = 0; + current_len += pSubmitMulti->sm_length; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + smpp_ton_to_string(ton_str, pSubmitMulti->source_addr_ton); + smpp_npi_to_string(npi_str, pSubmitMulti->source_addr_npi); + sprintf(debugBuf, "service_type: %s,\tsource_addr_ton: 0x%x - %s,\tsource_addr_npi: 0x%x - %s,\tsource_addr: %s\t", + pSubmitMulti->service_type, + pSubmitMulti->source_addr_ton, ton_str, + pSubmitMulti->source_addr_npi, npi_str, + pSubmitMulti->source_addr); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "number_of_dests: %d,\t", + pSubmitMulti->number_of_dests); + smpp_send_ascout(debugBuf); + for (i=0; inumber_of_dests; i++) + { + if (0 == pSubmitMulti->number_of_dests) break; + if (pSubmitMulti->dest_address[i].dest_flag == 1) + { + sprintf(debugBuf, "destination address %d flag: 0x01 - %s", + i, "SME address"); + smpp_send_ascout(debugBuf); + smpp_ton_to_string(ton_str, pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_ton); + smpp_npi_to_string(npi_str, pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_npi); + sprintf(debugBuf, "ton: 0x%02X - %s,\tnpi: 0x%02X - %s,\tdestination_addr: %s,\t", + pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_ton, ton_str, + pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.dest_addr_npi, npi_str, + pSubmitMulti->dest_address[i].dest_addr.sme_dest_address.destination_addr); + smpp_send_ascout(debugBuf); + }else if (pSubmitMulti->dest_address[i].dest_flag == 2) + { + sprintf(debugBuf, "destination address %d flag: 0x02 - %s,\tdl_name: %s,\t", + i, "Distribution List Name", + pSubmitMulti->dest_address[i].dest_addr.dl_name.dl_name); + smpp_send_ascout(debugBuf); + } + } + sprintf(debugBuf, "esm_class: 0x%x,\tprotocol_id: 0x%x,\tpriority_flag: 0x%x,\tschedule_delivery_time: %s,\tvalidity_period: %s,\tregistered_delivery: 0x%x\t", + pSubmitMulti->esm_class, + pSubmitMulti->protocol_id, + pSubmitMulti->priority_flag, + pSubmitMulti->schedule_delivery_time, + pSubmitMulti->validity_period, + pSubmitMulti->registered_delivery); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "replace_if_present_flag: 0x%x,\tdata_coding: 0x%x,\tsm_default_msg_id: 0x%x,\tsm_length: 0x%x,\tshort_message: %s\n", + pSubmitMulti->replace_if_present_flag, + pSubmitMulti->data_coding, + pSubmitMulti->sm_default_msg_id, + pSubmitMulti->sm_length, + pSubmitMulti->short_message); + smpp_send_ascout(debugBuf); + } + #endif + + /* optional parameter */ + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; iuser_message_reference, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "user_message_reference: 0x%04X\n", pSubmitMulti->user_message_reference); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_PORT: + memcpy(&pSubmitMulti->source_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_port: 0x%04X\n", pSubmitMulti->source_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_ADDR_SUBUNIT: + memcpy(&pSubmitMulti->source_addr_subunit, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_addr_subunit: 0x%02X\n", pSubmitMulti->source_addr_subunit); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DESTINATION_PORT: + memcpy(&pSubmitMulti->destination_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "destination_port: 0x%04X\n", pSubmitMulti->destination_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_ADDR_SUBUNIT: + memcpy(&pSubmitMulti->dest_addr_subunit, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_addr_subunit: 0x%02X\n", pSubmitMulti->dest_addr_subunit); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_MSG_REF_NUM: + memcpy(&pSubmitMulti->sar_msg_ref_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_msg_ref_num: 0x%04X\n", pSubmitMulti->sar_msg_ref_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_TOTAL_SEGMENTS: + memcpy(&pSubmitMulti->sar_total_segments, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_total_segments: 0x%02X\n", pSubmitMulti->sar_total_segments); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_SEGMENT_SEQNUM: + memcpy(&pSubmitMulti->sar_segment_seqnum, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_segment_seqnum: 0x%02X\n", pSubmitMulti->sar_segment_seqnum); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PAYLOAD_TYPE: + memcpy(&pSubmitMulti->payload_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "payload_type: 0x%02X\n", pSubmitMulti->payload_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MESSAGE_PAYLOAD: + memcpy(pSubmitMulti->message_payload, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "message_payload: %s\n", pSubmitMulti->message_payload); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PRIVACY_INDICATOR: + memcpy(&pSubmitMulti->privacy_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "privacy_indicator: 0x%02X\n", pSubmitMulti->privacy_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM: + memcpy(pSubmitMulti->callback_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num: %s\n", pSubmitMulti->callback_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM_PRES_IND: + memcpy(&pSubmitMulti->callback_num_pres_ind, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num_pres_ind: 0x%02X\n", pSubmitMulti->callback_num_pres_ind); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM_ATAG: + memcpy(pSubmitMulti->callback_num_atag, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num_atag: %s\n", pSubmitMulti->callback_num_atag); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_SUBADDRESS: + memcpy(pSubmitMulti->source_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_subaddress: %s\n", pSubmitMulti->source_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_SUBADDRESS: + memcpy(pSubmitMulti->dest_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_subaddress: %s\n", pSubmitMulti->dest_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DISPLAY_TIME: + memcpy(&pSubmitMulti->display_time, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "display_time: 0x%02X\n", pSubmitMulti->display_time); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SMS_SIGNAL: + memcpy(&pSubmitMulti->sms_signal, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sms_signal: 0x%04X\n", pSubmitMulti->sms_signal); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MS_VALIDITY: + memcpy(&pSubmitMulti->ms_validity, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ms_validity: 0x%02X\n", pSubmitMulti->ms_validity); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MS_MSG_WAIT_FACILITIES: + memcpy(&pSubmitMulti->ms_msg_wait_facilities, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ms_msg_wait_facilities: 0x%02X\n", pSubmitMulti->ms_msg_wait_facilities); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ALERT_ON_MESSAGE_DELIVERY: + current_len = current_len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "alert_on_message_delivery: 0x%02X\n", pSubmitMulti->alert_on_message_delivery); + smpp_send_ascout(debugBuf); + } + #endif + break; + case LANGUAGE_INDICATOR: + memcpy(&pSubmitMulti->language_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "language_indicator: 0x%02X\n", pSubmitMulti->language_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_NETWORK_TYPE: + memcpy(&pSubmitMulti->dest_network_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_network_type: 0x%04X\n", pSubmitMulti->dest_network_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in SUBMIT_MULTI. tag=0x%04X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + smpp_sendResponse(linkNo, SUBMIT_SM_RESP, ESME_ROPTPARNOTALLWD, sequence_number); + return 0; + } + } + } + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive SUBMIT_MULTI: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive SUBMIT_MULTI: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_SUBMIT_MULTI)); + break; + case SUBMIT_MULTI_RESP: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = SubmitMultiResp; + + pMsg = pData->msg; + pSubmitMultiResp = &smppMsg.pdu.submit_multi_resp; + smppMsg.message_type = 0x0E; + + memcpy(&(pSubmitMultiResp->head), &pData->head, 16); + + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMultiResp->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pSubmitMultiResp->no_unsuccess = *(pMsg+current_len); + current_len += 1; + for (i=0; ino_unsuccess; i++) + { + pSubmitMultiResp->unsuccess_sme[i].dest_addr_ton = *(pMsg+current_len); + current_len += 1; + pSubmitMultiResp->unsuccess_sme[i].dest_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pSubmitMultiResp->unsuccess_sme[i].destination_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + memcpy(&pSubmitMultiResp->unsuccess_sme[i].error_status_code, pMsg+current_len, 4); + } + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + sprintf(debugBuf, "message_id: %s\nno_unsuccess: %d\n", + pSubmitMultiResp->message_id, + pSubmitMultiResp->no_unsuccess); + for (i=0; ino_unsuccess; i++) + { + if (pSubmitMultiResp->no_unsuccess == 0) break; + smpp_ton_to_string(ton_str, pSubmitMultiResp->unsuccess_sme[i].dest_addr_ton); + smpp_npi_to_string(npi_str, pSubmitMultiResp->unsuccess_sme[i].dest_addr_npi); + smpp_command_status_to_string(status_str, pSubmitMultiResp->unsuccess_sme[i].error_status_code); + sprintf(debugBuf, "[unsuccess dest %d] ton: 0x%x - %s, npi: 0x%x - %s, destination_addr: %s, error_status_code: %u - %s\n", + i, + pSubmitMultiResp->unsuccess_sme[i].dest_addr_ton, ton_str, + pSubmitMultiResp->unsuccess_sme[i].dest_addr_npi, npi_str, + pSubmitMultiResp->unsuccess_sme[i].destination_addr, + pSubmitMultiResp->unsuccess_sme[i].error_status_code, status_str); + } + } + #endif + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_SUBMIT_MULTI_RESP)); + break; + case DELIVER_SM: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = DeliverSM; + smpp_link[linkNo].seq_num = sequence_number; + + pMsg = pData->msg; + pDeliverSM = &smppMsg.pdu.deliver_sm; + smppMsg.message_type = 0x0F; + + memcpy(&pDeliverSM->head, &pData->head, 16); + + /* mandatory parameter */ + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<6; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pDeliverSM->service_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pDeliverSM->source_addr_ton = *(pMsg+current_len); + current_len += 1; + pDeliverSM->source_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pDeliverSM->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pDeliverSM->dest_addr_ton = *(pMsg+current_len); + current_len += 1; + pDeliverSM->dest_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pDeliverSM->destination_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pDeliverSM->esm_class = *(pMsg+current_len); + current_len += 1; + pDeliverSM->protocol_id = *(pMsg+current_len); + current_len += 1; + pDeliverSM->priority_flag = *(pMsg+current_len); + current_len += 1; + pDeliverSM->schedule_delivery_time = *(pMsg+current_len); + current_len += 1; + pDeliverSM->validity_period = *(pMsg+current_len); + current_len += 1; + pDeliverSM->registered_delivery = *(pMsg+current_len); + current_len += 1; + pDeliverSM->replace_if_present_flag = *(pMsg+current_len); + current_len += 1; + pDeliverSM->data_coding = *(pMsg+current_len); + current_len += 1; + pDeliverSM->sm_default_msg_id = *(pMsg+current_len); + current_len += 1; + pDeliverSM->sm_length = *(pMsg+current_len); + current_len += 1; + memcpy(pDeliverSM->short_message, pMsg+current_len, pDeliverSM->sm_length); + current_len += pDeliverSM->sm_length; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + smpp_ton_to_string(ton_str, pDeliverSM->source_addr_ton); + smpp_npi_to_string(npi_str, pDeliverSM->source_addr_npi); + sprintf(debugBuf, "service_type: %s,\tsource_addr_ton: 0x%x - %s,\tsource_addr_npi: 0x%x - %s,\tsource_addr: %s\t", + pDeliverSM->service_type, + pDeliverSM->source_addr_ton, ton_str, + pDeliverSM->source_addr_npi, npi_str, + pDeliverSM->source_addr); + smpp_send_ascout(debugBuf); + smpp_ton_to_string(ton_str, pDeliverSM->dest_addr_ton); + smpp_npi_to_string(npi_str, pDeliverSM->dest_addr_npi); + sprintf(debugBuf, "dest_addr_ton: 0x%x - %s,\tdest_addr_npi: 0x%x - %s,\tdestination_addr: %s\t", + pDeliverSM->dest_addr_ton, ton_str, + pDeliverSM->dest_addr_npi, npi_str, + pDeliverSM->destination_addr); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "esm_class: 0x%x,\tprotocol_id: 0x%x,\tpriority_flag: 0x%x,\tschedule_delivery_time: 0x%02X,\tvalidity_period: 0x%02X,\tregistered_delivery: 0x%x\t", + pDeliverSM->esm_class, + pDeliverSM->protocol_id, + pDeliverSM->priority_flag, + pDeliverSM->schedule_delivery_time, + pDeliverSM->validity_period, + pDeliverSM->registered_delivery); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "replace_if_present_flag: 0x%x,\tdata_coding: 0x%x,\tsm_default_msg_id: 0x%x,\tsm_length: 0x%x,\tshort_message: %s\n", + pDeliverSM->replace_if_present_flag, + pDeliverSM->data_coding, + pDeliverSM->sm_default_msg_id, + pDeliverSM->sm_length, + pDeliverSM->short_message); + smpp_send_ascout(debugBuf); + } + #endif + + /* optional parameter */ + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; iuser_message_reference, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "user_message_reference: 0x%04X\n", pDeliverSM->user_message_reference); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_PORT: + memcpy(&pDeliverSM->source_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_port: 0x%04X\n", pDeliverSM->source_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DESTINATION_PORT: + memcpy(&pDeliverSM->destination_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "destination_port: 0x%04X\n", pDeliverSM->destination_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_MSG_REF_NUM: + memcpy(&pDeliverSM->sar_msg_ref_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_msg_ref_num: 0x%04X\n", pDeliverSM->sar_msg_ref_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_TOTAL_SEGMENTS: + memcpy(&pDeliverSM->sar_total_segments, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_total_segments: 0x%02X\n", pDeliverSM->sar_total_segments); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_SEGMENT_SEQNUM: + memcpy(&pDeliverSM->sar_segment_seqnum, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_segment_seqnum: 0x%02X\n", pDeliverSM->sar_segment_seqnum); + smpp_send_ascout(debugBuf); + } + #endif + break; + case USER_RESPONSE_CODE: + memcpy(&pDeliverSM->user_response_code, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "user_response_code: 0x%02X\n", pDeliverSM->user_response_code); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PRIVACY_INDICATOR: + memcpy(&pDeliverSM->privacy_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "privacy_indicator: 0x%02X\n", pDeliverSM->privacy_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PAYLOAD_TYPE: + memcpy(&pDeliverSM->payload_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "payload_type: 0x%02X\n", pDeliverSM->payload_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MESSAGE_PAYLOAD: + memcpy(pDeliverSM->message_payload, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "message_payload: %s\n", pDeliverSM->message_payload); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM: + memcpy(pDeliverSM->callback_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num: %s\n", pDeliverSM->callback_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_SUBADDRESS: + memcpy(pDeliverSM->source_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_subaddress: %s\n", pDeliverSM->source_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_SUBADDRESS: + memcpy(pDeliverSM->dest_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_subaddress: %s\n", pDeliverSM->dest_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case LANGUAGE_INDICATOR: + memcpy(&pDeliverSM->language_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "language_indicator: 0x%02X\n", pDeliverSM->language_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ITS_SESSION_INFO: + memcpy(pDeliverSM->its_session_info, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "its_session_info: 0x%02X%02X\n", + pDeliverSM->its_session_info[0], pDeliverSM->its_session_info[1]); + smpp_send_ascout(debugBuf); + } + #endif + break; + case NETWORK_ERROR_CODE: + memcpy(&pDeliverSM->network_error_code, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "network_error_code: 0x%02X%02X%02X\n", + pDeliverSM->network_error_code[0], + pDeliverSM->network_error_code[1], + pDeliverSM->network_error_code[2]); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MESSAGE_STATE: + memcpy(&pDeliverSM->message_state, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "message_state: 0x%02X\n", pDeliverSM->message_state); + smpp_send_ascout(debugBuf); + } + #endif + break; + case RECEIPTED_MESSAGE_ID: + memcpy(&pDeliverSM->receipted_message_id, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "receipted_message_id: %s\n", pDeliverSM->receipted_message_id); + smpp_send_ascout(debugBuf); + } + #endif + break; + case USSD_SERVICE_OP: + memcpy(&pDeliverSM->ussd_service_op, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ussd_service_op: 0x%04X\n", pDeliverSM->ussd_service_op); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in DELIVER_SM. tag=0x%04X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + smpp_sendResponse(linkNo, DATA_SM_RESP, ESME_ROPTPARNOTALLWD, sequence_number); + return 0; + } + } + } + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DELIVER_SM: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DELIVER_SM: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, &smppMsg, sizeof(PDU_DELIVER_SM)); + break; + case DELIVER_SM_RESP: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = DeliverSMResp; + /* fill with SMPP_MSG data structure. */ + pMsg = pData->msg; + pDeliverSMResp = &smppMsg.pdu.deliver_sm_resp; + smppMsg.message_type = 0x10; + + memcpy(&pDeliverSMResp->head, &pData->head, 16); + + current_len = 0; + c_octet_string_len = 1; + //lw modify here 06/10/08 decode code byte sequence error + pDeliverSMResp->head.command_length = ntohl(pData->head.command_length); + pDeliverSMResp->head.command_id = ntohl(pData->head.command_id); + pDeliverSMResp->head.command_status = ntohl(pData->head.command_status); + pDeliverSMResp->head.sequence_number = ntohl(pData->head.sequence_number); +// for (i=0; i<65; i++) +// { +// if (*(pMsg+current_len+i) != 0) c_octet_string_len++; +// else break; +// } +// comment patch 20 + memcpy(&pDeliverSMResp->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DELIVER_SM_RESP: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DELIVER_SM_RESP: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_DELIVER_SM_RESP)); + break; + case DATA_SM: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = DataSM; + smpp_link[linkNo].seq_num = sequence_number; + + pMsg = pData->msg; + pDataSM = &smppMsg.pdu.data_sm; + smppMsg.message_type = 0x11; + + memcpy(&pDataSM->head, &pData->head, 16); + + /* mandatory parameter */ + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<6; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pDataSM->service_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pDataSM->source_addr_ton = *(pMsg+current_len); + current_len += 1; + pDataSM->source_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pDataSM->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pDataSM->dest_addr_ton = *(pMsg+current_len); + current_len += 1; + pDataSM->dest_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pDataSM->destination_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pDataSM->esm_class = *(pMsg+current_len); + current_len += 1; + pDataSM->registered_delivery = *(pMsg+current_len); + current_len += 1; + pDataSM->data_coding = *(pMsg+current_len); + current_len += 1; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + smpp_ton_to_string(ton_str, pDataSM->source_addr_ton); + smpp_npi_to_string(npi_str, pDataSM->source_addr_npi); + sprintf(debugBuf, "service_type: %s,\tsource_addr_ton: 0x%x - %s,\tsource_addr_npi: 0x%x - %s,\tsource_addr: %s\t", + pDataSM->service_type, + pDataSM->source_addr_ton, ton_str, + pDataSM->source_addr_npi, npi_str, + pDataSM->source_addr); + smpp_send_ascout(debugBuf); + smpp_ton_to_string(ton_str, pDataSM->dest_addr_ton); + smpp_npi_to_string(npi_str, pDataSM->dest_addr_npi); + sprintf(debugBuf, "dest_addr_ton: 0x%x - %s,\tdest_addr_npi: 0x%x - %s,\tdestination_addr: %s\t", + pDataSM->dest_addr_ton, ton_str, + pDataSM->dest_addr_npi, npi_str, + pDataSM->destination_addr); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "esm_class: 0x%x,\tregistered_delivery: 0x%x\tdata_coding: 0x%x, current_len=%d\n", + pDataSM->esm_class, + pDataSM->registered_delivery, + pDataSM->data_coding, + current_len); + smpp_send_ascout(debugBuf); + } + #endif + + /* optional parameter */ + + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; isource_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_port: 0x%04X\n", pDataSM->source_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_ADDR_SUBUNIT: + memcpy(&pDataSM->source_addr_subunit, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_addr_subunit: 0x%02X\n", pDataSM->source_addr_subunit); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_NETWORK_TYPE: + memcpy(&pDataSM->source_network_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_network_type: 0x%02X\n", pDataSM->source_network_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_BEARER_TYPE: + memcpy(&pDataSM->source_bearer_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_bearer_type: 0x%02X\n", pDataSM->source_bearer_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_TELEMATICS_ID: + memcpy(&pDataSM->source_telematics_id, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_telematics_id: 0x%04X\n", pDataSM->source_telematics_id); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DESTINATION_PORT: + memcpy(&pDataSM->destination_port, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "destination_port: 0x%04X\n", pDataSM->destination_port); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_ADDR_SUBUNIT: + memcpy(&pDataSM->dest_addr_subunit, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_addr_subunit: 0x%02X\n", pDataSM->dest_addr_subunit); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_NETWORK_TYPE: + memcpy(&pDataSM->dest_network_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_network_type: 0x%02X\n", pDataSM->dest_network_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_BEARER_TYPE: + memcpy(&pDataSM->dest_bearer_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_bearer_type: 0x%02X\n", pDataSM->dest_bearer_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_TELEMATICS_ID: + memcpy(&pDataSM->dest_telematics_id, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_telematics_id: 0x%02X\n", pDataSM->dest_telematics_id); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_MSG_REF_NUM: + memcpy(&pDataSM->sar_msg_ref_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_msg_ref_num: 0x%04X\n", pDataSM->sar_msg_ref_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_TOTAL_SEGMENTS: + memcpy(&pDataSM->sar_total_segments, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_total_segments: 0x%02X\n", pDataSM->sar_total_segments); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SAR_SEGMENT_SEQNUM: + memcpy(&pDataSM->sar_segment_seqnum, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sar_segment_seqnum: 0x%02X\n", pDataSM->sar_segment_seqnum); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MORE_MESSAGES_TO_SEND: + memcpy(&pDataSM->more_messages_to_send, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "more_messages_to_send: 0x%02X\n", pDataSM->more_messages_to_send); + smpp_send_ascout(debugBuf); + } + #endif + break; + case QOS_TIME_TO_LIVE: + memcpy(&pDataSM->qos_time_to_live, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "qos_time_to_live: 0x%x\n", pDataSM->qos_time_to_live); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PAYLOAD_TYPE: + memcpy(&pDataSM->payload_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "payload_type: 0x%02X\n", pDataSM->payload_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MESSAGE_PAYLOAD: + memcpy(pDataSM->message_payload, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "message_payload: %s\n", pDataSM->message_payload); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SET_DPF: + memcpy(&pDataSM->set_dpf, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "set_dpf: 0x%02X\n", pDataSM->set_dpf); + smpp_send_ascout(debugBuf); + } + #endif + break; + case RECEIPTED_MESSAGE_ID: + memcpy(pDataSM->receipted_message_id, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "receipted_message_id: %s\n", pDataSM->receipted_message_id); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MESSAGE_STATE: + memcpy(&pDataSM->message_state, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "message_state: 0x%02X\n", pDataSM->message_state); + smpp_send_ascout(debugBuf); + } + #endif + break; + case NETWORK_ERROR_CODE: + memcpy(pDataSM->network_error_code, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "network_error_code: 0x%02X%02X%02X\n", + pDataSM->network_error_code[0], + pDataSM->network_error_code[1], + pDataSM->network_error_code[2]); + smpp_send_ascout(debugBuf); + } + #endif + break; + case USER_MESSAGE_REFERENCE: + memcpy(&pDataSM->user_message_reference, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "user_message_reference: 0x%02X\n", pDataSM->user_message_reference); + smpp_send_ascout(debugBuf); + } + #endif + break; + case PRIVACY_INDICATOR: + memcpy(&pDataSM->privacy_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "privacy_indicator: 0x%02X\n", pDataSM->privacy_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM: + memcpy(pDataSM->callback_num, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num: %s\n", pDataSM->callback_num); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM_PRES_IND: + memcpy(&pDataSM->callback_num_pres_ind, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num_pres_ind: 0x%02X\n", pDataSM->callback_num_pres_ind); + smpp_send_ascout(debugBuf); + } + #endif + break; + case CALLBACK_NUM_ATAG: + memcpy(&pDataSM->callback_num_atag, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "callback_num_atag: %s\n", pDataSM->callback_num_atag); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SOURCE_SUBADDRESS: + memcpy(pDataSM->source_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "source_subaddress: %s\n", pDataSM->source_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DEST_SUBADDRESS: + memcpy(pDataSM->dest_subaddress, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "dest_subaddress: %s\n", pDataSM->dest_subaddress); + smpp_send_ascout(debugBuf); + } + #endif + break; + case USER_RESPONSE_CODE: + memcpy(&pDataSM->user_response_code, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "user_response_code: 0x%02X\n", pDataSM->user_response_code); + smpp_send_ascout(debugBuf); + } + #endif + break; + case DISPLAY_TIME: + memcpy(&pDataSM->display_time, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "display_time: 0x%02X\n", pDataSM->display_time); + smpp_send_ascout(debugBuf); + } + #endif + break; + case SMS_SIGNAL: + memcpy(&pDataSM->sms_signal, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "sms_signal: 0x%04X\n", pDataSM->sms_signal); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MS_VALIDITY: + memcpy(&pDataSM->ms_validity, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ms_validity: 0x%02X\n", pDataSM->ms_validity); + smpp_send_ascout(debugBuf); + } + #endif + break; + case MS_MSG_WAIT_FACILITIES: + memcpy(&pDataSM->ms_msg_wait_facilities, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ms_msg_wait_facilities: 0x%02X\n", pDataSM->ms_msg_wait_facilities); + smpp_send_ascout(debugBuf); + } + #endif + break; + case NUMBER_OF_MESSAGES: + memcpy(&pDataSM->number_of_messages, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "number_of_messages: 0x%02X\n", pDataSM->number_of_messages); + smpp_send_ascout(debugBuf); + } + #endif + break; + case LANGUAGE_INDICATOR: + memcpy(&pDataSM->language_indicator, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "language_indicator: 0x%02X\n", pDataSM->language_indicator); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ALERT_ON_MESSAGE_DELIVERY: + current_len = current_len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "alert_on_message_delivery: 0x%02X\n", pDataSM->alert_on_message_delivery); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ITS_REPLY_TYPE: + memcpy(&pDataSM->its_reply_type, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "its_reply_type: 0x%02X\n", pDataSM->its_reply_type); + smpp_send_ascout(debugBuf); + } + #endif + break; + case ITS_SESSION_INFO: + memcpy(pDataSM->its_session_info, &opt_param[i].value, opt_param[i].len); + current_len = current_len + opt_param[i].len + 4; + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "its_session_info: 0x%02X%02X\n", + pDataSM->its_session_info[0], pDataSM->its_session_info[1]); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in DATA_SM. tag=0x%04X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + smpp_sendResponse(linkNo, DATA_SM_RESP, ESME_ROPTPARNOTALLWD, sequence_number); + return 0; + } + } + } + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DATA_SM: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DATA_SM: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_DATA_SM)); + break; + case DATA_SM_RESP: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = DataSMResp; + + pMsg = pData->msg; + pDataSMResp = &smppMsg.pdu.data_sm_resp; + smppMsg.message_type = 0x12; + + memcpy(&pDataSMResp->head, &pData->head, 16); + + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pDataSMResp->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DATA_SM_RESP: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive DATA_SM_RESP: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_DATA_SM_RESP)); + break; + case QUERY_SM: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = QuerySM; + smpp_link[linkNo].seq_num = sequence_number; + + pMsg = pData->msg; + pQuerySM = &smppMsg.pdu.query_sm; + smppMsg.message_type = 0x13; + + memcpy(&pQuerySM->head, &pData->head, 16); + + /* mandatory parameter */ + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pQuerySM->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pQuerySM->source_addr_ton = *(pMsg+current_len); + current_len += 1; + pQuerySM->source_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pQuerySM->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + smpp_ton_to_string(ton_str, pQuerySM->source_addr_ton); + smpp_npi_to_string(npi_str, pQuerySM->source_addr_npi); + sprintf(debugBuf, "message_id: %s,\tsource_addr_ton: 0x%x - %s,\tsource_addr_npi: 0x%x - %s,\tsource_addr: %s\t", + pQuerySM->message_id, + pQuerySM->source_addr_ton, ton_str, + pQuerySM->source_addr_npi, npi_str, + pQuerySM->source_addr); + smpp_send_ascout(debugBuf); + } + #endif + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive QUERY_SM: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive QUERY_SM: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_QUERY_SM)); + break; + case QUERY_SM_RESP: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = QuerySMResp; + + pMsg = pData->msg; + pQuerySMResp = &smppMsg.pdu.query_sm_resp; + smppMsg.message_type = 0x14; + + memcpy(&pQuerySMResp->head, &pData->head, 16); + + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pQuerySMResp->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + c_octet_string_len = 1; + for (i=0; i<17; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pQuerySMResp->final_date, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pQuerySMResp->message_state = *(pMsg+current_len); + current_len += 1; + pQuerySMResp->error_code = *(pMsg+current_len); + current_len += 1; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + sprintf(debugBuf, "message_id: %s,\tfinal_date: %s,\tmessage_state: 0x%x,\terror_code: 0x%02X\t", + pQuerySMResp->message_id, + pQuerySMResp->final_date, + pQuerySMResp->message_state, + pQuerySMResp->error_code); + smpp_send_ascout(debugBuf); + } + #endif + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive QUERY_SM_RESP: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive QUERY_SM_RESP: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_QUERY_SM_RESP)); + break; + case CANCEL_SM: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = CancelSM; + smpp_link[linkNo].seq_num = sequence_number; + + pMsg = pData->msg; + pCancelSM = &smppMsg.pdu.cancel_sm; + smppMsg.message_type = 0x15; + + memcpy(&(pCancelSM->head), &pData->head, 16); + + /* mandatory parameter */ + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<6; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pCancelSM->service_type, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pCancelSM->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pCancelSM->source_addr_ton = *(pMsg+current_len); + current_len += 1; + pCancelSM->source_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pCancelSM->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pCancelSM->dest_addr_ton = *(pMsg+current_len); + current_len += 1; + pCancelSM->dest_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pCancelSM->destination_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + smpp_ton_to_string(ton_str, pCancelSM->source_addr_ton); + smpp_npi_to_string(npi_str, pCancelSM->source_addr_npi); + sprintf(debugBuf, "service_type: %s,\tmessage_id: %s,\tsource_addr_ton: 0x%x - %s,\tsource_addr_npi: 0x%x - %s,\tsource_addr: %s\t", + pCancelSM->service_type, + pCancelSM->message_id, + pCancelSM->source_addr_ton, ton_str, + pCancelSM->source_addr_npi, npi_str, + pCancelSM->source_addr); + smpp_send_ascout(debugBuf); + smpp_ton_to_string(ton_str, pCancelSM->dest_addr_ton); + smpp_npi_to_string(npi_str, pCancelSM->dest_addr_npi); + sprintf(debugBuf, "dest_addr_ton: 0x%x - %s,\tdest_addr_npi: 0x%x - %s,\tdestination_addr: %s\t", + pCancelSM->dest_addr_ton, ton_str, + pCancelSM->dest_addr_npi, npi_str, + pCancelSM->destination_addr); + smpp_send_ascout(debugBuf); + } + #endif + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive CANCEL_SM: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive CANCEL_SM: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_CANCEL_SM)); + break; + case CANCEL_SM_RESP: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = CancelSMResp; + /* fill with SMPP_MSG data structure. */ + pCancelSMResp = &smppMsg.pdu.cancel_sm_resp; + smppMsg.message_type = 0x16; + + memcpy(&pCancelSMResp->head, &pData->head, 16); + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive CANCEL_SM_RESP: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive CANCEL_SM_RESP: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_CANCEL_SM_RESP)); + break; + case REPLACE_SM: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = ReplaceSM; + smpp_link[linkNo].seq_num = sequence_number; + + pMsg = pData->msg; + pReplaceSM = &smppMsg.pdu.replace_sm; + smppMsg.message_type = 0x17; + + memcpy(&pReplaceSM->head, &pData->head, 16); + + current_len = 0; + c_octet_string_len = 1; + for (i=0; i<6; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pReplaceSM->message_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pReplaceSM->source_addr_ton = *(pMsg+current_len); + current_len += 1; + pReplaceSM->source_addr_npi = *(pMsg+current_len); + current_len += 1; + c_octet_string_len = 1; + for (i=0; i<21; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pReplaceSM->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + c_octet_string_len = 1; + for (i=0; i<17; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pReplaceSM->schedule_delivery_time, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + c_octet_string_len = 1; + for (i=0; i<17; i++) + { + if (*(pMsg+current_len+i) != 0) c_octet_string_len++; + else break; + } + memcpy(pReplaceSM->validity_period, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + pReplaceSM->registered_delivery = *(pMsg+current_len); + current_len += 1; + pReplaceSM->sm_default_msg_id = *(pMsg+current_len); + current_len += 1; + pReplaceSM->sm_length = *(pMsg+current_len); + current_len += 1; + memcpy(pReplaceSM->short_message, pMsg+current_len, pReplaceSM->sm_length); + current_len += pReplaceSM->sm_length; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Mandatory parameters]\n"); + smpp_ton_to_string(ton_str, pReplaceSM->source_addr_ton); + smpp_npi_to_string(npi_str, pReplaceSM->source_addr_npi); + sprintf(debugBuf, "message_id: %s,\tsource_addr_ton: 0x%x - %s,\tsource_addr_npi: 0x%x - %s,\tsource_addr: %s\t", + pReplaceSM->message_id, + pReplaceSM->source_addr_ton, ton_str, + pReplaceSM->source_addr_npi, npi_str, + pReplaceSM->source_addr); + smpp_send_ascout(debugBuf); + sprintf(debugBuf, "schedule_delivery_time: %s,\tvalidity_period: %s,\tregistered_delivery: 0x%02X,\tsm_default_msg_id: 0x%02X, sm_length: 02%02X, short_message: %s\n", + pReplaceSM->schedule_delivery_time, + pReplaceSM->validity_period, + pReplaceSM->registered_delivery, + pReplaceSM->sm_default_msg_id, + pReplaceSM->sm_length, + pReplaceSM->short_message); + smpp_send_ascout(debugBuf); + } + #endif + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive REPLACE_SM: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive REPLACE_SM: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_REPLACE_SM)); + break; + case REPLACE_SM_RESP: + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = ReplaceSMResp; + /* fill with SMPP_MSG data structure. */ + pReplaceSMResp = &smppMsg.pdu.replace_sm_resp; + smppMsg.message_type = 0x18; + memcpy(&pReplaceSMResp->head, &pData->head, 16); + if(callBackFunc[linkNo].data_proc!= NULL) + callBackFunc[linkNo].data_proc(linkNo, (SMPP_MSG *)&smppMsg, sizeof(PDU_REPLACE_SM_RESP)); + break; + case UNBIND: + if (16 != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive UNBIND: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (16 != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive UNBIND: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = Unbind; + smpp_link[linkNo].seq_num = sequence_number; + break; + case UNBIND_RESP: + if (16 != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive UNBIND_RESP: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (16 != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive UNBIND_RESP: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = UnbindResp; + break; + case GENERIC_NAK: + if (16 != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive GENERIC_NAK: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (16 != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive GENERIC_NAK: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = GenericNak; + smpp_link[linkNo].seq_num = sequence_number; + break; + case OUTBIND: + pMsg = pData->msg; + pOutbind = &smppMsg.pdu.outbind; + smpp_link[linkNo].seq_num = sequence_number; + + /* mandatory parameter */ + + current_len = 0; + + /* system id */ + c_octet_string_len = 1; + for (i=0; i<16; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pOutbind->system_id, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* password */ + c_octet_string_len = 1; + for (i=0; i<9; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pOutbind->password, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive OUTBIND: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive OUTBIND: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + if (strcmp(pOutbind->system_id, smpp_param[linkNo].sys_id) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive OUTBIND: system_id = %s, sys_id in param=%s\n", + linkNo, + pOutbind->system_id, + smpp_param[linkNo].sys_id); + smpp_send_error(debugBuf); + } + #endif +// smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVSYSID); + return 0; + } + + if (strcmp(pOutbind->password, smpp_param[linkNo].password) != 0) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg]link %d receive OUTBIND: password = %s, password in param=%s\n", + linkNo, + pOutbind->password, + smpp_param[linkNo].password); + smpp_send_error(debugBuf); + } + #endif +// smpp_sendBindResp(linkNo, BindReceiverResp, ESME_RINVPASWD); + return 0; + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = Outbind; + break; + case ALERT_NOTIFICATION: + pMsg = pData->msg; + pAlertNotification = &smppMsg.pdu.alert_notification; + smpp_link[linkNo].seq_num = sequence_number; + + /* mandatory parameter */ + + current_len = 0; + + /* addr_ton */ + pAlertNotification->source_addr_ton = *(pMsg+current_len); + current_len += 1; + + /* addr_npi */ + pAlertNotification->source_addr_npi = *(pMsg+current_len); + current_len += 1; + + /* source_addr */ + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pAlertNotification->source_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + /* esme_addr_ton */ + pAlertNotification->esme_addr_ton = *(pMsg+current_len); + current_len += 1; + + /* esme_addr_npi */ + pAlertNotification->esme_addr_npi = *(pMsg+current_len); + current_len += 1; + + /* esme_addr */ + c_octet_string_len = 1; + for (i=0; i<65; i++) + { + if (pMsg[current_len+i] != 0) c_octet_string_len++; + else break; + } + memcpy(pAlertNotification->esme_addr, pMsg+current_len, c_octet_string_len); + current_len += c_octet_string_len; + + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_ton_to_string(ton_str, pAlertNotification->source_addr_ton); + smpp_npi_to_string(npi_str, pAlertNotification->source_addr_npi); + sprintf(debugBuf, "[Mandatory parameters]\nsource_addr_ton: 0x%x - %s, source_addr_npi: 0x%x - %s, source_addr: %s", + pAlertNotification->source_addr_ton, ton_str, + pAlertNotification->source_addr_npi, npi_str, + pAlertNotification->source_addr + ); + smpp_send_ascout(debugBuf); + smpp_ton_to_string(ton_str, pAlertNotification->esme_addr_ton); + smpp_npi_to_string(npi_str, pAlertNotification->esme_addr_npi); + sprintf(debugBuf, "esme_addr_ton: 0x%x - %s, esme_addr_npi: 0x%x - %s, esme_addr: %s\n", + pAlertNotification->esme_addr_ton, ton_str, + pAlertNotification->esme_addr_npi, npi_str, + pAlertNotification->esme_addr); + smpp_send_ascout(debugBuf); + } + #endif + + /* Optional parameter */ + if (current_len < command_length - 16) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + smpp_send_ascout("[Optional parameters]\n"); + } + #endif + + memset(opt_param, 0, sizeof(SMPP_OPTIONAL_PARAMETER) * SMPP_OPT_PARAM_NUM); + opt_num = smpp_decode_optional_parameter(opt_param, pMsg+current_len, command_length - current_len - 16); + for (i=0; ims_availability_status, &opt_param[i].value, opt_param[i].len); + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "ms_availability_status: 0x%02X\n", pAlertNotification->ms_availability_status); + smpp_send_ascout(debugBuf); + } + #endif + break; + default: + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, + "Optional parameter not allowed in ALERT_NOTIFICATION. tag=0x%02X", + opt_param[i].tag); + smpp_send_error(debugBuf); + } + #endif + return 0; + } + } + } + + current_len += 16; + if (current_len != command_length) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive ALERT_NOTIFICATION: decode length = %d, command length=%u\n", + linkNo, + current_len, + command_length); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVCMDLEN, 0); + return 0; + } + else if (current_len != len) + { + #ifdef SMPP_DEBUG + if ((smppDebug.debug_switch == 1) || (smppDebug.link_switch[linkNo] == 1)) + { + sprintf(debugBuf, "[smpp_decode_msg] link %d receive ALERT_NOTIFICATION: decode length = %d, message length=%d\n", + linkNo, + current_len, + len); + smpp_send_error(debugBuf); + } + #endif + smpp_sendGenericNack(linkNo, ESME_RINVMSGLEN, 0); + return 0; + } + + inter_head[linkNo] = (inter_head[linkNo]+1)&0x7; + interEvent[linkNo][inter_head[linkNo]] = AlertNotification; + break; + default: + smpp_sendGenericNack(linkNo, ESME_RINVCMDID, sequence_number); + break; + } + + #ifdef SMPP_PRINT_SCREEN +// printf("link %d interEvent[%d] = %d, exterEvent[%d] = %d\n", +// linkNo, +// inter_head[linkNo], +// interEvent[linkNo][inter_head[linkNo]], +// exter_head[linkNo], +// exterEvent[linkNo][inter_head[linkNo]]); + #endif //end ifdef SMPP_PRINT_SCREEN + + return 1; +} + +void smpp_sendBind(int linkNo, int event_id) +{ + SMPP_MSG smppMsg; + PDU_BIND *pBind; + + switch (event_id) + { + case BindTransmitter: + pBind = &smppMsg.pdu.bind_transmitter; + pBind->head.command_id = htonl(BIND_TRANSMITTER); + pBind->head.command_status = 0; + pBind->head.sequence_number = htonl(smpp_getSequenceNumber(linkNo)); + + memcpy(pBind->system_id, smpp_param[linkNo].sys_id, 16); + memcpy(pBind->password, smpp_param[linkNo].password, 9); + memcpy(pBind->system_type, smpp_param[linkNo].system_type, 13); + pBind->interface_version = 0x34; + pBind->addr_ton = 0x1; + pBind->addr_npi = 0x1; + memcpy(pBind->address_range,"888",sizeof(pBind->address_range)); +// printf("[smpp]link %d send bind transmitter.\n", linkNo); + break; + case BindReceiver: + pBind = &smppMsg.pdu.bind_receiver; + pBind->head.command_id = htonl(BIND_RECEIVER); + pBind->head.command_status = 0; + pBind->head.sequence_number = htonl(smpp_getSequenceNumber(linkNo)); + + memcpy(pBind->system_id, smpp_param[linkNo].sys_id, 16); + memcpy(pBind->password, smpp_param[linkNo].password, 9); + memcpy(pBind->system_type, smpp_param[linkNo].system_type, 13); + pBind->interface_version = 0x34; + pBind->addr_ton = 0x1; + pBind->addr_npi = 0x1; + memcpy(pBind->address_range,"888",sizeof(pBind->address_range)); +// printf("[smpp]link %d send bind receiver.\n", linkNo); + break; + case BindTransceiver: + pBind = &smppMsg.pdu.bind_transceiver; + pBind->head.command_id = htonl(BIND_TRANSCEIVER); + pBind->head.command_status = 0; + pBind->head.sequence_number = htonl(smpp_getSequenceNumber(linkNo)); + + memcpy(pBind->system_id, smpp_param[linkNo].sys_id, 16); + memcpy(pBind->password, smpp_param[linkNo].password, 9); + memcpy(pBind->system_type, smpp_param[linkNo].system_type, 13); + pBind->interface_version = 0x34; + pBind->addr_ton = 0x1; + pBind->addr_npi = 0x1; + memcpy(pBind->address_range,"888",sizeof(pBind->address_range)); +// printf("[smpp]link %d send bind transceiver.\n", linkNo); + break; + default: + return; + } + smpp_encode_msg(linkNo, &smppMsg, event_id); +} + +void smpp_sendBindResp(int linkNo, int event_id, DWORD command_status) +{ + SMPP_MSG smppMsg; + + switch (event_id) + { + case BindTransmitterResp: + smppMsg.pdu.bind_transmitter_resp.head.command_id = htonl(BIND_TRANSMITTER_RESP); + smppMsg.pdu.bind_transmitter_resp.head.command_status = htonl(command_status); + smppMsg.pdu.bind_transmitter_resp.head.sequence_number = htonl(smpp_link[linkNo].seq_num); + memcpy(smppMsg.pdu.bind_transmitter_resp.system_id, smpp_param[linkNo].sys_id, 16); + smppMsg.pdu.bind_transmitter_resp.sc_interface_version = SMPP_VERSION; +// printf("link %d send BindTransmitterResp.\n", linkNo); + break; + case BindReceiverResp: + smppMsg.pdu.bind_receiver_resp.head.command_id = htonl(BIND_RECEIVER_RESP); + smppMsg.pdu.bind_receiver_resp.head.command_status = htonl(command_status); + smppMsg.pdu.bind_receiver_resp.head.sequence_number = htonl(smpp_link[linkNo].seq_num); + memcpy(smppMsg.pdu.bind_receiver_resp.system_id, smpp_param[linkNo].sys_id, 16); + smppMsg.pdu.bind_transmitter_resp.sc_interface_version = SMPP_VERSION; +// printf("link %d send BindReceiverResp.\n", linkNo); + break; + case BindTransceiverResp: + smppMsg.pdu.bind_transceiver_resp.head.command_id = htonl(BIND_TRANSCEIVER_RESP); + smppMsg.pdu.bind_transceiver_resp.head.command_status = htonl(command_status); + smppMsg.pdu.bind_transceiver_resp.head.sequence_number = htonl(smpp_link[linkNo].seq_num); + memcpy(smppMsg.pdu.bind_transceiver_resp.system_id, smpp_param[linkNo].sys_id, 16); + smppMsg.pdu.bind_transmitter_resp.sc_interface_version = SMPP_VERSION; +// printf("link %d send BindTransceiverResp.\n", linkNo); + break; + default: +// printf("[ERROR]send bind resp. no such command id.(=%d)\n", event_id); + break; + } + smpp_encode_msg(linkNo, &smppMsg, event_id); +} + +void smpp_sendUnbind(int linkNo) +{ + SMPP_MSG smppMsg; + + smppMsg.pdu.unbind.head.command_length = htonl(sizeof(PDU_UNBIND)); + smppMsg.pdu.unbind.head.command_id = htonl(UNBIND); + smppMsg.pdu.unbind.head.command_status = 0; + smppMsg.pdu.unbind.head.sequence_number = htonl(smpp_getSequenceNumber(linkNo)); + + smpp_encode_msg(linkNo, &smppMsg, Unbind); +} + +void smpp_sendUnbindResp(int linkNo) +{ + SMPP_MSG smppMsg; + + smppMsg.pdu.unbind_resp.head.command_length = htonl(sizeof(PDU_UNBIND_RESP)); + smppMsg.pdu.unbind_resp.head.command_id = htonl(UNBIND_RESP); + smppMsg.pdu.unbind_resp.head.command_status = 0; + smppMsg.pdu.unbind_resp.head.sequence_number = htonl(smpp_link[linkNo].seq_num); + + smpp_encode_msg(linkNo, &smppMsg, UnbindResp); +} + +void smpp_sendEnquireLink(int linkNo) +{ + SMPP_MSG smppMsg; + + smppMsg.pdu.enquire_link.head.command_length = htonl(sizeof(PDU_ENQUIRE_LINK)); + smppMsg.pdu.enquire_link.head.command_id = htonl(ENQUIRE_LINK); + smppMsg.pdu.enquire_link.head.command_status = 0; + smppMsg.pdu.enquire_link.head.sequence_number = htonl(smpp_getSequenceNumber(linkNo)); +// printf("link %d send enquire link.\n", linkNo); + smpp_encode_msg(linkNo, &smppMsg, EnquireLink); +} + +void smpp_sendEnquireLinkResp(int linkNo) +{ + SMPP_MSG smppMsg; + + smppMsg.pdu.enquire_link_resp.head.command_length = htonl(sizeof(PDU_ENQUIRE_LINK_RESP)); + smppMsg.pdu.enquire_link_resp.head.command_id = htonl(ENQUIRE_LINK_RESP); + smppMsg.pdu.enquire_link_resp.head.command_status = htonl(ESME_ROK); + smppMsg.pdu.enquire_link_resp.head.sequence_number = htonl(smpp_link[linkNo].seq_num); + //printf("link %d send enquire link resp.\n", linkNo); + smpp_encode_msg(linkNo, &smppMsg, EnquireLinkResp); +} + +void smpp_sendOutbind(int linkNo) +{ + SMPP_MSG smppMsg; + + smppMsg.pdu.outbind.head.command_length = htonl(sizeof(PDU_OUTBIND)); + smppMsg.pdu.outbind.head.command_id = htonl(OUTBIND); + smppMsg.pdu.outbind.head.command_status = 0; + smppMsg.pdu.outbind.head.sequence_number = htonl(smpp_getSequenceNumber(linkNo)); + + strcpy(smppMsg.pdu.outbind.system_id,smpp_param[linkNo].sys_id); + memcpy(smppMsg.pdu.outbind.password,smpp_param[linkNo].password,sizeof(smppMsg.pdu.outbind.password)); + + //printf("link %d send OUTBIND.\n", linkNo); + smpp_encode_msg(linkNo, &smppMsg, Outbind); +} + +void smpp_sendGenericNack(int linkNo, DWORD command_status, DWORD sequence_number) +{ + SMPP_MSG smppMsg; + + smppMsg.pdu.generic_nack.head.command_length = htonl(sizeof(PDU_GENERIC_NACK)); + smppMsg.pdu.generic_nack.head.command_id = htonl(GENERIC_NAK); + smppMsg.pdu.generic_nack.head.command_status = htonl(command_status); + smppMsg.pdu.generic_nack.head.sequence_number = htonl(sequence_number); + + smpp_encode_msg(linkNo, &smppMsg, UnknownCommandID); +} + +void smpp_sendResponse(int linkNo, DWORD command_id, DWORD command_status, DWORD sequence_number) +{ + SMPP_MSG smppMsg; + + switch (command_id) + { + case SUBMIT_SM_RESP: + smppMsg.pdu.submit_sm_resp.head.command_length = htonl(16); + smppMsg.pdu.submit_sm_resp.head.command_id = htonl(SUBMIT_SM_RESP); + smppMsg.pdu.submit_sm_resp.head.command_status = htonl(command_status); + smppMsg.pdu.submit_sm_resp.head.sequence_number = htonl(sequence_number); + + smpp_encode_msg(linkNo, &smppMsg, SubmitSMResp); + break; + case DELIVER_SM_RESP: + smppMsg.pdu.deliver_sm_resp.head.command_length = htonl(16); + smppMsg.pdu.deliver_sm_resp.head.command_id = htonl(DELIVER_SM_RESP); + smppMsg.pdu.deliver_sm_resp.head.command_status = htonl(command_status); + smppMsg.pdu.deliver_sm_resp.head.sequence_number= htonl(sequence_number); + + smpp_encode_msg(linkNo, &smppMsg, DeliverSMResp); + break; + case DATA_SM_RESP: + smppMsg.pdu.data_sm_resp.head.command_length = htonl(16); + smppMsg.pdu.data_sm_resp.head.command_id = htonl(DATA_SM_RESP); + smppMsg.pdu.data_sm_resp.head.command_status = htonl(command_status); + smppMsg.pdu.data_sm_resp.head.sequence_number = htonl(sequence_number); + + smpp_encode_msg(linkNo, &smppMsg, DataSMResp); + break; + default: + break; + } +} diff --git a/plat/smpp/ut/conf/MIB_files/.svn/all-wcprops b/plat/smpp/ut/conf/MIB_files/.svn/all-wcprops new file mode 100644 index 0000000..ba67447 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/all-wcprops @@ -0,0 +1,95 @@ +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files +END +mib_list_file.txt +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/mib_list_file.txt +END +WXC2-SS7-MIB.txt +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-SS7-MIB.txt +END +Special_App-SMI.txt +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/Special_App-SMI.txt +END +System_IP_List.txt +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/System_IP_List.txt +END +WXC2-MSC-MIB.txt +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-MSC-MIB.txt +END +WXC2-SMI.txt +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-SMI.txt +END +WXC2-HLR-MIB.txt +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-HLR-MIB.txt +END +menu_page +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/menu_page +END +menu_tree.txt +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/menu_tree.txt +END +WXC2-PPS-MIB.txt +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-PPS-MIB.txt +END +WXC2-MSS-MIB.txt +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-MSS-MIB.txt +END +WXC2-SMSC-MIB.txt +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-SMSC-MIB.txt +END +IWV-SMI.txt +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/IWV-SMI.txt +END +WXC2-AUC-MIB.txt +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/WXC2-AUC-MIB.txt +END +mib_write_tree.txt +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/smpp/ut/conf/MIB_files/mib_write_tree.txt +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/entries b/plat/smpp/ut/conf/MIB_files/.svn/entries new file mode 100644 index 0000000..698064a --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/entries @@ -0,0 +1,538 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/smpp/ut/conf/MIB_files +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +mib_list_file.txt +file + + + + +2012-12-28T03:06:04.156250Z +e59e7013ff47d5331bc5e68f42248885 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +259 + +WXC2-SS7-MIB.txt +file + + + + +2012-12-28T03:06:04.171875Z +91d2557ea5be19fe06b92e2c879d8377 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +93367 + +Special_App-SMI.txt +file + + + + +2012-12-28T03:06:04.187500Z +97ed2af0dacccade5e3baab77ca99295 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +932 + +System_IP_List.txt +file + + + + +2012-12-28T03:06:04.203125Z +7f68bfdab1c0892d2391924bd1115f73 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +888 + +WXC2-MSC-MIB.txt +file + + + + +2012-12-28T03:06:04.203125Z +51e7fa91629d05cf8eca01f20d967fc8 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +102848 + +WXC2-SMI.txt +file + + + + +2012-12-28T03:06:04.234375Z +2e85c17d3dc4bb21d376a86eb9a5f849 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1107 + +WXC2-HLR-MIB.txt +file + + + + +2012-12-28T03:06:04.250000Z +12831926c39eb44e7d775167b0ed38ce +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +51898 + +menu_page +file + + + + +2012-12-28T03:06:04.171875Z +a4c3041b9ba49e5e98a6c7888e52aa7b +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +528 + +menu_tree.txt +file + + + + +2012-12-28T03:06:04.187500Z +addab8c771a403371f6b208388c37f8a +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +33070 + +WXC2-PPS-MIB.txt +file + + + + +2012-12-28T03:06:04.218750Z +d3905e6500df6a9afe34b0e128f6a8b4 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +390028 + +WXC2-MSS-MIB.txt +file + + + + +2012-12-28T03:06:04.218750Z +6629dfee3fa27b4fda3b74d5bcb3f6a1 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1326 + +WXC2-SMSC-MIB.txt +file + + + + +2012-12-28T03:06:04.250000Z +fac370b62b453bf23d5d43e5c47e0a10 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +5823 + +IWV-SMI.txt +file + + + + +2012-12-28T03:06:04.234375Z +98316bf7b30187298164c96030583d89 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1036 + +WXC2-AUC-MIB.txt +file + + + + +2012-12-28T03:06:04.265625Z +35cb757ffc0367d867e78026b8d9996b +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +10058 + +mib_write_tree.txt +file + + + + +2012-12-28T03:06:04.265625Z +ca660623f2314251a90d317e99acdf64 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +639972 + diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/IWV-SMI.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/IWV-SMI.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/IWV-SMI.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/Special_App-SMI.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/Special_App-SMI.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/Special_App-SMI.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/System_IP_List.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/System_IP_List.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/System_IP_List.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-AUC-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-AUC-MIB.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-AUC-MIB.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-HLR-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-HLR-MIB.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-HLR-MIB.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSC-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSC-MIB.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSC-MIB.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSS-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSS-MIB.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-MSS-MIB.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-PPS-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-PPS-MIB.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-PPS-MIB.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMI.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMI.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMI.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMSC-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMSC-MIB.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SMSC-MIB.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SS7-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SS7-MIB.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/WXC2-SS7-MIB.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_page.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_page.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_tree.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_tree.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/menu_tree.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_list_file.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_list_file.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_list_file.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_write_tree.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_write_tree.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/prop-base/mib_write_tree.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/IWV-SMI.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/IWV-SMI.txt.svn-base new file mode 100644 index 0000000..b5269e3 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/IWV-SMI.txt.svn-base @@ -0,0 +1,40 @@ +-- ***************************************************************** +-- IWV-SMI: interWAVE Enterprise Structure of Management Information +-- +-- draft November 2000, Huang qilong +-- 1st November 2004, Sheng Xueqiang +-- +-- Copyright (c) 2000 by interWAVE, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- + +IWV-SMI DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, + OBJECT-IDENTITY, + enterprises + FROM SNMPv2-SMI; + +IWV MODULE-IDENTITY + LAST-UPDATED "0411170000Z" + ORGANIZATION "interWAVE, Inc." + CONTACT-INFO + "http://www.iwv.com" + DESCRIPTION + "The Structure of Management Information for the interWAVE enterprise." + REVISION "200411170000Z" + DESCRIPTION + "1st version of this MIB module." + ::= { enterprises 1373 } -- assigned by IANA + + +IWV_Products OBJECT-IDENTITY + STATUS current + DESCRIPTION + "iwvProducts is the root OBJECT IDENTIFIER from which sysObjectID values are assigned. Actual values are defined in IWV-PRODUCTS-MIB." + ::= { IWV 1 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/Special_App-SMI.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/Special_App-SMI.txt.svn-base new file mode 100644 index 0000000..ad05aa6 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/Special_App-SMI.txt.svn-base @@ -0,0 +1,43 @@ +-- ***************************************************************** +-- Special_App-SMI: WXC2 Structure of Management Information +-- +-- draft November 2004, Sheng Xueqiang +-- +-- Copyright (c) 2004 by interWAVE, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- + +Special_App-SMI DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, + OBJECT-IDENTITY, + FROM SNMPv2-SMI + IWV_Products + FROM IWV-SMI; + +Special_App MODULE-IDENTITY + LAST-UPDATED "0411180000Z" + ORGANIZATION "interWAVE, Inc." + CONTACT-INFO + "http://www.iwv.com" + DESCRIPTION + "The Structure of Management Information for the Special Application of interWAVE enterprise." + REVISION "200411180000Z" + DESCRIPTION + "1st version of this MIB module." + ::= { IWV_Products 2 } + +-- CNF Center +-- IWF +IWF OBJECT-IDENTITY + STATUS current + DESCRIPTION + "IWF " + ::= { Special_App 8 } + +-- PPP Route + +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/System_IP_List.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/System_IP_List.txt.svn-base new file mode 100644 index 0000000..577452c --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/System_IP_List.txt.svn-base @@ -0,0 +1,26 @@ +// host ip +// "//" is the annotation characters; ";" is the septation characters; +// Please put the localhost subsystem ip at the first of the group ip on one subsystem +MTP3_0_0 mss-0 ; LocalHost; +MTP3_1_0 mss-1 ; 172.18.133.1; +MTP3_2_0 -- ; 172.18.123.1; +MTP3_3_0 -- ; 172.18.143.1; +SCCP_0_0 mss-0 ; LOCALHOST; +SCCP_1_0 mss-1 ; 172.18.133.1; +XAPP_0_0 MSS-0 ; localhost; +XAPP_1_0 MSS-1 ; 172.18.133.1; +SMPP_0_0 SMPP-0; LocalHost; +MSC_0_0 -- ; LocalHost; +MSC_1_0 -- ; 172.18.133.1; +CCF(MSC)_0_0 --; LocalHost; +CCF(MSC)_0_1 --; 172.18.133.1; +VLR_0_0 VLR-0 ; LocalHost; +VLR_1_0 VLR-1 ; 172.18..1; +HLR_0_0 -- ; LocalHost; +HLR_1_0 -- ; 172.18.234.230; +AUC_0_0 -- ; LocalHost; +AUC_1_0 -- ; 172.18.234.230; +SMSC_0_0 -- ; LocalHost; +SMSC_1_0 -- ; 172.18.234.230; +PPS_0_0 -- ; LocalHost; +PPS_1_0 -- ; 172.18.234.230; diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-AUC-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-AUC-MIB.txt.svn-base new file mode 100644 index 0000000..a78176a --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-AUC-MIB.txt.svn-base @@ -0,0 +1,437 @@ +alvr1188-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +AUC OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for AUC . + " + ::= { App 4 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for AUC . + " + ::= { AUC 2 } + +Public_parameter OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Public_parameter for AUC . + " + ::= { Configuration 1 } + + +SSD OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]share SSD + { + [u]0.0-0.7 + [u]select + [v]0[opt]not share + [v]1[opt]share + } + + [2]Update SSD timer + { + [u]1.0-2.7 + [u]input + [v]toDec-high-0 + } + [3]reserved + { + [u]3.0-7.7 + [u]select + } + Remark: SSD + [End] + " + ::= { Public_parameter 2 } + +Count OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]Count Match Range + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + + [2]reserved + { + [u]1.0-7.7 + [u]select + } + Remark: Count. + [End] + " + ::= { Public_parameter 3 } + +Failures OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: + [1]AUTHR Mismatch + { + [u]0.0-0.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + + [2]Count Mismatch + { + [u]1.0-1.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [3]Unique Challenge Failure + { + [u]2.0-2.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [4]SSD Update Failure + { + [u]3.0-3.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [5]Count Update Failure + { + [u]4.0-4.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [6]Missing AUTH Parameters + { + [u]5.0-5.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + + [7]reserved + { + [u]6.0-7.7 + [u]select + } + + Remark: Count. + [End] + " + ::= { Public_parameter 4 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management . + " + ::= { Configuration 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag: S1.2 + Field: [1]Save parameters to HD + { + [u]00.0-00.2 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + [v]01[opt]Saving + [v]02[opt]Save succeeds + [v]03[opt]Save fails + } + [2]Save user data to HD&OMC + { + [u]00.3-00.5 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + [v]01[opt]Saving + [v]02[opt]Save succeeds + [v]03[opt]Save fails + } + [3]Reserved + { + [u]00.6-00.7 + [u]select + } + Remark: Command for AUC paramters and user data operation, and the result of command. + [End] + " + ::= { Management 2 } + +License_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]Licenses + { + [u]00.0-15.7 + [u]input + [v]keepHex-high-0 + } + Remark: 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of AUC subscribers for service provider. The new license can not support less AUC subscribers than what the old license supports. + [End] + " + ::= { Management 3 } + +MAX_License OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark: The maximum quantity of approved AUC subscribers determined by License control Read only. + [End] + " + ::= { Management 11 } + +Used_License OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Used Licenses + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of currently registered EIR subscribers (Read only). + [End] + " + ::= { Management 12 } + +User_information OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + User Information . + " + ::= { Management 13 } + +Provisioned_Users OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 000000 + Field: [1]Provisioned users + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of service enabled AUC subscribers (Read only). + [End] + " + ::= { User_information 1 } + +Version OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Version . + " + ::= { Management 14 } + +Software OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]System + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Module + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Test + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of AUC software (Read only). + System: System release version, based on basic function and structure. + Module: Software module version, based on software module. + Test: Test version, 0=Release version. 1=Test version. + [End] + " + ::= { Version 1 } + +User_data OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]System + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]User data + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Test + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of AUC subscriber data (Read only). + System: System release version, based on basic function and structure. + User data: Subscriber profile version, based on software module. + Test: Test version, 0=Release version. 1=Test version. + [End] + " + ::= { Version 2 } + +IMSI_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1000 + Length: 4 + Default: 00000000 + Field: [1]IMSI segment + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: IMSI segment table (Read only): + 100,000 IMSIs are subdivided into 1000 segments, each IMSI segment use the 8 most significant digits (from the 6th digit to 13th digit of 15-digit of IMSI) as the segment number. + IMSI=MCC(3)+MNC(2)+MSIN(10) + Segment number=the 8 most significant digits of the MSIN, each segment has 100 subscribers (00-99). + e.g. If IMSI=460002356090098 then it belongs to IMSI segemt 23560900 and its account number in that segment=98. 0=empty segment. + [End] + " + ::= { Management 15 } + +Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Status for AUC . + " + ::= { AUC 3 } + +Import_status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 12 + Default: 000000000000000000000000 + Field: + Remark: Import status. + [End] + " + ::= { Status 2 } +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-HLR-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-HLR-MIB.txt.svn-base new file mode 100644 index 0000000..a1469fa --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-HLR-MIB.txt.svn-base @@ -0,0 +1,2431 @@ +WXC2-HLR-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +HLR OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for HLR . + " + ::= { App 3 } + +Config OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for HLR . + " + ::= { HLR 2 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Public parameter . + " + ::= { Config 1 } + +HPLMN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 17 + Default: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + Field: [1]CC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]NDC + { + [u]02.0-04.7 + [u]input + [v]keepHex-low-E + } + [3]Start SN + { + [u]05.0-10.7 + [u]input + [v]keepHex-low-E + } + [4]End SN + { + [u]11.0-16.7 + [u]input + [v]keepHex-low-E + } + Remark: Define the SN (VLR phone number) range of the VLR in the HPLMN (home PLMN) by specifying the start and end phone number of the range. + MSISDN=CC(country code)+NDC(National Destination Code)+SN. + All VLRs within a HPLMN have the same CC and NDC but the different SN. The SN of all VLR in a HPLMN must lie within the defined SN range. + Byte0-1=Country code. + Byte2-3=National destination code. + Byte4-9=Start SN of the VLR SN. + Byte10-15=End SN of the VLR SN. + e.g. For China country code=86, Shanghai national destination code=21, VLR SN=26060888: + Byte0-1=86EE, + Byte2-3=21EE, + SN=26060888, + Else=E. + [End] + " + ::= { Public_Param 11 } + +VPLMNs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 17 + Default: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + Field: [1]CC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]NDC + { + [u]02.0-04.7 + [u]input + [v]keepHex-low-E + } + [3]Start SN + { + [u]05.0-10.7 + [u]input + [v]keepHex-low-E + } + [4]End SN + { + [u]11.0-16.7 + [u]input + [v]keepHex-low-E + } + Remark: Define all connected VPLMNs (up tp 256) by specifying all VLR zones included in these VPLMNs. Each VLR zone is defined by its VLR MSISDN. MSISDN=CC+NDC+SN. All VLRs within a same VPLMN have the CC and NDC but the different SN. A VPLMN contains a group of VLRs whose SN is included in the defined SN range, E=random digit. + This parameter also define two ranges of VLR CSRR (Country specific roaming restrictionszones) zones for each VPLMN. In these defined VLR CSRR zones all HPLMN subscribers may be subjected to country specific roaming restrictions. + For each VPLMN setup, the format is: + byte0=ISDN numbering plan, default=91. + byte1-2=country code, EEEE. + byte3-4=national destination code, EEEE. + byte5-10=start SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. + byte11-16=end SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. + byte17-22=start SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + byte23-28=end SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + byte29-34=start SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + byte35-40=end SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + E=random digit. + [End] + " + ::= { Public_Param 12 } + +CSRR_List OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 32 + Default: 0000000000000000000000000000000000000000000000000000000000000000 + Field: [1]VPLMN0 Roaming allowed + { + [u]31.0-31.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [2]VPLMN1 Roaming allowed + { + [u]31.1-31.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [3]VPLMN2 Roaming allowed + { + [u]31.2-31.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [4]VPLMN3 Roaming allowed + { + [u]31.3-31.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [5]VPLMN4 Roaming allowed + { + [u]31.4-31.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [6]VPLMN5 Roaming allowed + { + [u]31.5-31.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [7]VPLMN6 Roaming allowed + { + [u]31.6-31.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [8]VPLMN7 Roaming allowed + { + [u]31.7-31.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [9]VPLMN8 Roaming allowed + { + [u]30.0-30.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [10]VPLMN9 Roaming allowed + { + [u]30.1-30.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [11]VPLMN10 Roaming allowed + { + [u]30.2-30.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [12]VPLMN11 Roaming allowed + { + [u]30.3-30.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [13]VPLMN12 Roaming allowed + { + [u]30.4-30.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [14]VPLMN13 Roaming allowed + { + [u]30.5-30.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [15]VPLMN14 Roaming allowed + { + [u]30.6-30.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [16]VPLMN15 Roaming allowed + { + [u]30.7-30.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [17]VPLMN16 Roaming allowed + { + [u]29.0-29.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [18]VPLMN17 Roaming allowed + { + [u]29.1-29.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [19]VPLMN18 Roaming allowed + { + [u]29.2-29.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [20]VPLMN19 Roaming allowed + { + [u]29.3-29.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [21]VPLMN20 Roaming allowed + { + [u]29.4-29.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [22]VPLMN21 Roaming allowed + { + [u]29.5-29.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [23]VPLMN22 Roaming allowed + { + [u]29.6-29.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [24]VPLMN23 Roaming allowed + { + [u]29.7-29.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [25]VPLMN24 Roaming allowed + { + [u]28.0-28.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [26]VPLMN25 Roaming allowed + { + [u]28.1-28.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [27]VPLMN26 Roaming allowed + { + [u]28.2-28.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [28]VPLMN27 Roaming allowed + { + [u]28.3-28.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [29]VPLMN28 Roaming allowed + { + [u]28.4-28.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [30]VPLMN29 Roaming allowed + { + [u]28.5-28.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [31]VPLMN30 Roaming allowed + { + [u]28.6-28.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [32]VPLMN31 Roaming allowed + { + [u]28.7-28.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [33]VPLMN32 Roaming allowed + { + [u]27.0-27.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [34]VPLMN33 Roaming allowed + { + [u]27.1-27.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [35]VPLMN34 Roaming allowed + { + [u]27.2-27.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [36]VPLMN35 Roaming allowed + { + [u]27.3-27.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [37]VPLMN36 Roaming allowed + { + [u]27.4-27.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [38]VPLMN37 Roaming allowed + { + [u]27.5-27.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [39]VPLMN38 Roaming allowed + { + [u]27.6-27.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [40]VPLMN39 Roaming allowed + { + [u]27.7-27.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [41]VPLMN40 Roaming allowed + { + [u]26.0-26.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [42]VPLMN41 Roaming allowed + { + [u]26.1-26.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [43]VPLMN42 Roaming allowed + { + [u]26.2-26.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [44]VPLMN43 Roaming allowed + { + [u]26.3-26.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [45]VPLMN44 Roaming allowed + { + [u]26.4-26.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [46]VPLMN45 Roaming allowed + { + [u]26.5-26.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [47]VPLMN46 Roaming allowed + { + [u]26.6-26.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [48]VPLMN47 Roaming allowed + { + [u]26.7-26.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [49]VPLMN48 Roaming allowed + { + [u]25.0-25.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [50]VPLMN49 Roaming allowed + { + [u]25.1-25.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [51]VPLMN50 Roaming allowed + { + [u]25.2-25.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [52]VPLMN51 Roaming allowed + { + [u]25.3-25.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [53]VPLMN52 Roaming allowed + { + [u]25.4-25.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [54]VPLMN53 Roaming allowed + { + [u]25.5-25.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [55]VPLMN54 Roaming allowed + { + [u]25.6-25.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [56]VPLMN55 Roaming allowed + { + [u]25.7-25.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [57]VPLMN56 Roaming allowed + { + [u]24.0-24.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [58]VPLMN57 Roaming allowed + { + [u]24.1-24.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [59]VPLMN58 Roaming allowed + { + [u]24.2-24.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [60]VPLMN59 Roaming allowed + { + [u]24.3-24.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [61]VPLMN60 Roaming allowed + { + [u]24.4-24.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [62]VPLMN61 Roaming allowed + { + [u]24.5-24.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [63]VPLMN62 Roaming allowed + { + [u]24.6-24.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [64]VPLMN63 Roaming allowed + { + [u]24.7-24.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [65]VPLMN64 Roaming allowed + { + [u]23.0-23.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [66]VPLMN65 Roaming allowed + { + [u]23.1-23.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [67]VPLMN66 Roaming allowed + { + [u]23.2-23.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [68]VPLMN67 Roaming allowed + { + [u]23.3-23.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [69]VPLMN68 Roaming allowed + { + [u]23.4-23.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [70]VPLMN69 Roaming allowed + { + [u]23.5-23.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [71]VPLMN70 Roaming allowed + { + [u]23.6-23.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [72]VPLMN71 Roaming allowed + { + [u]23.7-23.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [73]VPLMN72 Roaming allowed + { + [u]22.0-22.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [74]VPLMN73 Roaming allowed + { + [u]22.1-22.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [75]VPLMN74 Roaming allowed + { + [u]22.2-22.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [76]VPLMN75 Roaming allowed + { + [u]22.3-22.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [77]VPLMN76 Roaming allowed + { + [u]22.4-22.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [78]VPLMN77 Roaming allowed + { + [u]22.5-22.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [79]VPLMN78 Roaming allowed + { + [u]22.6-22.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [80]VPLMN79 Roaming allowed + { + [u]22.7-22.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [81]VPLMN80 Roaming allowed + { + [u]21.0-21.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [82]VPLMN81 Roaming allowed + { + [u]21.1-21.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [83]VPLMN82 Roaming allowed + { + [u]21.2-21.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [84]VPLMN83 Roaming allowed + { + [u]21.3-21.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [85]VPLMN84 Roaming allowed + { + [u]21.4-21.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [86]VPLMN85 Roaming allowed + { + [u]21.5-21.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [87]VPLMN86 Roaming allowed + { + [u]21.6-21.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [88]VPLMN87 Roaming allowed + { + [u]21.7-21.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [89]VPLMN88 Roaming allowed + { + [u]20.0-20.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [90]VPLMN89 Roaming allowed + { + [u]20.1-20.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [91]VPLMN90 Roaming allowed + { + [u]20.2-20.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [92]VPLMN91 Roaming allowed + { + [u]20.3-20.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [93]VPLMN92 Roaming allowed + { + [u]20.4-20.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [94]VPLMN93 Roaming allowed + { + [u]20.5-20.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [95]VPLMN94 Roaming allowed + { + [u]20.6-20.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [96]VPLMN95 Roaming allowed + { + [u]20.7-20.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [97]VPLMN96 Roaming allowed + { + [u]19.0-19.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [98]VPLMN97 Roaming allowed + { + [u]19.1-19.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [99]VPLMN98 Roaming allowed + { + [u]19.2-19.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [100]VPLMN99 Roaming allowed + { + [u]19.3-19.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [101]VPLMN100 Roaming allowed + { + [u]19.4-19.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [102]VPLMN101 Roaming allowed + { + [u]19.5-19.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [103]VPLMN102 Roaming allowed + { + [u]19.6-19.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [104]VPLMN103 Roaming allowed + { + [u]19.7-19.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [105]VPLMN104 Roaming allowed + { + [u]18.0-18.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [106]VPLMN105 Roaming allowed + { + [u]18.1-18.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [107]VPLMN106 Roaming allowed + { + [u]18.2-18.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [108]VPLMN107 Roaming allowed + { + [u]18.3-18.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [109]VPLMN108 Roaming allowed + { + [u]18.4-18.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [110]VPLMN109 Roaming allowed + { + [u]18.5-18.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [111]VPLMN110 Roaming allowed + { + [u]18.6-18.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [112]VPLMN111 Roaming allowed + { + [u]18.7-18.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [113]VPLMN112 Roaming allowed + { + [u]17.0-17.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [114]VPLMN113 Roaming allowed + { + [u]17.1-17.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [115]VPLMN114 Roaming allowed + { + [u]17.2-17.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [116]VPLMN115 Roaming allowed + { + [u]17.3-17.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [117]VPLMN116 Roaming allowed + { + [u]17.4-17.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [118]VPLMN117 Roaming allowed + { + [u]17.5-17.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [119]VPLMN118 Roaming allowed + { + [u]17.6-17.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [120]VPLMN119 Roaming allowed + { + [u]17.7-17.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [121]VPLMN120 Roaming allowed + { + [u]16.0-16.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [122]VPLMN121 Roaming allowed + { + [u]16.1-16.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [123]VPLMN122 Roaming allowed + { + [u]16.2-16.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [124]VPLMN123 Roaming allowed + { + [u]16.3-16.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [125]VPLMN124 Roaming allowed + { + [u]16.4-16.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [126]VPLMN125 Roaming allowed + { + [u]16.5-16.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [127]VPLMN126 Roaming allowed + { + [u]16.6-16.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [128]VPLMN127 Roaming allowed + { + [u]16.7-16.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [129]VPLMN128 Roaming allowed + { + [u]15.0-15.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [130]VPLMN129 Roaming allowed + { + [u]15.1-15.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [131]VPLMN130 Roaming allowed + { + [u]15.2-15.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [132]VPLMN131 Roaming allowed + { + [u]15.3-15.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [133]VPLMN132 Roaming allowed + { + [u]15.4-15.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [134]VPLMN133 Roaming allowed + { + [u]15.5-15.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [135]VPLMN134 Roaming allowed + { + [u]15.6-15.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [136]VPLMN135 Roaming allowed + { + [u]15.7-15.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [137]VPLMN136 Roaming allowed + { + [u]14.0-14.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [138]VPLMN137 Roaming allowed + { + [u]14.1-14.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [139]VPLMN138 Roaming allowed + { + [u]14.2-14.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [140]VPLMN139 Roaming allowed + { + [u]14.3-14.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [141]VPLMN140 Roaming allowed + { + [u]14.4-14.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [142]VPLMN141 Roaming allowed + { + [u]14.5-14.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [143]VPLMN142 Roaming allowed + { + [u]14.6-14.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [144]VPLMN143 Roaming allowed + { + [u]14.7-14.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [145]VPLMN144 Roaming allowed + { + [u]13.0-13.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [146]VPLMN145 Roaming allowed + { + [u]13.1-13.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [147]VPLMN146 Roaming allowed + { + [u]13.2-13.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [148]VPLMN147 Roaming allowed + { + [u]13.3-13.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [149]VPLMN148 Roaming allowed + { + [u]13.4-13.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [150]VPLMN149 Roaming allowed + { + [u]13.5-13.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [151]VPLMN150 Roaming allowed + { + [u]13.6-13.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [152]VPLMN151 Roaming allowed + { + [u]13.7-13.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [153]VPLMN152 Roaming allowed + { + [u]12.0-12.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [154]VPLMN153 Roaming allowed + { + [u]12.1-12.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [155]VPLMN154 Roaming allowed + { + [u]12.2-12.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [156]VPLMN155 Roaming allowed + { + [u]12.3-12.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [157]VPLMN156 Roaming allowed + { + [u]12.4-12.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [158]VPLMN157 Roaming allowed + { + [u]12.5-12.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [159]VPLMN158 Roaming allowed + { + [u]12.6-12.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [160]VPLMN159 Roaming allowed + { + [u]12.7-12.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [161]VPLMN160 Roaming allowed + { + [u]11.0-11.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [162]VPLMN161 Roaming allowed + { + [u]11.1-11.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [163]VPLMN162 Roaming allowed + { + [u]11.2-11.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [164]VPLMN163 Roaming allowed + { + [u]11.3-11.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [165]VPLMN164 Roaming allowed + { + [u]11.4-11.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [166]VPLMN165 Roaming allowed + { + [u]11.5-11.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [167]VPLMN166 Roaming allowed + { + [u]11.6-11.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [168]VPLMN167 Roaming allowed + { + [u]11.7-11.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [169]VPLMN168 Roaming allowed + { + [u]10.0-10.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [170]VPLMN169 Roaming allowed + { + [u]10.1-10.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [171]VPLMN170 Roaming allowed + { + [u]10.2-10.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [172]VPLMN171 Roaming allowed + { + [u]10.3-10.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [173]VPLMN172 Roaming allowed + { + [u]10.4-10.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [174]VPLMN173 Roaming allowed + { + [u]10.5-10.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [175]VPLMN174 Roaming allowed + { + [u]10.6-10.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [176]VPLMN175 Roaming allowed + { + [u]10.7-10.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [177]VPLMN176 Roaming allowed + { + [u]09.0-09.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [178]VPLMN177 Roaming allowed + { + [u]09.1-09.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [179]VPLMN178 Roaming allowed + { + [u]09.2-09.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [180]VPLMN179 Roaming allowed + { + [u]09.3-09.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [181]VPLMN180 Roaming allowed + { + [u]09.4-09.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [182]VPLMN181 Roaming allowed + { + [u]09.5-09.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [183]VPLMN182 Roaming allowed + { + [u]09.6-09.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [184]VPLMN183 Roaming allowed + { + [u]09.7-09.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [185]VPLMN184 Roaming allowed] + { + [u]08.0-08.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [186]VPLMN185 Roaming allowed + { + [u]08.1-08.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [187]VPLMN186 Roaming allowed + { + [u]08.2-08.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [188]VPLMN187 Roaming allowed + { + [u]08.3-08.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [189]VPLMN188 Roaming allowed + { + [u]08.4-08.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [190]VPLMN189 Roaming allowed + { + [u]08.5-08.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [191]VPLMN190 Roaming allowed + { + [u]08.6-08.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [192]VPLMN191 Roaming allowed + { + [u]08.7-08.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [193]VPLMN192 Roaming allowed + { + [u]07.0-07.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [194]VPLMN193 Roaming allowed + { + [u]07.1-07.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [195]VPLMN194 Roaming allowed + { + [u]07.2-07.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [196]VPLMN195 Roaming allowed + { + [u]07.3-07.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [197]VPLMN196 Roaming allowed + { + [u]07.4-07.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [198]VPLMN197 Roaming allowed + { + [u]07.5-07.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [199]VPLMN198 Roaming allowed + { + [u]07.6-07.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [200]VPLMN199 Roaming allowed + { + [u]07.7-07.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [201]VPLMN200 Roaming allowed + { + [u]06.0-06.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [202]VPLMN201 Roaming allowed + { + [u]06.1-06.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [203]VPLMN202 Roaming allowed + { + [u]06.2-06.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [204]VPLMN203 Roaming allowed + { + [u]06.3-06.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [205]VPLMN204 Roaming allowed + { + [u]06.4-06.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [206]VPLMN205 Roaming allowed + { + [u]06.5-06.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [207]VPLMN206 Roaming allowed + { + [u]06.6-06.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [208]VPLMN207 Roaming allowed + { + [u]06.7-06.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [209]VPLMN208 Roaming allowed + { + [u]05.0-05.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [210]VPLMN209 Roaming allowed + { + [u]05.1-05.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [211]VPLMN210 Roaming allowed + { + [u]05.2-05.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [212]VPLMN211 Roaming allowed + { + [u]05.3-05.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [213]VPLMN212 Roaming allowed + { + [u]05.4-05.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [214]VPLMN213 Roaming allowed + { + [u]05.5-05.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [215]VPLMN214 Roaming allowed + { + [u]05.6-05.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [216]VPLMN215 Roaming allowed + { + [u]05.7-05.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [217]VPLMN216 Roaming allowed + { + [u]04.0-04.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [218]VPLMN217 Roaming allowed + { + [u]04.1-04.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [219]VPLMN218 Roaming allowed + { + [u]04.2-04.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [220]VPLMN219 Roaming allowed + { + [u]04.3-04.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [221]VPLMN220 Roaming allowed + { + [u]04.4-04.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [222]VPLMN221 Roaming allowed + { + [u]04.5-04.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [223]VPLMN222 Roaming allowed + { + [u]04.6-04.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [224]VPLMN223 Roaming allowed + { + [u]04.7-04.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [225]VPLMN224 Roaming allowed + { + [u]03.0-03.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [226]VPLMN225 Roaming allowed + { + [u]03.1-03.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [227]VPLMN226 Roaming allowed + { + [u]03.2-03.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [228]VPLMN227 Roaming allowed + { + [u]03.3-03.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [229]VPLMN228 Roaming allowed + { + [u]03.4-03.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [230]VPLMN229 Roaming allowed + { + [u]03.5-03.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [231]VPLMN230 Roaming allowed + { + [u]03.6-03.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [232]VPLMN231 Roaming allowed + { + [u]03.7-03.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [233]VPLMN232 Roaming allowed + { + [u]02.0-02.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [234]VPLMN233 Roaming allowed + { + [u]02.1-02.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [235]VPLMN234 Roaming allowed + { + [u]02.2-02.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [236]VPLMN235 Roaming allowed + { + [u]02.3-02.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [237]VPLMN236 Roaming allowed + { + [u]02.4-02.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [238]VPLMN237 Roaming allowed + { + [u]02.5-02.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [239]VPLMN238 Roaming allowed + { + [u]02.6-02.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [240]VPLMN239 Roaming allowed + { + [u]02.7-02.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [241]VPLMN240 Roaming allowed + { + [u]01.0-01.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [242]VPLMN241 Roaming allowed + { + [u]01.1-01.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [243]VPLMN242 Roaming allowed + { + [u]01.2-01.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [244]VPLMN243 Roaming allowed + { + [u]01.3-01.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [245]VPLMN244 Roaming allowed + { + [u]01.4-01.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [246]VPLMN245 Roaming allowed + { + [u]01.5-01.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [247]VPLMN246 Roaming allowed + { + [u]01.6-01.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [248]VPLMN247 Roaming allowed + { + [u]01.7-01.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [249]VPLMN248 Roaming allowed + { + [u]00.0-00.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [250]VPLMN249 Roaming allowed + { + [u]00.1-00.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [251]VPLMN250 Roaming allowed + { + [u]00.2-00.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [252]VPLMN251 Roaming allowed + { + [u]00.3-00.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [253]VPLMN252 Roaming allowed + { + [u]00.4-00.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [254]VPLMN253 Roaming allowed + { + [u]00.5-00.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [255]VPLMN254 Roaming allowed + { + [u]00.6-00.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [256]VPLMN255 Roaming allowed + { + [u]00.7-00.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + Remark: Define 8 CSRR (country specific roaming restriction) lists to confine the roaming range of a subscriber. + Each CSRR list defines the roaming restriction for 256 VPLMN ranges. + [End] + " + ::= { Public_Param 13 } + +Regional_Subs_List OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 255 + Length: 7 + Default: EEEEEEEEEEEEEE + Field: [1]Country Code + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]National Destination Code + { + [u]02.0-04.7 + [u]input + [v]keepHex-low-E + } + [3]Zone Code + { + [u]05.0-06.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the regional subscription zone code list. HLR supports up to 256 regional subscription zone code. + Regional subscription code = CC+NDC+zone code + [End] + " + ::= { Public_Param 14 } + +Licenses_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]Licenses + { + [u]00.0-07.7 + [u]input + [v]keepHex-high-0 + } + Remark: 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of HLR subscribers for service provider: + The new license can not support less HLR subscribers than what the old license supports. + [End] + " + ::= { Public_Param 15 } + +CDR_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]CDR control + { + [u]00.0-00.7 + [u]select + [v]00[opt]Off + [v]01[opt]On + } + Remark: HLR CDR generation flag: + Off=Not generate HLR CDR. + On=Generate HLR CDR. + [End] + " + ::= { Public_Param 16 } + +Feature_Code OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 64 + Default: 90EE68EE72EE92EE70EE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]CFB + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]CFD + { + [u]02.0-03.7 + [u]input + [v]keepHex-low-E + } + [3]CFNA + { + [u]04.0-05.7 + [u]input + [v]keepHex-low-E + } + [4]CFU + { + [u]06.0-07.7 + [u]input + [v]keepHex-low-E + } + [5]Call waiting + { + [u]08.0-09.7 + [u]input + [v]keepHex-low-E + } + [6]Reserved + { + [u]10.0-63.7 + [u]select + } + Remark: None. + [End] + " + ::= { Public_Param 27 } + + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management . + " + ::= { Config 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag: S1.2 + Field: [1]Save parameter to HD + { + [u]00.0-00.2 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + } + [2]Save subscriber data to HD&OMC + { + [u]00.3-00.5 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + } + [3]Reserved + { + [u]00.6-00.7 + [u]select + } + Remark: Bit0-2: HLR paramter save control: + Idle=no operation. + Save=Save parameters from HLR memory to HLR hard disk. + Bit3-5: HLR subscriber data save control: + Idle=no operation. + Save=Save HLR subscriber data from HLR memory to both HLR hard disk and OMC database. + Bit6-7: Reserved. + [End] + " + ::= { Management 2 } + +Subscriber_Import OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading Failed + } + [2]Total subscriber requested + { + [u]01.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]Total imported subscribers + { + [u]04.0-06.7 + [u]input + [v]toDec-high-0 + } + Remark: Progress and result of HLR subscriber import. + Byte0: Progress of HLR subscriber import. + Byte1-3: Total quantity of HLR subscribers requesting import. + Byte4-7: Quantity of successfully imported HLR subscribers. + [End] + " + ::= { Management 3 } + +Max_Licenses OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Max Licenses + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The maximum quantity of approved HLR subscribers determined by License control (Read Only). + [End] + " + ::= { Management 11 } + +Used_Licenses OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Used Licenses + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of currently registered HLR subscribers (Read Only). + [End] + " + ::= { Management 12 } + +Subscriber_Info OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subscriber information . + " + ::= { Management 13 } + +Provisioned_Subs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Provisioned Subs + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of service provisioned and active HLR subscribers (Read Only). + [End] + " + ::= { Subscriber_Info 1 } + +Registered_Subs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Registered Subs + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of registered (both active and inactive) HLR subscribers (Read Only). + [End] + " + ::= { Subscriber_Info 2 } + +Roaming_Subs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Roaming Subs + { + [u]00.0-03.7[u]input + [v]toDec-high-0 + } + Remark: The quantity of provisioned HLR subscribers currently roaming to VPLMNs (Read Only). + [End] + " + ::= { Subscriber_Info 3 } + +Version OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Version . + " + ::= { Management 14 } + +Software OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Release + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Version + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Slice + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of HLR software (Read Only): + Byte0: System release version number: + - Based on basic function and structure. + Byte1: Software module version number: + - Based on software module. + Byte2: Test version: + - 0=Release version number. + - 1=Test version number. + [End] + " + ::= { Version 1 } + +User_Data OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Release + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Version + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Slice + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of AUC subscriber data (Read Only): + System release version: Based on basic function and structure. + Subscriber data version: Based on software module. + Test version: 0=Release version 1=Test version + [End] + " + ::= { Version 2 } + +IMSI_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1000 + Length: 4 + Default: 00000000 + Field: [1]IMSI segment + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: MSISDN segment table (Read Only): + Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + [End] + " + ::= { Management 15 } + +MSISDN_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1000 + Length: 4 + Default: 00000000 + Field: [1]MSISDN segment + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: MSISDN segment table (Read Only): + Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + [End] + " + ::= { Management 16 } + +CNF_Applicant_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 9 + Default: 000000000000000000 + Field: [1]Charge Type + { + [u]00.0-00.7 + [u]select + [v]00[opt]Invalid user + [v]01[opt]Post-pay user + [v]02[opt]Prepaid user + } + [2]IMSI + { + [u]01.0-08.7 + [u]input + [v]keepHex-low-E + } + Remark: Display the IMSI and charge type of the latest conference applicant (Read Only). + [End] + " + ::= { Management 27 } +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSC-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSC-MIB.txt.svn-base new file mode 100644 index 0000000..a7a00f6 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSC-MIB.txt.svn-base @@ -0,0 +1,4084 @@ +WXC2-MSC-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +MSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for msc . + " + ::= { App 2 } +-- +-- sub system CCF(MSC) +-- + +CCF(MSC) OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for msc . + " + ::= { MSC 2 } + +CCF_Config OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for CCF . + " + ::= { CCF(MSC) 2 } + +-- +-- CCF -> Configuration -> Call Routing +-- + +Call_Routing OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Call Routing . + " + ::= { CCF_Config 1 } + +Prefix_Assignment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 8 + Default : EEEEEEEEEEEEEEEE + Field : [1]Prefix + { + [u]0.0-7.7 + [u]input + [v]keepHex-low-E + } + Remark: 4 bytes are used to set a 8-digit prefix for dialed number. + Prefix is the first layer for dialed number based call routing. If the dialed number of a call matches a pre-programmed prefix in this table, this call will be routed to a certain trunk group, subsequently that trunk group will route this call via a dedicated E1 port.This system has totally 256 prefixes. + Dialed number without matching a pre-programmed prefix will be routed to the default trunk group 0. + Prefix 252 is for default international call, all internation calls unable to be routed out will be routed from the trunk group assigned to prefix 252, keep default EEEEEEEE. + Prefix 253 is for default national call, all national calls unable to be routed out will be routed from the trunk group assigned to prefix 253, keep default EEEEEEEE. + Prefix 254 is for default subscriber call, all dialed MSISDN unable to be routed out will be routed from the trunk group assigned to prefix 254, keep default EEEEEEEE. + Prefix 255 is for unknown call, all unknown calls unable to be routed out will be routed from the trunk group assigned to prefix 255, keep default EEEEEEEE. + E=End tag, C='#', B='*'. + Default=0xEEEEEEEE. + [End] + " + ::= { Call_Routing 1 } + +Prefix_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 18 + Default : 2200EEEEEEEEEEEEEEEE010800EEEEEEEE03 + Flag : E10 + Field : [1]TON incoming call + { + [u]0.0-0.3 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [2]TON outgoing call + { + [u]0.4-0.7 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [3]Out trunk deletion count + { + [u]1.0-1.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [4]Out trunk insertion count + { + [u]1.4-1.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [5]Out trunk inserted digits + { + [u]2.0-9.7 + [u]input + [v]keepHex-low-E + } + [6]CDR on/off + { + [u]10.0-10.0 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [7]Reserved + { + [u]10.1-10.1 + [u]select + } + [8]Properties + { + [u]10.2-10.3 + [u]select + [v]0[opt]Trunk + [v]1[opt]MSISDN + [v]2[opt]MSRN + [v]3[opt]MSC + } + [9]Call type + { + [u]10.4-10.6 + [u]select + [v]0[opt]Normal Call + [v]1[opt]Emergency + [v]2[opt]MCT + [v]3[opt]VMS + [v]4[opt]IN + } + [10]Enable + { + [u]10.7-10.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } + [11]Length of dialed number + { + [u]11.0-11.7 + [u]input + [v]toDec-high-0 + } + [12]E.164 International deletion count + { + [u]12.0-12.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]Delete first one + [v]2[opt]Delete first two + [v]3[opt]Delete first three + [v]4[opt]Delete first four + [v]5[opt]Delete first five + [v]6[opt]Delete first six + [v]7[opt]Delete first seven + [v]8[opt]Delete first eight + } + [13]E.164 International insertion count + { + [u]12.4-12.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]Insert first one + [v]2[opt]Insert first two + [v]3[opt]Insert first three + [v]4[opt]Insert first four + [v]5[opt]Insert first five + [v]6[opt]Insert first six + [v]7[opt]Insert first seven + [v]8[opt]Insert first eight + } + [14]E.164 international inserted digits + { + [u]13.0-16.7 + [u]input + [v]keepHex-low-E + } + [15]Cli-type + { + [u]17.0-17.7 + [u]select + [v]0[opt]Sub + [v]1[opt]NDD + [v]2[opt]IDD + [v]3[opt]Unknown(local) + [v]4[opt]Unknown(NDD) + [v]5[opt]Unknown(IDD) + } + Remark: Enable: Y=prefix enable, N=prefix disable. + TON incoming call: Type of number for incoming call, include unknown, MSISDN, NDD and IDD. It is specified by originating node for terminating node to route this call with proper dialed number manipulation. + For system subscriber dialed prefix, always use unknown for In-TON except the prefix of international prefix beginning with a . For this kind of prefix (such as 86755832) we should set the In-TON as IDD to support dialing. + TON outgoing call: Type of number for outgoing call, include unknown, MSISDN, NDD and IDD. It specifies the type of an outgoing call for terminating node to route this call with proper dialed number manipulation. Generally the MSC uses IDD for outgoing call. + Out trunk deletion count: Quantity of deleted digit of a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no deletion, 1-8=delete first 1-8 digits. + Out trunk insertion count: Quantity of inserted digit for a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no insertion, 1-8=insert 1-8 digits from the beginning of this number. + Out trunk inserted digits: 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number. + CDR on/off: Turn on/off the CDR of dialed numbers beginning with this prefix. + Properties: Specify the properties of a prefix. Trunk=to PSTN, MSISDN=to A interface, MSRN=MS roaming number, MSC=to peer MSC. + Call type: Normal=no verification for MT, Emergency call=no verification for MO (free call), MCT=Malicious Call Trace, VMS call=send signaling carried DTMF to VMS. + Length of dialed number: Length of dialed number (1-32). + E.164 international deletion count: Quantity of deleted digit of E164 international number, always use IDD for outgoing call for PPS debiting. + E.164 international insertion count: Quantity of inserted digit of E164 international number, always use IDD for outgoing call for PPS debiting. + E.164 international inserted digits: Inserted digit to the E164 international number, 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number, always use IDD for outgoing call for PPS debiting. + [End] + " + ::= { Call_Routing 2 } + +Prefix_TG OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field: + [1]Assign TG to prefix + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a trunk group for each prefix for call routing, a single prefix points to only one trunk group, multiple prefix can be assigned the same trunk group, default is the no. of the prefix. + [End] + " + ::= { Call_Routing 3 } + +TG_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 10 + Default : 00000000000000000000000000 + Flag : E2 + Field: [1]DPC + { + [u]0.0-3.7 + [u]input + [v]keepHex-high-0 + } + [2]TG flag + { + [u]4.0-4.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]CDR on/off + { + [u]4.1-4.1 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [4]Announcement + { + [u]4.2-4.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [5]TG category + { + [u]4.3-4.5 + [u]select + [v]0[opt]PSTN + [v]1[opt]HPLMN + [v]2[opt]VHLMN + [v]3[opt]SUB + [v]4[opt]IP + [v]5[opt]Intercept + } + [6]Alternative TG flag + { + [u]4.6-4.6 + [u]select + [v]0[opt]Disable + [v]1[opt]enable + } + [7]Loopback + { + [u]4.7-4.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [8]Network indicator + { + [u]5.0-5.7 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [9]Circuit selection + { + [u]6.0-6.1 + [u]select + [v]0[opt]Clockwise + [v]1[opt]Anti-clockwise + [v]2[opt]Odd + [v]3[opt]Even + } + [10]Back off + { + [u]6.2-6.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [11]Reserved + { + [u]6.3-6.4 + [u]select + } + [12]MPTY + { + [u]6.5-6.5 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [13]Location + { + [u]6.6-6.7 + [u]select + [v]0[opt]MSC-0 + [v]1[opt]MSC-1 + [v]2[opt]Both + [v]3[opt]Spare + } + [14]Alternative TG + { + [u]7.0-7.7 + [u]input + [v]toDec-high-0 + } + [15]Tandem restriction + { + [u]8.0-8.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [16]Incoming Call type + { + [u]9.0-9.7 + [u]select + [v]0[opt]Normal + [v]1[opt]IN + } + Remark: DPC: Destination point code of this trunk group. + TG flag: enable or disable this trunk group. + CDR on/off: CDR on or off option for this trunk group. + Announcement: Voice announcement enable or disable for this trunk group. + TG category: PSTN=to PSTN, IP=to VMS and VPS, HPLMN=to HPLMN, VPLMN=to VPLMN, SUB=to BSC, Intercept=to intercept LEA + Alternative TG flag: Alternative trunk group enable or disable option. + Alternative TG: Alternative trunk group for backup purpose. + Loop back: Incoming call loop back enable or disable, used for MSC loop back. + Network indicator: Specify network type, International, International spare , National, National spare. + Circuit selection: Preferred circuit selection mode, include clockwise, anti-clockwise, odd and even. + Back off: Back off on or off when simultaneously select the same channel with the opposite side. + Location: For normal trunk group, select Both. For a trunk group to a VPS, configure this trunk group as MSC0 or MSC1. + MPTY: Multi-party call enable or disable. For all trunk groups to BSC, select Enable. + Tandem restriction:Y: Tandem disabled. Not support transit call from PSTN to PSTN via this trunk group. + N: Tandem enabled. Support transit call from PSTN to PSTN via this trunk group. + [End] + " + ::= { Call_Routing 4 } + +Call_Routing_CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 2 + Default : 03FF + Field : [1]Reserved + { + [u]0.3-0.7 + [u]select + } + [2]Redirection + { + [u]0.3-0.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [3]Feature Request + { + [u]0.2-0.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [4]Sorm + { + [u]0.1-0.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [5]MCT + { + [u]0.0-0.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [6]MT SM + { + [u]1.7-1.7 + [u]select + [v]0[opt]off + [v]1[opt]on + + } + [7]MO SM + { + [u]1.6-1.6 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [8]Transit call + { + [u]1.5-1.5 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [9]Gateway outgoing call + { + [u]1.4-1.4 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [10]Gateway incoming call + { + [u]1.3-1.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [11]Roaming call + { + [u]1.2-1.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [12]MT call + { + [u]1.1-1.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [13]MO call + { + [u]1.0-1.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + Remark: Sorm: call intercept MCT: malicious call trace + Default=CDR of MO call and MT call is enabled, CDR of roaming call, gateway incoming call, gateway outgoing call, transit call, MO SMS and MT SMS is disabled. + [End] + " + ::= { Call_Routing 5 } + +Voice_Prompt_Announcement_option OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 16 + Default : 00000000000000000000000000000000 + Field : [1]Announcement 0 + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [2]Announcement 1 + { + [u]1.0-1.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [3]Announcement 2 + { + [u]2.0-2.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [4]Announcement 3 + { + [u]3.0-3.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + + [5]Announcement 4 + { + [u]4.0-4.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [6]Announcement 5 + { + [u]5.0-5.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [7]Announcement 6 + { + [u]6.0-6.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [8]Announcement 7 + { + [u]7.0-7.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [9]Announcement 8 + { + [u]8.0-8.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [10]Announcement 9 + { + [u]9.0-9.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [11]Announcement 10 + { + [u]10.0-10.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [12]Announcement 11 + { + [u]11.0-11.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [13]Announcement 12 + { + [u]12.0-12.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [14]Announcement 13 + { + [u]13.0-13.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [15]Announcement 14 + { + [u]14.0-14.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [16]Announcement 15 + { + [u]15.0-15.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + Remark : Set to play either announcement or tone indicating call unattainable reason for subscribers. System has total 8 announcements and tones that can be independently set. + Announcement 0: The dialed number is invalid. + Announcement 1: The subscriber dialed is not activated. + Announcement 2: The subscriber is busy. + Announcement 3: The network is busy. + Announcement 4: Caller's account was deactivated. + Announcement 5: The subscriber dialed was deactivated. + Announcement 6: Feature not available to caller. + Announcement 7: The subscriber dialed is not available. + [End] + " + ::= { Call_Routing 6 } + +Call_Routing_Warning OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 32 + Field : [1]Remanent time for warning tone + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark :Set time to play prompt tone for reaching zero balance prepaid subscriber when a call is in progress, unit is second. e.g. if set as 60, the system will play prompt tone one minute before a subscriber uses up his balance. + [End] + " + ::= { Call_Routing 7 } + + + +-- +-- CCF -> Configuration -> MSC +-- + + +CCF_MSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CCF Configuration MSC ." + ::= { CCF_Config 2 } + +Emergency_Call OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 21 + Default : 0000000000EEEEEEEEEEEEEEEE112EEEEEEEEEEEEE + Flag : E1 + Field : [1]Enable flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]LAC + { + [u]01.0-02.7 + [u]input + [v]toDec-high-0 + } + [3]CI + { + [u]03.0-04.7 + [u]input + [v]toDec-high-0 + } + [4]Dial number + { + [u]05.0-12.7 + [u]input + [v]keepHex-low-E + } + [5]Local emergency number + { + [u]13.0-20.7 + [u]input + [v]keepHex-low-E + } + Remark: Emergency call number. Default=112. + [End] + " + ::= { CCF_MSC 5 } + +Location_Management OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 8 + Default : 0000000000000000 + Flag : E1 + Field : [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } + [2]TG + { + [u]01.0-01.7 + [u]input + [v]toDec-high-0 + } + [3]LAC + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [4]CI + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + [5]Zone Code + { + [u]06.0-07.7 + [u]input + [v]toDec-high-0 + } + Remark :Manage the MS location by correlate TG (trunk group), LAC (location area code, cell ID and zone code, totally 256 location management. + [End] + " + ::= { CCF_MSC 8 } + + + +-- +-- CCF -> Configuration -> CPC Management +-- + + +CPC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CPC Management." + ::= { CCF_Config 3 } + +SRF_Address OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 8 + Default : 8675500000000009 + Field : [1]EIR number + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-E + } + Remark: E.164 number of HLR server:HLR MSISDN used for SCCP addressing, F=end tag. + Default=91867555950502FFFF=91867555950502. + [End] + " + ::= { CPC 3 } + +Max_Call_Duration OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 3C + Field : [1]Max. call duration + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark : Define the permitted maximum call duration. Any ongoing call reaching this duration threshold will be compulsively cut off. byte value: 0=disable this function, 1-255=max. call duration, unit=minute. Default=0. + [End] + " + ::= { CPC 7 } + +-- +-- CCF -> Configuration -> E1 Port +-- + + +E1_Port OBJECT-IDENTITY + STATUS current + DESCRIPTION + "E1 Port." + ::= { CCF_Config 4 } + +E1_Interface OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]E1 interface + { + [u]0.0-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF CDMA2K + [v]4[opt]BICC + [v]5[opt]CI-CNF + [v]6[opt]CI-loopback + } + Remark: Set the type of E1 interface for 256 E1 ports. + [End] + " + ::= { E1_Port 1 } + +E1_TG OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : EE + Field : [1]Assign TG + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark :Assign a trunk group to each E1 port for call routing. A single E1 port points to only one trunk group, multiple E1 port can be assigned the same trunk group. Default=number of the E1 port. + [End] + " + ::= { E1_Port 2 } + +E1_CIC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 4 + Default : 00000000 + Field : [1]E1 CIC + { + [u]0.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark :Circuit identity code, uniquely identify each circuit within a trunk group. CIC of both ends of a circuit must be identical. 256 CIC for dual MSC platform 256 E1 ports. + [End] + " + ::= { E1_Port 3 } + +E1_Media_Control_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 4 + Default : 00000000 + Field : [1]E1 Control Protocol Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Internal + [v]1[opt]MGCP + } + [2]E1 Enable + { + [u]1.0-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]MG Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + [4]Trunk Number + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark :E1 Media Control Attributes + [End] + " + ::= { E1_Port 4 } + +-- +-- CCF -> Configuration -> Channel attributes +-- + + +Channel_Attributes OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Channel attributes." + ::= { CCF_Config 5 } + +Card0_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 1 } + +Card1_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 2 } + +Card2_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 3 } + +Card3_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 4 } + +Card4_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 5 } + +Card5_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 6 } + +Card6_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 7 } + +Card7_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 8 } + +Card8_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 9 } + +Card9_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 10 } + +Card10_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 11 } + +Card11_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 12 } + +Card12_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 13 } + +Card13_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 14 } + +Card14_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 15 } + +Card15_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 16 } + +Card16_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 17 } + +Card17_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 18 } + +Card18_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 19 } + +Card19_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 20 } + +Card20_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 21 } + +Card21_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 22 } + +Card22_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 23 } + +Card23_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 24 } + +Card24_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 25 } + +Card25_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 26 } + +Card26_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 27 } + +Card27_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 28 } + +Card28_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 29 } + +Card29_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 30 } + +Card30_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 31 } + +Card31_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 32 } +-- +--CCF -> CPC_attributes +-- + +CPC_attributes OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CPC attributes." + ::= { CCF_Config 6 } +MSCID OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : [1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + [2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: MSCID + [End] + " + ::= { CPC_attributes 3 } + +-- +-- CCF -> Media_gateway +-- + +Media_gateway OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Media_gateway ." + ::= { CCF_Config 7 } + +MG_Attribute OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 53 + Default : 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field : [1]MG Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]MG IP Address + { + [u]1.0-4.7 + [u]input + [v]keepHex-high-0 + } + [3]MG Name + { + [u]5.0-52.7 + [u]input + [v]toAscii-low-0 + } + Remark: MG Attributes + [End] + " + ::= { Media_gateway 1 } + +-- +-- CCF -> CCF_Status +-- + +CCF_Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Status for CCF ." + ::= { CCF(MSC) 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : + Remark : Version of MSC software (Read only).
+ Byte0: System release version number, based on basic function and structure.
+ Byte1: Software module version number, based on software module.
+ Byte2: Test version, 0=Release version number, 1=Test version number.. + [End] + " + ::= { CCF_Status 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : EE + Flag : S1.3 + Field : [1]Command + { + [u]0.0-0.7 + [u]select + [v]90[opt]Reset + [v]165[opt]Initialize + [v]181[opt]Save parameter + [v]238[opt]No command + } + Remark: Control command for MSC-CPC. + Reset: Used for CPC status initialization. + Initialize: Restore the parameter setup to the default factory setting. + Save parameter: Save the parameters residing in CPC's memory into CPC's harddisk. + [End] + " + ::= { CCF_Status 2 } + +E1_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length : 1 + Default : EE + Field : [1]Quantity of occupied timeslot + { + [u]0.0-0.4 + [u]input + [v]toDec-high-0 + } + + [2]E1 type + { + [u]0.5-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF_CDMA2K + [v]4[opt]BICC + } + Remark : E1 status (read only). + [End] + " + ::= { CCF_Status 4 } + +Channel_Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Channel status (read only)." + ::= { CCF_Status 5 } + +Card0_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 1 } + +Card1_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 2 } + +Card2_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 3 } + +Card3_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 4 } + +Card4_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 5 } + +Card5_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 6 } + +Card6_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 7 } + +Card7_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 8 } + +Card8_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 9 } + +Card9_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 10 } + +Card10_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 11 } + +Card11_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 12 } + +Card12_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 13 } + +Card13_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 14 } + +Card14_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 15 } + +Card15_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 16 } + +-- +-- sub system VLR +-- + +VLR OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]sub for VLR . + " + ::= { MSC 5 } + +-- +-- VLR -> Configuration +-- + +VLR_Config OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for VLR . + " + ::= { VLR 2 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Public parameters . " + ::= { VLR_Config 1 } + +OptAuthReq OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 1 + Default : 00 + Field : [1]Update Location + { + [u]00.0-00.0 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [2]MO + { + [u]00.1-00.1 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [3]MT + { + [u]00.2-00.2 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [4]Spare + { + [u]00.3-00.7 + [u]input + [v]toDec-high-0 + } + Remark :Flag of SIM authentication on MS poweron and MO/MT call. + [End] + " + ::= { Public_Param 1 } + +OptReuseTriplets OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptReuseTriplets + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]double authentication + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Spare + { + [u]00.2-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Flag of reusing authentication triplets in VLR in the case that authentication to HLR is not available. Default=disable. + [End] + " + ::= { Public_Param 2 } + +OptCipReq OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptCipReq + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark : Flag of voice ciphering over air interface by MS. Default=Disable. + [End] + " + ::= { Public_Param 3 } + +OptCiphAlgo OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 4 + Default : 00000000 + Field : [1]OptCiphAlgo + { + [u]00.0-00.7 + [u]select + [v]0[opt]None + [v]1[opt]A5_1 + [v]2[opt]A5_2 + [v]3[opt]A5_3 + [v]4[opt]A5_4 + [v]5[opt]A5_5 + [v]6[opt]A5_6 + [v]7[opt]A5_7 + } + Remark : Voice ciphering algorithm selection. Default=no ciphering. + [End] + " + ::= { Public_Param 4 } + +OptTmsiAlloc OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]TMSI Allocation Option + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Allocate TMSI + [v]2[opt]Reallocate TMSI + } + Remark :Flag of allocating a new TMSI every time a call management service is requested. Default=Disable. + [End] + " + ::= { Public_Param 5 } + +OptEcSetUpAllow OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]OptEcSetUpAllow + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark : Flag of making emergency call for non-registered MS or MS without SIM. Default=Enable. + [End] + " + ::= { Public_Param 7 } + +OptCheckIMEI OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]Update Location + { + [u]00.0-00.0 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [2]MO + { + [u]00.1-00.1 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [3]MT + { + [u]00.2-00.2 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [4]Spare + { + [u]00.3-00.7 + [u]input + [v]toDec-high-0 + } + Remark : Flag of IMEI verification via EIR. Default=no IMEI verification. + [End] + " + ::= { Public_Param 8 } + +OptVlrPurge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptVlrPurge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + Remark : Flag of VLR purge. Default=Off. + [End] + " + ::= { Public_Param 9 } + +IdlePeriod2Purge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 3C + Field : [1]IdlePeriod2Purge + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark : Set the threshold of idle time to purge. If a mobile's idle time reaches this threshold, VLR will purge all records of this MS, unit=6 minute. Default=60minutes. + [End] + " + ::= { Public_Param 10 } + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]CDR on/off + { + [u]00.0-00.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + Remark : VLR CDR flag. Default=On. + [End] + " + ::= { Public_Param 11 } + +MSRN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 16 + Default : 8675531240000FFF8675531241000FFF + Field : [3]Start number + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-F + } + [4]End number + { + [u]08.0-15.7 + [u]input + [v]keepHex-low-F + } + Remark : Mobile station roaming number, use 16 bytes (32 digits) to define a range of MSRN. The length of start MSRN and end MSRN must be identical. F=end tag. + [End] + " + ::= { Public_Param 13 } + +-- +-- VLR -> Management +-- + +VLR_Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management for VLR . + " + ::= { VLR 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : + Remark : Version of VLR software (Read only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { VLR_Management 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : EE + Flag : S1.2 + Field : [1]Management + { + [u]00.0-00.7 + [u]select + [v]0[opt]Reset VLR + [v]1[opt]Save parameters + } + Remark : Control command for VLR. + Reset: Used to initialize the status of VLR. + Save parameters: Save the parameters residing in memory into harddisk. + [End] + " + ::= { VLR_Management 3 } + +Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : + Remark :Basic status of VLR. + [End] + " + ::= { VLR_Management 4 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSS-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSS-MIB.txt.svn-base new file mode 100644 index 0000000..ddb4465 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-MSS-MIB.txt.svn-base @@ -0,0 +1,54 @@ +WXC2-MSS-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +MSS OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Subsystems for MSS . " + ::= { App 16 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for MSS . " + ::= { MSS 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Management for MSS . " + ::= { Configuration 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 1 + Default : 00 + Field : [1]Command + { + [u]00.0-00.7 + [u]select + [v]4[opt]Shutdown + [v]5[opt]Undefine value + } + Remark : Safely shut down MSS server by stoping MSS process, saving subscriber data to harddisk and shut down the server. + Operation procedures: + 1. Select -Shutdown- at above pulldown menu. + 2. Click -Set- button in this set window. + 3. Click -SET- button on operation page. + [End] + " + ::= { Management 1 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-PPS-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-PPS-MIB.txt.svn-base new file mode 100644 index 0000000..b566b21 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-PPS-MIB.txt.svn-base @@ -0,0 +1,13090 @@ +WXC2-PPS-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +PPS OBJECT-IDENTITY + STATUS current + DESCRIPTION + "[SubSystem_Module]Subsystems for PPS . " + ::= { App 6 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " public parameters for MSS . " + ::= { PPS 2 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for PPS . " + ::= { Public_Param 1 } + +Service_Control OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service Control . " + ::= { Configuration 1 } + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]CDR flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark: PPS CDR generation enable or disable. Default=PPS generate CDR. + [End] + " + ::= { Service_Control 1 } + +Blacklist_Threshold OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 05 + Field: [1]Blacklist threshold + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Legal recharge failure, subsciber who breaks the threshold will be marked in black list and suspended from service provisioning. Default=5. + [End] + " + ::= { Service_Control 2 } + +Maximum_Balance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00100000 + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This value is for overflow prevention. Normally operator doesn't need to change this value. e.g. 5000, and the smallest unit is cent then the maximum allowed balance is 5000 cents. + [End] + " + ::= { Service_Control 3 } + +License_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]License + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-E + } + Remark: 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of PPS subscribers for service provider. The new license can not support less PPS subscribers than what the old license supports. + [End] + " + ::= { Service_Control 4 } + +Prompt_Resolution OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Currency resolution + { + [u]00.0-00.1 + [u]select + [v]0[opt]1 + [v]1[opt]10 + [v]2[opt]100 + } + [2]Date format + { + [u]00.2-00.3 + [u]select + [v]0[opt]YYYY-MM-DD + [v]1[opt]DD-MM-YYYY + [v]2[opt]MM-DD-YYYY + } + [3]Currency symbol position + { + [u]00.4-00.4[u]select + [v]0[opt]Front + [v]1[opt]Rear + } + [4]Reserved + { + [u]00.5-00.7 + [u]select + } + Remark: Currency style: Set the number of decimals in account balance SM display format. If account balance=55555 in smallest currency unit: + 1=account balance display in SM is 55555. + 10=account balance display in SM is 5555.5. + 100=account balance display in SM is 555.55. + Default=100. + Date style: Set the date format displayed in SM or announcement. Default=YYYY-MM-DD. + Currency symbol position: Set the position of the currency symbol. + There are two types: at the front of the amount (e.g. $5) or at the rear of the amount (e.g. 5Fr). Default=at the front. + [End] + " + ::= { Service_Control 5 } + +SMS_Sentence OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 5 + Length: 112 + Default: 00596F7572206163636F756E742062616C616E63652069733A000000000000004578706972656420696E3A000000000000000000000000000000000000000000506C6561736520726563686172676520796F7572206163636F756E740000000000000000000000000000000000000000 + Field: [1]SM encode type + { + [u]00.0-00.7 + [u]select + [v]0[opt]7 bit + [v]4[opt]octet + [v]8[opt]unicode + } + [2]Account balance + { + [u]01.0-31.7 + [u]input + [v]toAscii-low-0 + } + [3]expired in + { + [u]32.0-63.7 + [u]input + [v]toAscii-low-0 + } + [4]recharge in time + { + [u]64.0-111.7 + [u]input + [v]toAscii-low-0 + } + Remark: The # of sentence(0-4) refers to differenct language type; + [End] + " + ::= { Service_Control 6 } + +Last_Call_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 5 + Length: 88 + Default: 4C6173742063616C6C2073656E74206F6E3A00000000000000000000000000004C6173742063616C6C207265636569766564206F6E3A200000000000000000004174000000000000546F00000000000046726F6D00000000 + Field: [1]Last call sent on + { + [u]00.0-31.7 + [u]input + [v]toAscii-low-0 + } + [2]Last call received on + { + [u]32.0-63.7 + [u]input + [v]toAscii-low-0 + } + [3]At + { + [u]64.0-71.7 + [u]input + [v]toAscii-low-0 + } + [4]To + { + [u]72.0-79.7 + [u]input + [v]toAscii-low-0 + } + [5]From + { + [u]80.0-87.7 + [u]input + [v]toAscii-low-0 + } + Remark: The # of sentence(0-4) refers to differenct language type. + [End] + " + ::= { Service_Control 7 } + +Currency_Symbol OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 2400000000000000 + Field: [1]Currency symbol + { + [u]00.0-07.7 + [u]input + [v]toAscii-low-0 + } + Remark: Set the symbol of the local currency in SMS amount display. e.g. $, RMB, EUR, US$, FR$. default=$. In the set window, type the currency symbol. The input symbol will be converted to ASCII code. + Do not input any symbol that not listed on the ASCII code table. ASCII table: 'A'=0x41, 'B'=0x42 ... 'I'=0x49, 'J'=0x4a, 'K'=0x4b ... 'Z'=0x5A, '$'=0x24 + e.g. RMB=0x52 0x4d 0x42, US$=0x55 0x53 0x24 + [End] + " + ::= { Service_Control 8 } + +Third_Party_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Service ID + { + [u]00.0-07.7 + [u]input + [v]toAscii-low-0 + } + [2]Service password + { + [u]08.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: This parameter is a verification for third party ESME when the third party ESME sends a billing request to PPS server. For example, if a subscriber sends a short message via a ESME (e.g. website), the ESME will send a billing request to PPS to debit this subscriber. This billing request must contains a service ID and password to pass the verification. After verification, the subscriber will be debited by the PPS. PPS supports 8 ESME connections. + [End] + " + ::= { Service_Control 9 } + +Basic_Tariff_Zone OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 64 + Length: 9 + Default: 000000000000000000 + Field: [1]MCC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-F + } + [2]MNC + { + [u]02.0-02.7 + [u]input + [v]keepHex-low-F + } + [3]LAC + { + [u]03.0-04.7 + [u]input + [v]toDec-high-0 + } + [4]Cell ID + { + [u]05.0-06.7 + [u]input + [v]toDec-high-0 + } + [5]MO tariff ID + { + [u]07.0-07.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [6]MT tariff ID + { + [u]08.0-08.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: The basic tariff is applied for each calling or called number prefix. The WXC2 System supports 16 MO and MT tariffs (0-15) and 256 billing zones. This parameter defines basic tariff for each billing zone. Each parameter is a combination of MCC, MNC, cell ID, LAC and MO/MT tariff ID. The billing zone may be set as a cell, a LAC or a zone. Normally a single billing zone deploys only one basic tariff. + Each PPS subscriber profile also contains its tariff setup specifying which tariff should be applied for this subscriber. Using either basic tariff zone (location dependent) or tariff in subscriber profile (subscriber dependent) is determined by a parameter -Tariff subscription-. + LAC: If LAC=65536, all LACs in the MCC and MNC use the same basic tariff. + Cell ID: If cell ID=65536, all cells in the LAC use the same basic tariff. + [End] + " + ::= { Service_Control 10 } + +SRF_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SRF parameters . " + ::= { Configuration 2 } + +SRF_Number OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SRF Number. " + ::= { SRF_Param 1 } + +SRF_0_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]SRF 0 number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: E.164 number of SRF 0 (Special Resource Function) entity. + [End] + " + ::= { SRF_Number 1 } + +SRF_1_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]SRF 1 number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: E.164 number of SRF 1 (Special Resource Function) entity. + [End] + " + ::= { SRF_Number 2 } + +Service_Number OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service number . " + ::= { SRF_Param 2 } + +Hotline OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Hotline + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: PPS service center number. Subscriber dials this number to recharge, enquire their account and modify favorite numbers. + [End] + " + ::= { Service_Number 1 } + +Inquiry OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Inquiry number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated PPS number for account (balance and validity) inquiry. + [End] + " + ::= { Service_Number 2 } + +Scratch_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge via scratch card + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via scratch card. + [End] + " + ::= { Service_Number 3 } + +Credit_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge via credit card + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via credit card. + [End] + " + ::= { Service_Number 4 } + +Third_Party_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge other account + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharging other account from MS or PSTN. + [End] + " + ::= { Service_Number 5 } + +Customer_Care_Center OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Customer care center number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number to connect customer care center. + [End] + " + ::= { Service_Number 6 } + +Rechareg_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via scratch card or credit card. + [End] + " + ::= { Service_Number 7 } + +Service_Key OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service key . " + ::= { SRF_Param 3 } + +Inquiry OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Key for inquiry + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the function key to enquire account balance after entering the PPS service center. + [End] + " + ::= { Service_Key 2 } + +Scratch_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Field: [1]Key for recharging via scratch card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to recharge account via scratch card after entering the PPS service center. + [End] + " + ::= { Service_Key 3 } + +Credit_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Key for recharging via credit card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key for recharging account via credit card after entering the PPS service center. + [End] + " + ::= { Service_Key 4 } + +Set_Favorite_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 04 + Field: [1]Key to set favorite number + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to set favorite number after entering the PPS service center. + [End] + " + ::= { Service_Key 5 } + +Language_Selection OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 05 + Field: [1]Key for language selection + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to select system language (from 5 available candidates) after entering the PPS service center. All announcements in the PPS service center is played in the system language. + [End] + " + ::= { Service_Key 6 } + +SetPasswd OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 06 + Field: [1]PPS account password + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to set account password after entering the PPS service center. When recharging account] selecting language] modifying favorite number or seting password] subscriber is asked to pass the password verification. + [End] + " + ::= { Service_Key 7 } + +File_Operation OBJECT-IDENTITY + STATUS current + DESCRIPTION + " File operation . " + ::= { Configuration 3 } + +Import_User_Data OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Command status + { + [u]00.0-00.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading failed + } + [2]Total number sent + { + [u]01.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]Records loaded + { + [u]04.0-06.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. Progress and result of PPS subscriber import. + Total number sent: Total quantity of PPS subscribers requesting import. + Records loaded: Quantity of successfully imported PPS subscribers. + [End] + " + ::= { File_Operation 1 } + +Import_Recharge_Card OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Import recharge card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. Result of uploading recharge card to PPS. 0=unsuccessful. 1=successful. + [End] + " + ::= { File_Operation 2 } + +New_Tariff_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { File_Operation 3 } + +New_Tariff_Start_Time OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 20050101000000 + Field: [1]Year + { + [u]00.0-01.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]03.0-03.7 + [u]input + [v]keepHex-high-0 + } + [4]Hour + { + [u]04.0-04.7 + [u]input + [v]keepHex-high-0 + } + [5]Minute + { + [u]05.0-05.7 + [u]input + [v]keepHex-high-0 + } + [6]Second + { + [u]06.0-06.7 + [u]input + [v]keepHex-high-0 + } + Remark: Read only. Set start time for new tariff plan. + [End] + " + ::= { File_Operation 4 } + +COS_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS parameters . " + ::= { Configuration 4 } + +COS_0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 0 Parameters. " + ::= { COS_Param 1 } + +Recharge_Promotion_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_0 1 } + +Start_Date_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS0 1 } + +End_Date_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS0 2 } + +Promotion_Bonus_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS0 3 } + +Tariff_Resolution_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_0 2 } + +MO_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS0 1 } + +MT_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS0 2 } + +Tariff_Subscription_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS0 3 } + +Recharge_Card_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS0 4 } + +Account_Control_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_0 3 } + +Min_balance_MO_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS0 1 } + +Maximum_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS0 2 } + +Release_Day_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS0 3 } + +MT_Control_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_0 4 } + +Charge_Flag_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS0 1 } + +Zero_Balance_Control_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS0 2 } + +Validity_Solution_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_0 5 } + +Clear_Balance_Option_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS0 1 } + +Validity_Recharge_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS0 2 } + +Validity_Zero_Balance_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS0 3 } + +Activated_Account_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS0 4 } + +FF_Number_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS0 5 } + +Support_Credit_Card_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS0 + [End] + " + ::= { Validity_Solution_COS0 6 } + +Credit_Vault_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS0 7 } + +SM_Inquiry_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_0 6 } + +Feedback_SM_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS0 1 } + +Inquiry_SM_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS0 2 } + +SM_Expiry_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS0 3 } + +SM_Low_Balance_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS0 4 } + +COS_1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 1 Parameters. " + ::= { COS_Param 2 } + +Recharge_Promotion_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_1 1 } + +Start_Date_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS1 1 } + +End_Date_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS1 2 } + +Promotion_Bonus_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS1 3 } + +Tariff_Resolution_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_1 2 } + +MO_Tariff_ID_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS1 1 } + +MT_Tariff_ID_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS1 2 } + +Tariff_Subscription_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS1 3 } + +Recharge_Card_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS1 4 } + +Account_Control_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_1 3 } + +Min_balance_MO_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS1 1 } + +Maximum_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS1 2 } + +Release_Day_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS1 3 } + +MT_Control_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_1 4 } + +Charge_Flag_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS1 1 } + +Zero_Balance_Control_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS1 2 } + +Validity_Solution_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_1 5 } + +Clear_Balance_Option_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS1 1 } + +Validity_Recharge_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS1 2 } + +Validity_Zero_Balance_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS1 3 } + +Activated_Account_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS1 4 } + +FF_Number_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS1 5 } + +Support_Credit_Card_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS1 6 } + +Credit_Vault_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS1 7 } + +SM_Inquiry_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_1 6 } + +Feedback_SM_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS1 1 } + +Inquiry_SM_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS1 2 } + +SM_Expiry_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS1 3 } + +SM_Low_Balance_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS1 4 } + +COS_2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 2 Parameters. " + ::= { COS_Param 3 } + +Recharge_Promotion_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_2 1 } + +Start_Date_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS2 1 } + +End_Date_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS2 2 } + +Promotion_Bonus_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS2 3 } + +Tariff_Resolution_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_2 2 } + +MO_Tariff_ID_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS2 1 } + +MT_Tariff_ID_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS2 2 } + +Tariff_Subscription_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS2 3 } + +Recharge_Card_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS2 4 } + +Account_Control_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_2 3 } + +Min_balance_MO_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS2 1 } + +Maximum_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS2 2 } + +Release_Day_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS2 3 } + +MT_Control_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_2 4 } + +Charge_Flag_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS2 1 } + +Zero_Balance_Control_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS2 2 } + +Validity_Solution_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_2 5 } + +Clear_Balance_Option_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS2 1 } + +Validity_Recharge_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS2 2 } + +Validity_Zero_Balance_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS2 3 } + +Activated_Account_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS2 4 } + +FF_Number_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Free times of changing: set total times of free change for family number if charge is enabled. Maximum is 15. + [End] + " + ::= { Validity_Solution_COS2 5 } + +Support_Credit_Card_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS2 6 } + +Credit_Vault_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS2 7 } + +SM_Inquiry_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_2 6 } + +Feedback_SM_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS2 1 } + +Inquiry_SM_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS2 2 } + +SM_Expiry_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS2 3 } + +SM_Low_Balance_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS2 4 } + +COS_3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 3 Parameters. " + ::= { COS_Param 4 } + +Recharge_Promotion_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_3 1 } + +Start_Date_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS3 1 } + +End_Date_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS3 2 } + +Promotion_Bonus_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS3 3 } + +Tariff_Resolution_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_3 2 } + +MO_Tariff_ID_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS3 1 } + +MT_Tariff_ID_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS3 2 } + +Tariff_Subscription_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS3 3 } + +Recharge_Card_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS3 4 } + +Account_Control_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_3 3 } + +Min_balance_MO_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS3 1 } + +Maximum_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS3 2 } + +Release_Day_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS3 3 } + +MT_Control_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_3 4 } + +Charge_Flag_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS3 1 } + +Zero_Balance_Control_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS3 2 } + +Validity_Solution_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_3 5 } + +Clear_Balance_Option_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS3 1 } + +Validity_Recharge_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS3 2 } + +Validity_Zero_Balance_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS3 3 } + +Activated_Account_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS3 4 } + +FF_Number_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS3 5 } + +Support_Credit_Card_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS3 6 } + +Credit_Vault_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS3 7 } + +SM_Inquiry_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_3 6 } + +Feedback_SM_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS3 1 } + +Inquiry_SM_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS3 2 } + +SM_Expiry_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS3 3 } + +SM_Low_Balance_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS3 4 } + +COS_4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 4 Parameters. " + ::= { COS_Param 5 } + +Recharge_Promotion_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_4 1 } + +Start_Date_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS4 1 } + +End_Date_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS4 2 } + +Promotion_Bonus_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS4 3 } + +Tariff_Resolution_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_4 2 } + +MO_Tariff_ID_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS4 1 } + +MT_Tariff_ID_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS4 2 } + +Tariff_Subscription_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS4 3 } + +Recharge_Card_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS4 4 } + +Account_Control_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_4 3 } + +Min_balance_MO_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS4 1 } + +Maximum_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS4 2 } + +Release_Day_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS4 3 } + +MT_Control_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_4 4 } + +Charge_Flag_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS4 1 } + +Zero_Balance_Control_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS4 2 } + +Validity_Solution_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_4 5 } + +Clear_Balance_Option_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS4 1 } + +Validity_Recharge_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS4 2 } + +Validity_Zero_Balance_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS4 3 } + +Activated_Account_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS4 4 } + +FF_Number_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS4 5 } + +Support_Credit_Card_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS4 6 } + +Credit_Vault_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS4 7 } + +SM_Inquiry_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_4 6 } + +Feedback_SM_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS4 1 } + +Inquiry_SM_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS4 2 } + +SM_Expiry_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS4 3 } + +SM_Low_Balance_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS4 4 } + +COS_5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 5 Parameters. " + ::= { COS_Param 6 } + +Recharge_Promotion_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_5 1 } + +Start_Date_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS5 1 } + +End_Date_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS5 2 } + +Promotion_Bonus_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS5 3 } + +Tariff_Resolution_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_5 2 } + +MO_Tariff_ID_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS5 1 } + +MT_Tariff_ID_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] Select a MT tariff for this COS. The COS ID is included in subscriber profile for MT call charge. Total 16 MT tariffs available. + " + ::= { Tariff_Resolution_COS5 2 } + +Tariff_Subscription_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS5 3 } + +Recharge_Card_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS5 4 } + +Account_Control_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_5 3 } + +Min_balance_MO_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS5 1 } + +Maximum_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS5 2 } + +Release_Day_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS5 3 } + +MT_Control_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_5 4 } + +Charge_Flag_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS5 1 } + +Zero_Balance_Control_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS5 2 } + +Validity_Solution_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_5 5 } + +Clear_Balance_Option_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS5 1 } + +Validity_Recharge_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS5 2 } + +Validity_Zero_Balance_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS5 3 } + +Activated_Account_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS5 4 } + +FF_Number_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS5 5 } + +Support_Credit_Card_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS5 6 } + +Credit_Vault_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS5 7 } + +SM_Inquiry_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_5 6 } + +Feedback_SM_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS5 1 } + +Inquiry_SM_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS5 2 } + +SM_Expiry_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS5 3 } + +SM_Low_Balance_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS5 4 } + +COS_6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 6 Parameters. " + ::= { COS_Param 7 } + +Recharge_Promotion_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_6 1 } + +Start_Date_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS6 1 } + +End_Date_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS6 2 } + +Promotion_Bonus_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS6 3 } + +Tariff_Resolution_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_6 2 } + +MO_Tariff_ID_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS6 1 } + +MT_Tariff_ID_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS6 2 } + +Tariff_Subscription_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS6 3 } + +Recharge_Card_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS6 4 } + +Account_Control_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_6 3 } + +Min_balance_MO_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS6 1 } + +Maximum_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS6 2 } + +Release_Day_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS6 3 } + +MT_Control_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_6 4 } + +Charge_Flag_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS6 1 } + +Zero_Balance_Control_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS6 2 } + +Validity_Solution_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_6 5 } + +Clear_Balance_Option_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS6 1 } + +Validity_Recharge_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS6 2 } + +Validity_Zero_Balance_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS6 3 } + +Activated_Account_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS6 4 } + +FF_Number_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS6 5 } + +Support_Credit_Card_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS6 6 } + +Credit_Vault_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS6 7 } + +SM_Inquiry_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_6 6 } + +Feedback_SM_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS6 1 } + +Inquiry_SM_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS6 2 } + +SM_Expiry_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS6 3 } + +SM_Low_Balance_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS6 4 } + +COS_7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 7 Parameters. " + ::= { COS_Param 8 } + +Recharge_Promotion_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_7 1 } + +Start_Date_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS7 1 } + +End_Date_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS7 2 } + +Promotion_Bonus_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS7 3 } + +Tariff_Resolution_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_7 2 } + +MO_Tariff_ID_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS7 1 } + +MT_Tariff_ID_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS7 2 } + +Tariff_Subscription_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS7 3 } + +Recharge_Card_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS7 4 } + +Account_Control_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_7 3 } + +Min_balance_MO_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS7 1 } + +Maximum_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS7 2 } + +Release_Day_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS7 3 } + +MT_Control_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_7 4 } + +Charge_Flag_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS7 1 } + +Zero_Balance_Control_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS7 2 } + +Validity_Solution_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_7 5 } + +Clear_Balance_Option_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS7 1 } + +Validity_Recharge_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS7 2 } + +Validity_Zero_Balance_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS7 3 } + +Activated_Account_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS7 4 } + +FF_Number_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS7 5 } + +Support_Credit_Card_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS7 6 } + +Credit_Vault_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS7 7 } + +SM_Inquiry_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_7 6 } + +Feedback_SM_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS7 1 } + +Inquiry_SM_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS7 2 } + +SM_Expiry_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS7 3 } + +SM_Low_Balance_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS7 4 } + +COS_8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 8 Parameters. " + ::= { COS_Param 9 } + +Recharge_Promotion_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_8 1 } + +Start_Date_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS8 1 } + +End_Date_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS8 2 } + +Promotion_Bonus_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS8 3 } + +Tariff_Resolution_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_8 2 } + +MO_Tariff_ID_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS8 1 } + +MT_Tariff_ID_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS8 2 } + +Tariff_Subscription_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS8 3 } + +Recharge_Card_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS8 4 } + +Account_Control_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_8 3 } + +Min_balance_MO_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS8 1 } + +Maximum_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS8 2 } + +Release_Day_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS8 3 } + +MT_Control_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_8 4 } + +Charge_Flag_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS8 1 } + +Zero_Balance_Control_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS8 2 } + +Validity_Solution_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_8 5 } + +Clear_Balance_Option_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS8 1 } + +Validity_Recharge_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS8 2 } + +Validity_Zero_Balance_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS8 3 } + +Activated_Account_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS8 4 } + +FF_Number_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS8 5 } + +Support_Credit_Card_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS8 6 } + +Credit_Vault_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS8 7 } + +SM_Inquiry_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_8 6 } + +Feedback_SM_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS8 1 } + +Inquiry_SM_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS8 2 } + +SM_Expiry_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS8 3 } + +SM_Low_Balance_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS8 4 } + +COS_9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 9 Parameters. " + ::= { COS_Param 10 } + +Recharge_Promotion_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_9 1 } + +Start_Date_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS9 1 } + +End_Date_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS9 2 } + +Promotion_Bonus_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS9 3 } + +Tariff_Resolution_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_9 2 } + +MO_Tariff_ID_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS9 1 } + +MT_Tariff_ID_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS9 2 } + +Tariff_Subscription_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS9 3 } + +Recharge_Card_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS9 4 } + +Account_Control_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_9 3 } + +Min_balance_MO_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS9 1 } + +Maximum_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS9 2 } + +Release_Day_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS9 3 } + +MT_Control_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_9 4 } + +Charge_Flag_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS9 1 } + +Zero_Balance_Control_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS9 2 } + +Validity_Solution_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_9 5 } + +Clear_Balance_Option_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS9 1 } + +Validity_Recharge_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS9 2 } + +Validity_Zero_Balance_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS9 3 } + +Activated_Account_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS9 4 } + +FF_Number_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS9 5 } + +Support_Credit_Card_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS9 6 } + +Credit_Vault_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS9 7 } + +SM_Inquiry_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_9 6 } + +Feedback_SM_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS9 1 } + +Inquiry_SM_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS9 2 } + +SM_Expiry_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS9 3 } + +SM_Low_Balance_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS9 4 } + +COS_10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 10 Parameters. " + ::= { COS_Param 11 } + +Recharge_Promotion_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_10 1 } + +Start_Date_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS10 1 } + +End_Date_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS10 2 } + +Promotion_Bonus_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS10 3 } + +Tariff_Resolution_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_10 2 } + +MO_Tariff_ID_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS10 1 } + +MT_Tariff_ID_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS10 2 } + +Tariff_Subscription_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS10 3 } + +Recharge_Card_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS10 4 } + +Account_Control_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_10 3 } + +Min_balance_MO_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS10 1 } + +Maximum_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS10 2 } + +Release_Day_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS10 3 } + +MT_Control_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_10 4 } + +Charge_Flag_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS10 1 } + +Zero_Balance_Control_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS10 2 } + +Validity_Solution_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_10 5 } + +Clear_Balance_Option_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS10 1 } + +Validity_Recharge_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS10 2 } + +Validity_Zero_Balance_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS10 3 } + +Activated_Account_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS10 4 } + +FF_Number_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS10 5 } + +Support_Credit_Card_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS10 6 } + +Credit_Vault_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS10 7 } + +SM_Inquiry_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_10 6 } + +Feedback_SM_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS10 1 } + +Inquiry_SM_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS10 2 } + +SM_Expiry_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS10 3 } + +SM_Low_Balance_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS10 4 } + +COS_11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 11 Parameters. " + ::= { COS_Param 12 } + +Recharge_Promotion_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_11 1 } + +Start_Date_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS11 1 } + +End_Date_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS11 2 } + +Promotion_Bonus_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS11 3 } + +Tariff_Resolution_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_11 2 } + +MO_Tariff_ID_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS11 1 } + +MT_Tariff_ID_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS11 2 } + +Tariff_Subscription_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS11 3 } + +Recharge_Card_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS11 4 } + +Account_Control_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_11 3 } + +Min_balance_MO_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS11 1 } + +Maximum_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS11 2 } + +Release_Day_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS11 3 } + +MT_Control_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_11 4 } + +Charge_Flag_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS11 1 } + +Zero_Balance_Control_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS11 2 } + +Validity_Solution_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_11 5 } + +Clear_Balance_Option_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS11 1 } + +Validity_Recharge_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS11 2 } + +Validity_Zero_Balance_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS11 3 } + +Activated_Account_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS11 4 } + +FF_Number_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS11 5 } + +Support_Credit_Card_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS11 6 } + +Credit_Vault_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS11 7 } + +SM_Inquiry_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_11 6 } + +Feedback_SM_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS11 1 } + +Inquiry_SM_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS11 2 } + +SM_Expiry_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS11 3 } + +SM_Low_Balance_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS11 4 } + +COS_12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 12 Parameters. " + ::= { COS_Param 13 } + +Recharge_Promotion_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_12 1 } + +Start_Date_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS12 1 } + +End_Date_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS12 2 } + +Promotion_Bonus_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS12 3 } + +Tariff_Resolution_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_12 2 } + +MO_Tariff_ID_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS12 1 } + +MT_Tariff_ID_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS12 2 } + +Tariff_Subscription_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS12 3 } + +Recharge_Card_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS12 4 } + +Account_Control_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_12 3 } + +Min_balance_MO_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS12 1 } + +Maximum_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS12 2 } + +Release_Day_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS12 3 } + +MT_Control_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_12 4 } + +Charge_Flag_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS12 1 } + +Zero_Balance_Control_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS12 2 } + +Validity_Solution_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_12 5 } + +Clear_Balance_Option_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS12 1 } + +Validity_Recharge_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS12 2 } + +Validity_Zero_Balance_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS12 3 } + +Activated_Account_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS12 4 } + +FF_Number_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS12 5 } + +Support_Credit_Card_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS12 6 } + +Credit_Vault_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS12 7 } + +SM_Inquiry_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_12 6 } + +Feedback_SM_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS12 1 } + +Inquiry_SM_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS12 2 } + +SM_Expiry_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS12 3 } + +SM_Low_Balance_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS12 4 } + +COS_13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 13 Parameters. " + ::= { COS_Param 14 } + +Recharge_Promotion_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_13 1 } + +Start_Date_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS13 1 } + +End_Date_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS13 2 } + +Promotion_Bonus_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS13 3 } + +Tariff_Resolution_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_13 2 } + +MO_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS13 1 } + +MT_Tariff_ID_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS13 2 } + +Tariff_Subscription_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS13 3 } + +Recharge_Card_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS13 4 } + +Account_Control_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_13 3 } + +Min_balance_MO_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS13 1 } + +Maximum_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS13 2 } + +Release_Day_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS13 3 } + +MT_Control_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_13 4 } + +Charge_Flag_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS13 1 } + +Zero_Balance_Control_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS13 2 } + +Validity_Solution_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_13 5 } + +Clear_Balance_Option_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS13 1 } + +Validity_Recharge_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS13 2 } + +Validity_Zero_Balance_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS13 3 } + +Activated_Account_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS13 4 } + +FF_Number_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS13 5 } + +Support_Credit_Card_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS13 6 } + +Credit_Vault_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS13 7 } + +SM_Inquiry_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_13 6 } + +Feedback_SM_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS13 1 } + +Inquiry_SM_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS13 2 } + +SM_Expiry_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS13 3 } + +SM_Low_Balance_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS13 4 } + +COS_14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 14 Parameters. " + ::= { COS_Param 15 } + +Recharge_Promotion_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_14 1 } + +Start_Date_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS14 1 } + +End_Date_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS14 2 } + +Promotion_Bonus_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS14 3 } + +Tariff_Resolution_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_14 2 } + +MO_Tariff_ID_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS14 1 } + +MT_Tariff_ID_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS14 2 } + +Tariff_Subscription_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS14 3 } + +Recharge_Card_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS14 4 } + +Account_Control_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_14 3 } + +Min_balance_MO_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS14 1 } + +Maximum_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS14 2 } + +Release_Day_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS14 3 } + +MT_Control_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_14 4 } + +Charge_Flag_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS14 1 } + +Zero_Balance_Control_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS14 2 } + +Validity_Solution_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_14 5 } + +Clear_Balance_Option_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS14 1 } + +Validity_Recharge_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS14 2 } + +Validity_Zero_Balance_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS14 3 } + +Activated_Account_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS14 4 } + +FF_Number_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS14 5 } + +Support_Credit_Card_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS14 6 } + +Credit_Vault_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS14 7 } + +SM_Inquiry_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_14 6 } + +Feedback_SM_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS14 1 } + +Inquiry_SM_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS14 2 } + +SM_Expiry_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS14 3 } + +SM_Low_Balance_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS14 4 } + +COS_15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 15 Parameters. " + ::= { COS_Param 16 } + +Recharge_Promotion_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_15 1 } + +Start_Date_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS15 1 } + +End_Date_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS15 2 } + +Promotion_Bonus_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS15 3 } + +Tariff_Resolution_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_15 2 } + +MO_Tariff_ID_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS15 1 } + +MT_Tariff_ID_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS15 2 } + +Tariff_Subscription_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS15 3 } + +Recharge_Card_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS15 4 } + +Account_Control_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_15 3 } + +Min_balance_MO_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS15 1 } + +Maximum_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS15 2 } + +Release_Day_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS15 3 } + +MT_Control_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_15 4 } + +Charge_Flag_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS15 1 } + +Zero_Balance_Control_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS15 2 } + +Validity_Solution_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_15 5 } + +Clear_Balance_Option_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS15 1 } + +Validity_Recharge_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS15 2 } + +Validity_Zero_Balance_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS15 3 } + +Activated_Account_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS15 4 } + +FF_Number_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS15 5 } + +Support_Credit_Card_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS15 6 } + +Credit_Vault_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS15 7 } + +SM_Inquiry_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_15 6 } + +Feedback_SM_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS15 1 } + +Inquiry_SM_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS15 2 } + +SM_Expiry_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS15 3 } + +SM_Low_Balance_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS15 4 } + +Call_Routing_VMS OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Call routing to VMS . " + ::= { Configuration 5 } + +VMS_PLMN_Maintenance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS service number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 1 } + +VMS_PSTN_Maintenance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS service number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 2 } + +--VMS_Deposit_Number OBJECT-TYPE +-- SYNTAX OCTET STRING +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- " Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. +-- " +-- ::= { Call_Routing_VMS 3 } + +VMS_leave_msg_No OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS deposit number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 3 } + +--Access_VoiceBox OBJECT-TYPE +-- SYNTAX OCTET STRING +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- " Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. +-- " +-- ::= { Call_Routing_VMS 4 } + +Rule OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Route by + { + [u]00.0-00.0 + [u]select + [v]0[opt]Prefix + [v]1[opt]Whole number + } + [2]Route + { + [u]00.1-00.1 + [u]select + [v]0[opt]Caller number + [v]1[opt]Called number + } + [3]Reserved + { + [u]00.2-00.7 + [u]input + [v]toDec-high-0 + } + Remark: rule + [End] + " + ::= { Call_Routing_VMS 4 } + +VMS_User_Segments OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 80 + Default: 3836373535393030303030000000000038363735353939393939390000000000383637353539393830300000000000003836373535393938303100000000000038363735353939383032000000000000 + Field: [1]Start MSISDN + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + [2]End MSISDN + { + [u]16.0-31.7 + [u]input + [v]toAscii-low-0 + } + [3]VMS service number - PLMN + { + [u]32.0-47.7 + [u]input + [v]toAscii-low-0 + } + [4]VMS service number - PSTN + { + [u]48.0-63.7 + [u]input + [v]toAscii-low-0 + } + [5]Leave message deposit number + { + [u]64.0-79.7 + [u]input + [v]toAscii-low-0 + } + Remark: VMS user segments + [End] + " + ::= { Call_Routing_VMS 5 } + +Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Status. " + ::= { Configuration 6 } + +Activation OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]System status + { + [u]00.0-00.7 + [u]select + [v]0[opt]Normal + } + Remark: Set PPS system status. 0=normal. After initial PPS installation, if the PPS system doesn't has subscriber profiles, its status is suspended. In this case operator may set this parameter (normal) to activate the PPS server. + [End] + " + ::= { Status 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag : S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]1[opt]Save parameters + [v]2[opt]Save user data + } + Remark: PPS management command. + Save parameters: Save PPS parameters in PPS memory to PPS hard disk. + Save user data: Save PPS subscriber data in PPS memory to PPS hard disk. + [End] + " + ::= { Status 2 } + +END \ No newline at end of file diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMI.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMI.txt.svn-base new file mode 100644 index 0000000..4841a50 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMI.txt.svn-base @@ -0,0 +1,57 @@ +-- ***************************************************************** +-- WXC2-SMI: WXC2 Structure of Management Information +-- +-- draft November 2000, Huang qilong +-- 1st November 2004, Sheng Xueqiang +-- +-- Copyright (c) 2004 by interWAVE, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- + +WXC2-SMI DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, + OBJECT-IDENTITY, + FROM SNMPv2-SMI + IWV_Products + FROM IWV-SMI; + +WXC2 MODULE-IDENTITY + LAST-UPDATED "200506050000Z" + ORGANIZATION "interWAVE, Inc." + CONTACT-INFO + "http://www.iwv.com" + DESCRIPTION + "The Structure of Management Information for the WXC2 of interWAVE enterprise." + REVISION "200506050000Z" + DESCRIPTION + "1st version of this MIB module." + ::= { IWV_Products 3 } + +-- WXC2_PCM +PCM OBJECT-IDENTITY + STATUS current + DESCRIPTION + "PCM " + ::= { WXC2 1 } + + +-- WXC2_platform +Platform OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Platform " + ::= { WXC2 2 } + +-- WXC2_App + +App OBJECT-IDENTITY + STATUS current + DESCRIPTION + "App platform" + ::= { WXC2 3 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMSC-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMSC-MIB.txt.svn-base new file mode 100644 index 0000000..d6a5a82 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SMSC-MIB.txt.svn-base @@ -0,0 +1,259 @@ +WXC2-SMSC-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +SMSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "[SubSystem_Module]Subsystems for SMSC . " + ::= { App 5 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for SMSC . " + ::= { SMSC 2 } + +System_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " system parameter . " + ::= { Configuration 1 } + + + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]SMSC CDR + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [2]SMSC LOG + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [3]Reserved + { + [u]0.2-0.7 + [u]select + } + + Remark: SMSC CDR generation enable or disable. + [End] + " + ::= { System_Param 1 } + +SM_Validity OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 0000A8C0 + Field: [1]SM validity + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Period of validity of short message, define a threshold how long an awaiting sending message should be kept in sending array till sent to MS, unit is second, default=0c0a8h seconds=12 hours. + [End] + " + ::= { System_Param 2 } + +MSISDN_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 16 + Length: 19 + Default: 8675557127000EEEEE8675557127999EEEEE00 + Field: [1]Start MSISDN + { + [u]00.0-08.7 + [u]input + [v]keepHex-low-E + } + [2]End MSISDN + { + [u]09.0-17.7 + [u]input + [v]keepHex-low-E + } + [3]Number Type + { + [u]18.0-18.7 + [u]select + [v]0[opt]GSM + [v]1[opt]CDMA + } + Remark: Specify the beginning MSISDN for the range of provisioned subscriber. F=end tag. + [End] + " + ::= { System_Param 3 } + +SMPP_parameters OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 32 + Length: 12 + Default: 000000000000000000000000 + Field: [1]Enable flag + { + [u]00.0-00.7 + [u]select + [v]00[opt]Disable + [v]01[opt]Enable + } + [2]Session type + { + [u]01.0-01.7 + [u]select + [v]00[opt]BIND_TX + [v]01[opt]BIND_RX + [v]02[opt]BIND_TRX + } + [3]Service number + { + [u]02.0-9.7 + [u]input + [v]toAscii-low-0 + } + [4]Message mode + { + [u]10.0-10.7 + [u]select + [v]00[opt]Store and forward + [v]01[opt]Datagram + [v]02[opt]Transaction + } + [5]Data Coding Scheme + { + [u]11.0-11.7 + [u]select + [v]00[opt]To smpp=7bit,default=7bit + [v]01[opt]To smpp=8bit,default=7bit + [v]16[opt]To smpp=7bit,default=8bit + [v]17[opt]To smpp=8bit,default=8bit + } + Remark: Name: Can be any name, generally use the name of the connected device. + Service number: SMPP connected party MSISDN used for display on MT MS, + e.g. for a SMPP to PPS, set the service number as MSISDN of PPS. + Data coding scheme: + 00:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 7bit + 01:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 7bit + 10:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 8bit + 11:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 8bit + Default=0. + [End] + " + ::= { Configuration 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management for SMSC . + " + ::= { SMSC 3 } + +SMSC_ID OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]SMSC ID + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-E + } + Remark: SMSC ID + [End] + " + ::= { Management 1 } + +Software_Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Version + { + [u]00.0-02.7 + [u]input + [v]keepHex-low-E + } + Remark: Software version + [End] + " + ::= { Management 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Flag: S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]01[opt]Save parameters + [v]04[opt]Reset system + [v]05[opt]Delete pending SM + } + Remark: SMSC system command. + Save parameters: Save the SMSC parameters in memory to SMSC harddisk. + Delete pending SM: Delete the pending SM in awaiting array. + [End] + " + ::= { Management 3 } + + + +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SS7-MIB.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SS7-MIB.txt.svn-base new file mode 100644 index 0000000..a642454 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/WXC2-SS7-MIB.txt.svn-base @@ -0,0 +1,3729 @@ +WXC2-SS7-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + Platform + FROM WXC2-SMI; + +SS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for SS7 . + " + ::= { Platform 2 } + + +-- +-- sub system MTP3 +-- + +MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for MTP3 . + " + ::= { SS7 2 } + +Config_MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MTP3 Configuration. " + ::= { MTP3 2 } + +Network_Indicator OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]International network + { + [u]0.0-0.0 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [2]International network spare + { + [u]0.1-0.1 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [3]National network + { + [u]0.2-0.2 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [4]National network spare + { + [u]0.3-0.3 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [5]International network + { + [u]0.4-0.4 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [6]International network spare + { + [u]0.5-0.5 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [7]National network + { + [u]0.6-0.6 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [8]National network spare + { + [u]0.7-0.7 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + Remark: MTP3 network indicator. + [End] + " + ::= { Config_MTP3 2 } + + + + +OPC OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Originating point code. " + ::= { Config_MTP3 3 } + +International_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 1 } + +International_Spare_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 2 } + +National_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 3 } + +National_Spare_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 4 } + +International_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 5 } + +International_Spare_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 6} + +National_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 7 } + +National_Spare_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 8 } + +Linkset OBJECT-IDENTITY + STATUS current + DESCRIPTION + " linkset. " + ::= { Config_MTP3 4 } + +Linkset_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 4 + Default: 00000000 + Field: [1]Linkset DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Network indicator + { + [u]3.0-3.1 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [3]Reserved + { + [u]3.2-3.2 + [u]select + } + [4]Linkset loopback + { + [u]3.3-3.3 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [5]Reserved + { + [u]3.4-3.7 + [u]select + } + Remark: Opposite point code: The opposite point code of the linkset. + Network indicator: The network type of the opposite point code. + Loop back: Loop back enable or disable, used for MSC loop back link. + [End] + " + ::= { Linkset 1 } + +Link OBJECT-IDENTITY + STATUS current + DESCRIPTION + " link. " + ::= { Config_MTP3 5 } + +Link_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 15 + Default: 8010FFFFFFFF000000000000000000 + Field: [1]Linkset no. + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + [2]SLC no. + { + [u]01.0-01.7 + [u]input + [v]toDec-high-0 + } + [3]CPC IP + { + [u]02.0-05.7 + [u]input + [v]keepHex-high-0 + } + [4]Link Type + { + [u]06.0-06.0 + [u]select + [v]0[opt]Non-sigtran + [v]1[opt]Sigtran + } + [5]Link Enable + { + [u]06.1-06.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [6]MTP3-Lite Enable + { + [u]06.2-06.2 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [7]Reserved + { + [u]06.3-06.7 + [u]select + } + [8]SG no. + { + [u]07.0-07.7 + [u]input + [v]toDec-high-0 + } + [9]M2UA Interface ID + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + [10]MTP3-Lite Remote IP + { + [u]09.0-12.7 + [u]input + [v]keepHex-high-0 + } + [11]MTP3-Lite Inactivity Timeout + { + [u]13.0-13.7 + [u]input + [v]toDec-high-0 + } + [12]MTP3-Lite Allowed Inactivity Timeouts + { + [u]14.0-14.7 + [u]input + [v]toDec-high-0 + } + Remark: E1 link attributes. + Linkset no.: Assign linkset to E1 link, MSC has up to 128 linksets (0-127). 128=TCH E1. + SLC no.: Assign SLC to each E1 link of a linkset, each linkset has up to 13 E1 links (0-15). + IP: E1 link management IP. The third byte of CPC IP: + 98=E1 link 0-127, 99=E1 link 128-255. + Default=0x000032. + [End] + " + ::= { Link 1 } + +Link_Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 01 + Field: [1]E1 link + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + [v]2[opt]Inhibit + [v]3[opt]Uninhibit + } + Remark: Used for E1 link control, not affect call traffic. + Disable=Disable E1 link MTP2 layer. + Enable=Enable a disabled E1 link MTP2 layer. + Inhibit=Inhibit E1 link MTP3 layer. + Uninhibit=Uninhibit a inhibited E1 link MTP3 layer. + Default=Enable a disabled E1 link MTP2 layer. + [End] + " + ::= { Link 2 } + +TCP_Port OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-writed + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1388 + Field: [1]TCP Port + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + Remark: TCP server port for SCCP-Lite. + [End] + " + ::= { Link 3 } + +Routing OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Routing. " + ::= { Config_MTP3 6 } + +International OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 1 } + +International_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 2 } + +National OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 3 } + +National_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 4 } + +SPC_to_ACN OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SPC to ACN. " + ::= { Config_MTP3 7 } + +Local_ACN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 1 } + +International OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 2 } + +International_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 3 } + +National OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 4 } + +National_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 5 } + +Signaling_Gateway OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 7 + Default: 00000000000000 + Field: [1]Enable + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Server + { + [u]01.0-01.7 + [u]select + [v]0[opt]Client + [v]1[opt]Server + } + [3]ACK + { + [u]02.0-02.7 + [u]select + [v]0[opt]no ACK + [v]1[opt]ACK + } + [4]IP + { + [u]03.0-06.7 + [u]input + [v]keepHex-high-0 + } + Remark: SG attributes + [End] + " + ::= { Config_MTP3 9 } + +Status_MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MTP3 Status. " + ::= { MTP3 3 } + +Link_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 01 + Field: [1]Link status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Inhibited + } + Remark: E1 link MTP3 status (Read Only). + [End] + " + ::= { Status_MTP3 1 } + +Linkset_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 1 + Default: 01 + Field: [1]Linkset status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Reserved + } + Remark: Linkset status (Read only). + [End] + " + ::= { Status_MTP3 2 } + +International_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8A + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 3 } + +International_Spare_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 4 } + +National_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 5 } + +National_Spare_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 6 } + + + +Command_MTP3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag :S1.3 + Field: [1]command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No command + [v]1[opt]Reset + [v]2[opt]Save parameter + } + Remark: Control command for MTP3 platform. + Reset=status initialization. + Save parameter=save parameters residing in memory into harddisk. + [End] + " + ::= { Status_MTP3 7 } + +-- +-- sub system SCCP +-- + +SCCP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for SCCP . + " + ::= { SS7 3 } + +Config_SCCP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SCCP Configuration. " + ::= { SCCP 2 } + +Local_Node OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Local Node. " + ::= { Config_SCCP 1 } + +OMC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: OMC E.134 number. + IP0: OMC0 IP, 172.18.128.1. + IP1: OMC1 IP, 172.18.129.1. + [End] + " + ::= { Local_Node 4 } + +HLR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: HLR E.134 number. + IP0: HLR0 IP, 172.18.98.1. + IP1: HLR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 6 } + +VLR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VLR E.134 number. + IP0: VLR0 IP, 172.18.98.1. + IP1: VLR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 7 } + +MSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: MSC E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 8 } + +EIR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: EIR E.134 number. + IP0: EIR0 IP, 172.18.98.1. + IP1: EIR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 9 } + +AUC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: AUC E.134 number. + IP0: AUC0 IP, 172.18.98.1. + IP1: AUC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 10 } + +SMSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: SMSC E.134 number. + IP0: OMC0 IP, 172.18.98.1. + IP1: OMC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 11 } + +SMPP_EMSE OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VMS-SMPP E.134 number. + IP0: VMS0 IP, 172.18.147.1. + IP1: VMS1 IP, 172.18.148.1. + [End] + " + ::= { Local_Node 19 } + +SMPP_SMSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: SMSC-SMPP E.134 number. + IP0: SMSC0 IP, 172.18.98.1. + IP1: SMSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 20 } + +SMPP_OMC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: OMC-SMPP E.134 number. + IP0: OMC0 IP, 172.18.128.1. + IP1: OMC1 IP, 172.18.129.1. + [End] + " + ::= { Local_Node 21 } + +SRF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VMS SRF E.134 number. + IP0: VMS0 IP, 172.18.147.1. + IP1: VMS1 IP, 172.18.148.1. + [End] + " + ::= { Local_Node 22 } + +SSF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: MSC SSF E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 143 } + +SCF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: PPS SCF E.134 number. + IP0: PPS0 IP, 172.18.98.1. + IP1: PPS1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 147 } + +AIF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: AIF E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 254 } + +GTT_Table OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 43 + Default: 000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000007000000FFFFFFFFFFFFFFFFFFFF + Field: [1]On/off + { + [u]00.0-00.7 + [u]select + [v]1[opt]On + [v]0[opt]Off + } + [2]Numbering plan + { + [u]01.0-01.7 + [u]select + [v]0[opt]0 + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } + [3]TT + { + [u]02.0-02.7 + [u]input + [v]keepHex-low-F + } + [4]Start GT number + { + [u]03.0-12.7 + [u]input + [v]keepHex-low-F + } + [4]End GT number + { + [u]13.0-22.7 + [u]input + [v]keepHex-low-F + } + [5]Network indicator + { + [u]23.0-23.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + } + [6]DPC + { + [u]24.0-26.7 + [u]input + [v]toDec-high-0 + } + [7]SSN + { + [u]27.0-27.7 + [u]input + [v]toDec-high-0 + } + [8]Route indicator + { + [u]28.0-28.7 + [u]select + [v]0[opt]Route on GT + [v]1[opt]Route on SSN + } + [9]Address indicator + { + [u]29.0-29.7 + [u]select + [v]0[opt]NULL + [v]3[opt]DPC+SSN + [v]6[opt]GT+SSN + [v]7[opt]GT+DPC+SSN + } + [10]Replaced start digit + { + [u]30.0-30.7 + [u]input + [v]keepHex-high-0 + } + [11]Replaced end digit + { + [u]31.0-31.7 + [u]input + [v]keepHex-high-0 + } + [12]Outgoing number plan + { + [u]32.0-32.7 + [u]select + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } + [13]Replacing digits + { + [u]33.0-42.7 + [u]input + [v]keepHex-low-F + } + Remark: On/off: GTT flag, off=disable, on=enable. + Numbering plan: 1=MSISDN, 3=IMSI, 7=GT. + Specify the beginning number of a group of consecutive numbers routed by GTT, for single-number GTT route, the start number is same as the end number. + End GT number: Specify the end number of a group of consecutive number routed by GT. If there are some inconsecutive numbers for a same destination, a different GTT record should be set. + Network indicator (NI): 0=International network, 1=International network spare, 2=National network, 3=National network spare, + DPC: Destination point code. + SSN: Subsystem number. + 2=Reserved for ITU-T allocation. + 3=ISDN user part. + 4=OMC. + 5=MAP. + 3=HLR. + 7=VLR. + 8=MSC. + 9=EIR. + 10=AUC. + 11=SMSC. + 147=PPS. + 254=BSSMAP. + Route indicator: For IMSI and MSISDN, select Route on SSN. For the record of the connected network, select Route on GT. + Address indicator: select the contribution of SCCP Address. + Replaced start digit: Specify the beginning digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. + Replaced end digit: Specify the end digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. + Outgoing number plan: Outgoing number plan, include MSISDN, IMSI and GT. + Replacing digits: Replacing digits, the length of replacing digits and replaced digits may be different. + [End] + " + ::= { Config_SCCP 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Management. " + ::= { SCCP 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: + Remark: Version of SCCP platform software (Read Only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { Management 1 } + +Command_SCCP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag : S1.2 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]0[opt]Reset + [v]2[opt]Save parameters + } + Remark: Control command for SCCP. + Reset: Used for SCCP status initialization. + Load parameter: Load the parameters from device's harddisk to device's memory. + Save parameter: Save the parameters residing in device's memory into device's harddisk. + [End] + " + ::= { Management 2 } + +-- +-- sub system XAPP +-- + +XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for XAPP . + " + ::= { SS7 5 } + +Config_XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Configuration. " + ::= { XAPP 2 } + +MCC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 460E + Field: [1]MCC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + + Remark: Mobile country code. + [End] + " + ::= { Config_XAPP 1 } + +MNC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Field: [1]MNC + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-E + } + Remark: Mobile network code. + [End] + " + ::= { Config_XAPP 2 } + +CC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 86EE + Field: [1]CC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + Remark: Country code. + [End] + " + ::= { Config_XAPP 3 } + +NDC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 755EEE + Field: [1]NDC + { + [u]00.0-02.7 + [u]input + [v]keepHex-low-E + } + Remark: National destination code. + [End] + " + ::= { Config_XAPP 4 } + +International_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 00ee + Field: [1]International prefix + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + Remark: International call prefix. + [End] + " + ::= { Config_XAPP 5 } + +National_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0EEE + Field: [1]National prefix + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + + Remark: National call prefix. + [End] + " + ::= { Config_XAPP 6 } + +Local_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: EEEE + Field: + Remark: Local prefix. + [End] + " + ::= { Config_XAPP 7 } + +Conv_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 35 + Default: 0000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]Prefix + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + [2]Delete length + { + [u]16.0-16.7[u]input + [v]toDec-high-0 + } + [3]Add length + { + [u]17.0-17.7 + [u]input + [v]toDec-high-0 + } + [4]Add digits + { + [u]18.0-33.7 + [u]input + [v]toAscii-low-0 + } + [5]Valid length + { + [u]34.0-34.7 + [u]input + [v]toDec-high-0 + } + Remark: Conv prefix . + [End] + " + ::= { Config_XAPP 8 } + +CLI_Conv_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 37 + Default: 0000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]In property + { + [u]00.0-00.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } + [2]Prefix + { + [u]01.0-16.7 + [u]input + [v]toAscii-low-0 + } + [3]Delete length + { + [u]17.0-17.7 + [u]input + [v]toDec-high-0 + } + [4]Out property + { + [u]18.0-18.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } + [5]Add length + { + [u]19.0-19.7 + [u]input + [v]toDec-high-0 + } + [6]Add digits + { + [u]20.0-35.7 + [u]input + [v]toAscii-low-0 + + } + [7]Valid length + { + [u]36.0-36.7 + [u]input + [v]toDec-high-0 + } + Remark: CLI_Conv prefix . + [End] + " + ::= { Config_XAPP 9 } + +mscid_to_number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 12 + Default: 00000000EEEEEEEEEEEEEEEE + Field: + + [1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + [2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + [3]SSN + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [4]Number + { + [u]04.0-11.7 + [u]input + [v]keepHex-low-E + } + Remark: Conv prefix . + [End] + " + ::= { Config_XAPP 10 } + +Status_XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Status. " + ::= { XAPP 3 } + +Version_XAPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: + Remark: Version of XAPP module (Read Only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { Status_XAPP 1 } + +Command_XAPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag: S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]01[opt]Save parameters + } + Remark: Control command for XAPP. + Save parameter: Save the parameters in memory into local harddisk. + [End] + " + ::= { Status_XAPP 2 } + +Maplat OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for Maplat . + " + ::= { Platform 3 } +-- +-- sub system SMPP +-- + +SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for SMPP . + " + ::= { Maplat 4 } + +Config_SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SMPP Configuration. " + ::= { SMPP 2 } +SMPP_Link_Parameter OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 32 + Length: 106 + Default: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field:[1]Link enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Link type + { + [u]1.0-1.7 + [u]select + [v]0[opt]UDP + [v]1[opt]TCP + } + [3]Server type + { + [u]2.0-2.7 + [u]select + [v]0[opt]SMPP_CLIENT + [v]1[opt]SMPP_SERVER + } + [4]Session type + { + [u]3.0-3.7 + [u]select + [v]00[opt]BIND_TX + [v]01[opt]BIND_RX + [v]02[opt]BIND_TRX + } + [5]System ID + { + [u]4.0-19.7 + [u]input + [v]toAscii-low-0 + } + [6]Password + { + [u]20.0-28.7 + [u]input + [v]toAscii-low-0 + } + [7]System type + { + [u]29.0-41.7 + [u]input + [v]toAscii-low-0 + } + [8]Local GTT + { + [u]42.0-57.7 + [u]input + [v]toAscii-low-0 + } + [9]Remote GTT + { + [u]58.0-73.7 + [u]input + [v]toAscii-low-0 + } + [10]Local IP + { + [u]74.0-77.7 + [u]input + [v]keepHex-low-F + } + [11]Remote IP + { + [u]78.0-81.7 + [u]input + [v]keepHex-low-F + } + [12]Session init timer + { + [u]82.0-85.7 + [u]input + [v]toDec-high-0 + } + [13]Enquire link timer + { + [u]86.0-89.7 + [u]input + [v]toDec-high-0 + } + [14]Inactivity timer + { + [u]90.0-93.7 + [u]input + [v]toDec-high-0 + } + [15]Response timer + { + [u]94.0-97.7 + [u]input + [v]toDec-high-0 + } + [16]Remote service number + { + [u]98.0-105.7 + [u]input + [v]toAscii-low-0 + } + + Remark: Session type: BIND_TX-bind as transmitter, BIND_RX-bind as receiver, BIND_TRX-bind as transceiver. + System ID: using in BIND and OUTBIND. + Password: The password parameter is used by the SMSC to authenticate the identity of the binding ESME. The Service Provider may require ESME¡¯s to provide a password when binding to the SMSC. This password is normally issued by the SMSC system administrator. + The password parameter may also be used by the ESME to authenticate the identity of the binding SMSC (e.g. in the case of the outbind operation). + System type: The system_type may be used to categorise the system, e.g., ¡°EMAIL¡±, ¡°WWW¡±, etc. + The system_type parameter is used to categorize the type of ESME that is binding to the SMSC. Examples include ¡°VMS¡± (voice mail system) and ¡°OTA¡± (over-the-air activation system). + Specification of the system_type is optional - some SMSC¡¯s may not require ESME¡¯s to provide this detail. In this case, the ESME can set the system_type to NULL. + IP: Specify the IP addresses of 16 SMPP connected devices.
e.g. 0xAC127001=172.18.112.1.
+ Session init timer: This timer specifies the time lapse allowed between a network connection being established and a bind_transmitter or bind_receiver request being sent to SMSC. This timer should be active on the SMSC. + Enquire link timer: This timer specifies the time lapse allowed between operations after which an SMPP entity should interrogate whether it's peer still has an active session. + The scale is second. + Inactivity timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) + Response timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) + Local service number: compare with application's service number while bind as TX or TRX. + remote service number: compare with application's service number while bind as RX + [End] + " + ::= { Config_SMPP 1 } + + +Status_SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Status. " + ::= { SMPP 3 } + +Command_SMPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Flag :S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]2[opt]save parameter + } + Remark: Control command for SMPP. + [End] + " + ::= { Status_SMPP 2 } + + +END diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_page.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_page.svn-base new file mode 100644 index 0000000..7edaddc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_page.svn-base @@ -0,0 +1,13 @@ + + ******************* + * Module Page * + ******************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- PPS + d -- TCAP l -- SNMP + e -- XAPP m -- M2UA + f -- MSC n -- DEBUG + g -- VLR o -- AUC + h -- SSF p -- EIR diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_tree.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_tree.txt.svn-base new file mode 100644 index 0000000..2f52696 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/menu_tree.txt.svn-base @@ -0,0 +1,908 @@ +############## The debug menu tree config file root=wxc2 root_oid={1.3.6.1.4.1.1373.1.3} +#(0)(1)(2)(9) ip group +#/ the layer +#.1.1.3. menu_id +#{3.2.2.1.2} the last oid from the root +#[name] menu name +#M:8 the id of the menu in the current object +############## all the line must end for ';',and menu id and last oid must do not contain space + +##WXC2 +/. (9); + +M:1 [MSC] {3.2}; +M:2 [VLR] {3.2.5}; +M:3 [HLR] {3.3}; +M:4 [PPS] {3.6}; +M:5 [SMSC] {3.5}; +M:6 [AUC] {3.4}; +##M:7 [EIR] {3.8}; + +##MSC +/ /.1. (9); + +M:1 [Prefix Assignment] {3.2.2.2.1.1}; +M:2 [Prefix Attributes] {3.2.2.2.1.2}; +M:3 [Assign TG to Prefix] {3.2.2.2.1.3}; +M:4 [TG attributes] {3.2.2.2.1.4}; +M:5 [CDR Flag] {3.2.2.2.1.5}; +M:6 [Announcement Option] {3.2.2.2.1.6}; +M:7 [Warning tone] {3.2.2.2.1.7}; +M:8 [Emergency call] {3.2.2.2.2.5}; +M:9 [Location management] {3.2.2.2.2.8}; +M:10 [Max. call duration] {3.2.2.2.3.7}; +M:11 [E1 Port] {3.2.2.2.4}; +M:12 [channel attributes] {3.2.2.2.5}; +M:13 [Platform] {2}; +M:14 [MSC0] (1) {3.2}; +M:15 [MSC1] (2) {3.2}; + +##MSC->E1 Port +/ / /.1.11. (9); + +M:1 [E1 interface] {3.2.2.2.4.1}; +M:2 [Assign TG to E1] {3.2.2.2.4.2}; +M:3 [CIC of E1] {3.2.2.2.4.3}; + +##MSC->channel attributes->8K card 0-31 +/ / /.1.12. (9); + +M:1 [Card 0 channel attributes] {3.2.2.2.5.1}; +M:2 [Card 1 channel attributes] {3.2.2.2.5.2}; +M:3 [Card 2 channel attributes] {3.2.2.2.5.3}; +M:4 [Card 3 channel attributes] {3.2.2.2.5.4}; +M:5 [Card 4 channel attributes] {3.2.2.2.5.5}; +M:6 [Card 5 channel attributes] {3.2.2.2.5.6}; +M:7 [Card 6 channel attributes] {3.2.2.2.5.7}; +M:8 [Card 7 channel attributes] {3.2.2.2.5.8}; +M:9 [Card 8 channel attributes] {3.2.2.2.5.9}; +M:10 [Card 9 channel attributes] {3.2.2.2.5.10}; +M:11 [Card 10 channel attributes] {3.2.2.2.5.11}; +M:12 [Card 11 channel attributes] {3.2.2.2.5.12}; +M:13 [Card 12 channel attributes] {3.2.2.2.5.13}; +M:14 [Card 13 channel attributes] {3.2.2.2.5.14}; +M:15 [Card 14 channel attributes] {3.2.2.2.5.15}; +M:16 [Card 15 channel attributes] {3.2.2.2.5.16}; +M:17 [Card 16 channel attributes] {3.2.2.2.5.17}; +M:18 [Card 17 channel attributes] {3.2.2.2.5.18}; +M:19 [Card 18 channel attributes] {3.2.2.2.5.19}; +M:20 [Card 19 channel attributes] {3.2.2.2.5.20}; +M:21 [Card 20 channel attributes] {3.2.2.2.5.21}; +M:22 [Card 21 channel attributes] {3.2.2.2.5.22}; +M:23 [Card 22 channel attributes] {3.2.2.2.5.23}; +M:24 [Card 23 channel attributes] {3.2.2.2.5.24}; +M:25 [Card 24 channel attributes] {3.2.2.2.5.25}; +M:26 [Card 25 channel attributes] {3.2.2.2.5.26}; +M:27 [Card 26 channel attributes] {3.2.2.2.5.27}; +M:28 [Card 27 channel attributes] {3.2.2.2.5.28}; +M:29 [Card 28 channel attributes] {3.2.2.2.5.29}; +M:30 [Card 29 channel attributes] {3.2.2.2.5.30}; +M:31 [Card 30 channel attributes] {3.2.2.2.5.31}; +M:32 [Card 31 channel attributes] {3.2.2.2.5.32}; + + +##MSC->Platform +/ / /.1.13. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##MSC->Platform->MTP3 +/ / /.1.13.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [ACN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##MSC->Platform->MTP3->Status +/ / /.1.13.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##MSC->Platform->SCCP +/ / /.1.13.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##MSC->Platform->XAPP +/ / /.1.13.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + + +##MSC->MSC0->E1 status +/ / /.1.14. (1); + +M:1 [E1 Status] {3.2.2.3.4}; +M:2 [Channel Status] {3.2.2.3.5}; +##M:3 [CSU0] {1.1}; + + +##MSC->MSC1->E1 status +/ / /.1.15. (2); + +M:1 [E1 Status] {3.2.2.3.4}; +M:2 [Channel Status] {3.2.2.3.5}; +##M:3 [CSU1] {1.1}; + + +##MSC->MSC0->Channel Status +/ / / /.1.14.2. (1); + +M:1 [8K Card 0] {3.2.2.3.5.1}; +M:2 [8K Card 1] {3.2.2.3.5.2}; +M:3 [8K Card 2] {3.2.2.3.5.3}; +M:4 [8K Card 3] {3.2.2.3.5.4}; +M:5 [8K Card 4] {3.2.2.3.5.5}; +M:6 [8K Card 5] {3.2.2.3.5.6}; +M:7 [8K Card 6] {3.2.2.3.5.7}; +M:8 [8K Card 7] {3.2.2.3.5.8}; +M:9 [8K Card 8] {3.2.2.3.5.9}; +M:10 [8K Card 9] {3.2.2.3.5.10}; +M:11 [8K Card 10] {3.2.2.3.5.11}; +M:12 [8K Card 11] {3.2.2.3.5.12}; +M:13 [8K Card 12] {3.2.2.3.5.13}; +M:14 [8K Card 13] {3.2.2.3.5.14}; +M:15 [8K Card 14] {3.2.2.3.5.15}; +M:16 [8K Card 15] {3.2.2.3.5.16}; + + +##MSC->MSC1->channel status +/ / / /.1.15.2. (2); + +M:1 [8K Card 0] {3.2.2.3.5.1}; +M:2 [8K Card 1] {3.2.2.3.5.2}; +M:3 [8K Card 2] {3.2.2.3.5.3}; +M:4 [8K Card 3] {3.2.2.3.5.4}; +M:5 [8K Card 4] {3.2.2.3.5.5}; +M:6 [8K Card 5] {3.2.2.3.5.6}; +M:7 [8K Card 6] {3.2.2.3.5.7}; +M:8 [8K Card 7] {3.2.2.3.5.8}; +M:9 [8K Card 8] {3.2.2.3.5.9}; +M:10 [8K Card 9] {3.2.2.3.5.10}; +M:11 [8K Card 10] {3.2.2.3.5.11}; +M:12 [8K Card 11] {3.2.2.3.5.12}; +M:13 [8K Card 12] {3.2.2.3.5.13}; +M:14 [8K Card 13] {3.2.2.3.5.14}; +M:15 [8K Card 14] {3.2.2.3.5.15}; +M:16 [8K Card 15] {3.2.2.3.5.16}; + + +##MSC->MSC0->CSU0 +##/ / / / /.1.14.3. (1); + +##M:1 [E1 enable] {1.1.1.2.1}; +##M:2 [MTP alarm on/off] {1.1.1.2.2}; +##M:3 [Link type] {1.1.1.2.3}; +##M:4 [NT/LT] {1.1.1.2.4}; +##M:5 [DPLL priority] {1.1.1.2.5}; +##M:6 [CRC4 flag] {1.1.1.2.6}; +##M:7 [Ringback Tone] {1.1.1.2.7.1}; +##M:8 [Busy Tone] {1.1.1.2.7.2}; +##M:9 [Unavailable Tone] {1.1.1.2.7.3}; +##M:10 [Congestion Tone] {1.1.1.2.7.4}; +##M:11 [Proceeding Tone] {1.1.1.2.7.5}; +##M:12 [Warning tone] {1.1.1.2.7.6}; +##M:13 [Tone assignment] {1.1.1.2.7.9}; +##M:14 [DTMF mark&space] {1.1.1.2.7.10}; +##M:15 [8KE1_0] (0) {1.1.1.3}; +##M:16 [8KE1_1] (0) {1.1.1.3}; +##M:17 [8KE1_2] (0) {1.1.1.3}; +##M:18 [8KE1_3] (0) {1.1.1.3}; +##M:19 [8KE1_4] (0) {1.1.1.3}; +##M:20 [8KE1_5] (0) {1.1.1.3}; +##M:21 [8KE1_6] (0) {1.1.1.3}; +##M:22 [8KE1_7] (0) {1.1.1.3}; +##M:23 [8KE1_8] (0) {1.1.1.3}; +##M:24 [8KE1_9] (0) {1.1.1.3}; +##M:25 [8KE1_10] (0) {1.1.1.3}; +##M:26 [8KE1_11] (0) {1.1.1.3}; +##M:27 [8KE1_12] (0) {1.1.1.3}; +##M:28 [8KE1_13] (0) {1.1.1.3}; +##M:29 [8KE1_14] (0) {1.1.1.3}; +##M:30 [8KE1_15] (0) {1.1.1.3}; + + +##MSC->MSC1->CSU1 +##/ / / / /.1.15.3. (2); + +##M:1 [E1 enable] {1.1.1.2.1}; +##M:2 [MTP alarm on/off] {1.1.1.2.2}; +##M:3 [Link type] {1.1.1.2.3}; +##M:4 [NT/LT] {1.1.1.2.4}; +##M:5 [DPLL priority] {1.1.1.2.5}; +##M:6 [CRC4 flag] {1.1.1.2.6}; +##M:7 [Ringback Tone] {1.1.1.2.7.1}; +##M:8 [Busy Tone] {1.1.1.2.7.2}; +##M:9 [Unavailable Tone] {1.1.1.2.7.3}; +##M:10 [Congestion Tone] {1.1.1.2.7.4}; +##M:11 [Proceeding Tone] {1.1.1.2.7.5}; +##M:12 [Warning tone] {1.1.1.2.7.6}; +##M:13 [Tone assignment] {1.1.1.2.7.9}; +##M:14 [DTMF mark&space] {1.1.1.2.7.10}; +##M:15 [8KE1_0] (0) {1.1.1.3}; +##M:16 [8KE1_1] (0) {1.1.1.3}; +##M:17 [8KE1_2] (0) {1.1.1.3}; +##M:18 [8KE1_3] (0) {1.1.1.3}; +##M:19 [8KE1_4] (0) {1.1.1.3}; +##M:20 [8KE1_5] (0) {1.1.1.3}; +##M:21 [8KE1_6] (0) {1.1.1.3}; +##M:22 [8KE1_7] (0) {1.1.1.3}; +##M:23 [8KE1_8] (0) {1.1.1.3}; +##M:24 [8KE1_9] (0) {1.1.1.3}; +##M:25 [8KE1_10] (0) {1.1.1.3}; +##M:26 [8KE1_11] (0) {1.1.1.3}; +##M:27 [8KE1_12] (0) {1.1.1.3}; +##M:28 [8KE1_13] (0) {1.1.1.3}; +##M:29 [8KE1_14] (0) {1.1.1.3}; +##M:30 [8KE1_15] (0) {1.1.1.3}; + +##VLR +/ / /.2. (9); + +M:1 [OptAuthReq] {3.2.5.2.1.1}; +M:2 [OpReuseTriplets] {3.2.5.2.1.2}; +M:3 [OptCipReq] {3.2.5.2.1.3}; +M:4 [OptCiphAlgo] {3.2.5.2.1.4}; +M:5 [OptTmsiAlloc] {3.2.5.2.1.5}; +M:6 [OptEcsSetUpAllow] {3.2.5.2.1.7}; +M:7 [OptCheckIMEI] {3.2.5.2.1.8}; +M:8 [OptVlrPurge] {3.2.5.2.1.9}; +M:9 [idlePeriod2Purge] {3.2.5.2.1.10}; +M:10 [CDR flag] {3.2.5.2.1.11}; +M:11 [MSRN] {3.2.5.2.1.13}; +M:12 [VLR0] {3.2.5}; +M:13 [VLR1] {3.2.5}; + +##VLR->VLR0 + +/ / /.2.12. (1); + +M:1 [Version] {3.2.5.3.2}; +M:2 [Command] {3.2.5.3.3}; +M:3 [Status] {3.2.5.3.4}; + +##VLR->VLR0 + +/ / /.2.13. (2); + +M:1 [Version] {3.2.5.3.2}; +M:2 [Command] {3.2.5.3.3}; +M:3 [Status] {3.2.5.3.4}; + + +##HLR +/ / /.3. (9); + +M:1 [HPLMN] {3.3.2.1.11}; +M:2 [VPLMNs] {3.3.2.1.12}; +M:3 [CSRR list] {3.3.2.1.13}; +M:4 [Regional Subscription] {3.3.2.1.14}; +M:5 [License control] {3.3.2.1.15}; +M:6 [CDR control] {3.3.2.1.16}; +M:7 [Feature Code] {3.3.2.1.27}; +M:8 [Platform] {2}; +M:9 [HLR0] {3.3}; +M:10 [HLR1] {3.3}; + +##HLR->Platform +/ / /.3.8. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##HLR->Platform->MTP3 +/ / /.3.8.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [ACN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##HLR->Platform->MTP3->Status +/ / /.3.8.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##HLR->Platform->SCCP +/ / /.3.8.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##HLR->Platform->XAPP +/ / /.3.8.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##HLR->HLR0 + +/ / /.3.9. (1); + +M:1 [Command] {3.3.2.2.2}; +M:2 [Subscriber import] {3.3.2.2.3}; +M:3 [Max Licenses] {3.3.2.2.11}; +M:4 [Used Licenses] {3.3.2.2.12}; +M:5 [Subscriber information] {3.3.2.2.13}; +M:6 [Version] {3.3.2.2.14}; +M:7 [IMSI segment] {3.3.2.2.15}; +M:8 [MSISDN segment] {3.3.2.2.16}; +M:9 [CNF applicant info] {3.3.2.2.27}; +##M:10 [Contry code] {3.3.2.2.10}; + +##HLR->HLR0->Subscriber information + +/ / /.3.9.5. (1); + +M:1 [Provisioned subscribers] {3.3.2.2.13.1}; +M:2 [Registered subscribers] {3.3.2.2.13.2}; +M:3 [Roaming subscribers] {3.3.2.2.13.3}; + +##HLR->HLR0->Version +/ / /.3.9.6. (1); + +M:1 [Software] {3.3.2.2.14.1}; +M:2 [User data] {3.3.2.2.14.2}; + + +##HLR->HLR1 + +/ / /.3.10. (2); + +M:1 [Command] {3.3.2.2.2}; +M:2 [Subscriber import] {3.3.2.2.3}; +M:3 [Max Licenses] {3.3.2.2.11}; +M:4 [Used Licenses] {3.3.2.2.12}; +M:5 [Subscriber information] {3.3.2.2.13}; +M:6 [Version] {3.3.2.2.14}; +M:7 [IMSI segment] {3.3.2.2.15}; +M:8 [MSISDN segment] {3.3.2.2.16}; +M:9 [CNF applicant info] {3.3.2.2.27}; +##M:10 [Contry code] {3.3.2.2.10}; + +##HLR->HLR1->Subscriber information +/ / /.3.10.5. (2); + +M:1 [Provisioned subscribers] {3.3.2.2.13.1}; +M:2 [Registered subscribers] {3.3.2.2.13.2}; +M:3 [Roaming subscribers] {3.3.2.2.13.3}; + +##HLR->HLR1->Version +/ / /.3.10.6. (2); + +M:1 [Software] {3.3.2.2.14.1}; +M:2 [User data] {3.3.2.2.14.2}; + +##PPS +/ / /.4. (9); + +M:1 [Service control] {3.6.2.1.1}; +M:2 [SRF Number] {3.6.2.1.2.1}; +M:3 [Service number] {3.6.2.1.2.2}; +M:4 [Service key] {3.6.2.1.2.3}; +M:5 [COS Parameter] {3.6.2.1.4}; +M:6 [Call routing to VMS] {3.6.2.1.5}; +M:7 [Status] {3.6.2.1.6}; +M:8 [Platform] {2}; + +##PPS->Service control +/ / /.4.1. (9); + +M:1 [CDR flag] {3.6.2.1.1.1}; +M:2 [Blacklist threshhold] {3.6.2.1.1.2}; +M:3 [Maximun balance] {3.6.2.1.1.3}; +M:4 [license control] {3.6.2.1.1.4}; +M:5 [Prompt resolution] {3.6.2.1.1.5}; +M:6 [SMS Sentence] {3.6.2.1.1.6}; +M:7 [Last call info] {3.6.2.1.1.7}; +M:8 [Currency Symbol] {3.6.2.1.1.8}; +M:9 [Third party info] {3.6.2.1.1.9}; +M:10 [Basic Tariff Zone] {3.6.2.1.1.10}; + +##PPS->Service number +/ / /.4.3. (9); + +M:1 [Hotline] {3.6.2.1.2.2.1}; +M:2 [Inquiry] {3.6.2.1.2.2.2}; +M:3 [Scratch card rechagne] {3.6.2.1.2.2.3}; +M:4 [Credit card recharge] {3.6.2.1.2.2.4}; +M:5 [Third party recharge] {3.6.2.1.2.2.5}; +M:6 [Customer care center] {3.6.2.1.2.2.6}; +M:7 [Recharge] {3.6.2.1.2.2.7}; + +##PPS->Service key +/ / /.4.4. (9); + +M:1 [Inquiry] {3.6.2.1.2.3.2}; +M:2 [Scratch card rechagne] {3.6.2.1.2.3.3}; +M:3 [Credit card recharge] {3.6.2.1.2.3.4}; +M:4 [Set favorite number] {3.6.2.1.2.3.5}; +M:5 [Set password] {3.6.2.1.2.3.6}; + + +##PPS->COS Parameter +/ / /.4.5. (9); + +M:1 [COS0] {3.6.2.1.4.1}; +M:2 [COS1] {3.6.2.1.4.2}; +M:3 [COS2] {3.6.2.1.4.3}; +M:4 [COS3] {3.6.2.1.4.4}; +M:5 [COS4] {3.6.2.1.4.5}; +M:6 [COS5] {3.6.2.1.4.6}; +M:7 [COS6] {3.6.2.1.4.7}; +M:8 [COS7] {3.6.2.1.4.8}; +M:9 [COS8] {3.6.2.1.4.9}; +M:10 [COS9] {3.6.2.1.4.10}; +M:11 [COS10] {3.6.2.1.4.11}; +M:12 [COS11] {3.6.2.1.4.12}; +M:13 [COS12] {3.6.2.1.4.13}; +M:14 [COS13] {3.6.2.1.4.14}; +M:15 [COS14] {3.6.2.1.4.15}; +M:16 [COS15] {3.6.2.1.4.16}; + + +##PPS->COS Parameter->COS 0-15 +/ / /.4.5.1. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.1.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.1.2}; +M:3 [Account control] {3.6.2.1.4.1.3}; +M:4 [MT Call control] {3.6.2.1.4.1.4}; +M:5 [Validity control] {3.6.2.1.4.1.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.1.6}; + +/ / /.4.5.2. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.2.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.2.2}; +M:3 [Account control] {3.6.2.1.4.2.3}; +M:4 [MT Call control] {3.6.2.1.4.2.4}; +M:5 [Validity control] {3.6.2.1.4.2.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.2.6}; + +/ / /.4.5.3. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.3.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.3.2}; +M:3 [Account control] {3.6.2.1.4.3.3}; +M:4 [MT Call control] {3.6.2.1.4.3.4}; +M:5 [Validity control] {3.6.2.1.4.3.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.3.6}; + +/ / /.4.5.4. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.4.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.4.2}; +M:3 [Account control] {3.6.2.1.4.4.3}; +M:4 [MT Call control] {3.6.2.1.4.4.4}; +M:5 [Validity control] {3.6.2.1.4.4.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.4.6}; + +/ / /.4.5.5. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.5.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.5.2}; +M:3 [Account control] {3.6.2.1.4.5.3}; +M:4 [MT Call control] {3.6.2.1.4.5.4}; +M:5 [Validity control] {3.6.2.1.4.5.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.5.6}; + +/ / /.4.5.6. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.6.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.6.2}; +M:3 [Account control] {3.6.2.1.4.6.3}; +M:4 [MT Call control] {3.6.2.1.4.6.4}; +M:5 [Validity control] {3.6.2.1.4.6.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.6.6}; + +/ / /.4.5.7. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.7.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.7.2}; +M:3 [Account control] {3.6.2.1.4.7.3}; +M:4 [MT Call control] {3.6.2.1.4.7.4}; +M:5 [Validity control] {3.6.2.1.4.7.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.7.6}; + +/ / /.4.5.8. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.8.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.8.2}; +M:3 [Account control] {3.6.2.1.4.8.3}; +M:4 [MT Call control] {3.6.2.1.4.8.4}; +M:5 [Validity control] {3.6.2.1.4.8.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.8.6}; + +/ / /.4.5.9. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.9.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.9.2}; +M:3 [Account control] {3.6.2.1.4.9.3}; +M:4 [MT Call control] {3.6.2.1.4.9.4}; +M:5 [Validity control] {3.6.2.1.4.9.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.9.6}; + +/ / /.4.5.10. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.10.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.10.2}; +M:3 [Account control] {3.6.2.1.4.10.3}; +M:4 [MT Call control] {3.6.2.1.4.10.4}; +M:5 [Validity control] {3.6.2.1.4.10.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.10.6}; + +/ / /.4.5.11. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.11.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.11.2}; +M:3 [Account control] {3.6.2.1.4.11.3}; +M:4 [MT Call control] {3.6.2.1.4.11.4}; +M:5 [Validity control] {3.6.2.1.4.11.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.11.6}; + +/ / /.4.5.12. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.12.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.12.2}; +M:3 [Account control] {3.6.2.1.4.12.3}; +M:4 [MT Call control] {3.6.2.1.4.12.4}; +M:5 [Validity control] {3.6.2.1.4.12.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.12.6}; + +/ / /.4.5.13. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.13.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.13.2}; +M:3 [Account control] {3.6.2.1.4.13.3}; +M:4 [MT Call control] {3.6.2.1.4.13.4}; +M:5 [Validity control] {3.6.2.1.4.13.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.13.6}; + +/ / /.4.5.14. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.14.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.14.2}; +M:3 [Account control] {3.6.2.1.4.14.3}; +M:4 [MT Call control] {3.6.2.1.4.14.4}; +M:5 [Validity control] {3.6.2.1.4.14.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.14.6}; + +/ / /.4.5.15. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.15.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.15.2}; +M:3 [Account control] {3.6.2.1.4.15.3}; +M:4 [MT Call control] {3.6.2.1.4.15.4}; +M:5 [Validity control] {3.6.2.1.4.15.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.15.6}; + +/ / /.4.5.16. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.16.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.16.2}; +M:3 [Account control] {3.6.2.1.4.16.3}; +M:4 [MT Call control] {3.6.2.1.4.16.4}; +M:5 [Validity control] {3.6.2.1.4.16.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.16.6}; + + +##PPS->call routing to VMS +/ / /.4.6. (9); + +M:1 [VMS service number-PLMN] {3.6.2.1.5.1}; +M:2 [VMS service number-PSTN] {3.6.2.1.5.2}; +M:3 [VMS leave message number] {3.6.2.1.5.3}; +M:4 [Routing rule] {3.6.2.1.5.4}; +M:5 [VMS user segments] {3.6.2.1.5.5}; + +##PPS->Status +/ / /.4.7. (9); + +M:1 [Activaion] {3.6.2.1.6.1}; +M:2 [Command] {3.6.2.1.6.2}; + + +##PPS->Platform +/ / /.4.8. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; +M:4 [SMPP] {2.3.4} + +##PPS->Platform->MTP3 +/ / /.4.8.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##PPS->Platform->MTP3->Status +/ / /.4.8.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##PPS->Platform->SCCP +/ / /.4.8.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##PPS->Platform->XAPP +/ / /.4.8.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##PPS-->Platform->SMPP +/ / /.4.8.4. (9); + +M:1 [SMPP_Link_Param] {2.3.4.2.1}; +M:2 [Command] {2.3.4.3.2}; + + +## SMSC +/ / /.5. (9); + +M:1 [CDR flag] {3.5.2.1.1}; +M:2 [SM Validity] {3.5.2.1.2}; +M:3 [MSISDN Segment] {3.5.2.1.3}; +M:4 [SMPP parameters] {3.5.2.2}; +M:5 [Command] {3.5.3.3}; +M:6 [Platform] {2}; +M:7 [SMSC0] {3.5}; +M:8 [SMSC1] {3.5}; + + +##SMSC->Platform +/ / /.5.6. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; +M:4 [SMPP] {2.3.4}; + +##SMSC->Platform->MTP3 +/ / /.5.6.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##SMSC->Platform->MTP3->Status +/ / /.5.6.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##SMSC->Platform->SCCP +/ / /.5.6.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##SMSC->Platform->XAPP +/ / /.5.6.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##SMSC->Platform->SMPP +/ / /.5.6.4. (9); + +M:1 [SMPP_Link_Param] {2.3.4.2.1}; +M:2 [Command] {2.3.4.3.2}; + + +##SMSC->SMSC0 +/ / /.5.7. (1); + +M:1 [SMSC ID] {3.5.3.1}; +M:2 [Software version] {3.5.3.2}; + +##SMSC->SMSC1 +/ / /.5.8. (2); + +M:1 [SMSC ID] {3.5.3.1}; +M:2 [Software version] {3.5.3.2}; + +##AUC +/ / /.6. (9); + +M:1 [Platform] {2}; +M:2 [AUC0] (1) {3.4}; +M:3 [AUC1] (2) {3.4}; + + +##AUC->Platform +/ / /.6.1. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##AUC->Platform->MTP3 +/ / /.6.1.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##AUC->Platform->MTP3->Status +/ / /.6.1.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##AUC->Platform->SCCP +/ / /.6.1.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##AUC->Platform->XAPP +/ / /.6.1.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + + +##EIR +##/ / /.7. (9); + +##M:1 [Platform] {2}; +##M:2 [EIR0] (1) {3.8}; +##M:3 [EIR1] (2) {3.8}; + +##EIR->Platform +##/ / /.7.1. (9); + +##M:1 [MTP3] {2.2.2}; +##M:2 [SCCP] {2.2.3}; +##M:3 [XAPP] {2.2.5}; + +##EIR->Platform->MTP3 +##/ / /.7.1.1. (9); + +##M:1 [Network Indicator] {2.2.2.2.2}; +##M:2 [Originating Point code] {2.2.2.2.3}; +##M:3 [Link Set] {2.2.2.2.4}; +##M:4 [Link] {2.2.2.2.5}; +##M:5 [Routing] {2.2.2.2.6}; +##M:6 [CAN] {2.2.2.2.7}; +##M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##EIR->Platform->MTP3->Status +##/ / /.7.1.1.7. (9); + +####M:1 [Link status] {2.2.2.3.1}; +##M:2 [Link set status] {2.2.2.3.2}; +##M:3 [International routing] {2.2.2.3.3}; +##M:4 [International spare] {2.2.2.3.4}; +##M:5 [National routing] {2.2.2.3.5}; +##M:6 [National spare routing] {2.2.2.3.6}; +##M:7 [Command] {2.2.2.3.7}; + +##EIR->Platform->SCCP +##/ / /.7.1.2. (9); + +##M:1 [Local node] {2.2.3.2.1}; +##M:2 [GTT] {2.2.3.2.2}; +##M:3 [Command] {2.2.3.3.2}; + +##EIR->Platform->XAPP +##/ / /.7.1.3. (9); + +##M:1 [MCC] {2.2.5.2.1}; +##M:2 [MNC] {2.2.5.2.2}; +##M:3 [CC] {2.2.5.2.3}; +##M:5 [International prefix] {2.2.5.2.5}; +##M:6 [National Prefix] {2.2.5.2.6}; +##M:7 [Local Prefix] {2.2.5.2.7}; +##M:8 [Convert Prefix] {2.2.5.2.8}; +##M:9 [Command] {2.2.5.3.2}; diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_list_file.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_list_file.txt.svn-base new file mode 100644 index 0000000..c51c1d3 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_list_file.txt.svn-base @@ -0,0 +1,14 @@ +// "//" is the annotation characters; +IWV-SMI.txt +Special_App-SMI.txt +//PPPRT-MIB.txt +WXC2-SMI.txt +//WXC2-CSU-MIB.txt +WXC2-SS7-MIB.txt +WXC2-MSC-MIB.txt +WXC2-HLR-MIB.txt +WXC2-AUC-MIB.txt +//WXC2-EIR-MIB.txt +WXC2-SMSC-MIB.txt +WXC2-PPS-MIB.txt +WXC2-MSS-MIB.txt diff --git a/plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_write_tree.txt.svn-base b/plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_write_tree.txt.svn-base new file mode 100644 index 0000000..b6e9303 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/.svn/text-base/mib_write_tree.txt.svn-base @@ -0,0 +1,25897 @@ +Create node: IWV(OID: 1.3.6.1.4.1.1373) +-> father_name = [enterprises] +-> -> IWV(0) + + +Create node: IWV_Products(OID: 1.3.6.1.4.1.1373.1) +-> father_name = [IWV] +-> -> IWV_Products(0) + + +Remark: iwvProducts is the root OBJECT IDENTIFIER from which sysObjectID values are assigned. Actual values are defined in IWV-PRODUCTS-MIB. + + +Create node: Special_App(OID: 1.3.6.1.4.1.1373.1.2) +-> father_name = [IWV_Products] +-> -> Special_App(0) + + +Create node: IWF(OID: 1.3.6.1.4.1.1373.1.2.8) +-> father_name = [Special_App] +-> -> IWF(0) + + +Remark: IWF + + +Create node: WXC2(OID: 1.3.6.1.4.1.1373.1.3) +-> father_name = [IWV_Products] +-> -> Special_App(0) +-> -> WXC2(1) + + +Create node: PCM(OID: 1.3.6.1.4.1.1373.1.3.1) +-> father_name = [WXC2] +-> -> PCM(0) + + +Remark: PCM + + +Create node: Platform(OID: 1.3.6.1.4.1.1373.1.3.2) +-> father_name = [WXC2] +-> -> PCM(0) +-> -> Platform(1) + + +Remark: Platform + + +Create node: App(OID: 1.3.6.1.4.1.1373.1.3.3) +-> father_name = [WXC2] +-> -> PCM(0) +-> -> Platform(1) +-> -> App(2) + + +Remark: App platform + + +Create node: SS7(OID: 1.3.6.1.4.1.1373.1.3.2.2) +-> father_name = [Platform] +-> -> SS7(0) + + +Remark: + Subsystems for SS7 . + + +Create node: MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2) +-> father_name = [SS7] +-> -> MTP3(0) + + +Remark: Subsystems for MTP3 . + + +Create node: Config_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2) +-> father_name = [MTP3] +-> -> Config_MTP3(0) + + +Remark: MTP3 Configuration. + + +Create node: Network_Indicator(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.2) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) + + +Register leaf node: Network_Indicator. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : MTP3 network indicator. + +Field : total(8) +Access : read-write [1]International network + { + [u]0.0-0.0 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [2]International network spare + { + [u]0.1-0.1 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [3]National network + { + [u]0.2-0.2 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [4]National network spare + { + [u]0.3-0.3 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [5]International network + { + [u]0.4-0.4 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [6]International network spare + { + [u]0.5-0.5 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [7]National network + { + [u]0.6-0.6 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [8]National network spare + { + [u]0.7-0.7 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + + +Create node: OPC(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) + + +Remark: Originating point code. + + +Create node: International_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.1) +-> father_name = [OPC] +-> -> International_14bit(0) + + +Register leaf node: International_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.2) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) + + +Register leaf node: International_Spare_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.3) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) + + +Register leaf node: National_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.4) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) + + +Register leaf node: National_Spare_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.5) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) + + +Register leaf node: International_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.6) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) + + +Register leaf node: International_Spare_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.7) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) +-> -> National_24bit(6) + + +Register leaf node: National_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.8) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) +-> -> National_24bit(6) +-> -> National_Spare_24bit(7) + + +Register leaf node: National_Spare_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Linkset(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.4) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) + + +Remark: linkset. + + +Create node: Linkset_Attributes(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.4.1) +-> father_name = [Linkset] +-> -> Linkset_Attributes(0) + + +Register leaf node: Linkset_Attributes. +Instance: 128 +Length : 4 +Flag : 255 +Default : +Remark : Opposite point code: The opposite point code of the linkset. +Network indicator: The network type of the opposite point code. +Loop back: Loop back enable or disable, used for MSC loop back link. + +Field : total(5) +Access : read-write[1]Linkset DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + [2]Network indicator + { + [u]3.0-3.1 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [4]Linkset loopback + { + [u]3.3-3.3 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Link(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) + + +Remark: link. + + +Create node: Link_Attributes(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.1) +-> father_name = [Link] +-> -> Link_Attributes(0) + + +Register leaf node: Link_Attributes. +Instance: 256 +Length : 15 +Flag : 255 +Default : €ÿÿÿÿ +Remark : E1 link attributes. +Linkset no.: Assign linkset to E1 link, MSC has up to 128 linksets (0-127). 128=TCH E1. +SLC no.: Assign SLC to each E1 link of a linkset, each linkset has up to 13 E1 links (0-15). +IP: E1 link management IP. The third byte of CPC IP: +98=E1 link 0-127, 99=E1 link 128-255. +Default=0x000032. + +Field : total(12) +Access : read-write[1]Linkset no. + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } +[2]SLC no. + { + [u]1.0-1.7 + [u]input + [v]toDec high 0 + } +[3]CPC IP + { + [u]2.0-5.7 + [u]input + [v]KeepHex high 0 + } + [4]Link Type + { + [u]6.0-6.0 + [u]select + [v]0[opt]Non-sigtran + [v]1[opt]Sigtran + } + [5]Link Enable + { + [u]6.1-6.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [6]MTP3-Lite Enable + { + [u]6.2-6.2 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[8]SG no. + { + [u]7.0-7.7 + [u]input + [v]toDec high 0 + } +[9]M2UA Interface ID + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } +[10]MTP3-Lite Remote IP + { + [u]9.0-12.7 + [u]input + [v]KeepHex high 0 + } +[11]MTP3-Lite Inactivity Timeout + { + [u]13.0-13.7 + [u]input + [v]toDec high 0 + } +[12]MTP3-Lite Allowed Inactivity Timeouts + { + [u]14.0-14.7 + [u]input + [v]toDec high 0 + } + + +Create node: Link_Command(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.2) +-> father_name = [Link] +-> -> Link_Attributes(0) +-> -> Link_Command(1) + + +Register leaf node: Link_Command. +Instance: 256 +Length : 1 +Flag : 255 +Default :  +Remark : Used for E1 link control, not affect call traffic. +Disable=Disable E1 link MTP2 layer. +Enable=Enable a disabled E1 link MTP2 layer. +Inhibit=Inhibit E1 link MTP3 layer. +Uninhibit=Uninhibit a inhibited E1 link MTP3 layer. +Default=Enable a disabled E1 link MTP2 layer. + +Field : total(1) +Access : write-only [1]E1 link + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + [v]2[opt]Inhibit + [v]3[opt]Uninhibit + } + + +Create node: TCP_Port(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.3) +-> father_name = [Link] +-> -> Link_Attributes(0) +-> -> Link_Command(1) +-> -> TCP_Port(2) + + +Register leaf node: TCP_Port. +Instance: 1 +Length : 2 +Flag : 255 +Default : ˆ +Remark : TCP server port for SCCP-Lite. + +Field : total(1) +Access : read-write[1]TCP Port + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) + + +Remark: Routing. + + +Create node: International(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.1) +-> father_name = [Routing] +-> -> International(0) + + +Register leaf node: International. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.2) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) + + +Register leaf node: International_Spare. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: National(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.3) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) +-> -> National(2) + + +Register leaf node: National. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.4) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) +-> -> National(2) +-> -> National_Spare(3) + + +Register leaf node: National_Spare. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: SPC_to_ACN(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) +-> -> SPC_to_ACN(5) + + +Remark: SPC to ACN. + + +Create node: Local_ACN(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.1) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) + + +Register leaf node: Local_ACN. +Instance: 1 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: International(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.2) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) + + +Register leaf node: International. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: International_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.3) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) + + +Register leaf node: International_Spare. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: National(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.4) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) +-> -> National(3) + + +Register leaf node: National. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: National_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.5) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) +-> -> National(3) +-> -> National_Spare(4) + + +Register leaf node: National_Spare. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: Signaling_Gateway(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.9) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) +-> -> SPC_to_ACN(5) +-> -> Signaling_Gateway(6) + + +Register leaf node: Signaling_Gateway. +Instance: 256 +Length : 7 +Flag : 255 +Default : +Remark : SG attributes + +Field : total(4) +Access : read-write [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Server + { + [u]1.0-1.7 + [u]select + [v]0[opt]Client + [v]1[opt]Server + } + [3]ACK + { + [u]2.0-2.7 + [u]select + [v]0[opt]no ACK + [v]1[opt]ACK + } +[4]IP + { + [u]3.0-6.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Status_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3) +-> father_name = [MTP3] +-> -> Config_MTP3(0) +-> -> Status_MTP3(1) + + +Remark: MTP3 Status. + + +Create node: Link_Status(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.1) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) + + +Register leaf node: Link_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default :  +Remark : E1 link MTP3 status (Read Only). + +Field : total(1) +Access : read-only [1]Link status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Inhibited + } + + +Create node: Linkset_Status(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.2) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) + + +Register leaf node: Linkset_Status. +Instance: 128 +Length : 1 +Flag : 255 +Default :  +Remark : Linkset status (Read only). + +Field : total(1) +Access : read-only [1]Linkset status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Reserved + } + + +Create node: International_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.3) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) + + +Register leaf node: International_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: International_Spare_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.4) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) + + +Register leaf node: International_Spare_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: National_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.5) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) + + +Register leaf node: National_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: National_Spare_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.6) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) +-> -> National_Spare_Routing(5) + + +Register leaf node: National_Spare_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: Command_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.7) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) +-> -> National_Spare_Routing(5) +-> -> Command_MTP3(6) + + +Register leaf node: Command_MTP3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for MTP3 platform. +Reset=status initialization. +Save parameter=save parameters residing in memory into harddisk. + +Field : total(1) +Access : read-write [1]command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No command + [v]1[opt]Reset + [v]2[opt]Save parameter + } + + +Create node: SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3) +-> father_name = [SS7] +-> -> MTP3(0) +-> -> SCCP(1) + + +Remark: Subsystems for SCCP . + + +Create node: Config_SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2) +-> father_name = [SCCP] +-> -> Config_SCCP(0) + + +Remark: SCCP Configuration. + + +Create node: Local_Node(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1) +-> father_name = [Config_SCCP] +-> -> Local_Node(0) + + +Remark: Local Node. + + +Create node: OMC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.4) +-> father_name = [Local_Node] +-> -> OMC(0) + + +Register leaf node: OMC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: OMC E.134 number. +IP0: OMC0 IP, 172.18.128.1. +IP1: OMC1 IP, 172.18.129.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: HLR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.6) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) + + +Register leaf node: HLR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: HLR E.134 number. +IP0: HLR0 IP, 172.18.98.1. +IP1: HLR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: VLR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.7) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) + + +Register leaf node: VLR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VLR E.134 number. +IP0: VLR0 IP, 172.18.98.1. +IP1: VLR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: MSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.8) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) + + +Register leaf node: MSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: MSC E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: EIR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.9) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) + + +Register leaf node: EIR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: EIR E.134 number. +IP0: EIR0 IP, 172.18.98.1. +IP1: EIR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: AUC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.10) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) + + +Register leaf node: AUC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: AUC E.134 number. +IP0: AUC0 IP, 172.18.98.1. +IP1: AUC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.11) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) + + +Register leaf node: SMSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: SMSC E.134 number. +IP0: OMC0 IP, 172.18.98.1. +IP1: OMC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_EMSE(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.19) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) + + +Register leaf node: SMPP_EMSE. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VMS-SMPP E.134 number. +IP0: VMS0 IP, 172.18.147.1. +IP1: VMS1 IP, 172.18.148.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_SMSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.20) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) + + +Register leaf node: SMPP_SMSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: SMSC-SMPP E.134 number. +IP0: SMSC0 IP, 172.18.98.1. +IP1: SMSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_OMC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.21) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) + + +Register leaf node: SMPP_OMC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: OMC-SMPP E.134 number. +IP0: OMC0 IP, 172.18.128.1. +IP1: OMC1 IP, 172.18.129.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SRF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.22) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) + + +Register leaf node: SRF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VMS SRF E.134 number. +IP0: VMS0 IP, 172.18.147.1. +IP1: VMS1 IP, 172.18.148.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SSF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.143) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) + + +Register leaf node: SSF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: MSC SSF E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SCF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.147) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) +-> -> SCF(12) + + +Register leaf node: SCF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: PPS SCF E.134 number. +IP0: PPS0 IP, 172.18.98.1. +IP1: PPS1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: AIF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.254) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) +-> -> SCF(12) +-> -> AIF(13) + + +Register leaf node: AIF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: AIF E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: GTT_Table(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.2) +-> father_name = [Config_SCCP] +-> -> Local_Node(0) +-> -> GTT_Table(1) + + +Register leaf node: GTT_Table. +Instance: 256 +Length : 43 +Flag : 255 +Default : +Remark : On/off: GTT flag, off=disable, on=enable. +Numbering plan: 1=MSISDN, 3=IMSI, 7=GT. +Specify the beginning number of a group of consecutive numbers routed by GTT, for single-number GTT route, the start number is same as the end number. +End GT number: Specify the end number of a group of consecutive number routed by GT. If there are some inconsecutive numbers for a same destination, a different GTT record should be set. +Network indicator (NI): 0=International network, 1=International network spare, 2=National network, 3=National network spare, +DPC: Destination point code. +SSN: Subsystem number. +2=Reserved for ITU-T allocation. +3=ISDN user part. +4=OMC. +5=MAP. +3=HLR. +7=VLR. +8=MSC. +9=EIR. +10=AUC. +11=SMSC. +147=PPS. +254=BSSMAP. +Route indicator: For IMSI and MSISDN, select Route on SSN. For the record of the connected network, select Route on GT. +Address indicator: select the contribution of SCCP Address. +Replaced start digit: Specify the beginning digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. +Replaced end digit: Specify the end digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. +Outgoing number plan: Outgoing number plan, include MSISDN, IMSI and GT. +Replacing digits: Replacing digits, the length of replacing digits and replaced digits may be different. + +Field : total(14) +Access : read-write [1]On/off + { + [u]0.0-0.7 + [u]select + [v]1[opt]On + [v]0[opt]Off + } + [2]Numbering plan + { + [u]1.0-1.7 + [u]select + [v]0[opt]0 + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } +[3]TT + { + [u]2.0-2.7 + [u]input + [v]KeepHex Low F + } +[4]Start GT number + { + [u]3.0-12.7 + [u]input + [v]KeepHex Low F + } +[4]End GT number + { + [u]13.0-22.7 + [u]input + [v]KeepHex Low F + } + [5]Network indicator + { + [u]23.0-23.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + } +[6]DPC + { + [u]24.0-26.7 + [u]input + [v]toDec high 0 + } +[7]SSN + { + [u]27.0-27.7 + [u]input + [v]toDec high 0 + } + [8]Route indicator + { + [u]28.0-28.7 + [u]select + [v]0[opt]Route on GT + [v]1[opt]Route on SSN + } + [9]Address indicator + { + [u]29.0-29.7 + [u]select + [v]0[opt]NULL + [v]3[opt]DPC+SSN + [v]6[opt]GT+SSN + [v]7[opt]GT+DPC+SSN + } +[10]Replaced start digit + { + [u]30.0-30.7 + [u]input + [v]KeepHex high 0 + } +[11]Replaced end digit + { + [u]31.0-31.7 + [u]input + [v]KeepHex high 0 + } + [12]Outgoing number plan + { + [u]32.0-32.7 + [u]select + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } +[13]Replacing digits + { + [u]33.0-42.7 + [u]input + [v]KeepHex Low F + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3) +-> father_name = [SCCP] +-> -> Config_SCCP(0) +-> -> Management(1) + + +Remark: Management. + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.1) +-> father_name = [Management] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of SCCP platform software (Read Only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-write + +Create node: Command_SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.2) +-> father_name = [Management] +-> -> Version(0) +-> -> Command_SCCP(1) + + +Register leaf node: Command_SCCP. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for SCCP. +Reset: Used for SCCP status initialization. +Load parameter: Load the parameters from device's harddisk to device's memory. +Save parameter: Save the parameters residing in device's memory into device's harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]0[opt]Reset + [v]2[opt]Save parameters + } + + +Create node: XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5) +-> father_name = [SS7] +-> -> MTP3(0) +-> -> SCCP(1) +-> -> XAPP(2) + + +Remark: Subsystems for XAPP . + + +Create node: Config_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2) +-> father_name = [XAPP] +-> -> Config_XAPP(0) + + +Remark: XAPP Configuration. + + +Create node: MCC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.1) +-> father_name = [Config_XAPP] +-> -> MCC(0) + + +Register leaf node: MCC. +Instance: 1 +Length : 2 +Flag : 255 +Default : F +Remark : Mobile country code. + +Field : total(1) +Access : read-write[1]MCC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: MNC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.2) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) + + +Register leaf node: MNC. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Mobile network code. + +Field : total(1) +Access : read-write[1]MNC + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low E + } + + +Create node: CC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.3) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) + + +Register leaf node: CC. +Instance: 1 +Length : 2 +Flag : 255 +Default : †î +Remark : Country code. + +Field : total(1) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: NDC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.4) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) + + +Register leaf node: NDC. +Instance: 1 +Length : 3 +Flag : 255 +Default : u^î +Remark : National destination code. + +Field : total(1) +Access : read-write[1]NDC + { + [u]0.0-2.7 + [u]input + [v]KeepHex Low E + } + + +Create node: International_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.5) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) + + +Register leaf node: International_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : International call prefix. + +Field : total(1) +Access : read-write[1]International prefix + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: National_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.6) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) + + +Register leaf node: National_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : î +Remark : National call prefix. + +Field : total(1) +Access : read-write[1]National prefix + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Local_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.7) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) + + +Register leaf node: Local_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : îî +Remark : Local prefix. + +Field : total(0) +Access : read-write + +Create node: Conv_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.8) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) + + +Register leaf node: Conv_Prefix. +Instance: 128 +Length : 35 +Flag : 255 +Default : +Remark : Conv prefix . + +Field : total(5) +Access : read-write[1]Prefix + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } +[2]Delete length + { + [u]0.0-0.0 + [u]input + [v]toDec high 0 + } +[3]Add length + { + [u]17.0-17.7 + [u]input + [v]toDec high 0 + } +[4]Add digits + { + [u]18.0-33.7 + [u]input + [v]ToAscii Low 0 + } +[5]Valid length + { + [u]34.0-34.7 + [u]input + [v]toDec high 0 + } + + +Create node: CLI_Conv_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.9) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) +-> -> CLI_Conv_Prefix(8) + + +Register leaf node: CLI_Conv_Prefix. +Instance: 8 +Length : 37 +Flag : 255 +Default : +Remark : CLI_Conv prefix . + +Field : total(7) +Access : read-write [1]In property + { + [u]0.0-0.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } +[2]Prefix + { + [u]1.0-16.7 + [u]input + [v]ToAscii Low 0 + } +[3]Delete length + { + [u]17.0-17.7 + [u]input + [v]toDec high 0 + } + [4]Out property + { + [u]18.0-18.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } +[5]Add length + { + [u]19.0-19.7 + [u]input + [v]toDec high 0 + } +[6]Add digits + { + [u]20.0-35.7 + [u]input + [v]ToAscii Low 0 + } +[7]Valid length + { + [u]36.0-36.7 + [u]input + [v]toDec high 0 + } + + +Create node: mscid_to_number(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.10) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) +-> -> CLI_Conv_Prefix(8) +-> -> mscid_to_number(9) + + +Register leaf node: mscid_to_number. +Instance: 256 +Length : 12 +Flag : 255 +Default : +Remark : Conv prefix . + +Field : total(4) +Access : read-write[1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } +[3]SSN + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[4]Number + { + [u]4.0-11.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Status_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3) +-> father_name = [XAPP] +-> -> Config_XAPP(0) +-> -> Status_XAPP(1) + + +Remark: XAPP Status. + + +Create node: Version_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.1) +-> father_name = [Status_XAPP] +-> -> Version_XAPP(0) + + +Register leaf node: Version_XAPP. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of XAPP module (Read Only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-only + +Create node: Command_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.2) +-> father_name = [Status_XAPP] +-> -> Version_XAPP(0) +-> -> Command_XAPP(1) + + +Register leaf node: Command_XAPP. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for XAPP. +Save parameter: Save the parameters in memory into local harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + } + + +Create node: Maplat(OID: 1.3.6.1.4.1.1373.1.3.2.3) +-> father_name = [Platform] +-> -> SS7(0) +-> -> Maplat(1) + + +Remark: + Subsystems for Maplat . + + +Create node: SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4) +-> father_name = [Maplat] +-> -> SMPP(0) + + +Remark: Subsystems for SMPP . + + +Create node: Config_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.2) +-> father_name = [SMPP] +-> -> Config_SMPP(0) + + +Remark: SMPP Configuration. + + +Create node: SMPP_Link_Parameter(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.2.1) +-> father_name = [Config_SMPP] +-> -> SMPP_Link_Parameter(0) + + +Register leaf node: SMPP_Link_Parameter. +Instance: 32 +Length : 106 +Flag : 255 +Default : +Remark : Session type: BIND_TX-bind as transmitter, BIND_RX-bind as receiver, BIND_TRX-bind as transceiver. +System ID: using in BIND and OUTBIND. +Password: The password parameter is used by the SMSC to authenticate the identity of the binding ESME. The Service Provider may require ESME¡¯s to provide a password when binding to the SMSC. This password is normally issued by the SMSC system administrator. +The password parameter may also be used by the ESME to authenticate the identity of the binding SMSC (e.g. in the case of the outbind operation). +System type: The system_type may be used to categorise the system, e.g., ¡°EMAIL¡±, ¡°WWW¡±, etc. +The system_type parameter is used to categorize the type of ESME that is binding to the SMSC. Examples include ¡°VMS¡± (voice mail system) and ¡°OTA¡± (over-the-air activation system). +Specification of the system_type is optional - some SMSC¡¯s may not require ESME¡¯s to provide this detail. In this case, the ESME can set the system_type to NULL. +IP: Specify the IP addresses of 16 SMPP connected devices.
e.g. 0xAC127001=172.18.112.1.
+Session init timer: This timer specifies the time lapse allowed between a network connection being established and a bind_transmitter or bind_receiver request being sent to SMSC. This timer should be active on the SMSC. +Enquire link timer: This timer specifies the time lapse allowed between operations after which an SMPP entity should interrogate whether it's peer still has an active session. +The scale is second. +Inactivity timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) +Response timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) +Local service number: compare with application's service number while bind as TX or TRX. +remote service number: compare with application's service number while bind as RX + +Field : total(16) +Access : read-write [1]Link enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Link type + { + [u]1.0-1.7 + [u]select + [v]0[opt]UDP + [v]1[opt]TCP + } + [3]Server type + { + [u]2.0-2.7 + [u]select + [v]0[opt]SMPP_CLIENT + [v]1[opt]SMPP_SERVER + } + [4]Session type + { + [u]3.0-3.7 + [u]select + [v]0[opt]BIND_TX + [v]1[opt]BIND_RX + [v]2[opt]BIND_TRX + } +[5]System ID + { + [u]4.0-19.7 + [u]input + [v]ToAscii Low 0 + } +[6]Password + { + [u]20.0-28.7 + [u]input + [v]ToAscii Low 0 + } +[7]System type + { + [u]29.0-41.7 + [u]input + [v]ToAscii Low 0 + } +[8]Local GTT + { + [u]42.0-57.7 + [u]input + [v]ToAscii Low 0 + } +[9]Remote GTT + { + [u]58.0-73.7 + [u]input + [v]ToAscii Low 0 + } +[10]Local IP + { + [u]74.0-77.7 + [u]input + [v]KeepHex Low F + } +[11]Remote IP + { + [u]78.0-81.7 + [u]input + [v]KeepHex Low F + } +[12]Session init timer + { + [u]82.0-85.7 + [u]input + [v]toDec high 0 + } +[13]Enquire link timer + { + [u]86.0-89.7 + [u]input + [v]toDec high 0 + } +[14]Inactivity timer + { + [u]90.0-93.7 + [u]input + [v]toDec high 0 + } +[15]Response timer + { + [u]94.0-97.7 + [u]input + [v]toDec high 0 + } +[16]Remote service number + { + [u]98.0-105.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Status_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3) +-> father_name = [SMPP] +-> -> Config_SMPP(0) +-> -> Status_SMPP(1) + + +Remark: XAPP Status. + + +Create node: Command_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3.2) +-> father_name = [Status_SMPP] +-> -> Command_SMPP(0) + + +Register leaf node: Command_SMPP. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Control command for SMPP. + +Field : total(1) +Access : write-only [1]Command + { + [u]0.0-0.7 + [u]select + [v]2[opt]save parameter + } + + +Create node: MSC(OID: 1.3.6.1.4.1.1373.1.3.3.2) +-> father_name = [App] +-> -> MSC(0) + + +Remark: + Subsystems for msc . + + +Create node: CCF(MSC)(OID: 1.3.6.1.4.1.1373.1.3.3.2.2) +-> father_name = [MSC] +-> -> CCF(MSC)(0) + + +Remark: Subsystems for msc . + + +Create node: CCF_Config(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2) +-> father_name = [CCF(MSC)] +-> -> CCF_Config(0) + + +Remark: + Configuration for CCF . + + +Create node: Call_Routing(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) + + +Remark: + Call Routing . + + +Create node: Prefix_Assignment(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.1) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) + + +Register leaf node: Prefix_Assignment. +Instance: 256 +Length : 8 +Flag : 255 +Default : îîîîîîîî +Remark : 4 bytes are used to set a 8-digit prefix for dialed number. +Prefix is the first layer for dialed number based call routing. If the dialed number of a call matches a pre-programmed prefix in this table, this call will be routed to a certain trunk group, subsequently that trunk group will route this call via a dedicated E1 port.This system has totally 256 prefixes. +Dialed number without matching a pre-programmed prefix will be routed to the default trunk group 0. +Prefix 252 is for default international call, all internation calls unable to be routed out will be routed from the trunk group assigned to prefix 252, keep default EEEEEEEE. +Prefix 253 is for default national call, all national calls unable to be routed out will be routed from the trunk group assigned to prefix 253, keep default EEEEEEEE. +Prefix 254 is for default subscriber call, all dialed MSISDN unable to be routed out will be routed from the trunk group assigned to prefix 254, keep default EEEEEEEE. +Prefix 255 is for unknown call, all unknown calls unable to be routed out will be routed from the trunk group assigned to prefix 255, keep default EEEEEEEE. +E=End tag, C='#', B='*'. +Default=0xEEEEEEEE. + +Field : total(1) +Access : read-write[1]Prefix + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Prefix_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.2) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) + + +Register leaf node: Prefix_Attributes. +Instance: 256 +Length : 18 +Flag : 9 +Default : " +Remark : Enable: Y=prefix enable, N=prefix disable. +TON incoming call: Type of number for incoming call, include unknown, MSISDN, NDD and IDD. It is specified by originating node for terminating node to route this call with proper dialed number manipulation. +For system subscriber dialed prefix, always use unknown for In-TON except the prefix of international prefix beginning with a . For this kind of prefix (such as 86755832) we should set the In-TON as IDD to support dialing. +TON outgoing call: Type of number for outgoing call, include unknown, MSISDN, NDD and IDD. It specifies the type of an outgoing call for terminating node to route this call with proper dialed number manipulation. Generally the MSC uses IDD for outgoing call. +Out trunk deletion count: Quantity of deleted digit of a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no deletion, 1-8=delete first 1-8 digits. +Out trunk insertion count: Quantity of inserted digit for a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no insertion, 1-8=insert 1-8 digits from the beginning of this number. +Out trunk inserted digits: 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number. +CDR on/off: Turn on/off the CDR of dialed numbers beginning with this prefix. +Properties: Specify the properties of a prefix. Trunk=to PSTN, MSISDN=to A interface, MSRN=MS roaming number, MSC=to peer MSC. +Call type: Normal=no verification for MT, Emergency call=no verification for MO (free call), MCT=Malicious Call Trace, VMS call=send signaling carried DTMF to VMS. +Length of dialed number: Length of dialed number (1-32). +E.164 international deletion count: Quantity of deleted digit of E164 international number, always use IDD for outgoing call for PPS debiting. +E.164 international insertion count: Quantity of inserted digit of E164 international number, always use IDD for outgoing call for PPS debiting. +E.164 international inserted digits: Inserted digit to the E164 international number, 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number, always use IDD for outgoing call for PPS debiting. + +Field : total(15) +Access : read-write [1]TON incoming call + { + [u]0.0-0.3 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [2]TON outgoing call + { + [u]0.4-0.7 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [3]Out trunk deletion count + { + [u]1.0-1.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [4]Out trunk insertion count + { + [u]1.4-1.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } +[5]Out trunk inserted digits + { + [u]2.0-9.7 + [u]input + [v]KeepHex Low E + } + [6]CDR on/off + { + [u]10.0-10.0 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [8]Properties + { + [u]10.2-10.3 + [u]select + [v]0[opt]Trunk + [v]1[opt]MSISDN + [v]2[opt]MSRN + [v]3[opt]MSC + } + [9]Call type + { + [u]10.4-10.6 + [u]select + [v]0[opt]Normal Call + [v]1[opt]Emergency + [v]2[opt]MCT + [v]3[opt]VMS + [v]4[opt]IN + } + [10]Enable + { + [u]10.7-10.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } +[11]Length of dialed number + { + [u]11.0-11.7 + [u]input + [v]toDec high 0 + } + [12]E.164 International deletion count + { + [u]12.0-12.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]Delete first one + [v]2[opt]Delete first two + [v]3[opt]Delete first three + [v]4[opt]Delete first four + [v]5[opt]Delete first five + [v]6[opt]Delete first six + [v]7[opt]Delete first seven + [v]8[opt]Delete first eight + } + [13]E.164 International insertion count + { + [u]12.4-12.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]Insert first one + [v]2[opt]Insert first two + [v]3[opt]Insert first three + [v]4[opt]Insert first four + [v]5[opt]Insert first five + [v]6[opt]Insert first six + [v]7[opt]Insert first seven + [v]8[opt]Insert first eight + } +[14]E.164 international inserted digits + { + [u]13.0-16.7 + [u]input + [v]KeepHex Low E + } + [15]Cli-type + { + [u]17.0-17.7 + [u]select + [v]0[opt]Sub + [v]1[opt]NDD + [v]2[opt]IDD + [v]3[opt]Unknown(local) + [v]4[opt]Unknown(NDD) + [v]5[opt]Unknown(IDD) + } + + +Create node: Prefix_TG(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.3) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) + + +Register leaf node: Prefix_TG. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Assign a trunk group for each prefix for call routing, a single prefix points to only one trunk group, multiple prefix can be assigned the same trunk group, default is the no. of the prefix. + +Field : total(1) +Access : read-write[1]Assign TG to prefix + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: TG_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.4) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) + + +Register leaf node: TG_Attributes. +Instance: 256 +Length : 10 +Flag : 1 +Default : +Remark : DPC: Destination point code of this trunk group. +TG flag: enable or disable this trunk group. +CDR on/off: CDR on or off option for this trunk group. +Announcement: Voice announcement enable or disable for this trunk group. +TG category: PSTN=to PSTN, IP=to VMS and VPS, HPLMN=to HPLMN, VPLMN=to VPLMN, SUB=to BSC, Intercept=to intercept LEA +Alternative TG flag: Alternative trunk group enable or disable option. +Alternative TG: Alternative trunk group for backup purpose. +Loop back: Incoming call loop back enable or disable, used for MSC loop back. +Network indicator: Specify network type, International, International spare , National, National spare. +Circuit selection: Preferred circuit selection mode, include clockwise, anti-clockwise, odd and even. +Back off: Back off on or off when simultaneously select the same channel with the opposite side. +Location: For normal trunk group, select Both. For a trunk group to a VPS, configure this trunk group as MSC0 or MSC1. +MPTY: Multi-party call enable or disable. For all trunk groups to BSC, select Enable. +Tandem restriction:Y: Tandem disabled. Not support transit call from PSTN to PSTN via this trunk group. +N: Tandem enabled. Support transit call from PSTN to PSTN via this trunk group. + +Field : total(16) +Access : read-write[1]DPC + { + [u]0.0-3.7 + [u]input + [v]KeepHex high 0 + } + [2]TG flag + { + [u]4.0-4.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]CDR on/off + { + [u]4.1-4.1 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [4]Announcement + { + [u]4.2-4.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [5]TG category + { + [u]4.3-4.5 + [u]select + [v]0[opt]PSTN + [v]1[opt]HPLMN + [v]2[opt]VHLMN + [v]3[opt]SUB + [v]4[opt]IP + [v]5[opt]Intercept + } + [6]Alternative TG flag + { + [u]4.6-4.6 + [u]select + [v]0[opt]Disable + [v]1[opt]enable + } + [7]Loopback + { + [u]4.7-4.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [8]Network indicator + { + [u]5.0-5.7 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [9]Circuit selection + { + [u]6.0-6.1 + [u]select + [v]0[opt]Clockwise + [v]1[opt]Anti-clockwise + [v]2[opt]Odd + [v]3[opt]Even + } + [10]Back off + { + [u]6.2-6.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [12]MPTY + { + [u]6.5-6.5 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [13]Location + { + [u]6.6-6.7 + [u]select + [v]0[opt]MSC-0 + [v]1[opt]MSC-1 + [v]2[opt]Both + [v]3[opt]Spare + } +[14]Alternative TG + { + [u]7.0-7.7 + [u]input + [v]toDec high 0 + } + [15]Tandem restriction + { + [u]8.0-8.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [16]Incoming Call type + { + [u]9.0-9.7 + [u]select + [v]0[opt]Normal + [v]1[opt]IN + } + + +Create node: Call_Routing_CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.5) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) + + +Register leaf node: Call_Routing_CDR_Flag. +Instance: 1 +Length : 2 +Flag : 255 +Default : ÿ +Remark : Sorm: call intercept MCT: malicious call trace +Default=CDR of MO call and MT call is enabled, CDR of roaming call, gateway incoming call, gateway outgoing call, transit call, MO SMS and MT SMS is disabled. + +Field : total(13) +Access : read-write [2]Redirection + { + [u]0.3-0.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [3]Feature Request + { + [u]0.2-0.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [4]Sorm + { + [u]0.1-0.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [5]MCT + { + [u]0.0-0.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [6]MT SM + { + [u]1.7-1.7 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [7]MO SM + { + [u]1.6-1.6 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [8]Transit call + { + [u]1.5-1.5 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [9]Gateway outgoing call + { + [u]1.4-1.4 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [10]Gateway incoming call + { + [u]1.3-1.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [11]Roaming call + { + [u]1.2-1.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [12]MT call + { + [u]1.1-1.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [13]MO call + { + [u]1.0-1.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + + +Create node: Voice_Prompt_Announcement_option(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.6) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) +-> -> Voice_Prompt_Announcement_option(5) + + +Register leaf node: Voice_Prompt_Announcement_option. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Set to play either announcement or tone indicating call unattainable reason for subscribers. System has total 8 announcements and tones that can be independently set. +Announcement 0: The dialed number is invalid. +Announcement 1: The subscriber dialed is not activated. +Announcement 2: The subscriber is busy. +Announcement 3: The network is busy. +Announcement 4: Caller's account was deactivated. +Announcement 5: The subscriber dialed was deactivated. +Announcement 6: Feature not available to caller. +Announcement 7: The subscriber dialed is not available. + +Field : total(16) +Access : read-write [1]Announcement 0 + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [2]Announcement 1 + { + [u]1.0-1.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [3]Announcement 2 + { + [u]2.0-2.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [4]Announcement 3 + { + [u]3.0-3.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [5]Announcement 4 + { + [u]4.0-4.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [6]Announcement 5 + { + [u]5.0-5.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [7]Announcement 6 + { + [u]6.0-6.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [8]Announcement 7 + { + [u]7.0-7.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [9]Announcement 8 + { + [u]8.0-8.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [10]Announcement 9 + { + [u]9.0-9.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [11]Announcement 10 + { + [u]10.0-10.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [12]Announcement 11 + { + [u]11.0-11.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [13]Announcement 12 + { + [u]12.0-12.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [14]Announcement 13 + { + [u]13.0-13.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [15]Announcement 14 + { + [u]14.0-14.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [16]Announcement 15 + { + [u]15.0-15.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + +Create node: Call_Routing_Warning(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.7) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) +-> -> Voice_Prompt_Announcement_option(5) +-> -> Call_Routing_Warning(6) + + +Register leaf node: Call_Routing_Warning. +Instance: 1 +Length : 1 +Flag : 255 +Default : 2 +Remark : Set time to play prompt tone for reaching zero balance prepaid subscriber when a call is in progress, unit is second. e.g. if set as 60, the system will play prompt tone one minute before a subscriber uses up his balance. + +Field : total(1) +Access : read-write[1]Remanent time for warning tone + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: CCF_MSC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) + + +Remark: CCF Configuration MSC . + + +Create node: Emergency_Call(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2.5) +-> father_name = [CCF_MSC] +-> -> Emergency_Call(0) + + +Register leaf node: Emergency_Call. +Instance: 256 +Length : 21 +Flag : 0 +Default : +Remark : Emergency call number. Default=112. + +Field : total(5) +Access : read-write [1]Enable flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]LAC + { + [u]1.0-2.7 + [u]input + [v]toDec high 0 + } +[3]CI + { + [u]3.0-4.7 + [u]input + [v]toDec high 0 + } +[4]Dial number + { + [u]5.0-12.7 + [u]input + [v]KeepHex Low E + } +[5]Local emergency number + { + [u]13.0-20.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Location_Management(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2.8) +-> father_name = [CCF_MSC] +-> -> Emergency_Call(0) +-> -> Location_Management(1) + + +Register leaf node: Location_Management. +Instance: 256 +Length : 8 +Flag : 0 +Default : +Remark : Manage the MS location by correlate TG (trunk group), LAC (location area code, cell ID and zone code, totally 256 location management. + +Field : total(5) +Access : read-write [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } +[2]TG + { + [u]1.0-1.7 + [u]input + [v]toDec high 0 + } +[3]LAC + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[4]CI + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } +[5]Zone Code + { + [u]6.0-7.7 + [u]input + [v]toDec high 0 + } + + +Create node: CPC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) + + +Remark: CPC Management. + + +Create node: SRF_Address(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3.3) +-> father_name = [CPC] +-> -> SRF_Address(0) + + +Register leaf node: SRF_Address. +Instance: 1 +Length : 8 +Flag : 255 +Default : †uP +Remark : E.164 number of HLR server:HLR MSISDN used for SCCP addressing, F=end tag. +Default=91867555950502FFFF=91867555950502. + +Field : total(1) +Access : read-write[1]EIR number + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Max_Call_Duration(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3.7) +-> father_name = [CPC] +-> -> SRF_Address(0) +-> -> Max_Call_Duration(1) + + +Register leaf node: Max_Call_Duration. +Instance: 1 +Length : 1 +Flag : 255 +Default : < +Remark : Define the permitted maximum call duration. Any ongoing call reaching this duration threshold will be compulsively cut off. byte value: 0=disable this function, 1-255=max. call duration, unit=minute. Default=0. + +Field : total(1) +Access : read-write[1]Max. call duration + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_Port(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) + + +Remark: E1 Port. + + +Create node: E1_Interface(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.1) +-> father_name = [E1_Port] +-> -> E1_Interface(0) + + +Register leaf node: E1_Interface. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Set the type of E1 interface for 256 E1 ports. + +Field : total(1) +Access : read-write [1]E1 interface + { + [u]0.0-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF CDMA2K + [v]4[opt]BICC + [v]5[opt]CI-CNF + [v]6[opt]CI-loopback + } + + +Create node: E1_TG(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.2) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) + + +Register leaf node: E1_TG. +Instance: 256 +Length : 1 +Flag : 255 +Default : î +Remark : Assign a trunk group to each E1 port for call routing. A single E1 port points to only one trunk group, multiple E1 port can be assigned the same trunk group. Default=number of the E1 port. + +Field : total(1) +Access : read-write[1]Assign TG + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_CIC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.3) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) +-> -> E1_CIC(2) + + +Register leaf node: E1_CIC. +Instance: 256 +Length : 4 +Flag : 255 +Default : +Remark : Circuit identity code, uniquely identify each circuit within a trunk group. CIC of both ends of a circuit must be identical. 256 CIC for dual MSC platform 256 E1 ports. + +Field : total(1) +Access : read-write[1]E1 CIC + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_Media_Control_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.4) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) +-> -> E1_CIC(2) +-> -> E1_Media_Control_Attributes(3) + + +Register leaf node: E1_Media_Control_Attributes. +Instance: 256 +Length : 4 +Flag : 255 +Default : +Remark : E1 Media Control Attributes + +Field : total(4) +Access : read-write [1]E1 Control Protocol Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Internal + [v]1[opt]MGCP + } + [2]E1 Enable + { + [u]1.0-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[3]MG Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } +[4]Trunk Number + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Channel_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) + + +Remark: Channel attributes. + + +Create node: Card0_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.1) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) + + +Register leaf node: Card0_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card1_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.2) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) + + +Register leaf node: Card1_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card2_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.3) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) + + +Register leaf node: Card2_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card3_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.4) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) + + +Register leaf node: Card3_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card4_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.5) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) + + +Register leaf node: Card4_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card5_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.6) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) + + +Register leaf node: Card5_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card6_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.7) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) + + +Register leaf node: Card6_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card7_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.8) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) + + +Register leaf node: Card7_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card8_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.9) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) + + +Register leaf node: Card8_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card9_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.10) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) + + +Register leaf node: Card9_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card10_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.11) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) + + +Register leaf node: Card10_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card11_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.12) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) + + +Register leaf node: Card11_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card12_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.13) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) + + +Register leaf node: Card12_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card13_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.14) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) + + +Register leaf node: Card13_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card14_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.15) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) + + +Register leaf node: Card14_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card15_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.16) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) + + +Register leaf node: Card15_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card16_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.17) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) + + +Register leaf node: Card16_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card17_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.18) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) + + +Register leaf node: Card17_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card18_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.19) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) + + +Register leaf node: Card18_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card19_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.20) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) + + +Register leaf node: Card19_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card20_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.21) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) + + +Register leaf node: Card20_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card21_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.22) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) + + +Register leaf node: Card21_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card22_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.23) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) + + +Register leaf node: Card22_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card23_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.24) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) + + +Register leaf node: Card23_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card24_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.25) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) + + +Register leaf node: Card24_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card25_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.26) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) + + +Register leaf node: Card25_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card26_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.27) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) + + +Register leaf node: Card26_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card27_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.28) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) + + +Register leaf node: Card27_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card28_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.29) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) + + +Register leaf node: Card28_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card29_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.30) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) + + +Register leaf node: Card29_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card30_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.31) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) +-> -> Card30_Channel(30) + + +Register leaf node: Card30_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card31_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.32) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) +-> -> Card30_Channel(30) +-> -> Card31_Channel(31) + + +Register leaf node: Card31_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: CPC_attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.6) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) +-> -> CPC_attributes(5) + + +Remark: CPC attributes. + + +Create node: MSCID(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.6.3) +-> father_name = [CPC_attributes] +-> -> MSCID(0) + + +Register leaf node: MSCID. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : MSCID + +Field : total(2) +Access : read-write[1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Media_gateway(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.7) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) +-> -> CPC_attributes(5) +-> -> Media_gateway(6) + + +Remark: Media_gateway . + + +Create node: MG_Attribute(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.7.1) +-> father_name = [Media_gateway] +-> -> MG_Attribute(0) + + +Register leaf node: MG_Attribute. +Instance: 256 +Length : 53 +Flag : 255 +Default : +Remark : MG Attributes + +Field : total(3) +Access : read-only [1]MG Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]MG IP Address + { + [u]1.0-4.7 + [u]input + [v]KeepHex high 0 + } +[3]MG Name + { + [u]5.0-52.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: CCF_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3) +-> father_name = [CCF(MSC)] +-> -> CCF_Config(0) +-> -> CCF_Status(1) + + +Remark: Status for CCF . + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.1) +-> father_name = [CCF_Status] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of MSC software (Read only).
+Byte0: System release version number, based on basic function and structure.
+Byte1: Software module version number, based on software module.
+Byte2: Test version, 0=Release version number, 1=Test version number.. + +Field : total(0) +Access : read-only + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.2) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : î +Remark : Control command for MSC-CPC. +Reset: Used for CPC status initialization. +Initialize: Restore the parameter setup to the default factory setting. +Save parameter: Save the parameters residing in CPC's memory into CPC's harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]90[opt]Reset + [v]165[opt]Initialize + [v]181[opt]Save parameter + [v]238[opt]No command + } + + +Create node: E1_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.4) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) +-> -> E1_Status(2) + + +Register leaf node: E1_Status. +Instance: 128 +Length : 1 +Flag : 255 +Default : î +Remark : E1 status (read only). + +Field : total(2) +Access : read-only[1]Quantity of occupied timeslot + { + [u]0.0-0.4 + [u]input + [v]toDec high 0 + } + [2]E1 type + { + [u]0.5-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF_CDMA2K + [v]4[opt]BICC + } + + +Create node: Channel_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) +-> -> E1_Status(2) +-> -> Channel_Status(3) + + +Remark: Channel status (read only). + + +Create node: Card0_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.1) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) + + +Register leaf node: Card0_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card1_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.2) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) + + +Register leaf node: Card1_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card2_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.3) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) + + +Register leaf node: Card2_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card3_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.4) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) + + +Register leaf node: Card3_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card4_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.5) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) + + +Register leaf node: Card4_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card5_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.6) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) + + +Register leaf node: Card5_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card6_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.7) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) + + +Register leaf node: Card6_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card7_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.8) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) + + +Register leaf node: Card7_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card8_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.9) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) + + +Register leaf node: Card8_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card9_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.10) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) + + +Register leaf node: Card9_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card10_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.11) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) + + +Register leaf node: Card10_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card11_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.12) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) + + +Register leaf node: Card11_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card12_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.13) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) + + +Register leaf node: Card12_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card13_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.14) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) + + +Register leaf node: Card13_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card14_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.15) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) +-> -> Card14_Status(14) + + +Register leaf node: Card14_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card15_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.16) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) +-> -> Card14_Status(14) +-> -> Card15_Status(15) + + +Register leaf node: Card15_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: VLR(OID: 1.3.6.1.4.1.1373.1.3.3.2.5) +-> father_name = [MSC] +-> -> CCF(MSC)(0) +-> -> VLR(1) + + +Remark: sub for VLR . + + +Create node: VLR_Config(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2) +-> father_name = [VLR] +-> -> VLR_Config(0) + + +Remark: + Configuration for VLR . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1) +-> father_name = [VLR_Config] +-> -> Public_Param(0) + + +Remark: Public parameters . + + +Create node: OptAuthReq(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.1) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) + + +Register leaf node: OptAuthReq. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of SIM authentication on MS poweron and MO/MT call. + +Field : total(4) +Access : read-write [1]Update Location + { + [u]0.0-0.0 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [2]MO + { + [u]0.1-0.1 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [3]MT + { + [u]0.2-0.2 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } +[4]Spare + { + [u]0.3-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptReuseTriplets(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.2) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) + + +Register leaf node: OptReuseTriplets. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of reusing authentication triplets in VLR in the case that authentication to HLR is not available. Default=disable. + +Field : total(3) +Access : read-write [1]OptReuseTriplets + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]double authentication + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[3]Spare + { + [u]0.2-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptCipReq(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.3) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) + + +Register leaf node: OptCipReq. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of voice ciphering over air interface by MS. Default=Disable. + +Field : total(1) +Access : read-write [1]OptCipReq + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: OptCiphAlgo(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.4) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) + + +Register leaf node: OptCiphAlgo. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Voice ciphering algorithm selection. Default=no ciphering. + +Field : total(1) +Access : read-write [1]OptCiphAlgo + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]A5_1 + [v]2[opt]A5_2 + [v]3[opt]A5_3 + [v]4[opt]A5_4 + [v]5[opt]A5_5 + [v]6[opt]A5_6 + [v]7[opt]A5_7 + } + + +Create node: OptTmsiAlloc(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.5) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) + + +Register leaf node: OptTmsiAlloc. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Flag of allocating a new TMSI every time a call management service is requested. Default=Disable. + +Field : total(1) +Access : read-write [1]TMSI Allocation Option + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Allocate TMSI + [v]2[opt]Reallocate TMSI + } + + +Create node: OptEcSetUpAllow(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.7) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) + + +Register leaf node: OptEcSetUpAllow. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Flag of making emergency call for non-registered MS or MS without SIM. Default=Enable. + +Field : total(1) +Access : read-write [1]OptEcSetUpAllow + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: OptCheckIMEI(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.8) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) + + +Register leaf node: OptCheckIMEI. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of IMEI verification via EIR. Default=no IMEI verification. + +Field : total(4) +Access : read-write [1]Update Location + { + [u]0.0-0.0 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [2]MO + { + [u]0.1-0.1 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [3]MT + { + [u]0.2-0.2 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } +[4]Spare + { + [u]0.3-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptVlrPurge(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.9) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) + + +Register leaf node: OptVlrPurge. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of VLR purge. Default=Off. + +Field : total(1) +Access : read-write [1]OptVlrPurge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: IdlePeriod2Purge(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.10) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) + + +Register leaf node: IdlePeriod2Purge. +Instance: 1 +Length : 1 +Flag : 255 +Default : < +Remark : Set the threshold of idle time to purge. If a mobile's idle time reaches this threshold, VLR will purge all records of this MS, unit=6 minute. Default=60minutes. + +Field : total(1) +Access : read-write[1]IdlePeriod2Purge + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.11) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) +-> -> CDR_Flag(9) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : VLR CDR flag. Default=On. + +Field : total(1) +Access : read-write [1]CDR on/off + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: MSRN(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.13) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) +-> -> CDR_Flag(9) +-> -> MSRN(10) + + +Register leaf node: MSRN. +Instance: 1 +Length : 16 +Flag : 255 +Default : †uS@ +Remark : Mobile station roaming number, use 16 bytes (32 digits) to define a range of MSRN. The length of start MSRN and end MSRN must be identical. F=end tag. + +Field : total(2) +Access : read-write[3]Start number + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low F + } +[4]End number + { + [u]8.0-15.7 + [u]input + [v]KeepHex Low F + } + + +Create node: VLR_Management(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3) +-> father_name = [VLR] +-> -> VLR_Config(0) +-> -> VLR_Management(1) + + +Remark: + Management for VLR . + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.2) +-> father_name = [VLR_Management] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of VLR software (Read only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-only + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.3) +-> father_name = [VLR_Management] +-> -> Version(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : î +Remark : Control command for VLR. +Reset: Used to initialize the status of VLR. +Save parameters: Save the parameters residing in memory into harddisk. + +Field : total(1) +Access : write-only [1]Management + { + [u]0.0-0.7 + [u]select + [v]0[opt]Reset VLR + [v]1[opt]Save parameters + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.4) +-> father_name = [VLR_Management] +-> -> Version(0) +-> -> Command(1) +-> -> Status(2) + + +Register leaf node: Status. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Basic status of VLR. + +Field : total(0) +Access : read-only + +Create node: HLR(OID: 1.3.6.1.4.1.1373.1.3.3.3) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) + + +Remark: Subsystems for HLR . + + +Create node: Config(OID: 1.3.6.1.4.1.1373.1.3.3.3.2) +-> father_name = [HLR] +-> -> Config(0) + + +Remark: + Configuration for HLR . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1) +-> father_name = [Config] +-> -> Public_Param(0) + + +Remark: + Public parameter . + + +Create node: HPLMN(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.11) +-> father_name = [Public_Param] +-> -> HPLMN(0) + + +Register leaf node: HPLMN. +Instance: 1 +Length : 17 +Flag : 255 +Default : îîîîîîîîîîîîîîîîî +Remark : Define the SN (VLR phone number) range of the VLR in the HPLMN (home PLMN) by specifying the start and end phone number of the range. +MSISDN=CC(country code)+NDC(National Destination Code)+SN. +All VLRs within a HPLMN have the same CC and NDC but the different SN. The SN of all VLR in a HPLMN must lie within the defined SN range. +Byte0-1=Country code. +Byte2-3=National destination code. +Byte4-9=Start SN of the VLR SN. +Byte10-15=End SN of the VLR SN. +e.g. For China country code=86, Shanghai national destination code=21, VLR SN=26060888: +Byte0-1=86EE, +Byte2-3=21EE, +SN=26060888, +Else=E. + +Field : total(4) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]NDC + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Start SN + { + [u]5.0-10.7 + [u]input + [v]KeepHex Low E + } +[4]End SN + { + [u]11.0-16.7 + [u]input + [v]KeepHex Low E + } + + +Create node: VPLMNs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.12) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) + + +Register leaf node: VPLMNs. +Instance: 256 +Length : 17 +Flag : 255 +Default : îîîîîîîîîîîîîîîîî +Remark : Define all connected VPLMNs (up tp 256) by specifying all VLR zones included in these VPLMNs. Each VLR zone is defined by its VLR MSISDN. MSISDN=CC+NDC+SN. All VLRs within a same VPLMN have the CC and NDC but the different SN. A VPLMN contains a group of VLRs whose SN is included in the defined SN range, E=random digit. +This parameter also define two ranges of VLR CSRR (Country specific roaming restrictionszones) zones for each VPLMN. In these defined VLR CSRR zones all HPLMN subscribers may be subjected to country specific roaming restrictions. +For each VPLMN setup, the format is: +byte0=ISDN numbering plan, default=91. +byte1-2=country code, EEEE. +byte3-4=national destination code, EEEE. +byte5-10=start SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. +byte11-16=end SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. +byte17-22=start SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte23-28=end SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte29-34=start SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte35-40=end SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +E=random digit. + +Field : total(4) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]NDC + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Start SN + { + [u]5.0-10.7 + [u]input + [v]KeepHex Low E + } +[4]End SN + { + [u]11.0-16.7 + [u]input + [v]KeepHex Low E + } + + +Create node: CSRR_List(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.13) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) + + +Register leaf node: CSRR_List. +Instance: 8 +Length : 32 +Flag : 255 +Default : +Remark : Define 8 CSRR (country specific roaming restriction) lists to confine the roaming range of a subscriber. +Each CSRR list defines the roaming restriction for 256 VPLMN ranges. + +Field : total(256) +Access : read-write [1]VPLMN0 Roaming allowed + { + [u]31.0-31.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [2]VPLMN1 Roaming allowed + { + [u]31.1-31.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [3]VPLMN2 Roaming allowed + { + [u]31.2-31.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [4]VPLMN3 Roaming allowed + { + [u]31.3-31.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [5]VPLMN4 Roaming allowed + { + [u]31.4-31.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [6]VPLMN5 Roaming allowed + { + [u]31.5-31.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [7]VPLMN6 Roaming allowed + { + [u]31.6-31.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [8]VPLMN7 Roaming allowed + { + [u]31.7-31.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [9]VPLMN8 Roaming allowed + { + [u]30.0-30.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [10]VPLMN9 Roaming allowed + { + [u]30.1-30.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [11]VPLMN10 Roaming allowed + { + [u]30.2-30.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [12]VPLMN11 Roaming allowed + { + [u]30.3-30.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [13]VPLMN12 Roaming allowed + { + [u]30.4-30.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [14]VPLMN13 Roaming allowed + { + [u]30.5-30.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [15]VPLMN14 Roaming allowed + { + [u]30.6-30.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [16]VPLMN15 Roaming allowed + { + [u]30.7-30.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [17]VPLMN16 Roaming allowed + { + [u]29.0-29.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [18]VPLMN17 Roaming allowed + { + [u]29.1-29.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [19]VPLMN18 Roaming allowed + { + [u]29.2-29.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [20]VPLMN19 Roaming allowed + { + [u]29.3-29.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [21]VPLMN20 Roaming allowed + { + [u]29.4-29.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [22]VPLMN21 Roaming allowed + { + [u]29.5-29.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [23]VPLMN22 Roaming allowed + { + [u]29.6-29.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [24]VPLMN23 Roaming allowed + { + [u]29.7-29.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [25]VPLMN24 Roaming allowed + { + [u]28.0-28.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [26]VPLMN25 Roaming allowed + { + [u]28.1-28.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [27]VPLMN26 Roaming allowed + { + [u]28.2-28.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [28]VPLMN27 Roaming allowed + { + [u]28.3-28.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [29]VPLMN28 Roaming allowed + { + [u]28.4-28.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [30]VPLMN29 Roaming allowed + { + [u]28.5-28.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [31]VPLMN30 Roaming allowed + { + [u]28.6-28.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [32]VPLMN31 Roaming allowed + { + [u]28.7-28.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [33]VPLMN32 Roaming allowed + { + [u]27.0-27.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [34]VPLMN33 Roaming allowed + { + [u]27.1-27.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [35]VPLMN34 Roaming allowed + { + [u]27.2-27.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [36]VPLMN35 Roaming allowed + { + [u]27.3-27.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [37]VPLMN36 Roaming allowed + { + [u]27.4-27.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [38]VPLMN37 Roaming allowed + { + [u]27.5-27.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [39]VPLMN38 Roaming allowed + { + [u]27.6-27.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [40]VPLMN39 Roaming allowed + { + [u]27.7-27.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [41]VPLMN40 Roaming allowed + { + [u]26.0-26.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [42]VPLMN41 Roaming allowed + { + [u]26.1-26.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [43]VPLMN42 Roaming allowed + { + [u]26.2-26.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [44]VPLMN43 Roaming allowed + { + [u]26.3-26.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [45]VPLMN44 Roaming allowed + { + [u]26.4-26.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [46]VPLMN45 Roaming allowed + { + [u]26.5-26.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [47]VPLMN46 Roaming allowed + { + [u]26.6-26.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [48]VPLMN47 Roaming allowed + { + [u]26.7-26.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [49]VPLMN48 Roaming allowed + { + [u]25.0-25.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [50]VPLMN49 Roaming allowed + { + [u]25.1-25.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [51]VPLMN50 Roaming allowed + { + [u]25.2-25.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [52]VPLMN51 Roaming allowed + { + [u]25.3-25.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [53]VPLMN52 Roaming allowed + { + [u]25.4-25.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [54]VPLMN53 Roaming allowed + { + [u]25.5-25.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [55]VPLMN54 Roaming allowed + { + [u]25.6-25.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [56]VPLMN55 Roaming allowed + { + [u]25.7-25.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [57]VPLMN56 Roaming allowed + { + [u]24.0-24.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [58]VPLMN57 Roaming allowed + { + [u]24.1-24.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [59]VPLMN58 Roaming allowed + { + [u]24.2-24.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [60]VPLMN59 Roaming allowed + { + [u]24.3-24.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [61]VPLMN60 Roaming allowed + { + [u]24.4-24.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [62]VPLMN61 Roaming allowed + { + [u]24.5-24.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [63]VPLMN62 Roaming allowed + { + [u]24.6-24.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [64]VPLMN63 Roaming allowed + { + [u]24.7-24.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [65]VPLMN64 Roaming allowed + { + [u]23.0-23.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [66]VPLMN65 Roaming allowed + { + [u]23.1-23.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [67]VPLMN66 Roaming allowed + { + [u]23.2-23.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [68]VPLMN67 Roaming allowed + { + [u]23.3-23.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [69]VPLMN68 Roaming allowed + { + [u]23.4-23.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [70]VPLMN69 Roaming allowed + { + [u]23.5-23.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [71]VPLMN70 Roaming allowed + { + [u]23.6-23.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [72]VPLMN71 Roaming allowed + { + [u]23.7-23.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [73]VPLMN72 Roaming allowed + { + [u]22.0-22.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [74]VPLMN73 Roaming allowed + { + [u]22.1-22.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [75]VPLMN74 Roaming allowed + { + [u]22.2-22.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [76]VPLMN75 Roaming allowed + { + [u]22.3-22.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [77]VPLMN76 Roaming allowed + { + [u]22.4-22.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [78]VPLMN77 Roaming allowed + { + [u]22.5-22.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [79]VPLMN78 Roaming allowed + { + [u]22.6-22.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [80]VPLMN79 Roaming allowed + { + [u]22.7-22.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [81]VPLMN80 Roaming allowed + { + [u]21.0-21.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [82]VPLMN81 Roaming allowed + { + [u]21.1-21.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [83]VPLMN82 Roaming allowed + { + [u]21.2-21.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [84]VPLMN83 Roaming allowed + { + [u]21.3-21.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [85]VPLMN84 Roaming allowed + { + [u]21.4-21.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [86]VPLMN85 Roaming allowed + { + [u]21.5-21.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [87]VPLMN86 Roaming allowed + { + [u]21.6-21.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [88]VPLMN87 Roaming allowed + { + [u]21.7-21.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [89]VPLMN88 Roaming allowed + { + [u]20.0-20.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [90]VPLMN89 Roaming allowed + { + [u]20.1-20.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [91]VPLMN90 Roaming allowed + { + [u]20.2-20.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [92]VPLMN91 Roaming allowed + { + [u]20.3-20.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [93]VPLMN92 Roaming allowed + { + [u]20.4-20.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [94]VPLMN93 Roaming allowed + { + [u]20.5-20.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [95]VPLMN94 Roaming allowed + { + [u]20.6-20.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [96]VPLMN95 Roaming allowed + { + [u]20.7-20.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [97]VPLMN96 Roaming allowed + { + [u]19.0-19.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [98]VPLMN97 Roaming allowed + { + [u]19.1-19.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [99]VPLMN98 Roaming allowed + { + [u]19.2-19.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [100]VPLMN99 Roaming allowed + { + [u]19.3-19.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [101]VPLMN100 Roaming allowed + { + [u]19.4-19.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [102]VPLMN101 Roaming allowed + { + [u]19.5-19.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [103]VPLMN102 Roaming allowed + { + [u]19.6-19.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [104]VPLMN103 Roaming allowed + { + [u]19.7-19.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [105]VPLMN104 Roaming allowed + { + [u]18.0-18.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [106]VPLMN105 Roaming allowed + { + [u]18.1-18.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [107]VPLMN106 Roaming allowed + { + [u]18.2-18.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [108]VPLMN107 Roaming allowed + { + [u]18.3-18.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [109]VPLMN108 Roaming allowed + { + [u]18.4-18.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [110]VPLMN109 Roaming allowed + { + [u]18.5-18.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [111]VPLMN110 Roaming allowed + { + [u]18.6-18.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [112]VPLMN111 Roaming allowed + { + [u]18.7-18.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [113]VPLMN112 Roaming allowed + { + [u]17.0-17.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [114]VPLMN113 Roaming allowed + { + [u]17.1-17.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [115]VPLMN114 Roaming allowed + { + [u]17.2-17.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [116]VPLMN115 Roaming allowed + { + [u]17.3-17.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [117]VPLMN116 Roaming allowed + { + [u]17.4-17.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [118]VPLMN117 Roaming allowed + { + [u]17.5-17.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [119]VPLMN118 Roaming allowed + { + [u]17.6-17.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [120]VPLMN119 Roaming allowed + { + [u]17.7-17.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [121]VPLMN120 Roaming allowed + { + [u]16.0-16.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [122]VPLMN121 Roaming allowed + { + [u]16.1-16.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [123]VPLMN122 Roaming allowed + { + [u]16.2-16.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [124]VPLMN123 Roaming allowed + { + [u]16.3-16.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [125]VPLMN124 Roaming allowed + { + [u]16.4-16.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [126]VPLMN125 Roaming allowed + { + [u]16.5-16.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [127]VPLMN126 Roaming allowed + { + [u]16.6-16.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [128]VPLMN127 Roaming allowed + { + [u]16.7-16.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [129]VPLMN128 Roaming allowed + { + [u]15.0-15.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [130]VPLMN129 Roaming allowed + { + [u]15.1-15.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [131]VPLMN130 Roaming allowed + { + [u]15.2-15.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [132]VPLMN131 Roaming allowed + { + [u]15.3-15.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [133]VPLMN132 Roaming allowed + { + [u]15.4-15.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [134]VPLMN133 Roaming allowed + { + [u]15.5-15.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [135]VPLMN134 Roaming allowed + { + [u]15.6-15.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [136]VPLMN135 Roaming allowed + { + [u]15.7-15.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [137]VPLMN136 Roaming allowed + { + [u]14.0-14.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [138]VPLMN137 Roaming allowed + { + [u]14.1-14.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [139]VPLMN138 Roaming allowed + { + [u]14.2-14.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [140]VPLMN139 Roaming allowed + { + [u]14.3-14.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [141]VPLMN140 Roaming allowed + { + [u]14.4-14.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [142]VPLMN141 Roaming allowed + { + [u]14.5-14.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [143]VPLMN142 Roaming allowed + { + [u]14.6-14.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [144]VPLMN143 Roaming allowed + { + [u]14.7-14.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [145]VPLMN144 Roaming allowed + { + [u]13.0-13.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [146]VPLMN145 Roaming allowed + { + [u]13.1-13.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [147]VPLMN146 Roaming allowed + { + [u]13.2-13.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [148]VPLMN147 Roaming allowed + { + [u]13.3-13.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [149]VPLMN148 Roaming allowed + { + [u]13.4-13.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [150]VPLMN149 Roaming allowed + { + [u]13.5-13.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [151]VPLMN150 Roaming allowed + { + [u]13.6-13.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [152]VPLMN151 Roaming allowed + { + [u]13.7-13.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [153]VPLMN152 Roaming allowed + { + [u]12.0-12.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [154]VPLMN153 Roaming allowed + { + [u]12.1-12.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [155]VPLMN154 Roaming allowed + { + [u]12.2-12.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [156]VPLMN155 Roaming allowed + { + [u]12.3-12.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [157]VPLMN156 Roaming allowed + { + [u]12.4-12.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [158]VPLMN157 Roaming allowed + { + [u]12.5-12.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [159]VPLMN158 Roaming allowed + { + [u]12.6-12.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [160]VPLMN159 Roaming allowed + { + [u]12.7-12.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [161]VPLMN160 Roaming allowed + { + [u]11.0-11.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [162]VPLMN161 Roaming allowed + { + [u]11.1-11.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [163]VPLMN162 Roaming allowed + { + [u]11.2-11.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [164]VPLMN163 Roaming allowed + { + [u]11.3-11.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [165]VPLMN164 Roaming allowed + { + [u]11.4-11.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [166]VPLMN165 Roaming allowed + { + [u]11.5-11.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [167]VPLMN166 Roaming allowed + { + [u]11.6-11.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [168]VPLMN167 Roaming allowed + { + [u]11.7-11.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [169]VPLMN168 Roaming allowed + { + [u]10.0-10.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [170]VPLMN169 Roaming allowed + { + [u]10.1-10.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [171]VPLMN170 Roaming allowed + { + [u]10.2-10.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [172]VPLMN171 Roaming allowed + { + [u]10.3-10.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [173]VPLMN172 Roaming allowed + { + [u]10.4-10.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [174]VPLMN173 Roaming allowed + { + [u]10.5-10.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [175]VPLMN174 Roaming allowed + { + [u]10.6-10.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [176]VPLMN175 Roaming allowed + { + [u]10.7-10.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [177]VPLMN176 Roaming allowed + { + [u]9.0-9.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [178]VPLMN177 Roaming allowed + { + [u]9.1-9.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [179]VPLMN178 Roaming allowed + { + [u]9.2-9.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [180]VPLMN179 Roaming allowed + { + [u]9.3-9.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [181]VPLMN180 Roaming allowed + { + [u]9.4-9.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [182]VPLMN181 Roaming allowed + { + [u]9.5-9.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [183]VPLMN182 Roaming allowed + { + [u]9.6-9.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [184]VPLMN183 Roaming allowed + { + [u]9.7-9.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [185]VPLMN184 Roaming allowed] + { + [u]8.0-8.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [186]VPLMN185 Roaming allowed + { + [u]8.1-8.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [187]VPLMN186 Roaming allowed + { + [u]8.2-8.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [188]VPLMN187 Roaming allowed + { + [u]8.3-8.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [189]VPLMN188 Roaming allowed + { + [u]8.4-8.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [190]VPLMN189 Roaming allowed + { + [u]8.5-8.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [191]VPLMN190 Roaming allowed + { + [u]8.6-8.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [192]VPLMN191 Roaming allowed + { + [u]8.7-8.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [193]VPLMN192 Roaming allowed + { + [u]7.0-7.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [194]VPLMN193 Roaming allowed + { + [u]7.1-7.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [195]VPLMN194 Roaming allowed + { + [u]7.2-7.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [196]VPLMN195 Roaming allowed + { + [u]7.3-7.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [197]VPLMN196 Roaming allowed + { + [u]7.4-7.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [198]VPLMN197 Roaming allowed + { + [u]7.5-7.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [199]VPLMN198 Roaming allowed + { + [u]7.6-7.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [200]VPLMN199 Roaming allowed + { + [u]7.7-7.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [201]VPLMN200 Roaming allowed + { + [u]6.0-6.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [202]VPLMN201 Roaming allowed + { + [u]6.1-6.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [203]VPLMN202 Roaming allowed + { + [u]6.2-6.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [204]VPLMN203 Roaming allowed + { + [u]6.3-6.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [205]VPLMN204 Roaming allowed + { + [u]6.4-6.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [206]VPLMN205 Roaming allowed + { + [u]6.5-6.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [207]VPLMN206 Roaming allowed + { + [u]6.6-6.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [208]VPLMN207 Roaming allowed + { + [u]6.7-6.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [209]VPLMN208 Roaming allowed + { + [u]5.0-5.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [210]VPLMN209 Roaming allowed + { + [u]5.1-5.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [211]VPLMN210 Roaming allowed + { + [u]5.2-5.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [212]VPLMN211 Roaming allowed + { + [u]5.3-5.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [213]VPLMN212 Roaming allowed + { + [u]5.4-5.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [214]VPLMN213 Roaming allowed + { + [u]5.5-5.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [215]VPLMN214 Roaming allowed + { + [u]5.6-5.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [216]VPLMN215 Roaming allowed + { + [u]5.7-5.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [217]VPLMN216 Roaming allowed + { + [u]4.0-4.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [218]VPLMN217 Roaming allowed + { + [u]4.1-4.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [219]VPLMN218 Roaming allowed + { + [u]4.2-4.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [220]VPLMN219 Roaming allowed + { + [u]4.3-4.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [221]VPLMN220 Roaming allowed + { + [u]4.4-4.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [222]VPLMN221 Roaming allowed + { + [u]4.5-4.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [223]VPLMN222 Roaming allowed + { + [u]4.6-4.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [224]VPLMN223 Roaming allowed + { + [u]4.7-4.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [225]VPLMN224 Roaming allowed + { + [u]3.0-3.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [226]VPLMN225 Roaming allowed + { + [u]3.1-3.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [227]VPLMN226 Roaming allowed + { + [u]3.2-3.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [228]VPLMN227 Roaming allowed + { + [u]3.3-3.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [229]VPLMN228 Roaming allowed + { + [u]3.4-3.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [230]VPLMN229 Roaming allowed + { + [u]3.5-3.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [231]VPLMN230 Roaming allowed + { + [u]3.6-3.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [232]VPLMN231 Roaming allowed + { + [u]3.7-3.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [233]VPLMN232 Roaming allowed + { + [u]2.0-2.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [234]VPLMN233 Roaming allowed + { + [u]2.1-2.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [235]VPLMN234 Roaming allowed + { + [u]2.2-2.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [236]VPLMN235 Roaming allowed + { + [u]2.3-2.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [237]VPLMN236 Roaming allowed + { + [u]2.4-2.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [238]VPLMN237 Roaming allowed + { + [u]2.5-2.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [239]VPLMN238 Roaming allowed + { + [u]2.6-2.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [240]VPLMN239 Roaming allowed + { + [u]2.7-2.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [241]VPLMN240 Roaming allowed + { + [u]1.0-1.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [242]VPLMN241 Roaming allowed + { + [u]1.1-1.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [243]VPLMN242 Roaming allowed + { + [u]1.2-1.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [244]VPLMN243 Roaming allowed + { + [u]1.3-1.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [245]VPLMN244 Roaming allowed + { + [u]1.4-1.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [246]VPLMN245 Roaming allowed + { + [u]1.5-1.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [247]VPLMN246 Roaming allowed + { + [u]1.6-1.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [248]VPLMN247 Roaming allowed + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [249]VPLMN248 Roaming allowed + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [250]VPLMN249 Roaming allowed + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [251]VPLMN250 Roaming allowed + { + [u]0.2-0.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [252]VPLMN251 Roaming allowed + { + [u]0.3-0.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [253]VPLMN252 Roaming allowed + { + [u]0.4-0.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [254]VPLMN253 Roaming allowed + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [255]VPLMN254 Roaming allowed + { + [u]0.6-0.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [256]VPLMN255 Roaming allowed + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Regional_Subs_List(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.14) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) + + +Register leaf node: Regional_Subs_List. +Instance: 255 +Length : 7 +Flag : 255 +Default : îîîîîîî +Remark : Define the regional subscription zone code list. HLR supports up to 256 regional subscription zone code. +Regional subscription code = CC+NDC+zone code + +Field : total(3) +Access : read-write[1]Country Code + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]National Destination Code + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Zone Code + { + [u]5.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Licenses_Control(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.15) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) + + +Register leaf node: Licenses_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of HLR subscribers for service provider: +The new license can not support less HLR subscribers than what the old license supports. + +Field : total(1) +Access : write-only[1]Licenses + { + [u]0.0-7.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: CDR_Control(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.16) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) +-> -> CDR_Control(5) + + +Register leaf node: CDR_Control. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : HLR CDR generation flag: +Off=Not generate HLR CDR. +On=Generate HLR CDR. + +Field : total(1) +Access : read-write [1]CDR control + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: Feature_Code(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.27) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) +-> -> CDR_Control(5) +-> -> Feature_Code(6) + + +Register leaf node: Feature_Code. +Instance: 1 +Length : 64 +Flag : 255 +Default : �îhîrî’îpî +Remark : None. + +Field : total(6) +Access : read-write[1]CFB + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]CFD + { + [u]2.0-3.7 + [u]input + [v]KeepHex Low E + } +[3]CFNA + { + [u]4.0-5.7 + [u]input + [v]KeepHex Low E + } +[4]CFU + { + [u]6.0-7.7 + [u]input + [v]KeepHex Low E + } +[5]Call waiting + { + [u]8.0-9.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2) +-> father_name = [Config] +-> -> Public_Param(0) +-> -> Management(1) + + +Remark: + Management . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.2) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Bit0-2: HLR paramter save control: +Idle=no operation. +Save=Save parameters from HLR memory to HLR hard disk. +Bit3-5: HLR subscriber data save control: +Idle=no operation. +Save=Save HLR subscriber data from HLR memory to both HLR hard disk and OMC database. +Bit6-7: Reserved. + +Field : total(3) +Access : read-write [1]Save parameter to HD + { + [u]0.0-0.2 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + } + [2]Save subscriber data to HD&OMC + { + [u]0.3-0.5 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + } + + +Create node: Subscriber_Import(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.3) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) + + +Register leaf node: Subscriber_Import. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Progress and result of HLR subscriber import. +Byte0: Progress of HLR subscriber import. +Byte1-3: Total quantity of HLR subscribers requesting import. +Byte4-7: Quantity of successfully imported HLR subscribers. + +Field : total(3) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading Failed + } +[2]Total subscriber requested + { + [u]1.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Total imported subscribers + { + [u]4.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Max_Licenses(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.11) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) + + +Register leaf node: Max_Licenses. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The maximum quantity of approved HLR subscribers determined by License control (Read Only). + +Field : total(1) +Access : read-only[1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Used_Licenses(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.12) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) + + +Register leaf node: Used_Licenses. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of currently registered HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Used Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Subscriber_Info(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) + + +Remark: + Subscriber information . + + +Create node: Provisioned_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.1) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) + + +Register leaf node: Provisioned_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of service provisioned and active HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Provisioned Subs + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Registered_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.2) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) +-> -> Registered_Subs(1) + + +Register leaf node: Registered_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of registered (both active and inactive) HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Registered Subs + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Roaming_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.3) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) +-> -> Registered_Subs(1) +-> -> Roaming_Subs(2) + + +Register leaf node: Roaming_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of provisioned HLR subscribers currently roaming to VPLMNs (Read Only). + +Field : total(1) +Access : read-only[1]Roaming Subs + { + [u]0.0-0.0 + [u]input + [v]toDec high 0 + } + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) + + +Remark: + Version . + + +Create node: Software(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14.1) +-> father_name = [Version] +-> -> Software(0) + + +Register leaf node: Software. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of HLR software (Read Only): +Byte0: System release version number: +- Based on basic function and structure. +Byte1: Software module version number: +- Based on software module. +Byte2: Test version: +- 0=Release version number. +- 1=Test version number. + +Field : total(3) +Access : read-only[1]Release + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Version + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Slice + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: User_Data(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14.2) +-> father_name = [Version] +-> -> Software(0) +-> -> User_Data(1) + + +Register leaf node: User_Data. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC subscriber data (Read Only): +System release version: Based on basic function and structure. +Subscriber data version: Based on software module. +Test version: 0=Release version 1=Test version + +Field : total(3) +Access : read-only[1]Release + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Version + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Slice + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: IMSI_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.15) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) + + +Register leaf node: IMSI_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : MSISDN segment table (Read Only): +Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + +Field : total(1) +Access : read-only[1]IMSI segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: MSISDN_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.16) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) +-> -> MSISDN_Segment(7) + + +Register leaf node: MSISDN_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : MSISDN segment table (Read Only): +Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + +Field : total(1) +Access : read-only[1]MSISDN segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: CNF_Applicant_Info(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.27) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) +-> -> MSISDN_Segment(7) +-> -> CNF_Applicant_Info(8) + + +Register leaf node: CNF_Applicant_Info. +Instance: 1 +Length : 9 +Flag : 255 +Default : +Remark : Display the IMSI and charge type of the latest conference applicant (Read Only). + +Field : total(2) +Access : read-only [1]Charge Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Invalid user + [v]1[opt]Post-pay user + [v]2[opt]Prepaid user + } +[2]IMSI + { + [u]1.0-8.7 + [u]input + [v]KeepHex Low E + } + + +Create node: AUC(OID: 1.3.6.1.4.1.1373.1.3.3.4) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) + + +Remark: Subsystems for AUC . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.4.2) +-> father_name = [AUC] +-> -> Configuration(0) + + +Remark: + Configuration for AUC . + + +Create node: Public_parameter(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1) +-> father_name = [Configuration] +-> -> Public_parameter(0) + + +Remark: + Public_parameter for AUC . + + +Create node: SSD(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.2) +-> father_name = [Public_parameter] +-> -> SSD(0) + + +Register leaf node: SSD. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : SSD + +Field : total(3) +Access : read-write [1]share SSD + { + [u]0.0-0.7 + [u]select + [v]0[opt]not share + [v]1[opt]share + } +[2]Update SSD timer + { + [u]1.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Count(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.3) +-> father_name = [Public_parameter] +-> -> SSD(0) +-> -> Count(1) + + +Register leaf node: Count. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : Count. + +Field : total(2) +Access : read-write[1]Count Match Range + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Failures(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.4) +-> father_name = [Public_parameter] +-> -> SSD(0) +-> -> Count(1) +-> -> Failures(2) + + +Register leaf node: Failures. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : Count. + +Field : total(7) +Access : read-write [1]AUTHR Mismatch + { + [u]0.0-0.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + [2]Count Mismatch + { + [u]1.0-1.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [3]Unique Challenge Failure + { + [u]2.0-2.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [4]SSD Update Failure + { + [u]3.0-3.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [5]Count Update Failure + { + [u]4.0-4.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [6]Missing AUTH Parameters + { + [u]5.0-5.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2) +-> father_name = [Configuration] +-> -> Public_parameter(0) +-> -> Management(1) + + +Remark: + Management . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.2) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Command for AUC paramters and user data operation, and the result of command. + +Field : total(3) +Access : read-write [1]Save parameters to HD + { + [u]0.0-0.2 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + [v]1[opt]Saving + [v]2[opt]Save succeeds + [v]3[opt]Save fails + } + [2]Save user data to HD&OMC + { + [u]0.3-0.5 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + [v]1[opt]Saving + [v]2[opt]Save succeeds + [v]3[opt]Save fails + } + + +Create node: License_Control(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.3) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) + + +Register leaf node: License_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of AUC subscribers for service provider. The new license can not support less AUC subscribers than what the old license supports. + +Field : total(1) +Access : write-only[1]Licenses + { + [u]0.0-15.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: MAX_License(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.11) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) + + +Register leaf node: MAX_License. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The maximum quantity of approved AUC subscribers determined by License control Read only. + +Field : total(1) +Access : write-only[1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Used_License(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.12) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) + + +Register leaf node: Used_License. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of currently registered EIR subscribers (Read only). + +Field : total(1) +Access : read-only[1]Used Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: User_information(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.13) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) + + +Remark: + User Information . + + +Create node: Provisioned_Users(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.13.1) +-> father_name = [User_information] +-> -> Provisioned_Users(0) + + +Register leaf node: Provisioned_Users. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of service enabled AUC subscribers (Read only). + +Field : total(1) +Access : read-only[1]Provisioned users + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) +-> -> Version(5) + + +Remark: + Version . + + +Create node: Software(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14.1) +-> father_name = [Version] +-> -> Software(0) + + +Register leaf node: Software. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC software (Read only). +System: System release version, based on basic function and structure. +Module: Software module version, based on software module. +Test: Test version, 0=Release version. 1=Test version. + +Field : total(3) +Access : read-only[1]System + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Module + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Test + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: User_data(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14.2) +-> father_name = [Version] +-> -> Software(0) +-> -> User_data(1) + + +Register leaf node: User_data. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC subscriber data (Read only). +System: System release version, based on basic function and structure. +User data: Subscriber profile version, based on software module. +Test: Test version, 0=Release version. 1=Test version. + +Field : total(3) +Access : read-only[1]System + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]User data + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Test + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: IMSI_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.15) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) +-> -> Version(5) +-> -> IMSI_Segment(6) + + +Register leaf node: IMSI_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : IMSI segment table (Read only): +100,000 IMSIs are subdivided into 1000 segments, each IMSI segment use the 8 most significant digits (from the 6th digit to 13th digit of 15-digit of IMSI) as the segment number. +IMSI=MCC(3)+MNC(2)+MSIN(10) +Segment number=the 8 most significant digits of the MSIN, each segment has 100 subscribers (00-99). +e.g. If IMSI=460002356090098 then it belongs to IMSI segemt 23560900 and its account number in that segment=98. 0=empty segment. + +Field : total(1) +Access : read-only[1]IMSI segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.4.3) +-> father_name = [AUC] +-> -> Configuration(0) +-> -> Status(1) + + +Remark: + Status for AUC . + + +Create node: Import_status(OID: 1.3.6.1.4.1.1373.1.3.3.4.3.2) +-> father_name = [Status] +-> -> Import_status(0) + + +Register leaf node: Import_status. +Instance: 1 +Length : 12 +Flag : 255 +Default : +Remark : Import status. + +Field : total(0) +Access : read-write + +Create node: SMSC(OID: 1.3.6.1.4.1.1373.1.3.3.5) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) + + +Remark: Subsystems for SMSC . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.5.2) +-> father_name = [SMSC] +-> -> Configuration(0) + + +Remark: Configuration for SMSC . + + +Create node: System_Param(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1) +-> father_name = [Configuration] +-> -> System_Param(0) + + +Remark: system parameter . + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.1) +-> father_name = [System_Param] +-> -> CDR_Flag(0) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : SMSC CDR generation enable or disable. + +Field : total(3) +Access : read-write [1]SMSC CDR + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [2]SMSC LOG + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + + +Create node: SM_Validity(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.2) +-> father_name = [System_Param] +-> -> CDR_Flag(0) +-> -> SM_Validity(1) + + +Register leaf node: SM_Validity. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Period of validity of short message, define a threshold how long an awaiting sending message should be kept in sending array till sent to MS, unit is second, default=0c0a8h seconds=12 hours. + +Field : total(1) +Access : read-write[1]SM validity + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: MSISDN_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.3) +-> father_name = [System_Param] +-> -> CDR_Flag(0) +-> -> SM_Validity(1) +-> -> MSISDN_Segment(2) + + +Register leaf node: MSISDN_Segment. +Instance: 16 +Length : 19 +Flag : 255 +Default : †uUq' +Remark : Specify the beginning MSISDN for the range of provisioned subscriber. F=end tag. + +Field : total(3) +Access : read-write[1]Start MSISDN + { + [u]0.0-8.7 + [u]input + [v]KeepHex Low E + } +[2]End MSISDN + { + [u]9.0-17.7 + [u]input + [v]KeepHex Low E + } + [3]Number Type + { + [u]18.0-18.7 + [u]select + [v]0[opt]GSM + [v]1[opt]CDMA + } + + +Create node: SMPP_parameters(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.2) +-> father_name = [Configuration] +-> -> System_Param(0) +-> -> SMPP_parameters(1) + + +Register leaf node: SMPP_parameters. +Instance: 32 +Length : 12 +Flag : 255 +Default : +Remark : Name: Can be any name, generally use the name of the connected device. +Service number: SMPP connected party MSISDN used for display on MT MS, +e.g. for a SMPP to PPS, set the service number as MSISDN of PPS. +Data coding scheme: +00:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 7bit +01:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 7bit +10:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 8bit +11:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 8bit +Default=0. + +Field : total(5) +Access : read-write [1]Enable flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Session type + { + [u]1.0-1.7 + [u]select + [v]0[opt]BIND_TX + [v]1[opt]BIND_RX + [v]2[opt]BIND_TRX + } +[3]Service number + { + [u]2.0-9.7 + [u]input + [v]ToAscii Low 0 + } + [4]Message mode + { + [u]10.0-10.7 + [u]select + [v]0[opt]Store and forward + [v]1[opt]Datagram + [v]2[opt]Transaction + } + [5]Data Coding Scheme + { + [u]11.0-11.7 + [u]select + [v]0[opt]To smpp=7bit,default=7bit + [v]1[opt]To smpp=8bit,default=7bit + [v]16[opt]To smpp=7bit,default=8bit + [v]17[opt]To smpp=8bit,default=8bit + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.5.3) +-> father_name = [SMSC] +-> -> Configuration(0) +-> -> Management(1) + + +Remark: + Management for SMSC . + + +Create node: SMSC_ID(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.1) +-> father_name = [Management] +-> -> SMSC_ID(0) + + +Register leaf node: SMSC_ID. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : SMSC ID + +Field : total(1) +Access : read-write[1]SMSC ID + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Software_Version(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.2) +-> father_name = [Management] +-> -> SMSC_ID(0) +-> -> Software_Version(1) + + +Register leaf node: Software_Version. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Software version + +Field : total(1) +Access : write-only[1]Version + { + [u]0.0-2.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.3) +-> father_name = [Management] +-> -> SMSC_ID(0) +-> -> Software_Version(1) +-> -> Command(2) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : SMSC system command. +Save parameters: Save the SMSC parameters in memory to SMSC harddisk. +Delete pending SM: Delete the pending SM in awaiting array. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + [v]4[opt]Reset system + [v]5[opt]Delete pending SM + } + + +Create node: PPS(OID: 1.3.6.1.4.1.1373.1.3.3.6) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) +-> -> PPS(4) + + +Remark: Subsystems for PPS . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2) +-> father_name = [PPS] +-> -> Public_Param(0) + + +Remark: public parameters for MSS . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1) +-> father_name = [Public_Param] +-> -> Configuration(0) + + +Remark: Configuration for PPS . + + +Create node: Service_Control(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1) +-> father_name = [Configuration] +-> -> Service_Control(0) + + +Remark: Service Control . + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.1) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : PPS CDR generation enable or disable. Default=PPS generate CDR. + +Field : total(1) +Access : read-write [1]CDR flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Blacklist_Threshold(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.2) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) + + +Register leaf node: Blacklist_Threshold. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Legal recharge failure, subsciber who breaks the threshold will be marked in black list and suspended from service provisioning. Default=5. + +Field : total(1) +Access : read-write[1]Blacklist threshold + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Balance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.3) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) + + +Register leaf node: Maximum_Balance. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This value is for overflow prevention. Normally operator doesn't need to change this value. e.g. 5000, and the smallest unit is cent then the maximum allowed balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: License_Control(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.4) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) + + +Register leaf node: License_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of PPS subscribers for service provider. The new license can not support less PPS subscribers than what the old license supports. + +Field : total(1) +Access : read-write[1]License + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Prompt_Resolution(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.5) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) + + +Register leaf node: Prompt_Resolution. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Currency style: Set the number of decimals in account balance SM display format. If account balance=55555 in smallest currency unit: +1=account balance display in SM is 55555. +10=account balance display in SM is 5555.5. +100=account balance display in SM is 555.55. +Default=100. +Date style: Set the date format displayed in SM or announcement. Default=YYYY-MM-DD. +Currency symbol position: Set the position of the currency symbol. +There are two types: at the front of the amount (e.g. $5) or at the rear of the amount (e.g. 5Fr). Default=at the front. + +Field : total(4) +Access : read-write [1]Currency resolution + { + [u]0.0-0.1 + [u]select + [v]0[opt]1 + [v]1[opt]10 + [v]2[opt]100 + } + [2]Date format + { + [u]0.2-0.3 + [u]select + [v]0[opt]YYYY-MM-DD + [v]1[opt]DD-MM-YYYY + [v]2[opt]MM-DD-YYYY + } + [3]Currency symbol position + { + [u]0.0-0.0 + [u]select + [v]0[opt]Front + [v]1[opt]Rear + } + + +Create node: SMS_Sentence(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.6) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) + + +Register leaf node: SMS_Sentence. +Instance: 5 +Length : 112 +Flag : 255 +Default : +Remark : The # of sentence(0-4) refers to differenct language type; + +Field : total(4) +Access : read-write [1]SM encode type + { + [u]0.0-0.7 + [u]select + [v]0[opt]7 bit + [v]4[opt]octet + [v]8[opt]unicode + } +[2]Account balance + { + [u]1.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[3]expired in + { + [u]32.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[4]recharge in time + { + [u]64.0-111.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Last_Call_Info(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.7) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) + + +Register leaf node: Last_Call_Info. +Instance: 5 +Length : 88 +Flag : 255 +Default : Last call sent on: +Remark : The # of sentence(0-4) refers to differenct language type. + +Field : total(5) +Access : read-write[1]Last call sent on + { + [u]0.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[2]Last call received on + { + [u]32.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[3]At + { + [u]64.0-71.7 + [u]input + [v]ToAscii Low 0 + } +[4]To + { + [u]72.0-79.7 + [u]input + [v]ToAscii Low 0 + } +[5]From + { + [u]80.0-87.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Currency_Symbol(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.8) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) + + +Register leaf node: Currency_Symbol. +Instance: 1 +Length : 8 +Flag : 255 +Default : $ +Remark : Set the symbol of the local currency in SMS amount display. e.g. $, RMB, EUR, US$, FR$. default=$. In the set window, type the currency symbol. The input symbol will be converted to ASCII code. +Do not input any symbol that not listed on the ASCII code table. ASCII table: 'A'=0x41, 'B'=0x42 ... 'I'=0x49, 'J'=0x4a, 'K'=0x4b ... 'Z'=0x5A, '$'=0x24 +e.g. RMB=0x52 0x4d 0x42, US$=0x55 0x53 0x24 + +Field : total(1) +Access : read-write[1]Currency symbol + { + [u]0.0-7.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Third_Party_Info(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.9) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) +-> -> Third_Party_Info(8) + + +Register leaf node: Third_Party_Info. +Instance: 8 +Length : 16 +Flag : 255 +Default : +Remark : This parameter is a verification for third party ESME when the third party ESME sends a billing request to PPS server. For example, if a subscriber sends a short message via a ESME (e.g. website), the ESME will send a billing request to PPS to debit this subscriber. This billing request must contains a service ID and password to pass the verification. After verification, the subscriber will be debited by the PPS. PPS supports 8 ESME connections. + +Field : total(2) +Access : read-write[1]Service ID + { + [u]0.0-7.7 + [u]input + [v]ToAscii Low 0 + } +[2]Service password + { + [u]8.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Basic_Tariff_Zone(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.10) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) +-> -> Third_Party_Info(8) +-> -> Basic_Tariff_Zone(9) + + +Register leaf node: Basic_Tariff_Zone. +Instance: 64 +Length : 9 +Flag : 255 +Default : +Remark : The basic tariff is applied for each calling or called number prefix. The WXC2 System supports 16 MO and MT tariffs (0-15) and 256 billing zones. This parameter defines basic tariff for each billing zone. Each parameter is a combination of MCC, MNC, cell ID, LAC and MO/MT tariff ID. The billing zone may be set as a cell, a LAC or a zone. Normally a single billing zone deploys only one basic tariff. +Each PPS subscriber profile also contains its tariff setup specifying which tariff should be applied for this subscriber. Using either basic tariff zone (location dependent) or tariff in subscriber profile (subscriber dependent) is determined by a parameter -Tariff subscription-. +LAC: If LAC=65536, all LACs in the MCC and MNC use the same basic tariff. +Cell ID: If cell ID=65536, all cells in the LAC use the same basic tariff. + +Field : total(6) +Access : read-write[1]MCC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low F + } +[2]MNC + { + [u]2.0-2.7 + [u]input + [v]KeepHex Low F + } +[3]LAC + { + [u]3.0-4.7 + [u]input + [v]toDec high 0 + } +[4]Cell ID + { + [u]5.0-6.7 + [u]input + [v]toDec high 0 + } + [5]MO tariff ID + { + [u]7.0-7.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [6]MT tariff ID + { + [u]8.0-8.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: SRF_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) + + +Remark: SRF parameters . + + +Create node: SRF_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) + + +Remark: SRF Number. + + +Create node: SRF_0_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1.1) +-> father_name = [SRF_Number] +-> -> SRF_0_Number(0) + + +Register leaf node: SRF_0_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : E.164 number of SRF 0 (Special Resource Function) entity. + +Field : total(1) +Access : read-write[1]SRF 0 number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: SRF_1_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1.2) +-> father_name = [SRF_Number] +-> -> SRF_0_Number(0) +-> -> SRF_1_Number(1) + + +Register leaf node: SRF_1_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : E.164 number of SRF 1 (Special Resource Function) entity. + +Field : total(1) +Access : read-write[1]SRF 1 number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Service_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) +-> -> Service_Number(1) + + +Remark: Service number . + + +Create node: Hotline(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.1) +-> father_name = [Service_Number] +-> -> Hotline(0) + + +Register leaf node: Hotline. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : PPS service center number. Subscriber dials this number to recharge, enquire their account and modify favorite numbers. + +Field : total(1) +Access : read-write[1]Hotline + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Inquiry(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.2) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) + + +Register leaf node: Inquiry. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated PPS number for account (balance and validity) inquiry. + +Field : total(1) +Access : read-write[1]Inquiry number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Scratch_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.3) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) + + +Register leaf node: Scratch_Card_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via scratch card. + +Field : total(1) +Access : read-write[1]Recharge via scratch card + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Credit_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.4) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) + + +Register leaf node: Credit_Card_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via credit card. + +Field : total(1) +Access : read-write[1]Recharge via credit card + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Third_Party_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.5) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) + + +Register leaf node: Third_Party_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharging other account from MS or PSTN. + +Field : total(1) +Access : read-write[1]Recharge other account + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Customer_Care_Center(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.6) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) +-> -> Customer_Care_Center(5) + + +Register leaf node: Customer_Care_Center. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number to connect customer care center. + +Field : total(1) +Access : read-write[1]Customer care center number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Rechareg_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.7) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) +-> -> Customer_Care_Center(5) +-> -> Rechareg_Number(6) + + +Register leaf node: Rechareg_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via scratch card or credit card. + +Field : total(1) +Access : read-write[1]Recharge number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Service_Key(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) +-> -> Service_Number(1) +-> -> Service_Key(2) + + +Remark: Service key . + + +Create node: Inquiry(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.2) +-> father_name = [Service_Key] +-> -> Inquiry(0) + + +Register leaf node: Inquiry. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the function key to enquire account balance after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for inquiry + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Scratch_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.3) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) + + +Register leaf node: Scratch_Card_Recharge. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to recharge account via scratch card after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for recharging via scratch card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Credit_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.4) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) + + +Register leaf node: Credit_Card_Recharge. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key for recharging account via credit card after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for recharging via credit card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Set_Favorite_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.5) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) + + +Register leaf node: Set_Favorite_Number. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to set favorite number after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key to set favorite number + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Language_Selection(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.6) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) +-> -> Language_Selection(4) + + +Register leaf node: Language_Selection. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to select system language (from 5 available candidates) after entering the PPS service center. All announcements in the PPS service center is played in the system language. + +Field : total(1) +Access : read-write[1]Key for language selection + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: SetPasswd(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.7) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) +-> -> Language_Selection(4) +-> -> SetPasswd(5) + + +Register leaf node: SetPasswd. +Instance: 1 +Length : 3 +Flag : 255 +Default :  +Remark : Define the key to set account password after entering the PPS service center. When recharging account] selecting language] modifying favorite number or seting password] subscriber is asked to pass the password verification. + +Field : total(1) +Access : read-write[1]PPS account password + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: File_Operation(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) + + +Remark: File operation . + + +Create node: Import_User_Data(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.1) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) + + +Register leaf node: Import_User_Data. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Read only. Progress and result of PPS subscriber import. +Total number sent: Total quantity of PPS subscribers requesting import. +Records loaded: Quantity of successfully imported PPS subscribers. + +Field : total(3) +Access : read-only [1]Command status + { + [u]0.0-0.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading failed + } +[2]Total number sent + { + [u]1.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Records loaded + { + [u]4.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Import_Recharge_Card(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.2) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) + + +Register leaf node: Import_Recharge_Card. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Read only. Result of uploading recharge card to PPS. 0=unsuccessful. 1=successful. + +Field : total(1) +Access : read-only[1]Import recharge card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: New_Tariff_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.3) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) +-> -> New_Tariff_Flag(2) + + +Register leaf node: New_Tariff_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-only [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: New_Tariff_Start_Time(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.4) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) +-> -> New_Tariff_Flag(2) +-> -> New_Tariff_Start_Time(3) + + +Register leaf node: New_Tariff_Start_Time. +Instance: 1 +Length : 7 +Flag : 255 +Default :  +Remark : Read only. Set start time for new tariff plan. + +Field : total(6) +Access : read-only[1]Year + { + [u]0.0-1.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]3.0-3.7 + [u]input + [v]KeepHex high 0 + } +[4]Hour + { + [u]4.0-4.7 + [u]input + [v]KeepHex high 0 + } +[5]Minute + { + [u]5.0-5.7 + [u]input + [v]KeepHex high 0 + } +[6]Second + { + [u]6.0-6.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: COS_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) + + +Remark: COS parameters . + + +Create node: COS_0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1) +-> father_name = [COS_Param] +-> -> COS_0(0) + + +Remark: COS 0 Parameters. + + +Create node: Recharge_Promotion_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.1) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) + + +Register leaf node: Start_Date_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.2) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) +-> -> End_Date_COS0(1) + + +Register leaf node: End_Date_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.3) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) +-> -> End_Date_COS0(1) +-> -> Promotion_Bonus_COS0(2) + + +Register leaf node: Promotion_Bonus_COS0. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.1) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) + + +Register leaf node: MO_Tariff_ID_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.2) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) + + +Register leaf node: MT_Tariff_ID_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.3) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) +-> -> Tariff_Subscription_COS0(2) + + +Register leaf node: Tariff_Subscription_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.4) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) +-> -> Tariff_Subscription_COS0(2) +-> -> Recharge_Card_Validity_COS0(3) + + +Register leaf node: Recharge_Card_Validity_COS0. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.1) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) + + +Register leaf node: Min_balance_MO_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.2) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) +-> -> Maximum_Validity_COS0(1) + + +Register leaf node: Maximum_Validity_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.3) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) +-> -> Maximum_Validity_COS0(1) +-> -> Release_Day_COS0(2) + + +Register leaf node: Release_Day_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4.1) +-> father_name = [MT_Control_COS0] +-> -> Charge_Flag_COS0(0) + + +Register leaf node: Charge_Flag_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4.2) +-> father_name = [MT_Control_COS0] +-> -> Charge_Flag_COS0(0) +-> -> Zero_Balance_Control_COS0(1) + + +Register leaf node: Zero_Balance_Control_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) +-> -> Validity_Solution_COS0(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.1) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) + + +Register leaf node: Clear_Balance_Option_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.2) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) + + +Register leaf node: Validity_Recharge_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.3) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) + + +Register leaf node: Validity_Zero_Balance_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.4) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) + + +Register leaf node: Activated_Account_Validity_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.5) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) + + +Register leaf node: FF_Number_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.6) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) +-> -> Support_Credit_Card_COS0(5) + + +Register leaf node: Support_Credit_Card_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS0 + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.7) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) +-> -> Support_Credit_Card_COS0(5) +-> -> Credit_Vault_COS0(6) + + +Register leaf node: Credit_Vault_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) +-> -> Validity_Solution_COS0(4) +-> -> SM_Inquiry_COS0(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.1) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) + + +Register leaf node: Feedback_SM_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.2) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) + + +Register leaf node: Inquiry_SM_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.3) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) +-> -> SM_Expiry_COS0(2) + + +Register leaf node: SM_Expiry_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.4) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) +-> -> SM_Expiry_COS0(2) +-> -> SM_Low_Balance_COS0(3) + + +Register leaf node: SM_Low_Balance_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) + + +Remark: COS 1 Parameters. + + +Create node: Recharge_Promotion_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.1) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) + + +Register leaf node: Start_Date_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.2) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) +-> -> End_Date_COS1(1) + + +Register leaf node: End_Date_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.3) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) +-> -> End_Date_COS1(1) +-> -> Promotion_Bonus_COS1(2) + + +Register leaf node: Promotion_Bonus_COS1. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.1) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) + + +Register leaf node: MO_Tariff_ID_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.2) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) + + +Register leaf node: MT_Tariff_ID_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.3) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) +-> -> Tariff_Subscription_COS1(2) + + +Register leaf node: Tariff_Subscription_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.4) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) +-> -> Tariff_Subscription_COS1(2) +-> -> Recharge_Card_Validity_COS1(3) + + +Register leaf node: Recharge_Card_Validity_COS1. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.1) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) + + +Register leaf node: Min_balance_MO_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.2) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) +-> -> Maximum_Validity_COS1(1) + + +Register leaf node: Maximum_Validity_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.3) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) +-> -> Maximum_Validity_COS1(1) +-> -> Release_Day_COS1(2) + + +Register leaf node: Release_Day_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4.1) +-> father_name = [MT_Control_COS1] +-> -> Charge_Flag_COS1(0) + + +Register leaf node: Charge_Flag_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4.2) +-> father_name = [MT_Control_COS1] +-> -> Charge_Flag_COS1(0) +-> -> Zero_Balance_Control_COS1(1) + + +Register leaf node: Zero_Balance_Control_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) +-> -> Validity_Solution_COS1(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.1) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) + + +Register leaf node: Clear_Balance_Option_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.2) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) + + +Register leaf node: Validity_Recharge_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.3) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) + + +Register leaf node: Validity_Zero_Balance_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.4) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) + + +Register leaf node: Activated_Account_Validity_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.5) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) + + +Register leaf node: FF_Number_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.6) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) +-> -> Support_Credit_Card_COS1(5) + + +Register leaf node: Support_Credit_Card_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.7) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) +-> -> Support_Credit_Card_COS1(5) +-> -> Credit_Vault_COS1(6) + + +Register leaf node: Credit_Vault_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) +-> -> Validity_Solution_COS1(4) +-> -> SM_Inquiry_COS1(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.1) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) + + +Register leaf node: Feedback_SM_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.2) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) + + +Register leaf node: Inquiry_SM_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.3) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) +-> -> SM_Expiry_COS1(2) + + +Register leaf node: SM_Expiry_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.4) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) +-> -> SM_Expiry_COS1(2) +-> -> SM_Low_Balance_COS1(3) + + +Register leaf node: SM_Low_Balance_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) + + +Remark: COS 2 Parameters. + + +Create node: Recharge_Promotion_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.1) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) + + +Register leaf node: Start_Date_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.2) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) +-> -> End_Date_COS2(1) + + +Register leaf node: End_Date_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.3) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) +-> -> End_Date_COS2(1) +-> -> Promotion_Bonus_COS2(2) + + +Register leaf node: Promotion_Bonus_COS2. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.1) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) + + +Register leaf node: MO_Tariff_ID_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.2) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) + + +Register leaf node: MT_Tariff_ID_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.3) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) +-> -> Tariff_Subscription_COS2(2) + + +Register leaf node: Tariff_Subscription_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.4) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) +-> -> Tariff_Subscription_COS2(2) +-> -> Recharge_Card_Validity_COS2(3) + + +Register leaf node: Recharge_Card_Validity_COS2. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.1) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) + + +Register leaf node: Min_balance_MO_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.2) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) +-> -> Maximum_Validity_COS2(1) + + +Register leaf node: Maximum_Validity_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.3) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) +-> -> Maximum_Validity_COS2(1) +-> -> Release_Day_COS2(2) + + +Register leaf node: Release_Day_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4.1) +-> father_name = [MT_Control_COS2] +-> -> Charge_Flag_COS2(0) + + +Register leaf node: Charge_Flag_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4.2) +-> father_name = [MT_Control_COS2] +-> -> Charge_Flag_COS2(0) +-> -> Zero_Balance_Control_COS2(1) + + +Register leaf node: Zero_Balance_Control_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) +-> -> Validity_Solution_COS2(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.1) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) + + +Register leaf node: Clear_Balance_Option_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.2) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) + + +Register leaf node: Validity_Recharge_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.3) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) + + +Register leaf node: Validity_Zero_Balance_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.4) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) + + +Register leaf node: Activated_Account_Validity_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.5) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) + + +Register leaf node: FF_Number_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Free times of changing: set total times of free change for family number if charge is enabled. Maximum is 15. + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.6) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) +-> -> Support_Credit_Card_COS2(5) + + +Register leaf node: Support_Credit_Card_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.7) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) +-> -> Support_Credit_Card_COS2(5) +-> -> Credit_Vault_COS2(6) + + +Register leaf node: Credit_Vault_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) +-> -> Validity_Solution_COS2(4) +-> -> SM_Inquiry_COS2(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.1) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) + + +Register leaf node: Feedback_SM_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.2) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) + + +Register leaf node: Inquiry_SM_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.3) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) +-> -> SM_Expiry_COS2(2) + + +Register leaf node: SM_Expiry_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.4) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) +-> -> SM_Expiry_COS2(2) +-> -> SM_Low_Balance_COS2(3) + + +Register leaf node: SM_Low_Balance_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) + + +Remark: COS 3 Parameters. + + +Create node: Recharge_Promotion_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.1) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) + + +Register leaf node: Start_Date_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.2) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) +-> -> End_Date_COS3(1) + + +Register leaf node: End_Date_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.3) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) +-> -> End_Date_COS3(1) +-> -> Promotion_Bonus_COS3(2) + + +Register leaf node: Promotion_Bonus_COS3. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.1) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) + + +Register leaf node: MO_Tariff_ID_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.2) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) + + +Register leaf node: MT_Tariff_ID_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.3) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) +-> -> Tariff_Subscription_COS3(2) + + +Register leaf node: Tariff_Subscription_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.4) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) +-> -> Tariff_Subscription_COS3(2) +-> -> Recharge_Card_Validity_COS3(3) + + +Register leaf node: Recharge_Card_Validity_COS3. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.1) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) + + +Register leaf node: Min_balance_MO_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.2) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) +-> -> Maximum_Validity_COS3(1) + + +Register leaf node: Maximum_Validity_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.3) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) +-> -> Maximum_Validity_COS3(1) +-> -> Release_Day_COS3(2) + + +Register leaf node: Release_Day_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4.1) +-> father_name = [MT_Control_COS3] +-> -> Charge_Flag_COS3(0) + + +Register leaf node: Charge_Flag_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4.2) +-> father_name = [MT_Control_COS3] +-> -> Charge_Flag_COS3(0) +-> -> Zero_Balance_Control_COS3(1) + + +Register leaf node: Zero_Balance_Control_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) +-> -> Validity_Solution_COS3(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.1) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) + + +Register leaf node: Clear_Balance_Option_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.2) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) + + +Register leaf node: Validity_Recharge_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.3) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) + + +Register leaf node: Validity_Zero_Balance_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.4) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) + + +Register leaf node: Activated_Account_Validity_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.5) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) + + +Register leaf node: FF_Number_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.6) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) +-> -> Support_Credit_Card_COS3(5) + + +Register leaf node: Support_Credit_Card_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.7) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) +-> -> Support_Credit_Card_COS3(5) +-> -> Credit_Vault_COS3(6) + + +Register leaf node: Credit_Vault_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) +-> -> Validity_Solution_COS3(4) +-> -> SM_Inquiry_COS3(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.1) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) + + +Register leaf node: Feedback_SM_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.2) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) + + +Register leaf node: Inquiry_SM_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.3) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) +-> -> SM_Expiry_COS3(2) + + +Register leaf node: SM_Expiry_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.4) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) +-> -> SM_Expiry_COS3(2) +-> -> SM_Low_Balance_COS3(3) + + +Register leaf node: SM_Low_Balance_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) + + +Remark: COS 4 Parameters. + + +Create node: Recharge_Promotion_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.1) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) + + +Register leaf node: Start_Date_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.2) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) +-> -> End_Date_COS4(1) + + +Register leaf node: End_Date_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.3) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) +-> -> End_Date_COS4(1) +-> -> Promotion_Bonus_COS4(2) + + +Register leaf node: Promotion_Bonus_COS4. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.1) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) + + +Register leaf node: MO_Tariff_ID_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.2) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) + + +Register leaf node: MT_Tariff_ID_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.3) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) +-> -> Tariff_Subscription_COS4(2) + + +Register leaf node: Tariff_Subscription_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.4) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) +-> -> Tariff_Subscription_COS4(2) +-> -> Recharge_Card_Validity_COS4(3) + + +Register leaf node: Recharge_Card_Validity_COS4. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.1) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) + + +Register leaf node: Min_balance_MO_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.2) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) +-> -> Maximum_Validity_COS4(1) + + +Register leaf node: Maximum_Validity_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.3) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) +-> -> Maximum_Validity_COS4(1) +-> -> Release_Day_COS4(2) + + +Register leaf node: Release_Day_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4.1) +-> father_name = [MT_Control_COS4] +-> -> Charge_Flag_COS4(0) + + +Register leaf node: Charge_Flag_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4.2) +-> father_name = [MT_Control_COS4] +-> -> Charge_Flag_COS4(0) +-> -> Zero_Balance_Control_COS4(1) + + +Register leaf node: Zero_Balance_Control_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) +-> -> Validity_Solution_COS4(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.1) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) + + +Register leaf node: Clear_Balance_Option_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.2) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) + + +Register leaf node: Validity_Recharge_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.3) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) + + +Register leaf node: Validity_Zero_Balance_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.4) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) + + +Register leaf node: Activated_Account_Validity_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.5) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) + + +Register leaf node: FF_Number_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.6) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) +-> -> Support_Credit_Card_COS4(5) + + +Register leaf node: Support_Credit_Card_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.7) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) +-> -> Support_Credit_Card_COS4(5) +-> -> Credit_Vault_COS4(6) + + +Register leaf node: Credit_Vault_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) +-> -> Validity_Solution_COS4(4) +-> -> SM_Inquiry_COS4(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.1) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) + + +Register leaf node: Feedback_SM_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.2) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) + + +Register leaf node: Inquiry_SM_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.3) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) +-> -> SM_Expiry_COS4(2) + + +Register leaf node: SM_Expiry_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.4) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) +-> -> SM_Expiry_COS4(2) +-> -> SM_Low_Balance_COS4(3) + + +Register leaf node: SM_Low_Balance_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) + + +Remark: COS 5 Parameters. + + +Create node: Recharge_Promotion_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.1) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) + + +Register leaf node: Start_Date_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.2) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) +-> -> End_Date_COS5(1) + + +Register leaf node: End_Date_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.3) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) +-> -> End_Date_COS5(1) +-> -> Promotion_Bonus_COS5(2) + + +Register leaf node: Promotion_Bonus_COS5. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.1) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) + + +Register leaf node: MO_Tariff_ID_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.2) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) + + +Register leaf node: MT_Tariff_ID_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.3) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) +-> -> Tariff_Subscription_COS5(2) + + +Register leaf node: Tariff_Subscription_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.4) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) +-> -> Tariff_Subscription_COS5(2) +-> -> Recharge_Card_Validity_COS5(3) + + +Register leaf node: Recharge_Card_Validity_COS5. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.1) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) + + +Register leaf node: Min_balance_MO_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.2) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) +-> -> Maximum_Validity_COS5(1) + + +Register leaf node: Maximum_Validity_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.3) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) +-> -> Maximum_Validity_COS5(1) +-> -> Release_Day_COS5(2) + + +Register leaf node: Release_Day_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4.1) +-> father_name = [MT_Control_COS5] +-> -> Charge_Flag_COS5(0) + + +Register leaf node: Charge_Flag_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4.2) +-> father_name = [MT_Control_COS5] +-> -> Charge_Flag_COS5(0) +-> -> Zero_Balance_Control_COS5(1) + + +Register leaf node: Zero_Balance_Control_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) +-> -> Validity_Solution_COS5(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.1) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) + + +Register leaf node: Clear_Balance_Option_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.2) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) + + +Register leaf node: Validity_Recharge_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.3) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) + + +Register leaf node: Validity_Zero_Balance_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.4) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) + + +Register leaf node: Activated_Account_Validity_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.5) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) + + +Register leaf node: FF_Number_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.6) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) +-> -> Support_Credit_Card_COS5(5) + + +Register leaf node: Support_Credit_Card_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.7) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) +-> -> Support_Credit_Card_COS5(5) +-> -> Credit_Vault_COS5(6) + + +Register leaf node: Credit_Vault_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) +-> -> Validity_Solution_COS5(4) +-> -> SM_Inquiry_COS5(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.1) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) + + +Register leaf node: Feedback_SM_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.2) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) + + +Register leaf node: Inquiry_SM_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.3) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) +-> -> SM_Expiry_COS5(2) + + +Register leaf node: SM_Expiry_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.4) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) +-> -> SM_Expiry_COS5(2) +-> -> SM_Low_Balance_COS5(3) + + +Register leaf node: SM_Low_Balance_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) + + +Remark: COS 6 Parameters. + + +Create node: Recharge_Promotion_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.1) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) + + +Register leaf node: Start_Date_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.2) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) +-> -> End_Date_COS6(1) + + +Register leaf node: End_Date_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.3) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) +-> -> End_Date_COS6(1) +-> -> Promotion_Bonus_COS6(2) + + +Register leaf node: Promotion_Bonus_COS6. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.1) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) + + +Register leaf node: MO_Tariff_ID_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.2) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) + + +Register leaf node: MT_Tariff_ID_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.3) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) +-> -> Tariff_Subscription_COS6(2) + + +Register leaf node: Tariff_Subscription_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.4) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) +-> -> Tariff_Subscription_COS6(2) +-> -> Recharge_Card_Validity_COS6(3) + + +Register leaf node: Recharge_Card_Validity_COS6. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.1) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) + + +Register leaf node: Min_balance_MO_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.2) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) +-> -> Maximum_Validity_COS6(1) + + +Register leaf node: Maximum_Validity_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.3) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) +-> -> Maximum_Validity_COS6(1) +-> -> Release_Day_COS6(2) + + +Register leaf node: Release_Day_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4.1) +-> father_name = [MT_Control_COS6] +-> -> Charge_Flag_COS6(0) + + +Register leaf node: Charge_Flag_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4.2) +-> father_name = [MT_Control_COS6] +-> -> Charge_Flag_COS6(0) +-> -> Zero_Balance_Control_COS6(1) + + +Register leaf node: Zero_Balance_Control_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) +-> -> Validity_Solution_COS6(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.1) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) + + +Register leaf node: Clear_Balance_Option_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.2) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) + + +Register leaf node: Validity_Recharge_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.3) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) + + +Register leaf node: Validity_Zero_Balance_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.4) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) + + +Register leaf node: Activated_Account_Validity_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.5) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) + + +Register leaf node: FF_Number_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.6) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) +-> -> Support_Credit_Card_COS6(5) + + +Register leaf node: Support_Credit_Card_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.7) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) +-> -> Support_Credit_Card_COS6(5) +-> -> Credit_Vault_COS6(6) + + +Register leaf node: Credit_Vault_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) +-> -> Validity_Solution_COS6(4) +-> -> SM_Inquiry_COS6(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.1) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) + + +Register leaf node: Feedback_SM_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.2) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) + + +Register leaf node: Inquiry_SM_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.3) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) +-> -> SM_Expiry_COS6(2) + + +Register leaf node: SM_Expiry_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.4) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) +-> -> SM_Expiry_COS6(2) +-> -> SM_Low_Balance_COS6(3) + + +Register leaf node: SM_Low_Balance_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) + + +Remark: COS 7 Parameters. + + +Create node: Recharge_Promotion_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.1) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) + + +Register leaf node: Start_Date_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.2) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) +-> -> End_Date_COS7(1) + + +Register leaf node: End_Date_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.3) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) +-> -> End_Date_COS7(1) +-> -> Promotion_Bonus_COS7(2) + + +Register leaf node: Promotion_Bonus_COS7. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.1) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) + + +Register leaf node: MO_Tariff_ID_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.2) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) + + +Register leaf node: MT_Tariff_ID_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.3) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) +-> -> Tariff_Subscription_COS7(2) + + +Register leaf node: Tariff_Subscription_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.4) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) +-> -> Tariff_Subscription_COS7(2) +-> -> Recharge_Card_Validity_COS7(3) + + +Register leaf node: Recharge_Card_Validity_COS7. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.1) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) + + +Register leaf node: Min_balance_MO_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.2) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) +-> -> Maximum_Validity_COS7(1) + + +Register leaf node: Maximum_Validity_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.3) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) +-> -> Maximum_Validity_COS7(1) +-> -> Release_Day_COS7(2) + + +Register leaf node: Release_Day_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4.1) +-> father_name = [MT_Control_COS7] +-> -> Charge_Flag_COS7(0) + + +Register leaf node: Charge_Flag_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4.2) +-> father_name = [MT_Control_COS7] +-> -> Charge_Flag_COS7(0) +-> -> Zero_Balance_Control_COS7(1) + + +Register leaf node: Zero_Balance_Control_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) +-> -> Validity_Solution_COS7(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.1) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) + + +Register leaf node: Clear_Balance_Option_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.2) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) + + +Register leaf node: Validity_Recharge_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.3) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) + + +Register leaf node: Validity_Zero_Balance_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.4) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) + + +Register leaf node: Activated_Account_Validity_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.5) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) + + +Register leaf node: FF_Number_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.6) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) +-> -> Support_Credit_Card_COS7(5) + + +Register leaf node: Support_Credit_Card_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.7) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) +-> -> Support_Credit_Card_COS7(5) +-> -> Credit_Vault_COS7(6) + + +Register leaf node: Credit_Vault_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) +-> -> Validity_Solution_COS7(4) +-> -> SM_Inquiry_COS7(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.1) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) + + +Register leaf node: Feedback_SM_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.2) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) + + +Register leaf node: Inquiry_SM_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.3) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) +-> -> SM_Expiry_COS7(2) + + +Register leaf node: SM_Expiry_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.4) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) +-> -> SM_Expiry_COS7(2) +-> -> SM_Low_Balance_COS7(3) + + +Register leaf node: SM_Low_Balance_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) + + +Remark: COS 8 Parameters. + + +Create node: Recharge_Promotion_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.1) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) + + +Register leaf node: Start_Date_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.2) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) +-> -> End_Date_COS8(1) + + +Register leaf node: End_Date_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.3) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) +-> -> End_Date_COS8(1) +-> -> Promotion_Bonus_COS8(2) + + +Register leaf node: Promotion_Bonus_COS8. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.1) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) + + +Register leaf node: MO_Tariff_ID_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.2) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) + + +Register leaf node: MT_Tariff_ID_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.3) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) +-> -> Tariff_Subscription_COS8(2) + + +Register leaf node: Tariff_Subscription_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.4) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) +-> -> Tariff_Subscription_COS8(2) +-> -> Recharge_Card_Validity_COS8(3) + + +Register leaf node: Recharge_Card_Validity_COS8. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.1) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) + + +Register leaf node: Min_balance_MO_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.2) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) +-> -> Maximum_Validity_COS8(1) + + +Register leaf node: Maximum_Validity_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.3) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) +-> -> Maximum_Validity_COS8(1) +-> -> Release_Day_COS8(2) + + +Register leaf node: Release_Day_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4.1) +-> father_name = [MT_Control_COS8] +-> -> Charge_Flag_COS8(0) + + +Register leaf node: Charge_Flag_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4.2) +-> father_name = [MT_Control_COS8] +-> -> Charge_Flag_COS8(0) +-> -> Zero_Balance_Control_COS8(1) + + +Register leaf node: Zero_Balance_Control_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) +-> -> Validity_Solution_COS8(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.1) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) + + +Register leaf node: Clear_Balance_Option_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.2) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) + + +Register leaf node: Validity_Recharge_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.3) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) + + +Register leaf node: Validity_Zero_Balance_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.4) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) + + +Register leaf node: Activated_Account_Validity_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.5) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) + + +Register leaf node: FF_Number_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.6) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) +-> -> Support_Credit_Card_COS8(5) + + +Register leaf node: Support_Credit_Card_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.7) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) +-> -> Support_Credit_Card_COS8(5) +-> -> Credit_Vault_COS8(6) + + +Register leaf node: Credit_Vault_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) +-> -> Validity_Solution_COS8(4) +-> -> SM_Inquiry_COS8(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.1) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) + + +Register leaf node: Feedback_SM_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.2) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) + + +Register leaf node: Inquiry_SM_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.3) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) +-> -> SM_Expiry_COS8(2) + + +Register leaf node: SM_Expiry_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.4) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) +-> -> SM_Expiry_COS8(2) +-> -> SM_Low_Balance_COS8(3) + + +Register leaf node: SM_Low_Balance_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) + + +Remark: COS 9 Parameters. + + +Create node: Recharge_Promotion_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.1) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) + + +Register leaf node: Start_Date_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.2) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) +-> -> End_Date_COS9(1) + + +Register leaf node: End_Date_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.3) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) +-> -> End_Date_COS9(1) +-> -> Promotion_Bonus_COS9(2) + + +Register leaf node: Promotion_Bonus_COS9. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.1) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) + + +Register leaf node: MO_Tariff_ID_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.2) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) + + +Register leaf node: MT_Tariff_ID_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.3) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) +-> -> Tariff_Subscription_COS9(2) + + +Register leaf node: Tariff_Subscription_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.4) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) +-> -> Tariff_Subscription_COS9(2) +-> -> Recharge_Card_Validity_COS9(3) + + +Register leaf node: Recharge_Card_Validity_COS9. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.1) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) + + +Register leaf node: Min_balance_MO_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.2) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) +-> -> Maximum_Validity_COS9(1) + + +Register leaf node: Maximum_Validity_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.3) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) +-> -> Maximum_Validity_COS9(1) +-> -> Release_Day_COS9(2) + + +Register leaf node: Release_Day_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4.1) +-> father_name = [MT_Control_COS9] +-> -> Charge_Flag_COS9(0) + + +Register leaf node: Charge_Flag_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4.2) +-> father_name = [MT_Control_COS9] +-> -> Charge_Flag_COS9(0) +-> -> Zero_Balance_Control_COS9(1) + + +Register leaf node: Zero_Balance_Control_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) +-> -> Validity_Solution_COS9(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.1) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) + + +Register leaf node: Clear_Balance_Option_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.2) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) + + +Register leaf node: Validity_Recharge_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.3) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) + + +Register leaf node: Validity_Zero_Balance_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.4) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) + + +Register leaf node: Activated_Account_Validity_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.5) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) + + +Register leaf node: FF_Number_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.6) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) +-> -> Support_Credit_Card_COS9(5) + + +Register leaf node: Support_Credit_Card_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.7) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) +-> -> Support_Credit_Card_COS9(5) +-> -> Credit_Vault_COS9(6) + + +Register leaf node: Credit_Vault_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) +-> -> Validity_Solution_COS9(4) +-> -> SM_Inquiry_COS9(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.1) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) + + +Register leaf node: Feedback_SM_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.2) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) + + +Register leaf node: Inquiry_SM_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.3) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) +-> -> SM_Expiry_COS9(2) + + +Register leaf node: SM_Expiry_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.4) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) +-> -> SM_Expiry_COS9(2) +-> -> SM_Low_Balance_COS9(3) + + +Register leaf node: SM_Low_Balance_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) + + +Remark: COS 10 Parameters. + + +Create node: Recharge_Promotion_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.1) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) + + +Register leaf node: Start_Date_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.2) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) +-> -> End_Date_COS10(1) + + +Register leaf node: End_Date_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.3) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) +-> -> End_Date_COS10(1) +-> -> Promotion_Bonus_COS10(2) + + +Register leaf node: Promotion_Bonus_COS10. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.1) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) + + +Register leaf node: MO_Tariff_ID_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.2) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) + + +Register leaf node: MT_Tariff_ID_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.3) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) +-> -> Tariff_Subscription_COS10(2) + + +Register leaf node: Tariff_Subscription_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.4) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) +-> -> Tariff_Subscription_COS10(2) +-> -> Recharge_Card_Validity_COS10(3) + + +Register leaf node: Recharge_Card_Validity_COS10. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.1) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) + + +Register leaf node: Min_balance_MO_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.2) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) +-> -> Maximum_Validity_COS10(1) + + +Register leaf node: Maximum_Validity_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.3) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) +-> -> Maximum_Validity_COS10(1) +-> -> Release_Day_COS10(2) + + +Register leaf node: Release_Day_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4.1) +-> father_name = [MT_Control_COS10] +-> -> Charge_Flag_COS10(0) + + +Register leaf node: Charge_Flag_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4.2) +-> father_name = [MT_Control_COS10] +-> -> Charge_Flag_COS10(0) +-> -> Zero_Balance_Control_COS10(1) + + +Register leaf node: Zero_Balance_Control_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) +-> -> Validity_Solution_COS10(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.1) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) + + +Register leaf node: Clear_Balance_Option_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.2) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) + + +Register leaf node: Validity_Recharge_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.3) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) + + +Register leaf node: Validity_Zero_Balance_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.4) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) + + +Register leaf node: Activated_Account_Validity_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.5) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) + + +Register leaf node: FF_Number_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.6) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) +-> -> Support_Credit_Card_COS10(5) + + +Register leaf node: Support_Credit_Card_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.7) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) +-> -> Support_Credit_Card_COS10(5) +-> -> Credit_Vault_COS10(6) + + +Register leaf node: Credit_Vault_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) +-> -> Validity_Solution_COS10(4) +-> -> SM_Inquiry_COS10(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.1) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) + + +Register leaf node: Feedback_SM_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.2) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) + + +Register leaf node: Inquiry_SM_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.3) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) +-> -> SM_Expiry_COS10(2) + + +Register leaf node: SM_Expiry_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.4) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) +-> -> SM_Expiry_COS10(2) +-> -> SM_Low_Balance_COS10(3) + + +Register leaf node: SM_Low_Balance_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) + + +Remark: COS 11 Parameters. + + +Create node: Recharge_Promotion_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.1) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) + + +Register leaf node: Start_Date_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.2) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) +-> -> End_Date_COS11(1) + + +Register leaf node: End_Date_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.3) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) +-> -> End_Date_COS11(1) +-> -> Promotion_Bonus_COS11(2) + + +Register leaf node: Promotion_Bonus_COS11. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.1) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) + + +Register leaf node: MO_Tariff_ID_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.2) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) + + +Register leaf node: MT_Tariff_ID_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.3) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) +-> -> Tariff_Subscription_COS11(2) + + +Register leaf node: Tariff_Subscription_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.4) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) +-> -> Tariff_Subscription_COS11(2) +-> -> Recharge_Card_Validity_COS11(3) + + +Register leaf node: Recharge_Card_Validity_COS11. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.1) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) + + +Register leaf node: Min_balance_MO_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.2) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) +-> -> Maximum_Validity_COS11(1) + + +Register leaf node: Maximum_Validity_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.3) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) +-> -> Maximum_Validity_COS11(1) +-> -> Release_Day_COS11(2) + + +Register leaf node: Release_Day_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4.1) +-> father_name = [MT_Control_COS11] +-> -> Charge_Flag_COS11(0) + + +Register leaf node: Charge_Flag_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4.2) +-> father_name = [MT_Control_COS11] +-> -> Charge_Flag_COS11(0) +-> -> Zero_Balance_Control_COS11(1) + + +Register leaf node: Zero_Balance_Control_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) +-> -> Validity_Solution_COS11(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.1) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) + + +Register leaf node: Clear_Balance_Option_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.2) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) + + +Register leaf node: Validity_Recharge_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.3) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) + + +Register leaf node: Validity_Zero_Balance_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.4) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) + + +Register leaf node: Activated_Account_Validity_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.5) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) + + +Register leaf node: FF_Number_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.6) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) +-> -> Support_Credit_Card_COS11(5) + + +Register leaf node: Support_Credit_Card_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.7) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) +-> -> Support_Credit_Card_COS11(5) +-> -> Credit_Vault_COS11(6) + + +Register leaf node: Credit_Vault_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) +-> -> Validity_Solution_COS11(4) +-> -> SM_Inquiry_COS11(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.1) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) + + +Register leaf node: Feedback_SM_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.2) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) + + +Register leaf node: Inquiry_SM_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.3) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) +-> -> SM_Expiry_COS11(2) + + +Register leaf node: SM_Expiry_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.4) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) +-> -> SM_Expiry_COS11(2) +-> -> SM_Low_Balance_COS11(3) + + +Register leaf node: SM_Low_Balance_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) + + +Remark: COS 12 Parameters. + + +Create node: Recharge_Promotion_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.1) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) + + +Register leaf node: Start_Date_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.2) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) +-> -> End_Date_COS12(1) + + +Register leaf node: End_Date_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.3) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) +-> -> End_Date_COS12(1) +-> -> Promotion_Bonus_COS12(2) + + +Register leaf node: Promotion_Bonus_COS12. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.1) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) + + +Register leaf node: MO_Tariff_ID_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.2) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) + + +Register leaf node: MT_Tariff_ID_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.3) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) +-> -> Tariff_Subscription_COS12(2) + + +Register leaf node: Tariff_Subscription_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.4) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) +-> -> Tariff_Subscription_COS12(2) +-> -> Recharge_Card_Validity_COS12(3) + + +Register leaf node: Recharge_Card_Validity_COS12. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.1) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) + + +Register leaf node: Min_balance_MO_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.2) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) +-> -> Maximum_Validity_COS12(1) + + +Register leaf node: Maximum_Validity_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.3) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) +-> -> Maximum_Validity_COS12(1) +-> -> Release_Day_COS12(2) + + +Register leaf node: Release_Day_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4.1) +-> father_name = [MT_Control_COS12] +-> -> Charge_Flag_COS12(0) + + +Register leaf node: Charge_Flag_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4.2) +-> father_name = [MT_Control_COS12] +-> -> Charge_Flag_COS12(0) +-> -> Zero_Balance_Control_COS12(1) + + +Register leaf node: Zero_Balance_Control_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) +-> -> Validity_Solution_COS12(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.1) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) + + +Register leaf node: Clear_Balance_Option_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.2) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) + + +Register leaf node: Validity_Recharge_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.3) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) + + +Register leaf node: Validity_Zero_Balance_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.4) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) + + +Register leaf node: Activated_Account_Validity_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.5) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) + + +Register leaf node: FF_Number_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.6) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) +-> -> Support_Credit_Card_COS12(5) + + +Register leaf node: Support_Credit_Card_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.7) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) +-> -> Support_Credit_Card_COS12(5) +-> -> Credit_Vault_COS12(6) + + +Register leaf node: Credit_Vault_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) +-> -> Validity_Solution_COS12(4) +-> -> SM_Inquiry_COS12(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.1) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) + + +Register leaf node: Feedback_SM_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.2) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) + + +Register leaf node: Inquiry_SM_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.3) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) +-> -> SM_Expiry_COS12(2) + + +Register leaf node: SM_Expiry_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.4) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) +-> -> SM_Expiry_COS12(2) +-> -> SM_Low_Balance_COS12(3) + + +Register leaf node: SM_Low_Balance_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) + + +Remark: COS 13 Parameters. + + +Create node: Recharge_Promotion_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.1) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) + + +Register leaf node: Start_Date_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.2) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) +-> -> End_Date_COS13(1) + + +Register leaf node: End_Date_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.3) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) +-> -> End_Date_COS13(1) +-> -> Promotion_Bonus_COS13(2) + + +Register leaf node: Promotion_Bonus_COS13. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.1) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) + + +Register leaf node: MO_Tariff_ID_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.2) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) + + +Register leaf node: MT_Tariff_ID_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.3) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) +-> -> Tariff_Subscription_COS13(2) + + +Register leaf node: Tariff_Subscription_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.4) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) +-> -> Tariff_Subscription_COS13(2) +-> -> Recharge_Card_Validity_COS13(3) + + +Register leaf node: Recharge_Card_Validity_COS13. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.1) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) + + +Register leaf node: Min_balance_MO_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.2) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) +-> -> Maximum_Validity_COS13(1) + + +Register leaf node: Maximum_Validity_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.3) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) +-> -> Maximum_Validity_COS13(1) +-> -> Release_Day_COS13(2) + + +Register leaf node: Release_Day_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4.1) +-> father_name = [MT_Control_COS13] +-> -> Charge_Flag_COS13(0) + + +Register leaf node: Charge_Flag_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4.2) +-> father_name = [MT_Control_COS13] +-> -> Charge_Flag_COS13(0) +-> -> Zero_Balance_Control_COS13(1) + + +Register leaf node: Zero_Balance_Control_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) +-> -> Validity_Solution_COS13(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.1) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) + + +Register leaf node: Clear_Balance_Option_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.2) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) + + +Register leaf node: Validity_Recharge_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.3) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) + + +Register leaf node: Validity_Zero_Balance_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.4) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) + + +Register leaf node: Activated_Account_Validity_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.5) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) + + +Register leaf node: FF_Number_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.6) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) +-> -> Support_Credit_Card_COS13(5) + + +Register leaf node: Support_Credit_Card_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.7) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) +-> -> Support_Credit_Card_COS13(5) +-> -> Credit_Vault_COS13(6) + + +Register leaf node: Credit_Vault_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) +-> -> Validity_Solution_COS13(4) +-> -> SM_Inquiry_COS13(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.1) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) + + +Register leaf node: Feedback_SM_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.2) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) + + +Register leaf node: Inquiry_SM_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.3) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) +-> -> SM_Expiry_COS13(2) + + +Register leaf node: SM_Expiry_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.4) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) +-> -> SM_Expiry_COS13(2) +-> -> SM_Low_Balance_COS13(3) + + +Register leaf node: SM_Low_Balance_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) +-> -> COS_14(14) + + +Remark: COS 14 Parameters. + + +Create node: Recharge_Promotion_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.1) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) + + +Register leaf node: Start_Date_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.2) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) +-> -> End_Date_COS14(1) + + +Register leaf node: End_Date_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.3) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) +-> -> End_Date_COS14(1) +-> -> Promotion_Bonus_COS14(2) + + +Register leaf node: Promotion_Bonus_COS14. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.1) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) + + +Register leaf node: MO_Tariff_ID_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.2) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) + + +Register leaf node: MT_Tariff_ID_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.3) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) +-> -> Tariff_Subscription_COS14(2) + + +Register leaf node: Tariff_Subscription_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.4) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) +-> -> Tariff_Subscription_COS14(2) +-> -> Recharge_Card_Validity_COS14(3) + + +Register leaf node: Recharge_Card_Validity_COS14. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.1) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) + + +Register leaf node: Min_balance_MO_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.2) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) +-> -> Maximum_Validity_COS14(1) + + +Register leaf node: Maximum_Validity_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.3) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) +-> -> Maximum_Validity_COS14(1) +-> -> Release_Day_COS14(2) + + +Register leaf node: Release_Day_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4.1) +-> father_name = [MT_Control_COS14] +-> -> Charge_Flag_COS14(0) + + +Register leaf node: Charge_Flag_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4.2) +-> father_name = [MT_Control_COS14] +-> -> Charge_Flag_COS14(0) +-> -> Zero_Balance_Control_COS14(1) + + +Register leaf node: Zero_Balance_Control_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) +-> -> Validity_Solution_COS14(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.1) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) + + +Register leaf node: Clear_Balance_Option_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.2) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) + + +Register leaf node: Validity_Recharge_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.3) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) + + +Register leaf node: Validity_Zero_Balance_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.4) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) + + +Register leaf node: Activated_Account_Validity_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.5) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) + + +Register leaf node: FF_Number_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.6) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) +-> -> Support_Credit_Card_COS14(5) + + +Register leaf node: Support_Credit_Card_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.7) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) +-> -> Support_Credit_Card_COS14(5) +-> -> Credit_Vault_COS14(6) + + +Register leaf node: Credit_Vault_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) +-> -> Validity_Solution_COS14(4) +-> -> SM_Inquiry_COS14(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.1) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) + + +Register leaf node: Feedback_SM_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.2) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) + + +Register leaf node: Inquiry_SM_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.3) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) +-> -> SM_Expiry_COS14(2) + + +Register leaf node: SM_Expiry_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.4) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) +-> -> SM_Expiry_COS14(2) +-> -> SM_Low_Balance_COS14(3) + + +Register leaf node: SM_Low_Balance_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) +-> -> COS_14(14) +-> -> COS_15(15) + + +Remark: COS 15 Parameters. + + +Create node: Recharge_Promotion_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.1) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) + + +Register leaf node: Start_Date_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.2) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) +-> -> End_Date_COS15(1) + + +Register leaf node: End_Date_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.3) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) +-> -> End_Date_COS15(1) +-> -> Promotion_Bonus_COS15(2) + + +Register leaf node: Promotion_Bonus_COS15. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.1) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) + + +Register leaf node: MO_Tariff_ID_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.2) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) + + +Register leaf node: MT_Tariff_ID_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.3) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) +-> -> Tariff_Subscription_COS15(2) + + +Register leaf node: Tariff_Subscription_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.4) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) +-> -> Tariff_Subscription_COS15(2) +-> -> Recharge_Card_Validity_COS15(3) + + +Register leaf node: Recharge_Card_Validity_COS15. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.1) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) + + +Register leaf node: Min_balance_MO_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.2) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) +-> -> Maximum_Validity_COS15(1) + + +Register leaf node: Maximum_Validity_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.3) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) +-> -> Maximum_Validity_COS15(1) +-> -> Release_Day_COS15(2) + + +Register leaf node: Release_Day_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4.1) +-> father_name = [MT_Control_COS15] +-> -> Charge_Flag_COS15(0) + + +Register leaf node: Charge_Flag_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4.2) +-> father_name = [MT_Control_COS15] +-> -> Charge_Flag_COS15(0) +-> -> Zero_Balance_Control_COS15(1) + + +Register leaf node: Zero_Balance_Control_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) +-> -> Validity_Solution_COS15(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.1) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) + + +Register leaf node: Clear_Balance_Option_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.2) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) + + +Register leaf node: Validity_Recharge_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.3) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) + + +Register leaf node: Validity_Zero_Balance_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.4) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) + + +Register leaf node: Activated_Account_Validity_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.5) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) + + +Register leaf node: FF_Number_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.6) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) +-> -> Support_Credit_Card_COS15(5) + + +Register leaf node: Support_Credit_Card_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.7) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) +-> -> Support_Credit_Card_COS15(5) +-> -> Credit_Vault_COS15(6) + + +Register leaf node: Credit_Vault_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) +-> -> Validity_Solution_COS15(4) +-> -> SM_Inquiry_COS15(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.1) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) + + +Register leaf node: Feedback_SM_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.2) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) + + +Register leaf node: Inquiry_SM_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.3) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) +-> -> SM_Expiry_COS15(2) + + +Register leaf node: SM_Expiry_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.4) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) +-> -> SM_Expiry_COS15(2) +-> -> SM_Low_Balance_COS15(3) + + +Register leaf node: SM_Low_Balance_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Call_Routing_VMS(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) +-> -> Call_Routing_VMS(4) + + +Remark: Call routing to VMS . + + +Create node: VMS_PLMN_Maintenance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.1) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) + + +Register leaf node: VMS_PLMN_Maintenance. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS service number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: VMS_PSTN_Maintenance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.2) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) + + +Register leaf node: VMS_PSTN_Maintenance. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS service number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: VMS_leave_msg_No(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.3) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) + + +Register leaf node: VMS_leave_msg_No. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS deposit number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Rule(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.4) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) +-> -> Rule(3) + + +Register leaf node: Rule. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : rule + +Field : total(3) +Access : read-only [1]Route by + { + [u]0.0-0.0 + [u]select + [v]0[opt]Prefix + [v]1[opt]Whole number + } + [2]Route + { + [u]0.1-0.1 + [u]select + [v]0[opt]Caller number + [v]1[opt]Called number + } + + +Create node: VMS_User_Segments(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.5) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) +-> -> Rule(3) +-> -> VMS_User_Segments(4) + + +Register leaf node: VMS_User_Segments. +Instance: 128 +Length : 80 +Flag : 255 +Default : 86755900000 +Remark : VMS user segments + +Field : total(5) +Access : read-only[1]Start MSISDN + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } +[2]End MSISDN + { + [u]16.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[3]VMS service number - PLMN + { + [u]32.0-47.7 + [u]input + [v]ToAscii Low 0 + } +[4]VMS service number - PSTN + { + [u]48.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[5]Leave message deposit number + { + [u]64.0-79.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) +-> -> Call_Routing_VMS(4) +-> -> Status(5) + + +Remark: Status. + + +Create node: Activation(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.1) +-> father_name = [Status] +-> -> Activation(0) + + +Register leaf node: Activation. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set PPS system status. 0=normal. After initial PPS installation, if the PPS system doesn't has subscriber profiles, its status is suspended. In this case operator may set this parameter (normal) to activate the PPS server. + +Field : total(1) +Access : read-only [1]System status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Normal + } + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.2) +-> father_name = [Status] +-> -> Activation(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS management command. +Save parameters: Save PPS parameters in PPS memory to PPS hard disk. +Save user data: Save PPS subscriber data in PPS memory to PPS hard disk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + [v]2[opt]Save user data + } + + +Create node: MSS(OID: 1.3.6.1.4.1.1373.1.3.3.16) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) +-> -> PPS(4) +-> -> MSS(5) + + +Remark: Subsystems for MSS . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.16.2) +-> father_name = [MSS] +-> -> Configuration(0) + + +Remark: Configuration for MSS . + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.16.2.1) +-> father_name = [Configuration] +-> -> Management(0) + + +Remark: Management for MSS . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.16.2.1.1) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Safely shut down MSS server by stoping MSS process, saving subscriber data to harddisk and shut down the server. +Operation procedures: +1. Select -Shutdown- at above pulldown menu. +2. Click -Set- button in this set window. +3. Click -SET- button on operation page. + +Field : total(1) +Access : write-only [1]Command + { + [u]0.0-0.7 + [u]select + [v]4[opt]Shutdown + [v]5[opt]Undefine value + } + + + + + +SubSystem Module +Index:0 OID: 1.3.6.1.4.1.1373.1.3.2.2.2. name:MTP3 MaxGroup:3 +Index:1 OID: 1.3.6.1.4.1.1373.1.3.2.2.3. name:SCCP MaxGroup:1 +Index:2 OID: 1.3.6.1.4.1.1373.1.3.2.2.5. name:XAPP MaxGroup:1 +Index:3 OID: 1.3.6.1.4.1.1373.1.3.2.3.4. name:SMPP MaxGroup:0 +Index:4 OID: 1.3.6.1.4.1.1373.1.3.3.2.2. name:CCF(MSC) MaxGroup:0 +Index:5 OID: 1.3.6.1.4.1.1373.1.3.3.2.5. name:VLR MaxGroup:1 +Index:6 OID: 1.3.6.1.4.1.1373.1.3.3.3. name:HLR MaxGroup:1 +Index:7 OID: 1.3.6.1.4.1.1373.1.3.3.4. name:AUC MaxGroup:1 +Index:8 OID: 1.3.6.1.4.1.1373.1.3.3.5. name:SMSC MaxGroup:1 +Index:9 OID: 1.3.6.1.4.1.1373.1.3.3.6. name:PPS MaxGroup:1 + + + + + + +Host IP +Index:0 Group index:0 Membre index:0 Host name:MTP3_0_0 mss-0 Host ip:172.54.240.80. +Index:1 Group index:1 Membre index:0 Host name:MTP3_1_0 mss-1 Host ip:172.18.133.1. +Index:2 Group index:2 Membre index:0 Host name:MTP3_2_0 -- Host ip:172.18.123.1. +Index:3 Group index:3 Membre index:0 Host name:MTP3_3_0 -- Host ip:172.18.143.1. +Index:4 Group index:0 Membre index:0 Host name:SCCP_0_0 mss-0 Host ip:172.54.240.80. +Index:5 Group index:1 Membre index:0 Host name:SCCP_1_0 mss-1 Host ip:172.18.133.1. +Index:6 Group index:0 Membre index:0 Host name:XAPP_0_0 MSS-0 Host ip:172.54.240.80. +Index:7 Group index:1 Membre index:0 Host name:XAPP_1_0 MSS-1 Host ip:172.18.133.1. +Index:8 Group index:0 Membre index:0 Host name:SMPP_0_0 SMPP-0 Host ip:172.54.240.80. +Index:9 Group index:0 Membre index:0 Host name:MSC_0_0 -- Host ip:172.54.240.80. +Index:10 Group index:1 Membre index:0 Host name:MSC_1_0 -- Host ip:172.18.133.1. +Index:11 Group index:0 Membre index:0 Host name:CCF(MSC)_0_0 -- Host ip:172.54.240.80. +Index:12 Group index:0 Membre index:1 Host name:CCF(MSC)_0_1 -- Host ip:172.18.133.1. +Index:13 Group index:0 Membre index:0 Host name:VLR_0_0 VLR-0 Host ip:172.54.240.80. +Index:14 Group index:1 Membre index:0 Host name:VLR_1_0 VLR-1 Host ip:172.18.0.1. +Index:15 Group index:0 Membre index:0 Host name:HLR_0_0 -- Host ip:172.54.240.80. +Index:16 Group index:1 Membre index:0 Host name:HLR_1_0 -- Host ip:172.18.234.230. +Index:17 Group index:0 Membre index:0 Host name:AUC_0_0 -- Host ip:172.54.240.80. +Index:18 Group index:1 Membre index:0 Host name:AUC_1_0 -- Host ip:172.18.234.230. +Index:19 Group index:0 Membre index:0 Host name:SMSC_0_0 -- Host ip:172.54.240.80. +Index:20 Group index:1 Membre index:0 Host name:SMSC_1_0 -- Host ip:172.18.234.230. +Index:21 Group index:0 Membre index:0 Host name:PPS_0_0 -- Host ip:172.54.240.80. +Index:22 Group index:1 Membre index:0 Host name:PPS_1_0 -- Host ip:172.18.234.230. + + + + + + +Module Save flag +Module Index:0 OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.7. oid len:14 select id:3 field id:1 +Module Index:1 OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.2. oid len:14 select id:2 field id:1 +Module Index:2 OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.2. oid len:14 select id:1 field id:1 +Module Index:3 OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3.2. oid len:14 select id:1 field id:1 +Module Index:4 OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.2. oid len:14 select id:3 field id:1 +Module Index:5 OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.3. oid len:14 select id:2 field id:1 +Module Index:6 OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.2. oid len:14 select id:2 field id:1 +Module Index:7 OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.2. oid len:14 select id:2 field id:1 +Module Index:8 OID: 1.3.6.1.4.1.1373.1.3.3.5.3.3. oid len:13 select id:1 field id:1 +Module Index:9 OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.2. oid len:15 select id:1 field id:1 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 + + + diff --git a/plat/smpp/ut/conf/MIB_files/IWV-SMI.txt b/plat/smpp/ut/conf/MIB_files/IWV-SMI.txt new file mode 100644 index 0000000..b5269e3 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/IWV-SMI.txt @@ -0,0 +1,40 @@ +-- ***************************************************************** +-- IWV-SMI: interWAVE Enterprise Structure of Management Information +-- +-- draft November 2000, Huang qilong +-- 1st November 2004, Sheng Xueqiang +-- +-- Copyright (c) 2000 by interWAVE, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- + +IWV-SMI DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, + OBJECT-IDENTITY, + enterprises + FROM SNMPv2-SMI; + +IWV MODULE-IDENTITY + LAST-UPDATED "0411170000Z" + ORGANIZATION "interWAVE, Inc." + CONTACT-INFO + "http://www.iwv.com" + DESCRIPTION + "The Structure of Management Information for the interWAVE enterprise." + REVISION "200411170000Z" + DESCRIPTION + "1st version of this MIB module." + ::= { enterprises 1373 } -- assigned by IANA + + +IWV_Products OBJECT-IDENTITY + STATUS current + DESCRIPTION + "iwvProducts is the root OBJECT IDENTIFIER from which sysObjectID values are assigned. Actual values are defined in IWV-PRODUCTS-MIB." + ::= { IWV 1 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/Special_App-SMI.txt b/plat/smpp/ut/conf/MIB_files/Special_App-SMI.txt new file mode 100644 index 0000000..ad05aa6 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/Special_App-SMI.txt @@ -0,0 +1,43 @@ +-- ***************************************************************** +-- Special_App-SMI: WXC2 Structure of Management Information +-- +-- draft November 2004, Sheng Xueqiang +-- +-- Copyright (c) 2004 by interWAVE, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- + +Special_App-SMI DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, + OBJECT-IDENTITY, + FROM SNMPv2-SMI + IWV_Products + FROM IWV-SMI; + +Special_App MODULE-IDENTITY + LAST-UPDATED "0411180000Z" + ORGANIZATION "interWAVE, Inc." + CONTACT-INFO + "http://www.iwv.com" + DESCRIPTION + "The Structure of Management Information for the Special Application of interWAVE enterprise." + REVISION "200411180000Z" + DESCRIPTION + "1st version of this MIB module." + ::= { IWV_Products 2 } + +-- CNF Center +-- IWF +IWF OBJECT-IDENTITY + STATUS current + DESCRIPTION + "IWF " + ::= { Special_App 8 } + +-- PPP Route + +END diff --git a/plat/smpp/ut/conf/MIB_files/System_IP_List.txt b/plat/smpp/ut/conf/MIB_files/System_IP_List.txt new file mode 100644 index 0000000..577452c --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/System_IP_List.txt @@ -0,0 +1,26 @@ +// host ip +// "//" is the annotation characters; ";" is the septation characters; +// Please put the localhost subsystem ip at the first of the group ip on one subsystem +MTP3_0_0 mss-0 ; LocalHost; +MTP3_1_0 mss-1 ; 172.18.133.1; +MTP3_2_0 -- ; 172.18.123.1; +MTP3_3_0 -- ; 172.18.143.1; +SCCP_0_0 mss-0 ; LOCALHOST; +SCCP_1_0 mss-1 ; 172.18.133.1; +XAPP_0_0 MSS-0 ; localhost; +XAPP_1_0 MSS-1 ; 172.18.133.1; +SMPP_0_0 SMPP-0; LocalHost; +MSC_0_0 -- ; LocalHost; +MSC_1_0 -- ; 172.18.133.1; +CCF(MSC)_0_0 --; LocalHost; +CCF(MSC)_0_1 --; 172.18.133.1; +VLR_0_0 VLR-0 ; LocalHost; +VLR_1_0 VLR-1 ; 172.18..1; +HLR_0_0 -- ; LocalHost; +HLR_1_0 -- ; 172.18.234.230; +AUC_0_0 -- ; LocalHost; +AUC_1_0 -- ; 172.18.234.230; +SMSC_0_0 -- ; LocalHost; +SMSC_1_0 -- ; 172.18.234.230; +PPS_0_0 -- ; LocalHost; +PPS_1_0 -- ; 172.18.234.230; diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-AUC-MIB.txt b/plat/smpp/ut/conf/MIB_files/WXC2-AUC-MIB.txt new file mode 100644 index 0000000..a78176a --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-AUC-MIB.txt @@ -0,0 +1,437 @@ +alvr1188-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +AUC OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for AUC . + " + ::= { App 4 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for AUC . + " + ::= { AUC 2 } + +Public_parameter OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Public_parameter for AUC . + " + ::= { Configuration 1 } + + +SSD OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]share SSD + { + [u]0.0-0.7 + [u]select + [v]0[opt]not share + [v]1[opt]share + } + + [2]Update SSD timer + { + [u]1.0-2.7 + [u]input + [v]toDec-high-0 + } + [3]reserved + { + [u]3.0-7.7 + [u]select + } + Remark: SSD + [End] + " + ::= { Public_parameter 2 } + +Count OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]Count Match Range + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + + [2]reserved + { + [u]1.0-7.7 + [u]select + } + Remark: Count. + [End] + " + ::= { Public_parameter 3 } + +Failures OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: + [1]AUTHR Mismatch + { + [u]0.0-0.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + + [2]Count Mismatch + { + [u]1.0-1.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [3]Unique Challenge Failure + { + [u]2.0-2.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [4]SSD Update Failure + { + [u]3.0-3.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [5]Count Update Failure + { + [u]4.0-4.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + + [6]Missing AUTH Parameters + { + [u]5.0-5.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + + [7]reserved + { + [u]6.0-7.7 + [u]select + } + + Remark: Count. + [End] + " + ::= { Public_parameter 4 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management . + " + ::= { Configuration 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag: S1.2 + Field: [1]Save parameters to HD + { + [u]00.0-00.2 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + [v]01[opt]Saving + [v]02[opt]Save succeeds + [v]03[opt]Save fails + } + [2]Save user data to HD&OMC + { + [u]00.3-00.5 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + [v]01[opt]Saving + [v]02[opt]Save succeeds + [v]03[opt]Save fails + } + [3]Reserved + { + [u]00.6-00.7 + [u]select + } + Remark: Command for AUC paramters and user data operation, and the result of command. + [End] + " + ::= { Management 2 } + +License_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]Licenses + { + [u]00.0-15.7 + [u]input + [v]keepHex-high-0 + } + Remark: 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of AUC subscribers for service provider. The new license can not support less AUC subscribers than what the old license supports. + [End] + " + ::= { Management 3 } + +MAX_License OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark: The maximum quantity of approved AUC subscribers determined by License control Read only. + [End] + " + ::= { Management 11 } + +Used_License OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Used Licenses + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of currently registered EIR subscribers (Read only). + [End] + " + ::= { Management 12 } + +User_information OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + User Information . + " + ::= { Management 13 } + +Provisioned_Users OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 000000 + Field: [1]Provisioned users + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of service enabled AUC subscribers (Read only). + [End] + " + ::= { User_information 1 } + +Version OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Version . + " + ::= { Management 14 } + +Software OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]System + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Module + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Test + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of AUC software (Read only). + System: System release version, based on basic function and structure. + Module: Software module version, based on software module. + Test: Test version, 0=Release version. 1=Test version. + [End] + " + ::= { Version 1 } + +User_data OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]System + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]User data + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Test + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of AUC subscriber data (Read only). + System: System release version, based on basic function and structure. + User data: Subscriber profile version, based on software module. + Test: Test version, 0=Release version. 1=Test version. + [End] + " + ::= { Version 2 } + +IMSI_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1000 + Length: 4 + Default: 00000000 + Field: [1]IMSI segment + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: IMSI segment table (Read only): + 100,000 IMSIs are subdivided into 1000 segments, each IMSI segment use the 8 most significant digits (from the 6th digit to 13th digit of 15-digit of IMSI) as the segment number. + IMSI=MCC(3)+MNC(2)+MSIN(10) + Segment number=the 8 most significant digits of the MSIN, each segment has 100 subscribers (00-99). + e.g. If IMSI=460002356090098 then it belongs to IMSI segemt 23560900 and its account number in that segment=98. 0=empty segment. + [End] + " + ::= { Management 15 } + +Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Status for AUC . + " + ::= { AUC 3 } + +Import_status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 12 + Default: 000000000000000000000000 + Field: + Remark: Import status. + [End] + " + ::= { Status 2 } +END diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-HLR-MIB.txt b/plat/smpp/ut/conf/MIB_files/WXC2-HLR-MIB.txt new file mode 100644 index 0000000..a1469fa --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-HLR-MIB.txt @@ -0,0 +1,2431 @@ +WXC2-HLR-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +HLR OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for HLR . + " + ::= { App 3 } + +Config OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for HLR . + " + ::= { HLR 2 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Public parameter . + " + ::= { Config 1 } + +HPLMN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 17 + Default: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + Field: [1]CC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]NDC + { + [u]02.0-04.7 + [u]input + [v]keepHex-low-E + } + [3]Start SN + { + [u]05.0-10.7 + [u]input + [v]keepHex-low-E + } + [4]End SN + { + [u]11.0-16.7 + [u]input + [v]keepHex-low-E + } + Remark: Define the SN (VLR phone number) range of the VLR in the HPLMN (home PLMN) by specifying the start and end phone number of the range. + MSISDN=CC(country code)+NDC(National Destination Code)+SN. + All VLRs within a HPLMN have the same CC and NDC but the different SN. The SN of all VLR in a HPLMN must lie within the defined SN range. + Byte0-1=Country code. + Byte2-3=National destination code. + Byte4-9=Start SN of the VLR SN. + Byte10-15=End SN of the VLR SN. + e.g. For China country code=86, Shanghai national destination code=21, VLR SN=26060888: + Byte0-1=86EE, + Byte2-3=21EE, + SN=26060888, + Else=E. + [End] + " + ::= { Public_Param 11 } + +VPLMNs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 17 + Default: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + Field: [1]CC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]NDC + { + [u]02.0-04.7 + [u]input + [v]keepHex-low-E + } + [3]Start SN + { + [u]05.0-10.7 + [u]input + [v]keepHex-low-E + } + [4]End SN + { + [u]11.0-16.7 + [u]input + [v]keepHex-low-E + } + Remark: Define all connected VPLMNs (up tp 256) by specifying all VLR zones included in these VPLMNs. Each VLR zone is defined by its VLR MSISDN. MSISDN=CC+NDC+SN. All VLRs within a same VPLMN have the CC and NDC but the different SN. A VPLMN contains a group of VLRs whose SN is included in the defined SN range, E=random digit. + This parameter also define two ranges of VLR CSRR (Country specific roaming restrictionszones) zones for each VPLMN. In these defined VLR CSRR zones all HPLMN subscribers may be subjected to country specific roaming restrictions. + For each VPLMN setup, the format is: + byte0=ISDN numbering plan, default=91. + byte1-2=country code, EEEE. + byte3-4=national destination code, EEEE. + byte5-10=start SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. + byte11-16=end SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. + byte17-22=start SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + byte23-28=end SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + byte29-34=start SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + byte35-40=end SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. + E=random digit. + [End] + " + ::= { Public_Param 12 } + +CSRR_List OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 32 + Default: 0000000000000000000000000000000000000000000000000000000000000000 + Field: [1]VPLMN0 Roaming allowed + { + [u]31.0-31.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [2]VPLMN1 Roaming allowed + { + [u]31.1-31.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [3]VPLMN2 Roaming allowed + { + [u]31.2-31.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [4]VPLMN3 Roaming allowed + { + [u]31.3-31.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [5]VPLMN4 Roaming allowed + { + [u]31.4-31.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [6]VPLMN5 Roaming allowed + { + [u]31.5-31.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [7]VPLMN6 Roaming allowed + { + [u]31.6-31.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [8]VPLMN7 Roaming allowed + { + [u]31.7-31.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [9]VPLMN8 Roaming allowed + { + [u]30.0-30.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [10]VPLMN9 Roaming allowed + { + [u]30.1-30.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [11]VPLMN10 Roaming allowed + { + [u]30.2-30.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [12]VPLMN11 Roaming allowed + { + [u]30.3-30.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [13]VPLMN12 Roaming allowed + { + [u]30.4-30.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [14]VPLMN13 Roaming allowed + { + [u]30.5-30.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [15]VPLMN14 Roaming allowed + { + [u]30.6-30.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [16]VPLMN15 Roaming allowed + { + [u]30.7-30.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [17]VPLMN16 Roaming allowed + { + [u]29.0-29.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [18]VPLMN17 Roaming allowed + { + [u]29.1-29.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [19]VPLMN18 Roaming allowed + { + [u]29.2-29.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [20]VPLMN19 Roaming allowed + { + [u]29.3-29.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [21]VPLMN20 Roaming allowed + { + [u]29.4-29.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [22]VPLMN21 Roaming allowed + { + [u]29.5-29.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [23]VPLMN22 Roaming allowed + { + [u]29.6-29.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [24]VPLMN23 Roaming allowed + { + [u]29.7-29.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [25]VPLMN24 Roaming allowed + { + [u]28.0-28.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [26]VPLMN25 Roaming allowed + { + [u]28.1-28.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [27]VPLMN26 Roaming allowed + { + [u]28.2-28.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [28]VPLMN27 Roaming allowed + { + [u]28.3-28.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [29]VPLMN28 Roaming allowed + { + [u]28.4-28.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [30]VPLMN29 Roaming allowed + { + [u]28.5-28.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [31]VPLMN30 Roaming allowed + { + [u]28.6-28.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [32]VPLMN31 Roaming allowed + { + [u]28.7-28.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [33]VPLMN32 Roaming allowed + { + [u]27.0-27.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [34]VPLMN33 Roaming allowed + { + [u]27.1-27.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [35]VPLMN34 Roaming allowed + { + [u]27.2-27.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [36]VPLMN35 Roaming allowed + { + [u]27.3-27.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [37]VPLMN36 Roaming allowed + { + [u]27.4-27.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [38]VPLMN37 Roaming allowed + { + [u]27.5-27.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [39]VPLMN38 Roaming allowed + { + [u]27.6-27.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [40]VPLMN39 Roaming allowed + { + [u]27.7-27.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [41]VPLMN40 Roaming allowed + { + [u]26.0-26.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [42]VPLMN41 Roaming allowed + { + [u]26.1-26.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [43]VPLMN42 Roaming allowed + { + [u]26.2-26.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [44]VPLMN43 Roaming allowed + { + [u]26.3-26.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [45]VPLMN44 Roaming allowed + { + [u]26.4-26.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [46]VPLMN45 Roaming allowed + { + [u]26.5-26.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [47]VPLMN46 Roaming allowed + { + [u]26.6-26.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [48]VPLMN47 Roaming allowed + { + [u]26.7-26.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [49]VPLMN48 Roaming allowed + { + [u]25.0-25.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [50]VPLMN49 Roaming allowed + { + [u]25.1-25.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [51]VPLMN50 Roaming allowed + { + [u]25.2-25.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [52]VPLMN51 Roaming allowed + { + [u]25.3-25.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [53]VPLMN52 Roaming allowed + { + [u]25.4-25.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [54]VPLMN53 Roaming allowed + { + [u]25.5-25.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [55]VPLMN54 Roaming allowed + { + [u]25.6-25.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [56]VPLMN55 Roaming allowed + { + [u]25.7-25.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [57]VPLMN56 Roaming allowed + { + [u]24.0-24.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [58]VPLMN57 Roaming allowed + { + [u]24.1-24.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [59]VPLMN58 Roaming allowed + { + [u]24.2-24.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [60]VPLMN59 Roaming allowed + { + [u]24.3-24.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [61]VPLMN60 Roaming allowed + { + [u]24.4-24.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [62]VPLMN61 Roaming allowed + { + [u]24.5-24.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [63]VPLMN62 Roaming allowed + { + [u]24.6-24.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [64]VPLMN63 Roaming allowed + { + [u]24.7-24.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [65]VPLMN64 Roaming allowed + { + [u]23.0-23.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [66]VPLMN65 Roaming allowed + { + [u]23.1-23.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [67]VPLMN66 Roaming allowed + { + [u]23.2-23.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [68]VPLMN67 Roaming allowed + { + [u]23.3-23.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [69]VPLMN68 Roaming allowed + { + [u]23.4-23.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [70]VPLMN69 Roaming allowed + { + [u]23.5-23.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [71]VPLMN70 Roaming allowed + { + [u]23.6-23.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [72]VPLMN71 Roaming allowed + { + [u]23.7-23.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [73]VPLMN72 Roaming allowed + { + [u]22.0-22.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [74]VPLMN73 Roaming allowed + { + [u]22.1-22.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [75]VPLMN74 Roaming allowed + { + [u]22.2-22.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [76]VPLMN75 Roaming allowed + { + [u]22.3-22.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [77]VPLMN76 Roaming allowed + { + [u]22.4-22.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [78]VPLMN77 Roaming allowed + { + [u]22.5-22.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [79]VPLMN78 Roaming allowed + { + [u]22.6-22.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [80]VPLMN79 Roaming allowed + { + [u]22.7-22.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [81]VPLMN80 Roaming allowed + { + [u]21.0-21.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [82]VPLMN81 Roaming allowed + { + [u]21.1-21.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [83]VPLMN82 Roaming allowed + { + [u]21.2-21.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [84]VPLMN83 Roaming allowed + { + [u]21.3-21.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [85]VPLMN84 Roaming allowed + { + [u]21.4-21.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [86]VPLMN85 Roaming allowed + { + [u]21.5-21.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [87]VPLMN86 Roaming allowed + { + [u]21.6-21.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [88]VPLMN87 Roaming allowed + { + [u]21.7-21.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [89]VPLMN88 Roaming allowed + { + [u]20.0-20.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [90]VPLMN89 Roaming allowed + { + [u]20.1-20.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [91]VPLMN90 Roaming allowed + { + [u]20.2-20.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [92]VPLMN91 Roaming allowed + { + [u]20.3-20.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [93]VPLMN92 Roaming allowed + { + [u]20.4-20.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [94]VPLMN93 Roaming allowed + { + [u]20.5-20.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [95]VPLMN94 Roaming allowed + { + [u]20.6-20.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [96]VPLMN95 Roaming allowed + { + [u]20.7-20.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [97]VPLMN96 Roaming allowed + { + [u]19.0-19.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [98]VPLMN97 Roaming allowed + { + [u]19.1-19.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [99]VPLMN98 Roaming allowed + { + [u]19.2-19.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [100]VPLMN99 Roaming allowed + { + [u]19.3-19.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [101]VPLMN100 Roaming allowed + { + [u]19.4-19.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [102]VPLMN101 Roaming allowed + { + [u]19.5-19.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [103]VPLMN102 Roaming allowed + { + [u]19.6-19.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [104]VPLMN103 Roaming allowed + { + [u]19.7-19.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [105]VPLMN104 Roaming allowed + { + [u]18.0-18.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [106]VPLMN105 Roaming allowed + { + [u]18.1-18.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [107]VPLMN106 Roaming allowed + { + [u]18.2-18.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [108]VPLMN107 Roaming allowed + { + [u]18.3-18.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [109]VPLMN108 Roaming allowed + { + [u]18.4-18.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [110]VPLMN109 Roaming allowed + { + [u]18.5-18.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [111]VPLMN110 Roaming allowed + { + [u]18.6-18.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [112]VPLMN111 Roaming allowed + { + [u]18.7-18.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [113]VPLMN112 Roaming allowed + { + [u]17.0-17.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [114]VPLMN113 Roaming allowed + { + [u]17.1-17.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [115]VPLMN114 Roaming allowed + { + [u]17.2-17.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [116]VPLMN115 Roaming allowed + { + [u]17.3-17.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [117]VPLMN116 Roaming allowed + { + [u]17.4-17.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [118]VPLMN117 Roaming allowed + { + [u]17.5-17.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [119]VPLMN118 Roaming allowed + { + [u]17.6-17.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [120]VPLMN119 Roaming allowed + { + [u]17.7-17.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [121]VPLMN120 Roaming allowed + { + [u]16.0-16.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [122]VPLMN121 Roaming allowed + { + [u]16.1-16.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [123]VPLMN122 Roaming allowed + { + [u]16.2-16.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [124]VPLMN123 Roaming allowed + { + [u]16.3-16.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [125]VPLMN124 Roaming allowed + { + [u]16.4-16.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [126]VPLMN125 Roaming allowed + { + [u]16.5-16.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [127]VPLMN126 Roaming allowed + { + [u]16.6-16.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [128]VPLMN127 Roaming allowed + { + [u]16.7-16.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [129]VPLMN128 Roaming allowed + { + [u]15.0-15.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [130]VPLMN129 Roaming allowed + { + [u]15.1-15.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [131]VPLMN130 Roaming allowed + { + [u]15.2-15.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [132]VPLMN131 Roaming allowed + { + [u]15.3-15.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [133]VPLMN132 Roaming allowed + { + [u]15.4-15.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [134]VPLMN133 Roaming allowed + { + [u]15.5-15.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [135]VPLMN134 Roaming allowed + { + [u]15.6-15.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [136]VPLMN135 Roaming allowed + { + [u]15.7-15.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [137]VPLMN136 Roaming allowed + { + [u]14.0-14.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [138]VPLMN137 Roaming allowed + { + [u]14.1-14.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [139]VPLMN138 Roaming allowed + { + [u]14.2-14.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [140]VPLMN139 Roaming allowed + { + [u]14.3-14.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [141]VPLMN140 Roaming allowed + { + [u]14.4-14.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [142]VPLMN141 Roaming allowed + { + [u]14.5-14.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [143]VPLMN142 Roaming allowed + { + [u]14.6-14.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [144]VPLMN143 Roaming allowed + { + [u]14.7-14.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [145]VPLMN144 Roaming allowed + { + [u]13.0-13.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [146]VPLMN145 Roaming allowed + { + [u]13.1-13.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [147]VPLMN146 Roaming allowed + { + [u]13.2-13.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [148]VPLMN147 Roaming allowed + { + [u]13.3-13.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [149]VPLMN148 Roaming allowed + { + [u]13.4-13.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [150]VPLMN149 Roaming allowed + { + [u]13.5-13.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [151]VPLMN150 Roaming allowed + { + [u]13.6-13.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [152]VPLMN151 Roaming allowed + { + [u]13.7-13.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [153]VPLMN152 Roaming allowed + { + [u]12.0-12.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [154]VPLMN153 Roaming allowed + { + [u]12.1-12.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [155]VPLMN154 Roaming allowed + { + [u]12.2-12.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [156]VPLMN155 Roaming allowed + { + [u]12.3-12.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [157]VPLMN156 Roaming allowed + { + [u]12.4-12.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [158]VPLMN157 Roaming allowed + { + [u]12.5-12.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [159]VPLMN158 Roaming allowed + { + [u]12.6-12.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [160]VPLMN159 Roaming allowed + { + [u]12.7-12.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [161]VPLMN160 Roaming allowed + { + [u]11.0-11.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [162]VPLMN161 Roaming allowed + { + [u]11.1-11.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [163]VPLMN162 Roaming allowed + { + [u]11.2-11.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [164]VPLMN163 Roaming allowed + { + [u]11.3-11.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [165]VPLMN164 Roaming allowed + { + [u]11.4-11.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [166]VPLMN165 Roaming allowed + { + [u]11.5-11.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [167]VPLMN166 Roaming allowed + { + [u]11.6-11.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [168]VPLMN167 Roaming allowed + { + [u]11.7-11.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [169]VPLMN168 Roaming allowed + { + [u]10.0-10.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [170]VPLMN169 Roaming allowed + { + [u]10.1-10.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [171]VPLMN170 Roaming allowed + { + [u]10.2-10.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [172]VPLMN171 Roaming allowed + { + [u]10.3-10.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [173]VPLMN172 Roaming allowed + { + [u]10.4-10.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [174]VPLMN173 Roaming allowed + { + [u]10.5-10.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [175]VPLMN174 Roaming allowed + { + [u]10.6-10.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [176]VPLMN175 Roaming allowed + { + [u]10.7-10.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [177]VPLMN176 Roaming allowed + { + [u]09.0-09.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [178]VPLMN177 Roaming allowed + { + [u]09.1-09.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [179]VPLMN178 Roaming allowed + { + [u]09.2-09.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [180]VPLMN179 Roaming allowed + { + [u]09.3-09.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [181]VPLMN180 Roaming allowed + { + [u]09.4-09.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [182]VPLMN181 Roaming allowed + { + [u]09.5-09.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [183]VPLMN182 Roaming allowed + { + [u]09.6-09.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [184]VPLMN183 Roaming allowed + { + [u]09.7-09.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [185]VPLMN184 Roaming allowed] + { + [u]08.0-08.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [186]VPLMN185 Roaming allowed + { + [u]08.1-08.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [187]VPLMN186 Roaming allowed + { + [u]08.2-08.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [188]VPLMN187 Roaming allowed + { + [u]08.3-08.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [189]VPLMN188 Roaming allowed + { + [u]08.4-08.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [190]VPLMN189 Roaming allowed + { + [u]08.5-08.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [191]VPLMN190 Roaming allowed + { + [u]08.6-08.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [192]VPLMN191 Roaming allowed + { + [u]08.7-08.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [193]VPLMN192 Roaming allowed + { + [u]07.0-07.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [194]VPLMN193 Roaming allowed + { + [u]07.1-07.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [195]VPLMN194 Roaming allowed + { + [u]07.2-07.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [196]VPLMN195 Roaming allowed + { + [u]07.3-07.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [197]VPLMN196 Roaming allowed + { + [u]07.4-07.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [198]VPLMN197 Roaming allowed + { + [u]07.5-07.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [199]VPLMN198 Roaming allowed + { + [u]07.6-07.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [200]VPLMN199 Roaming allowed + { + [u]07.7-07.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [201]VPLMN200 Roaming allowed + { + [u]06.0-06.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [202]VPLMN201 Roaming allowed + { + [u]06.1-06.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [203]VPLMN202 Roaming allowed + { + [u]06.2-06.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [204]VPLMN203 Roaming allowed + { + [u]06.3-06.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [205]VPLMN204 Roaming allowed + { + [u]06.4-06.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [206]VPLMN205 Roaming allowed + { + [u]06.5-06.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [207]VPLMN206 Roaming allowed + { + [u]06.6-06.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [208]VPLMN207 Roaming allowed + { + [u]06.7-06.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [209]VPLMN208 Roaming allowed + { + [u]05.0-05.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [210]VPLMN209 Roaming allowed + { + [u]05.1-05.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [211]VPLMN210 Roaming allowed + { + [u]05.2-05.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [212]VPLMN211 Roaming allowed + { + [u]05.3-05.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [213]VPLMN212 Roaming allowed + { + [u]05.4-05.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [214]VPLMN213 Roaming allowed + { + [u]05.5-05.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [215]VPLMN214 Roaming allowed + { + [u]05.6-05.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [216]VPLMN215 Roaming allowed + { + [u]05.7-05.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [217]VPLMN216 Roaming allowed + { + [u]04.0-04.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [218]VPLMN217 Roaming allowed + { + [u]04.1-04.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [219]VPLMN218 Roaming allowed + { + [u]04.2-04.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [220]VPLMN219 Roaming allowed + { + [u]04.3-04.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [221]VPLMN220 Roaming allowed + { + [u]04.4-04.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [222]VPLMN221 Roaming allowed + { + [u]04.5-04.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [223]VPLMN222 Roaming allowed + { + [u]04.6-04.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [224]VPLMN223 Roaming allowed + { + [u]04.7-04.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [225]VPLMN224 Roaming allowed + { + [u]03.0-03.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [226]VPLMN225 Roaming allowed + { + [u]03.1-03.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [227]VPLMN226 Roaming allowed + { + [u]03.2-03.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [228]VPLMN227 Roaming allowed + { + [u]03.3-03.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [229]VPLMN228 Roaming allowed + { + [u]03.4-03.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [230]VPLMN229 Roaming allowed + { + [u]03.5-03.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [231]VPLMN230 Roaming allowed + { + [u]03.6-03.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [232]VPLMN231 Roaming allowed + { + [u]03.7-03.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [233]VPLMN232 Roaming allowed + { + [u]02.0-02.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [234]VPLMN233 Roaming allowed + { + [u]02.1-02.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [235]VPLMN234 Roaming allowed + { + [u]02.2-02.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [236]VPLMN235 Roaming allowed + { + [u]02.3-02.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [237]VPLMN236 Roaming allowed + { + [u]02.4-02.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [238]VPLMN237 Roaming allowed + { + [u]02.5-02.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [239]VPLMN238 Roaming allowed + { + [u]02.6-02.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [240]VPLMN239 Roaming allowed + { + [u]02.7-02.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [241]VPLMN240 Roaming allowed + { + [u]01.0-01.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [242]VPLMN241 Roaming allowed + { + [u]01.1-01.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [243]VPLMN242 Roaming allowed + { + [u]01.2-01.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [244]VPLMN243 Roaming allowed + { + [u]01.3-01.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [245]VPLMN244 Roaming allowed + { + [u]01.4-01.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [246]VPLMN245 Roaming allowed + { + [u]01.5-01.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [247]VPLMN246 Roaming allowed + { + [u]01.6-01.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [248]VPLMN247 Roaming allowed + { + [u]01.7-01.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [249]VPLMN248 Roaming allowed + { + [u]00.0-00.0 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [250]VPLMN249 Roaming allowed + { + [u]00.1-00.1 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [251]VPLMN250 Roaming allowed + { + [u]00.2-00.2 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [252]VPLMN251 Roaming allowed + { + [u]00.3-00.3 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [253]VPLMN252 Roaming allowed + { + [u]00.4-00.4 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [254]VPLMN253 Roaming allowed + { + [u]00.5-00.5 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [255]VPLMN254 Roaming allowed + { + [u]00.6-00.6 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + [256]VPLMN255 Roaming allowed + { + [u]00.7-00.7 + [u]select + [v]00[opt]Not allowed + [v]01[opt]Allowed + } + Remark: Define 8 CSRR (country specific roaming restriction) lists to confine the roaming range of a subscriber. + Each CSRR list defines the roaming restriction for 256 VPLMN ranges. + [End] + " + ::= { Public_Param 13 } + +Regional_Subs_List OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 255 + Length: 7 + Default: EEEEEEEEEEEEEE + Field: [1]Country Code + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]National Destination Code + { + [u]02.0-04.7 + [u]input + [v]keepHex-low-E + } + [3]Zone Code + { + [u]05.0-06.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the regional subscription zone code list. HLR supports up to 256 regional subscription zone code. + Regional subscription code = CC+NDC+zone code + [End] + " + ::= { Public_Param 14 } + +Licenses_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]Licenses + { + [u]00.0-07.7 + [u]input + [v]keepHex-high-0 + } + Remark: 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of HLR subscribers for service provider: + The new license can not support less HLR subscribers than what the old license supports. + [End] + " + ::= { Public_Param 15 } + +CDR_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]CDR control + { + [u]00.0-00.7 + [u]select + [v]00[opt]Off + [v]01[opt]On + } + Remark: HLR CDR generation flag: + Off=Not generate HLR CDR. + On=Generate HLR CDR. + [End] + " + ::= { Public_Param 16 } + +Feature_Code OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 64 + Default: 90EE68EE72EE92EE70EE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]CFB + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + [2]CFD + { + [u]02.0-03.7 + [u]input + [v]keepHex-low-E + } + [3]CFNA + { + [u]04.0-05.7 + [u]input + [v]keepHex-low-E + } + [4]CFU + { + [u]06.0-07.7 + [u]input + [v]keepHex-low-E + } + [5]Call waiting + { + [u]08.0-09.7 + [u]input + [v]keepHex-low-E + } + [6]Reserved + { + [u]10.0-63.7 + [u]select + } + Remark: None. + [End] + " + ::= { Public_Param 27 } + + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management . + " + ::= { Config 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag: S1.2 + Field: [1]Save parameter to HD + { + [u]00.0-00.2 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + } + [2]Save subscriber data to HD&OMC + { + [u]00.3-00.5 + [u]select + [v]00[opt]Idle + [v]01[opt]Save + } + [3]Reserved + { + [u]00.6-00.7 + [u]select + } + Remark: Bit0-2: HLR paramter save control: + Idle=no operation. + Save=Save parameters from HLR memory to HLR hard disk. + Bit3-5: HLR subscriber data save control: + Idle=no operation. + Save=Save HLR subscriber data from HLR memory to both HLR hard disk and OMC database. + Bit6-7: Reserved. + [End] + " + ::= { Management 2 } + +Subscriber_Import OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading Failed + } + [2]Total subscriber requested + { + [u]01.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]Total imported subscribers + { + [u]04.0-06.7 + [u]input + [v]toDec-high-0 + } + Remark: Progress and result of HLR subscriber import. + Byte0: Progress of HLR subscriber import. + Byte1-3: Total quantity of HLR subscribers requesting import. + Byte4-7: Quantity of successfully imported HLR subscribers. + [End] + " + ::= { Management 3 } + +Max_Licenses OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Max Licenses + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The maximum quantity of approved HLR subscribers determined by License control (Read Only). + [End] + " + ::= { Management 11 } + +Used_Licenses OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Used Licenses + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of currently registered HLR subscribers (Read Only). + [End] + " + ::= { Management 12 } + +Subscriber_Info OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subscriber information . + " + ::= { Management 13 } + +Provisioned_Subs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Provisioned Subs + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of service provisioned and active HLR subscribers (Read Only). + [End] + " + ::= { Subscriber_Info 1 } + +Registered_Subs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Registered Subs + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: The quantity of registered (both active and inactive) HLR subscribers (Read Only). + [End] + " + ::= { Subscriber_Info 2 } + +Roaming_Subs OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00000000 + Field: [1]Roaming Subs + { + [u]00.0-03.7[u]input + [v]toDec-high-0 + } + Remark: The quantity of provisioned HLR subscribers currently roaming to VPLMNs (Read Only). + [End] + " + ::= { Subscriber_Info 3 } + +Version OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Version . + " + ::= { Management 14 } + +Software OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Release + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Version + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Slice + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of HLR software (Read Only): + Byte0: System release version number: + - Based on basic function and structure. + Byte1: Software module version number: + - Based on software module. + Byte2: Test version: + - 0=Release version number. + - 1=Test version number. + [End] + " + ::= { Version 1 } + +User_Data OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Release + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Version + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Slice + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: Version of AUC subscriber data (Read Only): + System release version: Based on basic function and structure. + Subscriber data version: Based on software module. + Test version: 0=Release version 1=Test version + [End] + " + ::= { Version 2 } + +IMSI_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1000 + Length: 4 + Default: 00000000 + Field: [1]IMSI segment + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: MSISDN segment table (Read Only): + Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + [End] + " + ::= { Management 15 } + +MSISDN_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1000 + Length: 4 + Default: 00000000 + Field: [1]MSISDN segment + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: MSISDN segment table (Read Only): + Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + [End] + " + ::= { Management 16 } + +CNF_Applicant_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 9 + Default: 000000000000000000 + Field: [1]Charge Type + { + [u]00.0-00.7 + [u]select + [v]00[opt]Invalid user + [v]01[opt]Post-pay user + [v]02[opt]Prepaid user + } + [2]IMSI + { + [u]01.0-08.7 + [u]input + [v]keepHex-low-E + } + Remark: Display the IMSI and charge type of the latest conference applicant (Read Only). + [End] + " + ::= { Management 27 } +END diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-MSC-MIB.txt b/plat/smpp/ut/conf/MIB_files/WXC2-MSC-MIB.txt new file mode 100644 index 0000000..a7a00f6 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-MSC-MIB.txt @@ -0,0 +1,4084 @@ +WXC2-MSC-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +MSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for msc . + " + ::= { App 2 } +-- +-- sub system CCF(MSC) +-- + +CCF(MSC) OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for msc . + " + ::= { MSC 2 } + +CCF_Config OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for CCF . + " + ::= { CCF(MSC) 2 } + +-- +-- CCF -> Configuration -> Call Routing +-- + +Call_Routing OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Call Routing . + " + ::= { CCF_Config 1 } + +Prefix_Assignment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 8 + Default : EEEEEEEEEEEEEEEE + Field : [1]Prefix + { + [u]0.0-7.7 + [u]input + [v]keepHex-low-E + } + Remark: 4 bytes are used to set a 8-digit prefix for dialed number. + Prefix is the first layer for dialed number based call routing. If the dialed number of a call matches a pre-programmed prefix in this table, this call will be routed to a certain trunk group, subsequently that trunk group will route this call via a dedicated E1 port.This system has totally 256 prefixes. + Dialed number without matching a pre-programmed prefix will be routed to the default trunk group 0. + Prefix 252 is for default international call, all internation calls unable to be routed out will be routed from the trunk group assigned to prefix 252, keep default EEEEEEEE. + Prefix 253 is for default national call, all national calls unable to be routed out will be routed from the trunk group assigned to prefix 253, keep default EEEEEEEE. + Prefix 254 is for default subscriber call, all dialed MSISDN unable to be routed out will be routed from the trunk group assigned to prefix 254, keep default EEEEEEEE. + Prefix 255 is for unknown call, all unknown calls unable to be routed out will be routed from the trunk group assigned to prefix 255, keep default EEEEEEEE. + E=End tag, C='#', B='*'. + Default=0xEEEEEEEE. + [End] + " + ::= { Call_Routing 1 } + +Prefix_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 18 + Default : 2200EEEEEEEEEEEEEEEE010800EEEEEEEE03 + Flag : E10 + Field : [1]TON incoming call + { + [u]0.0-0.3 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [2]TON outgoing call + { + [u]0.4-0.7 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [3]Out trunk deletion count + { + [u]1.0-1.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [4]Out trunk insertion count + { + [u]1.4-1.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [5]Out trunk inserted digits + { + [u]2.0-9.7 + [u]input + [v]keepHex-low-E + } + [6]CDR on/off + { + [u]10.0-10.0 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [7]Reserved + { + [u]10.1-10.1 + [u]select + } + [8]Properties + { + [u]10.2-10.3 + [u]select + [v]0[opt]Trunk + [v]1[opt]MSISDN + [v]2[opt]MSRN + [v]3[opt]MSC + } + [9]Call type + { + [u]10.4-10.6 + [u]select + [v]0[opt]Normal Call + [v]1[opt]Emergency + [v]2[opt]MCT + [v]3[opt]VMS + [v]4[opt]IN + } + [10]Enable + { + [u]10.7-10.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } + [11]Length of dialed number + { + [u]11.0-11.7 + [u]input + [v]toDec-high-0 + } + [12]E.164 International deletion count + { + [u]12.0-12.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]Delete first one + [v]2[opt]Delete first two + [v]3[opt]Delete first three + [v]4[opt]Delete first four + [v]5[opt]Delete first five + [v]6[opt]Delete first six + [v]7[opt]Delete first seven + [v]8[opt]Delete first eight + } + [13]E.164 International insertion count + { + [u]12.4-12.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]Insert first one + [v]2[opt]Insert first two + [v]3[opt]Insert first three + [v]4[opt]Insert first four + [v]5[opt]Insert first five + [v]6[opt]Insert first six + [v]7[opt]Insert first seven + [v]8[opt]Insert first eight + } + [14]E.164 international inserted digits + { + [u]13.0-16.7 + [u]input + [v]keepHex-low-E + } + [15]Cli-type + { + [u]17.0-17.7 + [u]select + [v]0[opt]Sub + [v]1[opt]NDD + [v]2[opt]IDD + [v]3[opt]Unknown(local) + [v]4[opt]Unknown(NDD) + [v]5[opt]Unknown(IDD) + } + Remark: Enable: Y=prefix enable, N=prefix disable. + TON incoming call: Type of number for incoming call, include unknown, MSISDN, NDD and IDD. It is specified by originating node for terminating node to route this call with proper dialed number manipulation. + For system subscriber dialed prefix, always use unknown for In-TON except the prefix of international prefix beginning with a . For this kind of prefix (such as 86755832) we should set the In-TON as IDD to support dialing. + TON outgoing call: Type of number for outgoing call, include unknown, MSISDN, NDD and IDD. It specifies the type of an outgoing call for terminating node to route this call with proper dialed number manipulation. Generally the MSC uses IDD for outgoing call. + Out trunk deletion count: Quantity of deleted digit of a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no deletion, 1-8=delete first 1-8 digits. + Out trunk insertion count: Quantity of inserted digit for a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no insertion, 1-8=insert 1-8 digits from the beginning of this number. + Out trunk inserted digits: 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number. + CDR on/off: Turn on/off the CDR of dialed numbers beginning with this prefix. + Properties: Specify the properties of a prefix. Trunk=to PSTN, MSISDN=to A interface, MSRN=MS roaming number, MSC=to peer MSC. + Call type: Normal=no verification for MT, Emergency call=no verification for MO (free call), MCT=Malicious Call Trace, VMS call=send signaling carried DTMF to VMS. + Length of dialed number: Length of dialed number (1-32). + E.164 international deletion count: Quantity of deleted digit of E164 international number, always use IDD for outgoing call for PPS debiting. + E.164 international insertion count: Quantity of inserted digit of E164 international number, always use IDD for outgoing call for PPS debiting. + E.164 international inserted digits: Inserted digit to the E164 international number, 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number, always use IDD for outgoing call for PPS debiting. + [End] + " + ::= { Call_Routing 2 } + +Prefix_TG OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field: + [1]Assign TG to prefix + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a trunk group for each prefix for call routing, a single prefix points to only one trunk group, multiple prefix can be assigned the same trunk group, default is the no. of the prefix. + [End] + " + ::= { Call_Routing 3 } + +TG_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 10 + Default : 00000000000000000000000000 + Flag : E2 + Field: [1]DPC + { + [u]0.0-3.7 + [u]input + [v]keepHex-high-0 + } + [2]TG flag + { + [u]4.0-4.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]CDR on/off + { + [u]4.1-4.1 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [4]Announcement + { + [u]4.2-4.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [5]TG category + { + [u]4.3-4.5 + [u]select + [v]0[opt]PSTN + [v]1[opt]HPLMN + [v]2[opt]VHLMN + [v]3[opt]SUB + [v]4[opt]IP + [v]5[opt]Intercept + } + [6]Alternative TG flag + { + [u]4.6-4.6 + [u]select + [v]0[opt]Disable + [v]1[opt]enable + } + [7]Loopback + { + [u]4.7-4.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [8]Network indicator + { + [u]5.0-5.7 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [9]Circuit selection + { + [u]6.0-6.1 + [u]select + [v]0[opt]Clockwise + [v]1[opt]Anti-clockwise + [v]2[opt]Odd + [v]3[opt]Even + } + [10]Back off + { + [u]6.2-6.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [11]Reserved + { + [u]6.3-6.4 + [u]select + } + [12]MPTY + { + [u]6.5-6.5 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [13]Location + { + [u]6.6-6.7 + [u]select + [v]0[opt]MSC-0 + [v]1[opt]MSC-1 + [v]2[opt]Both + [v]3[opt]Spare + } + [14]Alternative TG + { + [u]7.0-7.7 + [u]input + [v]toDec-high-0 + } + [15]Tandem restriction + { + [u]8.0-8.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [16]Incoming Call type + { + [u]9.0-9.7 + [u]select + [v]0[opt]Normal + [v]1[opt]IN + } + Remark: DPC: Destination point code of this trunk group. + TG flag: enable or disable this trunk group. + CDR on/off: CDR on or off option for this trunk group. + Announcement: Voice announcement enable or disable for this trunk group. + TG category: PSTN=to PSTN, IP=to VMS and VPS, HPLMN=to HPLMN, VPLMN=to VPLMN, SUB=to BSC, Intercept=to intercept LEA + Alternative TG flag: Alternative trunk group enable or disable option. + Alternative TG: Alternative trunk group for backup purpose. + Loop back: Incoming call loop back enable or disable, used for MSC loop back. + Network indicator: Specify network type, International, International spare , National, National spare. + Circuit selection: Preferred circuit selection mode, include clockwise, anti-clockwise, odd and even. + Back off: Back off on or off when simultaneously select the same channel with the opposite side. + Location: For normal trunk group, select Both. For a trunk group to a VPS, configure this trunk group as MSC0 or MSC1. + MPTY: Multi-party call enable or disable. For all trunk groups to BSC, select Enable. + Tandem restriction:Y: Tandem disabled. Not support transit call from PSTN to PSTN via this trunk group. + N: Tandem enabled. Support transit call from PSTN to PSTN via this trunk group. + [End] + " + ::= { Call_Routing 4 } + +Call_Routing_CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 2 + Default : 03FF + Field : [1]Reserved + { + [u]0.3-0.7 + [u]select + } + [2]Redirection + { + [u]0.3-0.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [3]Feature Request + { + [u]0.2-0.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [4]Sorm + { + [u]0.1-0.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [5]MCT + { + [u]0.0-0.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [6]MT SM + { + [u]1.7-1.7 + [u]select + [v]0[opt]off + [v]1[opt]on + + } + [7]MO SM + { + [u]1.6-1.6 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [8]Transit call + { + [u]1.5-1.5 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [9]Gateway outgoing call + { + [u]1.4-1.4 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [10]Gateway incoming call + { + [u]1.3-1.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [11]Roaming call + { + [u]1.2-1.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [12]MT call + { + [u]1.1-1.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [13]MO call + { + [u]1.0-1.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + Remark: Sorm: call intercept MCT: malicious call trace + Default=CDR of MO call and MT call is enabled, CDR of roaming call, gateway incoming call, gateway outgoing call, transit call, MO SMS and MT SMS is disabled. + [End] + " + ::= { Call_Routing 5 } + +Voice_Prompt_Announcement_option OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 16 + Default : 00000000000000000000000000000000 + Field : [1]Announcement 0 + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [2]Announcement 1 + { + [u]1.0-1.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [3]Announcement 2 + { + [u]2.0-2.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [4]Announcement 3 + { + [u]3.0-3.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + + [5]Announcement 4 + { + [u]4.0-4.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [6]Announcement 5 + { + [u]5.0-5.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [7]Announcement 6 + { + [u]6.0-6.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [8]Announcement 7 + { + [u]7.0-7.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + + [9]Announcement 8 + { + [u]8.0-8.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [10]Announcement 9 + { + [u]9.0-9.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [11]Announcement 10 + { + [u]10.0-10.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [12]Announcement 11 + { + [u]11.0-11.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + + [13]Announcement 12 + { + [u]12.0-12.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [14]Announcement 13 + { + [u]13.0-13.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [15]Announcement 14 + { + [u]14.0-14.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + [16]Announcement 15 + { + [u]15.0-15.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + Remark : Set to play either announcement or tone indicating call unattainable reason for subscribers. System has total 8 announcements and tones that can be independently set. + Announcement 0: The dialed number is invalid. + Announcement 1: The subscriber dialed is not activated. + Announcement 2: The subscriber is busy. + Announcement 3: The network is busy. + Announcement 4: Caller's account was deactivated. + Announcement 5: The subscriber dialed was deactivated. + Announcement 6: Feature not available to caller. + Announcement 7: The subscriber dialed is not available. + [End] + " + ::= { Call_Routing 6 } + +Call_Routing_Warning OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 32 + Field : [1]Remanent time for warning tone + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark :Set time to play prompt tone for reaching zero balance prepaid subscriber when a call is in progress, unit is second. e.g. if set as 60, the system will play prompt tone one minute before a subscriber uses up his balance. + [End] + " + ::= { Call_Routing 7 } + + + +-- +-- CCF -> Configuration -> MSC +-- + + +CCF_MSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CCF Configuration MSC ." + ::= { CCF_Config 2 } + +Emergency_Call OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 21 + Default : 0000000000EEEEEEEEEEEEEEEE112EEEEEEEEEEEEE + Flag : E1 + Field : [1]Enable flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]LAC + { + [u]01.0-02.7 + [u]input + [v]toDec-high-0 + } + [3]CI + { + [u]03.0-04.7 + [u]input + [v]toDec-high-0 + } + [4]Dial number + { + [u]05.0-12.7 + [u]input + [v]keepHex-low-E + } + [5]Local emergency number + { + [u]13.0-20.7 + [u]input + [v]keepHex-low-E + } + Remark: Emergency call number. Default=112. + [End] + " + ::= { CCF_MSC 5 } + +Location_Management OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 8 + Default : 0000000000000000 + Flag : E1 + Field : [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } + [2]TG + { + [u]01.0-01.7 + [u]input + [v]toDec-high-0 + } + [3]LAC + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [4]CI + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + [5]Zone Code + { + [u]06.0-07.7 + [u]input + [v]toDec-high-0 + } + Remark :Manage the MS location by correlate TG (trunk group), LAC (location area code, cell ID and zone code, totally 256 location management. + [End] + " + ::= { CCF_MSC 8 } + + + +-- +-- CCF -> Configuration -> CPC Management +-- + + +CPC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CPC Management." + ::= { CCF_Config 3 } + +SRF_Address OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 8 + Default : 8675500000000009 + Field : [1]EIR number + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-E + } + Remark: E.164 number of HLR server:HLR MSISDN used for SCCP addressing, F=end tag. + Default=91867555950502FFFF=91867555950502. + [End] + " + ::= { CPC 3 } + +Max_Call_Duration OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 3C + Field : [1]Max. call duration + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark : Define the permitted maximum call duration. Any ongoing call reaching this duration threshold will be compulsively cut off. byte value: 0=disable this function, 1-255=max. call duration, unit=minute. Default=0. + [End] + " + ::= { CPC 7 } + +-- +-- CCF -> Configuration -> E1 Port +-- + + +E1_Port OBJECT-IDENTITY + STATUS current + DESCRIPTION + "E1 Port." + ::= { CCF_Config 4 } + +E1_Interface OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]E1 interface + { + [u]0.0-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF CDMA2K + [v]4[opt]BICC + [v]5[opt]CI-CNF + [v]6[opt]CI-loopback + } + Remark: Set the type of E1 interface for 256 E1 ports. + [End] + " + ::= { E1_Port 1 } + +E1_TG OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : EE + Field : [1]Assign TG + { + [u]0.0-0.7 + [u]input + [v]toDec-high-0 + } + Remark :Assign a trunk group to each E1 port for call routing. A single E1 port points to only one trunk group, multiple E1 port can be assigned the same trunk group. Default=number of the E1 port. + [End] + " + ::= { E1_Port 2 } + +E1_CIC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 4 + Default : 00000000 + Field : [1]E1 CIC + { + [u]0.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark :Circuit identity code, uniquely identify each circuit within a trunk group. CIC of both ends of a circuit must be identical. 256 CIC for dual MSC platform 256 E1 ports. + [End] + " + ::= { E1_Port 3 } + +E1_Media_Control_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 4 + Default : 00000000 + Field : [1]E1 Control Protocol Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Internal + [v]1[opt]MGCP + } + [2]E1 Enable + { + [u]1.0-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]MG Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + [4]Trunk Number + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + Remark :E1 Media Control Attributes + [End] + " + ::= { E1_Port 4 } + +-- +-- CCF -> Configuration -> Channel attributes +-- + + +Channel_Attributes OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Channel attributes." + ::= { CCF_Config 5 } + +Card0_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 1 } + +Card1_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 2 } + +Card2_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 3 } + +Card3_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 4 } + +Card4_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 5 } + +Card5_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 6 } + +Card6_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 7 } + +Card7_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 8 } + +Card8_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 9 } + +Card9_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 10 } + +Card10_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 11 } + +Card11_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 12 } + +Card12_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 13 } + +Card13_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 14 } + +Card14_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 15 } + +Card15_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 16 } + +Card16_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 17 } + +Card17_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 18 } + +Card18_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 19 } + +Card19_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 20 } + +Card20_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 21 } + +Card21_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 22 } + +Card22_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 23 } + +Card23_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 24 } + +Card24_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 25 } + +Card25_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 26 } + +Card26_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 27 } + +Card27_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 28 } + +Card28_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 29 } + +Card29_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 30 } + +Card30_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 31 } + +Card31_Channel OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 3 + Default : 05EEEE + Flag : E1 + Field : [1]Channel flag + { + [u]00.0-00.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]00.1-00.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } + [3]Reserved + { + [u]00.3-00.7 + [u]select + } + [4]LCCP card (0-15) + { + [u]01.0-01.3 + [u]input + [v]toDec-high-0 + } + [5]Reserved + { + [u]01.4-01.7 + [u]select + } + [6]LCCP timeslot (1-15, 17-31) + { + [u]02.0-02.4 + [u]input + [v]toDec-high-0 + } + [7]LCCP E1 (0-7) + { + [u]02.5-02.7 + [u]input + [v]toDec-high-0 + } + Remark: Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. + LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). + LCCP E1 (0-7)=Lease circuit connected E1 (0-7). + LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). + Default=0x05EEEE. + [End] + " + ::= { Channel_Attributes 32 } +-- +--CCF -> CPC_attributes +-- + +CPC_attributes OBJECT-IDENTITY + STATUS current + DESCRIPTION + "CPC attributes." + ::= { CCF_Config 6 } +MSCID OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : [1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + [2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: MSCID + [End] + " + ::= { CPC_attributes 3 } + +-- +-- CCF -> Media_gateway +-- + +Media_gateway OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Media_gateway ." + ::= { CCF_Config 7 } + +MG_Attribute OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 53 + Default : 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field : [1]MG Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]MG IP Address + { + [u]1.0-4.7 + [u]input + [v]keepHex-high-0 + } + [3]MG Name + { + [u]5.0-52.7 + [u]input + [v]toAscii-low-0 + } + Remark: MG Attributes + [End] + " + ::= { Media_gateway 1 } + +-- +-- CCF -> CCF_Status +-- + +CCF_Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Status for CCF ." + ::= { CCF(MSC) 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : + Remark : Version of MSC software (Read only).
+ Byte0: System release version number, based on basic function and structure.
+ Byte1: Software module version number, based on software module.
+ Byte2: Test version, 0=Release version number, 1=Test version number.. + [End] + " + ::= { CCF_Status 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : EE + Flag : S1.3 + Field : [1]Command + { + [u]0.0-0.7 + [u]select + [v]90[opt]Reset + [v]165[opt]Initialize + [v]181[opt]Save parameter + [v]238[opt]No command + } + Remark: Control command for MSC-CPC. + Reset: Used for CPC status initialization. + Initialize: Restore the parameter setup to the default factory setting. + Save parameter: Save the parameters residing in CPC's memory into CPC's harddisk. + [End] + " + ::= { CCF_Status 2 } + +E1_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length : 1 + Default : EE + Field : [1]Quantity of occupied timeslot + { + [u]0.0-0.4 + [u]input + [v]toDec-high-0 + } + + [2]E1 type + { + [u]0.5-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF_CDMA2K + [v]4[opt]BICC + } + Remark : E1 status (read only). + [End] + " + ::= { CCF_Status 4 } + +Channel_Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Channel status (read only)." + ::= { CCF_Status 5 } + +Card0_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 1 } + +Card1_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 2 } + +Card2_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 3 } + +Card3_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 4 } + +Card4_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 5 } + +Card5_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 6 } + +Card6_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 7 } + +Card7_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 8 } + +Card8_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 9 } + +Card9_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 10 } + +Card10_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 11 } + +Card11_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 12 } + +Card12_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 13 } + +Card13_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 14 } + +Card14_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 15 } + +Card15_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length : 1 + Default : 00 + Field : [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + Remark: Card Channel status (read only). + [End] + " + ::= { Channel_Status 16 } + +-- +-- sub system VLR +-- + +VLR OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]sub for VLR . + " + ::= { MSC 5 } + +-- +-- VLR -> Configuration +-- + +VLR_Config OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Configuration for VLR . + " + ::= { VLR 2 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Public parameters . " + ::= { VLR_Config 1 } + +OptAuthReq OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 1 + Default : 00 + Field : [1]Update Location + { + [u]00.0-00.0 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [2]MO + { + [u]00.1-00.1 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [3]MT + { + [u]00.2-00.2 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [4]Spare + { + [u]00.3-00.7 + [u]input + [v]toDec-high-0 + } + Remark :Flag of SIM authentication on MS poweron and MO/MT call. + [End] + " + ::= { Public_Param 1 } + +OptReuseTriplets OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptReuseTriplets + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]double authentication + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Spare + { + [u]00.2-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Flag of reusing authentication triplets in VLR in the case that authentication to HLR is not available. Default=disable. + [End] + " + ::= { Public_Param 2 } + +OptCipReq OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptCipReq + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark : Flag of voice ciphering over air interface by MS. Default=Disable. + [End] + " + ::= { Public_Param 3 } + +OptCiphAlgo OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 4 + Default : 00000000 + Field : [1]OptCiphAlgo + { + [u]00.0-00.7 + [u]select + [v]0[opt]None + [v]1[opt]A5_1 + [v]2[opt]A5_2 + [v]3[opt]A5_3 + [v]4[opt]A5_4 + [v]5[opt]A5_5 + [v]6[opt]A5_6 + [v]7[opt]A5_7 + } + Remark : Voice ciphering algorithm selection. Default=no ciphering. + [End] + " + ::= { Public_Param 4 } + +OptTmsiAlloc OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]TMSI Allocation Option + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Allocate TMSI + [v]2[opt]Reallocate TMSI + } + Remark :Flag of allocating a new TMSI every time a call management service is requested. Default=Disable. + [End] + " + ::= { Public_Param 5 } + +OptEcSetUpAllow OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]OptEcSetUpAllow + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark : Flag of making emergency call for non-registered MS or MS without SIM. Default=Enable. + [End] + " + ::= { Public_Param 7 } + +OptCheckIMEI OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]Update Location + { + [u]00.0-00.0 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [2]MO + { + [u]00.1-00.1 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [3]MT + { + [u]00.2-00.2 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [4]Spare + { + [u]00.3-00.7 + [u]input + [v]toDec-high-0 + } + Remark : Flag of IMEI verification via EIR. Default=no IMEI verification. + [End] + " + ::= { Public_Param 8 } + +OptVlrPurge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : [1]OptVlrPurge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + Remark : Flag of VLR purge. Default=Off. + [End] + " + ::= { Public_Param 9 } + +IdlePeriod2Purge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 3C + Field : [1]IdlePeriod2Purge + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark : Set the threshold of idle time to purge. If a mobile's idle time reaches this threshold, VLR will purge all records of this MS, unit=6 minute. Default=60minutes. + [End] + " + ::= { Public_Param 10 } + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 01 + Field : [1]CDR on/off + { + [u]00.0-00.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + Remark : VLR CDR flag. Default=On. + [End] + " + ::= { Public_Param 11 } + +MSRN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 16 + Default : 8675531240000FFF8675531241000FFF + Field : [3]Start number + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-F + } + [4]End number + { + [u]08.0-15.7 + [u]input + [v]keepHex-low-F + } + Remark : Mobile station roaming number, use 16 bytes (32 digits) to define a range of MSRN. The length of start MSRN and end MSRN must be identical. F=end tag. + [End] + " + ::= { Public_Param 13 } + +-- +-- VLR -> Management +-- + +VLR_Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management for VLR . + " + ::= { VLR 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 3 + Default : 000000 + Field : + Remark : Version of VLR software (Read only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { VLR_Management 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : EE + Flag : S1.2 + Field : [1]Management + { + [u]00.0-00.7 + [u]select + [v]0[opt]Reset VLR + [v]1[opt]Save parameters + } + Remark : Control command for VLR. + Reset: Used to initialize the status of VLR. + Save parameters: Save the parameters residing in memory into harddisk. + [End] + " + ::= { VLR_Management 3 } + +Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length : 1 + Default : 00 + Field : + Remark :Basic status of VLR. + [End] + " + ::= { VLR_Management 4 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-MSS-MIB.txt b/plat/smpp/ut/conf/MIB_files/WXC2-MSS-MIB.txt new file mode 100644 index 0000000..ddb4465 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-MSS-MIB.txt @@ -0,0 +1,54 @@ +WXC2-MSS-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +MSS OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Subsystems for MSS . " + ::= { App 16 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for MSS . " + ::= { MSS 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Management for MSS . " + ::= { Configuration 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance : 1 + Length : 1 + Default : 00 + Field : [1]Command + { + [u]00.0-00.7 + [u]select + [v]4[opt]Shutdown + [v]5[opt]Undefine value + } + Remark : Safely shut down MSS server by stoping MSS process, saving subscriber data to harddisk and shut down the server. + Operation procedures: + 1. Select -Shutdown- at above pulldown menu. + 2. Click -Set- button in this set window. + 3. Click -SET- button on operation page. + [End] + " + ::= { Management 1 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-PPS-MIB.txt b/plat/smpp/ut/conf/MIB_files/WXC2-PPS-MIB.txt new file mode 100644 index 0000000..b566b21 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-PPS-MIB.txt @@ -0,0 +1,13090 @@ +WXC2-PPS-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +PPS OBJECT-IDENTITY + STATUS current + DESCRIPTION + "[SubSystem_Module]Subsystems for PPS . " + ::= { App 6 } + +Public_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " public parameters for MSS . " + ::= { PPS 2 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for PPS . " + ::= { Public_Param 1 } + +Service_Control OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service Control . " + ::= { Configuration 1 } + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]CDR flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + Remark: PPS CDR generation enable or disable. Default=PPS generate CDR. + [End] + " + ::= { Service_Control 1 } + +Blacklist_Threshold OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 05 + Field: [1]Blacklist threshold + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Legal recharge failure, subsciber who breaks the threshold will be marked in black list and suspended from service provisioning. Default=5. + [End] + " + ::= { Service_Control 2 } + +Maximum_Balance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 00100000 + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This value is for overflow prevention. Normally operator doesn't need to change this value. e.g. 5000, and the smallest unit is cent then the maximum allowed balance is 5000 cents. + [End] + " + ::= { Service_Control 3 } + +License_Control OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 0000000000000000 + Field: [1]License + { + [u]00.0-07.7 + [u]input + [v]keepHex-low-E + } + Remark: 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of PPS subscribers for service provider. The new license can not support less PPS subscribers than what the old license supports. + [End] + " + ::= { Service_Control 4 } + +Prompt_Resolution OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Currency resolution + { + [u]00.0-00.1 + [u]select + [v]0[opt]1 + [v]1[opt]10 + [v]2[opt]100 + } + [2]Date format + { + [u]00.2-00.3 + [u]select + [v]0[opt]YYYY-MM-DD + [v]1[opt]DD-MM-YYYY + [v]2[opt]MM-DD-YYYY + } + [3]Currency symbol position + { + [u]00.4-00.4[u]select + [v]0[opt]Front + [v]1[opt]Rear + } + [4]Reserved + { + [u]00.5-00.7 + [u]select + } + Remark: Currency style: Set the number of decimals in account balance SM display format. If account balance=55555 in smallest currency unit: + 1=account balance display in SM is 55555. + 10=account balance display in SM is 5555.5. + 100=account balance display in SM is 555.55. + Default=100. + Date style: Set the date format displayed in SM or announcement. Default=YYYY-MM-DD. + Currency symbol position: Set the position of the currency symbol. + There are two types: at the front of the amount (e.g. $5) or at the rear of the amount (e.g. 5Fr). Default=at the front. + [End] + " + ::= { Service_Control 5 } + +SMS_Sentence OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 5 + Length: 112 + Default: 00596F7572206163636F756E742062616C616E63652069733A000000000000004578706972656420696E3A000000000000000000000000000000000000000000506C6561736520726563686172676520796F7572206163636F756E740000000000000000000000000000000000000000 + Field: [1]SM encode type + { + [u]00.0-00.7 + [u]select + [v]0[opt]7 bit + [v]4[opt]octet + [v]8[opt]unicode + } + [2]Account balance + { + [u]01.0-31.7 + [u]input + [v]toAscii-low-0 + } + [3]expired in + { + [u]32.0-63.7 + [u]input + [v]toAscii-low-0 + } + [4]recharge in time + { + [u]64.0-111.7 + [u]input + [v]toAscii-low-0 + } + Remark: The # of sentence(0-4) refers to differenct language type; + [End] + " + ::= { Service_Control 6 } + +Last_Call_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 5 + Length: 88 + Default: 4C6173742063616C6C2073656E74206F6E3A00000000000000000000000000004C6173742063616C6C207265636569766564206F6E3A200000000000000000004174000000000000546F00000000000046726F6D00000000 + Field: [1]Last call sent on + { + [u]00.0-31.7 + [u]input + [v]toAscii-low-0 + } + [2]Last call received on + { + [u]32.0-63.7 + [u]input + [v]toAscii-low-0 + } + [3]At + { + [u]64.0-71.7 + [u]input + [v]toAscii-low-0 + } + [4]To + { + [u]72.0-79.7 + [u]input + [v]toAscii-low-0 + } + [5]From + { + [u]80.0-87.7 + [u]input + [v]toAscii-low-0 + } + Remark: The # of sentence(0-4) refers to differenct language type. + [End] + " + ::= { Service_Control 7 } + +Currency_Symbol OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 8 + Default: 2400000000000000 + Field: [1]Currency symbol + { + [u]00.0-07.7 + [u]input + [v]toAscii-low-0 + } + Remark: Set the symbol of the local currency in SMS amount display. e.g. $, RMB, EUR, US$, FR$. default=$. In the set window, type the currency symbol. The input symbol will be converted to ASCII code. + Do not input any symbol that not listed on the ASCII code table. ASCII table: 'A'=0x41, 'B'=0x42 ... 'I'=0x49, 'J'=0x4a, 'K'=0x4b ... 'Z'=0x5A, '$'=0x24 + e.g. RMB=0x52 0x4d 0x42, US$=0x55 0x53 0x24 + [End] + " + ::= { Service_Control 8 } + +Third_Party_Info OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Service ID + { + [u]00.0-07.7 + [u]input + [v]toAscii-low-0 + } + [2]Service password + { + [u]08.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: This parameter is a verification for third party ESME when the third party ESME sends a billing request to PPS server. For example, if a subscriber sends a short message via a ESME (e.g. website), the ESME will send a billing request to PPS to debit this subscriber. This billing request must contains a service ID and password to pass the verification. After verification, the subscriber will be debited by the PPS. PPS supports 8 ESME connections. + [End] + " + ::= { Service_Control 9 } + +Basic_Tariff_Zone OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 64 + Length: 9 + Default: 000000000000000000 + Field: [1]MCC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-F + } + [2]MNC + { + [u]02.0-02.7 + [u]input + [v]keepHex-low-F + } + [3]LAC + { + [u]03.0-04.7 + [u]input + [v]toDec-high-0 + } + [4]Cell ID + { + [u]05.0-06.7 + [u]input + [v]toDec-high-0 + } + [5]MO tariff ID + { + [u]07.0-07.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [6]MT tariff ID + { + [u]08.0-08.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: The basic tariff is applied for each calling or called number prefix. The WXC2 System supports 16 MO and MT tariffs (0-15) and 256 billing zones. This parameter defines basic tariff for each billing zone. Each parameter is a combination of MCC, MNC, cell ID, LAC and MO/MT tariff ID. The billing zone may be set as a cell, a LAC or a zone. Normally a single billing zone deploys only one basic tariff. + Each PPS subscriber profile also contains its tariff setup specifying which tariff should be applied for this subscriber. Using either basic tariff zone (location dependent) or tariff in subscriber profile (subscriber dependent) is determined by a parameter -Tariff subscription-. + LAC: If LAC=65536, all LACs in the MCC and MNC use the same basic tariff. + Cell ID: If cell ID=65536, all cells in the LAC use the same basic tariff. + [End] + " + ::= { Service_Control 10 } + +SRF_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SRF parameters . " + ::= { Configuration 2 } + +SRF_Number OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SRF Number. " + ::= { SRF_Param 1 } + +SRF_0_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]SRF 0 number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: E.164 number of SRF 0 (Special Resource Function) entity. + [End] + " + ::= { SRF_Number 1 } + +SRF_1_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]SRF 1 number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: E.164 number of SRF 1 (Special Resource Function) entity. + [End] + " + ::= { SRF_Number 2 } + +Service_Number OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service number . " + ::= { SRF_Param 2 } + +Hotline OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Hotline + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: PPS service center number. Subscriber dials this number to recharge, enquire their account and modify favorite numbers. + [End] + " + ::= { Service_Number 1 } + +Inquiry OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Inquiry number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated PPS number for account (balance and validity) inquiry. + [End] + " + ::= { Service_Number 2 } + +Scratch_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge via scratch card + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via scratch card. + [End] + " + ::= { Service_Number 3 } + +Credit_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge via credit card + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via credit card. + [End] + " + ::= { Service_Number 4 } + +Third_Party_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge other account + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharging other account from MS or PSTN. + [End] + " + ::= { Service_Number 5 } + +Customer_Care_Center OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Customer care center number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number to connect customer care center. + [End] + " + ::= { Service_Number 6 } + +Rechareg_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]Recharge number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Dedicated shortcut number for recharge via scratch card or credit card. + [End] + " + ::= { Service_Number 7 } + +Service_Key OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Service key . " + ::= { SRF_Param 3 } + +Inquiry OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Key for inquiry + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the function key to enquire account balance after entering the PPS service center. + [End] + " + ::= { Service_Key 2 } + +Scratch_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Field: [1]Key for recharging via scratch card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to recharge account via scratch card after entering the PPS service center. + [End] + " + ::= { Service_Key 3 } + +Credit_Card_Recharge OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Key for recharging via credit card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key for recharging account via credit card after entering the PPS service center. + [End] + " + ::= { Service_Key 4 } + +Set_Favorite_Number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 04 + Field: [1]Key to set favorite number + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to set favorite number after entering the PPS service center. + [End] + " + ::= { Service_Key 5 } + +Language_Selection OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 05 + Field: [1]Key for language selection + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to select system language (from 5 available candidates) after entering the PPS service center. All announcements in the PPS service center is played in the system language. + [End] + " + ::= { Service_Key 6 } + +SetPasswd OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 06 + Field: [1]PPS account password + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Define the key to set account password after entering the PPS service center. When recharging account] selecting language] modifying favorite number or seting password] subscriber is asked to pass the password verification. + [End] + " + ::= { Service_Key 7 } + +File_Operation OBJECT-IDENTITY + STATUS current + DESCRIPTION + " File operation . " + ::= { Configuration 3 } + +Import_User_Data OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Command status + { + [u]00.0-00.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading failed + } + [2]Total number sent + { + [u]01.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]Records loaded + { + [u]04.0-06.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. Progress and result of PPS subscriber import. + Total number sent: Total quantity of PPS subscribers requesting import. + Records loaded: Quantity of successfully imported PPS subscribers. + [End] + " + ::= { File_Operation 1 } + +Import_Recharge_Card OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Import recharge card + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. Result of uploading recharge card to PPS. 0=unsuccessful. 1=successful. + [End] + " + ::= { File_Operation 2 } + +New_Tariff_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { File_Operation 3 } + +New_Tariff_Start_Time OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 20050101000000 + Field: [1]Year + { + [u]00.0-01.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]03.0-03.7 + [u]input + [v]keepHex-high-0 + } + [4]Hour + { + [u]04.0-04.7 + [u]input + [v]keepHex-high-0 + } + [5]Minute + { + [u]05.0-05.7 + [u]input + [v]keepHex-high-0 + } + [6]Second + { + [u]06.0-06.7 + [u]input + [v]keepHex-high-0 + } + Remark: Read only. Set start time for new tariff plan. + [End] + " + ::= { File_Operation 4 } + +COS_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS parameters . " + ::= { Configuration 4 } + +COS_0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 0 Parameters. " + ::= { COS_Param 1 } + +Recharge_Promotion_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_0 1 } + +Start_Date_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS0 1 } + +End_Date_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS0 2 } + +Promotion_Bonus_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS0 3 } + +Tariff_Resolution_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_0 2 } + +MO_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS0 1 } + +MT_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS0 2 } + +Tariff_Subscription_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS0 3 } + +Recharge_Card_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS0 4 } + +Account_Control_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_0 3 } + +Min_balance_MO_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS0 1 } + +Maximum_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS0 2 } + +Release_Day_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS0 3 } + +MT_Control_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_0 4 } + +Charge_Flag_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS0 1 } + +Zero_Balance_Control_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS0 2 } + +Validity_Solution_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_0 5 } + +Clear_Balance_Option_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS0 1 } + +Validity_Recharge_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS0 2 } + +Validity_Zero_Balance_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS0 3 } + +Activated_Account_Validity_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS0 4 } + +FF_Number_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS0 5 } + +Support_Credit_Card_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS0 + [End] + " + ::= { Validity_Solution_COS0 6 } + +Credit_Vault_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS0 7 } + +SM_Inquiry_COS0 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_0 6 } + +Feedback_SM_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS0 1 } + +Inquiry_SM_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS0 2 } + +SM_Expiry_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS0 3 } + +SM_Low_Balance_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS0 4 } + +COS_1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 1 Parameters. " + ::= { COS_Param 2 } + +Recharge_Promotion_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_1 1 } + +Start_Date_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS1 1 } + +End_Date_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS1 2 } + +Promotion_Bonus_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS1 3 } + +Tariff_Resolution_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_1 2 } + +MO_Tariff_ID_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS1 1 } + +MT_Tariff_ID_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS1 2 } + +Tariff_Subscription_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS1 3 } + +Recharge_Card_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS1 4 } + +Account_Control_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_1 3 } + +Min_balance_MO_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS1 1 } + +Maximum_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS1 2 } + +Release_Day_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS1 3 } + +MT_Control_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_1 4 } + +Charge_Flag_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS1 1 } + +Zero_Balance_Control_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS1 2 } + +Validity_Solution_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_1 5 } + +Clear_Balance_Option_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS1 1 } + +Validity_Recharge_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS1 2 } + +Validity_Zero_Balance_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS1 3 } + +Activated_Account_Validity_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS1 4 } + +FF_Number_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS1 5 } + +Support_Credit_Card_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS1 6 } + +Credit_Vault_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS1 7 } + +SM_Inquiry_COS1 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_1 6 } + +Feedback_SM_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS1 1 } + +Inquiry_SM_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS1 2 } + +SM_Expiry_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS1 3 } + +SM_Low_Balance_COS1 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS1 4 } + +COS_2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 2 Parameters. " + ::= { COS_Param 3 } + +Recharge_Promotion_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_2 1 } + +Start_Date_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS2 1 } + +End_Date_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS2 2 } + +Promotion_Bonus_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS2 3 } + +Tariff_Resolution_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_2 2 } + +MO_Tariff_ID_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS2 1 } + +MT_Tariff_ID_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS2 2 } + +Tariff_Subscription_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS2 3 } + +Recharge_Card_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS2 4 } + +Account_Control_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_2 3 } + +Min_balance_MO_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS2 1 } + +Maximum_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS2 2 } + +Release_Day_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS2 3 } + +MT_Control_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_2 4 } + +Charge_Flag_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS2 1 } + +Zero_Balance_Control_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS2 2 } + +Validity_Solution_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_2 5 } + +Clear_Balance_Option_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS2 1 } + +Validity_Recharge_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS2 2 } + +Validity_Zero_Balance_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS2 3 } + +Activated_Account_Validity_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS2 4 } + +FF_Number_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Free times of changing: set total times of free change for family number if charge is enabled. Maximum is 15. + [End] + " + ::= { Validity_Solution_COS2 5 } + +Support_Credit_Card_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS2 6 } + +Credit_Vault_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS2 7 } + +SM_Inquiry_COS2 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_2 6 } + +Feedback_SM_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS2 1 } + +Inquiry_SM_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS2 2 } + +SM_Expiry_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS2 3 } + +SM_Low_Balance_COS2 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS2 4 } + +COS_3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 3 Parameters. " + ::= { COS_Param 4 } + +Recharge_Promotion_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_3 1 } + +Start_Date_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS3 1 } + +End_Date_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS3 2 } + +Promotion_Bonus_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS3 3 } + +Tariff_Resolution_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_3 2 } + +MO_Tariff_ID_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS3 1 } + +MT_Tariff_ID_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS3 2 } + +Tariff_Subscription_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS3 3 } + +Recharge_Card_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS3 4 } + +Account_Control_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_3 3 } + +Min_balance_MO_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS3 1 } + +Maximum_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS3 2 } + +Release_Day_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS3 3 } + +MT_Control_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_3 4 } + +Charge_Flag_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS3 1 } + +Zero_Balance_Control_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS3 2 } + +Validity_Solution_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_3 5 } + +Clear_Balance_Option_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS3 1 } + +Validity_Recharge_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS3 2 } + +Validity_Zero_Balance_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS3 3 } + +Activated_Account_Validity_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS3 4 } + +FF_Number_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS3 5 } + +Support_Credit_Card_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS3 6 } + +Credit_Vault_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS3 7 } + +SM_Inquiry_COS3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_3 6 } + +Feedback_SM_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS3 1 } + +Inquiry_SM_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS3 2 } + +SM_Expiry_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS3 3 } + +SM_Low_Balance_COS3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS3 4 } + +COS_4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 4 Parameters. " + ::= { COS_Param 5 } + +Recharge_Promotion_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_4 1 } + +Start_Date_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS4 1 } + +End_Date_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS4 2 } + +Promotion_Bonus_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS4 3 } + +Tariff_Resolution_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_4 2 } + +MO_Tariff_ID_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS4 1 } + +MT_Tariff_ID_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS4 2 } + +Tariff_Subscription_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS4 3 } + +Recharge_Card_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS4 4 } + +Account_Control_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_4 3 } + +Min_balance_MO_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS4 1 } + +Maximum_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS4 2 } + +Release_Day_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS4 3 } + +MT_Control_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_4 4 } + +Charge_Flag_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS4 1 } + +Zero_Balance_Control_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS4 2 } + +Validity_Solution_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_4 5 } + +Clear_Balance_Option_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS4 1 } + +Validity_Recharge_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS4 2 } + +Validity_Zero_Balance_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS4 3 } + +Activated_Account_Validity_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS4 4 } + +FF_Number_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS4 5 } + +Support_Credit_Card_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS4 6 } + +Credit_Vault_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS4 7 } + +SM_Inquiry_COS4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_4 6 } + +Feedback_SM_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS4 1 } + +Inquiry_SM_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS4 2 } + +SM_Expiry_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS4 3 } + +SM_Low_Balance_COS4 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS4 4 } + +COS_5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 5 Parameters. " + ::= { COS_Param 6 } + +Recharge_Promotion_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_5 1 } + +Start_Date_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS5 1 } + +End_Date_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS5 2 } + +Promotion_Bonus_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS5 3 } + +Tariff_Resolution_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_5 2 } + +MO_Tariff_ID_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS5 1 } + +MT_Tariff_ID_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] Select a MT tariff for this COS. The COS ID is included in subscriber profile for MT call charge. Total 16 MT tariffs available. + " + ::= { Tariff_Resolution_COS5 2 } + +Tariff_Subscription_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS5 3 } + +Recharge_Card_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS5 4 } + +Account_Control_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_5 3 } + +Min_balance_MO_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS5 1 } + +Maximum_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS5 2 } + +Release_Day_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS5 3 } + +MT_Control_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_5 4 } + +Charge_Flag_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS5 1 } + +Zero_Balance_Control_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS5 2 } + +Validity_Solution_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_5 5 } + +Clear_Balance_Option_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS5 1 } + +Validity_Recharge_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS5 2 } + +Validity_Zero_Balance_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS5 3 } + +Activated_Account_Validity_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS5 4 } + +FF_Number_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS5 5 } + +Support_Credit_Card_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS5 6 } + +Credit_Vault_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS5 7 } + +SM_Inquiry_COS5 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_5 6 } + +Feedback_SM_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS5 1 } + +Inquiry_SM_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS5 2 } + +SM_Expiry_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS5 3 } + +SM_Low_Balance_COS5 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS5 4 } + +COS_6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 6 Parameters. " + ::= { COS_Param 7 } + +Recharge_Promotion_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_6 1 } + +Start_Date_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS6 1 } + +End_Date_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS6 2 } + +Promotion_Bonus_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS6 3 } + +Tariff_Resolution_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_6 2 } + +MO_Tariff_ID_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS6 1 } + +MT_Tariff_ID_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS6 2 } + +Tariff_Subscription_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS6 3 } + +Recharge_Card_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS6 4 } + +Account_Control_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_6 3 } + +Min_balance_MO_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS6 1 } + +Maximum_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS6 2 } + +Release_Day_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS6 3 } + +MT_Control_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_6 4 } + +Charge_Flag_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS6 1 } + +Zero_Balance_Control_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS6 2 } + +Validity_Solution_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_6 5 } + +Clear_Balance_Option_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS6 1 } + +Validity_Recharge_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS6 2 } + +Validity_Zero_Balance_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS6 3 } + +Activated_Account_Validity_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS6 4 } + +FF_Number_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS6 5 } + +Support_Credit_Card_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS6 6 } + +Credit_Vault_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS6 7 } + +SM_Inquiry_COS6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_6 6 } + +Feedback_SM_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS6 1 } + +Inquiry_SM_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS6 2 } + +SM_Expiry_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS6 3 } + +SM_Low_Balance_COS6 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS6 4 } + +COS_7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 7 Parameters. " + ::= { COS_Param 8 } + +Recharge_Promotion_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_7 1 } + +Start_Date_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS7 1 } + +End_Date_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS7 2 } + +Promotion_Bonus_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS7 3 } + +Tariff_Resolution_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_7 2 } + +MO_Tariff_ID_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS7 1 } + +MT_Tariff_ID_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS7 2 } + +Tariff_Subscription_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS7 3 } + +Recharge_Card_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS7 4 } + +Account_Control_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_7 3 } + +Min_balance_MO_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS7 1 } + +Maximum_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS7 2 } + +Release_Day_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS7 3 } + +MT_Control_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_7 4 } + +Charge_Flag_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS7 1 } + +Zero_Balance_Control_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS7 2 } + +Validity_Solution_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_7 5 } + +Clear_Balance_Option_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS7 1 } + +Validity_Recharge_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS7 2 } + +Validity_Zero_Balance_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS7 3 } + +Activated_Account_Validity_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS7 4 } + +FF_Number_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS7 5 } + +Support_Credit_Card_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS7 6 } + +Credit_Vault_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS7 7 } + +SM_Inquiry_COS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_7 6 } + +Feedback_SM_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS7 1 } + +Inquiry_SM_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS7 2 } + +SM_Expiry_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS7 3 } + +SM_Low_Balance_COS7 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS7 4 } + +COS_8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 8 Parameters. " + ::= { COS_Param 9 } + +Recharge_Promotion_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_8 1 } + +Start_Date_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS8 1 } + +End_Date_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS8 2 } + +Promotion_Bonus_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS8 3 } + +Tariff_Resolution_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_8 2 } + +MO_Tariff_ID_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS8 1 } + +MT_Tariff_ID_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS8 2 } + +Tariff_Subscription_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS8 3 } + +Recharge_Card_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS8 4 } + +Account_Control_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_8 3 } + +Min_balance_MO_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS8 1 } + +Maximum_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS8 2 } + +Release_Day_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS8 3 } + +MT_Control_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_8 4 } + +Charge_Flag_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS8 1 } + +Zero_Balance_Control_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS8 2 } + +Validity_Solution_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_8 5 } + +Clear_Balance_Option_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS8 1 } + +Validity_Recharge_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS8 2 } + +Validity_Zero_Balance_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS8 3 } + +Activated_Account_Validity_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS8 4 } + +FF_Number_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS8 5 } + +Support_Credit_Card_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS8 6 } + +Credit_Vault_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS8 7 } + +SM_Inquiry_COS8 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_8 6 } + +Feedback_SM_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS8 1 } + +Inquiry_SM_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS8 2 } + +SM_Expiry_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS8 3 } + +SM_Low_Balance_COS8 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS8 4 } + +COS_9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 9 Parameters. " + ::= { COS_Param 10 } + +Recharge_Promotion_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_9 1 } + +Start_Date_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS9 1 } + +End_Date_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS9 2 } + +Promotion_Bonus_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS9 3 } + +Tariff_Resolution_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_9 2 } + +MO_Tariff_ID_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS9 1 } + +MT_Tariff_ID_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS9 2 } + +Tariff_Subscription_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS9 3 } + +Recharge_Card_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS9 4 } + +Account_Control_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_9 3 } + +Min_balance_MO_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS9 1 } + +Maximum_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS9 2 } + +Release_Day_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS9 3 } + +MT_Control_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_9 4 } + +Charge_Flag_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS9 1 } + +Zero_Balance_Control_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS9 2 } + +Validity_Solution_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_9 5 } + +Clear_Balance_Option_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS9 1 } + +Validity_Recharge_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS9 2 } + +Validity_Zero_Balance_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS9 3 } + +Activated_Account_Validity_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS9 4 } + +FF_Number_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS9 5 } + +Support_Credit_Card_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS9 6 } + +Credit_Vault_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS9 7 } + +SM_Inquiry_COS9 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_9 6 } + +Feedback_SM_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS9 1 } + +Inquiry_SM_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS9 2 } + +SM_Expiry_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS9 3 } + +SM_Low_Balance_COS9 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS9 4 } + +COS_10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 10 Parameters. " + ::= { COS_Param 11 } + +Recharge_Promotion_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_10 1 } + +Start_Date_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS10 1 } + +End_Date_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS10 2 } + +Promotion_Bonus_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS10 3 } + +Tariff_Resolution_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_10 2 } + +MO_Tariff_ID_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS10 1 } + +MT_Tariff_ID_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS10 2 } + +Tariff_Subscription_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS10 3 } + +Recharge_Card_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS10 4 } + +Account_Control_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_10 3 } + +Min_balance_MO_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS10 1 } + +Maximum_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS10 2 } + +Release_Day_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS10 3 } + +MT_Control_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_10 4 } + +Charge_Flag_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS10 1 } + +Zero_Balance_Control_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS10 2 } + +Validity_Solution_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_10 5 } + +Clear_Balance_Option_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS10 1 } + +Validity_Recharge_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS10 2 } + +Validity_Zero_Balance_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS10 3 } + +Activated_Account_Validity_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS10 4 } + +FF_Number_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS10 5 } + +Support_Credit_Card_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS10 6 } + +Credit_Vault_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS10 7 } + +SM_Inquiry_COS10 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_10 6 } + +Feedback_SM_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS10 1 } + +Inquiry_SM_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS10 2 } + +SM_Expiry_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS10 3 } + +SM_Low_Balance_COS10 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS10 4 } + +COS_11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 11 Parameters. " + ::= { COS_Param 12 } + +Recharge_Promotion_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_11 1 } + +Start_Date_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS11 1 } + +End_Date_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS11 2 } + +Promotion_Bonus_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS11 3 } + +Tariff_Resolution_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_11 2 } + +MO_Tariff_ID_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS11 1 } + +MT_Tariff_ID_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS11 2 } + +Tariff_Subscription_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS11 3 } + +Recharge_Card_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS11 4 } + +Account_Control_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_11 3 } + +Min_balance_MO_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS11 1 } + +Maximum_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS11 2 } + +Release_Day_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS11 3 } + +MT_Control_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_11 4 } + +Charge_Flag_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS11 1 } + +Zero_Balance_Control_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS11 2 } + +Validity_Solution_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_11 5 } + +Clear_Balance_Option_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS11 1 } + +Validity_Recharge_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS11 2 } + +Validity_Zero_Balance_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS11 3 } + +Activated_Account_Validity_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS11 4 } + +FF_Number_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS11 5 } + +Support_Credit_Card_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS11 6 } + +Credit_Vault_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS11 7 } + +SM_Inquiry_COS11 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_11 6 } + +Feedback_SM_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS11 1 } + +Inquiry_SM_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS11 2 } + +SM_Expiry_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS11 3 } + +SM_Low_Balance_COS11 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS11 4 } + +COS_12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 12 Parameters. " + ::= { COS_Param 13 } + +Recharge_Promotion_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_12 1 } + +Start_Date_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS12 1 } + +End_Date_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS12 2 } + +Promotion_Bonus_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS12 3 } + +Tariff_Resolution_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_12 2 } + +MO_Tariff_ID_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS12 1 } + +MT_Tariff_ID_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS12 2 } + +Tariff_Subscription_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS12 3 } + +Recharge_Card_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS12 4 } + +Account_Control_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_12 3 } + +Min_balance_MO_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS12 1 } + +Maximum_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS12 2 } + +Release_Day_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS12 3 } + +MT_Control_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_12 4 } + +Charge_Flag_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS12 1 } + +Zero_Balance_Control_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS12 2 } + +Validity_Solution_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_12 5 } + +Clear_Balance_Option_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS12 1 } + +Validity_Recharge_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS12 2 } + +Validity_Zero_Balance_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS12 3 } + +Activated_Account_Validity_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS12 4 } + +FF_Number_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS12 5 } + +Support_Credit_Card_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS12 6 } + +Credit_Vault_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS12 7 } + +SM_Inquiry_COS12 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_12 6 } + +Feedback_SM_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS12 1 } + +Inquiry_SM_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS12 2 } + +SM_Expiry_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS12 3 } + +SM_Low_Balance_COS12 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS12 4 } + +COS_13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 13 Parameters. " + ::= { COS_Param 14 } + +Recharge_Promotion_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_13 1 } + +Start_Date_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS13 1 } + +End_Date_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS13 2 } + +Promotion_Bonus_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS13 3 } + +Tariff_Resolution_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_13 2 } + +MO_Tariff_ID_COS0 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS13 1 } + +MT_Tariff_ID_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS13 2 } + +Tariff_Subscription_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS13 3 } + +Recharge_Card_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS13 4 } + +Account_Control_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_13 3 } + +Min_balance_MO_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS13 1 } + +Maximum_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS13 2 } + +Release_Day_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS13 3 } + +MT_Control_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_13 4 } + +Charge_Flag_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS13 1 } + +Zero_Balance_Control_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS13 2 } + +Validity_Solution_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_13 5 } + +Clear_Balance_Option_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS13 1 } + +Validity_Recharge_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS13 2 } + +Validity_Zero_Balance_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS13 3 } + +Activated_Account_Validity_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS13 4 } + +FF_Number_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS13 5 } + +Support_Credit_Card_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS13 6 } + +Credit_Vault_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS13 7 } + +SM_Inquiry_COS13 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_13 6 } + +Feedback_SM_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS13 1 } + +Inquiry_SM_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS13 2 } + +SM_Expiry_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS13 3 } + +SM_Low_Balance_COS13 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS13 4 } + +COS_14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 14 Parameters. " + ::= { COS_Param 15 } + +Recharge_Promotion_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_14 1 } + +Start_Date_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS14 1 } + +End_Date_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS14 2 } + +Promotion_Bonus_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS14 3 } + +Tariff_Resolution_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_14 2 } + +MO_Tariff_ID_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS14 1 } + +MT_Tariff_ID_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS14 2 } + +Tariff_Subscription_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS14 3 } + +Recharge_Card_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS14 4 } + +Account_Control_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_14 3 } + +Min_balance_MO_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS14 1 } + +Maximum_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS14 2 } + +Release_Day_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS14 3 } + +MT_Control_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_14 4 } + +Charge_Flag_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS14 1 } + +Zero_Balance_Control_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS14 2 } + +Validity_Solution_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_14 5 } + +Clear_Balance_Option_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS14 1 } + +Validity_Recharge_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS14 2 } + +Validity_Zero_Balance_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS14 3 } + +Activated_Account_Validity_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS14 4 } + +FF_Number_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS14 5 } + +Support_Credit_Card_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS14 6 } + +Credit_Vault_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS14 7 } + +SM_Inquiry_COS14 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_14 6 } + +Feedback_SM_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS14 1 } + +Inquiry_SM_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS14 2 } + +SM_Expiry_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS14 3 } + +SM_Low_Balance_COS14 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS14 4 } + +COS_15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " COS 15 Parameters. " + ::= { COS_Param 16 } + +Recharge_Promotion_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Recharge Promotion. " + ::= { COS_15 1 } + +Start_Date_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is + valid. Operator defines the promotion period by specifying the start and end + date. Each COS may have its own promotion period. Subscriber recharges his + account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS15 1 } + +End_Date_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Year: 20 + { + [u]00.0-00.7 + [u]input + [v]keepHex-high-0 + } + [2]Month + { + [u]01.0-01.7 + [u]input + [v]keepHex-high-0 + } + [3]Day + { + [u]02.0-02.7 + [u]input + [v]keepHex-high-0 + } + Remark: The promotion period is the period of time in which the recharge promotion is valid. Operator + defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. + Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. + To turn off the recharge promotion, set the start and end date as 000000. + [End] + " + ::= { Recharge_Promotion_COS15 2 } + +Promotion_Bonus_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 9 + Default: 000000000000000000 + Field: [1]Recharge card credit + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + [2]Promotion bonus + { + [u]04.0-07.7 + [u]input + [v]toDec-high-0 + } + [3]Bonus validity + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + Remark: Promotion bonus is the extra credit that a subscriber will get when he recharges his account + in the promotion period. The amount of the bonus is determined by the recharge card credit. + Operator may set the bonus for four types of recharge card of each COS. Generally the recharge + card with higher credit is awarded more bonus. + Please note that the promotion bonus is only applicable for paying call charging. It can't be + used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be + deducted prior to the recharge card credit. + Promotion bonus validity is the period of time that the bonus is valid. Bonus over the + validity period will be obsolete and deleted from account balance. That means the subscriber + must consume his entire promotion bonus within the time frame set by the operator. The operator + has the total freedom to design the validity period - shorter, same or longer than the validity + period of the recharge credit. + [End] + " + ::= { Recharge_Promotion_COS15 3 } + +Tariff_Resolution_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Tariff Resolution. " + ::= { COS_15 2 } + +MO_Tariff_ID_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk + to PPS memory after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS15 1 } + +MT_Tariff_ID_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT tariff ID + { + [u]00.0-00.7 + [u]select + [v]00[opt]00 + [v]01[opt]01 + [v]02[opt]02 + [v]03[opt]03 + [v]04[opt]04 + [v]05[opt]05 + [v]06[opt]06 + [v]07[opt]07 + [v]08[opt]08 + [v]09[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + Remark: Select a MT tariff for this COS. The COS ID is included in subscriber profile + for MT call charge. Total 16 MT tariffs available. + [End] + " + ::= { Tariff_Resolution_COS15 2 } + +Tariff_Subscription_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Charge by + { + [u]00.0-00.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + Remark: PPS basic tariff may be applied on either area (parameter Basic tariff zone) + or subscriber (Tariff ID in subscriber profile) basis. This parameter defines + which one is preference when debiting a subscriber. + [End] + " + ::= { Tariff_Resolution_COS15 3 } + +Recharge_Card_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 4 + Length: 6 + Default: 000000000000 + Field: [1]Face value + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + [2]MO validity + { + [u]02.0-03.7 + [u]input + [v]toDec-high-0 + } + [3]MT validity + { + [u]04.0-05.7 + [u]input + [v]toDec-high-0 + } + Remark: Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory + after submitting the new tariff to the PPS harddisk + consequently enable the new tariff startup. + [End] + " + ::= { Tariff_Resolution_COS15 4 } + +Account_Control_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Account control . " + ::= { COS_15 3 } + +Min_balance_MO_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0000 + Field: [1]Set threshold for MO call + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } + [2]Minimum balance for MO call + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Set a minimum balance for MO call. The subscriber whose balance is below this + threshold can't make MO call. The unit of the minimum balance is the smallest + unit of currency. + [End] + " + ::= { Account_Control_COS15 1 } + +Maximum_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Maximum account balance + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Specify the legal maximum balance, unit is the minimum currency unit. This + value is for overflow prevention. Normally operator doesn't need to change + this value. e.g. 5000, and the smallest unit is cent then the maximum allowed + balance is 5000 cents. + [End] + " + ::= { Account_Control_COS15 2 } + +Release_Day_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 02DA + Field: [1]Release day + { + [u]00.0-01.7 + [u]input + [v]toDec-high-0 + } + Remark: Number of days to hold an expiried prepaid account. After these release days, + if the expired prepaid user does't recharge his account, his account will be released. After + released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + [End] + " + ::= { Account_Control_COS15 3 } + +MT_Control_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MT control . " + ::= { COS_15 4 } + +Charge_Flag_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + Remark: Enable or disable MT call charge for prepaid subscriber. + [End] + " + ::= { MT_Control_COS15 1 } + +Zero_Balance_Control_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Field: [1]Zero balance MT call + { + [u]00.0-00.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + Remark: Enable or disable (MT) incoming calls when balance reaches zero. + [End] + " + ::= { MT_Control_COS15 2 } + +Validity_Solution_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Validity solution . " + ::= { COS_15 5 } + +Clear_Balance_Option_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]When account expires + { + [u]00.0-00.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]00.1-00.1[u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if clear off balance when an account expires or released. + If the balance is cleared] the balance will not be reused anyway. + [End] + " + ::= { Validity_Solution_COS15 1 } + +Validity_Recharge_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity after recharge + { + [u]00.0-00.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + Remark: Set account validity increasement mode after a successful recharge. Accumulate: + the validity of the recharged money will be accumulated to the recharged account. + Replace: if the validity of the recharged money is more than the current account + validity, the account validity will be replaced by the validity of recharged money, + if the validity of the recharged money is less than the current account validity] the + account validity will not be changed after a successful recharge. + [End] + " + ::= { Validity_Solution_COS15 2 } + +Validity_Zero_Balance_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Validity on zero balance + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } + [2]Days + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the + validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity + to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for + a zero balance account. If a zero balance account's current validity is less than the preset adjustment + validity] the system will keep this account's current validity. e.g. If this function is enabled] + and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] + his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter + Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + [End] + " + ::= { Validity_Solution_COS15 3 } + +Activated_Account_Validity_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Activation by inquiring + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Validity of activated account with zero balance + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Set validity for an account who is activated from fresh status by dialing inquiry + number. The unit is day. Defaul=30 days. + [End] + " + ::= { Validity_Solution_COS15 4 } + +FF_Number_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: f5 + Field: [1]CUG serivce flag + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]00.6-00.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]00.5-00.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [4]Reserved + { + [u]00.4-00.4 + [u]select + } + [5]Free times of changing + { + [u]00.0-00.3 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge for changing family number. Free times of changing: set total times + of free change for family number if charge is enabled. Maximum is 15 + [End] + " + ::= { Validity_Solution_COS15 5 } + +Support_Credit_Card_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Support credit card flag + { + [u]00.0-00.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + Remark: Support_Credit_Card_COS + [End] + " + ::= { Validity_Solution_COS15 6 } + +Credit_Vault_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1064 + Field: [1]Support credit vault + { + [u]01.7-01.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } + [2]Credit vault + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: When a subscriber is rejected to make a call because of the insufficient balance, he may select + to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft + (credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + [End] + " + ::= { Validity_Solution_COS15 7 } + +SM_Inquiry_COS15 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SM inquiry notification . " + ::= { COS_15 6 } + +Feedback_SM_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]Send SM for recharge result + { + [u]00.0-00.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]00.1-00.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Reserved + { + [u]00.2-00.7 + [u]select + } + Remark: Set if send feedback short message for balance inquiry or recharge operation. + [End] + " + ::= { SM_Inquiry_COS15 1 } + +Inquiry_SM_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 83 + Field: [1]Charge on inquiry SM + { + [u]00.7-00.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } + [2]Free SM every day + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) + to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if + charge is enabled. Maximum is 128. + [End] + " + ::= { SM_Inquiry_COS15 2 } + +SM_Expiry_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 8a + Field: [1]Send SM notification + { + [u]00.7-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Days prior to expiry date + { + [u]00.0-00.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account is going to expire. If the Days + is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire + in five days. + [End] + " + ::= { SM_Inquiry_COS15 3 } + +SM_Low_Balance_COS15 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 81F4 + Field: [1]Send SM notification + { + [u]01.7-01.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Balance level to send SM + { + [u]00.0-01.6 + [u]input + [v]toDec-high-0 + } + Remark: Enable or disable sending notification short message when an account's balance is too low. + Balance level to send SM: set a low balance for short message notification. PPS will send + a notification short message to an subscriber whose balance is no more than the preset low + balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, + the PPS will send the notification SM to this subscriber indicating low balance. + [End] + " + ::= { SM_Inquiry_COS15 4 } + +Call_Routing_VMS OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Call routing to VMS . " + ::= { Configuration 5 } + +VMS_PLMN_Maintenance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS service number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 1 } + +VMS_PSTN_Maintenance OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS service number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 2 } + +--VMS_Deposit_Number OBJECT-TYPE +-- SYNTAX OCTET STRING +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- " Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. +-- " +-- ::= { Call_Routing_VMS 3 } + +VMS_leave_msg_No OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 16 + Default: 00000000000000000000000000000000 + Field: [1]VMS deposit number + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + Remark: Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + [End] + " + ::= { Call_Routing_VMS 3 } + +--Access_VoiceBox OBJECT-TYPE +-- SYNTAX OCTET STRING +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- " Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. +-- " +-- ::= { Call_Routing_VMS 4 } + +Rule OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]Route by + { + [u]00.0-00.0 + [u]select + [v]0[opt]Prefix + [v]1[opt]Whole number + } + [2]Route + { + [u]00.1-00.1 + [u]select + [v]0[opt]Caller number + [v]1[opt]Called number + } + [3]Reserved + { + [u]00.2-00.7 + [u]input + [v]toDec-high-0 + } + Remark: rule + [End] + " + ::= { Call_Routing_VMS 4 } + +VMS_User_Segments OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 80 + Default: 3836373535393030303030000000000038363735353939393939390000000000383637353539393830300000000000003836373535393938303100000000000038363735353939383032000000000000 + Field: [1]Start MSISDN + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + [2]End MSISDN + { + [u]16.0-31.7 + [u]input + [v]toAscii-low-0 + } + [3]VMS service number - PLMN + { + [u]32.0-47.7 + [u]input + [v]toAscii-low-0 + } + [4]VMS service number - PSTN + { + [u]48.0-63.7 + [u]input + [v]toAscii-low-0 + } + [5]Leave message deposit number + { + [u]64.0-79.7 + [u]input + [v]toAscii-low-0 + } + Remark: VMS user segments + [End] + " + ::= { Call_Routing_VMS 5 } + +Status OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Status. " + ::= { Configuration 6 } + +Activation OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]System status + { + [u]00.0-00.7 + [u]select + [v]0[opt]Normal + } + Remark: Set PPS system status. 0=normal. After initial PPS installation, if the PPS system doesn't has subscriber profiles, its status is suspended. In this case operator may set this parameter (normal) to activate the PPS server. + [End] + " + ::= { Status 1 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag : S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]1[opt]Save parameters + [v]2[opt]Save user data + } + Remark: PPS management command. + Save parameters: Save PPS parameters in PPS memory to PPS hard disk. + Save user data: Save PPS subscriber data in PPS memory to PPS hard disk. + [End] + " + ::= { Status 2 } + +END \ No newline at end of file diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-SMI.txt b/plat/smpp/ut/conf/MIB_files/WXC2-SMI.txt new file mode 100644 index 0000000..4841a50 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-SMI.txt @@ -0,0 +1,57 @@ +-- ***************************************************************** +-- WXC2-SMI: WXC2 Structure of Management Information +-- +-- draft November 2000, Huang qilong +-- 1st November 2004, Sheng Xueqiang +-- +-- Copyright (c) 2004 by interWAVE, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- + +WXC2-SMI DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, + OBJECT-IDENTITY, + FROM SNMPv2-SMI + IWV_Products + FROM IWV-SMI; + +WXC2 MODULE-IDENTITY + LAST-UPDATED "200506050000Z" + ORGANIZATION "interWAVE, Inc." + CONTACT-INFO + "http://www.iwv.com" + DESCRIPTION + "The Structure of Management Information for the WXC2 of interWAVE enterprise." + REVISION "200506050000Z" + DESCRIPTION + "1st version of this MIB module." + ::= { IWV_Products 3 } + +-- WXC2_PCM +PCM OBJECT-IDENTITY + STATUS current + DESCRIPTION + "PCM " + ::= { WXC2 1 } + + +-- WXC2_platform +Platform OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Platform " + ::= { WXC2 2 } + +-- WXC2_App + +App OBJECT-IDENTITY + STATUS current + DESCRIPTION + "App platform" + ::= { WXC2 3 } + +END diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-SMSC-MIB.txt b/plat/smpp/ut/conf/MIB_files/WXC2-SMSC-MIB.txt new file mode 100644 index 0000000..d6a5a82 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-SMSC-MIB.txt @@ -0,0 +1,259 @@ +WXC2-SMSC-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + App + FROM WXC2-SMI; + +SMSC OBJECT-IDENTITY + STATUS current + DESCRIPTION + "[SubSystem_Module]Subsystems for SMSC . " + ::= { App 5 } + +Configuration OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Configuration for SMSC . " + ::= { SMSC 2 } + +System_Param OBJECT-IDENTITY + STATUS current + DESCRIPTION + " system parameter . " + ::= { Configuration 1 } + + + +CDR_Flag OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 03 + Field: [1]SMSC CDR + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [2]SMSC LOG + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [3]Reserved + { + [u]0.2-0.7 + [u]select + } + + Remark: SMSC CDR generation enable or disable. + [End] + " + ::= { System_Param 1 } + +SM_Validity OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 4 + Default: 0000A8C0 + Field: [1]SM validity + { + [u]00.0-03.7 + [u]input + [v]toDec-high-0 + } + Remark: Period of validity of short message, define a threshold how long an awaiting sending message should be kept in sending array till sent to MS, unit is second, default=0c0a8h seconds=12 hours. + [End] + " + ::= { System_Param 2 } + +MSISDN_Segment OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 16 + Length: 19 + Default: 8675557127000EEEEE8675557127999EEEEE00 + Field: [1]Start MSISDN + { + [u]00.0-08.7 + [u]input + [v]keepHex-low-E + } + [2]End MSISDN + { + [u]09.0-17.7 + [u]input + [v]keepHex-low-E + } + [3]Number Type + { + [u]18.0-18.7 + [u]select + [v]0[opt]GSM + [v]1[opt]CDMA + } + Remark: Specify the beginning MSISDN for the range of provisioned subscriber. F=end tag. + [End] + " + ::= { System_Param 3 } + +SMPP_parameters OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 32 + Length: 12 + Default: 000000000000000000000000 + Field: [1]Enable flag + { + [u]00.0-00.7 + [u]select + [v]00[opt]Disable + [v]01[opt]Enable + } + [2]Session type + { + [u]01.0-01.7 + [u]select + [v]00[opt]BIND_TX + [v]01[opt]BIND_RX + [v]02[opt]BIND_TRX + } + [3]Service number + { + [u]02.0-9.7 + [u]input + [v]toAscii-low-0 + } + [4]Message mode + { + [u]10.0-10.7 + [u]select + [v]00[opt]Store and forward + [v]01[opt]Datagram + [v]02[opt]Transaction + } + [5]Data Coding Scheme + { + [u]11.0-11.7 + [u]select + [v]00[opt]To smpp=7bit,default=7bit + [v]01[opt]To smpp=8bit,default=7bit + [v]16[opt]To smpp=7bit,default=8bit + [v]17[opt]To smpp=8bit,default=8bit + } + Remark: Name: Can be any name, generally use the name of the connected device. + Service number: SMPP connected party MSISDN used for display on MT MS, + e.g. for a SMPP to PPS, set the service number as MSISDN of PPS. + Data coding scheme: + 00:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 7bit + 01:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 7bit + 10:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 8bit + 11:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 8bit + Default=0. + [End] + " + ::= { Configuration 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Management for SMSC . + " + ::= { SMSC 3 } + +SMSC_ID OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]SMSC ID + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-E + } + Remark: SMSC ID + [End] + " + ::= { Management 1 } + +Software_Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 7 + Default: 00000000000000 + Field: [1]Version + { + [u]00.0-02.7 + [u]input + [v]keepHex-low-E + } + Remark: Software version + [End] + " + ::= { Management 2 } + +Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 01 + Flag: S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]01[opt]Save parameters + [v]04[opt]Reset system + [v]05[opt]Delete pending SM + } + Remark: SMSC system command. + Save parameters: Save the SMSC parameters in memory to SMSC harddisk. + Delete pending SM: Delete the pending SM in awaiting array. + [End] + " + ::= { Management 3 } + + + +END diff --git a/plat/smpp/ut/conf/MIB_files/WXC2-SS7-MIB.txt b/plat/smpp/ut/conf/MIB_files/WXC2-SS7-MIB.txt new file mode 100644 index 0000000..a642454 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/WXC2-SS7-MIB.txt @@ -0,0 +1,3729 @@ +WXC2-SS7-MIB DEFINITIONS ::= BEGIN +IMPORTS + OBJECT-TYPE, Integer32, Opaque + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, DisplayString, TruthValue + FROM SNMPv2-TC + Platform + FROM WXC2-SMI; + +SS7 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for SS7 . + " + ::= { Platform 2 } + + +-- +-- sub system MTP3 +-- + +MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for MTP3 . + " + ::= { SS7 2 } + +Config_MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MTP3 Configuration. " + ::= { MTP3 2 } + +Network_Indicator OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Field: [1]International network + { + [u]0.0-0.0 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [2]International network spare + { + [u]0.1-0.1 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [3]National network + { + [u]0.2-0.2 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [4]National network spare + { + [u]0.3-0.3 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [5]International network + { + [u]0.4-0.4 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [6]International network spare + { + [u]0.5-0.5 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [7]National network + { + [u]0.6-0.6 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [8]National network spare + { + [u]0.7-0.7 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + Remark: MTP3 network indicator. + [End] + " + ::= { Config_MTP3 2 } + + + + +OPC OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Originating point code. " + ::= { Config_MTP3 3 } + +International_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 1 } + +International_Spare_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 2 } + +National_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 3 } + +National_Spare_14bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 14-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 4 } + +International_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 5 } + +International_Spare_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 6} + +National_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 7 } + +National_Spare_24bit OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: [1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + Remark: 24-bit originating point code (OPC) in an international network. Default=0. + [End] + " + ::= { OPC 8 } + +Linkset OBJECT-IDENTITY + STATUS current + DESCRIPTION + " linkset. " + ::= { Config_MTP3 4 } + +Linkset_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 4 + Default: 00000000 + Field: [1]Linkset DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Network indicator + { + [u]3.0-3.1 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [3]Reserved + { + [u]3.2-3.2 + [u]select + } + [4]Linkset loopback + { + [u]3.3-3.3 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [5]Reserved + { + [u]3.4-3.7 + [u]select + } + Remark: Opposite point code: The opposite point code of the linkset. + Network indicator: The network type of the opposite point code. + Loop back: Loop back enable or disable, used for MSC loop back link. + [End] + " + ::= { Linkset 1 } + +Link OBJECT-IDENTITY + STATUS current + DESCRIPTION + " link. " + ::= { Config_MTP3 5 } + +Link_Attributes OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 15 + Default: 8010FFFFFFFF000000000000000000 + Field: [1]Linkset no. + { + [u]00.0-00.7 + [u]input + [v]toDec-high-0 + } + [2]SLC no. + { + [u]01.0-01.7 + [u]input + [v]toDec-high-0 + } + [3]CPC IP + { + [u]02.0-05.7 + [u]input + [v]keepHex-high-0 + } + [4]Link Type + { + [u]06.0-06.0 + [u]select + [v]0[opt]Non-sigtran + [v]1[opt]Sigtran + } + [5]Link Enable + { + [u]06.1-06.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [6]MTP3-Lite Enable + { + [u]06.2-06.2 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [7]Reserved + { + [u]06.3-06.7 + [u]select + } + [8]SG no. + { + [u]07.0-07.7 + [u]input + [v]toDec-high-0 + } + [9]M2UA Interface ID + { + [u]08.0-08.7 + [u]input + [v]toDec-high-0 + } + [10]MTP3-Lite Remote IP + { + [u]09.0-12.7 + [u]input + [v]keepHex-high-0 + } + [11]MTP3-Lite Inactivity Timeout + { + [u]13.0-13.7 + [u]input + [v]toDec-high-0 + } + [12]MTP3-Lite Allowed Inactivity Timeouts + { + [u]14.0-14.7 + [u]input + [v]toDec-high-0 + } + Remark: E1 link attributes. + Linkset no.: Assign linkset to E1 link, MSC has up to 128 linksets (0-127). 128=TCH E1. + SLC no.: Assign SLC to each E1 link of a linkset, each linkset has up to 13 E1 links (0-15). + IP: E1 link management IP. The third byte of CPC IP: + 98=E1 link 0-127, 99=E1 link 128-255. + Default=0x000032. + [End] + " + ::= { Link 1 } + +Link_Command OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 01 + Field: [1]E1 link + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + [v]2[opt]Inhibit + [v]3[opt]Uninhibit + } + Remark: Used for E1 link control, not affect call traffic. + Disable=Disable E1 link MTP2 layer. + Enable=Enable a disabled E1 link MTP2 layer. + Inhibit=Inhibit E1 link MTP3 layer. + Uninhibit=Uninhibit a inhibited E1 link MTP3 layer. + Default=Enable a disabled E1 link MTP2 layer. + [End] + " + ::= { Link 2 } + +TCP_Port OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-writed + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 1388 + Field: [1]TCP Port + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + Remark: TCP server port for SCCP-Lite. + [End] + " + ::= { Link 3 } + +Routing OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Routing. " + ::= { Config_MTP3 6 } + +International OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 1 } + +International_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 2 } + +National OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 3 } + +National_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 5 + Default: 0000008080 + Field: [1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec-high-0 + } + [2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec-high-0 + } + Remark: Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + [End] + " + ::= { Routing 4 } + +SPC_to_ACN OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SPC to ACN. " + ::= { Config_MTP3 7 } + +Local_ACN OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 1 } + +International OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 2 } + +International_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 3 } + +National OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 4 } + +National_Spare OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 36 + Default: 030303030202020202030302020303020303020303030303030303030303030302020202 + Field: [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + Remark: The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + [End] + " + ::= { SPC_to_ACN 5 } + +Signaling_Gateway OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 7 + Default: 00000000000000 + Field: [1]Enable + { + [u]00.0-00.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Server + { + [u]01.0-01.7 + [u]select + [v]0[opt]Client + [v]1[opt]Server + } + [3]ACK + { + [u]02.0-02.7 + [u]select + [v]0[opt]no ACK + [v]1[opt]ACK + } + [4]IP + { + [u]03.0-06.7 + [u]input + [v]keepHex-high-0 + } + Remark: SG attributes + [End] + " + ::= { Config_MTP3 9 } + +Status_MTP3 OBJECT-IDENTITY + STATUS current + DESCRIPTION + " MTP3 Status. " + ::= { MTP3 3 } + +Link_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 01 + Field: [1]Link status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Inhibited + } + Remark: E1 link MTP3 status (Read Only). + [End] + " + ::= { Status_MTP3 1 } + +Linkset_Status OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 1 + Default: 01 + Field: [1]Linkset status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Reserved + } + Remark: Linkset status (Read only). + [End] + " + ::= { Status_MTP3 2 } + +International_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8A + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 3 } + +International_Spare_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 4 } + +National_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 5 } + +National_Spare_Routing OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 1 + Default: 8a + Field: [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + Remark: Normal linkset status (bit0-1): + - 0=Available + - 1=Reserved + - 2=Unavailable + Alternative linkset status (bit2-3): + - 0=Available + - 1=Reserved + - 2=Unavailable + DPC accessibility (bit4): + - 0=Inaccessible + - 1=Accessible + Current route (bit3-7): + - 0=Normal linkset + - 1=Alternative linkset + - 2=No route. + [End] + " + ::= { Status_MTP3 6 } + + + +Command_MTP3 OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag :S1.3 + Field: [1]command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No command + [v]1[opt]Reset + [v]2[opt]Save parameter + } + Remark: Control command for MTP3 platform. + Reset=status initialization. + Save parameter=save parameters residing in memory into harddisk. + [End] + " + ::= { Status_MTP3 7 } + +-- +-- sub system SCCP +-- + +SCCP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for SCCP . + " + ::= { SS7 3 } + +Config_SCCP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SCCP Configuration. " + ::= { SCCP 2 } + +Local_Node OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Local Node. " + ::= { Config_SCCP 1 } + +OMC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: OMC E.134 number. + IP0: OMC0 IP, 172.18.128.1. + IP1: OMC1 IP, 172.18.129.1. + [End] + " + ::= { Local_Node 4 } + +HLR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: HLR E.134 number. + IP0: HLR0 IP, 172.18.98.1. + IP1: HLR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 6 } + +VLR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VLR E.134 number. + IP0: VLR0 IP, 172.18.98.1. + IP1: VLR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 7 } + +MSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: MSC E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 8 } + +EIR OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: EIR E.134 number. + IP0: EIR0 IP, 172.18.98.1. + IP1: EIR1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 9 } + +AUC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: AUC E.134 number. + IP0: AUC0 IP, 172.18.98.1. + IP1: AUC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 10 } + +SMSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: SMSC E.134 number. + IP0: OMC0 IP, 172.18.98.1. + IP1: OMC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 11 } + +SMPP_EMSE OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VMS-SMPP E.134 number. + IP0: VMS0 IP, 172.18.147.1. + IP1: VMS1 IP, 172.18.148.1. + [End] + " + ::= { Local_Node 19 } + +SMPP_SMSC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: SMSC-SMPP E.134 number. + IP0: SMSC0 IP, 172.18.98.1. + IP1: SMSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 20 } + +SMPP_OMC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: OMC-SMPP E.134 number. + IP0: OMC0 IP, 172.18.128.1. + IP1: OMC1 IP, 172.18.129.1. + [End] + " + ::= { Local_Node 21 } + +SRF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: VMS SRF E.134 number. + IP0: VMS0 IP, 172.18.147.1. + IP1: VMS1 IP, 172.18.148.1. + [End] + " + ::= { Local_Node 22 } + +SSF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: MSC SSF E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 143 } + +SCF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: PPS SCF E.134 number. + IP0: PPS0 IP, 172.18.98.1. + IP1: PPS1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 147 } + +AIF OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 19 + Default: 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + Field: [1]NI + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-F + } + [2]MSISDN + { + [u]01.0-10.7 + [u]input + [v]keepHex-low-F + } + [3]IP0 + { + [u]11.0-14.7 + [u]input + [v]keepHex-low-F + } + [4]IP1 + { + [u]15.0-18.7 + [u]input + [v]keepHex-low-F + } + Remark: NI: Network indicator. + 0=International network. + 1=International network spare. + 2=National network. + 3=National network spare. + MSISDN: AIF E.134 number. + IP0: MSC0 IP, 172.18.98.1. + IP1: MSC1 IP, 172.18.99.1. + [End] + " + ::= { Local_Node 254 } + +GTT_Table OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 43 + Default: 000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000007000000FFFFFFFFFFFFFFFFFFFF + Field: [1]On/off + { + [u]00.0-00.7 + [u]select + [v]1[opt]On + [v]0[opt]Off + } + [2]Numbering plan + { + [u]01.0-01.7 + [u]select + [v]0[opt]0 + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } + [3]TT + { + [u]02.0-02.7 + [u]input + [v]keepHex-low-F + } + [4]Start GT number + { + [u]03.0-12.7 + [u]input + [v]keepHex-low-F + } + [4]End GT number + { + [u]13.0-22.7 + [u]input + [v]keepHex-low-F + } + [5]Network indicator + { + [u]23.0-23.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + } + [6]DPC + { + [u]24.0-26.7 + [u]input + [v]toDec-high-0 + } + [7]SSN + { + [u]27.0-27.7 + [u]input + [v]toDec-high-0 + } + [8]Route indicator + { + [u]28.0-28.7 + [u]select + [v]0[opt]Route on GT + [v]1[opt]Route on SSN + } + [9]Address indicator + { + [u]29.0-29.7 + [u]select + [v]0[opt]NULL + [v]3[opt]DPC+SSN + [v]6[opt]GT+SSN + [v]7[opt]GT+DPC+SSN + } + [10]Replaced start digit + { + [u]30.0-30.7 + [u]input + [v]keepHex-high-0 + } + [11]Replaced end digit + { + [u]31.0-31.7 + [u]input + [v]keepHex-high-0 + } + [12]Outgoing number plan + { + [u]32.0-32.7 + [u]select + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } + [13]Replacing digits + { + [u]33.0-42.7 + [u]input + [v]keepHex-low-F + } + Remark: On/off: GTT flag, off=disable, on=enable. + Numbering plan: 1=MSISDN, 3=IMSI, 7=GT. + Specify the beginning number of a group of consecutive numbers routed by GTT, for single-number GTT route, the start number is same as the end number. + End GT number: Specify the end number of a group of consecutive number routed by GT. If there are some inconsecutive numbers for a same destination, a different GTT record should be set. + Network indicator (NI): 0=International network, 1=International network spare, 2=National network, 3=National network spare, + DPC: Destination point code. + SSN: Subsystem number. + 2=Reserved for ITU-T allocation. + 3=ISDN user part. + 4=OMC. + 5=MAP. + 3=HLR. + 7=VLR. + 8=MSC. + 9=EIR. + 10=AUC. + 11=SMSC. + 147=PPS. + 254=BSSMAP. + Route indicator: For IMSI and MSISDN, select Route on SSN. For the record of the connected network, select Route on GT. + Address indicator: select the contribution of SCCP Address. + Replaced start digit: Specify the beginning digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. + Replaced end digit: Specify the end digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. + Outgoing number plan: Outgoing number plan, include MSISDN, IMSI and GT. + Replacing digits: Replacing digits, the length of replacing digits and replaced digits may be different. + [End] + " + ::= { Config_SCCP 2 } + +Management OBJECT-IDENTITY + STATUS current + DESCRIPTION + " Management. " + ::= { SCCP 3 } + +Version OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: + Remark: Version of SCCP platform software (Read Only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { Management 1 } + +Command_SCCP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag : S1.2 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]0[opt]Reset + [v]2[opt]Save parameters + } + Remark: Control command for SCCP. + Reset: Used for SCCP status initialization. + Load parameter: Load the parameters from device's harddisk to device's memory. + Save parameter: Save the parameters residing in device's memory into device's harddisk. + [End] + " + ::= { Management 2 } + +-- +-- sub system XAPP +-- + +XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for XAPP . + " + ::= { SS7 5 } + +Config_XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Configuration. " + ::= { XAPP 2 } + +MCC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 460E + Field: [1]MCC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + + Remark: Mobile country code. + [End] + " + ::= { Config_XAPP 1 } + +MNC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Field: [1]MNC + { + [u]00.0-00.7 + [u]input + [v]keepHex-low-E + } + Remark: Mobile network code. + [End] + " + ::= { Config_XAPP 2 } + +CC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 86EE + Field: [1]CC + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + Remark: Country code. + [End] + " + ::= { Config_XAPP 3 } + +NDC OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 755EEE + Field: [1]NDC + { + [u]00.0-02.7 + [u]input + [v]keepHex-low-E + } + Remark: National destination code. + [End] + " + ::= { Config_XAPP 4 } + +International_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 00ee + Field: [1]International prefix + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + Remark: International call prefix. + [End] + " + ::= { Config_XAPP 5 } + +National_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: 0EEE + Field: [1]National prefix + { + [u]00.0-01.7 + [u]input + [v]keepHex-low-E + } + + Remark: National call prefix. + [End] + " + ::= { Config_XAPP 6 } + +Local_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 2 + Default: EEEE + Field: + Remark: Local prefix. + [End] + " + ::= { Config_XAPP 7 } + +Conv_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 128 + Length: 35 + Default: 0000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]Prefix + { + [u]00.0-15.7 + [u]input + [v]toAscii-low-0 + } + [2]Delete length + { + [u]16.0-16.7[u]input + [v]toDec-high-0 + } + [3]Add length + { + [u]17.0-17.7 + [u]input + [v]toDec-high-0 + } + [4]Add digits + { + [u]18.0-33.7 + [u]input + [v]toAscii-low-0 + } + [5]Valid length + { + [u]34.0-34.7 + [u]input + [v]toDec-high-0 + } + Remark: Conv prefix . + [End] + " + ::= { Config_XAPP 8 } + +CLI_Conv_Prefix OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 8 + Length: 37 + Default: 0000000000000000000000000000000000000000000000000000000000000000000000 + Field: [1]In property + { + [u]00.0-00.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } + [2]Prefix + { + [u]01.0-16.7 + [u]input + [v]toAscii-low-0 + } + [3]Delete length + { + [u]17.0-17.7 + [u]input + [v]toDec-high-0 + } + [4]Out property + { + [u]18.0-18.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } + [5]Add length + { + [u]19.0-19.7 + [u]input + [v]toDec-high-0 + } + [6]Add digits + { + [u]20.0-35.7 + [u]input + [v]toAscii-low-0 + + } + [7]Valid length + { + [u]36.0-36.7 + [u]input + [v]toDec-high-0 + } + Remark: CLI_Conv prefix . + [End] + " + ::= { Config_XAPP 9 } + +mscid_to_number OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 256 + Length: 12 + Default: 00000000EEEEEEEEEEEEEEEE + Field: + + [1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec-high-0 + } + [2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec-high-0 + } + [3]SSN + { + [u]3.0-3.7 + [u]input + [v]toDec-high-0 + } + [4]Number + { + [u]04.0-11.7 + [u]input + [v]keepHex-low-E + } + Remark: Conv prefix . + [End] + " + ::= { Config_XAPP 10 } + +Status_XAPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Status. " + ::= { XAPP 3 } + +Version_XAPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 3 + Default: 000000 + Field: + Remark: Version of XAPP module (Read Only). + Byte0: System release version number, based on basic function and structure. + Byte1: Software module version number, based on software module. + Byte2: Test version, 0=Release version number, 1=Test version number. + [End] + " + ::= { Status_XAPP 1 } + +Command_XAPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 00 + Flag: S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]01[opt]Save parameters + } + Remark: Control command for XAPP. + Save parameter: Save the parameters in memory into local harddisk. + [End] + " + ::= { Status_XAPP 2 } + +Maplat OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + Subsystems for Maplat . + " + ::= { Platform 3 } +-- +-- sub system SMPP +-- + +SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " + [SubSystem_Module]Subsystems for SMPP . + " + ::= { Maplat 4 } + +Config_SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " SMPP Configuration. " + ::= { SMPP 2 } +SMPP_Link_Parameter OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-write + STATUS current + DESCRIPTION + " + [Begin] + Instance: 32 + Length: 106 + Default: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Field:[1]Link enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Link type + { + [u]1.0-1.7 + [u]select + [v]0[opt]UDP + [v]1[opt]TCP + } + [3]Server type + { + [u]2.0-2.7 + [u]select + [v]0[opt]SMPP_CLIENT + [v]1[opt]SMPP_SERVER + } + [4]Session type + { + [u]3.0-3.7 + [u]select + [v]00[opt]BIND_TX + [v]01[opt]BIND_RX + [v]02[opt]BIND_TRX + } + [5]System ID + { + [u]4.0-19.7 + [u]input + [v]toAscii-low-0 + } + [6]Password + { + [u]20.0-28.7 + [u]input + [v]toAscii-low-0 + } + [7]System type + { + [u]29.0-41.7 + [u]input + [v]toAscii-low-0 + } + [8]Local GTT + { + [u]42.0-57.7 + [u]input + [v]toAscii-low-0 + } + [9]Remote GTT + { + [u]58.0-73.7 + [u]input + [v]toAscii-low-0 + } + [10]Local IP + { + [u]74.0-77.7 + [u]input + [v]keepHex-low-F + } + [11]Remote IP + { + [u]78.0-81.7 + [u]input + [v]keepHex-low-F + } + [12]Session init timer + { + [u]82.0-85.7 + [u]input + [v]toDec-high-0 + } + [13]Enquire link timer + { + [u]86.0-89.7 + [u]input + [v]toDec-high-0 + } + [14]Inactivity timer + { + [u]90.0-93.7 + [u]input + [v]toDec-high-0 + } + [15]Response timer + { + [u]94.0-97.7 + [u]input + [v]toDec-high-0 + } + [16]Remote service number + { + [u]98.0-105.7 + [u]input + [v]toAscii-low-0 + } + + Remark: Session type: BIND_TX-bind as transmitter, BIND_RX-bind as receiver, BIND_TRX-bind as transceiver. + System ID: using in BIND and OUTBIND. + Password: The password parameter is used by the SMSC to authenticate the identity of the binding ESME. The Service Provider may require ESME¡¯s to provide a password when binding to the SMSC. This password is normally issued by the SMSC system administrator. + The password parameter may also be used by the ESME to authenticate the identity of the binding SMSC (e.g. in the case of the outbind operation). + System type: The system_type may be used to categorise the system, e.g., ¡°EMAIL¡±, ¡°WWW¡±, etc. + The system_type parameter is used to categorize the type of ESME that is binding to the SMSC. Examples include ¡°VMS¡± (voice mail system) and ¡°OTA¡± (over-the-air activation system). + Specification of the system_type is optional - some SMSC¡¯s may not require ESME¡¯s to provide this detail. In this case, the ESME can set the system_type to NULL. + IP: Specify the IP addresses of 16 SMPP connected devices.
e.g. 0xAC127001=172.18.112.1.
+ Session init timer: This timer specifies the time lapse allowed between a network connection being established and a bind_transmitter or bind_receiver request being sent to SMSC. This timer should be active on the SMSC. + Enquire link timer: This timer specifies the time lapse allowed between operations after which an SMPP entity should interrogate whether it's peer still has an active session. + The scale is second. + Inactivity timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) + Response timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) + Local service number: compare with application's service number while bind as TX or TRX. + remote service number: compare with application's service number while bind as RX + [End] + " + ::= { Config_SMPP 1 } + + +Status_SMPP OBJECT-IDENTITY + STATUS current + DESCRIPTION + " XAPP Status. " + ::= { SMPP 3 } + +Command_SMPP OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS write-only + STATUS current + DESCRIPTION + " + [Begin] + Instance: 1 + Length: 1 + Default: 02 + Flag :S1.1 + Field: [1]Command + { + [u]00.0-00.7 + [u]select + [v]2[opt]save parameter + } + Remark: Control command for SMPP. + [End] + " + ::= { Status_SMPP 2 } + + +END diff --git a/plat/smpp/ut/conf/MIB_files/menu_page b/plat/smpp/ut/conf/MIB_files/menu_page new file mode 100644 index 0000000..7edaddc --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/menu_page @@ -0,0 +1,13 @@ + + ******************* + * Module Page * + ******************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- PPS + d -- TCAP l -- SNMP + e -- XAPP m -- M2UA + f -- MSC n -- DEBUG + g -- VLR o -- AUC + h -- SSF p -- EIR diff --git a/plat/smpp/ut/conf/MIB_files/menu_tree.txt b/plat/smpp/ut/conf/MIB_files/menu_tree.txt new file mode 100644 index 0000000..2f52696 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/menu_tree.txt @@ -0,0 +1,908 @@ +############## The debug menu tree config file root=wxc2 root_oid={1.3.6.1.4.1.1373.1.3} +#(0)(1)(2)(9) ip group +#/ the layer +#.1.1.3. menu_id +#{3.2.2.1.2} the last oid from the root +#[name] menu name +#M:8 the id of the menu in the current object +############## all the line must end for ';',and menu id and last oid must do not contain space + +##WXC2 +/. (9); + +M:1 [MSC] {3.2}; +M:2 [VLR] {3.2.5}; +M:3 [HLR] {3.3}; +M:4 [PPS] {3.6}; +M:5 [SMSC] {3.5}; +M:6 [AUC] {3.4}; +##M:7 [EIR] {3.8}; + +##MSC +/ /.1. (9); + +M:1 [Prefix Assignment] {3.2.2.2.1.1}; +M:2 [Prefix Attributes] {3.2.2.2.1.2}; +M:3 [Assign TG to Prefix] {3.2.2.2.1.3}; +M:4 [TG attributes] {3.2.2.2.1.4}; +M:5 [CDR Flag] {3.2.2.2.1.5}; +M:6 [Announcement Option] {3.2.2.2.1.6}; +M:7 [Warning tone] {3.2.2.2.1.7}; +M:8 [Emergency call] {3.2.2.2.2.5}; +M:9 [Location management] {3.2.2.2.2.8}; +M:10 [Max. call duration] {3.2.2.2.3.7}; +M:11 [E1 Port] {3.2.2.2.4}; +M:12 [channel attributes] {3.2.2.2.5}; +M:13 [Platform] {2}; +M:14 [MSC0] (1) {3.2}; +M:15 [MSC1] (2) {3.2}; + +##MSC->E1 Port +/ / /.1.11. (9); + +M:1 [E1 interface] {3.2.2.2.4.1}; +M:2 [Assign TG to E1] {3.2.2.2.4.2}; +M:3 [CIC of E1] {3.2.2.2.4.3}; + +##MSC->channel attributes->8K card 0-31 +/ / /.1.12. (9); + +M:1 [Card 0 channel attributes] {3.2.2.2.5.1}; +M:2 [Card 1 channel attributes] {3.2.2.2.5.2}; +M:3 [Card 2 channel attributes] {3.2.2.2.5.3}; +M:4 [Card 3 channel attributes] {3.2.2.2.5.4}; +M:5 [Card 4 channel attributes] {3.2.2.2.5.5}; +M:6 [Card 5 channel attributes] {3.2.2.2.5.6}; +M:7 [Card 6 channel attributes] {3.2.2.2.5.7}; +M:8 [Card 7 channel attributes] {3.2.2.2.5.8}; +M:9 [Card 8 channel attributes] {3.2.2.2.5.9}; +M:10 [Card 9 channel attributes] {3.2.2.2.5.10}; +M:11 [Card 10 channel attributes] {3.2.2.2.5.11}; +M:12 [Card 11 channel attributes] {3.2.2.2.5.12}; +M:13 [Card 12 channel attributes] {3.2.2.2.5.13}; +M:14 [Card 13 channel attributes] {3.2.2.2.5.14}; +M:15 [Card 14 channel attributes] {3.2.2.2.5.15}; +M:16 [Card 15 channel attributes] {3.2.2.2.5.16}; +M:17 [Card 16 channel attributes] {3.2.2.2.5.17}; +M:18 [Card 17 channel attributes] {3.2.2.2.5.18}; +M:19 [Card 18 channel attributes] {3.2.2.2.5.19}; +M:20 [Card 19 channel attributes] {3.2.2.2.5.20}; +M:21 [Card 20 channel attributes] {3.2.2.2.5.21}; +M:22 [Card 21 channel attributes] {3.2.2.2.5.22}; +M:23 [Card 22 channel attributes] {3.2.2.2.5.23}; +M:24 [Card 23 channel attributes] {3.2.2.2.5.24}; +M:25 [Card 24 channel attributes] {3.2.2.2.5.25}; +M:26 [Card 25 channel attributes] {3.2.2.2.5.26}; +M:27 [Card 26 channel attributes] {3.2.2.2.5.27}; +M:28 [Card 27 channel attributes] {3.2.2.2.5.28}; +M:29 [Card 28 channel attributes] {3.2.2.2.5.29}; +M:30 [Card 29 channel attributes] {3.2.2.2.5.30}; +M:31 [Card 30 channel attributes] {3.2.2.2.5.31}; +M:32 [Card 31 channel attributes] {3.2.2.2.5.32}; + + +##MSC->Platform +/ / /.1.13. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##MSC->Platform->MTP3 +/ / /.1.13.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [ACN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##MSC->Platform->MTP3->Status +/ / /.1.13.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##MSC->Platform->SCCP +/ / /.1.13.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##MSC->Platform->XAPP +/ / /.1.13.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + + +##MSC->MSC0->E1 status +/ / /.1.14. (1); + +M:1 [E1 Status] {3.2.2.3.4}; +M:2 [Channel Status] {3.2.2.3.5}; +##M:3 [CSU0] {1.1}; + + +##MSC->MSC1->E1 status +/ / /.1.15. (2); + +M:1 [E1 Status] {3.2.2.3.4}; +M:2 [Channel Status] {3.2.2.3.5}; +##M:3 [CSU1] {1.1}; + + +##MSC->MSC0->Channel Status +/ / / /.1.14.2. (1); + +M:1 [8K Card 0] {3.2.2.3.5.1}; +M:2 [8K Card 1] {3.2.2.3.5.2}; +M:3 [8K Card 2] {3.2.2.3.5.3}; +M:4 [8K Card 3] {3.2.2.3.5.4}; +M:5 [8K Card 4] {3.2.2.3.5.5}; +M:6 [8K Card 5] {3.2.2.3.5.6}; +M:7 [8K Card 6] {3.2.2.3.5.7}; +M:8 [8K Card 7] {3.2.2.3.5.8}; +M:9 [8K Card 8] {3.2.2.3.5.9}; +M:10 [8K Card 9] {3.2.2.3.5.10}; +M:11 [8K Card 10] {3.2.2.3.5.11}; +M:12 [8K Card 11] {3.2.2.3.5.12}; +M:13 [8K Card 12] {3.2.2.3.5.13}; +M:14 [8K Card 13] {3.2.2.3.5.14}; +M:15 [8K Card 14] {3.2.2.3.5.15}; +M:16 [8K Card 15] {3.2.2.3.5.16}; + + +##MSC->MSC1->channel status +/ / / /.1.15.2. (2); + +M:1 [8K Card 0] {3.2.2.3.5.1}; +M:2 [8K Card 1] {3.2.2.3.5.2}; +M:3 [8K Card 2] {3.2.2.3.5.3}; +M:4 [8K Card 3] {3.2.2.3.5.4}; +M:5 [8K Card 4] {3.2.2.3.5.5}; +M:6 [8K Card 5] {3.2.2.3.5.6}; +M:7 [8K Card 6] {3.2.2.3.5.7}; +M:8 [8K Card 7] {3.2.2.3.5.8}; +M:9 [8K Card 8] {3.2.2.3.5.9}; +M:10 [8K Card 9] {3.2.2.3.5.10}; +M:11 [8K Card 10] {3.2.2.3.5.11}; +M:12 [8K Card 11] {3.2.2.3.5.12}; +M:13 [8K Card 12] {3.2.2.3.5.13}; +M:14 [8K Card 13] {3.2.2.3.5.14}; +M:15 [8K Card 14] {3.2.2.3.5.15}; +M:16 [8K Card 15] {3.2.2.3.5.16}; + + +##MSC->MSC0->CSU0 +##/ / / / /.1.14.3. (1); + +##M:1 [E1 enable] {1.1.1.2.1}; +##M:2 [MTP alarm on/off] {1.1.1.2.2}; +##M:3 [Link type] {1.1.1.2.3}; +##M:4 [NT/LT] {1.1.1.2.4}; +##M:5 [DPLL priority] {1.1.1.2.5}; +##M:6 [CRC4 flag] {1.1.1.2.6}; +##M:7 [Ringback Tone] {1.1.1.2.7.1}; +##M:8 [Busy Tone] {1.1.1.2.7.2}; +##M:9 [Unavailable Tone] {1.1.1.2.7.3}; +##M:10 [Congestion Tone] {1.1.1.2.7.4}; +##M:11 [Proceeding Tone] {1.1.1.2.7.5}; +##M:12 [Warning tone] {1.1.1.2.7.6}; +##M:13 [Tone assignment] {1.1.1.2.7.9}; +##M:14 [DTMF mark&space] {1.1.1.2.7.10}; +##M:15 [8KE1_0] (0) {1.1.1.3}; +##M:16 [8KE1_1] (0) {1.1.1.3}; +##M:17 [8KE1_2] (0) {1.1.1.3}; +##M:18 [8KE1_3] (0) {1.1.1.3}; +##M:19 [8KE1_4] (0) {1.1.1.3}; +##M:20 [8KE1_5] (0) {1.1.1.3}; +##M:21 [8KE1_6] (0) {1.1.1.3}; +##M:22 [8KE1_7] (0) {1.1.1.3}; +##M:23 [8KE1_8] (0) {1.1.1.3}; +##M:24 [8KE1_9] (0) {1.1.1.3}; +##M:25 [8KE1_10] (0) {1.1.1.3}; +##M:26 [8KE1_11] (0) {1.1.1.3}; +##M:27 [8KE1_12] (0) {1.1.1.3}; +##M:28 [8KE1_13] (0) {1.1.1.3}; +##M:29 [8KE1_14] (0) {1.1.1.3}; +##M:30 [8KE1_15] (0) {1.1.1.3}; + + +##MSC->MSC1->CSU1 +##/ / / / /.1.15.3. (2); + +##M:1 [E1 enable] {1.1.1.2.1}; +##M:2 [MTP alarm on/off] {1.1.1.2.2}; +##M:3 [Link type] {1.1.1.2.3}; +##M:4 [NT/LT] {1.1.1.2.4}; +##M:5 [DPLL priority] {1.1.1.2.5}; +##M:6 [CRC4 flag] {1.1.1.2.6}; +##M:7 [Ringback Tone] {1.1.1.2.7.1}; +##M:8 [Busy Tone] {1.1.1.2.7.2}; +##M:9 [Unavailable Tone] {1.1.1.2.7.3}; +##M:10 [Congestion Tone] {1.1.1.2.7.4}; +##M:11 [Proceeding Tone] {1.1.1.2.7.5}; +##M:12 [Warning tone] {1.1.1.2.7.6}; +##M:13 [Tone assignment] {1.1.1.2.7.9}; +##M:14 [DTMF mark&space] {1.1.1.2.7.10}; +##M:15 [8KE1_0] (0) {1.1.1.3}; +##M:16 [8KE1_1] (0) {1.1.1.3}; +##M:17 [8KE1_2] (0) {1.1.1.3}; +##M:18 [8KE1_3] (0) {1.1.1.3}; +##M:19 [8KE1_4] (0) {1.1.1.3}; +##M:20 [8KE1_5] (0) {1.1.1.3}; +##M:21 [8KE1_6] (0) {1.1.1.3}; +##M:22 [8KE1_7] (0) {1.1.1.3}; +##M:23 [8KE1_8] (0) {1.1.1.3}; +##M:24 [8KE1_9] (0) {1.1.1.3}; +##M:25 [8KE1_10] (0) {1.1.1.3}; +##M:26 [8KE1_11] (0) {1.1.1.3}; +##M:27 [8KE1_12] (0) {1.1.1.3}; +##M:28 [8KE1_13] (0) {1.1.1.3}; +##M:29 [8KE1_14] (0) {1.1.1.3}; +##M:30 [8KE1_15] (0) {1.1.1.3}; + +##VLR +/ / /.2. (9); + +M:1 [OptAuthReq] {3.2.5.2.1.1}; +M:2 [OpReuseTriplets] {3.2.5.2.1.2}; +M:3 [OptCipReq] {3.2.5.2.1.3}; +M:4 [OptCiphAlgo] {3.2.5.2.1.4}; +M:5 [OptTmsiAlloc] {3.2.5.2.1.5}; +M:6 [OptEcsSetUpAllow] {3.2.5.2.1.7}; +M:7 [OptCheckIMEI] {3.2.5.2.1.8}; +M:8 [OptVlrPurge] {3.2.5.2.1.9}; +M:9 [idlePeriod2Purge] {3.2.5.2.1.10}; +M:10 [CDR flag] {3.2.5.2.1.11}; +M:11 [MSRN] {3.2.5.2.1.13}; +M:12 [VLR0] {3.2.5}; +M:13 [VLR1] {3.2.5}; + +##VLR->VLR0 + +/ / /.2.12. (1); + +M:1 [Version] {3.2.5.3.2}; +M:2 [Command] {3.2.5.3.3}; +M:3 [Status] {3.2.5.3.4}; + +##VLR->VLR0 + +/ / /.2.13. (2); + +M:1 [Version] {3.2.5.3.2}; +M:2 [Command] {3.2.5.3.3}; +M:3 [Status] {3.2.5.3.4}; + + +##HLR +/ / /.3. (9); + +M:1 [HPLMN] {3.3.2.1.11}; +M:2 [VPLMNs] {3.3.2.1.12}; +M:3 [CSRR list] {3.3.2.1.13}; +M:4 [Regional Subscription] {3.3.2.1.14}; +M:5 [License control] {3.3.2.1.15}; +M:6 [CDR control] {3.3.2.1.16}; +M:7 [Feature Code] {3.3.2.1.27}; +M:8 [Platform] {2}; +M:9 [HLR0] {3.3}; +M:10 [HLR1] {3.3}; + +##HLR->Platform +/ / /.3.8. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##HLR->Platform->MTP3 +/ / /.3.8.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [ACN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##HLR->Platform->MTP3->Status +/ / /.3.8.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##HLR->Platform->SCCP +/ / /.3.8.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##HLR->Platform->XAPP +/ / /.3.8.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##HLR->HLR0 + +/ / /.3.9. (1); + +M:1 [Command] {3.3.2.2.2}; +M:2 [Subscriber import] {3.3.2.2.3}; +M:3 [Max Licenses] {3.3.2.2.11}; +M:4 [Used Licenses] {3.3.2.2.12}; +M:5 [Subscriber information] {3.3.2.2.13}; +M:6 [Version] {3.3.2.2.14}; +M:7 [IMSI segment] {3.3.2.2.15}; +M:8 [MSISDN segment] {3.3.2.2.16}; +M:9 [CNF applicant info] {3.3.2.2.27}; +##M:10 [Contry code] {3.3.2.2.10}; + +##HLR->HLR0->Subscriber information + +/ / /.3.9.5. (1); + +M:1 [Provisioned subscribers] {3.3.2.2.13.1}; +M:2 [Registered subscribers] {3.3.2.2.13.2}; +M:3 [Roaming subscribers] {3.3.2.2.13.3}; + +##HLR->HLR0->Version +/ / /.3.9.6. (1); + +M:1 [Software] {3.3.2.2.14.1}; +M:2 [User data] {3.3.2.2.14.2}; + + +##HLR->HLR1 + +/ / /.3.10. (2); + +M:1 [Command] {3.3.2.2.2}; +M:2 [Subscriber import] {3.3.2.2.3}; +M:3 [Max Licenses] {3.3.2.2.11}; +M:4 [Used Licenses] {3.3.2.2.12}; +M:5 [Subscriber information] {3.3.2.2.13}; +M:6 [Version] {3.3.2.2.14}; +M:7 [IMSI segment] {3.3.2.2.15}; +M:8 [MSISDN segment] {3.3.2.2.16}; +M:9 [CNF applicant info] {3.3.2.2.27}; +##M:10 [Contry code] {3.3.2.2.10}; + +##HLR->HLR1->Subscriber information +/ / /.3.10.5. (2); + +M:1 [Provisioned subscribers] {3.3.2.2.13.1}; +M:2 [Registered subscribers] {3.3.2.2.13.2}; +M:3 [Roaming subscribers] {3.3.2.2.13.3}; + +##HLR->HLR1->Version +/ / /.3.10.6. (2); + +M:1 [Software] {3.3.2.2.14.1}; +M:2 [User data] {3.3.2.2.14.2}; + +##PPS +/ / /.4. (9); + +M:1 [Service control] {3.6.2.1.1}; +M:2 [SRF Number] {3.6.2.1.2.1}; +M:3 [Service number] {3.6.2.1.2.2}; +M:4 [Service key] {3.6.2.1.2.3}; +M:5 [COS Parameter] {3.6.2.1.4}; +M:6 [Call routing to VMS] {3.6.2.1.5}; +M:7 [Status] {3.6.2.1.6}; +M:8 [Platform] {2}; + +##PPS->Service control +/ / /.4.1. (9); + +M:1 [CDR flag] {3.6.2.1.1.1}; +M:2 [Blacklist threshhold] {3.6.2.1.1.2}; +M:3 [Maximun balance] {3.6.2.1.1.3}; +M:4 [license control] {3.6.2.1.1.4}; +M:5 [Prompt resolution] {3.6.2.1.1.5}; +M:6 [SMS Sentence] {3.6.2.1.1.6}; +M:7 [Last call info] {3.6.2.1.1.7}; +M:8 [Currency Symbol] {3.6.2.1.1.8}; +M:9 [Third party info] {3.6.2.1.1.9}; +M:10 [Basic Tariff Zone] {3.6.2.1.1.10}; + +##PPS->Service number +/ / /.4.3. (9); + +M:1 [Hotline] {3.6.2.1.2.2.1}; +M:2 [Inquiry] {3.6.2.1.2.2.2}; +M:3 [Scratch card rechagne] {3.6.2.1.2.2.3}; +M:4 [Credit card recharge] {3.6.2.1.2.2.4}; +M:5 [Third party recharge] {3.6.2.1.2.2.5}; +M:6 [Customer care center] {3.6.2.1.2.2.6}; +M:7 [Recharge] {3.6.2.1.2.2.7}; + +##PPS->Service key +/ / /.4.4. (9); + +M:1 [Inquiry] {3.6.2.1.2.3.2}; +M:2 [Scratch card rechagne] {3.6.2.1.2.3.3}; +M:3 [Credit card recharge] {3.6.2.1.2.3.4}; +M:4 [Set favorite number] {3.6.2.1.2.3.5}; +M:5 [Set password] {3.6.2.1.2.3.6}; + + +##PPS->COS Parameter +/ / /.4.5. (9); + +M:1 [COS0] {3.6.2.1.4.1}; +M:2 [COS1] {3.6.2.1.4.2}; +M:3 [COS2] {3.6.2.1.4.3}; +M:4 [COS3] {3.6.2.1.4.4}; +M:5 [COS4] {3.6.2.1.4.5}; +M:6 [COS5] {3.6.2.1.4.6}; +M:7 [COS6] {3.6.2.1.4.7}; +M:8 [COS7] {3.6.2.1.4.8}; +M:9 [COS8] {3.6.2.1.4.9}; +M:10 [COS9] {3.6.2.1.4.10}; +M:11 [COS10] {3.6.2.1.4.11}; +M:12 [COS11] {3.6.2.1.4.12}; +M:13 [COS12] {3.6.2.1.4.13}; +M:14 [COS13] {3.6.2.1.4.14}; +M:15 [COS14] {3.6.2.1.4.15}; +M:16 [COS15] {3.6.2.1.4.16}; + + +##PPS->COS Parameter->COS 0-15 +/ / /.4.5.1. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.1.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.1.2}; +M:3 [Account control] {3.6.2.1.4.1.3}; +M:4 [MT Call control] {3.6.2.1.4.1.4}; +M:5 [Validity control] {3.6.2.1.4.1.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.1.6}; + +/ / /.4.5.2. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.2.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.2.2}; +M:3 [Account control] {3.6.2.1.4.2.3}; +M:4 [MT Call control] {3.6.2.1.4.2.4}; +M:5 [Validity control] {3.6.2.1.4.2.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.2.6}; + +/ / /.4.5.3. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.3.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.3.2}; +M:3 [Account control] {3.6.2.1.4.3.3}; +M:4 [MT Call control] {3.6.2.1.4.3.4}; +M:5 [Validity control] {3.6.2.1.4.3.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.3.6}; + +/ / /.4.5.4. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.4.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.4.2}; +M:3 [Account control] {3.6.2.1.4.4.3}; +M:4 [MT Call control] {3.6.2.1.4.4.4}; +M:5 [Validity control] {3.6.2.1.4.4.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.4.6}; + +/ / /.4.5.5. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.5.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.5.2}; +M:3 [Account control] {3.6.2.1.4.5.3}; +M:4 [MT Call control] {3.6.2.1.4.5.4}; +M:5 [Validity control] {3.6.2.1.4.5.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.5.6}; + +/ / /.4.5.6. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.6.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.6.2}; +M:3 [Account control] {3.6.2.1.4.6.3}; +M:4 [MT Call control] {3.6.2.1.4.6.4}; +M:5 [Validity control] {3.6.2.1.4.6.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.6.6}; + +/ / /.4.5.7. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.7.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.7.2}; +M:3 [Account control] {3.6.2.1.4.7.3}; +M:4 [MT Call control] {3.6.2.1.4.7.4}; +M:5 [Validity control] {3.6.2.1.4.7.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.7.6}; + +/ / /.4.5.8. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.8.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.8.2}; +M:3 [Account control] {3.6.2.1.4.8.3}; +M:4 [MT Call control] {3.6.2.1.4.8.4}; +M:5 [Validity control] {3.6.2.1.4.8.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.8.6}; + +/ / /.4.5.9. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.9.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.9.2}; +M:3 [Account control] {3.6.2.1.4.9.3}; +M:4 [MT Call control] {3.6.2.1.4.9.4}; +M:5 [Validity control] {3.6.2.1.4.9.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.9.6}; + +/ / /.4.5.10. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.10.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.10.2}; +M:3 [Account control] {3.6.2.1.4.10.3}; +M:4 [MT Call control] {3.6.2.1.4.10.4}; +M:5 [Validity control] {3.6.2.1.4.10.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.10.6}; + +/ / /.4.5.11. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.11.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.11.2}; +M:3 [Account control] {3.6.2.1.4.11.3}; +M:4 [MT Call control] {3.6.2.1.4.11.4}; +M:5 [Validity control] {3.6.2.1.4.11.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.11.6}; + +/ / /.4.5.12. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.12.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.12.2}; +M:3 [Account control] {3.6.2.1.4.12.3}; +M:4 [MT Call control] {3.6.2.1.4.12.4}; +M:5 [Validity control] {3.6.2.1.4.12.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.12.6}; + +/ / /.4.5.13. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.13.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.13.2}; +M:3 [Account control] {3.6.2.1.4.13.3}; +M:4 [MT Call control] {3.6.2.1.4.13.4}; +M:5 [Validity control] {3.6.2.1.4.13.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.13.6}; + +/ / /.4.5.14. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.14.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.14.2}; +M:3 [Account control] {3.6.2.1.4.14.3}; +M:4 [MT Call control] {3.6.2.1.4.14.4}; +M:5 [Validity control] {3.6.2.1.4.14.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.14.6}; + +/ / /.4.5.15. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.15.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.15.2}; +M:3 [Account control] {3.6.2.1.4.15.3}; +M:4 [MT Call control] {3.6.2.1.4.15.4}; +M:5 [Validity control] {3.6.2.1.4.15.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.15.6}; + +/ / /.4.5.16. (9); + +M:1 [Recharge Promotion] {3.6.2.1.4.16.1}; +M:2 [Tariff Resolution] {3.6.2.1.4.16.2}; +M:3 [Account control] {3.6.2.1.4.16.3}; +M:4 [MT Call control] {3.6.2.1.4.16.4}; +M:5 [Validity control] {3.6.2.1.4.16.5}; +M:6 [SM Inquiry Notification] {3.6.2.1.4.16.6}; + + +##PPS->call routing to VMS +/ / /.4.6. (9); + +M:1 [VMS service number-PLMN] {3.6.2.1.5.1}; +M:2 [VMS service number-PSTN] {3.6.2.1.5.2}; +M:3 [VMS leave message number] {3.6.2.1.5.3}; +M:4 [Routing rule] {3.6.2.1.5.4}; +M:5 [VMS user segments] {3.6.2.1.5.5}; + +##PPS->Status +/ / /.4.7. (9); + +M:1 [Activaion] {3.6.2.1.6.1}; +M:2 [Command] {3.6.2.1.6.2}; + + +##PPS->Platform +/ / /.4.8. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; +M:4 [SMPP] {2.3.4} + +##PPS->Platform->MTP3 +/ / /.4.8.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##PPS->Platform->MTP3->Status +/ / /.4.8.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##PPS->Platform->SCCP +/ / /.4.8.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##PPS->Platform->XAPP +/ / /.4.8.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##PPS-->Platform->SMPP +/ / /.4.8.4. (9); + +M:1 [SMPP_Link_Param] {2.3.4.2.1}; +M:2 [Command] {2.3.4.3.2}; + + +## SMSC +/ / /.5. (9); + +M:1 [CDR flag] {3.5.2.1.1}; +M:2 [SM Validity] {3.5.2.1.2}; +M:3 [MSISDN Segment] {3.5.2.1.3}; +M:4 [SMPP parameters] {3.5.2.2}; +M:5 [Command] {3.5.3.3}; +M:6 [Platform] {2}; +M:7 [SMSC0] {3.5}; +M:8 [SMSC1] {3.5}; + + +##SMSC->Platform +/ / /.5.6. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; +M:4 [SMPP] {2.3.4}; + +##SMSC->Platform->MTP3 +/ / /.5.6.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##SMSC->Platform->MTP3->Status +/ / /.5.6.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##SMSC->Platform->SCCP +/ / /.5.6.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##SMSC->Platform->XAPP +/ / /.5.6.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + +##SMSC->Platform->SMPP +/ / /.5.6.4. (9); + +M:1 [SMPP_Link_Param] {2.3.4.2.1}; +M:2 [Command] {2.3.4.3.2}; + + +##SMSC->SMSC0 +/ / /.5.7. (1); + +M:1 [SMSC ID] {3.5.3.1}; +M:2 [Software version] {3.5.3.2}; + +##SMSC->SMSC1 +/ / /.5.8. (2); + +M:1 [SMSC ID] {3.5.3.1}; +M:2 [Software version] {3.5.3.2}; + +##AUC +/ / /.6. (9); + +M:1 [Platform] {2}; +M:2 [AUC0] (1) {3.4}; +M:3 [AUC1] (2) {3.4}; + + +##AUC->Platform +/ / /.6.1. (9); + +M:1 [MTP3] {2.2.2}; +M:2 [SCCP] {2.2.3}; +M:3 [XAPP] {2.2.5}; + +##AUC->Platform->MTP3 +/ / /.6.1.1. (9); + +M:1 [Network Indicator] {2.2.2.2.2}; +M:2 [Originating Point code] {2.2.2.2.3}; +M:3 [Link Set] {2.2.2.2.4}; +M:4 [Link] {2.2.2.2.5}; +M:5 [Routing] {2.2.2.2.6}; +M:6 [CAN] {2.2.2.2.7}; +M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##AUC->Platform->MTP3->Status +/ / /.6.1.1.7. (9); + +M:1 [Link status] {2.2.2.3.1}; +M:2 [Link set status] {2.2.2.3.2}; +M:3 [International routing] {2.2.2.3.3}; +M:4 [International spare] {2.2.2.3.4}; +M:5 [National routing] {2.2.2.3.5}; +M:6 [National spare routing] {2.2.2.3.6}; +M:7 [Command] {2.2.2.3.7}; + +##AUC->Platform->SCCP +/ / /.6.1.2. (9); + +M:1 [Local node] {2.2.3.2.1}; +M:2 [GTT] {2.2.3.2.2}; +M:3 [Command] {2.2.3.3.2}; + +##AUC->Platform->XAPP +/ / /.6.1.3. (9); + +M:1 [MCC] {2.2.5.2.1}; +M:2 [MNC] {2.2.5.2.2}; +M:3 [CC] {2.2.5.2.3}; +M:4 [NDC] {2.2.5.2.4}; +M:5 [International prefix] {2.2.5.2.5}; +M:6 [National Prefix] {2.2.5.2.6}; +M:7 [Local Prefix] {2.2.5.2.7}; +M:8 [Convert Prefix] {2.2.5.2.8}; +M:9 [Command] {2.2.5.3.2}; + + +##EIR +##/ / /.7. (9); + +##M:1 [Platform] {2}; +##M:2 [EIR0] (1) {3.8}; +##M:3 [EIR1] (2) {3.8}; + +##EIR->Platform +##/ / /.7.1. (9); + +##M:1 [MTP3] {2.2.2}; +##M:2 [SCCP] {2.2.3}; +##M:3 [XAPP] {2.2.5}; + +##EIR->Platform->MTP3 +##/ / /.7.1.1. (9); + +##M:1 [Network Indicator] {2.2.2.2.2}; +##M:2 [Originating Point code] {2.2.2.2.3}; +##M:3 [Link Set] {2.2.2.2.4}; +##M:4 [Link] {2.2.2.2.5}; +##M:5 [Routing] {2.2.2.2.6}; +##M:6 [CAN] {2.2.2.2.7}; +##M:7 [Status] {2.2.2.3}; +M:8 [Signaling GateWay] {2.2.2.2.9}; + + +##EIR->Platform->MTP3->Status +##/ / /.7.1.1.7. (9); + +####M:1 [Link status] {2.2.2.3.1}; +##M:2 [Link set status] {2.2.2.3.2}; +##M:3 [International routing] {2.2.2.3.3}; +##M:4 [International spare] {2.2.2.3.4}; +##M:5 [National routing] {2.2.2.3.5}; +##M:6 [National spare routing] {2.2.2.3.6}; +##M:7 [Command] {2.2.2.3.7}; + +##EIR->Platform->SCCP +##/ / /.7.1.2. (9); + +##M:1 [Local node] {2.2.3.2.1}; +##M:2 [GTT] {2.2.3.2.2}; +##M:3 [Command] {2.2.3.3.2}; + +##EIR->Platform->XAPP +##/ / /.7.1.3. (9); + +##M:1 [MCC] {2.2.5.2.1}; +##M:2 [MNC] {2.2.5.2.2}; +##M:3 [CC] {2.2.5.2.3}; +##M:5 [International prefix] {2.2.5.2.5}; +##M:6 [National Prefix] {2.2.5.2.6}; +##M:7 [Local Prefix] {2.2.5.2.7}; +##M:8 [Convert Prefix] {2.2.5.2.8}; +##M:9 [Command] {2.2.5.3.2}; diff --git a/plat/smpp/ut/conf/MIB_files/mib_list_file.txt b/plat/smpp/ut/conf/MIB_files/mib_list_file.txt new file mode 100644 index 0000000..c51c1d3 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/mib_list_file.txt @@ -0,0 +1,14 @@ +// "//" is the annotation characters; +IWV-SMI.txt +Special_App-SMI.txt +//PPPRT-MIB.txt +WXC2-SMI.txt +//WXC2-CSU-MIB.txt +WXC2-SS7-MIB.txt +WXC2-MSC-MIB.txt +WXC2-HLR-MIB.txt +WXC2-AUC-MIB.txt +//WXC2-EIR-MIB.txt +WXC2-SMSC-MIB.txt +WXC2-PPS-MIB.txt +WXC2-MSS-MIB.txt diff --git a/plat/smpp/ut/conf/MIB_files/mib_write_tree.txt b/plat/smpp/ut/conf/MIB_files/mib_write_tree.txt new file mode 100644 index 0000000..b6e9303 --- /dev/null +++ b/plat/smpp/ut/conf/MIB_files/mib_write_tree.txt @@ -0,0 +1,25897 @@ +Create node: IWV(OID: 1.3.6.1.4.1.1373) +-> father_name = [enterprises] +-> -> IWV(0) + + +Create node: IWV_Products(OID: 1.3.6.1.4.1.1373.1) +-> father_name = [IWV] +-> -> IWV_Products(0) + + +Remark: iwvProducts is the root OBJECT IDENTIFIER from which sysObjectID values are assigned. Actual values are defined in IWV-PRODUCTS-MIB. + + +Create node: Special_App(OID: 1.3.6.1.4.1.1373.1.2) +-> father_name = [IWV_Products] +-> -> Special_App(0) + + +Create node: IWF(OID: 1.3.6.1.4.1.1373.1.2.8) +-> father_name = [Special_App] +-> -> IWF(0) + + +Remark: IWF + + +Create node: WXC2(OID: 1.3.6.1.4.1.1373.1.3) +-> father_name = [IWV_Products] +-> -> Special_App(0) +-> -> WXC2(1) + + +Create node: PCM(OID: 1.3.6.1.4.1.1373.1.3.1) +-> father_name = [WXC2] +-> -> PCM(0) + + +Remark: PCM + + +Create node: Platform(OID: 1.3.6.1.4.1.1373.1.3.2) +-> father_name = [WXC2] +-> -> PCM(0) +-> -> Platform(1) + + +Remark: Platform + + +Create node: App(OID: 1.3.6.1.4.1.1373.1.3.3) +-> father_name = [WXC2] +-> -> PCM(0) +-> -> Platform(1) +-> -> App(2) + + +Remark: App platform + + +Create node: SS7(OID: 1.3.6.1.4.1.1373.1.3.2.2) +-> father_name = [Platform] +-> -> SS7(0) + + +Remark: + Subsystems for SS7 . + + +Create node: MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2) +-> father_name = [SS7] +-> -> MTP3(0) + + +Remark: Subsystems for MTP3 . + + +Create node: Config_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2) +-> father_name = [MTP3] +-> -> Config_MTP3(0) + + +Remark: MTP3 Configuration. + + +Create node: Network_Indicator(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.2) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) + + +Register leaf node: Network_Indicator. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : MTP3 network indicator. + +Field : total(8) +Access : read-write [1]International network + { + [u]0.0-0.0 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [2]International network spare + { + [u]0.1-0.1 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [3]National network + { + [u]0.2-0.2 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [4]National network spare + { + [u]0.3-0.3 + [u]select + [v]0[opt]14bit + [v]1[opt]24bit + } + [5]International network + { + [u]0.4-0.4 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [6]International network spare + { + [u]0.5-0.5 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [7]National network + { + [u]0.6-0.6 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + [8]National network spare + { + [u]0.7-0.7 + [u]select + [v]0[opt]ITU + [v]1[opt]ANSI + } + + +Create node: OPC(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) + + +Remark: Originating point code. + + +Create node: International_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.1) +-> father_name = [OPC] +-> -> International_14bit(0) + + +Register leaf node: International_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.2) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) + + +Register leaf node: International_Spare_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.3) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) + + +Register leaf node: National_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare_14bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.4) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) + + +Register leaf node: National_Spare_14bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 14-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.5) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) + + +Register leaf node: International_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.6) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) + + +Register leaf node: International_Spare_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.7) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) +-> -> National_24bit(6) + + +Register leaf node: National_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare_24bit(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.3.8) +-> father_name = [OPC] +-> -> International_14bit(0) +-> -> International_Spare_14bit(1) +-> -> National_14bit(2) +-> -> National_Spare_14bit(3) +-> -> International_24bit(4) +-> -> International_Spare_24bit(5) +-> -> National_24bit(6) +-> -> National_Spare_24bit(7) + + +Register leaf node: National_Spare_24bit. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : 24-bit originating point code (OPC) in an international network. Default=0. + +Field : total(1) +Access : read-write[1]Originating point code + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Linkset(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.4) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) + + +Remark: linkset. + + +Create node: Linkset_Attributes(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.4.1) +-> father_name = [Linkset] +-> -> Linkset_Attributes(0) + + +Register leaf node: Linkset_Attributes. +Instance: 128 +Length : 4 +Flag : 255 +Default : +Remark : Opposite point code: The opposite point code of the linkset. +Network indicator: The network type of the opposite point code. +Loop back: Loop back enable or disable, used for MSC loop back link. + +Field : total(5) +Access : read-write[1]Linkset DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } + [2]Network indicator + { + [u]3.0-3.1 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [4]Linkset loopback + { + [u]3.3-3.3 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Link(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) + + +Remark: link. + + +Create node: Link_Attributes(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.1) +-> father_name = [Link] +-> -> Link_Attributes(0) + + +Register leaf node: Link_Attributes. +Instance: 256 +Length : 15 +Flag : 255 +Default : €ÿÿÿÿ +Remark : E1 link attributes. +Linkset no.: Assign linkset to E1 link, MSC has up to 128 linksets (0-127). 128=TCH E1. +SLC no.: Assign SLC to each E1 link of a linkset, each linkset has up to 13 E1 links (0-15). +IP: E1 link management IP. The third byte of CPC IP: +98=E1 link 0-127, 99=E1 link 128-255. +Default=0x000032. + +Field : total(12) +Access : read-write[1]Linkset no. + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } +[2]SLC no. + { + [u]1.0-1.7 + [u]input + [v]toDec high 0 + } +[3]CPC IP + { + [u]2.0-5.7 + [u]input + [v]KeepHex high 0 + } + [4]Link Type + { + [u]6.0-6.0 + [u]select + [v]0[opt]Non-sigtran + [v]1[opt]Sigtran + } + [5]Link Enable + { + [u]6.1-6.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [6]MTP3-Lite Enable + { + [u]6.2-6.2 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[8]SG no. + { + [u]7.0-7.7 + [u]input + [v]toDec high 0 + } +[9]M2UA Interface ID + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } +[10]MTP3-Lite Remote IP + { + [u]9.0-12.7 + [u]input + [v]KeepHex high 0 + } +[11]MTP3-Lite Inactivity Timeout + { + [u]13.0-13.7 + [u]input + [v]toDec high 0 + } +[12]MTP3-Lite Allowed Inactivity Timeouts + { + [u]14.0-14.7 + [u]input + [v]toDec high 0 + } + + +Create node: Link_Command(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.2) +-> father_name = [Link] +-> -> Link_Attributes(0) +-> -> Link_Command(1) + + +Register leaf node: Link_Command. +Instance: 256 +Length : 1 +Flag : 255 +Default :  +Remark : Used for E1 link control, not affect call traffic. +Disable=Disable E1 link MTP2 layer. +Enable=Enable a disabled E1 link MTP2 layer. +Inhibit=Inhibit E1 link MTP3 layer. +Uninhibit=Uninhibit a inhibited E1 link MTP3 layer. +Default=Enable a disabled E1 link MTP2 layer. + +Field : total(1) +Access : write-only [1]E1 link + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + [v]2[opt]Inhibit + [v]3[opt]Uninhibit + } + + +Create node: TCP_Port(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.5.3) +-> father_name = [Link] +-> -> Link_Attributes(0) +-> -> Link_Command(1) +-> -> TCP_Port(2) + + +Register leaf node: TCP_Port. +Instance: 1 +Length : 2 +Flag : 255 +Default : ˆ +Remark : TCP server port for SCCP-Lite. + +Field : total(1) +Access : read-write[1]TCP Port + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) + + +Remark: Routing. + + +Create node: International(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.1) +-> father_name = [Routing] +-> -> International(0) + + +Register leaf node: International. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: International_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.2) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) + + +Register leaf node: International_Spare. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: National(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.3) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) +-> -> National(2) + + +Register leaf node: National. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: National_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.6.4) +-> father_name = [Routing] +-> -> International(0) +-> -> International_Spare(1) +-> -> National(2) +-> -> National_Spare(3) + + +Register leaf node: National_Spare. +Instance: 256 +Length : 5 +Flag : 255 +Default : +Remark : Assign a normal linkset and an alternative linkset for each destination point code for signaling addressing. Basically the normal linkset is always used. The alternative linkset can only be used when the normal linkset is not available. Default=0x0000008080. + +Field : total(3) +Access : read-write[1]DPC + { + [u]0.0-2.7 + [u]input + [v]toDec high 0 + } +[2]Normal linkset + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Alternative linkset + { + [u]4.0-4.7 + [u]input + [v]toDec high 0 + } + + +Create node: SPC_to_ACN(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) +-> -> SPC_to_ACN(5) + + +Remark: SPC to ACN. + + +Create node: Local_ACN(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.1) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) + + +Register leaf node: Local_ACN. +Instance: 1 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: International(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.2) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) + + +Register leaf node: International. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: International_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.3) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) + + +Register leaf node: International_Spare. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: National(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.4) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) +-> -> National(3) + + +Register leaf node: National. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: National_Spare(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.7.5) +-> father_name = [SPC_to_ACN] +-> -> Local_ACN(0) +-> -> International(1) +-> -> International_Spare(2) +-> -> National(3) +-> -> National_Spare(4) + + +Register leaf node: National_Spare. +Instance: 256 +Length : 36 +Flag : 255 +Default :  +Remark : The ACN facility enables the version negotiation for the above messages, which make the WXC2 System more compatible with the other networks by means of flexible message version adjustment. The adjustable version includes Version 1, Version 2 and Version 3. + +Field : total(36) +Access : read-write [1]Network Location Update + { + [u]0.0-0.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [2]Location Cancel + { + [u]1.0-1.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [3]Roaming number nequiry + { + [u]2.0-2.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [4]Location Info Retrieval + { + [u]3.0-3.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [5]Reset Context + { + [u]4.0-4.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [6]Handover Control + { + [u]5.0-5.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [7]Equipment management + { + [u]6.0-6.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [8]Info Retrieval + { + [u]7.0-7.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [9]Inter VLR Info Retrieval + { + [u]8.0-8.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [10]Subscriber Data Management + { + [u]9.0-9.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [11]Tracing + { + [u]10.0-10.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [12]Network Functional SS + { + [u]11.0-11.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [13]Network Unstructured SS + { + [u]12.0-12.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [14]Short Message Gateway + { + [u]13.0-13.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [15]Short Messsage MO Relay + { + [u]14.0-14.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [16]Short Message Alert + { + [u]15.0-15.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [17]Short Message Waiting Data Management + { + [u]16.0-16.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [18]Mobile Terminating Short Message Relay + { + [u]17.0-17.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [19]IMSI Retrieval + { + [u]18.0-18.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [20]MS purging + { + [u]19.0-19.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [21]Subscriber Info Enquiry + { + [u]20.0-20.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [22]Any Time Info Enquiry + { + [u]21.0-21.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [23]Call Control Transfer + { + [u]22.0-22.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [24]Invocation Notification + { + [u]23.0-23.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [25]SIWFS Allocation + { + [u]24.0-24.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [26]Group Call Control + { + [u]25.0-25.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [27]GPRS Location Update + { + [u]26.0-26.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [28]GPRS Location Info Retrieval + { + [u]27.0-27.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [29]Failure Report + { + [u]28.0-28.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [30]GPRS Notify + { + [u]29.0-29.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [31]Reporting + { + [u]30.0-30.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [32]Call Completion + { + [u]31.0-31.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [33]Security Triplets + { + [u]32.0-32.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [34]Subscriber Interrogate + { + [u]33.0-33.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [35]HLR Subscriber Management + { + [u]34.0-34.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + [36]HLR Ping AUC + { + [u]35.0-35.7 + [u]select + [v]2[opt]Version 2 + [v]3[opt]Version 3 + } + + +Create node: Signaling_Gateway(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.2.9) +-> father_name = [Config_MTP3] +-> -> Network_Indicator(0) +-> -> OPC(1) +-> -> Linkset(2) +-> -> Link(3) +-> -> Routing(4) +-> -> SPC_to_ACN(5) +-> -> Signaling_Gateway(6) + + +Register leaf node: Signaling_Gateway. +Instance: 256 +Length : 7 +Flag : 255 +Default : +Remark : SG attributes + +Field : total(4) +Access : read-write [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Server + { + [u]1.0-1.7 + [u]select + [v]0[opt]Client + [v]1[opt]Server + } + [3]ACK + { + [u]2.0-2.7 + [u]select + [v]0[opt]no ACK + [v]1[opt]ACK + } +[4]IP + { + [u]3.0-6.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Status_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3) +-> father_name = [MTP3] +-> -> Config_MTP3(0) +-> -> Status_MTP3(1) + + +Remark: MTP3 Status. + + +Create node: Link_Status(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.1) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) + + +Register leaf node: Link_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default :  +Remark : E1 link MTP3 status (Read Only). + +Field : total(1) +Access : read-only [1]Link status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Inhibited + } + + +Create node: Linkset_Status(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.2) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) + + +Register leaf node: Linkset_Status. +Instance: 128 +Length : 1 +Flag : 255 +Default :  +Remark : Linkset status (Read only). + +Field : total(1) +Access : read-only [1]Linkset status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Unavailable + [v]1[opt]Available + [v]2[opt]Reserved + } + + +Create node: International_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.3) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) + + +Register leaf node: International_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: International_Spare_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.4) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) + + +Register leaf node: International_Spare_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: National_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.5) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) + + +Register leaf node: National_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: National_Spare_Routing(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.6) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) +-> -> National_Spare_Routing(5) + + +Register leaf node: National_Spare_Routing. +Instance: 256 +Length : 1 +Flag : 255 +Default : Š +Remark : Normal linkset status (bit0-1): +- 0=Available +- 1=Reserved +- 2=Unavailable +Alternative linkset status (bit2-3): +- 0=Available +- 1=Reserved +- 2=Unavailable +DPC accessibility (bit4): +- 0=Inaccessible +- 1=Accessible +Current route (bit3-7): +- 0=Normal linkset +- 1=Alternative linkset +- 2=No route. + +Field : total(4) +Access : read-only [1]Normal linkset + { + [u]0.0-0.1 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [2]Alternative linkset + { + [u]0.2-0.3 + [u]select + [v]0[opt]available + [v]1[opt]reserved + [v]2[opt]unavailable + } + [3]DPC accessibility + { + [u]0.4-0.4 + [u]select + [v]0[opt]inaccessible + [v]1[opt]accessible + } + [4]Current route + { + [u]0.6-0.7 + [u]select + [v]0[opt]normal linkset + [v]1[opt]alternative linkset + [v]2[opt]no route + } + + +Create node: Command_MTP3(OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.7) +-> father_name = [Status_MTP3] +-> -> Link_Status(0) +-> -> Linkset_Status(1) +-> -> International_Routing(2) +-> -> International_Spare_Routing(3) +-> -> National_Routing(4) +-> -> National_Spare_Routing(5) +-> -> Command_MTP3(6) + + +Register leaf node: Command_MTP3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for MTP3 platform. +Reset=status initialization. +Save parameter=save parameters residing in memory into harddisk. + +Field : total(1) +Access : read-write [1]command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No command + [v]1[opt]Reset + [v]2[opt]Save parameter + } + + +Create node: SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3) +-> father_name = [SS7] +-> -> MTP3(0) +-> -> SCCP(1) + + +Remark: Subsystems for SCCP . + + +Create node: Config_SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2) +-> father_name = [SCCP] +-> -> Config_SCCP(0) + + +Remark: SCCP Configuration. + + +Create node: Local_Node(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1) +-> father_name = [Config_SCCP] +-> -> Local_Node(0) + + +Remark: Local Node. + + +Create node: OMC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.4) +-> father_name = [Local_Node] +-> -> OMC(0) + + +Register leaf node: OMC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: OMC E.134 number. +IP0: OMC0 IP, 172.18.128.1. +IP1: OMC1 IP, 172.18.129.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: HLR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.6) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) + + +Register leaf node: HLR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: HLR E.134 number. +IP0: HLR0 IP, 172.18.98.1. +IP1: HLR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: VLR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.7) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) + + +Register leaf node: VLR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VLR E.134 number. +IP0: VLR0 IP, 172.18.98.1. +IP1: VLR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: MSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.8) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) + + +Register leaf node: MSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: MSC E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: EIR(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.9) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) + + +Register leaf node: EIR. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: EIR E.134 number. +IP0: EIR0 IP, 172.18.98.1. +IP1: EIR1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: AUC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.10) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) + + +Register leaf node: AUC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: AUC E.134 number. +IP0: AUC0 IP, 172.18.98.1. +IP1: AUC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.11) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) + + +Register leaf node: SMSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: SMSC E.134 number. +IP0: OMC0 IP, 172.18.98.1. +IP1: OMC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_EMSE(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.19) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) + + +Register leaf node: SMPP_EMSE. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VMS-SMPP E.134 number. +IP0: VMS0 IP, 172.18.147.1. +IP1: VMS1 IP, 172.18.148.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_SMSC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.20) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) + + +Register leaf node: SMPP_SMSC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: SMSC-SMPP E.134 number. +IP0: SMSC0 IP, 172.18.98.1. +IP1: SMSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SMPP_OMC(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.21) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) + + +Register leaf node: SMPP_OMC. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: OMC-SMPP E.134 number. +IP0: OMC0 IP, 172.18.128.1. +IP1: OMC1 IP, 172.18.129.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SRF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.22) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) + + +Register leaf node: SRF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: VMS SRF E.134 number. +IP0: VMS0 IP, 172.18.147.1. +IP1: VMS1 IP, 172.18.148.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SSF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.143) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) + + +Register leaf node: SSF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: MSC SSF E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: SCF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.147) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) +-> -> SCF(12) + + +Register leaf node: SCF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: PPS SCF E.134 number. +IP0: PPS0 IP, 172.18.98.1. +IP1: PPS1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: AIF(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.1.254) +-> father_name = [Local_Node] +-> -> OMC(0) +-> -> HLR(1) +-> -> VLR(2) +-> -> MSC(3) +-> -> EIR(4) +-> -> AUC(5) +-> -> SMSC(6) +-> -> SMPP_EMSE(7) +-> -> SMPP_SMSC(8) +-> -> SMPP_OMC(9) +-> -> SRF(10) +-> -> SSF(11) +-> -> SCF(12) +-> -> AIF(13) + + +Register leaf node: AIF. +Instance: 1 +Length : 19 +Flag : 255 +Default : +Remark : NI: Network indicator. +0=International network. +1=International network spare. +2=National network. +3=National network spare. +MSISDN: AIF E.134 number. +IP0: MSC0 IP, 172.18.98.1. +IP1: MSC1 IP, 172.18.99.1. + +Field : total(4) +Access : read-write[1]NI + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low F + } +[2]MSISDN + { + [u]1.0-10.7 + [u]input + [v]KeepHex Low F + } +[3]IP0 + { + [u]11.0-14.7 + [u]input + [v]KeepHex Low F + } +[4]IP1 + { + [u]15.0-18.7 + [u]input + [v]KeepHex Low F + } + + +Create node: GTT_Table(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.2.2) +-> father_name = [Config_SCCP] +-> -> Local_Node(0) +-> -> GTT_Table(1) + + +Register leaf node: GTT_Table. +Instance: 256 +Length : 43 +Flag : 255 +Default : +Remark : On/off: GTT flag, off=disable, on=enable. +Numbering plan: 1=MSISDN, 3=IMSI, 7=GT. +Specify the beginning number of a group of consecutive numbers routed by GTT, for single-number GTT route, the start number is same as the end number. +End GT number: Specify the end number of a group of consecutive number routed by GT. If there are some inconsecutive numbers for a same destination, a different GTT record should be set. +Network indicator (NI): 0=International network, 1=International network spare, 2=National network, 3=National network spare, +DPC: Destination point code. +SSN: Subsystem number. +2=Reserved for ITU-T allocation. +3=ISDN user part. +4=OMC. +5=MAP. +3=HLR. +7=VLR. +8=MSC. +9=EIR. +10=AUC. +11=SMSC. +147=PPS. +254=BSSMAP. +Route indicator: For IMSI and MSISDN, select Route on SSN. For the record of the connected network, select Route on GT. +Address indicator: select the contribution of SCCP Address. +Replaced start digit: Specify the beginning digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. +Replaced end digit: Specify the end digit of a segment of digits to be replaced within a GT number, the replacement is for changing number and numbering plan. +Outgoing number plan: Outgoing number plan, include MSISDN, IMSI and GT. +Replacing digits: Replacing digits, the length of replacing digits and replaced digits may be different. + +Field : total(14) +Access : read-write [1]On/off + { + [u]0.0-0.7 + [u]select + [v]1[opt]On + [v]0[opt]Off + } + [2]Numbering plan + { + [u]1.0-1.7 + [u]select + [v]0[opt]0 + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } +[3]TT + { + [u]2.0-2.7 + [u]input + [v]KeepHex Low F + } +[4]Start GT number + { + [u]3.0-12.7 + [u]input + [v]KeepHex Low F + } +[4]End GT number + { + [u]13.0-22.7 + [u]input + [v]KeepHex Low F + } + [5]Network indicator + { + [u]23.0-23.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + } +[6]DPC + { + [u]24.0-26.7 + [u]input + [v]toDec high 0 + } +[7]SSN + { + [u]27.0-27.7 + [u]input + [v]toDec high 0 + } + [8]Route indicator + { + [u]28.0-28.7 + [u]select + [v]0[opt]Route on GT + [v]1[opt]Route on SSN + } + [9]Address indicator + { + [u]29.0-29.7 + [u]select + [v]0[opt]NULL + [v]3[opt]DPC+SSN + [v]6[opt]GT+SSN + [v]7[opt]GT+DPC+SSN + } +[10]Replaced start digit + { + [u]30.0-30.7 + [u]input + [v]KeepHex high 0 + } +[11]Replaced end digit + { + [u]31.0-31.7 + [u]input + [v]KeepHex high 0 + } + [12]Outgoing number plan + { + [u]32.0-32.7 + [u]select + [v]1[opt]MSISDN + [v]6[opt]IMSI + [v]7[opt]GT + } +[13]Replacing digits + { + [u]33.0-42.7 + [u]input + [v]KeepHex Low F + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3) +-> father_name = [SCCP] +-> -> Config_SCCP(0) +-> -> Management(1) + + +Remark: Management. + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.1) +-> father_name = [Management] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of SCCP platform software (Read Only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-write + +Create node: Command_SCCP(OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.2) +-> father_name = [Management] +-> -> Version(0) +-> -> Command_SCCP(1) + + +Register leaf node: Command_SCCP. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for SCCP. +Reset: Used for SCCP status initialization. +Load parameter: Load the parameters from device's harddisk to device's memory. +Save parameter: Save the parameters residing in device's memory into device's harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]0[opt]Reset + [v]2[opt]Save parameters + } + + +Create node: XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5) +-> father_name = [SS7] +-> -> MTP3(0) +-> -> SCCP(1) +-> -> XAPP(2) + + +Remark: Subsystems for XAPP . + + +Create node: Config_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2) +-> father_name = [XAPP] +-> -> Config_XAPP(0) + + +Remark: XAPP Configuration. + + +Create node: MCC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.1) +-> father_name = [Config_XAPP] +-> -> MCC(0) + + +Register leaf node: MCC. +Instance: 1 +Length : 2 +Flag : 255 +Default : F +Remark : Mobile country code. + +Field : total(1) +Access : read-write[1]MCC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: MNC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.2) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) + + +Register leaf node: MNC. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Mobile network code. + +Field : total(1) +Access : read-write[1]MNC + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low E + } + + +Create node: CC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.3) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) + + +Register leaf node: CC. +Instance: 1 +Length : 2 +Flag : 255 +Default : †î +Remark : Country code. + +Field : total(1) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: NDC(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.4) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) + + +Register leaf node: NDC. +Instance: 1 +Length : 3 +Flag : 255 +Default : u^î +Remark : National destination code. + +Field : total(1) +Access : read-write[1]NDC + { + [u]0.0-2.7 + [u]input + [v]KeepHex Low E + } + + +Create node: International_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.5) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) + + +Register leaf node: International_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : International call prefix. + +Field : total(1) +Access : read-write[1]International prefix + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: National_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.6) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) + + +Register leaf node: National_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : î +Remark : National call prefix. + +Field : total(1) +Access : read-write[1]National prefix + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Local_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.7) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) + + +Register leaf node: Local_Prefix. +Instance: 1 +Length : 2 +Flag : 255 +Default : îî +Remark : Local prefix. + +Field : total(0) +Access : read-write + +Create node: Conv_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.8) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) + + +Register leaf node: Conv_Prefix. +Instance: 128 +Length : 35 +Flag : 255 +Default : +Remark : Conv prefix . + +Field : total(5) +Access : read-write[1]Prefix + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } +[2]Delete length + { + [u]0.0-0.0 + [u]input + [v]toDec high 0 + } +[3]Add length + { + [u]17.0-17.7 + [u]input + [v]toDec high 0 + } +[4]Add digits + { + [u]18.0-33.7 + [u]input + [v]ToAscii Low 0 + } +[5]Valid length + { + [u]34.0-34.7 + [u]input + [v]toDec high 0 + } + + +Create node: CLI_Conv_Prefix(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.9) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) +-> -> CLI_Conv_Prefix(8) + + +Register leaf node: CLI_Conv_Prefix. +Instance: 8 +Length : 37 +Flag : 255 +Default : +Remark : CLI_Conv prefix . + +Field : total(7) +Access : read-write [1]In property + { + [u]0.0-0.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } +[2]Prefix + { + [u]1.0-16.7 + [u]input + [v]ToAscii Low 0 + } +[3]Delete length + { + [u]17.0-17.7 + [u]input + [v]toDec high 0 + } + [4]Out property + { + [u]18.0-18.7 + [u]select + [v]1[opt]IDD + [v]2[opt]NDD + [v]3[opt]Unknown + } +[5]Add length + { + [u]19.0-19.7 + [u]input + [v]toDec high 0 + } +[6]Add digits + { + [u]20.0-35.7 + [u]input + [v]ToAscii Low 0 + } +[7]Valid length + { + [u]36.0-36.7 + [u]input + [v]toDec high 0 + } + + +Create node: mscid_to_number(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.2.10) +-> father_name = [Config_XAPP] +-> -> MCC(0) +-> -> MNC(1) +-> -> CC(2) +-> -> NDC(3) +-> -> International_Prefix(4) +-> -> National_Prefix(5) +-> -> Local_Prefix(6) +-> -> Conv_Prefix(7) +-> -> CLI_Conv_Prefix(8) +-> -> mscid_to_number(9) + + +Register leaf node: mscid_to_number. +Instance: 256 +Length : 12 +Flag : 255 +Default : +Remark : Conv prefix . + +Field : total(4) +Access : read-write[1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } +[3]SSN + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } +[4]Number + { + [u]4.0-11.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Status_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3) +-> father_name = [XAPP] +-> -> Config_XAPP(0) +-> -> Status_XAPP(1) + + +Remark: XAPP Status. + + +Create node: Version_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.1) +-> father_name = [Status_XAPP] +-> -> Version_XAPP(0) + + +Register leaf node: Version_XAPP. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of XAPP module (Read Only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-only + +Create node: Command_XAPP(OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.2) +-> father_name = [Status_XAPP] +-> -> Version_XAPP(0) +-> -> Command_XAPP(1) + + +Register leaf node: Command_XAPP. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Control command for XAPP. +Save parameter: Save the parameters in memory into local harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + } + + +Create node: Maplat(OID: 1.3.6.1.4.1.1373.1.3.2.3) +-> father_name = [Platform] +-> -> SS7(0) +-> -> Maplat(1) + + +Remark: + Subsystems for Maplat . + + +Create node: SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4) +-> father_name = [Maplat] +-> -> SMPP(0) + + +Remark: Subsystems for SMPP . + + +Create node: Config_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.2) +-> father_name = [SMPP] +-> -> Config_SMPP(0) + + +Remark: SMPP Configuration. + + +Create node: SMPP_Link_Parameter(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.2.1) +-> father_name = [Config_SMPP] +-> -> SMPP_Link_Parameter(0) + + +Register leaf node: SMPP_Link_Parameter. +Instance: 32 +Length : 106 +Flag : 255 +Default : +Remark : Session type: BIND_TX-bind as transmitter, BIND_RX-bind as receiver, BIND_TRX-bind as transceiver. +System ID: using in BIND and OUTBIND. +Password: The password parameter is used by the SMSC to authenticate the identity of the binding ESME. The Service Provider may require ESME¡¯s to provide a password when binding to the SMSC. This password is normally issued by the SMSC system administrator. +The password parameter may also be used by the ESME to authenticate the identity of the binding SMSC (e.g. in the case of the outbind operation). +System type: The system_type may be used to categorise the system, e.g., ¡°EMAIL¡±, ¡°WWW¡±, etc. +The system_type parameter is used to categorize the type of ESME that is binding to the SMSC. Examples include ¡°VMS¡± (voice mail system) and ¡°OTA¡± (over-the-air activation system). +Specification of the system_type is optional - some SMSC¡¯s may not require ESME¡¯s to provide this detail. In this case, the ESME can set the system_type to NULL. +IP: Specify the IP addresses of 16 SMPP connected devices.
e.g. 0xAC127001=172.18.112.1.
+Session init timer: This timer specifies the time lapse allowed between a network connection being established and a bind_transmitter or bind_receiver request being sent to SMSC. This timer should be active on the SMSC. +Enquire link timer: This timer specifies the time lapse allowed between operations after which an SMPP entity should interrogate whether it's peer still has an active session. +The scale is second. +Inactivity timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) +Response timer: This timer specifies the maximum time lapse allowed between transactions, after which period of inactivity, an SMPP entity may assume that the session is no longer active. This timer may be active on either commnicating SMPP entity(i.e. SMSC or ESME) +Local service number: compare with application's service number while bind as TX or TRX. +remote service number: compare with application's service number while bind as RX + +Field : total(16) +Access : read-write [1]Link enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Link type + { + [u]1.0-1.7 + [u]select + [v]0[opt]UDP + [v]1[opt]TCP + } + [3]Server type + { + [u]2.0-2.7 + [u]select + [v]0[opt]SMPP_CLIENT + [v]1[opt]SMPP_SERVER + } + [4]Session type + { + [u]3.0-3.7 + [u]select + [v]0[opt]BIND_TX + [v]1[opt]BIND_RX + [v]2[opt]BIND_TRX + } +[5]System ID + { + [u]4.0-19.7 + [u]input + [v]ToAscii Low 0 + } +[6]Password + { + [u]20.0-28.7 + [u]input + [v]ToAscii Low 0 + } +[7]System type + { + [u]29.0-41.7 + [u]input + [v]ToAscii Low 0 + } +[8]Local GTT + { + [u]42.0-57.7 + [u]input + [v]ToAscii Low 0 + } +[9]Remote GTT + { + [u]58.0-73.7 + [u]input + [v]ToAscii Low 0 + } +[10]Local IP + { + [u]74.0-77.7 + [u]input + [v]KeepHex Low F + } +[11]Remote IP + { + [u]78.0-81.7 + [u]input + [v]KeepHex Low F + } +[12]Session init timer + { + [u]82.0-85.7 + [u]input + [v]toDec high 0 + } +[13]Enquire link timer + { + [u]86.0-89.7 + [u]input + [v]toDec high 0 + } +[14]Inactivity timer + { + [u]90.0-93.7 + [u]input + [v]toDec high 0 + } +[15]Response timer + { + [u]94.0-97.7 + [u]input + [v]toDec high 0 + } +[16]Remote service number + { + [u]98.0-105.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Status_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3) +-> father_name = [SMPP] +-> -> Config_SMPP(0) +-> -> Status_SMPP(1) + + +Remark: XAPP Status. + + +Create node: Command_SMPP(OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3.2) +-> father_name = [Status_SMPP] +-> -> Command_SMPP(0) + + +Register leaf node: Command_SMPP. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Control command for SMPP. + +Field : total(1) +Access : write-only [1]Command + { + [u]0.0-0.7 + [u]select + [v]2[opt]save parameter + } + + +Create node: MSC(OID: 1.3.6.1.4.1.1373.1.3.3.2) +-> father_name = [App] +-> -> MSC(0) + + +Remark: + Subsystems for msc . + + +Create node: CCF(MSC)(OID: 1.3.6.1.4.1.1373.1.3.3.2.2) +-> father_name = [MSC] +-> -> CCF(MSC)(0) + + +Remark: Subsystems for msc . + + +Create node: CCF_Config(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2) +-> father_name = [CCF(MSC)] +-> -> CCF_Config(0) + + +Remark: + Configuration for CCF . + + +Create node: Call_Routing(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) + + +Remark: + Call Routing . + + +Create node: Prefix_Assignment(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.1) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) + + +Register leaf node: Prefix_Assignment. +Instance: 256 +Length : 8 +Flag : 255 +Default : îîîîîîîî +Remark : 4 bytes are used to set a 8-digit prefix for dialed number. +Prefix is the first layer for dialed number based call routing. If the dialed number of a call matches a pre-programmed prefix in this table, this call will be routed to a certain trunk group, subsequently that trunk group will route this call via a dedicated E1 port.This system has totally 256 prefixes. +Dialed number without matching a pre-programmed prefix will be routed to the default trunk group 0. +Prefix 252 is for default international call, all internation calls unable to be routed out will be routed from the trunk group assigned to prefix 252, keep default EEEEEEEE. +Prefix 253 is for default national call, all national calls unable to be routed out will be routed from the trunk group assigned to prefix 253, keep default EEEEEEEE. +Prefix 254 is for default subscriber call, all dialed MSISDN unable to be routed out will be routed from the trunk group assigned to prefix 254, keep default EEEEEEEE. +Prefix 255 is for unknown call, all unknown calls unable to be routed out will be routed from the trunk group assigned to prefix 255, keep default EEEEEEEE. +E=End tag, C='#', B='*'. +Default=0xEEEEEEEE. + +Field : total(1) +Access : read-write[1]Prefix + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Prefix_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.2) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) + + +Register leaf node: Prefix_Attributes. +Instance: 256 +Length : 18 +Flag : 9 +Default : " +Remark : Enable: Y=prefix enable, N=prefix disable. +TON incoming call: Type of number for incoming call, include unknown, MSISDN, NDD and IDD. It is specified by originating node for terminating node to route this call with proper dialed number manipulation. +For system subscriber dialed prefix, always use unknown for In-TON except the prefix of international prefix beginning with a . For this kind of prefix (such as 86755832) we should set the In-TON as IDD to support dialing. +TON outgoing call: Type of number for outgoing call, include unknown, MSISDN, NDD and IDD. It specifies the type of an outgoing call for terminating node to route this call with proper dialed number manipulation. Generally the MSC uses IDD for outgoing call. +Out trunk deletion count: Quantity of deleted digit of a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no deletion, 1-8=delete first 1-8 digits. +Out trunk insertion count: Quantity of inserted digit for a dialed number beginning with this prefix. It ranges from 0 to 8. 0=no insertion, 1-8=insert 1-8 digits from the beginning of this number. +Out trunk inserted digits: 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number. +CDR on/off: Turn on/off the CDR of dialed numbers beginning with this prefix. +Properties: Specify the properties of a prefix. Trunk=to PSTN, MSISDN=to A interface, MSRN=MS roaming number, MSC=to peer MSC. +Call type: Normal=no verification for MT, Emergency call=no verification for MO (free call), MCT=Malicious Call Trace, VMS call=send signaling carried DTMF to VMS. +Length of dialed number: Length of dialed number (1-32). +E.164 international deletion count: Quantity of deleted digit of E164 international number, always use IDD for outgoing call for PPS debiting. +E.164 international insertion count: Quantity of inserted digit of E164 international number, always use IDD for outgoing call for PPS debiting. +E.164 international inserted digits: Inserted digit to the E164 international number, 8 digits ranging from EEEEEEEE to 99999999, E=any decimal number, always use IDD for outgoing call for PPS debiting. + +Field : total(15) +Access : read-write [1]TON incoming call + { + [u]0.0-0.3 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [2]TON outgoing call + { + [u]0.4-0.7 + [u]select + [v]0[opt]Spare + [v]1[opt]MSISDN + [v]2[opt]Unkown + [v]3[opt]NDD + [v]4[opt]IDD + [v]5[opt]Spare + } + [3]Out trunk deletion count + { + [u]1.0-1.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [4]Out trunk insertion count + { + [u]1.4-1.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } +[5]Out trunk inserted digits + { + [u]2.0-9.7 + [u]input + [v]KeepHex Low E + } + [6]CDR on/off + { + [u]10.0-10.0 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [8]Properties + { + [u]10.2-10.3 + [u]select + [v]0[opt]Trunk + [v]1[opt]MSISDN + [v]2[opt]MSRN + [v]3[opt]MSC + } + [9]Call type + { + [u]10.4-10.6 + [u]select + [v]0[opt]Normal Call + [v]1[opt]Emergency + [v]2[opt]MCT + [v]3[opt]VMS + [v]4[opt]IN + } + [10]Enable + { + [u]10.7-10.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } +[11]Length of dialed number + { + [u]11.0-11.7 + [u]input + [v]toDec high 0 + } + [12]E.164 International deletion count + { + [u]12.0-12.3 + [u]select + [v]0[opt]Delete none + [v]1[opt]Delete first one + [v]2[opt]Delete first two + [v]3[opt]Delete first three + [v]4[opt]Delete first four + [v]5[opt]Delete first five + [v]6[opt]Delete first six + [v]7[opt]Delete first seven + [v]8[opt]Delete first eight + } + [13]E.164 International insertion count + { + [u]12.4-12.7 + [u]select + [v]0[opt]Insert none + [v]1[opt]Insert first one + [v]2[opt]Insert first two + [v]3[opt]Insert first three + [v]4[opt]Insert first four + [v]5[opt]Insert first five + [v]6[opt]Insert first six + [v]7[opt]Insert first seven + [v]8[opt]Insert first eight + } +[14]E.164 international inserted digits + { + [u]13.0-16.7 + [u]input + [v]KeepHex Low E + } + [15]Cli-type + { + [u]17.0-17.7 + [u]select + [v]0[opt]Sub + [v]1[opt]NDD + [v]2[opt]IDD + [v]3[opt]Unknown(local) + [v]4[opt]Unknown(NDD) + [v]5[opt]Unknown(IDD) + } + + +Create node: Prefix_TG(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.3) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) + + +Register leaf node: Prefix_TG. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Assign a trunk group for each prefix for call routing, a single prefix points to only one trunk group, multiple prefix can be assigned the same trunk group, default is the no. of the prefix. + +Field : total(1) +Access : read-write[1]Assign TG to prefix + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: TG_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.4) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) + + +Register leaf node: TG_Attributes. +Instance: 256 +Length : 10 +Flag : 1 +Default : +Remark : DPC: Destination point code of this trunk group. +TG flag: enable or disable this trunk group. +CDR on/off: CDR on or off option for this trunk group. +Announcement: Voice announcement enable or disable for this trunk group. +TG category: PSTN=to PSTN, IP=to VMS and VPS, HPLMN=to HPLMN, VPLMN=to VPLMN, SUB=to BSC, Intercept=to intercept LEA +Alternative TG flag: Alternative trunk group enable or disable option. +Alternative TG: Alternative trunk group for backup purpose. +Loop back: Incoming call loop back enable or disable, used for MSC loop back. +Network indicator: Specify network type, International, International spare , National, National spare. +Circuit selection: Preferred circuit selection mode, include clockwise, anti-clockwise, odd and even. +Back off: Back off on or off when simultaneously select the same channel with the opposite side. +Location: For normal trunk group, select Both. For a trunk group to a VPS, configure this trunk group as MSC0 or MSC1. +MPTY: Multi-party call enable or disable. For all trunk groups to BSC, select Enable. +Tandem restriction:Y: Tandem disabled. Not support transit call from PSTN to PSTN via this trunk group. +N: Tandem enabled. Support transit call from PSTN to PSTN via this trunk group. + +Field : total(16) +Access : read-write[1]DPC + { + [u]0.0-3.7 + [u]input + [v]KeepHex high 0 + } + [2]TG flag + { + [u]4.0-4.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]CDR on/off + { + [u]4.1-4.1 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [4]Announcement + { + [u]4.2-4.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [5]TG category + { + [u]4.3-4.5 + [u]select + [v]0[opt]PSTN + [v]1[opt]HPLMN + [v]2[opt]VHLMN + [v]3[opt]SUB + [v]4[opt]IP + [v]5[opt]Intercept + } + [6]Alternative TG flag + { + [u]4.6-4.6 + [u]select + [v]0[opt]Disable + [v]1[opt]enable + } + [7]Loopback + { + [u]4.7-4.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [8]Network indicator + { + [u]5.0-5.7 + [u]select + [v]0[opt]International + [v]1[opt]International spare + [v]2[opt]National + [v]3[opt]National spare + } + [9]Circuit selection + { + [u]6.0-6.1 + [u]select + [v]0[opt]Clockwise + [v]1[opt]Anti-clockwise + [v]2[opt]Odd + [v]3[opt]Even + } + [10]Back off + { + [u]6.2-6.2 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + [12]MPTY + { + [u]6.5-6.5 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [13]Location + { + [u]6.6-6.7 + [u]select + [v]0[opt]MSC-0 + [v]1[opt]MSC-1 + [v]2[opt]Both + [v]3[opt]Spare + } +[14]Alternative TG + { + [u]7.0-7.7 + [u]input + [v]toDec high 0 + } + [15]Tandem restriction + { + [u]8.0-8.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [16]Incoming Call type + { + [u]9.0-9.7 + [u]select + [v]0[opt]Normal + [v]1[opt]IN + } + + +Create node: Call_Routing_CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.5) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) + + +Register leaf node: Call_Routing_CDR_Flag. +Instance: 1 +Length : 2 +Flag : 255 +Default : ÿ +Remark : Sorm: call intercept MCT: malicious call trace +Default=CDR of MO call and MT call is enabled, CDR of roaming call, gateway incoming call, gateway outgoing call, transit call, MO SMS and MT SMS is disabled. + +Field : total(13) +Access : read-write [2]Redirection + { + [u]0.3-0.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [3]Feature Request + { + [u]0.2-0.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [4]Sorm + { + [u]0.1-0.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [5]MCT + { + [u]0.0-0.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [6]MT SM + { + [u]1.7-1.7 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [7]MO SM + { + [u]1.6-1.6 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [8]Transit call + { + [u]1.5-1.5 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [9]Gateway outgoing call + { + [u]1.4-1.4 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [10]Gateway incoming call + { + [u]1.3-1.3 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [11]Roaming call + { + [u]1.2-1.2 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [12]MT call + { + [u]1.1-1.1 + [u]select + [v]0[opt]off + [v]1[opt]on + } + [13]MO call + { + [u]1.0-1.0 + [u]select + [v]0[opt]off + [v]1[opt]on + } + + +Create node: Voice_Prompt_Announcement_option(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.6) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) +-> -> Voice_Prompt_Announcement_option(5) + + +Register leaf node: Voice_Prompt_Announcement_option. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Set to play either announcement or tone indicating call unattainable reason for subscribers. System has total 8 announcements and tones that can be independently set. +Announcement 0: The dialed number is invalid. +Announcement 1: The subscriber dialed is not activated. +Announcement 2: The subscriber is busy. +Announcement 3: The network is busy. +Announcement 4: Caller's account was deactivated. +Announcement 5: The subscriber dialed was deactivated. +Announcement 6: Feature not available to caller. +Announcement 7: The subscriber dialed is not available. + +Field : total(16) +Access : read-write [1]Announcement 0 + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [2]Announcement 1 + { + [u]1.0-1.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [3]Announcement 2 + { + [u]2.0-2.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [4]Announcement 3 + { + [u]3.0-3.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [5]Announcement 4 + { + [u]4.0-4.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [6]Announcement 5 + { + [u]5.0-5.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [7]Announcement 6 + { + [u]6.0-6.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [8]Announcement 7 + { + [u]7.0-7.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [9]Announcement 8 + { + [u]8.0-8.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [10]Announcement 9 + { + [u]9.0-9.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [11]Announcement 10 + { + [u]10.0-10.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [12]Announcement 11 + { + [u]11.0-11.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [13]Announcement 12 + { + [u]12.0-12.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [14]Announcement 13 + { + [u]13.0-13.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [15]Announcement 14 + { + [u]14.0-14.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + [16]Announcement 15 + { + [u]15.0-15.7 + [u]select + [v]0[opt]None + [v]1[opt]Tone + [v]2[opt]Voice + [v]3[opt]lease line + } + + +Create node: Call_Routing_Warning(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.1.7) +-> father_name = [Call_Routing] +-> -> Prefix_Assignment(0) +-> -> Prefix_Attributes(1) +-> -> Prefix_TG(2) +-> -> TG_Attributes(3) +-> -> Call_Routing_CDR_Flag(4) +-> -> Voice_Prompt_Announcement_option(5) +-> -> Call_Routing_Warning(6) + + +Register leaf node: Call_Routing_Warning. +Instance: 1 +Length : 1 +Flag : 255 +Default : 2 +Remark : Set time to play prompt tone for reaching zero balance prepaid subscriber when a call is in progress, unit is second. e.g. if set as 60, the system will play prompt tone one minute before a subscriber uses up his balance. + +Field : total(1) +Access : read-write[1]Remanent time for warning tone + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: CCF_MSC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) + + +Remark: CCF Configuration MSC . + + +Create node: Emergency_Call(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2.5) +-> father_name = [CCF_MSC] +-> -> Emergency_Call(0) + + +Register leaf node: Emergency_Call. +Instance: 256 +Length : 21 +Flag : 0 +Default : +Remark : Emergency call number. Default=112. + +Field : total(5) +Access : read-write [1]Enable flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]LAC + { + [u]1.0-2.7 + [u]input + [v]toDec high 0 + } +[3]CI + { + [u]3.0-4.7 + [u]input + [v]toDec high 0 + } +[4]Dial number + { + [u]5.0-12.7 + [u]input + [v]KeepHex Low E + } +[5]Local emergency number + { + [u]13.0-20.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Location_Management(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.2.8) +-> father_name = [CCF_MSC] +-> -> Emergency_Call(0) +-> -> Location_Management(1) + + +Register leaf node: Location_Management. +Instance: 256 +Length : 8 +Flag : 0 +Default : +Remark : Manage the MS location by correlate TG (trunk group), LAC (location area code, cell ID and zone code, totally 256 location management. + +Field : total(5) +Access : read-write [1]Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]N + [v]1[opt]Y + } +[2]TG + { + [u]1.0-1.7 + [u]input + [v]toDec high 0 + } +[3]LAC + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[4]CI + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } +[5]Zone Code + { + [u]6.0-7.7 + [u]input + [v]toDec high 0 + } + + +Create node: CPC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) + + +Remark: CPC Management. + + +Create node: SRF_Address(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3.3) +-> father_name = [CPC] +-> -> SRF_Address(0) + + +Register leaf node: SRF_Address. +Instance: 1 +Length : 8 +Flag : 255 +Default : †uP +Remark : E.164 number of HLR server:HLR MSISDN used for SCCP addressing, F=end tag. +Default=91867555950502FFFF=91867555950502. + +Field : total(1) +Access : read-write[1]EIR number + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Max_Call_Duration(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.3.7) +-> father_name = [CPC] +-> -> SRF_Address(0) +-> -> Max_Call_Duration(1) + + +Register leaf node: Max_Call_Duration. +Instance: 1 +Length : 1 +Flag : 255 +Default : < +Remark : Define the permitted maximum call duration. Any ongoing call reaching this duration threshold will be compulsively cut off. byte value: 0=disable this function, 1-255=max. call duration, unit=minute. Default=0. + +Field : total(1) +Access : read-write[1]Max. call duration + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_Port(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) + + +Remark: E1 Port. + + +Create node: E1_Interface(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.1) +-> father_name = [E1_Port] +-> -> E1_Interface(0) + + +Register leaf node: E1_Interface. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Set the type of E1 interface for 256 E1 ports. + +Field : total(1) +Access : read-write [1]E1 interface + { + [u]0.0-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF CDMA2K + [v]4[opt]BICC + [v]5[opt]CI-CNF + [v]6[opt]CI-loopback + } + + +Create node: E1_TG(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.2) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) + + +Register leaf node: E1_TG. +Instance: 256 +Length : 1 +Flag : 255 +Default : î +Remark : Assign a trunk group to each E1 port for call routing. A single E1 port points to only one trunk group, multiple E1 port can be assigned the same trunk group. Default=number of the E1 port. + +Field : total(1) +Access : read-write[1]Assign TG + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_CIC(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.3) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) +-> -> E1_CIC(2) + + +Register leaf node: E1_CIC. +Instance: 256 +Length : 4 +Flag : 255 +Default : +Remark : Circuit identity code, uniquely identify each circuit within a trunk group. CIC of both ends of a circuit must be identical. 256 CIC for dual MSC platform 256 E1 ports. + +Field : total(1) +Access : read-write[1]E1 CIC + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: E1_Media_Control_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.4.4) +-> father_name = [E1_Port] +-> -> E1_Interface(0) +-> -> E1_TG(1) +-> -> E1_CIC(2) +-> -> E1_Media_Control_Attributes(3) + + +Register leaf node: E1_Media_Control_Attributes. +Instance: 256 +Length : 4 +Flag : 255 +Default : +Remark : E1 Media Control Attributes + +Field : total(4) +Access : read-write [1]E1 Control Protocol Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Internal + [v]1[opt]MGCP + } + [2]E1 Enable + { + [u]1.0-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[3]MG Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } +[4]Trunk Number + { + [u]3.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Channel_Attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) + + +Remark: Channel attributes. + + +Create node: Card0_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.1) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) + + +Register leaf node: Card0_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card1_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.2) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) + + +Register leaf node: Card1_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card2_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.3) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) + + +Register leaf node: Card2_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card3_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.4) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) + + +Register leaf node: Card3_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card4_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.5) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) + + +Register leaf node: Card4_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card5_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.6) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) + + +Register leaf node: Card5_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card6_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.7) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) + + +Register leaf node: Card6_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card7_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.8) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) + + +Register leaf node: Card7_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card8_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.9) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) + + +Register leaf node: Card8_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card9_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.10) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) + + +Register leaf node: Card9_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card10_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.11) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) + + +Register leaf node: Card10_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card11_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.12) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) + + +Register leaf node: Card11_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card12_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.13) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) + + +Register leaf node: Card12_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card13_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.14) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) + + +Register leaf node: Card13_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card14_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.15) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) + + +Register leaf node: Card14_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card15_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.16) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) + + +Register leaf node: Card15_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card16_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.17) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) + + +Register leaf node: Card16_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card17_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.18) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) + + +Register leaf node: Card17_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card18_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.19) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) + + +Register leaf node: Card18_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card19_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.20) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) + + +Register leaf node: Card19_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card20_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.21) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) + + +Register leaf node: Card20_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card21_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.22) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) + + +Register leaf node: Card21_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card22_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.23) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) + + +Register leaf node: Card22_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card23_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.24) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) + + +Register leaf node: Card23_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card24_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.25) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) + + +Register leaf node: Card24_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card25_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.26) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) + + +Register leaf node: Card25_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card26_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.27) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) + + +Register leaf node: Card26_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card27_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.28) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) + + +Register leaf node: Card27_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card28_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.29) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) + + +Register leaf node: Card28_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card29_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.30) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) + + +Register leaf node: Card29_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card30_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.31) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) +-> -> Card30_Channel(30) + + +Register leaf node: Card30_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Card31_Channel(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.5.32) +-> father_name = [Channel_Attributes] +-> -> Card0_Channel(0) +-> -> Card1_Channel(1) +-> -> Card2_Channel(2) +-> -> Card3_Channel(3) +-> -> Card4_Channel(4) +-> -> Card5_Channel(5) +-> -> Card6_Channel(6) +-> -> Card7_Channel(7) +-> -> Card8_Channel(8) +-> -> Card9_Channel(9) +-> -> Card10_Channel(10) +-> -> Card11_Channel(11) +-> -> Card12_Channel(12) +-> -> Card13_Channel(13) +-> -> Card14_Channel(14) +-> -> Card15_Channel(15) +-> -> Card16_Channel(16) +-> -> Card17_Channel(17) +-> -> Card18_Channel(18) +-> -> Card19_Channel(19) +-> -> Card20_Channel(20) +-> -> Card21_Channel(21) +-> -> Card22_Channel(22) +-> -> Card23_Channel(23) +-> -> Card24_Channel(24) +-> -> Card25_Channel(25) +-> -> Card26_Channel(26) +-> -> Card27_Channel(27) +-> -> Card28_Channel(28) +-> -> Card29_Channel(29) +-> -> Card30_Channel(30) +-> -> Card31_Channel(31) + + +Register leaf node: Card31_Channel. +Instance: 256 +Length : 3 +Flag : 0 +Default : îî +Remark : Set lease circuit of MSC. Each 8K E1 Card has 256 configurable channels. +LCCP card (0-15)=Lease circuit connected 8K E1 Card (0-15). +LCCP E1 (0-7)=Lease circuit connected E1 (0-7). +LCCP timeslot=Lease circuit connected timeslot (1-15,17-31). +Default=0x05EEEE. + +Field : total(7) +Access : read-write [1]Channel flag + { + [u]0.0-0.0 + [u]select + [v]0[opt]disable + [v]1[opt]enable + } + [2]Channel type + { + [u]0.1-0.2 + [u]select + [v]0[opt]incoming + [v]1[opt]outgoing + [v]2[opt]bi-direction + [v]3[opt]lease + } +[4]LCCP card (0-15) + { + [u]1.0-1.3 + [u]input + [v]toDec high 0 + } +[6]LCCP timeslot (1-15, 17-31) + { + [u]2.0-2.4 + [u]input + [v]toDec high 0 + } +[7]LCCP E1 (0-7) + { + [u]2.5-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: CPC_attributes(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.6) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) +-> -> CPC_attributes(5) + + +Remark: CPC attributes. + + +Create node: MSCID(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.6.3) +-> father_name = [CPC_attributes] +-> -> MSCID(0) + + +Register leaf node: MSCID. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : MSCID + +Field : total(2) +Access : read-write[1]Market ID + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]Switch Number + { + [u]2.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Media_gateway(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.7) +-> father_name = [CCF_Config] +-> -> Call_Routing(0) +-> -> CCF_MSC(1) +-> -> CPC(2) +-> -> E1_Port(3) +-> -> Channel_Attributes(4) +-> -> CPC_attributes(5) +-> -> Media_gateway(6) + + +Remark: Media_gateway . + + +Create node: MG_Attribute(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.2.7.1) +-> father_name = [Media_gateway] +-> -> MG_Attribute(0) + + +Register leaf node: MG_Attribute. +Instance: 256 +Length : 53 +Flag : 255 +Default : +Remark : MG Attributes + +Field : total(3) +Access : read-only [1]MG Enable + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]MG IP Address + { + [u]1.0-4.7 + [u]input + [v]KeepHex high 0 + } +[3]MG Name + { + [u]5.0-52.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: CCF_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3) +-> father_name = [CCF(MSC)] +-> -> CCF_Config(0) +-> -> CCF_Status(1) + + +Remark: Status for CCF . + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.1) +-> father_name = [CCF_Status] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of MSC software (Read only).
+Byte0: System release version number, based on basic function and structure.
+Byte1: Software module version number, based on software module.
+Byte2: Test version, 0=Release version number, 1=Test version number.. + +Field : total(0) +Access : read-only + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.2) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : î +Remark : Control command for MSC-CPC. +Reset: Used for CPC status initialization. +Initialize: Restore the parameter setup to the default factory setting. +Save parameter: Save the parameters residing in CPC's memory into CPC's harddisk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]90[opt]Reset + [v]165[opt]Initialize + [v]181[opt]Save parameter + [v]238[opt]No command + } + + +Create node: E1_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.4) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) +-> -> E1_Status(2) + + +Register leaf node: E1_Status. +Instance: 128 +Length : 1 +Flag : 255 +Default : î +Remark : E1 status (read only). + +Field : total(2) +Access : read-only[1]Quantity of occupied timeslot + { + [u]0.0-0.4 + [u]input + [v]toDec high 0 + } + [2]E1 type + { + [u]0.5-0.7 + [u]select + [v]0[opt]TUP + [v]1[opt]ISUP + [v]2[opt]AIF + [v]3[opt]AIF_CDMA2K + [v]4[opt]BICC + } + + +Create node: Channel_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5) +-> father_name = [CCF_Status] +-> -> Version(0) +-> -> Command(1) +-> -> E1_Status(2) +-> -> Channel_Status(3) + + +Remark: Channel status (read only). + + +Create node: Card0_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.1) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) + + +Register leaf node: Card0_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card1_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.2) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) + + +Register leaf node: Card1_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card2_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.3) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) + + +Register leaf node: Card2_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card3_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.4) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) + + +Register leaf node: Card3_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card4_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.5) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) + + +Register leaf node: Card4_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card5_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.6) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) + + +Register leaf node: Card5_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card6_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.7) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) + + +Register leaf node: Card6_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card7_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.8) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) + + +Register leaf node: Card7_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card8_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.9) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) + + +Register leaf node: Card8_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card9_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.10) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) + + +Register leaf node: Card9_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card10_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.11) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) + + +Register leaf node: Card10_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card11_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.12) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) + + +Register leaf node: Card11_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card12_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.13) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) + + +Register leaf node: Card12_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card13_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.14) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) + + +Register leaf node: Card13_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card14_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.15) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) +-> -> Card14_Status(14) + + +Register leaf node: Card14_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: Card15_Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.5.16) +-> father_name = [Channel_Status] +-> -> Card0_Status(0) +-> -> Card1_Status(1) +-> -> Card2_Status(2) +-> -> Card3_Status(3) +-> -> Card4_Status(4) +-> -> Card5_Status(5) +-> -> Card6_Status(6) +-> -> Card7_Status(7) +-> -> Card8_Status(8) +-> -> Card9_Status(9) +-> -> Card10_Status(10) +-> -> Card11_Status(11) +-> -> Card12_Status(12) +-> -> Card13_Status(13) +-> -> Card14_Status(14) +-> -> Card15_Status(15) + + +Register leaf node: Card15_Status. +Instance: 256 +Length : 1 +Flag : 255 +Default : +Remark : Card Channel status (read only). + +Field : total(1) +Access : read-only [1]Timeslot status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Idle + [v]2[opt]Busy + [v]3[opt]Local blocked + [v]4[opt]Remote blocked + } + + +Create node: VLR(OID: 1.3.6.1.4.1.1373.1.3.3.2.5) +-> father_name = [MSC] +-> -> CCF(MSC)(0) +-> -> VLR(1) + + +Remark: sub for VLR . + + +Create node: VLR_Config(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2) +-> father_name = [VLR] +-> -> VLR_Config(0) + + +Remark: + Configuration for VLR . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1) +-> father_name = [VLR_Config] +-> -> Public_Param(0) + + +Remark: Public parameters . + + +Create node: OptAuthReq(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.1) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) + + +Register leaf node: OptAuthReq. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of SIM authentication on MS poweron and MO/MT call. + +Field : total(4) +Access : read-write [1]Update Location + { + [u]0.0-0.0 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [2]MO + { + [u]0.1-0.1 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } + [3]MT + { + [u]0.2-0.2 + [u]select + [v]0[opt]No authetication + [v]1[opt]Authetication + } +[4]Spare + { + [u]0.3-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptReuseTriplets(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.2) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) + + +Register leaf node: OptReuseTriplets. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of reusing authentication triplets in VLR in the case that authentication to HLR is not available. Default=disable. + +Field : total(3) +Access : read-write [1]OptReuseTriplets + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]double authentication + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[3]Spare + { + [u]0.2-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptCipReq(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.3) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) + + +Register leaf node: OptCipReq. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of voice ciphering over air interface by MS. Default=Disable. + +Field : total(1) +Access : read-write [1]OptCipReq + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: OptCiphAlgo(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.4) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) + + +Register leaf node: OptCiphAlgo. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Voice ciphering algorithm selection. Default=no ciphering. + +Field : total(1) +Access : read-write [1]OptCiphAlgo + { + [u]0.0-0.7 + [u]select + [v]0[opt]None + [v]1[opt]A5_1 + [v]2[opt]A5_2 + [v]3[opt]A5_3 + [v]4[opt]A5_4 + [v]5[opt]A5_5 + [v]6[opt]A5_6 + [v]7[opt]A5_7 + } + + +Create node: OptTmsiAlloc(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.5) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) + + +Register leaf node: OptTmsiAlloc. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Flag of allocating a new TMSI every time a call management service is requested. Default=Disable. + +Field : total(1) +Access : read-write [1]TMSI Allocation Option + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Allocate TMSI + [v]2[opt]Reallocate TMSI + } + + +Create node: OptEcSetUpAllow(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.7) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) + + +Register leaf node: OptEcSetUpAllow. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Flag of making emergency call for non-registered MS or MS without SIM. Default=Enable. + +Field : total(1) +Access : read-write [1]OptEcSetUpAllow + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: OptCheckIMEI(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.8) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) + + +Register leaf node: OptCheckIMEI. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of IMEI verification via EIR. Default=no IMEI verification. + +Field : total(4) +Access : read-write [1]Update Location + { + [u]0.0-0.0 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [2]MO + { + [u]0.1-0.1 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } + [3]MT + { + [u]0.2-0.2 + [u]select + [v]0[opt]No IMEI verification + [v]1[opt]IMEI verification + } +[4]Spare + { + [u]0.3-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: OptVlrPurge(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.9) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) + + +Register leaf node: OptVlrPurge. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Flag of VLR purge. Default=Off. + +Field : total(1) +Access : read-write [1]OptVlrPurge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: IdlePeriod2Purge(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.10) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) + + +Register leaf node: IdlePeriod2Purge. +Instance: 1 +Length : 1 +Flag : 255 +Default : < +Remark : Set the threshold of idle time to purge. If a mobile's idle time reaches this threshold, VLR will purge all records of this MS, unit=6 minute. Default=60minutes. + +Field : total(1) +Access : read-write[1]IdlePeriod2Purge + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.11) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) +-> -> CDR_Flag(9) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : VLR CDR flag. Default=On. + +Field : total(1) +Access : read-write [1]CDR on/off + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: MSRN(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.2.1.13) +-> father_name = [Public_Param] +-> -> OptAuthReq(0) +-> -> OptReuseTriplets(1) +-> -> OptCipReq(2) +-> -> OptCiphAlgo(3) +-> -> OptTmsiAlloc(4) +-> -> OptEcSetUpAllow(5) +-> -> OptCheckIMEI(6) +-> -> OptVlrPurge(7) +-> -> IdlePeriod2Purge(8) +-> -> CDR_Flag(9) +-> -> MSRN(10) + + +Register leaf node: MSRN. +Instance: 1 +Length : 16 +Flag : 255 +Default : †uS@ +Remark : Mobile station roaming number, use 16 bytes (32 digits) to define a range of MSRN. The length of start MSRN and end MSRN must be identical. F=end tag. + +Field : total(2) +Access : read-write[3]Start number + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low F + } +[4]End number + { + [u]8.0-15.7 + [u]input + [v]KeepHex Low F + } + + +Create node: VLR_Management(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3) +-> father_name = [VLR] +-> -> VLR_Config(0) +-> -> VLR_Management(1) + + +Remark: + Management for VLR . + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.2) +-> father_name = [VLR_Management] +-> -> Version(0) + + +Register leaf node: Version. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of VLR software (Read only). +Byte0: System release version number, based on basic function and structure. +Byte1: Software module version number, based on software module. +Byte2: Test version, 0=Release version number, 1=Test version number. + +Field : total(0) +Access : read-only + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.3) +-> father_name = [VLR_Management] +-> -> Version(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : î +Remark : Control command for VLR. +Reset: Used to initialize the status of VLR. +Save parameters: Save the parameters residing in memory into harddisk. + +Field : total(1) +Access : write-only [1]Management + { + [u]0.0-0.7 + [u]select + [v]0[opt]Reset VLR + [v]1[opt]Save parameters + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.4) +-> father_name = [VLR_Management] +-> -> Version(0) +-> -> Command(1) +-> -> Status(2) + + +Register leaf node: Status. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Basic status of VLR. + +Field : total(0) +Access : read-only + +Create node: HLR(OID: 1.3.6.1.4.1.1373.1.3.3.3) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) + + +Remark: Subsystems for HLR . + + +Create node: Config(OID: 1.3.6.1.4.1.1373.1.3.3.3.2) +-> father_name = [HLR] +-> -> Config(0) + + +Remark: + Configuration for HLR . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1) +-> father_name = [Config] +-> -> Public_Param(0) + + +Remark: + Public parameter . + + +Create node: HPLMN(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.11) +-> father_name = [Public_Param] +-> -> HPLMN(0) + + +Register leaf node: HPLMN. +Instance: 1 +Length : 17 +Flag : 255 +Default : îîîîîîîîîîîîîîîîî +Remark : Define the SN (VLR phone number) range of the VLR in the HPLMN (home PLMN) by specifying the start and end phone number of the range. +MSISDN=CC(country code)+NDC(National Destination Code)+SN. +All VLRs within a HPLMN have the same CC and NDC but the different SN. The SN of all VLR in a HPLMN must lie within the defined SN range. +Byte0-1=Country code. +Byte2-3=National destination code. +Byte4-9=Start SN of the VLR SN. +Byte10-15=End SN of the VLR SN. +e.g. For China country code=86, Shanghai national destination code=21, VLR SN=26060888: +Byte0-1=86EE, +Byte2-3=21EE, +SN=26060888, +Else=E. + +Field : total(4) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]NDC + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Start SN + { + [u]5.0-10.7 + [u]input + [v]KeepHex Low E + } +[4]End SN + { + [u]11.0-16.7 + [u]input + [v]KeepHex Low E + } + + +Create node: VPLMNs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.12) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) + + +Register leaf node: VPLMNs. +Instance: 256 +Length : 17 +Flag : 255 +Default : îîîîîîîîîîîîîîîîî +Remark : Define all connected VPLMNs (up tp 256) by specifying all VLR zones included in these VPLMNs. Each VLR zone is defined by its VLR MSISDN. MSISDN=CC+NDC+SN. All VLRs within a same VPLMN have the CC and NDC but the different SN. A VPLMN contains a group of VLRs whose SN is included in the defined SN range, E=random digit. +This parameter also define two ranges of VLR CSRR (Country specific roaming restrictionszones) zones for each VPLMN. In these defined VLR CSRR zones all HPLMN subscribers may be subjected to country specific roaming restrictions. +For each VPLMN setup, the format is: +byte0=ISDN numbering plan, default=91. +byte1-2=country code, EEEE. +byte3-4=national destination code, EEEE. +byte5-10=start SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. +byte11-16=end SN (SN prefix or whole SN) of VPLMNs, EEEEEEEEEEEE. +byte17-22=start SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte23-28=end SN (SN prefix or whole SN) of range 0 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte29-34=start SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +byte35-40=end SN (SN prefix or whole SN) of range 1 of VLR CSRR zones of a VPLMN, EEEEEEEEEEEE. +E=random digit. + +Field : total(4) +Access : read-write[1]CC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]NDC + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Start SN + { + [u]5.0-10.7 + [u]input + [v]KeepHex Low E + } +[4]End SN + { + [u]11.0-16.7 + [u]input + [v]KeepHex Low E + } + + +Create node: CSRR_List(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.13) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) + + +Register leaf node: CSRR_List. +Instance: 8 +Length : 32 +Flag : 255 +Default : +Remark : Define 8 CSRR (country specific roaming restriction) lists to confine the roaming range of a subscriber. +Each CSRR list defines the roaming restriction for 256 VPLMN ranges. + +Field : total(256) +Access : read-write [1]VPLMN0 Roaming allowed + { + [u]31.0-31.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [2]VPLMN1 Roaming allowed + { + [u]31.1-31.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [3]VPLMN2 Roaming allowed + { + [u]31.2-31.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [4]VPLMN3 Roaming allowed + { + [u]31.3-31.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [5]VPLMN4 Roaming allowed + { + [u]31.4-31.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [6]VPLMN5 Roaming allowed + { + [u]31.5-31.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [7]VPLMN6 Roaming allowed + { + [u]31.6-31.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [8]VPLMN7 Roaming allowed + { + [u]31.7-31.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [9]VPLMN8 Roaming allowed + { + [u]30.0-30.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [10]VPLMN9 Roaming allowed + { + [u]30.1-30.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [11]VPLMN10 Roaming allowed + { + [u]30.2-30.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [12]VPLMN11 Roaming allowed + { + [u]30.3-30.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [13]VPLMN12 Roaming allowed + { + [u]30.4-30.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [14]VPLMN13 Roaming allowed + { + [u]30.5-30.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [15]VPLMN14 Roaming allowed + { + [u]30.6-30.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [16]VPLMN15 Roaming allowed + { + [u]30.7-30.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [17]VPLMN16 Roaming allowed + { + [u]29.0-29.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [18]VPLMN17 Roaming allowed + { + [u]29.1-29.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [19]VPLMN18 Roaming allowed + { + [u]29.2-29.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [20]VPLMN19 Roaming allowed + { + [u]29.3-29.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [21]VPLMN20 Roaming allowed + { + [u]29.4-29.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [22]VPLMN21 Roaming allowed + { + [u]29.5-29.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [23]VPLMN22 Roaming allowed + { + [u]29.6-29.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [24]VPLMN23 Roaming allowed + { + [u]29.7-29.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [25]VPLMN24 Roaming allowed + { + [u]28.0-28.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [26]VPLMN25 Roaming allowed + { + [u]28.1-28.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [27]VPLMN26 Roaming allowed + { + [u]28.2-28.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [28]VPLMN27 Roaming allowed + { + [u]28.3-28.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [29]VPLMN28 Roaming allowed + { + [u]28.4-28.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [30]VPLMN29 Roaming allowed + { + [u]28.5-28.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [31]VPLMN30 Roaming allowed + { + [u]28.6-28.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [32]VPLMN31 Roaming allowed + { + [u]28.7-28.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [33]VPLMN32 Roaming allowed + { + [u]27.0-27.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [34]VPLMN33 Roaming allowed + { + [u]27.1-27.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [35]VPLMN34 Roaming allowed + { + [u]27.2-27.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [36]VPLMN35 Roaming allowed + { + [u]27.3-27.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [37]VPLMN36 Roaming allowed + { + [u]27.4-27.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [38]VPLMN37 Roaming allowed + { + [u]27.5-27.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [39]VPLMN38 Roaming allowed + { + [u]27.6-27.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [40]VPLMN39 Roaming allowed + { + [u]27.7-27.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [41]VPLMN40 Roaming allowed + { + [u]26.0-26.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [42]VPLMN41 Roaming allowed + { + [u]26.1-26.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [43]VPLMN42 Roaming allowed + { + [u]26.2-26.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [44]VPLMN43 Roaming allowed + { + [u]26.3-26.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [45]VPLMN44 Roaming allowed + { + [u]26.4-26.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [46]VPLMN45 Roaming allowed + { + [u]26.5-26.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [47]VPLMN46 Roaming allowed + { + [u]26.6-26.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [48]VPLMN47 Roaming allowed + { + [u]26.7-26.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [49]VPLMN48 Roaming allowed + { + [u]25.0-25.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [50]VPLMN49 Roaming allowed + { + [u]25.1-25.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [51]VPLMN50 Roaming allowed + { + [u]25.2-25.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [52]VPLMN51 Roaming allowed + { + [u]25.3-25.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [53]VPLMN52 Roaming allowed + { + [u]25.4-25.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [54]VPLMN53 Roaming allowed + { + [u]25.5-25.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [55]VPLMN54 Roaming allowed + { + [u]25.6-25.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [56]VPLMN55 Roaming allowed + { + [u]25.7-25.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [57]VPLMN56 Roaming allowed + { + [u]24.0-24.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [58]VPLMN57 Roaming allowed + { + [u]24.1-24.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [59]VPLMN58 Roaming allowed + { + [u]24.2-24.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [60]VPLMN59 Roaming allowed + { + [u]24.3-24.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [61]VPLMN60 Roaming allowed + { + [u]24.4-24.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [62]VPLMN61 Roaming allowed + { + [u]24.5-24.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [63]VPLMN62 Roaming allowed + { + [u]24.6-24.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [64]VPLMN63 Roaming allowed + { + [u]24.7-24.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [65]VPLMN64 Roaming allowed + { + [u]23.0-23.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [66]VPLMN65 Roaming allowed + { + [u]23.1-23.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [67]VPLMN66 Roaming allowed + { + [u]23.2-23.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [68]VPLMN67 Roaming allowed + { + [u]23.3-23.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [69]VPLMN68 Roaming allowed + { + [u]23.4-23.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [70]VPLMN69 Roaming allowed + { + [u]23.5-23.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [71]VPLMN70 Roaming allowed + { + [u]23.6-23.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [72]VPLMN71 Roaming allowed + { + [u]23.7-23.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [73]VPLMN72 Roaming allowed + { + [u]22.0-22.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [74]VPLMN73 Roaming allowed + { + [u]22.1-22.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [75]VPLMN74 Roaming allowed + { + [u]22.2-22.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [76]VPLMN75 Roaming allowed + { + [u]22.3-22.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [77]VPLMN76 Roaming allowed + { + [u]22.4-22.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [78]VPLMN77 Roaming allowed + { + [u]22.5-22.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [79]VPLMN78 Roaming allowed + { + [u]22.6-22.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [80]VPLMN79 Roaming allowed + { + [u]22.7-22.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [81]VPLMN80 Roaming allowed + { + [u]21.0-21.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [82]VPLMN81 Roaming allowed + { + [u]21.1-21.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [83]VPLMN82 Roaming allowed + { + [u]21.2-21.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [84]VPLMN83 Roaming allowed + { + [u]21.3-21.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [85]VPLMN84 Roaming allowed + { + [u]21.4-21.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [86]VPLMN85 Roaming allowed + { + [u]21.5-21.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [87]VPLMN86 Roaming allowed + { + [u]21.6-21.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [88]VPLMN87 Roaming allowed + { + [u]21.7-21.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [89]VPLMN88 Roaming allowed + { + [u]20.0-20.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [90]VPLMN89 Roaming allowed + { + [u]20.1-20.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [91]VPLMN90 Roaming allowed + { + [u]20.2-20.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [92]VPLMN91 Roaming allowed + { + [u]20.3-20.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [93]VPLMN92 Roaming allowed + { + [u]20.4-20.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [94]VPLMN93 Roaming allowed + { + [u]20.5-20.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [95]VPLMN94 Roaming allowed + { + [u]20.6-20.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [96]VPLMN95 Roaming allowed + { + [u]20.7-20.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [97]VPLMN96 Roaming allowed + { + [u]19.0-19.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [98]VPLMN97 Roaming allowed + { + [u]19.1-19.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [99]VPLMN98 Roaming allowed + { + [u]19.2-19.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [100]VPLMN99 Roaming allowed + { + [u]19.3-19.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [101]VPLMN100 Roaming allowed + { + [u]19.4-19.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [102]VPLMN101 Roaming allowed + { + [u]19.5-19.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [103]VPLMN102 Roaming allowed + { + [u]19.6-19.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [104]VPLMN103 Roaming allowed + { + [u]19.7-19.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [105]VPLMN104 Roaming allowed + { + [u]18.0-18.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [106]VPLMN105 Roaming allowed + { + [u]18.1-18.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [107]VPLMN106 Roaming allowed + { + [u]18.2-18.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [108]VPLMN107 Roaming allowed + { + [u]18.3-18.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [109]VPLMN108 Roaming allowed + { + [u]18.4-18.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [110]VPLMN109 Roaming allowed + { + [u]18.5-18.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [111]VPLMN110 Roaming allowed + { + [u]18.6-18.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [112]VPLMN111 Roaming allowed + { + [u]18.7-18.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [113]VPLMN112 Roaming allowed + { + [u]17.0-17.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [114]VPLMN113 Roaming allowed + { + [u]17.1-17.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [115]VPLMN114 Roaming allowed + { + [u]17.2-17.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [116]VPLMN115 Roaming allowed + { + [u]17.3-17.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [117]VPLMN116 Roaming allowed + { + [u]17.4-17.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [118]VPLMN117 Roaming allowed + { + [u]17.5-17.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [119]VPLMN118 Roaming allowed + { + [u]17.6-17.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [120]VPLMN119 Roaming allowed + { + [u]17.7-17.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [121]VPLMN120 Roaming allowed + { + [u]16.0-16.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [122]VPLMN121 Roaming allowed + { + [u]16.1-16.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [123]VPLMN122 Roaming allowed + { + [u]16.2-16.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [124]VPLMN123 Roaming allowed + { + [u]16.3-16.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [125]VPLMN124 Roaming allowed + { + [u]16.4-16.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [126]VPLMN125 Roaming allowed + { + [u]16.5-16.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [127]VPLMN126 Roaming allowed + { + [u]16.6-16.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [128]VPLMN127 Roaming allowed + { + [u]16.7-16.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [129]VPLMN128 Roaming allowed + { + [u]15.0-15.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [130]VPLMN129 Roaming allowed + { + [u]15.1-15.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [131]VPLMN130 Roaming allowed + { + [u]15.2-15.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [132]VPLMN131 Roaming allowed + { + [u]15.3-15.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [133]VPLMN132 Roaming allowed + { + [u]15.4-15.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [134]VPLMN133 Roaming allowed + { + [u]15.5-15.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [135]VPLMN134 Roaming allowed + { + [u]15.6-15.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [136]VPLMN135 Roaming allowed + { + [u]15.7-15.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [137]VPLMN136 Roaming allowed + { + [u]14.0-14.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [138]VPLMN137 Roaming allowed + { + [u]14.1-14.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [139]VPLMN138 Roaming allowed + { + [u]14.2-14.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [140]VPLMN139 Roaming allowed + { + [u]14.3-14.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [141]VPLMN140 Roaming allowed + { + [u]14.4-14.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [142]VPLMN141 Roaming allowed + { + [u]14.5-14.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [143]VPLMN142 Roaming allowed + { + [u]14.6-14.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [144]VPLMN143 Roaming allowed + { + [u]14.7-14.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [145]VPLMN144 Roaming allowed + { + [u]13.0-13.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [146]VPLMN145 Roaming allowed + { + [u]13.1-13.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [147]VPLMN146 Roaming allowed + { + [u]13.2-13.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [148]VPLMN147 Roaming allowed + { + [u]13.3-13.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [149]VPLMN148 Roaming allowed + { + [u]13.4-13.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [150]VPLMN149 Roaming allowed + { + [u]13.5-13.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [151]VPLMN150 Roaming allowed + { + [u]13.6-13.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [152]VPLMN151 Roaming allowed + { + [u]13.7-13.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [153]VPLMN152 Roaming allowed + { + [u]12.0-12.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [154]VPLMN153 Roaming allowed + { + [u]12.1-12.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [155]VPLMN154 Roaming allowed + { + [u]12.2-12.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [156]VPLMN155 Roaming allowed + { + [u]12.3-12.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [157]VPLMN156 Roaming allowed + { + [u]12.4-12.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [158]VPLMN157 Roaming allowed + { + [u]12.5-12.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [159]VPLMN158 Roaming allowed + { + [u]12.6-12.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [160]VPLMN159 Roaming allowed + { + [u]12.7-12.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [161]VPLMN160 Roaming allowed + { + [u]11.0-11.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [162]VPLMN161 Roaming allowed + { + [u]11.1-11.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [163]VPLMN162 Roaming allowed + { + [u]11.2-11.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [164]VPLMN163 Roaming allowed + { + [u]11.3-11.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [165]VPLMN164 Roaming allowed + { + [u]11.4-11.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [166]VPLMN165 Roaming allowed + { + [u]11.5-11.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [167]VPLMN166 Roaming allowed + { + [u]11.6-11.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [168]VPLMN167 Roaming allowed + { + [u]11.7-11.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [169]VPLMN168 Roaming allowed + { + [u]10.0-10.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [170]VPLMN169 Roaming allowed + { + [u]10.1-10.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [171]VPLMN170 Roaming allowed + { + [u]10.2-10.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [172]VPLMN171 Roaming allowed + { + [u]10.3-10.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [173]VPLMN172 Roaming allowed + { + [u]10.4-10.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [174]VPLMN173 Roaming allowed + { + [u]10.5-10.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [175]VPLMN174 Roaming allowed + { + [u]10.6-10.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [176]VPLMN175 Roaming allowed + { + [u]10.7-10.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [177]VPLMN176 Roaming allowed + { + [u]9.0-9.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [178]VPLMN177 Roaming allowed + { + [u]9.1-9.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [179]VPLMN178 Roaming allowed + { + [u]9.2-9.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [180]VPLMN179 Roaming allowed + { + [u]9.3-9.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [181]VPLMN180 Roaming allowed + { + [u]9.4-9.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [182]VPLMN181 Roaming allowed + { + [u]9.5-9.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [183]VPLMN182 Roaming allowed + { + [u]9.6-9.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [184]VPLMN183 Roaming allowed + { + [u]9.7-9.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [185]VPLMN184 Roaming allowed] + { + [u]8.0-8.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [186]VPLMN185 Roaming allowed + { + [u]8.1-8.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [187]VPLMN186 Roaming allowed + { + [u]8.2-8.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [188]VPLMN187 Roaming allowed + { + [u]8.3-8.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [189]VPLMN188 Roaming allowed + { + [u]8.4-8.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [190]VPLMN189 Roaming allowed + { + [u]8.5-8.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [191]VPLMN190 Roaming allowed + { + [u]8.6-8.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [192]VPLMN191 Roaming allowed + { + [u]8.7-8.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [193]VPLMN192 Roaming allowed + { + [u]7.0-7.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [194]VPLMN193 Roaming allowed + { + [u]7.1-7.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [195]VPLMN194 Roaming allowed + { + [u]7.2-7.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [196]VPLMN195 Roaming allowed + { + [u]7.3-7.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [197]VPLMN196 Roaming allowed + { + [u]7.4-7.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [198]VPLMN197 Roaming allowed + { + [u]7.5-7.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [199]VPLMN198 Roaming allowed + { + [u]7.6-7.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [200]VPLMN199 Roaming allowed + { + [u]7.7-7.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [201]VPLMN200 Roaming allowed + { + [u]6.0-6.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [202]VPLMN201 Roaming allowed + { + [u]6.1-6.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [203]VPLMN202 Roaming allowed + { + [u]6.2-6.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [204]VPLMN203 Roaming allowed + { + [u]6.3-6.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [205]VPLMN204 Roaming allowed + { + [u]6.4-6.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [206]VPLMN205 Roaming allowed + { + [u]6.5-6.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [207]VPLMN206 Roaming allowed + { + [u]6.6-6.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [208]VPLMN207 Roaming allowed + { + [u]6.7-6.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [209]VPLMN208 Roaming allowed + { + [u]5.0-5.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [210]VPLMN209 Roaming allowed + { + [u]5.1-5.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [211]VPLMN210 Roaming allowed + { + [u]5.2-5.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [212]VPLMN211 Roaming allowed + { + [u]5.3-5.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [213]VPLMN212 Roaming allowed + { + [u]5.4-5.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [214]VPLMN213 Roaming allowed + { + [u]5.5-5.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [215]VPLMN214 Roaming allowed + { + [u]5.6-5.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [216]VPLMN215 Roaming allowed + { + [u]5.7-5.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [217]VPLMN216 Roaming allowed + { + [u]4.0-4.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [218]VPLMN217 Roaming allowed + { + [u]4.1-4.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [219]VPLMN218 Roaming allowed + { + [u]4.2-4.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [220]VPLMN219 Roaming allowed + { + [u]4.3-4.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [221]VPLMN220 Roaming allowed + { + [u]4.4-4.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [222]VPLMN221 Roaming allowed + { + [u]4.5-4.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [223]VPLMN222 Roaming allowed + { + [u]4.6-4.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [224]VPLMN223 Roaming allowed + { + [u]4.7-4.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [225]VPLMN224 Roaming allowed + { + [u]3.0-3.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [226]VPLMN225 Roaming allowed + { + [u]3.1-3.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [227]VPLMN226 Roaming allowed + { + [u]3.2-3.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [228]VPLMN227 Roaming allowed + { + [u]3.3-3.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [229]VPLMN228 Roaming allowed + { + [u]3.4-3.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [230]VPLMN229 Roaming allowed + { + [u]3.5-3.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [231]VPLMN230 Roaming allowed + { + [u]3.6-3.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [232]VPLMN231 Roaming allowed + { + [u]3.7-3.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [233]VPLMN232 Roaming allowed + { + [u]2.0-2.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [234]VPLMN233 Roaming allowed + { + [u]2.1-2.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [235]VPLMN234 Roaming allowed + { + [u]2.2-2.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [236]VPLMN235 Roaming allowed + { + [u]2.3-2.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [237]VPLMN236 Roaming allowed + { + [u]2.4-2.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [238]VPLMN237 Roaming allowed + { + [u]2.5-2.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [239]VPLMN238 Roaming allowed + { + [u]2.6-2.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [240]VPLMN239 Roaming allowed + { + [u]2.7-2.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [241]VPLMN240 Roaming allowed + { + [u]1.0-1.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [242]VPLMN241 Roaming allowed + { + [u]1.1-1.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [243]VPLMN242 Roaming allowed + { + [u]1.2-1.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [244]VPLMN243 Roaming allowed + { + [u]1.3-1.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [245]VPLMN244 Roaming allowed + { + [u]1.4-1.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [246]VPLMN245 Roaming allowed + { + [u]1.5-1.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [247]VPLMN246 Roaming allowed + { + [u]1.6-1.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [248]VPLMN247 Roaming allowed + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [249]VPLMN248 Roaming allowed + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [250]VPLMN249 Roaming allowed + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [251]VPLMN250 Roaming allowed + { + [u]0.2-0.2 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [252]VPLMN251 Roaming allowed + { + [u]0.3-0.3 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [253]VPLMN252 Roaming allowed + { + [u]0.4-0.4 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [254]VPLMN253 Roaming allowed + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [255]VPLMN254 Roaming allowed + { + [u]0.6-0.6 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + [256]VPLMN255 Roaming allowed + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Regional_Subs_List(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.14) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) + + +Register leaf node: Regional_Subs_List. +Instance: 255 +Length : 7 +Flag : 255 +Default : îîîîîîî +Remark : Define the regional subscription zone code list. HLR supports up to 256 regional subscription zone code. +Regional subscription code = CC+NDC+zone code + +Field : total(3) +Access : read-write[1]Country Code + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]National Destination Code + { + [u]2.0-4.7 + [u]input + [v]KeepHex Low E + } +[3]Zone Code + { + [u]5.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Licenses_Control(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.15) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) + + +Register leaf node: Licenses_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of HLR subscribers for service provider: +The new license can not support less HLR subscribers than what the old license supports. + +Field : total(1) +Access : write-only[1]Licenses + { + [u]0.0-7.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: CDR_Control(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.16) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) +-> -> CDR_Control(5) + + +Register leaf node: CDR_Control. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : HLR CDR generation flag: +Off=Not generate HLR CDR. +On=Generate HLR CDR. + +Field : total(1) +Access : read-write [1]CDR control + { + [u]0.0-0.7 + [u]select + [v]0[opt]Off + [v]1[opt]On + } + + +Create node: Feature_Code(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.1.27) +-> father_name = [Public_Param] +-> -> HPLMN(0) +-> -> VPLMNs(1) +-> -> CSRR_List(2) +-> -> Regional_Subs_List(3) +-> -> Licenses_Control(4) +-> -> CDR_Control(5) +-> -> Feature_Code(6) + + +Register leaf node: Feature_Code. +Instance: 1 +Length : 64 +Flag : 255 +Default : �îhîrî’îpî +Remark : None. + +Field : total(6) +Access : read-write[1]CFB + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low E + } +[2]CFD + { + [u]2.0-3.7 + [u]input + [v]KeepHex Low E + } +[3]CFNA + { + [u]4.0-5.7 + [u]input + [v]KeepHex Low E + } +[4]CFU + { + [u]6.0-7.7 + [u]input + [v]KeepHex Low E + } +[5]Call waiting + { + [u]8.0-9.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2) +-> father_name = [Config] +-> -> Public_Param(0) +-> -> Management(1) + + +Remark: + Management . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.2) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Bit0-2: HLR paramter save control: +Idle=no operation. +Save=Save parameters from HLR memory to HLR hard disk. +Bit3-5: HLR subscriber data save control: +Idle=no operation. +Save=Save HLR subscriber data from HLR memory to both HLR hard disk and OMC database. +Bit6-7: Reserved. + +Field : total(3) +Access : read-write [1]Save parameter to HD + { + [u]0.0-0.2 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + } + [2]Save subscriber data to HD&OMC + { + [u]0.3-0.5 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + } + + +Create node: Subscriber_Import(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.3) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) + + +Register leaf node: Subscriber_Import. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Progress and result of HLR subscriber import. +Byte0: Progress of HLR subscriber import. +Byte1-3: Total quantity of HLR subscribers requesting import. +Byte4-7: Quantity of successfully imported HLR subscribers. + +Field : total(3) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading Failed + } +[2]Total subscriber requested + { + [u]1.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Total imported subscribers + { + [u]4.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Max_Licenses(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.11) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) + + +Register leaf node: Max_Licenses. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The maximum quantity of approved HLR subscribers determined by License control (Read Only). + +Field : total(1) +Access : read-only[1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Used_Licenses(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.12) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) + + +Register leaf node: Used_Licenses. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of currently registered HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Used Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Subscriber_Info(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) + + +Remark: + Subscriber information . + + +Create node: Provisioned_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.1) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) + + +Register leaf node: Provisioned_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of service provisioned and active HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Provisioned Subs + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Registered_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.2) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) +-> -> Registered_Subs(1) + + +Register leaf node: Registered_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of registered (both active and inactive) HLR subscribers (Read Only). + +Field : total(1) +Access : read-only[1]Registered Subs + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Roaming_Subs(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.13.3) +-> father_name = [Subscriber_Info] +-> -> Provisioned_Subs(0) +-> -> Registered_Subs(1) +-> -> Roaming_Subs(2) + + +Register leaf node: Roaming_Subs. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of provisioned HLR subscribers currently roaming to VPLMNs (Read Only). + +Field : total(1) +Access : read-only[1]Roaming Subs + { + [u]0.0-0.0 + [u]input + [v]toDec high 0 + } + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) + + +Remark: + Version . + + +Create node: Software(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14.1) +-> father_name = [Version] +-> -> Software(0) + + +Register leaf node: Software. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of HLR software (Read Only): +Byte0: System release version number: +- Based on basic function and structure. +Byte1: Software module version number: +- Based on software module. +Byte2: Test version: +- 0=Release version number. +- 1=Test version number. + +Field : total(3) +Access : read-only[1]Release + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Version + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Slice + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: User_Data(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.14.2) +-> father_name = [Version] +-> -> Software(0) +-> -> User_Data(1) + + +Register leaf node: User_Data. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC subscriber data (Read Only): +System release version: Based on basic function and structure. +Subscriber data version: Based on software module. +Test version: 0=Release version 1=Test version + +Field : total(3) +Access : read-only[1]Release + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Version + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Slice + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: IMSI_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.15) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) + + +Register leaf node: IMSI_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : MSISDN segment table (Read Only): +Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + +Field : total(1) +Access : read-only[1]IMSI segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: MSISDN_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.16) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) +-> -> MSISDN_Segment(7) + + +Register leaf node: MSISDN_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : MSISDN segment table (Read Only): +Use SN of MSISDN (MSISDN=CC+NDC+SN) excluding the last three digits to divide the MSISDN into 200 segments. + +Field : total(1) +Access : read-only[1]MSISDN segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: CNF_Applicant_Info(OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.27) +-> father_name = [Management] +-> -> Command(0) +-> -> Subscriber_Import(1) +-> -> Max_Licenses(2) +-> -> Used_Licenses(3) +-> -> Subscriber_Info(4) +-> -> Version(5) +-> -> IMSI_Segment(6) +-> -> MSISDN_Segment(7) +-> -> CNF_Applicant_Info(8) + + +Register leaf node: CNF_Applicant_Info. +Instance: 1 +Length : 9 +Flag : 255 +Default : +Remark : Display the IMSI and charge type of the latest conference applicant (Read Only). + +Field : total(2) +Access : read-only [1]Charge Type + { + [u]0.0-0.7 + [u]select + [v]0[opt]Invalid user + [v]1[opt]Post-pay user + [v]2[opt]Prepaid user + } +[2]IMSI + { + [u]1.0-8.7 + [u]input + [v]KeepHex Low E + } + + +Create node: AUC(OID: 1.3.6.1.4.1.1373.1.3.3.4) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) + + +Remark: Subsystems for AUC . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.4.2) +-> father_name = [AUC] +-> -> Configuration(0) + + +Remark: + Configuration for AUC . + + +Create node: Public_parameter(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1) +-> father_name = [Configuration] +-> -> Public_parameter(0) + + +Remark: + Public_parameter for AUC . + + +Create node: SSD(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.2) +-> father_name = [Public_parameter] +-> -> SSD(0) + + +Register leaf node: SSD. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : SSD + +Field : total(3) +Access : read-write [1]share SSD + { + [u]0.0-0.7 + [u]select + [v]0[opt]not share + [v]1[opt]share + } +[2]Update SSD timer + { + [u]1.0-2.7 + [u]input + [v]toDec high 0 + } + + +Create node: Count(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.3) +-> father_name = [Public_parameter] +-> -> SSD(0) +-> -> Count(1) + + +Register leaf node: Count. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : Count. + +Field : total(2) +Access : read-write[1]Count Match Range + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Failures(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.1.4) +-> father_name = [Public_parameter] +-> -> SSD(0) +-> -> Count(1) +-> -> Failures(2) + + +Register leaf node: Failures. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : Count. + +Field : total(7) +Access : read-write [1]AUTHR Mismatch + { + [u]0.0-0.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + [2]Count Mismatch + { + [u]1.0-1.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [3]Unique Challenge Failure + { + [u]2.0-2.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [4]SSD Update Failure + { + [u]3.0-3.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [5]Count Update Failure + { + [u]4.0-4.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + } + [6]Missing AUTH Parameters + { + [u]5.0-5.7 + [u]select + [v]0[opt]Allow Access + [v]1[opt]Deny Access + [v]2[opt]Unique Challenge + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2) +-> father_name = [Configuration] +-> -> Public_parameter(0) +-> -> Management(1) + + +Remark: + Management . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.2) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Command for AUC paramters and user data operation, and the result of command. + +Field : total(3) +Access : read-write [1]Save parameters to HD + { + [u]0.0-0.2 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + [v]1[opt]Saving + [v]2[opt]Save succeeds + [v]3[opt]Save fails + } + [2]Save user data to HD&OMC + { + [u]0.3-0.5 + [u]select + [v]0[opt]Idle + [v]1[opt]Save + [v]1[opt]Saving + [v]2[opt]Save succeeds + [v]3[opt]Save fails + } + + +Create node: License_Control(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.3) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) + + +Register leaf node: License_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of AUC subscribers for service provider. The new license can not support less AUC subscribers than what the old license supports. + +Field : total(1) +Access : write-only[1]Licenses + { + [u]0.0-15.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: MAX_License(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.11) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) + + +Register leaf node: MAX_License. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The maximum quantity of approved AUC subscribers determined by License control Read only. + +Field : total(1) +Access : write-only[1]Max Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Used_License(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.12) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) + + +Register leaf node: Used_License. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of currently registered EIR subscribers (Read only). + +Field : total(1) +Access : read-only[1]Used Licenses + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: User_information(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.13) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) + + +Remark: + User Information . + + +Create node: Provisioned_Users(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.13.1) +-> father_name = [User_information] +-> -> Provisioned_Users(0) + + +Register leaf node: Provisioned_Users. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : The quantity of service enabled AUC subscribers (Read only). + +Field : total(1) +Access : read-only[1]Provisioned users + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Version(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) +-> -> Version(5) + + +Remark: + Version . + + +Create node: Software(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14.1) +-> father_name = [Version] +-> -> Software(0) + + +Register leaf node: Software. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC software (Read only). +System: System release version, based on basic function and structure. +Module: Software module version, based on software module. +Test: Test version, 0=Release version. 1=Test version. + +Field : total(3) +Access : read-only[1]System + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Module + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Test + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: User_data(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.14.2) +-> father_name = [Version] +-> -> Software(0) +-> -> User_data(1) + + +Register leaf node: User_data. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Version of AUC subscriber data (Read only). +System: System release version, based on basic function and structure. +User data: Subscriber profile version, based on software module. +Test: Test version, 0=Release version. 1=Test version. + +Field : total(3) +Access : read-only[1]System + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]User data + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Test + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: IMSI_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.15) +-> father_name = [Management] +-> -> Command(0) +-> -> License_Control(1) +-> -> MAX_License(2) +-> -> Used_License(3) +-> -> User_information(4) +-> -> Version(5) +-> -> IMSI_Segment(6) + + +Register leaf node: IMSI_Segment. +Instance: 1000 +Length : 4 +Flag : 255 +Default : +Remark : IMSI segment table (Read only): +100,000 IMSIs are subdivided into 1000 segments, each IMSI segment use the 8 most significant digits (from the 6th digit to 13th digit of 15-digit of IMSI) as the segment number. +IMSI=MCC(3)+MNC(2)+MSIN(10) +Segment number=the 8 most significant digits of the MSIN, each segment has 100 subscribers (00-99). +e.g. If IMSI=460002356090098 then it belongs to IMSI segemt 23560900 and its account number in that segment=98. 0=empty segment. + +Field : total(1) +Access : read-only[1]IMSI segment + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.4.3) +-> father_name = [AUC] +-> -> Configuration(0) +-> -> Status(1) + + +Remark: + Status for AUC . + + +Create node: Import_status(OID: 1.3.6.1.4.1.1373.1.3.3.4.3.2) +-> father_name = [Status] +-> -> Import_status(0) + + +Register leaf node: Import_status. +Instance: 1 +Length : 12 +Flag : 255 +Default : +Remark : Import status. + +Field : total(0) +Access : read-write + +Create node: SMSC(OID: 1.3.6.1.4.1.1373.1.3.3.5) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) + + +Remark: Subsystems for SMSC . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.5.2) +-> father_name = [SMSC] +-> -> Configuration(0) + + +Remark: Configuration for SMSC . + + +Create node: System_Param(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1) +-> father_name = [Configuration] +-> -> System_Param(0) + + +Remark: system parameter . + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.1) +-> father_name = [System_Param] +-> -> CDR_Flag(0) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : SMSC CDR generation enable or disable. + +Field : total(3) +Access : read-write [1]SMSC CDR + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + [2]SMSC LOG + { + [u]0.1-0.1 + [u]select + [v]0[opt]Not generate + [v]1[opt]Generate + } + + +Create node: SM_Validity(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.2) +-> father_name = [System_Param] +-> -> CDR_Flag(0) +-> -> SM_Validity(1) + + +Register leaf node: SM_Validity. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Period of validity of short message, define a threshold how long an awaiting sending message should be kept in sending array till sent to MS, unit is second, default=0c0a8h seconds=12 hours. + +Field : total(1) +Access : read-write[1]SM validity + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: MSISDN_Segment(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.1.3) +-> father_name = [System_Param] +-> -> CDR_Flag(0) +-> -> SM_Validity(1) +-> -> MSISDN_Segment(2) + + +Register leaf node: MSISDN_Segment. +Instance: 16 +Length : 19 +Flag : 255 +Default : †uUq' +Remark : Specify the beginning MSISDN for the range of provisioned subscriber. F=end tag. + +Field : total(3) +Access : read-write[1]Start MSISDN + { + [u]0.0-8.7 + [u]input + [v]KeepHex Low E + } +[2]End MSISDN + { + [u]9.0-17.7 + [u]input + [v]KeepHex Low E + } + [3]Number Type + { + [u]18.0-18.7 + [u]select + [v]0[opt]GSM + [v]1[opt]CDMA + } + + +Create node: SMPP_parameters(OID: 1.3.6.1.4.1.1373.1.3.3.5.2.2) +-> father_name = [Configuration] +-> -> System_Param(0) +-> -> SMPP_parameters(1) + + +Register leaf node: SMPP_parameters. +Instance: 32 +Length : 12 +Flag : 255 +Default : +Remark : Name: Can be any name, generally use the name of the connected device. +Service number: SMPP connected party MSISDN used for display on MT MS, +e.g. for a SMPP to PPS, set the service number as MSISDN of PPS. +Data coding scheme: +00:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 7bit +01:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 7bit +10:smsc to smpp=7bit,when dcs = 0,smsc to smpp default = 8bit +11:smsc to smpp=8bit,when dcs = 0,smsc to smpp default = 8bit +Default=0. + +Field : total(5) +Access : read-write [1]Enable flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Session type + { + [u]1.0-1.7 + [u]select + [v]0[opt]BIND_TX + [v]1[opt]BIND_RX + [v]2[opt]BIND_TRX + } +[3]Service number + { + [u]2.0-9.7 + [u]input + [v]ToAscii Low 0 + } + [4]Message mode + { + [u]10.0-10.7 + [u]select + [v]0[opt]Store and forward + [v]1[opt]Datagram + [v]2[opt]Transaction + } + [5]Data Coding Scheme + { + [u]11.0-11.7 + [u]select + [v]0[opt]To smpp=7bit,default=7bit + [v]1[opt]To smpp=8bit,default=7bit + [v]16[opt]To smpp=7bit,default=8bit + [v]17[opt]To smpp=8bit,default=8bit + } + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.5.3) +-> father_name = [SMSC] +-> -> Configuration(0) +-> -> Management(1) + + +Remark: + Management for SMSC . + + +Create node: SMSC_ID(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.1) +-> father_name = [Management] +-> -> SMSC_ID(0) + + +Register leaf node: SMSC_ID. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : SMSC ID + +Field : total(1) +Access : read-write[1]SMSC ID + { + [u]0.0-0.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Software_Version(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.2) +-> father_name = [Management] +-> -> SMSC_ID(0) +-> -> Software_Version(1) + + +Register leaf node: Software_Version. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Software version + +Field : total(1) +Access : write-only[1]Version + { + [u]0.0-2.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.5.3.3) +-> father_name = [Management] +-> -> SMSC_ID(0) +-> -> Software_Version(1) +-> -> Command(2) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : SMSC system command. +Save parameters: Save the SMSC parameters in memory to SMSC harddisk. +Delete pending SM: Delete the pending SM in awaiting array. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + [v]4[opt]Reset system + [v]5[opt]Delete pending SM + } + + +Create node: PPS(OID: 1.3.6.1.4.1.1373.1.3.3.6) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) +-> -> PPS(4) + + +Remark: Subsystems for PPS . + + +Create node: Public_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2) +-> father_name = [PPS] +-> -> Public_Param(0) + + +Remark: public parameters for MSS . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1) +-> father_name = [Public_Param] +-> -> Configuration(0) + + +Remark: Configuration for PPS . + + +Create node: Service_Control(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1) +-> father_name = [Configuration] +-> -> Service_Control(0) + + +Remark: Service Control . + + +Create node: CDR_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.1) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) + + +Register leaf node: CDR_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : PPS CDR generation enable or disable. Default=PPS generate CDR. + +Field : total(1) +Access : read-write [1]CDR flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Blacklist_Threshold(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.2) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) + + +Register leaf node: Blacklist_Threshold. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Legal recharge failure, subsciber who breaks the threshold will be marked in black list and suspended from service provisioning. Default=5. + +Field : total(1) +Access : read-write[1]Blacklist threshold + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Balance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.3) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) + + +Register leaf node: Maximum_Balance. +Instance: 1 +Length : 4 +Flag : 255 +Default : +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This value is for overflow prevention. Normally operator doesn't need to change this value. e.g. 5000, and the smallest unit is cent then the maximum allowed balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: License_Control(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.4) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) + + +Register leaf node: License_Control. +Instance: 1 +Length : 8 +Flag : 255 +Default : +Remark : 8-byte encrypted license provided by interWAVE used to provision an approved quantiy of PPS subscribers for service provider. The new license can not support less PPS subscribers than what the old license supports. + +Field : total(1) +Access : read-write[1]License + { + [u]0.0-7.7 + [u]input + [v]KeepHex Low E + } + + +Create node: Prompt_Resolution(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.5) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) + + +Register leaf node: Prompt_Resolution. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Currency style: Set the number of decimals in account balance SM display format. If account balance=55555 in smallest currency unit: +1=account balance display in SM is 55555. +10=account balance display in SM is 5555.5. +100=account balance display in SM is 555.55. +Default=100. +Date style: Set the date format displayed in SM or announcement. Default=YYYY-MM-DD. +Currency symbol position: Set the position of the currency symbol. +There are two types: at the front of the amount (e.g. $5) or at the rear of the amount (e.g. 5Fr). Default=at the front. + +Field : total(4) +Access : read-write [1]Currency resolution + { + [u]0.0-0.1 + [u]select + [v]0[opt]1 + [v]1[opt]10 + [v]2[opt]100 + } + [2]Date format + { + [u]0.2-0.3 + [u]select + [v]0[opt]YYYY-MM-DD + [v]1[opt]DD-MM-YYYY + [v]2[opt]MM-DD-YYYY + } + [3]Currency symbol position + { + [u]0.0-0.0 + [u]select + [v]0[opt]Front + [v]1[opt]Rear + } + + +Create node: SMS_Sentence(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.6) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) + + +Register leaf node: SMS_Sentence. +Instance: 5 +Length : 112 +Flag : 255 +Default : +Remark : The # of sentence(0-4) refers to differenct language type; + +Field : total(4) +Access : read-write [1]SM encode type + { + [u]0.0-0.7 + [u]select + [v]0[opt]7 bit + [v]4[opt]octet + [v]8[opt]unicode + } +[2]Account balance + { + [u]1.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[3]expired in + { + [u]32.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[4]recharge in time + { + [u]64.0-111.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Last_Call_Info(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.7) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) + + +Register leaf node: Last_Call_Info. +Instance: 5 +Length : 88 +Flag : 255 +Default : Last call sent on: +Remark : The # of sentence(0-4) refers to differenct language type. + +Field : total(5) +Access : read-write[1]Last call sent on + { + [u]0.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[2]Last call received on + { + [u]32.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[3]At + { + [u]64.0-71.7 + [u]input + [v]ToAscii Low 0 + } +[4]To + { + [u]72.0-79.7 + [u]input + [v]ToAscii Low 0 + } +[5]From + { + [u]80.0-87.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Currency_Symbol(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.8) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) + + +Register leaf node: Currency_Symbol. +Instance: 1 +Length : 8 +Flag : 255 +Default : $ +Remark : Set the symbol of the local currency in SMS amount display. e.g. $, RMB, EUR, US$, FR$. default=$. In the set window, type the currency symbol. The input symbol will be converted to ASCII code. +Do not input any symbol that not listed on the ASCII code table. ASCII table: 'A'=0x41, 'B'=0x42 ... 'I'=0x49, 'J'=0x4a, 'K'=0x4b ... 'Z'=0x5A, '$'=0x24 +e.g. RMB=0x52 0x4d 0x42, US$=0x55 0x53 0x24 + +Field : total(1) +Access : read-write[1]Currency symbol + { + [u]0.0-7.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Third_Party_Info(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.9) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) +-> -> Third_Party_Info(8) + + +Register leaf node: Third_Party_Info. +Instance: 8 +Length : 16 +Flag : 255 +Default : +Remark : This parameter is a verification for third party ESME when the third party ESME sends a billing request to PPS server. For example, if a subscriber sends a short message via a ESME (e.g. website), the ESME will send a billing request to PPS to debit this subscriber. This billing request must contains a service ID and password to pass the verification. After verification, the subscriber will be debited by the PPS. PPS supports 8 ESME connections. + +Field : total(2) +Access : read-write[1]Service ID + { + [u]0.0-7.7 + [u]input + [v]ToAscii Low 0 + } +[2]Service password + { + [u]8.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Basic_Tariff_Zone(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.1.10) +-> father_name = [Service_Control] +-> -> CDR_Flag(0) +-> -> Blacklist_Threshold(1) +-> -> Maximum_Balance(2) +-> -> License_Control(3) +-> -> Prompt_Resolution(4) +-> -> SMS_Sentence(5) +-> -> Last_Call_Info(6) +-> -> Currency_Symbol(7) +-> -> Third_Party_Info(8) +-> -> Basic_Tariff_Zone(9) + + +Register leaf node: Basic_Tariff_Zone. +Instance: 64 +Length : 9 +Flag : 255 +Default : +Remark : The basic tariff is applied for each calling or called number prefix. The WXC2 System supports 16 MO and MT tariffs (0-15) and 256 billing zones. This parameter defines basic tariff for each billing zone. Each parameter is a combination of MCC, MNC, cell ID, LAC and MO/MT tariff ID. The billing zone may be set as a cell, a LAC or a zone. Normally a single billing zone deploys only one basic tariff. +Each PPS subscriber profile also contains its tariff setup specifying which tariff should be applied for this subscriber. Using either basic tariff zone (location dependent) or tariff in subscriber profile (subscriber dependent) is determined by a parameter -Tariff subscription-. +LAC: If LAC=65536, all LACs in the MCC and MNC use the same basic tariff. +Cell ID: If cell ID=65536, all cells in the LAC use the same basic tariff. + +Field : total(6) +Access : read-write[1]MCC + { + [u]0.0-1.7 + [u]input + [v]KeepHex Low F + } +[2]MNC + { + [u]2.0-2.7 + [u]input + [v]KeepHex Low F + } +[3]LAC + { + [u]3.0-4.7 + [u]input + [v]toDec high 0 + } +[4]Cell ID + { + [u]5.0-6.7 + [u]input + [v]toDec high 0 + } + [5]MO tariff ID + { + [u]7.0-7.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + [6]MT tariff ID + { + [u]8.0-8.7 + [u]select + [v]0[opt]0 + [v]1[opt]1 + [v]2[opt]2 + [v]3[opt]3 + [v]4[opt]4 + [v]5[opt]5 + [v]6[opt]6 + [v]7[opt]7 + [v]8[opt]8 + [v]9[opt]9 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: SRF_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) + + +Remark: SRF parameters . + + +Create node: SRF_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) + + +Remark: SRF Number. + + +Create node: SRF_0_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1.1) +-> father_name = [SRF_Number] +-> -> SRF_0_Number(0) + + +Register leaf node: SRF_0_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : E.164 number of SRF 0 (Special Resource Function) entity. + +Field : total(1) +Access : read-write[1]SRF 0 number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: SRF_1_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.1.2) +-> father_name = [SRF_Number] +-> -> SRF_0_Number(0) +-> -> SRF_1_Number(1) + + +Register leaf node: SRF_1_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : E.164 number of SRF 1 (Special Resource Function) entity. + +Field : total(1) +Access : read-write[1]SRF 1 number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Service_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) +-> -> Service_Number(1) + + +Remark: Service number . + + +Create node: Hotline(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.1) +-> father_name = [Service_Number] +-> -> Hotline(0) + + +Register leaf node: Hotline. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : PPS service center number. Subscriber dials this number to recharge, enquire their account and modify favorite numbers. + +Field : total(1) +Access : read-write[1]Hotline + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Inquiry(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.2) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) + + +Register leaf node: Inquiry. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated PPS number for account (balance and validity) inquiry. + +Field : total(1) +Access : read-write[1]Inquiry number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Scratch_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.3) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) + + +Register leaf node: Scratch_Card_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via scratch card. + +Field : total(1) +Access : read-write[1]Recharge via scratch card + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Credit_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.4) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) + + +Register leaf node: Credit_Card_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via credit card. + +Field : total(1) +Access : read-write[1]Recharge via credit card + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Third_Party_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.5) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) + + +Register leaf node: Third_Party_Recharge. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharging other account from MS or PSTN. + +Field : total(1) +Access : read-write[1]Recharge other account + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Customer_Care_Center(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.6) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) +-> -> Customer_Care_Center(5) + + +Register leaf node: Customer_Care_Center. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number to connect customer care center. + +Field : total(1) +Access : read-write[1]Customer care center number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Rechareg_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.2.7) +-> father_name = [Service_Number] +-> -> Hotline(0) +-> -> Inquiry(1) +-> -> Scratch_Card_Recharge(2) +-> -> Credit_Card_Recharge(3) +-> -> Third_Party_Recharge(4) +-> -> Customer_Care_Center(5) +-> -> Rechareg_Number(6) + + +Register leaf node: Rechareg_Number. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Dedicated shortcut number for recharge via scratch card or credit card. + +Field : total(1) +Access : read-write[1]Recharge number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Service_Key(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3) +-> father_name = [SRF_Param] +-> -> SRF_Number(0) +-> -> Service_Number(1) +-> -> Service_Key(2) + + +Remark: Service key . + + +Create node: Inquiry(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.2) +-> father_name = [Service_Key] +-> -> Inquiry(0) + + +Register leaf node: Inquiry. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the function key to enquire account balance after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for inquiry + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Scratch_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.3) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) + + +Register leaf node: Scratch_Card_Recharge. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to recharge account via scratch card after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for recharging via scratch card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Credit_Card_Recharge(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.4) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) + + +Register leaf node: Credit_Card_Recharge. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key for recharging account via credit card after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key for recharging via credit card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Set_Favorite_Number(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.5) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) + + +Register leaf node: Set_Favorite_Number. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to set favorite number after entering the PPS service center. + +Field : total(1) +Access : read-write[1]Key to set favorite number + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: Language_Selection(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.6) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) +-> -> Language_Selection(4) + + +Register leaf node: Language_Selection. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Define the key to select system language (from 5 available candidates) after entering the PPS service center. All announcements in the PPS service center is played in the system language. + +Field : total(1) +Access : read-write[1]Key for language selection + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: SetPasswd(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.2.3.7) +-> father_name = [Service_Key] +-> -> Inquiry(0) +-> -> Scratch_Card_Recharge(1) +-> -> Credit_Card_Recharge(2) +-> -> Set_Favorite_Number(3) +-> -> Language_Selection(4) +-> -> SetPasswd(5) + + +Register leaf node: SetPasswd. +Instance: 1 +Length : 3 +Flag : 255 +Default :  +Remark : Define the key to set account password after entering the PPS service center. When recharging account] selecting language] modifying favorite number or seting password] subscriber is asked to pass the password verification. + +Field : total(1) +Access : read-write[1]PPS account password + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: File_Operation(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) + + +Remark: File operation . + + +Create node: Import_User_Data(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.1) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) + + +Register leaf node: Import_User_Data. +Instance: 1 +Length : 7 +Flag : 255 +Default : +Remark : Read only. Progress and result of PPS subscriber import. +Total number sent: Total quantity of PPS subscribers requesting import. +Records loaded: Quantity of successfully imported PPS subscribers. + +Field : total(3) +Access : read-only [1]Command status + { + [u]0.0-0.7 + [u]select + [v]0[opt]No operation + [v]1[opt]Send command + [v]2[opt]Begin loading + [v]3[opt]Loading OK + [v]4[opt]Loading failed + } +[2]Total number sent + { + [u]1.0-3.7 + [u]input + [v]toDec high 0 + } +[3]Records loaded + { + [u]4.0-6.7 + [u]input + [v]toDec high 0 + } + + +Create node: Import_Recharge_Card(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.2) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) + + +Register leaf node: Import_Recharge_Card. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Read only. Result of uploading recharge card to PPS. 0=unsuccessful. 1=successful. + +Field : total(1) +Access : read-only[1]Import recharge card + { + [u]0.0-0.7 + [u]input + [v]toDec high 0 + } + + +Create node: New_Tariff_Flag(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.3) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) +-> -> New_Tariff_Flag(2) + + +Register leaf node: New_Tariff_Flag. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-only [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: New_Tariff_Start_Time(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.3.4) +-> father_name = [File_Operation] +-> -> Import_User_Data(0) +-> -> Import_Recharge_Card(1) +-> -> New_Tariff_Flag(2) +-> -> New_Tariff_Start_Time(3) + + +Register leaf node: New_Tariff_Start_Time. +Instance: 1 +Length : 7 +Flag : 255 +Default :  +Remark : Read only. Set start time for new tariff plan. + +Field : total(6) +Access : read-only[1]Year + { + [u]0.0-1.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]3.0-3.7 + [u]input + [v]KeepHex high 0 + } +[4]Hour + { + [u]4.0-4.7 + [u]input + [v]KeepHex high 0 + } +[5]Minute + { + [u]5.0-5.7 + [u]input + [v]KeepHex high 0 + } +[6]Second + { + [u]6.0-6.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: COS_Param(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) + + +Remark: COS parameters . + + +Create node: COS_0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1) +-> father_name = [COS_Param] +-> -> COS_0(0) + + +Remark: COS 0 Parameters. + + +Create node: Recharge_Promotion_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.1) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) + + +Register leaf node: Start_Date_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.2) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) +-> -> End_Date_COS0(1) + + +Register leaf node: End_Date_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.1.3) +-> father_name = [Recharge_Promotion_COS0] +-> -> Start_Date_COS0(0) +-> -> End_Date_COS0(1) +-> -> Promotion_Bonus_COS0(2) + + +Register leaf node: Promotion_Bonus_COS0. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.1) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) + + +Register leaf node: MO_Tariff_ID_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.2) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) + + +Register leaf node: MT_Tariff_ID_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.3) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) +-> -> Tariff_Subscription_COS0(2) + + +Register leaf node: Tariff_Subscription_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.2.4) +-> father_name = [Tariff_Resolution_COS0] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS0(1) +-> -> Tariff_Subscription_COS0(2) +-> -> Recharge_Card_Validity_COS0(3) + + +Register leaf node: Recharge_Card_Validity_COS0. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.1) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) + + +Register leaf node: Min_balance_MO_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.2) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) +-> -> Maximum_Validity_COS0(1) + + +Register leaf node: Maximum_Validity_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.3.3) +-> father_name = [Account_Control_COS0] +-> -> Min_balance_MO_COS0(0) +-> -> Maximum_Validity_COS0(1) +-> -> Release_Day_COS0(2) + + +Register leaf node: Release_Day_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4.1) +-> father_name = [MT_Control_COS0] +-> -> Charge_Flag_COS0(0) + + +Register leaf node: Charge_Flag_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.4.2) +-> father_name = [MT_Control_COS0] +-> -> Charge_Flag_COS0(0) +-> -> Zero_Balance_Control_COS0(1) + + +Register leaf node: Zero_Balance_Control_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) +-> -> Validity_Solution_COS0(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.1) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) + + +Register leaf node: Clear_Balance_Option_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.2) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) + + +Register leaf node: Validity_Recharge_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.3) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) + + +Register leaf node: Validity_Zero_Balance_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.4) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) + + +Register leaf node: Activated_Account_Validity_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.5) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) + + +Register leaf node: FF_Number_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.6) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) +-> -> Support_Credit_Card_COS0(5) + + +Register leaf node: Support_Credit_Card_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS0 + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.5.7) +-> father_name = [Validity_Solution_COS0] +-> -> Clear_Balance_Option_COS0(0) +-> -> Validity_Recharge_COS0(1) +-> -> Validity_Zero_Balance_COS0(2) +-> -> Activated_Account_Validity_COS0(3) +-> -> FF_Number_COS0(4) +-> -> Support_Credit_Card_COS0(5) +-> -> Credit_Vault_COS0(6) + + +Register leaf node: Credit_Vault_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6) +-> father_name = [COS_0] +-> -> Recharge_Promotion_COS0(0) +-> -> Tariff_Resolution_COS0(1) +-> -> Account_Control_COS0(2) +-> -> MT_Control_COS0(3) +-> -> Validity_Solution_COS0(4) +-> -> SM_Inquiry_COS0(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.1) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) + + +Register leaf node: Feedback_SM_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.2) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) + + +Register leaf node: Inquiry_SM_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.3) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) +-> -> SM_Expiry_COS0(2) + + +Register leaf node: SM_Expiry_COS0. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.1.6.4) +-> father_name = [SM_Inquiry_COS0] +-> -> Feedback_SM_COS0(0) +-> -> Inquiry_SM_COS0(1) +-> -> SM_Expiry_COS0(2) +-> -> SM_Low_Balance_COS0(3) + + +Register leaf node: SM_Low_Balance_COS0. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) + + +Remark: COS 1 Parameters. + + +Create node: Recharge_Promotion_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.1) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) + + +Register leaf node: Start_Date_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.2) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) +-> -> End_Date_COS1(1) + + +Register leaf node: End_Date_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.1.3) +-> father_name = [Recharge_Promotion_COS1] +-> -> Start_Date_COS1(0) +-> -> End_Date_COS1(1) +-> -> Promotion_Bonus_COS1(2) + + +Register leaf node: Promotion_Bonus_COS1. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.1) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) + + +Register leaf node: MO_Tariff_ID_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.2) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) + + +Register leaf node: MT_Tariff_ID_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.3) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) +-> -> Tariff_Subscription_COS1(2) + + +Register leaf node: Tariff_Subscription_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.2.4) +-> father_name = [Tariff_Resolution_COS1] +-> -> MO_Tariff_ID_COS1(0) +-> -> MT_Tariff_ID_COS1(1) +-> -> Tariff_Subscription_COS1(2) +-> -> Recharge_Card_Validity_COS1(3) + + +Register leaf node: Recharge_Card_Validity_COS1. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.1) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) + + +Register leaf node: Min_balance_MO_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.2) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) +-> -> Maximum_Validity_COS1(1) + + +Register leaf node: Maximum_Validity_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.3.3) +-> father_name = [Account_Control_COS1] +-> -> Min_balance_MO_COS1(0) +-> -> Maximum_Validity_COS1(1) +-> -> Release_Day_COS1(2) + + +Register leaf node: Release_Day_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4.1) +-> father_name = [MT_Control_COS1] +-> -> Charge_Flag_COS1(0) + + +Register leaf node: Charge_Flag_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.4.2) +-> father_name = [MT_Control_COS1] +-> -> Charge_Flag_COS1(0) +-> -> Zero_Balance_Control_COS1(1) + + +Register leaf node: Zero_Balance_Control_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) +-> -> Validity_Solution_COS1(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.1) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) + + +Register leaf node: Clear_Balance_Option_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.2) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) + + +Register leaf node: Validity_Recharge_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.3) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) + + +Register leaf node: Validity_Zero_Balance_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.4) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) + + +Register leaf node: Activated_Account_Validity_COS1. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.5) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) + + +Register leaf node: FF_Number_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.6) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) +-> -> Support_Credit_Card_COS1(5) + + +Register leaf node: Support_Credit_Card_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.5.7) +-> father_name = [Validity_Solution_COS1] +-> -> Clear_Balance_Option_COS1(0) +-> -> Validity_Recharge_COS1(1) +-> -> Validity_Zero_Balance_COS1(2) +-> -> Activated_Account_Validity_COS1(3) +-> -> FF_Number_COS1(4) +-> -> Support_Credit_Card_COS1(5) +-> -> Credit_Vault_COS1(6) + + +Register leaf node: Credit_Vault_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6) +-> father_name = [COS_1] +-> -> Recharge_Promotion_COS1(0) +-> -> Tariff_Resolution_COS1(1) +-> -> Account_Control_COS1(2) +-> -> MT_Control_COS1(3) +-> -> Validity_Solution_COS1(4) +-> -> SM_Inquiry_COS1(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.1) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) + + +Register leaf node: Feedback_SM_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.2) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) + + +Register leaf node: Inquiry_SM_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.3) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) +-> -> SM_Expiry_COS1(2) + + +Register leaf node: SM_Expiry_COS1. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS1(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.2.6.4) +-> father_name = [SM_Inquiry_COS1] +-> -> Feedback_SM_COS1(0) +-> -> Inquiry_SM_COS1(1) +-> -> SM_Expiry_COS1(2) +-> -> SM_Low_Balance_COS1(3) + + +Register leaf node: SM_Low_Balance_COS1. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) + + +Remark: COS 2 Parameters. + + +Create node: Recharge_Promotion_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.1) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) + + +Register leaf node: Start_Date_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.2) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) +-> -> End_Date_COS2(1) + + +Register leaf node: End_Date_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.1.3) +-> father_name = [Recharge_Promotion_COS2] +-> -> Start_Date_COS2(0) +-> -> End_Date_COS2(1) +-> -> Promotion_Bonus_COS2(2) + + +Register leaf node: Promotion_Bonus_COS2. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.1) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) + + +Register leaf node: MO_Tariff_ID_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.2) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) + + +Register leaf node: MT_Tariff_ID_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.3) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) +-> -> Tariff_Subscription_COS2(2) + + +Register leaf node: Tariff_Subscription_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.2.4) +-> father_name = [Tariff_Resolution_COS2] +-> -> MO_Tariff_ID_COS2(0) +-> -> MT_Tariff_ID_COS2(1) +-> -> Tariff_Subscription_COS2(2) +-> -> Recharge_Card_Validity_COS2(3) + + +Register leaf node: Recharge_Card_Validity_COS2. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.1) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) + + +Register leaf node: Min_balance_MO_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.2) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) +-> -> Maximum_Validity_COS2(1) + + +Register leaf node: Maximum_Validity_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.3.3) +-> father_name = [Account_Control_COS2] +-> -> Min_balance_MO_COS2(0) +-> -> Maximum_Validity_COS2(1) +-> -> Release_Day_COS2(2) + + +Register leaf node: Release_Day_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4.1) +-> father_name = [MT_Control_COS2] +-> -> Charge_Flag_COS2(0) + + +Register leaf node: Charge_Flag_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.4.2) +-> father_name = [MT_Control_COS2] +-> -> Charge_Flag_COS2(0) +-> -> Zero_Balance_Control_COS2(1) + + +Register leaf node: Zero_Balance_Control_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) +-> -> Validity_Solution_COS2(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.1) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) + + +Register leaf node: Clear_Balance_Option_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.2) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) + + +Register leaf node: Validity_Recharge_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.3) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) + + +Register leaf node: Validity_Zero_Balance_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.4) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) + + +Register leaf node: Activated_Account_Validity_COS2. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.5) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) + + +Register leaf node: FF_Number_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Free times of changing: set total times of free change for family number if charge is enabled. Maximum is 15. + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.6) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) +-> -> Support_Credit_Card_COS2(5) + + +Register leaf node: Support_Credit_Card_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.5.7) +-> father_name = [Validity_Solution_COS2] +-> -> Clear_Balance_Option_COS2(0) +-> -> Validity_Recharge_COS2(1) +-> -> Validity_Zero_Balance_COS2(2) +-> -> Activated_Account_Validity_COS2(3) +-> -> FF_Number_COS2(4) +-> -> Support_Credit_Card_COS2(5) +-> -> Credit_Vault_COS2(6) + + +Register leaf node: Credit_Vault_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6) +-> father_name = [COS_2] +-> -> Recharge_Promotion_COS2(0) +-> -> Tariff_Resolution_COS2(1) +-> -> Account_Control_COS2(2) +-> -> MT_Control_COS2(3) +-> -> Validity_Solution_COS2(4) +-> -> SM_Inquiry_COS2(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.1) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) + + +Register leaf node: Feedback_SM_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.2) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) + + +Register leaf node: Inquiry_SM_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.3) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) +-> -> SM_Expiry_COS2(2) + + +Register leaf node: SM_Expiry_COS2. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS2(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.3.6.4) +-> father_name = [SM_Inquiry_COS2] +-> -> Feedback_SM_COS2(0) +-> -> Inquiry_SM_COS2(1) +-> -> SM_Expiry_COS2(2) +-> -> SM_Low_Balance_COS2(3) + + +Register leaf node: SM_Low_Balance_COS2. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) + + +Remark: COS 3 Parameters. + + +Create node: Recharge_Promotion_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.1) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) + + +Register leaf node: Start_Date_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.2) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) +-> -> End_Date_COS3(1) + + +Register leaf node: End_Date_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.1.3) +-> father_name = [Recharge_Promotion_COS3] +-> -> Start_Date_COS3(0) +-> -> End_Date_COS3(1) +-> -> Promotion_Bonus_COS3(2) + + +Register leaf node: Promotion_Bonus_COS3. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.1) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) + + +Register leaf node: MO_Tariff_ID_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.2) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) + + +Register leaf node: MT_Tariff_ID_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.3) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) +-> -> Tariff_Subscription_COS3(2) + + +Register leaf node: Tariff_Subscription_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.2.4) +-> father_name = [Tariff_Resolution_COS3] +-> -> MO_Tariff_ID_COS3(0) +-> -> MT_Tariff_ID_COS3(1) +-> -> Tariff_Subscription_COS3(2) +-> -> Recharge_Card_Validity_COS3(3) + + +Register leaf node: Recharge_Card_Validity_COS3. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.1) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) + + +Register leaf node: Min_balance_MO_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.2) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) +-> -> Maximum_Validity_COS3(1) + + +Register leaf node: Maximum_Validity_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.3.3) +-> father_name = [Account_Control_COS3] +-> -> Min_balance_MO_COS3(0) +-> -> Maximum_Validity_COS3(1) +-> -> Release_Day_COS3(2) + + +Register leaf node: Release_Day_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4.1) +-> father_name = [MT_Control_COS3] +-> -> Charge_Flag_COS3(0) + + +Register leaf node: Charge_Flag_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.4.2) +-> father_name = [MT_Control_COS3] +-> -> Charge_Flag_COS3(0) +-> -> Zero_Balance_Control_COS3(1) + + +Register leaf node: Zero_Balance_Control_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) +-> -> Validity_Solution_COS3(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.1) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) + + +Register leaf node: Clear_Balance_Option_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.2) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) + + +Register leaf node: Validity_Recharge_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.3) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) + + +Register leaf node: Validity_Zero_Balance_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.4) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) + + +Register leaf node: Activated_Account_Validity_COS3. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.5) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) + + +Register leaf node: FF_Number_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.6) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) +-> -> Support_Credit_Card_COS3(5) + + +Register leaf node: Support_Credit_Card_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.5.7) +-> father_name = [Validity_Solution_COS3] +-> -> Clear_Balance_Option_COS3(0) +-> -> Validity_Recharge_COS3(1) +-> -> Validity_Zero_Balance_COS3(2) +-> -> Activated_Account_Validity_COS3(3) +-> -> FF_Number_COS3(4) +-> -> Support_Credit_Card_COS3(5) +-> -> Credit_Vault_COS3(6) + + +Register leaf node: Credit_Vault_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6) +-> father_name = [COS_3] +-> -> Recharge_Promotion_COS3(0) +-> -> Tariff_Resolution_COS3(1) +-> -> Account_Control_COS3(2) +-> -> MT_Control_COS3(3) +-> -> Validity_Solution_COS3(4) +-> -> SM_Inquiry_COS3(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.1) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) + + +Register leaf node: Feedback_SM_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.2) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) + + +Register leaf node: Inquiry_SM_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.3) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) +-> -> SM_Expiry_COS3(2) + + +Register leaf node: SM_Expiry_COS3. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS3(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.4.6.4) +-> father_name = [SM_Inquiry_COS3] +-> -> Feedback_SM_COS3(0) +-> -> Inquiry_SM_COS3(1) +-> -> SM_Expiry_COS3(2) +-> -> SM_Low_Balance_COS3(3) + + +Register leaf node: SM_Low_Balance_COS3. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) + + +Remark: COS 4 Parameters. + + +Create node: Recharge_Promotion_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.1) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) + + +Register leaf node: Start_Date_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.2) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) +-> -> End_Date_COS4(1) + + +Register leaf node: End_Date_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.1.3) +-> father_name = [Recharge_Promotion_COS4] +-> -> Start_Date_COS4(0) +-> -> End_Date_COS4(1) +-> -> Promotion_Bonus_COS4(2) + + +Register leaf node: Promotion_Bonus_COS4. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.1) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) + + +Register leaf node: MO_Tariff_ID_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.2) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) + + +Register leaf node: MT_Tariff_ID_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.3) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) +-> -> Tariff_Subscription_COS4(2) + + +Register leaf node: Tariff_Subscription_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.2.4) +-> father_name = [Tariff_Resolution_COS4] +-> -> MO_Tariff_ID_COS4(0) +-> -> MT_Tariff_ID_COS4(1) +-> -> Tariff_Subscription_COS4(2) +-> -> Recharge_Card_Validity_COS4(3) + + +Register leaf node: Recharge_Card_Validity_COS4. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.1) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) + + +Register leaf node: Min_balance_MO_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.2) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) +-> -> Maximum_Validity_COS4(1) + + +Register leaf node: Maximum_Validity_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.3.3) +-> father_name = [Account_Control_COS4] +-> -> Min_balance_MO_COS4(0) +-> -> Maximum_Validity_COS4(1) +-> -> Release_Day_COS4(2) + + +Register leaf node: Release_Day_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4.1) +-> father_name = [MT_Control_COS4] +-> -> Charge_Flag_COS4(0) + + +Register leaf node: Charge_Flag_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.4.2) +-> father_name = [MT_Control_COS4] +-> -> Charge_Flag_COS4(0) +-> -> Zero_Balance_Control_COS4(1) + + +Register leaf node: Zero_Balance_Control_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) +-> -> Validity_Solution_COS4(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.1) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) + + +Register leaf node: Clear_Balance_Option_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.2) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) + + +Register leaf node: Validity_Recharge_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.3) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) + + +Register leaf node: Validity_Zero_Balance_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.4) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) + + +Register leaf node: Activated_Account_Validity_COS4. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.5) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) + + +Register leaf node: FF_Number_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.6) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) +-> -> Support_Credit_Card_COS4(5) + + +Register leaf node: Support_Credit_Card_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.5.7) +-> father_name = [Validity_Solution_COS4] +-> -> Clear_Balance_Option_COS4(0) +-> -> Validity_Recharge_COS4(1) +-> -> Validity_Zero_Balance_COS4(2) +-> -> Activated_Account_Validity_COS4(3) +-> -> FF_Number_COS4(4) +-> -> Support_Credit_Card_COS4(5) +-> -> Credit_Vault_COS4(6) + + +Register leaf node: Credit_Vault_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6) +-> father_name = [COS_4] +-> -> Recharge_Promotion_COS4(0) +-> -> Tariff_Resolution_COS4(1) +-> -> Account_Control_COS4(2) +-> -> MT_Control_COS4(3) +-> -> Validity_Solution_COS4(4) +-> -> SM_Inquiry_COS4(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.1) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) + + +Register leaf node: Feedback_SM_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.2) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) + + +Register leaf node: Inquiry_SM_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.3) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) +-> -> SM_Expiry_COS4(2) + + +Register leaf node: SM_Expiry_COS4. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS4(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.5.6.4) +-> father_name = [SM_Inquiry_COS4] +-> -> Feedback_SM_COS4(0) +-> -> Inquiry_SM_COS4(1) +-> -> SM_Expiry_COS4(2) +-> -> SM_Low_Balance_COS4(3) + + +Register leaf node: SM_Low_Balance_COS4. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) + + +Remark: COS 5 Parameters. + + +Create node: Recharge_Promotion_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.1) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) + + +Register leaf node: Start_Date_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.2) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) +-> -> End_Date_COS5(1) + + +Register leaf node: End_Date_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.1.3) +-> father_name = [Recharge_Promotion_COS5] +-> -> Start_Date_COS5(0) +-> -> End_Date_COS5(1) +-> -> Promotion_Bonus_COS5(2) + + +Register leaf node: Promotion_Bonus_COS5. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.1) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) + + +Register leaf node: MO_Tariff_ID_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.2) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) + + +Register leaf node: MT_Tariff_ID_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.3) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) +-> -> Tariff_Subscription_COS5(2) + + +Register leaf node: Tariff_Subscription_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.2.4) +-> father_name = [Tariff_Resolution_COS5] +-> -> MO_Tariff_ID_COS5(0) +-> -> MT_Tariff_ID_COS5(1) +-> -> Tariff_Subscription_COS5(2) +-> -> Recharge_Card_Validity_COS5(3) + + +Register leaf node: Recharge_Card_Validity_COS5. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.1) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) + + +Register leaf node: Min_balance_MO_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.2) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) +-> -> Maximum_Validity_COS5(1) + + +Register leaf node: Maximum_Validity_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.3.3) +-> father_name = [Account_Control_COS5] +-> -> Min_balance_MO_COS5(0) +-> -> Maximum_Validity_COS5(1) +-> -> Release_Day_COS5(2) + + +Register leaf node: Release_Day_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4.1) +-> father_name = [MT_Control_COS5] +-> -> Charge_Flag_COS5(0) + + +Register leaf node: Charge_Flag_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.4.2) +-> father_name = [MT_Control_COS5] +-> -> Charge_Flag_COS5(0) +-> -> Zero_Balance_Control_COS5(1) + + +Register leaf node: Zero_Balance_Control_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) +-> -> Validity_Solution_COS5(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.1) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) + + +Register leaf node: Clear_Balance_Option_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.2) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) + + +Register leaf node: Validity_Recharge_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.3) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) + + +Register leaf node: Validity_Zero_Balance_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.4) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) + + +Register leaf node: Activated_Account_Validity_COS5. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.5) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) + + +Register leaf node: FF_Number_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.6) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) +-> -> Support_Credit_Card_COS5(5) + + +Register leaf node: Support_Credit_Card_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.5.7) +-> father_name = [Validity_Solution_COS5] +-> -> Clear_Balance_Option_COS5(0) +-> -> Validity_Recharge_COS5(1) +-> -> Validity_Zero_Balance_COS5(2) +-> -> Activated_Account_Validity_COS5(3) +-> -> FF_Number_COS5(4) +-> -> Support_Credit_Card_COS5(5) +-> -> Credit_Vault_COS5(6) + + +Register leaf node: Credit_Vault_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6) +-> father_name = [COS_5] +-> -> Recharge_Promotion_COS5(0) +-> -> Tariff_Resolution_COS5(1) +-> -> Account_Control_COS5(2) +-> -> MT_Control_COS5(3) +-> -> Validity_Solution_COS5(4) +-> -> SM_Inquiry_COS5(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.1) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) + + +Register leaf node: Feedback_SM_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.2) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) + + +Register leaf node: Inquiry_SM_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.3) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) +-> -> SM_Expiry_COS5(2) + + +Register leaf node: SM_Expiry_COS5. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS5(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.6.6.4) +-> father_name = [SM_Inquiry_COS5] +-> -> Feedback_SM_COS5(0) +-> -> Inquiry_SM_COS5(1) +-> -> SM_Expiry_COS5(2) +-> -> SM_Low_Balance_COS5(3) + + +Register leaf node: SM_Low_Balance_COS5. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) + + +Remark: COS 6 Parameters. + + +Create node: Recharge_Promotion_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.1) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) + + +Register leaf node: Start_Date_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.2) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) +-> -> End_Date_COS6(1) + + +Register leaf node: End_Date_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.1.3) +-> father_name = [Recharge_Promotion_COS6] +-> -> Start_Date_COS6(0) +-> -> End_Date_COS6(1) +-> -> Promotion_Bonus_COS6(2) + + +Register leaf node: Promotion_Bonus_COS6. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.1) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) + + +Register leaf node: MO_Tariff_ID_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.2) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) + + +Register leaf node: MT_Tariff_ID_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.3) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) +-> -> Tariff_Subscription_COS6(2) + + +Register leaf node: Tariff_Subscription_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.2.4) +-> father_name = [Tariff_Resolution_COS6] +-> -> MO_Tariff_ID_COS6(0) +-> -> MT_Tariff_ID_COS6(1) +-> -> Tariff_Subscription_COS6(2) +-> -> Recharge_Card_Validity_COS6(3) + + +Register leaf node: Recharge_Card_Validity_COS6. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.1) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) + + +Register leaf node: Min_balance_MO_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.2) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) +-> -> Maximum_Validity_COS6(1) + + +Register leaf node: Maximum_Validity_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.3.3) +-> father_name = [Account_Control_COS6] +-> -> Min_balance_MO_COS6(0) +-> -> Maximum_Validity_COS6(1) +-> -> Release_Day_COS6(2) + + +Register leaf node: Release_Day_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4.1) +-> father_name = [MT_Control_COS6] +-> -> Charge_Flag_COS6(0) + + +Register leaf node: Charge_Flag_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.4.2) +-> father_name = [MT_Control_COS6] +-> -> Charge_Flag_COS6(0) +-> -> Zero_Balance_Control_COS6(1) + + +Register leaf node: Zero_Balance_Control_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) +-> -> Validity_Solution_COS6(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.1) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) + + +Register leaf node: Clear_Balance_Option_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.2) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) + + +Register leaf node: Validity_Recharge_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.3) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) + + +Register leaf node: Validity_Zero_Balance_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.4) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) + + +Register leaf node: Activated_Account_Validity_COS6. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.5) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) + + +Register leaf node: FF_Number_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.6) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) +-> -> Support_Credit_Card_COS6(5) + + +Register leaf node: Support_Credit_Card_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.5.7) +-> father_name = [Validity_Solution_COS6] +-> -> Clear_Balance_Option_COS6(0) +-> -> Validity_Recharge_COS6(1) +-> -> Validity_Zero_Balance_COS6(2) +-> -> Activated_Account_Validity_COS6(3) +-> -> FF_Number_COS6(4) +-> -> Support_Credit_Card_COS6(5) +-> -> Credit_Vault_COS6(6) + + +Register leaf node: Credit_Vault_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6) +-> father_name = [COS_6] +-> -> Recharge_Promotion_COS6(0) +-> -> Tariff_Resolution_COS6(1) +-> -> Account_Control_COS6(2) +-> -> MT_Control_COS6(3) +-> -> Validity_Solution_COS6(4) +-> -> SM_Inquiry_COS6(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.1) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) + + +Register leaf node: Feedback_SM_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.2) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) + + +Register leaf node: Inquiry_SM_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.3) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) +-> -> SM_Expiry_COS6(2) + + +Register leaf node: SM_Expiry_COS6. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS6(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.7.6.4) +-> father_name = [SM_Inquiry_COS6] +-> -> Feedback_SM_COS6(0) +-> -> Inquiry_SM_COS6(1) +-> -> SM_Expiry_COS6(2) +-> -> SM_Low_Balance_COS6(3) + + +Register leaf node: SM_Low_Balance_COS6. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) + + +Remark: COS 7 Parameters. + + +Create node: Recharge_Promotion_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.1) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) + + +Register leaf node: Start_Date_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.2) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) +-> -> End_Date_COS7(1) + + +Register leaf node: End_Date_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.1.3) +-> father_name = [Recharge_Promotion_COS7] +-> -> Start_Date_COS7(0) +-> -> End_Date_COS7(1) +-> -> Promotion_Bonus_COS7(2) + + +Register leaf node: Promotion_Bonus_COS7. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.1) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) + + +Register leaf node: MO_Tariff_ID_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.2) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) + + +Register leaf node: MT_Tariff_ID_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.3) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) +-> -> Tariff_Subscription_COS7(2) + + +Register leaf node: Tariff_Subscription_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.2.4) +-> father_name = [Tariff_Resolution_COS7] +-> -> MO_Tariff_ID_COS7(0) +-> -> MT_Tariff_ID_COS7(1) +-> -> Tariff_Subscription_COS7(2) +-> -> Recharge_Card_Validity_COS7(3) + + +Register leaf node: Recharge_Card_Validity_COS7. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.1) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) + + +Register leaf node: Min_balance_MO_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.2) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) +-> -> Maximum_Validity_COS7(1) + + +Register leaf node: Maximum_Validity_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.3.3) +-> father_name = [Account_Control_COS7] +-> -> Min_balance_MO_COS7(0) +-> -> Maximum_Validity_COS7(1) +-> -> Release_Day_COS7(2) + + +Register leaf node: Release_Day_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4.1) +-> father_name = [MT_Control_COS7] +-> -> Charge_Flag_COS7(0) + + +Register leaf node: Charge_Flag_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.4.2) +-> father_name = [MT_Control_COS7] +-> -> Charge_Flag_COS7(0) +-> -> Zero_Balance_Control_COS7(1) + + +Register leaf node: Zero_Balance_Control_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) +-> -> Validity_Solution_COS7(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.1) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) + + +Register leaf node: Clear_Balance_Option_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.2) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) + + +Register leaf node: Validity_Recharge_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.3) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) + + +Register leaf node: Validity_Zero_Balance_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.4) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) + + +Register leaf node: Activated_Account_Validity_COS7. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.5) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) + + +Register leaf node: FF_Number_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.6) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) +-> -> Support_Credit_Card_COS7(5) + + +Register leaf node: Support_Credit_Card_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.5.7) +-> father_name = [Validity_Solution_COS7] +-> -> Clear_Balance_Option_COS7(0) +-> -> Validity_Recharge_COS7(1) +-> -> Validity_Zero_Balance_COS7(2) +-> -> Activated_Account_Validity_COS7(3) +-> -> FF_Number_COS7(4) +-> -> Support_Credit_Card_COS7(5) +-> -> Credit_Vault_COS7(6) + + +Register leaf node: Credit_Vault_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6) +-> father_name = [COS_7] +-> -> Recharge_Promotion_COS7(0) +-> -> Tariff_Resolution_COS7(1) +-> -> Account_Control_COS7(2) +-> -> MT_Control_COS7(3) +-> -> Validity_Solution_COS7(4) +-> -> SM_Inquiry_COS7(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.1) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) + + +Register leaf node: Feedback_SM_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.2) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) + + +Register leaf node: Inquiry_SM_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.3) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) +-> -> SM_Expiry_COS7(2) + + +Register leaf node: SM_Expiry_COS7. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS7(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.8.6.4) +-> father_name = [SM_Inquiry_COS7] +-> -> Feedback_SM_COS7(0) +-> -> Inquiry_SM_COS7(1) +-> -> SM_Expiry_COS7(2) +-> -> SM_Low_Balance_COS7(3) + + +Register leaf node: SM_Low_Balance_COS7. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) + + +Remark: COS 8 Parameters. + + +Create node: Recharge_Promotion_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.1) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) + + +Register leaf node: Start_Date_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.2) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) +-> -> End_Date_COS8(1) + + +Register leaf node: End_Date_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.1.3) +-> father_name = [Recharge_Promotion_COS8] +-> -> Start_Date_COS8(0) +-> -> End_Date_COS8(1) +-> -> Promotion_Bonus_COS8(2) + + +Register leaf node: Promotion_Bonus_COS8. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.1) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) + + +Register leaf node: MO_Tariff_ID_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.2) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) + + +Register leaf node: MT_Tariff_ID_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.3) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) +-> -> Tariff_Subscription_COS8(2) + + +Register leaf node: Tariff_Subscription_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.2.4) +-> father_name = [Tariff_Resolution_COS8] +-> -> MO_Tariff_ID_COS8(0) +-> -> MT_Tariff_ID_COS8(1) +-> -> Tariff_Subscription_COS8(2) +-> -> Recharge_Card_Validity_COS8(3) + + +Register leaf node: Recharge_Card_Validity_COS8. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.1) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) + + +Register leaf node: Min_balance_MO_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.2) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) +-> -> Maximum_Validity_COS8(1) + + +Register leaf node: Maximum_Validity_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.3.3) +-> father_name = [Account_Control_COS8] +-> -> Min_balance_MO_COS8(0) +-> -> Maximum_Validity_COS8(1) +-> -> Release_Day_COS8(2) + + +Register leaf node: Release_Day_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4.1) +-> father_name = [MT_Control_COS8] +-> -> Charge_Flag_COS8(0) + + +Register leaf node: Charge_Flag_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.4.2) +-> father_name = [MT_Control_COS8] +-> -> Charge_Flag_COS8(0) +-> -> Zero_Balance_Control_COS8(1) + + +Register leaf node: Zero_Balance_Control_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) +-> -> Validity_Solution_COS8(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.1) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) + + +Register leaf node: Clear_Balance_Option_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.2) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) + + +Register leaf node: Validity_Recharge_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.3) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) + + +Register leaf node: Validity_Zero_Balance_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.4) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) + + +Register leaf node: Activated_Account_Validity_COS8. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.5) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) + + +Register leaf node: FF_Number_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.6) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) +-> -> Support_Credit_Card_COS8(5) + + +Register leaf node: Support_Credit_Card_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.5.7) +-> father_name = [Validity_Solution_COS8] +-> -> Clear_Balance_Option_COS8(0) +-> -> Validity_Recharge_COS8(1) +-> -> Validity_Zero_Balance_COS8(2) +-> -> Activated_Account_Validity_COS8(3) +-> -> FF_Number_COS8(4) +-> -> Support_Credit_Card_COS8(5) +-> -> Credit_Vault_COS8(6) + + +Register leaf node: Credit_Vault_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6) +-> father_name = [COS_8] +-> -> Recharge_Promotion_COS8(0) +-> -> Tariff_Resolution_COS8(1) +-> -> Account_Control_COS8(2) +-> -> MT_Control_COS8(3) +-> -> Validity_Solution_COS8(4) +-> -> SM_Inquiry_COS8(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.1) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) + + +Register leaf node: Feedback_SM_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.2) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) + + +Register leaf node: Inquiry_SM_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.3) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) +-> -> SM_Expiry_COS8(2) + + +Register leaf node: SM_Expiry_COS8. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS8(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.9.6.4) +-> father_name = [SM_Inquiry_COS8] +-> -> Feedback_SM_COS8(0) +-> -> Inquiry_SM_COS8(1) +-> -> SM_Expiry_COS8(2) +-> -> SM_Low_Balance_COS8(3) + + +Register leaf node: SM_Low_Balance_COS8. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) + + +Remark: COS 9 Parameters. + + +Create node: Recharge_Promotion_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.1) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) + + +Register leaf node: Start_Date_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.2) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) +-> -> End_Date_COS9(1) + + +Register leaf node: End_Date_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.1.3) +-> father_name = [Recharge_Promotion_COS9] +-> -> Start_Date_COS9(0) +-> -> End_Date_COS9(1) +-> -> Promotion_Bonus_COS9(2) + + +Register leaf node: Promotion_Bonus_COS9. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.1) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) + + +Register leaf node: MO_Tariff_ID_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.2) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) + + +Register leaf node: MT_Tariff_ID_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.3) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) +-> -> Tariff_Subscription_COS9(2) + + +Register leaf node: Tariff_Subscription_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.2.4) +-> father_name = [Tariff_Resolution_COS9] +-> -> MO_Tariff_ID_COS9(0) +-> -> MT_Tariff_ID_COS9(1) +-> -> Tariff_Subscription_COS9(2) +-> -> Recharge_Card_Validity_COS9(3) + + +Register leaf node: Recharge_Card_Validity_COS9. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.1) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) + + +Register leaf node: Min_balance_MO_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.2) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) +-> -> Maximum_Validity_COS9(1) + + +Register leaf node: Maximum_Validity_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.3.3) +-> father_name = [Account_Control_COS9] +-> -> Min_balance_MO_COS9(0) +-> -> Maximum_Validity_COS9(1) +-> -> Release_Day_COS9(2) + + +Register leaf node: Release_Day_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4.1) +-> father_name = [MT_Control_COS9] +-> -> Charge_Flag_COS9(0) + + +Register leaf node: Charge_Flag_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.4.2) +-> father_name = [MT_Control_COS9] +-> -> Charge_Flag_COS9(0) +-> -> Zero_Balance_Control_COS9(1) + + +Register leaf node: Zero_Balance_Control_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) +-> -> Validity_Solution_COS9(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.1) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) + + +Register leaf node: Clear_Balance_Option_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.2) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) + + +Register leaf node: Validity_Recharge_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.3) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) + + +Register leaf node: Validity_Zero_Balance_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.4) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) + + +Register leaf node: Activated_Account_Validity_COS9. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.5) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) + + +Register leaf node: FF_Number_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.6) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) +-> -> Support_Credit_Card_COS9(5) + + +Register leaf node: Support_Credit_Card_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.5.7) +-> father_name = [Validity_Solution_COS9] +-> -> Clear_Balance_Option_COS9(0) +-> -> Validity_Recharge_COS9(1) +-> -> Validity_Zero_Balance_COS9(2) +-> -> Activated_Account_Validity_COS9(3) +-> -> FF_Number_COS9(4) +-> -> Support_Credit_Card_COS9(5) +-> -> Credit_Vault_COS9(6) + + +Register leaf node: Credit_Vault_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6) +-> father_name = [COS_9] +-> -> Recharge_Promotion_COS9(0) +-> -> Tariff_Resolution_COS9(1) +-> -> Account_Control_COS9(2) +-> -> MT_Control_COS9(3) +-> -> Validity_Solution_COS9(4) +-> -> SM_Inquiry_COS9(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.1) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) + + +Register leaf node: Feedback_SM_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.2) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) + + +Register leaf node: Inquiry_SM_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.3) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) +-> -> SM_Expiry_COS9(2) + + +Register leaf node: SM_Expiry_COS9. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS9(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.10.6.4) +-> father_name = [SM_Inquiry_COS9] +-> -> Feedback_SM_COS9(0) +-> -> Inquiry_SM_COS9(1) +-> -> SM_Expiry_COS9(2) +-> -> SM_Low_Balance_COS9(3) + + +Register leaf node: SM_Low_Balance_COS9. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) + + +Remark: COS 10 Parameters. + + +Create node: Recharge_Promotion_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.1) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) + + +Register leaf node: Start_Date_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.2) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) +-> -> End_Date_COS10(1) + + +Register leaf node: End_Date_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.1.3) +-> father_name = [Recharge_Promotion_COS10] +-> -> Start_Date_COS10(0) +-> -> End_Date_COS10(1) +-> -> Promotion_Bonus_COS10(2) + + +Register leaf node: Promotion_Bonus_COS10. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.1) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) + + +Register leaf node: MO_Tariff_ID_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.2) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) + + +Register leaf node: MT_Tariff_ID_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.3) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) +-> -> Tariff_Subscription_COS10(2) + + +Register leaf node: Tariff_Subscription_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.2.4) +-> father_name = [Tariff_Resolution_COS10] +-> -> MO_Tariff_ID_COS10(0) +-> -> MT_Tariff_ID_COS10(1) +-> -> Tariff_Subscription_COS10(2) +-> -> Recharge_Card_Validity_COS10(3) + + +Register leaf node: Recharge_Card_Validity_COS10. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.1) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) + + +Register leaf node: Min_balance_MO_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.2) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) +-> -> Maximum_Validity_COS10(1) + + +Register leaf node: Maximum_Validity_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.3.3) +-> father_name = [Account_Control_COS10] +-> -> Min_balance_MO_COS10(0) +-> -> Maximum_Validity_COS10(1) +-> -> Release_Day_COS10(2) + + +Register leaf node: Release_Day_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4.1) +-> father_name = [MT_Control_COS10] +-> -> Charge_Flag_COS10(0) + + +Register leaf node: Charge_Flag_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.4.2) +-> father_name = [MT_Control_COS10] +-> -> Charge_Flag_COS10(0) +-> -> Zero_Balance_Control_COS10(1) + + +Register leaf node: Zero_Balance_Control_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) +-> -> Validity_Solution_COS10(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.1) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) + + +Register leaf node: Clear_Balance_Option_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.2) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) + + +Register leaf node: Validity_Recharge_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.3) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) + + +Register leaf node: Validity_Zero_Balance_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.4) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) + + +Register leaf node: Activated_Account_Validity_COS10. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.5) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) + + +Register leaf node: FF_Number_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.6) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) +-> -> Support_Credit_Card_COS10(5) + + +Register leaf node: Support_Credit_Card_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.5.7) +-> father_name = [Validity_Solution_COS10] +-> -> Clear_Balance_Option_COS10(0) +-> -> Validity_Recharge_COS10(1) +-> -> Validity_Zero_Balance_COS10(2) +-> -> Activated_Account_Validity_COS10(3) +-> -> FF_Number_COS10(4) +-> -> Support_Credit_Card_COS10(5) +-> -> Credit_Vault_COS10(6) + + +Register leaf node: Credit_Vault_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6) +-> father_name = [COS_10] +-> -> Recharge_Promotion_COS10(0) +-> -> Tariff_Resolution_COS10(1) +-> -> Account_Control_COS10(2) +-> -> MT_Control_COS10(3) +-> -> Validity_Solution_COS10(4) +-> -> SM_Inquiry_COS10(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.1) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) + + +Register leaf node: Feedback_SM_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.2) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) + + +Register leaf node: Inquiry_SM_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.3) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) +-> -> SM_Expiry_COS10(2) + + +Register leaf node: SM_Expiry_COS10. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS10(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.11.6.4) +-> father_name = [SM_Inquiry_COS10] +-> -> Feedback_SM_COS10(0) +-> -> Inquiry_SM_COS10(1) +-> -> SM_Expiry_COS10(2) +-> -> SM_Low_Balance_COS10(3) + + +Register leaf node: SM_Low_Balance_COS10. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) + + +Remark: COS 11 Parameters. + + +Create node: Recharge_Promotion_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.1) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) + + +Register leaf node: Start_Date_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.2) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) +-> -> End_Date_COS11(1) + + +Register leaf node: End_Date_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.1.3) +-> father_name = [Recharge_Promotion_COS11] +-> -> Start_Date_COS11(0) +-> -> End_Date_COS11(1) +-> -> Promotion_Bonus_COS11(2) + + +Register leaf node: Promotion_Bonus_COS11. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.1) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) + + +Register leaf node: MO_Tariff_ID_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.2) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) + + +Register leaf node: MT_Tariff_ID_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.3) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) +-> -> Tariff_Subscription_COS11(2) + + +Register leaf node: Tariff_Subscription_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.2.4) +-> father_name = [Tariff_Resolution_COS11] +-> -> MO_Tariff_ID_COS11(0) +-> -> MT_Tariff_ID_COS11(1) +-> -> Tariff_Subscription_COS11(2) +-> -> Recharge_Card_Validity_COS11(3) + + +Register leaf node: Recharge_Card_Validity_COS11. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.1) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) + + +Register leaf node: Min_balance_MO_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.2) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) +-> -> Maximum_Validity_COS11(1) + + +Register leaf node: Maximum_Validity_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.3.3) +-> father_name = [Account_Control_COS11] +-> -> Min_balance_MO_COS11(0) +-> -> Maximum_Validity_COS11(1) +-> -> Release_Day_COS11(2) + + +Register leaf node: Release_Day_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4.1) +-> father_name = [MT_Control_COS11] +-> -> Charge_Flag_COS11(0) + + +Register leaf node: Charge_Flag_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.4.2) +-> father_name = [MT_Control_COS11] +-> -> Charge_Flag_COS11(0) +-> -> Zero_Balance_Control_COS11(1) + + +Register leaf node: Zero_Balance_Control_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) +-> -> Validity_Solution_COS11(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.1) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) + + +Register leaf node: Clear_Balance_Option_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.2) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) + + +Register leaf node: Validity_Recharge_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.3) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) + + +Register leaf node: Validity_Zero_Balance_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.4) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) + + +Register leaf node: Activated_Account_Validity_COS11. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.5) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) + + +Register leaf node: FF_Number_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.6) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) +-> -> Support_Credit_Card_COS11(5) + + +Register leaf node: Support_Credit_Card_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.5.7) +-> father_name = [Validity_Solution_COS11] +-> -> Clear_Balance_Option_COS11(0) +-> -> Validity_Recharge_COS11(1) +-> -> Validity_Zero_Balance_COS11(2) +-> -> Activated_Account_Validity_COS11(3) +-> -> FF_Number_COS11(4) +-> -> Support_Credit_Card_COS11(5) +-> -> Credit_Vault_COS11(6) + + +Register leaf node: Credit_Vault_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6) +-> father_name = [COS_11] +-> -> Recharge_Promotion_COS11(0) +-> -> Tariff_Resolution_COS11(1) +-> -> Account_Control_COS11(2) +-> -> MT_Control_COS11(3) +-> -> Validity_Solution_COS11(4) +-> -> SM_Inquiry_COS11(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.1) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) + + +Register leaf node: Feedback_SM_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.2) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) + + +Register leaf node: Inquiry_SM_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.3) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) +-> -> SM_Expiry_COS11(2) + + +Register leaf node: SM_Expiry_COS11. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS11(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.12.6.4) +-> father_name = [SM_Inquiry_COS11] +-> -> Feedback_SM_COS11(0) +-> -> Inquiry_SM_COS11(1) +-> -> SM_Expiry_COS11(2) +-> -> SM_Low_Balance_COS11(3) + + +Register leaf node: SM_Low_Balance_COS11. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) + + +Remark: COS 12 Parameters. + + +Create node: Recharge_Promotion_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.1) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) + + +Register leaf node: Start_Date_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.2) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) +-> -> End_Date_COS12(1) + + +Register leaf node: End_Date_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.1.3) +-> father_name = [Recharge_Promotion_COS12] +-> -> Start_Date_COS12(0) +-> -> End_Date_COS12(1) +-> -> Promotion_Bonus_COS12(2) + + +Register leaf node: Promotion_Bonus_COS12. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.1) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) + + +Register leaf node: MO_Tariff_ID_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.2) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) + + +Register leaf node: MT_Tariff_ID_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.3) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) +-> -> Tariff_Subscription_COS12(2) + + +Register leaf node: Tariff_Subscription_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.2.4) +-> father_name = [Tariff_Resolution_COS12] +-> -> MO_Tariff_ID_COS12(0) +-> -> MT_Tariff_ID_COS12(1) +-> -> Tariff_Subscription_COS12(2) +-> -> Recharge_Card_Validity_COS12(3) + + +Register leaf node: Recharge_Card_Validity_COS12. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.1) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) + + +Register leaf node: Min_balance_MO_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.2) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) +-> -> Maximum_Validity_COS12(1) + + +Register leaf node: Maximum_Validity_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.3.3) +-> father_name = [Account_Control_COS12] +-> -> Min_balance_MO_COS12(0) +-> -> Maximum_Validity_COS12(1) +-> -> Release_Day_COS12(2) + + +Register leaf node: Release_Day_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4.1) +-> father_name = [MT_Control_COS12] +-> -> Charge_Flag_COS12(0) + + +Register leaf node: Charge_Flag_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.4.2) +-> father_name = [MT_Control_COS12] +-> -> Charge_Flag_COS12(0) +-> -> Zero_Balance_Control_COS12(1) + + +Register leaf node: Zero_Balance_Control_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) +-> -> Validity_Solution_COS12(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.1) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) + + +Register leaf node: Clear_Balance_Option_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.2) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) + + +Register leaf node: Validity_Recharge_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.3) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) + + +Register leaf node: Validity_Zero_Balance_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.4) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) + + +Register leaf node: Activated_Account_Validity_COS12. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.5) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) + + +Register leaf node: FF_Number_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.6) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) +-> -> Support_Credit_Card_COS12(5) + + +Register leaf node: Support_Credit_Card_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.5.7) +-> father_name = [Validity_Solution_COS12] +-> -> Clear_Balance_Option_COS12(0) +-> -> Validity_Recharge_COS12(1) +-> -> Validity_Zero_Balance_COS12(2) +-> -> Activated_Account_Validity_COS12(3) +-> -> FF_Number_COS12(4) +-> -> Support_Credit_Card_COS12(5) +-> -> Credit_Vault_COS12(6) + + +Register leaf node: Credit_Vault_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6) +-> father_name = [COS_12] +-> -> Recharge_Promotion_COS12(0) +-> -> Tariff_Resolution_COS12(1) +-> -> Account_Control_COS12(2) +-> -> MT_Control_COS12(3) +-> -> Validity_Solution_COS12(4) +-> -> SM_Inquiry_COS12(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.1) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) + + +Register leaf node: Feedback_SM_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.2) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) + + +Register leaf node: Inquiry_SM_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.3) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) +-> -> SM_Expiry_COS12(2) + + +Register leaf node: SM_Expiry_COS12. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS12(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.13.6.4) +-> father_name = [SM_Inquiry_COS12] +-> -> Feedback_SM_COS12(0) +-> -> Inquiry_SM_COS12(1) +-> -> SM_Expiry_COS12(2) +-> -> SM_Low_Balance_COS12(3) + + +Register leaf node: SM_Low_Balance_COS12. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) + + +Remark: COS 13 Parameters. + + +Create node: Recharge_Promotion_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.1) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) + + +Register leaf node: Start_Date_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.2) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) +-> -> End_Date_COS13(1) + + +Register leaf node: End_Date_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.1.3) +-> father_name = [Recharge_Promotion_COS13] +-> -> Start_Date_COS13(0) +-> -> End_Date_COS13(1) +-> -> Promotion_Bonus_COS13(2) + + +Register leaf node: Promotion_Bonus_COS13. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS0(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.1) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) + + +Register leaf node: MO_Tariff_ID_COS0. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.2) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) + + +Register leaf node: MT_Tariff_ID_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.3) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) +-> -> Tariff_Subscription_COS13(2) + + +Register leaf node: Tariff_Subscription_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.2.4) +-> father_name = [Tariff_Resolution_COS13] +-> -> MO_Tariff_ID_COS0(0) +-> -> MT_Tariff_ID_COS13(1) +-> -> Tariff_Subscription_COS13(2) +-> -> Recharge_Card_Validity_COS13(3) + + +Register leaf node: Recharge_Card_Validity_COS13. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.1) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) + + +Register leaf node: Min_balance_MO_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.2) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) +-> -> Maximum_Validity_COS13(1) + + +Register leaf node: Maximum_Validity_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.3.3) +-> father_name = [Account_Control_COS13] +-> -> Min_balance_MO_COS13(0) +-> -> Maximum_Validity_COS13(1) +-> -> Release_Day_COS13(2) + + +Register leaf node: Release_Day_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4.1) +-> father_name = [MT_Control_COS13] +-> -> Charge_Flag_COS13(0) + + +Register leaf node: Charge_Flag_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.4.2) +-> father_name = [MT_Control_COS13] +-> -> Charge_Flag_COS13(0) +-> -> Zero_Balance_Control_COS13(1) + + +Register leaf node: Zero_Balance_Control_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) +-> -> Validity_Solution_COS13(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.1) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) + + +Register leaf node: Clear_Balance_Option_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.2) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) + + +Register leaf node: Validity_Recharge_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.3) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) + + +Register leaf node: Validity_Zero_Balance_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.4) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) + + +Register leaf node: Activated_Account_Validity_COS13. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.5) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) + + +Register leaf node: FF_Number_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.6) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) +-> -> Support_Credit_Card_COS13(5) + + +Register leaf node: Support_Credit_Card_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.5.7) +-> father_name = [Validity_Solution_COS13] +-> -> Clear_Balance_Option_COS13(0) +-> -> Validity_Recharge_COS13(1) +-> -> Validity_Zero_Balance_COS13(2) +-> -> Activated_Account_Validity_COS13(3) +-> -> FF_Number_COS13(4) +-> -> Support_Credit_Card_COS13(5) +-> -> Credit_Vault_COS13(6) + + +Register leaf node: Credit_Vault_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6) +-> father_name = [COS_13] +-> -> Recharge_Promotion_COS13(0) +-> -> Tariff_Resolution_COS13(1) +-> -> Account_Control_COS13(2) +-> -> MT_Control_COS13(3) +-> -> Validity_Solution_COS13(4) +-> -> SM_Inquiry_COS13(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.1) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) + + +Register leaf node: Feedback_SM_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.2) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) + + +Register leaf node: Inquiry_SM_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.3) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) +-> -> SM_Expiry_COS13(2) + + +Register leaf node: SM_Expiry_COS13. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS13(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.14.6.4) +-> father_name = [SM_Inquiry_COS13] +-> -> Feedback_SM_COS13(0) +-> -> Inquiry_SM_COS13(1) +-> -> SM_Expiry_COS13(2) +-> -> SM_Low_Balance_COS13(3) + + +Register leaf node: SM_Low_Balance_COS13. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) +-> -> COS_14(14) + + +Remark: COS 14 Parameters. + + +Create node: Recharge_Promotion_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.1) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) + + +Register leaf node: Start_Date_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.2) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) +-> -> End_Date_COS14(1) + + +Register leaf node: End_Date_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.1.3) +-> father_name = [Recharge_Promotion_COS14] +-> -> Start_Date_COS14(0) +-> -> End_Date_COS14(1) +-> -> Promotion_Bonus_COS14(2) + + +Register leaf node: Promotion_Bonus_COS14. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.1) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) + + +Register leaf node: MO_Tariff_ID_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.2) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) + + +Register leaf node: MT_Tariff_ID_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.3) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) +-> -> Tariff_Subscription_COS14(2) + + +Register leaf node: Tariff_Subscription_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.2.4) +-> father_name = [Tariff_Resolution_COS14] +-> -> MO_Tariff_ID_COS14(0) +-> -> MT_Tariff_ID_COS14(1) +-> -> Tariff_Subscription_COS14(2) +-> -> Recharge_Card_Validity_COS14(3) + + +Register leaf node: Recharge_Card_Validity_COS14. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.1) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) + + +Register leaf node: Min_balance_MO_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.2) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) +-> -> Maximum_Validity_COS14(1) + + +Register leaf node: Maximum_Validity_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.3.3) +-> father_name = [Account_Control_COS14] +-> -> Min_balance_MO_COS14(0) +-> -> Maximum_Validity_COS14(1) +-> -> Release_Day_COS14(2) + + +Register leaf node: Release_Day_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4.1) +-> father_name = [MT_Control_COS14] +-> -> Charge_Flag_COS14(0) + + +Register leaf node: Charge_Flag_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.4.2) +-> father_name = [MT_Control_COS14] +-> -> Charge_Flag_COS14(0) +-> -> Zero_Balance_Control_COS14(1) + + +Register leaf node: Zero_Balance_Control_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) +-> -> Validity_Solution_COS14(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.1) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) + + +Register leaf node: Clear_Balance_Option_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.2) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) + + +Register leaf node: Validity_Recharge_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.3) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) + + +Register leaf node: Validity_Zero_Balance_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.4) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) + + +Register leaf node: Activated_Account_Validity_COS14. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.5) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) + + +Register leaf node: FF_Number_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.6) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) +-> -> Support_Credit_Card_COS14(5) + + +Register leaf node: Support_Credit_Card_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.5.7) +-> father_name = [Validity_Solution_COS14] +-> -> Clear_Balance_Option_COS14(0) +-> -> Validity_Recharge_COS14(1) +-> -> Validity_Zero_Balance_COS14(2) +-> -> Activated_Account_Validity_COS14(3) +-> -> FF_Number_COS14(4) +-> -> Support_Credit_Card_COS14(5) +-> -> Credit_Vault_COS14(6) + + +Register leaf node: Credit_Vault_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6) +-> father_name = [COS_14] +-> -> Recharge_Promotion_COS14(0) +-> -> Tariff_Resolution_COS14(1) +-> -> Account_Control_COS14(2) +-> -> MT_Control_COS14(3) +-> -> Validity_Solution_COS14(4) +-> -> SM_Inquiry_COS14(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.1) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) + + +Register leaf node: Feedback_SM_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.2) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) + + +Register leaf node: Inquiry_SM_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.3) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) +-> -> SM_Expiry_COS14(2) + + +Register leaf node: SM_Expiry_COS14. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS14(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.15.6.4) +-> father_name = [SM_Inquiry_COS14] +-> -> Feedback_SM_COS14(0) +-> -> Inquiry_SM_COS14(1) +-> -> SM_Expiry_COS14(2) +-> -> SM_Low_Balance_COS14(3) + + +Register leaf node: SM_Low_Balance_COS14. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: COS_15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16) +-> father_name = [COS_Param] +-> -> COS_0(0) +-> -> COS_1(1) +-> -> COS_2(2) +-> -> COS_3(3) +-> -> COS_4(4) +-> -> COS_5(5) +-> -> COS_6(6) +-> -> COS_7(7) +-> -> COS_8(8) +-> -> COS_9(9) +-> -> COS_10(10) +-> -> COS_11(11) +-> -> COS_12(12) +-> -> COS_13(13) +-> -> COS_14(14) +-> -> COS_15(15) + + +Remark: COS 15 Parameters. + + +Create node: Recharge_Promotion_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) + + +Remark: Recharge Promotion. + + +Create node: Start_Date_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.1) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) + + +Register leaf node: Start_Date_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is +valid. Operator defines the promotion period by specifying the start and end +date. Each COS may have its own promotion period. Subscriber recharges his +account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: End_Date_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.2) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) +-> -> End_Date_COS15(1) + + +Register leaf node: End_Date_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : The promotion period is the period of time in which the recharge promotion is valid. Operator +defines the promotion period by specifying the start and end date. Each COS may have its own promotion period. +Subscriber recharges his account within the promotion period of his COS will receive a promotion bonus. +To turn off the recharge promotion, set the start and end date as 000000. + +Field : total(3) +Access : read-write[1]Year: 20 + { + [u]0.0-0.7 + [u]input + [v]KeepHex high 0 + } +[2]Month + { + [u]1.0-1.7 + [u]input + [v]KeepHex high 0 + } +[3]Day + { + [u]2.0-2.7 + [u]input + [v]KeepHex high 0 + } + + +Create node: Promotion_Bonus_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.1.3) +-> father_name = [Recharge_Promotion_COS15] +-> -> Start_Date_COS15(0) +-> -> End_Date_COS15(1) +-> -> Promotion_Bonus_COS15(2) + + +Register leaf node: Promotion_Bonus_COS15. +Instance: 4 +Length : 9 +Flag : 255 +Default : +Remark : Promotion bonus is the extra credit that a subscriber will get when he recharges his account +in the promotion period. The amount of the bonus is determined by the recharge card credit. +Operator may set the bonus for four types of recharge card of each COS. Generally the recharge +card with higher credit is awarded more bonus. +Please note that the promotion bonus is only applicable for paying call charging. It can't be +used to pay the rental fee. (e.g. monthly rental). In addition, the bonus will always be +deducted prior to the recharge card credit. +Promotion bonus validity is the period of time that the bonus is valid. Bonus over the +validity period will be obsolete and deleted from account balance. That means the subscriber +must consume his entire promotion bonus within the time frame set by the operator. The operator +has the total freedom to design the validity period - shorter, same or longer than the validity +period of the recharge credit. + +Field : total(3) +Access : read-write[1]Recharge card credit + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } +[2]Promotion bonus + { + [u]4.0-7.7 + [u]input + [v]toDec high 0 + } +[3]Bonus validity + { + [u]8.0-8.7 + [u]input + [v]toDec high 0 + } + + +Create node: Tariff_Resolution_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) + + +Remark: Tariff Resolution. + + +Create node: MO_Tariff_ID_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.1) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) + + +Register leaf node: MO_Tariff_ID_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk +to PPS memory after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(1) +Access : read-write [1]New tariff flag + { + [u]0.0-0.7 + [u]select + [v]1[opt]Set + } + + +Create node: MT_Tariff_ID_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.2) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) + + +Register leaf node: MT_Tariff_ID_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Select a MT tariff for this COS. The COS ID is included in subscriber profile +for MT call charge. Total 16 MT tariffs available. + +Field : total(1) +Access : read-write [1]MT tariff ID + { + [u]0.0-0.7 + [u]select + [v]0[opt]00 + [v]1[opt]01 + [v]2[opt]02 + [v]3[opt]03 + [v]4[opt]04 + [v]5[opt]05 + [v]6[opt]06 + [v]7[opt]07 + [v]8[opt]08 + [v]9[opt]09 + [v]10[opt]10 + [v]11[opt]11 + [v]12[opt]12 + [v]13[opt]13 + [v]14[opt]14 + [v]15[opt]15 + } + + +Create node: Tariff_Subscription_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.3) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) +-> -> Tariff_Subscription_COS15(2) + + +Register leaf node: Tariff_Subscription_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS basic tariff may be applied on either area (parameter Basic tariff zone) +or subscriber (Tariff ID in subscriber profile) basis. This parameter defines +which one is preference when debiting a subscriber. + +Field : total(1) +Access : read-write [1]Charge by + { + [u]0.0-0.7 + [u]select + [v]0[opt]Tariff set in subscriber profile + [v]1[opt]Parameter 'Basic tariff zone' + } + + +Create node: Recharge_Card_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.2.4) +-> father_name = [Tariff_Resolution_COS15] +-> -> MO_Tariff_ID_COS15(0) +-> -> MT_Tariff_ID_COS15(1) +-> -> Tariff_Subscription_COS15(2) +-> -> Recharge_Card_Validity_COS15(3) + + +Register leaf node: Recharge_Card_Validity_COS15. +Instance: 4 +Length : 6 +Flag : 255 +Default : +Remark : Read only. This flag is used to upload the new tariff stored in PPS harddisk to PPS memory +after submitting the new tariff to the PPS harddisk +consequently enable the new tariff startup. + +Field : total(3) +Access : read-write[1]Face value + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } +[2]MO validity + { + [u]2.0-3.7 + [u]input + [v]toDec high 0 + } +[3]MT validity + { + [u]4.0-5.7 + [u]input + [v]toDec high 0 + } + + +Create node: Account_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) + + +Remark: Account control . + + +Create node: Min_balance_MO_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.1) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) + + +Register leaf node: Min_balance_MO_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : +Remark : Set a minimum balance for MO call. The subscriber whose balance is below this +threshold can't make MO call. The unit of the minimum balance is the smallest +unit of currency. + +Field : total(2) +Access : read-write [1]Set threshold for MO call + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not set + [v]1[opt]Set + } +[2]Minimum balance for MO call + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Maximum_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.2) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) +-> -> Maximum_Validity_COS15(1) + + +Register leaf node: Maximum_Validity_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Specify the legal maximum balance, unit is the minimum currency unit. This +value is for overflow prevention. Normally operator doesn't need to change +this value. e.g. 5000, and the smallest unit is cent then the maximum allowed +balance is 5000 cents. + +Field : total(1) +Access : read-write[1]Maximum account balance + { + [u]0.0-3.7 + [u]input + [v]toDec high 0 + } + + +Create node: Release_Day_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.3.3) +-> father_name = [Account_Control_COS15] +-> -> Min_balance_MO_COS15(0) +-> -> Maximum_Validity_COS15(1) +-> -> Release_Day_COS15(2) + + +Register leaf node: Release_Day_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : Ú +Remark : Number of days to hold an expiried prepaid account. After these release days, +if the expired prepaid user does't recharge his account, his account will be released. After +released, the MSISDN of the released account can be reuse by other subscribers. Dedault=30. + +Field : total(1) +Access : read-write[1]Release day + { + [u]0.0-1.7 + [u]input + [v]toDec high 0 + } + + +Create node: MT_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) + + +Remark: MT control . + + +Create node: Charge_Flag_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4.1) +-> father_name = [MT_Control_COS15] +-> -> Charge_Flag_COS15(0) + + +Register leaf node: Charge_Flag_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable MT call charge for prepaid subscriber. + +Field : total(1) +Access : read-write [1]MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not charged + [v]1[opt]Charged + } + + +Create node: Zero_Balance_Control_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.4.2) +-> father_name = [MT_Control_COS15] +-> -> Charge_Flag_COS15(0) +-> -> Zero_Balance_Control_COS15(1) + + +Register leaf node: Zero_Balance_Control_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Enable or disable (MT) incoming calls when balance reaches zero. + +Field : total(1) +Access : read-write [1]Zero balance MT call + { + [u]0.0-0.7 + [u]select + [v]0[opt]Not allowed + [v]1[opt]Allowed + } + + +Create node: Validity_Solution_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) +-> -> Validity_Solution_COS15(4) + + +Remark: Validity solution . + + +Create node: Clear_Balance_Option_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.1) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) + + +Register leaf node: Clear_Balance_Option_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set if clear off balance when an account expires or released. +If the balance is cleared] the balance will not be reused anyway. + +Field : total(3) +Access : read-write [1]When account expires + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + [2]When account is released + { + [u]0.0-0.0 + [u]select + [v]0[opt]Not clear balance + [v]1[opt]Clear balance + } + + +Create node: Validity_Recharge_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.2) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) + + +Register leaf node: Validity_Recharge_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set account validity increasement mode after a successful recharge. Accumulate: +the validity of the recharged money will be accumulated to the recharged account. +Replace: if the validity of the recharged money is more than the current account +validity, the account validity will be replaced by the validity of recharged money, +if the validity of the recharged money is less than the current account validity] the +account validity will not be changed after a successful recharge. + +Field : total(1) +Access : read-write [1]Validity after recharge + { + [u]0.0-0.7 + [u]select + [v]0[opt]Accumulate + [v]1[opt]Replace + } + + +Create node: Validity_Zero_Balance_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.3) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) + + +Register leaf node: Validity_Zero_Balance_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Enable or disable account validity ajustment when balance reaches zero,and if enabled, preset the +validity ajustment days. Disable=not change validity when balance reaches zero. Enable=change validity +to a preset period (see below) when balance reaches zero. Days: preset a validity ajustment period for +a zero balance account. If a zero balance account's current validity is less than the preset adjustment +validity] the system will keep this account's current validity. e.g. If this function is enabled] +and validity ajustment is set as 30 days] when a subscriber with 40 days' validity reaches zero balance] +his validity will be changed to 30 days. He will can receive incoming call for 30 days given the parameter +Zero balance MT call is enabled. Defaut=not change] validity adjustment disable. + +Field : total(2) +Access : read-write [1]Validity on zero balance + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not change + [v]1[opt]Change + } +[2]Days + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: Activated_Account_Validity_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.4) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) + + +Register leaf node: Activated_Account_Validity_COS15. +Instance: 1 +Length : 3 +Flag : 255 +Default : +Remark : Set validity for an account who is activated from fresh status by dialing inquiry +number. The unit is day. Defaul=30 days. + +Field : total(2) +Access : read-write [1]Activation by inquiring + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Validity of activated account with zero balance + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: FF_Number_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.5) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) + + +Register leaf node: FF_Number_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : õ +Remark : Enable or disable charge for changing family number. Free times of changing: set total times +of free change for family number if charge is enabled. Maximum is 15 + +Field : total(5) +Access : read-write [1]CUG serivce flag + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]F & F service flag + { + [u]0.6-0.6 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [3]Edition F & F list charge flag + { + [u]0.5-0.5 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[5]Free times of changing + { + [u]0.0-0.3 + [u]input + [v]toDec high 0 + } + + +Create node: Support_Credit_Card_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.6) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) +-> -> Support_Credit_Card_COS15(5) + + +Register leaf node: Support_Credit_Card_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Support_Credit_Card_COS + +Field : total(1) +Access : read-write [1]Support credit card flag + { + [u]0.0-0.7 + [u]select + [v]0[opt]Support + [v]1[opt]Not support + } + + +Create node: Credit_Vault_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.5.7) +-> father_name = [Validity_Solution_COS15] +-> -> Clear_Balance_Option_COS15(0) +-> -> Validity_Recharge_COS15(1) +-> -> Validity_Zero_Balance_COS15(2) +-> -> Activated_Account_Validity_COS15(3) +-> -> FF_Number_COS15(4) +-> -> Support_Credit_Card_COS15(5) +-> -> Credit_Vault_COS15(6) + + +Register leaf node: Credit_Vault_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : d +Remark : When a subscriber is rejected to make a call because of the insufficient balance, he may select +to set the credit vault to get a preset amount of overdraft to make call. The amount of the overdraft +(credit vault) is set by network operator. The system will deduct this overdraft by debiting his account balance at the next recharge. + +Field : total(2) +Access : read-write [1]Support credit vault + { + [u]1.7-1.7 + [u]select + [v]0[opt]Not support + [v]1[opt]Support + } +[2]Credit vault + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Inquiry_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6) +-> father_name = [COS_15] +-> -> Recharge_Promotion_COS15(0) +-> -> Tariff_Resolution_COS15(1) +-> -> Account_Control_COS15(2) +-> -> MT_Control_COS15(3) +-> -> Validity_Solution_COS15(4) +-> -> SM_Inquiry_COS15(5) + + +Remark: SM inquiry notification . + + +Create node: Feedback_SM_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.1) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) + + +Register leaf node: Feedback_SM_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default :  +Remark : Set if send feedback short message for balance inquiry or recharge operation. + +Field : total(3) +Access : read-write [1]Send SM for recharge result + { + [u]0.0-0.0 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + [2]Send SM for inquiry result + { + [u]0.1-0.1 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } + + +Create node: Inquiry_SM_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.2) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) + + +Register leaf node: Inquiry_SM_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : ƒ +Remark : Enable or disable charge on inquiry short message. Subscriber may inquire his account by sending a SM (may be vacant) +to the inquiry service number. Free SMs for every day: set quantity of free inquiry short message on a daily basis if +charge is enabled. Maximum is 128. + +Field : total(2) +Access : read-write [1]Charge on inquiry SM + { + [u]0.7-0.7 + [u]select + [v]0[opt]Not charge + [v]1[opt]Charge + } +[2]Free SM every day + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Expiry_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.3) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) +-> -> SM_Expiry_COS15(2) + + +Register leaf node: SM_Expiry_COS15. +Instance: 1 +Length : 1 +Flag : 255 +Default : Š +Remark : Enable or disable sending notification short message when an account is going to expire. If the Days +is set as 5, the PPS will send the notification SM to a subscriber whose account validity will expire +in five days. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]0.7-0.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Days prior to expiry date + { + [u]0.0-0.6 + [u]input + [v]toDec high 0 + } + + +Create node: SM_Low_Balance_COS15(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.4.16.6.4) +-> father_name = [SM_Inquiry_COS15] +-> -> Feedback_SM_COS15(0) +-> -> Inquiry_SM_COS15(1) +-> -> SM_Expiry_COS15(2) +-> -> SM_Low_Balance_COS15(3) + + +Register leaf node: SM_Low_Balance_COS15. +Instance: 1 +Length : 2 +Flag : 255 +Default : �ô +Remark : Enable or disable sending notification short message when an account's balance is too low. +Balance level to send SM: set a low balance for short message notification. PPS will send +a notification short message to an subscriber whose balance is no more than the preset low +balance value. e.g. if set bit0-14 as 100, when a subscriber'sbalance becomes less than 100, +the PPS will send the notification SM to this subscriber indicating low balance. + +Field : total(2) +Access : read-write [1]Send SM notification + { + [u]1.7-1.7 + [u]select + [v]0[opt]Disable + [v]1[opt]Enable + } +[2]Balance level to send SM + { + [u]0.0-1.6 + [u]input + [v]toDec high 0 + } + + +Create node: Call_Routing_VMS(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) +-> -> Call_Routing_VMS(4) + + +Remark: Call routing to VMS . + + +Create node: VMS_PLMN_Maintenance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.1) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) + + +Register leaf node: VMS_PLMN_Maintenance. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS service number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: VMS_PSTN_Maintenance(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.2) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) + + +Register leaf node: VMS_PSTN_Maintenance. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS service number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: VMS_leave_msg_No(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.3) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) + + +Register leaf node: VMS_leave_msg_No. +Instance: 1 +Length : 16 +Flag : 255 +Default : +Remark : Voice mail service center number. It is used by the PPS to route the VMS calls to the VMS. + +Field : total(1) +Access : read-only[1]VMS deposit number + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Rule(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.4) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) +-> -> Rule(3) + + +Register leaf node: Rule. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : rule + +Field : total(3) +Access : read-only [1]Route by + { + [u]0.0-0.0 + [u]select + [v]0[opt]Prefix + [v]1[opt]Whole number + } + [2]Route + { + [u]0.1-0.1 + [u]select + [v]0[opt]Caller number + [v]1[opt]Called number + } + + +Create node: VMS_User_Segments(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.5.5) +-> father_name = [Call_Routing_VMS] +-> -> VMS_PLMN_Maintenance(0) +-> -> VMS_PSTN_Maintenance(1) +-> -> VMS_leave_msg_No(2) +-> -> Rule(3) +-> -> VMS_User_Segments(4) + + +Register leaf node: VMS_User_Segments. +Instance: 128 +Length : 80 +Flag : 255 +Default : 86755900000 +Remark : VMS user segments + +Field : total(5) +Access : read-only[1]Start MSISDN + { + [u]0.0-15.7 + [u]input + [v]ToAscii Low 0 + } +[2]End MSISDN + { + [u]16.0-31.7 + [u]input + [v]ToAscii Low 0 + } +[3]VMS service number - PLMN + { + [u]32.0-47.7 + [u]input + [v]ToAscii Low 0 + } +[4]VMS service number - PSTN + { + [u]48.0-63.7 + [u]input + [v]ToAscii Low 0 + } +[5]Leave message deposit number + { + [u]64.0-79.7 + [u]input + [v]ToAscii Low 0 + } + + +Create node: Status(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6) +-> father_name = [Configuration] +-> -> Service_Control(0) +-> -> SRF_Param(1) +-> -> File_Operation(2) +-> -> COS_Param(3) +-> -> Call_Routing_VMS(4) +-> -> Status(5) + + +Remark: Status. + + +Create node: Activation(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.1) +-> father_name = [Status] +-> -> Activation(0) + + +Register leaf node: Activation. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Set PPS system status. 0=normal. After initial PPS installation, if the PPS system doesn't has subscriber profiles, its status is suspended. In this case operator may set this parameter (normal) to activate the PPS server. + +Field : total(1) +Access : read-only [1]System status + { + [u]0.0-0.7 + [u]select + [v]0[opt]Normal + } + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.2) +-> father_name = [Status] +-> -> Activation(0) +-> -> Command(1) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : PPS management command. +Save parameters: Save PPS parameters in PPS memory to PPS hard disk. +Save user data: Save PPS subscriber data in PPS memory to PPS hard disk. + +Field : total(1) +Access : read-write [1]Command + { + [u]0.0-0.7 + [u]select + [v]1[opt]Save parameters + [v]2[opt]Save user data + } + + +Create node: MSS(OID: 1.3.6.1.4.1.1373.1.3.3.16) +-> father_name = [App] +-> -> MSC(0) +-> -> HLR(1) +-> -> AUC(2) +-> -> SMSC(3) +-> -> PPS(4) +-> -> MSS(5) + + +Remark: Subsystems for MSS . + + +Create node: Configuration(OID: 1.3.6.1.4.1.1373.1.3.3.16.2) +-> father_name = [MSS] +-> -> Configuration(0) + + +Remark: Configuration for MSS . + + +Create node: Management(OID: 1.3.6.1.4.1.1373.1.3.3.16.2.1) +-> father_name = [Configuration] +-> -> Management(0) + + +Remark: Management for MSS . + + +Create node: Command(OID: 1.3.6.1.4.1.1373.1.3.3.16.2.1.1) +-> father_name = [Management] +-> -> Command(0) + + +Register leaf node: Command. +Instance: 1 +Length : 1 +Flag : 255 +Default : +Remark : Safely shut down MSS server by stoping MSS process, saving subscriber data to harddisk and shut down the server. +Operation procedures: +1. Select -Shutdown- at above pulldown menu. +2. Click -Set- button in this set window. +3. Click -SET- button on operation page. + +Field : total(1) +Access : write-only [1]Command + { + [u]0.0-0.7 + [u]select + [v]4[opt]Shutdown + [v]5[opt]Undefine value + } + + + + + +SubSystem Module +Index:0 OID: 1.3.6.1.4.1.1373.1.3.2.2.2. name:MTP3 MaxGroup:3 +Index:1 OID: 1.3.6.1.4.1.1373.1.3.2.2.3. name:SCCP MaxGroup:1 +Index:2 OID: 1.3.6.1.4.1.1373.1.3.2.2.5. name:XAPP MaxGroup:1 +Index:3 OID: 1.3.6.1.4.1.1373.1.3.2.3.4. name:SMPP MaxGroup:0 +Index:4 OID: 1.3.6.1.4.1.1373.1.3.3.2.2. name:CCF(MSC) MaxGroup:0 +Index:5 OID: 1.3.6.1.4.1.1373.1.3.3.2.5. name:VLR MaxGroup:1 +Index:6 OID: 1.3.6.1.4.1.1373.1.3.3.3. name:HLR MaxGroup:1 +Index:7 OID: 1.3.6.1.4.1.1373.1.3.3.4. name:AUC MaxGroup:1 +Index:8 OID: 1.3.6.1.4.1.1373.1.3.3.5. name:SMSC MaxGroup:1 +Index:9 OID: 1.3.6.1.4.1.1373.1.3.3.6. name:PPS MaxGroup:1 + + + + + + +Host IP +Index:0 Group index:0 Membre index:0 Host name:MTP3_0_0 mss-0 Host ip:172.54.240.80. +Index:1 Group index:1 Membre index:0 Host name:MTP3_1_0 mss-1 Host ip:172.18.133.1. +Index:2 Group index:2 Membre index:0 Host name:MTP3_2_0 -- Host ip:172.18.123.1. +Index:3 Group index:3 Membre index:0 Host name:MTP3_3_0 -- Host ip:172.18.143.1. +Index:4 Group index:0 Membre index:0 Host name:SCCP_0_0 mss-0 Host ip:172.54.240.80. +Index:5 Group index:1 Membre index:0 Host name:SCCP_1_0 mss-1 Host ip:172.18.133.1. +Index:6 Group index:0 Membre index:0 Host name:XAPP_0_0 MSS-0 Host ip:172.54.240.80. +Index:7 Group index:1 Membre index:0 Host name:XAPP_1_0 MSS-1 Host ip:172.18.133.1. +Index:8 Group index:0 Membre index:0 Host name:SMPP_0_0 SMPP-0 Host ip:172.54.240.80. +Index:9 Group index:0 Membre index:0 Host name:MSC_0_0 -- Host ip:172.54.240.80. +Index:10 Group index:1 Membre index:0 Host name:MSC_1_0 -- Host ip:172.18.133.1. +Index:11 Group index:0 Membre index:0 Host name:CCF(MSC)_0_0 -- Host ip:172.54.240.80. +Index:12 Group index:0 Membre index:1 Host name:CCF(MSC)_0_1 -- Host ip:172.18.133.1. +Index:13 Group index:0 Membre index:0 Host name:VLR_0_0 VLR-0 Host ip:172.54.240.80. +Index:14 Group index:1 Membre index:0 Host name:VLR_1_0 VLR-1 Host ip:172.18.0.1. +Index:15 Group index:0 Membre index:0 Host name:HLR_0_0 -- Host ip:172.54.240.80. +Index:16 Group index:1 Membre index:0 Host name:HLR_1_0 -- Host ip:172.18.234.230. +Index:17 Group index:0 Membre index:0 Host name:AUC_0_0 -- Host ip:172.54.240.80. +Index:18 Group index:1 Membre index:0 Host name:AUC_1_0 -- Host ip:172.18.234.230. +Index:19 Group index:0 Membre index:0 Host name:SMSC_0_0 -- Host ip:172.54.240.80. +Index:20 Group index:1 Membre index:0 Host name:SMSC_1_0 -- Host ip:172.18.234.230. +Index:21 Group index:0 Membre index:0 Host name:PPS_0_0 -- Host ip:172.54.240.80. +Index:22 Group index:1 Membre index:0 Host name:PPS_1_0 -- Host ip:172.18.234.230. + + + + + + +Module Save flag +Module Index:0 OID: 1.3.6.1.4.1.1373.1.3.2.2.2.3.7. oid len:14 select id:3 field id:1 +Module Index:1 OID: 1.3.6.1.4.1.1373.1.3.2.2.3.3.2. oid len:14 select id:2 field id:1 +Module Index:2 OID: 1.3.6.1.4.1.1373.1.3.2.2.5.3.2. oid len:14 select id:1 field id:1 +Module Index:3 OID: 1.3.6.1.4.1.1373.1.3.2.3.4.3.2. oid len:14 select id:1 field id:1 +Module Index:4 OID: 1.3.6.1.4.1.1373.1.3.3.2.2.3.2. oid len:14 select id:3 field id:1 +Module Index:5 OID: 1.3.6.1.4.1.1373.1.3.3.2.5.3.3. oid len:14 select id:2 field id:1 +Module Index:6 OID: 1.3.6.1.4.1.1373.1.3.3.3.2.2.2. oid len:14 select id:2 field id:1 +Module Index:7 OID: 1.3.6.1.4.1.1373.1.3.3.4.2.2.2. oid len:14 select id:2 field id:1 +Module Index:8 OID: 1.3.6.1.4.1.1373.1.3.3.5.3.3. oid len:13 select id:1 field id:1 +Module Index:9 OID: 1.3.6.1.4.1.1373.1.3.3.6.2.1.6.2. oid len:15 select id:1 field id:1 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 +Module Index:0 OID: oid len:0 select id:0 field id:0 + + + diff --git a/plat/smpp/ut/conf/guess_number_test.conf b/plat/smpp/ut/conf/guess_number_test.conf new file mode 100644 index 0000000..5e34f22 --- /dev/null +++ b/plat/smpp/ut/conf/guess_number_test.conf @@ -0,0 +1 @@ +594694911035 diff --git a/plat/smpp/ut/conf/help_page b/plat/smpp/ut/conf/help_page new file mode 100644 index 0000000..9be9280 --- /dev/null +++ b/plat/smpp/ut/conf/help_page @@ -0,0 +1,16 @@ + + ****************** + * HELP PAGE * + ****************** + + Welcome to DEBUG MONITOR. + + Press 's' or 'S' to enter "SUB MODULE SELECTION PAGE". + + In "SUB MODULE SELECTION PAGE", + Press 'x' or 'X' to return "HELP PAGE", + Press 'a-p' or 'A-P' to select sub module. + + In each sub module, + Press '0-9' and 'a-f' to select pages. +$ diff --git a/plat/smpp/ut/conf/iptrans.conf b/plat/smpp/ut/conf/iptrans.conf new file mode 100644 index 0000000..bc731b5 --- /dev/null +++ b/plat/smpp/ut/conf/iptrans.conf @@ -0,0 +1,25 @@ +#ipconfig for pps +4950=UDP,6,DIRECT +4951=UDP,0,BUFFER +4952=UDP,0,BUFFER +4953=UDP,0,BUFFER +4954=UDP,0,BUFFER +4955=UDP,3,BUFFER +4956=UDP,0,BUFFER +4957=UDP,4,BUFFER +4958=UDP,0,BUFFER +4959=UDP,0,BUFFER +4960=UDP,0,BUFFER +4961=UDP,0,BUFFER +4962=UDP,0,BUFFER +4963=UDP,0,BUFFER +4964=UDP,0,BUFFER +4965=TCP,6,BUFFER +4966=UDP,2,DIRECT +4967=UDP,0,BUFFER +4968=UDP,0,BUFFER +4969=UDP,0,BUFFER +4970=UDP,0,BUFFER +4971=UDP,0,BUFFER +4972=UDP,0,BUFFER +4973=UDP,0,BUFFER diff --git a/plat/smpp/ut/conf/menu_page b/plat/smpp/ut/conf/menu_page new file mode 100644 index 0000000..2202726 --- /dev/null +++ b/plat/smpp/ut/conf/menu_page @@ -0,0 +1,22 @@ + + ********************************* + * SUB MODULE SELECTION PAGE * + ********************************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- SCF + d -- TCAP l -- SNMP + e -- XAP-P m -- DATA SYNC + f -- CCF n -- DEBUG + g -- VLR o -- reserved + h -- SSF p -- SMPP + + + + + + + + + diff --git a/plat/smpp/ut/conf/mtp3.conf b/plat/smpp/ut/conf/mtp3.conf new file mode 100644 index 0000000..b234624 --- /dev/null +++ b/plat/smpp/ut/conf/mtp3.conf @@ -0,0 +1,1408 @@ +#MTP3 CONFIGURE FILE + +[SERVICE NETWORK SP LEN] +[04] + +[LOCAL SP] +[000000] [000000] [001fd3] [002ee0] +[000000] [000000] [888888] [000202] + +[LINK ATTRIBUTE] +[00.00.00] [03.00.62] [08.00.62] [05.00.62] +[7e.00.62] [14.00.62] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [15.00.62] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [0a.00.62] +[01.00.62] [00.00.00] [07.00.62] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [0b.00.62] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [03.01.63] [08.01.63] [05.01.63] +[7f.00.63] [14.01.63] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [15.01.63] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [0a.01.63] +[00.00.00] [00.00.00] [07.01.63] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [0b.01.63] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] +[00.00.00] [00.00.00] [00.00.00] [00.00.00] + +[LINKSET ATTRIBUTE] +[000000.00] [000b03.02] [000000.00] [002eea.02] +[000000.00] [002eeb.02] [000000.00] [001fe7.02] +[001fe8.02] [000000.00] [0032d2.02] [0032d3.02] +[000000.00] [000000.00] [0032dc.03] [0032dd.03] +[000000.00] [000000.00] [000000.00] [000000.00] +[000003.02] [000004.02] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [00007e.0b] [00007f.0b] + +[NATIONAL NETWORK SP] +[0032d2.0a.7e] [000b03.01.7f] [002081.01.7f] [000000.80.80] +[000003.14.7e] [000004.15.7e] [000000.80.80] [002eea.03.7e] +[000000.80.80] [000000.80.80] [001fe7.07.7e] [001fe8.08.7e] +[000000.80.80] [000000.80.80] [0032d3.0b.7e] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[00001c.1c.80] [00001d.1d.80] [000000.80.80] [00001f.1f.80] +[002eeb.05.7e] [000000.80.80] [00003c.22.00] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[NATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [00007e.7e.7f] +[00007f.7f.7e] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[LOCAL ACN] +030303030202020202030302020202020202020203030303030303030303030302020202 + +[INTERNATIONAL NETWORK ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[INTERNATIONAL NETWORK SPARE ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[NATIONAL NETWORK ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + +[NATIONAL NETWORK SPARE ACN] +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 +020202020202020202020202020202020202020202020202020202020202020202020202 + diff --git a/plat/smpp/ut/conf/sccp.conf b/plat/smpp/ut/conf/sccp.conf new file mode 100644 index 0000000..62fbd41 --- /dev/null +++ b/plat/smpp/ut/conf/sccp.conf @@ -0,0 +1,22 @@ +#SCCP Config file (R3_V1_T07) +#copy this file to /etc/sccp.conf to set global options +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 2 236060011 172.18.128.1 172.18.129.1 +10 2 2360620103 172.18.98.1 172.18.99.1 +21 2 2360620104 172.18.166.1 172.18.167.1 +62 2 100 172.18.145.1 172.18.128.1 + +[GTT_Table] +#No NP StartDigits EndDigits NetID SPC SSN RI S E N ReplaceDigits +0 1 236060000 236069999 2 002808 6 1 +1 1 236090000 236099999 2 002808 6 1 +2 6 623045200000000 623045299999999 2 002808 6 1 +3 1 236060013 236060013 3 222222 22 1 +4 1 236060014 236060014 3 232323 22 1 +5 1 100 299 2 888888 62 0 + +[RL_SSN] +#Subsystems needed to be detected frequently +#NetID DPC SSN + diff --git a/plat/smpp/ut/conf/smpp.conf b/plat/smpp/ut/conf/smpp.conf new file mode 100644 index 0000000..617cbd8 --- /dev/null +++ b/plat/smpp/ut/conf/smpp.conf @@ -0,0 +1,35 @@ +#SMPP Config file (R10V0_13) +#Copy this file to ./conf/smpp.conf to set global options +#No lkEn lkType serverType sessionType sysID pwd sysType LGTT RGTT LIP RIP sessionTimer enqTimer inactTimer rspTimer ServiceNum +0 1 1 0 2 Test1 123456 -- -- -- 172.18.128.1 172.18.98.1 5 10 5 5 86755001 +1 1 1 1 2 Test2 123456 -- -- -- 172.18.128.1 172.18.98.1 5 10 5 5 86755002 +2 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +3 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +4 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +5 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +6 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +7 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +8 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +9 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +10 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +11 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +12 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +13 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +14 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +15 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +16 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +17 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +18 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +19 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +20 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +21 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +22 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +23 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +24 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +25 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +26 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +27 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +28 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +29 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +30 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- +31 0 0 0 0 Test 123456 GSM -- -- 0.0.0.0 0.0.0.0 5 10 5 5 -- diff --git a/plat/smpp/ut/smpp_test/smpp_test.c b/plat/smpp/ut/smpp_test/smpp_test.c new file mode 100644 index 0000000..82d2f65 --- /dev/null +++ b/plat/smpp/ut/smpp_test/smpp_test.c @@ -0,0 +1,688 @@ +/* +** CDMA 2000 project, SMPP module +** +** File name: smpp_test.c +** Written by Li Long at 2004-11-25 +** CVS $Id: smpp_test.c,v0.1 2004/11/25 17:03:14 lilong Exp $ +** +*/ + +#include "./include/smpp.h" + +#define SD_PKT_NUM 10 +#define STORE_MSG_ITEM 5 + +typedef struct SMPP_MSG_STORE_STRUCT +{ + BYTE short_message[SMPP_MSG_LEN]; + BYTE message_id[65]; +} SMPP_MSG_STORE_STRUCT; + +typedef struct SMPP_LINK_ATTRIBUTE +{ + BYTE enable; + BYTE session_type; //BIND_TX/BIND_RX/BIND_TRX + BYTE message_mode; //STORE AND FORWARD/DATAGRAM/TRANSACTION + BYTE terminal_type; //SMPP_CLIENT/SMPP_SERVER +} SMPP_LINK_ATTRIBUTE; +static struct itimerval itimer,old_itimer; +static int timer_counter[MAX_SMPP_LINK]; +static int stateFlag[MAX_SMPP_LINK]; +static int msg_count[MAX_SMPP_LINK]; +static int msg_pointer[MAX_SMPP_LINK]; +static SMPP_MSG_STORE_STRUCT store_msg_buf[MAX_SMPP_LINK][STORE_MSG_ITEM]; +static SMPP_LINK_ATTRIBUTE smpp_link_attr[MAX_SMPP_LINK]; + +static void On_Timer(); +static void SetTimer(); +static void smpp_test_init(); +static void sendTestSM(int, int); +static int smpp_onDataRecv(BYTE linkNo, SMPP_MSG *pData, WORD dataLen); +static int smpp_onLinkStateChange(BYTE linkNo, BYTE linkstate); + +void smpp_test_init() +{ + int i; + + for (i=0; imessage_type) + { + case 0x0B: /* SUBMIT SM */ + printf("[TEST PROGRAM]Link %d received SUBMIT SM:\n", linkNo); + + /* store smpp message */ + if (smpp_link_attr[linkNo].message_mode == STORE_AND_FORWARD) + { + //if (pMsg->pdu.submit_sm.sm_length < SMPP_MSG_LEN) + { + pointer = (msg_pointer[linkNo]+1)%STORE_MSG_ITEM; + memcpy(&store_msg_buf[linkNo][pointer].short_message, + pMsg->pdu.submit_sm.short_message, pMsg->pdu.submit_sm.sm_length); + sprintf(store_msg_buf[linkNo][pointer].message_id, + "%ld", pMsg->pdu.submit_sm.head.sequence_number); + } + } + + /* fill with SUBMIT SM RESP structure. */ + smpp_msg.message_type = 0x0C; + smpp_msg.pdu.submit_sm_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.submit_sm_resp.head.sequence_number = pMsg->pdu.submit_sm.head.sequence_number; + sprintf(smpp_msg.pdu.submit_sm_resp.message_id, "%ld", + smpp_msg.pdu.submit_sm_resp.head.sequence_number); + smpp_send(linkNo, &smpp_msg, dataLen); + break; + case 0x0C: /* SUBMIT SM RESP */ + printf("[TEST PROGRAM]Link %d received SUBMIT SM RESP.\n", linkNo); + break; + case 0x0D: /* SUBMIT MULTI */ + printf("[TEST PROGRAM]Link %d received SUBMIT MULTI.\n", linkNo); + /* store smpp message */ + if (smpp_link_attr[linkNo].message_mode == STORE_AND_FORWARD) + { + //if (pMsg->pdu.submit_multi.sm_length < SMPP_MSG_LEN) + { + pointer = (msg_pointer[linkNo]+1)%STORE_MSG_ITEM; + memcpy(&store_msg_buf[linkNo][pointer].short_message, + pMsg->pdu.submit_sm.short_message, pMsg->pdu.submit_multi.sm_length); + sprintf(store_msg_buf[linkNo][pointer].message_id, + "%ld", pMsg->pdu.submit_multi.head.sequence_number); + } + } + + /* fill with SUBMIT MULTI RESP structure. */ + smpp_msg.message_type = 0x0E; + smpp_msg.pdu.submit_multi_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.submit_multi_resp.head.sequence_number = pMsg->pdu.submit_multi.head.sequence_number; + sprintf(smpp_msg.pdu.submit_multi_resp.message_id, "%ld", + smpp_msg.pdu.submit_multi_resp.head.sequence_number); + smpp_msg.pdu.submit_multi_resp.no_unsuccess = 0; + smpp_send(linkNo, &smpp_msg, dataLen); + break; + case 0x0E: /* SUBMIT MULTI RESP */ + printf("[TEST PROGRAM]Link %d received SUBMIT MULTI RESP.\n", linkNo); + break; + case 0x0F: /* DELIVER SM */ + printf("[TEST PROGRAM]Link %d received DELIVER SM.\n", linkNo); + + /* store smpp message */ + if (smpp_link_attr[linkNo].message_mode == STORE_AND_FORWARD) + { + //if (pMsg->pdu.deliver_sm.sm_length < SMPP_MSG_LEN) + { + pointer = (msg_pointer[linkNo]+1)%STORE_MSG_ITEM; + memcpy(&store_msg_buf[linkNo][pointer].short_message, + pMsg->pdu.deliver_sm.short_message, pMsg->pdu.deliver_sm.sm_length); + sprintf(store_msg_buf[linkNo][pointer].message_id, + "%ld", pMsg->pdu.deliver_sm.head.sequence_number); + } + } + + /* fill with DELIVER SM RESP structure. */ + smpp_msg.message_type = 0x10; + smpp_msg.pdu.deliver_sm_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.deliver_sm_resp.head.sequence_number = pMsg->pdu.deliver_sm.head.sequence_number; + smpp_msg.pdu.deliver_sm_resp.message_id = 0x0; + smpp_send(linkNo, &smpp_msg, dataLen); + break; + case 0x10: /* DELIVER SM RESP */ + printf("[TEST PROGRAM]Link %d received DELIVER SM RESP.\n", linkNo); + break; + case 0x11: /* DATA SM */ + printf("[TEST PROGRAM]Link %d received DATA SM.\n", linkNo); + + /* store smpp message */ + if (smpp_link_attr[linkNo].message_mode == STORE_AND_FORWARD) + { + if (strlen(pMsg->pdu.data_sm.message_payload) < SMPP_MSG_LEN) + { + pointer = (msg_pointer[linkNo]+1)%STORE_MSG_ITEM; + memcpy(&store_msg_buf[linkNo][pointer].short_message, + pMsg->pdu.data_sm.message_payload, strlen(pMsg->pdu.data_sm.message_payload)); + sprintf(store_msg_buf[linkNo][pointer].message_id, + "%ld", pMsg->pdu.data_sm.head.sequence_number); + } + } + + /* fill with DATA SM RESP structure. */ + smpp_msg.message_type = 0x12; + smpp_msg.pdu.data_sm_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.data_sm_resp.head.sequence_number = pMsg->pdu.data_sm.head.sequence_number; + sprintf(smpp_msg.pdu.data_sm_resp.message_id, "%ld", + smpp_msg.pdu.data_sm_resp.head.sequence_number); + smpp_send(linkNo, &smpp_msg, dataLen); + break; + case 0x12: /* DATA SM RESP */ + printf("[TEST PROGRAM]Link %d received DATA SM RESP.\n", linkNo); + break; + case 0x13: /* QUERY SM */ + printf("[TEST PROGRAM]Link %d received QUERY SM.\n", linkNo); + + pointer = -1; + for (i=0; ipdu.query_sm.message_id) == 0) + { + pointer = i; + break; + } + } + + /* fill with QUERY SM RESP structure */ + smpp_msg.message_type = 0x14; + smpp_msg.pdu.query_sm_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.query_sm_resp.head.sequence_number = pMsg->pdu.query_sm.head.sequence_number; + sprintf(smpp_msg.pdu.query_sm_resp.message_id, "%ld", + smpp_msg.pdu.query_sm_resp.head.sequence_number); + smpp_msg.pdu.query_sm_resp.final_date[0] = 0x0; + if (pointer == -1) + { + smpp_msg.pdu.query_sm_resp.message_state = 0x04; + } + else + { + smpp_msg.pdu.query_sm_resp.message_state = 0x02; + } + + smpp_msg.pdu.query_sm_resp.error_code = 0x0; + smpp_send(linkNo, &smpp_msg, dataLen); + break; + case 0x14: /* QUERY SM RESP */ + printf("[TEST PROGRAM]Link %d received QUERY SM RESP.\n", linkNo); + break; + case 0x15: /* CANCEL SM */ + printf("[TEST PROGRAM]Link %d received CANCEL SM RESP.\n", linkNo); + pointer = -1; + if (pMsg->pdu.cancel_sm.message_id[0] == 0){ + memset(store_msg_buf[linkNo], 0, sizeof(SMPP_MSG_STORE_STRUCT)*STORE_MSG_ITEM); + msg_pointer[linkNo] = 0; + smpp_msg.pdu.cancel_sm_resp.head.command_status = htonl(ESME_ROK); + }else{ + for (i=0; ipdu.cancel_sm.message_id, store_msg_buf[linkNo][i].message_id); + if (strcmp(store_msg_buf[linkNo][i].message_id, pMsg->pdu.cancel_sm.message_id) == 0) + { + pointer = i; + break; + } + } + if (pointer == -1) + { + smpp_msg.pdu.cancel_sm_resp.head.command_status = htonl(ESME_RCANCELFAIL); + }else{ + smpp_msg.pdu.cancel_sm_resp.head.command_status = htonl(ESME_ROK); + } + } + + /* fill with CANCEL SM RESP structure */ + smpp_msg.message_type = 0x16; + smpp_msg.pdu.cancel_sm_resp.head.sequence_number = pMsg->pdu.cancel_sm.head.sequence_number; + smpp_send(linkNo, &smpp_msg, dataLen); + break; + case 0x16: /* CANCEL SM RESP */ + printf("[TEST PROGRAM]Link %d received CANCEL RESP.\n", linkNo); + break; + case 0x17: /* REPLACE SM */ + printf("[TEST PROGRAM]Link %d received REPLACE SM.\n", linkNo); + pointer = -1; + for (i=0; ipdu.replace_sm.message_id) == 0) + { + pointer = i; + break; + } + } + + /* store new smpp message */ + if (pointer != -1) + { + //if (pMsg->pdu.replace_sm.sm_length < SMPP_MSG_LEN) + { + memcpy(&store_msg_buf[linkNo][pointer].short_message, + pMsg->pdu.replace_sm.short_message, pMsg->pdu.replace_sm.sm_length); + } + } + + /* fill with REPLACE SM RESP structure */ + smpp_msg.message_type = 0x18; + if (pointer == -1) + { + smpp_msg.pdu.replace_sm_resp.head.command_status = htonl(ESME_RREPLACEFAIL); + } + else + { + smpp_msg.pdu.replace_sm_resp.head.command_status = htonl(ESME_ROK); + } + smpp_msg.pdu.replace_sm_resp.head.sequence_number = pMsg->pdu.replace_sm.head.sequence_number; + smpp_send(linkNo, &smpp_msg, dataLen); + break; + case 0x18: /* REPLACE SM RESP */ + printf("[TEST PROGRAM]Link %d received REPLACE SM RESP.\n", linkNo); + break; + default: + return 0; + } + + return sequence_number; +} + +int smpp_onLinkStateChange(BYTE linkNo, BYTE linkstate) +{ + printf("[TEST PROGRAM]link %d state change to %d\n",linkNo, linkstate); + if (linkstate == 1) + stateFlag[linkNo] = TRUE; + else + stateFlag[linkNo] = FALSE; + + return linkNo; +} + +//0-submit_sm, 1-deliver_sm, 2-data_sm +void sendTestSM(int linkNo, int msg_type) +{ + SMPP_MSG smpp_msg; + WORD dataLen; + + memset(&smpp_msg, 0, sizeof(SMPP_MSG)); + switch (msg_type) + { + case 0: //send submit sm + smpp_msg.message_type = 0x0B; + smpp_msg.optional_param_flag1 = 0x0FF67FFF; + smpp_msg.optional_param_flag2 = 0x0; + + //Mandatory parameters. + strcpy(smpp_msg.pdu.submit_sm.service_type, "USSD"); + smpp_msg.pdu.submit_sm.source_addr_ton = 0x2; //National + smpp_msg.pdu.submit_sm.source_addr_npi = 0x1; //ISDN + strcpy(smpp_msg.pdu.submit_sm.source_addr, "172.18.166.1"); + smpp_msg.pdu.submit_sm.dest_addr_ton = 0x2; //National + smpp_msg.pdu.submit_sm.dest_addr_npi = 0x1; //ISDN + strcpy(smpp_msg.pdu.submit_sm.destination_addr, "13923482085"); + smpp_msg.pdu.submit_sm.esm_class = 0x00; + smpp_msg.pdu.submit_sm.protocol_id = 0x0; + smpp_msg.pdu.submit_sm.priority_flag = 0x3; + strcpy(smpp_msg.pdu.submit_sm.schedule_delivery_time, "041231151200000R"); + strcpy(smpp_msg.pdu.submit_sm.validity_period, "041231151200000+"); + smpp_msg.pdu.submit_sm.registered_delivery = 0x11; + smpp_msg.pdu.submit_sm.replace_if_present_flag = 0x01; + smpp_msg.pdu.submit_sm.data_coding = 0x07; + smpp_msg.pdu.submit_sm.sm_default_msg_id = 0x01; + smpp_msg.pdu.submit_sm.sm_length = 0x0; + strcpy(smpp_msg.pdu.submit_sm.short_message, ""); + //Optional parameters. + smpp_msg.pdu.submit_sm.user_message_reference = 0x00; + smpp_msg.pdu.submit_sm.source_port = 0x6666; + smpp_msg.pdu.submit_sm.source_addr_subunit = 0x01; + smpp_msg.pdu.submit_sm.destination_port = 0x8888; + smpp_msg.pdu.submit_sm.dest_addr_subunit = 0x02; + smpp_msg.pdu.submit_sm.sar_msg_ref_num = 0x7700; + smpp_msg.pdu.submit_sm.sar_total_segments = 0x01; + smpp_msg.pdu.submit_sm.sar_segment_seqnum = 0x01; + smpp_msg.pdu.submit_sm.more_messages_to_send = 0x01; + smpp_msg.pdu.submit_sm.payload_type = 0x00; + strcpy(smpp_msg.pdu.submit_sm.message_payload, "messae in submit sm optional"); + smpp_msg.pdu.submit_sm.privacy_indicator = 0x03; + + //strcpy(smpp_msg.pdu.submit_sm.callback_num, "F0453245"); + smpp_msg.pdu.submit_sm.callback_num[0] = 0x01; //ASCII + smpp_msg.pdu.submit_sm.callback_num[1] = 0x02; //National + smpp_msg.pdu.submit_sm.callback_num[2] = 0x03; //Data + strcpy(smpp_msg.pdu.submit_sm.callback_num+3, "F0453245"); + smpp_msg.pdu.submit_sm.callback_num_pres_ind = 0x06; + strcpy(smpp_msg.pdu.submit_sm.callback_num_atag, "callback_num_atag"); + //strcpy(smpp_msg.pdu.submit_sm.source_subaddress, "123"); + //smpp_msg.pdu.submit_sm.source_subaddress[0] = 0x88; + //strcpy(smpp_msg.pdu.submit_sm.source_subaddress+1,"123"); + + //smpp_msg.pdu.submit_sm.dest_subaddress[0] = 0x88; + //strcpy(smpp_msg.pdu.submit_sm.dest_subaddress+1, "789"); + smpp_msg.pdu.submit_sm.user_response_code = 0x03; + smpp_msg.pdu.submit_sm.display_time = 0x02; + //smpp_msg.pdu.submit_sm.sms_signal = 0x03; + + smpp_msg.pdu.submit_sm.ms_validity = 0x03; + smpp_msg.pdu.submit_sm.ms_msg_wait_facilities = 0x03; + smpp_msg.pdu.submit_sm.number_of_messages = 0x03; + smpp_msg.pdu.submit_sm.alert_on_message_delivery = 0x03; + + smpp_msg.pdu.submit_sm.language_indicator = 0x01; + smpp_msg.pdu.submit_sm.its_reply_type = 0x03; + smpp_msg.pdu.submit_sm.its_session_info[0] = 0x01; + smpp_msg.pdu.submit_sm.its_session_info[1] = 0x53; + smpp_msg.pdu.submit_sm.ussd_service_op = 0x03; + + break; + case 1: //send deliver sm + smpp_msg.message_type = 0x0F; + smpp_msg.optional_param_flag1 = 0x000167FF; + smpp_msg.optional_param_flag2 = 0x0; + + //Mandatory parameters. + strcpy(smpp_msg.pdu.deliver_sm.service_type, "USSD"); + smpp_msg.pdu.deliver_sm.source_addr_ton = 0x2; //National + smpp_msg.pdu.deliver_sm.source_addr_npi = 0x1; //ISDN + strcpy(smpp_msg.pdu.deliver_sm.source_addr, "172.18.166.1"); + smpp_msg.pdu.deliver_sm.dest_addr_ton = 0x2; //National + smpp_msg.pdu.deliver_sm.dest_addr_npi = 0x1; //ISDN + strcpy(smpp_msg.pdu.deliver_sm.destination_addr, "13923482085"); + smpp_msg.pdu.deliver_sm.esm_class = 0x00; + smpp_msg.pdu.deliver_sm.protocol_id = 0x0; + smpp_msg.pdu.deliver_sm.priority_flag = 0x3; + smpp_msg.pdu.deliver_sm.schedule_delivery_time = 0x0; + smpp_msg.pdu.deliver_sm.validity_period = 0x0; + smpp_msg.pdu.deliver_sm.registered_delivery = 0x12; + smpp_msg.pdu.deliver_sm.replace_if_present_flag = 0x01; + smpp_msg.pdu.deliver_sm.data_coding = 0x07; + smpp_msg.pdu.deliver_sm.sm_default_msg_id = 0x01; + smpp_msg.pdu.deliver_sm.sm_length = 0x0; + strcpy(smpp_msg.pdu.deliver_sm.short_message, ""); + + //Optional parameters. + smpp_msg.pdu.deliver_sm.user_message_reference = 0x00; + smpp_msg.pdu.deliver_sm.source_port = 0x6666; + smpp_msg.pdu.deliver_sm.destination_port = 0x8888; + smpp_msg.pdu.deliver_sm.sar_msg_ref_num = 0x7700; + + smpp_msg.pdu.deliver_sm.sar_total_segments = 0x01; + smpp_msg.pdu.deliver_sm.sar_segment_seqnum = 0x01; + smpp_msg.pdu.deliver_sm.user_response_code = 0x03; + smpp_msg.pdu.deliver_sm.privacy_indicator = 0x03; + + smpp_msg.pdu.deliver_sm.payload_type = 0x00; + strcpy(smpp_msg.pdu.deliver_sm.message_payload, "messae in deliver sm optional"); + smpp_msg.pdu.deliver_sm.callback_num[0] = 0x01; //ASCII + smpp_msg.pdu.deliver_sm.callback_num[1] = 0x02; //National + smpp_msg.pdu.deliver_sm.callback_num[2] = 0x03; //Data + strcpy(smpp_msg.pdu.deliver_sm.callback_num+3, "F0453245"); + //smpp_msg.pdu.deliver_sm.source_subaddress[0] = 0xA0; + //smpp_msg.pdu.deliver_sm.source_subaddress[1] = 0x01; + //strcpy(smpp_msg.pdu.deliver_sm.source_subaddress+1, "123"); + + //smpp_msg.pdu.deliver_sm.dest_subaddress[0] = 0xA0; + //smpp_msg.pdu.deliver_sm.dest_subaddress[1] = 0x01; + //strcpy(smpp_msg.pdu.deliver_sm.dest_subaddress+1, "321"); + smpp_msg.pdu.deliver_sm.language_indicator = 0x01; + smpp_msg.pdu.deliver_sm.its_session_info[0] = 0x01; + smpp_msg.pdu.deliver_sm.its_session_info[1] = 0x53; + //smpp_msg.pdu.deliver_sm.network_error_code[0] = 0x03; + //smpp_msg.pdu.deliver_sm.network_error_code[1] = 0x03; + //smpp_msg.pdu.deliver_sm.network_error_code[2] = 0x00; + + smpp_msg.pdu.deliver_sm.message_state = 0x01; + //strcpy(smpp_msg.pdu.deliver_sm.receipted_message_id, "receipted message id in deliver sm"); + break; + case 2: //data_sm + smpp_msg.message_type = 0x11; + smpp_msg.optional_param_flag1 = 0xB3EBFFFF; + smpp_msg.optional_param_flag2 = 0x0000003F; + //smpp_msg.optional_param_flag1 = 0x0C000000; + //smpp_msg.optional_param_flag2 = 0x0; + + //Mandatory parameters. + strcpy(smpp_msg.pdu.data_sm.service_type, "USSD"); + smpp_msg.pdu.data_sm.source_addr_ton = 0x2; //National + smpp_msg.pdu.data_sm.source_addr_npi = 0x1; //ISDN + strcpy(smpp_msg.pdu.data_sm.source_addr, "172.18.166.1"); + smpp_msg.pdu.data_sm.dest_addr_ton = 0x2; //National + smpp_msg.pdu.data_sm.dest_addr_npi = 0x1; //ISDN + strcpy(smpp_msg.pdu.data_sm.destination_addr, "13923482085"); + smpp_msg.pdu.data_sm.esm_class = 0x00; + smpp_msg.pdu.data_sm.registered_delivery = 0x11; + smpp_msg.pdu.data_sm.data_coding = 0x07; + + //Optional parameters. + smpp_msg.pdu.data_sm.source_port = 0x6666; + smpp_msg.pdu.data_sm.source_addr_subunit = 0x01; + smpp_msg.pdu.data_sm.source_network_type = 0x01; + smpp_msg.pdu.data_sm.source_bearer_type = 0x03; + + smpp_msg.pdu.data_sm.source_telematics_id = 0x0003; + smpp_msg.pdu.data_sm.destination_port = 0x8888; + smpp_msg.pdu.data_sm.dest_addr_subunit = 0x03; + smpp_msg.pdu.data_sm.dest_network_type = 0x03; + + smpp_msg.pdu.data_sm.dest_bearer_type = 0x03; + smpp_msg.pdu.data_sm.dest_telematics_id = 0x0003; + smpp_msg.pdu.data_sm.sar_msg_ref_num = 0x7700; + smpp_msg.pdu.data_sm.sar_total_segments = 0x01; + + smpp_msg.pdu.data_sm.sar_segment_seqnum = 0x01; + smpp_msg.pdu.data_sm.more_messages_to_send = 0x01; + smpp_msg.pdu.data_sm.qos_time_to_live = 0x000000FF; + smpp_msg.pdu.data_sm.payload_type = 0x00; + + strcpy(smpp_msg.pdu.data_sm.message_payload, "smpp message in data sm optional"); + smpp_msg.pdu.data_sm.set_dpf = 0x01; + //strcpy(smpp_msg.pdu.data_sm.receipted_message_id, "receipted message id"); + smpp_msg.pdu.data_sm.message_state = 0x01; + + //smpp_msg.pdu.data_sm.network_error_code[0] = 0x03; + //smpp_msg.pdu.data_sm.network_error_code[1] = 0x03; + //smpp_msg.pdu.data_sm.network_error_code[2] = 0x00; + smpp_msg.pdu.data_sm.user_message_reference = 0x00; + smpp_msg.pdu.data_sm.privacy_indicator = 0x03; + smpp_msg.pdu.data_sm.callback_num[0] = 0x01; + smpp_msg.pdu.data_sm.callback_num[1] = 0x02; + smpp_msg.pdu.data_sm.callback_num[2] = 0x03; + strcpy(smpp_msg.pdu.data_sm.callback_num+3, "call back num"); + + smpp_msg.pdu.data_sm.callback_num_pres_ind = 0x06; + strcpy(smpp_msg.pdu.data_sm.callback_num_atag, "callback num atag in data sm"); + smpp_msg.pdu.data_sm.source_subaddress[0] = 0xA0; + smpp_msg.pdu.data_sm.source_subaddress[1] = 0x01; + //strcpy(smpp_msg.pdu.data_sm.source_subaddress+1, "123"); + smpp_msg.pdu.data_sm.dest_subaddress[0] = 0xA0; + smpp_msg.pdu.data_sm.dest_subaddress[1] = 0x01; + //strcpy(smpp_msg.pdu.data_sm.dest_subaddress+1, "321"); + + smpp_msg.pdu.data_sm.user_response_code = 0x03; + smpp_msg.pdu.data_sm.display_time = 0x02; + //smpp_msg.pdu.data_sm.sms_signal = 0x03; + smpp_msg.pdu.data_sm.ms_validity = 0x03; + + smpp_msg.pdu.data_sm.ms_msg_wait_facilities = 0x03; + smpp_msg.pdu.data_sm.number_of_messages = 0x03; + smpp_msg.pdu.data_sm.alert_on_message_delivery = 0x03; + smpp_msg.pdu.data_sm.language_indicator = 0x01; + + smpp_msg.pdu.data_sm.its_reply_type = 0x03; + smpp_msg.pdu.data_sm.its_session_info[0] = 0x01; + smpp_msg.pdu.data_sm.its_session_info[1] = 0x53; + break; + } + + smpp_send(linkNo, &smpp_msg, dataLen); +} diff --git a/plat/smpp/ut/smpp_ussd_test/guess_number.c b/plat/smpp/ut/smpp_ussd_test/guess_number.c new file mode 100644 index 0000000..7c00650 --- /dev/null +++ b/plat/smpp/ut/smpp_ussd_test/guess_number.c @@ -0,0 +1,948 @@ +//-------------------------------------- +// USSD EAE write for ussd test +// Author: lw 2006/7/10 +//-------------------------------------- + +#include "./include/smpp.h" + +#define ISDN_LEN 9 + +typedef struct GameSession +{ + BYTE LinkNo; + BYTE flag; + BYTE ussd_ref; + BYTE seed[4]; + BYTE ssm_state; + BYTE shmsg[256]; + BYTE us_prm; + BYTE input[4]; + BYTE history[512]; + BYTE count; + char msisdn[(ISDN_LEN+1)*2+2]; +} +GameSession; + + + +typedef enum _USSD_OP +{ + PSSDR = 0 , // MAP_Process_USS_Data request operation + PSSRR = 1 , // MAP_Process_USS_Request request operation + USSRR = 2 , // MAP_USS_Request Request operation + USSNR = 3 , // MAP_USS_Notify Request operation + OPENR = 4 , // open request operation + RELR = 5 , // Release request operation + + PSSDA = 6 , // MAP_Process_USS_Data Answer operation + PSSDE = 7 , // MAP_Process_USS_Data error operation + + PSSRA = 8 , // MAP_Process_USS_Request Answer operation + PSSRE = 9 , // MAP_Process_USS_Request error operation + + USSRA = 10 , // MAP_USS_Request Answer operation + USSRE = 11, // MAP_USS_Request Error operation + + USSNA = 12, // MAP_USS_Notify Answer operation + USSNE = 13, // MAP_USS_Notify Error operation + + OPENE = 14, // open error operation + RELE = 15, // Release error operation + + PSSDS = 16, // MAP_Process_USS_Data confirm operation + PSSRS = 17, // MAP_Process_USS_Request confirm operation + USSRC = 18, // MAP_USS_Request Confirm operation + USSNC = 19, // MAP_USS_Notify Confirm operation + + USSRS = 20, // MAP_USS_Request response operation + USSNS = 21, // MAP_USS_Notify response operation + PSSRC = 22, // MAP_Process_USS_Request confirm operation + OPENC = 23, // open confirm operation + RELC = 24, // Release confirm operation +} +USSD_OP; + +struct ussd_op +{ + char *s; + USSD_OP v; +}; + +#define USSD_OP_NUM 25 +#define USSD_OP_LEN 5 + +static const struct ussd_op op_map_name[25] = { + { "PSSDR" , PSSDR }, // 0 MAP_Process_USS_Data request operation + { "PSSRR" , PSSRR }, // 1 MAP_Process_USS_Request request operation + { "USSRR" , USSRR }, // 2 MAP_USS_Request Request operation + { "USSNR" , USSNR }, // 3 MAP_USS_Notify Request operation + { "OPENR" , OPENR }, // 4 open request operation + { "RELR " , RELR }, // 5 Release request operation + + { "PSSAE" , PSSDA }, // 6 MAP_Process_USS_Data Answer operation + { "PSSDE" , PSSDE }, // 7 MAP_Process_USS_Data error operation + + { "PSSRE" , PSSRA }, // 8 MAP_Process_USS_Request Answer operation + { "PSSRE" , PSSRE }, // 9 MAP_Process_USS_Request error operation + + { "USSRA" , USSRA }, // 10 MAP_USS_Request Answer operation + { "USSRE" , USSRE }, // 11 MAP_USS_Request Error operation + + { "USSNA" , USSNA }, // 12 MAP_USS_Notify Answer operation + { "USSNE" , USSNE }, // 13 MAP_USS_Notify Error operation + + { "OPENE" , OPENE }, // 14 open error operation + { "RELE " , RELE }, // 15 Release error operation + + { "PSSDS" , PSSDS }, // 16 MAP_Process_USS_Data confirm operation + { "PSSRS" , PSSRS }, // 17 MAP_Process_USS_Request confirm operation + { "USSRC" , USSRC }, // 18 MAP_USS_Request Confirm operation + { "USSNC" , USSNC }, // 19 MAP_USS_Notify Confirm operation + + { "USSRS" , USSRS }, // 20 MAP_USS_Request response operation + { "USSNS" , USSNS }, // 21 MAP_USS_Notify response operation + { "PSSRC" , PSSRC }, // 22 MAP_Process_USS_Request confirm operation + { "OPENC" , OPENC }, // 23 open confirm operation + { "RELC " , RELC }, // 24 Release confirm operation +}; + +typedef enum US_STATE +{ + US_IDLE=0, + US_OPENR, + US_OPENC, + US_OPENE, + US_PSSRR, + US_PSSRA, + US_PSSRE, + US_PSSRC, + US_PSSRS, + US_USSRR, + US_USSRC, + US_USSRS, + US_USSNR, + US_USSNC, + US_USSNS, + US_RELER, + US_RELEC, + US_RELES, + US_RELEE, +} +US_STATE; + +#define MAX_GAME_SESSION 255 + +typedef struct GuessGame +{ + BYTE wxc2_hlr_number[8]; + char service_number[8]; + BYTE link_enable; + BYTE link; +}GuessGame; + +GuessGame gg; + + +struct GameSession ssm_data[MAX_GAME_SESSION]; + +#define SD_PKT_NUM 10 +#define STORE_MSG_ITEM 60 + +typedef struct SMPP_MSG_STORE_STRUCT +{ + BYTE short_message[SMPP_MSG_LEN]; + BYTE message_id[65]; +} SMPP_MSG_STORE_STRUCT; + + +#define MAX_GAME_LINK 1 + +static struct itimerval itimer,old_itimer; +static int timer_counter[MAX_GAME_LINK]; +static int stateFlag[MAX_GAME_LINK]; +static int msg_count[MAX_GAME_LINK]; +static int msg_pointer[MAX_GAME_LINK]; +static SMPP_MSG_STORE_STRUCT store_msg_buf[MAX_GAME_LINK][STORE_MSG_ITEM]; + +static void On_Timer(); +static void SetTimer(); +static void smpp_test_init(); +static int smpp_onDataRecv(BYTE linkNo, SMPP_MSG *pData, WORD dataLen); +static int smpp_onLinkStateChange(BYTE linkNo, BYTE linkstate); + +BYTE hae_isdn_ston(BYTE *normal_isdn,BYTE *str_isdn) +{ + BYTE ii; + BYTE len; + + len = strlen(str_isdn); + if (len > ISDN_LEN*2-2) + return 0; + if ((len % 2) == 1) // odd number + { + AsciiToBcd(normal_isdn+1,str_isdn,len-1); + ii = len/2 + 1; + normal_isdn[ii] = (str_isdn[len-1] - '0') << 4; + normal_isdn[ii] |= 0x0E; + } + else + { + AsciiToBcd(normal_isdn+1,str_isdn,len); + ii = len/2; + } + memset(normal_isdn+ii+1,0xEE,ISDN_LEN-ii-1); + normal_isdn[0] = 0x91; // default value + return 1; +} + + +void hae_isdn_ntos(BYTE *str_isdn,BYTE *normal_isdn) +{ + BYTE len = 0; + BYTE ii,jj; + + for (ii = 1;ii < ISDN_LEN;ii ++) + { + jj = (normal_isdn[ii] >> 4) & 0x0f; + if (jj > 0x0c) + break; + str_isdn[len++] = jj + '0'; + jj = normal_isdn[ii] & 0x0f; + if (jj > 0x0c) + break; + str_isdn[len++] = jj + '0'; + } + str_isdn[len] = '\0'; +} + +int register_link() +{ + BYTE ret; + + strcpy( gg.service_number , "86755001"); + + if( gg.link == MAX_SMPP_LINK+1 ) + { + ret = smpp_registerLink(SMPP_CLIENT, BIND_TRX, gg.service_number, TRANSACTION); + if ((ret&0x80) == 0x80) + { + gg.link = ret&0x7f; + printf("Get link for GuessGame EAE .link:%d", gg.link); + smpp_attach_link(gg.link, smpp_onDataRecv, smpp_onLinkStateChange); + return 1; + } + } + else + { + smpp_attach_link(gg.link, smpp_onDataRecv, smpp_onLinkStateChange); + return 1; + } + return 0; +} + +void smpp_test_init(int flag) +{ + int i; + + FILE *fp; + char line[32]; + char test_file[] = "./conf/guess_number_test.conf"; + + gg.link_enable = 0; + gg.link = MAX_SMPP_LINK+1; + for (i=0; i 6 ; i -- ) + { + if( line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '\n') + { + continue; + } + else if( isdigit( line[i] ) ) + { + break; + } + } + if( i < 16 && i > 6 ) + { + line[i+1] = '\0'; + } + line[16] = '\0'; + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + + if( !ssm_data[i].flag ) + { + ssm_data[i].flag = 1; + ssm_data[i].ssm_state =6; + printf("read msisdn :%s\n",line); + strcpy ( ssm_data[i].msisdn, line ); + //hae_isdn_ston ( temp_isdn, temp_msisdn ); + //memcpy( ssm_data[i].msisdn , temp_isdn , ISDN_LEN); + break; + } + } + } + } +} + +extern int iptrMainInit(); + + +int main(int argc,char *argv[]) +{ + int i; + char ret; + + heartbeat_init(0xFFFF); + debug_init(); + iptrMainInit(); + snmp_init(SMPP_PORT); + mtp_shm_init(); + sccp_init(); + + smpp_init_new(); + while ((ret = getopt(argc,argv,"n")) != -1) + { + switch (ret) + { + case 'n': + printf("\n\n\nNetwork initial ussd to ms\n\n\n"); + smpp_test_init(1); + break; + default: + smpp_test_init(0); + break; + } + } + + + for (i=0; imessage_type) + { + + case 0x0C: /* SUBMIT SM RESP */ + printf("[TEST PROGRAM]Link %d received SUBMIT SM RESP.\n", linkNo); + break; + case 0x0F: /* DELIVER SM */ + printf("[TEST PROGRAM]Link %d received DELIVER SM. op:%d \n", linkNo , pMsg->pdu.deliver_sm.ussd_service_op); + switch( pMsg->pdu.deliver_sm.ussd_service_op ) + { + case PSSRR: + smpp_send_ascout("\33[32mGuess Game Recv PSSRR\33[0m\n"); + if( pMsg->pdu.deliver_sm.user_message_reference >= MAX_GAME_SESSION ) + { + smpp_send_ascout("\33[32mThe session id is too large!\33[0m\n"); + return -1; + } + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + if( pMsg->pdu.deliver_sm.user_message_reference == ssm_data[i].ussd_ref ) + { + if( ssm_data[i].flag == 1) + { + smpp_send_ascout("\33[32mThe session id is in used!\33[0m\n"); + return -1; + } + } + } + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + if( ssm_data[i].flag == 0) + { + break; + } + } + ssm_data[i].flag = 1; + ssm_data[i].ssm_state =1; + ssm_data[i].ussd_ref = pMsg->pdu.deliver_sm.user_message_reference; + strcpy ( ssm_data[i].msisdn, pMsg->pdu.deliver_sm.source_addr ); + break; + case USSRC: + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + if( strcmp( pMsg->pdu.deliver_sm.source_addr ,ssm_data[i].msisdn ) == 0 ) + { + break; + } + } + if( i == MAX_GAME_SESSION ) + { + printf( "unkown USSRC msisdn :%s \n",pMsg->pdu.deliver_sm.source_addr ); + SendMsgToSMPP( pMsg->pdu.deliver_sm.user_message_reference ,ssm_ptr->shmsg , RELR ); + ssm_ptr->us_prm = US_RELER; + return -1; + } + ssm_ptr = &ssm_data[i]; + ssm_ptr->us_prm = US_USSRC; + smpp_send_ascout("\33[32mGuess Game Recv USSRC\33[0m\n"); + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , pMsg->pdu.deliver_sm.user_message_reference); + smpp_send_ascout(temp_str); + if( pMsg->pdu.deliver_sm.sm_length == 4 ) + { + memcpy( &ssm_ptr->input , &pMsg->pdu.deliver_sm.short_message ,4); + ssm_ptr->input[0] -= '0'; + ssm_ptr->input[1] -= '0'; + ssm_ptr->input[2] -= '0'; + ssm_ptr->input[3] -= '0'; + } + strcpy( ssm_ptr->shmsg , pMsg->pdu.deliver_sm.short_message ); + ssm_ptr->shmsg[pMsg->pdu.deliver_sm.sm_length] = '\0'; + break; + case USSNC: + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + if( strcmp( pMsg->pdu.deliver_sm.source_addr ,ssm_data[i].msisdn ) == 0 ) + { + break; + } + } + if( i == MAX_GAME_SESSION ) + { + printf( "unkown USSRC msisdn :%s \n",pMsg->pdu.deliver_sm.source_addr ); + if( pMsg->pdu.deliver_sm.user_message_reference < MAX_GAME_SESSION ) + { + ssm_ptr = &ssm_data[i]; + strcpy( ssm_ptr->shmsg , " incorrect user msg reference " ); + SendMsgToSMPP( pMsg->pdu.deliver_sm.user_message_reference ,ssm_ptr->shmsg , RELR ); + } + return -1; + } + ssm_ptr = &ssm_data[i]; + ssm_ptr->us_prm = US_USSNC; + smpp_send_ascout("\33[32mGuess Game Recv USSNC\33[0m\n"); + break; + case RELR: + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + if( strcmp( pMsg->pdu.deliver_sm.source_addr ,ssm_data[i].msisdn ) == 0 ) + { + break; + } + } + if( i == MAX_GAME_SESSION ) + { + + //sprintf( ssm_ptr->shmsg ,"unkown RELR msisdn :%s \n",pMsg->pdu.deliver_sm.source_addr ); + //SendMsgToSMPP( pMsg->pdu.deliver_sm.user_message_reference ,ssm_ptr->shmsg , RELR ); + return -1; + } + ssm_ptr = &ssm_data[i]; + ssm_ptr->us_prm = US_RELEC; + smpp_send_ascout("\33[32mGuess Game Recv RELR\33[0m\n"); + break; + case RELC: + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + if( strcmp( pMsg->pdu.deliver_sm.source_addr ,ssm_data[i].msisdn ) == 0 ) + { + break; + } + } + if( i == MAX_GAME_SESSION ) + { + printf( "unkown RELC msisdn :%s \n",pMsg->pdu.deliver_sm.source_addr ); + SendMsgToSMPP( pMsg->pdu.deliver_sm.user_message_reference ,ssm_ptr->shmsg , RELR ); + return -1; + } + ssm_ptr = &ssm_data[i]; + ssm_ptr->us_prm = US_RELES; + smpp_send_ascout("\33[32mGuess Game Recv RELR\33[0m\n"); + break; + default: + break; + } + + /* fill with DELIVER SM RESP structure. */ + smpp_msg.message_type = 0x10; + smpp_msg.pdu.deliver_sm_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.deliver_sm_resp.head.sequence_number = pMsg->pdu.deliver_sm.head.sequence_number; + smpp_msg.pdu.deliver_sm_resp.message_id = 0x0; + smpp_send(linkNo, &smpp_msg, dataLen); + smpp_send_ascout("Send deliver_sm_resp\n"); + call_flag = 0; + break; + } + return sequence_number; +} + +int smpp_onLinkStateChange(BYTE linkNo, BYTE linkstate) +{ + printf("[TEST PROGRAM]link %d state change to %d\n",linkNo, linkstate); + if (linkstate == 1) + gg.link_enable = 1; + else + gg.link_enable = 0; + + return linkNo; +} + +int RandomNum(BYTE *seed) +{ + int count , i , j; + i = j = count = 0 ; + while( count < 4 ) + { + j = 1 +(int)(10.0*rand()/(RAND_MAX+1.0)); + if( j >= 10 ) + { + continue; + } + for( i = count ; i > 0 ; i-- ) + { + if( j == seed[i] ) + { + break; + } + } + if( !count || j != seed[i]) + { + seed[count] = j; + count++; + } + } + return (count == 4 ? 1 : 0); +} + + +int CheckInput(BYTE *input) +{ + int input_index ,index; + + for( input_index = 0 ; input_index < 4 ; input_index++ ) + { + for( index = 0 ; index < 4 ; index++ ) + { + if( index != input_index && input[input_index] == input[index] ) + { + return 0; + } + } + } + return 1; +} + +int GuessNumber(BYTE* input,BYTE* seed) +{ + BYTE seed_index , input_index ; + BYTE rt_a , rt_b ; + + rt_a = rt_b = 0; + for( input_index = 0 ; input_index < 4 ; input_index++ ) + { + for( seed_index = 0 ; seed_index < 4 ; seed_index++ ) + { + if( input[(int)input_index] == seed[(int)seed_index] ) + { + if( input_index == seed_index ) + { + rt_a++; + } + else + { + rt_b++; + } + } + } + } + return (rt_a << 4) + rt_b; +} + +void SendMsgToSMPP(int sid , BYTE* msg , BYTE ussd_op) +{ + SMPP_MSG pMsg; + int data_len; + PDU_SUBMIT_SM *submit_sm; + struct GameSession *ssm_ptr; + char temp_str[256]; + + if( sid >= MAX_GAME_SESSION ) + { + ssm_ptr = &ssm_data[sid - MAX_GAME_SESSION]; + } + else + { + ssm_ptr = &ssm_data[sid]; + } + memset( &pMsg , 0 , sizeof(SMPP_MSG)); + + submit_sm = &pMsg.pdu.submit_sm; + pMsg.message_type = 0x0B; + pMsg.optional_param_flag1 = 0x08000001; + if( sid < MAX_GAME_SESSION ) + submit_sm->user_message_reference = ssm_ptr->ussd_ref; + else + submit_sm->user_message_reference = 0xFFFF; + submit_sm->ussd_service_op = ussd_op; + strcpy( submit_sm->service_type , "USSD" ); + strcpy( submit_sm->destination_addr , ssm_ptr->msisdn ); + strcpy( submit_sm->source_addr , gg.service_number ); + //hae_isdn_ntos( submit_sm->destination_addr , ssm_ptr->msisdn ); + sprintf(temp_str, "\33[32mGuessGame send smpp msg: ussd_op :%s ssm_ptr->msisdn :%s user_refer : %d\33[0m\n" + , op_map_name[submit_sm->ussd_service_op].s ,ssm_ptr->msisdn , submit_sm->user_message_reference); + smpp_send_ascout(temp_str); + submit_sm->sm_length = strlen( msg ); + strcpy( submit_sm->short_message , msg ); + smpp_send( gg.link , &pMsg , data_len ); +} + + +void GameFsm() +{ + int rt; + int i; + char temp_str[1024]; + struct GameSession *ssm_ptr; + + if( !gg.link_enable && !register_link() ) + { + smpp_send_ascout("Try to connect to WXC2 HLR fail\n"); + printf("Try to connect to WXC2 HLR fail\n"); + return; + } + //sprintf(debugBuf,); + //smpp_send_ascout("The session id is in used!\n"); + + for( i = 0 ;i < MAX_GAME_SESSION ; i++) + { + ssm_ptr = &ssm_data[i]; + if( ssm_ptr->flag == 0 ) + { + continue; + } + if( ssm_ptr->us_prm == US_RELES ) + { + ssm_ptr->ssm_state = 7; + } + else if( ssm_ptr->us_prm == US_RELEC ) + { + strcpy( ssm_ptr->shmsg , "Release ack!\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , RELC ); + ssm_ptr->ssm_state = 7; + } + switch( ssm_ptr->ssm_state ) + { + case 0: + continue; + case 1: + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + if( !RandomNum( ssm_ptr->seed ) ) + { + //"Create random number fail" + return; + } + //sid = pMsg->pdu.deliver_sm.user_message_reference ; + //if( sid > MAX_GAME_SESSION ) + //{ + // //"Game EAE do no support so much session .sid :%d",sid + // return; + //} + sprintf( ssm_ptr->shmsg ," WellCome to WXC2 Online Guess Number Game System!\n Please input you guess nubmer:\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 2; + break; + case 2: + switch( ssm_ptr->us_prm ) + { + case US_IDLE: + break; + case US_RELER: + break; + case US_USSRC: + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + if( strlen(ssm_ptr->shmsg) != 4 ) + { + sprintf(temp_str, "\33[32mThe input string length is not 4. input again.\33[0m\n"); + smpp_send_ascout(temp_str); + strcpy ( ssm_ptr->shmsg , "The input string length is not 4. input again."); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->shmsg[0] = '\0'; + ssm_ptr->us_prm = US_IDLE; + return; + } + if( !CheckInput( ssm_ptr->input ) ) + { + sprintf( ssm_ptr->shmsg ,"Input is Error! Please input four difference numbers.\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + } + rt = GuessNumber( ssm_ptr->input , ssm_ptr->seed ) & 0xFF ; + ssm_ptr->count ++; + if( ssm_ptr->count >= 8 ) + { + sprintf ( ssm_ptr->shmsg ,"Game Over!\n"); + sprintf ( temp_str , "NO%d:%d%d%d%d ",ssm_ptr->count , ssm_ptr->input[0],ssm_ptr->input[1],ssm_ptr->input[2],ssm_ptr->input[3]); + strcat ( ssm_ptr->history , temp_str ); + sprintf ( temp_str , "->%dA%dB\n" , rt>>4 , rt&0x0F); + strcat ( ssm_ptr->history , temp_str ); + //strcat ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 3; + ssm_ptr->us_prm = US_IDLE; + return ; + } + sprintf( temp_str , "NO%d:%d%d%d%d ",ssm_ptr->count , ssm_ptr->input[0],ssm_ptr->input[1],ssm_ptr->input[2],ssm_ptr->input[3]); + if( rt != 0x40 ) + { + strcat ( ssm_ptr->history , temp_str ); + sprintf( temp_str , "->%dA%dB\n" , rt>>4 , rt&0x0F); + strcat ( ssm_ptr->history , temp_str ); + strcpy ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->us_prm = US_IDLE; + } + else + { + strcat ( ssm_ptr->history , temp_str ); + sprintf( temp_str , "->%dA%dB\n" , rt>>4 , rt&0x0F); + strcat ( ssm_ptr->history , temp_str ); + strcpy ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 3; + ssm_ptr->us_prm = US_IDLE; + } + break; + } + break; + case 3: + if( ssm_ptr->us_prm == US_USSNC ) + { + switch( ssm_ptr->count ) + { + case 1: + sprintf ( ssm_ptr->shmsg ," So Luck!\n"); + break; + case 2: + sprintf ( ssm_ptr->shmsg ," Luck\n"); + break; + case 3: + sprintf ( ssm_ptr->shmsg ," Perfect\n"); + break; + case 4: + sprintf ( ssm_ptr->shmsg ," Very Good\n"); + break; + case 5: + sprintf ( ssm_ptr->shmsg ," Good\n"); + break; + case 6: + case 7: + case 8: + sprintf ( ssm_ptr->shmsg ," Correct\n"); + break; + default: + strcpy ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 4; + return; + break; + } + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 4; + } + case 4: + if( ssm_ptr->us_prm == US_USSNC ) + { + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + sprintf( ssm_ptr->shmsg ," Guess Number\n1 . Restart game \n 2 . exit\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + ssm_ptr->ssm_state = 5; + ssm_ptr->count =0; + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + } + break; + case 5: + if( ssm_ptr->us_prm == US_USSRC ) + { + if( ssm_ptr->shmsg[0] == '1' ) + { + if( !RandomNum( ssm_ptr->seed ) ) + { + //"Create random number fail" + return; + } + sprintf( ssm_ptr->shmsg ," Game Restart.input four difference numbers: \n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + ssm_ptr->history[0]= '\0'; + ssm_ptr->ssm_state = 2; + } + else if( ssm_ptr->shmsg[0] == '2' ) + { + sprintf( ssm_ptr->shmsg ," Game Exit.GoodBye! Wellcome to use WXC2 system!\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + memset( ssm_ptr , 0 , sizeof(GameSession )); + + } + else + { + sprintf( ssm_ptr->shmsg ," Unexpeced menu selection!\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + ssm_ptr->ssm_state = 7; + } + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + } + break; + case 6: + if( gg.link_enable ) + { + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + if( !RandomNum( ssm_ptr->seed ) ) + { + //"Create random number fail" + return; + } + sprintf( ssm_ptr->shmsg ," WellCome to WXC2 Online Guess Number Game System!\n Please input you guess nubmer:\n"); + SendMsgToSMPP( i+MAX_GAME_SESSION ,ssm_ptr->shmsg , USSRR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 2; + sprintf(temp_str, "\33[32mGame Fsm change to state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + } + break; + case 7: //release + if( ssm_ptr->us_prm == US_USSNC ) + { + strcpy( ssm_ptr->shmsg , "session is closed"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , RELR ); + } + sprintf(temp_str, "\33[32mRecv Release command ! sid: %d ussd_ref: %d\33[0m\n" , i ,ssm_ptr->ussd_ref); + smpp_send_ascout(temp_str); + memset( ssm_ptr , 0 , sizeof(GameSession )); + break; + } + } +} + diff --git a/plat/smpp/ut/smpp_ussd_test/pppchat.c b/plat/smpp/ut/smpp_ussd_test/pppchat.c new file mode 100644 index 0000000..a3e1def --- /dev/null +++ b/plat/smpp/ut/smpp_ussd_test/pppchat.c @@ -0,0 +1,704 @@ +//-------------------------------------- +// USSD EAE write for ussd test +// Author: lw 2006/7/10 +//-------------------------------------- + +#include "./include/smpp.h" + +#define ISDN_LEN 9 + +typedef struct PPPChatSession +{ + BYTE LinkNo; + BYTE flag; + BYTE sid; + BYTE link_sid; + BYTE link_flag; + BYTE seed[4]; + BYTE ssm_state; + BYTE shmsg[256]; + BYTE us_prm; + BYTE input[4]; + BYTE history[512]; + BYTE count; + char msisdn[ISDN_LEN*2+1]; + char mt_msisdn[ISDN_LEN*2+1]; + char buf[256]; +} +PPPChatSession; + +typedef enum _USSD_OP +{ + PSSDR = 0 , // MAP_Process_USS_Data request operation + PSSRR = 1 , // MAP_Process_USS_Request request operation + USSRR = 2 , // MAP_USS_Request Request operation + USSNR = 3 , // MAP_USS_Notify Request operation + OPENR = 5 , // open request operation + RELR = 6 , // Release request operation + + PSSDE = 7 , // MAP_Process_USS_Data error operation + PSSRE = 8 , // MAP_Process_USS_Request error operation + USSRA = 9 , // MAP_USS_Request Answer operation + USSRE = 10, // MAP_USS_Request Error operation + USSNE = 11, // MAP_USS_Notify Error operation + USSNA = 12, // MAP_USS_Notify Answer operation + OPENE = 13, // open error operation + RELE = 14, // Release error operation + UTEST = 15, // USSD TEST Message + + PSSDS = 16, // MAP_Process_USS_Data confirm operation + PSSRS = 17, // MAP_Process_USS_Request confirm operation + USSRC = 18, // MAP_USS_Request Confirm operation + USSNC = 19, // MAP_USS_Notify Confirm operation + PSSRC = 20, // MAP_Process_USS_Request confirm operation + OPENC = 21, // open confirm operation + RELC = 22, // Release confirm operation +} +USSD_OP; + +typedef enum US_STATE +{ + US_IDLE=0, + US_OPENR, + US_OPENC, + US_OPENE, + US_PSSRR, + US_PSSRA, + US_PSSRE, + US_PSSRC, + US_PSSRS, + US_USSRR, + US_USSRC, + US_USSRS, + US_USSNR, + US_USSNC, + US_USSNS, + US_RELER, + US_RELEC, + US_RELEE, +} +US_STATE; + +#define MAX_GAME_SESSION 255 + +typedef struct GuessGame +{ + BYTE wxc2_hlr_number[8]; + BYTE link_enable; + BYTE link; +}GuessGame; + +GuessGame gg; + + +struct PPPChatSession ssm_data[MAX_GAME_SESSION]; + +#define SD_PKT_NUM 10 +#define STORE_MSG_ITEM 60 + +typedef struct SMPP_MSG_STORE_STRUCT +{ + BYTE short_message[SMPP_MSG_LEN]; + BYTE message_id[65]; +} SMPP_MSG_STORE_STRUCT; + + +#define MAX_GAME_LINK 1 + +static struct itimerval itimer,old_itimer; +static int timer_counter[MAX_GAME_LINK]; +static int stateFlag[MAX_GAME_LINK]; +static int msg_count[MAX_GAME_LINK]; +static int msg_pointer[MAX_GAME_LINK]; +static SMPP_MSG_STORE_STRUCT store_msg_buf[MAX_GAME_LINK][STORE_MSG_ITEM]; + +static void On_Timer(); +static void SetTimer(); +static void smpp_test_init(); +static int smpp_onDataRecv(BYTE linkNo, SMPP_MSG *pData, WORD dataLen); +static int smpp_onLinkStateChange(BYTE linkNo, BYTE linkstate); + +BYTE hae_isdn_ston(BYTE *normal_isdn,BYTE *str_isdn) +{ + BYTE ii; + BYTE len; + + len = strlen(str_isdn); + if (len > ISDN_LEN*2-2) + return 0; + if ((len % 2) == 1) // odd number + { + AsciiToBcd(normal_isdn+1,str_isdn,len-1); + ii = len/2 + 1; + normal_isdn[ii] = (str_isdn[len-1] - '0') << 4; + normal_isdn[ii] |= 0x0E; + } + else + { + AsciiToBcd(normal_isdn+1,str_isdn,len); + ii = len/2; + } + memset(normal_isdn+ii+1,0xEE,ISDN_LEN-ii-1); + normal_isdn[0] = 0x91; // default value + return 1; +} + + +void hae_isdn_ntos(BYTE *str_isdn,BYTE *normal_isdn) +{ + BYTE len = 0; + BYTE ii,jj; + + for (ii = 1;ii < ISDN_LEN;ii ++) + { + jj = (normal_isdn[ii] >> 4) & 0x0f; + if (jj > 0x0c) + break; + str_isdn[len++] = jj + '0'; + jj = normal_isdn[ii] & 0x0f; + if (jj > 0x0c) + break; + str_isdn[len++] = jj + '0'; + } + str_isdn[len] = '\0'; +} + +int register_link() +{ + BYTE ret; + + if( gg.link == MAX_SMPP_LINK+1 ) + { + ret = smpp_registerLink(SMPP_CLIENT, BIND_TRX, gg.wxc2_hlr_number, TRANSACTION); + if ((ret&0x80) == 0x80) + { + gg.link = ret&0x7f; + printf("Get link for GuessGame EAE .link:%d", gg.link); + smpp_attach_link(gg.link, smpp_onDataRecv, smpp_onLinkStateChange); + return 1; + } + } + else + { + smpp_attach_link(gg.link, smpp_onDataRecv, smpp_onLinkStateChange); + return 1; + } + return 0; +} + +void smpp_test_init(int flag) +{ + int i; + + FILE *fp; + char line[32]; + BYTE temp_isdn[ISDN_LEN+1]; + BYTE temp_msisdn[65]; + char test_file[] = "./conf/guess_number_test.conf"; + + gg.link_enable = 0; + gg.link = MAX_SMPP_LINK+1; + for (i=0; i 6 ; i -- ) + { + if( line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '\n') + { + continue; + } + else if( isdigit( line[i] ) ) + { + break; + } + } + if( i < 16 && i > 6 ) + { + line[i+1] = '\0'; + } + line[16] = '\0'; + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + + if( !ssm_data[i].flag ) + { + ssm_data[i].flag = 1; + ssm_data[i].ssm_state =6; + printf("read msisdn :%s\n",line); + strcpy ( temp_msisdn, line ); + hae_isdn_ston ( temp_isdn, temp_msisdn ); + memcpy( ssm_data[i].msisdn , temp_isdn , ISDN_LEN); + break; + } + } + } + } +} + + + +int main(int argc,char *argv[]) +{ + int i; + char ret; + + heartbeat_init(0xFFFF); + debug_init(); + iptrMainInit(); + snmp_init(SMPP_PORT); + mtp_shm_init(); + sccp_init(); + + smpp_init_new(); + while ((ret = getopt(argc,argv,"n")) != -1) + { + switch (ret) + { + case 'n': + printf("\n\n\nNetwork initial ussd to ms\n\n\n"); + smpp_test_init(1); + break; + default: + smpp_test_init(0); + break; + } + } + + + for (i=0; imessage_type) + { + + case 0x0C: /* SUBMIT SM RESP */ + printf("[TEST PROGRAM]Link %d received SUBMIT SM RESP.\n", linkNo); + break; + case 0x0F: /* DELIVER SM */ + printf("[TEST PROGRAM]Link %d received DELIVER SM. op:%d \n", linkNo , pMsg->pdu.deliver_sm.ussd_service_op); + switch( pMsg->pdu.deliver_sm.ussd_service_op ) + { + case PSSRR: + smpp_send_ascout("\33[32mPPP Chat Recv PSSRR\33[0m\n"); + if( pMsg->pdu.deliver_sm.user_message_reference >= MAX_GAME_SESSION ) + { + smpp_send_ascout("\33[32mThe session id is too large!\33[0m\n"); + return -1; + } + for( i = 0 ; i < MAX_GAME_SESSION ; i ++ ) + { + if( pMsg->pdu.deliver_sm.user_message_reference == ssm_data[i].sid || pMsg->pdu.deliver_sm.user_message_reference == ssm_data[i].link_sid ) + { + if( ssm_data[i].flag == 1) + { + smpp_send_ascout("\33[32mThe session id is in used!\33[0m\n"); + return -1; + } + ssm_data[i].flag = 1; + ssm_data[i].ssm_state =1; + strcpy ( temp_msisdn, pMsg->pdu.submit_sm.source_addr ); + hae_isdn_ston ( temp_isdn, temp_msisdn ); + memcpy( ssm_data[i].msisdn , temp_isdn , ISDN_LEN); + if( pMsg->pdu.deliver_sm.short_message_len <= ISDN*2 ) + { + memcpy( ssm_data[i].mt_msisdn , pMsg->pdu.deliver_sm.short_message , pMsg->pdu.deliver_sm.short_message_len ); + } + break; + } + } + + break; + case USSRC: + ssm_ptr = &ssm_data[pMsg->pdu.deliver_sm.user_message_reference]; + ssm_ptr->us_prm = US_USSRC; + smpp_send_ascout("\33[32mGuess Game Recv USSRC\33[0m\n"); + if( pMsg->pdu.deliver_sm.sm_length == 4 ) + { + memcpy( &ssm_ptr->input , &pMsg->pdu.deliver_sm.short_message ,4); + ssm_ptr->input[0] -= '0'; + ssm_ptr->input[1] -= '0'; + ssm_ptr->input[2] -= '0'; + ssm_ptr->input[3] -= '0'; + } + strcpy( ssm_ptr->shmsg , pMsg->pdu.deliver_sm.short_message ); + ssm_ptr->shmsg[pMsg->pdu.deliver_sm.sm_length] = '\0'; + break; + case USSNC: + ssm_ptr->us_prm = US_USSNC; + smpp_send_ascout("\33[32mGuess Game Recv USSNC\33[0m\n"); + break; + default: + break; + } + + /* fill with DELIVER SM RESP structure. */ + smpp_msg.message_type = 0x10; + smpp_msg.pdu.deliver_sm_resp.head.command_status = htonl(ESME_ROK); + smpp_msg.pdu.deliver_sm_resp.head.sequence_number = pMsg->pdu.deliver_sm.head.sequence_number; + smpp_msg.pdu.deliver_sm_resp.message_id = 0x0; + smpp_send(linkNo, &smpp_msg, dataLen); + smpp_send_ascout("Send deliver_sm_resp\n"); + call_flag = 0; + break; + } + return sequence_number; +} + +int smpp_onLinkStateChange(BYTE linkNo, BYTE linkstate) +{ + printf("[TEST PROGRAM]link %d state change to %d\n",linkNo, linkstate); + if (linkstate == 1) + gg.link_enable = 1; + else + gg.link_enable = 0; + + return linkNo; +} + +void SendMsgToSMPP(int sid , BYTE* msg , BYTE ussd_op) +{ + SMPP_MSG pMsg; + int data_len; + PDU_SUBMIT_SM *submit_sm; + struct PPPChatSession *ssm_ptr; + + if( sid >= MAX_GAME_SESSION ) + { + ssm_ptr = &ssm_data[sid - MAX_GAME_SESSION]; + } + else + { + ssm_ptr = &ssm_data[sid]; + } + memset( &pMsg , 0 , sizeof(SMPP_MSG)); + + submit_sm = &pMsg.pdu.submit_sm; + pMsg.message_type = 0x0B; + pMsg.optional_param_flag1 = 0x08000001; + if( sid < MAX_GAME_SESSION ) + submit_sm->user_message_reference = sid; + else + submit_sm->user_message_reference = 0xFFFF; + submit_sm->ussd_service_op = ussd_op; + strcpy( submit_sm->service_type , "USSD" ); + hae_isdn_ntos( submit_sm->destination_addr , ssm_ptr->msisdn ); + submit_sm->sm_length = strlen( msg ); + strcpy( submit_sm->short_message , msg ); + smpp_send( gg.link , &pMsg , data_len ); +} + + +void ChatFsm() +{ + int rt; + int i; + char temp_str[1024]; + struct PPPChatSession *ssm_ptr; + + if( !gg.link_enable && !register_link() ) + { + smpp_send_ascout("Try to connect to WXC2 HLR fail\n"); + printf("Try to connect to WXC2 HLR fail\n"); + return; + } + //sprintf(debugBuf,); + //smpp_send_ascout("The session id is in used!\n"); + + for( i = 0 ;i < MAX_GAME_SESSION ; i++) + { + ssm_ptr = &ssm_data[i]; + if( ssm_ptr->flag == 0 ) + { + continue; + } + switch( ssm_ptr->ssm_state ) + { + case 0: + continue; + case 1: + sprintf(temp_str, "\33[32mPPP Chat recv PSSR MO:%s MT:%s \nFsm state :% d sid : %d\33[0m\n" + , ssm_ptr->ssm_state , i , ssm_data[i].msisdn , ssm_data[i].mt_msisdn ); + smpp_send_ascout(temp_str); + sprintf( ssm_ptr->shmsg ," Mobile Phone request to chat with you: 1 : Accept ;\n2 : Reject:\n "); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 2; + break; + case 2: + switch( ssm_ptr->us_prm ) + { + case US_IDLE: + break; + case US_RELER: + break; + case US_USSRC: + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + if( strlen(ssm_ptr->shmsg) != 4 ) + { + sprintf(temp_str, "\33[32mThe input string length is not 4.\33[0m\n"); + smpp_send_ascout(temp_str); + return; + } + if( !CheckInput( ssm_ptr->input ) ) + { + sprintf( ssm_ptr->shmsg ,"Input is Error! Please input four difference numbers.\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + } + rt = GuessNumber( ssm_ptr->input , ssm_ptr->seed ) & 0xFF ; + ssm_ptr->count ++; + if( ssm_ptr->count >= 8 ) + { + sprintf ( ssm_ptr->shmsg ,"Game Over!\n"); + sprintf ( temp_str , "NO%d:%d%d%d%d ",ssm_ptr->count , ssm_ptr->input[0],ssm_ptr->input[1],ssm_ptr->input[2],ssm_ptr->input[3]); + strcat ( ssm_ptr->history , temp_str ); + sprintf ( temp_str , "->%dA%dB\n" , rt>>4 , rt&0x0F); + strcat ( ssm_ptr->history , temp_str ); + //strcat ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 3; + ssm_ptr->us_prm = US_IDLE; + return ; + } + sprintf( temp_str , "NO%d:%d%d%d%d ",ssm_ptr->count , ssm_ptr->input[0],ssm_ptr->input[1],ssm_ptr->input[2],ssm_ptr->input[3]); + if( rt != 0x40 ) + { + strcat ( ssm_ptr->history , temp_str ); + sprintf( temp_str , "->%dA%dB\n" , rt>>4 , rt&0x0F); + strcat ( ssm_ptr->history , temp_str ); + strcpy ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->us_prm = US_IDLE; + } + else + { + strcat ( ssm_ptr->history , temp_str ); + sprintf( temp_str , "->%dA%dB\n" , rt>>4 , rt&0x0F); + strcat ( ssm_ptr->history , temp_str ); + strcpy ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 3; + ssm_ptr->us_prm = US_IDLE; + } + break; + } + break; + case 3: + if( ssm_ptr->us_prm == US_USSNC ) + { + switch( ssm_ptr->count ) + { + case 1: + sprintf ( ssm_ptr->shmsg ," So Luck!\n"); + break; + case 2: + sprintf ( ssm_ptr->shmsg ," Luck\n"); + break; + case 3: + sprintf ( ssm_ptr->shmsg ," Perfect\n"); + break; + case 4: + sprintf ( ssm_ptr->shmsg ," Very Good\n"); + break; + case 5: + sprintf ( ssm_ptr->shmsg ," Good\n"); + break; + case 6: + case 7: + case 8: + sprintf ( ssm_ptr->shmsg ," Correct\n"); + break; + default: + strcpy ( ssm_ptr->shmsg , ssm_ptr->history ); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 4; + return; + break; + } + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 4; + } + case 4: + if( ssm_ptr->us_prm == US_USSNC ) + { + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + sprintf( ssm_ptr->shmsg ," Guess Number\n1 . Restart game \n 2 . exit\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + ssm_ptr->ssm_state = 5; + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + } + break; + case 5: + if( ssm_ptr->us_prm == US_USSNC ) + { + if( ssm_ptr->shmsg[0] == '1' ) + { + if( !RandomNum( ssm_ptr->seed ) ) + { + //"Create random number fail" + return; + } + sprintf( ssm_ptr->shmsg ," Game Restart.input four difference numbers: \n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSRR ); + ssm_ptr->ssm_state = 2; + } + else if( ssm_ptr->shmsg[0] == '2' ) + { + sprintf( ssm_ptr->shmsg ," Game Exit.GoodBye! Wellcome to use WXC2 system!\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + ssm_ptr->ssm_state = 0; + ssm_ptr->flag = 0; + } + else + { + sprintf( ssm_ptr->shmsg ," Unexpeced menu selection!\n"); + SendMsgToSMPP( i ,ssm_ptr->shmsg , USSNR ); + } + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + } + break; + case 6: + if( gg.link_enable ) + { + sprintf(temp_str, "\33[32mGame Fsm state :% d sid : %d\33[0m\n" , ssm_ptr->ssm_state , i); + smpp_send_ascout(temp_str); + if( !RandomNum( ssm_ptr->seed ) ) + { + //"Create random number fail" + return; + } + sprintf( ssm_ptr->shmsg ," WellCome to WXC2 Online Guess Number Game System!\n Please input you guess nubmer:\n"); + SendMsgToSMPP( i+MAX_GAME_SESSION ,ssm_ptr->shmsg , USSRR ); + sprintf(temp_str , "\n\n\33[32mSend Game Info :\n%s\33[0m\n\n" , ssm_ptr->shmsg ); + smpp_send_ascout(temp_str); + ssm_ptr->ssm_state = 2; + } + break; + } + } +} + diff --git a/plat/snmp/Makefile b/plat/snmp/Makefile new file mode 100644 index 0000000..b7a96f5 --- /dev/null +++ b/plat/snmp/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = snmp +TYPE = plat + +DBUG_FLAGS_ADD = -D_CDMA_SNMP +RELS_FLAGS_ADD = -D_CDMA_SNMP + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/snmp/src/heartbeat.c b/plat/snmp/src/heartbeat.c new file mode 100644 index 0000000..aa880c1 --- /dev/null +++ b/plat/snmp/src/heartbeat.c @@ -0,0 +1,315 @@ +/*****************************************************/ +/*Title: heartbeat.c */ +/*Descr: Generate flatform's heartbeart */ +/*Author: Liang Hanxi */ +/*Create: 2002-06-24 */ +/*Modify: */ +/*****************************************************/ +#include "./include/heartbeat.h" + +// fix multiple definition==================================== +DWORD ExistIP[64]; +DWORD ExistIPNum; +// + +heartbeat_shm *HbShm=NULL; +static DWORD ObjID[20]=FLATFORM_HB_OID; +static snmp_addr HBAddr; +static BYTE InitOnce=0; +static DWORD latestAlmCmp=0; +static BYTE latestAlmCod=0; + + +static void send_alarm(); +static void send_heartbeat(); + +void heartbeat_init(u_short sys_id) +{ + int shmid; + struct shmid_ds shm_info; + + if(InitOnce == 0) + { + ExistIPNum = 0; + HBAddr.local_port = HBAddr.remote_port = HB_PORT; + HBAddr.remote_ip = inet_addr(HB_IP); + HBAddr.broadcast = 1; + sysctrl_init(); + } + + if(HbShm==NULL) + { + /*open share memory*/ + if((shmid=shmget(HEARTBEAT_SHM_KEY+wxc2_get_shm_offset(), + sizeof(heartbeat_shm),HEARTBEAT_SHM_PERM))==-1) + { + if((shmid=shmget(HEARTBEAT_SHM_KEY+wxc2_get_shm_offset(), + sizeof(heartbeat_shm),HEARTBEAT_SHM_PERM|IPC_CREAT))==-1) + { + printf("fail to open share memory"); + exit(1); + } + } + if((HbShm=(heartbeat_shm *)shmat(shmid,0,0))==(heartbeat_shm *)-1) + { + printf("fail to attach share memory"); + exit(1); + } + + shmctl(shmid,IPC_STAT,&shm_info); + if(shm_info.shm_nattch==1) + { + memset(HbShm,0,sizeof(heartbeat_shm)); + HbShm->msg.sys_id=0xFF; + HbShm->msg.subsys_id=0xFF; + } + } + + if((sys_id & 0xFF)!=0xFF) + { + HbShm->msg.sys_id =HbShm->sys_id=sys_id>>8; + HbShm->msg.subsys_id =HbShm->subsys_id=sys_id & 0xFF; + snmp_debug_hb(2); + } + + InitOnce=1; +} + +void heartbeat_timer() //called per 20ms +{ + static time_t l_oldtime = 0,l_time; + static int counter=0; + + l_time = time(NULL); + + if(l_time - l_oldtime >= 10) + counter = 500; + + system_report(); + switch(counter) + { + case 500: + + send_heartbeat(); + counter=0; + l_oldtime = l_time; + break; + default: + + if(HbShm->alarm_num >0) + { + //system_report(); + send_alarm(); + counter=0; + } + else + counter++; + break; + } +} + + +void send_heartbeat() +{ + int i; + short len,msglen=0; + snmp_pdu pdu; + u_long curtime; + curtime=htonl(time(NULL)); + memcpy(HbShm->msg.timestamp,(BYTE *)&curtime,4); + for(i=0;i<8;i++) + HbShm->msg.led_color[i]=(HbShm->led[2*i]<<4) | HbShm->led[2*i+1]; + + for(i=0;imsg.info[msglen++]=0; +#endif + HbShm->msg.info[msglen++]=i; + len=HbShm->component[i].status_len; +#if _CDMA_SNMP + HbShm->msg.info[msglen++]=len >> 8; +#endif + HbShm->msg.info[msglen++]=len & 255; + memcpy(HbShm->msg.info+msglen,HbShm->component[i].status,len); + msglen+=len; + } +#if _CDMA_SNMP + HbShm->msg.length[0] = msglen >> 8; + HbShm->msg.length[1] = msglen & 255; + msglen++; + msglen+=19; +#else + HbShm->msg.length =msglen; + msglen+=18; +#endif + +#if _CDMA_SNMP +/* daniel modify on 2005-7-24 */ + HbShm->msg.component_id[0]=latestAlmCmp >> 8; + HbShm->msg.component_id[1]=latestAlmCmp & 255; +/* daniel modify on 2005-7-24 */ +#else + HbShm->msg.component_id=latestAlmCmp; +#endif + HbShm->msg.alarm_code =latestAlmCod; + /*send out---->*/ + pdu.error_index =pdu.error_status =0; + pdu.pdu_type =PDU_TRAP; + pdu.request_id =0; + memcpy(pdu.var[0].msg,(BYTE *)&HbShm->msg,msglen); + pdu.var_num=1; + pdu.var[0].msglen =msglen; + pdu.var[0].vartype =4; + memcpy(pdu.var[0].oid,ObjID,14*sizeof(DWORD)); + pdu.var[0].oidlen =14; + + HBAddr.local_port =HBAddr.remote_port =HB_PORT; + HBAddr.remote_ip =inet_addr(HB_IP); + + for(i = 0; i < ExistIPNum; i++) + { + HBAddr.remote_ip = ExistIP[i]; + HBAddr.broadcast = 0; + snmp_plat_send(&pdu, &HBAddr); + } +} + +void send_alarm() +{ + int i; + short len,msglen=0; + snmp_pdu pdu; + u_long curtime; + curtime=htonl(time(NULL)); + memcpy(HbShm->msg.timestamp,(BYTE *)&curtime,4); + for(i=0;i<8;i++) + HbShm->msg.led_color[i]=(HbShm->led[2*i]<<4) | HbShm->led[2*i+1]; + + if(HbShm->alarm_num<=0) + return; + + for(i=0;ialarm[i].flag) + { +#if _CDMA_SNMP + HbShm->msg.component_id[0] = i >> 8; + HbShm->msg.component_id[1] = i & 255; +#else + HbShm->msg.component_id= i; +#endif + HbShm->msg.alarm_code =HbShm->alarm[i].alarm_code; + + HbShm->alarm[i].flag =0; + +/* daniel add on 2005-7-24 */ + latestAlmCmp = i; + latestAlmCod = HbShm->msg.alarm_code; +/* daniel add on 2005-7-24 */ + break; + } + } + + for(i=0;imsg.info[msglen++]=0; +#endif + HbShm->msg.info[msglen++]=i; + len=HbShm->component[i].status_len; +#if _CDMA_SNMP + HbShm->msg.info[msglen++]=len >> 8; +#endif + HbShm->msg.info[msglen++]=len&255; + memcpy(HbShm->msg.info+msglen,HbShm->component[i].status,len); + msglen+=len; + } + +#if _CDMA_SNMP + HbShm->msg.length[0] = msglen >> 8; + HbShm->msg.length[1] = msglen & 255; + msglen++; + msglen+=19; +#else + HbShm->msg.length =msglen; + msglen+=18; +#endif + + if(HbShm->alarm_num >=1) + HbShm->alarm_num--; + + /*send out---->*/ + pdu.error_index =pdu.error_status =0; + pdu.pdu_type =PDU_TRAP; + pdu.request_id =0; + memcpy(pdu.var[0].msg,(BYTE *)&HbShm->msg,msglen); + pdu.var_num=1; + pdu.var[0].msglen =msglen; + pdu.var[0].vartype =4; + memcpy(pdu.var[0].oid,ObjID,14*sizeof(DWORD)); + pdu.var[0].oidlen =14; + + HBAddr.local_port = 4950; /* to test if 4950 works */ + HBAddr.remote_port =HB_PORT; + HBAddr.remote_ip =inet_addr(HB_IP); + + for(i = 0; i < ExistIPNum; i++) + { + HBAddr.broadcast = 0; + HBAddr.remote_ip = ExistIP[i]; + + snmp_plat_send(&pdu, &HBAddr); + } +} + + +void set_led(BYTE nled,BYTE ncolor) +{ + if(HbShm==NULL) + heartbeat_init(0xFF); + HbShm->led[nled]=ncolor; +} + +void set_alarm(WORD component_id,BYTE alarm_code) +{ + if(HbShm==NULL) + heartbeat_init(0xFF); + if(component_id>ALARM_COMPONENT_NUM) + { + snmp_debug(SNMPDB_ALARM | SNMPDB_ERR, "Fail to send Alarm:No Such component id(%d)",component_id); + return; + } + snmp_debug(SNMPDB_ALARM, "set alarm.component id=%d,alarm_code=%d",component_id,alarm_code); + + if(HbShm->alarm[component_id].alarm_code !=alarm_code) + { + HbShm->alarm[component_id].flag=1; + HbShm->alarm_num ++; + } + HbShm->alarm[component_id].alarm_code =alarm_code; +} + +void set_status(BYTE component_id,int info_len,BYTE *info) +{ + if(HbShm == NULL) + heartbeat_init(0xFF); + + if(component_id > COMPONENT_NUM) + { + snmp_debug(SNMPDB_ERR, "Fail to set status of component %d:No Such component id",component_id); + return; + } + /* + if(info_len>=256) + { + snmp_debug(SNMPDB_ERR, "Fail to set status of component %d:the length(%d) of status part exceed limit(256Byte)",component_id,info_len); + return; + }*/ + if(info_len > 512) + info_len=512; + HbShm->component[component_id].status_len =info_len; + memcpy(HbShm->component[component_id].status,info,info_len); +} + + diff --git a/plat/snmp/src/include/heartbeat.h b/plat/snmp/src/include/heartbeat.h new file mode 100644 index 0000000..c0f435f --- /dev/null +++ b/plat/snmp/src/include/heartbeat.h @@ -0,0 +1,88 @@ +/*************************************************/ +/*Title: heartbeat.h */ +/*Descr: heartbeat processor(Head File) */ +/*Author: Liang Hanxi */ +/*Create: 2002-4-5 */ +/*Modify: 2002-6-25 */ +/*************************************************/ +#ifndef __HEART_BEAT__H +#define __HEART_BEAT__H + +#include "snmp.h" +#include "time.h" +#include "sysctrl.h" + + +#define HEARTBEAT_SHM_KEY 0x00112233 +#define HEARTBEAT_SHM_PERM 0666 +#define COMPONENT_NUM 10 +#define ALARM_COMPONENT_NUM 1024 +#define LED_NUM 16 + +#define FLATFORM_HB_OID {1,3,6,1,4,1,1373,2,3,2,0} +#define FLATFORM_HB_OIDLEN 11 + +#define HB_PORT 4957 +#define HB_IP "172.18.255.255" +#define INFO_LEN 1024 + +#define MasterSubSysID 0 +#define MasterSysID 0 + +// fix multiple definition==================================== +extern DWORD ExistIP[64]; +extern DWORD ExistIPNum; +// + +typedef struct component_buf{ + BOOL flag; + BYTE alarm_code; + int status_len; + BYTE status[512]; +}component_buf; + +typedef struct alarm_buf{ + BOOL flag; + BYTE alarm_code; +}alarm_buf; + +typedef struct heartbeat_msg{ + BYTE sys_id; + BYTE subsys_id; + BYTE timestamp[4]; + BYTE led_color[8]; +#if _CDMA_SNMP + BYTE component_id[2]; +#else + BYTE component_id; +#endif + BYTE alarm_code; +#if _CDMA_SNMP + BYTE length[2]; +#else + BYTE reserved; + BYTE length; +#endif + BYTE info[INFO_LEN]; +}heartbeat_msg; + +typedef struct heartbeat_shm{ + BYTE sys_id; + BYTE subsys_id; + BYTE led[LED_NUM]; + component_buf component[COMPONENT_NUM]; + alarm_buf alarm[ALARM_COMPONENT_NUM]; + BYTE alarm_num; + heartbeat_msg msg; +}heartbeat_shm; + +void set_led(BYTE nled,BYTE ncolor); +void set_alarm(WORD component_id,BYTE alarm_code); +void set_status(BYTE component_id,int info_len,BYTE *info); +void heartbeat_init(u_short sys_id); +void heartbeat_timer(); + +#endif + + + diff --git a/plat/snmp/src/include/macro.h b/plat/snmp/src/include/macro.h new file mode 100644 index 0000000..6319c80 --- /dev/null +++ b/plat/snmp/src/include/macro.h @@ -0,0 +1,100 @@ +#ifndef _SNMP_MACRO_H +#define _SNMP_MACRO_H + +#define SyntaxInteger 0x02 +#define SyntaxOctetString 0x04 +#define SyntaxIpAddress 0x40 +#define SyntaxCounter 0x41 +#define SyntaxTimeTicks 0x43 +#define SyntaxOpaque 0x44 + +#define Create_Object_Cloumn 1 +#define Create_Sub_Object_Command 1 + +#define GET_NULL() do { \ + *pdata = 0; \ + *vartype = SyntaxInteger; \ + datalen = 1; \ +} while(0) + +#define GET_INTEGER(integer) do { \ + *((int *)pdata) = htonl(integer); \ + *vartype = SyntaxInteger; \ + datalen = 4; \ +} while(0) + +#define SET_INTEGER(integer) do { \ + int i; \ + if(datalen > 4) \ + return -1; \ + for(i = 0, integer = 0; i < datalen; i++) \ + { \ + integer = integer << 8; \ + integer += pdata[i]; \ + } \ +} while(0) + +#define RETURN_INTEGER(integer) do { \ + int i; \ + if(datalen > 4) \ + datalen = 4; \ + for(i = 0; i < datalen; i++) \ + { \ + pdata[datalen-i-1] = ((u8 *)&integer)[i]; \ + } \ +} while(0) + +#undef GET_U8 /* undefine the "public" macro */ +#define GET_U8(byte) do { \ + *pdata = byte; \ + *vartype = SyntaxInteger; \ + datalen = 1; \ +} while(0) + +#define SET_U8(byte) do { \ + byte = pdata[datalen-1]; \ +} while(0) + +#define GET_STRING(string) do { \ + strcpy((char *)pdata, (char *)string); \ + *vartype = SyntaxOctetString; \ + datalen = strlen((char *)string); \ +} while(0) + +#define SET_STRING(string) do { \ + memcpy(string, pdata, datalen); \ + string[datalen] = 0; \ +} while(0) + +#define GET_OCTETSTRING(octets, count) do { \ + memcpy(pdata, octets, count); \ + *vartype = SyntaxOctetString; \ + datalen = count; \ +} while(0) + +#define SET_OCTETSTRING(octets, count) do { \ + memcpy(octets, pdata, count); \ +} while(0) + +#define GET_OPAQUE(octets, count) do { \ + memcpy(pdata, octets, count); \ + *vartype = SyntaxOpaque; \ + datalen = count; \ +} while(0) + +#define SET_OPAQUE(octets, count) do { \ + memcpy(octets, pdata, count); \ +} while(0) + +#define GET_IP(ip) do { \ + memcpy(pdata, ip, 4); \ + *vartype = SyntaxIpAddress; \ + datalen = 4; \ +} while(0) + +#define SET_IP(ip) do { \ + memcpy(ip, pdata, 4); \ +} while(0) + +#endif + diff --git a/plat/snmp/src/include/snmp.h b/plat/snmp/src/include/snmp.h new file mode 100644 index 0000000..a043fef --- /dev/null +++ b/plat/snmp/src/include/snmp.h @@ -0,0 +1,415 @@ +/*************************************************/ +/*Title: snmp.h */ +/*Descr: SNMP Agent(Head File) */ +/*Author: Liang Hanxi */ +/*Create: 2002-4-1 */ +/*Modify: 2002-6-25 */ +/*************************************************/ + +#ifndef _SNMP_HEAD_FILE +#define _SNMP_HEAD_FILE +#include "../../../debug/src/include/debug.h" +#include "../../../iptrans/src/include/iptrans.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_ENGINE 16 + +#define SNMP_DEBUG_MASK 0 +#define SNMP_DEBUG_LOG 0 + +#define SNMP_VERSION {1, 0, 01} +#define SNMP_V1 0 +#define SNMP_V2 1 +#define SNMP_V3 3 +#define COMMUNITY "public" +#define SNMP_ANY_COMMUNITY 0 //Should be set to 1 if snmp module is invoked in OMC +#define BIND_MAX 50 +#define OID_MAXLEN 32 +//#define FIX_OID {0x2b,0x06,0x01,0x04,0x01,0x8a,0x5d,0x01,0x01} +#define FIX_OID {1,3,6,1,4,1,1373,1,3} +//{iso(1).org(3).dod(6).internet(1).private(4).enterprises(1).interWAVE(1373).1.1} +#define FIX_OIDLEN 8 +#define SNMP_OID {1,3,6,1,4,1,1373,1,3,2,3,3} +#define SNMP_OIDLEN 12 + +typedef enum usmStats +{ + UnsupportedSecLevels = 1, + NotInTimeWindows, + UnknownUserNames, + UnknownEngineIDs, + WrongDigests, + DecryptionErrors +}usmstatsErrors; + +#define HEAP_SIZE 500*1024 +#define SNMP_PORT 4957 +#define SNMP_VAR_MAX 1600 +//PDU +#define PDU_GET 0 +#define PDU_GETNEXT 1 +#define PDU_RSP 2 +#define PDU_SET 3 +#define PDU_GETBULK 5 +#define PDU_INFORM 6 +#define PDU_TRAP 7 +#define PDU_REPORT 8 +//variable type +#define NoSuchObject 0x80 +#define NosuchInstance 0x81 +#define EndOfMibView 0x82 + +//Debug +#define SNMPDB_IN 0x00 +#define SNMPDB_OUT 0x01 +#define SNMPDB_ERR 0x02 +#define SNMPDB_NOREG 0x04 +#define SNMPDB_VALUE 0x10 +#define SNMPDB_ALARM 0x20 +#define SNMPDB_MIB 0x40 +#define SNMPDB_SYS 0x80 + +#ifndef _T_BYTE +#define _T_BYTE + typedef unsigned char BYTE; +#endif + +#ifndef _T_BOOL +#define _T_BOOL + typedef unsigned char BOOL; +#endif + +#ifndef _T_DWORD +#define _T_DWORD + typedef unsigned int DWORD; +#endif + +#ifndef _T_WORD +#define _T_WORD + typedef unsigned short WORD; +#endif + +extern char SnmpVer[16]; + +typedef struct var_list{ + DWORD oid[OID_MAXLEN]; + BYTE oidlen; + BYTE vartype; + short msglen; + BYTE msg[SNMP_VAR_MAX]; +}var_list; + +typedef struct _HeaderData +{ + DWORD seqFlag; + DWORD msgID; //INTEGER (0..2147483647), + DWORD msgMaxSize; //INTEGER (484..2147483647), + char msgFlags;// OCTET STRING (SIZE(1)), + // .... ...1 authFlag + // .... ..1. privFlag + // .... .1.. reportableFlag + DWORD msgSecurityModel;// INTEGER (1..2147483647) +}HeaderData; + +typedef struct _ScopedPDU +{ + DWORD seqFlag; + char contextEngineID[32]; + char contextName[32]; +// snmp_pdu data; +}ScopedPDU; + +typedef struct _ScopedPduData +{ + DWORD optFlag; + ScopedPDU plaintext; + char encryptedPDU[SNMP_VAR_MAX];// OCTET STRING -- encrypted scopedPDU value +}ScopedPduData; + +typedef struct _UsmSecurityParameters +{ //global User-based security parameters + DWORD seqFlag; + char msgAuthoritativeEngineID[32]; + DWORD msgAuthoritativeEngineBoots;// INTEGER (0..2147483647), + DWORD msgAuthoritativeEngineTime;// INTEGER (0..2147483647), + char msgUserName[32];//OCTET STRING (SIZE(0..32)), + char msgAuthenticationParameters[32];//-- authentication protocol specific parameters + char msgPrivacyParameters[16];//-- privacy protocol specific parameters +}UsmSecurityParameters; + +typedef struct _SNMPv3Message +{ + DWORD seqFlag; + DWORD msgVersion; //INTEGER ( 0 .. 2147483647 ), + HeaderData msgGlobalData; + char msgSecurityParameters[128]; + ScopedPduData msgData; +}SNMPv3Message; + +typedef struct snmp_pdu //protocol data unit +{ + BYTE pdu_type; //0-get request 2-get(set) respond 3-set request 7-trap + DWORD request_id; + char community[16]; + BYTE var_num; + var_list var[BIND_MAX]; + BYTE error_status; //0:no error 1:too big 2:nosuchname 3:badvalue 4:readonly 5:generr + BYTE error_index; + //add by yizane start + DWORD non_repeaters; //in getbulk replace error_status + DWORD max_repetitions; //in getbulk replace error_index + //add by yizane end +//v3 + DWORD msgVersion; //INTEGER ( 0 .. 2147483647 ), + HeaderData msgGlobalData; + UsmSecurityParameters msgSecurityParameters; + ScopedPduData msgData; +} snmp_pdu; + +typedef struct _snmpV3SecurityPara +{ + char engineType;//1=client, 0=server, 2=internal mss to ems; + char securityEngineID[32]; + char securityUserName[32]; + char contextName[32]; + char contextEngineID[32]; + BYTE securityLevel;//0 no-auth&no-pri, 1auth&no-pri, 3 auth&pri + BYTE authProtocol; + char authPassword[32]; + BYTE authKey[16]; + BYTE privacyProtocol; + char privacyPassword[32]; + BYTE privacyKey[16]; + DWORD boots; + DWORD authInTime; + DWORD remote_ip; + WORD remote_port; + char admin_state; +}snmpV3SecurityPara; + + +typedef struct snmp_addr +{ + DWORD remote_ip; + DWORD local_ip; + WORD remote_port; + WORD local_port; + BYTE broadcast; +} snmp_addr; + +typedef struct snmp_msg +{ + snmp_addr addr; + message_list msglist; +}snmp_msg; + +typedef struct snmp_buf +{ + snmp_msg msgout[256]; + BYTE readsub, writesub; +}snmp_buf; + +//snmp_buf snmp_outbuf; + +typedef struct snmp_filter +{ + BYTE flag; + BYTE type; + BYTE oidlen; + DWORD ip; + DWORD oid[OID_MAXLEN]; + short local_port; + short remote_port; + + +}snmp_filter; + +#define MAX_SNMP_RECORD 32 +#define SNMP_SHM_KEY 0x60000001 +#define SNMP_SHM_PERM 0666 + +typedef struct snmp_log_info +{ + BYTE currentNo; /*from 0-MAX_SNMP_RECORD-1 */ + char log_info[MAX_SNMP_RECORD][512]; +}snmp_log_info; + + +/*---------------------------------------*/ +typedef void (*trapcall)(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD len,snmp_addr *addr); +typedef int (*setcall)(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD len); +typedef int (*getcall)(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +//add by yizane start +typedef int (*getnextcall)(BYTE in_oidlen, DWORD *in_oid, BYTE *oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +//add by yizane end +typedef void (*rspcall)(snmp_pdu *pdu,snmp_addr *addr); +typedef int (*snmpcall)(snmp_pdu *pdu,snmp_addr *addr); + +typedef struct mib_nod{ + DWORD id; + trapcall trap_proc; + setcall set_proc; + getcall get_proc; + //add by yizane start + getnextcall getnext_proc; + //add by yizane end + rspcall rsp_proc; + snmpcall snmp_proc; + struct mib_nod *pnext; + struct mib_nod *psub; +}mib_nod; + +typedef struct snmp_csta{ + DWORD timestamp; + DWORD trap_in; + DWORD trap_out; + DWORD set_in; + DWORD set_out; + DWORD get_in; + DWORD get_out; + //add by yizane start + DWORD getnext_in; + DWORD getnext_out; + DWORD getbulk_in; + DWORD getbulk_out; + //add by yizane end + DWORD rsp_in; + DWORD rsp_out; + DWORD fail_parse; + DWORD not_register; + DWORD fail_build; +}snmp_csta; + +typedef struct snmp_mib{ + BYTE sysid[2]; + BYTE setpasswd[10]; + BYTE getpasswd[10]; + DWORD set_oid[64][20]; + DWORD get_oid[64][20]; + DWORD trap_oid[64][20]; + DWORD rsp_oid[64][20]; +}snmp_mib; + +/********************************************************************/ +/* Macros For ASN.1 Encoding */ +/********************************************************************/ +#define insert_length(buf,pos,len) {\ + if(len<0)\ + {\ + snmp_debug(SNMPDB_ERR,"length should be larger than zero.");\ + return 0;\ + }\ + else if(len<0x80)\ + *(buf+pos--)=len;\ + else if(len<0x100)\ + {\ + *(buf+pos--)=len;\ + *(buf+pos--)=0x81;\ + }\ + else if(len<1600)\ + {\ + *(buf+pos--)=len & 0xFF;\ + *(buf+pos--)=len >>8;\ + *(buf+pos--)=0x82;\ + }\ + else\ + {\ + snmp_debug(SNMPDB_ERR,"Length(%d) exceed limit.varindex=%d",len,var_num);\ + return 0;\ + }\ +} + +#define enc_integer(buf,pos,val) {\ + if(val<0)\ + {\ + snmp_debug(SNMPDB_ERR,"integer should larger than zero.val=%d",val);\ + return -1;\ + }\ + else if(val<0x80)\ + {\ + *(buf+pos--)=(BYTE)val;\ + *(buf+pos--)=1;\ + }\ + else if(val<0x8000)\ + {\ + *(buf+pos--)=val & 0xFF;\ + *(buf+pos--)=val>>8;\ + *(buf+pos--)=2;\ + }\ + else if(val<0x800000)\ + {\ + *(buf+pos--)= val & 0xFF;\ + *(buf+pos--)=(val & 0xFFFF)>>8;\ + *(buf+pos--)=val>>16;\ + *(buf+pos--)=3;\ + }\ + else if(val<0x80000000)\ + {\ + *(buf+pos--)= val & 0xFF;\ + *(buf+pos--)=(val & 0xFFFF)>>8;\ + *(buf+pos--)=(val & 0xFFFFFF)>>16;\ + *(buf+pos--)=val>>24;\ + *(buf+pos--)=4;\ + }\ + else if(val<0xFFFFFFFF)\ + {\ + *(buf+pos--)= val & 0xFF;\ + *(buf+pos--)=(val & 0xFFFF)>>8;\ + *(buf+pos--)=(val & 0xFFFFFF)>>16;\ + *(buf+pos--)=val>>24;\ + *(buf+pos--)=0;\ + *(buf+pos--)=5;\ + }\ + else\ + {\ + snmp_debug(SNMPDB_ERR,"Integer's value exceed limit.val=%d",val);\ + return -1;\ + }\ +} + +void snmp_init(WORD nport); +void snmpmib_init(); +void snmp_timer(); +int snmp_send(snmp_pdu *msgbuf,snmp_addr *addr); +int snmp_plat_send(snmp_pdu *msgbuf,snmp_addr *addr); +int snmp_receive(snmp_pdu *msgbuf,snmp_addr *addr); +int get_response(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +int set_response(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD datalen); +//add by yizane start +int getnext_response(BYTE pr_oidlen, DWORD *pre_oid, BYTE *oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +//add by yizane end +void inquire_trapmsg(trapcall trap_proc); +void inquire_setmsg(BYTE oidlen,DWORD *oid,setcall set_proc); +void inquire_getmsg(BYTE oidlen,DWORD *oid,getcall get_proc); +void inquire_rspmsg(BYTE oidlen,DWORD *oid,rspcall rsp_proc); +void inquire_snmpmsg(BYTE oidlen,DWORD *oid,snmpcall snmp_proc); +//add by yizane start +void inquire_getnextmsg(BYTE oidlen,DWORD *oid,getnextcall getnext_proc); +//add by yizane end +void rob_trapmsg(BYTE oidlen,DWORD *oid,trapcall trap_proc); +BYTE encode_integer(BYTE *buf,DWORD val); +DWORD decode_integer(BYTE *buf,BYTE len); +void snmp_log(char *info); +void snmp_debug(DWORD mask, const char *fmt,...); +void snmp_showbuf(DWORD mask, BYTE *buf, int len); +void snmp_logmsg(DWORD mask, snmp_pdu *pdu, snmp_addr *addr); +void snmp_debug_setup(); +void snmp_debug_timer(); +void snmp_debug_csta(BYTE npage,int instance); +void snmp_debug_hb(BYTE npage); +void snmp_init_serial_number(char *Serial); +void snmp_set_timenosync();//call of this function will tell snmp module do not sync the omc time + +#include "table.h" + +/********************************************************************/ +#endif + diff --git a/plat/snmp/src/include/snmpv3AuthCry.h b/plat/snmp/src/include/snmpv3AuthCry.h new file mode 100644 index 0000000..77b0a0e --- /dev/null +++ b/plat/snmp/src/include/snmpv3AuthCry.h @@ -0,0 +1,77 @@ + +#ifndef snmpv3authcryp_h +#define snmpv3authcryp_h + +#include "../../../../plat/public/src/include/public.h" + + +#define AUTH_KEY_LEN 16 +#define MD5_DIGEST_90_LEN 12 + + + extern int snmpV3AuthenticateOutgoingMsg + (/* result >0:success,else fail */ + u8 *inAuthKey, /*secret key for authentication*/ + u16 inAuthKeyLen, + u8 *inWholeMsg, /* unauthenticated complete message*/ + u16 inWholeMsgLen, + u8 *outAuthParameters, /* authenticationParamemeter */ + u16 *outAuthParametersLen + ); + + + extern int snmpV3AuthenticateIncomingMsg + (/* result >0:success,else fail */ + u8 *inAuthKey, /*secret key for authentication*/ + u16 inAuthKeyLen, + u8 *inWholeMsg, /* as received on the wire*/ + u16 inWholeMsgLen, + u8 *inAuthParameters, /* as received on the wire*/ + u16 inAuthParametersLen + ); + + + extern int snmpV3EncryptData + (/* result >0:success,else fail */ + u8 *inEncryptKey, /* secret key for encryption*/ + u16 inEncryptKeyLen, + u8 *inDataToEncrypt, /* data to encrypt (scopedPDU)*/ + u16 inDataToEncryptLen, + u8 *outEncryptedData, /* encrypted data (encryptedPDU)*/ + u16 *outEncryptedDataLen, + u8 *outPrivParameters, /* filled in by service provider*/ + u16 *outPrivParametersLen, + ulong runTime + ); + + + extern int snmpV3DecryptData + (/* result >0:success,else fail */ + u8 *inDecryptKey, /*secret key for decryption*/ + u16 inDecryptKeyLen, + u8 *inPrivParameters, /* as received on the wire*/ + u16 inPrivParametersLen, + u8 *inEncryptedData, /* encrypted data (encryptedPDU)*/ + u16 inEncryptedDataLen, + u8 *outDecryptedData, /*decrypted data (scopedPDU)*/ + u16 *outDecryptedDataLen + + ); + + +#endif + + + + + + + + + + + + + + + diff --git a/plat/snmp/src/include/sysctrl.h b/plat/snmp/src/include/sysctrl.h new file mode 100644 index 0000000..b9d5df2 --- /dev/null +++ b/plat/snmp/src/include/sysctrl.h @@ -0,0 +1,57 @@ +/*************************************************/ +/*Title: sysctrl.h */ +/*Descr: */ +/*Author: Liang Hanxi */ +/*Create: 2002-4-5 */ +/*Modify: 2002-6-25 */ +/*************************************************/ + +#ifndef __SYSCTRL__H +#define __SYSCTRL__H + +#include "time.h" +#include +#include +#include +#include +#include "heartbeat.h" + +#define SYS_T_report 50*60*1 //1min + +#define MAX_PARTITION_NUM 16 + +typedef struct partition +{ + char mountpoint_path[16]; + DWORD used_space; + DWORD total_space; +}partition; + +typedef struct hb_sysinfo{ + DWORD up_time; + BYTE idle_cpu_rate; + DWORD ram_total_used; + DWORD ram_total; + DWORD ram_swap_used; + DWORD ram_swap_total; + DWORD ram_buffers; + DWORD ram_cached; + BYTE pt_count; + partition pt[MAX_PARTITION_NUM]; +}hb_sysinfo; + +typedef struct mnt_list +{ + char mnt_fsname[50]; + char mnt_dir[50]; + DWORD total; + DWORD free; + DWORD limit; +}mnt_list; + +void sysctrl_init(); +void system_report(); +#endif + + + diff --git a/plat/snmp/src/include/table.h b/plat/snmp/src/include/table.h new file mode 100644 index 0000000..450cfe3 --- /dev/null +++ b/plat/snmp/src/include/table.h @@ -0,0 +1,42 @@ +#ifndef _SNMP_TABLE_H +#define _SNMP_TABLE_H + +#define MAX_COLUMNAR_OF_TABLE 48 + +typedef struct table_index { + u8 len; + u32 oid[32]; +} table_index; + +/* Get an exist instance from the inclusive one pointed to by address 'instance' */ +typedef int (*table_get_instance)(u32 *instance); +typedef int (*table_get_resp)(u32 column, u32 *instance, u8 *pdata, u8 *vartype); +typedef int (*table_set_resp)(u32 column, u32 *instance, u8 *pdata, u16 datalen); + +struct snmp_table_profile { + char name[32]; + table_index index; /* oid of table with entry exclusive */ + u32 column[MAX_COLUMNAR_OF_TABLE]; /* define all columns of a table, use '0' indicating the end */ + u8 level; /* level of instance in order to identify a row */ + table_get_instance get_instance; + table_get_resp get_resp; + table_set_resp set_resp; +}; + +struct snmp_register { + char name[32]; + u8 prefix_len; /* Module prefix len */ + u32 prefix_oid[32]; /* Module prefix oid */ + u8 num_of_table; /* how many tables being registered, such tables is pointed to by address 'table' */ + struct snmp_table_profile *table; + + /* In case no table is matched, default callback function is invoked if it is not NULL. Hence, + you can implement get/set in much the same way before, i.e. traveling all branches of MIB */ + getcall default_get_resp; + setcall default_set_resp; +}; + +extern int register_snmp_table(struct snmp_register *reg); + +#endif + diff --git a/plat/snmp/src/md5.c b/plat/snmp/src/md5.c new file mode 100644 index 0000000..ebe8b2d --- /dev/null +++ b/plat/snmp/src/md5.c @@ -0,0 +1,301 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to SQUID_MD5Init, call SQUID_MD5Update as + * needed on buffers full of bytes, and then call SQUID_MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' header + * definitions; now uses stuff from dpkg's config.h. + * - Ian Jackson . + * Still in the public domain. + * + * Changed SQUID_MD5Update to take a void * for easier use and some other + * minor cleanup. - Henrik Nordstrom . + * Still in the public domain. + * + * Prefixed all symbols with "Squid" so they don't collide with + * other libraries. Henrik Nordstrom . + * Still in the public domain. + */ + + +#include /* for memcpy() */ +#include /* for stupid systems */ +#include /* for ntohl() */ + +#include "md5.h" + +/* + * Now that we have several alternatives the MD5 files are + * passed in by default. But a header-selection decides whether + * this provided version is to be built. + * TODO: may obsolete the MSV #if below. + */ + + +void byteSwap(uint32_t * buf, unsigned words) +{ + uint8_t *p = (uint8_t *) buf; + + do { + *buf++ = (uint32_t) ((unsigned) p[3] << 8 | p[2]) << 16 | + ((unsigned) p[1] << 8 | p[0]); + p += 4; + } while (--words); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void SQUID_MD5Init(struct SquidMD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bytes[0] = 0; + ctx->bytes[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void SQUID_MD5Update(struct SquidMD5Context *ctx, const void *_buf, unsigned len) +{ + uint8_t const *buf = _buf; + uint32_t t; + + /* Update byte count */ + + t = ctx->bytes[0]; + if ((ctx->bytes[0] = t + len) < t) + ctx->bytes[1]++; /* Carry from low to high */ + + t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ + if (t > len) { + memcpy((uint8_t *) ctx->in + 64 - t, buf, len); + return; + } + /* First chunk is an odd size */ + memcpy((uint8_t *) ctx->in + 64 - t, buf, t); + byteSwap(ctx->in, 16); + SQUID_MD5Transform(ctx->buf, ctx->in); // Squid_MD5Transform(ctx->buf, ctx->in); + buf += t; + len -= t; + + /* Process data in 64-byte chunks */ + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteSwap(ctx->in, 16); + SQUID_MD5Transform(ctx->buf, ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void SQUID_MD5Final(unsigned char digest[16], struct SquidMD5Context *ctx) +{ + int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ + uint8_t *p = (uint8_t *) ctx->in + count; + + /* Set the first char of padding to 0x80. There is always room. */ + *p++ = 0x80; + + /* Bytes of padding needed to make 56 bytes (-8..55) */ + count = 56 - 1 - count; + + if (count < 0) { /* Padding forces an extra block */ + memset(p, 0, count + 8); + byteSwap(ctx->in, 16); + SQUID_MD5Transform(ctx->buf, ctx->in); + p = (uint8_t *) ctx->in; + count = 56; + } + memset(p, 0, count); + byteSwap(ctx->in, 14); + + /* Append length in bits and transform */ + ctx->in[14] = ctx->bytes[0] << 3; + ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; + SQUID_MD5Transform(ctx->buf, ctx->in); + + byteSwap(ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +void md5_calc(uint8_t *output, uint8_t *input, uint32_t inlen) +{ + SquidMD5_CTX context; + + SQUID_MD5Init(&context); + SQUID_MD5Update(&context, input, inlen); + SQUID_MD5Final(output, &context); +} + +void password_to_key_md5( + u_char *password, + u_int passwordlen, + u_char *engineID, + u_int engineLength, + u_char *key) + { + SquidMD5_CTX MD; + u_char *cp, password_buf[64]; + u_long password_index = 0; + u_long count = 0, i; + SQUID_MD5Init (&MD); /* initialize MD5 */ +/**********************************************/ +/* Use while loop until we've done 1 Megabyte */ +/**********************************************/ + while (count < 1048576) { + cp = password_buf; + for (i = 0; i < 64; i++) { +/*************************************************/ +/* Take the next octet of the password, wrapping */ +/* to the beginning of the password as necessary.*/ +/*************************************************/ + *cp++ = password[password_index++ % passwordlen]; + } + SQUID_MD5Update (&MD, password_buf, 64); + count += 64; + } + SQUID_MD5Final (key, &MD); /* tell MD5 we're done */ +/*****************************************************/ +/* Now localize the key with the engineID and pass */ +/* through MD5 to produce final key */ +/* May want to ensure that engineLength <= 32, */ +/* otherwise need to use a buffer larger than 64 */ +/*****************************************************/ + memcpy(password_buf, key, 16); + memcpy(password_buf+16, engineID, engineLength); + memcpy(password_buf+16+engineLength, key, 16); + SQUID_MD5Init(&MD); + SQUID_MD5Update(&MD, password_buf, 32+engineLength); + SQUID_MD5Final(key, &MD); + return; +} + + +//#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f,w,x,y,z,in,s) \ + (w += f(x,y,z) + in, w = (w<>(32-s)) + x) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. SQUID_MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void SQUID_MD5Transform(uint32_t buf[4], uint32_t const in[16]) +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} +//#endif /* !ASM_MD5 */ diff --git a/plat/snmp/src/md5.h b/plat/snmp/src/md5.h new file mode 100644 index 0000000..46500fd --- /dev/null +++ b/plat/snmp/src/md5.h @@ -0,0 +1,21 @@ +#ifndef SQUID_MD5_H +#define SQUID_MD5_H + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +typedef struct SquidMD5Context { + uint32_t buf[4]; + uint32_t bytes[2]; + uint32_t in[16]; +}SquidMD5_CTX; + +void SquidMD5Init(struct SquidMD5Context *context); +void SquidMD5Update(struct SquidMD5Context *context, const void *buf, unsigned len); +void SquidMD5Final(uint8_t digest[16], struct SquidMD5Context *context); +void SQUID_MD5Transform(uint32_t buf[4], uint32_t const in[16]); // void SquidMD5Transform(uint32_t buf[4], uint32_t const in[16]); + +#define SQUID_MD5_DIGEST_LENGTH 16 + +#endif /** SQUID_MD5_H */ diff --git a/plat/snmp/src/mib_parser/snmp_mib.c b/plat/snmp/src/mib_parser/snmp_mib.c new file mode 100644 index 0000000..ed4b26c --- /dev/null +++ b/plat/snmp/src/mib_parser/snmp_mib.c @@ -0,0 +1,4152 @@ +/*********************************************************************** +Copyright ?2007 LGC Wireless, Inc. All rights reserved +File Name: snmp_mib.h +Description: header file of snmp mib parser +Version: v9.0.0 +Author: Roy Jiang +Create Date: 2007-6-9 + +History: +2007-6-9 v9.0.0 Create + +BEWARE: Portions of this file are subject to the copyrights of + open-source project Net-SNMP. See the Net-SNMP's COPYING file + for more details +***********************************************************************/ +#include +#include +#include +#include +#include +#include "snmp_mib.h" + +//Macro definition---------------------------------------------------------------- +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define SYNTAX_MASK 0x80 +/* + * types of tokens + * Tokens wiht the SYNTAX_MASK bit set are syntax tokens + */ +#define CONTINUE -1 +#define ENDOFFILE 0 +#define LABEL 1 +#define SUBTREE 2 +#define SYNTAX 3 +#define OBJID (4 | SYNTAX_MASK) +#define OCTETSTR (5 | SYNTAX_MASK) +#define INTEGER (6 | SYNTAX_MASK) +#define NETADDR (7 | SYNTAX_MASK) +#define IPADDR (8 | SYNTAX_MASK) +#define COUNTER (9 | SYNTAX_MASK) +#define GAUGE (10 | SYNTAX_MASK) +#define TIMETICKS (11 | SYNTAX_MASK) +#define KW_OPAQUE (12 | SYNTAX_MASK) +#define NUL (13 | SYNTAX_MASK) +#define SEQUENCE 14 +#define OF 15 /* SEQUENCE OF */ +#define OBJTYPE 16 +#define ACCESS 17 +#define READONLY 18 +#define READWRITE 19 +#define WRITEONLY 20 +#ifdef NOACCESS +#undef NOACCESS /* agent 'NOACCESS' token */ +#endif +#define NOACCESS 21 +#define STATUS 22 +#define MANDATORY 23 +#define KW_OPTIONAL 24 +#define OBSOLETE 25 +/* + * #define RECOMMENDED 26 + */ +#define PUNCT 27 +#define EQUALS 28 +#define NUMBER 29 +#define LEFTBRACKET 30 +#define RIGHTBRACKET 31 +#define LEFTPAREN 32 +#define RIGHTPAREN 33 +#define COMMA 34 +#define DESCRIPTION 35 +#define QUOTESTRING 36 +#define INDEX 37 +#define DEFVAL 38 +#define DEPRECATED 39 +#define SIZE 40 +#define BITSTRING (41 | SYNTAX_MASK) +#define NSAPADDRESS (42 | SYNTAX_MASK) +#define COUNTER64 (43 | SYNTAX_MASK) +#define OBJGROUP 44 +#define NOTIFTYPE 45 +#define AUGMENTS 46 +#define COMPLIANCE 47 +#define READCREATE 48 +#define UNITS 49 +#define REFERENCE 50 +#define NUM_ENTRIES 51 +#define MODULEIDENTITY 52 +#define LASTUPDATED 53 +#define ORGANIZATION 54 +#define CONTACTINFO 55 +#define UINTEGER32 (56 | SYNTAX_MASK) +#define CURRENT 57 +#define DEFINITIONS 58 +#define END 59 +#define SEMI 60 +#define TRAPTYPE 61 +#define ENTERPRISE 62 +/* + * #define DISPLAYSTR (63 | SYNTAX_MASK) + */ +#define BEGIN 64 +#define IMPORTS 65 +#define EXPORTS 66 +#define ACCNOTIFY 67 +#define BAR 68 +#define RANGE 69 +#define CONVENTION 70 +#define DISPLAYHINT 71 +#define FROM 72 +#define AGENTCAP 73 +#define MACRO 74 +#define IMPLIED 75 +#define SUPPORTS 76 +#define INCLUDES 77 +#define VARIATION 78 +#define REVISION 79 +#define NOTIMPL 80 +#define OBJECTS 81 +#define NOTIFICATIONS 82 +#define MODULE 83 +#define MINACCESS 84 +#define PRODREL 85 +#define WRSYNTAX 86 +#define CREATEREQ 87 +#define NOTIFGROUP 88 +#define MANDATORYGROUPS 89 +#define GROUP 90 +#define OBJECT 91 +#define IDENTIFIER 92 +#define CHOICE 93 +#define LEFTSQBRACK 95 +#define RIGHTSQBRACK 96 +#define IMPLICIT 97 +#define APPSYNTAX (98 | SYNTAX_MASK) +#define OBJSYNTAX (99 | SYNTAX_MASK) +#define SIMPLESYNTAX (100 | SYNTAX_MASK) +#define OBJNAME (101 | SYNTAX_MASK) +#define NOTIFNAME (102 | SYNTAX_MASK) +#define VARIABLES 103 +#define UNSIGNED32 (104 | SYNTAX_MASK) +#define INTEGER32 (105 | SYNTAX_MASK) +#define OBJIDENTITY 106 + +#define MODULE_NOT_FOUND 0 +#define MODULE_LOADED_OK 1 +#define MODULE_ALREADY_LOADED 2 +#define MODULE_LOAD_FAILED MODULE_NOT_FOUND +//for hash table +#define HASHSIZE 32 +#define BUCKET(x) (x & (HASHSIZE-1)) + +#define NHASHSIZE 128 +#define NBUCKET(x) (x & (NHASHSIZE-1)) + +#define NUMBER_OF_ROOT_NODES 1 + +#define label_compare strcmp +#define SNMP_FREE(s) do { if (s) { free((void *)s); s=NULL; } } while(0) +/* + * Beware of reaching SYNTAX_MASK (0x80) + */ +//end of macro definition--------------------------------------------------------- + +//public var definition----------------------------------------------------------- +int mibLine = 0; +const char *File = "(none)"; + +/* + * A linked list of nodes. + */ +struct node { + struct node *next; + char *label; /* This node's (unique) textual name */ + unsigned int subid; /* This node's integer subidentifier */ + int modid; /* The module containing this node */ + char *parent; /* The parent's textual name */ + int tc_index; /* index into tclist (-1 if NA) */ + int type; /* The type of object this represents */ + int access; + int status; + struct enum_list *enums; /* (optional) list of enumerated integers */ + struct range_list *ranges; + struct index_list *indexes; + char *augments; + struct varbind_list *varbinds; + char *hint; + char *units; + char *description; /* description (a quoted string) */ + char *reference; /* references (a quoted string) */ + char *defaultValue; + char *filename; + int lineno; +}; + +struct tree *tree_head = NULL; +struct node *orphan_nodes = NULL; + +#define MAXTC 4096 +struct tc { /* textual conventions */ + int type; + int modid; + char *descriptor; + char *hint; + struct enum_list *enums; + struct range_list *ranges; + char *description; +} tclist[MAXTC]; + +struct tok { + const char *name; /* token name */ + int len; /* length not counting nul */ + int token; /* value */ + int hash; /* hash of name */ + struct tok *next; /* pointer to next in hash table */ +}; +static struct tok tokens[] = { + {"obsolete", sizeof("obsolete") - 1, OBSOLETE} + , + {"Opaque", sizeof("Opaque") - 1, KW_OPAQUE} + , + {"optional", sizeof("optional") - 1, KW_OPTIONAL} + , + {"LAST-UPDATED", sizeof("LAST-UPDATED") - 1, LASTUPDATED} + , + {"ORGANIZATION", sizeof("ORGANIZATION") - 1, ORGANIZATION} + , + {"CONTACT-INFO", sizeof("CONTACT-INFO") - 1, CONTACTINFO} + , + {"MODULE-IDENTITY", sizeof("MODULE-IDENTITY") - 1, MODULEIDENTITY} + , + {"MODULE-COMPLIANCE", sizeof("MODULE-COMPLIANCE") - 1, COMPLIANCE} + , + {"DEFINITIONS", sizeof("DEFINITIONS") - 1, DEFINITIONS} + , + {"END", sizeof("END") - 1, END} + , + {"AUGMENTS", sizeof("AUGMENTS") - 1, AUGMENTS} + , + {"not-accessible", sizeof("not-accessible") - 1, NOACCESS} + , + {"write-only", sizeof("write-only") - 1, WRITEONLY} + , + {"NsapAddress", sizeof("NsapAddress") - 1, NSAPADDRESS} + , + {"UNITS", sizeof("Units") - 1, UNITS} + , + {"REFERENCE", sizeof("REFERENCE") - 1, REFERENCE} + , + {"NUM-ENTRIES", sizeof("NUM-ENTRIES") - 1, NUM_ENTRIES} + , + {"BITSTRING", sizeof("BITSTRING") - 1, BITSTRING} + , + {"BIT", sizeof("BIT") - 1, CONTINUE} + , + {"BITS", sizeof("BITS") - 1, BITSTRING} + , + {"Counter64", sizeof("Counter64") - 1, COUNTER64} + , + {"TimeTicks", sizeof("TimeTicks") - 1, TIMETICKS} + , + {"NOTIFICATION-TYPE", sizeof("NOTIFICATION-TYPE") - 1, NOTIFTYPE} + , + {"OBJECT-GROUP", sizeof("OBJECT-GROUP") - 1, OBJGROUP} + , + {"OBJECT-IDENTITY", sizeof("OBJECT-IDENTITY") - 1, OBJIDENTITY} + , + {"IDENTIFIER", sizeof("IDENTIFIER") - 1, IDENTIFIER} + , + {"OBJECT", sizeof("OBJECT") - 1, OBJECT} + , + {"NetworkAddress", sizeof("NetworkAddress") - 1, NETADDR} + , + {"Gauge", sizeof("Gauge") - 1, GAUGE} + , + {"Gauge32", sizeof("Gauge32") - 1, GAUGE} + , + {"Unsigned32", sizeof("Unsigned32") - 1, UNSIGNED32} + , + {"read-write", sizeof("read-write") - 1, READWRITE} + , + {"read-create", sizeof("read-create") - 1, READCREATE} + , + {"OCTETSTRING", sizeof("OCTETSTRING") - 1, OCTETSTR} + , + {"OCTET", sizeof("OCTET") - 1, CONTINUE} + , + {"OF", sizeof("OF") - 1, OF} + , + {"SEQUENCE", sizeof("SEQUENCE") - 1, SEQUENCE} + , + {"NULL", sizeof("NULL") - 1, NUL} + , + {"IpAddress", sizeof("IpAddress") - 1, IPADDR} + , + {"UInteger32", sizeof("UInteger32") - 1, UINTEGER32} + , + {"INTEGER", sizeof("INTEGER") - 1, INTEGER} + , + {"Integer32", sizeof("Integer32") - 1, INTEGER32} + , + {"Counter", sizeof("Counter") - 1, COUNTER} + , + {"Counter32", sizeof("Counter32") - 1, COUNTER} + , + {"read-only", sizeof("read-only") - 1, READONLY} + , + {"DESCRIPTION", sizeof("DESCRIPTION") - 1, DESCRIPTION} + , + {"INDEX", sizeof("INDEX") - 1, INDEX} + , + {"DEFVAL", sizeof("DEFVAL") - 1, DEFVAL} + , + {"deprecated", sizeof("deprecated") - 1, DEPRECATED} + , + {"SIZE", sizeof("SIZE") - 1, SIZE} + , + {"MAX-ACCESS", sizeof("MAX-ACCESS") - 1, ACCESS} + , + {"ACCESS", sizeof("ACCESS") - 1, ACCESS} + , + {"mandatory", sizeof("mandatory") - 1, MANDATORY} + , + {"current", sizeof("current") - 1, CURRENT} + , + {"STATUS", sizeof("STATUS") - 1, STATUS} + , + {"SYNTAX", sizeof("SYNTAX") - 1, SYNTAX} + , + {"OBJECT-TYPE", sizeof("OBJECT-TYPE") - 1, OBJTYPE} + , + {"TRAP-TYPE", sizeof("TRAP-TYPE") - 1, TRAPTYPE} + , + {"ENTERPRISE", sizeof("ENTERPRISE") - 1, ENTERPRISE} + , + {"BEGIN", sizeof("BEGIN") - 1, BEGIN} + , + {"IMPORTS", sizeof("IMPORTS") - 1, IMPORTS} + , + {"EXPORTS", sizeof("EXPORTS") - 1, EXPORTS} + , + {"accessible-for-notify", sizeof("accessible-for-notify") - 1, ACCNOTIFY} + , + {"TEXTUAL-CONVENTION", sizeof("TEXTUAL-CONVENTION") - 1, CONVENTION} + , + {"NOTIFICATION-GROUP", sizeof("NOTIFICATION-GROUP") - 1, NOTIFGROUP} + , + {"DISPLAY-HINT", sizeof("DISPLAY-HINT") - 1, DISPLAYHINT} + , + {"FROM", sizeof("FROM") - 1, FROM} + , + {"AGENT-CAPABILITIES", sizeof("AGENT-CAPABILITIES") - 1, AGENTCAP} + , + {"MACRO", sizeof("MACRO") - 1, MACRO} + , + {"IMPLIED", sizeof("IMPLIED") - 1, IMPLIED} + , + {"SUPPORTS", sizeof("SUPPORTS") - 1, SUPPORTS} + , + {"INCLUDES", sizeof("INCLUDES") - 1, INCLUDES} + , + {"VARIATION", sizeof("VARIATION") - 1, VARIATION} + , + {"REVISION", sizeof("REVISION") - 1, REVISION} + , + {"not-implemented", sizeof("not-implemented") - 1, NOTIMPL} + , + {"OBJECTS", sizeof("OBJECTS") - 1, OBJECTS} + , + {"NOTIFICATIONS", sizeof("NOTIFICATIONS") - 1, NOTIFICATIONS} + , + {"MODULE", sizeof("MODULE") - 1, MODULE} + , + {"MIN-ACCESS", sizeof("MIN-ACCESS") - 1, MINACCESS} + , + {"PRODUCT-RELEASE", sizeof("PRODUCT-RELEASE") - 1, PRODREL} + , + {"WRITE-SYNTAX", sizeof("WRITE-SYNTAX") - 1, WRSYNTAX} + , + {"CREATION-REQUIRES", sizeof("CREATION-REQUIRES") - 1, CREATEREQ} + , + {"MANDATORY-GROUPS", sizeof("MANDATORY-GROUPS") - 1, MANDATORYGROUPS} + , + {"GROUP", sizeof("GROUP") - 1, GROUP} + , + {"CHOICE", sizeof("CHOICE") - 1, CHOICE} + , + {"IMPLICIT", sizeof("IMPLICIT") - 1, IMPLICIT} + , + {"ObjectSyntax", sizeof("ObjectSyntax") - 1, OBJSYNTAX} + , + {"SimpleSyntax", sizeof("SimpleSyntax") - 1, SIMPLESYNTAX} + , + {"ApplicationSyntax", sizeof("ApplicationSyntax") - 1, APPSYNTAX} + , + {"ObjectName", sizeof("ObjectName") - 1, OBJNAME} + , + {"NotificationName", sizeof("NotificationName") - 1, NOTIFNAME} + , + {"VARIABLES", sizeof("VARIABLES") - 1, VARIABLES} + , + {NULL} +}; + +/* + * This is one element of an object identifier with either an integer + * subidentifier, or a textual string label, or both. + * The subid is -1 if not present, and label is NULL if not present. + */ +struct subid_s { + int subid; + int modid; + char *label; +}; + +struct objgroup { + char *name; + int line; + struct objgroup *next; +}*objgroups = NULL, *objects = NULL, *notifs = NULL; + +static struct tok *buckets[HASHSIZE]; +static struct node *nbuckets[NHASHSIZE]; +static struct tree *tbuckets[NHASHSIZE]; + +struct module *module_head = NULL; + +static int current_module = 0; +static int max_module = 0; +static int anonymous = 0; +static char *last_err_module = 0; /* no repeats on "Cannot find module..." */ + +static struct module_import root_imports[NUMBER_OF_ROOT_NODES]; + +//end of public var definition---------------------------------------------------- + +//forward function declearation--------------------------------------------------- +struct tree *read_mib(const char *filename); +struct tree *read_module(const char *name); +static int read_module_internal(const char *name); +int get_token(FILE * fp, char *token, int maxtlen); +void new_module(const char *name, const char *file); +static int is_labelchar(int ich); +static void print_error(const char *str, const char *token, int type); +static int name_hash(const char *name); +void init_mib_internals(void); +static void build_translation_table(); +static void init_tree_roots(); +static struct node *parse(FILE * fp, struct node *root); +void print_nodes(FILE * fp, struct node *root); +static void scan_objlist(struct node *root, struct objgroup *list, const char *error); +static void do_linkup(struct module *mp, struct node *np); +static void init_node_hash(struct node *nodes); +static int get_tc_index(const char *descriptor, int modid); +static void do_subtree(struct tree *root, struct node **nodes); +static void tree_from_node(struct tree *tp, struct node *np); +static void free_node(struct node *np); +void free_tree(struct tree *Tree); +static void free_indexes(struct index_list **spp); +static void free_varbinds(struct varbind_list **spp); +static void free_enums(struct enum_list **spp); +static void free_ranges(struct range_list **spp); +static void unlink_tbucket(struct tree *tp); +static void unlink_tree(struct tree *tp); +static void merge_anon_children(struct tree *tp1, struct tree *tp2); +static void free_partial_tree(struct tree *tp, int keep_label); +int which_module(const char *name); +static struct node *parse_macro(FILE * fp, char *name); +static struct node *alloc_node(int modid); +static struct node *parse_objecttype(FILE * fp, char *name); +static int get_tc(const char *descriptor, int modid, int *tc_index, + struct enum_list **ep, struct range_list **rp, char **hint); +static struct index_list *getIndexes(FILE * fp, struct index_list **retp); +static int tossObjectIdentifier(FILE * fp); +static struct node *merge_parse_objectid(struct node *np, FILE * fp, char *name); +static struct node *parse_objectid(FILE * fp, char *name); +static int getoid(FILE * fp, struct subid_s *id, int length); +static struct node *parse_objectgroup(FILE * fp, char *name, int what, struct objgroup **ol); +static struct varbind_list *getVarbinds(FILE * fp, struct varbind_list **retp); +static struct node *parse_trapDefinition(FILE * fp, char *name); +static struct node *parse_notificationDefinition(FILE * fp, char *name); +static struct node *parse_compliance(FILE * fp, char *name); +static int compliance_lookup(const char *name, int modid); +char *module_name(int modid, char *cp); +struct tree *find_tree_node(const char *name, int modid); +static int eat_syntax(FILE * fp, char *token, int maxtoken); +static struct node *parse_capabilities(FILE * fp, char *name); +static struct node *parse_moduleIdentity(FILE * fp, char *name); +static struct node *parse_asntype(FILE * fp, char *name, int *ntype, char *ntoken); +static void parse_imports(FILE * fp); +static void check_utc(const char *utc); +static void print_module_not_found(const char *cp); +void print_subtree(FILE * f, struct tree *tree, int count); +static int parseQuoteString(FILE * fp, char *token, int maxtlen); +//end of forward function declearation-------------------------------------------- + +//TOP LAYER FUNCTION DEFINITIONS-------------------------------------------------------- +//Returns the root of the whole tree +struct tree *read_mib(const char *filename) +{ + FILE *fp; + char token[MAXTOKEN]; + + fp = fopen(filename, "r"); + if (fp == NULL) { +// snmp_log_perror(filename); + return NULL; + } + mibLine = 1; + File = filename; + get_token(fp, token, MAXTOKEN); + fclose(fp); + new_module(token, filename); + (void) read_module(token); + printf("Parsing MIB file: %s", filename); + printf(".........................................OK\n"); + + return tree_head; +} + +struct tree *read_module(const char *name) +{ + if (read_module_internal(name) == MODULE_NOT_FOUND) + print_error("Cannot find module", name, CONTINUE); + return tree_head; +} + +struct tree *get_tree(int *objid, int objidlen, struct tree *subtree) +{ + struct tree *return_tree = NULL; + + for (; subtree; subtree = subtree->next_peer) { + if (*objid == subtree->subid) + goto found; + } + + return NULL; + + found: + while (subtree->next_peer && subtree->next_peer->subid == *objid) + subtree = subtree->next_peer; + + if (objidlen > 1) + return_tree = + get_tree(objid + 1, objidlen - 1, subtree->child_list); + + if (return_tree != NULL) + return return_tree; + else + return subtree; +} +//END OF TOP LAYER FUNCTION DEFINITIONS------------------------------------------------- + +//support function definition----------------------------------------------------- +/* + * Parses a token from the file. The type of the token parsed is returned, + * and the text is placed in the string pointed to by token. + * Warning: this method may recurse. + */ +int get_token(FILE * fp, char *token, int maxtlen) +{ + register int ch, ch_next; + register char *cp = token; + register int hash = 0; + register struct tok *tp; + int too_long = 0; + + /* + * skip all white space + */ + do { + ch = getc(fp); + if (ch == '\n') + mibLine++; + } + while (isspace(ch) && ch != EOF); + *cp++ = ch; + *cp = '\0'; + switch (ch) { + case EOF: + return ENDOFFILE; + case '"': + return parseQuoteString(fp, token, maxtlen); + case '\'': /* binary or hex constant */ + while ((ch = getc(fp)) != EOF && ch != '\'' + && cp - token < maxtlen - 2) + *cp++ = ch; + if (ch == '\'') { + unsigned long val = 0; + *cp++ = '\''; + *cp++ = ch = getc(fp); + *cp = 0; + cp = token + 1; + switch (ch) { + case EOF: + return ENDOFFILE; + case 'b': + case 'B': + while ((ch = *cp++) != '\'') + if (ch != '0' && ch != '1') + return LABEL; + else + val = val * 2 + ch - '0'; + break; + case 'h': + case 'H': + while ((ch = *cp++) != '\'') + if ('0' <= ch && ch <= '9') + val = val * 16 + ch - '0'; + else if ('a' <= ch && ch <= 'f') + val = val * 16 + ch - 'a' + 10; + else if ('A' <= ch && ch <= 'F') + val = val * 16 + ch - 'A' + 10; + else + return LABEL; + break; + default: + return LABEL; + } + sprintf(token, "%ld", val); + return NUMBER; + } else + return LABEL; + case '(': + return LEFTPAREN; + case ')': + return RIGHTPAREN; + case '{': + return LEFTBRACKET; + case '}': + return RIGHTBRACKET; + case '[': + return LEFTSQBRACK; + case ']': + return RIGHTSQBRACK; + case ';': + return SEMI; + case ',': + return COMMA; + case '|': + return BAR; + case '.': + ch_next = getc(fp); + if (ch_next == '.') + return RANGE; + ungetc(ch_next, fp); + return LABEL; + case ':': + ch_next = getc(fp); + if (ch_next != ':') { + ungetc(ch_next, fp); + return LABEL; + } + ch_next = getc(fp); + if (ch_next != '=') { + ungetc(ch_next, fp); + return LABEL; + } + return EQUALS; + case '-': + ch_next = getc(fp); + if (ch_next == '-') { + #if 0 + if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_MIB_COMMENT_TERM)) { + /* + * Treat the rest of this line as a comment. + */ + while ((ch_next != EOF) && (ch_next != '\n')) + ch_next = getc(fp); + } else + #endif + { + + /* + * Treat the rest of the line or until another '--' as a comment + */ + /* + * (this is the "technically" correct way to parse comments) + */ + ch = ' '; + ch_next = getc(fp); + while (ch_next != EOF && ch_next != '\n' && + (ch != '-' || ch_next != '-')) { + ch = ch_next; + ch_next = getc(fp); + } + } + if (ch_next == EOF) + return ENDOFFILE; + if (ch_next == '\n') + mibLine++; + return get_token(fp, token, maxtlen); + } + ungetc(ch_next, fp); + default: + /* + * Accumulate characters until end of token is found. Then attempt to + * match this token as a reserved word. If a match is found, return the + * type. Else it is a label. + */ + if (!is_labelchar(ch)) + return LABEL; + hash += tolower(ch); + more: + while (is_labelchar(ch_next = getc(fp))) { + hash += tolower(ch_next); + if (cp - token < maxtlen - 1) + *cp++ = ch_next; + else + too_long = 1; + } + ungetc(ch_next, fp); + *cp = '\0'; + + if (too_long) + print_error("Warning: token too long", token, CONTINUE); + for (tp = buckets[BUCKET(hash)]; tp; tp = tp->next) { + if ((tp->hash == hash) && (!label_compare(tp->name, token))) + break; + } + if (tp) { + if (tp->token != CONTINUE) + return (tp->token); + while (isspace((ch_next = getc(fp)))) + if (ch_next == '\n') + mibLine++; + if (ch_next == EOF) + return ENDOFFILE; + if (isalnum(ch_next)) { + *cp++ = ch_next; + hash += tolower(ch_next); + goto more; + } + } + if (token[0] == '-' || isdigit(token[0])) { + for (cp = token + 1; *cp; cp++) + if (!isdigit(*cp)) + return LABEL; + return NUMBER; + } + return LABEL; + } +} + +void new_module(const char *name, const char *file) +{ + struct module *mp; + + for (mp = module_head; mp; mp = mp->next) + if (!label_compare(mp->name, name)) + return; + + /* + * Add this module to the list + */ + mp = (struct module *) calloc(1, sizeof(struct module)); + if (mp == NULL) + return; + mp->name = strdup(name); + mp->file = strdup(file); + mp->imports = NULL; + mp->no_imports = -1; /* Not yet loaded */ + mp->modid = max_module; + ++max_module; + + mp->next = module_head; /* Or add to the *end* of the list? */ + module_head = mp; +} + +/* + * Read in the named module + * Returns the root of the whole tree + * (by analogy with 'read_mib') + */ +static int read_module_internal(const char *name) +{ + struct module *mp; + FILE *fp; + struct node *np; + + init_mib_internals(); + + for (mp = module_head; mp; mp = mp->next){ + if (!label_compare(mp->name, name)) { + const char *oldFile = File; + int oldLine = mibLine; + int oldModule = current_module; + + if (mp->no_imports != -1) { + return MODULE_ALREADY_LOADED; + } + if ((fp = fopen(mp->file, "r")) == NULL) { + printf("ERROR: can not open file: %s", mp->file); + return MODULE_LOAD_FAILED; + } + mp->no_imports = 0; /* Note that we've read the file */ + File = mp->file; + mibLine = 1; + current_module = mp->modid; + /* + * Parse the file + */ + printf("Parsing MIB file: %s\n", mp->file); + np = parse(fp, NULL); + fclose(fp); + File = oldFile; + mibLine = oldLine; + current_module = oldModule; + return MODULE_LOADED_OK; + } + } + + return MODULE_NOT_FOUND; +} + +void init_mib_internals(void) +{ + register struct tok *tp; + register int b; +// int max_modc; + + if (tree_head) + return; + + /* + * Set up hash list of pre-defined tokens + */ + memset(buckets, 0, sizeof(buckets)); + for (tp = tokens; tp->name; tp++) { + tp->hash = name_hash(tp->name); + b = BUCKET(tp->hash); + if (buckets[b]) + tp->next = buckets[b]; /* BUG ??? */ + buckets[b] = tp; + } + + /* + * Initialise other internal structures + */ + memset(nbuckets, 0, sizeof(nbuckets)); + memset(tbuckets, 0, sizeof(tbuckets)); + memset(tclist, 0, MAXTC * sizeof(struct tc)); + build_translation_table(); + init_tree_roots(); /* Set up initial roots */ + /* + * Relies on 'add_mibdir' having set up the modules + */ +} + +static void init_tree_roots() +{ + struct tree *tp, *lasttp; + int base_modid; + int hash; + + base_modid = which_module("SNMPv2-SMI"); + + /* + * build root node + */ + tp = (struct tree *) calloc(1, sizeof(struct tree)); + if (tp == NULL) + return; + tp->label = strdup("joint-iso-ccitt"); + tp->modid = base_modid; + tp->number_modules = 1; + tp->module_list = &(tp->modid); + tp->subid = 2; + tp->oid[tp->oid_len++] = tp->subid; + tp->tc_index = -1; +// set_function(tp); /* from mib.c */ + hash = NBUCKET(name_hash(tp->label)); + tp->next = tbuckets[hash]; + tbuckets[hash] = tp; + lasttp = tp; + root_imports[0].label = strdup(tp->label); + root_imports[0].modid = base_modid; + + /* + * build root node + */ + tp = (struct tree *) calloc(1, sizeof(struct tree)); + if (tp == NULL) + return; + tp->next_peer = lasttp; + tp->label = strdup("ccitt"); + tp->modid = base_modid; + tp->number_modules = 1; + tp->module_list = &(tp->modid); + tp->subid = 0; + tp->oid[tp->oid_len++] = tp->subid; + tp->tc_index = -1; +// set_function(tp); /* from mib.c */ + hash = NBUCKET(name_hash(tp->label)); + tp->next = tbuckets[hash]; + tbuckets[hash] = tp; + lasttp = tp; + root_imports[1].label = strdup(tp->label); + root_imports[1].modid = base_modid; + + /* + * build root node + */ + tp = (struct tree *) calloc(1, sizeof(struct tree)); + if (tp == NULL) + return; + tp->next_peer = lasttp; + tp->label = strdup("iso"); + tp->modid = base_modid; + tp->number_modules = 1; + tp->module_list = &(tp->modid); + tp->subid = 1; + tp->oid[tp->oid_len++] = tp->subid; + tp->tc_index = -1; +// set_function(tp); /* from mib.c */ + hash = NBUCKET(name_hash(tp->label)); + tp->next = tbuckets[hash]; + tbuckets[hash] = tp; + lasttp = tp; + root_imports[2].label = strdup(tp->label); + root_imports[2].modid = base_modid; + + tree_head = tp; +} + +/* + * Parses a mib file and returns a linked list of nodes found in the file. + * Returns NULL on error. + */ +#define BETWEEN_MIBS 1 +#define IN_MIB 2 +static struct node *parse(FILE * fp, struct node *root) +{ + char token[MAXTOKEN]; + char name[MAXTOKEN]; + int type = LABEL; + int lasttype = LABEL; + int state = BETWEEN_MIBS; + struct node *np, *nnp; + struct objgroup *oldgroups = NULL, *oldobjects = NULL, *oldnotifs = + NULL; + +// if (last_err_module) +// free(last_err_module); +// last_err_module = 0; + + np = root; + if (np != NULL) { + /* + * now find end of chain + */ + while (np->next) + np = np->next; + } + + while (type != ENDOFFILE) { + if (lasttype == CONTINUE) + lasttype = type; + else + type = lasttype = get_token(fp, token, MAXTOKEN); + + switch (type) { + case END: + if (state != IN_MIB) { + print_error("Error, END before start of MIB", NULL, type); + return NULL; + } else { + struct module *mp; +#ifdef _TEST_ + printf("\nNodes for Module %s:\n", name); + print_nodes(stdout, root); +#endif + scan_objlist(root, objgroups, "Undefined OBJECT-GROUP"); + scan_objlist(root, objects, "Undefined OBJECT"); + scan_objlist(root, notifs, "Undefined NOTIFICATION"); + objgroups = oldgroups; + objects = oldobjects; + notifs = oldnotifs; + for (mp = module_head; mp; mp = mp->next) + if (mp->modid == current_module) + break; + do_linkup(mp, root); + np = root = NULL; + } + state = BETWEEN_MIBS; + continue; + case IMPORTS: + parse_imports(fp); + continue; + case EXPORTS: + while (type != SEMI && type != ENDOFFILE) + type = get_token(fp, token, MAXTOKEN); + continue; + case LABEL: + case INTEGER: + case INTEGER32: + case UINTEGER32: + case UNSIGNED32: + case COUNTER: + case COUNTER64: + case GAUGE: + case IPADDR: + case NETADDR: + case NSAPADDRESS: + case OBJSYNTAX: + case APPSYNTAX: + case SIMPLESYNTAX: + case OBJNAME: + case NOTIFNAME: + case KW_OPAQUE: + case TIMETICKS: + break; + case ENDOFFILE: + continue; + default: + strcpy(name, token); + type = get_token(fp, token, MAXTOKEN); + nnp = NULL; + if (type == MACRO) { + nnp = parse_macro(fp, name); + if (nnp == NULL) { + print_error("Bad parse of MACRO", NULL, type); + /* + * return NULL; + */ + } + free_node(nnp); /* IGNORE */ + nnp = NULL; + } else + print_error(name, "is a reserved word", lasttype); + continue; /* see if we can parse the rest of the file */ + } + strcpy(name, token); + type = get_token(fp, token, MAXTOKEN); + nnp = NULL; + + /* + * Handle obsolete method to assign an object identifier to a + * module + */ + if (lasttype == LABEL && type == LEFTBRACKET) { + while (type != RIGHTBRACKET && type != ENDOFFILE) + type = get_token(fp, token, MAXTOKEN); + if (type == ENDOFFILE) { + print_error("Expected \"}\"", token, type); + return NULL; + } + type = get_token(fp, token, MAXTOKEN); + } + + switch (type) { + case DEFINITIONS: + if (state != BETWEEN_MIBS) { + print_error("Error, nested MIBS", NULL, type); + return NULL; + } + state = IN_MIB; + current_module = which_module(name); + oldgroups = objgroups; + objgroups = NULL; + oldobjects = objects; + objects = NULL; + oldnotifs = notifs; + notifs = NULL; + if (current_module == -1) { + new_module(name, File); + current_module = which_module(name); + } + + while ((type = get_token(fp, token, MAXTOKEN)) != ENDOFFILE) + if (type == BEGIN) + break; + break; + case OBJTYPE: + nnp = parse_objecttype(fp, name); + if (nnp == NULL) { + print_error("Bad parse of OBJECT-TYPE", NULL, type); + return NULL; + } + break; + case OBJGROUP: + nnp = parse_objectgroup(fp, name, OBJECTS, &objects); + if (nnp == NULL) { + print_error("Bad parse of OBJECT-GROUP", NULL, type); + return NULL; + } + break; + case NOTIFGROUP: + nnp = parse_objectgroup(fp, name, NOTIFICATIONS, ¬ifs); + if (nnp == NULL) { + print_error("Bad parse of NOTIFICATION-GROUP", NULL, type); + return NULL; + } + break; + case TRAPTYPE: + nnp = parse_trapDefinition(fp, name); + if (nnp == NULL) { + print_error("Bad parse of TRAP-TYPE", NULL, type); + return NULL; + } + break; + case NOTIFTYPE: + nnp = parse_notificationDefinition(fp, name); + if (nnp == NULL) { + print_error("Bad parse of NOTIFICATION-TYPE", NULL, type); + return NULL; + } + break; + case COMPLIANCE: + nnp = parse_compliance(fp, name); + if (nnp == NULL) { + print_error("Bad parse of MODULE-COMPLIANCE", NULL, type); + return NULL; + } + break; + case AGENTCAP: + nnp = parse_capabilities(fp, name); + if (nnp == NULL) { + print_error("Bad parse of AGENT-CAPABILITIES", NULL, type); + return NULL; + } + break; + case MACRO: + nnp = parse_macro(fp, name); + if (nnp == NULL) { + print_error("Bad parse of MACRO", NULL, type); + /* + * return NULL; + */ + } + free_node(nnp); /* IGNORE */ + nnp = NULL; + break; + case MODULEIDENTITY: + nnp = parse_moduleIdentity(fp, name); + if (nnp == NULL) { + print_error("Bad parse of MODULE-IDENTITY", NULL, type); + return NULL; + } + break; + case OBJIDENTITY: + nnp = parse_objectgroup(fp, name, OBJECTS, &objects); + if (nnp == NULL) { + print_error("Bad parse of OBJECT-IDENTITY", NULL, type); + return NULL; + } + break; + case OBJECT: + type = get_token(fp, token, MAXTOKEN); + if (type != IDENTIFIER) { + print_error("Expected IDENTIFIER", token, type); + return NULL; + } + type = get_token(fp, token, MAXTOKEN); + if (type != EQUALS) { + print_error("Expected \"::=\"", token, type); + return NULL; + } + nnp = parse_objectid(fp, name); + if (nnp == NULL) { + print_error("Bad parse of OBJECT IDENTIFIER", NULL, type); + return NULL; + } + break; + case EQUALS: + nnp = parse_asntype(fp, name, &type, token); + lasttype = CONTINUE; + break; + case ENDOFFILE: + break; + default: + print_error("Bad operator", token, type); + return NULL; + } + if (nnp) { + if (np) + np->next = nnp; + else + np = root = nnp; + while (np->next) + np = np->next; + if (np->type == TYPE_OTHER) + np->type = type; + } + } + return root; +} + +static void scan_objlist(struct node *root, struct objgroup *list, const char *error) +{ + int oLine = mibLine; + + while (list) { + struct objgroup *gp = list; + struct node *np; + list = list->next; + np = root; + while (np) + if (label_compare(np->label, gp->name)) + np = np->next; + else + break; + if (!np) { + mibLine = gp->line; + print_error(error, gp->name, QUOTESTRING); + } + free(gp->name); + free(gp); + } + mibLine = oLine; +} + +static void do_linkup(struct module *mp, struct node *np) +{ + struct module_import *mip; + struct node *onp, *oldp, *newp; + struct tree *tp; + int i, more; + /* + * All modules implicitly import + * the roots of the tree + */ + if (mp->no_imports == 0) { + mp->no_imports = NUMBER_OF_ROOT_NODES; + mp->imports = root_imports; + } + + /* + * Build the tree + */ + init_node_hash(np); + for (i = 0, mip = mp->imports; i < mp->no_imports; ++i, ++mip) { + char modbuf[256]; + if (get_tc_index(mip->label, mip->modid) != -1) + continue; + tp = find_tree_node(mip->label, mip->modid); + if (!tp) { + printf("Did not find '%s' in module %s (%s)\n", + mip->label, module_name(mip->modid, modbuf),File); + continue; + } + do_subtree(tp, &np); + } + + /* + * If any nodes left over, + * check that they're not the result of a "fully qualified" + * name, and then add them to the list of orphans + */ + + if (!np) + return; + for (tp = tree_head; tp; tp = tp->next_peer) + do_subtree(tp, &np); + if (!np) + return; + + /* + * quietly move all internal references to the orphan list + */ + oldp = orphan_nodes; + do { + for (i = 0; i < NHASHSIZE; i++) + for (onp = nbuckets[i]; onp; onp = onp->next) { + struct node *op = NULL; + int hash = NBUCKET(name_hash(onp->label)); + np = nbuckets[hash]; + while (np) { + if (label_compare(onp->label, np->parent)) { + op = np; + np = np->next; + } else { + if (op) + op->next = np->next; + else + nbuckets[hash] = np->next; + np->next = orphan_nodes; + orphan_nodes = np; + op = NULL; + np = nbuckets[hash]; + } + } + } + newp = orphan_nodes; + more = 0; + for (onp = orphan_nodes; onp != oldp; onp = onp->next) { + struct node *op = NULL; + int hash = NBUCKET(name_hash(onp->label)); + np = nbuckets[hash]; + while (np) { + if (label_compare(onp->label, np->parent)) { + op = np; + np = np->next; + } else { + if (op) + op->next = np->next; + else + nbuckets[hash] = np->next; + np->next = orphan_nodes; + orphan_nodes = np; + op = NULL; + np = nbuckets[hash]; + more = 1; + } + } + } + oldp = newp; + } while (more); + + /* + * complain about left over nodes + */ + for (np = orphan_nodes; np && np->next; np = np->next); /* find the end of the orphan list */ + for (i = 0; i < NHASHSIZE; i++) + if (nbuckets[i]) { + if (orphan_nodes) + onp = np->next = nbuckets[i]; + else + onp = orphan_nodes = nbuckets[i]; + nbuckets[i] = NULL; + while (onp) { + printf("Unlinked OID in %s: %s ::= { %s %d }\n", + (mp->name ? mp->name : ""), + (onp->label ? onp->label : ""), + (onp->parent ? onp->parent : ""), + onp->subid); + printf("Undefined identifier: %s near line %d of %s\n", + (onp->parent ? onp->parent : ""), + onp->lineno, onp->filename); + np = onp; + onp = onp->next; + } + } + return; +} + +/* + * Find all the children of root in the list of nodes. Link them into the + * tree and out of the nodes list. + */ +static void do_subtree(struct tree *root, struct node **nodes) +{ + struct tree *tp, *anon_tp = NULL; + struct tree *xroot = root; + struct node *np, **headp; + struct node *oldnp = NULL, *child_list = NULL, *childp = NULL; + int hash; + int *int_p; + + while (xroot->next_peer && xroot->next_peer->subid == root->subid) { + xroot = xroot->next_peer; + } + + tp = root; + headp = &nbuckets[NBUCKET(name_hash(tp->label))]; + /* + * Search each of the nodes for one whose parent is root, and + * move each into a separate list. + */ + for (np = *headp; np; np = np->next) { + if (!label_compare(tp->label, np->parent)) { + /* + * take this node out of the node list + */ + if (oldnp == NULL) { + *headp = np->next; /* fix root of node list */ + } else { + oldnp->next = np->next; /* link around this node */ + } + if (child_list) + childp->next = np; + else + child_list = np; + childp = np; + } else { + oldnp = np; + } + + } + if (childp) + childp->next = NULL; + /* + * Take each element in the child list and place it into the tree. + */ + for (np = child_list; np; np = np->next) { + struct tree *otp = NULL; + struct tree *xxroot = xroot; + anon_tp = NULL; + tp = xroot->child_list; + + if (np->subid == -1) { + /* + * name ::= { parent } + */ + np->subid = xroot->subid; + tp = xroot; + xxroot = xroot->parent; + } + + while (tp) { + if (tp->subid == np->subid) + break; + else { + otp = tp; + tp = tp->next_peer; + } + } + if (tp) { + if (!label_compare(tp->label, np->label)) { + /* + * Update list of modules + */ + int_p = + (int *) malloc((tp->number_modules + 1) * sizeof(int)); + if (int_p == NULL) + return; + memcpy(int_p, tp->module_list, + tp->number_modules * sizeof(int)); + int_p[tp->number_modules] = np->modid; + if (tp->number_modules > 1) + free((char *) tp->module_list); + ++tp->number_modules; + tp->module_list = int_p; + + /* + * Handle children + */ + do_subtree(tp, nodes); + continue; + } + if (!strncmp(np->label, ANON, ANON_LEN) || + !strncmp(tp->label, ANON, ANON_LEN)) { + anon_tp = tp; /* Need to merge these two trees later */ + } + } + + tp = (struct tree *) calloc(1, sizeof(struct tree)); + if (tp == NULL) + return; + tp->parent = xxroot; + tp->modid = np->modid; + tp->number_modules = 1; + tp->module_list = &(tp->modid); + tree_from_node(tp, np); + tp->next_peer = otp ? otp->next_peer : xxroot->child_list; + if (otp) + otp->next_peer = tp; + else + xxroot->child_list = tp; + hash = NBUCKET(name_hash(tp->label)); + tp->next = tbuckets[hash]; + tbuckets[hash] = tp; + do_subtree(tp, nodes); + + if (anon_tp) { + if (!strncmp(tp->label, ANON, ANON_LEN)) { + /* + * The new node is anonymous, + * so merge it with the existing one. + */ + merge_anon_children(tp, anon_tp); + + /* + * unlink and destroy tp + */ + unlink_tree(tp); + free_tree(tp); + } else if (!strncmp(anon_tp->label, ANON, ANON_LEN)) { + struct tree *ntp; + /* + * The old node was anonymous, + * so merge it with the existing one, + * and fill in the full information. + */ + merge_anon_children(anon_tp, tp); + + /* + * unlink anon_tp from the hash + */ + unlink_tbucket(anon_tp); + + /* + * get rid of old contents of anon_tp + */ + free_partial_tree(anon_tp, FALSE); + + /* + * put in the current information + */ + anon_tp->label = tp->label; + anon_tp->child_list = tp->child_list; + anon_tp->modid = tp->modid; + anon_tp->tc_index = tp->tc_index; + anon_tp->type = tp->type; + anon_tp->enums = tp->enums; + anon_tp->indexes = tp->indexes; + anon_tp->augments = tp->augments; + anon_tp->varbinds = tp->varbinds; + anon_tp->ranges = tp->ranges; + anon_tp->hint = tp->hint; + anon_tp->units = tp->units; + anon_tp->description = tp->description; + anon_tp->reference = tp->reference; + anon_tp->defaultValue = tp->defaultValue; + anon_tp->parent = tp->parent; + + // set_function(anon_tp); + + /* + * update parent pointer in moved children + */ + ntp = anon_tp->child_list; + while (ntp) { + ntp->parent = anon_tp; + ntp = ntp->next_peer; + } + + /* + * hash in anon_tp in its new place + */ + hash = NBUCKET(name_hash(anon_tp->label)); + anon_tp->next = tbuckets[hash]; + tbuckets[hash] = anon_tp; + + /* + * unlink and destroy tp + */ + unlink_tbucket(tp); + unlink_tree(tp); + free(tp); + } + anon_tp = NULL; + } + } + /* + * free all nodes that were copied into tree + */ + oldnp = NULL; + for (np = child_list; np; np = np->next) { + if (oldnp) + free_node(oldnp); + oldnp = np; + } + if (oldnp) + free_node(oldnp); +} + +static void merge_anon_children(struct tree *tp1, struct tree *tp2) +/* + * NB: tp1 is the 'anonymous' node + */ +{ + struct tree *child1, *child2, *previous; + + for (child1 = tp1->child_list; child1;) { + + for (child2 = tp2->child_list, previous = NULL; + child2; previous = child2, child2 = child2->next_peer) { + + if (child1->subid == child2->subid) { + /* + * Found 'matching' children, + * so merge them + */ + if (!strncmp(child1->label, ANON, ANON_LEN)) { + merge_anon_children(child1, child2); + + child1->child_list = NULL; + previous = child1; /* Finished with 'child1' */ + child1 = child1->next_peer; + free_tree(previous); + goto next; + } + + else if (!strncmp(child2->label, ANON, ANON_LEN)) { + merge_anon_children(child2, child1); + + if (previous) + previous->next_peer = child2->next_peer; + else + tp2->child_list = child2->next_peer; + free_tree(child2); + + previous = child1; /* Move 'child1' to 'tp2' */ + child1 = child1->next_peer; + previous->next_peer = tp2->child_list; + tp2->child_list = previous; + for (previous = tp2->child_list; + previous; previous = previous->next_peer) + previous->parent = tp2; + goto next; + } else if (!label_compare(child1->label, child2->label)) { + continue; + } else { + /* + * Two copies of the same node. + * 'child2' adopts the children of 'child1' + */ + + if (child2->child_list) { + for (previous = child2->child_list; previous->next_peer; previous = previous->next_peer); /* Find the end of the list */ + previous->next_peer = child1->child_list; + } else + child2->child_list = child1->child_list; + for (previous = child1->child_list; + previous; previous = previous->next_peer) + previous->parent = child2; + child1->child_list = NULL; + + previous = child1; /* Finished with 'child1' */ + child1 = child1->next_peer; + free_tree(previous); + goto next; + } + } + } + /* + * If no match, move 'child1' to 'tp2' child_list + */ + if (child1) { + previous = child1; + child1 = child1->next_peer; + previous->parent = tp2; + previous->next_peer = tp2->child_list; + tp2->child_list = previous; + } + next:; + } +} + +/* + * Parses a MACRO definition + * Expect BEGIN, discard everything to end. + * Returns 0 on error. + */ +static struct node *parse_macro(FILE * fp, char *name) +{ + register int type; + char token[MAXTOKEN]; + struct node *np; + + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, sizeof(token)); + while (type != EQUALS && type != ENDOFFILE) { + type = get_token(fp, token, sizeof(token)); + } + if (type != EQUALS) { + if (np) + free_node(np); + return NULL; + } + while (type != BEGIN && type != ENDOFFILE) { + type = get_token(fp, token, sizeof(token)); + } + if (type != BEGIN) { + if (np) + free_node(np); + return NULL; + } + while (type != END && type != ENDOFFILE) { + type = get_token(fp, token, sizeof(token)); + } + if (type != END) { + if (np) + free_node(np); + return NULL; + } + +// printf("%s MACRO (lines %d..%d parsed and ignored).\n", name,iLine, mibLine); + + return np; +} + +/* + * Parses an enumeration list of the form: + * { label(value) label(value) ... } + * The initial { has already been parsed. + * Returns NULL on error. + */ +static struct enum_list *parse_enumlist(FILE * fp, struct enum_list **retp) +{ + register int type; + char token[MAXTOKEN]; + struct enum_list *ep = NULL, **epp = &ep; + + free_enums(retp); + + while ((type = get_token(fp, token, MAXTOKEN)) != ENDOFFILE) { + if (type == RIGHTBRACKET) + break; + if (type == LABEL) { + /* + * this is an enumerated label + */ + *epp = + (struct enum_list *) calloc(1, sizeof(struct enum_list)); + if (*epp == NULL) + return (NULL); + /* + * a reasonable approximation for the length + */ + (*epp)->label = strdup(token); + type = get_token(fp, token, MAXTOKEN); + if (type != LEFTPAREN) { + print_error("Expected \"(\"", token, type); + return NULL; + } + type = get_token(fp, token, MAXTOKEN); + if (type != NUMBER) { + print_error("Expected integer", token, type); + return NULL; + } + (*epp)->value = strtol(token, NULL, 10); + type = get_token(fp, token, MAXTOKEN); + if (type != RIGHTPAREN) { + print_error("Expected \")\"", token, type); + return NULL; + } + epp = &(*epp)->next; + } + } + if (type == ENDOFFILE) { + print_error("Expected \"}\"", token, type); + return NULL; + } + *retp = ep; + return ep; +} + +static struct range_list *parse_ranges(FILE * fp, struct range_list **retp) +{ + int low, high; + char nexttoken[MAXTOKEN]; + int nexttype; + struct range_list *rp = NULL, **rpp = &rp; + int size = 0, taken = 1; + + free_ranges(retp); + + nexttype = get_token(fp, nexttoken, MAXTOKEN); + if (nexttype == SIZE) { + size = 1; + taken = 0; + nexttype = get_token(fp, nexttoken, MAXTOKEN); + if (nexttype != LEFTPAREN) + print_error("Expected \"(\" after SIZE", nexttoken, nexttype); + } + + do { + if (!taken) + nexttype = get_token(fp, nexttoken, MAXTOKEN); + else + taken = 0; + high = low = strtol(nexttoken, NULL, 10); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + if (nexttype == RANGE) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + errno = 0; + high = strtol(nexttoken, NULL, 10); + if ( errno == ERANGE ) { + printf("Warning: Upper bound not handled correctly (%s != %d): At line %d in %s\n", + nexttoken, high, mibLine, File); + } + nexttype = get_token(fp, nexttoken, MAXTOKEN); + } + *rpp = (struct range_list *) calloc(1, sizeof(struct range_list)); + if (*rpp == NULL) + break; + (*rpp)->low = low; + (*rpp)->high = high; + rpp = &(*rpp)->next; + + } while (nexttype == BAR); + if (size) { + if (nexttype != RIGHTPAREN) + print_error("Expected \")\" after SIZE", nexttoken, nexttype); + nexttype = get_token(fp, nexttoken, nexttype); + } + if (nexttype != RIGHTPAREN) + print_error("Expected \")\"", nexttoken, nexttype); + + *retp = rp; + return rp; +} + +/* + * Parses a module import clause + * loading any modules referenced + */ +#define MAX_IMPORTS 256 +static void parse_imports(FILE * fp) +{ + register int type; + char token[MAXTOKEN]; + char modbuf[256]; + struct module_import import_list[MAX_IMPORTS]; + int this_module; + struct module *mp; + + int import_count = 0; /* Total number of imported descriptors */ + int i = 0, old_i; /* index of first import from each module */ + + type = get_token(fp, token, MAXTOKEN); + + /* + * Parse the IMPORTS clause + */ + while (type != SEMI && type != ENDOFFILE) { + if (type == LABEL) { + if (import_count == MAX_IMPORTS) { + print_error("Too many imported symbols", token, type); + do { + type = get_token(fp, token, MAXTOKEN); + } while (type != SEMI && type != ENDOFFILE); + return; + } + import_list[import_count++].label = strdup(token); + } else if (type == FROM) { + type = get_token(fp, token, MAXTOKEN); + if (import_count == i) { /* All imports are handled internally */ + type = get_token(fp, token, MAXTOKEN); + continue; + } + this_module = which_module(token); + + for (old_i = i; i < import_count; ++i) + import_list[i].modid = this_module; + + /* + * Recursively read any pre-requisite modules + */ + if (read_module_internal(token) == MODULE_NOT_FOUND) { + int found = 0; +// for (; old_i < import_count; ++old_i) { +// found += read_import_replacements(token, &import_list[old_i]); +// } + if (!found) + print_module_not_found(token); + } + } + type = get_token(fp, token, MAXTOKEN); + } + + /* + * Save the import information + * in the global module table + */ + for (mp = module_head; mp; mp = mp->next) + if (mp->modid == current_module) { + if (import_count == 0) + return; + if (mp->imports && (mp->imports != root_imports)) { + /* + * this can happen if all modules are in one source file. + */ + for (i = 0; i < mp->no_imports; ++i) { + free((char *) mp->imports[i].label); + } + free((char *) mp->imports); + } + mp->imports = (struct module_import *) + calloc(import_count, sizeof(struct module_import)); + if (mp->imports == NULL) + return; + for (i = 0; i < import_count; ++i) { + mp->imports[i].label = import_list[i].label; + mp->imports[i].modid = import_list[i].modid; + } + mp->no_imports = import_count; + return; + } + + /* + * Shouldn't get this far + */ + print_module_not_found(module_name(current_module, modbuf)); + return; +} + +/* + * Parses an OBJECT TYPE macro. + * Returns 0 on error. + */ +static struct node *parse_objecttype(FILE * fp, char *name) +{ + register int type; + char token[MAXTOKEN]; + char nexttoken[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + int nexttype, tctype; + register struct node *np; + + type = get_token(fp, token, MAXTOKEN); + if (type != SYNTAX) { + print_error("Bad format for OBJECT-TYPE", token, type); + return NULL; + } + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, MAXTOKEN); + if (type == OBJECT) { + type = get_token(fp, token, MAXTOKEN); + if (type != IDENTIFIER) { + print_error("Expected IDENTIFIER", token, type); + free_node(np); + return NULL; + } + type = OBJID; + } + if (type == LABEL) { + int tmp_index; + tctype = get_tc(token, current_module, &tmp_index, + &np->enums, &np->ranges, &np->hint); + type = tctype; + np->tc_index = tmp_index; /* store TC for later reference */ + } + np->type = type; + nexttype = get_token(fp, nexttoken, MAXTOKEN); + switch (type) { + case SEQUENCE: + if (nexttype == OF) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + } + break; + case INTEGER: + case INTEGER32: + case UINTEGER32: + case UNSIGNED32: + case COUNTER: + case GAUGE: + case BITSTRING: + case LABEL: + if (nexttype == LEFTBRACKET) { + /* + * if there is an enumeration list, parse it + */ + np->enums = parse_enumlist(fp, &np->enums); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + } else if (nexttype == LEFTPAREN) { + /* + * if there is a range list, parse it + */ + np->ranges = parse_ranges(fp, &np->ranges); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + } + break; + case OCTETSTR: + case KW_OPAQUE: + /* + * parse any SIZE specification + */ + if (nexttype == LEFTPAREN) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + if (nexttype == SIZE) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + if (nexttype == LEFTPAREN) { + np->ranges = parse_ranges(fp, &np->ranges); + nexttype = get_token(fp, nexttoken, MAXTOKEN); /* ) */ + if (nexttype == RIGHTPAREN) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + break; + } + } + } + print_error("Bad SIZE syntax", token, type); + free_node(np); + return NULL; + } + break; + case OBJID: + case NETADDR: + case IPADDR: + case TIMETICKS: + case NUL: + case NSAPADDRESS: + case COUNTER64: + break; + default: + print_error("Bad syntax", token, type); + free_node(np); + return NULL; + } + if (nexttype == UNITS) { + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad UNITS", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->units = strdup(quoted_string_buffer); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + } + if (nexttype != ACCESS) { + print_error("Should be ACCESS", nexttoken, nexttype); + free_node(np); + return NULL; + } + type = get_token(fp, token, MAXTOKEN); + if (type != READONLY && type != READWRITE && type != WRITEONLY + && type != NOACCESS && type != READCREATE && type != ACCNOTIFY) { + print_error("Bad ACCESS type", token, type); + free_node(np); + return NULL; + } + np->access = type; + type = get_token(fp, token, MAXTOKEN); + if (type != STATUS) { + print_error("Should be STATUS", token, type); + free_node(np); + return NULL; + } + type = get_token(fp, token, MAXTOKEN); + if (type != MANDATORY && type != CURRENT && type != KW_OPTIONAL && + type != OBSOLETE && type != DEPRECATED) { + print_error("Bad STATUS", token, type); + free_node(np); + return NULL; + } + np->status = type; + /* + * Optional parts of the OBJECT-TYPE macro + */ + type = get_token(fp, token, MAXTOKEN); + while (type != EQUALS && type != ENDOFFILE) { + switch (type) { + case DESCRIPTION: + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->description = strdup(quoted_string_buffer); + break; + + case REFERENCE: + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad REFERENCE", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->reference = strdup(quoted_string_buffer); + break; + case INDEX: + if (np->augments) { + print_error("Cannot have both INDEX and AUGMENTS", token, + type); + free_node(np); + return NULL; + } + np->indexes = getIndexes(fp, &np->indexes); + if (np->indexes == NULL) { + print_error("Bad INDEX list", token, type); + free_node(np); + return NULL; + } + break; + case AUGMENTS: + if (np->indexes) { + print_error("Cannot have both INDEX and AUGMENTS", token, + type); + free_node(np); + return NULL; + } + np->indexes = getIndexes(fp, &np->indexes); + if (np->indexes == NULL) { + print_error("Bad AUGMENTS list", token, type); + free_node(np); + return NULL; + } + np->augments = strdup(np->indexes->ilabel); + free_indexes(&np->indexes); + break; + case DEFVAL: + /* + * Mark's defVal section + */ + type = get_token(fp, quoted_string_buffer, MAXTOKEN); + if (type != LEFTBRACKET) { + print_error("Bad DEFAULTVALUE", quoted_string_buffer, + type); + free_node(np); + return NULL; + } + + { + int level = 1; + char defbuf[512]; + + defbuf[0] = 0; + while (1) { + type = get_token(fp, quoted_string_buffer, MAXTOKEN); + if ((type == RIGHTBRACKET && --level == 0) + || type == ENDOFFILE) + break; + else if (type == LEFTBRACKET) + level++; + if (type == QUOTESTRING) { + if (strlen(defbuf)+2 < sizeof(defbuf)) { + defbuf[ strlen(defbuf)+2 ] = 0; + defbuf[ strlen(defbuf)+1 ] = '"'; + defbuf[ strlen(defbuf) ] = '\\'; + } + defbuf[ sizeof(defbuf)-1 ] = 0; + } + strncat(defbuf, quoted_string_buffer, + sizeof(defbuf)-strlen(defbuf)); + defbuf[ sizeof(defbuf)-1 ] = 0; + if (type == QUOTESTRING) { + if (strlen(defbuf)+2 < sizeof(defbuf)) { + defbuf[ strlen(defbuf)+2 ] = 0; + defbuf[ strlen(defbuf)+1 ] = '"'; + defbuf[ strlen(defbuf) ] = '\\'; + } + defbuf[ sizeof(defbuf)-1 ] = 0; + } + if (strlen(defbuf)+1 < sizeof(defbuf)) { + defbuf[ strlen(defbuf)+1 ] = 0; + defbuf[ strlen(defbuf) ] = ' '; + } + } + + if (type != RIGHTBRACKET) { + print_error("Bad DEFAULTVALUE", quoted_string_buffer, + type); + free_node(np); + return NULL; + } + + defbuf[strlen(defbuf) - 1] = 0; + np->defaultValue = strdup(defbuf); + } + + break; + + case NUM_ENTRIES: + if (tossObjectIdentifier(fp) != OBJID) { + print_error("Bad Object Identifier", token, type); + free_node(np); + return NULL; + } + break; + + default: + print_error("Bad format of optional clauses", token, type); + free_node(np); + return NULL; + } + type = get_token(fp, token, MAXTOKEN); + } + if (type != EQUALS) { + print_error("Bad format", token, type); + free_node(np); + return NULL; + } + return merge_parse_objectid(np, fp, name); +} + +/* + * Parse a sequence of object subidentifiers for the given name. + * The "label OBJECT IDENTIFIER ::=" portion has already been parsed. + * + * The majority of cases take this form : + * label OBJECT IDENTIFIER ::= { parent 2 } + * where a parent label and a child subidentifier number are specified. + * + * Variations on the theme include cases where a number appears with + * the parent, or intermediate subidentifiers are specified by label, + * by number, or both. + * + * Here are some representative samples : + * internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 } + * mgmt OBJECT IDENTIFIER ::= { internet 2 } + * rptrInfoHealth OBJECT IDENTIFIER ::= { snmpDot3RptrMgt 0 4 } + * + * Here is a very rare form : + * iso OBJECT IDENTIFIER ::= { 1 } + * + * Returns NULL on error. When this happens, memory may be leaked. + */ +static struct node *parse_objectid(FILE * fp, char *name) +{ + register int count; + register struct subid_s *op, *nop; + int length; + struct subid_s loid[32]; + struct node *np, *root = NULL, *oldnp = NULL; + struct tree *tp; + + if ((length = getoid(fp, loid, 32)) == 0) { + print_error("Bad object identifier", NULL, CONTINUE); + return NULL; + } + + /* + * Handle numeric-only object identifiers, + * by labelling the first sub-identifier + */ + op = loid; + if (!op->label) { + if (length == 1) { + print_error("Attempt to define a root oid", name, OBJECT); + return NULL; + } + for (tp = tree_head; tp; tp = tp->next_peer) + if ((int) tp->subid == op->subid) { + op->label = strdup(tp->label); + break; + } + } + + /* + * Handle "label OBJECT-IDENTIFIER ::= { subid }" + */ + if (length == 1) { + op = loid; + np = alloc_node(op->modid); + if (np == NULL) + return (NULL); + np->subid = op->subid; + np->label = strdup(name); + np->parent = op->label; + return np; + } + + /* + * For each parent-child subid pair in the subid array, + * create a node and link it into the node list. + */ + for (count = 0, op = loid, nop = loid + 1; count < (length - 1); + count++, op++, nop++) { + /* + * every node must have parent's name and child's name or number + */ + /* + * XX the next statement is always true -- does it matter ?? + */ + if (op->label && (nop->label || (nop->subid != -1))) { + np = alloc_node(nop->modid); + if (np == NULL) + return (NULL); + if (root == NULL) + root = np; + + np->parent = strdup(op->label); + if (count == (length - 2)) { + /* + * The name for this node is the label for this entry + */ + np->label = strdup(name); + } else { + if (!nop->label) { + nop->label = (char *) malloc(20 + ANON_LEN); + if (nop->label == NULL) + return (NULL); + sprintf(nop->label, "%s%d", ANON, anonymous++); + } + np->label = strdup(nop->label); + } + if (nop->subid != -1) + np->subid = nop->subid; + else + print_error("Warning: This entry is pretty silly", + np->label, CONTINUE); + + /* + * set up next entry + */ + if (oldnp) + oldnp->next = np; + oldnp = np; + } /* end if(op->label... */ + } + + /* + * free the loid array + */ + for (count = 0, op = loid; count < length; count++, op++) { + if (op->label) + free(op->label); + } + + return root; +} + +/* + * Parses an OBJECT GROUP macro. + * Returns 0 on error. + * + * Also parses object-identity, since they are similar (ignore STATUS). + * - WJH 10/96 + */ +static struct node *parse_objectgroup(FILE * fp, char *name, int what, struct objgroup **ol) +{ + int type; + char token[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + struct node *np; + + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, MAXTOKEN); + if (type == what) { + type = get_token(fp, token, MAXTOKEN); + if (type != LEFTBRACKET) { + print_error("Expected \"{\"", token, type); + goto skip; + } + do { + struct objgroup *o; + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad identifier", token, type); + goto skip; + } + o = (struct objgroup *) malloc(sizeof(struct objgroup)); + if (!o) { + print_error("Resource failure", token, type); + goto skip; + } + o->line = mibLine; + o->name = strdup(token); + o->next = *ol; + *ol = o; + type = get_token(fp, token, MAXTOKEN); + } while (type == COMMA); + if (type != RIGHTBRACKET) { + print_error("Expected \"}\" after list", token, type); + goto skip; + } + type = get_token(fp, token, type); + } + if (type != STATUS) { + print_error("Expected STATUS", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != CURRENT && type != DEPRECATED && type != OBSOLETE) { + print_error("Bad STATUS value", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != DESCRIPTION) { + print_error("Expected DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->description = strdup(quoted_string_buffer); + type = get_token(fp, token, MAXTOKEN); + if (type == REFERENCE) { + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad REFERENCE", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->reference = strdup(quoted_string_buffer); + type = get_token(fp, token, MAXTOKEN); + } + if (type != EQUALS) + print_error("Expected \"::=\"", token, type); + skip: + while (type != EQUALS && type != ENDOFFILE) + type = get_token(fp, token, MAXTOKEN); + + return merge_parse_objectid(np, fp, name); +} + +static int parseQuoteString(FILE * fp, char *token, int maxtlen) +{ + register int ch; + int count = 0; + int too_long = 0; + char *token_start = token; + + for (ch = getc(fp); ch != EOF; ch = getc(fp)) { + if (ch == '\r') + continue; + if (ch == '\n') { + mibLine++; + } else if (ch == '"') { + *token = '\0'; + if (too_long) + { + /* + * show short form for brevity sake + */ + char ch_save = *(token_start + 50); + *(token_start + 50) = '\0'; + print_error("Warning: string too long", + token_start, QUOTESTRING); + *(token_start + 50) = ch_save; + } + return QUOTESTRING; + } + /* + * maximum description length check. If greater, keep parsing + * but truncate the string + */ + if (++count < maxtlen) + *token++ = ch; + else + too_long = 1; + } + + return 0; +} + +/* + * Parses a TRAP-TYPE macro. + * Returns 0 on error. + */ +static struct node *parse_trapDefinition(FILE * fp, char *name) +{ + register int type; + char token[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + register struct node *np; + + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, MAXTOKEN); + while (type != EQUALS && type != ENDOFFILE) { + switch (type) { + case DESCRIPTION: + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->description = strdup(quoted_string_buffer); + break; + case REFERENCE: + /* I'm not sure REFERENCEs are legal in smiv1 traps??? */ + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad REFERENCE", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->reference = strdup(quoted_string_buffer); + break; + case ENTERPRISE: + type = get_token(fp, token, MAXTOKEN); + if (type == LEFTBRACKET) { + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad Trap Format", token, type); + free_node(np); + return NULL; + } + np->parent = strdup(token); + /* + * Get right bracket + */ + type = get_token(fp, token, MAXTOKEN); + } else if (type == LABEL) + np->parent = strdup(token); + break; + case VARIABLES: + np->varbinds = getVarbinds(fp, &np->varbinds); + if (!np->varbinds) { + print_error("Bad VARIABLES list", token, type); + free_node(np); + return NULL; + } + break; + default: + /* + * NOTHING + */ + break; + } + type = get_token(fp, token, MAXTOKEN); + } + type = get_token(fp, token, MAXTOKEN); + + np->label = strdup(name); + + if (type != NUMBER) { + print_error("Expected a Number", token, type); + free_node(np); + return NULL; + } + np->subid = strtoul(token, NULL, 10); + np->next = alloc_node(current_module); + if (np->next == NULL) { + free_node(np); + return (NULL); + } + np->next->parent = np->parent; + np->parent = (char *) malloc(strlen(np->parent) + 2); + if (np->parent == NULL) { + free_node(np->next); + free_node(np); + return (NULL); + } + strcpy(np->parent, np->next->parent); + strcat(np->parent, "#"); + np->next->label = strdup(np->parent); + return np; +} + +/* + * Parses a NOTIFICATION-TYPE macro. + * Returns 0 on error. + */ +static struct node *parse_notificationDefinition(FILE * fp, char *name) +{ + register int type; + char token[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + register struct node *np; + + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, MAXTOKEN); + while (type != EQUALS && type != ENDOFFILE) { + switch (type) { + case DESCRIPTION: + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->description = strdup(quoted_string_buffer); + break; + case REFERENCE: + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad REFERENCE", quoted_string_buffer, type); + free_node(np); + return NULL; + } + np->reference = strdup(quoted_string_buffer); + break; + case OBJECTS: + np->varbinds = getVarbinds(fp, &np->varbinds); + if (!np->varbinds) { + print_error("Bad OBJECTS list", token, type); + free_node(np); + return NULL; + } + break; + default: + /* + * NOTHING + */ + break; + } + type = get_token(fp, token, MAXTOKEN); + } + return merge_parse_objectid(np, fp, name); +} + +static struct node *parse_compliance(FILE * fp, char *name) +{ + int type; + char token[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + struct node *np; + + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, MAXTOKEN); + if (type != STATUS) { + print_error("Expected STATUS", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != CURRENT && type != DEPRECATED && type != OBSOLETE) { + print_error("Bad STATUS", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != DESCRIPTION) { + print_error("Expected DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", quoted_string_buffer, type); + goto skip; + } + np->description = strdup(quoted_string_buffer); + type = get_token(fp, token, MAXTOKEN); + if (type == REFERENCE) { + type = get_token(fp, quoted_string_buffer, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Bad REFERENCE", quoted_string_buffer, type); + goto skip; + } + np->reference = strdup(quoted_string_buffer); + type = get_token(fp, token, MAXTOKEN); + } + if (type != MODULE) { + print_error("Expected MODULE", token, type); + goto skip; + } + while (type == MODULE) { + int modid = -1; + char modname[MAXTOKEN]; + type = get_token(fp, token, MAXTOKEN); + if (type == LABEL + && strcmp(token, module_name(current_module, modname))) { + modid = read_module_internal(token); + if (modid != MODULE_LOADED_OK + && modid != MODULE_ALREADY_LOADED) { + print_error("Unknown module", token, type); + goto skip; + } + modid = which_module(token); + type = get_token(fp, token, MAXTOKEN); + } + if (type == MANDATORYGROUPS) { + type = get_token(fp, token, MAXTOKEN); + if (type != LEFTBRACKET) { + print_error("Expected \"{\"", token, type); + goto skip; + } + do { + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad group name", token, type); + goto skip; + } + if (!compliance_lookup(token, modid)) + print_error("Unknown group", token, type); + type = get_token(fp, token, MAXTOKEN); + } while (type == COMMA); + if (type != RIGHTBRACKET) { + print_error("Expected \"}\"", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + while (type == GROUP || type == OBJECT) { + if (type == GROUP) { + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad group name", token, type); + goto skip; + } + if (!compliance_lookup(token, modid)) + print_error("Unknown group", token, type); + type = get_token(fp, token, MAXTOKEN); + } else { + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad object name", token, type); + goto skip; + } + if (!compliance_lookup(token, modid)) + print_error("Unknown group", token, type); + type = get_token(fp, token, MAXTOKEN); + if (type == SYNTAX) + type = eat_syntax(fp, token, MAXTOKEN); + if (type == WRSYNTAX) + type = eat_syntax(fp, token, MAXTOKEN); + if (type == MINACCESS) { + type = get_token(fp, token, MAXTOKEN); + if (type != NOACCESS && type != ACCNOTIFY + && type != READONLY && type != WRITEONLY + && type != READCREATE && type != READWRITE) { + print_error("Bad MIN-ACCESS spec", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + } + if (type != DESCRIPTION) { + print_error("Expected DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + } + skip: + while (type != EQUALS && type != ENDOFFILE) + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + + return merge_parse_objectid(np, fp, name); +} + +/* + * Parses a capabilities macro + * Returns 0 on error. + */ +static struct node *parse_capabilities(FILE * fp, char *name) +{ + int type; + char token[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + struct node *np; + + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, MAXTOKEN); + if (type != PRODREL) { + print_error("Expected PRODUCT-RELEASE", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Expected STRING after PRODUCT-RELEASE", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != STATUS) { + print_error("Expected STATUS", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != CURRENT && type != OBSOLETE) { + print_error("STATUS should be current or obsolete", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != DESCRIPTION) { + print_error("Expected DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", token, type); + goto skip; + } + np->description = strdup(token); + type = get_token(fp, token, MAXTOKEN); + if (type == REFERENCE) { + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Bad REFERENCE", token, type); + goto skip; + } + np->reference = strdup(token); + type = get_token(fp, token, type); + } + while (type == SUPPORTS) { + int modid; + struct tree *tp; + + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad module name", token, type); + goto skip; + } + modid = read_module_internal(token); + if (modid != MODULE_LOADED_OK && modid != MODULE_ALREADY_LOADED) { + print_error("Module not found", token, type); + goto skip; + } + modid = which_module(token); + type = get_token(fp, token, MAXTOKEN); + if (type != INCLUDES) { + print_error("Expected INCLUDES", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != LEFTBRACKET) { + print_error("Expected \"{\"", token, type); + goto skip; + } + do { + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Expected group name", token, type); + goto skip; + } + tp = find_tree_node(token, modid); + if (!tp) + print_error("Group not found in module", token, type); + type = get_token(fp, token, MAXTOKEN); + } while (type == COMMA); + if (type != RIGHTBRACKET) { + print_error("Expected \"}\" after group list", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + while (type == VARIATION) { + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad object name", token, type); + goto skip; + } + tp = find_tree_node(token, modid); + if (!tp) + print_error("Object not found in module", token, type); + type = get_token(fp, token, MAXTOKEN); + if (type == SYNTAX) { + type = eat_syntax(fp, token, MAXTOKEN); + } + if (type == WRSYNTAX) { + type = eat_syntax(fp, token, MAXTOKEN); + } + if (type == ACCESS) { + type = get_token(fp, token, MAXTOKEN); + if (type != ACCNOTIFY && type != READONLY + && type != READWRITE && type != READCREATE + && type != WRITEONLY && type != NOTIMPL) { + print_error("Bad ACCESS", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + if (type == CREATEREQ) { + type = get_token(fp, token, MAXTOKEN); + if (type != LEFTBRACKET) { + print_error("Expected \"{\"", token, type); + goto skip; + } + do { + type = get_token(fp, token, MAXTOKEN); + if (type != LABEL) { + print_error("Bad object name in list", token, + type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } while (type == COMMA); + if (type != RIGHTBRACKET) { + print_error("Expected \"}\" after list", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + if (type == DEFVAL) { + int level = 1; + type = get_token(fp, token, MAXTOKEN); + if (type != LEFTBRACKET) { + print_error("Expected \"{\" after DEFVAL", token, + type); + goto skip; + } + do { + type = get_token(fp, token, MAXTOKEN); + if (type == LEFTBRACKET) + level++; + else if (type == RIGHTBRACKET) + level--; + } while (type != RIGHTBRACKET && type != ENDOFFILE + && level != 0); + if (type != RIGHTBRACKET) { + print_error("Missing \"}\" after DEFVAL", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + if (type != DESCRIPTION) { + print_error("Expected DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + } + if (type != EQUALS) + print_error("Expected \"::=\"", token, type); + skip: + while (type != EQUALS && type != ENDOFFILE) { + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + } + return merge_parse_objectid(np, fp, name); +} + +static struct node *parse_moduleIdentity(FILE * fp, char *name) +{ + register int type; + char token[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + register struct node *np; + + np = alloc_node(current_module); + if (np == NULL) + return (NULL); + type = get_token(fp, token, MAXTOKEN); + if (type != LASTUPDATED) { + print_error("Expected LAST-UPDATED", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Need STRING for LAST-UPDATED", token, type); + goto skip; + } + check_utc(token); + type = get_token(fp, token, MAXTOKEN); + if (type != ORGANIZATION) { + print_error("Expected ORGANIZATION", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Bad ORGANIZATION", token, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != CONTACTINFO) { + print_error("Expected CONTACT-INFO", token, type); + goto skip; + } + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad CONTACT-INFO", quoted_string_buffer, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + if (type != DESCRIPTION) { + print_error("Expected DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", quoted_string_buffer, type); + goto skip; + } + np->description = strdup(quoted_string_buffer); + type = get_token(fp, token, MAXTOKEN); + while (type == REVISION) { + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) { + print_error("Bad REVISION", token, type); + goto skip; + } + check_utc(token); + type = get_token(fp, token, MAXTOKEN); + if (type != DESCRIPTION) { + print_error("Expected DESCRIPTION", token, type); + goto skip; + } + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) { + print_error("Bad DESCRIPTION", quoted_string_buffer, type); + goto skip; + } + type = get_token(fp, token, MAXTOKEN); + } + if (type != EQUALS) + print_error("Expected \"::=\"", token, type); + skip: + while (type != EQUALS && type != ENDOFFILE) { + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + } + return merge_parse_objectid(np, fp, name); +} + +/* + * Parses an asn type. Structures are ignored by this parser. + * Returns NULL on error. + */ +static struct node *parse_asntype(FILE * fp, char *name, int *ntype, char *ntoken) +{ + int type, i; + char token[MAXTOKEN]; + char quoted_string_buffer[MAXQUOTESTR]; + char *hint = NULL; + char *descr = NULL; + struct tc *tcp; + int level; + + type = get_token(fp, token, MAXTOKEN); + if (type == SEQUENCE || type == CHOICE) { + level = 0; + while ((type = get_token(fp, token, MAXTOKEN)) != ENDOFFILE) { + if (type == LEFTBRACKET) { + level++; + } else if (type == RIGHTBRACKET && --level == 0) { + *ntype = get_token(fp, ntoken, MAXTOKEN); + return NULL; + } + } + print_error("Expected \"}\"", token, type); + return NULL; + } else if (type == LEFTBRACKET) { + struct node *np; + int ch_next = '{'; + ungetc(ch_next, fp); + np = parse_objectid(fp, name); + if (np != NULL) { + *ntype = get_token(fp, ntoken, MAXTOKEN); + return np; + } + return NULL; + } else if (type == LEFTSQBRACK) { + int size = 0; + do { + type = get_token(fp, token, MAXTOKEN); + } while (type != ENDOFFILE && type != RIGHTSQBRACK); + if (type != RIGHTSQBRACK) { + print_error("Expected \"]\"", token, type); + return NULL; + } + type = get_token(fp, token, MAXTOKEN); + if (type == IMPLICIT) + type = get_token(fp, token, MAXTOKEN); + *ntype = get_token(fp, ntoken, MAXTOKEN); + if (*ntype == LEFTPAREN) { + switch (type) { + case OCTETSTR: + *ntype = get_token(fp, ntoken, MAXTOKEN); + if (*ntype != SIZE) { + print_error("Expected SIZE", ntoken, *ntype); + return NULL; + } + size = 1; + *ntype = get_token(fp, ntoken, MAXTOKEN); + if (*ntype != LEFTPAREN) { + print_error("Expected \"(\" after SIZE", ntoken, + *ntype); + return NULL; + } + /* + * fall through + */ + case INTEGER: + *ntype = get_token(fp, ntoken, MAXTOKEN); + do { + if (*ntype != NUMBER) + print_error("Expected NUMBER", ntoken, *ntype); + *ntype = get_token(fp, ntoken, MAXTOKEN); + if (*ntype == RANGE) { + *ntype = get_token(fp, ntoken, MAXTOKEN); + if (*ntype != NUMBER) + print_error("Expected NUMBER", ntoken, *ntype); + *ntype = get_token(fp, ntoken, MAXTOKEN); + } + } while (*ntype == BAR); + if (*ntype != RIGHTPAREN) { + print_error("Expected \")\"", ntoken, *ntype); + return NULL; + } + *ntype = get_token(fp, ntoken, MAXTOKEN); + if (size) { + if (*ntype != RIGHTPAREN) { + print_error("Expected \")\" to terminate SIZE", + ntoken, *ntype); + return NULL; + } + *ntype = get_token(fp, ntoken, MAXTOKEN); + } + } + } + return NULL; + } else { + if (type == CONVENTION) { + while (type != SYNTAX && type != ENDOFFILE) { + if (type == DISPLAYHINT) { + type = get_token(fp, token, MAXTOKEN); + if (type != QUOTESTRING) + print_error("DISPLAY-HINT must be string", token, + type); + else + hint = strdup(token); + } else if (type == DESCRIPTION) { + type = get_token(fp, quoted_string_buffer, MAXQUOTESTR); + if (type != QUOTESTRING) + print_error("DESCRIPTION must be string", token, + type); + else + descr = strdup(quoted_string_buffer); + } else + type = + get_token(fp, quoted_string_buffer, MAXQUOTESTR); + } + type = get_token(fp, token, MAXTOKEN); + if (type == OBJECT) { + type = get_token(fp, token, MAXTOKEN); + if (type != IDENTIFIER) { + print_error("Expected IDENTIFIER", token, type); + SNMP_FREE(hint); + return NULL; + } + type = OBJID; + } + } else if (type == OBJECT) { + type = get_token(fp, token, MAXTOKEN); + if (type != IDENTIFIER) { + print_error("Expected IDENTIFIER", token, type); + return NULL; + } + type = OBJID; + } + + if (type == LABEL) { + type = get_tc(token, current_module, NULL, NULL, NULL, NULL); + } + + /* + * textual convention + */ + for (i = 0; i < MAXTC; i++) { + if (tclist[i].type == 0) + break; + } + + if (i == MAXTC) { + print_error("Too many textual conventions", token, type); + SNMP_FREE(hint); + return NULL; + } + if (!(type & SYNTAX_MASK)) { + print_error("Textual convention doesn't map to real type", + token, type); + SNMP_FREE(hint); + return NULL; + } + tcp = &tclist[i]; + tcp->modid = current_module; + tcp->descriptor = strdup(name); + tcp->hint = hint; + tcp->description = descr; + tcp->type = type; + *ntype = get_token(fp, ntoken, MAXTOKEN); + if (*ntype == LEFTPAREN) { + tcp->ranges = parse_ranges(fp, &tcp->ranges); + *ntype = get_token(fp, ntoken, MAXTOKEN); + } else if (*ntype == LEFTBRACKET) { + /* + * if there is an enumeration list, parse it + */ + tcp->enums = parse_enumlist(fp, &tcp->enums); + *ntype = get_token(fp, ntoken, MAXTOKEN); + } + return NULL; + } +} + +/* + * Parses a compliance macro + * Returns 0 on error. + */ +static int eat_syntax(FILE * fp, char *token, int maxtoken) +{ + int type, nexttype; + struct node *np = alloc_node(current_module); + char nexttoken[MAXTOKEN]; + + type = get_token(fp, token, maxtoken); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + switch (type) { + case INTEGER: + case INTEGER32: + case UINTEGER32: + case UNSIGNED32: + case COUNTER: + case GAUGE: + case BITSTRING: + case LABEL: + if (nexttype == LEFTBRACKET) { + /* + * if there is an enumeration list, parse it + */ + np->enums = parse_enumlist(fp, &np->enums); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + } else if (nexttype == LEFTPAREN) { + /* + * if there is a range list, parse it + */ + np->ranges = parse_ranges(fp, &np->ranges); + nexttype = get_token(fp, nexttoken, MAXTOKEN); + } + break; + case OCTETSTR: + case KW_OPAQUE: + /* + * parse any SIZE specification + */ + if (nexttype == LEFTPAREN) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + if (nexttype == SIZE) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + if (nexttype == LEFTPAREN) { + np->ranges = parse_ranges(fp, &np->ranges); + nexttype = get_token(fp, nexttoken, MAXTOKEN); /* ) */ + if (nexttype == RIGHTPAREN) { + nexttype = get_token(fp, nexttoken, MAXTOKEN); + break; + } + } + } + print_error("Bad SIZE syntax", token, type); + free_node(np); + return nexttype; + } + break; + case OBJID: + case NETADDR: + case IPADDR: + case TIMETICKS: + case NUL: + case NSAPADDRESS: + case COUNTER64: + break; + default: + print_error("Bad syntax", token, type); + free_node(np); + return nexttype; + } + free_node(np); + return nexttype; +} + +/* + * Parses a module identity macro + * Returns 0 on error. + */ +static void check_utc(const char *utc) +{ + int len, year, month, day, hour, minute; + + len = strlen(utc); + if (utc[len - 1] != 'Z' && utc[len - 1] != 'z') { + print_error("Timestamp should end with Z", utc, QUOTESTRING); + return; + } + if (len == 11) { + len = + sscanf(utc, "%2d%2d%2d%2d%2dZ", &year, &month, &day, &hour, + &minute); + year += 1900; + } else if (len == 13) + len = + sscanf(utc, "%4d%2d%2d%2d%2dZ", &year, &month, &day, &hour, + &minute); + else { + print_error("Bad timestamp format (11 or 13 characters)", + utc, QUOTESTRING); + return; + } + if (len != 5) { + print_error("Bad timestamp format", utc, QUOTESTRING); + return; + } + if (month < 1 || month > 12) + print_error("Bad month in timestamp", utc, QUOTESTRING); + if (day < 1 || day > 31) + print_error("Bad day in timestamp", utc, QUOTESTRING); + if (hour < 0 || hour > 23) + print_error("Bad hour in timestamp", utc, QUOTESTRING); + if (minute < 0 || minute > 59) + print_error("Bad minute in timestamp", utc, QUOTESTRING); +} +//end of support function definition---------------------------------------------- + +//tools definition---------------------------------------------------------------- +/* + * return zero if character is not a label character. + */ +static int is_labelchar(int ich) +{ + if ((isalnum(ich)) || (ich == '-')) + return 1; + + return 0; +} + +static void print_error(const char *str, const char *token, int type) +{ +// erroneousMibs++; + if (type == ENDOFFILE) + printf("%s (EOF): At line %d in %s\n", str, mibLine, File); + else if (token && *token) + printf("%s (%s): At line %d in %s\n", str, token, mibLine, File); + else + printf("%s: At line %d in %s\n", str, mibLine, File); +} + +static int name_hash(const char *name) +{ + int hash = 0; + const char *cp; + + if (!name) + return 0; + for (cp = name; *cp; cp++) + hash += tolower(*cp); + return (hash); +} + +static int translation_table[256]; +static void build_translation_table() +{ + int count; + + for (count = 0; count < 256; count++) { + switch (count) { + case OBJID: + translation_table[count] = TYPE_OBJID; + break; + case OCTETSTR: + translation_table[count] = TYPE_OCTETSTR; + break; + case INTEGER: + translation_table[count] = TYPE_INTEGER; + break; + case NETADDR: + translation_table[count] = TYPE_NETADDR; + break; + case IPADDR: + translation_table[count] = TYPE_IPADDR; + break; + case COUNTER: + translation_table[count] = TYPE_COUNTER; + break; + case GAUGE: + translation_table[count] = TYPE_GAUGE; + break; + case TIMETICKS: + translation_table[count] = TYPE_TIMETICKS; + break; + case KW_OPAQUE: + translation_table[count] = TYPE_OPAQUE; + break; + case NUL: + translation_table[count] = TYPE_NULL; + break; + case COUNTER64: + translation_table[count] = TYPE_COUNTER64 ; + break; + case BITSTRING: + translation_table[count] = TYPE_BITSTRING; + break; + case NSAPADDRESS: + translation_table[count] = TYPE_NSAPADDRESS; + break; + case INTEGER32: + translation_table[count] = TYPE_INTEGER32; + break; + case UINTEGER32: + translation_table[count] = TYPE_UINTEGER; + break; + case UNSIGNED32: + translation_table[count] = TYPE_UNSIGNED32; + break; + case TRAPTYPE: + translation_table[count] = TYPE_TRAPTYPE; + break; + case NOTIFTYPE: + translation_table[count] = TYPE_NOTIFTYPE; + break; + case NOTIFGROUP: + translation_table[count] = TYPE_NOTIFGROUP; + break; + case OBJGROUP: + translation_table[count] = TYPE_OBJGROUP; + break; + case MODULEIDENTITY: + translation_table[count] = TYPE_MODID; + break; + case OBJIDENTITY: + translation_table[count] = TYPE_OBJIDENTITY; + break; + case AGENTCAP: + translation_table[count] = TYPE_AGENTCAP; + break; + case COMPLIANCE: + translation_table[count] = TYPE_MODCOMP; + break; + default: + translation_table[count] = TYPE_OTHER; + break; + } + } +} + +void print_nodes(FILE * fp, struct node *root) +{ + extern void xmalloc_stats(FILE *); + struct enum_list *ep; + struct index_list *ip; + struct range_list *rp; + struct varbind_list *vp; + struct node *np; + + for (np = root; np; np = np->next) { + fprintf(fp, "%s ::= { %s %d } (%d)\n", np->label, np->parent, + np->subid, np->type); + if (np->tc_index >= 0) + fprintf(fp, " TC = %s\n", tclist[np->tc_index].descriptor); + if (np->enums) { + fprintf(fp, " Enums: \n"); + for (ep = np->enums; ep; ep = ep->next) { + fprintf(fp, " %s(%d)\n", ep->label, ep->value); + } + } + if (np->ranges) { + fprintf(fp, " Ranges: \n"); + for (rp = np->ranges; rp; rp = rp->next) { + fprintf(fp, " %d..%d\n", rp->low, rp->high); + } + } + if (np->indexes) { + fprintf(fp, " Indexes: \n"); + for (ip = np->indexes; ip; ip = ip->next) { + fprintf(fp, " %s\n", ip->ilabel); + } + } + if (np->augments) + fprintf(fp, " Augments: %s\n", np->augments); + if (np->varbinds) { + fprintf(fp, " Varbinds: \n"); + for (vp = np->varbinds; vp; vp = vp->next) { + fprintf(fp, " %s\n", vp->vblabel); + } + } + if (np->hint) + fprintf(fp, " Hint: %s\n", np->hint); + if (np->units) + fprintf(fp, " Units: %s\n", np->units); + if (np->defaultValue) + fprintf(fp, " DefaultValue: %s\n", np->defaultValue); + } +} + +static void init_node_hash(struct node *nodes) +{ + struct node *np, *nextp; + int hash; + + memset(nbuckets, 0, sizeof(nbuckets)); + for (np = nodes; np;) { + nextp = np->next; + hash = NBUCKET(name_hash(np->parent)); + np->next = nbuckets[hash]; + nbuckets[hash] = np; + np = nextp; + } +} + +/* + * return index into tclist of given TC descriptor + * return -1 if not found + */ +static int get_tc_index(const char *descriptor, int modid) +{ + int i; + struct tc *tcp; + struct module *mp; + struct module_import *mip; + + /* + * Check that the descriptor isn't imported + * by searching the import list + */ + + for (mp = module_head; mp; mp = mp->next) + if (mp->modid == modid) + break; + if (mp) + for (i = 0, mip = mp->imports; i < mp->no_imports; ++i, ++mip) { + if (!label_compare(mip->label, descriptor)) { + /* + * Found it - so amend the module ID + */ + modid = mip->modid; + break; + } + } + + + for (i = 0, tcp = tclist; i < MAXTC; i++, tcp++) { + if (tcp->type == 0) + break; + if (!label_compare(descriptor, tcp->descriptor) && + ((modid == tcp->modid) || (modid == -1))) { + return i; + } + } + return -1; +} + +static void free_indexes(struct index_list **spp) +{ + if (spp && *spp) { + struct index_list *pp, *npp; + + pp = *spp; + *spp = NULL; + + while (pp) { + npp = pp->next; + if (pp->ilabel) + free(pp->ilabel); + free(pp); + pp = npp; + } + } +} + +static void free_varbinds(struct varbind_list **spp) +{ + if (spp && *spp) { + struct varbind_list *pp, *npp; + + pp = *spp; + *spp = NULL; + + while (pp) { + npp = pp->next; + if (pp->vblabel) + free(pp->vblabel); + free(pp); + pp = npp; + } + } +} + +static void free_ranges(struct range_list **spp) +{ + if (spp && *spp) { + struct range_list *pp, *npp; + + pp = *spp; + *spp = NULL; + + while (pp) { + npp = pp->next; + free(pp); + pp = npp; + } + } +} + +static void free_enums(struct enum_list **spp) +{ + if (spp && *spp) { + struct enum_list *pp, *npp; + + pp = *spp; + *spp = NULL; + + while (pp) { + npp = pp->next; + if (pp->label) + free(pp->label); + free(pp); + pp = npp; + } + } +} + +static void free_partial_tree(struct tree *tp, int keep_label) +{ + if (!tp) + return; + + /* + * remove the data from this tree node + */ + free_enums(&tp->enums); + free_ranges(&tp->ranges); + free_indexes(&tp->indexes); + free_varbinds(&tp->varbinds); + if (!keep_label) + SNMP_FREE(tp->label); + SNMP_FREE(tp->hint); + SNMP_FREE(tp->units); + SNMP_FREE(tp->description); + SNMP_FREE(tp->reference); + SNMP_FREE(tp->augments); + SNMP_FREE(tp->defaultValue); +} + +/* + * transfer data to tree from node + * + * move pointers for alloc'd data from np to tp. + * this prevents them from being freed when np is released. + * parent member is not moved. + * + * CAUTION: nodes may be repeats of existing tree nodes. + * This can happen especially when resolving IMPORT clauses. + * + */ +static void tree_from_node(struct tree *tp, struct node *np) +{ + free_partial_tree(tp, FALSE); + + tp->label = np->label; + np->label = NULL; + tp->enums = np->enums; + np->enums = NULL; + tp->ranges = np->ranges; + np->ranges = NULL; + tp->indexes = np->indexes; + np->indexes = NULL; + tp->augments = np->augments; + np->augments = NULL; + tp->varbinds = np->varbinds; + np->varbinds = NULL; + tp->hint = np->hint; + np->hint = NULL; + tp->units = np->units; + np->units = NULL; + tp->description = np->description; + np->description = NULL; + tp->reference = np->reference; + np->reference = NULL; + tp->defaultValue = np->defaultValue; + np->defaultValue = NULL; + tp->subid = np->subid; + tp->oid_len = tp->parent->oid_len; + memcpy(tp->oid, tp->parent->oid, tp->oid_len * sizeof(int)); + tp->oid[tp->oid_len++] = np->subid; + tp->tc_index = np->tc_index; + tp->type = translation_table[np->type]; + tp->access = np->access; + tp->status = np->status; + +// set_function(tp); +} + +static void free_node(struct node *np) +{ + if (!np) + return; + + free_enums(&np->enums); + free_ranges(&np->ranges); + free_indexes(&np->indexes); + free_varbinds(&np->varbinds); + if (np->label) + free(np->label); + if (np->hint) + free(np->hint); + if (np->units) + free(np->units); + if (np->description) + free(np->description); + if (np->reference) + free(np->reference); + if (np->defaultValue) + free(np->defaultValue); + if (np->parent) + free(np->parent); + if (np->augments) + free(np->augments); + if (np->filename) + free(np->filename); + free((char *) np); +} + +/* + * free a tree node. Note: the node must already have been unlinked + * from the tree when calling this routine + */ +void free_tree(struct tree *Tree) +{ + if (!Tree) + return; + + unlink_tbucket(Tree); + free_partial_tree(Tree, FALSE); + if (Tree->number_modules > 1) + free((char *) Tree->module_list); + free((char *) Tree); +} + +static struct enum_list *copy_enums(struct enum_list *sp) +{ + struct enum_list *xp = NULL, **spp = &xp; + + while (sp) { + *spp = (struct enum_list *) calloc(1, sizeof(struct enum_list)); + if (!*spp) + break; + (*spp)->label = strdup(sp->label); + (*spp)->value = sp->value; + spp = &(*spp)->next; + sp = sp->next; + } + return (xp); +} + +static struct range_list *copy_ranges(struct range_list *sp) +{ + struct range_list *xp = NULL, **spp = &xp; + + while (sp) { + *spp = (struct range_list *) calloc(1, sizeof(struct range_list)); + if (!*spp) + break; + (*spp)->low = sp->low; + (*spp)->high = sp->high; + spp = &(*spp)->next; + sp = sp->next; + } + return (xp); +} + +static void unlink_tbucket(struct tree *tp) +{ + int hash = NBUCKET(name_hash(tp->label)); + struct tree *otp = NULL, *ntp = tbuckets[hash]; + + while (ntp && ntp != tp) { + otp = ntp; + ntp = ntp->next; + } + if (!ntp) + printf("Can't find %s in tbuckets\n", tp->label); + else if (otp) + otp->next = ntp->next; + else + tbuckets[hash] = tp->next; +} + +static void unlink_tree(struct tree *tp) +{ + struct tree *otp = NULL, *ntp = tp->parent; + + if (ntp){ + ntp = ntp->child_list; + + while (ntp && ntp != tp) { + otp = ntp; + ntp = ntp->next_peer; + } + if (!ntp) + printf("Can't find %s in %s's children\n", + tp->label, tp->parent->label); + else if (otp) + otp->next_peer = ntp->next_peer; + else + tp->parent->child_list = tp->next_peer; + } + + if (tree_head == tp) + tree_head = tp->next_peer; +} + +int which_module(const char *name) +{ + struct module *mp; + + for (mp = module_head; mp; mp = mp->next) + if (!label_compare(mp->name, name)) + return (mp->modid); + + return (-1); +} + +static struct node *alloc_node(int modid) +{ + struct node *np; + np = (struct node *) calloc(1, sizeof(struct node)); + if (np) { + np->tc_index = -1; + np->modid = modid; + np->filename = strdup(File); + np->lineno = mibLine; + } + return np; +} + +static int get_tc(const char *descriptor, int modid, int *tc_index, + struct enum_list **ep, struct range_list **rp, char **hint) +{ + int i; + struct tc *tcp; + + i = get_tc_index(descriptor, modid); + if (tc_index) + *tc_index = i; + if (i != -1) { + tcp = &tclist[i]; + if (ep) { + free_enums(ep); + *ep = copy_enums(tcp->enums); + } + if (rp) { + free_ranges(rp); + *rp = copy_ranges(tcp->ranges); + } + if (hint) { + if (*hint) + free(*hint); + *hint = (tcp->hint ? strdup(tcp->hint) : NULL); + } + return tcp->type; + } + return LABEL; +} + +/* + * struct index_list * + * getIndexes(FILE *fp): + * This routine parses a string like { blah blah blah } and returns a + * list of the strings enclosed within it. + * + */ +static struct index_list *getIndexes(FILE * fp, struct index_list **retp) +{ + int type; + char token[MAXTOKEN]; + char nextIsImplied = 0; + + struct index_list *mylist = NULL; + struct index_list **mypp = &mylist; + + free_indexes(retp); + + type = get_token(fp, token, MAXTOKEN); + + if (type != LEFTBRACKET) { + return NULL; + } + + type = get_token(fp, token, MAXTOKEN); + while (type != RIGHTBRACKET && type != ENDOFFILE) { + if ((type == LABEL) || (type & SYNTAX_MASK)) { + *mypp = + (struct index_list *) calloc(1, sizeof(struct index_list)); + if (*mypp) { + (*mypp)->ilabel = strdup(token); + (*mypp)->isimplied = nextIsImplied; + mypp = &(*mypp)->next; + nextIsImplied = 0; + } + } else if (type == IMPLIED) { + nextIsImplied = 1; + } + type = get_token(fp, token, MAXTOKEN); + } + + *retp = mylist; + return mylist; +} + +/* + * This routine parses a string like { blah blah blah } and returns OBJID if + * it is well formed, and NULL if not. + */ +static int tossObjectIdentifier(FILE * fp) +{ + int type; + char token[MAXTOKEN]; + int bracketcount = 1; + + type = get_token(fp, token, MAXTOKEN); + + if (type != LEFTBRACKET) + return 0; + while ((type != RIGHTBRACKET || bracketcount > 0) && type != ENDOFFILE) { + type = get_token(fp, token, MAXTOKEN); + if (type == LEFTBRACKET) + bracketcount++; + else if (type == RIGHTBRACKET) + bracketcount--; + } + + if (type == RIGHTBRACKET) + return OBJID; + else + return 0; +} + +/* + * Merge the parsed object identifier with the existing node. + * If there is a problem with the identifier, release the existing node. + */ +static struct node *merge_parse_objectid(struct node *np, FILE * fp, char *name) +{ + struct node *nnp; + /* + * printf("merge defval --> %s\n",np->defaultValue); + */ + nnp = parse_objectid(fp, name); + if (nnp) { + + /* + * apply last OID sub-identifier data to the information + */ + /* + * already collected for this node. + */ + struct node *headp, *nextp; + int ncount = 0; + nextp = headp = nnp; + while (nnp->next) { + nextp = nnp; + ncount++; + nnp = nnp->next; + } + + np->label = nnp->label; + np->subid = nnp->subid; + np->modid = nnp->modid; + np->parent = nnp->parent; + if (nnp->filename != NULL) { + free(nnp->filename); + } + free(nnp); + + if (ncount) { + nextp->next = np; + np = headp; + } + } else { + free_node(np); + np = NULL; + } + + return np; +} + +/* + * Takes a list of the form: + * { iso org(3) dod(6) 1 } + * and creates several nodes, one for each parent-child pair. + * Returns 0 on error. + */ +static int getoid(FILE * fp, struct subid_s *id, /* an array of subids */ + int length) /* the length of the array */ +{ + register int count; + int type; + char token[MAXTOKEN]; + + if ((type = get_token(fp, token, MAXTOKEN)) != LEFTBRACKET) { + print_error("Expected \"{\"", token, type); + return 0; + } + type = get_token(fp, token, MAXTOKEN); + for (count = 0; count < length; count++, id++) { + id->label = NULL; + id->modid = current_module; + id->subid = -1; + if (type == RIGHTBRACKET){ + return count; + } + if (type == LABEL) { + /* + * this entry has a label + */ + id->label = strdup(token); + type = get_token(fp, token, MAXTOKEN); + if (type == LEFTPAREN) { + type = get_token(fp, token, MAXTOKEN); + if (type == NUMBER) { + id->subid = strtoul(token, NULL, 10); + if ((type = + get_token(fp, token, MAXTOKEN)) != RIGHTPAREN) { + print_error("Expected a closing parenthesis", + token, type); + return 0; + } + } else { + print_error("Expected a number", token, type); + return 0; + } + } else { + continue; + } + } else if (type == NUMBER) { + /* + * this entry has just an integer sub-identifier + */ + id->subid = strtoul(token, NULL, 10); + } else { + print_error("Expected label or number", token, type); + return 0; + } + type = get_token(fp, token, MAXTOKEN); + } + print_error("Too long OID", token, type); + return 0; +} + +static struct varbind_list *getVarbinds(FILE * fp, struct varbind_list **retp) +{ + int type; + char token[MAXTOKEN]; + + struct varbind_list *mylist = NULL; + struct varbind_list **mypp = &mylist; + + free_varbinds(retp); + + type = get_token(fp, token, MAXTOKEN); + + if (type != LEFTBRACKET) { + return NULL; + } + + type = get_token(fp, token, MAXTOKEN); + while (type != RIGHTBRACKET && type != ENDOFFILE) { + if ((type == LABEL) || (type & SYNTAX_MASK)) { + *mypp = + (struct varbind_list *) calloc(1, + sizeof(struct + varbind_list)); + if (*mypp) { + (*mypp)->vblabel = strdup(token); + mypp = &(*mypp)->next; + } + } + type = get_token(fp, token, MAXTOKEN); + } + + *retp = mylist; + return mylist; +} + +static int compliance_lookup(const char *name, int modid) +{ + if (modid == -1) { + struct objgroup *op = + (struct objgroup *) malloc(sizeof(struct objgroup)); + if (!op) + return 0; + op->next = objgroups; + op->name = strdup(name); + op->line = mibLine; + objgroups = op; + return 1; + } else + return find_tree_node(name, modid) != NULL; +} + +/* + * module_name - copy module name to user buffer, return ptr to same. + */ +char *module_name(int modid, char *cp) +{ + struct module *mp; + + for (mp = module_head; mp; mp = mp->next) + if (mp->modid == modid) { + strcpy(cp, mp->name); + return (cp); + } + + sprintf(cp, "#%d", modid); + return (cp); +} + +struct tree *find_tree_node(const char *name, int modid) +{ + struct tree *tp, *headtp; + int count, *int_p; + + if (!name || !*name) + return (NULL); + + headtp = tbuckets[NBUCKET(name_hash(name))]; + for (tp = headtp; tp; tp = tp->next) { + if (tp->label && !label_compare(tp->label, name)) { + + if (modid == -1) /* Any module */ + return (tp); + + for (int_p = tp->module_list, count = 0; + count < tp->number_modules; ++count, ++int_p) + if (*int_p == modid) + return (tp); + } + } + + return (NULL); +} + +static void print_module_not_found(const char *cp) +{ + if (!last_err_module || strcmp(cp, last_err_module)) + print_error("Cannot find module", cp, CONTINUE); + if (last_err_module) + free(last_err_module); + last_err_module = strdup(cp); +} + +void print_subtree(FILE * f, struct tree *tree, int count) +{ + struct tree *tp; + int i; + char modbuf[256]; + + for (i = 0; i < count; i++) + fprintf(f, " "); + + fprintf(f, "Children of %s(%d):\n", tree->label, tree->subid); + count++; + + for (tp = tree->child_list; tp; tp = tp->next_peer) { + for (i = 0; i < count; i++) + fprintf(f, " "); + + fprintf(f, "%s:%s(%d) type=%d", + module_name(tp->module_list[0], modbuf), + tp->label, tp->subid, tp->type); + if (tp->tc_index != -1) + fprintf(f, " tc=%d", tp->tc_index); + if (tp->hint) + fprintf(f, " hint=%s", tp->hint); + if (tp->units) + fprintf(f, " units=%s", tp->units); + + if (tp->number_modules > 1) { + fprintf(f, " modules:"); + for (i = 1; i < tp->number_modules; i++) + fprintf(f, " %s", module_name(tp->module_list[i], modbuf)); + } + fprintf(f, " OID: %d", tp->oid[0]); + for(i = 1; i < tp->oid_len; i++) + fprintf(f, ".%d", tp->oid[i]); + + fprintf(f, "\n"); + } + + for (tp = tree->child_list; tp; tp = tp->next_peer) { + if (tp->child_list) + print_subtree(f, tp, count); + } +} + +//end of tools definition--------------------------------------------------------- + diff --git a/plat/snmp/src/mib_parser/snmp_mib.h b/plat/snmp/src/mib_parser/snmp_mib.h new file mode 100644 index 0000000..9a94f1d --- /dev/null +++ b/plat/snmp/src/mib_parser/snmp_mib.h @@ -0,0 +1,171 @@ +/******************************************************************** +Copyright ?2007 LGC Wireless, Inc. All rights reserved +File Name: snmp_mib.h +Description: header file of snmp mib parser +Version: v9.0.0 +Author: Roy Jiang +Create Date: 2007-6-9 + +History: +2007-6-9 v9.0.0 Create + +BEWARE: Portions of this file are subject to the copyrights of + open-source project Net-SNMP.See the Net-SNMP's COPYING file + for more details +*********************************************************************/ +#ifndef __WXC2_SNMP_MIB_H_ +#define __WXC2_SNMP_MIB_H_ + +#define MAXLABEL 64 /* maximum characters in a label */ +#define MAXTOKEN 128 /* maximum characters in a token */ +#define MAXQUOTESTR (8192*4) /* maximum characters in a quoted string */ + +struct variable_list; + +/* + * A linked list of tag-value pairs for enumerated integers. + */ +struct enum_list { + struct enum_list *next; + int value; + char *label; +}; + +/* + * A linked list of ranges + */ +struct range_list { + struct range_list *next; + int low, high; +}; + +/* + * A linked list of indexes + */ +struct index_list { + struct index_list *next; + char *ilabel; + char isimplied; +}; + +/* + * A linked list of varbinds + */ +struct varbind_list { + struct varbind_list *next; + char *vblabel; +}; + +/* + * A tree in the format of the tree structure of the MIB. + */ +struct tree { + struct tree *child_list; /* list of children of this node */ + struct tree *next_peer; /* Next node in list of peers */ + struct tree *next; /* Next node in hashed list of names */ + struct tree *parent; + char *label; /* This node's textual name */ + int subid; /* This node's integer subidentifier */ + int modid; /* The module containing this node */ + int number_modules; + int *module_list; /* To handle multiple modules */ + int tc_index; /* index into tclist (-1 if NA) */ + int type; /* This node's object type */ + int access; /* This nodes access */ + int status; /* This nodes status */ + struct enum_list *enums; /* (optional) list of enumerated integers */ + struct range_list *ranges; + struct index_list *indexes; + char *augments; + struct varbind_list *varbinds; + char *hint; + char *units; + char *description; /* description (a quoted string) */ + char *reference; /* references (a quoted string) */ + int reported; /* 1=report started in print_subtree... */ + char *defaultValue; + int oid[32]; + int oid_len; +}; + +/* + * Information held about each MIB module + */ +struct module_import { + char *label; /* The descriptor being imported */ + int modid; /* The module imported from */ +}; + +struct module { + char *name; /* This module's name */ + char *file; /* The file containing the module */ + struct module_import *imports; /* List of descriptors being imported */ + int no_imports; /* The number of such import descriptors */ + /* + * -1 implies the module hasn't been read in yet + */ + int modid; /* The index number of this module */ + struct module *next; /* Linked list pointer */ +}; + +struct module_compatability { + const char *old_module; + const char *new_module; + const char *tag; /* NULL implies unconditional replacement, + * otherwise node identifier or prefix */ + size_t tag_len; /* 0 implies exact match (or unconditional) */ + struct module_compatability *next; /* linked list */ +}; + + +/* + * non-aggregate types for tree end nodes + */ +#define TYPE_OTHER 0 +#define TYPE_OBJID 1 +#define TYPE_OCTETSTR 2 +#define TYPE_INTEGER 3 +#define TYPE_NETADDR 4 +#define TYPE_IPADDR 5 +#define TYPE_COUNTER 6 +#define TYPE_GAUGE 7 +#define TYPE_TIMETICKS 8 +#define TYPE_OPAQUE 9 +#define TYPE_NULL 10 +#define TYPE_COUNTER64 11 +#define TYPE_BITSTRING 12 +#define TYPE_NSAPADDRESS 13 +#define TYPE_UINTEGER 14 +#define TYPE_UNSIGNED32 15 +#define TYPE_INTEGER32 16 + +#define TYPE_SIMPLE_LAST 16 + +#define TYPE_TRAPTYPE 20 +#define TYPE_NOTIFTYPE 21 +#define TYPE_OBJGROUP 22 +#define TYPE_NOTIFGROUP 23 +#define TYPE_MODID 24 +#define TYPE_AGENTCAP 25 +#define TYPE_MODCOMP 26 +#define TYPE_OBJIDENTITY 27 + +#define MIB_ACCESS_READONLY 18 +#define MIB_ACCESS_READWRITE 19 +#define MIB_ACCESS_WRITEONLY 20 +#define MIB_ACCESS_NOACCESS 21 +#define MIB_ACCESS_NOTIFY 67 +#define MIB_ACCESS_CREATE 48 + +#define MIB_STATUS_MANDATORY 23 +#define MIB_STATUS_OPTIONAL 24 +#define MIB_STATUS_OBSOLETE 25 +#define MIB_STATUS_DEPRECATED 39 +#define MIB_STATUS_CURRENT 57 + +#define ANON "anonymous#" +#define ANON_LEN strlen(ANON) + + + +#endif diff --git a/plat/snmp/src/mib_parser/snmp_mib_api.c b/plat/snmp/src/mib_parser/snmp_mib_api.c new file mode 100644 index 0000000..e5039aa --- /dev/null +++ b/plat/snmp/src/mib_parser/snmp_mib_api.c @@ -0,0 +1,122 @@ +/*********************************************************************** +Copyright ?2007 LGC Wireless, Inc. All rights reserved +File Name: snmp_mib_api.c +Description: API for SNMP MIB parser +Version: v9.0.0 +Author: Roy Jiang +Create Date: 2007-6-19 + +History: +2007-6-9 v9.0.0 Create +***********************************************************************/ +#include +#include +#include "snmp_mib.h" +#include "snmp_mib_api.h" + +const char *mib_dir = "./mib"; +const char *index_file = "index"; + +extern struct tree *tree_head; +extern struct module *module_head; +extern void new_module(const char *name, const char *file); +extern struct tree *read_module(const char *name); +extern int get_token(FILE * fp, char *token, int maxtlen); +extern void print_subtree(FILE * f, struct tree *tree, int count); +extern struct tree *find_tree_node(const char *name, int modid); +extern void free_tree(struct tree *Tree); + +//return 0 on success +int init_mib() +{ + //open dir and check mib files in the dir + { + FILE *ip, *fp; + char tmpstr[300]; + int count = 0; + char token[MAXTOKEN]; + char newline; + struct stat dir_stat, idx_stat; + char tmpstr1[300]; + + printf("Scanning directory %s\n", mib_dir); + + snprintf(token, sizeof(token), "%s/%s", mib_dir, index_file); + token[ sizeof(token)-1 ] = 0; + if (stat(token, &idx_stat) == 0 && stat(mib_dir, &dir_stat) == 0) { + if ((ip = fopen(token, "r")) != NULL) { + while (fscanf(ip, "%256s%c", tmpstr, &newline) == 2) + { + /* + * If an overflow of the token or tmpstr buffers has been + * found log a message and break out of the while loop, + * thus the rest of the file tokens will be ignored. + */ + if (newline != '\n') { + printf("add_mibdir: strings scanned in from %s/%s " \ + "are too large. count = %d\n ", mib_dir, + ".index", count); + break; + } + + snprintf(tmpstr1, sizeof(tmpstr1), "%s/%s", mib_dir, tmpstr); + tmpstr1[ sizeof(tmpstr1)-1 ] = 0; + fp = fopen(tmpstr1, "r"); + if (fp == NULL) { + printf("Can not open mib file: %s\n", tmpstr1); + continue; + } + get_token(fp, token, MAXTOKEN); + fclose(fp); + new_module(token, tmpstr1); + count++; + } + fclose(ip); + } + else + printf("Can't read index\n"); + } + else + printf("No index\n"); + } + + //read all mibs + { + struct module *mp; + for (mp = module_head; mp; mp = mp->next) + if (mp->no_imports == -1) + read_module(mp->name); + } + +#ifdef _TEST_ +{ + //for debug + print_subtree(stdout, tree_head, 0); +} +#endif + + return 0; +} + +struct tree *getLGCroot() +{ + return find_tree_node("lgcNS", -1); +} + +void close_mib() +{ + free_tree(tree_head); + return; +} + +//test---------------------------------------------------------------------------- +#ifdef _TEST_ +int main(int argc, char *argv[]) +{ + init_mib(); + + return 0; +} +#endif +//end of test--------------------------------------------------------------------- + diff --git a/plat/snmp/src/mib_parser/snmp_mib_api.h b/plat/snmp/src/mib_parser/snmp_mib_api.h new file mode 100644 index 0000000..754ae75 --- /dev/null +++ b/plat/snmp/src/mib_parser/snmp_mib_api.h @@ -0,0 +1,49 @@ +/*********************************************************************** +Copyright ?2007 LGC Wireless, Inc. All rights reserved +File Name: snmp_mib.h +Description: header file of snmp mib parser +Version: v9.0.0 +Author: Roy Jiang +Create Date: 2007-6-9 + +History: +2007-6-9 v9.0.0 Create +***********************************************************************/ +#ifndef _WXC2_SNMP_MIB_API_H_ +#define _WXC2_SNMP_MIB_API_H_ + +#include "snmp_mib.h" + +/* +*Purpose: Init mib parser, read all mib files listed in ./mib/index, +* you should config which mib file you want to parse in the file./mib/index +*Input: None +*Output: None +*/ +extern int init_mib(); + +/* +*Purpose: get the LGC root node of mib tree +*Input: None +*Output: LGC root tree node +*/ +extern struct tree *getLGCroot(); + +/* +*Purpose: Close mib parser and release all resources used in parsing mib files +*Input: None +*Output: None +*/ +extern void close_mib(); + +/* +*Purpose: Get tree node from oid +*Input: const int oid: oid of the tree node to get + int oidlen: the length of the oid + struct tree *subtree: tree node from which the search start +*Output: tree node +*/ +extern struct tree *get_tree(const int *oid, int oidlen, struct tree *subtree); + +#endif + diff --git a/plat/snmp/src/snmp.c b/plat/snmp/src/snmp.c new file mode 100644 index 0000000..d9bafea --- /dev/null +++ b/plat/snmp/src/snmp.c @@ -0,0 +1,3319 @@ +/****************************************/ +/*Title: snmp.c */ +/*Descr: SNMP Agent */ +/*Author: Liang Hanxi */ +/*Create: 2002-4-1 */ +/*Modify: 2003-5-16 */ +/****************************************/ +#include "./include/heartbeat.h" +#include "./include/snmpv3AuthCry.h" + +// fix multiple definition==================================== +char SnmpVer[16]; +// + +extern BYTE snmpDebugFull; +static BYTE initonce = 0; +static BYTE fun_num = 0; +static trapcall trap_proc[100]; +static mib_nod *phead = NULL; +static BYTE setcall_num = 0, getcall_num = 0, trapcall_num = 0, rspcall_num = 0; +static short SnmpPort = 4957; +snmp_csta SnmpCsta[96]; +int snmp_ins; +BYTE snmpVersion=SNMP_V2; +snmp_mib SnmpMib; +static snmp_csta *pCsta; +snmp_log_info *pLogInfo; +snmpV3SecurityPara v3_engine[MAX_ENGINE]; +char snmpconfile[] = {"./conf/snmp.conf"}; +BYTE securityEngineID[32]; +snmpV3SecurityPara manager_engine; + +extern struct timeval tvnow; + +//Private Functions------------------> +static int get_len(BYTE *asnbuf, int *len); +static int parse_snmpmsg(BYTE *msgin, int msglen, snmp_pdu *psnmp, BYTE *error_status); +static int build_snmpmsg(BYTE *pbuf, snmp_pdu *psnmp, DWORD ip, WORD port); +static DWORD assign_rid(); +static BYTE *getmem(int nsize); +static int trap_handle(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen, snmp_addr *addr); +static int rsp_handle(BYTE oidlen, DWORD *oid, snmp_pdu *pdu, snmp_addr *addr); +static int snmp_handle(BYTE oidlen, DWORD *oid, snmp_pdu *pdu, snmp_addr *addr); +static void snmp_hb_init(); +void init_engine_para(); +int init_engine(char * engine_name); +void snmp_readpara(); + +void update_engine_authtime(); +int find_engine_server(char *userName, DWORD ip); +int find_engine(char * userName); +int load_engine_para(snmp_pdu * engine, DWORD ip, WORD port); + + +extern void password_to_key_md5( + unsigned char *password, + unsigned int passwordlen, + unsigned char *engineID, + unsigned int engineLength, + unsigned char *key); +/*-----------------------------------------*/ + +#ifdef _EWS_H_ +extern void ews_proc_heartbeat(BYTE oidLen,DWORD *oid, WORD dataLen,BYTE *pdata); +#endif + +void snmp_log_init() +{ + int shm_id,loop; + FILE *fpLog; + + shm_id = shmget(SNMP_SHM_KEY+wxc2_get_shm_offset(),32*1024,SNMP_SHM_PERM | IPC_CREAT); + if(shm_id == -1) + { + printf("Failed to create snmp shmmem\n"); + exit(1); + } + pLogInfo = (snmp_log_info *)shmat(shm_id,(char *)0,0); + if(pLogInfo == (void *)-1) + { + printf("Failed to shmat snmp shmmem\n"); + exit(2); + } + + fpLog = fopen("../log/snmp_log.txt","w"); + if(fpLog == NULL) return; + + fprintf(fpLog,"-------- SNMP log info -------\n"); + fprintf(fpLog,"----------------------------------\n"); + fprintf(fpLog,"---> Lastest log No. = %02d <-----\n", + (pLogInfo->currentNo+MAX_SNMP_RECORD-1)%MAX_SNMP_RECORD); + for(loop=0;looplog_info[loop]); + } + fprintf(fpLog,"------------- End --------------\n"); + memset(pLogInfo,0,sizeof(snmp_log_info)); + fclose(fpLog); +} + +void snmpLogInfo(char *logInfo) +{ + static int currentNo=0; + sprintf(pLogInfo->log_info[currentNo]," %02d->%s", + currentNo,logInfo); + currentNo ++; + currentNo %= MAX_SNMP_RECORD; + pLogInfo->currentNo = currentNo; +} + +unsigned long long SNMPSerialNumber; +BYTE snmp_synctime_flag; + +void snmp_init(WORD nport) +{ + long l_time; + struct tm *t; + BYTE version[3] = SNMP_VERSION; + + SnmpPort = nport; + if(initonce == 1) + return; + sprintf(SnmpVer, "V%d.%d.%02d", version[0], version[1], version[2]); + + memset(trap_proc, 0, 100 * sizeof(trapcall)); + + l_time = time(NULL); + t = localtime(&l_time); + snmp_ins = t->tm_hour * 4 + t->tm_min/15; + memset(&SnmpCsta[0], 0, sizeof(snmp_csta) * 96); + pCsta = &SnmpCsta[snmp_ins]; + pCsta->timestamp = time(NULL); + + snmpmib_init(); + snmp_debug_setup(); + snmp_debug_csta(1, snmp_ins); + snmp_log_init(); + snmp_readpara(); + init_engine_para(); + + + SNMPSerialNumber = 0; + snmp_synctime_flag = 1;//default to sync omc time + + printf("SNMP Agent Version %s ...... Finish initialization!\n", SnmpVer); + initonce = 1; +} + +ull Str2Ull(char *pStr); +void snmp_init_serial_number(char *Serial) +{ + SNMPSerialNumber = Str2Ull(Serial); +} + +void snmp_set_timenosync()//call of this function will tell snmp module do not sync the omc time +{ + snmp_synctime_flag = 0; +} + +void snmp_timer() +{ + static message_list msgin; + static snmp_pdu snmpmsg; + static snmp_addr addr; + static var_list *pvar; + static int len; + static DWORD *poid; + static BYTE idlen; + int i, j, loop = 10; + struct tm *t; + long l_time; + static DWORD time_counter=0; + static BYTE m_state = 0, ch;//watch_point; + + BYTE err_status=0; +#if SNMP_DEBUG_LOG + char debugBuf[512]; +#endif + //add by yizane start + DWORD in_oid[OID_MAXLEN]; + //add by yizane end + + snmpDebugFull = 0; + snmp_debug_timer(); + if(m_state++ == 25) //switch csta buffer + { + l_time = time(NULL); + t = localtime(&l_time); + if(ch == 0 && t->tm_min%15 == 0) + { + snmp_ins = t->tm_hour * 4 + t->tm_min/15; + pCsta = &SnmpCsta[snmp_ins]; + memset(pCsta, 0, sizeof(snmp_csta)); + pCsta->timestamp = l_time; + snmp_debug_csta(1, snmp_ins); + ch = 1; + } + if(t->tm_min%15 == 1) + ch = 0; + m_state = 0; + } + + time_counter++; + if(time_counter==100)// 1 secend + { + time_counter=0; + update_engine_authtime(); + + } + + while(loop-- > 0) + { + if(iptrGetMessage(&msgin, SnmpPort) != 1) + return; + + strcpy(snmpmsg.community, "public"); + snmpmsg.error_status = snmpmsg.error_index = 0; + +#if SNMP_DEBUG_LOG + snmpLogInfo("snmp_timer() entering parse_snmpmsg()"); +#endif + + if(parse_snmpmsg(msgin.msgContent, msgin.msgLength, &snmpmsg, &err_status) == -1) + { + pCsta->fail_parse++; + snmp_debug(SNMPDB_ERR, "Fail to parse message1.Give up dealing with it!, src ip=%x, src port=%d, dst port=%d", msgin.msgSrcIP,msgin.msgSrcPort,msgin.msgDstPort); + snmp_showbuf(SNMPDB_ERR, msgin.msgContent, msgin.msgLength); + continue; + } + + //store address + addr.remote_ip = msgin.msgSrcIP; + addr.remote_port = msgin.msgSrcPort; + addr.local_ip = msgin.msgDstIP; + addr.local_port = msgin.msgDstPort; + + snmp_logmsg(SNMPDB_IN, &snmpmsg, &addr); + +#if SNMP_DEBUG_LOG + sprintf(debugBuf,"msgIN type: %d , %08lx.%04d from %08lx.%04d", + snmpmsg.pdu_type, + msgin.msgSrcIP,msgin.msgSrcPort, + msgin.msgDstIP,msgin.msgDstPort); + snmpLogInfo(debugBuf); + sprintf(debugBuf,"oidLen: %d, lastest 8 oid=%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld", + snmpmsg.var[0].oidlen, + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-9], + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-8], + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-7], + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-6], + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-5], + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-4], + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-3], + snmpmsg.var[0].oid[snmpmsg.var[0].oidlen-2]); + snmpLogInfo(debugBuf); +#endif + + + if((snmpmsg.msgVersion == SNMP_V3)&&( ((snmpmsg.msgSecurityParameters.seqFlag&1)==0) ||((snmpmsg.msgGlobalData.msgFlags&4)&&memcmp(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, manager_engine.securityEngineID, 12)!=0))) + {//send report + var_list report_state= + { + .oid={1,3,6,1,6,3,15,1,1,4,0},//{1,3,6,1,4,1,1373,2,3,2},//PLATFORM_HB_OID, + .oidlen=11,//PLATFORM_HB_LEN, + .vartype=0x41, + .msglen=1, + .msg={6} + }; + snmpmsg.msgSecurityParameters.seqFlag |=1; + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, securityEngineID, 32); //pierre + memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, manager_engine.securityEngineID, 32); + snmpmsg.pdu_type = PDU_REPORT; + snmpmsg.var_num = 1; + memcpy(&snmpmsg.var, &report_state, sizeof(var_list)); + snmpmsg.msgData.plaintext.seqFlag = 1;// contextEngineID + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, securityEngineID, 32); //pierre + memcpy(snmpmsg.msgData.plaintext.contextEngineID, manager_engine.securityEngineID, 32); + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime= manager_engine.authInTime; //0x02a097; + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots = manager_engine.boots; + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + continue; + } + if(snmpmsg.msgVersion == SNMP_V3 && (snmpmsg.msgGlobalData.msgFlags&4)!=0 && (snmpmsg.msgGlobalData.msgFlags&1)!=0) + {//send report + if((snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime>manager_engine.authInTime&&\ + (snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime-manager_engine.authInTime)>150)||\ + (snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime150)\ + ||(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime==0&&snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots==0)) + { + int index; + var_list report_state= + { + .oid={1,3,6,1,6,3,15,1,1,2,0},//{1,3,6,1,4,1,1373,2,3,2},//PLATFORM_HB_OID, + .oidlen=11,//PLATFORM_HB_LEN, + .vartype=0x41, + .msglen=1, + .msg={1} + }; + + index = find_engine(snmpmsg.msgSecurityParameters.msgUserName); + + + if(index>=0) + { + if(v3_engine[index].engineType!=2)// type==2 is internal snmp_v3, it need not check time + { + + snmpmsg.msgGlobalData.msgFlags &=1; + snmpmsg.msgSecurityParameters.seqFlag |=1; + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, securityEngineID, 32); //pierre + memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.pdu_type = PDU_REPORT; + snmpmsg.var_num = 1; + //report_state.msglen = encode_integer(report_state.msg , manager_engine.authInTime); + memcpy(&snmpmsg.var, &report_state, sizeof(var_list)); + snmpmsg.msgData.plaintext.seqFlag = 1;// contextEngineID + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, securityEngineID, 32); //pierre + memcpy(snmpmsg.msgData.plaintext.contextName, v3_engine[index].contextName, 32); + memcpy(snmpmsg.msgData.plaintext.contextEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime= manager_engine.authInTime; //0x02a097; + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots = manager_engine.boots; + + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + continue; + } + } + } + } + + if(snmpmsg.msgVersion == SNMP_V3 && (snmpmsg.msgGlobalData.msgFlags&4)!=0) + {//send report + int index; + var_list report_state= + { + .oid={1,3,6,1,6,3,15,1,1,1,0},//{1,3,6,1,4,1,1373,2,3,2},//PLATFORM_HB_OID, + .oidlen=11,//PLATFORM_HB_LEN, + .vartype=0x41, + .msglen=1, + .msg={1} + }; + + index = find_engine(snmpmsg.msgSecurityParameters.msgUserName); + + + if(index<0) + { + //if(v3_engine[index].engineType!=2) + //{ + report_state.oid[9]=3; + snmpmsg.msgGlobalData.msgFlags &=1; + snmpmsg.msgSecurityParameters.seqFlag |=1; + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, securityEngineID, 32); //pierre + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.pdu_type = PDU_REPORT; + snmpmsg.var_num = 1; + //report_state.msglen = encode_integer(report_state.msg , manager_engine.authInTime); + memcpy(&snmpmsg.var, &report_state, sizeof(var_list)); + snmpmsg.msgData.plaintext.seqFlag = 1;// contextEngineID + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, securityEngineID, 32); //pierre + //memcpy(snmpmsg.msgData.plaintext.contextName, v3_engine[index].contextName, 32); + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime= manager_engine.authInTime; //0x02a097; + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots = manager_engine.boots; + + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + continue; + //} + + } + else if(v3_engine[index].securityLevel!=(snmpmsg.msgGlobalData.msgFlags&3) && (v3_engine[index].engineType!=2)) + { + if(snmpmsg.var_num!=0) + { + + snmpmsg.msgGlobalData.msgFlags &=1; + snmpmsg.msgSecurityParameters.seqFlag |=1; + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, securityEngineID, 32); //pierre + memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.pdu_type = PDU_REPORT; + snmpmsg.var_num = 1; + //report_state.msglen = encode_integer(report_state.msg , manager_engine.authInTime); + memcpy(&snmpmsg.var, &report_state, sizeof(var_list)); + snmpmsg.msgData.plaintext.seqFlag = 1;// contextEngineID + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, securityEngineID, 32); //pierre + //memcpy(snmpmsg.msgData.plaintext.contextName, v3_engine[index].contextName, 32); + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime= manager_engine.authInTime; //0x02a097; + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots = manager_engine.boots; + + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + continue; + } + else + {//UltraVIEW OMC need a response + snmpmsg.msgGlobalData.msgFlags &=1; + snmpmsg.msgSecurityParameters.seqFlag |=1; + memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, manager_engine.securityEngineID, 32); + snmpmsg.pdu_type = PDU_RSP; + snmpmsg.var_num = 0; + snmpmsg.error_status = 0x10;// authorizationError + memcpy(&snmpmsg.var, &report_state, sizeof(var_list)); + snmpmsg.msgData.plaintext.seqFlag = 1;// contextEngineID + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime= manager_engine.authInTime; //0x02a097; + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots = manager_engine.boots; + + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + continue; + } + + } + + } + + + if(snmpmsg.msgVersion == SNMP_V3 && (snmpmsg.msgGlobalData.msgFlags&4)!=0 && err_status !=0) + {//send report + var_list report_state= + { + .oid={1,3,6,1,6,3,15,1,1,1,0},//{1,3,6,1,4,1,1373,2,3,2},//PLATFORM_HB_OID, + .oidlen=11,//PLATFORM_HB_LEN, + .vartype=0x41, + .msglen=1, + .msg={1} + }; + report_state.oid[9]=err_status; + snmpmsg.msgGlobalData.msgFlags &=1; + snmpmsg.msgSecurityParameters.seqFlag |=1; + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, securityEngineID, 32); //pierre + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.pdu_type = PDU_REPORT; + snmpmsg.var_num = 1; + //report_state.msglen = encode_integer(report_state.msg , manager_engine.authInTime); + memcpy(&snmpmsg.var, &report_state, sizeof(var_list)); + snmpmsg.msgData.plaintext.seqFlag = 1;// contextEngineID + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, securityEngineID, 32); //pierre + //memcpy(snmpmsg.msgData.plaintext.contextName, v3_engine[index].contextName, 32); + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime= manager_engine.authInTime; //0x02a097; + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots = manager_engine.boots; + + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + continue; + + } + if(snmpmsg.msgVersion == SNMP_V3 && (snmpmsg.pdu_type==PDU_GETNEXT)) + {//send report + var_list report_state= + { + .oid={1,3,6,1,2,1,1,3},//{1,3,6,1,4,1,1373,2,3,2},//PLATFORM_HB_OID, + .oidlen=8,//PLATFORM_HB_LEN, + .vartype=0x43, + .msglen=3, + .msg={0xf5} + }; + if(memcmp(report_state.oid ,snmpmsg.var[0].oid, 8*4)==0) + { + snmpmsg.msgSecurityParameters.seqFlag |=1; + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, securityEngineID, 32); //pierre + //memcpy(snmpmsg.msgSecurityParameters.msgAuthoritativeEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.pdu_type = PDU_RSP; + snmpmsg.var_num = 1; + report_state.msglen = encode_integer(report_state.msg , manager_engine.authInTime*100); + memcpy(&snmpmsg.var, &report_state, sizeof(var_list)); + snmpmsg.msgData.plaintext.seqFlag = 1;// contextEngineID + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, securityEngineID, 32); //pierre + //memcpy(snmpmsg.msgData.plaintext.contextName, v3_engine[index].contextName, 32); + //memcpy(snmpmsg.msgData.plaintext.contextEngineID, v3_engine[index].securityEngineID, 32); + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime= manager_engine.authInTime; //0x02a097; + snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots = manager_engine.boots; + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + continue; + + } + + } + + switch(snmpmsg.pdu_type) + { + case PDU_RSP: + pCsta->rsp_in++; + rsp_handle(snmpmsg.var[0].oidlen, snmpmsg.var[0].oid, &snmpmsg, &addr); + continue; + break; + case PDU_SET: + pCsta->set_in++; + if(snmpmsg.error_status != 0 ) + continue; + if(snmp_handle(snmpmsg.var[0].oidlen, snmpmsg.var[0].oid, &snmpmsg, &addr)>0) + continue; + break; + case PDU_GET: + pCsta->get_in++; + if(snmpmsg.error_status != 0 ) + continue; + if(snmp_handle(snmpmsg.var[0].oidlen, snmpmsg.var[0].oid, &snmpmsg, &addr)>0) + continue; + break; + case PDU_TRAP: + pCsta->trap_in++; + break; + case PDU_GETNEXT: + //add by yizane start + pCsta->getnext_in++; + if(snmpmsg.error_status != 0 ) + continue; + if(snmp_handle(snmpmsg.var[0].oidlen, snmpmsg.var[0].oid, &snmpmsg, &addr)>0) + continue; + break; + case PDU_GETBULK: + pCsta->getbulk_in++; + if(snmpmsg.error_status != 0 ) + continue; + if(snmp_handle(snmpmsg.var[0].oidlen, snmpmsg.var[0].oid, &snmpmsg, &addr)>0) + continue; + break; + //add by yizane end + case PDU_REPORT: + if(snmpmsg.msgVersion==SNMP_V3 && snmpVersion==SNMP_V3) + { + int index=0, ret; + DWORD authInTimeOid[]={1,3,6,1,6,3,15,1,1,2}; + DWORD unknowEngineOid[]={1,3,6,1,6,3,15,1,1,4}; + int oidlen=10; + + ret = memcmp(poid,unknowEngineOid, oidlen*4); + if(memcmp(poid,authInTimeOid, oidlen*4)==0||ret==0) + { + index = find_engine_server(snmpmsg.msgSecurityParameters.msgUserName, addr.remote_ip); + if(!strcmp(snmpmsg.msgSecurityParameters.msgUserName, v3_engine[index].securityUserName)) + { + v3_engine[index].authInTime = snmpmsg.msgSecurityParameters.msgAuthoritativeEngineTime; + v3_engine[index].boots = snmpmsg.msgSecurityParameters.msgAuthoritativeEngineBoots; + memcpy(v3_engine[index].contextEngineID,snmpmsg.msgData.plaintext.contextEngineID,0x0c); + } + } + } + continue; + break; + default: + snmp_debug(SNMPDB_ERR, "Unknow PDU type(%d)!", snmpmsg.pdu_type); + snmp_logmsg(SNMPDB_ERR, &snmpmsg, &addr); + continue; + } + + //deal with each variable in var_list + for(i = 0; i < snmpmsg.var_num; i++) + { + pvar = &snmpmsg.var[i]; + poid = pvar->oid; + idlen = pvar->oidlen; + switch(snmpmsg.pdu_type) + { + case PDU_TRAP: + if(trap_handle(idlen, poid, pvar->msg, pvar->msglen, &addr) == 1) + continue; + for(j = 0; j < fun_num; j++) + { + if(trap_proc[j] != NULL) + trap_proc[j](idlen, poid, pvar->msg, pvar->msglen, &addr); + } + continue; + case PDU_GETNEXT: + //add by yizane start + memset(in_oid,0,OID_MAXLEN*sizeof(DWORD)); + memcpy(in_oid,poid,idlen*sizeof(DWORD)); + len = getnext_response(idlen, in_oid, &pvar->oidlen, poid, pvar->msg, &pvar->vartype); + if(len >= 0){ + pvar->msglen = len; //L + } + else if(len == -1) + { + snmp_debug(SNMPDB_NOREG, "EndOfMibView"); + snmp_logmsg(SNMPDB_NOREG, &snmpmsg, &addr); + pvar->vartype = EndOfMibView; + pvar->msglen = 0; + } + else + { + snmpmsg.error_status=3; + snmpmsg.error_index = i + 1; + pvar->vartype = 4; + pvar->msg[128] = 0; + pvar->msglen = strlen((char *)pvar->msg); + } + break; + //add by yizane end + + case PDU_GET: + len = get_response(idlen, poid, pvar->msg, &pvar->vartype); + + if(len >= 0) + pvar->msglen = len; //L + else if(len == -1) + { + snmp_debug(SNMPDB_NOREG, "NoSuchObject or NoSuchInstance:"); + snmp_logmsg(SNMPDB_NOREG, &snmpmsg, &addr); + if(poid[idlen-1] == 0) + pvar->vartype = NoSuchObject; + else + pvar->vartype = NosuchInstance; + pvar->msglen = 0; + } + else + { + snmpmsg.error_status=3; + snmpmsg.error_index = i + 1; + pvar->vartype = 4; + pvar->msg[128] = 0; + pvar->msglen = strlen((char *)pvar->msg); + } + break; + case PDU_SET: + len = set_response(idlen, poid, pvar->msg, pvar->msglen); + if(len >= 0) + { + pvar->msglen = len; //L + } + else if(len == -1) + { + snmp_debug(SNMPDB_NOREG, "NoSuchObject or NoSuchInstance:"); + snmp_logmsg(SNMPDB_NOREG, &snmpmsg, &addr); + if(poid[idlen-1] == 0) + pvar->vartype = NoSuchObject; + else + pvar->vartype = NosuchInstance; + pvar->msglen = 0; + } + else + { + snmpmsg.error_status=3; + snmpmsg.error_index = i + 1; + pvar->vartype = 4; + pvar->msg[128] = 0; + pvar->msglen = strlen((char *)pvar->msg); + } + break; + case PDU_REPORT: + break; + }/* switch */ + } /* for */ + +//add by yizane start + if(snmpmsg.pdu_type == PDU_GETBULK){ + int n,m,r,end_count,index; + static DWORD *pre_poid; + m = snmpmsg.max_repetitions; + + if (snmpmsg.non_repeaters < snmpmsg.var_num) { + n = snmpmsg.non_repeaters; + } else { + n = snmpmsg.var_num; + } + if ((r = snmpmsg.var_num - n) < 0) { + r = 0; + } + + snmpmsg.var_num=0; + for(i = 0; i < n; i++){ + if(i>=BIND_MAX){ + break; + } + pvar = &snmpmsg.var[i]; + poid = pvar->oid; + idlen = pvar->oidlen; + + memset(in_oid,0,OID_MAXLEN*sizeof(DWORD)); + memcpy(in_oid,poid,idlen*sizeof(DWORD)); + len = getnext_response(idlen, in_oid, &pvar->oidlen, poid, pvar->msg, &pvar->vartype); + if(len >= 0) + pvar->msglen = len; //L + else if(len == -1) + { + snmp_debug(SNMPDB_NOREG, "EndOfMibView"); + snmp_logmsg(SNMPDB_NOREG, &snmpmsg, &addr); + pvar->vartype = EndOfMibView; + pvar->msglen = 0; + } + else + { + snmpmsg.error_status=3; + snmpmsg.error_index = i + 1; + pvar->vartype = 4; + pvar->msg[128] = 0; + pvar->msglen = strlen((char *)pvar->msg); + } + snmpmsg.var_num++; + } + + + + for(i = 0; i < m; i++){ + end_count=0; + for(j = 0; j < r; j++){ + index = n+i*r+j; + if(index>=BIND_MAX){ + end_count = r ; + break; + } + pvar = &snmpmsg.var[index]; + poid = pvar->oid; + + memset(in_oid,0,OID_MAXLEN*sizeof(DWORD)); + if(i==0) + { + pre_poid = pvar->oid; + idlen = pvar->oidlen; + memcpy(in_oid,pre_poid,idlen*sizeof(DWORD)); + } + else + { + pre_poid = snmpmsg.var[n+i*r+j-r].oid; + idlen = snmpmsg.var[n+i*r+j-r].oidlen; + memcpy(in_oid,pre_poid,idlen*sizeof(DWORD)); + } + + len = getnext_response(idlen, in_oid, &pvar->oidlen, poid, pvar->msg, &pvar->vartype); + if(len >= 0) + pvar->msglen = len; //L + else if(len == -1) + { + snmp_debug(SNMPDB_NOREG, "EndOfMibView"); + snmp_logmsg(SNMPDB_NOREG, &snmpmsg, &addr); + pvar->vartype = EndOfMibView; + pvar->msglen = 0; + end_count++; + } + else + { + snmpmsg.error_index = i + 1; + pvar->vartype = 4; + pvar->msg[128] = 0; + pvar->msglen = strlen((char *)pvar->msg); + } + snmpmsg.var_num++; + + } + if(end_count==r) + break; + } + + if(snmpmsg.var_num>BIND_MAX) + snmpmsg.var_num=BIND_MAX; + } + + //response----------------> + //response----------------> + if(snmpmsg.pdu_type == PDU_SET || snmpmsg.pdu_type == PDU_GET + || snmpmsg.pdu_type == PDU_GETNEXT|| snmpmsg.pdu_type == PDU_GETBULK ) +//add by yizane end + { + snmpmsg.pdu_type = PDU_RSP; + /* + if(len != -2) + { + snmpmsg.error_index = 0; + } + */ + /* + if(len == -2) + { + snmpmsg.error_status = 3; + snmpmsg.error_index = 1; + } + else + { + snmpmsg.error_index = 0; + } + */ + len = build_snmpmsg(msgin.msgContent, &snmpmsg, addr.remote_ip, addr.remote_port); + msgin.msgLength = len; + + msgin.msgDstIP = addr.remote_ip; + msgin.msgDstPort = addr.remote_port; + msgin.msgSrcPort = addr.local_port; + snmp_logmsg(SNMPDB_OUT, &snmpmsg, &addr); + iptrPlatPutMessage(msgin); + } + } + +} + +int get_response(BYTE oidlen, DWORD *oid, BYTE *pdata, BYTE *vartype) +{ + BYTE i = 0; + mib_nod *p1; + +#if SNMP_DEBUG_LOG + char debugBuf[512]; + sprintf(debugBuf, + "get_response(), oidlen: %d, lastest 8 oid:%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld", + oidlen,oid[oidlen-9], + oid[oidlen-8],oid[oidlen-7],oid[oidlen-6],oid[oidlen-5], + oid[oidlen-4],oid[oidlen-3],oid[oidlen-2]); + snmpLogInfo(debugBuf); +#endif + + p1 = phead; + while(i < oidlen) + { + if(p1 == NULL) + { + pCsta->not_register++; + return -1; + } + if(p1->id == oid[i]) + { + if(p1->get_proc != NULL) + return p1->get_proc(oidlen, oid, pdata, vartype); + if(ipsub; + } + else + { + if(p1->pnext == NULL) + { + pCsta->not_register++; + return -1; + } + else + { + p1 = p1->pnext; + continue; + } + } + i++; + } + pCsta->not_register++; + return -1; +} + +//add by yizane start +int getnext_response(BYTE in_oidlen, DWORD *in_oid, BYTE *oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype) +{ + BYTE i = 0; + mib_nod *p1; + p1 = phead; + + while(i < in_oidlen) + { + if(p1 == NULL) + { + pCsta->not_register++; + return -1; + } + if(p1->id == in_oid[i]) + { + if(p1->getnext_proc != NULL) + return p1->getnext_proc(in_oidlen, in_oid, oidlen, oid, pdata, vartype); + if(ipsub; + } + else + { + if(p1->pnext == NULL) + { + pCsta->not_register++; + return -1; + } + else + { + p1 = p1->pnext; + continue; + } + } + i++; + } + pCsta->not_register++; + return -1; +} +//add by yizane end + +int set_response(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen) +{ + BYTE i = 0; + mib_nod *p1; + +#if SNMP_DEBUG_LOG + char debugBuf[512]; + sprintf(debugBuf, + "set_response(), oidlen: %d, lastest 8 oid:%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld", + oidlen,oid[oidlen-9], + oid[oidlen-8],oid[oidlen-7],oid[oidlen-6],oid[oidlen-5], + oid[oidlen-4],oid[oidlen-3],oid[oidlen-2]); + snmpLogInfo(debugBuf); +#endif + p1 = phead; + while(i < oidlen) + { + if(p1 == NULL) + { + pCsta->not_register++; + return -1; + } + if(p1->id == oid[i]) + { + if(p1->set_proc != NULL) + return p1->set_proc(oidlen, oid, pdata, datalen); + if(i < oidlen-1) + p1 = p1->psub; + } + else + { + if(p1->pnext == NULL) + { + pCsta->not_register++; + return -1; + } + else + { + p1 = p1->pnext; + continue; + } + } + i++; + } + pCsta->not_register++; + return -1; +} + +int trap_handle(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen, snmp_addr *addr) +{ + BYTE i = 0; + mib_nod *p1; + +#if SNMP_DEBUG_LOG + char debugBuf[512]; + sprintf(debugBuf, + "trap_handle(), oidlen: %d, lastest 8 oid:%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld", + oidlen,oid[oidlen-9], + oid[oidlen-8],oid[oidlen-7],oid[oidlen-6],oid[oidlen-5], + oid[oidlen-4],oid[oidlen-3],oid[oidlen-2]); + snmpLogInfo(debugBuf); +#endif + + p1 = phead; + while(i < oidlen) + { + if(p1 == NULL) + return -1; + if(p1->id == oid[i]) + { + if(p1->trap_proc != NULL) + { + p1->trap_proc(oidlen, oid, pdata, datalen, addr); + return 1; + } + if(i < oidlen-1) + p1 = p1->psub; + } + else + { + if(p1->pnext == NULL) + return -1; + else + { + p1 = p1->pnext; + continue; + } + } + i++; + } + return -1; +} + +int rsp_handle(BYTE oidlen, DWORD *oid, snmp_pdu *pdu, snmp_addr *addr) +{ + BYTE i = 0; + mib_nod *p1; + +#if SNMP_DEBUG_LOG + char debugBuf[512]; + sprintf(debugBuf, + "rsp_handle(), oidlen: %d, lastest 8 oid:%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld", + oidlen,oid[oidlen-9], + oid[oidlen-8],oid[oidlen-7],oid[oidlen-6],oid[oidlen-5], + oid[oidlen-4],oid[oidlen-3],oid[oidlen-2]); + snmpLogInfo(debugBuf); +#endif + + p1 = phead; + while(i < oidlen) + { + if(p1 == NULL) + { + pCsta->not_register++; + return -1; + } + if(p1->id == oid[i]) + { + if(p1->rsp_proc != NULL) + { + p1->rsp_proc(pdu, addr); + return 1; + } + if(i < oidlen-1) + p1 = p1->psub; + } + else + { + if(p1->pnext == NULL) + { + pCsta->not_register++; + return -1; + } + else + { + p1 = p1->pnext; + continue; + } + } + i++; + } + pCsta->not_register++; + return -1; +} + +int snmp_handle(BYTE oidlen, DWORD *oid, snmp_pdu *pdu, snmp_addr *addr) +{ + BYTE i = 0; + mib_nod *p1; + +#if SNMP_DEBUG_LOG + char debugBuf[512]; + sprintf(debugBuf, + "snmp_handle(), oidlen: %d, lastest 8 oid:%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld", + oidlen,oid[oidlen-9], + oid[oidlen-8],oid[oidlen-7],oid[oidlen-6],oid[oidlen-5], + oid[oidlen-4],oid[oidlen-3],oid[oidlen-2]); + snmpLogInfo(debugBuf); +#endif + + p1 = phead; + while(i < oidlen) + { + if(p1 == NULL) + return -1; + if(p1->id == oid[i]) + { + if(p1->snmp_proc != NULL) + { + p1->snmp_proc(pdu, addr); + return 1; + } + if(i < oidlen-1) + p1 = p1->psub; + } + else + { + if(p1->pnext == NULL) + return -1; + else + { + p1 = p1->pnext; + continue; + } + } + i++; + } + return -1; +} + +void snmp_hb_init() +{ + BYTE status[64] = {3, 3, 2, 1}; + status[4] = trapcall_num; + status[5] = setcall_num; + status[6] = getcall_num; + status[7] = rspcall_num; + set_status(4, 8, status); +} +/********************************************************************/ + +void inquire_trapmsg(trapcall func) +{ + BYTE i; + for(i = 0; i < fun_num && i < 100; i++) + { + if(trap_proc[i] == NULL) + { + trap_proc[i] = func; + fun_num = i+1; + return; + } + if(trap_proc[i] == func) + return; + } + if(fun_num >= 100) + return; + trap_proc[fun_num++] = func; + trapcall_num++; + snmp_hb_init(); +} + +void rob_trapmsg(BYTE oidlen, DWORD *oid, trapcall trap_proc) +{ + BYTE i = 0; + mib_nod *p1, *p2; + if(phead == NULL) + { + phead = (mib_nod *)getmem(sizeof(mib_nod)); + phead->id = oid[0]; + } + p1 = phead; + while(i < oidlen) + { + if(p1->id == oid[i]) + { + if(i == oidlen-1) + p1->trap_proc = trap_proc; + else + { + if(p1->psub == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i+1]; + p1->psub = p2; + p1 = p2; + } + else + p1 = p1->psub; + } + } + else + { + if(p1->pnext == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i]; + p1->pnext = p2; + p1 = p2; + } + else + p1 = p1->pnext; + continue; + } + i++; + } + trapcall_num++; + snmp_hb_init(); +} + +void inquire_setmsg(BYTE oidlen, DWORD *oid, setcall set_proc) +{ + BYTE i = 0; + mib_nod *p1, *p2; + if(phead == NULL) + { + phead = (mib_nod *)getmem(sizeof(mib_nod)); + phead->id = oid[0]; + } + p1 = phead; + while(i < oidlen) + { + if(p1->id == oid[i]) + { + if(i == oidlen-1) + p1->set_proc = set_proc; + else + { + if(p1->psub == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i+1]; + p1->psub = p2; + p1 = p2; + } + else + p1 = p1->psub; + } + } + else + { + if(p1->pnext == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i]; + p1->pnext = p2; + p1 = p2; + } + else + p1 = p1->pnext; + continue; + } + i++; + } + setcall_num++; + snmp_hb_init(); +} + +void inquire_getmsg(BYTE oidlen, DWORD *oid, getcall get_proc) +{ + BYTE i = 0; + mib_nod *p1, *p2; + if(phead == NULL) + { + phead = (mib_nod *)getmem(sizeof(mib_nod)); + phead->id = oid[0]; + } + p1 = phead; + while(i < oidlen) + { + if(p1->id == oid[i]) + { + if(i == oidlen - 1) + p1->get_proc = get_proc; + else + { + if(p1->psub == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i+1]; + p1->psub = p2; + p1 = p2; + } + else + p1 = p1->psub; + } + } + else + { + if(p1->pnext == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i]; + p1->pnext = p2; + p1 = p2; + } + else + p1 = p1->pnext; + continue; + } + i++; + } + getcall_num++; + snmp_hb_init(); +} + +//add by yizane start +void inquire_getnextmsg(BYTE oidlen, DWORD *oid, getnextcall getnext_proc) +{ + BYTE i = 0; + mib_nod *p1, *p2; + if(phead == NULL) + { + phead = (mib_nod *)getmem(sizeof(mib_nod)); + phead->id = oid[0]; + } + p1 = phead; + while(i < oidlen) + { + if(p1->id == oid[i]) + { + if(i == oidlen - 1) + p1->getnext_proc = getnext_proc; + else + { + if(p1->psub == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i+1]; + p1->psub = p2; + p1 = p2; + } + else + p1 = p1->psub; + } + } + else + { + if(p1->pnext == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i]; + p1->pnext = p2; + p1 = p2; + } + else + p1 = p1->pnext; + continue; + } + i++; + } + getcall_num++; + snmp_hb_init(); +} +//add by yizane end + +void inquire_rspmsg(BYTE oidlen, DWORD *oid, rspcall rsp_proc) +{ + + BYTE i = 0; + mib_nod *p1, *p2; + if(phead == NULL) + { + phead = (mib_nod *)getmem(sizeof(mib_nod)); + phead->id = oid[0]; + } + p1 = phead; + while(iid == oid[i]) + { + if(i == oidlen - 1) + p1->rsp_proc = rsp_proc; + else + { + if(p1->psub == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i+1]; + p1->psub = p2; + p1 = p2; + } + else + p1 = p1->psub; + } + } + else + { + if(p1->pnext == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i]; + p1->pnext = p2; + p1 = p2; + } + else + p1 = p1->pnext; + continue; + } + i++; + } + rspcall_num++; + snmp_hb_init(); +} + +void inquire_snmpmsg(BYTE oidlen, DWORD *oid, snmpcall snmp_proc) +{ + + BYTE i = 0; + mib_nod *p1, *p2; + if(phead == NULL) + { + phead = (mib_nod *)getmem(sizeof(mib_nod)); + phead->id = oid[0]; + } + p1 = phead; + while(i < oidlen) + { + if(p1->id == oid[i]) + { + if(i == oidlen-1) + p1->snmp_proc = snmp_proc; + else + { + if(p1->psub == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i+1]; + p1->psub = p2; + p1 = p2; + } + else + p1 = p1->psub; + } + } + else + { + if(p1->pnext == NULL) + { + p2 = (mib_nod *)getmem(sizeof(mib_nod)); + p2->id = oid[i]; + p1->pnext = p2; + p1 = p2; + } + else + p1 = p1->pnext; + continue; + } + i++; + } + //rspcall_num++; + //snmp_hb_init(); +} +/********************************************************************/ + +int snmp_send(snmp_pdu *msgbuf, snmp_addr *addr) +{ + message_list msgout; + +#if SNMP_DEBUG_LOG + char debugBuf[512]; +#endif + snmp_logmsg(SNMPDB_OUT, msgbuf, addr); + if(msgbuf->var_num == 0 || msgbuf->var_num >BIND_MAX) + { + snmp_debug(SNMPDB_ERR, "var_num = %d, exceed limit(%d)", msgbuf->var_num, BIND_MAX); + snmp_logmsg(SNMPDB_ERR, msgbuf, addr); + return 0; + } + +#if SNMP_DEBUG_LOG + sprintf(debugBuf,"snmp_send() pdu_type: %d",msgbuf->pdu_type); + snmpLogInfo(debugBuf); +#endif + + switch(msgbuf->pdu_type) + { + case PDU_SET: + pCsta->set_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + case PDU_GET: + pCsta->get_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + //add by yizane start + case PDU_GETNEXT: + pCsta->getnext_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + case PDU_GETBULK: + pCsta->getbulk_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + //add by yizane end + case PDU_TRAP: + pCsta->trap_out++; + msgbuf->request_id = 1; + +#ifdef _EWS_H_ + if(addr->local_port == 4957 && addr->remote_port == 4957) + { + ews_proc_heartbeat(msgbuf->var[0].oidlen, + msgbuf->var[0].oid, + msgbuf->var[0].msglen, + msgbuf->var[0].msg); + } +#endif + break; + case PDU_RSP: + pCsta->rsp_out++; + break; + default: + return 0; + } +#if SNMP_DEBUG_LOG + sprintf(debugBuf,"snmp_send->msginfo: %08lx.%04d to %08lx.%04d", + addr->local_ip,addr->local_port, + addr->remote_ip,addr->remote_port); + snmpLogInfo(debugBuf); +#endif + + msgout.msgLength = build_snmpmsg(msgout.msgContent , msgbuf, addr->remote_ip, addr->remote_port); + if(msgout.msgLength == 0 || msgout.msgLength > 1500) + { + snmp_debug(SNMPDB_ERR, "Encoding Failure or Message length exceed limit"); + snmp_logmsg(SNMPDB_ERR, msgbuf, addr); + return 0; + } + + msgout.msgDstIP = addr->remote_ip ; + msgout.msgDstPort = addr->remote_port ; + msgout.msgSrcIP = addr->local_ip ; + msgout.msgSrcPort = addr->local_port ; + msgout.msgBroadcast = addr->broadcast ; + +#if SNMP_DEBUG_LOG + snmpLogInfo("end of snmp_send()"); +#endif + if(iptrPutMessage(msgout) == 0) + return 0; + else + return msgbuf->request_id; +} + +int snmp_plat_send(snmp_pdu *msgbuf, snmp_addr *addr) +{ + message_list msgout; + + snmp_logmsg(SNMPDB_OUT, msgbuf, addr); + if(msgbuf->var_num == 0 || msgbuf->var_num >BIND_MAX) + { + snmp_debug(SNMPDB_ERR, "var_num = %d, exceed limit(%d)", msgbuf->var_num, BIND_MAX); + snmp_logmsg(SNMPDB_ERR, msgbuf, addr); + return 0; + } + + switch(msgbuf->pdu_type) + { + case PDU_SET: + pCsta->set_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + case PDU_GET: + pCsta->get_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + //add by yizane start + case PDU_GETNEXT: + pCsta->getnext_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + case PDU_GETBULK: + pCsta->getbulk_out++; + msgbuf->error_index = msgbuf->error_status = 0; + if(msgbuf->request_id == 0 ) + msgbuf->request_id = assign_rid(); + break; + //add by yizane end + case PDU_TRAP: + pCsta->trap_out++; + msgbuf->request_id = 1; +#ifdef _EWS_H_ + if(addr->local_port == 4957 && addr->remote_port == 4957) + { + ews_proc_heartbeat(msgbuf->var[0].oidlen, + msgbuf->var[0].oid, + msgbuf->var[0].msglen, + msgbuf->var[0].msg); + } +#endif + break; + case PDU_RSP: + pCsta->rsp_out++; + break; + default: + return 0; + } + + msgout.msgLength = build_snmpmsg(msgout.msgContent , msgbuf, addr->remote_ip, addr->remote_port); + if(msgout.msgLength == 0 || msgout.msgLength > 1500) + { + snmp_debug(SNMPDB_ERR, "Encoding Failure or Messages length exceed limit"); + snmp_logmsg(SNMPDB_ERR, msgbuf, addr); + return 0; + } + + msgout.msgDstIP = addr->remote_ip ; + msgout.msgDstPort = addr->remote_port ; + msgout.msgSrcIP = addr->local_ip ; + msgout.msgSrcPort = addr->local_port ; + msgout.msgBroadcast = addr->broadcast ; + + if(iptrPlatPutMessage(msgout) == 0) + return 0; + else + return msgbuf->request_id; +} + + +int snmp_receive(snmp_pdu *msgbuf, snmp_addr *addr) +{ + message_list msgin; +#if SNMP_DEBUG_SNMP + char debugBuf[512]; +#endif + BYTE err_status=0; + + if(iptrGetMessage(&msgin, addr->local_port) == 1) + { +#if SNMP_DEBUG_SNMP + sprintf(debugBuf,"snmp_receive(),len=%d, %08x.%04d from %08x.%04d entering parse_shmpmsg()", + msgin.msgLength, + msgin.msgSrcIP,msgin.msgSrcPort, + msgin.msgDstIP,msgin.msgDstPort); + snmpLogInfo(debugBuf); +#endif + if(parse_snmpmsg(msgin.msgContent, msgin.msgLength, msgbuf, &err_status) == 1 && msgbuf->var_num>0) + { + if(msgbuf->msgVersion==SNMP_V3 && snmpVersion==SNMP_V3 && msgbuf->pdu_type==PDU_REPORT) + { + int index=0, ret; + DWORD authInTimeOid[]={1,3,6,1,6,3,15,1,1,2}; + DWORD unknowEngineOid[]={1,3,6,1,6,3,15,1,1,4}; + int oidlen=10; + + ret = memcmp(msgbuf->var[0].oid,unknowEngineOid, 4*oidlen); + if(memcmp(msgbuf->var[0].oid,authInTimeOid, 4*oidlen)==0 ||ret == 0) + { + index = find_engine_server(msgbuf->msgSecurityParameters.msgUserName,msgin.msgSrcIP); + if(index>=0) + { + v3_engine[index].authInTime = msgbuf->msgSecurityParameters.msgAuthoritativeEngineTime; + v3_engine[index].boots = msgbuf->msgSecurityParameters.msgAuthoritativeEngineBoots; + memcpy(v3_engine[index].securityEngineID, msgbuf->msgSecurityParameters.msgAuthoritativeEngineID, 32); + memcpy(v3_engine[index].contextEngineID, msgbuf->msgData.plaintext.contextEngineID, 32); + memcpy(v3_engine[index].contextName, msgbuf->msgData.plaintext.contextName,32); + init_engine(v3_engine[index].securityUserName); + } + } + } + addr->remote_ip = msgin.msgSrcIP; + addr->remote_port = msgin.msgSrcPort; + addr->local_port = msgin.msgDstPort; + addr->local_ip = msgin.msgDstIP; + + snmp_logmsg(SNMPDB_IN, msgbuf, addr); + return 1; + } + else + { + pCsta->fail_parse++; + snmp_debug(SNMPDB_ERR, "Fail to parse message2.Give up dealing with it!, src ip=%x, src port=%d, dst port=%d", msgin.msgSrcIP,msgin.msgSrcPort,msgin.msgDstPort); + snmp_showbuf(SNMPDB_ERR, msgin.msgContent, msgin.msgLength); + } + } + return 0; +} + +/********************************************************************/ + +int build_snmpmsg(BYTE *pbuf, snmp_pdu *psnmp, DWORD ip, WORD port) +{ + BYTE msg[2000], encryptBuf[2000]={0}; + short pos = 1900, len, outlen2,pdu_pos=0; + var_list *pvar; + BYTE var_num; + BYTE idlen; + DWORD *poid, val; + short stack[10]; + BYTE pstack = 0; + BOOL error_status = 0; + BYTE tmp_int[4]; + BYTE *pAuthPara; + int index; + static DWORD boots=0; + u16 outlen = 0; + +#if SNMP_DEBUG_LOG + char debugBuf[512]; + sprintf(debugBuf,"build_snmpmsg(): var_num: %d",psnmp->var_num); + snmpLogInfo(debugBuf); +#endif + if(snmpVersion == SNMP_V3) + { + switch(psnmp->pdu_type) + { + case PDU_INFORM: + case PDU_REPORT: + case PDU_RSP: + psnmp->msgGlobalData.msgFlags &=0x3; + break; + case PDU_TRAP: + load_engine_para(psnmp, ip, port); + psnmp->msgGlobalData.msgFlags &=0x3; + break; + default: + load_engine_para(psnmp, ip, port); + psnmp->msgGlobalData.msgFlags |=0x4; + break; + } + } + else + psnmp->msgGlobalData.msgFlags =0; +// if(psnmp->msgVersion != SNMP_V3 && snmpVersion==SNMP_V3) +// load_engine_para(psnmp); + psnmp->msgGlobalData.msgMaxSize = SNMP_VAR_MAX; + var_num = psnmp->var_num; + for(pstack = 0; pstack < 5; pstack++) + stack[pstack] = pos; //push + + while(var_num-- >0) + { + stack[pstack++] = pos; //push + pvar = &psnmp->var[var_num]; + //add by yizane start + if(psnmp->pdu_type == PDU_GET|| + psnmp->pdu_type == PDU_GETBULK|| + psnmp->pdu_type == PDU_GETNEXT) + //add by yizane end + { + pvar->vartype = 5; + pvar->msglen = 0; + } + else + { + switch(pvar->vartype) + { + case 5: //NULL + case NoSuchObject: + case NosuchInstance: + case EndOfMibView: + pvar->msglen = 0; + } + } + poid = pvar->oid; + //Value + if(pvar->msglen>SNMP_VAR_MAX) + { + if(psnmp->error_status == 0) + { + psnmp->error_status = 1; //Too big + psnmp->error_index = var_num; + } + snmp_debug(SNMPDB_ERR, "Variable's length(%d) exceed limit:varindex = %d", pvar->msglen, SNMP_VAR_MAX, var_num); + pvar->msglen = 0; + error_status = 1; + return 0; + } + else if(((pos - pvar->msglen) < 500&&snmpVersion!=SNMP_V3)||((pos - pvar->msglen) < 586&&snmpVersion==SNMP_V3)) + { + if(psnmp->error_status == 0) + { + psnmp->error_status = 1; //Too big + psnmp->error_index = var_num; + } + snmp_debug(SNMPDB_ERR, "Totol length(%d) exceed limit(1500):current varindex = %d", 1900-pos+pvar->msglen, var_num); + pstack--; + pvar->msglen = 0; +// error_status = 1; +// return 0; + break; + } + else if(pvar->msglen > 0) + { + memcpy(msg + pos - pvar->msglen + 1, pvar->msg, pvar->msglen); //V + } + pos -= pvar->msglen; + + insert_length(msg, pos, pvar->msglen); //L + msg[pos--] = pvar->vartype; //T + //Object ID + stack[pstack++] = pos; //push + + idlen = pvar->oidlen; + if(idlen >= OID_MAXLEN) + { +// snmp_debug(SNMPDB_ERR, "OID's Length(%d) is Invalid.", idlen); + return 0; + } + + while(idlen-- > 2) //V + { + val = poid[idlen]; + if(val < 0x80) //1byte + *(msg + (pos--)) = val; + else if(val < 0x4000) //2byte + { + *(msg + (pos--)) = val & 0x7F; + *(msg + (pos--)) = ((val & 0x3FFF) >> 7) | 0x80; + } + else if(val < 0x200000) //3byte + { + *(msg + (pos--)) = val & 0x7F; + *(msg + (pos--)) = ((val & 0x3FFF) >> 7) | 0x80; + *(msg + (pos--)) = (val >> 14) | 0x80; + } + else if(val < 0x10000000) //4byte + { + *(msg + (pos--)) = val & 0x7F; + *(msg + (pos--)) = ((val & 0x3FFF) >> 7) | 0x80; + *(msg + (pos--)) = ((val & 0x1FFFFF) >> 14) | 0x80; + *(msg + (pos--)) = (val >> 21) | 0x80; + } + else //5byte + { + *(msg+(pos--)) = val & 0x7F; + *(msg+(pos--)) = ((val & 0x3FFF) >> 7) | 0x80; + *(msg+(pos--)) = ((val & 0x1FFFFF) >> 14) | 0x80; + *(msg+(pos--)) = ((val & 0x0FFFFFFF) >> 21) | 0x80; + *(msg+(pos--)) = (val>>28) | 0x80; + } + } + if(poid[0] > 3 || (poid[0] < 3 && poid[1] >= 40)) + { +// snmp_debug(SNMPDB_ERR, "Wrong oid, varindex = %d, oid = %ld.%ld...\n", var_num, poid[0], poid[1]); + return 0; + } + *(msg + (pos--)) = poid[idlen] + poid[idlen - 1] * 40; + + + len = stack[--pstack] - pos; //pop + insert_length(msg, pos, len); //L + msg[pos--] = 0x06; + //Variable + len = stack[--pstack] - pos; //pop + insert_length(msg, pos, len); //L + msg[pos--] = 0x30; //T + }; + + //Variable Binding + len = stack[--pstack] - pos; //pop + insert_length(msg, pos, len); //L + msg[pos--] = 0x30; //T + //add by yizane start + if(psnmp->pdu_type == PDU_GETBULK) + { + //max-repeaters + msg[pos--] = psnmp->max_repetitions; //V + msg[pos--] = 1; //L + msg[pos--] = 0x02; //T + //Non-repeaters + msg[pos--] = psnmp->non_repeaters; //V + msg[pos--] = 1; //L + msg[pos--] = 0x02; //T + } + else + { + //error index + msg[pos--] = psnmp->error_index; //V + msg[pos--] = 1; //L + msg[pos--] = 0x02; //T + //error status + msg[pos--] = psnmp->error_status ; //V + msg[pos--] = 1; //L + msg[pos--] = 0x02; //T + } + //add by yizane end + //request-id + enc_integer(msg, pos, psnmp->request_id); //V L + msg[pos--] = 0x02; //T + //PDU + len = stack[--pstack] - pos; //pop + insert_length(msg, pos, len); //L + msg[pos--] = psnmp->pdu_type | 0xA0; //T + + if(snmpVersion == SNMP_V3)//(psnmp->msgVersion==SNMP_V3) + { + len = strlen(psnmp->msgData.plaintext.contextName); + + memcpy(msg + pos - len + 1, (BYTE *)psnmp->msgData.plaintext.contextName, len); //V + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x4;//T + + if(psnmp->msgData.plaintext.seqFlag&1) + len = 12; + else + len = 0; + //memcpy(msg + pos - len + 1, (BYTE *)psnmp->msgData.plaintext.contextEngineID, len); //V + memcpy(msg + pos - len + 1, (BYTE *)psnmp->msgSecurityParameters.msgAuthoritativeEngineID,len); //pierre, should be contextEngineID + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x4;//T + + pdu_pos = pos+1; +// len = stack[--pstack] - pos; //pop + len =1900-pos; + insert_length(msg, pos, len); //L + if((psnmp->msgGlobalData.msgFlags&0x3)!=3) + msg[pos--] = 0x30; + else + { + msg[pos--] = 0x30; + pdu_pos = pos+1; +/* pdu_pos = pos+1; //encrypt pdu + len =1900-pos; + insert_length(msg, pos, len); //L + msg[pos--] = 0x4; +*/ + } +// len = stack[--pstack] - pos; //pop + len = 1900 - pos; + if(psnmp->msgGlobalData.msgFlags&1)//auth + { + + psnmp->msgSecurityParameters.seqFlag |=16; + index = find_engine(psnmp->msgSecurityParameters.msgUserName)%MAX_ENGINE; + + if((psnmp->msgGlobalData.msgFlags>>1)&1) + { + int i; + psnmp->msgSecurityParameters.seqFlag |=32; + snmpV3EncryptData(v3_engine[index].privacyKey, AUTH_KEY_LEN,\ + &msg[pdu_pos], len, encryptBuf, &outlen,\ + (u8 *)psnmp->msgSecurityParameters.msgPrivacyParameters, (u16 *)&outlen2, boots); + for(i = 0; imsgSecurityParameters.seqFlag = psnmp->msgSecurityParameters.seqFlag%16; + + //build_msgSecurityParameters + outlen2 = pos; + if((psnmp->msgSecurityParameters.seqFlag>>5)&1) + len = 8; + else + len = 0; + memcpy(msg + pos - len + 1, (BYTE *)psnmp->msgSecurityParameters.msgPrivacyParameters, len); //V + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x4;//T + if((psnmp->msgSecurityParameters.seqFlag>>4)&1) + len = 12; + else + len = 0; + pAuthPara = msg + pos - len + 1; + memcpy(msg + pos - len + 1, (BYTE *)psnmp->msgSecurityParameters.msgAuthenticationParameters, len); //V + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x4;//T + if((psnmp->msgSecurityParameters.seqFlag>>3)&1) + len = strlen(psnmp->msgSecurityParameters.msgUserName); + else + len = 0; + memcpy(msg + pos - len + 1, (BYTE *)psnmp->msgSecurityParameters.msgUserName, len); //V + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x4;//T + if((psnmp->msgSecurityParameters.seqFlag>>2)&1) + { + len = encode_integer(tmp_int , psnmp->msgSecurityParameters.msgAuthoritativeEngineTime); + memcpy(msg + pos -len + 1, tmp_int, len); + } + else + len = 0; + + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x2;//T + + if((psnmp->msgSecurityParameters.seqFlag>>1)&1) + { + len = encode_integer(tmp_int , psnmp->msgSecurityParameters.msgAuthoritativeEngineBoots); + memcpy(msg + pos -len + 1, tmp_int, len); + } + else + len = 0; + + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x2;//T + + if((psnmp->msgSecurityParameters.seqFlag)&1) + len = 12; + else + len = 0; + memcpy(msg + pos - len + 1, (BYTE *)psnmp->msgSecurityParameters.msgAuthoritativeEngineID, len); //V + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x4;//T + + len = outlen2-pos; + insert_length(msg, pos, len); //L + msg[pos--] = 0x30; + len = outlen2-pos; + insert_length(msg, pos, len); //L + msg[pos--] = 0x4; + + //build_msgGlobalData + outlen2 = pos; + + len = encode_integer(tmp_int , psnmp->msgGlobalData.msgSecurityModel); + memcpy(msg + pos -len + 1, tmp_int, len); + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x2;//T + + len = 1; +/* + switch(psnmp->pdu_type) + { + case PDU_TRAP: + case PDU_INFORM: + case PDU_REPORT: + case PDU_RSP: + psnmp->msgGlobalData.msgFlags &=0x3; + break; + default: + psnmp->msgGlobalData.msgFlags |=0x4; + break; + } +*/ + msg[pos] = psnmp->msgGlobalData.msgFlags; + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x4;//T + + if((psnmp->msgGlobalData.seqFlag>>1)&1) + { + len = encode_integer(tmp_int , psnmp->msgGlobalData.msgMaxSize); + memcpy(msg + pos -len + 1, tmp_int, len); + } + else + len = 0; + + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x2;//T + + if((psnmp->msgGlobalData.seqFlag)&1) + { + len = encode_integer(tmp_int , psnmp->msgGlobalData.msgID); + memcpy(msg + pos -len + 1, tmp_int, len); + } + else + len = 0; + + pos -= len; + msg[pos--] = len; + msg[pos--] = 0x2;//T + + //len = stack[--pstack] - pos; //pop + len = outlen2 -pos; + insert_length(msg, pos, len); //L + msg[pos--] = 0x30; + } + else + { + //community + + if(psnmp->pdu_type == PDU_TRAP) + { + memcpy(msg + pos - 5, (BYTE *)COMMUNITY, 6); //V + pos -= 6; + msg[pos--] = 6; + } + else + { +#if SNMP_ANY_COMMUNITY + psnmp->community[15] = 0; //max length = 15 + comm_len = strlen(psnmp->community); + + memcpy(msg + pos - comm_len + 1, (BYTE *)psnmp->community, comm_len); //V + pos -= comm_len; + msg[pos--] = comm_len; +#else //use "public" as community + memcpy(msg + pos - 5, (BYTE *)COMMUNITY, 6); //V + pos -= 6; + msg[pos--] = 6; +#endif + } + if(pos<4) return 0; + /*added by LHB, Oct. 30 04 */ + if(pstack<2) return 0; + /*added by LHB, Oct. 30 04 */ + //L + msg[pos--] = 0x04; //T + } + //version + //msg[pos--] = SNMP_V2; //V + msg[pos--] = snmpVersion;// psnmp->msgVersion; //V + msg[pos--] = 1; //L + msg[pos--] = 0x02; //T + //head + len = stack[--pstack] - pos; //pop + if(len<0) return 0; + /*added by LHB, Oct. 30 04 */ + insert_length(msg, pos, len); //L + msg[pos--] = 0x30; //T + len = stack[--pstack] - pos; //pop + if(len<0) return 0; + /*added by LHB, Oct. 30 04 */ + if((psnmp->msgGlobalData.msgFlags&1) && (snmpVersion == SNMP_V3))//auth + { + snmpV3AuthenticateOutgoingMsg (v3_engine[index].authKey, /*secret key for authentication*/ + AUTH_KEY_LEN, + &msg[pos+1], /* unauthenticated complete message*/ + len, + pAuthPara, /* authenticationParamemeter */ + &outlen + ); + } + if(len >= 1514)//MAX_CONTENT_LEN) + { + snmp_debug(SNMPDB_ERR, "Build_msg 's length(%d) exceed limit:varindex = %d", len, var_num); + pvar->msglen = 0; + error_status = 1; + return 0; + } + memcpy(pbuf, msg + pos + 1, len); + //if(error_status) + // return 0; + //else + boots++; + +#if SNMP_DEBUG_LOG + snmpLogInfo("end of build_snmpmsg()"); +#endif + return len; +} + +int parse_snmpmsg(BYTE *msgin, int msglen, snmp_pdu *psnmp, BYTE *error_status) +{ + u_int pos = 0, idend; + u_int pdu_len,offset; + int len, tmplen; + BYTE idlen, varindex = 0; + var_list *pvar; + DWORD *poid; + BYTE *pAuthPtr; +#if SNMP_DEBUG_LOG + char debugBuf[512]; + sprintf(debugBuf,"parse_snmpmsg(), msg len = %d",msglen); + snmpLogInfo(debugBuf); +#endif + + if(msglen > 1536 || msglen < 0) + { + return -1; + } + psnmp->error_status = 0; + if(msgin[pos++] != 0x30) //T + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg0: Wrong Encoding of SNMP Message. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg1: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + + pos += tmplen; + + if(pos + len > msglen) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg2: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else //correct length + { + msglen = pos + len; + } + +//version------> + if(msgin[pos] != 2 || msgin[pos + 1] != 1) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg3: Wrong Encoding of SNMP Message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += 2; + + if(msgin[pos] != SNMP_V1 && msgin[pos] != SNMP_V2 && msgin[pos] != SNMP_V3) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg4: Version check error, Version = %d", msgin[pos]); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + psnmp->msgVersion = msgin[pos]; + pos++; + if(psnmp->msgVersion==SNMP_V3) + { + if(msgin[pos++]!=0x30) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg5: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg111: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else if((pos + len > msglen)||(len > msglen)) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg69: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + + //tmplen = msgin[pos++]; //pierre + //parse_hd + if(msgin[pos++]!=2) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg6: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]%5; + psnmp->msgGlobalData.msgID = decode_integer(&msgin[pos], tmplen); + pos +=tmplen; + if(msgin[pos++]!=2) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg7: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]%5; + psnmp->msgGlobalData.msgMaxSize = decode_integer(&msgin[pos], tmplen); + pos +=tmplen; + if(msgin[pos++]!=4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg8: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]%5; + psnmp->msgGlobalData.msgFlags = decode_integer(&msgin[pos], tmplen); + pos +=tmplen; + if(msgin[pos++]!=2) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg9: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]%5; + psnmp->msgGlobalData.msgSecurityModel = decode_integer(&msgin[pos], tmplen); + pos +=tmplen; + psnmp->msgGlobalData.seqFlag = 0xff; + //parse_securityPara + psnmp->msgSecurityParameters.seqFlag = 0; + + if(msgin[pos++]!=4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg10: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(msgin[pos++] != 0x30) //T + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg11: Wrong Encoding of SNMP Message. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg12: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else if((pos + len > msglen)||(len > msglen)) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg70: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos +=tmplen; + if(msgin[pos++]!=4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg13: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(tmplen != 0) + psnmp->msgSecurityParameters.seqFlag |= 1; + memcpy(psnmp->msgSecurityParameters.msgAuthoritativeEngineID,&msgin[pos], tmplen); + pos +=tmplen; + if(msgin[pos++]!=2) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg14: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(tmplen != 0) + psnmp->msgSecurityParameters.seqFlag |= 2; + psnmp->msgSecurityParameters.msgAuthoritativeEngineBoots = decode_integer(&msgin[pos], tmplen); + pos +=tmplen; + if(msgin[pos++]!=2) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg15: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(tmplen != 0) + psnmp->msgSecurityParameters.seqFlag |= 4; + psnmp->msgSecurityParameters.msgAuthoritativeEngineTime = decode_integer(&msgin[pos], tmplen); + pos +=tmplen; + if(msgin[pos++]!=4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg16: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(tmplen != 0) + psnmp->msgSecurityParameters.seqFlag |= 8; + memcpy(psnmp->msgSecurityParameters.msgUserName,&msgin[pos], tmplen); + psnmp->msgSecurityParameters.msgUserName[tmplen]=0; + pos +=tmplen; + if(msgin[pos++]!=4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg17: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(tmplen != 0) + psnmp->msgSecurityParameters.seqFlag |= 16; + memcpy(psnmp->msgSecurityParameters.msgAuthenticationParameters,&msgin[pos], tmplen); + pAuthPtr = msgin+pos; + pos +=tmplen; + if(msgin[pos++]!=4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg18: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(tmplen != 0) + psnmp->msgSecurityParameters.seqFlag |= 32; + memcpy(psnmp->msgSecurityParameters.msgPrivacyParameters,&msgin[pos], tmplen); + pos +=tmplen; + + if((psnmp->msgGlobalData.msgFlags&0x03)==3)//auth & privacy //pierre + { + if(msgin[pos++]!=4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg19: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg20: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else if((pos + len > msglen)||(len > msglen)) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg71: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos +=tmplen; + + } + else + { + if(msgin[pos++] != 0x30) //T + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg21: Wrong Encoding of SNMP Message. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg22: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else if((pos + len > msglen)||(len > msglen)) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg72: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos +=tmplen; + + } + + if(psnmp->msgGlobalData.msgFlags&0x1)//auth + { + int ret, index; + index = find_engine(psnmp->msgSecurityParameters.msgUserName); + if(index < 0) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg: unknow userName = %s", psnmp->msgSecurityParameters.msgUserName); + *error_status = UnknownUserNames; + } + else + { + ret = snmpV3AuthenticateIncomingMsg(v3_engine[index].authKey, + AUTH_KEY_LEN, + //msgin+pos, + //len, + msgin, + len+pos, + //psnmp->msgSecurityParameters.msgAuthenticationParameters, MD5_DIGEST_90_LEN); + pAuthPtr, MD5_DIGEST_90_LEN); + if(ret<0) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg: Auth failed of userName = %s", psnmp->msgSecurityParameters.msgUserName); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + *error_status = WrongDigests; + //return -1; + } + if(psnmp->msgGlobalData.msgFlags&0x2)//privacy + { + memcpy(psnmp->msgData.encryptedPDU, &msgin[pos], len); + if(snmpV3DecryptData(v3_engine[index].privacyKey, AUTH_KEY_LEN, (u8 *)psnmp->msgSecurityParameters.msgPrivacyParameters, + 8, (u8 *)psnmp->msgData.encryptedPDU, len, + msgin+pos, (u16 *)&tmplen)<0) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg: Decrypt failed of userName = %s", psnmp->msgSecurityParameters.msgUserName); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + *error_status = DecryptionErrors; + return 1; + } + } + } + } + + if(msgin[pos]== 0x30) + { + pos++; + //tmplen = get_len(msgin + pos, &len); + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg73: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else if((pos + len > msglen)||(len > msglen)) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg74: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos +=tmplen; + } + + if(msgin[pos++]!= 4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg23: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + //tmplen = get_len(msgin + pos, &len); + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg75: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else if((pos + len > msglen)||(len > msglen)) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg76: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos +=tmplen; + + psnmp->msgData.plaintext.seqFlag = 0; + if(len>0) + psnmp->msgData.plaintext.seqFlag |=1; + memcpy(psnmp->msgData.plaintext.contextEngineID, &msgin[pos], len); + pos +=len; + + if(msgin[pos++]!= 4) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg24: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + tmplen = msgin[pos++]; + if(tmplen>0) + psnmp->msgData.plaintext.seqFlag |=2; + memcpy(psnmp->msgData.plaintext.contextName, &msgin[pos], tmplen); + psnmp->msgData.plaintext.contextName[tmplen]=0; + pos +=tmplen; + + } + else + { +//community------> + + if(msgin[pos++] != 4) //T + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg25: Wrong Encoding of SNMP Message. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg26: Wrong Encoding of Length. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + + if(len > 32) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg27: Invalid Length of community. pos = %d, len = %d", pos - tmplen, len); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + + if((msgin[pos + len] & 0x1F) != PDU_TRAP) + { +#if SNMP_ANY_COMMUNITY + if(memcmp(msgin + pos, psnmp->community, len) != 0) //V + { + //authorization error + psnmp->error_status = 16; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg28: Authorization error. COMMUNITY(%s):", psnmp->community); + snmp_showbuf(SNMPDB_ERR, msgin + pos, len); + } +#else //"public" as community + if(memcmp(msgin + pos, COMMUNITY, len) != 0) //V + { + //authorization error + psnmp->error_status = 16; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg29: Authorization error. COMMUNITY(%s):", COMMUNITY); + snmp_showbuf(SNMPDB_ERR, msgin + pos, len); + } +#endif + } + pos += len; + } +//PDU------> + psnmp->pdu_type = msgin[pos++] & 0x1F; //T + + if(psnmp->pdu_type == PDU_REPORT) + { + printf("snmp receive REPORT\n"); + printf("\n"); + } + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg30: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + else if((pos + len > msglen)||(len > msglen)) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg77: Message's length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + pdu_len = len; + offset = pos; //pierre +/* + if(pos + len != msglen) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg: Length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } +*/ + //request-id------> + if(msgin[pos++] != 2) //T + { + //wrong encoding + if(psnmp->error_status == 0) + psnmp->error_status = 9; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg50: Wrong encoding of SNMP message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + } + + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg51: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + if(len > 5) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg52: ASN.1 encoding error.pos = %d", pos - 4); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + psnmp->request_id = decode_integer(msgin + pos, len); //V + pos += len; + //error status------> + //add by yizane start + if(psnmp->pdu_type==PDU_GETBULK) + { + if(msgin[pos++] != 2) //T + { + //wrong encoding + if(psnmp->error_status == 0) + psnmp->error_status = 9; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg53: Wrong encoding of SNMP message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + } + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg54: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + if(len > 5) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg55: ASN.1 encoding error.pos = %d", pos - 4); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + idend = pos + len; + psnmp->non_repeaters = 0; + do //V + { + if((msgin[pos] & 0x80) == 0) + psnmp->non_repeaters |= msgin[pos]; + else + psnmp->non_repeaters = (psnmp->non_repeaters | (msgin[pos] & 0x7F)) << 7; + pos++; + }while(pos < idend); + } + else + { + if(msgin[pos] != 2 || msgin[pos + 1] != 1) //T L + { + //wrong encoding + if(psnmp->error_status == 0) + psnmp->error_status = 9; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg56: Wrong encoding of SNMP message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + } + pos += 2; + + if(psnmp->error_status == 0){ + psnmp->error_status = msgin[pos++]; //V + }else + pos++; + } + + //error index------> + if(psnmp->pdu_type==PDU_GETBULK) + { + if(msgin[pos++] != 2) //T + { + //wrong encoding + if(psnmp->error_status == 0) + psnmp->error_status = 9; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg57: Wrong encoding of SNMP message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + } + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg58: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + if(len > 5) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg59: ASN.1 encoding error.pos = %d", pos - 4); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + idend = pos + len; + psnmp->max_repetitions =0; + do //V + { + if((msgin[pos] & 0x80) == 0) + psnmp->max_repetitions |= msgin[pos]; + else + psnmp->max_repetitions = (psnmp->max_repetitions | (msgin[pos] & 0x7F)) << 7; + pos++; + }while(pos < idend); + } + else + { + if(msgin[pos] != 2 || msgin[pos + 1] != 1) //T L + { + //wrong encoding + if(psnmp->error_status == 0) + psnmp->error_status = 9; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg60: Wrong Encoding of SNMP message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + } + pos += 2; + psnmp->error_index = msgin[pos++]; //V + } + //add by yizane end + + //variable-binding list------> + if(msgin[pos++] != 0x30) //T + { + //wrong encoding + if(psnmp->error_status == 0) + psnmp->error_status = 9; + snmp_debug(SNMPDB_ERR, "parse_snmpmsg61: Wrong encoding of SNMP message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + } + + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg62: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; +/* + if(pos + len != msglen) //check length + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg: Message's Length check error"); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } +*/ + if(pos >= msglen) + { + psnmp->var_num = 0; + return 1;// no varibale + } + //variable------> + varindex = 0; + do + { + pvar = &psnmp->var[varindex]; + + poid = pvar->oid; + if(msgin[pos++] != 0x30) //T + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg63: Wrong encoding of SNMP message. pos = %d", pos); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg64: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + //OID------> + if((msgin[pos++] & 0x3F) != 0x06) //T + { + if(psnmp->error_status == 0) + { + psnmp->error_status = 9; + } + } + + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg65: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + + if(len > OID_MAXLEN) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg66: OID length exceed limit. oidlen = %d", len); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + + memset(poid, 0, sizeof(DWORD) * OID_MAXLEN); + idend = pos + len; + poid[0] = msgin[pos] / 40; + poid[1] = msgin[pos++] % 40; + idlen = 2; + do //V + { + if((msgin[pos] & 0x80) == 0) + poid[idlen++] |= msgin[pos]; + else + poid[idlen] = (poid[idlen] | (msgin[pos] & 0x7F)) << 7; + pos++; + }while(pos < idend && idlen < OID_MAXLEN); + + pvar->oidlen = idlen; + //value + pvar->vartype = msgin[pos++]; //T + + if((tmplen = get_len(msgin + pos, &len)) < 0) //L + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg67: Wrong Encoding of Length. pos = %d", pos - 1); + snmp_showbuf(SNMPDB_ERR, msgin, msglen); + return -1; + } + pos += tmplen; + + if(len > 1500 || len > msglen-pos) + { + snmp_debug(SNMPDB_ERR, "parse_snmpmsg68: Error length of variant.varindex = %d, length = %d", varindex, len); + return -1; + } + else if(len > 0) + { + memcpy(pvar->msg, msgin + pos, len); //V + } + pos += len; + pvar->msglen = len; + varindex++; + //}while(pos < msglen); + }while((pos-offset) < pdu_len); + + psnmp->var_num = varindex; + +#if SNMP_DEBUG_LOG + snmpLogInfo("end of parse_snmpmsg()"); +#endif + return 1; +} + +/********************************************************************/ +DWORD assign_rid() +{ + static DWORD rid = 1; + + rid = (rid-1)%0x10000000+2; + return rid; +} + +BYTE *getmem(int nsize) +{ + //static BYTE watchPoint; + static BYTE heap[HEAP_SIZE]; //500K + static int heap_pos = 0; + //static BYTE watchPoint2; + if(heap_pos+nsize>HEAP_SIZE) + return NULL; + else + { + memset(heap+heap_pos, 0, nsize); + heap_pos+= nsize; + //printf("assigned memory = %d Byte\n", heap_pos); + return &heap[heap_pos-nsize]; + } +} +/********************************************************************/ + +int get_len(BYTE *asnbuf, int *len) +{ + u_int pos = 0, lenbyte; + + if((asnbuf[pos] & 0x80) == 0) + *len = asnbuf[pos++] & 0x7F; + else + { + *len = 0; + lenbyte = asnbuf[pos++] & 0x7F; + if(lenbyte > 4 || lenbyte < 0) + return -1; + + if(lenbyte == 0) + { + *len = -1; + return 1; + } + else + { + while(lenbyte-- > 0) + *len = (*len) * 0x100 + asnbuf[pos++]; + } + } + return pos; +} + +BYTE encode_integer(BYTE *buf, DWORD val) +{ + if(val < 128) + { + buf[0] = val; + return 1; + } + else if(val < 0x8000) + { + buf[0] = val >> 8; + buf[1] = val; + return 2; + } + else if(val < 0x800000) + { + buf[0] = val >> 16; + buf[1] = val >> 8; + buf[2] = val; + return 3; + } + else if(val < 0x80000000) + { + buf[0] = val >> 24; + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; + return 4; + } + else + { + buf[0] = 0; + buf[1] = val >> 24; + buf[2] = val >> 16; + buf[3] = val >> 8; + buf[4] = val; + return 5; + } +} + +DWORD decode_integer(BYTE *buf, BYTE len) +{ + BYTE i = 0; + DWORD val = 0; + while(i < len) + val = (val << 8) | buf[i++]; + return val; +} + +int add_security_engine(snmpV3SecurityPara *engine) +{ + return 1; +} + +int delete_security_engine(snmpV3SecurityPara *engine) +{ + return 1; +} + +int check_security_engine(snmpV3SecurityPara *engine) +{ + return 1; +} + +int load_engine_para(snmp_pdu *engine, DWORD ip, WORD port) +{ + int i=0, first_level=-1, sec_level=-1, third_level=-1,server_index; + static int msgID=0; + snmpV3SecurityPara *ptr=NULL; + + for(i=0; i=0) + { + server_index = third_level; + } + if(sec_level>=0) + { + server_index = sec_level; + } + if(first_level>=0) + { + server_index = first_level; + } + + ptr = &v3_engine[server_index]; + engine->msgGlobalData.seqFlag = 0xF; + engine->msgGlobalData.msgID=msgID++ ; + engine->msgGlobalData.msgMaxSize = SNMP_VAR_MAX; + engine->msgGlobalData.msgSecurityModel = 3; + engine->msgGlobalData.msgFlags = ptr->securityLevel; + engine->msgVersion = SNMP_V3; + engine->msgData.plaintext.seqFlag = 0xf; + memcpy(engine->msgData.plaintext.contextEngineID, ptr->contextEngineID,32); + memcpy(engine->msgData.plaintext.contextName, ptr->contextName,32); + engine->msgSecurityParameters.seqFlag = 0xff; + memcpy(engine->msgSecurityParameters.msgAuthoritativeEngineID, ptr->securityEngineID,32); +// memcpy(engine.msgSecurityParameters.msgAuthenticationParameters, ptr->authPassword,32); + memcpy(engine->msgSecurityParameters.msgUserName, ptr->securityUserName, 32); + engine->msgSecurityParameters.msgAuthoritativeEngineBoots = ptr->boots; + engine->msgSecurityParameters.msgAuthoritativeEngineTime = ptr->authInTime; +// memcpy(engine.msgSecurityParameters.msgPrivacyParameters, ptr->privacyProtocol, 32); + return 0; +} + +void init_engine_para() +{ + int i; + snmpV3SecurityPara *psnmp; + + for(i=0;i < MAX_ENGINE; i++) + { + psnmp = &v3_engine[i]; + if(strlen(psnmp->securityUserName)==0) + continue; + if(psnmp->engineType==0) + memcpy(securityEngineID, psnmp->securityEngineID, 32); + password_to_key_md5((u8 *)psnmp->privacyPassword, strlen(psnmp->privacyPassword), (u8 *)psnmp->securityEngineID, 12, psnmp->privacyKey); + password_to_key_md5((u8 *)psnmp->authPassword, strlen(psnmp->authPassword), (u8 *)psnmp->securityEngineID, 12, psnmp->authKey); + } + +} + +int init_engine(char *engine_name) +{ + int i; + snmpV3SecurityPara *psnmp; + + for(i=0;i < MAX_ENGINE; i++) + { + psnmp = &v3_engine[i]; + if(strlen(psnmp->securityUserName)==0 ) + continue; + if(strcmp(psnmp->securityUserName, engine_name)!=0 ) + continue; + password_to_key_md5((u8 *)psnmp->privacyPassword, strlen(psnmp->privacyPassword), (u8 *)psnmp->securityEngineID, 12, psnmp->privacyKey); + password_to_key_md5((u8 *)psnmp->authPassword, strlen(psnmp->authPassword), (u8 *)psnmp->securityEngineID, 12, psnmp->authKey); + } + return 1; +} + +int load_snmp_para() +{ + return 1; +} +void update_engine_authtime() +{ + int i,len; + + for(i=0; i=MAX_ENGINE) + return 0; + + s[strlen(s)-1]=0; + if(strstr(s, "userName=")!=NULL) + { + s[strlen(s)]=0; + strncpy(v3_engine[index].securityUserName, s+9, 32); + return 0; + } + else if(strstr(s, "authPassword=")!=NULL) + { + strncpy(v3_engine[index].authPassword, s+13, 32); + + return 0; + } + else if(strstr(s, "privacyPassword=")!=NULL) + { + strncpy(v3_engine[index].privacyPassword, s+16, 32); + + return 0; + } + else if(strstr(s, "engineID=")!=NULL) + { + //strncpy(v3_engine[index].securityEngineID, s+9, 32); + AsciiToBcd((BYTE *)v3_engine[index].securityEngineID, s+9, 24); + return 0; + } + else if(strstr(s, "engineType=")!=NULL) + { + v3_engine[index].engineType = atoi(s+11); + + return 0; + }else if(strstr(s, "securityLevel=")!=NULL) + { + v3_engine[index].securityLevel= atoi(s+14); + return 0; + }else if(strstr(s, "boots=")!=NULL) + { + v3_engine[index].boots= atoi(s+6); + return 0; + }else if(strstr(s, "authInTime=")!=NULL) + { + v3_engine[index].authInTime= atoi(s+11); + return 0; + }else if(strstr(s, "contextName=")!=NULL) + { + if(s[12] != 0x3d ) //\d + strncpy(v3_engine[index].contextName, s+12, 32); + else + memset(v3_engine[index].contextName,0,32); + return 0; + }else if(strstr(s, "contextEngineID=")!=NULL) + { + //strncpy(v3_engine[index].contextEngineID, s+16, 32); + AsciiToBcd((BYTE *)v3_engine[index].contextEngineID, s+16, 24); + return 0; + }else if(strstr(s, "remoteIp=")!=NULL) + { + //strncpy(v3_engine[index].contextEngineID, s+16, 32); + v3_engine[index].remote_ip=inet_addr(s+9); + return 0; + }else if(strstr(s, "remotePort=")!=NULL) + { + v3_engine[index].remote_port=atoi(s+11); + return 0; + }else if(strstr(s, "admin_state=")!=NULL) + { + //strncpy(v3_engine[index].contextEngineID, s+16, 32); + v3_engine[index].admin_state=atoi(s+12); + return 0; + } + return 0; +} + +void snmp_readpara() +{ + char s[1024]={0}; + int len, index; + + BYTE state = 0; + FILE *fp; + + fp = fopen(snmpconfile,"rb"); + + if (fp==NULL) + { + printf("snmpconfig file %s missed!!\n",snmpconfile); + return; + } + + s[0] = 0; + while ( fgets(s,1024,fp) != (char *)0 ) + { + if ( (int *)strchr(s,'#') != NULL ) continue; + if ( (len=strlen(s))==0 ) continue; + + if ( strstr(s,"[engine-") != NULL ) + { + index = atoi(s+8); + state = 1; + continue; + } + else if(strstr(s,"[manager]") != NULL) + { + state = 3; + continue; + } + else if ( strstr(s,"[version-") != NULL ) + { + snmpVersion = atoi(s+9); + state = 2; + continue; + } + switch (state) + { + case 1: + if (ReadEngineUserPara(s, index)) + state = 0; + break; + case 3: + ReadManagerPara(s); + break; + default: + break; + } + } + fclose(fp); +} + + +int snmp_write_parameter() +{ + int i; + FILE *snmpfp; + struct in_addr ad1; + char str[256]={0}; + + snmpfp = fopen(snmpconfile,"w"); + if (snmpfp == NULL) + return -1; + + fprintf(snmpfp,"[version-%d]\n", snmpVersion); + fprintf(snmpfp,"\n"); + fprintf(snmpfp,"[manager]\n"); + BcdToAscii(str, (BYTE *)manager_engine.securityEngineID, 24); + fprintf(snmpfp,"engineID=%s\n",str); + fprintf(snmpfp,"\n"); + for(i=0;i 4096) + { + snmpDebugFull = 1; + return; + } + + strncat(debug_buf, info, 4094); + strcat(debug_buf, "\r\n"); + return; +} + +int snmp_filter_msg(snmp_pdu *pMsg, snmp_addr *pAddr) +{ + int i; + for(i = 0; i < SnmpFilterIndex % 9; i++) + { + if(SnmpFilter[i].type != pMsg->pdu_type && pMsg->pdu_type != 0xFF) + continue; + if(SnmpFilter[i].flag & 0x01) + { + if(SnmpFilter[i].ip != pAddr->remote_ip) + continue; + } + if(SnmpFilter[i].flag & 0x02) + { + if(memcmp(SnmpFilter[i].oid, pMsg->var[0].oid, SnmpFilter[i].oidlen * 4) != 0) + continue; + } + if(SnmpFilter[i].flag & 0x04) + { + if(SnmpFilter[i].local_port != pAddr->local_port) + continue; + } + if(SnmpFilter[i].flag & 0x08) + { + if(SnmpFilter[i].remote_port != pAddr->remote_port) + continue; + } + return 1; + } + return 0; +} + +void snmp_debug(DWORD mask, const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + if((mask & debug_mask) == 0 || snmpDebugFull) + return; + + if(mask & SNMPDB_ERR) + strcat(debug_buf, "\33[31m"); + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + strcat(buf,"\33[37m"); + snmp_log(buf); +} + +void snmp_showbuf(DWORD mask, BYTE *buf, int len) +{ + int i = 0, j = 0, linemax = 24; + char info[1024]; + + if((debug_mask & SNMPDB_VALUE) == 0 || (debug_mask & mask) == 0 || snmpDebugFull) + return; + + if(len >= 256) + len = 256; + + while(i * 24 < len) + { + if((linemax = len - 24 * i) > 24) + linemax = 24; + for(j = 0; j < linemax; j ++) + { + sprintf(info + 3 * j, "%02X ", buf[24 * i + j]); + } + snmp_log(info); + i ++; + } +} +int oid2str(char *pStr, DWORD *oid, BYTE oidlen) +{ + int i; + char tmpstr[16]; + + pStr[0] = 0; + if(oidlen > OID_MAXLEN) oidlen = OID_MAXLEN; + + for(i = 0; i < oidlen - 1; i++) + { + sprintf(tmpstr, "%u.", oid[i]); + strcat(pStr, tmpstr); + } + sprintf(tmpstr, "%u", oid[oidlen - 1]); + strcat(pStr, tmpstr); + return 1; +} + +void snmp_logvalue(BYTE *msgbuf, short msglen) +{ + int len, i = 0, j, linemax; + char info[1024]; + + len = msglen % 256; + while(i * 24 < len) + { + if((linemax = len - 24 * i) > 24) + linemax = 24; + for(j = 0; j < linemax; j ++) + { + sprintf(info + 3 * j, "%02X ", msgbuf[24 * i + j]); + } + snmp_log(info); + i ++; + } +} + +void snmp_logmsg(DWORD mask, snmp_pdu *pdu, snmp_addr *addr) +{ + struct in_addr inaddr; + int i = 0; + char info[1024], oidstr[64], desc[64] = "\0"; + + if((debug_mask & mask) == 0 && snmp_filter_msg(pdu, addr) == 0) + return; + + if(snmpDebugFull) + return; + + if(mask & SNMPDB_ERR) + strcat(debug_buf, "\33[31m"); + + inaddr.s_addr = addr->remote_ip; + if(mask & SNMPDB_IN) + sprintf(desc, "\r\nlocal:%d <== %s:%d ", addr->local_port, inet_ntoa(inaddr), addr->remote_port); + else if(mask & SNMPDB_OUT) + sprintf(desc, "\r\nlocal:%d ==> %s:%d ", addr->local_port, inet_ntoa(inaddr), addr->remote_port); + else + sprintf(desc, "\r\nlocal:%d <=> %s:%d ", addr->local_port, inet_ntoa(inaddr), addr->remote_port); + + sprintf(info, "%sType=%s, RID=%u, Error=%d, Bind=%d\33[37m", desc, Type_Name[pdu->pdu_type], pdu->request_id + , pdu->error_status, pdu->var_num); + snmp_log(info); + + for(i = 0; i < pdu->var_num % 16; i++) + { + oid2str(oidstr, pdu->var[i].oid, pdu->var[i].oidlen); + sprintf(info, "oid[%d]=%s, vartype=%02x, msglen=%d", i, oidstr, pdu->var[i].vartype, pdu->var[i].msglen); + snmp_log(info); + + if((debug_mask & SNMPDB_VALUE) == 0) + return; + snmp_logvalue(pdu->var[i].msg, pdu->var[i].msglen); + } + +} + +static int get_word(char *pWord, char *pInStr, BYTE max) +{ + char *pStart = pInStr, *pCh = NULL; + + while(*pStart == ' ' || *pStart == '\t') + pStart ++; + + strncpy(pWord, pStart, max); + pCh = strchr(pWord, ' '); + if(pCh != NULL) + *pCh = 0; + return 1; +} + +static int parsecond(char *cmdstr, BYTE type) +{ + char *pKey = cmdstr, *pEQ, info[256], tmpStr[64], valStr[32]; + + if(SnmpFilterIndex >= 8) + { + snmp_log("only 8 pieces of condition can be set"); + return 0; + } + + sprintf(info, "type = 0x%02X", type); + SnmpFilter[SnmpFilterIndex].type = type; + SnmpFilter[SnmpFilterIndex].flag = 0; + + if((pKey = strstr(cmdstr, "ip")) != NULL && (pEQ = strchr(pKey, '=')) != NULL) + { + get_word(valStr, pEQ + 1, 32); + SnmpFilter[SnmpFilterIndex].ip = inet_addr(valStr); + sprintf(tmpStr, " and ip = %s", valStr); + strcat(info, tmpStr); + SnmpFilter[SnmpFilterIndex].flag |= 0x01; + } + if((pKey = strstr(cmdstr, "oid")) != NULL && (pEQ = strchr(pKey, '=')) != NULL) + { + get_word(valStr, pEQ + 1, 32); + if(SnmpFilter[SnmpFilterIndex].flag > 0) strcat(info, " and "); + sprintf(tmpStr, " and oid = %s", valStr); + strcat(info, tmpStr); + SnmpFilter[SnmpFilterIndex].oidlen = Str2Oid(SnmpFilter[SnmpFilterIndex].oid, valStr, OID_MAXLEN) % OID_MAXLEN; + SnmpFilter[SnmpFilterIndex].flag |= 0x02; + } + if((pKey = strstr(cmdstr, "local port")) != NULL && (pEQ = strchr(pKey, '=')) != NULL) + { + get_word(valStr, pEQ + 1, 32); + SnmpFilter[SnmpFilterIndex].local_port = atoi(valStr); + if(SnmpFilter[SnmpFilterIndex].flag > 0) strcat(info, " and "); + sprintf(tmpStr, " and local port = %d", SnmpFilter[SnmpFilterIndex].local_port); + strcat(info, tmpStr); + SnmpFilter[SnmpFilterIndex].flag |= 0x04; + } + if((pKey = strstr(cmdstr, "remote port")) != NULL && (pEQ = strchr(pKey, '=')) != NULL) + { + get_word(valStr, pEQ + 1, 32); + SnmpFilter[SnmpFilterIndex].remote_port = atoi(valStr); + if(SnmpFilter[SnmpFilterIndex].flag > 0) strcat(info, " and "); + sprintf(tmpStr, " and remote port = %d", SnmpFilter[SnmpFilterIndex].remote_port); + strcat(info, tmpStr); + SnmpFilter[SnmpFilterIndex].flag |= 0x08; + } + + SnmpFilterIndex ++; + snmp_log(info); + snmp_log("command OK"); + return 1; +} + +void snmp_debug_timer() +{ + BYTE npage, nline; + char *cmdstr = asc_in + 1; + if(strlen(asc_in) <= 1) + return; + debug_buf[0] = '\0'; + npage = asc_in[0] - 1; + + if(npage > 0) + { + nline = atoi(asc_in + 1); + switch(npage) + { + case 1: //csta + snmp_debug_csta(1,nline); + break; + } + asc_in[0]='\0'; + return; + } + + asc_in[0]='\0'; + if(strstr(cmdstr, "help") != NULL || strstr(cmdstr, "?") != NULL) + { + snmp_log(help_info); + return; + } + else if(strstr(cmdstr, "log all") != NULL) + { + SnmpFilterIndex = 0; + debug_mask = 0xFFFFFFFF; + } + else if(strstr(cmdstr, "log none") != NULL) + { + SnmpFilterIndex = 0; + debug_mask = 0; + } + else if(strstr(cmdstr, "log error on") != NULL) + debug_mask |= SNMPDB_ERR; + else if(strstr(cmdstr, "log error off") != NULL) + debug_mask &= (~SNMPDB_ERR); + else if(strstr(cmdstr, "log onreg on") != NULL) + debug_mask |= SNMPDB_NOREG; + else if(strstr(cmdstr, "log onreg off") != NULL) + debug_mask &= (~SNMPDB_NOREG); + else if(strstr(cmdstr, "log value on") != NULL) + debug_mask |= SNMPDB_VALUE; + else if(strstr(cmdstr, "log value off") != NULL) + debug_mask &= (~SNMPDB_VALUE); + else if(strstr(cmdstr, "log alarm on") != NULL) + debug_mask |= SNMPDB_ALARM; + else if(strstr(cmdstr, "log alarm off") != NULL) + debug_mask &= (~SNMPDB_ALARM); + else if(strstr(cmdstr, "log mib on") != NULL) + debug_mask |= SNMPDB_MIB; + else if(strstr(cmdstr, "log mib off") != NULL) + debug_mask &= (~SNMPDB_MIB); + else if(strstr(cmdstr, "log sys on") != NULL) + debug_mask |= SNMPDB_SYS; + else if(strstr(cmdstr, "log sys off") != NULL) + debug_mask &= (~SNMPDB_SYS); + else if(strstr(cmdstr, "log snmp") != NULL) + { + parsecond(cmdstr + 8, 0xFF); + return; + } + else if(strstr(cmdstr, "log get") != NULL) + { + parsecond(cmdstr + 7, 0); + return; + } + else if(strstr(cmdstr, "log set") != NULL) + { + parsecond(cmdstr + 7, 3); + return; + } + else if(strstr(cmdstr, "log rsp") != NULL) + { + parsecond(cmdstr + 7, 2); + return; + } + else if(strstr(cmdstr, "log trap") != NULL) + { + parsecond(cmdstr + 8, 7); + return; + } + else if(strstr(cmdstr, "reload") != NULL) + { + snmp_readpara(); + init_engine_para(); + snmp_log("Command OK"); + + return; + } + else + { + snmp_log("Invalid command/parameter(s)."); + return; + } + + snmp_log("Command OK"); + return; +} + +void snmp_debug_info(BYTE npage, BYTE nline, BYTE *pt, BYTE len) +{ + DWORD oid[20]={1,3,6,1,4,1,1373,1,1,2,3,1,2,13,5,2,2}; + oid[14] = 5 + npage; + oid[15] = 2 + nline; + debug_set_response(17, oid, pt, len); +} + +/*-----------------------------------------------*/ +/*-------------------CSTA------------------------*/ +/*-----------------------------------------------*/ +void snmp_debug_csta(BYTE npage,int instance) +{ + char title[256]; + snmp_csta *pcsta; + + instance=instance%96; + pcsta=&SnmpCsta[instance]; + + sprintf(title,"\tSNMP-%s\tPage %02d\t\tMIB-CSTA(ID:1 Instance:%d)\r\n\r\n"\ + "trap in\r\n"\ + "trap out\r\n"\ + "set in\r\n"\ + "set out\r\n"\ + "get in\r\n"\ + "get out\r\n"\ + "rsp in\r\n"\ + "rsp out\r\n"\ + "fail to parse\r\n"\ + "OID Not registered\r\n"\ + "fail to build\r\n", SnmpVer, npage, instance); + + title_id[14]=5+npage; + debug_set_response(16,title_id, (BYTE *)title,strlen(title)); + + snmp_debug_info(npage,0,(BYTE *)&pcsta->trap_in,4); + snmp_debug_info(npage,1,(BYTE *)&pcsta->trap_out,4); + snmp_debug_info(npage,2,(BYTE *)&pcsta->set_in,4); + snmp_debug_info(npage,3,(BYTE *)&pcsta->set_out,4); + snmp_debug_info(npage,4,(BYTE *)&pcsta->get_in,4); + snmp_debug_info(npage,5,(BYTE *)&pcsta->get_out,4); + snmp_debug_info(npage,6,(BYTE *)&pcsta->rsp_in,4); + snmp_debug_info(npage,7,(BYTE *)&pcsta->rsp_out,4); + snmp_debug_info(npage,8,(BYTE *)&pcsta->fail_parse,4); + snmp_debug_info(npage,9,(BYTE *)&pcsta->not_register,4); + snmp_debug_info(npage,10,(BYTE *)&pcsta->fail_build,4); + +} + +void snmp_debug_hb(BYTE npage) +{ + char title[512]; + sprintf(title,"\tSNMP-%s\tPage %02d\t\tHeartBeat\r\n"\ + "\r\n"\ + "subsys id\r\n"\ + "LED\r\n"\ + "Component 0\r\n"\ + "\r\n"\ + "Component 1\r\n"\ + "\r\n"\ + "Component 2\r\n"\ + "\r\n"\ + "Component 3\r\n"\ + "\r\n"\ + "Component 4\r\n"\ + "\r\n"\ + "Component 5\r\n"\ + "\r\n"\ + "Component 6\r\n"\ + "\r\n"\ + "alarm num\r\n"\ + "HB message\r\n\r\n", SnmpVer, npage); + + title_id[14]=5+npage; + + debug_set_response(16,title_id, (BYTE *)title,strlen(title)); + + snmp_debug_info(npage,0,(BYTE *)&HbShm->sys_id,2); + snmp_debug_info(npage,1,(BYTE *)HbShm->led,LED_NUM); + snmp_debug_info(npage,2,(BYTE *)&HbShm->component[0],20); + snmp_debug_info(npage,3,(BYTE *)&HbShm->component[0]+20,20); + snmp_debug_info(npage,4,(BYTE *)&HbShm->component[1],20); + snmp_debug_info(npage,5,(BYTE *)&HbShm->component[1]+20,20); + snmp_debug_info(npage,6,(BYTE *)&HbShm->component[2],20); + snmp_debug_info(npage,7,(BYTE *)&HbShm->component[2]+20,20); + snmp_debug_info(npage,8,(BYTE *)&HbShm->component[3],20); + snmp_debug_info(npage,9,(BYTE *)&HbShm->component[3]+20,20); + snmp_debug_info(npage,10,(BYTE *)&HbShm->component[4],20); + snmp_debug_info(npage,11,(BYTE *)&HbShm->component[4]+20,20); + snmp_debug_info(npage,12,(BYTE *)&HbShm->component[5],20); + snmp_debug_info(npage,13,(BYTE *)&HbShm->component[5]+20,20); + snmp_debug_info(npage,14,(BYTE *)&HbShm->component[6],20); + snmp_debug_info(npage,15,(BYTE *)&HbShm->component[6]+20,20); + + snmp_debug_info(npage,16,(BYTE *)&HbShm->alarm_num,1); + snmp_debug_info(npage,17,(BYTE *)&HbShm->msg,20); + snmp_debug_info(npage,18,(BYTE *)&HbShm->msg+20,20); + snmp_debug_info(npage,19,(BYTE *)&HbShm->msg+40,20); + snmp_debug_info(npage,20,(BYTE *)&HbShm->msg+60,20); + snmp_debug_info(npage,21,(BYTE *)&HbShm->msg+80,20); + +} + + + diff --git a/plat/snmp/src/snmpmib.c b/plat/snmp/src/snmpmib.c new file mode 100644 index 0000000..f0d87d6 --- /dev/null +++ b/plat/snmp/src/snmpmib.c @@ -0,0 +1,224 @@ +/**************************************************/ +/*Title: snmpdebug.c */ +/*Descr: Debug Module of SNMP Agent */ +/*Author: Liang Hanxi */ +/*Create: 2002-4-1 */ +/*Modify: */ +/**************************************************/ +#include "./include/heartbeat.h" +static unsigned long l_starttime; +extern snmp_csta SnmpCsta[96]; +extern int snmp_ins; +extern heartbeat_shm *HbShm; + +int snmp_setmib(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD datalen); +int snmp_getmib(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +int snmp_getsys(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +void time_sync(BYTE oidlen,DWORD *oid,BYTE *pdata,WORD len,snmp_addr *addr); +static void submit_snmpcsta(BYTE *pdword,BYTE *pbyte,int len); + +void snmpmib_init() +{ + DWORD oid[OID_MAXLEN]=SNMP_OID; + DWORD sysoid[8]={1,3,6,1,2,1,1}; + l_starttime=time(NULL); + inquire_getmsg(SNMP_OIDLEN,oid,snmp_getmib); + inquire_setmsg(SNMP_OIDLEN,oid,snmp_setmib); + inquire_getmsg(7,sysoid,snmp_getsys); + inquire_trapmsg(time_sync); +} + +int snmp_setmib(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD datalen) +{ + return -1; + switch(oid[SNMP_OIDLEN]) + { + case 1: //Measure + return -1; //read only + case 2: //Configuration + switch(oid[SNMP_OIDLEN+1]) + { + case 1: //SNMP Parameter + switch(oid[SNMP_OIDLEN+2]) + { + case 1: //Port + return -1; //not allow + case 2: //password + return -1; //not provide now + } + break; + case 2: + break; + + case 3: + break; + } + break; + case 3: + break; + } +} + + +int snmp_getmib(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype) +{ + int instance; + snmp_csta *pcsta; + switch(oid[SNMP_OIDLEN]) + { + case 1: //csta + if(oidlen!=SNMP_OIDLEN+2) + return -1; + instance=oid[SNMP_OIDLEN+1]; + if(instance==snmp_ins || instance>95) + { + *vartype=NosuchInstance; + snmp_debug(SNMPDB_MIB,"csta message not ready.instance=%d",instance); + return -1; + } + pcsta=&SnmpCsta[instance]; + if(pcsta->timestamp ==0) + { + snmp_debug(SNMPDB_MIB,"csta message is expired"); + *vartype=5; + return 0; + } + *vartype=4; + snmp_debug(SNMPDB_MIB, "Respond csta message"); + submit_snmpcsta((BYTE *)&pcsta->timestamp,pdata,sizeof(snmp_csta)); + //memcpy(pdata,(BYTE *)&pcsta->timestamp,sizeof(snmp_csta)); + return sizeof(snmp_csta); + default: + return -1; + } + return -1; +} + + +int snmp_getsys(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype) +{ + unsigned long l_time; + char contact[50]="InterWAVE"; + char sysname[50]; + + switch(oid[oidlen - 1]) + { + case 1: + *vartype = 4; + memcpy(pdata, SnmpVer, strlen(SnmpVer)); + return strlen(SnmpVer); + case 3: + l_time=time(NULL); + *vartype=0x43; + return encode_integer(pdata,(l_time-l_starttime)*100); + case 4: + *vartype=4; + memcpy(pdata,contact,strlen(contact)); + return strlen(contact); + case 5: + *vartype=4; + sprintf(sysname,"SNMP Agent %d.%d",HbShm->sys_id,HbShm->subsys_id); + memcpy(pdata,sysname,strlen(sysname)); + return strlen(sysname); + } + return -1; +} + +#define SNMP_OMC_HB_OID {1,3,6,1,4,1,1373,2,4,1} +#define SNMP_OMC_HB_OIDLEN 10 +#define SNMP_SERNUM_LEN 4 + +ull Bcd2Ull(BYTE *pBcd, int BcdLen); + +extern unsigned long long SNMPSerialNumber; +extern BYTE snmp_synctime_flag; +void time_sync(BYTE oidlen,DWORD *oid,BYTE *pdata,WORD len,snmp_addr *addr) +{ + //DWORD ObjID[20]=FLATFORM_HB_OID; + DWORD OMCHBObjID[20] = SNMP_OMC_HB_OID; + heartbeat_msg *pmsg=(heartbeat_msg *)pdata; + struct timeval tv; + struct timezone tz; + long l_time,l_temp; + static long master_host=0,master_timeout; + + if (!snmp_synctime_flag) + return; + + if(memcmp(&oid[7], &OMCHBObjID[7], (SNMP_OMC_HB_OIDLEN - 7) * 4) == 0)//omc heartbeat + {//automatic add omc ip into ip list, + //if receive omc heartbeat and the omc serial number is equial to the local serial number, + //then the platform will send heartbeat if received omc heartbeat + if ((SNMPSerialNumber==0) ||//support old version, do not have serial number + (Bcd2Ull(&pdata[39],SNMP_SERNUM_LEN)==SNMPSerialNumber) ) + {} + else + return; + + } + else// if it is not omc heartbeat then return + return; + + if(pmsg->subsys_id ==HbShm->subsys_id && pmsg->sys_id ==HbShm->sys_id) + return; + +/* + if(memcmp(&oid[9],&ObjID[9],(FLATFORM_HB_OIDLEN-9)*4)!=0) + { + return; + } +*/ +/* + if(pmsg->sys_id!=MasterSysID || pmsg->subsys_id!=MasterSubSysID) + return; +*/ + + if(SNMPSerialNumber!=0){//New version + if(pdata[26]!=5&&pdata[26]!=7)//not the master omc + return; + }else{//Old version + if(pdata[21]!=5&&pdata[21]!=7)//not the master omc + return; + } + + memcpy((BYTE *)&l_temp,pmsg->timestamp,4); + l_time=htonl(l_temp); //timestamp in heartbeat + gettimeofday(&tv,&tz); //local time + + if(master_host==0 || master_timeout<=0) + { + snmp_debug(SNMPDB_SYS, "change master host to %lX",htonl(addr->remote_ip)); + master_host=addr->remote_ip; + master_timeout=8; + } + + if(addr->remote_ip != master_host) + { + master_timeout--; + snmp_debug(SNMPDB_SYS, "Found another master,ip=%lX.current master=%lX,timeout=%ld\n",htonl(addr->remote_ip),htonl(master_host),master_timeout); + return; + } + else + master_timeout=8; + + if(abs(l_time-tv.tv_sec)<2) //compare + { + return; + } + tv.tv_sec =l_time; + settimeofday(&tv,&tz); + snmp_debug(SNMPDB_SYS, "system's time is changed by %lX\n",htonl(addr->remote_ip)); +} + +void submit_snmpcsta(BYTE *pdword,BYTE *pbyte,int len) +{ + int i; + DWORD *p1,*p2; + for(i=0;i + * + * Description: provide a mechanism to register and maintain snmp table, simplify app programing + */ + +#include "./include/snmp.h" + + +#define MAX_SNMP_REGISTER 32 /* Maximum of modules registering snmp table */ + +/* It's great chance that next object and current one in same table, so cache improves searching efficiency */ +static struct snmp_table_profile *cache; +static struct snmp_register *reg_cache; +static struct snmp_register snmpregister[MAX_SNMP_REGISTER]; + +//#define PRINT_OID + +#ifdef PRINT_OID +static void printoid(u32 *oid, u8 len) +{ + int i; + + if(len == 0) + printf("OID length is 0!\n"); + + printf("%ld", oid[0]); + for(i = 1; i < len; i++) + { + printf(".%ld", oid[i]); + } + printf("\n"); +} +#endif + +/* To check if oid matches oid prefix */ +static int oid_match_prefix(u8 prefix_len, u32 *prefix, u8 oid_len, u32 *oid) +{ + if(prefix_len == 0) + return 0; + if(oid_len < prefix_len) + return 0; + if(!memcmp(prefix, oid, prefix_len*sizeof(u32))) + return 1; + else + return 0; +} + +static struct snmp_register *find_snmp_register(u8 oid_len, u32 *oid) +{ + int i; + struct snmp_register *reg; + + if(reg_cache != NULL) + { + if(oid_match_prefix(reg_cache->prefix_len, reg_cache->prefix_oid, oid_len, oid) == 1) + return reg_cache; + } + + for(i = 0; i < MAX_SNMP_REGISTER; i++) + { + reg = &snmpregister[i]; + if(oid_match_prefix(reg->prefix_len, reg->prefix_oid, oid_len, oid) == 1) + { + reg_cache = reg; + return reg; + } + } + return NULL; +} + +/* Check cache first, otherwise check all snmp tables by matching oid with table index */ +static struct snmp_table_profile *find_snmp_table(u8 oid_len, u32 *oid) +{ + int i; + struct snmp_register *reg; + struct snmp_table_profile *t; + + if(cache != NULL) + { + if(oid_match_prefix(cache->index.len, cache->index.oid, oid_len, oid) == 1) + return cache; + } + + if((reg = find_snmp_register(oid_len, oid)) == NULL) + return NULL; + + for(i = 0; i < reg->num_of_table; i++) + { + t = ®->table[i]; + if(oid_match_prefix(t->index.len, t->index.oid, oid_len, oid) == 1) + { + cache = t; + return t; + } + } + return NULL; +} + +static u32 find_next_column(u32 current_column, u32 *columns) +{ + int i; + + for(i = 0; i < MAX_COLUMNAR_OF_TABLE-1; i++) + { + if(current_column == columns[i]) + return columns[i+1]; + } + return 0; +} + +static void point_to_column_and_instance(u32 **column, u32 **instance, u32 *oid, struct snmp_table_profile *t) +{ + if(t->level != 0) + { + *column = oid + t->index.len + 1; /* count the entry, hence plus 1 */ + } + else + { + *column = oid + t->index.len; + } + *instance = *column + 1; +} + +static int table_set_response(u8 oidlen, u32 *oid, u8 *pdata, u16 datalen) +{ + struct snmp_table_profile *t; + struct snmp_register *reg; + u32 *column; + u32 *instance; + + if((t = find_snmp_table(oidlen, oid)) == NULL) + { + if((reg = find_snmp_register(oidlen, oid)) == NULL) + return -1; + if(reg->default_set_resp == NULL) + return -1; + else + return reg->default_set_resp(oidlen, oid, pdata, datalen); + } + + point_to_column_and_instance(&column, &instance, oid, t); + + if(t->set_resp == NULL) + return -1; + else + return t->set_resp(*column, instance, pdata, datalen); +} + +static int table_get_response(u8 oidlen, u32 *oid, u8 *pdata, u8 *vartype) +{ + struct snmp_table_profile *t; + struct snmp_register *reg; + u32 *column; + u32 *instance; + + if((t = find_snmp_table(oidlen, oid)) == NULL) + { + if((reg = find_snmp_register(oidlen, oid)) == NULL) + return -1; + if(reg->default_get_resp == NULL) + return -1; + else + return reg->default_get_resp(oidlen, oid, pdata, vartype); + } + + point_to_column_and_instance(&column, &instance, oid, t); + + if(t->get_resp == NULL) + return -1; + else + return t->get_resp(*column, instance, pdata, vartype); +} + +static int get_next_oid(u8 *oidlen, u32 *oid) +{ + struct snmp_table_profile *t; + u32 *entry; + u8 entry_oid_len; + u32 *column; + u8 column_oid_len; + u32 *instance; + u8 full_oid_len; + u8 plus_one_suppress = 0; + + if((t = find_snmp_table(*oidlen, oid)) == NULL) + return 0; + if(t->level == 0) /* If MIB is not table basis, do not support get next */ + return 0; + + entry = oid + t->index.len; + entry_oid_len = t->index.len + 1; + column = entry + 1; + column_oid_len = entry_oid_len + 1; + instance = column + 1; + full_oid_len = column_oid_len + t->level; + + if(*oidlen < full_oid_len) + { + memset(oid+*oidlen, 0, (full_oid_len-*oidlen)*sizeof(u32)); + if(*oidlen < entry_oid_len) + *entry = 1; + if(*oidlen < column_oid_len) + *column = t->column[0]; + *oidlen = full_oid_len; + plus_one_suppress = 1; + } + for(; *column != 0; *column = find_next_column(*column, t->column)) + { + if(plus_one_suppress == 0) + instance[t->level-1]++; + + if(t->get_instance(instance) == 1) + return 1; + else + { + memset(instance, 0, t->level*sizeof(u32)); + plus_one_suppress = 1; + } + } + return 0; +} + +static int table_getnext_response(u8 prev_oidlen, u32 *prev_oid, u8 *oidlen, u32 *oid, u8 *pdata, u8 *vartype) +{ + memcpy(oid, prev_oid, prev_oidlen*sizeof(u32)); + *oidlen = prev_oidlen; +#ifdef PRINT_OID + printf("Prev oid: "); + printoid(oid, *oidlen); +#endif + if(get_next_oid(oidlen, oid) == 1) + { +#ifdef PRINT_OID + printf("Next oid: "); + printoid(oid, *oidlen); +#endif + return table_get_response(*oidlen, oid, pdata, vartype); + } + else + return -1; +} + +int register_snmp_table(struct snmp_register *reg) +{ + int i; + struct snmp_register *r; + + /* TODO: check table validation */ + + for(i = 0; i < MAX_SNMP_REGISTER; i++) + { + r = &snmpregister[i]; + if(r->prefix_len == 0) + { + memcpy(r, reg, sizeof(struct snmp_register)); + inquire_getmsg(r->prefix_len, r->prefix_oid, table_get_response); + inquire_setmsg(r->prefix_len, r->prefix_oid, table_set_response); + inquire_getnextmsg(r->prefix_len, r->prefix_oid, table_getnext_response); + return 1; + } + } + return 0; +} + + diff --git a/plat/snmp/src/snmptest.c b/plat/snmp/src/snmptest.c new file mode 100644 index 0000000..dfbcd57 --- /dev/null +++ b/plat/snmp/src/snmptest.c @@ -0,0 +1,254 @@ +#include "./include/snmp.h" +#include "./include/heartbeat.h" + +static struct itimerval itimer,old_itimer; +int intval; +char strval[50]="hello!"; +static void On_Timer(); +static void SetTimer(); +static int get_rsp(BYTE object_id_len, DWORD *object_id, BYTE *data_ptr,BYTE *vartype); +static int getnext_rsp(BYTE in_oidlen, DWORD in_oid[], BYTE *oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype); +static int set_rsp(BYTE object_id_len, DWORD *object_id, BYTE *data_ptr,WORD len); +static void pro_rsp(snmp_pdu *pdata,snmp_addr *addr); +//static int atoi_hex(char* input); + + static DWORD oid[10] ={1,3,6,1,4,1,12189,2,2,50}; +//static DWORD oid[11] ={1,3,6,1,4,1,12189,2,1,50,6}; + static int table_len = 9; + static int row_len = 11; + static int table_id = 50; + +void showbuf(BYTE *buf,int len) +{ + int i; + for(i=0;i0 && i%25==0) + printf("\n"); + else + printf(" "); + } + printf("\n"); +} + +static void showid(DWORD *buf,int len) +{ + int i; + for(i=0;i0 && i%25==0) + printf("\n"); + } + printf("\n"); +} +static void trap_callback(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD len,snmp_addr *addr) +{ + //printf("Receive trap message,oid:"); + //showid(oid,oidlen); + //showbuf(pdata,len); +} + + +int main() +{ + intval=123456; + snmp_init(4961); + heartbeat_init(0x1234); + SetTimer(); + inquire_trapmsg(trap_callback); + inquire_setmsg(1,oid,set_rsp); + inquire_getmsg(1,oid,get_rsp); + inquire_rspmsg(10,oid,pro_rsp); + inquire_getnextmsg(10,oid,getnext_rsp); + //cls; + set_led(0,8); + set_alarm(0,1); + +{ + + DWORD request_id; + snmp_pdu request_msg; + snmp_addr request_addr; +// iptrans_init(); + iptrMainInit(); + + request_msg.pdu_type = PDU_GETBULK; + request_msg.max_repetitions = 199900; + request_msg.non_repeaters = 0; + request_msg.request_id = 10; + request_msg.var_num = 1; + sprintf(request_msg.community, "public"); + + memcpy(request_msg.var[0].oid, oid, 4 * 10); + + request_msg.var[0].oidlen = 10; + + + + request_addr.remote_ip =inet_addr("127.0.0.1"); + request_addr.local_ip =inet_addr("172.48.234.128"); + request_addr.remote_port =4961; + request_addr.local_port =4961; + request_addr.broadcast =1; + + + request_id = snmp_send(&request_msg, &request_addr); + printf("%u\n",request_id); + sleep(2); + +} + while(1) + { + usleep(50); + } + + return 1; + +} + + +int getnext_rsp(BYTE in_oidlen, DWORD *in_oid, BYTE *oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype) +{ + memcpy(oid,in_oid,in_oidlen*sizeof(DWORD)); + //printf("receive command\n"); + if(in_oidlen<12) + { + oid[10]=1; + oid[11]=1; + oid[12]=0; + in_oidlen=13; + } + else + { + oid[in_oidlen-1] =in_oid[in_oidlen-1]+1; + } + if(oid[in_oidlen-1]>12) + { + oid[in_oidlen-1]=0; + oid[in_oidlen-2]=in_oid[in_oidlen-2]+1; + if(oid[in_oidlen-2]>20) + return -1; + } + pdata[0] = oid[in_oidlen-1]; + *vartype=2; + *oidlen = in_oidlen; + return 1; +} + + +void pro_rsp(snmp_pdu *pdata,snmp_addr *addr) +{ + int i,getflag,value=0; + static int old_oid=0; + DWORD request_id; + snmp_pdu request_msg; + snmp_addr request_addr; + getflag = 1; + for(i=0;ivar_num;i++) + { + if(pdata->var[i].oid[table_len]!=table_id||pdata->var[i].vartype==EndOfMibView) + { + printf("\n"); + getflag = 0; + break; + } + if(pdata->var[i].oid[row_len]!=old_oid) + printf("\n"); + + old_oid = pdata->var[i].oid[row_len]; + value = decode_integer(pdata->var[i].msg,pdata->var[i].msglen); + printf("%-5d",value); + } + + if(getflag) + { + request_msg.pdu_type = PDU_GETBULK; + request_msg.max_repetitions = 10; + request_msg.non_repeaters = 0; + request_msg.var_num = 1; + sprintf(request_msg.community, "public"); + memcpy(request_msg.var[0].oid, pdata->var[pdata->var_num-1].oid, 4 * pdata->var[pdata->var_num-1].oidlen); + request_msg.var[0].oidlen = pdata->var[pdata->var_num-1].oidlen; + + request_addr.remote_ip =addr->remote_ip; + request_addr.remote_port =addr->remote_port; + request_addr.local_port =addr->local_port; + request_id = snmp_send(&request_msg, &request_addr); + } + return; +} + +void On_Timer() +{ + + snmp_timer(); + iptrans_timer(); + //heartbeat_timer(); +} + +void SetTimer() +{ + struct sigaction act; + act.sa_handler=On_Timer; + sigemptyset(&act.sa_mask); + act.sa_flags=0; + if(sigaction(SIGALRM,&act,NULL)<0) + { + perror("Produce Sigaction"); + exit(1); + } + + itimer.it_interval.tv_sec=0; + itimer.it_interval.tv_usec=1000; + itimer.it_value.tv_sec=0; + itimer.it_value.tv_usec=1000; + + if (setitimer(ITIMER_REAL,&itimer,&old_itimer) !=0 ) + { + printf("Setting Timer error! \n"); + exit(1); + } +} + + + +int get_rsp(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype) +{ + printf("I Receive get message,oid:"); + showid(oid,oidlen); + /* + if(object_id[1]==2) + { + memcpy(data_ptr,(BYTE *)&intval,4); + return 4; + } + else + { + memcpy(data_ptr,(BYTE *)&strval,strlen(strval)); + return strlen(strval); + } + */ + return -1; +} + +int set_rsp(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD len) +{ + printf("I Receive set message,oid:"); + showid(oid,oidlen); + showbuf(pdata,len); + /* + if(object_id[1]==2) + { + memcpy((BYTE *)&intval,data_ptr,4); + return 4; + } + else + { + memcpy((BYTE *)&strval,data_ptr,len); + return len; + } + */ + return -1; +} diff --git a/plat/snmp/src/snmpv3AuthCry.c b/plat/snmp/src/snmpv3AuthCry.c new file mode 100644 index 0000000..21de7ac --- /dev/null +++ b/plat/snmp/src/snmpv3AuthCry.c @@ -0,0 +1,278 @@ + +#include +#include +#include +#include +#include +#include +#include "include/snmpv3AuthCry.h" + +extern void md5_calc( + unsigned char *output, + unsigned char *input, /* input block */ + unsigned int inlen /* length of input block */ + ); + +extern void des(unsigned char *output, const unsigned char *input, const unsigned char *key, int direction); + +#define EXTEND_AUTH_LEN 64 +#define MD5_DIGEST_LEN 16 + +#define MAX_SNMP_LEN 1500 + +#define CRYPTIPN_BLOCK_LEN 8 + +static const u8 IPAD[EXTEND_AUTH_LEN]= +{ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36 +}; + +static const u8 OPAD[EXTEND_AUTH_LEN]= +{ + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C, + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C, + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C, + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C, + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C, + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C, + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C, + 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C +}; + + +static void XORFunction(u8 *input0, const u8 *input1,u8 *output,u8 len) +{ + int i; + + for(i=0;i0:success,else fail */ + u8 *inAuthKey, /*secret key for authentication*/ + u16 inAuthKeyLen, + u8 *inWholeMsg, /* unauthenticated complete message*/ + u16 inWholeMsgLen, + u8 *outAuthParameters, /* authenticationParamemeter */ + u16 *outAuthParametersLen +) +{ + int i; + u8 extendedAuthKey[EXTEND_AUTH_LEN]; + u8 K1[EXTEND_AUTH_LEN],K2[EXTEND_AUTH_LEN]; + u8 snmpData[MAX_SNMP_LEN]; + u8 digest1[MD5_DIGEST_LEN],digest2[MD5_DIGEST_LEN]; + + + if(inAuthKeyLen != AUTH_KEY_LEN) + return -1; + + memset(outAuthParameters,0,MD5_DIGEST_90_LEN); + memset(extendedAuthKey,0,EXTEND_AUTH_LEN); + memcpy(extendedAuthKey,inAuthKey,AUTH_KEY_LEN); + XORFunction(extendedAuthKey,IPAD,K1,EXTEND_AUTH_LEN); + XORFunction(extendedAuthKey,OPAD,K2,EXTEND_AUTH_LEN); + + memcpy(snmpData,K1,EXTEND_AUTH_LEN); + memcpy(snmpData+EXTEND_AUTH_LEN,inWholeMsg,inWholeMsgLen); + md5_calc(digest1,snmpData,EXTEND_AUTH_LEN+inWholeMsgLen); + + memcpy(snmpData,K2,EXTEND_AUTH_LEN); + memcpy(snmpData+EXTEND_AUTH_LEN,digest1,MD5_DIGEST_LEN); + md5_calc(digest2,snmpData,EXTEND_AUTH_LEN+MD5_DIGEST_LEN); + + *outAuthParametersLen = MD5_DIGEST_90_LEN; + for(i=0;i0:success,else fail */ + u8 *inAuthKey, /*secret key for authentication*/ + u16 inAuthKeyLen, + u8 *inWholeMsg, /* as received on the wire*/ + u16 inWholeMsgLen, + u8 *inAuthParameters, /* as received on the wire*/ + u16 inAuthParametersLen +) +{ + int i; + u8 extendedAuthKey[EXTEND_AUTH_LEN]; + u8 K1[EXTEND_AUTH_LEN],K2[EXTEND_AUTH_LEN]; + u8 snmpData[MAX_SNMP_LEN]; + u8 digest1[MD5_DIGEST_LEN],digest2[MD5_DIGEST_LEN],oldMAC[MD5_DIGEST_90_LEN],newMAC[MD5_DIGEST_90_LEN]; + + if(inAuthKeyLen != AUTH_KEY_LEN) + return -1; + if(inAuthParametersLen != MD5_DIGEST_90_LEN) + return -1; + memcpy(oldMAC,inAuthParameters,MD5_DIGEST_90_LEN); + memset(inAuthParameters,0,MD5_DIGEST_90_LEN); + + memset(extendedAuthKey,0,EXTEND_AUTH_LEN); + memcpy(extendedAuthKey,inAuthKey,AUTH_KEY_LEN); + XORFunction(extendedAuthKey,IPAD,K1,EXTEND_AUTH_LEN); + XORFunction(extendedAuthKey,OPAD,K2,EXTEND_AUTH_LEN); + + memcpy(snmpData,K1,EXTEND_AUTH_LEN); + memcpy(snmpData+EXTEND_AUTH_LEN,inWholeMsg,inWholeMsgLen); + md5_calc(digest1,snmpData,EXTEND_AUTH_LEN+inWholeMsgLen); + + memcpy(snmpData,K2,EXTEND_AUTH_LEN); + memcpy(snmpData+EXTEND_AUTH_LEN,digest1,MD5_DIGEST_LEN); + md5_calc(digest2,snmpData,EXTEND_AUTH_LEN+MD5_DIGEST_LEN); + + for(i=0;i0:success,else fail */ + u8 *inEncryptKey, /* secret key for encryption*/ + u16 inEncryptKeyLen, + u8 *inDataToEncrypt, /* data to encrypt (scopedPDU)*/ + u16 inDataToEncryptLen, + u8 *outEncryptedData, /* encrypted data (encryptedPDU)*/ + u16 *outEncryptedDataLen, + u8 *outPrivParameters, /* filled in by service provider*/ + u16 *outPrivParametersLen, + ulong runTime +) +{ + int i,blockCount; + u8 modValue,preIV[CRYPTIPN_BLOCK_LEN],iv[CRYPTIPN_BLOCK_LEN]; + u8 /*plainText[CRYPTIPN_BLOCK_LEN],*/XORedText[CRYPTIPN_BLOCK_LEN],CipherText[CRYPTIPN_BLOCK_LEN]; + u8 *pPlainText,*pCipherText; + u8 snmpV3Salt[CRYPTIPN_BLOCK_LEN]; + + if(inEncryptKeyLen != AUTH_KEY_LEN) + return -1; + modValue = inDataToEncryptLen % CRYPTIPN_BLOCK_LEN; + if(modValue) + {/* pad 0 to the rear */ + for(i=0;i0:success,else fail */ + u8 *inDecryptKey, /*secret key for decryption*/ + u16 inDecryptKeyLen, + u8 *inPrivParameters, /* as received on the wire*/ + u16 inPrivParametersLen, + u8 *inEncryptedData, /* encrypted data (encryptedPDU)*/ + u16 inEncryptedDataLen, + u8 *outDecryptedData, /*decrypted data (scopedPDU)*/ + u16 *outDecryptedDataLen +) +{ + int i,blockCount; + u8 desKey[CRYPTIPN_BLOCK_LEN],preIV[CRYPTIPN_BLOCK_LEN]; + u8 CipherText[CRYPTIPN_BLOCK_LEN],/*XORedText[CRYPTIPN_BLOCK_LEN],*/previousCipherText[CRYPTIPN_BLOCK_LEN]; + u8 *pPlainText,*pCipherText; + u8 initationVector[CRYPTIPN_BLOCK_LEN]; + + if(inDecryptKeyLen != AUTH_KEY_LEN) + return -1; + if(inEncryptedDataLen % CRYPTIPN_BLOCK_LEN) + return -1; + blockCount = inEncryptedDataLen / CRYPTIPN_BLOCK_LEN; + memcpy(desKey,inDecryptKey,CRYPTIPN_BLOCK_LEN); + memcpy(preIV,inDecryptKey+CRYPTIPN_BLOCK_LEN,CRYPTIPN_BLOCK_LEN); + XORFunction(preIV,inPrivParameters,initationVector,CRYPTIPN_BLOCK_LEN); + memcpy(previousCipherText,initationVector,CRYPTIPN_BLOCK_LEN); + + pPlainText = outDecryptedData; + pCipherText = inEncryptedData; + for(i=0;i16 + +//static mnt_list MntInfo[MAX_MNT_FILESYS]; +//static BYTE MntNum=0; +static hb_sysinfo SysInfo; +extern int errno; + +static BYTE get_idlecpu(); +static int parse_infoline(char *str,char (*row)[64],int maxrow); + +static int get_raminfo(hb_sysinfo *info); +static int get_ptinfo(hb_sysinfo *info); +static int change_hb_byte(hb_sysinfo *info, BYTE *output, BYTE *outlen); + +static BYTE snmp_hb_byte[512]; +static BYTE snmp_hb_len; + +void sysctrl_init() +{ + memset(&SysInfo,0,sizeof(SysInfo)); + + SysInfo.up_time=time(NULL); + SysInfo.idle_cpu_rate=get_idlecpu(); + get_raminfo(&SysInfo); + get_ptinfo(&SysInfo); + + change_hb_byte(&SysInfo,snmp_hb_byte,&snmp_hb_len); +} + +void system_report() +{ + static int m_state=0; + //struct sysinfo info; + //unsigned long totaldisk,freedisk; + + switch(m_state) + { + case 50*60*10: //10min + m_state=0; + + get_ptinfo(&SysInfo); + change_hb_byte(&SysInfo,snmp_hb_byte,&snmp_hb_len); + set_status(8,snmp_hb_len,(BYTE*)snmp_hb_byte); + + break; + default: + m_state++; + if(m_state%(50*30)==0) //30s + { + SysInfo.idle_cpu_rate=get_idlecpu(); + get_raminfo(&SysInfo); + change_hb_byte(&SysInfo,snmp_hb_byte,&snmp_hb_len); + set_status(8,snmp_hb_len,(BYTE*)snmp_hb_byte); + } + break; + } +} + +BYTE get_idlecpu() +{ + char buf[128],row[5][64]; + unsigned long timeofuser,timeofsys,timeofnice,timeofidle; + static unsigned long oldusertime=0,oldsystime=0,oldnicetime=0,oldidletime=0; + + unsigned long idlecpu,totalcpu; + unsigned short idlerate; + FILE *stat_fp=NULL; + + if((stat_fp=fopen("/proc/stat","r"))==NULL) + { + printf("Fail to open /proc/stat\n"); + exit(1); + } + + if(stat_fp == NULL) + return 0; + + if(fseek(stat_fp,0,SEEK_SET)!=0) + { + return 0; + } + if(fgets(buf,128,stat_fp)==NULL) + { + return 0; + } + + if(parse_infoline(buf,row,5)<5) + return 0; + + timeofuser=strtoul(row[1],NULL,10); + timeofnice=strtoul(row[2],NULL,10); + timeofsys=strtoul(row[3],NULL,10); + timeofidle=strtoul(row[4],NULL,10); + + totalcpu=timeofuser - oldusertime + timeofnice - oldnicetime + timeofsys - oldsystime + timeofidle - oldidletime; + if(totalcpu==0) + { + fclose(stat_fp); + return 0; + } + + idlecpu=timeofidle-oldidletime; + idlerate=(unsigned short)(((double)idlecpu/totalcpu)*100); + //store current time + oldusertime=timeofuser; + oldnicetime=timeofnice; + oldsystime=timeofsys; + oldidletime=timeofidle; + + if(idlerate > 100) + idlerate=100; + + fclose(stat_fp); + + return (BYTE)idlerate; +} + + +int get_raminfo(hb_sysinfo *info) +{ + int rn; + unsigned char rb,prb; + int field_id=0; + int field_id2=0; + char field_value[256][256]; + FILE *mem_fp=NULL; + + if((mem_fp=fopen("/proc/meminfo","r"))==NULL) + { + printf("Fail to open /proc/meminfo\n"); + exit(1); + } + + if(mem_fp == NULL) + return 0; + + memset(field_value,0,sizeof(field_value)); + + if(fseek(mem_fp,0,SEEK_SET)!=0) + { + fclose(mem_fp); + return 0; + } + + while((rn = fread(&rb,1,1,mem_fp))) + { + if(rb != 0x0A) + field_value[field_id][field_id2]=rb; + if(!(prb == 0x20 && rb == 0x20)) + field_id2++; + if((prb != 0x20 && rb == 0x20) || (rb == 0x0A)) + { + field_id2=0; + field_id++; + } + prb=rb; + } + + info->ram_total_used=atol(field_value[1])-atol(field_value[4]); + info->ram_total=atol(field_value[1]); + info->ram_swap_used=atol(field_value[34])-atol(field_value[37]); + info->ram_swap_total=atol(field_value[34]); + info->ram_buffers=atol(field_value[7]); + info->ram_cached=atol(field_value[10]); + + fclose(mem_fp); + + return 1; +} + +int get_ptinfo(hb_sysinfo *info) +{ + FILE *handle; + char line[256]; + char path[256]; + char *pc; + struct statfs fsbuf; + + handle=fopen("/etc/mtab","r"); + if(handle == NULL) + return 0; + + info->pt_count=0; + while(fgets(line,256,handle)) + { + if(strncmp(line,"/dev",4) == 0) + { + strtok(line," "); + pc=strtok(NULL," "); + if(pc == NULL) + continue; + sprintf(path,"%s",pc); + if(statfs(path,&fsbuf) == 0) + { + sprintf(info->pt[info->pt_count].mountpoint_path,"%s",path); + info->pt[info->pt_count].used_space=(fsbuf.f_blocks - fsbuf.f_bfree) * (fsbuf.f_bsize / 1024); + info->pt[info->pt_count].total_space=fsbuf.f_blocks * (fsbuf.f_bsize / 1024); + //printf("%s\t%ld\t%ld\n",path,info->pt[info->pt_count].total_space,info->pt[info->pt_count].used_space); + info->pt_count++; + if(info->pt_count == MAX_PARTITION_NUM) + { + fclose(handle); + return 1; + } + } + } + } + + fclose(handle); + + return 1; +} + +int change_hb_byte(hb_sysinfo *info, BYTE *output, BYTE *outlen) +{ + DWORD *pd; + BYTE *pb; + BYTE *copy; + int i; + BYTE len; + + copy=output; + pd=(DWORD*)copy; + *pd=htonl(info->up_time); + + copy+=sizeof(DWORD); + pb=(BYTE*)copy; + *pb=(BYTE)(info->idle_cpu_rate); + + copy+=sizeof(BYTE); + pd=(DWORD*)copy; + *pd=htonl(info->ram_total_used); + + copy+=sizeof(DWORD); + pd=(DWORD*)copy; + *pd=htonl(info->ram_total); + + copy+=sizeof(DWORD); + pd=(DWORD*)copy; + *pd=htonl(info->ram_swap_used); + + copy+=sizeof(DWORD); + pd=(DWORD*)copy; + *pd=htonl(info->ram_swap_total); + + copy+=sizeof(DWORD); + pd=(DWORD*)copy; + *pd=htonl(info->ram_buffers); + + copy+=sizeof(DWORD); + pd=(DWORD*)copy; + *pd=htonl(info->ram_cached); + + copy+=sizeof(DWORD); + pb=(BYTE*)copy; + *pb=(BYTE)(info->pt_count); + + copy+=sizeof(BYTE); + + for(i=0;ipt_count;i++) + { + len=strlen(info->pt[i].mountpoint_path); + pb=(BYTE*)copy; + *pb=(BYTE)len; + + copy+=sizeof(BYTE); + memcpy(copy,info->pt[i].mountpoint_path,len); + + copy+=len; + pd=(DWORD*)copy; + *pd=htonl(info->pt[i].used_space); + + copy+=sizeof(DWORD); + pd=(DWORD*)copy; + *pd=htonl(info->pt[i].total_space); + + copy+=sizeof(DWORD); + } + + *outlen=copy - output; + + return 1; +} + +int parse_infoline(char *str,char (*row)[64],int maxrow) +{ + char *pstr=str; + int len,index=0,i; + BOOL black=0; + len=strlen(str); + for(i=0;i64) + pstr[63]=0; + sprintf(row[index++],"%s",pstr); + pstr=str+i+1; + } + black=0; + } + else + black=1; + } + if(black==1) + { + if(strlen(pstr)>64) + pstr[63]=0; + sprintf(row[index++],"%s",pstr); + } + return index; +} + + diff --git a/plat/tcap/Makefile b/plat/tcap/Makefile new file mode 100644 index 0000000..689c379 --- /dev/null +++ b/plat/tcap/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = tcap +TYPE = plat + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/tcap/src/idmanage.c b/plat/tcap/src/idmanage.c new file mode 100644 index 0000000..17882fa --- /dev/null +++ b/plat/tcap/src/idmanage.c @@ -0,0 +1,292 @@ +/* ID management c file */ +/* written by Liu zhiguo 2002-08-06 */ +/* version 2.0 */ +/* ----------------------------- */ + +#include "../../sccp/src/include/sccp.h" +#include "./include/tcap_public.h" +#include "./include/tcap_struct.h" + +// fix multiple definition==================================== +struct tcapbuf_struct *tcap_ptr; +// + +/*@ignore@*/ +#define ID_VM_KEY 0xa0800000 +#define ID_VM_PERM 0664 + +typedef struct id_struct +{ + u32 current_did; + u32 count_did; + u32 count_did_occupied; + u32 count_did_max; + u32 count_did_tmp; + u8 dialogue_id[MAX_DIALOGUEID]; + u8 current_iid[MAX_DIALOGUEID]; + u8 invoke_id[MAX_DIALOGUEID][MAX_INVOKEID]; + u8 trans_iid[MAX_DIALOGUEID][MAX_INVOKEID]; +}id_struct; + +struct id_struct *ID_ptr; + +typedef struct _did_queunce_struct +{ + u32 head; + u32 tail; + u32 idle_did[MAX_DIALOGUEID*2]; +}did_queunce_struct; + +did_queunce_struct tcap_did_queunce; + +void init_id(int grantdid) // init the ID share memory +{ + int shm_id,i; + + /* tcap state machine share memory */ + if ((shm_id = shmget(ID_VM_KEY+wxc2_get_shm_offset(),sizeof(id_struct),ID_VM_PERM|IPC_CREAT)) == -1) + { + printf("can not init ID share memory"); + exit(0); + } + if ((ID_ptr = (id_struct *)shmat(shm_id,(char *)0,0)) == (id_struct *) -1) + { + printf("can not init ID share memory"); + exit(0); + } + memset(ID_ptr,0,sizeof(id_struct)); + + memset(&tcap_did_queunce,0,sizeof(did_queunce_struct)); + for(i=1;icount_did; +} + +u32 chkcount_did_occupied(void) +{ + return ID_ptr->count_did_occupied; +} + +u32 chkcount_did_max(void) +{ + return ID_ptr->count_did_max; +} + +void clrcount_did_max(void) +{ + ID_ptr->count_did_max = 0; +} + +u8 xapp_check_did_state(u32 did); + +u32 assign_did(void) +{ + u32 tmp_did=0; + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + + if(tcap_did_queunce.head != tcap_did_queunce.tail) + { + + tmp_did = tcap_did_queunce.idle_did[tcap_did_queunce.tail++]; + tcap_did_queunce.tail %= (MAX_DIALOGUEID*2); + + if(ID_ptr->dialogue_id[tmp_did]) + { + debug_ptr->watch_dog[218] ++; + assign_did(); + } + + ID_ptr->dialogue_id[tmp_did] = 1; + ID_ptr->count_did ++; + debug_ptr->watch_dog[223]++; + } + else + { + debug_ptr->watch_dog[218] ++; + } + + return tmp_did%MAX_DIALOGUEID; +} + +u32 assign_did1(void) // assign dialogue id +{ + u32 ii; + u32 jj; + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + + for (ii = 1;ii < (tcap_ptr->grantdid);ii++) + { + jj = (ID_ptr->current_did++) % (tcap_ptr->grantdid); + if ((jj != 0) && (ID_ptr->dialogue_id[jj] == 0) && (xapp_check_did_state(jj))) + { + ID_ptr->dialogue_id[jj] = 1; + ID_ptr->count_did ++; + ID_ptr->current_did = ID_ptr->current_did % (tcap_ptr->grantdid); + debug_ptr->watch_dog[223]++; + return jj; + } + } + debug_ptr->watch_dog[218] ++; + return 0; +} + +void free_did(u32 did) +{ + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + + if (did == 0 || did >= (tcap_ptr->grantdid)) + { + debug_ptr->watch_dog[219] ++; + return; + } + if (ID_ptr->dialogue_id[did] == 1) + { + ID_ptr->dialogue_id[did] = 0; + if (ID_ptr->count_did != 0) + ID_ptr->count_did --; + memset(ID_ptr->invoke_id[did],0,MAX_INVOKEID); // free all invoke id + debug_ptr->watch_dog[213] ++; + + tcap_did_queunce.idle_did[tcap_did_queunce.head++] = did; + tcap_did_queunce.head %= (MAX_DIALOGUEID*2); + } + debug_ptr->watch_dog[220] ++; + + +} + +void free_did1(u32 did) // free dialogue id +{ + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + + if (did == 0 || did >= (tcap_ptr->grantdid)) + { + debug_ptr->watch_dog[219] ++; + return; + } + if (ID_ptr->dialogue_id[did] == 1) + { + ID_ptr->dialogue_id[did] = 0; + if (ID_ptr->count_did != 0) + ID_ptr->count_did --; + memset(ID_ptr->invoke_id[did],0,MAX_INVOKEID); // free all invoke id + debug_ptr->watch_dog[213] ++; + } + debug_ptr->watch_dog[220] ++; +} + +int check_did(u32 did) +{ + if (did == 0 || did >= (tcap_ptr->grantdid)) + return 0; + if (ID_ptr->dialogue_id[did] == 0) // dialogue id is not assigned + return 0; + else + return 1; +} + +u8 assign_iid(u32 did) // assign invoke id,need know the dialogue id +{ + u32 ii, iid=64; + u8 current_iid; + //char buf[128]; + + if (did == 0 || did >= (tcap_ptr->grantdid)) + return 0xff; + current_iid = ID_ptr->current_iid[did]; + for (ii = 0;ii < MAX_INVOKEID;ii ++) + { + iid = (ii + 64 + current_iid) % MAX_INVOKEID;// % MAX_INVOKEID; + if (ID_ptr->invoke_id[did][iid] == 0) + { + //sprintf(buf,"assign iid: iid=%d, ii=%d, current_iid=%d\n", + // iid,ii,current_iid); + // tcap_send_ascout(buf); + ID_ptr->invoke_id[did][iid] = 1; + ID_ptr->trans_iid[did][iid] = iid; + ID_ptr->current_iid[did]++; + return iid; + } + } + //tcap_send_ascout("assign iid failed\n"); + memset(ID_ptr->invoke_id[did],0,MAX_INVOKEID); + return assign_iid(did); +} + +void free_iid(u32 did,u8 iid) // free invoke id +{ + //u8 info[1024]; + //u8 suc = 0; + + if (did >= 0 && did < (tcap_ptr->grantdid)) + { + ID_ptr->invoke_id[did][iid] = 0; + //suc = 1; + } + + //sprintf(info, "free_iid: did: %d, iid: %d suc: %d\r\n", did, iid, suc); + //tcap_send_ascout(info); +} + +int check_iid(u32 did,u8 iid) // check invoke id +{ + if (did == 0 || did >= (tcap_ptr->grantdid)) + return 0; + if (ID_ptr->invoke_id[did][iid] == 0) + return 0; + else + return 1; +} + +u8 store_iid(u32 did,u8 iid) // store invoke id +{ + //u8 info[1024]; + + //sprintf(info, "store_iid: did: %d, iid: %d\r\n", did, iid); + //tcap_send_ascout(info); + + if (did == 0 || did >= (tcap_ptr->grantdid)) + return 0; + //if (iid == 0) + // memset(ID_ptr->invoke_id[did],0,MAX_INVOKEID); + + //Change by daniel on 2006-6-19 + ////tcap do not has state machine for receiving invoke, so no need to look at the iid state everytime, + ////just set it to be occupied everytime + + if (ID_ptr->invoke_id[did][iid] == 1) + { + return 0; + } + ID_ptr->invoke_id[did][iid] = 1; + ID_ptr->trans_iid[did][iid] = iid; + ID_ptr->current_iid[did]++; + return 1; +} + +u8 transfer_iid(int did, u8 iid) +{ + u8 tmp_iid; + + tmp_iid = assign_iid(did); + ID_ptr->trans_iid[did][tmp_iid] = iid; + return tmp_iid; +} + +u8 get_transfer_iid(int did, u8 iid) +{ + return ID_ptr->trans_iid[did][iid]; +} + +void SetCurrentDid(u_short did) +{ + ID_ptr->current_did = did % (tcap_ptr->grantdid); +} +/*@end@*/ diff --git a/plat/tcap/src/include/idmanage.h b/plat/tcap/src/include/idmanage.h new file mode 100644 index 0000000..5a39eb5 --- /dev/null +++ b/plat/tcap/src/include/idmanage.h @@ -0,0 +1,16 @@ +/* ID manage head file */ +/* written by Liu Zhiguo 2002-08-06 */ +/* Version 2.0 */ +/* -------------------------------- */ + +void init_id(); +u32 chkcount_did(void); +u32 chkcount_did_occupied(void); +u32 chkcount_did_max(void); +u32 assign_did(); +void free_did(u32 did); +u8 check_did(u32 did); +u8 assign_iid(u32 did); +void free_iid(u32 did,u8 iid); +u8 check_iid(u32 did,u8 iid); +u8 store_iid(u32 did,u8 iid); diff --git a/plat/tcap/src/include/itcap.h b/plat/tcap/src/include/itcap.h new file mode 100644 index 0000000..508baf9 --- /dev/null +++ b/plat/tcap/src/include/itcap.h @@ -0,0 +1,18 @@ +/* itcap head file */ +#ifdef _ITCAP_H_ +#define _ITCAP_H_ + +#include "../../../public/src/include/public.h" +#include "tcap_public.h" +#include "tcap_struct.h" + +void tcap_disp_dlg(struct CSLdlg_struct *dha_ptr,u8 disp_flag); +void tcap_disp_cmp(struct CSLcmp_struct *cha_ptr,u8 disp_flag); + +u8 RecvTcapDlg(struct CSLdlg_struct *dha_ptr,u32 dlg_flag); +u8 RecvTcapCmp(struct CSLcmp_struct *cha_ptr,u32 dlg_flag); +u8 SendTcapDlg(struct CSLdlg_struct *dha_ptr); +u8 SendTcapCmp(struct CSLcmp_struct *cha_ptr); +int itcap_reg_ssn(u8 ssn); +void tcap_change_local_ssn(u32 proc,u8 src_ssn,u8 dst_ssn); +#endif diff --git a/plat/tcap/src/include/tcap_head.h b/plat/tcap/src/include/tcap_head.h new file mode 100644 index 0000000..a72084a --- /dev/null +++ b/plat/tcap/src/include/tcap_head.h @@ -0,0 +1,256 @@ +/* TCAP head file */ +/* Written by Liu Zhiguo 2002-08-06 */ +/* Version 2.0 */ +/* --------------------------------- */ +#ifndef _TCAP_HEAD +#define _TCAP_HEAD + +/* TC or TR dialogue portion */ +/* TC or TR message type tag */ +#define Unidirectional 0x61 +#define Begin 0x62 +#define End 0x64 +#define Continue 0x65 +#define P_Abort 0x66 // terminated by service provider +#define U_Abort 0x67 // terminated by TC user +#define Abort 0x67 +#define Notice 0x68 // Network Service Provider inform + +#define Unidirectional_Ansi 0xE1 +#define Query_WithPerm_Ansi 0xE2 +#define Query_WithoutPerm_Ansi 0xE3 +#define Response_Ansi 0xE4 +#define Conversation_WithPerm_Ansi 0xE5 +#define Conversation_WithoutPerm_Ansi 0xE6 +#define Abort_Ansi 0xF6 +#define P_Abort_Ansi 0xF5 // terminated by service provider +#define U_Abort_Ansi 0xF6 // terminated by TC user + +/* transaction ID tags */ +#define Org_TID 0x48 // originating transaction ID tag +#define Dst_TID 0x49 // destination transaction ID tag + +/* P-Abort cause tag */ +#define P_Abort_Cause 0x4a + +/* coding of P-Abort Cause values */ +#define P_Abort_UMT 0x00 // unrecognized message type +#define P_Abort_UTID 0x01 // unrecognized transaction ID +#define P_Abort_BFTP 0x02 // badly formatted transaction portion +#define P_Abort_ITP 0x03 // incorrect transaction portion +#define P_Abort_RL 0x04 // resource limitation +#define P_Abort_ADLG 0x05 // abnormal dialogue +#define P_Abort_NCDP 0x06 // no common dialogue portion + +#define P_Abort_UMT_Ansi 0x01 // unrecognized message type +#define P_Abort_ITP_Ansi 0x02 // incorrect transaction portion +#define P_Abort_BFTP_Ansi 0x03 // badly formatted transaction portion +#define P_Abort_UTID_Ansi 0x04 // unrecognized transaction ID +#define P_Abort_PTRP_Ansi 0x05 // permission to release problem +#define P_Abort_RL_Ansi 0x06 // resource limitation +#define P_Abort_UDPID_Ansi 0x07 // unrecognized dialogue portion id +#define P_Abort_BSDP_Ansi 0x08 // badly structured dialogue portion +#define P_Abort_MDP_Ansi 0x09 // missing dialogue portion +#define P_Abort_IDP_Ansi 0x0A // inconsistent dialogue portion + +/* dialogue portion tag */ +#define Dialogue_Portion 0x6b + +/* component portion tag */ +#define Component_Portion 0x6c + +/* TC Component portion */ +/* component type tag */ +#define Invoke 0xa1 +#define Result_L 0xa2 // return result last +#define Error 0xa3 // indicate operation execution failed +#define U_Error 0xa3 +#define Reject 0xa4 +#define U_Reject 0xa4 // reject by TC user +#define L_Reject 0xa5 // local reject +#define R_Reject 0xa6 // remote reject +#define Result_NL 0xa7 // return result not last +#define L_Cancel 0xa8 // inform TC user local terminated by timeout +#define U_Cancel 0xa8 // local terminate by TC user + +#define Invoke_L_Ansi 0xe9 // Invoke Last +#define Result_L_Ansi 0xea // return result last +#define Error_Ansi 0xeb // indicate operation execution failed +#define U_Error_Ansi 0xeb +#define Reject_Ansi 0xec // Reject +#define U_Reject_Ansi 0xec // reject by TC user +#define L_Reject_Ansi 0xe8 // local reject +#define R_Reject_Ansi 0xe7 // remote reject +#define Invoke_NL_Ansi 0xed // Invoke not last +#define Result_NL_Ansi 0xee // return result not last + +/* component ID tag */ +#define Invoke_ID 0x02 +#define Linked_ID 0x80 + +/* coding of NULL tag */ +#define Invoke_ID_NULL 0x05 + +/* operation code tag */ +#define Local_Operation_Code 0x02 +#define Global_Operation_Code 0x06 + +/* parameter tag */ +#define Sequence 0x30 +#define Set 0x31 + +/* error code tag */ +#define Local_Error_Code 0x02 +#define Global_Error_Code 0x06 + +/* coding of problem type tag */ +#define General_Problem 0x80 +#define Invoke_Problem 0x81 +#define Return_Result 0x82 +#define Return_Error 0x83 + +#define General_Problem_Ansi 0x01 +#define Invoke_Problem_Ansi 0x02 +#define Return_Result_Ansi 0x03 +#define Return_Error_Ansi 0x04 +#define Transaction_Ansi 0x05 + +/* coding of general problem */ +#define General_Problem_UC 0x00 // unrecognized component +#define General_Problem_MC 0x01 // mistyped component +#define General_Problem_BSC 0x02 // badly structured component + +#define General_Problem_UC_Ansi 0x01 // unrecognized component +#define General_Problem_MC_Ansi 0x02 // mistyped component/incorrect component portion +#define General_Problem_BSC_Ansi 0x03 // badly structured component +#define General_Problem_ICC_Ansi 0x04 // incorrect component coding + +/* coding of invoke problem */ +#define Invoke_Problem_DIID 0x00 // duplicate invoke ID +#define Invoke_Problem_UO 0x01 // unrecognized operation +#define Invoke_Problem_MP 0x02 // mistyped parameter +#define Invoke_Problem_RL 0x03 // resource limitation +#define Invoke_Problem_IR 0x04 // initiating release +#define Invoke_Problem_ULID 0x05 // unrecognized linked ID +#define Invoke_Problem_LRU 0x06 // linked response unexpected +#define Invoke_Problem_ULO 0x07 // unexpected linked operation + +#define Invoke_Problem_DIID_Ansi 0x01 // duplicate invoke ID +#define Invoke_Problem_UO_Ansi 0x02 // unrecognized operation +#define Invoke_Problem_MP_Ansi 0x03 // mistyped parameter +#define Invoke_Problem_ULID_Ansi 0x04 // unrecognized linked ID + +/* coding of return result problem */ +#define Return_Result_UIID 0x00 // unrecognized invoke ID +#define Return_Result_RRU 0x01 // return result unexpected +#define Return_Result_MP 0x02 // mistyped parameter + +#define Return_Result_UIID_Ansi 0x01 // unrecognized invoke ID +#define Return_Result_RRU_Ansi 0x02 // return result unexpected +#define Return_Result_MP_Ansi 0x03 // mistyped parameter + +/* coding of return error problem */ +#define Return_Error_UIID 0x00 // unrecognized invoke ID +#define Return_Error_REU 0x01 // return error unexpected +#define Return_Error_URE 0x02 // unrecognized error +#define Return_Error_UEE 0x03 // unexpected error +#define Return_Error_MP 0x04 // mistyped parameter + +#define Return_Error_UIID_Ansi 0x01 // unrecognized invoke ID +#define Return_Error_REU_Ansi 0x02 // return error unexpected +#define Return_Error_URE_Ansi 0x03 // unrecognized error +#define Return_Error_UEE_Ansi 0x04 // unexpected error +#define Return_Error_MP_Ansi 0x05 // mistyped parameter + +/* Dialogue Portion */ +/* external tag */ +#define External 0x28 + +/* object identifier */ +#define Object_Identifier 0x06 +#define Integer 0x02 + +/* dialogue tag */ +#define PDU_AARQ 0x60 +#define PDU_AARE 0x61 +#define PDU_ABRT 0x64 +/* protocol version tag */ +#define Protocol_Version 0x80 + +/* application context name tag */ +#define Application_Context_Name 0xa1 + +/* user information tag */ +#define User_Information 0xbe + +/* abort source tag */ +#define Abort_Source 0x80 + +/* result tag in Q.773 this tag is 0x82 */ +//#define Result 0xa2 + +/* result source diagnostic tag */ +#define Result_Source_Diagnostic 0xa3 + +/* encoding tag */ +#define Single_ASN1_type 0xa0 +#define Octet_Aligned 0x81 // maybe 0xa1 +#define Arbitrary 0x82 // maybe 0xa2 + +/* result value */ +#define Accepted 0x00 +#define Reject_permanent 0x01 + +/* dialogue service diagnostic tag in Q.773,value is 0x21 and 0x22 */ +#define Dialogue_Service_Provider 0x02 +#define Dialogue_Service_User 0x01 + +/* dialogue service user diagnostic tag */ +#define DSU_N 0x00 // null +#define DSU_NRG 0x01 // no reason given +#define DSU_ACNNS 0x02 // application context name not supplied + +/* dialogue service provider diagnostic tag */ +#define DSP_N 0x00 // null +#define DSP_NRG 0x01 // no reason given +#define DSP_NCDP 0x02 // no common dialogue portion + +/* abort source */ + +#define ABRTDlg_Service_User 0x00 +#define ABRTDlg_Service_Provider 0x01 + +/* unidirectional dialogue tag */ +#define PDU_AUDT 0x65 +#define PDU_ASUDT 0x66 + +#define REQUEST 1 +#define INDICATE 2 +#define RESPONSE 3 +#define CONFIRM 4 + +#define PRE_END 1 // pre arranged end +#define BASIC_END 2 // basic end + +#define DERR_ASN1 0x01 // decode error: asn1 decode error +#define DERR_UNTYPE 0x02 // decode error: unknown message type +#define DERR_UNTID 0x03 // decode error: lack transaction id +#define DERR_OTHER 0x04 // decode error: other reason + +#define UABORT_NULL 0x00 // uabort reason:no +#define UABORT_SPEC 0x01 // uabort reason:specific reason +#define UABORT_ACNNS 0x02 // uabort reason:application context name not supplied + +#define ANSI_TAG_CLASS_CONS 0xE0 +#define ANSI_TAG_CLASS_PRIM 0xC0 + +#define ITU_TCAP 0 +#define ANSI_TCAP 1 + +#define TYPE_NATIONAL 0 +#define TYPE_PRIVATE 1 + +#define TYPE_INT 0 +#define TYPE_OID 1 + +#endif diff --git a/plat/tcap/src/include/tcap_m.h b/plat/tcap/src/include/tcap_m.h new file mode 100644 index 0000000..c44c577 --- /dev/null +++ b/plat/tcap/src/include/tcap_m.h @@ -0,0 +1,21 @@ +/* TCAP monitor head file */ +/* written by Liu Zhiguo 2001-10-19 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#include "../../../public/src/include/pub_include.h" + +#ifndef _TCAP_M +#define _TCAP_M + +/* in the m.c */ +void init_m(); +void tcap_set_local_ip(); +void tcap_monitor(); +void tcap_send_ascout(char *asc_str); +void tcap_send_error(char *err_str); +void tcap_send_alarm(u8 alarm_code,u8 alarm_level); +void HexToDisplay(u8 *to_asc, u8 *from_hex, u8 from_len); +void tcap_send_info(char *info); + +#endif diff --git a/plat/tcap/src/include/tcap_proc.h b/plat/tcap/src/include/tcap_proc.h new file mode 100644 index 0000000..10db693 --- /dev/null +++ b/plat/tcap/src/include/tcap_proc.h @@ -0,0 +1,3 @@ +void tcap_fsm(void); // TCAP state machine, 10ms +void tcap_init(int didgrant,u_long localip, u_long peerip); // init TCAP system + diff --git a/plat/tcap/src/include/tcap_public.h b/plat/tcap/src/include/tcap_public.h new file mode 100644 index 0000000..3418193 --- /dev/null +++ b/plat/tcap/src/include/tcap_public.h @@ -0,0 +1,68 @@ +/* TCAP public define head file */ +/* written by Liu Zhiguo 2002-08-06 */ +/* Version 2.0 */ +/* ------------------------------- */ + +#ifndef _TCAP_PUBLIC +#define _TCAP_PUBLIC + +#include "../../../public/src/include/includes.h" +#include "tcap_head.h" + +#define MAX_DIALOGUEID 4096 +#define MAX_INVOKEID 256 +#define TCAP_ASCIN_LEN 80 +#define TCAP_ASCOUT_LEN 4096 +#define TCAP_UTILIZE_COUNT 97 +#define TCAP_UTILIZE_LEN 76 +#define TCAP_HB_LEN 8 +#define TCAP_DLG_LEN 128 // max dialogue length +#define TCAP_CMP_LEN 256 // max component length +#define TCAP_ACN_LEN 10 // max context name length +#define TCAP_USERINFO_LEN 64 // max user infomation length +#define TCAP_UABORT_INFO_LEN 64 // max user abort infomation length +#define TCAP_SECURITY_CONTEXT_LEN 64 // max security context infomation length +#define TCAP_CONFIDENTIAL_INFO_LEN 64 // max confidentiality infomation length +#define MAX_TEMPINVOKEID 8 +#define TCAP_BUF_LEN 256 +#define TCAP_SLS_NUM 16 +//#define TCAP_PARAM_LEN 170 // max parameter length when has dialogue portion +#define TCAP_PARAM_LEN 210 // max parameter length when has dialogue portion +#define TCAP_PARAM_LEN_1 210 // max parameter length when has not dialogue portion + +#define MAX_TSL_BUF 4 +#define MAX_CSL_BUF 8 + +#define TCAP_MODULE_ID 3 +#define TCAP_SYSTEM_ID 4 +#define TCAP_LED_CODE 5 + +/* the state of TSM or DSM */ +#define TCAP_INIT 0 +#define TCAP_IDLE 1 +#define TCAP_IR 2 // initiation received +#define TCAP_IS 3 // initiation send +#define TCAP_ACTIVE 4 // active state +#define TCAP_SUSPEND 7 // suspend state +/* the state of ISM */ +#define SENT_STATE1 2 +#define SENT_STATE2 3 +#define SENT_STATE3 4 +#define SENT_STATE4 5 +#define WAIT_REJECT_STATE 6 + +/* the class of ISM */ +#define OPERATION_CLASS1 1 // operation class 1 +#define OPERATION_CLASS2 2 // operation class 2 +#define OPERATION_CLASS3 3 // operation class 3 +#define OPERATION_CLASS4 4 // operation class 4 + +#define INVOKE_TIMER 10 +#define REJECT_TIMER 2 +#define SUSPEND_TIMER 2 +#define IDLE_TIMER 60 +#define EXPIRE_TIMER 240 +#define TCAP_TIMERHZ 50 +#define ISM_TIMERHZ 50 + +#endif diff --git a/plat/tcap/src/include/tcap_struct.h b/plat/tcap/src/include/tcap_struct.h new file mode 100644 index 0000000..da30b2a --- /dev/null +++ b/plat/tcap/src/include/tcap_struct.h @@ -0,0 +1,396 @@ +/* TCAP structure head file */ +/* written by Liu Zhiguo 2002-08-06 */ +/* Version 2.0 */ +/* ------------------------------- */ + +#ifndef _TCAP_STRUCT +#define _TCAP_STRUCT + +#define TCAP_KEY 0xa0100000 +#define TCAP_PERM 0664 + +typedef struct tcapdebug_struct // tcap debug structure +{ + u8 default_invtime; // default invoke time, init is 10s + u8 default_rejtime; // default reject time, init is 1s + u8 error_switch; // show error record switch + u8 sccp_switch; // show receive data from sccp switch + u8 tcu_switch; // show send data to TC-User switch + u8 send_control; // control if can send out tcap message + u8 start_time[6]; + u8 current_time[6]; + u32 monitor_did; + u32 local_ip; + u32 peer_ip; + u8 watch_dog[256]; + u8 ascin_buf[TCAP_ASCIN_LEN]; + u8 ascout_buf[TCAP_ASCOUT_LEN]; + u8 current_csta; + u32 csta_time[TCAP_UTILIZE_COUNT]; + u32 tc_utilize[TCAP_UTILIZE_COUNT][TCAP_UTILIZE_LEN]; + u8 hb_status[TCAP_HB_LEN]; +} tcapdebug_struct; + +/* +++++++++++++++++++++++++++++++ */ +/* Transaction sub-layer structure */ +/* +++++++++++++++++++++++++++++++ */ +typedef struct TRUni_struct // transaction unidirectional struct +{ + u8 dialogue_len; + u8 components_len; + u8 dialogue[TCAP_DLG_LEN]; + u8 components[TCAP_CMP_LEN]; +} TRUni_struct; + +typedef struct TRBegin_struct // transaction begin struct +{ + u8 tid_flag; + u32 transaction_id; + u8 dialogue_len; + u8 components_len; + u8 dialogue[TCAP_DLG_LEN]; + u8 components[TCAP_CMP_LEN]; +} TRBegin_struct; + +typedef struct TRContinue_struct // transaction continue struct +{ + u8 ltid_flag; + u8 ptid_flag; + u32 local_tid; + u32 peer_tid; + u8 dialogue_len; + u8 components_len; + u8 dialogue[TCAP_DLG_LEN]; + u8 components[TCAP_CMP_LEN]; +} TRContinue_struct; + +typedef struct TREnd_struct // transaction end struct +{ + u8 tid_flag; + u32 transaction_id; + u8 termination; + u8 dialogue_len; + u8 components_len; + u8 dialogue[TCAP_DLG_LEN]; + u8 components[TCAP_CMP_LEN]; +} TREnd_struct; + +typedef struct TRUAbort_struct // transaction u-abort struct +{ + u8 tid_flag; + u32 transaction_id; + u8 dialogue_len; + u8 dialogue[TCAP_DLG_LEN]; + u8 uabort_info_len; + u8 uabort_info[TCAP_UABORT_INFO_LEN]; +} TRUAbort_struct; + +typedef struct TRPAbort_struct // transaction p-abort struct +{ + u8 tid_flag; + u32 transaction_id; + u8 abort_reason; +} TRPAbort_struct; + +typedef struct TRNotice_struct // transcation notice struct +{ + u8 tid_flag; + u32 transaction_id; + u8 report_cause; +} TRNotice_struct; + +typedef struct TSL_struct +{ + u8 message_type; + u8 message_flag; + u8 peer_tid_len; /* added by Pierre, 2006-08-19 */ + struct SCCP_ADDRESS local_add; + struct SCCP_ADDRESS peer_add; + union + { + struct TRUni_struct tr_uni; + struct TRBegin_struct tr_begin; + struct TRContinue_struct tr_continue; + struct TREnd_struct tr_end; + struct TRUAbort_struct tr_uabort; + struct TRPAbort_struct tr_pabort; + struct TRNotice_struct tr_notice; + } tsl_prim; +} TSL_struct; + +/* +++++++++++++++++++++++++++++++ */ +/* Component sub-layer structure */ +/* +++++++++++++++++++++++++++++++ */ + +/* define dialogue handing primitive structure */ +typedef struct AARQ_struct +{ + u8 version[2]; + u8 acn_len; + u8 acn[TCAP_ACN_LEN]; + u8 user_info_len; + u8 user_info[TCAP_USERINFO_LEN]; +} AARQ_struct; + +typedef struct AARE_struct +{ + u8 version[2]; + u8 acn_len; + u8 acn[TCAP_ACN_LEN]; + u8 result; + u8 diagnostic_flag; // user or provider + u8 diagnostic_type; // reason + u8 user_info_len; + u8 user_info[TCAP_USERINFO_LEN]; +} AARE_struct; + +typedef struct ABRT_struct +{ + u8 abort_source; + u8 user_info_len; + u8 user_info[TCAP_USERINFO_LEN]; +} ABRT_struct; + +typedef struct ASUDT_struct +{ + u8 version; + u8 acn_type; + u8 acn_len; + u8 acn[TCAP_ACN_LEN]; + u8 user_info_len; + u8 user_info[TCAP_USERINFO_LEN]; + u8 security_context_type; + u8 security_context_len; + u8 security_context[TCAP_SECURITY_CONTEXT_LEN]; + u8 confidential_info_len; + u8 confidential_info[TCAP_CONFIDENTIAL_INFO_LEN]; +} ASUDT_struct; + +typedef struct dlgPDU_struct +{ + u8 dialogue_type; + union + { + struct AARQ_struct aarq; + struct AARE_struct aare; + struct ABRT_struct abrt; + struct ASUDT_struct asudt; + } pdu_union; +} dlgPDU_struct; + +typedef struct dlgport_struct // dialogue portion in the TC +{ + u8 acn_type; + u8 acn_len; + u8 acn[TCAP_ACN_LEN]; + u8 user_info_len; + u8 user_info[TCAP_USERINFO_LEN]; + u8 security_context_type; + u8 security_context_len; + u8 security_context[TCAP_SECURITY_CONTEXT_LEN]; + u8 confidential_info_len; + u8 confidential_info[TCAP_CONFIDENTIAL_INFO_LEN]; +} dlgport_struct; + +typedef struct TCUni_struct // component unidirectional struct +{ + struct SCCP_ADDRESS local_add; + struct SCCP_ADDRESS peer_add; + u8 dialogue_flag; + struct dlgport_struct dlg_data; + u8 component_present; +} TCUni_struct; + +typedef struct TCBegin_struct +{ + struct SCCP_ADDRESS local_add; + struct SCCP_ADDRESS peer_add; + u8 dialogue_flag; + struct dlgport_struct dlg_data; + u8 component_present; +} TCBegin_struct; + +typedef struct TCContinue_struct +{ + u8 dialogue_flag; + struct dlgport_struct dlg_data; + u8 component_present; +} TCContinue_struct; + +typedef struct TCEnd_struct +{ + u8 dialogue_flag; + struct dlgport_struct dlg_data; + u8 component_present; + u8 termination; +} TCEnd_struct; + +typedef struct TCUAbort_struct +{ + u8 uabort_reason; + u8 dialogue_flag; + struct dlgport_struct dlg_data; + u8 uabort_info_len; + u8 uabort_info[TCAP_UABORT_INFO_LEN]; +} TCUAbort_struct; + +typedef struct TCPAbort_struct +{ + u8 pabort_reason; +} TCPAbort_struct; + +typedef struct TCNotice_struct +{ + u8 report_reason; +} TCNotice_struct; + +typedef struct CSLdlg_struct // dialogue primitive in CSL +{ + u32 dialogue_id; + u8 message_type; + u8 message_flag; + union + { + struct TCUni_struct tc_uni; + struct TCBegin_struct tc_begin; + struct TCContinue_struct tc_continue; + struct TCEnd_struct tc_end; + struct TCUAbort_struct tc_uabort; + struct TCPAbort_struct tc_pabort; + struct TCNotice_struct tc_notice; + } dlg_prim; +} CSLdlg_struct; + +/* define component handing primitive structure */ +typedef struct TCInvoke_struct +{ + u8 linkedid_flag; + u8 linked_id; + u8 operation_domain; + u8 operation_family; + u8 operation_code; + u8 parameter_len; + u8 parameter[TCAP_CMP_LEN]; + u8 operation_class; + u32 timer; +} TCInvoke_struct; + +typedef struct TCResult_struct +{ + u8 operation_flag; // the flag indicate if has operation code + u8 operation_domain; + u8 operation_family; + u8 operation_code; + u8 parameter_len; + u8 parameter[TCAP_CMP_LEN]; +} TCResult_struct; + +typedef struct TCUError_struct +{ + u8 error_type; // error tag + u8 error_code; // error code + u8 parameter_len; + u8 parameter[TCAP_CMP_LEN]; +} TCUError_struct; + +typedef struct TCReject_struct +{ + u8 problem_type; + u8 problem_code; + u8 parameter_len; + u8 parameter[TCAP_CMP_LEN]; +} TCReject_struct; + +typedef struct CSLcmp_struct +{ + u32 dialogue_id; // dialogue id + u8 invoke_id; // invoke id + u8 message_type; + u8 message_flag; + u8 last_flag; + union + { + struct TCInvoke_struct tc_invoke; + struct TCResult_struct tc_result; + struct TCUError_struct tc_uerror; + struct TCReject_struct tc_reject; + } cmp_prim; +} CSLcmp_struct; + +/* +++++++++++++++++++++++++++++++ */ +/* TCAP virtue machine structure */ +/* +++++++++++++++++++++++++++++++ */ +typedef struct ismvm_data +{ + u8 used_flag; + u8 linked_iid; + u8 ism_state; + u8 ism_msgtype; + u8 ism_msgflag; + u8 ism_msgclass; + u8 ism_oper_domain; + u8 ism_oper_family; + u8 ism_oper_code; + u32 ism_timer; +} ismvm_data; + +typedef struct tcapvm_struct +{ + struct SCCP_ADDRESS local_add; + struct SCCP_ADDRESS peer_add; + u8 peer_tid_len; + u32 peer_tid; + u8 send_flag; + u8 src_sls; + u32 tcap_timer; + u8 tcap_state; + u8 ac_mode; + u8 proto_type; + u8 tcaprecv_head; + u8 tcaprecv_tail; + u8 sccp_class; + struct ismvm_data ism_data[MAX_TEMPINVOKEID]; + struct TSL_struct tsl_data[MAX_TSL_BUF]; +} tcapvm_struct; + +typedef struct tcapint_struct // tcap interface structure +{ + u8 dlgrecv_head; + u8 dlgrecv_tail; + u8 dlgsend_head; + u8 dlgsend_tail; + struct CSLdlg_struct dlg_recv[MAX_TSL_BUF]; + struct CSLdlg_struct dlg_send[MAX_TSL_BUF]; + u8 cmprecv_head; + u8 cmprecv_tail; + u8 cmpsend_head; + u8 cmpsend_tail; + struct CSLcmp_struct cmp_recv[MAX_CSL_BUF]; + struct CSLcmp_struct cmp_send[MAX_CSL_BUF]; +} tcapint_struct; + +typedef struct tcapbuf_struct // TCAP buffer structure +{ + int grantdid; + struct tcapvm_struct tcapvm_data[MAX_DIALOGUEID]; + struct tcapint_struct tcapint_data[MAX_DIALOGUEID]; + struct tcapdebug_struct tcap_debug; +} tcapbuf_struct; + +// fix multiple definition==================================== +extern struct tcapbuf_struct *tcap_ptr; +// + +u8 tsl_message_decode(struct SCLC_MSG *sccp_ptr,struct TSL_struct *dst_ptr,u8 *err_code);// tsl decode +u8 tsl_message_encode(struct SCLC_MSG *sccp_ptr,struct TSL_struct *tsl_ptr,u8 flag);// tsl encode +u8 extract_dp(struct dlgPDU_struct *pdu_ptr,u8 *databuf,int datalen,u8 proto_type); // extract dialogue portion +u8 build_dp(u8 *content,struct dlgPDU_struct *dlg_ptr,u8 un_flag,u8 proto_type); // build dialogue portion +int extract_component(struct CSLcmp_struct *cmp_ptr,u8 *data_buf,u32 proc,int *section_len); // extract component portion +int assemble_component(u8 *string,struct CSLcmp_struct *cha_ptr); // assemble component portion +void tcapvm_init(); // init share memory +u8 write_ism(CSLcmp_struct *cmp_ptr); +void tco_program(void); // transaction coordinator +void tsm_program(u32 proc); +void ism_program(u32 proc); // invocation state machine + +#endif diff --git a/plat/tcap/src/itcap.c b/plat/tcap/src/itcap.c new file mode 100644 index 0000000..5c33ae2 --- /dev/null +++ b/plat/tcap/src/itcap.c @@ -0,0 +1,759 @@ +/* interface c file */ +/* written by Liu zhiguo 2002-08-16 */ +/* version 2.0 */ +/* ----------------------------- */ +#include "../../sccp/src/include/sccp.h" +#include "./include/tcap_public.h" +#include "./include/tcap_struct.h" +#include "./include/idmanage.h" +#include "./include/tcap_m.h" + +/*@ignore@*/ +static u8 t10ms_flag; +static u32 tcap_proc; + +u32 tcap_dlg_h[MAX_DIALOGUEID]; +u32 tcap_dlg_t[MAX_DIALOGUEID]; +u32 tcap_dlg_stats[MAX_DIALOGUEID]; + +typedef struct id_struct +{ + u32 current_did; + u32 count_did; + u32 count_did_occupied; + u32 count_did_max; + u32 count_did_tmp; + u8 dialogue_id[MAX_DIALOGUEID]; + u8 current_iid[MAX_DIALOGUEID]; + u8 invoke_id[MAX_DIALOGUEID][MAX_INVOKEID]; +}id_struct; + +extern struct id_struct *ID_ptr; +extern u8 xapp_check_did ( u32 did ); +extern int register_ssn ( BYTE ssn, BYTE usertype ); +void tcap_disp_dlg(struct CSLdlg_struct *dha_ptr,u8 disp_flag) +{ + char temp_buf[1024],temp_data[1024]; + char info_str[1024]; + char *cur_time; + struct TCUni_struct *uni_ptr; + struct TCBegin_struct *begin_ptr; + struct TCContinue_struct *con_ptr; + struct TCEnd_struct *end_ptr; + struct TCUAbort_struct *uabrt_ptr; + struct TCPAbort_struct *pabrt_ptr; + u8 proto_type; + + if (tcap_ptr->tcap_debug.send_control == 1) + return; + if (tcap_ptr->tcap_debug.tcu_switch == 0 && dha_ptr->dialogue_id != tcap_ptr->tcap_debug.monitor_did) + return; + if (disp_flag == 1) // send data to tc-user + strcpy(info_str,"Dialogue tcap->tc user, time: "); + else + strcpy(info_str,"Dialogue tc user->tcap, time: "); + cur_time = GetAsciiTime(); + strcat(info_str,cur_time); + strcat(info_str,"\rType: "); + if (dha_ptr->message_flag == REQUEST) + sprintf(temp_buf,"\tFlag: Request\tDialogue id: %u\r\n",dha_ptr->dialogue_id); + else + sprintf(temp_buf,"\tFlag: Indicate\tDialogue id: %u\r\n",dha_ptr->dialogue_id); + if ((dha_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + switch (dha_ptr->message_type) + { + case Unidirectional: + case Unidirectional_Ansi: + if (dha_ptr->message_type == Unidirectional) + strcat(info_str,"Unidirectional"); + else + strcat(info_str,"Unidirectional_Ansi"); + strcat(info_str,temp_buf); + uni_ptr = (TCUni_struct *) &dha_ptr->dlg_prim.tc_uni; + if (uni_ptr->dialogue_flag == 1) + { + if (uni_ptr->dlg_data.acn_len > 0) + { + HexToDisplay((u8 *)temp_buf,uni_ptr->dlg_data.acn,uni_ptr->dlg_data.acn_len); + sprintf(temp_data,"ACN is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (uni_ptr->dlg_data.user_info_len > 0) + { + HexToDisplay((u8 *)temp_buf,uni_ptr->dlg_data.user_info,uni_ptr->dlg_data.user_info_len); + sprintf(temp_data,"User info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (proto_type) + { + if (uni_ptr->dlg_data.security_context_len > 0) + { + HexToDisplay((u8 *)temp_buf,uni_ptr->dlg_data.security_context,uni_ptr->dlg_data.security_context_len); + sprintf(temp_data,"Security context is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (uni_ptr->dlg_data.confidential_info_len > 0) + { + HexToDisplay((u8 *)temp_buf,uni_ptr->dlg_data.confidential_info,uni_ptr->dlg_data.confidential_info_len); + sprintf(temp_data,"Confidential info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + } + } + if (uni_ptr->component_present != 0) + strcat(info_str,"Has component\r\n"); + strcat(info_str,"\r\n"); + break; + case Begin: + case Query_WithPerm_Ansi: + case Query_WithoutPerm_Ansi: + if (dha_ptr->message_type == Begin) + strcat(info_str,"Begin"); + else if (dha_ptr->message_type == Query_WithPerm_Ansi) + strcat(info_str,"Query_WithPerm_Ansi"); + else + strcat(info_str,"Query_WithoutPerm_Ansi"); + strcat(info_str,temp_buf); + begin_ptr = (TCBegin_struct *) &dha_ptr->dlg_prim.tc_begin; + if (begin_ptr->dialogue_flag == 1) + { + if (begin_ptr->dlg_data.acn_len > 0) + { + HexToDisplay((u8 *)temp_buf,begin_ptr->dlg_data.acn,begin_ptr->dlg_data.acn_len); + sprintf(temp_data,"ACN is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (begin_ptr->dlg_data.user_info_len != 0) + { + HexToDisplay((u8 *)temp_buf,begin_ptr->dlg_data.user_info,begin_ptr->dlg_data.user_info_len); + sprintf(temp_data,"User info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (proto_type) + { + if (begin_ptr->dlg_data.security_context_len > 0) + { + HexToDisplay((u8 *)temp_buf,begin_ptr->dlg_data.security_context,begin_ptr->dlg_data.security_context_len); + sprintf(temp_data,"Security context is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (begin_ptr->dlg_data.confidential_info_len > 0) + { + HexToDisplay((u8 *)temp_buf,begin_ptr->dlg_data.confidential_info,begin_ptr->dlg_data.confidential_info_len); + sprintf(temp_data,"Confidential info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + } + } + if (begin_ptr->component_present != 0) + strcat(info_str,"Has component\r\n"); + strcat(info_str,"\r\n"); + break; + case Continue: + case Conversation_WithPerm_Ansi: + case Conversation_WithoutPerm_Ansi: + if (dha_ptr->message_type == Continue) + strcat(info_str,"Continue"); + else if (dha_ptr->message_type == Conversation_WithPerm_Ansi) + strcat(info_str,"Conversation_WithPerm_Ansi"); + else + strcat(info_str,"Conversation_WithoutPerm_Ansi"); + strcat(info_str,temp_buf); + con_ptr = (TCContinue_struct *) &dha_ptr->dlg_prim.tc_continue; + if (con_ptr->dialogue_flag == 1) + { + if (con_ptr->dlg_data.acn_len > 0) + { + HexToDisplay((u8 *)temp_buf,con_ptr->dlg_data.acn,con_ptr->dlg_data.acn_len); + sprintf(temp_data,"ACN is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (con_ptr->dlg_data.user_info_len != 0) + { + HexToDisplay((u8 *)temp_buf,con_ptr->dlg_data.user_info,con_ptr->dlg_data.user_info_len); + sprintf(temp_data,"User info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (proto_type) + { + if (con_ptr->dlg_data.security_context_len > 0) + { + HexToDisplay((u8 *)temp_buf,con_ptr->dlg_data.security_context,con_ptr->dlg_data.security_context_len); + sprintf(temp_data,"Security context is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (con_ptr->dlg_data.confidential_info_len > 0) + { + HexToDisplay((u8 *)temp_buf,con_ptr->dlg_data.confidential_info,con_ptr->dlg_data.confidential_info_len); + sprintf(temp_data,"Confidential info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + } + } + if (con_ptr->component_present != 0) + strcat(info_str,"Has component\r\n"); + strcat(info_str,"\r\n"); + break; + case End: + case Response_Ansi: + if (dha_ptr->message_type == End) + strcat(info_str,"End"); + else + strcat(info_str,"Response"); + strcat(info_str,temp_buf); + end_ptr = (TCEnd_struct *) &dha_ptr->dlg_prim.tc_end; + if (end_ptr->dialogue_flag == 1) + { + if (end_ptr->dlg_data.acn_len > 0) + { + HexToDisplay((u8 *)temp_buf,end_ptr->dlg_data.acn,end_ptr->dlg_data.acn_len); + sprintf(temp_data,"ACN is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (proto_type) + { + if (end_ptr->dlg_data.user_info_len != 0) + { + HexToDisplay((u8 *)temp_buf,end_ptr->dlg_data.user_info,end_ptr->dlg_data.user_info_len); + sprintf(temp_data,"User info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (end_ptr->dlg_data.security_context_len > 0) + { + HexToDisplay((u8 *)temp_buf,end_ptr->dlg_data.security_context,end_ptr->dlg_data.security_context_len); + sprintf(temp_data,"Security context is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (end_ptr->dlg_data.confidential_info_len > 0) + { + HexToDisplay((u8 *)temp_buf,end_ptr->dlg_data.confidential_info,end_ptr->dlg_data.confidential_info_len); + sprintf(temp_data,"Confidential info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + } + } + if (end_ptr->component_present != 0) + strcat(info_str,"Has component\r\n"); + strcat(info_str,"\r\n"); + break; + case U_Abort: + case U_Abort_Ansi: + if (dha_ptr->message_type == U_Abort) + strcat(info_str,"U_Abort"); + else + strcat(info_str,"U_Abort_Ansi"); + strcat(info_str,temp_buf); + uabrt_ptr = (TCUAbort_struct *) &dha_ptr->dlg_prim.tc_uabort; + if (uabrt_ptr->dialogue_flag == 1) + { + if (uabrt_ptr->dlg_data.acn_len != 0) + { + HexToDisplay((u8 *)temp_buf,uabrt_ptr->dlg_data.acn,uabrt_ptr->dlg_data.acn_len); + sprintf(temp_data,"ACN is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (proto_type) + { + if (uabrt_ptr->dlg_data.user_info_len != 0) + { + HexToDisplay((u8 *)temp_buf,uabrt_ptr->dlg_data.user_info,uabrt_ptr->dlg_data.user_info_len); + sprintf(temp_data,"User info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (uabrt_ptr->dlg_data.security_context_len > 0) + { + HexToDisplay((u8 *)temp_buf,uabrt_ptr->dlg_data.security_context,uabrt_ptr->dlg_data.security_context_len); + sprintf(temp_data,"Security context is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + if (uabrt_ptr->dlg_data.confidential_info_len > 0) + { + HexToDisplay((u8 *)temp_buf,uabrt_ptr->dlg_data.confidential_info,uabrt_ptr->dlg_data.confidential_info_len); + sprintf(temp_data,"Confidential info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + } + } + if (!proto_type) + { + sprintf(temp_buf,"User abort reason: %d\r\n",uabrt_ptr->uabort_reason); + strcat(info_str,temp_buf); + } + else + { + if (uabrt_ptr->uabort_info_len != 0) + { + HexToDisplay((u8 *)temp_buf,uabrt_ptr->uabort_info,uabrt_ptr->uabort_info_len); + sprintf(temp_data,"User abort info is: %s\r\n",temp_buf); + strcat(info_str,temp_data); + } + } + strcat(info_str, "\r\n"); + break; + case P_Abort: + case P_Abort_Ansi: + if (dha_ptr->message_type == P_Abort) + strcat(info_str,"P_Abort"); + else + strcat(info_str,"P_Abort_Ansi"); + strcat(info_str,temp_buf); + pabrt_ptr = (TCPAbort_struct *) &dha_ptr->dlg_prim.tc_pabort; + sprintf(temp_buf,"Provider abort reason: %d\r\n",pabrt_ptr->pabort_reason); + strcat(info_str,temp_buf); + strcat(info_str, "\r\n"); + break; + default: + break; + } + tcap_send_ascout(info_str); +} + +void tcap_disp_cmp(struct CSLcmp_struct *cha_ptr,u8 disp_flag) +{ + int ii=0; + char temp_buf[1024]; + char info_str[1024]; + char *cur_time; + u8 proto_type; + struct TCInvoke_struct *invoke_ptr; + struct TCResult_struct *result_ptr; + struct TCUError_struct *uerror_ptr; + struct TCReject_struct *reject_ptr; + + if (tcap_ptr->tcap_debug.send_control == 1) + return; + if (tcap_ptr->tcap_debug.tcu_switch == 0 && cha_ptr->dialogue_id != tcap_ptr->tcap_debug.monitor_did) + return; + if (disp_flag == 1) // send data to tc-user + strcpy(info_str,"Component tcap->tc user, time: "); + else + strcpy(info_str,"Component tc user->tcap, time: "); + cur_time = GetAsciiTime(); + strcat(info_str,cur_time); + strcat(info_str,"\rType: "); + if (cha_ptr->message_flag == REQUEST) + sprintf(temp_buf,"\tFlag: Request\tDialogue id: %u, Invoke id: %d\r\n",cha_ptr->dialogue_id,cha_ptr->invoke_id); + else + sprintf(temp_buf,"\tFlag: Indicate\tDialogue id: %u, Invoke id: %d\r\n",cha_ptr->dialogue_id,cha_ptr->invoke_id); + if ((cha_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + switch (cha_ptr->message_type) + { + case Invoke: + case Invoke_L_Ansi: + case Invoke_NL_Ansi: + if (cha_ptr->message_type == Invoke) + strcat(info_str,"Invoke"); + else if (cha_ptr->message_type == Invoke_L_Ansi) + strcat(info_str,"Invoke_L_Ansi"); + else + strcat(info_str,"Invoke_NL_Ansi"); + strcat(info_str,temp_buf); + invoke_ptr = (TCInvoke_struct *) &cha_ptr->cmp_prim.tc_invoke; + ii = invoke_ptr->parameter_len; + if (cha_ptr->message_type == Invoke) + sprintf(temp_buf,"Operation code: %d\tParameter len: %d\r\n",invoke_ptr->operation_code,ii); + else + sprintf(temp_buf,"Operation family: %d\tOperation code: %d\tParameter len: %d\r\n",invoke_ptr->operation_family,invoke_ptr->operation_code,ii); + strcat(info_str,temp_buf); + if (ii != 0) + { + strcat(info_str,"Parameter: "); + HexToDisplay((u8 *)temp_buf,invoke_ptr->parameter,ii); + strcat(info_str,temp_buf); + strcat(info_str,"\r\n"); + } + strcat(info_str, "\r\n"); + break; + case Result_L: + case Result_NL: + case Result_L_Ansi: + case Result_NL_Ansi: + if (cha_ptr->message_type == Result_L) + strcat(info_str,"Result_L"); + else if (cha_ptr->message_type == Result_NL) + strcat(info_str,"Result_NL"); + else if (cha_ptr->message_type == Result_L_Ansi) + strcat(info_str,"Result_L_Ansi"); + else + strcat(info_str,"Result_NL_Ansi"); + strcat(info_str,temp_buf); + result_ptr = (TCResult_struct *) &cha_ptr->cmp_prim.tc_result; + ii = result_ptr->parameter_len; + if (ii != 0) + { + if ((cha_ptr->message_type == Result_L_Ansi) || + (cha_ptr->message_type == Result_NL_Ansi)) + sprintf(temp_buf,"Operation family: %d\tOperation code: %d\tParameter len: %d\r\n",result_ptr->operation_family,result_ptr->operation_code,ii); + else + sprintf(temp_buf,"Operation code: %d\tParameter len: %d\r\n",result_ptr->operation_code,ii); + strcat(info_str,temp_buf); + strcat(info_str,"Parameter: "); + HexToDisplay((u8 *)temp_buf,result_ptr->parameter,ii); + strcat(info_str,temp_buf); + strcat(info_str,"\r\n"); + } + strcat(info_str, "\r\n"); + break; + case U_Error: + case U_Error_Ansi: + if (cha_ptr->message_type == U_Error) + strcat(info_str,"U_Error"); + else + strcat(info_str,"U_Error_Ansi"); + strcat(info_str,temp_buf); + uerror_ptr = (TCUError_struct *) &cha_ptr->cmp_prim.tc_uerror; + ii = uerror_ptr->parameter_len; + sprintf(temp_buf,"Error code: %d\tParameter len: %d\r\n",uerror_ptr->error_code,ii); + strcat(info_str,temp_buf); + if (ii != 0) + { + strcat(info_str,"Parameter: "); + HexToDisplay((u8 *)temp_buf,uerror_ptr->parameter,ii); + strcat(info_str,temp_buf); + strcat(info_str,"\r\n"); + } + strcat(info_str, "\r\n"); + break; + case U_Reject: + case L_Reject: + case R_Reject: + case U_Reject_Ansi: + case L_Reject_Ansi: + case R_Reject_Ansi: + switch (cha_ptr->message_type) + { + case U_Reject: + strcat(info_str,"U_Reject"); + break; + case L_Reject: + strcat(info_str,"L_Reject"); + break; + case R_Reject: + strcat(info_str,"R_Reject"); + break; + case U_Reject_Ansi: + strcat(info_str,"U_Reject_Ansi"); + break; + case L_Reject_Ansi: + strcat(info_str,"L_Reject_Ansi"); + break; + case R_Reject_Ansi: + strcat(info_str,"R_Reject_Ansi"); + break; + } + strcat(info_str,temp_buf); + reject_ptr = (TCReject_struct *) &cha_ptr->cmp_prim.tc_reject; + sprintf(temp_buf,"Problem type: %d\tProblem code: %d",reject_ptr->problem_type,reject_ptr->problem_code); + strcat(info_str,temp_buf); + if (proto_type) + { + ii = reject_ptr->parameter_len; + if (ii != 0) + { + sprintf(temp_buf,"\tParameter len: %d\r\n",ii); + strcat(info_str,temp_buf); + strcat(info_str,"Parameter: "); + HexToDisplay((u8 *)temp_buf,reject_ptr->parameter,ii); + strcat(info_str,temp_buf); + } + } + strcat(info_str,"\r\n\r\n"); + break; + default: + if (cha_ptr->message_type == L_Cancel) + strcat(info_str,"Local cancel"); + else if (cha_ptr->message_type == U_Cancel) + strcat(info_str,"User cancel"); + strcat(info_str,temp_buf); + strcat(info_str,"\r\n"); + break; + } + tcap_send_ascout(info_str); +} + +u8 RecvTcapDlg(struct CSLdlg_struct *dha_ptr,u32 dlg_flag) // receive the dialogue portion +{ + struct tcapint_struct *int_ptr; + u8 ii; + + if (dlg_flag >= (tcap_ptr->grantdid)) + return 0; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[dlg_flag]; + ii = int_ptr->dlgrecv_tail; + if (ii == int_ptr->dlgrecv_head) + return 0; + memcpy(dha_ptr,&int_ptr->dlg_recv[ii],sizeof(CSLdlg_struct)); + int_ptr->dlgrecv_tail = (ii + 1) % MAX_TSL_BUF; + tcap_disp_dlg(dha_ptr,1); + return 1; +} + +u8 RecvTcapCmp(struct CSLcmp_struct *cha_ptr,u32 dlg_flag) // receive the component portion +{ + struct tcapint_struct *int_ptr; + u8 ii; + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + + if (dlg_flag >= (tcap_ptr->grantdid)) + { + debug_ptr->watch_dog[247]++; + return 0; + } + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[dlg_flag]; + ii = int_ptr->cmprecv_tail; + if (ii == int_ptr->cmprecv_head) + return 0; + memcpy(cha_ptr,&int_ptr->cmp_recv[ii],sizeof(CSLcmp_struct)); + int_ptr->cmprecv_tail = (ii + 1) % MAX_CSL_BUF; + tcap_disp_cmp(cha_ptr,1); + debug_ptr->watch_dog[246]++; + return 1; +} + +u8 SendTcapDlg(struct CSLdlg_struct *dha_ptr) // send the dialogue portion +{ + struct tcapint_struct *int_ptr; + u32 dlg_flag; + u8 ii; + char info_str[1024]; + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + + dlg_flag = dha_ptr->dialogue_id; + if (dlg_flag >= (tcap_ptr->grantdid)) + { + debug_ptr->watch_dog[194]++; + return 0; + } + + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[dlg_flag]; + ii = int_ptr->dlgsend_head; + + if (tcap_dlg_h[dlg_flag] != int_ptr->dlgsend_head) + { + debug_ptr->watch_dog[192] ++; + //printf("h: %d-%d\n", tcap_dlg_h[dlg_flag], int_ptr->dlgsend_head); + } + + if (((ii + 1) % MAX_TSL_BUF) == int_ptr->dlgsend_tail) // buffer is full + { + tcap_send_error("TCAP error. TCU to TCAP buffer is full"); + debug_ptr->watch_dog[193]++; + return 0; + } + memcpy(&int_ptr->dlg_send[ii],dha_ptr,sizeof(CSLdlg_struct)); + int_ptr->dlgsend_head = (ii + 1) % MAX_TSL_BUF; + + tcap_dlg_h[dlg_flag] = int_ptr->dlgsend_head; + + switch (dha_ptr->message_type) + { + case U_Abort: + case U_Abort_Ansi: + if (tcap_ptr->tcap_debug.error_switch) + { + if (dha_ptr->message_type == U_Abort) + sprintf(info_str,"CSL warning. Receive U_Abort from TC-user. Did: %u",dlg_flag); + else + sprintf(info_str,"CSL warning. Receive U_Abort_Ansi from TC-user. Did: %u",dlg_flag); + tcap_send_error(info_str); + } + break; + case P_Abort: + case P_Abort_Ansi: + if (tcap_ptr->tcap_debug.error_switch) + { + if (dha_ptr->message_type == P_Abort) + sprintf(info_str,"CSL warning. Receive P_Abort from TC-user. Did: %u",dlg_flag); + else + sprintf(info_str,"CSL warning. Receive P_Abort_Ansi from TC-user. Did: %u",dlg_flag); + tcap_send_error(info_str); + } + break; + default: + break; + } + tcap_disp_dlg(dha_ptr,2); + if (dha_ptr->message_type == Begin) + { + if (ID_ptr->dialogue_id[dlg_flag] == 0) + debug_ptr->watch_dog[183]++; + if (++tcap_dlg_stats[dlg_flag] > 1) + debug_ptr->watch_dog[182]++; + debug_ptr->watch_dog[196]++; + } + debug_ptr->watch_dog[195]++; + + return 1; +} + +u8 SendTcapCmp(struct CSLcmp_struct *cha_ptr) // send the component portion +{ + struct tcapint_struct *int_ptr; + u32 dlg_flag; + u8 inv_flag; + u8 ii,jj,kk; + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + + dlg_flag = cha_ptr->dialogue_id; + inv_flag = cha_ptr->invoke_id; + if (dlg_flag >= (tcap_ptr->grantdid)) + { + debug_ptr->watch_dog[253]++; + return 0; + } + +//add by daniel on 2006-06-19, to release invoke id propery, if the component is not invoke, then the iid will be released + if ((cha_ptr->message_type != Invoke ) && + (cha_ptr->message_type != Result_NL)) + { + free_iid(dlg_flag,inv_flag); + //tcap_send_ascout("sendTcapCmp free_iid\r\n"); + } +//add by daniel on 2006-06-19, to release invoke id propery, if the component is not invoke, then the iid will be released + + + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[dlg_flag]; + tcap_disp_cmp(cha_ptr,2); + if (cha_ptr->message_type == U_Cancel) + { + ii = int_ptr->cmpsend_tail; + while (ii != int_ptr->cmpsend_head) // search any INV component for this DID and TID + { + if (int_ptr->cmp_send[ii].invoke_id == inv_flag) // has data which is not sent out + { + jj = ii; + kk = (ii + 1) % MAX_CSL_BUF; + while (kk != int_ptr->cmpsend_head) + { + memcpy(&int_ptr->cmp_send[jj],&int_ptr->cmp_send[kk],sizeof(CSLcmp_struct)); + jj = (jj + 1) % MAX_CSL_BUF; + kk = (kk + 1) % MAX_CSL_BUF; + } + if (int_ptr->cmpsend_head == 0) + int_ptr->cmpsend_head = MAX_CSL_BUF - 1; + else + int_ptr->cmpsend_head -= 1; + if (int_ptr->cmpsend_head == ii) + { + write_ism(cha_ptr); + debug_ptr->watch_dog[238]++; + debug_ptr->watch_dog[255]++; + return 1; + } + } + ii = (ii + 1) % MAX_CSL_BUF; + debug_ptr->watch_dog[235]++; + } + write_ism(cha_ptr); + debug_ptr->watch_dog[240]++; + debug_ptr->watch_dog[255]++; + return 1; + } + ii = int_ptr->cmpsend_head; + if (((ii + 1) % MAX_CSL_BUF) == int_ptr->cmpsend_tail) // buffer full + { + tcap_send_alarm(3,1); + tcap_send_error("CSL warning. ISM buffer is full"); + debug_ptr->watch_dog[254]++; + return 0; + } + memcpy(&int_ptr->cmp_send[ii],cha_ptr,sizeof(CSLcmp_struct)); + int_ptr->cmpsend_head = (ii + 1) % MAX_CSL_BUF; + if ((cha_ptr->message_type == U_Reject) || + (cha_ptr->message_type == U_Reject_Ansi) || + (cha_ptr->message_type == Invoke) || + (cha_ptr->message_type == Invoke_L_Ansi) || + (cha_ptr->message_type == Invoke_NL_Ansi)) + { + debug_ptr->watch_dog[239]++; + write_ism(cha_ptr); + } + else + { + debug_ptr->watch_dog[237]++; + if (cha_ptr->message_type != Result_L) + { + debug_ptr->watch_dog[236]++; +// printf("tcap: %d\n", cha_ptr->message_type); + } + } + debug_ptr->watch_dog[255]++; + return 1; +} + +void tcap_fsm(void) // TCAP state machine +{ + register u32 proc; + struct tcapdebug_struct *debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + +// write_paralport(TCAP_LED_CODE,1); + t10ms_flag ++; + if (t10ms_flag >= 2) // 20ms circle + { + t10ms_flag = 0; + tcap_monitor(); + } + for (proc = 0;proc < 64;proc++) + tco_program(); + for (proc = 0;proc < (tcap_ptr->grantdid)/2;proc ++) + { + ism_program(tcap_proc); + tsm_program(tcap_proc); + if (tcap_proc != 0) + { + if (check_did(tcap_proc) || !xapp_check_did(tcap_proc)) + ID_ptr->count_did_tmp++; + } + if (tcap_proc == (tcap_ptr->grantdid - 1)) + { + if ((ID_ptr->count_did_occupied = ID_ptr->count_did_tmp) > ID_ptr->count_did_max) + ID_ptr->count_did_max = ID_ptr->count_did_occupied; + ID_ptr->count_did_tmp = 0; + memcpy(&debug_ptr->watch_dog[160], (BYTE *) &ID_ptr->count_did, sizeof(u32)); + memcpy(&debug_ptr->watch_dog[164], (BYTE *) &ID_ptr->count_did_occupied, sizeof(u32)); + memcpy(&debug_ptr->watch_dog[168], (BYTE *) &ID_ptr->count_did_max, sizeof(u32)); + } + tcap_proc = (tcap_proc + 1) % (tcap_ptr->grantdid); + } +// write_paralport(TCAP_LED_CODE,0); +} + +int itcap_reg_ssn(u8 ssn) +{ + return register_ssn(ssn,0); +} + +int tcap_get_grantdid() +{ + return ((tcap_ptr->grantdid>MAX_DIALOGUEID) \ + ? MAX_DIALOGUEID: tcap_ptr->grantdid); +} + +void tcap_init(int didgrant,u_long localip,u_long peerip) // init TCAP system +{ + printf("Tcap init start!\n"); + if( didgrant <= 0 || didgrant > MAX_DIALOGUEID) + { + printf( "unexpect tcap did grant number!\r\n"); + exit(0); + } + init_id(didgrant); + tcapvm_init(localip,peerip); + tcap_ptr->grantdid = didgrant; + init_m(); + t10ms_flag = 0; + tcap_proc = 0; + + memset(tcap_dlg_h, 0, sizeof(u32) * MAX_DIALOGUEID); + memset(tcap_dlg_t, 0, sizeof(u32) * MAX_DIALOGUEID); + memset(tcap_dlg_stats, 0, sizeof(u32) * MAX_DIALOGUEID); + + printf("Tcap init complete!\n"); +} +/*@end@*/ diff --git a/plat/tcap/src/tcap_coding.c b/plat/tcap/src/tcap_coding.c new file mode 100644 index 0000000..f60d476 --- /dev/null +++ b/plat/tcap/src/tcap_coding.c @@ -0,0 +1,2272 @@ +/* TCAP code/decode c file */ +/* written by Liu Zhiguo 2002-08-08 */ +/* Version 2.0 */ +/* -------------------------------- */ + +#include "../../public/src/include/asn1.h" +#include "../../sccp/src/include/sccp.h" +#include "./include/tcap_public.h" +#include "./include/tcap_struct.h" +#include "./include/tcap_m.h" + +/*@ignore@*/ +/* protocol version */ +static u8 Version_1[2] = {0x07,0x80}; + +/* Undialogue-As-ID value */ +static u8 Undialogue_As_ID[7] = {0x00,0x11,0x86,0x05,0x01,0x02,0x01}; +/* Dialogue-As-ID value */ +static u8 Dialogue_As_ID[7] = {0x00,0x11,0x86,0x05,0x01,0x01,0x01}; + +void print_msg(u8 *ptr, u16 len) +{ + int i; + + for (i = 0; i < len; i++) + printf("%02X ", ptr[i]); + + printf("\n"); +} + +u8 tsl_message_decode(struct SCLC_MSG *src_ptr,struct TSL_struct *dst_ptr, u8 *err_code)// tsl decode +{ + #define TMPBUFSIZE 512 + ASN_BUF asn_buf; + struct TRUni_struct *uni_ptr; + struct TRBegin_struct *begin_ptr; + struct TRContinue_struct *con_ptr; + struct TREnd_struct *end_ptr; + struct TRUAbort_struct *uabort_ptr; + struct TRPAbort_struct *pabort_ptr; + int len=0; + u32 temp_tid=0; + u8 temp_buf[TMPBUFSIZE]; + u8 tag_class; + u16 tag_code; + u8 uabort_flag; + + memcpy(&dst_ptr->peer_add,&src_ptr->src_addr,sizeof(SCCP_ADDR)); + memcpy(&dst_ptr->local_add,&src_ptr->dst_addr,sizeof(SCCP_ADDR)); + + len = asn_decode(src_ptr->msg,1,&asn_buf); + if (len == -1) + tcap_send_error("TSL decode error. ASN.1 structure has problem"); + + len = GetAnyTLV("1",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is Unidirectional/Unidirectional_Ansi + if (len != -1) // message_type is Unidirectional/Unidirectional_Ansi + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + dst_ptr->message_type = Unidirectional_Ansi; + tcap_send_info("Unidirectional_Ansi received from sccp"); + } + else + { + dst_ptr->message_type = Unidirectional; + tcap_send_info("Unidirectional received from sccp"); + } + dst_ptr->message_flag = INDICATE; + uni_ptr = (TRUni_struct *) &dst_ptr->tsl_prim.tr_uni; + uni_ptr->dialogue_len = uni_ptr->components_len = 0; + if (tag_class == ANSI_TAG_CLASS_CONS) + { + len = get_tlv("1.7",temp_buf,&asn_buf); + if (len != 0) + { + tcap_send_error("TSL decode error. Lacks transaction id"); + *err_code = DERR_OTHER; + return 0; + } + } + if (tag_class == ANSI_TAG_CLASS_CONS) + len = get_tlv("1.25",temp_buf,&asn_buf); // get dialogue portion + else + len = get_tlv("1.11",temp_buf,&asn_buf); + if (len != -1) + { + if (len <= TCAP_DLG_LEN) + { + uni_ptr->dialogue_len = len; + memcpy(uni_ptr->dialogue,temp_buf,len); + } + else + { + tcap_send_error("TSL decode error. Dialogue portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + } + if (tag_class == ANSI_TAG_CLASS_CONS) + len = get_tlv("1.8",uni_ptr->components,&asn_buf); + else + len = get_tlv("1.12",uni_ptr->components,&asn_buf); + if ((len == -1) || (len > TCAP_CMP_LEN)) + { + if (len == -1) + tcap_send_error("TSL decode error. Lacks component portion"); + else + tcap_send_error("TSL decode error. Component portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + uni_ptr->components_len = len; + sprintf((char *)temp_buf, "dialogue portion len: %02X, component portion len: %02X\r\n", uni_ptr->dialogue_len, uni_ptr->components_len); + tcap_send_info((char *)temp_buf); + return 1; + } + + len = GetAnyTLV("2",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is begin/query with permission + if (len == -1) + len = GetAnyTLV("3",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is query without permission + if (len != -1) // message_type is begin/query + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 2) + { + dst_ptr->message_type = Query_WithPerm_Ansi; + tcap_send_info("Query_WithPerm_Ansi received from sccp"); + } + else + { + dst_ptr->message_type = Query_WithoutPerm_Ansi; + tcap_send_info("Query_WithoutPerm_Ansi received from sccp"); + } + } + else + { + dst_ptr->message_type = Begin; + tcap_send_info("Begin received from sccp"); + } + dst_ptr->message_flag = INDICATE; + begin_ptr = (TRBegin_struct *) &dst_ptr->tsl_prim.tr_begin; + begin_ptr->dialogue_len = begin_ptr->components_len = 0; + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 2) // get otid + len = get_tlv("2.7",temp_buf,&asn_buf); + else + len = get_tlv("3.7",temp_buf,&asn_buf); + if (len != 4) + { + tcap_send_error("TSL decode error. Lacks originating transaction id"); + begin_ptr->tid_flag = 0; + *err_code = DERR_OTHER; + return 0; + } + } + else + { + len = get_tlv("2.8",temp_buf,&asn_buf); // get otid + if ((len == -1) || (len > 4) || (len == 0)) + { + tcap_send_error("TSL decode error. Lacks originating transaction id"); + begin_ptr->tid_flag = 0; + *err_code = DERR_UNTID; + return 0; + } + } + + dst_ptr->peer_tid_len = len; /* added by Pierre, 2006-08-19 */ + + begin_ptr->transaction_id = bcdtou32(temp_buf,len); + begin_ptr->tid_flag = 1; + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 2) + len = get_tlv("2.25",temp_buf,&asn_buf); + else + len = get_tlv("3.25",temp_buf,&asn_buf); + } + else + len = get_tlv("2.11",temp_buf,&asn_buf); + if (len != -1) // has dialogue portion + { + if (len <= TCAP_DLG_LEN) + { + begin_ptr->dialogue_len = len; + memcpy(begin_ptr->dialogue,temp_buf,len); + } + else + { + tcap_send_error("TSL decode error. Dialogue portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + } + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 2) + len = get_tlv("2.8",begin_ptr->components,&asn_buf); + else + len = get_tlv("3.8",begin_ptr->components,&asn_buf); + } + else + len = get_tlv("2.12",begin_ptr->components,&asn_buf); + if (((len == -1) || (len > TCAP_CMP_LEN)) && (tag_class == ANSI_TAG_CLASS_CONS)) // has components portion + { + if (len == -1) + tcap_send_error("TSL decode error. Lacks component portion"); + else + tcap_send_error("TSL decode error. Component portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + if (len != -1 && len <= TCAP_CMP_LEN) + begin_ptr->components_len = len; + sprintf((char *)temp_buf, "otid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n", + begin_ptr->transaction_id, begin_ptr->dialogue_len, begin_ptr->components_len); + tcap_send_info((char *)temp_buf); + return 1; + } + + len = GetAnyTLV("4",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is end/response + if (len != -1) // message_type is end/response + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + dst_ptr->message_type = Response_Ansi; + tcap_send_info("Response_Ansi received from sccp"); + } + else + { + dst_ptr->message_type = End; + tcap_send_info("End received from sccp"); + } + dst_ptr->message_flag = INDICATE; + end_ptr = (TREnd_struct *) &dst_ptr->tsl_prim.tr_end; + end_ptr->dialogue_len = end_ptr->components_len = 0; + if (tag_class == ANSI_TAG_CLASS_CONS) + { + len = get_tlv("4.7",temp_buf,&asn_buf); // get dtid + if (len != 4) + { + tcap_send_error("TSL decode error. Lacks responding transaction id"); + end_ptr->tid_flag = 0; + *err_code = DERR_UNTID; + return 0; + } + } + else + { + len = get_tlv("4.9",temp_buf,&asn_buf); // get dtid + if ((len == -1) || (len > 4) || (len == 0)) + { + tcap_send_error("TSL decode error. Lacks destination transaction id"); + end_ptr->tid_flag = 0; + *err_code = DERR_UNTID; + return 0; + } + } + end_ptr->transaction_id = bcdtou32(temp_buf,len); + end_ptr->tid_flag = 1; + if (tag_class == ANSI_TAG_CLASS_CONS) + len = get_tlv("4.25",temp_buf,&asn_buf); + else + len = get_tlv("4.11",temp_buf,&asn_buf); + if (len != -1) // has dialogue portion + { + if (len <= TCAP_DLG_LEN) + { + end_ptr->dialogue_len = len; + memcpy(end_ptr->dialogue,temp_buf,len); + } + else + { + tcap_send_error("TSL decode error. Dialogue portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + } + if (tag_class == ANSI_TAG_CLASS_CONS) + len = get_tlv("4.8",end_ptr->components,&asn_buf); + else + len = get_tlv("4.12",end_ptr->components,&asn_buf); + if (((len == -1) || (len > TCAP_CMP_LEN)) && (tag_class == ANSI_TAG_CLASS_CONS)) // has components portion + { + if (len == -1) + tcap_send_error("TSL decode error. Lacks component portion"); + else + tcap_send_error("TSL decode error. Component portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + if (len != -1 && len <= TCAP_CMP_LEN) + end_ptr->components_len = len; + sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n", + end_ptr->transaction_id, end_ptr->dialogue_len, end_ptr->components_len); + tcap_send_info((char *)temp_buf); + return 1; + } + + len = GetAnyTLV("5",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is continue/conversation with permission + if (len == -1) + len = GetAnyTLV("6",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is conversation without permission + if (len != -1) // message_type is continue/conversation + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 5) + { + dst_ptr->message_type = Conversation_WithPerm_Ansi; + tcap_send_info("Conversation_WithPerm_Ansi received from sccp"); + } + else + { + dst_ptr->message_type = Conversation_WithoutPerm_Ansi; + tcap_send_info("Conversation_WithoutPerm_Ansi received from sccp"); + } + } + else + { + dst_ptr->message_type = Continue; + tcap_send_info("Continue received from sccp"); + } + dst_ptr->message_flag = INDICATE; + con_ptr = (TRContinue_struct *) &dst_ptr->tsl_prim.tr_continue; + con_ptr->dialogue_len = con_ptr->components_len = 0; + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 5) + len = get_tlv("5.7",temp_buf,&asn_buf); // get tid + else + len = get_tlv("6.7",temp_buf,&asn_buf); + if (len != 8) + { + tcap_send_error("TSL decode error. Lacks transaction id"); + con_ptr->ltid_flag = 0; + con_ptr->ptid_flag = 0; + *err_code = DERR_OTHER; + return 0; + } + dst_ptr->peer_tid_len = len; /* added by Pierre , 2006-08-19 */ + + con_ptr->peer_tid = bcdtou32(temp_buf,4); + con_ptr->ptid_flag = 1; + con_ptr->local_tid = bcdtou32(temp_buf + 4,4); + con_ptr->ltid_flag = 1; + } + else + { + len = get_tlv("5.8",temp_buf,&asn_buf); // get otid + if ((len == -1) || (len > 4) || (len == 0)) + { + tcap_send_error("TSL decode error. Lacks originating transaction id"); + con_ptr->ptid_flag = 0; + *err_code = DERR_UNTID; + return 0; + } + dst_ptr->peer_tid_len = len; /* added by Pierre, 2006-08-19 */ + con_ptr->peer_tid = bcdtou32(temp_buf,len); + con_ptr->ptid_flag = 1; + len = get_tlv("5.9",temp_buf,&asn_buf); // get dtid + if ((len == -1) || (len > 4) || (len == 0)) + { + tcap_send_error("TSL decode error. Lacks destination transaction id"); + con_ptr->ltid_flag = 0; + *err_code = DERR_UNTID; + return 0; + } + con_ptr->local_tid = bcdtou32(temp_buf,len); + con_ptr->ltid_flag = 1; + } + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 5) + len = get_tlv("5.25",temp_buf,&asn_buf); + else + len = get_tlv("6.25",temp_buf,&asn_buf); + } + else + len = get_tlv("5.11",temp_buf,&asn_buf); + if (len != -1) // has dialogue portion + { + if (len <= TCAP_DLG_LEN) + { + con_ptr->dialogue_len = len; + memcpy(con_ptr->dialogue,temp_buf,len); + } + else + { + tcap_send_error("TSL decode error. Dialogue portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + } + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tag_code == 5) + len = get_tlv("5.8",con_ptr->components,&asn_buf); + else + len = get_tlv("6.8",con_ptr->components,&asn_buf); + } + else + len = get_tlv("5.12",con_ptr->components,&asn_buf); + if (((len == -1) || (len > TCAP_CMP_LEN)) && (tag_class == ANSI_TAG_CLASS_CONS)) // has components portion + { + if (len == -1) + tcap_send_error("TSL decode error. Lacks component portion"); + else + tcap_send_error("TSL decode error. Component portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + if (len != -1 && len <= TCAP_CMP_LEN) + con_ptr->components_len = len; + sprintf((char *)temp_buf, "otid: %08X, dtid: %08X\r\ndialogue portion len: %02X, component portion len: %02X\r\n", + con_ptr->peer_tid, con_ptr->local_tid, con_ptr->dialogue_len, con_ptr->components_len); + tcap_send_info((char *)temp_buf); + return 1; + } + + len = GetAnyTLV("7",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is abort + if (len != -1) // message_type is abort + { + dst_ptr->message_type = U_Abort; + tcap_send_info("Abort received from sccp"); + dst_ptr->message_flag = INDICATE; + uabort_ptr = (TRUAbort_struct *) &dst_ptr->tsl_prim.tr_uabort; + uabort_ptr->dialogue_len = 0; + uabort_ptr->uabort_info_len = 0; + len = get_tlv("7.9",temp_buf,&asn_buf); // get dtid + if (len == -1 || len > 4 || len == 0) + { + tcap_send_error("TSL decode error. Lacks destination transaction id"); + uabort_ptr->tid_flag = 0; + *err_code = DERR_UNTID; + return 0; + } + temp_tid = bcdtou32(temp_buf,len); + uabort_ptr->tid_flag = 1; + uabort_ptr->transaction_id = temp_tid; + len = get_tlv("7.11",temp_buf,&asn_buf); + if (len != -1 && len <= TCAP_DLG_LEN) // has dialogue portion + { + uabort_ptr->dialogue_len = len; + memcpy(uabort_ptr->dialogue,temp_buf,len); + sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X\r\n", + uabort_ptr->transaction_id, uabort_ptr->dialogue_len); + tcap_send_info((char *)temp_buf); + return 1; + } + else if (len > TCAP_DLG_LEN) + { + tcap_send_error("TSL decode error. Dialogue portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + len = get_tlv("7.10",temp_buf,&asn_buf); + if (len != -1) // has P_Abort_Cause + { + dst_ptr->message_type = P_Abort; + pabort_ptr = (TRPAbort_struct *) &dst_ptr->tsl_prim.tr_pabort; + pabort_ptr->tid_flag = 1; + pabort_ptr->transaction_id = temp_tid; + if (len != 1) + { + tcap_send_error("TSL decode error. P_Abort lacks abort reason"); + *err_code = DERR_OTHER; + return 0; + } + pabort_ptr->abort_reason = temp_buf[0]; + sprintf((char *)temp_buf, "dtid: %08X, pabort reason: %02X\r\n", + pabort_ptr->transaction_id, pabort_ptr->abort_reason); + tcap_send_info((char *)temp_buf); + return 1; + } + } + + len = GetAnyTLV("22",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is ansi abort + if (len != -1) // message_type is ansi abort + { + dst_ptr->message_type = U_Abort_Ansi; + tcap_send_info("Abort_Ansi received from sccp"); + dst_ptr->message_flag = INDICATE; + uabort_ptr = (TRUAbort_struct *) &dst_ptr->tsl_prim.tr_uabort; + uabort_ptr->dialogue_len = 0; + uabort_ptr->uabort_info_len = 0; + uabort_flag = 0; + len = get_tlv("22.7",temp_buf,&asn_buf); // get dtid + if (len != 4) + { + tcap_send_error("TSL decode error. Lacks responding transaction id"); + uabort_ptr->tid_flag = 0; + *err_code = DERR_UNTID; + return 0; + } + temp_tid = bcdtou32(temp_buf,4); + uabort_ptr->tid_flag = 1; + uabort_ptr->transaction_id = temp_tid; + len = get_tlv("22.25",temp_buf,&asn_buf); + if (len != -1) // has dialogue portion + { + uabort_flag = 1; + if (len <= TCAP_DLG_LEN) + { + uabort_ptr->dialogue_len = len; + memcpy(uabort_ptr->dialogue,temp_buf,len); + } + else + { + tcap_send_error("TSL decode error. Dialogue portion is too long"); + *err_code = DERR_OTHER; + return 0; + } + } + len = get_tlv("22.24",temp_buf,&asn_buf); + if (len >= 0) // has user abort info + { + if (len <= TCAP_UABORT_INFO_LEN) + { + uabort_ptr->uabort_info_len = len; + memcpy(uabort_ptr->uabort_info,temp_buf,len); + sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, uabort info len: %02X\r\n", + uabort_ptr->transaction_id, uabort_ptr->dialogue_len, uabort_ptr->uabort_info_len); + tcap_send_info((char *)temp_buf); + return 1; + } + else + { + tcap_send_error("TSL decode error. Uabort info is too long"); + *err_code = DERR_OTHER; + return 0; + } + } + else if (uabort_flag) + { + *err_code = DERR_OTHER; + tcap_send_error("TSL decode error. U_Abort lacks uabort info"); + return 0; + } + len = get_tlv("22.23",temp_buf,&asn_buf); + if (len != -1) // has P_Abort_Cause + { + dst_ptr->message_type = P_Abort_Ansi; + pabort_ptr = (TRPAbort_struct *) &dst_ptr->tsl_prim.tr_pabort; + pabort_ptr->tid_flag = 1; + pabort_ptr->transaction_id = temp_tid; + if (len != 1) + { + tcap_send_error("TSL decode error. P_Abort lacks abort reason"); + *err_code = DERR_OTHER; + return 0; + } + pabort_ptr->abort_reason = temp_buf[0]; + sprintf((char *)temp_buf, "dtid: %08X, pabort reason: %02X\r\n", + pabort_ptr->transaction_id, pabort_ptr->abort_reason); + tcap_send_info((char *)temp_buf); + return 1; + } + } + + tcap_send_error("TSL decode error. Can not recognize package type"); + return 0; +} + +u8 tsl_message_encode(struct SCLC_MSG *sccp_ptr,struct TSL_struct *tsl_ptr,u8 flag)// tsl encode +{ + ASN_BUF asn_buf; + u8 temp_buf[512]; + u8 tag_class; + u32 len = 0; + u32 temp_tid=0; + struct TRUni_struct *uni_ptr; + struct TRBegin_struct *begin_ptr; + struct TRContinue_struct *con_ptr; + struct TREnd_struct *end_ptr; + struct TRUAbort_struct *uabort_ptr; + struct TRPAbort_struct *pabort_ptr; + + if (flag) // resend + { + memcpy(&sccp_ptr->dst_addr,&tsl_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&sccp_ptr->src_addr,&tsl_ptr->peer_add,sizeof(SCCP_ADDR)); + } + else + { + memcpy(&sccp_ptr->dst_addr,&tsl_ptr->peer_add,sizeof(SCCP_ADDR)); + memcpy(&sccp_ptr->src_addr,&tsl_ptr->local_add,sizeof(SCCP_ADDR)); + } + asn_encode(sccp_ptr->msg,&asn_buf); + tag_class = tsl_ptr->message_type & 0xE0; + switch (tsl_ptr->message_type) + { + case Unidirectional: + case Unidirectional_Ansi: + if (tag_class == ANSI_TAG_CLASS_CONS) + { + sccp_ptr->msglen = add_tlv("1",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("Unidirectional_Ansi sent to sccp"); + } + else + { + sccp_ptr->msglen = add_tlv("1",0,temp_buf,0x60,&asn_buf); + tcap_send_info("Unidirectional sent to sccp"); + } + uni_ptr = (TRUni_struct *) &tsl_ptr->tsl_prim.tr_uni; + if (tag_class == ANSI_TAG_CLASS_CONS) // Transaction ID + sccp_ptr->msglen = add_tlv("1.7-1",0,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + if (uni_ptr->dialogue_len != 0) // dialogue portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("1.25-2",uni_ptr->dialogue_len,uni_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("1.11",uni_ptr->dialogue_len,uni_ptr->dialogue,0x60,&asn_buf); + } + if (uni_ptr->components_len != 0) // component portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("1.8-3",uni_ptr->components_len,uni_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("1.12",uni_ptr->components_len,uni_ptr->components,0x60,&asn_buf); + } + sprintf((char *)temp_buf, "dialogue portion len: %02X, component portion len: %02X\r\n", uni_ptr->dialogue_len, uni_ptr->components_len); + tcap_send_info((char *)temp_buf); + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][0] ++; + break; + case Begin: + case Query_WithPerm_Ansi: + case Query_WithoutPerm_Ansi: + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tsl_ptr->message_type == Query_WithPerm_Ansi) + { + sccp_ptr->msglen = add_tlv("2",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("Query_WithPerm_Ansi sent to sccp"); + } + else + { + sccp_ptr->msglen = add_tlv("3",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("Query_WithoutPerm_Ansi sent to sccp"); + } + } + else + { + sccp_ptr->msglen = add_tlv("2",0,temp_buf,0x60,&asn_buf); + tcap_send_info("Begin sent to sccp"); + } + begin_ptr = (TRBegin_struct *) &tsl_ptr->tsl_prim.tr_begin; + temp_tid = (tcap_ptr->tcap_debug.local_ip & 0xffff0000) + begin_ptr->transaction_id; + len = u32tobcd(temp_buf,temp_tid); //encode orig TID + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tsl_ptr->message_type == Query_WithPerm_Ansi) + sccp_ptr->msglen = add_tlv("2.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + sccp_ptr->msglen = add_tlv("3.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + } + else + sccp_ptr->msglen = add_tlv("2.8",len,temp_buf,0x40,&asn_buf); + if (begin_ptr->dialogue_len != 0) // dialogue portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tsl_ptr->message_type == Query_WithPerm_Ansi) + sccp_ptr->msglen = add_tlv("2.25-2",begin_ptr->dialogue_len,begin_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("3.25-2",begin_ptr->dialogue_len,begin_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf); + } + else + sccp_ptr->msglen = add_tlv("2.11",begin_ptr->dialogue_len,begin_ptr->dialogue,0x60,&asn_buf); + } + if (begin_ptr->components_len != 0) // component portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tsl_ptr->message_type == Query_WithPerm_Ansi) + sccp_ptr->msglen = add_tlv("2.8-3",begin_ptr->components_len,begin_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("3.8-3",begin_ptr->components_len,begin_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf); + } + else + sccp_ptr->msglen = add_tlv("2.12",begin_ptr->components_len,begin_ptr->components,0x60,&asn_buf); + } + sprintf((char *)temp_buf, "otid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n", begin_ptr->transaction_id, begin_ptr->dialogue_len, begin_ptr->components_len); + tcap_send_info((char *)temp_buf); + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][1] ++; + break; + case Continue: + case Conversation_WithPerm_Ansi: + case Conversation_WithoutPerm_Ansi: + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tsl_ptr->message_type == Conversation_WithPerm_Ansi) + { + sccp_ptr->msglen = add_tlv("5",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("Conversation_WithPerm_Ansi sent to sccp"); + } + else + { + sccp_ptr->msglen = add_tlv("6",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("Conversation_WithoutPerm_Ansi sent to sccp"); + } + } + else + { + sccp_ptr->msglen = add_tlv("5",0,temp_buf,0x60,&asn_buf); + tcap_send_info("Continue sent to sccp"); + } + con_ptr = (TRContinue_struct *) &tsl_ptr->tsl_prim.tr_continue; + if (flag) //resend + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + u32tobcd(temp_buf,con_ptr->peer_tid); + temp_tid = con_ptr->local_tid | 0x8000; + u32tobcd(temp_buf + 4,temp_tid); + if (tsl_ptr->message_type == Conversation_WithPerm_Ansi) + sccp_ptr->msglen = add_tlv("5.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + sccp_ptr->msglen = add_tlv("6.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + } + else + { + memset(temp_buf,0,4); + len = u32tobcd(temp_buf,con_ptr->peer_tid); + len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */ + sccp_ptr->msglen = add_tlv("5.8",len,&temp_buf[4-len],0x40,&asn_buf); + temp_tid = con_ptr->local_tid ;//| 0x8000; + memset(temp_buf,0,4); + len = u32tobcd(temp_buf,temp_tid); + if(len == 0) len = 4; + sccp_ptr->msglen = add_tlv("5.9",len,temp_buf,0x40,&asn_buf); + } + } + else + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + temp_tid = (tcap_ptr->tcap_debug.local_ip & 0xffff0000) + con_ptr->local_tid; + u32tobcd(temp_buf,temp_tid); + u32tobcd(temp_buf + 4,con_ptr->peer_tid); + if (tsl_ptr->message_type == Conversation_WithPerm_Ansi) + sccp_ptr->msglen = add_tlv("5.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + sccp_ptr->msglen = add_tlv("6.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + } + else + { + memset(temp_buf,0,4); + temp_tid = (tcap_ptr->tcap_debug.local_ip & 0xffff0000) + con_ptr->local_tid; + len = u32tobcd(temp_buf,temp_tid); //encode orig TID + sccp_ptr->msglen = add_tlv("5.8",len,temp_buf,0x40,&asn_buf); + memset(temp_buf,0,4); + len = u32tobcd(temp_buf,con_ptr->peer_tid); // encode dst TID + len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */ + if(len == 0) len = 4; + sccp_ptr->msglen = add_tlv("5.9",len,&temp_buf[4-len],0x40,&asn_buf); + } + } + if (con_ptr->dialogue_len != 0) // dialogue portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tsl_ptr->message_type == Conversation_WithPerm_Ansi) + sccp_ptr->msglen = add_tlv("5.25-2",con_ptr->dialogue_len,con_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("6.25-2",con_ptr->dialogue_len,con_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf); + } + else + sccp_ptr->msglen = add_tlv("5.11",con_ptr->dialogue_len,con_ptr->dialogue,0x60,&asn_buf); + } + if (con_ptr->components_len != 0) // component portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + { + if (tsl_ptr->message_type == Conversation_WithPerm_Ansi) + sccp_ptr->msglen = add_tlv("5.8-3",con_ptr->components_len,con_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("6.8-3",con_ptr->components_len,con_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf); + } + else + sccp_ptr->msglen = add_tlv("5.12",con_ptr->components_len,con_ptr->components,0x60,&asn_buf); + } + sprintf((char *)temp_buf, "otid: %08X, dtid: %08X\r\ndialogue portion len: %02X, component portion len: %02X\r\n", con_ptr->local_tid, con_ptr->peer_tid, con_ptr->dialogue_len, con_ptr->components_len); + tcap_send_info((char *)temp_buf); + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][2] ++; + break; + case End: + case Response_Ansi: + if (tag_class == ANSI_TAG_CLASS_CONS) + { + sccp_ptr->msglen = add_tlv("4",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("Response_Ansi sent to sccp"); + } + else + { + sccp_ptr->msglen = add_tlv("4",0,temp_buf,0x60,&asn_buf); + tcap_send_info("End sent to sccp"); + } + end_ptr = (TREnd_struct *) &tsl_ptr->tsl_prim.tr_end; +// if (flag) +// temp_tid = end_ptr->transaction_id | 0x8000; +// else + temp_tid = end_ptr->transaction_id; + memset(temp_buf,0,4); + len = u32tobcd(temp_buf,temp_tid); //encode dst TID + + if(!flag) + len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */ + if(len == 0) len = 4; + + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("4.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + sccp_ptr->msglen = add_tlv("4.9",len,&temp_buf[4-len],0x40,&asn_buf); + if (end_ptr->dialogue_len != 0) // dialogue portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("4.25-2",end_ptr->dialogue_len,end_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("4.11",end_ptr->dialogue_len,end_ptr->dialogue,0x60,&asn_buf); + } + if (end_ptr->components_len != 0) // component portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("4.8-3",end_ptr->components_len,end_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("4.12",end_ptr->components_len,end_ptr->components,0x60,&asn_buf); + } + sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n", end_ptr->transaction_id, end_ptr->dialogue_len, end_ptr->components_len); + tcap_send_info((char *)temp_buf); + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][3] ++; + break; + case P_Abort: + case P_Abort_Ansi: + if (tag_class == ANSI_TAG_CLASS_CONS) + { + sccp_ptr->msglen = add_tlv("22",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("P_Abort_Ansi sent to sccp"); + } + else + { + sccp_ptr->msglen = add_tlv("7",0,temp_buf,0x60,&asn_buf); + tcap_send_info("P_Abort sent to sccp"); + } + pabort_ptr = (TRPAbort_struct *) &tsl_ptr->tsl_prim.tr_pabort; +// if (flag) +// temp_tid = pabort_ptr->transaction_id | 0x8000; +// else + temp_tid = pabort_ptr->transaction_id; + memset(temp_buf,0,4); + len = u32tobcd(temp_buf,temp_tid); //encode dst TID + + if(!flag) + len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */ + if(len == 0) len = 4; + + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("22.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + sccp_ptr->msglen = add_tlv("7.9",len,temp_buf,0x40,&asn_buf); + temp_buf[0] = pabort_ptr->abort_reason; + len = 1; + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("22.23-2",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + sccp_ptr->msglen = add_tlv("7.10",len,temp_buf,0x40,&asn_buf); + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][4] ++; + switch (pabort_ptr->abort_reason) + { + case P_Abort_UMT: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][48] ++; + break; + case P_Abort_ITP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][49] ++; + break; + case P_Abort_BFTP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][50] ++; + break; + case P_Abort_UTID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][51] ++; + break; + case P_Abort_RL: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][52] ++; + break; + default: + break; + } + sprintf((char *)temp_buf, "dtid: %08X, pabort reason: %02X\r\n", pabort_ptr->transaction_id, pabort_ptr->abort_reason); + tcap_send_info((char *)temp_buf); + break; + case U_Abort: + case U_Abort_Ansi: + if (tag_class == ANSI_TAG_CLASS_CONS) + { + sccp_ptr->msglen = add_tlv("22",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf); + tcap_send_info("mU_Abort_Ansi sent to sccp"); + } + else + { + sccp_ptr->msglen = add_tlv("7",0,temp_buf,0x60,&asn_buf); + tcap_send_info("U_Abort sent to sccp"); + } + uabort_ptr = (TRUAbort_struct *) &tsl_ptr->tsl_prim.tr_uabort; +// if (flag) +// temp_tid = uabort_ptr->transaction_id | 0x8000; +// else + temp_tid = uabort_ptr->transaction_id; + memset(temp_buf,0,4); + len = u32tobcd(temp_buf,temp_tid); //encode dst TID + if(!flag) + len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */ + if(len == 0) len = 4; + + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("22.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + sccp_ptr->msglen = add_tlv("7.9",len,temp_buf,0x40,&asn_buf); + if (uabort_ptr->dialogue_len != 0) // dialogue portion + { + if (tag_class == ANSI_TAG_CLASS_CONS) + sccp_ptr->msglen = add_tlv("22.25-2",uabort_ptr->dialogue_len,uabort_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf); + else + sccp_ptr->msglen = add_tlv("7.11",uabort_ptr->dialogue_len,uabort_ptr->dialogue,0x60,&asn_buf); + } + if (tag_class == ANSI_TAG_CLASS_CONS) + { + sccp_ptr->msglen = add_tlv("22.24-3",uabort_ptr->uabort_info_len,uabort_ptr->uabort_info,ANSI_TAG_CLASS_PRIM,&asn_buf); + sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, uabort info len: %02X\r\n", uabort_ptr->transaction_id, uabort_ptr->dialogue_len, uabort_ptr->uabort_info_len); + } + else + sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X\r\n", uabort_ptr->transaction_id, uabort_ptr->dialogue_len); + tcap_send_info((char *)temp_buf); + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][4] ++; + break; + default: //unknown message type + tcap_send_error("TSL encode error. Can not recognize package type"); + return 0; + break; + } + return 1; +} + +int extract_acn(u8 *acn,u8 *data,int data_len) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[TCAP_BUF_LEN]; + + len = asn_decode(data,1,&asn_buf); + if (len != data_len) // data length is wrong + { + tcap_send_error("CSL dialogue decode error. ACN structure is error"); + return 0; + } + len = get_tlv("6",temp_buf,&asn_buf); // get Object_Identifier + if (len == -1 || len > TCAP_ACN_LEN) + { + tcap_send_error("CSL dialogue decode error. dialogue portion lack ACN"); + return 0; + } + memcpy(acn,temp_buf,len); + return len; +} + +u8 extract_result(u8 *result,u8 *data,int data_len) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[TCAP_BUF_LEN]; + + len = asn_decode(data,1,&asn_buf); + if (len != data_len) + { + tcap_send_error("CSL dialogue decode error. Result structure is error"); + return 0; + } + len = get_tlv("2",temp_buf,&asn_buf); // get Integer + if (len != 1) + { + tcap_send_error("CSL dialogue decode error. Result structure is error"); + return 0; + } + *result = temp_buf[0]; + return 1; +} + +u8 extract_diag(u8 *result,u8 *data,int data_len) // extract diagnostic +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[TCAP_BUF_LEN]; + u8 result_type; + + len = asn_decode(data,1,&asn_buf); + if (len != data_len) + { + tcap_send_error("CSL dialogue decode error. ASN.1 structure is error"); + return 0; + } + len = get_tlv("1",temp_buf,&asn_buf); // check dialogue service user + if (len != -1) + { + result_type = Dialogue_Service_User; + len = get_tlv("1.2",temp_buf,&asn_buf); + if (len == 0) + *result = 0; + else + *result = temp_buf[0]; + return result_type; + } + len = get_tlv("2",temp_buf,&asn_buf); // check dialogue service provider + if (len != -1) + { + result_type = Dialogue_Service_Provider; + len = get_tlv("2.2",temp_buf,&asn_buf); + if (len == 0) + *result = 0; + else + *result = temp_buf[0]; + return result_type; + } + tcap_send_error("CSL dialogue decode error. Can not recognize diagnostic service type"); + return 0; +} + +u8 extract_dp(struct dlgPDU_struct *pdu_ptr,u8 *databuf,int datalen,u8 proto_type) // extract dialogue portion +{ + ASN_BUF asn_buf; + int len; + int result; + u8 id_value_flag = 0; + struct AARQ_struct *aarq_ptr; + struct AARE_struct *aare_ptr; + struct ABRT_struct *abrt_ptr; + struct ASUDT_struct *asudt_ptr; + u8 asn_data[TCAP_BUF_LEN]; + u8 temp_data[TCAP_BUF_LEN]; + + memset(pdu_ptr,0,sizeof(dlgPDU_struct)); + if (!proto_type) + len = asn_decode(databuf,1,&asn_buf); + else + len = asn_decode(databuf,5,&asn_buf); + if (len == -1) // asn1 decode error + { + tcap_send_error("CSL dialogue decode error. ASN.1 structure has error"); + return 0; + } + + if (proto_type) + { + result = 0; + asudt_ptr = (ASUDT_struct *) &pdu_ptr->pdu_union.asudt; + len = get_tlv("26",temp_data,&asn_buf); // get protocol version + if (len == 1) + { + asudt_ptr->version = temp_data[0]; + result = 1; + } + len = get_tlv("28",temp_data,&asn_buf); // get object identifier ACN + if (len != -1) + asudt_ptr->acn_type = TYPE_OID; + else + { + len = get_tlv("27",temp_data,&asn_buf); // get integer ACN + if (len != -1) + asudt_ptr->acn_type = TYPE_INT; + } + if (len > 0) + { + asudt_ptr->acn_len = len; + memcpy(asudt_ptr->acn,temp_data,len); + result = 1; + } + len = get_tlv("29",temp_data,&asn_buf); // get user information + if (len != -1) + { + asudt_ptr->user_info_len = len; + memcpy(asudt_ptr->user_info,temp_data,len); + result = 1; + } + len = get_tlv("1",temp_data,&asn_buf); // get object id security context + if (len != -1) + asudt_ptr->security_context_type = TYPE_OID; + else + { + len = get_tlv("0",temp_data,&asn_buf); // get integer security context + if (len != -1) + asudt_ptr->security_context_type = TYPE_INT; + } + if (len != -1) + { + asudt_ptr->security_context_len = len; + memcpy(asudt_ptr->security_context,temp_data,len); + result = 1; + } + len = get_tlv("2",temp_data,&asn_buf); // get confidentiality information + if (len != -1) + { + asudt_ptr->confidential_info_len = len; + memcpy(asudt_ptr->confidential_info,temp_data,len); + result = 1; + } + if (result) + { + pdu_ptr->dialogue_type = PDU_ASUDT; + return 1; + } + else + return 0; + } + else + { + len = get_tlv("8",temp_data,&asn_buf); // get External + if (len == -1) + { + tcap_send_error("CSL dialogue decode error. Lack External structure"); + return 0; + } + len = get_tlv("8.6",temp_data,&asn_buf); // get Object_Identifier + if (len == -1) // dialogue-as-ID portion + { + tcap_send_error("CSL dialogue decode error. Lack Object identifier"); + return 0; + } + if (memcmp(Undialogue_As_ID,temp_data,len) == 0) // undialogue as id value + id_value_flag = 2; + else if (memcmp(Dialogue_As_ID,temp_data,len) == 0) // dialogue as id value + id_value_flag = 1; + else // unknwn data + { + tcap_send_error("CSL dialogue decode error. Dialogue-as-ID value error"); + return 0; + } + len = get_tlv("8.0",asn_data,&asn_buf); // get Single ASN.1 type + if (len == -1) + { + tcap_send_error("CSL dialogue decode error. Lack single ASN.1 structure"); + return 0; + } + len = asn_decode(asn_data,1,&asn_buf); + if (len == -1) + { + tcap_send_error("CSL dialogue decode error. ASN.1 structure is error"); + return 0; + } + len = get_tlv("0",temp_data,&asn_buf); // get AARQ dialogue + if (len != -1) // has AARQ + { + pdu_ptr->dialogue_type = PDU_AARQ; + aarq_ptr = (AARQ_struct *) &pdu_ptr->pdu_union.aarq; + memcpy(aarq_ptr->version,Version_1,2); + len = get_tlv("0.0",temp_data,&asn_buf); // get protocol version + if (len != 2) // lack protocol version or version is error + { + temp_data[0] = 0x07; + temp_data[1] = 0x80; + tcap_send_error("CSL dialogue decode error. AARQ lack protocol version"); + //return 0; + } + memcpy(aarq_ptr->version,temp_data,2); + len = get_tlv("0.1",temp_data,&asn_buf); // get ACN + if (len == -1 || len > TCAP_ACN_LEN) + { + tcap_send_error("CSL dialogue decode error. AARQ lack ACN"); + return 0; + } + aarq_ptr->acn_len = extract_acn(aarq_ptr->acn,temp_data,len); + len = get_tlv("0.30",temp_data,&asn_buf); // get user info + if (len != -1 && len <= TCAP_USERINFO_LEN) // has user information + { + aarq_ptr->user_info_len = len; + memcpy(aarq_ptr->user_info,temp_data,len); + } + return 1; + } + len = get_tlv("1",temp_data,&asn_buf); // get AARE dialogue + if (len != -1) // has AARE + { + pdu_ptr->dialogue_type = PDU_AARE; + aare_ptr = (AARE_struct *) &pdu_ptr->pdu_union.aare; + memcpy(aare_ptr->version,Version_1,2); + len = get_tlv("1.0",temp_data,&asn_buf); // get protocol version + if (len != 2) // lack protocol version or version is error + { + temp_data[0] = 0x07; + temp_data[1] = 0x80; + tcap_send_error("CSL dialogue decode error. AARE lack protocol version"); + //return 0; + } + memcpy(aare_ptr->version,temp_data,2); + len = get_tlv("1.1",temp_data,&asn_buf); // get ACN + if (len == -1) + { + tcap_send_error("CSL dialogue decode error. AARE lack ACN"); + return 0; + } + aare_ptr->acn_len = extract_acn(aare_ptr->acn,temp_data,len); + len = get_tlv("1.2",temp_data,&asn_buf); // get result + if (len == -1) // has no result + { + tcap_send_error("CSL dialogue decode error. AARE lack result"); + return 0; + } + if (!extract_result(&aare_ptr->result,temp_data,len)) + return 0; + len = get_tlv("1.3",temp_data,&asn_buf); // get source diagnostic + if (len == -1) + { + tcap_send_error("CSL dialogue decode error. AARE lack source diagnostic"); + return 0; + } + result = extract_diag(&aare_ptr->diagnostic_type,temp_data,len); + if (result == 0) + return 0; + else + aare_ptr->diagnostic_flag = result; + len = get_tlv("1.30",temp_data,&asn_buf); // get user info + if (len != -1 && len <= TCAP_USERINFO_LEN) // has user information + { + aare_ptr->user_info_len = len; + memcpy(aare_ptr->user_info,temp_data,len); + } + return 1; + } + len = get_tlv("4",temp_data,&asn_buf); // get ABRT dialogue + if (len != -1) // has ABRT + { + pdu_ptr->dialogue_type = PDU_ABRT; + abrt_ptr = (ABRT_struct *) &pdu_ptr->pdu_union.abrt; + len = get_tlv("4.0",temp_data,&asn_buf); // get reason + if (len != 1) // lack reason + { + tcap_send_error("CSL dialogue decode error. ABRT lack reason"); + return 0; + } + abrt_ptr->abort_source = temp_data[0]; + len = get_tlv("4.30",temp_data,&asn_buf); // get user info + if (len != -1 && len <= TCAP_USERINFO_LEN) // has user information + { + abrt_ptr->user_info_len = len; + memcpy(abrt_ptr->user_info,temp_data,len); + } + return 1; + } + tcap_send_error("CSL dialogue decode error. Can not recognize dialogue type"); + return 0; + } +} + +u8 build_dp(u8 *content,struct dlgPDU_struct *dlg_ptr,u8 un_flag,u8 proto_type) // build dialogue portion +{ + ASN_BUF asn_buf; + u8 temp_data[TCAP_BUF_LEN]; + u32 len = 0,len1 = 0; + struct AARQ_struct *aarq_ptr; + struct AARE_struct *aare_ptr; + struct ABRT_struct *abrt_ptr; + struct ASUDT_struct *asudt_ptr; + + if (proto_type) + asn_encode(content,&asn_buf); + else + asn_encode(temp_data,&asn_buf); + switch (dlg_ptr->dialogue_type) // encode the content of dialogue portion + { + case PDU_AARQ: + aarq_ptr = (AARQ_struct *) &dlg_ptr->pdu_union.aarq; + len1 = add_tlv("0",0,temp_data,0x60,&asn_buf); + len1 = add_tlv("0.0",2,aarq_ptr->version,0x80,&asn_buf); + if (aarq_ptr->acn_len != 0) + { + len1 = add_tlv("0.1",0,aarq_ptr->acn,0x0a0,&asn_buf); + len1 = add_tlv("0.1.6",aarq_ptr->acn_len,aarq_ptr->acn,0x00,&asn_buf); + } + if (aarq_ptr->user_info_len != 0) + len1 = add_tlv("0.30",aarq_ptr->user_info_len,aarq_ptr->user_info,0x0a0,&asn_buf); + break; + case PDU_AARE: + aare_ptr = (AARE_struct *) &dlg_ptr->pdu_union.aare; + len1 = add_tlv("1",0,temp_data,0x60,&asn_buf); + len1 = add_tlv("1.0",2,aare_ptr->version,0x80,&asn_buf); + if (aare_ptr->acn_len != 0) // encode acn portion + { + len1 = add_tlv("1.1",0,aare_ptr->acn,0x0a0,&asn_buf); + len1 = add_tlv("1.1.6",aare_ptr->acn_len,aare_ptr->acn,0x00,&asn_buf); + } + len1 = add_tlv("1.2",0,&aare_ptr->result,0x0a0,&asn_buf);// encode result + len1 = add_tlv("1.2.2",1,&aare_ptr->result,0x00,&asn_buf); + len1 = add_tlv("1.3",0,&aare_ptr->diagnostic_flag,0x0a0,&asn_buf); // encode diagnostic + if (aare_ptr->diagnostic_flag == Dialogue_Service_Provider) + { + len1 = add_tlv("1.3.2",0,&aare_ptr->diagnostic_flag,0x0a0,&asn_buf); + len1 = add_tlv("1.3.2.2",1,&aare_ptr->diagnostic_type,0x00,&asn_buf); + } + else + { + len1 = add_tlv("1.3.1",0,&aare_ptr->diagnostic_flag,0x0a0,&asn_buf); + len1 = add_tlv("1.3.1.2",1,&aare_ptr->diagnostic_type,0x00,&asn_buf); + } + if (aare_ptr->user_info_len != 0) + len1 = add_tlv("1.30",aare_ptr->user_info_len,aare_ptr->user_info,0x0a0,&asn_buf); + break; + case PDU_ABRT: + abrt_ptr = (ABRT_struct *) &dlg_ptr->pdu_union.abrt; + len1 = add_tlv("4",0,temp_data,0x60,&asn_buf); + len1 = add_tlv("4.0",1,&abrt_ptr->abort_source,0x80,&asn_buf); + if (abrt_ptr->user_info_len != 0) + len1 = add_tlv("4.30",abrt_ptr->user_info_len,abrt_ptr->user_info,0x0a0,&asn_buf); + break; + case PDU_ASUDT: + asudt_ptr = (ASUDT_struct *) &dlg_ptr->pdu_union.asudt; + len1 = add_tlv("26-1",1,&asudt_ptr->version,ANSI_TAG_CLASS_PRIM,&asn_buf); + if (asudt_ptr->acn_len > 0) + { + if (asudt_ptr->acn_type == TYPE_OID) // object id acn + len1 = add_tlv("28-2",asudt_ptr->acn_len,asudt_ptr->acn,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + len1 = add_tlv("27-2",asudt_ptr->acn_len,asudt_ptr->acn,ANSI_TAG_CLASS_PRIM,&asn_buf); + } + if (asudt_ptr->user_info_len > 0) + len1 = add_tlv("29-3",asudt_ptr->user_info_len,asudt_ptr->user_info,ANSI_TAG_CLASS_PRIM,&asn_buf); + if (asudt_ptr->security_context_len > 0) + { + if (asudt_ptr->security_context_type == TYPE_OID) // object id security context + len1 = add_tlv("1-4",asudt_ptr->security_context_len,asudt_ptr->security_context,0x80,&asn_buf); + else + len1 = add_tlv("0-4",asudt_ptr->security_context_len,asudt_ptr->security_context,0x80,&asn_buf); + } + if (asudt_ptr->confidential_info_len > 0) + len1 = add_tlv("2-5",asudt_ptr->confidential_info_len,asudt_ptr->confidential_info,0xA0,&asn_buf); + return len1; + break; + default: + tcap_send_error("CSL dialogue encode error. Can not recognize dialogue type"); + return 0; + break; + } + asn_encode(content,&asn_buf); + len = add_tlv("8",0,temp_data,0x20,&asn_buf); + if (un_flag == 1) // unidirectional dialogue + len = add_tlv("8.6-1",7,Undialogue_As_ID,0x00,&asn_buf); + else + len = add_tlv("8.6-1",7,Dialogue_As_ID,0x00,&asn_buf); + len = add_tlv("8.0-2",len1,temp_data,0x0a0,&asn_buf); + return len; +} + +int extract_component(struct CSLcmp_struct *cmp_ptr,u8 *data_buf,u32 proc,int *section_len) // extract component portion +{ + ASN_BUF asn_buf; + int len,len1=0,len2=0; + u8 temp_buf[TCAP_BUF_LEN],temp_buf1[TCAP_BUF_LEN]; + u8 tag1; + char tlv1[32]; + struct TCInvoke_struct *invoke_ptr; + struct TCResult_struct *result_ptr; + struct TCUError_struct *uerror_ptr; + struct TCReject_struct *reject_ptr; + int result; + u8 tag_class; + u16 tag_code; + + cmp_ptr->dialogue_id = proc; + cmp_ptr->invoke_id = 0xff; + cmp_ptr->message_flag = INDICATE; + result = asn_decode_v2(data_buf,1,section_len,&asn_buf); + if (*section_len == -1) + { + tcap_send_error("CSL component decode length error. ASN.1 structure is error"); + return 0; // 0 indicate that the syntax is error + } + if (result == -1) + tcap_send_error("CSL component decode error. ASN.1 structure is error"); + + len1 = GetAnyTLV("1",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get invoke + if (len1 == -1) + { + len1 = GetAnyTLV("9",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Invoke_L_Ansi + if (len1 == -1) + len1 = GetAnyTLV("13",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Invoke_NL_Ansi + } + if (len1 != -1) // has invoke + { + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][15] ++; + if (tag_code == 1) + cmp_ptr->message_type = Invoke; + else if (tag_code == 9) + cmp_ptr->message_type = Invoke_L_Ansi; + else + cmp_ptr->message_type = Invoke_NL_Ansi; + invoke_ptr = (TCInvoke_struct *) &cmp_ptr->cmp_prim.tc_invoke; + if (tag_class != ANSI_TAG_CLASS_CONS) + { + len = get_tlv("1.2-1",temp_buf,&asn_buf); // get invoke id + if (len != 1) // has no invoke id + { + tcap_send_error("CSL component decode error. Invoke primitive lack invoke id"); + return 0; + } + len2 += 3; + cmp_ptr->invoke_id = temp_buf[0]; + tag1 = 2; + len = get_tlv("1.0",temp_buf,&asn_buf); // get linked id + if (len != -1) + { + if (len != 1) + { + tcap_send_error("CSL component decode error. Invoke primitive has error linked id"); + return 0; + } + //invoke_ptr->linkedid_flag = 1; + invoke_ptr->linked_id = temp_buf[0]; + tag1 ++; + len2 += 3; + } + sprintf(tlv1,"1.2-%d\n",tag1); + len = get_tlv(tlv1,temp_buf,&asn_buf); // get operation code + if (len != 1) // has no operation code + { + len = get_tlv("1.6",temp_buf,&asn_buf); + if (len != 1) + { + tcap_send_error("CSL component decode error. Invoke primitive lack operation code"); + return 0; + } + } + invoke_ptr->operation_code = temp_buf[0]; + len2 += 3; + } + else + { + if (tag_code == 9) + len = get_tlv("9.15",temp_buf,&asn_buf); // get invoke id + else + len = get_tlv("13.15",temp_buf,&asn_buf); + if (len == -1) // has no invoke id + { // Mandatory when Correlation ID present or if reply expected + tcap_send_error("CSL component decode error. Ansi Invoke primitive lack invoke id"); + return 0; + } + else + { + len2 += 3; + cmp_ptr->invoke_id = temp_buf[0]; + if (len == 2) + { + //invoke_ptr->linkedid_flag = 1; + invoke_ptr->linked_id = temp_buf[1]; + len2++; + } + } + if (tag_code == 9) + { + len = get_tlv("9.17",temp_buf,&asn_buf); // get private operation code + if (len != -1) + invoke_ptr->operation_domain = TYPE_PRIVATE; + else + { + len = get_tlv("9.16",temp_buf,&asn_buf); // get national operation code + if (len != -1) + invoke_ptr->operation_domain = TYPE_NATIONAL; + } + } + else + { + len = get_tlv("13.17",temp_buf,&asn_buf); // get private operation code + if (len != -1) + invoke_ptr->operation_domain = TYPE_PRIVATE; + else + { + len = get_tlv("13.16",temp_buf,&asn_buf); // get national operation code + if (len != -1) + invoke_ptr->operation_domain = TYPE_NATIONAL; + } + } + if (len == -1) + { + tcap_send_error("CSL component decode error. Ansi Invoke primitive lack operation code"); + return 0; + } + invoke_ptr->operation_family = temp_buf[0]; + invoke_ptr->operation_code = temp_buf[1]; + len2 += 4; + } + if (len1 > len2) + { + invoke_ptr->parameter_len = len1 - len2; + memcpy(invoke_ptr->parameter,temp_buf1+len2,len1-len2); + } + else + invoke_ptr->parameter_len = 0; + return 1; + } + + len = GetAnyTLV("2",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get return result + if (len == -1) + { + len = GetAnyTLV("7",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get return result not last + if (len == -1) + { + len = GetAnyTLV("10",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Result_L_Ansi + if (len == -1) + len = GetAnyTLV("14",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Result_NL_Ansi + } + } + if (len != -1) // has return result + { + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][16] ++; + if (tag_code == 2) + cmp_ptr->message_type = Result_L; + else if (tag_code == 7) + cmp_ptr->message_type = Result_NL; + else if (tag_code == 10) + cmp_ptr->message_type = Result_L_Ansi; + else + cmp_ptr->message_type = Result_NL_Ansi; + result_ptr = (TCResult_struct *) &cmp_ptr->cmp_prim.tc_result; + if (tag_class != ANSI_TAG_CLASS_CONS) + { + len = get_tlv("2.2",temp_buf,&asn_buf); // get invoke id + if (len != 1) // has no invoke id + { + tcap_send_error("CSL component decode error. Result last primitive lack invoke id"); + return 0; + } + cmp_ptr->invoke_id = temp_buf[0]; + len1 = get_tlv("2.16",temp_buf,&asn_buf); // get SEQUENCE + if (len1 != -1) + { + len = get_tlv("2.16.2",temp_buf,&asn_buf); // operation code, just one byte + if (len != 1) + { + len = get_tlv("2.16.6",temp_buf,&asn_buf); + if (len != 1) + { + tcap_send_error("CSL component decode error. Result primitive lack operation code"); + return 0; + } + } + result_ptr->operation_flag = 1; + result_ptr->operation_code = temp_buf[0]; + if (len1 <= 3) + { + result_ptr->parameter_len = 0; + tcap_send_error("CSL component decode error. Result primitive lack parameter"); + return 0; + } + len = len1 - 3; + result_ptr->parameter_len = len; + memcpy(result_ptr->parameter,temp_buf+3,len); + } + return 1; + } + else + { + if (tag_code == 10) + len1 = get_tlv("10.15",temp_buf,&asn_buf); // get invoke id + else + len1 = get_tlv("14.15",temp_buf,&asn_buf); + if (len1 != 1) // has no invoke id + { + tcap_send_error("CSL component decode error. Ansi return result primitive lack invoke id"); + return 0; + } + else + { + cmp_ptr->invoke_id = temp_buf[0]; + len2 += 3; + } + if (len > len2) + { + result_ptr->parameter_len = len - len2; + memcpy(result_ptr->parameter,temp_buf1+len2,len-len2); + } + return 1; + } + } + + len1 = GetAnyTLV("3",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get return error + if (len1 == -1) + len1 = GetAnyTLV("11",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Error_Ansi + if (len1 != -1) // has return error + { + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][17] ++; + if (tag_code == 3) + cmp_ptr->message_type = Error; + else + cmp_ptr->message_type = Error_Ansi; + uerror_ptr = (TCUError_struct *) &cmp_ptr->cmp_prim.tc_uerror; + if (tag_class != ANSI_TAG_CLASS_CONS) + { + len = get_tlv("3.2-1",temp_buf,&asn_buf); // get invoke id + if (len != 1) // has no invoke id + { + tcap_send_error("CSL component decode error. Error primitive lack invoke id"); + return 0; + } + cmp_ptr->invoke_id = temp_buf[0]; + len2 = 3; + len = get_tlv("3.2-2",temp_buf,&asn_buf); // get error code + if (len == 1) // success + uerror_ptr->error_type = Local_Error_Code; + else + { + len = get_tlv("3.6",temp_buf,&asn_buf); + if (len != 1) + { + tcap_send_error("CSL component decode error. Error primitive lack error code"); + return 0; + } + uerror_ptr->error_type = Global_Error_Code; + } + uerror_ptr->error_code = temp_buf[0]; + len2 = 3; + if (len1 > len2) + { + uerror_ptr->parameter_len = len1 - len2; + memcpy(uerror_ptr->parameter,temp_buf1+len2,len1-len2); + } + else + uerror_ptr->parameter_len = 0; + return 1; + } + else + { + len = get_tlv("11.15",temp_buf,&asn_buf); // get invoke id + if (len != 1) // has no invoke id + { + tcap_send_error("CSL component decode error. Ansi return error primitive lack invoke id"); + return 0; + } + else + { + cmp_ptr->invoke_id = temp_buf[0]; + len2 += 3; + } + len = get_tlv("11.20",temp_buf,&asn_buf); // get private error code + if (len != -1) + uerror_ptr->error_type = TYPE_PRIVATE; + else + { + len = get_tlv("11.19",temp_buf,&asn_buf); // get national error code + if (len != -1) + uerror_ptr->error_type = TYPE_NATIONAL; + } + if (len != 1) + { + tcap_send_error("CSL component decode error. Ansi Error primitive lack error code"); + return 0; + } + else + { + uerror_ptr->error_code = temp_buf[0]; + len2 += 3; + } + if (len1 > len2) + { + uerror_ptr->parameter_len = len1 - len2; + memcpy(uerror_ptr->parameter,temp_buf1+len2,len1-len2); + } + else + uerror_ptr->parameter_len = 0; + return 1; + } + } + + len1 = GetAnyTLV("4",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get reject + if (len1 == -1) + len1 = GetAnyTLV("12",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Reject_Ansi + if (len1 != -1) // has reject + { + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][18] ++; + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][74] ++; + if (tag_code == 4) + cmp_ptr->message_type = Reject; + else + cmp_ptr->message_type = Reject_Ansi; + reject_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject; + if (tag_class != ANSI_TAG_CLASS_CONS) + { + len = get_tlv("4.2-1",temp_buf,&asn_buf); // get invoke id + if (len != 1) // has no invoke id + { + len = get_tlv("4.5",temp_buf,&asn_buf); // get Invoke_ID_NULL + if (len != 1) + { + tcap_send_error("CSL component decode error. Reject primitive lack invoke id"); + return 0; + } + temp_buf[0] = 0xff; + } + cmp_ptr->invoke_id = temp_buf[0]; + len = get_tlv("4.0",temp_buf,&asn_buf); // get general problem + if (len == 1) + { + reject_ptr->problem_type = General_Problem; + reject_ptr->problem_code = temp_buf[0]; + switch (temp_buf[0]) + { + case General_Problem_UC: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][30] ++; + break; + case General_Problem_MC: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][31] ++; + break; + case General_Problem_BSC: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][32] ++; + break; + default: + break; + } + return 1; + } + len = get_tlv("4.1",temp_buf,&asn_buf); // get invoke problem + if (len == 1) + { + reject_ptr->problem_type = Invoke_Problem; + reject_ptr->problem_code = temp_buf[0]; + switch (temp_buf[0]) + { + case Invoke_Problem_ULID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][33] ++; + break; + case Invoke_Problem_DIID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][38] ++; + break; + case Invoke_Problem_UO: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][39] ++; + break; + case Invoke_Problem_MP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][40] ++; + break; + case Invoke_Problem_IR: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][41] ++; + break; + case Invoke_Problem_LRU: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][42] ++; + break; + case Invoke_Problem_ULO: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][43] ++; + break; + default: + break; + } + return 1; + } + len = get_tlv("4.2-2",temp_buf,&asn_buf); // get return result problem + if (len == 1) + { + reject_ptr->problem_type = Return_Result; + reject_ptr->problem_code = temp_buf[0]; + switch (temp_buf[0]) + { + case Return_Result_UIID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][34] ++; + break; + case Return_Result_RRU: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][35] ++; + break; + case Return_Result_MP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][46] ++; + break; + default: + break; + } + return 1; + } + len = get_tlv("4.3",temp_buf,&asn_buf); // get return error problem + if (len == 1) + { + reject_ptr->problem_type = Return_Error; + reject_ptr->problem_code = temp_buf[0]; + switch (temp_buf[0]) + { + case Return_Error_UIID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][36] ++; + break; + case Return_Error_REU: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][37] ++; + break; + case Return_Error_URE: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][44] ++; + break; + case Return_Error_UEE: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][45] ++; + break; + case Return_Error_MP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][47] ++; + break; + default: + break; + } + return 1; + } + tcap_send_error("CSL component decode error. Reject primitive lack problem type"); + return 0; + } + else + { + len = get_tlv("12.15",temp_buf,&asn_buf); // get invoke id + if (len != 1) // has no invoke id + { + tcap_send_error("CSL component decode error. Ansi Reject primitive lack invoke id"); + return 0; + } + else + { + cmp_ptr->invoke_id = temp_buf[0]; + len2 += 3; + } + len = get_tlv("12.21",temp_buf,&asn_buf); // get problem code + if (len != 2) + { + tcap_send_error("CSL component decode error. Ansi reject primitive lack problem code"); + return 0; + } + else + { + reject_ptr->problem_type = temp_buf[0]; + reject_ptr->problem_code = temp_buf[1]; + len2 += 4; + } + if (len1 > len2) + { + reject_ptr->parameter_len = len1 - len2; + memcpy(reject_ptr->parameter,temp_buf1+len2,len1-len2); + } + else + reject_ptr->parameter_len = 0; + switch (temp_buf[0]) + { + case General_Problem_Ansi: + switch (temp_buf[1]) + { + case General_Problem_UC_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][30] ++; + break; + case General_Problem_MC_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][31] ++; + break; + case General_Problem_BSC_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][32] ++; + break; + default: + break; + } + return 1; + break; + case Invoke_Problem_Ansi: + switch (temp_buf[1]) + { + case Invoke_Problem_ULID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][33] ++; + break; + case Invoke_Problem_DIID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][38] ++; + break; + case Invoke_Problem_UO_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][39] ++; + break; + case Invoke_Problem_MP_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][40] ++; + break; + default: + break; + } + return 1; + break; + case Return_Result_Ansi: + switch (temp_buf[1]) + { + case Return_Result_UIID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][34] ++; + break; + case Return_Result_RRU_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][35] ++; + break; + case Return_Result_MP_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][46] ++; + break; + default: + break; + } + return 1; + break; + case Return_Error_Ansi: + switch (temp_buf[1]) + { + case Return_Error_UIID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][36] ++; + break; + case Return_Error_REU_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][37] ++; + break; + case Return_Error_URE_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][44] ++; + break; + case Return_Error_UEE_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][45] ++; + break; + case Return_Error_MP_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][47] ++; + break; + default: + break; + } + return 1; + break; + case Transaction_Ansi: + return 1; + break; + } + tcap_send_error("CSL component decode error. Ansi Reject primitive lack problem type"); + return 0; + } + } + + tcap_send_error("CSL component decode error. Can not recognize message type"); + return 0; +} + +u8 assemble_param(u8 *data_buf,u8 *string,u8 str_len,u8 opr_code,u8 opr_family,u8 opr_domain,u8 proto_type) +{ + ASN_BUF asn_buf; + int len = 0; + u8 temp_buf[8]; + + asn_encode(data_buf,&asn_buf); + if (!proto_type) + len = add_tlv("2",1,&opr_code,0x00,&asn_buf); + else + { + temp_buf[0] = opr_family; + temp_buf[1] = opr_code; + if (opr_domain) + len = add_tlv("17",2,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + len = add_tlv("16",2,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf); + } + if (str_len != 0) + { + memcpy(data_buf+len,string,str_len); + len += str_len; + } + return len; +} + +int assemble_component(u8 *string,struct CSLcmp_struct *cha_ptr) // assemble component portion +{ + ASN_BUF asn_buf; + u8 temp_data[TCAP_BUF_LEN],temp_str[TCAP_BUF_LEN]; + u32 len = 0,temp_len; + struct TCInvoke_struct *invoke_ptr; + struct TCResult_struct *result_ptr; + struct TCUError_struct *uerror_ptr; + struct TCReject_struct *reject_ptr; + u8 proto_type; + + if ((cha_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + switch (cha_ptr->message_type) + { + case Invoke: + case Invoke_L_Ansi: + case Invoke_NL_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][10] ++; + invoke_ptr = (TCInvoke_struct *) &cha_ptr->cmp_prim.tc_invoke; + asn_encode(temp_data,&asn_buf); + if (!proto_type) + { + temp_len = add_tlv("2-1",1,&cha_ptr->invoke_id,0x00,&asn_buf); + if (invoke_ptr->linkedid_flag ==1) // has linked id + temp_len = add_tlv("0-2",1,&invoke_ptr->linked_id,0x80,&asn_buf); + len = assemble_param(string,invoke_ptr->parameter,invoke_ptr->parameter_len, + invoke_ptr->operation_code,invoke_ptr->operation_family,invoke_ptr->operation_domain,proto_type); + memcpy(temp_data+temp_len,string,len); + temp_len += len; + asn_encode(string,&asn_buf); + len = add_tlv("1",temp_len,temp_data,0x0a0,&asn_buf); + } + else + { + temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf); + len = assemble_param(string,invoke_ptr->parameter,invoke_ptr->parameter_len, + invoke_ptr->operation_code,invoke_ptr->operation_family,invoke_ptr->operation_domain,proto_type); + memcpy(temp_data+temp_len,string,len); + temp_len += len; + asn_encode(string,&asn_buf); + if (cha_ptr->message_type == Invoke_L_Ansi) + len = add_tlv("9",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf); + else + len = add_tlv("13",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf); + } + break; + case Result_L: + case Result_NL: + case Result_L_Ansi: + case Result_NL_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][11] ++; + result_ptr = (TCResult_struct *) &cha_ptr->cmp_prim.tc_result; + asn_encode(temp_data,&asn_buf); + if (!proto_type) + { + temp_len = add_tlv("2",1,&cha_ptr->invoke_id,0x00,&asn_buf); + if (result_ptr->parameter_len > 0) + { + len = assemble_param(temp_str,result_ptr->parameter,result_ptr->parameter_len, + result_ptr->operation_code,result_ptr->operation_family,result_ptr->operation_domain,proto_type); + asn_encode(string,&asn_buf); + len = add_tlv("16",len,temp_str,0x20,&asn_buf); + } + memcpy(temp_data+temp_len,string,len); + temp_len += len; + asn_encode(string,&asn_buf); + if (cha_ptr->message_type == Result_L) + len = add_tlv("2",temp_len,temp_data,0x0a0,&asn_buf); // add result last + else + len = add_tlv("7",temp_len,temp_data,0x0a0,&asn_buf); // add result not last + } + else + { + temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf); + memcpy(temp_data+temp_len,result_ptr->parameter,result_ptr->parameter_len); + temp_len += result_ptr->parameter_len; + asn_encode(string,&asn_buf); + if (cha_ptr->message_type == Result_L_Ansi) + len = add_tlv("10",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf); + else + len = add_tlv("14",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf); + } + break; + case Error: + case Error_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][12] ++; + uerror_ptr = (TCUError_struct *) &cha_ptr->cmp_prim.tc_uerror; + asn_encode(temp_data,&asn_buf); + if (!proto_type) + { + temp_len = add_tlv("2",1,&cha_ptr->invoke_id,0x00,&asn_buf); + asn_encode(string,&asn_buf); + if (uerror_ptr->error_type == Local_Error_Code) + len = add_tlv("2",1,&uerror_ptr->error_code,0x00,&asn_buf); + else + len = add_tlv("6",1,&uerror_ptr->error_code,0x00,&asn_buf); + if (uerror_ptr->parameter_len != 0) + { + memcpy(string+len,uerror_ptr->parameter,uerror_ptr->parameter_len); + len += uerror_ptr->parameter_len; + } + memcpy(temp_data+temp_len,string,len); + temp_len += len; + asn_encode(string,&asn_buf); + len = add_tlv("3",temp_len,temp_data,0x0a0,&asn_buf); // add result error + } + else + { + temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf); + if (uerror_ptr->error_type) + temp_len = add_tlv("20",1,&uerror_ptr->error_code,ANSI_TAG_CLASS_PRIM,&asn_buf); + else + temp_len = add_tlv("19",1,&uerror_ptr->error_code,ANSI_TAG_CLASS_PRIM,&asn_buf); + memcpy(temp_data+temp_len,uerror_ptr->parameter,uerror_ptr->parameter_len); + temp_len += uerror_ptr->parameter_len; + asn_encode(string,&asn_buf); + len = add_tlv("11",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf); + } + break; + case Reject: + case Reject_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][13] ++; + reject_ptr = (TCReject_struct *) &cha_ptr->cmp_prim.tc_reject; + if (!proto_type) + asn_encode(string,&asn_buf); + else + asn_encode(temp_data,&asn_buf); + if (!proto_type) + { + len = add_tlv("4",0,temp_data,0x0a0,&asn_buf); // add result reject + if (cha_ptr->invoke_id != 0xff) + len = add_tlv("4.2-1",1,&cha_ptr->invoke_id,0x00,&asn_buf); + else + len = add_null("4.5-1",0x00,&asn_buf); + switch (reject_ptr->problem_type) + { + case General_Problem: + len = add_tlv("4.0-2",1,&reject_ptr->problem_code,0x80,&asn_buf); + switch (reject_ptr->problem_code) + { + case General_Problem_UC: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][53] ++; + break; + case General_Problem_MC: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][54] ++; + break; + case General_Problem_BSC: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][55] ++; + break; + default: + break; + } + break; + case Invoke_Problem: + len = add_tlv("4.1-2",1,&reject_ptr->problem_code,0x80,&asn_buf); + switch (reject_ptr->problem_code) + { + case Invoke_Problem_DIID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][61] ++; + break; + case Invoke_Problem_UO: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][62] ++; + break; + case Invoke_Problem_MP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][63] ++; + break; + case Invoke_Problem_IR: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][64] ++; + break; + case Invoke_Problem_ULID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][56] ++; + break; + case Invoke_Problem_LRU: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][65] ++; + break; + case Invoke_Problem_ULO: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][66] ++; + break; + default: + break; + } + break; + case Return_Result: + len = add_tlv("4.2-2",1,&reject_ptr->problem_code,0x80,&asn_buf); + switch (reject_ptr->problem_code) + { + case Return_Result_UIID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][57] ++; + break; + case Return_Result_RRU: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][58] ++; + break; + case Return_Result_MP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][69] ++; + break; + default: + break; + } + break; + default: + len = add_tlv("4.3-2",1,&reject_ptr->problem_code,0x80,&asn_buf); + switch (reject_ptr->problem_code) + { + case Return_Error_UIID: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][59] ++; + break; + case Return_Error_REU: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][60] ++; + break; + case Return_Error_URE: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][67] ++; + break; + case Return_Error_UEE: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][68] ++; + break; + case Return_Error_MP: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][70] ++; + break; + default: + break; + } + break; + } + } + else + { + temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf); + temp_str[0] = reject_ptr->problem_type; + temp_str[1] = reject_ptr->problem_code; + temp_len = add_tlv("21",2,temp_str,ANSI_TAG_CLASS_PRIM,&asn_buf); + memcpy(temp_data+temp_len,reject_ptr->parameter,reject_ptr->parameter_len); + temp_len += reject_ptr->parameter_len; + asn_encode(string,&asn_buf); + len = add_tlv("12",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf); + switch (reject_ptr->problem_type) + { + case General_Problem_Ansi: + switch (reject_ptr->problem_code) + { + case General_Problem_UC_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][53] ++; + break; + case General_Problem_MC_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][54] ++; + break; + case General_Problem_BSC_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][55] ++; + break; + default: + break; + } + break; + case Invoke_Problem_Ansi: + switch (reject_ptr->problem_code) + { + case Invoke_Problem_DIID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][61] ++; + break; + case Invoke_Problem_UO_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][62] ++; + break; + case Invoke_Problem_MP_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][63] ++; + break; + case Invoke_Problem_ULID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][56] ++; + break; + default: + break; + } + break; + case Return_Result_Ansi: + switch (reject_ptr->problem_code) + { + case Return_Result_UIID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][57] ++; + break; + case Return_Result_RRU_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][58] ++; + break; + case Return_Result_MP_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][69] ++; + break; + default: + break; + } + break; + default: + switch (reject_ptr->problem_code) + { + case Return_Error_UIID_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][59] ++; + break; + case Return_Error_REU_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][60] ++; + break; + case Return_Error_URE_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][67] ++; + break; + case Return_Error_UEE_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][68] ++; + break; + case Return_Error_MP_Ansi: + tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][70] ++; + break; + default: + break; + } + break; + } + } + break; + default: + tcap_send_error("CSL component encode error. Can not recognize component type"); + return 0; + break; + } + return len; +} +/*@end@*/ diff --git a/plat/tcap/src/tcap_fsm.c b/plat/tcap/src/tcap_fsm.c new file mode 100644 index 0000000..5f5641b --- /dev/null +++ b/plat/tcap/src/tcap_fsm.c @@ -0,0 +1,3102 @@ +/* TCAP c program file */ +/* written by Liu Zhiguo 2002-08-06 */ +/* Version 2.0 */ +/* -------------------------------- */ +#include "../../sccp/src/include/sccp.h" +#include "./include/tcap_public.h" +#include "./include/idmanage.h" +#include "./include/tcap_struct.h" +#include "./include/tcap_m.h" + +typedef struct id_struct +{ + u32 current_did; + u32 count_did; + u32 count_did_occupied; + u32 count_did_max; + u32 count_did_tmp; + u8 dialogue_id[MAX_DIALOGUEID]; + u8 current_iid[MAX_DIALOGUEID]; + u8 invoke_id[MAX_DIALOGUEID][MAX_INVOKEID]; +}id_struct; + +extern struct id_struct *ID_ptr; + +/*@ignore@*/ +static struct tcapdebug_struct *debug_ptr; +void print_msg(u8 *ptr, u16 len); +extern int sclc_receive(SCLC_MSG * pmsg, BYTE usertype); +extern int sclc_send(SCLC_MSG * pmsg); +extern u8 get_transfer_iid(int did, u8 iid); +extern u8 transfer_iid(int did, u8 iid); +extern int xap_get_est_timer(); +extern u32 tcap_dlg_h[MAX_DIALOGUEID]; +extern u32 tcap_dlg_t[MAX_DIALOGUEID]; + +/* protocol version */ +static u8 Version_1[2] = {0x07,0x80}; +static u8 Version_Ansi = 0x01; +void tcap_set_local_ip() +{ + char hostname[64]; + struct hostent *pcn; + struct in_addr *hostip_add; + + if ((gethostname(hostname,-1)) == -1) + { + printf("get host name fail\n"); + exit(0); + } + pcn = gethostbyname(hostname); + if (pcn == NULL) + { + printf("get host name fail!\n"); + exit(0); + } + ((struct in_addr *)(*pcn->h_addr_list))->s_addr = GetLocalIP(); + hostip_add = (struct in_addr *) (*pcn->h_addr_list); + debug_ptr->local_ip = hostip_add->s_addr; + //debug_ptr->peer_ip = debug_ptr->local_ip + 0x10000; + /* like : mss0=172.18.98.1-0x016212ac, mss1=172.18.99.1-0x016312ac */ +} + +void tcapvm_init(u_long localip, u_long peerip) // init share memory +{ + int shm_id; + + /* init share memory */ + if ((shm_id = shmget(TCAP_KEY+wxc2_get_shm_offset(),sizeof(tcapbuf_struct),TCAP_PERM|IPC_CREAT)) == -1) + { + printf("can not init tcap share memory"); + exit(0); + } + if ((tcap_ptr = (tcapbuf_struct *)shmat(shm_id,(char *)0,0)) == (tcapbuf_struct *) -1) + { + printf("can not init tcap share memory"); + exit(0); + } + memset(tcap_ptr,0,sizeof(tcapbuf_struct)); + debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + if(localip>0) + { + debug_ptr->local_ip = localip; + debug_ptr->peer_ip = peerip; + } + else + { + tcap_set_local_ip(); + } +} + +void get_dlgpdu(struct dlgPDU_struct *pdu_ptr,struct dlgport_struct *port_ptr) +{ + switch (pdu_ptr->dialogue_type) + { + case PDU_AARQ: + port_ptr->acn_len = pdu_ptr->pdu_union.aarq.acn_len; + memcpy(port_ptr->acn,pdu_ptr->pdu_union.aarq.acn,port_ptr->acn_len); + port_ptr->user_info_len = pdu_ptr->pdu_union.aarq.user_info_len; + memcpy(port_ptr->user_info,pdu_ptr->pdu_union.aarq.user_info,port_ptr->user_info_len); + break; + case PDU_AARE: + port_ptr->acn_len = pdu_ptr->pdu_union.aare.acn_len; + memcpy(port_ptr->acn,pdu_ptr->pdu_union.aare.acn,port_ptr->acn_len); + port_ptr->user_info_len = pdu_ptr->pdu_union.aare.user_info_len; + memcpy(port_ptr->user_info,pdu_ptr->pdu_union.aare.user_info,port_ptr->user_info_len); + break; + case PDU_ABRT: + port_ptr->acn_len = 0; + port_ptr->user_info_len = pdu_ptr->pdu_union.abrt.user_info_len; + memcpy(port_ptr->user_info,pdu_ptr->pdu_union.abrt.user_info,port_ptr->user_info_len); + break; + case PDU_ASUDT: + port_ptr->acn_type = pdu_ptr->pdu_union.asudt.acn_type; + port_ptr->acn_len = pdu_ptr->pdu_union.asudt.acn_len; + memcpy(port_ptr->acn,pdu_ptr->pdu_union.asudt.acn,port_ptr->acn_len); + port_ptr->user_info_len = pdu_ptr->pdu_union.asudt.user_info_len; + memcpy(port_ptr->user_info,pdu_ptr->pdu_union.asudt.user_info,port_ptr->user_info_len); + port_ptr->security_context_type = pdu_ptr->pdu_union.asudt.security_context_type; + port_ptr->security_context_len = pdu_ptr->pdu_union.asudt.security_context_len; + memcpy(port_ptr->security_context,pdu_ptr->pdu_union.asudt.security_context,port_ptr->security_context_len); + port_ptr->confidential_info_len = pdu_ptr->pdu_union.asudt.confidential_info_len; + memcpy(port_ptr->confidential_info,pdu_ptr->pdu_union.asudt.confidential_info,port_ptr->confidential_info_len); + break; + default: + tcap_send_error("CSL error. Dialogue PDU type error"); + break; + } +} + +void set_dlgpdu(struct dlgPDU_struct *pdu_ptr,struct dlgport_struct *port_ptr) +{ + if (port_ptr->user_info_len > TCAP_USERINFO_LEN) + port_ptr->user_info_len = TCAP_USERINFO_LEN; + if (port_ptr->acn_len > TCAP_ACN_LEN) + port_ptr->acn_len = TCAP_ACN_LEN; + if (port_ptr->security_context_len > TCAP_SECURITY_CONTEXT_LEN) + port_ptr->security_context_len = TCAP_SECURITY_CONTEXT_LEN; + if (port_ptr->confidential_info_len > TCAP_CONFIDENTIAL_INFO_LEN) + port_ptr->confidential_info_len = TCAP_CONFIDENTIAL_INFO_LEN; + + switch (pdu_ptr->dialogue_type) + { + case PDU_AARQ: + pdu_ptr->pdu_union.aarq.acn_len = port_ptr->acn_len; + memcpy(pdu_ptr->pdu_union.aarq.acn,port_ptr->acn,port_ptr->acn_len); + pdu_ptr->pdu_union.aarq.user_info_len = port_ptr->user_info_len; + memcpy(pdu_ptr->pdu_union.aarq.user_info,port_ptr->user_info,port_ptr->user_info_len); + break; + case PDU_AARE: + pdu_ptr->pdu_union.aare.acn_len = port_ptr->acn_len; + memcpy(pdu_ptr->pdu_union.aare.acn,port_ptr->acn,port_ptr->acn_len); + pdu_ptr->pdu_union.aare.user_info_len = port_ptr->user_info_len; + memcpy(pdu_ptr->pdu_union.aare.user_info,port_ptr->user_info,port_ptr->user_info_len); + break; + case PDU_ABRT: + pdu_ptr->pdu_union.abrt.user_info_len = port_ptr->user_info_len; + memcpy(pdu_ptr->pdu_union.abrt.user_info,port_ptr->user_info,port_ptr->user_info_len); + break; + case PDU_ASUDT: + pdu_ptr->pdu_union.asudt.acn_type = port_ptr->acn_type; + pdu_ptr->pdu_union.asudt.acn_len = port_ptr->acn_len; + memcpy(pdu_ptr->pdu_union.asudt.acn,port_ptr->acn,port_ptr->acn_len); + pdu_ptr->pdu_union.asudt.user_info_len = port_ptr->user_info_len; + memcpy(pdu_ptr->pdu_union.asudt.user_info,port_ptr->user_info,port_ptr->user_info_len); + pdu_ptr->pdu_union.asudt.security_context_type = port_ptr->security_context_type; + pdu_ptr->pdu_union.asudt.security_context_len = port_ptr->security_context_len; + memcpy(pdu_ptr->pdu_union.asudt.security_context,port_ptr->security_context,port_ptr->security_context_len); + pdu_ptr->pdu_union.asudt.confidential_info_len = port_ptr->confidential_info_len; + memcpy(pdu_ptr->pdu_union.asudt.confidential_info,port_ptr->confidential_info,port_ptr->confidential_info_len); + break; + default: + memset(pdu_ptr,0,sizeof(dlgPDU_struct)); + break; + } +} + +void ism_terminate(u32 did,u8 iid) +{ + struct tcapvm_struct *vm_ptr; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[did]; + vm_ptr->ism_data[iid].ism_state = TCAP_INIT; +} + +void tcap_terminate(u32 proc) +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + memset(&vm_ptr->ism_data,0,MAX_TEMPINVOKEID*sizeof(ismvm_data)); + int_ptr->cmprecv_head = int_ptr->cmprecv_tail = 0; + int_ptr->cmpsend_head = int_ptr->cmpsend_tail = 0; +} + +void tcap_clear_fsm(u32 proc) +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + vm_ptr->peer_tid = 0; + vm_ptr->tcap_timer = 0; + vm_ptr->ac_mode = 0; + vm_ptr->proto_type = 0; + vm_ptr->sccp_class = 0; + + ID_ptr->current_iid[proc] = 0; //added by yingmin 2007-12-6 + + vm_ptr->tcaprecv_head = vm_ptr->tcaprecv_tail = 0; + int_ptr->dlgrecv_head = int_ptr->dlgrecv_tail = 0; + int_ptr->dlgsend_head = int_ptr->dlgsend_tail = 0; + tcap_dlg_h[proc] = 0; + tcap_dlg_t[proc] = 0; + debug_ptr->watch_dog[190]++; + tcap_terminate(proc); +} + +u8 tcap_from_sccp(struct SCLC_MSG *data_ptr) //receive data from sccp +{ + char buf[4*TCAP_BUF_LEN]; + char *cur_time; + + if (!sclc_receive(data_ptr,0)) + return 0; + if (debug_ptr->sccp_switch == 1 && debug_ptr->send_control == 0) + { + cur_time = GetAsciiTime(); + sprintf(buf,"sccp->tcap, len: %d, time: %s\r",data_ptr->msglen,cur_time); + HexToDisplay((u8 *)buf+strlen(buf),data_ptr->msg,data_ptr->msglen); + strcat(buf,"\r\n\r\n"); + tcap_send_ascout(buf); + } + debug_ptr->watch_dog[0] ++; + return 1; +} + +u8 tcap_get_sls(u32 tid) +{ + u8 ii; + u8 sls; + + ii = (tid >> 16) & 0xff; + if (ii % 2) // odd + sls = (((tid + 1)/2) * 2 + 1) % TCAP_SLS_NUM; + else + sls = (((tid + 1)/2) * 2) % TCAP_SLS_NUM; + return sls; +} + +void tcap_set_sccp_class(u32 did) +{ + struct tcapvm_struct *vm_ptr; + + if(did>=MAX_DIALOGUEID) return; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[did]; + vm_ptr->sccp_class = 1; +} + +void tcap_to_sccp(struct TSL_struct *tsl_data,u8 sls,u8 flag) // send data to sccp +{ + struct SCLC_MSG sccp_data; + char buf[4*TCAP_BUF_LEN]; + char *cur_time; + + if (!tsl_message_encode(&sccp_data,tsl_data,flag)) // encode the tsl message + { + debug_ptr->watch_dog[1] ++; + return; + } + if (debug_ptr->sccp_switch == 1 && debug_ptr->send_control == 0) + { + cur_time = GetAsciiTime(); + sprintf(buf,"tcap->sccp, len: %d, time: %s\r",sccp_data.msglen,cur_time); + HexToDisplay((u8 *)buf+strlen(buf),sccp_data.msg,sccp_data.msglen); + strcat(buf,"\r\n\r\n"); + tcap_send_ascout(buf); + } + if((tsl_data->message_type != Begin) && (sccp_data.src_addr.SSN != 247)) //MNP calling address neednot change + sccp_data.src_addr.RI = RI_GT; + if (flag == 1) + sccp_data.sls = 0x80; + else{ + sccp_data.sls = sls % TCAP_SLS_NUM; + sccp_data.sequence_control = 0; + } + sclc_send(&sccp_data); + debug_ptr->watch_dog[2] ++; +} + +void tcap_to_sccp_class(struct TSL_struct *tsl_data,u8 sls,u8 flag, u32 proc) // send data to sccp +{ + struct SCLC_MSG sccp_data; + char buf[4*TCAP_BUF_LEN]; + char *cur_time; + struct tcapvm_struct *vm_ptr; + + if(proc>=MAX_DIALOGUEID) return; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + + if (!tsl_message_encode(&sccp_data,tsl_data,flag)) // encode the tsl message + { + debug_ptr->watch_dog[1] ++; + return; + } + if (debug_ptr->sccp_switch == 1 && debug_ptr->send_control == 0) + { + cur_time = GetAsciiTime(); + sprintf(buf,"tcap->sccp, len: %d, time: %s\r",sccp_data.msglen,cur_time); + HexToDisplay((u8 *)buf+strlen(buf),sccp_data.msg,sccp_data.msglen); + strcat(buf,"\r\n\r\n"); + tcap_send_ascout(buf); + } + if((tsl_data->message_type != Begin) && (sccp_data.src_addr.SSN != 247)) //MNP calling address neednot change + sccp_data.src_addr.RI = RI_GT; + if (flag == 1) + sccp_data.sls = 0x80; + else{ + sccp_data.sls = sls % TCAP_SLS_NUM; + sccp_data.sequence_control = vm_ptr->sccp_class; + } + sclc_send(&sccp_data); + debug_ptr->watch_dog[2] ++; +} + +u8 check_resend(struct TSL_struct *tsl_ptr,u32 tid) +{ + u32 ii; + + ii = tid & 0xffff0000; + if (ii == (debug_ptr->local_ip & 0xffff0000))// owner data, do not need resend + return 0; + if(ii == (debug_ptr->peer_ip & 0xffff0000)) + { + ii = tid & 0x8000; + if (ii == 0) // resend data + tcap_to_sccp(tsl_ptr,0x80,1); + } + else + { + tcap_send_error("local ip chanage it back\r\n"); + tcap_set_local_ip(); + } + return 1; +} + +void tco_to_tsm(struct TSL_struct *tsl_data,u32 tid_flag) // send data to TSM +{ + struct tcapvm_struct *vm_ptr; + u8 head_flag; + u8 tail_flag; + u8 info_buf[1024]; + + if (tid_flag >= (tcap_ptr->grantdid)) + return; + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[tid_flag]; + head_flag = vm_ptr->tcaprecv_head; + tail_flag = vm_ptr->tcaprecv_tail; + if (((head_flag + 1) % MAX_TSL_BUF) == tail_flag) // buffer is full + { + if (debug_ptr->error_switch) + { + sprintf((char *)info_buf,"TSL error. TCO -> TSM buffer is full, dialogue id: %u",tid_flag); + tcap_send_error((char *)info_buf); + } + return; + } + /*added by Pierre, 2006-08-19 */ + if(tsl_data->message_type == Begin || + tsl_data->message_type == Continue) + { + vm_ptr->peer_tid_len = tsl_data->peer_tid_len; + } + memcpy(&vm_ptr->tsl_data[head_flag],tsl_data,sizeof(TSL_struct)); + vm_ptr->tcaprecv_head = (head_flag + 1) % MAX_TSL_BUF; +} + +void send_pabort_sccp(u8 tid_len,u32 tid,u8 reason,SCCP_ADDR *local_add,SCCP_ADDR *peer_add,u8 proto_type) +{ + struct TSL_struct tsl_data; + struct TRPAbort_struct *pabort_ptr; + u8 sls; + + if (tid == 0) + return; + if (proto_type == ANSI_TCAP) + tsl_data.message_type = P_Abort_Ansi; + else + tsl_data.message_type = P_Abort; + tsl_data.message_flag = REQUEST; + memcpy(&tsl_data.local_add,local_add,sizeof(SCCP_ADDR)); + memcpy(&tsl_data.peer_add,peer_add,sizeof(SCCP_ADDR)); + pabort_ptr = (TRPAbort_struct *) &tsl_data.tsl_prim.tr_pabort; + pabort_ptr->transaction_id = tid; + pabort_ptr->abort_reason = reason; + sls = tcap_get_sls(tid); + tsl_data.peer_tid_len = tid_len; + tcap_to_sccp(&tsl_data,sls,0); +} + +void send_pabort_tsm(u32 tid,u8 reason,u8 proto_type) +{ + struct TSL_struct tsl_data; + struct TRPAbort_struct *pabort_ptr; + + if (proto_type == ANSI_TCAP) + tsl_data.message_type = P_Abort_Ansi; + else + tsl_data.message_type = P_Abort; + tsl_data.message_flag = INDICATE; + pabort_ptr = (TRPAbort_struct *) &tsl_data.tsl_prim.tr_pabort; + pabort_ptr->transaction_id = tid; + pabort_ptr->abort_reason = reason; + + tco_to_tsm(&tsl_data,tid); +} + +void send_pabort_tcu(u32 did,u8 reason,u8 data_flag,u8 proto_type) +{ + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[did]; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[data_flag]; + if (proto_type) + csl_ptr->message_type = P_Abort_Ansi; + else + csl_ptr->message_type = P_Abort; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = did; + csl_ptr->dlg_prim.tc_pabort.pabort_reason = reason; + int_ptr->dlgrecv_head = (data_flag + 1) % MAX_TSL_BUF; +} + +void send_uabort_sccp(u32 proc,struct dlgPDU_struct *pdu_ptr,u8 proto_type,u8 uabort_info_len, u8 *uabort_info) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct tsl_data; + struct TRUAbort_struct *uabort_ptr; + u8 sls; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + if (vm_ptr->peer_tid == 0) + return; + if (!proto_type) + tsl_data.message_type = U_Abort; + else + tsl_data.message_type = U_Abort_Ansi; + tsl_data.message_flag = REQUEST; + memcpy(&tsl_data.local_add,&vm_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&tsl_data.peer_add,&vm_ptr->peer_add,sizeof(SCCP_ADDR)); + uabort_ptr = (TRUAbort_struct *) &tsl_data.tsl_prim.tr_uabort; + uabort_ptr->transaction_id = vm_ptr->peer_tid; + uabort_ptr->dialogue_len = 0; + uabort_ptr->dialogue_len = build_dp(uabort_ptr->dialogue,pdu_ptr,0,proto_type); + if (proto_type) + { + uabort_ptr->uabort_info_len = uabort_info_len; + memcpy(uabort_ptr->uabort_info,uabort_info,uabort_info_len); + } + sls = tcap_get_sls(vm_ptr->peer_tid); + tsl_data.peer_tid_len = vm_ptr->peer_tid_len; //modified by Pierre, 06-08-19 + tcap_to_sccp(&tsl_data,sls,0); +} + +u8 check_csldata(u32 proc) +{ + struct tcapint_struct *int_ptr; + //char info_str[1024]; + + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + if (int_ptr->dlgrecv_head == int_ptr->dlgrecv_tail) // dlg recv buffer is empty + { + if (int_ptr->cmprecv_head == int_ptr->cmprecv_tail) + return 1; + //debug_ptr->watch_dog[159]++; + //printf("check_csldata, cmprecv: %d, did: %d\n", int_ptr->cmp_recv[int_ptr->cmprecv_tail].message_type, proc); + //sprintf(info_str, "check_csldata, cmprecv: %d, did: %ld\n", int_ptr->cmp_recv[int_ptr->cmprecv_tail].message_type, proc); + //tcap_send_error(info_str); + } + else + { + ; + //debug_ptr->watch_dog[158]++; + //printf("check_csldata, dlgrecv: %d, did: %d\n", int_ptr->dlg_recv[int_ptr->dlgrecv_tail].message_type, proc); + //sprintf(info_str, "check_csldata, dlgrecv: %d, did: %ld\n", int_ptr->dlg_recv[int_ptr->dlgrecv_tail].message_type, proc); + //tcap_send_error(info_str); + } + + return 0; +} + +void tco_program(void) // transaction coordinator +{ + struct SCLC_MSG sccp_data; + struct TSL_struct tsl_data; + struct TRBegin_struct *begin_ptr; + struct TRContinue_struct *con_ptr; + struct TREnd_struct *end_ptr; + struct TRUAbort_struct *uabort_ptr; + struct TRPAbort_struct *pabort_ptr; + struct TRNotice_struct *notice_ptr; + u8 decode_result; + u8 decode_error; + u8 proto_type, pabort_cause; + u32 temp_tid = 0; + u32 ii; + char info_str[1024]; + + if (tcap_from_sccp(&sccp_data)) // get data from sccp buffer + { + memset(&tsl_data,0,sizeof(TSL_struct)); + decode_result = tsl_message_decode(&sccp_data,&tsl_data,&decode_error); + if ((tsl_data.message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + switch (tsl_data.message_type) + { + case Unidirectional: + case Unidirectional_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][5] ++; + debug_ptr->watch_dog[32] ++; + if (decode_result == 1) + { + debug_ptr->watch_dog[33] ++; + temp_tid = assign_did(); + if (temp_tid != 0) + { + debug_ptr->watch_dog[222] ++; + tco_to_tsm(&tsl_data,temp_tid); + } + } + break; + case Begin: + case Query_WithPerm_Ansi: + case Query_WithoutPerm_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][6] ++; + debug_ptr->watch_dog[34] ++; + begin_ptr = (TRBegin_struct *) &tsl_data.tsl_prim.tr_begin; + if (decode_result == 0) // message format is wrong + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][75] ++; + debug_ptr->watch_dog[35] ++; + if (begin_ptr->tid_flag == 1) // ptid derivable + { + debug_ptr->watch_dog[36] ++; + if (proto_type) + pabort_cause = P_Abort_ITP_Ansi; + else + pabort_cause = P_Abort_ITP; + send_pabort_sccp(tsl_data.peer_tid_len, //modified by Pierre, 06-08-19 */ + begin_ptr->transaction_id,pabort_cause,&tsl_data.local_add,&tsl_data.peer_add,proto_type); + } + return; + } + temp_tid = assign_did(); + if (temp_tid == 0) // can not assign a dialogue id + { + tcap_send_alarm(5,1); + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][72] ++; + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][24]++; + tcap_send_error("TSL error. Can not assign transaction id"); + debug_ptr->watch_dog[37] ++; + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_sccp(tsl_data.peer_tid_len,//modified by Pierre, 06-08-19 + begin_ptr->transaction_id,pabort_cause,&tsl_data.local_add,&tsl_data.peer_add,proto_type); + return; + } + debug_ptr->watch_dog[221] ++; + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][20]++; + tco_to_tsm(&tsl_data,temp_tid); + break; + case Continue: + case Conversation_WithPerm_Ansi: + case Conversation_WithoutPerm_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][7] ++; + debug_ptr->watch_dog[38] ++; + con_ptr = (TRContinue_struct *) &tsl_data.tsl_prim.tr_continue; + if (decode_result == 0) // message format is wrong + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][75] ++; + debug_ptr->watch_dog[39] ++; + if (con_ptr->ptid_flag == 1) // ptid derivable + { + if (con_ptr->ltid_flag == 0) // DTID not assigned + { + debug_ptr->watch_dog[40] ++; + if (proto_type) + pabort_cause = P_Abort_ITP_Ansi; + else + pabort_cause = P_Abort_ITP; + send_pabort_sccp(tsl_data.peer_tid_len, //modified by Pierre, 06-08-19 + con_ptr->peer_tid,pabort_cause,&tsl_data.local_add,&tsl_data.peer_add,proto_type); + } + else + { + ii = con_ptr->local_tid; + if (check_resend(&tsl_data,ii)) + return; + ii = ii & 0x7fff; + if (!check_did(ii)) + { + debug_ptr->watch_dog[40] ++; + if (proto_type) + pabort_cause = P_Abort_ITP_Ansi; + else + pabort_cause = P_Abort_ITP; + send_pabort_sccp(tsl_data.peer_tid_len, //modified by Pierre, 06-08-19 + con_ptr->peer_tid,pabort_cause,&tsl_data.local_add,&tsl_data.peer_add,proto_type); + } + else + { + debug_ptr->watch_dog[41] ++; + if (decode_error == DERR_UNTID || decode_error == DERR_OTHER) + { + if (proto_type) + pabort_cause = P_Abort_ITP_Ansi; + else + pabort_cause = P_Abort_ITP; + } + else + { + if (proto_type) + pabort_cause = P_Abort_BFTP_Ansi; + else + pabort_cause = P_Abort_BFTP; + } + send_pabort_sccp(tsl_data.peer_tid_len, //modified by Pierre, 06-08-19 + con_ptr->peer_tid,pabort_cause,&tsl_data.local_add,&tsl_data.peer_add,proto_type); + send_pabort_tsm(ii,pabort_cause,proto_type); + } + } + } + return; + } + ii = con_ptr->local_tid; + if (check_resend(&tsl_data,ii)) + return; + con_ptr->local_tid = ii & 0x7fff; + if (!check_did(con_ptr->local_tid)) // DTID not assigned + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][72] ++; + sprintf(info_str, "TSL error. Can not check out transaction id, did: %u, type: %d, continue", temp_tid, tsl_data.message_type); + tcap_send_error(info_str); + debug_ptr->watch_dog[230]++; + //tcap_send_error("TSL error. Can not check out transaction id"); + debug_ptr->watch_dog[42] ++; + if (con_ptr->peer_tid != 0) // ptid derivable + { + debug_ptr->watch_dog[43] ++; + if (proto_type) + pabort_cause = P_Abort_UTID_Ansi; + else + pabort_cause = P_Abort_UTID; + send_pabort_sccp(tsl_data.peer_tid_len, //modified by Pierre, 06-08-19 + con_ptr->peer_tid,pabort_cause,&tsl_data.local_add,&tsl_data.peer_add,proto_type); + } + return; + } + tco_to_tsm(&tsl_data,con_ptr->local_tid); + break; + case End: + case Response_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][8] ++; + debug_ptr->watch_dog[44] ++; + end_ptr = (TREnd_struct *) &tsl_data.tsl_prim.tr_end; + if (check_resend(&tsl_data,end_ptr->transaction_id)) + return; + end_ptr->transaction_id &= 0x7fff; + temp_tid = end_ptr->transaction_id; + if (decode_result == 0) + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][75] ++; + debug_ptr->watch_dog[45] ++; + if (end_ptr->tid_flag == 0 || !check_did(temp_tid)) + debug_ptr->watch_dog[46] ++; + else + { + if (proto_type) + pabort_cause = P_Abort_BFTP_Ansi; + else + pabort_cause = P_Abort_BFTP; + send_pabort_tsm(temp_tid,pabort_cause,proto_type); + } + return; + } + if (!check_did(temp_tid)) + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][72] ++; + sprintf(info_str, "TSL error. Can not check out transaction id, did: %u, type: %d, end", temp_tid, tsl_data.message_type); + tcap_send_error(info_str); + //printf("TSL error. Can not check out transaction id, did: %ld, type: %d, end\n", temp_tid, tsl_data.message_type); + debug_ptr->watch_dog[229]++; + //tcap_send_error("TSL error. Can not check out transaction id"); + return; + } + tco_to_tsm(&tsl_data,temp_tid); + break; + case U_Abort: + case U_Abort_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][9] ++; + debug_ptr->watch_dog[47] ++; + uabort_ptr = (TRUAbort_struct *) &tsl_data.tsl_prim.tr_uabort; + if (check_resend(&tsl_data,uabort_ptr->transaction_id)) + return; + uabort_ptr->transaction_id &= 0x7fff; + temp_tid = uabort_ptr->transaction_id; + if (decode_result == 0) + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][75] ++; + debug_ptr->watch_dog[48] ++; + if (uabort_ptr->tid_flag == 0 || !check_did(temp_tid)) + { + debug_ptr->watch_dog[49] ++; + if (proto_type) + pabort_cause = P_Abort_BFTP_Ansi; + else + pabort_cause = P_Abort_BFTP; + send_pabort_tsm(temp_tid,pabort_cause,proto_type); + } + return; + } + if (!check_did(temp_tid)) + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][72] ++; + sprintf(info_str, "TSL error. Can not check out transaction id, did: %u, type: %d, uabort", temp_tid, tsl_data.message_type); + tcap_send_error(info_str); + debug_ptr->watch_dog[228]++; + //tcap_send_error("TSL error. Can not check out transaction id"); + return; + } + if (debug_ptr->error_switch) + { + if (!proto_type) + sprintf(info_str,"TSL warning. Receive U_Abort from other machine. Tid= %u",temp_tid); + else + sprintf(info_str,"TSL warning. Receive U_Abort_Ansi from other machine. Tid= %u",temp_tid); + tcap_send_error(info_str); + } + tco_to_tsm(&tsl_data,temp_tid); + break; + case P_Abort: + case P_Abort_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][9] ++; + debug_ptr->watch_dog[50] ++; + pabort_ptr = (TRPAbort_struct *) &tsl_data.tsl_prim.tr_pabort; + if (check_resend(&tsl_data,pabort_ptr->transaction_id)) + return; + pabort_ptr->transaction_id &= 0x7fff; + temp_tid = pabort_ptr->transaction_id; + if (decode_result == 0) + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][75] ++; + debug_ptr->watch_dog[51] ++; + if (pabort_ptr->tid_flag == 0 || !check_did(temp_tid)) + debug_ptr->watch_dog[52] ++; + else + { + if (proto_type) + pabort_cause = P_Abort_BFTP_Ansi; + else + pabort_cause = P_Abort_BFTP; + send_pabort_tsm(temp_tid,pabort_cause,proto_type); + } + return; + } + if (!check_did(temp_tid)) + { + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][72] ++; + sprintf(info_str, "TSL error. Can not check out transaction id, did: %u, type: %d, pabort", temp_tid, tsl_data.message_type); + tcap_send_error(info_str); + debug_ptr->watch_dog[227]++; + //tcap_send_error("TSL error. Can not check out transaction id"); + return; + } + tco_to_tsm(&tsl_data,temp_tid); + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][73] ++; + if (!proto_type) + { + switch (pabort_ptr->abort_reason) + { + case P_Abort_UMT: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][25] ++; + break; + case P_Abort_ITP: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][26] ++; + break; + case P_Abort_BFTP: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][27] ++; + break; + case P_Abort_UTID: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][28] ++; + break; + case P_Abort_RL: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][29] ++; + break; + default: + break; + } + } + else + { + switch (pabort_ptr->abort_reason) + { + case P_Abort_UMT_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][25] ++; + break; + case P_Abort_ITP_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][26] ++; + break; + case P_Abort_BFTP_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][27] ++; + break; + case P_Abort_UTID_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][28] ++; + break; + case P_Abort_RL_Ansi: + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][29] ++; + break; + default: + break; + } + } + if (debug_ptr->error_switch) + { + if (!proto_type) + sprintf(info_str,"TSL warning. Receive P_Abort from other machine. Tid= %u",temp_tid); + else + sprintf(info_str,"TSL warning. Receive P_Abort_Ansi from other machine. Tid= %u",temp_tid); + tcap_send_error(info_str); + } + break; + case Notice: + debug_ptr->watch_dog[53] ++; + notice_ptr = (TRNotice_struct *) &tsl_data.tsl_prim.tr_notice; + temp_tid = notice_ptr->transaction_id; + if (!check_did(temp_tid)) + { + sprintf(info_str, "TSL error. Can not check out transaction id, did: %u, type: %d, notice", temp_tid, tsl_data.message_type); + tcap_send_error(info_str); + debug_ptr->watch_dog[226]++; + //tcap_send_error("TSL error. Can not check out transaction id"); + return; + } + tco_to_tsm(&tsl_data,temp_tid); + tcap_send_error("TSL error. Receive Notice from lower layer"); + break; + default: + debug_ptr->watch_dog[54] ++; + break; + } + } +} + +int get_from_cha(u8 *content,u32 proc,u8 *temp,u8 data_count,u8 level) // build component primitive +{ + struct tcapint_struct *int_ptr; + int len = 0; + int ii,jj,aa; + u8 default_len,send_count=0; + u8 temp_buf[TCAP_BUF_LEN]; + + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + *temp = 0; + if (level == 1) + default_len = TCAP_PARAM_LEN_1; + else + default_len = TCAP_PARAM_LEN; + for (ii = 0;ii < data_count;ii ++) + { + jj = int_ptr->cmpsend_tail; + if (jj == int_ptr->cmpsend_head) + break; + int_ptr->cmp_send[jj].invoke_id = get_transfer_iid(proc, int_ptr->cmp_send[jj].invoke_id); //2010-11-04 for dup iid + + aa = assemble_component(temp_buf,&int_ptr->cmp_send[jj]); + if ((len+aa) > default_len) // components data is too long + { + tcap_send_error("CSL warning.components length is larger than expected"); + *temp = send_count; + debug_ptr->watch_dog[250]++; + break; + } + else + { + memcpy(content+len,temp_buf,aa); + int_ptr->cmpsend_tail = (jj + 1) % MAX_CSL_BUF; + len += aa; + send_count ++; + debug_ptr->watch_dog[251]++; + } + } + return len; +} + +void send_cancel_tcu(u32 proc,u8 invid) +{ + struct tcapint_struct *int_ptr; + struct CSLcmp_struct *cmp_ptr; + u8 ii; + u8 info_buf[1024]; + + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + ii = int_ptr->cmprecv_head; + if ((ii + 1) % MAX_CSL_BUF == int_ptr->cmprecv_tail) // buffer is full + { + if (debug_ptr->error_switch) + { + sprintf((char *)info_buf,"ISM error. component buffer is full:%u",proc); + tcap_send_error((char *)info_buf); + } + return; + } + cmp_ptr = (CSLcmp_struct *) &int_ptr->cmp_recv[ii]; + cmp_ptr->message_type = L_Cancel; + cmp_ptr->message_flag = INDICATE; + cmp_ptr->dialogue_id = proc; + cmp_ptr->invoke_id = invid; + int_ptr->cmprecv_head = (ii + 1) % MAX_CSL_BUF; + debug_ptr->watch_dog[156]++; +} + +void send_reject_tcu(u32 proc,u8 invid,u8 err_type,u8 err_code,u8 proto_type) +{ + struct tcapint_struct *int_ptr; + struct CSLcmp_struct *cmp_ptr; + struct TCReject_struct *reject_ptr; + u8 ii; + u8 flag=0; + + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + ii = int_ptr->cmprecv_tail; + while(ii != int_ptr->cmprecv_head) + { + if (int_ptr->cmp_recv[ii].invoke_id == invid) // find exist data + { + flag = 1; + break; + } + ii = (ii + 1) % MAX_CSL_BUF; + } + if (flag == 0) + { + ii = int_ptr->cmprecv_head; + int_ptr->cmprecv_head = (ii + 1) % MAX_CSL_BUF; + } + cmp_ptr = (CSLcmp_struct *) &int_ptr->cmp_recv[ii]; + if (proto_type) + cmp_ptr->message_type = L_Reject_Ansi; + else + cmp_ptr->message_type = L_Reject; + cmp_ptr->message_flag = INDICATE; + cmp_ptr->dialogue_id = proc; + cmp_ptr->invoke_id = invid; + cmp_ptr->last_flag = 1; + reject_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject; + reject_ptr->problem_type = err_type; + reject_ptr->problem_code = err_code; // badly structured component +} + +u8 find_tempiid(u32 did,u8 iid,u8 flag) +{ + struct tcapvm_struct *vm_ptr; + struct ismvm_data *ism_ptr; + u8 ii; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[did]; + if (flag == 1) //apply for new iid + { + for (ii = 0;ii < MAX_TEMPINVOKEID;ii ++) + { + ism_ptr = (ismvm_data *) &vm_ptr->ism_data[ii]; + if (ism_ptr->used_flag == 0) // empty temp iid + { + ism_ptr->used_flag = 1; + ism_ptr->linked_iid = iid; + return ii; + } + } + } + else //search assigned iid + { + for (ii = 0;ii < MAX_TEMPINVOKEID;ii ++) + { + ism_ptr = (ismvm_data *) &vm_ptr->ism_data[ii]; + if ((ism_ptr->used_flag==1)&&(ism_ptr->linked_iid==iid)) + return ii; + } + } + tcap_send_error("CSL warning.Can not assign a temp invoke id"); + return 0xff; +} + +u8 write_ism(CSLcmp_struct *cmp_ptr) +{ + struct tcapvm_struct *vm_ptr; + struct ismvm_data *ism_ptr; + u8 iid,temp_iid; + u32 did; + + did = cmp_ptr->dialogue_id; + iid = cmp_ptr->invoke_id; + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[did]; + + if (((cmp_ptr->message_type == Invoke) || + (cmp_ptr->message_type == Invoke_L_Ansi) || + (cmp_ptr->message_type == Invoke_NL_Ansi)) && + (cmp_ptr->message_flag == REQUEST)) + temp_iid = find_tempiid(did,iid,1); + else + temp_iid = find_tempiid(did,iid,0); + if (temp_iid == 0xff) // can not find temp iid + { + debug_ptr->watch_dog[252]++; + return 0; + } + ism_ptr = (ismvm_data *) &vm_ptr->ism_data[temp_iid]; + ism_ptr->ism_msgtype = cmp_ptr->message_type; + ism_ptr->ism_msgflag = cmp_ptr->message_flag; + if (((cmp_ptr->message_type == Invoke) || + (cmp_ptr->message_type == Invoke_L_Ansi) || + (cmp_ptr->message_type == Invoke_NL_Ansi)) && + (cmp_ptr->message_flag == REQUEST)) + { + ism_ptr->ism_msgclass = cmp_ptr->cmp_prim.tc_invoke.operation_class; + ism_ptr->ism_oper_domain = cmp_ptr->cmp_prim.tc_invoke.operation_domain; + ism_ptr->ism_oper_family = cmp_ptr->cmp_prim.tc_invoke.operation_family; + ism_ptr->ism_oper_code = cmp_ptr->cmp_prim.tc_invoke.operation_code; + if (cmp_ptr->cmp_prim.tc_invoke.timer != 0) // has invoke time + ism_ptr->ism_timer = cmp_ptr->cmp_prim.tc_invoke.timer*ISM_TIMERHZ; + else + ism_ptr->ism_timer = debug_ptr->default_invtime*ISM_TIMERHZ; + } + else if ((cmp_ptr->message_type == U_Cancel) && (cmp_ptr->message_flag == REQUEST)) + { + debug_ptr->watch_dog[157]++; + ism_ptr->ism_state = TCAP_INIT; + } + else if (((cmp_ptr->message_type == U_Reject) || + (cmp_ptr->message_type == U_Reject_Ansi)) && + (cmp_ptr->message_flag == REQUEST)) + { + if ((cmp_ptr->cmp_prim.tc_reject.problem_type != Invoke_Problem) && + (cmp_ptr->cmp_prim.tc_reject.problem_type != Invoke_Problem_Ansi)) + ism_ptr->ism_state = TCAP_INIT; + } + return 1; +} + +void send_to_cha(u32 proc,u8 *content,u8 data_len) // analyse the component primitive +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + struct CSLcmp_struct *cmp_ptr; + struct ismvm_data *state_ptr=NULL; + struct TCInvoke_struct *invoke_ptr; + struct TCReject_struct *reject_ptr; + u8 ii; + u8 temp_invid; + u8 flag; + u8 proto_type; + int len = 0; + int sec_len; + int result; + char info_str[1024]; + u8 problem_type,problem_code; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + while (len < data_len) + { + ii = int_ptr->cmprecv_head; + if (((ii + 1) % MAX_CSL_BUF) == int_ptr->cmprecv_tail) + { + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM error. Component buffer is full: %u",proc); + tcap_send_error(info_str); + } + int_ptr->cmp_recv[ii].last_flag = 1; + return; + } + cmp_ptr = (CSLcmp_struct *) &int_ptr->cmp_recv[ii]; + memset(cmp_ptr,0,sizeof(CSLcmp_struct)); + result = extract_component(cmp_ptr,content+len,proc,&sec_len); + if (sec_len == -1) // structure length is error + { + debug_ptr->watch_dog[249]++; + return; + } + if (result != 0) // syntax is right + { + debug_ptr->watch_dog[248]++; + len += sec_len; + } + if (len == data_len) // this component is the last one + cmp_ptr->last_flag = 1; + temp_invid = cmp_ptr->invoke_id; + if ((cmp_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + switch (cmp_ptr->message_type) + { + case Invoke: + case Invoke_L_Ansi: + case Invoke_NL_Ansi: + if (result == 0) // syntax error + { + if (!proto_type) + { + problem_type = General_Problem; + problem_code = General_Problem_MC; + } + else + { + problem_type = General_Problem_Ansi; + problem_code = General_Problem_MC_Ansi; + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + return; + } + if (!store_iid(proc,temp_invid)) + { + cmp_ptr->invoke_id = transfer_iid(proc, temp_invid); + tcap_send_error("Duplicate invoke id, transfer it!"); + /* + tcap_send_error("CSL error. Duplicate invoke id"); + if (!proto_type) + { + problem_type = Invoke_Problem; + problem_code = Invoke_Problem_DIID; + } + else + { + problem_type = Invoke_Problem_Ansi; + problem_code = Invoke_Problem_DIID_Ansi; + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + return; + */ + } + invoke_ptr = (TCInvoke_struct *) &cmp_ptr->cmp_prim.tc_invoke; + if (invoke_ptr->linkedid_flag == 1) // linked other operation + { + flag = find_tempiid(proc,invoke_ptr->linked_id,0); + if (flag != 0xff) // find temp invoke id + state_ptr = (ismvm_data *) &vm_ptr->ism_data[flag]; + if ((flag == 0xff)||(state_ptr->ism_state!=SENT_STATE1&&state_ptr->ism_state!=SENT_STATE2&&state_ptr->ism_state!=SENT_STATE3&&state_ptr->ism_state!=SENT_STATE4))// the linked ISM is not in sent state + { + tcap_send_error("CSL error. Linked ID is not in use"); + if (!proto_type) + { + problem_type = Invoke_Problem; + problem_code = Invoke_Problem_ULID; + } + else + { + problem_type = Invoke_Problem_Ansi; + problem_code = Invoke_Problem_ULID_Ansi; + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + } + else + int_ptr->cmprecv_head = (ii + 1) % MAX_CSL_BUF; + } + else + int_ptr->cmprecv_head = (ii + 1) % MAX_CSL_BUF; + break; + case Result_NL: + case Result_L: + case Error: + case Result_NL_Ansi: + case Result_L_Ansi: + case Error_Ansi: + if (result == 0) + { + if (check_iid(proc,temp_invid)) // invoke id can search + { + flag = find_tempiid(proc,temp_invid,0); + if (flag != 0xff) + ism_terminate(proc,flag); + if (!proto_type) + { + problem_type = General_Problem; + problem_code = General_Problem_MC; + } + else + { + problem_type = General_Problem_Ansi; + problem_code = General_Problem_MC_Ansi; + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + } + return; + } + flag = find_tempiid(proc,temp_invid,0); + if (flag != 0xff) + state_ptr = (ismvm_data *) &vm_ptr->ism_data[flag]; + if ((flag == 0xff)||(state_ptr->ism_state == TCAP_IDLE)) // invoke id is not active + { + if ((cmp_ptr->message_type == Result_NL) || + (cmp_ptr->message_type == Result_L) || + (cmp_ptr->message_type == Result_NL_Ansi) || + (cmp_ptr->message_type == Result_L_Ansi)) + { + if (!proto_type) + { + problem_type = Return_Result; + problem_code = Return_Result_RRU; + tcap_send_error("CSL error. Return Result is not expected"); + } + else + { + problem_type = Return_Result_Ansi; + problem_code = Return_Result_RRU_Ansi; + tcap_send_error("CSL error. Return Result Ansi is not expected"); + } + } + else + { + if (!proto_type) + { + problem_type = Return_Error; + problem_code = Return_Error_UEE; + tcap_send_error("CSL error. Return Error is not expected"); + } + else + { + problem_type = Return_Error_Ansi; + problem_code = Return_Error_UEE_Ansi; + tcap_send_error("CSL error. Return Error Ansi is not expected"); + } + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + return; + } + if (((cmp_ptr->message_type == Error) || + (cmp_ptr->message_type == Error_Ansi)) && + (debug_ptr->error_switch)) + { + if (cmp_ptr->message_type == Error) + sprintf(info_str,"CSL warning. Return Error received from other machine. Did is %u, Iid is %d",proc,temp_invid); + else + sprintf(info_str,"CSL warning. Return Error Ansi received from other machine. Did is %u, Iid is %d",proc,temp_invid); + tcap_send_error(info_str); + } + if (proto_type) + { + if ((cmp_ptr->message_type == Result_NL_Ansi) || + (cmp_ptr->message_type == Result_L_Ansi)) + { + cmp_ptr->cmp_prim.tc_result.operation_flag = 1; + cmp_ptr->cmp_prim.tc_result.operation_domain = state_ptr->ism_oper_domain; + cmp_ptr->cmp_prim.tc_result.operation_family = state_ptr->ism_oper_family; + cmp_ptr->cmp_prim.tc_result.operation_code = state_ptr->ism_oper_code; + } + } + if (!write_ism(cmp_ptr)) + debug_ptr->watch_dog[230] ++; + int_ptr->cmprecv_head = (ii + 1) % MAX_CSL_BUF; + break; + case Reject: + case Reject_Ansi: + reject_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject; + if (result == 0) // syntax error + { + if (!proto_type) + { + problem_type = General_Problem; + problem_code = General_Problem_MC; + } + else + { + problem_type = General_Problem_Ansi; + problem_code = General_Problem_MC_Ansi; + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + return; + } + if ((reject_ptr->problem_type == Invoke_Problem) || + (reject_ptr->problem_type == Invoke_Problem_Ansi)) // invoke problem type + { + flag = find_tempiid(proc,temp_invid,0); + if (flag != 0xff) + state_ptr = (ismvm_data *) &vm_ptr->ism_data[flag]; + if ((flag == 0xff)||(state_ptr->ism_state == TCAP_IDLE)) // the ism is not active + { + if (proto_type) + cmp_ptr->message_type = R_Reject_Ansi; + else + cmp_ptr->message_type = R_Reject; + } + else + { + ism_terminate(proc,flag); + if ((reject_ptr->problem_code == Invoke_Problem_ULID) || + (reject_ptr->problem_code == Invoke_Problem_ULID_Ansi)) + { + if (proto_type) + cmp_ptr->message_type = R_Reject_Ansi; + else + cmp_ptr->message_type = R_Reject; + } + else + { + if (proto_type) + cmp_ptr->message_type = U_Reject_Ansi; + else + cmp_ptr->message_type = U_Reject; + } + } + } + else + { + if ((reject_ptr->problem_type == General_Problem) || + (reject_ptr->problem_type == General_Problem_Ansi)) + { + if (proto_type) + cmp_ptr->message_type = R_Reject_Ansi; + else + cmp_ptr->message_type = R_Reject; + } + else if ((reject_ptr->problem_type == Return_Result) || + (reject_ptr->problem_type == Return_Result_Ansi)) + { + if ((reject_ptr->problem_code == Return_Result_MP) || + (reject_ptr->problem_code == Return_Result_MP_Ansi)) + { + if (proto_type) + cmp_ptr->message_type = U_Reject_Ansi; + else + cmp_ptr->message_type = U_Reject; + } + else + { + if (proto_type) + cmp_ptr->message_type = R_Reject_Ansi; + else + cmp_ptr->message_type = R_Reject; + } + } + else + { + if ((reject_ptr->problem_code == Return_Error_UIID) || + (reject_ptr->problem_code == Return_Error_UIID_Ansi) || + (reject_ptr->problem_code == Return_Error_REU) || + (reject_ptr->problem_code == Return_Error_REU_Ansi)) + { + if (proto_type) + cmp_ptr->message_type = R_Reject_Ansi; + else + cmp_ptr->message_type = R_Reject; + } + else + { + if (proto_type) + cmp_ptr->message_type = U_Reject_Ansi; + else + cmp_ptr->message_type = U_Reject; + } + } + } + if (debug_ptr->error_switch) + { + if (!proto_type) + sprintf(info_str,"CSL warning. Reject Received from other machine. Did is %u, Iid is %d",proc,temp_invid); + else + sprintf(info_str,"CSL warning. Reject Ansi Received from other machine. Did is %u, Iid is %d",proc,temp_invid); + tcap_send_error(info_str); + } + int_ptr->cmprecv_head = (ii + 1) % MAX_CSL_BUF; + break; + default: + if (result == 0) + { + if (!proto_type) + { + problem_type = General_Problem; + problem_code = General_Problem_MC; + } + else + { + problem_type = General_Problem_Ansi; + problem_code = General_Problem_MC_Ansi; + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + return; + } + if (check_iid(proc,temp_invid)) // invoke id can search + { + flag = find_tempiid(proc,temp_invid,0); + if (flag != 0xff) + ism_terminate(proc,flag); + } + if (!proto_type) + { + problem_type = General_Problem; + problem_code = General_Problem_UC; + } + else + { + problem_type = General_Problem_Ansi; + problem_code = General_Problem_UC_Ansi; + } + send_reject_tcu(proc,temp_invid,problem_type,problem_code,proto_type); + break; + } + } +} + +void tcap_uni_request(u32 proc,u8 data_flag) +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCUni_struct *tcuni_ptr; + struct TSL_struct tsl_data; + struct TRUni_struct *truni_ptr; + struct dlgPDU_struct pdu_data; + u8 ii,proto_type; + u8 temp=0; + u8 cmp_level,sls; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[data_flag]; + tcuni_ptr = (TCUni_struct *) &csl_ptr->dlg_prim.tc_uni; + tsl_data.message_type = csl_ptr->message_type; + tsl_data.message_flag = REQUEST; + if ((csl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + memcpy(&tsl_data.local_add,&tcuni_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&tsl_data.peer_add,&tcuni_ptr->peer_add,sizeof(SCCP_ADDR)); + truni_ptr = (TRUni_struct *) &tsl_data.tsl_prim.tr_uni; + truni_ptr->dialogue_len = truni_ptr->components_len = 0; + if (tcuni_ptr->dialogue_flag == 1) // has dialogue portion + { + if (!proto_type) + { + pdu_data.dialogue_type = PDU_AUDT; + memcpy(pdu_data.pdu_union.aarq.version,Version_1,2); + } + else + { + pdu_data.dialogue_type = PDU_ASUDT; + pdu_data.pdu_union.asudt.version = Version_Ansi; + } + set_dlgpdu(&pdu_data,&tcuni_ptr->dlg_data); + truni_ptr->dialogue_len = build_dp(truni_ptr->dialogue,&pdu_data,1,proto_type); + cmp_level = 0; + } + else + cmp_level = 1; + ii = tcuni_ptr->component_present; + if (ii != 0) + truni_ptr->components_len = get_from_cha(truni_ptr->components,proc,&temp,ii,cmp_level); + if (temp == 0) // components is not too long + { + vm_ptr->proto_type = proto_type; + sls = proc % TCAP_SLS_NUM; + tcap_to_sccp(&tsl_data,sls,0); + } + else + tcap_send_error("CSL error. Component is too long"); +} + +u8 tcap_uni_indicate(u32 proc,u8 data_flag) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct TRUni_struct *truni_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCUni_struct *tcuni_ptr; + struct dlgPDU_struct pdu_data; + u8 ii, proto_type; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[data_flag]; + truni_ptr = (TRUni_struct *) &tsl_ptr->tsl_prim.tr_uni; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + ii = int_ptr->dlgrecv_head; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[ii]; + csl_ptr->message_type = tsl_ptr->message_type; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = proc; + if ((tsl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + tcuni_ptr = (TCUni_struct *) &csl_ptr->dlg_prim.tc_uni; + memcpy(&tcuni_ptr->local_add,&tsl_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&tcuni_ptr->peer_add,&tsl_ptr->peer_add,sizeof(SCCP_ADDR)); + if (truni_ptr->dialogue_len != 0) + { + if ((!proto_type && !extract_dp(&pdu_data,truni_ptr->dialogue,truni_ptr->dialogue_len,proto_type)) || + (!proto_type && (pdu_data.dialogue_type != PDU_AUDT))) + { + tcap_send_error("CSL error. Unidirectional primitive has error PDU type"); + return 0; + } + if ((proto_type && (pdu_data.pdu_union.asudt.version != 0) && + (pdu_data.pdu_union.asudt.version != Version_Ansi)) || + (!proto_type && (memcmp(pdu_data.pdu_union.aarq.version,Version_1,2) != 0))) + { + tcap_send_error("CSL error. Unidirectional primitive has error protocol version"); + return 0; + } + tcuni_ptr->dialogue_flag = 1; + get_dlgpdu(&pdu_data,&tcuni_ptr->dlg_data); + } + if (truni_ptr->components_len > 0) + { + send_to_cha(proc,truni_ptr->components,truni_ptr->components_len); + tcuni_ptr->component_present = 1; + } + else + tcuni_ptr->component_present = 0; + vm_ptr->proto_type = proto_type; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return 1; +} + +u8 tcap_begin_request(u32 proc) +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCBegin_struct *tcbegin_ptr; + struct TSL_struct tsl_data; + struct TRBegin_struct *trbegin_ptr; + struct dlgPDU_struct pdu_data; + u8 data_flag; + u8 cmp_level; + u8 ii,proto_type,pabort_cause; + u8 temp=0,sls; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + data_flag = int_ptr->dlgsend_tail; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + int_ptr->dlgsend_tail = (data_flag + 1) % MAX_TSL_BUF; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[data_flag]; + tcbegin_ptr = (TCBegin_struct *) &csl_ptr->dlg_prim.tc_begin; + memcpy(&vm_ptr->local_add,&tcbegin_ptr->local_add,sizeof(SCCP_ADDR)); + tsl_data.message_type = csl_ptr->message_type; + tsl_data.message_flag = REQUEST; + if ((csl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + memcpy(&tsl_data.local_add,&tcbegin_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&tsl_data.peer_add,&tcbegin_ptr->peer_add,sizeof(SCCP_ADDR)); + trbegin_ptr = (TRBegin_struct *) &tsl_data.tsl_prim.tr_begin; + trbegin_ptr->transaction_id = proc; + trbegin_ptr->dialogue_len = trbegin_ptr->components_len = 0; + if (tcbegin_ptr->dialogue_flag == 1) // has dialogue portion + { + if (!proto_type) + { + vm_ptr->ac_mode = 1; // set AC mode + pdu_data.dialogue_type = PDU_AARQ; + memcpy(pdu_data.pdu_union.aarq.version,Version_1,2); + } + else + { + vm_ptr->ac_mode = 0; + pdu_data.dialogue_type = PDU_ASUDT; + pdu_data.pdu_union.asudt.version = Version_Ansi; + } + set_dlgpdu(&pdu_data,&tcbegin_ptr->dlg_data); + trbegin_ptr->dialogue_len = build_dp(trbegin_ptr->dialogue,&pdu_data,0,proto_type); + } + else + cmp_level = 1; + ii = tcbegin_ptr->component_present; + if (ii != 0) + trbegin_ptr->components_len = get_from_cha(trbegin_ptr->components,proc,&temp,ii,cmp_level); + if (temp != 0) // components is too long + { + tcap_send_error("CSL error. Component is too long"); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_head,proto_type); + debug_ptr->watch_dog[187] ++; + return 0; + } + vm_ptr->proto_type = proto_type; + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][20]++; + if (tcbegin_ptr->peer_add.ip != 0) // has set the SLS by uplayer + { + sls = tcbegin_ptr->peer_add.ip % TCAP_SLS_NUM; + debug_ptr->watch_dog[188] ++; + } + else + sls = proc % TCAP_SLS_NUM; + tcap_to_sccp(&tsl_data,sls,0); + debug_ptr->watch_dog[189] ++; + return 1; +} + +u8 tcap_begin_indicate(u32 proc,u8 data_flag) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct TRBegin_struct *trbegin_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCBegin_struct *tcbegin_ptr; + struct dlgPDU_struct pdu_data; + u8 ii,proto_type; + u8 acn_len=0; + u8 acn[TCAP_ACN_LEN]; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[data_flag]; + trbegin_ptr = (TRBegin_struct *) &tsl_ptr->tsl_prim.tr_begin; + memcpy(&vm_ptr->peer_add,&tsl_ptr->peer_add,sizeof(SCCP_ADDR)); + memcpy(&vm_ptr->local_add,&tsl_ptr->local_add,sizeof(SCCP_ADDR)); + vm_ptr->peer_tid = trbegin_ptr->transaction_id; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + ii = int_ptr->dlgrecv_head; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[ii]; + csl_ptr->message_type = tsl_ptr->message_type; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = proc; + if ((tsl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + tcbegin_ptr = (TCBegin_struct *) &csl_ptr->dlg_prim.tc_begin; + memcpy(&tcbegin_ptr->local_add,&vm_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&tcbegin_ptr->peer_add,&vm_ptr->peer_add,sizeof(SCCP_ADDR)); + if (trbegin_ptr->dialogue_len != 0) // has dialogue portion + { + if (!proto_type) + { + if (!extract_dp(&pdu_data,trbegin_ptr->dialogue,trbegin_ptr->dialogue_len,proto_type) || pdu_data.dialogue_type != PDU_AARQ) + { + tcap_send_error("CSL error. Begin primitive has error dialogue portion"); + pdu_data.dialogue_type = PDU_ABRT; // build ABORT apdu + pdu_data.pdu_union.abrt.abort_source = ABRTDlg_Service_Provider; + pdu_data.pdu_union.abrt.user_info_len = 0; + send_uabort_sccp(proc,&pdu_data,ITU_TCAP,0,NULL); + return 0; + } + if (memcmp(pdu_data.pdu_union.aarq.version,Version_1,2) != 0) // protocol is error + { + tcap_send_error("CSL error. Begin primitive has error protocol version"); + acn_len = pdu_data.pdu_union.aarq.acn_len; + memcpy(acn,pdu_data.pdu_union.aarq.acn,acn_len); + pdu_data.dialogue_type = PDU_AARE; + pdu_data.pdu_union.aare.acn_len = acn_len; + memcpy(pdu_data.pdu_union.aare.acn,acn,acn_len); + pdu_data.pdu_union.aare.result = Reject_permanent; + pdu_data.pdu_union.aare.diagnostic_flag = Dialogue_Service_Provider; + pdu_data.pdu_union.aare.diagnostic_type = DSP_NCDP; + pdu_data.pdu_union.aare.user_info_len = 0; + send_uabort_sccp(proc,&pdu_data,ITU_TCAP,0,NULL); + return 0; + } + } + else + { + extract_dp(&pdu_data,trbegin_ptr->dialogue,trbegin_ptr->dialogue_len,proto_type); + if ((pdu_data.pdu_union.asudt.version != 0) && + (pdu_data.pdu_union.asudt.version != Version_Ansi)) + { + tcap_send_error("CSL error. Ansi Query has error protocol version"); + return 0; + } + } + vm_ptr->ac_mode = 1; + tcbegin_ptr->dialogue_flag = 1; + get_dlgpdu(&pdu_data,&tcbegin_ptr->dlg_data); + } + else + { + tcbegin_ptr->dialogue_flag = 0; + vm_ptr->ac_mode = 0; + } + if (trbegin_ptr->components_len != 0) // has components + { + send_to_cha(proc,trbegin_ptr->components,trbegin_ptr->components_len); + tcbegin_ptr->component_present = 1; + } + else + tcbegin_ptr->component_present = 0; + vm_ptr->proto_type = proto_type; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return 1; +} + +void tcap_con_request(u32 proc) +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCContinue_struct *tccon_ptr; + struct TSL_struct tsl_data; + struct TRContinue_struct *trcon_ptr; + struct dlgPDU_struct pdu_data; + u8 ii,proto_type; + u8 cmp_level; + u8 temp=0; + u8 data_flag,sls; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + data_flag = int_ptr->dlgsend_tail; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[data_flag]; + tccon_ptr = (TCContinue_struct *) &csl_ptr->dlg_prim.tc_continue; + tsl_data.message_type = csl_ptr->message_type; + tsl_data.message_flag = REQUEST; + if ((csl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + memcpy(&tsl_data.local_add,&vm_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&tsl_data.peer_add,&vm_ptr->peer_add,sizeof(SCCP_ADDR)); + trcon_ptr = (TRContinue_struct *) &tsl_data.tsl_prim.tr_continue; + trcon_ptr->local_tid = proc; + trcon_ptr->peer_tid = vm_ptr->peer_tid; + trcon_ptr->dialogue_len = trcon_ptr->components_len = 0; + if (tccon_ptr->dialogue_flag == 1) // has dialogue portion + { + if (!proto_type) + { + pdu_data.dialogue_type = PDU_AARE; + memcpy(pdu_data.pdu_union.aarq.version,Version_1,2); + pdu_data.pdu_union.aare.result = Accepted; + pdu_data.pdu_union.aare.diagnostic_flag = Dialogue_Service_User; + pdu_data.pdu_union.aare.diagnostic_type = DSU_N; + } + else + { + pdu_data.dialogue_type = PDU_ASUDT; + pdu_data.pdu_union.asudt.version = Version_Ansi; + } + set_dlgpdu(&pdu_data,&tccon_ptr->dlg_data); + trcon_ptr->dialogue_len = build_dp(trcon_ptr->dialogue,&pdu_data,0,proto_type); + cmp_level = 0; + } + else + cmp_level = 1; + ii = tccon_ptr->component_present; + if (ii != 0) + trcon_ptr->components_len = get_from_cha(trcon_ptr->components,proc,&temp,ii,cmp_level); + if (temp != 0) // components is too long + { + tccon_ptr->component_present -= temp; + tccon_ptr->dialogue_flag = 0; + tcap_send_error("CSL error. component is too long"); + } + else + { + if (data_flag != tcap_dlg_t[proc]) + { + data_flag = tcap_dlg_t[proc]; + debug_ptr->watch_dog[186] ++; + } + int_ptr->dlgsend_tail = (data_flag + 1) % MAX_TSL_BUF; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + } + sls = tcap_get_sls(vm_ptr->peer_tid); + tsl_data.peer_tid_len = vm_ptr->peer_tid_len; //modified by Pierre, 06-08-19 + tcap_to_sccp_class(&tsl_data,sls,0,proc); +} + +u8 tcap_con_indicate(u32 proc,u8 data_flag,u8 state_flag) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct TRContinue_struct *trcon_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCContinue_struct *tccon_ptr; + struct dlgPDU_struct pdu_data; + u8 ii,proto_type,pabort_cause; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[data_flag]; + trcon_ptr = (TRContinue_struct *) &tsl_ptr->tsl_prim.tr_continue; + if (state_flag == TCAP_IS) + { + memcpy(&vm_ptr->peer_add,&tsl_ptr->peer_add,sizeof(SCCP_ADDR)); + vm_ptr->peer_tid = trcon_ptr->peer_tid; + } + if ((tsl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + ii = int_ptr->dlgrecv_head; + if (((ii+1) %MAX_TSL_BUF) == int_ptr->dlgrecv_tail) // buffer is full + { + tcap_send_error("TCAP error. TCAP to TCU buffer is full"); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_tail,proto_type); + send_pabort_sccp(vm_ptr->peer_tid_len, //modified by Pierre, 06-08-19 + vm_ptr->peer_tid,pabort_cause,&vm_ptr->local_add,&vm_ptr->peer_add,proto_type); + return 0; + } + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[ii]; + csl_ptr->message_type = tsl_ptr->message_type; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = proc; + tccon_ptr = (TCContinue_struct *) &csl_ptr->dlg_prim.tc_continue; + if (trcon_ptr->dialogue_len != 0) + { + if (!proto_type) + { + if (state_flag == TCAP_ACTIVE || vm_ptr->ac_mode == 0) + { + tcap_send_error("CSL error. Continue primitive has dialogue portion, but do not need it"); + pdu_data.dialogue_type = PDU_ABRT; + pdu_data.pdu_union.abrt.abort_source = ABRTDlg_Service_Provider; + pdu_data.pdu_union.abrt.user_info_len = 0; + send_uabort_sccp(proc,&pdu_data,ITU_TCAP,0,NULL); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return 0; + } + if (!extract_dp(&pdu_data,trcon_ptr->dialogue,trcon_ptr->dialogue_len,proto_type) || pdu_data.dialogue_type != PDU_AARE) + { + tcap_send_error("CSL error. Continue primitive has error dialogue portion"); + pdu_data.dialogue_type = PDU_ABRT; + pdu_data.pdu_union.abrt.abort_source = ABRTDlg_Service_Provider; + pdu_data.pdu_union.abrt.user_info_len = 0; + send_uabort_sccp(proc,&pdu_data,ITU_TCAP,0,NULL); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return 0; + } + } + else + { + extract_dp(&pdu_data,trcon_ptr->dialogue,trcon_ptr->dialogue_len,proto_type); + if ((pdu_data.pdu_union.asudt.version != 0) && + (pdu_data.pdu_union.asudt.version != Version_Ansi)) + { + tcap_send_error("CSL error. Ansi Conversation has error protocol version"); + return 0; + } + } + tccon_ptr->dialogue_flag = 1; + get_dlgpdu(&pdu_data,&tccon_ptr->dlg_data); + if (trcon_ptr->components_len != 0) + { + send_to_cha(proc,trcon_ptr->components,trcon_ptr->components_len); + tccon_ptr->component_present = 1; + } + else + tccon_ptr->component_present = 0; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return 1; + } + else + { + tccon_ptr->dialogue_flag = 0; + if (!proto_type) + { + if (state_flag == TCAP_ACTIVE || vm_ptr->ac_mode == 0) + { + if (trcon_ptr->components_len != 0) + { + send_to_cha(proc,trcon_ptr->components,trcon_ptr->components_len); + tccon_ptr->component_present = 1; + } + else + tccon_ptr->component_present = 0; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return 1; + } + else + { + tcap_send_error("CSL error. Continue primitive has not dialogue portion, but need it"); + pdu_data.dialogue_type = PDU_ABRT; + pdu_data.pdu_union.abrt.abort_source = ABRTDlg_Service_Provider; + pdu_data.pdu_union.abrt.user_info_len = 0; + send_uabort_sccp(proc,&pdu_data,ITU_TCAP,0,NULL); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return 0; + } + } + else + { + if (trcon_ptr->components_len != 0) + { + send_to_cha(proc,trcon_ptr->components,trcon_ptr->components_len); + tccon_ptr->component_present = 1; + } + else + tccon_ptr->component_present = 0; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return 1; + } + } +} + +u8 tcap_end_request(u32 proc) +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCEnd_struct *tcend_ptr; + struct TSL_struct tsl_data; + struct TSL_struct temp_tsl; + struct TRContinue_struct *trcon_ptr; + struct TREnd_struct *trend_ptr; + struct dlgPDU_struct pdu_data; + u8 ii,proto_type; + u8 cmp_level; + u8 temp=0; + u8 data_flag,sls; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + data_flag = int_ptr->dlgsend_tail; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[data_flag]; + tcend_ptr = (TCEnd_struct *) &csl_ptr->dlg_prim.tc_end; + if (tcend_ptr->termination == PRE_END) + { + if (data_flag != tcap_dlg_t[proc]) + { + data_flag = tcap_dlg_t[proc]; + debug_ptr->watch_dog[185] ++; + } + int_ptr->dlgsend_tail = (data_flag + 1) % MAX_TSL_BUF; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + return 1; + } + tsl_data.message_type = csl_ptr->message_type; + tsl_data.message_flag = REQUEST; + if ((csl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + memcpy(&tsl_data.local_add,&vm_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&tsl_data.peer_add,&vm_ptr->peer_add,sizeof(SCCP_ADDR)); + trend_ptr = (TREnd_struct *) &tsl_data.tsl_prim.tr_end; + trend_ptr->transaction_id = vm_ptr->peer_tid; + trend_ptr->dialogue_len = trend_ptr->components_len = 0; + if (tcend_ptr->dialogue_flag == 1) // has dialogue portion + { + if (!proto_type) + { + pdu_data.dialogue_type = PDU_AARE; + memcpy(pdu_data.pdu_union.aarq.version,Version_1,2); + pdu_data.pdu_union.aare.result = Accepted; + pdu_data.pdu_union.aare.diagnostic_flag = Dialogue_Service_User; + pdu_data.pdu_union.aare.diagnostic_type = DSU_N; + } + else + { + pdu_data.dialogue_type = PDU_ASUDT; + pdu_data.pdu_union.asudt.version = Version_Ansi; + } + set_dlgpdu(&pdu_data,&tcend_ptr->dlg_data); + trend_ptr->dialogue_len = build_dp(trend_ptr->dialogue,&pdu_data,0,proto_type); + cmp_level = 0; + } + else + cmp_level = 1; + ii = tcend_ptr->component_present; + if (ii != 0) + trend_ptr->components_len = get_from_cha(trend_ptr->components,proc,&temp,ii,cmp_level); + if (temp != 0) // components is too long + { + tcap_send_error("CSL error. component is too long"); + if (!proto_type) + temp_tsl.message_type = Continue; + else + temp_tsl.message_type = Conversation_WithPerm_Ansi; + temp_tsl.message_flag = REQUEST; + memcpy(&temp_tsl.local_add,&vm_ptr->local_add,sizeof(SCCP_ADDR)); + memcpy(&temp_tsl.peer_add,&vm_ptr->peer_add,sizeof(SCCP_ADDR)); + trcon_ptr = (TRContinue_struct *) &temp_tsl.tsl_prim.tr_continue; + trcon_ptr->local_tid = proc; + trcon_ptr->peer_tid = vm_ptr->peer_tid; + trcon_ptr->dialogue_len = trend_ptr->dialogue_len; + memcpy(trcon_ptr->dialogue,trend_ptr->dialogue,trend_ptr->dialogue_len); + trcon_ptr->components_len = trend_ptr->components_len; + memcpy(trcon_ptr->components,trend_ptr->components,trend_ptr->components_len); + tcend_ptr->dialogue_flag = 0; + tcend_ptr->component_present -= temp; + sls = tcap_get_sls(vm_ptr->peer_tid); + tsl_data.peer_tid_len = vm_ptr->peer_tid_len; + tcap_to_sccp_class(&temp_tsl,sls,0,proc); + return 0; + } + else + { + sls = tcap_get_sls(vm_ptr->peer_tid); + tsl_data.peer_tid_len = vm_ptr->peer_tid_len; + tcap_to_sccp_class(&tsl_data,sls,0,proc); + if (data_flag != tcap_dlg_t[proc]) + { + data_flag = tcap_dlg_t[proc]; + debug_ptr->watch_dog[184] ++; + } + int_ptr->dlgsend_tail = (data_flag + 1) % MAX_TSL_BUF; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + return 1; + } +} + +void tcap_end_indicate(u32 proc,u8 data_flag,u8 state_flag) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct TREnd_struct *trend_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCEnd_struct *tcend_ptr; + struct dlgPDU_struct pdu_data; + u8 ii,proto_type,pabort_cause; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[data_flag]; + trend_ptr = (TREnd_struct *) &tsl_ptr->tsl_prim.tr_end; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + if ((tsl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + ii = int_ptr->dlgrecv_head; + if (((ii+1) % MAX_TSL_BUF) == int_ptr->dlgrecv_tail) // buffer is full + { + tcap_send_error("TCAP error. TCAP to TCU buffer is full"); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_tail,proto_type); + return; + } + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[ii]; + csl_ptr->message_type = tsl_ptr->message_type; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = proc; + tcend_ptr = (TCEnd_struct *) &csl_ptr->dlg_prim.tc_end; + if (trend_ptr->dialogue_len != 0) + { + if (!proto_type) + { + if (vm_ptr->ac_mode == 0) + { + tcap_send_error("CSL error. End primitive has dialogue portion, but do not need it"); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + if (!extract_dp(&pdu_data,trend_ptr->dialogue,trend_ptr->dialogue_len,proto_type) || pdu_data.dialogue_type != PDU_AARE) + { + tcap_send_error("CSL error. End primitive has error dialogue portion"); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + } + else + { + extract_dp(&pdu_data,trend_ptr->dialogue,trend_ptr->dialogue_len,proto_type); + if ((pdu_data.pdu_union.asudt.version != 0) && + (pdu_data.pdu_union.asudt.version != Version_Ansi)) + { + tcap_send_error("CSL error. Ansi Response has error protocol version"); + return; + } + } + tcend_ptr->dialogue_flag = 1; + get_dlgpdu(&pdu_data,&tcend_ptr->dlg_data); + if (trend_ptr->components_len != 0) + { + send_to_cha(proc,trend_ptr->components,trend_ptr->components_len); + tcend_ptr->component_present = 1; + } + else + tcend_ptr->component_present = 0; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return; + } + else + { + tcend_ptr->dialogue_flag = 0; + if (!proto_type) + { + if (state_flag == TCAP_ACTIVE || vm_ptr->ac_mode == 0) + { + if (trend_ptr->components_len != 0) + { + send_to_cha(proc,trend_ptr->components,trend_ptr->components_len); + tcend_ptr->component_present = 1; + } + else + tcend_ptr->component_present = 0; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return; + } + else + { + tcap_send_error("CSL error. End primitive has not dialogue portion, but need it"); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + } + else + { + if (trend_ptr->components_len != 0) + { + send_to_cha(proc,trend_ptr->components,trend_ptr->components_len); + tcend_ptr->component_present = 1; + } + else + tcend_ptr->component_present = 0; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + return; + } + } +} + +void tcap_uabort_request(u32 proc) +{ + struct tcapvm_struct *vm_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCUAbort_struct *tcuabort_ptr; + struct dlgPDU_struct pdu_data; + u8 data_flag; + u8 proto_type; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + data_flag = int_ptr->dlgsend_tail; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + int_ptr->dlgsend_tail = (data_flag + 1) % MAX_TSL_BUF; + tcap_dlg_t[proc] = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[data_flag]; + tcuabort_ptr = (TCUAbort_struct *) &csl_ptr->dlg_prim.tc_uabort; + if ((csl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + if (!proto_type) + { + if (vm_ptr->ac_mode == 1) + { + if (tcuabort_ptr->uabort_reason == UABORT_ACNNS) + { + pdu_data.dialogue_type = PDU_AARE; + memcpy(pdu_data.pdu_union.aare.version,Version_1,2); + set_dlgpdu(&pdu_data,&tcuabort_ptr->dlg_data); + pdu_data.pdu_union.aare.result = Reject_permanent; + pdu_data.pdu_union.aare.diagnostic_flag = Dialogue_Service_User; + pdu_data.pdu_union.aare.diagnostic_type = DSU_ACNNS; + send_uabort_sccp(proc,&pdu_data,ITU_TCAP,0,NULL); + } + else if (tcuabort_ptr->dlg_data.user_info_len != 0) + { + pdu_data.dialogue_type = PDU_ABRT; + pdu_data.pdu_union.abrt.abort_source = ABRTDlg_Service_User; + set_dlgpdu(&pdu_data,&tcuabort_ptr->dlg_data); + send_uabort_sccp(proc,&pdu_data,ITU_TCAP,0,NULL); + } + else + send_pabort_sccp(vm_ptr->peer_tid_len, + vm_ptr->peer_tid,P_Abort_NCDP,&vm_ptr->local_add,&vm_ptr->peer_add,proto_type); + } + else + send_pabort_sccp(vm_ptr->peer_tid_len, + vm_ptr->peer_tid,P_Abort_NCDP,&vm_ptr->local_add,&vm_ptr->peer_add,proto_type); + } + else + { + pdu_data.dialogue_type = PDU_ASUDT; + pdu_data.pdu_union.asudt.version = Version_Ansi; + set_dlgpdu(&pdu_data,&tcuabort_ptr->dlg_data); + send_uabort_sccp(proc,&pdu_data,proto_type,tcuabort_ptr->uabort_info_len,tcuabort_ptr->uabort_info); + } +} + +void tcap_uabort_indicate(u32 proc,u8 data_flag) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct TRUAbort_struct *truabort_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCUAbort_struct *tcuabort_ptr; + struct dlgPDU_struct pdu_data; + u8 ii,proto_type,pabort_cause; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[data_flag]; + truabort_ptr = (TRUAbort_struct *) &tsl_ptr->tsl_prim.tr_uabort; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + if ((tsl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + ii = int_ptr->dlgrecv_head; + if (((ii+1) %MAX_TSL_BUF) == int_ptr->dlgrecv_tail) // buffer is full + { + tcap_send_error("TCAP error. TCAP to TCU buffer is full"); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_tail,proto_type); + return; + } + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[ii]; + csl_ptr->message_type = tsl_ptr->message_type; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = proc; + tcuabort_ptr = (TCUAbort_struct *) &csl_ptr->dlg_prim.tc_uabort; + if (truabort_ptr->dialogue_len != 0) + { + if (!proto_type) + { + if (vm_ptr->ac_mode == 0) + { + tcap_send_error("CSL error. U_Abort primitive has dialogue portion, but do not need it"); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + if (!extract_dp(&pdu_data,truabort_ptr->dialogue,truabort_ptr->dialogue_len,proto_type)) + { + tcap_send_error("CSL error. U_Abort primitive has error dialogue portion"); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + } + else + { + extract_dp(&pdu_data,truabort_ptr->dialogue,truabort_ptr->dialogue_len,proto_type); + if ((pdu_data.pdu_union.asudt.version != 0) && + (pdu_data.pdu_union.asudt.version != Version_Ansi)) + { + tcap_send_error("CSL error. Ansi Uabort has error protocol version"); + return; + } + } + tcuabort_ptr->dialogue_flag = 1; + get_dlgpdu(&pdu_data,&tcuabort_ptr->dlg_data); + if (!proto_type) + { + if (pdu_data.dialogue_type == PDU_AARE) + tcuabort_ptr->uabort_reason = UABORT_ACNNS; + else if (pdu_data.dialogue_type == PDU_ABRT) + { + if (pdu_data.pdu_union.abrt.abort_source == ABRTDlg_Service_User) + tcuabort_ptr->uabort_reason = UABORT_NULL; + else + { + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + } + else + { + tcap_send_error("CSL error. U_Abort primitive has error dialogue portion"); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + } + } + else + { + if (!proto_type) + { + if (vm_ptr->ac_mode == 1) + { + tcap_send_error("CSL error. U_Abort primitive has not dialogue portion, but need it"); + send_pabort_tcu(proc,P_Abort_ADLG,ii,proto_type); + return; + } + tcuabort_ptr->uabort_reason = UABORT_SPEC; + } + tcuabort_ptr->dialogue_flag = 0; + } + if (proto_type) + { + tcuabort_ptr->uabort_info_len = truabort_ptr->uabort_info_len; + memcpy(tcuabort_ptr->uabort_info, truabort_ptr->uabort_info, truabort_ptr->uabort_info_len); + } + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; +} + +void tcap_pabort_indicate(u32 proc,u8 data_flag) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct TRPAbort_struct *trpabort_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCPAbort_struct *tcpabort_ptr; + u8 ii,proto_type,pabort_cause; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[data_flag]; + trpabort_ptr = (TRPAbort_struct *) &tsl_ptr->tsl_prim.tr_pabort; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + if ((tsl_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS) + proto_type = ANSI_TCAP; + else + proto_type = ITU_TCAP; + ii = int_ptr->dlgrecv_head; + if (((ii+1) %MAX_TSL_BUF) == int_ptr->dlgrecv_tail) // buffer is full + { + tcap_send_error("TCAP error. TCAP to TCU buffer is full"); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_tail,proto_type); + } + else + { + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[ii]; + csl_ptr->message_type = tsl_ptr->message_type; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = proc; + tcpabort_ptr = (TCPAbort_struct *) &csl_ptr->dlg_prim.tc_pabort; + tcpabort_ptr->pabort_reason = trpabort_ptr->abort_reason; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + } +} + +void tcap_notice_indicate(u32 proc,u8 data_flag,u8 proto_type) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct TRNotice_struct *trnotice_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + struct TCNotice_struct *tcnotice_ptr; + u8 ii,pabort_reason; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[data_flag]; + trnotice_ptr = (TRNotice_struct *) &tsl_ptr->tsl_prim.tr_notice; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + ii = int_ptr->dlgrecv_head; + if (((ii+1) %MAX_TSL_BUF) == int_ptr->dlgrecv_tail) // buffer is full + { + tcap_send_error("TCAP error. TCAP to TCU buffer is full"); + if (!proto_type) + pabort_reason = P_Abort_RL; + else + pabort_reason = P_Abort_RL_Ansi; + send_pabort_tcu(proc,pabort_reason,int_ptr->dlgrecv_tail,proto_type); + } + else + { + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_recv[ii]; + csl_ptr->message_type = Notice; + csl_ptr->message_flag = INDICATE; + csl_ptr->dialogue_id = proc; + tcnotice_ptr = (TCNotice_struct *) &csl_ptr->dlg_prim.tc_notice; + tcnotice_ptr->report_reason = trnotice_ptr->report_cause; + int_ptr->dlgrecv_head = (ii + 1) % MAX_TSL_BUF; + } +} + +void tsm_program(u32 proc) +{ + struct tcapvm_struct *vm_ptr; + struct TSL_struct *tsl_ptr; + struct tcapint_struct *int_ptr; + struct CSLdlg_struct *csl_ptr; + u8 ii,pabort_cause,proto_type; + u8 info[128]; + //char info_str[1024]; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + int_ptr = (tcapint_struct *) &tcap_ptr->tcapint_data[proc]; + proto_type = vm_ptr->proto_type; + + switch (vm_ptr->tcap_state) + { + case TCAP_INIT: + tcap_clear_fsm(proc); + free_did(proc); + debug_ptr->watch_dog[217] ++; + vm_ptr->tcap_state = TCAP_IDLE; + break; + case TCAP_IDLE: + if (vm_ptr->tcaprecv_head != vm_ptr->tcaprecv_tail) + { + ii = vm_ptr->tcaprecv_tail; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[ii]; + vm_ptr->tcaprecv_tail = (ii + 1) % MAX_TSL_BUF; + switch (tsl_ptr->message_type) + { + case Begin: + case Query_WithPerm_Ansi: + case Query_WithoutPerm_Ansi: + if (tcap_begin_indicate(proc,ii)) + vm_ptr->tcap_state = TCAP_IR; + else + { + debug_ptr->watch_dog[212] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + vm_ptr->tcap_timer = 0; + break; + case Unidirectional: + case Unidirectional_Ansi: + if (tcap_uni_indicate(proc,ii)) + { + debug_ptr->watch_dog[211] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + else + { + debug_ptr->watch_dog[210] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + vm_ptr->tcap_timer = 0; + break; + default: + sprintf((char *)info, "TSL error. Improper message Received from lower layer in idle state, did: %u, type: %d", proc, tsl_ptr->message_type); + tcap_send_error((char *)info); + //printf("TSL error. Improper message Received from lower layer in idle state, did: %ld, type: %d", proc, tsl_ptr->message_type); + debug_ptr->watch_dog[225]++; + debug_ptr->watch_dog[73] ++; + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + } + } + else + { + if (int_ptr->dlgsend_head != int_ptr->dlgsend_tail) + { + ii = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[ii]; + switch (csl_ptr->message_type) + { + case Begin: + case Query_WithPerm_Ansi: + case Query_WithoutPerm_Ansi: + debug_ptr->watch_dog[71] ++; + if (tcap_begin_request(proc)) + vm_ptr->tcap_state = TCAP_IS; + else + { + debug_ptr->watch_dog[209] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + vm_ptr->tcap_timer = 0; + break; + case Unidirectional: + case Unidirectional_Ansi: + tcap_uni_request(proc,ii); + vm_ptr->tcap_timer = 0; + debug_ptr->watch_dog[208] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + default: + sprintf((char *)info, "TSL error. Improper message Received from tc user in idle state, did: %u, type: %d", proc, csl_ptr->message_type); + tcap_send_error((char *)info); + //printf("TSL error. Improper message Received from tc user in idle state, did: %ld, type: %d\n", proc, csl_ptr->message_type); + debug_ptr->watch_dog[224]++; + debug_ptr->watch_dog[73] ++; + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + } + } + } + if (check_did(proc)) + { + if ((vm_ptr->tcap_timer++) >= IDLE_TIMER*TCAP_TIMERHZ) + { + vm_ptr->tcap_timer = 0; + debug_ptr->watch_dog[216] ++; + vm_ptr->tcap_state = TCAP_INIT; + } + } + break; + case TCAP_IR: + if (int_ptr->dlgsend_head != int_ptr->dlgsend_tail) + { + ii = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[ii]; + switch (csl_ptr->message_type) + { + case Continue: + case Conversation_WithPerm_Ansi: + case Conversation_WithoutPerm_Ansi: + debug_ptr->watch_dog[74] ++; + tcap_con_request(proc); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_ACTIVE; + break; + case End: + case Response_Ansi: + debug_ptr->watch_dog[75] ++; + vm_ptr->tcap_timer = 0; + if (tcap_end_request(proc)) + { + debug_ptr->watch_dog[207] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + else + vm_ptr->tcap_state = TCAP_ACTIVE; + break; + case U_Abort: + case U_Abort_Ansi: + debug_ptr->watch_dog[78] ++; + tcap_uabort_request(proc); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + default: + break; + } + } + if ((vm_ptr->tcap_timer++) >= (xap_get_est_timer()+60)*TCAP_TIMERHZ) + { + sprintf((char *)info, "TSL error. timer expired in TCAP_IR state, did: %u", proc); + tcap_send_error((char *)info); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_sccp(vm_ptr->peer_tid_len, + vm_ptr->peer_tid,pabort_cause,&vm_ptr->local_add,&vm_ptr->peer_add,proto_type); + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_head,proto_type); + vm_ptr->tcap_timer = 0; + debug_ptr->watch_dog[206] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + break; + case TCAP_IS: + if (vm_ptr->tcaprecv_head != vm_ptr->tcaprecv_tail) + { + ii = vm_ptr->tcaprecv_tail; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[ii]; + vm_ptr->tcaprecv_tail = (ii + 1) % MAX_TSL_BUF; + switch (tsl_ptr->message_type) + { + case Continue: + case Conversation_WithPerm_Ansi: + case Conversation_WithoutPerm_Ansi: + debug_ptr->watch_dog[80] ++; + vm_ptr->tcap_timer = 0; + if (tcap_con_indicate(proc,ii,TCAP_IS)) + vm_ptr->tcap_state = TCAP_ACTIVE; + else + { + debug_ptr->watch_dog[205] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + break; + case End: + case Response_Ansi: + debug_ptr->watch_dog[81] ++; + tcap_end_indicate(proc,ii,TCAP_IS); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + case U_Abort: + case U_Abort_Ansi: + debug_ptr->watch_dog[82] ++; + tcap_uabort_indicate(proc,ii); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + case P_Abort: + case P_Abort_Ansi: + debug_ptr->watch_dog[83] ++; + tcap_pabort_indicate(proc,ii); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + case Notice: + tcap_notice_indicate(proc,ii,proto_type); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + debug_ptr->watch_dog[204] ++; + break; + default: + break; + } + } + else + { + if (int_ptr->dlgsend_head != int_ptr->dlgsend_tail) + { + ii = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[ii]; + switch (csl_ptr->message_type) + { + case End: + case Response_Ansi: + debug_ptr->watch_dog[75] ++; + vm_ptr->tcap_timer = 0; + if (tcap_end_request(proc)) + { + debug_ptr->watch_dog[203] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + else + vm_ptr->tcap_state = TCAP_ACTIVE; + break; + case U_Abort: + case U_Abort_Ansi: + tcap_uabort_request(proc); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + debug_ptr->watch_dog[202] ++; + break; + default: + break; + } + } + } + if ((vm_ptr->tcap_timer++) >= (xap_get_est_timer()+60)*TCAP_TIMERHZ) + { + sprintf((char *)info, "TSL error. timer expired in TCAP_IS state, did: %u", proc); + tcap_send_error((char *)info); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; +// send_pabort_sccp(vm_ptr->peer_tid_len,vm_ptr->peer_tid,pabort_cause,&vm_ptr->local_add,&vm_ptr->peer_add,proto_type); + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_head,proto_type); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + debug_ptr->watch_dog[201] ++; + } + break; + case TCAP_ACTIVE: + if (vm_ptr->tcaprecv_head != vm_ptr->tcaprecv_tail) + { + ii = vm_ptr->tcaprecv_tail; + tsl_ptr = (TSL_struct *) &vm_ptr->tsl_data[ii]; + vm_ptr->tcaprecv_tail = (ii + 1) % MAX_TSL_BUF; + switch (tsl_ptr->message_type) + { + case Continue: + case Conversation_WithPerm_Ansi: + case Conversation_WithoutPerm_Ansi: + debug_ptr->watch_dog[84] ++; + if (!tcap_con_indicate(proc,ii,TCAP_ACTIVE)) + { + debug_ptr->watch_dog[200] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + vm_ptr->tcap_timer = 0; + break; + case End: + case Response_Ansi: + debug_ptr->watch_dog[86] ++; + tcap_end_indicate(proc,ii,TCAP_ACTIVE); + vm_ptr->tcap_state = TCAP_SUSPEND; + vm_ptr->tcap_timer = 0; + break; + case U_Abort: + case U_Abort_Ansi: + debug_ptr->watch_dog[88] ++; + tcap_uabort_indicate(proc,ii); + vm_ptr->tcap_state = TCAP_SUSPEND; + vm_ptr->tcap_timer = 0; + break; + case P_Abort: + case P_Abort_Ansi: + debug_ptr->watch_dog[90] ++; + tcap_pabort_indicate(proc,ii); + vm_ptr->tcap_state = TCAP_SUSPEND; + vm_ptr->tcap_timer = 0; + break; + case Notice: + tcap_notice_indicate(proc,ii,proto_type); + vm_ptr->tcap_state = TCAP_SUSPEND; + vm_ptr->tcap_timer = 0; + debug_ptr->watch_dog[199] ++; + break; + default: + break; + } + } + else + { + if (int_ptr->dlgsend_head != int_ptr->dlgsend_tail) + { + ii = int_ptr->dlgsend_tail; + csl_ptr = (CSLdlg_struct *) &int_ptr->dlg_send[ii]; + switch (csl_ptr->message_type) + { + case Continue: + case Conversation_WithPerm_Ansi: + case Conversation_WithoutPerm_Ansi: + debug_ptr->watch_dog[85] ++; + vm_ptr->tcap_timer = 0; + tcap_con_request(proc); + break; + case End: + case Response_Ansi: + debug_ptr->watch_dog[87] ++; + vm_ptr->tcap_timer = 0; + if (tcap_end_request(proc)) + { + debug_ptr->watch_dog[198] ++; + vm_ptr->tcap_state = TCAP_SUSPEND; + } + break; + case U_Abort: + case U_Abort_Ansi: + debug_ptr->watch_dog[89] ++; + tcap_uabort_request(proc); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + break; + default: + break; + } + } + } + if ((vm_ptr->tcap_timer++) >= (xap_get_est_timer()+60)*TCAP_TIMERHZ) + { + sprintf((char *)info, "TSL error. timer expired in TCAP_ACTIVE state, did: %u", proc); + tcap_send_error((char *)info); + if (proto_type) + pabort_cause = P_Abort_RL_Ansi; + else + pabort_cause = P_Abort_RL; + send_pabort_sccp(vm_ptr->peer_tid_len, + vm_ptr->peer_tid,pabort_cause,&vm_ptr->local_add,&vm_ptr->peer_add,proto_type); + send_pabort_tcu(proc,pabort_cause,int_ptr->dlgrecv_head,proto_type); + vm_ptr->tcap_timer = 0; + vm_ptr->tcap_state = TCAP_SUSPEND; + debug_ptr->watch_dog[197] ++; + } + break; + case TCAP_SUSPEND: + if (check_csldata(proc)) + vm_ptr->tcap_state = TCAP_INIT; + else if ((vm_ptr->tcap_timer++) >= SUSPEND_TIMER*TCAP_TIMERHZ) + + vm_ptr->tcap_state = TCAP_INIT; + + /* + if ((vm_ptr->tcap_timer++) >= 10 ) + { + if (!check_csldata(proc)) + { + sprintf(info_str, "TCAP_SUSPEND error. did: %ld", proc); + tcap_send_error(info_str); + } + vm_ptr->tcap_state = TCAP_INIT; + debug_ptr->watch_dog[215] ++; + }*/ + break; + default: + vm_ptr->tcap_state = TCAP_INIT; + debug_ptr->watch_dog[214] ++; + break; + } +} + +void ism_program(u32 proc) // invocation state machine +{ + register u8 inv_proc,total_iid; + struct tcapvm_struct *vm_ptr; + struct ismvm_data *shm_ptr; + char info_str[1024]; + u8 proto_type,problem_type,problem_code; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + /* + total_iid = (vm_ptr->total_iid+1) ; + if(total_iid> MAX_TEMPINVOKEID) + */ + total_iid = MAX_TEMPINVOKEID ; + + proto_type = vm_ptr->proto_type; + for (inv_proc = 0;inv_proc < total_iid;inv_proc++) + { + shm_ptr = (ismvm_data *) &vm_ptr->ism_data[inv_proc]; + switch (shm_ptr->ism_state) + { + case TCAP_INIT: + free_iid(proc,shm_ptr->linked_iid); //add by daniel on 2006-6-15 + //this problem(call will drop after 4600s) was found in OMT + //it is because of the invoke id occupation do not release after assigned + + //tcap_send_ascout("tcap init free linked_did\r\n"); + memset(shm_ptr,0,sizeof(ismvm_data)); + shm_ptr->ism_state = TCAP_IDLE; + break; + case TCAP_IDLE: + if ((shm_ptr->ism_msgtype == Invoke) || + (shm_ptr->ism_msgtype == Invoke_L_Ansi) || + (shm_ptr->ism_msgtype == Invoke_NL_Ansi)) + { + shm_ptr->ism_msgtype = 0; + switch (shm_ptr->ism_msgclass) + { + case OPERATION_CLASS1: + shm_ptr->ism_state = SENT_STATE1; + break; + case OPERATION_CLASS2: + shm_ptr->ism_state = SENT_STATE2; + break; + case OPERATION_CLASS3: + shm_ptr->ism_state = SENT_STATE3; + break; + case OPERATION_CLASS4: + shm_ptr->ism_state = SENT_STATE4; + break; + default: + shm_ptr->ism_state = SENT_STATE4; + break; + } + } + break; + case SENT_STATE1: + if ((shm_ptr->ism_timer--) == 0) // invocation timer expiry + { + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Invoke timer expired 1. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + send_cancel_tcu(proc,shm_ptr->linked_iid); + shm_ptr->ism_state = TCAP_INIT; + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][71] ++; + debug_ptr->watch_dog[234]++; + } + switch (shm_ptr->ism_msgtype) + { + case Result_L: + case Result_L_Ansi: + case Error: + case Error_Ansi: + shm_ptr->ism_timer = 0; + shm_ptr->ism_state = WAIT_REJECT_STATE; + shm_ptr->ism_msgtype = 0; + break; + case Result_NL: + case Result_NL_Ansi: + case Invoke_NL_Ansi: + shm_ptr->ism_msgtype = 0; + break; + default: + break; + } + break; + case SENT_STATE2: + if ((shm_ptr->ism_timer--) == 0) // invocation timer expiry + { + if (debug_ptr->error_switch) + { + // sprintf(info_str,"ISM warning. Invoke timer expired 2. Did: %ld, Iid: %d",proc,shm_ptr->linked_iid); + // tcap_send_error(info_str); + } + send_cancel_tcu(proc,shm_ptr->linked_iid); + shm_ptr->ism_state = TCAP_INIT; + debug_ptr->watch_dog[233]++; + } + switch (shm_ptr->ism_msgtype) + { + case Error: + case Error_Ansi: + shm_ptr->ism_timer = 0; + shm_ptr->ism_state = WAIT_REJECT_STATE; + shm_ptr->ism_msgtype = 0; + break; + case Result_L: + case Result_NL: + case Result_L_Ansi: + case Result_NL_Ansi: + if (proto_type) + { + problem_type = Return_Result_Ansi; + problem_code = Return_Result_RRU_Ansi; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Result_Ansi not expected 1. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + else + { + problem_type = Return_Result; + problem_code = Return_Result_RRU; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Result not expected 1. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + send_reject_tcu(proc,shm_ptr->linked_iid,problem_type,problem_code,proto_type); + shm_ptr->ism_state = TCAP_INIT; + break; + default: + break; + } + break; + case SENT_STATE3: + if ((shm_ptr->ism_timer--) == 0) // invocation timer expiry + { + if (debug_ptr->error_switch) + { + // sprintf(info_str,"ISM warning. Invoke timer expire. Did: %ld, Iid: %d",proc,shm_ptr->linked_iid); + // tcap_send_error(info_str); + } + send_cancel_tcu(proc,shm_ptr->linked_iid); + shm_ptr->ism_state = TCAP_INIT; + debug_ptr->watch_dog[232]++; + } + switch (shm_ptr->ism_msgtype) + { + case Result_L: + case Result_L_Ansi: + shm_ptr->ism_timer = 0; + shm_ptr->ism_state = WAIT_REJECT_STATE; + shm_ptr->ism_msgtype = 0; + break; + case Result_NL: + case Result_NL_Ansi: + shm_ptr->ism_msgtype = 0; + break; + case Error: + case Error_Ansi: + if (proto_type) + { + problem_type = Return_Error_Ansi; + problem_code = Return_Error_REU_Ansi; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Error_Ansi not expected 1. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + else + { + problem_type = Return_Error; + problem_code = Return_Error_REU; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Error not expected 1. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + send_reject_tcu(proc,shm_ptr->linked_iid,problem_type,problem_code,proto_type); + shm_ptr->ism_state = TCAP_INIT; + break; + default: + break; + } + break; + case SENT_STATE4: + if ((shm_ptr->ism_timer--) == 0) // invocation timer expiry + { + if (debug_ptr->error_switch) + { + // sprintf(info_str,"ISM warning. Invoke timer expired 4. Did: %ld, Iid: %d",proc,shm_ptr->linked_iid); + // tcap_send_error(info_str); + } + send_cancel_tcu(proc,shm_ptr->linked_iid); + shm_ptr->ism_state = TCAP_INIT; + debug_ptr->watch_dog[231]++; + } + switch (shm_ptr->ism_msgtype) + { + case Result_NL: + case Result_L: + case Result_NL_Ansi: + case Result_L_Ansi: + if (proto_type) + { + problem_type = Return_Result_Ansi; + problem_code = Return_Result_RRU_Ansi; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Result_Ansi not expected 2. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + else + { + problem_type = Return_Result; + problem_code = Return_Result_RRU; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Result not expected 2. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + send_reject_tcu(proc,shm_ptr->linked_iid,problem_type,problem_code,proto_type); + shm_ptr->ism_state = TCAP_INIT; + break; + case Error: + case Error_Ansi: + if (proto_type) + { + problem_type = Return_Error_Ansi; + problem_code = Return_Error_REU_Ansi; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Error_Ansi not expected 2. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + else + { + problem_type = Return_Error; + problem_code = Return_Error_REU; + if (debug_ptr->error_switch) + { + sprintf(info_str,"ISM warning. Return_Error not expected 2. Did: %u, Iid: %d",proc,shm_ptr->linked_iid); + tcap_send_error(info_str); + } + } + send_reject_tcu(proc,shm_ptr->linked_iid,problem_type,problem_code,proto_type); + shm_ptr->ism_state = TCAP_INIT; + break; + default: + break; + } + break; + case WAIT_REJECT_STATE: + if ((shm_ptr->ism_timer++) >= debug_ptr->default_rejtime * ISM_TIMERHZ) + shm_ptr->ism_state = TCAP_INIT; + break; + default: + shm_ptr->ism_state = TCAP_INIT; + break; + } + } +} + +void tcap_change_local_ssn(u32 proc,u8 src_ssn,u8 dst_ssn) +{ + struct tcapvm_struct *vm_ptr; + + if (proc >= (tcap_ptr->grantdid)) + return; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + if (src_ssn == vm_ptr->local_add.SSN) + vm_ptr->local_add.SSN = dst_ssn; +} + +void tcap_change_local_tt(u32 proc,u8 src_ssn,u8 tt) //change local tt for ANSI network +{ + struct tcapvm_struct *vm_ptr; + + if (proc >= (tcap_ptr->grantdid)) + return; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + if (src_ssn == vm_ptr->local_add.SSN) + vm_ptr->local_add.TT = tt; +} + +extern int GetMSISDNOfSSN ( BYTE ssn, BYTE * msisdn ); +u8 tcap_change_local_gtt(u32 proc, u8 uSSN) +{ + struct tcapvm_struct *vm_ptr; + u8 aGTT[ISDN_LEN]; + + if (proc >= (tcap_ptr->grantdid)) + return 0; + + vm_ptr = (tcapvm_struct *) &tcap_ptr->tcapvm_data[proc]; + if (uSSN != vm_ptr->local_add.SSN) + return 0; + + if( GetMSISDNOfSSN ( uSSN, aGTT ) ) + { + u8 aISDN[ISDN_LEN]; + + GttToIsdn ( aISDN, aGTT ); + vm_ptr->local_add.len = IsdnToGtai( vm_ptr->local_add.GTAI ,aISDN ); + return vm_ptr->local_add.len; + } + return 0; + } + +/*@end@*/ diff --git a/plat/tcap/src/tcap_m.c b/plat/tcap/src/tcap_m.c new file mode 100644 index 0000000..ef21790 --- /dev/null +++ b/plat/tcap/src/tcap_m.c @@ -0,0 +1,603 @@ +/* TCAP monitor c file */ +/* Written by Liu Zhiguo 2002-05-06 */ +/* Version 1.0 */ +/* ----------------------------------- */ +#include "../../public/src/include/pub_include.h" +#include "../../sccp/src/include/sccp.h" +#include "../../debug/src/include/debug.h" +#include "../../snmp/src/include/snmp.h" +#include "../../snmp/src/include/heartbeat.h" +#include "./include/tcap_public.h" +#include "./include/tcap_struct.h" +#include "./include/idmanage.h" + + +/*@ignore@*/ +#define LED_GREEN 9 +#define LED_YELLOW 10 +#define LED_RED 11 +#define MAX_PAGE 8 +#define MAX_LINE 22 +#define STATE_LINE 20 +#define TCAP_CSTA_INTERVAL 15 // tcap CDR interval time:15 minutes +#define TCAP_PREOBJ_LEN 11 // tcap prefix object id length +#define TCAP_HBOBJ_LEN 14 // tcap heartbeat led object id length +#define TCAP_ID_LEN 15 +#define TCAP_TITLE_LEN 16 +#define TCAP_LINE_LEN 17 +#define TCAP_PAGE_POINT 14 +#define TCAP_LINE_POINT 15 +#define TCAP_VERSION_LEN 3 + +static struct tcapdebug_struct *debug_ptr; +extern u32 tcap_dlg_stats[MAX_DIALOGUEID]; + +static u8 tcap_1s_flag; +static u8 tcap_10s_flag; +static u8 sec_page; +static u8 *disp_ptr; +static u8 tcap_status = 1; +static u32 tcap_object_id[] = {1,3,6,1,4,1,1373,2,3,2,4}; +static u32 tcap_status_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,TCAP_MODULE_ID + 2,1}; +static u32 tcap_version_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,TCAP_MODULE_ID + 2,2}; +static u32 tcap_ascin_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,TCAP_MODULE_ID + 2,3}; +static u32 tcap_ascout_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,TCAP_MODULE_ID + 2,4}; +static u32 tcap_page_title[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,TCAP_MODULE_ID + 2,5,1}; +static u32 tcap_page_line[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,TCAP_MODULE_ID + 2,5,2,2}; +//static u8 tcap_ver[] = {6,5,10}; +static u8 tcap_ver[] = {1,0,01}; +static u8 title1[] = {"Page 01\t\tTCAP module information\r\n\nStart time\r\nCurrent time\r\nInvoke timer\r\nReject timer\r\nMonitor did\r\nTcap status\r\n"}; +static u8 title2[] = {"Page 02\t\tTCAP watch_dog page\r\n\t\t 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15\r\n"}; +static u8 title3[] = {"Page 03\t\tTCAP CSTA information\r\n\t\t 00\t 01\t 02\t 03\t 04\r\nSection page\r\n"}; + +static u8 ascii[16] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46}; + +void HexToDisplay(u8 *to_asc, u8 *from_hex, u8 from_len) +{ + int i, j = 0; + + for (i = 0; i < from_len; i++) + { + to_asc[j] = ascii[from_hex[i] >> 4]; + j++; + to_asc[j] = ascii[from_hex[i] & 0x0f]; + j++; + to_asc[j] = ' '; + j++; + } + to_asc[j] = '\0'; +} + +void tcap_send_ascout(char *asc_str) +{ + if (debug_ptr->send_control == 1) + return; + if ((strlen(asc_str) + strlen((char *)debug_ptr->ascout_buf)) > TCAP_ASCOUT_LEN/2) // buffer is full + { + debug_ptr->send_control = 1; +// strcat(debug_ptr->ascout_buf,"\r\n--\r\n"); +// strcpy(debug_ptr->ascout_buf,asc_str); + } + else + strcat((char *)debug_ptr->ascout_buf,asc_str); +} + +void tcap_send_error(char *err_str) +{ + char info_str[1024]; + + if (debug_ptr->error_switch == 0 || debug_ptr->send_control == 1) + return; + sprintf(info_str,"\33[31m%s\33[0m\n\r\n\r",err_str); + tcap_send_ascout(info_str); +} + +void tcap_send_info(char *info) +{ + char info_str[1024]; + + if (debug_ptr->sccp_switch == 0 || debug_ptr->send_control == 1) + return; + sprintf(info_str,"%s\n\r",info); + tcap_send_ascout(info_str); +} + +u8 tcap_disp_line(u8 page,u8 line) +{ + u8 line_len=0; + u32 ii; + + disp_ptr = tcap_ver; + switch (page) + { + case 1: // page 1 + switch (line) + { + case 0: + disp_ptr = debug_ptr->start_time; + line_len = 6; + break; + case 1: + disp_ptr = debug_ptr->current_time; + line_len = 6; + break; + case 2: // invoke time + disp_ptr = &debug_ptr->default_invtime; + line_len = 1; + break; + case 3: // reject time + disp_ptr = &debug_ptr->default_rejtime; + line_len = 1; + break; + case 4: // monitor dialogue id + disp_ptr = (u8 *) &debug_ptr->monitor_did; + line_len = 4; + break; + case 5: // heartbeat status + disp_ptr = debug_ptr->hb_status; + line_len = TCAP_HB_LEN; + break; + case 6: + line_len = 8; + disp_ptr = (u8 *)&debug_ptr->local_ip; + break; + default: + line_len = 0; + break; + } + break; + case 2: // page 2 + if (line < 16) + { + disp_ptr = debug_ptr->watch_dog + line * 16; + line_len = 16; + } + break; + case 3: // page 3 + if (line == 0) + { + disp_ptr = &sec_page; + line_len = 1; + } + else if (line < TCAP_UTILIZE_LEN/5+1) + { + ii = sec_page % (TCAP_UTILIZE_COUNT-1); + disp_ptr = (u8 *)&debug_ptr->tc_utilize[ii][(line-1)*5]; + line_len = 20; + } + break; + case 4: // tcap state + if (line < STATE_LINE) + { + ii = (sec_page * STATE_LINE + line) % (tcap_ptr->grantdid); + disp_ptr = (u8 *) &tcap_ptr->tcapvm_data[ii].peer_tid; + line_len = 20; + } + else if (line == STATE_LINE+1) + { + disp_ptr = &sec_page; + line_len = 1; + } + break; + case 5: // ism state + if (line < MAX_TEMPINVOKEID) + { + ii = sec_page % (tcap_ptr->grantdid); + disp_ptr = (u8 *) &tcap_ptr->tcapvm_data[ii].ism_data[line].used_flag; + line_len = 20; + } + else if (line == MAX_TEMPINVOKEID+1) + { + disp_ptr = &sec_page; + line_len = 1; + } + break; + default: + line_len = 0; + break; + } + return line_len; +} + +void tcap_disp_page(u8 page) +{ + u8 line; + u8 line_len; + + tcap_page_line[TCAP_PAGE_POINT] = page + 5; + for (line = 0;line < MAX_LINE;line ++) + { + line_len = tcap_disp_line(page,line); + tcap_page_line[TCAP_LINE_POINT] = line + 2; + debug_set_response(TCAP_LINE_LEN,tcap_page_line,disp_ptr,line_len); + } +} + +int tcap_snmp_set(u8 oid_len,u32 *oid,u8 *data_buf,u16 data_len) +{ + u8 ii; + + ii = TCAP_PREOBJ_LEN; + if (oid_len < ii+2) + return -1; + switch (oid[ii]) + { + case 2: // set timer + switch (oid[ii+1]) + { + case 1: // set invoke timer + if (data_len == 1) // only one octet + { + debug_ptr->default_invtime = data_buf[0]; + return 1; + } + break; + case 2: // set reject timer + if (data_len == 1) + { + debug_ptr->default_rejtime = data_buf[0]; + return 1; + } + break; + case 3: // set monitor switch + switch (oid[ii+2]) + { + case 1: // monitor SCCP + if (data_len == 1) + { + debug_ptr->sccp_switch = data_buf[0]; + return 1; + } + break; + case 2: // monitor tcu + if (data_len == 1) + { + debug_ptr->tcu_switch = data_buf[0]; + return 1; + } + break; + case 3: // monitor error + if (data_len == 1) + { + debug_ptr->error_switch = data_buf[0]; + return 1; + } + break; + case 4: // monitor dialogue id + if (data_len <= 4) + { + debug_ptr->monitor_did = bcdtou32(data_buf,data_len); + return data_len; + } + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + return -1; // set fail +} + +int tcap_snmp_get(u8 oid_len,u32 *oid,u8 *data_buf,u8 *data_type) +{ + u8 ii,jj,kk; + int data_len=-1; + + ii = TCAP_PREOBJ_LEN; + if (oid_len <= ii+1) + return -1; + switch (oid[ii]) // judge object id + { + case 3: // measure + if (oid_len != ii + 2) // reach instance, get total measure data + return -1; // not support + if (oid[ii+1] > TCAP_UTILIZE_COUNT-2) + return -1; + if (oid[ii+1] == debug_ptr->current_csta) + return -1; + jj = oid[ii+1]; + if (debug_ptr->csta_time[jj] == 0) + return 0; + u32tobyte(data_buf,debug_ptr->csta_time[jj]); + data_len = 4; + for (kk = 0;kk < TCAP_UTILIZE_LEN;kk ++) + u32tobyte(data_buf+(kk+1)*4,debug_ptr->tc_utilize[jj][kk]); + data_len += TCAP_UTILIZE_LEN * 4; + *data_type = 4; + break; + case 2: // configure + switch (oid[ii+1]) + { + case 1: // invoke timer + data_len = 1; + data_buf[0] = debug_ptr->default_invtime; + *data_type = 2; + break; + case 2: // reject timer + data_len = 1; + data_buf[0] = debug_ptr->default_rejtime; + *data_type = 2; + break; + case 3: // monitro switch + switch (oid[ii+2]) + { + case 1: // sccp switch + data_buf[0] = debug_ptr->sccp_switch; + data_len = 1; + *data_type = 2; + break; + case 2: // tcu switch + data_buf[0] = debug_ptr->tcu_switch; + data_len = 1; + *data_type = 2; + break; + case 3: // error switch + data_buf[0] = debug_ptr->error_switch; + data_len = 1; + *data_type = 2; + break; + case 4: // dialogue id switch + u32tobyte(data_buf,debug_ptr->monitor_did); + data_len = 4; + *data_type = 4; + break; + default: + break; + } + break; + default: + break; + } + break; + case 1: // status + switch (oid[ii+1]) + { + case 1: // get version + data_len = TCAP_VERSION_LEN; + memcpy(data_buf,tcap_ver,data_len); + *data_type = 4; + break; + case 2: // get tcap status + data_len = TCAP_HB_LEN; + memcpy(data_buf,debug_ptr->hb_status,data_len); + *data_type = 4; + break; + default: + break; + } + break; + default: // can not recognize object id + break; + } + return data_len; // get fail +} + +void init_m(void) +{ + u8 page,ii; + char info_str[1024]; + char temp_str[256]; + char *cur_time; + u32 str_len; + + debug_ptr = (tcapdebug_struct *) &tcap_ptr->tcap_debug; + tcap_1s_flag = 0; + tcap_10s_flag = 0; + sec_page = 0; + GetCurrentTime(debug_ptr->start_time); + debug_ptr->ascin_buf[0] = '\0'; + debug_ptr->ascout_buf[0] = '\0'; + debug_set_response(TCAP_ID_LEN,tcap_status_id,&tcap_status,1); // set status id + sprintf(info_str,"V%d.%d.%02d",tcap_ver[0],tcap_ver[1],tcap_ver[2]); + debug_set_response(TCAP_ID_LEN,tcap_version_id,(BYTE *)info_str,strlen(info_str)); // set module description + debug_set_response(TCAP_ID_LEN,tcap_ascin_id,debug_ptr->ascin_buf,TCAP_ASCIN_LEN); + debug_set_response(TCAP_ID_LEN,tcap_ascout_id,debug_ptr->ascout_buf,TCAP_ASCOUT_LEN); + for (page = 1;page < MAX_PAGE;page ++) + { + switch (page) + { + case 1: + sprintf(info_str,"Version:R%dV%dT%d\t%s",tcap_ver[0],tcap_ver[1],tcap_ver[2],title1); + str_len = strlen(info_str); + break; + case 2: + sprintf(info_str,"Version:R%dV%dT%d\t%s",tcap_ver[0],tcap_ver[1],tcap_ver[2],title2); + for (ii = 0;ii < 16;ii ++) + { + sprintf(temp_str,"watch_dog%d\r\n",ii*16); + strcat(info_str,temp_str); + } + str_len = strlen(info_str); + break; + case 3: + sprintf(info_str,"Version:R%dV%dT%d\t%s",tcap_ver[0],tcap_ver[1],tcap_ver[2],title3); + for (ii = 0;ii < TCAP_UTILIZE_LEN/5;ii ++) + { + sprintf(temp_str,"Data%d--%d\r\n",ii*5,ii*5+4); + strcat(info_str,temp_str); + } + str_len = strlen(info_str); + break; + case 4: + sprintf(info_str,"Version:R%dV%dT%d\tTCAP state\r\n\n",tcap_ver[0],tcap_ver[1],tcap_ver[2]); + for (ii = 0;ii < STATE_LINE;ii ++) + { + sprintf(temp_str,"TCAP %d\r\n",ii); + strcat(info_str,temp_str); + } + strcat(info_str,"\nCurrent_page\r\n"); + str_len = strlen(info_str); + break; + case 5: + sprintf(info_str,"Version:R%dV%dT%d\tISM state\r\n\n",tcap_ver[0],tcap_ver[1],tcap_ver[2]); + for (ii = 0;ii < MAX_TEMPINVOKEID;ii ++) + { + sprintf(temp_str,"ISM %d\r\n",ii); + strcat(info_str,temp_str); + } + strcat(info_str,"\nCurrent_page\r\n"); + str_len = strlen(info_str); + break; + default: + strcpy(info_str, (char *)title1); + str_len = 0; + break; + } + tcap_page_title[TCAP_PAGE_POINT] = page + 5; + debug_set_response(TCAP_TITLE_LEN,tcap_page_title, (BYTE *)info_str,str_len); + tcap_disp_page(page); + } + +// init snmp portion +// heartbeat_init(TCAP_SYSTEM_ID); // register tcap heartbeat + inquire_setmsg(TCAP_PREOBJ_LEN,tcap_object_id,tcap_snmp_set); + inquire_getmsg(TCAP_PREOBJ_LEN,tcap_object_id,tcap_snmp_get); + debug_ptr->default_invtime = INVOKE_TIMER; + debug_ptr->default_rejtime = REJECT_TIMER; + + cur_time = GetAsciiTime(); + sprintf(info_str,"TCAP init process completed. Init time is:%s\r",cur_time); + tcap_send_ascout(info_str); +// init_paralport(); // init parallel port +// write_paralport(TCAP_LED_CODE,1); +} + +extern void clrcount_did_max(void); +void tcap_monitor(void) +{ + u32 ii,jj; + u8 *time_ptr; + u16 used_id; + char info_str[1024],temp_info[1024]; + + debug_ptr->send_control = 0; + if (strlen((char *)debug_ptr->ascin_buf) > 0) // has command + { + if (strcmp((char *)debug_ptr->ascin_buf+1,"clear") == 0) + { + memset(debug_ptr->watch_dog,0,256); + memset(tcap_dlg_stats, 0, sizeof(u32) * MAX_DIALOGUEID); + clrcount_did_max(); + } + else if (strncmp((char *)debug_ptr->ascin_buf+1,"go to ",6) == 0) // change section page + { + ii = atol((char *)debug_ptr->ascin_buf+7); + sec_page = ii; + } + else if (strncmp((char *)debug_ptr->ascin_buf+1,"log port ",9) == 0) // monitor the did + { + ii = atol((char *)debug_ptr->ascin_buf+10); + if (ii >= (tcap_ptr->grantdid)) + tcap_send_ascout("The appointed dialogue id is not expected\r\n"); + else + debug_ptr->monitor_did = ii; + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"list para") == 0)// display parameter + { + tcap_send_ascout("The TCAP system parameters are:\r\n"); + sprintf(info_str,"Invoke timer:%d s\r\nReject timer:%d s\r\n",debug_ptr->default_invtime,debug_ptr->default_rejtime); + tcap_send_ascout(info_str); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log none") == 0)// close all switch + { + debug_ptr->error_switch = 0; + debug_ptr->sccp_switch = 0; + debug_ptr->tcu_switch = 0; + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log error on") == 0) + { + debug_ptr->error_switch = 1; + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log error off") == 0) + { + debug_ptr->error_switch = 0; + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log all") == 0) + { + debug_ptr->error_switch = 1; + debug_ptr->sccp_switch = 1; + debug_ptr->tcu_switch = 1; + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log sccp") == 0) + { + debug_ptr->sccp_switch = 1; + tcap_send_ascout("tcap monitoring sccp message switch open\n\r"); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log tcu") == 0) + { + debug_ptr->tcu_switch = 1; + } + else if (strncmp((char *)debug_ptr->ascin_buf+1,"help",6) == 0) // display help message + { + sprintf(temp_info,"%d-%02d-%02d %02d:%02d:%02d",debug_ptr->start_time[0]+2000,debug_ptr->start_time[1],debug_ptr->start_time[2],debug_ptr->start_time[3],debug_ptr->start_time[4],debug_ptr->start_time[5]); + sprintf(info_str,"TCAP module R%dV%d_%02d, start time: %s\r\n\n",tcap_ver[0],tcap_ver[1],tcap_ver[2],temp_info); + tcap_send_ascout(info_str); + tcap_send_ascout("Command list:\r\n"); + tcap_send_ascout("log all --------- Turn on all log items\r\n"); + tcap_send_ascout("log none --------- Turn off all log items\r\n"); + tcap_send_ascout("log error on/off --------- Turn on/off error log item\r\n"); + tcap_send_ascout("log tcu --------- Turn on TCAP<->TCUser log item\r\n"); + tcap_send_ascout("log sccp --------- Turn on TCAP<->SCCP log item\r\n"); + tcap_send_ascout("log port [did] ---- Monitor the specified dialogue id\r\n"); + tcap_send_ascout("list para --------- Display TCAP system parameters\r\n"); + } + debug_ptr->ascin_buf[0] = '\0'; + } +/* for (page_n = 1;page_n < MAX_PAGE;page_n ++) + tcap_disp_page(page_n);*/ + if (++tcap_1s_flag > 24) + tcap_1s_flag = 0; + if (tcap_1s_flag == 0) + { + GetCurrentTime(debug_ptr->current_time); + time_ptr = debug_ptr->current_time; + jj = (time_ptr[3]*60+time_ptr[4])/TCAP_CSTA_INTERVAL; + for (ii = 0;ii < TCAP_UTILIZE_LEN;ii ++) + { + if ((time_ptr[4] % TCAP_CSTA_INTERVAL)==0 && time_ptr[5]==0) // clear CDR + { + debug_ptr->tc_utilize[jj][ii] = 0; + debug_ptr->csta_time[jj] = time(NULL); + debug_ptr->current_csta = jj; + } + debug_ptr->tc_utilize[jj][ii] += debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][ii]; + debug_ptr->tc_utilize[TCAP_UTILIZE_COUNT-1][ii] = 0; + } + used_id = chkcount_did_occupied(); + debug_ptr->tc_utilize[jj][21] += used_id; + if (debug_ptr->tc_utilize[jj][23] < used_id) + debug_ptr->tc_utilize[jj][23] = used_id; + if (++tcap_10s_flag > 9) + tcap_10s_flag = 0; + if (tcap_10s_flag == 0) // 10s timer, set tcap status + { + set_led(TCAP_LED_CODE,LED_GREEN); + memcpy(debug_ptr->hb_status,tcap_ver,TCAP_VERSION_LEN); + debug_ptr->hb_status[TCAP_VERSION_LEN] = tcap_status; + debug_ptr->hb_status[TCAP_VERSION_LEN+1] = used_id >> 8; + debug_ptr->hb_status[TCAP_VERSION_LEN+2] = used_id; + used_id = chkcount_did_max(); + debug_ptr->hb_status[TCAP_VERSION_LEN+3] = used_id >> 8; + debug_ptr->hb_status[TCAP_VERSION_LEN+4] = used_id; + set_status(TCAP_MODULE_ID,TCAP_HB_LEN,debug_ptr->hb_status); + //clrcount_did_max(); + } + } +} + +void tcap_send_alarm(u8 alarm_code,u8 alarm_level) +{ + if (alarm_level == 1) // mini alarm + set_led(TCAP_LED_CODE,LED_YELLOW); + else if (alarm_level == 2) // critical alarm + set_led(TCAP_LED_CODE,LED_RED); + set_alarm(TCAP_MODULE_ID,alarm_code); +} +/*@end@*/ diff --git a/plat/tcp/Makefile b/plat/tcp/Makefile new file mode 100644 index 0000000..21d9984 --- /dev/null +++ b/plat/tcp/Makefile @@ -0,0 +1,98 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module template : V1.6.3 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/07/07 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + +MODULE = tcp +TYPE = plat + +DBUG_FLAGS_ADD = -DDEBUG +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + + +PLT_LIB = + +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../mss + +OBJ_ADD = +TEST_OBJ_PATH = + +PREPROC_CMD = +POSTPROC_CMD = + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = no +COVER_REPORT_PATH = ./output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/tcp/src/include/tcp_debug.h b/plat/tcp/src/include/tcp_debug.h new file mode 100644 index 0000000..53c8b03 --- /dev/null +++ b/plat/tcp/src/include/tcp_debug.h @@ -0,0 +1,20 @@ +#ifndef _TCP_DEBUG_H_ +#define _TCP_DEBUG_H_ + +#include "../../../../plat/debug/src/include/debug.h" + +extern void tcp_print_time(); +extern void tcp_print_debug(const char *fmt, ...); +extern void tcp_print_warn(const char *fmt, ...); +extern void tcp_print_error(const char *fmt, ...); +extern void tcp_print_func(const char *fmt, ...); +extern int tcp_debug_init(); +extern void tcp_debug_timer(); + +//tcp_port.c +extern BOOL tcp_print_all_port(void); +extern BOOL tcp_print_port(int pid); +extern BOOL tcp_clear_stat(int pid); + +#endif + diff --git a/plat/tcp/src/include/tcp_if.h b/plat/tcp/src/include/tcp_if.h new file mode 100644 index 0000000..a7ce936 --- /dev/null +++ b/plat/tcp/src/include/tcp_if.h @@ -0,0 +1,32 @@ +#ifndef _TCP_IF_H_ +#define _TCP_IF_H_ + +#include "tcp_inc.h" +#include "tcp_port.h" +#define TCP_MAX_NUM_OF_SAP 4 +#define TCP_MAX_USER_NAME_LEN 16 + +typedef int (*tcp_recv_callback)(WORD usr_port, BYTE *pdata, WORD datalen, DWORD param1, DWORD param2, DWORD param3); + +typedef struct _tcp_sap_t +{ + BYTE id; + char name[TCP_MAX_USER_NAME_LEN]; + tcp_recv_callback recv_cb; +}tcp_sap_t; + +extern void tcp_init(void); +extern void tcp_timer(void); +extern int tcp_bind(tcp_sap_t *ptr_sap); +extern int tcp_unbind(tcp_sap_t *ptr_sap, BYTE index); +extern tcp_sap_t *tcp_sap_get_by_index(int index); + + +//rtp_port.c +extern int tcp_port_alloc_port(int sap_id, WORD usr_port, tcp_session_t *pSess); +extern int tcp_port_release_port(int sap_id, WORD usr_port, WORD pid); +extern int tcp_send(int sap_id, WORD usr_port, WORD pid, BYTE *payload, WORD len, DWORD param1, DWORD param2, DWORD param3); +extern tcp_session_t *tcp_port_update_sess(int sap_id, WORD usr_port, WORD pid, tcp_session_t *ptr_sess); + +#endif + diff --git a/plat/tcp/src/include/tcp_inc.h b/plat/tcp/src/include/tcp_inc.h new file mode 100644 index 0000000..9b633d7 --- /dev/null +++ b/plat/tcp/src/include/tcp_inc.h @@ -0,0 +1,134 @@ +#ifndef _TCP_INC_H_ +#define _TCP_INC_H_ + +#include "../../../public/src/include/includes.h" +#include "../../../public/src/include/public.h" + +/* +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef _T_BYTE +#define _T_BYTE +typedef unsigned char BYTE; +#endif + +#ifndef _T_WORD +#define _T_WORD +typedef unsigned short WORD; +#endif + +#ifndef _T_DWORD +#define _T_DWORD +typedef unsigned long DWORD; +#endif + +#ifndef _T_ULL +#define _T_ULL +typedef unsigned long long ull; +#endif + +#ifndef _T_U8 +#define _T_U8 +typedef unsigned char u8; +#endif + +#ifndef _T_U16 +#define _T_U16 +typedef unsigned short u16; +#endif + +#ifndef _T_U32 +#define _T_U32 +typedef unsigned long u32; +#endif + +#ifndef _T_U64 +#define _T_U64 +typedef unsigned long long u64; +#endif + +#ifndef _T_BOOL +#define _T_BOOL +typedef int BOOL; +#endif + +#ifndef SUCCESS +#define SUCCESS (0) +#endif + +#ifndef FAILURE +#define FAILURE (-1) +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef YES +#define YES (1) +#endif + +#ifndef NO +#define NO (0) +#endif + +#ifndef ERROR +#define ERROR (-1) +#endif + +#ifndef EMPTY +#define EMPTY (0) +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define BUFSIZE 8192 +#define MAXBUFLEN 8192 +#define MAXLINE 8192 +*/ + +#endif + diff --git a/plat/tcp/src/include/tcp_port.h b/plat/tcp/src/include/tcp_port.h new file mode 100644 index 0000000..8ddd870 --- /dev/null +++ b/plat/tcp/src/include/tcp_port.h @@ -0,0 +1,59 @@ +#ifndef _TCP_PORT_H_ +#define _TCP_PORT_H_ + +#include "tcp_inc.h" + +#define TCP_MAX_NUM_OF_PORT 16 +#define TCP_MAX_RECV_MSG_LEN 1500 +#define TCP_MAX_SEND_MSG_LEN 1500 +#define TCP_MAX_PAYLOAD_SIZE 1350 +#define TCP_MAX_RECV_BUF_LEN 8192 +#define TCP_MAX_RECV_COUNT 128 + +typedef struct _tcp_header_t +{ + BYTE ver; // version + BYTE pt; // payload type + WORD sn; // sequence number + DWORD timestamp; + DWORD ssrc; //synchronization src +}tcp_header_t; + +typedef struct _tcp_session_t +{ + DWORD src_ip; + WORD src_port; + DWORD dst_ip; + WORD dst_port; + BYTE bServer; // tcp client: 0; server: 1; +}tcp_session_t; + +typedef struct _tcp_port_t +{ + BYTE flag; + int index; + BYTE status; + int timer; + int retry_num; + WORD usr_port; + int fd; + int cli_fd; + + BYTE rv_buf[TCP_MAX_RECV_BUF_LEN]; + int buf_len; + + int connected_num; + int disconnect_num; + int sent_fail_num; + tcp_session_t sess; + struct _tcp_sap_t *ptr_sap; +}tcp_port_t; + +extern void tcp_port_init(WORD id); +extern void tcp_port_recv_msg(void); +extern int tcp_link_fsm(); + +int get_tcp_sess(WORD hdlPort, tcp_session_t *sess); + +#endif + diff --git a/plat/tcp/src/tcp_debug.c b/plat/tcp/src/tcp_debug.c new file mode 100644 index 0000000..c00792e --- /dev/null +++ b/plat/tcp/src/tcp_debug.c @@ -0,0 +1,429 @@ +/* +** +*/ +#include "./include/tcp_debug.h" + + + +#define TCP_MAX_OPR_LEN 16 +#define TCP_MAX_OBJ_LEN 32 +#define TCP_MAX_VALUE_LEN 32 + +#define TCP_LOG_OFF 0 +#define TCP_LOG_ON 1 +#define TCP_MAX_ASC_IN_LEN 128 +#define TCP_MAX_ASC_OUT_LEN 4096 +#define TCP_DEBUG_ID 36// menu_page2: m +#define TCP_MAX_LINE 10 + +/*Color Set */ +#define TCP_COL_WHITE 37 +#define TCP_COL_RED 31 +#define TCP_COL_YELLOW 33 +#define TCP_COL_GREEN 32 +#define TCP_COL_BLUE 34 +#define TCP_COL_BROWN 35 +#define TCP_COL_MEGEN 36 +#define TCP_COL_GRAY 38 +#define TCP_COL_HI_WHI 58 +#define TCP_COL_HI_RED 39 +#define TCP_COL_HI_YEL 52 +#define TCP_COL_HI_GRE 51 +#define TCP_COL_HI_BLU 53 +#define TCP_COL_HI_BRO 54 +#define TCP_COL_HI_MEG 55 +#define TCP_COL_BLACK 30 +#define TCP_COL_ESC '\033' + + +typedef struct +{ + u8 log_time; + u8 log_debug; + u8 log_warn; + u8 log_err; + u8 log_func; +}tcp_debug_t; + +char tcp_ascii_in[TCP_MAX_ASC_IN_LEN]; +char tcp_ascii_out[TCP_MAX_ASC_OUT_LEN]; +tcp_debug_t tcp_debug; +static u8 TCP_VERSION[4] = {1, 0, 0, 2}; //V1.0.01 T002 + +static u32 debug_status_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,1 +}; + +static u32 debug_name_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,2 +}; + +static u32 debug_ascin_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,3 +}; + +static u32 debug_ascout_id[20] = +{ + 1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,4 +}; + + +const BYTE tcp_base_id_len = 15; + +static char help_menu[] = +{ + "TCP log help page\n\r\ +========================================================================\n\r\ +| Command | Remark |\n\r\ +========================================================================\n\r\ +| help | help page |\n\r\ +| log all/none | display all/none logs |\n\r\ +| log warn on/off | display warn logs |\n\r\ +| log error on/off | display error logs |\n\r\ +| log func on/off | display function logs |\n\r\ +| log time on/off | display time logs |\n\r\ +| list port[-id] | display tcp port resource |\n\r\ +========================================================================\n\r\ +" +}; + + +static void tcp_print(const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + + if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN) + strcat((char*)tcp_ascii_out, buf); + else + strcpy((char*) tcp_ascii_out, buf); + + va_end(ap); +} + +void tcp_print_time() +{ + struct timeval tv; + struct timezone tz; + struct tm *t; + char timestr[128]; + + if(!tcp_debug.log_time) + return; + + gettimeofday(&tv, &tz); + t = localtime(&tv.tv_sec); + sprintf(timestr, "[%d:%d:%d.%ld] ", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec); + tcp_print(timestr); +} + +void tcp_print_debug(const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + +// if(!tcp_debug.log_debug) +// return ; + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + + if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN) + strcat((char*)tcp_ascii_out, buf); + else + strcpy((char*)tcp_ascii_out, buf); + + va_end(ap); +} + +void tcp_print_warn(const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + if(!tcp_debug.log_warn) + return ; + sprintf(buf, "\33[33mWARN: "); + + tcp_print_time(); + + va_start(ap, fmt); + vsprintf(buf+strlen(buf), fmt, ap); + strcat(buf, "\33[0m"); + + if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN) + strcat((char*)tcp_ascii_out, buf); + else + strcpy((char*)tcp_ascii_out, buf); + + va_end(ap); +} + +void tcp_print_error(const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + if(!tcp_debug.log_err) + return ; + sprintf(buf, "\33[31mERROR: "); + + tcp_print_time(); + + va_start(ap, fmt); + vsprintf(buf+strlen(buf), fmt, ap); + strcat(buf, "\33[0m"); + + if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN) + strcat((char*)tcp_ascii_out, buf); + else + strcpy((char*)tcp_ascii_out, buf); + + va_end(ap); +} + + +void tcp_print_func(const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + if(!tcp_debug.log_func) + return ; + + sprintf(buf, "\33[32mFUNC: "); //, TCP_COL_GREEN + + tcp_print_time(); + + va_start(ap, fmt); + vsprintf(buf+strlen(buf), fmt, ap); + strcat(buf, "\33[0m"); + + if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN) + strcat((char*)tcp_ascii_out, buf); + else + strcpy((char*)tcp_ascii_out, buf); + + va_end(ap); + +} + + +static int tcp_set_debug(u8 *log_flag, char *value) +{ + if(log_flag == NULL || value == NULL) + return -1; + if(strcmp(value, "on") == 0) + *log_flag = TCP_LOG_ON; + else if(strcmp(value, "off") == 0) + *log_flag = TCP_LOG_OFF; + else + return 0; + + return 1; +} + +static void tcp_set_all_debug() +{ + tcp_debug.log_debug = TCP_LOG_ON; + tcp_debug.log_warn = TCP_LOG_ON; + tcp_debug.log_err = TCP_LOG_ON; + tcp_debug.log_func = TCP_LOG_ON; +} + +int tcp_debug_init() +{ + u8 debug_status; + u8 data[10]; + u8 *ptr; + char version_info[16]={""}; + + memset(tcp_ascii_in,0,128); + memset(tcp_ascii_out,0,4096); + sprintf(version_info,"V%d.%d.%02d",TCP_VERSION[0],TCP_VERSION[1],TCP_VERSION[2]); +// memcpy(rtp_param.sys.version, TCP_VERSION, 4); + + ptr = data; + debug_status = 1; + debug_set_response(tcp_base_id_len, debug_status_id, &debug_status,1); + debug_set_response(tcp_base_id_len, debug_name_id, (u8*)version_info,12); /* module name */ + debug_set_response(tcp_base_id_len, debug_ascin_id, (u8*)tcp_ascii_in, 128); /* ascii in buf */ + debug_set_response(tcp_base_id_len, debug_ascout_id, (u8*)tcp_ascii_out,4096); /* ascii out buf */ + + return 1; +} + + +static void tcp_command_decompose(char *opr, char *obj, char *value, char *cmd) +{ + int i; + int len; + char *sep; + + if(opr == NULL || obj == NULL || value == NULL || cmd == NULL) + return ; + opr[0] = obj[0] = value[0] = '\0'; + for(i = 0; i < 80; i++) + { + sep = strsep(&cmd, " \t"); /* Seprate by SPACE and TAB */ + if(sep == NULL) /* Touch the end */ + return; + else if((len = strlen(sep)) == 0) /* Touch the SPACE or TAB */ + continue; + if(opr[0] == '\0') + { + if(len < TCP_MAX_OPR_LEN) + strcpy(opr, sep); + } + else if(obj[0] == '\0') + { + if(len < TCP_MAX_OBJ_LEN) + strcpy(obj, sep); + } + else if(value[0] == '\0') + { + if(len < TCP_MAX_VALUE_LEN) + { + strcpy(value, sep); + return; + } + } + } +} + +static int tcp_debug_cmd_handle(char *cmd) +{ + char opr[TCP_MAX_OPR_LEN] = {""}; + char obj[TCP_MAX_OBJ_LEN] = {""}; + char value[TCP_MAX_VALUE_LEN] = {""}; + char *ver = (char*)TCP_VERSION; + char *str_start = NULL; + int port; + + if(cmd == NULL) + return -1; + tcp_command_decompose(opr, obj, value, cmd); + if(strcmp(opr, "help") == 0 || strcmp(opr, "?") == 0) + tcp_print("%s\r\nV%d.%d.%02d T%03d\r\n", help_menu, ver[0], ver[1], ver[2], ver[3]); + else if(strcmp(opr, "log") == 0) + { + if(strcmp(obj, "all") == 0) + tcp_set_all_debug(); + else if(strcmp(obj, "none") == 0) + memset(&tcp_debug, 0, sizeof(tcp_debug_t)); + else if(strcmp(obj, "debug") == 0) + return tcp_set_debug(&tcp_debug.log_debug, value); + else if(strcmp(obj, "warn") == 0) + return tcp_set_debug(&tcp_debug.log_warn, value); + else if(strcmp(obj, "error") == 0) + return tcp_set_debug(&tcp_debug.log_err, value); + else if(strcmp(obj, "func") == 0) + return tcp_set_debug(&tcp_debug.log_func, value); + else if(strcmp(obj, "time") == 0) + return tcp_set_debug(&tcp_debug.log_time, value); + else + return 0; + } + else if(strcmp(opr, "list") == 0) + { + if(strstr(obj, "port") != NULL) + { + if((str_start = strstr(obj, "-")) != NULL) + { + port = strtol(str_start+1, NULL, 10); + return tcp_print_port(port); + } + else + return tcp_print_all_port(); + } + else + return 0; + } + else if (strcmp(opr, "reset") == 0) + { + if(strstr(obj, "stat") != NULL) + { + if((str_start = strstr(obj, "-")) != NULL) + { + port = strtol(str_start+1, NULL, 11); + return tcp_clear_stat(port); + } + else + return 0; + } + else + return 0; + } +/* else if(strcmp(opr, "save") == 0) + { + if(strcmp(obj, "para") == 0) + rtpproxy_param_save_para(); + else + return 0; + } + else if(strcmp(opr, "load") == 0) + { + if(strcmp(obj, "para") == 0) + { + rtpproxy_modify_para(); + } + else + return 0; + }*/ +/* else if(strcmp(opr, "save") == 0) + { + if(strcmp(obj, "rz") == 0) + return rtp_save_rz(); + else if(strcmp(obj, "mg") == 0) + return rtp_save_mg(); + else if(strcmp(obj, "sys") == 0) + return rtp_save_system(); + else + return 0; + } + else if(strcmp(opr, "test") == 0) + { + if(strcmp(obj, "port_enable") == 0) // + { + int test_i; + for(test_i = 1; test_i < 3; test_i++) + test_rtp_set_port_enable(test_i); + } + else + return 0; + }*/ + else + return 0; + + return 1; +} + +void tcp_debug_timer() +{ + int ret, len; + char cmd[128] = {""}; + + if(tcp_ascii_in[0] == 0) + return; + len = strlen(tcp_ascii_in); + if(len ==0) + return; + if(strlen((char*)&tcp_ascii_in[1]) >= 128) + return; + strcpy(cmd, (char*)&tcp_ascii_in[1]); + memset(tcp_ascii_in, 0, TCP_MAX_ASC_IN_LEN); + + ret = tcp_debug_cmd_handle(cmd); + if(ret == 1) + tcp_print("Command OK!\r\n"); + else + tcp_print("Command Error!\r\n"); + +} + + diff --git a/plat/tcp/src/tcp_if.c b/plat/tcp/src/tcp_if.c new file mode 100644 index 0000000..50b4d86 --- /dev/null +++ b/plat/tcp/src/tcp_if.c @@ -0,0 +1,99 @@ +/* +* +*/ +#include "./include/tcp_if.h" +#include "./include/tcp_port.h" +#include "./include/tcp_debug.h" + +static tcp_sap_t tcp_sap[TCP_MAX_NUM_OF_SAP]; + +static void tcp_sap_init(tcp_sap_t *ptr_sap, BYTE index) +{ + if((ptr_sap == NULL) || (index >= TCP_MAX_NUM_OF_SAP)) + { + return; + } + + ptr_sap->id = index; + strcpy(ptr_sap->name, "\0"); + ptr_sap->recv_cb = NULL; +} + +tcp_sap_t *tcp_sap_get_by_index(int index) +{ + if(index < 0 || index >= TCP_MAX_NUM_OF_SAP) + return NULL; + return &tcp_sap[index]; +} + +void tcp_init(void) +{ + WORD i; + + for(i = 0; i < TCP_MAX_NUM_OF_SAP; i++) + { + tcp_sap_init(&tcp_sap[i], (BYTE)i); + } + + for(i = 0; i < TCP_MAX_NUM_OF_PORT; i++) + { + tcp_port_init(i); + } + + tcp_debug_init(); + + return; +} + +void tcp_timer(void) +{ + tcp_link_fsm(); + tcp_port_recv_msg(); + tcp_debug_timer(); +} + +int tcp_bind(tcp_sap_t *ptr_sap) +{ + BYTE i; + tcp_sap_t *ptr_tmp = NULL; + + if((ptr_sap == NULL) || (ptr_sap->recv_cb == NULL)) + { + return -1; + } + + for(i = 0; i < TCP_MAX_NUM_OF_SAP; i++) + { + ptr_tmp = &tcp_sap[i]; + if(ptr_tmp->recv_cb != NULL) + { + continue; + } + + memcpy((BYTE*)ptr_tmp, ptr_sap, sizeof(tcp_sap_t)); + ptr_tmp->id = i; + ptr_tmp->name[TCP_MAX_USER_NAME_LEN-1] = '\0'; + + return i; + } + + return -1; +} + +int tcp_unbind(tcp_sap_t *ptr_sap, BYTE index) +{ + if((ptr_sap == NULL) || (index >= TCP_MAX_NUM_OF_SAP)) + { + return -1; + } + + if(ptr_sap->id != index) + { + return -1; + } + + tcp_sap_init(ptr_sap, index); + + return 0; +} + diff --git a/plat/tcp/src/tcp_port.c b/plat/tcp/src/tcp_port.c new file mode 100644 index 0000000..f534838 --- /dev/null +++ b/plat/tcp/src/tcp_port.c @@ -0,0 +1,1063 @@ +/* +* tcp port +*/ +#include "./include/tcp_port.h" +#include "./include/tcp_if.h" +#include "./include/tcp_debug.h" + +#define TCP_F_BB1 0x7E // Begin: The first byte +#define TCP_F_BB2 0xA5 // Begin: The second byte +#define TCP_F_EB1 0x7E // End: The first byte +#define TCP_F_EB2 0x0D // End: The second byte + +#define TCP_F_INF_BEGIN_FLAG_LEN 2 // length of begin flag +#define TCP_F_INF_MSG_LEN_LEN 2 // length of msg length field +//#define TCP_F_INF_MSG_TYPE_LEN 2 // length of msg type +#define TCP_F_INF_END_FLAG_LEN 2 // length of end flag +#define TCP_F_INF_HEAD_LEN 4 // length of format begin+lengthField +#define TCP_F_INF_ALL_LEN 6 // total length of format + +#define TCP_IsfBegin(f1,f2) ((f1==TCP_F_BB1) && (f2==TCP_F_BB2))// Begin flag of msg +#define TCP_IsfEnd(f1,f2) ((f1==TCP_F_EB1) && (f2==TCP_F_EB2))// End flag of msg + +#define TCP_MSG_DATA 1 // Data +#define TCP_MSG_HB 2 // HB +#define TCP_MSG_HB_ACK 3 // HB_ACK + +#define TCP_TIMER_1_SEC (100) // 10ms * 100 +#define TCP_TIMER_WAIT_CONNECT (5) // 50ms +#define TCP_TIMER_REINIT (3*TCP_TIMER_1_SEC) // 3 Sec +#define TCP_TIMER_RECONNECT (3*TCP_TIMER_1_SEC) // 3 Sec +#define TCP_TIMER_HB (3*TCP_TIMER_1_SEC) // 3 Sec + +#define TCP_MAX_RETRY_NUM (3) + +typedef enum +{ + TCP_STATUS_NULL, + TCP_STATUS_INITING, + TCP_STATUS_INITED, + TCP_STATUS_CONNECTING, + TCP_STATUS_TESTING, + TCP_STATUS_CONNECTED, + TCP_STATUS_MAX, +}e_tcp_status; + +typedef struct +{ + WORD usMsgId; // Tcp internal message Id, 1: Data; 2: HB; 3: HB_ACK + WORD usPlLen; // Payload length + DWORD param1; // App param1, optional + DWORD param2; // App param2, optional + DWORD param3; // App param3, optional +} tcp_head_t; + +static char tcp_status_str[TCP_STATUS_MAX][64] = {\ + "null", \ + "initing", \ + "inited", \ + "connecting", \ + "testing", \ + "connected" +}; + +static tcp_port_t tcp_port[TCP_MAX_NUM_OF_PORT]; + +void tcp_port_init(WORD id) +{ + tcp_port_t *ptr_port = NULL; + + if(id >= TCP_MAX_NUM_OF_PORT) + { + return; + } + + ptr_port = &tcp_port[id]; + memset((BYTE*)ptr_port, 0, sizeof(tcp_port_t)); + ptr_port->fd = -1; + ptr_port->cli_fd = -1; + ptr_port->ptr_sap = NULL; + + return; +} + + +static tcp_port_t *tcp_port_get_by_index(WORD index) +{ + if (index >= TCP_MAX_NUM_OF_PORT) + { + return NULL; + } + + return &tcp_port[index]; +} + + +static int tcp_port_get_unused_pid(void) +{ + static WORD index = 0; + WORD id, i; + tcp_port_t *ptr_port = NULL; + + i = index; + do + { + id = i; + ptr_port = &tcp_port[id]; + if(++i >= TCP_MAX_NUM_OF_PORT) + { + i = 0; + } + + if(ptr_port->flag != FALSE) + { + continue; + } + + index = i; + return id; + }while(i != index); + + return -1; +} + + +static int tcp_init_socket(tcp_session_t *pSess) +{ + int sock = -1, on = 1, timeout = 20; + struct sockaddr_in srcaddr; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + tcp_print_error("Error create socket!\r\n"); + return -1; + } + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + { + tcp_print_error("setsockopt reuse addr failed!\r\n"); + close(sock); + return -2; + } + + //if (bServer) + { + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &timeout, sizeof(timeout)) != 0) + { + tcp_print_error("set keepalive failed!\r\n"); + return -3; + } + } + + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) + { + tcp_print_error("set nonblock failed!\r\n"); + close(sock); + return -4; + } + + memset( (void *)&srcaddr, 0, sizeof(srcaddr) ); + srcaddr.sin_family = AF_INET; + srcaddr.sin_addr.s_addr = pSess->src_ip;//htonl( INADDR_ANY ); + srcaddr.sin_port = htons(pSess->src_port); + if (bind(sock, (struct sockaddr *)&srcaddr, sizeof(srcaddr)) < 0) + { + tcp_print_error("bind failed, ip[0x%x], port[%d]\r\n", pSess->src_ip, pSess->src_port); + close(sock); + return -5; + } + + if (pSess->bServer) + { + // change to passive socket + if (listen(sock, 5)) + { + tcp_print_error("listen failed!\r\n"); + close(sock); + return -6; + } + } + + return sock; +} + + +static int tcp_set_status(tcp_port_t *ptr_port, WORD new_status) +{ + if ((ptr_port == NULL) || (ptr_port->status == new_status) || (new_status >= TCP_STATUS_MAX)) + { + return -1; + } + + tcp_print_warn("pid[%d], link status change from [%s] to [%s]!\r\n", ptr_port->index, tcp_status_str[ptr_port->status], tcp_status_str[new_status]); + + if (ptr_port->status == TCP_STATUS_CONNECTED) + { + ptr_port->disconnect_num++; + } + + ptr_port->status = new_status; + + return 0; +} + + +static int tcp_connect(tcp_port_t *ptr_port) +{ + int ret; + struct sockaddr_in serv_addr; + + if (ptr_port == NULL) + { + return -1; + } + + /* set family to internet */ + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = ptr_port->sess.dst_ip; + serv_addr.sin_port = htons(ptr_port->sess.dst_port); + ret = connect(ptr_port->fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)); + if (ret < 0) + { + if (errno == EINPROGRESS) + { + tcp_print_warn("pid[%d], tcp connect: Operation now in progress, errno[115]!\r\n", ptr_port->index); + return 0; + } + + tcp_print_error("pid[%d], tcp connect fail, errno[%d]!\r\n", ptr_port->index, errno); + /*if((106 == errno)//Transport endpoint is already connected + ||(89 == errno))//Destination address required + { + return 0; + }*/ + + return -1; + } + else + { + tcp_print_debug("pid[%d], tcp connect ok!\r\n", ptr_port->index); + return 0; + } +} + + +static int tcp_check_conn(tcp_port_t *ptr_port) +{ + int client_sock; + int timeout = 20; + struct sockaddr_in remote; + socklen_t len = sizeof(struct sockaddr_in); + tcp_session_t *pSess = NULL; + + if (ptr_port == NULL) + { + return -1; + } + pSess = &ptr_port->sess; + + // fill with zero terms + memset(&remote, 0, sizeof( remote)); + + // wait for connetion + client_sock = accept(ptr_port->fd, (struct sockaddr *)&(remote), &len); + if ( client_sock < 0 ) + { + return -1; + } + + if ((remote.sin_port != htons(pSess->dst_port)) || (remote.sin_addr.s_addr != pSess->dst_ip)) + { + tcp_print_error("pid[%d], invalid remote addr: ip[0x%x], port[%d]\r\n", ptr_port->index, remote.sin_addr.s_addr, ntohs(remote.sin_port)); + close(client_sock); + return -2; + } + + if (setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, &timeout, sizeof(timeout)) != 0) + { + tcp_print_error("pid[%d], set keepalive failed\r\n", ptr_port->index); + //return -3; + } + + if (fcntl(client_sock, F_SETFL, O_NONBLOCK) < 0) + { + tcp_print_error("pid[%d], set nonblock failed\r\n", ptr_port->index); + //return -4; + } + + ptr_port->cli_fd = client_sock; + return client_sock; +} + + +int tcp_port_alloc_port(int sap_id, WORD usr_port, tcp_session_t *pSess) +{ + int pid; + tcp_port_t *ptr_port = NULL; + tcp_sap_t *ptr_sap = NULL; + + if(pSess == NULL || pSess->src_ip == 0 || pSess->src_port == 0 \ + || pSess->dst_ip == 0 || pSess->dst_port == 0) + { + tcp_print_error("tcp_port_alloc_port()->err param!\r\n"); + return -1; + } + + if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL) + { + tcp_print_error("tcp_port_alloc_port()->err sap[%d]!\r\n", sap_id); + return -1; + } + + if((pid = tcp_port_get_unused_pid()) < 0) + { + tcp_print_error("tcp_port_alloc_port()->sap[%d], alloc pid fail!\r\n", sap_id); + return -1; + } + + ptr_port = &tcp_port[pid]; + if((ptr_port->fd = tcp_init_socket(pSess)) < 0) + { + tcp_print_error("tcp_port_alloc_port()->pid[%d] init socket failed!\r\n", pid); + return -1; + } + + ptr_port->flag = TRUE; + ptr_port->index = pid; + tcp_set_status(ptr_port, TCP_STATUS_INITED); + ptr_port->timer = 0; + ptr_port->retry_num = 0; + ptr_port->ptr_sap = ptr_sap; + ptr_port->usr_port = usr_port; + ptr_port->cli_fd = -1; + ptr_port->buf_len = 0; + + ptr_port->connected_num = 0; + ptr_port->disconnect_num = 0; + ptr_port->sent_fail_num = 0; + + memcpy(&ptr_port->sess, pSess, sizeof(tcp_session_t)); + + return pid; +} + + +int tcp_port_release_port(int sap_id, WORD usr_port, WORD pid) +{ + tcp_sap_t *ptr_sap = NULL; + tcp_port_t *ptr_port = NULL; + + if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL) + { + tcp_print_debug("tcp_port_release_port()->Invalid sap[%d]!\r\n", sap_id); + return -1; + } + + if((ptr_port = tcp_port_get_by_index(pid)) == NULL) + { + tcp_print_debug("tcp_port_release_port()->Invalid pid[%d]!\r\n", pid); + return -1; + } + + if((ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port)) + { + tcp_print_debug("tcp_port_release_port()->sap[%d] or pid[%d] not matched!\r\n", sap_id, pid); + return -1; + } + + if(ptr_port->fd >= 0) + { + close(ptr_port->fd); + } + + tcp_port_init(pid); + + return 0; +} + +tcp_session_t *tcp_port_update_sess(int sap_id, WORD usr_port, WORD pid, tcp_session_t *ptr_sess) +{ + tcp_sap_t *ptr_sap = NULL; + tcp_port_t *ptr_port = NULL; + + if(ptr_sess == NULL) + { + tcp_print_debug("tcp_port_update_sess()->Invalid param!\r\n"); + return NULL; + } + + if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL) + { + tcp_print_debug("tcp_port_update_sess()->Invalid sap[%d]!\r\n", sap_id); + return NULL; + } + + if((ptr_port = tcp_port_get_by_index(pid)) == NULL) + { + tcp_print_debug("tcp_port_update_sess()->Invalid pid[%d]!\r\n", pid); + return NULL; + } + + if((ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port)) + { + tcp_print_debug("tcp_port_update_sess()->sap[%d] or pid[%d] not matched!\r\n", sap_id, pid); + return NULL; + } + + memcpy((BYTE*)&ptr_port->sess, (BYTE*)ptr_sess, sizeof(tcp_session_t)); + + return &ptr_port->sess; +} + + +int get_tcp_sess(WORD pid, tcp_session_t *sess) +{ + tcp_port_t *ptr_port = NULL; + + if (pid >= TCP_MAX_NUM_OF_PORT) + { + return -1; + } + + if(sess == NULL) + { + return -1; + } + + if((ptr_port = tcp_port_get_by_index(pid)) == NULL) + { + tcp_print_debug("get_tcp_sess()->Invalid pid[%d]!\r\n", pid); + return -1; + } + + memcpy(sess, &ptr_port->sess, sizeof(tcp_session_t)); + + return 0; +} + + +static int tcp_send_msg(tcp_port_t *ptr_port, BYTE *msg, WORD len) +{ + int fd; + + if((ptr_port == NULL) || (len > TCP_MAX_SEND_MSG_LEN)) + { + tcp_print_error("tcp_send_msg()->Invalid param!\r\n"); + return -1; + } + + if (ptr_port->sess.bServer) + { + fd = ptr_port->cli_fd; + } + else + { + fd = ptr_port->fd; + } + + if (fd < 0) + { + tcp_print_error("tcp_send_msg()->pid[%d], invalid fd[%d]!\r\n", ptr_port->index, fd); + return -1; + } + + if (send(fd, msg, len, MSG_NOSIGNAL) < 0)// add MSG_NOSIGNAL, to avoid Broken pipe, while sending data after received FIN and sent FIN_ACK + { + tcp_print_error("TCP send msg failed! pid[%d], fd=%d, usr_port=%d, len[%d]\r\n", ptr_port->index, ptr_port->fd, ptr_port->usr_port, len); + return -1; + } + else + { + //tcp_print_debug("%d TCP send msg success! usr_port=%d\r\n", pid, ptr_port->usr_port); + } + + return 0; +} + + +static int tcp_send_hb(tcp_port_t *ptr_port, WORD msg_id) +{ + int ret = -1; + BYTE msg_buf[TCP_MAX_SEND_MSG_LEN]; + WORD msg_len; + DWORD pos = 0; + BYTE *pDst = NULL; + tcp_head_t *pHead = NULL; + + if(ptr_port == NULL || ptr_port->flag == FALSE) + { + tcp_print_error("tcp_send_hb()->Invalid port, used flag[%d]!\r\n", ptr_port->flag); + return -1; + } + + pDst = msg_buf; + + // Begin flag + pDst[pos++] = TCP_F_BB1; + pDst[pos++] = TCP_F_BB2; + // + + // len, 2 Bytes + msg_len = htons(sizeof(tcp_head_t)); + memcpy(&pDst[pos], (BYTE *)&msg_len, sizeof(msg_len)); + pos += sizeof(msg_len); + // + + // Head + pHead = (tcp_head_t *)&pDst[pos]; + pHead->usMsgId = htons(msg_id); + pHead->usPlLen = 0; + pHead->param1 = 0; + pHead->param2 = 0; + pHead->param3 = 0; + memcpy(&pDst[pos], (BYTE *)pHead, sizeof(tcp_head_t)); + pos += sizeof(tcp_head_t); + // + + // flagEnd + pDst[pos++] = TCP_F_EB1; + pDst[pos++] = TCP_F_EB2; + // + + msg_len = pos; + + ret = tcp_send_msg(ptr_port, msg_buf, msg_len); + //tcp_print_debug("tcp_send_hb()->send msg [%d]\r\n", msg_id); + + return ret; +} + + +static int tcp_handle_hb(tcp_port_t *ptr_port, tcp_head_t *pTcpHead) +{ + WORD usMsgId = 0; + if (ptr_port == NULL || pTcpHead == NULL) + { + return -1; + } + + if (pTcpHead->usPlLen != 0) + { + tcp_print_error("tcp_handle_hb()->pid[%d], err pl len[%d].\r\n", ptr_port->index, ntohl(pTcpHead->usPlLen)); + return -1; + } + + usMsgId = ntohs(pTcpHead->usMsgId); + if (usMsgId == TCP_MSG_HB) + { + //tcp_print_debug("tcp_handle_hb()->recv hb.\r\n"); + tcp_send_hb(ptr_port, TCP_MSG_HB_ACK); + } + else if (usMsgId == TCP_MSG_HB_ACK) + { + //tcp_print_debug("tcp_handle_hb()->recv hb ack.\r\n"); + if (ptr_port->status == TCP_STATUS_TESTING) + { + tcp_set_status(ptr_port, TCP_STATUS_CONNECTED); + ptr_port->connected_num++; + ptr_port->retry_num = 0; + } + else if (ptr_port->status == TCP_STATUS_CONNECTED) + { + ptr_port->retry_num = 0; + } + } + + return 0; +} + + +//static int tcp_port_handle_recv_msg(WORD pid, BYTE *buf, WORD len) +static int tcp_port_handle_recv_msg(tcp_port_t *ptr_port) +{ + tcp_sap_t *ptr_sap = NULL; + WORD ulCurMsgAllLen= 0; + DWORD fBeginPos = 0; + DWORD fEndPos = 0; + WORD usMsgLen = 0; + BYTE *pData = NULL; + tcp_head_t *pTcpHead = NULL; + + if(ptr_port == NULL || ptr_port->ptr_sap == NULL) + { + return -1; + } + + ptr_sap = ptr_port->ptr_sap; + if(ptr_sap->recv_cb == NULL) + { + return -1; + } + + for (;;) + { + // Check data leng in the buffer, start to handle if longer than format length + if (ptr_port->buf_len <= TCP_F_INF_ALL_LEN) + { + break; + } + + // Check begin flag + pData = &ptr_port->rv_buf[fBeginPos]; + if (!TCP_IsfBegin(pData[0], pData[1]))// Begin flag error, move 1 byte ahead + { + tcp_print_error("pid[%d], begin flag error, move 1 Byte ahead.\r\n", ptr_port->index); + ptr_port->buf_len -= 1;// Begin flag error, move 1 byte ahead, continue to parse buffer + fBeginPos += 1; + continue; + } + + // Check message length, msg length + format length < buffer length + usMsgLen = *((WORD *)&pData[TCP_F_INF_BEGIN_FLAG_LEN]); + usMsgLen = ntohs(usMsgLen); + if ((usMsgLen + TCP_F_INF_ALL_LEN) > TCP_MAX_RECV_BUF_LEN) + { + tcp_print_error("pid[%d], msg len error, move 2 Byte ahead.\r\n", ptr_port->index); + ptr_port->buf_len -= 2;// Msg length error, move 2 byte ahead, continue to parse buffer + fBeginPos += 2; + continue; + } + + ulCurMsgAllLen = usMsgLen + TCP_F_INF_ALL_LEN; + if (ptr_port->buf_len < ulCurMsgAllLen) + { + break;// msg not receive complete yet + } + + fEndPos = TCP_F_INF_HEAD_LEN + usMsgLen; + if (!TCP_IsfEnd(pData[fEndPos], pData[fEndPos+1])) + { + tcp_print_error("pid[%d], end flag error, move 2 Byte ahead.\r\n", ptr_port->index); + ptr_port->buf_len -= 2;// End flag error, move 2 byte ahead, continue to parse buffer + fBeginPos += 2; + continue; + } + + // Handle message + pTcpHead = (tcp_head_t *)(pData + TCP_F_INF_HEAD_LEN); + if (usMsgLen >= sizeof(tcp_head_t)) + { + WORD usPlLen = ntohs(pTcpHead->usPlLen); + if (usPlLen + sizeof(tcp_head_t) == usMsgLen) + { + WORD usMsgId; + BYTE *pPl = pData + TCP_F_INF_HEAD_LEN + sizeof(tcp_head_t); + + usMsgId = ntohs(pTcpHead->usMsgId); + if ((usMsgId == TCP_MSG_HB) || (usMsgId == TCP_MSG_HB_ACK)) + { + if (usMsgLen != sizeof(tcp_head_t)) + { + tcp_print_error("pid[%d], recv HB msg len error\r\n", ptr_port->index); + } + else + { + // Handle HB + tcp_handle_hb(ptr_port, pTcpHead); + } + } + else if (usMsgId == TCP_MSG_DATA) + { + DWORD ulParam1, ulParam2, ulParam3; + ulParam1 = ntohl(pTcpHead->param1); + ulParam2 = ntohl(pTcpHead->param2); + ulParam3 = ntohl(pTcpHead->param3); + ptr_sap->recv_cb(ptr_port->usr_port, pPl, usPlLen, ulParam1, ulParam2, ulParam3); + } + else + { + //g_ulMpuMsgStat[MPU_OPR_ERROR_PR_MSG]++; + tcp_print_error("pid[%d], msg id error\r\n", ptr_port->index); + } + + } + else + { + //g_ulMpuMsgStat[MPU_OPR_ERROR_PR_MSG]++; + tcp_print_error("pid[%d], msg len error\r\n", ptr_port->index); + } + } + else + { + tcp_print_error("pid[%d], Invalid msg.\r\n", ptr_port->index); + } + + // move buffer poiter + ptr_port->buf_len -= ulCurMsgAllLen; + fBeginPos += ulCurMsgAllLen; + } + + // After message handle, update buffer + if (ptr_port->buf_len && fBeginPos) + { + //g_ulMpuMsgStat[MPU_OPR_PM_LK_MEMMOVE_CNT]++; + memmove(&ptr_port->rv_buf[0], &ptr_port->rv_buf[fBeginPos], ptr_port->buf_len); + } + + return 0; +} + +void tcp_port_recv_msg(void) +{ + int index, i, len, addr_len, fd, pos; + BYTE msg_buf[TCP_MAX_RECV_MSG_LEN]; + //struct timeval tv; + + struct sockaddr_in sin_addr; + tcp_port_t *ptr_port = NULL; + + addr_len = sizeof(struct sockaddr); + memset(&sin_addr, 0, addr_len); + + for(index = 0; index < TCP_MAX_NUM_OF_PORT; index++) + { + ptr_port = &tcp_port[index]; + if(ptr_port->flag == FALSE) + { + continue; + } + + if(((ptr_port->sess.bServer) && (ptr_port->fd < 0 || ptr_port->cli_fd < 0)) \ + || ((!ptr_port->sess.bServer) && (ptr_port->fd < 0))) + { + continue; + } + + if (ptr_port->sess.bServer) + { + fd = ptr_port->cli_fd; + } + else + { + fd = ptr_port->fd; + } + + for(i = 0; i < TCP_MAX_RECV_COUNT; i++) + { + pos = ptr_port->buf_len; + len = recv(fd, msg_buf, TCP_MAX_RECV_MSG_LEN, 0); + if(len <= 0) + { + break; + } + + if((pos + len) >= TCP_MAX_RECV_BUF_LEN) + { + ptr_port->buf_len = 0; + pos = 0; + break; + } + + memcpy(&ptr_port->rv_buf[pos], msg_buf, len); + ptr_port->buf_len += len; + tcp_port_handle_recv_msg(ptr_port); + } + } + + return; +} + + +int tcp_send(int sap_id, WORD usr_port, WORD pid, BYTE *payload, WORD len, DWORD param1, DWORD param2, DWORD param3) +{ + int ret = -1; + BYTE msg_buf[TCP_MAX_SEND_MSG_LEN]; + WORD msg_len; + tcp_sap_t *ptr_sap = NULL; + tcp_port_t *ptr_port = NULL; + WORD pos = 0; + BYTE *pDst = NULL; + tcp_head_t *pHead = NULL; + + if((payload == NULL) || (len > TCP_MAX_PAYLOAD_SIZE)) + { + tcp_print_error("tcp_send()->Invalid payload[%p] or len[%d]!\r\n", payload, len); + return -1; + } + + if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL) + { + tcp_print_error("tcp_send()->Invalid sap[%d]!\r\n", sap_id); + return -1; + } + + if(pid >= TCP_MAX_NUM_OF_PORT) + { + tcp_print_error("tcp_send()->Invalid pid[%d]!\r\n", pid); + return -1; + } + + ptr_port = &tcp_port[pid]; + if((ptr_port->flag == FALSE) || (ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port)) + { + tcp_print_error("tcp_send()->pid[%d], invalid port, used flag[%d]!\r\n", ptr_port->index, ptr_port->flag); + return -1; + } + + if (ptr_port->status != TCP_STATUS_CONNECTED) + { + tcp_print_error("tcp_send()->pid[%d], link not connected!\r\n", ptr_port->index); + return -1; + } + + pDst = msg_buf; + + // Begin flag + pDst[pos++] = TCP_F_BB1; + pDst[pos++] = TCP_F_BB2; + // + + // len, 2 Bytes + msg_len = htons(len + sizeof(tcp_head_t)); + memcpy(&pDst[pos], (BYTE *)&msg_len, sizeof(msg_len)); + pos += sizeof(msg_len); + // + + // Head + pHead = (tcp_head_t *)&pDst[pos]; + pHead->usMsgId = htons(TCP_MSG_DATA); + pHead->usPlLen = htons(len); + pHead->param1 = htonl(param1); + pHead->param2 = htonl(param2); + pHead->param3 = htonl(param3); + memcpy(&pDst[pos], (BYTE *)pHead, sizeof(tcp_head_t)); + pos += sizeof(tcp_head_t); + // + + // msgData + memcpy(&pDst[pos], payload, len); + pos += len; + // + + // flagEnd + pDst[pos++] = TCP_F_EB1; + pDst[pos++] = TCP_F_EB2; + // + + msg_len = pos; + + ret = tcp_send_msg(ptr_port, msg_buf, msg_len); + if(ret < 0) + { + ptr_port->sent_fail_num++; + } + + return ret; +} + + +int tcp_link_fsm() +{ + int i; + tcp_port_t *ptr_port = NULL; + tcp_session_t *pSess = NULL; + + for (i=0; iflag) + { + continue; + } + + //if (ptr_port->fd < 0) + //{ + // tcp_port_init(i); + // continue; + //} + + pSess = &ptr_port->sess; + switch (ptr_port->status) + { + case TCP_STATUS_INITING: + if (--ptr_port->timer > 0) + { + continue; + } + + ptr_port->fd = tcp_init_socket(pSess); + if (ptr_port->fd < 0) + { + ptr_port->timer = TCP_TIMER_REINIT; + } + else + { + tcp_set_status(ptr_port, TCP_STATUS_INITED); + } + break; + case TCP_STATUS_INITED: + if (--ptr_port->timer > 0) + { + continue; + } + + if (pSess->bServer) + { + if (tcp_check_conn(ptr_port) < 0) + { + ptr_port->timer = TCP_TIMER_WAIT_CONNECT; + } + else + { + ptr_port->timer = 0; + ptr_port->retry_num = 0; + tcp_set_status(ptr_port, TCP_STATUS_TESTING); + } + } + else + { + if (tcp_connect(ptr_port) < 0) + { + close(ptr_port->fd); + ptr_port->fd = -1; + tcp_set_status(ptr_port, TCP_STATUS_INITING); + tcp_print_error("pid[%d] tcp connect failed!\r\n", i); + ptr_port->timer = TCP_TIMER_REINIT; + } + else + { + ptr_port->timer = TCP_TIMER_WAIT_CONNECT; + ptr_port->retry_num = 0; + tcp_set_status(ptr_port, TCP_STATUS_TESTING); + } + } + break; + case TCP_STATUS_TESTING:// sending HB + case TCP_STATUS_CONNECTED: + if (--ptr_port->timer > 0) + { + continue; + } + + if (ptr_port->retry_num++ >= TCP_MAX_RETRY_NUM) + { + if (ptr_port->sess.bServer) + { + close(ptr_port->cli_fd); + ptr_port->cli_fd = -1; + ptr_port->timer = 0; + tcp_set_status(ptr_port, TCP_STATUS_INITED); + } + else + { + close(ptr_port->fd); + ptr_port->fd = -1; + ptr_port->timer = 0; + tcp_set_status(ptr_port, TCP_STATUS_INITING); + } + } + else + { + tcp_send_hb(ptr_port, TCP_MSG_HB); + ptr_port->timer = TCP_TIMER_HB; + } + break; + default: + break; + } + } + + return 0; +} + + +BOOL tcp_print_all_port(void) +{ + int j = 0, i; + char buf[516], tmp_buf[8]; + tcp_port_t *ptr_port = NULL; + + strcpy(buf, "\0"); + tcp_print_debug("Used tcp port:\r\n"); + for(i = 0; i < TCP_MAX_NUM_OF_PORT; i++) + { + ptr_port = &tcp_port[i]; + if(ptr_port->flag == TRUE) + { + if(j % 20 == 0 && j != 0) + { + tcp_print_debug("%s\r\n", buf); + strcpy(buf, "\0"); + } + sprintf(tmp_buf, "%d ", i); + strcat(buf, tmp_buf); + j++; + } + } + + if(j % 20) + { + tcp_print_debug("%s\r\n", buf); + } +// tcp_print_debug("\r\n"); + + return TRUE; +} + +BOOL tcp_print_port(int pid) +{ + tcp_port_t *ptr_port = NULL; + + if((pid < 0) || (pid >= TCP_MAX_NUM_OF_PORT)) + { + return FALSE; + } + + ptr_port = &tcp_port[pid]; + tcp_print_debug("TCP port %d: %s\r\n", pid, (ptr_port->flag==TRUE)?"used":"idle"); + if(ptr_port->flag == FALSE) + { + return TRUE; + } + + tcp_print_debug("usr port: %d\r\n", ptr_port->usr_port); + if (ptr_port->status < TCP_STATUS_MAX) + { + tcp_print_debug("status: %s\r\n", tcp_status_str[ptr_port->status]); + } + tcp_print_debug("retry: %d\r\n", ptr_port->retry_num); + tcp_print_debug("fd: %d\r\n", ptr_port->fd); + tcp_print_debug("proto: %s\r\n", (ptr_port->sess.bServer==TRUE)?"Server":"Client"); + if (ptr_port->sess.bServer) + { + tcp_print_debug("cli_fd: %d\r\n", ptr_port->cli_fd); + } + tcp_print_debug("src ip: %d.%d.%d.%d\r\n", (ptr_port->sess.src_ip)&0xFF, (ptr_port->sess.src_ip>>8)&0xFF, \ + (ptr_port->sess.src_ip>>16)&0xFF, (ptr_port->sess.src_ip>>24)&0xFF); + tcp_print_debug("src port: %d\r\n", ptr_port->sess.src_port); + tcp_print_debug("dst ip: %d.%d.%d.%d\r\n", (ptr_port->sess.dst_ip)&0xFF, (ptr_port->sess.dst_ip>>8)&0xFF, \ + (ptr_port->sess.dst_ip>>16)&0xFF, (ptr_port->sess.dst_ip>>24)&0xFF); + tcp_print_debug("dst port: %d\r\n", ptr_port->sess.dst_port); + + tcp_print_debug("connected num: %d\r\n", ptr_port->connected_num); + tcp_print_debug("disconnect num: %d\r\n", ptr_port->disconnect_num); + tcp_print_debug("sent fail num: %d\r\n", ptr_port->sent_fail_num); + + return TRUE; +} + + +BOOL tcp_clear_stat(int pid) +{ + tcp_port_t *ptr_port = NULL; + + if((pid < 0) || (pid >= TCP_MAX_NUM_OF_PORT)) + { + return FALSE; + } + + ptr_port = &tcp_port[pid]; + if(ptr_port->flag == FALSE) + { + return TRUE; + } + + ptr_port->connected_num = 0; + ptr_port->disconnect_num = 0; + ptr_port->sent_fail_num = 0; + + return TRUE; +} + diff --git a/plat/xapp/Makefile b/plat/xapp/Makefile new file mode 100644 index 0000000..0f3b8b8 --- /dev/null +++ b/plat/xapp/Makefile @@ -0,0 +1,95 @@ + +##----------------------------------------------------------## +## ## +## Universal Makefile for module Version : V1.4 ## +## ## +## Created : Wei Liu 07/04/11 ## +## Revision: [Last]Wei Liu 07/06/18 ## +## ## +##----------------------------------------------------------## + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Project correlation(Customer define) +## +##-------------------------------------- + +## MODULE= [Module Name] +## TYPE = app/plat => Module Type + +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ] +## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release] + +## BUILD = lib/exef => Output file format +## CFG = debug/release => Build Configuration + +## SRC_PATH = [Source file path] +## INC_PATH = [Include file path] +## APP_PATH = [App Module path] +## PLT_PATH = [Plat Module path] + +## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main +## APP_LIB = [Needed app lib for Link] => just for test or wxc2main +## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main + +## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \ +## 8ecp bicc smpp xapp tcap mtp3 m2ua \ +## snmp iptrans debug sccp public +## +## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas +## LIB_ADD e.g. = -liba3a8 -lm + +## OBJ_ADD = [Extend third party object files needed] +## TEST_OBJ_PATH = [module object files Path for test ] => just for test +##---------------------------------------------------------------------## + + + +MODULE = xapp +TYPE = plat + +DBUG_FLAGS_ADD = +RELS_FLAGS_ADD = + +##Default commonly as below + +BUILD = lib +CFG = debug + +PLT_LIB = +APP_LIB = +LIB_ADD = + +SRC_PATH = ./src/capp ./src/mapp ./src +INC_PATH = ./src/include +PLT_PATH = ../../plat +APP_PATH = ../../app + +OBJ_ADD = +TEST_OBJ_PATH = ../../obj + +##---------------------------------------------------------------------## +##-------------------------------------- +## +## Make configuration(Customer define) +## +##-------------------------------------- + +## CCFLAG_SWITCH = on/off => gcc flag show on/off +## COVER_NEED = yes/no => PTF cover report needed +## COVER_REPORT_PATH = [path ] => PTF cover report path + +CCFLAG_SWITCH = off +COVER_NEED = +COVER_REPORT_PATH = ./ut/ut_doc/output + +##---------------------------------------------------------------------## + + +##-------------------------------------- +## +## include makefile.rules (Do not change) +## +##-------------------------------------- +include Makefile.rules diff --git a/plat/xapp/conf/cap_acn.conf b/plat/xapp/conf/cap_acn.conf new file mode 100644 index 0000000..2977f57 --- /dev/null +++ b/plat/xapp/conf/cap_acn.conf @@ -0,0 +1,8 @@ +#application context name configure file for CAP +total data length=4 + +#application context name data +No.1:50 00 // gsmSSF to gsmSCF +No.2:51 00 // assist handoff gsmSSF to gsmSCF +No.3:52 00 // gsmSRF to gsmSCF +No.4:128 00 // gsmSRF to gsmSCF diff --git a/plat/xapp/conf/cap_operation.conf b/plat/xapp/conf/cap_operation.conf new file mode 100644 index 0000000..1bf4c08 --- /dev/null +++ b/plat/xapp/conf/cap_operation.conf @@ -0,0 +1,36 @@ +# operation code configure file for CAP +total data length=32 + +#operation code +No.1:00 04 5 // initial DP +No.2:16 02 5 // assist request instructions +No.3:17 02 20 // establish temporary connection +No.4:18 04 5 // disconnect forward connection +No.5:19 04 5 // connect to resource +No.6:20 04 5 // connect +No.7:22 04 5 // release call +No.8:23 04 5 // request report BCSM event +No.9:24 04 5 // event report BCSM +No.10:31 04 5 // continue +No.11:33 04 5 // reset timer +No.12:34 04 5 // furnish charging information +No.13:35 04 5 // apply charging +No.14:36 04 5 // apply charging report +No.15:44 04 5 // call information report +No.16:45 04 5 // call information request +No.17:46 04 5 // send charging information +No.18:47 04 60 // play announcement +No.19:48 01 60 // prompt and collect user information +No.20:49 04 5 // specialized resource report +No.21:53 04 5 // cancel +No.22:55 01 5 // activity test +No.23:60 04 5 // initial DPSMS +No.24:61 04 5 // Furnishing charging info.SMS +No.25:62 04 5 // connect DPSMS +No.26:63 04 5 // request SMS event +No.27:64 04 5 // event report SMS +No.28:65 04 5 // continue SMS +No.29:66 04 5 // release DPSMS +No.30:67 04 5 // reset timer DPSMS +No.31:176 04 5 // VPS to PPS +No.32:177 04 5 // PPS to VPS diff --git a/plat/xapp/conf/map_acn.conf b/plat/xapp/conf/map_acn.conf new file mode 100644 index 0000000..16e9e11 --- /dev/null +++ b/plat/xapp/conf/map_acn.conf @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 01 // subscriber data management +No.11:17 03 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 02 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/plat/xapp/conf/map_operation.conf b/plat/xapp/conf/map_operation.conf new file mode 100644 index 0000000..2493051 --- /dev/null +++ b/plat/xapp/conf/map_operation.conf @@ -0,0 +1,76 @@ +# operation code configure file +total data length=72 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:09 01 20 // send parameters +No.64:48 01 20 // not subscriber present +No.65:19 01 20 // process unstructure SS data +No.66:54 01 20 // beging subscriber activity +No.67:28 01 20 // perform handover +No.68:30 01 20 // perform subsequence handvoer +No.69:35 01 20 // note internal handover +No.70:54 01 20 // beging subscriber activity +No.71:49 01 20 // alert service center without result +No.72:52 01 20 // trace subscriber activity \ No newline at end of file diff --git a/plat/xapp/src/capp/cap_coding.h b/plat/xapp/src/capp/cap_coding.h new file mode 100644 index 0000000..5753b19 --- /dev/null +++ b/plat/xapp/src/capp/cap_coding.h @@ -0,0 +1,39 @@ +/* CAP message coding/decoding head file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* ------------------------------------- */ + +#ifndef _CAP_CODING +#define _CAP_CODING + +#ifndef _SRF_RELEVANT +#define _SRF_RELEVANT +#endif + +int encSubscriberState(u_char sel, char *tagprefix, CapSubscriberState arg, ASN_BUF * asnbuf); +int decSubscriberState(char *tagprefix, CapSubscriberState * parg, ASN_BUF * asnbuf); +int encExt_BasicServiceCode(u_char sel, char *tagprefix, CapExt_BasicServiceCode arg, ASN_BUF * asnbuf); +int decExt_BasicServiceCode(char *tagprefix, CapExt_BasicServiceCode * parg, ASN_BUF * asnbuf); +int encLocationInformation(char *tagprefix, CapLocationInformation arg, ASN_BUF * asnbuf); +int decLocationInformation(char *tagprefix, CapLocationInformation * parg, ASN_BUF * asnbuf); +int encACBCC(struct CapACBCC arg, char *msgbuf, int maxlen); +int decACBCC(char *msgbuf, int msglen, CapACBCC * parg); +int encLegID(u_char sel, char *tagprefix, CapLegID arg, ASN_BUF * asnbuf); +int decLegID(char *tagprefix, CapLegID * parg, ASN_BUF * asnbuf); +int encESIBCSM(char *tagprefix, CapESIBCSM arg, ASN_BUF * asnbuf); +int decESIBCSM(char *tagprefix, CapESIBCSM * parg, ASN_BUF * asnbuf); +int encLocationInformationGPRS(char *tagprefix, CapLocationInformationGPRS arg, ASN_BUF * asnbuf); +int decLocationInformationGPRS(char *tagprefix, CapLocationInformationGPRS * parg, ASN_BUF * asnbuf); +int encESISMS(char *tagprefix, CapESISMS arg, ASN_BUF * asnbuf); +int decESISMS(char *tagprefix, CapESISMS * parg, ASN_BUF * asnbuf); + +#ifdef _SRF_RELEVANT +int encServiceInteractionIndicatorsTwo(char *tagprefix, CapServiceInteractionIndicatorsTwo arg, ASN_BUF * asnbuf); +int decServiceInteractionIndicatorsTwo(char *tagprefix, CapServiceInteractionIndicatorsTwo * parg, ASN_BUF * asnbuf); +int encInformationToSend(char *tagprefix, CapInformationToSend arg, ASN_BUF * asnbuf); +int decInformationToSend(char *tagprefix, CapInformationToSend * parg, ASN_BUF * asnbuf); +int encCollectedInfo(char *tagprefix, CapCollectedInfo arg, ASN_BUF * asnbuf); +int decCollectedInfo(char *tagprefix, CapCollectedInfo * parg, ASN_BUF * asnbuf); +#endif + +#endif diff --git a/plat/xapp/src/capp/cap_head.h b/plat/xapp/src/capp/cap_head.h new file mode 100644 index 0000000..3d94295 --- /dev/null +++ b/plat/xapp/src/capp/cap_head.h @@ -0,0 +1,151 @@ +#ifndef _CAP_HEAD +#define _CAP_HEAD + +#ifndef _SRF_RELEVANT +#define _SRF_RELEVANT +#endif + +#define CAP_FLAG 0x8a + +#ifndef MAX_ACN_LEN +#define MAX_ACN_LEN TCAP_ACN_LEN +#endif + +#define TV_SSF 100 +#define TV_Wait_Open TV_SSF//1s +#define TV_Wait_Continue (TV_SSF * 5)//5s +#define TV_Wait_Request (TV_SSF * 10)//10s +#define TV_Non_User_Interaction (TV_SSF * 30)//30s +#define TV_Reset TV_SSF +#define TV_Interaction (TV_SSF * 10)//10s +#define TV_TCE 12*(TV_SSF*10) +#define TV_Pending (TV_SSF * 1/2) + +#define ONE_SECOND_TICKS TV_SSF +#define WTRESPONSE_TIMER (10*ONE_SECOND_TICKS) // 10s +#define WTSSF_TIMER (11*ONE_SECOND_TICKS) // 11s + +#define minAChBillingChargingLength 5 +#define maxAChBillingChargingLength 177 +#define minAttributesLength 2 +#define maxAttributesLength 10 +#define maxBearerCapabilityLength 11 +#define minCallResultLength 12 +#define maxCallResultLength 24 +#define minCalledPartyBCDNumberLength 1 +#define maxCalledPartyBCDNumberLength 41 +#define minCalledPartyNumberLength 3 +#define maxCalledPartyNumberLength 12 +#define minCallingPartyNumberLength 2 +#define maxCallingPartyNumberLength 10 +#define minCauseLength 2 +#define maxCauseLength 2 +#define minDigitsLength 2 +#define maxDigitsLength 16 +#define minFCIBillingChargingDataLength 1 +#define maxFCIBillingChargingDataLength 40 +#define minFCIBillingChargingLength 5 +#define maxFCIBillingChargingLength 49 +#define minGenericNumberLength 3 +#define maxGenericNumberLength 11 +#define minIPSSPCapabilitiesLength 1 +#define maxIPSSPCapabilitiesLength 4 +#define minLocationNumberLength 2 +#define maxLocationNumberLength 10 +#define minMessageContentLength 1 +#define maxMessageContentLength 127 +#define minOriginalCalledPartyIDLength 2 +#define maxOriginalCalledPartyIDLength 10 +#define minRedirectingPartyIDLength 2 +#define maxRedirectingPartyIDLength 10 +#define minScfIDLength 2 +#define maxScfIDLength 10 +#define minSCIBillingChargingLength 4 +#define maxSCIBillingChargingLength 69 +#define minTimeAndTimezoneLength 8 +#define maxTimeAndTimezoneLength 8 +#define numOfBCSMEvents 10 +#define numOfExtensions 10 +#define numOfGenericNumbers 5 +#define numOfInfoItems 4 +#define numOfMessageIDs 5 + +#define maxIMSILength 8 +#define maxISDNAddressLength 9 +#define maxcallReferenceNumberLength 8 +#define numOfSMSEvents 10 +#define MAX_EDP_NUM (18+1) +#define MAX_DP_NUM 32 +#define CAP_CONTENT_LEN 256 + +//Operation Code +#define CAP_MSG_TYPE CAP_FLAG + +#define CAP_O_OPEN 0xff +#define CAP_O_END 0xfe +#define CAP_O_UABORT 0xfd +#define CAP_O_PABORT 0xfc +#define CAP_O_NOTICE 0xfb +#define CAP_O_DELIMETER 0xfa +#define CAP_O_ERROR 0xf0 +#define CAP_O_LINK 0xef +#define CAP_O_REFUSE_AC 0xE0 +#define CAP_O_AC_ERROR 0xE1 +#define CAP_OC_Release 0xfe +#define CAP_OC_Error 0xf0 + +#define CAP_OC_InitialDP 0 +#define CAP_OC_AssistRequestInstructions 16 +#define CAP_OC_EstablishTemporaryConnection 17 +#define CAP_OC_DisconnectForwardConnection 18 +#define CAP_OC_ConnectToResource 19 +#define CAP_OC_Connect 20 +#define CAP_OC_ReleaseCall 22 +#define CAP_OC_RequestReportBCSMEvent 23 +#define CAP_OC_EventReportBCSM 24 +#define CAP_OC_Continue 31 +#define CAP_OC_ResetTimer 33 +#define CAP_OC_FurnishChargingInformation 34 +#define CAP_OC_ApplyCharging 35 +#define CAP_OC_ApplyChargingReport 36 +#define CAP_OC_CallInformationReport 44 +#define CAP_OC_CallInformationRequest 45 +#define CAP_OC_SendChargingInformation 46 +#define CAP_OC_PlayAnnouncement 47 +#define CAP_OC_PromptAndCollectUserInformation 48 +#define CAP_OC_SpecializedResourceReport 49 +#define CAP_OC_Cancel 53 +#define CAP_OC_ActivityTest 55 +#define CAP_OC_ApplyWarningTone 128 //self define +#define CAP_OC_CCF_Continue 129 //self define + +#define CAP_OC_InitialDPSMS 60 +#define CAP_OC_FurnishChargingInformationSMS 61 +#define CAP_OC_ConnectSMS 62 +#define CAP_OC_RequestReportSMSEvent 63 +#define CAP_OC_EventReportSMS 64 +#define CAP_OC_ContinueSMS 65 +#define CAP_OC_ReleaseSMS 66 +#define CAP_OC_ResetTimerSMS 67 + +#ifdef _SRF_RELEVANT +//CAP Operation Type +#define CAP_REQUEST 0x01 +#define CAP_INDICATE 0x02 +#define CAP_RESPONSE 0x03 +#define CAP_CONFIRM 0x04 +#endif + +/* defined for VPS interface */ +#define CAP_OC_VPSOprRequest 0xb0 +#ifndef _SRF_RELEVANT +#define CAP_OC_PlayAnnouncement 0xb1 +#endif + +#define maxVPSCallingLen 8 +#define maxVPSCalledLen 16 +#define maxVPSInfoLen 64 + +#define CAP_ACN_VPSREQUEST 0x80 + +#endif diff --git a/plat/xapp/src/capp/cap_msg.c b/plat/xapp/src/capp/cap_msg.c new file mode 100644 index 0000000..9cd812e --- /dev/null +++ b/plat/xapp/src/capp/cap_msg.c @@ -0,0 +1,1520 @@ + +/************************************************/ +/*Title: capmsg.c */ +/*Descr: Encode/Decode Cap Message */ +/*Author: Liang Hanxi */ +/*Create: 2002-10-31 */ +/*Modify: 2002-12-4 */ + +/************************************************/ + +#include "../../../public/src/include/pub_include.h" +#include "cap_head.h" +#include "cap_msg.h" +#include "cap_coding.h" + +/*++++++++++++++++++++++++++++++++++++++ */ +/*Cancel-------------------------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eCancel(struct CapCancel caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + switch (caparg.ch) + { + case 0: + return AddInteger("2", caparg.invokeID, 0, &asnbuf); + case 1: + return add_null("5", 0, &asnbuf); + default: + return -1; + } +} + +int dCancel(char *msgbuf, int msglen, PCapCancel pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if(GetInteger("2", (int *)&pcaparg->invokeID, 0, &asnbuf) >= 0) + { + pcaparg->ch = 0; + return 1; + } + else if(GetTLV("5", 1, &pcaparg->allRequest, 0, &asnbuf) >= 0) + { + pcaparg->ch = 1; + return 1; + } + return -1; +} + +/*************************************/ +/*InitialDP-------------------------> */ + +/*************************************/ +int eInitialDP(struct CapInitialDP caparg, char *msgbuf, int maxlen,u8 version) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + retval = AddInteger("16.0", caparg.serviceKey, 0x80, &asnbuf); + //optional part + if(check_bit(caparg.optional_flag, 0)) + { + if((retval = AddTLV("16.2", caparg.calledPartyNumber[0], caparg.calledPartyNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 1)) + { + if((retval = AddTLV("16.3", caparg.callingPartyNumber[0], caparg.callingPartyNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 2)) + { + if((retval = AddTLV("16.5", 1, &caparg.callingPartysCategory, 0x80, &asnbuf)) < 0) + return -1; + } + if( version > 1 ) + { + if(check_bit(caparg.optional_flag, 3)) + { + if((retval = AddTLV("16.8", caparg.iPSSPCapabilities[0], caparg.iPSSPCapabilities + 1, 0x80, &asnbuf)) < 0) + return -1; + } + } + if(check_bit(caparg.optional_flag, 4)) + { + if((retval = AddTLV("16.10", caparg.locationNumber[0], caparg.locationNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 5)) + { + if((retval = AddTLV("16.12", caparg.originalCalledPartyID[0], caparg.originalCalledPartyID + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 7)) + { + if((retval = AddTLV("16.23", caparg.highLayerCompatibility[0], caparg.highLayerCompatibility + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 8)) + { + if((retval = AddTLV("16.25", caparg.additionalCallingPartyNumber[0], caparg.additionalCallingPartyNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 9)) + { + if((retval = AddTLV("16.27.0", caparg.bearerCapability.bearerCap[0], caparg.bearerCapability.bearerCap + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 10)) + { + if((retval = AddInteger("16.28", caparg.eventTypeBCSM, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 11)) + { + if((retval = AddTLV("16.29", caparg.redirectingPartyID[0], caparg.redirectingPartyID + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 12)) + { + if((retval = AddTLV("16.30", caparg.redirectionInformation[0], caparg.redirectionInformation + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 13)) + { + if((retval = AddTLV("16.50", caparg.iMSI[0], caparg.iMSI + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 14)) + { + if((retval = encSubscriberState(caparg.subscriberState_ch, "16.51", caparg.subscriberState, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 15)) + { + if((retval = encLocationInformation("16.52", caparg.locationInformation, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 16)) + { + if((retval = encExt_BasicServiceCode(caparg.ext_basicServiceCode_ch, "16.53", caparg.ext_basicServiceCode, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 17)) + { + if((retval = AddTLV("16.54", caparg.callReferenceNumber[0], caparg.callReferenceNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + + if(check_bit(caparg.optional_flag, 18)) + { + if((retval = AddTLV("16.55", caparg.mscAddress[0], caparg.mscAddress + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 19)) + { + if((retval = AddTLV("16.56", caparg.calledPartyBCDNumber[0], caparg.calledPartyBCDNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + + if( version >1 ) + { + if(check_bit(caparg.optional_flag, 20)) + { + if((retval = AddTLV("16.57", caparg.timeAndTimezone[0], caparg.timeAndTimezone + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 21)) + { + if((retval = AddTLV("16.58", 0, &caparg.gsm_ForwardingPending, 0x80, &asnbuf)) < 0) + return -1; + } + } + return retval; +} + +int dInitialDP(char *msgbuf, int msglen, PCapInitialDP pcaparg , u8 version ) +{ + ASN_BUF asnbuf; + int temp, sel, len; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &temp, &asnbuf)) < 0) + { + return -1; + } + if(GetInteger("16.0", &pcaparg->serviceKey, 0x80, &asnbuf) < 0) //serviceKey + return -1; + //optional part + //called party number============> + if((len = GetTLV("16.2", maxCalledPartyNumberLength, pcaparg->calledPartyNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 0); + pcaparg->calledPartyNumber[0] = len; + } + //calling party number============> + if((len = GetTLV("16.3", maxCallingPartyNumberLength, pcaparg->callingPartyNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 1); + pcaparg->callingPartyNumber[0] = len; + } + //calling party category============> + if((len = GetTLV("16.5", 1, &pcaparg->callingPartysCategory, 0x80, &asnbuf)) > 0) + set_bit(pcaparg->optional_flag, 2); + if( version >1 ) + { + //IPSSPCapabilities============> + if((len = GetTLV("16.8", maxIPSSPCapabilitiesLength, pcaparg->iPSSPCapabilities + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 3); + pcaparg->iPSSPCapabilities[0] = len; + } + } + //LocationNumber============> + if((len = GetTLV("16.10", maxLocationNumberLength, pcaparg->locationNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 4); + pcaparg->locationNumber[0] = len; + } + //OriginalCalledPartyID============> + if((len = GetTLV("16.12", maxOriginalCalledPartyIDLength, pcaparg->originalCalledPartyID + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 5); + pcaparg->originalCalledPartyID[0] = len; + } + //highLayerCompatibility============> + if((len = GetTLV("16.23", 2, pcaparg->highLayerCompatibility + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 7); + pcaparg->highLayerCompatibility[0] = len; + } + //additionalCallingPartyNumber============> + if((len = GetTLV("16.25", maxDigitsLength, pcaparg->additionalCallingPartyNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 8); + pcaparg->additionalCallingPartyNumber[0] = len; + } + //bearerCapability============> + if((len = GetTLV("16.27.0", maxBearerCapabilityLength, pcaparg->bearerCapability.bearerCap + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 9); + pcaparg->bearerCapability.bearerCap[0] = len; + } + //eventTypeBCSM============> + if((len = GetInteger("16.28", (int *)&pcaparg->eventTypeBCSM, 0x80, &asnbuf)) > 0) + set_bit(pcaparg->optional_flag, 10); + //redirectingPartyID============> + if((len = GetTLV("16.29", maxRedirectingPartyIDLength, pcaparg->redirectingPartyID + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 11); + pcaparg->redirectingPartyID[0] = len; + } + //redirectingPartyID============> + if((len = GetTLV("16.30", 2, pcaparg->redirectionInformation + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 12); + pcaparg->redirectionInformation[0] = len; + } + //iMSI============> + if((len = GetTLV("16.50", maxIMSILength, pcaparg->iMSI + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 13); + pcaparg->iMSI[0] = len; + } + //subscriberState============> + if((sel = decSubscriberState("16.51", &pcaparg->subscriberState, &asnbuf)) >= 0) + { + set_bit(pcaparg->optional_flag, 14); + pcaparg->subscriberState_ch = sel; + } + //locationInformation============> + if(decLocationInformation("16.52", &pcaparg->locationInformation, &asnbuf) >= 0) + set_bit(pcaparg->optional_flag, 15); + //ext_basicServiceCode============> + if((sel = decExt_BasicServiceCode("16.53", &pcaparg->ext_basicServiceCode, &asnbuf)) >= 0) + { + set_bit(pcaparg->optional_flag, 16); + pcaparg->ext_basicServiceCode_ch = sel; + } + //callReferenceNumber============> + if((len = GetTLV("16.54", maxcallReferenceNumberLength, pcaparg->callReferenceNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 17); + pcaparg->callReferenceNumber[0] = len; + } + + //if( version >1 ) + { + //mscAddress============> + if((len = GetTLV("16.55", maxISDNAddressLength, pcaparg->mscAddress + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 18); + pcaparg->mscAddress[0] = len; + } + //calledPartyBCDNumber============> + if((len = GetTLV("16.56", maxCalledPartyBCDNumberLength, pcaparg->calledPartyBCDNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 19); + pcaparg->calledPartyBCDNumber[0] = len; + } + //timeAndTimezone============> + if((len = GetTLV("16.57", maxTimeAndTimezoneLength, pcaparg->timeAndTimezone + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 20); + pcaparg->timeAndTimezone[0] = len; + } + //gsm_ForwardingPending============> + if((len = GetTLV("16.58", 1, &pcaparg->gsm_ForwardingPending, 0x80, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 21); + } + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++ */ +/*ApplyCharging------------------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eApplyCharging(struct CapApplyCharging caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1, len; + u_char bill_info[256]; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + if((len = encACBCC(caparg.ACBCC, (char *)bill_info, 256)) < 0) + return -1; + if((retval = AddTLV("16.0", len, bill_info, 0x80, &asnbuf)) < 0) + return -1; + if((retval = AddTLV("16.2.0", 1, &caparg.partyToCharge, 0x80, &asnbuf)) < 0) + return -1; + return retval; +} + +int dApplyCharging(char *msgbuf, int msglen, PCapApplyCharging pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + u_char bill_info[256]; + + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if((len = GetTLV("16.0", 256, bill_info, 0x80, &asnbuf)) < 0) + return -1; + if(decACBCC((char *)bill_info, len, &pcaparg->ACBCC) < 0) + return -1; + if((len = GetTLV("16.2.0", 1, &pcaparg->partyToCharge, 0x80, &asnbuf)) < 0) + return -1; + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++ */ +/*RequestReportBCSMEvent--------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eRequestReportBCSMEvent(struct CapRequestReportBCSMEvent caparg, char *msgbuf, int maxlen, int version) +{ + ASN_BUF asnbuf; + int retval = -1, index = 0; + char tagseq[32]; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + for(index = 0; index < caparg.bcsmEvents_num; index++) + { + sprintf(tagseq, "16.0.16-%d", index + 1); + add_null(tagseq, 0x20, &asnbuf); + sprintf(tagseq, "16.0.16-%d.0", index + 1); //eventTypeBCSM + if((retval = AddInteger(tagseq, caparg.bcsmEvents[index].eventTypeBCSM, 0x80, &asnbuf)) < 0) + return -1; + sprintf(tagseq, "16.0.16-%d.1", index + 1); //monitorMode + if((retval = AddInteger(tagseq, caparg.bcsmEvents[index].monitorMode, 0x80, &asnbuf)) < 0) + return -1; + sprintf(tagseq, "16.0.16-%d.2", index + 1); //LegID + if(check_bit(caparg.bcsmEvents[index].optional_flag, 0)) //LegID + { + if((retval = encLegID(caparg.bcsmEvents[index].legID_ch, tagseq, caparg.bcsmEvents[index].legID, &asnbuf)) < 0) + return -1; + } + if(version != 1) + { + sprintf(tagseq, "16.0.16-%d.30.1", index + 1); //dPSpecificCriteria(applicationTimer) + if(check_bit(caparg.bcsmEvents[index].optional_flag, 1)) //LegID + { + if((retval = AddInteger(tagseq, caparg.bcsmEvents[index].dPSpecificCriteria.applicationTimer, 0x80, &asnbuf)) < 0) + return -1; + } + } + } + return retval; +} + +int dRequestReportBCSMEvent(char *msgbuf, int msglen, PCapRequestReportBCSMEvent pcaparg, int version) +{ + ASN_BUF asnbuf; + int errpos, sel, len, index = 0; + char tagseq[32]; + CapBCSMEvent *pevent; + + pcaparg->bcsmEvents_num = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + do + { + pevent = &pcaparg->bcsmEvents[index]; + pevent->optional_flag = 0; + sprintf(tagseq, "16.0.16-%d.0", index + 1); //eventTypeBCSM + if((len = GetInteger(tagseq, (int *)&pevent->eventTypeBCSM, 0x80, &asnbuf)) < 0) + break; + sprintf(tagseq, "16.0.16-%d.1", index + 1); //monitorMode + if((len = GetInteger(tagseq, (int *)&pevent->monitorMode, 0x80, &asnbuf)) < 0) + break; + sprintf(tagseq, "16.0.16-%d.2", index + 1); //LegID + if((sel = decLegID(tagseq, &pevent->legID, &asnbuf)) >= 0) + { + set_bit(pevent->optional_flag, 0); + pevent->legID_ch = sel; + } + if(version != 1) + { + sprintf(tagseq, "16.0.16-%d.30.1", index + 1); //dPSpecificCriteria(applicationTimer) + if((len = GetInteger(tagseq, (int *)&pevent->dPSpecificCriteria.applicationTimer, 0x80, &asnbuf)) > 0) + { + set_bit(pevent->optional_flag, 1); + } + } + } + while(++index < numOfBCSMEvents); + if((pcaparg->bcsmEvents_num = index) < 1) + return -1; + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++ */ +/*EventReportBCSM--------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eEventReportBCSM(struct CapEventReportBCSM caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + if((retval = AddInteger("16.0", caparg.eventTypeBCSM, 0x80, &asnbuf)) < 0) + return -1; + if(check_bit(caparg.optional_flag, 0)) //eventSpecificInformationBCSM + { + if((retval = encESIBCSM("16.2", caparg.eventSpecificInformationBCSM, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 1)) //legID + { + if((retval = AddTLV("16.3.1", 1, &caparg.legID, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 2)) //legID + { + if((retval = AddInteger("16.4.0", caparg.miscCallInfo.messageType, 0x80, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int dEventReportBCSM(char *msgbuf, int msglen, PCapEventReportBCSM pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if((len = GetInteger("16.0", (int *)&pcaparg->eventTypeBCSM, 0x80, &asnbuf)) < 0) + return -1; + if((len = decESIBCSM("16.2", &pcaparg->eventSpecificInformationBCSM, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 0); + //pcaparg->eventSpecificInformationBCSM_ch = sel; + } + if((len = GetTLV("16.3.1", 1, &pcaparg->legID, 0x80, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 1); + + if((len = GetInteger("16.4.0", (int *)&pcaparg->miscCallInfo.messageType, 0x80, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 2); + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++ */ +/*Apply Charging Report-------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eApplyChargingReport(CapApplyChargingReport caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int len = -1; + u_char callresult[256]; + + //CAMEL-CallResult-timeDurationCharging + AsnEncode(callresult, 256, &asnbuf); + if((len = AddTLV("0.0.1", 1, &caparg.partyToCharge, 0x80, &asnbuf)) < 0) + return -1; + switch (caparg.timeInformation_ch) + { + case 0: + if((len = AddInteger("0.1.0", caparg.timeInformation.timeIfNoTariffSwitch, 0x80, &asnbuf)) < 0) + return -1; + break; + case 1: + if((len = AddInteger("0.1.1.0", caparg.timeInformation.timeIfTariffSwitch.timeSinceTariffSwitch, 0x80, &asnbuf)) < 0) + return -1; + if((len = AddInteger("0.1.1.1", caparg.timeInformation.timeIfTariffSwitch.tariffSwitchInterval, 0x80, &asnbuf)) < 0) + return -1; + break; + } + if((len = AddTLV("0.2", 1, &caparg.callActive, 0x80, &asnbuf)) < 0) + return -1; + //ApplyChargingReportArg + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + if((len = AddTLV("4", len, callresult, 0, &asnbuf)) < 0) + return -1; + return len; +} + +int dApplyChargingReport(char *msgbuf, int msglen, PCapApplyChargingReport pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + u_short tagcode; + u_char callresult[256], temp[64]; + + //ApplyChargingReportArg + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if((len = GetTLV("4", 256, callresult, 0, &asnbuf)) < 0) + return -1; + //CAMEL-CallResult-timeDurationCharging + if(AsnDecode(callresult, len, 1, &errpos, &asnbuf) < 0) + { + return -1; + } + if((len = GetTLV("0.0.1", 1, &pcaparg->partyToCharge, 0x80, &asnbuf)) < 0) + return -1; + + if((len = GetAnyTLV("0.1.-1", 64, temp, NULL, &tagcode, &asnbuf)) < 0) + return -1; + + switch (tagcode) + { + case 0: + pcaparg->timeInformation_ch = 0; + if((len = GetInteger("0.1.0", (int *)&pcaparg->timeInformation.timeIfNoTariffSwitch, 0x80, &asnbuf)) < 0) + return -1; + break; + case 1: + pcaparg->timeInformation_ch = 1; + if((len = GetInteger("0.1.1.0", (int *)&pcaparg->timeInformation.timeIfTariffSwitch.timeSinceTariffSwitch, 0x80, &asnbuf)) < 0) + return -1; + if((len = GetInteger("0.1.1.1", (int *)&pcaparg->timeInformation.timeIfTariffSwitch.tariffSwitchInterval, 0x80, &asnbuf)) < 0) + return -1; + break; + } + if((len = GetTLV("0.2", 1, &pcaparg->callActive, 0x80, &asnbuf)) < 0) + { + pcaparg->callActive = 1; + // return -1; + } + return 1; +} + +int eReleaseCall(CapReleaseCall caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int reval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + reval = AddTLV("4", caparg.cause[0], caparg.cause + 1, 0, &asnbuf); + return reval; +} + +int dReleaseCall(char *msgbuf, int msglen, PCapReleaseCall pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + if(AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf) < 0) + { + return -1; + } + if((len = GetTLV("4", maxCauseLength, pcaparg->cause + 1, 0, &asnbuf)) > 0) + { + pcaparg->cause[0] = len; + return 1; + } + else + return -1; +} + +/*************************************/ +/*InitialDPSMS----------------------> */ + +/*************************************/ +int eInitialDPSMS(struct CapInitialDPSMS caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + retval = AddInteger("16.0", caparg.serviceKey, 0x80, &asnbuf); + //optional part + if(check_bit(caparg.optional_flag, 0)) + { + if((retval = AddTLV("16.1", caparg.destinationSubscriberNumber[0], caparg.destinationSubscriberNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 1)) + { + if((retval = AddTLV("16.2", caparg.callingPartyNumber[0], caparg.callingPartyNumber + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 2)) + { + if((retval = AddInteger("16.3", caparg.eventTypeSMS, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 3)) + { + if((retval = AddTLV("16.4", caparg.iMSI[0], caparg.iMSI + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 4)) + { + if((retval = encLocationInformation("16.5", caparg.locationInformation, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 5)) + { + if((retval = encLocationInformationGPRS("16.6", caparg.locationInformationGPRS, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 6)) + { + if((retval = AddTLV("16.7", caparg.sMSCAddress[0], caparg.sMSCAddress + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 7)) + { + if((retval = AddTLV("16.8", caparg.timeAndTimezone[0], caparg.timeAndTimezone + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 8)) + { + if((retval = AddTLV("16.9", 1, &caparg.tPShortMessageSubmissionInfo, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 9)) + { + if((retval = AddTLV("16.10", 1, &caparg.tPProtocolIdentifier, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 10)) + { + if((retval = AddTLV("16.11", 1, &caparg.tPDataCodingScheme + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 11)) + { + if((retval = AddTLV("16.12", caparg.tPValidityPeriod[0], caparg.tPValidityPeriod + 1, 0x80, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int dInitialDPSMS(char *msgbuf, int msglen, PCapInitialDPSMS pcaparg) +{ + ASN_BUF asnbuf; + int temp, len; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &temp, &asnbuf)) < 0) + return -1; + //serviceKey==============> + if(GetInteger("16.0", &pcaparg->serviceKey, 0x80, &asnbuf) < 0) + return -1; + //optional part + //destinationSubscriberNumber============> + if((len = GetTLV("16.1", maxCalledPartyBCDNumberLength, pcaparg->destinationSubscriberNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 0); + pcaparg->destinationSubscriberNumber[0] = len; + } + //calling party number============> + if((len = GetTLV("16.2", maxISDNAddressLength, pcaparg->callingPartyNumber + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 1); + pcaparg->callingPartyNumber[0] = len; + } + //eventTypeSMS============> + if((len = GetInteger("16.3", (int *)&pcaparg->eventTypeSMS, 0x80, &asnbuf)) > 0) + set_bit(pcaparg->optional_flag, 2); + //iMSI============> + if((len = GetTLV("16.4", maxIMSILength, pcaparg->iMSI + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 3); + pcaparg->iMSI[0] = len; + } + //locationInformation============> + if(decLocationInformation("16.5", &pcaparg->locationInformation, &asnbuf) >= 0) + set_bit(pcaparg->optional_flag, 4); + //locationInformationGPRS============> + if(decLocationInformationGPRS("16.6", &pcaparg->locationInformationGPRS, &asnbuf) >= 0) + set_bit(pcaparg->optional_flag, 5); + //sMSCAddress============> + if((len = GetTLV("16.7", maxISDNAddressLength, pcaparg->sMSCAddress + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 6); + pcaparg->sMSCAddress[0] = len; + } + //timeAndTimezone============> + if((len = GetTLV("16.8", maxTimeAndTimezoneLength, pcaparg->timeAndTimezone + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 7); + pcaparg->timeAndTimezone[0] = len; + } + //tPShortMessageSubmissionInfo============> + if((len = GetTLV("16.9", 1, &pcaparg->tPShortMessageSubmissionInfo, 0x80, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 8); + //tPProtocolIdentifier============> + if((len = GetTLV("16.10", 1, &pcaparg->tPProtocolIdentifier, 0x80, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 9); + //tPDataCodingScheme============> + if((len = GetTLV("16.11", 1, &pcaparg->tPDataCodingScheme, 0x80, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 10); + //tPDataCodingScheme============> + if((len = GetTLV("16.12", 7, pcaparg->tPValidityPeriod + 1, 0x80, &asnbuf)) >= 0) + { + set_bit(pcaparg->optional_flag, 11); + pcaparg->tPValidityPeriod[0] = len; + } + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++ */ +/*RequestReportSMSEvent--------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eRequestReportSMSEvent(struct CapRequestReportSMSEvent caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1, index = 0; + char tagseq[32]; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + for(index = 0; index < caparg.sMSEvents_num; index++) + { + sprintf(tagseq, "16.0.16-%d", index + 1); + add_null(tagseq, 0x20, &asnbuf); + sprintf(tagseq, "16.0.16-%d.0", index + 1); //eventTypeSMS + if((retval = AddInteger(tagseq, caparg.sMSEvents[index].eventTypeSMS, 0x80, &asnbuf)) < 0) + return -1; + sprintf(tagseq, "16.0.16-%d.1", index + 1); //monitorMode + if((retval = AddInteger(tagseq, caparg.sMSEvents[index].monitorMode, 0x80, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int dRequestReportSMSEvent(char *msgbuf, int msglen, PCapRequestReportSMSEvent pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len, index = 0; + char tagseq[32]; + CapSMSEvent *pevent; + + pcaparg->sMSEvents_num = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + return -1; + do + { + pevent = &pcaparg->sMSEvents[index]; + sprintf(tagseq, "16.0.16-%d.0", index + 1); //eventTypeSMS + if((len = GetInteger(tagseq, (int *)&pevent->eventTypeSMS, 0x80, &asnbuf)) < 0) + break; + sprintf(tagseq, "16.0.16-%d.1", index + 1); //monitorMode + if((len = GetInteger(tagseq, (int *)&pevent->monitorMode, 0x80, &asnbuf)) < 0) + break; + } + while(++index < numOfSMSEvents); + if((pcaparg->sMSEvents_num = index) < 1) + return -1; + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++ */ +/*EventReportSMS--------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eEventReportSMS(struct CapEventReportSMS caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + if((retval = AddInteger("16.0", caparg.eventTypeSMS, 0x80, &asnbuf)) < 0) + return -1; + if(check_bit(caparg.optional_flag, 0)) //eventSpecificInformationSMS + { + if((retval = encESISMS("16.1", caparg.eventSpecificInformationSMS, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 1)) //miscCallInfo + { + if((retval = AddInteger("16.2.0", caparg.miscCallInfo.messageType, 0x80, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int dEventReportSMS(char *msgbuf, int msglen, PCapEventReportSMS pcaparg) +{ + ASN_BUF asnbuf; + int errpos, sel, len; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + return -1; + if((len = GetInteger("16.0", (int *)&pcaparg->eventTypeSMS, 0x80, &asnbuf)) < 0) + return -1; + if((sel = decESISMS("16.1", &pcaparg->eventSpecificInformationSMS, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 0); + if((len = GetInteger("16.2.0", (int *)&pcaparg->miscCallInfo.messageType, 0x80, &asnbuf)) >= 0) + set_bit(pcaparg->optional_flag, 1); + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++ */ +/*ReleaseSMS-------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +int eReleaseSMS(CapReleaseSMS caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + return AddTLV("4", 1, &caparg.cause, 0, &asnbuf); +} + +int dReleaseSMS(char *msgbuf, int msglen, PCapReleaseSMS pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + if(AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf) < 0) + return -1; + if((len = GetTLV("4", 1, &pcaparg->cause, 0, &asnbuf)) > 0) + return 1; + else + return -1; +} + +int dVPSRequst(char *msgbuf, int msglen, CapVPSRequest * vpsreq) +{ + ASN_BUF asn_buf; + int errpos, len; + u8 temp_buf[1024]; + + if(AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asn_buf) < 0) + return -1; + len = get_tlv("16.0", temp_buf, &asn_buf); + if(len == maxVPSCallingLen) + memcpy(vpsreq->calling_num, temp_buf, maxVPSCallingLen); + else + return -1; + len = get_tlv("16.1", temp_buf, &asn_buf); + if(len == maxVPSCalledLen) + memcpy(vpsreq->called_num, temp_buf, maxVPSCalledLen); + else + return -1; + return 1; +} + +int eVPSPlayAnnounce(CapVPSPlayAnnounce * vps_ptr, char *msgbuf, int maxlen) +{ + int temp_len; + ASN_BUF asnbuf; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + temp_len = add_null("16", 0x20, &asnbuf); + temp_len = add_tlv("16.0", vps_ptr->info_len, vps_ptr->send_info, 0x80, &asnbuf); + return temp_len; +} + +#ifdef _SRF_RELEVANT +int eAssistRequestInstructions(struct CapAssistRequestInstructions caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + if((retval = AddTLV("16.0", caparg.correlationID[0], caparg.correlationID + 1, 0x80, &asnbuf)) < 0) + return -1; + if((retval = AddTLV("16.2", caparg.iPSSPCapabilities[0], caparg.iPSSPCapabilities + 1, 0x80, &asnbuf)) < 0) + return -1; + return retval; +} + +int dAssistRequestInstructions(char *msgbuf, int msglen, PCapAssistRequestInstructions pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if((len = GetTLV("16.0", maxDigitsLength, pcaparg->correlationID + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->correlationID[0] = len; + } + if((len = GetTLV("16.2", maxIPSSPCapabilitiesLength, pcaparg->iPSSPCapabilities + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->iPSSPCapabilities[0] = len; + } + return 1; +} + +int eEstablishTemporaryConnection(CapEstablishTemporaryConnection caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + if((retval = AddTLV("16.0", caparg.assistingSSPIPRoutingAddress[0], caparg.assistingSSPIPRoutingAddress + 1, 0x80, &asnbuf)) < 0) + return -1; + if(check_bit(caparg.optional_flag, 0)) + { + if((retval = AddTLV("16.1", caparg.correlationID[0], caparg.correlationID + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 1)) + { + if((retval = AddTLV("16.3", caparg.scfID[0], caparg.scfID + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 3)) + { + if((retval = encServiceInteractionIndicatorsTwo("16.7", caparg.serviceInteractionIndicatorsTwo, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int dEstablishTemporaryConnection(char *msgbuf, int msglen, PCapEstablishTemporaryConnection pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if((len = GetTLV("16.0", maxDigitsLength, pcaparg->assistingSSPIPRoutingAddress + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->assistingSSPIPRoutingAddress[0] = len; + } + if((len = GetTLV("16.1", maxDigitsLength, pcaparg->correlationID + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 0); + pcaparg->correlationID[0] = len; + } + if((len = GetTLV("16.3", maxScfIDLength, pcaparg->scfID + 1, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 1); + pcaparg->scfID[0] = len; + } + if(decServiceInteractionIndicatorsTwo("16.7", &pcaparg->serviceInteractionIndicatorsTwo, &asnbuf) >= 0) + { + set_bit(pcaparg->optional_flag, 3); + } + return 1; +} + +int eConnectToResource(CapConnectToResource caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + switch (caparg.resourceAddress.choice_id) + { + case 0: + if((retval = AddTLV("16.0", caparg.resourceAddress.ipRoutingAddress[0], caparg.resourceAddress.ipRoutingAddress + 1, 0x80, &asnbuf)) < 0) + return -1; + break; + case 1: + if((retval = add_bool("16.3", caparg.resourceAddress.none, 0x80, &asnbuf)) < 0) + return -1;; + break; + } + if(check_bit(caparg.optional_flag, 1)) + { + if((retval = encServiceInteractionIndicatorsTwo("16.7", caparg.serviceInteractionIndicatorsTwo, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int dConnectToResource(char *msgbuf, int msglen, PCapConnectToResource pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if((len = GetTLV("16.0", maxCalledPartyNumberLength, pcaparg->resourceAddress.ipRoutingAddress + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->resourceAddress.ipRoutingAddress[0] = len; + pcaparg->resourceAddress.choice_id = 0; + } + else if((len = GetTLV("16.3", 1, &pcaparg->resourceAddress.none, 0x80, &asnbuf)) > 0) + { + pcaparg->resourceAddress.choice_id = 1; + } + if(decServiceInteractionIndicatorsTwo("16.7", &pcaparg->serviceInteractionIndicatorsTwo, &asnbuf) >= 0) + { + set_bit(pcaparg->optional_flag, 1); + } + return 1; +} + +int eConnect(CapConnect caparg, char *msgbuf, int maxlen , u8 version) +{ + ASN_BUF asnbuf; + int retval = -1; + int index=0; + char tagseq[16]; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + sprintf(tagseq, "16.0.4"); + if((retval = AddTLV(tagseq, caparg.destinationRoutingAddress[0], + caparg.destinationRoutingAddress + 1, 0x00, &asnbuf)) < 0) + return -1; + + if( version >1 ) + { + if(check_bit(caparg.optional_flag, 0)) + { + sprintf(tagseq, "16.1"); + if((retval = AddTLV("16.1", 3, caparg.alertingPattern, 0x80, &asnbuf)) < 0) + return -1; + } + } + + if(check_bit(caparg.optional_flag, 1)) + { + sprintf(tagseq, "16.6.4"); + if((retval = AddTLV(tagseq, caparg.originalCalledPartyID[0], caparg.originalCalledPartyID + 1, 0x00, &asnbuf)) < 0) + return -1; + } + + if( version == 1 ) + { + if(check_bit(caparg.optional_flag, 6)) + { + for(index = 0; index < caparg.genericNumbers.num; index++) + { + sprintf(tagseq, "16.14"); + if((retval = AddTLV(tagseq, caparg.genericNumbers.genericNumber[index][0], caparg.genericNumbers.genericNumber[index] + 1, 0x80, &asnbuf)) < 0) + return -1; + } + } + + + if(check_bit(caparg.optional_flag, 9)) + { + sprintf(tagseq, "16.27.4"); + if((retval = AddTLV("16.27.4", caparg.callingpartynum.callingpartyNmuber_len, caparg.callingpartynum.callingPartyNumber, 0x80, &asnbuf)) < 0) + return -1; + } + } + + if(check_bit(caparg.optional_flag, 3)) + { + sprintf(tagseq, "16.28-%d",index+1); + if((retval = AddTLV("16.28", 1, &caparg.callingPartysCategory, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 4)) + { + sprintf(tagseq, "16.29-%d",index+1); + if((retval = AddTLV("16.29", caparg.redirectingPartyID[0], caparg.redirectingPartyID + 1, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 5)) + { + + sprintf(tagseq, "16.30-%d",index+1); + if((retval = AddTLV("16.30", caparg.redirectionInformation[0], caparg.redirectionInformation + 1, 0x80, &asnbuf)) < 0) + return -1; + } + + if( version >1 ) + { + + if(check_bit(caparg.optional_flag, 6)) + { + for(index = 0; index < caparg.genericNumbers.num; index++) + { + sprintf(tagseq, "16.14-%d", index + 1); + if((retval = AddTLV(tagseq, caparg.genericNumbers.genericNumber[index][0], caparg.genericNumbers.genericNumber[index] + 1, 0x80, &asnbuf)) < 0) + return -1; + } + } + } + + if(check_bit(caparg.optional_flag, 7)) + { + sprintf(tagseq, "16.55-%d",index+1); + if((retval = AddTLV("16.55", 1, &caparg.suppressionOfAnnouncement, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 8)) + { + sprintf(tagseq, "16.56-%d",index+1); + if((retval = AddTLV("16.56", 1, &caparg.oCSIApplicable, 0x80, &asnbuf)) < 0) + return -1; + } + + return retval; +} + +int dConnect(char *msgbuf, int msglen, PCapConnect pcaparg , u8 version) +{ + ASN_BUF asnbuf; + int errpos, len; + char tagseq[16]; + int index; + u8 temp_buf[256]; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + + if((len = GetTLV("16.0.4", maxCalledPartyNumberLength, pcaparg->destinationRoutingAddress + 1, 0x00, &asnbuf)) > 0) + { + pcaparg->destinationRoutingAddress[0] = len; + } + if((len = GetTLV("16.1", 3, pcaparg->alertingPattern, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 0); + } + if((len = GetTLV("16.6.4", maxOriginalCalledPartyIDLength, pcaparg->originalCalledPartyID + 1, 0x00, &asnbuf)) > 0) + { + pcaparg->originalCalledPartyID[0] = len; + set_bit(pcaparg->optional_flag, 1); + } + + + pcaparg->genericNumbers.num = 0; + for(index = 0; index < numOfGenericNumbers; index++) //refer to decVariablePart(to be modified) + { + sprintf(tagseq, "16.14-%d", index + 1); + if((len = GetTLV(tagseq, maxGenericNumberLength, pcaparg->genericNumbers.genericNumber[index] + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->genericNumbers.genericNumber[index][0] = len; + pcaparg->genericNumbers.num++; + } + else + { + if(pcaparg->genericNumbers.num > 0) + { + set_bit(pcaparg->optional_flag, 6); + } + break; + } + } + + if((len = GetTLV("16.28", 1, &pcaparg->callingPartysCategory, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 3); + } + if((len = GetTLV("16.29", maxRedirectingPartyIDLength, pcaparg->redirectingPartyID + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->redirectingPartyID[0] = len; + set_bit(pcaparg->optional_flag, 4); + } + if((len = GetTLV("16.30", 2, pcaparg->redirectionInformation + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->redirectionInformation[0] = len; + set_bit(pcaparg->optional_flag, 5); + } + + if((len = GetTLV("16,55", 1, &pcaparg->suppressionOfAnnouncement, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 7); + } + if((len = GetTLV("16.56", 1, &pcaparg->oCSIApplicable, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 8); + } + + if((len = get_tlv("16.27.4", temp_buf, &asnbuf)) != -1) + { + pcaparg->callingpartynum.callingpartyNmuber_len = len; + memcpy(pcaparg->callingpartynum.callingPartyNumber, temp_buf, len); + set_bit(pcaparg->optional_flag, 9); + } + return 1; +} + +int ePlayAnnouncement(CapPlayAnnouncement caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + if((retval = encInformationToSend("16.0", caparg.informationToSend, &asnbuf)) < 0) + return -1; + if(check_bit(caparg.optional_flag, 0)) + { + if((retval = AddTLV("16.1", 1, &caparg.disconnectFromIPForbidden, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 1)) + { + if((retval = AddTLV("16.2", 1, &caparg.requestAnnouncementComplete, 0x80, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int dPlayAnnouncement(char *msgbuf, int msglen, PCapPlayAnnouncement pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + pcaparg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if(decInformationToSend("16.0", &pcaparg->informationToSend, &asnbuf) < 0) + return -1; + if((len = GetTLV("16.1", 1, &pcaparg->disconnectFromIPForbidden, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 0); + } + if((len = GetTLV("16.2", 1, &pcaparg->requestAnnouncementComplete, 0x80, &asnbuf)) > 0) + { + set_bit(pcaparg->optional_flag, 1); + } + return 1; +} + +int ePromptAndCollectUserInformation(u8 otype, CapPromptAndCollectUserInformation caparg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + add_null("16", 0x20, &asnbuf); + + if(otype == CAP_REQUEST) //invoke + { + if((retval = encCollectedInfo("16.0", caparg.collectedInfo, &asnbuf)) < 0) + return -1; + if(check_bit(caparg.optional_flag, 0)) + { + if((retval = AddTLV("16.1", 1, &caparg.disconnectFromIPForbidden, 0x80, &asnbuf)) < 0) + return -1; + } + if(check_bit(caparg.optional_flag, 1)) + { + if((retval = encInformationToSend("16.2", caparg.informationToSend, &asnbuf)) < 0) + return -1; + } + } + else if(otype == CAP_RESPONSE) //return result + { + if(caparg.choice_id == 0) + { + if((retval = AddTLV("16.0", caparg.digitsResponse[0], caparg.digitsResponse + 1, 0x80, &asnbuf)) < 0) + return -1; + } + } + return retval; +} + +int dPromptAndCollectUserInformation(u8 otype, char *msgbuf, int msglen, PCapPromptAndCollectUserInformation pcaparg) +{ + ASN_BUF asnbuf; + int errpos, len; + + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + return -1; + } + if(otype == CAP_INDICATE) + { + pcaparg->optional_flag = 0; + if(decCollectedInfo("16.0", &pcaparg->collectedInfo, &asnbuf) < 0) + return -1; + if(GetTLV("16.1", 1, &pcaparg->disconnectFromIPForbidden, 0x80, &asnbuf) >= 0) + { + set_bit(pcaparg->optional_flag, 0); + } + if(decInformationToSend("16.2", &pcaparg->informationToSend, &asnbuf) >= 0) + { + set_bit(pcaparg->optional_flag, 1); + } + } + else if(otype == CAP_CONFIRM) + { + if((len = GetTLV("16.0", maxDigitsLength, pcaparg->digitsResponse + 1, 0x80, &asnbuf)) > 0) + { + pcaparg->digitsResponse[0] = len; + pcaparg->choice_id = 0; + } + else + { + return -1; + } + } + return 1; +} +#endif + +int encode_capmsg(struct CapArg caparg, u8 * msgbuf, u16 maxlen) +{ //return the length of byte flow, if failed return -1 + int retval = -1; + +#ifdef _SRF_RELEVANT + u8 otype; +#endif + + switch (caparg.ocode) + { + case CAP_OC_ActivityTest: + retval = 0; + break; + case CAP_OC_Cancel: + retval = eCancel(caparg.msg_list.cancelArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_Continue: + retval = 0; + break; + case CAP_OC_EventReportBCSM: + retval = eEventReportBCSM(caparg.msg_list.eventReportBCSMArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_InitialDP: + retval = eInitialDP(caparg.msg_list.initialDPArg, (char *)msgbuf, maxlen,caparg.version+1); + break; + case CAP_OC_ApplyCharging: + retval = eApplyCharging(caparg.msg_list.applyChargingArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_ApplyChargingReport: + retval = eApplyChargingReport(caparg.msg_list.applyChargingReportArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_RequestReportBCSMEvent: + retval = eRequestReportBCSMEvent(caparg.msg_list.requestReportBCSMEventArg, (char *)msgbuf, maxlen, caparg.version+1); + break; + case CAP_OC_ReleaseCall: + retval = eReleaseCall(caparg.msg_list.releaseCallArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_ContinueSMS: + retval = 0; + break; + case CAP_OC_EventReportSMS: + retval = eEventReportSMS(caparg.msg_list.eventReportSMSArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_InitialDPSMS: + retval = eInitialDPSMS(caparg.msg_list.initialDPSMSArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_RequestReportSMSEvent: + retval = eRequestReportSMSEvent(caparg.msg_list.requestReportSMSEventArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_ReleaseSMS: + retval = eReleaseSMS(caparg.msg_list.releaseSMSArg, (char *)msgbuf, maxlen); + break; + case 0xb1: + retval = eVPSPlayAnnounce(&caparg.msg_list.vpsPlayAnnounce, (char *)msgbuf, maxlen); + break; +#ifdef _SRF_RELEVANT + case CAP_OC_AssistRequestInstructions: + retval = eAssistRequestInstructions(caparg.msg_list.assistRequestInstructionsArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_EstablishTemporaryConnection: + retval = eEstablishTemporaryConnection(caparg.msg_list.establishTemporaryConnectionArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_DisconnectForwardConnection: + retval = 0; + break; + case CAP_OC_ConnectToResource: + retval = eConnectToResource(caparg.msg_list.connectToResourceArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_Connect: + retval = eConnect(caparg.msg_list.connectArg, (char *)msgbuf, maxlen, caparg.version+1); + break; + case CAP_OC_PlayAnnouncement: + retval = ePlayAnnouncement(caparg.msg_list.playAnnouncementArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_PromptAndCollectUserInformation: + otype = caparg.message_flag; + retval = ePromptAndCollectUserInformation(otype, caparg.msg_list.promptAndCollectUserInformationArg, (char *)msgbuf, maxlen); + break; + case CAP_OC_SpecializedResourceReport: + retval = 0; + break; +#endif + default: + break; + } + return retval; +} + +#ifdef _SRF_RELEVANT +int decode_capmsg(char *msgbuf, u16 msglen, u8 ocode, u8 otype, struct CapArg *pcaparg) +#else +int decode_capmsg(char *msgbuf, u16 msglen, u8 ocode, struct CapArg *pcaparg) +#endif +{ + int retval = 0; + + switch (ocode) + { + case CAP_OC_ActivityTest: + break; + case CAP_OC_Cancel: + retval = dCancel(msgbuf, msglen, &pcaparg->msg_list.cancelArg); + break; + case CAP_OC_Continue: + break; + case CAP_OC_EventReportBCSM: + retval = dEventReportBCSM(msgbuf, msglen, &pcaparg->msg_list.eventReportBCSMArg); + break; + case CAP_OC_InitialDP: + retval = dInitialDP(msgbuf, msglen, &pcaparg->msg_list.initialDPArg,pcaparg->version+1); + break; + case CAP_OC_ApplyCharging: + retval = dApplyCharging(msgbuf, msglen, &pcaparg->msg_list.applyChargingArg); + break; + case CAP_OC_ApplyChargingReport: + retval = dApplyChargingReport(msgbuf, msglen, &pcaparg->msg_list.applyChargingReportArg); + break; + case CAP_OC_RequestReportBCSMEvent: + retval = dRequestReportBCSMEvent(msgbuf, msglen, &pcaparg->msg_list.requestReportBCSMEventArg, pcaparg->version+1); + break; + case CAP_OC_ReleaseCall: + retval = dReleaseCall(msgbuf, msglen, &pcaparg->msg_list.releaseCallArg); + break; + case CAP_OC_ContinueSMS: + break; + case CAP_OC_EventReportSMS: + retval = dEventReportSMS(msgbuf, msglen, &pcaparg->msg_list.eventReportSMSArg); + break; + case CAP_OC_InitialDPSMS: + retval = dInitialDPSMS(msgbuf, msglen, &pcaparg->msg_list.initialDPSMSArg); + break; + case CAP_OC_RequestReportSMSEvent: + retval = dRequestReportSMSEvent(msgbuf, msglen, &pcaparg->msg_list.requestReportSMSEventArg); + break; + case CAP_OC_ReleaseSMS: + retval = dReleaseSMS(msgbuf, msglen, &pcaparg->msg_list.releaseSMSArg); + break; + case 0xb0: + retval = dVPSRequst(msgbuf, msglen, &pcaparg->msg_list.vpsRequest); + break; +#ifdef _SRF_RELEVANT + case CAP_OC_AssistRequestInstructions: + retval = dAssistRequestInstructions(msgbuf, msglen, &pcaparg->msg_list.assistRequestInstructionsArg); + break; + case CAP_OC_EstablishTemporaryConnection: + retval = dEstablishTemporaryConnection(msgbuf, msglen, &pcaparg->msg_list.establishTemporaryConnectionArg); + break; + case CAP_OC_DisconnectForwardConnection: + break; + case CAP_OC_ConnectToResource: + retval = dConnectToResource(msgbuf, msglen, &pcaparg->msg_list.connectToResourceArg); + break; + case CAP_OC_Connect: + retval = dConnect(msgbuf, msglen, &pcaparg->msg_list.connectArg,pcaparg->version+1); + break; + case CAP_OC_PlayAnnouncement: + retval = dPlayAnnouncement(msgbuf, msglen, &pcaparg->msg_list.playAnnouncementArg); + break; + case CAP_OC_PromptAndCollectUserInformation: + retval = dPromptAndCollectUserInformation(otype, msgbuf, msglen, &pcaparg->msg_list.promptAndCollectUserInformationArg); + break; + case CAP_OC_SpecializedResourceReport: + break; +#endif + default: + break; + } + pcaparg->ocode = ocode; + return retval; +} diff --git a/plat/xapp/src/capp/cap_msg.h b/plat/xapp/src/capp/cap_msg.h new file mode 100644 index 0000000..ec0c44e --- /dev/null +++ b/plat/xapp/src/capp/cap_msg.h @@ -0,0 +1,876 @@ + +/************************************************/ +/*Title: smsmsg.h */ +/*Descr: CAP-DataTypes(ETSI TS 101046 6.3) */ +/*Author: Liang Hanxi */ +/*Create: 2002-9-11 */ +/*Modify: */ + +/************************************************/ + +#ifndef _CAP_MESSAGE +#define _CAP_MESSAGE + +#ifndef _SRF_RELEVANT +#define _SRF_RELEVANT +#endif + +#define check_bit(flag,pos) ((flag & (1< */ + +/*************************************/ +typedef enum CapEventTypeBCSM +{ + capp_collectedInfo = 2, + capp_routeSelectFailure = 4, + capp_oBusy = 5, + capp_oCalledPartyBusy = 5, + capp_oNoAnswer = 6, + capp_oAnswer = 7, + capp_oDisconnect = 9, + capp_oAbandon = 10, + capp_termAttemptAuthorized = 12, + capp_tBusy = 13, + capp_tNoAnswer = 14, + capp_tAnswer = 15, + capp_tDisconnect = 17, + capp_tAbandon = 18, + //self define==> + Int_Rel = 24, + capp_activetest = 25, + Int_TCE = 26, + Int_ETC_Failed = 27, + Int_TC_Released = 28, + Int_SRFConnected = 29, + Int_CTR_Failed = 30, + Int_SRFReleased = 31 +} +CapEventTypeBCSM; + +typedef enum CapNotReachableReason +{ + capp_msPurged = 0, + capp_imsiDetached = 1, + capp_restrictedArea = 2, + capp_notRegistered = 3 +} +CapNotReachableReason; + +typedef enum CapCriticalityType +{ + capp_ignore = 0, + capp_abort = 1 +} +CapCriticalityType; + +typedef union CapBearerCapability +{ //CAP-DataTypes + u8 bearerCap[maxBearerCapabilityLength + 1]; +} +CapBearerCapability; + +typedef struct CapExtensionField +{ //CAP-DataTypes + u32 type; + CapCriticalityType criticality; + u8 *value; +} +CapExtensionField; + +typedef union CapSubscriberState +{ //MAP-MS-DataTypes + u8 assumedIdle; + u8 camelBusy; + CapNotReachableReason netDetNotReachable; + u8 notProvidedFromVLR; +} +CapSubscriberState; + +typedef union CapCellIdOrLAI +{ //MAP-CH-DataTypes + u8 cellIdFixedLength[7 + 1]; + u8 laiFixedLength[5 + 1]; +} +CapCellIdOrLAI; + +typedef struct CapLocationInformation +{ //MAP-MS-DataTypes + u32 optional_flag; + int ageOfLocationInformation; + u8 geographicalInformation[8 + 1]; + u8 vlr_number[maxISDNAddressLength + 1]; + u8 locationNumber[maxLocationNumberLength + 1]; + u8 cellIdOrLAI_ch; + CapCellIdOrLAI cellIdOrLAI; +} +CapLocationInformation; + +typedef union CapExt_BasicServiceCode +{ //MAP-CommonDataTypes + u8 ext_BearerService[5 + 1]; + u8 ext_Teleservice[5 + 1]; +} +CapExt_BasicServiceCode; + +typedef struct CapNACarrierInformation +{ //CAP-DataTypes + u8 naCarrierId[3 + 1]; + u8 naCICSelectionType; +} +CapNACarrierInformation; + +typedef struct CapInitialDPArgExtension +{ + u32 optional_flag; + CapNACarrierInformation naCarrierInformation; + u8 gmscAddress[9 + 1]; +} +CapInitialDPArgExtension; + +typedef struct CapInitialDP //V1 GSM 09.78 18 TS 101 046 V5.0.1 Page 19 //GSM 09.78 version 7.1.0 (2000-07) Page 37 +{ + int serviceKey; /*tag 0 */ + u32 optional_flag; + u8 calledPartyNumber[maxCalledPartyNumberLength + 1]; /*Version 1 0[0x01],2 *//*Version 2 *//*0 */ + u8 callingPartyNumber[maxCallingPartyNumberLength + 1]; /*Version 1 1[0x02],3 *//*Version 2 *//*1 */ + u8 callingPartysCategory; /*Version 1 2[0x04],5 *//*Version 2 *//*2 */ + u8 iPSSPCapabilities[maxIPSSPCapabilitiesLength + 1]; /*Version 2 *//*3 */ + u8 locationNumber[maxLocationNumberLength + 1]; /*Version 1 3[0x08],10 *//*Version 2 *//*4 */ + u8 originalCalledPartyID[maxOriginalCalledPartyIDLength + 1]; /*Version 1 4[0x10],12 *//*Version 2 *//*5 */ + // CapExtensionField extensions[numOfExtensions]; /*Version 1 5[0x20],15*/ /*Version 2*//*6*/ + u8 highLayerCompatibility[2 + 1]; /*Version 1 6[0x40],23 *//*Version 2 *//*7 */ + u8 additionalCallingPartyNumber[maxDigitsLength + 1]; /*Version 1 7[0x80],25 *//*Version 2 *//*8 */ + CapBearerCapability bearerCapability; /*Version 1 8[0x100],27 *//*Version 2 *//*9 */ + CapEventTypeBCSM eventTypeBCSM; /*Version 1 9[0x200],28 *//*Version 2 *//*10 */ + u8 redirectingPartyID[maxRedirectingPartyIDLength + 1]; /*Version 1 10[0x400],29 *//*Version 2 *//*11 */ + u8 redirectionInformation[2 + 1]; /*Version 1 11[0x800],30 *//*Version 2 *//*12 */ + u8 iMSI[maxIMSILength + 1]; /*Version 1 12[0x1000],50 *//*Version 2 *//*13 */ + u8 subscriberState_ch; + CapSubscriberState subscriberState; /*Version 1 13[0x2000],51 *//*Version 2 *//*14 */ + CapLocationInformation locationInformation; /*Version 1 14[0x4000],52 *//*Version 2 *//*15 */ + u8 ext_basicServiceCode_ch; + CapExt_BasicServiceCode ext_basicServiceCode; /*Version 1 15[0x8000],53 *//*Version 2 *//*16 */ + u8 callReferenceNumber[maxcallReferenceNumberLength + 1]; /*Version 1 16[0x10000],54 *//*Version 2 *//*17 */ + + u8 mscAddress[maxISDNAddressLength + 1]; /*Version 2 *//*18 */ + u8 calledPartyBCDNumber[maxCalledPartyBCDNumberLength + 1]; /*Version 2 *//*19 */ + u8 timeAndTimezone[maxTimeAndTimezoneLength + 1]; /*Version 2 *//*20 */ + u8 gsm_ForwardingPending; /*Version 2 *//*21 */ + CapInitialDPArgExtension initialDPArgExtension; /*Version 2 *//*22 */ +} +CapInitialDP, *PCapInitialDP; + +/*++++++++++++++++++++++++++ */ +/*Cancel--------------> */ +/*++++++++++++++++++++++++++ */ +typedef struct CapCancel +{ + u8 ch; //ch=0:invokeID;ch=1:allRequest + u8 invokeID; //ch=0 + u8 allRequest; //ch=1 +} +CapCancel, *PCapCancel; + +/*++++++++++++++++++++++++++++++++++++++ */ +/*ApplyCharging--------------> */ +/*++++++++++++++++++++++++++++++++++++++ */ +typedef struct CapReleaseIfDurationExceeded +{ + u8 tone; +} +CapReleaseIfDurationExceeded; + +typedef struct CapACBCC +{ //aChbillingChargingCharacteristics + int maxCallPeriodDuration; + u32 optional_flag; + CapReleaseIfDurationExceeded releaseIfdurationExceeded; /*0 */ + int tariffSwitchInterval; /*1 */ +} +CapACBCC; + +typedef struct CapApplyCharging +{ + u8 partyToCharge; + CapACBCC ACBCC; +} +CapApplyCharging, *PCapApplyCharging; + +/*************************************/ +/*Apply Charging Report-------------> */ + +/*************************************/ +typedef struct CapTimeIfTariffSwitch +{ + int timeSinceTariffSwitch; + int tariffSwitchInterval; +} +CapTimeIfTariffSwitch; + +typedef union CAP_TimeInformation +{ + int timeIfNoTariffSwitch; + CapTimeIfTariffSwitch timeIfTariffSwitch; +} +CapTimeInformation; + +typedef struct CAMEL_CallResult +{ + u8 partyToCharge; + u8 timeInformation_ch; + CapTimeInformation timeInformation; + u8 callActive; +} +CAMEL_CallResult; + +typedef CAMEL_CallResult CapApplyChargingReport; +typedef CAMEL_CallResult *PCapApplyChargingReport; + +/*************************************/ +/*Request Report BCSM Event---------> */ + +/*************************************/ +typedef enum CapMonitorMode +{ + capp_interrupted = 0, + capp_notifyAndContinue = 1, + capp_transparent = 2 +} +CapMonitorMode; + +typedef union CapLegID +{ + u8 sendingSideID; + u8 receivingSideID; +} +CapLegID; + +typedef union CapDPSpecificCriteria +{ + int applicationTimer; +} +CapDPSpecificCriteria; + +typedef struct CapBCSMEvent +{ + CapEventTypeBCSM eventTypeBCSM; + CapMonitorMode monitorMode; + u32 optional_flag; + u8 legID_ch; + CapLegID legID; + CapDPSpecificCriteria dPSpecificCriteria; +} +CapBCSMEvent; + +typedef struct CapRequestReportBCSMEvent +{ + u8 bcsmEvents_num; + CapBCSMEvent bcsmEvents[numOfBCSMEvents]; + // ExtensionField extensions[numOfExtensions]; +} +CapRequestReportBCSMEvent, *PCapRequestReportBCSMEvent; + +/*************************************/ +/*Event Report BCSM-----------------> */ + +/*************************************/ +typedef struct CapESIBCSM +{ //EventSpecificInformationBCSM + u8 infotype; + //2:route select failure + //3:oCalledPartyBusy + //4:oNoAnswer + //5:oAnswer + //7:oDisconnect + //8:tBusy + //9:tNoAnswer + //10:tAnswer + //12:tDisconnect + u8 cause[maxCauseLength + 1]; + //cause[0] as length,if no cause is provided,cause[0]=0,or cause[0]=maxCauseLength(2) + u8 callForwarded; + //Boolean value(1/0) +} +CapESIBCSM; + +typedef union CapMiscCallInfo +{ + enum + { + capp_request = 0, + capp_notification = 1 + } + messageType; +} +CapMiscCallInfo; + +typedef struct CapEventReportBCSM +{ + CapEventTypeBCSM eventTypeBCSM; + u_int optional_flag; + u8 legID; /*0 */ + CapESIBCSM eventSpecificInformationBCSM; /*1 */ + CapMiscCallInfo miscCallInfo; /*2 */ +} +CapEventReportBCSM, *PCapEventReportBCSM; + +/*************************************/ +/*Furnish Charging Information------> */ + +/*************************************/ +//FCIBCC<==>FCIBillingChargingCharacteristics +typedef struct CAP_CAMEL_FCIBCC +{ + u8 freeFormatData[maxFCIBillingChargingDataLength]; + u8 partyToCharge; +} +CAMEL_FCIBCC; + +//CAMEL_FCIBCC FurnishChargingInformationArg; + +/*************************************/ +/*ReleaseCall-----------------------> */ + +/*************************************/ +typedef struct CapReleaseCall +{ + u8 cause[maxCauseLength + 1]; +} +CapReleaseCall, *PCapReleaseCall; + +/*************************************/ +/*InitialDPSMS----------------------> */ + +/*************************************/ +typedef enum CapEventTypeSMS +{ + capp_smsCollectedInfo = 1, + capp_osmsFailure = 2, + capp_osmsSubmitted = 3, +} +CapEventTypeSMS; + +typedef struct CapLocationInformationGPRS +{ //MAP-MS-DataTypes + u32 optional_flag; + u8 cellGlobalIdOrServiceAreaIdOrLAI[7 + 1]; + u8 routeingAreaIdentity[7 + 1]; + u8 geographicalInformation[8 + 1]; + u8 sgsn_Number[maxISDNAddressLength + 1]; + u8 selectedLSAIdentity[3 + 1]; + u8 sai_Present; +} +CapLocationInformationGPRS; + +typedef struct CapInitialDPSMS +{ + int serviceKey; + u32 optional_flag; + u8 destinationSubscriberNumber[maxCalledPartyBCDNumberLength + 1]; /*0 */ + u8 callingPartyNumber[maxISDNAddressLength + 1]; /*1 */ + CapEventTypeSMS eventTypeSMS; /*2 */ + u8 iMSI[maxIMSILength + 1]; /*3 */ + CapLocationInformation locationInformation; /*4 */ + CapLocationInformationGPRS locationInformationGPRS; /*5 */ + u8 sMSCAddress[maxISDNAddressLength + 1]; /*6 */ + u8 timeAndTimezone[maxTimeAndTimezoneLength + 1]; /*7 */ + u8 tPShortMessageSubmissionInfo; /*8 */ + u8 tPProtocolIdentifier; /*9 */ + u8 tPDataCodingScheme; /*10 */ + u8 tPValidityPeriod[7 + 1]; /*11 */ +} +CapInitialDPSMS, *PCapInitialDPSMS; + +/*************************************/ +/*Request Report SMS Event---------> */ + +/*************************************/ +typedef struct CapSMSEvent +{ + CapEventTypeSMS eventTypeSMS; + CapMonitorMode monitorMode; +} +CapSMSEvent; + +typedef struct CapRequestReportSMSEvent +{ + u8 sMSEvents_num; + CapSMSEvent sMSEvents[numOfSMSEvents]; +} +CapRequestReportSMSEvent, *PCapRequestReportSMSEvent; + +/*************************************/ +/*Event Report SMS------------------> */ + +/*************************************/ +typedef enum CapSMSCause +{ + capp_systemFailure = 0, + capp_unexpectedDataValue = 1, + capp_facilityNotSupported = 2, + capp_sMDeliveryFailure = 3, + releaseFromRadioInterface = 4, +} +CapSMSCause; + +typedef struct CapESISMS +{ //EventSpecificInformationSMS + u8 infotype; //0:o-smsFailureSpecificInfo 1:o-smsSubmittedSpecificInfo + u8 cause_flag; + CapSMSCause cause; +} +CapESISMS; + +typedef struct CapEventReportSMS +{ + CapEventTypeSMS eventTypeSMS; + u32 optional_flag; + CapESISMS eventSpecificInformationSMS; /*0 */ + CapMiscCallInfo miscCallInfo; /*1 */ +} +CapEventReportSMS, *PCapEventReportSMS; + +/*************************************/ +/*ReleaseSMS------------------------> */ + +/*************************************/ +typedef struct CapReleaseSMS +{ + u8 cause; +} +CapReleaseSMS, *PCapReleaseSMS; + +/*************************************/ +/*ResetTimerSMS------> */ + +/*************************************/ +typedef enum CapTimerID +{ + Cap_Tssf = 0, +} +CapTimerID; + +typedef struct CapResetTimerSMS +{ + CapTimerID timerID; + u_int timerValue; +} +CapResetTimerSMS; + +typedef struct CapVPSRequest +{ + u8 calling_num[maxVPSCallingLen]; + u8 called_num[maxVPSCalledLen]; +} +CapVPSRequest; + +typedef struct CapVPSPlayAnnounce +{ + u8 info_len; + u8 send_info[maxVPSInfoLen]; +} +CapVPSPlayAnnounce; + +/******************************************/ + +/************** SRF Relevant **************/ + +/******************************************/ +#ifdef _SRF_RELEVANT + +/************************/ + +/** Common Data Type **/ + +/************************/ +#if 0 +typedef struct CapNACarrierInformation +{ + u32 optional_flag; + u8 naCarrierId[3]; /*0 */ + u8 naCICSelectionType; /*1 */ +} +CapNACarrierInformation; + +typedef struct CapNA_Info +{ + u32 optional_flag; + CapNACarrierInformation naCarrierInformation; /*0 */ + u8 naOliInfo; /*1 */ + u8 naChargeNumber[7 + 1]; /*2 */ +} +CapNA_Info; + +typedef struct CapResourceAddress +{ + u8 choice_id; + u8 ipRoutingAddress[maxCalledPartyNumberLength + 1]; /*0,0 */ + u8 none; /*1,3 */ +} +CapResourceAddress; +#endif + +typedef struct CapServiceInteractionIndicatorsTwo +{ + u32 optional_flag; + u8 bothwayThroughConnectionInd; /*0,2 */ +} +CapServiceInteractionIndicatorsTwo; + +typedef struct CapVariablePart +{ + u32 choice_id; + u32 integer; /*0,0 */ + u8 number[maxDigitsLength + 1]; /*1,1 */ + u8 time[2]; /*2,2 */ + u8 date[4]; /*3,3 */ + u8 price[4]; /*4,4 */ + u8 signSymbol; /*5,,5*/ +} +CapVariablePart; + +#define MAX_VAR_NUMS 10 + +typedef struct CapMessageID +{ + u8 choice_id; + u32 elementaryMessageID; /*0,0 */ + // text /*1,1*/ + struct CapElementaryMessageIDs + { + u8 num; + u32 elementaryMessageID[numOfMessageIDs]; + } + elementaryMessageIDs; /*2,29 */ + struct CapVariableMessage + { + + u32 elementaryMessageID; /*-,0*/ + struct CapVariableParts + { + u8 num; + CapVariablePart variablePart[MAX_VAR_NUMS]; + } + + variableParts; /*-,1*/ + } + variableMessage; /*3,30 */ +} +CapMessageID; + +typedef struct CapInbandInfo +{ + + CapMessageID messageID; /*-,0*/ + u32 optional_flag; + int numberOfRepetitions; /*0,1 */ + int duration; /*1,2 */ + int interval; /*2,3 */ +} +CapInbandInfo; + +typedef struct CapTone +{ + + u32 toneID; /*-,0*/ + u32 optional_flag; + u32 duration; /*0,1 */ +} +CapTone; + +typedef struct CapInformationToSend +{ + u8 choice_id; + CapInbandInfo inbandInfo; /*0,0 */ + CapTone tone; /*1,1 */ +} +CapInformationToSend; + +typedef enum CapErrorTreatment +{ + stdErrorAndInfo = 0, + help = 1, + repeatPrompt = 2, +} +CapErrorTreatment; + +typedef struct CapCollectedDigits +{ + + u8 minimumNbOfDigits; /*-,0*/ + + u8 maximumNbOfDigits; /*-,1*/ + u32 optional_flag; + u8 endOfReplyDigit[2 + 1]; /*0,2 */ + u8 cancelDigit[2 + 1]; /*1,3 */ + u8 startDigit[2 + 1]; /*2,4 */ + u8 firstDigitTimeOut; /*3,5 */ + u8 interDigitTimeOut; /*4,6 */ + CapErrorTreatment errorTreatment; /*5,7 */ + u8 interruptableAnnInd; /*6,8 */ + u8 voiceInformation; /*7,9 */ + u8 voiceBack; /*8,10 */ +} +CapCollectedDigits; + +typedef struct CapCollectedInfo +{ + u8 choice_id; + CapCollectedDigits collectedDigits; /*0,0 */ +} +CapCollectedInfo; + +/************************/ + +/** Argument Data Type **/ + +/************************/ +typedef struct CapAssistRequestInstructions +{ + + u8 correlationID[maxDigitsLength + 1]; /*-,0*/ + + u8 iPSSPCapabilities[maxIPSSPCapabilitiesLength + 1]; /*-,2*/ +} +CapAssistRequestInstructions, *PCapAssistRequestInstructions; + +typedef struct CapConnect +{ + u8 destinationRoutingAddress[maxCalledPartyNumberLength + 1]; /*-,0*/ + u32 optional_flag; + u8 alertingPattern[3]; /*Versinon2 0[0x01],1 */ + u8 originalCalledPartyID[maxOriginalCalledPartyIDLength + 1]; /*Versinon 1 0[0x01],6 *//*Versinon2 1[0x02],6 */ + // CapExtensionField extensions[numOfExtensions]; /*Versinon 1 1[0x02],10*/ /*Versinon2 2[0x04],10*/ + u8 callingPartysCategory; /*Versinon 1 4[0x10],28 *//*Versinon2 3[0x08],28 */ + u8 redirectingPartyID[maxRedirectingPartyIDLength + 1]; /*Versinon 1 5[0x20],29 *//*Versinon2 4[0x10],29 */ + u8 redirectionInformation[2 + 1]; /*Versinon 1 6[0x40],30 *//*Versinon2 5[0x20],30 */ + struct + { + u8 num; + u8 genericNumber[numOfGenericNumbers][maxGenericNumberLength + 1]; + } + genericNumbers; /*Versinon2 6[0x40],14 */ + u8 suppressionOfAnnouncement; /*Versinon 1 7[0x80],55 *//*Versinon2 7[0x80],14 */ + u8 oCSIApplicable; /*Versinon 1 8[0x100],56 *//*Versinon2 8[0x100],14 */ + //CapNA_Info na_Info; + struct + { + u8 callingpartyNmuber_len; + u8 callingPartyNumber[maxCallingPartyNumberLength]; /*Versinon 1 3[0x08],27 */ + } + callingpartynum; /*Versinon2 9[0x200],57*/ +}CapConnect, *PCapConnect; + +typedef struct CapConnectToResource +{ + // CapResourceAddress resourceAddress; + struct + { + u8 choice_id; + u8 ipRoutingAddress[maxCalledPartyNumberLength + 1]; /*0,0 */ + u8 none; /*1,3 */ + } + resourceAddress; + u32 optional_flag; + // CapExtensionField extensions[numOfExtensions]; /*0,4*/ + CapServiceInteractionIndicatorsTwo serviceInteractionIndicatorsTwo; /*1,7 */ +} +CapConnectToResource, *PCapConnectToResource; + +typedef struct CapDisconnectForwardConnection +{ +} +CapDisconnectForwardConnection, *PCapDisconnectForwardConnection; + +typedef struct CapEstablishTemporaryConnection +{ + + u8 assistingSSPIPRoutingAddress[maxDigitsLength + 1]; /*-,0*/ + u32 optional_flag; + u8 correlationID[maxDigitsLength + 1]; /*0,1 */ + u8 scfID[maxScfIDLength + 1]; /*1,3 */ + // CapExtensionField extensions[numOfExtensions]; /*2,4*/ + CapServiceInteractionIndicatorsTwo serviceInteractionIndicatorsTwo; /*3,7 */ + // CapNA_Info na_Info; /*4,50*/ +} +CapEstablishTemporaryConnection, *PCapEstablishTemporaryConnection; + +typedef struct CapPlayAnnouncement +{ + + CapInformationToSend informationToSend; /*-,0*/ + u32 optional_flag; + u8 disconnectFromIPForbidden; /*0,1 */ + u8 requestAnnouncementComplete; /*1,2 */ + // CapExtensionField extensions[numOfExtensions]; /*2,3*/ +} +CapPlayAnnouncement, *PCapPlayAnnouncement; + +typedef struct CapPromptAndCollectUserInformation +{ + + CapCollectedInfo collectedInfo; /*-,0*/ + u32 optional_flag; + u8 disconnectFromIPForbidden; /*0,1 */ + CapInformationToSend informationToSend; /*1,2 */ + // CapExtensionField extensions[numOfExtensions]; /*2,3*/ + + u8 choice_id; + + u8 digitsResponse[maxDigitsLength + 1]; /*-,0*///CapReceivedInformation +} +CapPromptAndCollectUserInformation, *PCapPromptAndCollectUserInformation; + +/*typedef union CapReceivedInformation + { + u8 digitsResponse[maxDigitsLength+1]; + }CapReceivedInformation; */ + +typedef struct CapSpecializedResourceReport +{ +} +CapSpecializedResourceReport, *PCapSpecializedResourceReport; + +#endif + +/*************************************/ +/*Cap Structure---------------------> */ + +/*************************************/ +typedef struct CapArg +{ + u8 ocode; + u8 message_flag; + u16 port_id; + u16 dialogue_id; + u8 invoke_id; + u8 version; + union + { + CapInitialDP initialDPArg; + CapApplyCharging applyChargingArg; + CapApplyChargingReport applyChargingReportArg; + CapRequestReportBCSMEvent requestReportBCSMEventArg; + CapCancel cancelArg; + CapEventReportBCSM eventReportBCSMArg; + CapReleaseCall releaseCallArg; + CapInitialDPSMS initialDPSMSArg; + CapRequestReportSMSEvent requestReportSMSEventArg; + CapEventReportSMS eventReportSMSArg; + CapReleaseSMS releaseSMSArg; + CapResetTimerSMS resetTimerArg; + CapVPSRequest vpsRequest; + CapVPSPlayAnnounce vpsPlayAnnounce; + CapAssistRequestInstructions assistRequestInstructionsArg; + CapConnect connectArg; + //CapConnect_v1 connectArg_v1; + CapConnectToResource connectToResourceArg; + CapDisconnectForwardConnection disconnectForwardConnectionArg; + CapEstablishTemporaryConnection establishTemporaryConnectionArg; + CapPlayAnnouncement playAnnouncementArg; + CapPromptAndCollectUserInformation promptAndCollectUserInformationArg; + //CapReceivedInformation receivedInformationArg; // RR of P&C + CapSpecializedResourceReport specializedResourceReportArg; + } + msg_list; +} +CapArg, *PCapArg; + +/* + typedef struct _CAP_Message + { + u8 msgLength[2]; // u80 is the higher part + u8 msgServiceCode; // fixed as 0xAF + u8 port_id[3]; // u8 0 is the higher part,u8 1 is the lower part ,and u8 2 is reserved + u8 dialogue_id[3]; + u8 msgOperaCode; // message type code ,e.g , InitialDP = 0x00 + u8 msgOperaType; // 1/2/3/4 = request, indicate, response, confirm + u8 msgContent[CAP_CONTENT_LEN]; + // if the message if cap operation ,then the first u8 of msgContent is invoke id + }CAP_Message, *PCAP_Message; + + typedef struct DestCriteria + { + u8 DestNumber[maxISDNAddressLength+1]; + u8 Type; //0:unknown 1:enable 2:inhibit + }DestCriteria; + + typedef struct CapCSI + { + int ServiceKey; + u8 SCFAddress[maxISDNAddressLength+1]; + u8 DefaultHandle; //The Default Call Handling indicates whether the call shall be released or + //continued as requested in case of error in the gsmSSF to gsmSCF dialogue. + //0:release 1:continue + CapEventTypeBCSM TDP; //TDP_R + //O-CSI:capp_collectedInfo = 2, + //T-CSI:capp_termAttemptAuthorized = 12, + u8 DstNum; + DestCriteria DstList[10]; //The DP criteria indicate whether the gsmSSF shall request the gsmSCF for instructions. + u8 BSNum; + u32 BSCode[5]; //Basic service triggering criteria + u8 FWCriteria; //Forwarding triggering criteria + //1:enabling 0:inhibiting + }CapCSI; + */ + +#endif diff --git a/plat/xapp/src/capp/cap_msgtype.c b/plat/xapp/src/capp/cap_msgtype.c new file mode 100644 index 0000000..4583ad9 --- /dev/null +++ b/plat/xapp/src/capp/cap_msgtype.c @@ -0,0 +1,1073 @@ + +/************************************************/ +/*Title: common_type.c */ +/*Descr: CAP Provide */ +/*Author: Liang Hanxi */ +/*Create: 2002-5-7 */ +/************************************************/ + +#include "../../../public/src/include/pub_include.h" +#include "cap_head.h" +#include "cap_msg.h" + +/*++++++++++++++++++++++++ */ +//SubscriberState===========> +/*++++++++++++++++++++++++ */ +int encSubscriberState(u_char sel, char *tagprefix, CapSubscriberState arg, ASN_BUF * asnbuf) +{ //return length if success,or -1 is returned + char tagseq[16]; + + switch (sel) + { + case 0: //assumedIdle--->(NULL) + sprintf(tagseq, "%s.0", tagprefix); + return add_null(tagseq, 0x80, asnbuf); + case 1: //camelBusy--->(NULL) + sprintf(tagseq, "%s.1", tagprefix); + return add_null(tagseq, 0x80, asnbuf); + case 2: //netDetNotReachable + sprintf(tagseq, "%s.10", tagprefix); + return AddInteger(tagseq, arg.netDetNotReachable, 0, asnbuf); + case 3: //notProvidedFromVLR--->(NULL) + sprintf(tagseq, "%s.2", tagprefix); + return add_null(tagseq, 0x80, asnbuf); + } + return -1; +} + +int decSubscriberState(char *tagprefix, CapSubscriberState * parg, ASN_BUF * asnbuf) +//return choice indicator,-1 if none. +{ + char tagseq[16]; + int len; + + //-------(0)assumedIdle--->(NULL) + sprintf(tagseq, "%s.0", tagprefix); + if((len = GetTLV(tagseq, 1, &parg->assumedIdle, 0x80, asnbuf)) >= 0) + return 0; + //-------(1)camelBusy--->(NULL) + sprintf(tagseq, "%s.1", tagprefix); + if((len = GetTLV(tagseq, 1, &parg->camelBusy, 0x80, asnbuf)) >= 0) + return 1; + //-------(2)netDetNotReachable---> + sprintf(tagseq, "%s.10", tagprefix); + if((len = GetInteger(tagseq, (int *)&parg->netDetNotReachable, 0, asnbuf)) > 0) + return 2; + //-------(3)notProvidedFromVLR--->(NULL) + sprintf(tagseq, "%s.2", tagprefix); + if((len = GetTLV(tagseq, 1, &parg->notProvidedFromVLR, 0x80, asnbuf)) >= 0) + return 3; + return -1; +} + +/*++++++++++++++++++++++++ */ +//CellIdOrLAI==============> +/*++++++++++++++++++++++++ */ +int encCellIdOrLAI(u_char sel, char *tagprefix, CapCellIdOrLAI arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + + switch (sel) + { + case 0: //cellIdFixedLength + sprintf(tagseq, "%s.0", tagprefix); + return AddTLV(tagseq, arg.cellIdFixedLength[0], arg.cellIdFixedLength + 1, 0x80, asnbuf); + case 1: //laiFixedLength + sprintf(tagseq, "%s.1", tagprefix); + return AddTLV(tagseq, arg.cellIdFixedLength[0], arg.laiFixedLength + 1, 0x80, asnbuf); + } + return -1; +} + +int decCellIdOrLAI(char *tagprefix, CapCellIdOrLAI * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int len; + + //-------(0)cellIdFixedLength---> + sprintf(tagseq, "%s.0", tagprefix); + if((len = GetTLV(tagseq, 7, parg->cellIdFixedLength + 1, 0x80, asnbuf)) > 0) + { + parg->cellIdFixedLength[0] = len; + return 0; + } + //-------(1)laiFixedLength---> + sprintf(tagseq, "%s.1", tagprefix); + if((len = GetTLV(tagseq, 5, parg->laiFixedLength + 1, 0x80, asnbuf)) > 0) + { + parg->laiFixedLength[0] = len; + return 1; + } + return -1; +} + +/*+++++++++++++++++++++++++ */ +//Ext_BasicServiceCode======> +/*+++++++++++++++++++++++++ */ +int encExt_BasicServiceCode(u_char sel, char *tagprefix, CapExt_BasicServiceCode arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + + switch (sel) + { + case 0: //ext_BearerService + sprintf(tagseq, "%s.2", tagprefix); + return AddTLV(tagseq, arg.ext_BearerService[0], arg.ext_BearerService + 1, 0x80, asnbuf); + case 1: //ext_Teleservice + sprintf(tagseq, "%s.3", tagprefix); + return AddTLV(tagseq, arg.ext_Teleservice[0], arg.ext_Teleservice + 1, 0x80, asnbuf); + } + return -1; +} + +int decExt_BasicServiceCode(char *tagprefix, CapExt_BasicServiceCode * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int len; + + //-------(0)ext_BearerService---> + sprintf(tagseq, "%s.2", tagprefix); + if((len = GetTLV(tagseq, 5, parg->ext_BearerService + 1, 0x80, asnbuf)) > 0) + { + parg->ext_BearerService[0] = len; + return 0; + } + //-------(1)ext_Teleservice---> + sprintf(tagseq, "%s.3", tagprefix); + if((len = GetTLV(tagseq, 5, parg->ext_Teleservice + 1, 0x80, asnbuf)) > 0) + { + parg->ext_Teleservice[0] = len; + return 1; + } + return -1; +} + +/*++++++++++++++++++++++++ */ +//LocationInformation======> +/*++++++++++++++++++++++++ */ +int encLocationInformation(char *tagprefix, CapLocationInformation arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval = -1; + + if(check_bit(arg.optional_flag, 0)) //ageOfLocationInformation----> + { + sprintf(tagseq, "%s.2-1", tagprefix); + if((retval = AddInteger(tagseq, arg.ageOfLocationInformation, 0, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 1)) //geographicalInformation----> + { + sprintf(tagseq, "%s.0-2", tagprefix); + if((retval = AddTLV(tagseq, arg.geographicalInformation[0], arg.geographicalInformation + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 2)) //vlr_number----> + { + sprintf(tagseq, "%s.1-3", tagprefix); + if((retval = AddTLV(tagseq, arg.vlr_number[0], arg.vlr_number + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 3)) //locationNumber----> + { + sprintf(tagseq, "%s.2-4", tagprefix); + if((retval = AddTLV(tagseq, arg.locationNumber[0], arg.locationNumber + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 4)) //cellIdOrLAI----> + { + sprintf(tagseq, "%s.3-5", tagprefix); + if((retval = encCellIdOrLAI(arg.cellIdOrLAI_ch, tagseq, arg.cellIdOrLAI, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decLocationInformation(char *tagprefix, CapLocationInformation * parg, ASN_BUF * asnbuf) +{ + int retval = -1, len, sel; + char tagseq[16]; + + parg->optional_flag = 0; + + //ageOfLocationInformation----> + sprintf(tagseq, "%s.2", tagprefix); + if((len = GetInteger(tagseq, &parg->ageOfLocationInformation, 0, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 0); + retval = 1; + } + //geographicalInformation----> + sprintf(tagseq, "%s.0", tagprefix); + if((len = GetTLV(tagseq, 8, parg->geographicalInformation + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 1); + parg->geographicalInformation[0] = len; + retval = 1; + } + //vlr_number----> + sprintf(tagseq, "%s.1", tagprefix); + if((len = GetTLV(tagseq, maxISDNAddressLength, parg->vlr_number + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 2); + parg->vlr_number[0] = len; + retval = 1; + } + //locationNumber----> + sprintf(tagseq, "%s.2", tagprefix); + if((len = GetTLV(tagseq, maxLocationNumberLength, parg->locationNumber + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 3); + parg->locationNumber[0] = len; + retval = 1; + } + //cellIdOrLAI----> + sprintf(tagseq, "%s.3", tagprefix); + if((sel = decCellIdOrLAI(tagseq, &parg->cellIdOrLAI, asnbuf)) >= 0) + { + set_bit(parg->optional_flag, 4); + parg->cellIdOrLAI_ch = sel; + retval = 1; + } + return retval; +} + +/*++++++++++++++++++++++++++++ */ +//LocationInformationGPRS======> +/*++++++++++++++++++++++++++++ */ +int encLocationInformationGPRS(char *tagprefix, CapLocationInformationGPRS arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval = -1; + + if(check_bit(arg.optional_flag, 0)) //cellGlobalIdOrServiceAreaIdOrLAI ----> + { + sprintf(tagseq, "%s.0", tagprefix); + if((retval = AddTLV(tagseq, arg.cellGlobalIdOrServiceAreaIdOrLAI[0], arg.cellGlobalIdOrServiceAreaIdOrLAI + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 1)) //routeingAreaIdentity ----> + { + sprintf(tagseq, "%s.1", tagprefix); + if((retval = AddTLV(tagseq, arg.routeingAreaIdentity[0], arg.routeingAreaIdentity + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 2)) //geographicalInformation----> + { + sprintf(tagseq, "%s.2", tagprefix); + if((retval = AddTLV(tagseq, arg.geographicalInformation[0], arg.geographicalInformation + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 3)) //sgsn_Number----> + { + sprintf(tagseq, "%s.3", tagprefix); + if((retval = AddTLV(tagseq, arg.sgsn_Number[0], arg.sgsn_Number + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 4)) //cellIdOrLAI----> + { + sprintf(tagseq, "%s.4", tagprefix); + if((retval = AddTLV(tagseq, arg.selectedLSAIdentity[0], arg.selectedLSAIdentity + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 6)) //cellIdOrLAI----> + { + sprintf(tagseq, "%s.6", tagprefix); + if((retval = add_null(tagseq, 0x80, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decLocationInformationGPRS(char *tagprefix, CapLocationInformationGPRS * parg, ASN_BUF * asnbuf) +{ + int retval = -1, len; + char tagseq[16]; + + parg->optional_flag = 0; + + //cellGlobalIdOrServiceAreaIdOrLAI----> + sprintf(tagseq, "%s.0", tagprefix); + if((len = GetTLV(tagseq, 7, parg->cellGlobalIdOrServiceAreaIdOrLAI + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 0); + parg->cellGlobalIdOrServiceAreaIdOrLAI[0] = len; + retval = 1; + } + //routeingAreaIdentity----> + sprintf(tagseq, "%s.1", tagprefix); + if((len = GetTLV(tagseq, 7, parg->routeingAreaIdentity + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 1); + parg->routeingAreaIdentity[0] = len; + retval = 1; + } + //geographicalInformation----> + sprintf(tagseq, "%s.2", tagprefix); + if((len = GetTLV(tagseq, 8, parg->geographicalInformation + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 2); + parg->geographicalInformation[0] = len; + retval = 1; + } + //sgsn_Number----> + sprintf(tagseq, "%s.3", tagprefix); + if((len = GetTLV(tagseq, maxISDNAddressLength, parg->sgsn_Number + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 3); + parg->sgsn_Number[0] = len; + retval = 1; + } + //selectedLSAIdentity----> + sprintf(tagseq, "%s.4", tagprefix); + if((len = GetTLV(tagseq, 3, parg->selectedLSAIdentity + 1, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 4); + parg->selectedLSAIdentity[0] = len; + retval = 1; + } + //selectedLSAIdentity----> + sprintf(tagseq, "%s.6", tagprefix); + if((len = GetTLV(tagseq, 1, &parg->sai_Present, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 5); + retval = 1; + } + return retval; +} + +/*++++++++++++++++++++++++++++++++++++++++++++ */ +//CAMEL-aChbillingChargingCharacteristics======> +/*++++++++++++++++++++++++++++++++++++++++++++ */ +int encACBCC(struct CapACBCC arg, char *msgbuf, int maxlen) +{ + ASN_BUF asnbuf; + int retval = -1; + + AsnEncode((u_char *)msgbuf, maxlen, &asnbuf); + if((retval = AddInteger("0.0", arg.maxCallPeriodDuration, 0x80, &asnbuf)) < 0) + return -1; + if(check_bit(arg.optional_flag, 0)) + { + if((retval = AddTLV("0.1.1", 1, &arg.releaseIfdurationExceeded.tone, 0, &asnbuf)) < 0) + /* no reason, why code as following lines */ + // if((retval=AddTLV("0.1",1,&arg.releaseIfdurationExceeded.tone,0x80,&asnbuf))<0) + return -1; + } + if(check_bit(arg.optional_flag, 1)) + { + if((retval = AddInteger("0.2", arg.tariffSwitchInterval, 0x80, &asnbuf)) < 0) + return -1; + } + return retval; +} + +int decACBCC(char *msgbuf, int msglen, CapACBCC * parg) +{ + ASN_BUF asnbuf; + int errpos, len; + + parg->optional_flag = 0; + if((len = AsnDecode((u_char *)msgbuf, msglen, 1, &errpos, &asnbuf)) < 0) + { + printf("Decode error:%s", asnbuf.errmsg); + return -1; + } + if(GetInteger("0.0", &parg->maxCallPeriodDuration, 0x80, &asnbuf) < 0) + return -1; + if((len = GetTLV("0.1.1", 1, &parg->releaseIfdurationExceeded.tone, 0, &asnbuf)) > 0) + set_bit(parg->optional_flag, 0); + if((len = GetInteger("0.2", &parg->tariffSwitchInterval, 0x80, &asnbuf)) > 0) + set_bit(parg->optional_flag, 1); + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++++++++ */ +//LegID======> +/*++++++++++++++++++++++++++++++++++++++++++++ */ +int encLegID(u_char sel, char *tagprefix, CapLegID arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + + switch (sel) + { + case 0: //sendingSideID + sprintf(tagseq, "%s.0", tagprefix); + return AddTLV(tagseq, 1, &arg.sendingSideID, 0x80, asnbuf); + case 1: //receivingSideID + sprintf(tagseq, "%s.1", tagprefix); + return AddTLV(tagseq, 1, &arg.receivingSideID, 0x80, asnbuf); + } + return -1; +} + +int decLegID(char *tagprefix, CapLegID * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int len; + + sprintf(tagseq, "%s.0", tagprefix); //sendingSideID + if((len = GetTLV(tagseq, 1, &parg->sendingSideID, 0x80, asnbuf)) >= 0) + return 0; + sprintf(tagseq, "%s.1", tagprefix); //receivingSideID + if((len = GetTLV(tagseq, 1, &parg->receivingSideID, 0x80, asnbuf)) >= 0) + return 1; + return -1; +} + +/*++++++++++++++++++++++++++++++++++++++++++++ */ +//EventSpecificInformationBCSM======> +/*++++++++++++++++++++++++++++++++++++++++++++ */ +int encESIBCSM(char *tagprefix, CapESIBCSM arg, ASN_BUF * asnbuf) +{ + char tagseq[32]; + int retval = -1; + + if(arg.infotype < 2 || arg.infotype > 12) + return -1; + sprintf(tagseq, "%s.%d", tagprefix, arg.infotype); + if((retval = add_null(tagseq, 0xA0, asnbuf)) < 0) + return -1; + if(arg.cause[0] > 0) + { + sprintf(tagseq, "%s.%d.0", tagprefix, arg.infotype); + if((retval = AddTLV(tagseq, arg.cause[0], arg.cause + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(arg.callForwarded) + { + sprintf(tagseq, "%s.%d.50", tagprefix, arg.infotype); + if((retval = add_null(tagseq, 0x80, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decESIBCSM(char *tagprefix, CapESIBCSM * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + u_char msgbuf[64]; + int len; + u_short tagcode; + + sprintf(tagseq, "%s.-1", tagprefix); //get first tlv + if(GetAnyTLV(tagseq, 64, msgbuf, NULL, &tagcode, asnbuf) < 0) + return -1; + parg->infotype = tagcode; + parg->callForwarded = 0; + switch (tagcode) + { + case 2: + case 3: + case 7: + case 12: + sprintf(tagseq, "%s.-1.0", tagprefix); + if((len = GetTLV(tagseq, maxCauseLength, parg->cause + 1, 0x80, asnbuf)) > 0) + parg->cause[0] = len; + else + parg->cause[0] = 0; + break; + case 8: + sprintf(tagseq, "%s.-1.0", tagprefix); + if((len = GetTLV(tagseq, maxCauseLength, parg->cause + 1, 0x80, asnbuf)) > 0) + parg->cause[0] = len; + else + parg->cause[0] = 0; + sprintf(tagseq, "%s.-1.50", tagprefix); + if((len = GetTLV(tagseq, 0, &parg->callForwarded, 0x80, asnbuf)) >= 0) + parg->callForwarded = 1; + break; + case 9: + sprintf(tagseq, "%s.-1.50", tagprefix); + if(GetTLV(tagseq, 0, &parg->callForwarded, 0x80, asnbuf) >= 0) + parg->callForwarded = 1; + break; + case 4: + case 5: + case 10: + break; + default: + return -1; + } + return 1; +} + +/*++++++++++++++++++++++++++++++++++++++++++++ */ +//EventSpecificInformationSMS======> +/*++++++++++++++++++++++++++++++++++++++++++++ */ +int encESISMS(char *tagprefix, CapESISMS arg, ASN_BUF * asnbuf) +{ + char tagseq[32]; + int retval = -1; + + if(arg.infotype > 1) + return -1; + sprintf(tagseq, "%s.%d", tagprefix, arg.infotype); + if((retval = add_null(tagseq, 0xA0, asnbuf)) < 0) + return -1; + if(arg.infotype == 0 && arg.cause_flag) + { + sprintf(tagseq, "%s.%d.0", tagprefix, arg.infotype); + if((retval = AddInteger(tagseq, arg.cause, 0x80, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decESISMS(char *tagprefix, CapESISMS * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + u_char msgbuf[64]; + int len; + u_short tagcode; + + sprintf(tagseq, "%s.-1", tagprefix); //get first tlv + if(GetAnyTLV(tagseq, 64, msgbuf, NULL, &tagcode, asnbuf) < 0) + return -1; + parg->infotype = tagcode; + if(tagcode == 0) + { + sprintf(tagseq, "%s.-1.0", tagprefix); + if((len = GetInteger(tagseq, (int *)&parg->cause, 0x80, asnbuf)) > 0) + parg->cause_flag = 1; + else + parg->cause_flag = 0; + } + return 1; +} + +#ifdef _SRF_RELEVANT +int encServiceInteractionIndicatorsTwo(char *tagprefix, CapServiceInteractionIndicatorsTwo arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval = 0; + + if(check_bit(arg.optional_flag, 0)) + { + sprintf(tagseq, "%s.2", tagprefix); + if((retval = add_bool(tagseq, arg.bothwayThroughConnectionInd, 0x80, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decServiceInteractionIndicatorsTwo(char *tagprefix, CapServiceInteractionIndicatorsTwo * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval = -1; + int len; + + parg->optional_flag = 0; + sprintf(tagseq, "%s.2", tagprefix); + if((len = GetTLV(tagseq, 1, &parg->bothwayThroughConnectionInd, 0x80, asnbuf)) >= 0) + { + set_bit(parg->optional_flag, 0); + retval = 1; + } + return retval; +} + +int encVariablePart(char seq, char *tagprefix, CapVariablePart arg, ASN_BUF * asnbuf) +{ + char tagseq[32]; + int retval = 0; + + switch (arg.choice_id) + { + case 0: + sprintf(tagseq, "%s.0-%d", tagprefix, seq); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.integer, 0x80, asnbuf)) < 0) + return -1; + break; + case 1: + sprintf(tagseq, "%s.1-%d", tagprefix, seq); + if((retval = AddTLV(tagseq, arg.number[0], arg.number + 1, 0x80, asnbuf)) < 0) + return -1; + break; + case 2: + sprintf(tagseq, "%s.2-%d", tagprefix, seq); + if((retval = AddTLV(tagseq, 2, (u8 *) & arg.time, 0x80, asnbuf)) < 0) + return -1; + break; + case 3: + sprintf(tagseq, "%s.3-%d", tagprefix, seq); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.date, 0x80, asnbuf)) < 0) + return -1; + break; + case 4: + sprintf(tagseq, "%s.4-%d", tagprefix, seq); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.price, 0x80, asnbuf)) < 0) + return -1; + break; + case 5: + sprintf(tagseq, "%s.5-%d", tagprefix, seq); + if((retval = AddTLV(tagseq, 1, (u8 *) & arg.signSymbol, 0x80, asnbuf)) < 0) + return -1; + break; + } + return retval; +} + +int decVariablePart(char *tagprefix, CapVariablePart * parg, ASN_BUF * asnbuf) +{ + //char tagseq[32]; + int len; + char msgbuf[64]; + u_short tagcode; + + /*char tagseq[16]; + u_char msgbuf[64]; + int len; + u_short tagcode; + + sprintf(tagseq, "%s.-1", tagprefix); //get first tlv + if(GetAnyTLV(tagseq, 64, msgbuf, NULL, &tagcode, asnbuf) < 0) */ + + if((len = GetAnyTLV(tagprefix, 64, (u_char *)msgbuf, NULL, &tagcode, asnbuf)) > 0) + { + switch (tagcode) + { + case 0: + memcpy(&parg->integer, msgbuf, len); + parg->choice_id = 0; + return 1; + case 1: + memcpy(parg->number + 1, msgbuf, len); + parg->number[0] = len; + parg->choice_id = 1; + return 1; + case 2: + memcpy(parg->time, msgbuf, len); + parg->choice_id = 2; + return 1; + case 3: + memcpy(parg->date, msgbuf, len); + parg->choice_id = 3; + return 1; + case 4: + memcpy(parg->price, msgbuf, len); + parg->choice_id = 4; + return 1; + case 5: + parg->signSymbol = msgbuf[0]; + parg->choice_id = 5; + return 1; + } + } + return -1; + /*sprintf(tagseq, "%s.0", tagprefix); + if(GetTLV(tagseq,4,(u8 *)&parg->integer,0x80,asnbuf)>0) + { + parg->choice_id = 0; + return 1; + } + sprintf(tagseq, "%s.1", tagprefix); + if((len=GetTLV(tagseq,maxDigitsLength,parg->number+1,0x80,asnbuf))>0) + { + parg->number[0] = len; + parg->choice_id = 1; + return 1; + } + sprintf(tagseq, "%s.2", tagprefix); + if(GetTLV(tagseq,2,(u8 *)&parg->time,0x80,asnbuf)>0) + { + parg->choice_id = 2; + return 1; + } + sprintf(tagseq, "%s.3", tagprefix); + if(GetTLV(tagseq,4,(u8 *)&parg->date,0x80,asnbuf)>0) + { + parg->choice_id = 3; + return 1; + } + sprintf(tagseq, "%s.4", tagprefix); + if(GetTLV(tagseq,4,(u8 *)&parg->price,0x80,asnbuf)>0) + { + parg->choice_id = 4; + return 1; + } + return -1; */ +} + +int encMessageID(char *tagprefix, CapMessageID arg, ASN_BUF * asnbuf) +{ + char tagseq[32]; + int retval = 0; + int index; + + switch (arg.choice_id) + { + case 0: + sprintf(tagseq, "%s.0", tagprefix); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.elementaryMessageID, 0x80, asnbuf)) < 0) + return -1; + break; + case 1: //text + break; + case 2: + for(index = 0; index < arg.elementaryMessageIDs.num; index++) + { + sprintf(tagseq, "%s.29-%d", tagprefix, index + 1); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.elementaryMessageIDs.elementaryMessageID[index], 0x80, asnbuf)) < 0) + return -1; + } + break; + case 3: + sprintf(tagseq, "%s.30.0", tagprefix); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.variableMessage.elementaryMessageID, 0x80, asnbuf)) < 0) + return -1; + for(index = 0; index < arg.variableMessage.variableParts.num; index++) + { + sprintf(tagseq, "%s.30.1", tagprefix); + if((retval = encVariablePart(index + 1, tagseq, arg.variableMessage.variableParts.variablePart[index], asnbuf)) < 0) + return -1; + } + break; + } + return retval; +} + +int decMessageID(char *tagprefix, CapMessageID * parg, ASN_BUF * asnbuf) +{ + char tagseq[32]; + int index , ret = 0 ; + + sprintf(tagseq, "%s.0", tagprefix); + if(GetTLV(tagseq, 4, (u8 *) & parg->elementaryMessageID, 0x80, asnbuf) > 0) + { + parg->choice_id = 0; + return 1; + } + + parg->elementaryMessageIDs.num = 0; + for(index = 0; index < numOfMessageIDs; index++) + { + sprintf(tagseq, "%s.29-%d", tagprefix, index + 1); + if(GetTLV(tagseq, 4, (u8 *) & parg->elementaryMessageIDs.elementaryMessageID[index], 0x80, asnbuf) > 0) + { + parg->elementaryMessageIDs.num++; + ret = 1; + } + } + if( ret ) + { + parg->choice_id = 2; + return 1; + } + + sprintf(tagseq, "%s.30.0", tagprefix); + if(GetTLV(tagseq, 4, (u8 *) & parg->variableMessage.elementaryMessageID, 0x80, asnbuf) < 0) + return -1; + parg->variableMessage.variableParts.num = 0; + for(index = 0; index < MAX_VAR_NUMS; index++) + { + sprintf(tagseq, "%s.30.1.-%d", tagprefix, index + 1); + if(decVariablePart(tagseq, &parg->variableMessage.variableParts.variablePart[index], asnbuf) >= 0) + { + parg->variableMessage.variableParts.num++; + ret = 1; + } + } + if( ret ) + { + parg->choice_id = 3; + return 1; + } + return -1; +} + +int encInbandInfo(char *tagprefix, CapInbandInfo arg, ASN_BUF * asnbuf) +{ + char tagseq[32]; + int retval = 0; + + sprintf(tagseq, "%s.0", tagprefix); + if((retval = encMessageID(tagseq, arg.messageID, asnbuf)) < 0) + return -1; + if(check_bit(arg.optional_flag, 0)) + { + sprintf(tagseq, "%s.1", tagprefix); + if((retval = AddInteger(tagseq, arg.numberOfRepetitions, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 1)) + { + sprintf(tagseq, "%s.2", tagprefix); + if((retval = AddInteger(tagseq, arg.duration, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 2)) + { + sprintf(tagseq, "%s.3", tagprefix); + if((retval = AddInteger(tagseq, arg.interval, 0x80, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decInbandInfo(char *tagprefix, CapInbandInfo * parg, ASN_BUF * asnbuf) +{ + char tagseq[32]; + int retval = -1; + + parg->optional_flag = 0; + sprintf(tagseq, "%s.0", tagprefix); + if(decMessageID(tagseq, &parg->messageID, asnbuf) >= 0) + { + retval = 1; + } + sprintf(tagseq, "%s.1", tagprefix); + if((GetInteger(tagseq, &parg->numberOfRepetitions, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 0); + } + sprintf(tagseq, "%s.2", tagprefix); + if((GetInteger(tagseq, &parg->duration, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 1); + } + sprintf(tagseq, "%s.3", tagprefix); + if((GetInteger(tagseq, &parg->interval, 0x80, asnbuf)) > 0) + { + set_bit(parg->optional_flag, 2); + } + return retval; +} + +int encTone(char *tagprefix, CapTone arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval = 0; + + sprintf(tagseq, "%s.0", tagprefix); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.toneID, 0x80, asnbuf)) < 0) + return -1; + if(check_bit(arg.optional_flag, 0)) + { + sprintf(tagseq, "%s.1", tagprefix); + if((retval = AddTLV(tagseq, 4, (u8 *) & arg.duration, 0x80, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decTone(char *tagprefix, CapTone * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval = -1; + + parg->optional_flag = 0; + sprintf(tagseq, "%s.0", tagprefix); + if(GetTLV(tagseq, 4, (u8 *) & parg->toneID, 0x80, asnbuf) > 0) + { + retval = 1; + } + sprintf(tagseq, "%s.1", tagprefix); + if(GetTLV(tagseq, 4, (u8 *) & parg->duration, 0x80, asnbuf) > 0) + { + set_bit(parg->optional_flag, 0); + } + return retval; +} + +int encInformationToSend(char *tagprefix, CapInformationToSend arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval; + + switch (arg.choice_id) + { + case 0: + sprintf(tagseq, "%s.0", tagprefix); + if((retval = encInbandInfo(tagseq, arg.inbandInfo, asnbuf)) < 0) + return -1; + break; + case 1: + sprintf(tagseq, "%s.1", tagprefix); + if((retval = encTone(tagseq, arg.tone, asnbuf)) < 0) + return -1; + break; + } + return retval; +} + +int decInformationToSend(char *tagprefix, CapInformationToSend * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + + sprintf(tagseq, "%s.0", tagprefix); + if(decInbandInfo(tagseq, &parg->inbandInfo, asnbuf) >= 0) + { + parg->choice_id = 0; + return 1; + } + sprintf(tagseq, "%s.1", tagprefix); + if(decTone(tagseq, &parg->tone, asnbuf) >= 0) + { + parg->choice_id = 1; + return 1; + } + return -1; +} + +int encCollectedDigits(char *tagprefix, CapCollectedDigits arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval; + + sprintf(tagseq, "%s.0", tagprefix); + if((retval = AddTLV(tagseq, 1, &arg.minimumNbOfDigits, 0x80, asnbuf)) < 0) + return -1; + sprintf(tagseq, "%s.1", tagprefix); + if((retval = AddTLV(tagseq, 1, &arg.maximumNbOfDigits, 0x80, asnbuf)) < 0) + return -1; + + if(check_bit(arg.optional_flag, 0)) + { + sprintf(tagseq, "%s.2", tagprefix); + if((retval = AddTLV(tagseq, arg.endOfReplyDigit[0], arg.endOfReplyDigit + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 1)) + { + sprintf(tagseq, "%s.3", tagprefix); + if((retval = AddTLV(tagseq, arg.cancelDigit[0], arg.cancelDigit + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 2)) + { + sprintf(tagseq, "%s.4", tagprefix); + if((retval = AddTLV(tagseq, arg.startDigit[0], arg.startDigit + 1, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 3)) + { + sprintf(tagseq, "%s.5", tagprefix); + if((retval = AddTLV(tagseq, 1, &arg.firstDigitTimeOut, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 4)) + { + sprintf(tagseq, "%s.6", tagprefix); + if((retval = AddTLV(tagseq, 1, &arg.interDigitTimeOut, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 5)) + { + sprintf(tagseq, "%s.7", tagprefix); + if((retval = AddTLV(tagseq, 1, (u8 *) & arg.errorTreatment, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 6)) + { + sprintf(tagseq, "%s.8", tagprefix); + if((retval = AddTLV(tagseq, 1, &arg.interruptableAnnInd, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 7)) + { + sprintf(tagseq, "%s.9", tagprefix); + if((retval = AddTLV(tagseq, 1, &arg.voiceInformation, 0x80, asnbuf)) < 0) + return -1; + } + if(check_bit(arg.optional_flag, 8)) + { + sprintf(tagseq, "%s.10", tagprefix); + if((retval = AddTLV(tagseq, 1, &arg.voiceBack, 0x80, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decCollectedDigits(char *tagprefix, CapCollectedDigits * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int len; + + parg->optional_flag = 0; + sprintf(tagseq, "%s.0", tagprefix); + if(GetTLV(tagseq, 1, &parg->minimumNbOfDigits, 0x80, asnbuf) < 0) + ; //return -1; + sprintf(tagseq, "%s.1", tagprefix); + if(GetTLV(tagseq, 1, &parg->maximumNbOfDigits, 0x80, asnbuf) < 0) + return -1; + + sprintf(tagseq, "%s.2", tagprefix); + if((len = GetTLV(tagseq, 3, parg->endOfReplyDigit + 1, 0x80, asnbuf)) > 0) + { + parg->endOfReplyDigit[0] = len; + set_bit(parg->optional_flag, 0); + } + sprintf(tagseq, "%s.3", tagprefix); + if((len = GetTLV(tagseq, 3, parg->cancelDigit + 1, 0x80, asnbuf)) > 0) + { + parg->cancelDigit[0] = len; + set_bit(parg->optional_flag, 1); + } + sprintf(tagseq, "%s.4", tagprefix); + if((len = GetTLV(tagseq, 3, parg->startDigit + 1, 0x80, asnbuf)) > 0) + { + parg->startDigit[0] = len; + set_bit(parg->optional_flag, 2); + } + sprintf(tagseq, "%s.5", tagprefix); + if(GetTLV(tagseq, 1, &parg->firstDigitTimeOut, 0x80, asnbuf) > 0) + { + set_bit(parg->optional_flag, 3); + } + sprintf(tagseq, "%s.6", tagprefix); + if(GetTLV(tagseq, 1, &parg->interDigitTimeOut, 0x80, asnbuf) > 0) + { + set_bit(parg->optional_flag, 4); + } + sprintf(tagseq, "%s.7", tagprefix); + if(GetTLV(tagseq, 1, (u8 *) & parg->errorTreatment, 0x80, asnbuf) > 0) + { + set_bit(parg->optional_flag, 5); + } + sprintf(tagseq, "%s.8", tagprefix); + if(GetTLV(tagseq, 1, &parg->interruptableAnnInd, 0x80, asnbuf) > 0) + { + set_bit(parg->optional_flag, 6); + } + sprintf(tagseq, "%s.9", tagprefix); + if(GetTLV(tagseq, 1, &parg->voiceInformation, 0x80, asnbuf) > 0) + { + set_bit(parg->optional_flag, 7); + } + sprintf(tagseq, "%s.10", tagprefix); + if(GetTLV(tagseq, 1, &parg->voiceBack, 0x80, asnbuf) > 0) + { + set_bit(parg->optional_flag, 8); + } + return 1; +} + +int encCollectedInfo(char *tagprefix, CapCollectedInfo arg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + int retval; + + if(arg.choice_id == 0) + { + sprintf(tagseq, "%s.0", tagprefix); + if((retval = encCollectedDigits(tagseq, arg.collectedDigits, asnbuf)) < 0) + return -1; + } + return retval; +} + +int decCollectedInfo(char *tagprefix, CapCollectedInfo * parg, ASN_BUF * asnbuf) +{ + char tagseq[16]; + + sprintf(tagseq, "%s.0", tagprefix); + if(decCollectedDigits(tagseq, &parg->collectedDigits, asnbuf) >= 0) + { + parg->choice_id = 0; + return 1; + } + return -1; +} + +#endif diff --git a/plat/xapp/src/capp/cap_public.c b/plat/xapp/src/capp/cap_public.c new file mode 100644 index 0000000..cbf4a32 --- /dev/null +++ b/plat/xapp/src/capp/cap_public.c @@ -0,0 +1,497 @@ +/* CAP public function c file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#include "../../../public/src/include/pub_include.h" +#include "../../../sccp/src/include/sccp.h" +#include "../mapp/map_const.h" +#include "../mapp/map_code.h" +#include "../mapp/map_struct.h" +#include "cap_head.h" + +void cap_get_sccpadd(struct SCCP_ADDRESS *add_ptr, u8 * data) +{ + u8 temp_len; + + add_ptr->ip = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + add_ptr->DPC = (data[4] << 24) + (data[5] << 16) + (data[6] << 8) + data[7]; + add_ptr->NetID = data[8]; + add_ptr->SSN = data[9]; + add_ptr->RI = data[10]; + add_ptr->GTI = data[11]; + add_ptr->TT = data[12]; + add_ptr->NP = data[13]; + add_ptr->ES = data[14]; + add_ptr->NAI = data[15]; + add_ptr->len = data[16]; + temp_len = (data[16] + 1) / 2; + memcpy(add_ptr->GTAI, data + 17, temp_len); +} + +void cap_set_sccpadd(struct SCCP_ADDRESS *add_ptr, u8 * data) +{ + u8 temp_len; + + data[0] = add_ptr->ip >> 24; + data[1] = add_ptr->ip >> 16; + data[2] = add_ptr->ip >> 8; + data[3] = add_ptr->ip; + data[4] = add_ptr->DPC >> 24; + data[5] = add_ptr->DPC >> 16; + data[6] = add_ptr->DPC >> 8; + data[7] = add_ptr->DPC; + data[8] = add_ptr->NetID; + data[9] = add_ptr->SSN; + data[10] = add_ptr->RI; + data[11] = add_ptr->GTI; + data[12] = add_ptr->TT; + data[13] = add_ptr->NP; + data[14] = add_ptr->ES; + data[15] = add_ptr->NAI; + data[16] = add_ptr->len; + temp_len = (add_ptr->len + 1) / 2; + memcpy(data + 17, add_ptr->GTAI, temp_len); +} + +u8 cap_com_ftos(struct MapComSrv_struct *map_com, u8 * data_flow) +{ // common service data flow to structure + u32 aa; + u32 len; + u8 ii; + u8 delimiter_flag = 0; + struct MapOpen_Arg *open_arg; + struct MapOpen_Res *open_res; + struct MapClose_Arg *close_ptr; + struct MapUAbort_Arg *uabrt_ptr; + struct MapPAbort_Arg *pabrt_ptr; + + len = (data_flow[0] << 8) + data_flow[1]; + if(len < 9) // data flow is too short + return 0; + if(data_flow[2] != CAP_FLAG) + return 0; + map_com->port_id = (data_flow[3] << 8) + data_flow[4]; + map_com->dialogue_id = (data_flow[6] << 8) + data_flow[7]; + map_com->message_type = data_flow[9]; + map_com->message_flag = data_flow[10]; + switch (map_com->message_type) + { + case MAP_OPEN: + if(map_com->message_flag == MAP_REQUEST || map_com->message_flag == MAP_INDICATE) + { + open_arg = (MapOpen_Arg *) & map_com->dlg_list.open_arg; + open_arg->acn_data.acn = data_flow[11]; + open_arg->acn_data.acn_ver = data_flow[12]; + cap_get_sccpadd(&open_arg->peer_add, data_flow + 13); + cap_get_sccpadd(&open_arg->local_add, data_flow + 41); + open_arg->param_flag = 0x0b; + aa = 70; + for(ii = 0; ii < 3; ii++) + { + if(data_flow[aa] == 0x00) + break; + else if(data_flow[aa] == 0x01) // peer reference + { + len = data_flow[aa + 1]; + if(len > ISDN_LEN) + return 0; + open_arg->peerref_len = len; + memcpy(open_arg->peer_reference, &data_flow[aa + 2], len); + aa += len + 2; + open_arg->param_flag |= 0x04; + } + else if(data_flow[aa] == 0x02) // local reference + { + len = data_flow[aa + 1]; + if(len > ISDN_LEN) + return 0; + open_arg->localref_len = len; + memcpy(open_arg->local_reference, &data_flow[aa + 2], len); + aa += len + 2; + open_arg->param_flag |= 0x10; + } + else if(data_flow[aa] == 0x03) // specific info + { + len = data_flow[aa + 1]; + if(len >= MAX_SPCINFO_LEN) + return 0; + open_arg->specific_info.info_len = len; + memcpy(open_arg->specific_info.info_data, &data_flow[aa + 2], len); + open_arg->param_flag |= 0x20; + aa += 2 + len; + } + else if(data_flow[aa] == 0x10) + { + delimiter_flag = 1; + aa += 2; + } + } + } + else if(map_com->message_flag == MAP_RESPONSE || map_com->message_flag == MAP_CONFIRM) + { + open_res = (MapOpen_Res *) & map_com->dlg_list.open_res; + open_res->result = data_flow[11]; + open_res->param_flag = 0x08; + aa = 13; + for(ii = 0; ii < 4; ii++) + { + if(data_flow[aa] == 0x00) + break; + else if(data_flow[aa] == 0x01) // acn + { + open_res->acn_data.acn = data_flow[aa + 2]; + open_res->acn_data.acn_ver = data_flow[aa + 3]; + aa += 4; + open_res->param_flag |= 0x01; + } + else if(data_flow[aa] == 0x02) // specific info + { + len = data_flow[aa + 1]; + if(len >= MAX_SPCINFO_LEN) + return 0; + open_res->specific_info.info_len = len; + memcpy(open_res->specific_info.info_data, &data_flow[aa + 2], len); + open_res->param_flag |= 0x02; + aa += 2 + len; + } + else if(data_flow[aa] == 0x03) // refuse reason + { + open_res->refuse_reason = data_flow[aa + 2]; + open_res->param_flag |= 0x10; + aa += 3; + } + else if(data_flow[aa] == 0x04) // provider error + { + open_res->provider_error = data_flow[aa + 2]; + open_res->param_flag |= 0x20; + aa += 3; + } + else if(data_flow[aa] == 0x10) + { + delimiter_flag = 1; + aa += 2; + } + } + } + else + return 0; + break; + case MAP_CLOSE: + close_ptr = (MapClose_Arg *) & map_com->dlg_list.close_arg; + close_ptr->release_method = data_flow[11]; + close_ptr->param_flag = 0x01; + if(data_flow[13] == 0x01) + { + len = data_flow[14]; + if(len >= MAX_SPCINFO_LEN) + return 0; + close_ptr->specific_info.info_len = len; + memcpy(close_ptr->specific_info.info_data, &data_flow[15], len); + close_ptr->param_flag |= 0x02; + } + break; + case MAP_U_ABORT: + uabrt_ptr = (MapUAbort_Arg *) & map_com->dlg_list.uabort_arg; + uabrt_ptr->user_reason = data_flow[11]; + uabrt_ptr->param_flag = 0x01; + aa = 13; + for(ii = 0; ii < 2; ii++) + { + if(data_flow[aa] == 0) + break; + else if(data_flow[aa] == 0x01) // diagnostic flag + { + uabrt_ptr->diag_info = data_flow[aa + 2]; + uabrt_ptr->param_flag |= 0x02; + aa += 3; + } + else if(data_flow[aa] == 0x02) // specific info + { + len = data_flow[aa + 1]; + if(len >= MAX_SPCINFO_LEN) + return 0; + uabrt_ptr->specific_info.info_len = len; + memcpy(uabrt_ptr->specific_info.info_data, &data_flow[aa + 2], len); + uabrt_ptr->param_flag |= 0x04; + aa += 2 + len; + } + } + break; + case MAP_P_ABORT: + pabrt_ptr = (MapPAbort_Arg *) & map_com->dlg_list.pabort_arg; + pabrt_ptr->provider_reason = data_flow[11]; + pabrt_ptr->source = data_flow[12]; + pabrt_ptr->param_flag = 0x03; + break; + case MAP_NOTICE: + map_com->dlg_list.notice_arg.problem = data_flow[11]; + map_com->dlg_list.notice_arg.param_flag = 0x01; + break; + case MAP_DELIMITER: + case MAP_LINK: + break; + default: + return 0; + break; + } + if(delimiter_flag == 1) + return 2; + else + return 1; +} + +void cap_com_stof(struct MapComSrv_struct *com_ptr, u8 * data_flow, u8 delimiter_flag) +{ // transfer common structure to data flow + u32 ii; + u32 len; + struct MapOpen_Arg *open_arg; + struct MapOpen_Res *open_res; + struct MapClose_Arg *close_arg; + struct MapUAbort_Arg *uabrt_arg; + + data_flow[2] = CAP_FLAG; + data_flow[3] = com_ptr->port_id >> 8; + data_flow[4] = com_ptr->port_id; + data_flow[6] = com_ptr->dialogue_id >> 8; + data_flow[7] = com_ptr->dialogue_id; + data_flow[9] = com_ptr->message_type; + data_flow[10] = com_ptr->message_flag; + ii = 11; + switch (com_ptr->message_type) + { + case MAP_OPEN: + if(com_ptr->message_flag == MAP_INDICATE || com_ptr->message_flag == MAP_REQUEST) + { + open_arg = (MapOpen_Arg *) & com_ptr->dlg_list.open_arg; + data_flow[ii++] = open_arg->acn_data.acn; + data_flow[ii++] = open_arg->acn_data.acn_ver; + cap_set_sccpadd(&open_arg->peer_add, data_flow + ii); + ii += 28; + cap_set_sccpadd(&open_arg->local_add, data_flow + ii); + ii += 28; + data_flow[ii++] = 1; // optional point + if((open_arg->param_flag & 0x04)) // has peer reference address + { + data_flow[ii++] = 0x01; + len = open_arg->peerref_len; + data_flow[ii++] = len; + memcpy(data_flow + ii, open_arg->peer_reference, len); + ii += len; + } + if((open_arg->param_flag & 0x10)) // has local reference address + { + data_flow[ii++] = 0x02; + len = open_arg->localref_len; + data_flow[ii++] = len; + memcpy(data_flow + ii, open_arg->local_reference, len); + ii += len; + } + if((open_arg->param_flag & 0x20)) + { + data_flow[ii++] = 0x03; + len = open_arg->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow + ii, open_arg->specific_info.info_data, len); + ii += len; + } + if(delimiter_flag == 1) + { + data_flow[ii++] = 0x10; + data_flow[ii++] = 0x00; + } + data_flow[ii++] = 0x00; + } + else if(com_ptr->message_flag == MAP_RESPONSE || com_ptr->message_flag == MAP_CONFIRM) + { + open_res = (MapOpen_Res *) & com_ptr->dlg_list.open_res; + data_flow[ii++] = open_res->result; + data_flow[ii++] = 0x01; // optional point + if((open_res->param_flag & 0x01)) // has ACN + { + data_flow[ii++] = 0x01; + data_flow[ii++] = 2; + data_flow[ii++] = open_res->acn_data.acn; + data_flow[ii++] = open_res->acn_data.acn_ver; + } + if((open_res->param_flag & 0x02)) // has specific info + { + data_flow[ii++] = 0x02; + len = open_res->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow + ii, open_res->specific_info.info_data, len); + ii += len; + } + if((open_res->param_flag & 0x10)) // has refuse reason + { + data_flow[ii++] = 0x03; + data_flow[ii++] = 1; + data_flow[ii++] = open_res->refuse_reason; + } + if((open_res->param_flag & 0x20)) // has provider error + { + data_flow[ii++] = 0x04; + data_flow[ii++] = 1; + data_flow[ii++] = open_res->provider_error; + } + if(delimiter_flag == 1) + { + data_flow[ii++] = 0x10; + data_flow[ii++] = 0x00; + } + data_flow[ii++] = 0x00; + } + break; + case MAP_CLOSE: + close_arg = (MapClose_Arg *) & com_ptr->dlg_list.close_arg; + data_flow[ii++] = close_arg->release_method; + data_flow[ii++] = 0x01; // optional point + if((close_arg->param_flag & 0x02)) // has specific info + { + data_flow[ii++] = 0x01; + len = close_arg->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow + ii, close_arg->specific_info.info_data, len); + ii += len; + } + data_flow[ii++] = 0x00; + break; + case MAP_U_ABORT: + uabrt_arg = (MapUAbort_Arg *) & com_ptr->dlg_list.uabort_arg; + data_flow[ii++] = uabrt_arg->user_reason; + data_flow[ii++] = 0x01; // optional point + if((uabrt_arg->param_flag & 0x02)) + { + data_flow[ii++] = 0x01; + data_flow[ii++] = 1; + data_flow[ii++] = uabrt_arg->diag_info; + } + if((uabrt_arg->param_flag & 0x04)) // has specific info + { + data_flow[ii++] = 0x02; + len = uabrt_arg->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow + ii, uabrt_arg->specific_info.info_data, len); + ii += len; + } + data_flow[ii++] = 0x00; + break; + case MAP_P_ABORT: + data_flow[ii++] = com_ptr->dlg_list.pabort_arg.provider_reason; + data_flow[ii++] = com_ptr->dlg_list.pabort_arg.source; + break; + case MAP_NOTICE: + data_flow[ii++] = com_ptr->dlg_list.notice_arg.problem; + break; + default: + break; + } + ii -= 2; + data_flow[0] = ii >> 8; + data_flow[1] = ii; +} + +u8 cap_opr_ftos(struct MapOprData_struct *opr_ptr, u8 * data_flow) +{ // transfer opration data flow to structure + u32 aa; + u32 len; + u8 ii; + u8 delimiter_flag = 0; + + len = (data_flow[0] << 8) + data_flow[1]; + if(len < 10) + return 0; + if(data_flow[2] != CAP_FLAG) + return 0; + opr_ptr->port_id = (data_flow[3] << 8) + data_flow[4]; + opr_ptr->dialogue_id = (data_flow[6] << 8) + data_flow[7]; + opr_ptr->message_type = data_flow[9]; + opr_ptr->message_flag = data_flow[10]; + opr_ptr->invoke_id = data_flow[11]; + opr_ptr->param_flag = 0x1f; + opr_ptr->param_len = 0; + aa = 13; + for(ii = 0; ii < 2; ii++) + { + if(data_flow[aa] == 0x00) + break; + else if(data_flow[aa] == 0x01) // parameter + { + len = (data_flow[aa + 1] << 8) + data_flow[aa + 2]; + if(len > MAX_MAPPOPR_LEN) + return 0; + opr_ptr->param_len = len; + memcpy(opr_ptr->param, &data_flow[aa + 3], len); + aa += len + 3; + opr_ptr->param_flag |= 0x20; + } + else if(data_flow[aa] == 0x02) // user error + { + opr_ptr->user_error = data_flow[aa + 2]; + opr_ptr->param_flag |= 0x40; + aa += 3; + } + else if(data_flow[aa] == 0x03) // provider error + { + opr_ptr->provider_error = data_flow[aa + 2]; + opr_ptr->param_flag |= 0x80; + aa += 3; + } + else if(data_flow[aa] == 0x10) + { + delimiter_flag = 1; + aa += 2; + } + } + if(delimiter_flag == 1) + return 2; + else + return 1; +} + +void cap_opr_stof(struct MapOprData_struct *opr_ptr, u8 * data_flow, u8 delimiter_flag) +{ // transfer opration structure to data flow + u32 ii; + u32 len; + + data_flow[2] = CAP_FLAG; + data_flow[3] = opr_ptr->port_id >> 8; + data_flow[4] = opr_ptr->port_id; + data_flow[6] = opr_ptr->dialogue_id >> 8; + data_flow[7] = opr_ptr->dialogue_id; + data_flow[9] = opr_ptr->message_type; + data_flow[10] = opr_ptr->message_flag; + data_flow[11] = opr_ptr->invoke_id; + data_flow[12] = 1; + ii = 13; + if((opr_ptr->param_flag & 0x20)) // has component + { + data_flow[ii++] = 0x01; + len = opr_ptr->param_len; + data_flow[ii++] = len >> 8; + data_flow[ii++] = len; + memcpy(data_flow + ii, opr_ptr->param, len); + ii += len; + } + if((opr_ptr->param_flag & 0x40)) // has user error + { + data_flow[ii++] = 0x02; + data_flow[ii++] = 1; + data_flow[ii++] = opr_ptr->user_error; + } + if((opr_ptr->param_flag & 0x80)) // has provider error + { + data_flow[ii++] = 0x03; + data_flow[ii++] = 1; + data_flow[ii++] = opr_ptr->provider_error; + } + if(delimiter_flag == 1) + { + data_flow[ii++] = 0x10; + data_flow[ii++] = 0x00; + } + data_flow[ii++] = 0; + ii -= 2; + data_flow[0] = ii >> 8; + data_flow[1] = ii; +} diff --git a/plat/xapp/src/capp/cap_public.h b/plat/xapp/src/capp/cap_public.h new file mode 100644 index 0000000..33fa7e0 --- /dev/null +++ b/plat/xapp/src/capp/cap_public.h @@ -0,0 +1,14 @@ +/* CAP public function head file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#ifndef _CAP_PUBLIC +#define _CAP_PUBLIC + +u8 cap_com_ftos(struct MapComSrv_struct *map_com, u8 * data_flow); +void cap_com_stof(struct MapComSrv_struct *com_ptr, u8 * data_flow, u8 delimiter_flag); +u8 cap_opr_ftos(struct MapOprData_struct *opr_ptr, u8 * data_flow); +void cap_opr_stof(struct MapOprData_struct *opr_ptr, u8 * data_flow, u8 delimiter_flag); + +#endif diff --git a/plat/xapp/src/capp/icap.h b/plat/xapp/src/capp/icap.h new file mode 100644 index 0000000..bc9d2e7 --- /dev/null +++ b/plat/xapp/src/capp/icap.h @@ -0,0 +1,20 @@ +/* CAP message interface head file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#ifndef _CAP_INTERFACE +#define _CAP_INTERFACE + +#include "cap_head.h" +#include "cap_msg.h" + +int encode_capmsg(struct CapArg caparg, u8 * msgbuf, u16 maxlen); + +#ifdef _SRF_RELEVANT +int decode_capmsg(char *msgbuf, u16 msglen, u8 ocode, u8 otype, struct CapArg *pcaparg); +#else +int decode_capmsg(char *msgbuf, u16 msglen, u8 ocode, struct CapArg *pcaparg); +#endif + +#endif diff --git a/plat/xapp/src/conv_prefix.c b/plat/xapp/src/conv_prefix.c new file mode 100644 index 0000000..a1113db --- /dev/null +++ b/plat/xapp/src/conv_prefix.c @@ -0,0 +1,1323 @@ +#include +#include +#include +#include + +#include "../../snmp/src/include/snmp.h" +#include "../../snmp/src/include/macro.h" + +#include "conv_prefix.h" +#include "../../public/src/uwav/numgrp.h" +#include "../../public/src/uwav/number.h" + +_conv_prefix conv_prefix; + +#define ASN_1_OCTET_STRING 4 +#define ASN_1_INTEGER 2 +struct numgrp_table *xapp_grptab_ptr=NULL; + +int xappSearchGroupTable(char *msisdn_unk); +int xappCreateGroupPrefixTable(); +extern int xap_get_response(u8 oidlen,u32 *oid,u8 *pdata,u8 *vartype); +extern int xap_set_response(u8 oidlen,u32 *oid,u8 *pdata,u16 datalen); +extern void xap_set_conv_param_flag(); + +extern void StringCut(char *str, int c); +/*------------------------------------------------------------------*/ + +int readConvPrefixConf() +{ + char filename[]="./conf/conv_prefix.conf"; + FILE *fpConf = NULL; + int i; + + fpConf = fopen(filename,"r"); + if(fpConf == NULL) return 0; + fread(&conv_prefix,sizeof(_conv_prefix),1,fpConf); + fclose(fpConf); +/* + for(i=0;i=MAX_CONV_PREFIX) return 0; + if(datalen<19) return 0; + + conv_prefix.conv_prefix[instance].used_flag = 1; + memcpy(conv_prefix.conv_prefix[instance].prefix,pdata,16); + conv_prefix.conv_prefix[instance].delete_length = pdata[16]; + conv_prefix.conv_prefix[instance].add_length = pdata[17]; + memcpy(conv_prefix.conv_prefix[instance].add_digits,&pdata[18],16); + conv_prefix.conv_prefix[instance].valid_length = pdata[34]; + if(datalen==43) + { + memset(conv_prefix.conv_name[instance],0,MAX_NAME_LEN); + memcpy(conv_prefix.conv_name[instance],&pdata[35],MAX_NAME_LEN); + } + if(instance == MAX_CONV_PREFIX-1) saveConvPrefix(); + return datalen; +} + +int snmpGetConvPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype) +{ + u32 instance; + + *vartype = 0x04; + if(oidlen<16) return 0; + instance = oid[15]; + memcpy(pdata,conv_prefix.conv_prefix[instance].prefix,16); + pdata[16] = conv_prefix.conv_prefix[instance].delete_length; + pdata[17] = conv_prefix.conv_prefix[instance].add_length; + memcpy(&pdata[18],conv_prefix.conv_prefix[instance].add_digits,16); + pdata[34] = conv_prefix.conv_prefix[instance].valid_length; + memcpy(&pdata[35],conv_prefix.conv_name[instance],MAX_NAME_LEN); + return 35+8; +} + +int snmpSetCliPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen) +{ + u32 instance; + + if(oidlen<15) return 0; + instance = oid[14]; + if(instance>=MAX_CLI_PREFIX) return 0; + if(datalen<19) return 0; + + conv_prefix.cli_prefix[instance].in_property = pdata[0]; + memcpy(conv_prefix.cli_prefix[instance].prefix,&pdata[1],16); + conv_prefix.cli_prefix[instance].delete_length = pdata[17]; + conv_prefix.cli_prefix[instance].out_property = pdata[18]; + conv_prefix.cli_prefix[instance].add_length = pdata[19]; + memcpy(conv_prefix.cli_prefix[instance].add_digits,&pdata[20],16); + conv_prefix.cli_prefix[instance].valid_length = pdata[36]; + if(datalen == 45) + { + memset(conv_prefix.cli_name[instance],0,MAX_NAME_LEN); + memcpy(conv_prefix.cli_name[instance],&pdata[37],MAX_NAME_LEN); + } + if(instance == MAX_CLI_PREFIX-1) saveConvPrefix(); + return datalen; +} + +int snmpGetCliPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype) +{ + u32 instance; + + *vartype = 0x04; + if(oidlen<15) return 0; + instance = oid[14]; + if(instance>=MAX_CLI_PREFIX) return 0; + pdata[0] = conv_prefix.cli_prefix[instance].in_property; + memcpy(&pdata[1],conv_prefix.cli_prefix[instance].prefix,16); + pdata[17] = conv_prefix.cli_prefix[instance].delete_length; + pdata[18] = conv_prefix.cli_prefix[instance].out_property; + pdata[19] = conv_prefix.cli_prefix[instance].add_length; + memcpy(&pdata[20],conv_prefix.cli_prefix[instance].add_digits,16); + pdata[36] = conv_prefix.cli_prefix[instance].valid_length; + memcpy(&pdata[37],conv_prefix.cli_name[instance],MAX_NAME_LEN); + return 37+8; +} + +int msisdnUnkToInt(char *msisdn_unk, char *msisdn_int) +/* return value: + -1 = error length; + 0 = cannn't find appropriate prefix; + 1 = conv. succeed +*/ +{ + int retval = 0, index = -1; + int loop,len=0,max_len=0,old_len; + int delete_len,add_len; + + index = xappSearchGroupTable(msisdn_unk); + if(index>=0) + { + char tmpStart[17],tmpEnd[17]; + + strcpy(tmpStart,msisdn_unk); + tmpStart[conv_prefix.group_conv_prefix[index].repStartDigit] = 0; + + strcpy(tmpEnd,&msisdn_unk[conv_prefix.group_conv_prefix[index].repEndDigit]); + + sprintf(msisdn_int,"%s%s%s", + tmpStart, + conv_prefix.group_conv_prefix[index].repDigitWith, + tmpEnd); + + return 1; + } + for(loop=0;loop0) + { + if(len>max_len) + if(strncasecmp(msisdn_unk, + conv_prefix.conv_prefix[loop].prefix, + len)==0) + { + max_len = len; + index = loop; + }//cmp + }//len>0 + }//used + } + + if(index>=0 && index24) len = 24; + old_len = len; + + /* + len = strlen(msisdn_unk); + + if(len>24) len = 24; + old_len = len; + for(loop=len-1;loop>2;loop--) + { + if(toupper(msisdn_unk[loop])>'C') + len --; + else + break; + } + */ + if(conv_prefix.conv_prefix[index].valid_length>0) + { + if(len != conv_prefix.conv_prefix[index].valid_length) + { + strcpy(msisdn_int,msisdn_unk); + return -1; + } + } + delete_len = conv_prefix.conv_prefix[index].delete_length; + if(delete_len>len) + { + strcpy(msisdn_int,msisdn_unk); + return -1; + } + + add_len = conv_prefix.conv_prefix[index].add_length; + if(add_len != strlen(conv_prefix.conv_prefix[index].add_digits)) + { + strcpy(msisdn_int,msisdn_unk); + return -1; + } + strcpy(msisdn_int, + conv_prefix.conv_prefix[index].add_digits); + strcat(msisdn_int, + &msisdn_unk[delete_len]); + msisdn_int[add_len+old_len-delete_len] = 0; + retval = 1; + } + return retval; +} + +int cliUptoCalled(char *caller, char *called) +{ + char callerBuf[128],tmpBuf[128];//tmpBuf1[128]; + int loop0=0,loop=0,index=-1,index1=-1;/*1=91 IDD,2=A1 NDD,3=81 UNK*/ + int len=0,maxlen=0,delete_len=0, add_len=0; + int times = 1; + + if(called != NULL) + times = 2; + + strcpy(callerBuf,caller); +// msisdnUnkToInt(callerBuf,caller); + for(loop0=0;loop00 && len>maxlen) + if(len>0 ) + { + if(loop0==0) + { + if(strncasecmp(caller, + tmpBuf, + len)==0) + { + index1 = loop; + if(len > maxlen) + maxlen = len; + }//cmp + }else + { + if(strncasecmp(called, + tmpBuf, + len)==0) + { + index = loop; + if(len > maxlen) + maxlen = len; + }//cmp + } + }//len>0 + } + } + + if(index1>=0 && index>=0) + { + len = strlen(caller); + delete_len = conv_prefix.cli_prefix[index1].delete_length; + if(delete_len>len) + { + return -1; + } + add_len = conv_prefix.cli_prefix[index1].add_length; + if(add_len != strlen(conv_prefix.cli_prefix[index1].add_digits)) + { + return -1; + } + if(conv_prefix.cli_prefix[index1].out_property == 1) + { + sprintf(caller,"91"); + }else if(conv_prefix.cli_prefix[index1].out_property == 2) + { + sprintf(caller,"a1"); + }else if(conv_prefix.cli_prefix[index1].out_property == 3) + { + sprintf(caller,"81"); + }else + sprintf(caller,"81"); + strcat(caller, + conv_prefix.cli_prefix[index1].add_digits); + strcat(caller, + &callerBuf[delete_len+2]); + len = strlen(callerBuf); + caller[add_len+len-delete_len] = 0; + } + return 1; +} + + +int snmpSetPlatName(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen) +{ + u32 instance; + + if(oidlen<15) return 0; + instance = oid[14]; + if(instance>=MAX_PLAT_NAME_INSTANCE) return 0; + if(datalen != MAX_PLAT_NAME_LEN) return 0; + memcpy(conv_prefix.plat_name[instance],pdata,MAX_PLAT_NAME_LEN); + if(instance == MAX_PLAT_NAME_INSTANCE-1) + saveConvPrefix(); + + return datalen; +} + + +int snmpGetPlatName(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype) +{ + u32 instance; + + *vartype = 0x04; + if(oidlen<15) return 0; + instance = oid[14]; + if(instance>=MAX_PLAT_NAME_INSTANCE) return 0; + + memcpy(pdata,conv_prefix.plat_name[instance],MAX_PLAT_NAME_LEN); + return MAX_PLAT_NAME_LEN; +} + + +int snmpSetGroupConvPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen) +{ + u32 instance; + int len=0, invalid_flag=0; + _xapp_group_prefix tempGroupPrefix; + + if(oidlen<16) return 0; + instance = oid[15]; + if(instance>=MAX_CONV_PREFIX) return 0; + if(datalen<50) return 0; + + memset(&tempGroupPrefix,0,sizeof(_xapp_group_prefix)); + + len = 0; + memcpy(tempGroupPrefix.startNumber,&pdata[len],MAX_PREFIX_LEN); + len += MAX_PREFIX_LEN; + memcpy(tempGroupPrefix.endNumber,&pdata[len],MAX_PREFIX_LEN); + len += MAX_PREFIX_LEN; + tempGroupPrefix.repStartDigit = pdata[len]; + len += 1; + tempGroupPrefix.repEndDigit = pdata[len]; + len += 1; + memcpy(tempGroupPrefix.repDigitWith,&pdata[len],MAX_PREFIX_LEN); + //check validity + if(tempGroupPrefix.repStartDigit>tempGroupPrefix.repEndDigit) + invalid_flag = 1; + if(strcmp(tempGroupPrefix.startNumber,tempGroupPrefix.endNumber)>0) + { + invalid_flag = 1; + } + if(invalid_flag) + { + sprintf((char *)pdata,"Error parameter, start>end!"); + return -2; + } + + memcpy(&conv_prefix.group_conv_prefix[instance],&tempGroupPrefix,sizeof(_xapp_group_prefix)); + + if(instance == MAX_CONV_PREFIX-1){ + saveConvPrefix(); + xappCreateGroupPrefixTable(); + } + + return datalen; +} + +int snmpGetGroupConvPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype) +{ + u32 instance; + int len = 0; + + *vartype = 0x04; + if(oidlen<16) return 0; + instance = oid[15]; + if(instance>=MAX_CONV_PREFIX) return 0; + + memcpy(&pdata[len],conv_prefix.group_conv_prefix[instance].startNumber,MAX_PREFIX_LEN); + len += MAX_PREFIX_LEN; + memcpy(&pdata[len],conv_prefix.group_conv_prefix[instance].endNumber,MAX_PREFIX_LEN); + len += MAX_PREFIX_LEN; + pdata[len] = conv_prefix.group_conv_prefix[instance].repStartDigit; + len += 1; + pdata[len] = conv_prefix.group_conv_prefix[instance].repEndDigit; + len += 1; + memcpy(&pdata[len],conv_prefix.group_conv_prefix[instance].repDigitWith,MAX_PREFIX_LEN); + len += MAX_PREFIX_LEN; + return len; +} + +int xappCreateGroupPrefixTable() +{ + int i,len; + struct number_group tmp_num_grp; + + if(xapp_grptab_ptr != NULL) + delete_numgrp_table(xapp_grptab_ptr); + + xapp_grptab_ptr = assign_numgrp_table("xapp",MAX_CONV_PREFIX); + for(i=0;iMAX_PREFIX_LEN) + continue; + len = strlen(conv_prefix.group_conv_prefix[i].startNumber); + tmp_num_grp.start.num_of_digit = len; + memcpy(tmp_num_grp.start.digit,conv_prefix.group_conv_prefix[i].startNumber,len); + + len = strlen(conv_prefix.group_conv_prefix[i].endNumber); + tmp_num_grp.end.num_of_digit = len; + memcpy(tmp_num_grp.end.digit,conv_prefix.group_conv_prefix[i].endNumber,len); + tmp_num_grp.index = i; + + numgrp_insert(xapp_grptab_ptr, + &tmp_num_grp.start, + &tmp_num_grp.end, + tmp_num_grp.index); + } + return 0; +} + +int xappSearchGroupTable(char *msisdn_unk) +{ + num16_t num16_tmp; + int tmpResult; + int len; + char tmp_number[32]; + + if(xapp_grptab_ptr==NULL) return -1; + + strcpy(tmp_number,msisdn_unk); + StringCut(tmp_number,'E'); + len = strlen(tmp_number); + + if(len==0) return -1; + if(len>MAX_PREFIX_LEN) len = MAX_PREFIX_LEN; + num16_tmp.num_of_digit = len; + memcpy(num16_tmp.digit,tmp_number,len); + if(numgrp_search(&tmpResult,xapp_grptab_ptr,&num16_tmp)) + return tmpResult; + return -1; +} + +/* -----------------------------------------------------------------------------------------*/ +/* -- following codes support XAPP mib structrue, refer to XAPP mib definition for detail --*/ +/* -- record @2008-10-29 --*/ +/* -----------------------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------*/ +/* ------------------------ function: xap_get_idle_index() -------------------*/ +/* -- type1=manipulation prefix, type2=manipulation group, type3=cli prefix --*/ +/* -- return =0 ,failed, otherwise succeed -----------------------------------*/ +/* ---------------------------------------------------------------------------*/ +int xap_get_idle_index(int type, int *newID) +{ + int i; + + switch(type) + { + case 1: + for(i=1;i= MAX_CONV_PREFIX + || conv_prefix.conv_prefix[index].used_flag == FALSE) + return -1; + + *vartype = ASN_1_OCTET_STRING; + switch(column) + { + case 1: /* index */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: /* title */ + datalen = strlen(conv_prefix.conv_name[index]); + memcpy(pdata,conv_prefix.conv_name[index],datalen); + //if(datalen == 0) datalen = 1; + break; + case 3: /* prefix */ + datalen = strlen(conv_prefix.conv_prefix[index].prefix); + memcpy(pdata,conv_prefix.conv_prefix[index].prefix,datalen); + break; + case 4: /* delete count */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.conv_prefix[index].delete_length; + break; + case 5:/* insert count */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.conv_prefix[index].add_length; + break; + case 6: /* insert digits */ + datalen = strlen(conv_prefix.conv_prefix[index].add_digits); + memcpy(pdata,conv_prefix.conv_prefix[index].add_digits,datalen); + break; + case 7: /* number length */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.conv_prefix[index].valid_length; + break; + case 8: /* status */ + *vartype = ASN_1_INTEGER; + pdata[0] = 1; /* active */ + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +void set_default_xap_prefix_entry(int index) +{ + conv_prefix.conv_prefix[index].used_flag = TRUE; + sprintf(conv_prefix.conv_name[index],"Prx_%d",index); + //sprintf(conv_prefix.conv_prefix[index].prefix," "); +} + +int xap_set_manPrefix(u32 column, u32 *instance, u_char *pdata, unsigned short datalen) +{ + int index; + //int newId; + + //if(datalen == 0) + // return -1; + + index = instance[0]; + if(index < 0 || index >= MAX_CONV_PREFIX) + return -1; + xap_set_conv_param_flag(); + switch(column) + { + case 1:/* create */ + /* + if(xap_get_idle_index(1, &newId)) + { + conv_prefix.conv_prefix[index].used_flag = TRUE; + return newId; + } + else + return -1; + */ + index = pdata[0]; + if(index < 0 || index >= MAX_CONV_PREFIX) + return -1; + //if(conv_prefix.conv_prefix[index].used_flag) + // return -1; + set_default_xap_prefix_entry(index); + break; + case 2: /* title */ + if(datalen>=MAX_NAME_LEN) + datalen = MAX_NAME_LEN-1; + memset(conv_prefix.conv_name[index], 0, MAX_NAME_LEN); + memcpy(conv_prefix.conv_name[index], pdata, datalen); + break; + case 3: /* prefix */ + if(datalen>=MAX_PREFIX_LEN) + return -1; + memset(conv_prefix.conv_prefix[index].prefix, 0, MAX_PREFIX_LEN); + memcpy(conv_prefix.conv_prefix[index].prefix, pdata, datalen); + break; + case 4: /* delete count */ + if(pdata[0]>=MAX_PREFIX_LEN) + return -1; + conv_prefix.conv_prefix[index].delete_length = pdata[0]; + break; + case 5: /* insert count */ + if(pdata[0]>=MAX_PREFIX_LEN) + return -1; + conv_prefix.conv_prefix[index].add_length = pdata[0]; + break; + case 6: /* insert digits */ + if(datalen>=MAX_PREFIX_LEN) + return -1; + memset(conv_prefix.conv_prefix[index].add_digits, 0, MAX_PREFIX_LEN); + memcpy(conv_prefix.conv_prefix[index].add_digits, pdata, datalen); + break; + case 7: /* number length */ + if(pdata[0]>=MAX_PREFIX_LEN) + return -1; + conv_prefix.conv_prefix[index].valid_length = pdata[0]; + //saveConvPrefix(); + break; + case 8: /* status */ + if(pdata[0] == 6) /* 6==delete */ + { + memset(&conv_prefix.conv_prefix[index],0,sizeof(_conv_prefix_record)); + memset(conv_prefix.conv_name[index], 0, MAX_NAME_LEN); + // saveConvPrefix(); + } + break; + default: + return -1; + break; + } + return datalen; +} + +/*------------------*/ +/*-- group routines --*/ +/*------------------*/ + +int xap_getnext_groupPrefix(u32 *index_id) +{ + int i; + + for(i = *index_id; i < MAX_CONV_PREFIX; i++) + { + if(conv_prefix.group_conv_prefix[i].used_flag) + { + *index_id = i; + return 1; + } + } + *index_id = 0; + return 0; +} + +int xap_get_groupPrefix(u32 column, u32 *instance, u_char *pdata, u_char *vartype) +{ + int datalen = 0,index; + + index = instance[0]; + if(index < 0 || index >= MAX_CONV_PREFIX + || conv_prefix.group_conv_prefix[index].used_flag == 0) + return -1; + + *vartype = ASN_1_OCTET_STRING; + switch(column) + { + case 1: /* index */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: /* title, this define inhert...not reasonable */ + datalen = strlen(conv_prefix.plat_name[index]); + memcpy(pdata,conv_prefix.plat_name[index],datalen); + //if(datalen == 0) datalen = 1; + break; + case 3: /* start number */ + datalen = strlen(conv_prefix.group_conv_prefix[index].startNumber); + memcpy(pdata,conv_prefix.group_conv_prefix[index].startNumber,datalen); + break; + case 4: /* end number */ + datalen = strlen(conv_prefix.group_conv_prefix[index].endNumber); + memcpy(pdata,conv_prefix.group_conv_prefix[index].endNumber,datalen); + break; + case 5:/* replace digit start */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.group_conv_prefix[index].repStartDigit; + break; + case 6: /* replace digit end */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.group_conv_prefix[index].repEndDigit; + break; + case 7: /* replace digit with */ + datalen = strlen(conv_prefix.group_conv_prefix[index].repDigitWith); + memcpy(pdata,conv_prefix.group_conv_prefix[index].repDigitWith,datalen); + break; + case 8: /* lock flag */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.group_conv_prefix[index].status; + break; + case 9: /* status */ + *vartype = ASN_1_INTEGER; + pdata[0] = 1; /* active */ + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +void set_default_xap_groupprefix_entry(int index) +{ + if(index < 0 || index >= MAX_CONV_PREFIX) + return; + conv_prefix.group_conv_prefix[index].used_flag = 1; + sprintf(conv_prefix.plat_name[index],"Grp_%d",index); + +} + +int xap_set_groupPrefix(u32 column, u32 *instance, u_char *pdata, unsigned short datalen) +{ + int index; + //int newId; + + //if(datalen == 0 ) + // return -1; + + index = instance[0]; + if(index < 0 || index >= MAX_CONV_PREFIX) + return -1; + xap_set_conv_param_flag(); + switch(column) + { + case 1:/* create */ + /* + if(xap_get_idle_index(2, &newId)) + { + return newId; + } + else + return -1; + */ + index = pdata[0]; + if(index < 0 || index >= MAX_CONV_PREFIX) + return -1; + //if(conv_prefix.group_conv_prefix[index].used_flag) + // return -1; + set_default_xap_groupprefix_entry(index); + break; + case 2: /* title */ + if(datalen>=MAX_NAME_LEN) + datalen = MAX_NAME_LEN - 1; + memset(conv_prefix.plat_name[index], 0, MAX_NAME_LEN); + memcpy(conv_prefix.plat_name[index], pdata, datalen); + break; + case 3: /* start number */ + if(datalen>MAX_PREFIX_LEN) return -1; + memset(conv_prefix.group_conv_prefix[index].startNumber, 0, MAX_PREFIX_LEN+1); + memcpy(conv_prefix.group_conv_prefix[index].startNumber,pdata,datalen); + break; + case 4: /* end number */ + if(datalen>MAX_PREFIX_LEN) return -1; + memset(conv_prefix.group_conv_prefix[index].endNumber, 0, MAX_PREFIX_LEN+1); + memcpy(conv_prefix.group_conv_prefix[index].endNumber,pdata,datalen); + break; + case 5:/* replace digit start */ + if(datalen>=MAX_PREFIX_LEN) return -1; + conv_prefix.group_conv_prefix[index].repStartDigit = pdata[0]; + break; + case 6: /* replace digit end */ + if(datalen>=MAX_PREFIX_LEN) return -1; + conv_prefix.group_conv_prefix[index].repEndDigit = pdata[0]; + break; + case 7: /* replace digit with */ + if(datalen>MAX_PREFIX_LEN) return -1; + memset(conv_prefix.group_conv_prefix[index].repDigitWith, 0, MAX_PREFIX_LEN+1); + memcpy(conv_prefix.group_conv_prefix[index].repDigitWith,pdata,datalen); + break; + case 8: /* lock flag */ /* here, create table should be more technical, but... */ + conv_prefix.group_conv_prefix[index].status = pdata[0] ; + xappCreateGroupPrefixTable(); + //saveConvPrefix(); + break; + case 9: /* status */ + if(pdata[0] == 6) /* 6==delete */ + { + memset(&conv_prefix.group_conv_prefix[index],0,sizeof(_xapp_group_prefix)); + memset(conv_prefix.plat_name[index], 0, MAX_NAME_LEN); + xappCreateGroupPrefixTable(); + //saveConvPrefix(); + } + break; + default: + return -1; + break; + } + return datalen; +} + +/* ------------------*/ +/* -- local msisdn -----*/ +/* ------------------*/ + +int xap_getnext_local_msisdn(u32 *index_id) +{ + int i; + + for(i = *index_id; i < MAX_LOCAL_MSISDN_SEG; i++) + { + if(conv_prefix.local_msisdn_segment[i].used_flag) + { + *index_id = i; + return 1; + } + } + *index_id = 0; + return 0; +} + +int xap_get_local_msisdn(u32 column, u32 *instance, u_char *pdata, u_char *vartype) +{ + int datalen = 0,index; + + index = instance[0]; + if(index < 0 || index >= MAX_LOCAL_MSISDN_SEG + || conv_prefix.local_msisdn_segment[index].used_flag == 0) + return -1; + + *vartype = ASN_1_OCTET_STRING; + switch(column) + { + case 1: /* index */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: /* title, this define inhert...not reasonable */ + datalen = strlen(conv_prefix.msisdn_segment_name[index]); + memcpy(pdata,conv_prefix.msisdn_segment_name[index],datalen); + //if(datalen == 0) datalen = 1; + break; + case 3: /* start number */ + datalen = strlen(conv_prefix.local_msisdn_segment[index].startNumber); + memcpy(pdata,conv_prefix.local_msisdn_segment[index].startNumber,datalen); + break; + case 4: /* end number */ + datalen = strlen(conv_prefix.local_msisdn_segment[index].endNumber); + memcpy(pdata,conv_prefix.local_msisdn_segment[index].endNumber,datalen); + break; + case 5: /* lock flag */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.local_msisdn_segment[index].status; + break; + case 6: /* status */ + *vartype = ASN_1_INTEGER; + pdata[0] = 1; /* active */ + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +void set_default_xap_local_msisdn_entry(int index) +{ + if(index < 0 || index >= MAX_LOCAL_MSISDN_SEG) + return; + conv_prefix.local_msisdn_segment[index].used_flag = 1; + sprintf(conv_prefix.msisdn_segment_name[index],"msisdn_seg#%d",index); + +} + +int xap_set_local_msisdn(u32 column, u32 *instance, u_char *pdata, unsigned short datalen) +{ + int index; + //int newId; + + //if(datalen == 0 ) + // return -1; + + index = instance[0]; + if(index < 0 || index >= MAX_LOCAL_MSISDN_SEG) + return -1; + xap_set_conv_param_flag(); + switch(column) + { + case 1:/* create */ + /* + if(xap_get_idle_index(2, &newId)) + { + return newId; + } + else + return -1; + */ + index = pdata[0]; + if(index < 0 || index >= MAX_LOCAL_MSISDN_SEG) + return -1; + //if(conv_prefix.group_conv_prefix[index].used_flag) + // return -1; + set_default_xap_local_msisdn_entry(index); + break; + case 2: /* title */ + if(datalen>=MAX_PLAT_NAME_LEN) + datalen = MAX_PLAT_NAME_LEN - 1; + memset(conv_prefix.msisdn_segment_name[index], 0, MAX_PLAT_NAME_LEN); + memcpy(conv_prefix.msisdn_segment_name[index], pdata, datalen); + break; + case 3: /* start number */ + if(datalen>MAX_PREFIX_LEN) return -1; + memset(conv_prefix.local_msisdn_segment[index].startNumber, 0, MAX_PREFIX_LEN+1); + memcpy(conv_prefix.local_msisdn_segment[index].startNumber,pdata,datalen); + break; + case 4: /* end number */ + if(datalen>MAX_PREFIX_LEN) return -1; + memset(conv_prefix.local_msisdn_segment[index].endNumber, 0, MAX_PREFIX_LEN+1); + memcpy(conv_prefix.local_msisdn_segment[index].endNumber,pdata,datalen); + break; + case 5: /* status */ + if(pdata[0] == 6) /* 6==delete */ + { + memset(&conv_prefix.local_msisdn_segment[index],0,sizeof(_xapp_local_msisdn)); + memset(conv_prefix.msisdn_segment_name[index], 0, MAX_PLAT_NAME_LEN); + } + break; + default: + return -1; + break; + } + return datalen; +} + + +int xappCheckIfLocalMSISDN(char *msisdn) +{ + int retval = 0; + int index; + + if(msisdn == NULL) return retval; + if(strlen(msisdn) == 0) return retval; + + for(index=0;index=0) + { + retval = 1; + break; + } + } + + return retval; +} + +/* --local msisdn end --*/ + + + + +/*------------------*/ +/*-- cli routines --*/ +/*------------------*/ + +int xap_getnext_cliPrefix(u32 *index_id) +{ + int i; + + for(i = *index_id; i < MAX_CLI_PREFIX; i++) + { + if(conv_prefix.cli_prefix[i].used_flag) + { + *index_id = i; + return 1; + } + } + *index_id = 0; + return 0; +} + +int xap_get_cliPrefix(u32 column, u32 *instance, u_char *pdata, u_char *vartype) +{ + int datalen = 0,index; + + index = instance[0]; + if(index < 0 || index >= MAX_CLI_PREFIX + || conv_prefix.cli_prefix[index].used_flag == 0) + return -1; + + *vartype = ASN_1_OCTET_STRING; + switch(column) + { + case 1: /* index */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: /* title */ + datalen = strlen(conv_prefix.cli_name[index]); + if(datalen>MAX_NAME_LEN) datalen = MAX_NAME_LEN; + memcpy(pdata,conv_prefix.cli_name[index],datalen); + //if(datalen == 0) datalen = 1; + break; + case 3: /* o nai */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.cli_prefix[index].in_property; + break; + case 4: /* prefix */ + datalen = strlen(conv_prefix.cli_prefix[index].prefix); + memcpy(pdata,conv_prefix.cli_prefix[index].prefix,datalen); + //if(datalen == 0) datalen = 1; + break; + case 5: /* delete count */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.cli_prefix[index].delete_length; + break; + case 6: + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.cli_prefix[index].out_property; + break; + case 7:/* add count */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.cli_prefix[index].add_length; + break; + case 8: /* insert digits */ + datalen = strlen(conv_prefix.cli_prefix[index].add_digits); + memcpy(pdata,conv_prefix.cli_prefix[index].add_digits,datalen); + break; + case 9: /* number length */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = conv_prefix.cli_prefix[index].valid_length; + break; + case 10: /* status */ + *vartype = ASN_1_INTEGER; + pdata[0] = 1; /* active */ + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + +void set_default_xap_cliprefix_entry(int index) +{ + conv_prefix.cli_prefix[index].used_flag = 1; + sprintf(conv_prefix.cli_name[index],"Cli_%d",index); +} + +int xap_set_cliPrefix(u32 column, u32 *instance, u_char *pdata, unsigned short datalen) +{ + int index; + //int newId; + +// if(datalen == 0) +// return -1; + + index = instance[0]; + if(index < 0 || index >= MAX_CLI_PREFIX) + return -1; + xap_set_conv_param_flag(); + switch(column) + { + case 1:/* create */ + /* + if(xap_get_idle_index(3, &newId)) + { + return newId; + } + else + return -1; + */ + index = pdata[0]; + if(index < 0 || index >= MAX_CLI_PREFIX) + return -1; + //if(conv_prefix.cli_prefix[index].used_flag) + // return -1; + set_default_xap_cliprefix_entry(index); + break; + case 2: /* title */ + if(datalen>MAX_NAME_LEN) + datalen = MAX_NAME_LEN ; + memset(conv_prefix.cli_name[index], 0, MAX_NAME_LEN); + memcpy(conv_prefix.cli_name[index], pdata, datalen); + break; + case 3: /* in nai */ + conv_prefix.cli_prefix[index].in_property = pdata[0] ; + break; + case 4: /* prefix */ + if(datalen>=MAX_PREFIX_LEN) + return -1; + memset(conv_prefix.cli_prefix[index].prefix, 0, MAX_PREFIX_LEN); + memcpy(conv_prefix.cli_prefix[index].prefix, pdata, datalen); + break; + case 5: /* delete count */ + if(pdata[0]>=MAX_PREFIX_LEN) + return -1; + conv_prefix.cli_prefix[index].delete_length = pdata[0]; + break; + case 6: /* out nai */ + conv_prefix.cli_prefix[index].out_property = pdata[0] ; + break; + case 7: /* insert count */ + if(pdata[0]>=MAX_PREFIX_LEN) + return -1; + conv_prefix.cli_prefix[index].add_length = pdata[0]; + break; + case 8: /* insert digits */ + if(datalen>MAX_PREFIX_LEN-1) + return -1; + memset(conv_prefix.cli_prefix[index].add_digits, 0, MAX_PREFIX_LEN-1); + memcpy(conv_prefix.cli_prefix[index].add_digits, pdata, datalen); + break; + case 9: /* number length */ + if(pdata[0]>=MAX_PREFIX_LEN) + return -1; + conv_prefix.cli_prefix[index].valid_length = pdata[0]; + saveConvPrefix(); + break; + case 10: /* status */ + if(pdata[0] == 6) /* 6==delete */ + { + memset(&conv_prefix.cli_prefix[index],0,sizeof(_cli_prefix)); + memset(conv_prefix.cli_name[index], 0, MAX_NAME_LEN); + //saveConvPrefix(); + } + break; + default: + return -1; + break; + } + return datalen; +} + + +static struct snmp_table_profile xapp_tables[] = { + { + .name = "xappManPrefix", + .index.len = 11+3, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,2,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 0}, + .level = 1, + .get_instance = xap_getnext_manPrefix, + .get_resp = xap_get_manPrefix, + .set_resp = xap_set_manPrefix + }, + { + .name = "xappManGroup", + .index.len = 11+3, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,3,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, + .level = 1, + .get_instance = xap_getnext_groupPrefix, + .get_resp = xap_get_groupPrefix, + .set_resp = xap_set_groupPrefix + }, + { + .name = "xappCliPrefix", + .index.len = 11+3, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,4,1}, + .column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0}, + .level = 1, + .get_instance = xap_getnext_cliPrefix, + .get_resp = xap_get_cliPrefix, + .set_resp = xap_set_cliPrefix + }, + { + .name = "localMSISDN", + .index.len = 11+3, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,5,1}, + .column = {1, 2, 3, 4, 5, 0}, + .level = 1, + .get_instance = xap_getnext_local_msisdn, + .get_resp = xap_get_local_msisdn, + .set_resp = xap_set_local_msisdn + }, + { + .name = "roamingRule", + .index.len = 11+3, + .index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,6,1}, + .column = {1, 2, 3, 4, 5, 6,7,8,9,0}, + .level = 1, + .get_instance = xap_getnext_roaming_rule, + .get_resp = xap_get_roaming_rule, + .set_resp = xap_set_roaming_rule + } + +}; + +static struct snmp_register xapp_register = { + .name = "XAPP", + .prefix_len = 11, + .prefix_oid = {1,3,6,1,4,1,1373,2,3,2,5}, + .num_of_table = 5, + .table = xapp_tables, + .default_get_resp = (getcall)xap_get_response, + .default_set_resp = (setcall)xap_set_response +}; + +void xap_snmp_registration(void) +{ + register_snmp_table(&xapp_register); +} diff --git a/plat/xapp/src/conv_prefix.h b/plat/xapp/src/conv_prefix.h new file mode 100644 index 0000000..6fd9e7e --- /dev/null +++ b/plat/xapp/src/conv_prefix.h @@ -0,0 +1,91 @@ +#ifndef _CONV_PREFIX_H +#define _CONV_PREFIX_H + +#include + +#define MAX_CONV_PREFIX 128 +#define MAX_CLI_PREFIX 64 +#define MAX_PREFIX_LEN 16 +#define MAX_NAME_LEN 8 +#define MAX_LOCAL_MSISDN_SEG 32 + +#define MAX_PLAT_NAME_LEN 24 +#define MAX_PLAT_NAME_INSTANCE 256 + +typedef struct conv_prefix_record +{ + u_char used_flag; + char prefix[MAX_PREFIX_LEN]; + char delete_length; + char add_length; + char add_digits[MAX_PREFIX_LEN]; + u_char valid_length; +}_conv_prefix_record; + +typedef struct cli_prefix +{ + u_char in_property; + char prefix[MAX_PREFIX_LEN]; + char delete_length; + u_char out_property; + char add_length; + char add_digits[MAX_PREFIX_LEN-1]; + u_char used_flag; + u_char valid_length; +}_cli_prefix; + +typedef struct xapp_group_prefix +{ + char startNumber[MAX_PREFIX_LEN+1]; + char endNumber[MAX_PREFIX_LEN+1]; + u_char repStartDigit; + u_char repEndDigit; + char repDigitWith[MAX_PREFIX_LEN+1]; + u_char status; /* 0=unlock, 1=lock */ + u_char used_flag; + char cReserved[MAX_PREFIX_LEN-1]; +}_xapp_group_prefix; + +typedef struct xapp_local_msisdn +{ + char startNumber[MAX_PREFIX_LEN+1]; + char endNumber[MAX_PREFIX_LEN+1]; + u_char status; /* 0=unlock, 1=lock */ + u_char used_flag; + char cReserved[MAX_PREFIX_LEN]; +}_xapp_local_msisdn; + +typedef struct conv_prefix +{ + _conv_prefix_record conv_prefix[MAX_CONV_PREFIX]; + _cli_prefix cli_prefix[MAX_CLI_PREFIX]; + char conv_name[MAX_CONV_PREFIX][MAX_NAME_LEN]; + char cli_name[MAX_CLI_PREFIX][MAX_NAME_LEN]; + char plat_name[MAX_PLAT_NAME_INSTANCE][MAX_PLAT_NAME_LEN]; + _xapp_group_prefix group_conv_prefix[MAX_CONV_PREFIX]; + char msisdn_segment_name[MAX_LOCAL_MSISDN_SEG][MAX_PLAT_NAME_LEN]; + _xapp_local_msisdn local_msisdn_segment[MAX_LOCAL_MSISDN_SEG]; +}_conv_prefix; + +int snmpSetConvPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen); +int snmpGetConvPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype); +int snmpSetCliPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen); +int snmpGetCliPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype); +int snmpSetPlatName(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen); +int snmpGetPlatName(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype); +int msisdnUnkToInt(char *msisdn_unk, char *msisdn_int); +int cliUptoCalled(char *caller, char *called); +int snmpGetGroupConvPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype); +int snmpSetGroupConvPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen); +extern int xap_getnext_roaming_rule(u32 *index_id); +extern int xap_get_roaming_rule(u32 column, u32 *instance, u_char *pdata, u_char *vartype); +extern int xap_set_roaming_rule(u32 column, u32 *instance, u_char *pdata, unsigned short datalen); +int saveConvPrefix(); + +/* return value: + -1 = error length; + 0 = cannn't find appropriate prefix; + 1 = conv. succeed +*/ + +#endif diff --git a/plat/xapp/src/ixap.h b/plat/xapp/src/ixap.h new file mode 100644 index 0000000..1449a50 --- /dev/null +++ b/plat/xapp/src/ixap.h @@ -0,0 +1,77 @@ +/* XAP provider interface head file */ +/* Written by Liu Zhiguo 2003-03-13 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#ifndef _XAP_INTERFACE +#define _XAP_INTERFACE + +#include "mapp/imap.h" +#include "capp/icap.h" + +/* defined in xap_interface.c */ +void xap_get_mcc(u8 *mcc); +void xap_get_mnc(u8 *mnc); +void xap_get_cc(u8 *cc); +void xap_get_ndc(u8 *ndc); +void xap_get_interprefix(u8 *inter_prefix); +void xap_get_nationalprefix(u8 *national_prefix); +void xap_get_localprefix(u8 *local_prefix); +int xap_mscid_to_num(u8 *mscid,u8 ssn, u8 *num); + +int imap_reg_ssn(u8 ssn); +u8 map_check_sendcom(u32 did); +u8 map_send_comdata(u8 *data_flow); // send map common service data +u8 map_check_sendopr(u32 did); +u8 map_send_oprdata(u8 *data_flow); // send map operation service data +u8 map_get_comdata(u8 *data_flow,u32 did); +u8 map_get_open(u8 *data_flow,u8 ssn); +u8 map_get_oprdata(u8 *data_flow,u32 did); +u32 map_get_dialogueid(u8 ssn); +u8 map_get_invokeid(u32 did); +u8 map_check_map_flag(u32 did); +u8 map_send_oprsrv( MapOprSrv_struct *srv_ptr, u8 DelimiterFlag , u8 *data_flow); +u8 map_send_comsrv(MapComSrv_struct *com_ptr,u8 uDelimiterFlag,u8 *data_flow); +u8 map_send_open( MapOpenArgParam *pOpenParam , u8 *uDataFlow ); +u8 map_send_close( u32 pid , u32 did , u8 uCloseReasion ); +u8 map_extract_param(MapOprSrv_struct *srv_ptr,MapOprData_struct *data_ptr , int ver); +u8 map_get_comdata_struct(MapComSrv_struct *map_com,u32 did); +u8 map_get_oprdata_struct(MapOprData_struct *map_opr,u32 did); + +u32 is41_get_dialogueid(u8 ssn); + +int icap_reg_ssn(u8 ssn); +u8 cap_check_sendcom(u32 did); +u8 cap_send_comdata(u8 *data_flow); // send cap common service data +u8 cap_check_sendopr(u32 did); +u8 cap_send_oprdata(u8 *data_flow); // send cap operation service data +u8 cap_get_comdata(u8 *data_flow,u32 did); +u8 cap_get_open(u8 *data_flow,u8 ssn); +u8 cap_get_oprdata(u8 *data_flow,u32 did); +u32 cap_get_dialogueid(u8 ssn); +u8 cap_get_invokeid(u32 did); + +/* defined in xap_provider.c */ +u8 map_get_acnver(SCCP_ADDR *sccp_ptr,u8 acn); +u8 map_set_acnver(SCCP_ADDR *sccp_ptr,u8 acn,u8 acn_ver); +void xap_init( int grantdid ); +void xap_fsm(); + +int snmpGetCliPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_char *vartype); +int snmpSetCliPrefix(u_char oidlen,u32 *oid,u_char *pdata,u_short datalen); +int saveConvPrefix(); +u8 init_mappconst(void); +u8 init_cappconst(void); +void wxc2_trace_xapp(u32 did); +/******AIN*********/ +u32 ain_get_dialogueid ( u8 ssn ); +int ain_reg_ssn(u8 ssn); +u8 ain_get_invokeid ( u32 did ); +int ain_send_oprsrv( MapOprSrv_struct *srv_ptr, u8 DelimiterFlag, u8 *data_flow ); +//int ain_send_rsp(MapOprSrv_struct *srv_ptr, u8 DelimiterFlag, u8 * data_flow ); +u8 ain_get_oprdata_struct ( MapOprData_struct *map_opr, u32 did);//get query or response data +u8 ain_send_open( MapOpenArgParam *pOpenParam, u8 *uDataFlow);//set sccp address +u8 ain_send_close ( u32 pid, u32 did, u8 uCloseReasion ); +u8 ain_get_open(u8 *data_flow, u8 ssn );//get query command +/******AIN*********/ +#endif diff --git a/plat/xapp/src/mapp/Map_opr.c b/plat/xapp/src/mapp/Map_opr.c new file mode 100644 index 0000000..7abbfa2 --- /dev/null +++ b/plat/xapp/src/mapp/Map_opr.c @@ -0,0 +1,918 @@ + #include "map_includes.h" + + /**************** vlr inquery opr ********************/ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding MapDetermineOprUser Arg argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_MapDetermineOprUserArg(struct MapDetermineOprUser_Arg *dou_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = dou_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,dou_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + + if (flag & 0x02) // has imei + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,IMEI_LEN,dou_ptr->imei,0x80,&asn_buf);//add imei parameter + } + + if (flag & 0x04) //has roamingRestraintFlag + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&dou_ptr->roamingRestraintFlag,0x80,&asn_buf); + } + + dou_ptr->param_flag = flag; + return buf_len; +} + +int extract_MapDetermineOprUserArg(struct MapDetermineOprUser_Arg *dou_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + dou_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapDetermineOprUserArg param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(dou_ptr->imsi,temp_buf,len); + } + + + len = get_tlv("1",temp_buf,&asn_buf); + if (len == IMEI_LEN) // get imei + { + flag |= 0x02; + memcpy(dou_ptr->imei,temp_buf,len); + } + + + len = get_tlv("2",temp_buf,&asn_buf); //get roamingRestraintFlag + if (len == 1) + { + dou_ptr->roamingRestraintFlag = temp_buf[0]; + flag |= 0x04; + } + + dou_ptr->param_flag = flag; + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding MapDetermineOprUser Response */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_MapDetermineOprUserRes(struct MapDetermineOprUser_Res *dou_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = dou_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,dou_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapDetermineOprUserRes loss IMSI"); + return RER; + } + if (flag & 0x02) // has imei + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,IMEI_LEN,dou_ptr->imei,0x80,&asn_buf);//add imei parameter + } + else + { + mapp_log_debug("assign MapDetermineOprUserRes loss IMEI"); + return RER; + } + if (flag & 0x04) //has oprFlag + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&dou_ptr->oprflag,0x80,&asn_buf); + } + else + { + mapp_log_debug("assign MapDetermineOprUserRes loss oprFlag"); + return RER; + } + if (flag & 0x08) //has msisdn + { + sprintf(tlv1,"3-%d",tag1++); + buf_len = add_tlv(tlv1,dou_ptr->msisdn[0],dou_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + dou_ptr->param_flag = flag; + return buf_len; +} + +int extract_MapDetermineOprUserRes(struct MapDetermineOprUser_Res *dou_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + dou_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapDetermineOprUserRes param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(dou_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("extract MapDetermineOprUserRes:loss IMSI"); + return RER; + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len == IMEI_LEN) // get imei + { + flag |= 0x02; + memcpy(dou_ptr->imei,temp_buf,len); + } + else + { + mapp_log_debug("extract MapDetermineOprUserRes:loss IMEI"); + return RER; + } + + len = get_tlv("2",temp_buf,&asn_buf); //get oprflag + if (len == 1) + { + dou_ptr->oprflag = temp_buf[0]; + flag |= 0x04; + } + else + { + mapp_log_debug("extract MapDetermineOprUserRes:loss oprflag"); + return RER; + } + len = get_tlv("3",temp_buf,&asn_buf); //get msisdn + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x08; + dou_ptr->msisdn[0] = len; + memcpy(dou_ptr->msisdn+1,temp_buf,len); + } + + dou_ptr->param_flag = flag; + return buf_len; +} + +/**************** opr updataLocation vlr ********************/ +int assign_MapVlrUpdateLocationArg(struct MapVlrUpdateLocation_Arg *cuwm_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = cuwm_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,cuwm_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapVlrUpdateLocationArg loss IMSI"); + return RER; + } + if (flag & 0x02) // has oprflag + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->status,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapVlrUpdateLocationArg loss status"); + return RER; + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + + +int extract_MapVlrUpdateLocationArg(struct MapVlrUpdateLocation_Arg *cuwm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + cuwm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapVlrUpdateLocationArg param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(cuwm_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("extract MapVlrUpdateLocationArg:loss IMSI"); + return RER; + } + len = get_tlv("1",temp_buf,&asn_buf);/* get status */ + if (len == 1) + { + flag |= 0x02; + cuwm_ptr->status = temp_buf[0]; + } + else + { + mapp_log_debug("extract MapVlrUpdateLocationArg:loss status"); + return RER; + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + +int assign_MapVlrUpdateLocationRes(struct MapVlrUpdateLocation_Res *cuwm_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = cuwm_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,cuwm_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + + if (flag & 0x02) // has status + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->status,0x80,&asn_buf);//add msisdn parameter + } + + if (flag & 0x04) //has error + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->error,0x80,&asn_buf); + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + +int extract_MapVlrUpdateLocationRes(struct MapVlrUpdateLocation_Res *cuwm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + cuwm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapVlrUpdateLocationRes param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(cuwm_ptr->imsi,temp_buf,len); + } + + + len = get_tlv("1",temp_buf,&asn_buf); + if (len == 1) + { + flag |= 0x02; + cuwm_ptr->status = temp_buf[0]; + } + + len = get_tlv("2",temp_buf,&asn_buf); //get reult + if (len == 1) + { + cuwm_ptr->error = temp_buf[0]; + flag |= 0x04; + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + + +/**************** opr create hlr ********************/ +int assign_MapCreateUserWithMsisdnImsiArg(struct MapCreateUserWithMsisdnImsi_Arg *cuwm_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = cuwm_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,cuwm_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapCreateUserWithMsisdnImsiArg loss IMSI"); + return RER; + } + if (flag & 0x02) // has msisdn + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,cuwm_ptr->msisdn[0],cuwm_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapCreateUserWithMsisdnImsiArg loss MSISDN"); + return RER; + } + + if (flag & 0x04) //has imsiFlag + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->imsiflag,0x80,&asn_buf); + } + else + { + mapp_log_debug("assign MapCreateUserWithMsisdnImsiArg loss imsiFlag"); + return RER; + } + + if (flag & 0x08) //has camelFlag + { + sprintf(tlv1,"3-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->camelflag,0x80,&asn_buf); + } + else + { + mapp_log_debug("assign MapCreateUserWithMsisdnImsiArg loss camelflag"); + return RER; + } + cuwm_ptr->param_flag = flag; + return buf_len; +} + + +int extract_MapCreateUserWithMsisdnImsiArg(struct MapCreateUserWithMsisdnImsi_Arg *cuwm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + cuwm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapCreateUserWithMsisdnImsiArg param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(cuwm_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("extract MapCreateUserWithMsisdnImsiArg:loss IMSI"); + return RER; + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x02; + cuwm_ptr->msisdn[0] = len; + memcpy(cuwm_ptr->msisdn+1,temp_buf,len); + } + else + { + mapp_log_debug("extract MapCreateUserWithMsisdnImsiArg:msisdn length error"); + return RER; + } + + len = get_tlv("2",temp_buf,&asn_buf); //get imsiflag + if (len == 1) + { + cuwm_ptr->imsiflag = temp_buf[0]; + flag |= 0x04; + } + else + { + mapp_log_debug("extract MapCreateUserWithMsisdnImsiArg:loss roamingRestraintFlag"); + return RER; + } + len = get_tlv("3",temp_buf,&asn_buf); //get camelflag + if (len == 1) + { + cuwm_ptr->camelflag = temp_buf[0]; + flag |= 0x08; + } + else + { + mapp_log_debug("extract MapCreateUserWithMsisdnImsiArg:loss camelflag"); + return RER; + } + cuwm_ptr->param_flag = flag; + return buf_len; +} + +int assign_MapCreateUserWithMsisdnImsiRes(struct MapCreateUserWithMsisdnImsi_Res *cuwm_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = cuwm_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,cuwm_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + + if (flag & 0x02) // has msisdn + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,cuwm_ptr->msisdn[0],cuwm_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + + + if (flag & 0x04) //has result + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->result,0x80,&asn_buf); + } + else + { + mapp_log_debug("assign MapCreateUserWithMsisdnImsiRes loss result"); + return RER; + } + + if (flag & 0x08) //has cause + { + sprintf(tlv1,"3-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->cause,0x80,&asn_buf); + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + +int extract_MapCreateUserWithMsisdnImsiRes(struct MapCreateUserWithMsisdnImsi_Res *cuwm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + cuwm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapCreateUserWithMsisdnImsiRes param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(cuwm_ptr->imsi,temp_buf,len); + } + + + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x02; + cuwm_ptr->msisdn[0] = len; + memcpy(cuwm_ptr->msisdn+1,temp_buf,len); + } + + + len = get_tlv("2",temp_buf,&asn_buf); //get reult + if (len == 1) + { + cuwm_ptr->result = temp_buf[0]; + flag |= 0x04; + } + else + { + mapp_log_debug("extract MapCreateUserWithMsisdnImsiArg:loss result"); + return RER; + } + + len = get_tlv("3",temp_buf,&asn_buf); //get cause + if (len == 1) + { + cuwm_ptr->cause = temp_buf[0]; + flag |= 0x08; + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + + + +/*********** opr delete hlr ***************************/ +int assign_MapDeleteOprUserArg(struct MapDeleteOprUser_Arg *dou_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = dou_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,dou_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapDeleteOprUserArg loss IMSI"); + return RER; + } + + if (flag & 0x02) // has msisdn + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,dou_ptr->msisdn[0],dou_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapDeleteOprUserArg loss MSISDN"); + return RER; + } + + dou_ptr->param_flag = flag; + return buf_len; +} + + +int extract_MapDeleteOprUserArg(struct MapDeleteOprUser_Arg *dou_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + dou_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapDeleteOprUserArg param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(dou_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("extract MapDeleteOprUserArg:loss IMSI"); + return RER; + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x02; + dou_ptr->msisdn[0] = len; + memcpy(dou_ptr->msisdn+1,temp_buf,len); + } + else + { + mapp_log_debug("extract MapDeleteOprUserArg:msisdn length error"); + return RER; + } + + dou_ptr->param_flag = flag; + return buf_len; +} + +int assign_MapDeleteOprUserRes(struct MapDeleteOprUser_Res *dou_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = dou_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,dou_ptr->imsi,0x80,&asn_buf);//add msisdn parameter + } + + if (flag & 0x02) // has msisdn + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,dou_ptr->msisdn[0],dou_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + + + if (flag & 0x04) //has result + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&dou_ptr->result,0x80,&asn_buf); + } + else + { + mapp_log_debug("assign MapDeleteOprUserRes loss result"); + return RER; + } + + if (flag & 0x08) //has cause + { + sprintf(tlv1,"3-%d",tag1++); + buf_len = add_tlv(tlv1,1,&dou_ptr->cause,0x80,&asn_buf); + } + + dou_ptr->param_flag = flag; + return buf_len; +} + +int extract_MapDeleteOprUserRes(struct MapDeleteOprUser_Res *dou_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + dou_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapDeleteOprUserRes param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(dou_ptr->imsi,temp_buf,len); + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x02; + dou_ptr->msisdn[0] = len; + memcpy(dou_ptr->msisdn+1,temp_buf,len); + } + + + len = get_tlv("2",temp_buf,&asn_buf); //get reult + if (len == 1) + { + dou_ptr->result = temp_buf[0]; + flag |= 0x04; + } + else + { + mapp_log_debug("extract MapDeleteOprUserRes:loss result"); + return RER; + } + + len = get_tlv("3",temp_buf,&asn_buf); //get cause + if (len == 1) + { + dou_ptr->cause = temp_buf[0]; + flag |= 0x08; + } + + dou_ptr->param_flag = flag; + return buf_len; +} + + +int assign_MapVlrEnquiryIMDM_Arg(struct MapVlrEnquiryIMDM_Arg *cuwm_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = cuwm_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,cuwm_ptr->imsi,0x80,&asn_buf);//add imsi parameter + } + else + { + mapp_log_debug("assign MapVlrEnquiryIMDM_Arg loss IMSI"); + return RER; + } + if (flag & 0x02) // has msisdn + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,cuwm_ptr->msisdn[0],cuwm_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("assign MapCreateUserWithMsisdnImsiArg loss MSISDN"); + return RER; + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + + +int assign_MapVlrEnquiryIMDM_Res(struct MapVlrEnquiryIMDM_Res *cuwm_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = cuwm_ptr->param_flag; + if (flag & 0x01) // has imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,cuwm_ptr->imsi,0x80,&asn_buf);//add imsi parameter + } + + if (flag & 0x02) // has msisdn + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,cuwm_ptr->msisdn[0],cuwm_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + + if (flag & 0x04) // has status + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cuwm_ptr->status,0x80,&asn_buf); + } + else + { + mapp_log_debug("assign MapVlrEnquiryIMDM_Arg loss staus"); + return RER; + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + + +int extract_MapVlrEnquiryIMDM_Arg(struct MapVlrEnquiryIMDM_Arg *cuwm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + cuwm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapVlrEnquiryIMDM_Arg param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(cuwm_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("extract MapVlrEnquiryIMDM_Arg:loss IMSI"); + return RER; + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x02; + cuwm_ptr->msisdn[0] = len; + memcpy(cuwm_ptr->msisdn+1,temp_buf,len); + } + else + { + mapp_log_debug("extract MapVlrEnquiryIMDM_Arg:msisdn length error"); + return RER; + } + + cuwm_ptr->param_flag = flag; + return buf_len; +} + +int extract_MapVlrEnquiryIMDM_Res(struct MapVlrEnquiryIMDM_Res *cuwm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + cuwm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("extract_MapVlrEnquiryIMDM_Res param len is:0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN) + { + flag |= 0x01; + memcpy(cuwm_ptr->imsi,temp_buf,len); + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x02; + cuwm_ptr->msisdn[0] = len; + memcpy(cuwm_ptr->msisdn+1,temp_buf,len); + } + + len = get_tlv("2",temp_buf,&asn_buf);/* status */ + if (len == 1) + { + flag |= 0x04; + cuwm_ptr->status = temp_buf[0]; + } + else + { + mapp_log_debug("extract MapVlrEnquiryIMDM_Res:status loss"); + return RER; + } + + + cuwm_ptr->param_flag = flag; + return buf_len; +} + diff --git a/plat/xapp/src/mapp/imap.h b/plat/xapp/src/mapp/imap.h new file mode 100644 index 0000000..4746216 --- /dev/null +++ b/plat/xapp/src/mapp/imap.h @@ -0,0 +1,28 @@ +/* MAP message interface head file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#ifndef _MAP_INTERFACE +#define _MAP_INTERFACE + +#include "../../../sccp/src/include/sccp.h" +#include "map_const.h" +#include "map_struct.h" + +int build_mapparam(struct MapOprSrv_struct *opr_ptr,u8 *buf); +u8 extract_mapparam(struct MapOprSrv_struct *opr_ptr,u8 opr_code,u8 opr_flag,u32 pre_param_len,u8 *pre_param); + +int build_is41param(struct MapOprSrv_struct *opr_ptr,u8 *buf); // build is41 service paramter +u8 extract_is41param(struct MapOprSrv_struct *opr_ptr,u8 opr_code,u8 opr_flag,u32 pre_param_len,u8 *pre_param); + +int code_ansitcap_digits(struct _ansiTcapDigits *digits, u8 *outBuf);// return len +int decode_ansitcap_digits(struct _ansiTcapDigits *digits, u8 *inBuf); + +int build_ainparam(struct MapOprSrv_struct *opr_ptr,u8 *buf); // build ain service paramter +u8 extract_ainparam(struct MapOprSrv_struct *opr_ptr,u8 opr_code,u8 opr_flag,u32 pre_param_len,u8 *pre_param); + +void is41_init(); +void is41_timer(); + +#endif diff --git a/plat/xapp/src/mapp/is41_code.h b/plat/xapp/src/mapp/is41_code.h new file mode 100644 index 0000000..d362a70 --- /dev/null +++ b/plat/xapp/src/mapp/is41_code.h @@ -0,0 +1,110 @@ +/* IS41 code define */ +/* Created by daniel on 2005-05-27 */ +/* Modified by daniel on 2005-05-27 */ +/* -------------------------------------*/ +#ifndef _IS41_CODE +#define _IS41_CODE + +//Authorization Denied reason +#define AUTHDEN_DELINQUENT_ACCOUNT 1 +#define AUTHDEN_INVALID_SERIAL_NUMBER 2 +#define AUTHDEN_STOLEN_UNIT 3 +#define AUTHDEN_DUPLICATE_UNIT 4 +#define AUTHDEN_UNASSIGNED_DIRECTORY_NUMBER 5 +#define AUTHDEN_UNSPECIFIED 6 +#define AUTHDEN_MULTIPLE_ACCESS 7 +#define AUTHDEN_NOT_AUTHORIZED_FOR_THE_MSC 8 +#define AUTHDEN_MISSING_AUTHENTICATION_PARAMETERS 9 +#define AUTHDEN_TERMINALTYPE_MISMATCH 10 + +#define WXC_SYSTEM_MY_TYPE_CODE 0 + +#define CANTYP_SERVING_SYSTEM_OPTION 1 +#define CANTYP_REPORTINCALL 2 +#define CANTYP_DISCONTINUE 3 + +//type of digits +#define TOD_CALLED_PARTY_NUMBER 1 +#define TOD_CALLING_PARTY_NUMBER 2 +#define TOD_CALLER_INTERACTION 3 +#define TOD_ROUTING_NUMBER 4 +#define TOD_BILLING_NUMBER 5 +#define TOD_DESTINATION_NUMBER 6//This is the network address of the called party +#define TOD_LATA 7 +#define TOD_CARRIER 8//In North America the three, four, or five digits represent an interexchange or international carrier + +#define QUALCODE_VALIDATION_ONLY 2 +#define QUALCODE_VALIDATION_AND_PROFILE 3 +#define QUALCODE_PROFILE_ONLY 4 + +#define ACCDEN_UNASSIGNED_DIRECTORY_NUMBER 1 +#define ACCDEN_INACTIVE 2 +#define ACCDEN_BUSY 3 +#define ACCDEN_TERMINATION_DENIED 4 +#define ACCDEN_NO_PAGE_RESPONSE 5 +#define ACCDEN_UNAVAILABLE 6 + +//DMH_RedirectionIndicator +#define REDIND_CFU 1 +#define REDIND_CFB 2 +#define REDIND_CFNA 3 +#define REDIND_CFO 4 +#define REDIND_CD_UNSPECIFIED 5 +#define REDIND_CD_PSTN 6 +#define REDIND_CD_PRIVATE 7 +#define REDIND_PSTN_TANDEM 8 +#define REDIND_PRIVATE_TANDEM 9 +#define REDIND_BUSY 10 +#define REDIND_INACTIVE 11 +#define REDIND_UNASSIGNED 12 +#define REDIND_TERMINATION_DENIED 13 +#define REDIND_CD_FAILURE 14 +#define REDIND_ECT 15 +#define REDIND_MAH 16 +#define REDIND_FA 17 +#define REDIND_ABANDONED_CALL_LEG 18 +#define REDIND_PCA_CALL_REFUSED 19 +#define REDIND_SCA_CALL_REFUSED 20 +#define REDIND_DIALOGUE 21 +#define REDIND_CFD 22 +#define REDIND_CD_LOCAL 23 +#define REDIND_VOICE_MAIL_RETRIEVAL 24 + +//RedirectionReason +#define REDREASON_BUSY 1 +#define REDREASON_NO_ANSWER 2 +#define REDREASON_UNCONDITIONAL 3 +#define REDREASON_NO_PAGE_RESPONSE 4 +#define REDREASON_UNAVAILABLE 5 +#define REDREASON_UNROUTABLE 6 +#define REDREASON_CALL_ACCEPTED 7 +#define REDREASON_CALL_REFUSED 8 + +#define ORIGIND_Prior_agreement 1 +#define ORIGIND_Origination_denied 2 +#define ORIGIND_Local_calls_only 3 +#define ORIGIND_Selected_ldigits 4 +#define ORIGIND_Selected_ldigits_and_local_call 5 +#define ORIGIND_National_long_distance 6 +#define ORIGIND_International_calls 7 +#define ORIGIND_Single_directory_number 8 + +#define AUTHPER_Per_Call 1 +#define AUTHPER_Hours 2 +#define AUTHPER_Days 3 +#define AUTHPER_Weeks 4 +#define AUTHPER_Per_Agreement 5 +#define AUTHPER_Indefinite 6 +#define AUTHPER_Number_of_calls 7 + + +#define ACCTYPE_FLASHREQ 2 +#define ACCTYPE_REGISTRATION 3 +#define ACCTYPE_ORIGINATION 4 +#define ACCTYPE_TERMINATION 5 +#define ACCTYPE_NOACCESS 6 +#define ACCTYPE_POWERDOWN 7 +#define ACCTYPE_SMS_PAGERESPONSE 8 + + +#endif diff --git a/plat/xapp/src/mapp/is41_code_auc.c b/plat/xapp/src/mapp/is41_code_auc.c new file mode 100644 index 0000000..2a730cd --- /dev/null +++ b/plat/xapp/src/mapp/is41_code_auc.c @@ -0,0 +1,1345 @@ +/* is41 coding auc service file */ +/* written by daniel zhang 2004-06-16 */ +/* modified by daniel on 2004-07-09 */ +/* -------------------------------- */ + +#include "map_includes.h" + +/* external functions */ +void is41_log(char *info); +void is41_debug(DWORD mask, const char *fmt, ...); +void is41_showbuf(DWORD mask, BYTE *buf, int len); +int decode_Is41Parameter(char *tag,int len,BYTE *value,ASN_BUF *asn_buf); +char *is41_sequenceTag(char *tag,int sequence); + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding security triplets argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ + +int assign_is41AuthenticationDirective_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_AUTHDIR_ARG *ptr; + + ptr = &opr_ptr->msg_list.authdir_arg; + + + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,(BYTE*)&ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + is41_debug(IS41DB_ENCODE,"[IS41-Encode] Starting...ESN=%lx%lx%lx%lx,MIN=%ld%ld%ld%ld", + ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3], + ptr->min[0],ptr->min[1], + ptr->min[2],ptr->min[3],ptr->min[4]); + +// optional part---> + if((flag & BIT2_TRUE)>0) //AuthenticationAlgorithmVersion + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AAV,3),1,&ptr->aav,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //AuthenticationResponseUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHU,4),3,ptr->authu,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,5),1,&ptr->count,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //DenyAccess + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DENACC,6),1,&ptr->denacc,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //LocationAreaID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,7),2,ptr->locid,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //RandomVariableSSD + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDSSD,8),7,ptr->randssd,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //RandomVariableUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDU,9),3,ptr->randu,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //SenderIdentificationNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,10),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) //SharedSecretData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SSD,11),16,ptr->ssd,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) //SSDNotShared + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NOSSD,12),1,&ptr->nossd,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) //UpdateCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_UPDCOUNT,13),1,&ptr->updcount,0x80,&asn_buf); + + + return buf_len; +} + +int assign_is41AuthenticationDirective_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_AUTHDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.authdir_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(IS41PAR_COUNT,1,(BYTE*)&ptr->count,0x80,&asn_buf); + else + return 0; + + return buf_len; +} + +int extract_is41AuthenticationDirective_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 len; + + struct IS41_AUTHDIR_ARG *ptr; + + ptr = &opr_ptr->msg_list.authdir_arg; + + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,(BYTE*)&ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_AAV,1,&ptr->aav,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter(IS41PAR_AUTHU,3,ptr->authu,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if (decode_Is41Parameter(IS41PAR_DENACC,1,&ptr->denacc,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter(IS41PAR_LOCID,2,ptr->locid,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDSSD,7,ptr->randssd,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDU,8,ptr->randu,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT9_TRUE; + } + if (decode_Is41Parameter(IS41PAR_SSD,16,ptr->ssd,&asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if (decode_Is41Parameter(IS41PAR_NOSSD,1,&ptr->nossd,&asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if (decode_Is41Parameter(IS41PAR_UPDCOUNT,1,&ptr->updcount,&asn_buf)) + ptr->param_flag |= BIT12_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int extract_is41AuthenticationDirective_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_AUTHDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.authdir_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,1,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41AuthenticationDirectiveForward_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41AucDirectiveForward_arg *ptr; + + ptr = &opr_ptr->msg_list.AUCDirForw_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //inter MSC CircuitID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_IMSCCID,1),2,ptr->InterMSCCircuitID,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSC CID absent!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->MobileIdentificationNumber,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!"); + return 0; + } + + is41_debug(IS41DB_ENCODE,"[IS41-Encode] Starting...MSC CID=%x.%x,MIN=%ld%ld%ld%ld", + ptr->InterMSCCircuitID[0],ptr->InterMSCCircuitID[1], + ptr->MobileIdentificationNumber[0],ptr->MobileIdentificationNumber[1], + ptr->MobileIdentificationNumber[2],ptr->MobileIdentificationNumber[3],ptr->MobileIdentificationNumber[4]); + +// optional part---> + if((flag & BIT2_TRUE)>0) //AuthenticationAlgorithmVersion + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHU,3),3,ptr->AuthenticationResponseUniqueChallenge,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //RandomVariableUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDU,4),3,ptr->RandomVariableUniqueChallenge,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41AuthenticationDirectiveForward_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + + struct IS41AucDirectiveForward_arg *ptr; + + ptr = &opr_ptr->msg_list.AUCDirForw_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,4,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_IMSCCID,2,(BYTE*)&ptr->InterMSCCircuitID,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSC ID absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->MobileIdentificationNumber,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + +//optional part + if (decode_Is41Parameter(IS41PAR_AUTHU,3,ptr->AuthenticationResponseUniqueChallenge,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDU,3,ptr->RandomVariableUniqueChallenge,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41AuthenticationFailureReport_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_AFREPORT_ARG *ptr; + + ptr = &opr_ptr->msg_list.afreport_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,(BYTE*)&ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //reportType + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RPTTYP,3),1,&ptr->rpttyp1,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:reportType absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //system access type + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSACCTYPE,4),1,&ptr->sysacctype,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:system access type absent!"); + return 0; + } + + if((flag & BIT4_TRUE)>0) //system capabilities + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSCAP,5),1,&ptr->syscap,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:system access type absent!"); + return 0; + } + + is41_debug(IS41DB_ENCODE,"[IS41-Encode] Starting...ESN=%lx%lx%lx%lx,MIN=%ld%ld%ld%ld,ReportType=%d,sysAccType=%d,sysCap=%d", + ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3], + ptr->min[0],ptr->min[1], + ptr->min[2],ptr->min[3],ptr->min[4], + ptr->rpttyp1,ptr->sysacctype,ptr->syscap); + +// optional part---> + if((flag & BIT5_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,6),1,&ptr->count,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //CallHistoryCountExpected + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNTEx,7),1,&ptr->countex,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,8),3,ptr->mscid,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //reportType + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RPTTYP,9),1,&ptr->rpttyp2,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //SenderIdentificationNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,10),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41AuthenticationFailureReport_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 len; + + struct IS41_AFREPORT_ARG *ptr; + + ptr = &opr_ptr->msg_list.afreport_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,10,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,(BYTE*)&ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(is41_sequenceTag(IS41PAR_RPTTYP,3),1,&ptr->rpttyp1,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ReportType absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_SYSACCTYPE,1,&ptr->sysacctype,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SystemAccessType absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_SYSCAP,1,&ptr->syscap,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SystemCapabilities absent!"); + return 0; + } + +// optional part---> + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter(IS41PAR_COUNTEx,1,&ptr->countex,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter(is41_sequenceTag(IS41PAR_RPTTYP,9),1,&ptr->rpttyp2,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT9_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41AuthenticationFailureReport_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_AFREPORT_RSP *ptr; + + ptr = &opr_ptr->msg_list.afreport_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + +// optional part---> + if((flag & BIT0_TRUE)>0) //AuthenticationAlgorithmVersion + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AAV,1),1,&ptr->aav,0x80,&asn_buf); + + if((flag & BIT1_TRUE)>0) //AuthenticationResponseUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHU,2),3,ptr->authu,0x80,&asn_buf); + + if((flag & BIT2_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,3),1,&ptr->count,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //DenyAccess + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DENACC,4),1,&ptr->denacc,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //RandomVariableSSD + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDSSD,5),7,ptr->randssd,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //RandomVariableUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDU,6),3,ptr->randu,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //SharedSecretData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SSD,7),16,ptr->ssd,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //SSDNotShared + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NOSSD,8),1,&ptr->nossd,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //TerminalType + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTYP,9),1,&ptr->termtyp,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //UpdateCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_UPDCOUNT,10),1,&ptr->updcount,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41AuthenticationFailureReport_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + + struct IS41_AFREPORT_RSP *ptr; + + ptr = &opr_ptr->msg_list.afreport_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,10,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_AAV,1,&ptr->aav,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if (decode_Is41Parameter(IS41PAR_AUTHU,3,ptr->authu,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter(IS41PAR_DENACC,1,&ptr->denacc,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDSSD,7,ptr->randssd,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDU,8,ptr->randu,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter(IS41PAR_SSD,16,ptr->ssd,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter(IS41PAR_NOSSD,1,&ptr->nossd,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter(IS41PAR_TERMTYP,1,&ptr->termtyp,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if (decode_Is41Parameter(IS41PAR_UPDCOUNT,1,&ptr->updcount,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41AuthenticationRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_AUTHREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.authreq_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,(BYTE*)&ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3),3,ptr->mscid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSCID absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //system access type + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSACCTYPE,4),1,&ptr->sysacctype,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:system access type absent!"); + return 0; + } + + if((flag & BIT4_TRUE)>0) //system capabilities + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSCAP,5),1,&ptr->syscap,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:system access type absent!"); + return 0; + } + + is41_debug(IS41DB_ENCODE,"[IS41-Encode] Starting...ESN=%lx%lx%lx%lx,MIN=%ld%ld%ld%ld,MSCID=%d,sysAccType=%d,sysCap=%d", + ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3], + ptr->min[0],ptr->min[1], + ptr->min[2],ptr->min[3],ptr->min[4], + ptr->mscid,ptr->sysacctype,ptr->syscap); + +//optional part---> + if((flag & BIT5_TRUE)>0) //AuthenticationData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHDATA,6),3,ptr->authdata,0x80,&asn_buf); + if((flag & BIT6_TRUE)>0) //AuthenticationResponse + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHR,7),3,ptr->authr,0x80,&asn_buf); + if((flag & BIT7_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,8),1,&ptr->count,0x80,&asn_buf); + if((flag & BIT8_TRUE)>0) //ConfidentialityModes + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CMODES,9),1,&ptr->cmodes,0x80,&asn_buf); + if((flag & BIT9_TRUE)>0) //Digits + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,10),ptr->DigitsLen & MAX_IS41_VARPAR_LEN_1,ptr->digits,0x80,&asn_buf); + if((flag & BIT10_TRUE)>0) //PC_SSN + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,11),5,ptr->pcssn,0x80,&asn_buf); + if((flag & BIT11_TRUE)>0) //RandomVariable + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RAND,12),4,ptr->rand,0x80,&asn_buf); + if((flag & BIT12_TRUE)>0) //SenderIdentificationNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,13),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + if((flag & BIT13_TRUE)>0) //TerminalType + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTYP,14),1,&ptr->termtyp,0x80,&asn_buf); + + return buf_len; + +} + +int extract_is41AuthenticationRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_AUTHREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.authreq_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,14,&decErr,&asn_buf) == -1) + { + return 0; + } + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,(BYTE*)&ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + { + ptr->param_flag |= BIT2_TRUE; + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_SYSACCTYPE,1,&ptr->sysacctype,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SystemAccessType absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_SYSCAP,1,&ptr->syscap,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SystemCapabilities absent!"); + return 0; + } + +// optional part---> + if (decode_Is41Parameter(IS41PAR_AUTHDATA,3,ptr->authdata,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter(IS41PAR_AUTHR,3,ptr->authr,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter(IS41PAR_CMODES,1,&ptr->cmodes,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + len = decode_Is41Parameter(IS41PAR_DIGITS,32,ptr->digits,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->DigitsLen = len; + } + if (decode_Is41Parameter(IS41PAR_PCSSN,5,ptr->pcssn,&asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if (decode_Is41Parameter(IS41PAR_RAND,4,ptr->rand,&asn_buf)) + ptr->param_flag |= BIT11_TRUE; + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT12_TRUE; + } + len = decode_Is41Parameter(IS41PAR_TERMTYP,1,&ptr->termtyp,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT13_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + + +int assign_is41AuthenticationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_AUTHREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.authreq_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + +// optional part---> + if((flag & BIT0_TRUE)>0) //AuthenticationAlgorithmVersion + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AAV,1),1,&ptr->aav,0x80,&asn_buf); + + if((flag & BIT1_TRUE)>0) //AuthenticationResponseUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHU,2),3,ptr->authu,0x80,&asn_buf); + + if((flag & BIT2_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,3),1,&ptr->count,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //CDMAPrivateLongCodeMask + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CDMAPLCM,4),6,ptr->cdmaplcm,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //DenyAccess + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DENACC,5),1,&ptr->denacc,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //RandomVariableSSD + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDSSD,6),7,ptr->randssd,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //RandomVariableUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDU,7),3,ptr->randu,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //SharedSecretData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SSD,8),16,ptr->ssd,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //SharedSecretData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMEKEY,9),8,ptr->smekey,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //SSDNotShared + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NOSSD,10),1,&ptr->nossd,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) //UpdateCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_UPDCOUNT,11),1,&ptr->updcount,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) //VoicePrivacyMask + buf_len = AddTLV(is41_sequenceTag(IS41PAR_VPMASK,12),66,ptr->vpmask,0x80,&asn_buf); + + + return buf_len; +} + +int extract_is41AuthenticationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + + struct IS41_AUTHREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.authreq_rsp; + ptr->param_flag = 0; + + if (buf_len == 0) + { +// is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 1; + } + if(AsnDecode(buf,buf_len,12,&decErr,&asn_buf) == -1) + return 0; + + if (decode_Is41Parameter(IS41PAR_AAV,1,&ptr->aav,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if (decode_Is41Parameter(IS41PAR_AUTHU,3,ptr->authu,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter(IS41PAR_CDMAPLCM,6,ptr->cdmaplcm,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if (decode_Is41Parameter(IS41PAR_DENACC,1,&ptr->denacc,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDSSD,7,ptr->randssd,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDU,3,ptr->randu,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter(IS41PAR_SSD,16,ptr->ssd,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter(IS41PAR_SMEKEY,8,ptr->smekey,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if (decode_Is41Parameter(IS41PAR_NOSSD,1,&ptr->nossd,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if (decode_Is41Parameter(IS41PAR_UPDCOUNT,1,&ptr->updcount,&asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if (decode_Is41Parameter(IS41PAR_VPMASK,66,ptr->vpmask,&asn_buf)) + ptr->param_flag |= BIT11_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41AuthenticationStatusReport_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_ASREPORT_ARG *ptr; + + ptr = &opr_ptr->msg_list.asreport_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,(BYTE*)&ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //system capabilities + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSCAP,3),1,&ptr->syscap,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:system access type absent!"); + return 0; + } + + is41_debug(IS41DB_ENCODE,"[IS41-Encode] Starting...ESN=%lx%lx%lx%lx,MIN=%ld%ld%ld%ld,sysCap=%d", + ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3], + ptr->min[0],ptr->min[1], + ptr->min[2],ptr->min[3],ptr->min[4], + ptr->syscap); + +//optional part---> + if((flag & BIT3_TRUE)>0) //CountUpdateReport + { + if (ptr->CntUpdRepLen > 32) + { + ptr->CntUpdRepLen = 32; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNTRPT,4),ptr->CntUpdRepLen,ptr->countrpt,0x80,&asn_buf); + } + + if((flag & BIT4_TRUE)>0) //SenderIdentificationNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,5),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //SSDUpdateReport + { + if (ptr->SSDUpdRepLen > 32) + { + ptr->SSDUpdRepLen = 32; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SSDURPT,6),ptr->SSDUpdRepLen,ptr->ssdurpt,0x80,&asn_buf); + } + + if((flag & BIT6_TRUE)>0) //UniqueChallengeReport + { + if (ptr->UniChaRepLen > 32) + { + ptr->UniChaRepLen = 32; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_UCHALRPT,7),ptr->UniChaRepLen,ptr->uchalrpt,0x80,&asn_buf); + } + + return buf_len; + +} + +int extract_is41AuthenticationStatusReport_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_ASREPORT_ARG *ptr; + + ptr = &opr_ptr->msg_list.asreport_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,7,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,(BYTE*)&ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_SYSCAP,1,&ptr->syscap,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SystemCapabilities absent!"); + return 0; + } + +// optional part---> + len = decode_Is41Parameter(IS41PAR_COUNTRPT,32,ptr->countrpt,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->CntUpdRepLen = len; + } + + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT4_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_SSDURPT,32,ptr->ssdurpt,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->SSDUpdRepLen = len; + } + + len = decode_Is41Parameter(IS41PAR_UCHALRPT,32,ptr->uchalrpt,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->UniChaRepLen = len; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41AuthenticationStatusReport_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_ASREPORT_RSP *ptr; + + ptr = &opr_ptr->msg_list.asreport_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + +//optional part---> + if((flag & BIT0_TRUE)>0) //AuthenticationAlgorithmVersion + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AAV,1),1,&ptr->aav,0x80,&asn_buf); + if((flag & BIT1_TRUE)>0) //AuthenticationResponseUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHU,2),3,ptr->authu,0x80,&asn_buf); + if((flag & BIT2_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,3),1,&ptr->count,0x80,&asn_buf); + if((flag & BIT3_TRUE)>0) //DenyAccess + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DENACC,4),1,&ptr->denacc,0x80,&asn_buf); + if((flag & BIT4_TRUE)>0) //RandomVariableSSD + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDSSD,5),7,ptr->randssd,0x80,&asn_buf); + if((flag & BIT5_TRUE)>0) //RandomVariableUniqueChallenge + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDU,6),3,ptr->randu,0x80,&asn_buf); + if((flag & BIT6_TRUE)>0) //SharedSecretData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SSD,7),16,ptr->ssd,0x80,&asn_buf); + if((flag & BIT7_TRUE)>0) //SSDNotShared + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NOSSD,8),1,&ptr->nossd,0x80,&asn_buf); + if((flag & BIT8_TRUE)>0) //UpdateCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_UPDCOUNT,9),1,&ptr->updcount,0x80,&asn_buf); + + return buf_len; + +} + +int extract_is41AuthenticationStatusReport_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + + struct IS41_ASREPORT_RSP *ptr; + + ptr = &opr_ptr->msg_list.asreport_rsp; + ptr->param_flag = 0; + + if (buf_len == 0) + { +// is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 1; + } + if(AsnDecode(buf,buf_len,9,&decErr,&asn_buf) == -1) + return 0; + + + +// optional part---> + if (decode_Is41Parameter(IS41PAR_AAV,1,&ptr->aav,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if (decode_Is41Parameter(IS41PAR_AUTHU,3,ptr->authu,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter(IS41PAR_DENACC,1,&ptr->denacc,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDSSD,7,ptr->randssd,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if (decode_Is41Parameter(IS41PAR_RANDU,8,ptr->randu,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter(IS41PAR_SSD,16,ptr->ssd,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter(IS41PAR_NOSSD,1,&ptr->nossd,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter(IS41PAR_UPDCOUNT,1,&ptr->updcount,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + + +int assign_is41BaseStationChallenge_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_BSCHALL_ARG *ptr; + + ptr = &opr_ptr->msg_list.bschall_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,(BYTE*)&ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //randbs + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RANDBS,3),4,ptr->randbs,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:RANDBS absent!!"); + return 0; + } + +//optional part---> + if((flag & BIT3_TRUE)>0) //SenderIdentificationNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,13),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + return buf_len; + +} + +int extract_is41BaseStationChallenge_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 len; + + struct IS41_BSCHALL_ARG *ptr; + + ptr = &opr_ptr->msg_list.bschall_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,14,&decErr,&asn_buf) == -1) + { + return 0; + } + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,(BYTE*)&ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_RANDBS,4,ptr->randbs,&asn_buf)) + { + ptr->param_flag |= BIT2_TRUE; + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + + +// optional part---> + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0); + { + ptr->senderinLen = len; + ptr->param_flag |= BIT3_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + + +int assign_is41BaseStationChallenge_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_BSCHALL_RSP *ptr; + + ptr = &opr_ptr->msg_list.bschall_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //authbs + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHBS,1),3,(BYTE*)&ptr->authbs,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:AUTHBS absent!!"); + return 0; + } + + + return buf_len; +} + +int extract_is41BaseStationChallenge_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + + struct IS41_BSCHALL_RSP *ptr; + + ptr = &opr_ptr->msg_list.bschall_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,12,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_AUTHBS,4,(BYTE*)&ptr->authbs,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:AUTHBS absent!"); + return 0; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41CountRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_COUNTREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.countreq_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,(BYTE*)&ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + + +//optional part---> + if((flag & BIT2_TRUE)>0) //SenderIdentificationNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,3),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + return buf_len; + +} + +int extract_is41CountRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 len; + + struct IS41_COUNTREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.countreq_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,14,&decErr,&asn_buf) == -1) + { + return 0; + } + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,(BYTE*)&ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + +// optional part---> + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT2_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + + +int assign_is41CountRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_COUNTREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.countreq_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + +// optional part---> + if((flag & BIT0_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,1),1,&ptr->count,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41CountRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + + struct IS41_COUNTREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.countreq_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,12,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} diff --git a/plat/xapp/src/mapp/is41_code_ms.c b/plat/xapp/src/mapp/is41_code_ms.c new file mode 100644 index 0000000..ae43043 --- /dev/null +++ b/plat/xapp/src/mapp/is41_code_ms.c @@ -0,0 +1,3968 @@ +/* is41 coding auc service file */ +/* written by daniel zhang 2004-06-16 */ +/* modified by daniel on 2004-07-09 */ +/* -------------------------------- */ + +#include "map_includes.h" +/* external functions */ +void is41_log(char *info); +void is41_debug(DWORD mask, const char *fmt, ...); +void is41_showbuf(DWORD mask, BYTE *buf, int len); +int decode_Is41Parameter(char *tag,int len,BYTE *value,ASN_BUF *asn_buf); +char *is41_sequenceTag(char *tag,int sequence); + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding security triplets argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ + +int assign_is41RegistrationNotification_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag,flag1; + struct IS41_REGNOT_ARG *ptr; + struct IS41_PAR_WIN_CAP *ptr1; + char tag[64]; + + ptr = &opr_ptr->msg_list.regnot_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3),3,ptr->mscid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSCID absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //QualificationInformationCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_QUALCODE,4),1,&ptr->qualcode,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:QUALCODE absent!!"); + return 0; + } + + if((flag & BIT4_TRUE)>0) //SystemMyTypeCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,5),1,&ptr->mytyp,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MYTYP absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT5_TRUE)>0) //Availability Type + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AVTYP,6),1,&ptr->avtyp,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //BorderCellAccess + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BORDACC,7),1,&ptr->bordacc,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //ControlChannelData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCDATA,8),4,ptr->ccdata,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //ExtendedMSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_EXTMSCID,9),4,ptr->extmscid,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //LocationAreaID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,10),2,ptr->locid,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) //pcssn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,11),5,ptr->pcssn,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) //ReceivedSignalQuality + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSIGQUAL,12),1,&ptr->rsigqual,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) //rpttyp + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RPTTYP,13),1,&ptr->rpttyp,0x80,&asn_buf); + + if((flag & BIT13_TRUE)>0) //senderin + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,14),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT14_TRUE)>0) //SMS_DestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSADDR,15),ptr->smsaddrLen & MAX_IS41_VARPAR_LEN_1,ptr->smsaddr,0x80,&asn_buf); + + if((flag & BIT15_TRUE)>0) //smsmwi + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSMWI,16),0,&ptr->smsmwi,0x80,&asn_buf); + + if((flag & BIT16_TRUE)>0) //sysaccdata + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSACCDATA,16),5,ptr->sysaccdata,0x80,&asn_buf); + + if((flag & BIT17_TRUE)>0) //sysacctype + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSACCTYPE,17),1,&ptr->sysacctype,0x80,&asn_buf); + + if((flag & BIT18_TRUE)>0) //syscap + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSCAP,18),1,&ptr->syscap,0x80,&asn_buf); + + if((flag & BIT19_TRUE)>0) //termtyp + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTYP,19),1,&ptr->termtyp,0x80,&asn_buf); + + if((flag & BIT20_TRUE)>0) //transcap + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,20),ptr->transcapLen & MAX_IS41_VARPAR_LEN_1,ptr->transcap,0x80,&asn_buf); + + if((flag & BIT21_TRUE)>0) //wincap + { + ptr1 = &ptr->wincap; + flag1 = ptr1->param_flag; + if (!(flag1 & 0x03)) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:wincap no content!!"); + return 0; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_WINCAP,21),0,NULL,0xA0,&asn_buf); + if((flag1 & BIT0_TRUE)>0) //triggercapability + { + sprintf(tag,"%s.%s",IS41PAR_WINCAP,IS41PAR_TRIGCAP); + buf_len = AddTLV(is41_sequenceTag(tag,1),ptr1->triggercapLen & MAX_IS41_VARPAR_LEN_1,ptr1->triggercap,0x80,&asn_buf); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + sprintf(tag,"%s.%s",IS41PAR_WINCAP,IS41PAR_WINOPRCAP); + buf_len = AddTLV(is41_sequenceTag(tag,2),ptr1->winoprcapLen & MAX_IS41_VARPAR_LEN_1,ptr1->winoprcap,0x80,&asn_buf); + } + } + + return buf_len; +} + +int decode_param_profile(IS41_PAR_PROFILE *ptr,ASN_BUF *asn_buf) +{ + int len,i,count; + char tag[64]; + IS41_PAR_TRIGGER_LIST *ptr1; + + ptr->param_flag = 0; + + len = decode_Is41Parameter(IS41PAR_AUTHCAP,MAX_IS41_VARPAR_LEN,ptr->authcap,asn_buf); + if (len > 0) + { + ptr->authcapLen = len; + ptr->param_flag |= BIT0_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_CFI,MAX_IS41_VARPAR_LEN,ptr->cfi,asn_buf); + if (len > 0) + { + ptr->cfiLen = len; + ptr->param_flag |= BIT1_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_CARDGTS,MAX_IS41_VARPAR_LEN,ptr->cardgts,asn_buf); + if (len > 0) + { + ptr->cardgtsLen = len; + ptr->param_flag |= BIT2_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_ACDGTS,MAX_IS41_VARPAR_LEN,ptr->acdgts,asn_buf); + if (len > 0) + { + ptr->acdgtsLen = len; + ptr->param_flag |= BIT3_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_ABDGTS,MAX_IS41_VARPAR_LEN,ptr->abdgts,asn_buf); + if (len > 0) + { + ptr->abdgtsLen = len; + ptr->param_flag |= BIT4_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_BILLDGTS,MAX_IS41_VARPAR_LEN,ptr->billdgts,asn_buf); + if (len > 0) + { + ptr->billdgtsLen = len; + ptr->param_flag |= BIT5_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_GEOAUTH,MAX_IS41_VARPAR_LEN,ptr->geoauth,asn_buf); + if (len > 0) + { + ptr->geoauthLen = len; + ptr->param_flag |= BIT6_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_MWNCOUNT,MAX_IS41_VARPAR_LEN,ptr->mwncount,asn_buf); + if (len > 0) + { + ptr->mwncountLen = len; + ptr->param_flag |= BIT7_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_MWNCOUNT,MAX_IS41_VARPAR_LEN,ptr->mwncount,asn_buf); + if (len > 0) + { + ptr->mwncountLen = len; + ptr->param_flag |= BIT8_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_MDN,MAX_IS41_VARPAR_LEN,ptr->mdn,asn_buf); + if (len > 0) + { + ptr->mdnLen = len; + ptr->param_flag |= BIT9_TRUE; + } + + if (decode_Is41Parameter(IS41PAR_ORIGIND,1,&ptr->origind,asn_buf)) + ptr->param_flag |= BIT10_TRUE; + + len = decode_Is41Parameter(IS41PAR_ORIGTRIG,MAX_IS41_VARPAR_LEN,ptr->origtrig,asn_buf); + if (len > 0) + { + ptr->origtrigLen = len; + ptr->param_flag |= BIT11_TRUE; + } + + if (decode_Is41Parameter(IS41PAR_PACAIND,1,&ptr->pacaind,asn_buf)) + ptr->param_flag |= BIT12_TRUE; + + if (decode_Is41Parameter(IS41PAR_PLIND,1,&ptr->plind,asn_buf)) + ptr->param_flag |= BIT13_TRUE; + + len = decode_Is41Parameter(IS41PAR_RESDGTS,MAX_IS41_VARPAR_LEN,ptr->resdgts,asn_buf); + if (len > 0) + { + ptr->resdgtsLen = len; + ptr->param_flag |= BIT14_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_ROUTDGTS,MAX_IS41_VARPAR_LEN,ptr->routdgts,asn_buf); + if (len > 0) + { + ptr->routdgtsLen = len; + ptr->param_flag |= BIT15_TRUE; + } + + if (decode_Is41Parameter(IS41PAR_SMSORGRES,1,&ptr->smsorgres,asn_buf)) + ptr->param_flag |= BIT16_TRUE; + + if (decode_Is41Parameter(IS41PAR_SMSTERMRES,1,&ptr->smstermres,asn_buf)) + ptr->param_flag |= BIT17_TRUE; + + len = decode_Is41Parameter(IS41PAR_SPINIPIN,MAX_IS41_VARPAR_LEN,ptr->spinipin,asn_buf); + if (len > 0) + { + ptr->spinipinLen = len; + ptr->param_flag |= BIT18_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_SPINITRIG,MAX_IS41_VARPAR_LEN,ptr->spinitrig,asn_buf); + if (len > 0) + { + ptr->spinitrigLen = len; + ptr->param_flag |= BIT19_TRUE; + } + + if (decode_Is41Parameter(IS41PAR_TERMRES,1,&ptr->termres,asn_buf)) + ptr->param_flag |= BIT20_TRUE; + + len = decode_Is41Parameter(IS41PAR_TERMTRIG,MAX_IS41_VARPAR_LEN,ptr->termtrig,asn_buf); + if (len > 0) + { + ptr->termtrigLen = len; + ptr->param_flag |= BIT21_TRUE; + } + + ptr->triggerlistnum = 0; + for (i = 0; i < MAX_IS41_TRIG_LIST_NUM; i++) + { + ptr1 = &ptr->triggerlist[i]; + count = 0; + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_GLOBALTITLE); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->destaddr,asn_buf); + if (len > 0) + { + ptr1->param_flag |= BIT0_TRUE; + ptr1->destaddrLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_WINTRIGLIST); + if (get_null(tag,asn_buf)) + { + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->wintriglist,asn_buf); + if (len >= 0) + { + ptr1->param_flag |= BIT1_TRUE; + ptr1->wintriglistLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + } + if (count == 2) + { + ptr->triggerlistnum++; + ptr->param_flag |= BIT22_TRUE; + } + else if (count == 1) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + else if (!count) + break; + } + + if (ptr->param_flag>0) + return 1; + return 0; +} + +int encode_param_profile(struct IS41_PAR_PROFILE *ptr,u32 flag,ASN_BUF *asn_buf,int *buf_len) +{ + u32 flag1; + struct IS41_PAR_TRIGGER_LIST *ptr1; + u8 i,triglistnum; + char tag[64]; + + if((flag & BIT0_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHCAP,1),ptr->authcapLen & MAX_IS41_VARPAR_LEN_1,ptr->authcap,0x80,asn_buf); + if((flag & BIT1_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_CFI,2),ptr->cfiLen & MAX_IS41_VARPAR_LEN_1,ptr->cfi,0x80,asn_buf); + if((flag & BIT2_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_CARDGTS,3),ptr->cardgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->cardgts,0x80,asn_buf); + if((flag & BIT3_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,4),ptr->acdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->acdgts,0x80,asn_buf); + if((flag & BIT4_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,5),ptr->abdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->abdgts,0x80,asn_buf); + if((flag & BIT5_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,6),ptr->billdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->billdgts,0x80,asn_buf); + if((flag & BIT6_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_GEOAUTH,7),ptr->geoauthLen & MAX_IS41_VARPAR_LEN_1,ptr->geoauth,0x80,asn_buf); + if((flag & BIT7_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_MWNCOUNT,8),ptr->mwncountLen & MAX_IS41_VARPAR_LEN_1,ptr->mwncount,0x80,asn_buf); + if((flag & BIT8_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_MWNTYPE,9),ptr->mwntypeLen & MAX_IS41_VARPAR_LEN_1,ptr->mwntype,0x80,asn_buf); + if((flag & BIT9_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,10),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,asn_buf); + if((flag & BIT10_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_ORIGIND,11),1,&ptr->origind,0x80,asn_buf); + if((flag & BIT11_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_ORIGTRIG,12),ptr->origtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->origtrig,0x80,asn_buf); + if((flag & BIT12_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_PACAIND,13),1,&ptr->pacaind,0x80,asn_buf); + if((flag & BIT13_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_PLIND,14),1,&ptr->plind,0x80,asn_buf); + if((flag & BIT14_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_RESDGTS,15),ptr->resdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->resdgts,0x80,asn_buf); + if((flag & BIT15_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_ROUTDGTS,16),ptr->routdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->routdgts,0x80,asn_buf); + if((flag & BIT16_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSORGRES,17),1,&ptr->smsorgres,0x80,asn_buf); + if((flag & BIT17_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSTERMRES,18),1,&ptr->smstermres,0x80,asn_buf); + if((flag & BIT18_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_SPINIPIN,19),ptr->spinipinLen & MAX_IS41_VARPAR_LEN_1,ptr->spinipin,0x80,asn_buf); + if((flag & BIT19_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_SPINITRIG,20),ptr->spinitrigLen & MAX_IS41_VARPAR_LEN_1,ptr->spinitrig,0x80,asn_buf); + if((flag & BIT20_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMRES,21),1,&ptr->termres,0x80,asn_buf); + if((flag & BIT21_TRUE)>0) + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,22),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,asn_buf); + + if((flag & BIT22_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + if (!triglistnum) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:TriggerAddressList no content!!"); + return 0; + } + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGADRLIST,23),0,NULL,0xA0,asn_buf); + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + if ((flag1 & 0x03) != 0x03) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + sprintf(tag,"%s.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST); + *buf_len = AddTLV(is41_sequenceTag(tag,i+1),0,NULL,0xA0,asn_buf); + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_GLOBALTITLE); + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr1->destaddrLen & MAX_IS41_VARPAR_LEN_1,ptr1->destaddr,0x80,asn_buf); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_WINTRIGLIST); + *buf_len = AddTLV(is41_sequenceTag(tag,2),ptr1->wintriglistLen & MAX_IS41_VARPAR_LEN_1,ptr1->wintriglist,0x80,asn_buf); + } + } + } + + return 1; +} + +int encode_param_isterm(struct IS41_PAR_ISTERM *ptr,u32 flag,ASN_BUF *asn_buf,int *buf_len) +{ + char tag[64]; + + if((flag & BIT0_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_DESTDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->destdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->destdgts,0x80,asn_buf); + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:DestinationDigits absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //MSCID + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_MSCID); + *buf_len = AddTLV(is41_sequenceTag(tag,2),3,ptr->mscid,0x80,asn_buf); + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSCID absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT2_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_ACCDEN); + *buf_len = AddTLV(is41_sequenceTag(tag,3),1,&ptr->accden,0x80,asn_buf); + } + if((flag & BIT3_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_CARDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->cardgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->cardgts,0x80,asn_buf); + } + if((flag & BIT4_TRUE)>0) //esn + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_ESN); + *buf_len = AddTLV(is41_sequenceTag(tag,5),ESN_LEN,ptr->esn,0x80,asn_buf); + } + if((flag & BIT5_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_LEGINFO); + *buf_len = AddTLV(is41_sequenceTag(tag,6),ptr->leginfoLen & MAX_IS41_VARPAR_LEN_1,ptr->leginfo,0x80,asn_buf); + } + if((flag & BIT6_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_MDN); + *buf_len = AddTLV(is41_sequenceTag(tag,7),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,asn_buf); + } + if((flag & BIT7_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_MSCIN); + *buf_len = AddTLV(is41_sequenceTag(tag,8),ptr->mscinLen & MAX_IS41_VARPAR_LEN_1,ptr->mscin,0x80,asn_buf); + } + if((flag & BIT8_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_ROUTDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,9),ptr->routdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->routdgts,0x80,asn_buf); + } + if((flag & BIT9_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_TERMTRIG); + *buf_len = AddTLV(is41_sequenceTag(tag,10),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,asn_buf); + } + return 1; +} + +int encode_param_locterm(struct IS41_PAR_LOCTERM *ptr,u32 flag,ASN_BUF *asn_buf,int *buf_len) +{ + char tag[64]; + + if((flag & BIT0_TRUE)>0) //esn + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_ESN); + *buf_len = AddTLV(is41_sequenceTag(tag,1),ESN_LEN,ptr->esn,0x80,asn_buf); + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_MIN); + *buf_len = AddTLV(is41_sequenceTag(tag,2),MIN_LEN,ptr->min,0x80,asn_buf); + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + if((flag & BIT2_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_TERMTRMT); + *buf_len = AddTLV(is41_sequenceTag(tag,3),ptr->termtrmtLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrmt,0x80,asn_buf); + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:termtrmt absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT3_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_ALRTCODE); + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->alrtcodeLen & MAX_IS41_VARPAR_LEN_1,ptr->alrtcode,0x80,asn_buf); + } + if((flag & BIT4_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_CARDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,5),ptr->cardgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->cardgts,0x80,asn_buf); + } + if((flag & BIT5_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_DESTDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,6),ptr->destdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->destdgts,0x80,asn_buf); + } + if((flag & BIT6_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_LEGINFO); + *buf_len = AddTLV(is41_sequenceTag(tag,7),ptr->leginfoLen & MAX_IS41_VARPAR_LEN_1,ptr->leginfo,0x80,asn_buf); + } + if((flag & BIT7_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_MDN); + *buf_len = AddTLV(is41_sequenceTag(tag,8),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,asn_buf); + } + if((flag & BIT8_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_OTFI); + *buf_len = AddTLV(is41_sequenceTag(tag,9),ptr->otfiLen & MAX_IS41_VARPAR_LEN_1,ptr->otfi,0x80,asn_buf); + } + if((flag & BIT9_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_ROUTDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,10),ptr->routdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->routdgts,0x80,asn_buf); + } + if((flag & BIT10_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_TERMTRIG); + *buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,11),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,asn_buf); + } + if((flag & BIT11_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_VMSPIN); + *buf_len = AddTLV(is41_sequenceTag(tag,12),ptr->vmspinLen & MAX_IS41_VARPAR_LEN_1,ptr->vmspin,0x80,asn_buf); + } + if((flag & BIT12_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_VMBOX); + *buf_len = AddTLV(is41_sequenceTag(tag,13),ptr->vmboxLen & MAX_IS41_VARPAR_LEN_1,ptr->vmbox,0x80,asn_buf); + } + return 1; +} + +int encode_param_pstnterm(struct IS41_PAR_PSTNTERM *ptr,u32 flag,ASN_BUF *asn_buf,int *buf_len) +{ + char tag[64]; + + if((flag & BIT0_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_DESTDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->destdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->destdgts,0x80,asn_buf); + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:DestinationDigits absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT1_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_CARDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,2),ptr->cardgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->cardgts,0x80,asn_buf); + } + + if((flag & BIT2_TRUE)>0) //esn + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_ESN); + *buf_len = AddTLV(is41_sequenceTag(tag,3),ESN_LEN,ptr->esn,0x80,asn_buf); + } + if((flag & BIT3_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_LEGINFO); + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->leginfoLen & MAX_IS41_VARPAR_LEN_1,ptr->leginfo,0x80,asn_buf); + } + + if((flag & BIT4_TRUE)>0) //min + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_MIN); + *buf_len = AddTLV(is41_sequenceTag(tag,5),MIN_LEN,ptr->min,0x80,asn_buf); + } + if((flag & BIT5_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_ROUTDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,6),ptr->routdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->routdgts,0x80,asn_buf); + } + if((flag & BIT6_TRUE)>0) + { + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_TERMTRIG); + *buf_len = AddTLV(is41_sequenceTag(tag,7),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,asn_buf); + } + + return 1; +} + +int encode_param_termlist(struct IS41_PAR_TERMLIST *ptr,u32 flag,ASN_BUF *asn_buf,int *buf_len) +{ + if ((flag & BIT0_TRUE) > 0) + { + if (!encode_param_isterm(&ptr->isterm,ptr->isterm.param_flag,asn_buf,buf_len)) + return 0; + } + + if ((flag & BIT1_TRUE) > 0) + { + if (!encode_param_locterm(&ptr->locterm,ptr->locterm.param_flag,asn_buf,buf_len)) + return 0; + } + + if ((flag & BIT2_TRUE) > 0) + { + if (!encode_param_pstnterm(&ptr->pstnterm,ptr->pstnterm.param_flag,asn_buf,buf_len)) + return 0; + } + + return 1; +} + +int decode_param_isterm(IS41_PAR_ISTERM *ptr,ASN_BUF *asn_buf) +{ + int len; + char tag[64]; + + ptr->param_flag = 0; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_DESTDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->destdgts,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT0_TRUE; + ptr->destdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:DestinationDigits absent!"); + return 0; + } + + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_MSCID); + if (decode_Is41Parameter(tag,3,ptr->mscid,asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + +//optional + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_ACCDEN); + if (decode_Is41Parameter(tag,1,&ptr->accden,asn_buf)) + ptr->param_flag |= BIT2_TRUE; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_BILLID); + if (decode_Is41Parameter(tag,7,ptr->billid,asn_buf)) + ptr->param_flag |= BIT3_TRUE; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_CARDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->cardgts,asn_buf); + if (len > 0) + { + ptr->cardgtsLen = len; + ptr->param_flag |= BIT4_TRUE; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_ESN); + if (decode_Is41Parameter(tag,ESN_LEN,ptr->esn,asn_buf)) + ptr->param_flag |= BIT5_TRUE; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_LEGINFO); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->leginfo,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->leginfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_MDN); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->mdn,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->mdnLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_MIN); + if (decode_Is41Parameter(tag,MIN_LEN,ptr->min,asn_buf)) + ptr->param_flag |= BIT8_TRUE; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_MSCIN); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->mscin,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->mscinLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_ROUTDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->routdgts,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->routdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_ISTERM,IS41PAR_TERMTRIG); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->termtrig,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->termtrigLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (ptr->param_flag>0) + return 1; + return 0; +} + +int decode_param_locterm(IS41_PAR_LOCTERM *ptr,ASN_BUF *asn_buf) +{ + int len; + char tag[64]; + + ptr->param_flag = 0; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_ESN); + if (decode_Is41Parameter(tag,ESN_LEN,ptr->esn,asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_MIN); + if (decode_Is41Parameter(tag,MIN_LEN,ptr->min,asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_TERMTRMT); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->termtrmt,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT2_TRUE; + ptr->termtrmtLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:termtrmt absent!"); + return 0; + } + +//optional + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_ALRTCODE); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->alrtcode,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->alrtcodeLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_CARDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->cardgts,asn_buf); + if (len > 0) + { + ptr->cardgtsLen = len; + ptr->param_flag |= BIT4_TRUE; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_DESTDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->destdgts,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->destdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_LEGINFO); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->leginfo,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->leginfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_MDN); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->mdn,asn_buf); + if (len > 0) + { + ptr->mdnLen = len; + ptr->param_flag |= BIT7_TRUE; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_OTFI); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->otfi,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->otfiLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_ROUTDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->routdgts,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->routdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_TERMTRIG); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->termtrig,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->termtrigLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_VMSPIN); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->vmspin,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->vmspinLen = len & MAX_IS41_VARPAR_LEN_1; + } + + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_LOCTERM,IS41PAR_VMBOX); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->vmbox,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT12_TRUE; + ptr->vmboxLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (ptr->param_flag>0) + return 1; + return 0; +} + +int decode_param_pstnterm(IS41_PAR_PSTNTERM *ptr,ASN_BUF *asn_buf) +{ + int len; + char tag[64]; + + ptr->param_flag = 0; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_DESTDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->destdgts,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT0_TRUE; + ptr->destdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:DestinationDigits absent!"); + return 0; + } + +//optional + + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_CARDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->cardgts,asn_buf); + if (len > 0) + { + ptr->cardgtsLen = len; + ptr->param_flag |= BIT1_TRUE; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_ESN); + if (decode_Is41Parameter(tag,ESN_LEN,ptr->esn,asn_buf)) + ptr->param_flag |= BIT2_TRUE; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_LEGINFO); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->leginfo,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->leginfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_MIN); + if (decode_Is41Parameter(tag,MIN_LEN,ptr->min,asn_buf)) + ptr->param_flag |= BIT4_TRUE; + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_ROUTDGTS); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->routdgts,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->routdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + sprintf(tag,"%s.%s.%s",IS41PAR_TERMLIST,IS41PAR_PSTNTERM,IS41PAR_TERMTRIG); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->termtrig,asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->termtrigLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (ptr->param_flag>0) + return 1; + return 0; +} + +int decode_param_termlist(IS41_PAR_TERMLIST *ptr,ASN_BUF *asn_buf) +{ + u8 count=0; + + ptr->param_flag = 0; + + if (decode_param_isterm(&ptr->isterm,asn_buf) > 0) + ptr->param_flag |= BIT0_TRUE; + else + count ++; + + if (decode_param_locterm(&ptr->locterm,asn_buf) > 0) + ptr->param_flag |= BIT1_TRUE; + else + count ++; + + if (decode_param_pstnterm(&ptr->pstnterm,asn_buf) > 0) + ptr->param_flag |= BIT2_TRUE; + else + count ++; + + if (count > 0) + return 1; + return 0; +} + + +int assign_is41RegistrationNotification_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + u32 flag; + ASN_BUF asn_buf; + int buf_len=0; + struct IS41_REGNOT_RSP *ptr; + + ptr = &opr_ptr->msg_list.regnot_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //SystemMyTypeCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,1),1,&ptr->mytyp,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MYTYP absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT1_TRUE)>0) //AuthorizationDenied + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHDEN,2),1,&ptr->authden,0x80,&asn_buf); + + if((flag & BIT2_TRUE)>0) //AuthorizationPeriod + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHPER,3),2,ptr->authper,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //ControlChannelData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCDATA,4),4,ptr->ccdata,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //DeniedAuthorizationPeriod + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DENAUTHPER,5),ptr->denauthperLen & MAX_IS41_VARPAR_LEN_1,ptr->denauthper,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //Digits carrier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,6),ptr->digitsCarrierLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsCarrier,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //Digits Destination + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,7),ptr->digitsDestLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsDest,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,8),3,ptr->mscid,0x80,&asn_buf); + +/* Profile **macro** */ + if ((flag & BIT8_TRUE) > 0) + { + if (!encode_param_profile(&ptr->profile,ptr->profile.param_flag,&asn_buf,&buf_len)) + return 0; + } +/* Profile **macro** */ + + if((flag & BIT9_TRUE)>0) //ReceivedSignalQuality + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSIGQUAL,9),1,&ptr->rsigqual,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) //senderin + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,10),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) //smsmwi + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSMWI,11),0,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) //sysaccdata + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSACCDATA,12),5,ptr->sysaccdata,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41RegistrationNotification_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_REGNOT_ARG *ptr; + int len; + char tag[64]; + + ptr = &opr_ptr->msg_list.regnot_arg; + + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,24,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_QUALCODE,1,&ptr->qualcode,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:QUALCODE absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MYTYP,1,&ptr->mytyp,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MYTYP absent!"); + return 0; + } + + + +//optional par---> + if (decode_Is41Parameter(IS41PAR_AVTYP,1,&ptr->avtyp,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter(IS41PAR_BORDACC,1,&ptr->bordacc,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter(IS41PAR_CCDATA,4,ptr->ccdata,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter(IS41PAR_EXTMSCID,4,ptr->extmscid,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if (decode_Is41Parameter(IS41PAR_LOCID,2,ptr->locid,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if (decode_Is41Parameter(IS41PAR_PCSSN,5,ptr->pcssn,&asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if (decode_Is41Parameter(IS41PAR_RSIGQUAL,1,&ptr->rsigqual,&asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if (decode_Is41Parameter(IS41PAR_RPTTYP,1,&ptr->rpttyp,&asn_buf)) + ptr->param_flag |= BIT12_TRUE; + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT13_TRUE; + } + len = decode_Is41Parameter(IS41PAR_SMSADDR,MAX_IS41_VARPAR_LEN,ptr->smsaddr,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT14_TRUE; + ptr->smsaddrLen = len & MAX_IS41_VARPAR_LEN_1; + } + + //smsmwi + + if (decode_Is41Parameter(IS41PAR_SYSACCDATA,5,ptr->sysaccdata,&asn_buf)) + ptr->param_flag |= BIT16_TRUE; + if (decode_Is41Parameter(IS41PAR_SYSACCTYPE,1,&ptr->sysacctype,&asn_buf)) + ptr->param_flag |= BIT17_TRUE; + if (decode_Is41Parameter(IS41PAR_SYSCAP,1,&ptr->syscap,&asn_buf)) + ptr->param_flag |= BIT18_TRUE; + if (decode_Is41Parameter(IS41PAR_TERMTYP,1,&ptr->termtyp,&asn_buf)) + ptr->param_flag |= BIT19_TRUE; + len = decode_Is41Parameter(IS41PAR_TRANSCAP,MAX_IS41_VARPAR_LEN,ptr->transcap,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT20_TRUE; + ptr->transcapLen = len & MAX_IS41_VARPAR_LEN_1; + } + + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_TRIGCAP); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->wincap.triggercap,&asn_buf); + if (len > 0) + { + ptr->wincap.param_flag |= BIT0_TRUE; + ptr->wincap.triggercapLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT21_TRUE; + } + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_WINOPRCAP); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->wincap.winoprcap,&asn_buf); + if (len > 0) + { + ptr->wincap.param_flag |= BIT1_TRUE; + ptr->wincap.winoprcapLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT21_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int extract_is41RegistrationNotification_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_REGNOT_RSP *ptr; + int len; + + ptr = &opr_ptr->msg_list.regnot_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + + if(AsnDecode(buf,buf_len,43,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_MYTYP,1,&ptr->mytyp,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MYTYP absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_AUTHDEN,1,&ptr->authden,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if (decode_Is41Parameter(IS41PAR_AUTHPER,2,ptr->authper,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter(IS41PAR_CCDATA,4,ptr->ccdata,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + len = decode_Is41Parameter(IS41PAR_DENAUTHPER,MAX_IS41_VARPAR_LEN,ptr->denauthper,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->denauthperLen = len & MAX_IS41_VARPAR_LEN_1; + } + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsCarrier,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->digitsCarrierLen = len & MAX_IS41_VARPAR_LEN_1; + } + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsDest,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->digitsDestLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + +/* Profile **macro** */ + if (decode_param_profile(&ptr->profile,&asn_buf) > 0) + ptr->param_flag |= BIT8_TRUE; +/* Profile **macro** */ + + + if (decode_Is41Parameter(IS41PAR_RSIGQUAL,1,&ptr->rsigqual,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT10_TRUE; + } + + //smsmwi + + if (decode_Is41Parameter(IS41PAR_SYSACCDATA,5,ptr->sysaccdata,&asn_buf)) + ptr->param_flag |= BIT12_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41RegistrationCancellation_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_REGCANC_ARG *ptr; + + ptr = &opr_ptr->msg_list.regcanc_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT2_TRUE)>0) //Cancellation Type + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CANTP,3),ptr->canctyplen & 3,ptr->canctyp,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //ControlChannelData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCDATA,4),4,ptr->ccdata,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //ReceivedSignalQuality + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSIGQUAL,5),1,&ptr->rsigqual,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //senderin + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,6),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //sysaccdata + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSACCDATA,7),5,ptr->sysaccdata,0x80,&asn_buf); + + return buf_len; +} + +int assign_is41RegistrationCancellation_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + u32 flag; + ASN_BUF asn_buf; + int buf_len=0; + struct IS41_REGCANC_RSP *ptr; + + ptr = &opr_ptr->msg_list.regcanc_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + +// optional part---> + if((flag & BIT0_TRUE)>0) //CallHistoryCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,3),1,&ptr->count,0x80,&asn_buf); + + if((flag & BIT1_TRUE)>0) //CancellationDenied + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CANCD,3),1,&ptr->cancdenied,0x80,&asn_buf); + + if((flag & BIT2_TRUE)>0) //ControlChannelData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCDATA,4),4,ptr->ccdata,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //ReceivedSignalQuality + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSIGQUAL,5),1,&ptr->rsigqual,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //smsmwi + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSMWI,16),0,&ptr->smsmwi,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //sysaccdata + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SYSACCDATA,7),5,ptr->sysaccdata,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41RegistrationCancellation_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_REGCANC_ARG *ptr; + int len; + + ptr = &opr_ptr->msg_list.regcanc_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,24,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_CANTP,4,ptr->canctyp,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter(IS41PAR_CCDATA,4,ptr->ccdata,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if (decode_Is41Parameter(IS41PAR_RSIGQUAL,1,&ptr->rsigqual,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT5_TRUE; + } + if (decode_Is41Parameter(IS41PAR_SYSACCDATA,5,ptr->sysaccdata,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int extract_is41RegistrationCancellation_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_REGCANC_RSP *ptr; + + ptr = &opr_ptr->msg_list.regcanc_rsp; + + if(AsnDecode(buf,buf_len,43,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + +//optional par---> + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if (decode_Is41Parameter(IS41PAR_CANCD,2,&ptr->cancdenied,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if (decode_Is41Parameter(IS41PAR_CCDATA,4,ptr->ccdata,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + + if (decode_Is41Parameter(IS41PAR_RSIGQUAL,1,&ptr->rsigqual,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + + if (decode_Is41Parameter(IS41PAR_SMSMWI,0,ptr->sysaccdata,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + + if (decode_Is41Parameter(IS41PAR_SYSACCDATA,5,ptr->sysaccdata,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41LocationRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag,flag1; + struct IS41_LOCREQ_ARG *ptr; + struct IS41_PAR_WIN_CAP *ptr1; + char tag[64]; + + ptr = &opr_ptr->msg_list.locreq_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1),7,ptr->billid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:BILLID absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,2),ptr->digitsLen & MAX_IS41_VARPAR_LEN_1,ptr->digits,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:Digits absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3),3,ptr->mscid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSCID absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //SystemMyTypeCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,4),1,&ptr->mytyp,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MYTYP absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS1,5),ptr->cpndgts1Len & MAX_IS41_VARPAR_LEN_1,ptr->cpndgts1,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS2,6),ptr->cpndgts2Len & MAX_IS41_VARPAR_LEN_1,ptr->cpndgts2,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,7),ptr->cpsubLen & MAX_IS41_VARPAR_LEN_1,ptr->cpsub,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,8),ptr->mscinLen & MAX_IS41_VARPAR_LEN_1,ptr->mscin,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,9),5,ptr->pcssn,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNDGTS,10),ptr->rndgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->rndgts,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSUB,11),ptr->rsubLen & MAX_IS41_VARPAR_LEN_1,ptr->rsub,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TAT,12),1,&ptr->tat,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,13),ptr->transcapLen & MAX_IS41_VARPAR_LEN_1,ptr->transcap,0x80,&asn_buf); + + if((flag & BIT13_TRUE)>0) //wincap + { + ptr1 = &ptr->wincap; + flag1 = ptr1->param_flag; + if (!(flag1 & 0x03)) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:wincap no content!!"); + return 0; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_WINCAP,14),0,NULL,0xA0,&asn_buf); + if((flag1 & BIT0_TRUE)>0) //triggercapability + { + sprintf(tag,"%s.%s",IS41PAR_WINCAP,IS41PAR_TRIGCAP); + buf_len = AddTLV(is41_sequenceTag(tag,1),ptr1->triggercapLen & MAX_IS41_VARPAR_LEN_1,ptr1->triggercap,0x80,&asn_buf); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + sprintf(tag,"%s.%s",IS41PAR_WINCAP,IS41PAR_WINOPRCAP); + buf_len = AddTLV(is41_sequenceTag(tag,2),ptr1->winoprcapLen & MAX_IS41_VARPAR_LEN_1,ptr1->winoprcap,0x80,&asn_buf); + } + } + + return buf_len; +} + +int extract_is41LocationRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_LOCREQ_ARG *ptr; + int len; + char tag[64]; + + ptr = &opr_ptr->msg_list.locreq_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,17,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_BILLID,7,ptr->billid,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:BILLID absent!"); + return 0; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digits,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT1_TRUE; + ptr->digitsLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:Digits absent!!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MYTYP,1,&ptr->mytyp,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MYTYP absent!"); + return 0; + } + +//optional par---> + len = decode_Is41Parameter(IS41PAR_CPNDGTS1,MAX_IS41_VARPAR_LEN,ptr->cpndgts1,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->cpndgts1Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNDGTS2,MAX_IS41_VARPAR_LEN,ptr->cpndgts2,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->cpndgts2Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPSUB,MAX_IS41_VARPAR_LEN,ptr->cpsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->cpsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_MSCIN,MAX_IS41_VARPAR_LEN,ptr->mscin,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->mscinLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_PCSSN,5,ptr->pcssn,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + + len = decode_Is41Parameter(IS41PAR_RNDGTS,MAX_IS41_VARPAR_LEN,ptr->rndgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->rndgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RSUB,MAX_IS41_VARPAR_LEN,ptr->rsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->rsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_TAT,1,&ptr->tat,&asn_buf)) + ptr->param_flag |= BIT11_TRUE; + + len = decode_Is41Parameter(IS41PAR_TRANSCAP,MAX_IS41_VARPAR_LEN,ptr->transcap,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT12_TRUE; + ptr->transcapLen = len & MAX_IS41_VARPAR_LEN_1; + } + + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_TRIGCAP); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->wincap.triggercap,&asn_buf); + if (len > 0) + { + ptr->wincap.param_flag |= BIT0_TRUE; + ptr->wincap.triggercapLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT13_TRUE; + } + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_WINOPRCAP); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->wincap.winoprcap,&asn_buf); + if (len > 0) + { + ptr->wincap.param_flag |= BIT1_TRUE; + ptr->wincap.winoprcapLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT14_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + + +int assign_is41LocationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag,flag1; + struct IS41_LOCREQ_RSP *ptr; + struct IS41_PAR_TRIGGER_LIST *ptr1; + u8 i,triglistnum; + char tag[64]; + + ptr = &opr_ptr->msg_list.locreq_rsp; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3),3,ptr->mscid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSCID absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT3_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACCDEN,4),1,&ptr->accden,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,5),ptr->annlistLen & MAX_IS41_VARPAR_LEN_1,ptr->annlist,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG1,6),ptr->cpnstrg1Len & MAX_IS41_VARPAR_LEN_1,ptr->cpnstrg1,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG2,7),ptr->cpnstrg2Len & MAX_IS41_VARPAR_LEN_1,ptr->cpnstrg2,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,8),ptr->digitsCarrierLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsCarrier,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,9),ptr->digitsDestLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsDest,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,10),ptr->acdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->acdgts,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,11),ptr->abdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->abdgts,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,12),ptr->billdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->billdgts,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDIND,13),ptr->redindLen & MAX_IS41_VARPAR_LEN_1,ptr->redind,0x80,&asn_buf); + + if((flag & BIT13_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_GRPINFO,14),ptr->grpinfoLen & MAX_IS41_VARPAR_LEN_1,ptr->grpinfo,0x80,&asn_buf); + +// if((flag & BIT11_TRUE)>0) + // buf_len = AddTLV(is41_sequenceTag(IS41PAR_TAT,12),1,&ptr->tat,0x80,&asn_buf); + + if((flag & BIT14_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,15),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,&asn_buf); + + if((flag & BIT15_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NATIME,16),ptr->natimeLen & MAX_IS41_VARPAR_LEN_1,ptr->natime,0x80,&asn_buf); + + if((flag & BIT16_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,17),ptr->otfiLen & MAX_IS41_VARPAR_LEN_1,ptr->otfi,0x80,&asn_buf); + + if((flag & BIT17_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,18),5,ptr->pcssn,0x80,&asn_buf); + + if((flag & BIT18_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNDGTS,19),ptr->rndgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->rndgts,0x80,&asn_buf); + + if((flag & BIT19_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNSTRING,20),ptr->rnstringLen & MAX_IS41_VARPAR_LEN_1,ptr->rnstring,0x80,&asn_buf); + + if((flag & BIT20_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSUB,21),ptr->rsubLen & MAX_IS41_VARPAR_LEN_1,ptr->rsub,0x80,&asn_buf); + + if((flag & BIT21_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ROUTDGTS,22),ptr->routdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->routdgts,0x80,&asn_buf); + + if ((flag & BIT22_TRUE) > 0) + { + if (!encode_param_termlist(&ptr->termlist,ptr->termlist.param_flag,&asn_buf,&buf_len)) + return 0; + } + + if((flag & BIT23_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,24),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,&asn_buf); + + if((flag & BIT24_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + if (!triglistnum) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:TriggerAddressList no content!!"); + return 0; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGADRLIST,25),0,NULL,0xA0,&asn_buf); + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + if ((flag1 & 0x03) != 0x03) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + sprintf(tag,"%s.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST); + buf_len = AddTLV(is41_sequenceTag(tag,i+1),0,NULL,0xA0,&asn_buf); + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_GLOBALTITLE); + buf_len = AddTLV(is41_sequenceTag(tag,1),ptr1->destaddrLen & MAX_IS41_VARPAR_LEN_1,ptr1->destaddr,0x80,&asn_buf); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_WINTRIGLIST); + buf_len = AddTLV(is41_sequenceTag(tag,2),ptr1->wintriglistLen & MAX_IS41_VARPAR_LEN_1,ptr1->wintriglist,0x80,&asn_buf); + } + } + } + + return buf_len; +} + +int extract_is41LocationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_LOCREQ_RSP *ptr; + IS41_PAR_TRIGGER_LIST *ptr1; + int len,i,count; + char tag[64]; + + ptr = &opr_ptr->msg_list.locreq_rsp; + + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,33,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ACCDEN,1,&ptr->accden,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + + len = decode_Is41Parameter(IS41PAR_ANNLIST,MAX_IS41_VARPAR_LEN,ptr->annlist,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->annlistLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNSTRG1,MAX_IS41_VARPAR_LEN,ptr->cpnstrg1,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->cpnstrg1Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNSTRG2,MAX_IS41_VARPAR_LEN,ptr->cpnstrg2,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->cpnstrg2Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsCarrier,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->digitsCarrierLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsDest,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->digitsDestLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ACDGTS,MAX_IS41_VARPAR_LEN,ptr->acdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->acdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ABDGTS,MAX_IS41_VARPAR_LEN,ptr->abdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->abdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_BILLDGTS,MAX_IS41_VARPAR_LEN,ptr->billdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->billdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_REDIND,MAX_IS41_VARPAR_LEN,ptr->redind,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT12_TRUE; + ptr->redindLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_GRPINFO,MAX_IS41_VARPAR_LEN,ptr->grpinfo,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT13_TRUE; + ptr->grpinfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_MDN,MAX_IS41_VARPAR_LEN,ptr->mdn,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT14_TRUE; + ptr->mdnLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_NATIME,MAX_IS41_VARPAR_LEN,ptr->natime,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT15_TRUE; + ptr->natimeLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_OTFI,MAX_IS41_VARPAR_LEN,ptr->otfi,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT16_TRUE; + ptr->otfiLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_PCSSN,5,ptr->pcssn,&asn_buf)) + ptr->param_flag |= BIT17_TRUE; + + len = decode_Is41Parameter(IS41PAR_RNDGTS,MAX_IS41_VARPAR_LEN,ptr->rndgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT18_TRUE; + ptr->rndgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RNSTRING,MAX_IS41_VARPAR_LEN,ptr->rnstring,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT19_TRUE; + ptr->rnstringLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RSUB,MAX_IS41_VARPAR_LEN,ptr->rsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT20_TRUE; + ptr->rsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ROUTDGTS,MAX_IS41_VARPAR_LEN,ptr->routdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT21_TRUE; + ptr->routdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_param_termlist(&ptr->termlist,&asn_buf) > 0) + ptr->param_flag |= BIT22_TRUE; + + len = decode_Is41Parameter(IS41PAR_TERMTRIG,MAX_IS41_VARPAR_LEN,ptr->termtrig,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT23_TRUE; + ptr->termtrigLen = len & MAX_IS41_VARPAR_LEN_1; + } + + ptr->triggerlistnum = 0; + for (i = 0; i < MAX_IS41_TRIG_LIST_NUM; i++) + { + ptr1 = &ptr->triggerlist[i]; + count = 0; + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_GLOBALTITLE); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->destaddr,&asn_buf); + if (len > 0) + { + ptr1->param_flag |= BIT0_TRUE; + ptr1->destaddrLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_WINTRIGLIST); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->wintriglist,&asn_buf); + if (len > 0) + { + ptr1->param_flag |= BIT1_TRUE; + ptr1->wintriglistLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + if (count == 2) + { + ptr->triggerlistnum++; + ptr->param_flag |= BIT24_TRUE; + } + else if (count == 1) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + else if (!count) + break; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41RoutingRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_ROUTREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.routreq_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1),7,ptr->billid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:BILLID absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT2_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,3),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,4),3,ptr->mscid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSCID absent!!"); + return 0; + } + + if((flag & BIT4_TRUE)>0) //SystemMyTypeCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,5),1,&ptr->mytyp,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MYTYP absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ALRTCODE,6),ptr->alrtcodeLen & MAX_IS41_VARPAR_LEN_1,ptr->alrtcode,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG1,7),ptr->cpnstrg1Len & MAX_IS41_VARPAR_LEN_1,ptr->cpnstrg1,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG2,8),ptr->cpnstrg2Len & MAX_IS41_VARPAR_LEN_1,ptr->cpnstrg2,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,9),ptr->cpsubLen & MAX_IS41_VARPAR_LEN_1,ptr->cpsub,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DESTDGTS,10),ptr->destdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->destdgts,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,11),ptr->acdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->acdgts,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,12),ptr->abdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->abdgts,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,13),ptr->billdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->billdgts,0x80,&asn_buf); + + if((flag & BIT13_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LEGINFO,14),ptr->leginfoLen & MAX_IS41_VARPAR_LEN_1,ptr->leginfo,0x80,&asn_buf); + + if((flag & BIT14_TRUE)>0) //LocationAreaID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,15),2,ptr->locid,0x80,&asn_buf); + + if((flag & BIT15_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,16),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,&asn_buf); + + if((flag & BIT16_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,17),ptr->mscinLen & MAX_IS41_VARPAR_LEN_1,ptr->mscin,0x80,&asn_buf); + + if((flag & BIT17_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NATIME,18),ptr->natimeLen & MAX_IS41_VARPAR_LEN_1,ptr->natime,0x80,&asn_buf); + + if((flag & BIT18_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,19),ptr->otfiLen & MAX_IS41_VARPAR_LEN_1,ptr->otfi,0x80,&asn_buf); + + if((flag & BIT19_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,20),5,ptr->pcssn,0x80,&asn_buf); + + if((flag & BIT20_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PILOTBID,21),7,ptr->pilotbid,0x80,&asn_buf); + + if((flag & BIT21_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PILOT,22),ptr->pilotLen & MAX_IS41_VARPAR_LEN_1,ptr->pilot,0x80,&asn_buf); + + if((flag & BIT22_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNSTRING,23),ptr->rnstringLen & MAX_IS41_VARPAR_LEN_1,ptr->rnstring,0x80,&asn_buf); + + if((flag & BIT23_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSUB,24),ptr->rsubLen & MAX_IS41_VARPAR_LEN_1,ptr->rsub,0x80,&asn_buf); + + if((flag & BIT24_TRUE)>0) //senderin + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,25),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT25_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRMT,26),ptr->termtrmtLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrmt,0x80,&asn_buf); + + if((flag & BIT26_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,27),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,&asn_buf); + + if((flag & BIT27_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_VMBOX,28),ptr->vmboxLen & MAX_IS41_VARPAR_LEN_1,ptr->vmbox,0x80,&asn_buf); + + if((flag & BIT28_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_VMSPIN,29),ptr->vmspinLen & MAX_IS41_VARPAR_LEN_1,ptr->vmspin,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41RoutingRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ROUTREQ_ARG *ptr; + int len; + + ptr = &opr_ptr->msg_list.routreq_arg; + + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,29,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_BILLID,7,ptr->billid,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:BILLID absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MYTYP,1,&ptr->mytyp,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MYTYP absent!"); + return 0; + } + +//optional par---> + len = decode_Is41Parameter(IS41PAR_ALRTCODE,MAX_IS41_VARPAR_LEN,ptr->alrtcode,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->alrtcodeLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNSTRG1,MAX_IS41_VARPAR_LEN,ptr->cpnstrg1,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->cpnstrg1Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNSTRG2,MAX_IS41_VARPAR_LEN,ptr->cpnstrg2,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->cpnstrg2Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPSUB,MAX_IS41_VARPAR_LEN,ptr->cpsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->cpsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DESTDGTS,MAX_IS41_VARPAR_LEN,ptr->destdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->destdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ACDGTS,MAX_IS41_VARPAR_LEN,ptr->acdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->acdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ABDGTS,MAX_IS41_VARPAR_LEN,ptr->abdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->abdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_BILLDGTS,MAX_IS41_VARPAR_LEN,ptr->billdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT12_TRUE; + ptr->billdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_LEGINFO,MAX_IS41_VARPAR_LEN,ptr->leginfo,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT13_TRUE; + ptr->leginfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_LOCID,2,ptr->locid,&asn_buf)) + ptr->param_flag |= BIT14_TRUE; + + len = decode_Is41Parameter(IS41PAR_MDN,MAX_IS41_VARPAR_LEN,ptr->mdn,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT15_TRUE; + ptr->mdnLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_MSCIN,MAX_IS41_VARPAR_LEN,ptr->mscin,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT16_TRUE; + ptr->mscinLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_NATIME,MAX_IS41_VARPAR_LEN,ptr->natime,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT17_TRUE; + ptr->natimeLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_OTFI,MAX_IS41_VARPAR_LEN,ptr->otfi,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT18_TRUE; + ptr->otfiLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_PCSSN,5,ptr->pcssn,&asn_buf)) + ptr->param_flag |= BIT19_TRUE; + + if (decode_Is41Parameter(IS41PAR_PILOTBID,7,ptr->pilotbid,&asn_buf)) + ptr->param_flag |= BIT20_TRUE; + + len = decode_Is41Parameter(IS41PAR_PILOT,MAX_IS41_VARPAR_LEN,ptr->pilot,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT21_TRUE; + ptr->pilotLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RNSTRING,MAX_IS41_VARPAR_LEN,ptr->rnstring,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT22_TRUE; + ptr->rnstringLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RSUB,MAX_IS41_VARPAR_LEN,ptr->rsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT23_TRUE; + ptr->rsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT24_TRUE; + } + + len = decode_Is41Parameter(IS41PAR_TERMTRMT,MAX_IS41_VARPAR_LEN,ptr->termtrmt,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT25_TRUE; + ptr->termtrmtLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_TERMTRIG,MAX_IS41_VARPAR_LEN,ptr->termtrig,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT26_TRUE; + ptr->termtrigLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_VMBOX,MAX_IS41_VARPAR_LEN,ptr->vmbox,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT27_TRUE; + ptr->vmboxLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_VMSPIN,MAX_IS41_VARPAR_LEN,ptr->vmspin,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT28_TRUE; + ptr->vmspinLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41RoutingRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_ROUTREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.routreq_rsp; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,1),3,ptr->mscid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MSCID absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT1_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACCDEN,2),1,&ptr->accden,0x80,&asn_buf); + + if((flag & BIT2_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,3),7,ptr->billid,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CDEN,4),1,&ptr->cden,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,5),ptr->digitsLen & MAX_IS41_VARPAR_LEN_1,ptr->digits,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,6),ptr->mscinLen & MAX_IS41_VARPAR_LEN_1,ptr->mscin,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,7),5,ptr->pcssn,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41RoutingRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ROUTREQ_RSP *ptr; + int len; + + ptr = &opr_ptr->msg_list.routreq_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + + if(AsnDecode(buf,buf_len,7,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MSCID absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ACCDEN,1,&ptr->accden,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + + if (decode_Is41Parameter(IS41PAR_BILLID,7,ptr->billid,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + + if (decode_Is41Parameter(IS41PAR_CDEN,1,&ptr->cden,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digits,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->digitsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_MSCIN,MAX_IS41_VARPAR_LEN,ptr->mscin,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->mscinLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_PCSSN,5,ptr->pcssn,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + + +int assign_is41MSInactive_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_MSINACT_ARG *ptr; + + ptr = &opr_ptr->msg_list.msinact_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT2_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_COUNT,3),1,&ptr->count,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DEREG,4),1,&ptr->dereg,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //LocationAreaID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,5),2,ptr->locid,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //senderin + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,6),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41MSInactive_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_MSINACT_ARG *ptr; + u8 len; + + ptr = &opr_ptr->msg_list.msinact_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + + if(AsnDecode(buf,buf_len,6,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_COUNT,1,&ptr->count,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + + if (decode_Is41Parameter(IS41PAR_DEREG,1,&ptr->dereg,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + + if (decode_Is41Parameter(IS41PAR_LOCID,2,ptr->locid,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT5_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41MSInactive_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_MSINACT_RSP *ptr; + + ptr = &opr_ptr->msg_list.msinact_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + return buf_len; +} + +int extract_is41MSInactive_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + struct IS41_MSINACT_RSP *ptr; + + ptr = &opr_ptr->msg_list.msinact_rsp; + ptr->param_flag = 0; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41QualificationDirective_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_QUALDIR_ARG *ptr; + + ptr = &opr_ptr->msg_list.qualdir_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //QualificationInformationCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_QUALCODE,3),1,&ptr->qualcode,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:QUALCODE absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //SystemMyTypeCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,4),1,&ptr->mytyp,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MYTYP absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT4_TRUE)>0) //AuthorizationDenied + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHDEN,5),1,&ptr->authden,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //AuthorizationPeriod + buf_len = AddTLV(is41_sequenceTag(IS41PAR_AUTHPER,6),2,ptr->authper,0x80,&asn_buf); + if((flag & BIT6_TRUE)>0) //DeniedAuthorizationPeriod + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DENAUTHPER,7),ptr->denauthperLen & MAX_IS41_VARPAR_LEN_1,ptr->denauthper,0x80,&asn_buf); + if((flag & BIT7_TRUE)>0) //Digits carrier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,8),ptr->digitsCarrierLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsCarrier,0x80,&asn_buf); + if((flag & BIT8_TRUE)>0) //Digits Destination + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,9),ptr->digitsDestLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsDest,0x80,&asn_buf); + if((flag & BIT9_TRUE)>0) //LocationAreaID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,10),2,ptr->locid,0x80,&asn_buf); + +/* Profile **macro** */ + if ((flag & BIT10_TRUE) > 0) + { + if (!encode_param_profile(&ptr->profile,ptr->profile.param_flag,&asn_buf,&buf_len)) + return 0; + } +/* Profile **macro** */ + + if((flag & BIT11_TRUE)>0) //senderin + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,11),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41QualificationDirective_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_QUALDIR_ARG *ptr; + int len; + + ptr = &opr_ptr->msg_list.qualdir_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,24,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_QUALCODE,1,&ptr->qualcode,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:QUALCODE absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MYTYP,1,&ptr->mytyp,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MYTYP absent!"); + return 0; + } + + + +//optional par---> + if (decode_Is41Parameter(IS41PAR_AUTHDEN,1,&ptr->authden,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if (decode_Is41Parameter(IS41PAR_AUTHPER,2,ptr->authper,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + len = decode_Is41Parameter(IS41PAR_DENAUTHPER,MAX_IS41_VARPAR_LEN,ptr->denauthper,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->denauthperLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsCarrier,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->digitsCarrierLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsDest,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->digitsDestLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_LOCID,2,ptr->locid,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + +/* Profile **macro** */ + if (decode_param_profile(&ptr->profile,&asn_buf) > 0) + ptr->param_flag |= BIT10_TRUE; +/* Profile **macro** */ + + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT11_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41QualificationDirective_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_QUALDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.qualdir_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + return buf_len; +} + +int extract_is41QualificationDirective_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + struct IS41_QUALDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.qualdir_rsp; + ptr->param_flag = 0; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41FeatureRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_FEATREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.featreq_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //Dialed Digits + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,1),ptr->digitsLen & MAX_IS41_VARPAR_LEN_1,ptr->digits,0x80,&asn_buf); + + if((flag & BIT1_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,3),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + +//optional + if((flag & BIT3_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,4),7,ptr->billid,0x80,&asn_buf); + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS1,5),ptr->cpndgts1Len & MAX_IS41_VARPAR_LEN_1,ptr->cpndgts1,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS2,6),ptr->cpndgts2Len & MAX_IS41_VARPAR_LEN_1,ptr->cpndgts2,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,7),ptr->cpsubLen & MAX_IS41_VARPAR_LEN_1,ptr->cpsub,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCI,8),ptr->cciLen & MAX_IS41_VARPAR_LEN_1,ptr->cci,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,9),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,10),3,ptr->mscid,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,11),ptr->mscinLen & MAX_IS41_VARPAR_LEN_1,ptr->mscin,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,12),ptr->otfiLen & MAX_IS41_VARPAR_LEN_1,ptr->otfi,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) //pcssn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,13),5,ptr->pcssn,0x80,&asn_buf); + + if((flag & BIT13_TRUE)>0) //senderin + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,14),ptr->senderinLen & MAX_IS41_VARPAR_LEN_1,ptr->senderin,0x80,&asn_buf); + + if((flag & BIT14_TRUE)>0) //transcap + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,15),ptr->transcapLen & MAX_IS41_VARPAR_LEN_1,ptr->transcap,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41FeatureRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_FEATREQ_ARG *ptr; + int len; + + ptr = &opr_ptr->msg_list.featreq_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,24,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digits,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT0_TRUE; + ptr->digitsLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:Digits absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + +//optional + if (decode_Is41Parameter(IS41PAR_BILLID,7,ptr->billid,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + len = decode_Is41Parameter(IS41PAR_CPNDGTS1,MAX_IS41_VARPAR_LEN,ptr->cpndgts1,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->cpndgts1Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNDGTS2,MAX_IS41_VARPAR_LEN,ptr->cpndgts2,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->cpndgts2Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPSUB,MAX_IS41_VARPAR_LEN,ptr->cpsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->cpsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + len = decode_Is41Parameter(IS41PAR_CCI,MAX_IS41_VARPAR_LEN,ptr->cci,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->cciLen = len & MAX_IS41_VARPAR_LEN_1; + } + len = decode_Is41Parameter(IS41PAR_MDN,MAX_IS41_VARPAR_LEN,ptr->mdn,&asn_buf); + if (len > 0) + { + ptr->mdnLen = len; + ptr->param_flag |= BIT8_TRUE; + } + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + len = decode_Is41Parameter(IS41PAR_MSCIN,MAX_IS41_VARPAR_LEN,ptr->mscin,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->mscinLen = len & MAX_IS41_VARPAR_LEN_1; + } + len = decode_Is41Parameter(IS41PAR_OTFI,MAX_IS41_VARPAR_LEN,ptr->otfi,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->otfiLen = len & MAX_IS41_VARPAR_LEN_1; + } + if (decode_Is41Parameter(IS41PAR_PCSSN,5,ptr->pcssn,&asn_buf)) + ptr->param_flag |= BIT12_TRUE; + len = decode_Is41Parameter(IS41PAR_SENDERIN,MAX_IS41_VARPAR_LEN,ptr->senderin,&asn_buf); + if (len > 0) + { + ptr->senderinLen = len; + ptr->param_flag |= BIT13_TRUE; + } + len = decode_Is41Parameter(IS41PAR_TRANSCAP,MAX_IS41_VARPAR_LEN,ptr->transcap,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT14_TRUE; + ptr->transcapLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41FeatureRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag,flag1; + u8 i,triglistnum; + IS41_PAR_TRIGGER_LIST *ptr1; + char tag[64]; + + struct IS41_FEATREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.featreq_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //feature result + buf_len = AddTLV(is41_sequenceTag(IS41PAR_FEATRESULT,1),1,&ptr->featresult,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:Feature result absent!!"); + return 0; + } + +//optional + if((flag & BIT1_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACCDEN,2),1,&ptr->accden,0x80,&asn_buf); + if((flag & BIT2_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACTCODE,3),ptr->actcodeLen & MAX_IS41_VARPAR_LEN_1,ptr->actcode,0x80,&asn_buf); + if((flag & BIT3_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,4),ptr->annlistLen & MAX_IS41_VARPAR_LEN_1,ptr->annlist,0x80,&asn_buf); + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS1,5),ptr->cpndgts1Len & MAX_IS41_VARPAR_LEN_1,ptr->cpndgts1,0x80,&asn_buf); + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS2,6),ptr->cpndgts2Len & MAX_IS41_VARPAR_LEN_1,ptr->cpndgts2,0x80,&asn_buf); + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,7),ptr->cpsubLen & MAX_IS41_VARPAR_LEN_1,ptr->cpsub,0x80,&asn_buf); + if((flag & BIT7_TRUE)>0) //Digits carrier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,8),ptr->digitsCarrierLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsCarrier,0x80,&asn_buf); + if((flag & BIT8_TRUE)>0) //ConferenceCallingIndicator + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCI,9),ptr->cciLen & MAX_IS41_VARPAR_LEN_1,ptr->cci,0x80,&asn_buf); + if((flag & BIT9_TRUE)>0) //Digits carrier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,10),ptr->digitsLen & MAX_IS41_VARPAR_LEN_1,ptr->digits,0x80,&asn_buf); +/* if((flag & BIT10_TRUE)>0) //display text + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DISPTEXT,11),ptr->disptextLen & MAX_IS41_VARPAR_LEN_1,ptr->disptext,0x80,&asn_buf);*/ + if((flag & BIT11_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,12),ptr->acdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->acdgts,0x80,&asn_buf); + if((flag & BIT12_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,13),ptr->abdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->abdgts,0x80,&asn_buf); + if((flag & BIT13_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,14),ptr->billdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->billdgts,0x80,&asn_buf); + if((flag & BIT14_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDIND,15),ptr->redindLen & MAX_IS41_VARPAR_LEN_1,ptr->redind,0x80,&asn_buf); + if((flag & BIT15_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_GRPINFO,16),ptr->grpinfoLen & MAX_IS41_VARPAR_LEN_1,ptr->grpinfo,0x80,&asn_buf); + if((flag & BIT16_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,17),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,&asn_buf); + if((flag & BIT17_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NATIME,18),ptr->natimeLen & MAX_IS41_VARPAR_LEN_1,ptr->natime,0x80,&asn_buf); + if((flag & BIT18_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,19),ptr->otfiLen & MAX_IS41_VARPAR_LEN_1,ptr->otfi,0x80,&asn_buf); + if((flag & BIT19_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PACAIND,20),1,&ptr->pacaind,0x80,&asn_buf); + if((flag & BIT20_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PILOT,21),ptr->pilotLen & MAX_IS41_VARPAR_LEN_1,ptr->pilot,0x80,&asn_buf); + if((flag & BIT21_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNDGTS,22),ptr->rndgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->rndgts,0x80,&asn_buf); + if((flag & BIT22_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNSTRING,23),ptr->rnstringLen & MAX_IS41_VARPAR_LEN_1,ptr->rnstring,0x80,&asn_buf); + if((flag & BIT23_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSUB,24),ptr->rsubLen & MAX_IS41_VARPAR_LEN_1,ptr->rsub,0x80,&asn_buf); + if((flag & BIT24_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RESUMEPIC,25),1,&ptr->resumepic,0x80,&asn_buf); + if((flag & BIT25_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ROUTDGTS,26),ptr->routdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->routdgts,0x80,&asn_buf); + if ((flag & BIT26_TRUE) > 0) + { + if (!encode_param_termlist(&ptr->termlist,ptr->termlist.param_flag,&asn_buf,&buf_len)) + return 0; + } + if((flag & BIT27_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,28),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,&asn_buf); + + if((flag & BIT28_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + if (!triglistnum) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:TriggerAddressList no content!!"); + return 0; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGADRLIST,29),0,NULL,0xA0,&asn_buf); + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + if ((flag1 & 0x03) != 0x03) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + sprintf(tag,"%s.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST); + buf_len = AddTLV(is41_sequenceTag(tag,i+1),0,NULL,0xA0,&asn_buf); + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_GLOBALTITLE); + buf_len = AddTLV(is41_sequenceTag(tag,1),ptr1->destaddrLen & MAX_IS41_VARPAR_LEN_1,ptr1->destaddr,0x80,&asn_buf); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_WINTRIGLIST); + buf_len = AddTLV(is41_sequenceTag(tag,2),ptr1->wintriglistLen & MAX_IS41_VARPAR_LEN_1,ptr1->wintriglist,0x80,&asn_buf); + } + } + } + + return buf_len; +} + +int extract_is41FeatureRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_FEATREQ_RSP *ptr; + IS41_PAR_TRIGGER_LIST *ptr1; + int len,i,count; + char tag[64]; + + ptr = &opr_ptr->msg_list.featreq_rsp; + + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,33,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_FEATRESULT,1,&ptr->featresult,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ACCDEN,1,&ptr->accden,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + + len = decode_Is41Parameter(IS41PAR_ACTCODE,MAX_IS41_VARPAR_LEN,ptr->actcode,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT2_TRUE; + ptr->actcodeLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ANNLIST,MAX_IS41_VARPAR_LEN,ptr->annlist,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->annlistLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNDGTS1,MAX_IS41_VARPAR_LEN,ptr->cpndgts1,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->cpndgts1Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNDGTS2,MAX_IS41_VARPAR_LEN,ptr->cpndgts2,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->cpndgts2Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPSUB,MAX_IS41_VARPAR_LEN,ptr->cpsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->cpsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsCarrier,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->digitsCarrierLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CCI,MAX_IS41_VARPAR_LEN,ptr->cci,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->cciLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digits,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->digitsLen = len & MAX_IS41_VARPAR_LEN_1; + } + +/* len = decode_Is41Parameter(IS41PAR_DISPTEXT,MAX_IS41_VARPAR_LEN,ptr->disptext,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->disptextLen = len & MAX_IS41_VARPAR_LEN_1; + }*/ + + len = decode_Is41Parameter(IS41PAR_ACDGTS,MAX_IS41_VARPAR_LEN,ptr->acdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->acdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ABDGTS,MAX_IS41_VARPAR_LEN,ptr->abdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT12_TRUE; + ptr->abdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_BILLDGTS,MAX_IS41_VARPAR_LEN,ptr->billdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT13_TRUE; + ptr->billdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_REDIND,MAX_IS41_VARPAR_LEN,ptr->redind,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT14_TRUE; + ptr->redindLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_GRPINFO,MAX_IS41_VARPAR_LEN,ptr->grpinfo,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT15_TRUE; + ptr->grpinfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_MDN,MAX_IS41_VARPAR_LEN,ptr->mdn,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT16_TRUE; + ptr->mdnLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_NATIME,MAX_IS41_VARPAR_LEN,ptr->natime,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT17_TRUE; + ptr->natimeLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_OTFI,MAX_IS41_VARPAR_LEN,ptr->otfi,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT18_TRUE; + ptr->otfiLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_PACAIND,1,&ptr->pacaind,&asn_buf)) + ptr->param_flag |= BIT19_TRUE; + + len = decode_Is41Parameter(IS41PAR_PILOT,MAX_IS41_VARPAR_LEN,ptr->pilot,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT20_TRUE; + ptr->pilotLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RNDGTS,MAX_IS41_VARPAR_LEN,ptr->rndgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT21_TRUE; + ptr->rndgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RNSTRING,MAX_IS41_VARPAR_LEN,ptr->rnstring,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT22_TRUE; + ptr->rnstringLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RSUB,MAX_IS41_VARPAR_LEN,ptr->rsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT23_TRUE; + ptr->rsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_RESUMEPIC,1,&ptr->resumepic,&asn_buf)) + ptr->param_flag |= BIT24_TRUE; + + len = decode_Is41Parameter(IS41PAR_ROUTDGTS,MAX_IS41_VARPAR_LEN,ptr->routdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT25_TRUE; + ptr->routdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_param_termlist(&ptr->termlist,&asn_buf) > 0) + ptr->param_flag |= BIT26_TRUE; + + len = decode_Is41Parameter(IS41PAR_TERMTRIG,MAX_IS41_VARPAR_LEN,ptr->termtrig,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT27_TRUE; + ptr->termtrigLen = len & MAX_IS41_VARPAR_LEN_1; + } + + ptr->triggerlistnum = 0; + for (i = 0; i < MAX_IS41_TRIG_LIST_NUM; i++) + { + ptr1 = &ptr->triggerlist[i]; + count = 0; + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_GLOBALTITLE); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->destaddr,&asn_buf); + if (len > 0) + { + ptr1->param_flag |= BIT0_TRUE; + ptr1->destaddrLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_WINTRIGLIST); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->wintriglist,&asn_buf); + if (len > 0) + { + ptr1->param_flag |= BIT1_TRUE; + ptr1->wintriglistLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + if (count == 2) + { + ptr->triggerlistnum++; + ptr->param_flag |= BIT28_TRUE; + } + else if (count == 1) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + else if (!count) + break; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + + +int assign_is41TransferToNumberRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag,flag1; + struct IS41_TRANUMREQ_ARG *ptr; + struct IS41_PAR_WIN_CAP *ptr1; + char tag[64]; + + ptr = &opr_ptr->msg_list.tranumreq_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //REDIRECTION REASON + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDREASON,3),1,&ptr->redreason,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:redreason absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //SystemMyTypeCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,4),1,&ptr->mytyp,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MYTYP absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,5),7,ptr->billid,0x80,&asn_buf); + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_GRPINFO,6),ptr->grpinfoLen & MAX_IS41_VARPAR_LEN_1,ptr->grpinfo,0x80,&asn_buf); + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LEGINFO,7),ptr->leginfoLen & MAX_IS41_VARPAR_LEN_1,ptr->leginfo,0x80,&asn_buf); + if((flag & BIT7_TRUE)>0) //MSCID + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,8),3,ptr->mscid,0x80,&asn_buf); + if((flag & BIT8_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,9),ptr->mscinLen & MAX_IS41_VARPAR_LEN_1,ptr->mscin,0x80,&asn_buf); + if((flag & BIT9_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PILOTBID,10),7,ptr->pilotbid,0x80,&asn_buf); + if((flag & BIT10_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PILOT,11),ptr->pilotLen & MAX_IS41_VARPAR_LEN_1,ptr->pilot,0x80,&asn_buf); + if((flag & BIT11_TRUE)>0) //transcap + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,12),ptr->transcapLen & MAX_IS41_VARPAR_LEN_1,ptr->transcap,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) //wincap + { + ptr1 = &ptr->wincap; + flag1 = ptr1->param_flag; + if (!(flag1 & 0x03)) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:wincap no content!!"); + return 0; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_WINCAP,21),0,NULL,0xA0,&asn_buf); + if((flag1 & BIT0_TRUE)>0) //triggercapability + { + sprintf(tag,"%s.%s",IS41PAR_WINCAP,IS41PAR_TRIGCAP); + buf_len = AddTLV(is41_sequenceTag(tag,1),ptr1->triggercapLen & MAX_IS41_VARPAR_LEN_1,ptr1->triggercap,0x80,&asn_buf); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + sprintf(tag,"%s.%s",IS41PAR_WINCAP,IS41PAR_WINOPRCAP); + buf_len = AddTLV(is41_sequenceTag(tag,2),ptr1->winoprcapLen & MAX_IS41_VARPAR_LEN_1,ptr1->winoprcap,0x80,&asn_buf); + } + } + + return buf_len; +} + +int extract_is41TransferToNumberRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_TRANUMREQ_ARG *ptr; + int len; + char tag[64]; + + ptr = &opr_ptr->msg_list.tranumreq_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,24,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_REDREASON,1,&ptr->redreason,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:redreason absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MYTYP,1,&ptr->mytyp,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MYTYP absent!"); + return 0; + } + +//optional par---> + if (decode_Is41Parameter(IS41PAR_BILLID,7,ptr->billid,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + len = decode_Is41Parameter(IS41PAR_GRPINFO,MAX_IS41_VARPAR_LEN,ptr->grpinfo,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->grpinfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + len = decode_Is41Parameter(IS41PAR_LEGINFO,MAX_IS41_VARPAR_LEN,ptr->leginfo,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->leginfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + if (decode_Is41Parameter(IS41PAR_MSCID,3,ptr->mscid,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + len = decode_Is41Parameter(IS41PAR_MSCIN,MAX_IS41_VARPAR_LEN,ptr->mscin,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->mscinLen = len & MAX_IS41_VARPAR_LEN_1; + } + if (decode_Is41Parameter(IS41PAR_PILOTBID,7,ptr->pilotbid,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + + len = decode_Is41Parameter(IS41PAR_PILOT,MAX_IS41_VARPAR_LEN,ptr->pilot,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->pilotLen = len & MAX_IS41_VARPAR_LEN_1; + } + len = decode_Is41Parameter(IS41PAR_TRANSCAP,MAX_IS41_VARPAR_LEN,ptr->transcap,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->transcapLen = len & MAX_IS41_VARPAR_LEN_1; + } + + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_TRIGCAP); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->wincap.triggercap,&asn_buf); + if (len > 0) + { + ptr->wincap.param_flag |= BIT0_TRUE; + ptr->wincap.triggercapLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT12_TRUE; + } + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_WINOPRCAP); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr->wincap.winoprcap,&asn_buf); + if (len > 0) + { + ptr->wincap.param_flag |= BIT1_TRUE; + ptr->wincap.winoprcapLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT12_TRUE; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41TransferToNumberRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag,flag1; + u8 i,triglistnum; + IS41_PAR_TRIGGER_LIST *ptr1; + char tag[64]; + + struct IS41_TRANUMREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.tranumreq_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //Digits(Destination) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,1),ptr->digitsLen & MAX_IS41_VARPAR_LEN_1,ptr->digits,0x80,&asn_buf); +/* else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:Feature result absent!!"); + return 0; + }*/ + +//optional + if((flag & BIT1_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACCDEN,2),1,&ptr->accden,0x80,&asn_buf); + if((flag & BIT2_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACTCODE,3),ptr->actcodeLen & MAX_IS41_VARPAR_LEN_1,ptr->actcode,0x80,&asn_buf); + if((flag & BIT3_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,4),ptr->annlistLen & MAX_IS41_VARPAR_LEN_1,ptr->annlist,0x80,&asn_buf); + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG1,5),ptr->cpnstrg1Len & MAX_IS41_VARPAR_LEN_1,ptr->cpnstrg1,0x80,&asn_buf); + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG2,6),ptr->cpnstrg2Len & MAX_IS41_VARPAR_LEN_1,ptr->cpnstrg2,0x80,&asn_buf); + if((flag & BIT6_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,7),ptr->cpsubLen & MAX_IS41_VARPAR_LEN_1,ptr->cpsub,0x80,&asn_buf); + if((flag & BIT7_TRUE)>0) //Digits carrier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,8),ptr->digitsCarrierLen & MAX_IS41_VARPAR_LEN_1,ptr->digitsCarrier,0x80,&asn_buf); + if((flag & BIT8_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,9),ptr->acdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->acdgts,0x80,&asn_buf); + if((flag & BIT9_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,10),ptr->abdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->abdgts,0x80,&asn_buf); + if((flag & BIT10_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,11),ptr->billdgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->billdgts,0x80,&asn_buf); + if((flag & BIT11_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDIND,12),ptr->redindLen & MAX_IS41_VARPAR_LEN_1,ptr->redind,0x80,&asn_buf); + if((flag & BIT12_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DMH_SVCID,13),ptr->dmh_svcidLen & MAX_IS41_VARPAR_LEN_1,ptr->dmh_svcid,0x80,&asn_buf); + if((flag & BIT13_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_GRPINFO,14),ptr->grpinfoLen & MAX_IS41_VARPAR_LEN_1,ptr->grpinfo,0x80,&asn_buf); + if((flag & BIT14_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,15),ptr->mdnLen & MAX_IS41_VARPAR_LEN_1,ptr->mdn,0x80,&asn_buf); + if((flag & BIT15_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NATIME,16),ptr->natimeLen & MAX_IS41_VARPAR_LEN_1,ptr->natime,0x80,&asn_buf); + if((flag & BIT16_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PLIND,17),1,&ptr->plind,0x80,&asn_buf); + + if((flag & BIT17_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNDGTS,18),ptr->rndgtsLen & MAX_IS41_VARPAR_LEN_1,ptr->rndgts,0x80,&asn_buf); + if((flag & BIT18_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNSTRING,19),ptr->rnstringLen & MAX_IS41_VARPAR_LEN_1,ptr->rnstring,0x80,&asn_buf); + if((flag & BIT19_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSUB,20),ptr->rsubLen & MAX_IS41_VARPAR_LEN_1,ptr->rsub,0x80,&asn_buf); + + if ((flag & BIT20_TRUE) > 0) + { + if (!encode_param_termlist(&ptr->termlist,ptr->termlist.param_flag,&asn_buf,&buf_len)) + return 0; + } + if((flag & BIT21_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,22),ptr->termtrigLen & MAX_IS41_VARPAR_LEN_1,ptr->termtrig,0x80,&asn_buf); + + if((flag & BIT22_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + if (!triglistnum) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:TriggerAddressList no content!!"); + return 0; + } + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGADRLIST,23),0,NULL,0xA0,&asn_buf); + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + if ((flag1 & 0x03) != 0x03) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + sprintf(tag,"%s.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST); + buf_len = AddTLV(is41_sequenceTag(tag,i+1),0,NULL,0xA0,&asn_buf); + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_GLOBALTITLE); + buf_len = AddTLV(is41_sequenceTag(tag,1),ptr1->destaddrLen & MAX_IS41_VARPAR_LEN_1,ptr1->destaddr,0x80,&asn_buf); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + sprintf(tag,"%s.%s-%d.%s",IS41PAR_TRIGADRLIST,IS41PAR_TRIGLIST,i+1,IS41PAR_WINTRIGLIST); + buf_len = AddTLV(is41_sequenceTag(tag,2),ptr1->wintriglistLen & MAX_IS41_VARPAR_LEN_1,ptr1->wintriglist,0x80,&asn_buf); + } + } + } + + return buf_len; +} + +int extract_is41TransferToNumberRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_TRANUMREQ_RSP *ptr; + IS41_PAR_TRIGGER_LIST *ptr1; + int len,i,count; + char tag[64]; + + ptr = &opr_ptr->msg_list.tranumreq_rsp; + + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,33,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digits,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT0_TRUE; + ptr->digitsLen = len & MAX_IS41_VARPAR_LEN_1; + } +/* else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:Digits absent!"); + return 0; + }*/ + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ACCDEN,1,&ptr->accden,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + + len = decode_Is41Parameter(IS41PAR_ACTCODE,MAX_IS41_VARPAR_LEN,ptr->actcode,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT2_TRUE; + ptr->actcodeLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ANNLIST,MAX_IS41_VARPAR_LEN,ptr->annlist,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->annlistLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNSTRG1,MAX_IS41_VARPAR_LEN,ptr->cpnstrg1,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->cpnstrg1Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPNSTRG2,MAX_IS41_VARPAR_LEN,ptr->cpnstrg2,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->cpnstrg2Len = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_CPSUB,MAX_IS41_VARPAR_LEN,ptr->cpsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->cpsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DIGITS,MAX_IS41_VARPAR_LEN,ptr->digitsCarrier,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->digitsCarrierLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ACDGTS,MAX_IS41_VARPAR_LEN,ptr->acdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->acdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_ABDGTS,MAX_IS41_VARPAR_LEN,ptr->abdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->abdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_BILLDGTS,MAX_IS41_VARPAR_LEN,ptr->billdgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->billdgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_REDIND,MAX_IS41_VARPAR_LEN,ptr->redind,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->redindLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_DMH_SVCID,MAX_IS41_VARPAR_LEN,ptr->dmh_svcid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT12_TRUE; + ptr->dmh_svcidLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_GRPINFO,MAX_IS41_VARPAR_LEN,ptr->grpinfo,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT13_TRUE; + ptr->grpinfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_MDN,MAX_IS41_VARPAR_LEN,ptr->mdn,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT14_TRUE; + ptr->mdnLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_NATIME,MAX_IS41_VARPAR_LEN,ptr->natime,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT15_TRUE; + ptr->natimeLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_Is41Parameter(IS41PAR_PLIND,1,&ptr->plind,&asn_buf)) + ptr->param_flag |= BIT16_TRUE; + + len = decode_Is41Parameter(IS41PAR_RNDGTS,MAX_IS41_VARPAR_LEN,ptr->rndgts,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT17_TRUE; + ptr->rndgtsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RNSTRING,MAX_IS41_VARPAR_LEN,ptr->rnstring,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT18_TRUE; + ptr->rnstringLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_RSUB,MAX_IS41_VARPAR_LEN,ptr->rsub,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT19_TRUE; + ptr->rsubLen = len & MAX_IS41_VARPAR_LEN_1; + } + + if (decode_param_termlist(&ptr->termlist,&asn_buf) > 0) + ptr->param_flag |= BIT20_TRUE; + + len = decode_Is41Parameter(IS41PAR_TERMTRIG,MAX_IS41_VARPAR_LEN,ptr->termtrig,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT21_TRUE; + ptr->termtrigLen = len & MAX_IS41_VARPAR_LEN_1; + } + + ptr->triggerlistnum = 0; + for (i = 0; i < MAX_IS41_TRIG_LIST_NUM; i++) + { + ptr1 = &ptr->triggerlist[i]; + count = 0; + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_GLOBALTITLE); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->destaddr,&asn_buf); + if (len > 0) + { + ptr1->param_flag |= BIT0_TRUE; + ptr1->destaddrLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_WINTRIGLIST); + len = decode_Is41Parameter(tag,MAX_IS41_VARPAR_LEN,ptr1->wintriglist,&asn_buf); + if (len > 0) + { + ptr1->param_flag |= BIT1_TRUE; + ptr1->wintriglistLen = len & MAX_IS41_VARPAR_LEN_1; + count++; + } + if (count == 2) + { + ptr->triggerlistnum++; + ptr->param_flag |= BIT22_TRUE; + } + else if (count == 1) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + else if (!count) + break; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41RedirectionRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + struct IS41_REDREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.redreq_arg; + + flag = ptr->param_flag; + + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1),7,ptr->billid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:BILLID absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,3),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //REDIRECTION REASON + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDREASON,4),1,&ptr->redreason,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:redreason absent!!"); + return 0; + } + + +// optional part---> + if((flag & BIT4_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LEGINFO,5),ptr->leginfoLen & MAX_IS41_VARPAR_LEN_1,ptr->leginfo,0x80,&asn_buf); + if((flag & BIT5_TRUE)>0) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,6),ptr->mscinLen & MAX_IS41_VARPAR_LEN_1,ptr->mscin,0x80,&asn_buf); + + return buf_len; +} + +int extract_is41RedirectionRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_REDREQ_ARG *ptr; + int len; + + ptr = &opr_ptr->msg_list.redreq_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,24,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_BILLID,7,ptr->billid,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:BILLID absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + return 0; + } + + if (decode_Is41Parameter(IS41PAR_REDREASON,1,&ptr->redreason,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:redreason absent!"); + return 0; + } + + +//optional par---> + len = decode_Is41Parameter(IS41PAR_LEGINFO,MAX_IS41_VARPAR_LEN,ptr->leginfo,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->leginfoLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_MSCIN,MAX_IS41_VARPAR_LEN,ptr->mscin,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->mscinLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_is41RedirectionRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_REDREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.redreq_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + return buf_len; +} + +int extract_is41RedirectionRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + struct IS41_REDREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.redreq_rsp; + ptr->param_flag = 0; + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} diff --git a/plat/xapp/src/mapp/is41_code_sms.c b/plat/xapp/src/mapp/is41_code_sms.c new file mode 100644 index 0000000..97285c0 --- /dev/null +++ b/plat/xapp/src/mapp/is41_code_sms.c @@ -0,0 +1,1134 @@ +/* is41 coding smsc service file */ +/* written by daniel zhang 2004-07-10 */ +/* modified by daniel on 2004-07-10 */ +/* -------------------------------- */ + +#include "map_includes.h" + +/* external functions */ +void is41_log(char *info); +void is41_debug(DWORD mask, const char *fmt, ...); +void is41_showbuf(DWORD mask, BYTE *buf, int len); +int decode_Is41Parameter(char *tag,int len,BYTE *value,ASN_BUF *asn_buf); +char *is41_sequenceTag(char *tag,int sequence); + +int encode_Is41ParBearerData(IS41ParBearerData *ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if ((flag & BIT0_TRUE) > 0) + buf_len = AddTLV("0",3,ptr->MessageId,0x80,&asn_buf); + + if ((flag & BIT1_TRUE) > 0) + buf_len = AddTLV("1",ptr->UserDataLen & 31,ptr->UserData,0x80,&asn_buf); + + if ((flag & BIT2_TRUE) > 0) + buf_len = AddTLV("2",1,&ptr->UserRespondingCode,0x80,&asn_buf); + + if ((flag & BIT3_TRUE) > 0) + buf_len = AddTLV("3",6,ptr->MessageCenterTimeStamp,0x80,&asn_buf); + + if ((flag & BIT4_TRUE) > 0) + buf_len = AddTLV("4",6,ptr->ValidityPeriod_Absolute,0x80,&asn_buf); + if ((flag & BIT5_TRUE) > 0) + buf_len = AddTLV("5",1,&ptr->ValidityPeriod_Relative,0x80,&asn_buf); + if ((flag & BIT6_TRUE) > 0) + buf_len = AddTLV("6",6,ptr->DeferredDeliveryTime_Absolute,0x80,&asn_buf); + if ((flag & BIT7_TRUE) > 0) + buf_len = AddTLV("7",1,&ptr->DeferredDeliveryTime_Relative,0x80,&asn_buf); + if ((flag & BIT8_TRUE) > 0) + buf_len = AddTLV("8",1,&ptr->PriorityIndicator,0x80,&asn_buf); + if ((flag & BIT9_TRUE) > 0) + buf_len = AddTLV("9",1,&ptr->PrivacyIndicator,0x80,&asn_buf); + if ((flag & BIT10_TRUE) > 0) + buf_len = AddTLV("10",1,&ptr->ReplyOption,0x80,&asn_buf); + if ((flag & BIT11_TRUE) > 0) + buf_len = AddTLV("11",1,&ptr->NumberOfMessages,0x80,&asn_buf); + if ((flag & BIT12_TRUE) > 0) + buf_len = AddTLV("12",1,&ptr->AlertOnMessageDelivery,0x80,&asn_buf); + if ((flag & BIT13_TRUE) > 0) + buf_len = AddTLV("13",1,&ptr->LanguageIndicator,0x80,&asn_buf); + if ((flag & BIT14_TRUE) > 0) + buf_len = AddTLV("14",ptr->CallBackNumberLen & 31,ptr->CallBackNumber,0x80,&asn_buf); + if ((flag & BIT15_TRUE) > 0) + buf_len = AddTLV("15",1,&ptr->MessageDisplayMode,0x80,&asn_buf); + if ((flag & BIT16_TRUE) > 0) + buf_len = AddTLV("16",ptr->MultipleEncodingUserDataLen & 31,ptr->MultipleEncodingUserData,0x80,&asn_buf); + + if ((flag & BIT17_TRUE) > 0) + buf_len = AddTLV("20",1,&ptr->MessageStatus,0x80,&asn_buf); + if ((flag & BIT18_TRUE) > 0) + buf_len = AddTLV("21",1,&ptr->TPFailureCause,0x80,&asn_buf); + + + return buf_len; +} + +int decode_Is41ParBearerData(IS41ParBearerData *ptr, u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + if(AsnDecode(buf,buf_len,19,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter("0",3,ptr->MessageId,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + + len = decode_Is41Parameter("1",128,ptr->UserData,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT1_TRUE; + ptr->UserDataLen = len & 127; + } + if (decode_Is41Parameter("2",1,&ptr->UserRespondingCode,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if (decode_Is41Parameter("3",6,ptr->MessageCenterTimeStamp,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if (decode_Is41Parameter("4",6,ptr->ValidityPeriod_Absolute,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if (decode_Is41Parameter("5",1,&ptr->ValidityPeriod_Relative,&asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if (decode_Is41Parameter("6",6,ptr->DeferredDeliveryTime_Absolute,&asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if (decode_Is41Parameter("7",1,&ptr->DeferredDeliveryTime_Relative,&asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if (decode_Is41Parameter("8",1,&ptr->PriorityIndicator,&asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if (decode_Is41Parameter("9",1,&ptr->PrivacyIndicator,&asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if (decode_Is41Parameter("10",1,&ptr->ReplyOption,&asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if (decode_Is41Parameter("11",1,&ptr->NumberOfMessages,&asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if (decode_Is41Parameter("12",1,&ptr->AlertOnMessageDelivery,&asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if (decode_Is41Parameter("13",1,&ptr->LanguageIndicator,&asn_buf)) + ptr->param_flag |= BIT13_TRUE; + len = decode_Is41Parameter("14",MAX_IS41_VARPAR_LEN,ptr->CallBackNumber,&asn_buf); + if (len > 0) + { + ptr->CallBackNumberLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT14_TRUE; + } + if (decode_Is41Parameter("15",1,&ptr->MessageDisplayMode,&asn_buf)) + ptr->param_flag |= BIT15_TRUE; + len = decode_Is41Parameter("16",MAX_IS41_VARPAR_LEN,ptr->MultipleEncodingUserData,&asn_buf); + if (len > 0) + { + ptr->MultipleEncodingUserDataLen = len & MAX_IS41_VARPAR_LEN_1; + ptr->param_flag |= BIT16_TRUE; + } + if (decode_Is41Parameter("20",1,&ptr->MessageStatus,&asn_buf)) + ptr->param_flag |= BIT17_TRUE; + if (decode_Is41Parameter("21",1,&ptr->TPFailureCause,&asn_buf)) + ptr->param_flag |= BIT18_TRUE; + return 1; + +} + +int assign_Is41SmsDeliveryBackward_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMDBACK_ARG *ptr; + + ptr = &opr_ptr->msg_list.smdback_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_IMSCCID,1),2,(BYTE*)&ptr->imsccid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:InterMSCCID absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //SMS_BearerData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBD,3),ptr->BearerDataLen,ptr->BearerData,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_BearerData absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //SMS_TeleserviceIdentifier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSTID,4),ptr->smstidLen & MAX_IS41_VARPAR_LEN_1,ptr->smstid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_TeleserviceIdentifier absent!!"); + return 0; + } + + +// optional part---> + if((flag & BIT4_TRUE)>0) //ElectronicSerialNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,5),ESN_LEN,ptr->esn,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //SMS_ChargeIndicator + { + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCID,6),ptr->smscidLen & MAX_IS41_VARPAR_LEN_1,ptr->smscid,0x80,&asn_buf); + } + + if((flag & BIT6_TRUE)>0) //SMS_DestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSDA,7),ptr->smsdaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsda,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //SMS_OriginalDestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODA,8),ptr->smsodaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoda,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //SMS_OriginalDestinationSubaddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODS,9),ptr->smsodsLen & MAX_IS41_VARPAR_LEN_1,ptr->smsods,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //SMS_OriginalOriginatingAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOA,10),ptr->smsooaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsooa,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) //SMS_OriginalOriginatingSubaddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOS,11),ptr->smsoosLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoos,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) //smsoa + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOA,12),ptr->smsoaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoa,0x80,&asn_buf); + + return buf_len; +} + +int extract_Is41SmsDeliveryBackward_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMDBACK_ARG *ptr; + + ptr = &opr_ptr->msg_list.smdback_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_IMSCCID,2,ptr->imsccid,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:InterMSCCID absent!"); + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + + if ((ptr->BearerDataLen=decode_Is41Parameter(IS41PAR_SMSBD,256,ptr->BearerData,&asn_buf))>0) + ptr->param_flag |= BIT2_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_BearerData absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSTID,MAX_IS41_VARPAR_LEN,ptr->smstid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->smstidLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:IS41PAR_SMSTID absent!"); + + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + + len = decode_Is41Parameter(IS41PAR_SMSCID,MAX_IS41_VARPAR_LEN,ptr->smscid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->smscidLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSDA,MAX_IS41_VARPAR_LEN,ptr->smsda,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->smsdaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSODA,MAX_IS41_VARPAR_LEN,ptr->smsoda,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->smsodaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSODS,MAX_IS41_VARPAR_LEN,ptr->smsods,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->smsodsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOOA,MAX_IS41_VARPAR_LEN,ptr->smsooa,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->smsooaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOOS,MAX_IS41_VARPAR_LEN,ptr->smsoos,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->smsoosLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOA,MAX_IS41_VARPAR_LEN,ptr->smsoa,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->smsoaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsDeliveryBackward_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMDBACK_RSP *ptr; + + ptr = &opr_ptr->msg_list.smdback_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //SMS_BearerData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBD,1),ptr->BearerDataLen,ptr->BearerData,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_BearerData absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //SMS_CauseCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCC,2),ptr->smsccLen & MAX_IS41_VARPAR_LEN_1,ptr->smscc,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_CauseCode absent!!"); + return 0; + } + + return buf_len; +} + + +int extract_Is41SmsDeliveryBackward_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMDBACK_RSP *ptr; + + ptr = &opr_ptr->msg_list.smdback_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if ((ptr->BearerDataLen=decode_Is41Parameter(IS41PAR_SMSBD,256,ptr->BearerData,&asn_buf))>0) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_BearerData absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSCC,MAX_IS41_VARPAR_LEN,ptr->smscc,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT1_TRUE; + ptr->smsccLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_CauseCode absent!"); + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsDeliveryForward_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMDFWD_ARG *ptr; + + ptr = &opr_ptr->msg_list.smdfwd_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + if((flag & BIT0_TRUE)>0) //esn + buf_len = AddTLV(is41_sequenceTag(IS41PAR_IMSCCID,1),2,(BYTE*)&ptr->imsccid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:InterMSCCID absent!!"); + return 0; + } + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + + if((flag & BIT2_TRUE)>0) //SMS_BearerData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBD,3),ptr->BearerDataLen,ptr->BearerData,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_BearerData absent!!"); + return 0; + } + + if((flag & BIT3_TRUE)>0) //SMS_TeleserviceIdentifier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSTID,4),ptr->smstidLen & MAX_IS41_VARPAR_LEN_1,ptr->smstid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_TeleserviceIdentifier absent!!"); + return 0; + } + + +// optional part---> + if((flag & BIT4_TRUE)>0) //ElectronicSerialNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,5),ESN_LEN,ptr->esn,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //SMS_ChargeIndicator + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCID,6),ptr->smscidLen & MAX_IS41_VARPAR_LEN_1,ptr->smscid,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //SMS_DestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSDA,7),ptr->smsdaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsda,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //SMS_OriginalDestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODA,8),ptr->smsodaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoda,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //SMS_OriginalDestinationSubaddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODS,9),ptr->smsodsLen & MAX_IS41_VARPAR_LEN_1,ptr->smsods,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //SMS_OriginalOriginatingAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOA,10),ptr->smsooaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsooa,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) //SMS_OriginalOriginatingSubaddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOS,11),ptr->smsoosLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoos,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) //SMS_OriginatingAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOA,12),ptr->smsoaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoa,0x80,&asn_buf); + + return buf_len; +} + +int extract_Is41SmsDeliveryForward_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMDFWD_ARG *ptr; + + ptr = &opr_ptr->msg_list.smdfwd_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_IMSCCID,2,ptr->imsccid,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:InterMSCCID absent!"); + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + + if ((ptr->BearerDataLen=decode_Is41Parameter(IS41PAR_SMSBD,256,ptr->BearerData,&asn_buf))>0) + ptr->param_flag |= BIT2_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_BearerData absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSTID,MAX_IS41_VARPAR_LEN,ptr->smstid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->smstidLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:IS41PAR_SMSTID absent!"); + + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT4_TRUE; + + len = decode_Is41Parameter(IS41PAR_SMSCID,MAX_IS41_VARPAR_LEN,ptr->smscid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->smscidLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSDA,MAX_IS41_VARPAR_LEN,ptr->smsda,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->smsdaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSODA,MAX_IS41_VARPAR_LEN,ptr->smsoda,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->smsodaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSODS,MAX_IS41_VARPAR_LEN,ptr->smsods,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->smsodsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOOA,MAX_IS41_VARPAR_LEN,ptr->smsooa,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->smsooaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOOS,MAX_IS41_VARPAR_LEN,ptr->smsoos,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->smsoosLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOA,MAX_IS41_VARPAR_LEN,ptr->smsoa,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->smsoaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsDeliveryForward_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + + struct IS41_SMDFWD_RSP *ptr; + + ptr = &opr_ptr->msg_list.smdfwd_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //SMS_BearerData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBD,1),ptr->BearerDataLen,ptr->BearerData,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_BearerData absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //SMS_CauseCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCC,2),ptr->smsccLen & MAX_IS41_VARPAR_LEN_1,ptr->smscc,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_CauseCode absent!!"); + return 0; + } + + return buf_len; +} + + +int extract_Is41SmsDeliveryForward_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMDFWD_RSP *ptr; + + ptr = &opr_ptr->msg_list.smdfwd_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if ((ptr->BearerDataLen=decode_Is41Parameter(IS41PAR_SMSBD,256,ptr->BearerData,&asn_buf))>0) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_BearerData absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSCC,MAX_IS41_VARPAR_LEN,ptr->smscc,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT1_TRUE; + ptr->smsccLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_CauseCode absent!"); + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsDeliveryPointToPoint_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMDPP_ARG *ptr; + + ptr = &opr_ptr->msg_list.smdpp_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //SMS_BearerData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBD,1),ptr->BearerDataLen,ptr->BearerData,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_BearerData absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //SMS_TeleserviceIdentifier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSTID,2),ptr->smstidLen & MAX_IS41_VARPAR_LEN_1,ptr->smstid,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_TeleserviceIdentifier absent!!"); + return 0; + } + + +// optional part---> + if((flag & BIT2_TRUE)>0) //ElectronicSerialNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,3),ESN_LEN,ptr->esn,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,4),MIN_LEN,ptr->min,0x80,&asn_buf); + + if((flag & BIT4_TRUE)>0) //SMS_ChargeIndicator + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCID,5),ptr->smscidLen & MAX_IS41_VARPAR_LEN_1,ptr->smscid,0x80,&asn_buf); + + if((flag & BIT5_TRUE)>0) //SMS_DestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSDA,6),ptr->smsdaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsda,0x80,&asn_buf); + + if((flag & BIT6_TRUE)>0) //SMS_MessageCount + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSMSGCNT,7),ptr->smsmsgcntLen & MAX_IS41_VARPAR_LEN_1,ptr->smsmsgcnt,0x80,&asn_buf); + + if((flag & BIT7_TRUE)>0) //SMS_NotificationIndicator + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSNOTIND,8),ptr->smsnotindLen & MAX_IS41_VARPAR_LEN_1,ptr->smsnotind,0x80,&asn_buf); + + if((flag & BIT8_TRUE)>0) //SMS_OriginalDestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODA,9),ptr->smsodaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoda,0x80,&asn_buf); + + if((flag & BIT9_TRUE)>0) //SMS_OriginalDestinationSubaddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODS,10),ptr->smsodsLen & MAX_IS41_VARPAR_LEN_1,ptr->smsods,0x80,&asn_buf); + + if((flag & BIT10_TRUE)>0) //SMS_OriginalOriginatingAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOA,11),ptr->smsooaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsooa,0x80,&asn_buf); + + if((flag & BIT11_TRUE)>0) //SMS_OriginalOriginatingSubaddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOS,12),ptr->smsoosLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoos,0x80,&asn_buf); + + if((flag & BIT12_TRUE)>0) //SMS_OriginatingAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOA,13),ptr->smsoaLen & MAX_IS41_VARPAR_LEN_1,ptr->smsoa,0x80,&asn_buf); + + return buf_len; +} + +int extract_Is41SmsDeliveryPointToPoint_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMDPP_ARG *ptr; + + ptr = &opr_ptr->msg_list.smdpp_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if ((ptr->BearerDataLen=decode_Is41Parameter(IS41PAR_SMSBD,256,ptr->BearerData,&asn_buf))>0) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_BearerData absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSTID,MAX_IS41_VARPAR_LEN,ptr->smstid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT1_TRUE; + ptr->smstidLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:IS41PAR_SMSTID absent!"); + + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT2_TRUE; + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT3_TRUE; + + len = decode_Is41Parameter(IS41PAR_SMSCID,MAX_IS41_VARPAR_LEN,ptr->smscid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT4_TRUE; + ptr->smscidLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSDA,MAX_IS41_VARPAR_LEN,ptr->smsda,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT5_TRUE; + ptr->smsdaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSMSGCNT,MAX_IS41_VARPAR_LEN,ptr->smsmsgcnt,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT6_TRUE; + ptr->smsmsgcntLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSNOTIND,MAX_IS41_VARPAR_LEN,ptr->smsnotind,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT7_TRUE; + ptr->smsnotindLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSODA,MAX_IS41_VARPAR_LEN,ptr->smsoda,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT8_TRUE; + ptr->smsodaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSODS,MAX_IS41_VARPAR_LEN,ptr->smsods,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT9_TRUE; + ptr->smsodsLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOOA,MAX_IS41_VARPAR_LEN,ptr->smsooa,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT10_TRUE; + ptr->smsooaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOOS,MAX_IS41_VARPAR_LEN,ptr->smsoos,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT11_TRUE; + ptr->smsoosLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSOA,MAX_IS41_VARPAR_LEN,ptr->smsoa,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT12_TRUE; + ptr->smsoaLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsDeliveryPointToPoint_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMDPP_RSP *ptr; + + ptr = &opr_ptr->msg_list.smdpp_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //SMS_BearerData + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBD,1),ptr->BearerDataLen,ptr->BearerData,0x80,&asn_buf); + + if((flag & BIT1_TRUE)>0) //SMS_CauseCode + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCC,2),ptr->smsccLen & MAX_IS41_VARPAR_LEN_1,ptr->smscc,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:SMS_CauseCode absent!!"); + return 0; + } + + return buf_len; +} + + +int extract_Is41SmsDeliveryPointToPoint_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMDPP_RSP *ptr; + + ptr = &opr_ptr->msg_list.smdpp_rsp; + ptr->param_flag = 0; + + if (buf_len == 0) + return 1; + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + + if ((ptr->BearerDataLen=decode_Is41Parameter(IS41PAR_SMSBD,256,ptr->BearerData,&asn_buf))>0) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_BearerData absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSCC,MAX_IS41_VARPAR_LEN,ptr->smscc,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT1_TRUE; + ptr->smsccLen = len & MAX_IS41_VARPAR_LEN_1; + } + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:SMS_CauseCode absent!"); + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsNotification_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMSNOT_ARG *ptr; + + ptr = &opr_ptr->msg_list.smsnot_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //ElectronicSerialNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:ESN absent!!"); + return 0; + } + + if((flag & BIT1_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,2),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + +// optional part---> + + if((flag & BIT2_TRUE)>0) //SMS_AccessDeniedReason + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSACCDEN,3),ptr->smsaccdenLen & MAX_IS41_VARPAR_LEN_1,ptr->smsaccden,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //SMS_DestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSADDR,4),ptr->smsaddrLen & MAX_IS41_VARPAR_LEN_1,ptr->smsaddr,0x80,&asn_buf); + + return buf_len; +} + +int extract_Is41SmsNotification_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMSNOT_ARG *ptr; + + ptr = &opr_ptr->msg_list.smsnot_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + +//optional par---> + len = decode_Is41Parameter(IS41PAR_SMSACCDEN,MAX_IS41_VARPAR_LEN,ptr->smsaccden,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT2_TRUE; + ptr->smsaccdenLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSADDR,MAX_IS41_VARPAR_LEN,ptr->smsaddr,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->smsaddrLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsNotification_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMSNOT_RSP *ptr; + + ptr = &opr_ptr->msg_list.smsnot_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + return buf_len; +} + +int extract_Is41SmsNotification_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + + struct IS41_SMSNOT_RSP *ptr; + + ptr = &opr_ptr->msg_list.smsnot_rsp; + + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMSREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.smsreq_arg; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + if((flag & BIT0_TRUE)>0) //min + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MIN,1),MIN_LEN,ptr->min,0x80,&asn_buf); + else + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:MIN absent!!"); + return 0; + } + +// optional part---> + if((flag & BIT1_TRUE)>0) //ElectronicSerialNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2),ESN_LEN,ptr->esn,0x80,&asn_buf); + + if((flag & BIT2_TRUE)>0) //SMS_NotificationIndicator + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSNOTIND,3),ptr->smsnotindLen & MAX_IS41_VARPAR_LEN_1,ptr->smsnotind,0x80,&asn_buf); + + if((flag & BIT3_TRUE)>0) //SMS_TeleserviceIdentifier + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSTID,4),ptr->smstidLen & MAX_IS41_VARPAR_LEN_1,ptr->smstid,0x80,&asn_buf); + + return buf_len; +} + +int extract_Is41SmsRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMSREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.smsreq_arg; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + if (decode_Is41Parameter(IS41PAR_MIN,MIN_LEN,ptr->min,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:MIN absent!"); + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSNOTIND,MAX_IS41_VARPAR_LEN,ptr->smsnotind,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT2_TRUE; + ptr->smsnotindLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSTID,MAX_IS41_VARPAR_LEN,ptr->smstid,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT3_TRUE; + ptr->smstidLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} + +int assign_Is41SmsRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + struct IS41_SMSREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.smsreq_rsp; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + +// optional part---> + if((flag & BIT0_TRUE)>0) //ElectronicSerialNumber + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,1),ESN_LEN,ptr->esn,0x80,&asn_buf); + + if((flag & BIT1_TRUE)>0) //SMS_AccessDeniedReason + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSACCDEN,2),ptr->smsaccdenLen & MAX_IS41_VARPAR_LEN_1,ptr->smsaccden,0x80,&asn_buf); + + if((flag & BIT2_TRUE)>0) //SMS_DestinationAddress + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSADDR,3),ptr->smsaddrLen & MAX_IS41_VARPAR_LEN_1,ptr->smsaddr,0x80,&asn_buf); + + return buf_len; +} + +int extract_Is41SmsRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + + struct IS41_SMSREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.smsreq_rsp; + + if (buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf,buf_len,13,&decErr,&asn_buf) == -1) + return 0; + ptr->param_flag = 0; + + +//optional par---> + if (decode_Is41Parameter(IS41PAR_ESN,ESN_LEN,ptr->esn,&asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:ESN absent!"); + + len = decode_Is41Parameter(IS41PAR_SMSACCDEN,MAX_IS41_VARPAR_LEN,ptr->smsaccden,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT1_TRUE; + ptr->smsaccdenLen = len & MAX_IS41_VARPAR_LEN_1; + } + + len = decode_Is41Parameter(IS41PAR_SMSADDR,MAX_IS41_VARPAR_LEN,ptr->smsaddr,&asn_buf); + if (len > 0) + { + ptr->param_flag |= BIT2_TRUE; + ptr->smsaddrLen = len & MAX_IS41_VARPAR_LEN_1; + } + + is41_debug(IS41DB_DECODE,"[IS41-Decode]Completed, flag=0x%lx",ptr->param_flag); + + return 1; +} diff --git a/plat/xapp/src/mapp/is41_code_win.c b/plat/xapp/src/mapp/is41_code_win.c new file mode 100644 index 0000000..e7a7932 --- /dev/null +++ b/plat/xapp/src/mapp/is41_code_win.c @@ -0,0 +1,1871 @@ +/* ------------------------------------*/ +/* IS41 codec for WIN */ +/* created by Xinyu Yan 2006-04-14 */ +/* ------------------------------------*/ +#include "map_includes.h" + +extern void is41_debug(DWORD mask, const char *fmt, ...); +extern int encode_param_termlist(struct IS41_PAR_TERMLIST *ptr,u32 flag,ASN_BUF *asn_buf,int *buf_len); +extern int decode_param_termlist(IS41_PAR_TERMLIST *ptr,ASN_BUF *asn_buf); + +#define BIT30_TRUE 0x40000000 + +void is41enc_print_absent(char *param_str) +{ + is41_debug(IS41DB_ERR, "[IS41-Encode]: %s absent!", param_str); +} + +void is41dec_print_absent(char *param_str) +{ + is41_debug(IS41DB_ERR, "[IS41-Decode]: %s absent!", param_str); +} + +int decode_Is41Param(char *tag, int maxlen, u8 *len, u8 *value, ASN_BUF *asn_buf) +{ + int decodeLen; + + decodeLen = GetTLV(tag, maxlen, value, 0x80, asn_buf); + if(decodeLen > 0) + { + if(len != NULL) + *len = decodeLen; + return decodeLen; + } + return 0; +} + +u32 is41enc_MSID(u8 seq, IS41_PAR_MSID *ptr, ASN_BUF *asn_buf) +{ + if(ptr->choice_flag == 0) + return AddTLV(is41_sequenceTag(IS41PAR_MIN, seq), MIN_LEN, ptr->min, 0x80, asn_buf); + else if(ptr->choice_flag == 1) + return AddTLV(is41_sequenceTag(IS41PAR_IMSI, seq), IMSI_LEN, ptr->imsi, 0x80, asn_buf); + else + return 0; +} + +u32 is41dec_MSID(IS41_PAR_MSID *ptr, ASN_BUF *asn_buf) +{ + if(decode_Is41Param(IS41PAR_MIN, MIN_LEN, NULL, ptr->min, asn_buf)) + ptr->choice_flag = 0; + else if(decode_Is41Param(IS41PAR_IMSI, IMSI_LEN, NULL, ptr->imsi, asn_buf)) + ptr->choice_flag = 1; + else + return 0; + return 1; +} + +u32 is41enc_WINCAP(u8 seq, IS41_PAR_WIN_CAP *ptr, ASN_BUF *asn_buf) +{ + u32 buf_len = 0; + char tag[32]; + + if(!(ptr->param_flag & 0x03)) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:wincap no content!!"); + return 0; + } + if(ptr->param_flag & BIT0_TRUE) + { + sprintf(tag, "%s-%d.%s", IS41PAR_WINCAP, seq, IS41PAR_TRIGCAP); + buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->triggercapLen & MAX_IS41_VARPAR_LEN_1,ptr->triggercap,0x80,asn_buf); + } + if(ptr->param_flag & BIT1_TRUE) + { + sprintf(tag, "%s-%d.%s", IS41PAR_WINCAP, seq, IS41PAR_WINOPRCAP); + buf_len = AddTLV(is41_sequenceTag(tag,2),ptr->winoprcapLen & MAX_IS41_VARPAR_LEN_1,ptr->winoprcap,0x80,asn_buf); + } + return buf_len; +} + +u32 is41dec_WINCAP(IS41_PAR_WIN_CAP *ptr, ASN_BUF *asn_buf) +{ + char tag[32]; + + ptr->param_flag = 0; + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_TRIGCAP); + if(decode_Is41Param(tag, 32, &ptr->triggercapLen, ptr->triggercap, asn_buf)) + ptr->param_flag |= BIT0_TRUE; + sprintf(tag, "%s.%s", IS41PAR_WINCAP, IS41PAR_WINOPRCAP); + if(decode_Is41Param(tag, 32, &ptr->winoprcapLen, ptr->winoprcap, asn_buf)); + ptr->param_flag |= BIT1_TRUE; + + if(ptr->param_flag != 0) + return 1; + else + return 0; +} + +u32 is41enc_triggerlist(u8 seq, u8 triggerlistnum, IS41_PAR_TRIGGER_LIST *ptr, ASN_BUF *asn_buf) +{ + u32 buf_len = 0; + int i; + char tag[64]; + u32 flag1; + IS41_PAR_TRIGGER_LIST *ptr1; + + if(!triggerlistnum) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:TriggerAddressList no content!!"); + return 0; + } + for(i = 0; i < triggerlistnum; i++) + { + ptr1 = ptr + i; + flag1 = ptr1->param_flag; + if((flag1 & 0x03) != 0x03) + { + is41_debug(IS41DB_ERR,"[IS41-Encode] Stopped,reason:triggerlist lacks mandatory info!!"); + return 0; + } + if(flag1 & BIT0_TRUE) + { + sprintf(tag, "%s-%d.%s-%d.%s", IS41PAR_TRIGADRLIST, seq, IS41PAR_TRIGLIST, i+1, IS41PAR_GLOBALTITLE); + buf_len = AddTLV(is41_sequenceTag(tag,1), ptr1->destaddrLen, ptr1->destaddr, 0x80, asn_buf); + } + if(flag1 & BIT1_TRUE) + { + sprintf(tag, "%s-%d.%s-%d.%s", IS41PAR_TRIGADRLIST, seq, IS41PAR_TRIGLIST, i+1, IS41PAR_WINTRIGLIST); + buf_len = AddTLV(is41_sequenceTag(tag,2), ptr1->wintriglistLen, ptr1->wintriglist, 0x80, asn_buf); + } + } + return buf_len; +} + +u32 is41dec_triggerlist(u8 *triggerlistnum, IS41_PAR_TRIGGER_LIST *ptr, ASN_BUF *asn_buf) +{ + int i; + char tag[64]; + IS41_PAR_TRIGGER_LIST *ptr1; + + *triggerlistnum = 0; + for(i = 0; i < MAX_IS41_TRIG_LIST_NUM; i++) + { + ptr1 = ptr + i; + ptr1->param_flag = 0; + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_GLOBALTITLE); + if(decode_Is41Param(tag, 32, &ptr1->destaddrLen, ptr1->destaddr, asn_buf)) + ptr1->param_flag |= BIT0_TRUE; + sprintf(tag, "%s.%s-%d.%s", IS41PAR_TRIGADRLIST, IS41PAR_TRIGLIST, i+1, IS41PAR_WINTRIGLIST); + if(decode_Is41Param(tag, 32, &ptr1->wintriglistLen, ptr->wintriglist, asn_buf)) + ptr1->param_flag |= BIT1_TRUE; + if(ptr1->param_flag == 0x03) + (*triggerlistnum)++; + else if(ptr1->param_flag == 0) + break; + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:triggerlist lacks mandatory info!!"); + break; + } + } + if(*triggerlistnum != 0) + return 1; + else + return 0; +} + +u32 is41enc_exescr(u8 seq, IS41_PAR_EXESCR *ptr, ASN_BUF *asn_buf) +{ + u32 buf_len = 0; + char tag[32]; + + if(ptr->param_flag & BIT0_TRUE) + { + sprintf(tag, "%s-%d.%s", IS41PAR_EXESCR, seq, IS41PAR_SCRNAME); + buf_len = AddTLV(is41_sequenceTag(tag,1), ptr->scrnameLen, ptr->scrname, 0x80, asn_buf); + } + else + is41_debug(IS41DB_ERR,"[IS41-Encode] Warning,reason:exescr lacks mandatory info!!"); + if(ptr->param_flag & BIT1_TRUE) + { + sprintf(tag, "%s-%d.%s", IS41PAR_EXESCR, seq, IS41PAR_SCRARG); + buf_len = AddTLV(is41_sequenceTag(tag,2), ptr->scrargLen, ptr->scrarg, 0x80, asn_buf); + } + return buf_len; +} + +u32 is41dec_exescr(IS41_PAR_EXESCR *ptr, ASN_BUF *asn_buf) +{ + char tag[32]; + + ptr->param_flag = 0; + sprintf(tag, "%s.%s", IS41PAR_EXESCR, IS41PAR_SCRNAME); + if(decode_Is41Param(tag, 32, &ptr->scrnameLen, ptr->scrname, asn_buf)) + ptr->param_flag |= BIT0_TRUE; + sprintf(tag, "%s.%s", IS41PAR_EXESCR, IS41PAR_SCRARG); + if(decode_Is41Param(tag, 96, &ptr->scrargLen, ptr->scrarg, asn_buf)); + ptr->param_flag |= BIT1_TRUE; + + if(ptr->param_flag&BIT0_TRUE) + return 1; + else + return 0; +} + +/****************************************************************************************/ +int assign_is41OriginationRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_ORREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.orreq_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1), 7, ptr->billid, 0x80, &asn_buf); + else + is41enc_print_absent("BillingID"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,2), ptr->digitsLen, ptr->digits, 0x80, &asn_buf); + else + is41enc_print_absent("Digits"); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,3), 4, ptr->esn, 0x80, &asn_buf); + else + is41enc_print_absent("ESN"); + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,4), 3, ptr->mscid, 0x80, &asn_buf); + else + is41enc_print_absent("MSCID"); + if(flag & BIT4_TRUE) + buf_len = is41enc_MSID(5, &ptr->msid, &asn_buf); + else + is41enc_print_absent("MSID"); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ORIGTRIG,6), ptr->origtrigLen, ptr->origtrig, 0x80, &asn_buf); + else + is41enc_print_absent("OriginationTriggers"); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,7), ptr->transcapLen, ptr->transcap, 0x80, &asn_buf); + else + is41enc_print_absent("TransactionCapability"); + //optional + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNAME,8), ptr->cpnameLen, ptr->cpname, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS1,9), ptr->cpndgts1Len, ptr->cpndgts1, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS2,10), ptr->cpndgts2Len, ptr->cpndgts2, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,11), ptr->cpsubLen, ptr->cpsub, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,12), 2, ptr->locid, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,13), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_FEATIND,14), ptr->featindLen, ptr->featind, 0x80, &asn_buf); + if(flag & BIT14_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,15), ptr->mscinLen, ptr->mscin, 0x80, &asn_buf); + if(flag & BIT15_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,16), ptr->otfiLen, ptr->otfi, 0x80, &asn_buf); + if(flag & BIT16_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PCSSN,17), 5, ptr->pc_ssn, 0x80, &asn_buf); + if(flag & BIT17_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PLIND,18), 1, &ptr->plind, 0x80, &asn_buf); + if(flag & BIT18_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SENDERIN,19), ptr->senderinLen, ptr->senderin, 0x80, &asn_buf); + if(flag & BIT19_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SCID,20), 2, ptr->scellid, 0x80, &asn_buf); + if(flag & BIT20_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGERTYPE,21), 1, &ptr->triggertype, 0x80, &asn_buf); + if(flag & BIT21_TRUE) + buf_len = is41enc_WINCAP(22, &ptr->wincap, &asn_buf); + return buf_len; +} + +int assign_is41OriginationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_ORREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.orreq_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACCDEN,1), 1, &ptr->accden, 0x80, &asn_buf); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACTCODE,2), ptr->actcodeLen, ptr->actcode, 0x80, &asn_buf); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,3), ptr->annlistLen, ptr->annlist, 0x80, &asn_buf); + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG1,4), ptr->cpnstrg1Len, ptr->cpnstrg1, 0x80, &asn_buf); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNSTRG2,5), ptr->cpnstrg2Len, ptr->cpnstrg2, 0x80, &asn_buf); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,6), ptr->cpsubLen, ptr->cpsub, 0x80, &asn_buf); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CARDGTS,7), ptr->cardgtsLen, ptr->cardgts, 0x80, &asn_buf); + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,8), ptr->digitsLen, ptr->digits, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DISPTEXT,9), ptr->disptextLen, ptr->disptext, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,10), ptr->acdgtsLen, ptr->acdgts, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,11), ptr->abdgtsLen, ptr->abdgts, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,12), ptr->billdgtsLen, ptr->billdgts, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDIND,13), ptr->redindLen, ptr->redind, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DMH_SVCID,14), ptr->dmh_svcidLen, ptr->dmh_svcid, 0x80, &asn_buf); + if(flag & BIT14_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_GRPINFO,15), ptr->grpinfoLen, ptr->grpinfo, 0x80, &asn_buf); + if(flag & BIT15_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,16), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT16_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NATIME,17), ptr->natimeLen, ptr->natime, 0x80, &asn_buf); + if(flag & BIT17_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,18), ptr->otfiLen, ptr->otfi, 0x80, &asn_buf); + if(flag & BIT18_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PILOT,19), ptr->pilotLen, ptr->pilot, 0x80, &asn_buf); + if(flag & BIT19_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNDGTS,20), ptr->rndgtsLen, ptr->rndgts, 0x80, &asn_buf); + if(flag & BIT20_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNSTRING,21), ptr->rnstringLen, ptr->rnstring, 0x80, &asn_buf); + if(flag & BIT21_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSUB,22), ptr->rsubLen, ptr->rsub, 0x80, &asn_buf); + if(flag & BIT22_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RESUMEPIC,23), 1, &ptr->resumepic, 0x80, &asn_buf); + if(flag & BIT23_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ROUTDGTS,24), ptr->routdgtsLen, ptr->routdgts, 0x80, &asn_buf); + if(flag & BIT24_TRUE) + encode_param_termlist(&ptr->termlist, ptr->termlist.param_flag, &asn_buf, &buf_len); + if(flag & BIT25_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,26), ptr->termtrigLen, ptr->termtrig, 0x80, &asn_buf); + if(flag & BIT26_TRUE) + buf_len = is41enc_triggerlist(27, ptr->triggerlistnum, ptr->triggerlist, &asn_buf); + return buf_len; +} + +int extract_is41OriginationRequest_arg(struct MapOprSrv_struct *opr_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ORREQ_ARG *ptr; + + ptr = &opr_ptr->msg_list.orreq_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_BILLID, 7, NULL, ptr->billid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("BillingID"); + if(decode_Is41Param(IS41PAR_DIGITS, 32, &ptr->digitsLen, ptr->digits, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("Digits"); + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("ESN"); + if(decode_Is41Param(IS41PAR_MSCID, 3, NULL, ptr->mscid, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + is41dec_print_absent("MSCID"); + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + is41dec_print_absent("MSID"); + if(decode_Is41Param(IS41PAR_ORIGTRIG, 32, &ptr->origtrigLen, ptr->origtrig, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + else + is41dec_print_absent("OriginationTriggers"); + if(decode_Is41Param(IS41PAR_TRANSCAP, 32, &ptr->transcapLen, ptr->transcap, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + else + is41dec_print_absent("TransactionCapability"); + //optional + if(decode_Is41Param(IS41PAR_CPNAME, 32, &ptr->cpnameLen, ptr->cpname, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_CPNDGTS1, 32, &ptr->cpndgts1Len, ptr->cpndgts1, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_CPNDGTS2, 32, &ptr->cpndgts2Len, ptr->cpndgts2, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_CPSUB, 32, &ptr->cpsubLen, ptr->cpsub, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_LOCID, 2, NULL, ptr->locid, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_Is41Param(IS41PAR_FEATIND, 32, &ptr->featindLen, ptr->featind, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(decode_Is41Param(IS41PAR_MSCIN, 32, &ptr->mscinLen, ptr->mscin, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + if(decode_Is41Param(IS41PAR_OTFI, 32, &ptr->otfiLen, ptr->otfi, &asn_buf)) + ptr->param_flag |= BIT15_TRUE; + if(decode_Is41Param(IS41PAR_PCSSN, 5, NULL, ptr->pc_ssn, &asn_buf)) + ptr->param_flag |= BIT16_TRUE; + if(decode_Is41Param(IS41PAR_PLIND, 1, NULL, &ptr->plind, &asn_buf)) + ptr->param_flag |= BIT17_TRUE; + if(decode_Is41Param(IS41PAR_SENDERIN, 32, &ptr->senderinLen, ptr->senderin, &asn_buf)) + ptr->param_flag |= BIT18_TRUE; + if(decode_Is41Param(IS41PAR_SCID, 2, NULL, ptr->scellid, &asn_buf)) + ptr->param_flag |= BIT19_TRUE; + if(decode_Is41Param(IS41PAR_TRIGERTYPE, 1, NULL, &ptr->triggertype, &asn_buf)) + ptr->param_flag |= BIT20_TRUE; + if(is41dec_WINCAP(&ptr->wincap, &asn_buf)) + ptr->param_flag |= BIT21_TRUE; + return 1; +} + +int extract_is41OriginationRequest_rsp(struct MapOprSrv_struct *opr_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ORREQ_RSP *ptr; + + ptr = &opr_ptr->msg_list.orreq_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_ACCDEN, 1, NULL, &ptr->accden, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if(decode_Is41Param(IS41PAR_ACTCODE, 32, &ptr->actcodeLen, ptr->actcode, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if(decode_Is41Param(IS41PAR_ANNLIST, 32, &ptr->annlistLen, ptr->annlist, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if(decode_Is41Param(IS41PAR_CPNSTRG1, 32, &ptr->cpnstrg1Len, ptr->cpnstrg1, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if(decode_Is41Param(IS41PAR_CPNSTRG2, 32, &ptr->cpnstrg2Len, ptr->cpnstrg2, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if(decode_Is41Param(IS41PAR_CPSUB, 32, &ptr->cpsubLen, ptr->cpsub, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if(decode_Is41Param(IS41PAR_CARDGTS, 32, &ptr->cardgtsLen, ptr->cardgts, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if(decode_Is41Param(IS41PAR_DIGITS, 32, &ptr->digitsLen, ptr->digits, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_DISPTEXT, 32, &ptr->disptextLen, ptr->disptext, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_ACDGTS, 32, &ptr->acdgtsLen, ptr->acdgts, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_ABDGTS, 32, &ptr->abdgtsLen, ptr->abdgts, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_BILLDGTS, 32, &ptr->billdgtsLen, ptr->billdgts, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_REDIND, 32, &ptr->redindLen, ptr->redind, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_Is41Param(IS41PAR_DMH_SVCID, 32, &ptr->dmh_svcidLen, ptr->dmh_svcid, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(decode_Is41Param(IS41PAR_GRPINFO, 32, &ptr->grpinfoLen, ptr->grpinfo, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT15_TRUE; + if(decode_Is41Param(IS41PAR_NATIME, 32, &ptr->natimeLen, ptr->natime, &asn_buf)) + ptr->param_flag |= BIT16_TRUE; + if(decode_Is41Param(IS41PAR_OTFI, 32, &ptr->otfiLen, ptr->otfi, &asn_buf)) + ptr->param_flag |= BIT17_TRUE; + if(decode_Is41Param(IS41PAR_PILOT, 32, &ptr->pilotLen, ptr->pilot, &asn_buf)) + ptr->param_flag |= BIT18_TRUE; + if(decode_Is41Param(IS41PAR_RNDGTS, 32, &ptr->rndgtsLen, ptr->rndgts, &asn_buf)) + ptr->param_flag |= BIT19_TRUE; + if(decode_Is41Param(IS41PAR_RNSTRING, 32, &ptr->rnstringLen, ptr->rnstring, &asn_buf)) + ptr->param_flag |= BIT20_TRUE; + if(decode_Is41Param(IS41PAR_RSUB, 32, &ptr->rsubLen, ptr->rsub, &asn_buf)) + ptr->param_flag |= BIT21_TRUE; + if(decode_Is41Param(IS41PAR_RESUMEPIC, 1, NULL, &ptr->resumepic, &asn_buf)) + ptr->param_flag |= BIT22_TRUE; + if(decode_Is41Param(IS41PAR_ROUTDGTS, 32, NULL, ptr->routdgts, &asn_buf)) + ptr->param_flag |= BIT23_TRUE; + if(decode_param_termlist(&ptr->termlist, &asn_buf)) + ptr->param_flag |= BIT24_TRUE; + if(decode_Is41Param(IS41PAR_TERMTRIG, 32, &ptr->termtrigLen, ptr->termtrig, &asn_buf)) + ptr->param_flag |= BIT25_TRUE; + if(is41dec_triggerlist(&ptr->triggerlistnum, ptr->triggerlist, &asn_buf)) + ptr->param_flag |= BIT26_TRUE; + return 1; +} + +int assign_is41AnalyzedInformation_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_ANLYZD_ARG *ptr; + + ptr = &opr_ptr->msg_list.anlyzd_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1), 7, ptr->billid, 0x80, &asn_buf); + else + is41enc_print_absent("BillingID"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,2), ptr->digitsLen, ptr->digits, 0x80, &asn_buf); + else + is41enc_print_absent("Digits"); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3), 3, ptr->mscid, 0x80, &asn_buf); + else + is41enc_print_absent("MSCID"); + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,4), ptr->transcapLen, ptr->transcap, 0x80, &asn_buf); + else + is41enc_print_absent("TransactionCapability"); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGERTYPE,5), 1, &ptr->triggertype, 0x80, &asn_buf); + else + is41enc_print_absent("TriggerType"); + if(flag & BIT5_TRUE) + buf_len = is41enc_WINCAP(6, &ptr->wincap, &asn_buf); + else + is41enc_print_absent("WINCapability"); + //optional + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNAME,7), ptr->cpnameLen, ptr->cpname, 0x80, &asn_buf); + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS1,8), ptr->cpndgts1Len, ptr->cpndgts1, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPNDGTS2,9), ptr->cpndgts2Len, ptr->cpndgts2, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CPSUB,10), ptr->cpsubLen, ptr->cpsub, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CARDGTS,11), ptr->cardgtsLen, ptr->cardgts, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCI,12), ptr->cciLen, ptr->cci, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DESTDGTS,13), ptr->destdgtsLen, ptr->destdgts, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDIND,14), ptr->redindLen, ptr->redind, 0x80, &asn_buf); + if(flag & BIT14_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,15), 4, ptr->esn, 0x80, &asn_buf); + if(flag & BIT15_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_FEATIND,16), ptr->featindLen, ptr->featind, 0x80, &asn_buf); + if(flag & BIT16_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,17), 2, ptr->locid, 0x80, &asn_buf); + if(flag & BIT17_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,18), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT18_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,19), ptr->mscinLen, ptr->mscin, 0x80, &asn_buf); + if(flag & BIT19_TRUE) + buf_len = is41enc_MSID(20, &ptr->msid, &asn_buf); + if(flag & BIT20_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,21), ptr->otfiLen, ptr->otfi, 0x80, &asn_buf); + if(flag & BIT21_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PLIND,22), 1, &ptr->plind, 0x80, &asn_buf); + if(flag & BIT22_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNDGTS,23), ptr->rndgtsLen, ptr->rndgts, 0x80, &asn_buf); + if(flag & BIT23_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RDNAME,24), ptr->rdnameLen, ptr->rdname, 0x80, &asn_buf); + if(flag & BIT24_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RSUB,25), ptr->rsubLen, ptr->rsub, 0x80, &asn_buf); + if(flag & BIT25_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ROUTDGTS,26), ptr->routdgtsLen, ptr->routdgts, 0x80, &asn_buf); + if(flag & BIT26_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SCID,27), 2, ptr->scellid, 0x80, &asn_buf); + if(flag & BIT27_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,28), 1, &ptr->mytyp, 0x80, &asn_buf); + if(flag & BIT28_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TAT,29), 1, &ptr->tat, 0x80, &asn_buf); + if(flag & BIT29_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TDO,30), 2, ptr->tdo, 0x80, &asn_buf); + if(flag & BIT30_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TOD,31), 3, ptr->tod, 0x80, &asn_buf); + return buf_len; +} + +int assign_is41AnalyzedInformation_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_ANLYZD_RSP *ptr; + + ptr = &opr_ptr->msg_list.anlyzd_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACCDEN,1), 1, &ptr->accden, 0x80, &asn_buf); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACTCODE,2), ptr->actcodeLen, ptr->actcode, 0x80, &asn_buf); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,3), ptr->annlistLen, ptr->annlist, 0x80, &asn_buf); + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CARDGTS,4), ptr->cardgtsLen, ptr->cardgts, 0x80, &asn_buf); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CCI,5), ptr->cciLen, ptr->cci, 0x80, &asn_buf); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,6), ptr->digitsLen, ptr->digits, 0x80, &asn_buf); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DISPTEXT,7), ptr->disptextLen, ptr->disptext, 0x80, &asn_buf); + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,8), ptr->acdgtsLen, ptr->acdgts, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,9), ptr->abdgtsLen, ptr->abdgts, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,10), ptr->billdgtsLen, ptr->billdgts, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDIND,11), ptr->redindLen, ptr->redind, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DMH_SVCID,12), ptr->dmh_svcidLen, ptr->dmh_svcid, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_NATIME,13), ptr->natimeLen, ptr->natime, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_OTFI,14), ptr->otfiLen, ptr->otfi, 0x80, &asn_buf); + if(flag & BIT14_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RNDGTS,15), ptr->rndgtsLen, ptr->rndgts, 0x80, &asn_buf); + if(flag & BIT15_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RESUMEPIC,16), 1, &ptr->resumepic, 0x80, &asn_buf); + if(flag & BIT16_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ROUTDGTS,17), ptr->routdgtsLen, ptr->routdgts, 0x80, &asn_buf); + if(flag & BIT17_TRUE) + encode_param_termlist(&ptr->termlist, ptr->termlist.param_flag, &asn_buf, &buf_len); + if(flag & BIT18_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TERMTRIG,19), ptr->termtrigLen, ptr->termtrig, 0x80, &asn_buf); + if(flag & BIT19_TRUE) + buf_len = is41enc_triggerlist(20, ptr->triggerlistnum, ptr->triggerlist, &asn_buf); + return buf_len; +} + +int extract_is41AnalyzedInformation_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ANLYZD_ARG *ptr; + + ptr = &opr_ptr->msg_list.anlyzd_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_BILLID, 7, NULL, ptr->billid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("BillingID"); + if(decode_Is41Param(IS41PAR_DIGITS, 32, &ptr->digitsLen, ptr->digits, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("Digits"); + if(decode_Is41Param(IS41PAR_MSCID, 3, NULL, ptr->mscid, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("MSCID"); + if(decode_Is41Param(IS41PAR_TRANSCAP, 32, &ptr->transcapLen, ptr->transcap, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + is41dec_print_absent("TransactionCapability"); + if(decode_Is41Param(IS41PAR_TRIGERTYPE, 1, NULL, &ptr->triggertype, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + is41dec_print_absent("TriggerType"); + if(is41dec_WINCAP(&ptr->wincap, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + else + is41dec_print_absent("WINCapability"); + //optional + if(decode_Is41Param(IS41PAR_CPNAME, 32, &ptr->cpnameLen, ptr->cpname, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if(decode_Is41Param(IS41PAR_CPNDGTS1, 32, &ptr->cpndgts1Len, ptr->cpndgts1, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_CPNDGTS2, 32, &ptr->cpndgts2Len, ptr->cpndgts2, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_CPSUB, 32, &ptr->cpsubLen, ptr->cpsub, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_CARDGTS, 32, &ptr->cardgtsLen, ptr->cardgts, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_CCI, 32, &ptr->cciLen, ptr->cci, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_DESTDGTS, 32, &ptr->destdgtsLen, ptr->destdgts, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_Is41Param(IS41PAR_REDIND, 32, &ptr->redindLen, ptr->redind, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + if(decode_Is41Param(IS41PAR_FEATIND, 32, &ptr->featindLen, ptr->featind, &asn_buf)) + ptr->param_flag |= BIT15_TRUE; + if(decode_Is41Param(IS41PAR_LOCID, 2, NULL, ptr->locid, &asn_buf)) + ptr->param_flag |= BIT16_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT17_TRUE; + if(decode_Is41Param(IS41PAR_MSCIN, 32, &ptr->mscinLen, ptr->mscin, &asn_buf)) + ptr->param_flag |= BIT18_TRUE; + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT19_TRUE; + if(decode_Is41Param(IS41PAR_OTFI, 32, &ptr->otfiLen, ptr->otfi, &asn_buf)) + ptr->param_flag |= BIT20_TRUE; + if(decode_Is41Param(IS41PAR_PLIND, 1, NULL, &ptr->plind, &asn_buf)) + ptr->param_flag |= BIT21_TRUE; + if(decode_Is41Param(IS41PAR_RNDGTS, 32, &ptr->rndgtsLen, ptr->rndgts, &asn_buf)) + ptr->param_flag |= BIT22_TRUE; + if(decode_Is41Param(IS41PAR_RDNAME, 32, &ptr->rdnameLen, ptr->rdname, &asn_buf)) + ptr->param_flag |= BIT23_TRUE; + if(decode_Is41Param(IS41PAR_RSUB, 32, &ptr->rsubLen, ptr->rsub, &asn_buf)) + ptr->param_flag |= BIT24_TRUE; + if(decode_Is41Param(IS41PAR_ROUTDGTS, 32, &ptr->routdgtsLen, ptr->routdgts, &asn_buf)) + ptr->param_flag |= BIT25_TRUE; + if(decode_Is41Param(IS41PAR_SCID, 2, NULL, ptr->scellid, &asn_buf)) + ptr->param_flag |= BIT26_TRUE; + if(decode_Is41Param(IS41PAR_MYTYP, 1, NULL, &ptr->mytyp, &asn_buf)) + ptr->param_flag |= BIT27_TRUE; + if(decode_Is41Param(IS41PAR_TAT, 1, NULL, &ptr->tat, &asn_buf)) + ptr->param_flag |= BIT28_TRUE; + if(decode_Is41Param(IS41PAR_TDO, 2, NULL, ptr->tdo, &asn_buf)) + ptr->param_flag |= BIT29_TRUE; + if(decode_Is41Param(IS41PAR_TOD, 3, NULL, ptr->tod, &asn_buf)) + ptr->param_flag |= BIT30_TRUE; + return 1; +} + +int extract_is41AnalyzedInformation_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ANLYZD_RSP *ptr; + + ptr = &opr_ptr->msg_list.anlyzd_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_ACCDEN, 1, NULL, &ptr->accden, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if(decode_Is41Param(IS41PAR_ACTCODE, 32, &ptr->actcodeLen, ptr->actcode, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if(decode_Is41Param(IS41PAR_ANNLIST, 32, &ptr->annlistLen, ptr->annlist, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if(decode_Is41Param(IS41PAR_CARDGTS, 32, &ptr->cardgtsLen, ptr->cardgts, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if(decode_Is41Param(IS41PAR_CCI, 32, &ptr->cciLen, ptr->cci, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if(decode_Is41Param(IS41PAR_DIGITS, 32, &ptr->digitsLen, ptr->digits, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if(decode_Is41Param(IS41PAR_DISPTEXT, 32, &ptr->disptextLen, ptr->disptext, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if(decode_Is41Param(IS41PAR_ACDGTS, 32, &ptr->acdgtsLen, ptr->acdgts, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_ABDGTS, 32, &ptr->abdgtsLen, ptr->abdgts, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_BILLDGTS, 32, &ptr->billdgtsLen, ptr->billdgts, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_REDIND, 32, &ptr->redindLen, ptr->redind, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_DMH_SVCID, 32, &ptr->dmh_svcidLen, ptr->dmh_svcid, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_NATIME, 32, &ptr->natimeLen, ptr->natime, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_Is41Param(IS41PAR_OTFI, 32, &ptr->otfiLen, ptr->otfi, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(decode_Is41Param(IS41PAR_RNDGTS, 32, &ptr->rndgtsLen, ptr->rndgts, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + if(decode_Is41Param(IS41PAR_RESUMEPIC, 1, NULL, &ptr->resumepic, &asn_buf)) + ptr->param_flag |= BIT15_TRUE; + if(decode_Is41Param(IS41PAR_ROUTDGTS, 32, &ptr->routdgtsLen, ptr->routdgts, &asn_buf)) + ptr->param_flag |= BIT16_TRUE; + if(decode_param_termlist(&ptr->termlist, &asn_buf)) + ptr->param_flag |= BIT17_TRUE; + if(decode_Is41Param(IS41PAR_TERMTRIG, 32, &ptr->termtrigLen, ptr->termtrig, &asn_buf)) + ptr->param_flag |= BIT18_TRUE; + if(is41dec_triggerlist(&ptr->triggerlistnum, ptr->triggerlist, &asn_buf)) + ptr->param_flag |= BIT19_TRUE; + return 1; +} + +int assign_is41OAnswer_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_OANSWER_ARG *ptr; + + ptr = &opr_ptr->msg_list.oanswer_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1), 7, ptr->billid, 0x80, &asn_buf); + else + is41enc_print_absent("BillingID"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2), 4, ptr->esn, 0x80, &asn_buf); + else + is41enc_print_absent("ESN"); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3), 3, ptr->mscid, 0x80, &asn_buf); + else + is41enc_print_absent("MSCID"); + if(flag & BIT3_TRUE) + buf_len = is41enc_MSID(4, &ptr->msid, &asn_buf); + else + is41enc_print_absent("MSID"); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TDO,5), 2, ptr->tdo, 0x80, &asn_buf); + else + is41enc_print_absent("TimeDateOffset"); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TOD,6), 3, ptr->tod, 0x80, &asn_buf); + else + is41enc_print_absent("TimeOfDay"); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGERTYPE,7), 1, &ptr->triggertype, 0x80, &asn_buf); + else + is41enc_print_absent("TriggerType"); + //optional + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,8), 2, ptr->locid, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,9), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_FEATIND,10), ptr->featindLen, ptr->featind, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,11), ptr->mscinLen, ptr->mscin, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SCID,12), 2, ptr->scellid, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,13), 1, &ptr->mytyp, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41OAnswer_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_OANSWER_ARG *ptr; + + ptr = &opr_ptr->msg_list.oanswer_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_BILLID, 7, NULL, ptr->billid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("BillingID"); + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("ESN"); + if(decode_Is41Param(IS41PAR_MSCID, 3, NULL, ptr->mscid, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("MSCID"); + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + is41dec_print_absent("MSID"); + if(decode_Is41Param(IS41PAR_TDO, 2, NULL, ptr->tdo, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + is41dec_print_absent("TimeDateOffset"); + if(decode_Is41Param(IS41PAR_TOD, 3, NULL, ptr->tod, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + else + is41dec_print_absent("TimeOfDay"); + if(decode_Is41Param(IS41PAR_TRIGERTYPE, 1, NULL, &ptr->triggertype, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + else + is41dec_print_absent("TriggerType"); + //optional + if(decode_Is41Param(IS41PAR_LOCID, 2, NULL, ptr->locid, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_FEATIND, 32, &ptr->featindLen, ptr->featind, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_MSCIN, 32, &ptr->mscinLen, ptr->mscin, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_SCID, 2, NULL, ptr->scellid, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_MYTYP, 1, NULL, &ptr->mytyp, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + return 1; +} + +int assign_is41ODisconnect_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_ODISCONNECT_ARG *ptr; + + ptr = &opr_ptr->msg_list.odisconnect_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1), 7, ptr->billid, 0x80, &asn_buf); + else + is41enc_print_absent("BillingID"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2), 4, ptr->esn, 0x80, &asn_buf); + else + is41enc_print_absent("ESN"); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3), 3, ptr->mscid, 0x80, &asn_buf); + else + is41enc_print_absent("MSCID"); + if(flag & BIT3_TRUE) + buf_len = is41enc_MSID(4, &ptr->msid, &asn_buf); + else + is41enc_print_absent("MSID"); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RELCAUSE,5), 1, &ptr->relcause, 0x80, &asn_buf); + else + is41enc_print_absent("ReleaseCause"); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TDO,6), 2, ptr->tdo, 0x80, &asn_buf); + else + is41enc_print_absent("TimeDateOffset"); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TOD,7), 3, ptr->tod, 0x80, &asn_buf); + else + is41enc_print_absent("TimeOfDay"); + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,8), ptr->transcapLen, ptr->transcap, 0x80, &asn_buf); + else + is41enc_print_absent("TransactionCapability"); + if(flag & BIT8_TRUE) + buf_len = is41enc_WINCAP(9, &ptr->wincap, &asn_buf); + else + is41enc_print_absent("WINCapability"); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGERTYPE,10), 1, &ptr->triggertype, 0x80, &asn_buf); + else + is41enc_print_absent("TriggerType"); + //optional + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,11), 2, ptr->locid, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,12), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,13), ptr->mscinLen, ptr->mscin, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SCID,14), 2, ptr->scellid, 0x80, &asn_buf); + if(flag & BIT14_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,15), 1, &ptr->mytyp, 0x80, &asn_buf); + return buf_len; +} + +int assign_is41ODisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_ODISCONNECT_RSP *ptr; + + ptr = &opr_ptr->msg_list.odisconnect_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,1), ptr->annlistLen, ptr->annlist, 0x80, &asn_buf); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DMH_SVCID,2), ptr->dmh_svcidLen, ptr->dmh_svcid, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41ODisconnect_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ODISCONNECT_ARG *ptr; + + ptr = &opr_ptr->msg_list.odisconnect_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_BILLID, 7, NULL, ptr->billid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("BillingID"); + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("ESN"); + if(decode_Is41Param(IS41PAR_MSCID, 3, NULL, ptr->mscid, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("MSCID"); + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + is41dec_print_absent("MSID"); + if(decode_Is41Param(IS41PAR_RELCAUSE, 1, NULL, &ptr->relcause, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + is41dec_print_absent("ReleaseCause"); + if(decode_Is41Param(IS41PAR_TDO, 2, NULL, ptr->tdo, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + else + is41dec_print_absent("TimeDateOffset"); + if(decode_Is41Param(IS41PAR_TOD, 3, NULL, ptr->tod, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + else + is41dec_print_absent("TimeOfDay"); + if(decode_Is41Param(IS41PAR_TRANSCAP, 32, &ptr->transcapLen, ptr->transcap, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + else + is41dec_print_absent("TransactionCapability"); + if(is41dec_WINCAP(&ptr->wincap, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + else + is41dec_print_absent("WINCapability"); + if(decode_Is41Param(IS41PAR_TRIGERTYPE, 1, NULL, &ptr->triggertype, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + else + is41dec_print_absent("TriggerType"); + //optional + if(decode_Is41Param(IS41PAR_LOCID, 2, NULL, ptr->locid, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_MSCIN, 32, &ptr->mscinLen, ptr->mscin, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_Is41Param(IS41PAR_SCID, 2, NULL, ptr->scellid, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(decode_Is41Param(IS41PAR_MYTYP, 1, NULL, &ptr->mytyp, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + return 1; +} + +int extract_is41ODisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_ODISCONNECT_RSP *ptr; + + ptr = &opr_ptr->msg_list.odisconnect_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_ANNLIST, 32, &ptr->annlistLen, ptr->annlist, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if(decode_Is41Param(IS41PAR_DMH_SVCID, 32, &ptr->dmh_svcidLen, ptr->dmh_svcid, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + return 1; +} + +int assign_is41TAnswer_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_TANSWER_ARG *ptr; + + ptr = &opr_ptr->msg_list.tanswer_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1), 7, ptr->billid, 0x80, &asn_buf); + else + is41enc_print_absent("BillingID"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2), 4, ptr->esn, 0x80, &asn_buf); + else + is41enc_print_absent("ESN"); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3), 3, ptr->mscid, 0x80, &asn_buf); + else + is41enc_print_absent("MSCID"); + if(flag & BIT3_TRUE) + buf_len = is41enc_MSID(4, &ptr->msid, &asn_buf); + else + is41enc_print_absent("MSID"); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TDO,5), 2, ptr->tdo, 0x80, &asn_buf); + else + is41enc_print_absent("TimeDateOffset"); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TOD,6), 3, ptr->tod, 0x80, &asn_buf); + else + is41enc_print_absent("TimeOfDay"); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRANSCAP,7), ptr->transcapLen, ptr->transcap, 0x80, &asn_buf); + else + is41enc_print_absent("TransactionCapability"); + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGERTYPE,8), 1, &ptr->triggertype, 0x80, &asn_buf); + else + is41enc_print_absent("TriggerType"); + if(flag & BIT8_TRUE) + buf_len = is41enc_WINCAP(9, &ptr->wincap, &asn_buf); + else + is41enc_print_absent("WINCapability"); + //optional + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,10), 2, ptr->locid, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,11), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_FEATIND,12), ptr->featindLen, ptr->featind, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,13), ptr->mscinLen, ptr->mscin, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SCID,14), 2, ptr->scellid, 0x80, &asn_buf); + if(flag & BIT14_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,15), 1, &ptr->mytyp, 0x80, &asn_buf); + if(flag & BIT15_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TAT,16), 1, &ptr->tat, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41TAnswer_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_TANSWER_ARG *ptr; + + ptr = &opr_ptr->msg_list.tanswer_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_BILLID, 7, NULL, ptr->billid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("BillingID"); + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("ESN"); + if(decode_Is41Param(IS41PAR_MSCID, 3, NULL, ptr->mscid, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("MSCID"); + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + is41dec_print_absent("MSID"); + if(decode_Is41Param(IS41PAR_TDO, 2, NULL, ptr->tdo, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + is41dec_print_absent("TimeDateOffset"); + if(decode_Is41Param(IS41PAR_TOD, 3, NULL, ptr->tod, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + else + is41dec_print_absent("TimeOfDay"); + if(decode_Is41Param(IS41PAR_TRANSCAP, 32, &ptr->transcapLen, ptr->transcap, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + else + is41dec_print_absent("TransactionCapability"); + if(decode_Is41Param(IS41PAR_TRIGERTYPE, 1, NULL, &ptr->triggertype, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + else + is41dec_print_absent("TriggerType"); + if(is41dec_WINCAP(&ptr->wincap, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + else + is41dec_print_absent("WINCapability"); + //optional + if(decode_Is41Param(IS41PAR_LOCID, 2, NULL, ptr->locid, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_FEATIND, 32, &ptr->featindLen, ptr->featind, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_MSCIN, 32, &ptr->mscinLen, ptr->mscin, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_Is41Param(IS41PAR_SCID, 2, NULL, ptr->scellid, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(decode_Is41Param(IS41PAR_MYTYP, 1, NULL, &ptr->mytyp, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + if(decode_Is41Param(IS41PAR_TAT, 1, NULL, &ptr->tat, &asn_buf)) + ptr->param_flag |= BIT15_TRUE; + return 1; +} + +int assign_is41TDisconnect_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_TDISCONNECT_ARG *ptr; + + ptr = &opr_ptr->msg_list.tdisconnect_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1), 7, ptr->billid, 0x80, &asn_buf); + else + is41enc_print_absent("BillingID"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,2), 4, ptr->esn, 0x80, &asn_buf); + else + is41enc_print_absent("ESN"); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,3), 3, ptr->mscid, 0x80, &asn_buf); + else + is41enc_print_absent("MSCID"); + if(flag & BIT3_TRUE) + buf_len = is41enc_MSID(4, &ptr->msid, &asn_buf); + else + is41enc_print_absent("MSID"); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TDO,5), 2, ptr->tdo, 0x80, &asn_buf); + else + is41enc_print_absent("TimeDateOffset"); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TOD,6), 3, ptr->tod, 0x80, &asn_buf); + else + is41enc_print_absent("TimeOfDay"); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TRIGERTYPE,7), 1, &ptr->triggertype, 0x80, &asn_buf); + else + is41enc_print_absent("TriggerType"); + //optional + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_LOCID,8), 2, ptr->locid, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,9), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCIN,10), ptr->mscinLen, ptr->mscin, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_RELCAUSE,11), 1, &ptr->relcause, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SCID,12), 2, ptr->scellid, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MYTYP,13), 1, &ptr->mytyp, 0x80, &asn_buf); + return buf_len; +} + +int assign_is41TDisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_TDISCONNECT_RSP *ptr; + + ptr = &opr_ptr->msg_list.tdisconnect_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DMH_SVCID,1), ptr->dmh_svcidLen, ptr->dmh_svcid, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41TDisconnect_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_TDISCONNECT_ARG *ptr; + + ptr = &opr_ptr->msg_list.tdisconnect_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_BILLID, 7, NULL, ptr->billid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("BillingID"); + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("ESN"); + if(decode_Is41Param(IS41PAR_MSCID, 3, NULL, ptr->mscid, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("MSCID"); + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + is41dec_print_absent("MSID"); + if(decode_Is41Param(IS41PAR_TDO, 2, NULL, ptr->tdo, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + else + is41dec_print_absent("TimeDateOffset"); + if(decode_Is41Param(IS41PAR_TOD, 3, NULL, ptr->tod, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + else + is41dec_print_absent("TimeOfDay"); + if(decode_Is41Param(IS41PAR_TRIGERTYPE, 1, NULL, &ptr->triggertype, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + else + is41dec_print_absent("TriggerType"); + //optional + if(decode_Is41Param(IS41PAR_LOCID, 2, NULL, ptr->locid, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_MSCIN, 32, &ptr->mscinLen, ptr->mscin, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_RELCAUSE, 1, NULL, &ptr->relcause, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_SCID, 2, NULL, ptr->scellid, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_MYTYP, 1, NULL, &ptr->mytyp, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + return 1; +} + +int extract_is41TDisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_TDISCONNECT_RSP *ptr; + + ptr = &opr_ptr->msg_list.tdisconnect_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_DMH_SVCID, 32, &ptr->dmh_svcidLen, ptr->dmh_svcid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + return 1; +} + +int assign_is41CallControlDirective_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_CCDIR_ARG *ptr; + + ptr = &opr_ptr->msg_list.ccdir_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLID,1), 7, ptr->billid, 0x80, &asn_buf); + else + is41enc_print_absent("BillingID"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MSCID,2), 3, ptr->mscid, 0x80, &asn_buf); + else + is41enc_print_absent("MSCID"); + if(flag & BIT2_TRUE) + buf_len = is41enc_MSID(3, &ptr->msid, &asn_buf); + else + is41enc_print_absent("MSID"); + //optional + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACTCODE,4), ptr->actcodeLen, ptr->actcode, 0x80, &asn_buf); + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,5), ptr->annlistLen, ptr->annlist, 0x80, &asn_buf); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DISPTEXT,6), ptr->disptextLen, ptr->disptext, 0x80, &asn_buf); + if(flag & BIT6_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ACDGTS,7), ptr->acdgtsLen, ptr->acdgts, 0x80, &asn_buf); + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ABDGTS,8), ptr->abdgtsLen, ptr->abdgts, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_BILLDGTS,9), ptr->billdgtsLen, ptr->billdgts, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_REDIND,10), ptr->redindLen, ptr->redind, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,11), 4, ptr->esn, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,12), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PLIND,13), 1, &ptr->plind, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + encode_param_termlist(&ptr->termlist, ptr->termlist.param_flag, &asn_buf, &buf_len); + if(flag & BIT14_TRUE) + buf_len = is41enc_triggerlist(15, ptr->triggerlistnum, ptr->triggerlist, &asn_buf); + return buf_len; +} + +int assign_is41CallControlDirective_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_CCDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.ccdir_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CALLSTATUS,1), ptr->callstatusLen, ptr->callstatus, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41CallControlDirective_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_CCDIR_ARG *ptr; + + ptr = &opr_ptr->msg_list.ccdir_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_BILLID, 7, NULL, ptr->billid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("BillingID"); + if(decode_Is41Param(IS41PAR_MSCID, 3, NULL, ptr->mscid, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("MSCID"); + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("MSID"); + //optional + if(decode_Is41Param(IS41PAR_ACTCODE, 32, &ptr->actcodeLen, ptr->actcode, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + if(decode_Is41Param(IS41PAR_ANNLIST, 32, &ptr->annlistLen, ptr->annlist, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if(decode_Is41Param(IS41PAR_DISPTEXT, 32, &ptr->disptextLen, ptr->disptext, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if(decode_Is41Param(IS41PAR_ACDGTS, 32, &ptr->acdgtsLen, ptr->acdgts, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if(decode_Is41Param(IS41PAR_ABDGTS, 32, &ptr->abdgtsLen, ptr->abdgts, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_BILLDGTS, 32, &ptr->billdgtsLen, ptr->billdgts, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_REDIND, 32, &ptr->redindLen, ptr->redind, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_PLIND, 1, NULL, &ptr->plind, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_param_termlist(&ptr->termlist, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(is41dec_triggerlist(&ptr->triggerlistnum, ptr->triggerlist, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + return 1; +} + +int extract_is41CallControlDirective_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_CCDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.ccdir_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_CALLSTATUS, 32, &ptr->callstatusLen, ptr->callstatus, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + return 1; +} + +int assign_is41SeizeResource_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_SEIZERES_ARG *ptr; + + ptr = &opr_ptr->msg_list.seizeres_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PLIND,1), 1, &ptr->plind, 0x80, &asn_buf); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_PSR,2), ptr->psrLen, ptr->psr, 0x80, &asn_buf); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SR,3), ptr->srLen, ptr->sr, 0x80, &asn_buf); + return buf_len; +} + +int assign_is41SeizeResource_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_SEIZERES_RSP *ptr; + + ptr = &opr_ptr->msg_list.seizeres_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DESTDGTS,1), ptr->destdgtsLen, ptr->destdgts, 0x80, &asn_buf); + else + is41enc_print_absent("DestinationDigits"); + return buf_len; +} + +int extract_is41SeizeResource_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_SEIZERES_ARG *ptr; + + ptr = &opr_ptr->msg_list.seizeres_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_PLIND, 1, NULL, &ptr->plind, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if(decode_Is41Param(IS41PAR_PSR, 32, &ptr->psrLen, ptr->psr, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if(decode_Is41Param(IS41PAR_SR, 32, &ptr->srLen, ptr->sr, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + return 1; +} + +int extract_is41SeizeResource_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_SEIZERES_RSP *ptr; + + ptr = &opr_ptr->msg_list.seizeres_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_DESTDGTS, 32, &ptr->destdgtsLen, ptr->destdgts, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("DestinationDigits"); + return 1; +} + +int assign_is41ConnectResource_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_CONNRES_ARG *ptr; + + ptr = &opr_ptr->msg_list.connres_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DESTDGTS,1), ptr->destdgtsLen, ptr->destdgts, 0x80, &asn_buf); + else + is41enc_print_absent("DestinationDigits"); + //optional + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_CARDGTS,2), ptr->cardgtsLen, ptr->cardgts, 0x80, &asn_buf); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ROUTDGTS,3), ptr->routdgtsLen, ptr->routdgts, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41ConnectResource_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_CONNRES_ARG *ptr; + + ptr = &opr_ptr->msg_list.connres_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_DESTDGTS, 32, &ptr->destdgtsLen, ptr->destdgts, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("DestinationDigits"); + //optional + if(decode_Is41Param(IS41PAR_CARDGTS, 32, &ptr->cardgtsLen, ptr->cardgts, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if(decode_Is41Param(IS41PAR_ROUTDGTS, 32, &ptr->routdgtsLen, ptr->routdgts, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + return 1; +} + +int assign_is41SRFDirective_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_SRFDIR_ARG *ptr; + + ptr = &opr_ptr->msg_list.srfdir_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ANNLIST,1), ptr->annlistLen, ptr->annlist, 0x80, &asn_buf); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITCC,2), ptr->dgtccLen, ptr->dgtcc, 0x80, &asn_buf); + if(flag & BIT2_TRUE) + buf_len = is41enc_exescr(3, &ptr->exescr, &asn_buf); + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,4), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + return buf_len; +} + +int assign_is41SRFDirective_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_SRFDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.srfdir_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DIGITS,1), ptr->digitsLen, ptr->digits, 0x80, &asn_buf); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SCRRESULT,2), ptr->scrresultLen, ptr->scrresult, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41SRFDirective_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_SRFDIR_ARG *ptr; + + ptr = &opr_ptr->msg_list.srfdir_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_ANNLIST, 32, &ptr->annlistLen, ptr->annlist, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if(decode_Is41Param(IS41PAR_DIGITCC, 32, &ptr->dgtccLen, ptr->dgtcc, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if(is41dec_exescr(&ptr->exescr, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + return 1; +} + +int extract_is41SRFDirective_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_SRFDIR_RSP *ptr; + + ptr = &opr_ptr->msg_list.srfdir_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_DIGITS, 32, &ptr->digitsLen, ptr->digits, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if(decode_Is41Param(IS41PAR_SCRRESULT, 32, &ptr->scrresultLen, ptr->scrresult, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + return 1; +} + +int assign_is41ShortMessageAnalyzed_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_SM_ANLYZD_ARG *ptr; + + ptr = &opr_ptr->msg_list.smanlyzd_arg; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBRLEN,1), 2, ptr->sms_brlen, 0x80, &asn_buf); + else + is41enc_print_absent("SMS_BearerLength"); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBILLID,2), ptr->sms_billidLen, ptr->sms_billid, 0x80, &asn_buf); + else + is41enc_print_absent("SMS_BillingID"); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSEVENT,3), 1, &ptr->sms_event, 0x80, &asn_buf); + else + is41enc_print_absent("SMS_Event"); + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSTID,4), ptr->smstidLen, ptr->smstid, 0x80, &asn_buf); + else + is41enc_print_absent("SMS_TeleserviceIdentifier"); + //optional + if(flag & BIT4_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_ESN,5), 4, ptr->esn, 0x80, &asn_buf); + if(flag & BIT5_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_MDN,6), ptr->mdnLen, ptr->mdn, 0x80, &asn_buf); + if(flag & BIT6_TRUE) + buf_len = is41enc_MSID(7, &ptr->msid, &asn_buf); + if(flag & BIT7_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCID,8), ptr->smscidLen, ptr->smscid, 0x80, &asn_buf); + if(flag & BIT8_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSDA,9), ptr->smsdaLen, ptr->smsda, 0x80, &asn_buf); + if(flag & BIT9_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSPMCNT,10), 4, ptr->sms_pmcnt, 0x80, &asn_buf); + if(flag & BIT10_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODA,11), ptr->smsodaLen, ptr->smsoda, 0x80, &asn_buf); + if(flag & BIT11_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSODS,12), ptr->smsodsLen, ptr->smsods, 0x80, &asn_buf); + if(flag & BIT12_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOA,13), ptr->smsooaLen, ptr->smsooa, 0x80, &asn_buf); + if(flag & BIT13_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOOS,14), ptr->smsoosLen, ptr->smsoos, 0x80, &asn_buf); + if(flag & BIT14_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSOA,15), ptr->smsoaLen, ptr->smsoa, 0x80, &asn_buf); + if(flag & BIT15_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TDO,16), 2, ptr->tdo, 0x80, &asn_buf); + if(flag & BIT16_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_TOD,17), 3, ptr->tod, 0x80, &asn_buf); + return buf_len; +} + +int assign_is41ShortMessageAnalyzed_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + u32 flag; + IS41_SM_ANLYZD_RSP *ptr; + + ptr = &opr_ptr->msg_list.smanlyzd_rsp; + flag = ptr->param_flag; + AsnEncode(buf, 256, &asn_buf); + //optional + if(flag & BIT0_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DMH_SVCID,1), ptr->dmh_svcidLen, ptr->dmh_svcid, 0x80, &asn_buf); + if(flag & BIT1_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSBD,2), ptr->smsbdLen, ptr->smsbd, 0x80, &asn_buf); + if(flag & BIT2_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSCC,3), ptr->smscauseLen, ptr->smscause, 0x80, &asn_buf); + if(flag & BIT3_TRUE) + buf_len = AddTLV(is41_sequenceTag(IS41PAR_SMSEVENTNOT,4), ptr->sms_eventnotLen, ptr->sms_eventnot, 0x80, &asn_buf); + return buf_len; +} + +int extract_is41ShortMessageAnalyzed_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_SM_ANLYZD_ARG *ptr; + + ptr = &opr_ptr->msg_list.smanlyzd_arg; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + if(decode_Is41Param(IS41PAR_SMSBRLEN, 2, NULL, ptr->sms_brlen, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + else + is41dec_print_absent("SMS_BearerLength"); + if(decode_Is41Param(IS41PAR_SMSBILLID, 32, &ptr->sms_billidLen, ptr->sms_billid, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + else + is41dec_print_absent("SMS_BillingID"); + if(decode_Is41Param(IS41PAR_SMSEVENT, 1, NULL, &ptr->sms_event, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + else + is41dec_print_absent("SMS_Event"); + if(decode_Is41Param(IS41PAR_SMSTID, MAX_IS41_VARPAR_LEN, &ptr->smstidLen, ptr->smstid, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + else + is41dec_print_absent("SMS_TeleserviceIdentifier"); + //optional + if(decode_Is41Param(IS41PAR_ESN, 4, NULL, ptr->esn, &asn_buf)) + ptr->param_flag |= BIT4_TRUE; + if(decode_Is41Param(IS41PAR_MDN, 32, &ptr->mdnLen, ptr->mdn, &asn_buf)) + ptr->param_flag |= BIT5_TRUE; + if(is41dec_MSID(&ptr->msid, &asn_buf)) + ptr->param_flag |= BIT6_TRUE; + if(decode_Is41Param(IS41PAR_SMSCID, MAX_IS41_VARPAR_LEN , &ptr->smscidLen, ptr->smscid, &asn_buf)) + ptr->param_flag |= BIT7_TRUE; + if(decode_Is41Param(IS41PAR_SMSDA, MAX_IS41_VARPAR_LEN, &ptr->smsdaLen, ptr->smsda, &asn_buf)) + ptr->param_flag |= BIT8_TRUE; + if(decode_Is41Param(IS41PAR_SMSPMCNT, 4, NULL, ptr->sms_pmcnt, &asn_buf)) + ptr->param_flag |= BIT9_TRUE; + if(decode_Is41Param(IS41PAR_SMSODA, MAX_IS41_VARPAR_LEN, &ptr->smsodaLen, ptr->smsoda, &asn_buf)) + ptr->param_flag |= BIT10_TRUE; + if(decode_Is41Param(IS41PAR_SMSODS, MAX_IS41_VARPAR_LEN, &ptr->smsodsLen, ptr->smsods, &asn_buf)) + ptr->param_flag |= BIT11_TRUE; + if(decode_Is41Param(IS41PAR_SMSOOA, MAX_IS41_VARPAR_LEN, &ptr->smsooaLen, ptr->smsooa, &asn_buf)) + ptr->param_flag |= BIT12_TRUE; + if(decode_Is41Param(IS41PAR_SMSOOS, MAX_IS41_VARPAR_LEN, &ptr->smsoosLen, ptr->smsoos, &asn_buf)) + ptr->param_flag |= BIT13_TRUE; + if(decode_Is41Param(IS41PAR_SMSOA, MAX_IS41_VARPAR_LEN, &ptr->smsoaLen, ptr->smsoa, &asn_buf)) + ptr->param_flag |= BIT14_TRUE; + if(decode_Is41Param(IS41PAR_TDO, 2, NULL, ptr->tdo, &asn_buf)) + ptr->param_flag |= BIT15_TRUE; + if(decode_Is41Param(IS41PAR_TOD, 3, NULL, ptr->tod, &asn_buf)) + ptr->param_flag |= BIT16_TRUE; + return 1; +} + +int extract_is41ShortMessageAnalyzed_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + struct IS41_SM_ANLYZD_RSP *ptr; + + ptr = &opr_ptr->msg_list.smanlyzd_rsp; + ptr->param_flag = 0; + if(buf_len == 0) + { + is41_debug(IS41DB_ERR,"[IS41-Decode] Stopped,reason:buffer len=0!"); + return 0; + } + if(AsnDecode(buf, buf_len, 1, &decErr, &asn_buf) == -1) + return 0; + //optional + if(decode_Is41Param(IS41PAR_DMH_SVCID, 32, &ptr->dmh_svcidLen, ptr->dmh_svcid, &asn_buf)) + ptr->param_flag |= BIT0_TRUE; + if(decode_Is41Param(IS41PAR_SMSBD, 256, &ptr->smsbdLen, ptr->smsbd, &asn_buf)) + ptr->param_flag |= BIT1_TRUE; + if(decode_Is41Param(IS41PAR_SMSCC, 32, &ptr->smscauseLen, ptr->smscause, &asn_buf)) + ptr->param_flag |= BIT2_TRUE; + if(decode_Is41Param(IS41PAR_SMSEVENTNOT, 32, &ptr->sms_eventnotLen, ptr->sms_eventnot, &asn_buf)) + ptr->param_flag |= BIT3_TRUE; + return 1; +} + diff --git a/plat/xapp/src/mapp/is41_coding.c b/plat/xapp/src/mapp/is41_coding.c new file mode 100644 index 0000000..ade5caf --- /dev/null +++ b/plat/xapp/src/mapp/is41_coding.c @@ -0,0 +1,490 @@ +/* MAP Update Location c file */ +/* created by daniel zhang 2004-06-17 */ +/* last modufy by xinyu yan 2006-05-15 */ +/* ------------------------------------ */ + +#include "map_includes.h" +#include "map_code.h" + +/* external functions */ +void is41_debug(DWORD mask, const char *fmt, ...); +void is41_showbuf(DWORD mask, BYTE *buf, int len); + +static int (*is41_assign_arg[128]) (); +static int (*is41_assign_rsp[128]) (); +static int (*is41_extract_arg[128]) (); +static int (*is41_extract_rsp[128]) (); +static char is41_opr_string[128][48] = { + "", + "HandoffMeasurementRequest", + "FacilitiesDirective", + "MobileOnChannel", + "HandoffBack", + "FacilitiesRelease", + "QualificationRequest", + "QualificationDirective", + "Blocking", + "Unblocking", + "ResetCircuit", + "TrunkTest", + "TrunkTestDisconnect", + "RegistrationNotification", + "RegistrationCancellation", + "LocationRequest", + "RoutingRequest", + "FeatureRequest", + "ServiceProfileRequest", + "ServiceProfileDirective", + "UnreliableRoamerDataDirective", + "CallDataREquest", + "MSInactive", + "TransferToNumberRequest", + "RedirectionRequest", + "HandoffToThird", + "FlashRequest", + "AuthenticationDirective", + "AuthenticationRequest", + "BaseStationChallenge", + "AuthenticationFailureReport", + "CountRequest", + "InterSystemPage", + "UnsolicitedResponse", + "BulkDeregistration", + "HandoffMeasurementRequest2", + "FacilitiesDirective2", + "HandoffBack2", + "HandoffToThird2", + "AuthenticationDirectiveForward", + "AuthenticationStatusReport", + "InformationBackward", + "InformationDirective", + "InformationForward", + "InterSystemAnswer", + "InterSystemPage2", + "InterSystemSetup", + "OriginationRequest", + "RandomVariableRequest", + "RedirectionDirective", + "RemoteUserInteractionDirective", + "SMSDeliveryBackward", + "SMSDeliveryForward", + "SMSDeliveryPointToPoint", + "SMSNotification", + "SMSRequest", + "", "", "", "", "", "", "", "", + "AnalyzedInformation", + "ConnectionFailureReport", + "ConnectResource", + "DisconnectResource", + "FacilitySelectedAndAvailable", + "InstructionRequest", + "Modify", + "ResetTimer", + "Search", + "SeizeResource", + "SRFDirective", + "TBusy", + "TNoAnswer", + "", "", "", + "BulkDisconnection", + "CallControlDirective", + "OAnswer", + "ODisconnect", + "CallRecoveryReport", + "TAnswer", + "TDisconnect", + "UnreliableCallData", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "ShortMessageAnalyzed", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" +}; + +void is41_register_encode_arg(u8 opr_code, int (*func)()) +{ + is41_assign_arg[opr_code] = func; +} + +void is41_register_encode_rsp(u8 opr_code, int (*func)()) +{ + is41_assign_rsp[opr_code] = func; +} + +void is41_register_decode_arg(u8 opr_code, int (*func)()) +{ + is41_extract_arg[opr_code] = func; +} + +void is41_register_decode_rsp(u8 opr_code, int (*func)()) +{ + is41_extract_rsp[opr_code] = func; +} + +void init_assignFunc_pointer() +{ + is41_register_encode_arg(IS41OPR_AuthenticationDirective, assign_is41AuthenticationDirective_arg); + is41_register_encode_rsp(IS41OPR_AuthenticationDirective, assign_is41AuthenticationDirective_rsp); + + is41_register_encode_arg(IS41OPR_AuthenticationFailureReport, assign_is41AuthenticationFailureReport_arg); + is41_register_encode_rsp(IS41OPR_AuthenticationFailureReport, assign_is41AuthenticationFailureReport_rsp); + + is41_register_encode_arg(IS41OPR_AuthenticationRequest, assign_is41AuthenticationRequest_arg); + is41_register_encode_rsp(IS41OPR_AuthenticationRequest, assign_is41AuthenticationRequest_rsp); + + is41_register_encode_arg(IS41OPR_AuthenticationStatusReport, assign_is41AuthenticationStatusReport_arg); + is41_register_encode_rsp(IS41OPR_AuthenticationStatusReport, assign_is41AuthenticationStatusReport_rsp); + + is41_register_encode_arg(IS41OPR_AuthenticationDirectiveForward, assign_is41AuthenticationDirectiveForward_arg); + + is41_register_encode_arg(IS41OPR_BaseStationChallenge, assign_is41BaseStationChallenge_arg); + is41_register_encode_rsp(IS41OPR_BaseStationChallenge, assign_is41BaseStationChallenge_rsp); + + is41_register_encode_arg(IS41OPR_CountRequest, assign_is41CountRequest_arg); + is41_register_encode_rsp(IS41OPR_CountRequest, assign_is41CountRequest_rsp); + + is41_register_encode_arg(IS41OPR_SMSDeliveryBackward, assign_Is41SmsDeliveryBackward_arg); + is41_register_encode_rsp(IS41OPR_SMSDeliveryBackward, assign_Is41SmsDeliveryBackward_rsp); + + is41_register_encode_arg(IS41OPR_SMSDeliveryForward, assign_Is41SmsDeliveryForward_arg); + is41_register_encode_rsp(IS41OPR_SMSDeliveryForward, assign_Is41SmsDeliveryForward_rsp); + + is41_register_encode_arg(IS41OPR_SMSDeliveryPointToPoint, assign_Is41SmsDeliveryPointToPoint_arg); + is41_register_encode_rsp(IS41OPR_SMSDeliveryPointToPoint, assign_Is41SmsDeliveryPointToPoint_rsp); + + is41_register_encode_arg(IS41OPR_SMSNotification, assign_Is41SmsNotification_arg); + is41_register_encode_rsp(IS41OPR_SMSNotification, assign_Is41SmsNotification_rsp); + + is41_register_encode_arg(IS41OPR_SMSRequest, assign_Is41SmsRequest_arg); + is41_register_encode_rsp(IS41OPR_SMSRequest, assign_Is41SmsRequest_rsp); + + is41_register_encode_arg(IS41OPR_RegistrationNotification, assign_is41RegistrationNotification_arg); + is41_register_encode_rsp(IS41OPR_RegistrationNotification, assign_is41RegistrationNotification_rsp); + is41_register_encode_arg(IS41OPR_RegistrationCancellation, assign_is41RegistrationCancellation_arg); + is41_register_encode_rsp(IS41OPR_RegistrationCancellation, assign_is41RegistrationCancellation_rsp); + is41_register_encode_arg(IS41OPR_LocationRequest, assign_is41LocationRequest_arg); + is41_register_encode_rsp(IS41OPR_LocationRequest, assign_is41LocationRequest_rsp); + is41_register_encode_arg(IS41OPR_RoutingRequest, assign_is41RoutingRequest_arg); + is41_register_encode_rsp(IS41OPR_RoutingRequest, assign_is41RoutingRequest_rsp); + is41_register_encode_arg(IS41OPR_MSInactive, assign_is41MSInactive_arg); + is41_register_encode_rsp(IS41OPR_MSInactive, assign_is41MSInactive_rsp); + + is41_register_encode_arg(IS41OPR_FeatureRequest, assign_is41FeatureRequest_arg); + is41_register_encode_rsp(IS41OPR_FeatureRequest, assign_is41FeatureRequest_rsp); + + is41_register_encode_arg(IS41OPR_QualificationDirective, assign_is41QualificationDirective_arg); + is41_register_encode_rsp(IS41OPR_QualificationDirective, assign_is41QualificationDirective_rsp); + + is41_register_encode_arg(IS41OPR_TransferToNumberRequest, assign_is41TransferToNumberRequest_arg); + is41_register_encode_rsp(IS41OPR_TransferToNumberRequest, assign_is41TransferToNumberRequest_rsp); + + is41_register_encode_arg(IS41OPR_RedirectionRequest, assign_is41RedirectionRequest_arg); + is41_register_encode_rsp(IS41OPR_RedirectionRequest, assign_is41RedirectionRequest_rsp); + + is41_register_encode_arg(IS41OPR_OriginationRequest, assign_is41OriginationRequest_arg); + is41_register_encode_rsp(IS41OPR_OriginationRequest, assign_is41OriginationRequest_rsp); + + is41_register_encode_arg(IS41OPR_AnalyzedInformation, assign_is41AnalyzedInformation_arg); + is41_register_encode_rsp(IS41OPR_AnalyzedInformation, assign_is41AnalyzedInformation_rsp); + + is41_register_encode_arg(IS41OPR_OAnswer, assign_is41OAnswer_arg); + + is41_register_encode_arg(IS41OPR_ODisconnect, assign_is41ODisconnect_arg); + is41_register_encode_rsp(IS41OPR_ODisconnect, assign_is41ODisconnect_rsp); + + is41_register_encode_arg(IS41OPR_TAnswer, assign_is41TAnswer_arg); + + is41_register_encode_arg(IS41OPR_TDisconnect, assign_is41TDisconnect_arg); + is41_register_encode_rsp(IS41OPR_TDisconnect, assign_is41TDisconnect_rsp); + + is41_register_encode_arg(IS41OPR_CallControlDirective, assign_is41CallControlDirective_arg); + is41_register_encode_rsp(IS41OPR_CallControlDirective, assign_is41CallControlDirective_rsp); + + is41_register_encode_arg(IS41OPR_SeizeResource, assign_is41SeizeResource_arg); + is41_register_encode_rsp(IS41OPR_SeizeResource, assign_is41SeizeResource_rsp); + + is41_register_encode_arg(IS41OPR_ConnectResource, assign_is41ConnectResource_arg); + + is41_register_encode_arg(IS41OPR_SRFDirective, assign_is41SRFDirective_arg); + is41_register_encode_rsp(IS41OPR_SRFDirective, assign_is41SRFDirective_rsp); + + is41_register_encode_arg(IS41OPR_ShortMessageAnalyzed, assign_is41ShortMessageAnalyzed_arg); + is41_register_encode_rsp(IS41OPR_ShortMessageAnalyzed, assign_is41ShortMessageAnalyzed_rsp); +} + +void init_extractFunc_pointer() +{ + is41_register_decode_arg(IS41OPR_AuthenticationDirective, extract_is41AuthenticationDirective_arg); + is41_register_decode_rsp(IS41OPR_AuthenticationDirective, extract_is41AuthenticationDirective_rsp); + + is41_register_decode_arg(IS41OPR_AuthenticationFailureReport, extract_is41AuthenticationFailureReport_arg); + is41_register_decode_rsp(IS41OPR_AuthenticationFailureReport, extract_is41AuthenticationFailureReport_rsp); + + is41_register_decode_arg(IS41OPR_AuthenticationRequest, extract_is41AuthenticationRequest_arg); + is41_register_decode_rsp(IS41OPR_AuthenticationRequest, extract_is41AuthenticationRequest_rsp); + + is41_register_decode_arg(IS41OPR_AuthenticationStatusReport, extract_is41AuthenticationStatusReport_arg); + is41_register_decode_rsp(IS41OPR_AuthenticationStatusReport, extract_is41AuthenticationStatusReport_rsp); + + is41_register_decode_arg(IS41OPR_AuthenticationDirectiveForward, extract_is41AuthenticationDirectiveForward_arg); + + is41_register_decode_arg(IS41OPR_BaseStationChallenge, extract_is41BaseStationChallenge_arg); + is41_register_decode_rsp(IS41OPR_BaseStationChallenge, extract_is41BaseStationChallenge_rsp); + + is41_register_decode_arg(IS41OPR_CountRequest, extract_is41CountRequest_arg); + is41_register_decode_rsp(IS41OPR_CountRequest, extract_is41CountRequest_rsp); + + is41_register_decode_arg(IS41OPR_SMSDeliveryBackward, extract_Is41SmsDeliveryBackward_arg); + is41_register_decode_rsp(IS41OPR_SMSDeliveryBackward, extract_Is41SmsDeliveryBackward_rsp); + + is41_register_decode_arg(IS41OPR_SMSDeliveryForward, extract_Is41SmsDeliveryForward_arg); + is41_register_decode_rsp(IS41OPR_SMSDeliveryForward, extract_Is41SmsDeliveryForward_rsp); + + is41_register_decode_arg(IS41OPR_SMSDeliveryPointToPoint, extract_Is41SmsDeliveryPointToPoint_arg); + is41_register_decode_rsp(IS41OPR_SMSDeliveryPointToPoint, extract_Is41SmsDeliveryPointToPoint_rsp); + + is41_register_decode_arg(IS41OPR_SMSNotification, extract_Is41SmsNotification_arg); + is41_register_decode_rsp(IS41OPR_SMSNotification, extract_Is41SmsNotification_rsp); + + is41_register_decode_arg(IS41OPR_SMSRequest, extract_Is41SmsRequest_arg); + is41_register_decode_rsp(IS41OPR_SMSRequest, extract_Is41SmsRequest_rsp); + + is41_register_decode_arg(IS41OPR_RegistrationNotification, extract_is41RegistrationNotification_arg); + is41_register_decode_rsp(IS41OPR_RegistrationNotification, extract_is41RegistrationNotification_rsp); + is41_register_decode_arg(IS41OPR_RegistrationCancellation, extract_is41RegistrationCancellation_arg); + is41_register_decode_rsp(IS41OPR_RegistrationCancellation, extract_is41RegistrationCancellation_rsp); + is41_register_decode_arg(IS41OPR_LocationRequest, extract_is41LocationRequest_arg); + is41_register_decode_rsp(IS41OPR_LocationRequest, extract_is41LocationRequest_rsp); + is41_register_decode_arg(IS41OPR_RoutingRequest, extract_is41RoutingRequest_arg); + is41_register_decode_rsp(IS41OPR_RoutingRequest, extract_is41RoutingRequest_rsp); + is41_register_decode_arg(IS41OPR_MSInactive, extract_is41MSInactive_arg); + is41_register_decode_rsp(IS41OPR_MSInactive, extract_is41MSInactive_rsp); + + is41_register_decode_arg(IS41OPR_FeatureRequest, extract_is41FeatureRequest_arg); + is41_register_decode_rsp(IS41OPR_FeatureRequest, extract_is41FeatureRequest_rsp); + + is41_register_decode_arg(IS41OPR_QualificationDirective, extract_is41QualificationDirective_arg); + is41_register_decode_rsp(IS41OPR_QualificationDirective, extract_is41QualificationDirective_rsp); + + is41_register_decode_arg(IS41OPR_TransferToNumberRequest, extract_is41TransferToNumberRequest_arg); + is41_register_decode_rsp(IS41OPR_TransferToNumberRequest, extract_is41TransferToNumberRequest_rsp); + + is41_register_decode_arg(IS41OPR_RedirectionRequest, extract_is41RedirectionRequest_arg); + is41_register_decode_rsp(IS41OPR_RedirectionRequest, extract_is41RedirectionRequest_rsp); + + is41_register_decode_arg(IS41OPR_OriginationRequest, extract_is41OriginationRequest_arg); + is41_register_decode_rsp(IS41OPR_OriginationRequest, extract_is41OriginationRequest_rsp); + + is41_register_decode_arg(IS41OPR_AnalyzedInformation, extract_is41AnalyzedInformation_arg); + is41_register_decode_rsp(IS41OPR_AnalyzedInformation, extract_is41AnalyzedInformation_rsp); + + is41_register_decode_arg(IS41OPR_OAnswer, extract_is41OAnswer_arg); + + is41_register_decode_arg(IS41OPR_ODisconnect, extract_is41ODisconnect_arg); + is41_register_decode_rsp(IS41OPR_ODisconnect, extract_is41ODisconnect_rsp); + + is41_register_decode_arg(IS41OPR_TAnswer, extract_is41TAnswer_arg); + + is41_register_decode_arg(IS41OPR_TDisconnect, extract_is41TDisconnect_arg); + is41_register_decode_rsp(IS41OPR_TDisconnect, extract_is41TDisconnect_rsp); + + is41_register_decode_arg(IS41OPR_CallControlDirective, extract_is41CallControlDirective_arg); + is41_register_decode_rsp(IS41OPR_CallControlDirective, extract_is41CallControlDirective_rsp); + + is41_register_decode_arg(IS41OPR_SeizeResource, extract_is41SeizeResource_arg); + is41_register_decode_rsp(IS41OPR_SeizeResource, extract_is41SeizeResource_rsp); + + is41_register_decode_arg(IS41OPR_ConnectResource, extract_is41ConnectResource_arg); + + is41_register_decode_arg(IS41OPR_SRFDirective, extract_is41SRFDirective_arg); + is41_register_decode_rsp(IS41OPR_SRFDirective, extract_is41SRFDirective_rsp); + + is41_register_decode_arg(IS41OPR_ShortMessageAnalyzed, extract_is41ShortMessageAnalyzed_arg); + is41_register_decode_rsp(IS41OPR_ShortMessageAnalyzed, extract_is41ShortMessageAnalyzed_rsp); +} + +int is41_u8Type_to_charType(u8 type,char *cType) +{ + if(type >= 128) + return 0; + else if(strlen(is41_opr_string[type]) == 0) + return 0; + strcpy(cType, is41_opr_string[type]); + return 1; +} + +/*int is41_u8Type_to_charType(u8 type,char *cType) +{ + switch (type) + { + // Authentication service operation + case IS41OPR_AuthenticationDirective: + sprintf(cType,"AuthenticationDirective"); + break; + case IS41OPR_AuthenticationFailureReport: + sprintf(cType,"AuthenticationFailureReport"); + break; + case IS41OPR_AuthenticationRequest: + sprintf(cType,"AuthenticationRequest"); + break; + case IS41OPR_AuthenticationStatusReport: + sprintf(cType,"AuthenticationStatusReport"); + break; + case IS41OPR_AuthenticationDirectiveForward: + sprintf(cType,"AuthenticationDirectiveForward"); + break; + case IS41OPR_CountRequest: + sprintf(cType,"CountRequest"); + break; + case IS41OPR_BaseStationChallenge: + sprintf(cType,"BaseStationChallenge"); + break; + case IS41OPR_SMSDeliveryBackward: + sprintf(cType,"SMSDeliveryBackward"); + break; + case IS41OPR_SMSDeliveryForward: + sprintf(cType,"SMSDeliveryForward"); + break; + case IS41OPR_SMSDeliveryPointToPoint: + sprintf(cType,"SMSDeliveryPointToPoint"); + break; + case IS41OPR_SMSNotification: + sprintf(cType,"IS41OPR_SMSNotification"); + break; + case IS41OPR_SMSRequest: + sprintf(cType,"SMSRequest"); + break; + + case IS41OPR_RegistrationNotification: + sprintf(cType,"REGNOT"); + break; + case IS41OPR_RegistrationCancellation: + sprintf(cType,"REGCANC"); + break; + case IS41OPR_LocationRequest: + sprintf(cType,"LOCREQ"); + break; + case IS41OPR_RoutingRequest: + sprintf(cType,"ROUTREQ"); + break; + case IS41OPR_MSInactive: + sprintf(cType,"MSINACT"); + break; + case IS41OPR_FeatureRequest: + sprintf(cType,"FEATREQ"); + break; + case IS41OPR_QualificationDirective: + sprintf(cType,"QUALDIR"); + break; + case IS41OPR_TransferToNumberRequest: + sprintf(cType,"TRANUMREQ"); + break; + case IS41OPR_RedirectionRequest: + sprintf(cType,"REDREQ"); + break; + + default: // unknown operation +// sprintf(info_str,"MAPP error:the operation is unknown:%d",opr_ptr->message_type); +// xap_send_error(info_str); + return 0; + } + return 1; +}*/ + +int build_is41param(struct MapOprSrv_struct *opr_ptr,u8 *buf) // build is41 service paramter +{ + ASN_BUF asn_buf; + u8 seq_flag=1; + int param_len = 0; + u8 info_str[1024]; + char charName[128]; + + if (opr_ptr == NULL || buf == NULL) + return 0; + if (!is41_u8Type_to_charType(opr_ptr->message_type,charName)) + { + is41_debug(IS41DB_ENCODE,"[IS41-Encode]Building param,Operation code:%d not correct",opr_ptr->message_type); + return 0; + } + + if (opr_ptr->message_flag == MAP_REQUEST) + { + is41_debug(IS41DB_ENCODE,"[IS41-Encode] MAP_REQUEST,OPRType=%s",charName); + param_len = (*is41_assign_arg[opr_ptr->message_type]) (opr_ptr,buf); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + is41_debug(IS41DB_ENCODE,"[IS41-Encode] MAP_RESPONSE,OPRType=%s",charName); + param_len = (*is41_assign_rsp[opr_ptr->message_type])(opr_ptr,buf); + } + else + return 0; + + if (seq_flag == 1 && param_len > 0) + { + memcpy(info_str,buf,param_len%1024); + AsnEncode(buf,256,&asn_buf); + param_len = AddTLV(SET_NATIONAL,param_len,info_str,0xe0,&asn_buf); + is41_debug(IS41DB_ENCODE,"[IS41-Encode] Completed,len=%d",param_len); + is41_showbuf(IS41DB_ENCODE,buf,param_len); + } + else + { + AsnEncode(buf,256,&asn_buf); + param_len = AddTLV(SET_NATIONAL,0,info_str,0xc0,&asn_buf); + is41_debug(IS41DB_ENCODE,"[IS41-Encode] Completed,paramlen=0"); + is41_showbuf(IS41DB_ENCODE,buf,param_len); + } + return param_len; +} + +u8 extract_is41param(struct MapOprSrv_struct *opr_ptr,u8 opr_code,u8 opr_flag,u32 pre_param_len,u8 *pre_param) +{ + ASN_BUF asn_buf; +// u8 info_str[1024]; + u8 param[1024]; + int param_len; + char charName[128]; + + asn_decode(pre_param,1,&asn_buf); + param_len = get_tlv(SET_NATIONAL,param,&asn_buf); + + if (param_len == -1) // not has sequence id + { + param_len = pre_param_len; + memcpy(param,pre_param,param_len); + } + + if (!is41_u8Type_to_charType(opr_code,charName)) + { + is41_debug(IS41DB_ENCODE,"[IS41-Encode]Extracting param,Operation code:%d not correct",opr_code); + return 0; + } + + if (opr_flag == MAP_INDICATE) + { + is41_debug(IS41DB_DECODE,"[IS41-Decode]USER->IS41P,IS41_INDICATE,OPRType=%s",charName); + is41_showbuf(IS41DB_DECODE,param,param_len); + if (*is41_extract_arg[opr_code] != NULL) + { + return (*is41_extract_arg[opr_code])(opr_ptr,param_len,param); + } + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode]No decode function for IS41_INDICATE opr_code=%d",opr_code); + return 0; + } + } + else if (opr_flag == MAP_CONFIRM) + { + is41_debug(IS41DB_DECODE,"[IS41-Decode]USER->IS41P,MAP_CONFIRM,OPRType=%s",charName); + is41_showbuf(IS41DB_DECODE,param,param_len); + if (*is41_extract_rsp[opr_code] != NULL) + return (*is41_extract_rsp[opr_code])(opr_ptr,param_len,param); + else + { + is41_debug(IS41DB_ERR,"[IS41-Decode]No decode function for IS41_CONFIRM opr_code=%d",opr_code); + return 0; + } + } + + return 1; +} diff --git a/plat/xapp/src/mapp/is41_debug.c b/plat/xapp/src/mapp/is41_debug.c new file mode 100644 index 0000000..b604741 --- /dev/null +++ b/plat/xapp/src/mapp/is41_debug.c @@ -0,0 +1,3650 @@ +/* IS41 debug function c file */ +/* created by daniel zhang 2004-06-18 */ +/* last modufy by daniel zhang 2004-06-18 */ +/* version 1.0 */ +/* ------------------------------------ */ + +#include "../../../debug/src/include/debug.h" +#include "map_includes.h" +#include "is41_code.h" + +static char debug_buf[5120]; +BYTE is41DebugFull = 0; +static unsigned long debug_mask = 0; + +static char help_info[] = "Commands provided now:\r\n\ +help\r\n\ +log all Output all debug information\r\n\ +log none Turn off all information\r\n\ +log error on/off Show error information\r\n\ +"; + + +void is41_debug_setup() +{ +#if MAP_CODE_DEBUG + DWORD ascout_id[20] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,17,4}; + DWORD ascin_id[20] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,17,3}; + DWORD status_id[20] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,17,1}; + DWORD name_id[20] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,17,2}; + BYTE debug_status = 1; + + sprintf(is41_ver, "R9V00_T1"); + debug_set_response(15, ascout_id, debug_buf, 1); + debug_set_response(15, ascin_id, asc_in, 1); + debug_set_response(15, status_id, &debug_status, 1); + debug_set_response(15, name_id, is41_ver, strlen(is41_ver)); + +#endif +} + +void is41_log(char *info) +{ + if(strlen(debug_buf) + strlen(info) > 2048) + { + is41DebugFull = 1; + return; + } +// printf("send log\n"); + strncat(debug_buf, info, 2048); + strcat(debug_buf, "\r\n"); + return; +} + +void is41_debug(DWORD mask, const char *fmt, ...) +{ +#if MAP_CODE_DEBUG + va_list ap; + char buf[1024]; + + if((mask & debug_mask) == 0) + return; + +/* if(debug_mask & SCCPDB_TIME) + { + struct timeval tv; + struct timezone tz; + struct tm *t; + char timestr[32]; + gettimeofday(&tv, &tz); + t=localtime(&tv.tv_sec); + sprintf(timestr, "(%d:%d:%d.%ld):",t->tm_hour,t->tm_min,t->tm_sec,tv.tv_usec); + is41_log(timestr); + }*/ + + if(mask & IS41DB_ERR) + strcat(debug_buf, "\33[31m"); + + va_start(ap, fmt); + vsnprintf(buf, 1024, fmt, ap); + va_end(ap); + strcat(buf,"\33[37m"); + is41_log(buf); +#endif +} + +void is41_showbuf(DWORD mask, BYTE *buf, int len) +{ +#if MAP_CODE_DEBUG + int i = 0, j = 0, linemax = 24; + char info[1024]; + +/* if((debug_mask & SCCPDB_MSG) == 0 || (debug_mask & mask) == 0 || sccpDebugFull) + return;*/ + + if(len >= 256) + len = 256; + + while(i * 24 < len) + { + if((linemax = len - 24 * i) > 24) + linemax = 24; + for(j = 0; j < linemax; j ++) + { + sprintf(info + 3 * j, "%02X ", buf[24 * i + j]); + } + is41_log(info); + i ++; + } +#endif +} + + +int parsecmd(char *cmdstr) +{ + if(strstr(cmdstr,"help") != NULL || strstr(cmdstr,"?")!=NULL) + is41_log(help_info); + else if(strstr(cmdstr, "log all") != NULL) + { +// sccpFilterIndex = 0; + debug_mask = 0xFFFFFFFF; + } + else if(strstr(cmdstr, "log none") != NULL) + { +// sccpFilterIndex = 0; + debug_mask = 0; + } + else if(strstr(cmdstr, "log error on") != NULL) + debug_mask |= IS41DB_ERR; + else if(strstr(cmdstr, "log error off") != NULL) + debug_mask &= (~IS41DB_ERR); + else if(strstr(cmdstr, "Test Auc") != NULL) + { + printf("CMD OK\n"); + } + is41_log("Command OK."); + return 1; +} + + +void is41_debug_timer() +{ +#if MAP_CODE_DEBUG + BYTE npage, nline; + + if(strlen(asc_in) <= 1) + return; + debug_buf[0] = '\0'; + npage = asc_in[0] - 1; + if(npage == 0) + { + parsecmd(asc_in + 1); + asc_in[0] = '\0'; + return; + } + else + nline = atoi(asc_in + 1); + switch(npage) + { + case 1: //csta +// sccp_debug_csta(npage, nline); + break; + case 2: //local subsystem +// sccp_debug_local(npage, nline); + break; + case 3: //related subsystem +// sccp_debug_related(npage, nline); + break; + } + asc_in[0] = '\0'; +#endif +} + + +int debug_show_REGNOT_ARG(IS41_REGNOT_ARG *ptr,char *buf) +{ + u32 flag,flag1; + struct IS41_PAR_WIN_CAP *ptr1; + int i; + char tempchar[512]; + + flag = ptr->param_flag; + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //esn + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + + if((flag & BIT1_TRUE)>0) //min + { + sprintf(tempchar,"MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + + if((flag & BIT3_TRUE)>0) //QualificationInformationCode + { + sprintf(tempchar,"QUALCODE=%02x,",ptr->qualcode); + strcat(buf,tempchar); + } + + if((flag & BIT4_TRUE)>0) //SystemMyTypeCode + { + sprintf(tempchar,"MYTYP=%02x,",ptr->mytyp); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT5_TRUE)>0) //Availability Type + { + sprintf(tempchar,"AVTYP=%02x,",ptr->avtyp); + strcat(buf,tempchar); + } + + if((flag & BIT6_TRUE)>0) //BorderCellAccess + { + sprintf(tempchar,"BORDACC=%02x,",ptr->bordacc); + strcat(buf,tempchar); + } + + if((flag & BIT7_TRUE)>0) //ControlChannelData + { + sprintf(tempchar,"CCDATA=%02x%02x%02x%02x,",ptr->ccdata[0],ptr->ccdata[1],ptr->ccdata[2],ptr->ccdata[3]); + strcat(buf,tempchar); + } + + if((flag & BIT8_TRUE)>0) //ExtendedMSCID + { + sprintf(tempchar,"EXTMSCID=%02x%02x%02x%02x,",ptr->extmscid[0],ptr->extmscid[1],ptr->extmscid[2],ptr->extmscid[3]); + strcat(buf,tempchar); + } + + if((flag & BIT9_TRUE)>0) //LocationAreaID + { + sprintf(tempchar,"LOCID=%02x%02x,",ptr->locid[0],ptr->locid[1]); + strcat(buf,tempchar); + } + + if((flag & BIT10_TRUE)>0) //pcssn + { + sprintf(tempchar,"PCSSN=%02x%02x%02x%02x%02x,",ptr->pcssn[0],ptr->pcssn[1],ptr->pcssn[2],ptr->pcssn[3],ptr->pcssn[4]); + strcat(buf,tempchar); + } + + if((flag & BIT11_TRUE)>0) //ReceivedSignalQuality + { + sprintf(tempchar,"RSIGQUAL=%02x,",ptr->rsigqual); + strcat(buf,tempchar); + } + + if((flag & BIT12_TRUE)>0) //rpttyp + { + sprintf(tempchar,"RPTTYP=%02x,",ptr->rpttyp); + strcat(buf,tempchar); + } + + if((flag & BIT13_TRUE)>0) //senderin + { + strcat(buf,"SENDERIN="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",ptr->senderin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT14_TRUE)>0) //SMS_DestinationAddress + { + strcat(buf,"SMSADDR="); + for (i=0;ismsaddrLen;i++) + { + sprintf(tempchar,"%02x",ptr->smsaddr[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT15_TRUE)>0) //smsmwi + strcat(buf,"SMSMWI,"); + + if((flag & BIT16_TRUE)>0) //sysaccdata + { + sprintf(tempchar,"SYSACCDATA=%02x%02x%02x%02x%02x,",ptr->sysaccdata[0],ptr->sysaccdata[1],ptr->sysaccdata[2],ptr->sysaccdata[3],ptr->sysaccdata[4]); + strcat(buf,tempchar); + } + + if((flag & BIT17_TRUE)>0) //sysacctype + { + sprintf(tempchar,"SYSACCTYPE=%02x,",ptr->sysacctype); + strcat(buf,tempchar); + } + + if((flag & BIT18_TRUE)>0) //syscap + { + sprintf(tempchar,"SYSCAP=%02x,",ptr->syscap); + strcat(buf,tempchar); + } + + if((flag & BIT19_TRUE)>0) //termtyp + { + sprintf(tempchar,"TERMTYP=%02x,",ptr->termtyp); + strcat(buf,tempchar); + } + + if((flag & BIT20_TRUE)>0) //transcap + { + strcat(buf,"TRANSCAP="); + for (i=0;itranscapLen;i++) + { + sprintf(tempchar,"%02x",ptr->transcap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT21_TRUE)>0) //wincap + { + ptr1 = &ptr->wincap; + flag1 = ptr1->param_flag; + if((flag1 & BIT0_TRUE)>0) //triggercapability + { + strcat(buf,"WINCAP-TRIGGERCAP="); + for (i=0;itriggercapLen;i++) + { + sprintf(tempchar,"%02x",ptr1->triggercap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + strcat(buf,"WINCAP-WINOPRCAP="); + for (i=0;iwinoprcapLen;i++) + { + sprintf(tempchar,"%02x",ptr1->winoprcap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + } + if (flag > 0) + return 1; + return 0; +} + +int debug_show_profile(struct IS41_PAR_PROFILE *ptr,u8 *buf) +{ + u32 flag1; + struct IS41_PAR_TRIGGER_LIST *ptr1; + u32 flag; + u8 i,triglistnum; + char tempchar[512]; + + flag = ptr->param_flag; + + if((flag & BIT0_TRUE)>0) + { + strcat((char *)buf,"AUTHCAP="); + for (i=0;iauthcapLen;i++) + { + sprintf(tempchar,"%02x",ptr->authcap[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT1_TRUE)>0) + { + strcat((char *)buf,"CFI="); + for (i=0;icfiLen;i++) + { + sprintf(tempchar,"%02x",ptr->cfi[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT2_TRUE)>0) + { + strcat((char *)buf,"CARDGTS="); + for (i=0;icardgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->cardgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT3_TRUE)>0) + { + strcat((char *)buf,"ACDGTS="); + for (i=0;iacdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->acdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT4_TRUE)>0) + { + strcat((char *)buf,"ABDGTS="); + for (i=0;iabdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->abdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT5_TRUE)>0) + { + strcat((char *)buf,"BILLDGTS="); + for (i=0;ibilldgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->billdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT6_TRUE)>0) + { + strcat((char *)buf,"GEOAUTH="); + for (i=0;igeoauthLen;i++) + { + sprintf(tempchar,"%02x",ptr->geoauth[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT7_TRUE)>0) + { + strcat((char *)buf,"MWNCOUNT="); + for (i=0;imwncountLen;i++) + { + sprintf(tempchar,"%02x",ptr->mwncount[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT8_TRUE)>0) + { + strcat((char *)buf,"MWNTYPE="); + for (i=0;imwntypeLen;i++) + { + sprintf(tempchar,"%02x",ptr->mwntype[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT9_TRUE)>0) + { + strcat((char *)buf,"MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT10_TRUE)>0) + { + sprintf(tempchar,"ORIGIND=%02x,",ptr->origind); + strcat((char *)buf,tempchar); + } + if((flag & BIT11_TRUE)>0) + { + strcat((char *)buf,"ORIGTRIG="); + for (i=0;iorigtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->origtrig[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT12_TRUE)>0) + { + sprintf(tempchar,"PACAIND=%02x,",ptr->pacaind); + strcat((char *)buf,tempchar); + } + if((flag & BIT13_TRUE)>0) + { + sprintf(tempchar,"PLIND=%02x,",ptr->plind); + strcat((char *)buf,tempchar); + } + if((flag & BIT14_TRUE)>0) + { + strcat((char *)buf,"RESDGTS="); + for (i=0;iresdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->resdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT15_TRUE)>0) + { + strcat((char *)buf,"ROUTDGTS="); + for (i=0;iroutdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->routdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT16_TRUE)>0) + { + sprintf(tempchar,"SMSORGRES=%02x,",ptr->smsorgres); + strcat((char *)buf,tempchar); + } + if((flag & BIT17_TRUE)>0) + { + sprintf(tempchar,"SMSTERMRES=%02x,",ptr->smstermres); + strcat((char *)buf,tempchar); + } + if((flag & BIT18_TRUE)>0) + { + strcat((char *)buf,"SPINIPIN="); + for (i=0;ispinipinLen;i++) + { + sprintf(tempchar,"%02x",ptr->spinipin[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT19_TRUE)>0) + { + strcat((char *)buf,"SPINITRIG="); + for (i=0;ispinitrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->spinitrig[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT20_TRUE)>0) + { + sprintf(tempchar,"SMSTERMRES=%02x,",ptr->termres); + strcat((char *)buf,tempchar); + } + if((flag & BIT21_TRUE)>0) + { + strcat((char *)buf,"TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + + if((flag & BIT22_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + strcat((char *)buf,"TRIGADRLIST-TRIGLIST-DESTADDR="); + for (i=0;idestaddrLen;i++) + { + sprintf(tempchar,"%02x",ptr1->destaddr[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + strcat((char *)buf,"TRIGADRLIST-TRIGLIST-WINTRIGLIST="); + for (i=0;iwintriglistLen;i++) + { + sprintf(tempchar,"%02x",ptr1->wintriglist[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + } + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_REGNOT_RSP(struct IS41_REGNOT_RSP *ptr,char *buf) +{ + u32 flag; + int i; + char tempchar[512]; + + buf[0] = 0; + + flag = ptr->param_flag; + + if((flag & BIT0_TRUE)>0) //SystemMyTypeCode + { + sprintf(tempchar,"MYTYP=%02x,",ptr->mytyp); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT1_TRUE)>0) //AuthorizationDenied + { + sprintf(tempchar,"AUTHDEN=%02x,",ptr->authden); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) //AuthorizationPeriod + { + sprintf(tempchar,"AUTHPER=%02x%02x,",ptr->authper[0],ptr->authper[1]); + strcat(buf,tempchar); + } + + if((flag & BIT3_TRUE)>0) //ControlChannelData + { + sprintf(tempchar,"CCDATA=%02x%02x%02x%02x,",ptr->ccdata[0],ptr->ccdata[1],ptr->ccdata[2],ptr->ccdata[3]); + strcat(buf,tempchar); + } + + if((flag & BIT4_TRUE)>0) //DeniedAuthorizationPeriod + { + strcat(buf,"DENAUTHPER="); + for (i=0;idenauthperLen;i++) + { + sprintf(tempchar,"%02x",ptr->denauthper[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT5_TRUE)>0) //Digits carrier + { + strcat(buf,"DIGITS CARRIER="); + for (i=0;idigitsCarrierLen;i++) + { + sprintf(tempchar,"%02x",ptr->digitsCarrier[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT6_TRUE)>0) //Digits Destination + { + strcat(buf,"DIGITS DEST="); + for (i=0;idigitsDestLen;i++) + { + sprintf(tempchar,"%02x",ptr->digitsDest[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT7_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + +/* Profile **macro** */ + if ((flag & BIT8_TRUE) > 0) + { + debug_show_profile(&ptr->profile, (u8 *)buf); + } +/* Profile **macro** */ + +/* if((flag & BIT9_TRUE)>0) //ReceivedSignalQuality + { + sprintf(tempchar,"RSIGQUAL=%02x,",ptr->rsigqual); + strcat(buf,tempchar); + }*/ + + if((flag & BIT10_TRUE)>0) //senderin + { + strcat(buf,"SENDERIN="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",ptr->senderin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT11_TRUE)>0) + strcat(buf,"SMSMWI"); + + + if((flag & BIT12_TRUE)>0) //sysaccdata + { + sprintf(tempchar,"SYSACCDATA=%02x%02x%02x%02x%02x,",ptr->sysaccdata[0],ptr->sysaccdata[1],ptr->sysaccdata[2],ptr->sysaccdata[3],ptr->sysaccdata[4]); + strcat(buf,tempchar); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_LOCREQ_ARG(struct IS41_LOCREQ_ARG *ptr,char *buf) +{ + int i; + u32 flag,flag1; + struct IS41_PAR_WIN_CAP *ptr1; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) + { + strcat(buf,"BILLID="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",ptr->billid[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT1_TRUE)>0) + { + strcat(buf,"DIGITS="); + for (i=0;idigitsLen;i++) + { + sprintf(tempchar,"%02x",ptr->digits[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT2_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + + if((flag & BIT3_TRUE)>0) //SystemMyTypeCode + { + sprintf(tempchar,"MYTYP=%02x,",ptr->mytyp); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT4_TRUE)>0) + { + strcat(buf,"CPNDGTS1="); + for (i=0;icpndgts1Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpndgts1[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"CPNDGTS2="); + for (i=0;icpndgts2Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpndgts2[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT6_TRUE)>0) + { + strcat(buf,"CPSUB="); + for (i=0;icpsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->cpsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT7_TRUE)>0) + { + strcat(buf,"MSCIN="); + for (i=0;imscinLen;i++) + { + sprintf(tempchar,"%02x",ptr->mscin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT8_TRUE)>0) + { + sprintf(tempchar,"PCSSN=%02x%02x%02x%02x%02x,",ptr->pcssn[0],ptr->pcssn[1],ptr->pcssn[2],ptr->pcssn[3],ptr->pcssn[4]); + strcat(buf,tempchar); + } + + if((flag & BIT9_TRUE)>0) + { + strcat(buf,"RNDGTS="); + for (i=0;irndgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->rndgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT10_TRUE)>0) + { + strcat(buf,"RSUB="); + for (i=0;irsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->rsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT11_TRUE)>0) + { + sprintf(tempchar,"TAT=%02x,",ptr->tat); + strcat(buf,tempchar); + } + + if((flag & BIT12_TRUE)>0) + { + strcat(buf,"TRANSCAP="); + for (i=0;itranscapLen;i++) + { + sprintf(tempchar,"%02x",ptr->transcap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT13_TRUE)>0) //wincap + { + ptr1 = &ptr->wincap; + flag1 = ptr1->param_flag; + if((flag1 & BIT0_TRUE)>0) //triggercapability + { + strcat(buf,"WINCAP-TRIGGERCAP="); + for (i=0;itriggercapLen;i++) + { + sprintf(tempchar,"%02x",ptr1->triggercap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + strcat(buf,"WINCAP-WINOPRCAP="); + for (i=0;iwinoprcapLen;i++) + { + sprintf(tempchar,"%02x",ptr1->winoprcap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_param_isterm(struct IS41_PAR_ISTERM *ptr,u8 *buf) +{ + u32 flag; + u8 i; + char tempchar[512]; + + flag = ptr->param_flag; + + if((flag & BIT0_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-ISTERM-DESTDGTS="); + for (i=0;idestdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->destdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT1_TRUE)>0) //MSCID + { + strcat((char *)buf,"TERMLIST-ISTERM-MSCID="); + for (i=0;i<3;i++) + { + sprintf(tempchar,"%02x",ptr->mscid[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + +// optional part---> + if((flag & BIT2_TRUE)>0) + { + sprintf(tempchar,"TERMLIST-ISTERM-ACCDEN=%02x,",ptr->accden); + strcat((char *)buf,tempchar); + } + if((flag & BIT3_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-ISTERM-CARDGTS="); + for (i=0;icardgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->cardgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT4_TRUE)>0) //esn + { + sprintf(tempchar,"TERMLIST-ISTERM-ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat((char *)buf,tempchar); + } + if((flag & BIT5_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-ISTERM-LEGINFO="); + for (i=0;ileginfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->leginfo[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT6_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-ISTERM-MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT7_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-ISTERM-MSCIN="); + for (i=0;imscinLen;i++) + { + sprintf(tempchar,"%02x",ptr->mscin[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT8_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-ISTERM-ROUTDGTS="); + for (i=0;iroutdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->routdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT9_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-ISTERM-TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if (flag > 0) + return 1; + return 0; +} + +int debug_show_param_locterm(struct IS41_PAR_LOCTERM *ptr,u8 *buf) +{ + u32 flag; + u8 i; + char tempchar[512]; + + flag = ptr->param_flag; + + if((flag & BIT0_TRUE)>0) //esn + { + sprintf(tempchar,"TERMLIST-LOCTERM-ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat((char *)buf,tempchar); + } + if((flag & BIT1_TRUE)>0) //min + { + sprintf(tempchar,"TERMLIST-LOCTERM-MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat((char *)buf,tempchar); + } + if((flag & BIT2_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-TERMTRMT="); + for (i=0;itermtrmtLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrmt[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + +// optional part---> + if((flag & BIT3_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-ALRTCODE="); + for (i=0;ialrtcodeLen;i++) + { + sprintf(tempchar,"%02x",ptr->alrtcode[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT4_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-CARDGTS="); + for (i=0;icardgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->cardgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT5_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-DESTDGTS="); + for (i=0;idestdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->destdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT6_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-LEGINFO="); + for (i=0;ileginfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->leginfo[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT7_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT8_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-OTFI="); + for (i=0;iotfiLen;i++) + { + sprintf(tempchar,"%02x",ptr->otfi[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT9_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-ROUTDGTS="); + for (i=0;iroutdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->routdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT10_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT11_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-VMSPIN="); + for (i=0;ivmspinLen;i++) + { + sprintf(tempchar,"%02x",ptr->vmspin[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT12_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-LOCTERM-VMBOX="); + for (i=0;ivmboxLen;i++) + { + sprintf(tempchar,"%02x",ptr->vmbox[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + + if (flag > 0) + return 1; + return 0; +} + + +int debug_show_param_pstnterm(struct IS41_PAR_PSTNTERM *ptr,u8 *buf) +{ + u32 flag; + u8 i; + char tempchar[512]; + + flag = ptr->param_flag; + + if((flag & BIT0_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-PSTNTERM-DESTDGTS="); + for (i=0;idestdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->destdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + +// optional part---> + if((flag & BIT1_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-PSTNTERM-CARDGTS="); + for (i=0;icardgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->cardgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + + if((flag & BIT2_TRUE)>0) //esn + { + sprintf(tempchar,"TERMLIST-PSTNTERM-ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat((char *)buf,tempchar); + } + if((flag & BIT3_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-PSTNTERM-LEGINFO="); + for (i=0;ileginfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->leginfo[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + + if((flag & BIT4_TRUE)>0) //min + { + sprintf(tempchar,"TERMLIST-PSTNTERM-MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat((char *)buf,tempchar); + } + if((flag & BIT5_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-PSTNTERM-ROUTDGTS="); + for (i=0;iroutdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->routdgts[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + if((flag & BIT6_TRUE)>0) + { + strcat((char *)buf,"TERMLIST-PSTNTERM-TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat((char *)buf,tempchar); + } + strcat((char *)buf,","); + } + + if (flag > 0) + return 1; + return 0; +} + + +int debug_show_param_termlist(struct IS41_PAR_TERMLIST *ptr,u8 *buf) +{ + u32 flag; + + flag = ptr->param_flag; + + if ((flag & BIT0_TRUE) > 0) + { + debug_show_param_isterm(&ptr->isterm,buf); + } + + if ((flag & BIT1_TRUE) > 0) + { + debug_show_param_locterm(&ptr->locterm,buf); + } + + if ((flag & BIT2_TRUE) > 0) + { + debug_show_param_pstnterm(&ptr->pstnterm,buf); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_LOCREQ_RSP(struct IS41_LOCREQ_RSP *ptr,char *buf) +{ + u32 flag,flag1; + struct IS41_PAR_TRIGGER_LIST *ptr1; + u8 i,triglistnum; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //esn + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + if((flag & BIT1_TRUE)>0) //min + { + sprintf(tempchar,"MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT3_TRUE)>0) + { + sprintf(tempchar,"ACCDEN=%02x,",ptr->accden); + strcat(buf,tempchar); + } + + if((flag & BIT4_TRUE)>0) + { + strcat(buf,"ANNLIST="); + for (i=0;iannlistLen;i++) + { + sprintf(tempchar,"%02x",ptr->annlist[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"CPNSTRG1="); + for (i=0;icpnstrg1Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpnstrg1[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT6_TRUE)>0) + { + strcat(buf,"CPNSTRG2="); + for (i=0;icpnstrg2Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpnstrg2[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT7_TRUE)>0) + { + strcat(buf,"DIGITS CARRIER="); + for (i=0;idigitsCarrierLen;i++) + { + sprintf(tempchar,"%02x",ptr->digitsCarrier[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT8_TRUE)>0) + { + strcat(buf,"DIGITS DEST="); + for (i=0;idigitsDestLen;i++) + { + sprintf(tempchar,"%02x",ptr->digitsDest[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT9_TRUE)>0) + { + strcat(buf,"ACDGTS="); + for (i=0;iacdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->acdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT10_TRUE)>0) + { + strcat(buf,"ABDGTS="); + for (i=0;iabdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->abdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT11_TRUE)>0) + { + strcat(buf,"BILLDGTS="); + for (i=0;ibilldgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->billdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT12_TRUE)>0) + { + strcat(buf,"REDIND="); + for (i=0;iredindLen;i++) + { + sprintf(tempchar,"%02x",ptr->redind[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT13_TRUE)>0) + { + strcat(buf,"GRPINFO="); + for (i=0;igrpinfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->grpinfo[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + +// if((flag & BIT11_TRUE)>0) + // buf_len = AddTLV(is41_sequenceTag(IS41PAR_TAT,12),1,&ptr->tat,0x80,&asn_buf); + + if((flag & BIT14_TRUE)>0) + { + strcat(buf,"MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT15_TRUE)>0) + { + strcat(buf,"NATIME="); + for (i=0;inatimeLen;i++) + { + sprintf(tempchar,"%02x",ptr->natime[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT16_TRUE)>0) + { + strcat(buf,"OTFI="); + for (i=0;iotfiLen;i++) + { + sprintf(tempchar,"%02x",ptr->otfi[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT17_TRUE)>0) + { + sprintf(tempchar,"PCSSN=%02x%02x%02x%02x%02x,",ptr->pcssn[0],ptr->pcssn[1],ptr->pcssn[2],ptr->pcssn[3],ptr->pcssn[4]); + strcat(buf,tempchar); + } + + if((flag & BIT18_TRUE)>0) + { + strcat(buf,"RNDGTS="); + for (i=0;irndgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->rndgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT19_TRUE)>0) + { + strcat(buf,"RNSTRING="); + for (i=0;irnstringLen;i++) + { + sprintf(tempchar,"%02x",ptr->rnstring[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT20_TRUE)>0) + { + strcat(buf,"RSUB="); + for (i=0;irsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->rsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT21_TRUE)>0) + { + strcat(buf,"ROUTDGTS="); + for (i=0;iroutdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->routdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if ((flag & BIT22_TRUE) > 0) + { + debug_show_param_termlist(&ptr->termlist, (u8 *)buf); + } + + if((flag & BIT23_TRUE)>0) + { + strcat(buf,"TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT24_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + strcat(buf,"TRIGADRLIST-TRIGLIST-DESTADDR="); + for (i=0;idestaddrLen;i++) + { + sprintf(tempchar,"%02x",ptr1->destaddr[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + strcat(buf,"TRIGADRLIST-TRIGLIST-WINTRIGLIST="); + for (i=0;iwintriglistLen;i++) + { + sprintf(tempchar,"%02x",ptr1->wintriglist[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + } + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_ROUTREQ_ARG(struct IS41_ROUTREQ_ARG *ptr,char *buf) +{ + int i; + u32 flag; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) + { + strcat(buf,"BILLID="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",ptr->billid[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT1_TRUE)>0) //esn + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) //min + { + sprintf(tempchar,"MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat(buf,tempchar); + } + + if((flag & BIT3_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + + if((flag & BIT4_TRUE)>0) //SystemMyTypeCode + { + sprintf(tempchar,"MYTYP=%02x,",ptr->mytyp); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"ALRTCODE="); + for (i=0;ialrtcodeLen;i++) + { + sprintf(tempchar,"%02x",ptr->alrtcode[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT6_TRUE)>0) + { + strcat(buf,"CPNSTRG1="); + for (i=0;icpnstrg1Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpnstrg1[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT7_TRUE)>0) + { + strcat(buf,"CPNSTRG2="); + for (i=0;icpnstrg2Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpnstrg2[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT8_TRUE)>0) + { + strcat(buf,"CPSUB="); + for (i=0;icpsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->cpsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT9_TRUE)>0) + { + strcat(buf,"DESTDGTS="); + for (i=0;idestdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->destdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT10_TRUE)>0) + { + strcat(buf,"ACDGTS="); + for (i=0;iacdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->acdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT11_TRUE)>0) + { + strcat(buf,"ABDGTS="); + for (i=0;iabdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->abdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT12_TRUE)>0) + { + strcat(buf,"BILLDGTS="); + for (i=0;ibilldgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->billdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT13_TRUE)>0) + { + strcat(buf,"LEGINFO="); + for (i=0;ileginfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->leginfo[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT14_TRUE)>0) //LocationAreaID + { + sprintf(tempchar,"LOCID=%02x%02x,",ptr->locid[0],ptr->locid[1]); + strcat(buf,tempchar); + } + + if((flag & BIT15_TRUE)>0) + { + strcat(buf,"MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT16_TRUE)>0) + { + strcat(buf,"MSCIN="); + for (i=0;imscinLen;i++) + { + sprintf(tempchar,"%02x",ptr->mscin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT17_TRUE)>0) + { + strcat(buf,"NATIME="); + for (i=0;inatimeLen;i++) + { + sprintf(tempchar,"%02x",ptr->natime[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT18_TRUE)>0) + { + strcat(buf,"OTFI="); + for (i=0;iotfiLen;i++) + { + sprintf(tempchar,"%02x",ptr->otfi[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT19_TRUE)>0) + { + sprintf(tempchar,"PCSSN=%02x%02x%02x%02x%02x,",ptr->pcssn[0],ptr->pcssn[1],ptr->pcssn[2],ptr->pcssn[3],ptr->pcssn[4]); + strcat(buf,tempchar); + } + + if((flag & BIT20_TRUE)>0) + { + sprintf(tempchar,"PILOTBID=%02x%02x%02x%02x%02x%02x%02x,",ptr->pilotbid[0],ptr->pilotbid[1],ptr->pilotbid[2],ptr->pilotbid[3],ptr->pilotbid[4],ptr->pilotbid[5],ptr->pilotbid[6]); + strcat(buf,tempchar); + } + + if((flag & BIT21_TRUE)>0) + { + strcat(buf,"PILOT="); + for (i=0;ipilotLen;i++) + { + sprintf(tempchar,"%02x",ptr->pilot[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT22_TRUE)>0) + { + strcat(buf,"RNSTRING="); + for (i=0;irnstringLen;i++) + { + sprintf(tempchar,"%02x",ptr->rnstring[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT23_TRUE)>0) + { + strcat(buf,"RSUB="); + for (i=0;irsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->rsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT24_TRUE)>0) //senderin + { + strcat(buf,"SENDERIN="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",ptr->senderin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT25_TRUE)>0) + { + strcat(buf,"TERMTRMT="); + for (i=0;itermtrmtLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrmt[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT26_TRUE)>0) + { + strcat(buf,"TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT27_TRUE)>0) + { + strcat(buf,"VMBOX="); + for (i=0;ivmboxLen;i++) + { + sprintf(tempchar,"%02x",ptr->vmbox[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT28_TRUE)>0) + { + strcat(buf,"VMSPIN="); + for (i=0;ivmspinLen;i++) + { + sprintf(tempchar,"%02x",ptr->vmspin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_ROUTREQ_RSP(struct IS41_ROUTREQ_RSP *ptr,char *buf) +{ + int i; + u32 flag; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT1_TRUE)>0) + { + sprintf(tempchar,"ACCDEN=%02x,",ptr->accden); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) + { + strcat(buf,"BILLID="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",ptr->billid[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT3_TRUE)>0) + { + sprintf(tempchar,"CDEN=%02x,",ptr->cden); + strcat(buf,tempchar); + } + + if((flag & BIT4_TRUE)>0) + { + strcat(buf,"DIGITS="); + for (i=0;idigitsLen;i++) + { + sprintf(tempchar,"%02x",ptr->digits[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"MSCIN="); + for (i=0;imscinLen;i++) + { + sprintf(tempchar,"%02x",ptr->mscin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT6_TRUE)>0) + { + sprintf(tempchar,"PCSSN=%02x%02x%02x%02x%02x,",ptr->pcssn[0],ptr->pcssn[1],ptr->pcssn[2],ptr->pcssn[3],ptr->pcssn[4]); + strcat(buf,tempchar); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_TRANUMREQ_ARG(struct IS41_TRANUMREQ_ARG *ptr,char *buf) +{ + int i; + u32 flag,flag1; + char tempchar[512]; + struct IS41_PAR_WIN_CAP *ptr1; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //esn + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + + if((flag & BIT1_TRUE)>0) //min + { + sprintf(tempchar,"MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) //REDIRECTION REASON + { + sprintf(tempchar,"REDREASON=%02x,",ptr->redreason); + strcat(buf,tempchar); + } + + if((flag & BIT3_TRUE)>0) //SystemMyTypeCode + { + sprintf(tempchar,"MYTYP=%02x,",ptr->mytyp); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT4_TRUE)>0) + { + strcat(buf,"BILLID="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",ptr->billid[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"GRPINFO="); + for (i=0;igrpinfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->grpinfo[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT6_TRUE)>0) + { + strcat(buf,"LEGINFO="); + for (i=0;ileginfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->leginfo[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT7_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + if((flag & BIT8_TRUE)>0) + { + strcat(buf,"MSCIN="); + for (i=0;imscinLen;i++) + { + sprintf(tempchar,"%02x",ptr->mscin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT9_TRUE)>0) + { + sprintf(tempchar,"PILOTBID=%02x%02x%02x%02x%02x%02x%02x,",ptr->pilotbid[0],ptr->pilotbid[1],ptr->pilotbid[2],ptr->pilotbid[3],ptr->pilotbid[4],ptr->pilotbid[5],ptr->pilotbid[6]); + strcat(buf,tempchar); + } + if((flag & BIT10_TRUE)>0) + { + strcat(buf,"PILOT="); + for (i=0;ipilotLen;i++) + { + sprintf(tempchar,"%02x",ptr->pilot[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT11_TRUE)>0) //transcap + { + strcat(buf,"TRANSCAP="); + for (i=0;itranscapLen;i++) + { + sprintf(tempchar,"%02x",ptr->transcap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT12_TRUE)>0) //wincap + { + ptr1 = &ptr->wincap; + flag1 = ptr1->param_flag; + + if((flag1 & BIT0_TRUE)>0) //triggercapability + { + strcat(buf,"WINCAP-TRIGGERCAP="); + for (i=0;itriggercapLen;i++) + { + sprintf(tempchar,"%02x",ptr1->triggercap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + strcat(buf,"WINCAP-WINOPRCAP="); + for (i=0;iwinoprcapLen;i++) + { + sprintf(tempchar,"%02x",ptr1->winoprcap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_TRANUMREQ_RSP(struct IS41_TRANUMREQ_RSP *ptr,char *buf) +{ + int i,triglistnum; + u32 flag,flag1; + char tempchar[512]; + IS41_PAR_TRIGGER_LIST *ptr1; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //Digits(Destination) + { + strcat(buf,"DIGITS="); + for (i=0;idigitsLen;i++) + { + sprintf(tempchar,"%02x",ptr->digits[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + +//optional + if((flag & BIT1_TRUE)>0) + { + sprintf(tempchar,"TERMLIST-ISTERM-ACCDEN=%02x,",ptr->accden); + strcat(buf,tempchar); + } + if((flag & BIT2_TRUE)>0) + { + strcat(buf,"ACTCODE="); + for (i=0;iactcodeLen;i++) + { + sprintf(tempchar,"%02x",ptr->actcode[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT3_TRUE)>0) + { + strcat(buf,"ANNLIST="); + for (i=0;iannlistLen;i++) + { + sprintf(tempchar,"%02x",ptr->annlist[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT4_TRUE)>0) + { + strcat(buf,"CPNSTRG1="); + for (i=0;icpnstrg1Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpnstrg1[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"CPNSTRG2="); + for (i=0;icpnstrg2Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpnstrg2[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT6_TRUE)>0) + { + strcat(buf,"CPSUB="); + for (i=0;icpsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->cpsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT7_TRUE)>0) //Digits carrier + { + strcat(buf,"DIGITS CARRIER="); + for (i=0;idigitsCarrierLen;i++) + { + sprintf(tempchar,"%02x",ptr->digitsCarrier[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT8_TRUE)>0) + { + strcat(buf,"ACDGTS="); + for (i=0;iacdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->acdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT9_TRUE)>0) + { + strcat(buf,"ABDGTS="); + for (i=0;iabdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->abdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT10_TRUE)>0) + { + strcat(buf,"BILLDGTS="); + for (i=0;ibilldgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->billdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT11_TRUE)>0) + { + strcat(buf,"REDIND="); + for (i=0;iredindLen;i++) + { + sprintf(tempchar,"%02x",ptr->redind[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT12_TRUE)>0) + { + strcat(buf,"DMH_SVCID="); + for (i=0;idmh_svcidLen;i++) + { + sprintf(tempchar,"%02x",ptr->dmh_svcid[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT13_TRUE)>0) + { + strcat(buf,"GRPINFO="); + for (i=0;igrpinfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->grpinfo[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT14_TRUE)>0) + { + strcat(buf,"MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT15_TRUE)>0) + { + strcat(buf,"NATIME="); + for (i=0;inatimeLen;i++) + { + sprintf(tempchar,"%02x",ptr->natime[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT16_TRUE)>0) + { + sprintf(tempchar,"PLIND=%02x,",ptr->plind); + strcat(buf,tempchar); + } + + if((flag & BIT17_TRUE)>0) + { + strcat(buf,"RNDGTS="); + for (i=0;irndgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->rndgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT18_TRUE)>0) + { + strcat(buf,"RNSTRING="); + for (i=0;irnstringLen;i++) + { + sprintf(tempchar,"%02x",ptr->rnstring[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT19_TRUE)>0) + { + strcat(buf,"RSUB="); + for (i=0;irsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->rsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if ((flag & BIT20_TRUE) > 0) + { + debug_show_param_termlist(&ptr->termlist, (u8 *)buf); + } + if((flag & BIT21_TRUE)>0) + { + strcat(buf,"TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT22_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + strcat(buf,"TRIGADRLIST-TRIGLIST-DESTADDR="); + for (i=0;idestaddrLen;i++) + { + sprintf(tempchar,"%02x",ptr1->destaddr[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + strcat(buf,"TRIGADRLIST-TRIGLIST-WINTRIGLIST="); + for (i=0;iwintriglistLen;i++) + { + sprintf(tempchar,"%02x",ptr1->wintriglist[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + } + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_SMSREQ_ARG(struct IS41_SMSREQ_ARG *ptr,char *buf) +{ + int i; + u32 flag; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //min + { + sprintf(tempchar,"MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT1_TRUE)>0) //ElectronicSerialNumber + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) //SMS_NotificationIndicator + { + strcat(buf,"SMSNOTIND="); + for (i=0;ismsnotindLen;i++) + { + sprintf(tempchar,"%02x",ptr->smsnotind[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT3_TRUE)>0) //SMS_TeleserviceIdentifier + { + strcat(buf,"SMSTID="); + for (i=0;ismstidLen;i++) + { + sprintf(tempchar,"%02x",ptr->smstid[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_SMSREQ_RSP(struct IS41_SMSREQ_RSP *ptr,char *buf) +{ + int i; + u32 flag; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //ElectronicSerialNumber + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + + if((flag & BIT1_TRUE)>0) //SMS_AccessDeniedReason + { + strcat(buf,"SMSACCDEN="); + for (i=0;ismsaccdenLen;i++) + { + sprintf(tempchar,"%02x",ptr->smsaccden[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT2_TRUE)>0) //SMS_DestinationAddress + { + strcat(buf,"SMSADDR="); + for (i=0;ismsaddrLen;i++) + { + sprintf(tempchar,"%02x",ptr->smsaddr[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_MSINACT_ARG(struct IS41_MSINACT_ARG *ptr,char *buf) +{ + int i; + u32 flag; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //esn + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + if((flag & BIT1_TRUE)>0) //min + { + sprintf(tempchar,"MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat(buf,tempchar); + } + +// optional part---> + if((flag & BIT2_TRUE)>0) + { + sprintf(tempchar,"COUNT=%02x,",ptr->count); + strcat(buf,tempchar); + } + + if((flag & BIT3_TRUE)>0) + { + sprintf(tempchar,"DEREG=%02x,",ptr->dereg); + strcat(buf,tempchar); + } + + if((flag & BIT4_TRUE)>0) //LocationAreaID + { + sprintf(tempchar,"LOCID=%02x%02x,",ptr->locid[0],ptr->locid[1]); + strcat(buf,tempchar); + } + + if((flag & BIT5_TRUE)>0) //senderin + { + strcat(buf,"SENDERIN="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",ptr->senderin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_MSINACT_RSP(struct IS41_MSINACT_RSP *ptr,char *buf) +{ + buf[0] = 0; + + return 0; +} + +int debug_show_FEATREQ_ARG(struct IS41_FEATREQ_ARG *ptr,char *buf) +{ + int i; + u32 flag; + char tempchar[512]; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //Dialed Digits + { + strcat(buf,"DIGITS="); + for (i=0;idigitsLen;i++) + { + sprintf(tempchar,"%02x",ptr->digits[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT1_TRUE)>0) //esn + { + sprintf(tempchar,"ESN=%02x%02x%02x%02x,",ptr->esn[0],ptr->esn[1],ptr->esn[2],ptr->esn[3]); + strcat(buf,tempchar); + } + + if((flag & BIT2_TRUE)>0) //min + { + sprintf(tempchar,"MIN=%02x%02x%02x%02x%02x,",ptr->min[0],ptr->min[1],ptr->min[2],ptr->min[3],ptr->min[4]); + strcat(buf,tempchar); + } + +//optional + if((flag & BIT3_TRUE)>0) + { + strcat(buf,"BILLID="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",ptr->billid[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT4_TRUE)>0) + { + strcat(buf,"CPNDGTS1="); + for (i=0;icpndgts1Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpndgts1[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"CPNDGTS2="); + for (i=0;icpndgts2Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpndgts2[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT6_TRUE)>0) + { + strcat(buf,"CPSUB="); + for (i=0;icpsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->cpsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT7_TRUE)>0) + { + strcat(buf,"CCI="); + for (i=0;icciLen;i++) + { + sprintf(tempchar,"%02x",ptr->cci[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT8_TRUE)>0) + { + strcat(buf,"MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT9_TRUE)>0) //MSCID + { + sprintf(tempchar,"MSCID=%02x%02x%02x,",ptr->mscid[0],ptr->mscid[1],ptr->mscid[2]); + strcat(buf,tempchar); + } + + if((flag & BIT10_TRUE)>0) + { + strcat(buf,"MSCIN="); + for (i=0;imscinLen;i++) + { + sprintf(tempchar,"%02x",ptr->mscin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT11_TRUE)>0) + { + strcat(buf,"OTFI="); + for (i=0;iotfiLen;i++) + { + sprintf(tempchar,"%02x",ptr->otfi[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT12_TRUE)>0) //pcssn + { + sprintf(tempchar,"PCSSN=%02x%02x%02x%02x%02x,",ptr->pcssn[0],ptr->pcssn[1],ptr->pcssn[2],ptr->pcssn[3],ptr->pcssn[4]); + strcat(buf,tempchar); + } + + if((flag & BIT13_TRUE)>0) //senderin + { + strcat(buf,"SENDERIN="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",ptr->senderin[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT14_TRUE)>0) //transcap + { + strcat(buf,"TRANSCAP="); + for (i=0;itranscapLen;i++) + { + sprintf(tempchar,"%02x",ptr->transcap[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_FEATREQ_RSP(struct IS41_FEATREQ_RSP *ptr,char *buf) +{ + int i,triglistnum; + u32 flag,flag1; + char tempchar[512]; + IS41_PAR_TRIGGER_LIST *ptr1; + + flag = ptr->param_flag; + + buf[0] = 0; + + if((flag & BIT0_TRUE)>0) //feature result + { + sprintf(tempchar,"FEATRESULT=%02x,",ptr->featresult); + strcat(buf,tempchar); + } + +//optional + if((flag & BIT1_TRUE)>0) + { + sprintf(tempchar,"ACCDEN=%02x,",ptr->accden); + strcat(buf,tempchar); + } + if((flag & BIT2_TRUE)>0) + { + strcat(buf,"ACTCODE="); + for (i=0;iactcodeLen;i++) + { + sprintf(tempchar,"%02x",ptr->actcode[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT3_TRUE)>0) + { + strcat(buf,"ANNLIST="); + for (i=0;iannlistLen;i++) + { + sprintf(tempchar,"%02x",ptr->annlist[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT4_TRUE)>0) + { + strcat(buf,"CPNDGTS1="); + for (i=0;icpndgts1Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpndgts1[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT5_TRUE)>0) + { + strcat(buf,"CPNDGTS2="); + for (i=0;icpndgts2Len;i++) + { + sprintf(tempchar,"%02x",ptr->cpndgts2[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT6_TRUE)>0) + { + strcat(buf,"CPSUB="); + for (i=0;icpsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->cpsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT7_TRUE)>0) //Digits carrier + { + strcat(buf,"DIGITS CARRIER="); + for (i=0;idigitsCarrierLen;i++) + { + sprintf(tempchar,"%02x",ptr->digitsCarrier[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT8_TRUE)>0) //ConferenceCallingIndicator + { + strcat(buf,"CCI="); + for (i=0;icciLen;i++) + { + sprintf(tempchar,"%02x",ptr->cci[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT9_TRUE)>0) //Digits carrier + { + strcat(buf,"DIGITS="); + for (i=0;idigitsLen;i++) + { + sprintf(tempchar,"%02x",ptr->digits[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } +/* if((flag & BIT10_TRUE)>0) //display text + buf_len = AddTLV(is41_sequenceTag(IS41PAR_DISPTEXT,11),ptr->disptextLen & MAX_IS41_VARPAR_LEN_1,ptr->disptext,0x80,&asn_buf);*/ + if((flag & BIT11_TRUE)>0) + { + strcat(buf,"ACDGTS="); + for (i=0;iacdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->acdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT12_TRUE)>0) + { + strcat(buf,"ABDGTS="); + for (i=0;iabdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->abdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT13_TRUE)>0) + { + strcat(buf,"BILLDGTS="); + for (i=0;ibilldgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->billdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT14_TRUE)>0) + { + strcat(buf,"REDIND="); + for (i=0;iredindLen;i++) + { + sprintf(tempchar,"%02x",ptr->redind[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT15_TRUE)>0) + { + strcat(buf,"GRPINFO="); + for (i=0;igrpinfoLen;i++) + { + sprintf(tempchar,"%02x",ptr->grpinfo[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT16_TRUE)>0) + { + strcat(buf,"MDN="); + for (i=0;imdnLen;i++) + { + sprintf(tempchar,"%02x",ptr->mdn[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT17_TRUE)>0) + { + strcat(buf,"NATIME="); + for (i=0;inatimeLen;i++) + { + sprintf(tempchar,"%02x",ptr->natime[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT18_TRUE)>0) + { + strcat(buf,"OTFI="); + for (i=0;iotfiLen;i++) + { + sprintf(tempchar,"%02x",ptr->otfi[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT19_TRUE)>0) + { + sprintf(tempchar,"PACAIND=%02x,",ptr->pacaind); + strcat(buf,tempchar); + } + if((flag & BIT20_TRUE)>0) + { + strcat(buf,"PILOT="); + for (i=0;ipilotLen;i++) + { + sprintf(tempchar,"%02x",ptr->pilot[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT21_TRUE)>0) + { + strcat(buf,"RNDGTS="); + for (i=0;irndgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->rndgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT22_TRUE)>0) + { + strcat(buf,"RNSTRING="); + for (i=0;irnstringLen;i++) + { + sprintf(tempchar,"%02x",ptr->rnstring[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT23_TRUE)>0) + { + strcat(buf,"RSUB="); + for (i=0;irsubLen;i++) + { + sprintf(tempchar,"%02x",ptr->rsub[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag & BIT24_TRUE)>0) + { + sprintf(tempchar,"RESUMEPIC=%02x,",ptr->resumepic); + strcat(buf,tempchar); + } + if((flag & BIT25_TRUE)>0) + { + strcat(buf,"ROUTDGTS="); + for (i=0;iroutdgtsLen;i++) + { + sprintf(tempchar,"%02x",ptr->routdgts[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if ((flag & BIT26_TRUE) > 0) + { + debug_show_param_termlist(&ptr->termlist, (u8 *)buf); + } + if((flag & BIT27_TRUE)>0) + { + strcat(buf,"TERMTRIG="); + for (i=0;itermtrigLen;i++) + { + sprintf(tempchar,"%02x",ptr->termtrig[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + + if((flag & BIT28_TRUE)>0) //TriggerAddressList + { + triglistnum = ptr->triggerlistnum & MAX_IS41_TRIG_LIST_NUM_1; + + for (i = 0; i < triglistnum; i++) + { + ptr1 = &ptr->triggerlist[i]; + flag1 = ptr1->param_flag; + + if((flag1 & BIT0_TRUE)>0) //destinationaddress -- choice global title + { + strcat(buf,"TRIGADRLIST-TRIGLIST-DESTADDR="); + for (i=0;idestaddrLen;i++) + { + sprintf(tempchar,"%02x",ptr1->destaddr[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + if((flag1 & BIT1_TRUE)>0) //winoperationscapability + { + strcat(buf,"TRIGADRLIST-TRIGLIST-WINTRIGLIST="); + for (i=0;iwintriglistLen;i++) + { + sprintf(tempchar,"%02x",ptr1->wintriglist[i]); + strcat(buf,tempchar); + } + strcat(buf,","); + } + } + } + + if (flag > 0) + return 1; + return 0; +} + +int debug_show_AUTHREQ_ARG(IS41_AUTHREQ_ARG *AUTHREQ,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + char name[32]; + + param_flag = AUTHREQ->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"esn=%02x%02x%02x%02x;",AUTHREQ->esn[0],AUTHREQ->esn[1],AUTHREQ->esn[2],AUTHREQ->esn[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"min=%02x%02x%02x%02x%02x;",AUTHREQ->min[0],AUTHREQ->min[1],AUTHREQ->min[2],AUTHREQ->min[3],AUTHREQ->min[4]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"mscid=%02x%02x%02x;",AUTHREQ->mscid[0],AUTHREQ->mscid[1],AUTHREQ->mscid[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT3_TRUE) + { + switch (AUTHREQ->sysacctype) + { + case ACCTYPE_REGISTRATION: + sprintf(name,"REGISTRATION"); + break; + case ACCTYPE_ORIGINATION: + sprintf(name,"ORIGINATION"); + break; + case ACCTYPE_TERMINATION: + sprintf(name,"TERMINATION"); + break; + case ACCTYPE_NOACCESS: + sprintf(name,"NO ACCESS"); + break; + case ACCTYPE_POWERDOWN: + sprintf(name,"POWER DOWN"); + break; + case ACCTYPE_SMS_PAGERESPONSE: + sprintf(name,"SMS PAGE RESPONSE"); + break; + default: + sprintf(name,"UNSPECIFIED"); + break; + } + sprintf(tempchar,"SysAccType=%s(%02x);",name,AUTHREQ->sysacctype); + strcat(charOpr,tempchar); + } + if (param_flag & BIT4_TRUE) + { + sprintf(tempchar,"SysCap=%02x;",AUTHREQ->syscap); + strcat(charOpr,tempchar); + } + if (param_flag & BIT5_TRUE) + { + sprintf(tempchar,"AuthData=%02x%02x%02x;",AUTHREQ->authdata[0],AUTHREQ->authdata[1],AUTHREQ->authdata[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT6_TRUE) + { + sprintf(tempchar,"Authr=%02x%02x%02x;",AUTHREQ->authr[0],AUTHREQ->authr[1],AUTHREQ->authr[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT7_TRUE) + { + sprintf(tempchar,"COUNT=%02d;",AUTHREQ->count); + strcat(charOpr,tempchar); + } + if (param_flag & BIT8_TRUE) + { + sprintf(tempchar,"CMODES=%02x;",AUTHREQ->cmodes); + strcat(charOpr,tempchar); + } + if (param_flag & BIT9_TRUE) + { + strcat(charOpr,"digits="); + for (i=0;iDigitsLen;i++) + { + sprintf(tempchar,"%02x",AUTHREQ->digits[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT10_TRUE) + { + sprintf(tempchar,"PCSSN=%02x%02x%02x%02x%02x;",AUTHREQ->pcssn[0],AUTHREQ->pcssn[1],AUTHREQ->pcssn[2],AUTHREQ->pcssn[3],AUTHREQ->pcssn[4]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT11_TRUE) + { + sprintf(tempchar,"RAND=%02x%02x%02x%02x;",AUTHREQ->rand[0],AUTHREQ->rand[1],AUTHREQ->rand[2],AUTHREQ->rand[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT12_TRUE) + { + strcat(charOpr,"senderin="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",AUTHREQ->senderin[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT13_TRUE) + { + sprintf(tempchar,"TermType=%02x;",AUTHREQ->termtyp); + strcat(charOpr,tempchar); + } + + if (param_flag) + return 1; + return 0; +} + +int debug_show_authreq_rsp(IS41_AUTHREQ_RSP *authreq,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + + param_flag = authreq->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"AAV=%02x;",authreq->aav); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"AUTHU=%02x%02x%02x;",authreq->authu[0],authreq->authu[1],authreq->authu[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"COUNT=%02x;",authreq->count); + strcat(charOpr,tempchar); + } + if (param_flag & BIT3_TRUE) + { + sprintf(tempchar,"CDMAPLCM=%02x%02x%02x%02x%02x%02x;", + authreq->cdmaplcm[0],authreq->cdmaplcm[1],authreq->cdmaplcm[2],authreq->cdmaplcm[3], + authreq->cdmaplcm[4],authreq->cdmaplcm[5]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT4_TRUE) + { + sprintf(tempchar,"DenAcc=%02x;",authreq->denacc); + strcat(charOpr,tempchar); + } + if (param_flag & BIT5_TRUE) + { + strcat(charOpr,"RANDSSD="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",authreq->randssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT6_TRUE) + { + strcat(charOpr,"RANDU="); + for (i=0;i<3;i++) + { + sprintf(tempchar,"%02x",authreq->randu[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT7_TRUE) + { + strcat(charOpr,"SSD="); + for (i=0;i<16;i++) + { + sprintf(tempchar,"%02x",authreq->ssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT8_TRUE) + { + strcat(charOpr,"SMEKEY="); + for (i=0;i<8;i++) + { + sprintf(tempchar,"%02x",authreq->smekey[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT9_TRUE) + { + sprintf(tempchar,"NOSSD=%02x;",authreq->nossd); + strcat(charOpr,tempchar); + } + if (param_flag & BIT10_TRUE) + { + sprintf(tempchar,"UpdCount=%02x;",authreq->updcount); + strcat(charOpr,tempchar); + } + if (param_flag & BIT11_TRUE) + { + strcat(charOpr,"VPMASK="); + for (i=0;i<66;i++) + { + sprintf(tempchar,"%02x",authreq->vpmask[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag) + return 1; + return 0; +} + +int debug_show_ASREPORT_ARG(IS41_ASREPORT_ARG *ASREPORT,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + + param_flag = ASREPORT->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"esn=%02x%02x%02x%02x;",ASREPORT->esn[0],ASREPORT->esn[1],ASREPORT->esn[2],ASREPORT->esn[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"min=%02x%02x%02x%02x%02x;",ASREPORT->min[0],ASREPORT->min[1],ASREPORT->min[2],ASREPORT->min[3],ASREPORT->min[4]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"SysCap=%02x;",ASREPORT->syscap); + strcat(charOpr,tempchar); + } + if (param_flag & BIT3_TRUE) + { + strcat(charOpr,"countrpt="); + for (i=0;iCntUpdRepLen;i++) + { + sprintf(tempchar,"%02x",ASREPORT->countrpt[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT4_TRUE) + { + strcat(charOpr,"senderin="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",ASREPORT->senderin[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag & BIT5_TRUE) + { + strcat(charOpr,"ssdurpt="); + for (i=0;iSSDUpdRepLen;i++) + { + sprintf(tempchar,"%02x",ASREPORT->ssdurpt[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag & BIT6_TRUE) + { + strcat(charOpr,"uchalrpt="); + for (i=0;iUniChaRepLen;i++) + { + sprintf(tempchar,"%02x",ASREPORT->uchalrpt[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag) + return 1; + return 0; +} + +int debug_show_asreport_rsp(IS41_ASREPORT_RSP *asreport,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + + param_flag = asreport->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"AAV=%02x;",asreport->aav); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"AUTHU=%02x%02x%02x;",asreport->authu[0],asreport->authu[1],asreport->authu[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"COUNT=%02x;",asreport->count); + strcat(charOpr,tempchar); + } + if (param_flag & BIT3_TRUE) + { + sprintf(tempchar,"DenAcc=%02x;",asreport->denacc); + strcat(charOpr,tempchar); + } + if (param_flag & BIT4_TRUE) + { + strcat(charOpr,"RANDSSD="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",asreport->randssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT5_TRUE) + { + strcat(charOpr,"RANDU="); + for (i=0;i<3;i++) + { + sprintf(tempchar,"%02x",asreport->randu[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT6_TRUE) + { + strcat(charOpr,"SSD="); + for (i=0;i<16;i++) + { + sprintf(tempchar,"%02x",asreport->ssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT7_TRUE) + { + sprintf(tempchar,"NOSSD=%02x;",asreport->nossd); + strcat(charOpr,tempchar); + } + if (param_flag & BIT8_TRUE) + { + sprintf(tempchar,"UpdCount=%02x;",asreport->updcount); + strcat(charOpr,tempchar); + } + + if (param_flag) + return 1; + return 0; +} + +int debug_show_BSCHALL_ARG(IS41_BSCHALL_ARG *BSCHALL,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + + param_flag = BSCHALL->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"esn=%02x%02x%02x%02x;",BSCHALL->esn[0],BSCHALL->esn[1],BSCHALL->esn[2],BSCHALL->esn[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"min=%02x%02x%02x%02x%02x;",BSCHALL->min[0],BSCHALL->min[1],BSCHALL->min[2],BSCHALL->min[3],BSCHALL->min[4]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"RANDBS=%02x%02x%02x%02x;",BSCHALL->randbs[0],BSCHALL->randbs[1],BSCHALL->randbs[2],BSCHALL->randbs[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT3_TRUE) + { + strcat(charOpr,"SENDERIN="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",BSCHALL->senderin[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag) + return 1; + return 0; +} + +int debug_show_bschall_rsp(IS41_BSCHALL_RSP *bschall,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + + param_flag = bschall->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"AUTHBS=%02x%02x%02x",bschall->authbs[0],bschall->authbs[1],bschall->authbs[2]); + strcat(charOpr,tempchar); + } + + if (param_flag) + return 1; + return 0; +} + +int debug_show_AFREPORT_ARG(IS41_AFREPORT_ARG *AFREPORT,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + char name[32]; + + param_flag = AFREPORT->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"esn=%02x%02x%02x%02x;",AFREPORT->esn[0],AFREPORT->esn[1],AFREPORT->esn[2],AFREPORT->esn[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"min=%02x%02x%02x%02x%02x;",AFREPORT->min[0],AFREPORT->min[1],AFREPORT->min[2],AFREPORT->min[3],AFREPORT->min[4]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"rpttyp1=%02x;",AFREPORT->rpttyp1); + strcat(charOpr,tempchar); + } + if (param_flag & BIT3_TRUE) + { + switch (AFREPORT->sysacctype) + { + case ACCTYPE_REGISTRATION: + sprintf(name,"REGISTRATION"); + break; + case ACCTYPE_ORIGINATION: + sprintf(name,"ORIGINATION"); + break; + case ACCTYPE_TERMINATION: + sprintf(name,"TERMINATION"); + break; + case ACCTYPE_NOACCESS: + sprintf(name,"NO ACCESS"); + break; + case ACCTYPE_POWERDOWN: + sprintf(name,"POWER DOWN"); + break; + case ACCTYPE_SMS_PAGERESPONSE: + sprintf(name,"SMS PAGE RESPONSE"); + break; + default: + sprintf(name,"UNSPECIFIED"); + break; + } + sprintf(tempchar,"SysAccType=%s(%02x);",name,AFREPORT->sysacctype); + strcat(charOpr,tempchar); + } + if (param_flag & BIT4_TRUE) + { + sprintf(tempchar,"SysCap=%02x;",AFREPORT->syscap); + strcat(charOpr,tempchar); + } + if (param_flag & BIT5_TRUE) + { + sprintf(tempchar,"COUNT=%02x;",AFREPORT->count); + strcat(charOpr,tempchar); + } + if (param_flag & BIT6_TRUE) + { + sprintf(tempchar,"COUNTex=%02x;",AFREPORT->countex); + strcat(charOpr,tempchar); + } + if (param_flag & BIT7_TRUE) + { + strcat(charOpr,"mscid="); + for (i=0;i<3;i++) + { + sprintf(tempchar,"%02x",AFREPORT->mscid[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT8_TRUE) + { + sprintf(tempchar,"rpttyp2=%02x;",AFREPORT->rpttyp2); + strcat(charOpr,tempchar); + } + if (param_flag & BIT9_TRUE) + { + strcat(charOpr,"senderin="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",AFREPORT->senderin[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag) + return 1; + return 0; +} + +int debug_show_afreport_rsp(IS41_AFREPORT_RSP *afreport,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + + param_flag = afreport->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"aav=%02x;",afreport->aav); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"AUTHU=%02x%02x%02x;",afreport->authu[0],afreport->authu[1],afreport->authu[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"COUNT=%02x;",afreport->count); + strcat(charOpr,tempchar); + } + if (param_flag & BIT3_TRUE) + { + sprintf(tempchar,"DENACC=%02x;",afreport->denacc); + strcat(charOpr,tempchar); + } + if (param_flag & BIT4_TRUE) + { + strcat(charOpr,"RANDSSD="); + for (i=0;i<8;i++) + { + sprintf(tempchar,"%02x",afreport->randssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT5_TRUE) + { + sprintf(tempchar,"RANDU=%02x%02x%02x;",afreport->randu[0],afreport->randu[1],afreport->randu[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT6_TRUE) + { + strcat(charOpr,"SSD="); + for (i=0;i<16;i++) + { + sprintf(tempchar,"%02x",afreport->ssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT7_TRUE) + { + sprintf(tempchar,"NOSSD=%02x;",afreport->nossd); + strcat(charOpr,tempchar); + } + if (param_flag & BIT8_TRUE) + { + sprintf(tempchar,"TERMTYP=%02x;",afreport->termtyp); + strcat(charOpr,tempchar); + } + if (param_flag & BIT9_TRUE) + { + sprintf(tempchar,"UPDCOUNT=%02x;",afreport->updcount); + strcat(charOpr,tempchar); + } + + if (param_flag) + return 1; + return 0; +} + +int auc_debug_show_COUNTREQ_ARG(IS41_COUNTREQ_ARG *COUNTREQ,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + + sprintf(charOpr,"[AC->HLR] COUNTREQ (Invoke)\n"); + + param_flag = COUNTREQ->param_flag; + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"esn=%02x%02x%02x%02x;",COUNTREQ->esn[0],COUNTREQ->esn[1],COUNTREQ->esn[2],COUNTREQ->esn[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"min=%02x%02x%02x%02x%02x;",COUNTREQ->min[0],COUNTREQ->min[1],COUNTREQ->min[2],COUNTREQ->min[3],COUNTREQ->min[4]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT2_TRUE) + { + strcat(charOpr,"senderin="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",COUNTREQ->senderin[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag) + return 1; + return 0; +} + +int auc_debug_show_countreq_rsp(IS41_COUNTREQ_RSP *countreq,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + + sprintf(charOpr,"[HLR->AC] countreq (Result)\n"); + + param_flag = countreq->param_flag; + + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"COUNT=%02x;",countreq->count); + strcat(charOpr,tempchar); + } + + if (param_flag) + return 1; + return 0; +} + +int auc_debug_show_AUTHDIR_ARG(IS41_AUTHDIR_ARG *AUTHDIR,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + int i; + + sprintf(charOpr,"[AC->HLR] AUTHDIR (invoke)\n"); + + param_flag = AUTHDIR->param_flag; + + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"esn=%02x%02x%02x%02x;",AUTHDIR->esn[0],AUTHDIR->esn[1],AUTHDIR->esn[2],AUTHDIR->esn[3]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT1_TRUE) + { + sprintf(tempchar,"min=%02x%02x%02x%02x%02x;",AUTHDIR->min[0],AUTHDIR->min[1],AUTHDIR->min[2],AUTHDIR->min[3],AUTHDIR->min[4]); + strcat(charOpr,tempchar); + } + + if (param_flag & BIT2_TRUE) + { + sprintf(tempchar,"AAV=%02x;",AUTHDIR->aav); + strcat(charOpr,tempchar); + } + + if (param_flag & BIT3_TRUE) + { + sprintf(tempchar,"AUTHU=%02x%02x%02x;",AUTHDIR->authu[0],AUTHDIR->authu[1],AUTHDIR->authu[2]); + strcat(charOpr,tempchar); + } + if (param_flag & BIT4_TRUE) + { + sprintf(tempchar,"COUNT=%02x;",AUTHDIR->count); + strcat(charOpr,tempchar); + } + if (param_flag & BIT5_TRUE) + { + sprintf(tempchar,"DenAcc=%02x;",AUTHDIR->denacc); + strcat(charOpr,tempchar); + } + + if (param_flag & BIT6_TRUE) + { + sprintf(tempchar,"LocID=%02x%02x;",AUTHDIR->locid[0],AUTHDIR->locid[1]); + strcat(charOpr,tempchar); + } + + if (param_flag & BIT7_TRUE) + { + strcat(charOpr,"RANDSSD="); + for (i=0;i<7;i++) + { + sprintf(tempchar,"%02x",AUTHDIR->randssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT8_TRUE) + { + strcat(charOpr,"RANDU="); + for (i=0;i<3;i++) + { + sprintf(tempchar,"%02x",AUTHDIR->randu[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag & BIT9_TRUE) + { + strcat(charOpr,"senderin="); + for (i=0;isenderinLen;i++) + { + sprintf(tempchar,"%02x",AUTHDIR->senderin[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + + if (param_flag & BIT10_TRUE) + { + strcat(charOpr,"SSD="); + for (i=0;i<16;i++) + { + sprintf(tempchar,"%02x",AUTHDIR->ssd[i]); + strcat(charOpr,tempchar); + } + strcat(charOpr,";"); + } + if (param_flag & BIT11_TRUE) + { + sprintf(tempchar,"NOSSD=%02x;",AUTHDIR->nossd); + strcat(charOpr,tempchar); + } + if (param_flag & BIT12_TRUE) + { + sprintf(tempchar,"UpdCount=%02x;",AUTHDIR->updcount); + strcat(charOpr,tempchar); + } + + if (param_flag) + return 1; + return 0; +} + +int auc_debug_show_authdir_rsp(IS41_AUTHDIR_RSP *authdir,char *charOpr) +{ + char tempchar[512]; + u32 param_flag; + + sprintf(charOpr,"[HLR->AC] authdir (Result)\n"); + + param_flag = authdir->param_flag; + + if (param_flag & BIT0_TRUE) + { + sprintf(tempchar,"COUNT=%02x;",authdir->count); + strcat(charOpr,tempchar); + } + + if (param_flag) + return 1; + return 0; +} + diff --git a/plat/xapp/src/mapp/is41_init.c b/plat/xapp/src/mapp/is41_init.c new file mode 100644 index 0000000..f628f7f --- /dev/null +++ b/plat/xapp/src/mapp/is41_init.c @@ -0,0 +1,23 @@ +/* IS41 init c file */ +/* created by daniel zhang 2004-06-18 */ +/* last modify by daniel zhang 2004-07-13 */ +/* version 1.0 */ +/* ------------------------------------ */ + +void is41_debug_setup(); +void is41_debug_timer(); + + +void init_assignFunc_pointer(); +void init_extractFunc_pointer(); +void is41_init() +{ + is41_debug_setup(); + init_assignFunc_pointer(); + init_extractFunc_pointer(); +} + +void is41_timer() +{ + is41_debug_timer(); +} diff --git a/plat/xapp/src/mapp/map_LCSCode.c b/plat/xapp/src/mapp/map_LCSCode.c new file mode 100644 index 0000000..a8aea46 --- /dev/null +++ b/plat/xapp/src/mapp/map_LCSCode.c @@ -0,0 +1,430 @@ + #include "map_includes.h" + + + + + +int extract_RoutingInfoForLCS_Arg(RoutingInfoForLCS_Arg *ptr,u32 buf_len,u8 *buf) + +{ + + ASN_BUF asn_buf; + + int len; + + u8 temp_buf[256]; + + u32 flag=0; + + + + if (buf_len == 0) + + { + + mapp_log_debug("extract RoutingInfoForLCS_Arg param len is:0"); + + return RER; + + } + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + + return RER; + + len = get_tlv("0",temp_buf,&asn_buf); /* mlc number */ + + if (len > 1 && len <= ISDN_LEN) + + { + + flag |= 0x01; + + ptr->mlcNumber[0] = len; + + memcpy(ptr->mlcNumber+1,temp_buf,len); + + } + + else + + { + + mapp_log_debug("extract RoutingInfoForLCS_Arg:loss MLC number"); + + return RER; + + } + + + + if (get_tlv("1",temp_buf,&asn_buf) != -1)/* targetMs */ + + { + + flag |= 0x02; + + len = get_tlv("1.0",temp_buf,&asn_buf); // IMSI + + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + + { + + ptr->targetMs.identityChoice = 0x01; + + memcpy(ptr->targetMs.imsi,temp_buf,IMSI_LEN); + + } + + else + + { + + len = get_tlv("1.1",temp_buf,&asn_buf); // msisdn + + if (len > 0 && len <= ISDN_LEN) + + { + + ptr->targetMs.identityChoice = 0x02; + + ptr->targetMs.msisdn[0] = len; + + memcpy(ptr->targetMs.msisdn+1,temp_buf,len); + + } + + else + + return RER; + + } + + } + + else + + { + + mapp_log_debug("extract RoutingInfoForLCS_Arg:loss TargetMs"); + + return RER; + + } + + ptr->param_flag = flag; + + return buf_len; + +} + + + +int assign_RoutingInfoForLCS_Res(RoutingInfoForLCS_Res *ptr,u8 *buf, u8 ver) + +{ + + ASN_BUF asn_buf; + + u32 flag; + + int buf_len=0; + + u8 len; + + + + asn_encode(buf,&asn_buf); + + flag = ptr->param_flag; + + + + if (flag & 0x01) /* targetMs */ + + { + + if (ptr->targetMs.identityChoice == 1) // IMSI + + buf_len = add_tlv("0.0",IMSI_LEN,ptr->targetMs.imsi,0x80,&asn_buf); + + else if (ptr->targetMs.identityChoice == 2) // msisdn + + { + + len = ptr->targetMs.msisdn[0]; + + buf_len = add_tlv("0.1",len,ptr->targetMs.msisdn+1,0x80,&asn_buf); + + } + + else + + return RER; + + } + + else + + return RER; + + + + if (flag & 0x02)/* mscNumber */ + + { + + len = ptr->mscNumber[0]; + + buf_len = add_tlv("1.4-1",len,ptr->mscNumber+1,0x00,&asn_buf); + + } + + else { + + mapp_log_debug("assign RoutingInfoForLCS_Res:loss MSC NUMBER"); + + return RER; + + } + + + + return buf_len; + +} + + + +int extract_ProvideSubscriberLocation_Arg(ProvideSubscriberLocation_Arg *ptr,u32 buf_len,u8 *buf) + +{ + + ASN_BUF asn_buf; + + int len; + + u8 temp_buf[256]; + + u32 flag=0; + + + + + + if (buf_len == 0) + + { + + mapp_log_debug("extract ProvideSubscriberLocation_Arg param len is:0"); + + return RER; + + } + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + + return RER; + + + + if((len=get_tlv("16-1.0",temp_buf,&asn_buf)) > 0)/* locationType */ + + { + + flag |= 0x01; + + ptr->locationType.locationEstimateType = temp_buf[0]; + + } + + else + + return RER; + + + + if((len=get_tlv("4-2",temp_buf,&asn_buf)) > 0)/* MLC number */ + + { + + flag |= 0x02; + + ptr->mlcNumber[0] = len; + + memcpy(ptr->mlcNumber+1,temp_buf,len); + + } + + else + + return RER; + + + + if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1) /* imsi */ + + { + + if (len == IMSI_LEN) + + { + + flag |= 0x08; + + memcpy(ptr->imsi,temp_buf,len); + + } + + else + + return RER; + + } + + + + + + if ((len=get_tlv("3",temp_buf,&asn_buf)) != -1) /* msisdn */ + + { + + if (len > 0 && len <= ISDN_LEN) + + { + + flag |= 0x04; + + ptr->msisdn[0] = len; + + memcpy(ptr->msisdn+1,temp_buf,len); + + } + + else + + return RER; + + } + + + + ptr->param_flag = flag; + + return buf_len; + +} + + + + + +int assign_ProvideSubscriberLocation_Res(ProvideSubscriberLocation_Res *ptr,u8 *buf, u8 ver) + +{ + + ASN_BUF asn_buf; + + u32 flag; + + int buf_len=0; + + + + asn_encode(buf,&asn_buf); + + flag = ptr->param_flag; + + if (flag & 0x01)/* locationEstimate */ + + { + + u8 locationEstimate[maxExtGeographicalInformation] = {0}; + + if(ptr->locationEstimate.typeOfShape != EllipsoidPoint) /* only support EllipsoidPoint */ + + return RER; + + locationEstimate[0] |= ptr->locationEstimate.typeOfShape << 4; + + + + + + if(ptr->locationEstimate.degreesOfLatitude >= 0) + + locationEstimate[1] &= 0x00; + + else + + locationEstimate[1] |= 0x80; + + ptr->locationEstimate.degreesOfLatitude &= 0x7fffff; + + locationEstimate[1] |= ptr->locationEstimate.degreesOfLatitude >> 16; + + locationEstimate[2] = ptr->locationEstimate.degreesOfLatitude >> 8; + + locationEstimate[3] = ptr->locationEstimate.degreesOfLatitude & 0xff; + + + + ptr->locationEstimate.degreesOfLongitude &= 0xffffff; + + locationEstimate[4] = ptr->locationEstimate.degreesOfLongitude >> 16; + + locationEstimate[5] = ptr->locationEstimate.degreesOfLongitude >> 8; + + locationEstimate[6] = ptr->locationEstimate.degreesOfLongitude & 0xff; + + + + buf_len = add_tlv("4-1",7,locationEstimate,0x00,&asn_buf); + + } + + else { + + return RER; + + } + + + + if (flag & 0x02)/* cgi */ + + { + + u8 cgi[16] = {0}; + + if(ptr->cgi.cgiOrLaiChoice != CgiOrSai) /* only support cgiOrSai */ + + return RER; + + memcpy(cgi,ptr->cgi.mccMnc,3); + + cgi[3] = ptr->cgi.lac >> 8; + + cgi[4] = ptr->cgi.lac & 0xff; + + cgi[5] = ptr->cgi.cellId >> 8; + + cgi[6] = ptr->cgi.cellId & 0xff; + + buf_len = add_tlv("6-2.0",7,cgi,0x80,&asn_buf); + + } + + else { + + + + } + + + + return buf_len; + +} + diff --git a/plat/xapp/src/mapp/map_LCSCode.h b/plat/xapp/src/mapp/map_LCSCode.h new file mode 100644 index 0000000..af1874a --- /dev/null +++ b/plat/xapp/src/mapp/map_LCSCode.h @@ -0,0 +1,260 @@ + + +/***************** LCS ************** + +#define AC_locationServiceGateWay 37 + +#define AC_locationServiceEnquiry 38 + + + +#define RoutingInfoForLCS 85 + +#define ProvideSubscriberLocation 83 + +**************** LCS **************/ + + + +typedef struct _SubscriberIdentity + +{ + + u8 identityChoice; /*1:imsi,2:msisdn*/ + + u8 msisdn[ISDN_LEN+1]; /* TBCD */ + + u8 imsi[IMSI_LEN+1]; /* TBCD */ + +}SubscriberIdentity; + + + +typedef struct _MapRoutingInfoForLCS_Arg + +{ + + u32 param_flag; + + u8 mlcNumber[ISDN_LEN+1]; /* TBCD */ + + SubscriberIdentity targetMs; + + u8 user_error; + + u8 provider_error; + +}RoutingInfoForLCS_Arg; + + + +typedef struct _MapRoutingInfoForLCS_Res + +{ + + u32 param_flag; + + SubscriberIdentity targetMs; + + u8 mscNumber[ISDN_LEN+1]; /* TBCD */ + + u8 user_error; + + u8 provider_error; + +}RoutingInfoForLCS_Res; + + + + + +typedef enum _LocationEstimateType + +{ + + currentLocation = 0, + + currentOrLastKnownLocation, + + initialLocation, + + activateDeferredLocation, + + cancelDeferredLocation, + + notificationVerificationOnly + +}LocationEstimateType; + + + +typedef enum _DeferredLocationEventType + +{ + + msAvailable = 0, + + enteringIntoArea, + + leavingFromArea, + + beingInsideArea, + + periodicLDR + +}DeferredLocationEventType; + + + +typedef struct _LocationType + +{ + + LocationEstimateType locationEstimateType; + + DeferredLocationEventType deferredLocationEventType; + +}LocationType; + + + +typedef struct _ProvideSubscriberLocation_Arg + +{ + + u32 param_flag; + + LocationType locationType; + + u8 mlcNumber[ISDN_LEN+1]; /* TBCD */ + + u8 msisdn[ISDN_LEN+1]; /* TBCD */ + + u8 imsi[IMSI_LEN+1]; /* TBCD */ + + u8 user_error; + + u8 provider_error; + +}ProvideSubscriberLocation_Arg; + + + +typedef enum _TypeOfShape + +{ + + EllipsoidPoint = 0, + + EllipsoidPointWithUncertaintyCircle = 1, + + EllipsoidPointWithUncertaintyEllipse = 3, + + Polygon = 5, + + EllipsoidPointWithAltitude = 8, + + EllipsoidPointWithAltitudeAndUncertaintyEllipsoid = 9, + + EllipsoidArc =10 + +}TypeOfShape; + + + + + +#define maxExtGeographicalInformation 20 + +typedef struct _LocationEstimate + +{ + + TypeOfShape typeOfShape;/* only support EllipsoidPoint */ + + long degreesOfLatitude; + + long degreesOfLongitude; + + u8 reserve[maxExtGeographicalInformation - 7]; + +}LocationEstimate; + + + + + +typedef enum _CgiSaiOrLaiChoice + +{ + + CgiOrSai = 1, + + LAI = 2 + +}CgiSaiOrLaiChoice; + + + +typedef struct _CGI + +{ + + CgiSaiOrLaiChoice cgiOrLaiChoice; + +/* + +-- octet 1 bits 4321 Mobile Country Code 1st digit + +-- bits 8765 Mobile Country Code 2nd digit + +-- octet 2 bits 4321 Mobile Country Code 3rd digit + +-- bits 8765 Mobile Network Code 3rd digit + +-- or filler (1111) for 2 digit MNCs + +-- octet 3 bits 4321 Mobile Network Code 1st digit + +-- bits 8765 Mobile Network Code 2nd digit + +-- octets 4 and 5 Location Area Code according to 3GPP TS 24.008 + +-- octets 6 and 7 Cell Identity (CI) value or + +-- Service Area Code (SAC) value + +-- according to 3GPP TS 23.003 + +*/ + + u8 mccMnc[3]; /* tbcd */ + + u16 lac; /* integer */ + + u16 cellId; /* integer */ + +}CGI; + + + +typedef struct _ProvideSubscriberLocation_Res + +{ + + u32 param_flag; + + LocationEstimate locationEstimate; + + CGI cgi; + + u8 user_error; + + u8 provider_error; + +}ProvideSubscriberLocation_Res; + + + + + diff --git a/plat/xapp/src/mapp/map_acn.h b/plat/xapp/src/mapp/map_acn.h new file mode 100644 index 0000000..a8f0781 --- /dev/null +++ b/plat/xapp/src/mapp/map_acn.h @@ -0,0 +1,75 @@ +/* MAP application context name head file */ +/* Written by Liu zhiguo 2001-12-28 */ +/* Version 1.0 (according GSM 09.02 17.3.3) */ +/* ---------------------------------------- */ +#ifndef _MAP_ACN +#define _MAP_ACN + +/* public portion */ +#define Identified_Organization 0x04 +#define ETSI 0x00 +#define MobileDomain 0x00 +#define GSM_Network 0x01 +#define AC_ID 0x00 +#define AC_Version1 0x01 +#define AC_Version2 0x02 +#define AC_Version3 0x03 +/* private portion */ +#define AC_networkLocUp 1 // network loction update +#define AC_locationCancel 2 // location cancel +#define AC_roamingNbEnquiry 3 // roaming number enquiry +#define AC_locInfoRetrieval 5 // location info retrieval +#define AC_reset 10 // reset context +#define AC_handoverControl 11 // handover control +#define AC_equipmentMngt 13 // equipment management +#define AC_infoRetrieval 14 // info retrieval +#define AC_interVlrInfoRetrieval 15 +#define AC_subscriberDataMngt 16 +#define AC_tracing 17 // tracing +#define AC_networkFunctionalSs 18 +#define AC_networkUnstructuredSs 19 +#define AC_shortMsgGateway 20 +#define AC_shortMsgMoRelay 21 +#define AC_shortMsgAlert 23 +#define AC_mwdMngt 24 +#define AC_shortMsgMtRelay 25 +#define AC_imsiRetrieval 26 +#define AC_msPurging 27 +#define AC_subsriberInfoEnquiry 28 +#define AC_anyTimeInfoEnquiry 29 +#define AC_callControlTransfer 6 +#define AC_ssInvNotify 36 // ss-InvocationNotificationContext +#define AC_sIWFSAllocation 12 // sIWFSAllocationContext +#define AC_groupCallControl 31 // group call control context +#define AC_gprsLocUp 32 // GPRS location update context +#define AC_gprsLocInfoRetrieval 33 // GPRS location info retrieval context +#define AC_failureReport 34 // failure report context +#define AC_gprsNotify 35 // GPRS notify context +#define AC_reporting 7 // reporting context +#define AC_callCompletion 8 // call completion context +#define AC_authFailReport 39 //authenticationFailureReport add by gxchen +#define AC_istAlert 4 //istAlertingContext ist-Alert add by gxchen +#define AC_serviceTermination 9 //serviceTerminationContext ist-Command add by gxchen + +#define AC_anyTimeInfoHandling 43 + +/* MAP-H application context */ +#define AC_SecurityTriplet 200 // security triplet +#define AC_SubsInter 201 // subscriber interrogate +#define AC_HLRSubsMng 202 // HLR subscriber management +#define AC_HLRPingAUC 203 // HLR ping AUC + +#define AC_VlrCamelPhase 209 + +/* Opr,vlr,hlr ACN */ +#define OprVlrACN 210 +#define OprHlrACN 211 + +/***************** LCS **************/ +#define AC_locationServiceGateWay 37 +#define AC_locationServiceEnquiry 38 +/***************** LCS **************/ + +#define AC_Test 255 + +#endif diff --git a/plat/xapp/src/mapp/map_code.h b/plat/xapp/src/mapp/map_code.h new file mode 100644 index 0000000..e0b9126 --- /dev/null +++ b/plat/xapp/src/mapp/map_code.h @@ -0,0 +1,343 @@ +/* MAP operation and error code */ +/* written by liu zhiguo 2001-07-25 */ +/* Version 1.0 (according GSM 09.02 17.5) */ +/* ------------------------------------- */ +#ifndef _MAP_CODE +#define _MAP_CODE + +/* +++++++++++++++++ */ +/* MAP message type */ +/* +++++++++++++++++ */ +/* dialogue control portion */ +#define MAP_OPEN 0xff +#define MAP_CLOSE 0xfe +#define MAP_U_ABORT 0xfd +#define MAP_P_ABORT 0xfc +#define MAP_NOTICE 0xfb +#define MAP_DELIMITER 0xfa +#define MAP_LINK 0xef + +#define MAP_REQUEST 0x01 +#define MAP_INDICATE 0x02 +#define MAP_RESPONSE 0x03 +#define MAP_CONFIRM 0x04 + +/* ++++++++++++++++++++ */ +/* MAP operation code */ +/* ++++++++++++++++++++ */ + +/* locaion registration operation codes */ +#define UpLoc 2 // update location +#define CancelLoc 3 // cancel location +#define PurgeMS 67 // purge mobile station +#define SndIdent 55 // send identification + +/* handover operatin codes */ +#define PreHo 68 // prepare handover +#define SndEndSig 29 // send end signal +#define ProcAccSig 33 // process access signalling +#define FwdAccSig 34 // forward access signalling +#define PreSubsHo 69 // prepare subsequent handover + +/* authentication operation codes */ +#define SndAuthInfo 56 // send authentication information +#define AuthFailReport 15 //authenticationFailureReport add by gxchen + +/* IMEI management operation codes */ +#define ChkIMEI 43 // check IMEI + +/* subscriber management operation codes */ +#define InsSubData 7 // insert subscriber data +#define DelSubData 8 // delete subscriber data +#define SendParam 9 // send parameters + +/* fault recovery operation codes */ +#define Reset 37 // reset +#define FwdChkSSInd 38 // forward check SS indication +#define RestoreData 57 // restore data + +/* operation and maintenance operation codes */ +#define ActvTraceMode 50 // active trace mode +#define DeactvTraceMode 51 // deactive trace mode +#define SndIMSI 58 // send IMSI + +/* call handling operation codes */ +#define SndRoutInfo 22 // send routing information +#define ProvRoamNum 4 // provide roaming number +#define ResumeCH 6 // resume call handling +#define ProvSIWFSNum 31 // provide SIWFS nunmber +#define SIWFSSigMdf 32 // SIWFS signalling modify +#define SetRepState 73 // set report state +#define StatusRep 74 // status report +#define RmtUserFree 75 // remote user free +#define IstAlert 87 //ist-Alert add by gxchen +#define IstCommand 88 //ist-Command add by gxchen + +/* supplementary service handling operation codes */ +#define RegSS 10 // register SS +#define EraseSS 11 // erase SS +#define ActvSS 12 // activate SS +#define DeactvSS 13 // deactivate SS +#define InterSS 14 // interrogate SS +#define ProcUnstrctSSReq 59 // process unstructure SS request +#define UnstrctSSReq 60 // unstructure SS request +#define UnstrctSSNoti 61 // unstructure SS notify +#define RegPasswd 17 // register password +#define GetPasswd 18 // get password +#define RegCCEntry 76 // register CC entry +#define EraseCCEntry 77 // erase CC entry + +/* short message service operation codes */ +#define SndRoutInfoForSM 45 // send routing information for SM +#define FwdSM 46 // Forward SM V1 +#define MOFwdSM 46 // MO-forward SM +#define MTFwdSM 46 // MT-forward SM +#define MTFwdSM_v3 44 +#define RptSMDelvStat 47 // report SM delivery status +#define InfSC 63 // inform service center +#define AlrtSC 64 // alert service center +#define RdyForSM 66 // ready for SM + +/* provide subsriber info operation codes */ +#define ProvSubInfo 70 // provider subscriber information + +/* any time interrogation operation codes */ +#define AnyTimeInter 71 // any time interrogation + +/* any time subscription interrogation operation codes */ +#define AnyTimeSubInter 62 // any time subscription interrogation + +/* supplementary service invocation notification operation codes */ +#define SSInvNoti 72 // SS invocation notification + +/* group call operation codes */ +#define PreGrpCall 39 // prepare group call +#define SndGrpCallEndSig 40 // send group call end signal +#define ProcGrpCallSig 41 // process group call signalling +#define FwdGrpCallSig 42 // forward group call signalling + +/* GPRS location updating operation codes */ +#define UpGprsLoc 23 // update GPRS location + +/* GPRS location information retrieval operation codes */ +#define SndRoutInfoForGprs 24 // send routing info for GPRS + +/* failure reportin operation codes */ +#define FailRep 25 // failure report + +/* GPRS notification operation codes */ +#define NoteMsPresForGprs 26 // note ms present for GPRS + +/* MAP-H operaion codes, defined by owner */ +#define SecuTrip 200 // security triplets +#define InterrSubs 201 // interrogate subscriber +#define CreateSubs 202 // create subscriber +#define DelSubs 203 // deleter subscriber +#define PingAuc 204 // HLR ping AUC + +/* +++++++++++++++++++++++++ */ +/* MAP operation error code */ +/* +++++++++++++++++++++++++ */ + +/* generic error codes */ +#define SysFail 34 // system failure +#define DataMissing 35 +#define UnexpDataVal 36 // unexpected data value +#define FaciNotSpprt 21 // facility not support +#define IncomTerm 28 // incompatible terminal +#define ResLimit 51 // resource limitation + +/* identification and numbering error codes */ +#define UnknwnSub 1 // unknown subscriber +#define NumChng 44 // number changed +#define UnknwnMSC 3 // unknown MSC +#define UnidentSub 5 // unidentified subscriber +#define UnknwnEquip 7 // unkown equipment + +/* subscription error codes */ +#define RoamNotAllow 8 // roaming not allowed +#define IllgSub 9 // illegal subscriber +#define IllgEquip 12 // illegal equipment +#define BSNotProv 10 // bearer service not provisioned +#define TSNotProv 11 // teleservice not provisioned + +/* handover error codes */ +#define NoHONumAvail 25 // no handover number available +#define SubsHOFail 26 // subsequent handover failure + +/* operation and maintenance error codes */ +#define TrcBufferFull 40 // tracing buffer full + +/* call handling error codes */ +#define NoRoamNumAvail 39 // no roaming number available +#define AbsentSub 27 // absent subscriber +#define BusySub 45 // busy subscriber +#define NoSubReply 46 // no subscriber reply +#define CallBarred 13 +#define FwdFail 47 // forwarding failing +#define OR_NotAllow 48 // OR not allowed +#define FwdViolate 14 // forwarding violate +#define CUG_Reject 15 + +/* any time interrogatin error codes */ +#define ATI_NotAllow 49 // ati not allowed +#define InformationNotAvailable 62 + +/* group call error codes */ +#define NoGrpCallNumAvail 50 // no group call number available + +/* supplementary service error codes */ +#define IllgSSOper 16 // illegal SS operation +#define SSErrStatus 17 // SS error status +#define SSNotAvail 18 // SS not available +#define SSSubscViolate 19 // SS subscription violation +#define SSIncompat 20 // SS incompatibility +#define UnknwnAlph 71 // unknown alphabet +#define USSDBusy 72 +#define PWRegFail 37 // pw-registration failure +#define NegPWCheck 38 // negative pw-check +#define NumOfPWAttViolate 43 // number of pw-attempts violation +#define ShortTermDen 29 // short term denial +#define LongTermDen 30 // long term denial + +/* short message service error codes */ +#define SubBusyForMTSMS 31 // subscriber busy for MT-SMS +#define SMDelivFail 32 // SM-delivery failure +#define MsgWaitListFull 33 // message waiting list full +#define AbsentSubSM 6 // absent subscriber SM + +/* ++++++++++++++++++++++++++++++++ */ +/* MAP operation provider error */ +/* defined by user */ +/* ++++++++++++++++++++++++++++++++ */ +#define DupInvokeId 101 // duplicated invoke id +#define SrvNotSupport 102 // service not supported +#define MistypeParam 103 // mistyped parameter +#define ResourceLimit 104 // resource limitation +#define InitRelease 105 // initiating release +#define UnexpResFromPeer 106 // unexpected response from the peer +#define SrvCompleteFailure 107 // service completion failure +#define NoResFromPeer 108 // no response from the peer +#define InvResReceive 109 // invalid response received + +/* ++++++++++++++++++++++++++++++++ */ +/* the following codes is reserved */ +/* ++++++++++++++++++++++++++++++++ */ + +/* reserved operation codes */ +#define SndParam 9 // send parameter +#define ProcUnstrctSSData 19 // process unstructure SS data +#define PerformHo 28 // perform handover +#define PerformSubsHo 30 // perform subsequence handvoer +#define NoteInterHo 35 // note internal handover +#define NoteSubPrnt 48 // not subscriber present +#define AlrtSCWithoutRes 49 // alert service center without result +#define TraceSubAct 52 // trace subscriber activity +#define BeginSubAct 54 // beging subscriber activity + +/* reserved error codes */ +#define UnknwnBS 2 // unknowd base station +#define InvalidTBS 23 // invalid target base station +#define NoRRAvail 24 // no radio resource available + +/* MAP OPEN response result */ +#define OpenResultRefuse 0x01 +#define OpenResultAccept 0x02 + +/* MAP OPEN refuse result */ +#define ACNotSupported 0x01 +#define InvalidDesReference 0x02 // invalid destination reference +#define InvalidOrgReference 0x03 // invalid original reference +#define NoReasonGiven 0x04 +#define RemoteNodeNotReachable 0x05 +#define PotentialVerIncompat 0x06 // potential version incompatibility + +/* MAP CLOSE release method */ +#define NormalRelease 0x01 +#define PrearrangedEnd 0x02 + +/* MAP U-ABORT user reason */ +#define ResourceLimite 0x01 +#define ResourceUnavailable 0x02 +#define ApplicationCancel 0x03 +#define ProcedureError 0x04 + +/* MAP U-AOBRT diagnostic information */ +#define ShortTermProblem 0x01 +#define LongTermProblem 0x02 +#define HandoverCancel 0x03 +#define RadioChannelRelease 0x04 +#define NetworkPathRelease 0x05 +#define CallRelease 0x06 +#define AssociateProcedureFailure 0x07 +#define TandemDialogueRelease 0x08 +#define RemoteOperationFailure 0x09 + +/* MAP P-ABORT provider reason */ +#define ProviderMalfunction 0x01 +#define SupportingReleased 0x02 +#define ResourceLimitation 0x03 +#define MaintenanceActivity 0x04 +#define VersionIncompatibility 0x05 +#define AbnormalMAPDialogue 0x06 + +/* MAP P-ABORT source */ +#define MAPProblem 0x01 +#define TCProblem 0x02 +#define NetworkProblem 0x03 + +/* MAP NOTICE problem diagnostic */ +#define AbnormalEventDetect 0x01 +#define ResponseRejected 0x02 +#define AbnormalEventReceived 0x03 +#define MessageNotDelivered 0x04 + + + + + + + +/////////////////////////////////////lw add MAP V1 Modify + +#define SendParam 9 // send parameters +#define NoteSubPrnt 48 // not subscriber present +#define ProcUnstrctSSData 19 // process unstructure SS data +#define BeginSubAct 54 // beging subscriber activity +#define PerformHo 28 // perform handover +#define PerformSubsHo 30 // perform subsequence handvoer +#define NoteInterHo 35 // note internal handover +#define BeginSubAct 54 // beging subscriber activity +#define AlrtSCWithoutRes 49 // alert service center without result +#define TraceSubAct 52 // trace subscriber activity +////////////////////////////////////// + +/**** OPR VLR message ********/ +#define DetermineOprUser 128 +#define VlrUpdateLocation 129 +/**** OPR VLR message ********/ + +/**** OPR HLR message ********/ +#define CreateUserWithMsisdnImsi 130 +#define DeleteOprUser 131 +/**** OPR HLR message ********/ + +/**** IMDM VLR message ********/ +#define VlrEnquiryIMDMStatus 132 +/**** IMDM VLR message ********/ + +/***************** LCS **************/ +#define RoutingInfoForLCS 85 +#define ProvideSubscriberLocation 83 +/***************** LCS **************/ + + +///////////////////////////////////Jink add MNP AIN (ANSI TCAP) start +//National Operations code +#define ProvideInstructionStart 3 +// opr_ptr->message_type = ProvideInstructionStart; opr_ptr->message_flag = 1; +#define ConnectionControlConnect 4 +///////////////////////////////////Jink add MNP AIN (ANSI TCAP) end + + +#endif diff --git a/plat/xapp/src/mapp/map_code_auc.c b/plat/xapp/src/mapp/map_code_auc.c new file mode 100644 index 0000000..d59ea65 --- /dev/null +++ b/plat/xapp/src/mapp/map_code_auc.c @@ -0,0 +1,436 @@ +/* map coding auc service file */ +/* written by Liu Zhiguo 2002-06-03 */ +/* Version 2.0 */ +/* -------------------------------- */ + +#include "map_includes.h" + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding security triplets argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_securityTriplets_arg(struct MapST_Arg *ptr,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + u8 tag1 = 1; + char tlv1[8]; + + asn_encode(buf,&asn_buf); + + sprintf(tlv1, "4-%d", tag1++); + if(ptr->param_flag & 0x01) //imsi + buf_len = add_tlv(tlv1,IMSI_LEN,ptr->imsi,0x00,&asn_buf); + else + return RER; + sprintf(tlv1, "4-%d", tag1++); + if(ptr->param_flag & 0x02) //hlr_id + buf_len = add_tlv(tlv1,HLRID_LEN,ptr->hlr_id,0x00,&asn_buf); +/* sprintf(tlv1, "1-%d", tag1++); + if(ptr->param_flag & 0x04) + buf_len = add_tlv(tlv1, 1, (u8*)&ptr->choice_flag, 0x80, &asn_buf);*/ + + //quintuplet add by gxchen + if(version == 3) + { + sprintf(tlv1, "2-%d", tag1++); + if(ptr->param_flag & 0x04) + buf_len = add_tlv(tlv1, 1, &ptr->num_req_vec, 0x00, &asn_buf); + else + { + mapp_log_debug("version_4 assign security arg lack numberOfRequestedVectors"); +// return RER; //temp take out + } + sprintf(tlv1, "5-%d", tag1++); + if(ptr->param_flag & 0x08) + buf_len = add_tlv(tlv1, 1, &ptr->seg_prohibit, 0x00, &asn_buf); + sprintf(tlv1, "1-%d", tag1++); + if(ptr->param_flag & 0x10) + buf_len = add_tlv(tlv1, 1, &ptr->imm_res_prefer, 0x80, &asn_buf); + sprintf(tlv1, "16"); + if(ptr->param_flag & 0x20) + { + temp_len = assign_authReSynInfo(&ptr->resyn_info, temp_buf); + if(temp_len != RER) + buf_len = add_tlv(tlv1, temp_len, temp_buf, 0x20, &asn_buf); + } + sprintf(tlv1, "3-%d", tag1++); + if(ptr->param_flag & 0x40) + buf_len = add_tlv(tlv1, 1, (u8*)&ptr->node_type, 0x80, &asn_buf); + sprintf(tlv1, "4-%d", tag1++); + if(ptr->param_flag & 0x80) + buf_len = add_tlv(tlv1, 3, ptr->req_plmn_id, 0x80, &asn_buf); + sprintf(tlv1, "5-%d", tag1++); + if(ptr->param_flag & 0x100) + buf_len = add_tlv(tlv1, 1, &ptr->num_req_add_vec, 0x80, &asn_buf); + sprintf(tlv1, "6-%d", tag1++); + if(ptr->param_flag & 0x200) + buf_len = add_tlv(tlv1, 1, &ptr->add_vec_eps, 0x80, &asn_buf); + } + + return buf_len; +} + +int extract_securityTriplets_arg(struct MapST_Arg *ptr,u32 buf_len,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + u8 tag1 = 1; + char tlv1[8]; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_securityTriplets_arg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ptr->param_flag = 0; + + sprintf(tlv1, "4-%d", tag1++); + len = get_tlv(tlv1,temp_buf,&asn_buf); + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0 ) //imsi + { + ptr->param_flag |= 0x01; + memcpy(ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("%s: lack IMSI", __FUNCTION__); + return RER; + } + sprintf(tlv1, "4-%d", tag1++); + if((len=get_tlv(tlv1,temp_buf,&asn_buf)) == HLRID_LEN ) //hlr_id + { + ptr->param_flag |= 0x02; + memcpy(ptr->hlr_id,temp_buf,len); + } +/* sprintf(tlv1, "1-%d", tag1++); + if((get_tlv(tlv1, temp_buf, &asn_buf)) == 1) //choice_flag + { + ptr->param_flag |= 0x04; + ptr->choice_flag = temp_buf[0]; + }*/ + + //quintuplet add by gxchen + if(version == 3) + { + sprintf(tlv1, "2-%d", tag1++); + if(get_tlv(tlv1, temp_buf, &asn_buf) == 1) + { + ptr->param_flag |= 0x04; + ptr->num_req_vec = temp_buf[0]; + } + else + { + mapp_log_debug("%s: lack numberOfRequestedVectors", __FUNCTION__); +// return RER; //temp take out + } + sprintf(tlv1, "5-%d", tag1++); + if(get_tlv(tlv1, temp_buf, &asn_buf) == 1) + { + ptr->param_flag |= 0x08; + ptr->seg_prohibit = temp_buf[0]; + } + sprintf(tlv1, "1-%d", tag1++); + if(get_tlv(tlv1, temp_buf, &asn_buf) == 1) + { + ptr->param_flag |= 0x10; + ptr->imm_res_prefer = temp_buf[0]; + } + sprintf(tlv1, "16"); + if((len = get_tlv(tlv1, temp_buf, &asn_buf)) > 0) + { + ptr->param_flag |= 0x20; + extract_authReSynInfo(&ptr->resyn_info, len, temp_buf); + } + sprintf(tlv1, "3-%d", tag1++); + if(get_tlv(tlv1, temp_buf, &asn_buf) == 1) + { + ptr->param_flag |= 0x40; + ptr->node_type = temp_buf[0]; + } + sprintf(tlv1, "4-%d", tag1++); + if(get_tlv(tlv1, temp_buf, &asn_buf) > 0) + { + ptr->param_flag |= 0x80; + memcpy(ptr->req_plmn_id, temp_buf, 3); + } + sprintf(tlv1, "5-%d", tag1++); + if(get_tlv(tlv1, temp_buf, &asn_buf) == 1) + { + ptr->param_flag |= 0x100; + ptr->num_req_add_vec = temp_buf[0]; + } + sprintf(tlv1, "6-%d", tag1++); + if(get_tlv(tlv1, temp_buf, &asn_buf) == 1) + { + ptr->param_flag |= 0x200; + ptr->add_vec_eps = temp_buf[0]; + } + } + + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding security triplets response */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_securityTriplets_res(struct MapST_Res *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int ii; + char tlv1[32]; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if ((ptr->param_flag & 0x2) == 0) + { + mapp_log_debug("MAPP--assign_securityTriplets_res flag=0"); + return RER; + } + if(ptr->param_flag & 0x01) + buf_len = add_tlv("1", 1, (u8*)&ptr->choice_flag, 0x80, &asn_buf); + + if(ptr->choice_flag == AUTH_LIST_QUINTUPLET) //add by gxchen + { + if (ptr->choice.quin_list.quin_len > AUTHLIST_LEN) + { + mapp_log_debug("MAPP--assign_securityTriplets_res quintuplet auth_len>AUTHLIST_LEN"); + return RER; + } + for(ii = 0; ii < ptr->choice.quin_list.quin_len && ii < 1; ii ++) + { + temp_len = assign_quintuplet(&ptr->choice.quin_list.quintuplet[ii], temp_buf); + if(temp_len == RER) + break; + sprintf(tlv1, "16-%d", ii+1); + buf_len = add_tlv(tlv1, temp_len, temp_buf, 0x20, &asn_buf); + } + } + else + { + if (ptr->choice.tri_list.tri_len > AUTHLIST_LEN) + { + mapp_log_debug("MAPP--assign_securityTriplets_res auth_len>AUTHLIST_LEN"); + return RER; + } + for (ii = 0;ii < ptr->choice.tri_list.tri_len;ii ++) + { + temp_len = assign_authset((AuthSet_struct*)&ptr->choice.tri_list.triplet[ii],temp_buf); + if (temp_len == RER) + break; + sprintf(tlv1,"16-%d",ii+1); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x20,&asn_buf); + } + } + + return buf_len; +} + +int extract_securityTriplets_res(struct MapST_Res *ptr,u32 buf_len,u8 *buf) +{ + u8 temp_buf[256]; + char tlv1[32]; + int ii; + int len; + ASN_BUF asn_buf; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_securityTriplets_res buf_len=0"); + return ROK; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ptr->param_flag = 0; + + //add by gxchen + if((get_tlv("1", temp_buf, &asn_buf)) == 1) //choice flag + { + ptr->param_flag |= 0x01; + ptr->choice_flag = temp_buf[0]; + } + if(ptr->choice_flag == AUTH_LIST_QUINTUPLET) //quintuplet + { + ptr->choice.quin_list.quin_len = 0; + for(ii = 0; ii < AUTHLIST_LEN; ii++) + { + sprintf(tlv1, "16-%d", ii+1); + len = get_tlv(tlv1, temp_buf, &asn_buf); + if(len <= 0) //has not data + break; + if(!extract_quintuplet(&ptr->choice.quin_list.quintuplet[ii], len, temp_buf)) + break; + ptr->param_flag |= 0x02; + ptr->choice.quin_list.quin_len++; + } + } + else + { + ptr->choice.tri_list.tri_len = 0; + for(ii = 0;ii < AUTHLIST_LEN;ii ++) + { + sprintf(tlv1,"16-%d",ii+1); + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len == -1) + break; + if (!extract_authset((AuthSet_struct*)&ptr->choice.tri_list.triplet[ii],len,temp_buf)) + break; + ptr->param_flag |= 0x02; + ptr->choice.tri_list.tri_len++; + } + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding interrogation subscriber argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_interrogateSubscriber_arg(struct MapIS_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if(flag & 0x01) //imsi + buf_len = add_tlv("4-1",IMSI_LEN,ptr->imsi,0x00,&asn_buf); + else + return RER; + if(flag & 0x02) //hlr_id + buf_len = add_tlv("4-2",HLRID_LEN,ptr->hlr_id,0x00,&asn_buf); + return buf_len; +} + +int extract_interrogateSubscriber_arg(struct MapIS_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_interrogateSubscriber_arg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ptr->param_flag = 0; + len = get_tlv("4-1",temp_buf,&asn_buf); + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0 )//imsi + { + ptr->param_flag|=0x01; + memcpy(ptr->imsi,temp_buf,len); + } + else + return RER; + if((get_tlv("4-2",temp_buf,&asn_buf)) == HLRID_LEN)//hlr_id + { + ptr->param_flag |= 0x02; + memcpy(ptr->hlr_id,temp_buf,HLRID_LEN); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding create subscriber argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_createSubscriber_arg(struct MapCS_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if(flag & 0x01) //imsi + buf_len = add_tlv("4-1",IMSI_LEN,ptr->imsi,0x00,&asn_buf); + else + return RER; + if(flag & 0x02) //hlr_id + buf_len = add_tlv("4-2",HLRID_LEN,ptr->hlr_id,0x00,&asn_buf); + return buf_len; +} + +int extract_createSubscriber_arg(struct MapCS_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_createSubscriber_arg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ptr->param_flag = 0; + len = get_tlv("4-1",temp_buf,&asn_buf); + if(len == IMSI_LEN && (temp_buf[7]&0xf0) == 0xf0) //imsi + { + ptr->param_flag |= 0x01; + memcpy(ptr->imsi,temp_buf,len); + } + if((get_tlv("4-2",temp_buf,&asn_buf))==HLRID_LEN) //hlr_id + { + ptr->param_flag |= 0x02; + memcpy(ptr->hlr_id,temp_buf,HLRID_LEN); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding delete subscriber argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_deleteSubscriber_arg(struct MapDS_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if(flag & 0x01) //imsi + buf_len = add_tlv("4-1",IMSI_LEN,ptr->imsi,0x00,&asn_buf); + else + return RER; + if(flag & 0x02) //hlr_id + buf_len = add_tlv("4-2",HLRID_LEN,ptr->hlr_id,0x00,&asn_buf); + return buf_len; +} + +int extract_deleteSubscriber_arg(struct MapDS_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_createSubscriber_arg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ptr->param_flag = 0; + len = get_tlv("4-1",temp_buf,&asn_buf); + if(len == IMSI_LEN && (temp_buf[7]&0xf0) == 0xf0) //imsi + { + ptr->param_flag |= 0x01; + memcpy(ptr->imsi,temp_buf,len); + } + if((get_tlv("4-2",temp_buf,&asn_buf))==HLRID_LEN) //hlr_id + { + ptr->param_flag |= 0x02; + memcpy(ptr->hlr_id,temp_buf,HLRID_LEN); + } + return ROK; +} diff --git a/plat/xapp/src/mapp/map_code_ch.c b/plat/xapp/src/mapp/map_code_ch.c new file mode 100644 index 0000000..4fb642c --- /dev/null +++ b/plat/xapp/src/mapp/map_code_ch.c @@ -0,0 +1,1937 @@ +/* mapp coding call handling c file */ +/* written by Liu Zhiguo 2003-03-04 */ +/* Version 2.0 */ +/* -------------------------------- */ + +#include "map_includes.h" + +int assign_cugcheckinfo(struct CugChkInfo_struct *cci_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (cci_ptr->param_flag & 0x01) + buf_len = add_tlv("4",CUGLOCK_LEN,cci_ptr->cug_intlock,0x00,&asn_buf); + if (cci_ptr->param_flag & 0x02) + buf_len = add_null("5",0x00,&asn_buf); + return buf_len; +} + +int extract_cugcheckinfo(struct CugChkInfo_struct *cci_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + cci_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); + if (len == CUGLOCK_LEN) + { + cci_ptr->param_flag |= 0x01; + memcpy(cci_ptr->cug_intlock,temp_buf,CUGLOCK_LEN); + } + len = get_null("5",&asn_buf); + if (len != -1) + cci_ptr->param_flag |= 0x02; + return ROK; +} + +int assign_fwddata(struct FwdData_struct *fwd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (fwd_ptr->param_flag & 0x01) //fwd num + { + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,fwd_ptr->fwd_num[0],fwd_ptr->fwd_num+1,0x80,&asn_buf); + } + if (fwd_ptr->param_flag & 0x02) // fwd to sub addr + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_tlv(tlv1,fwd_ptr->fwd_subadd[0],fwd_ptr->fwd_subadd+1,0x80,&asn_buf); + } + if (fwd_ptr->param_flag & 0x04) //fwd option + { + sprintf(tlv1,"6-%d",tag1++); + buf_len = add_tlv(tlv1,1,&fwd_ptr->fwd_option,0x80,&asn_buf); + } + return buf_len; +} + +int extract_fwddata(struct FwdData_struct *fwd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + fwd_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("5",temp_buf,&asn_buf); + if (len != -1 && len <= ISDN_LEN) // fwd num + { + fwd_ptr->param_flag |= 0x01; + fwd_ptr->fwd_num[0] = len; + memcpy(fwd_ptr->fwd_num+1,temp_buf,len); + } + len = get_tlv("4",temp_buf,&asn_buf); + if (len != -1 && len <= ISDNSUB_LEN) // fwd subadd + { + fwd_ptr->param_flag |= 0x02; + fwd_ptr->fwd_subadd[0] = len; + memcpy(fwd_ptr->fwd_subadd+1,temp_buf,len); + } + if (get_tlv("6",temp_buf,&asn_buf) == 1) // fwd option + { + fwd_ptr->param_flag |= 0x04; + fwd_ptr->fwd_option = temp_buf[0]; + } + return ROK; +} + +int assign_tcsi(struct TCsi_struct *tcsi_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + u8 ii; + int buf_len=0; + u8 temp_len; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (tcsi_ptr->tdpdata_list.tdpdata_len > TDPDATA_NUM) + return RER; + buf_len = add_null("16",0x20,&asn_buf); + for (ii = 0;ii < tcsi_ptr->tdpdata_list.tdpdata_len;ii ++) //o-BCSM Camel TDP Data List + { + sprintf(tlv1,"16.16-%d",ii+1); + buf_len = add_null(tlv1,0x20,&asn_buf); + sprintf(tlv1,"16.16-%d.10-1",ii+1); + buf_len = add_int(tlv1,tcsi_ptr->tdpdata_list.tdp_data[ii].det_point,0x00,&asn_buf); + sprintf(tlv1,"16.16-%d.2-2",ii+1); + buf_len = add_int(tlv1,tcsi_ptr->tdpdata_list.tdp_data[ii].service_key,0x00,&asn_buf); + sprintf(tlv1,"16.16-%d.0-3",ii+1); + temp_len = tcsi_ptr->tdpdata_list.tdp_data[ii].scf_add[0]; + buf_len = add_tlv(tlv1,temp_len,tcsi_ptr->tdpdata_list.tdp_data[ii].scf_add+1,0x80,&asn_buf); + sprintf(tlv1,"16.16-%d.1-4",ii+1); + buf_len = add_int(tlv1,tcsi_ptr->tdpdata_list.tdp_data[ii].def_hand,0x80,&asn_buf); + } + if (tcsi_ptr->param_flag & 0x02) //camel capability Handling + buf_len = add_int("0-2",tcsi_ptr->camel_caphand,0x80,&asn_buf); + return buf_len; +} + +int extract_tcsi(struct TCsi_struct *tcsi_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 ii,jj; + u8 temp_buf[256]; + char tlv1[32]; + + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + tcsi_ptr->tdpdata_list.tdpdata_len = 0; + for (ii = 0;ii < TDPDATA_NUM;ii ++) + { + jj = tcsi_ptr->tdpdata_list.tdpdata_len; + sprintf(tlv1,"16.16-%d",ii+1); + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len == -1) + break; + sprintf(tlv1,"16.16-%d.10",ii+1); // det_point + if (get_tlv(tlv1,temp_buf,&asn_buf) != 1) + return RER; + tcsi_ptr->tdpdata_list.tdp_data[jj].det_point = temp_buf[0]; + sprintf(tlv1,"16.16-%d.2",ii+1); // service key + len = get_int(tlv1,&asn_buf); + if (len == -1) + return RER; + tcsi_ptr->tdpdata_list.tdp_data[jj].service_key = len; + sprintf(tlv1,"16.16-%d.0",ii+1); // scf address + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len == -1 || len > ISDN_LEN) + return RER; + tcsi_ptr->tdpdata_list.tdp_data[jj].scf_add[0] = len; + memcpy(tcsi_ptr->tdpdata_list.tdp_data[jj].scf_add+1,temp_buf,len); + sprintf(tlv1,"16.16-%d.1",ii+1); // default call handling + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len != 1) + return RER; + tcsi_ptr->tdpdata_list.tdp_data[jj].def_hand = temp_buf[0]; + tcsi_ptr->tdpdata_list.tdpdata_len ++; + } + tcsi_ptr->param_flag |= 0x01; + if (get_tlv("0",temp_buf,&asn_buf) == 1) + { + tcsi_ptr->param_flag |= 0x02; + tcsi_ptr->camel_caphand = temp_buf[0]; + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send routing info argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndroutinfoarg(struct MapSRI_Arg *sri_ptr,u8 *buf, u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = sri_ptr->param_flag; + if (flag & 0x01) // has MSISDN + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,sri_ptr->msisdn[0],sri_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter + } + else + { + mapp_log_debug("send routing information loss MSISDN"); + return RER; + } + if (flag & 0x02) // has CUG check info + { + sprintf(tlv1,"1-%d",tag1++); + temp_len = assign_cugcheckinfo(&sri_ptr->chk_info,temp_buf); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (flag & 0x04) //has number of forwarding + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&sri_ptr->fwd_num,0x80,&asn_buf); + } + if (flag & 0x08 && ver >1) //interrogation type + { + sprintf(tlv1,"3-%d",tag1++); + temp_buf[0] = sri_ptr->inter_type; + buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf); + } + if (flag & 0x10 && ver >1) //or-interrogation + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x20 && ver >1) // or-capability + { + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,1,&sri_ptr->or_cap,0x80,&asn_buf); + } + if (flag & 0x40 && ver >1)// gmsc addr + { + sprintf(tlv1,"6-%d",tag1++); + buf_len = add_tlv(tlv1,sri_ptr->gmsc_add[0],sri_ptr->gmsc_add+1,0x80,&asn_buf); + } + if (flag & 0x80 && ver >1) // call ref num + { + sprintf(tlv1,"7-%d",tag1++); + buf_len = add_tlv(tlv1,sri_ptr->callref_num[0],sri_ptr->callref_num+1,0x80,&asn_buf); + } + if (flag & 0x100 && ver >1) // fwd reason num + { + sprintf(tlv1,"8-%d",tag1++); + temp_buf[0] = sri_ptr->fwd_reason; + buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf); + } + if(flag & 0x200 && ver >1 ) //bs group + { + sprintf(tlv1,"9-%d",tag1++); + temp_len = assign_bscode(&sri_ptr->bs_group,temp_buf,0); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (flag & 0x400) // net info + { + sprintf(tlv1,"10-%d",tag1++); + temp_len = assign_extsiginfo(&sri_ptr->net_info,temp_buf); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (flag & 0x800 && ver >1) //camelInfo + { + if (sri_ptr->camel_info.param_flag & 0x01) + { + sprintf(tlv1,"11-%d.3",tag1); + buf_len = add_tlv(tlv1,2,sri_ptr->camel_info.camel_phase,0x00,&asn_buf); + } + if (sri_ptr->camel_info.param_flag & 0x02) //suppress-T-CSI + { + sprintf(tlv1,"11-%d.5",tag1); + buf_len = add_null(tlv1,0x00,&asn_buf); + } + tag1 ++; + } + if (flag & 0x1000 && ver >1) //suppression Of Announcement + { + sprintf(tlv1,"12-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x2000 && ver >1) //alerting Pattern + { + sprintf(tlv1,"14-%d",tag1++); + buf_len = add_tlv(tlv1,1,&sri_ptr->alt_pattern,0x80,&asn_buf); + } + if (flag & 0x4000 && ver >1) //ccbs-Call + { + sprintf(tlv1,"15-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x8000 && ver >1) //supported CCBS phase + { + sprintf(tlv1,"16-%d",tag1++); + buf_len = AddInteger(tlv1,sri_ptr->ccbs_phase,0x80,&asn_buf); + } + return buf_len; +} + +int extract_sndroutinfoarg(struct MapSRI_Arg *sri_ptr,u32 buf_len,u8 *buf , u8 ver) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + sri_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get MSISDN + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x01; + sri_ptr->msisdn[0] = len; + memcpy(sri_ptr->msisdn+1,temp_buf,len); + } + else + { + mapp_log_debug("extract_sndroutinfoarg:loss MSISDN"); + return RER; + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 0) // CUG-checkInfo + { + flag |= 0x02; + extract_cugcheckinfo(&sri_ptr->chk_info,len,temp_buf); + } + + len = get_tlv("2",temp_buf,&asn_buf); //number Of Forwarding + if (len == 1) + { + sri_ptr->fwd_num = temp_buf[0]; + flag |= 0x04; + } + + if( ver > 1 ) + { + if (GetInteger("3",(int *)&sri_ptr->inter_type,0x80,&asn_buf) > 0) //interrogation type + flag |= 0x08; + if (get_null("4",&asn_buf) > 0 ) //or-Interrogation + { + flag |= 0x10; + sri_ptr->or_inter = 1; + } + len = get_tlv("5",temp_buf,&asn_buf); //or-capability + if (len == 1) + { + sri_ptr->or_cap = temp_buf[0]; + flag |= 0x20; + } + len = get_tlv("6",temp_buf,&asn_buf); //gmsc-Address + if (len > 1 && len <= ISDN_LEN) + { + flag |= 0x40; + sri_ptr->gmsc_add[0] = len; + memcpy(sri_ptr->gmsc_add+1,temp_buf,len); + } + len = get_tlv("7",temp_buf,&asn_buf); //call Reference Number + if (len > 0 && len <= CALLREF_NUM) + { + flag |= 0x80; + sri_ptr->callref_num[0] = len; + memcpy(sri_ptr->callref_num+1,temp_buf,len); + } + if (GetInteger("8",(int *)&sri_ptr->fwd_reason,0x80,&asn_buf) > 0) //forwarding Reason + flag |= 0x100; + len = get_tlv("9",temp_buf,&asn_buf); //basicServiceGroup + if (len > 0) + { + flag |= 0x200; + extract_bscode(&sri_ptr->bs_group,len,temp_buf); + } + } + + len = get_tlv("10",temp_buf,&asn_buf); //networkSignalInfo + if (len > 0) + { + flag |= 0x400; + extract_extsiginfo(&sri_ptr->net_info,len,temp_buf); + } + + if( ver > 1 ) + { + len = get_tlv("11.3",temp_buf,&asn_buf); //camelInfo=>supported camel phases + if (len != -1) + { + memcpy(sri_ptr->camel_info.camel_phase,temp_buf,3); + sri_ptr->camel_info.param_flag |= 0x01; + flag |= 0x800; + } + if (get_null("11.5", &asn_buf) >= 0) //camelInfo=>suppress-T-CSI + { + sri_ptr->camel_info.supp_tcsi = 1; + sri_ptr->camel_info.param_flag |= 0x02; + flag |= 0x800; + } + if (get_null("12", &asn_buf) >= 0) //suppression of announcement + { + sri_ptr->supp_ann = 1; + flag |= 0x1000; + } + if (get_tlv("14",temp_buf,&asn_buf) == 1) //alertingPattern + { + sri_ptr->alt_pattern = temp_buf[0]; + flag |= 0x2000; + } + if (get_null("15",&asn_buf) >= 0) //ccbs-Call + { + sri_ptr->ccbs_call = 1; + flag |= 0x4000; + } + if (get_tlv("16",temp_buf,&asn_buf) == 1) //supportedCCBS phase + { + sri_ptr->ccbs_phase = temp_buf[0]; + flag |= 0x8000; + } + } + sri_ptr->param_flag = flag; + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send routing info response */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndroutinfores(struct MapSRI_Res *sri_ptr,u8 *buf,u8 version) +{ + ASN_BUF asn_buf; + u32 flag; + u32 temp_flag; + int len=0, jj; + int buf_len = 0; + int tag1=1,tag2=1; + char tlv1[32],tlv2[32]; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + flag = sri_ptr->param_flag; + if (flag & 0x01) // has IMSI + { + if (version <= 1) + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,sri_ptr->imsi,0x00,&asn_buf); + } + else + { + sprintf(tlv1,"9-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,sri_ptr->imsi,0x80,&asn_buf); + } + } + if (flag & 0x02) // has ext routing information + { + if (sri_ptr->rout_info.choice_flag == 1) // route info + { + if (sri_ptr->rout_info.choice.rout_info.choice_flag == 1)//roam num + { + sprintf(tlv1,"4-%d",tag1); + len = sri_ptr->rout_info.choice.rout_info.choice.roam_num[0]; + buf_len = add_tlv(tlv1,len,sri_ptr->rout_info.choice.rout_info.choice.roam_num+1,0x00,&asn_buf); + } + else if (sri_ptr->rout_info.choice.rout_info.choice_flag == 2)//fwd data + { + temp_len = assign_fwddata(&sri_ptr->rout_info.choice.rout_info.choice.fwd_data,temp_buf); + sprintf(tlv1,"16-%d",tag1);//tag1,forwardingData + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x20,&asn_buf); + } + } + else if (sri_ptr->rout_info.choice_flag == 2 && version >1 ) //camel Routing Info + { + tag2 = 1; + if (sri_ptr->rout_info.choice.camel_info.param_flag & 0x01) //forwardingData + { + temp_len = assign_fwddata(&sri_ptr->rout_info.choice.camel_info.fwd_data,temp_buf); + sprintf(tlv1,"8-%d.16-%d",tag1,tag2++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x20,&asn_buf); + } + if (sri_ptr->rout_info.choice.camel_info.param_flag & 0x02) //gmscCamelSubscriptionInfo + { + sprintf(tlv1,"8-%d.0-%d",tag1,tag2); + if (sri_ptr->rout_info.choice.camel_info.subs_info.param_flag & 0x01) //t-CSI + { + temp_len = assign_tcsi(&sri_ptr->rout_info.choice.camel_info.subs_info.t_csi,temp_buf); + sprintf(tlv2,"%s.0-1",tlv1); + buf_len = add_tlv(tlv2,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (sri_ptr->rout_info.choice.camel_info.subs_info.param_flag & 0x02) //o-CSI + { + temp_len = assign_ocsi(&sri_ptr->rout_info.choice.camel_info.subs_info.o_csi,temp_buf); + sprintf(tlv2,"%s.1-2",tlv1); + buf_len = add_tlv(tlv2,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (sri_ptr->rout_info.choice.camel_info.subs_info.param_flag & 0x04) //o-BcsmCamelTDP-CriteriaList + { + temp_len = assign_tdpcritlist(&sri_ptr->rout_info.choice.camel_info.subs_info.ob_list,temp_buf); + sprintf(tlv2,"%s.3-3",tlv1); + buf_len = add_tlv(tlv2,temp_len,temp_buf,0x0a0,&asn_buf); + } + } + } + tag1 ++; + } + if (flag & 0x04) //cug-checkInfo + { + sprintf(tlv1,"3-%d",tag1++); + temp_len = assign_cugcheckinfo(&sri_ptr->cugchk_info,temp_buf); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if( version >1 ) + { + if (flag & 0x08) //cugSubscription Flag + { + sprintf(tlv1,"6-%d",tag1++); + buf_len = add_null(tlv1,0x00,&asn_buf); + } + if (flag & 0x10) //subscriberInfo + { + temp_len = assign_subinfo(&sri_ptr->sub_info,temp_buf); + sprintf(tlv1,"7-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (flag & 0x20) //ss-List + { + if (sri_ptr->ss_list.sslist_len > SS_LEN) + { + mapp_log_debug("assign_sndroutinfores: sslist_len > SS_LEN"); + return RER; + } + for(jj = 0;jj < sri_ptr->ss_list.sslist_len;jj ++) + { + sprintf(tlv1,"1-%d.4-%d",tag1,jj+1); + buf_len = add_tlv(tlv1,1,&sri_ptr->ss_list.ss_code[jj],0x00,&asn_buf); + } + tag1 ++; + } + if (flag & 0x40) //basicService + { + temp_len = assign_bscode(&sri_ptr->bs_code,temp_buf,0); + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (flag & 0x80) //forwarding Interrogation Required + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x100) //vmsc-Address + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,sri_ptr->vmsc_add[0],sri_ptr->vmsc_add+1,0x80,&asn_buf); + } + if (flag & 0x200) //naea-PreferredCI + { + sprintf(tlv1,"10-%d.0",tag1++); + buf_len = add_tlv(tlv1,NAEA_LEN,sri_ptr->naea_ci.cic,0x80,&asn_buf); + } + if((flag & 0x400) == 0x400) //ccbs-Indicators + { + tag2 = 1; + temp_flag = sri_ptr->ccbs_ind.param_flag; + if (temp_flag & 0x01) //ccbs-Possible + { + sprintf(tlv1,"11-%d.0-%d",tag1,tag2++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if(temp_flag & 0x02) //kepCCBS-CalIndicator + { + sprintf(tlv1,"11-%d.1-%d",tag1,tag2++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + tag1++; + } + if((flag & 0x800) == 0x800) //mnp indicator + { + sprintf(tlv1,"13-%d",tag1++); + temp_buf[0] = sri_ptr->mnp_indicator; + buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf); + } + } + return buf_len; +} + +int extract_sndroutinfores(struct MapSRI_Res *sri_ptr,u32 buf_len,u8 *buf,u8 version) +{ + ASN_BUF asn_buf; + u8 ii,jj; + int len; + int temp_len; + u8 temp_buf[256]; + u8 tag1; + char tlv1[32]; + u32 flag=0; + + sri_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + tag1 = 1; + if (version <= 1) + len = get_tlv("4-1",temp_buf,&asn_buf); + else + len = get_tlv("9",temp_buf,&asn_buf); //imsi + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + flag |= 0x01; + memcpy(sri_ptr->imsi,temp_buf,len); + tag1 ++; + } + else + mapp_log_debug("extract_sndroutinfores: no IMSI"); + sprintf(tlv1,"4-%d",tag1); + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len > 0) // roaming number + { + flag |= 0x02; + sri_ptr->rout_info.choice_flag = 1; + sri_ptr->rout_info.choice.rout_info.choice_flag = 1; + sri_ptr->rout_info.choice.rout_info.choice.roam_num[0] = len; + memcpy(sri_ptr->rout_info.choice.rout_info.choice.roam_num+1,temp_buf,len); + tag1 ++; + } + else + { + len = get_tlv("16",temp_buf,&asn_buf); //forwarding data + if (len != -1) + { + flag |= 0x02; + sri_ptr->rout_info.choice_flag = 1; + sri_ptr->rout_info.choice.rout_info.choice_flag = 2; + if (!extract_fwddata(&sri_ptr->rout_info.choice.rout_info.choice.fwd_data,len,temp_buf)) + return RER; + tag1 ++; + } + else if( version >1 ) + { + len = get_tlv("8",temp_buf,&asn_buf); // camelRoutingInfo + if (len != -1) + { + flag |= 0x02; + sri_ptr->rout_info.choice_flag = 2; + sri_ptr->rout_info.choice.camel_info.param_flag = 0; + temp_len = get_tlv("8.16",temp_buf,&asn_buf); // fwd data + if (temp_len != -1) + { + sri_ptr->rout_info.choice.camel_info.param_flag |= 0x01; + if (!extract_fwddata(&sri_ptr->rout_info.choice.camel_info.fwd_data,temp_len,temp_buf)) + return RER; + } + temp_len = get_tlv("8.0",temp_buf,&asn_buf); //gmscCamelSubscriptionInfo + if (temp_len != -1) + { + sri_ptr->rout_info.choice.camel_info.param_flag |= 0x02; + sri_ptr->rout_info.choice.camel_info.subs_info.param_flag = 0; + temp_len = get_tlv("8.0.0",temp_buf,&asn_buf); // t-CSI + if (temp_len != -1) + { + sri_ptr->rout_info.choice.camel_info.subs_info.param_flag |= 0x01; + if (!extract_tcsi(&sri_ptr->rout_info.choice.camel_info.subs_info.t_csi,temp_len,temp_buf)) + return RER; + } + temp_len = get_tlv("8.0.1",temp_buf,&asn_buf); // o-CSI + if (temp_len != -1) + { + sri_ptr->rout_info.choice.camel_info.subs_info.param_flag |= 0x02; + if (!extract_ocsi(&sri_ptr->rout_info.choice.camel_info.subs_info.o_csi,temp_len,temp_buf)) + return RER; + } + temp_len = get_tlv("8.0.3",temp_buf,&asn_buf); //o-BcsmCamelTDP-CrteriaList + if (temp_len != -1) + { + sri_ptr->rout_info.choice.camel_info.subs_info.param_flag |= 0x04; + if (!extract_tdpcritlist(&sri_ptr->rout_info.choice.camel_info.subs_info.ob_list,temp_len,temp_buf)) + return RER; + } + } + tag1 ++; + } + } + } + len = get_tlv("3",temp_buf,&asn_buf); //cug-CheckInfo + if (len != -1) + { + if (!extract_cugcheckinfo(&sri_ptr->cugchk_info,len,temp_buf)) + return RER; + flag |= 0x04; + tag1 ++; + } + if( version > 1 ) + { + if (get_tlv("6",temp_buf,&asn_buf) != -1) //cug Subscription flag + { + flag |= 0x08; + sri_ptr->cugsubs_flag = 1; + tag1 ++; + } + len = get_tlv("7",temp_buf,&asn_buf); //subscriber info + if (len != -1) + { + flag |= 0x10; + if (!extract_subinfo(&sri_ptr->sub_info,len,temp_buf)) + return RER; + tag1 ++; + } + if (get_tlv("1",temp_buf,&asn_buf) != -1) + { + flag |= 0x20; + sri_ptr->ss_list.sslist_len = 0; + for (ii = 0;ii < SS_LEN;ii ++) + { + jj = sri_ptr->ss_list.sslist_len; + sprintf(tlv1,"1.4-%d",ii+1); + if (get_tlv(tlv1,temp_buf,&asn_buf) != 1) + break; + sri_ptr->ss_list.ss_code[jj] = temp_buf[0]; + sri_ptr->ss_list.sslist_len ++; + } + tag1 ++; + } + len = get_tlv("5",temp_buf,&asn_buf); //basicService + if (len != -1) + { + flag |= 0x40; + if (!extract_bscode(&sri_ptr->bs_code,len,temp_buf)) + return RER; + tag1 ++; + } + sprintf(tlv1,"4-%d",tag1); + len = get_null(tlv1,&asn_buf); //forwarding Interrogation Required + if (len != -1) + { + flag |= 0x80; + tag1 ++; + } + len = get_tlv("2",temp_buf,&asn_buf); //vmsc-Address + if (len != -1 && len < ISDN_LEN) + { + flag |= 0x100; + sri_ptr->vmsc_add[0] = len; + memcpy(sri_ptr->vmsc_add+1,temp_buf,len); + tag1 ++; + } + if(get_tlv("10.0",temp_buf,&asn_buf) == NAEA_LEN) + { + flag |= 0x200; + memcpy(sri_ptr->naea_ci.cic,temp_buf,NAEA_LEN); + tag1 ++; + } + if (get_tlv("11",temp_buf,&asn_buf) != -1) //ccbs-Indicator + { + flag |= 0x400; + if (get_null("11.0",&asn_buf) > 0) //ccbs-Possible + { + sri_ptr->ccbs_ind.param_flag |= 0x01; + sri_ptr->ccbs_ind.ccbs_possible = 1; + } + if(get_null("11.1", &asn_buf) > 0) //keepCCBS-CallIndicator + { + sri_ptr->ccbs_ind.param_flag |= 0x02; + sri_ptr->ccbs_ind.ccbs_indicator = 1; + } + tag1 ++; + } + if (get_tlv("13",temp_buf,&asn_buf) == 1 ) //mnp indicator + { + flag |= 0x800; + sri_ptr->mnp_indicator = temp_buf[0]; + tag1 ++; + } + } + sri_ptr->param_flag = flag; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding provider roaming num argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_provroamnumarg(MapPRN_Arg *prn_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len; + int temp_len; + u8 temp_buf[256]; + int tag1=1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = prn_ptr->param_flag; + if(flag & 0x01) // imsi + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,prn_ptr->imsi,0x80,&asn_buf); + } + else + { + mapp_log_debug("Error:assign_prroamnumarg: lack imsi"); + return RER; + } + if (flag & 0x02) //msc number + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,prn_ptr->msc_num[0],prn_ptr->msc_num+1,0x80,&asn_buf); + } + else + { + mapp_log_debug("assign_prroamnumarg: lack msc number"); + return RER; + } + if (flag & 0x04) //msisdn number + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,prn_ptr->msisdn[0],prn_ptr->msisdn+1,0x80,&asn_buf); + } + if (flag & 0x08) // lmsi + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_tlv(tlv1,LMSI_LEN,prn_ptr->lmsi,0x80,&asn_buf); + } + if (flag & 0x10) // bearer capability + { + temp_len = assign_extsiginfo(&prn_ptr->bearer_cap,temp_buf); + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (flag & 0x20) // net info + { + temp_len = assign_extsiginfo(&prn_ptr->net_info,temp_buf); + sprintf(tlv1,"6-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (flag & 0x40) // suppression of announcement + { + sprintf(tlv1,"7-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x80) // gmsc address + { + sprintf(tlv1,"8-%d",tag1++); + buf_len = add_tlv(tlv1,prn_ptr->gmsc_add[0],prn_ptr->gmsc_add+1,0x80,&asn_buf); + } + if (flag & 0x100) // call reference number + { + sprintf(tlv1,"9-%d",tag1++); + buf_len = add_tlv(tlv1,prn_ptr->callref_num[0],prn_ptr->callref_num+1,0x80,&asn_buf); + } + if (flag & 0x200) // or interrogation + { + sprintf(tlv1,"10-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x400) // alert pattern + { + sprintf(tlv1,"12-%d",tag1++); + buf_len = add_tlv(tlv1,1,&prn_ptr->alt_pattern,0x80,&asn_buf); + } + if (flag & 0x800) // ccbs call + { + sprintf(tlv1,"13-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x1000) // supproted camel phase in gmsc + { + sprintf(tlv1,"14-%d",tag1++); + buf_len = add_tlv(tlv1,3,prn_ptr->camel_phase,0x80,&asn_buf); + } + return buf_len; +} + +int extract_provroamnumarg(struct MapPRN_Arg *prn_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag=0; + + prn_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + flag |= 0x01; + memcpy(prn_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("extract_prroamnumarg:lack imsi"); + return RER; + } + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 2 && len <= ISDN_LEN) + { + flag |= 0x02; + prn_ptr->msc_num[0] = len; + memcpy(prn_ptr->msc_num+1,temp_buf,len); + } + else + { + mapp_log_debug("extract_prroamnumarg:lack msc number"); + return RER; + } + len = get_tlv("2",temp_buf,&asn_buf); + if (len > 2 && len <= ISDN_LEN) + { + flag |= 0x04; + prn_ptr->msisdn[0] = len; + memcpy(prn_ptr->msisdn+1,temp_buf,len); + } + len = get_tlv("4",temp_buf,&asn_buf); + if (len == LMSI_LEN) + { + memcpy(prn_ptr->lmsi,temp_buf,LMSI_LEN); + flag |= 0x08; + } + len = get_tlv("5",temp_buf,&asn_buf); + if (len != -1) + { + if (!extract_extsiginfo(&prn_ptr->bearer_cap,len,temp_buf)) + return RER; + flag |= 0x10; + } + len = get_tlv("6",temp_buf,&asn_buf); + if (len != -1) + { + if (!extract_extsiginfo(&prn_ptr->net_info,len,temp_buf)) + return RER; + flag |= 0x20; + } + if (get_null("7",&asn_buf) != -1) + { + flag |= 0x40; + prn_ptr->sup_ann = 1; + } + len = get_tlv("8",temp_buf,&asn_buf); + if (len > 2 && len <= ISDN_LEN) + { + flag |= 0x80; + prn_ptr->gmsc_add[0] = len; + memcpy(prn_ptr->gmsc_add+1,temp_buf,len); + } + len = get_tlv("9",temp_buf,&asn_buf); + if (len > 0 && len <= CALLREF_NUM) + { + flag |= 0x100; + prn_ptr->callref_num[0] = len; + memcpy(prn_ptr->callref_num+1,temp_buf,len); + } + if (get_null("10",&asn_buf) != -1) + { + flag |= 0x200; + prn_ptr->or_interr = 1; + } + if (get_tlv("12",temp_buf,&asn_buf) == 1) + { + flag |= 0x400; + prn_ptr->alt_pattern = temp_buf[0]; + } + if (get_null("13",&asn_buf) != -1) + { + flag |= 0x800; + prn_ptr->ccbs_call = 1; + } + if (get_tlv("14",temp_buf,&asn_buf) == 3) + { + flag |= 0x1000; + memcpy(prn_ptr->camel_phase,temp_buf,3); + } + prn_ptr->param_flag = flag; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding provider roaming num response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_provroamnumres(struct MapPRN_Res *prn_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf, &asn_buf); + if (prn_ptr->param_flag & 0x01) // roaming number + buf_len = add_tlv("4",prn_ptr->roam_num[0],prn_ptr->roam_num+1,0x00,&asn_buf); + else + { + mapp_log_debug("assign_prroamnumRES: lack roaming number"); + return RER; + } + return buf_len; +} + +int extract_provroamnumres(struct MapPRN_Res *prn_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + prn_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); + if (len > 2) + { + prn_ptr->param_flag |= 0x01; + prn_ptr->roam_num[0] = len; + memcpy(prn_ptr->roam_num+1,temp_buf,len); + } + else + { + mapp_log_debug("extract_prroamnumres: lack roaming number"); + return RER; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding resume call handling argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_rescallhandarg(struct MapRCH_Arg *rch_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + u8 tag1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (rch_ptr->param_flag & 0x01) // call reference number + buf_len = add_tlv("0",rch_ptr->callref_num[0],rch_ptr->callref_num+1,0x80,&asn_buf); + else + return RER; + if (rch_ptr->param_flag & 0x02) // bs group + { + temp_len = assign_bscode(&rch_ptr->bs_group,temp_buf,0); + buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + if (rch_ptr->param_flag & 0x04) // forward data + { + temp_len = assign_fwddata(&rch_ptr->fwd_data,temp_buf); + buf_len = add_tlv("2",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + if (rch_ptr->param_flag & 0x08) // imsi + buf_len = add_tlv("3",IMSI_LEN,rch_ptr->imsi,0x80,&asn_buf); + else + return RER; + tag1 = 5; + if (rch_ptr->param_flag & 0x10) // cug check info + { + temp_len = assign_cugcheckinfo(&rch_ptr->cugchk_info,temp_buf); + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (rch_ptr->param_flag & 0x20) // o-csi + { + temp_len = assign_ocsi(&rch_ptr->o_csi,temp_buf); + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (rch_ptr->param_flag & 0x40) // ccbs possible + { + sprintf(tlv1,"8-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + return buf_len; +} + +int extract_rescallhandarg(struct MapRCH_Arg *rch_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + rch_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_resume call handling buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // call reference + if (len > 0 && len <= CALLREF_NUM) + { + rch_ptr->param_flag |= 0x01; + rch_ptr->callref_num[0] = len; + memcpy(rch_ptr->callref_num+1,temp_buf,len); + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); // bs group + if (len > 0) + { + if (!extract_bscode(&rch_ptr->bs_group,len,temp_buf)) + return RER; + rch_ptr->param_flag |= 0x02; + } + else + return RER; + len = get_tlv("2",temp_buf,&asn_buf); // forward data + if (len > 0) + { + if (!extract_fwddata(&rch_ptr->fwd_data,len,temp_buf)) + return RER; + rch_ptr->param_flag |= 0x04; + } + else + return RER; + len = get_tlv("3",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + rch_ptr->param_flag |= 0x08; + memcpy(rch_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("4",temp_buf,&asn_buf); // cug check info + if (len > 0) + { + if (!extract_cugcheckinfo(&rch_ptr->cugchk_info,len,temp_buf)) + return RER; + rch_ptr->param_flag |= 0x10; + } + len = get_tlv("5",temp_buf,&asn_buf); // o-csi + if (len > 0) + { + if (!extract_ocsi(&rch_ptr->o_csi,len,temp_buf)) + return RER; + rch_ptr->param_flag |= 0x20; + } + if (get_tlv("8",temp_buf,&asn_buf) != -1) // ccbs possible + { + rch_ptr->param_flag |= 0x40; + rch_ptr->ccbs_possible = 1; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding resume call handling response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_rescallhandres(struct MapRCH_Res *rch_ptr,u8 *buf) +{ + return 0; +} + +int extract_rescallhandres(struct MapRCH_Res *rch_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding provide SIWFS number argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prvsiwfsnumarg(struct MapPSN_Arg *psn_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + u8 tag1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (psn_ptr->param_flag & 0x01) // gsm bearer capability + { + temp_len = assign_extsiginfo(&psn_ptr->gsm_bc,temp_buf); + buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + if (psn_ptr->param_flag & 0x02) // ISDN bearer capability + { + temp_len = assign_extsiginfo(&psn_ptr->isdn_bc,temp_buf); + buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + if (psn_ptr->param_flag & 0x04) // call direction + buf_len = add_tlv("2",1,&psn_ptr->call_direction,0x80,&asn_buf); + else + return RER; + if (psn_ptr->param_flag & 0x08) // b-subscriber address + buf_len = add_tlv("3",psn_ptr->bsub_add[0],psn_ptr->bsub_add+1,0x80,&asn_buf); + else + return RER; + if (psn_ptr->param_flag & 0x10) // chosen channel + { + temp_len = assign_extsiginfo(&psn_ptr->chose_chan,temp_buf); + buf_len = add_tlv("4",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + tag1 = 6; + if (psn_ptr->param_flag & 0x20) // low layer compatibility + { + temp_len = assign_extsiginfo(&psn_ptr->low_camp,temp_buf); + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (psn_ptr->param_flag & 0x40) // high layer compatibility + { + temp_len = assign_extsiginfo(&psn_ptr->high_camp,temp_buf); + sprintf(tlv1,"6-%d",tag1++); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + return buf_len; +} + +int extract_prvsiwfsnumarg(struct MapPSN_Arg *psn_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + psn_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_provide siwfs number buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // GSM bearer capability + if (len > 0) + { + if (!extract_extsiginfo(&psn_ptr->gsm_bc,len,temp_buf)) + return RER; + psn_ptr->param_flag |= 0x01; + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); // ISDN bearer capability + if (len > 0) + { + if (!extract_extsiginfo(&psn_ptr->isdn_bc,len,temp_buf)) + return RER; + psn_ptr->param_flag |= 0x02; + } + else + return RER; + if (get_tlv("2",temp_buf,&asn_buf) == 1) // call direction + { + psn_ptr->param_flag |= 0x04; + psn_ptr->call_direction = temp_buf[0]; + } + else + return RER; + len = get_tlv("3",temp_buf,&asn_buf); // b-subscriber address + if (len > 0) + { + psn_ptr->param_flag |= 0x08; + psn_ptr->bsub_add[0] = len; + memcpy(psn_ptr->bsub_add+1,temp_buf,len); + } + else + return RER; + len = get_tlv("4",temp_buf,&asn_buf); // chosen channel + if (len > 0) + { + if (!extract_extsiginfo(&psn_ptr->chose_chan,len,temp_buf)) + return RER; + psn_ptr->param_flag |= 0x10; + } + else + return RER; + len = get_tlv("5",temp_buf,&asn_buf); // low layer compatibility + if (len > 0) + { + if (!extract_extsiginfo(&psn_ptr->low_camp,len,temp_buf)) + return RER; + psn_ptr->param_flag |= 0x20; + } + len = get_tlv("6",temp_buf,&asn_buf); // high layer compatibility + if (len > 0) + { + if (!extract_extsiginfo(&psn_ptr->high_camp,len,temp_buf)) + return RER; + psn_ptr->param_flag |= 0x40; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding provide SIWFS number response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prvsiwfsnumres(struct MapPSN_Res *psn_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (psn_ptr->param_flag & 0x01) + buf_len = add_tlv("0",psn_ptr->siwfs_num[0],psn_ptr->siwfs_num+1,0x80,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_prvsiwfsnumres(struct MapPSN_Res *psn_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + psn_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_provide siwfs number buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len > 0 && len <= ISDN_LEN) + { + psn_ptr->param_flag |= 0x01; + psn_ptr->siwfs_num[0] = len; + memcpy(psn_ptr->siwfs_num+1,temp_buf,len); + } + else + return RER; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding SIWFS signalling modify argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_siwfssigmodarg(struct MapSSM_Arg *ssm_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (ssm_ptr->param_flag & 0x01) // channel type + { + temp_len = assign_extsiginfo(&ssm_ptr->chan_type,temp_buf); + buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf); + } + if (ssm_ptr->param_flag & 0x02) // chosen channel + { + temp_len = assign_extsiginfo(&ssm_ptr->chose_chan,temp_buf); + buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf); + } + return buf_len; +} + +int extract_siwfssigmodarg(struct MapSSM_Arg *ssm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ssm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_siwfs signalling modify buf_len=0"); + return ROK; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // channel type + if (len > 0) + { + if (!extract_extsiginfo(&ssm_ptr->chan_type,len,temp_buf)) + return RER; + ssm_ptr->param_flag |= 0x01; + } + len = get_tlv("1",temp_buf,&asn_buf); // chosen channel + if (len > 0) + { + if (!extract_extsiginfo(&ssm_ptr->chose_chan,len,temp_buf)) + return RER; + ssm_ptr->param_flag |= 0x02; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding SIWFS signalling modify response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_siwfssigmodres(struct MapSSM_Res *ssm_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (ssm_ptr->param_flag & 0x01) // chosen channel + { + temp_len = assign_extsiginfo(&ssm_ptr->chose_chan,temp_buf); + buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf); + } + return buf_len; +} + +int extract_siwfssigmodres(struct MapSSM_Res *ssm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ssm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_siwfs signalling modify buf_len=0"); + return ROK; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // chosen channel + if (len > 0) + { + if (!extract_extsiginfo(&ssm_ptr->chose_chan,len,temp_buf)) + return RER; + ssm_ptr->param_flag |= 0x01; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding set reporting state argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_setrepstatearg(struct MapSRS_Arg *srs_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (srs_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,srs_ptr->imsi,0x80,&asn_buf); + if (srs_ptr->param_flag & 0x02) // lmsi + buf_len = add_tlv("1",LMSI_LEN,srs_ptr->lmsi,0x80,&asn_buf); + if (srs_ptr->param_flag & 0x04) // ccbs monitoring + { + temp_buf[0] = srs_ptr->ccbs_monitor; + buf_len = add_tlv("2",1,temp_buf,0x80,&asn_buf); + } + return buf_len; +} + +int extract_setrepstatearg(struct MapSRS_Arg *srs_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + srs_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_set reporting state buf_len=0"); + return ROK; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + srs_ptr->param_flag |= 0x01; + memcpy(srs_ptr->imsi,temp_buf,IMSI_LEN); + } + if (get_tlv("1",temp_buf,&asn_buf) == LMSI_LEN) // get lmsi + { + srs_ptr->param_flag |= 0x02; + memcpy(srs_ptr->lmsi,temp_buf,LMSI_LEN); + } + if (get_tlv("2",temp_buf,&asn_buf) == 1) // get ccbs monitor + { + srs_ptr->param_flag |= 0x04; + srs_ptr->ccbs_monitor = temp_buf[0]; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding set reporting state response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_setrepstateres(struct MapSRS_Res *srs_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (srs_ptr->param_flag & 0x01) // ccbs subscriber status + { + temp_buf[0] = srs_ptr->ccbs_stat; + buf_len = add_tlv("0",1,temp_buf,0x80,&asn_buf); + } + return buf_len; +} + +int extract_setrepstateres(struct MapSRS_Res *srs_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + srs_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_set reporting state buf_len=0"); + return ROK; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) == 1) // get ccbs subscriber status + { + srs_ptr->param_flag |= 0x01; + srs_ptr->ccbs_stat = temp_buf[0]; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding status report argument */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_statreparg(struct MapSR_Arg *sr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (sr_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,sr_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (sr_ptr->param_flag & 0x02) // event report data + { + if (sr_ptr->event_data.param_flag & 0x01) // ccbs subscriber status + { + temp_buf[0] = sr_ptr->event_data.ccbs_stat; + buf_len = add_tlv("1.0",1,temp_buf,0x80,&asn_buf); + } + } + if (sr_ptr->param_flag & 0x04) // call report data + { + if (sr_ptr->call_data.param_flag & 0x01) // monitor mode + { + temp_buf[0] = sr_ptr->call_data.monitor_mode; + buf_len = add_tlv("2.0",1,temp_buf,0x80,&asn_buf); + } + if (sr_ptr->call_data.param_flag & 0x02) // call outcome + { + temp_buf[0] = sr_ptr->call_data.call_outcome; + buf_len = add_tlv("2.1",1,temp_buf,0x80,&asn_buf); + } + } + return buf_len; +} + +int extract_statreparg(struct MapSR_Arg *sr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + sr_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_status report buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + sr_ptr->param_flag |= 0x01; + memcpy(sr_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + if (get_tlv("1.0",temp_buf,&asn_buf) != -1) // ccbs subscriber status + { + sr_ptr->param_flag |= 0x02; + sr_ptr->event_data.param_flag |= 0x01; + sr_ptr->event_data.ccbs_stat = temp_buf[0]; + } + if (get_tlv("2.0",temp_buf,&asn_buf) != -1) // monitor mode + { + sr_ptr->param_flag |= 0x04; + sr_ptr->call_data.param_flag |= 0x01; + sr_ptr->call_data.monitor_mode = temp_buf[0]; + } + if (get_tlv("2.1",temp_buf,&asn_buf) != -1) // call outcome + { + sr_ptr->param_flag |= 0x04; + sr_ptr->call_data.param_flag |= 0x02; + sr_ptr->call_data.call_outcome = temp_buf[0]; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding status report response */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_statrepres(struct MapSR_Res *sr_ptr,u8 *buf) +{ + return 0; +} + +int extract_statrepres(struct MapSR_Res *sr_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding remote user free argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_rmtuserfreearg(struct MapRUF_Arg *ruf_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + u8 tag1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (ruf_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,ruf_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (ruf_ptr->param_flag & 0x02) // call info + { + temp_len = assign_extsiginfo(&ruf_ptr->call_info,temp_buf); + buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + if (ruf_ptr->param_flag & 0x04) // ccbs feature + { + temp_len = assign_ccbsfeat(&ruf_ptr->ccbs_feat,temp_buf); + buf_len = add_tlv("2",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + if (ruf_ptr->param_flag & 0x08) // translate number + buf_len = add_tlv("3",ruf_ptr->trans_num[0],ruf_ptr->trans_num+1,0x80,&asn_buf); + tag1 = 5; + if (ruf_ptr->param_flag & 0x10) // replace number + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (ruf_ptr->param_flag & 0x20) // alert pattern + { + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,1,&ruf_ptr->alt_pattern,0x80,&asn_buf); + } + return buf_len; +} + +int extract_rmtuserfreearg(struct MapRUF_Arg *ruf_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ruf_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_remote user free buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + ruf_ptr->param_flag |= 0x01; + memcpy(ruf_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); // get call info + if (len > 0) + { + if (!extract_extsiginfo(&ruf_ptr->call_info,len,temp_buf)) + return RER; + ruf_ptr->param_flag |= 0x02; + } + else + return RER; + len = get_tlv("2",temp_buf,&asn_buf); // get ccbs feature + if (len > 0) + { + if (!extract_ccbsfeat(&ruf_ptr->ccbs_feat,len,temp_buf)) + return RER; + ruf_ptr->param_flag |= 0x04; + } + else + return RER; + len = get_tlv("3",temp_buf,&asn_buf); // get tranlate number + if (len > 0 && len <= ISDN_LEN) + { + ruf_ptr->param_flag |= 0x08; + ruf_ptr->trans_num[0] = len; + memcpy(ruf_ptr->trans_num+1,temp_buf,len); + } + else + return RER; + if (get_tlv("4",temp_buf,&asn_buf) != -1) // get replace number + { + ruf_ptr->param_flag |= 0x10; + ruf_ptr->replace_num = 1; + } + if (get_tlv("5",temp_buf,&asn_buf) == 1) // get alert pattern + { + ruf_ptr->param_flag |= 0x20; + ruf_ptr->alt_pattern = temp_buf[0]; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding remote user free response */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_rmtuserfreeres(struct MapRUF_Res *ruf_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (ruf_ptr->param_flag & 0x01) // ruf outcome + { + temp_buf[0] = ruf_ptr->ruf_outcome; + buf_len = add_tlv("0",1,temp_buf,0x80,&asn_buf); + } + else + return RER; + return buf_len; +} + +int extract_rmtuserfreeres(struct MapRUF_Res *ruf_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + ruf_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_remote user free buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) == 1) + { + ruf_ptr->param_flag |= 0x01; + ruf_ptr->ruf_outcome = temp_buf[0]; + } + else + return RER; + return ROK; +} + + +//umts add by gxchen start +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ist-Alert argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_istalertarg(struct MapISTAlert_Arg *ista_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + + asn_encode(buf, &asn_buf); + if(ista_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0", IMSI_LEN, ista_ptr->imsi, 0x80, &asn_buf); + else + { + mapp_log_debug("assign istalertarg lack IMSI"); + return RER; + } + + return buf_len; +} +int extract_istalertarg(struct MapISTAlert_Arg *ista_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + int len=0; + u8 temp_buf[256]; + + ista_ptr->param_flag = 0; + if(buf_len == 0) + { + mapp_log_debug("MAPP--extract istalertarg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf, buf_len, &decErr, &asn_buf) == -1) + return RER; + len = get_tlv("0", temp_buf, &asn_buf); + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + ista_ptr->param_flag |= 0x01; + memcpy(ista_ptr->imsi, temp_buf, len); + } + else + { + mapp_log_debug("extract istalertarg lack IMSI"); + return RER; + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ist-Alert response */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_istalertres(struct MapISTAlert_Res *ista_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + + asn_encode(buf, &asn_buf); + if(ista_ptr->param_flag & 0x01) + buf_len = add_tlv("0", 1, &ista_ptr->ist_alert_timer, 0x80, &asn_buf); + if(ista_ptr->param_flag & 0x02) + buf_len = add_tlv("1", 1, &ista_ptr->ist_info_withdraw, 0x80, &asn_buf); + if(ista_ptr->param_flag & 0x04) + buf_len = add_tlv("2", 1, (u8*)&ista_ptr->callterm_ind, 0x80, &asn_buf); + + return buf_len; +} +int extract_istalertres(struct MapISTAlert_Res *ista_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + //int len=0; + u8 temp_buf[256]; + + ista_ptr->param_flag = 0; + if(buf_len == 0) + { + mapp_log_debug("MAPP--extract istalertres buf_len=0"); + return RER; + } + if(asn_decode_v3(buf, buf_len, &decErr, &asn_buf) == -1) + return RER; + if(1 == get_tlv("0", temp_buf, &asn_buf)) + { + ista_ptr->param_flag |= 0x01; + ista_ptr->ist_alert_timer = temp_buf[0]; + } + if(1 == get_tlv("1", temp_buf, &asn_buf)) + { + ista_ptr->param_flag |= 0x02; + ista_ptr->ist_info_withdraw = temp_buf[0]; + } + if(1 == get_tlv("2", temp_buf, &asn_buf)) + { + ista_ptr->param_flag |= 0x04; + ista_ptr->callterm_ind = temp_buf[0]; + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ist-Commad argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_istcmdarg(struct MapISTCmd_Arg *istc_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len = 0; + + asn_encode(buf, &asn_buf); + if(istc_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0", IMSI_LEN, istc_ptr->imsi, 0x80, &asn_buf); + else + { + mapp_log_debug("assign istcmdarg lack IMSI"); + return RER; + } + + return buf_len; +} +int extract_istcmdarg(struct MapISTCmd_Arg *istc_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + int len=0; + u8 temp_buf[256]; + + istc_ptr->param_flag = 0; + if(buf_len == 0) + { + mapp_log_debug("MAPP--extract istcmdarg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf, buf_len, &decErr, &asn_buf) == -1) + return RER; + len = get_tlv("0", temp_buf, &asn_buf); + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + istc_ptr->param_flag |= 0x01; + memcpy(istc_ptr->imsi, temp_buf, len); + } + else + { + mapp_log_debug("extract istcmdarg lack IMSI"); + return RER; + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ist-Commad response */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/*int assign_istcmdres(struct MapISTCmd_Res *istc_ptr,u8 *buf) +{ +} +int extract_istcmdres(struct MapISTCmd_Res *istc_ptr,u32 buf_len,u8 *buf) +{ +} +*/ +//add by gxchen end + diff --git a/plat/xapp/src/mapp/map_code_dlgpdu.c b/plat/xapp/src/mapp/map_code_dlgpdu.c new file mode 100644 index 0000000..c671786 --- /dev/null +++ b/plat/xapp/src/mapp/map_code_dlgpdu.c @@ -0,0 +1,210 @@ +/* MAP dialogue PDU coding/decoding c file */ +/* Written by Liu Zhiguo 2003-08-25 */ +/* Version: 1.0 */ +/* -------------------------------------- */ + +#include "map_includes.h" +#include "../../../tcap/src/include/tcap_head.h" +#include "../../../tcap/src/include/tcap_public.h" +#include "../../../tcap/src/include/tcap_struct.h" +#include "../xap_interfunc.h" +#include "map_dlgpdu.h" + + +static u8 MAPP_Dlgpdu[7] = {0x04,0x00,0x00,0x01,0x01,0x01,0x01}; + +u8 build_mapdlg(struct MapDlg_struct *dlg_ptr,u8 *data_buf) // build user information portion +{ + struct MapDlgOpen_struct *map_open; + struct MapDlgUAbort_struct *map_uabort; + ASN_BUF asn_buf; + u8 temp_buf[256],temp_data[256]; + int len=0,len1=0; + + asn_encode(temp_buf,&asn_buf); + switch (dlg_ptr->dlg_type) + { + case MAPDLG_OPEN: + map_open = (MapDlgOpen_struct *) &dlg_ptr->map_dlg.map_open; + if ((map_open->param_flag & 0x01)) + len1 = add_tlv("0.0",map_open->peer_ref[0],map_open->peer_ref+1,0x80,&asn_buf); + if ((map_open->param_flag & 0x02)) + len1 = add_tlv("0.1",map_open->local_ref[0],map_open->local_ref+1,0x80,&asn_buf); + break; + case MAPDLG_ACCEPT: + len1 = add_tlv("1",0,&dlg_ptr->dlg_type,0x80,&asn_buf); + break; + case MAPDLG_CLOSE: + len1 = add_tlv("2",0,&dlg_ptr->dlg_type,0x80,&asn_buf); + break; + case MAPDLG_REFUSE: + temp_data[0] = dlg_ptr->map_dlg.map_refuse.reason; + len1 = add_tlv("3.10",1,temp_data,0x00,&asn_buf); + break; + case MAPDLG_UABORT: + map_uabort = (MapDlgUAbort_struct *) &dlg_ptr->map_dlg.map_uabort; + switch (map_uabort->choice_flag) + { + case 0: + len1 = add_null("4.0",0x00,&asn_buf); + break; + case 1: + len1 = add_null("4.1",0x00,&asn_buf); + break; + case 2: + temp_data[0] = map_uabort->choice.resunavi; + len1 = add_tlv("4.2.10",1,temp_data,0x00,&asn_buf); + break; + case 3: + temp_data[0] = map_uabort->choice.appproccancel; + len1 = add_tlv("4.3.10",1,temp_data,0x00,&asn_buf); + break; + default: + break; + } + break; + case MAPDLG_PABORT: + temp_data[0] = dlg_ptr->map_dlg.map_pabort.reason; + len1 = add_tlv("5.10",1,temp_data,0x00,&asn_buf); + break; + default: + break; + } + asn_encode(data_buf,&asn_buf); + len = add_tlv("8",0,temp_data,0x20,&asn_buf); + len = add_tlv("8.6-1",7,MAPP_Dlgpdu,0x00,&asn_buf); + len = add_tlv("8.0-2",len1,temp_buf,0xa0,&asn_buf); + return len; +} + +u8 extract_mapdlg(struct MapDlg_struct *dlg_ptr,struct dlgport_struct *port_ptr) +{ + struct MapDlgOpen_struct *map_open; + struct MapDlgUAbort_struct *map_uabort; + ASN_BUF asn_buf; + u8 temp_buf[256],temp_data[256]; + int len; + + dlg_ptr->dlg_type = 0xff; + len = asn_decode(port_ptr->user_info,1,&asn_buf); + if (len != port_ptr->user_info_len) + { + sprintf((char *)temp_buf, "MAPP extract user info error, wrong length, %d v.s. %d", len, port_ptr->user_info_len); + xap_send_error((char *)temp_buf); + //return 0; + } + len = get_tlv("8",temp_buf,&asn_buf); // get External tag + if (len == -1) // has nor external tag + { + xap_send_error("MAPP extract user info error, no external Tag"); + return 0; + } + len = get_tlv("8.6",temp_buf,&asn_buf); + if (len == 7) // get MAP dialgoue PDU + { + if (temp_buf[5] != 1 || temp_buf[6] != 1) + { + xap_send_error("MAPP extract user info error identifier"); + return 0; + } + } + len = get_tlv("8.0",temp_buf,&asn_buf); // get ASN.1 type + if (len == -1) + { + xap_send_error("MAPP extract user info error ASN.1 type"); + return 0; + } + len = asn_decode(temp_buf,1,&asn_buf); + len = get_tlv("0",temp_data,&asn_buf); // MAP_OPEN info + if (len != -1) + { + dlg_ptr->dlg_type = MAPDLG_OPEN; + map_open = (MapDlgOpen_struct *) &dlg_ptr->map_dlg.map_open; + map_open->param_flag = 0; + len = get_tlv("0.0",temp_data,&asn_buf); // local reference + if (len != -1) + { + map_open->param_flag |= 0x02; + map_open->local_ref[0] = len; + memcpy(map_open->local_ref+1,temp_data,len); + } + len = get_tlv("0.1",temp_data,&asn_buf); // peer reference + if (len != -1) + { + map_open->param_flag |= 0x01; + map_open->peer_ref[0] = len; + memcpy(map_open->peer_ref+1,temp_data,len); + } + return 1; + } + len = get_tlv("1",temp_data,&asn_buf); // MAP_ACCEPT info + if (len != -1) + { + dlg_ptr->dlg_type = MAPDLG_ACCEPT; + return 1; + } + len = get_tlv("2",temp_data,&asn_buf); // MAP_CLOSE info + if (len != -1) + { + dlg_ptr->dlg_type = MAPDLG_CLOSE; + return 1; + } + len = get_tlv("3",temp_data,&asn_buf); // MAP_REFUSE info + if (len != -1) + { + dlg_ptr->dlg_type = MAPDLG_REFUSE; + len = get_tlv("3.10",temp_data,&asn_buf); + if (len != 1) + { + xap_send_error("MAPP extract user info refuse lack reason"); + return 0; + } + dlg_ptr->map_dlg.map_refuse.param_flag = 0x01; + dlg_ptr->map_dlg.map_refuse.reason = temp_data[0]; + return 1; + } + len = get_tlv("4",temp_data,&asn_buf); // MAP_UABORT info + if (len != -1) + { + dlg_ptr->dlg_type = MAPDLG_UABORT; + map_uabort = (MapDlgUAbort_struct *) &dlg_ptr->map_dlg.map_uabort; + len = get_tlv("4.0",temp_data,&asn_buf); // user specific reason + if (len != -1) + map_uabort->choice_flag = 0; + len = get_tlv("4.1",temp_data,&asn_buf); // user resource limitation + if (len != -1) + map_uabort->choice_flag = 1; + len = get_tlv("4.2",temp_data,&asn_buf); // resource unabailable + if (len != -1) + { + map_uabort->choice_flag = 2; + len = get_tlv("4.2.10",temp_data,&asn_buf); + if (len == -1) + return 0; + map_uabort->choice.resunavi = temp_data[0]; + } + len = get_tlv("4.3",temp_data,&asn_buf); // APC + if (len != -1) + { + map_uabort->choice_flag = 3; + len = get_tlv("4.3.10",temp_data,&asn_buf); + if (len == -1) + return 0; + map_uabort->choice.appproccancel = temp_data[0]; + } + return 1; + } + len = get_tlv("5",temp_data,&asn_buf); // MAP_PAOBRT info + if (len != -1) + { + dlg_ptr->dlg_type = MAPDLG_PABORT; + len = get_tlv("5.10",temp_data,&asn_buf); + if (len != 1) + return 0; + dlg_ptr->map_dlg.map_pabort.param_flag = 0x01; + dlg_ptr->map_dlg.map_pabort.reason = temp_data[0]; + return 1; + } + xap_send_error("MAPP extract user info unknown type"); + return 0; +} diff --git a/plat/xapp/src/mapp/map_code_ms.c b/plat/xapp/src/mapp/map_code_ms.c new file mode 100644 index 0000000..dc9b952 --- /dev/null +++ b/plat/xapp/src/mapp/map_code_ms.c @@ -0,0 +1,5305 @@ +/* map coding mobile service c file */ +/* written by Liu Zhiguo 2003-03-04 */ +/* Version 2.0 */ +/* -------------------------------- */ + +#include "map_includes.h" +#include "map_acn.h" + + +SCCP_ADDR *did_to_sccpAddr(u32 dialogue_id); + +int assign_sscsi(char *tag_prefix, struct SsCsi_struct *p_csi, ASN_BUF *asnbuf) +{ + char tagseq[32]; + int ii, buflen; + + sprintf(tagseq, "%s.16-1", tag_prefix); + add_null(tagseq, 0x20, asnbuf); + if(p_csi->event_list.list_len > CAMELSS_LEN) + return RER; + sprintf(tagseq, "%s.16-1.16", tag_prefix); + add_null(tagseq, 0x20, asnbuf); + for(ii = 0;ii < p_csi->event_list.list_len; ii++) + { + sprintf(tagseq, "%s.16-1.16.4-%d", tag_prefix, ii+1); + buflen = add_tlv(tagseq, 1, &p_csi->event_list.ss_code[ii], 0x00, asnbuf); + } + buflen = p_csi->scf_add[0]; + sprintf(tagseq, "%s.16-1.4-10", tag_prefix); + buflen = add_tlv(tagseq, buflen, p_csi->scf_add + 1, 0x00, asnbuf); + return buflen; +} + +int extract_sscsi(char *tag_prefix, struct SsCsi_struct *p_csi, ASN_BUF *asnbuf) +{ + char tagseq[32]; + int retval = -1, ii = 0; + + while(ii < CAMELSS_LEN) + { + sprintf(tagseq, "%s.16.16.4-%d", tag_prefix, ii); + if((retval = GetTLV(tagseq, 1, &p_csi->event_list.ss_code[ii], 0x00, asnbuf)) < 0) + break; + ii ++; + } + if(ii == 0) + return RER; + sprintf(tagseq, "%s.16.4", tag_prefix); + if((retval = GetTLV(tagseq, ISDN_LEN, p_csi->scf_add + 1, 0x00, asnbuf)) < 0) + return RER; + p_csi->scf_add[0] = retval; + return ROK; +} + +int assign_smscsi(char *tag_prefix, struct SMSCsi_struct *p_csi, ASN_BUF *asnbuf) +{ + char tagseq[32]; + int len=0, ii, buflen; + + if((p_csi->param_flag & 0x01) == 0x01) + { + if(p_csi->tdpdata_list.tdpdata_len > TDPDATA_NUM) + return -1; + for(ii = 0; ii < p_csi->tdpdata_list.tdpdata_len; ii++) //sms-BCSM Camel TDP Data List + { + sprintf(tagseq, "%s.0.16-%d", tag_prefix, ii + 1); + add_null(tagseq, 0x20, asnbuf); + sprintf(tagseq, "%s.0.16-%d.0-1", tag_prefix, ii + 1); + len = AddInteger(tagseq, p_csi->tdpdata_list.tdp_data[ii].det_point, 0x80, asnbuf); + sprintf(tagseq, "%s.0.16-%d.1-2", tag_prefix, ii + 1); + len = AddInteger(tagseq, p_csi->tdpdata_list.tdp_data[ii].service_key, 0x80, asnbuf); + if((buflen = p_csi->tdpdata_list.tdp_data[ii].scf_add[0]) > ISDN_LEN) + buflen = ISDN_LEN; + sprintf(tagseq, "%s.0.16-%d.2-3", tag_prefix, ii + 1); + len = AddTLV(tagseq, buflen, p_csi->tdpdata_list.tdp_data[ii].scf_add + 1, 0x80, asnbuf); + sprintf(tagseq, "%s.0.16-%d.3-4", tag_prefix, ii + 1); + len = AddInteger(tagseq, p_csi->tdpdata_list.tdp_data[ii].def_hand, 0x80, asnbuf); + } + } + if((p_csi->param_flag & 0x02) == 0x02) //camel capability Handling + { + sprintf(tagseq, "%s.1", tag_prefix); + len = AddInteger(tagseq, p_csi->camel_caphand, 0x80, asnbuf); + } + if((p_csi->param_flag & 0x04) == 0x04) //notificationTOCSE + { + sprintf(tagseq, "%s.3", tag_prefix); + len = add_null(tagseq, 0x80, asnbuf); + } + if((p_csi->param_flag & 0x08) == 0x08) //csiActive + { + sprintf(tagseq, "%s.4", tag_prefix); + len = add_null(tagseq, 0x80, asnbuf); + } + return len; +} + +int extract_smscsi(char *tag_prefix, struct SMSCsi_struct *p_csi, ASN_BUF *asnbuf) +{ + char tagseq[32]; + int retval = -1, ii =0 ; + + p_csi->param_flag = 0; + while(ii < TDPDATA_NUM) + { + sprintf(tagseq, "%s.0.16-%d.0", tag_prefix, ii + 1); + if((retval = GetInteger(tagseq, (int *)&p_csi->tdpdata_list.tdp_data[ii].det_point, 0x80, asnbuf)) < 0) + break; + sprintf(tagseq, "%s.0.16-%d.1", tag_prefix, ii + 1); + if((retval = GetInteger(tagseq, (int *)&p_csi->tdpdata_list.tdp_data[ii].service_key, 0x80, asnbuf)) < 0) + break; + sprintf(tagseq, "%s.0.16-%d.2", tag_prefix, ii + 1); + if((retval = GetTLV(tagseq, ISDN_LEN, p_csi->tdpdata_list.tdp_data[ii].scf_add + 1, 0x80, asnbuf)) < 0) + break; + p_csi->tdpdata_list.tdp_data[ii].scf_add[0] = retval; + sprintf(tagseq, "%s.0.16-%d.3", tag_prefix, ii + 1); + if((retval = GetInteger(tagseq, (int *)&p_csi->tdpdata_list.tdp_data[ii].def_hand, 0x80, asnbuf)) < 0) + break; + ii ++; + } + if(ii > 0) + { + p_csi->param_flag |= 0x01; + p_csi->tdpdata_list.tdpdata_len = ii; + } + //camel Capability Handling + sprintf(tagseq, "%s.1", tag_prefix); + if(GetInteger(tagseq, (int *)&p_csi->tdpdata_list.tdp_data[ii].def_hand, 0x80, asnbuf) > 0) + p_csi->param_flag |= 0x02; + //notificationTOCSE + sprintf(tagseq, "%s.3", tag_prefix); + if(get_null(tagseq, asnbuf) >= 0) + { + p_csi->param_flag |= 0x04; + p_csi->notificationToCSE = 1; + } + //csi-Active + sprintf(tagseq, "%s.4", tag_prefix); + if(get_null(tagseq, asnbuf) >= 0) + { + p_csi->param_flag |= 0x08; + p_csi->csi_Active = 1; + } + return 1; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding update loction argument */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_uplocarg(struct MapUL_Arg *ul_ptr,u8 *buf ,u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = ul_ptr->param_flag; + if (flag & 0x01) // has IMSI + buf_len = add_tlv("4-1",IMSI_LEN,ul_ptr->imsi,0x00,&asn_buf); + else + { + mapp_log_debug("update location request lack IMSI"); + return RER; + } + if ( (flag & 0x02) && ( !(flag & 0x20) || ver >1 ) ) // has not MSC number + buf_len = add_tlv("1-2",ul_ptr->msc_num[0],ul_ptr->msc_num+1,0x80,&asn_buf); + else + { + mapp_log_debug("update location request lack MSISDN"); + return RER; + } + + if (flag & 0x04) // has not VLR address + buf_len = add_tlv("4-3",ul_ptr->vlr_num[0],ul_ptr->vlr_num+1,0x00,&asn_buf); + else + { + mapp_log_debug("update location request lack VLR address"); + return RER; + } + tag1 = 4; + if (flag & 0x08) // has LMSI + { + sprintf(tlv1,"10-%d",tag1++); + buf_len = add_tlv(tlv1,LMSI_LEN,ul_ptr->lmsi,0x80,&asn_buf); + } + if (flag & 0x10) // vlr capability + { + if (ul_ptr->vlr_cap.param_flag & 0x01) // camel phase + { + sprintf(tlv1,"6-%d.0",tag1++); + buf_len = add_tlv(tlv1,3,ul_ptr->vlr_cap.camel_phase,0x80,&asn_buf); + } + } + + if( (flag & 0x20) && !(flag & 0x02) && (ver == 1) ) + buf_len = add_tlv("0-2",ul_ptr->vlr_num[0],ul_ptr->vlr_num+1,0x00,&asn_buf); + else + { + mapp_log_debug("update location request lack VLR address"); + return RER; + } + return buf_len; +} + +int extract_uplocarg(struct MapUL_Arg *ul_ptr,u32 buf_len,u8 *buf ,u8 ver) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u32 flag = 0; + + ul_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4-1",temp_buf,&asn_buf); // get imsi + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)// get IMSI + { + flag |= 0x01; + memcpy(ul_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("update location indicate error IMSI"); + return RER; + } + len = get_tlv("0", temp_buf,&asn_buf); + if( len > 2 ) + { + flag |= 0x20; + ul_ptr->roaming_num[0] = len; + memcpy( ul_ptr->roaming_num+1,temp_buf,len); + } + else if ((len = get_tlv("1",temp_buf,&asn_buf)) > 2) // get MSC number + { + flag |= 0x02; + ul_ptr->msc_num[0] = len; + memcpy(ul_ptr->msc_num+1,temp_buf,len); + } + else + { + mapp_log_debug("update location indicate lack MSC number or roaming num"); + return RER; + } + if ((len = get_tlv("4-3",temp_buf,&asn_buf)) > 2) // get VLR number + { + flag |= 0x04; + ul_ptr->vlr_num[0] = len; + memcpy(ul_ptr->vlr_num+1,temp_buf,len); + } + else + { + mapp_log_debug("update location indicate lack VLR number"); + return RER; + } + len = get_tlv("10",temp_buf,&asn_buf); // get lmsi number + if (len == LMSI_LEN) + { + flag |= 0x08; + memcpy(ul_ptr->lmsi,temp_buf,LMSI_LEN); + } + len = get_tlv("6.0",temp_buf,&asn_buf); //get camel info + if (len != -1) + { + memcpy(ul_ptr->vlr_cap.camel_phase,temp_buf,3); + flag |= 0x10; + } + ul_ptr->param_flag = flag; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding update loction response */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_uplocres(struct MapUL_Res *ul_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ul_ptr->param_flag & 0x01) + buf_len = add_tlv("4",ul_ptr->hlr_num[0],ul_ptr->hlr_num+1,0x00,&asn_buf); + else + { + mapp_log_debug("update location response lack hlr number"); + return RER; + } + return buf_len; +} + +int extract_uplocres(struct MapUL_Res *ul_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ul_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_uplocres buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if ((len = get_tlv("4",temp_buf,&asn_buf)) > 2) // get HLR number + { + ul_ptr->param_flag |= 0x01; + ul_ptr->hlr_num[0] = len; + memcpy(ul_ptr->hlr_num+1,temp_buf,len); + } + else + { + mapp_log_debug("update location confirm lack HLR number"); + return RER; + } + return ROK; +} + + + +/* --->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAP V1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,---*/ + + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send parameters argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_SendParaArg(struct MapSP_Arg *sendpara_ptr,u8 *buf) // lw_add +{ + ASN_BUF asn_buf; + int flag,buf_len=0; + + int temp_index; + int param_num; + + asn_encode(buf,&asn_buf); + flag = sendpara_ptr->param_flag; + //add_null("16", 0x20, &asn_buf); + buf_len = AddTLV("16",0,NULL,0x20,&asn_buf); + if( sendpara_ptr->param_flag & 0x01 ) + { + if(sendpara_ptr->sub_id.choice_flag == 1)//imsi + { + buf_len = add_tlv("16.0",IMSI_LEN,sendpara_ptr->sub_id.id_choice.imsi,0x80,&asn_buf); + } + else if(sendpara_ptr->sub_id.choice_flag == 2)//tmsi + { + + buf_len = add_tlv("16.1",TMSI_LEN,sendpara_ptr->sub_id.id_choice.tmsi,0x80,&asn_buf); + } + else + { + mapp_log_debug("sendParameter indicate subscriber id choice error");;//do report err + } + } + else + { + mapp_log_debug("sendParameter indicate lack subscriber id ");;//do report err + } + //Request Parameter List + if( sendpara_ptr->param_flag & 0x02 ) + { + char tag[16]; + param_num = sendpara_ptr->ReqPara_num; + if( sendpara_ptr->ReqPara_num > 2 ) + { + mapp_log_debug("sendParameter indicate request parameter list num error");;//do reptor_err; + param_num = 2; + } + //add_null("16", 0x20, &asn_buf); + buf_len = AddTLV("16.16",0,NULL,0x20,&asn_buf); + for( temp_index =0 ;temp_index < param_num ;temp_index ++) + { + sprintf(tag,"16.16.10-%d",temp_index+1); + buf_len = add_tlv(tag,1,(u8 *)&sendpara_ptr->ReqPara[temp_index],0x00,&asn_buf); + } + } + else + { + mapp_log_debug("sendParameter indicate lack Request Parameter List ");;//do report err + } + return buf_len; +} + + + +int extract_SendParaArg(struct MapSP_Arg *sendpara_ptr,u32 buf_len,u8 *buf) //lw_add +{ + ASN_BUF asn_buf; + int len,index; + u8 temp_buf[256]; + + sendpara_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("0-1",temp_buf,&asn_buf); // get IMSI + if (len ==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + sendpara_ptr->param_flag |= 0x01; + sendpara_ptr->sub_id.choice_flag = 0x01; + memcpy(sendpara_ptr->sub_id.id_choice.imsi,temp_buf,len); + } + + len = get_tlv("1-1",temp_buf,&asn_buf); // get TMSI + if (len == TMSI_LEN) + { + sendpara_ptr->param_flag |= 0x01; + sendpara_ptr->sub_id.choice_flag = 0x02; + memcpy(sendpara_ptr->sub_id.id_choice.tmsi,temp_buf,len); + } + + index =0 ; + while( ( len = get_tlv("16-2.10",temp_buf,&asn_buf) ) == 1 && index < 2 ) + { + memcpy( sendpara_ptr->ReqPara+index++ , temp_buf , len ); // get Request parameter + } + if( index > 0 ) + { + sendpara_ptr->param_flag |= 0x02; + sendpara_ptr->ReqPara_num = index ; + } + return ROK; +} + + + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send parameters response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_Sub_Data(Sub_data_struct *sub_data, u8 *buf ) +{ + ASN_BUF asn_buf; + int jj,kk; + u32 flag1; + u32 flag; + u32 len; + int buf_len=0; + int temp_len; + u8 temp_data[256],temp_buf[256]; + u8 tag1=1,tag2=1,tag3=1,tag4=1,tag5=1; + char tlv1[32],tlv2[32],tlv3[32],tlv4[32],tlv5[32]; + struct ExtFwdInfo_struct *fwd_ptr; + struct ExtSsData_struct *ss_ptr; + struct ExtCallBarInfo_struct *callbar_ptr; + + asn_encode(buf,&asn_buf); + flag = sub_data->param_flag; + + if (flag & 0x02) // MSISDN + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,sub_data->msisdn[0],sub_data->msisdn+1,0x80,&asn_buf); + } + if (flag & 0x04) // category + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&sub_data->category,0x80,&asn_buf); + } + if (flag & 0x08) // sub status + { + sprintf(tlv1,"3-%d",tag1++); + temp_data[0] = sub_data->sub_status; + buf_len = add_tlv(tlv1,1,temp_data,0x80,&asn_buf); + } + if (flag & 0x20) // bearer service list + { + temp_len = bearer_bittostr(sub_data->bearer_data,temp_data,0); + + if(temp_len > 0) + { + sprintf(tlv1,"4-%d",tag1++); + + for (jj = 0;jj < temp_len;jj ++) + { + sprintf(tlv2,"%s.4-%d",tlv1,jj+1); + buf_len = add_tlv(tlv2,1,temp_data+jj,0x00,&asn_buf); + } + } + } + if (flag & 0x40) // tele service list + { + temp_len = tele_bittostr(sub_data->tele_data,temp_data,0); + if(temp_len > 0) + { + sprintf(tlv1,"6-%d",tag1++); + for (jj = 0;jj < temp_len;jj++) + { + sprintf(tlv2,"%s.4-%d",tlv1,jj+1); + buf_len = add_tlv(tlv2,1,temp_data+jj,0x00,&asn_buf); + } + } + } + if (flag & 0x80) // ss info list + { + sprintf(tlv1,"7-%d",tag1++); + tag2 = 1; + if (sub_data->ss_info.param_flag & 0x01) // fwd info + { + fwd_ptr = (ExtFwdInfo_struct *) &sub_data->ss_info.fwd_info; + for (jj = 0;jj < 4;jj ++) //tag2 + { + tag3 = 1; + kk = 0x01 << jj; + if (fwd_ptr->param_flag & kk) + { + sprintf(tlv2,"%s.0-%d",tlv1,tag2++); + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); // for ss_code + buf_len = add_tlv(tlv3,1,&fwd_ptr->ss_code[jj],0x00,&asn_buf); + sprintf(tlv3,"%s.16-%d",tlv2,tag3++); + add_null(tlv3,0x20,&asn_buf); + tag4 = 1; + sprintf(tlv4,"%s.16-%d",tlv3,tag4); + add_null(tlv4,0x20,&asn_buf); + tag5 = 1; + flag1 = fwd_ptr->fwd_feat[jj].param_flag; + if (flag1 & 0x01) // bs group + { + if (fwd_ptr->fwd_feat[jj].bs_code.param_flag == 1) + { + sprintf(tlv5,"%s.2-%d",tlv4,tag5++); + if (tele_bittostr(fwd_ptr->fwd_feat[jj].bs_code.tele_code,temp_data,1)) + buf_len = add_tlv(tlv5,1,temp_data,0x80,&asn_buf); + } + else if(fwd_ptr->fwd_feat[jj].bs_code.param_flag == 2) + { + sprintf(tlv5,"%s.3-%d",tlv4,tag5++); + if (bearer_bittostr(fwd_ptr->fwd_feat[jj].bs_code.bearer_code,temp_data,1)) + buf_len = add_tlv(tlv5,1,temp_data,0x80,&asn_buf); + } + } + if (flag1 & 0x02) //ss status + { + sprintf(tlv5,"%s.4-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&fwd_ptr->fwd_feat[jj].ss_status,0x80,&asn_buf); + } + if (flag1 & 0x04) //fwdto_num + { + sprintf(tlv5,"%s.5-%d",tlv4,tag5++); + len = fwd_ptr->fwd_feat[jj].fwdto_num[0]; + buf_len = add_tlv(tlv5,len,fwd_ptr->fwd_feat[jj].fwdto_num+1,0x80,&asn_buf); + } + if (flag1 &0x08) //fwd opt + { + sprintf(tlv5,"%s.6-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&fwd_ptr->fwd_feat[jj].fwd_option,0x80,&asn_buf); + } + if (flag1 &0x10) //norc time + { + sprintf(tlv5,"%s.7-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&fwd_ptr->fwd_feat[jj].norc_time,0x80,&asn_buf); + } + } + } + } + if (sub_data->ss_info.param_flag & 0x02) // call bar info + { + callbar_ptr = (ExtCallBarInfo_struct *) &sub_data->ss_info.call_info; + for (jj = 0;jj < 5;jj ++) + { + kk = 0x01 << jj; + if ((callbar_ptr->param_flag & kk) != 0) + { + sprintf(tlv2,"%s.1-%d",tlv1,tag2++); + tag3 = 1; + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); + buf_len = add_tlv(tlv3,1,&callbar_ptr->ss_code[jj],0x00,&asn_buf); + sprintf(tlv3,"%s.16-%d",tlv2,tag3++); + add_null(tlv3,0x20,&asn_buf); + tag4 = 1; + sprintf(tlv4,"%s.16-%d",tlv3,tag4); + add_null(tlv4,0x20,&asn_buf); + tag5 = 1; + if (callbar_ptr->bs_code[jj].param_flag == 2) + { + sprintf(tlv5,"%s.2-%d",tlv4,tag5++); + if (bearer_bittostr(callbar_ptr->bs_code[jj].bearer_code,temp_data,1)) + buf_len = add_tlv(tlv5,1,temp_data,0x80,&asn_buf); + } + else if (callbar_ptr->bs_code[jj].param_flag == 1) + { + sprintf(tlv5,"%s.3-%d",tlv4,tag5++); + if (tele_bittostr(callbar_ptr->bs_code[jj].tele_code,temp_data,1)) + buf_len = add_tlv(tlv5,1,temp_data,0x80,&asn_buf); + } + sprintf(tlv5,"%s.4-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&callbar_ptr->ss_status[jj],0x80,&asn_buf); + } + } + } + if (sub_data->ss_info.param_flag & 0x08) // ss data + { + ss_ptr = (ExtSsData_struct *)&sub_data->ss_info.ss_data; + for(jj = 0;jj < 16;jj ++) + { + kk = 0x01 << jj; + if (ss_ptr->param_flag & kk) + { + sprintf(tlv2,"%s.3-%d",tlv1,tag2++); + tag3 = 1; + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); + buf_len = add_tlv(tlv3,1,&ss_ptr->ss_code[jj],0x00,&asn_buf); + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); + buf_len = add_tlv(tlv3,1,&ss_ptr->ss_status[jj],0x80,&asn_buf); + if (ss_ptr->subs_opt[jj].choice_flag == 1) + { + sprintf(tlv3,"%s.2-%d",tlv2,tag3++); + temp_buf[0] = ss_ptr->subs_opt[jj].choice.clires_opt; + buf_len = add_tlv(tlv3,1,temp_buf,0x80,&asn_buf); + } + else if (ss_ptr->subs_opt[jj].choice_flag == 2) + { + sprintf(tlv3,"%s.1-%d",tlv2,tag3++); + temp_buf[0] = ss_ptr->subs_opt[jj].choice.over_cate; + buf_len = add_tlv(tlv3,1,temp_buf,0x80,&asn_buf); + } + } + } + } + } + + if (flag & 0x10) // odb-data + { + if(sub_data->odb_data.param_flag & 0x03) + { + sprintf(tlv1,"8-%d",tag1++); + tag2 = 1; + if (sub_data->odb_data.param_flag & 0x01) // ODB general data + { + sprintf(tlv2,"%s.3-%d",tlv1,tag2++); + temp_buf[0] = sub_data->odb_data.odb_general >> 8; + temp_buf[1] = sub_data->odb_data.odb_general; + len = bytestrtobitstr(temp_data,temp_buf,6); + //len = bytestrtobitstr(temp_data,temp_buf,15); /* odb is 6bitstring for version1/2 */ + buf_len = add_tlv(tlv2,len,temp_data,0x00,&asn_buf); + } + if (sub_data->odb_data.param_flag & 0x02) // ODB HPLMN data + { + sprintf(tlv2,"%s.3-%d",tlv1,tag2++); + temp_buf[0] = sub_data->odb_data.odb_hplmn; + len = bytestrtobitstr(temp_data,temp_buf,4); + buf_len = add_tlv(tlv2,len,temp_data,0x00,&asn_buf); + } + } + } + + + if (flag & 0x100) // roaming restriction due to unsuppoerted feature + { + sprintf(tlv1,"9-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x200) // regional Subscription Data + { + if (sub_data->zc_list.list_len > ZONECODE_LEN) + return RER; + for (jj = 0;jj < sub_data->zc_list.list_len;jj ++) + { + sprintf(tlv1,"10-%d.4-%d",tag1,jj+1); + buf_len = add_tlv(tlv1,2,sub_data->zc_list.zone_code[jj],0x00,&asn_buf); + } + tag1 ++; + } + return buf_len; +} + +int extract_Sub_Data(Sub_data_struct *sub_data , u32 buf_len , u8 *buf) +{ + ASN_BUF asn_buf; + int len,jj,index; + int temp_len,ss_mask; + u32 flag=0; + u8 tag1; + char tlv2[32],tlv3[32]; + u8 temp_buf[256],temp_data[256]; + struct ExtFwdInfo_struct *fwd_ptr; + struct ExtCallBarInfo_struct *callbar_ptr; + struct ExtSsData_struct *ss_ptr; + + sub_data->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + flag |= 0x01; + memcpy(sub_data->imsi,temp_buf,len); + } + if ((len=get_tlv("1",temp_buf,&asn_buf)) > 2) + { + flag |= 0x02; + sub_data->msisdn[0] = len; + memcpy(sub_data->msisdn+1,temp_buf,len); + } + if (get_tlv("2",temp_buf,&asn_buf) > 0) + { + flag |= 0x04; + sub_data->category = temp_buf[0]; + } + if(get_tlv("3",temp_buf,&asn_buf) > 0) + { + flag |= 0x08; + sub_data->sub_status = temp_buf[0]; + } + sub_data->odb_data.param_flag = 0; + len = get_tlv("8.3-1",temp_buf,&asn_buf); //odb-data->odb->GreneralData + if (len != -1) + { + flag |= 0x10; // odb - data + sub_data->odb_data.param_flag |= 0x01; //odb general + jj = bitstrtobytestr(temp_data,temp_buf,len); + sub_data->odb_data.odb_general = bcdtou32(temp_data,jj); + } + len = get_tlv("8.3-2",temp_buf,&asn_buf); + if (len != -1) + { + flag |= 0x10; // odb - data + sub_data->odb_data.param_flag |= 0x02; // odb hplmn + jj = bitstrtobytestr(temp_data,temp_buf,len); + sub_data->odb_data.odb_hplmn = bcdtou32(temp_data,jj); + } + temp_len = 0; + for (jj = 0;jj < BSLIST_LEN;jj ++) // bearer Service List + { + sprintf(tlv2,"4.4-%d",jj+1); + if (get_tlv(tlv2,temp_buf,&asn_buf) < 1) + break; + temp_data[jj] = temp_buf[0]; + temp_len ++; + flag |= 0x20; + } + sub_data->bearer_data = bearer_strtobit(temp_data,temp_len); + temp_len = 0; + for (jj = 0;jj < TSLIST_LEN;jj ++) // tele Service List + { + sprintf(tlv2,"6.4-%d",jj+1); + if (get_tlv(tlv2,temp_buf,&asn_buf) < 1) + break; + temp_data[jj] = temp_buf[0]; + temp_len++; + flag |= 0x40; + } + sub_data->tele_data = tele_strtobit(temp_data,temp_len); + sub_data->ss_info.param_flag = 0; + tag1 = 1; ss_mask = 0; + for(index=0;index<3;index++) + { + if (!(ss_mask & 0x01) && get_tlv("7.0",temp_buf,&asn_buf) != -1) // forwarding info + { + flag |= 0x80; // ss info + sub_data->ss_info.param_flag |= 0x01; // fwd info + fwd_ptr = (ExtFwdInfo_struct *)&sub_data->ss_info.fwd_info; + fwd_ptr->param_flag = 0; + for (jj = 0;jj < 4;jj ++) + { + fwd_ptr->fwd_feat[jj].param_flag = 0; + fwd_ptr->fwd_feat[jj].bs_code.param_flag = 0; + sprintf(tlv2,"7.0-%d.4",tag1); // ss code + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len > 0) + { + fwd_ptr->param_flag |= (0x01 << jj); + fwd_ptr->ss_code[jj] = temp_buf[0]; + ss_mask |= 0x01; + } + else + break; + sprintf(tlv2,"7.0-%d.16.16",tag1); // forward feature + sprintf(tlv3,"%s.2",tlv2); // bearer code of bs code + len = get_tlv(tlv3,temp_buf,&asn_buf); + if (len > 0) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x01; + fwd_ptr->fwd_feat[jj].bs_code.param_flag = 2; // bearer + fwd_ptr->fwd_feat[jj].bs_code.bearer_code = bearer_strtobit(temp_buf,1); + } + sprintf(tlv3,"%s.3",tlv2); // tele code of bs code + len = get_tlv(tlv3,temp_buf, &asn_buf); + if (len >= 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x01; // bs code + fwd_ptr->fwd_feat[jj].bs_code.param_flag = 1;// tele + fwd_ptr->fwd_feat[jj].bs_code.tele_code = tele_strtobit(temp_buf,1); + } + sprintf(tlv3,"%s.4",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x02; // ss status + fwd_ptr->fwd_feat[jj].ss_status = temp_buf[0]; + } + sprintf(tlv3,"%s.5",tlv2); + len = get_tlv(tlv3,temp_buf,&asn_buf); + if (len >= 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x04; // fwd to num + fwd_ptr->fwd_feat[jj].fwdto_num[0] = len; + memcpy(fwd_ptr->fwd_feat[jj].fwdto_num+1,temp_buf,len); + } + sprintf(tlv3,"%s.6",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x08; // fwd opt + fwd_ptr->fwd_feat[jj].fwd_option = temp_buf[0]; + } + sprintf(tlv3,"%s.7",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x10; // norc time + fwd_ptr->fwd_feat[jj].norc_time = temp_buf[0]; + } + tag1 ++; + } + } + if (!(ss_mask & 0x02) && get_tlv("7.1",temp_buf,&asn_buf) != -1) // call Barring Info + { + flag |= 0x80; // ss info + sub_data->ss_info.param_flag |= 0x02; // call bar info + callbar_ptr = (ExtCallBarInfo_struct *)&sub_data->ss_info.call_info; + callbar_ptr->param_flag = 0; + for (jj = 0;jj < 5;jj ++) + { + callbar_ptr->bs_code[jj].param_flag = 0; + sprintf(tlv2,"7.1-%d.4",tag1); //callbarringInfo + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + callbar_ptr->param_flag |= (0x01 << jj); // ss code + callbar_ptr->ss_code[jj] = temp_buf[0]; + ss_mask |= 0x02; + } + else + break; + sprintf(tlv2,"7.1-%d.16.16",tag1); + sprintf(tlv3,"%s.4",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + callbar_ptr->ss_status[jj] = temp_buf[0]; + sprintf(tlv3,"%s.2",tlv2); + len = get_tlv(tlv3,temp_buf,&asn_buf); + if (len >= 1) + { + callbar_ptr->bs_code[jj].param_flag = 2; // bearer + callbar_ptr->bs_code[jj].bearer_code = bearer_strtobit(temp_buf,1); + } + sprintf(tlv3,"%s.3",tlv2); + len = get_tlv(tlv3,temp_buf,&asn_buf); + if (len >= 1) + { + callbar_ptr->bs_code[jj].param_flag = 1; // bearer + callbar_ptr->bs_code[jj].tele_code = tele_strtobit(temp_buf,1); + } + tag1 ++; + } + } + if (!(ss_mask & 0x04) && get_tlv("7.3",temp_buf,&asn_buf) != -1) // ss_Data + { + flag |= 0x80; // ss info + sub_data->ss_info.param_flag |= 0x08; // ss data + ss_ptr = (ExtSsData_struct *)&sub_data->ss_info.ss_data; + ss_ptr->param_flag = 0; + for(jj = 0;jj < 16;jj ++) + { + sprintf(tlv2,"7.3-%d.4-1",tag1); + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + ss_ptr->param_flag |= (0x01 << jj); + ss_ptr->ss_code[jj] = temp_buf[0]; + ss_mask |= 0x04; + } + else + break; + sprintf(tlv2,"7.3-%d.4-2",tag1); //ss-status + // len = get_tlv(tlv2,temp_buf,&asn_buf); + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + ss_ptr->ss_status[jj] = temp_buf[0]; + ss_ptr->subs_opt[jj].choice_flag = 0; + sprintf(tlv2,"7.3-%d.2-3",tag1); //cliRestrictionOption + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + ss_ptr->subs_opt[jj].choice_flag = 1; // clires opt + ss_ptr->subs_opt[jj].choice.clires_opt = temp_buf[0]; + } + sprintf(tlv2,"7.3-%d.1-3",tag1); //overrideCategory + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + ss_ptr->subs_opt[jj].choice_flag = 2; // clires opt + ss_ptr->subs_opt[jj].choice.over_cate = temp_buf[0]; + } + sprintf(tlv2,"7.3-%d.2-2",tag1); // bearer code + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len > 0) + ss_ptr->bs_code[jj].bearer_code = bearer_strtobit(temp_buf,1); + sprintf(tlv2,"7.3-%d.3",tag1); // tele code + len = get_tlv(tlv2,temp_buf, &asn_buf); + if (len >= 1) + ss_ptr->bs_code[jj].tele_code = tele_strtobit(temp_buf,1); + tag1 ++; + } + } + } + if (get_null("9",&asn_buf) != -1) //get roaming restriction data + { + flag |= 0x100; + sub_data->roam_feature = 1; + } + len = get_tlv("10",temp_buf,&asn_buf); //regional Subscription Data + if (len > 0) + { + flag |= 0x200; + for (jj = 0;jj < ZONECODE_LEN;jj ++) + { + sprintf(tlv2,"10.4-%d",jj+1); + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len == 2) + memcpy(sub_data->zc_list.zone_code[jj],temp_buf,2); + else + break; + } + sub_data->zc_list.list_len = jj; + } + + sub_data->param_flag = flag; + return ROK; +} + +int assign_SendParaRes(struct MapSP_Res *sp_ptr,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0,param_num,index,temp_len; + u8 temp_buf[256]; + char tag[16]; + //char str[640]; + u8 uSubDataCount = 0 ; + + asn_encode(buf,&asn_buf); + flag = sp_ptr->param_flag; + + if (flag & 0x01) // has sentparalist + { + param_num = sp_ptr->sendparamlist_num ; + if( param_num > 6) + { + mapp_log_debug("send param response sentparalist num error, is more than 6");;//do report err + param_num = 6 ; + } + + for( index = 0 ; index < param_num ; index++ ) + { + if( sp_ptr->sendparalist[index].choice_flag == 4 ) + { + uSubDataCount++; + } + } + + if( uSubDataCount > 2) + { + mapp_log_debug("send param response sentparalist sub data is too much, may exceed the supported map message len\r\n");;//do report err + return buf_len; + } + + buf_len = add_null("16",0x20,&asn_buf); + for( index=0; index< param_num ; index++) + { + switch( sp_ptr->sendparalist[index].choice_flag ) + { + case 1: //imsi + sprintf(tag,"16.0-%d",index+1); + buf_len = add_tlv(tag,IMSI_LEN,sp_ptr->sendparalist[index].SP_Res_Choice.imsi,0x80,&asn_buf); + break; + case 2: // authlist set + sprintf(tag,"16.1-%d",index+1); + temp_len = assign_authset( (struct AuthSet_struct* )&sp_ptr->sendparalist[index].SP_Res_Choice.auth_set, temp_buf ); + buf_len = add_tlv(tag, temp_len, temp_buf, 0xa0, &asn_buf); + break; + case 4: // sub data + sprintf(tag,"16.2-%d",index+1); + memset( temp_buf ,0 ,256); + temp_len = assign_Sub_Data( &sp_ptr->sendparalist[index].SP_Res_Choice.sub_data , temp_buf ); + //Bcd2Str_Space(str, temp_buf, temp_len); + //printf("\r\nsub data code :[%d]\r\n%s\r\n",temp_len,str); + buf_len = add_tlv(tag, temp_len, temp_buf, 0xa0, &asn_buf); + break; + case 8: //ki + sprintf(tag,"16.4-%d",index+1); + buf_len = add_tlv(tag,16,sp_ptr->sendparalist[index].SP_Res_Choice.ki,0x80,&asn_buf); + break; + default: + break; + } + } + } + //Bcd2Str_Space(str, buf, buf_len); + //printf("\r\nSend para Res code :[%d]\r\n%s\r\n",buf_len,str); + return buf_len; +} + +int extract_SendParaRes ( struct MapSP_Res *sp_ptr, u32 buf_len, u8 * buf ) // lw add +{ + ASN_BUF asn_buf; + int index; + u8 temp_buf[256]; + int temp_len; + char tag[16]; + + sp_ptr->param_flag = 0; + + if( buf_len == 0 ) + return RER; + if( asn_decode_v3 ( buf, buf_len, &decErr, &asn_buf ) == -1 ) + return RER; + for ( index = 0; index < 6; index++ ) + { + + sprintf(tag,"16.0-%d",index+1); + if( ( ( temp_len = get_tlv ( tag, temp_buf, &asn_buf ) ) != -1 ) && ( ( temp_buf[IMSI_LEN - 1] & 0xf0 ) == 0xf0 ) ) + { + sp_ptr->param_flag |= 0x01; + sp_ptr->sendparamlist_num++; + sp_ptr->sendparalist[index].choice_flag = 1; + memcpy ( sp_ptr->sendparalist[index].SP_Res_Choice.imsi, temp_buf, temp_len ); + continue; + } + else + { + sprintf(tag,"16.1-%d",index+1); + if( ( temp_len = get_tlv ( tag, temp_buf, &asn_buf ) ) > 0 ) + { + sp_ptr->param_flag |= 0x01; + sp_ptr->sendparamlist_num++; + if( ( extract_authset ( ( struct AuthSet_struct * ) &sp_ptr->sendparalist[index].SP_Res_Choice.auth_set, temp_len, temp_buf ) ) != 0 ) + { + sp_ptr->sendparalist[index].choice_flag = 2; + continue; + } + } + else + { + sprintf(tag,"16.2-%d",index+1); + if( ( temp_len = get_tlv ( tag, temp_buf, &asn_buf ) ) > 0 ) + { + sp_ptr->param_flag |= 0x01; + sp_ptr->sendparamlist_num++; + if( ( extract_Sub_Data ( &sp_ptr->sendparalist[index].SP_Res_Choice.sub_data, temp_len, temp_buf ) ) != 0 ) + { + sp_ptr->sendparalist[index].choice_flag = 4; + continue; + } + } + else + { + sprintf(tag,"16.4-%d",index+1); + if( ( temp_len = get_tlv ( tag, temp_buf, &asn_buf ) ) > 0 ) + { + sp_ptr->sendparalist[index].choice_flag = 8; + memcpy ( sp_ptr->sendparalist[index].SP_Res_Choice.ki, temp_buf, temp_len ); + sp_ptr->sendparamlist_num++; + continue; + } + else + { + if( 0 == index ) + { + return RER; + } + else + { + break; + } + } + } + } + } + } + //} + return ROK; +} + + + + + + + + + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding noteSubscriberPresent argument*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_NotPresentArg(struct MapNP_Arg *np_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + asn_encode(buf,&asn_buf); + flag = np_ptr->param_flag; + if (flag == 0x01) // has lmsi + { + + buf_len = add_tlv("4",IMSI_LEN,np_ptr->imsi,0x00,&asn_buf); + } + else + { + mapp_log_debug("nosubsriberpresent param flag error"); + return -1; + } + + return buf_len; +} + +int extract_NotPresentArg( struct MapNP_Arg *np_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + np_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4",temp_buf,&asn_buf); // get IMSI + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + np_ptr->param_flag = 0x01; + memcpy(np_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("nosubsriberpresent lack imsi or imsi err\r\n"); + return RER; + } + + return ROK; +} + + + + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ProcessUnstructuredSS-Data argument*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_ProcessUSSDArg(struct MapPUSSD_Arg *ussd_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + asn_encode(buf,&asn_buf); + flag = ussd_ptr->param_flag; + if (flag == 0x01) + { + + buf_len = add_tlv("4",ussd_ptr->ussd_len,ussd_ptr->ussd_data,0x00,&asn_buf); + } + else + { + mapp_log_debug("Process USSD param flag error"); + return -1; + } + + return buf_len; +} + +int extract_ProcessUSSDArg( struct MapPUSSD_Arg *ussd_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ussd_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4",temp_buf,&asn_buf); + if (len != -1) + { + ussd_ptr->param_flag = 0x01; + ussd_ptr->ussd_len = len; + memcpy(ussd_ptr->ussd_data,temp_buf,len); + } + else + { + mapp_log_debug("Process USSD lack imsi"); + return RER; + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ProcessUnstructuredSS-Data ResPonse*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_ProcessUSSDRes(struct MapPUSSD_Res *ussd_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + asn_encode(buf,&asn_buf); + flag = ussd_ptr->param_flag; + if (flag == 0x01) + { + buf_len = add_tlv("4",ussd_ptr->ussd_len,ussd_ptr->ussd_data,0x00,&asn_buf); + } + else + { + mapp_log_debug("Process USSD param flag error"); + return -1; + } + + return buf_len; +} + +int extract_ProcessUSSDRes( struct MapPUSSD_Res *ussd_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ussd_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4",temp_buf,&asn_buf); + if (len != -1) + { + ussd_ptr->param_flag = 0x01; + ussd_ptr->ussd_len = len; + memcpy(ussd_ptr->ussd_data,temp_buf,len); + } + else + { + mapp_log_debug("Process USSD lack imsi"); + return RER; + } + + return ROK; +} + + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding BeginSubscriberActivity Argmnet*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_SAArg(struct MapSA_Arg *sa_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + asn_encode(buf,&asn_buf); + flag = sa_ptr->param_flag; + if (flag == 0x03) + { + buf_len = add_tlv("4-1",IMSI_LEN+1,sa_ptr->imsi,0x00,&asn_buf); + buf_len = add_tlv("4-2",9,sa_ptr->Enity_num,0x00,&asn_buf); + } + else + { + mapp_log_debug(" BeginSubscriberActivity param flag error"); + return -1; + } + + return buf_len; +} + +int extract_SAArg( struct MapSA_Arg *sa_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + sa_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4-1",temp_buf,&asn_buf); + if (len == IMSI_LEN + 1) + { + sa_ptr->param_flag |= 0x01; + memcpy(sa_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("Process USSD lack imsi"); + return RER; + } + + len = get_tlv("4-2",temp_buf,&asn_buf); + if (len != -1) + { + sa_ptr->param_flag |= 0x01; + sa_ptr->enity_len = len; + memcpy(sa_ptr->Enity_num,temp_buf,len); + } + else + { + mapp_log_debug("Process USSD lack Enity_nu"); + return RER; + } + + return ROK; +} + + + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding PerformHandover Argmnet*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_HOArg(struct MapHO_Arg *ho_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + asn_encode(buf,&asn_buf); + flag = ho_ptr->param_flag; + if (flag & 0x01) + { + buf_len = add_tlv("4-1",7,ho_ptr->tgt_cellID,0x00,&asn_buf); + } + else + { + mapp_log_debug(" PerformHanover lack target cell id"); + return -1; + } + + if (flag & 0x02) + { + buf_len = add_tlv("4-2",7,ho_ptr->srv_cellID,0x00,&asn_buf); + } + else + { + mapp_log_debug(" PerformHanover lack service cell id"); + return -1; + } + + if (flag & 0x04) + { + buf_len = add_tlv("4-3",10,ho_ptr->chl_type,0x00,&asn_buf); + } + else + { + mapp_log_debug(" PerformHanover lack channel type"); + return -1; + } + + if (flag & 0x08) + { + buf_len = add_tlv("4-4",2,ho_ptr->class_mark,0x00,&asn_buf); + } + else + { + mapp_log_debug(" PerformHanover lack class mark info"); + return -1; + } + + if (flag & 0x10) + { + buf_len = add_tlv("11",1,&ho_ptr->ho_priority,0x80,&asn_buf); + } + + + if (flag & 0x20) + { + buf_len = add_tlv("12",8,ho_ptr->kc,0x80,&asn_buf); + } + + + return buf_len; +} + +int extract_HOArg( struct MapHO_Arg *ho_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ho_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4-1",temp_buf,&asn_buf); + if (len == 7) + { + ho_ptr->param_flag |= 0x01; + memcpy(ho_ptr->tgt_cellID,temp_buf,len); + } + else + { + mapp_log_debug(" PerformHanover lack target cell id"); + } + + len = get_tlv("4-2",temp_buf,&asn_buf); + if (len == 7) + { + ho_ptr->param_flag |= 0x02; + memcpy(ho_ptr->srv_cellID,temp_buf,len); + } + else + { + mapp_log_debug(" PerformHanover lack service cell id"); + } + + len = get_tlv("4-3",temp_buf,&asn_buf); + if (len == 10) + { + ho_ptr->param_flag |= 0x04; + memcpy(ho_ptr->chl_type,temp_buf,len); + } + else + { + mapp_log_debug(" PerformHanover lack channel type"); + } + + len = get_tlv("4-4",temp_buf,&asn_buf); + if (len == 2) + { + ho_ptr->param_flag |= 0x08; + memcpy(ho_ptr->class_mark,temp_buf,len); + } + else + { + mapp_log_debug(" PerformHanover lack class mark info"); + } + + len = get_tlv("11",temp_buf,&asn_buf); + if (len == 1) + { + ho_ptr->param_flag |= 0x10; + memcpy(&ho_ptr->ho_priority,temp_buf,len); + } + else + { + mapp_log_debug(" PerformHanover lack handover priority"); + } + + len = get_tlv("12",temp_buf,&asn_buf); + if (len == 8) + { + ho_ptr->param_flag |= 0x20; + memcpy(ho_ptr->kc,temp_buf,len); + } + else + { + mapp_log_debug(" PerformHanover lack kc"); + } + + return ROK; +} + + + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding PerformHandover ResPonse*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_HORes(struct MapHO_Res *ho_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + asn_encode(buf,&asn_buf); + flag = ho_ptr->param_flag; + if (flag & 0x01) + { + + buf_len = add_tlv("4",9,ho_ptr->ho_num,0x00,&asn_buf); + } + else + { + mapp_log_debug("handover res lack handovber"); + return -1; + } + + if (flag & 0x02) + { + + buf_len = add_tlv("16.2",1,&ho_ptr->access_singal_info.protocol_id,0x00,&asn_buf); + buf_len = add_tlv("16.4",ho_ptr->access_singal_info.singal_info_len,ho_ptr->access_singal_info.signal_info,0x00,&asn_buf); + } + else + { + mapp_log_debug("handover res lack handovber"); + return -1; + } + + return buf_len; +} + +int extract_HORes( struct MapHO_Res *ho_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ho_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4",temp_buf,&asn_buf); + if (len != -1) + { + ho_ptr->param_flag |= 0x01; + memcpy(ho_ptr->ho_num,temp_buf,len); + } + else + { + mapp_log_debug("performhandover lack handover number"); + return RER; + } + + len = get_tlv("16",temp_buf,&asn_buf); + if (len != -1) + { + len = get_tlv("16.2",temp_buf,&asn_buf); + if( len == 1) + { + memcpy(&ho_ptr->access_singal_info.protocol_id , temp_buf ,len); + } + else + { + mapp_log_debug("performhandover lack protocol_id"); + return RER; + } + + len = get_tlv("16.4",temp_buf,&asn_buf); + if( len != -1) + { + memcpy(ho_ptr->access_singal_info.signal_info, temp_buf ,len); + ho_ptr->access_singal_info.singal_info_len= len; + } + else + { + mapp_log_debug("performhandover lack protocol_id"); + return RER; + } + } + else + { + mapp_log_debug("performhandover lack access_singal_info"); + return RER; + } + + return ROK; +} + + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding PreformSubsequenceHandover Arg*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_PFSHOArg(struct MapPFSHO_Arg *psho_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + //char str[512]; + + asn_encode(buf,&asn_buf); + flag = psho_ptr->param_flag; + if (flag & 0x01) + { + buf_len = add_tlv("4-1",GCID_LEN,psho_ptr->target_id,0x00,&asn_buf); + } + else + { + mapp_log_debug("performsubsequenthandover arg lack target id"); + return -1; + } + if (flag & 0x02) + { + buf_len = add_tlv("4-2",GCID_LEN,psho_ptr->service_id,0x00,&asn_buf); + } + else + { + mapp_log_debug("performsubsequenthandover arg lack service id"); + return -1; + } + + if (flag & 0x04) + { + buf_len = add_tlv("4-3",ISDN_LEN,psho_ptr->msc_num,0x00,&asn_buf); + } + else + { + mapp_log_debug("performsubsequenthandover arg lack msc number"); + return -1; + } + + if (flag & 0x08) + { + buf_len = add_tlv("10-4",2,psho_ptr->classmark_info,0x80,&asn_buf); + } + + //Bcd2Str_Space(str, buf, buf_len); + //printf("\r\nPFSHO arg code :[%d]\r\n%s\r\n",buf_len,str); + return buf_len; +} + +int extract_PFSHOArg( struct MapPFSHO_Arg *psho_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + psho_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4",temp_buf,&asn_buf); + if (len == GCID_LEN) + { + psho_ptr->param_flag |= 0x01; + memcpy( psho_ptr->target_id,temp_buf,len); + } + else + { + mapp_log_debug("performsubsequenthandover res lack target id"); + return RER; + } + + len = get_tlv("4",temp_buf,&asn_buf); + if (len == GCID_LEN) + { + psho_ptr->param_flag |= 0x02; + memcpy( psho_ptr->service_id,temp_buf,len); + } + else + { + mapp_log_debug("performsubsequenthandover res lack service id"); + return RER; + } + + len = get_tlv("4-3",temp_buf,&asn_buf); + if (len <= ISDN_LEN ) + { + psho_ptr->param_flag |= 0x04; + psho_ptr->msc_num[0] = len; + memcpy( psho_ptr->msc_num+1,temp_buf,len); + } + else + { + mapp_log_debug("performsubsequenthandover res lack msc number"); + return RER; + } + + len = get_tlv("10-4",temp_buf,&asn_buf); + if (len == 2 ) + { + psho_ptr->param_flag |= 0x08; + memcpy( psho_ptr->classmark_info,temp_buf,len); + } + else + { + mapp_log_debug("performsubsequenthandover lack msc number"); + return RER; + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding PreformSubsequenceHandover res */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ + +int assign_PFSHORes(struct MapPFSHO_Res *psho_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (psho_ptr->param_flag & 0x01) // access_sig_info + { + temp_len = assign_extsiginfo(&psho_ptr->access_sig_info,temp_buf); + buf_len = add_tlv("16",temp_len,temp_buf,0x20,&asn_buf); + } + return buf_len; +} + +int extract_PFSHORes(struct MapPFSHO_Res *psho_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + psho_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("16",temp_buf,&asn_buf); // access_sig_info + if (len != -1) + { + if (!extract_extsiginfo(&psho_ptr->access_sig_info,len,temp_buf)) + return RER; + psho_ptr->param_flag |= 0x01; + } + return ROK; +} + + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding NoteInternalHandover Arg */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ + +int assign_NIHOArg(struct MapNIHO_Arg *niho_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0,temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + flag = niho_ptr->param_flag; + if (flag & 0x01) + { + buf_len = add_tlv("10-1",1,&niho_ptr->ho_type,0x00,&asn_buf); + } + else + { + mapp_log_debug("NoteInternalHandover lack handover type"); + return -1; + } + if (flag & 0x02) + { + buf_len = add_tlv("1-2",GCID_LEN,niho_ptr->target_id,0x80,&asn_buf); + } + + if (flag & 0x04) + { + temp_len = assign_extsiginfo(&niho_ptr->channel_id,temp_buf); + buf_len = add_tlv("2-3",temp_len, temp_buf,0x80,&asn_buf); + } + else + { + mapp_log_debug("NoteInternalHandover lack channel id"); + return -1; + } + + //Bcd2Str_Space(temp_buf, buf, buf_len); + //printf("\r\nNIHO arg code :[%d]\r\n%s\r\n",buf_len,temp_buf); + return buf_len; +} + +int extract_NIHOArg( struct MapNIHO_Arg *niho_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + niho_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("10-1",temp_buf,&asn_buf); + if (len == 1) + { + niho_ptr->param_flag |= 0x01; + memcpy( &niho_ptr->ho_type,temp_buf,len); + } + else + { + mapp_log_debug("NoteInternalHandover lack handover type"); + return RER; + } + + len = get_tlv("1",temp_buf,&asn_buf); + if (len == GCID_LEN) + { + niho_ptr->param_flag |= 0x02; + memcpy(niho_ptr->target_id,temp_buf,len); + } + + len = get_tlv("2",temp_buf,&asn_buf); + if (len != -1 ) + { + if(!extract_extsiginfo(&niho_ptr->channel_id,len,temp_buf)) + return RER; + niho_ptr->param_flag |= 0x04; + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding Tracesubscirberactivity Arg */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ + +int assign_TSAArg(struct MapTSA_Arg *tsa_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + + asn_encode(buf,&asn_buf); + flag = tsa_ptr->param_flag; + if (flag & 0x01) + { + buf_len = add_tlv("0",IMSI_LEN,tsa_ptr->imsi,0x80,&asn_buf); + } + + if (flag & 0x02) + { + buf_len = add_tlv("1",2,tsa_ptr->trace_ref,0x80,&asn_buf); + } + else + { + mapp_log_debug("Tracesubscirberactivity lack call reference"); + return -1; + } + + if (flag & 0x04) + { + buf_len = add_tlv("2",1,&tsa_ptr->trace_type,0x80,&asn_buf); + } + else + { + mapp_log_debug("TracesubscirberactivityTracesubscirberactivity lack call type"); + return -1; + } + + if (flag & 0x08) + { + buf_len = add_tlv("3",tsa_ptr->omc_id_len,tsa_ptr->omc_id,0x80,&asn_buf); + } + + if (flag & 0x10) + { + buf_len = add_tlv("4",3,tsa_ptr->call_ref,0x80,&asn_buf); + } + + + return buf_len; +} + +int extract_TSAArg( struct MapTSA_Arg *tsa_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + tsa_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("0",temp_buf,&asn_buf); + if (len == IMSI_LEN) + { + tsa_ptr->param_flag |= 0x01; + memcpy( &tsa_ptr->imsi,temp_buf,len); + } + + + len = get_tlv("1",temp_buf,&asn_buf); + if (len == 2) + { + tsa_ptr->param_flag |= 0x02; + memcpy(&tsa_ptr->trace_ref,temp_buf,len); + } + + len = get_tlv("2",temp_buf,&asn_buf); + if (len == 1 ) + { + tsa_ptr->param_flag |= 0x04; + memcpy(&tsa_ptr->trace_type,temp_buf,len); + } + + len = get_tlv("3",temp_buf,&asn_buf); + if (len != -1 ) + { + tsa_ptr->param_flag |= 0x08; + tsa_ptr->omc_id_len = len; + memcpy(&tsa_ptr->omc_id,temp_buf,len); + } + + len = get_tlv("4",temp_buf,&asn_buf); + if (len == 3 ) + { + tsa_ptr->param_flag |= 0x04; + memcpy(&tsa_ptr->call_ref,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding BeginSubscriberActivity Arg */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ + +int assign_BSAArg(struct MapBSA_Arg *bsa_ptr, u8 *buf) // lw add +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + + asn_encode(buf,&asn_buf); + flag = bsa_ptr->param_flag; + if (flag & 0x01) + { + buf_len = add_tlv("4-1",IMSI_LEN+1,bsa_ptr->imsi,0x00,&asn_buf); + } + + if (flag & 0x02) + { + buf_len = add_tlv("4-2",bsa_ptr->orgenty_num_len,bsa_ptr->orgenty_num,0x00,&asn_buf); + } + return buf_len; +} + +int extract_BSAArg( struct MapBSA_Arg *bsa_ptr,u32 buf_len,u8 *buf) // lw add +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + bsa_ptr->param_flag = 0; + + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + len = get_tlv("4-1",temp_buf,&asn_buf); + if (len == IMSI_LEN+1) + { + bsa_ptr->param_flag |= 0x01; + memcpy( bsa_ptr->imsi,temp_buf,len); + } + + len = get_tlv("4-2",temp_buf,&asn_buf); + if (len != -1) + { + bsa_ptr->param_flag |= 0x02; + bsa_ptr->orgenty_num_len = len; + memcpy(&bsa_ptr->orgenty_num,temp_buf,len); + } + return ROK; +} + + +/* --->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAP V1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,---*/ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding cancel location argument */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_cancellocarg(struct MapCL_Arg *cl_ptr,u8 *buf,u8 ver) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 temp_buf[256]; + CL_identity *id; + + asn_encode(buf,&asn_buf); + flag = cl_ptr->param_flag; + if( flag & 0x01 ) + { + id = &cl_ptr->id; + if( id->choice_flag == 1 ) + { + buf_len = add_tlv("4-1",IMSI_LEN,id->choice.imsi,0x00,&asn_buf); + } + else if( id->choice_flag == 2 ) + { + buf_len = add_null("16", 0x20, &asn_buf); + buf_len = add_tlv("16-1.4-1",IMSI_LEN,id->choice.imsi_withlmsi.imsi,0x00,&asn_buf); + buf_len = add_tlv("16-1.4-2",4,id->choice.imsi_withlmsi.lmsi,0x00,&asn_buf); + } + } + else + { + mapp_log_debug("cancellocation arg lack identity"); + return RER; + } + + +// if( ver !=3 && flag & 0x02 ) + if( flag & 0x02 ) + { + temp_buf[0] = cl_ptr->type; + buf_len = add_tlv("10-2",1,temp_buf,0x00,&asn_buf); + } + + return buf_len; +} + +int extract_cancellocarg(struct MapCL_Arg *cl_ptr,u32 buf_len,u8 *buf,u8 ver) +{ + ASN_BUF asn_buf; + int len1; + u8 temp_buf1[256],temp_buf2[256]; + CL_identity *id; + + cl_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if( ( get_tlv("4-1",temp_buf1,&asn_buf) == IMSI_LEN ) + && ((temp_buf1[IMSI_LEN-1]&0xf0) == 0xf0 ) ) + { + id = &cl_ptr->id; + cl_ptr->param_flag |= 0x01; + id->choice_flag = 1; + memcpy( id->choice.imsi , temp_buf1 , IMSI_LEN ); + } + else + { + if( ( get_tlv("16-1.4-1",temp_buf1,&asn_buf) == IMSI_LEN ) && ( get_tlv("16-1.4-2",temp_buf2,&asn_buf) == LMSI_LEN ) + && ((temp_buf1[IMSI_LEN-1] & 0xf0 ) == 0xf0 ) ) + { + id = &cl_ptr->id; + cl_ptr->param_flag |= 0x01; + id->choice_flag = 2; + memcpy( id->choice.imsi_withlmsi.imsi , temp_buf1 , IMSI_LEN); + memcpy( id->choice.imsi_withlmsi.lmsi , temp_buf2 ,LMSI_LEN); + } + } + + if( ver !=3 && ( len1 = get_tlv("10-2",temp_buf1,&asn_buf) ) == 1 ) + { + cl_ptr->param_flag |= 0x02; + memcpy( &cl_ptr->type,temp_buf1,len1); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding cancel location response */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_cancellocres(struct MapCL_Res *cl_ptr,u8 *buf) +{ + return 0; +} + +int extract_cancellocres(struct MapCL_Res *cl_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding purge ms argument */ +/* ++++++++++++++++++++++++++++++++++++ */ +int assign_purgemsarg(struct MapPMS_Arg *pms_ptr,u8 *buf,u8 version) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + flag = pms_ptr->param_flag; + if (flag & 0x01) // IMSI + buf_len = add_tlv("4-1",IMSI_LEN,pms_ptr->imsi,0x00,&asn_buf); // add IMSI parameter + else + { + mapp_log_debug("purgeMS request lack IMSI"); + return RER; + } + tag1 = 2; + if (flag & 0x02) // VLR address + { + if (version == 2) + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_tlv(tlv1,pms_ptr->vlr_num[0],pms_ptr->vlr_num+1,0,&asn_buf); + } + else + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,pms_ptr->vlr_num[0],pms_ptr->vlr_num+1,0x80,&asn_buf); + } + } + if (flag & 0x04) // sgsn address + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,pms_ptr->sgsn_num[0],pms_ptr->sgsn_num+1,0x80,&asn_buf); + } + return buf_len; +} + +int extract_purgemsarg(struct MapPMS_Arg *pms_ptr,u32 buf_len,u8 *buf,u8 version) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + pms_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_purge MS arg,buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); // get IMSI + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + pms_ptr->param_flag |= 0x01; + memcpy(pms_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("purge ms indicate error IMSI"); + return RER; + } + if (version == 2) // get VLR number + len = get_tlv("4-2",temp_buf,&asn_buf); + else + len = get_tlv("0-2",temp_buf,&asn_buf); + if (len > 2) + { + pms_ptr->param_flag |= 0x02; + pms_ptr->vlr_num[0] = len; + memcpy(pms_ptr->vlr_num+1,temp_buf,len); + } + if ((len = get_tlv("1",temp_buf,&asn_buf)) > 2) // get sgsn number + { + pms_ptr->param_flag |= 0x04; + pms_ptr->sgsn_num[0] = len; + memcpy(pms_ptr->sgsn_num+1,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding purge ms response */ +/* ++++++++++++++++++++++++++++++++++++ */ +int assign_purgemsres(struct MapPMS_Res *pms_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (pms_ptr->param_flag & 0x01) // freeze TMSI + buf_len = add_null("0",0x80,&asn_buf); + if (pms_ptr->param_flag & 0x02) // freeze P-TMSI + buf_len = add_null("1",0x80,&asn_buf); + return buf_len; +} + +int extract_purgemsres(struct MapPMS_Res *pms_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + pms_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) > 0) // freeze TMSI + { + pms_ptr->param_flag |= 0x01; + pms_ptr->freeze_tmsi = 1; + } + if (get_tlv("1",temp_buf,&asn_buf) > 0) // freeze P-TMSI + { + pms_ptr->param_flag |= 0x02; + pms_ptr->freeze_ptmsi = 1; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send identification argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndidentarg(struct MapSI_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ptr->param_flag & 0x01) // TMSI + buf_len = add_tlv("4",TMSI_LEN,ptr->tmsi,0x00,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_sndidentarg(struct MapSI_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4",temp_buf,&asn_buf) == TMSI_LEN) + { + ptr->param_flag |= 0x01; + memcpy(ptr->tmsi,temp_buf,TMSI_LEN); + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send identification response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndidentres(struct MapSI_Res *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int ii; + int temp_len; + u8 temp_buf[256]; + char tlv2[32]; + + asn_encode(buf,&asn_buf); + if (ptr->param_flag & 0x01) // IMSI + buf_len = add_tlv("4",IMSI_LEN,ptr->imsi,0x00,&asn_buf); + else + return RER; + if (ptr->param_flag & 0x02) // auth list + { + for (ii = 0;ii < ptr->authlist.auth_len;ii ++) + { + temp_len = assign_authset(&ptr->authlist.auth_set[ii],temp_buf); + if (temp_len == RER) + break; + sprintf(tlv2,"16-%d",ii+1); + buf_len = add_tlv(tlv2,temp_len,temp_buf,0x20,&asn_buf); + } + } + return buf_len; +} + +int extract_sndidentres(struct MapSI_Res *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + int ii; + char tlv2[32]; + + ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + ptr->param_flag |= 0x01; + memcpy(ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + for (ii = 0;ii < AUTHLIST_LEN;ii++) + { + ptr->authlist.auth_set[ii].param_flag = 0; + sprintf(tlv2,"16-%d",ii+1); + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len <= 0) // has not data + break; + if (!extract_authset(&ptr->authlist.auth_set[ii],len,temp_buf)) + break; + ptr->param_flag |= 0x02; + ptr->authlist.auth_len++; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding update GPRS location argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_upgprslocarg(struct MapUGL_Arg *ugl_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (ugl_ptr->param_flag & 0x01) // IMSI + buf_len = add_tlv("4-1",IMSI_LEN,ugl_ptr->imsi,0x00,&asn_buf); + else + return RER; + if (ugl_ptr->param_flag & 0x02) // sgsn number + buf_len = add_tlv("4-2",ugl_ptr->sgsn_num[0],ugl_ptr->sgsn_num+1,0x00,&asn_buf); + else + return RER; + if (ugl_ptr->param_flag & 0x04) // sgsn address + buf_len = add_tlv("4-3",ugl_ptr->sgsn_add[0],ugl_ptr->sgsn_add+1,0x00,&asn_buf); + else + return RER; + + if (ugl_ptr->param_flag & 0x08) // sgsn capability + { +// buf_len = add_null("0-4", 0xa0, &asn_buf); + temp_len = assign_sgsnCapability(&ugl_ptr->sgsn_cap, temp_buf); + if(temp_len != RER) + buf_len = add_tlv("0-4", temp_len, temp_buf, 0xa0, &asn_buf); + } + + return buf_len; +} + +int extract_upgprslocarg(struct MapUGL_Arg *ugl_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ugl_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4-1",temp_buf,&asn_buf); // IMSI + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + ugl_ptr->param_flag |= 0x01; + memcpy(ugl_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("4-2",temp_buf,&asn_buf); // sgsn number + if (len > 0 && len <= ISDN_LEN) + { + ugl_ptr->param_flag |= 0x02; + ugl_ptr->sgsn_num[0] = len; + memcpy(ugl_ptr->sgsn_num+1,temp_buf,len); + } + else + return RER; + len = get_tlv("4-3",temp_buf,&asn_buf); // sgsn address + if (len > 0 && len <= GSN_LEN) + { + ugl_ptr->param_flag |= 0x04; + ugl_ptr->sgsn_add[0] = len; + memcpy(ugl_ptr->sgsn_add+1,temp_buf,len); + } + else + return RER; + + len = get_tlv("0-4",temp_buf,&asn_buf); // sgsn capability + if (len > 0) + { + ugl_ptr->param_flag |= 0x08; + extract_sgsnCapability(&ugl_ptr->sgsn_cap, len, temp_buf); + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding update GPRS location response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_upgprslocres(struct MapUGL_Res *ugl_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ugl_ptr->param_flag & 0x01) // hlr number + buf_len = add_tlv("4",ugl_ptr->hlr_num[0],ugl_ptr->hlr_num+1,0x00,&asn_buf); + else + return RER; + + if (ugl_ptr->param_flag & 0x02) // add capability + { + buf_len = add_null("5", 0x80, &asn_buf); + } + + return buf_len; +} + +int extract_upgprslocres(struct MapUGL_Res *ugl_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ugl_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); // hlr number + if (len > 0 && len <= ISDN_LEN) + { + ugl_ptr->param_flag |= 0x01; + ugl_ptr->hlr_num[0] = len; + memcpy(ugl_ptr->hlr_num+1,temp_buf,len); + } + else + return RER; + + len = get_tlv("0",temp_buf,&asn_buf); // add capability + if (len > 0) + { + ugl_ptr->add_cap = 1; + ugl_ptr->param_flag |= 0x02; + } + + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding provider subscriber info argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prvsubinfoarg(struct MapPSI_Arg *psi_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (psi_ptr->param_flag & 0x01) // IMSI + buf_len = add_tlv("0",IMSI_LEN,psi_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (psi_ptr->param_flag & 0x02) // LMSI + buf_len = add_tlv("1",LMSI_LEN,psi_ptr->lmsi,0x80,&asn_buf); + if (psi_ptr->param_flag & 0x04) // request info + { + if (psi_ptr->req_info.param_flag & 0x01) // location info + buf_len = add_null("2.0",0x80,&asn_buf); + if (psi_ptr->req_info.param_flag & 0x02) // subscriber state + buf_len = add_null("2.1",0x80,&asn_buf); + } + return buf_len; +} + +int extract_prvsubinfoarg(struct MapPSI_Arg *psi_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + psi_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // IMSI + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + psi_ptr->param_flag |= 0x01; + memcpy(psi_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + if (get_tlv("1",temp_buf,&asn_buf) == LMSI_LEN) // lmsi + { + psi_ptr->param_flag |= 0x02; + memcpy(psi_ptr->lmsi,temp_buf,LMSI_LEN); + } + if (get_tlv("2.0",temp_buf,&asn_buf) != -1) // location info + { + psi_ptr->param_flag |= 0x04; + psi_ptr->req_info.param_flag |= 0x01; + psi_ptr->req_info.loc_info = 1; + } + if (get_tlv("2.1",temp_buf,&asn_buf) != -1) // subscriber state + { + psi_ptr->param_flag |= 0x04; + psi_ptr->req_info.param_flag |= 0x02; + psi_ptr->req_info.sub_state = 1; + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding provider subscriber info response */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prvsubinfores(struct MapPSI_Res *psi_ptr,u8 *buf) +{ + int buf_len=0; + ASN_BUF asn_buf; + u_char info_str[1024]; + + if (psi_ptr->param_flag & 0x01) // subscriber info + { + buf_len = assign_subinfo(&psi_ptr->sub_info,buf); + memcpy(info_str,buf,buf_len%1024); + AsnEncode(buf,256,&asn_buf); + buf_len = AddTLV("16",buf_len,info_str,0x20,&asn_buf); + } + else + return RER; + return buf_len; +} + +int extract_prvsubinfores(struct MapPSI_Res *psi_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + psi_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if ((len = get_tlv("16",temp_buf,&asn_buf)) <= 0) + { + return RER; + } + return extract_subinfo(&psi_ptr->sub_info,len,temp_buf); +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding any time interrogation argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_anytimeintarg(struct MapATI_Arg *ati_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int len; + + asn_encode(buf,&asn_buf); + if (ati_ptr->param_flag & 0x01) // subscriber ideentity + { + if (ati_ptr->sub_ident.choice_flag == 1) // IMSI + buf_len = add_tlv("0.0",IMSI_LEN,ati_ptr->sub_ident.choice.imsi,0x80,&asn_buf); + else if (ati_ptr->sub_ident.choice_flag == 2) // msisdn + { + len = ati_ptr->sub_ident.choice.msisdn[0]; + buf_len = add_tlv("0.1",len,ati_ptr->sub_ident.choice.msisdn+1,0x80,&asn_buf); + } + } + else + return RER; + if (ati_ptr->param_flag & 0x02) // request info + { + if (ati_ptr->req_info.param_flag & 0x01) // location info + buf_len = add_null("1.0",0x80,&asn_buf); + if (ati_ptr->req_info.param_flag & 0x02) // subscriber state + buf_len = add_null("1.1",0x80,&asn_buf); + if (ati_ptr->req_info.param_flag & 0x04) // current location + buf_len = add_null("1.3",0x80,&asn_buf); + if (ati_ptr->req_info.param_flag & 0x08) // requested domain + buf_len = add_null("1.4",0x80,&asn_buf); + if (ati_ptr->req_info.param_flag & 0x10) // imei + buf_len = add_null("1.6",0x80,&asn_buf); + if (ati_ptr->req_info.param_flag & 0x20) // ms classmark + buf_len = add_null("1.5",0x80,&asn_buf); + if (ati_ptr->req_info.param_flag & 0x40) // mnp requested info + buf_len = add_null("1.7",0x80,&asn_buf); + } + else + return RER; + if (ati_ptr->param_flag & 0x04) // scf address + buf_len = add_tlv("3",ati_ptr->scf_add[0],ati_ptr->scf_add+1,0x80,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_anytimeintarg(struct MapATI_Arg *ati_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ati_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) != -1) + { + ati_ptr->param_flag |= 0x01; + len = get_tlv("0.0",temp_buf,&asn_buf); // IMSI + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + ati_ptr->sub_ident.choice_flag = 0x01; + memcpy(ati_ptr->sub_ident.choice.imsi,temp_buf,IMSI_LEN); + } + else + { + len = get_tlv("0.1",temp_buf,&asn_buf); // msisdn + if (len > 0 && len <= ISDN_LEN) + { + ati_ptr->sub_ident.choice_flag = 0x02; + ati_ptr->sub_ident.choice.msisdn[0] = len; + memcpy(ati_ptr->sub_ident.choice.msisdn+1,temp_buf,len); + } + else + return RER; + } + } + else + return RER; + if (get_tlv("1",temp_buf,&asn_buf) != -1) + { + if (get_tlv("1.0",temp_buf,&asn_buf) != -1) // location info + { + ati_ptr->param_flag |= 0x02; + ati_ptr->req_info.param_flag |= 0x01; + ati_ptr->req_info.loc_info = 1; + } + if (get_tlv("1.1",temp_buf,&asn_buf) != -1) // subscriber state + { + ati_ptr->param_flag |= 0x02; + ati_ptr->req_info.param_flag |= 0x02; + ati_ptr->req_info.sub_state = 1; + } + if (get_tlv("1.3",temp_buf,&asn_buf) != -1) // current location + { + ati_ptr->param_flag |= 0x02; + ati_ptr->req_info.param_flag |= 0x04; + ati_ptr->req_info.cur_location = 1; + } + if (get_tlv("1.4",temp_buf,&asn_buf) != -1) // requested domain + { + ati_ptr->param_flag |= 0x02; + ati_ptr->req_info.param_flag |= 0x08; + ati_ptr->req_info.req_domain= 1; + } + if (get_tlv("1.6",temp_buf,&asn_buf) != -1) // imei + { + ati_ptr->param_flag |= 0x02; + ati_ptr->req_info.param_flag |= 0x10; + ati_ptr->req_info.imei = 1; + } + if (get_tlv("1.5",temp_buf,&asn_buf) != -1) // ms classmark + { + ati_ptr->param_flag |= 0x02; + ati_ptr->req_info.param_flag |= 0x20; + ati_ptr->req_info.ms_classmark = 1; + } + if (get_tlv("1.7",temp_buf,&asn_buf) != -1) // mnp requested info + { + ati_ptr->param_flag |= 0x02; + ati_ptr->req_info.param_flag |= 0x40; + ati_ptr->req_info.mnp_req_info = 1; + } + } + else + return RER; + len = get_tlv("3",temp_buf,&asn_buf); + if (len > 0 && len <= ISDN_LEN) + { + ati_ptr->param_flag |= 0x04; + ati_ptr->scf_add[0] = len; + memcpy(ati_ptr->scf_add+1,temp_buf,len); + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding any time interrogate response */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_anytimeintres(struct MapATI_Res *ati_ptr,u8 *buf) +{ + int buf_len=0; + ASN_BUF asn_buf; + u_char info_str[1024]; + + if (ati_ptr->param_flag & 0x01) // subscriber info + { + buf_len = assign_subinfo(&ati_ptr->sub_info,buf); + memcpy(info_str,buf,buf_len%1024); + AsnEncode(buf,256,&asn_buf); + buf_len = AddTLV("16",buf_len,info_str,0x20,&asn_buf); + } + else + return RER; + return buf_len; +} + +int extract_anytimeintres(struct MapATI_Res *ati_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ati_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if ((len = get_tlv("16",temp_buf,&asn_buf)) <= 0) + { + return RER; + } + ati_ptr->param_flag = 1; + return extract_subinfo(&ati_ptr->sub_info,len,temp_buf); +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding any time subscription interrogation argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_anytimesubintarg(struct MapATSI_Arg *atsi_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int len; + + asn_encode(buf,&asn_buf); + if (atsi_ptr->param_flag & 0x01) // subscriber ideentity + { + if (atsi_ptr->sub_ident.choice_flag == 1) // IMSI + buf_len = add_tlv("0.0",IMSI_LEN,atsi_ptr->sub_ident.choice.imsi,0x80,&asn_buf); + else if (atsi_ptr->sub_ident.choice_flag == 2) // msisdn + { + len = atsi_ptr->sub_ident.choice.msisdn[0]; + buf_len = add_tlv("0.1",len,atsi_ptr->sub_ident.choice.msisdn+1,0x80,&asn_buf); + } + } + else + return RER; + return buf_len; +} + +int extract_anytimesubintarg(struct MapATSI_Arg *atsi_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + atsi_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) != -1) + { + atsi_ptr->param_flag |= 0x01; + len = get_tlv("0.0",temp_buf,&asn_buf); // IMSI + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + atsi_ptr->sub_ident.choice_flag = 0x01; + memcpy(atsi_ptr->sub_ident.choice.imsi,temp_buf,IMSI_LEN); + } + else + { + len = get_tlv("0.1",temp_buf,&asn_buf); // msisdn + if (len > 0 && len <= ISDN_LEN) + { + atsi_ptr->sub_ident.choice_flag = 0x02; + atsi_ptr->sub_ident.choice.msisdn[0] = len; + memcpy(atsi_ptr->sub_ident.choice.msisdn+1,temp_buf,len); + } + else + return RER; + } + } + else + return RER; + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding any time interrogate response */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_anytimesubintres(struct MapATSI_Res *atsi_ptr,u8 *buf) +{ + int buf_len=0; + ASN_BUF asn_buf; + //char info_str[1024]; + char tlv1[32]; + + AsnEncode(buf,256,&asn_buf); + + if (atsi_ptr->param_flag & 0x01) + { + sprintf(tlv1,"4.%d",10); + buf_len = assign_smscsi(tlv1,&atsi_ptr->subs_info.sms_csi,&asn_buf); + } + else + return RER; + return buf_len; +} + +int extract_anytimesubintres(struct MapATSI_Res *atsi_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + char tlv1[32]; + + atsi_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if ((len = get_tlv("4",temp_buf,&asn_buf)) <= 0) + { + return RER; + } + atsi_ptr->param_flag = 1; + sprintf(tlv1, "4.%d", 10); + return extract_smscsi(tlv1, &atsi_ptr->subs_info.sms_csi, &asn_buf); +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding prepare handover argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prehoarg(struct MapPHO_Arg *pho_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (pho_ptr->param_flag & 0x01) // target cell id + buf_len = add_tlv("4",GCID_LEN,pho_ptr->target_id,0x00,&asn_buf); + if (pho_ptr->param_flag & 0x02) // ho number not required + buf_len = add_null("5",0x00,&asn_buf); + if (pho_ptr->param_flag & 0x04) // bss apdu + { + temp_len = assign_extsiginfo(&pho_ptr->bss_apdu,temp_buf); + buf_len = add_tlv("16",temp_len,temp_buf,0x20,&asn_buf); + } + return buf_len; +} + +int extract_prehoarg(struct MapPHO_Arg *pho_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + pho_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4",temp_buf,&asn_buf) == GCID_LEN) // target cell id + { + pho_ptr->param_flag |= 0x01; + memcpy(pho_ptr->target_id,temp_buf,GCID_LEN); + } + if (get_tlv("5",temp_buf,&asn_buf) != -1) // ho number not required + { + pho_ptr->param_flag |= 0x02; + pho_ptr->numnot_require = 1; + } + len = get_tlv("16",temp_buf,&asn_buf); // bss apdu + if (len != -1) + { + if (!extract_extsiginfo(&pho_ptr->bss_apdu,len,temp_buf)) + return RER; + pho_ptr->param_flag |= 0x04; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding prepare handover response */ +/* ++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prehores(struct MapPHO_Res *pho_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (pho_ptr->param_flag & 0x01) // handover number + buf_len = add_tlv("4",pho_ptr->ho_num[0],pho_ptr->ho_num+1,0x00,&asn_buf); + if (pho_ptr->param_flag & 0x02) // bss apdu + { + temp_len = assign_extsiginfo(&pho_ptr->bss_apdu,temp_buf); + buf_len = add_tlv("16",temp_len,temp_buf,0x20,&asn_buf); + } + return buf_len; +} + +int extract_prehores(struct MapPHO_Res *pho_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + pho_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); + if (len > 0 && len <= ISDN_LEN) // handover number + { + pho_ptr->param_flag |= 0x01; + pho_ptr->ho_num[0] = len; + memcpy(pho_ptr->ho_num+1,temp_buf,len); + } + len = get_tlv("16",temp_buf,&asn_buf); // bss apdu + if (len != -1) + { + if (!extract_extsiginfo(&pho_ptr->bss_apdu,len,temp_buf)) + return RER; + pho_ptr->param_flag |= 0x02; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send end signal argument */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndendsigarg(struct MapSES_Arg *ses_ptr,u8 *buf) +{ + + if (ses_ptr->param_flag |= 0x01) // bss apdu + return assign_extsiginfo(&ses_ptr->bss_apdu,buf); + else + return RER; +} + +int extract_sndendsigarg(struct MapSES_Arg *ses_ptr,u32 buf_len,u8 *buf) +{ + if (extract_extsiginfo(&ses_ptr->bss_apdu,buf_len,buf)) + { + ses_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding process access signalling argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prcaccsigarg(struct MapPAS_Arg *pas_ptr,u8 *buf) +{ + + if (pas_ptr->param_flag |= 0x01) // bss apdu + return assign_extsiginfo(&pas_ptr->bss_apdu,buf); + else + return RER; +} + +int extract_prcaccsigarg(struct MapPAS_Arg *pas_ptr,u32 buf_len,u8 *buf) +{ + if (extract_extsiginfo(&pas_ptr->bss_apdu,buf_len,buf)) + { + pas_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding forward access signalling argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_fwdaccsigarg(struct MapFAS_Arg *fas_ptr,u8 *buf) +{ + + if (fas_ptr->param_flag |= 0x01) // bss apdu + return assign_extsiginfo(&fas_ptr->bss_apdu,buf); + else + return RER; +} + +int extract_fwdaccsigarg(struct MapFAS_Arg *fas_ptr,u32 buf_len,u8 *buf) +{ + if (extract_extsiginfo(&fas_ptr->bss_apdu,buf_len,buf)) + { + fas_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding prepare subsequent handover argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_presubshoarg(struct MapPSHO_Arg *psho_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (psho_ptr->param_flag & 0x01) // target cell id + buf_len = add_tlv("4-1",GCID_LEN,psho_ptr->target_id,0x00,&asn_buf); + else + return RER; + if (psho_ptr->param_flag & 0x02) // target msc number + buf_len = add_tlv("4-2",psho_ptr->msc_num[0],psho_ptr->msc_num+1,0x00,&asn_buf); + else + return RER; + if (psho_ptr->param_flag & 0x04) // bss apdu + { + temp_len = assign_extsiginfo(&psho_ptr->bss_apdu,temp_buf); + buf_len = add_tlv("16",temp_len,temp_buf,0x20,&asn_buf); + } + else + return RER; + return buf_len; +} + +int extract_presubshoarg(struct MapPSHO_Arg *psho_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + psho_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1",temp_buf,&asn_buf) == GCID_LEN) // target cell id + { + psho_ptr->param_flag |= 0x01; + memcpy(psho_ptr->target_id,temp_buf,GCID_LEN); + } + else + return RER; + len = get_tlv("4-2",temp_buf,&asn_buf); // target msc number + if (len > 0 && len <= ISDN_LEN) + { + psho_ptr->param_flag |= 0x02; + psho_ptr->msc_num[0] = len; + memcpy(psho_ptr->msc_num+1,temp_buf,len); + } + len = get_tlv("16",temp_buf,&asn_buf); // bss apdu + if (len != -1) + { + if (!extract_extsiginfo(&psho_ptr->bss_apdu,len,temp_buf)) + return RER; + psho_ptr->param_flag |= 0x04; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding prepare subsequent handover response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_presubshores(struct MapPSHO_Res *psho_ptr,u8 *buf) +{ + + if (psho_ptr->param_flag |= 0x01) // bss apdu + return assign_extsiginfo(&psho_ptr->bss_apdu,buf); + else + return RER; +} + +int extract_presubshores(struct MapPSHO_Res *psho_ptr,u32 buf_len,u8 *buf) +{ + if (extract_extsiginfo(&psho_ptr->bss_apdu,buf_len,buf)) + { + psho_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send Authentiction Info argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndauthinfoarg(struct MapSAI_Arg *sai_ptr,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + u8 tag1 = 1; + char tlv2[8]; + + asn_encode(buf, &asn_buf); + + if(version == AC_Version3) //add by gxchen + { + sprintf(tlv2, "0-%d", tag1++); + if(sai_ptr->param_flag & 0x01) + buf_len = add_tlv(tlv2, IMSI_LEN, sai_ptr->imsi, 0x80, &asn_buf); + else + { + mapp_log_debug("version_4 assign sndauthinfo lack IMSI"); + return RER; + } + sprintf(tlv2, "2-%d", tag1++); + if(sai_ptr->param_flag & 0x02) + buf_len = add_tlv(tlv2, 1, &sai_ptr->num_req_vec, 0x00, &asn_buf); + else + { + mapp_log_debug("version_4 assign sndauthinfo lack numberOfRequestedVectors"); + return RER; + } + sprintf(tlv2, "5-%d", tag1++); + if(sai_ptr->param_flag & 0x04) + buf_len = add_tlv(tlv2, 1, &sai_ptr->seg_prohibit, 0x00, &asn_buf); + sprintf(tlv2, "1-%d", tag1++); + if(sai_ptr->param_flag & 0x08) + buf_len = add_tlv(tlv2, 1, &sai_ptr->imm_res_prefer, 0x80, &asn_buf); + sprintf(tlv2, "16"); + if(sai_ptr->param_flag & 0x10) + { + temp_len = assign_authReSynInfo(&sai_ptr->resyn_info, temp_buf); + if(temp_len != RER) + buf_len = add_tlv(tlv2, temp_len, temp_buf, 0x20, &asn_buf); + } + sprintf(tlv2, "3-%d", tag1++); + if(sai_ptr->param_flag & 0x20) + { + temp_buf[0] = sai_ptr->node_type; + buf_len = add_tlv(tlv2, 1, temp_buf, 0x80, &asn_buf); + } + sprintf(tlv2, "4-%d", tag1++); + if(sai_ptr->param_flag & 0x40) + buf_len = add_tlv(tlv2, 3, sai_ptr->req_plmn_id, 0x80, &asn_buf); + sprintf(tlv2, "5-%d", tag1++); + if(sai_ptr->param_flag & 0x80) + buf_len = add_tlv(tlv2, 1, &sai_ptr->num_req_add_vec, 0x80, &asn_buf); + sprintf(tlv2, "6-%d", tag1++); + if(sai_ptr->param_flag & 0x100) + buf_len = add_tlv(tlv2, 1, &sai_ptr->add_vec_eps, 0x80, &asn_buf); + } + else + { + if (sai_ptr->param_flag & 0x01) // has IMSI + buf_len = add_tlv("4",IMSI_LEN,sai_ptr->imsi,0x00,&asn_buf); + else + { + mapp_log_debug("assign sndauthinfo lack IMSI"); + return RER; + } + } + + return buf_len; +} + +int extract_sndauthinfoarg(struct MapSAI_Arg *sai_ptr,u32 buf_len,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + int len=0; + u8 temp_buf[256]; + u8 tag1 = 1; + char tlv2[8]; + + sai_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + if(version == AC_Version3) //add by gxchen + { + sprintf(tlv2, "0-%d", tag1++); + len = get_tlv(tlv2, temp_buf, &asn_buf); + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + sai_ptr->param_flag |= 0x01; + memcpy(sai_ptr->imsi, temp_buf, len); + } + else + { + mapp_log_debug("extract_sndauthinfoarg version_4 lack IMSI"); + return RER; + } + sprintf(tlv2, "2-%d", tag1++); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + sai_ptr->param_flag |= 0x02; + sai_ptr->num_req_vec = temp_buf[0]; + } + else + { + mapp_log_debug("extract_sndauthinfoarg version_4 lack numberOfRequestedVectors"); +// return RER; + } + sprintf(tlv2, "5-%d", tag1++); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + sai_ptr->param_flag |= 0x04; + sai_ptr->seg_prohibit = temp_buf[0]; + } + sprintf(tlv2, "1-%d", tag1++); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + sai_ptr->param_flag |= 0x08; + sai_ptr->imm_res_prefer = temp_buf[0]; + } + sprintf(tlv2, "16"); + if((len = get_tlv(tlv2, temp_buf, &asn_buf)) > 0) + { + sai_ptr->param_flag |= 0x10; + extract_authReSynInfo(&sai_ptr->resyn_info, len, temp_buf); + } + sprintf(tlv2, "3-%d", tag1++); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + sai_ptr->param_flag |= 0x20; + sai_ptr->node_type = temp_buf[0]; + } + sprintf(tlv2, "4-%d", tag1++); + if(get_tlv(tlv2, temp_buf, &asn_buf) > 0) + { + sai_ptr->param_flag |= 0x40; + memcpy(sai_ptr->req_plmn_id, temp_buf, 3); + } + sprintf(tlv2, "5-%d", tag1++); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + sai_ptr->param_flag |= 0x80; + sai_ptr->num_req_add_vec = temp_buf[0]; + } + sprintf(tlv2, "6-%d", tag1++); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + sai_ptr->param_flag |= 0x100; + sai_ptr->add_vec_eps = temp_buf[0]; + } + } + else + { + len = get_tlv("4",temp_buf,&asn_buf); + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + sai_ptr->param_flag = 0x01; + memcpy(sai_ptr->imsi,temp_buf,len); + } + else + { + mapp_log_debug("extract_sndauthinfoarg lack IMSI"); + return RER; + } + } + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send Authentiction Info response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndauthinfores(struct MapSAI_Res *sai_ptr,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 ii=0; + int temp_len; + u8 temp_buf[256]; + char tlv2[32]; + + asn_encode(buf,&asn_buf); + if(version == AC_Version3) //add by gxchen if(sai_ptr->choice_flag == AUTH_UMTS) + { + if(sai_ptr->param_flag & 0x01) + { + if(sai_ptr->choice.umts.authlist.choice_flag == AUTH_LIST_QUINTUPLET) + { + sprintf(tlv2, "1"); +// buf_len = add_tlv(tlv2, temp_len, temp_buf, 0xa0, &asn_buf); + buf_len = add_null(tlv2, 0xa0, &asn_buf); + for(ii = 0; ii < sai_ptr->choice.umts.authlist.choice.quin_list.quin_len; ii ++) + { + temp_len = assign_quintuplet(&sai_ptr->choice.umts.authlist.choice.quin_list.quintuplet[ii], temp_buf); + if(temp_len == RER) + break; + sprintf(tlv2, "1.16-%d", ii+1); + buf_len = add_tlv(tlv2, temp_len, temp_buf, 0x20, &asn_buf); + } + } + else + { + sprintf(tlv2, "0"); +// buf_len = add_tlv(tlv2, temp_len, temp_buf, 0xa0, &asn_buf); + buf_len = add_null(tlv2, 0xa0, &asn_buf); + for(ii = 0; ii < sai_ptr->choice.umts.authlist.choice.tri_list.tri_len; ii++) + { + temp_len = assign_triplet(&sai_ptr->choice.umts.authlist.choice.tri_list.triplet[ii], temp_buf); + if(temp_len == RER) + break; + sprintf(tlv2, "0.16-%d", ii+1); + buf_len = add_tlv(tlv2, temp_len, temp_buf, 0x20, &asn_buf); + } + } + } + } + else + { + if (sai_ptr->param_flag & 0x01) // has authenticate data + { + for (ii = 0;ii < sai_ptr->choice.gsm.authlist.auth_len;ii++) + { + temp_len = assign_authset(&sai_ptr->choice.gsm.authlist.auth_set[ii],temp_buf); + if (temp_len == RER) + break; + sprintf(tlv2,"16-%d",ii+1); + buf_len = add_tlv(tlv2,temp_len,temp_buf,0x20,&asn_buf); + } + } + } + + return buf_len; +} + +int extract_sndauthinfores(struct MapSAI_Res *sai_ptr,u32 buf_len,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u8 ii; + char tlv2[32]; + +// sai_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_sndauthinfores buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + if(version == AC_Version3) //add by gxchen + { + sai_ptr->choice_flag = AUTH_UMTS; + sai_ptr->param_flag = 0; + if((len = get_tlv("1", temp_buf, &asn_buf)) > 0) //quintuplet + { + sai_ptr->param_flag |= 0x01; + sai_ptr->choice.umts.authlist.choice_flag = AUTH_LIST_QUINTUPLET; + sai_ptr->choice.umts.authlist.choice.quin_list.quin_len = 0; + for(ii = 0; ii < AUTHLIST_LEN; ii++) + { + sai_ptr->choice.umts.authlist.choice.quin_list.quintuplet[ii].param_flag = 0; + sprintf(tlv2, "1.16-%d", ii+1); + len = get_tlv(tlv2, temp_buf, &asn_buf); + if(len <= 0) //has not data + break; + if(!extract_quintuplet(&sai_ptr->choice.umts.authlist.choice.quin_list.quintuplet[ii], len, temp_buf)) + break; + sai_ptr->choice.umts.authlist.choice.quin_list.quin_len++; + } + } + else if((len = get_tlv("0", temp_buf, &asn_buf)) > 0) //triplet + { + sai_ptr->param_flag |= 0x01; + sai_ptr->choice.umts.authlist.choice_flag = AUTH_LIST_TRIPLET; + sai_ptr->choice.umts.authlist.choice.tri_list.tri_len = 0; + for(ii = 0; ii < AUTHLIST_LEN; ii++) + { + sai_ptr->choice.umts.authlist.choice.tri_list.triplet[ii].param_flag = 0; + sprintf(tlv2, "0.16-%d", ii+1); + len = get_tlv(tlv2, temp_buf, &asn_buf); + if(len <= 0) //has not data + break; + if(!extract_triplet(&sai_ptr->choice.umts.authlist.choice.tri_list.triplet[ii], len, temp_buf)) + break; + sai_ptr->choice.umts.authlist.choice.tri_list.tri_len++; + } + } + } + else + { + sai_ptr->choice_flag = AUTH_GSM; + sai_ptr->param_flag = 0; + sai_ptr->choice.gsm.authlist.auth_len = 0; + for (ii = 0;ii < AUTHLIST_LEN;ii++) + { + sai_ptr->choice.gsm.authlist.auth_set[ii].param_flag = 0; + sprintf(tlv2,"16-%d",ii+1); + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len <= 0) // has not data + break; + if (!extract_authset(&sai_ptr->choice.gsm.authlist.auth_set[ii],len,temp_buf)) + break; + sai_ptr->param_flag = 0x01; + sai_ptr->choice.gsm.authlist.auth_len++; + } + } + + return ROK; +} + +//add by gxchen start +/* +++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding authentication failure report argument */ +/* +++++++++++++++++++++++++++++++++++++ */ +int assign_authfailreportarg(MapAuthFailReport_Arg *fail_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 tag1 = 1; + char tlv2[8]; + + asn_encode(buf, &asn_buf); + sprintf(tlv2, "4-%d", tag1++); + if(fail_ptr->param_flag & 0x01) + buf_len = add_tlv(tlv2, IMSI_LEN, fail_ptr->imsi, 0x00, &asn_buf); + else + { + mapp_log_debug("assign authfailreportarg lack IMSI"); + return RER; + } + sprintf(tlv2, "10-%d", tag1++); + if(fail_ptr->param_flag & 0x02) + buf_len = add_tlv(tlv2, 1, (u8*)&fail_ptr->cause, 0x00, &asn_buf); + else + { + mapp_log_debug("version_4 assign authfailreportarg lack failureCause"); + return RER; + } + sprintf(tlv2, "1-%d", tag1++); + if(fail_ptr->param_flag & 0x04) + buf_len = add_tlv(tlv2, 1, &fail_ptr->reattemp, 0x00, &asn_buf); + sprintf(tlv2, "10-%d", tag1++); + if(fail_ptr->param_flag & 0x08) + buf_len = add_tlv(tlv2, 1, (u8*)&fail_ptr->access_type, 0x00, &asn_buf); + sprintf(tlv2, "4-%d", tag1++); + if(fail_ptr->param_flag & 0x10) + buf_len = add_tlv(tlv2, RAND_LEN, fail_ptr->rand, 0x00, &asn_buf); + sprintf(tlv2, "0-%d", tag1++); + if(fail_ptr->param_flag & 0x20) + buf_len = add_tlv(tlv2, fail_ptr->vlr_num[0], fail_ptr->vlr_num+1, 0x80, &asn_buf); + sprintf(tlv2, "1-%d", tag1++); + if(fail_ptr->param_flag & 0x40) + buf_len = add_tlv(tlv2, fail_ptr->sgsn_num[0], fail_ptr->sgsn_num+1, 0x80, &asn_buf); + + return buf_len; +} + +int extract_authfailreportarg(MapAuthFailReport_Arg *fail_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + int len=0; + u8 temp_buf[256]; + u8 tag1 = 1; + char tlv2[8]; + + fail_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + sprintf(tlv2, "4-%d", tag1++); + len = get_tlv(tlv2, temp_buf, &asn_buf); + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + fail_ptr->param_flag |= 0x01; + memcpy(fail_ptr->imsi, temp_buf, len); + } + else + { + mapp_log_debug("extract authfailreportarg lack IMSI"); + return RER; + } + sprintf(tlv2, "10-%d", tag1++); + if(1 == get_tlv(tlv2, temp_buf, &asn_buf)) + { + fail_ptr->param_flag |= 0x02; + fail_ptr->cause = temp_buf[0]; + } + sprintf(tlv2, "1-%d", tag1++); + if(1 == get_tlv(tlv2, temp_buf, &asn_buf)) + { + fail_ptr->param_flag |= 0x04; + fail_ptr->reattemp = temp_buf[0]; + } + sprintf(tlv2, "10-%d", tag1++); + if(1 == get_tlv(tlv2, temp_buf, &asn_buf)) + { + fail_ptr->param_flag |= 0x08; + fail_ptr->access_type = temp_buf[0]; + } + sprintf(tlv2, "4-%d", tag1++); + if(RAND_LEN == (len = get_tlv(tlv2, temp_buf, &asn_buf))) + { + fail_ptr->param_flag |= 0x10; + memcpy(fail_ptr->rand, temp_buf, len); + } + sprintf(tlv2, "0-%d", tag1++); + if(2 < (len = get_tlv(tlv2, temp_buf, &asn_buf))) + { + fail_ptr->param_flag |= 0x20; + fail_ptr->vlr_num[0] = len; + memcpy(fail_ptr->vlr_num+1, temp_buf, len); + } + sprintf(tlv2, "1-%d", tag1++); + if(2 < (len = get_tlv(tlv2, temp_buf, &asn_buf))) + { + fail_ptr->param_flag |= 0x40; + fail_ptr->sgsn_num[0] = len; + memcpy(fail_ptr->sgsn_num+1, temp_buf, len); + } + + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding authentication failure report response */ +/* +++++++++++++++++++++++++++++++++++++ */ +/*int assign_authfailreportres(MapAuthFailReport_Res *fail_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf, &asn_buf); + if(fail_ptr->param_flag & 0x01) + buf_len = add_tlv("10-1", 1, (u8*)&fail_ptr->error, 0x00, &asn_buf); + + return buf_len; +} + +int extract_authfailreportres(MapAuthFailReport_Res *fail_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + fail_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; //maybe RER + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + + if(1 == get_tlv("10-1", temp_buf, &asn_buf)) + { + fail_ptr->param_flag |= 0x01; + fail_ptr->error = temp_buf[0]; + } + + return ROK; +}*/ +//add by gxchen end + +/* +++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding check IMEI argument */ +/* +++++++++++++++++++++++++++++++++++++ */ +int assign_chkimeiarg(struct MapCIMEI_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if(flag & 0x01) //imei + buf_len = add_tlv("4",IMEI_LEN,ptr->imei,0x00,&asn_buf); + return buf_len; +} + +int extract_chkimeiarg(struct MapCIMEI_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_chkimeiarg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ptr->param_flag = 0; + if((get_tlv("4",temp_buf,&asn_buf)) != IMEI_LEN) //imei + return RER; + ptr->param_flag |= 0x01; + memcpy(ptr->imei,temp_buf,IMEI_LEN); + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding check IMEI response */ +/* +++++++++++++++++++++++++++++++++++++ */ +int assign_chkimeires(struct MapCIMEI_Res *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 data; + + asn_encode(buf,&asn_buf); + if(ptr->param_flag & 0x01) + { + data = ptr->equip_status; + buf_len = add_tlv("10",1,&data,0x00,&asn_buf); + } + return buf_len; +} + +int extract_chkimeires(struct MapCIMEI_Res *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_chkimeires buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ptr->param_flag = 0; + if(get_tlv("10",temp_buf,&asn_buf) != 1) + return RER; + ptr->param_flag |= 0x01; + ptr->equip_status = temp_buf[0]; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding insert subscribe Data argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_inssubdataarg(struct MapISD_Arg *isd_ptr,u8 *buf,u8 version) +{ + ASN_BUF asn_buf; + int jj,kk; + u32 flag1; + u32 flag; + u32 len; + int buf_len=0; + int temp_len; + u8 temp_data[256],temp_buf[256]; + u8 tag1=1,tag2=1,tag3=1,tag4=1,tag5=1; + char tlv1[32],tlv2[32],tlv3[32],tlv4[32],tlv5[32]; + struct ExtFwdInfo_struct *fwd_ptr; + struct ExtSsData_struct *ss_ptr; + struct ExtCallBarInfo_struct *callbar_ptr; + struct EmlppInfo_struct *emlpp_ptr; + struct PdpContext_struct *pdp_ptr; + + asn_encode(buf,&asn_buf); + flag = isd_ptr->param_flag; + if (flag & 0x01) // IMSI + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,IMSI_LEN,isd_ptr->imsi,0x80,&asn_buf); + } + if (flag & 0x02) // MSISDN + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,isd_ptr->msisdn[0],isd_ptr->msisdn+1,0x80,&asn_buf); + } + if (flag & 0x04) // category + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_tlv(tlv1,1,&isd_ptr->category,0x80,&asn_buf); + } + if (flag & 0x08) // sub status + { + sprintf(tlv1,"3-%d",tag1++); + temp_data[0] = isd_ptr->sub_status; + buf_len = add_tlv(tlv1,1,temp_data,0x80,&asn_buf); + } + if (flag & 0x20) // bearer service list + { + temp_len = bearer_bittostr(isd_ptr->bearer_data,temp_data,0); + + if(temp_len > 0) + { + sprintf(tlv1,"4-%d",tag1++); + + for (jj = 0;jj < temp_len;jj ++) + { + sprintf(tlv2,"%s.4-%d",tlv1,jj+1); + buf_len = add_tlv(tlv2,1,temp_data+jj,0x00,&asn_buf); + } + } + } + if (flag & 0x40) // tele service list + { + temp_len = tele_bittostr(isd_ptr->tele_data,temp_data,0); + if(temp_len > 0) + { + sprintf(tlv1,"6-%d",tag1++); + for (jj = 0;jj < temp_len;jj++) + { + sprintf(tlv2,"%s.4-%d",tlv1,jj+1); + buf_len = add_tlv(tlv2,1,temp_data+jj,0x00,&asn_buf); + } + } + } + if (flag & 0x80) // ss info list + { + sprintf(tlv1,"7-%d",tag1++); + tag2 = 1; + if (isd_ptr->ss_info.param_flag & 0x01) // fwd info + { + fwd_ptr = (ExtFwdInfo_struct *) &isd_ptr->ss_info.fwd_info; + for (jj = 0;jj < 4;jj ++) //tag2 + { + tag3 = 1; + kk = 0x01 << jj; + if (fwd_ptr->param_flag & kk) + { + sprintf(tlv2,"%s.0-%d",tlv1,tag2++); + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); // for ss_code + buf_len = add_tlv(tlv3,1,&fwd_ptr->ss_code[jj],0x00,&asn_buf); + sprintf(tlv3,"%s.16-%d",tlv2,tag3++); + add_null(tlv3,0x20,&asn_buf); + tag4 = 1; + sprintf(tlv4,"%s.16-%d",tlv3,tag4); + add_null(tlv4,0x20,&asn_buf); + tag5 = 1; + flag1 = fwd_ptr->fwd_feat[jj].param_flag; + if (flag1 & 0x01) // bs group + { + if (fwd_ptr->fwd_feat[jj].bs_code.param_flag == 1) + { + sprintf(tlv5,"%s.2-%d",tlv4,tag5++); + if (tele_bittostr(fwd_ptr->fwd_feat[jj].bs_code.tele_code,temp_data,1)) + buf_len = add_tlv(tlv5,1,temp_data,0x80,&asn_buf); + } + else if(fwd_ptr->fwd_feat[jj].bs_code.param_flag == 2) + { + sprintf(tlv5,"%s.3-%d",tlv4,tag5++); + if (bearer_bittostr(fwd_ptr->fwd_feat[jj].bs_code.bearer_code,temp_data,1)) + buf_len = add_tlv(tlv5,1,temp_data,0x80,&asn_buf); + } + } + if (flag1 & 0x02) //ss status + { + sprintf(tlv5,"%s.4-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&fwd_ptr->fwd_feat[jj].ss_status,0x80,&asn_buf); + } + if (flag1 & 0x04) //fwdto_num + { + sprintf(tlv5,"%s.5-%d",tlv4,tag5++); + len = fwd_ptr->fwd_feat[jj].fwdto_num[0]; + buf_len = add_tlv(tlv5,len,fwd_ptr->fwd_feat[jj].fwdto_num+1,0x80,&asn_buf); + } + if (flag1 &0x08) //fwd opt + { + sprintf(tlv5,"%s.6-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&fwd_ptr->fwd_feat[jj].fwd_option,0x80,&asn_buf); + } + if (flag1 &0x10) //norc time + { + sprintf(tlv5,"%s.7-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&fwd_ptr->fwd_feat[jj].norc_time,0x80,&asn_buf); + } + } + } + } + if (isd_ptr->ss_info.param_flag & 0x02) // call bar info + { + int mm=0, nn; + callbar_ptr = (ExtCallBarInfo_struct *) &isd_ptr->ss_info.call_info; + for (jj = 0;jj < 5;jj ++) + { + kk = 0x01 << jj; + if ((callbar_ptr->param_flag & kk) != 0) + { + sprintf(tlv2,"%s.1-%d",tlv1,tag2++); + tag3 = 1; + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); + buf_len = add_tlv(tlv3,1,&callbar_ptr->ss_code[jj],0x00,&asn_buf); + sprintf(tlv3,"%s.16-%d",tlv2,tag3++); + add_null(tlv3,0x20,&asn_buf); + tag4 = 1; + for(mm=0;mm<5;mm++) + { + nn = 0x01<< mm; + if (!(callbar_ptr->bar_list[jj].param_flag & nn)) + continue; + + sprintf(tlv4,"%s.16-%d",tlv3,tag4); + add_null(tlv4,0x20,&asn_buf); + tag5 = 1; + + if (callbar_ptr->bar_list[jj].bs_code[mm].param_flag == 1) + { + sprintf(tlv5,"%s.3-%d",tlv4,tag5++); + buf_len = add_int(tlv5,callbar_ptr->bar_list[jj].bs_code[mm].tele_code,0x80,&asn_buf); + } + else// if(callbar_ptr->bar_list[jj].bs_code[mm].param_flag == 2) + { + sprintf(tlv5,"%s.2-%d",tlv4,tag5++); + buf_len = add_int(tlv5,callbar_ptr->bar_list[jj].bs_code[mm].bearer_code,0x80,&asn_buf); + } + + sprintf(tlv5,"%s.4-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,1,&callbar_ptr->bar_list[jj].ss_status[mm],0x80,&asn_buf); + } + } + } + } + if (isd_ptr->ss_info.param_flag & 0x08) // ss data + { + ss_ptr = (ExtSsData_struct *)&isd_ptr->ss_info.ss_data; + for(jj = 0;jj < 16;jj ++) + { + kk = 0x01 << jj; + if (ss_ptr->param_flag & kk) + { + sprintf(tlv2,"%s.3-%d",tlv1,tag2++); + tag3 = 1; + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); + buf_len = add_tlv(tlv3,1,&ss_ptr->ss_code[jj],0x00,&asn_buf); + sprintf(tlv3,"%s.4-%d",tlv2,tag3++); + buf_len = add_tlv(tlv3,1,&ss_ptr->ss_status[jj],0x80,&asn_buf); + if (ss_ptr->subs_opt[jj].choice_flag == 1) + { + sprintf(tlv3,"%s.2-%d",tlv2,tag3++); + temp_buf[0] = ss_ptr->subs_opt[jj].choice.clires_opt; + buf_len = add_tlv(tlv3,1,temp_buf,0x80,&asn_buf); + } + else if (ss_ptr->subs_opt[jj].choice_flag == 2) + { + sprintf(tlv3,"%s.1-%d",tlv2,tag3++); + temp_buf[0] = ss_ptr->subs_opt[jj].choice.over_cate; + buf_len = add_tlv(tlv3,1,temp_buf,0x80,&asn_buf); + } + } + } + } + if(isd_ptr->ss_info.param_flag & 0x10) //emlpp-Info + { + emlpp_ptr = (EmlppInfo_struct *)&isd_ptr->ss_info.emlpp_info; + sprintf(tlv2,"%s.4-%d",tlv1,tag2++); + tag3 = 1; + sprintf(tlv3, "%s.2-%d", tlv2, tag3++); + if(emlpp_ptr->param_flag & 0x01) + buf_len = add_tlv(tlv3, 1, &emlpp_ptr->maxent_prio, 0x00, &asn_buf); + sprintf(tlv3, "%s.2-%d", tlv2, tag3++); + if(emlpp_ptr->param_flag & 0x02) + buf_len = add_tlv(tlv3, 1, &emlpp_ptr->default_prio, 0x00, &asn_buf); + } + } + + if (flag & 0x10) // odb-data + { + if(isd_ptr->odb_data.param_flag & 0x03) + { + sprintf(tlv1,"8-%d",tag1++); + tag2 = 1; + if (isd_ptr->odb_data.param_flag & 0x01) // ODB general data + { + sprintf(tlv2,"%s.3-%d",tlv1,tag2++); + temp_buf[0] = isd_ptr->odb_data.odb_general >> 8; + temp_buf[1] = isd_ptr->odb_data.odb_general; + if(version<3) + len = bytestrtobitstr(temp_data,temp_buf,6); + else + len = bytestrtobitstr(temp_data,temp_buf,15); + buf_len = add_tlv(tlv2,len,temp_data,0x00,&asn_buf); + } + if (isd_ptr->odb_data.param_flag & 0x02) // ODB HPLMN data + { + sprintf(tlv2,"%s.3-%d",tlv1,tag2++); + temp_buf[0] = isd_ptr->odb_data.odb_hplmn; + len = bytestrtobitstr(temp_data,temp_buf,4); + buf_len = add_tlv(tlv2,len,temp_data,0x00,&asn_buf); + } + } + } + + + if (flag & 0x100) // roaming restriction due to unsuppoerted feature + { + sprintf(tlv1,"9-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x200) // regional Subscription Data + { + if (isd_ptr->zc_list.list_len > ZONECODE_LEN) + return RER; + for (jj = 0;jj < isd_ptr->zc_list.list_len;jj ++) + { + sprintf(tlv1,"10-%d.4-%d",tag1,jj+1); + buf_len = add_tlv(tlv1,2,isd_ptr->zc_list.zone_code[jj],0x00,&asn_buf); + } + tag1 ++; + } + if (flag & 0x400) // vbs Subscription Data + { + if (isd_ptr->vbsdata_list.list_len > VBS_LEN) + return RER; + for (jj = 0;jj < isd_ptr->vbsdata_list.list_len;jj ++) + { + sprintf(tlv1,"11-%d.16-%d.4",tag1,jj+1); + buf_len = add_tlv(tlv1,3,isd_ptr->vbsdata_list.vbs_data[jj].group_id,0x00,&asn_buf); + if (isd_ptr->vbsdata_list.vbs_data[jj].param_flag & 0x02) + { + sprintf(tlv1,"11-%d.16-%d.5",tag1,jj+1); + buf_len = add_null(tlv1,0x00,&asn_buf); + } + } + tag1 ++; + } + if (flag & 0x800) // vgcs Subscription Data + { + if (isd_ptr->vgcdata_list.list_len > VGCS_LEN) + return -1; + for (jj = 0;jj < isd_ptr->vgcdata_list.list_len;jj ++) + { + sprintf(tlv1,"12-%d.16-%d.4",tag1,jj+1); + buf_len = add_tlv(tlv1,3,isd_ptr->vgcdata_list.vgc_data[jj].group_id,0x00,&asn_buf); + } + tag1 ++; + } + if (flag & 0x1000) // vlr Camel Subscription Info + { + if (isd_ptr->subs_info.param_flag & 0x01) //o-CSI + { + temp_len = assign_ocsi(&isd_ptr->subs_info.o_csi,temp_buf); + sprintf(tlv1,"13-%d.0",tag1); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (isd_ptr->subs_info.param_flag & 0x02) //ss-CSI + { + sprintf(tlv1,"13-%d.2",tag1); + buf_len = assign_sscsi(tlv1,&isd_ptr->subs_info.ss_csi,&asn_buf); + } + if (isd_ptr->subs_info.param_flag & 0x04) //O-BcsmCamelTDPCriteriaList + { + temp_len = assign_tdpcritlist(&isd_ptr->subs_info.tdp_list,temp_buf); + sprintf(tlv1,"13-%d.4",tag1); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf); + } + if (isd_ptr->subs_info.param_flag & 0x08) //sms-CSI + { + sprintf(tlv1,"13-%d.6",tag1); + buf_len = assign_smscsi(tlv1,&isd_ptr->subs_info.sms_csi,&asn_buf); + } + tag1 ++; + } + if (flag & 0x2000) // naea Preferred CI + { + sprintf(tlv1,"15-%d",tag1++); + buf_len = add_tlv(tlv1,NAEA_LEN,isd_ptr->naea_ci.cic,0x80,&asn_buf); + } + if (flag & 0x4000) // GPRS Subscription Data + { + if (isd_ptr->gprs_data.param_flag & 0x01) //data list include + { + sprintf(tlv1,"16-%d.5",tag1); + buf_len = add_null(tlv1,0x00,&asn_buf); + + sprintf(tlv1,"16-%d.1-2",tag1); + } + else + sprintf(tlv1,"16-%d.1",tag1); + + if (isd_ptr->gprs_data.gprs_list.list_len > PDPCONTEXT_LEN) + return RER; + + for (jj = 0;jj < isd_ptr->gprs_data.gprs_list.list_len;jj ++) + { + kk = 1; + sprintf(tlv2,"%s.16-%d",tlv1,jj+1); + buf_len = add_null(tlv2, 0x20, &asn_buf); + pdp_ptr = (PdpContext_struct *) &isd_ptr->gprs_data.gprs_list.pdp_context[jj]; + if (pdp_ptr->param_flag & 0x01) // pdp context id + { + sprintf(tlv2,"%s.16-%d.2-%d",tlv1,jj+1, kk++); + buf_len = add_int(tlv2,pdp_ptr->pdpcontext_id,0x00,&asn_buf); + } + if (pdp_ptr->param_flag & 0x02) // pdp type + { + sprintf(tlv2,"%s.16-%d.16-%d",tlv1,jj+1, kk++); + buf_len = add_tlv(tlv2,2,pdp_ptr->pdp_type,0x80,&asn_buf); + } + if (pdp_ptr->param_flag & 0x04) // pdp add + { + sprintf(tlv2,"%s.16-%d.17-%d",tlv1,jj+1, kk++); + buf_len = add_tlv(tlv2,pdp_ptr->pdp_add[0],pdp_ptr->pdp_add+1,0x80,&asn_buf); + } + if (pdp_ptr->param_flag & 0x08) // QoS subscribed + { + sprintf(tlv2,"%s.16-%d.18-%d",tlv1,jj+1, kk++); + buf_len = add_tlv(tlv2,3,pdp_ptr->qos_sub,0x80,&asn_buf); + } + if (pdp_ptr->param_flag & 0x10) // VPLMN address allowed + { + sprintf(tlv2,"%s.16-%d.19-%d",tlv1,jj+1, kk++); + buf_len = add_null(tlv2,0x80,&asn_buf); + } + if (pdp_ptr->param_flag & 0x20) // apn + { + if (pdp_ptr->apn.apn_len > APN_LEN) + return RER; + sprintf(tlv2,"%s.16-%d.20-%d",tlv1,jj+1, kk++); + buf_len = add_tlv(tlv2,pdp_ptr->apn.apn_len,pdp_ptr->apn.apn_data,0x80,&asn_buf); + } + if (pdp_ptr->param_flag & 0x40) // ext QoS subscribed + { + sprintf(tlv2,"%s.16-%d.0-%d",tlv1,jj+1, kk++); + buf_len = add_tlv(tlv2,pdp_ptr->ext_qos_sub[0],pdp_ptr->ext_qos_sub+1,0x80,&asn_buf); + } + if(pdp_ptr->param_flag & 0x100) // ext 2 QoS subscribed + { + sprintf(tlv2,"%s.16-%d.2-%d",tlv1,jj+1, kk++); + buf_len = add_tlv(tlv2,pdp_ptr->ext2_qos_sub[0],pdp_ptr->ext2_qos_sub+1,0x80,&asn_buf); + } + if(pdp_ptr->param_flag & 0x200) // ext 3 QoS subscribed + { + sprintf(tlv2,"%s.16-%d.3-%d",tlv1,jj+1, kk++); + buf_len = add_tlv(tlv2,pdp_ptr->ext3_qos_sub[0],pdp_ptr->ext3_qos_sub+1,0x80,&asn_buf); + } + } + tag1 ++; + } + if (flag & 0x8000) // roaming Restricted In Sgsn Due To Unsupported Feature + { + sprintf(tlv1,"23-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x10000) // network Aceess Mode + { + sprintf(tlv1,"24-%d",tag1++); + buf_len = add_int(tlv1,isd_ptr->net_mode,0x80,&asn_buf); + } + return buf_len; +} + +int extract_inssubdataarg(struct MapISD_Arg *isd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len,jj,kk,index; + int temp_len,ss_mask=0; + u32 flag=0, code_flag=0; + u8 tag1,tag2=0; + char tlv2[32],tlv3[32]; + u8 temp_buf[256],temp_data[256]; + struct ExtFwdInfo_struct *fwd_ptr; + struct ExtCallBarInfo_struct *callbar_ptr; + struct ExtSsData_struct *ss_ptr; + struct EmlppInfo_struct *emlpp_ptr; + struct PdpContext_struct *pdp_ptr; + + isd_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); // get imsi + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + flag |= 0x01; + memcpy(isd_ptr->imsi,temp_buf,len); + } + if ((len=get_tlv("1",temp_buf,&asn_buf)) > 2) + { + flag |= 0x02; + isd_ptr->msisdn[0] = len; + memcpy(isd_ptr->msisdn+1,temp_buf,len); + } + if (get_tlv("2",temp_buf,&asn_buf) > 0) + { + flag |= 0x04; + isd_ptr->category = temp_buf[0]; + } + if(get_tlv("3",temp_buf,&asn_buf) > 0) + { + flag |= 0x08; + isd_ptr->sub_status = temp_buf[0]; + } + isd_ptr->odb_data.param_flag = 0; + len = get_tlv("8.3-1",temp_buf,&asn_buf); //odb-data->odb->GreneralData + if (len != -1) + { + flag |= 0x10; // odb - data + isd_ptr->odb_data.param_flag |= 0x01; //odb general + jj = bitstrtobytestr(temp_data,temp_buf,len); + isd_ptr->odb_data.odb_general = bcdtou32(temp_data,jj); + } + len = get_tlv("8.3-2",temp_buf,&asn_buf); + if (len != -1) + { + flag |= 0x10; // odb - data + isd_ptr->odb_data.param_flag |= 0x02; // odb hplmn + jj = bitstrtobytestr(temp_data,temp_buf,len); + isd_ptr->odb_data.odb_hplmn = bcdtou32(temp_data,jj); + } + temp_len = 0; + for (jj = 0;jj < BSLIST_LEN;jj ++) // bearer Service List + { + sprintf(tlv2,"4.4-%d",jj+1); + if (get_tlv(tlv2,temp_buf,&asn_buf) < 1) + break; + temp_data[jj] = temp_buf[0]; + temp_len ++; + flag |= 0x20; + } + isd_ptr->bearer_data = bearer_strtobit(temp_data,temp_len); + temp_len = 0; + for (jj = 0;jj < TSLIST_LEN;jj ++) // tele Service List + { + sprintf(tlv2,"6.4-%d",jj+1); + if (get_tlv(tlv2,temp_buf,&asn_buf) < 1) + break; + temp_data[jj] = temp_buf[0]; + temp_len++; + flag |= 0x40; + } + isd_ptr->tele_data = tele_strtobit(temp_data,temp_len); + isd_ptr->ss_info.param_flag = 0; + tag1 = 1; ss_mask = 0; + for(index=0;index<4;index++) /* sometime, the sequence of 7.0/7.1/7.3 is not in order */ + { + if (!(ss_mask & 0x01) && get_tlv("7.0",temp_buf,&asn_buf) != -1) // forwarding info + { + flag |= 0x80; // ss info + isd_ptr->ss_info.param_flag |= 0x01; // fwd info + fwd_ptr = (ExtFwdInfo_struct *)&isd_ptr->ss_info.fwd_info; + fwd_ptr->param_flag = 0; + for (jj = 0;jj < 4;jj ++) + { + fwd_ptr->fwd_feat[jj].param_flag = 0; + fwd_ptr->fwd_feat[jj].bs_code.param_flag = 0; + sprintf(tlv2,"7.0-%d.4",tag1); // ss code + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len > 0) + { + fwd_ptr->param_flag |= (0x01 << jj); + fwd_ptr->ss_code[jj] = temp_buf[0]; + ss_mask |= 0x01; + } + else + break; + sprintf(tlv2,"7.0-%d.16.16",tag1); // forward feature + sprintf(tlv3,"%s.2",tlv2); // bearer code of bs code + len = get_tlv(tlv3,temp_buf,&asn_buf); + if (len > 0) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x01; + fwd_ptr->fwd_feat[jj].bs_code.param_flag = 2; // bearer + fwd_ptr->fwd_feat[jj].bs_code.bearer_code = bearer_strtobit(temp_buf,1); + } + sprintf(tlv3,"%s.3",tlv2); // tele code of bs code + len = get_tlv(tlv3,temp_buf, &asn_buf); + if (len >= 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x01; // bs code + fwd_ptr->fwd_feat[jj].bs_code.param_flag = 1;// tele + fwd_ptr->fwd_feat[jj].bs_code.tele_code = tele_strtobit(temp_buf,1); + } + sprintf(tlv3,"%s.4",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x02; // ss status + fwd_ptr->fwd_feat[jj].ss_status = temp_buf[0]; + } + sprintf(tlv3,"%s.5",tlv2); + len = get_tlv(tlv3,temp_buf,&asn_buf); + if (len >= 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x04; // fwd to num + fwd_ptr->fwd_feat[jj].fwdto_num[0] = len; + memcpy(fwd_ptr->fwd_feat[jj].fwdto_num+1,temp_buf,len); + } + sprintf(tlv3,"%s.6",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x08; // fwd opt + fwd_ptr->fwd_feat[jj].fwd_option = temp_buf[0]; + } + sprintf(tlv3,"%s.7",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + { + fwd_ptr->fwd_feat[jj].param_flag |= 0x10; // norc time + fwd_ptr->fwd_feat[jj].norc_time = temp_buf[0]; + } + tag1 ++; + } + } + if (!(ss_mask & 0x02) && get_tlv("7.1",temp_buf,&asn_buf) != -1) // call Barring Info + { + flag |= 0x80; // ss info + isd_ptr->ss_info.param_flag |= 0x02; // call bar info + callbar_ptr = (ExtCallBarInfo_struct *)&isd_ptr->ss_info.call_info; + memset(callbar_ptr, 0x00, sizeof(ExtCallBarInfo_struct)); + callbar_ptr->param_flag = 0; + tag2=1; + for (jj = 0;jj < 5;jj ++) + { + callbar_ptr->bs_code[jj].param_flag = 0; + sprintf(tlv2,"7.1-%d.4",tag1); //callbarringInfo + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + callbar_ptr->param_flag |= (0x01 << jj); // ss code + callbar_ptr->ss_code[jj] = temp_buf[0]; + ss_mask |= 0x02; + } + else + break; + tag1++; + code_flag = 0; + for(kk=0;kk<5;kk++) + { + sprintf(tlv2,"7.1-%d.16.16-%d",tag1-1,kk+1); + sprintf(tlv3,"%s.4",tlv2); + if (get_tlv(tlv3,temp_buf,&asn_buf) == 1) + callbar_ptr->bar_list[jj].ss_status[kk] = temp_buf[0]; + else + continue; + callbar_ptr->bar_list[jj].param_flag |= 0x01<= 1) + { + callbar_ptr->bar_list[jj].bs_code[kk].param_flag = 2; // bearer + callbar_ptr->bar_list[jj].bs_code[kk].bearer_code = bearer_strtobit(temp_buf,1); + code_flag = 1; + } + sprintf(tlv3,"%s.3",tlv2); + len = get_tlv(tlv3,temp_buf,&asn_buf); + if (len >= 1) + { + callbar_ptr->bar_list[jj].bs_code[kk].param_flag = 1; // bearer + callbar_ptr->bar_list[jj].bs_code[kk].tele_code = tele_strtobit(temp_buf,1); + code_flag = 1; + } + } + if(code_flag == 0) + { + callbar_ptr->bar_list[jj].bs_code[0].param_flag = 1; // bearer + temp_buf[0] = TS_AllSTS; + callbar_ptr->bar_list[jj].bs_code[0].tele_code = tele_strtobit(temp_buf,1); + + callbar_ptr->bar_list[jj].bs_code[1].param_flag = 1; // bearer + temp_buf[0] = TS_AllSMS; + callbar_ptr->bar_list[jj].bs_code[1].tele_code = tele_strtobit(temp_buf,1); + callbar_ptr->bar_list[jj].ss_status[1] = callbar_ptr->bar_list[jj].ss_status[0]; + callbar_ptr->bar_list[jj].param_flag |= 0x03; + } + tag2++; + } + } + if (!(ss_mask & 0x04) && get_tlv("7.3",temp_buf,&asn_buf) != -1) // ss_Data + { + flag |= 0x80; // ss info + isd_ptr->ss_info.param_flag |= 0x08; // ss data + ss_ptr = (ExtSsData_struct *)&isd_ptr->ss_info.ss_data; + ss_ptr->param_flag = 0; + for(jj = 0;jj < 16;jj ++) + { + sprintf(tlv2,"7.3-%d.4-1",tag1); + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + ss_ptr->param_flag |= (0x01 << jj); + ss_ptr->ss_code[jj] = temp_buf[0]; + ss_mask |= 0x04; + } + else + break; + sprintf(tlv2,"7.3-%d.4-2",tag1); //ss-status + // len = get_tlv(tlv2,temp_buf,&asn_buf); + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + ss_ptr->ss_status[jj] = temp_buf[0]; + ss_ptr->subs_opt[jj].choice_flag = 0; + sprintf(tlv2,"7.3-%d.2-3",tag1); //cliRestrictionOption + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + ss_ptr->subs_opt[jj].choice_flag = 1; // clires opt + ss_ptr->subs_opt[jj].choice.clires_opt = temp_buf[0]; + } + sprintf(tlv2,"7.3-%d.1-3",tag1); //overrideCategory + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + ss_ptr->subs_opt[jj].choice_flag = 2; // clires opt + ss_ptr->subs_opt[jj].choice.over_cate = temp_buf[0]; + } + sprintf(tlv2,"7.3-%d.2-2",tag1); // bearer code + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len > 0) + ss_ptr->bs_code[jj].bearer_code = bearer_strtobit(temp_buf,1); + sprintf(tlv2,"7.3-%d.3",tag1); // tele code + len = get_tlv(tlv2,temp_buf, &asn_buf); + if (len >= 1) + ss_ptr->bs_code[jj].tele_code = tele_strtobit(temp_buf,1); + tag1 ++; + } + } + if(!(ss_mask & 0x08) && get_tlv("7.4", temp_buf, &asn_buf) != -1) //emlpp-Info + { + flag |= 0x80; // ss info + isd_ptr->ss_info.param_flag |= 0x10; //emlpp info + emlpp_ptr = (EmlppInfo_struct *)&isd_ptr->ss_info.emlpp_info; + emlpp_ptr->param_flag = 0; + ss_mask |= 0x08; + sprintf(tlv2, "7.4-%d.2-1", tag1); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + emlpp_ptr->param_flag |= 0x01; + emlpp_ptr->maxent_prio = temp_buf[0]; + } + sprintf(tlv2, "7.4-%d.2-2", tag1); + if(get_tlv(tlv2, temp_buf, &asn_buf) == 1) + { + emlpp_ptr->param_flag |= 0x02; + emlpp_ptr->default_prio = temp_buf[0]; + } + } + } + if (get_null("9",&asn_buf) != -1) //get roaming restriction data + { + flag |= 0x100; + isd_ptr->roam_feature = 1; + } + len = get_tlv("10",temp_buf,&asn_buf); //regional Subscription Data + if (len > 0) + { + flag |= 0x200; + for (jj = 0;jj < ZONECODE_LEN;jj ++) + { + sprintf(tlv2,"10.4-%d",jj+1); + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len == 2) + memcpy(isd_ptr->zc_list.zone_code[jj],temp_buf,2); + else + break; + } + isd_ptr->zc_list.list_len = jj; + } + len = get_tlv("11",temp_buf,&asn_buf); //vbs Subscription Data + if (len > 0) + { + flag |= 0x400; + for (jj = 0;jj < VBS_LEN;jj ++) + { + sprintf(tlv2,"11.16-%d.4",jj+1); + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len == 3) + { + memcpy(isd_ptr->vbsdata_list.vbs_data[jj].group_id,temp_buf,3); + isd_ptr->vbsdata_list.vbs_data[jj].param_flag |= 0x01; + } + else + break; + sprintf(tlv2,"11.16-%d.5",jj+1); + if (get_null(tlv2,&asn_buf) >= 0) + isd_ptr->vbsdata_list.vbs_data[jj].param_flag |= 0x02; + } + isd_ptr->vbsdata_list.list_len = jj; + } + len = get_tlv("12",temp_buf,&asn_buf); //vgcs Subscription Data + if (len > 0) + { + flag |= 0x800; + for (jj = 0;jj < VGCS_LEN;jj ++) + { + sprintf(tlv2,"12.16-%d.4",jj+1); + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len == 3) + { + memcpy(isd_ptr->vgcdata_list.vgc_data[jj].group_id,temp_buf,3); + isd_ptr->vgcdata_list.vgc_data[jj].param_flag = 0x01; + } + else + break; + } + isd_ptr->vgcdata_list.list_len = jj; + } + len = get_tlv("13",temp_buf,&asn_buf); //vlr Camel Subscription Info + if (len > 0) + { + flag |= 0x1000; + isd_ptr->subs_info.param_flag = 0; + len = get_tlv("13.0",temp_buf,&asn_buf); //o-CSI + if (len != -1) + { + if (!extract_ocsi(&isd_ptr->subs_info.o_csi,len,temp_buf)) + return RER; + isd_ptr->subs_info.param_flag |= 0x01; + } + if (extract_sscsi("13.2",&isd_ptr->subs_info.ss_csi,&asn_buf) > 0) //ss-CSI + isd_ptr->subs_info.param_flag |= 0x02; + len = get_tlv("13.4",temp_buf,&asn_buf); //O-BcsmCamelTDPCriteriaList + if (len != -1) + { + if (!extract_tdpcritlist(&isd_ptr->subs_info.tdp_list,len,temp_buf)) + return RER; + isd_ptr->subs_info.param_flag |= 0x04; + } + if (extract_smscsi("13.6",&isd_ptr->subs_info.sms_csi,&asn_buf) > 0) //sms-CSI + isd_ptr->subs_info.param_flag |= 0x08; + } + if (get_tlv("15.0",temp_buf,&asn_buf) == NAEA_LEN) //naea Preferred CI + { + memcpy(isd_ptr->naea_ci.cic,temp_buf,NAEA_LEN); + flag |= 0x2000; + } + len = get_tlv("16",temp_buf,&asn_buf); //GPRS Subscription Data + if (len > 0) + { + flag |= 0x4000; + if (get_null("16.5",&asn_buf) != -1) + { + isd_ptr->gprs_data.param_flag |= 0x01; + isd_ptr->gprs_data.data_include = 1; + } + for (jj = 0;jj < PDPCONTEXT_LEN;jj ++) + { + pdp_ptr = (PdpContext_struct *) &isd_ptr->gprs_data.gprs_list.pdp_context[jj]; + pdp_ptr->param_flag = 0; + sprintf(tlv2,"16.16-%d.2",jj+1); // pdp context id + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + pdp_ptr->param_flag |= 0x01; + pdp_ptr->pdpcontext_id = temp_buf[0]; + } + else + break; + sprintf(tlv2,"16.16-%d.16",jj+1); // pdp type + if (get_tlv(tlv2,temp_buf,&asn_buf) == 2) + { + pdp_ptr->param_flag |= 0x02; + memcpy(pdp_ptr->pdp_type,temp_buf,2); + } + sprintf(tlv2,"16.16-%d.17",jj+1); // pdp address + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len != -1 && len < PDP_LEN) + { + pdp_ptr->param_flag |= 0x04; + pdp_ptr->pdp_add[0] = len; + memcpy(pdp_ptr->pdp_add+1,temp_buf,len); + } + sprintf(tlv2,"16.16-%d.18",jj+1); // QoS subscribed + if (get_tlv(tlv2,temp_buf,&asn_buf) == 3) + { + pdp_ptr->param_flag |= 0x08; + memcpy(pdp_ptr->qos_sub,temp_buf,3); + } + sprintf(tlv2,"16.16-%d.19",jj+1); // vplmn allow + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + pdp_ptr->param_flag |= 0x10; + pdp_ptr->vplmn_allow = temp_buf[0]; + } + sprintf(tlv2,"16.16-%d.20",jj+1); // apn + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len != -1 && len < APN_LEN) + { + pdp_ptr->param_flag |= 0x20; + pdp_ptr->apn.apn_len = len; + memcpy(pdp_ptr->apn.apn_data,temp_buf,len); + } + sprintf(tlv2,"16.16-%d.0",jj+1); // ext QoS subscribed + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len != -1 && len < EXT_QOS_SUB_LEN) + { + pdp_ptr->param_flag |= 0x40; + pdp_ptr->ext_qos_sub[0] = len; + memcpy(pdp_ptr->ext_qos_sub+1,temp_buf,len); + } + } + if (jj != 0) + isd_ptr->gprs_data.param_flag |= 0x02; + isd_ptr->gprs_data.gprs_list.list_len = jj; + } + if (get_null("23",&asn_buf) != -1)//roaming Restricted In Sgsn Due To Unsupported Feature + { + flag |= 0x8000; + isd_ptr->roamsgsn_feature = 1; + } + if (get_tlv("24",temp_buf,&asn_buf) == 1) + { + flag |= 0x10000; + isd_ptr->net_mode = temp_buf[0]; + } + isd_ptr->param_flag = flag; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding insert subscribe Data response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_inssubdatares(struct MapISD_Res *isd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int temp_len; + u8 temp_buf[256],temp_data[256]; + int flag,jj,buf_len=0; + int tag1=1; + char tlv1[32],tlv2[32]; + + asn_encode(buf,&asn_buf); + flag = isd_ptr->param_flag; + if (flag & 0x01) // tele list + { + temp_len = tele_bittostr(isd_ptr->tele_data,temp_data,0); + sprintf(tlv1,"1-%d",tag1++); + for (jj = 0;jj < temp_len;jj ++) + { + sprintf(tlv2,"%s.4-%d",tlv1,jj+1); + buf_len = add_tlv(tlv2,1,&temp_data[jj],0x00,&asn_buf); + } + } + if (flag & 0x02) // bearer list + { + temp_len = bearer_bittostr(isd_ptr->bearer_data,temp_data,0); + sprintf(tlv1,"2-%d",tag1++); + for (jj = 0;jj < temp_len;jj ++) + { + sprintf(tlv2,"%s.4-%d",tlv1,jj+1); + buf_len = add_tlv(tlv2,1,&temp_data[jj],0x00,&asn_buf); + } + } + if (flag & 0x04) // ss list + { + sprintf(tlv1,"3-%d",tag1++); + for (jj = 0;jj < isd_ptr->ss_list.sslist_len;jj ++) + { + sprintf(tlv2,"%s.4-%d",tlv1,jj+1); + buf_len = add_tlv(tlv2,1,&isd_ptr->ss_list.ss_code[jj],0x00,&asn_buf); + } + } + if (flag & 0x08) // odb data + { + sprintf(tlv1,"4-%d",tag1++); + temp_buf[0] = isd_ptr->odb_data; + temp_len = bytestrtobitstr(temp_data,temp_buf,6); + buf_len = add_tlv(tlv1,temp_len,temp_data,0x80,&asn_buf); + } + if (flag & 0x10) //subs res + { + sprintf(tlv1,"5-%d",tag1++); + temp_buf[0] = isd_ptr->subs_res; + buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf); + } + if (flag & 0x20) // camel phase + { + sprintf(tlv1,"6-%d",tag1++); + buf_len = add_tlv(tlv1,3,isd_ptr->camel_phase,0x80,&asn_buf); + } + return buf_len; +} + +int extract_inssubdatares(struct MapISD_Res *isd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len,jj; + int temp_len; + u8 temp_buf[256],temp_data[256]; + u32 flag=0; + char tlv2[32]; + + isd_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + temp_len = 0; + for (jj = 0;jj < TSLIST_LEN;jj ++) // tele Service List + { + sprintf(tlv2,"1.4-%d",jj+1); + if(get_tlv(tlv2,temp_buf,&asn_buf) < 1) + break; + temp_data[jj] = temp_buf[0]; + temp_len++; + flag |= 0x01; + } + isd_ptr->tele_data = tele_strtobit(temp_data,temp_len); + temp_len = 0; + for (jj = 0;jj < BSLIST_LEN;jj ++) // bearer Service List + { + sprintf(tlv2,"2.4-%d",jj+1); + if(get_tlv(tlv2,temp_buf,&asn_buf) < 1) + break; + temp_data[jj] = temp_buf[0]; + temp_len ++; + flag |= 0x02; + } + isd_ptr->bearer_data = bearer_strtobit(temp_data,temp_len); + isd_ptr->ss_list.sslist_len = 0; + for (jj = 0;jj < SS_LEN;jj ++) // ss list + { + sprintf(tlv2,"3.4-%d",jj+1); + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) + { + flag |= 0x04; + isd_ptr->ss_list.ss_code[jj] = temp_buf[0]; + } + else + break; + } + isd_ptr->ss_list.sslist_len = jj; + len = get_tlv("4",temp_buf,&asn_buf); //odb-data + if (len != -1) + { + flag |= 0x08; + jj = bitstrtobytestr(temp_data,temp_buf,len); + isd_ptr->odb_data = bcdtou32(temp_data,jj); + } + if (get_tlv("5",temp_buf,&asn_buf) == 1)// subs response + { + isd_ptr->subs_res = temp_buf[0]; + flag |= 0x10; + } + if (get_tlv("6",temp_buf,&asn_buf) == 3) + { + memcpy(isd_ptr->camel_phase,temp_buf,3); + flag |= 0x20; + } + isd_ptr->param_flag = flag; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding delete Subscriber Data argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_delsubdataarg(struct MapDSD_Arg *dsd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0,jj; + char tlv2[32]; + u32 flag; + int temp_len; + u8 temp_data[256]; + + flag = dsd_ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //imsi + buf_len = add_tlv("0",IMSI_LEN,dsd_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (flag & 0x02) //bs code + { + temp_len = assign_bscode(&dsd_ptr->bs_code,temp_data,0); + buf_len = add_tlv("1",temp_len,temp_data,0x80,&asn_buf); + } + if (flag & 0x04) //ss list + { + for (jj = 0;jj < dsd_ptr->ss_list.sslist_len;jj ++) + { + sprintf(tlv2,"2.4-%d",jj+1); + buf_len = add_tlv(tlv2,1,&dsd_ptr->ss_list.ss_code[jj],0x00,&asn_buf); + } + } + if (flag & 0x08) //roaming restriction due to unsupported feature + buf_len = add_null("4",0x80,&asn_buf); + if (flag & 0x10) //regional subscription identifier (zone code) + buf_len = add_tlv("5",2,dsd_ptr->regional_ident,0x80,&asn_buf); + if (flag & 0x20) //vbsGroupIndication + buf_len = add_null("7",0x80,&asn_buf); + if (flag & 0x40) //vgcGroupIndication + buf_len = add_null("8",0x80,&asn_buf); + if (flag & 0x80) //camelSubscriptionInfoWithdraw + buf_len = add_null("9",0x80,&asn_buf); + if (flag & 0x100) //gprsSubscriptionDataWithdraw + { + if (dsd_ptr->gprs_withdraw.choice_flag & 0x01) + buf_len = add_null("10.5",0x00,&asn_buf); + else if (dsd_ptr->gprs_withdraw.choice_flag & 0x02) + { + if (dsd_ptr->gprs_withdraw.choice.context_list.list_len > PDPCONTEXT_LEN) + return RER; + temp_len = dsd_ptr->gprs_withdraw.choice.context_list.list_len; + for (jj = 0;jj < temp_len;jj ++) + { + sprintf(tlv2,"10.4-%d",jj+1); + buf_len = add_int(tlv2,dsd_ptr->gprs_withdraw.choice.context_list.context_id[jj],0x00,&asn_buf); + } + } + } + if (flag & 0x200) //roaming restricted insgsn due to unsupported feature + buf_len = add_null("11",0x80,&asn_buf); + return buf_len; +} + +int extract_delsubdataarg(struct MapDSD_Arg *dsd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len,jj; + u8 temp_buf[256]; + char tlv2[32]; + + dsd_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //imsi + { + dsd_ptr->param_flag|=0x01; + memcpy(dsd_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + if ((len=get_tlv("1",temp_buf,&asn_buf)) > 0) //bs code + { + if (!extract_bscode(&dsd_ptr->bs_code,len,temp_buf)) + return RER; + dsd_ptr->param_flag |= 0x02; + } + dsd_ptr->ss_list.sslist_len = 0; + for (jj = 0;jj < SS_LEN;jj ++) //get ss list + { + sprintf(tlv2,"2.4-%d",jj+1); + if (get_tlv(tlv2,temp_buf,&asn_buf) != 1) + break; + dsd_ptr->ss_list.sslist_len++; + dsd_ptr->ss_list.ss_code[jj] = temp_buf[0]; + dsd_ptr->param_flag|=0x04; + } + if (get_tlv("4",temp_buf,&asn_buf) != -1) //roaming restriction due to unsupported feature + { + dsd_ptr->param_flag |= 0x08; + dsd_ptr->roam_feature = 1; + } + if (get_tlv("5",temp_buf,&asn_buf) == 2) // regional subscription identifier (zone code) + { + dsd_ptr->param_flag |= 0x10; + memcpy(dsd_ptr->regional_ident,temp_buf,2); + } + if (get_tlv("7",temp_buf,&asn_buf) != -1) //vbsGroupIndication + { + dsd_ptr->param_flag |= 0x20; + dsd_ptr->vbsg_ind = 1; + } + if (get_tlv("8",temp_buf,&asn_buf) != -1) //vgcGroupIndication + { + dsd_ptr->param_flag |= 0x40; + dsd_ptr->vgcsg_ind = 1; + } + if (get_tlv("9",temp_buf,&asn_buf) != -1) //camelSubscriptionInfoWithdraw + { + dsd_ptr->param_flag |= 0x80; + dsd_ptr->camel_withdraw = 1; + } + if (get_tlv("10",temp_buf,&asn_buf) != -1) //gprsSubscriptionDataWithdraw + { + dsd_ptr->param_flag |= 0x100; + if (get_tlv("10.5",temp_buf,&asn_buf) != -1) // all GPRS data + { + dsd_ptr->gprs_withdraw.choice_flag = 0x01; + dsd_ptr->gprs_withdraw.choice.allgprs_data = 1; + } + else + { + dsd_ptr->gprs_withdraw.choice.context_list.list_len = 0; + for (jj = 0;jj < PDPCONTEXT_LEN;jj ++) + { + sprintf(tlv2,"10.4-%d",jj+1); + if (get_tlv(tlv2,temp_buf,&asn_buf) != 1) + break; + dsd_ptr->gprs_withdraw.choice.context_list.context_id[jj] = temp_buf[0]; + dsd_ptr->gprs_withdraw.choice.context_list.list_len ++; + dsd_ptr->gprs_withdraw.choice_flag = 0x02; + } + } + } + if (get_tlv("11",temp_buf,&asn_buf) != -1) //roaming restricted insgsn due to unsupported feature + { + dsd_ptr->param_flag |= 0x200; + dsd_ptr->roamsgsn_feature = 1; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding delete Subscriber Data response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_delsubdatares(struct MapDSD_Res *dsdr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 temp_buf[16]; + + asn_encode(buf,&asn_buf); + if (dsdr_ptr->param_flag & 0x01) + { + temp_buf[0] = dsdr_ptr->subs_res; + buf_len = add_tlv("0",1,temp_buf,0x80,&asn_buf); + } + return buf_len; +} + +int extract_delsubdatares(struct MapDSD_Res *dsdr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + dsdr_ptr->param_flag=0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) > 0) + { + dsdr_ptr->subs_res = temp_buf[0]; + dsdr_ptr->param_flag |= 0x01; + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++ */ +/* encoding/decoding RESET argument */ +/* +++++++++++++++++++++++++++++++++ */ +int assign_resetarg(struct MapReset_Arg *rs_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0,ii; + u8 temp_isdn[32]; + char tlv2[32]; + + asn_encode(buf,&asn_buf); + flag = rs_ptr->param_flag; + if (flag & 0x01) // hlr num + buf_len = add_tlv("4",rs_ptr->hlr_num[0],rs_ptr->hlr_num+1,0x00,&asn_buf); + else + { + mapp_log_debug("reset lack hlr_num"); + return RER; + } + if (flag & 0x02) // hlr_list + { + for(ii = 0;ii < rs_ptr->hlr_list.list_len;ii ++) + { + buf_len = add_null("16",0x20,&asn_buf); + sprintf(tlv2,"16.4-%d",ii+1); + buf_len = add_tlv(tlv2,IMSI_LEN,rs_ptr->hlr_list.hlr_id[ii],0x00,&asn_buf); + } + } + if (flag & 0x04) //networkResource + { + temp_isdn[0] = rs_ptr->networkResource; + buf_len = add_tlv("10",1,temp_isdn,0x00,&asn_buf); + } + return buf_len; +} + +int extract_resetarg(struct MapReset_Arg *rs_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + int ii; + char tlv2[32]; + + rs_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_reset,buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); //hlr num + if(len > 2) + { + rs_ptr->param_flag |= 0x01; + rs_ptr->hlr_num[0] = len; + memcpy(rs_ptr->hlr_num+1,temp_buf,len); + } + else + { + mapp_log_debug("extract resetArg lack hlr number"); + return RER; + } + rs_ptr->hlr_list.list_len=0; + for (ii = 0;ii < HLRID_NUM;ii ++) + { + sprintf(tlv2,"16.4-%d",ii+1); + len = get_tlv(tlv2,temp_buf,&asn_buf); + if (len != IMSI_LEN) + break; + rs_ptr->param_flag |= 0x02; + memcpy(rs_ptr->hlr_list.hlr_id[ii],temp_buf,IMSI_LEN); + } + rs_ptr->hlr_list.list_len = ii; + if(get_tlv("10",temp_buf,&asn_buf) == 1) + { + rs_ptr->networkResource=temp_buf[0]; + rs_ptr->param_flag |= 0x04; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding restore Data argument */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_restdataarg(struct MapRD_Arg *rsd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (rsd_ptr->param_flag & 0x01) //imsi + buf_len = add_tlv("4-1",IMSI_LEN,rsd_ptr->imsi,0x00,&asn_buf); + else + return RER; + if (rsd_ptr->param_flag & 0x02) //lmsi + buf_len = add_tlv("4-2",LMSI_LEN,rsd_ptr->lmsi,0x00,&asn_buf); + if (rsd_ptr->param_flag & 0x04) // VLR capability + { + if (rsd_ptr->vlr_cap.param_flag & 0x01) // camel phase + buf_len = add_tlv("6.0",3,rsd_ptr->vlr_cap.camel_phase,0x80,&asn_buf); + } + return buf_len; +} + +int extract_restdataarg(struct MapRD_Arg *rsd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_restdataarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + rsd_ptr->param_flag = 0; + len = get_tlv("4-1",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + rsd_ptr->param_flag |= 0x01; + memcpy(rsd_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + if (get_tlv("4-2",temp_buf,&asn_buf) == LMSI_LEN) //get lmsi + { + memcpy(rsd_ptr->lmsi,temp_buf,LMSI_LEN); + rsd_ptr->param_flag |= 0x02; + } + len = get_tlv("6.0",temp_buf,&asn_buf); //get camel info + if (len != -1) + { + memcpy(rsd_ptr->vlr_cap.camel_phase,temp_buf,3); + rsd_ptr->vlr_cap.param_flag = 0x01; + rsd_ptr->param_flag |= 0x04; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding restore Data response */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_restdatares(struct MapRD_Res *rsd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (rsd_ptr->param_flag & 0x01) //hlr num + buf_len = add_tlv("4",rsd_ptr->hlr_num[0],rsd_ptr->hlr_num+1,0x00,&asn_buf); + else + return RER; + if (rsd_ptr->param_flag & 0x02) //MS not reachable + buf_len = add_null("5",0x00,&asn_buf); + return buf_len; +} + +int extract_restdatares(struct MapRD_Res *rsd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_restdatares buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + rsd_ptr->param_flag = 0; + if((len=get_tlv("4",temp_buf,&asn_buf)) > 2 )//get hlr number + { + rsd_ptr->hlr_num[0] = len; + memcpy(rsd_ptr->hlr_num+1,temp_buf,len); + rsd_ptr->param_flag|=0x01; + } + else + return RER; + if(get_tlv("5",temp_buf,&asn_buf) != -1) //get MS not reachable + { + rsd_ptr->param_flag |= 0x02; + rsd_ptr->msnot_reach = 1; + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send routing info for GPRS argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndroutinfogprsarg(struct MapSRIFG_Arg *sfg_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (sfg_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,sfg_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (sfg_ptr->param_flag & 0x02) // ggsn address + buf_len = add_tlv("1",sfg_ptr->ggsn_add[0],sfg_ptr->ggsn_add+1,0x80,&asn_buf); + if (sfg_ptr->param_flag & 0x04) // ggsn number + buf_len = add_tlv("2",sfg_ptr->ggsn_num[0],sfg_ptr->ggsn_num+1,0x80,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_sndroutinfogprsarg(struct MapSRIFG_Arg *sfg_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + sfg_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_sendroutinfoforgprs buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + sfg_ptr->param_flag |= 0x01; + memcpy(sfg_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 0 && len <= GSN_LEN) //get ggsn address + { + sfg_ptr->param_flag |= 0x02; + sfg_ptr->ggsn_add[0] = len; + memcpy(sfg_ptr->ggsn_add+1,temp_buf,len); + } + len = get_tlv("2",temp_buf,&asn_buf); // get ggsn number + if (len >0 && len <= ISDN_LEN) + { + sfg_ptr->param_flag |= 0x04; + sfg_ptr->ggsn_num[0] = len; + memcpy(sfg_ptr->ggsn_num+1,temp_buf,len); + } + else + return RER; + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send routing info for GPRS response */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_sndroutinfogprsres(struct MapSRIFG_Res *sfg_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (sfg_ptr->param_flag & 0x01) // sgsn address + buf_len = add_tlv("0",sfg_ptr->sgsn_add[0],sfg_ptr->sgsn_add+1,0x80,&asn_buf); + else + return RER; + if (sfg_ptr->param_flag & 0x02) // ggsn address + buf_len = add_tlv("1",sfg_ptr->ggsn_add[0],sfg_ptr->ggsn_add+1,0x80,&asn_buf); + if (sfg_ptr->param_flag & 0x04) // mobile not reachable reason + buf_len = add_tlv("2",1,&sfg_ptr->mobile_reason,0x80,&asn_buf); + return buf_len; +} + +int extract_sndroutinfogprsres(struct MapSRIFG_Res *sfg_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + sfg_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_sendroutinfoforgprs res buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len > 0 && len <= GSN_LEN) + { + sfg_ptr->param_flag |= 0x01; + sfg_ptr->sgsn_add[0] = len; + memcpy(sfg_ptr->sgsn_add+1,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); + if (len > 0 && len <= GSN_LEN) //get ggsn address + { + sfg_ptr->param_flag |= 0x02; + sfg_ptr->ggsn_add[0] = len; + memcpy(sfg_ptr->ggsn_add+1,temp_buf,len); + } + if (get_tlv("2",temp_buf,&asn_buf) == 1) // get mobile not reachable reason + { + sfg_ptr->param_flag |= 0x04; + sfg_ptr->mobile_reason = temp_buf[0]; + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding failure report argument */ +/* +++++++++++++++++++++++++++++++++++++++++ */ +int assign_failreportarg(struct MapFR_Arg *fr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (fr_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,fr_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (fr_ptr->param_flag & 0x02) // ggsn number + buf_len = add_tlv("1",fr_ptr->ggsn_num[0],fr_ptr->ggsn_num+1,0x80,&asn_buf); + else + return RER; + if (fr_ptr->param_flag & 0x04) // ggsn address + buf_len = add_tlv("2",fr_ptr->ggsn_add[0],fr_ptr->ggsn_add+1,0x80,&asn_buf); + return buf_len; +} + +int extract_failreportarg(struct MapFR_Arg *fr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + fr_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_failure report buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + fr_ptr->param_flag |= 0x01; + memcpy(fr_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); // get ggsn number + if (len >0 && len <= ISDN_LEN) + { + fr_ptr->param_flag |= 0x02; + fr_ptr->ggsn_num[0] = len; + memcpy(fr_ptr->ggsn_num+1,temp_buf,len); + } + else + return RER; + len = get_tlv("2",temp_buf,&asn_buf); + if (len > 0 && len <= GSN_LEN) //get ggsn address + { + fr_ptr->param_flag |= 0x04; + fr_ptr->ggsn_add[0] = len; + memcpy(fr_ptr->ggsn_add+1,temp_buf,len); + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding failure report response */ +/* +++++++++++++++++++++++++++++++++++++++++ */ +int assign_failreportres(struct MapFR_Res *fr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (fr_ptr->param_flag & 0x01) // ggsn address + buf_len = add_tlv("0",fr_ptr->ggsn_add[0],fr_ptr->ggsn_add+1,0x80,&asn_buf); + return buf_len; +} + +int extract_failreportres(struct MapFR_Res *fr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + fr_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len > 0 && len <= GSN_LEN) //get ggsn address + { + fr_ptr->param_flag |= 0x01; + fr_ptr->ggsn_add[0] = len; + memcpy(fr_ptr->ggsn_add+1,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding note MS present for GPRS argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_notemspregprsarg(struct MapNMPFG_Arg *npg_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (npg_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,npg_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (npg_ptr->param_flag & 0x02) // sgsn address + buf_len = add_tlv("1",npg_ptr->sgsn_add[0],npg_ptr->sgsn_add+1,0x80,&asn_buf); + else + return RER; + if (npg_ptr->param_flag & 0x04) // ggsn address + buf_len = add_tlv("2",npg_ptr->ggsn_add[0],npg_ptr->ggsn_add+1,0x80,&asn_buf); + return buf_len; +} + +int extract_notemspregprsarg(struct MapNMPFG_Arg *npg_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + npg_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--note ms present for gprs buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + npg_ptr->param_flag |= 0x01; + memcpy(npg_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); // get sgsn address + if (len >0 && len <= GSN_LEN) + { + npg_ptr->param_flag |= 0x02; + npg_ptr->sgsn_add[0] = len; + memcpy(npg_ptr->sgsn_add+1,temp_buf,len); + } + else + return RER; + len = get_tlv("2",temp_buf,&asn_buf); //get ggsn address + if (len > 0 && len <= GSN_LEN) + { + npg_ptr->param_flag |= 0x04; + npg_ptr->ggsn_add[0] = len; + memcpy(npg_ptr->ggsn_add+1,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding note MS present for GPRS response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_notemspregprsres(struct MapNMPFG_Res *npg_ptr,u8 *buf) +{ + return 0; +} + +int extract_notemspregprsres(struct MapNMPFG_Res *npg_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} diff --git a/plat/xapp/src/mapp/map_code_om.c b/plat/xapp/src/mapp/map_code_om.c new file mode 100644 index 0000000..2f2776d --- /dev/null +++ b/plat/xapp/src/mapp/map_code_om.c @@ -0,0 +1,231 @@ +/* map coding operation & maintenance c file */ +/* written by Liu Zhiguo 2003-03-04 */ +/* Version 2.0 */ +/* ----------------------------------------- */ + +#include "map_includes.h" + +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding activate trace mode argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_acttrcmodearg(struct MapATM_Arg *atm_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (atm_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,atm_ptr->imsi,0x80,&asn_buf); + if (atm_ptr->param_flag & 0x02) // trace reference + buf_len = add_tlv("1",2,atm_ptr->trace_ref,0x80,&asn_buf); + else + return RER; + if (atm_ptr->param_flag & 0x04) // trace type + buf_len = add_int("2",atm_ptr->trace_type,0x80,&asn_buf); + else + return RER; + if (atm_ptr->param_flag & 0x08) // omc id + buf_len = add_tlv("3",atm_ptr->omc_id[0],atm_ptr->omc_id+1,0x80,&asn_buf); + return buf_len; +} + +int extract_acttrcmodearg(struct MapATM_Arg *atm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + atm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_activate trace mode buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + atm_ptr->param_flag |= 0x01; + memcpy(atm_ptr->imsi,temp_buf,IMSI_LEN); + } + if (get_tlv("1",temp_buf,&asn_buf) == 2) + { + atm_ptr->param_flag |= 0x02; + memcpy(atm_ptr->trace_ref,temp_buf,2); + } + else + return RER; + if (get_tlv("2",temp_buf,&asn_buf) == 1) + { + atm_ptr->param_flag |= 0x04; + atm_ptr->trace_type = temp_buf[0]; + } + else + return RER; + len = get_tlv("3",temp_buf,&asn_buf); + if (len > 0 && len <= ISDN_LEN) + { + atm_ptr->param_flag |= 0x08; + atm_ptr->omc_id[0] = len; + memcpy(atm_ptr->omc_id+1,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding activate trace mode response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_acttrcmoderes(struct MapATM_Res *atm_ptr,u8 *buf) +{ + return 0; +} + +int extract_acttrcmoderes(struct MapATM_Res *atm_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding deactivate trace mode argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_deacttrcmodearg(struct MapDTM_Arg *dtm_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (dtm_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,dtm_ptr->imsi,0x80,&asn_buf); + if (dtm_ptr->param_flag & 0x02) // trace reference + buf_len = add_tlv("1",2,dtm_ptr->trace_ref,0x80,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_deacttrcmodearg(struct MapDTM_Arg *dtm_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + dtm_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_deactivate trace mode buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + dtm_ptr->param_flag |= 0x01; + memcpy(dtm_ptr->imsi,temp_buf,IMSI_LEN); + } + if (get_tlv("1",temp_buf,&asn_buf) == 2) + { + dtm_ptr->param_flag |= 0x02; + memcpy(dtm_ptr->trace_ref,temp_buf,2); + } + else + return RER; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding deactivate trace mode response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_deacttrcmoderes(struct MapDTM_Res *dtm_ptr,u8 *buf) +{ + return 0; +} + +int extract_deacttrcmoderes(struct MapDTM_Res *dtm_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send IMSI argument */ +/* ++++++++++++++++++++++++++++++++++++ */ +int assign_sndimsiarg(struct MapSIMSI_Arg *sim_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (sim_ptr->param_flag & 0x01) // msisdn + buf_len = add_tlv("4",sim_ptr->msisdn[0],sim_ptr->msisdn+1,0x00,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_sndimsiarg(struct MapSIMSI_Arg *sim_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + sim_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_send imsi buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); + if (len > 0 && len <= ISDN_LEN) + { + sim_ptr->param_flag |= 0x01; + sim_ptr->msisdn[0] = len; + memcpy(sim_ptr->msisdn+1,temp_buf,len); + } + else + return RER; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding send IMSI response */ +/* ++++++++++++++++++++++++++++++++++++ */ +int assign_sndimsires(struct MapSIMSI_Res *sim_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (sim_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("4",IMSI_LEN,sim_ptr->imsi,0x00,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_sndimsires(struct MapSIMSI_Res *sim_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + sim_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_send imsi buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf); + if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + sim_ptr->param_flag |= 0x01; + memcpy(sim_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + return ROK; +} diff --git a/plat/xapp/src/mapp/map_code_sms.c b/plat/xapp/src/mapp/map_code_sms.c new file mode 100644 index 0000000..1f87bc7 --- /dev/null +++ b/plat/xapp/src/mapp/map_code_sms.c @@ -0,0 +1,1322 @@ +/* mapp coding short message c file */ +/* written by Liu Zhiguo 2003-03-04 */ +/* Version 2.0 */ +/* -------------------------------- */ + +#include "map_includes.h" + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding Send Routing Info For SM argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_routinfoforsmarg(struct MapRIFSM_Arg *rif_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = rif_ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //msisdn + buf_len = add_tlv("0",rif_ptr->msisdn[0],rif_ptr->msisdn+1,0x80,&asn_buf); + else + return RER; + if (flag & 0x02) //sm_rp_pri + buf_len = add_tlv("1",1,&rif_ptr->sm_rp_pri,0x80,&asn_buf); + else + return RER; + if (flag & 0x04) //service centre address + buf_len = add_tlv("2",rif_ptr->sc_add[0],rif_ptr->sc_add+1,0x80,&asn_buf); + else + return RER; + if (flag & 0x08) // gprs support indicator + buf_len = add_null("7",0x80,&asn_buf); + if (flag & 0x10) // sm-rp-mti + buf_len = add_tlv("8",1,&rif_ptr->sm_rp_mti,0x80,&asn_buf); + if (flag & 0x20) // sm-rp-smea + buf_len = add_tlv("9",rif_ptr->sm_rp_smea[0],rif_ptr->sm_rp_smea+1,0x80,&asn_buf); + return buf_len; +} + +int extract_routinfoforsmarg(struct MapRIFSM_Arg *rif_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + rif_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_routinfoforsmarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if((len=get_tlv("0",temp_buf,&asn_buf)) > 2) //get msisdn + { + rif_ptr->msisdn[0] = len; + memcpy(rif_ptr->msisdn+1,temp_buf,len); + rif_ptr->param_flag |= 0x01; + } + else + return RER; + if(get_tlv("1",temp_buf,&asn_buf) == 1) //get sm_rp_pri + { + rif_ptr->sm_rp_pri = temp_buf[0]; + rif_ptr->param_flag |= 0x02; + } + else + return RER; + if((len=get_tlv("2",temp_buf,&asn_buf)) > 2 ) //get service centre address + { + rif_ptr->sc_add[0] = len; + memcpy(rif_ptr->sc_add+1,temp_buf,len); + rif_ptr->param_flag |= 0x04; + } + else + return RER; + if (get_tlv("7",temp_buf,&asn_buf) != -1) // gprs support indicator + { + rif_ptr->param_flag |= 0x08; + rif_ptr->gprssup_flag = 1; + } + if (get_tlv("8",temp_buf,&asn_buf) == 1) // sm-rp-mti + { + rif_ptr->param_flag |= 0x10; + rif_ptr->sm_rp_mti = temp_buf[0]; + } + len = get_tlv("9",temp_buf,&asn_buf); + if (len != -1 && len < SMEA_LEN) // sm-rp-smea + { + rif_ptr->param_flag |= 0x20; + rif_ptr->sm_rp_smea[0] =len; + memcpy(rif_ptr->sm_rp_smea+1,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding Send Routing Info For SM response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_routinfoforsmres(struct MapRIFSM_Res *rif_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 len; + u32 flag; + u8 tag1; + char tlv1[32]; + + flag = rif_ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //imsi + buf_len = add_tlv("4-1",IMSI_LEN,rif_ptr->imsi,0x00,&asn_buf); + else + return RER; + if (flag & 0x02) //LocInfoLMSI_struct + { + tag1 = 1; + if (rif_ptr->loc_info.param_flag & 0x01) //msc_number + { + sprintf(tlv1,"0-2.1-%d",tag1++); + len = rif_ptr->loc_info.netnode_num[0]; + buf_len = add_tlv(tlv1,len,rif_ptr->loc_info.netnode_num+1,0x80,&asn_buf); + } + if (rif_ptr->loc_info.param_flag & 0x02) //lmsi + { + sprintf(tlv1,"0-2.4-%d",tag1++); + buf_len = add_tlv(tlv1,LMSI_LEN,rif_ptr->loc_info.lmsi,0x00,&asn_buf); + } + if (rif_ptr->loc_info.param_flag & 0x04) // gprs node indicator + { + sprintf(tlv1,"0-2.5-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (rif_ptr->loc_info.param_flag & 0x08) // additional number + { + if (rif_ptr->loc_info.add_num.choice_flag & 0x01) // msc number + { + sprintf(tlv1,"0-2.6-%d.0",tag1); + len = rif_ptr->loc_info.add_num.choice.msc_num[0]; + buf_len = add_tlv(tlv1,len,rif_ptr->loc_info.add_num.choice.msc_num+1,0x80,&asn_buf); + } + else + { + sprintf(tlv1,"0-2.6-%d.1",tag1); + len = rif_ptr->loc_info.add_num.choice.sgsn_num[0]; + buf_len = add_tlv(tlv1,len,rif_ptr->loc_info.add_num.choice.sgsn_num+1,0x80,&asn_buf); + } + } + } + else + return RER; + return buf_len; +} + +int extract_routinfoforsmres(struct MapRIFSM_Res *rif_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len,loop; + + rif_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_routinfoforsmres buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4",temp_buf,&asn_buf) % 9; +// if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + if (len>0) + { + if(lenimsi,temp_buf,IMSI_LEN); + rif_ptr->param_flag |= 0x01; + } + else + return RER; + if (get_tlv("0",temp_buf,&asn_buf) > 0) //get LocInfoLMSI_struct + { + rif_ptr->param_flag|=0x02; + rif_ptr->loc_info.param_flag = 0; + if((len=get_tlv("0.1",temp_buf,&asn_buf)) > 0) //msc_num + { + rif_ptr->loc_info.param_flag |= 0x01; + rif_ptr->loc_info.netnode_num[0] = len; + memcpy(rif_ptr->loc_info.netnode_num+1,temp_buf,len); + } + if(get_tlv("0.4",temp_buf,&asn_buf) == LMSI_LEN) //get lmsi + { + rif_ptr->loc_info.param_flag |= 0x02; + memcpy(rif_ptr->loc_info.lmsi,temp_buf,LMSI_LEN); + } + if (get_tlv("0.5",temp_buf,&asn_buf) != -1) // gprs node indicator + { + rif_ptr->loc_info.param_flag |= 0x04; + rif_ptr->loc_info.gprsnode_flag = 1; + } + len = get_tlv("0.6.0",temp_buf,&asn_buf); // msc number + if (len != -1 && len <= ISDN_LEN) + { + rif_ptr->loc_info.param_flag |= 0x08; + rif_ptr->loc_info.add_num.choice_flag = 1; + rif_ptr->loc_info.add_num.choice.msc_num[0] = len; + memcpy(rif_ptr->loc_info.add_num.choice.msc_num+1,temp_buf,len); + } + else + { + len = get_tlv("0.6.1",temp_buf,&asn_buf); // sgsn number + if (len != -1 && len <= ISDN_LEN) + { + rif_ptr->loc_info.param_flag |= 0x08; + rif_ptr->loc_info.add_num.choice_flag = 2; + rif_ptr->loc_info.add_num.choice.sgsn_num[0] = len; + memcpy(rif_ptr->loc_info.add_num.choice.sgsn_num+1,temp_buf,len); + } + } + } + else + return RER; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding Send Routing Info For SM V1 argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_routinfoforsm_v1_arg(struct MapRIFSMV1_Arg *rif_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = rif_ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01)//msisdn + buf_len = add_tlv("0",rif_ptr->msisdn[0],rif_ptr->msisdn+1,0x80,&asn_buf); + else + return RER; + if (flag & 0x02) //sm_rp_pri + buf_len = add_tlv("1",1,&rif_ptr->sm_rp_pri,0x80,&asn_buf); + else + return RER; + if (flag & 0x04) //service centre address + buf_len = add_tlv("2",rif_ptr->sc_add[0],rif_ptr->sc_add+1,0x80,&asn_buf); + else + return RER; + if (flag & 0x08) //tele service + buf_len = add_tlv("5",1,&rif_ptr->tele_service,0x80,&asn_buf); + + return buf_len; +} + +int extract_routinfoforsm_v1_arg(struct MapRIFSMV1_Arg *rif_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + rif_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_routinfoforsmarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if((len=get_tlv("0",temp_buf,&asn_buf)) > 2) //get msisdn + { + rif_ptr->msisdn[0] = len; + memcpy(rif_ptr->msisdn+1,temp_buf,len); + rif_ptr->param_flag |= 0x01; + } + else + return RER; + if(get_tlv("1",temp_buf,&asn_buf) == 1) //get sm_rp_pri + { + rif_ptr->sm_rp_pri = temp_buf[0]; + rif_ptr->param_flag |= 0x02; + } + else + return RER; + if((len=get_tlv("2",temp_buf,&asn_buf)) > 2 ) //get service centre address + { + rif_ptr->sc_add[0] = len; + memcpy(rif_ptr->sc_add+1,temp_buf,len); + rif_ptr->param_flag |= 0x04; + } + else + return RER; + if (get_tlv("5",temp_buf,&asn_buf) == -1) // gprs support indicator + { + rif_ptr->param_flag |= 0x08; + memcpy( &rif_ptr->tele_service , temp_buf ,1 ); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding Send Routing Info For SM response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_routinfoforsm_v1_res(struct MapRIFSMV1_Res *rif_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + + flag = rif_ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //imsi + buf_len = add_tlv("4-1",IMSI_LEN,rif_ptr->imsi,0x00,&asn_buf); + else + return RER; + if (flag & 0x02) //LocInfoLMSI_struct_v1 + { + + if (rif_ptr->loc_info.param_flag & 0x01) //location info + { + if( rif_ptr->loc_info.choice_flag == 1) + { + buf_len = add_tlv("0-2.0-1",ISDN_LEN,rif_ptr->loc_info.choice.roaming_num,0x80,&asn_buf); + } + else if( rif_ptr->loc_info.choice_flag == 2) + { + buf_len = add_tlv("0-2.1-1",ISDN_LEN,rif_ptr->loc_info.choice.msc_num,0x80,&asn_buf); + } + } + if (rif_ptr->loc_info.param_flag & 0x02) //imsi + { + buf_len = add_tlv("0-2.4-2",IMSI_LEN,rif_ptr->loc_info.imsi,0x80,&asn_buf); + } + } + else + return RER; + + if( flag & 0x04 ) + buf_len = add_tlv("2-3",1,&rif_ptr->mwd_set,0x80,&asn_buf); + return buf_len; +} + +int extract_routinfoforsm_v1_res(struct MapRIFSMV1_Res *rif_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + rif_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_routinfoforsmres buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("4-1",temp_buf,&asn_buf) ; + if ( len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + memcpy(rif_ptr->imsi,temp_buf,IMSI_LEN); + rif_ptr->param_flag |= 0x01; + } + else + return RER; + + if (get_tlv("0",temp_buf,&asn_buf) > 0) //get LocInfoLMSI_struct + { + rif_ptr->param_flag|=0x02; + rif_ptr->loc_info.param_flag = 0; + if((len=get_tlv("0.0",temp_buf,&asn_buf)) > 0) //msc_num + { + rif_ptr->loc_info.param_flag |= 0x01; + rif_ptr->loc_info.choice_flag = 1; + memcpy(rif_ptr->loc_info.choice.roaming_num,temp_buf,len); + } + if(get_tlv("0.1",temp_buf,&asn_buf) == LMSI_LEN) //get lmsi + { + rif_ptr->loc_info.param_flag |= 0x01; + rif_ptr->loc_info.choice_flag = 2; + memcpy(rif_ptr->loc_info.choice.msc_num,temp_buf,len); + } + if (get_tlv("0.4",temp_buf,&asn_buf) == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) // gprs node indicator + { + rif_ptr->loc_info.param_flag |= 0x02; + memcpy(rif_ptr->loc_info.imsi,temp_buf,IMSI_LEN); + } + } + else + return RER; + + if( get_tlv("0",temp_buf,&asn_buf) == 1 ) + { + memcpy(&rif_ptr->mwd_set,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding forward SM Arg */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_fwdsmarg(struct MapFSM_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 len; + u32 flag; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //sm_rp_da + { + if (ptr->sm_rp_da_choice == 1) //imsi + buf_len = add_tlv("0-1",IMSI_LEN,ptr->sm_rp_da.imsi,0x80,&asn_buf); + else if (ptr->sm_rp_da_choice == 2) //lmsi + buf_len = add_tlv("1-1",LMSI_LEN,ptr->sm_rp_da.lmsi,0x80,&asn_buf); + else if( ptr->sm_rp_da_choice == 3 ) + { + len = ptr->sm_rp_da.roaming_num[0]; + buf_len = add_tlv("3-1",len,ptr->sm_rp_da.roaming_num+1,0x80,&asn_buf); + } + else if (ptr->sm_rp_da_choice== 4) //sc_add + { + len = ptr->sm_rp_da.sc_add[0]; + buf_len = add_tlv("4-1",len,ptr->sm_rp_da.sc_add+1,0x80,&asn_buf); + } + else + buf_len = add_null("5-2",0x80,&asn_buf); + } + else + { + mapp_log_debug("MAPP--assign_fwdsmarg:loss sm_rp_da"); + return RER; + } + if (flag & 0x02) //sm_rp_oa + { + if (ptr->sm_rp_oa_choice == 1) //msisdn + { + len = ptr->sm_rp_oa.msisdn[0]; + buf_len = add_tlv("2-2",len,ptr->sm_rp_oa.msisdn+1,0x80,&asn_buf); + } + else if (ptr->sm_rp_oa_choice == 2)//sc_add + { + len = ptr->sm_rp_oa.sc_add[0]; + buf_len = add_tlv("4-2",len,ptr->sm_rp_oa.sc_add+1,0x80,&asn_buf); + } + else + buf_len = add_null("5-2",0x80,&asn_buf); + } + else + { + mapp_log_debug("MAPP--assign_fwdsmarg:loss sm_rp_oa"); + return RER; + } + if (flag & 0x04) //sm_rp_ui + { + len = ptr->sm_rp_ui_len; + buf_len = add_tlv("4-3",len,ptr->sm_rp_ui,0x00,&asn_buf); + } + else + return RER; + + return buf_len; +} + +int extract_fwdsmarg(struct MapFSM_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_mofwdsmarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); //imsi + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + ptr->sm_rp_da_choice = 1; + memcpy(ptr->sm_rp_da.imsi,temp_buf,IMSI_LEN); + } + else + { + if((len=get_tlv("1",temp_buf,&asn_buf)) == LMSI_LEN)//lmsi + { + ptr->sm_rp_da_choice = 2; + memcpy(ptr->sm_rp_da.lmsi,temp_buf,LMSI_LEN); + } + else + { + if((len=get_tlv("3-1",temp_buf,&asn_buf)) > 0)//sc_add + { + ptr->sm_rp_da_choice = 3; + ptr->sm_rp_da.roaming_num[0] = len; + memcpy(ptr->sm_rp_da.roaming_num+1,temp_buf,len); + } + else + { + if((len=get_tlv("4-1",temp_buf,&asn_buf)) > 0)//sc_add + { + ptr->sm_rp_da_choice = 4; + ptr->sm_rp_da.sc_add[0] = len; + memcpy(ptr->sm_rp_da.sc_add+1,temp_buf,len); + } + else + { + if (get_tlv("5-1",temp_buf,&asn_buf) != -1) // no SM-RP-DA + { + ptr->sm_rp_da_choice = 5; + ptr->sm_rp_da.noms_rp_da = 1; + } + else + return RER; + } + } + + } + } + + ptr->param_flag |= 0x01; + if ((len=get_tlv("2",temp_buf,&asn_buf)) > 0) //msisdn + { + ptr->sm_rp_oa_choice = 1; + ptr->sm_rp_oa.msisdn[0] = len; + memcpy(ptr->sm_rp_oa.msisdn+1,temp_buf,len); + } + else + { + if ((len=get_tlv("4-2",temp_buf,&asn_buf)) > 0) //sc_add + { + ptr->sm_rp_oa_choice = 2; + ptr->sm_rp_oa.sc_add[0] = len; + memcpy(ptr->sm_rp_oa.sc_add+1,temp_buf,len); + } + else + { + if (get_tlv("5-2",temp_buf,&asn_buf) != -1) // no SM-RP-OA + { + ptr->sm_rp_oa_choice = 3; + ptr->sm_rp_oa.noms_rp_oa = 1; + } + else + return RER; + } + } + ptr->param_flag |= 0x02; + if((len=get_tlv("4-3",temp_buf,&asn_buf)) !=-1) + { + ptr->param_flag |= 0x04; + ptr->sm_rp_ui_len = len; + memcpy(ptr->sm_rp_ui,temp_buf,len); + } + + return ROK; +} + + + + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding MO forward SM Arg */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_mofwdsmarg(struct MapMOFSM_Arg *ptr,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 len; + u32 flag; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //sm_rp_da + { + if (ptr->sm_rp_da.choice_flag == 1) //imsi + buf_len = add_tlv("0-1",IMSI_LEN,ptr->sm_rp_da.choice.imsi,0x80,&asn_buf); + else if (ptr->sm_rp_da.choice_flag == 2) //lmsi + buf_len = add_tlv("1-1",LMSI_LEN,ptr->sm_rp_da.choice.lmsi,0x80,&asn_buf); + else if (ptr->sm_rp_da.choice_flag == 3) //sc_add + { + len = ptr->sm_rp_da.choice.sc_add[0]; + buf_len = add_tlv("4-1",len,ptr->sm_rp_da.choice.sc_add+1,0x80,&asn_buf); + } + else if( version <3 && ptr->sm_rp_da.choice_flag == 5 ) + { + len = ptr->sm_rp_da.choice.roaming_num[0]; + buf_len = add_tlv("3-1",len,ptr->sm_rp_da.choice.roaming_num+1,0x80,&asn_buf); + } + else + buf_len = add_null("5-1",0x80,&asn_buf); + } + else + { + mapp_log_debug("MAPP--assign_mofwdsmarg:loss sm_rp_da"); + return RER; + } + if (flag & 0x02) //sm_rp_oa + { + if (ptr->sm_rp_oa.choice_flag == 1) //msisdn + { + len = ptr->sm_rp_oa.choice.msisdn[0]; + buf_len = add_tlv("2-2",len,ptr->sm_rp_oa.choice.msisdn+1,0x80,&asn_buf); + } + else if (ptr->sm_rp_oa.choice_flag == 2)//sc_add + { + len = ptr->sm_rp_oa.choice.sc_add[0]; + buf_len = add_tlv("4-2",len,ptr->sm_rp_oa.choice.sc_add+1,0x80,&asn_buf); + } + else + buf_len = add_null("5-2",0x80,&asn_buf); + } + else + { + mapp_log_debug("MAPP--assign_mofwdsmarg:loss sm_rp_oa"); + return RER; + } + if (flag & 0x04) //sm_rp_ui + { + len = ptr->sm_rp_ui.siginfo_len; + buf_len = add_tlv("4-3",len,ptr->sm_rp_ui.signal_info,0x00,&asn_buf); + } + else + return RER; + if ((flag & 0x08) && (version==2)) //moremsg_flag,only MAP V2 support this + buf_len = add_null("5-4",0x00,&asn_buf); + + return buf_len; +} + +int extract_mofwdsmarg(struct MapMOFSM_Arg *ptr,u32 buf_len,u8 *buf,u8 version) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_mofwdsmarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); //imsi + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + ptr->sm_rp_da.choice_flag = 1; + memcpy(ptr->sm_rp_da.choice.imsi,temp_buf,IMSI_LEN); + } + else + { + if((len=get_tlv("1",temp_buf,&asn_buf)) == LMSI_LEN)//lmsi + { + ptr->sm_rp_da.choice_flag = 2; + memcpy(ptr->sm_rp_da.choice.lmsi,temp_buf,LMSI_LEN); + } + else + { + if((len=get_tlv("4-1",temp_buf,&asn_buf)) > 0)//sc_add + { + ptr->sm_rp_da.choice_flag = 3; + ptr->sm_rp_da.choice.sc_add[0] = len; + memcpy(ptr->sm_rp_da.choice.sc_add+1,temp_buf,len); + } + else + { + if( version < 3 && (len=get_tlv("3-1",temp_buf,&asn_buf)) > 0 ) //roaming_num for ver <3 + { + ptr->sm_rp_da.choice_flag =5; + ptr->sm_rp_da.choice.roaming_num[0]= len; + memcpy( ptr->sm_rp_da.choice.roaming_num+1, temp_buf,len); + } + else + { + if (get_tlv("5-1",temp_buf,&asn_buf) != -1) // no SM-RP-DA + { + ptr->sm_rp_da.choice_flag = 4; + ptr->sm_rp_da.choice.no_rpda = 1; + } + else + return RER; + } + } + } + } + ptr->param_flag |= 0x01; + if ((len=get_tlv("2",temp_buf,&asn_buf)) > 0) //msisdn + { + ptr->sm_rp_oa.choice_flag = 1; + ptr->sm_rp_oa.choice.msisdn[0] = len; + memcpy(ptr->sm_rp_oa.choice.msisdn+1,temp_buf,len); + } + else + { + if ((len=get_tlv("4-2",temp_buf,&asn_buf)) > 0) //sc_add + { + ptr->sm_rp_oa.choice_flag = 2; + ptr->sm_rp_oa.choice.sc_add[0] = len; + memcpy(ptr->sm_rp_oa.choice.sc_add+1,temp_buf,len); + } + else + { + if (get_tlv("5-2",temp_buf,&asn_buf) != -1) // no SM-RP-OA + { + ptr->sm_rp_oa.choice_flag = 3; + ptr->sm_rp_oa.choice.no_rpoa = 1; + } + else + return RER; + } + } + ptr->param_flag |= 0x02; + if((len=get_tlv("4-3",temp_buf,&asn_buf)) !=-1 ) + { + ptr->param_flag |= 0x04; + ptr->sm_rp_ui.siginfo_len = len; + memcpy(ptr->sm_rp_ui.signal_info,temp_buf,len); + } + if (get_tlv("5-4",temp_buf,&asn_buf) != -1) + ptr->param_flag |= 0x08; + + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding MO forward SM response */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_mofwdsmres(struct MapMOFSM_Res *ptr,u8 *buf, u8 version) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 len; + + if(version<3) + return buf_len; + + asn_encode(buf,&asn_buf); + if (ptr->param_flag & 0x01) // sm-rp-ui + { + len = ptr->sm_rp_ui.siginfo_len; + buf_len = add_tlv("4",len,ptr->sm_rp_ui.signal_info,0x00,&asn_buf); + } + return buf_len; +} + +int extract_mofwdsmres(struct MapMOFSM_Res *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if((len=get_tlv("4",temp_buf,&asn_buf)) > 0) + { + ptr->param_flag |= 0x01; + ptr->sm_rp_ui.siginfo_len = len; + memcpy(ptr->sm_rp_ui.signal_info,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding MT forward SM argument */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_mtfwdsmarg(struct MapMTFSM_Arg *ptr,u8 *buf,u8 MAPVer) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 len; + u32 flag; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //sm_rp_da + { + if (ptr->sm_rp_da.choice_flag == 1) //imsi + { + len = IMSI_LEN; + if(ptr->sm_rp_da.choice.imsi[IMSI_LEN-1]== 0xff) + { + int loop; + for(loop=IMSI_LEN-1;loop>2;loop--) + { + if(ptr->sm_rp_da.choice.imsi[loop] == 0xff) + len --; + } + } + + buf_len = add_tlv("0-1", + len, + ptr->sm_rp_da.choice.imsi, + 0x80, + &asn_buf); + } + else if (ptr->sm_rp_da.choice_flag == 2) //lmsi + buf_len = add_tlv("1-1",LMSI_LEN,ptr->sm_rp_da.choice.lmsi,0x80,&asn_buf); + else if (ptr->sm_rp_da.choice_flag == 3) //sc_add + { + len = ptr->sm_rp_da.choice.sc_add[0]; + buf_len = add_tlv("4-1",len,ptr->sm_rp_da.choice.sc_add+1,0x80,&asn_buf); + } + else + buf_len = add_null("5-1",0x80,&asn_buf); + } + else + { + mapp_log_debug("MAPP--assign_mofwdsmarg:loss sm_rp_da"); + return RER; + } + if (flag & 0x02) //sm_rp_oa + { + if (ptr->sm_rp_oa.choice_flag == 1) //msisdn + { + len = ptr->sm_rp_oa.choice.msisdn[0]; + buf_len = add_tlv("2-2",len,ptr->sm_rp_oa.choice.msisdn+1,0x80,&asn_buf); + } + else if (ptr->sm_rp_oa.choice_flag == 2)//sc_add + { + len = ptr->sm_rp_oa.choice.sc_add[0]; + buf_len = add_tlv("4-2",len,ptr->sm_rp_oa.choice.sc_add+1,0x80,&asn_buf); + } + else + buf_len = add_null("5-2",0x80,&asn_buf); + } + else + { + mapp_log_debug("MAPP--assign_mofwdsmarg:loss sm_rp_oa"); + return RER; + } + if (flag & 0x04) //sm_rp_ui + { + len = ptr->sm_rp_ui.siginfo_len; + buf_len = add_tlv("4-3",len,ptr->sm_rp_ui.signal_info,0x00,&asn_buf); + } + else + return RER; + if ((flag & 0x08) && ((MAPVer==3)||(MAPVer==2))) //moremsg_flag,only MAP V3 support this + buf_len = add_null("5-4",0x00,&asn_buf); + return buf_len; +} + +int extract_mtfwdsmarg(struct MapMTFSM_Arg *ptr,u32 buf_len,u8 *buf,u8 MAPVer) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_mofwdsmarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); //imsi + if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) + { + ptr->sm_rp_da.choice_flag = 1; + memcpy(ptr->sm_rp_da.choice.imsi,temp_buf,IMSI_LEN); + } + else + { + if((len=get_tlv("1",temp_buf,&asn_buf)) == LMSI_LEN)//lmsi + { + ptr->sm_rp_da.choice_flag = 2; + memcpy(ptr->sm_rp_da.choice.lmsi,temp_buf,LMSI_LEN); + } + else + { + if((len=get_tlv("4-1",temp_buf,&asn_buf)) > 0)//sc_add + { + ptr->sm_rp_da.choice_flag = 3; + ptr->sm_rp_da.choice.sc_add[0] = len; + memcpy(ptr->sm_rp_da.choice.sc_add+1,temp_buf,len); + } + else + { + if (get_tlv("5-1",temp_buf,&asn_buf) != -1) // no SM-RP-DA + { + ptr->sm_rp_da.choice_flag = 4; + ptr->sm_rp_da.choice.no_rpda = 1; + } + else + return RER; + } + } + } + ptr->param_flag |= 0x01; + if ((len=get_tlv("2",temp_buf,&asn_buf)) > 0) //msisdn + { + ptr->sm_rp_oa.choice_flag = 1; + ptr->sm_rp_oa.choice.msisdn[0] = len; + memcpy(ptr->sm_rp_oa.choice.msisdn+1,temp_buf,len); + } + else + { + if ((len=get_tlv("4-2",temp_buf,&asn_buf)) > 0) //sc_add + { + ptr->sm_rp_oa.choice_flag = 2; + ptr->sm_rp_oa.choice.sc_add[0] = len; + memcpy(ptr->sm_rp_oa.choice.sc_add+1,temp_buf,len); + } + else + { + if (get_tlv("5-2",temp_buf,&asn_buf) != -1) // no SM-RP-OA + { + ptr->sm_rp_oa.choice_flag = 3; + ptr->sm_rp_oa.choice.no_rpoa = 1; + } + else + return RER; + } + } + ptr->param_flag |= 0x02; + if((len=get_tlv("4-3",temp_buf,&asn_buf)) != -1) + { + ptr->param_flag |= 0x04; + ptr->sm_rp_ui.siginfo_len = len; + memcpy(ptr->sm_rp_ui.signal_info,temp_buf,len); + } + if (get_tlv("5-4",temp_buf,&asn_buf) != -1) + ptr->param_flag |= 0x08; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding MT forward SM response */ +/* ++++++++++++++++++++++++++++++++++++++++ */ +int assign_mtfwdsmres(struct MapMTFSM_Res *ptr,u8 *buf,u8 MAPVer) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 len; + + asn_encode(buf,&asn_buf); + if (ptr->param_flag & 0x01) // sm-rp-ui + { + len = ptr->sm_rp_ui.siginfo_len; + buf_len = add_tlv("4",len,ptr->sm_rp_ui.signal_info,0x00,&asn_buf); + } + return buf_len; +} + +int extract_mtfwdsmres(struct MapMTFSM_Res *ptr,u32 buf_len,u8 *buf,u8 MAPVer) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if((len=get_tlv("4",temp_buf,&asn_buf)) > 0) + { + ptr->param_flag |= 0x01; + ptr->sm_rp_ui.siginfo_len = len; + memcpy(ptr->sm_rp_ui.signal_info,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding report SM Delivery Status argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_repsmdelstatarg(struct MapRSMDS_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + u8 temp_buf[256]; + u8 tag1; + char tlv1[32]; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //msisdn + buf_len = add_tlv("4-1",ptr->msisdn[0],ptr->msisdn+1,0x00,&asn_buf); + else + { + mapp_log_debug("MAPP--assign_reportSM_DeliveryStatus_arg:loss msisdn"); + return RER; + } + if (flag & 0x02) //sc_add + buf_len = add_tlv("4-2",ptr->sc_add[0],ptr->sc_add+1,0x00,&asn_buf); + else + { + mapp_log_debug("MAPP--assign_reportSM_DeliveryStatus_arg:loss sc_add"); + return RER; + } + if (flag & 0x04) //sm_deliout + { + temp_buf[0] = ptr->sm_deliout; + buf_len = add_tlv("10-3",1,temp_buf,0x00,&asn_buf); + } + else + return RER; + tag1 = 4; + if (flag & 0x08) // absent subscriber diagnostic sm + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,1,&ptr->abssubdiagsm,0x80,&asn_buf); + } + if (flag & 0x10) // gprs support indicator + { + sprintf(tlv1,"2-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x20) // delivery outcome indicator + { + sprintf(tlv1,"3-%d",tag1++); + buf_len = add_null(tlv1,0x80,&asn_buf); + } + if (flag & 0x40) // additional sm delivery outcome + { + sprintf(tlv1,"4-%d",tag1++); + temp_buf[0] = ptr->addsm_deliout; + buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf); + } + if (flag & 0x80) // additional absent subscriber diagnostic sm + { + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,1,&ptr->add_abssubdiagsm,0x80,&asn_buf); + } + return buf_len; +} + +int extract_repsmdelstatarg(struct MapRSMDS_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + u8 tag1; + char tlv1[32]; + + ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_repsmdelstatarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if((len=get_tlv("4-1",temp_buf,&asn_buf)) > 0)//msisdn + { + ptr->param_flag |= 0x01; + ptr->msisdn[0] = len; + memcpy(ptr->msisdn+1,temp_buf,len); + } + else + return RER; + if((len=get_tlv("4-2",temp_buf,&asn_buf)) > 0)//sc_add + { + ptr->param_flag |= 0x02; + ptr->sc_add[0] = len; + memcpy(ptr->sc_add+1,temp_buf,len); + } + else + return RER; + if(get_tlv("10",temp_buf,&asn_buf) > 0) //sm_deliout + { + ptr->param_flag |= 0x04; + ptr->sm_deliout = temp_buf[0]; + } + else + return RER; + tag1 = 4; + if (get_tlv("0",temp_buf,&asn_buf) == 1) // absent subscriber diagnostic sm + { + ptr->param_flag |= 0x08; + ptr->abssubdiagsm = temp_buf[0]; + tag1 ++; + } + if (get_tlv("2",temp_buf,&asn_buf) != -1) // gprs support indicator + { + ptr->param_flag |= 0x10; + ptr->gprssup_flag = 1; + tag1 ++; + } + if (get_tlv("3",temp_buf,&asn_buf) != -1) // delivery outcome indicator + { + ptr->param_flag |= 0x20; + ptr->deliout_flag = 1; + tag1 ++; + } + sprintf(tlv1,"4-%d",tag1); + if (get_tlv(tlv1,temp_buf,&asn_buf) != -1) // additional sm delivery outcome + { + ptr->param_flag |= 0x40; + ptr->addsm_deliout = temp_buf[0]; + } + if (get_tlv("5",temp_buf,&asn_buf) != -1) // additional absent subscriber diagnostic sm + { + ptr->param_flag |= 0x80; + ptr->add_abssubdiagsm = temp_buf[0]; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding report SM Delivery Status response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_repsmdelstatres(struct MapRSMDS_Res *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ptr->param_flag & 0x01) //stored_msisdn + buf_len = add_tlv("4",ptr->stored_msisdn[0],ptr->stored_msisdn+1,0x00,&asn_buf); + return buf_len; +} + +int extract_repsmdelstatres(struct MapRSMDS_Res *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if((len=get_tlv("4",temp_buf,&asn_buf)) > 0)//stored_msisdn + { + ptr->param_flag |= 0x01; + ptr->stored_msisdn[0] = len; + memcpy(ptr->stored_msisdn+1,temp_buf,len); + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding inform service Center argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_infsrvcentarg(struct MapISC_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 len; + u8 temp_buf[16],temp_data[16]; + + asn_encode(buf,&asn_buf); + if (ptr->param_flag & 0x01) //stored_msisdn + buf_len = add_tlv("4-1",ptr->stored_msisdn[0],ptr->stored_msisdn+1,0x00,&asn_buf); + if (ptr->param_flag & 0x02) //mw_status + { + temp_data[0] = ptr->mw_status; + len = bytestrtobitstr(temp_buf,temp_data,6); + buf_len = add_tlv("3-2",len,temp_buf,0x00,&asn_buf); + } + return buf_len; +} + +int extract_infsrvcentarg(struct MapISC_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256],temp_data[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if((len=get_tlv("4",temp_buf,&asn_buf)) > 0)//stored_msisdn + { + ptr->param_flag |= 0x01; + ptr->stored_msisdn[0] = len; + memcpy(ptr->stored_msisdn+1,temp_buf,len); + } + if ((len = get_tlv("3",temp_buf,&asn_buf)) > 0)//mw_status + { + ptr->param_flag |= 0x02; + bitstrtobytestr(temp_data,temp_buf,len); + ptr->mw_status = temp_data[0]; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding alert service Center argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_altsrvcentarg(struct MapASC_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ptr->param_flag & 0x01) //msisdn + buf_len = add_tlv("4-1",ptr->msisdn[0],ptr->msisdn+1,0x00,&asn_buf); + else + return RER; + if (ptr->param_flag & 0x02) //service center address + buf_len = add_tlv("4-2",ptr->sc_add[0],ptr->sc_add+1,0x00,&asn_buf); + else + return RER; + return buf_len; +} + +int extract_altsrvcentarg(struct MapASC_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_altsrvcentarg buf_len=0"); + return RER; + } + if(asn_decode_v3(buf,buf_len,&decErr,&asn_buf)==-1) + return RER; + if((len=get_tlv("4-1",temp_buf,&asn_buf)) > 0)//msisdn + { + ptr->param_flag |= 0x01; + ptr->msisdn[0] = len; + memcpy(ptr->msisdn+1,temp_buf,len); + } + else + return RER; + if((len=get_tlv("4-2",temp_buf,&asn_buf)) > 0)//sc_add + { + ptr->param_flag |= 0x02; + ptr->sc_add[0] = len; + memcpy(ptr->sc_add+1,temp_buf,len); + } + else + return RER; + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ready For SM argument */ +/* +++++++++++++++++++++++++++++++++++++++ */ +int assign_rdyforsmarg(struct MapRFSM_Arg *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + u8 temp_buf[256]; + + flag = ptr->param_flag; + asn_encode(buf,&asn_buf); + if (flag & 0x01) //imsi + buf_len = add_tlv("0",IMSI_LEN,ptr->imsi,0x80,&asn_buf); + else + return RER; + if (flag & 0x02) //alert_reason + { + temp_buf[0] = ptr->alert_reason; + buf_len = add_tlv("10",1,temp_buf,0x00,&asn_buf); + } + else + return RER; + if (flag & 0x04) // alert reason indicator + buf_len = add_null("5",0x00,&asn_buf); + return buf_len; +} + +int extract_rdyforsmarg(struct MapRFSM_Arg *ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + int len; + + ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_rdyforsmarg buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if(len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)//imsi + { + ptr->param_flag |= 0x01; + memcpy(ptr->imsi,temp_buf,len); + } + else + return RER; + if((len=get_tlv("10",temp_buf,&asn_buf)) >0)//alert_reason + { + ptr->param_flag |= 0x02; + ptr->alert_reason = temp_buf[0]; + } + else + return RER; + if (get_tlv("5",temp_buf,&asn_buf) != -1) // alert reason indicator + { + ptr->param_flag |= 0x04; + ptr->altreason_flag = 1; + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding ready For SM response */ +/* +++++++++++++++++++++++++++++++++++++++ */ +int assign_rdyforsmres(struct MapRFSM_Res *ptr,u8 *buf) +{ + return 0; +} + +int extract_rdyforsmres(struct MapRFSM_Res *ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} diff --git a/plat/xapp/src/mapp/map_code_ss.c b/plat/xapp/src/mapp/map_code_ss.c new file mode 100644 index 0000000..0e18f3a --- /dev/null +++ b/plat/xapp/src/mapp/map_code_ss.c @@ -0,0 +1,1647 @@ +/* mapp coding supplementary service c file */ +/* written by Liu Zhiguo 2003-03-04 */ +/* Version 2.0 */ +/* ----------------------------------------- */ + +#include "map_includes.h" + +int assign_fwdfeat(struct FwdFeat_struct *fwd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + u32 flag1; + int buf_len=0; + int temp_len; + u_char temp_buf[256]; + + asn_encode(buf,&asn_buf); + buf_len = add_null("16",0x20,&asn_buf); + flag1 = fwd_ptr->param_flag; + if (flag1 & 0x01) // bs code + { + if (fwd_ptr->bs_code.param_flag == 1) + { + temp_len = tele_bittostr(fwd_ptr->bs_code.tele_code,temp_buf,1); + buf_len = add_tlv("16.3",temp_len,temp_buf,0x80,&asn_buf); + } + else if (fwd_ptr->bs_code.param_flag == 2) + { + temp_len = bearer_bittostr(fwd_ptr->bs_code.bearer_code,temp_buf,1); + buf_len = add_tlv("16.2",temp_len,temp_buf,0x80,&asn_buf); + } + } + else + { + temp_buf[0] = 0x10; + buf_len = add_tlv("16.3",1,temp_buf,0x80,&asn_buf); + } + + if (flag1 & 0x02) //ss status + buf_len = add_tlv("16.4",1,&fwd_ptr->ss_status,0x80,&asn_buf); + if (flag1 & 0x04) //fwdto_num + buf_len = add_tlv("16.5",fwd_ptr->fwdto_num[0],fwd_ptr->fwdto_num+1,0x80,&asn_buf); + /** + if (flag1 & 0x08) //fwdto sub addr + { + sprintf(tlv5,"%s.8-%d",tlv4,tag5++); + buf_len = add_tlv(tlv5,ISDNSUB_LEN,fwd_ptr->fwdto_subadd,0x80,&asn_buf); + } + **/ + if (flag1 & 0x08) //fwd opt + buf_len = add_tlv("16.6",1,&fwd_ptr->fwd_option,0x80,&asn_buf); + if (flag1 & 0x10) //norc time + buf_len = add_tlv("16.7",1,&fwd_ptr->norc_time,0x80,&asn_buf); + return buf_len; +} + +int extract_fwdfeat(struct FwdFeat_struct *fwd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + fwd_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("16.2",temp_buf,&asn_buf); + if (len != -1) // bearer code + { + fwd_ptr->param_flag |= 0x01; // bs code + fwd_ptr->bs_code.param_flag = 2; // bearer + fwd_ptr->bs_code.bearer_code = bearer_strtobit(temp_buf,len); + } + len = get_tlv("16.3",temp_buf,&asn_buf); + if (len != -1) // tele code + { + fwd_ptr->param_flag |= 0x01; // bs code + fwd_ptr->bs_code.param_flag = 1;// tele + fwd_ptr->bs_code.tele_code = tele_strtobit(temp_buf,len); + } + if (get_tlv("16.4",temp_buf,&asn_buf) == 1) // ss status + { + fwd_ptr->param_flag |= 0x02; // ss status + fwd_ptr->ss_status = temp_buf[0]; + } + len = get_tlv("16.5",temp_buf,&asn_buf); + if (len != -1 && len <= ISDN_LEN) + { + fwd_ptr->param_flag |= 0x04; // fwd to num + fwd_ptr->fwdto_num[0]=len; + memcpy(fwd_ptr->fwdto_num+1,temp_buf,len); + } + /** + len = get_tlv("8",temp_buf,&asn_buf); + if (len >= 1) + { + fwd_ptr->param_flag |= 0x08; // fwd to sub addr + memcpy(fwd_ptr->fwdto_subadd,temp_buf,len); + } + **/ + if (get_tlv("16.6",temp_buf,&asn_buf) == 1) // forward option + { + fwd_ptr->param_flag |= 0x08; // fwd opt + fwd_ptr->fwd_option = temp_buf[0]; + } + if (get_tlv("16.7",temp_buf,&asn_buf) == 1) // no reply condition time + { + fwd_ptr->param_flag |= 0x10; // norc time + fwd_ptr->norc_time = temp_buf[0]; + } + return ROK; +} + +int assign_ssforbscode(struct SsForBsCode_struct *BSptr, u8 *buf) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + int temp_len; + u_char temp_buf[256]; + + asn_encode(buf,&asn_buf); + flag = BSptr->param_flag; + if (flag & 0x01) + buf_len = add_tlv("4-1",1,&BSptr->ss_code,0x00,&asn_buf); + else + { + mapp_log_debug("MAPP--encode_ss_for_bs_code has not ss_code"); + return RER; + } + if (flag & 0x02) + { + if (BSptr->bs_code.param_flag == 2) //bearer code + { + temp_len = bearer_bittostr(BSptr->bs_code.bearer_code,temp_buf,1); + buf_len = add_tlv("2-2",temp_len,temp_buf,0x80,&asn_buf); + } + else if (BSptr->bs_code.param_flag == 1) + { + temp_len = tele_bittostr(BSptr->bs_code.tele_code,temp_buf,1); + buf_len = add_tlv("3-2",temp_len,temp_buf,0x80,&asn_buf); + } + } + return buf_len; +} + +int extract_ssforbscode(struct SsForBsCode_struct *BSptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + BSptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if(get_tlv("4",temp_buf,&asn_buf) == 1) + { + BSptr->param_flag |= 0x01; //ss code + BSptr->ss_code = temp_buf[0]; + } + else + return RER; + if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1) + { + BSptr->param_flag |= 0x02;//bs code + BSptr->bs_code.param_flag = 2;//bearer + BSptr->bs_code.bearer_code = bearer_strtobit(temp_buf,len); + } + else if ((len=get_tlv("3",temp_buf,&asn_buf)) != -1) + { + BSptr->param_flag |= 0x02;//bs code + BSptr->bs_code.param_flag = 1;//tele + BSptr->bs_code.tele_code = tele_strtobit(temp_buf,len); + } + return ROK; +} + +int assign_ssinfo(struct SsInfo_struct *sf_ptr,u8 *buf) +{ + u32 flag1; + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + u8 tag2; + char tlv2[32]; + struct FwdInfo_struct *fwd_ptr; + struct SsData_struct *ss_ptr; + struct CBInfo_struct *cbinf_ptr; + + asn_encode(buf,&asn_buf); + if (sf_ptr->choice_flag == 1) //forward info, flag = 1 + { + fwd_ptr = (FwdInfo_struct*) &sf_ptr->choice.fwd_info; + if (fwd_ptr->param_flag & 0x01) // ss code + buf_len = add_tlv("0.4",1,&fwd_ptr->ss_code,0x00,&asn_buf); + if (fwd_ptr->param_flag & 0x02) // forwarding feature list + { + temp_len = assign_fwdfeat(&fwd_ptr->fwd_feat,temp_buf); + buf_len = add_tlv("0.16",temp_len,temp_buf,0x20,&asn_buf); + } + else + return RER; + } + else if (sf_ptr->choice_flag == 2) //call barring info, flag = 2 + { + cbinf_ptr = (CBInfo_struct*)&sf_ptr->choice.cb_info; + if (cbinf_ptr->param_flag & 0x01) // ss code + buf_len = add_tlv("1.4",1,&cbinf_ptr->ss_code,0x00,&asn_buf); + if (cbinf_ptr->param_flag & 0x02) // call barring feature list + { + flag1 = cbinf_ptr->cb_feat.param_flag; + if (flag1 & 0x01) // bs code + { + temp_len = assign_bscode(&cbinf_ptr->cb_feat.bs_code,temp_buf,1); + buf_len = add_null("1.16",0x20,&asn_buf); + buf_len = add_tlv("1.16.16",temp_len,temp_buf,0x20,&asn_buf); + if (flag1 & 0x02) + buf_len = add_tlv("1.16.16.4",1,&cbinf_ptr->cb_feat.ss_status,0x80,&asn_buf); + } + else if (flag1 & 0x02) //ss status + { + buf_len = add_null("1.16",0x20,&asn_buf); + buf_len = add_null("1.16.16",0x20,&asn_buf); + buf_len = add_tlv("1.16.16.4",1,&cbinf_ptr->cb_feat.ss_status,0x80,&asn_buf); + } + } + else + return RER; + } + else if (sf_ptr->choice_flag == 3) //ss data, flag = 3 + { + ss_ptr = (SsData_struct*)&sf_ptr->choice.ss_data; + tag2 = 1; + if (ss_ptr->param_flag & 0x01) //ss-code + { + sprintf(tlv2,"3.4-%d",tag2++); + buf_len = add_tlv(tlv2,1,&ss_ptr->ss_code,0x00,&asn_buf); + } + if (ss_ptr->param_flag & 0x02) //ss-status + { + sprintf(tlv2,"3.4-%d",tag2++); + buf_len = add_tlv(tlv2,1,&ss_ptr->ss_status,0x80,&asn_buf); + } + if (ss_ptr->param_flag & 0x04) //ss-subscriptionOption + { + if (ss_ptr->subs_opt.choice_flag == 1) + { + sprintf(tlv2,"3.2-%d",tag2); + temp_buf[0] = ss_ptr->subs_opt.choice.clires_opt; + buf_len = add_tlv(tlv2,1,temp_buf,0x80,&asn_buf); + } + else if (ss_ptr->subs_opt.choice_flag == 2) + { + sprintf(tlv2,"3.1-%d",tag2); + temp_buf[0] = ss_ptr->subs_opt.choice.over_cate; + buf_len = add_tlv(tlv2,1,temp_buf,0x80,&asn_buf); + } + tag2 ++; + } + if (ss_ptr->param_flag & 0x08) //basicServiceGroupList + { + temp_len = assign_bscode(&ss_ptr->bs_code,temp_buf,1); + sprintf(tlv2,"3.16-%d",tag2++); + buf_len = add_tlv(tlv2,temp_len,temp_buf,0x20,&asn_buf); + } + if (ss_ptr->param_flag & 0x10) // default priority + { + sprintf(tlv2,"3.4-%d",tag2); + buf_len = add_tlv(tlv2,1,&ss_ptr->default_prio,0x00,&asn_buf); + } + } + else + return RER; + return buf_len; +} + +int extract_ssinfo(struct SsInfo_struct *sf_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 tag2; + char tlv2[32]; + u8 temp_buf[256]; + struct FwdInfo_struct *fwd_ptr; + struct CBInfo_struct *cbinf_ptr; + struct SsData_struct *ss_ptr; + + sf_ptr->choice_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("decode SS info buf_len=0"); + return ROK; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return 0; + if (get_tlv("0",temp_buf,&asn_buf) > 0) //---forwardingInfo + { + sf_ptr->choice_flag = 1; + fwd_ptr = (FwdInfo_struct*) &sf_ptr->choice.fwd_info; + fwd_ptr->param_flag = 0; + fwd_ptr->fwd_feat.param_flag = 0; + if (get_tlv("0.4",temp_buf,&asn_buf) == 1) // ss code + { + fwd_ptr->param_flag |= 0x01; + fwd_ptr->ss_code = temp_buf[0]; + } + len = get_tlv("0.16",temp_buf,&asn_buf); + if (len != -1) // + { + fwd_ptr->param_flag |= 0x02; // fwd feat + if (!extract_fwdfeat(&fwd_ptr->fwd_feat,len,temp_buf)) + return RER; + } + } + else if (get_tlv("1",temp_buf,&asn_buf) > 1) //callBarringInfo + { + sf_ptr->choice_flag = 2; + cbinf_ptr = (CBInfo_struct*)&sf_ptr->choice.cb_info; + cbinf_ptr->param_flag=0; + cbinf_ptr->cb_feat.param_flag = 0; + if (get_tlv("1.4",temp_buf,&asn_buf) == 1) // ss code + { + cbinf_ptr->param_flag |= 0x01; // ss code + cbinf_ptr->ss_code = temp_buf[0]; + } + len = get_tlv("1.16",temp_buf,&asn_buf); // basic code + if (len != -1) + { + cbinf_ptr->param_flag |= 0x02; // call barring info + cbinf_ptr->cb_feat.param_flag |= 0x01; // bs code + extract_bscode(&cbinf_ptr->cb_feat.bs_code,len,temp_buf); + } + if (get_tlv("1.16.4",temp_buf,&asn_buf) == 1) // ss status + { + cbinf_ptr->param_flag |= 0x02; // call barring info + cbinf_ptr->cb_feat.param_flag |= 0x02; // ss status + cbinf_ptr->cb_feat.ss_status = temp_buf[0]; + } + } + else if (get_tlv("3",temp_buf,&asn_buf) > 1) //ss-Data + { + sf_ptr->choice_flag = 3; + ss_ptr = (SsData_struct*) &sf_ptr->choice.ss_data; + ss_ptr->param_flag = 0; + if (get_tlv("3.4-1",temp_buf,&asn_buf) == 1) // ss code + { + ss_ptr->param_flag |= 0x01; // ss code + ss_ptr->ss_code = temp_buf[0]; + } + tag2 = 2; + sprintf(tlv2,"3.4-%d",tag2); + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) // ss-status + { + ss_ptr->param_flag |= 0x02; + ss_ptr->ss_status = temp_buf[0]; + tag2 ++; + } + if (get_tlv("3.2",temp_buf,&asn_buf) == 1) // cli restrction option + { + ss_ptr->param_flag |= 0x04; // subs opt + ss_ptr->subs_opt.choice_flag = 1; // clires opt + ss_ptr->subs_opt.choice.clires_opt = temp_buf[0]; + tag2 ++; + } + if (get_tlv("3.1",temp_buf,&asn_buf) == 1) // override category + { + ss_ptr->param_flag |= 0x04; // subs opt + ss_ptr->subs_opt.choice_flag = 2; // clires opt + ss_ptr->subs_opt.choice.over_cate = temp_buf[0]; + tag2 ++; + } + len = get_tlv("3.16",temp_buf,&asn_buf); // basic code + if (len != -1) + { + extract_bscode(&ss_ptr->bs_code,len,temp_buf); + ss_ptr->param_flag |= 0x08; // bs code + tag2 ++; + } + sprintf(tlv2,"3.4-%d",tag2); + if (get_tlv(tlv2,temp_buf,&asn_buf) == 1) // default priority + { + ss_ptr->param_flag |= 0x10; + ss_ptr->default_prio = temp_buf[0]; + tag2 ++; + } + } + else + return RER; + return ROK; +} + +int assign_ussdarg(struct UssdArg_struct *ussd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 tag1; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (ussd_ptr->param_flag & 0x01) // ussd scheme + buf_len = add_tlv("4-1",1,&ussd_ptr->ussd_scheme,0x00,&asn_buf); + else + return RER; + if (ussd_ptr->param_flag & 0x02) // ussd string + { + if (ussd_ptr->ussd_string.string_len > USSD_LEN) + return RER; + buf_len = add_tlv("4-2",ussd_ptr->ussd_string.string_len,ussd_ptr->ussd_string.ussd_data,0x00,&asn_buf); + } + else + return RER; + tag1 = 3; + if (ussd_ptr->param_flag & 0x04) // alert pattern + { + sprintf(tlv1,"4-%d",tag1++); + buf_len = add_tlv(tlv1,1,&ussd_ptr->alt_pattern,0x00,&asn_buf); + } + if (ussd_ptr->param_flag & 0x08) // msisdn + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,ussd_ptr->msisdn[0],ussd_ptr->msisdn+1,0x80,&asn_buf); + } + return buf_len; +} + +int extract_ussdarg(struct UssdArg_struct *ussd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ussd_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1",temp_buf,&asn_buf) == 1) // ussd scheme + { + ussd_ptr->param_flag |= 0x01; + ussd_ptr->ussd_scheme = temp_buf[0]; + } + else + return RER; + len = get_tlv("4-2",temp_buf,&asn_buf); // ussd data + if (len > 0 && len <= USSD_LEN) + { + ussd_ptr->param_flag |= 0x02; + ussd_ptr->ussd_string.string_len = len; + memcpy(ussd_ptr->ussd_string.ussd_data,temp_buf,len); + } + else + return RER; + if (get_tlv("4-3",temp_buf,&asn_buf) == 1) // alert pattern + { + ussd_ptr->param_flag |= 0x04; + ussd_ptr->alt_pattern = temp_buf[0]; + } + len = get_tlv("0",temp_buf,&asn_buf); // msisdn + if (len > 0 && len <= ISDN_LEN) + { + ussd_ptr->param_flag |= 0x08; + ussd_ptr->msisdn[0] = len; + memcpy(ussd_ptr->msisdn+1,temp_buf,len); + } + return ROK; +} + +int assign_ussdres(struct UssdRes_struct *ussd_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ussd_ptr->param_flag & 0x01) // ussd scheme + buf_len = add_tlv("4-1",1,&ussd_ptr->ussd_scheme,0x00,&asn_buf); + else + return RER; + if (ussd_ptr->param_flag & 0x02) // ussd string + { + if (ussd_ptr->ussd_string.string_len > USSD_LEN) + return RER; + buf_len = add_tlv("4-2",ussd_ptr->ussd_string.string_len,ussd_ptr->ussd_string.ussd_data,0x00,&asn_buf); + } + else + return RER; + return buf_len; +} + +int extract_ussdres(struct UssdRes_struct *ussd_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + ussd_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1",temp_buf,&asn_buf) == 1) // ussd scheme + { + ussd_ptr->param_flag |= 0x01; + ussd_ptr->ussd_scheme = temp_buf[0]; + } + else + return RER; + len = get_tlv("4-2",temp_buf,&asn_buf); // ussd data + if (len > 0 && len <= USSD_LEN) + { + ussd_ptr->param_flag |= 0x02; + ussd_ptr->ussd_string.string_len = len; + memcpy(ussd_ptr->ussd_string.ussd_data,temp_buf,len); + } + else + return RER; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding register SS argument */ +/* ++++++++++++++++++++++++++++++++++++++ */ +int assign_regssarg(struct MapRSS_Arg *rss_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + u32 flag; + int buf_len=0; + u8 tag1; + char tlv1[32]; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + flag = rss_ptr->param_flag; + if(flag & 0x01) // ss-code + buf_len = add_tlv("4-1",1,&rss_ptr->ss_code,0x00,&asn_buf); + else + { + mapp_log_debug("register SS request lack ss code"); + return RER; + } + tag1 = 2; + if(flag & 0x02) // basic service code + { + if (rss_ptr->bs_code.param_flag & 0x01) + { + sprintf(tlv1,"3-%d",tag1++); + temp_len = tele_bittostr(rss_ptr->bs_code.tele_code,temp_buf,1); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x80,&asn_buf); + } + else if (rss_ptr->bs_code.param_flag & 0x02) + { + sprintf(tlv1,"2-%d",tag1++); + temp_len = bearer_bittostr(rss_ptr->bs_code.bearer_code,temp_buf,1); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x80,&asn_buf); + } + } + if (flag & 0x04) // fwdToNum + { + sprintf(tlv1,"4-%d",tag1++); + temp_len = rss_ptr->fwdto_num[0]; + if(temp_len>ISDN_LEN) temp_len = ISDN_LEN; + buf_len = add_tlv(tlv1,temp_len,rss_ptr->fwdto_num+1,0x80,&asn_buf); + } + /** + if((flag & 0x08) != 0x08) // no fwdToSubAdr + mapp_log_debug("register SS request lack fwdToSubAdr"); + else + { + sprintf(tlv1,"6-%d",tag1++); + len = rss_ptr->fwdto_subadd[0]; + buf_len = add_tlv(tlv1,len,rss_ptr->fwdto_subadd+1,0x80,&asn_buf); + } +**/ + if (flag & 0x08) // nrc time + { + sprintf(tlv1,"5-%d",tag1++); + buf_len = add_tlv(tlv1,1,&rss_ptr->norc_time,0x80,&asn_buf); + } + if(flag & 0x10) // default prio + { + sprintf(tlv1,"7-%d",tag1++); + buf_len = add_tlv(tlv1,1,&rss_ptr->default_prio,0x80,&asn_buf); + } + return buf_len; +} + +int extract_regssarg(struct MapRSS_Arg *rss_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u32 flag=0; + u8 temp_buf[256]; + u8 tag1; + char tlv1[32]; + + rss_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1",temp_buf,&asn_buf) == 1) + { + rss_ptr->ss_code = temp_buf[0]; + flag |= 0x01; + } + else + { + mapp_log_debug("extract_regssarg:lack ss_code"); + return RER; + } + tag1 = 2; + if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1) + { + flag |= 0x02; + rss_ptr->bs_code.param_flag = 2; + rss_ptr->bs_code.bearer_code = bearer_strtobit(temp_buf,len); + tag1 ++; + } + if ((len=get_tlv("3",temp_buf,&asn_buf)) != -1) + { + flag |= 0x02; + rss_ptr->bs_code.param_flag = 1; + rss_ptr->bs_code.tele_code =tele_strtobit(temp_buf,len); + tag1 ++; + } + sprintf(tlv1,"4-%d",tag1); + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len >= 1) + { + flag |= 0x04; + if(len>ISDN_LEN) len = ISDN_LEN; + rss_ptr->fwdto_num[0] = len; + memcpy(rss_ptr->fwdto_num+1,temp_buf,len); + } + /** + sprintf(tlv1,"6-%d",tag1); + len=get_tlv(tlv1,temp_buf,&asn_buf); + if (len>=1) + { + tag1++; + mapp_log_debug("extract_regssarg: get fwdToSubAddr"); + rss_ptr->fwdto_subadd[0]=len; + memcpy(rss_ptr->fwdto_subadd+1,temp_buf,len); + flag |= 0x08; + } + **/ + if (get_tlv("5",temp_buf,&asn_buf) == 1) + { + rss_ptr->norc_time = temp_buf[0]; + flag |= 0x08; + } + if (get_tlv("7",temp_buf,&asn_buf) == 1) + { + rss_ptr->default_prio = temp_buf[0]; + flag |= 0x10; + } + rss_ptr->param_flag = flag; + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding register SS response */ +/* ++++++++++++++++++++++++++++++++++++++ */ +int assign_regssres(struct MapRSS_Res *rss_ptr,u8 *buf) +{ + if (rss_ptr->param_flag & 0x01) + return assign_ssinfo(&rss_ptr->ss_info,buf); + else + return 0; +} + +int extract_regssres(struct MapRSS_Res *rss_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + rss_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + return_value = extract_ssinfo(&rss_ptr->ss_info,buf_len,buf); + if (return_value == ROK) + { + rss_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* +++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding erase SS argument */ +/* +++++++++++++++++++++++++++++++++++ */ +int assign_erassarg(struct MapESS_Arg *ess_ptr, u8 *buf) +{ + if (ess_ptr->param_flag & 0x01) + return assign_ssforbscode(&ess_ptr->ss_forbs,buf); + else + return RER; +} + +int extract_erassarg(struct MapESS_Arg *ess_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + ess_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + return_value = extract_ssforbscode(&ess_ptr->ss_forbs,buf_len,buf); + if (return_value == ROK) + { + ess_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* +++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding erase SS response */ +/* +++++++++++++++++++++++++++++++++++ */ +int assign_erassres(MapESS_Res *essr_ptr, u8 *buf) +{ + if (essr_ptr->param_flag & 0x01) + return assign_ssinfo(&essr_ptr->ss_info,buf); + else + return 0; +} + +int extract_erassres(struct MapESS_Res *essr_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + essr_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + return_value = extract_ssinfo(&essr_ptr->ss_info,buf_len,buf); + if (return_value == ROK) + { + essr_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding active SS argument */ +/* ++++++++++++++++++++++++++++++++++++ */ +int assign_actssarg(MapASS_Arg *ass_ptr, u8 *buf) +{ + if (ass_ptr->param_flag & 0x01) + return assign_ssforbscode(&ass_ptr->ss_forbs,buf); + else + return RER; +} + +int extract_actssarg(struct MapASS_Arg *ass_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + ass_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + return_value = extract_ssforbscode(&ass_ptr->ss_forbs,buf_len,buf); + if(return_value == ROK) + { + ass_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding active SS response */ +/* ++++++++++++++++++++++++++++++++++++ */ +int assign_actssres(MapASS_Res *assr_ptr,u8 *buf) +{ + if (assr_ptr->param_flag & 0x01) + return assign_ssinfo(&assr_ptr->ss_info,buf); + else + return 0; +} + +int extract_actssres(struct MapASS_Res *assr_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + assr_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + return_value = extract_ssinfo(&assr_ptr->ss_info,buf_len,buf); + if(return_value == ROK) + { + assr_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding deactive SS argument */ +/* ++++++++++++++++++++++++++++++++++++++ */ +int assign_deactssarg(MapDASS_Arg *dss_ptr,u8 *buf) +{ + if (dss_ptr->param_flag & 0x01) + return assign_ssforbscode(&dss_ptr->ss_forbs,buf); + else + return RER; +} + +int extract_deactssarg(struct MapDASS_Arg *dss_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + dss_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + return_value = extract_ssforbscode(&dss_ptr->ss_forbs,buf_len,buf); + if(return_value == ROK) + { + dss_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding deactive SS response */ +/* ++++++++++++++++++++++++++++++++++++++ */ +int assign_deactssres(MapDASS_Res *dssr_ptr,u8 *buf) +{ + if (dssr_ptr->param_flag & 0x01) + return assign_ssinfo(&dssr_ptr->ss_info,buf); + else + return 0; +} + +int extract_deactssres(struct MapDASS_Res *dssr_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + dssr_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + return_value = extract_ssinfo(&dssr_ptr->ss_info,buf_len,buf); + if(return_value == ROK) + { + dssr_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding interrogate SS argument */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_intrssarg(MapINTSS_Arg *intrss_ptr, u8 *buf) +{ + if (intrss_ptr->param_flag & 0x01) + return assign_ssforbscode(&intrss_ptr->ss_forbs,buf); + else + return RER; +} + +int extract_intrssarg(struct MapINTSS_Arg *intr_ptr,u32 buf_len,u8 *buf) +{ + int return_value; + + intr_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + return_value = extract_ssforbscode(&intr_ptr->ss_forbs,buf_len,buf); + if(return_value == ROK) + { + intr_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding interrogate SS response */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_intrssres(MapINTSS_Res *intrss_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 temp_flag; + int temp_len; + u8 tag1; + char tlv1[32]; + u8 temp_buf[256]; + struct GenSerInfo_struct *gen_ptr; + + asn_encode(buf, &asn_buf); + if ((intrss_ptr->param_flag & 0x01) != 0x01) // no result + { + mapp_log_debug("assign_intrssres: lack ss status"); + return RER; + } + temp_flag = intrss_ptr->result.choice_flag; + if (temp_flag == 1) //ss status + buf_len = add_tlv("0",1,&intrss_ptr->result.choice.ss_status,0x80,&asn_buf); + else if (temp_flag == 2) //basic service group list + { + temp_len = assign_bscode(&intrss_ptr->result.choice.bs_code,temp_buf,1); + buf_len = add_tlv("2",temp_len,temp_buf,0x0a0,&asn_buf); + } + else if (temp_flag == 3) // fwd feature list + { + temp_len = assign_fwdfeat(&intrss_ptr->result.choice.fwd_feat,temp_buf); + buf_len = add_tlv("3",temp_len,temp_buf,0x0a0,&asn_buf); + } + else if (temp_flag == 4) // genser_info + { + gen_ptr = (GenSerInfo_struct *) &intrss_ptr->result.choice.genser_info; + if (gen_ptr->param_flag & 0x01) // ss status + buf_len = add_tlv("4.4",1,&gen_ptr->ss_status,0x00,&asn_buf); + tag1 = 2; + if (gen_ptr->param_flag & 0x02) // clires opt + { + temp_buf[0] = gen_ptr->clires_opt; + sprintf(tlv1,"4.10-%d",tag1++); + buf_len = add_tlv(tlv1,1,temp_buf,0x00,&asn_buf); + } + if (gen_ptr->param_flag & 0x04) // max entitled priority + { + sprintf(tlv1,"4.0-%d",tag1++); + buf_len = add_tlv(tlv1,1,&gen_ptr->maxent_prio,0x00,&asn_buf); + } + if (gen_ptr->param_flag & 0x08) // default priority + { + sprintf(tlv1,"4.1-%d",tag1++); + buf_len = add_tlv(tlv1,1,&gen_ptr->default_prio,0x00,&asn_buf); + } + // empty the ccbs feature list + } + else + return RER; + return buf_len; +} + +int extract_intrssres(struct MapINTSS_Res *intrss_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + int choice_flag=0; + + intrss_ptr->param_flag = 0; + intrss_ptr->result.choice_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) == 1) + { + intrss_ptr->result.choice.ss_status = temp_buf[0]; + choice_flag = 1; + } + if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1) // basic service + { + if (!extract_bscode(&intrss_ptr->result.choice.bs_code,len,temp_buf)) + return RER; + choice_flag = 2; + } + len = get_tlv("3",temp_buf,&asn_buf); //forwardingFeatureList + if (len > 0)//forwardingFeatureList + { + choice_flag = 3; + if (!extract_fwdfeat(&intrss_ptr->result.choice.fwd_feat,len,temp_buf)) + return RER; + } + if (get_tlv("4",temp_buf,&asn_buf)>0) // generic service info + { + choice_flag = 4; + intrss_ptr->result.choice.genser_info.param_flag = 0; + if (get_tlv("4.4",temp_buf,&asn_buf) == 1) // ss status + { + intrss_ptr->result.choice.genser_info.ss_status = temp_buf[0]; + intrss_ptr->result.choice.genser_info.param_flag |= 0x01; // ss status + } + if (get_tlv("4.10",temp_buf,&asn_buf) == 1) // cli restriction option + { + intrss_ptr->result.choice.genser_info.clires_opt = temp_buf[0]; + intrss_ptr->result.choice.genser_info.param_flag |= 0x02; // cilres opt + } + if (get_tlv("4.0",temp_buf,&asn_buf) == 1) // max entitled priority + { + intrss_ptr->result.choice.genser_info.maxent_prio = temp_buf[0]; + intrss_ptr->result.choice.genser_info.param_flag |= 0x04; + } + if (get_tlv("4.1",temp_buf,&asn_buf) == 1) // default priority + { + intrss_ptr->result.choice.genser_info.default_prio = temp_buf[0]; + intrss_ptr->result.choice.genser_info.param_flag |= 0x08; + } + } + if (choice_flag > 0) + { + intrss_ptr->result.choice_flag = choice_flag; + intrss_ptr->param_flag = 0x01; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding process unstructured SS request argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prcunssreqarg(struct MapPUSSR_Arg *psr_ptr,u8 *buf) +{ + if (psr_ptr->param_flag & 0x01) + return assign_ussdarg(&psr_ptr->ussd_arg,buf); + else + return RER; +} + +int extract_prcunssreqarg(struct MapPUSSR_Arg *psr_ptr,u32 buf_len,u8 *buf) +{ + if (extract_ussdarg(&psr_ptr->ussd_arg,buf_len,buf)) + { + psr_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding process unstructured SS request response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_prcunssreqres(struct MapPUSSR_Res *psr_ptr,u8 *buf) +{ + if (psr_ptr->param_flag & 0x01) + return assign_ussdres(&psr_ptr->ussd_res,buf); + else + return RER; +} + +int extract_prcunssreqres(struct MapPUSSR_Res *psr_ptr,u32 buf_len,u8 *buf) +{ + if (extract_ussdres(&psr_ptr->ussd_res,buf_len,buf)) + { + psr_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding unstructured ss request argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_unssreqarg(struct MapUSSR_Arg *usr_ptr,u8 *buf) +{ + if (usr_ptr->param_flag & 0x01) + return assign_ussdarg(&usr_ptr->ussd_arg,buf); + else + return RER; +} + +int extract_unssreqarg(struct MapUSSR_Arg *usr_ptr,u32 buf_len,u8 *buf) +{ + if (extract_ussdarg(&usr_ptr->ussd_arg,buf_len,buf)) + { + usr_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding unstructured SS request response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_unssreqres(struct MapUSSR_Res *usr_ptr,u8 *buf) +{ + if (usr_ptr->param_flag & 0x01) + return assign_ussdres(&usr_ptr->ussd_res,buf); + else + return 0; +} + +int extract_unssreqres(struct MapUSSR_Res *usr_ptr,u32 buf_len,u8 *buf) +{ + if (buf_len == 0) + return ROK; + if (extract_ussdres(&usr_ptr->ussd_res,buf_len,buf)) + { + usr_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding unstructured ss notify argument */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_unssnotarg(struct MapUSSN_Arg *usn_ptr,u8 *buf) +{ + if (usn_ptr->param_flag & 0x01) + return assign_ussdarg(&usn_ptr->ussd_arg,buf); + else + return RER; +} + +int extract_unssnotarg(struct MapUSSN_Arg *usn_ptr,u32 buf_len,u8 *buf) +{ + if (extract_ussdarg(&usn_ptr->ussd_arg,buf_len,buf)) + { + usn_ptr->param_flag = 0x01; + return ROK; + } + else + return RER; +} + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding unstructured ss notify response */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_unssnotres(struct MapUSSN_Res *usn_ptr,u8 *buf) +{ + return 0; +} + +int extract_unssnotres(struct MapUSSN_Res *usn_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding register Password argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_regpswdarg(struct MapRPSS_Arg *rpw_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (rpw_ptr->param_flag & 0x01) + { + buf_len = add_tlv("4",1,&rpw_ptr->ss_code,0x00,&asn_buf); + return buf_len; + } + else + return RER; +} + +int extract_regpswdarg(struct MapRPSS_Arg *rpw_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + rpw_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return 0; + if (get_tlv("4",temp_buf,&asn_buf) == 1) + { + rpw_ptr->ss_code = temp_buf[0]; + rpw_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding register Password response */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_regpswdres(struct MapRPSS_Res *rpwr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (rpwr_ptr->param_flag & 0x01) + { + buf_len = add_tlv("18",PASSWD_LEN,rpwr_ptr->passwd,0x00,&asn_buf); + return buf_len; + } + else + return RER; +} + +int extract_regpswdres(struct MapRPSS_Res *rpwr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + rpwr_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return 0; + if (get_tlv("18",temp_buf,&asn_buf) == PASSWD_LEN) + { + memcpy(rpwr_ptr->passwd,temp_buf,PASSWD_LEN); + rpwr_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* +++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding get Password argument */ +/* +++++++++++++++++++++++++++++++++++++++ */ +int assign_getpswdarg(struct MapGPSS_Arg *gpw_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u_char temp_buf[32]; + + asn_encode(buf,&asn_buf); + if (gpw_ptr->param_flag & 0x01) // has not + { + temp_buf[0] = gpw_ptr->gui_info; + buf_len = add_tlv("10",1,temp_buf,0x00,&asn_buf); + return buf_len; + } + else + return RER; +} + +int extract_getpswdarg(struct MapGPSS_Arg *gpw_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + gpw_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("10",temp_buf,&asn_buf) > 0) + { + gpw_ptr->gui_info = temp_buf[0]; + gpw_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* +++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding get Password response */ +/* +++++++++++++++++++++++++++++++++++++++ */ +int assign_getpswdres(struct MapGPSS_Res *rpwr_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (rpwr_ptr->param_flag & 0x01) + { + buf_len = add_tlv("18",PASSWD_LEN,rpwr_ptr->passwd,0x00,&asn_buf); + return buf_len; + } + else + return RER; +} + +int extract_getpswdres(struct MapGPSS_Res *rpwr_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + rpwr_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("18",temp_buf,&asn_buf) == PASSWD_LEN) + { + memcpy(rpwr_ptr->passwd,temp_buf,PASSWD_LEN); + rpwr_ptr->param_flag |= 0x01; + return ROK; + } + return RER; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding SS invocation notification argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_ssinvnotarg(struct MapSSIN_Arg *sin_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 ii; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (sin_ptr->param_flag & 0x01) // imsi + buf_len = add_tlv("0",IMSI_LEN,sin_ptr->imsi,0x80,&asn_buf); + else + return RER; + if (sin_ptr->param_flag & 0x02) // msisdn + buf_len = add_tlv("1",sin_ptr->msisdn[0],sin_ptr->msisdn+1,0x80,&asn_buf); + else + return RER; + if (sin_ptr->param_flag & 0x04) // ss event + buf_len = add_tlv("2",1,&sin_ptr->ss_event,0x80,&asn_buf); + else + return RER; + if (sin_ptr->param_flag & 0x08) // ss event specification + { + if (sin_ptr->event.event_len > EVENT_LEN) + return RER; + for (ii = 0;ii < sin_ptr->event.event_len;ii ++) + { + sprintf(tlv1,"3.4-%d",ii+1); + buf_len = add_tlv(tlv1,sin_ptr->event.event_spe[ii][0],sin_ptr->event.event_spe[ii]+1,0x00,&asn_buf); + } + } + return buf_len; +} + +int extract_ssinvnotarg(struct MapSSIN_Arg *sin_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u8 ii; + char tlv1[32]; + + sin_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_ss invocation notification buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0) //get imsi + { + sin_ptr->param_flag |= 0x01; + memcpy(sin_ptr->imsi,temp_buf,IMSI_LEN); + } + else + return RER; + len = get_tlv("1",temp_buf,&asn_buf); // get msisdn + if (len > 0 && len <= ISDN_LEN) + { + sin_ptr->param_flag |= 0x02; + sin_ptr->msisdn[0] = len; + memcpy(sin_ptr->msisdn+1,temp_buf,len); + } + else + return RER; + if (get_tlv("2",temp_buf,&asn_buf) == 1) // ss event + { + sin_ptr->param_flag |= 0x04; + sin_ptr->ss_event = temp_buf[0]; + } + else + return RER; + if (get_tlv("3",temp_buf,&asn_buf) != -1) // ss event specification + { + for (ii = 0;ii < EVENT_LEN;ii ++) + { + sprintf(tlv1,"3.4-%d",ii+1); + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len > 0 && len <= ISDN_LEN) + { + sin_ptr->param_flag |= 0x08; + sin_ptr->event.event_spe[ii][0] = len; + memcpy(sin_ptr->event.event_spe[ii]+1,temp_buf,len); + } + else + { + sin_ptr->event.event_len = ii; + break; + } + } + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding SS invocation notification response */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_ssinvnotres(struct MapSSIN_Res *sin_ptr,u8 *buf) +{ + return 0; +} + +int extract_ssinvnotres(struct MapSSIN_Res *sin_ptr,u32 buf_len,u8 *buf) +{ + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding register CC entity argument */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_regccentarg(struct MapRCCE_Arg *rce_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256],temp_data[256]; + + asn_encode(buf,&asn_buf); + if (rce_ptr->param_flag & 0x01) // ss code + buf_len = add_tlv("0",1,&rce_ptr->ss_code,0x80,&asn_buf); + else + return RER; + if (rce_ptr->param_flag & 0x02) // CCBS data + { + if (rce_ptr->ccbs_data.param_flag & 0x01) // ccbs feature + { + temp_len = assign_ccbsfeat(&rce_ptr->ccbs_data.ccbs_feat,temp_buf); + buf_len = add_tlv("1.0",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + if (rce_ptr->ccbs_data.param_flag & 0x02) // translated B-number + { + temp_len = rce_ptr->ccbs_data.trans_num[0]; + buf_len = add_tlv("1.1",temp_len,rce_ptr->ccbs_data.trans_num+1,0x80,&asn_buf); + } + else + return RER; + if (rce_ptr->ccbs_data.param_flag & 0x04) // service indicator + { + temp_data[0] = rce_ptr->ccbs_data.ser_ind; + temp_len = bytestrtobitstr(temp_buf,temp_data,2); + buf_len = add_tlv("1.2",temp_len,temp_buf,0x80,&asn_buf); + } + if (rce_ptr->ccbs_data.param_flag & 0x08) // call info + { + temp_len = assign_extsiginfo(&rce_ptr->ccbs_data.call_info,temp_buf); + buf_len = add_tlv("1.3",temp_len,temp_buf,0x80,&asn_buf); + } + else + return RER; + if (rce_ptr->ccbs_data.param_flag & 0x10) // network signal info + { + temp_len = assign_extsiginfo(&rce_ptr->ccbs_data.net_info,temp_buf); + buf_len = add_tlv("1.4",temp_len,temp_buf,0x0a0,&asn_buf); + } + else + return RER; + } + return buf_len; +} + +int extract_regccentarg(struct MapRCCE_Arg *rce_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + int temp_len; + u8 temp_buf[256],temp_data[256]; + + rce_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_register CC entity buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) == 1) // ss code + { + rce_ptr->param_flag |= 0x01; + rce_ptr->ss_code = temp_buf[0]; + } + else + return RER; + if (get_tlv("1",temp_buf,&asn_buf) != -1) // ccbs data + { + rce_ptr->param_flag |= 0x02; + len = get_tlv("1.0",temp_buf,&asn_buf); + if (len != -1) + { + if (!extract_ccbsfeat(&rce_ptr->ccbs_data.ccbs_feat,len,temp_buf)) + return RER; + rce_ptr->ccbs_data.param_flag |= 0x01; + } + else + return RER; + len = get_tlv("1.1",temp_buf,&asn_buf); // translate B-number + if (len > 0 && len <= ISDN_LEN) + { + rce_ptr->ccbs_data.param_flag |= 0x02; + rce_ptr->ccbs_data.trans_num[0] = len; + memcpy(rce_ptr->ccbs_data.trans_num+1,temp_buf,len); + } + else + return RER; + len = get_tlv("1.2",temp_buf,&asn_buf); // service indicator + if (len != -1) + { + rce_ptr->ccbs_data.param_flag |= 0x04; + temp_len = bitstrtobytestr(temp_data,temp_buf,len); + rce_ptr->ccbs_data.ser_ind = bcdtou32(temp_data,temp_len); + } + len = get_tlv("1.3",temp_buf,&asn_buf); + if (len != -1) + { + if (extract_extsiginfo(&rce_ptr->ccbs_data.call_info,len,temp_buf) != RER) + rce_ptr->ccbs_data.param_flag |= 0x08; + } + else + return RER; + len = get_tlv("1.4",temp_buf,&asn_buf); + if (len != -1) + { + if (extract_extsiginfo(&rce_ptr->ccbs_data.net_info,len,temp_buf) != RER) + rce_ptr->ccbs_data.param_flag |= 0x10; + } + else + return RER; + } + return ROK; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding register CC entity response */ +/* +++++++++++++++++++++++++++++++++++++++++++++ */ +int assign_regccentres(struct MapRCCE_Res *rce_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + + asn_encode(buf,&asn_buf); + if (rce_ptr->param_flag & 0x01) // ccbs feature + { + temp_len = assign_ccbsfeat(&rce_ptr->ccbs_feat,temp_buf); + buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf); + } + return buf_len; +} + +int extract_regccentres(struct MapRCCE_Res *rce_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + rce_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + len = get_tlv("0",temp_buf,&asn_buf); + if (len != -1) + { + if (!extract_ccbsfeat(&rce_ptr->ccbs_feat,len,temp_buf)) + return RER; + rce_ptr->param_flag |= 0x01; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding erase CC entity argument */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_eraseccentarg(struct MapECCE_Arg *ece_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ece_ptr->param_flag & 0x01) // ss code + buf_len = add_tlv("0",1,&ece_ptr->ss_code,0x80,&asn_buf); + else + return RER; + if (ece_ptr->param_flag & 0x02) // ccbs index + buf_len = add_tlv("1",1,&ece_ptr->ccbs_index,0x80,&asn_buf); + return buf_len; +} + +int extract_eraseccentarg(struct MapECCE_Arg *ece_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + ece_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_erase CC entity buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) == 1) // ss code + { + ece_ptr->param_flag |= 0x01; + ece_ptr->ss_code = temp_buf[0]; + } + else + return RER; + if (get_tlv("1",temp_buf,&asn_buf) == 1) // ccbs index + { + ece_ptr->param_flag |= 0x02; + ece_ptr->ccbs_index = temp_buf[0]; + } + return ROK; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* encoding/decoding erase CC entity response */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_eraseccentres(struct MapECCE_Res *ece_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (ece_ptr->param_flag & 0x01) // ss code + buf_len = add_tlv("0",1,&ece_ptr->ss_code,0x80,&asn_buf); + else + return RER; + if (ece_ptr->param_flag & 0x02) // ss status + buf_len = add_tlv("1",1,&ece_ptr->ss_status,0x80,&asn_buf); + return buf_len; +} + +int extract_eraseccentres(struct MapECCE_Res *ece_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + ece_ptr->param_flag = 0; + if (buf_len == 0) + { + mapp_log_debug("MAPP--extract_erase CC entity buf_len=0"); + return RER; + } + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) == 1) // ss code + { + ece_ptr->param_flag |= 0x01; + ece_ptr->ss_code = temp_buf[0]; + } + else + return RER; + if (get_tlv("1",temp_buf,&asn_buf) == 1) // ss status + { + ece_ptr->param_flag |= 0x02; + ece_ptr->ss_status = temp_buf[0]; + } + return ROK; +} diff --git a/plat/xapp/src/mapp/map_coding.c b/plat/xapp/src/mapp/map_coding.c new file mode 100644 index 0000000..d38efec --- /dev/null +++ b/plat/xapp/src/mapp/map_coding.c @@ -0,0 +1,2345 @@ +/* MAP Update Location c file */ +/* written by Liu zhiguo 2003-03-04 */ +/* version 2.0 */ +/* -------------------------------- */ + +#include "map_includes.h" +#include "../xap_interfunc.h" +#include "map_code.h" +#include "map_opr_func.h" + +int build_mapparam(struct MapOprSrv_struct *opr_ptr,u8 *buf) // build map service paramter +{ + ASN_BUF asn_buf; + u8 seq_flag=1; + int param_len = 0; + u8 info_str[1024]; + + if (opr_ptr == NULL || buf == NULL) + return RER; + switch (opr_ptr->message_type) + { +/* MAP V1--lw add */ +/* daniel */ + /* + case SendParam://sendParameters + if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_sendParameterres(&opr_ptr->msg_list.sp_res,buf); + break; + */ +/* daniel */ + case SendParam :// send parameters + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 0; + param_len = assign_SendParaArg(&opr_ptr->msg_list.sp_arg,buf); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 0; + param_len = assign_SendParaRes(&opr_ptr->msg_list.sp_res,buf); + } + break; + case NoteSubPrnt :// not subscriber present + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 0; + param_len = assign_NotPresentArg(&opr_ptr->msg_list.np_arg,buf); + } + break; + case ProcUnstrctSSData:// process unstructure SS data + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 0; + param_len = assign_ProcessUSSDArg(&opr_ptr->msg_list.pussd_arg,buf); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 0; + param_len = assign_ProcessUSSDRes(&opr_ptr->msg_list.pussd_res,buf); + } + break; + case BeginSubAct:// beging subscriber activity + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 1; + param_len = assign_BSAArg(&opr_ptr->msg_list.bsa_arg,buf); + } + break; + case PerformHo :// perform handover + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 1; + param_len = assign_HOArg(&opr_ptr->msg_list.ho_arg,buf); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 1; + param_len = assign_HORes(&opr_ptr->msg_list.ho_res,buf); + } + break; + case PerformSubsHo: + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag =1; + param_len = assign_PFSHOArg(&opr_ptr->msg_list.pfsho_arg,buf); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 1; + param_len = assign_PFSHORes(&opr_ptr->msg_list.pfsho_res,buf); + } + break; + case NoteInterHo: + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 1; + param_len = assign_NIHOArg(&opr_ptr->msg_list.niho_arg,buf); + } + break; + case TraceSubAct: + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 1; + param_len = assign_TSAArg(&opr_ptr->msg_list.tsa_arg,buf); + } + break; + case AlrtSCWithoutRes: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_altsrvcentarg(&opr_ptr->msg_list.asc_arg,buf); + break; + /* + case BeginSubAct: + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 1; + return assign_BSAArg(&opr_ptr->msg_list.bsa_arg,buf); + } + break; + */ + case FwdSM : + //case MOFwdSM : + //case MTFwdSM : + /* + if( opr_ptr->version == 1) + { + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 1; + param_len = assign_fwdsmarg(&opr_ptr->msg_list.fsm_arg,buf); + } + } + else + */ + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_mofwdsmarg(&opr_ptr->msg_list.mofsm_arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + param_len = assign_mofwdsmres(&opr_ptr->msg_list.mofsm_res,buf,opr_ptr->version); + if(opr_ptr->version<3) + seq_flag = 0; + } + break; + case MTFwdSM_v3: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_mtfwdsmarg(&opr_ptr->msg_list.mtfsm_arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + param_len = assign_mtfwdsmres(&opr_ptr->msg_list.mtfsm_res,buf,opr_ptr->version); + if(param_len <=0) + { + seq_flag = 0; + /* older version mo fwd doesn't take any parameter */ + } + } + break; +/* MAP V1--lw add */ + // mobile service operation + case UpLoc: + if (opr_ptr->message_flag == MAP_REQUEST) + { + param_len = assign_uplocarg(&opr_ptr->msg_list.ul_arg,buf,opr_ptr->version); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + param_len = assign_uplocres(&opr_ptr->msg_list.ul_res,buf); + } + break; + case CancelLoc: + if (opr_ptr->message_flag == MAP_REQUEST) + { + param_len = assign_cancellocarg(&opr_ptr->msg_list.cl_arg,buf,opr_ptr->version); + if(opr_ptr->version != 3) + seq_flag = 0; + else + seq_flag = 2; + } + else if (opr_ptr->message_flag == MAP_RESPONSE && opr_ptr->version == 3) + param_len = assign_cancellocres(&opr_ptr->msg_list.cl_res,buf); + break; + case PurgeMS: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_purgemsarg(&opr_ptr->msg_list.pms_arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_purgemsres(&opr_ptr->msg_list.pms_res,buf); + break; + case SndIdent: + if (opr_ptr->message_flag == MAP_REQUEST) + { + seq_flag = 0; + param_len = assign_sndidentarg(&opr_ptr->msg_list.si_arg,buf); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_sndidentres(&opr_ptr->msg_list.si_res,buf); + break; + case UpGprsLoc: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_upgprslocarg(&opr_ptr->msg_list.ugl_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_upgprslocres(&opr_ptr->msg_list.ugl_res,buf); + break; + case ProvSubInfo: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_prvsubinfoarg(&opr_ptr->msg_list.psi_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_prvsubinfores(&opr_ptr->msg_list.psi_res,buf); + break; + case AnyTimeInter: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_anytimeintarg(&opr_ptr->msg_list.ati_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_anytimeintres(&opr_ptr->msg_list.ati_res,buf); + break; + case AnyTimeSubInter: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_anytimesubintarg(&opr_ptr->msg_list.atsi_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_anytimesubintres(&opr_ptr->msg_list.atsi_res,buf); + break; + case PreHo: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_prehoarg(&opr_ptr->msg_list.pho_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_prehores(&opr_ptr->msg_list.pho_res,buf); + break; + case SndEndSig: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_sndendsigarg(&opr_ptr->msg_list.ses_arg,buf); + break; + case ProcAccSig: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_prcaccsigarg(&opr_ptr->msg_list.pas_arg,buf); + break; + case FwdAccSig: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_fwdaccsigarg(&opr_ptr->msg_list.fas_arg,buf); + break; + case PreSubsHo: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_presubshoarg(&opr_ptr->msg_list.psho_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_presubshores(&opr_ptr->msg_list.psho_res,buf); + break; + case SndAuthInfo: //modify by gxchen + if (opr_ptr->message_flag == MAP_REQUEST) + { + if(opr_ptr->version < 3) + seq_flag = 0; + param_len = assign_sndauthinfoarg(&opr_ptr->msg_list.sai_arg,buf,opr_ptr->version); + } + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + param_len = assign_sndauthinfores(&opr_ptr->msg_list.sai_res,buf,opr_ptr->version); + if(opr_ptr->version == 3) + seq_flag = 2; + } + break; + case AuthFailReport: //add by gxchen + if(opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_authfailreportarg(&opr_ptr->msg_list.authfr_arg, buf); +// else if(opr_ptr->message_flag == MAP_RESPONSE) +// param_len = assign_authfailreportres(&opr_ptr->msg_list.authfr_res, buf); + break; + case ChkIMEI: + seq_flag = 0; + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_chkimeiarg(&opr_ptr->msg_list.cimei_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_chkimeires(&opr_ptr->msg_list.cimei_res,buf); + break; + case InsSubData: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_inssubdataarg(&opr_ptr->msg_list.isd_arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_inssubdatares(&opr_ptr->msg_list.isd_res,buf); + break; + case DelSubData: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_delsubdataarg(&opr_ptr->msg_list.dsd_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_delsubdatares(&opr_ptr->msg_list.dsd_res,buf); + break; + case Reset: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_resetarg(&opr_ptr->msg_list.reset_arg,buf); + break; + case RestoreData: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_restdataarg(&opr_ptr->msg_list.rd_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_restdatares(&opr_ptr->msg_list.rd_res,buf); + break; + case SndRoutInfoForGprs: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_sndroutinfogprsarg(&opr_ptr->msg_list.srifg_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_sndroutinfogprsres(&opr_ptr->msg_list.srifg_res,buf); + break; + case FailRep: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_failreportarg(&opr_ptr->msg_list.fr_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_failreportres(&opr_ptr->msg_list.fr_res,buf); + break; + case NoteMsPresForGprs: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_notemspregprsarg(&opr_ptr->msg_list.nmpfg_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_notemspregprsres(&opr_ptr->msg_list.nmpfg_res,buf); + break; + // operation and maintenance operations + case ActvTraceMode: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_acttrcmodearg(&opr_ptr->msg_list.atm_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_acttrcmoderes(&opr_ptr->msg_list.atm_res,buf); + break; + case DeactvTraceMode: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_deacttrcmodearg(&opr_ptr->msg_list.dtm_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_deacttrcmoderes(&opr_ptr->msg_list.dtm_res,buf); + break; + case SndIMSI: + seq_flag = 0; + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_sndimsiarg(&opr_ptr->msg_list.simsi_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_sndimsires(&opr_ptr->msg_list.simsi_res,buf); + break; + // call handling operation + case SndRoutInfo: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_sndroutinfoarg(&opr_ptr->msg_list.sri_arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + param_len = assign_sndroutinfores(&opr_ptr->msg_list.sri_res,buf,opr_ptr->version); + if(opr_ptr->version == 3) + seq_flag = 2; + } + break; + case ProvRoamNum: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_provroamnumarg(&opr_ptr->msg_list.prn_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_provroamnumres(&opr_ptr->msg_list.prn_res,buf); + break; + case ResumeCH: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_rescallhandarg(&opr_ptr->msg_list.rch_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_rescallhandres(&opr_ptr->msg_list.rch_res,buf); + break; + case ProvSIWFSNum: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_prvsiwfsnumarg(&opr_ptr->msg_list.psn_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_prvsiwfsnumres(&opr_ptr->msg_list.psn_res,buf); + break; + case SIWFSSigMdf: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_siwfssigmodarg(&opr_ptr->msg_list.ssm_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_siwfssigmodres(&opr_ptr->msg_list.ssm_res,buf); + break; + case SetRepState: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_setrepstatearg(&opr_ptr->msg_list.srs_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_setrepstateres(&opr_ptr->msg_list.srs_res,buf); + break; + case StatusRep: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_statreparg(&opr_ptr->msg_list.sr_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_statrepres(&opr_ptr->msg_list.sr_res,buf); + break; + case RmtUserFree: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_rmtuserfreearg(&opr_ptr->msg_list.ruf_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_rmtuserfreeres(&opr_ptr->msg_list.ruf_res,buf); + break; + case IstAlert: //ist-Alert umts add by gxchen + if(opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_istalertarg(&opr_ptr->msg_list.istalt_arg, buf); + else if(opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_istalertres(&opr_ptr->msg_list.istalt_res, buf); + break; + case IstCommand: //ist-Command umts add by gxchen + if(opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_istcmdarg(&opr_ptr->msg_list.istcmd_arg, buf); +// else if(opr_ptr->message_flag == MAP_RESPONSE) +// param_len = assign_istcmdres(&opr_ptr->msg_list.istcmd_res, buf); + break; + // supplementary service operation + case RegSS: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_regssarg(&opr_ptr->msg_list.rss_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 0; + param_len = assign_regssres(&opr_ptr->msg_list.rss_res,buf); + } + break; + case EraseSS: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_erassarg(&opr_ptr->msg_list.ess_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 0; + param_len = assign_erassres(&opr_ptr->msg_list.ess_res,buf); + } + break; + case ActvSS: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_actssarg(&opr_ptr->msg_list.ass_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 0; + param_len = assign_actssres(&opr_ptr->msg_list.ass_res,buf); + } + break; + case DeactvSS: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_deactssarg(&opr_ptr->msg_list.dass_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag=0; + param_len = assign_deactssres(&opr_ptr->msg_list.dass_res,buf); + } + break; + case InterSS: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_intrssarg(&opr_ptr->msg_list.intss_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + seq_flag = 0; + param_len = assign_intrssres(&opr_ptr->msg_list.intss_res,buf); + } + break; + case ProcUnstrctSSReq: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_prcunssreqarg(&opr_ptr->msg_list.pussr_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_prcunssreqres(&opr_ptr->msg_list.pussr_res,buf); + break; + case UnstrctSSReq: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_unssreqarg(&opr_ptr->msg_list.ussr_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_unssreqres(&opr_ptr->msg_list.ussr_res,buf); + break; + case UnstrctSSNoti: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_unssnotarg(&opr_ptr->msg_list.ussn_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + { + param_len = assign_unssnotres(&opr_ptr->msg_list.ussn_res,buf); + seq_flag=0; + } + break; + case RegPasswd: + seq_flag=0; + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_regpswdarg(&opr_ptr->msg_list.rpss_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_regpswdres(&opr_ptr->msg_list.rpss_res,buf); + break; + case GetPasswd: + seq_flag=0; + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_getpswdarg(&opr_ptr->msg_list.gpss_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_getpswdres(&opr_ptr->msg_list.gpss_res,buf); + break; + case SSInvNoti: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_ssinvnotarg(&opr_ptr->msg_list.ssin_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_ssinvnotres(&opr_ptr->msg_list.ssin_res,buf); + break; + case RegCCEntry: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_regccentarg(&opr_ptr->msg_list.rcce_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_regccentres(&opr_ptr->msg_list.rcce_res,buf); + break; + case EraseCCEntry: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_eraseccentarg(&opr_ptr->msg_list.ecce_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_eraseccentres(&opr_ptr->msg_list.ecce_res,buf); + break; + // short message service operation + case SndRoutInfoForSM: + if( opr_ptr->version == 1 ) + { + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_routinfoforsm_v1_arg(&opr_ptr->msg_list.rifsm_v1_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_routinfoforsm_v1_res(&opr_ptr->msg_list.rifsm_v1_res,buf); + } + else + { + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_routinfoforsmarg(&opr_ptr->msg_list.rifsm_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_routinfoforsmres(&opr_ptr->msg_list.rifsm_res,buf); + } + break; + case RptSMDelvStat: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_repsmdelstatarg(&opr_ptr->msg_list.rsmds_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_repsmdelstatres(&opr_ptr->msg_list.rsmds_res,buf); + break; + case AlrtSC: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_altsrvcentarg(&opr_ptr->msg_list.asc_arg,buf); + break; + case InfSC: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_infsrvcentarg(&opr_ptr->msg_list.isc_arg,buf); + break; + case RdyForSM: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_rdyforsmarg(&opr_ptr->msg_list.rfsm_arg,buf); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_rdyforsmres(&opr_ptr->msg_list.rfsm_res,buf); + break; + /*MAP-H (AUC and HLR) */ + case SecuTrip: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_securityTriplets_arg(&opr_ptr->msg_list.st_arg,buf, opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_securityTriplets_res(&opr_ptr->msg_list.st_res,buf); + break; + case InterrSubs: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_interrogateSubscriber_arg(&opr_ptr->msg_list.is_arg,buf); + break; + case CreateSubs: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_createSubscriber_arg(&opr_ptr->msg_list.cs_arg,buf); + break; + case DelSubs: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_deleteSubscriber_arg(&opr_ptr->msg_list.ds_arg,buf); + break; + /********** map opr **********/ + case DetermineOprUser: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_MapDetermineOprUserArg(&opr_ptr->msg_list.DetermineOprUser_Arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_MapDetermineOprUserRes(&opr_ptr->msg_list.DetermineOprUser_Res,buf,opr_ptr->version); + break; + case VlrUpdateLocation: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_MapVlrUpdateLocationArg(&opr_ptr->msg_list.VlrUpdateLocation_Arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_MapVlrUpdateLocationRes(&opr_ptr->msg_list.VlrUpdateLocation_Res,buf,opr_ptr->version); + break; + case CreateUserWithMsisdnImsi: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_MapCreateUserWithMsisdnImsiArg(&opr_ptr->msg_list.CreateUserWithMsisdnImsi_Arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_MapCreateUserWithMsisdnImsiRes(&opr_ptr->msg_list.CreateUserWithMsisdnImsi_Res,buf,opr_ptr->version); + break; + case DeleteOprUser: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_MapDeleteOprUserArg(&opr_ptr->msg_list.DeleteOprUser_Arg,buf,opr_ptr->version); + else if (opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_MapDeleteOprUserRes(&opr_ptr->msg_list.DeleteOprUser_Res,buf,opr_ptr->version); + break; + case VlrEnquiryIMDMStatus: + if (opr_ptr->message_flag == MAP_REQUEST) + param_len = assign_MapVlrEnquiryIMDM_Arg(&opr_ptr->msg_list.EnquiryIMDM_Arg,buf,opr_ptr->version); + else if(opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_MapVlrEnquiryIMDM_Res(&opr_ptr->msg_list.EnquiryIMDM_Res,buf,opr_ptr->version); + break; + case RoutingInfoForLCS: + if (opr_ptr->message_flag == MAP_REQUEST) + { + xap_send_error("RoutingInfoForLCS Arg is not support to assign"); + return RER; + } + else if(opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_RoutingInfoForLCS_Res(&opr_ptr->msg_list.routingInfoForLCS_Res,buf,opr_ptr->version); + break; + case ProvideSubscriberLocation: + if (opr_ptr->message_flag == MAP_REQUEST) + { + xap_send_error("ProvideSubscriberLocation Arg is not support to assign"); + return RER; + } + else if(opr_ptr->message_flag == MAP_RESPONSE) + param_len = assign_ProvideSubscriberLocation_Res(&opr_ptr->msg_list.provideSubscriberLocation_Res,buf,opr_ptr->version); + break; + /********* map opr **********/ + default: // unknown operation + xap_send_error("MAPP error:the operation is unknown:%d",opr_ptr->message_type); + return RER; + } + +// if(param_len <= 0) + if(param_len < 0) + return 0; + + switch(seq_flag) + { + case 0: + break; + case 1: + memcpy(info_str,buf,param_len%1024); + asn_encode(buf,&asn_buf); + param_len = add_tlv("16",param_len,info_str,0x20,&asn_buf); + break; + case 2: + memcpy(info_str,buf,param_len%1024); + asn_encode(buf,&asn_buf); + param_len = add_tlv("3",param_len,info_str,0xA0,&asn_buf); + break; + } + //Bcd2Str_Space(info_str, buf, param_len); + //printf("\r\nassign code :[%d] len :[%d]\r\n%s\r\n",opr_ptr->message_type,param_len,info_str); + return param_len; +} + +u8 extract_mapparam(struct MapOprSrv_struct *opr_ptr,u8 opr_code,u8 opr_flag,u32 pre_param_len,u8 *pre_param) +{ + ASN_BUF asn_buf; + u8 param[1024]; + int param_len; + //char info_str[1024]; + + asn_decode(pre_param,1,&asn_buf); + //Bcd2Str_Space(info_str, pre_param, pre_param_len); + //printf("\r\nextract code :[%d] len :[%ld]\r\n%s\r\n",opr_code,pre_param_len,info_str); + if(opr_ptr->version == 3 && ( + (opr_code == SndRoutInfo && opr_flag == MAP_CONFIRM) || + (opr_code == SndAuthInfo && opr_flag == MAP_CONFIRM) || + (opr_code == CancelLoc && opr_flag == MAP_INDICATE) || + (opr_code == PurgeMS && opr_flag == MAP_INDICATE))) + { + param_len = get_tlv("3",param,&asn_buf); + } + else if( !( opr_code == SendParam && opr_flag == MAP_CONFIRM )) + { + param_len = get_tlv("16",param,&asn_buf); + } + if (param_len == -1 || (opr_code == SendParam && opr_flag == MAP_CONFIRM) ) // not has sequence id + { + param_len = pre_param_len; + memcpy(param,pre_param,param_len); + } + + switch (opr_code) + { +/* ------------->>>>>>>>>>>>>. MAP V1 <<<<<<<<<<<<<<<<<--------------------*/ +/* daniel */ + /* + case SendParam: + if (opr_flag == MAP_INDICATE) + return extract_sendParameterArg(&opr_ptr->msg_list.sp_arg,param_len,param,opr_ptr->dialogue_id); + break; + */ +/* daniel */ + case SendParam :// send parameters + if (opr_flag == MAP_INDICATE) + return extract_SendParaArg(&opr_ptr->msg_list.sp_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_SendParaRes(&opr_ptr->msg_list.sp_res,param_len,param); + break; + case NoteSubPrnt :// not subscriber present + if (opr_flag == MAP_INDICATE) + return extract_NotPresentArg(&opr_ptr->msg_list.np_arg,param_len,param); + break; + case ProcUnstrctSSData:// process unstructure SS data + if (opr_flag == MAP_INDICATE) + return extract_ProcessUSSDArg(&opr_ptr->msg_list.pussd_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_ProcessUSSDRes(&opr_ptr->msg_list.pussd_res,param_len,param); + break; + case BeginSubAct:// beging subscriber activity + if (opr_flag == MAP_INDICATE) + return extract_BSAArg(&opr_ptr->msg_list.bsa_arg,param_len,param); + break; + case PerformHo :// perform handover + if (opr_flag == MAP_INDICATE) + return extract_HOArg(&opr_ptr->msg_list.ho_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_HORes(&opr_ptr->msg_list.ho_res,param_len,param); + break; + case PerformSubsHo: + if (opr_flag == MAP_INDICATE) + return extract_PFSHOArg(&opr_ptr->msg_list.pfsho_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_PFSHORes(&opr_ptr->msg_list.pfsho_res,param_len,param); + break; + case NoteInterHo: + if (opr_flag == MAP_INDICATE) + return extract_NIHOArg(&opr_ptr->msg_list.niho_arg,param_len,param); + break; + case TraceSubAct: + if (opr_flag == MAP_INDICATE) + return extract_TSAArg(&opr_ptr->msg_list.tsa_arg,param_len,param); + break; + case AlrtSCWithoutRes: + if (opr_flag == MAP_INDICATE) + return extract_altsrvcentarg(&opr_ptr->msg_list.asc_arg,param_len,param); + break; + /* + case BeginSubAct: + if (opr_flag == MAP_INDICATE) + return extract_BSAArg(&opr_ptr->msg_list.bsa_arg,param_len,param); + break; + */ +/* ------------->>>>>>>>>>>>>. MAP V1 <<<<<<<<<<<<<<<<<--------------------*/ + case UpLoc: + if (opr_flag == MAP_INDICATE) + return extract_uplocarg(&opr_ptr->msg_list.ul_arg,param_len,param,opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + return extract_uplocres(&opr_ptr->msg_list.ul_res,param_len,param); + break; + case CancelLoc: + if (opr_flag == MAP_INDICATE) + return extract_cancellocarg(&opr_ptr->msg_list.cl_arg,param_len,param,opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + return extract_cancellocres(&opr_ptr->msg_list.cl_res,param_len,param); + break; + case PurgeMS: + if (opr_flag == MAP_INDICATE) + return extract_purgemsarg(&opr_ptr->msg_list.pms_arg,param_len,param,opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + return extract_purgemsres(&opr_ptr->msg_list.pms_res,param_len,param); + break; + case SndIdent: + if (opr_flag == MAP_INDICATE) + return extract_sndidentarg(&opr_ptr->msg_list.si_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_sndidentres(&opr_ptr->msg_list.si_res,param_len,param); + break; + case UpGprsLoc: + if (opr_flag == MAP_INDICATE) + return extract_upgprslocarg(&opr_ptr->msg_list.ugl_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_upgprslocres(&opr_ptr->msg_list.ugl_res,param_len,param); + break; + case ProvSubInfo: + if (opr_flag == MAP_INDICATE) + return extract_prvsubinfoarg(&opr_ptr->msg_list.psi_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_prvsubinfores(&opr_ptr->msg_list.psi_res,param_len,param); + break; + case AnyTimeInter: + if (opr_flag == MAP_INDICATE) + return extract_anytimeintarg(&opr_ptr->msg_list.ati_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_anytimeintres(&opr_ptr->msg_list.ati_res,param_len,param); + break; + case AnyTimeSubInter: + if (opr_flag == MAP_INDICATE) + return extract_anytimesubintarg(&opr_ptr->msg_list.atsi_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_anytimesubintres(&opr_ptr->msg_list.atsi_res,param_len,param); + break; + case PreHo: + if (opr_flag == MAP_INDICATE) + return extract_prehoarg(&opr_ptr->msg_list.pho_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_prehores(&opr_ptr->msg_list.pho_res,param_len,param); + break; + case SndEndSig: + if (opr_flag == MAP_INDICATE) + return extract_sndendsigarg(&opr_ptr->msg_list.ses_arg,param_len,param); + break; + case ProcAccSig: + if (opr_flag == MAP_INDICATE) + return extract_prcaccsigarg(&opr_ptr->msg_list.pas_arg,param_len,param); + break; + case FwdAccSig: + if (opr_flag == MAP_INDICATE) + return extract_fwdaccsigarg(&opr_ptr->msg_list.fas_arg,param_len,param); + break; + case PreSubsHo: + if (opr_flag == MAP_INDICATE) + return extract_presubshoarg(&opr_ptr->msg_list.psho_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_presubshores(&opr_ptr->msg_list.psho_res,param_len,param); + break; + case SndAuthInfo: //modify by gxchen + if (opr_flag == MAP_INDICATE) + return extract_sndauthinfoarg(&opr_ptr->msg_list.sai_arg,param_len,param,opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + return extract_sndauthinfores(&opr_ptr->msg_list.sai_res,param_len,param,opr_ptr->version); + break; + case AuthFailReport: //add by gxchen + if(opr_flag == MAP_INDICATE) + return extract_authfailreportarg(&opr_ptr->msg_list.authfr_arg, param_len, param); +// else if(opr_flag == MAP_CONFIRM) +// return extract_authfailreportres(&opr_ptr->msg_list.authfr_res, param_len, param); + break; + case ChkIMEI: + if (opr_flag == MAP_INDICATE) + return extract_chkimeiarg(&opr_ptr->msg_list.cimei_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_chkimeires(&opr_ptr->msg_list.cimei_res,param_len,param); + break; + case InsSubData: + if (opr_flag == MAP_INDICATE) + return extract_inssubdataarg(&opr_ptr->msg_list.isd_arg,param_len,param); + if (opr_flag == MAP_CONFIRM) + return extract_inssubdatares(&opr_ptr->msg_list.isd_res,param_len,param); + break; + case DelSubData: + if (opr_flag == MAP_INDICATE) + return extract_delsubdataarg(&opr_ptr->msg_list.dsd_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_delsubdatares(&opr_ptr->msg_list.dsd_res,param_len,param); + break; + case Reset: + if (opr_flag == MAP_INDICATE) + return extract_resetarg(&opr_ptr->msg_list.reset_arg,param_len,param); + break; + case RestoreData: + if (opr_flag == MAP_INDICATE) + return extract_restdataarg(&opr_ptr->msg_list.rd_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_restdatares(&opr_ptr->msg_list.rd_res,param_len,param); + break; + case SndRoutInfoForGprs: + if (opr_flag == MAP_INDICATE) + return extract_sndroutinfogprsarg(&opr_ptr->msg_list.srifg_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_sndroutinfogprsres(&opr_ptr->msg_list.srifg_res,param_len,param); + break; + case FailRep: + if (opr_flag == MAP_INDICATE) + return extract_failreportarg(&opr_ptr->msg_list.fr_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_failreportres(&opr_ptr->msg_list.fr_res,param_len,param); + break; + case NoteMsPresForGprs: + if (opr_flag == MAP_INDICATE) + return extract_notemspregprsarg(&opr_ptr->msg_list.nmpfg_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_notemspregprsres(&opr_ptr->msg_list.nmpfg_res,param_len,param); + break; + case ActvTraceMode: + if (opr_flag == MAP_INDICATE) + return extract_acttrcmodearg(&opr_ptr->msg_list.atm_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_acttrcmoderes(&opr_ptr->msg_list.atm_res,param_len,param); + break; + case DeactvTraceMode: + if (opr_flag == MAP_INDICATE) + return extract_deacttrcmodearg(&opr_ptr->msg_list.dtm_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_deacttrcmoderes(&opr_ptr->msg_list.dtm_res,param_len,param); + break; + case SndIMSI: + if (opr_flag == MAP_INDICATE) + return extract_sndimsiarg(&opr_ptr->msg_list.simsi_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_sndimsires(&opr_ptr->msg_list.simsi_res,param_len,param); + break; + case SndRoutInfo: + if (opr_flag == MAP_INDICATE) + return extract_sndroutinfoarg(&opr_ptr->msg_list.sri_arg,param_len,param,opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + return extract_sndroutinfores(&opr_ptr->msg_list.sri_res,param_len,param,opr_ptr->version); + break; + case ProvRoamNum: + if (opr_flag == MAP_INDICATE) + return extract_provroamnumarg(&opr_ptr->msg_list.prn_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_provroamnumres(&opr_ptr->msg_list.prn_res,param_len,param); + break; + case ResumeCH: + if (opr_flag == MAP_INDICATE) + return extract_rescallhandarg(&opr_ptr->msg_list.rch_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_rescallhandres(&opr_ptr->msg_list.rch_res,param_len,param); + break; + case ProvSIWFSNum: + if (opr_flag == MAP_INDICATE) + return extract_prvsiwfsnumarg(&opr_ptr->msg_list.psn_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_prvsiwfsnumres(&opr_ptr->msg_list.psn_res,param_len,param); + break; + case SIWFSSigMdf: + if (opr_flag == MAP_INDICATE) + return extract_siwfssigmodarg(&opr_ptr->msg_list.ssm_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_siwfssigmodres(&opr_ptr->msg_list.ssm_res,param_len,param); + break; + case SetRepState: + if (opr_flag == MAP_INDICATE) + return extract_setrepstatearg(&opr_ptr->msg_list.srs_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_setrepstateres(&opr_ptr->msg_list.srs_res,param_len,param); + break; + case StatusRep: + if (opr_flag == MAP_INDICATE) + return extract_statreparg(&opr_ptr->msg_list.sr_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_statrepres(&opr_ptr->msg_list.sr_res,param_len,param); + break; + case RmtUserFree: + if (opr_flag == MAP_INDICATE) + return extract_rmtuserfreearg(&opr_ptr->msg_list.ruf_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_rmtuserfreeres(&opr_ptr->msg_list.ruf_res,param_len,param); + break; + case IstAlert: //ist-Alert umts add by gxchen + if(opr_flag == MAP_INDICATE) + return extract_istalertarg(&opr_ptr->msg_list.istalt_arg, param_len, param); + else if(opr_flag == MAP_CONFIRM) + return extract_istalertres(&opr_ptr->msg_list.istalt_res, param_len, param); + break; + case IstCommand: //ist-Command umts add by gxchen + if(opr_flag == MAP_INDICATE) + return extract_istcmdarg(&opr_ptr->msg_list.istcmd_arg, param_len, param); +// else if(opr_flag == MAP_CONFIRM) +// return extract_istcmdres(&opr_ptr->msg_list.istcmd_res, param_len, param); + break; + case RegSS: + if (opr_flag == MAP_INDICATE) + return extract_regssarg(&opr_ptr->msg_list.rss_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_regssres(&opr_ptr->msg_list.rss_res,param_len,param); + break; + case EraseSS: + if (opr_flag == MAP_INDICATE) + return extract_erassarg(&opr_ptr->msg_list.ess_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_erassres(&opr_ptr->msg_list.ess_res,param_len,param); + break; + case ActvSS: + if (opr_flag == MAP_INDICATE) + return extract_actssarg(&opr_ptr->msg_list.ass_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_actssres(&opr_ptr->msg_list.ass_res,param_len,param); + break; + case DeactvSS: + if (opr_flag == MAP_INDICATE) + return extract_deactssarg(&opr_ptr->msg_list.dass_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_deactssres(&opr_ptr->msg_list.dass_res,param_len,param); + break; + case InterSS: + if (opr_flag == MAP_INDICATE) + return extract_intrssarg(&opr_ptr->msg_list.intss_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_intrssres(&opr_ptr->msg_list.intss_res,param_len,param); + break; + case ProcUnstrctSSReq: + if (opr_flag == MAP_INDICATE) + return extract_prcunssreqarg(&opr_ptr->msg_list.pussr_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_prcunssreqres(&opr_ptr->msg_list.pussr_res,param_len,param); + break; + case UnstrctSSReq: + if (opr_flag == MAP_INDICATE) + return extract_unssreqarg(&opr_ptr->msg_list.ussr_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_unssreqres(&opr_ptr->msg_list.ussr_res,param_len,param); + break; + case UnstrctSSNoti: + if (opr_flag == MAP_INDICATE) + return extract_unssnotarg(&opr_ptr->msg_list.ussn_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_unssnotres(&opr_ptr->msg_list.ussn_res,param_len,param); + break; + case RegPasswd: + if (opr_flag == MAP_INDICATE) + return extract_regpswdarg(&opr_ptr->msg_list.rpss_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_regpswdres(&opr_ptr->msg_list.rpss_res,param_len,param); + break; + case GetPasswd: + if (opr_flag == MAP_INDICATE) + return extract_getpswdarg(&opr_ptr->msg_list.gpss_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_getpswdres(&opr_ptr->msg_list.gpss_res,param_len,param); + break; + case SSInvNoti: + if (opr_flag == MAP_INDICATE) + return extract_ssinvnotarg(&opr_ptr->msg_list.ssin_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_ssinvnotres(&opr_ptr->msg_list.ssin_res,param_len,param); + break; + case RegCCEntry: + if (opr_flag == MAP_INDICATE) + return extract_regccentarg(&opr_ptr->msg_list.rcce_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_regccentres(&opr_ptr->msg_list.rcce_res,param_len,param); + break; + case EraseCCEntry: + if (opr_flag == MAP_INDICATE) + return extract_eraseccentarg(&opr_ptr->msg_list.ecce_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_eraseccentres(&opr_ptr->msg_list.ecce_res,param_len,param); + break; + case SndRoutInfoForSM: + if( opr_ptr->version == 1) + { + if (opr_flag == MAP_INDICATE) + return extract_routinfoforsm_v1_arg(&opr_ptr->msg_list.rifsm_v1_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_routinfoforsm_v1_res(&opr_ptr->msg_list.rifsm_v1_res,param_len,param); + } + else + { + if (opr_flag == MAP_INDICATE) + return extract_routinfoforsmarg(&opr_ptr->msg_list.rifsm_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_routinfoforsmres(&opr_ptr->msg_list.rifsm_res,param_len,param); + } + break; + case FwdSM: + //case MOFwdSM: + //case MTFwdSM: + if (opr_flag == MAP_INDICATE) + return extract_mofwdsmarg(&opr_ptr->msg_list.mofsm_arg,param_len,param,opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + { + if(opr_ptr->version<3) + return ROK; + return extract_mofwdsmres(&opr_ptr->msg_list.mofsm_res,param_len,param); + } + break; + case MTFwdSM_v3: + if (opr_flag == MAP_INDICATE) + return extract_mtfwdsmarg(&opr_ptr->msg_list.mtfsm_arg,param_len,param,opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + return extract_mtfwdsmres(&opr_ptr->msg_list.mtfsm_res,param_len,param,opr_ptr->version); + break; + case RptSMDelvStat: + if (opr_flag == MAP_INDICATE) + return extract_repsmdelstatarg(&opr_ptr->msg_list.rsmds_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_repsmdelstatres(&opr_ptr->msg_list.rsmds_res,param_len,param); + break; + case AlrtSC: + if (opr_flag == MAP_INDICATE) + return extract_altsrvcentarg(&opr_ptr->msg_list.asc_arg,param_len,param); + break; + case InfSC: + if (opr_flag == MAP_INDICATE) + return extract_infsrvcentarg(&opr_ptr->msg_list.isc_arg,param_len,param); + break; + case RdyForSM: + if (opr_flag == MAP_INDICATE) + return extract_rdyforsmarg(&opr_ptr->msg_list.rfsm_arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_rdyforsmres(&opr_ptr->msg_list.rfsm_res,param_len,param); + break; + case SecuTrip: + if (opr_flag == MAP_INDICATE) + return extract_securityTriplets_arg(&opr_ptr->msg_list.st_arg,param_len,param, opr_ptr->version); + else if (opr_flag == MAP_CONFIRM) + return extract_securityTriplets_res(&opr_ptr->msg_list.st_res,param_len,param); + break; + case InterrSubs: + if (opr_flag == MAP_INDICATE) + return extract_interrogateSubscriber_arg(&opr_ptr->msg_list.is_arg,param_len,param); + break; + case CreateSubs: + if (opr_flag == MAP_INDICATE) + return extract_createSubscriber_arg(&opr_ptr->msg_list.cs_arg,param_len,param); + break; + case DelSubs: + if (opr_flag == MAP_INDICATE) + return extract_deleteSubscriber_arg(&opr_ptr->msg_list.ds_arg,param_len,param); + break; + /**** map opr **********/ + case DetermineOprUser: + if (opr_flag == MAP_INDICATE) + return extract_MapDetermineOprUserArg(&opr_ptr->msg_list.DetermineOprUser_Arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_MapDetermineOprUserRes(&opr_ptr->msg_list.DetermineOprUser_Res,param_len,param); + break; + case VlrUpdateLocation: + if (opr_flag == MAP_INDICATE) + return extract_MapVlrUpdateLocationArg(&opr_ptr->msg_list.VlrUpdateLocation_Arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_MapVlrUpdateLocationRes(&opr_ptr->msg_list.VlrUpdateLocation_Res,param_len,param); + break; + case CreateUserWithMsisdnImsi: + if (opr_flag == MAP_INDICATE) + return extract_MapCreateUserWithMsisdnImsiArg(&opr_ptr->msg_list.CreateUserWithMsisdnImsi_Arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_MapCreateUserWithMsisdnImsiRes(&opr_ptr->msg_list.CreateUserWithMsisdnImsi_Res,param_len,param); + break; + case DeleteOprUser: + if (opr_flag == MAP_INDICATE) + return extract_MapDeleteOprUserArg(&opr_ptr->msg_list.DeleteOprUser_Arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_MapDeleteOprUserRes(&opr_ptr->msg_list.DeleteOprUser_Res,param_len,param); + break; + case VlrEnquiryIMDMStatus: + if (opr_flag == MAP_INDICATE) + return extract_MapVlrEnquiryIMDM_Arg(&opr_ptr->msg_list.EnquiryIMDM_Arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + return extract_MapVlrEnquiryIMDM_Res(&opr_ptr->msg_list.EnquiryIMDM_Res,param_len,param); + break; + case RoutingInfoForLCS: + if (opr_flag == MAP_INDICATE) + return extract_RoutingInfoForLCS_Arg(&opr_ptr->msg_list.routingInfoForLCS_Arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + { + xap_send_error("RoutingInfoForLCS Res is not support to extract"); + return RER; + } + break; + case ProvideSubscriberLocation: + if (opr_flag == MAP_INDICATE) + return extract_ProvideSubscriberLocation_Arg(&opr_ptr->msg_list.provideSubscriberLocation_Arg,param_len,param); + else if (opr_flag == MAP_CONFIRM) + { + xap_send_error("ProvideSubscriberLocation Res is not support to extract"); + return RER; + } + break; + /**** map opr **********/ + default: + xap_send_error("the operation is not support:%d",opr_code); + return 0; + } + return 1; +} + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* +++++ Common types +++++ */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +int assign_authset(struct AuthSet_struct *auth_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (auth_ptr->param_flag != 0x07) + return RER; + buf_len = add_tlv("4-1",RAND_LEN,auth_ptr->rand,0x00,&asn_buf); + buf_len = add_tlv("4-2",SRES_LEN,auth_ptr->sres,0x00,&asn_buf); + buf_len = add_tlv("4-3",KC_LEN,auth_ptr->kc,0x00,&asn_buf); + return buf_len; +} + +int extract_authset(struct AuthSet_struct *auth_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1",temp_buf,&asn_buf) == RAND_LEN) + memcpy(auth_ptr->rand,temp_buf,RAND_LEN); + else + return RER; + if(get_tlv("4-2",temp_buf,&asn_buf) == SRES_LEN) + memcpy(auth_ptr->sres,temp_buf,SRES_LEN); + else + return RER; + if(get_tlv("4-3",temp_buf,&asn_buf) == KC_LEN) + memcpy(auth_ptr->kc,temp_buf,KC_LEN); + else + return RER; + auth_ptr->param_flag = 0x07; + return ROK; +} + +//add by gxchen start +int assign_triplet(Triplet_st *auth_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf,&asn_buf); + if (auth_ptr->param_flag != 0x07) + return RER; + buf_len = add_tlv("4-1",RAND_LEN,auth_ptr->rand,0x00,&asn_buf); + buf_len = add_tlv("4-2",SRES_LEN,auth_ptr->sres,0x00,&asn_buf); + buf_len = add_tlv("4-3",KC_LEN,auth_ptr->kc,0x00,&asn_buf); + return buf_len; +} + +int extract_triplet(Triplet_st *auth_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1",temp_buf,&asn_buf) == RAND_LEN) + memcpy(auth_ptr->rand,temp_buf,RAND_LEN); + else + return RER; + if(get_tlv("4-2",temp_buf,&asn_buf) == SRES_LEN) + memcpy(auth_ptr->sres,temp_buf,SRES_LEN); + else + return RER; + if(get_tlv("4-3",temp_buf,&asn_buf) == KC_LEN) + memcpy(auth_ptr->kc,temp_buf,KC_LEN); + else + return RER; + auth_ptr->param_flag = 0x07; + return ROK; +} + +int assign_quintuplet(Quintuplet_st *auth_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf, &asn_buf); + if (auth_ptr->param_flag != 0x1F) + return RER; + buf_len = add_tlv("4-1", RAND_LEN, auth_ptr->rand, 0x00, &asn_buf); + buf_len = add_tlv("4-2", XRES_LEN, auth_ptr->xres, 0x00, &asn_buf); + buf_len = add_tlv("4-3", CK_LEN, auth_ptr->ck, 0x00, &asn_buf); + buf_len = add_tlv("4-4", IK_LEN, auth_ptr->ik, 0x00, &asn_buf); + buf_len = add_tlv("4-5", AUTN_LEN, auth_ptr->autn, 0x00, &asn_buf); + return buf_len; +} + +int extract_quintuplet(Quintuplet_st *auth_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1", temp_buf, &asn_buf) == RAND_LEN) + memcpy(auth_ptr->rand, temp_buf, RAND_LEN); + else + return RER; + if(get_tlv("4-2", temp_buf, &asn_buf) == XRES_LEN) + memcpy(auth_ptr->xres, temp_buf, XRES_LEN); + else + return RER; + if(get_tlv("4-3", temp_buf, &asn_buf) == CK_LEN) + memcpy(auth_ptr->ck, temp_buf, CK_LEN); + else + return RER; + if(get_tlv("4-4", temp_buf, &asn_buf) == IK_LEN) + memcpy(auth_ptr->ik, temp_buf, IK_LEN); + else + return RER; + if(get_tlv("4-5", temp_buf, &asn_buf) == AUTN_LEN) + memcpy(auth_ptr->autn, temp_buf, AUTN_LEN); + else + return RER; + auth_ptr->param_flag = 0x1F; + return ROK; +} + +int assign_gsmSecCon(GsmSecCon_st *con_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf, &asn_buf); + if (con_ptr->param_flag != 0x03) + return RER; + buf_len = add_tlv("4-1", KC_LEN, con_ptr->kc, 0x00, &asn_buf); + buf_len = add_tlv("4-2", 1, &con_ptr->cksn, 0x00, &asn_buf); + return buf_len; +} + +int extract_gsmSecCon(GsmSecCon_st *con_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1", temp_buf, &asn_buf) == KC_LEN) + memcpy(con_ptr->kc, temp_buf, KC_LEN); + else + return RER; + if(get_tlv("4-2", temp_buf, &asn_buf) == 1) + con_ptr->cksn = temp_buf[0]; + else + return RER; + con_ptr->param_flag = 0x03; + return ROK; +} + +int assign_umtsSecCon(UmtsSecCon_st *con_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf, &asn_buf); + if (con_ptr->param_flag != 0x07) + return RER; + buf_len = add_tlv("4-1", CK_LEN, con_ptr->ck, 0x00, &asn_buf); + buf_len = add_tlv("4-2", IK_LEN, con_ptr->ik, 0x00, &asn_buf); + buf_len = add_tlv("4-3", 1, &con_ptr->ksi, 0x00, &asn_buf); + return buf_len; +} + +int extract_umtsSecCon(UmtsSecCon_st *con_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1", temp_buf, &asn_buf) == CK_LEN) + memcpy(con_ptr->ck, temp_buf, CK_LEN); + else + return RER; + if (get_tlv("4-2", temp_buf, &asn_buf) == IK_LEN) + memcpy(con_ptr->ik, temp_buf, IK_LEN); + else + return RER; + if(get_tlv("4-3", temp_buf, &asn_buf) == 1) + con_ptr->ksi= temp_buf[0]; + else + return RER; + con_ptr->param_flag = 0x07; + return ROK; +} + +int assign_authReSynInfo(AuthReSynInfo_st *resyn_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + + asn_encode(buf, &asn_buf); + if (resyn_ptr->param_flag != 0x03) + return RER; + buf_len = add_tlv("4-1", RAND_LEN, resyn_ptr->rand, 0x00, &asn_buf); + buf_len = add_tlv("4-2", AUTS_LEN, resyn_ptr->auts, 0x00, &asn_buf); + return buf_len; +} + +int extract_authReSynInfo(AuthReSynInfo_st *resyn_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + u8 temp_buf[256]; + + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("4-1", temp_buf, &asn_buf) == RAND_LEN) + memcpy(resyn_ptr->rand, temp_buf, RAND_LEN); + else + return RER; + if (get_tlv("4-2", temp_buf, &asn_buf) == AUTS_LEN) + memcpy(resyn_ptr->auts, temp_buf, AUTS_LEN); + else + return RER; + resyn_ptr->param_flag = 0x03; + return ROK; +} + +int assign_sgsnCapability(struct SgsnCap_s *cap_ptr, u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 tag1=1; + char tlv1[32]; + + asn_encode(buf, &asn_buf); + if(cap_ptr->param_flag & 0x04) + { + sprintf(tlv1,"3-%d",tag1++); + buf_len = add_null(tlv1, 0x80, &asn_buf); + } + return buf_len; +} + +int extract_sgsnCapability(struct SgsnCap_s *cap_ptr, u32 buf_len, u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 tag1=1; + char tlv1[32]; + //u8 temp_buf[256]; + + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + sprintf(tlv1,"3-%d",tag1++); + len = get_null(tlv1, &asn_buf); //get_tlv + if(len > 0) + { + cap_ptr->gprs_supp_ind = 1; + cap_ptr->param_flag |= 0x04; + } + return ROK; +} + +//add by gxchen end + +int assign_extsiginfo(struct ExtSigInfo_struct *sig_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 temp_buf[2]; + + asn_encode(buf,&asn_buf); + if (sig_ptr->param_flag & 0x01) //prt_id + { + temp_buf[0] = sig_ptr->prt_id; + buf_len = add_tlv("10-1",1,temp_buf,0x00,&asn_buf); + } + if (sig_ptr->param_flag & 0x02) //siginfo + buf_len = add_tlv("4-2",sig_ptr->siginfo.siginfo_len,sig_ptr->siginfo.signal_info,0x00,&asn_buf); + return buf_len; +} + +int extract_extsiginfo(struct ExtSigInfo_struct *sig_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + sig_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("10",temp_buf,&asn_buf) == 1) + { + sig_ptr->prt_id = temp_buf[0]; + sig_ptr->param_flag |= 0x01; + } + len = get_tlv("4",temp_buf,&asn_buf); + if (len > 0 && len < SIGNALINFO_LEN) + { + sig_ptr->siginfo.siginfo_len = len; + memcpy(sig_ptr->siginfo.signal_info,temp_buf,len); + sig_ptr->param_flag |= 0x02; + } + return ROK; +} + +int assign_bscode(struct BSCode_struct *bs_ptr,u8 *buf,u8 flag) +{ + ASN_BUF asn_buf; + int ii; + int buf_len=0; + int temp_len; + u8 temp_buf[256]; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (bs_ptr->param_flag & 0x01) + { + temp_len = tele_bittostr(bs_ptr->tele_code,temp_buf,flag); + for (ii = 0;ii < temp_len;ii ++) + { + sprintf(tlv1,"3-%d",ii+1); + buf_len = add_tlv(tlv1,1,temp_buf+ii,0x80,&asn_buf); + } + } + if (bs_ptr->param_flag & 0x02) + { + temp_len = bearer_bittostr(bs_ptr->bearer_code,temp_buf,flag); + for (ii = 0;ii < temp_len;ii ++) + { + sprintf(tlv1,"2-%d",ii+1); + buf_len = add_tlv(tlv1,1,temp_buf+ii,0x80,&asn_buf); + } + } + return buf_len; +} + +int extract_bscode(struct BSCode_struct *bs_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int ii; + u8 temp_buf[256],temp_data[256]; + char tlv1[32]; + + bs_ptr->param_flag = 0; + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + for (ii = 0;ii < TSLIST_LEN;ii ++) // tele + { + sprintf(tlv1,"3-%d",ii+1); + if (get_tlv(tlv1,temp_buf,&asn_buf) < 1) + { + bs_ptr->tele_code = tele_strtobit(temp_data,ii); + bs_ptr->param_flag |= 0x01; + break; + } + temp_data[ii] = temp_buf[0]; + } + for (ii = 0;ii < BSLIST_LEN;ii ++) // bearer + { + sprintf(tlv1,"2-%d",ii+1); + if (get_tlv(tlv1,temp_buf,&asn_buf) < 1) + { + bs_ptr->bearer_code = bearer_strtobit(temp_data,ii); + bs_ptr->param_flag |= 0x02; + break; + } + temp_data[ii] = temp_buf[0]; + } + return ROK; +} + +int assign_subinfo(struct SubInfo_struct *info_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u8 tag1=1,tag2; + char tlv1[32],tlv2[32]; + + asn_encode(buf,&asn_buf); + if (info_ptr->param_flag & 0x01) // location info + { + tag2 = 1; + if (info_ptr->loc_info.param_flag & 0x01) // age of location info + { + sprintf(tlv1,"0-%d.2-%d",tag1,tag2++); + buf_len = add_int(tlv1,info_ptr->loc_info.age_info,0x00,&asn_buf); + } + if (info_ptr->loc_info.param_flag & 0x02) // geographical info + { + sprintf(tlv1,"0-%d.0-%d",tag1,tag2++); + buf_len = add_tlv(tlv1,8,info_ptr->loc_info.geog_info,0x80,&asn_buf); + } + if (info_ptr->loc_info.param_flag & 0x04) // vlr number + { + sprintf(tlv1,"0-%d.1-%d",tag1,tag2++); + buf_len = add_tlv(tlv1,info_ptr->loc_info.vlr_num[0],info_ptr->loc_info.vlr_num+1,0x80,&asn_buf); + } + if (info_ptr->loc_info.param_flag & 0x08) // location number + { + sprintf(tlv1,"0-%d.2-%d",tag1,tag2++); + buf_len = add_tlv(tlv1,info_ptr->loc_info.loc_num[0],info_ptr->loc_info.loc_num+1,0x80,&asn_buf); + } + if (info_ptr->loc_info.param_flag & 0x10) // cell id or LAI + { + sprintf(tlv1,"0-%d.3-%d",tag1,tag2++); + if (info_ptr->loc_info.cell_lai.choice_flag == 1) // cell id + { + sprintf(tlv2,"%s.0",tlv1); + buf_len = add_tlv(tlv2,GCID_LEN,info_ptr->loc_info.cell_lai.cell_choice.cellid,0x80,&asn_buf); + } + else // lai + { + sprintf(tlv2,"%s.1",tlv1); + buf_len = add_tlv(tlv2,LAI_LEN,info_ptr->loc_info.cell_lai.cell_choice.lai,0x80,&asn_buf); + } + } + tag1 ++; + } + if (info_ptr->param_flag & 0x02) // subscriber state + { + switch (info_ptr->sub_state.choice_flag) + { + case 0x01: // assume idle + sprintf(tlv1,"1-%d.0",tag1); + buf_len = add_null(tlv1,0x80,&asn_buf); + break; + case 0x02: // camel busy + sprintf(tlv1,"1-%d.1",tag1); + buf_len = add_null(tlv1,0x80,&asn_buf); + break; + case 0x04: // net not reachable + sprintf(tlv1,"1-%d.10",tag1); + buf_len = add_int(tlv1,info_ptr->sub_state.choice.net_reason,0x00,&asn_buf); + break; + case 0x08: // not provided from vlr + sprintf(tlv1,"1-%d.2",tag1); + buf_len = add_null(tlv1,0x80,&asn_buf); + break; + default: + break; + } + } + if (info_ptr->param_flag & 0x04) // location info GPRS + { + tag1 = 3; + sprintf(tlv1,"%d",tag1); + buf_len = add_int(tlv1,info_ptr->locationInfoGPRS,0x80,&asn_buf); + } + if (info_ptr->param_flag & 0x08) // ps subscriber state + { + tag1 = 4; + sprintf(tlv1,"%d",tag1); + buf_len = add_int(tlv1,info_ptr->locationInfoGPRS,0x80,&asn_buf); + } + if (info_ptr->param_flag & 0x10) // imei + { + tag1 = 5; + sprintf(tlv1,"%d",tag1); + buf_len = add_tlv(tlv1,IMEI_LEN, + info_ptr->imei,0x80,&asn_buf); + } + if (info_ptr->param_flag & 0x20) // ms classmark + { + tag1 = 6; + sprintf(tlv1,"%d",tag1); + buf_len = add_int(tlv1,info_ptr->ms_classmark,0x80,&asn_buf); + } + if (info_ptr->param_flag & 0x40) // gprs class mark + { + tag1 = 7; + sprintf(tlv1,"%d",tag1); + buf_len = add_int(tlv1,info_ptr->gprs_ms_class,0x80,&asn_buf); + } + if (info_ptr->param_flag & 0x80) // mnp info response + { + struct MnpInfoRes *mnpInfoResPtr; + mnpInfoResPtr = &info_ptr->mnp_info_res; + tag1 = 8; + if(mnpInfoResPtr->param_flag & 0x01) + { + sprintf(tlv1,"%d.0",tag1); + buf_len = add_tlv(tlv1, + mnpInfoResPtr->routing_number[0]%(ISDN_LEN+1), + mnpInfoResPtr->routing_number+1, + 0x80, + &asn_buf); + } + if(mnpInfoResPtr->param_flag & 0x02) + { + sprintf(tlv1,"%d.1",tag1); + buf_len = add_tlv(tlv1, + IMSI_LEN, + mnpInfoResPtr->imsi, + 0x80, + &asn_buf); + } + if(mnpInfoResPtr->param_flag & 0x04) + { + sprintf(tlv1,"%d.2",tag1); + buf_len = add_tlv(tlv1, + mnpInfoResPtr->msisdn[0]%(ISDN_LEN+1), + mnpInfoResPtr->msisdn+1, + 0x80, + &asn_buf); + } + if(mnpInfoResPtr->param_flag & 0x08) + { + sprintf(tlv1,"%d.3",tag1); + buf_len = add_tlv(tlv1, + 1, + (u_char *)&mnpInfoResPtr->mnp_status, + 0x80, + &asn_buf); + } + } + return buf_len; +} + +int extract_subinfo(struct SubInfo_struct *info_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + u8 tag1; + char tlv1[32]; + + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) != -1) // location info + { + info_ptr->param_flag |= 0x01; + tag1 = 1; + len = get_int("0.2-1",&asn_buf); // age of location info + if (len != -1) + { + info_ptr->loc_info.param_flag |= 0x01; + info_ptr->loc_info.age_info = len; + tag1 ++; + } + if (get_tlv("0.0",temp_buf,&asn_buf) == 8) // geographical info + { + info_ptr->loc_info.param_flag |= 0x02; + memcpy(info_ptr->loc_info.geog_info,temp_buf,8); + tag1 ++; + } + len = get_tlv("0.1",temp_buf,&asn_buf); // vlr num + if (len != -1 && len < ISDN_LEN) + { + info_ptr->loc_info.param_flag |= 0x04; + info_ptr->loc_info.vlr_num[0] = len; + memcpy(info_ptr->loc_info.vlr_num+1,temp_buf,len); + tag1 ++; + } + sprintf(tlv1,"0.2-%d",tag1); + len = get_tlv(tlv1,temp_buf,&asn_buf); // location num + if (len != -1 && len < LOCATION_NUM) + { + info_ptr->loc_info.param_flag |= 0x08; + info_ptr->loc_info.loc_num[0] = len; + memcpy(info_ptr->loc_info.loc_num+1,temp_buf,len); + } + if (get_tlv("0.3",temp_buf,&asn_buf) != -1) // cell id or lai + { + info_ptr->loc_info.param_flag |= 0x10; + if (get_tlv("0.3.0",temp_buf,&asn_buf) == GCID_LEN) + { + info_ptr->loc_info.cell_lai.choice_flag = 1; + memcpy(info_ptr->loc_info.cell_lai.cell_choice.cellid,temp_buf,GCID_LEN); + } + else if (get_tlv("0.3.1",temp_buf,&asn_buf) == LAI_LEN) + { + info_ptr->loc_info.cell_lai.choice_flag = 2; + memcpy(info_ptr->loc_info.cell_lai.cell_choice.lai,temp_buf,LAI_LEN); + } + } + } + if (get_tlv("1",temp_buf,&asn_buf) != -1) // location info + { + info_ptr->param_flag |= 0x02; + if (get_tlv("1.0",temp_buf,&asn_buf) != -1) // assume idle + info_ptr->sub_state.choice_flag = 1; + else if (get_tlv("1.1",temp_buf,&asn_buf) != -1) // camel busy + info_ptr->sub_state.choice_flag = 2; + else if (get_tlv("1.10",temp_buf,&asn_buf) != -1) // not reachalbe reason + { + info_ptr->sub_state.choice_flag = 0x04; + info_ptr->sub_state.choice.net_reason = temp_buf[0]; + } + else if (get_tlv("1.2",temp_buf,&asn_buf) != -1) // not provided from vlr + info_ptr->sub_state.choice_flag = 0x08; + } + if(get_tlv("3",temp_buf,&asn_buf) != -1) // location info GPRS + { + info_ptr->param_flag |= 0x04; + info_ptr->locationInfoGPRS = temp_buf[0]; + } + if (get_tlv("4",temp_buf,&asn_buf) != -1) // ps subscriber state + { + info_ptr->param_flag |= 0x08; + info_ptr->ps_subscriber_state = temp_buf[0]; + } + if ((len=get_tlv("5",temp_buf,&asn_buf)) != -1) // imei + { + info_ptr->param_flag |= 0x10; + info_ptr->imei[0] = len%(IMEI_LEN+1); + memcpy(&info_ptr->imei[1],temp_buf,IMEI_LEN); + } + if (get_tlv("6",temp_buf,&asn_buf) != -1) // ms class mark + { + info_ptr->param_flag |= 0x20; + info_ptr->ms_classmark = temp_buf[0]; + } + if (get_tlv("7",temp_buf,&asn_buf) != -1) // GPRS MS cla + { + info_ptr->param_flag |= 0x40; + info_ptr->gprs_ms_class = temp_buf[0]; + } + if (get_tlv("8",temp_buf,&asn_buf) != -1) // MNP info res + { + struct MnpInfoRes *mnpInfoResPtr; + mnpInfoResPtr = &info_ptr->mnp_info_res; + info_ptr->param_flag |= 0x80; + mnpInfoResPtr->param_flag = 0x00; + if ((len=get_tlv("8.0",temp_buf,&asn_buf)) != -1) // routing number + { + mnpInfoResPtr->param_flag |= 0x01; + len %= (ISDN_LEN+1); + mnpInfoResPtr->routing_number[0] = len; + memcpy(&mnpInfoResPtr->routing_number[1], + temp_buf, + len); + } + if((len=get_tlv("8.1",temp_buf,&asn_buf)) == IMSI_LEN) + { + mnpInfoResPtr->param_flag |= 0x02; + memcpy(mnpInfoResPtr->imsi,temp_buf,IMSI_LEN); + } + if((len=get_tlv("8.2",temp_buf,&asn_buf)) != -1) + { + mnpInfoResPtr->param_flag |= 0x04; + len %= (ISDN_LEN+1); + mnpInfoResPtr->msisdn[0] = len; + memcpy(&mnpInfoResPtr->msisdn[1],temp_buf,len); + } + if((len=get_tlv("8.3",temp_buf,&asn_buf)) != -1) + { + mnpInfoResPtr->param_flag |= 0x08; + mnpInfoResPtr->mnp_status = temp_buf[0]; + } + } + return ROK; +} + +int assign_ocsi(struct OCsi_struct *ocsi_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + u8 ii; + int buf_len=0; + u8 temp_len; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (ocsi_ptr->tdpdata_list.tdpdata_len > TDPDATA_NUM) + return RER; + buf_len = add_null("16",0x20,&asn_buf); + for(ii = 0;ii < ocsi_ptr->tdpdata_list.tdpdata_len;ii ++) //o-BCSM Camel TDP Data List + { + sprintf(tlv1,"16.16-%d",ii+1); + buf_len = add_null(tlv1,0x20,&asn_buf); + sprintf(tlv1,"16.16-%d.10-1",ii+1); + buf_len = add_int(tlv1,ocsi_ptr->tdpdata_list.tdp_data[ii].det_point,0x00,&asn_buf); + sprintf(tlv1,"16.16-%d.2-2",ii+1); + buf_len = add_int(tlv1,ocsi_ptr->tdpdata_list.tdp_data[ii].service_key,0x00,&asn_buf); + sprintf(tlv1,"16.16-%d.0-3",ii+1); + temp_len = ocsi_ptr->tdpdata_list.tdp_data[ii].scf_add[0]; + buf_len = add_tlv(tlv1,temp_len,ocsi_ptr->tdpdata_list.tdp_data[ii].scf_add+1,0x80,&asn_buf); + sprintf(tlv1,"16.16-%d.1-4",ii+1); + buf_len = add_int(tlv1,ocsi_ptr->tdpdata_list.tdp_data[ii].def_hand,0x80,&asn_buf); + } + if (ocsi_ptr->param_flag & 0x02) //camel capability Handling + buf_len = add_int("0-2",ocsi_ptr->camel_caphand,0x80,&asn_buf); + return buf_len; +} + +int extract_ocsi(struct OCsi_struct *ocsi_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 ii,jj; + u8 temp_buf[256]; + char tlv1[32]; + + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + ocsi_ptr->tdpdata_list.tdpdata_len = 0; + for (ii = 0;ii < TDPDATA_NUM;ii ++) + { + jj = ocsi_ptr->tdpdata_list.tdpdata_len; + sprintf(tlv1,"16.16-%d",ii+1); + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len == -1) + break; + sprintf(tlv1,"16.16-%d.10",ii+1); // det_point + if (get_tlv(tlv1,temp_buf,&asn_buf) != 1) + return RER; + ocsi_ptr->tdpdata_list.tdp_data[jj].det_point = temp_buf[0]; + sprintf(tlv1,"16.16-%d.2",ii+1); // service key + len = get_int(tlv1,&asn_buf); + if (len == -1) + return RER; + ocsi_ptr->tdpdata_list.tdp_data[jj].service_key = len; + sprintf(tlv1,"16.16-%d.0",ii+1); // scf address + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len == -1 || len > ISDN_LEN) + return RER; + ocsi_ptr->tdpdata_list.tdp_data[jj].scf_add[0] = len; + memcpy(ocsi_ptr->tdpdata_list.tdp_data[jj].scf_add+1,temp_buf,len); + sprintf(tlv1,"16.16-%d.1",ii+1); // default call handling + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len != 1) + return RER; + ocsi_ptr->tdpdata_list.tdp_data[jj].def_hand = temp_buf[0]; + ocsi_ptr->tdpdata_list.tdpdata_len ++; + } + if (get_tlv("0",temp_buf,&asn_buf) == 1) + { + ocsi_ptr->param_flag |= 0x02; + ocsi_ptr->camel_caphand = temp_buf[0]; + } + return ROK; +} + +int assign_tdpcritlist(struct OBCritLst_struct *list_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + u8 ii,jj; + int buf_len=0; + u8 tag1,tag2; + int temp_len; + u8 temp_buf[256]; + char tlv1[32],tlv2[32],tlv3[32]; + struct DstNumCrit_struct *dst_ptr; + + asn_encode(buf,&asn_buf); + if (list_ptr->list_len > TDPDATA_NUM) + return RER; + for (ii = 0;ii < list_ptr->list_len;ii ++) + { + sprintf(tlv1,"16-%d",ii+1); + buf_len = add_null(tlv1,0x20,&asn_buf); + sprintf(tlv2,"%s.10-1",tlv1); + buf_len = add_int(tlv2,list_ptr->crit_data[ii].det_point,0x00,&asn_buf); + tag1 = 2; + if (list_ptr->crit_data[ii].param_flag & 0x02) // dest number criteria + { + dst_ptr = (DstNumCrit_struct *) &list_ptr->crit_data[ii].dstCriteria; + if (dst_ptr->param_flag & 0x01) // match type + { + sprintf(tlv2,"%s.0-%d.0-1",tlv1,tag1); + buf_len = add_int(tlv2,dst_ptr->match_type,0x80,&asn_buf); + } + tag2 = 2; + if (dst_ptr->param_flag & 0x02) // dest number list + { + sprintf(tlv2,"%s.0-%d.1-%d",tlv1,tag1,tag2++); + if (dst_ptr->dstnum_list.dstnum_len > MAX_DSTNUM) + return RER; + for (jj = 0;jj < dst_ptr->dstnum_list.dstnum_len;jj ++) + { + sprintf(tlv3,"%s.4-%d",tlv2,jj+1); + buf_len = add_tlv(tlv3,dst_ptr->dstnum_list.dst_num[jj][0],dst_ptr->dstnum_list.dst_num[jj]+1,0x00,&asn_buf); + } + } + if (dst_ptr->param_flag & 0x04) // dest number length list + { + sprintf(tlv2,"%s.0-%d.2-%d",tlv1,tag1,tag2++); + if (dst_ptr->dstnumlen_list.numlength_len > DSTNUM_LEN) + return RER; + for (jj = 0;jj < dst_ptr->dstnumlen_list.numlength_len;jj ++) + { + sprintf(tlv3,"%s.2-%d",tlv2,jj+1); + buf_len = add_int(tlv3,dst_ptr->dstnumlen_list.num_length[jj],0x00,&asn_buf); + } + } + tag1 ++; + } + if (list_ptr->crit_data[ii].param_flag & 0x04) // basic service criteria + { + temp_len = assign_bscode(&list_ptr->crit_data[ii].bs_code,temp_buf,0); + sprintf(tlv2,"%s.1-%d",tlv1,tag1++); + buf_len = add_tlv(tlv2,temp_len,temp_buf,0x10,&asn_buf); + } + if (list_ptr->crit_data[ii].param_flag & 0x08) // call type criteria + { + sprintf(tlv2,"%s.2-%d",tlv1,tag1++); + buf_len = add_int(tlv2,list_ptr->crit_data[ii].call_crit,0x80,&asn_buf); + } + } + return buf_len; +} + +int extract_tdpcritlist(struct OBCritLst_struct *list_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 ii,jj; + u8 aa,bb; + u8 temp_buf[256]; + char tlv1[32]; + struct DstNumCrit_struct *dst_ptr; + + if (buf_len == 0) + return RER; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + list_ptr->list_len = 0; + for (ii = 0;ii < TDPDATA_NUM;ii ++) + { + jj = list_ptr->list_len; + list_ptr->crit_data[jj].param_flag = 0; + sprintf(tlv1,"16-%d",ii+1); + if (get_tlv(tlv1,temp_buf,&asn_buf) == -1) + break; + sprintf(tlv1,"16-%d.10",ii+1); // detection point + if (get_tlv(tlv1,temp_buf,&asn_buf) != 1) + return RER; + list_ptr->crit_data[jj].det_point = temp_buf[0]; + list_ptr->crit_data[jj].param_flag |= 0x01; + sprintf(tlv1,"16-%d.0",ii+1); // dest criteria + if (get_tlv(tlv1,temp_buf,&asn_buf) != -1) + { + list_ptr->crit_data[jj].param_flag |= 0x02; + dst_ptr = (DstNumCrit_struct *) &list_ptr->crit_data[jj].dstCriteria; + sprintf(tlv1,"16-%d.0.0",ii+1); // match type + if (get_tlv(tlv1,temp_buf,&asn_buf) != 1) + return RER; + dst_ptr->match_type = temp_buf[0]; + dst_ptr->param_flag = 0x01; + sprintf(tlv1,"16-%d.0.1",ii+1); // dest num list + if (get_tlv(tlv1,temp_buf,&asn_buf) != -1) + { + dst_ptr->param_flag |= 0x02; + dst_ptr->dstnum_list.dstnum_len = 0; + for (aa = 0;aa < MAX_DSTNUM;aa ++) + { + bb = dst_ptr->dstnum_list.dstnum_len; + sprintf(tlv1,"16-%d.0.1.4-%d",ii+1,aa+1); // dest num list + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len == -1 || len < ISDN_LEN) + break; + dst_ptr->dstnum_list.dst_num[bb][0] = len; + memcpy(dst_ptr->dstnum_list.dst_num[bb]+1,temp_buf,len); + dst_ptr->dstnum_list.dstnum_len ++; + } + } + sprintf(tlv1,"16-%d.0.2",ii+1); // dest num length list + if (get_tlv(tlv1,temp_buf,&asn_buf) != -1) + { + dst_ptr->param_flag |= 0x04; + dst_ptr->dstnumlen_list.numlength_len = 0; + for (aa = 0;aa < DSTNUM_LEN;aa ++) + { + bb = dst_ptr->dstnumlen_list.numlength_len; + sprintf(tlv1,"16-%d.0.2.2-%d",ii+1,aa+1); // dest num list + len = get_tlv(tlv1,temp_buf,&asn_buf); + if (len != 1) + break; + dst_ptr->dstnumlen_list.num_length[bb] = temp_buf[0]; + dst_ptr->dstnumlen_list.numlength_len ++; + } + } + } + sprintf(tlv1,"16-%d.1",ii+1); // bs criteria + if ((len=get_tlv(tlv1,temp_buf,&asn_buf)) != -1) + { + if (!extract_bscode(&list_ptr->crit_data[jj].bs_code,len,temp_buf)) + return RER; + list_ptr->crit_data[jj].param_flag |= 0x04; + } + sprintf(tlv1,"16-%d.2",ii+1); // call type criteria + if (get_tlv(tlv1,temp_buf,&asn_buf) == 1) + { + list_ptr->crit_data[jj].param_flag |= 0x08; + list_ptr->crit_data[jj].call_crit = temp_buf[0]; + } + list_ptr->list_len ++; + } + return ROK; +} + +int assign_ccbsfeat(struct CcbsFeat_struct *cf_ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + int temp_len; + u8 tag1=1; + u8 temp_buf[256]; + char tlv1[32]; + + asn_encode(buf,&asn_buf); + if (cf_ptr->param_flag & 0x01) // ccbs index + { + sprintf(tlv1,"0-%d",tag1++); + buf_len = add_tlv(tlv1,1,&cf_ptr->ccbs_index,0x80,&asn_buf); + } + if (cf_ptr->param_flag & 0x02) // b-subscriber number + { + sprintf(tlv1,"1-%d",tag1++); + buf_len = add_tlv(tlv1,cf_ptr->bsub_num[0],cf_ptr->bsub_num+1,0x80,&asn_buf); + } + if (cf_ptr->param_flag & 0x04) // bs code + { + sprintf(tlv1,"3-%d",tag1++); + temp_len = assign_bscode(&cf_ptr->bs_code,temp_buf,0); + buf_len = add_tlv(tlv1,temp_len,temp_buf,0x80,&asn_buf); + } + return buf_len; +} + +int extract_ccbsfeat(struct CcbsFeat_struct *cf_ptr,u32 buf_len,u8 *buf) +{ + ASN_BUF asn_buf; + int len; + u8 temp_buf[256]; + + cf_ptr->param_flag = 0; + if (buf_len == 0) + return ROK; + if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1) + return RER; + if (get_tlv("0",temp_buf,&asn_buf) == 1) // ccbs index + { + cf_ptr->param_flag |= 0x01; + cf_ptr->ccbs_index = temp_buf[0]; + } + len = get_tlv("1",temp_buf,&asn_buf); // b-subscriber number + if (len > 0 && len <= ISDN_LEN) + { + cf_ptr->param_flag |= 0x02; + cf_ptr->bsub_num[0] = len; + memcpy(cf_ptr->bsub_num+1,temp_buf,len); + } + len = get_tlv("3",temp_buf,&asn_buf); // bs code + if (len > 0) + { + if (!extract_bscode(&cf_ptr->bs_code,len,temp_buf)) + return RER; + cf_ptr->param_flag |= 0x04; + } + return ROK; +} + +int assign_ProvideInstructionStart(struct _ProvideInstructionStart *pis, u8 *buf) +{ + ASN_BUF asn_buf; + int flag,buf_len=0; + u8 info_str[1024]; + //int temp_index; + //int param_num; + + asn_encode(buf,&asn_buf); + flag = pis->param_flag; + //add_null("16", 0x20, &asn_buf); + + if(flag & BIT0_TRUE) + { + buf_len = add_tlv("10.4-1", pis->calledPartyNumber[0], pis->calledPartyNumber+1, 0x80, &asn_buf); + + } + if(flag & BIT1_TRUE) + { + buf_len = add_tlv("4-2", pis->callingPartyNumber[0], pis->callingPartyNumber+1, 0x80, &asn_buf); + } + if(flag & BIT2_TRUE) + { + buf_len = add_tlv("4-3", pis->LATA[0], pis->LATA+1, 0x80, &asn_buf); + } + if(flag & BIT3_TRUE) + { + buf_len = add_tlv("69", 1, &pis->OriginatingStationType, 0xC0, &asn_buf); + } + + memcpy(info_str,buf,buf_len%1024); + asn_encode(buf,&asn_buf); + buf_len = add_tlv("18",buf_len%1024,info_str,0xe0,&asn_buf); + return buf_len; +} + +int assign_ConnectionControlConnect(struct _ConnectionControlConnect *pis, u8 *buf) +{ + ASN_BUF asn_buf; + int flag,buf_len=0; + u8 info_str[1024]; + //int temp_index; + //int param_num; + + asn_encode(buf,&asn_buf); + flag = pis->param_flag; + + if(flag & BIT0_TRUE) + { + buf_len = add_tlv("4-1", pis->CIC[0], pis->CIC+1, 0x80, &asn_buf); + + } + if(flag & BIT1_TRUE) + { + buf_len = add_tlv("4-2", pis->RoutingNumber[0], pis->RoutingNumber+1, 0x80, &asn_buf); + } + if(flag & BIT2_TRUE) + { + buf_len = add_tlv("65", 1, &pis->BillingIndicator, 0xc0, &asn_buf); + } + + memcpy(info_str,buf,buf_len%1024); + asn_encode(buf,&asn_buf); + buf_len = add_tlv("18",buf_len%1024,info_str,0xe0,&asn_buf); + return buf_len; +} + +int build_ainparam(struct MapOprSrv_struct *opr_ptr,u8 *buf) // build ain service paramter +{ + //ASN_BUF asn_buf; + //u8 seq_flag=1; + int param_len = 0; + //u8 info_str[1024]; + u32 param_flag; + + param_flag = opr_ptr->msg_list.provideInstructionStart.param_flag; + if (opr_ptr == NULL || buf == NULL) + return RER; + switch (opr_ptr->message_type & 0x7f) + { + case ProvideInstructionStart: + if(opr_ptr->message_flag == MAP_REQUEST) + { + param_len = assign_ProvideInstructionStart(&opr_ptr->msg_list.provideInstructionStart, buf); + } + break; + case ConnectionControlConnect: + if(opr_ptr->message_flag == MAP_REQUEST) + { + param_len = assign_ConnectionControlConnect(&opr_ptr->msg_list.connectionControlConnect, buf); + } + break; + default: + break; + } + return param_len; +} + +int code_ansitcap_digits(struct _ansiTcapDigits *digits, u8 *outBuf) +{ + int len=0; + + if(digits == NULL || outBuf == NULL) + return 0; + + outBuf[0] = digits->typeOfDigits; + outBuf[1] = digits->natureOfNumber; + outBuf[2] = (digits->numberingPlan<<4) | (digits->encoding&0xf); + outBuf[3] = digits->numberOfDigits; + len = (digits->numberOfDigits + 1)/2; + memcpy(outBuf+4, digits->digits, len); + return len+4; +} + +int decode_ansitcap_digits(struct _ansiTcapDigits *digits, u8 *inBuf) +{ + int len = 0; + + if(digits == NULL || inBuf == NULL) + return 0; + digits->typeOfDigits = inBuf[0]; + digits->natureOfNumber = inBuf[1]; + digits->numberingPlan = (inBuf[2]>>4)&0xf; + digits->encoding = inBuf[2]&0xf; + digits->numberOfDigits = inBuf[3] % 20; + len = (inBuf[3]+1)/2; + memcpy(digits->digits, inBuf+4, len); + return len+4; +} + +u8 extract_ainparam(struct MapOprSrv_struct *opr_ptr,u8 opr_code,u8 opr_flag,u32 pre_param_len,u8 *pre_param) +{ + ASN_BUF asn_buf; + u8 param[1024]; + int param_len; + u32 *param_flag; + //char info_str[1024]; + + asn_decode(pre_param,1,&asn_buf); + param_len = get_tlv(SET_NATIONAL,param,&asn_buf); + + if (param_len == -1) // not has sequence id + { + param_len = pre_param_len; + memcpy(param,pre_param,param_len); + } + + opr_code &=0x7f; + + switch (opr_code) + { + case ProvideInstructionStart: + param_flag = &opr_ptr->msg_list.provideInstructionStart.param_flag; + param_len = get_tlv("18.10.4-1", param, &asn_buf); + if(param_len != -1) + { + *param_flag |= BIT0_TRUE; + memcpy(opr_ptr->msg_list.provideInstructionStart.calledPartyNumber+1, param, param_len); + opr_ptr->msg_list.provideInstructionStart.calledPartyNumber[0] = param_len; + } + else + { + xap_send_error("extract provideInstructionStart error, miss calledPartyNumber\n"); + } + param_len = get_tlv("18.4-2", param, &asn_buf); + if(param_len != -1) + { + *param_flag |= BIT1_TRUE; + memcpy(opr_ptr->msg_list.provideInstructionStart.callingPartyNumber+1, param, param_len); + opr_ptr->msg_list.provideInstructionStart.callingPartyNumber[0] = param_len; + }else + { + xap_send_error("extract provideInstructionStart error, miss callingPartyNumber\n"); + } + param_len = get_tlv("18.4-3", param, &asn_buf); + if(param_len != -1) + { + *param_flag |= BIT2_TRUE; + memcpy(opr_ptr->msg_list.provideInstructionStart.LATA+1, param, param_len); + opr_ptr->msg_list.provideInstructionStart.LATA[0] = param_len; + }else + { + xap_send_error("extract provideInstructionStart error, miss LATA\n"); + } + param_len = get_tlv("18.69", param, &asn_buf); + if(param_len != -1) + { + *param_flag |= BIT3_TRUE; + opr_ptr->msg_list.provideInstructionStart.OriginatingStationType = param[0]; + }else + { + xap_send_error("extract provideInstructionStart error, miss OriginatingStationType\n"); + } + + break; + case ConnectionControlConnect: + param_flag = &opr_ptr->msg_list.connectionControlConnect.param_flag; + param_len = get_tlv("18.4-1", param, &asn_buf); + if(param_len != -1) + { + *param_flag |= BIT0_TRUE; + memcpy(opr_ptr->msg_list.connectionControlConnect.CIC+1, param, param_len); + opr_ptr->msg_list.connectionControlConnect.CIC[0] = param_len; + } + else + { + xap_send_error("extract connectionControlConnect error, miss CIC\n"); + } + param_len = get_tlv("18.4-2", param, &asn_buf); + if(param_len != -1) + { + *param_flag |= BIT1_TRUE; + memcpy(opr_ptr->msg_list.connectionControlConnect.RoutingNumber+1, param, param_len); + opr_ptr->msg_list.connectionControlConnect.RoutingNumber[0] = param_len; + } + else + { + xap_send_error("extract connectionControlConnect error, miss RoutingNumber\n"); + return 0; + } + param_len = get_tlv("18.65", param, &asn_buf); + if(param_len != -1) + { + *param_flag |= BIT2_TRUE; + opr_ptr->msg_list.connectionControlConnect.BillingIndicator = param[0]; + } + else + { + xap_send_error("extract connectionControlConnect error, miss BillingIndicator\n"); + } + break; + default: + break; + + } + return 1; +} + diff --git a/plat/xapp/src/mapp/map_coding.h b/plat/xapp/src/mapp/map_coding.h new file mode 100644 index 0000000..06a22e8 --- /dev/null +++ b/plat/xapp/src/mapp/map_coding.h @@ -0,0 +1,546 @@ +/* MAP coding head file */ +/* written by Liu Zhiguo 2003-03-04 */ +/* version 2.0 */ +/* -------------------------------- */ + +#ifndef _MAP_CODING +#define _MAP_CODING + +/* define in map_code_ms.c */ +int assign_uplocarg(struct MapUL_Arg *ul_ptr,u8 *buf,u8 ver); +int extract_uplocarg(struct MapUL_Arg *ul_ptr,u32 buf_len,u8 *buf ,u8 ver); +int assign_uplocres(struct MapUL_Res *ul_ptr,u8 *buf); +int extract_uplocres(struct MapUL_Res *ul_ptr,u32 buf_len,u8 *buf); + + +/* ------------------------>>>>>>>>>>>>>>>> MAP v1 <<<<<<<<<<<<<<<<<<<<<<<<<----------------*/ + +//int assign_sendParameterres(struct MapSP_Res *sp_ptr,u8 *buf); +//int extract_sendParameterArg(struct MapSP_Arg *sp_ptr,u32 buf_len,u8 *buf,u32 dialogue_id); + +int assign_SendParaArg(struct MapSP_Arg *sendpara_ptr,u8 *buf); +int extract_SendParaArg(struct MapSP_Arg *sendpara_ptr,u32 buf_len,u8 *buf); +int assign_SendParaRes(struct MapSP_Res *sp_ptr,u8 *buf); +int extract_SendParaRes(struct MapSP_Res *sp_ptr,u32 buf_len,u8 *buf); + +int assign_NotPresentArg(struct MapNP_Arg *np_ptr, u8 *buf); +int extract_NotPresentArg( struct MapNP_Arg *np_ptr,u32 buf_len,u8 *buf) ; + +int assign_ProcessUSSDArg(struct MapPUSSD_Arg *ussd_ptr, u8 *buf); +int extract_ProcessUSSDArg( struct MapPUSSD_Arg *ussd_ptr,u32 buf_len,u8 *buf); +int assign_ProcessUSSDRes(struct MapPUSSD_Res *ussd_ptr, u8 *buf) ; +int extract_ProcessUSSDRes( struct MapPUSSD_Res *ussd_ptr,u32 buf_len,u8 *buf); + +int assign_SAArg(struct MapSA_Arg *sa_ptr, u8 *buf) ; +int extract_SAArg( struct MapSA_Arg *sa_ptr,u32 buf_len,u8 *buf); + +int assign_HOArg(struct MapHO_Arg *ho_ptr, u8 *buf) ; +int extract_HOArg( struct MapHO_Arg *ho_ptr,u32 buf_len,u8 *buf); +int assign_HORes(struct MapHO_Res *ho_ptr, u8 *buf) ; +int extract_HORes( struct MapHO_Res *ho_ptr,u32 buf_len,u8 *buf); + +int assign_PFSHOArg(struct MapPFSHO_Arg *psho_ptr, u8 *buf); +int extract_PFSHOArg( struct MapPFSHO_Arg *psho_ptr,u32 buf_len,u8 *buf); +int assign_PFSHORes(struct MapPFSHO_Res *psho_ptr,u8 *buf); +int extract_PFSHORes(struct MapPFSHO_Res *psho_ptr,u32 buf_len,u8 *buf); + +int assign_NIHOArg(struct MapNIHO_Arg *niho_ptr, u8 *buf) ; +int extract_NIHOArg( struct MapNIHO_Arg *niho_ptr,u32 buf_len,u8 *buf); + +int assign_TSAArg(struct MapTSA_Arg *tsa_ptr, u8 *buf); +int extract_TSAArg( struct MapTSA_Arg *TSA_ptr,u32 buf_len,u8 *buf); + +int assign_BSAArg(struct MapBSA_Arg *bsa_ptr, u8 *buf); +int extract_BSAArg( struct MapBSA_Arg *bsa_ptr,u32 buf_len,u8 *buf); + + +int assign_routinfoforsm_v1_arg(struct MapRIFSMV1_Arg *rif_ptr,u8 *buf); +int extract_routinfoforsm_v1_arg(struct MapRIFSMV1_Arg *rif_ptr,u32 buf_len,u8 *buf); +int assign_routinfoforsm_v1_res(struct MapRIFSMV1_Res *rif_ptr,u8 *buf); +int extract_routinfoforsm_v1_res(struct MapRIFSMV1_Res *rif_ptr,u32 buf_len,u8 *buf); + + +int assign_fwdsmarg(struct MapFSM_Arg *ptr,u8 *buf); +int extract_fwdsmarg(struct MapFSM_Arg *ptr,u32 buf_len,u8 *buf); + +int assign_cancellocarg(struct MapCL_Arg *cl_ptr,u8 *buf,u8 ver); +int extract_cancellocarg(struct MapCL_Arg *cl_ptr,u32 buf_len,u8 *buf,u8 ver); +int assign_cancellocres(struct MapCL_Res *cl_ptr,u8 *buf); +int extract_cancellocres(struct MapCL_Res *cl_ptr,u32 buf_len,u8 *buf); +/* ------------------------>>>>>>>>>>>>>>>> MAP v1 <<<<<<<<<<<<<<<<<<<<<<<<<----------------*/ + +int assign_purgemsarg(struct MapPMS_Arg *pms_ptr,u8 *buf,u8 version); +int extract_purgemsarg(struct MapPMS_Arg *pms_ptr,u32 buf_len,u8 *buf,u8 version); +int assign_purgemsres(struct MapPMS_Res *pms_ptr,u8 *buf); +int extract_purgemsres(struct MapPMS_Res *pms_ptr,u32 buf_len,u8 *buf); + +int assign_sndidentarg(struct MapSI_Arg *ptr,u8 *buf); +int extract_sndidentarg(struct MapSI_Arg *ptr,u32 buf_len,u8 *buf); +int assign_sndidentres(struct MapSI_Res *ptr,u8 *buf); +int extract_sndidentres(struct MapSI_Res *ptr,u32 buf_len,u8 *buf); + +int assign_upgprslocarg(struct MapUGL_Arg *ugl_ptr,u8 *buf); +int extract_upgprslocarg(struct MapUGL_Arg *ugl_ptr,u32 buf_len,u8 *buf); +int assign_upgprslocres(struct MapUGL_Res *ugl_ptr,u8 *buf); +int extract_upgprslocres(struct MapUGL_Res *ugl_ptr,u32 buf_len,u8 *buf); + +int assign_prvsubinfoarg(struct MapPSI_Arg *psi_ptr,u8 *buf); +int extract_prvsubinfoarg(struct MapPSI_Arg *psi_ptr,u32 buf_len,u8 *buf); +int assign_prvsubinfores(struct MapPSI_Res *psi_ptr,u8 *buf); +int extract_prvsubinfores(struct MapPSI_Res *psi_ptr,u32 buf_len,u8 *buf); + +int assign_anytimeintarg(struct MapATI_Arg *ati_ptr,u8 *buf); +int extract_anytimeintarg(struct MapATI_Arg *ati_ptr,u32 buf_len,u8 *buf); +int assign_anytimeintres(struct MapATI_Res *ati_ptr,u8 *buf); +int extract_anytimeintres(struct MapATI_Res *ati_ptr,u32 buf_len,u8 *buf); + +int assign_anytimesubintarg(struct MapATSI_Arg *atsi_ptr,u8 *buf); +int extract_anytimesubintarg(struct MapATSI_Arg *atsi_ptr,u32 buf_len,u8 *buf); +int assign_anytimesubintres(struct MapATSI_Res *atsi_ptr,u8 *buf); +int extract_anytimesubintres(struct MapATSI_Res *atsi_ptr,u32 buf_len,u8 *buf); + +int assign_authfailreportarg(MapAuthFailReport_Arg *fail_ptr, u8 *buf); +int extract_authfailreportarg(MapAuthFailReport_Arg *fail_ptr, u32 buf_len, u8 *buf); + +int assign_prehoarg(struct MapPHO_Arg *pho_ptr,u8 *buf); +int extract_prehoarg(struct MapPHO_Arg *pho_ptr,u32 buf_len,u8 *buf); +int assign_prehores(struct MapPHO_Res *pho_ptr,u8 *buf); +int extract_prehores(struct MapPHO_Res *pho_ptr,u32 buf_len,u8 *buf); + +int assign_sndendsigarg(struct MapSES_Arg *ses_ptr,u8 *buf); +int extract_sndendsigarg(struct MapSES_Arg *ses_ptr,u32 buf_len,u8 *buf); + +int assign_prcaccsigarg(struct MapPAS_Arg *pas_ptr,u8 *buf); +int extract_prcaccsigarg(struct MapPAS_Arg *pas_ptr,u32 buf_len,u8 *buf); + +int assign_fwdaccsigarg(struct MapFAS_Arg *fas_ptr,u8 *buf); +int extract_fwdaccsigarg(struct MapFAS_Arg *fas_ptr,u32 buf_len,u8 *buf); + +int assign_presubshoarg(struct MapPSHO_Arg *psho_ptr,u8 *buf); +int extract_presubshoarg(struct MapPSHO_Arg *psho_ptr,u32 buf_len,u8 *buf); +int assign_presubshores(struct MapPSHO_Res *psho_ptr,u8 *buf); +int extract_presubshores(struct MapPSHO_Res *psho_ptr,u32 buf_len,u8 *buf); + +int assign_sndauthinfoarg(struct MapSAI_Arg *sai_ptr,u8 *buf, u8 version); //modify by gxchen +int assign_sndauthinfores(struct MapSAI_Res *sai_ptr,u8 *buf, u8 version); +int extract_sndauthinfoarg(struct MapSAI_Arg *sai_ptr,u32 buf_len,u8 *buf, u8 version); +int extract_sndauthinfores(struct MapSAI_Res *sai_ptr,u32 buf_len,u8 *buf, u8 version); + +int assign_chkimeiarg(struct MapCIMEI_Arg *ptr,u8 *buf); +int extract_chkimeiarg(struct MapCIMEI_Arg *ptr,u32 buf_len,u8 *buf); +int assign_chkimeires(struct MapCIMEI_Res *ptr,u8 *buf); +int extract_chkimeires(struct MapCIMEI_Res *ptr,u32 buf_len,u8 *buf); + +int assign_inssubdataarg(struct MapISD_Arg *isd_ptr,u8 *buf,u8 version); +int assign_inssubdatares(struct MapISD_Res *isd_ptr,u8 *buf); +int extract_inssubdataarg(struct MapISD_Arg *isd_ptr,u32 buf_len,u8 *buf); +int extract_inssubdatares(struct MapISD_Res *isd_ptr,u32 buf_len,u8 *buf); + +int assign_delsubdataarg(struct MapDSD_Arg *dsd_ptr,u8 *buf); +int extract_delsubdataarg(struct MapDSD_Arg *dsd_ptr,u32 buf_len,u8 *buf); +int assign_delsubdatares(struct MapDSD_Res *dsdr_ptr,u8 *buf); +int extract_delsubdatares(struct MapDSD_Res *dsdr_ptr,u32 buf_len,u8 *buf); + +int assign_resetarg(struct MapReset_Arg *rs_ptr,u8 *buf); +int extract_resetarg(struct MapReset_Arg *rs_ptr,u32 buf_len,u8 *buf); + +int assign_restdataarg(struct MapRD_Arg *rsd_ptr,u8 *buf); +int extract_restdataarg(struct MapRD_Arg *rsd_ptr,u32 buf_len,u8 *buf); +int assign_restdatares(struct MapRD_Res *rsd_ptr,u8 *buf); +int extract_restdatares(struct MapRD_Res *rsd_ptr,u32 buf_len,u8 *buf); + +int assign_sndroutinfogprsarg(struct MapSRIFG_Arg *sfg_ptr,u8 *buf); +int extract_sndroutinfogprsarg(struct MapSRIFG_Arg *sfg_ptr,u32 buf_len,u8 *buf); +int assign_sndroutinfogprsres(struct MapSRIFG_Res *sfg_ptr,u8 *buf); +int extract_sndroutinfogprsres(struct MapSRIFG_Res *sfg_ptr,u32 buf_len,u8 *buf); + +int assign_failreportarg(struct MapFR_Arg *fr_ptr,u8 *buf); +int extract_failreportarg(struct MapFR_Arg *fr_ptr,u32 buf_len,u8 *buf); +int assign_failreportres(struct MapFR_Res *fr_ptr,u8 *buf); +int extract_failreportres(struct MapFR_Res *fr_ptr,u32 buf_len,u8 *buf); + +int assign_notemspregprsarg(struct MapNMPFG_Arg *npg_ptr,u8 *buf); +int extract_notemspregprsarg(struct MapNMPFG_Arg *npg_ptr,u32 buf_len,u8 *buf); +int assign_notemspregprsres(struct MapNMPFG_Res *npg_ptr,u8 *buf); +int extract_notemspregprsres(struct MapNMPFG_Res *npg_ptr,u32 buf_len,u8 *buf); + +/* define in map_code_om.c */ +int assign_acttrcmodearg(struct MapATM_Arg *atm_ptr,u8 *buf); +int extract_acttrcmodearg(struct MapATM_Arg *atm_ptr,u32 buf_len,u8 *buf); +int assign_acttrcmoderes(struct MapATM_Res *atm_ptr,u8 *buf); +int extract_acttrcmoderes(struct MapATM_Res *atm_ptr,u32 buf_len,u8 *buf); + +int assign_deacttrcmodearg(struct MapDTM_Arg *dtm_ptr,u8 *buf); +int extract_deacttrcmodearg(struct MapDTM_Arg *dtm_ptr,u32 buf_len,u8 *buf); +int assign_deacttrcmoderes(struct MapDTM_Res *dtm_ptr,u8 *buf); +int extract_deacttrcmoderes(struct MapDTM_Res *dtm_ptr,u32 buf_len,u8 *buf); + +int assign_sndimsiarg(struct MapSIMSI_Arg *sim_ptr,u8 *buf); +int extract_sndimsiarg(struct MapSIMSI_Arg *sim_ptr,u32 buf_len,u8 *buf); +int assign_sndimsires(struct MapSIMSI_Res *sim_ptr,u8 *buf); +int extract_sndimsires(struct MapSIMSI_Res *sim_ptr,u32 buf_len,u8 *buf); + +/* define in map_code_ch.c */ +int assign_sndroutinfoarg(struct MapSRI_Arg *sri_ptr,u8 *buf,u8 ver); +int assign_sndroutinfores(struct MapSRI_Res *sri_ptr,u8 *buf,u8 version); +int extract_sndroutinfoarg(struct MapSRI_Arg *sri_ptr,u32 buf_len,u8 *buf,u8 ver); +int extract_sndroutinfores(struct MapSRI_Res *sri_ptr,u32 buf_len,u8 *buf,u8 version); + +int assign_provroamnumarg(struct MapPRN_Arg *prn_ptr, u8 *buf); +int assign_provroamnumres(struct MapPRN_Res *prn_ptr, u8 *buf); +int extract_provroamnumarg(struct MapPRN_Arg *prn_ptr,u32 buf_len,u8 *buf); +int extract_provroamnumres(struct MapPRN_Res *prn_ptr,u32 buf_len,u8 *buf); + +int assign_rescallhandarg(struct MapRCH_Arg *rch_ptr,u8 *buf); +int extract_rescallhandarg(struct MapRCH_Arg *rch_ptr,u32 buf_len,u8 *buf); +int assign_rescallhandres(struct MapRCH_Res *rch_ptr,u8 *buf); +int extract_rescallhandres(struct MapRCH_Res *rch_ptr,u32 buf_len,u8 *buf); + +int assign_prvsiwfsnumarg(struct MapPSN_Arg *psn_ptr,u8 *buf); +int extract_prvsiwfsnumarg(struct MapPSN_Arg *psn_ptr,u32 buf_len,u8 *buf); +int assign_prvsiwfsnumres(struct MapPSN_Res *psn_ptr,u8 *buf); +int extract_prvsiwfsnumres(struct MapPSN_Res *psn_ptr,u32 buf_len,u8 *buf); + +int assign_siwfssigmodarg(struct MapSSM_Arg *ssm_ptr,u8 *buf); +int extract_siwfssigmodarg(struct MapSSM_Arg *ssm_ptr,u32 buf_len,u8 *buf); +int assign_siwfssigmodres(struct MapSSM_Res *ssm_ptr,u8 *buf); +int extract_siwfssigmodres(struct MapSSM_Res *ssm_ptr,u32 buf_len,u8 *buf); + +int assign_setrepstatearg(struct MapSRS_Arg *srs_ptr,u8 *buf); +int extract_setrepstatearg(struct MapSRS_Arg *srs_ptr,u32 buf_len,u8 *buf); +int assign_setrepstateres(struct MapSRS_Res *srs_ptr,u8 *buf); +int extract_setrepstateres(struct MapSRS_Res *srs_ptr,u32 buf_len,u8 *buf); + +int assign_statreparg(struct MapSR_Arg *sr_ptr,u8 *buf); +int extract_statreparg(struct MapSR_Arg *sr_ptr,u32 buf_len,u8 *buf); +int assign_statrepres(struct MapSR_Res *sr_ptr,u8 *buf); +int extract_statrepres(struct MapSR_Res *sr_ptr,u32 buf_len,u8 *buf); + +int assign_rmtuserfreearg(struct MapRUF_Arg *ruf_ptr,u8 *buf); +int extract_rmtuserfreearg(struct MapRUF_Arg *ruf_ptr,u32 buf_len,u8 *buf); +int assign_rmtuserfreeres(struct MapRUF_Res *ruf_ptr,u8 *buf); +int extract_rmtuserfreeres(struct MapRUF_Res *ruf_ptr,u32 buf_len,u8 *buf); + +int assign_istalertarg(struct MapISTAlert_Arg *ista_ptr, u8 *buf); +int extract_istalertarg(struct MapISTAlert_Arg *ista_ptr, u32 buf_len, u8 *buf); +int assign_istalertres(struct MapISTAlert_Res *ista_ptr, u8 *buf); +int extract_istalertres(struct MapISTAlert_Res *ista_ptr, u32 buf_len, u8 *buf); + +int assign_istcmdarg(struct MapISTCmd_Arg *istc_ptr, u8 *buf); +int extract_istcmdarg(struct MapISTCmd_Arg *istc_ptr, u32 buf_len, u8 *buf); +//int assign_istcmdres(struct MapISTCmd_Res *istc_ptr,u8 *buf); +//int extract_istcmdres(struct MapISTCmd_Res *istc_ptr,u32 buf_len,u8 *buf); + +/* define in map_code_ss.c */ +int assign_regssarg(struct MapRSS_Arg *rss_ptr, u8 *buf); +int extract_regssarg(struct MapRSS_Arg *rss_ptr,u32 buf_len,u8 *buf); +int assign_regssres(struct MapRSS_Res *rss_ptr, u8 *buf); +int extract_regssres(struct MapRSS_Res *rss_ptr,u32 buf_len,u8 *buf); + +int assign_erassarg(struct MapESS_Arg *ess_ptr, u8 *buf); +int extract_erassarg(struct MapESS_Arg *ess_ptr,u32 buf_len,u8 *buf); +int assign_erassres(struct MapESS_Res *essr_ptr, u8 *buf); +int extract_erassres(struct MapESS_Res *essr_ptr,u32 buf_len,u8 *buf); + +int assign_actssarg(struct MapASS_Arg *ass_ptr, u8 *buf); +int extract_actssarg(struct MapASS_Arg *ass_ptr,u32 buf_len,u8 *buf); +int assign_actssres(struct MapASS_Res *assr_ptr, u8 *buf); +int extract_actssres(struct MapASS_Res *assr_ptr,u32 buf_len,u8 *buf); + +int assign_deactssarg(struct MapDASS_Arg *dss_ptr, u8 *buf); +int extract_deactssarg(struct MapDASS_Arg *dss_ptr,u32 buf_len,u8 *buf); +int assign_deactssres(struct MapDASS_Res *dssr_ptr, u8 *buf); +int extract_deactssres(struct MapDASS_Res *dssr_ptr,u32 buf_len,u8 *buf); + +int assign_intrssarg(struct MapINTSS_Arg *intrss_ptr, u8 *buf); +int extract_intrssarg(struct MapINTSS_Arg *intr_ptr,u32 buf_len,u8 *buf); +int assign_intrssres(struct MapINTSS_Res *intrss_ptr, u8 *buf); +int extract_intrssres(struct MapINTSS_Res *intrss_ptr,u32 buf_len,u8 *buf); + +int assign_prcunssreqarg(struct MapPUSSR_Arg *psr_ptr,u8 *buf); +int extract_prcunssreqarg(struct MapPUSSR_Arg *psr_ptr,u32 buf_len,u8 *buf); +int assign_prcunssreqres(struct MapPUSSR_Res *psr_ptr,u8 *buf); +int extract_prcunssreqres(struct MapPUSSR_Res *psr_ptr,u32 buf_len,u8 *buf); + +int assign_unssreqarg(struct MapUSSR_Arg *usr_ptr,u8 *buf); +int extract_unssreqarg(struct MapUSSR_Arg *usr_ptr,u32 buf_len,u8 *buf); +int assign_unssreqres(struct MapUSSR_Res *usr_ptr,u8 *buf); +int extract_unssreqres(struct MapUSSR_Res *usr_ptr,u32 buf_len,u8 *buf); + +int assign_unssnotarg(struct MapUSSN_Arg *usn_ptr,u8 *buf); +int extract_unssnotarg(struct MapUSSN_Arg *usn_ptr,u32 buf_len,u8 *buf); +int assign_unssnotres(struct MapUSSN_Res *usn_ptr,u8 *buf); +int extract_unssnotres(struct MapUSSN_Res *usn_ptr,u32 buf_len,u8 *buf); + +int assign_regpswdarg(struct MapRPSS_Arg *rpw_ptr,u8 *buf); +int extract_regpswdarg(struct MapRPSS_Arg *rpw_ptr,u32 buf_len,u8 *buf); +int assign_regpswdres(struct MapRPSS_Res *rpwr_ptr,u8 *buf); +int extract_regpswdres(struct MapRPSS_Res *rpwr_ptr,u32 buf_len,u8 *buf); + +int assign_getpswdarg(struct MapGPSS_Arg *gpw_ptr,u8 *buf); +int extract_getpswdarg(struct MapGPSS_Arg *gpw_ptr,u32 buf_len,u8 *buf); +int assign_getpswdres(struct MapGPSS_Res *rpwr_ptr,u8 *buf); +int extract_getpswdres(struct MapGPSS_Res *rpwr_ptr,u32 buf_len,u8 *buf); + +int assign_ssinvnotarg(struct MapSSIN_Arg *sin_ptr,u8 *buf); +int extract_ssinvnotarg(struct MapSSIN_Arg *sin_ptr,u32 buf_len,u8 *buf); +int assign_ssinvnotres(struct MapSSIN_Res *sin_ptr,u8 *buf); +int extract_ssinvnotres(struct MapSSIN_Res *sin_ptr,u32 buf_len,u8 *buf); + +int assign_regccentarg(struct MapRCCE_Arg *rce_ptr,u8 *buf); +int extract_regccentarg(struct MapRCCE_Arg *rce_ptr,u32 buf_len,u8 *buf); +int assign_regccentres(struct MapRCCE_Res *rce_ptr,u8 *buf); +int extract_regccentres(struct MapRCCE_Res *rce_ptr,u32 buf_len,u8 *buf); + +int assign_eraseccentarg(struct MapECCE_Arg *ece_ptr,u8 *buf); +int extract_eraseccentarg(struct MapECCE_Arg *ece_ptr,u32 buf_len,u8 *buf); +int assign_eraseccentres(struct MapECCE_Res *ece_ptr,u8 *buf); +int extract_eraseccentres(struct MapECCE_Res *ece_ptr,u32 buf_len,u8 *buf); + +/* define in map_code_sms.c */ +int assign_routinfoforsmarg(struct MapRIFSM_Arg *rif_ptr,u8 *buf); +int extract_routinfoforsmarg(struct MapRIFSM_Arg *rif_ptr,u32 buf_len,u8 *buf); +int assign_routinfoforsmres(struct MapRIFSM_Res *rif_ptr,u8 *buf); +int extract_routinfoforsmres(); + +int assign_mofwdsmarg(struct MapMOFSM_Arg *ptr,u8 *buf,u8 version); +int extract_mofwdsmarg(struct MapMOFSM_Arg *ptr,u32 buf_len,u8 *buf,u8 version); +int assign_mofwdsmres(struct MapMOFSM_Res *ptr,u8 *buf,u8 version); +int extract_mofwdsmres(struct MapMOFSM_Res *ptr,u32 buf_len,u8 *buf); + +int assign_mtfwdsmarg(struct MapMTFSM_Arg *ptr,u8 *buf,u8 MAPVer); +int extract_mtfwdsmarg(struct MapMTFSM_Arg *ptr,u32 buf_len,u8 *buf,u8 MAPVer); +int assign_mtfwdsmres(struct MapMTFSM_Res *ptr,u8 *buf,u8 MAPVer); +int extract_mtfwdsmres(struct MapMTFSM_Res *ptr,u32 buf_len,u8 *buf,u8 MAPVer); + +int assign_repsmdelstatarg(struct MapRSMDS_Arg *ptr,u8 *buf); +int extract_repsmdelstatarg(struct MapRSMDS_Arg *ptr,u32 buf_len,u8 *buf); +int assign_repsmdelstatres(struct MapRSMDS_Res *ptr,u8 *buf); +int extract_repsmdelstatres(struct MapRSMDS_Res *ptr,u32 buf_len,u8 *buf); + +int assign_infsrvcentarg(struct MapISC_Arg *ptr,u8 *buf); +int extract_infsrvcentarg(struct MapISC_Arg *ptr,u32 buf_len,u8 *buf); + +int assign_altsrvcentarg(struct MapASC_Arg *ptr,u8 *buf); +int extract_altsrvcentarg(struct MapASC_Arg *ptr,u32 buf_len,u8 *buf); + +int assign_rdyforsmarg(struct MapRFSM_Arg *ptr,u8 *buf); +int extract_rdyforsmarg(struct MapRFSM_Arg *ptr,u32 buf_len,u8 *buf); +int assign_rdyforsmres(struct MapRFSM_Res *ptr,u8 *buf); +int extract_rdyforsmres(struct MapRFSM_Res *ptr,u32 buf_len,u8 *buf); + +/* +++++++++++++++++++++++++++++ */ +/* MAP-H (with AUC) structure */ +/* +++++++++++++++++++++++++++++ */ +int assign_securityTriplets_arg(struct MapST_Arg *ptr,u8 *buf, u8 version); +int extract_securityTriplets_arg(struct MapST_Arg *ptr,u32 buf_len,u8 *buf, u8 version); +int assign_securityTriplets_res(); +int extract_securityTriplets_res(); + +int assign_interrogateSubscriber_arg(); +int extract_interrogateSubscriber_arg(); + +int assign_createSubscriber_arg(); +int extract_createSubscriber_arg(); + +int assign_deleteSubscriber_arg(); +int extract_deleteSubscriber_arg(); + +/* ++++++++++++ */ +/* Common types */ +/* ++++++++++++ */ +int assign_authset(struct AuthSet_struct *auth_ptr,u8 *buf); +int extract_authset(struct AuthSet_struct *auth_ptr,u32 buf_len,u8 *buf); +//add by gxchen start +int assign_triplet(Triplet_st *auth_ptr,u8 *buf); +int extract_triplet(Triplet_st *auth_ptr,u32 buf_len,u8 *buf); +int assign_quintuplet(Quintuplet_st *auth_ptr,u8 *buf); +int extract_quintuplet(Quintuplet_st *auth_ptr,u32 buf_len,u8 *buf); +int assign_gsmSecCon(GsmSecCon_st *con_ptr,u8 *buf); +int extract_gsmSecCon(GsmSecCon_st *con_ptr,u32 buf_len,u8 *buf); +int assign_umtsSecCon(UmtsSecCon_st *con_ptr,u8 *buf); +int extract_umtsSecCon(UmtsSecCon_st *con_ptr,u32 buf_len,u8 *buf); +int assign_authReSynInfo(AuthReSynInfo_st *resyn_ptr,u8 *buf); +int extract_authReSynInfo(AuthReSynInfo_st *resyn_ptr,u32 buf_len,u8 *buf); +int assign_sgsnCapability(struct SgsnCap_s *cap_ptr, u8 *buf); +int extract_sgsnCapability(struct SgsnCap_s *cap_ptr, u32 buf_len, u8 *buf); +//add by gxchen end + +int assign_extsiginfo(struct ExtSigInfo_struct *sig_ptr,u8 *buf); +int extract_extsiginfo(struct ExtSigInfo_struct *sig_ptr,u32 buf_len,u8 *buf); +int assign_bscode(struct BSCode_struct *bs_ptr,u8 *buf,u8 flag); +int extract_bscode(struct BSCode_struct *bs_ptr,u32 buf_len,u8 *buf); +int assign_subinfo(struct SubInfo_struct *info_ptr,u8 *buf); +int extract_subinfo(struct SubInfo_struct *info_ptr,u32 buf_len,u8 *buf); +int assign_ocsi(struct OCsi_struct *ocsi_ptr,u8 *buf); +int extract_ocsi(struct OCsi_struct *ocsi_ptr,u32 buf_len,u8 *buf); +int assign_tdpcritlist(struct OBCritLst_struct *list_ptr,u8 *buf); +int extract_tdpcritlist(struct OBCritLst_struct *list_ptr,u32 buf_len,u8 *buf); +int assign_ccbsfeat(struct CcbsFeat_struct *cf_ptr,u8 *buf); +int extract_ccbsfeat(struct CcbsFeat_struct *cf_ptr,u32 buf_len,u8 *buf); + +/* is41 */ +int assign_is41AuthenticationDirective_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41AuthenticationDirective_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int extract_is41AuthenticationDirective_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41AuthenticationDirective_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int assign_is41AuthenticationDirectiveForward_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41AuthenticationFailureReport_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41AuthenticationFailureReport_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41AuthenticationRequest_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41AuthenticationRequest_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41AuthenticationStatusReport_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41AuthenticationStatusReport_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41BaseStationChallenge_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41BaseStationChallenge_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41CountRequest_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_is41CountRequest_rsp(struct MapOprSrv_struct *ptr,u8 *buf); + +int extract_is41AuthenticationDirectiveForward_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41AuthenticationFailureReport_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41AuthenticationFailureReport_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41AuthenticationRequest_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41AuthenticationRequest_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41AuthenticationStatusReport_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41AuthenticationStatusReport_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41BaseStationChallenge_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41BaseStationChallenge_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41CountRequest_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_is41CountRequest_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); + + +int assign_Is41SmsDeliveryBackward_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsDeliveryBackward_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsDeliveryForward_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsDeliveryForward_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsDeliveryPointToPoint_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsDeliveryPointToPoint_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsNotification_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsNotification_rsp(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsRequest_arg(struct MapOprSrv_struct *ptr,u8 *buf); +int assign_Is41SmsRequest_rsp(struct MapOprSrv_struct *ptr,u8 *buf); + +int extract_Is41SmsDeliveryBackward_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsDeliveryBackward_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsDeliveryForward_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsDeliveryForward_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsDeliveryPointToPoint_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsDeliveryPointToPoint_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsNotification_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsNotification_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsRequest_arg(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); +int extract_Is41SmsRequest_rsp(struct MapOprSrv_struct *ptr,u32 buf_len,u8 *buf); + +int assign_is41RegistrationNotification_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41RegistrationNotification_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41RegistrationCancellation_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41RegistrationCancellation_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41LocationRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41LocationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41RoutingRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41RoutingRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41MSInactive_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41MSInactive_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41FeatureRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41FeatureRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41QualificationDirective_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41QualificationDirective_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41TransferToNumberRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41TransferToNumberRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41RedirectionRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41RedirectionRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41OriginationRequest_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41OriginationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41AnalyzedInformation_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41AnalyzedInformation_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41OAnswer_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41ODisconnect_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41ODisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41TAnswer_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41TDisconnect_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41TDisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41CallControlDirective_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41CallControlDirective_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41SeizeResource_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41SeizeResource_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41ConnectResource_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41SRFDirective_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41SRFDirective_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41ShortMessageAnalyzed_arg(struct MapOprSrv_struct *opr_ptr,u8 *buf); +int assign_is41ShortMessageAnalyzed_rsp(struct MapOprSrv_struct *opr_ptr,u8 *buf); + +int extract_is41RegistrationNotification_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41RegistrationNotification_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41RegistrationCancellation_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41RegistrationCancellation_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41LocationRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41LocationRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41RoutingRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41RoutingRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41MSInactive_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41MSInactive_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41FeatureRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41FeatureRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41QualificationDirective_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41QualificationDirective_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41TransferToNumberRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41TransferToNumberRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41RedirectionRequest_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41RedirectionRequest_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41OriginationRequest_arg(struct MapOprSrv_struct *opr_ptr, u32 buf_len, u8 *buf); +int extract_is41OriginationRequest_rsp(struct MapOprSrv_struct *opr_ptr, u32 buf_len, u8 *buf); +int extract_is41AnalyzedInformation_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41AnalyzedInformation_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41OAnswer_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41ODisconnect_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41ODisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41TAnswer_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41TDisconnect_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41TDisconnect_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41CallControlDirective_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41CallControlDirective_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41SeizeResource_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41SeizeResource_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41ConnectResource_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41SRFDirective_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41SRFDirective_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41ShortMessageAnalyzed_arg(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); +int extract_is41ShortMessageAnalyzed_rsp(struct MapOprSrv_struct *opr_ptr,u32 buf_len,u8 *buf); + + +/***************** LCS **************/ +int assign_ProvideSubscriberLocation_Res(ProvideSubscriberLocation_Res *ptr,u8 *buf, u8 ver); +int assign_RoutingInfoForLCS_Res(RoutingInfoForLCS_Res *ptr,u8 *buf, u8 ver); +int extract_ProvideSubscriberLocation_Arg(ProvideSubscriberLocation_Arg *ptr,u32 buf_len,u8 *buf); +int extract_RoutingInfoForLCS_Arg(RoutingInfoForLCS_Arg *ptr,u32 buf_len,u8 *buf); +/***************** LCS **************/ + +//show message +int debug_show_REGNOT_ARG(struct IS41_REGNOT_ARG *ptr,char *buf); +int debug_show_REGNOT_RSP(struct IS41_REGNOT_RSP *ptr,char *buf); +int debug_show_LOCREQ_ARG(struct IS41_LOCREQ_ARG *ptr,char *buf); +int debug_show_LOCREQ_RSP(struct IS41_LOCREQ_RSP *ptr,char *buf); +int debug_show_ROUTREQ_ARG(struct IS41_ROUTREQ_ARG *ptr,char *buf); +int debug_show_ROUTREQ_RSP(struct IS41_ROUTREQ_RSP *ptr,char *buf); +int debug_show_TRANUMREQ_ARG(struct IS41_TRANUMREQ_ARG *ptr,char *buf); +int debug_show_TRANUMREQ_RSP(struct IS41_TRANUMREQ_RSP *ptr,char *buf); +int debug_show_SMSREQ_ARG(struct IS41_SMSREQ_ARG *ptr,char *buf); +int debug_show_SMSREQ_RSP(struct IS41_SMSREQ_RSP *ptr,char *buf); +int debug_show_MSINACT_ARG(struct IS41_MSINACT_ARG *ptr,char *buf); +int debug_show_MSINACT_RSP(struct IS41_MSINACT_RSP *ptr,char *buf); +int debug_show_FEATREQ_ARG(struct IS41_FEATREQ_ARG *ptr,char *buf); +int debug_show_FEATREQ_RSP(struct IS41_FEATREQ_RSP *ptr,char *buf); + +int debug_show_AUTHREQ_ARG(IS41_AUTHREQ_ARG *AUTHREQ,char *charOpr); +int debug_show_authreq_rsp(IS41_AUTHREQ_RSP *authreq,char *charOpr); +int debug_show_ASREPORT_ARG(IS41_ASREPORT_ARG *ASREPORT,char *charOpr); +int debug_show_asreport_rsp(IS41_ASREPORT_RSP *asreport,char *charOpr); +int debug_show_BSCHALL_ARG(IS41_BSCHALL_ARG *BSCHALL,char *charOpr); +int debug_show_bschall_rsp(IS41_BSCHALL_RSP *bschall,char *charOpr); +int debug_show_AFREPORT_ARG(IS41_AFREPORT_ARG *AFREPORT,char *charOpr); +int debug_show_afreport_rsp(IS41_AFREPORT_RSP *afreport,char *charOpr); +int auc_debug_show_COUNTREQ_ARG(IS41_COUNTREQ_ARG *COUNTREQ,char *charOpr); +int auc_debug_show_countreq_rsp(IS41_COUNTREQ_RSP *countreq,char *charOpr); +int auc_debug_show_AUTHDIR_ARG(IS41_AUTHDIR_ARG *AUTHDIR,char *charOpr); +int auc_debug_show_authdir_rsp(IS41_AUTHDIR_RSP *authdir,char *charOpr); +#endif diff --git a/plat/xapp/src/mapp/map_const.h b/plat/xapp/src/mapp/map_const.h new file mode 100644 index 0000000..ada26b7 --- /dev/null +++ b/plat/xapp/src/mapp/map_const.h @@ -0,0 +1,1353 @@ +/* MAP const define head file */ + +/* written by Liu Zhiguo 2002-01-09 */ + +/* Version 1.0 */ + +/* -------------------------------- */ + +#ifndef _MAP_CONST + +#define _MAP_CONST + + + +#define MAX_TCAPSEND_LEN (TCAP_PARAM_LEN-20) + +#define MAX_TCAPSEND_LEN_1 (TCAP_PARAM_LEN_1-20) + +#define HLR_SSN 6 + +#define VLR_SSN 7 + +#define MSC_SSN 8 + +#define EIR_SSN 9 + +#define AUC_SSN 10 + +#define SMSC_SSN 11 + +#define GMLC_SSN 0x91 + +#define SCF_SSN 0x93 + +#define SIWF_SSN 0x94 + +#define SGSN_SSN 0x95 + +#define GGSN_SSN 0x96 + +#define SCF_SSN_USSD 0x99 + +#define OPPS_SSN 33 + +/* timer values definition, according GSM 09.02 14.1.2 */ + +#define SmallTimer 5 + +#define MediumTimer 20 + +#define MLongTimer 60 + +#define LongTimer 108000 + + + +/* Address string coding, according GSM 09.02 14.7.8 */ + +/* extension indicator */ + +#define ADD_NOEXT 0x80 // no extension + +/* nature of address indicator */ + +#define ADD_NAT_INTER 0x10 // international number + +#define ADD_NAT_NATSIG 0x20 // national significant number + +#define ADD_NAT_NETSPE 0x30 // network specific number + +#define ADD_NAT_SUB 0x40 // subscriber number + +#define ADD_NAT_ABBR 0x60 // abbreviated number + +/* numbering plan indicator */ + +#define ADD_PLAN_ISDN 0x01 // ISDN/Teliphony numbering plan (CCITT E.164) + +#define ADD_PLAN_DATA 0x03 // data numbering plan (CCITT X.121) + +#define ADD_PLAN_TELEX 0x04 // telex numbering plan (CCITT F.69) + +#define ADD_PLAN_LANDM 0x06 // land mobile numbering plan (CCITT E.212) + +#define ADD_PLAN_NATIONAL 0x08 // national numbering plan + +#define ADD_PLAN_PRIV 0x09 //private numbering plan + + + +/* define the all kinds of parameter length */ + +#define SSDATA_NUM 16 + +#define SIGNALINFO_LEN 200 + +#define ADDRESS_LEN 20 + +#define ASCI_LEN 8 // ASCI call reference length + +#define ISDN_LEN 9 + +#define ISDNSUB_LEN 21 // ISDN subaddressing + +#define IMSI_LEN 8 + +#define TMSI_LEN 4 + +#define IMEI_LEN 8 + +#define LMSI_LEN 4 + +#define HLRID_NUM 50 + +#define NAEA_LEN 3 + +#define GCID_LEN 7 // global cell id + +#define LAI_LEN 5 + +#define SMEA_LEN 12 // SM-RP-SMEA length + +#define BSG_LEN 13 // basic service group length + +#define CCBS_LEN 5 // CCBS requests number + +#define USSD_LEN 160 // USSD string length + +#define SS_LEN 30 + +#define PASSWD_LEN 4 // password length + +#define USSD_LEN 160 // USSD string length + +#define EVENT_LEN 2 + +//#define FWD_NUM 5 // forwarding number + +#define CALLREF_NUM 8 // call reference number + +#define TDPDATA_NUM 10 // camel TDP data number + +#define MAX_DSTNUM 10 // camel destination number length + +#define DSTNUM_LEN 3 // camel destination number-lengths length + +#define ISDN_DIGIT 15 // ISDN address digits + +#define BSCRIT_LEN 5 // camel basic service criteria length + +#define LOCATION_NUM 10 // location number + +#define KI_LEN 16 + +#define RAND_LEN 16 + +#define SRES_LEN 4 + +#define KC_LEN 8 + +#define AUTHLIST_LEN 5 // authenticate list length +//add by gxchen authentication quintuplet parameter start +#define XRES_LEN 8 +#define CK_LEN 16 +#define IK_LEN 16 +#define AUTN_LEN 16 +#define AUTS_LEN 14 +//add by gxchen end + +#define GSN_LEN 17 + +#define PDP_LEN 17 // PDP address length + +#define APN_LEN 63 // APN length + +#define EXT_QOS_SUB_LEN 10 //ext QoS subscribed length +#define EXT2_QOS_SUB_LEN 4 //ext 2 QoS subscribed length +#define EXT3_QOS_SUB_LEN 3 //ext 3 QoS subscribed length + +#define PDPCONTEXT_LEN 50 // PDP context length + +#define EXTBSG_LEN 32 // extent basic service group + +#define BSLIST_LEN 50 // bearer service list length + +#define TSLIST_LEN 20 // tele service list length + +#define CUGLOCK_LEN 4 // CUG interlock length + +#define CUG_LEN 10 + +#define ZONECODE_LEN 10 + +#define BSL_LEN 70 // basic service list + +#define CAMELTDP_LEN 10 + +#define VBS_LEN 50 + +#define VGCS_LEN 50 + +#define CAMELSS_LEN 10 // camel SS event length + + + +#define CALLBAR_LEN 8 + +#define EMLPP_LEN 20 + +#define CKSN_LEN 16 + + + +#define MAX_FWDNUM 5 // MAX forwarding number + +#define HLRID_LEN 2 + +/* ++++++++++++++++++ */ + +/* teliservice codes */ + +/* ++++++++++++++++++ */ + +#define TS_All 0x00 // all teleservice + + + +#define TS_AllSTS 0x10 // all speech transmission services + +#define TS_PHONY 0x11 // telephony + +#define TS_EMERCALL 0x12 // emergency calls + + + +#define TS_AllSMS 0x20 // all short message services + +#define TS_SMMTPP 0x21 // short message MT-PP + +#define TS_SMMOPP 0x22 // short message MO-PP + + + +#define TS_AllFTS 0x60 // all facsimile transmission services + +#define TS_FG3AAS 0x61 // facsimile group3 and alter speech + +#define TS_AFG3 0x62 // automatic facsimile group3 + +#define TS_FG4 0x63 // facsimile group4 + + + +#define TS_AllData 0x70 // all data teleservices + +#define TS_AllEXSMS 0x80 // all teleservices expect SMS + + + +#define TS_AllVGCS 0x90 // all voice group call services + +#define TS_VGC 0x91 // voice group call + +#define TS_VBSC 0x92 // voice broadcase call + + + +#define TS_AllPLMN 0xd0 // all PLMN specific TS + +#define TS_PLMN1 0xd1 + +#define TS_PLMN2 0xd2 + +#define TS_PLMN3 0xd3 + +#define TS_PLMN4 0xd4 + +#define TS_PLMN5 0xd5 + +#define TS_PLMN6 0xd6 + +#define TS_PLMN7 0xd7 + +#define TS_PLMN8 0xd8 + +#define TS_PLMN9 0xd9 + +#define TS_PLMNa 0xda + +#define TS_PLMNb 0xdb + +#define TS_PLMNc 0xdc + +#define TS_PLMNd 0xdd + +#define TS_PLMNe 0xde + +#define TS_PLMNf 0xdf + + + +/* ++++++++++++++++++++ */ + +/* Bearer service codes */ + +/* ++++++++++++++++++++ */ + +#define BS_All 0x00 // all bearer service + + + +#define BS_AllDataCDA 0x10 // all data CDA services + +#define BS_CDA300 0x11 // data CDA-300 bps + +#define BS_CDA1200 0x12 // data CDA-1200 bps + +#define BS_CDA7500 0x13 // data CDA-1200-7500 bps + +#define BS_CDA2400 0x14 // data CDA-2400 bps + +#define BS_CDA4800 0x15 // data CDA-4800 bps + +#define BS_CDA9600 0x16 // data CDA-9600 bps + +#define BS_CDAGNRL 0x17 // general data CDA + + + +#define BS_AllDataCDS 0x18 // all data CDS services + +#define BS_CDS1200 0x1a // data CDS-1200 bps + +#define BS_CDS2400 0x1c // data CDS-2400 bps + +#define BS_CDS4800 0x1d // data CDS-4800 bps + +#define BS_CDS9600 0x1e // data CDS-9600 bps + +#define BS_CDSGNRL 0x1f // general data CDS + + + +#define BS_AllPACA 0x20 // all pad access CA services + +#define BS_PACA300 0x21 // pad access CA-300 bps + +#define BS_PACA1200 0x22 // pad access CA-1200 bps + +#define BS_PACA7500 0x23 // pad access CA-1200-7500 bps + +#define BS_PACA2400 0x24 // pad access CA-2400 bps + +#define BS_PACA4800 0x25 // pad access CA-4800 bps + +#define BS_PACA9600 0x26 // pad access CA-9600 bps + +#define BS_PACAGNRL 0x27 // general pad access CA + + + +#define BS_AllDPDS 0x28 // all data PDS services + +#define BS_DPDS2400 0x2c // data PDS-2400 bps + +#define BS_DPDS4800 0x2d // data PDS-4800 bps + +#define BS_DPDS9600 0x2e // data PDS-9600 bps + +#define BS_DPDSGNRL 0x2f // general data PDS + + + +#define BS_AllASDCDA 0x30 // all alternate speech data CDA + +#define BS_AllASDCDS 0x38 // all alternate speech data CDS + +#define BS_AllASFBDCDA 0x40 // all speech followed by Data CDA + +#define BS_AllASFBDCDS 0x48 // all speech followed by Data CDS + + + +#define BS_AllDCA 0x50 // all data circuit asynchronous + +#define BS_AllAS 0x60 // all asynchronous services + +#define BS_AllDCS 0x58 // all data circuit synchronous + +#define BS_AllSS 0x68 // all synchronous services + + + +#define BS_AllPLMN 0xd0 // all PLMN specific BS + +#define BS_PLMN1 0xd1 + +#define BS_PLMN2 0xd2 + +#define BS_PLMN3 0xd3 + +#define BS_PLMN4 0xd4 + +#define BS_PLMN5 0xd5 + +#define BS_PLMN6 0xd6 + +#define BS_PLMN7 0xd7 + +#define BS_PLMN8 0xd8 + +#define BS_PLMN9 0xd9 + +#define BS_PLMNa 0xda + +#define BS_PLMNb 0xdb + +#define BS_PLMNc 0xdc + +#define BS_PLMNd 0xdd + +#define BS_PLMNe 0xde + +#define BS_PLMNf 0xdf + + + +/* ++++++++++++++++++++++++++++ */ + +/* supplementary service codes */ + +/* ++++++++++++++++++++++++++++ */ + +#define SS_All 0x00 // (reserved) + +#define SS_AllIdent 0x10 // all line identification SS (reserved) + +#define SS_CLIP 0x11 // calling line identification presentation + +#define SS_CLIR 0x12 // calling line identification restriction + +#define SS_COLP 0x13 // connected line identification presentation + +#define SS_COLR 0x14 // coonected line identification restriction + +#define SS_MCI 0x15 // malicious call identification (reserved) + + + +#define SS_AllNI 0x18 // all name identification SS + +#define SS_CNAP 0x19 // calling name presentation + + + +#define SS_AllFwd 0x20 // all forwarding SS + +#define SS_CFU 0x21 // call forwarding unconditional + +#define SS_AllCFwd 0x28 // all conditional forwarding SS + +#define SS_CFB 0x29 // call forwarding on mobile suscriber busy + +#define SS_CFNRY 0x2a // call forwarding on no reply + +#define SS_CFNRC 0x2b // call forwarding on mobile subscriber not reachable + +#define SS_CD 0x24 // call deflection + + + +#define SS_AllCOff 0x30 // all call offering SS (reserved) + +#define SS_ECT 0x31 // explicit call transfer + +#define SS_MAH 0x32 // mobile access hunting (reserved) + + + +#define SS_AllCC 0x40 // all call completion SS (reserved) + +#define SS_CW 0x41 // call waiting + +#define SS_HOLD 0x42 // call hold + +#define SS_CCBSA 0x43 // completion of call to busy subscribers,originating side + +#define SS_CCBSB 0x44 // completion of call to busy subscribers,destination side + + + +#define SS_AllMP 0x50 // all multiparty SS (reserved) + +#define SS_MULTIPTY 0x51 // multiparty + + + +#define SS_AllCOI 0x60 // all community of interest SS (reserved) + +#define SS_CUG 0x61 // closed user group + + + +#define SS_AllCHG 0x70 // all charging SS (reserved) + +#define SS_AOCI 0x71 // advice of charge information + +#define SS_AOCC 0x72 // advice of charge charging + + + +#define SS_AllAIT 0x80 // all additional information transfer SS (reserved) + +#define SS_UUS 0x81 // user to user signalling (reserved) + + + +#define SS_AllBar 0x90 // all barring SS + +#define SS_BOC 0x91 // barring of outgoing calls + +#define SS_BAOC 0x92 // barring of all outgoing calls + +#define SS_BOIC 0x93 // barring of outgoing international calls + +#define SS_BOICEXHC 0x94 // barring of outgoing international calls except to the home PLMN + +#define SS_BIC 0x99 // barring of incoming calls + +#define SS_BAIC 0x9a // barring of all incoming calls + +#define SS_BICROAM 0x9b // barring of incoming calls when roaming outside home PLMN country + + + +#define SS_AllPLMNS 0xf0 // all PLMN specific SS + +#define SS_PLMN1 0xf1 + +#define SS_PLMN2 0xf2 + +#define SS_PLMN3 0xf3 + +#define SS_PLMN4 0xf4 + +#define SS_PLMN5 0xf5 + +#define SS_PLMN6 0xf6 + +#define SS_PLMN7 0xf7 + +#define SS_PLMN8 0xf8 + +#define SS_PLMN9 0xf9 + +#define SS_PLMNa 0xfa + +#define SS_PLMNb 0xfb + +#define SS_PLMNc 0xfc + +#define SS_PLMNd 0xfd + +#define SS_PLMNe 0xfe + +#define SS_PLMNf 0xff + + + +#define SS_AllCP 0xa0 // all call priority SS (reserved) + +#define SS_EMLPP 0xa1 // enhanced multilevel precedence pre-emption(EMLPP) service + + + +/* ++++++++++++++++++++++++ */ + +/* alerting pattern codes */ + +/* ++++++++++++++++++++++++ */ + +#define ALT_Lev0 0x00 // alerting level 0 + +#define ALT_Lev1 0x01 // alerting level 1 + +#define ALT_Lev2 0x02 // alerting level 2 + +#define ALT_CATE1 0x04 // alerting category 1 + +#define ALT_CATE2 0x05 // alerting category 2 + +#define ALT_CATE3 0x06 // alerting category 3 + +#define ALT_CATE4 0x07 // alerting category 4 + +#define ALT_CATE5 0x08 // alertign category 5 + + + +/* ++++++++++++++++++++++++ */ + +/* EMLPP priority codes */ + +/* ++++++++++++++++++++++++ */ + +#define EMLPP_LA 0x06 // EMLPP priority level A + +#define EMLPP_LB 0x05 // EMLPP priority level B + +#define EMLPP_L0 0x00 // EMLPP priority level 0 + +#define EMLPP_L1 0x01 // EMLPP priority level 1 + +#define EMLPP_L2 0x02 // EMLPP priority level 2 + +#define EMLPP_L3 0x03 // EMLPP priority level 3 + +#define EMLPP_L4 0x04 // EMLPP priority level 4 + + + + + +/* IS41 */ + +#define ESN_LEN 0X04 + +#define MIN_LEN 0x05 + +#define BIT0_TRUE 0x01 + +#define BIT1_TRUE 0x02 + +#define BIT2_TRUE 0x04 + +#define BIT3_TRUE 0x08 + +#define BIT4_TRUE 0x10 + +#define BIT5_TRUE 0x20 + +#define BIT6_TRUE 0x40 + +#define BIT7_TRUE 0x80 + +#define BIT8_TRUE 0x100 + +#define BIT9_TRUE 0x200 + +#define BIT10_TRUE 0x400 + +#define BIT11_TRUE 0x800 + +#define BIT12_TRUE 0x1000 + +#define BIT13_TRUE 0x2000 + +#define BIT14_TRUE 0x4000 + +#define BIT15_TRUE 0x8000 + +#define BIT16_TRUE 0x10000 + +#define BIT17_TRUE 0x20000 + +#define BIT18_TRUE 0x40000 + +#define BIT19_TRUE 0x80000 + +#define BIT20_TRUE 0x100000 + +#define BIT21_TRUE 0x200000 + +#define BIT22_TRUE 0x400000 + +#define BIT23_TRUE 0x800000 + +#define BIT24_TRUE 0x1000000 + +#define BIT25_TRUE 0x2000000 + +#define BIT26_TRUE 0x4000000 + +#define BIT27_TRUE 0x8000000 + +#define BIT28_TRUE 0x10000000 + +#define BIT29_TRUE 0x20000000 + + + +//asn.1 tag + +#define IS41PAR_BILLID "1" + +#define IS41PAR_SCID "2" + +#define IS41PAR_TCID "3" + +#define IS41PAR_DIGITS "4" + +#define IS41PAR_CD "5" + +#define IS41PAR_IMSCCID "6" + +#define IS41PAR_ISC "7" + +#define IS41PAR_MIN "8"//IMPLICIT OCTET STRING + +#define IS41PAR_ESN "9"//IMPLICIT OCTET STRING + +#define IS41PAR_RR "10" + +#define IS41PAR_SQ "11" + +#define IS41PAR_SCM "12" + +#define IS41PAR_AUTHDEN "13" + +#define IS41PAR_AUTHPER "14" + +#define IS41PAR_ST "15" + +#define IS41PAR_TS "16" + +#define IS41PAR_QUALCODE "17" + +#define IS41PAR_FEATRESULT "18" + +#define IS41PAR_REDREASON "19" + +#define IS41PAR_ACCDEN "20" + +#define IS41PAR_MSCID "21" + +#define IS41PAR_MYTYP "22" + +#define IS41PAR_ORIGIND "23" + +#define IS41PAR_TERMRES "24" + +#define IS41PAR_CFI "25" + +#define IS41PAR_FP "26" + +#define IS41PAR_UID "27" + +#define IS41PAR_TDMACD "28" + +#define IS41PAR_TDMACM "29" + +#define IS41PAR_HR "30" + +#define IS41PAR_TDMABID "31" + +#define IS41PAR_PCSSN "32" + +#define IS41PAR_LOCID "33"//IMPLICIT OCTET STRING + +#define IS41PAR_SYSACCTYPE "34" + +#define IS41PAR_AUTHR "35" + +#define IS41PAR_AUTHBS "36" + +#define IS41PAR_AUTHU "37"//IMPLICIT OCTET STRING + +#define IS41PAR_COUNT "38"//IMPLICIT Unsigned Integer (0..63) + +#define IS41PAR_CMODES "39" + +#define IS41PAR_RAND "40" + +#define IS41PAR_RANDBS "41" + +#define IS41PAR_RANDSSD "42"//IMPLICIT OCTET STRING + +#define IS41PAR_RANDU "43"//IMPLICIT OCTET STRING + +#define IS41PAR_RPTTYP "44"//IMPLICIT Unsigned Enumerated + +//#define IS41PAR_RPTTYP2 "44-2"//IMPLICIT Unsigned Enumerated + +#define IS41PAR_SMEKEY "45" + +#define IS41PAR_SSD "46"//IMPLICIT OCTET STRING + +#define IS41PAR_TERMTYP "47" + +#define IS41PAR_VPMASK "48" + +#define IS41PAR_SYSCAP "49" + +#define IS41PAR_DENACC "50" + +#define IS41PAR_UPDCOUNT "51"//IMPLICIT Unsigned Enumerated + +#define IS41PAR_NOSSD "52"//IMPLICIT Unsigned Enumerated + +#define IS41PAR_EXTMSCID "53" + +#define IS41PAR_EXTMYTYP "54" + +#define IS41PAR_CCDATA "55" + +#define IS41PAR_SYSACCDATA "56" + +#define IS41PAR_CANCD "57" + +#define IS41PAR_BORDACC "58" + +#define IS41PAR_CDMASCM "59" + +#define IS41PAR_CDMASOWD "60" + +#define IS41PAR_CDMATOWD "61" + +#define IS41PAR_CDMACM "62" + +#define IS41PAR_CDMACD "63" + +#define IS41PAR_CDMASQ "64" + +#define IS41PAR_CDMAPS "65" + +#define IS41PAR_CDMAMPR "66" + +#define IS41PAR_CDMAPLCM "67" + +#define IS41PAR_CDMACC "68" + +#define IS41PAR_CDMASW "69" + +#define IS41PAR_MSLOC "70" + +#define IS41PAR_PID "71" + +#define IS41PAR_RSIGQUAL "72" + +#define IS41PAR_DEREG "73" + +#define IS41PAR_NAMPSCD "74" + +#define IS41PAR_ALRTCODE "75" + +#define IS41PAR_ANCC "76" + +#define IS41PAR_AAV "77"//IMPLICIT OCTET STRING + +#define IS41PAR_AUTHCAP "78" + +#define IS41PAR_COUNTEx "79" + +#define IS41PAR_CPNDGTS1 "80" + +#define IS41PAR_CPNDGTS2 "81" + +#define IS41PAR_CPNSTRG1 "82" + +#define IS41PAR_CPNSTRG2 "83" + +#define IS41PAR_CPSUB "84" + +#define IS41PAR_CANTP "85" + +#define IS41PAR_CARDGTS "86" + +#define IS41PAR_DESTDGTS "87" + +#define IS41PAR_REDIND "88" + +#define IS41PAR_ISTERM "89" + +#define IS41PAR_AVTYP "90" + +#define IS41PAR_LOCTERM "91" + +#define IS41PAR_MWNCOUNT "92" + +#define IS41PAR_MDN "93" + +#define IS41PAR_MSCIN "94" + +#define IS41PAR_PSTNTERM "95" + +#define IS41PAR_NATIME "96" + +#define IS41PAR_OTFI "97" + +#define IS41PAR_ORIGTRIG "98" + +#define IS41PAR_RANDC "99" + +#define IS41PAR_RNDGTS "100" + +#define IS41PAR_RNSTRING "101" + +#define IS41PAR_RSUB "102" + +#define IS41PAR_SENDERIN "103"//IMPLICIT DigitsType + +#define IS41PAR_SMSADDR "104" + +#define IS41PAR_SMSBD "105" + +#define IS41PAR_SMSCID "106" + +#define IS41PAR_SMSDA "107" + +#define IS41PAR_SMSMSGCNT "108" + +#define IS41PAR_SMSNOTIND "109" + +#define IS41PAR_SMSODA "110" + +#define IS41PAR_SMSODS "111" + +#define IS41PAR_SMSOOA "112" + +#define IS41PAR_SMSOOS "113" + +#define IS41PAR_SMSOA "114" + +#define IS41PAR_SMSORGRES "115" + +#define IS41PAR_SMSTID "116" + +#define IS41PAR_SMSTERMRES "117" + +#define IS41PAR_SMSMWI "118" + +#define IS41PAR_TAT "119" + +#define IS41PAR_TERMLIST "120" + +#define IS41PAR_TERMTRMT "121" + +#define IS41PAR_TERMTRIG "122" + +#define IS41PAR_TRANSCAP "123" + +#define IS41PAR_UCHALRPT "124" + +//#define IS41PAR_RESERVED "125" + +//#define IS41PAR_RESERVED "126" + +//#define IS41PAR_RESERVED "127" + +#define IS41PAR_ACTCODE "128" + +#define IS41PAR_AR "129" + +#define IS41PAR_ANNLIST "130" + +#define IS41PAR_CDMACCI "131" + +#define IS41PAR_CDMACCL "132" + +#define IS41PAR_CDMATMI "133" + +#define IS41PAR_CDMATML "134" + +#define IS41PAR_CDMATMAHOI "135" + +#define IS41PAR_CDMATMAHOL "136" + +#define IS41PAR_CCI "137" + +#define IS41PAR_COUNTRPT "138" + +#define IS41PAR_DIGITCC "139"//IMPLICIT Unsigned Enumerated + +#define IS41PAR_ACDGTS "140" + +#define IS41PAR_ABDGTS "141" + +#define IS41PAR_BILLDGTS "142" + +#define IS41PAR_GEOAUTH "143" + +#define IS41PAR_LEGINFO "144" + +#define IS41PAR_MWNTYPE "145" + +#define IS41PAR_PACAIND "146" + +#define IS41PAR_PLIND "147" + +#define IS41PAR_RANDVT "148" + +#define IS41PAR_RESDGTS "149" + +#define IS41PAR_ROUTDGTS "150" + +#define IS41PAR_SR "151" + +#define IS41PAR_SMSACCDEN "152" + +#define IS41PAR_SMSCC "153" + +#define IS41PAR_SPINIPIN "154" + +#define IS41PAR_SPINITRIG "155" + +#define IS41PAR_SSDURPT "156" + +#define IS41PAR_TMINFO "157" + +#define IS41PAR_TML "158" + +#define IS41PAR_VMSPIN "159" + +#define IS41PAR_VMBOX "160" + +#define IS41PAR_AUTHDATA "161" + +#define IS41PAR_CDEN "162" + +#define IS41PAR_GRPINFO "163" + +#define IS41PAR_HOS "164" + +#define IS41PAR_NAMPSCM "165" + +#define IS41PAR_CDMASCI "166" + +#define IS41PAR_DENAUTHPER "167" + +#define IS41PAR_PILOT "168" + +#define IS41PAR_PILOTBID "169" + +#define IS41PAR_GLOBALTITLE "261" + +#define IS41PAR_RESUMEPIC "266" + +#define IS41PAR_TRIGADRLIST "276" + +#define IS41PAR_TRIGCAP "277" + +#define IS41PAR_TRIGLIST "278" + +#define IS41PAR_WINCAP "280" + +#define IS41PAR_WINOPRCAP "281" + +#define IS41PAR_WINTRIGLIST "283" + +#define IS41PAR_DMH_SVCID "286" + +//N.S0013-0 "WIN Phase 1" + +#define IS41PAR_EXESCR "258" + +#define IS41PAR_PSR "265" + +#define IS41PAR_SCRARG "267" + +#define IS41PAR_SCRNAME "268" + +#define IS41PAR_SCRRESULT "269" + +//#define IS41PAR_SR "274" + +#define IS41PAR_TDO "275" + +#define IS41PAR_TRIGERTYPE "279" + +//N.S0018 "TIA/EIA-41-D Pre-Paid Charging(Revision: 1)" + +#define IS41PAR_FEATIND "306" + +#define IS41PAR_RELCAUSE "308" + +#define IS41PAR_TOD "309" + +#define IS41PAR_CALLSTATUS "310" + +//N.S0009 "IMSI" + +#define IS41PAR_IMSI "242" + +//N.S0012 "CNAP/CNAR" + +#define IS41PAR_CPNAME "243" + +#define IS41PAR_DISPTEXT "244" + +#define IS41PAR_RDNAME "245" + +#define IS41PAR_SRVID "246" + +//X.S0010 "Pre-Paid Charging Enhancements for Circuit-Switched Data and Short Message Services" + +#define IS41PAR_SMSBRLEN "382" + +#define IS41PAR_SMSBILLID "383" + +#define IS41PAR_SMSEVENT "384" + +#define IS41PAR_SMSEVENTNOT "385" + +#define IS41PAR_SMSPMCNT "386" + + + + + +//is41 operations + +#define IS41OPR_HandoffMeasurementRequest 0x01 + +#define IS41OPR_FacilitiesDirective 0x02 + +#define IS41OPR_MobileOnChannel 0x03 + +#define IS41OPR_HandoffBack 0x04 + +#define IS41OPR_FacilitiesRelease 0x05 + +#define IS41OPR_QualificationRequest 0x06 + +#define IS41OPR_QualificationDirective 0x07 + +#define IS41OPR_Blocking 0x08 + +#define IS41OPR_Unblocking 0x09 + +#define IS41OPR_ResetCircuit 0x0a + +#define IS41OPR_TrunkTest 0x0b + +#define IS41OPR_TrunkTestDisconnect 0x0c + +#define IS41OPR_RegistrationNotification 0x0d + +#define IS41OPR_RegistrationCancellation 0x0e + +#define IS41OPR_LocationRequest 0x0f + +#define IS41OPR_RoutingRequest 0x10 + +#define IS41OPR_FeatureRequest 0x11 + +#define IS41OPR_ServiceProfileRequest 0x12 + +#define IS41OPR_ServiceProfileDirective 0x13 + +#define IS41OPR_UnreliableRoamerDataDirective 0x14 + +#define IS41OPR_CallDataREquest 0x15 + +#define IS41OPR_MSInactive 0x16 + +#define IS41OPR_TransferToNumberRequest 0x17 + +#define IS41OPR_RedirectionRequest 0x18 + +#define IS41OPR_HandoffToThird 0x19 + +#define IS41OPR_FlashRequest 0x1a + +#define IS41OPR_AuthenticationDirective 0x1b + +#define IS41OPR_AuthenticationRequest 0x1c + +#define IS41OPR_BaseStationChallenge 0x1d + +#define IS41OPR_AuthenticationFailureReport 0x1e + +#define IS41OPR_CountRequest 0x1f + +#define IS41OPR_InterSystemPage 0x20 + +#define IS41OPR_UnsolicitedResponse 0x21 + +#define IS41OPR_BulkDeregistration 0x22 + +#define IS41OPR_HandoffMeasurementRequest2 0x23 + +#define IS41OPR_FacilitiesDirective2 0x24 + +#define IS41OPR_HandoffBack2 0x25 + +#define IS41OPR_HandoffToThird2 0x26 + +#define IS41OPR_AuthenticationDirectiveForward 0x27 + +#define IS41OPR_AuthenticationStatusReport 0x28 + +#define IS41OPR_InformationBackward 0x29 + +#define IS41OPR_InformationDirective 0x2a + +#define IS41OPR_InformationForward 0x2b + +#define IS41OPR_InterSystemAnswer 0x2c + +#define IS41OPR_InterSystemPage2 0x2d + +#define IS41OPR_InterSystemSetup 0x2e + +#define IS41OPR_OriginationRequest 0x2f + +#define IS41OPR_RandomVariableRequest 0x30 + +#define IS41OPR_RedirectionDirective 0x31 + +#define IS41OPR_RemoteUserInteractionDirective 0x32 + +#define IS41OPR_SMSDeliveryBackward 0x33 + +#define IS41OPR_SMSDeliveryForward 0x34 + +#define IS41OPR_SMSDeliveryPointToPoint 0x35 + +#define IS41OPR_SMSNotification 0x36 + +#define IS41OPR_SMSRequest 0x37 + +//N.S0013-0 "WIN Phase 1" + +#define IS41OPR_AnalyzedInformation 64 + +#define IS41OPR_ConnectionFailureReport 65 + +#define IS41OPR_ConnectResource 66 + +#define IS41OPR_DisconnectResource 67 + +#define IS41OPR_FacilitySelectedAndAvailable 68 + +#define IS41OPR_InstructionRequest 69 + +#define IS41OPR_Modify 70 + +#define IS41OPR_ResetTimer 71 + +#define IS41OPR_Search 72 + +#define IS41OPR_SeizeResource 73 + +#define IS41OPR_SRFDirective 74 + +#define IS41OPR_TBusy 75 + +#define IS41OPR_TNoAnswer 76 + +//N.S0018 "TIA/EIA-41-D Pre-Paid Charging(Revision: 1)" + +#define IS41OPR_BulkDisconnection 80 + +#define IS41OPR_CallControlDirective 81 + +#define IS41OPR_OAnswer 82 + +#define IS41OPR_ODisconnect 83 + +#define IS41OPR_CallRecoveryReport 84 + +#define IS41OPR_TAnswer 85 + +#define IS41OPR_TDisconnect 86 + +#define IS41OPR_UnreliableCallData 87 + +//X.S0010-A "Pre-Paid Charging Enhancements for Circuit-Switched Data and Short Message Services" + +#define IS41OPR_ShortMessageAnalyzed 105 + + + +// debug + +#define IS41DB_DEBUG 0x01 + +#define IS41DB_ENCODE 0x02 + +#define IS41DB_DECODE 0x04 + +#define IS41DB_FLOW 0x08 + +#define IS41DB_ERR 0x10 + + + + + +#define IS41ERR_UNRECOGNIZED_MIN 0x81 + +#define IS41ERR_UNRECOGNIZED_ESN 0x82 + +#define IS41ERR_MIN_HLR_MISMATCH 0x83 + +#define IS41ERR_OPERATION_SEQUENCE_PROBLEM 0x84 + +#define IS41ERR_RESOURCE_SHORTAGE 0x85 + +#define IS41ERR_OPERATION_NOT_SUPPORTED 0x86 + +#define IS41ERR_TRUNK_UNAVAILABLE 0x87 + +#define IS41ERR_PARAMETER_ERROR 0x88 + +#define IS41ERR_SYSTEM_FAILURE 0x89 + +#define IS41ERR_UNRECOGNIZED_PARAMETER_VALUE 0x8a + +#define IS41ERR_FEATURE_INACTIVE 0x8b + +#define IS41ERR_MISSING_PARAMETER 0x8c + + + +// asn.1 + +#define SET_NATIONAL "18" + +#define ASN_OCTET_STRING "4" + +#define ASN_INTEGER "2" + +#define ASN_NULL "5" + +#define ASN_ENUMERATED "10" + +#define ASN_SEQUENCE "16" + +#define ASN_SET "17" + + + +#define ISDN_LEN 9 + + + +#define MAX_TCAPSEND_LEN (TCAP_PARAM_LEN-20) + +#define MAX_TCAPSEND_LEN_1 (TCAP_PARAM_LEN_1-20) + +#define MAX_IS41_VARPAR_LEN 32 + +#define MAX_IS41_VARPAR_LEN_1 31 + +#define MAX_IS41_TRIG_LIST_NUM 4 + +#define MAX_IS41_TRIG_LIST_NUM_1 3 + + + +#endif + diff --git a/plat/xapp/src/mapp/map_dlgpdu.h b/plat/xapp/src/mapp/map_dlgpdu.h new file mode 100644 index 0000000..b14aa93 --- /dev/null +++ b/plat/xapp/src/mapp/map_dlgpdu.h @@ -0,0 +1,104 @@ +/* MAP dialogue PDU head file */ +/* written by Liu zhiguo 2002-01-14 */ +/* Version 1.0 (according GSM 09.02 17.4) */ +/* ------------------------------------- */ +#ifndef _MAP_DLGPDU +#define _MAP_DLGPDU + +#define MAPDLG_OPEN 0x00 +#define MAPDLG_ACCEPT 0x01 +#define MAPDLG_CLOSE 0x02 +#define MAPDLG_REFUSE 0x03 +#define MAPDLG_UABORT 0x04 // user abort +#define MAPDLG_PABORT 0x05 // provider abort + +/* +++++++++++++++++++++++++ */ +/* MAP-Openinfo */ +/* +++++++++++++++++++++++++ */ +typedef struct MapDlgOpen_struct +{ + u8 param_flag; + u8 peer_ref[ISDN_LEN+1]; // peer reference + u8 local_ref[ISDN_LEN+1]; // local reference +} MapDlgOpen_struct; + +/* +++++++++++++++++++++++++ */ +/* MAP-Refuseinfo */ +/* +++++++++++++++++++++++++ */ +typedef enum MapDlgReason_enum +{ + noReasonGiven = 0, + invalidDstRef = 1, // invalid destination reference + invalidOrgRef = 2 // invalid original reference +} MapDlgReason_enum; + +typedef struct MapDlgRefuse_struct +{ + u8 param_flag; + enum MapDlgReason_enum reason; +} MapDlgRefuse_struct; + +/* +++++++++++++++++++++++++ */ +/* MAP-UserAbortinfo */ +/* +++++++++++++++++++++++++ */ +typedef enum MapDlgRUReason_enum // resource unavailable reason +{ + shortTRLimit = 0, // short term resource limitation + longTRLimit = 1 // long term resource limitation +} MapDlgRUReason_enum; + +typedef enum MapDlgPCReason_enum // procedure cancellation reason +{ + handoverCancel = 0, // hand over cancellation + radioChanRelease = 1, // radio channel release + netPathRelease = 2, // network path release + callRelease = 3, // call release + assProFailure = 4, // associated procedure failure + randomDialRelease = 5, // random dialogue release + remOperFailure = 6 // remote operation failure +} MapDlgPCReason_enum; + +typedef struct MapDlgUAbort_struct +{ + u8 choice_flag; // user abort choice + union + { + enum MapDlgRUReason_enum resunavi; // resource unavailable, choice_flag = 2 + enum MapDlgPCReason_enum appproccancel; // application procedure cancellation, choice_flag = 3 + } choice; +} MapDlgUAbort_struct; + +/* +++++++++++++++++++++++++ */ +/* MAP-UserAbortinfo */ +/* +++++++++++++++++++++++++ */ +typedef enum MapDlgPAbortReason_enum +{ + abnormaldial = 0, // abnormal dialogue + invalidPDU = 1 +} MapDlgPAbortReason_enum; + +typedef struct MapDlgPAbort_struct // MAP provider abort info +{ + u8 param_flag; + enum MapDlgPAbortReason_enum reason; +} MapDlgPAbort_struct; + +/* +++++++++++++++++++++++++ */ +/* MAP-DialoguePDU */ +/* +++++++++++++++++++++++++ */ +typedef struct MapDlg_struct +{ + u8 dlg_type; + union + { + struct MapDlgOpen_struct map_open; + struct MapDlgRefuse_struct map_refuse; + struct MapDlgUAbort_struct map_uabort; + struct MapDlgPAbort_struct map_pabort; + } map_dlg; +} MapDlg_struct; + +u8 build_mapdlg(struct MapDlg_struct *dlg_ptr,u8 *data_buf); +u8 extract_mapdlg(struct MapDlg_struct *dlg_ptr,struct dlgport_struct *port_ptr); + +#endif diff --git a/plat/xapp/src/mapp/map_includes.h b/plat/xapp/src/mapp/map_includes.h new file mode 100644 index 0000000..f779227 --- /dev/null +++ b/plat/xapp/src/mapp/map_includes.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////// +//Title : map_includes.c +//Auhtor : Liu Wei +//Desc : map include headers +//Created : 2007-05-18 +//Revision : +// +//Revision : +// +////////////////////////////////////////////////// + + +#ifndef _MAP_INCLUDES_H_ +#define _MAP_INCLUDES_H_ + + +#include "../../../public/src/include/pub_include.h" +#include "../../../sccp/src/include/sccp.h" +#include "map_const.h" +#include "map_struct.h" +#include "map_coding.h" +#include "map_public.h" + +#endif diff --git a/plat/xapp/src/mapp/map_opr_func.h b/plat/xapp/src/mapp/map_opr_func.h new file mode 100644 index 0000000..908e70c --- /dev/null +++ b/plat/xapp/src/mapp/map_opr_func.h @@ -0,0 +1,34 @@ +/* MAP extension operation */ +/* ------------------------------------- */ +#ifndef _MAP_OPR_FUNC +#define _MAP_OPR_FUNC + +#include "map_includes.h" +#include "../xap_interfunc.h" +#include "map_code.h" + +extern int assign_MapDetermineOprUserArg(struct MapDetermineOprUser_Arg *dou_ptr,u8 *buf, u8 ver); +extern int extract_MapDetermineOprUserArg(struct MapDetermineOprUser_Arg *dou_ptr,u32 buf_len,u8 *buf); +extern int assign_MapDetermineOprUserRes(struct MapDetermineOprUser_Res *dou_ptr,u8 *buf, u8 ver); +extern int extract_MapDetermineOprUserRes(struct MapDetermineOprUser_Res *dou_ptr,u32 buf_len,u8 *buf); + +extern int assign_MapVlrUpdateLocationArg(struct MapVlrUpdateLocation_Arg *cuwm_ptr,u8 *buf, u8 ver); +extern int extract_MapVlrUpdateLocationArg(struct MapVlrUpdateLocation_Arg *cuwm_ptr,u32 buf_len,u8 *buf); +extern int assign_MapVlrUpdateLocationRes(struct MapVlrUpdateLocation_Res *cuwm_ptr,u8 *buf, u8 ver); +extern int extract_MapVlrUpdateLocationRes(struct MapVlrUpdateLocation_Res *cuwm_ptr,u32 buf_len,u8 *buf); + +extern int assign_MapCreateUserWithMsisdnImsiArg(struct MapCreateUserWithMsisdnImsi_Arg *cuwm_ptr,u8 *buf, u8 ver); +extern int extract_MapCreateUserWithMsisdnImsiArg(struct MapCreateUserWithMsisdnImsi_Arg *cuwm_ptr,u32 buf_len,u8 *buf); +extern int assign_MapCreateUserWithMsisdnImsiRes(struct MapCreateUserWithMsisdnImsi_Res *cuwm_ptr,u8 *buf, u8 ver); +extern int extract_MapCreateUserWithMsisdnImsiRes(struct MapCreateUserWithMsisdnImsi_Res *cuwm_ptr,u32 buf_len,u8 *buf); + +extern int assign_MapDeleteOprUserArg(struct MapDeleteOprUser_Arg *dou_ptr,u8 *buf, u8 ver); +extern int extract_MapDeleteOprUserArg(struct MapDeleteOprUser_Arg *dou_ptr,u32 buf_len,u8 *buf); +extern int assign_MapDeleteOprUserRes(struct MapDeleteOprUser_Res *dou_ptr,u8 *buf, u8 ver); +extern int extract_MapDeleteOprUserRes(struct MapDeleteOprUser_Res *dou_ptr,u32 buf_len,u8 *buf); + +extern int assign_MapVlrEnquiryIMDM_Arg(struct MapVlrEnquiryIMDM_Arg *cuwm_ptr,u8 *buf, u8 ver); +extern int extract_MapVlrEnquiryIMDM_Arg(struct MapVlrEnquiryIMDM_Arg *cuwm_ptr,u32 buf_len,u8 *buf); +extern int assign_MapVlrEnquiryIMDM_Res(struct MapVlrEnquiryIMDM_Res *cuwm_ptr,u8 *buf, u8 ver); +extern int extract_MapVlrEnquiryIMDM_Res(struct MapVlrEnquiryIMDM_Res *cuwm_ptr,u32 buf_len,u8 *buf); +#endif diff --git a/plat/xapp/src/mapp/map_public.c b/plat/xapp/src/mapp/map_public.c new file mode 100644 index 0000000..ae6e310 --- /dev/null +++ b/plat/xapp/src/mapp/map_public.c @@ -0,0 +1,1112 @@ +/* MAP public function c file */ +/* Written by Liu Zhiguo 2002-03-25 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#include "map_includes.h" +#include "map_code.h" + +// fix multiple definition==================================== +int decErr; +// + +#define MAP_CODE_DEBUG 0 +static int map_code_debug1 = 1; +extern void xap_watch_dog(u32 wd_site); +#if _SUPPORT_ANSI +extern u8 map_check_map_flag(u32 did); +#endif + +void log_doit(int errnoflag, int priority, const char *fmt, va_list ap) +{ + int errno_save; + char buf[2048]; + + errno_save = errno; //value caller might want printed + vsprintf(buf, fmt, ap); + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcat(buf, "\n"); + if (map_code_debug1) + { + fflush(stdout); + fputs(buf, stderr); + fflush(stderr); + } + else + syslog(priority, "%s", buf); + return; +} + +void mapp_log_debug(const char *fmt, ...) +{ +#if MAP_CODE_DEBUG + va_list ap; + + va_start(ap, fmt); + log_doit(0,LOG_ERR, fmt, ap); + printf(fmt, ap); + va_end(ap); + return; +#endif +} + +u8 bytestrtobitstr(u8 *bit_str,u8 *byte_str,u8 bit_len) +{ // byte string code to bit string code + u8 ii; + u8 aa,bb,cc; + u8 str_len; + u8 null_len; + + str_len = bit_len / 8; + null_len = bit_len % 8; + if (null_len != 0) + { + str_len += 2; + bit_str[0] = 8 - null_len; + } + else + { + str_len += 1; + bit_str[0] = 0; + } + memset(bit_str+1,0,str_len-1); + for (ii = 0;ii < bit_len;ii ++) + { + aa = ii / 8; + bb = str_len - aa - 1; + cc = (byte_str[aa] >> (ii % 8)) & 0x01; + bit_str[bb] |= cc << (7 - (ii % 8)); + } + return str_len; +} + +u8 bitstrtobytestr(u8 *byte_str,u8 *bit_str,u8 bit_len) +{ + u8 ii; + u8 aa,bb,cc; + u8 str_len; + u8 total_len; + + str_len = bit_len - 1; + total_len = str_len * 8 - bit_str[0]; + memset(byte_str,0,str_len); + for (ii = 0;ii < total_len;ii ++) + { + aa = ii / 8 + 1; + bb = str_len - ii / 8 - 1; + cc = (bit_str[aa] >> (7 - (ii % 8))) & 0x01; + byte_str[bb] |= cc << (ii % 8); + } + return str_len; +} + +/* transfer tele service from bit string to bcd string */ +u8 tele_bittostr(u16 tele_data,u8 *tele_str,u8 ss_flag) +{ + u8 len=0; + u16 temp_data; + + temp_data = tele_data; + if ((temp_data & 0x1ff) == 0x1ff && ss_flag) // has all tele data + { + tele_str[0] = TS_All; + return 1; // tele service list length + } + if ((temp_data & 0x7c) == 0x7c && ss_flag) + { + tele_str[len++] = TS_AllData; + temp_data &= ~0x7c; + } + if ((temp_data & 0x73) == 0x73 && ss_flag) + { + tele_str[len++] = TS_AllEXSMS; + temp_data &= ~0x73; + } + if ((temp_data & 0x03) == 0x03 && ss_flag) + { + tele_str[len++] = TS_AllSTS; + temp_data &= ~0x03; + } + if ((temp_data & 0x01) == 0x01) + { + tele_str[len++] = TS_PHONY; + temp_data &= ~0x01; + } + if ((temp_data & 0x02) == 0x02) + { + tele_str[len++] = TS_EMERCALL; + temp_data &= ~0x02; + } + if ((temp_data & 0x0c) == 0x0c && ss_flag) + { + tele_str[len++] = TS_AllSMS; + temp_data &= ~0x0c; + } + if ((temp_data & 0x04) == 0x04) + { + tele_str[len++] = TS_SMMTPP; + temp_data &= ~0x04; + } + if ((temp_data & 0x08) == 0x08) + { + tele_str[len++] = TS_SMMOPP; + temp_data &= ~0x08; + } + if ((temp_data & 0x70) == 0x70 && ss_flag) + { + tele_str[len++] = TS_AllFTS; + temp_data &= ~0x70; + } + if ((temp_data & 0x10) == 0x10) + { + tele_str[len++] = TS_FG3AAS; + temp_data &= ~0x10; + } + if ((temp_data & 0x20) == 0x20) + { + tele_str[len++] = TS_AFG3; + temp_data &= ~0x20; + } + if ((temp_data & 0x40) == 0x40) + { + tele_str[len++] = TS_FG4; + temp_data &= ~0x40; + } + if ((temp_data & 0x180) == 0x180 && ss_flag) + { + tele_str[len++] = TS_AllVGCS; + temp_data &= ~0x180; + } + if ((temp_data & 0x80) == 0x80) + { + tele_str[len++] = TS_VGC; + temp_data &= ~0x80; + } + if ((temp_data & 0x100) == 0x100) + { + tele_str[len++] = TS_VBSC; + temp_data &= ~0x100; + } + return len; +} + +/* transfer tele service from bcd string to bit string */ +u16 tele_strtobit(u8 *tele_str,u8 tele_len) +{ + u16 tele_data=0; + u8 ii; + + for (ii = 0;ii < tele_len;ii ++) + { + switch (tele_str[ii]) + { + case TS_All: + tele_data |= 0x1ff; + break; + case TS_AllSTS: + tele_data |= 0x03; + break; + case TS_PHONY: + tele_data |= 0x01; + break; + case TS_EMERCALL: + tele_data |= 0x02; + break; + case TS_AllSMS: + tele_data |= 0x0c; + break; + case TS_SMMTPP: + tele_data |= 0x04; + break; + case TS_SMMOPP: + tele_data |= 0x08; + break; + case TS_AllFTS: + tele_data |= 0x70; + break; + case TS_FG3AAS: + tele_data |= 0x10; + break; + case TS_AFG3: + tele_data |= 0x20; + break; + case TS_FG4: + tele_data |= 0x40; + break; + case TS_AllData: + tele_data |= 0x7c; + break; + case TS_AllEXSMS: + tele_data |= 0x73; + break; + case TS_AllVGCS: + tele_data |= 0x180; + break; + case TS_VGC: + tele_data |= 0x80; + break; + case TS_VBSC: + tele_data |= 0x100; + break; + default: +// tele_data = 0; + break; + } + } + return tele_data; +} + +/* tranfer bearer service from bit string to bcd string */ +u8 bearer_bittostr(u32 bearer_data, u8 *bearer_str,u8 ss_flag) +{ +// u8 ii=0,jj; + u8 len=0; + u32 temp_data; + + temp_data = bearer_data; + if ((temp_data & 0x7ffffff) == 0x7ffffff && ss_flag) + { + bearer_str[0] = BS_All; + return 1; // bearer service list length + } + if ((temp_data & 0x287f07f) == 0x287f07f && ss_flag) + { + bearer_str[len++] = BS_AllAS; + temp_data &= ~0x287f07f; + } + if ((temp_data & 0x280007f) == 0x280007f && ss_flag) + { + bearer_str[len++] = BS_AllDCA; + temp_data &= ~0x280007f; + } + if ((temp_data & 0x280007f) == 0x5780f80 && ss_flag) + { + bearer_str[len++] = BS_AllSS; + temp_data &= ~0x5780f80; + } + if ((temp_data & 0x280007f) == 0x5000f80 && ss_flag) + { + bearer_str[len++] = BS_AllDCS; + temp_data &= ~0x5000f80; + } + if ((temp_data & 0x7f) == 0x7f && ss_flag) // all data CDA + { + bearer_str[len++] = BS_AllDataCDA; + temp_data &= ~0x7f; + } + if ((temp_data & 0x01) == 0x01) + { + bearer_str[len++] = BS_CDA300; + temp_data &= ~0x01; + } + if ((temp_data & 0x02) == 0x02) + { + bearer_str[len++] = BS_CDA1200; + temp_data &= ~0x02; + } + if ((temp_data & 0x04) == 0x04) + { + bearer_str[len++] = BS_CDA7500; + temp_data &= ~0x04; + } + if ((temp_data & 0x08) == 0x08) + { + bearer_str[len++] = BS_CDA2400; + temp_data &= ~0x08; + } + if ((temp_data & 0x10) == 0x10) + { + bearer_str[len++] = BS_CDA4800; + temp_data &= ~0x10; + } + if ((temp_data & 0x20) == 0x20) + { + bearer_str[len++] = BS_CDA9600; + temp_data &= ~0x20; + } + if ((temp_data & 0x40) == 0x40) + { + bearer_str[len++] = BS_CDAGNRL; + temp_data &= ~0x40; + } + if ((temp_data & 0x800000) == 0x800000) + { + bearer_str[len++] = BS_AllASDCDA; + temp_data &= ~0x800000; + } + if ((temp_data & 0x2000000) == 0x2000000) + { + bearer_str[len++] = BS_AllASFBDCDA; + temp_data &= ~0x2000000; + } + if ((temp_data & 0x7f000) == 0x7f000 && ss_flag) // all PDA acccess CDA + { + bearer_str[len++] = BS_AllPACA; + temp_data &= ~0x7f000; + } + if ((temp_data & 0x1000) == 0x1000) + { + bearer_str[len++] = BS_PACA300; + temp_data &= ~0x1000; + } + if ((temp_data & 0x2000) == 0x2000) + { + bearer_str[len++] = BS_PACA1200; + temp_data &= ~0x2000; + } + if ((temp_data & 0x4000) == 0x4000) + { + bearer_str[len++] = BS_PACA7500; + temp_data &= ~0x4000; + } + if ((temp_data & 0x8000) == 0x8000) + { + bearer_str[len++] = BS_PACA2400; + temp_data &= ~0x8000; + } + if ((temp_data & 0x10000) == 0x10000) + { + bearer_str[len++] = BS_PACA4800; + temp_data &= ~0x10000; + } + if ((temp_data & 0x20000) == 0x20000) + { + bearer_str[len++] = BS_PACA9600; + temp_data &= ~0x20000; + } + if ((temp_data & 0x40000) == 0x40000) + { + bearer_str[len++] = BS_PACAGNRL; + temp_data &= ~0x40000; + } + if ((temp_data & 0xf80) == 0xf80 && ss_flag) // all data CDS + { + bearer_str[len++] = BS_AllDataCDS; + temp_data &= ~0xf80; + } + if ((temp_data & 0x80) == 0x80) + { + bearer_str[len++] = BS_CDS1200; + temp_data &= ~0x80; + } + if ((temp_data & 0x100) == 0x100) + { + bearer_str[len++] = BS_CDS2400; + temp_data &= ~0x100; + } + if ((temp_data & 0x200) == 0x200) + { + bearer_str[len++] = BS_CDS4800; + temp_data &= ~0x200; + } + if ((temp_data & 0x400) == 0x400) + { + bearer_str[len++] = BS_CDS9600; + temp_data &= ~0x400; + } + if ((temp_data & 0x800) == 0x800) + { + bearer_str[len++] = BS_CDSGNRL; + temp_data &= ~0x800; + } + if ((temp_data & 0x1000000) == 0x1000000) + { + bearer_str[len++] = BS_AllASDCDS; + temp_data &= ~0x1000000; + } + if ((temp_data & 0x4000000) == 0x4000000) + { + bearer_str[len++] = BS_AllASFBDCDS; + temp_data &= ~0x4000000; + } + if ((temp_data & 0x780000) == 0x780000 && ss_flag) // all PDA acccess CDS + { + bearer_str[len++] = BS_AllDPDS; + temp_data &= ~0x780000; + } + if ((temp_data & 0x80000) == 0x80000) + { + bearer_str[len++] = BS_DPDS2400; + temp_data &= ~0x80000; + } + if ((temp_data & 0x100000) == 0x100000) + { + bearer_str[len++] = BS_DPDS4800; + temp_data &= ~0x100000; + } + if ((temp_data & 0x200000) == 0x200000) + { + bearer_str[len++] = BS_DPDS9600; + temp_data &= ~0x200000; + } + if ((temp_data & 0x400000) == 0x400000) + { + bearer_str[len++] = BS_DPDSGNRL; + temp_data &= ~0x400000; + } + return len; +} + +u32 bearer_strtobit(u8 *bearer_str,u8 bearer_len) +{ + u8 ii; + u32 bearer_data=0; + + for (ii = 0;ii < bearer_len;ii ++) + { + switch (bearer_str[ii]) + { + case BS_All: + bearer_data |= 0x7ffffff; + break; + case BS_AllDataCDA: + bearer_data |= 0x7f; + break; + case BS_CDA300: + bearer_data |= 0x01; + break; + case BS_CDA1200: + bearer_data |= 0x02; + break; + case BS_CDA7500: + bearer_data |= 0x04; + break; + case BS_CDA2400: + bearer_data |= 0x08; + break; + case BS_CDA4800: + bearer_data |= 0x10; + break; + case BS_CDA9600: + bearer_data |= 0x20; + break; + case BS_CDAGNRL: + bearer_data |= 0x40; + break; + case BS_AllDataCDS: + bearer_data |= 0xf80; + break; + case BS_CDS1200: + bearer_data |= 0x80; + break; + case BS_CDS2400: + bearer_data |= 0x100; + break; + case BS_CDS4800: + bearer_data |= 0x200; + break; + case BS_CDS9600: + bearer_data |= 0x400; + break; + case BS_CDSGNRL: + bearer_data |= 0x800; + break; + case BS_AllPACA: + bearer_data |= 0x7f000; + break; + case BS_PACA300: + bearer_data |= 0x1000; + break; + case BS_PACA1200: + bearer_data |= 0x2000; + break; + case BS_PACA7500: + bearer_data |= 0x4000; + break; + case BS_PACA2400: + bearer_data |= 0x8000; + break; + case BS_PACA4800: + bearer_data |= 0x10000; + break; + case BS_PACA9600: + bearer_data |= 0x20000; + break; + case BS_PACAGNRL: + bearer_data |= 0x40000; + break; + case BS_AllDPDS: + bearer_data |= 0x780000; + break; + case BS_DPDS2400: + bearer_data |= 0x80000; + break; + case BS_DPDS4800: + bearer_data |= 0x100000; + break; + case BS_DPDS9600: + bearer_data |= 0x200000; + break; + case BS_DPDSGNRL: + bearer_data |= 0x400000; + break; + case BS_AllASDCDA: + bearer_data |= 0x800000; + break; + case BS_AllASDCDS: + bearer_data |= 0x1000000; + break; + case BS_AllASFBDCDA: + bearer_data |= 0x2000000; + break; + case BS_AllASFBDCDS: + bearer_data |= 0x4000000; + break; + default: + bearer_data = 0; + break; + } + } + return bearer_data; +} + +void get_sccpadd(struct SCCP_ADDRESS *add_ptr,u8 *data) +{ + u8 temp_len; + + add_ptr->ip = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; + add_ptr->DPC = (data[4]<<24) + (data[5]<<16) + (data[6]<<8) + data[7]; + add_ptr->NetID = data[8]; + add_ptr->SSN = data[9]; + add_ptr->RI = data[10]; + add_ptr->GTI = data[11]; + add_ptr->TT = data[12]; + add_ptr->NP = data[13]; + add_ptr->ES = data[14]; + add_ptr->NAI = data[15]; + add_ptr->len = data[16]; + temp_len = (data[16] + 1) / 2; + memcpy(add_ptr->GTAI,data+17,temp_len%ISDN_LEN); +} + +void set_sccpadd(struct SCCP_ADDRESS *add_ptr,u8 *data) +{ + u8 temp_len; + + data[0] = add_ptr->ip >> 24; + data[1] = add_ptr->ip >> 16; + data[2] = add_ptr->ip >> 8; + data[3] = add_ptr->ip; + data[4] = add_ptr->DPC >> 24; + data[5] = add_ptr->DPC >> 16; + data[6] = add_ptr->DPC >> 8; + data[7] = add_ptr->DPC; + data[8] = add_ptr->NetID; + data[9] = add_ptr->SSN; + data[10] = add_ptr->RI; + data[11] = add_ptr->GTI; + data[12] = add_ptr->TT; + data[13] = add_ptr->NP; + data[14] = add_ptr->ES; + data[15] = add_ptr->NAI; + data[16] = add_ptr->len; + temp_len = (add_ptr->len + 1) / 2; + memcpy(data+17,add_ptr->GTAI,temp_len); +} + +u8 map_com_ftos(struct MapComSrv_struct *map_com,u8 *data_flow) +{ // common service data flow to structure + u32 aa; + u32 len; + u8 ii; + u8 delimiter_flag = 0; + struct MapOpen_Arg *open_arg; + struct MapOpen_Res *open_res; + struct MapClose_Arg *close_ptr; + struct MapUAbort_Arg *uabrt_ptr; + struct MapPAbort_Arg *pabrt_ptr; + + len = (data_flow[0] << 8) + data_flow[1]; + if (len < 9) // data flow is too short + return 0; + if ((data_flow[2] != MAP_FLAG) && + (data_flow[2] != IS41_FLAG) ) + return 0; + map_com->map_flag = data_flow[2]; + map_com->port_id = (data_flow[3] << 8) + data_flow[4]; + map_com->dialogue_id = (data_flow[6] << 8) + data_flow[7]; + map_com->message_type = data_flow[9]; + map_com->message_flag = data_flow[10]; + switch (map_com->message_type) + { + case MAP_OPEN: + if (map_com->message_flag == MAP_REQUEST || map_com->message_flag == MAP_INDICATE) + { + open_arg = (MapOpen_Arg *) &map_com->dlg_list.open_arg; + open_arg->acn_data.acn = data_flow[11]; + open_arg->acn_data.acn_ver = data_flow[12]; + get_sccpadd(&open_arg->peer_add,data_flow+13); + get_sccpadd(&open_arg->local_add,data_flow+41); + open_arg->param_flag = 0x0b; + aa = 70; + for (ii = 0;ii < 3;ii ++) + { + if (data_flow[aa] == 0x00) + break; + else if (data_flow[aa] == 0x01) // peer reference + { + len = data_flow[aa+1]; + if (len > ISDN_LEN) + return 0; + open_arg->peerref_len = len; + memcpy(open_arg->peer_reference,&data_flow[aa+2],len); + aa += len + 2; + open_arg->param_flag |= 0x04; + } + else if (data_flow[aa] == 0x02) // local reference + { + len = data_flow[aa+1]; + if (len > ISDN_LEN) + return 0; + open_arg->localref_len = len; + memcpy(open_arg->local_reference,&data_flow[aa+2],len); + aa+= len + 2; + open_arg->param_flag |= 0x10; + } + else if (data_flow[aa] == 0x03) // specific info + { + len = data_flow[aa+1]; + if (len >= MAX_SPCINFO_LEN) + return 0; + open_arg->specific_info.info_len = len; + memcpy(open_arg->specific_info.info_data,&data_flow[aa+2],len); + open_arg->param_flag |= 0x20; + aa += 2 + len; + } + else if (data_flow[aa] == 0x10) + { + delimiter_flag = 1; + aa += 2; + xap_watch_dog(66); + } + } + } + else if (map_com->message_flag == MAP_RESPONSE || map_com->message_flag == MAP_CONFIRM) + { + open_res = (MapOpen_Res *) &map_com->dlg_list.open_res; + open_res->result = data_flow[11]; + open_res->param_flag = 0x08; + aa = 13; + for (ii = 0;ii < 4;ii ++) + { + if (data_flow[aa] == 0x00) + break; + else if (data_flow[aa] == 0x01) // acn + { + open_res->acn_data.acn = data_flow[aa+2]; + open_res->acn_data.acn_ver = data_flow[aa+3]; + aa += 4; + open_res->param_flag |= 0x01; + } + else if (data_flow[aa] == 0x02) // specific info + { + len = data_flow[aa+1]; + if (len >= MAX_SPCINFO_LEN) + return 0; + open_res->specific_info.info_len = len; + memcpy(open_res->specific_info.info_data,&data_flow[aa+2],len); + open_res->param_flag |= 0x02; + aa += 2 + len; + } + else if (data_flow[aa] == 0x03) // refuse reason + { + open_res->refuse_reason = data_flow[aa+2]; + open_res->param_flag |= 0x10; + aa += 3; + } + else if (data_flow[aa] == 0x04) // provider error + { + open_res->provider_error = data_flow[aa+2]; + open_res->param_flag |= 0x20; + aa += 3; + } + else if (data_flow[aa] == 0x10) + { + delimiter_flag = 1; + aa += 2; + xap_watch_dog(69); + } + } + } + else + return 0; + break; + case MAP_CLOSE: + close_ptr = (MapClose_Arg *) &map_com->dlg_list.close_arg; + close_ptr->release_method = data_flow[11]; + close_ptr->param_flag = 0x01; + if (data_flow[13] == 0x01) + { + len = data_flow[14]; + if (len >= MAX_SPCINFO_LEN) + return 0; + close_ptr->specific_info.info_len = len; + memcpy(close_ptr->specific_info.info_data,&data_flow[15],len); + close_ptr->param_flag |= 0x02; + } + break; + case MAP_U_ABORT: + uabrt_ptr = (MapUAbort_Arg *) &map_com->dlg_list.uabort_arg; + uabrt_ptr->user_reason = data_flow[11]; + uabrt_ptr->param_flag = 0x01; + aa = 13; + for (ii = 0;ii < 2;ii ++) + { + if (data_flow[aa] == 0) + break; + else if (data_flow[aa] == 0x01) // diagnostic flag + { + uabrt_ptr->diag_info = data_flow[aa+2]; + uabrt_ptr->param_flag |= 0x02; + aa += 3; + } + else if (data_flow[aa] == 0x02) // specific info + { + len = data_flow[aa+1]; + if (len >= MAX_SPCINFO_LEN) + return 0; + uabrt_ptr->specific_info.info_len = len; + memcpy(uabrt_ptr->specific_info.info_data,&data_flow[aa+2],len); + uabrt_ptr->param_flag |= 0x04; + aa += 2 + len; + } + } + break; + case MAP_P_ABORT: + pabrt_ptr = (MapPAbort_Arg *) &map_com->dlg_list.pabort_arg; + pabrt_ptr->provider_reason = data_flow[11]; + pabrt_ptr->source = data_flow[12]; + pabrt_ptr->param_flag = 0x03; + break; + case MAP_NOTICE: + map_com->dlg_list.notice_arg.problem = data_flow[11]; + map_com->dlg_list.notice_arg.param_flag = 0x01; + break; + case MAP_DELIMITER: + case MAP_LINK: + break; + default: + return 0; + break; + } + if (delimiter_flag == 1) + { + xap_watch_dog(67); + return 2; + } + else + return 1; +} + +void map_com_stof(struct MapComSrv_struct *com_ptr,u8 *data_flow,u8 delimiter_flag) +{ // transfer common structure to data flow + u32 ii; + u32 len; + struct MapOpen_Arg *open_arg; + struct MapOpen_Res *open_res; + struct MapClose_Arg *close_arg; + struct MapUAbort_Arg *uabrt_arg; + +#if _SUPPORT_ANSI + if (map_check_map_flag(com_ptr->dialogue_id)) +#endif + data_flow[2] = MAP_FLAG; +#if _SUPPORT_ANSI + else + data_flow[2] = IS41_FLAG; +#endif + data_flow[3] = com_ptr->port_id >> 8; + data_flow[4] = com_ptr->port_id; + data_flow[6] = com_ptr->dialogue_id >> 8; + data_flow[7] = com_ptr->dialogue_id; + data_flow[9] = com_ptr->message_type; + data_flow[10] = com_ptr->message_flag; + ii = 11; + switch (com_ptr->message_type) + { + case MAP_OPEN: + if (com_ptr->message_flag == MAP_INDICATE || com_ptr->message_flag == MAP_REQUEST) + { + open_arg = (MapOpen_Arg *) &com_ptr->dlg_list.open_arg; + data_flow[ii++] = open_arg->acn_data.acn; + data_flow[ii++] = open_arg->acn_data.acn_ver; + set_sccpadd(&open_arg->peer_add,data_flow+ii); + ii += 28; + set_sccpadd(&open_arg->local_add,data_flow+ii); + ii += 28; + data_flow[ii++] = 1; // optional point + if ((open_arg->param_flag & 0x04)) // has peer reference address + { + data_flow[ii++] = 0x01; + len = open_arg->peerref_len; + data_flow[ii++] = len; + memcpy(data_flow+ii,open_arg->peer_reference,len); + ii += len; + } + if ((open_arg->param_flag & 0x10)) // has local reference address + { + data_flow[ii++] = 0x02; + len = open_arg->localref_len; + data_flow[ii++] = len; + memcpy(data_flow+ii,open_arg->local_reference,len); + ii += len; + } + if ((open_arg->param_flag & 0x20)) + { + data_flow[ii++] = 0x03; + len = open_arg->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow+ii,open_arg->specific_info.info_data,len); + ii += len; + } + if (delimiter_flag == 1) + { + data_flow[ii++] = 0x10; + data_flow[ii++] = 0x00; + xap_watch_dog(63); + } + data_flow[ii++] = 0x00; + } + else if (com_ptr->message_flag == MAP_RESPONSE || com_ptr->message_flag == MAP_CONFIRM) + { + open_res = (MapOpen_Res *) &com_ptr->dlg_list.open_res; + data_flow[ii++] = open_res->result; + data_flow[ii++] = 0x01; // optional point + if ((open_res->param_flag & 0x01)) // has ACN + { + data_flow[ii++] = 0x01; + data_flow[ii++] = 2; + data_flow[ii++] = open_res->acn_data.acn; + data_flow[ii++] = open_res->acn_data.acn_ver; + } + if ((open_res->param_flag & 0x02)) // has specific info + { + data_flow[ii++] = 0x02; + len = open_res->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow+ii,open_res->specific_info.info_data,len); + ii += len; + } + if ((open_res->param_flag & 0x10)) // has refuse reason + { + data_flow[ii++] = 0x03; + data_flow[ii++] = 1; + data_flow[ii++] = open_res->refuse_reason; + } + if ((open_res->param_flag & 0x20)) // has provider error + { + data_flow[ii++] = 0x04; + data_flow[ii++] = 1; + data_flow[ii++] = open_res->provider_error; + } + if (delimiter_flag == 1) + { + data_flow[ii++] = 0x10; + data_flow[ii++] = 0x00; + } + data_flow[ii++] = 0x00; + } + break; + case MAP_CLOSE: + close_arg = (MapClose_Arg *) &com_ptr->dlg_list.close_arg; + data_flow[ii++] = close_arg->release_method; + data_flow[ii++] = 0x01; // optional point + if ((close_arg->param_flag & 0x02)) // has specific info + { + data_flow[ii++] = 0x01; + len = close_arg->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow+ii,close_arg->specific_info.info_data,len); + ii += len; + } + data_flow[ii++] = 0x00; + break; + case MAP_U_ABORT: + uabrt_arg = (MapUAbort_Arg *) &com_ptr->dlg_list.uabort_arg; + data_flow[ii++] = uabrt_arg->user_reason; + data_flow[ii++] = 0x01; // optional point + if ((uabrt_arg->param_flag & 0x02)) + { + data_flow[ii++] = 0x01; + data_flow[ii++] = 1; + data_flow[ii++] = uabrt_arg->diag_info; + } + if ((uabrt_arg->param_flag & 0x04)) // has specific info + { + data_flow[ii++] = 0x02; + len = uabrt_arg->specific_info.info_len; + data_flow[ii++] = len; + memcpy(data_flow+ii,uabrt_arg->specific_info.info_data,len); + ii += len; + } + data_flow[ii++] = 0x00; + break; + case MAP_P_ABORT: + data_flow[ii++] = com_ptr->dlg_list.pabort_arg.provider_reason; + data_flow[ii++] = com_ptr->dlg_list.pabort_arg.source; + break; + case MAP_NOTICE: + data_flow[ii++] = com_ptr->dlg_list.notice_arg.problem; + break; + default: + break; + } + ii -= 2; + data_flow[0] = ii >> 8; + data_flow[1] = ii; +} + +u8 map_opr_ftos(struct MapOprData_struct *opr_ptr,u8 *data_flow) +{ // transfer opration data flow to structure + u32 aa; + u32 total_len,len; + u8 ii; + u8 delimiter_flag = 0; + + total_len = (data_flow[0] << 8) + data_flow[1]; + if (total_len < 10) + return 0; + if ((data_flow[2] != MAP_FLAG) && + (data_flow[2] != IS41_FLAG) ) + return 0; + opr_ptr->map_flag = data_flow[2]; + opr_ptr->port_id = (data_flow[3] << 8) + data_flow[4]; + opr_ptr->dialogue_id = (data_flow[6] << 8) + data_flow[7]; + opr_ptr->message_type = data_flow[9]; + opr_ptr->message_flag = data_flow[10]; + opr_ptr->invoke_id = data_flow[11]; + opr_ptr->param_flag = 0x1f; + opr_ptr->param_len = 0; + aa = 13; + for (ii = 0;ii < 3;ii ++) + { + if(aa>=total_len+2) + break; + + if (data_flow[aa] == 0x00) + break; + else if (data_flow[aa] == 0x01) // parameter + { + len = (data_flow[aa+1] << 8) + data_flow[aa+2]; + if (len > MAX_MAPPOPR_LEN) + return 0; + opr_ptr->param_len = len; + memcpy(opr_ptr->param,&data_flow[aa+3],len); + aa += len + 3; + opr_ptr->param_flag |= 0x20; + } + else if (data_flow[aa] == 0x02) // user error + { + opr_ptr->user_error = data_flow[aa+2]; + opr_ptr->param_flag |= 0x40; + aa += 3; + } + else if (data_flow[aa] == 0x03) // provider error + { + opr_ptr->provider_error = data_flow[aa+2]; + opr_ptr->param_flag |= 0x80; + aa += 3; + } + else if (data_flow[aa] == 0x04) // linked id + { + opr_ptr->linked_id = data_flow[aa+2]; + opr_ptr->param_flag |= 0x100; + aa += 3; + } + else if (data_flow[aa] == 0x10) + { + delimiter_flag = 1; + aa += 2; + ii = 3; + xap_watch_dog(70); + break; + } + } + if (delimiter_flag == 1) + return 2; + else + return 1; +} + +void map_opr_stof(struct MapOprData_struct *opr_ptr,u8 *data_flow,u8 delimiter_flag) +{ // transfer opration structure to data flow + u32 ii; + u32 len; + +#if _SUPPORT_ANSI + if (map_check_map_flag(opr_ptr->dialogue_id)) +#endif + data_flow[2] = MAP_FLAG; +#if _SUPPORT_ANSI + else + data_flow[2] = IS41_FLAG; +#endif + data_flow[3] = opr_ptr->port_id >> 8; + data_flow[4] = opr_ptr->port_id; + data_flow[6] = opr_ptr->dialogue_id >> 8; + data_flow[7] = opr_ptr->dialogue_id; + data_flow[9] = opr_ptr->message_type; + data_flow[10] = opr_ptr->message_flag; + data_flow[11] = opr_ptr->invoke_id; + data_flow[12] = 1; + ii = 13; + if ((opr_ptr->param_flag & 0x20)) // has component + { + data_flow[ii++] = 0x01; + len = opr_ptr->param_len; + data_flow[ii++] = len >> 8; + data_flow[ii++] = len; + memcpy(data_flow+ii,opr_ptr->param,len); + ii += len; + } + if ((opr_ptr->param_flag & 0x40)) // has user error + { + data_flow[ii++] = 0x02; + data_flow[ii++] = 1; + data_flow[ii++] = opr_ptr->user_error; + } + if ((opr_ptr->param_flag & 0x80)) // has provider error + { + data_flow[ii++] = 0x03; + data_flow[ii++] = 1; + data_flow[ii++] = opr_ptr->provider_error; + } + if ((opr_ptr->param_flag & 0x100)) // has linked id + { + data_flow[ii++] = 0x04; + data_flow[ii++] = 1; + data_flow[ii++] = opr_ptr->linked_id; + } + if (delimiter_flag == 1) + { + data_flow[ii++] = 0x10; + data_flow[ii++] = 0x00; + } + data_flow[ii++] = 0; + ii -= 2; + data_flow[0] = ii >> 8; + data_flow[1] = ii; +} + +char *is41_sequenceTag(char *tag,int sequence) +{ + static char sTag[32]; + + sprintf(sTag,"%s-%d",tag,sequence); + return sTag; +} + +int decode_Is41Parameter(char *tag,int len,BYTE *value,ASN_BUF *asn_buf) +{ + int decodeLen; + u8 temp_buf[256]; + + decodeLen = GetTLV(tag,len,temp_buf,0x80,asn_buf); + if ((decodeLen <= len) && (decodeLen > 0)) + { + memcpy(value,temp_buf,decodeLen); + return decodeLen; + } + return 0; +} diff --git a/plat/xapp/src/mapp/map_public.h b/plat/xapp/src/mapp/map_public.h new file mode 100644 index 0000000..4774cde --- /dev/null +++ b/plat/xapp/src/mapp/map_public.h @@ -0,0 +1,26 @@ +/* MAP public head file */ +/* written by Liu Zhiguo 2002-03-27 */ +/* version 1.0 */ +/* -------------------------------- */ + +#ifndef _MAP_PUBLIC +#define _MAP_PUBLIC + +void mapp_log_debug(const char *fmt, ...); + +u8 bytestrtobitstr(u8 *bit_str,u8 *byte_str,u8 bit_len); +u8 bitstrtobytestr(u8 *byte_str,u8 *bit_str,u8 bit_len); +u8 tele_bittostr(u16 tele_data,u8 *tele_str,u8 ss_flag); +u16 tele_strtobit(u8 *tele_str,u8 tele_len); +u8 bearer_bittostr(u32 bearer_data, u8 *bearer_str,u8 ss_flag); +u32 bearer_strtobit(u8 *bearer_str,u8 bearer_len); +void get_sccpadd(struct SCCP_ADDRESS *add_ptr,u8 *data); +void set_sccpadd(struct SCCP_ADDRESS *add_ptr,u8 *data); +u8 map_com_ftos(struct MapComSrv_struct *map_com,u8 *data_flow); +void map_com_stof(struct MapComSrv_struct *com_ptr,u8 *data_flow,u8 delimiter_flag); +u8 map_opr_ftos(struct MapOprData_struct *opr_ptr,u8 *data_flow); +void map_opr_stof(struct MapOprData_struct *opr_ptr,u8 *data_flow,u8 delimiter_flag); + +char *is41_sequenceTag(char *tag,int sequence); + +#endif diff --git a/plat/xapp/src/mapp/map_struct.h b/plat/xapp/src/mapp/map_struct.h new file mode 100644 index 0000000..fa64b96 --- /dev/null +++ b/plat/xapp/src/mapp/map_struct.h @@ -0,0 +1,4585 @@ +/* MAP data structure head file */ +/* Written by Liu zhiguo 2003-03-04 */ +/* Version 2.0 */ +/* --------------------------------- */ + +#ifndef _MAP_STRUCT +#define _MAP_STRUCT + +#include "map_LCSCode.h" +#ifndef _SUPPORT_ANSI +#define _SUPPORT_ANSI 1 + +#endif +#define RER 0 +#define ROK 1 + +#define MAP_FLAG 0x8f +#define IS41_FLAG 0x8e +#define MAX_SPCINFO_LEN 32 // specific information length +#define MAX_MAPPOPR_LEN 1024 + +// fix multiple definition==================================== +extern int decErr; +// + +/* MAP data structure. In here, ignore the extention portion */ +/* common service for MAP */ +typedef struct MapOpen_Arg // open argument +{ + u32 param_flag; + struct + { + u8 acn; + u8 acn_ver; + } acn_data; // application context name + struct SCCP_ADDRESS peer_add; + u8 peerref_len; + u8 peer_reference[ISDN_LEN+1]; + struct SCCP_ADDRESS local_add; + u8 localref_len; + u8 local_reference[ISDN_LEN+1]; + struct + { + u8 info_len; + u8 info_data[MAX_SPCINFO_LEN]; + } specific_info; +} MapOpen_Arg; + + +typedef struct map_open_arg_param{ + u32 pid; + u32 did; + u8 uDelimeterFlag; + SCCP_ADDR local_add; + SCCP_ADDR peer_add; + u8 acn; +} +MapOpenArgParam; + +typedef struct MapOpen_Res // open response +{ + u32 param_flag; + struct + { + u8 acn; + u8 acn_ver; + } acn_data; // application context name + struct + { + u8 info_len; + u8 info_data[MAX_SPCINFO_LEN]; + } specific_info; + struct SCCP_ADDRESS respond_add; + u8 result; + u8 refuse_reason; + u8 provider_error; +} MapOpen_Res; + +typedef struct MapClose_Arg // close argument +{ + u32 param_flag; + u8 release_method; + struct + { + u8 info_len; + u8 info_data[MAX_SPCINFO_LEN]; + } specific_info; +} MapClose_Arg; + +typedef struct MapUAbort_Arg // u-abort argument +{ + u32 param_flag; + u8 user_reason; + u8 diag_info; // diagnostic info + struct + { + u8 info_len; + u8 info_data[MAX_SPCINFO_LEN]; + } specific_info; +} MapUAbort_Arg; + +typedef struct MapPAbort_Arg // p-abort argument +{ + u32 param_flag; + u8 provider_reason; + u8 source; +} MapPAbort_Arg; + +typedef struct MapNotice_Arg // notice argument +{ + u32 param_flag; + u8 problem;// problem diagnostic +} MapNotice_Arg; + +typedef struct MapComSrv_struct // common service +{ + u8 map_flag;//is41 or map + u32 port_id; + u32 dialogue_id; + u8 message_type; + u8 message_flag; // distinguish REQUEST,INDICATE,RESPONSE,CONFIRM + u8 component_present; + union + { + struct MapOpen_Arg open_arg; + struct MapOpen_Res open_res; + struct MapClose_Arg close_arg; + struct MapUAbort_Arg uabort_arg; + struct MapPAbort_Arg pabort_arg; + struct MapNotice_Arg notice_arg; + } dlg_list; +} MapComSrv_struct; + +/* ************************ */ +/* MAP operation structure */ +/* ************************ */ + +/* ++++++++++++++++++++++++++++++++++++ */ +/* common data types, occording 17.7.8 */ +/* ++++++++++++++++++++++++++++++++++++ */ +typedef enum ProtocolId_enum // protocol id +{ + gsm0408 = 1, + gsm0806 = 2, + gsmBSSMAP = 3, + ets3001021 = 4 +} ProtocolId_enum; + +typedef enum ExtProtocolId_e //ext-ProtocolId +{ + ets300356 = 1 //ets-300356 +}ExtProtocolId_e; + +typedef enum NetRes_enum // network resource +{ + plmn = 0, + hlr = 1, + vlr = 2, + pvlr = 3, + ctrmsc = 4, // controlling MSC + vmsc = 5, + eir = 6, + rss = 7 +} NetRes_enum; + +typedef struct SigInfo_struct // signal information +{ + u8 siginfo_len; + u8 signal_info[SIGNALINFO_LEN]; // signal information +} SigInfo_struct; + +typedef struct ExtSigInfo_struct // external signal information +{ + u8 param_flag; + enum ProtocolId_enum prt_id; // protocol id + struct SigInfo_struct siginfo; +} ExtSigInfo_struct; // can not used in version 2 + +typedef struct AddSigInfo_s //additionalSignalInfo +{ + u8 param_flag; + enum ExtProtocolId_e prt_id; //ext-ProtocolId + struct SigInfo_struct sig_info; //signalInfo +}AddSigInfo_s; + +typedef struct SubId_struct // subscriber ID +{ + u8 choice_flag; + union + { + u8 imsi[IMSI_LEN]; // flag = 1 + u8 tmsi[TMSI_LEN]; // flag = 2 + } id_choice; +} SubId_struct; + +typedef struct NaeaPrefCi_struct // NAEA preferred CI +{ + u8 cic[NAEA_LEN]; // NAEA CIC +} NaeaPrefCi_struct; + +typedef struct CellIdLai_struct // cell id or lai +{ + u8 choice_flag; + union + { + u8 cellid[GCID_LEN]; // flag = 1 + u8 lai[LAI_LEN]; // flag = 2 + } cell_choice; +} CellIdLai_struct; + +typedef struct BSCode_struct // basic service code +{ + u8 param_flag; + u16 tele_code; + u32 bearer_code; +} BSCode_struct; + +typedef struct BS_Choice //MAP V1 Basic service +{ + u8 choice_flag; + union + { + u8 bear_service; + u8 tele_service; + } choice; +} BS_Choice; + +typedef struct EmlppInfo_struct // EMLPP info +{ + u8 param_flag; + u8 maxent_prio; // maximum entitle priority + u8 default_prio; // default priority +} EmlppInfo_struct; + +/* +++++++++++++++++++++++++++++++++++++++++ */ +/* short message structure, according 17.7.6 */ +/* +++++++++++++++++++++++++++++++++++++++++ */ +typedef enum SMDeliOutcome_enum // SM delivery outcome +{ + MemCapExceed = 0, // memory capacity exceeded + AbsSub = 1, // absent subscriber + SuccessTrans = 2 // successful transfer +} SMDeliOutcome_enum; + +typedef enum SMDeliNotInt_e //sm-deliveryNotIntended +{ + onlyIMSIReq = 0, //onlyIMSI-requested + onlyMCCMNCReq = 1 //onlyMCC-MNC-requested +}SMDeliNotInt_e; + +typedef enum AltReason_enum // alert reason +{ + ms_present = 0, + mem_avail = 1 +} AltReason_enum; + +typedef struct AddNum_struct // additional number +{ + u8 choice_flag; + union + { + u8 msc_num[ISDN_LEN+1]; // MSC number,flag = 1 + u8 sgsn_num[ISDN_LEN+1]; // SGSN number,flag = 2 + } choice; +} AddNum_struct; + +typedef struct LocInfoLMSI_struct // location info with LMSI +{ + u8 param_flag; + u8 netnode_num[ISDN_LEN+1]; // network node number + u8 lmsi[LMSI_LEN]; + u8 gprsnode_flag; // GPRS node indicator + struct AddNum_struct add_num;// additional number +} LocInfoLMSI_struct; + +typedef struct SmRpDa_struct // SM-RP-DA +{ + u8 choice_flag; + union + { + u8 imsi[IMSI_LEN]; // flag = 1 + u8 lmsi[LMSI_LEN]; // flag = 2 + u8 sc_add[ISDN_LEN+1]; // service centre address DA, flag = 3 + u8 no_rpda; // has not SM RP DA,flag = 4 + u8 roaming_num[ISDN_LEN+1]; + } choice; +} SmRpDa_struct; + +typedef struct SmRpOa_struct // SM-RP-OA +{ + u8 choice_flag; + union + { + u8 msisdn[ISDN_LEN+1]; // flag = 1 + u8 sc_add[ISDN_LEN+1]; // service centre address DA, flag = 2 + u8 no_rpoa; // has not SM RP OA, flag = 3 + } choice; +} SmRpOa_struct; + +typedef struct MapRIFSM_Arg // routing info for SM argument +{ + u32 param_flag; + u8 msisdn[ISDN_LEN+1]; + u8 sm_rp_pri; + u8 sc_add[ISDN_LEN+1]; // service centre address + u8 gprssup_flag; // GPRS support indicator + u8 sm_rp_mti; + u8 sm_rp_smea[SMEA_LEN+1]; + + enum SMDeliNotInt_e sm_deli_not_int; //sm-deliveryNotIntended add by gxchen +} MapRIFSM_Arg; + +typedef struct MapRIFSM_Res // routing info for SM response +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + struct LocInfoLMSI_struct loc_info; // location info with lmsi + u8 user_error; + u8 provider_error; +} MapRIFSM_Res; + +typedef struct LocInfoLMSI_struct_v1 +{ + u32 param_flag; + u8 choice_flag; + union + { + u8 roaming_num[ISDN_LEN+1]; + u8 msc_num[ISDN_LEN+1]; + } choice; + u8 imsi[IMSI_LEN]; +} LocInfoLMSI_struct_v1; + +typedef struct MapRIFSMV1_Arg // routing info for SM argument +{ + u32 param_flag; + u8 msisdn[ISDN_LEN+1]; + u8 sm_rp_pri; + u8 sc_add[ISDN_LEN+1]; // service centre address + u8 tele_service; +} MapRIFSMV1_Arg; + +typedef struct MapRIFSMV1_Res // routing info for SM response +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + LocInfoLMSI_struct_v1 loc_info; // location info with lmsi + u8 mwd_set; // boolean optional + u8 user_error; + u8 provider_error; +} MapRIFSMV1_Res; + +typedef struct MapMOFSM_Arg // MO forward SM argument +{ + u32 param_flag; + struct SmRpDa_struct sm_rp_da; + struct SmRpOa_struct sm_rp_oa; + struct SigInfo_struct sm_rp_ui; + + u8 moremsg_flag; // more message to send, for MAP V2, MO/T have the same code +} MapMOFSM_Arg; + +typedef struct MapMOFSM_Res // MO forward SM response +{ + u32 param_flag; + struct SigInfo_struct sm_rp_ui; + u8 user_error; + u8 provider_error; +} MapMOFSM_Res; + +typedef struct MapMTFSM_Arg // MT forward SM argument +{ + u32 param_flag; + struct SmRpDa_struct sm_rp_da; + struct SmRpOa_struct sm_rp_oa; + struct SigInfo_struct sm_rp_ui; + u8 moremsg_flag; // more message to send +} MapMTFSM_Arg; + +typedef struct MapMTFSM_Res // MT forward SM response +{ + u32 param_flag; + struct SigInfo_struct sm_rp_ui; + u8 user_error; + u8 provider_error; +} MapMTFSM_Res; + +typedef struct MapFSM_Arg +{ + u32 param_flag; + union // sm_rp_da + { + u8 imsi[IMSI_LEN]; + u8 lmsi[LMSI_LEN]; + u8 roaming_num[ISDN_LEN+1]; + u8 sc_add[ISDN_LEN+1]; // service centre address + u8 noms_rp_da; + } sm_rp_da; + u8 sm_rp_da_choice; + + union //sm_rp_oa + { + u8 msisdn[ISDN_LEN]; + u8 sc_add[ISDN_LEN+1]; // service centre address + u8 noms_rp_oa; + } sm_rp_oa; + u8 sm_rp_oa_choice; + + u8 sm_rp_ui_len; + u8 sm_rp_ui[200]; //sm_rp_ui + + u8 more_msgtosend; //more_msgtosend +} MapFSM_Arg; + +typedef struct MapTSA_Arg +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 trace_ref[2]; + u8 trace_type; + u8 omc_id_len; + u8 omc_id[20]; + u8 call_ref[3]; +} MapTSA_Arg; + +typedef struct MapRSMDS_Arg // report SM delivery status argument +{ + u32 param_flag; + u8 msisdn[ISDN_LEN+1]; + u8 sc_add[ISDN_LEN+1]; // service centre address + enum SMDeliOutcome_enum sm_deliout; // sm-delivery outcome + u8 abssubdiagsm; // absent subscriber diagnostic SM + u8 gprssup_flag; // GPRS support indicator + u8 deliout_flag; // delivery outcome indicator + enum SMDeliOutcome_enum addsm_deliout; // additional sm-delivery outcome + u8 add_abssubdiagsm; // additional absent subscriber diagnostic SM + + //umts add by gxchen + u8 ip_sm_gw_ind; //ip-sm-gw-Indicator + enum SMDeliOutcome_enum gw_sm_deliout; //ip-sm-gw-sm-deliveryOutcome + u8 gw_abssubdiagsm; //ip-sm-gw-absentSubscriberDiagnosticSM +} MapRSMDS_Arg; + +typedef struct MapRSMDS_Res // report SM delivery status response +{ + u32 param_flag; + u8 stored_msisdn[ISDN_LEN+1]; // stored MSISDN + u8 user_error; + u8 provider_error; +} MapRSMDS_Res; + +typedef struct MapASC_Arg // alert service centre argument +{ + u32 param_flag; + u8 msisdn[ISDN_LEN+1]; + u8 sc_add[ISDN_LEN+1];// service center address +} MapASC_Arg; + +typedef struct MapASC_Res // alert service centre response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapASC_Res; + +typedef struct MapISC_Arg // inform service centre argument +{ + u32 param_flag; + u8 stored_msisdn[ISDN_LEN+1]; // stored MSISDN + u16 mw_status; // MW-status + + //umts add by gxchen + u8 abssubdiagsm; //absentSubscriberDiagnosticSM + u8 add_abssubdiagsm; //additionalAbsentSubscriberDiagnosticSM +} MapISC_Arg; + +typedef struct MapRFSM_Arg // ready for SM argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + enum AltReason_enum alert_reason; // alert reason + u8 altreason_flag; // alert reason indicator + + u8 add_alt_reason_ind; //additionalAlertReasonIndicator umts +} MapRFSM_Arg; + +typedef struct MapRFSM_Res // ready for SM response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapRFSM_Res; + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* supplementary service data structure, according 17.7.4 */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +typedef enum CliResOpt_enum // Cli restriction option +{ + permanent = 0, + temdefres = 1, // temporary default restricted + temdefall = 2 // temporary default allowed +} CliResOpt_enum; + +typedef enum OverCate_enum // override category +{ + overenable = 0, // override enabled + overdisable = 1 // override disabled +} OverCate_enum; + +typedef enum GuiInfo_enum // guidance info +{ + enterpw = 0, + enternewpw = 1, + enternewpw_again = 2 +} GuiInfo_enum; + +typedef struct FwdFeat_struct // forward feature +{ + u8 param_flag; + struct BSCode_struct bs_code; + u8 ss_status; + u8 fwdto_num[ISDN_LEN+1]; // forward to number + u8 fwd_option; // forward option + u8 norc_time; // no reply condition time + + u8 fwdto_addr[22]; //forwardedToSubaddress + //umts add by gxchen + u8 long_fwdto_num[ISDN_LEN+1]; //longForwardedToNumber +} FwdFeat_struct; +/* +typedef struct FwdFeat // MAP V1 forward feature +{ + u8 param_flag; + struct BS_Choice bs; + u8 ss_status; + u8 fwdto_num[ISDN_LEN+1]; // forward to number + u8 fwdto_subaddr_len; + u8 fwdto_subaddr[21]; //forward to subaddress + u8 fwd_option; // forward option + u8 norc_time; // no reply condition time +} FwdFeat; +*/ +typedef struct FwdInfo_struct //forwarding info +{ + u8 param_flag; + u8 ss_code; + struct FwdFeat_struct fwd_feat; +// struct +// { +// u8 fwdfeat_len; +// struct FwdFeat_struct fwd_feat[BSG_LEN]; +// } fwdfeat_list; +} FwdInfo_struct; + +typedef struct CBFeat_struct // call barring feature +{ + u8 param_flag; + struct BSCode_struct bs_code; + u8 ss_status; +} CBFeat_struct; + +typedef struct CBInfo_struct // call barring info +{ + u8 param_flag; + u8 ss_code; + struct CBFeat_struct cb_feat; +// struct +// { +// u8 cbfeat_len; +// struct CBFeat_struct cb_feat[BSG_LEN]; +// } cbfeat_list; +} CBInfo_struct; + +typedef struct SsSubsOpt_struct // SS subscription option +{ + u8 choice_flag; + union + { + enum CliResOpt_enum clires_opt; // cli restriction option,flag=1 + enum OverCate_enum over_cate; // override category,flag=2 + } choice; +} SsSubsOpt_struct; + +typedef struct SsData_struct // SS data +{ + u8 param_flag; + u8 ss_code; + u8 ss_status; + struct SsSubsOpt_struct subs_opt; // ss subscription option + struct BSCode_struct bs_code; // basic service code + u8 default_prio; // default priority (EMLPP priority) + + u8 nbr_user; //nbrUser umts add by gxchen +} SsData_struct; + +typedef struct SsInfo_struct // SS info +{ + u8 choice_flag; + union + { + struct FwdInfo_struct fwd_info; // forward info, flag = 1 + struct CBInfo_struct cb_info; // call barring info, flag = 2 + struct SsData_struct ss_data; // ss data, flag = 3 + } choice; +} SsInfo_struct; + +typedef struct SsForBsCode_struct // SS-forBs-code +{ + u8 param_flag; + u8 ss_code; + struct BSCode_struct bs_code; + + u8 long_ftn_supp; //longFTN-Supported umts add by gxchen +} SsForBsCode_struct; + +typedef struct CcbsFeat_struct // CCBS feature +{ + u8 param_flag; + u8 ccbs_index; // ccbs index + u8 bsub_num[ISDN_LEN+1]; // b-subscriber number +// u8 bsub_subadd[ISDNSUB_LEN]; // b-subscriber subaddress + struct BSCode_struct bs_code; // basic service group +} CcbsFeat_struct; + +typedef struct GenSerInfo_struct // generic service info +{ + u8 param_flag; + u8 ss_status; + enum CliResOpt_enum clires_opt; // Cli restriction option + u8 maxent_prio; // maximum entitle priory + u8 default_prio; // default priory + struct + { + u8 ccbs_len; + struct CcbsFeat_struct ccbs_feat[CCBS_LEN]; + } ccbs_list; + + //umts add by gxchen + u8 nbr_sb; //nbrSB + u8 nbr_user; //nbrUser + u8 nbr_sn; //nbrSN +} GenSerInfo_struct; + +typedef struct UssdArg_struct // USSD Arg +{ + u8 param_flag; + u8 ussd_scheme; // USSD data coding scheme + struct + { + u8 string_len; + u8 ussd_data[USSD_LEN]; + } ussd_string; + u8 alt_pattern; // alert pattern + u8 msisdn[ISDN_LEN+1]; +} UssdArg_struct; + +typedef struct UssdRes_struct // USSD Res +{ + u8 param_flag; + u8 ussd_scheme; // USSD data coding scheme + struct + { + u8 string_len; + u8 ussd_data[USSD_LEN]; + } ussd_string; +} UssdRes_struct; + +typedef struct CcbsData_struct // CCBS data +{ + u8 param_flag; + struct CcbsFeat_struct ccbs_feat; + u8 trans_num[ISDN_LEN+1]; // translated B-number + u32 ser_ind; // service indicator + struct ExtSigInfo_struct call_info; // call info + struct ExtSigInfo_struct net_info; // network signal info +} CcbsData_struct; + +typedef struct MapRSS_Arg // register SS argument +{ + u32 param_flag; + u8 ss_code; + struct BSCode_struct bs_code; + u8 fwdto_num[ISDN_LEN+1]; // forward to number +// u8 fwdto_subadd[ISDNSUB_LEN];// forward to sub address + u8 norc_time; // no reply condition time + u8 default_prio; // default priority (EMLPP priority) + + //umts + u8 nbr_user; //nbrUser + u8 long_ftn_supp; //longFTN-Supported +} MapRSS_Arg; + +typedef struct MapRSS_Res // register SS response (SS info) +{ + u32 param_flag; + struct SsInfo_struct ss_info; + u8 user_error; + u8 provider_error; +} MapRSS_Res; + +typedef struct MapESS_Arg // erase SS argument +{ + u32 param_flag; + struct SsForBsCode_struct ss_forbs; +} MapESS_Arg; + +typedef struct MapESS_Res // erase SS response +{ + u32 param_flag; + struct SsInfo_struct ss_info; + u8 user_error; + u8 provider_error; +} MapESS_Res; + +typedef struct MapASS_Arg // activate SS argument +{ + u32 param_flag; + struct SsForBsCode_struct ss_forbs; +} MapASS_Arg; + +typedef struct MapASS_Res // activate SS response +{ + u32 param_flag; + struct SsInfo_struct ss_info; + u8 user_error; + u8 provider_error; +} MapASS_Res; + +typedef struct MapDASS_Arg // deactivate SS argument +{ + u32 param_flag; + struct SsForBsCode_struct ss_forbs; +} MapDASS_Arg; + +typedef struct MapDASS_Res // deactivate SS response +{ + u32 param_flag; + struct SsInfo_struct ss_info; + u8 user_error; + u8 provider_error; +} MapDASS_Res; + +typedef struct MapINTSS_Arg // interrogate SS argument +{ + u32 param_flag; + struct SsForBsCode_struct ss_forbs; +} MapINTSS_Arg; + +typedef struct MapINTSS_Res // interrogate SS response +{ + u32 param_flag; + struct + { + u8 choice_flag; + union + { + u8 ss_status; // flag = 1 + struct BSCode_struct bs_code; + struct FwdFeat_struct fwd_feat; +// struct // flag = 3 +// { +// u8 fwdfeat_len; +// struct FwdFeat_struct fwd_feat[BSG_LEN]; +// } fwdfeat_list; + struct GenSerInfo_struct genser_info; // generic service info,flag=4 + } choice; + } result; + u8 user_error; + u8 provider_error; +} MapINTSS_Res; + +typedef struct MapPUSSR_Arg // process Unstructured SS request argument +{ + u32 param_flag; + struct UssdArg_struct ussd_arg; +} MapPUSSR_Arg; + +typedef struct MapPUSSR_Res // process Unstructured SS request response +{ + u32 param_flag; + struct UssdRes_struct ussd_res; + u8 user_error; + u8 provider_error; +} MapPUSSR_Res; + +typedef struct MapUSSR_Arg // Unstructured SS request argument +{ + u32 param_flag; + struct UssdArg_struct ussd_arg; +} MapUSSR_Arg; + +typedef struct MapUSSR_Res // Unstructured SS request response +{ + u32 param_flag; + struct UssdRes_struct ussd_res; + u8 user_error; + u8 provider_error; +} MapUSSR_Res; + +typedef struct MapUSSN_Arg // Unstructured SS notify argument +{ + u32 param_flag; + struct UssdArg_struct ussd_arg; +} MapUSSN_Arg; + +typedef struct MapUSSN_Res // Unstructured SS notify response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapUSSN_Res; + +typedef struct MapBSA_Arg // Begin subsriber activaty +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 orgenty_num[9]; + u8 orgenty_num_len; +} MapBSA_Arg; + +typedef struct MapRPSS_Arg // register password argument +{ + u32 param_flag; + u8 ss_code; +} MapRPSS_Arg; + +typedef struct MapRPSS_Res // register password response +{ + u32 param_flag; + u8 passwd[PASSWD_LEN]; + u8 user_error; + u8 provider_error; +} MapRPSS_Res; + +typedef struct MapGPSS_Arg // get password argument +{ + u32 param_flag; + enum GuiInfo_enum gui_info; // guidance info +} MapGPSS_Arg; + +typedef struct MapGPSS_Res // get password response +{ + u32 param_flag; + u8 passwd[PASSWD_LEN]; + u8 provider_error; +} MapGPSS_Res; + +typedef struct MapSSIN_Arg // SS invocation notificatoin argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 msisdn[ISDN_LEN+1]; + u8 ss_event; // according ss code + struct + { + u8 event_len; + u8 event_spe[EVENT_LEN][ISDN_LEN+1]; + } event; +} MapSSIN_Arg; + +typedef struct MapSSIN_Res // SS invocation notification response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapSSIN_Res; + +typedef struct MapRCCE_Arg // register CC entity argument +{ + u32 param_flag; + u8 ss_code; + struct CcbsData_struct ccbs_data; +} MapRCCE_Arg; + +typedef struct MapRCCE_Res // register CC entity response +{ + u32 param_flag; + struct CcbsFeat_struct ccbs_feat; + u8 user_error; + u8 provider_error; +} MapRCCE_Res; + +typedef struct MapECCE_Arg // erase CC entity +{ + u32 param_flag; + u8 ss_code; + u8 ccbs_index; +} MapECCE_Arg; + +typedef struct MapECCE_Res // erase CC entity +{ + u32 param_flag; + u8 ss_code; + u8 ss_status; + u8 user_error; + u8 provider_error; +} MapECCE_Res; + +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* call handling sevices structure, according 17.7.3 */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +typedef enum InterType_enum // interrogation type +{ + basiccall = 0, + forwarding = 1 +} InterType_enum; + +typedef enum FwdReason_enum // forwarding reason +{ + fwdnotreach = 0, + fwdbusy = 1, + noreply = 2 +} FwdReason_enum; + +typedef enum TBTriDetPnt_enum // T-Bcsm trigger detection point +{ + termattmauth = 12, // term attempt authorized + + //umts add by gxchen + tbusy = 13, //tBusy + tnoanswer = 14 //tNoAnswer +} TBTriDetPnt_enum; + +typedef enum DefCallHand_enum // default call handling +{ + continue_call = 0, + release_call = 1 +} DefCallHand_enum; + +typedef enum DefSMSHand_enum // default call handling +{ + continue_transaction = 0, + release_transaction = 1 +} DefSMSHand_enum; + +typedef enum OBTriDetPnt_enum // O-Bcsm trigger detection point +{ + collected_info = 2, //collectedInfo + route_sel_fail = 4 //routeSelectFailure +} OBTriDetPnt_enum; + +typedef enum SMSTriDetPnt_enum // O-Bcsm trigger detection point +{ + sms_CollectedInfo = 1, //sms-CollectedInfo + + sms_DeliveryRequest = 2 //sms-DeliveryRequest umts gxchen +} SMSTriDetPnt_enum; + +typedef enum CallTypeCrit_enum // call type criteria +{ + forwarded = 0, + notforwared = 1 +} CallTypeCrit_enum; + +typedef enum MatchType_enum // match type +{ + inhibiting = 0, + enabling = 1 +} MatchType_enum; + +typedef enum NotReachReason_enum // not reachable reason +{ + mspurged = 0, + imsidetached = 1, + restrictedarea = 2, + notregistered = 3 +} NotReachReason_enum; + +typedef enum RepState_enum // reporting state +{ + stopmonitor = 0, + startmonitor = 1 +} RepState_enum; + +typedef enum CcbsSubStat_enum // CCBS subscriber status +{ + notidle = 0, // CCBS not idle + idle = 1, // CCBS idle + ccbsnotreach = 2 // CCBS not reachable +} CcbsSubStat_enum; + +typedef enum MonMode_enum // monitor mode +{ + aside = 0, + bside = 1 +} MonMode_enum; + +typedef enum CallOut_enum // call outcome +{ + success = 0, + failure = 1, + cobusy = 2 +} CallOut_enum; + +typedef enum RUFOut_enum // RUF outcome +{ + accepted = 0, + rejected = 1, + noresfree = 2, // no response from free MS + noresbusy = 3, // no response from busy MS + udubfree = 4, // udub from free MS + udubbusy = 5 // udub from busy MS +} RUFOut_enum; + +typedef enum IstSuppInd_e //istSupportIndicator +{ + BASIC_IST_SUPPORT = 0, //basicISTSupported + IST_CMD_SUPPORT = 1 //istCommandSupported +}IstSuppInd_e; + + +typedef struct CugChkInfo_struct // CUG check info +{ + u8 param_flag; + u8 cug_intlock[CUGLOCK_LEN]; // CUG interlock + u8 cug_outacc; // CUG outgoing access +} CugChkInfo_struct; + +typedef struct CamelInfo_struct // camel info +{ + u8 param_flag; + u8 camel_phase[3]; // supported camel phases + u8 supp_tcsi; //(0) suppress T-CSI + + u16 offer_camel; //offeredCamel4CSIs //add by gxchen +} CamelInfo_struct; + +typedef struct FwdData_struct // forwarding data +{ + u8 param_flag; + u8 fwd_num[ISDN_LEN + 1]; //(0) + u8 fwd_subadd[ISDNSUB_LEN + 1]; //(1) + u8 fwd_option; //(2) forwarding option + + u8 long_fwd_num[16]; //longForwardedToNumber add by gxchen +} FwdData_struct; + +typedef struct RoutInfo_struct // routing info +{ + u8 choice_flag; + union + { + u8 roam_num[ISDN_LEN+1]; // roaming number,flag = 1 + struct FwdData_struct fwd_data; // flag = 2 + } choice; +} RoutInfo_struct; + +typedef struct TBCTDPData_struct // T-Bcsm camel TDP data +{ + u8 param_flag; + enum TBTriDetPnt_enum det_point; // t-Bcsm trigger detection point + u32 service_key; + u8 scf_add[ISDN_LEN+1]; + enum DefCallHand_enum def_hand; // default call handling +} TBCTDPData_struct; + +typedef struct TCsi_struct // T-CSI +{ + u8 param_flag; + struct + { + u8 tdpdata_len; + struct TBCTDPData_struct tdp_data[TDPDATA_NUM]; + } tdpdata_list; + u8 camel_caphand; // camel capability handling + + //umts add by gxchen + u8 ntfy_cse; //notificationToCSE + u8 csi_active; //csi-Active +} TCsi_struct; + +typedef struct OBCTDPData_struct // O-Bcsm camel TDP data +{ + u8 param_flag; + enum OBTriDetPnt_enum det_point; // O-Bcsm trigger detection point + enum DefCallHand_enum def_hand; // default call handling + u8 scf_add[ISDN_LEN+1]; + u32 service_key; +} OBCTDPData_struct; + +typedef struct OCsi_struct // O-CSI +{ + u8 param_flag; + struct + { + u8 tdpdata_len; + struct OBCTDPData_struct tdp_data[TDPDATA_NUM]; + } tdpdata_list; + u8 camel_caphand; // camel capability handling + + //umts add by gxchen + u8 ntfy_cse; //notificationToCSE + u8 csi_active; //csi-Active +} OCsi_struct; + +typedef struct SMSCTDPData_struct // SMS camel TDP data +{ + enum SMSTriDetPnt_enum det_point; // SMS trigger detection point + enum DefSMSHand_enum def_hand; // default call handling + u8 scf_add[ISDN_LEN + 1]; + u32 service_key; +} SMSCTDPData_struct; + +typedef struct SMSCsi_struct // O-CSI +{ + u8 param_flag; + struct + { + u8 tdpdata_len; + struct SMSCTDPData_struct tdp_data[TDPDATA_NUM]; + } tdpdata_list; //(0) + u8 camel_caphand; //(1)camel capability handling + u8 notificationToCSE; //(2)notificationToCSE + u8 csi_Active; //(3)csi-Active +} SMSCsi_struct; + +typedef struct MCsi_s //m-CSI +{ + u8 param_flag; + struct + { + u8 mobtri_len; + u8 mob_tri[TDPDATA_NUM]; + }mobtri; //mobilityTriggers + u32 service_key; //serviceKey + u8 scf_add[ISDN_LEN+1]; //gsmSCF-Address + u8 ntfy_cse; //notificationToCSE + u8 csi_active; //csi-Active +}MCsi_s; + +typedef struct VTCsi_s //vt-CSI +{ + u8 param_flag; + struct TBCTDPData_struct tdp_data[TDPDATA_NUM]; //t-BcsmCamelTDPDataList + u8 camel_caphand; //camelCapabilityHandling + u8 ntfy_cse; //notificationToCSE + u8 csi_active; //csi-Active +}VTCsi_s; + + +typedef struct DstNumCrit_struct // destination number criteria +{ + u8 param_flag; + enum MatchType_enum match_type; + struct + { + u8 dstnum_len; + u8 dst_num[MAX_DSTNUM][ISDN_LEN+1]; + } dstnum_list; //destination number list + struct + { + u8 numlength_len; + u8 num_length[DSTNUM_LEN]; + } dstnumlen_list; +} DstNumCrit_struct; + +typedef struct OBCTDPCrit_struct // O-Bcsm camel TDP criteria +{ + u8 param_flag; + enum OBTriDetPnt_enum det_point; // O-Bcsm trigger detection point + struct DstNumCrit_struct dstCriteria; + struct BSCode_struct bs_code; + enum CallTypeCrit_enum call_crit; // call type criteria + + //umts add by gxchen + struct + { + u8 causeval_len; + u8 cause_val[5]; + }o_cause_var_cri; //o-CauseValueCriteria +} OBCTDPCrit_struct; + +typedef struct OBCritLst_struct +{ + u8 list_len; + struct OBCTDPCrit_struct crit_data[TDPDATA_NUM]; +}OBCritLst_struct; + +typedef struct TBCTDPCrit_s +{ + u8 param_flag; + enum TBTriDetPnt_enum det_point; //t-BCSM-TriggerDetectionPoint + struct BSCode_struct bs_code; //basicServiceCriteria + struct + { + u8 causeval_len; + u8 cause_val[5]; + }t_cause_var_cri; //t-CauseValueCriteria +}TBCTDPCrit_s; +typedef struct TBCritLst_s //t-BCSM-CAMEL-TDP-CriteriaList +{ + u8 list_len; + struct TBCTDPCrit_s crit_data[TDPDATA_NUM]; +}TBCritLst_s; + +typedef struct DPAnaInfoCrit_s //dp-AnalysedInfoCriteriaList +{ + u8 param_flag; + u8 dial_num[ISDN_LEN+1]; //dialedNumber + u32 service_key; //serviceKey + u8 scf_add[ISDN_LEN+1]; //gsmSCF-Address + enum DefCallHand_enum def_hand; //defaultCallHandling +}DPAnaInfoCrit_s; +typedef struct DCsi_s //d-CSI +{ + u8 param_flag; + struct + { + u8 dpcrit_len; + struct DPAnaInfoCrit_s dp_crit[TDPDATA_NUM]; + }dpcrit_list; + u8 camel_caphand; //camelCapabilityHandling + u8 ntfy_cse; //notificationToCSE + u8 csi_active; //csi-Active +}DCsi_s; + +typedef struct GCSubsInfo_struct // GMSC camel subscription info +{ + u8 param_flag; + struct TCsi_struct t_csi; + struct OCsi_struct o_csi; + struct OBCritLst_struct ob_list; // O-Bcsm camel TDP criteria list + + //umts add by gxchen + struct TBCritLst_s tb_list; + struct DCsi_s d_csi; +} GCSubsInfo_struct; + +typedef struct CamelRoutInfo_struct // camel routing info +{ + u8 param_flag; + struct FwdData_struct fwd_data; //(0) + struct GCSubsInfo_struct subs_info; // GMSC camel subscription info +} CamelRoutInfo_struct; + +typedef struct ExtRoutInfo_struct // extended routing info +{ + u8 choice_flag; + union + { + struct RoutInfo_struct rout_info; // flag = 1 + struct CamelRoutInfo_struct camel_info; // camel routing info,flag = 2 + } choice; +} ExtRoutInfo_struct; + +typedef struct SubState_struct // subscriber state +{// flag=1:assumeidle;flag=2:camelbusy;flag=4:netnotreachable;flag=8:notprovidfromvlr + u8 choice_flag; + union + { + u8 assume_idle; //assumedIdle + u8 camel_busy; //camelBusy + enum NotReachReason_enum net_reason; + u8 not_pro_vlr; //notProvidedFromVLR + } choice; +} SubState_struct; + +typedef struct LocInfo_struct // location information +{ + u8 param_flag; + u16 age_info; // age of location information + u8 geog_info[8]; // geographical information + u8 vlr_num[ISDN_LEN+1]; + u8 loc_num[LOCATION_NUM]; // location number + struct CellIdLai_struct cell_lai; // cell id or lai + + //umts add by gxchen + u8 sel_lsa_id[3]; //selectedLSA-Id + u8 msc_num[ISDN_LEN+1]; //msc-Number + u8 geo_info[10]; //geodeticInformation + u8 cur_loc_rtrv; //currentLocationRetrieved + u8 sai_pre; //sai-Present +} LocInfo_struct; + +typedef struct LocInfoGprs_s //locationInformationGPRS +{ + u8 param_flag; + struct CellIdLai_struct cell_lai; //cellGlobalIdOrServiceAreaIdOrLAI + u8 route_area_id[6]; //routeingAreaIdentity + u8 geogr_info[8]; //geographicalInfomartion + u8 sgsn_num[ISDN_LEN+1]; //sgsn-Present + u8 sel_lsa_id[3]; //selectedLSAIdentity + u8 sai_pre; //sai-Present + u8 geo_info[10]; //geodeticInformation + u8 cur_loc_rtrv; //currentLocationRetrieved + u16 age_info; //ageOfLocationInformation +}LocInfoGprs_s; + +typedef struct PsSubState_s //ps-SubscriberState +{ + u8 choice_flag; + union + { + u8 not_pro_sgsn; //notProvidedFromSGSN + u8 ps_detach; //ps-Detached + u8 ps_attach_nrfp; //ps-AttachedNotReachableForPaging + u8 ps_attach_rfp; //ps-AttachedReachableForPaging + u8 ps_pdp_active_nrfp; //ps-ActiveNotReachableForPaging //define later + u8 ps_pdp_active_rfp; //ps-ActiveReachableForPaging //define later + enum NotReachReason_enum net_reason; //netDetNotReachable + }choice; +}PsSubState_s; + +/* +typedef struct SubInfo_struct // subscriber information +{ + u8 param_flag; + struct LocInfo_struct loc_info; + struct SubState_struct sub_state; +// CapLocationInformation loc_info; //(0) location information + //<---defined in capmsg.h +// u8 sub_state_ch; +// CapSubscriberState sub_state; //(1) param_flag=1 subscriber state + //<---defined in capmsg.h +} SubInfo_struct; +*/ + +typedef enum NumberPortabilityStatus +{ + //notKnownToBePorted = 0, + //ownNumberPortedOut = 1, + //foreignNumberPortedToForeignNetwork = 2, + ownNumberNotPortedOut = 4, + foreignNumberPortedIn = 5 +}NumberPortabilityStatus; + +typedef struct MnpInfoRes +{ + u8 param_flag; + u8 routing_number[ISDN_LEN+1]; + u8 imsi[IMSI_LEN]; + u8 msisdn[ISDN_LEN+1]; + enum NumberPortabilityStatus mnp_status; +}MnpInfoRes; + + +typedef struct SubInfo_struct // subscriber information +{ + u8 param_flag; + struct LocInfo_struct loc_info; + struct SubState_struct sub_state; + u8 locationInfoGPRS; // define later +// struct LocInfoGprs_s loc_info_gprs; + u8 ps_subscriber_state; //define later +// struct PsSubState_s ps_sub_state; + u8 imei[IMEI_LEN]; + u8 ms_classmark; //define later + u8 gprs_ms_class; //define later + struct MnpInfoRes mnp_info_res; +// CapLocationInformation loc_info; //(0) location information +// //<---defined in capmsg.h +// // u8 sub_state_ch; +// CapSubscriberState sub_state; //(1) param_flag=1 subscriber state +// //<---defined in capmsg.h +} SubInfo_struct; + + +typedef struct CcbsInd_struct // CCBS indicator +{ + u8 param_flag; + u8 ccbs_possible; // CCBS possible + u8 ccbs_indicator; // keep CCBS call indicator +} CcbsInd_struct; + +typedef struct EveRepData_struct // event report data +{ + u8 param_flag; + enum CcbsSubStat_enum ccbs_stat; // CCBS subscriber status +} EveRepData_struct; + +typedef struct CallRepData_struct // call report data +{ + u8 param_flag; + enum MonMode_enum monitor_mode; // monitor mode + enum CallOut_enum call_outcome; // call outcome +} CallRepData_struct; + +typedef struct MapSRI_Arg // send routing info argument +{ + u32 param_flag; + u8 msisdn[ISDN_LEN+1]; //0 + struct CugChkInfo_struct chk_info; // CUG check info + u8 fwd_num; // number of forwarding + enum InterType_enum inter_type; // interrogation type + u8 or_inter; // or-interrogation + u8 or_cap; // or-capability + u8 gmsc_add[ISDN_LEN+1]; // gmsc address + u8 callref_num[CALLREF_NUM+1]; // call reference number + enum FwdReason_enum fwd_reason; // forwarding reason + struct BSCode_struct bs_group; // basic service group + struct ExtSigInfo_struct net_info; // network signal info + struct CamelInfo_struct camel_info; // camel info + u8 supp_ann; // suppression of announcement + u8 alt_pattern; // alert pattern + u8 ccbs_call; // CCBS call + u8 ccbs_phase; // supported CCBS phase + struct AddSigInfo_s add_info; //additionalSignalInfo + + //add by gxchen umts + enum IstSuppInd_e supp_ind; //istSupportIndicator + u8 pre_page_supp; //pre-pagingSupported + u8 call_div_ind; //callDiversionTreatmentIndicator + u8 ftn_supp; //longFTNSupported + u8 sps_vt_csi; //suppress-VT-CSI + u8 sps_in_call_bar; //suppressIncomingCallBarring + u8 gsmscf_init_call; //gsmSCF-InitiatedCall + struct BSCode_struct bs_group2; //basicServiceGroup2 + struct ExtSigInfo_struct net_info2; //networkSingalInfo2 + u8 sps_mt_ss[3]; //suppressMTSS + u8 mt_roam_retry_supp; //mtRoamingRetrySupported + u8 call_pri; //callPriority +} MapSRI_Arg; + +typedef enum MNPStatus_enum +// mnp status type, for MNP looping detect, added by Pierre, 06-01-23 + { + notKnownToBePorted=0, + ownNumberPortedOut, + foreignNumberPortedToForeignNetwork, + }MNPStatus_enum; + +typedef enum UnAvailCause_e //unavailabilityCause +{ + bearerServiceNotProvisioned = 1, + teleserviceNotProvisioned = 2, + absentSubscriber = 3, + busySubscriber = 4, + callBarred = 5, + cugReject = 6 +}UnAvailCause_e; + + +typedef struct MapSRI_Res // send routing information response +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; //(0) + struct ExtRoutInfo_struct rout_info; //(1)extended routing info + struct CugChkInfo_struct cugchk_info; //(2)CUG check info + u8 cugsubs_flag; //(3)CUG subsription flag + struct SubInfo_struct sub_info; //(4)subscriber info + struct + { + u8 sslist_len; + u8 ss_code[SS_LEN]; + } ss_list; //(5) + struct BSCode_struct bs_code; + u8 fwdinter_req; // forwarding interrogate required + u8 vmsc_add[ISDN_LEN+1]; + struct NaeaPrefCi_struct naea_ci; // NAEA preferred CI + struct CcbsInd_struct ccbs_ind; // CCBS indicator + u8 msisdn[ISDN_LEN+1]; + MNPStatus_enum mnp_indicator; //bit:0x800 + + //umts add by gxchen + u8 ist_alert_timer; //istAlertTimer (15~255) + u8 camel_phase_vmsc; //supportedCamelPhasesInVMSC + u8 offer_camel_vmsc; //offeredCamel4CSIsInVMSC + struct RoutInfo_struct rout_info_2; //routingInfo2 + struct + { + u8 sslist_len; + u8 ss_code[SS_LEN]; + }ss_list_2; //ss-List2 + u8 allow_serv[2]; //allowedServices + enum UnAvailCause_e unavail_cause; + u8 rel_res_supp; //releaseResourcesSupported + struct ExtSigInfo_struct bear_cap; //gsm-BearerCapability + + u8 user_error; + u8 provider_error; +} MapSRI_Res; + + +typedef enum CallTermInd_e //callTerminationIndicator +{ + terminateCallActivityReferred = 0, + terminateAllCallActivities = 1 +}CallTermInd_e; + +typedef struct MapISTAlert_Arg //ist-Alert argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; +}MapISTAlert_Arg; + +typedef struct MapISTAlert_Res //ist-Alert response +{ + u32 param_flag; + u8 ist_alert_timer; //istAlertTimer (15~255) + u8 ist_info_withdraw; //istInformationWithdraw + enum CallTermInd_e callterm_ind; + + u8 user_error; + u8 provider_error; +}MapISTAlert_Res; + +typedef struct MapISTCmd_Arg //ist-Commad argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; +}MapISTCmd_Arg; + +typedef struct MapISTCmd_Res //ist-Command response +{ + u32 param_flag; + + u8 user_error; + u8 provider_error; +}MapISTCmdRes; + + +typedef struct PageArea_s //pagingArea +{ + u8 choice_flag; + union + { + u8 lai_fix[5]; //laiFixedLength 0 + u8 lac; //lac 1 + }choice; +}PageArea_s; + +typedef struct MapPRN_Arg // provide roaming number argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 msc_num[ISDN_LEN+1]; // MSC number + u8 msisdn[ISDN_LEN+1]; + u8 lmsi[LMSI_LEN]; + struct ExtSigInfo_struct bearer_cap; // gsm bearer capability + struct ExtSigInfo_struct net_info; // network signal info + u8 sup_ann; // suppression of announcement + u8 gmsc_add[ISDN_LEN+1]; // GMSC address + u8 callref_num[CALLREF_NUM+1]; // call reference number + u8 or_interr; // or-interrogation + u8 alt_pattern; // alert pattern + u8 ccbs_call; // CCBS call + u8 camel_phase[3]; // supported camel phase + + struct AddSigInfo_s add_info; //additionalSignalInfo + u8 not_supp_gmsc; //orNotSupportedInGMSC + //umts add by gxchen + u8 pre_page_supp; //pre-pagingSupported + u8 long_ftn_supp; //longFTN-Supported + u8 sps_vt_csi; //suppress-VT-CSI + u16 offer_camel_node; //offeredCamel4CSIsInInterrogatingNode + u8 mt_roam_retry_supp; //mtRoamingRetrySupported + struct PageArea_s page_area; //pagingArea + u8 call_pri; //callPriority +} MapPRN_Arg; + +typedef struct MapPRN_Res // provider roaming number response +{ + u32 param_flag; + u8 roam_num[ISDN_LEN+1]; + + u8 rel_res_supp; //releaseResourcesSupported umts add by gxchen + u8 user_error; + u8 provider_error; +} MapPRN_Res; + +typedef struct MapRCH_Arg // resume call handling argument +{ + u32 param_flag; + u8 callref_num[CALLREF_NUM+1]; // call reference number + struct BSCode_struct bs_group; // basic service group + struct FwdData_struct fwd_data; // forwarding data + u8 imsi[IMSI_LEN]; + struct CugChkInfo_struct cugchk_info;// CUG check info + struct OCsi_struct o_csi; // o-CSI + u8 ccbs_possible; // CCBS possible +} MapRCH_Arg; + +typedef struct MapRCH_Res // resume call handling response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapRCH_Res; + +typedef struct MapPSN_Arg // provide SIWFS number argument +{ + u32 param_flag; + struct ExtSigInfo_struct gsm_bc; // GSM bearer capability + struct ExtSigInfo_struct isdn_bc; // ISDN bearer capability + u8 call_direction; // call direction + u8 bsub_add[ISDN_LEN+1]; // b-subscriber address + struct ExtSigInfo_struct chose_chan; // chosen channel + struct ExtSigInfo_struct low_camp; // low layer compatibility + struct ExtSigInfo_struct high_camp; // high layer compatibility +} MapPSN_Arg; + +typedef struct MapPSN_Res // provide SIWFS number response +{ + u32 param_flag; + u8 siwfs_num[ISDN_LEN+1]; // sIWFS number + u8 user_error; + u8 provider_error; +} MapPSN_Res; + +typedef struct MapSSM_Arg // SIWFS signalling modify argument +{ + u32 param_flag; + struct ExtSigInfo_struct chan_type; // channel type + struct ExtSigInfo_struct chose_chan; // chosen channel +} MapSSM_Arg; + +typedef struct MapSSM_Res // SIWFS signalling modify response +{ + u32 param_flag; + struct ExtSigInfo_struct chose_chan; // chosen channel + u8 user_error; + u8 provider_error; +} MapSSM_Res; + +typedef struct MapSRS_Arg // set reporting state argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 lmsi[LMSI_LEN]; + enum RepState_enum ccbs_monitor; // CCBS monitoring +} MapSRS_Arg; + +typedef struct MapSRS_Res // set reporting state response +{ + u32 param_flag; + enum CcbsSubStat_enum ccbs_stat; // CCBS subscriber status + u8 user_error; + u8 provider_error; +} MapSRS_Res; + +typedef struct MapSR_Arg // status report argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + struct EveRepData_struct event_data; // event report data + struct CallRepData_struct call_data; // call report data +} MapSR_Arg; + +typedef struct MapSR_Res // status report response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapSR_Res; + +typedef struct MapRUF_Arg // remote user free argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + struct ExtSigInfo_struct call_info; // call info + struct CcbsFeat_struct ccbs_feat; // CCBS feature + u8 trans_num[ISDN_LEN+1]; // translate number + u8 replace_num; // replace number + u8 alt_pattern; // alert pattern +} MapRUF_Arg; + +typedef struct MapRUF_Res // remote user free response +{ + u32 param_flag; + enum RUFOut_enum ruf_outcome; // RUF outcome + u8 user_error; + u8 provider_error; +} MapRUF_Res; + +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* operation and maintenance data structure, according 17.7.2 */ +/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +typedef enum TraceDepth_e //TraceDepth +{ + Trd_Min = 0, //minimum + Trd_Mid = 1, //medium + Trd_Max = 2 //maximum +}TraceDepth_e; + +typedef struct TraceDepthLst_s //traceDepthList +{ + enum TraceDepth_e msc_trd; //msc-s-TraceDepth + enum TraceDepth_e mgw_trd; //mgw-TraceDepth + enum TraceDepth_e sgsn_trd; //sgsn-TraceDepth + enum TraceDepth_e ggsn_trd; //ggsn-TraceDepth + enum TraceDepth_e rnc_trd; //rnc-TraceDepth + enum TraceDepth_e bmsc_trd; //bmsc-TraceDepth + enum TraceDepth_e mme_trd; //mme-TraceDepth + enum TraceDepth_e sgw_trd; //sgw-TraceDepth + enum TraceDepth_e pgw_trd; //pgw-TraceDepth + enum TraceDepth_e enb_trd; //eNB-TraceDepth +}TraceDepthLst_s; + +typedef struct TraceLst_s //trace List +{ + u16 msc_list; //msc-s-List + u8 mgw_list; //mgw-List + u16 sgsn_list; //sgsn-List + u8 ggsn_list; //ggsn-List + u8 bmsc_list; //bmsc-List + u8 mme_list; //mme-List + u8 sgw_list; //sgw-List + u16 pgw_list; //pgw-List + + u8 rnc_list; //rnc-List + u8 enb_list; //eNB-List +}TraceLst_s; + +typedef struct MapATM_Arg // activate trace mode argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 trace_ref[2]; // trace reference + u8 trace_type; + u8 omc_id[ISDN_LEN+1];// OMC ID + + //umts add by gxchen + u8 trace_ref_2; //traceReference2 + struct TraceDepthLst_s trace_depth; //traceDepthList + u16 trace_type_list; //traceNE-TypeList + struct TraceLst_s trace_if; //traceInterfaceList + struct TraceLst_s trace_event; //traceEventList + u8 trace_col_ent; //traceCollectionEntity +} MapATM_Arg; + +typedef struct MapATM_Res // activate trace mode response +{ + u32 param_flag; + u8 trace_supp_ind; //traceSupportIndicator umts add by gxchen + u8 user_error; + u8 provider_error; +} MapATM_Res; + +typedef struct MapDTM_Arg // deactivate trace mode argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 trace_ref[2]; // trace reference + + u8 trace_ref_2; //traceReference2 umts add by gxchen +} MapDTM_Arg; + +typedef struct MapDTM_Res // deactivate trace maode response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapDTM_Res; + +typedef struct MapSIMSI_Arg // send IMSI argument +{ + u32 param_flag; + u8 msisdn[ISDN_LEN+1]; +} MapSIMSI_Arg; + +typedef struct MapSIMSI_Res // send IMSI response +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 user_error; + u8 provider_error; +} MapSIMSI_Res; + +/* ++++++++++++++++++++++++++++++++++++++++++ */ +/* mobile service structure, according 14.7.1 */ +/* ++++++++++++++++++++++++++++++++++++++++++ */ +typedef enum CanLocType_enum // cancel location type +{ + update = 0, // update procedure + withdraw = 1 // subscription withdraw +} CanLocType_enum; + +typedef enum TypeUpdate_e //typeOfUpdate +{ + sgsnChg = 0, //sgsn-change + mmeChg = 1 //mme-change +}TypeUpdate_e; + +typedef enum EquipStatus_enum // equipment status +{ + whitelist = 0, + blacklist = 1, + greylist = 2 +} EquipStatus_enum; + +typedef enum NetAccMode_enum // network access mode +{ + mscandsgsn = 0, + onlymsc = 1, + onlysgsn = 2 +} NetAccMode_enum; + +typedef enum SubStatus_enum // subscriber status +{ + servicegrant = 0, // service granted + oprbarring = 1 // operator determined barring +} SubStatus_enum; + +typedef enum IntraCugOpt_enum // intra CUG option +{ + norestric = 0, // no CUG restriction + iccallbar = 1, // CUG ic call barring + ogcallbar = 2 // CUG og call barring +} IntraCugOpt_enum; + +typedef enum RegSubsRes_enum // regional subscription response +{ + netrestrict = 0, // network node area restricted + toomanyzc = 1, // too many zone code + zcconflict = 2, // zone code conflict + regnotsupport = 3 // regional subscription not support +} RegSubsRes_enum; + +typedef struct ChgSuppISNE_s +{ + u8 choice_flag; + union + { + u8 send_sub_data; //sendSubscriberData + u8 sub_data_store[7]; //subscriberDataStored + }choice; +}ChgSuppISNE_s; + +typedef struct VlrCap_struct // VLR capability +{ + u8 param_flag; + u8 camel_phase[3]; // supported camel phase + u8 sol_supp_ind; //solsaSupportIndicator add by gxchen + + //umts add by gxchen + enum IstSuppInd_e ist_supp_ind; //istSupportIndicator + struct ChgSuppISNE_s chg_supp_isne; //superChargerSupportedInServingNetworkEntity + u8 long_ftn_supp; //longFTN-Supported + u16 supp_cap_set; //supportedLCS-CapabilitySets + u16 offer_camel; //offeredCamel4CSIs + u8 supp_type_ind; //supportedRAT-TypesIndicator + u8 long_Gr_id_supp;//longGroupID-Supported +} VlrCap_struct; + +typedef struct SgsnCap_s //sgsn-Capability +{ + u32 param_flag; + u8 sol_supp_ind; //solsaSupportIndicator + struct ChgSuppISNE_s chg_supp_isne; //superChargerSupportedInServingNetworkEntity + u8 gprs_supp_ind; //gprsEnhancementsSupportIndicator + u16 camel_phase; //supportedCamelPhases + u16 supp_cap_set; //supportedLCS-CapabilitySets + u16 offer_camel; //offeredCamel4CSIs + u8 scb_supp_ind; //smsCallBarringSupportIndicator + u8 supp_type_ind; //supportedRAT-TypesIndicator + u32 supp_feat; //supportedFeatures +}SgsnCap_s; + +typedef struct AddInfo_s //add-info +{ + u8 param_flag; + u8 imei_sv[8]; //imeisv + u8 skip_sub_data_update; //skipSubscriberDataUpdate +}AddInfo_s; + +typedef struct PdnGwUpdate_s //pdn-gw-update +{ + u8 param_flag; + struct + { + u8 apn_len; + u8 apn_data[APN_LEN]; + }apn; //apn + u8 pdn_gw_id; //pdn-gw-Identity define later + u8 con_id; //contextId +}PdnGwUpdate_s; +typedef struct EpsInfo_s //eps-info +{ + u8 choice_flag; + union + { + struct PdnGwUpdate_s gw_up;//pdn-gw-update + u8 isr_info; //isr-Information + }choice; +}EpsInfo_s; + +typedef struct AuthSet_struct // authentication set +{ + u8 param_flag; + u8 rand[RAND_LEN]; + u8 sres[SRES_LEN]; + u8 kc[KC_LEN]; +} AuthSet_struct; + +/* +typedef struct ReqInfo_struct // requested info +{ + u8 param_flag; + u8 loc_info; // location information + u8 sub_state; // subscriber state +} ReqInfo_struct; +*/ +typedef struct ReqInfo_struct // requested info +{ + u8 param_flag; + u8 loc_info; // location information + u8 sub_state; // subscriber state + u8 cur_location; + u8 req_domain; + u8 imei; + u8 ms_classmark; + u8 mnp_req_info; +} ReqInfo_struct; + +typedef struct SubIdent_struct // subscriber identity +{ + u8 choice_flag; + union + { + u8 imsi[IMSI_LEN]; // flag = 1 + u8 msisdn[ISDN_LEN+1]; // flag = 2 + } choice; +} SubIdent_struct; + +typedef struct PdpContext_struct // PDP context +{ + u16 param_flag; + u8 pdpcontext_id; // PDP context ID + u8 pdp_type[2]; + u8 pdp_add[PDP_LEN+1]; // PDP address + u8 qos_sub[3]; // QOS subscribed + u8 vplmn_allow; // VPLMN address allowed + struct + { + u8 apn_len; + u8 apn_data[APN_LEN]; + } apn; + + //umts add by gxchen + u8 ext_qos_sub[EXT_QOS_SUB_LEN+1]; //ext-QoS-Subscribed + u8 pdp_chg_char[2]; //pdp-ChargingCharacteristics + u8 ext2_qos_sub[EXT2_QOS_SUB_LEN+1]; //ext2-QoS-Subscribed 4 + u8 ext3_qos_sub[EXT3_QOS_SUB_LEN+1]; //ext3-QoS-Subscribed 3 +} PdpContext_struct; + +typedef struct GprsSubsData_struct // GPRS subsequent data +{ + u8 param_flag; + u8 data_include; // complete data list included + struct + { + u8 list_len; + struct PdpContext_struct pdp_context[PDPCONTEXT_LEN]; + } gprs_list; +} GprsSubsData_struct; + +typedef struct ExtFwdInfo_struct // ext forward info +{ // 0: CFU 1: CFB 2: CFNRy 3: CFNRc + u8 param_flag; // param_flag=0x01 => ss_code[0] & fwd_feat[0] + u8 ss_code[4]; + struct FwdFeat_struct fwd_feat[4]; +} ExtFwdInfo_struct; + +typedef struct CallBarFeatList_struct +{ + u8 param_flag; /*bit0-4 = array index0-4 */ /* code and status are always in pairs */ + struct BSCode_struct bs_code[5]; + u8 ss_status[5]; +}CallBarFeatList_struct; + +typedef struct ExtCallBarInfo_struct // ext call barring info +{ // 0: BAOC 1:BOIC 2:BOIC-exHPLMN 3:BAIC 4:BIC-Roam + u8 param_flag; + u8 ss_code[5]; + struct CallBarFeatList_struct bar_list[5]; + u8 ss_status[5]; + struct BSCode_struct bs_code[5]; +} ExtCallBarInfo_struct; + +typedef struct CugSubs_struct // CUG subscription +{ + u8 param_flag; + u16 cug_index; + u8 cug_lock[CUGLOCK_LEN]; // CUG interlock + enum IntraCugOpt_enum cug_opt;// intra CUG options + struct BSCode_struct bs_code; +} CugSubs_struct; + +typedef struct CugFeat_struct // CUG feature +{ + u8 param_flag; + struct BSCode_struct bs_code; + u16 cug_indicator; // preferntial CUG indicator + u8 cug_restric; // inter CUG restrictions +} CugFeat_struct; + +typedef struct CugInfo_struct // CUG info +{ + u8 param_flag; + struct + { + u8 list_len; + struct CugSubs_struct cug_subs[CUG_LEN]; + } subs_list; // CUG subscription list + struct + { + u8 list_len; + struct CugFeat_struct cug_feat[EXTBSG_LEN]; + } feat_list; // CUG feature list +} CugInfo_struct; + +typedef struct McSSInfo_s //mc-SS-Info +{ + u8 param_flag; + u8 ss_code; //ss-Code + u8 ss_status[5]; //ss-Status + u8 nbr_sb; //nbrSB (2~7) + u8 nbr_user; //nbrUser (1~7) +}McSSInfo_s; + +typedef struct ExtSsData_struct // ext SS data +{// 0: CLIP 1: CLIR 2: COLP 3: COLR + u32 param_flag; + u8 ss_code[SSDATA_NUM]; + u8 ss_status[SSDATA_NUM]; + struct SsSubsOpt_struct subs_opt[SSDATA_NUM]; // ss subscription option + struct BSCode_struct bs_code[SSDATA_NUM]; +} ExtSsData_struct; + +typedef struct ExtSsInfo_struct +{ + u8 param_flag; + struct ExtFwdInfo_struct fwd_info; + struct ExtCallBarInfo_struct call_info; + struct CugInfo_struct cug_info; + struct ExtSsData_struct ss_data; + struct EmlppInfo_struct emlpp_info; +} ExtSsInfo_struct; + +typedef struct OdbData_struct // ODB data +{ + u8 param_flag; + u32 odb_general; // ODB general data + u32 odb_hplmn; // ODB hplmn data +} OdbData_struct; + +typedef struct VGCData_struct // voice group call data +{ + u8 param_flag; + u8 group_id[3]; + + //umts + u8 add_sub; //additionalSubscriptions + u8 add_info[17]; //additionalInfo + u8 long_group_id[4]; //longGroupId +} VGCData_struct; + +typedef struct VBSData_struct //voice broadcast data +{ + u8 param_flag; + u8 group_id[3]; + u8 init_entitle; // broadcast init entitlement + + u8 long_group_id[4]; //longGroupId umts +} VBSData_struct; + +typedef struct SsCsi_struct // SS CSI +{ + u8 param_flag; + struct + { + u8 list_len; + u8 ss_code[CAMELSS_LEN]; + } event_list; // ss event list + u8 scf_add[ISDN_LEN+1]; + + //umts add by gxchen + u8 ntfy_cse; //notificationToCSE + u8 csi_active; //csi-Active +} SsCsi_struct; + +typedef enum GTriDetPnt_e //gprs-TriggerDetectionPoint +{ + GTDP_Attach = 1, //attach + GTDP_Attach_Chg_Pos = 2, //attachChangeOfPosition + GTDP_Pdp_Con_Est = 11, //pdp-ContextEstablishment + GTDP_Pdp_Con_Est_Ack = 12, //pdp-ContextEstablishmentAcknowledgement + GTDP_Pdp_Con_Chg_Pos = 14 //pdp-ContextChangeOfPosition +}GTriDetPnt_e; +typedef enum TpduTypeCrit_e //tpdu-TypeCriterion +{ + Tpdu_sms_Deliver = 0, //sms-DELIVER + Tpdu_sms_Submit_report, //sms-SUBMIT-REPORT + Tpdu_sms_Status_report //sms-STATUS-REPORT +}TpduTypeCrit_e; +typedef struct GCTDPData_s //gprs-CamelTDPDataList +{ + u8 param_flag; + enum GTriDetPnt_e det_point; //gprs-TriggerDetectionPoint + u32 service_key; //serviceKey + u8 scf_add[ISDN_LEN+1]; //gsmSCF-Address + enum DefCallHand_enum def_hand; //defaultSessionHandling +}GCTDPData_s; +typedef struct GprsCsi_s //gprs-CSI +{ + u8 param_flag; + struct GCTDPData_s gc_tdp_data[TDPDATA_NUM];//gprs-CamelTDPDataList + u8 camel_caphand; //camelCapabilityHandling + u8 ntfy_cse; //notificationToCSE + u8 csi_active; //csi-Active +}GprsCsi_s; + +typedef struct SMSCTDPCrit_s //mt-smsCAMELTDP-CriteriaList +{ + u8 param_flag; + enum SMSTriDetPnt_enum det_point; //sms-TriggerDetectionPoint + struct + { + u8 typecrit_len; + enum TpduTypeCrit_e type_crit[5]; //tpdu-TypeCriterion + }tt_crit; //tpdu-TypeCriterion +}SMSCTDPCrit_s; + + +typedef struct VCSubsInfo_struct // VLR CAMEL subscription info +{ + u8 param_flag; + struct OCsi_struct o_csi; //O-CSI + struct SsCsi_struct ss_csi; //SS-CSI + struct OBCritLst_struct tdp_list; //o-bcsm camel TDP criteria list + struct SMSCsi_struct sms_csi; // SMS-CSI + + u8 tif_csi; //tif-CSI + //umts + struct MCsi_s m_csi; //m-CSI + struct VTCsi_s vt_csi; //vt-CSI + struct TBCritLst_s tb_list; //t-BCSM-CAMEL-TDP-CriteriaList + struct DCsi_s d_csi; //d-CSI + struct SMSCsi_struct mt_sms_csi; //mt-sms-CSI +}VCSubsInfo_struct; + +typedef struct SgsnCamelSub_s //sgsn-CAMEL-SubscriptionInfo +{ + u32 param_flag; + struct GprsCsi_s gprs_csi; //gprs-CSI + struct SMSCsi_struct mo_sms_csi; //mo-sms-CSI + struct SMSCsi_struct mt_sms_csi; //mt-sms-CSI + struct + { + u8 smscri_len; + struct SMSCTDPCrit_s sms_cri[TDPDATA_NUM]; + }mtsms_cri_list; //mt-smsCAMELTDP-CriteriaList + struct MCsi_s mg_csi; //mg-csi +}SgsnCamelSub_s; + +typedef struct GprsSDWithdraw_struct // GPRS subscription data withdrwa +{ + u8 choice_flag; + union + { + u8 allgprs_data; // flag = 1 + struct // flag = 2 + { + u8 list_len; + u8 context_id[PDPCONTEXT_LEN]; + } context_list; // context id list + } choice; +} GprsSDWithdraw_struct; + +typedef struct MapUL_Arg // update location argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 msc_num[ISDN_LEN+1]; // MSC number + u8 vlr_num[ISDN_LEN+1]; // VLR number + u8 lmsi[LMSI_LEN]; + struct VlrCap_struct vlr_cap;// VLR capability + u8 roaming_num[ISDN_LEN+1]; + + //umts add by gxchen + u8 inform_pre_ne; //informPreviousNetworkEntity + u8 cs_lcs_not_supp; //cs-LCS-NotSupportedByUE + u8 v_gmlc_add[17]; //v-gmlc-Address + struct AddInfo_s add_info; //add-info + struct PageArea_s page_area; //pagingArea + u8 skip_sub_data_update; //skipSubscriberDataUpdate +} MapUL_Arg; + +typedef struct MapUL_Res // update location response +{ + u32 param_flag; + u8 hlr_num[ISDN_LEN+1]; + + //umts add by gxchen + u8 add_cap; //add-Capability + u8 page_area_cap; //pagingArea-Capability + + u8 user_error; // bit 31, 0x80000000 + u8 provider_error; // bit 30, 0x40000000 +} MapUL_Res; + +typedef struct CL_identity +{ + u32 choice_flag; + union + { + u8 imsi[IMSI_LEN]; + struct imsi_withLmsi + { + u8 imsi[IMSI_LEN]; + u8 lmsi[4]; + } imsi_withlmsi; + } choice; +} CL_identity; + +typedef struct MapCL_Arg // cancel location argument +{ + u32 param_flag; + CL_identity id; + enum CanLocType_enum type; // cancel location type + + enum TypeUpdate_e type_update; //typeOfUpdate umts +} MapCL_Arg; + + +typedef struct MapNP_Arg //NoteSubscriberPresent argumnet +{ + u8 param_flag; + u8 imsi[IMSI_LEN]; +} MapNP_Arg; + +typedef struct MapPUSSD_Arg //ProcessUnstructuredSS-Data Response +{ + u8 param_flag; + u8 ussd_len; + u8 ussd_data[200]; +} MapPUSSD_Arg; + + + +typedef struct MapPUSSD_Res //ProcessUnstructuredSS-Data Response +{ + u8 param_flag; + u8 ussd_len; + u8 ussd_data[200]; +} MapPUSSD_Res; + + +typedef struct MapSA_Arg //BeginSubscriberActivity argumnet +{ + u8 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 enity_len; + u8 Enity_num[9]; +} MapSA_Arg; + +typedef struct MapHO_Arg //perform hand over argument +{ + u8 param_flag; + u8 tgt_cellID[7]; + u8 tgt_cellid_len; + u8 srv_cellID[7]; + u8 srv_cellid_len; + u8 chl_type[10]; + u8 chl_type_len; + u8 class_mark[2]; + u8 ho_priority; + u8 kc[8]; +} MapHO_Arg; + +typedef struct MapHO_Res //perform hand over response +{ + u8 param_flag; + u8 ho_num[9]; + u8 ho_num_len; + struct + { + u8 protocol_id; + u8 singal_info_len; + u8 signal_info[200]; + } access_singal_info; +} MapHO_Res; + + + +typedef struct MapCL_Res // cancel location response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapCL_Res; + +typedef struct MapPMS_Arg // purge MS argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 vlr_num[ISDN_LEN+1]; // VLR number + u8 sgsn_num[ISDN_LEN+1]; // SGSN number +} MapPMS_Arg; + +typedef struct MapPMS_Res // purge MS response +{ + u32 param_flag; + u8 freeze_tmsi; // freeze TMSI + u8 freeze_ptmsi; // freeze P-TMSI + + u8 freeze_mtmsi; //freezeM-TMSI umts add by gxchen + u8 user_error; + u8 provider_error; +} MapPMS_Res; + +typedef struct MapSI_Arg // send identification argument +{ + u32 param_flag; + u8 tmsi[TMSI_LEN]; + + //umts add by gxchen start + u8 num_req_vec; //number of requested vectors (1...5) + u8 msc_num[ISDN_LEN+1]; //msc number + u8 pre_lai[5]; //previous LAI + u8 hop_counter; //hop counter (0...3) + //add by gxchen end +} MapSI_Arg; + +//add by gxchen start +typedef enum _Authlist_e +{ + AUTH_LIST_TRIPLET = 0, + AUTH_LIST_QUINTUPLET=1 +}Authlist_e; +typedef enum _Auth_e //_AuthSecCon_e +{ + AUTH_GSM=0, //AUTH_SEC_CON_GSM + AUTH_UMTS=1 //AUTH_SEC_CON_UMTS +}Auth_e; + +typedef struct _Triplet_st //triplet +{ + u8 param_flag; + u8 rand[RAND_LEN]; + u8 sres[SRES_LEN]; + u8 kc[KC_LEN]; +}Triplet_st; +typedef struct _Quintuplet_st //quintuplet +{ + u8 param_flag; + u8 rand[RAND_LEN]; + u8 xres[XRES_LEN]; + u8 ck[CK_LEN]; + u8 ik[IK_LEN]; + u8 autn[AUTN_LEN]; +}Quintuplet_st; +typedef struct EpsAuthSet_s //eps-AuthenticationSet +{ + u8 param_flag; + u8 rand[RAND_LEN]; + u8 xres[XRES_LEN]; + u8 autn[AUTN_LEN]; + u8 kasme[IK_LEN]; //Key for the Access Security Management Entity +}EpsAuthSet_s; + +typedef struct _AuthSetListGsm_st //authenticationSetList +{ + u8 auth_len; + AuthSet_struct auth_set[AUTHLIST_LEN]; +}AuthSetListGsm_st; + +typedef struct _AuthSetListUmts_st //authenticationSetList UMTS +{ +// u8 auth_len; + Authlist_e choice_flag; //0:tripletList, 1:quintupletList + union + { + struct + { + u8 tri_len; //auth_len + Triplet_st triplet[AUTHLIST_LEN]; + }tri_list; + struct + { + u8 quin_len; //auth_len + Quintuplet_st quintuplet[AUTHLIST_LEN]; + }quin_list; + }choice; +}AuthSetListUmts_st; + +typedef struct _gsmSecCon_st //gsm-SecurityContextData +{ + u8 param_flag; + u8 kc[KC_LEN]; + u8 cksn; +}GsmSecCon_st; +typedef struct _umtsSecCon_st //umts-SecurityContextData +{ + u8 param_flag; + u8 ck[CK_LEN]; + u8 ik[IK_LEN]; + u8 ksi; +}UmtsSecCon_st; +typedef struct _AuthSecCon_st //currentSecurityContext +{ + Auth_e choice_flag; //0:gsm-SecurityContextData, 1:umts-SecuritycontextData + union + { + GsmSecCon_st gsmCon; + UmtsSecCon_st umtsCon; + }choice; +}AuthSecCon_st; +typedef struct MapSI_Res // send identification response +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + struct + { + u8 auth_len; + struct AuthSet_struct auth_set[AUTHLIST_LEN]; + } authlist; + u8 provider_error; +} MapSI_Res; +//add by gxchen end + +typedef enum UserRatType_e //usedRAT-Type +{ + Rat_Utran = 0, //utran + Rat_Geran = 1, //geran + Rat_Gan = 2, //gan + Rat_HspaEvo = 3, //i-hspa-evolution + Rat_EUtran = 4 //e-utran +}UserRatType_e; +typedef struct MapUGL_Arg // update GPRS location argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 sgsn_num[ISDN_LEN+1]; // SGSN number + u8 sgsn_add[GSN_LEN+1]; // SGSN address + + struct SgsnCap_s sgsn_cap; //sgsn-Capability + //umts add by gxchen + u8 inform_pre_ne; //informPreviousNetworkEntity + u8 ps_lcs_not_supp; //ps-LCS-NotSupportedByUE + u8 v_gmlc_add[17]; //v-gmlc-Address + struct AddInfo_s add_info; //add-info + struct EpsInfo_s eps_info; //eps-info + u8 ser_node_type_ind; //servingNodeTypeIndicator + u8 skip_sub_data_update; //skipSubscriberDataUpdate + enum UserRatType_e rat_type; //usedRAT-Type + u8 gprs_subdata_notneed; //gprsSubscriptionDataNotNeeded + u8 node_type_ind; //nodeTypeIndicator +} MapUGL_Arg; + +typedef struct MapUGL_Res // update GPRS location response +{ + u32 param_flag; + u8 hlr_num[ISDN_LEN+1]; + + //umts add by gxchen + u8 add_cap; //add-Capability + u8 sgsn_mme_sep_supp; //sgsn-mmeSeparationSupported + + u8 user_error; + u8 provider_error; +} MapUGL_Res; + +typedef struct MapPSI_Arg // provide subscriber info argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 lmsi[LMSI_LEN]; + struct ReqInfo_struct req_info;// requested info +} MapPSI_Arg; + +typedef struct MapPSI_Res // provide subscriber info response +{ + u32 param_flag; + struct SubInfo_struct sub_info;// subscriber info + u8 user_error; + u8 provider_error; +} MapPSI_Res; + +typedef struct MapATI_Arg // any time interrogation argument +{ + u32 param_flag; + struct SubIdent_struct sub_ident; // subscriber identity + struct ReqInfo_struct req_info; // requested info + u8 scf_add[ISDN_LEN+1]; // gsmSCF address +} MapATI_Arg; + +typedef struct MapATI_Res // any time interrogation response +{ + u32 param_flag; + struct SubInfo_struct sub_info; // subscriber info + u8 user_error; + u8 provider_error; +} MapATI_Res; + +typedef struct MapATSI_Arg // any time subscription interrogation argument +{ + u32 param_flag; + struct SubIdent_struct sub_ident; // subscriber identity +} MapATSI_Arg; + +typedef struct MapATSI_Res // any time interrogation response +{ + u32 param_flag; + struct VCSubsInfo_struct subs_info; //(10)Camel subscription info + u8 user_error; + u8 provider_error; +} MapATSI_Res; + + +typedef struct MapPHO_Arg // prepare handover argument +{ + u32 param_flag; + u8 target_id[GCID_LEN]; // target cell id + u8 numnot_require; // ho-number not required + struct ExtSigInfo_struct bss_apdu; // bss APDU +} MapPHO_Arg; + +typedef struct MapPHO_Res // prepare handover response +{ + u32 param_flag; + u8 ho_num[ISDN_LEN+1]; // handover number + struct ExtSigInfo_struct bss_apdu; // bss APDU + u8 user_error; + u8 provider_error; +} MapPHO_Res; + +typedef struct MapSES_Arg // send end signal argument +{ + u32 param_flag; + struct ExtSigInfo_struct bss_apdu; // bss APDU +} MapSES_Arg; + +typedef struct MapSES_Res // send end signal response +{ + u32 param_flag; + u8 provider_error; +} MapSES_Res; + +typedef struct MapPAS_Arg // process access signalling argument +{ + u32 param_flag; + struct ExtSigInfo_struct bss_apdu; +} MapPAS_Arg; + +typedef struct MapFAS_Arg // forward access signalling argument +{ + u32 param_flag; + struct ExtSigInfo_struct bss_apdu; +} MapFAS_Arg; + +typedef struct MapPSHO_Arg // prepare subsequent handover argument +{ + u32 param_flag; + u8 target_id[GCID_LEN]; // target cell id + u8 msc_num[ISDN_LEN+1]; // target MSC number + struct ExtSigInfo_struct bss_apdu; +} MapPSHO_Arg; + +typedef struct MapPSHO_Res // prepare subsequent handover response +{ + u32 param_flag; + struct ExtSigInfo_struct bss_apdu; + u8 user_error; + u8 provider_error; +} MapPSHO_Res; + + +typedef struct MapPFSHO_Arg // preform subsequent handover argument +{ + u32 param_flag; + u8 target_id[GCID_LEN]; // target cell id + u8 service_id[GCID_LEN]; // Serving cell id + u8 msc_num[ISDN_LEN+1]; // target MSC number + u8 classmark_info[2]; +} MapPFSHO_Arg; + +typedef struct MapPFSHO_Res // preform subsequent handover response +{ + u32 param_flag; + struct ExtSigInfo_struct access_sig_info; + u8 user_error; + u8 provider_error; +} MapPFSHO_Res; + + +typedef struct MapNIHO_Arg // preform note internal hand over +{ + u32 param_flag; + u8 ho_type; // handover type + u8 target_id[GCID_LEN]; + struct ExtSigInfo_struct channel_id; +} MapNIHO_Arg; + + +//add by gxchen start +typedef struct _AuthReSynInfo_st //re-synchronisationInfo +{ + u8 param_flag; + u8 rand[RAND_LEN]; + u8 auts[AUTS_LEN]; +}AuthReSynInfo_st; +typedef enum _AuthNodeType_e //requestingNodeType +{ + AUTH_VLR=0, //vlr + AUTH_SGSN=1, //sgsn + AUTH_SCSCF=2, //s-cscf + AUTH_BSF=3, //bsf + AUTH_GAN=4, //gan-aaa-server + AUTH_WLAN=5, //wlan-aaa-server + AUTH_MME=16, //mme + AUTH_MME_SGSN=17 //mme-sgsn +}AuthNodeType_e; +//add by gxchen end + +typedef struct MapSAI_Arg // send authenticate info argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + + //add by gxchen start umts + u8 num_req_vec; //number of requested vectors (1...5) + u8 seg_prohibit; //segmentationProhibited + u8 imm_res_prefer; //immediateResponsePreferred + AuthReSynInfo_st resyn_info; //re-synchronisation info + AuthNodeType_e node_type; //requestingNodeType + u8 req_plmn_id[3]; //requestingPLMN-Id + u8 num_req_add_vec; //number of requested additional vectors (1...5) + u8 add_vec_eps; //additionalVectorsAreForEPS + //add by gxchen end +} MapSAI_Arg; + +//modify by gxchen +typedef struct MapSAI_Res_GSM // send authenticate info response GSM +{ + u32 param_flag; + struct + { + u8 auth_len; + struct AuthSet_struct auth_set[AUTHLIST_LEN]; + } authlist; + u8 user_error; + u8 provider_error; +} MapSAI_Res_GSM; +typedef struct MapSAI_Res_UMTS // send authenticate info response UMTS +{ + u32 param_flag; + AuthSetListUmts_st authlist; //authenticationSetList + struct + { + u8 auth_len; + EpsAuthSet_s eps_auth_set[AUTHLIST_LEN]; + }eps_authlist; //eps-AuthenticationSetList + u8 user_error; + u8 provider_error; +}MapSAI_Res_UMTS; + +typedef struct MapSAI_Res // send authenticate info response +{ + u32 param_flag; + Auth_e choice_flag; + union + { + struct + { + struct + { + u8 auth_len; + struct AuthSet_struct auth_set[AUTHLIST_LEN]; + } authlist; //authenticationSetList + }gsm; + struct + { + AuthSetListUmts_st authlist; //authenticationSetList + struct + { + u8 auth_len; + EpsAuthSet_s eps_auth_set[AUTHLIST_LEN]; + }eps_authlist; //eps-AuthenticationSetList + }umts; + }choice; + u8 user_error; + u8 provider_error; +}MapSAI_Res; +/*typedef struct MapSAI_Res // send authenticate info response +{ + u32 param_flag; + union + { + AuthSetListGsm_st gsm; + AuthSetListUmts_st umts; + }choice; + u8 user_error; + u8 provider_error; +} MapSAI_Res; +*/ + +//add by gxchen start +typedef enum _AuthFailCause_e +{ + AUTH_WRONG_USER_RESPONSE = 0, //wrong user response + AUTH_WRONG_NET_SIGNATURE = 1 //wrong network signature +}AuthFailCause_e; +typedef enum _AuthAccessType_e +{ + AUTH_CALL = 0, //call + AUTH_EMER_CALL = 1, //emergencyCall + AUTH_LOC_UPDATE = 2, //locationUpdating + AUTH_SU_SERVICE = 3, //supplementaryService + AUTH_SMS = 4, //shortMessage + AUTH_GPRS_ATTACH = 5, //gprsAttach + AUTH_RA_UPDATE = 6, //routingAreaUpdating + AUTH_SER_REQUEST = 7, //serviceRequest + AUTH_PDP_CON_ACT = 8, //pdpContextActivation + AUTH_PDP_CON_DEACT = 9, //pdpContextDeactivation + AUTH_GPRS_DETACH = 10, //gprsDetach +}AuthAccessType_e; +typedef enum _AuthFailReportError_e +{ + AUTH_SYS_FAIL = 0, //system failure + AUTH_UNEXP_VAL = 1, //unexpected data value + AUTH_UNK_SUB = 2 //unknown subscriber +}AuthFailReportError_e; + +typedef struct MapAuthFailReport_Arg //authentication failure report argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + AuthFailCause_e cause; + u8 reattemp; // 0: fail, 1: true + AuthAccessType_e access_type; + u8 rand[RAND_LEN]; + u8 vlr_num[ISDN_LEN+1]; // vlr-number [0] + u8 sgsn_num[ISDN_LEN+1]; // sgsn-number [1] +}MapAuthFailReport_Arg; + +typedef struct MapAuthFailReport_Res //authentication failure report response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +}MapAuthFailReport_Res; +//add by gxchen end + +typedef struct MapCIMEI_Arg // check IMEI argument +{ + u32 param_flag; + u8 imei[IMEI_LEN]; +} MapCIMEI_Arg; + +typedef struct MapCIMEI_Res // check IMEI response +{ + u32 param_flag; + enum EquipStatus_enum equip_status; // equipment status + u8 user_error; + u8 provider_error; +} MapCIMEI_Res; + +typedef struct MapISD_Arg // insert subscriber data argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; //(0) + u8 msisdn[ISDN_LEN+1]; //(1) + u8 category; //(2) + enum SubStatus_enum sub_status; //(3)subscriber status + struct OdbData_struct odb_data; //(4) + u32 bearer_data; //(5) + u16 tele_data; //(6) + struct ExtSsInfo_struct ss_info; //(7) + u8 roam_feature; //(8)roaming restriction due to unsupported feature + struct + { + u8 list_len; + u8 zone_code[ZONECODE_LEN][2]; + } zc_list; //(9):zone code list + struct + { + u8 list_len; + struct VBSData_struct vbs_data[VBS_LEN]; + } vbsdata_list; //(10):VBS data list + struct + { + u8 list_len; + struct VGCData_struct vgc_data[VGCS_LEN]; + } vgcdata_list; //(11)VGC data list + struct VCSubsInfo_struct subs_info; //(12)VLR Camel subscription info + struct NaeaPrefCi_struct naea_ci; //(13)NAEA preferred CI + struct GprsSubsData_struct gprs_data; //(14)GPRS subscription data + u8 roamsgsn_feature; //(15)roaming restricted in SGSN due to unsupported feature + enum NetAccMode_enum net_mode; //(16)network access mode + + //struct LsaInfo_s lsa_info;//lsaInformation + u8 lmu_ind; //lmu-Indicator + //struct LcsInfo_s lcs_info;//lcsInformation + //umts add by gxchen + u8 ist_alert_timer; //istAlertTimer + u8 chg_supp_hlr[7]; //superChargerSupportedInHLR + struct McSSInfo_s mc_ss_info; //mc-SS-Info + u8 cs_allo_prior; //cs-AllocationRetentionPriority + struct SgsnCamelSub_s sgsn_camel_sub; //sgsn-CAMEL-SubscriptionInfo + u8 chg_char[2]; //chargingCharacteristics + u8 acc_restrict_data; //accessRestrictionData + u8 ics_ind; //ics-Indicator + //eps-SubscriptionData + //csg-SubscriptionDataList +}MapISD_Arg; + +typedef struct MapISD_Res // insert subscriber data response +{ + u32 param_flag; + u16 tele_data; + u32 bearer_data; + struct + { + u8 sslist_len; + u8 ss_code[SS_LEN]; + } ss_list; // ss list + u32 odb_data; // odb general data + enum RegSubsRes_enum subs_res; // regional subscription response + u8 camel_phase[3]; // supported camel phases + + //umts add by gxchen + u16 offer_camel; //offeredCamel4CSIs + u32 supp_feat; //supportedFeatures + + u8 user_error; + u8 provider_error; +} MapISD_Res; + +typedef struct MapSP_Arg//send parameters argument +{ + u8 param_flag; + SubId_struct sub_id; + u8 ReqPara_num; + u8 ReqPara[2]; +} MapSP_Arg; + +typedef struct Sub_data_struct +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; //(0) **** unused + u8 msisdn[ISDN_LEN+1]; //(1) + u8 category; //(2) + enum SubStatus_enum sub_status; //(3)subscriber status + struct OdbData_struct odb_data; //(4) + u32 bearer_data; //(5) + u16 tele_data; //(6) + struct ExtSsInfo_struct ss_info; //(7) + u8 roam_feature; //(8)roaming restriction due to unsupported feature + struct + { + u8 list_len; + u8 zone_code[ZONECODE_LEN][2]; + } zc_list; //(9):zone code list +} Sub_data_struct; + +typedef struct SendParaList +{ + u32 choice_flag;//1=IMSI, 2=AuthenticationSet, 4==SubscriberData,8=Ki, Others:Null + union + { + u8 imsi[IMSI_LEN]; //imsi + struct AuthSet_struct auth_set; + struct Sub_data_struct sub_data; //subscriber data + u8 ki[16]; //ki + } SP_Res_Choice; +} SendParaList; + +typedef struct MapSP_Res // Send parameters response +{ + u32 param_flag; + u8 sendparamlist_num; + struct SendParaList sendparalist[6]; //sentparalist + u8 user_error; + u8 provider_error; +}MapSP_Res; + + + +typedef struct MapDSD_Arg // delete subscriber data argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + struct BSCode_struct bs_code; + struct + { + u8 sslist_len; + u8 ss_code[SS_LEN]; + } ss_list; // ss list + u8 roam_feature; // roaming restriction due to unsupported feature + u8 regional_ident[2]; // regional subscription identifier (zone code) + u8 vbsg_ind; // vbs group indication + u8 vgcsg_ind; // vgcs group indication + u8 camel_withdraw; // camel subscription info withdraw + struct GprsSDWithdraw_struct gprs_withdraw; // gprs subscription data withdraw + u8 roamsgsn_feature; // roaming restricted in SGSN due to unsupported feature + + //lsaInformationWithdraw + //gmlc-ListWithdraw + //umts add by gxchen + u8 ist_info_withdraw; //istInformationWithdraw + u32 spe_csi_withdraw; //specificCSI-Withdraw + u8 chg_char_withdraw; //chargingCharacteristicsWithdraw + u8 stn_sr_withdraw; //stn-srWithdraw + struct GprsSDWithdraw_struct eps_sub_withdraw; //epsSubscriptionDataWithdraw + u8 apn_replace_withdraw; //apn-oi-replacementWithdraw + u8 csg_sub_del; //csg-SubscriptionDeleted +} MapDSD_Arg; + +typedef struct MapDSD_Res // delete subscriber data response +{ + u32 param_flag; + enum RegSubsRes_enum subs_res; // regional subscription response + u8 user_error; + u8 provider_error; +} MapDSD_Res; + +typedef struct MapReset_Arg // reset argument +{ + u32 param_flag; + u8 hlr_num[ISDN_LEN+1]; // hlr number + struct + { + u8 list_len; + u8 hlr_id[HLRID_NUM][IMSI_LEN]; + } hlr_list; // HLR list + u8 networkResource; +} MapReset_Arg; + +typedef struct MapRD_Arg // restore data argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 lmsi[LMSI_LEN]; + struct VlrCap_struct vlr_cap; // vlr capability +} MapRD_Arg; + +typedef struct MapRD_Res // restore data response +{ + u32 param_flag; + u8 hlr_num[ISDN_LEN+1]; + u8 msnot_reach; // MS not reachable + u8 user_error; + u8 provider_error; +} MapRD_Res; + +typedef struct MapSRIFG_Arg // send routing info for GPRS argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 ggsn_add[GSN_LEN+1]; // GGSN address + u8 ggsn_num[ISDN_LEN+1]; // GGSN number +} MapSRIFG_Arg; + +typedef struct MapSRIFG_Res // send routing info for GPRS response +{ + u32 param_flag; + u8 sgsn_add[GSN_LEN+1]; // SGSN address + u8 ggsn_add[GSN_LEN+1]; // GGSN address + u8 mobile_reason; // mobile not reachable reason + u8 user_error; + u8 provider_error; +} MapSRIFG_Res; + +typedef struct MapFR_Arg // failure report argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 ggsn_num[ISDN_LEN+1]; // GGSN number + u8 ggsn_add[GSN_LEN+1]; // GGSN address +} MapFR_Arg; + +typedef struct MapFR_Res // failure report response +{ + u32 param_flag; + u8 ggsn_add[GSN_LEN+1]; // GGSN address + u8 user_error; + u8 provider_error; +} MapFR_Res; + +typedef struct MapNMPFG_Arg // note MS present for GPRS argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 sgsn_add[GSN_LEN+1]; // SGSN address + u8 ggsn_add[GSN_LEN+1]; // GGSN address +} MapNMPFG_Arg; + +typedef struct MapNMPFG_Res // note MS present for GPRS response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapNMPFG_Res; + +/* +++++++++++++++++++++++++++++ */ +/* MAP-H (with AUC) structure */ +/* +++++++++++++++++++++++++++++ */ +typedef struct MapST_Arg // security triplets argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 hlr_id[HLRID_LEN]; +// Authlist_e choice_flag; + + //add by gxchen start + u8 num_req_vec; //number of requested vectors (1...5) + u8 seg_prohibit; //segmentationProhibited + u8 imm_res_prefer; //immediateResponsePreferred + AuthReSynInfo_st resyn_info; //re-synchronisation info + AuthNodeType_e node_type; //requestingNodeType + u8 req_plmn_id[3]; //requestingPLMN-Id + u8 num_req_add_vec; //number of requested additional vectors (1...5) + u8 add_vec_eps; //additionalVectorsAreForEPS + //add by gxchen end +} MapST_Arg; + +//modify by gxchen +typedef struct MapST_Res // security triplets response +{ + u32 param_flag; + Authlist_e choice_flag; //0:triplet, 1:quintuplet + union + { + struct + { + u8 tri_len; + Triplet_st triplet[AUTHLIST_LEN]; + }tri_list; + struct + { + u8 quin_len; + Quintuplet_st quintuplet[AUTHLIST_LEN]; + }quin_list; + }choice; + u8 user_error; + u8 provider_error; +} MapST_Res; + +typedef struct MapIS_Arg // interrogation subscriber argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 hlr_id[HLRID_LEN]; +} MapIS_Arg; + +typedef struct MapIS_Res // interrogation subscriber response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapIS_Res; + +typedef struct MapCS_Arg // create subscriber argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 hlr_id[HLRID_LEN]; +} MapCS_Arg; + +typedef struct MapCS_Res // create subscriber response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapCS_Res; + +typedef struct MapDS_Arg // delete subscriber argument +{ + u32 param_flag; + u8 imsi[IMSI_LEN]; + u8 hlr_id[HLRID_LEN]; +} MapDS_Arg; + +typedef struct MapDS_Res // delete subscriber response +{ + u32 param_flag; + u8 user_error; + u8 provider_error; +} MapDS_Res; + +/********** OPR *******************/ +typedef struct MapDetermineOprUser_Arg +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 imei[IMEI_LEN]; + u8 roamingRestraintFlag; +} MapDetermineOprUser_Arg; + +typedef struct MapDetermineOprUser_Res +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 imei[IMEI_LEN]; + u8 oprflag; + u8 msisdn[ISDN_LEN+1]; +} MapDetermineOprUser_Res; + +typedef struct MapVlrUpdateLocation_Arg +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 status; +} MapVlrUpdateLocation_Arg; + +typedef struct MapVlrUpdateLocation_Res +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 status; + u8 error; +} MapVlrUpdateLocation_Res; + +typedef struct MapCreateUserWithMsisdnImsi_Arg +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 msisdn[ISDN_LEN+1]; + u8 imsiflag; + u8 camelflag; +} MapCreateUserWithMsisdnImsi_Arg; + +typedef struct MapCreateUserWithMsisdnImsi_Res +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 msisdn[ISDN_LEN+1]; + u8 result; + u8 cause; +} MapCreateUserWithMsisdnImsi_Res; + + +typedef struct MapDeleteOprUser_Arg +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 msisdn[ISDN_LEN+1]; +} MapDeleteOprUser_Arg; + +typedef struct MapDeleteOprUser_Res +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 msisdn[ISDN_LEN+1]; + u8 result; + u8 cause; +} MapDeleteOprUser_Res; + +/********** OPR *******************/ +/********** IMDM *******************/ +typedef struct MapVlrEnquiryIMDM_Arg +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 msisdn[ISDN_LEN+1]; + +}MapVlrEnquiryIMDM_Arg; + +typedef struct MapVlrEnquiryIMDM_Res +{ + u32 param_flag; + u8 imsi[IMSI_LEN+1]; + u8 msisdn[ISDN_LEN+1]; + u8 status; +}MapVlrEnquiryIMDM_Res; +/********** IMDM *******************/ + +/**** is41 *****/ +#define MAX_IS41POPR_LEN 1024 + +typedef struct IS41ParBearerData +{ + u32 param_flag; + u8 MessageId[3]; + u8 UserDataLen; + u8 UserData[128]; + u8 UserRespondingCode; + u8 MessageCenterTimeStamp[6]; + u8 ValidityPeriod_Absolute[6]; + u8 ValidityPeriod_Relative; + u8 DeferredDeliveryTime_Absolute[6]; + u8 DeferredDeliveryTime_Relative; + u8 PriorityIndicator; + u8 PrivacyIndicator; + u8 ReplyOption; + u8 NumberOfMessages; + u8 AlertOnMessageDelivery; + u8 LanguageIndicator; + u8 CallBackNumberLen; + u8 CallBackNumber[MAX_IS41_VARPAR_LEN]; + u8 MessageDisplayMode; + u8 MultipleEncodingUserDataLen; + u8 MultipleEncodingUserData[MAX_IS41_VARPAR_LEN]; + u8 MessageStatus; + u8 TPFailureCause; +}IS41ParBearerData; + +/**IS41 Auc operation **/ +typedef struct IS41_AUTHDIR_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + +//optional part---> + u8 aav; + u8 authu[3]; + u8 count; + u8 denacc; + u8 locid[2]; + u8 randssd[7]; + u8 randu[3]; + u8 senderinLen; + u8 senderin[32]; + u8 ssd[16]; + u8 nossd; + u8 updcount; +}IS41_AUTHDIR_ARG; + +typedef struct IS41_AUTHDIR_RSP +{ + u32 param_flag; + +//optional part---> + u8 count; +}IS41_AUTHDIR_RSP; + +typedef struct IS41AucDirectiveForward_arg +{ + u32 param_flag; + + u8 InterMSCCircuitID[2]; + u8 MobileIdentificationNumber[MIN_LEN]; + +//optional part---> + u8 AuthenticationResponseUniqueChallenge[3]; + u8 RandomVariableUniqueChallenge[3]; +}IS41AucDirectiveForward_arg; + +typedef struct IS41_AFREPORT_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 rpttyp1; + u8 sysacctype; + u8 syscap; + +//optional part---> + u8 count; + u8 countex; + u8 mscid[3]; + u8 rpttyp2; + u8 senderinLen; + u8 senderin[32]; +}IS41_AFREPORT_ARG; + +typedef struct IS41_AFREPORT_RSP +{ + u32 param_flag; + +//optional part---> + u8 aav; + u8 authu[3]; + u8 count; + u8 denacc; + u8 randssd[7]; + u8 randu[3]; + u8 ssd[16]; + u8 nossd; + u8 termtyp; + u8 updcount; + + u8 user_error; + u8 provider_error; +}IS41_AFREPORT_RSP; + +typedef struct IS41_AUTHREQ_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 mscid[3]; // serving MSC + u8 sysacctype; + u8 syscap; // serving + +// optional part---> + u8 authdata[3]; + u8 authr[3]; + u8 count; + u8 cmodes; // actual + u8 DigitsLen; + u8 digits[32]; // dialed + u8 pcssn[5]; + u8 rand[4]; + u8 senderinLen; + u8 senderin[32]; + u8 termtyp; +}IS41_AUTHREQ_ARG; + +typedef struct IS41_AUTHREQ_RSP +{ + u32 param_flag; + +//optional part--> + u8 aav; + u8 authu[3]; + u8 count; + u8 cdmaplcm[6]; + u8 denacc; + u8 randssd[7]; + u8 randu[3]; + u8 ssd[16]; + u8 smekey[8]; + u8 nossd; + u8 updcount; + u8 vpmask[66]; + + u8 user_error; + u8 provider_error; +}IS41_AUTHREQ_RSP; + +typedef struct IS41_ASREPORT_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 syscap; // serving + +//optional part---> + u8 CntUpdRepLen; + u8 countrpt[32]; + u8 senderinLen; + u8 senderin[32]; + u8 SSDUpdRepLen; + u8 ssdurpt[32]; + u8 UniChaRepLen; + u8 uchalrpt[32]; +}IS41_ASREPORT_ARG; + +typedef struct IS41_ASREPORT_RSP +{ + u32 param_flag; + +//optional part---> + u8 aav; + u8 authu[3]; + u8 count; + u8 denacc; + u8 randssd[7]; + u8 randu[3]; + u8 ssd[16]; + u8 nossd; + u8 updcount; + + u8 user_error; + u8 provider_error; +}IS41_ASREPORT_RSP; + +typedef struct IS41_BSCHALL_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 randbs[4]; + +//optional part---> + u8 senderinLen; + u8 senderin[32]; +}IS41_BSCHALL_ARG; + +typedef struct IS41_BSCHALL_RSP +{ + u32 param_flag; + + u8 authbs[3]; + + u8 user_error; + u8 provider_error; +}IS41_BSCHALL_RSP; + +typedef struct IS41_COUNTREQ_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 senderinLen; + u8 senderin[32]; +}IS41_COUNTREQ_ARG; + +typedef struct IS41_COUNTREQ_RSP +{ + u32 param_flag; + + u8 count; +}IS41_COUNTREQ_RSP; + +/* IS41 Auc operation **/ + + +/* IS41 SMSC operation **/ +typedef struct IS41_SMDBACK_ARG +{ + u32 param_flag; + + u8 imsccid[2]; + u8 min[MIN_LEN]; + u8 BearerDataLen; + u8 BearerData[256]; + u8 smstidLen; + u8 smstid[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSTID + + //optional part---> + u8 esn[4]; + u8 smscidLen; + u8 smscid[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSCID + u8 smsdaLen; + u8 smsda[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSDA + u8 smsodaLen; + u8 smsoda[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSODA + u8 smsodsLen; + u8 smsods[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSODS + u8 smsooaLen; + u8 smsooa[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOOA + u8 smsoosLen; + u8 smsoos[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOOS + u8 smsoaLen; + u8 smsoa[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOA +}IS41_SMDBACK_ARG; + +typedef struct IS41_SMDBACK_RSP +{ + u32 param_flag; + + u8 BearerDataLen; + u8 BearerData[256]; + + u8 smsccLen; + u8 smscc[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSCC +}IS41_SMDBACK_RSP; + + +typedef struct IS41_SMDFWD_ARG +{ + u32 param_flag; + + u8 imsccid[2]; + u8 min[MIN_LEN]; + + u8 BearerDataLen; + u8 BearerData[256]; + u8 smstidLen; + u8 smstid[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSTID + + //optional part---> + u8 esn[4]; + u8 smscidLen; + u8 smscid[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSCID + u8 smsdaLen; + u8 smsda[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSDA + u8 smsodaLen; + u8 smsoda[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSODA + u8 smsodsLen; + u8 smsods[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSODS + u8 smsooaLen; + u8 smsooa[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOOA + u8 smsoosLen; + u8 smsoos[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOOS + u8 smsoaLen; + u8 smsoa[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOA +}IS41_SMDFWD_ARG; + +typedef struct IS41_SMDFWD_RSP +{ + u32 param_flag; + + u8 BearerDataLen; + u8 BearerData[256]; + u8 smsccLen; + u8 smscc[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSCC +}IS41_SMDFWD_RSP; + + +typedef struct IS41_SMDPP_ARG +{ + u32 param_flag; + + u8 BearerDataLen; + u8 BearerData[256]; + u8 smstidLen; + u8 smstid[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSTID + + //optional part---> + u8 esn[4]; + u8 min[MIN_LEN]; + u8 smscidLen; + u8 smscid[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSCID + u8 smsdaLen; + u8 smsda[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSDA + u8 smsmsgcntLen; + u8 smsmsgcnt[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSMSGCNT + u8 smsnotindLen; + u8 smsnotind[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSNOTIND + + u8 smsodaLen; + u8 smsoda[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSODA + u8 smsodsLen; + u8 smsods[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSODS + u8 smsooaLen; + u8 smsooa[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOOA + u8 smsoosLen; + u8 smsoos[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOOS + u8 smsoaLen; + u8 smsoa[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSOA +}IS41_SMDPP_ARG; + +typedef struct IS41_SMDPP_RSP +{ + u32 param_flag; + + u8 BearerDataLen; + u8 BearerData[256]; + u8 smsccLen; + u8 smscc[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSCC +}IS41_SMDPP_RSP; + +typedef struct IS41_SMSNOT_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + + //optional part---> + u8 smsaccdenLen; + u8 smsaccden[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSACCDEN + u8 smsaddrLen; + u8 smsaddr[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSADDR +}IS41_SMSNOT_ARG; + +typedef struct IS41_SMSNOT_RSP +{ + u32 param_flag; + //NULL +}IS41_SMSNOT_RSP; + +typedef struct IS41_SMSREQ_ARG +{ + u32 param_flag; + + u8 min[MIN_LEN]; + + //optional part---> + u8 esn[4]; + u8 smsnotindLen; + u8 smsnotind[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSNOTIND + u8 smstidLen; + u8 smstid[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSTID +}IS41_SMSREQ_ARG; + +typedef struct IS41_SMSREQ_RSP +{ + u32 param_flag; + + //optional part---> + u8 esn[4]; + u8 smsaccdenLen; + u8 smsaccden[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSACCDEN + u8 smsaddrLen; + u8 smsaddr[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSADDR + + u8 user_error; + u8 provider_error; +}IS41_SMSREQ_RSP; + +typedef struct IS41_PAR_TRIGGER_LIST +{ + u32 param_flag; + + u8 destaddrLen; + u8 destaddr[32]; //DestinationAddress -- choice global title + u8 wintriglistLen; + u8 wintriglist[32]; //WIN_TriggerList +}IS41_PAR_TRIGGER_LIST; + +typedef struct IS41_PAR_WIN_CAP +{ + u32 param_flag; + + u8 triggercapLen; + u8 triggercap[32]; //TriggerCapability + u8 winoprcapLen; + u8 winoprcap[32]; //WIN_OperationsCapability +}IS41_PAR_WIN_CAP; + +typedef struct IS41_PAR_PROFILE +{ + u32 param_flag; + +// optional + u8 authcapLen; + u8 authcap[32];//AuthenticationCapability,IMPLICIT OCTET STRING + u8 cfiLen; + u8 cfi[32];//CallingFeaturesIndicator,IMPLICIT OCTET STRING + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits,IMPLICIT DigitsType + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits,IMPLICIT DigitsType + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits,IMPLICIT DigitsType + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits,IMPLICIT DigitsType + u8 geoauthLen; + u8 geoauth[32];//GeographicAuthorization,IMPLICIT OCTET STRING + u8 mwncountLen; + u8 mwncount[32];//MessageWaitingNotificationCount,IMPLICIT OCTET STRING + u8 mwntypeLen; + u8 mwntype[32];//MessageWaitingNotificationType,IMPLICIT OCTET STRING + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 origind;//OriginationIndicator,IMPLICIT Unsigned Enumerated + u8 origtrigLen; + u8 origtrig[32];//OriginationTriggers,IMPLICIT OCTET STRING + u8 pacaind;//PACAIndicator,IMPLICIT OCTET STRING + u8 plind;//PreferredLanguageIndicator,IMPLICIT OCTET STRING + u8 resdgtsLen; + u8 resdgts[32];//RestrictionDigits,IMPLICIT DigitsType + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits,IMPLICIT Digits Type + u8 smsorgres;//SMS_OriginationRestrictions,IMPLICIT OCTET STRING + u8 smstermres;//SMS_TerminationRestrictions,IMPLICIT OCTET STRING + u8 spinipinLen; + u8 spinipin[32];//SPINIPIN,IMPLICIT DigitsType + u8 spinitrigLen; + u8 spinitrig[32];//SPINITriggers,IMPLICIT OCTET STRING + u8 termres;//TerminationRestrictionCode,IMPLICIT Unsigned Enumerated + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING + u8 triggerlistnum; + IS41_PAR_TRIGGER_LIST triggerlist[MAX_IS41_TRIG_LIST_NUM]; //TriggerAddressList, IMPLICIT SET OF + +}IS41_PAR_PROFILE; + +typedef struct IS41_PAR_ISTERM +{ + u32 param_flag; + + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits,IMPLICIT DigitsType + u8 mscid[3];//serving + +//optional + u8 accden;//AccessDeniedReason,IMPLICIT Unsigned Enumerated + u8 billid[7];//BillingID,IMPLICIT OCTET STRING + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits,IMPLICIT DigitsType + u8 esn[4]; + u8 leginfoLen; + u8 leginfo[32];//LegInformation IMPLICIT OCTET STRING + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 min[MIN_LEN]; + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber,IMPLICIT Digits Type + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits,IMPLICIT Digits Type + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING +}IS41_PAR_ISTERM; + +typedef struct IS41_PAR_LOCTERM +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 termtrmtLen; + u8 termtrmt[32];//TerminationTreatment,IMPLICIT OCTET STRING + +//optional + u8 alrtcodeLen; + u8 alrtcode[32];//AlertCode,IMPLICIT OCTET STRING + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits,IMPLICIT DigitsType + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits,IMPLICIT DigitsType + u8 leginfoLen; + u8 leginfo[32];//LegInformation IMPLICIT OCTET STRING + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator,IMPLICIT OCTET STRING + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits,IMPLICIT Digits Type + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING + u8 vmspinLen; + u8 vmspin[32];//VoiceMailboxPIN,IMPLICIT DigitsType + u8 vmboxLen; + u8 vmbox[32];//VoiceMailboxNumber,IMPLICIT DigitsType +}IS41_PAR_LOCTERM; + +typedef struct IS41_PAR_PSTNTERM +{ + u32 param_flag; + + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits,IMPLICIT DigitsType + +//optional + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits,IMPLICIT DigitsType + u8 esn[4]; + u8 leginfoLen; + u8 leginfo[32];//LegInformation IMPLICIT OCTET STRING + u8 min[MIN_LEN]; + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits,IMPLICIT Digits Type + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING +}IS41_PAR_PSTNTERM; + +typedef struct IS41_PAR_TERMLIST +{ + u32 param_flag; + + IS41_PAR_ISTERM isterm; + IS41_PAR_LOCTERM locterm; + IS41_PAR_PSTNTERM pstnterm; +}IS41_PAR_TERMLIST; + +typedef struct IS41_REGNOT_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 mscid[3]; + u8 qualcode;//QualificationInformationCode,IMPLICIT Unsigned Enumerated + u8 mytyp;//SystemMyTypeCode,IMPLICIT Unsigned Enumerated + +//optional + u8 avtyp;//Availability Type,IMPLICIT OCTET STRING + u8 bordacc;//BorderCellAccess,IMPLICIT Unsigned Enumerated + u8 ccdata[4];//ControlChannelData,IMPLICIT OCTET STRING + u8 extmscid[4];//ExtendedMSCID,IMPLICIT OCTET STRING + u8 locid[2];//LocationAreaID,IMPLICIT OCTET STRING + u8 pcssn[5]; + u8 rsigqual;//ReceivedSignalQuality,IMPLICIT Unsigned Integer + u8 rpttyp; + u8 senderinLen; + u8 senderin[32]; + u8 smsaddrLen; + u8 smsaddr[MAX_IS41_VARPAR_LEN];//IS41PAR_SMSADDR + u8 smsmwi;//SMS_MessageWaitingIndicator null,zero length + u8 sysaccdata[5];//SystemAccessData,IMPLICIT OCTET STRING + u8 sysacctype; + u8 syscap; + u8 termtyp; + u8 transcapLen; + u8 transcap[32];//TransactionCapability,IMPLICIT OCTET STRING + IS41_PAR_WIN_CAP wincap; +}IS41_REGNOT_ARG; + +typedef struct IS41_REGNOT_RSP +{ + u32 param_flag; + + u8 mytyp;//SystemMyTypeCode,IMPLICIT Unsigned Enumerated + +//optional + u8 authden;//AuthorizationDenied,IMPLICIT Unsigned Enumerated + u8 authper[2];//AuthorizationPeriod,IMPLICIT OCTET STRING + u8 ccdata[4];//ControlChannelData,IMPLICIT OCTET STRING + u8 denauthperLen; + u8 denauthper[32];//DeniedAuthorizationPeriod,IMPLICIT OCTET STRING + u8 digitsCarrierLen; + u8 digitsCarrier[32]; // carrier + u8 digitsDestLen; + u8 digitsDest[32]; // Destination + u8 mscid[3]; // HLR + + IS41_PAR_PROFILE profile; + + u8 rsigqual;//ReceivedSignalQuality,IMPLICIT Unsigned Integer + u8 senderinLen; + u8 senderin[32]; + u8 smsmwi;//SMS_MessageWaitingIndicator null,zero length + u8 sysaccdata[5];//SystemAccessData,IMPLICIT OCTET STRING + + u8 user_error; + u8 provider_error; +}IS41_REGNOT_RSP; + +typedef struct IS41_REGCANC_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + +//optional + u8 canctyplen; + u8 canctyp[4];//Cancellation Type,IMPLICIT OCTET STRING + u8 ccdata[4];//ControlChannelData,IMPLICIT OCTET STRING + u8 rsigqual;//ReceivedSignalQuality,IMPLICIT Unsigned Integer + u8 senderinLen; + u8 senderin[32]; + u8 sysaccdata[5];//SystemAccessData,IMPLICIT OCTET STRING +}IS41_REGCANC_ARG; + +typedef struct IS41_REGCANC_RSP +{ + u32 param_flag; + +//optional + u8 count; //CallHistoryCount + u8 cancdenied; //CancellationDenied, IMPLICIT Unsigned Enumerated + u8 ccdata[4];//ControlChannelData,IMPLICIT OCTET STRING + u8 rsigqual;//ReceivedSignalQuality,IMPLICIT Unsigned Integer + u8 smsmwi;//SMS_MessageWaitingIndicator null,zero length + u8 sysaccdata[5];//SystemAccessData,IMPLICIT OCTET STRING +}IS41_REGCANC_RSP; + +typedef struct IS41_LOCREQ_ARG +{ + u32 param_flag; + + u8 billid[7];//BillingID,IMPLICIT OCTET STRING + u8 digitsLen; + u8 digits[32]; // originating + u8 mscid[3];//originating + u8 mytyp;//SystemMyTypeCode,IMPLICIT Unsigned Enumerated + +//optional + u8 cpndgts1Len; + u8 cpndgts1[32];//CallingPartyNumberDigits1,IMPLICIT Digits Type + u8 cpndgts2Len; + u8 cpndgts2[32];//CallingPartyNumberDigits2,IMPLICIT Digits Type + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress,IMPLICIT Subaddress + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber,IMPLICIT Digits Type + u8 pcssn[5]; + u8 rndgtsLen; + u8 rndgts[32];//RedirectingNumberDigits,IMPLICIT Digits Type + u8 rsubLen; + u8 rsub[32];//RedirectingSubaddress,IMPLICIT Subaddress + u8 tat;//TerminationAccessType,IMPLICIT OCTET STRING + u8 transcapLen; + u8 transcap[32];//TransactionCapability,IMPLICIT OCTET STRING + IS41_PAR_WIN_CAP wincap; +}IS41_LOCREQ_ARG; + +typedef struct IS41_LOCREQ_RSP +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 mscid[3]; + +//optional + u8 accden;//AccessDeniedReason,IMPLICIT Unsigned Enumerated + u8 annlistLen; + u8 annlist[32];//AnnouncementList SEQUENCE OF + u8 cpnstrg1Len; + u8 cpnstrg1[32];//CallingPartyNumberString1,IMPLICIT Digits Type + u8 cpnstrg2Len; + u8 cpnstrg2[32];//CallingPartyNumberString2,IMPLICIT Digits Type + u8 digitsCarrierLen; + u8 digitsCarrier[32]; // carrier + u8 digitsDestLen; + u8 digitsDest[32]; // Destination + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits,IMPLICIT DigitsType + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits,IMPLICIT DigitsType + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits,IMPLICIT DigitsType + u8 redindLen; + u8 redind[32];//DMH_RedirectionIndicator,IMPLICIT ENUMERATED + u8 grpinfoLen; + u8 grpinfo[32];//GroupInformation,IMPLICIT OCTET STRING + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 natimeLen; + u8 natime[32];//NoAnswerTime,IMPLICIT OCTET STRING + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator,IMPLICIT OCTET STRING + u8 pcssn[5]; + u8 rndgtsLen; + u8 rndgts[32];//RedirectingNumberDigits,IMPLICIT Digits Type + u8 rnstringLen; + u8 rnstring[32];//RedirectingNumberString,IMPLICIT Digits Type + u8 rsubLen; + u8 rsub[32];//RedirectingSubaddress,IMPLICIT Subaddress + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits,IMPLICIT Digits Type + IS41_PAR_TERMLIST termlist;//TerminationList,SET OF CHOICE + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING + u8 triggerlistnum; + IS41_PAR_TRIGGER_LIST triggerlist[MAX_IS41_TRIG_LIST_NUM]; //TriggerAddressList, IMPLICIT SET OF + + + u8 user_error; + u8 provider_error; +}IS41_LOCREQ_RSP; + +typedef struct IS41_ROUTREQ_ARG +{ + u32 param_flag; + + u8 billid[7];//BillingID,IMPLICIT OCTET STRING + u8 esn[4]; + u8 min[MIN_LEN]; + u8 mscid[3];//originating MSC + u8 mytyp;//SystemMyTypeCode,IMPLICIT Unsigned Enumerated + +//optional + u8 alrtcodeLen; + u8 alrtcode[32];//AlertCode,IMPLICIT OCTET STRING + u8 cpnstrg1Len; + u8 cpnstrg1[32];//CallingPartyNumberString1,IMPLICIT Digits Type + u8 cpnstrg2Len; + u8 cpnstrg2[32];//CallingPartyNumberString2,IMPLICIT Digits Type + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress,IMPLICIT Subaddress + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits,IMPLICIT DigitsType + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits,IMPLICIT DigitsType + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits,IMPLICIT DigitsType + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits,IMPLICIT DigitsType + u8 leginfoLen; + u8 leginfo[32];//LegInformation,IMPLICIT OCTET STRING + u8 locid[2]; + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber,IMPLICIT Digits Type + u8 natimeLen; + u8 natime[32];//NoAnswerTime,IMPLICIT OCTET STRING + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator,IMPLICIT OCTET STRING + u8 pcssn[5]; + u8 pilotbid[7];//PilotBillingID,IMPLICIT OCTET STRING + u8 pilotLen; + u8 pilot[32];//PilotNumber,IMPLICIT DigitsType + u8 rnstringLen; + u8 rnstring[32];//RedirectingNumberString,IMPLICIT Digits Type + u8 rsubLen; + u8 rsub[32];//RedirectingSubaddress,IMPLICIT Subaddress + u8 senderinLen; + u8 senderin[32]; + u8 termtrmtLen; + u8 termtrmt[32];//TerminationTreatment,IMPLICIT OCTET STRING + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING + u8 vmboxLen; + u8 vmbox[32];//VoiceMailboxNumber,IMPLICIT DigitsType + u8 vmspinLen; + u8 vmspin[32];//VoiceMailboxPIN,IMPLICIT DigitsType +}IS41_ROUTREQ_ARG; + +typedef struct IS41_ROUTREQ_RSP +{ + u32 param_flag; + + u8 mscid[3]; + +//optional + u8 accden;//AccessDeniedReason,IMPLICIT Unsigned Enumerated + u8 billid[7];//BillingID,IMPLICIT OCTET STRING + u8 cden;//ConditionallyDeniedReason + u8 digitsLen; + u8 digits[32]; // dialed + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber,IMPLICIT Digits Type + u8 pcssn[5]; +}IS41_ROUTREQ_RSP; + +typedef struct IS41_MSINACT_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + +//optional part---> + u8 count; + u8 dereg;//DeregistrationType,IMPLICIT Unsigned Enumerated + u8 locid[2]; + u8 senderinLen; + u8 senderin[32]; +// u8 SMS_MessageWaitingIndicator; +}IS41_MSINACT_ARG; + +typedef struct IS41_MSINACT_RSP +{ + u32 param_flag; + +}IS41_MSINACT_RSP;//empty response + +typedef struct IS41_QUALDIR_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 qualcode;//QualificationInformationCode,IMPLICIT Unsigned Enumerated + u8 mytyp;//SystemMyTypeCode,IMPLICIT Unsigned Enumerated + +//optional + u8 authden;//AuthorizationDenied,IMPLICIT Unsigned Enumerated + u8 authper[2];//AuthorizationPeriod,IMPLICIT OCTET STRING + u8 denauthperLen; + u8 denauthper[32];//DeniedAuthorizationPeriod,IMPLICIT OCTET STRING + u8 digitsCarrierLen; + u8 digitsCarrier[32];// Carrier + u8 digitsDestLen; + u8 digitsDest[32]; // Destination + u8 locid[2];//LocationAreaID + + IS41_PAR_PROFILE profile; + + u8 senderinLen; + u8 senderin[32]; +}IS41_QUALDIR_ARG; + +typedef struct IS41_QUALDIR_RSP +{ + u32 param_flag; +}IS41_QUALDIR_RSP;//empty response + +typedef struct IS41_FEATREQ_ARG +{ + u32 param_flag; + + u8 digitsLen; + u8 digits[32]; // dialed + u8 esn[4]; + u8 min[MIN_LEN]; + +//optional + u8 billid[7];//BillingID,IMPLICIT OCTET STRING + u8 cpndgts1Len; + u8 cpndgts1[32];//CallingPartyNumberDigits1,IMPLICIT Digits Type + u8 cpndgts2Len; + u8 cpndgts2[32];//CallingPartyNumberDigits2,IMPLICIT Digits Type + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress,IMPLICIT Subaddress + u8 cciLen; + u8 cci[32];//ConferenceCallingIndicator,IMPLICIT OCTET STRING + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 mscid[3]; + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber,IMPLICIT Digits Type + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator,IMPLICIT OCTET STRING + u8 pcssn[5]; + u8 senderinLen; + u8 senderin[32]; + u8 transcapLen; + u8 transcap[32];//TransactionCapability,IMPLICIT OCTET STRING +}IS41_FEATREQ_ARG; + +typedef struct IS41_FEATREQ_RSP +{ + u32 param_flag; + + u8 featresult;//FeatureResult, IMPLICIT Unsigned Enumerated + +//optional + u8 accden;//AccessDeniedReason,IMPLICIT Unsigned Enumerated + u8 actcodeLen; + u8 actcode[32];//ActionCode IMPLICIT OCTET STRING + u8 annlistLen; + u8 annlist[32];//AnnouncementList SEQUENCE OF + u8 cpndgts1Len; + u8 cpndgts1[32];//CallingPartyNumberDigits1,IMPLICIT Digits Type + u8 cpndgts2Len; + u8 cpndgts2[32];//CallingPartyNumberDigits2,IMPLICIT Digits Type + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress,IMPLICIT Subaddress + u8 digitsCarrierLen; + u8 digitsCarrier[32];// Carrier + u8 cciLen; + u8 cci[32];//ConferenceCallingIndicator,IMPLICIT OCTET STRING + u8 digitsLen; + u8 digits[32];// Dialed +/* u8 disptextLen;//do not find + u8 disptext[32];*/ + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits,IMPLICIT DigitsType + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits,IMPLICIT DigitsType + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits,IMPLICIT DigitsType + u8 redindLen; + u8 redind[32];//DMH_RedirectionIndicator,IMPLICIT ENUMERATED + u8 grpinfoLen; + u8 grpinfo[32];//GroupInformation,IMPLICIT OCTET STRING + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 natimeLen; + u8 natime[32];//NoAnswerTime,IMPLICIT OCTET STRING + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator,IMPLICIT OCTET STRING + u8 pacaind;//PACAIndicator,IMPLICIT OCTET STRING + u8 pilotLen; + u8 pilot[32];//PilotNumber,IMPLICIT DigitsType + u8 rndgtsLen; + u8 rndgts[32];//RedirectingNumberDigits,IMPLICIT Digits Type + u8 rnstringLen; + u8 rnstring[32];//RedirectingNumberString,IMPLICIT Digits Type + u8 rsubLen; + u8 rsub[32];//RedirectingSubaddress,IMPLICIT Subaddress + u8 resumepic;//ResumePIC, IMPLICIT Unsigned Enumerated + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits,IMPLICIT Digits Type + IS41_PAR_TERMLIST termlist;//TerminationList,SET OF CHOICE + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING + u8 triggerlistnum; + IS41_PAR_TRIGGER_LIST triggerlist[MAX_IS41_TRIG_LIST_NUM]; //TriggerAddressList, IMPLICIT SET OF + + u8 user_error; + u8 provider_error; + +}IS41_FEATREQ_RSP; + +typedef struct IS41_REDREQ_ARG +{ + u32 param_flag; + + u8 billid[7];//BillingID,IMPLICIT OCTET STRING + u8 esn[4]; + u8 min[MIN_LEN]; + u8 redreason;//RedirectionReason IMPLICIT Unsigned Enumerated + +//optional + u8 leginfoLen; + u8 leginfo[32];//LegInformation IMPLICIT OCTET STRING + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber,IMPLICIT Digits Type +}IS41_REDREQ_ARG; + +typedef struct IS41_REDREQ_RSP +{ + u32 param_flag; +}IS41_REDREQ_RSP;//empty response + +typedef struct IS41_TRANUMREQ_ARG +{ + u32 param_flag; + + u8 esn[4]; + u8 min[MIN_LEN]; + u8 redreason;//RedirectionReason IMPLICIT Unsigned Enumerated + u8 mytyp;//SystemMyTypeCode,IMPLICIT Unsigned Enumerated + +//optional + u8 billid[7];//BillingID,IMPLICIT OCTET STRING + u8 grpinfoLen; + u8 grpinfo[32];//GroupInformation,IMPLICIT OCTET STRING + u8 leginfoLen; + u8 leginfo[32];//LegInformation IMPLICIT OCTET STRING + u8 mscid[3];//originating MSC + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber,IMPLICIT Digits Type + u8 pilotbid[7];//PilotBillingID,IMPLICIT OCTET STRING + u8 pilotLen; + u8 pilot[32];//PilotNumber,IMPLICIT DigitsType + u8 transcapLen; + u8 transcap[32];//TransactionCapability,IMPLICIT OCTET STRING + IS41_PAR_WIN_CAP wincap; +}IS41_TRANUMREQ_ARG; + +typedef struct IS41_TRANUMREQ_RSP +{ + u32 param_flag; + + u8 digitsLen; + u8 digits[32];// Destination + +//optional + u8 accden;//AccessDeniedReason,IMPLICIT Unsigned Enumerated + u8 actcodeLen; + u8 actcode[32];//ActionCode IMPLICIT OCTET STRING + u8 annlistLen; + u8 annlist[32];//AnnouncementList SEQUENCE OF + u8 cpnstrg1Len; + u8 cpnstrg1[32];//CallingPartyNumberString1,IMPLICIT Digits Type + u8 cpnstrg2Len; + u8 cpnstrg2[32];//CallingPartyNumberString2,IMPLICIT Digits Type + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress,IMPLICIT Subaddress + u8 digitsCarrierLen; + u8 digitsCarrier[32]; + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits,IMPLICIT DigitsType + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits,IMPLICIT DigitsType + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits,IMPLICIT DigitsType + u8 redindLen; + u8 redind[32];//DMH_RedirectionIndicator,IMPLICIT ENUMERATED + u8 dmh_svcidLen; + u8 dmh_svcid[32];//DMH_ServiceID, IMPLICIT Octet String + u8 grpinfoLen; + u8 grpinfo[32];//GroupInformation,IMPLICIT OCTET STRING + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber,IMPLICIT DigitsType + u8 natimeLen; + u8 natime[32];//NoAnswerTime,IMPLICIT OCTET STRING + u8 plind;//PreferredLanguageIndicator,IMPLICIT OCTET STRING + u8 rndgtsLen; + u8 rndgts[32];//RedirectingNumberDigits,IMPLICIT Digits Type + u8 rnstringLen; + u8 rnstring[32];//RedirectingNumberString,IMPLICIT Digits Type + u8 rsubLen; + u8 rsub[32];//RedirectingSubaddress,IMPLICIT Subaddress + IS41_PAR_TERMLIST termlist;//TerminationList,SET OF CHOICE + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers,IMPLICIT OCTET STRING + u8 triggerlistnum; + IS41_PAR_TRIGGER_LIST triggerlist[MAX_IS41_TRIG_LIST_NUM]; //TriggerAddressList, IMPLICIT SET OF + + u8 user_error; + u8 provider_error; +}IS41_TRANUMREQ_RSP; + +#include "win_struct.h" +/***** is41 *******/ + + +/***** AIN *******/ +#define AIN_CDPN_LEN 11 +#define AIN_CGPN_LEN 9 +#define LATA_LEN 6 +#define AIN_CIC_LEN 6 +#define AIN_RN_LEN 9 + +enum _ansiTypeOfDigits +{ + NotUsed = 0, + CalledPartyNumber, + CallingPartyNumber, + CallerInteraction, + RoutingNumber, + BillingNumber, + DestinationNumber, + LATA, + Carrier, + LastCallingParty, + LastPartyCalled, + CallingDirectoryNumber, + VMSRIdentifier, + OriginalCalledNumber, + RedirectingNumber, + ConnectedNumber +}; + +enum _ainsiNatureOfNumber +{ + National = 0, + International +}; + +enum _ansiCoding +{ + CodingNotUsed, + CodingBCD, + CodingIA5 +}; + +enum _ansiNumberingPlan +{ + Unknown, + ISDNNumber, + TelephonyNumbering, + DataNumbering, + TelexNumbering, + MaritimeMobileNumbering, + LandMobileNumbering, + PrivateNumberingPlan +}; + +typedef struct _ansiTcapDigits +{ + u8 typeOfDigits; + u8 natureOfNumber; + u8 numberingPlan; + u8 encoding;//BCD or + u8 numberOfDigits; + u8 digits[10];// 2 digits 1 byte +}ansiDigit; + +typedef struct _ProvideInstructionStart +{ + //In UWave IN-MNP implementation LATA and Originating Station Type are hard coded as: 0x000000000000, 0x00 + //All numbers in the message are of 10 digit NDD format. + u32 param_flag; + u8 calledPartyNumber[AIN_CDPN_LEN+1];//10 digit called party number digits + u8 callingPartyNumber[AIN_CGPN_LEN+1];//AIN Digits + u8 LATA[LATA_LEN+1];//LATA ID + u8 OriginatingStationType;//Binary value of AIN II digits +}PIStart; + +typedef struct _ConnectionControlConnect +{ + //If the called number is ported then NPDB will response with Routing Number; otherwise the dialed number is returned. This is the way for MSC/PPS to check whether the dialed number is ported or not. + u32 param_flag; + u8 CIC[AIN_CIC_LEN +1];//3 or 4 digit CIC + u8 RoutingNumber[AIN_RN_LEN +1];//10 digit RN or dialed number + u8 BillingIndicator;//Unspecified +}CCConect; + + +/***** AIN *******/ + +/* +++++++++++++++++++++++++++++ */ +/* the whole operation structure */ +/* +++++++++++++++++++++++++++++ */ +typedef struct MapOprSrv_struct // operation service struct +{ + u32 port_id; + u32 dialogue_id; + u8 invoke_id; + u8 message_type; + u8 message_flag; // distinguish REQUEST,INDICATE,RESPONSE,CONFIRM + u8 version; + union + { + struct MapRIFSM_Arg rifsm_arg; // routing info for SM argument + struct MapRIFSM_Res rifsm_res; // routing info for SM response + struct MapRIFSMV1_Arg rifsm_v1_arg; // routing info for SM argument + struct MapRIFSMV1_Res rifsm_v1_res; // routing info for SM response + struct MapFSM_Arg fsm_arg; // foward sm argument v1; + struct MapMOFSM_Arg mofsm_arg; // MO forward SM argument + struct MapMOFSM_Res mofsm_res; // MO forward SM response + struct MapMTFSM_Arg mtfsm_arg; // MT forward SM argument + struct MapMTFSM_Res mtfsm_res; // MT forward SM response + struct MapRSMDS_Arg rsmds_arg; // report SM delivery status argument + struct MapRSMDS_Res rsmds_res; // report SM delivery status response + struct MapASC_Arg asc_arg; // alert service centre argument + struct MapASC_Res asc_res; // alert service centre response + struct MapISC_Arg isc_arg; // inform service centre argument + struct MapRFSM_Arg rfsm_arg; // ready for SM argument + struct MapRFSM_Res rfsm_res; // ready for SM response + struct MapRSS_Arg rss_arg; // register SS argument + struct MapRSS_Res rss_res; // register SS response + struct MapESS_Arg ess_arg; // erase SS argument + struct MapESS_Res ess_res; // erase SS response + struct MapASS_Arg ass_arg; // activate SS argument + struct MapASS_Res ass_res; // activate SS response + struct MapDASS_Arg dass_arg; // deactivate SS argument + struct MapDASS_Res dass_res; // deactivate SS response + struct MapINTSS_Arg intss_arg; // interrogation SS argument + struct MapINTSS_Res intss_res; // interrogation SS response + struct MapPUSSR_Arg pussr_arg; + struct MapPUSSR_Res pussr_res; + struct MapUSSR_Arg ussr_arg; + struct MapUSSR_Res ussr_res; + struct MapUSSN_Arg ussn_arg; + struct MapUSSN_Res ussn_res; + struct MapRPSS_Arg rpss_arg; // register password argument + struct MapRPSS_Res rpss_res; // register password response + struct MapGPSS_Arg gpss_arg; // get password argument + struct MapGPSS_Res gpss_res; // get password response + struct MapSSIN_Arg ssin_arg; + struct MapSSIN_Res ssin_res; + struct MapRCCE_Arg rcce_arg; + struct MapRCCE_Res rcce_res; + struct MapECCE_Arg ecce_arg; + struct MapECCE_Res ecce_res; + struct MapSRI_Arg sri_arg; // send routing info argument + struct MapSRI_Res sri_res; // send routing info response + struct MapPRN_Arg prn_arg; // provide roaming number argument + struct MapPRN_Res prn_res; // provide roaming number response + struct MapRCH_Arg rch_arg; + struct MapRCH_Res rch_res; + struct MapPSN_Arg psn_arg; + struct MapPSN_Res psn_res; + struct MapSSM_Arg ssm_arg; + struct MapSSM_Res ssm_res; + struct MapSRS_Arg srs_arg; + struct MapSRS_Res srs_res; + struct MapSR_Arg sr_arg; + struct MapSR_Res sr_res; + struct MapRUF_Arg ruf_arg; + struct MapRUF_Res ruf_res; + struct MapISTAlert_Arg istalt_arg; //ist-Alert argument + struct MapISTAlert_Res istalt_res; //ist-Alert response + struct MapISTCmd_Arg istcmd_arg; //ist-Command argument + struct MapISTCmd_Res istcmd_res; //ist-Command response + struct MapATM_Arg atm_arg; // activate trace mode argument + struct MapATM_Res atm_res; // activate trace mode response + struct MapDTM_Arg dtm_arg; // deactivate trace mode argument + struct MapDTM_Res dtm_res; // deactivate trace mode response + struct MapSIMSI_Arg simsi_arg; // send IMSI argument + struct MapSIMSI_Res simsi_res; // send IMSI response + struct MapUL_Arg ul_arg; // update location argument + struct MapUL_Res ul_res; // update location response + struct MapCL_Arg cl_arg; // cancel location argument + struct MapCL_Res cl_res; // cancel location response + struct MapPMS_Arg pms_arg; // purge MS argument + struct MapPMS_Res pms_res; // purge MS response + struct MapSI_Arg si_arg; // send identification argument + struct MapSI_Res si_res; // send identification response + struct MapUGL_Arg ugl_arg; // update GPRS location argument + struct MapUGL_Res ugl_res; // update GPRS location response + struct MapPSI_Arg psi_arg; // provide subscriber info argument + struct MapPSI_Res psi_res; // provide subscriber info response + struct MapATI_Arg ati_arg; // any time interrogation argument + struct MapATI_Res ati_res; // any time interrogation response + struct MapPHO_Arg pho_arg; // prepare handover argument + struct MapPHO_Res pho_res; // prepare handover response + struct MapPFSHO_Arg pfsho_arg; // Preform Subsequence Handover + struct MapPFSHO_Res pfsho_res; // Preform Subsequence Handover + struct MapNIHO_Arg niho_arg; // NoteInternalHandover + struct MapSES_Arg ses_arg; // send end signal argument + struct MapSES_Res ses_res; // send end signal response + struct MapTSA_Arg tsa_arg; // Trace Subscriber activate + struct MapPAS_Arg pas_arg; // process access signalling argument + struct MapFAS_Arg fas_arg; // forward access signalling argument + struct MapPSHO_Arg psho_arg; // prepare subsequent handover argument + struct MapPSHO_Res psho_res; // prepare subsequent handover response + struct MapSAI_Arg sai_arg; // send authenticate info argument + struct MapSAI_Res sai_res; // send authenticate info response + MapAuthFailReport_Arg authfr_arg; //authentication failure report argument add by gxchen + MapAuthFailReport_Res authfr_res; //authentication failure report response add by gxchen + struct MapCIMEI_Arg cimei_arg; // check IMEI argument + struct MapCIMEI_Res cimei_res; // check IMEI response + struct MapISD_Arg isd_arg; // insert subscriber data argument + struct MapISD_Res isd_res; // insert subscriber data response + struct MapDSD_Arg dsd_arg; // delete subscriber data argument + struct MapDSD_Res dsd_res; // delete subscriber data response + struct MapSP_Arg sp_arg; // send parameters argument + struct MapSP_Res sp_res; // send parameters respons + struct MapReset_Arg reset_arg; // reset argument + struct MapRD_Arg rd_arg; // restore data argument + struct MapRD_Res rd_res; // restore data response + struct MapSRIFG_Arg srifg_arg; // send routing info for GPRS argument + struct MapSRIFG_Res srifg_res; // send routing info for GPRS response + struct MapFR_Arg fr_arg; // failure report argument + struct MapBSA_Arg bsa_arg; // Begin subscriber activaty + struct MapFR_Res fr_res; // failure report response + struct MapNMPFG_Arg nmpfg_arg; // note MS present for GPRS argument + struct MapNMPFG_Res nmpfg_res; // note MS present for GPRS response + struct MapST_Arg st_arg; // security triplets argument + struct MapST_Res st_res; // security triplets response + struct MapIS_Arg is_arg; // interrogate subscriber argument + struct MapIS_Res is_res; // interrogate subscriber response + struct MapCS_Arg cs_arg; // create subscriber argument + struct MapCS_Res cs_res; // create subscriber response + struct MapDS_Arg ds_arg; // delete subscriber argument + struct MapDS_Res ds_res; // delete subscirber response + struct MapATSI_Arg atsi_arg; // any time subscription interrogation argument + struct MapATSI_Res atsi_res; // any time subscrption interrogation response + + + /* MAP_V1 */ + struct MapNP_Arg np_arg; //NoteSubscriberPresent argumnet + struct MapPUSSD_Arg pussd_arg; //UnstructuredSS-Data Response + struct MapPUSSD_Res pussd_res; //UnstructuredSS-Data Response + //struct MapSA_Arg sa_arg; //BeginSubscriberActivity argumnet + struct MapHO_Arg ho_arg; //perform hand over argument + struct MapHO_Res ho_res; //perform hand over response + + /* OPR */ + struct MapDetermineOprUser_Arg DetermineOprUser_Arg; + struct MapDetermineOprUser_Res DetermineOprUser_Res; + struct MapCreateUserWithMsisdnImsi_Arg CreateUserWithMsisdnImsi_Arg; + struct MapCreateUserWithMsisdnImsi_Res CreateUserWithMsisdnImsi_Res; + struct MapVlrUpdateLocation_Arg VlrUpdateLocation_Arg; + struct MapVlrUpdateLocation_Res VlrUpdateLocation_Res; + struct MapDeleteOprUser_Arg DeleteOprUser_Arg; + struct MapDeleteOprUser_Res DeleteOprUser_Res; + + /* IMDM */ + struct MapVlrEnquiryIMDM_Arg EnquiryIMDM_Arg; + struct MapVlrEnquiryIMDM_Res EnquiryIMDM_Res; + /* MAP_V1 */ + + /***************** LCS **********/ + RoutingInfoForLCS_Arg routingInfoForLCS_Arg; + RoutingInfoForLCS_Res routingInfoForLCS_Res; + ProvideSubscriberLocation_Arg provideSubscriberLocation_Arg; + ProvideSubscriberLocation_Res provideSubscriberLocation_Res; + /***************** LCS **********/ + +/******is41********/ + struct IS41_AUTHDIR_ARG authdir_arg; + struct IS41_AUTHDIR_RSP authdir_rsp; + struct IS41AucDirectiveForward_arg AUCDirForw_arg; + struct IS41_AFREPORT_ARG afreport_arg; + struct IS41_AFREPORT_RSP afreport_rsp; + struct IS41_AUTHREQ_ARG authreq_arg; + struct IS41_AUTHREQ_RSP authreq_rsp; + struct IS41_ASREPORT_ARG asreport_arg; + struct IS41_ASREPORT_RSP asreport_rsp; + struct IS41_BSCHALL_ARG bschall_arg; + struct IS41_BSCHALL_RSP bschall_rsp; + struct IS41_COUNTREQ_ARG countreq_arg; + struct IS41_COUNTREQ_RSP countreq_rsp; + + struct IS41_SMDBACK_ARG smdback_arg; + struct IS41_SMDBACK_RSP smdback_rsp; + struct IS41_SMDFWD_ARG smdfwd_arg; + struct IS41_SMDFWD_RSP smdfwd_rsp; + struct IS41_SMDPP_ARG smdpp_arg; + struct IS41_SMDPP_RSP smdpp_rsp; + struct IS41_SMSNOT_ARG smsnot_arg; + struct IS41_SMSNOT_RSP smsnot_rsp; + struct IS41_SMSREQ_ARG smsreq_arg; + struct IS41_SMSREQ_RSP smsreq_rsp; + + struct IS41_REGNOT_ARG regnot_arg; + struct IS41_REGNOT_RSP regnot_rsp; + struct IS41_REGCANC_ARG regcanc_arg; + struct IS41_REGCANC_RSP regcanc_rsp; + struct IS41_LOCREQ_ARG locreq_arg; + struct IS41_LOCREQ_RSP locreq_rsp; + struct IS41_ROUTREQ_ARG routreq_arg; + struct IS41_ROUTREQ_RSP routreq_rsp; + struct IS41_MSINACT_ARG msinact_arg; + struct IS41_MSINACT_RSP msinact_rsp; + struct IS41_QUALDIR_ARG qualdir_arg; + struct IS41_QUALDIR_RSP qualdir_rsp; + struct IS41_FEATREQ_ARG featreq_arg; + struct IS41_FEATREQ_RSP featreq_rsp; + struct IS41_REDREQ_ARG redreq_arg; + struct IS41_REDREQ_RSP redreq_rsp; + struct IS41_TRANUMREQ_ARG tranumreq_arg; + struct IS41_TRANUMREQ_RSP tranumreq_rsp; + + /******* is41 for win ******/ + struct IS41_ORREQ_ARG orreq_arg; + struct IS41_ORREQ_RSP orreq_rsp; + struct IS41_ANLYZD_ARG anlyzd_arg; + struct IS41_ANLYZD_RSP anlyzd_rsp; + struct IS41_OANSWER_ARG oanswer_arg; + struct IS41_ODISCONNECT_ARG odisconnect_arg; + struct IS41_ODISCONNECT_RSP odisconnect_rsp; + struct IS41_TANSWER_ARG tanswer_arg; + struct IS41_TDISCONNECT_ARG tdisconnect_arg; + struct IS41_TDISCONNECT_RSP tdisconnect_rsp; + struct IS41_CCDIR_ARG ccdir_arg; + struct IS41_CCDIR_RSP ccdir_rsp; + struct IS41_SEIZERES_ARG seizeres_arg; + struct IS41_SEIZERES_RSP seizeres_rsp; + struct IS41_CONNRES_ARG connres_arg; + struct IS41_SRFDIR_ARG srfdir_arg; + struct IS41_SRFDIR_RSP srfdir_rsp; + struct IS41_SM_ANLYZD_ARG smanlyzd_arg; + struct IS41_SM_ANLYZD_RSP smanlyzd_rsp; + + /******** MNP AIN******/ + struct _ProvideInstructionStart provideInstructionStart; + struct _ConnectionControlConnect connectionControlConnect; + + /******** MNP AIN******/ + } msg_list; +} MapOprSrv_struct; + +typedef struct MapOprData_struct +{ + u8 map_flag;//is41 or map + u32 param_flag; + u32 port_id; + u32 dialogue_id; + u8 invoke_id; + u8 message_type; + u8 message_flag; + u32 param_len; + u8 param[MAX_MAPPOPR_LEN]; + u8 user_error; + u8 provider_error; + u8 linked_id; +} MapOprData_struct; + +#endif diff --git a/plat/xapp/src/mapp/win_struct.h b/plat/xapp/src/mapp/win_struct.h new file mode 100644 index 0000000..838ddf2 --- /dev/null +++ b/plat/xapp/src/mapp/win_struct.h @@ -0,0 +1,477 @@ +/***************************/ +/****** WIN Parameter ******/ +/***************************/ +//N.S0009: 6.5.2.bv +typedef struct IS41_PAR_MSID { + u8 choice_flag; //0:min; 1:imsi + u8 min[MIN_LEN]; + u8 imsi[IMSI_LEN]; +} IS41_PAR_MSID; + +//N.S0013: 6.5.2.cl +typedef struct IS41_PAR_EXESCR { + u8 param_flag; + u8 scrnameLen; + u8 scrname[32]; + //optional + u8 scrargLen; + u8 scrarg[96]; +} IS41_PAR_EXESCR; + +/***************************/ +/****** WIN Operation ******/ +/***************************/ +//N.S0018: 6.4.2.30 OriginationRequest INVOKE +typedef struct IS41_ORREQ_ARG { + u32 param_flag; + u8 billid[7];//BillingID (Originating) M 6.5.2.16 + u8 digitsLen; + u8 digits[32];//Digits (Dialed) M 6.5.2.58 + u8 esn[4];//ElectronicSerialNumber M 6.5.2.63 + u8 mscid[3];//MSCID (Originating MSC) M 6.5.2.82 + IS41_PAR_MSID msid;//MSID M 6.5.2.bv k + u8 origtrigLen; + u8 origtrig[32];//OriginationTriggers M 6.5.2.90 + u8 transcapLen; + u8 transcap[32];//TransactionCapability M 6.5.2.160 + //optional + u8 cpnameLen; + u8 cpname[32];//CallingPartyName O 6.5.2.bw g, i + u8 cpndgts1Len; + u8 cpndgts1[32];//CallingPartyNumberDigits1 O 6.5.2.21 a + u8 cpndgts2Len; + u8 cpndgts2[32];//CallingPartyNumberDigits2 O 6.5.2.22 a + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress O 6.5.2.25 a + u8 locid[2];//LocationAreaID O 6.5.2.77 a, l + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 b + u8 featindLen; + u8 featind[32];//FeatureIndicator O 6.5.2.ej m + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber O 6.5.2.83 c + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator O 6.5.2.88 d + u8 pc_ssn[5];//PC_SSN (Originating MSC) O 6.5.2.93 e + u8 plind;//PreferredLanguageIndicator O 6.5.2.96 j + u8 senderinLen; + u8 senderin[32];//SenderIdentificationNumber O 6.5.2.116 f + u8 scellid[2];//ServingCellID O 6.5.2.117 a, n + u8 triggertype;//TriggerType O 6.5.2.dh h + IS41_PAR_WIN_CAP wincap;//WINCapability O 6.5.2.di o +} IS41_ORREQ_ARG; + +//N.S0018: 6.4.2.30 OriginationRequest RETURN RESULT +typedef struct IS41_ORREQ_RSP { + u32 param_flag; + //optional + u8 accden;//AccessDeniedReason O 6.5.2.1 a + u8 actcodeLen; + u8 actcode[32];//ActionCode O 6.5.2.2 b + u8 annlistLen; + u8 annlist[32];//AnnouncementList O 6.5.2.6 c + u8 cpnstrg1Len; + u8 cpnstrg1[32];//CallingPartyNumberString1 O 6.5.2.23 d, e + u8 cpnstrg2Len; + u8 cpnstrg2[32];//CallingPartyNumberString2 O 6.5.2.24 d, e + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress O 6.5.2.25 d, e, f + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits O 6.5.2.28 g + u8 digitsLen; + u8 digits[32];//Digits (Dialed) O 6.5.2.58 h + u8 disptextLen; + u8 disptext[32];//DisplayText O 6.5.2.bx d, e, r + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits O 6.5.2.59 i + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits O 6.5.2.60 i + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits O 6.5.2.61 i + u8 redindLen; + u8 redind[32];//DMH_RedirectionIndicator O 6.5.2.62 i, j + u8 dmh_svcidLen; + u8 dmh_svcid[32];//DMH_ServiceID O 6.5.2.ei s + u8 grpinfoLen; + u8 grpinfo[32];//GroupInformation O 6.5.2.69 k + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 i + u8 natimeLen; + u8 natime[32];//NoAnswerTime O 6.5.2.87 l + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator O 6.5.2.88 m + u8 pilotLen; + u8 pilot[32];//PilotNumber O 6.5.2.95 k + u8 rndgtsLen; + u8 rndgts[32];//RedirectingNumberDigits O 6.5.2.107 f + u8 rnstringLen; + u8 rnstring[32];//RedirectingNumberString O 6.5.2.108 d + u8 rsubLen; + u8 rsub[32];//RedirectingSubaddress O 6.5.2.109 d, e + u8 resumepic;//ResumePIC O 6.5.2.cu p + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits O 6.5.2.114 g + IS41_PAR_TERMLIST termlist;//TerminationList O 6.5.2.156 n + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers O 6.5.2.57 o //should be 6.5.2.159 + u8 triggerlistnum; + IS41_PAR_TRIGGER_LIST triggerlist[MAX_IS41_TRIG_LIST_NUM];//TriggerAddressList O 6.5.2.de q +} IS41_ORREQ_RSP; + +//N.S0018: 6.4.2.i AnalyzedInformation INVOKE +typedef struct IS41_ANLYZD_ARG { + u32 param_flag; + u8 billid[7];//BillingID (Originating) M 6.5.2.16 a + u8 digitsLen; + u8 digits[32];//Digits (Dialed) M 6.5.2.58 + u8 mscid[3];//MSCID (Originating) M 6.5.2.82 b + u8 transcapLen; + u8 transcap[32];//TransactionCapability M 6.5.2.160 + u8 triggertype;//TriggerType M 6.5.2.dh c + IS41_PAR_WIN_CAP wincap;//WINCapability M 6.5.2.di d + //optional + u8 cpnameLen; + u8 cpname[32];//CallingPartyName O 6.5.2.bw e, m + u8 cpndgts1Len; + u8 cpndgts1[32];//CallingPartyNumberDigits1 O 6.5.2.21 e + u8 cpndgts2Len; + u8 cpndgts2[32];//CallingPartyNumberDigits2 O 6.5.2.22 e + u8 cpsubLen; + u8 cpsub[32];//CallingPartySubaddress O 6.5.2.25 e + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits O 6.5.2.28 n, o + u8 cciLen; + u8 cci[32];//ConferenceCallingIndicator O 6.5.2.49 f + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits O 6.5.2.56 n, p + u8 redindLen; + u8 redind[32];//DMH_RedirectionIndicator O 6.5.2.62 q + u8 esn[4];//ElectronicSerialNumber O 6.5.2.63 g, r + u8 featindLen; + u8 featind[32];//FeatureIndicator O 6.5.2.ej s + u8 locid[2];//LocationAreaID O 6.5.2.77 h, t + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 i + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber O 6.5.2.83 j + IS41_PAR_MSID msid;//MSID O 6.5.2.bv g, r + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator O 6.5.2.88 k + u8 plind;//PreferredLanguageIndicator O 6.5.2.96 + u8 rndgtsLen; + u8 rndgts[32];//RedirectingNumberDigits O 6.5.2.107 e + u8 rdnameLen; + u8 rdname[32];//RedirectingPartyName O 6.5.2.by b, m + u8 rsubLen; + u8 rsub[32];//RedirectingSubaddress O 6.5.2.109 e + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits O 6.5.2.114 n, u + u8 scellid[2];//ServingCellID O 6.5.2.117 h, v + u8 mytyp;//SystemMyTypeCode O 6.5.2.147 + u8 tat;//TerminationAccessType O 6.5.2.155 l + u8 tdo[2];//TimeDateOffset O 6.5.2.dd w + u8 tod[3];//TimeOfDay O 6.5.2.em x +} IS41_ANLYZD_ARG; + +//N.S0018: 6.4.2.i AnalyzedInformation RETURN RESULT +typedef struct IS41_ANLYZD_RSP { + u32 param_flag; + //optional + u8 accden;//AccessDeniedReason O 6.5.2.1 a + u8 actcodeLen; + u8 actcode[32];//ActionCode O 6.5.2.2 b + u8 annlistLen; + u8 annlist[32];//AnnouncementList O 6.5.2.6 c + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits O 6.5.2.28 d + u8 cciLen; + u8 cci[32];//ConferenceCallingIndicator O 6.5.2.49 e + u8 digitsLen; + u8 digits[32];//Digits (Dialed) O 6.5.2.58 f + u8 disptextLen; + u8 disptext[32];//DisplayText O 6.5.2.bx d, m + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits O 6.5.2.59 g + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits O 6.5.2.60 g + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits O 6.5.2.61 g + u8 redindLen; + u8 redind[32];//DMH_RedirectionIndicator O 6.5.2.62 g, h + u8 dmh_svcidLen; + u8 dmh_svcid[32];//DMH_ServiceID O 6.5.2.ei n + u8 natimeLen; + u8 natime[32];//NoAnswerTime O 6.5.2.87 i + u8 otfiLen; + u8 otfi[32];//OneTimeFeatureIndicator O 6.5.2.88 j + u8 rndgtsLen; + u8 rndgts[32];//RedirectingNumberDigits O 6.5.2.107 d + u8 resumepic;//ResumePIC O 6.5.2.cu k + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits O 6.5.2.114 d + IS41_PAR_TERMLIST termlist;//TerminationList O 6.5.2.156 l + u8 termtrigLen; + u8 termtrig[32];//TerminationTriggers O 6.5.2.159 d + u8 triggerlistnum; + IS41_PAR_TRIGGER_LIST triggerlist[MAX_IS41_TRIG_LIST_NUM];//TriggerAddressList O 6.5.2.de d, o +} IS41_ANLYZD_RSP; + +//N.S0018: 6.4.2.aa OAnswer INVOKE +typedef struct IS41_OANSWER_ARG { + u32 param_flag; + u8 billid[7];//BillingID (Originating) M 6.5.2.16 a + u8 esn[4];//ElectronicSerialNumber M 6.5.2.63 b + u8 mscid[3];//MSCID (Originating) M 6.5.2.82 c + IS41_PAR_MSID msid;//MSID M 6.5.2.bv d + u8 tdo[2];//TimeDateOffset M 6.5.2.dd e + u8 tod[3];//TimeOfDay M 6.5.2.em f + u8 triggertype;//TriggerType M 6.5.2.dh g + //optional + u8 locid[2];//LocationAreaID O 6.5.2.77 h, i + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 j + u8 featindLen; + u8 featind[32];//FeatureIndicator O 6.5.2.ej k + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber O 6.5.2.83 l + u8 scellid[2];//ServingCellID O 6.5.2.117 h, m + u8 mytyp;//SystemMyTypeCode O 6.5.2.147 +} IS41_OANSWER_ARG; + +//N.S0018: 6.4.2.ab ODisconnect INVOKE +typedef struct IS41_ODISCONNECT_ARG { + u32 param_flag; + u8 billid[7];//BillingID (Originating) M 6.5.2.16 a + u8 esn[4];//ElectronicSerialNumber M 6.5.2.63 b + u8 mscid[3];//MSCID (Originating) M 6.5.2.82 c + IS41_PAR_MSID msid;//MSID M 6.5.2.bv d + u8 relcause;//ReleaseCause M 6.5.2.el e + u8 tdo[2];//TimeDateOffset M 6.5.2.dd f + u8 tod[3];//TimeOfDay M 6.5.2.em g + u8 transcapLen; + u8 transcap[32];//TransactionCapability M 6.5.2.160 + IS41_PAR_WIN_CAP wincap;//WINCapability M 6.5.2.di + u8 triggertype;//TriggerType M 6.5.2.dh h + //optional + u8 locid[2];//LocationAreaID O 6.5.2.77 i, j + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 k + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber O 6.5.2.83 l + u8 scellid[2];//ServingCellID O 6.5.2.117 i, m + u8 mytyp;//SystemMyTypeCode O 6.5.2.147 +} IS41_ODISCONNECT_ARG; + +//N.S0018: 6.4.2.ab ODisconnect RETURN RESULT +typedef struct IS41_ODISCONNECT_RSP { + u32 param_flag; + //optional + u8 annlistLen; + u8 annlist[32];//AnnouncementList O 6.5.2.6 a + u8 dmh_svcidLen; + u8 dmh_svcid[32];//DMH_ServiceID O 6.5.2.ei b +} IS41_ODISCONNECT_RSP; + +//N.S0018: 6.4.2.ad TAnswer INVOKE +typedef struct IS41_TANSWER_ARG { + u32 param_flag; + u8 billid[7];//BillingID (Originating) M 6.5.2.16 a + u8 esn[4];//ElectronicSerialNumber M 6.5.2.63 b + u8 mscid[3];//MSCID M 6.5.2.82 c + IS41_PAR_MSID msid;//MSID M 6.5.2.bv b + u8 tdo[2];//TimeDateOffset M 6.5.2.dd d + u8 tod[3];//TimeOfDay M 6.5.2.em e + u8 transcapLen; + u8 transcap[32];//TransactionCapability M 6.5.2.160 + u8 triggertype;//TriggerType M 6.5.2.dh f + IS41_PAR_WIN_CAP wincap;//WINCapability M 6.5.2.di + //optional + u8 locid[2];//LocationAreaID O 6.5.2.77 g, h + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 i + u8 featindLen; + u8 featind[32];//FeatureIndicator O 6.5.2.ej j + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber O 6.5.2.83 k + u8 scellid[2];//ServingCellID O 6.5.2.117 g, l + u8 mytyp;//SystemMyTypeCode O 6.5.2.147 + u8 tat;//TerminationAccessType O 6.5.2.155 m +} IS41_TANSWER_ARG; + +//N.S0018: 6.4.2.ae TDisconnect INVOKE +typedef struct IS41_TDISCONNECT_ARG { + u32 param_flag; + u8 billid[7];//BillingID (Originating) M 6.5.2.16 a + u8 esn[4];//ElectronicSerialNumber M 6.5.2.63 b + u8 mscid[3];//MSCID M 6.5.2.82 c + IS41_PAR_MSID msid;//MSID M 6.5.2.bv d + u8 tdo[2];//TimeDateOffset M 6.5.2.dd e + u8 tod[3];//TimeOfDay M 6.5.2.em f + u8 triggertype;//TriggerType M 6.5.2.dh g + //optional + u8 locid[2];//LocationAreaID O 6.5.2.77 h, i + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 j + u8 mscinLen; + u8 mscin[32];//MSCIdentificationNumber O 6.5.2.83 k + u8 relcause;//ReleaseCause O 6.5.2.el l + u8 scellid[2];//ServingCellID O 6.5.2.117 h, m + u8 mytyp;//SystemMyTypeCode O 6.5.2.147 +} IS41_TDISCONNECT_ARG; + +//N.S0018: 6.4.2.ae TDisconnect RETURN RESULT +typedef struct IS41_TDISCONNECT_RSP { + u32 param_flag; + //optional + u8 dmh_svcidLen; + u8 dmh_svcid[32];//DMH_ServiceID O 6.5.2.ei a +} IS41_TDISCONNECT_RSP; + +//N.S0018: 6.4.2.z CallControlDirective INVOKE +typedef struct IS41_CCDIR_ARG { + u32 param_flag; + u8 billid[7];//BillingID M 6.5.2.16 a + u8 mscid[3];//MSCID M 6.5.2.82 b + IS41_PAR_MSID msid;//MSID M 6.5.2.bv c + //optional + u8 actcodeLen; + u8 actcode[32];//ActionCode O 6.5.2.2 d + u8 annlistLen; + u8 annlist[32];//AnnouncementList O 6.5.2.6 e + u8 disptextLen; + u8 disptext[32];//DisplayText O 6.5.2.bx f + u8 acdgtsLen; + u8 acdgts[32];//DMH_AccountCodeDigits O 6.5.2.59 g + u8 abdgtsLen; + u8 abdgts[32];//DMH_AlternateBillingDigits O 6.5.2.60 g + u8 billdgtsLen; + u8 billdgts[32];//DMH_BillingDigits O 6.5.2.61 g + u8 redindLen; + u8 redind[32];//DMH_RedirectionIndicator O 6.5.2.62 g, h + u8 esn[4];//ElectronicSerialNumber O 6.5.2.63 i, j + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 k + u8 plind;//PreferredLanguageIndicator O 6.5.2.96 l, m + IS41_PAR_TERMLIST termlist;//TerminationList O 6.5.2.156 n + u8 triggerlistnum; + IS41_PAR_TRIGGER_LIST triggerlist[MAX_IS41_TRIG_LIST_NUM];//TriggerAddressList O 6.5.2.de h +} IS41_CCDIR_ARG; + +//N.S0018: 6.4.2.z CallControlDirective RETURN RESULT +typedef struct IS41_CCDIR_RSP { + u32 param_flag; + //optional + u8 callstatusLen; + u8 callstatus[32];//CallStatus O 6.5.2.en a +} IS41_CCDIR_RSP; + +//N.S0013: 6.4.2.r SeizeResource INVOKE +typedef struct IS41_SEIZERES_ARG { + u32 param_flag; + //optional + u8 plind;//PreferredLanguageIndicator O 6.5.2.96 + u8 psrLen; + u8 psr[32];//PrivateSpecializedResource O 6.5.2.u a //should be 6.5.2.ct + u8 srLen; + u8 sr[32];//SpecializedResource O 6.5.2.dc a +} IS41_SEIZERES_ARG; + +//N.S0013: 6.4.2.r SeizeResource RETURN RESULT +typedef struct IS41_SEIZERES_RSP { + u32 param_flag; + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits M 6.5.2.56 a +} IS41_SEIZERES_RSP; + +//N.S0013: 6.4.2.k ConnectResource INVOKE +typedef struct IS41_CONNRES_ARG { + u32 param_flag; + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits M 6.5.2.56 + //optional + u8 cardgtsLen; + u8 cardgts[32];//CarrierDigits O 6.5.2.28 a + u8 routdgtsLen; + u8 routdgts[32];//RoutingDigits O 6.5.2.114 a +} IS41_CONNRES_ARG; + +//N.S0013: 6.4.2.n InstructionRequest INVOKE & RETURN RESULT +typedef struct IS41_INSTREQ_ARG { + u32 param_flag; //no parameter +} IS41_INSTREQ_ARG; + +typedef struct IS41_INSTREQ_RSP { + u32 param_flag; //no parameter +} IS41_INSTREQ_RSP; + +//N.S0018: 6.4.2.s SRFDirective INVOKE +typedef struct IS41_SRFDIR_ARG { + u32 param_flag; + //optional + u8 annlistLen; + u8 annlist[32];//AnnouncementList O 6.5.2.6 a, d + u8 dgtccLen; + u8 dgtcc[32];//DigitCollectionControl O 6.5.2.57 b + IS41_PAR_EXESCR exescr;//ExecuteScript O 6.5.2.cl c, d + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 e +} IS41_SRFDIR_ARG; + +//N.S0013: 6.4.2.s SRFDirective RETURN RESULT +typedef struct IS41_SRFDIR_RSP { + u32 param_flag; + //optional + u8 digitsLen; + u8 digits[32];//Digits (Dialed) O 6.5.2.58 a, b + u8 scrresultLen; + u8 scrresult[96];//ScriptResult O 6.5.2.cx c +} IS41_SRFDIR_RSP; + +//X.S0010: 6.4.2.ax ShortMessageAnalyzed INVOKE +typedef struct IS41_SM_ANLYZD_ARG { + u32 param_flag; + u8 sms_brlen[2];//SMS_BearerLength M 6.5.2.hn a + u8 sms_billidLen; + u8 sms_billid[32];//SMS_BillingID M 6.5.2.ho b + u8 sms_event;//SMS_Event M 6.5.2.hp c + u8 smstidLen; + u8 smstid[MAX_IS41_VARPAR_LEN];//SMS_TeleserviceIdentifier M 6.5.2.137 d + //optional + u8 esn[4];//ElectronicSerialNumber O 6.5.2.63 e, f + u8 mdnLen; + u8 mdn[32];//MobileDirectoryNumber O 6.5.2.80 e, f, g + IS41_PAR_MSID msid;//MSID O 6.5.2.bv e, f, g + u8 smscidLen; + u8 smscid[MAX_IS41_VARPAR_LEN];//SMS_ChargeIndicator O 6.5.2.126 h + u8 smsdaLen; + u8 smsda[MAX_IS41_VARPAR_LEN];//SMS_DestinationAddress O 6.5.2.127 i + u8 sms_pmcnt[4];//SMS_PendingMessageCount O 6.5.2.hr j + u8 smsodaLen; + u8 smsoda[MAX_IS41_VARPAR_LEN];//SMS_OriginalDestinationAddress O 6.5.2.131 k + u8 smsodsLen; + u8 smsods[MAX_IS41_VARPAR_LEN];//SMS_OriginalDestinationSubaddress O 6.5.2.132 l + u8 smsooaLen; + u8 smsooa[MAX_IS41_VARPAR_LEN];//SMS_OriginalOriginatingAddress O 6.5.2.133 m + u8 smsoosLen; + u8 smsoos[MAX_IS41_VARPAR_LEN];//SMS_OriginalOriginatingSubaddress O 6.5.2.134 l + u8 smsoaLen; + u8 smsoa[MAX_IS41_VARPAR_LEN];//SMS_OriginatingAddress O 6.5.2.135 n + u8 tdo[2];//TimeDateOffset O 6.5.2.dd o + u8 tod[3];//TimeOfDay O 6.5.2.em p +} IS41_SM_ANLYZD_ARG; + +//X.S0010: 6.4.2.ax ShortMessageAnalyzed RETURN RESULT +typedef struct IS41_SM_ANLYZD_RSP { + u32 param_flag; + //optional + u8 dmh_svcidLen; + u8 dmh_svcid[32];//DMH_ServiceID O 6.5.2.ei a + u8 smsbdLen; + u8 smsbd[256];//SMS_BearerData O 6.5.2.124 b + u8 smscauseLen; + u8 smscause[32];//SMS_CauseCode O 6.5.2.125 c + u8 sms_eventnotLen; + u8 sms_eventnot[32];//SMS_EventNotification O 6.5.2.hq d +} IS41_SM_ANLYZD_RSP; + + diff --git a/plat/xapp/src/roaming_rule.c b/plat/xapp/src/roaming_rule.c new file mode 100644 index 0000000..5110ace --- /dev/null +++ b/plat/xapp/src/roaming_rule.c @@ -0,0 +1,427 @@ +#include +#include +#include +#include + +#include "../../snmp/src/include/snmp.h" +#include "../../snmp/src/include/macro.h" + +#include "roaming_rule.h" +#include "../../public/src/uwav/numgrp.h" +#include "../../public/src/uwav/number.h" + +_roaming_rule_table rr_table; + +#define ASN_1_OCTET_STRING 4 +#define ASN_1_INTEGER 2 +struct numgrp_table *xapp_rr_ptr=NULL; +extern void xap_set_roaming_rule_flag(); +extern int ParseLineWithDot(char *str, char (*row)[128], int maxrow); +extern int ParseLineWithSquare(char *str, char (*row)[128], int maxrow); +extern int xap_get_response(u8 oidlen,u32 *oid,u8 *pdata,u8 *vartype); +extern int xap_set_response(u8 oidlen,u32 *oid,u8 *pdata,u16 datalen); +extern void xap_set_roaming_rule_param_flag(); +/*------------------------------------------------------------------*/ + +int xap_save_roaming_rule() +{ + char filename[]="./conf/roaming_rules.conf"; + int i; + FILE *fpConf = NULL; + _roaming_rule *ptr=NULL; + + fpConf = fopen(filename,"w"); + if(fpConf == NULL) + return 0; + + for(i=0; iused_flag == 1) + fprintf(fpConf, "%04d.%s.%d.%d.%d.%d.%d.%d.%d\r\n", + ptr->id, ptr->prefix, ptr->lu_action, ptr->reject_cause, + ptr->vlr_counter, ptr->no_voice_camel, + ptr->no_sms_camel, + ptr->smsc_camel_if, + ptr->routing_home); + } + fclose(fpConf); + return 1; +} + +int xap_read_roaming_rule_record(char * s) +{ + char LineInfo[10][128]={{0}, {0}}; + char DetailInfo[10][128]={{0}, {0}}; + int rtn; + int Instance; + _roaming_rule *ptr; + + rtn = ParseLineWithSquare(s, LineInfo, 1); + rtn = ParseLineWithDot(LineInfo[0],DetailInfo, 9); + Instance = strtoll(DetailInfo[0],NULL,10); + if(Instance >= MAX_RULES) + { + return 0; + } + ptr = &rr_table.roaming_rule[Instance]; + ptr->used_flag = 1; + ptr->id = Instance; + strcpy(ptr->prefix , DetailInfo[1]); + ptr->lu_action = atoi(DetailInfo[2]); + ptr->reject_cause = atoi(DetailInfo[3]); + ptr->vlr_counter = atoi(DetailInfo[4]); + ptr->no_voice_camel = atoi(DetailInfo[5]); + ptr->no_sms_camel = atoi(DetailInfo[6]); + ptr->smsc_camel_if = atoi(DetailInfo[7]); + ptr->routing_home = atoi(DetailInfo[8]); + + return 1; +} + +int xap_read_roaming_rule() +{ + char filename[]="./conf/roaming_rules.conf"; + FILE *fp=NULL; + char record[128]; + int len; + + fp = fopen(filename, "r"); + if(fp == NULL) + return 0; + + memset(&rr_table, 0x00, sizeof(_roaming_rule_table)); + + while ( fgets(record, 128, fp) != (char *)0 ) + { + if ( (int *)strchr(record,'#') != NULL ) continue; + if ( (len=strlen(record))==0 ) continue; + if(record[0]=='\n')continue; + + xap_read_roaming_rule_record(record); + } + + fclose(fp); + return 1; +} + +int xap_create_roaming_rule_table() +{ + int i,len; + struct number_group tmp_num_grp; + + if( xapp_rr_ptr!= NULL) + delete_numgrp_table(xapp_rr_ptr); + + xapp_rr_ptr = assign_numgrp_table("rrule",MAX_RULES); + for(i=0;iMAX_PREFIX_LEN) + continue; + tmp_num_grp.start.num_of_digit = len; + memcpy(tmp_num_grp.start.digit, rr_table.roaming_rule[i].prefix, len); + tmp_num_grp.end.num_of_digit = len; + memcpy(tmp_num_grp.end.digit, rr_table.roaming_rule[i].prefix, len); + tmp_num_grp.index = i; + + numgrp_insert(xapp_rr_ptr, + &tmp_num_grp.start, + &tmp_num_grp.end, + tmp_num_grp.index); + } + return 0; +} + +int xap_search_roaming_rule_table(char * vlr_number) +{ + num16_t num16_tmp; + int result=-1; + int len, maxlen=0; + register int i; + + + for(i=0; imaxlen) + { + maxlen = len; + result = i; + } + } + } + } + + return result; + + if(xapp_rr_ptr==NULL) return -1; + + if(len==0) return -1; + if(len>MAX_PREFIX_LEN) len = MAX_PREFIX_LEN; + + num16_tmp.num_of_digit = len; + memcpy(num16_tmp.digit,vlr_number,len); + if(numgrp_search(&result, xapp_rr_ptr, &num16_tmp)) + return result; + + return -1; +} + +int xap_roaming_rule_get_rule(char *vlr_number, _roaming_rule *ptr) +{ + int index=-1; + + if((index = xap_search_roaming_rule_table(vlr_number))< 0) + return 0; + + memcpy(ptr, &rr_table.roaming_rule[index], sizeof(_roaming_rule));; + + return 1; +} + +int xap_roaming_rule_get_smsc_camel_flag(char *vlr_number) +{ + int index=-1; + _roaming_rule *ptr= NULL; + + if((index = xap_search_roaming_rule_table(vlr_number))< 0) + return 0; + + ptr = &rr_table.roaming_rule[index]; + return ptr->smsc_camel_if; +} + +int xap_roaming_rule_get_routing_home_flag(char *vlr_number) +{ + int index=-1; + _roaming_rule *ptr= NULL; + + if((index = xap_search_roaming_rule_table(vlr_number))< 0) + return -1; + + ptr = &rr_table.roaming_rule[index]; + return ptr->routing_home; +} + +int xap_roaming_rule_test(char *vlr_number) +{ + _roaming_rule ptr; + + if(xap_roaming_rule_get_rule(vlr_number, &ptr)) + { + return ptr.id; + } + return -1; +} +/* ---------------------------------------------------------------------------*/ +/* ------------------------ function: xap_get_idle_index() -------------------*/ +/* -- return =0 ,failed, otherwise succeed -----------------------------------*/ +/* ---------------------------------------------------------------------------*/ +int xap_get_roaming_rule_idle_index(int type, int *newID) +{ + int i; + + switch(type) + { + case 1: + for(i=0;i= MAX_RULES ) + return -1; + if(rr_table.roaming_rule[index].used_flag == 0) + return -1; + + *vartype = ASN_1_OCTET_STRING; + switch(column) + { + case 1: /* index */ + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = index; + break; + case 2: + datalen = strlen(rr_table.roaming_rule[index].prefix); + memcpy(pdata,rr_table.roaming_rule[index].prefix,datalen); + //if(datalen == 0) datalen = 1; + break; + case 3: + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = rr_table.roaming_rule[index].lu_action; + break; + case 4: + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = rr_table.roaming_rule[index].reject_cause; + break; + case 5: + *vartype = ASN_1_INTEGER; + datalen = 4; + pdata[0] = rr_table.roaming_rule[index].vlr_counter>>24; + pdata[1] = rr_table.roaming_rule[index].vlr_counter>>16; + pdata[2] = rr_table.roaming_rule[index].vlr_counter>>8; + pdata[3] = rr_table.roaming_rule[index].vlr_counter; + break; + case 6: + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = rr_table.roaming_rule[index].no_voice_camel; + break; + case 7: + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = rr_table.roaming_rule[index].no_sms_camel; + break; + case 8: + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = rr_table.roaming_rule[index].smsc_camel_if; + break; + case 9: + *vartype = ASN_1_INTEGER; + datalen = 1; + pdata[0] = rr_table.roaming_rule[index].routing_home; + break; + case 10: + *vartype = ASN_1_INTEGER; + pdata[0] = 1; /* active */ + datalen = 1; + break; + default: + return -1; + break; + } + return datalen; +} + + +int xap_set_roaming_rule(u32 column, u32 *instance, u_char *pdata, unsigned short datalen) +{ + int index; + //int newId; + + //if(datalen == 0) + // return -1; + + index = instance[0]; + if(index < 0 || index >= MAX_RULES) + return -1; + + xap_set_roaming_rule_flag(); + switch(column) + { + case 1:/* create */ + index = pdata[0]; + if(index < 0 || index >= MAX_RULES) + return -1; + else + { + rr_table.roaming_rule[index].used_flag = 1; + rr_table.roaming_rule[index].id = index; + } + + break; + case 2: /* prefix */ + if(datalen>=MAX_PREFIX_LEN) + return -1; + memset(rr_table.roaming_rule[index].prefix, 0x00, MAX_PREFIX_LEN); + memcpy(rr_table.roaming_rule[index].prefix, pdata, datalen); + break; + case 3: + if(pdata[0]>=2) + return -1; + rr_table.roaming_rule[index].lu_action = pdata[0]; + break; + case 4: + rr_table.roaming_rule[index].reject_cause = pdata[0]; + break; + case 5: + if(datalen>=5) + return -1; + { + if(datalen==1) + rr_table.roaming_rule[index].vlr_counter = pdata[0]; + else + rr_table.roaming_rule[index].vlr_counter = pdata[0]*256+pdata[1]; + } + break; + case 6: + if(pdata[0]>2) + return -1; + rr_table.roaming_rule[index].no_voice_camel = pdata[0]; + break; + case 7: + if(pdata[0]>2) + return -1; + rr_table.roaming_rule[index].no_sms_camel = pdata[0]; + break; + case 8: + if(pdata[0]>2) + return -1; + rr_table.roaming_rule[index].smsc_camel_if = pdata[0]; + break; + case 9: + rr_table.roaming_rule[index].routing_home = pdata[0]; + break; + case 10: /* status */ + if(pdata[0] == 6) /* 6==delete */ + { + memset(&rr_table.roaming_rule[index] ,0x00 ,sizeof(_roaming_rule)); + } + break; + default: + return -1; + break; + } + return datalen; +} + +int xap_roaming_rules_init() +{ + xap_read_roaming_rule(); +// xap_create_roaming_rule_table(); + return 1; +} diff --git a/plat/xapp/src/roaming_rule.h b/plat/xapp/src/roaming_rule.h new file mode 100644 index 0000000..f3a337b --- /dev/null +++ b/plat/xapp/src/roaming_rule.h @@ -0,0 +1,44 @@ +#ifndef _ROAMING_RULES_H +#define _ROAMING_RULES_H + +#include + +#define MAX_RULES 2048 +#define MAX_PREFIX_LEN 16 + +#define PLMN_NOT_ALLOWED 8 +#define UNEXPECTED_DATA_VALUE 36 + +typedef enum RR_NVCS +{ + NO_NVCS_DISABLE, + NO_NVCS_LU_ONLY, /* Only LU is allowed, no MO service */ + NO_NVCS_BOTH, /* Both LU and MO service */ +}_RR_NVCS; + +typedef struct roaming_rule +{ + u_char used_flag; + u_short id; + char prefix[MAX_PREFIX_LEN]; + u_char lu_action; + u_char reject_cause; + int vlr_counter; + char no_voice_camel; + char no_sms_camel; + char smsc_camel_if; + char routing_home; +}_roaming_rule; + +typedef struct roaming_rule_table +{ + _roaming_rule roaming_rule[MAX_RULES]; +}_roaming_rule_table; + +int snmpSetRoamingRule(u_char oidlen,u_long *oid,u_char *pdata,u_short datalen); +int snmpGetRoamingRule(u_char oidlen,u_long *oid,u_char *pdata,u_char *vartype); +int xapGetRoamingRule(_roaming_rule *rr_ptr); +int xapGetSMSCamelFlag(char *vlr_number); +int saveRoamingRule(); + +#endif diff --git a/plat/xapp/src/xap_cdmacdr.c b/plat/xapp/src/xap_cdmacdr.c new file mode 100644 index 0000000..15a47a5 --- /dev/null +++ b/plat/xapp/src/xap_cdmacdr.c @@ -0,0 +1,1760 @@ +/* HLR CDMA cdr coding */ +/* Created by daniel:2005-06-21 */ +/* Modify by daniel:2005-06-21 */ +/* -------------------------------- */ + +#include "../../public/src/include/asn1.h" +#include "../../public/src/include/includes.h" +#include "../../public/src/include/pub_fmt.h" +#include "../../sccp/src/include/sccp.h" +#include "./mapp/map_const.h" +#include "xap_cdmacdr.h" + +// fix multiple definition==================================== +struct xap_vm_struct *xap_vm_ptr; +struct xap_inter_struct *xap_inter_ptr; +// + +char *is41_sequenceTag(char *tag,int sequence); + +void encode_param_CallLocation(DMH_CallLocation *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + u8 temp[8]; + + flag = ptr->param_flag; + + *buf_len = AddTLV(tag1,0,temp,0x60,asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_HCOORD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->HcoordinateLen % 3,ptr->Hcoordinate,0x40,asn_buf); + } + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NPANXX); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),3,ptr->NPANXX,0x40,asn_buf); + } + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_PLNAM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->PlaceNameLen % 20,ptr->PlaceName,0x40,asn_buf); + } + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SPNAM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),2,ptr->StateProvinceName,0x40,asn_buf); + } + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_VCOORD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->VcoordinateLen % 3,ptr->Vcoordinate,0x40,asn_buf); + } + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_LATA); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->LocalAccessTransportAreaLen % 4,ptr->LocalAccessTransportArea,0x40,asn_buf); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_WCNTRY); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),3,ptr->WorldCountry,0x40,asn_buf); + } +} + +void encode_param_cnvusg(DMH_ConversationUsage *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + u8 temp[8]; + + flag = ptr->param_flag; + + *buf_len = AddTLV(tag1,0,temp,0x60,asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->durLen % 5,ptr->dur,0x40,asn_buf); + } + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DATE); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),3,ptr->Date,0x40,asn_buf); + } + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RELIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->relind,0x40,asn_buf); + } + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TDO); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->tdoLen % 3,ptr->tdo,0x40,asn_buf); + } + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMOCT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numoctLen % 5,ptr->numoct,0x40,asn_buf); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMPKT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numpktLen % 5,ptr->numpkt,0x40,asn_buf); + } +} + +void encode_param_swid(DMH_SwitchID *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 temp[8]; + + flag = ptr->param_flag; + + *buf_len = AddTLV(tag1,0,temp,0x60,asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SWNO); + *buf_len = AddTLV(tag,1,&ptr->swno,0x40,asn_buf); + } + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SID); + *buf_len = AddTLV(tag,2,ptr->sid,0x40,asn_buf); + } + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_BRI); + *buf_len = AddTLV(tag,2,ptr->bri,0x40,asn_buf); + } + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_MYTYP); + *buf_len = AddTLV(tag,1,&ptr->mytyp,0x40,asn_buf); + } +} + +void encode_param_bfpath(DMH_BeginForwardPath *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CELLID); + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->cellidLen % 3,ptr->cellid,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_MODIND); + *buf_len = AddTLV(is41_sequenceTag(tag,2),1,&ptr->modind,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RCHNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,3),ptr->rchnumLen % 3,ptr->rchnum,0x40,asn_buf); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TKNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->tknumLen % 3,ptr->tknum,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +void encode_param_achusg(DMH_AirChannelUsage *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + + *buf_len = AddTLV(tag,0,temp,0x60,asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->durLen % 5,ptr->dur,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DATE); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),3,ptr->Date,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +void encode_param_fbusg(DMH_FeatureBridgeUsage *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + + *buf_len = AddTLV(tag1,0,temp,0x60,asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FBIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->fbind,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->durLen % 5,ptr->dur,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RLEG); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->rlegLen % 3,ptr->rleg,0x40,asn_buf); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +void encode_param_incusg(DMH_IncomingTrunkUsage *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + + *buf_len = AddTLV(tag1,0,temp,0x60,asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->durLen % 5,ptr->dur,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TKNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->tknumLen % 3,ptr->tknum,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +void encode_param_ogtusg(DMH_OutgoingTrunkUsage *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + + *buf_len = AddTLV(tag1,0,temp,0x60,asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->durLen % 5,ptr->dur,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TKNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->tknumLen % 3,ptr->tknum,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +void encode_param_audsub(DMH_AuditSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + u8 temp[8]; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AUDSN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->audsnLen % 5,ptr->audsn,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_ACHDUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->achdurLen % 5,ptr->achdur,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CNVDUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->cnvdurLen % 5,ptr->cnvdur,0x40,asn_buf); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FBDUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->fbdurLen % 5,ptr->fbdur,0x40,asn_buf); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_IECCDUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->ieccdurLen % 5,ptr->ieccdur,0x40,asn_buf); + } + + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_INCDUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->incdurLen % 5,ptr->incdur,0x40,asn_buf); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMACT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numactLen % 5,ptr->numact,0x40,asn_buf); + } + + if (flag & BIT7_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMCHRG); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numchrgLen % 5,ptr->numchrg,0x40,asn_buf); + } + + if (flag & BIT8_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMEVT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numevtLen % 5,ptr->numevt,0x40,asn_buf); + } + + if (flag & BIT9_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMLEG); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numlegLen % 5,ptr->numleg,0x40,asn_buf); + } + + if (flag & BIT10_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMSEG); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numsegLen % 5,ptr->numseg,0x40,asn_buf); + } + + if (flag & BIT11_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_OGTDUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->ogtdurLen % 5,ptr->ogtdur,0x40,asn_buf); + } + + if (flag & BIT12_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMFAL); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numfalLen % 5,ptr->numfal,0x40,asn_buf); + } + + if (flag & BIT13_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMORG); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numorgLen % 8,ptr->numorg,0x40,asn_buf); + } + + if (flag & BIT14_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMRED); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numredLen % 5,ptr->numred,0x40,asn_buf); + } + + if (flag & BIT15_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMTRM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numtrmLen % 5,ptr->numtrm,0x40,asn_buf); + } + + if (flag & BIT16_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMAUX); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numauxLen % 5,ptr->numaux,0x40,asn_buf); + } + + if (flag & BIT17_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMOCT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numoctLen % 5,ptr->numoct,0x40,asn_buf); + } + + if (flag & BIT18_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMPKT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numpktLen % 5,ptr->numpkt,0x40,asn_buf); + } + + if (flag & BIT19_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_IWFDUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->iwfdurLen % 5,ptr->iwfdur,0x40,asn_buf); + } + + if (flag & BIT20_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FILLIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->fillind.FaultyParameter.ParameterIdentifierLen % 17,ptr->fillind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FILLIC);//FillIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,2),1,&ptr->fillind.FillIndicatorCode,0x40,asn_buf); + } + + if (flag & BIT21_TRUE) + { + if (ptr->retind.param_flag & 3) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RETIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + } + + if (ptr->retind.param_flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_RICODE);//ReturnIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,3),1,&ptr->retind.ReturnIndicatorCode,0x40,asn_buf); + } + if (ptr->retind.param_flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->retind.FaultyParameter.ParameterIdentifierLen % 17,ptr->retind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + } + } +} + +void encode_param_idsub(DMH_IdentitySubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_DATE,offset++); + *buf_len = AddTLV(tag,3,ptr->Date,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + if (ptr->Choice1.ChoiceFlag == 0) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_ESN,offset++); + *buf_len = AddTLV(tag,4,ptr->Choice1.esn,0x40,asn_buf); + } + else + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_IMEI,offset++); + *buf_len = AddTLV(tag,5,ptr->Choice1.imei,0x40,asn_buf); + } + } + + if (flag & BIT2_TRUE) + { + switch (ptr->Choice2.ChoiceFlag) + { + case 0: + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_MIN,offset++); + *buf_len = AddTLV(tag,5,ptr->Choice2.min,0x40,asn_buf); + break; + case 1: + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_IMSI,offset++); + *buf_len = AddTLV(tag,8,ptr->Choice2.imsi,0x40,asn_buf); + break; + case 2: + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_NEICLNP,offset++); + *buf_len = AddTLV(tag,19,ptr->Choice2.neiclnp,0x40,asn_buf); + break; + case 3: + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_NEIIP,offset++); + *buf_len = AddTLV(tag,4,ptr->Choice2.neiip,0x40,asn_buf); + break; + default: + break; + } + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_TDO,offset++); + *buf_len = AddTLV(tag,ptr->tdoLen % 3,ptr->tdo,0x40,asn_buf); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_TOD,offset++); + *buf_len = AddTLV(tag,ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + + if (flag & BIT5_TRUE) + { + switch (ptr->Choice3.ChoiceFlag) + { + case 0: + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_ASWID,offset++); + encode_param_swid(&ptr->Choice3.aswid,asn_buf,buf_len,tag); + break; + case 1: + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_OSWID,offset++); + encode_param_swid(&ptr->Choice3.oswid,asn_buf,buf_len,tag); + break; + case 2: + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_SSWID,offset++); + encode_param_swid(&ptr->Choice3.sswid,asn_buf,buf_len,tag); + break; + default: + break; + } + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_BIN,offset++); + *buf_len = AddTLV(tag,ptr->binLen % 5,ptr->bin,0x40,asn_buf); + } + + if (flag & BIT7_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_HSWID,offset++); + encode_param_swid(&ptr->hswid,asn_buf,buf_len,tag); + } + + if (flag & BIT8_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_MDN,offset++); + *buf_len = AddTLV(tag,ptr->mdnLen % 9,ptr->mdn,0x40,asn_buf); + } + + if (flag & BIT9_TRUE) + { + sprintf(tag,"%s.%d-%d.%d",tag1,DMHPAR_FILLIND,offset++,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->fillind.FaultyParameter.ParameterIdentifierLen % 17,ptr->fillind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + + sprintf(tag,"%s.%d-%d.%d",tag1,DMHPAR_FILLIND,offset++,DMHPAR_FILLIC);//FillIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,2),1,&ptr->fillind.FillIndicatorCode,0x40,asn_buf); + } + + if (flag & BIT10_TRUE) + { + if (ptr->retind.param_flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d-%d.%d",tag1,DMHPAR_RETIND,offset++,DMHPAR_RICODE);//ReturnIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,1),1,&ptr->retind.ReturnIndicatorCode,0x40,asn_buf); + } + if (ptr->retind.param_flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d-%d.%d",tag1,DMHPAR_RETIND,offset++,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,2),ptr->retind.FaultyParameter.ParameterIdentifierLen % 17,ptr->retind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + } + } +} + +void encode_param_evtsub(DMH_EventSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_EVTIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->evtind,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RIN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->rinLen % 5,ptr->rin,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_ASWID,offset++); + encode_param_swid(&ptr->aswid,asn_buf,buf_len,tag); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AUTHCNT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->authcnt,0x40,asn_buf); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AUTHDEN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->authden,0x40,asn_buf); + } + + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AUTHTYP); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->authtyp,0x40,asn_buf); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_BIN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->binLen % 5,ptr->bin,0x40,asn_buf); + } + + if (flag & BIT7_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DATE); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),3,ptr->Date,0x40,asn_buf); + } + + if (flag & BIT8_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DENACC); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->denacc,0x40,asn_buf); + } + + if (flag & BIT9_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FEATIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->featind,0x40,asn_buf); + } + + if (flag & BIT10_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FEATOPN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->featopn,0x40,asn_buf); + } + + if (flag & BIT11_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FRIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->frind,0x40,asn_buf); + } + + if (flag & BIT12_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_OSWID,offset++); + encode_param_swid(&ptr->oswid,asn_buf,buf_len,tag); + } + + if (flag & BIT13_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RBIN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->rbinLen % 5,ptr->rbin,0x40,asn_buf); + } + + if (flag & BIT14_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SRT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->srt,0x40,asn_buf); + } + + if (flag & BIT15_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_SSWID,offset++); + encode_param_swid(&ptr->sswid,asn_buf,buf_len,tag); + } + + if (flag & BIT16_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TDO); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->tdoLen % 5,ptr->tdo,0x40,asn_buf); + } + + if (flag & BIT17_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + + if (flag & BIT18_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FILLIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->fillind.FaultyParameter.ParameterIdentifierLen % 17,ptr->fillind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FILLIC);//FillIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,2),1,&ptr->fillind.FillIndicatorCode,0x40,asn_buf); + } + + if (flag & BIT19_TRUE) + { + if (ptr->retind.param_flag & 3) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RETIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + } + + if (ptr->retind.param_flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_RICODE);//ReturnIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,3),1,&ptr->retind.ReturnIndicatorCode,0x40,asn_buf); + } + if (ptr->retind.param_flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->retind.FaultyParameter.ParameterIdentifierLen % 17,ptr->retind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + } + } +} + +void encode_param_chrgsub(DMH_ChargeSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + u8 temp[8]; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGAMT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->chrgamtLen % 5,ptr->chrgamt,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->chrgind,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGTAX); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->chrgtaxLen % 5,ptr->chrgtax,0x40,asn_buf); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGTIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->chrgtind,0x40,asn_buf); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGUNIT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->chrgunit,0x40,asn_buf); + } + + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DUR); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->durLen % 5,ptr->dur,0x40,asn_buf); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_MRPI); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->mrpi,0x40,asn_buf); + } + + if (flag & BIT7_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_PLNAM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->plnamLen % 21,ptr->plnam,0x40,asn_buf); + } + + if (flag & BIT8_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RPI); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->rpi,0x40,asn_buf); + } + + if (flag & BIT9_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SPNAM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),2,ptr->spnam,0x40,asn_buf); + } + + if (flag & BIT10_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TTIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->ttind,0x40,asn_buf); + } + + if (flag & BIT11_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_WCNTRY); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),3,ptr->wcntry,0x40,asn_buf); + } + + if (flag & BIT12_TRUE) + { + if (ptr->Choice.ChoiceFlag == 0) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_LNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->Choice.lnum,0x40,asn_buf); + } + else + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SEGNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->Choice.segnum,0x40,asn_buf); + } + } + + if (flag & BIT13_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGTCOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->chrgtcodLen % 3,ptr->chrgtcod,0x40,asn_buf); + } + + if (flag & BIT14_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGTTBL); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->chrgttbl,0x40,asn_buf); + } + + if (flag & BIT15_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMOCT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numoctLen % 5,ptr->numoct,0x40,asn_buf); + } + + if (flag & BIT16_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_NUMPKT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->numpktLen % 5,ptr->numpkt,0x40,asn_buf); + } + + if (flag & BIT17_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SELUSE); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->seluseLen % 101,ptr->seluse,0x40,asn_buf); + } + + if (flag & BIT18_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SUCOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->sucod,0x40,asn_buf); + } + + if (flag & BIT19_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TEXIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->texind,0x40,asn_buf); + } + + if (flag & BIT20_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FILLIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->fillind.FaultyParameter.ParameterIdentifierLen % 17,ptr->fillind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FILLIC);//FillIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,2),1,&ptr->fillind.FillIndicatorCode,0x40,asn_buf); + } + + if (flag & BIT21_TRUE) + { + if (ptr->retind.param_flag & 3) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RETIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + } + + if (ptr->retind.param_flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_RICODE);//ReturnIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,3),1,&ptr->retind.ReturnIndicatorCode,0x40,asn_buf); + } + if (ptr->retind.param_flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->retind.FaultyParameter.ParameterIdentifierLen % 17,ptr->retind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + } + } +} + +void encode_param_actsub(DMH_ActivitySubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_ACTIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->actind,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RIN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->rinLen % 5,ptr->rin,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AUTHDEN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->authden,0x40,asn_buf); + } + + if (flag & BIT3_TRUE)//BeginForwardPath, encode in the future + {} + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_BIN); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->binLen % 5,ptr->bin,0x40,asn_buf); + } + + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DATE); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),3,ptr->Date,0x40,asn_buf); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DENACC); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->denacc,0x40,asn_buf); + } + + if (flag & BIT7_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SRT); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->srt,0x40,asn_buf); + } + + if (flag & BIT8_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_SSWID,offset++); + encode_param_swid(&ptr->sswid,asn_buf,buf_len,tag); + } + + if (flag & BIT9_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TDO); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->tdoLen % 3,ptr->tdo,0x40,asn_buf); + } + + if (flag & BIT10_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TOD); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->todLen % 4,ptr->tod,0x40,asn_buf); + } + + if (flag & BIT11_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FILLIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->fillind.FaultyParameter.ParameterIdentifierLen % 17,ptr->fillind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_FILLIND,DMHPAR_FILLIC);//FillIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,2),1,&ptr->fillind.FillIndicatorCode,0x40,asn_buf); + } + + if (flag & BIT12_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RSEG); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->rsegLen % 4,ptr->rseg,0x40,asn_buf); + } + + if (flag & BIT13_TRUE) + { + if (ptr->retind.param_flag & 3) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RETIND);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,temp,0x60,asn_buf); + } + + if (ptr->retind.param_flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_RICODE);//ReturnIndicatorCode + *buf_len = AddTLV(is41_sequenceTag(tag,3),1,&ptr->retind.ReturnIndicatorCode,0x40,asn_buf); + } + if (ptr->retind.param_flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d.%d",tag1,DMHPAR_RETIND,DMHPAR_FPARM);//FaultyParameter + *buf_len = AddTLV(is41_sequenceTag(tag,4),ptr->retind.FaultyParameter.ParameterIdentifierLen % 17,ptr->retind.FaultyParameter.ParameterIdentifier,0x40,asn_buf); + } + } +} + +void encode_param_airssub(DMH_AirSegmentSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_ACHUSG,offset++); + encode_param_achusg(&ptr->achusg,asn_buf,buf_len,tag); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_SEGNUM,offset++); + *buf_len = AddTLV(tag,1,&ptr->segnum,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +void encode_param_falsub(DMH_FeatureActivationLegSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DIALDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->dialdgtsLen & 31,ptr->dialdgts,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_LNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->lnum,0x40,asn_buf); + } + +//optional part will be encoded in the future + if (flag & BIT13_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FRIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->frind,0x40,asn_buf); + } + + if (flag & BIT15_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_LLIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),0,&ptr->llind,0x40,asn_buf); + } +} + +void encode_param_olsub(DMH_OriginationLegSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_BILLIND,offset++); + *buf_len = AddTLV(tag,1,&ptr->billind,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_DIALDGTS,offset++); + *buf_len = AddTLV(tag,ptr->dialdgtsLen & 31,ptr->dialdgts,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_LNUM,offset++); + *buf_len = AddTLV(tag,1,&ptr->lnum,0x40,asn_buf); + } + + if (flag & BIT8_TRUE) + {//Called Location + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CDLOC,offset++); + encode_param_CallLocation(&ptr->CalledLocation,asn_buf,buf_len,tag); + } + + if (flag & BIT11_TRUE) + {//Calling Location + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CGLOC,offset++); + encode_param_CallLocation(&ptr->CallingLocation,asn_buf,buf_len,tag); + } + + if (flag & BIT14_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CNVUSG,offset++); + encode_param_cnvusg(&ptr->cnvusg,asn_buf,buf_len,tag); + } + + if (flag & BIT16_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_FBUSG,offset++); + encode_param_fbusg(&ptr->fbusg,asn_buf,buf_len,tag); + } + + if (flag & BIT19_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_LLIND,offset++); + *buf_len = AddTLV(tag,0,&ptr->llind,0x40,asn_buf); + } + if (flag & BIT20_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_OGTUSG,offset++); + encode_param_ogtusg(&ptr->ogtusg,asn_buf,buf_len,tag); + } + +//optional part will be encoded in the future +} + +void encode_param_pacasub(DMH_PACASegmentSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CELLID); + *buf_len = AddTLV(is41_sequenceTag(tag,1),ptr->cellidLen % 3,ptr->cellid,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DUR); + *buf_len = AddTLV(is41_sequenceTag(tag,2),ptr->durLen % 5,ptr->dur,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_PACAIND); + *buf_len = AddTLV(is41_sequenceTag(tag,3),1,&ptr->pacaind,0x40,asn_buf); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SEGNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,4),1,&ptr->segnum,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +void encode_param_rlsub(DMH_RedirectionLegSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_BILLIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->billind,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CDDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->cddgtsLen % 10,ptr->cddgts,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_INCUSG,offset++); + encode_param_incusg(&ptr->incusg,asn_buf,buf_len,tag); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_LNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->lnum,0x40,asn_buf); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_REDIND); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),1,&ptr->redind,0x40,asn_buf); + } + +//optional part will be encoded in the future + if (flag & BIT6_TRUE) + {//Called Location + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CDLOC,offset++); + encode_param_CallLocation(&ptr->CalledLocation,asn_buf,buf_len,tag); + } + + if (flag & BIT8_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CGDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->cgdgtsLen % 10,ptr->cgdgts,0x40,asn_buf); + } + + if (flag & BIT9_TRUE) + {//Calling Location + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CGLOC,offset++); + encode_param_CallLocation(&ptr->CallingLocation,asn_buf,buf_len,tag); + } + + if (flag & BIT12_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CNVUSG,offset++); + encode_param_cnvusg(&ptr->cnvusg,asn_buf,buf_len,tag); + } + + if (flag & BIT13_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_DESTDGTS); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),ptr->destdgtsLen % 10,ptr->destdgts,0x40,asn_buf); + } + + if (flag & BIT18_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_LLIND,offset++); + *buf_len = AddTLV(tag,0,&ptr->llind,0x40,asn_buf); + } + + if (flag & BIT19_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_OGTUSG,offset++); + encode_param_ogtusg(&ptr->ogtusg,asn_buf,buf_len,tag); + } +} + +void encode_param_tssub(DMH_TandemSegmentSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_OGTUSG,offset++); + encode_param_ogtusg(&ptr->ogtusg,asn_buf,buf_len,tag); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_SEGNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,offset++),4,&ptr->segnum,0x40,asn_buf); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_TSWID,offset++); + encode_param_swid(&ptr->tswid,asn_buf,buf_len,tag); + } + +//optional part will be encoded in the future +} + +void encode_param_tlsub(DMH_TerminationLegSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + u8 offset=1; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_BILLIND,offset++); + *buf_len = AddTLV(tag,1,&ptr->billind,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_LNUM,offset++); + *buf_len = AddTLV(tag,1,&ptr->lnum,0x40,asn_buf); + } + +//optional part will be encoded in the future + if (flag & BIT6_TRUE) + {//Called Location + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CDLOC,offset++); + encode_param_CallLocation(&ptr->CalledLocation,asn_buf,buf_len,tag); + } + + + if (flag & BIT9_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CGDGTS,offset++); + *buf_len = AddTLV(tag,ptr->cgdgtsLen,ptr->cgdgts,0x40,asn_buf); + } + + if (flag & BIT10_TRUE) + {//Calling Location + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CGLOC,offset++); + encode_param_CallLocation(&ptr->CallingLocation,asn_buf,buf_len,tag); + } + + if (flag & BIT13_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_CNVUSG,offset++); + encode_param_cnvusg(&ptr->cnvusg,asn_buf,buf_len,tag); + } + if (flag & BIT16_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_FBUSG,offset++); + encode_param_fbusg(&ptr->fbusg,asn_buf,buf_len,tag); + } + if (flag & BIT17_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_INCUSG,offset++); + encode_param_incusg(&ptr->incusg,asn_buf,buf_len,tag); + } + if (flag & BIT19_TRUE) + { + sprintf(tag,"%s.%d-%d",tag1,DMHPAR_LLIND,offset++); + *buf_len = AddTLV(tag,0,&ptr->llind,0x40,asn_buf); + } + +} + +void encode_param_auxlsub(DMH_AuxiliaryLegSubrecord *ptr,ASN_BUF *asn_buf,int *buf_len,char tag1[64]) +{ + u32 flag; + char tag[64]; + + flag = ptr->param_flag; + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_BILLIND); + *buf_len = AddTLV(is41_sequenceTag(tag,1),1,&ptr->billind,0x40,asn_buf); + } + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_LNUM); + *buf_len = AddTLV(is41_sequenceTag(tag,2),1,&ptr->lnum,0x40,asn_buf); + } + +//optional part will be encoded in the future +} + +int assign_DMHEventJacket(DMH_EventJacket *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + char tag[64]; + char tag1[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + sprintf(tag,"%d",DMHPAR_EJCKT); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_EJCKT,DMHPAR_AUDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + + encode_param_audsub(&ptr->audsub,&asn_buf,&buf_len,tag); + } + if (flag & BIT1_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_EJCKT,DMHPAR_IDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_idsub(&ptr->idsub,&asn_buf,&buf_len,tag); + } + + sprintf(tag1,"%d.16-%d",DMHPAR_EJCKT,offset); + buf_len = AddTLV(tag1,0,temp,0x20,&asn_buf); + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_EVTSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_evtsub(&ptr->evtsub,&asn_buf,&buf_len,tag); + } + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_chrgsub(&ptr->chrgsub,&asn_buf,&buf_len,tag); + } + + return buf_len; +} + +int assign_DMH_ActivityJacket(DMH_ActivityJacket *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + char tag[64]; + char tag1[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + sprintf(tag,"%d",DMHPAR_AJCKT); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_AJCKT,DMHPAR_AUDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_audsub(&ptr->audsub,&asn_buf,&buf_len,tag); + } + if (flag & BIT1_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_AJCKT,DMHPAR_IDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_idsub(&ptr->idsub,&asn_buf,&buf_len,tag); + } + + sprintf(tag1,"%d.16-%d",DMHPAR_AJCKT,offset); + buf_len = AddTLV(tag1,0,temp,0x20,&asn_buf); + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_ACTSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_actsub(&ptr->actsub,&asn_buf,&buf_len,tag); + } + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_chrgsub(&ptr->chrgsub,&asn_buf,&buf_len,tag); + } + + return buf_len; +} + +int assign_DMH_CallJacket(DMH_CallJacket *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + char tag[64]; + char tag1[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + sprintf(tag,"%d",DMHPAR_CJCKT); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_CJCKT,DMHPAR_AUDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_audsub(&ptr->audsub,&asn_buf,&buf_len,tag); + } + if (flag & BIT1_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_CJCKT,DMHPAR_IDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_idsub(&ptr->idsub,&asn_buf,&buf_len,tag); + } + + sprintf(tag1,"%d.16-%d",DMHPAR_CJCKT,offset); + buf_len = AddTLV(tag1,0,temp,0x20,&asn_buf); + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_ACTSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_actsub(&ptr->actsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AIRSSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_airssub(&ptr->airssub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_chrgsub(&ptr->chrgsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FALSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_falsub(&ptr->falsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_OLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_olsub(&ptr->olsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT7_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_PACASUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_pacasub(&ptr->pacasub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT8_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_rlsub(&ptr->rlsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT9_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TSSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_tssub(&ptr->tssub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT10_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_tlsub(&ptr->tlsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT11_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AUXLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_auxlsub(&ptr->auxlsub,&asn_buf,&buf_len,tag); + } + + return buf_len; +} + +int assign_DMH_LegJacket(DMH_LegJacket *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + char tag[64]; + char tag1[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + sprintf(tag,"%d",DMHPAR_LJCKT); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_LJCKT,DMHPAR_IDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_idsub(&ptr->idsub,&asn_buf,&buf_len,tag); + } + + sprintf(tag1,"%d.16-%d",DMHPAR_LJCKT,offset); + buf_len = AddTLV(tag1,0,temp,0x20,&asn_buf); + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_chrgsub(&ptr->chrgsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_FALSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_falsub(&ptr->falsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_OLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_olsub(&ptr->olsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_RLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_rlsub(&ptr->rlsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_tlsub(&ptr->tlsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT6_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AUXLSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_auxlsub(&ptr->auxlsub,&asn_buf,&buf_len,tag); + } + + return buf_len; +} + +int assign_DMH_SegmentJacket(DMH_SegmentJacket *ptr,u8 *buf) +{ + ASN_BUF asn_buf; + int buf_len=0; + u32 flag; + char tag[64]; + char tag1[64]; + u8 temp[8]; + u8 offset=1; + + flag = ptr->param_flag; + AsnEncode(buf,256,&asn_buf); + + sprintf(tag,"%d",DMHPAR_SJCKT); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + + if (flag & BIT0_TRUE) + { + sprintf(tag,"%d.%d-%d",DMHPAR_SJCKT,DMHPAR_IDSUB,offset++); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_idsub(&ptr->idsub,&asn_buf,&buf_len,tag); + } + + sprintf(tag1,"%d.16-%d",DMHPAR_SJCKT,offset); + buf_len = AddTLV(tag1,0,temp,0x20,&asn_buf); + + if (flag & BIT1_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_ACTSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_actsub(&ptr->actsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT2_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_AIRSSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_airssub(&ptr->airssub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT3_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_CHRGSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_chrgsub(&ptr->chrgsub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT4_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_PACASUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_pacasub(&ptr->pacasub,&asn_buf,&buf_len,tag); + } + + if (flag & BIT5_TRUE) + { + sprintf(tag,"%s.%d",tag1,DMHPAR_TSSUB); + buf_len = AddTLV(tag,0,temp,0x60,&asn_buf); + encode_param_tssub(&ptr->tssub,&asn_buf,&buf_len,tag); + } + + return buf_len; +} + + +void encode_DMH_date(u8 *date) +{ + time_t tick; + struct tm *tm_ptr; + + time(&tick); + tm_ptr = gmtime(&tick); + date[0] = tm_ptr->tm_year-84; //+1900-1984 + date[1] = tm_ptr->tm_mon+1; + date[2] = tm_ptr->tm_mday; +} + +u8 encode_DMH_TimeDateOffset(u8 *TimeDateOffset) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + return encode_integer(TimeDateOffset,tz.tz_minuteswest); +} + +u8 encode_DMH_TimeOfDay(u8 *TimeOfDay) +{ + struct timeval tv; + struct timezone tz; + u32 time; + + gettimeofday(&tv, &tz); + + time = (tv.tv_sec%86400)*10+tv.tv_usec/100000; + + return encode_integer(TimeOfDay, time); +} diff --git a/plat/xapp/src/xap_cdmacdr.h b/plat/xapp/src/xap_cdmacdr.h new file mode 100644 index 0000000..03f1423 --- /dev/null +++ b/plat/xapp/src/xap_cdmacdr.h @@ -0,0 +1,898 @@ +/* HLR CDMA cdr structure */ +/* Created by daniel:2005-06-21 */ +/* Modify by daniel:2005-06-21 */ +/* -------------------------------- */ + +#define DMHPAR_ASWID 0 +#define DMHPAR_AUDSN 1 +#define DMHPAR_AUDSUB 2 +#define DMHPAR_BIN 6 +#define DMHPAR_BILLIND 7 +#define DMHPAR_CDDGTS 8 +#define DMHPAR_CDLOC 9 +#define DMHPAR_CGDGTS 10 +#define DMHPAR_CGLOC 11 +#define DMHPAR_CHRGAMT 12 +#define DMHPAR_CNVDUR 13 +#define DMHPAR_CNVUSG 14 +#define DMHPAR_DATE 15 +#define DMHPAR_DIALDGTS 16 +#define DMHPAR_DUR 17 +#define DMHPAR_IDSUB 18 +#define DMHPAR_LNUM 19 +#define DMHPAR_MODIND 20 +#define DMHPAR_OSWID 21 +#define DMHPAR_RLEG 22 +#define DMHPAR_SEGNUM 23 +#define DMHPAR_SSWID 24 +#define DMHPAR_SWNO 25 +#define DMHPAR_SID 26 +#define DMHPAR_TOD 27 +#define DMHPAR_TKNUM 29 +#define DMHPAR_ACTIND 32 +#define DMHPAR_AJCKT 33 +#define DMHPAR_ACTSUB 34 +#define DMHPAR_ACHDUR 37 +#define DMHPAR_ACHUSG 38 +#define DMHPAR_AIRSSUB 39 +#define DMHPAR_AUTHCNT 42 +#define DMHPAR_AUTHDEN 43 +#define DMHPAR_AUTHTYP 44 +#define DMHPAR_CJCKT 47 +#define DMHPAR_CELLID 49 +#define DMHPAR_CHRGIND 50 +#define DMHPAR_CHRGSUB 51 +#define DMHPAR_CHRGTAX 52 +#define DMHPAR_CHRGTIND 53 +#define DMHPAR_CHRGUNIT 54 +#define DMHPAR_DENACC 56 +#define DMHPAR_DESTDGTS 57 +#define DMHPAR_ESN 58 +#define DMHPAR_EVTIND 60 +#define DMHPAR_FPARM 61 +#define DMHPAR_FBDUR 62 +#define DMHPAR_FBIND 64 +#define DMHPAR_FBUSG 65 +#define DMHPAR_FEATIND 66 +#define DMHPAR_FEATOPN 67 +#define DMHPAR_FRIND 68 +#define DMHPAR_HCOORD 69 +#define DMHPAR_HSWID 70 +#define DMHPAR_IECCDUR 71 +#define DMHPAR_INCDUR 73 +#define DMHPAR_INCUSG 74 +#define DMHPAR_LLIND 78 +#define DMHPAR_LJCKT 81 +#define DMHPAR_MIN 84 +#define DMHPAR_MRPI 85 +#define DMHPAR_NPANXX 86 +#define DMHPAR_NUMACT 87 +#define DMHPAR_NUMCHRG 89 +#define DMHPAR_NUMEVT 90 +#define DMHPAR_NUMLEG 91 +#define DMHPAR_NUMSEG 93 +#define DMHPAR_OLSUB 94 +#define DMHPAR_OGTDUR 95 +#define DMHPAR_OGTUSG 96 +#define DMHPAR_PLNAM 97 +#define DMHPAR_RCHNUM 99 +#define DMHPAR_RPI 100 +#define DMHPAR_REDIND 101 +#define DMHPAR_RLSUB 102 +#define DMHPAR_RBIN 103 +#define DMHPAR_RELIND 104 +#define DMHPAR_RIN 106 +#define DMHPAR_SRT 109 +#define DMHPAR_SJCKT 110 +#define DMHPAR_SPNAM 112 +#define DMHPAR_TSSUB 113 +#define DMHPAR_TSWID 114 +#define DMHPAR_TLSUB 115 +#define DMHPAR_TDO 116 +#define DMHPAR_TTIND 117 +#define DMHPAR_VCOORD 118 +#define DMHPAR_BINR 128 +#define DMHPAR_BRI 129 +#define DMHPAR_EJCKT 142 +#define DMHPAR_EVTSUB 143 +#define DMHPAR_FALSUB 146 +#define DMHPAR_PACAIND 150 +#define DMHPAR_PACASUB 151 +#define DMHPAR_AUXLSUB 161 +#define DMHPAR_IMEI 165 +#define DMHPAR_IMSI 166 +#define DMHPAR_LATA 167 +#define DMHPAR_NUMOCT 168 +#define DMHPAR_NUMPKT 169 +#define DMHPAR_TEXIND 170 +#define DMHPAR_CHRGTCOD 171 +#define DMHPAR_CHRGTTBL 172 +#define DMHPAR_FILLIND 178 +#define DMHPAR_FILLIC 179 +#define DMHPAR_MDN 184 +#define DMHPAR_NEICLNP 186 +#define DMHPAR_NUMFAL 188 +#define DMHPAR_NUMRED 189 +#define DMHPAR_NUMORG 190 +#define DMHPAR_NUMTRM 191 +#define DMHPAR_SELUSE 193 +#define DMHPAR_SUCOD 194 +#define DMHPAR_MYTYP 196 +#define DMHPAR_NUMAUX 199 +#define DMHPAR_NEIIP 200 +#define DMHPAR_IWFDUR 202 +#define DMHPAR_RETIND 207 +#define DMHPAR_RICODE 208 +#define DMHPAR_RSEG 209 +#define DMHPAR_WCNTRY 214 + +#define EVTIND_authorizationGranted 1 +#define EVTIND_authorizationExpired 2 +#define EVTIND_authorizationDenied 3 +#define EVTIND_securityViolationReport 4 +#define EVTIND_inactive 5 +#define EVTIND_deregistration 6 +#define EVTIND_registrationCanceled 7 +#define EVTIND_profileUpdated 8 +#define EVTIND_qualificationUpdated 9 +#define EVTIND_terminationDeniedInvalid 10 +#define EVTIND_terminationDeniedUnassigned 11 +#define EVTIND_terminationDeniedInactive 12 +#define EVTIND_terminationDeniedUnregistered 13 +#define EVTIND_terminationDeniedNoPageResponse 14 +#define EVTIND_terminationDeniedBusy 15 +#define EVTIND_terminationDeniedSCA 16 +#define EVTIND_terminationDeniedDND 17 +#define EVTIND_terminationDeniedCD 18 +#define EVTIND_terminationDeniedCS 19 +#define EVTIND_terminationDeniedOther 20 +#define EVTIND_callDelivered 21 +#define EVTIND_callForwarded 22 +#define EVTIND_callForwardingNotification 23 +#define EVTIND_messageWaitingNotification 24 +#define EVTIND_originationDeniedNoTrunk 25 +#define EVTIND_originationDeniedUnrecognized 26 +#define EVTIND_originationDeniedCB 27 +#define EVTIND_originationDeniedOther 28 +#define EVTIND_unspecifiedHourlyEvent 29 +#define EVTIND_unspecifiedDailyEvent 30 +#define EVTIND_unspecifiedWeeklyEvent 31 +#define EVTIND_unspecifiedMonthlyEvent 32 +#define EVTIND_unspecifiedQuarterlyEvent 33 +#define EVTIND_unspecifiedSemi_annualEvent 34 +#define EVTIND_unspecifiedAnnualEvent 35 +#define EVTIND_featureAccessAttempted 36 +#define EVTIND_SMSMO 37 +#define EVTIND_SMSMT 38 +#define EVTIND_SMSNOT 39 + +#define ACTIND_unspecified 0 +#define ACTIND_locallyDeniedRegistration 1 +#define ACTIND_homeDeniedRegistration 2 +#define ACTIND_powerOnRegistration 3 +#define ACTIND_autonomousRegistration 4 +#define ACTIND_missedAutonomousRegistration 5 +#define ACTIND_movementRegistration 6 +#define ACTIND_movementDetected 7 +#define ACTIND_powerDownDeregistration 8 +#define ACTIND_pageResponse 0 +#define ACTIND_noPageResponse 10 +#define ACTIND_messageWaiting 11 +#define ACTIND_abbreviatedAlert 12 +#define ACTIND_alert 13 +#define ACTIND_alertWithInformation 14 +#define ACTIND_alertingAnswered 15 +#define ACTIND_pACARequest 16 +#define ACTIND_originationRequest 17 +#define ACTIND_flashRequestWithoutInformation 18 +#define ACTIND_flashRequestWithInformation 19 +#define ACTIND_callModeChanged 20 +#define ACTIND_lostRadioContact 21 +#define ACTIND_measurementRequest 22 +#define ACTIND_mAHORequest 23 +#define ACTIND_intraSystemHandoff 24 +#define ACTIND_interSystemHandoff 25 +#define ACTIND_powerControlProblem 26 +#define ACTIND_protocolError 27 +#define ACTIND_spuriousEmissions 28 +#define ACTIND_orderedRegistration 29 +#define ACTIND_trafficChannelRegistration 30 +#define ACTIND_dataBurst_ShortMessage 31 +#define ACTIND_featureNotification 32 +#define ACTIND_lock 33 +#define ACTIND_unlock 34 +#define ACTIND_maintenanceRequired 35 +#define ACTIND_intrasystemSoftHandoffBegin 36 +#define ACTIND_intersystemSoftHandoffBegin 37 +#define ACTIND_packetDataRegistrationOnly 38 + +#define FEATIND_callForwarding_Unconditional 1 +#define FEATIND_callForwarding_Busy 2 +#define FEATIND_callForwarding_NoAnswer 3 +#define FEATIND_callForwarding_Other 4 +#define FEATIND_callWaiting 5 +#define FEATIND_threeWayCalling 6 +#define FEATIND_callDelivery 7 +#define FEATIND_doNotDisturb 8 +#define FEATIND_conferenceCalling 9 +#define FEATIND_callTransfer 10 +#define FEATIND_callingNumberIdentificationRestriction 11 +#define FEATIND_selectiveCallAcceptance 12 +#define FEATIND_authorizationCode 13 +#define FEATIND_speedDialing 14 +#define FEATIND_adviceOfCharging 15 +#define FEATIND_voiceMail 16 +#define FEATIND_callForwardDefault 17 +#define FEATIND_callingNumberIdentificationPresentation 18 +#define FEATIND_flexibleAlerting 19 +#define FEATIND_messageWaitingNotification 20 +#define FEATIND_mobileAccessHunting 21 +#define FEATIND_passwordCallAcceptance 22 +#define FEATIND_preferredLanguageService 23 +#define FEATIND_priorityAccessAndChannelAssignment 24 +#define FEATIND_remoteFeatureControl 25 +#define FEATIND_subscriberPINAccess 26 +#define FEATIND_subscriberPINIntercept 27 +#define FEATIND_voicePrivacy 28 +#define FEATIND_shortMessageDeliveryPoint_ToPointBearer 29 +#define FEATIND_shortMessageDeliveryBroadcast 30 +#define FEATIND_cellularPagingTeleservice 31 +#define FEATIND_cellularMessagingTeleservice 32 +#define FEATIND_intersystemCall 33 +#define FEATIND_voiceMailDelete 34 +#define FEATIND_voiceMailSend 35 +#define FEATIND_voiceMailDeposit 36 +#define FEATIND_answerHold 37 +#define FEATIND_userSelectiveCallForwarding 38 + +#define FEATOPN_featureRegistration 1 +#define FEATOPN_featureDeregistration 2 +#define FEATOPN_featureActivation 3 +#define FEATOPN_featureDeactivation 4 +#define FEATOPN_featureInvocation 5 +#define FEATOPN_featurePerCallActivation 6 +#define FEATOPN_featurePerCallDeactivation 7 +#define FEATOPN_featureRegistrationAndActivation 8 +#define FEATOPN_featureInterrogation 9 +#define FEATOPN_featureTesting 10 +#define FEATOPN_screenListEditing 11 + +#define FRIND_timerExpiry 1 +#define FRIND_networkFailure 2 +#define FRIND_operationError 3 +#define FRIND_operationReject 4 +#define FRIND_unspecified 5 +#define FRIND_unsuccessful 6 +#define FRIND_successful 7 + +typedef struct DMH_CallLocation +{ + u32 param_flag; + + u8 HcoordinateLen; + u8 Hcoordinate[3]; + + u8 NPANXX[3]; + + u8 PlaceNameLen; + u8 PlaceName[20]; + + u8 StateProvinceName[2]; + + u8 VcoordinateLen; + u8 Vcoordinate[3]; + + u8 LocalAccessTransportAreaLen; + u8 LocalAccessTransportArea[4]; + + u8 WorldCountry[3]; +}DMH_CallLocation; + +typedef struct DMH_ReturnIndicator +{ + u32 param_flag; + + u8 ReturnIndicatorCode; + +//optional part + struct + { + u8 ParameterIdentifierLen; + u8 ParameterIdentifier[16]; + } FaultyParameter; + +}DMH_ReturnIndicator; + +typedef struct DMH_FillIndicator +{ + struct + { + u8 ParameterIdentifierLen; + u8 ParameterIdentifier[16]; + } FaultyParameter; + + u8 FillIndicatorCode; +}DMH_FillIndicator; + +typedef struct DMH_AuditSubrecord +{ + u32 param_flag; + + u8 audsnLen; + u8 audsn[4];//AuditSequenceNumber + +//optional part + u8 achdurLen; + u8 achdur[4];//AirChannelDuration + u8 cnvdurLen; + u8 cnvdur[4];//ConversationDuration + u8 fbdurLen; + u8 fbdur[4];//FeatureBridgeDuration + u8 ieccdurLen; + u8 ieccdur[4];//IECConnectDuration + u8 incdurLen; + u8 incdur[4];//IncomingTrunkDuration + u8 numactLen; + u8 numact[4];//NumberOfActivities + u8 numchrgLen; + u8 numchrg[4];//NumberOfCharges + u8 numevtLen; + u8 numevt[4];//NumberOfEvents + u8 numlegLen; + u8 numleg[4];//NumberOfLegs + u8 numsegLen; + u8 numseg[4];//NumberOfSegments + u8 ogtdurLen; + u8 ogtdur[4];//OutgoingTrunkDuration + u8 numfalLen; + u8 numfal[4];//NumberOfFeatureActivationLegs + u8 numorgLen; + u8 numorg[8];//NumberOfOriginationLegs + u8 numredLen; + u8 numred[4];//NumberOfRedirectionLegs + u8 numtrmLen; + u8 numtrm[4];//NumberOfTerminationLegs + u8 numauxLen; + u8 numaux[4];//NumberOfAuxiliaryLegs + u8 numoctLen; + u8 numoct[4];//NumberOfOctets + u8 numpktLen; + u8 numpkt[4];//NumberOfPackets + u8 iwfdurLen; + u8 iwfdur[4];//IWFDuration + DMH_FillIndicator fillind; + DMH_ReturnIndicator retind; +}DMH_AuditSubrecord; + +typedef struct DMH_SwitchID +{ + u32 param_flag; + + u8 swno;//SwitchNumber + u8 sid[2];//SystemIdentifier + u8 bri[2];//BusinessRelationIdentifier + u8 mytyp;//SystemMyTypeCode +}DMH_SwitchID; + +typedef struct DMH_IdentitySubrecord +{ + u32 param_flag; + + u8 Date[3]; + struct + { + u8 ChoiceFlag; + + u8 esn[4]; + u8 imei[5]; + } Choice1; + + struct + { + u8 ChoiceFlag; + + u8 min[5]; + u8 imsi[8]; + u8 neiclnp[19]; + u8 neiip[4]; + } Choice2; + + u8 tdoLen; + u8 tdo[2];//TimeDateOffset + u8 todLen; + u8 tod[3];//TimeOfDay + + struct + { + u8 ChoiceFlag; + + DMH_SwitchID aswid;//AnchorSWID + DMH_SwitchID oswid;//OriginatingSWID + DMH_SwitchID sswid;//ServingSWID + } Choice3; + + u8 binLen; + u8 bin[4];//BillingIdentificationNumber + + DMH_SwitchID hswid;//HomeSWID + + u8 mdnLen; + u8 mdn[8]; + DMH_FillIndicator fillind; + DMH_ReturnIndicator retind; + +}DMH_IdentitySubrecord; + +typedef struct DMH_EventSubrecord +{ + u32 param_flag; + + u8 evtind;//EventIndicator + u8 rinLen; + u8 rin[4];//ReportIdentificationNumber + +//optional part + DMH_SwitchID aswid;//AnchorSWID + + u8 authcnt;//AuthorizationCount + u8 authden;//AuthorizationDenied + u8 authtyp;//AuthorizationType + u8 binLen; + u8 bin[4];//BillingIdentificationNumber + u8 Date[3]; + u8 denacc;//DenyAccess + u8 featind;//FeatureIndicator + u8 featopn;//FeatureOperation + u8 frind;//FeatureResultIndicator + + DMH_SwitchID oswid;//OriginatingSWID + + u8 rbinLen; + u8 rbin[4];//RelatedBillingIdentificationNumber + u8 srt;//SecurityReportType + + DMH_SwitchID sswid;//ServingSWID + + u8 tdoLen; + u8 tdo[2];//TimeDateOffset + u8 todLen; + u8 tod[3];//TimeOfDay + DMH_FillIndicator fillind; + DMH_ReturnIndicator retind; +}DMH_EventSubrecord; + +typedef struct DMH_ChargeSubrecord +{ + u32 param_flag; + + u8 chrgamtLen; + u8 chrgamt[4];//ChargeAmount + u8 chrgind;//ChargeIndicator + +//optional part + u8 chrgtaxLen; + u8 chrgtax[4];//ChargeTax + u8 chrgtind;//ChargeTaxIndicator + u8 chrgunit;//ChargeUnits + u8 durLen; + u8 dur[4];//Duration + u8 mrpi;//MultipleRatePeriodIndicator,len=0 + u8 plnamLen; + u8 plnam[20];//PlaceName + u8 rpi;//RatePeriodIndicator + u8 spnam[2];//StateProvinceName + u8 ttind;//TollTariffIndicator + u8 wcntry[3];//WorldCountry + + struct + { + u8 ChoiceFlag; + + u8 lnum;//LegNumber + u8 segnum;//SegmentNumber + } Choice; + + u8 chrgtcodLen; + u8 chrgtcod[2];//ChargeTaxCode + u8 chrgttbl;//ChargeTaxTable + u8 numoctLen; + u8 numoct[4];//NumberOfOctets + u8 numpktLen; + u8 numpkt[4];//NumberOfPackets + u8 seluseLen; + u8 seluse[100];//SelectiveUse + u8 sucod;//SelectiveUseCode + u8 texind;//TaxExemptIndicator + DMH_FillIndicator fillind; + DMH_ReturnIndicator retind; +}DMH_ChargeSubrecord; + +typedef struct DMH_BeginForwardPath +{ + u32 param_flag; + + u8 cellidLen; + u8 cellid[2];//CellIdentifier + u8 modind;//ModulationIndicator + u8 rchnumLen; + u8 rchnum[2];//RadioChannelNumber + u8 tknumLen; + u8 tknum[2];//TrunkNumber + +//optional part + u8 bearind;//BearerIndicator + u8 locidLen; + u8 locid[2];//LocationAreaIdentifier + u8 radattr[2];//RadioAttributes + u8 trnsnumLen; + u8 trnsnum[2];//TransceiverNumber + u8 tkgrpLen; + u8 tkgrp[2];//TrunkGroup + + struct + { + u8 ChoiceFlag; + //will add encode in the future + + } Choice; + + u8 cellnamLen; + u8 cellnam[8];//CellName + u8 tgpnamLen; + u8 tgpnam[12];//TrunkGroupName + u8 uzLen; + u8 uz[3];//UserZoneNumber + u8 bndclsLen; + u8 bndcls[63];//BandClass + u8 freqind;//FrequencyIndicator +}DMH_BeginForwardPath;//BeginForwardPath + +typedef struct DMH_EndForwardPath +{ + u32 param_flag; +}DMH_EndForwardPath;//BeginForwardPath + +typedef struct DMH_ActivitySubrecord +{ + u32 param_flag; + + u8 actind;//ActivityIndicator + u8 rinLen; + u8 rin[4];//ReportIdentificationNumber + +//optional part + u8 authden;//AuthorizationDenied + + DMH_BeginForwardPath bfpath; + u8 binLen; + u8 bin[4];//BillingIdentificationNumber + u8 Date[3]; + u8 denacc;//DenyAccess + u8 srt;//SecurityReportType + + DMH_SwitchID sswid;//ServingSWID + + u8 tdoLen; + u8 tdo[2];//TimeDateOffset + u8 todLen; + u8 tod[3];//TimeOfDay + DMH_FillIndicator fillind; + u8 rsegLen; + u8 rseg[3];//RelatedSegmentNumber + DMH_ReturnIndicator retind; +}DMH_ActivitySubrecord; + +typedef struct DMH_FeatureBridgeUsage +{ + u32 param_flag; + + u8 fbind; //FeatureBridgeIndicator + u8 durLen; + u8 dur[4];//Duration + u8 rlegLen; + u8 rleg[3];//RelatedLegNumber + u8 todLen; + u8 tod[3];//TimeOfDay + +}DMH_FeatureBridgeUsage; + +typedef struct DMH_IncomingTrunkUsage +{ + u32 param_flag; + + u8 durLen; + u8 dur[4];//Duration + u8 todLen; + u8 tod[3];//TimeOfDay + u8 tknumLen; + u8 tknum[2];//TrunkNumber + + u8 cardgts[2];//CarrierDigits + u8 Date[3]; + u8 relind;//ReleaseIndicator + u8 tdoLen; + u8 tdo[2];//TimeDateOffset + u8 tkgrpLen; + u8 tkgrp[2];//TrunkGroup + u8 tgpnamLen; + u8 tgpnam[12];//TrunkGroupName +}DMH_IncomingTrunkUsage; + +typedef struct DMH_OutgoingTrunkUsage +{ + u32 param_flag; + + u8 durLen; + u8 dur[4];//Duration + u8 todLen; + u8 tod[3];//TimeOfDay + u8 tknumLen; + u8 tknum[2];//TrunkNumber + + u8 cardgts[2];//CarrierDigits + u8 Date[3]; + u8 relind;//ReleaseIndicator + u8 tdoLen; + u8 tdo[2];//TimeDateOffset + u8 tkgrpLen; + u8 tkgrp[2];//TrunkGroup + u8 tgpnamLen; + u8 tgpnam[12];//TrunkGroupName +}DMH_OutgoingTrunkUsage; + +typedef struct DMH_AirChannelUsage +{ + u32 param_flag; + + DMH_BeginForwardPath bfpath; + u8 durLen; + u8 dur[4];//Duration + u8 todLen; + u8 tod[3];//TimeOfDay + u8 Date[3]; + +//optional part + DMH_EndForwardPath efpath; + u8 relind;//ReleaseIndicator + u8 tdoLen; + u8 tdo[2];//TimeDateOffset +}DMH_AirChannelUsage; + +typedef struct DMH_AirSegmentSubrecord +{ + u32 param_flag; + + DMH_AirChannelUsage achusg;//AirChannelUsage + u8 segnum;//SegmentNumber + +//optional part + struct + { + u32 param_flag; + + u8 latLen; + u8 lat[3];//Latitude + u8 LONGLen; + u8 LONG[3];//Longitude + u8 resolLen; + u8 resol[3];//Resolution + }begloc;//BeginLocation + DMH_IncomingTrunkUsage incusg;//IncomingTrunkUsage + u8 lsind;//LastSegmentIndicator,len=0 + DMH_SwitchID sswid;//ServingSWID + u8 cgblind;//ChargeableIndicator + DMH_FillIndicator fillind; + DMH_ReturnIndicator retind; + +}DMH_AirSegmentSubrecord; + +typedef struct DMH_FeatureActivationLegSubrecord +{ + u32 param_flag; + + u8 dialdgtsLen; + u8 dialdgts[32];//DialedDigits + u8 lnum;//LegNumber + +//optional part will be encoded in the future + u8 frind;//FeatureResultIndicator, BIT13 + u8 llind;//LastLegIndicator, BIT15 +}DMH_FeatureActivationLegSubrecord; + +typedef struct DMH_ConversationUsage +{ + u32 param_flag; + + u8 durLen; + u8 dur[4];//Duration + u8 todLen; + u8 tod[3];//TimeOfDay + +//optional part + u8 Date[3]; + u8 relind;//ReleaseIndicator + u8 tdoLen; + u8 tdo[2];//TimeDateOffset + u8 numoctLen; + u8 numoct[4];//NumberOfOctets + u8 numpktLen; + u8 numpkt[4];//NumberOfPackets +}DMH_ConversationUsage; + +typedef struct DMH_OriginationLegSubrecord +{ + u32 param_flag; + + u8 billind;//BillingIndicator + u8 dialdgtsLen; + u8 dialdgts[32];//DialedDigits + u8 lnum;//LegNumber + + DMH_CallLocation CalledLocation;//BIT8 + + DMH_CallLocation CallingLocation;//BIT11 + + DMH_ConversationUsage cnvusg;//ConversationUsage,BIT14 + DMH_FeatureBridgeUsage fbusg;//FeatureBridgeUsage,BIT16 + u8 llind;//LastLegIndicator,len=0,BIT19 + DMH_OutgoingTrunkUsage ogtusg;//OutgoingTrunkUsage.BIT20 + +}DMH_OriginationLegSubrecord; + +typedef struct DMH_PACASegmentSubrecord +{ + u32 param_flag; + + u8 cellidLen; + u8 cellid[2];//CellIdentifier + u8 durLen; + u8 dur[4];//Duration + u8 pacaind;//PACAIndicator + u8 segnum;//SegmentNumber +}DMH_PACASegmentSubrecord; + +typedef struct DMH_RedirectionLegSubrecord +{ + u32 param_flag; + + u8 billind;//BillingIndicator + u8 cddgtsLen; + u8 cddgts[9];//CalledDigits + DMH_IncomingTrunkUsage incusg;//IncomingTrunkUsage + u8 lnum;//LegNumber + u8 redind;//RedirectionIndicator + +//optional part + DMH_CallLocation CalledLocation;//BIT6 + + u8 cgdgtsLen; + u8 cgdgts[9];//CallingDigits, BIT8 + + DMH_CallLocation CallingLocation;//BIT9 + + DMH_ConversationUsage cnvusg;//ConversationUsage,BIT12 + u8 destdgtsLen; + u8 destdgts[32];//DestinationDigits,BIT13 + u8 llind;//LastLegIndicator,len=0,BIT18 + DMH_OutgoingTrunkUsage ogtusg;//OutgoingTrunkUsage.BIT19 + +}DMH_RedirectionLegSubrecord; + +typedef struct DMH_TandemSegmentSubrecord +{ + u32 param_flag; + + DMH_OutgoingTrunkUsage ogtusg;//OutgoingTrunkUsage + u8 segnum;//SegmentNumber + DMH_SwitchID tswid;//ServingSWID + +//optional part will be added in the future +}DMH_TandemSegmentSubrecord; + +typedef struct DMH_TerminationLegSubrecord +{ + u32 param_flag; + + u8 billind;//BillingIndicator + u8 lnum;//LegNumber + +//optional part + DMH_CallLocation CalledLocation;//BIT6 + + u8 cgdgtsLen; + u8 cgdgts[9];//CallingDigits,BIT9 + + DMH_CallLocation CallingLocation;//BIT10 + + DMH_ConversationUsage cnvusg;//ConversationUsage,BIT13 + DMH_FeatureBridgeUsage fbusg;//FeatureBridgeUsage,BIT16 + DMH_IncomingTrunkUsage incusg;//IncomingTrunkUsage,BIT17 + u8 llind;//LastLegIndicator,len=0,BIT19 + +}DMH_TerminationLegSubrecord; + +typedef struct DMH_AuxiliaryLegSubrecord +{ + u32 param_flag; + + u8 billind;//BillingIndicator + u8 lnum;//LegNumber +}DMH_AuxiliaryLegSubrecord; + +typedef struct DMH_EventJacket +{ + u32 param_flag; + + DMH_AuditSubrecord audsub; + DMH_IdentitySubrecord idsub; + DMH_EventSubrecord evtsub; + DMH_ChargeSubrecord chrgsub; +}DMH_EventJacket; + +typedef struct DMH_ActivityJacket +{ + u32 param_flag; + + DMH_AuditSubrecord audsub; + DMH_IdentitySubrecord idsub; + DMH_ActivitySubrecord actsub; + DMH_ChargeSubrecord chrgsub; +}DMH_ActivityJacket; + +typedef struct DMH_CallJacket +{ + u32 param_flag; + + DMH_AuditSubrecord audsub; + DMH_IdentitySubrecord idsub; + + DMH_ActivitySubrecord actsub; + DMH_AirSegmentSubrecord airssub; + DMH_ChargeSubrecord chrgsub; + DMH_FeatureActivationLegSubrecord falsub; + DMH_OriginationLegSubrecord olsub; + DMH_PACASegmentSubrecord pacasub; + DMH_RedirectionLegSubrecord rlsub; + DMH_TandemSegmentSubrecord tssub; + DMH_TerminationLegSubrecord tlsub; + DMH_AuxiliaryLegSubrecord auxlsub; +}DMH_CallJacket; + +typedef struct DMH_LegJacket +{ + u32 param_flag; + + DMH_IdentitySubrecord idsub; + + DMH_ChargeSubrecord chrgsub; + DMH_FeatureActivationLegSubrecord falsub; + DMH_OriginationLegSubrecord olsub; + DMH_RedirectionLegSubrecord rlsub; + DMH_TerminationLegSubrecord tlsub; + DMH_AuxiliaryLegSubrecord auxlsub; +}DMH_LegJacket; + +typedef struct DMH_SegmentJacket +{ + u32 param_flag; + + DMH_IdentitySubrecord idsub; + + DMH_ActivitySubrecord actsub; + DMH_AirSegmentSubrecord airssub; + DMH_ChargeSubrecord chrgsub; + DMH_PACASegmentSubrecord pacasub; + DMH_TandemSegmentSubrecord tssub; +}DMH_SegmentJacket; + + + +int assign_DMHEventJacket(DMH_EventJacket *ptr,u8 *buf); +int assign_DMH_ActivityJacket(DMH_ActivityJacket *ptr,u8 *buf); +int assign_DMH_CallJacket(DMH_CallJacket *ptr,u8 *buf); +int assign_DMH_LegJacket(DMH_LegJacket *ptr,u8 *buf); +int assign_DMH_SegmentJacket(DMH_SegmentJacket *ptr,u8 *buf); +void encode_DMH_date(u8 *date); +u8 encode_DMH_TimeDateOffset(u8 *TimeDateOffset); +u8 encode_DMH_TimeOfDay(u8 *TimeOfDay); + diff --git a/plat/xapp/src/xap_interface.c b/plat/xapp/src/xap_interface.c new file mode 100644 index 0000000..ba497f0 --- /dev/null +++ b/plat/xapp/src/xap_interface.c @@ -0,0 +1,1063 @@ +/* XAP provider interface c file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* -------------------------------- */ +#include "../../public/src/include/public.h" +#include "../../public/src/include/license_id.h" +#include "../../tcap/src/include/itcap.h" +#include "../../tcap/src/include/idmanage.h" +#include "xap_provider.h" +#include "xap_monitor.h" +#include "mapp/map_public.h" +#include "capp/cap_public.h" + +extern int itcap_reg_ssn(u8 ssn); +int xap_mscid_to_num ( u8 * mscid, u8 ssn, u8 * num ) +{ + int i; + + for ( i = 0; i < 256; i++ ) + { + if( ( memcmp ( mscid, xap_inter_ptr->mscidToNum[i], 3 ) == 0 ) && ( xap_inter_ptr->mscidToNum[i][3] == ssn ) ) + { + memcpy ( num, xap_inter_ptr->mscidToNum[4], 10 ); + return 1; + } + } + return 0; +} + +void xap_get_mcc ( u8 * mcc ) +{ + memcpy ( mcc, xap_inter_ptr->mcc, 2 ); +} + +void xap_get_mnc ( u8 * mnc ) +{ + memcpy ( mnc, &xap_inter_ptr->mnc, 2 ); +} + +void xap_get_cc ( u8 * cc ) +{ + memcpy ( cc, xap_inter_ptr->cc, 2 ); +} + +void xap_get_ndc ( u8 * ndc ) +{ + memcpy ( ndc, xap_inter_ptr->ndc, 3 ); +} + +void xap_get_interprefix ( u8 * inter_prefix ) +{ + memcpy ( inter_prefix, xap_inter_ptr->inter_prefix, 2 ); +} + +void xap_get_nationalprefix ( u8 * national_prefix ) +{ + memcpy ( national_prefix, xap_inter_ptr->national_prefix, 2 ); +} + +void xap_get_localprefix ( u8 * local_prefix ) +{ + memcpy ( local_prefix, xap_inter_ptr->local_prefix, 2 ); +} + +int imap_reg_ssn ( u8 ssn ) +{ + u8 ii, jj; + + ii = xap_inter_ptr->regssn_len; + if( ii >= MAX_XAP_SSN ) + { + xap_send_error ( "Can not register ssn in map provider" ); + return -1; + } + for ( jj = 0; jj < ii; jj++ ) + { + if( xap_inter_ptr->reg_ssn[jj] == ssn ) + { + xap_send_error ( "ssn has registered in map provider" ); + return -1; + } + } + xap_inter_ptr->reg_ssn[ii] = ssn; + xap_inter_ptr->regssn_flag[ii] = XAP_MAP_SSN; + xap_inter_ptr->regssn_len++; + return itcap_reg_ssn ( ssn ); +} + +u8 map_check_sendcom ( u32 did ) +{ + struct xapp_vm_data *vm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->recvcom_flag == 0 ) + return 1; + return 0; +} + +u8 map_send_comdata_struct ( MapComSrv_struct * map_com ) // send map common service data +{ + u32 temp_did; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + if( xap_vm_ptr->debug_data.send_control ) + { + u8 data_flow[512]; + + map_com_stof ( map_com, data_flow, 1 ); + xap_send_error ( "[%d]Sending Com:%d in Structure", map_com->dialogue_id, map_com->message_type ); + xap_msg_display ( data_flow ); + } + + temp_did = map_com->dialogue_id; + if( temp_did >= ( xap_vm_ptr->grantdid ) ) + { + xap_send_error ( "[%d]Com:%d sending did error", temp_did, map_com->message_type ); + return 0; + } + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did]; + if( ( vm_ptr->recvcom_flag == 1 ) && ( map_com->message_type != MAP_U_ABORT ) ) /* daniel change on 2005-4-29 */ + { + xap_send_error ( "[%d]Com:%d sending without permit", temp_did, map_com->message_type ); + return 0; + } + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + // if (result == 2 || map_com->message_type == MAP_DELIMITER) + psm_ptr->delimiter_flag = 1; + if( map_com->message_type != MAP_DELIMITER ) + { + memcpy ( &vm_ptr->recvcom_data, map_com, sizeof ( MapComSrv_struct ) ); + psm_ptr->msg_type = map_com->message_type; + psm_ptr->msg_flag = map_com->message_flag; + vm_ptr->recvcom_flag = 1; + xap_watch_dog(27); + } + xap_watch_dog(25); + return 1; +} + +u8 map_send_comdata ( u8 * data_flow ) // send map common service data +{ + u8 result; + u32 temp_did; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct MapComSrv_struct map_com; + + //xap_msg_display ( data_flow ); + if( ( result = map_com_ftos ( &map_com, data_flow ) ) == 0 ) + { + xap_send_error ( "[%d]Com:%d sending translate error", map_com.dialogue_id, map_com.message_type ); + return 0; + } + temp_did = map_com.dialogue_id; + if( temp_did >= ( xap_vm_ptr->grantdid ) ) + { + xap_send_error ( "[%d]Com:%d sending did error", temp_did, map_com.message_type ); + return 0; + } + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did]; + if( ( vm_ptr->recvcom_flag == 1 ) && ( map_com.message_type != MAP_U_ABORT ) ) /* daniel change on 2005-4-29 */ + { + xap_send_error ( "[%d]Com:%d sending without permit", temp_did, map_com.message_type ); + return 0; + } + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + if( result == 2 || map_com.message_type == MAP_DELIMITER ) + { + if (result == 2) + xap_watch_dog(64); + else + xap_watch_dog(65); + psm_ptr->delimiter_flag = 1; + } + if( map_com.message_type != MAP_DELIMITER ) + { + memcpy ( &vm_ptr->recvcom_data, &map_com, sizeof ( MapComSrv_struct ) ); + psm_ptr->msg_type = map_com.message_type; + psm_ptr->msg_flag = map_com.message_flag; + vm_ptr->recvcom_flag = 1; + xap_watch_dog(28); + } + xap_watch_dog(25); + return 1; +} + +u8 map_check_sendopr ( u32 did ) +{ + struct xapp_vm_data *vm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->recvopr_flag == 1 ) + return 0; + return 1; +} + +u8 map_send_oprdata ( u8 * data_flow ) // send map operation service data +{ + u8 result; + u32 temp_did; + struct xapp_vm_data *vm_ptr; + struct MapOprData_struct map_opr; + + //xap_msg_display ( data_flow ); + if( ( result = map_opr_ftos ( &map_opr, data_flow ) ) == 0 ) + { + xap_send_error ( "[%d]Opr:%d sending translate error", map_opr.dialogue_id, map_opr.message_type ); + return 0; + } + temp_did = map_opr.dialogue_id; + if( temp_did >= ( xap_vm_ptr->grantdid ) ) + { + xap_send_error ( "[%d]Opr:%d sending did error", temp_did, map_opr.message_type ); + return 0; + } + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did]; + if( vm_ptr->recvopr_flag == 1 ) + { + xap_send_error ( "[%d]Opr:%d sending without permit", temp_did, map_opr.message_type ); + return 0; + } + xap_msg_display ( data_flow ); + memcpy ( &vm_ptr->recvopr_data, &map_opr, sizeof ( MapOprData_struct ) ); + if( result == 2 ) + { + vm_ptr->psm_data.delimiter_flag = 1; + xap_watch_dog(68); + } + vm_ptr->recvopr_flag = 1; + xap_watch_dog(45); + xap_watch_dog(47); + if(map_opr.message_type == SndRoutInfo) + { + if(map_opr.message_flag == 1) + { + xap_watch_dog(16); + } + else + { + xap_watch_dog(17); + } + } + else if(map_opr.message_type == ProvRoamNum) + { + if(map_opr.message_flag == 1) + { + xap_watch_dog(20); + } + else + { + xap_watch_dog(21); + } + } + return 1; +} + +u8 map_send_oprdata_struct ( MapOprData_struct * map_opr ) // send map operation service data +{ + u32 temp_did; + struct xapp_vm_data *vm_ptr; + + // struct MapOprData_struct map_opr; + + temp_did = map_opr->dialogue_id; + if( temp_did >= ( xap_vm_ptr->grantdid ) ) + { + xap_send_error ( "[%d]Opr:%d sending did error", temp_did, map_opr->message_type ); + return 0; + } + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did]; + + if( xap_vm_ptr->debug_data.send_control ) + { + u8 data_flow[512]; + + map_opr_stof ( map_opr, data_flow, 1 ); + xap_send_error ( "[%d]Sending Opr:%d in Structure ", map_opr->dialogue_id, map_opr->message_type ); + xap_msg_display ( data_flow ); + } + if( vm_ptr->recvopr_flag == 1 ) + { + xap_send_error ( "[%d]Opr:%d sending without permit", temp_did, map_opr->message_type ); + return 0; + } + memcpy ( &vm_ptr->recvopr_data, map_opr, sizeof ( MapOprData_struct ) ); + // if (result == 2) + vm_ptr->psm_data.delimiter_flag = 0; + vm_ptr->recvopr_flag = 1; + xap_watch_dog(45); + xap_watch_dog(48); + if(map_opr->message_type == SndRoutInfo) + { + if(map_opr->message_flag == 1) + { + xap_watch_dog(16); + } + else + { + xap_watch_dog(17); + } + } + else if(map_opr->message_type == ProvRoamNum) + { + if(map_opr->message_flag == 1) + { + xap_watch_dog(20); + } + else + { + xap_watch_dog(21); + } + } + return 1; +} + +u8 map_get_comdata ( u8 * data_flow, u32 did ) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->sendcom_flag == 0 ) + return 0; + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + map_com_stof ( &vm_ptr->sendcom_data, data_flow, 0 ); + vm_ptr->sendcom_flag = 0; + xap_watch_dog(6); + xap_watch_dog(7); + xap_msg_display ( data_flow ); + return 1; +} + +u8 map_get_comdata_struct ( MapComSrv_struct * map_com, u32 did ) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->sendcom_flag == 0 ) + return 0; + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + memcpy ( map_com, &vm_ptr->sendcom_data, sizeof ( struct MapComSrv_struct ) ); + if( xap_vm_ptr->debug_data.send_control ) + { + u8 data_flow[512]; + + map_com_stof ( map_com, data_flow, 0 ); + xap_msg_display ( data_flow ); + } + vm_ptr->sendcom_flag = 0; + xap_watch_dog(6); + xap_watch_dog(8); + return 1; +} + +u8 map_get_open ( u8 * data_flow, u8 ssn ) +{ + u8 aa; + u8 ii; + u8 flag = 0; + u32 temp_did; + + for ( aa = 0; aa < xap_inter_ptr->regssn_len; aa++ ) + { + if( xap_inter_ptr->reg_ssn[aa] == ssn ) // find ssn + { + flag = 1; + break; + } + } + if( flag == 0 ) + { + xap_send_error ( "SSN--%d is not registerd", ssn ); + return 0; + } + ii = xap_inter_ptr->open_tail[aa]; + if( xap_inter_ptr->open_head[aa] == ii ) // empty + return 0; + temp_did = xap_inter_ptr->open_did[aa][ii]; + xap_inter_ptr->open_tail[aa] = ( ii + 1 ) % XAP_OPEN_LEN; + if( !map_get_comdata ( data_flow, temp_did ) ) + return 0; + return 1; +} + +u8 map_get_open_struct ( MapComSrv_struct * map_com, u8 ssn ) +{ + u8 aa; + u8 ii; + u8 flag = 0; + u32 temp_did; + + for ( aa = 0; aa < xap_inter_ptr->regssn_len; aa++ ) + { + if( xap_inter_ptr->reg_ssn[aa] == ssn ) // find ssn + { + flag = 1; + break; + } + } + if( flag == 0 ) + { + xap_send_error ( "SSN--%d is not registerd", ssn ); + return 0; + } + ii = xap_inter_ptr->open_tail[aa]; + if( xap_inter_ptr->open_head[aa] == ii ) // empty + return 0; + temp_did = xap_inter_ptr->open_did[aa][ii]; + xap_inter_ptr->open_tail[aa] = ( ii + 1 ) % XAP_OPEN_LEN; + if( !map_get_comdata_struct ( map_com, temp_did ) ) + return 0; + return 1; +} + +u8 map_get_oprdata ( u8 * data_flow, u32 did ) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->sendopr_flag != 1 ) + return 0; + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + map_opr_stof ( &vm_ptr->sendopr_data, data_flow, 0 ); + vm_ptr->sendopr_flag = 0; + xap_watch_dog(11); + xap_msg_display ( data_flow ); + + if(vm_ptr->sendopr_data.message_type == SndRoutInfo) + { + if(vm_ptr->sendopr_data.message_flag == 2) + { + xap_watch_dog(18); + } + else + { + xap_watch_dog(19); + } + } + else if(vm_ptr->sendopr_data.message_type == ProvRoamNum) + { + if(vm_ptr->sendopr_data.message_flag == 2) + { + xap_watch_dog(22); + } + else + { + xap_watch_dog(23); + } + } + + return 1; +} + +u8 map_get_oprdata_struct ( MapOprData_struct * map_opr, u32 did ) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->sendopr_flag != 1 ) + return 0; + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + + memcpy ( map_opr, &vm_ptr->sendopr_data, sizeof ( struct MapOprData_struct ) ); + if( xap_vm_ptr->debug_data.send_control ) + { + u8 data_flow[512]; + + map_opr_stof ( map_opr, data_flow, 0 ); + xap_msg_display ( data_flow ); + } + vm_ptr->sendopr_flag = 0; + xap_watch_dog(11); + if(vm_ptr->sendopr_data.message_type == SndRoutInfo) + { + if(vm_ptr->sendopr_data.message_flag == 2) + { + xap_watch_dog(18); + } + else + { + xap_watch_dog(19); + } + } + else if(vm_ptr->sendopr_data.message_type == ProvRoamNum) + { + if(vm_ptr->sendopr_data.message_flag == 2) + { + xap_watch_dog(22); + } + else + { + xap_watch_dog(23); + } + } + return 1; +} + +int map_get_oprType ( u32 did ) +{ + struct xapp_vm_data *vm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->psm_data.psm_state == XAP_IDLE ) + { + return -1; + } + if( ( vm_ptr->sendopr_data.message_type != 0 ) && ( vm_ptr->sendopr_flag != 0 ) ) + { + return vm_ptr->sendopr_data.message_type; + } + return 0; +} + +u32 map_get_dialogueid ( u8 ssn ) +{ + u32 did; + + if( ( did = assign_did ( ) ) == 0 ) + { + xap_send_error ( "Fail to get did(Map)" ); + return 0; + } + xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_MAP_SSN; + xap_watch_dog(55); + return did; +} + +#if _SUPPORT_ANSI +u32 is41_get_dialogueid ( u8 ssn ) +{ + u32 did; + + if( ( did = assign_did ( ) ) == 0 ) + { + xap_send_error ( "IS41 Fail to get did(Map)" ); + return 0; + } + xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_IS41_SSN; + xap_watch_dog(56); + return did; +} +#endif + +u8 map_get_invokeid ( u32 did ) +{ + return assign_iid ( did ); +} + +#if _SUPPORT_ANSI +u8 map_check_map_flag ( u32 did ) +{ + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + if( xap_vm_ptr->xap_data[did].psm_data.xap_flag == XAP_IS41_SSN || xap_vm_ptr->xap_data[did].psm_data.xap_flag == XAP_AIN_SSN ) + return 0; + + return 1; +} +#endif + +u8 get_xap_flag(u32 did) +{ + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + + return xap_vm_ptr->xap_data[did].psm_data.xap_flag; +} + +int icap_reg_ssn ( u8 ssn ) +{ + u8 ii, jj; + if(wxc2_get_license(LIC_CAP)<=0) + { + xap_send_error ( "Can not register ssn in cap provider:no license" ); + return -1; + } + ii = xap_inter_ptr->regssn_len; + if( ii >= MAX_XAP_SSN ) + { + xap_send_error ( "Can not register ssn in map provider" ); + return -1; + } + for ( jj = 0; jj < ii; jj++ ) + { + if( xap_inter_ptr->reg_ssn[jj] == ssn ) + { + xap_send_error ( "ssn has registered in map provider" ); + return -1; + } + } + xap_inter_ptr->reg_ssn[ii] = ssn; + xap_inter_ptr->regssn_flag[ii] = XAP_CAP_SSN; + xap_inter_ptr->regssn_len++; + return itcap_reg_ssn ( ssn ); +} + +u8 cap_check_sendcom ( u32 did ) +{ + struct xapp_vm_data *vm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->recvcom_flag == 0 ) + return 1; + return 0; +} + +u8 cap_send_comdata ( u8 * data_flow ) // send cap common service data +{ + u8 result; + u32 temp_did; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct MapComSrv_struct map_com; + + //xap_msg_display ( data_flow ); + if( ( result = cap_com_ftos ( &map_com, data_flow ) ) == 0 ) + return 0; + temp_did = map_com.dialogue_id; + if( temp_did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did]; + if( vm_ptr->recvcom_flag == 1 ) + return 0; + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + if( result == 2 || map_com.message_type == MAP_DELIMITER ) + psm_ptr->delimiter_flag = 1; + if( map_com.message_type != MAP_DELIMITER ) + { + memcpy ( &vm_ptr->recvcom_data, &map_com, sizeof ( MapComSrv_struct ) ); + psm_ptr->msg_type = map_com.message_type; + psm_ptr->msg_flag = map_com.message_flag; + vm_ptr->recvcom_flag = 1; + xap_watch_dog(29); + } + xap_watch_dog(25); + return 1; +} + +u8 cap_check_sendopr ( u32 did ) +{ + struct xapp_vm_data *vm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->recvopr_flag == 1 ) + return 0; + return 1; +} + +u8 cap_send_oprdata ( u8 * data_flow ) // send cap operation service data +{ + u8 result; + u32 temp_did; + struct xapp_vm_data *vm_ptr; + struct MapOprData_struct map_opr; + //u8 info[1024]; + + //xap_msg_display ( data_flow ); + if( ( result = cap_opr_ftos ( &map_opr, data_flow ) ) == 0 ) + { + xap_send_error ( "errro: cap ftos failed" ); + return 0; + } + temp_did = map_opr.dialogue_id; + if( temp_did >= ( xap_vm_ptr->grantdid ) ) + { + xap_send_error ( "cap errro: did > max did" ); + return 0; + } + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did]; + if( vm_ptr->recvopr_flag == 1 ) + { + //xap_send_error("cap errro: quence full"); + return 0; + } + xap_msg_display ( data_flow ); + memcpy ( &vm_ptr->recvopr_data, &map_opr, sizeof ( MapOprData_struct ) ); + if( result == 2 ) + { + vm_ptr->psm_data.delimiter_flag = 1; + //xap_send_ascout("Delimiter Flag = YES\r\n"); + } + vm_ptr->recvopr_flag = 1; + xap_watch_dog(45); + xap_watch_dog(49); + //sprintf(info, "cap_send_oprdata: did: %ld, iid: %d, iid_state: %d\r\n", map_opr.dialogue_id, map_opr.invoke_id, xap_vm_ptr->xap_data[map_opr.dialogue_id].psm_data.opr_state[map_opr.invoke_id]); + //xap_send_ascout(info); + + return 1; +} + +u8 cap_get_comdata ( u8 * data_flow, u32 did ) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->sendcom_flag == 0 ) + return 0; + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + cap_com_stof ( &vm_ptr->sendcom_data, data_flow, 0 ); + vm_ptr->sendcom_flag = 0; + xap_watch_dog(6); + xap_watch_dog(9); + xap_msg_display ( data_flow ); + return 1; +} + +u8 cap_get_open ( u8 * data_flow, u8 ssn ) +{ + u8 aa; + u8 ii; + u8 flag = 0; + u32 temp_did; + + for ( aa = 0; aa < xap_inter_ptr->regssn_len; aa++ ) + { + if( xap_inter_ptr->reg_ssn[aa] == ssn ) // find ssn + { + flag = 1; + break; + } + } + if( flag == 0 ) + { + xap_send_error ( "SSN--%d is not registerd", ssn ); + return 0; + } + ii = xap_inter_ptr->open_tail[aa]; + if( xap_inter_ptr->open_head[aa] == ii ) // empty + return 0; + temp_did = xap_inter_ptr->open_did[aa][ii]; + xap_inter_ptr->open_tail[aa] = ( ii + 1 ) % XAP_OPEN_LEN; + if( !cap_get_comdata ( data_flow, temp_did ) ) + return 0; + return 1; +} + +u8 cap_get_oprdata ( u8 * data_flow, u32 did ) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + if( did >= ( xap_vm_ptr->grantdid ) ) + return 0; + vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did]; + if( vm_ptr->sendopr_flag != 1 ) + return 0; + psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data; + cap_opr_stof ( &vm_ptr->sendopr_data, data_flow, 0 ); + vm_ptr->sendopr_flag = 0; + xap_watch_dog(11); + xap_msg_display ( data_flow ); + return 1; +} + +u32 cap_get_dialogueid ( u8 ssn ) +{ + u32 did; + + if( ( did = assign_did ( ) ) == 0 ) + { + xap_send_error ( "Fail to get did(Cap)" ); + return 0; + } + xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_CAP_SSN; + xap_watch_dog(57); + return did; +} + +u8 cap_get_invokeid ( u32 did ) +{ + return assign_iid ( did ); +} + +u8 xapp_check_did_state ( u32 did ) +{ + if( xap_vm_ptr->xap_data[did].psm_data.psm_state == XAP_IDLE ) + { + return 1; + } + xap_vm_ptr->debug_data.watch_dog[108]++; + return 0; +} + +u8 xapp_check_did ( u32 did ) +{ + if( xap_vm_ptr->xap_data[did].psm_data.psm_state <= XAP_IDLE ) + { + return 1; + } + return 0; +} + +u8 map_send_oprsrv ( MapOprSrv_struct * srv_ptr, u8 DelimiterFlag, u8 * data_flow ) +{ + u32 len; + u8 buf[4096]; + MapOprData_struct data_ptr; + + data_ptr.port_id = srv_ptr->port_id; + data_ptr.dialogue_id = srv_ptr->dialogue_id; + data_ptr.invoke_id = srv_ptr->invoke_id; + data_ptr.message_type = srv_ptr->message_type; + data_ptr.message_flag = srv_ptr->message_flag; + data_ptr.param_flag = 0x1f; +#if _SUPPORT_ANSI + if(map_check_map_flag(srv_ptr->dialogue_id)) +#endif + len = build_mapparam ( srv_ptr, buf ); +#if _SUPPORT_ANSI + else + { + len = build_ainparam(srv_ptr, buf); + data_ptr.map_flag = IS41_FLAG; + } +#endif + //printf ( "map_send_oprsrv: build map param len ; %d \n", len ); + if( len < 0 || len > MAX_MAPPOPR_LEN ) + { + xap_send_error ( "map_send_oprsrv: build mapparam too long!" ); + return 0; + } + data_ptr.param_len = len; + memcpy ( data_ptr.param, buf, len ); + data_ptr.param_flag |= 0x20; + map_opr_stof ( &data_ptr, data_flow, DelimiterFlag ); + + return map_send_oprdata ( data_flow ); +} + +u8 map_send_comsrv ( MapComSrv_struct * com_ptr, u8 uDelimiterFlag, u8 * data_flow ) +{ + map_com_stof ( com_ptr, data_flow, uDelimiterFlag ); + return map_send_comdata ( data_flow ); +} + +u8 map_send_open ( MapOpenArgParam * pOpenParam, u8 * uDataFlow ) +{ + MapComSrv_struct map_com; + MapOpen_Arg *pOpenArg; + + pOpenArg = &map_com.dlg_list.open_arg; + + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_REQUEST; + map_com.port_id = pOpenParam->pid; + map_com.dialogue_id = pOpenParam->did; + memcpy ( &pOpenArg->local_add, &pOpenParam->local_add, sizeof ( SCCP_ADDR ) ); + memcpy ( &pOpenArg->peer_add, &pOpenParam->peer_add, sizeof ( SCCP_ADDR ) ); + pOpenArg->acn_data.acn = pOpenParam->acn; + pOpenArg->acn_data.acn_ver = map_get_acnver ( &pOpenParam->local_add, pOpenParam->acn ); + pOpenArg->param_flag = 0x0b; + xap_watch_dog(60); + if (pOpenParam->uDelimeterFlag != 0) + xap_watch_dog(61); + return map_send_comsrv ( &map_com, pOpenParam->uDelimeterFlag, uDataFlow ); +} + +u8 map_send_close ( u32 pid, u32 did, u8 uCloseReasion ) +{ + MapComSrv_struct map_com; + u8 uDataFlow[4096]; + + map_com.message_type = MAP_CLOSE; + map_com.message_flag = MAP_REQUEST; + map_com.port_id = pid; + map_com.dialogue_id = did; + map_com.dlg_list.close_arg.release_method = uCloseReasion; + map_com.dlg_list.close_arg.param_flag = 0x01; + + return map_send_comsrv ( &map_com, 0, uDataFlow ); + +} + +u8 map_extract_param ( MapOprSrv_struct * srv_ptr, MapOprData_struct * data_ptr, int ver ) +{ + srv_ptr->port_id = data_ptr->port_id; + srv_ptr->dialogue_id = data_ptr->dialogue_id; + srv_ptr->invoke_id = data_ptr->invoke_id; + srv_ptr->message_type = data_ptr->message_type; + srv_ptr->message_flag = data_ptr->message_flag; + srv_ptr->version = ver; +/* + if( !( data_ptr->param_flag & 0x20 ) ) // has not parameter + return 0; + //some response doesn't take any parameter, like V2 fwdMOSMSResponse... +*/ + if(get_xap_flag(srv_ptr->dialogue_id) == XAP_AIN_SSN) + return extract_ainparam(srv_ptr, data_ptr->message_type, data_ptr->message_flag, data_ptr->param_len, data_ptr->param); + + return extract_mapparam ( srv_ptr, data_ptr->message_type, data_ptr->message_flag, data_ptr->param_len, data_ptr->param ); +} + +u8 cap_send_oprsrv ( CapArg * pCapArg, u8 DelimiterFlag, u8 * data_flow ) +{ + + u32 len; + u8 buf[4096]; + MapOprData_struct data_ptr; + + data_ptr.port_id = pCapArg->port_id; + data_ptr.dialogue_id = pCapArg->dialogue_id; + data_ptr.invoke_id = pCapArg->invoke_id; + data_ptr.message_type = pCapArg->ocode; + data_ptr.message_flag = pCapArg->message_flag; + data_ptr.param_flag = 0x1f; + len = encode_capmsg ( *pCapArg, buf, 4096 ); + //printf ( "cap_send_oprsrv: build map param len ; %d \n", len ); + if( len == 0 || len > MAX_MAPPOPR_LEN ) + { + xap_send_error ( "cap_send_oprsrv: build capparam too long!" ); + return 0; + } + data_ptr.param_len = len; + memcpy ( data_ptr.param, buf, len ); + data_ptr.param_flag |= 0x20; + cap_opr_stof ( &data_ptr, data_flow, DelimiterFlag ); + + return cap_send_oprdata ( data_flow ); +} + +u8 cap_send_comsrv ( MapComSrv_struct * com_ptr, u8 uDelimiterFlag, u8 * data_flow ) +{ + cap_com_stof ( com_ptr, data_flow, uDelimiterFlag ); + return cap_send_comdata ( data_flow ); +} + +void wxc2_trace_xapp(u32 did) +{ + if (did >= (xap_vm_ptr->grantdid)) + return; + xap_vm_ptr->debug_data.monitor_did = did; +} + +/******AIN*********/ +int ain_reg_ssn ( u8 ssn ) +{ + u8 ii, jj; + + ii = xap_inter_ptr->regssn_len; + if( ii >= MAX_XAP_SSN ) + { + xap_send_error ( "Can not register ssn in xap provider" ); + return -1; + } + for ( jj = 0; jj < ii; jj++ ) + { + if( xap_inter_ptr->reg_ssn[jj] == ssn ) + { + xap_send_error ( "ssn has registered in xap provider" ); + return -1; + } + } + xap_inter_ptr->reg_ssn[ii] = ssn; + xap_inter_ptr->regssn_flag[ii] = XAP_AIN_SSN; + xap_inter_ptr->regssn_len++; + return itcap_reg_ssn ( ssn ); +} + +u32 ain_get_dialogueid ( u8 ssn ) +{ + u32 did; + + if( ( did = assign_did ( ) ) == 0 ) + { + xap_send_error ( "Fail to get did(AIN)" ); + return 0; + } + xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_AIN_SSN; + xap_watch_dog(100); + return did; +} + +u8 ain_get_invokeid ( u32 did ) +{ + return assign_iid ( did ); +} + +int ain_send_oprsrv( MapOprSrv_struct *srv_ptr, u8 DelimiterFlag, u8 *data_flow ) +{ + u32 len; + u8 buf[4096]; + MapOprData_struct data_ptr; + + data_ptr.port_id = srv_ptr->port_id; + data_ptr.dialogue_id = srv_ptr->dialogue_id; + data_ptr.invoke_id = srv_ptr->invoke_id; + data_ptr.message_type = srv_ptr->message_type; + data_ptr.message_flag = srv_ptr->message_flag; + data_ptr.param_flag = 0x1f; + len = build_mapparam ( srv_ptr, buf ); + //printf ( "map_send_oprsrv: build map param len ; %d \n", len ); + if( len < 0 || len > MAX_MAPPOPR_LEN ) + { + xap_send_error ( "ain_send_oprsrv: build mapparam too long!" ); + return 0; + } + data_ptr.param_len = len; + memcpy ( data_ptr.param, buf, len ); + data_ptr.param_flag |= 0x20; + map_opr_stof ( &data_ptr, data_flow, DelimiterFlag ); + + return map_send_oprdata ( data_flow ); +} + +u8 ain_get_oprdata_struct ( MapOprData_struct *map_opr, u32 did)//get query or response data +{ + return map_get_oprdata_struct(map_opr, did); +} +u8 ain_send_open( MapOpenArgParam *pOpenParam, u8 *uDataFlow)//set sccp address +{ + //BYTE len; + MapComSrv_struct map_com_srv; + MapOpen_Arg *pOpenArg; + + pOpenArg = &map_com_srv.dlg_list.open_arg; + map_com_srv.map_flag = IS41_FLAG; + map_com_srv.message_type = MAP_OPEN; + map_com_srv.message_flag = MAP_REQUEST; + map_com_srv.port_id = pOpenParam->pid; + map_com_srv.dialogue_id = pOpenParam->did; + memcpy ( &pOpenArg->local_add, &pOpenParam->local_add, sizeof ( SCCP_ADDR ) ); + memcpy ( &pOpenArg->peer_add, &pOpenParam->peer_add, sizeof ( SCCP_ADDR ) ); +// pOpenArg->acn_data.acn = pOpenParam->acn; +// pOpenArg->acn_data.acn_ver = map_get_acnver ( &pOpenParam->local_add, pOpenParam->acn ); +// pOpenArg->param_flag = 0x0b; + pOpenArg->param_flag = 0x0a; + xap_watch_dog(60); + if (pOpenParam->uDelimeterFlag != 0) + xap_watch_dog(61); + return map_send_comsrv ( &map_com_srv, pOpenParam->uDelimeterFlag, uDataFlow ); +} +u8 ain_send_close ( u32 pid, u32 did, u8 uCloseReasion ) +{ + return 1; +} +u8 ain_get_open(u8 *data_flow, u8 ssn )//get query command +{ + return 1; +} +/******AIN*********/ diff --git a/plat/xapp/src/xap_interfunc.h b/plat/xapp/src/xap_interfunc.h new file mode 100644 index 0000000..15be860 --- /dev/null +++ b/plat/xapp/src/xap_interfunc.h @@ -0,0 +1,11 @@ +/* XAP interface for map/cap use head file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* --------------------------------------- */ + +#ifndef _XAP_INTER_FUNC +#define _XAP_INTER_FUNC + +void xap_send_error(const char *fmt,...); + +#endif diff --git a/plat/xapp/src/xap_monitor.c b/plat/xapp/src/xap_monitor.c new file mode 100644 index 0000000..05d23e0 --- /dev/null +++ b/plat/xapp/src/xap_monitor.c @@ -0,0 +1,1340 @@ +/* XAP provider monitor c file */ +/* Written by Liu Zhiguo 2003-03-13 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#include "xap_provider.h" +#include "capp/cap_head.h" +#include "../../snmp/src/include/snmp.h" +#include "../../snmp/src/include/macro.h" +#include "conv_prefix.h" + +#define XAP_MAX_PAGE 8 +#define XAP_MAX_LINE 22 +#define XAP_STATE_LINE 20 +#define XAP_MODULE_ID 4 +#define XAP_ID_LEN 15 +#define XAP_TITLE_LEN 16 +#define XAP_LINE_LEN 17 +#define XAP_PAGE_POINT 14 +#define XAP_LINE_POINT 15 + +#define XAP_CONF_FILE "conf/xap_sysparam.conf" +#define XAP_MSCID_CONF_FILE "conf/xap_mscid.conf" + +#define XAP_PREOBJ_LEN 11 +extern void xap_snmp_registration(); +extern int xap_roaming_rules_init(); +void xap_disp_page(u8 page); +void xap_init(); +int readConvPrefixConf(); +void xap_check_save_param(); +extern u8 init_mappconst(); +extern u8 init_cappconst(); +extern int xap_save_roaming_rule(); +extern int xap_roaming_rule_test(char *vlr_number); + +static u8 xap_status = 1; +static u8 *xap_disp_ptr; +static u32 xap_page; +static u8 xap_did[2],xap_next_did[2]; +static u8 xap_ver[] = {1,0,01}; +u32 xap_object_id[] = {1,3,6,1,4,1,1373,2,3,2,5}; +static u32 xap_status_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,1}; +static u32 xap_version_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,2}; +static u32 xap_ascin_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,3}; +static u32 xap_ascout_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,4}; +static u32 xap_page_title[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,5,1}; +static u32 xap_page_line[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,5,2,2}; + +static char opr_type_desc[5][16] = {"??", "Req", "Ind", "Rsp", "Cnf"}; + +static unsigned char xap_save_conv_param_flag = 0, + xap_save_roaming_rule_flag = 0, + xap_save_system_param_flag=0; + +char map_pabort_desc[7][32] = { + "Undefined", + "ProviderMalfunction", + "SupportingReleased", + "ResourceLimitation", + "MaintenanceActivity", + "VersionIncompatibility", + "AbnormalMAPDialogue"}; +char map_uabort_desc[10][32] = { + "Undefined", + "ShortTermProblem", + "LongTermProblem", + "HandoverCancel", + "RadioChannelRelease", + "NetworkPathRelease", + "CallRelease", + "AssociateProcedureFailure", + "TandemDialogueRelease", + "RemoteOperationFailure"}; + +char tcap_pabort_desc[7][64] = { + "unrecognized message tyep", + "unrecognized transaction ID", + "badly formatted transaction portion", + "incorrect transaction portion", + "resource limitation", + "abnormal dialogue", + "no common dialogue"}; + +char tcap_uabort_desc[3][32] = { + "no given reason", + "specific reason", + "ACN not supplied"}; + +u8 xap_get_addstr(char *str,u8 *bcd,u8 bcd_len) +{ // transfer bcd code to string + u8 ii; + + BcdToAscii(str,bcd,bcd_len*2); + for (ii = 0;ii < bcd_len*2;ii ++) + { + if (str[ii] == 'e' || str[ii] == 'E') + break; + } + str[ii] = '\0'; + return ii; +} +/* str size >64 */ +void xap_get_opstr(int flag , int op, char *str) +{ + if( flag == MAP_FLAG ) + { + switch(op) + { + case UpLoc : + strcpy(str , "MAP_UPDATE_LOCATION"); + break; + case CancelLoc: + strcpy(str , "MAP_CANCEL_LOCATION"); + break; + case PurgeMS: + strcpy(str , "MAP_PURGE_MS"); + break; + case SndIdent: + strcpy(str , "MAP_SEND_IDENTIFICATION"); + break; + case PreHo: + strcpy(str , "MAP_PREPARE_HANDOVER"); + break; + case SndEndSig: + strcpy(str , "MAP_SEND_END_SIGNAL"); + break; + case ProcAccSig: + strcpy(str , "MAP_PROCESS_ACCESS_SIGNALLING"); + break; + case FwdAccSig: + strcpy(str , "MAP_FORWARD_ACCESS_SIGNALLING"); + break; + case PreSubsHo: + strcpy(str , "MAP_PREPARE_SUBSEQUENT_HANDOVER"); + break; + case SndAuthInfo: + strcpy(str , "MAP_SEND_AUTHENTICATION_INFO"); + break; + case ChkIMEI: + strcpy(str , "MAP_CHECK_IMEI"); + break; + case InsSubData: + strcpy(str , "MAP_INSERT_SUBSCRIBER_DATA"); + break; + case DelSubData: + strcpy(str , "MAP_DELETE_SUBSCRIBER_DATA"); + break; + case Reset: + strcpy(str , "MAP_RESET"); + break; + case FwdChkSSInd: + strcpy(str , "MAP_FORWARD_CHECK_SS_INDICATION"); + break; + case RestoreData: + strcpy(str , "MAP_RESTORE_DATA"); + break; + case ActvTraceMode: + strcpy(str , "MAP_ACTIVATE_TRACE_MODE"); + break; + case DeactvTraceMode: + strcpy(str , "MAP_DEACTIVATE_TRACE_MODE"); + break; + case SndIMSI: + strcpy(str , "MAP_SEND_IMSI"); + break; + case SndRoutInfo: + strcpy(str , "MAP_SEND_ROUTING_INFORMATION"); + break; + case ProvRoamNum: + strcpy(str , "MAP_PROVIDE_ROAMING_NUMBER"); + break; + case ResumeCH : + strcpy(str , "MAP_RESUME_CALL_HANDLING"); + break; + case ProvSIWFSNum : + strcpy(str , "MAP_Provide_SIWFS_Number"); + break; + case SIWFSSigMdf : + strcpy(str , "MAP_SIWFS_Signalling_Modify"); + break; + case SetRepState : + strcpy(str , "MAP_SET_REPORTING_STATE"); + break; + case StatusRep : + strcpy(str , "MAP_STATUS_REPORT"); + break; + case RmtUserFree : + strcpy(str , "MAP_REMOTE_USER_FREE"); + break; + case RegSS : + strcpy(str , "MAP_REGISTER_SS"); + break; + case EraseSS : + strcpy(str , "MAP_ERASE_SS"); + break; + case ActvSS : + strcpy(str , "MAP_ACTIVATE_SS"); + break; + case DeactvSS : + strcpy(str , "MAP_DEACTIVATE_SS"); + break; + case InterSS : + strcpy(str , "MAP_INTERROGATE_SS"); + break; + case UnstrctSSReq : + strcpy(str , "MAP_UNSTRUCTURED_SS_REQUEST"); + break; + case UnstrctSSNoti : + strcpy(str , "MAP_UNSTRUCTURED_SS_NOTIFY"); + break; + case RegPasswd : + strcpy(str , "MAP_REGISTER_PASSWORD"); + break; + case GetPasswd : + strcpy(str , "MAP_GET_PASSWORD"); + break; + case RegCCEntry : + strcpy(str , "MAP_REGISTER_CC_ENTRY"); + break; + case EraseCCEntry : + strcpy(str , "MAP_ERASE_CC_ENTRY"); + break; + case SndRoutInfoForSM : + strcpy(str , "MAP_SEND_ROUTING_INFO_FOR_SM"); + break; + case FwdSM : + strcpy(str , "MAP_FORWARD_SHORT_MESSAGE"); + break; + //case MOFwdSM : + // strcpy(str , "MAP_MO_FORWARD_SHORT_MESSAGE"); + // break; + //case MTFwdSM : + // strcpy(str , "MAP_MT_FORWARD_SHORT_MESSAGE"); + // break; + case MTFwdSM_v3 : + strcpy(str , "MAP_MT_FORWARD_SHORT_MESSAGE"); + break; + case RptSMDelvStat: + strcpy(str , "MAP_REPORT_SM_DELIVERY_STATUS"); + break; + case InfSC : + strcpy(str , "MAP_INFORM_SERVICE_CENTRE"); + break; + case AlrtSC : + strcpy(str , "MAP_ALERT_SERVICE_CENTRE"); + break; + case RdyForSM : + strcpy(str , "MAP_READY_FOR_SM"); + break; + case ProvSubInfo: + strcpy(str , "MAP_PROVIDE_SUBSCRIBER_LOCATION"); + break; + case AnyTimeInter: + strcpy(str , "MAP_ANY_TIME_INTERROGATION"); + break; + case SSInvNoti: + strcpy(str , "MAP_SS_INVOCATION_NOTIFY"); + break; + case PreGrpCall : + strcpy(str , "MAP_PREPARE_GROUP_CALL"); + break; + case SndGrpCallEndSig : + strcpy(str , "MAP_send group call end signal"); + break; + case ProcGrpCallSig : + strcpy(str , "MAP_process group call signalling"); + break; + case FwdGrpCallSig : + strcpy(str , "forward group call signalling"); + break; + case UpGprsLoc: + strcpy(str , "MAP_update GPRS location"); + break; + case SndRoutInfoForGprs : + strcpy(str , "MAP_SEND_ROUTING_INFO_FOR_GPRS"); + break; + case FailRep : + strcpy(str , "MAP_FAIL_REPORT"); + break; + case NoteMsPresForGprs : + strcpy(str , "MAP_NOTE_MS_PRESENT_FOR_GPRS"); + break; + case SendParam : + strcpy(str , "MAP_SEND_PARAMETERS"); + break; + case NoteSubPrnt: + strcpy(str , "MAP_NOTE_SUBSCRIBER_PRESENT"); + break; + case ProcUnstrctSSData : + strcpy(str , "MAP_PROCESS_UNSTRUCTURED_SS_REQUEST"); + break; + case BeginSubAct: + strcpy(str , "MAP_BEGIN_SUBSRIBER_ACTIVITY"); + break; + case PerformHo: + strcpy(str , "MAP_PERFORM_HANDOVER"); + break; + case PerformSubsHo: + strcpy(str , "MAP_PERFORM_SUBSCRIBERS_HANDOVER"); + break; + case NoteInterHo : + strcpy(str , "MAP_NOTE_INTER_HANDOVER"); + break; + case AlrtSCWithoutRes : + strcpy(str , "MAP_ALERT_SERVICE_CENTRE_WITHOUT_RESULT"); + break; + case TraceSubAct : + strcpy(str , "MAP_TRACE_SUBSRCIBER_ACTIVITY"); + break; + case SecuTrip : + strcpy(str , "MAPH_ SECURITY_TRIPLETS"); + break; + case InterrSubs: + strcpy(str , "MAPH_INTERROGATE_SUBSCRIBER"); + break; + case CreateSubs: + strcpy(str , "MAPH_CREATE_SUBSCRIBER"); + break; + case DelSubs: + strcpy(str , "MAPH_DELETER_SUBSCRIBER"); + break; + case PingAuc : + strcpy(str , "MAPH_HLR_PING_AUC"); + break; + default : + strcpy(str,"MAP_OP_UNKNOWN"); + break; + } + } + else if( flag == CAP_FLAG ) + { + + switch(op) + { + case CAP_OC_InitialDP: + strcpy(str , "CAP_InitialDP"); + break; + case CAP_OC_AssistRequestInstructions: + strcpy(str , "CAP_AssistRequestInstructions"); + break; + case CAP_OC_EstablishTemporaryConnection: + strcpy(str , "CAP_EstablishTemporaryConnection"); + break; + case CAP_OC_DisconnectForwardConnection: + strcpy(str , "CAP_DisconnectForwardConnection"); + break; + case CAP_OC_ConnectToResource: + strcpy(str , "CAP_ConnectToResource"); + break; + case CAP_OC_Connect: + strcpy(str , "CAP_Connect"); + break; + case CAP_OC_ReleaseCall: + strcpy(str , "CAP_ReleaseCall"); + break; + case CAP_OC_RequestReportBCSMEvent: + strcpy(str , "CAP_RequestReportBCSMEvent"); + break; + case CAP_OC_EventReportBCSM: + strcpy(str , "CAP_EventReportBCSM"); + break; + case CAP_OC_Continue: + strcpy(str , "CAP_Continue"); + break; + case CAP_OC_ResetTimer: + strcpy(str , "CAP_ResetTimer"); + break; + case CAP_OC_FurnishChargingInformation: + strcpy(str , "CAP_FurnishChargingInformation"); + break; + case CAP_OC_ApplyCharging: + strcpy(str , "CAP_ApplyCharging"); + break; + case CAP_OC_ApplyChargingReport: + strcpy(str , "CAP_ApplyChargingReport"); + break; + case CAP_OC_CallInformationReport: + strcpy(str , "CAP_CallInformationReport"); + break; + case CAP_OC_CallInformationRequest: + strcpy(str , "CAP_CallInformationRequest"); + break; + case CAP_OC_SendChargingInformation: + strcpy(str , "CAP_SendChargingInformation"); + break; + case CAP_OC_PlayAnnouncement: + strcpy(str , "CAP_PlayAnnouncement"); + break; + case CAP_OC_PromptAndCollectUserInformation: + strcpy(str , "CAP_PromptAndCollectUserInformation"); + break; + case CAP_OC_SpecializedResourceReport: + strcpy(str , "CAP_SpecializedResourceReport"); + break; + case CAP_OC_Cancel: + strcpy(str , "CAP_Cancel"); + break; + case CAP_OC_ActivityTest: + strcpy(str , "MCAP_OC_ActivityTest"); + break; + case CAP_OC_ApplyWarningTone: + strcpy(str , "CAP_ApplyWarningTone"); + break; + case CAP_OC_CCF_Continue: + strcpy(str , "CAP_CCF_Continue"); + break; + case CAP_OC_InitialDPSMS: + strcpy(str , "CAP_InitialDPSMS"); + break; + case CAP_OC_FurnishChargingInformationSMS: + strcpy(str , "CAP_FurnishChargingInformationSMS"); + break; + case CAP_OC_ConnectSMS: + strcpy(str , "MCAP_OC_ConnectSMS"); + break; + case CAP_OC_RequestReportSMSEvent: + strcpy(str , "CAP_RequestReportSMSEvent"); + break; + case CAP_OC_EventReportSMS: + strcpy(str , "CAP_EventReportSMS"); + break; + case CAP_OC_ContinueSMS: + strcpy(str , "CAP_ContinueSMS"); + break; + case CAP_OC_ReleaseSMS: + strcpy(str , "CAP_ReleaseSMS"); + break; + case CAP_OC_ResetTimerSMS: + strcpy(str , "CAP_ResetTimerSMS"); + break; + default : + strcpy(str,"CAP_OP_UNKNOWN"); + break; + + } + } + + +} + +void xap_read_conf(void) +{ + FILE *fp; + struct stat fileinfo; + + xap_inter_ptr->local_prefix[0] = 0xEE; + xap_inter_ptr->local_prefix[1] = 0xEE; + fp = fopen(XAP_CONF_FILE,"rb"); + if (fp == NULL) + { + printf("can not open file %s!!\n",XAP_CONF_FILE); + return; + } + fread(xap_inter_ptr->mcc,20,1,fp); + + stat(XAP_CONF_FILE,&fileinfo); + if (fileinfo.st_size != 20) + {//old version, mdc is 1 octet long + xap_inter_ptr->mnc[0] = xap_inter_ptr->mnc0; + xap_inter_ptr->mnc[1] = 0xee; + } + if(xap_inter_ptr->establishment_timerestablishment_timer = DLGPEND_TIME; + + fclose(fp); +} + +void xap_read_mscid_conf(void) +{ + FILE *fp; + + fp = fopen(XAP_MSCID_CONF_FILE,"rb"); + if (fp == NULL) + { + printf("can not open file %s!!\n",XAP_MSCID_CONF_FILE); + return; + } + fread(xap_inter_ptr->mscidToNum,3072,1,fp); + + fclose(fp); +} + +void xap_write_conf(void) +{ + FILE *fp; + + fp = fopen(XAP_CONF_FILE,"wb"); + if (fp == NULL) + { + printf("can not open file %s!!\n",XAP_CONF_FILE); + return; + } + fwrite(xap_inter_ptr->mcc,20,1,fp); + fclose(fp); +} + +void xap_write_mscid_conf(void) +{ + FILE *fp; + + fp = fopen(XAP_MSCID_CONF_FILE,"wb"); + if (fp == NULL) + { + printf("can not open file %s!!\n",XAP_MSCID_CONF_FILE); + return; + } + fwrite(xap_inter_ptr->mscidToNum,3072,1,fp); + fclose(fp); +} + + + +#ifdef DEBUG_TEST +void xap_send_ascout(char *asc_str) +{ + StrTrimLeftSpace(asc_str); + if( asc_str[0] == CNULL ) + { + return; + } + //printf("[XAPP]: %s",asc_str); +} +#else +void xap_send_ascout(char *asc_str) +{ + if (xap_vm_ptr->debug_data.send_control == 1) + return; + if ((strlen(asc_str) + strlen((char *)xap_vm_ptr->debug_data.ascout_buf)) > XAP_ASCOUT_LEN/4) // buffer is full + { + xap_vm_ptr->debug_data.send_control = 1; +// strcat(xap_vm_ptr->debug_data.ascout_buf,"\r\n--\r\n"); +// strcpy(xap_vm_ptr->debug_data.ascout_buf,asc_str); + } + else + strcat((char *)xap_vm_ptr->debug_data.ascout_buf, asc_str); +} +#endif + + +void xap_send_error(const char *fmt,...) +{ + va_list ap; + char info[1024]; + + if (xap_vm_ptr->debug_data.error_switch == 0 || xap_vm_ptr->debug_data.send_control == 1) + return; + + xap_send_ascout("\33[31m"); + va_start(ap, fmt); + vsnprintf(info, 1020, fmt, ap); + va_end(ap); + + strcat(info, "\33[37m\r\n"); + xap_send_ascout(info); +} + +void xap_msg_display(u8 *info_str) +{ + int i = 0, j = 0, linemax = 24; + u32 msg_len; + u32 did; + char show_str[2048]; + char name[64]; + + if (xap_vm_ptr->debug_data.send_control == 1) + return; + + did = info_str[6] * 256 + info_str[7]; + + switch(info_str[2]) + { + case MAP_FLAG: + strcpy(name,"MAP"); + if (xap_vm_ptr->debug_data.map_switch == 0 && xap_vm_ptr->debug_data.monitor_did != did) + { + if(xap_vm_ptr->debug_data.error_switch == 0 || + (info_str[9] != MAP_U_ABORT && info_str[9] != MAP_P_ABORT && info_str[9] != MAP_NOTICE)) + return; + } + if (info_str[10] == 1 || info_str[10] == 3) // message type + { + sprintf(show_str, "[%04u]User ==> %s ", did,name); + xap_send_ascout(show_str); + } + else + { + sprintf(show_str, "[%04u]User <== %s ", did,name); + xap_send_ascout(show_str); + } + break; + case IS41_FLAG: + sprintf(name,"IS41"); + if (xap_vm_ptr->debug_data.map_switch == 0 && xap_vm_ptr->debug_data.monitor_did != did) + { + if(xap_vm_ptr->debug_data.error_switch == 0 || + (info_str[9] != MAP_U_ABORT && info_str[9] != MAP_P_ABORT && info_str[9] != MAP_NOTICE)) + return; + } + if (info_str[10] == 1 || info_str[10] == 3) // message type + { + sprintf(show_str, "[%04u]User ==> %s ", did,name); + xap_send_ascout(show_str); + } + else + { + sprintf(show_str, "[%04u]User <== %s ", did,name); + xap_send_ascout(show_str); + } + break; + case CAP_FLAG: + if (xap_vm_ptr->debug_data.cap_switch == 0 && xap_vm_ptr->debug_data.monitor_did != did) + { + if(xap_vm_ptr->debug_data.error_switch == 0 || + (info_str[9] != MAP_U_ABORT && info_str[9] != MAP_P_ABORT && info_str[9] != MAP_NOTICE)) + return; + } + if (info_str[10] == 1 || info_str[10] == 3) // message type + { + sprintf(show_str, "[%04u]User ==> CAP ", did); + xap_send_ascout(show_str); + } + else + { + sprintf(show_str, "[%04u]User <== CAP ", did); + xap_send_ascout(show_str); + } + break; + default: + xap_send_error("[%04u]Invalid User type:0x%02X ", did, info_str[2]); + break; + } + + switch(info_str[9]) + { + case MAP_OPEN: + if( info_str[10] < 3 ) // req or ind + { + sprintf(show_str, "Xap_Open_%s ACN = %d , Version = %d\r\n", opr_type_desc[info_str[10]%5],info_str[11],info_str[12]); + } + else if( info_str[12] == 1 && info_str[13] == 1 && info_str[14] == 2)// req or ind + { + sprintf(show_str, "Xap_Open_%s ACN = %d , Version = %d\r\n", opr_type_desc[info_str[10]%5],info_str[15],info_str[16]); + } + else + { + sprintf(show_str, "Xap_Open_%s \r\n", opr_type_desc[info_str[10]%5]); + } + xap_send_ascout(show_str); + break; + case MAP_CLOSE: + sprintf(show_str, "Xap_Close\tmethod=%d\r\n", info_str[11]); + xap_send_ascout(show_str); + break; + case MAP_U_ABORT: + xap_send_error("Xap_UAbort\tuser reason=%s", map_uabort_desc[info_str[11] % 11]); + break; + case MAP_P_ABORT: + xap_send_error("Xap_PAbort\tprovider reason=%s", map_pabort_desc[info_str[11] & 7]); + break; + case MAP_NOTICE: + xap_send_error("Xap_Notice"); + break; + case MAP_DELIMITER: + sprintf(show_str, "Xap_Delimeter\r\n"); + xap_send_ascout(show_str); + break; + case MAP_LINK: + sprintf(show_str, "Xap_Link\r\n"); + xap_send_ascout(show_str); + break; + default: + xap_get_opstr(info_str[2], info_str[9], name); + sprintf(show_str, "%s Operation-%02X(%s)\tiid=%d\r\n",name, info_str[9], opr_type_desc[info_str[10]%5], info_str[11]); + xap_send_ascout(show_str); + break; + } + + msg_len = info_str[0] * 256 + info_str[1] + 2; + if (msg_len > 300) + { + xap_send_error("Invalid Length:%d", msg_len); + msg_len = 300; + } + + while(i * 24 < msg_len) + { + if((linemax = msg_len - 24 * i) > 24) + linemax = 24; + for(j = 0; j < linemax; j ++) + { + sprintf(show_str + 3 * j, "%02X ", info_str[24 * i + j]); + } + strcat(show_str, "\r\n"); + xap_send_ascout(show_str); + i ++; + } + + xap_send_ascout("\r\n"); + +} + +void xap_dlg_display(struct CSLdlg_struct *dha_ptr) +{ + u8 dlg_flag; + + if (dha_ptr->dialogue_id != xap_vm_ptr->debug_data.monitor_did) + return; + if (dha_ptr->message_flag == REQUEST) + dlg_flag = 2; + else + dlg_flag = 1; +// tcap_disp_dlg(dha_ptr,dlg_flag); +} + +void xap_cmp_display(struct CSLcmp_struct *cha_ptr) +{ + u8 dlg_flag; + + if (cha_ptr->dialogue_id != xap_vm_ptr->debug_data.monitor_did) + return; + if (cha_ptr->message_flag == REQUEST) + dlg_flag = 2; + else + dlg_flag = 1; +// tcap_disp_cmp(cha_ptr,dlg_flag); +} + +int xap_get_response(u8 oidlen,u32 *oid,u8 *pdata,u8 *vartype) +{ + u32 ii; + int data_len = -1; + + ii = XAP_PREOBJ_LEN; + switch(oid[ii]) + { + case 1: //measure + break; + case 2: //configuration + switch(oid[ii+2]) + { + case 1: //MCC + memcpy(pdata,xap_inter_ptr->mcc,2); + data_len = 2; + *vartype = 0x44; + break; + case 2: //MNC + memcpy(pdata,&xap_inter_ptr->mnc,2); + data_len = 2; + *vartype = 0x44; + break; + case 3: //CC + memcpy(pdata,xap_inter_ptr->cc,2); + data_len = 2; + *vartype = 0x44; + break; + case 4: //NDC + memcpy(pdata,xap_inter_ptr->ndc,3); + data_len = 3; + *vartype = 0x44; + break; + case 5: //International Prefix + memcpy(pdata,xap_inter_ptr->inter_prefix,2); + data_len = 2; + *vartype = 0x44; + break; + case 6: //National Prefix + memcpy(pdata,xap_inter_ptr->national_prefix,2); + data_len = 2; + *vartype = 0x44; + break; + case 7: // monitor control flag + memcpy(pdata,xap_inter_ptr->local_prefix,2); + data_len = 2; + *vartype = 0x44; + break; + case 8: + switch(oid[ii+2]) + { + case 1: + return snmpGetConvPrefix(oidlen,oid,pdata,vartype); + break; + case 2: + return snmpGetGroupConvPrefix(oidlen,oid,pdata,vartype); + break; + } + break; + case 9: + return snmpGetCliPrefix(oidlen,oid,pdata,vartype); + break; + case 10: + memcpy(pdata,xap_inter_ptr->mscidToNum[oid[ii+2]],14); + data_len = 14; + *vartype = 4; + break; + break; + case 11: + return snmpGetPlatName(oidlen,oid,pdata,vartype); + break; + default: + break; + } + break; + case 3: //status + if (oid[ii+1] == 1) + { + memcpy(pdata,xap_ver,3); + data_len = 3; + *vartype = 4; + } + break; + default: + break; + } + return data_len; +} + +int xap_set_response(u8 oidlen,u32 *oid,u8 *pdata,u16 datalen) +{ + u32 ii; + + ii = XAP_PREOBJ_LEN; + switch(oid[ii]) + { + case 1: //measure + break; + case 2: //configuration + xap_save_system_param_flag = 1; + switch(oid[ii+2]) + { + case 1: //MCC + if (datalen != 2) + return -1; + memcpy(xap_inter_ptr->mcc,pdata,2); + return 2; + case 2: //MNC + if (datalen < 2) + return -1; + if (datalen == 2) + memcpy(xap_inter_ptr->mnc,pdata,2); + else + { + xap_inter_ptr->mnc[0] = pdata[0]; + xap_inter_ptr->mnc[1] = 0xee; + } + return 2; + case 3: //CC + if (datalen != 2) + return -1; + memcpy(xap_inter_ptr->cc,pdata,2); + return 2; + break; + case 4: //NDC + if (datalen != 3) + return -1; + memcpy(xap_inter_ptr->ndc,pdata,3); + return 3; + break; + case 5: //International Prefix + if (datalen != 2) + return -1; + memcpy(xap_inter_ptr->inter_prefix,pdata,2); + return 2; + break; + case 6: //National Prefix + if (datalen != 2) + return -1; + memcpy(xap_inter_ptr->national_prefix,pdata,2); + return 2; + break; + case 7: // debug flag control + if (datalen != 2) + return -1; + memcpy(xap_inter_ptr->local_prefix,pdata,2); + return 2; + break; + case 8: + switch(oid[ii+2]) + { + case 1: + return snmpSetConvPrefix(oidlen,oid,pdata,datalen); + break; + case 2: + return snmpSetGroupConvPrefix(oidlen,oid,pdata,datalen); + break; + } + break; + case 9: + return snmpSetCliPrefix(oidlen,oid,pdata,datalen); + break; + case 10: + if (datalen != 14) + return -1; + memcpy(xap_inter_ptr->mscidToNum[oid[ii+2]],pdata,14); + return 14; + break; + break; + case 11: + return snmpSetPlatName(oidlen,oid,pdata,datalen); + break; + case 12: + if(pdata[0] == 1) + { + xap_write_conf(); + xap_write_mscid_conf(); + saveConvPrefix(); + } + return 1; + break; + default: + break; + } + break; + case 3: //status + if (oid[ii+1] == 2) // system command + { + if (pdata[0] == 0x01) // save system parameter + { + xap_write_conf(); + xap_write_mscid_conf(); + saveConvPrefix(); + return 1; + } + if ((pdata[0] & 0x02) > 0)//reload parameters and reset + { + xap_init( xap_vm_ptr->grantdid ); + } + } + break; + default: + break; + } + //xap_write_conf(); + return -1; +} + +void xap_init_m(void) +{ + u32 str_len; + char temp_str[1024],info_str[1024]; + char *cur_time; + u8 page,ii; + + debug_set_response(XAP_ID_LEN,xap_status_id,&xap_status,1); // set status id + sprintf(info_str,"V%d.%d.%02d",xap_ver[0],xap_ver[1],xap_ver[2]); + debug_set_response(XAP_ID_LEN,xap_version_id,(BYTE *)info_str,strlen(info_str)); // set module description + debug_set_response(XAP_ID_LEN,xap_ascin_id,xap_vm_ptr->debug_data.ascin_buf,XAP_ASCIN_LEN); + debug_set_response(XAP_ID_LEN,xap_ascout_id,xap_vm_ptr->debug_data.ascout_buf,XAP_ASCOUT_LEN); + + xap_page = 0; + memset(xap_did,0,2); + memset(xap_next_did,0,2); + xap_next_did[1] = 1; + for (page = 1;page < XAP_MAX_PAGE;page ++) + { + switch (page) + { + case 1: // system parameter + sprintf(info_str,"Page %d\t\tXAP system parameter\r\n\nVersion\r\nMCC\r\nMNC\r\nCC\r\nNDC\r\nInter prefix\r\nNational prefix\r\nRegister SSN\r\n",page); + str_len = strlen(info_str); + break; + case 2: // map provider status + sprintf(temp_str,"Dialogue ID\r\nFSM state\r\nACN\r\nTimer\r\nOperation state\r\nOperation code\r\nOperation class\r\n"); + sprintf(info_str,"Page %d\t\tMAP status\r\n\n%s\nNext Dialogue ID status\r\n\n%s",page,temp_str,temp_str); + str_len = strlen(info_str); + break; + case 3: // SCF status + sprintf(temp_str,"Dialogue ID\r\nFSM state\r\nOperation\r\nEDPs\r\nEDP_flag\r\nExpire Times\r\nTimer\r\n"); + sprintf(info_str,"Page %d\t\tSCF status\r\n\n%s\nNext Dialogue ID status\r\n\n%s",page,temp_str,temp_str); + str_len = strlen(info_str); + break; + case 4: // SSF status + sprintf(temp_str,"Dialogue ID\r\nFSM state\r\nRelationship\r\nRequest number\r\nTssf timer\r\nO-BCSM\r\nT-BCSM\r\n"); + sprintf(info_str,"Page %d\t\tSSF status\r\n\n%s\nNext Dialogue ID status\r\n\n%s",page,temp_str,temp_str); + str_len = strlen(info_str); + break; + case 5: // xap watchdog + sprintf(info_str,"Page %d\t\tWatch dog\r\n\n",page); + for (ii = 0;ii < XAP_MAX_LINE;ii ++) + { + sprintf(temp_str,"%d--%d\r\n",ii*5,ii*5+4); + strcat(info_str,temp_str); + } + str_len = strlen(info_str); + break; + default: + strcpy(info_str,"NONE\r\n"); + str_len = strlen(info_str); + break; + } + xap_page_title[XAP_PAGE_POINT] = page + 5; + debug_set_response(XAP_TITLE_LEN,xap_page_title,(BYTE *)info_str,str_len); + xap_disp_page(page); + } + //inquire_setmsg(XAP_PREOBJ_LEN,xap_object_id,xap_set_response); + //inquire_getmsg(XAP_PREOBJ_LEN,xap_object_id,xap_get_response); + xap_snmp_registration(); + xap_read_conf(); + xap_read_mscid_conf(); + readConvPrefixConf(); + + xap_roaming_rules_init(); + + cur_time = GetAsciiTime(); + xap_vm_ptr->debug_data.start_time = GetAsciiTime(); + sprintf(info_str,"XAP init process completed. Init time is:%s\r",cur_time); + xap_send_ascout(info_str); +} + +u8 xap_disp_line(u8 page,u8 line) +{ + u8 temp_line; + u8 line_len=0; + u32 temp_did; + struct xapp_vm_data *vm_ptr; + + xap_disp_ptr = xap_ver; + switch (page) + { + case 1: // system parameter + switch (line) + { + case 0: // version + xap_disp_ptr = xap_ver; + line_len = 3; + break; + case 1: // MCC + xap_disp_ptr = xap_inter_ptr->mcc; + line_len = 2; + break; + case 2: // MNC + xap_disp_ptr = xap_inter_ptr->mnc; + line_len = 2; + break; + case 3: // CC + xap_disp_ptr = xap_inter_ptr->cc; + line_len = 2; + break; + case 4: // NDC + xap_disp_ptr = xap_inter_ptr->ndc; + line_len = 3; + break; + case 5: // international prefix + xap_disp_ptr = xap_inter_ptr->inter_prefix; + line_len = 2; + break; + case 6: // nationla prefix + xap_disp_ptr = xap_inter_ptr->national_prefix; + line_len = 2; + break; + case 7: // register ssn + xap_disp_ptr = xap_inter_ptr->reg_ssn; + line_len = MAX_XAP_SSN; + break; + default: + break; + } + break; + case 2: // show the map provider state + if (line < 10) + { + temp_did = xap_did[0] * 256 + xap_did[1]; + temp_line = line; + } + else + { + temp_did = (xap_next_did[0] * 256 + xap_next_did[1]) % (xap_vm_ptr->grantdid); + temp_line = line - 10; + } + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did]; + switch (temp_line) + { + case 0: // dialogue id + if (line < 10) + xap_disp_ptr = xap_did; + else + xap_disp_ptr = xap_next_did; + line_len = 2; + break; + case 1: // fsm state + xap_disp_ptr = &vm_ptr->psm_data.psm_state; + line_len = 2; + break; + case 2: // acn + xap_disp_ptr = &vm_ptr->psm_data.acn; + line_len = 2; + break; + case 3: // timer + xap_disp_ptr = (u8 *) &vm_ptr->psm_data.suspend_timer; + line_len = 4; + break; + case 4: // operation state + xap_disp_ptr = vm_ptr->psm_data.opr_state; + line_len = 20; + break; + case 5: // operation code + xap_disp_ptr = vm_ptr->psm_data.opr_code; + line_len = 20; + break; + case 6: // operation class + xap_disp_ptr = vm_ptr->psm_data.opr_class; + line_len = 20; + break; + default: + break; + } + break; + case 3: // show the scf provider state + break; + case 4: // show the ssf provider state + break; + case 5: + xap_disp_ptr = (u8 *) &xap_vm_ptr->debug_data.watch_dog[line*5]; + line_len = 20; + break; + default: + line_len = 0; + break; + } + return line_len; +} + +void xap_disp_page(u8 page) +{ + u8 line; + u8 line_len; + + xap_page_line[XAP_PAGE_POINT] = page + 5; + for (line = 0;line < XAP_MAX_LINE;line ++) + { + line_len = xap_disp_line(page,line); + xap_page_line[XAP_LINE_POINT] = line + 2; + debug_set_response(XAP_LINE_LEN,xap_page_line,xap_disp_ptr,line_len); + } +} + +void xap_monitor(void) +{ + u32 ii; + char info_str[1024],temp_str[1024]; + struct xap_debug_struct *debug_ptr; + int value; + + debug_ptr = (xap_debug_struct *) &xap_vm_ptr->debug_data; + debug_ptr->send_control = 0; + if (strlen((char *)debug_ptr->ascin_buf) > 0) // has command + { + if (strcmp((char *)debug_ptr->ascin_buf+1,"help") == 0) // show help info + { + sprintf(info_str,"Now the monitored module is XAP provider.\r\nVersion is R%dV%02d_%02d and start time is %s\r\n",xap_ver[0],xap_ver[1],xap_ver[2],debug_ptr->start_time); + xap_send_ascout(info_str); + xap_send_ascout("The XAP module command list:\r\n"); + xap_send_ascout("log all ---- Turn on all log items\r\n"); + xap_send_ascout("log none ---- Turn off all log items\r\n"); + xap_send_ascout("log map ---- Turn on the map log item\r\n"); + xap_send_ascout("log cap ---- Turn on the cap log item\r\n"); + xap_send_ascout("log error ---- Turn on the error log item\r\n"); + xap_send_ascout("log port [did] ---- Monitor the appointed dialogue id\r\n"); + xap_send_ascout("list parameter ---- Display the system parameter in XAP provider\r\n"); + xap_send_ascout("reset ---- Reset XAP provider\r\n"); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"clear") == 0) + memset(debug_ptr->watch_dog,0,XAP_WTDOG_LEN*sizeof(u32)); + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log none") == 0) // close all switch + { + debug_ptr->error_switch = 0; + debug_ptr->map_switch = 0; + debug_ptr->cap_switch = 0; + xap_send_ascout("XAP all switch close\n\r"); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log error") == 0)// open error switch + { + debug_ptr->error_switch = 1; + xap_send_ascout("XAP error switch open\n\r"); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log map") == 0)// open to map switch + { + debug_ptr->map_switch = 1; + xap_send_ascout("XAP monitor map switch open\n\r"); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log cap") == 0)// open to map switch + { + debug_ptr->cap_switch = 1; + xap_send_ascout("XAP monitor cap switch open\n\r"); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"log all") == 0)// open all switch + { + debug_ptr->error_switch = 1; + debug_ptr->map_switch = 1; + debug_ptr->cap_switch = 1; + xap_send_ascout("XAP all switch open\n\r"); + } + else if (strncmp((char *)debug_ptr->ascin_buf+1,"did ",4) == 0) // change section page + { + ii = atol((char *)debug_ptr->ascin_buf+5) % (xap_vm_ptr->grantdid); + xap_did[0] = ii >> 8; + xap_did[1] = ii & 0xff; + xap_next_did[0] = (ii+1) >> 8; + xap_next_did[1] = (ii+1) & 0xff; + } + else if (strncmp((char *)debug_ptr->ascin_buf+1,"log port ",9) == 0) // monitor the did + { + ii = atol((char *)debug_ptr->ascin_buf+10); + if (ii >= (xap_vm_ptr->grantdid)) + xap_send_ascout("The appointed dialogue id is not expected\r\n"); + else + debug_ptr->monitor_did = ii; + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"list parameter") == 0) // diaplay system parameter + { + xap_get_addstr(temp_str,xap_inter_ptr->mcc,2); + sprintf(info_str,"The XAP provider system parameter is:\r\nMCC(Mobile Country Code): %s\r\n",temp_str); + xap_send_ascout(info_str); + xap_get_addstr(temp_str,xap_inter_ptr->mnc,2); + sprintf(info_str,"MNC(Mobile Network Code): %s\r\n",temp_str); + xap_send_ascout(info_str); + xap_get_addstr(temp_str,xap_inter_ptr->cc,2); + sprintf(info_str,"CC(Country Code): %s\r\n",temp_str); + xap_send_ascout(info_str); + xap_get_addstr(temp_str,xap_inter_ptr->ndc,3); + sprintf(info_str,"NDC(National Destination Code): %s\r\n",temp_str); + xap_send_ascout(info_str); + xap_get_addstr(temp_str,xap_inter_ptr->inter_prefix,2); + sprintf(info_str,"International prefix: %s\r\n",temp_str); + xap_send_ascout(info_str); + xap_get_addstr(temp_str,xap_inter_ptr->national_prefix,2); + sprintf(info_str,"National prefix: %s\r\n",temp_str); + xap_send_ascout(info_str); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"reset") == 0) // diaplay system parameter + { + //xap_init( xap_vm_ptr->grantdid ); + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"reload acn") == 0) // diaplay system parameter + { + init_mappconst(); + init_cappconst(); + } + else if (strncasecmp((char *)debug_ptr->ascin_buf+1,"set timer=", 10) == 0) // set establishment timer + { + int ivalue; + + ivalue = atoi((char *)debug_ptr->ascin_buf+1+10); + if(ivalue>=180 && ivalue<=36000) + { + xap_inter_ptr->establishment_timer = ivalue; + xap_write_conf(); + sprintf(info_str,"set XAP establishment timer=%d, save it!\r\n", ivalue); + xap_send_ascout(info_str); + } + else + { + sprintf(info_str,"Invalid timer value, the XAP establishment timer should be 180-36000\r\n"); + xap_send_ascout(info_str); + } + } + else if (strcmp((char *)debug_ptr->ascin_buf+1,"est timer?") == 0) // diaplay system parameter + { + sprintf(info_str,"XAP establishment timer=%d\r\n",xap_inter_ptr->establishment_timer); + xap_send_ascout(info_str); + } + else if (strncasecmp((char *)debug_ptr->ascin_buf+1,"test rrule ", 11) == 0) + { + value = xap_roaming_rule_test((char *)debug_ptr->ascin_buf+12); + if(value < 0) + sprintf(info_str,"rule NOT found for the vlr %s \r\n",debug_ptr->ascin_buf+12); + else + sprintf(info_str,"rule found for the vlr %s index=%d\r\n",debug_ptr->ascin_buf+12, value); + xap_send_ascout(info_str); + } + + debug_ptr->ascin_buf[0] = '\0'; + } +/* for (ii = 1;ii < XAP_MAX_PAGE;ii ++) + xap_disp_page(ii);*/ + xap_check_save_param(); +} + +void xap_watch_dog(u32 wd_site) +{ + if (wd_site > XAP_WTDOG_LEN) + return; + xap_vm_ptr->debug_data.watch_dog[wd_site] ++; +} + +void xap_logdebug(const char *fmt,...) +{ + va_list ap; + char info[1024]; + + va_start(ap, fmt); + vsnprintf(info, 1020, fmt, ap); + va_end(ap); + + return xap_send_ascout(info); +} + +void xap_set_conv_param_flag() +{ + xap_save_conv_param_flag = 1; +} + +void xap_set_roaming_rule_flag() +{ + xap_save_roaming_rule_flag = 1; +} + +void xap_check_save_param() +{ + static int xap_check_param_counter = 0; + + if(xap_check_param_counter++%100==0)//10 senconds + { + if(xap_save_conv_param_flag ) + { + saveConvPrefix(); + xap_save_conv_param_flag = 0; + } + if(xap_save_system_param_flag) + { + xap_save_system_param_flag = 0; + xap_write_conf(); + } + if(xap_save_roaming_rule_flag) + { + xap_save_roaming_rule_flag = 0; + xap_save_roaming_rule(); + } + + } +} + +int xap_get_est_timer() +{ + if(xap_inter_ptr->establishment_timer>=DLGPEND_TIME) + return xap_inter_ptr->establishment_timer; + else + return DLGPEND_TIME; +} + diff --git a/plat/xapp/src/xap_monitor.h b/plat/xapp/src/xap_monitor.h new file mode 100644 index 0000000..7d53908 --- /dev/null +++ b/plat/xapp/src/xap_monitor.h @@ -0,0 +1,19 @@ +/* XAP monitor head file */ +/* Written by Liu Zhiguo 2003-03-13 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#ifndef _XAP_MONITOR +#define _XAP_MONITOR + +void xap_init_m(void); +void xap_monitor(void); + +void xap_send_error(const char *fmt,...); +void xap_msg_display(u8 *info_str); +void xap_dlg_display(struct CSLdlg_struct *dha_ptr); +void xap_cmp_display(struct CSLcmp_struct *cha_ptr); +void xap_watch_dog(u32 wd_site); +void xap_logdebug(const char *fmt,...); + +#endif diff --git a/plat/xapp/src/xap_provider.c b/plat/xapp/src/xap_provider.c new file mode 100644 index 0000000..7f507f9 --- /dev/null +++ b/plat/xapp/src/xap_provider.c @@ -0,0 +1,3496 @@ +/* XAP provider c file */ +/* Written by Liu Zhiguo 2003-03-12 */ +/* Version 1.0 */ +/* -------------------------------- */ +#include "xap_provider.h" +#include "xap_monitor.h" +#include "../../tcap/src/include/itcap.h" +#include "../../tcap/src/include/idmanage.h" + +struct xap_acn_info map_acn_buf; +struct xap_acn_info cap_acn_buf; +struct xap_opr_info map_opr_buf; +struct xap_opr_info cap_opr_buf; +struct xap_opr_info is41_opr_buf; + +extern int GetACNInfo ( SCCP_ADDR * pAddr, BYTE ** pAcnInfo ); +extern u8 SendTcapCmp(struct CSLcmp_struct *cha_ptr); +extern u8 RecvTcapCmp(struct CSLcmp_struct *cha_ptr,u32 dlg_flag); +extern u8 RecvTcapDlg(struct CSLdlg_struct *dha_ptr,u32 dlg_flag); +extern u8 SendTcapDlg(struct CSLdlg_struct *dha_ptr); + +extern char tcap_pabort_desc[7][64]; +extern char tcap_uabort_desc[3][32]; +/** extern function **/ +extern void is41_init(); +#if _SUPPORT_ANSI +extern u8 map_check_map_flag(u32 did); +#endif +static u8 xap_convert_cap_sms_acn=0; + +u8 init_is41const(void) +{ +#if _SUPPORT_ANSI + FILE *fp,*temp_fp; + char oprfile_name[32]="conf/is41_operation.conf"; + char string[256]; + char temp[256]; + char *ch_ptr; + int ii,jj; +#endif + + is41_init();//init is41 coding + +#if _SUPPORT_ANSI + fp = fopen(oprfile_name,"r"); // read operation code file + if (fp == NULL) + { + xap_send_error("XAPP can not open is41 operation code file %s!!\n",oprfile_name); + return 0; + } + temp_fp = fp; + while(!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"total data length=",18) == 0) // acn total length + { + strcpy(temp,(strchr(string,'=')+1)); + is41_opr_buf.buf_len = atol(temp); + if (is41_opr_buf.buf_len > XAP_OPR_NUM) + { + printf("XAPP is41 opration length is larger than expected"); + is41_opr_buf.buf_len = XAP_OPR_NUM; + return 0; + } + break; + } + } + for (ii = 0;ii < is41_opr_buf.buf_len;ii++) + { + temp_fp = fp; + while (!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"No.",3) == 0) + { + ch_ptr = strchr(string,'.') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,':')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + if (ii != (atol(temp)-1)) // not find data + continue; + ch_ptr = strchr(string,':') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + is41_opr_buf.opr_code[ii] = atol(temp); + ch_ptr = strchr(string,' ') + 1; + jj = strlen(ch_ptr) - strlen(strchr(ch_ptr,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + is41_opr_buf.opr_class[ii] = atol(temp); + ch_ptr = strchr(ch_ptr,' ') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,'\t')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + is41_opr_buf.opr_timer[ii] = atol(temp); + break; + } + } + } + fclose(fp); + +#endif + + return 1; +} + +u8 init_mappconst(void) +{ + FILE *fp,*temp_fp; + char acnfile_name[32]="conf/map_acn.conf"; + char oprfile_name[32]="conf/map_operation.conf"; + char string[256]; + char temp[256]; + char *ch_ptr; + int ii,jj; + + fp = fopen(acnfile_name,"r"); // read acn info + if (fp == NULL) + { + xap_send_error("XAPP can not open ACN file %s!!\n",acnfile_name); + return 0; + } + temp_fp = fp; + while(!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"total data length=",18) == 0) // acn total length + { + strcpy(temp,(strchr(string,'=')+1)); + map_acn_buf.buf_len = atol(temp); + if (map_acn_buf.buf_len > XAP_ACN_NUM) + { + printf("XAPP map acn length is larger than expected!!"); + map_acn_buf.buf_len = XAP_ACN_NUM; + return 0; + } + break; + } + } + for (ii = 0;ii < map_acn_buf.buf_len;ii++) + { + temp_fp = fp; + while (!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"No.",3) == 0) + { + ch_ptr = strchr(string,'.') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,':')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + if (ii != (atol(temp)-1)) // not find data + continue; + ch_ptr = strchr(string,':') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + map_acn_buf.acn[ii] = atol(temp); + ch_ptr = strchr(string,' ') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,'\t')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + map_acn_buf.acn_ver[ii] = atol(temp); + break; + } + } + } + fclose(fp); + + fp = fopen(oprfile_name,"r"); // read operation code file + if (fp == NULL) + { + xap_send_error("XAPP can not open map operation code file %s!!\n",oprfile_name); + return 0; + } + temp_fp = fp; + while(!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"total data length=",18) == 0) // acn total length + { + strcpy(temp,(strchr(string,'=')+1)); + map_opr_buf.buf_len = atol(temp); + if (map_opr_buf.buf_len > XAP_OPR_NUM) + { + printf("XAPP map opration length is larger than expected"); + map_opr_buf.buf_len = XAP_OPR_NUM; + return 0; + } + break; + } + } + for (ii = 0;ii < map_opr_buf.buf_len;ii++) + { + temp_fp = fp; + while (!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"No.",3) == 0) + { + ch_ptr = strchr(string,'.') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,':')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + if (ii != (atol(temp)-1)) // not find data + continue; + ch_ptr = strchr(string,':') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + map_opr_buf.opr_code[ii] = atol(temp); + ch_ptr = strchr(string,' ') + 1; + jj = strlen(ch_ptr) - strlen(strchr(ch_ptr,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + map_opr_buf.opr_class[ii] = atol(temp); + ch_ptr = strchr(ch_ptr,' ') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,'\t')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + map_opr_buf.opr_timer[ii] = atol(temp); + break; + } + } + } + fclose(fp); + + return 1; +} + +u8 init_cappconst(void) +{ + FILE *fp,*temp_fp; + char acnfile_name[32]="conf/cap_acn.conf"; + char oprfile_name[32]="conf/cap_operation.conf"; + char string[256]; + char temp[256]; + char *ch_ptr; + int ii,jj; + char info_str[1024]; + + xap_convert_cap_sms_acn = 0; + fp = fopen(acnfile_name,"r"); // read acn info + if (fp == NULL) + { + sprintf(info_str,"XAPP can not open ACN file %s!!\n",acnfile_name); + xap_send_error(info_str); + printf("%s",info_str); + return 0; + } + temp_fp = fp; + while(!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"total data length=",18) == 0) // acn total length + { + strcpy(temp,(strchr(string,'=')+1)); + cap_acn_buf.buf_len = atol(temp); + if (cap_acn_buf.buf_len > XAP_ACN_NUM) + { + printf("XAPP cap acn length is larger than expected!!"); + cap_acn_buf.buf_len = XAP_ACN_NUM; + return 0; + } + break; + } + else if(strncasecmp(string,"convert cap sms acn=yes",23)==0) + { + xap_convert_cap_sms_acn=1; + } + } + for (ii = 0;ii < cap_acn_buf.buf_len;ii++) + { + temp_fp = fp; + while (!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"No.",3) == 0) + { + ch_ptr = strchr(string,'.') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,':')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + if (ii != (atol(temp)-1)) // not find data + continue; + ch_ptr = strchr(string,':') + 1; + if(ch_ptr == NULL) continue; + jj = strlen(ch_ptr) - strlen(strchr(string,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + cap_acn_buf.acn[ii] = atol(temp); + ch_ptr = strchr(string,' ') + 1; + if(ch_ptr == NULL) continue; + jj = strlen(ch_ptr) - strlen(strchr(string,'\t')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + cap_acn_buf.acn_ver[ii] = atol(temp); + break; + } + } + } + fclose(fp); + + fp = fopen(oprfile_name,"r"); // read operation code file + if (fp == NULL) + { + xap_send_error("XAPP can not open operation code file %s!!\n",oprfile_name); + return 0; + } + temp_fp = fp; + while(!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"total data length=",18) == 0) // acn total length + { + strcpy(temp,(strchr(string,'=')+1)); + cap_opr_buf.buf_len = atol(temp); + if (cap_opr_buf.buf_len > XAP_OPR_NUM) + { + printf("XAPP cap opration length is larger than expected"); + cap_opr_buf.buf_len = XAP_OPR_NUM; + return 0; + } + break; + } + } + for (ii = 0;ii < cap_opr_buf.buf_len;ii++) + { + temp_fp = fp; + while (!feof(temp_fp)) + { + fgets(string,250,temp_fp); + if (strncmp(string,"No.",3) == 0) + { + ch_ptr = strchr(string,'.') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,':')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + if (ii != (atol(temp)-1)) // not find data + continue; + ch_ptr = strchr(string,':') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + cap_opr_buf.opr_code[ii] = atol(temp); + ch_ptr = strchr(string,' ') + 1; + jj = strlen(ch_ptr) - strlen(strchr(ch_ptr,' ')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + cap_opr_buf.opr_class[ii] = atol(temp); + ch_ptr = strchr(ch_ptr,' ') + 1; + jj = strlen(ch_ptr) - strlen(strchr(string,'\t')); + strncpy(temp,ch_ptr,jj); + temp[jj] = '\0'; + cap_opr_buf.opr_timer[ii] = atol(temp); + break; + } + } + } + fclose(fp); + return 1; +} + +void xap_init(int didgrant) +{ + int shm_id; + + /* xap virtue machine share memory */ + if ((shm_id = shmget(XAP_VM_KEY+wxc2_get_shm_offset(),sizeof(xap_vm_struct),XAP_VM_PERM|IPC_CREAT)) == -1) + { + printf("can not init xap_vm share memory1\n"); + exit(0); + } + if ((xap_vm_ptr = (xap_vm_struct *)shmat(shm_id,(char *)0,0)) == (xap_vm_struct *) -1) + { + printf("can not init xap_vm share memory2\n"); + exit(0); + } + memset(xap_vm_ptr,0,sizeof(xap_vm_struct)); + xap_vm_ptr->debug_data.ascin_buf[0] = '\0'; + xap_vm_ptr->debug_data.ascout_buf[0] = '\0'; + /* xap interface share memory */ + if ((shm_id = shmget(XAP_INTER_KEY+wxc2_get_shm_offset(),sizeof(xap_inter_struct),XAP_INTER_PERM|IPC_CREAT)) == -1) + { + printf("can not init xap_inter share memory1\n"); + exit(0); + } + if ((xap_inter_ptr = (xap_inter_struct *)shmat(shm_id,(char *)0,0)) == (xap_inter_struct *) -1) + { + printf("can not init xap_inter share memory2\n"); + exit(0); + } + if( didgrant <= 0 || didgrant > MAX_DIALOGUEID) + { + printf( "unexpect tcap did grant number!\r\n"); + exit(0); + } + (xap_vm_ptr->grantdid) = didgrant; + memset(xap_inter_ptr,0,sizeof(xap_inter_struct)); + memset(&map_acn_buf,0,sizeof(xap_acn_info)); + memset(&map_opr_buf,0,sizeof(xap_opr_info)); + memset(&is41_opr_buf,0,sizeof(xap_opr_info)); + if (!init_mappconst()) + xap_send_error("MAP system configure data has problem"); + memset(&cap_acn_buf,0,sizeof(xap_acn_info)); + memset(&cap_opr_buf,0,sizeof(xap_opr_info)); + if (!init_cappconst()) + xap_send_error("CAP system configure data has problem"); + if (!init_is41const()) + xap_send_error("IS41 system configure data has problem"); + xap_init_m(); +} + +void set_mapperr(struct MapOprData_struct *opr_ptr,u8 perr_flag) // set map provider error +{ + opr_ptr->param_flag |= 0x80; + opr_ptr->provider_error = perr_flag; +} + +void set_mapuerr(struct MapOprData_struct *opr_ptr,u8 uerr_flag) // set map user error +{ + opr_ptr->param_flag |= 0x40; + opr_ptr->user_error = uerr_flag; +} + +u8 check_mapuerr(struct MapOprData_struct *opr_ptr,u8 *temp_result) +{ + if (opr_ptr->message_flag != MAP_RESPONSE) + return 0; + if ((opr_ptr->param_flag & 0x40)) + { + *temp_result = opr_ptr->user_error; + return 1; + } + return 0; +} + +void get_mapuabort_reason(MapUAbort_Arg *abrt_ptr,MapDlgUAbort_struct *dlg_ptr) +{ + u32 temp_flag; + + temp_flag = 0x01; + switch (dlg_ptr->choice_flag) + { + case 0: // user specific reason + abrt_ptr->user_reason = ProcedureError; + break; + case 1: // user resource limitation + abrt_ptr->user_reason = ResourceLimite; + break; + case 2: // resource unavailable reason + temp_flag += 0x02; + abrt_ptr->user_reason = ResourceUnavailable; + if (dlg_ptr->choice.resunavi == 0) // short term resource limitation + abrt_ptr->diag_info = ShortTermProblem; + else + abrt_ptr->diag_info = LongTermProblem; + break; + case 3: // application procedure cancellation + temp_flag |= 0x02; + abrt_ptr->user_reason = ApplicationCancel; + switch (dlg_ptr->choice.appproccancel) + { + case 0: + abrt_ptr->diag_info = HandoverCancel; + break; + case 1: + abrt_ptr->diag_info = RadioChannelRelease; + break; + case 2: + abrt_ptr->diag_info = NetworkPathRelease; + break; + case 3: + abrt_ptr->diag_info = CallRelease; + break; + case 4: + abrt_ptr->diag_info = AssociateProcedureFailure; + break; + case 5: + abrt_ptr->diag_info = TandemDialogueRelease; + break; + case 6: + abrt_ptr->diag_info = RemoteOperationFailure; + break; + default: + abrt_ptr->diag_info = RemoteOperationFailure; + break; + } + break; + default: // unknown reason + abrt_ptr->user_reason = ResourceLimite; + break; + } + abrt_ptr->param_flag = temp_flag; +} + +void set_mapuabort_reason(MapDlgUAbort_struct *dlg_ptr,MapUAbort_Arg *abrt_ptr) +{ + switch (abrt_ptr->user_reason) + { + case ProcedureError: + dlg_ptr->choice_flag = 0; + break; + case ResourceLimite: + dlg_ptr->choice_flag = 1; + break; + case ResourceUnavailable: + dlg_ptr->choice_flag = 2; + if (abrt_ptr->diag_info == ShortTermProblem) + dlg_ptr->choice.resunavi = 0; + else + dlg_ptr->choice.resunavi = 1; + break; + case ApplicationCancel: + dlg_ptr->choice_flag = 3; + switch (abrt_ptr->diag_info) + { + case HandoverCancel: + dlg_ptr->choice.appproccancel = 0; + break; + case RadioChannelRelease: + dlg_ptr->choice.appproccancel = 1; + break; + case NetworkPathRelease: + dlg_ptr->choice.appproccancel = 2; + break; + case CallRelease: + dlg_ptr->choice.appproccancel = 3; + break; + case AssociateProcedureFailure: + dlg_ptr->choice.appproccancel = 4; + break; + case TandemDialogueRelease: + dlg_ptr->choice.appproccancel = 5; + break; + case RemoteOperationFailure: + dlg_ptr->choice.appproccancel = 6; + break; + default: + dlg_ptr->choice.appproccancel = 6; + break; + } + break; + default: + dlg_ptr->choice_flag = 1; + break; + } +} + +u8 get_mappabort_reason(struct TCPAbort_struct *dlg_ptr,u32 did) +{ + u8 reason=0; + +#if _SUPPORT_ANSI + if (map_check_map_flag(did))//map or cap + { +#endif + switch (dlg_ptr->pabort_reason) + { + case P_Abort_UMT: + reason = ProviderMalfunction; + break; + case P_Abort_UTID: + reason = SupportingReleased; + break; + case P_Abort_BFTP: + reason = ProviderMalfunction; + break; + case P_Abort_RL: + reason = ResourceLimitation; + break; + case P_Abort_ADLG: + reason = ProviderMalfunction; + break; + case P_Abort_NCDP: + reason = VersionIncompatibility; + break; + default: + reason = ProviderMalfunction; + break; + } +#if _SUPPORT_ANSI + } +#endif + +#if _SUPPORT_ANSI + else//is41 + { + switch (dlg_ptr->pabort_reason) + { + case P_Abort_UMT_Ansi: + reason = ProviderMalfunction; + break; + case P_Abort_UTID_Ansi: + reason = SupportingReleased; + break; + case P_Abort_BFTP_Ansi: + reason = ProviderMalfunction; + break; + case P_Abort_RL_Ansi: + reason = ResourceLimitation; + break; + default: + reason = ProviderMalfunction; + break; + } + } +#endif + return reason; +} + +u8 get_xapacn(struct psmvm_data *psm_ptr,struct dlgport_struct *dlg_ptr) +{ +/* daniel */ + switch (psm_ptr->xap_flag) + { + case XAP_MAP_SSN: + if (dlg_ptr->acn_len==0) + { + psm_ptr->acn = 0; + psm_ptr->acn_ver = AC_Version1; + return 1; + } + break; + case XAP_CAP_SSN: + if (dlg_ptr->acn_len==0) + { + psm_ptr->acn = 0; + psm_ptr->acn_ver = 0; + return 1; + } + break; +#if _SUPPORT_ANSI + case XAP_IS41_SSN: + psm_ptr->acn = 0; + psm_ptr->acn_ver = 0; + return 1; +#endif + default://XAP_CAP_SSN or XAP_IS41_SSN + psm_ptr->acn = 0; + psm_ptr->acn_ver = 0; + return 1; + break; + } +/* daniel */ + + +/* daniel + if (dlg_ptr->acn_len==0 && psm_ptr->xap_flag!=XAP_CAP_SSN) + { + psm_ptr->acn = 0; + psm_ptr->acn_ver = AC_Version1; + return 1; + } + daniel */ + + if (dlg_ptr->acn_len != XAP_ACN_LEN) + { + xap_send_error("MAPP receive error length ACN"); + return 0; + } + psm_ptr->acn = dlg_ptr->acn[XAP_ACN_LEN-2]; + psm_ptr->acn_ver = dlg_ptr->acn[XAP_ACN_LEN-1]; + if(psm_ptr->acn == 3 && psm_ptr->acn_ver == 61) + { + psm_ptr->acn = 50; + psm_ptr->acn_ver = 2; + } + + return 1; +} + +void set_xapacn(struct dlgport_struct *dlg_ptr,struct psmvm_data *psm_ptr) +{ + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) + { + dlg_ptr->acn_len = XAP_ACN_LEN; + dlg_ptr->acn[0] = Identified_Organization; + dlg_ptr->acn[1] = ETSI; + dlg_ptr->acn[2] = MobileDomain; + dlg_ptr->acn[3] = GSM_Network; + dlg_ptr->acn[4] = AC_ID; + dlg_ptr->acn[5] = psm_ptr->acn; + dlg_ptr->acn[6] = psm_ptr->acn_ver; + if(xap_convert_cap_sms_acn == 1 && + psm_ptr->acn == 50 && psm_ptr->acn_ver==2) + { + dlg_ptr->acn[4] = 21; + dlg_ptr->acn[5] = 3; + dlg_ptr->acn[6] = 61; + } + + } + else + {//IS41 do not has acn + dlg_ptr->acn_len = 0; +#if _SUPPORT_ANSI + dlg_ptr->confidential_info_len = 0; + dlg_ptr->security_context_len = 0; +#endif + dlg_ptr->user_info_len = 0; + } +} + +u8 get_xapacn_ver(u8 acn,u8 xap_flag) +{ + u32 ii; + + switch (xap_flag) + { + case XAP_MAP_SSN: + for (ii = 0;ii < map_acn_buf.buf_len;ii ++) + { + if (map_acn_buf.acn[ii] == acn) + return map_acn_buf.acn_ver[ii]; + } + break; +#if _SUPPORT_ANSI + case XAP_IS41_SSN: + case XAP_AIN_SSN: + return 1; +#endif + case XAP_CAP_SSN: + //printf("buflen=%d %d\n",cap_acn_buf.buf_len,cap_acn_buf.acn[0]); + for (ii = 0;ii < cap_acn_buf.buf_len;ii ++) + { + if (cap_acn_buf.acn[ii] == acn) + return cap_acn_buf.acn_ver[ii]; + } + break; + + default: + break; + } + return 0; +} + +u8 check_acname(u8 acn,u8 acn_ver,u8 xap_flag) // check if the AC is supported +{ + u8 temp_ver; + +/* daniel */ + switch (xap_flag) + { + case XAP_MAP_SSN: + if (acn_ver==AC_Version1) + { + return 0; + } + break; +#if _SUPPORT_ANSI + case XAP_IS41_SSN: + case XAP_AIN_SSN: + return 0; +#endif + case XAP_CAP_SSN: + if (acn_ver==0) + { + return 0; + } + break; + default: + if (acn_ver==AC_Version1 && acn==0) + return 0; + break; + } +/* daniel */ + +/* daniel + if (xap_flag!=XAP_CAP_SSN && acn_ver==AC_Version1 && acn==0) + return 0; + daniel */ + + temp_ver = get_xapacn_ver(acn,xap_flag); + if (temp_ver == 0 && xap_flag != XAP_CAP_SSN) + { + xap_send_error("XAP check unknown ACN :%d,%d",acn,acn_ver); + return 1; + } + if (temp_ver >= acn_ver) + return 0; + else + return 2; +} + +u8 cmp_acname(psmvm_data *psm_ptr,dlgport_struct *dlg_ptr) // compare is AC is changed +{ +#if _SUPPORT_ANSI + if (psm_ptr->xap_flag == XAP_IS41_SSN ||psm_ptr->xap_flag == XAP_AIN_SSN) + return 1; +#endif + + if (psm_ptr->xap_flag == XAP_MAP_SSN) + { + if (psm_ptr->acn_ver == AC_Version1) + return 1; + } + + else if (psm_ptr->xap_flag == XAP_CAP_SSN) + { + if (psm_ptr->acn_ver == 0) + {//cap version 1 + return 1; + } + } + if(dlg_ptr->acn[XAP_ACN_LEN-2] == 3 && + dlg_ptr->acn[XAP_ACN_LEN-1] == 61) + { + dlg_ptr->acn[XAP_ACN_LEN-1] = 2; + dlg_ptr->acn[XAP_ACN_LEN-2] = 50; + } + + if (dlg_ptr->acn_len != XAP_ACN_LEN) + return 0; + if (dlg_ptr->acn[XAP_ACN_LEN-1] != psm_ptr->acn_ver) + return 0; + if (dlg_ptr->acn[XAP_ACN_LEN-2] != psm_ptr->acn) + return 0; + return 1; +} + +u8 map_get_acnver(SCCP_ADDR *sccp_ptr,u8 acn) +{ + int ii; + u8 *acn_ptr; + + if (GetACNInfo(sccp_ptr,&acn_ptr)<=0) + return 2; // default version is 2 +// return 3; + for (ii = 0;ii < map_acn_buf.buf_len;ii ++) + { + if (map_acn_buf.acn[ii] == acn) + return acn_ptr[ii]; + } + return 2;//default version is 2 +// return 3; +} + +u8 map_set_acnver(SCCP_ADDR *sccp_ptr,u8 acn,u8 acn_ver) +{ // empty, need to fill later + return 0; +} + + +u8 find_oprclass(u8 opr_code,u8 xap_flag) // check operation code and find operation class +{ + u32 ii; + + switch (xap_flag) + { + case XAP_MAP_SSN: + for (ii = 0;ii < map_opr_buf.buf_len;ii++) + { + if (map_opr_buf.opr_code[ii] == opr_code) + return map_opr_buf.opr_class[ii]; // return operation class + } + xap_send_error("MAPP find unknown operation code:%d",opr_code); + break; +#if _SUPPORT_ANSI + case XAP_IS41_SSN: + for (ii = 0;ii < is41_opr_buf.buf_len;ii++) + { + if (is41_opr_buf.opr_code[ii] == opr_code) + return is41_opr_buf.opr_class[ii]; // return operation class + } + xap_send_error("IS41 find unknown operation code:%d",opr_code); + break; + case XAP_AIN_SSN: + return 4;// not need wait response + break; +#endif + case XAP_CAP_SSN: + for (ii = 0;ii < cap_opr_buf.buf_len;ii++) + { + if (cap_opr_buf.opr_code[ii] == opr_code) + return cap_opr_buf.opr_class[ii]; // return operation class + } + xap_send_error("CAPP find unknown operation code:%d, buf_len = %d", opr_code, cap_opr_buf.buf_len); + break; + default: + break; + } + + xap_send_error("XAPP can't find operation code: xap_flag=%d", xap_flag); + return 0; // can not find operation +} + +u32 find_oprtimer(u8 opr_code,u8 xap_flag) // find opreation timer +{ + u32 ii; + + switch (xap_flag) + { + case XAP_MAP_SSN: + for (ii = 0;ii < map_opr_buf.buf_len;ii++) + { + if (map_opr_buf.opr_code[ii] == opr_code) + return map_opr_buf.opr_timer[ii]; // return operation class + } + break; +#if _SUPPORT_ANSI + case XAP_IS41_SSN: + for (ii = 0;ii < is41_opr_buf.buf_len;ii++) + { + if (is41_opr_buf.opr_code[ii] == opr_code) + return is41_opr_buf.opr_timer[ii]; // return operation class + } + break; + case XAP_AIN_SSN: + return 2; +#endif + case XAP_CAP_SSN: + for (ii = 0;ii < cap_opr_buf.buf_len;ii++) + { + if (cap_opr_buf.opr_code[ii] == opr_code) + return cap_opr_buf.opr_timer[ii]; // return operation class + } + break; + default: + break; + } + + xap_send_error("XAP find unknown operation code:%d",opr_code); + return 0; // can not find operation +} + +u8 map_check_lnkid(u8 opr_code) +{ + switch (opr_code) + { + case RegPasswd: + return 1; + break; + default: + break; + } + return 0; +} + +void set_xap_flag(u32 did,u8 ssn) +{ + int ii; + u8 flag=0; + + for (ii = 0;ii < xap_inter_ptr->regssn_len;ii ++) + { + if (xap_inter_ptr->reg_ssn[ii] == ssn) + { + flag = 1; + break; + } + } + if (flag == 0) + { + xap_send_error("Can not find SSN=%d in xap provider",ssn); + return; + } + xap_vm_ptr->xap_data[did].psm_data.xap_flag = xap_inter_ptr->regssn_flag[ii]; +} + +u8 send_SSBeginSubActy(struct MapOpen_Arg *open_ptr , struct MapOprSrv_struct *srv_ptr) +{ + struct MapOprData_struct data_ptr; + struct MapBSA_Arg *bsa; + struct TCInvoke_struct *inv_ptr; + u8 data_flow[MAX_MAPPOPR_LEN]; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct CSLcmp_struct csl_cmp; + + u8 buf[4096]; + int len; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[srv_ptr->dialogue_id]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + bsa = (struct MapBSA_Arg *)&srv_ptr->msg_list.bsa_arg; + bsa->param_flag = 0; + + if (open_ptr->param_flag & 0x04) // has peer ref + { + bsa->param_flag |= 0x01; + if(open_ptr->peerref_len == 9 ) + { + memcpy(bsa->imsi,open_ptr->peer_reference,open_ptr->peerref_len); + } + else + { + xap_send_error("XAPP peer reference lenght err while SS MAP V1"); + return 0; + } + } + + if ((open_ptr->param_flag |= 0x10)) // has local ref + { + bsa->param_flag |= 0x02; + bsa->orgenty_num_len = open_ptr->localref_len; + memcpy(bsa->orgenty_num,open_ptr->local_reference,open_ptr->localref_len); + } + + data_ptr.port_id = srv_ptr->port_id; + data_ptr.dialogue_id = srv_ptr->dialogue_id; + data_ptr.invoke_id = srv_ptr->invoke_id; + data_ptr.message_type = srv_ptr->message_type; + data_ptr.message_flag = srv_ptr->message_flag; + data_ptr.param_flag = 0x1f; + + len = build_mapparam(srv_ptr,buf); + if (len == 0 || len > MAX_MAPPOPR_LEN) + { + return 0; + } + + data_ptr.param_len = len; + memcpy(data_ptr.param,buf,len); + data_ptr.param_flag |= 0x20; + + + map_opr_stof(&data_ptr,data_flow,1); + xap_msg_display(data_flow); + /*if( !map_send_oprdata(data_flow) ) + { + return 0; + } + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[srv_ptr->dialogue_id]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + + psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,1); + vm_ptr->recvopr_flag = 0; + */ + + inv_ptr = (TCInvoke_struct *) &csl_cmp.cmp_prim.tc_invoke; + csl_cmp.message_type = Invoke; + csl_cmp.message_flag = REQUEST; + csl_cmp.dialogue_id = data_ptr.dialogue_id ; + csl_cmp.invoke_id = data_ptr.invoke_id; + inv_ptr->linkedid_flag = 0; + + inv_ptr->operation_code = data_ptr.message_type; + inv_ptr->parameter_len = 0; + if ((data_ptr.param_flag & 0x20)) // has component portion + { + if (data_ptr.param_len > MAX_TCAPSEND_LEN) + { + xap_send_error("XAPP check the operation %d parameter is to long:%ld",data_ptr.message_type,data_ptr.param_len); + } + else + { + inv_ptr->parameter_len = data_ptr.param_len; + memcpy(inv_ptr->parameter,data_ptr.param,data_ptr.param_len); + } + } + if( (open_ptr->param_flag & 0x08) != 0x08 ) + { + xap_send_error("XAPP check the Open param flag do not include local add while SS MAP V1"); + return 0; + } + else + { + set_xap_flag(data_ptr.dialogue_id,open_ptr->local_add.SSN); + inv_ptr->operation_class = find_oprclass(data_ptr.message_type,psm_ptr->xap_flag); + inv_ptr->timer = find_oprtimer(data_ptr.message_type,psm_ptr->xap_flag); + psm_ptr->opr_class[csl_cmp.invoke_id] = inv_ptr->operation_class; + } + + SendTcapCmp(&csl_cmp); + xap_cmp_display(&csl_cmp); + return 1; + +} + +u8 recv_SSBeginSubActy(u32 did , struct CSLcmp_struct *csl_cmp ,struct MapOpen_Arg *open_ptr ) +{ + struct MapBSA_Arg *bsa; + struct MapOprSrv_struct srv_ptr; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + //u8 data_flow[MAX_MAPPOPR_LEN]; + struct TCInvoke_struct *inv_ptr; + struct MapOprData_struct data_ptr; + + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[did]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + if( !RecvTcapCmp(csl_cmp,did) ) + { + return 0; + } + xap_cmp_display(csl_cmp); + + if( csl_cmp->message_type != Invoke || csl_cmp->cmp_prim.tc_invoke.operation_code != BeginSubAct ) + { + return 2; + } + + //performing_ssm(&csl_cmp,SERVICE_INVOCATION_RECEIVED,0); + inv_ptr = (TCInvoke_struct *) &csl_cmp->cmp_prim.tc_invoke; + data_ptr.port_id = psm_ptr->port_id; + data_ptr.dialogue_id = csl_cmp->dialogue_id; + data_ptr.invoke_id = csl_cmp->invoke_id; + data_ptr.message_type = inv_ptr->operation_code; + data_ptr.message_flag = MAP_INDICATE; + data_ptr.param_flag = 0x1f; + data_ptr.param_len = 0; + + if (inv_ptr->parameter_len != 0) + { + data_ptr.param_len = inv_ptr->parameter_len; + memcpy(data_ptr.param,inv_ptr->parameter,inv_ptr->parameter_len); + data_ptr.param_flag |= 0x20; + } + + if( !(data_ptr.param_flag & 0x20)) // has not parameter + return -1; + + extract_mapparam(&srv_ptr, data_ptr.message_type, + data_ptr.message_flag,data_ptr.param_len,data_ptr.param); + + bsa = (struct MapBSA_Arg *)&srv_ptr.msg_list.bsa_arg; + if( bsa->param_flag != 0x03 ) + { + return -1; + } + + open_ptr->param_flag |= 0x04; + open_ptr->localref_len = IMSI_LEN + 1 ; + memcpy(open_ptr->local_reference,bsa->imsi,open_ptr->localref_len); + + open_ptr->param_flag |= 0x10; + open_ptr->peerref_len = bsa->orgenty_num_len ; + memcpy(open_ptr->peer_reference,bsa->orgenty_num,open_ptr->peerref_len); + + return 1; + +} + +u8 xap_store_open(u8 ssn,u32 did) +{ + int ii,jj; + u8 flag=0; + + for (ii = 0;ii < xap_inter_ptr->regssn_len;ii ++) + { + if (xap_inter_ptr->reg_ssn[ii] == ssn) + { + flag = 1; + break; + } + } + if (flag == 0) + { + xap_send_error("Can not find SSN=%d in xap provider",ssn); + return 0; + } + jj = xap_inter_ptr->open_head[ii]; + if (((jj + 1) % XAP_OPEN_LEN) == xap_inter_ptr->open_tail[ii]) + { + xap_send_error("XAP provider open buffer of ssn: %d has full, did: %d", ssn, did); + return 0; + } + xap_inter_ptr->open_did[ii][jj] = did; + xap_inter_ptr->open_head[ii] = (jj + 1) % XAP_OPEN_LEN; + return 1; +} + +int xapp_send_comdata(struct MapComSrv_struct *com_ptr) +{ + struct xapp_vm_data *vm_ptr; + u32 temp_did; + u8 ssn; + + temp_did = com_ptr->dialogue_id; + if (temp_did >= (xap_vm_ptr->grantdid)) + return 0; + if (com_ptr->message_type == MAP_OPEN && com_ptr->message_flag == MAP_INDICATE) + { // store data in open did buffer + xap_watch_dog(3); + ssn = com_ptr->dlg_list.open_arg.local_add.SSN; + if (!xap_store_open(ssn,temp_did)) + return 0; + } + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did]; + if (vm_ptr->sendcom_flag == 1) + return 0; + memcpy(&vm_ptr->sendcom_data,com_ptr,sizeof(MapComSrv_struct)); + vm_ptr->sendcom_flag = 1; + xap_watch_dog(5); + return 1; +} + +void xapp_send_openrefuse(u32 pid,u32 did,u8 reason) +{ + struct MapComSrv_struct map_com; + struct MapOpen_Res *mapo_ptr; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + if (did >= (xap_vm_ptr->grantdid)) + return; + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[did]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_CONFIRM; + map_com.port_id = pid; + map_com.dialogue_id = did; + mapo_ptr = (MapOpen_Res *) &map_com.dlg_list.open_res; + mapo_ptr->result = OpenResultRefuse; + mapo_ptr->refuse_reason = reason; + mapo_ptr->param_flag = 0x18; + if (reason == ACNotSupported) + { + mapo_ptr->acn_data.acn = psm_ptr->acn; + mapo_ptr->acn_data.acn_ver = psm_ptr->acn_ver; + mapo_ptr->param_flag |= 0x01; + } + xapp_send_comdata(&map_com); +} + +void xapp_send_pabort(u32 pid,u32 did,u8 reason,u8 source) +{ + struct MapComSrv_struct map_com; + struct MapPAbort_Arg *mappa_ptr; + + map_com.message_type = MAP_P_ABORT; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = pid; + map_com.dialogue_id = did; + mappa_ptr = (MapPAbort_Arg *) &map_com.dlg_list.pabort_arg; + mappa_ptr->provider_reason = reason; + mappa_ptr->source = source; + mappa_ptr->param_flag = 0x03; + xapp_send_comdata(&map_com); +} + +void xapp_send_notice(u32 pid,u32 did,u8 reason) +{ + struct MapComSrv_struct map_com; + + map_com.message_type = MAP_NOTICE; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = pid; + map_com.dialogue_id = did; + map_com.dlg_list.notice_arg.problem = reason; + map_com.dlg_list.notice_arg.param_flag = 0x01; + xapp_send_comdata(&map_com); +} + +void xapp_send_ureject(u32 did,u8 iid,u8 err_type,u8 err_code,u8 xap_flag) +{ + struct CSLcmp_struct csl_cmp; + +#if _SUPPORT_ANSI + if ((xap_flag == XAP_MAP_SSN) || + (xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = U_Reject; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = U_Reject_Ansi; +#endif + csl_cmp.message_flag = REQUEST; + csl_cmp.dialogue_id = did; + csl_cmp.invoke_id = iid; + csl_cmp.cmp_prim.tc_reject.problem_type = err_type; + csl_cmp.cmp_prim.tc_reject.problem_code = err_code; + SendTcapCmp(&csl_cmp); + xap_cmp_display(&csl_cmp); +} + +void xapp_send_uabort(u32 did,u8 reason,u8 dlg_flag,struct dlgport_struct *dlg_ptr,u8 xap_flag) +{ + struct TCUAbort_struct *uabort_ptr; + struct CSLdlg_struct csl_data; + + uabort_ptr = (TCUAbort_struct *) &csl_data.dlg_prim.tc_uabort; +#if _SUPPORT_ANSI + if ((xap_flag == XAP_MAP_SSN) || + (xap_flag == XAP_CAP_SSN)) +#endif + { + csl_data.message_type = U_Abort; + uabort_ptr->dialogue_flag = dlg_flag; + } +#if _SUPPORT_ANSI + else + { + csl_data.message_type = U_Abort_Ansi; + uabort_ptr->dialogue_flag = 0; + } +#endif + csl_data.message_flag = REQUEST; + csl_data.dialogue_id = did; + + uabort_ptr->uabort_reason = reason; + if (dlg_flag) + memcpy(&uabort_ptr->dlg_data,dlg_ptr,sizeof(dlgport_struct)); + else + uabort_ptr->dlg_data.user_info_len = 0; +#if _SUPPORT_ANSI + uabort_ptr->uabort_info_len = 0; + uabort_ptr->dlg_data.security_context_len = 0; + uabort_ptr->dlg_data.confidential_info_len = 0; +#endif + SendTcapDlg(&csl_data); + xap_dlg_display(&csl_data); +} + +u8 performing_ssm(void *data_ptr,u8 flag,u8 level) +{ // fail, return 0;success, return 1; partial data, return 2 + struct CSLcmp_struct *cmp_ptr=NULL; + struct MapOprData_struct *opr_ptr=NULL; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct TCInvoke_struct *inv_ptr; + struct CSLcmp_struct csl_cmp; + struct TCResult_struct *result_ptr; + u32 temp_did; + u8 temp_iid; + u32 temp_class; + u8 temp_result; + u8 default_len; + int param_len,param_site; +//char info_str[1024]; + + if (level == 1) + default_len = MAX_TCAPSEND_LEN_1; + else + default_len = MAX_TCAPSEND_LEN; + if (flag == SERVICE_INVOCATION_RECEIVED) + { + cmp_ptr = (CSLcmp_struct *) data_ptr; + temp_did = cmp_ptr->dialogue_id; + temp_iid = cmp_ptr->invoke_id; + } + else + { + opr_ptr = (MapOprData_struct *) data_ptr; + temp_did = opr_ptr->dialogue_id; + temp_iid = opr_ptr->invoke_id; + } + if (temp_did >= (xap_vm_ptr->grantdid)) + return 0; + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + switch (psm_ptr->opr_state[temp_iid]) + { + case SSM_IDLE: + if (flag != SERVICE_INVOCATION_RECEIVED) + { + vm_ptr->recvopr_flag = 0; + xap_watch_dog(46); + xap_watch_dog(50); + return 0; + } + temp_class = psm_ptr->opr_class[temp_iid]; + inv_ptr = (TCInvoke_struct *) &cmp_ptr->cmp_prim.tc_invoke; + vm_ptr->sendopr_data.port_id = psm_ptr->port_id; + vm_ptr->sendopr_data.dialogue_id = temp_did; + vm_ptr->sendopr_data.invoke_id = temp_iid; + vm_ptr->sendopr_data.message_type = inv_ptr->operation_code; + vm_ptr->sendopr_data.message_flag = MAP_INDICATE; +#ifdef _SUPPORT_ANSI + if(psm_ptr->xap_flag == XAP_AIN_SSN) + { + vm_ptr->sendopr_data.message_type = inv_ptr->operation_family; + vm_ptr->sendopr_data.message_flag = inv_ptr->operation_code; + } +#endif + vm_ptr->sendopr_data.param_flag = 0x1f; + vm_ptr->sendopr_data.param_len = 0; + if (inv_ptr->parameter_len != 0) + { + vm_ptr->sendopr_data.param_len = inv_ptr->parameter_len; + memcpy(vm_ptr->sendopr_data.param,inv_ptr->parameter,inv_ptr->parameter_len); + vm_ptr->sendopr_data.param_flag |= 0x20; + } + if (inv_ptr->linkedid_flag) + { + vm_ptr->sendopr_data.param_flag |= 0x100; + vm_ptr->sendopr_data.linked_id = inv_ptr->linked_id; + } + vm_ptr->sendopr_flag = 1; + xap_watch_dog(10); + xap_watch_dog(12); + if (temp_class != OPERATION_CLASS4) + psm_ptr->opr_state[temp_iid] = SSM_WFRESPONSE; + break; + case SSM_WFRESPONSE: // wait for response + if (flag == RESPONSE_ISSUED) + { + csl_cmp.message_flag = REQUEST; + csl_cmp.dialogue_id = temp_did; + csl_cmp.invoke_id = temp_iid; + if (check_mapuerr(opr_ptr,&temp_result)) // find the user error + { + if (temp_result == ResLimit) + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = U_Reject; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = U_Reject_Ansi; +#endif + csl_cmp.cmp_prim.tc_reject.problem_type = Invoke_Problem; + csl_cmp.cmp_prim.tc_reject.problem_code = Invoke_Problem_IR; + } + else + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = U_Error; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = U_Error_Ansi; +#endif + csl_cmp.cmp_prim.tc_uerror.error_type = Local_Error_Code; + csl_cmp.cmp_prim.tc_uerror.error_code = temp_result; +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.cmp_prim.tc_uerror.parameter_len = 0; +#if _SUPPORT_ANSI + else + { + param_len = vm_ptr->recvopr_data.param_len; + csl_cmp.cmp_prim.tc_uerror.parameter_len = param_len; + memcpy(csl_cmp.cmp_prim.tc_uerror.parameter,vm_ptr->recvopr_data.param,param_len); + } +#endif + xap_send_error("XAP ==> TCAP User Error. Operation Code=%d, Error Code=%d", psm_ptr->opr_code[temp_iid], Local_Error_Code); + } + vm_ptr->recvopr_flag = 0; + xap_watch_dog(46); + xap_watch_dog(51); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + } + else + { /* +++ the linked request operation is not support +++ */ + result_ptr = (TCResult_struct *) &csl_cmp.cmp_prim.tc_result; + result_ptr->operation_code = psm_ptr->opr_code[temp_iid]; +#if _SUPPORT_ANSI + if (psm_ptr->xap_flag == XAP_IS41_SSN) + { + result_ptr->operation_domain = XAPP_PRIVATE_TCAP; + result_ptr->operation_family = XAPP_OPER_FAMILY; + } + else if(psm_ptr->xap_flag == XAP_AIN_SSN) + { + result_ptr->operation_domain = XAPP_NATIONAL_TCAP; + result_ptr->operation_family = psm_ptr->msg_type; + result_ptr->operation_code = psm_ptr->msg_flag; + } +#endif + result_ptr->parameter_len = 0; + if (vm_ptr->recvopr_flag==2) // send partial data + { + param_site = vm_ptr->recvopr_site; + if (param_site+default_len >= vm_ptr->recvopr_data.param_len) // send result last + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = Result_L; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = Result_L_Ansi; +#endif + result_ptr->parameter_len = vm_ptr->recvopr_data.param_len-param_site; + memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param+param_site,result_ptr->parameter_len); + result_ptr->operation_flag = 1; + vm_ptr->recvopr_site = 0; + vm_ptr->recvopr_flag = 0; // clear the recvopr flag + xap_watch_dog(46); + xap_watch_dog(52); + } + else // send result not last + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = Result_NL; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = Result_NL_Ansi; +#endif + result_ptr->parameter_len = default_len; + memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param+param_site,default_len); + result_ptr->operation_flag = 1; + vm_ptr->recvopr_site += default_len; + } + } + else + { + param_len = vm_ptr->recvopr_data.param_len; + if (param_len <= default_len) // can send in one packet + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = Result_L; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = Result_L_Ansi; +#endif + result_ptr->parameter_len = param_len; + memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param,param_len); + if (param_len == 0) + result_ptr->operation_flag = 0; + else + result_ptr->operation_flag = 1; + vm_ptr->recvopr_flag = 0; + xap_watch_dog(46); + xap_watch_dog(53); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + } + else // long data,need split it + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = Result_NL; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = Result_NL_Ansi; +#endif + result_ptr->parameter_len = default_len; + memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param,default_len); + result_ptr->operation_flag = 1; + vm_ptr->recvopr_site = default_len; + vm_ptr->recvopr_flag = 2; + } + } + } + SendTcapCmp(&csl_cmp); + xap_cmp_display(&csl_cmp); + } + else if (flag == GUARD_TIMER) + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + else if (flag == TERMINATED) + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + default: + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + } + return 1; +} + +u8 requesting_ssm(void *data_ptr,u8 flag,u8 level) +{ + struct CSLcmp_struct *cmp_ptr=NULL; + struct MapOprData_struct *opr_ptr=NULL; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct CSLcmp_struct csl_cmp; + struct TCInvoke_struct *inv_ptr; + struct TCResult_struct *result_ptr; + struct TCReject_struct *rej_ptr; + u32 temp_did; + u8 temp_iid; + int param_len; + u8 default_len; + u8 result=0; + + + + if (flag == SERVICE_INVOKED) + { + opr_ptr = (MapOprData_struct *) data_ptr; + temp_did = opr_ptr->dialogue_id; + temp_iid = opr_ptr->invoke_id; + } + else + { + cmp_ptr = (CSLcmp_struct *) data_ptr; + temp_did = cmp_ptr->dialogue_id; + temp_iid = cmp_ptr->invoke_id; + } + + if (temp_did >= (xap_vm_ptr->grantdid)) + { + xap_send_error("requesting_ssm: temp_did >= grantdid\r\n"); + return 0; + } + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + + if( psm_ptr->acn_ver == 1 ) + default_len = MAX_TCAPSEND_LEN_1; + else if (level == 1) + default_len = MAX_TCAPSEND_LEN_1; + else + default_len = MAX_TCAPSEND_LEN; + + switch (psm_ptr->opr_state[temp_iid]) + { + case SSM_IDLE: + if (flag != SERVICE_INVOKED) + { + xap_send_error("requesting_ssm: flag != INVOKED"); + return 0; + } + inv_ptr = (TCInvoke_struct *) &csl_cmp.cmp_prim.tc_invoke; +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_cmp.message_type = Invoke; +#if _SUPPORT_ANSI + else + csl_cmp.message_type = Invoke_L_Ansi; +#endif + csl_cmp.message_flag = REQUEST; + csl_cmp.dialogue_id = temp_did; + csl_cmp.invoke_id = temp_iid; + inv_ptr->operation_code = opr_ptr->message_type; + + if ((opr_ptr->param_flag & 0x100)) // has linked_id + { + inv_ptr->linkedid_flag = 1; + inv_ptr->linked_id = opr_ptr->linked_id; + } + else + inv_ptr->linkedid_flag = 0; +#if _SUPPORT_ANSI + if (psm_ptr->xap_flag == XAP_IS41_SSN) + { + inv_ptr->operation_domain = XAPP_PRIVATE_TCAP;//0=national,1=private + inv_ptr->operation_family = XAPP_OPER_FAMILY; + } + else if(psm_ptr->xap_flag == XAP_AIN_SSN) + { + inv_ptr->operation_domain = XAPP_NATIONAL_TCAP;//0=national,1=private + inv_ptr->operation_family = opr_ptr->message_type; + inv_ptr->operation_code = opr_ptr->message_flag; + } +#endif + inv_ptr->parameter_len = 0; + if ((opr_ptr->param_flag & 0x20)) // has component portion + { + if (opr_ptr->param_len > default_len) + { + xap_send_error("XAPP check the operation %d parameter is too long:%ld",opr_ptr->message_type,opr_ptr->param_len); + } + else + { + inv_ptr->parameter_len = opr_ptr->param_len; + memcpy(inv_ptr->parameter,opr_ptr->param,opr_ptr->param_len); + } + } + inv_ptr->operation_class = find_oprclass(opr_ptr->message_type,psm_ptr->xap_flag); + inv_ptr->timer = find_oprtimer(opr_ptr->message_type,psm_ptr->xap_flag); + psm_ptr->opr_class[temp_iid] = inv_ptr->operation_class; + if (inv_ptr->operation_class != OPERATION_CLASS4) + { + psm_ptr->opr_state[temp_iid] = SSM_WFCONFIRM; + psm_ptr->opr_code[temp_iid] = opr_ptr->message_type; + } + SendTcapCmp(&csl_cmp); + xap_cmp_display(&csl_cmp); + vm_ptr->recvopr_flag = 0; + xap_watch_dog(46); + xap_watch_dog(54); + break; + case SSM_WFCONFIRM: + switch (flag) + { + case RESULT_RECEIVED: + result_ptr = (TCResult_struct *) &cmp_ptr->cmp_prim.tc_result; + param_len = result_ptr->parameter_len; + if (vm_ptr->sendopr_flag == 2) // has exist partial data + { + if (vm_ptr->sendopr_data.invoke_id == temp_iid) + { + if (param_len+vm_ptr->sendopr_data.param_flag > MAX_MAPPOPR_LEN) + { + xap_send_error("XAPP received result last data is too long"); + xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_MP,psm_ptr->xap_flag); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + return 0; + } + memcpy(vm_ptr->sendopr_data.param+vm_ptr->sendopr_data.param_len,result_ptr->parameter,param_len); + vm_ptr->sendopr_data.param_len += param_len; + vm_ptr->sendopr_data.param_flag |= 0x20; + vm_ptr->sendopr_flag = 1; + xap_watch_dog(10); + xap_watch_dog(13); + } + else + { + xap_send_error("XAPP received result last with wrong iid"); + xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_RRU,psm_ptr->xap_flag); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + return 0; + } + } + else + { + vm_ptr->sendopr_data.port_id = psm_ptr->port_id; + vm_ptr->sendopr_data.dialogue_id = temp_did; + vm_ptr->sendopr_data.invoke_id = temp_iid; + vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid]; + vm_ptr->sendopr_data.message_flag = MAP_CONFIRM; + vm_ptr->sendopr_data.param_flag = 0x1f; + memcpy(vm_ptr->sendopr_data.param,result_ptr->parameter,param_len); + vm_ptr->sendopr_data.param_len = param_len; + if (param_len != 0) + vm_ptr->sendopr_data.param_flag |= 0x20; + vm_ptr->sendopr_flag = 1; + xap_watch_dog(10); + xap_watch_dog(14); + } + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + case PARTIAL_RESULT_RECEIVED: + result_ptr = (TCResult_struct *) &cmp_ptr->cmp_prim.tc_result; + param_len = result_ptr->parameter_len; + if (vm_ptr->sendopr_flag == 0) // has not exist partial data + { + vm_ptr->sendopr_data.port_id = psm_ptr->port_id; + vm_ptr->sendopr_data.dialogue_id = temp_did; + vm_ptr->sendopr_data.invoke_id = temp_iid; + vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid]; + vm_ptr->sendopr_data.message_flag = MAP_CONFIRM; + vm_ptr->sendopr_data.param_flag = 0x1f; + memcpy(vm_ptr->sendopr_data.param,result_ptr->parameter,param_len); + vm_ptr->sendopr_data.param_len = param_len; + if (param_len != 0) + vm_ptr->sendopr_data.param_flag |= 0x20; + vm_ptr->sendopr_flag = 2; + } + else + { + if (vm_ptr->sendopr_data.invoke_id == temp_iid) + { + memcpy(vm_ptr->sendopr_data.param+vm_ptr->sendopr_data.param_len,result_ptr->parameter,param_len); + vm_ptr->sendopr_data.param_len += param_len; + vm_ptr->sendopr_flag = 2; + } + else // the buffer is used by other invoke id + { + xap_send_error("receive partial result with wrong iid"); + xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_RRU,psm_ptr->xap_flag); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + return 0; + } + } + break; + case NEGATIVE_RESULT_RECEIVED: + vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid]; + vm_ptr->sendopr_data.message_flag = MAP_CONFIRM; + vm_ptr->sendopr_data.port_id = psm_ptr->port_id; + vm_ptr->sendopr_data.dialogue_id = temp_did; + vm_ptr->sendopr_data.invoke_id = temp_iid; + vm_ptr->sendopr_data.param_flag = 0x1f; + set_mapuerr(&vm_ptr->sendopr_data,cmp_ptr->cmp_prim.tc_uerror.error_code); // set user error + xap_send_error("XAPP <== TCAP User Error. did=%d, iid=%d, oCode=0x%02X, errCode=%d", temp_did, temp_iid, vm_ptr->sendopr_data.message_type, cmp_ptr->cmp_prim.tc_uerror.error_code); + vm_ptr->sendopr_flag = 1; + xap_watch_dog(10); + xap_watch_dog(15); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + case LINKED_REQUEST_RECEIVED: + break; + case LINKED_SERVICE_INVOKED: + break; + case USER_REJECT_RECEIVED: + rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject; + vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid]; + vm_ptr->sendopr_data.message_flag = MAP_CONFIRM; + vm_ptr->sendopr_data.port_id = psm_ptr->port_id; + vm_ptr->sendopr_data.dialogue_id = temp_did; + vm_ptr->sendopr_data.invoke_id = temp_iid; + vm_ptr->sendopr_data.param_flag = 0x1f; + if (rej_ptr->problem_code == Invoke_Problem_DIID) + result = DupInvokeId; + else if (rej_ptr->problem_code == Invoke_Problem_UO) + result = SrvNotSupport; + else + result = MistypeParam; + set_mapperr(&vm_ptr->sendopr_data,result); // set provider error + xap_send_error("XAPP <== TCAP User Reject. did=%d, iid=%d, oCode=0x%02X, Problem=%d", temp_did, temp_iid, vm_ptr->sendopr_data.message_type, rej_ptr->problem_code); + vm_ptr->sendopr_flag = 1; + xap_watch_dog(10); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + case PROVIDER_REJECT_RECEIVED: + vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid]; + vm_ptr->sendopr_data.message_flag = MAP_CONFIRM; + vm_ptr->sendopr_data.port_id = psm_ptr->port_id; + vm_ptr->sendopr_data.dialogue_id = temp_did; + vm_ptr->sendopr_data.invoke_id = temp_iid; + vm_ptr->sendopr_data.param_flag = 0x1f; + set_mapperr(&vm_ptr->sendopr_data,UnexpResFromPeer); // set provider error + xap_send_error("XAPP <== TCAP Provider Reject. did=%d, iid=%d, oCode=0x%02X", temp_did, temp_iid, vm_ptr->sendopr_data.message_type); + vm_ptr->sendopr_flag = 1; + xap_watch_dog(10); + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + case TIMER_EXPIRY: + switch (psm_ptr->opr_class[temp_iid]) + { + case OPERATION_CLASS1: + case OPERATION_CLASS3: + vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid]; + vm_ptr->sendopr_data.message_flag = MAP_CONFIRM; + vm_ptr->sendopr_data.port_id = psm_ptr->port_id; + vm_ptr->sendopr_data.dialogue_id = temp_did; + vm_ptr->sendopr_data.invoke_id = temp_iid; + vm_ptr->sendopr_data.param_flag = 0x1f; + set_mapperr(&vm_ptr->sendopr_data,UnexpResFromPeer); // set provider error + xap_send_error("XAPP <== TCAP Timer Expired. did=%d, iid=%d, oCode=0x%02X, Class=%d", temp_did, temp_iid, vm_ptr->sendopr_data.message_type, psm_ptr->opr_class[temp_iid]); + vm_ptr->sendopr_flag = 1; + xap_watch_dog(10); + break; + default: + break; + } + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + case TERMINATED: + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + default: + break; + } + break; + default: + psm_ptr->opr_state[temp_iid] = SSM_IDLE; + break; + } + return 1; +} + +u8 process_components(struct CSLcmp_struct *cmp_ptr,u32 proc) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct TCInvoke_struct *inv_ptr; + struct TCReject_struct *rej_ptr; + u32 temp_did; + u8 temp_iid; + u8 result_flag; + + temp_did = cmp_ptr->dialogue_id; + temp_iid = cmp_ptr->invoke_id; + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + switch (cmp_ptr->message_type) + { + case Invoke: +#if _SUPPORT_ANSI + case Invoke_L_Ansi: +#endif + inv_ptr = (TCInvoke_struct *) &cmp_ptr->cmp_prim.tc_invoke; + if (inv_ptr->linkedid_flag == 0) + { + result_flag = find_oprclass(inv_ptr->operation_code,psm_ptr->xap_flag); + if (result_flag == 0) // can not find operation code + { + xap_send_error("process_components: can not find operation code"); + xapp_send_ureject(temp_did,temp_iid,Invoke_Problem,Invoke_Problem_UO,psm_ptr->xap_flag); + } + else + { + psm_ptr->opr_class[temp_iid] = result_flag; // store operation class + psm_ptr->opr_code[temp_iid] = inv_ptr->operation_code; + performing_ssm(cmp_ptr,SERVICE_INVOCATION_RECEIVED,0); + } + } + else + { + if (!check_iid(temp_did,inv_ptr->linked_id)) + { + if (psm_ptr->opr_state[inv_ptr->linked_id] != SSM_IDLE) + { + xap_send_error("receive Invoke with wrong link id"); + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived); + xapp_send_ureject(temp_did,inv_ptr->linked_id,Invoke_Problem,Invoke_Problem_ULID,psm_ptr->xap_flag); + } + } + else + { + if (psm_ptr->opr_class[inv_ptr->linked_id] == OPERATION_CLASS4) + requesting_ssm(cmp_ptr,LINKED_REQUEST_RECEIVED,0); + else + { + requesting_ssm(cmp_ptr,LINKED_SERVICE_INVOKED,0); + result_flag = find_oprclass(inv_ptr->operation_code,psm_ptr->xap_flag); + if (result_flag == 0) // can not find operation code + { + xap_send_error("process_components: can not find operation code 2"); + xapp_send_ureject(temp_did,temp_iid,Invoke_Problem,Invoke_Problem_UO,psm_ptr->xap_flag); + } + else + { + psm_ptr->opr_class[temp_iid] = result_flag; // store operation class + psm_ptr->opr_code[temp_iid] = inv_ptr->operation_code; + performing_ssm(cmp_ptr,SERVICE_INVOCATION_RECEIVED,0); + } + } + } + } + break; + case Result_L: +#if _SUPPORT_ANSI + case Result_L_Ansi: +#endif + if (!check_iid(temp_did,temp_iid)) + { + xap_send_error("received Result_L without correspond Invoke id"); + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived); + xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_UIID,psm_ptr->xap_flag); + } + else + requesting_ssm(cmp_ptr,RESULT_RECEIVED,0); + break; + case Result_NL: +#if _SUPPORT_ANSI + case Result_NL_Ansi: +#endif + if (!check_iid(temp_did,temp_iid)) + { + xap_send_error("received Result_NL without correspond Invoke id"); + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived); + xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_UIID,psm_ptr->xap_flag); + } + else + requesting_ssm(cmp_ptr,PARTIAL_RESULT_RECEIVED,0); + break; + case U_Error: +#if _SUPPORT_ANSI + case U_Error_Ansi: +#endif + if (!check_iid(temp_did,temp_iid)) + { + xap_send_error("received U_Error without correspond Invoke id"); + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived); + xapp_send_ureject(temp_did,temp_iid,Return_Error,Return_Error_UIID,psm_ptr->xap_flag); + } + else + requesting_ssm(cmp_ptr,NEGATIVE_RESULT_RECEIVED,0); + break; + case U_Reject: +#if _SUPPORT_ANSI + case U_Reject_Ansi: +#endif + rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject; + if (rej_ptr->problem_type == Invoke_Problem) + { + if (!check_iid(temp_did,temp_iid)) + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived); + else + requesting_ssm(cmp_ptr,USER_REJECT_RECEIVED,0); + } + else + xapp_send_notice(psm_ptr->port_id,temp_did,ResponseRejected); + break; + case R_Reject: +#if _SUPPORT_ANSI + case R_Reject_Ansi: +#endif + rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject; + if (rej_ptr->problem_type == Invoke_Problem) + { + if (!check_iid(temp_did,temp_iid)) + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived); + else + requesting_ssm(cmp_ptr,PROVIDER_REJECT_RECEIVED,0); // there is not identify with protocol + } + else + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventDetect); + break; + case L_Reject: +#if _SUPPORT_ANSI + case L_Reject_Ansi: +#endif + rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject; + if (rej_ptr->problem_type == Invoke_Problem) + { + if (!check_iid(temp_did,temp_iid)) + xapp_send_notice(psm_ptr->port_id,temp_did,MessageNotDelivered); + else + requesting_ssm(cmp_ptr,PROVIDER_REJECT_RECEIVED,0); + } + else + xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventDetect); + break; + default: + break; + } + if (cmp_ptr->last_flag == 1) + return 1; + return 0; +} + +int include_dialogue(u32 proc) +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + + switch (psm_ptr->xap_flag) + { + case XAP_MAP_SSN: + if (psm_ptr->acn_ver>AC_Version1) + return 1;//map version 2 and map version 3 include dialogue portion + break; + case XAP_CAP_SSN: + //if (psm_ptr->acn_ver>0) + return 1; + break; +#if _SUPPORT_ANSI + case XAP_IS41_SSN: + case XAP_AIN_SSN: + return 1;//is41 do not has dialogue portion +#endif + default: + break; + } + + return 0; +} + + +int wfur_program(u32 proc) // wait for user requests +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct MapOpen_Arg *open_ptr; + struct MapDlg_struct map_dlg; + struct MapDlgOpen_struct *dlg_open; + struct TCBegin_struct *begin_ptr; + struct CSLdlg_struct csl_data; + struct dlgport_struct tcap_dlg; + u8 ss_mapv1_flag=0; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + if (vm_ptr->recvopr_flag != 0 && !(psm_ptr->acn_ver == 1 && psm_ptr->acn == AC_networkFunctionalSs)) // has components + { + psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,0); + vm_ptr->recvopr_flag = 0; + } + else + { + + if (psm_ptr->delimiter_flag == 1) + { + if (vm_ptr->recvcom_data.message_type != MAP_OPEN) // reqeust open a dialogue + { + xap_watch_dog(62); + return -1; + } + + open_ptr = (MapOpen_Arg *) &vm_ptr->recvcom_data.dlg_list.open_arg; + begin_ptr = (TCBegin_struct *) &csl_data.dlg_prim.tc_begin; + +#if _SUPPORT_ANSI + if (psm_ptr->xap_flag == XAP_IS41_SSN ||psm_ptr->xap_flag == XAP_AIN_SSN) + csl_data.message_type = Query_WithPerm_Ansi; + else +#endif + csl_data.message_type = Begin; + begin_ptr->dialogue_flag = include_dialogue(proc); + + csl_data.message_flag = REQUEST; + csl_data.dialogue_id = proc; + + memcpy(&begin_ptr->peer_add,&open_ptr->peer_add,sizeof(SCCP_ADDR)); + memcpy(&begin_ptr->local_add,&open_ptr->local_add,sizeof(SCCP_ADDR)); + + if( psm_ptr->acn_ver == 1 && psm_ptr->acn == AC_networkFunctionalSs ) + { + if ((open_ptr->param_flag & 0x14) == 0x14 ) // has reference + { + begin_ptr->dlg_data.user_info_len = 0; + ss_mapv1_flag = 1; + } + } + else if ((open_ptr->param_flag & 0x4 ) ||(open_ptr->param_flag & 0x10 ) ) // has reference + { + map_dlg.dlg_type = MAPDLG_OPEN; + dlg_open = (MapDlgOpen_struct *) &map_dlg.map_dlg.map_open; + dlg_open->param_flag = 0; + if ((open_ptr->param_flag & 0x04) ) + { + if( open_ptr->peerref_len <= ISDN_LEN+1 ) // has peer ref + { + dlg_open->param_flag |= 0x01; + dlg_open->peer_ref[0] = open_ptr->peerref_len; + memcpy(dlg_open->peer_ref+1,open_ptr->peer_reference,open_ptr->peerref_len); + } + else + { + xap_send_error("dlg open peerref is too long :%d \r\n" , open_ptr->peerref_len ); + } + } + if ((open_ptr->param_flag |= 0x10) ) + { + if( open_ptr->localref_len <= ISDN_LEN+1) // has local ref + { + dlg_open->param_flag |= 0x02; + dlg_open->local_ref[0] = open_ptr->localref_len; + memcpy(dlg_open->local_ref+1,open_ptr->local_reference,open_ptr->localref_len); + } + else + { + xap_send_error("dlg open localref is too long :%d \r\n" , open_ptr->localref_len ); + } + } + + begin_ptr->dlg_data.user_info_len = build_mapdlg(&map_dlg,begin_ptr->dlg_data.user_info); + } + else + begin_ptr->dlg_data.user_info_len = 0; + +#if _SUPPORT_ANSI + begin_ptr->dlg_data.security_context_len = 0; + begin_ptr->dlg_data.confidential_info_len = 0; +#endif + /* ++++ not support the specific information +++ */ + if( ss_mapv1_flag ) + { + struct MapOprSrv_struct srv_ptr; + + srv_ptr.port_id = psm_ptr->port_id; + srv_ptr.dialogue_id = proc; + srv_ptr.invoke_id = map_get_invokeid(proc); + srv_ptr.message_type = BeginSubAct; + srv_ptr.message_flag = MAP_REQUEST; + + begin_ptr->dlg_data.user_info_len = 0; + send_SSBeginSubActy( open_ptr , &srv_ptr); + psm_ptr->data_count++; + if (vm_ptr->recvopr_flag != 0 && (psm_ptr->acn_ver == 1 && psm_ptr->acn == AC_networkFunctionalSs)) // has components + { + psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,0); + vm_ptr->recvopr_flag = 0; + } + } + begin_ptr->component_present = psm_ptr->data_count; + psm_ptr->data_count = 0; + + if( psm_ptr->acn_ver == 1 && psm_ptr->xap_flag != XAP_CAP_SSN) + psm_ptr->acn = 0; + + set_xapacn(&begin_ptr->dlg_data,psm_ptr); + + SendTcapDlg(&csl_data); + xap_watch_dog(4); + xap_dlg_display(&csl_data); + + psm_ptr->delimiter_flag = 0; +// psm_ptr->msg_type = 0; +// psm_ptr->msg_flag = 0; +// vm_ptr->recvcom_flag = 0; + return 1; + } + else if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST) + { + tcap_dlg.acn_len = 0; + map_dlg.dlg_type = MAPDLG_UABORT; + set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg); + tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(30); + return -1; + } + } + return 0; +} + +int wfcbi_program(u32 proc) // wait for check begin indicate +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct CSLdlg_struct *tcap_ptr; + struct TCBegin_struct *begin_ptr; + struct dlgport_struct *dlg_ptr; + struct MapDlg_struct *map_dlg; + struct MapDlgOpen_struct *dlg_open; + struct CSLcmp_struct csl_cmp; + struct MapComSrv_struct map_com; + struct MapOpen_Arg *open_ptr; + struct dlgport_struct tcap_dlg; + u8 result; + u32 temp_flag=0; + u8 mapv1_ss_flag=0; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + tcap_ptr = (CSLdlg_struct *) &vm_ptr->tcap_data; + begin_ptr = (TCBegin_struct *) &tcap_ptr->dlg_prim.tc_begin; + dlg_ptr = (dlgport_struct *) &begin_ptr->dlg_data; + map_dlg = (MapDlg_struct *) &vm_ptr->map_dlg; + switch (psm_ptr->sub_state1) + { + case 0: + if (begin_ptr->dialogue_flag == 0) + dlg_ptr->acn_len = 0; + result = get_xapacn(psm_ptr,dlg_ptr); + if( psm_ptr->acn == 0 && psm_ptr->acn_ver == AC_Version1 && begin_ptr->component_present == 0) + { + map_dlg->dlg_type = MAPDLG_PABORT; + map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xap_send_error("wait for check begin indicate: MAP V1 operation must send TC_Begin with component!\n", psm_ptr->xap_flag, psm_ptr->acn_ver); + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + return -1; + } + + if (result == 0) + { + map_dlg->dlg_type = MAPDLG_PABORT; + map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xap_send_error("wait for check begin indicate: ACN not Supported. xap_flag=%d Version=%d", psm_ptr->xap_flag, psm_ptr->acn_ver); + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + return -1; + } + else + { + if (dlg_ptr->user_info_len != 0) // include user information + { + if ((!extract_mapdlg(map_dlg,dlg_ptr)) || (map_dlg->dlg_type != MAPDLG_OPEN)) + { + map_dlg->dlg_type = MAPDLG_PABORT; + map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info); + +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xap_send_error("wait for check begin indicate: abnormal dialogue"); + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + return -1; + } + else + psm_ptr->sub_state1 = 2; + } + else + { + if (psm_ptr->acn == AC_networkFunctionalSs || psm_ptr->acn == AC_networkUnstructuredSs) + { + map_dlg->dlg_type = MAPDLG_PABORT; + map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xap_send_error("wait for check begin indicate: User information can't be absent in dialogue for AC_networkFunctionalSs"); + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + return -1; + } + else + psm_ptr->sub_state1 = 2; + } + } + break; + case 1: // wait for init data + if (vm_ptr->sendopr_flag == 0) // can receive operation data + { + if (RecvTcapCmp(&csl_cmp,proc)) + {/* +++ do not derive the version 1 of AC +++ */ + xap_send_error("wait for check begin indicate: AC not include 2"); + xap_cmp_display(&csl_cmp); + xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag); + return -1; + } + } + break; + case 2: // wait for load check result1 + open_ptr = (MapOpen_Arg *) &map_com.dlg_list.open_arg; + if( psm_ptr->acn_ver == AC_Version1 && begin_ptr->component_present > 0 ) //check if map v1 SS + { + result = recv_SSBeginSubActy( proc , &csl_cmp, open_ptr ); + switch( result ) + { + case 1: + mapv1_ss_flag = 1; //map v1 ss + break; + case 2: + mapv1_ss_flag = 2; // map v1 not ss + break; + default: + map_dlg->dlg_type = MAPDLG_PABORT; + map_dlg->map_dlg.map_pabort.reason = invalidPDU; // abnormal dialogue + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xap_send_error("MAP V1 SS wait for beginSubActivity fail xap_flag=%d Version=%d", psm_ptr->xap_flag, psm_ptr->acn_ver); + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + return -1; + break; + } + } + + result = check_acname(psm_ptr->acn,psm_ptr->acn_ver,psm_ptr->xap_flag); + if (result==0) // AC is supported + { + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = 0; // need deside by map user + map_com.dialogue_id = proc; + open_ptr = (MapOpen_Arg *) &map_com.dlg_list.open_arg; + open_ptr->acn_data.acn = psm_ptr->acn; + open_ptr->acn_data.acn_ver = psm_ptr->acn_ver; + temp_flag = 0x01; + memcpy(&open_ptr->peer_add,&begin_ptr->peer_add,sizeof(SCCP_ADDR)); + temp_flag |= 0x02; + memcpy(&open_ptr->local_add,&begin_ptr->local_add,sizeof(SCCP_ADDR)); + temp_flag |= 0x08; + if( mapv1_ss_flag == 1 ) + { + temp_flag |= 0x14; + } + else if (vm_ptr->map_dlg.dlg_type == MAPDLG_OPEN) // has dlg open + { + dlg_open = (MapDlgOpen_struct *) &map_dlg->map_dlg.map_open; + if (dlg_open->param_flag & 0x01) // has peer reference + { + open_ptr->peerref_len = dlg_open->peer_ref[0]; + memcpy(open_ptr->peer_reference,dlg_open->peer_ref+1,dlg_open->peer_ref[0]); + temp_flag |= 0x04; + } + if (dlg_open->param_flag & 0x02) // has local reference + { + open_ptr->localref_len = dlg_open->local_ref[0]; + memcpy(open_ptr->local_reference,dlg_open->local_ref+1,dlg_open->local_ref[0]); + temp_flag |= 0x10; + } + } + + open_ptr->param_flag = temp_flag; + map_com.component_present = begin_ptr->component_present; + if (xapp_send_comdata(&map_com)) + { + if (begin_ptr->component_present == 1) + { + psm_ptr->sub_state1 = 4; + if(mapv1_ss_flag == 2) + { + if (process_components(&csl_cmp,proc)) + psm_ptr->sub_state1 = 5; + } + } + else + psm_ptr->sub_state1 = 5; +// psm_ptr->sub_state1 = 3; + } + else + { + xap_send_error("wait for check begin indicate: xapp_send_comdata fail"); + xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag); + return -1; + } + } + else + { + tcap_dlg.acn_len = dlg_ptr->acn_len; + memcpy(tcap_dlg.acn,dlg_ptr->acn,dlg_ptr->acn_len); + if (result == 2) // acn version not support + { + tcap_dlg.acn[dlg_ptr->acn_len-1] = get_xapacn_ver(dlg_ptr->acn[dlg_ptr->acn_len-2],psm_ptr->xap_flag); + if(tcap_dlg.acn[dlg_ptr->acn_len-1] == psm_ptr->acn_ver ) + tcap_dlg.acn[dlg_ptr->acn_len-1] --; + } + tcap_dlg.user_info_len = 0; +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xap_send_error("wait for check begin indicate: ACN not Supported. AC=%d Version=%d", psm_ptr->acn, psm_ptr->acn_ver); + xapp_send_uabort(proc,UABORT_ACNNS,1,&tcap_dlg,psm_ptr->xap_flag); + return -1; + } + break; +// case 3: // wait the link response from map user +// if (psm_ptr->msg_type == MAP_LINK) +// { +// psm_ptr->port_id = vm_ptr->recvcom_data.port_id; +// psm_ptr->msg_type = 0; +// psm_ptr->msg_flag = 0; +// vm_ptr->recvcom_flag = 0; +// if (begin_ptr->component_present == 1) +// psm_ptr->sub_state1 = 4; +// else +// psm_ptr->sub_state1 = 5; +// } +// else if (psm_ptr->msg_type == MAP_CLOSE) +// { +// xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag); +// return -1; +// } +// break; + case 4: // process component + if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0) + { + if (RecvTcapCmp(&csl_cmp,proc)) + { + xap_cmp_display(&csl_cmp); + if (process_components(&csl_cmp,proc)) + psm_ptr->sub_state1 = 5; + } + } + break; + case 5: // send delimiter primitive + if (vm_ptr->sendcom_flag == 0) + { + map_com.message_type = MAP_DELIMITER; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + xapp_send_comdata(&map_com); + return 1; + } + break; + default: + psm_ptr->sub_state1 = 0; + break; + } + return 0; +} + +int dlginit_program(u32 proc) // dialogue initiated +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct CSLdlg_struct *tcap_ptr; + struct TCContinue_struct *tccon_ptr; + struct dlgport_struct *port_ptr; + struct TCEnd_struct *tcend_ptr; + struct TCUAbort_struct *tcua_ptr; + struct MapComSrv_struct map_com; + struct MapUAbort_Arg *mapua_ptr; + struct MapOpen_Res *mapo_ptr; + struct CSLdlg_struct csl_dlg; + struct CSLcmp_struct csl_cmp; + struct MapDlg_struct map_dlg; + struct dlgport_struct tcap_dlg; + u8 result; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + tcap_ptr = (CSLdlg_struct *) &vm_ptr->tcap_data; + switch (psm_ptr->sub_state1) + { + case 0: + if (vm_ptr->sendcom_flag == 0 && RecvTcapDlg(tcap_ptr,proc)) + { + xap_dlg_display(tcap_ptr); + switch (tcap_ptr->message_type) + { + case Continue: +#if _SUPPORT_ANSI + case Conversation_WithPerm_Ansi: +#endif + tccon_ptr = (TCContinue_struct *) &tcap_ptr->dlg_prim.tc_continue; + port_ptr = (dlgport_struct *) &tccon_ptr->dlg_data; + if (!cmp_acname(psm_ptr,port_ptr)) // AC changed + { + xap_send_error("XAPP <== TCAP TC-Continue(Unexpected Dlg, AC Changed), did=%d", proc); + xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem); + map_dlg.dlg_type = MAPDLG_PABORT; + map_dlg.map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->sub_state1 = 5; + } + else + { + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_CONFIRM; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + mapo_ptr = (MapOpen_Res *) &map_com.dlg_list.open_res; + if (tccon_ptr->dialogue_flag == 1 && port_ptr->acn_len != 0) // has acn + { + mapo_ptr->acn_data.acn = psm_ptr->acn; + mapo_ptr->acn_data.acn_ver = psm_ptr->acn_ver; + mapo_ptr->param_flag = 0x01; // indicate thata has acn + } + else + mapo_ptr->param_flag = 0; + mapo_ptr->result = OpenResultAccept; + mapo_ptr->param_flag += 0x08; + xapp_send_comdata(&map_com); + if (tccon_ptr->component_present == 1) + psm_ptr->sub_state1 = 1; + else + return 1; + } + break; + case End: +#if _SUPPORT_ANSI + case Response_Ansi: +#endif + tcend_ptr = (TCEnd_struct *) &tcap_ptr->dlg_prim.tc_end; + port_ptr = (dlgport_struct *) &tcend_ptr->dlg_data; + if (!cmp_acname(psm_ptr,port_ptr)) // AC changed + { + xap_send_error("XAPP <== TCAP TC-End(Unexpected Dlg, AC Changed), did=%d", proc); + xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem); + psm_ptr->sub_state1 = 5; + } + else + { + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_CONFIRM; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + mapo_ptr = (MapOpen_Res *) &map_com.dlg_list.open_res; + if (tcend_ptr->dialogue_flag == 1 && port_ptr->acn_len != 0) // has acn + { + mapo_ptr->acn_data.acn = psm_ptr->acn; + mapo_ptr->acn_data.acn_ver = psm_ptr->acn_ver; + mapo_ptr->param_flag = 0x01; // indicate thata has acn + } + else + mapo_ptr->param_flag = 0; + mapo_ptr->result = OpenResultAccept; + mapo_ptr->param_flag += 0x08; + xapp_send_comdata(&map_com); + if (tcend_ptr->component_present == 1) + psm_ptr->sub_state1 = 3; + else + psm_ptr->sub_state1 = 4; + } + break; + case U_Abort: +#if _SUPPORT_ANSI + case U_Abort_Ansi: +#endif + tcua_ptr = (TCUAbort_struct *) &tcap_ptr->dlg_prim.tc_uabort; + port_ptr = (dlgport_struct *) &tcua_ptr->dlg_data; + xap_send_error("XAPP <== TCAP U_Abort did=%d Reason=%s", proc, tcap_uabort_desc[tcua_ptr->uabort_reason % 3]); + if (tcua_ptr->uabort_reason == UABORT_SPEC) + { + if (!extract_mapdlg(&map_dlg,port_ptr)) + { + xapp_send_openrefuse(psm_ptr->port_id,proc,PotentialVerIncompat); + psm_ptr->sub_state1 = 5; + } + else + { + if (map_dlg.dlg_type == MAPDLG_UABORT) + { + map_com.message_type = MAP_U_ABORT; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + mapua_ptr = (MapUAbort_Arg *) &map_com.dlg_list.uabort_arg; + get_mapuabort_reason(mapua_ptr,&map_dlg.map_dlg.map_uabort); + xapp_send_comdata(&map_com); + psm_ptr->sub_state1 = 5; + } + else if (map_dlg.dlg_type == MAPDLG_PABORT) + { + xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem); + psm_ptr->sub_state1 = 5; + } + else if (map_dlg.dlg_type == MAPDLG_REFUSE) + { + switch (map_dlg.map_dlg.map_refuse.reason) + { + case 0: // noReasonGiven + result = NoReasonGiven; + break; + case 1: // invalidDstRef + result = InvalidDesReference; + break; + case 2: // invalidOrgRef + result = InvalidOrgReference; + break; + default: + result = NoReasonGiven; + break; + } + xapp_send_openrefuse(psm_ptr->port_id,proc,result); + psm_ptr->sub_state1 = 5; + } + else + { + xapp_send_openrefuse(psm_ptr->port_id,proc,PotentialVerIncompat); + psm_ptr->sub_state1 = 5; + } + } + } + else if (tcua_ptr->uabort_reason == UABORT_ACNNS) + { + get_xapacn(psm_ptr,&tcua_ptr->dlg_data); + xapp_send_openrefuse(psm_ptr->port_id,proc,ACNotSupported); + psm_ptr->sub_state1 = 5; + } + else + { + xapp_send_openrefuse(psm_ptr->port_id, proc, NoReasonGiven); + psm_ptr->sub_state1 = 5; + } + break; + case P_Abort: +#if _SUPPORT_ANSI + case P_Abort_Ansi: +#endif + xap_send_error("XAPP <== TCAP P_Abort did=%d Reason=%s", proc, tcap_pabort_desc[tcap_ptr->dlg_prim.tc_pabort.pabort_reason & 7]); + if (tcap_ptr->dlg_prim.tc_pabort.pabort_reason == P_Abort_ITP) // incorrect transaction portion + { + xapp_send_openrefuse(psm_ptr->port_id,proc,PotentialVerIncompat); + psm_ptr->sub_state1 = 5; + } + else + { + result = get_mappabort_reason(&tcap_ptr->dlg_prim.tc_pabort,proc); + xapp_send_pabort(psm_ptr->port_id,proc,result,TCProblem); + psm_ptr->sub_state1 = 5; + } + break; + case Notice: + xap_send_error("XAPP <== TCAP Notice did=%d", proc); + xapp_send_openrefuse(psm_ptr->port_id,proc,RemoteNodeNotReachable); + psm_ptr->sub_state1 = 5; + break; + default: + break; + } + } + else + { + if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST) + { + map_dlg.dlg_type = MAPDLG_PABORT; + set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg); + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(31); + psm_ptr->sub_state1 = 5; + } + else if (psm_ptr->msg_type == MAP_CLOSE && psm_ptr->msg_flag == MAP_REQUEST) + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_dlg.message_type = End; +#if _SUPPORT_ANSI + else + csl_dlg.message_type = Response_Ansi; +#endif + csl_dlg.message_flag = REQUEST; + csl_dlg.dialogue_id = proc; + tcend_ptr = (TCEnd_struct *) &csl_dlg.dlg_prim.tc_end; + tcend_ptr->dialogue_flag = 0; + tcend_ptr->termination = PRE_END; + SendTcapDlg(&csl_dlg); + xap_dlg_display(&csl_dlg); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(32); + psm_ptr->sub_state1 = 5; + } + else + { + if (vm_ptr->sendcom_flag == 0 && RecvTcapCmp(&csl_cmp,proc)) + { + xap_cmp_display(&csl_cmp); + if (csl_cmp.message_type == L_Cancel) + { + xap_send_error("L_Cancel did=%d", proc); + xapp_send_openrefuse(psm_ptr->port_id,proc,RemoteNodeNotReachable); + } + } + } + } + break; + case 1: // continue process component + if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0) + { + if (RecvTcapCmp(&csl_cmp,proc)) + { + xap_cmp_display(&csl_cmp); + if (process_components(&csl_cmp,proc)) + psm_ptr->sub_state1 = 2; + } + } + break; + case 2: // write delimiter + if (vm_ptr->sendcom_flag == 0) + { + map_com.message_type = MAP_DELIMITER; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + xapp_send_comdata(&map_com); + return 1; + } + break; + case 3: // end process component + if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0) + { + if (RecvTcapCmp(&csl_cmp,proc)) + { + xap_cmp_display(&csl_cmp); + if (process_components(&csl_cmp,proc)) + psm_ptr->sub_state1 = 4; + } + } + break; + case 4: // write end indicate + if (vm_ptr->sendcom_flag == 0) + { + map_com.message_type = MAP_CLOSE; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + map_com.dlg_list.close_arg.param_flag = 0; + xapp_send_comdata(&map_com); + psm_ptr->sub_state1 = 5; + } + break; + case 5: // terminate PSM&RSM +// performing_ssm(&csl_cmp,TIMER_EXPIRY); +// requesting_ssm(&csl_cmp,TIMER_EXPIRY); + return -1; + break; + default: + psm_ptr->sub_state1 = 0; + break; + } + return 0; +} + +int dlgpend_program(u32 proc) // dialogue pending +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct MapOpen_Res *open_ptr; + struct MapDlg_struct map_dlg; + struct dlgport_struct tcap_dlg; + struct CSLdlg_struct csl_dlg; + struct TCEnd_struct *tcend_ptr; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + switch (psm_ptr->sub_state1) + { + case 0: + if (psm_ptr->msg_type == MAP_OPEN && psm_ptr->msg_flag == MAP_RESPONSE) + { + psm_ptr->port_id = vm_ptr->recvcom_data.port_id; + open_ptr = (MapOpen_Res *) &vm_ptr->recvcom_data.dlg_list.open_res; + if (open_ptr->result == OpenResultAccept) + {/* +++ do not know how to judge if user info include +++ */ + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(33); + return 1; + } + else + { + xap_send_error("dialogue pending: Negative OPEN_RESPONSE"); + map_dlg.dlg_type = MAPDLG_REFUSE; + map_dlg.map_dlg.map_refuse.reason = 0; // no reason given + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->sub_state1 = 1; + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(34); + } + } + else if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST) + { + map_dlg.dlg_type = MAPDLG_UABORT; + set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg); + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(35); + psm_ptr->sub_state1 = 1; + } + else if (psm_ptr->msg_type == MAP_CLOSE && psm_ptr->msg_flag == MAP_REQUEST) + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_dlg.message_type = End; +#if _SUPPORT_ANSI + else + csl_dlg.message_type = Response_Ansi; +#endif + csl_dlg.message_flag = REQUEST; + csl_dlg.dialogue_id = proc; + tcend_ptr = (TCEnd_struct *) &csl_dlg.dlg_prim.tc_end; + tcend_ptr->dialogue_flag = 0; + tcend_ptr->termination = PRE_END; + SendTcapDlg(&csl_dlg); + xap_dlg_display(&csl_dlg); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(36); + psm_ptr->sub_state1 = 1; + } + else if (psm_ptr->msg_type == MAP_LINK) + { + psm_ptr->port_id = vm_ptr->recvcom_data.port_id; + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(37); + } + break; + case 1: +// performing_ssm(&csl_cmp,TIMER_EXPIRY); +// requesting_ssm(&csl_cmp,TIMER_EXPIRY); + return -1; + break; + default: + psm_ptr->sub_state1 = 0; + break; + } + return 0; +} + +int dlgaccp_program(u32 proc) //dialogue accept program +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct CSLdlg_struct csl_dlg; + struct MapDlg_struct map_dlg; + struct MapClose_Arg *mapcls_ptr; + struct TCEnd_struct *tcend_ptr; + struct dlgport_struct tcap_dlg; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + switch (psm_ptr->sub_state1) + { + case 0: + if (vm_ptr->recvopr_flag != 0) + { + if (vm_ptr->recvopr_data.message_flag == MAP_REQUEST) + { + psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,1); + vm_ptr->recvopr_flag = 0; + } + else if (vm_ptr->recvopr_data.message_flag == MAP_RESPONSE) + psm_ptr->data_count += performing_ssm(&vm_ptr->recvopr_data,RESPONSE_ISSUED,0); + } + else + { + if (psm_ptr->delimiter_flag == 1) + { + csl_dlg.dlg_prim.tc_continue.dialogue_flag = include_dialogue(proc); + +#if _SUPPORT_ANSI + if (psm_ptr->xap_flag == XAP_IS41_SSN) + csl_dlg.message_type = Conversation_WithPerm_Ansi;//ANSI-Continue + else +#endif + csl_dlg.message_type = Continue; + + + csl_dlg.message_flag = REQUEST; + csl_dlg.dialogue_id = proc; + set_xapacn(&csl_dlg.dlg_prim.tc_continue.dlg_data,psm_ptr); + csl_dlg.dlg_prim.tc_continue.dlg_data.user_info_len = 0; +#if _SUPPORT_ANSI + csl_dlg.dlg_prim.tc_continue.dlg_data.security_context_len = 0; + csl_dlg.dlg_prim.tc_continue.dlg_data.confidential_info_len = 0; +#endif + csl_dlg.dlg_prim.tc_continue.component_present = psm_ptr->data_count; + psm_ptr->data_count = 0; + SendTcapDlg(&csl_dlg); + xap_dlg_display(&csl_dlg); + psm_ptr->delimiter_flag = 0; +// psm_ptr->msg_type = 0; +// psm_ptr->msg_flag = 0; +// vm_ptr->recvcom_flag = 0; + return 1; + } + else if (psm_ptr->msg_type == MAP_CLOSE && psm_ptr->msg_flag == MAP_REQUEST) + { + mapcls_ptr = (MapClose_Arg *) &vm_ptr->recvcom_data.dlg_list.close_arg; + tcend_ptr = (TCEnd_struct *) &csl_dlg.dlg_prim.tc_end; + + tcend_ptr->dialogue_flag = include_dialogue(proc); +#if _SUPPORT_ANSI + if (psm_ptr->xap_flag == XAP_IS41_SSN || psm_ptr->xap_flag == XAP_AIN_SSN) + csl_dlg.message_type = Response_Ansi;//ANSI-End + else +#endif + csl_dlg.message_type = End; + + csl_dlg.message_flag = REQUEST; + csl_dlg.dialogue_id = proc; + + set_xapacn(&tcend_ptr->dlg_data,psm_ptr); + tcend_ptr->dlg_data.user_info_len = 0; +#ifdef _SUPPORT_ANSI + tcend_ptr->dlg_data.security_context_len = 0; + tcend_ptr->dlg_data.confidential_info_len = 0; +#endif + if (mapcls_ptr->release_method == NormalRelease) + { + tcend_ptr->termination = BASIC_END; + tcend_ptr->component_present = psm_ptr->data_count; + } + else + tcend_ptr->termination = PRE_END; + psm_ptr->data_count = 0; + SendTcapDlg(&csl_dlg); + xap_dlg_display(&csl_dlg); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(38); + psm_ptr->sub_state1 = 1; + } + else if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST) + { + map_dlg.dlg_type = MAPDLG_UABORT; + set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg); + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(39); + psm_ptr->sub_state1 = 1; + } + } + break; + case 1: +// performing_ssm(&csl_cmp,TIMER_EXPIRY); +// requesting_ssm(&csl_cmp,TIMER_EXPIRY); + return -1; + break; + default: + psm_ptr->sub_state1 = 0; + break; + } + return 0; +} + +int dlgestab_program(u32 proc) // dialogue established +{ + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct MapDlg_struct map_dlg; + struct CSLdlg_struct csl_dlg; + struct CSLdlg_struct *csl_ptr; + struct TCUAbort_struct *tcua_ptr; + struct TCEnd_struct *tcend_ptr; + struct CSLcmp_struct csl_cmp; + struct MapComSrv_struct map_com; + struct dlgport_struct tcap_dlg; + u8 result; + + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + switch (psm_ptr->sub_state1) + { + case 0: + if (vm_ptr->sendcom_flag == 0 && RecvTcapDlg(&csl_dlg,proc)) + { + switch (csl_dlg.message_type) + { + case Continue: +#if _SUPPORT_ANSI + case Conversation_WithPerm_Ansi: +#endif + if (csl_dlg.dlg_prim.tc_continue.component_present == 1) + { + psm_ptr->suspend_timer = 0; + psm_ptr->sub_state1 = 1; + } + break; + case End: +#if _SUPPORT_ANSI + case Response_Ansi: +#endif + if (csl_dlg.dlg_prim.tc_end.component_present == 1) + psm_ptr->sub_state1 = 2; + else + psm_ptr->sub_state1 = 3; + break; + case U_Abort: +#if _SUPPORT_ANSI + case U_Abort_Ansi: +#endif + tcua_ptr = (TCUAbort_struct *) &csl_dlg.dlg_prim.tc_uabort; + xap_send_error("XAPP <== TCAP U_Abort did=%d Reason=%s", proc, tcap_uabort_desc[tcua_ptr->uabort_reason%3]); +// if (extract_mapdlg(&map_dlg,&tcua_ptr->dlg_data)) // analyse user info + extract_mapdlg(&map_dlg,&tcua_ptr->dlg_data); // analyse user info + { + map_com.message_flag = MAP_INDICATE; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + /* + if (map_dlg.dlg_type == MAPDLG_UABORT) + { + map_com.message_type = MAP_U_ABORT; + get_mapuabort_reason(&map_com.dlg_list.uabort_arg,&map_dlg.map_dlg.map_uabort); + xapp_send_comdata(&map_com); + } + else if (map_dlg.dlg_type == MAPDLG_PABORT) + xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,TCProblem); + */ + if (map_dlg.dlg_type == MAPDLG_PABORT) + xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,TCProblem); + else + { + map_com.message_type = MAP_U_ABORT; + get_mapuabort_reason(&map_com.dlg_list.uabort_arg,&map_dlg.map_dlg.map_uabort); + xapp_send_comdata(&map_com); + } + } + psm_ptr->sub_state1 = 4; + break; + case P_Abort: +#if _SUPPORT_ANSI + case P_Abort_Ansi: +#endif + xap_send_error("XAPP <== TCAP P_Abort did=%d Reason=%s", proc, tcap_pabort_desc[csl_dlg.dlg_prim.tc_pabort.pabort_reason & 7]); + result = get_mappabort_reason(&csl_dlg.dlg_prim.tc_pabort,proc); + xapp_send_pabort(psm_ptr->port_id,proc,result,TCProblem); + psm_ptr->sub_state1 = 4; + break; + case Notice: + xap_send_error("XAPP <== TCAP Notice did=%d", proc); + xapp_send_notice(psm_ptr->port_id,proc,csl_dlg.dlg_prim.tc_notice.report_reason); + break; + default: + break; + } + } + else + { + if (vm_ptr->sendcom_flag == 0 && vm_ptr->sendopr_flag != 1 && RecvTcapCmp(&csl_cmp,proc)) + { + xap_cmp_display(&csl_cmp); + if (csl_cmp.message_type == L_Cancel) + requesting_ssm(&csl_cmp,TIMER_EXPIRY,0); + } + } + if (vm_ptr->recvopr_flag != 0) + { + if (vm_ptr->recvopr_data.message_flag == MAP_REQUEST) + { + psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,1); + vm_ptr->recvopr_flag = 0; + } + else if (vm_ptr->recvopr_data.message_flag == MAP_RESPONSE) + psm_ptr->data_count += performing_ssm(&vm_ptr->recvopr_data,RESPONSE_ISSUED,1); + } + else + { + if (vm_ptr->tcap_data.message_type != 0) + { + if (SendTcapDlg(&vm_ptr->tcap_data)) + { + xap_dlg_display(&vm_ptr->tcap_data); + if (vm_ptr->recvcom_flag == 1) + xap_watch_dog(41); + vm_ptr->recvcom_flag = 0; + psm_ptr->suspend_timer = 0; +#if _SUPPORT_ANSI + if (vm_ptr->tcap_data.message_type == End || vm_ptr->tcap_data.message_type == U_Abort || + vm_ptr->tcap_data.message_type == Response_Ansi || vm_ptr->tcap_data.message_type == U_Abort_Ansi) +#else + if (vm_ptr->tcap_data.message_type == End || vm_ptr->tcap_data.message_type == U_Abort) +#endif + psm_ptr->sub_state1 = 4; + vm_ptr->tcap_data.message_type = 0; + } + } + else + { + csl_ptr = (CSLdlg_struct *) &vm_ptr->tcap_data; + csl_ptr->message_flag = REQUEST; + csl_ptr->dialogue_id = proc; + if (psm_ptr->delimiter_flag == 1) + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_ptr->message_type = Continue; +#if _SUPPORT_ANSI + else + csl_ptr->message_type = Conversation_WithPerm_Ansi; +#endif + csl_ptr->dlg_prim.tc_continue.dialogue_flag = 0; + csl_ptr->dlg_prim.tc_continue.component_present = psm_ptr->data_count; + psm_ptr->data_count = 0; + psm_ptr->delimiter_flag = 0; +// psm_ptr->msg_type = 0; +// psm_ptr->msg_flag = 0; + } + else if (psm_ptr->msg_type == MAP_CLOSE) + { +#if _SUPPORT_ANSI + if ((psm_ptr->xap_flag == XAP_MAP_SSN) || + (psm_ptr->xap_flag == XAP_CAP_SSN)) +#endif + csl_ptr->message_type = End; +#if _SUPPORT_ANSI + else + csl_ptr->message_type = Response_Ansi; +#endif + tcend_ptr = (TCEnd_struct *) &csl_ptr->dlg_prim.tc_end; + tcend_ptr->dialogue_flag = 0; + if (vm_ptr->recvcom_data.dlg_list.close_arg.release_method == NormalRelease) + { + tcend_ptr->termination = BASIC_END; + tcend_ptr->component_present = psm_ptr->data_count; + } + else + tcend_ptr->termination = PRE_END; + psm_ptr->data_count = 0; + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + } + else if (psm_ptr->msg_type == MAP_U_ABORT) + { + map_dlg.dlg_type = MAPDLG_UABORT; + set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg); + tcap_dlg.acn_len = 0; + tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info); +#if _SUPPORT_ANSI + tcap_dlg.security_context_len = 0; + tcap_dlg.confidential_info_len = 0; +#endif + xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + + vm_ptr->recvcom_flag = 0; + psm_ptr->suspend_timer = 0; + + psm_ptr->sub_state1 = 4; + vm_ptr->tcap_data.message_type = 0; + } + } + } + break; + case 1: // receive continue component + if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0) + { + if (RecvTcapCmp(&csl_cmp,proc)) + { + xap_cmp_display(&csl_cmp); + if (process_components(&csl_cmp,proc)) + { + map_com.message_type = MAP_DELIMITER; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + xapp_send_comdata(&map_com); + psm_ptr->sub_state1 = 0; + } + } + } + break; + case 2: + if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0) + { + if (RecvTcapCmp(&csl_cmp,proc)) + { + xap_cmp_display(&csl_cmp); + if (process_components(&csl_cmp,proc)) + psm_ptr->sub_state1 = 3; + } + } + case 3: // send end indicate + if (vm_ptr->sendcom_flag == 0) + { + map_com.message_type = MAP_CLOSE; + map_com.message_flag = MAP_INDICATE; + map_com.port_id = psm_ptr->port_id; + map_com.dialogue_id = proc; + map_com.dlg_list.close_arg.param_flag = 0; + xapp_send_comdata(&map_com); + psm_ptr->sub_state1 = 4; + } + break; + case 4: +// performing_ssm(&csl_cmp,TIMER_EXPIRY); +// requesting_ssm(&csl_cmp,TIMER_EXPIRY); + return 1; + break; + default: + psm_ptr->sub_state1 = 0; + break; + } + return 0; +} + +void xap_fsm() //called per 10ms +{ + register u32 proc; + struct xapp_vm_data *vm_ptr; + struct psmvm_data *psm_ptr; + struct MapOpen_Arg *open_ptr; + struct dlgport_struct tcap_dlg; + int result; + +/* daniel changed on 2005-4-29 */ + xap_vm_ptr->debug_data.watch_dog[0] = 0; +/* daniel changed on 2005-4-29 */ + + xap_monitor(); + for (proc = 1;proc < (xap_vm_ptr->grantdid);proc ++) + { + vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc]; + psm_ptr = (psmvm_data *) &vm_ptr->psm_data; + +/* daniel changed on 2005-4-29 */ + if (psm_ptr->psm_state > XAP_IDLE) + { + xap_vm_ptr->debug_data.watch_dog[0]++; + } +/* daniel changed on 2005-4-29 */ + + switch (psm_ptr->psm_state) + { + case XAP_INIT: + memset(vm_ptr,0,sizeof(xapp_vm_data)); + psm_ptr->psm_state = XAP_IDLE; + break; + case XAP_IDLE: //idle; (USER)==>MAP-OPEN + if (psm_ptr->msg_type == MAP_OPEN && psm_ptr->msg_flag == MAP_REQUEST) + { + open_ptr = (MapOpen_Arg *) &vm_ptr->recvcom_data.dlg_list.open_arg; + psm_ptr->acn = open_ptr->acn_data.acn; // store acn data + psm_ptr->acn_ver = open_ptr->acn_data.acn_ver; + psm_ptr->port_id = vm_ptr->recvcom_data.port_id; + psm_ptr->msg_type = 0; + psm_ptr->msg_flag = 0; + vm_ptr->recvcom_flag = 0; + xap_watch_dog(26); + xap_watch_dog(40); + psm_ptr->psm_state = XAP_WFUR; + xap_watch_dog(1); + } + else if (psm_ptr->msg_type == 0) + { + if (vm_ptr->sendcom_flag == 0) // can send common data + { + if (RecvTcapDlg(&vm_ptr->tcap_data,proc)) + { + if (vm_ptr->tcap_data.message_type == Begin) + { + xap_watch_dog(2); + set_xap_flag(proc,vm_ptr->tcap_data.dlg_prim.tc_begin.local_add.SSN);// mark itu + psm_ptr->psm_state = XAP_WFCBI; + } +#if _SUPPORT_ANSI + else if (vm_ptr->tcap_data.message_type == Query_WithPerm_Ansi) + { + xap_watch_dog(2); + if(vm_ptr->tcap_data.dlg_prim.tc_begin.peer_add.SSN==34)//SSN=MNP_AIN + psm_ptr->xap_flag = XAP_AIN_SSN; + else + psm_ptr->xap_flag = XAP_IS41_SSN;// mark ansi + psm_ptr->psm_state = XAP_WFCBI; + } +#endif + } + } + } + else + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_SUSPEND; + } + break; + case XAP_WFUR: // wait for user requests: (USER)==>Request primitiv/MAP_DELIMITER + result = wfur_program(proc); + if (result == 1) + { + psm_ptr->sub_state1 = 0; + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_INITIATED; + } + else if (result == -1) + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_SUSPEND; + } + if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire + { + xap_send_error("wait for user requests: timer expired"); + psm_ptr->psm_state = XAP_DLG_HALT; + } + break; + case XAP_WFCBI: // wait for check begin indicate + result = wfcbi_program(proc); + if (result == 1) // return dialogue pending + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_PENDING; + psm_ptr->sub_state1 = 0; + } + else if (result == -1) + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_SUSPEND; + } + if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire + { + xap_send_error("wait for check begin indicate: timer expired"); + psm_ptr->psm_state = XAP_DLG_HALT; + } + break; + case XAP_DLG_INITIATED: //Continue<==(TCAP) + result = dlginit_program(proc); + if (result == 1) + { + vm_ptr->tcap_data.message_type = 0; + psm_ptr->sub_state1 = 0; + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_ESTABLISHED; + } + else if (result == -1) + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_SUSPEND; + } + if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire + { + xap_send_error("DLG_INITIATED: timer expired"); + psm_ptr->psm_state = XAP_DLG_HALT; + } + break; + case XAP_DLG_PENDING: + result = dlgpend_program(proc); + if (result == 1) + { + psm_ptr->sub_state1 = 0; + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_ACCEPTED; + } + else if (result == -1) + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_SUSPEND; + } + if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire + { + xap_send_error("DLG_PENDING: timer expired"); + psm_ptr->psm_state = XAP_DLG_HALT; + } + break; + case XAP_DLG_ACCEPTED: + result = dlgaccp_program(proc); + if (result == 1) + { + vm_ptr->tcap_data.message_type = 0; + psm_ptr->sub_state1 = 0; + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_ESTABLISHED; + } + else if (result == -1) + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_SUSPEND; + } + if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire + { + xap_send_error("DLG_ACCEPTED: timer expired"); + psm_ptr->psm_state = XAP_DLG_HALT; + } + break; + case XAP_DLG_ESTABLISHED: + if (dlgestab_program(proc)) + { + psm_ptr->suspend_timer = 0; + psm_ptr->psm_state = XAP_DLG_SUSPEND; + } + if ((psm_ptr->suspend_timer++) >= xap_inter_ptr->establishment_timer * XAPP_TIMERHZ) // timer is expire + { + xap_send_error("DLG_ESTABLISHED: timer expired"); + psm_ptr->psm_state = XAP_DLG_HALT; + } + break; + case XAP_DLG_SUSPEND: + if (vm_ptr->sendcom_flag == 0 && vm_ptr->sendopr_flag == 0) + psm_ptr->psm_state = XAP_INIT; + if ((psm_ptr->suspend_timer++) >= SUSPEND_TIME * XAPP_TIMERHZ/2) // timer is expire + { + psm_ptr->psm_state = XAP_INIT; + } + if(xap_vm_ptr->debug_data.monitor_did == proc) /* clear monitor flag, port0 never used */ + xap_vm_ptr->debug_data.monitor_did = 0; + break; + case XAP_DLG_HALT: + xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem); + xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag); + psm_ptr->psm_state = XAP_DLG_SUSPEND; + break; + default: + psm_ptr->psm_state = XAP_INIT; + break; + } + } +} + + + + + diff --git a/plat/xapp/src/xap_provider.h b/plat/xapp/src/xap_provider.h new file mode 100644 index 0000000..bf4bb45 --- /dev/null +++ b/plat/xapp/src/xap_provider.h @@ -0,0 +1,185 @@ +/* XAP provider head file */ +/* Written by Liu Zhiguo 2003-08-26 */ +/* Version 1.0 */ +/* -------------------------------- */ + +#include "../../public/src/include/includes.h" +#include "../../public/src/include/pub_fmt.h" +#include "../../sccp/src/include/sccp.h" +#include "../../tcap/src/include/tcap_head.h" +#include "../../tcap/src/include/tcap_public.h" +#include "../../tcap/src/include/tcap_struct.h" +#include "ixap.h" +#include "mapp/map_const.h" +#include "mapp/map_public.h" +#include "mapp/map_code.h" +#include "mapp/map_coding.h" +#include "mapp/is41_code.h" +#include "mapp/map_struct.h" +#include "mapp/map_acn.h" +#include "mapp/map_dlgpdu.h" + +#ifndef _PROVIDER_H +#define _PROVIDER_H + +#define XAP_MAP_SSN 1 // ssn is used for map +#define XAP_CAP_SSN 2 // ssn is used for cap +#define XAP_IS41_SSN 3 // ssn is used for is41 +#define XAP_AIN_SSN 4 //SSN IS USED FOR MNP AIN (ANSI TCAP) + +#define XAP_VM_KEY 0xa0e00000 +#define XAP_VM_PERM 0664 +#define XAP_INTER_KEY 0xa0f00000 +#define XAP_INTER_PERM 0664 + +#define MAX_XAP_SSN 16 +#define XAP_OPEN_LEN 128 +#define XAP_ACN_LEN 7 // xap acn length +#define XAP_ACN_NUM 50 // acn buffer length +#define XAP_OPR_NUM 80 // operation length + +#define XAP_ASCIN_LEN 1024 +#define XAP_ASCOUT_LEN 4096 +#define XAP_WTDOG_LEN 256 + +#define XAP_INIT 0x00 +#define XAP_IDLE 0x01 +#define XAP_WFUR 0x02 // wait for user requests +#define XAP_WFCBI 0x03 // wait for check begin indicate +#define XAP_DLG_INITIATED 0x05 +#define XAP_DLG_PENDING 0x04 // dialogue pending +#define XAP_DLG_ACCEPTED 0x06 +#define XAP_DLG_ESTABLISHED 0x07 +#define XAP_DLG_SUSPEND 0x08 +#define XAP_DLG_HALT 0x09 + +/* the state of SSM */ +#define SSM_IDLE 0x00 +#define SSM_WFRESPONSE 0x01 // wait for response +#define SSM_WFCONFIRM 0x02 + +/* the flag of requesting map SSM */ +#define SERVICE_INVOKED 0x01 +#define RESULT_RECEIVED 0x02 +#define PARTIAL_RESULT_RECEIVED 0x03 +#define NEGATIVE_RESULT_RECEIVED 0x04 +#define LINKED_REQUEST_RECEIVED 0x05 +#define LINKED_SERVICE_INVOKED 0x06 +#define USER_REJECT_RECEIVED 0x07 +#define PROVIDER_REJECT_RECEIVED 0x08 +#define TIMER_EXPIRY 0x09 +#define TERMINATED 0x0a + +/* the flag of performing map SSM */ +#define SERVICE_INVOCATION_RECEIVED 0x01 +#define RESPONSE_ISSUED 0x02 +#define GUARD_TIMER 0x03 + +#define SUSPEND_TIME 1 +#define DLGPEND_TIME 180 +#define XAPP_TIMERHZ 100 + +#define XAPP_PRIVATE_TCAP 1 +#define XAPP_OPER_FAMILY 9 +#define XAPP_NATIONAL_TCAP 0 +typedef struct xap_acn_info // store info about application context name +{ + u8 buf_len; + u8 acn[XAP_ACN_NUM]; // acn buffer + u8 acn_ver[XAP_ACN_NUM]; // acn version buffer +} xap_acn_info; + +typedef struct xap_opr_info // store info about opration code +{ + u8 buf_len; + u8 opr_code[XAP_OPR_NUM]; // operation code buffer + u8 opr_class[XAP_OPR_NUM]; // operation class buffer + u32 opr_timer[XAP_OPR_NUM]; // operation timer buffer +} xap_opr_info; + + +typedef struct xap_inter_struct // xap interface structure +{ + u8 mcc[2]; + u8 mnc0; + u8 cc[2]; + u8 ndc[3]; + u8 inter_prefix[2]; + u8 national_prefix[2]; + u8 local_prefix[2]; + u8 mnc[2];//expend mnc from 1 byte to 2 bytes + u32 establishment_timer; +/* mscid is special use for CDMA */ + u8 mscidToNum[256][14]; +/* mscid is special use for CDMA */ + + // define for the ssn control + u8 regssn_len; + u8 reg_ssn[MAX_XAP_SSN]; + u8 regssn_flag[MAX_XAP_SSN]; // indicate if the register SSN is MAP or CAP ssn + u8 open_head[MAX_XAP_SSN]; + u8 open_tail[MAX_XAP_SSN]; + u32 open_did[MAX_XAP_SSN][XAP_OPEN_LEN]; +} xap_inter_struct; + +typedef struct xap_debug_struct +{ + char *start_time; // time of module start + u32 monitor_did; // the dialogue id for monitored + u8 error_switch; + u8 map_switch; + u8 cap_switch; + u8 send_control; // control if can send xap message + u8 ascin_buf[XAP_ASCIN_LEN]; + u8 ascout_buf[XAP_ASCOUT_LEN]; + u32 watch_dog[XAP_WTDOG_LEN]; +} xap_debug_struct; + +typedef struct psmvm_data // xap provider state machine data +{ + u8 xap_flag; // 0: empty; 1: map primitive; 2: cap primitive + u8 psm_state; + u8 sub_state1; + u8 delimiter_flag; + u8 acn; + u8 acn_ver; + u8 msg_type; + u8 msg_flag; + u32 port_id; + u32 suspend_timer; + u8 data_count; + u8 recv_bsa_count; + u8 opr_state[MAX_INVOKEID]; + u8 opr_code[MAX_INVOKEID]; + u8 opr_class[MAX_INVOKEID]; +} psmvm_data; + +typedef struct xapp_vm_data // XAP provider virtue machine structure +{ + struct psmvm_data psm_data; + u8 recvcom_flag; // USER=>XAPP + u8 recvopr_flag; // USER=>XAPP 0: has not data 1: has data 2: has partial data + u8 sendcom_flag; // XAPP=>USER + u8 sendopr_flag; // XAPP=>USER + u32 recvopr_site; // USER=>XAPP 0: has not data 1: has data 2: has partial data + struct MapComSrv_struct recvcom_data; + struct MapOprData_struct recvopr_data; + struct MapComSrv_struct sendcom_data; + struct MapOprData_struct sendopr_data; + struct CSLdlg_struct tcap_data; + struct MapDlg_struct map_dlg; +} xapp_vm_data; + +typedef struct xap_vm_struct +{ + int grantdid; + struct xapp_vm_data xap_data[MAX_DIALOGUEID]; + struct xap_debug_struct debug_data; +} xap_vm_struct; + +// fix multiple definition==================================== +extern struct xap_vm_struct *xap_vm_ptr; +extern struct xap_inter_struct *xap_inter_ptr; +// + +#endif diff --git a/plat/xapp/ut/xapp_test/Makefile b/plat/xapp/ut/xapp_test/Makefile new file mode 100644 index 0000000..6d5fc1f --- /dev/null +++ b/plat/xapp/ut/xapp_test/Makefile @@ -0,0 +1,42 @@ +# Makefile create for XAPP Test +# Create by liuwei + +cc = gcc +#CFLAG = -g -Wall -c -DVMS_UNDER_DEVELOP +CFLAG = -g -Wall -c +LIB_DIR = ../.. +XAPP_TEST_OBJ = xapp_main.o xapp_op_test.o xapp_coding_test.o + +PUBLIC_LIB = -L$(LIB_DIR)/public -lpublic +MTP3_LIB = -L$(LIB_DIR)/mtp3 -lmtp3 +DEBUG_LIB = -L$(LIB_DIR)/debug -ldebug +SNMP_LIB = -L$(LIB_DIR)/snmp -lsnmp +SCCP_LIB = -L$(LIB_DIR)/sccp -lsccp +TCAP_LIB = -L$(LIB_DIR)/tcap -ltcap +XAPP_LIB = -L$(LIB_DIR)/xapp -lxapp +IPTRANS_LIB = -L$(LIB_DIR)/iptrans -liptrans + +xapp_test: $(XAPP_TEST_OBJ) + $(cc) -o xapp_test $(XAPP_TEST_OBJ) $(DEBUG_LIB) $(IPTRANS_LIB) $(SNMP_LIB) $(MTP3_LIB) $(SCCP_LIB) $(TCAP_LIB) $(XAPP_LIB) $(PUBLIC_LIB) -lm -lz + +xapp_main.o: xapp_main.c + $(cc) $(CFLAG) xapp_main.c + +xapp_op_test.o : xapp_op_test.c + $(cc) $(CFLAG) xapp_op_test.c + +xapp_coding_test.o : xapp_coding_test.c + $(cc) $(CFLAG) xapp_coding_test.c + +run: + cd .. ; rm -f *.a + cd ../mapp;make;cd .. + cd ../capp;make;cd .. + cd .. ;make; + rm -f xapp_test ; make +clean: + cd ../ ;make clean + rm -f *.o *.a *.bak core xapp_test + +backup: + diff --git a/plat/xapp/ut/xapp_test/conf/.sccp.conf.swo b/plat/xapp/ut/xapp_test/conf/.sccp.conf.swo new file mode 100644 index 0000000000000000000000000000000000000000..847a816cf68ebf7ae90da983d3437f7e36d4f4fd GIT binary patch literal 12288 zcmeI2&2G~`6oqdQAXWTTuw!*0NWdboXOc9I#0Di5id3SiX}hVa$W78V!o*f=XeAzi z6)(UNgxK)_EP*vUSR=uPS3u(DjO~)t4J7O8Ug>yp$8&sVK993VylrnZ?sK`|5MqJo zbn9d7*^e{yskB$@PV~|(9uJupshW(*M962 zRNNDIZe$&}K@cC>Q7??Fjz8G3!cHeBm`^j5k|9Ds2plJ{UewCYUBAXxF0UUyD?LI$ z2nYcoAOwVf5D)@FKnR>@0#PtWzp=to&{b$I6&eX4AOwVf5D)@FKnMr{As_^VfDjM@ zLg0iDaJxh|&k?V!9H-K-Kh`vIfq1TWH-GLUMPZx=vLv82=^!)O?ci znQQvoT;W#a4x@U1w;zSL6!X%cJC-pw8{9IJ#zc9w!FQ4J6613(pv`-0Ywb06+v{zS zE|<&%P2}U_=%6aPpzv~V5sm3h^J+CoNtLjY#G0%aD^X@)e~13Zip6KGagoC+|Fmjj z8@C#?syL}?WkDvUp3C@Rn5AxR&#HsTa~GhwSwF%)=3ivxmm1}CX8D>gEc0S zop5<3YfNO^n(pOMRb4CvT+%t7>%bb zUUxD+vnLM6D~*jlKk_S`>~hM5;eeBGfrnu~><%y{jed}9_ED~AbJ@IQ&rQFJXNz*J aT5W}EcyqqL%R7Cq$G29U4ZCd@Z_^*Ce+d!* literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/all-wcprops b/plat/xapp/ut/xapp_test/conf/.svn/all-wcprops new file mode 100644 index 0000000..80f0099 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/all-wcprops @@ -0,0 +1,179 @@ +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf +END +hae_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/hae_sys.conf +END +cc_table.conf +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/cc_table.conf +END +map_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/map_operation.conf +END +map_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/map_acn.conf +END +help_page +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/help_page +END +ppsConf.txt +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/ppsConf.txt +END +smsc_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/smsc_sys.conf +END +hlr_parambit.conf +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/hlr_parambit.conf +END +HlrSysPara +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/HlrSysPara +END +wxc2exit.txt +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/wxc2exit.txt +END +xap_sysparam.conf +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/xap_sysparam.conf +END +xapp_test.conf +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/xapp_test.conf +END +system.ini.30K +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/system.ini.30K +END +system.inimscvlrhlr +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/system.inimscvlrhlr +END +menu_page +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/menu_page +END +profile +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/profile +END +.sccp.conf.swo +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/.sccp.conf.swo +END +system.ini +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/system.ini +END +smsc_csta.conf +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/smsc_csta.conf +END +iptrans.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/iptrans.conf +END +wxc2_sys.conf +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/wxc2_sys.conf +END +conv_prefix.conf +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/conv_prefix.conf +END +mtp3.conf +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/mtp3.conf +END +cap_operation.conf +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/cap_operation.conf +END +conf.rar +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/conf.rar +END +cap_acn.conf +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/cap_acn.conf +END +smsc_parambit.conf +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/smsc_parambit.conf +END +sccp.conf +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/sccp.conf +END +system.ini.100k +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/wxc2/!svn/ver/1/trunk/R4S/plat/xapp/ut/xapp_test/conf/system.ini.100k +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/entries b/plat/xapp/ut/xapp_test/conf/.svn/entries new file mode 100644 index 0000000..46f3e4e --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/entries @@ -0,0 +1,1014 @@ +10 + +dir +114 +http://172.25.201.20/svn/wxc2/trunk/R4S/plat/xapp/ut/xapp_test/conf +http://172.25.201.20/svn/wxc2 + + + +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng + + + + + + + + + + + + + + +4a7aa47d-8bee-446f-9599-049dc37ff264 + +hae_sys.conf +file + + + + +2012-12-28T03:06:22.625000Z +649d3fce3992c1c1b43fc30172a7f2a7 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +116 + +cc_table.conf +file + + + + +2012-12-28T03:06:22.640625Z +9f0aa5dca95acac37a68fe54438fa684 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4438 + +map_operation.conf +file + + + + +2012-12-28T03:06:22.656250Z +63cb6cdc86026f84ed0b86942c18579a +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +3089 + +map_acn.conf +file + + + + +2012-12-28T03:06:22.656250Z +ba98ac6b009e2c7e570ced416edb5508 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1541 + +help_page +file + + + + +2012-12-28T03:06:22.671875Z +cf329064faeb00741b9a1390677c1b27 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +561 + +ppsConf.txt +file + + + + +2012-12-28T03:06:22.687500Z +2fe53e393703da5db021ba122df651da +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +28340 + +smsc_sys.conf +file + + + + +2012-12-28T03:06:22.687500Z +8a5c1de60a79d7149ea3aae56ad6ee4d +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +86 + +hlr_parambit.conf +file + + + + +2012-12-28T03:06:22.718750Z +8c63d6cbc22edc75874555b19a2c8ff0 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +20740 + +HlrSysPara +file + + + + +2012-12-28T03:06:22.703125Z +3698e8bf4de04c7bf65dcf683c1c8fc5 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +7244 + +wxc2exit.txt +file + + + + +2012-12-28T03:06:22.750000Z +36b3f4a9e9ff77055c211efac6de9013 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +74 + +xap_sysparam.conf +file + + + + +2012-12-28T03:06:22.734375Z +adb6e10944b332812a04e892e71d565f +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +13 + +xapp_test.conf +file + + + + +2012-12-28T03:06:22.734375Z +4167956694a1b91e9647870d16071444 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +20 + +system.ini.30K +file + + + + +2012-12-28T03:06:22.765625Z +d29bf66b93206f5aa8d317b606db1a85 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +212 + +system.inimscvlrhlr +file + + + + +2012-12-28T03:06:22.781250Z +9ee0f7508ccec1d795674486c5475f36 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +212 + +profile +file + + + + +2012-12-28T03:06:22.781250Z +0049e7048c766e13ddec943a200ae608 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +771 + +menu_page +file + + + + +2012-12-28T03:06:22.796875Z +28bff84476cbd37537645648c3d3fcc2 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +522 + +.sccp.conf.swo +file + + + + +2012-12-28T03:06:22.812500Z +414d66487f472f691d43a346684ea4e8 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +12288 + +system.ini +file + + + + +2012-12-28T03:06:22.812500Z +cc73dc3aa5b3d6d39d2f07b15dfdcab5 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +212 + +smsc_csta.conf +file + + + + +2012-12-28T03:06:22.828125Z +ecf8d97315dfb7401a6ff8cd615aab08 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +363 + +iptrans.conf +file + + + + +2012-12-28T03:06:22.828125Z +4f4ca03faae59f42555493b5fd3abad4 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +307 + +wxc2_sys.conf +file + + + + +2012-12-28T03:06:22.828125Z +c59a016f57ed632c76316173b7f560e1 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +19 + +conv_prefix.conf +file + + + + +2012-12-28T03:06:22.843750Z +e844a4aa6315c4ad71e8089422f675dc +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +4608 + +mtp3.conf +file + + + + +2012-12-28T03:06:22.843750Z +b44ca5c82a007cf88940026003aa780d +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +95312 + +cap_operation.conf +file + + + + +2012-12-28T03:06:22.859375Z +4b8f0a08008f42d11cc218d72dedea00 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1296 + +conf.rar +file + + + + +2012-12-28T03:06:22.859375Z +33e30944dd272606a8d3ea04aa3ca989 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +2638 + +cap_acn.conf +file + + + + +2012-12-28T03:06:22.875000Z +6e882749ca21cb342d7715486eae42ac +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +252 + +smsc_parambit.conf +file + + + + +2012-12-28T03:06:22.875000Z +c596c5d249e717db67ab93e6f0a4f7f2 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +2836 + +sccp.conf +file + + + + +2012-12-28T03:06:22.890625Z +c21dfd2bc924fb2b6a557d5c2bb77451 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +1142 + +system.ini.100k +file + + + + +2012-12-28T03:06:22.890625Z +e7d4f8e1f1e20d9863a718c0f4f9df46 +2011-09-23T09:01:37.023785Z +1 +xueqiang.sheng +has-props + + + + + + + + + + + + + + + + + + + + +212 + diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/.sccp.conf.swo.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/.sccp.conf.swo.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/.sccp.conf.swo.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/HlrSysPara.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/HlrSysPara.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/HlrSysPara.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_acn.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_acn.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_operation.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_operation.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cap_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cc_table.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cc_table.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/cc_table.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/conf.rar.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/conf.rar.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/conf.rar.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/conv_prefix.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/conv_prefix.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/conv_prefix.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/hae_sys.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/hae_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/hae_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/help_page.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/help_page.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/help_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/hlr_parambit.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/iptrans.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/iptrans.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/iptrans.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_acn.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_acn.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_acn.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_operation.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_operation.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/map_operation.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/menu_page.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/menu_page.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/menu_page.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/mtp3.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/mtp3.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/mtp3.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/ppsConf.txt.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/ppsConf.txt.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/ppsConf.txt.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/profile.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/profile.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/profile.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/sccp.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/sccp.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/sccp.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_csta.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_csta.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_csta.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_parambit.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_sys.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/smsc_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.100k.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.100k.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.100k.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.30K.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.30K.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.30K.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.ini.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.inimscvlrhlr.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.inimscvlrhlr.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/system.inimscvlrhlr.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2_sys.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2exit.txt.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2exit.txt.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/wxc2exit.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base new file mode 100644 index 0000000..197a54a --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/xap_sysparam.conf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/prop-base/xapp_test.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/xapp_test.conf.svn-base new file mode 100644 index 0000000..d37cebc --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/prop-base/xapp_test.conf.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/.sccp.conf.swo.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/.sccp.conf.swo.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..847a816cf68ebf7ae90da983d3437f7e36d4f4fd GIT binary patch literal 12288 zcmeI2&2G~`6oqdQAXWTTuw!*0NWdboXOc9I#0Di5id3SiX}hVa$W78V!o*f=XeAzi z6)(UNgxK)_EP*vUSR=uPS3u(DjO~)t4J7O8Ug>yp$8&sVK993VylrnZ?sK`|5MqJo zbn9d7*^e{yskB$@PV~|(9uJupshW(*M962 zRNNDIZe$&}K@cC>Q7??Fjz8G3!cHeBm`^j5k|9Ds2plJ{UewCYUBAXxF0UUyD?LI$ z2nYcoAOwVf5D)@FKnR>@0#PtWzp=to&{b$I6&eX4AOwVf5D)@FKnMr{As_^VfDjM@ zLg0iDaJxh|&k?V!9H-K-Kh`vIfq1TWH-GLUMPZx=vLv82=^!)O?ci znQQvoT;W#a4x@U1w;zSL6!X%cJC-pw8{9IJ#zc9w!FQ4J6613(pv`-0Ywb06+v{zS zE|<&%P2}U_=%6aPpzv~V5sm3h^J+CoNtLjY#G0%aD^X@)e~13Zip6KGagoC+|Fmjj z8@C#?syL}?WkDvUp3C@Rn5AxR&#HsTa~GhwSwF%)=3ivxmm1}CX8D>gEc0S zop5<3YfNO^n(pOMRb4CvT+%t7>%bb zUUxD+vnLM6D~*jlKk_S`>~hM5;eeBGfrnu~><%y{jed}9_ED~AbJ@IQ&rQFJXNz*J aT5W}EcyqqL%R7Cq$G29U4ZCd@Z_^*Ce+d!* literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/HlrSysPara.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/HlrSysPara.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..610468884f41c7f2e8b0e720cf80bc884fd22b3d GIT binary patch literal 7244 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 literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/conv_prefix.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/conv_prefix.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..bcd6108eb43833a985a9c46b761cfe4778151c0d GIT binary patch literal 4608 zcmeIuI}U&_41?hYi2-pLmKM1G#ds`E%Re%j$+6NPeQ}oIn~%2Fn#JeD%`<1@wk z>T@hFt}&b`F&!;$Ja_JY_g6kUOAK#l^bV=0vyUt&*@slr*+&+X>_aN*>>~?G_8}E@ m_K^i8`;dw{`^bWleMm)}ePlt&KBS_~KC+->A5u~Gm(K-CiUoH7 literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/hae_sys.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/hae_sys.conf.svn-base new file mode 100644 index 0000000..2e830a6 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/hae_sys.conf.svn-base @@ -0,0 +1,6 @@ +#HLR/AUC/EIR system configure file + +#IP info of SMSC +hlr-0=172.18.234.1; +#hlr-1=172.18.133.1; +hlr-1=172.54.240.147; diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/help_page.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/help_page.svn-base new file mode 100644 index 0000000..0746e55 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/help_page.svn-base @@ -0,0 +1,20 @@ + + ****************** + * HELP PAGE * + ****************** + + Welcome to DEBUG MONITOR. + + Press 's' or 'S' to enter "SUB MODULE SELECTION PAGE". + + In "SUB MODULE SELECTION PAGE", + Press 'x' or 'X' to return "HELP PAGE", + Press 'a-p' or 'A-P' to select sub module. + + In each sub module, Press '0-9' and 'a-f' to select pages. + + There are two methods to use Debug, + 1. Serial Port, use PC-to-PC serial line. + 2. Telnet, use "telnet dst_host_ip 4965". + +$ diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/hlr_parambit.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/hlr_parambit.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..8497c6f601155f75ff3c392b591bfca0b7623c67 GIT binary patch literal 20740 zcmeI)xo+J?6vpu@!8H+B{UG9I+-Be<%)M%eII*3$A!uf0;X!uNDW*;}uxwpf@#`x6vL)Lx zujkWwJKy-8uYB#Ne&!qB`p$3sKJWq+=pYTUzyvmMK_7ad3U!!pu zojE`E*WCHJ!OR(NHqu50;>k3Mwg$5z`^zCLc$?#JF+Mx92$$e8EWrep;R>w4DqMwY za2;+y12Nh1GnHd+=08$!#%hU58xp@g2(U#p29PD4lm#(yn7C*1drhfJcVcQ9A3an zcm=!g8s5NLcn9x+!vZY80xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd75 z0xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xa-9 Y3rz99xDWG@EI7_&ZvRZ59NFLh14RLh?*IS* literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/iptrans.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/iptrans.conf.svn-base new file mode 100644 index 0000000..b9b9d03 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/iptrans.conf.svn-base @@ -0,0 +1,17 @@ +#ipconfig for pps +#port=type,num,interface +#type=UDP/TCP +#num=0-6 +#interface=BUFFER/DIRECT +4950=UDP,6,DIRECT +4952=UDP,2,BUFFER +4953=UDP,3,BUFFER +4954=UDP,3,BUFFER +4955=UDP,3,BUFFER +4957=UDP,4,BUFFER +4960=UDP,3,BUFFER +4965=TCP,3,BUFFER +4969=UDP,3,BUFFER +4970=UDP,3,BUFFER +4971=UDP,2,BUFFER +4972=UDP,2,BUFFER diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/map_acn.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/map_acn.conf.svn-base new file mode 100644 index 0000000..7c3094e --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/map_acn.conf.svn-base @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 02 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/map_operation.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/map_operation.conf.svn-base new file mode 100644 index 0000000..4c08ef0 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/map_operation.conf.svn-base @@ -0,0 +1,76 @@ +# operation code configure file +total data length=72 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:09 01 20 // send parameters +No.64:48 01 20 // not subscriber present +No.65:19 01 20 // process unstructure SS data +No.66:54 01 20 // beging subscriber activity +No.67:28 01 20 // perform handover +No.68:30 01 20 // perform subsequence handvoer +No.69:35 01 20 // note internal handover +No.70:54 01 20 // beging subscriber activity +No.71:49 01 20 // alert service center without result +No.72:52 01 20 // trace subscriber activity \ No newline at end of file diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/menu_page.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/menu_page.svn-base new file mode 100644 index 0000000..facf381 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/menu_page.svn-base @@ -0,0 +1,13 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- PPS + d -- TCAP l -- SNMP + e -- XAPP m -- + f -- MSC n -- DEBUG + g -- VLR o -- AUC + h -- p -- EIR diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/mtp3.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/mtp3.conf.svn-base new file mode 100644 index 0000000..dd315c0 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/mtp3.conf.svn-base @@ -0,0 +1,1408 @@ +#MTP3 CONFIGURE FILE + +[SERVICE NETWORK SP LEN] +[00] + +[LOCAL SP] +[000000] [000000] [000028] [000000] +[000000] [000000] [000000] [000000] + +[LINK ATTRIBUTE] +[00.00.ea] [11.00.62] [80.10.ff] [10.00.62] +[14.00.62] [08.00.62] [4e.00.62] [80.10.ff] +[80.10.ff] [12.00.62] [80.10.ff] [0a.00.62] +[0b.00.62] [0c.00.62] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [11.01.63] [80.10.ff] [10.01.63] +[14.01.63] [08.02.63] [4f.00.63] [80.10.ff] +[80.10.ff] [12.01.63] [80.10.ff] [0a.01.63] +[0b.01.63] [0c.01.63] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] + +[LINKSET ATTRIBUTE] +[000028.02] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] + +[NATIONAL NETWORK SP] +[000028.00.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000008.08.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[NATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[LOCAL ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +010303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/ppsConf.txt.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/ppsConf.txt.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..b556699c6ff5344e6c9e9f74f686c509576fda12 GIT binary patch literal 28340 zcmeI5y>1gh5PV~Yowt>l)M2Q zQV`I=&hFX!W1_PnCkoQHl5;zI&y*vC-yg9U)6Z;aSD~@A5X+*!4Olu81ets-+ ze2nw!bNeh)>Qiz(xrUVe`!%vDKPP4GP5ikN1o~=Fud6|jowHeIHYRoX?JAL1nI@?s z#*-WgrB;v5maCWDQXM^Ao;^&l=~Ps@D15cb%Gct_>T7xG>Yq}V zs#+KC>Db%0)-LyCF_^hs+s4e&Z^b)CEy>+eFB_X8IlRlCZ!-O6K)=oO+X4M9)9(iK zr`mKs+JpABevZk0st1`iJX}mz3hSaku;1IM
vl8pnb3dO4ea@%fNB;f5 z2R@d-ras~ynLp6}2oU_k{V$g7{*CrCt1tA=X?>ynNO|BNDG&T3<$-^sJn)Z{2mX=r KxEcSj*Z2#4+qSC! literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/profile.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/profile.svn-base new file mode 100644 index 0000000..da7324f --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/profile.svn-base @@ -0,0 +1,37 @@ +# /etc/profile + +# System wide environment and startup programs +# Functions and aliases go in /etc/bashrc + +PATH=".:$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/etc/rc.d/init.d:/usr/local/wxc2/bin" +PATH=/usr/java/jdk1.3/bin:$PATH + +ulimit -c 80000 +if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then + umask 002 +else + umask 022 +fi + +USER=`id -un` +LOGNAME=$USER +MAIL="/var/spool/mail/$USER" + +HOSTNAME=`/bin/hostname` +HISTSIZE=1000 + +if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then + INPUTRC=/etc/inputrc +fi +JAVA_COMPILER=javacomp ; export JAVA_COMPILER +LD_LIBRARY_PATH=/usr/local/mysql/lib ; export LD_LIBRARY_PATH +export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC + +for i in /etc/profile.d/*.sh ; do + if [ -x $i ]; then + . $i + fi +done + +unset i +PATH=/usr/local/wxc2/bin:$PATH diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/sccp.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/sccp.conf.svn-base new file mode 100644 index 0000000..6f4a9a7 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/sccp.conf.svn-base @@ -0,0 +1,26 @@ +#SCCP Config file (R8V0_03) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 2 - 172.18.128.1 172.18.129.1 +6 2 8675557122002 172.18.199.1 - +7 2 8675557122001 172.18.198.1 - +8 2 8675599999999 172.18.234.3 172.18.99.1 +9 2 86755920005 172.18.132.1 172.18.99.1 +10 2 86755920004 172.18.132.1 172.18.99.1 +11 2 86755920006 172.18.132.1 172.18.99.1 +19 2 86755920007 172.18.132.1 172.18.99.1 +20 2 86755920008 172.18.132.1 172.18.99.1 +21 2 86755920009 172.18.132.1 172.18.99.1 +22 2 867559000213 172.18.132.1 - +146 2 86755920011 172.18.132.1 172.18.99.1 +147 2 86755920010 172.18.132.1 172.18.99.1 +254 2 - 172.18.132.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 460020000000000 460029999999999 2 000028 6 0 7 +#1 1 8675590000000 8675599999998 2 000028 6 0 7 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_csta.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_csta.conf.svn-base new file mode 100644 index 0000000..a9a11f0 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_csta.conf.svn-base @@ -0,0 +1,21 @@ +# This file defines the SMSC CSTA row +# The max number of row is 20 +# Attention: When you want to define the Entity name, the name of "MS" "All" and "Other" is reserved + +# define the entity who send short message to SMSC +Receive from: +MS +PPS +VMS +#VMS+PPS +Other +#All + +# define the entity who receive short message from SMSC +Send to: +MS +PPS +VMS +#VMS+PPS +Other +#All diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_parambit.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_parambit.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..cc4473d3930958eb4c721128deefdb0d14fe7117 GIT binary patch literal 2836 zcmeHHy-or_5Z*0lC@8M8G1pmX0L2$j%2Sd<6BDi|nQw2g)=skM+8S7Bt(!a!Vsq!cG2dUt;MSOi_vq}*X6(df z3eI_Qf@#LlbJ+oW0cy1mk2?6q<8nYjWbPBm^7Iex@LFHaA6$mY5a2vD*e1XCs zhdTxgIzfCt$T7g-I>hnp9qTpqKDK$UQfJ9( zob;eNF*FJbr@MIA1NDns?6D3%=^KH|gfu~Sy+ze+LwL}WRmLOdD>2$?yqKq$;&1b` zhiQ`Xr=%%pukn62?Gvz)$B|xIx6F$YQ@tx3x-^2G4o2=+(;ES33_kQuRDC zZW&LSbcgBLse~+9jjQkN%G19Xr)ACi_bhUx-3`1F4H1R=zMo%c4pvW%2Rwt1UAU(q z51fzi=<~rkEmb?*YJ7p`V9tZRXVKeAp0MUdKFlNMA^EZobrWo33p}Ec)ToL__gy8A i%!0Nmo{(e9qt#fk5ALZ%Y|lrO_{IKH-LmL~CjSBF9jD9y literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_sys.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_sys.conf.svn-base new file mode 100644 index 0000000..a36c5f3 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/smsc_sys.conf.svn-base @@ -0,0 +1,5 @@ +#SMSC system configure file + +#IP info of SMSC +wxc2-0=172.18.98.1; +wxc2-1=172.18.99.1; diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.100k.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.100k.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..2b5124e1888a0c1b29289e86924f0881679f89be GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffnMzAh#&^F)%D>V?@CqF%Sj;69X4#16LzU M6Js|gCo^LU0Q9{MnE(I) literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.30K.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.30K.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..814c2c85df9a7026c04c4200c069f510a71e63e2 GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffnMzAh#&^F)$dEqGFI32!nuyg`uIdg@LK7 LsjHExo2fYfruhth literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/system.ini.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..775a1a33efc5d5ae6d752e86370eb923443ee529 GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffm9r%x+}9f*%9Jf;L7l2C^63p2ffj-=GC<}l_%SdnXk%mm(dZbY$I{Z=*xbUv N)XBij(9Ouj8~~+c3|RmG literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2_sys.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2_sys.conf.svn-base new file mode 100644 index 0000000..45f407f --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2_sys.conf.svn-base @@ -0,0 +1 @@ +pps-1=172.18.98.1; diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2exit.txt.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2exit.txt.svn-base new file mode 100644 index 0000000..4229e83 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/wxc2exit.txt.svn-base @@ -0,0 +1,4 @@ +WXC2 procedure exit log + Time: Fri Nov 5 05:27:51 2004 + +Now module: MSC diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/xap_sysparam.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/xap_sysparam.conf.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..2bc914e6193e787454bbf6b5dfe5804653a2bf5b GIT binary patch literal 13 UcmZ?cV`_U>8uyOj9pAfm03>Y&WB>pF literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/.svn/text-base/xapp_test.conf.svn-base b/plat/xapp/ut/xapp_test/conf/.svn/text-base/xapp_test.conf.svn-base new file mode 100644 index 0000000..668a293 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/.svn/text-base/xapp_test.conf.svn-base @@ -0,0 +1,2 @@ +172.18.199.1 +2000 diff --git a/plat/xapp/ut/xapp_test/conf/HlrSysPara b/plat/xapp/ut/xapp_test/conf/HlrSysPara new file mode 100644 index 0000000000000000000000000000000000000000..610468884f41c7f2e8b0e720cf80bc884fd22b3d GIT binary patch literal 7244 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 literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/conv_prefix.conf b/plat/xapp/ut/xapp_test/conf/conv_prefix.conf new file mode 100644 index 0000000000000000000000000000000000000000..bcd6108eb43833a985a9c46b761cfe4778151c0d GIT binary patch literal 4608 zcmeIuI}U&_41?hYi2-pLmKM1G#ds`E%Re%j$+6NPeQ}oIn~%2Fn#JeD%`<1@wk z>T@hFt}&b`F&!;$Ja_JY_g6kUOAK#l^bV=0vyUt&*@slr*+&+X>_aN*>>~?G_8}E@ m_K^i8`;dw{`^bWleMm)}ePlt&KBS_~KC+->A5u~Gm(K-CiUoH7 literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/hae_sys.conf b/plat/xapp/ut/xapp_test/conf/hae_sys.conf new file mode 100644 index 0000000..2e830a6 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/hae_sys.conf @@ -0,0 +1,6 @@ +#HLR/AUC/EIR system configure file + +#IP info of SMSC +hlr-0=172.18.234.1; +#hlr-1=172.18.133.1; +hlr-1=172.54.240.147; diff --git a/plat/xapp/ut/xapp_test/conf/help_page b/plat/xapp/ut/xapp_test/conf/help_page new file mode 100644 index 0000000..0746e55 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/help_page @@ -0,0 +1,20 @@ + + ****************** + * HELP PAGE * + ****************** + + Welcome to DEBUG MONITOR. + + Press 's' or 'S' to enter "SUB MODULE SELECTION PAGE". + + In "SUB MODULE SELECTION PAGE", + Press 'x' or 'X' to return "HELP PAGE", + Press 'a-p' or 'A-P' to select sub module. + + In each sub module, Press '0-9' and 'a-f' to select pages. + + There are two methods to use Debug, + 1. Serial Port, use PC-to-PC serial line. + 2. Telnet, use "telnet dst_host_ip 4965". + +$ diff --git a/plat/xapp/ut/xapp_test/conf/hlr_parambit.conf b/plat/xapp/ut/xapp_test/conf/hlr_parambit.conf new file mode 100644 index 0000000000000000000000000000000000000000..8497c6f601155f75ff3c392b591bfca0b7623c67 GIT binary patch literal 20740 zcmeI)xo+J?6vpu@!8H+B{UG9I+-Be<%)M%eII*3$A!uf0;X!uNDW*;}uxwpf@#`x6vL)Lx zujkWwJKy-8uYB#Ne&!qB`p$3sKJWq+=pYTUzyvmMK_7ad3U!!pu zojE`E*WCHJ!OR(NHqu50;>k3Mwg$5z`^zCLc$?#JF+Mx92$$e8EWrep;R>w4DqMwY za2;+y12Nh1GnHd+=08$!#%hU58xp@g2(U#p29PD4lm#(yn7C*1drhfJcVcQ9A3an zcm=!g8s5NLcn9x+!vZY80xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd75 z0xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xZA+EWiRRzyd750xa-9 Y3rz99xDWG@EI7_&ZvRZ59NFLh14RLh?*IS* literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/iptrans.conf b/plat/xapp/ut/xapp_test/conf/iptrans.conf new file mode 100644 index 0000000..b9b9d03 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/iptrans.conf @@ -0,0 +1,17 @@ +#ipconfig for pps +#port=type,num,interface +#type=UDP/TCP +#num=0-6 +#interface=BUFFER/DIRECT +4950=UDP,6,DIRECT +4952=UDP,2,BUFFER +4953=UDP,3,BUFFER +4954=UDP,3,BUFFER +4955=UDP,3,BUFFER +4957=UDP,4,BUFFER +4960=UDP,3,BUFFER +4965=TCP,3,BUFFER +4969=UDP,3,BUFFER +4970=UDP,3,BUFFER +4971=UDP,2,BUFFER +4972=UDP,2,BUFFER diff --git a/plat/xapp/ut/xapp_test/conf/map_acn.conf b/plat/xapp/ut/xapp_test/conf/map_acn.conf new file mode 100644 index 0000000..7c3094e --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/map_acn.conf @@ -0,0 +1,42 @@ +#application context name configure file +total data length=36 + +#application context name data +No.1:01 03 // network location update +No.2:02 03 // location cancel +No.3:03 03 // roaming number enquiry +No.4:05 03 // location info retrieval +No.5:10 02 // reset context +No.6:11 02 // handover control +No.7:13 02 // equipment management +No.8:14 02 // info retrieval +No.9:15 02 // inter VLR info retrieval +No.10:16 03 // subscriber data management +No.11:17 03 // tracing +No.12:18 02 // network functional SS +No.13:19 02 // network unstructured SS +No.14:20 03 // short message gateway +No.15:21 03 // short message MO relay +No.16:23 02 // short message alert +No.17:24 03 // short message waiting data management +No.18:25 03 // mobile terminating short message relay +No.19:26 02 // imsi retrieval +No.20:27 03 // MS purging +No.21:28 03 // subscriber info enquiry +No.22:29 03 // any time info enquiry +No.23:06 03 // call control transfer +No.24:36 03 // invocation notification +No.25:12 03 // sIWFS allocation +No.26:31 03 // group call control +No.27:32 03 // GPRS location update +No.28:33 03 // GPRS location info retrieval +No.29:34 03 // failure report +No.30:35 03 // GPRS notify +No.31:07 03 // reporting +No.32:08 03 // call completion +No.33:200 02 // security triplets (MAP-H defined by Meng Xiaozhen) +No.34:201 02 // subscriber interrogate (MAP-H defined by Meng Xiaozhen) +No.35:202 02 // HLR subscriber management (MAP-H defined by Meng Xiaozhen) +No.36:203 02 // HLR ping AUC (MAP-H defined by Meng Xiaozhen reserved) +NO.37:09 01 // Send parameter + diff --git a/plat/xapp/ut/xapp_test/conf/map_operation.conf b/plat/xapp/ut/xapp_test/conf/map_operation.conf new file mode 100644 index 0000000..4c08ef0 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/map_operation.conf @@ -0,0 +1,76 @@ +# operation code configure file +total data length=72 + +#operation code +No.1:02 01 20 // update location +No.2:03 01 10 // cancel location +No.3:67 01 20 // purge mobile station +No.4:55 01 05 // send identification +No.5:68 01 20 // prepare handover +No.6:29 03 108000 // send end signal +No.7:33 04 05 // process access signalling +No.8:34 04 05 // forward access signalling +No.9:69 01 20 // prepare subsequent handover +No.10:56 01 20 // send authentication info +No.11:43 01 20 // check IMEI +No.12:07 01 20 // insert subscriber data +No.13:08 01 20 // delete subscriber data +No.14:37 04 20 // reset +No.15:38 04 20 // forward check ss indication +No.16:57 01 20 // restore data +No.17:50 01 20 // active trace mode +No.18:51 01 20 // deactive trace mode +No.19:58 01 20 // send imsi +No.20:22 01 20 // send routing info +No.21:04 01 20 // provide roaming number +No.22:06 01 20 // resume call handling +No.23:31 01 20 // provide SIWFS number +No.24:32 01 20 // SIWFS signalling modify +No.25:73 01 20 // set report state +No.26:74 01 20 // status report +No.27:75 01 60 // remote user free +No.28:10 01 20 // register ss +No.29:11 01 20 // erase ss +No.30:12 01 20 // activate ss +No.31:13 01 20 // deactivate ss +No.32:14 01 20 // interrogate ss +No.33:59 01 600 // process unstructure ss request +No.34:60 01 60 // unstructure ss request +No.35:61 01 60 // unstructure ss notify +No.36:17 01 60 // register password +No.37:18 03 20 // get password +No.38:76 01 20 // register cc entry +No.39:77 01 20 // erase cc entry +No.40:45 01 20 // send routing info for sm +No.41:46 01 60 // mo forward sm +No.42:44 01 60 // mt forward sm +No.43:47 01 05 // report sm delivery status +No.44:63 04 05 // inform service centre +No.45:64 01 05 // alert service center +No.46:66 01 05 // ready for sm +No.47:70 01 20 // provider subscriber info +No.48:71 01 20 // any time interrogation +No.49:72 01 20 // ss invocatin notification +No.50:39 01 20 // prepare group call +No.51:40 03 108000 // send group call end signal +No.52:41 04 05 // process group call signalling +No.53:42 04 05 // forward group call signalling +No.54:23 01 20 // update GPRS location +No.55:24 01 20 // send routing info for GPRS +No.56:25 01 20 // failure report +No.57:26 01 20 // note ms present for GPRS +No.58:200 01 05 // security triplets (MAP-H defined by Meng Xiaozhen) +No.59:201 01 05 // interrogate subscriber (MAP-H defined by Meng Xiaozhen) +No.60:202 01 05 // hlr create subscriber (MAP-H defined by Meng Xiaozhen) +No.61:203 01 05 // hlr delete subscriber (MAP-H defined by Meng Xiaozhen) +No.62:204 01 05 // hlr ping auc (MAP-H defined by Meng Xiaozhen reserved) +No.63:09 01 20 // send parameters +No.64:48 01 20 // not subscriber present +No.65:19 01 20 // process unstructure SS data +No.66:54 01 20 // beging subscriber activity +No.67:28 01 20 // perform handover +No.68:30 01 20 // perform subsequence handvoer +No.69:35 01 20 // note internal handover +No.70:54 01 20 // beging subscriber activity +No.71:49 01 20 // alert service center without result +No.72:52 01 20 // trace subscriber activity \ No newline at end of file diff --git a/plat/xapp/ut/xapp_test/conf/menu_page b/plat/xapp/ut/xapp_test/conf/menu_page new file mode 100644 index 0000000..facf381 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/menu_page @@ -0,0 +1,13 @@ + + ******************* + * MENU PAGE * + ******************* + + a -- IPTR i -- HLR + b -- MTP3 j -- SMSC + c -- SCCP k -- PPS + d -- TCAP l -- SNMP + e -- XAPP m -- + f -- MSC n -- DEBUG + g -- VLR o -- AUC + h -- p -- EIR diff --git a/plat/xapp/ut/xapp_test/conf/mtp3.conf b/plat/xapp/ut/xapp_test/conf/mtp3.conf new file mode 100644 index 0000000..dd315c0 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/mtp3.conf @@ -0,0 +1,1408 @@ +#MTP3 CONFIGURE FILE + +[SERVICE NETWORK SP LEN] +[00] + +[LOCAL SP] +[000000] [000000] [000028] [000000] +[000000] [000000] [000000] [000000] + +[LINK ATTRIBUTE] +[00.00.ea] [11.00.62] [80.10.ff] [10.00.62] +[14.00.62] [08.00.62] [4e.00.62] [80.10.ff] +[80.10.ff] [12.00.62] [80.10.ff] [0a.00.62] +[0b.00.62] [0c.00.62] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [11.01.63] [80.10.ff] [10.01.63] +[14.01.63] [08.02.63] [4f.00.63] [80.10.ff] +[80.10.ff] [12.01.63] [80.10.ff] [0a.01.63] +[0b.01.63] [0c.01.63] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] +[80.10.ff] [80.10.ff] [80.10.ff] [80.10.ff] + +[LINKSET ATTRIBUTE] +[000028.02] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] +[000000.00] [000000.00] [000000.00] [000000.00] + +[NATIONAL NETWORK SP] +[000028.00.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000008.08.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[NATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[INTERNATIONAL NETWORK SPARE SP] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] +[000000.80.80] [000000.80.80] [000000.80.80] [000000.80.80] + +[LOCAL ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[INTERNATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +010303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + +[NATIONAL NETWORK SPARE ACN] +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 +030303030202020202030302020303020303020303030303030303030303030302020202 + diff --git a/plat/xapp/ut/xapp_test/conf/ppsConf.txt b/plat/xapp/ut/xapp_test/conf/ppsConf.txt new file mode 100644 index 0000000000000000000000000000000000000000..b556699c6ff5344e6c9e9f74f686c509576fda12 GIT binary patch literal 28340 zcmeI5y>1gh5PV~Yowt>l)M2Q zQV`I=&hFX!W1_PnCkoQHl5;zI&y*vC-yg9U)6Z;aSD~@A5X+*!4Olu81ets-+ ze2nw!bNeh)>Qiz(xrUVe`!%vDKPP4GP5ikN1o~=Fud6|jowHeIHYRoX?JAL1nI@?s z#*-WgrB;v5maCWDQXM^Ao;^&l=~Ps@D15cb%Gct_>T7xG>Yq}V zs#+KC>Db%0)-LyCF_^hs+s4e&Z^b)CEy>+eFB_X8IlRlCZ!-O6K)=oO+X4M9)9(iK zr`mKs+JpABevZk0st1`iJX}mz3hSaku;1IM
vl8pnb3dO4ea@%fNB;f5 z2R@d-ras~ynLp6}2oU_k{V$g7{*CrCt1tA=X?>ynNO|BNDG&T3<$-^sJn)Z{2mX=r KxEcSj*Z2#4+qSC! literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/profile b/plat/xapp/ut/xapp_test/conf/profile new file mode 100644 index 0000000..da7324f --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/profile @@ -0,0 +1,37 @@ +# /etc/profile + +# System wide environment and startup programs +# Functions and aliases go in /etc/bashrc + +PATH=".:$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/etc/rc.d/init.d:/usr/local/wxc2/bin" +PATH=/usr/java/jdk1.3/bin:$PATH + +ulimit -c 80000 +if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then + umask 002 +else + umask 022 +fi + +USER=`id -un` +LOGNAME=$USER +MAIL="/var/spool/mail/$USER" + +HOSTNAME=`/bin/hostname` +HISTSIZE=1000 + +if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then + INPUTRC=/etc/inputrc +fi +JAVA_COMPILER=javacomp ; export JAVA_COMPILER +LD_LIBRARY_PATH=/usr/local/mysql/lib ; export LD_LIBRARY_PATH +export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC + +for i in /etc/profile.d/*.sh ; do + if [ -x $i ]; then + . $i + fi +done + +unset i +PATH=/usr/local/wxc2/bin:$PATH diff --git a/plat/xapp/ut/xapp_test/conf/sccp.conf b/plat/xapp/ut/xapp_test/conf/sccp.conf new file mode 100644 index 0000000..6f4a9a7 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/sccp.conf @@ -0,0 +1,26 @@ +#SCCP Config file (R8V0_03) + +[Local Node] +#ssn NetID msisdn ip0 ip1 +4 2 - 172.18.128.1 172.18.129.1 +6 2 8675557122002 172.18.199.1 - +7 2 8675557122001 172.18.198.1 - +8 2 8675599999999 172.18.234.3 172.18.99.1 +9 2 86755920005 172.18.132.1 172.18.99.1 +10 2 86755920004 172.18.132.1 172.18.99.1 +11 2 86755920006 172.18.132.1 172.18.99.1 +19 2 86755920007 172.18.132.1 172.18.99.1 +20 2 86755920008 172.18.132.1 172.18.99.1 +21 2 86755920009 172.18.132.1 172.18.99.1 +22 2 867559000213 172.18.132.1 - +146 2 86755920011 172.18.132.1 172.18.99.1 +147 2 86755920010 172.18.132.1 172.18.99.1 +254 2 - 172.18.132.1 172.18.99.1 +[GTT_Table] +#No NP StartDigits EndDigits NI SPC SSN RI AI S E N Rep +0 6 460020000000000 460029999999999 2 000028 6 0 7 +#1 1 8675590000000 8675599999998 2 000028 6 0 7 + +[RL_SSN] +#NetID DPC SSN + diff --git a/plat/xapp/ut/xapp_test/conf/smsc_csta.conf b/plat/xapp/ut/xapp_test/conf/smsc_csta.conf new file mode 100644 index 0000000..a9a11f0 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/smsc_csta.conf @@ -0,0 +1,21 @@ +# This file defines the SMSC CSTA row +# The max number of row is 20 +# Attention: When you want to define the Entity name, the name of "MS" "All" and "Other" is reserved + +# define the entity who send short message to SMSC +Receive from: +MS +PPS +VMS +#VMS+PPS +Other +#All + +# define the entity who receive short message from SMSC +Send to: +MS +PPS +VMS +#VMS+PPS +Other +#All diff --git a/plat/xapp/ut/xapp_test/conf/smsc_parambit.conf b/plat/xapp/ut/xapp_test/conf/smsc_parambit.conf new file mode 100644 index 0000000000000000000000000000000000000000..cc4473d3930958eb4c721128deefdb0d14fe7117 GIT binary patch literal 2836 zcmeHHy-or_5Z*0lC@8M8G1pmX0L2$j%2Sd<6BDi|nQw2g)=skM+8S7Bt(!a!Vsq!cG2dUt;MSOi_vq}*X6(df z3eI_Qf@#LlbJ+oW0cy1mk2?6q<8nYjWbPBm^7Iex@LFHaA6$mY5a2vD*e1XCs zhdTxgIzfCt$T7g-I>hnp9qTpqKDK$UQfJ9( zob;eNF*FJbr@MIA1NDns?6D3%=^KH|gfu~Sy+ze+LwL}WRmLOdD>2$?yqKq$;&1b` zhiQ`Xr=%%pukn62?Gvz)$B|xIx6F$YQ@tx3x-^2G4o2=+(;ES33_kQuRDC zZW&LSbcgBLse~+9jjQkN%G19Xr)ACi_bhUx-3`1F4H1R=zMo%c4pvW%2Rwt1UAU(q z51fzi=<~rkEmb?*YJ7p`V9tZRXVKeAp0MUdKFlNMA^EZobrWo33p}Ec)ToL__gy8A i%!0Nmo{(e9qt#fk5ALZ%Y|lrO_{IKH-LmL~CjSBF9jD9y literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/smsc_sys.conf b/plat/xapp/ut/xapp_test/conf/smsc_sys.conf new file mode 100644 index 0000000..a36c5f3 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/smsc_sys.conf @@ -0,0 +1,5 @@ +#SMSC system configure file + +#IP info of SMSC +wxc2-0=172.18.98.1; +wxc2-1=172.18.99.1; diff --git a/plat/xapp/ut/xapp_test/conf/system.ini b/plat/xapp/ut/xapp_test/conf/system.ini new file mode 100644 index 0000000000000000000000000000000000000000..775a1a33efc5d5ae6d752e86370eb923443ee529 GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffm9r%x+}9f*%9Jf;L7l2C^63p2ffnMzAh#&^F)%D>V?@CqF%Sj;69X4#16LzU M6Js|gCo^LU0Q9{MnE(I) literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/system.ini.30K b/plat/xapp/ut/xapp_test/conf/system.ini.30K new file mode 100644 index 0000000000000000000000000000000000000000..814c2c85df9a7026c04c4200c069f510a71e63e2 GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffnMzAh#&^F)$dEqGFI32!nuyg`uIdg@LK7 LsjHExo2fYfruhth literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/system.inimscvlrhlr b/plat/xapp/ut/xapp_test/conf/system.inimscvlrhlr new file mode 100644 index 0000000000000000000000000000000000000000..53e9e53989e8c3fcc89159a692cdd27c5c32ccf5 GIT binary patch literal 212 zcmZQ%U|=Y(NH$7QC`v6ZNh~S>^63p2ffj-=GC<}l_%SdnXk%mm(dZbY$I{Z=*xbUv N)XBij(9Ouj8~~+c3|RmG literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/wxc2_sys.conf b/plat/xapp/ut/xapp_test/conf/wxc2_sys.conf new file mode 100644 index 0000000..45f407f --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/wxc2_sys.conf @@ -0,0 +1 @@ +pps-1=172.18.98.1; diff --git a/plat/xapp/ut/xapp_test/conf/wxc2exit.txt b/plat/xapp/ut/xapp_test/conf/wxc2exit.txt new file mode 100644 index 0000000..4229e83 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/wxc2exit.txt @@ -0,0 +1,4 @@ +WXC2 procedure exit log + Time: Fri Nov 5 05:27:51 2004 + +Now module: MSC diff --git a/plat/xapp/ut/xapp_test/conf/xap_sysparam.conf b/plat/xapp/ut/xapp_test/conf/xap_sysparam.conf new file mode 100644 index 0000000000000000000000000000000000000000..2bc914e6193e787454bbf6b5dfe5804653a2bf5b GIT binary patch literal 13 UcmZ?cV`_U>8uyOj9pAfm03>Y&WB>pF literal 0 HcmV?d00001 diff --git a/plat/xapp/ut/xapp_test/conf/xapp_test.conf b/plat/xapp/ut/xapp_test/conf/xapp_test.conf new file mode 100644 index 0000000..668a293 --- /dev/null +++ b/plat/xapp/ut/xapp_test/conf/xapp_test.conf @@ -0,0 +1,2 @@ +172.18.199.1 +2000 diff --git a/plat/xapp/ut/xapp_test/xapp_coding_test.c b/plat/xapp/ut/xapp_test/xapp_coding_test.c new file mode 100644 index 0000000..3a38056 --- /dev/null +++ b/plat/xapp/ut/xapp_test/xapp_coding_test.c @@ -0,0 +1,652 @@ +/* XAPP coding test function c file */ +/* created by Liu Wei 2006-01-13 */ +/* Version 1.0 */ +/* ------------------------------------- */ + +#include "xapp_coding_test.h" +#include "xapp_main.h" + +CAP_Message CAP_Com_OpenResponse = { + {0, 16} + , + CAP_FLAG, + {0, 0, 0} + , + {0, 0, 0} + , + CAP_O_OPEN, //CAP_O_OPEN, + CAP_RESPONSE, //RESPONSE, + {2, //RESULT=accept + 1, // + 1, //acn tag + 2, //len + 50, //acn + 2, //acn version + 0,} //end flag +}; + +CAP_Message CAP_Com_End = { + {0, 12} + , + CAP_FLAG, + {0, 0, 0} + , + {0, 0, 0} + , + CAP_O_END, //CAP_O_END, + CAP_REQUEST, //REQUEST, + {1, //release method + 0, //optional part + 0,} +}; + +int bcd_hton(BYTE * netbcd, const BYTE * hostbcd, BYTE max_octet) +{ + int i; + BYTE bcd_h, bcd_l; + + for(i = 0; i < max_octet; i++) + { + if((bcd_h = hostbcd[i] >> 4) == 0x0f) + return i * 2; + else if((bcd_l = hostbcd[i] & 0x0f) == 0x0f) + { + netbcd[i] = bcd_h & 0x0f; + return i * 2 + 1; + } + else + netbcd[i] = (bcd_l << 4) | bcd_h; + } + return i * 2; +} + +/* end by "F" */ +int bcd_ntoh(BYTE * hostbcd, const BYTE * netbcd, BYTE max_octet) +{ + int i; + int bcd_h, bcd_l; + + for(i = 0; i < max_octet; i++) + { + if((bcd_h = netbcd[i] & 0x0f) == 0x0f) + { + memset(&hostbcd[i], 0xff, max_octet - i); + return i * 2; + } + else if((bcd_l = netbcd[i] >> 4) == 0x0f) + { + hostbcd[i] = (bcd_h << 4) | 0x0f; + memset(&hostbcd[i + 1], 0xff, max_octet - i - 1); + return i * 2 + 1; + } + else + { + hostbcd[i] = (bcd_h << 4) | bcd_l; + } + } + return i * 2; +} + +void isdn_aton(u8 *normal_isdn,u8 *anti_isdn) +{ + u8 ii; + u8 aa=0,bb=0; + u8 isdn_len; + + isdn_len = anti_isdn[0]; + if (isdn_len > ISDN_LEN) + isdn_len = ISDN_LEN; + normal_isdn[0] = anti_isdn[1]; + for (ii = 1;ii < isdn_len;ii ++) + { + if ((anti_isdn[ii+1] & 0x0f) >= 0x0e) + break; + aa = (anti_isdn[ii+1] & 0x0f0) >> 4; + if (aa > 0x0c) + aa = 0x0e; + bb = anti_isdn[ii+1] & 0x0f; + normal_isdn[ii] = (bb << 4) + aa; + } + for (;ii < ISDN_LEN;ii ++) + normal_isdn[ii] = 0x0ee; +} + +void imsi_aton(u8 *normal_imsi,u8 *anti_imsi) +{ // the IMSI must 15 digits + u8 ii; + u8 aa,bb=0; + + normal_imsi[0] = 0; + for (ii = 0;ii < IMSI_LEN*2;ii++) + { + if ((ii % 2) == 1) + { + aa = anti_imsi[ii/2] & 0x0f; + normal_imsi[ii/2] |= aa; + } + else + { + if (ii/2 != IMSI_LEN -1) + { + bb = anti_imsi[ii/2] & 0x0f0; + normal_imsi[ii/2+1] = bb; + } + } + } +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* transfer IMSI format from normal to anti sequence */ +/* 0460022157127001 --> 64002251177200f1 */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +void imsi_ntoa(u8 *anti_imsi,u8 *normal_imsi) +{ + u8 ii; + u8 aa,bb=0; + + for (ii = 1;ii <= IMSI_LEN*2;ii++) + { + if ((ii % 2) == 1) + bb = normal_imsi[ii/2] & 0x0f; + else + { + if (ii == IMSI_LEN * 2) + aa = 0x0f0; + else + aa = normal_imsi[ii/2] & 0x0f0; + anti_imsi[ii/2-1] = aa | bb; + } + } +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* transfer IMSI format from normal to ascii string */ +/* 0460022157127001 --> "460022157127001" */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +void imsi_ntos(u8 *str_imsi,u8 *normal_imsi) +{ + u8 len; + u8 ii,jj; + + str_imsi[0] = (normal_imsi[0] & 0x0f) + '0'; + len = 1; + for (ii = 1;ii < IMSI_LEN;ii ++) + { + jj = (normal_imsi[ii] >> 4) & 0x0f; + str_imsi[len++] = jj + '0'; + jj = normal_imsi[ii] & 0x0f; + str_imsi[len++] = jj + '0'; + } + str_imsi[len] = '\0'; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* transfer IMSI format from ascii string to normal */ +/* "460022157127001" --> 0460022157127001 */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +void imsi_ston(u8 *normal_imsi,u8 *str_imsi) +{ + if (strlen(str_imsi) != IMSI_LEN*2-1) + return; + normal_imsi[0] = str_imsi[0] - '0'; + AsciiToBcd(normal_imsi+1,str_imsi+1,IMSI_LEN*2-2); +} +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* transfer ISDN format from normal to ascii string */ +/* 918675557127001EEE --> "8675557127001" */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +void isdn_ntos(u8 *str_isdn,u8 *normal_isdn) +{ + u8 len = 0; + u8 ii,jj; + + for (ii = 1;ii < ISDN_LEN;ii ++) + { + jj = (normal_isdn[ii] >> 4) & 0x0f; + if (jj > 0x0c) + break; + str_isdn[len++] = jj + '0'; + jj = normal_isdn[ii] & 0x0f; + if (jj > 0x0c) + break; + str_isdn[len++] = jj + '0'; + } + str_isdn[len] = '\0'; +} + +void isdn_ntoa(u8 * anti_isdn, u8 * normal_isdn) +{ + u8 ii; + u8 aa = 0, bb = 0; + u8 len; + + anti_isdn[1] = normal_isdn[0]; // nature of address and numbering plan indicator + len = 1; + for(ii = 1; ii < ISDN_LEN; ii++) + { + if(normal_isdn[ii] == 0xee) + break; + else + { + aa = (normal_isdn[ii] & 0x0f0) >> 4; + bb = normal_isdn[ii] & 0x0f; + if(bb > 0x0c) + bb = 0x0f; + anti_isdn[ii + 1] = (bb << 4) + aa; + len++; + } + } + anti_isdn[0] = len; +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +/* transfer ISDN format from ascii string to normal */ +/* "8675557127001" --> 918675557127001EEE */ +/* return value: 0--string has error; 1--success */ +/* +++++++++++++++++++++++++++++++++++++++++++++++++ */ +u8 isdn_ston(u8 *normal_isdn,u8 *str_isdn) +{ + u8 ii; + u8 len; + + len = strlen(str_isdn); + if (len > ISDN_LEN*2-2) + return 0; + if ((len % 2) == 1) // odd number + { + AsciiToBcd(normal_isdn+1,str_isdn,len-1); + ii = len/2 + 1; + normal_isdn[ii] = (str_isdn[len-1] - '0') << 4; + normal_isdn[ii] |= 0x0E; + } + else + { + AsciiToBcd(normal_isdn+1,str_isdn,len); + ii = len/2; + } + memset(normal_isdn+ii+1,0xEE,ISDN_LEN-ii-1); + normal_isdn[0] = 0x91; // default value + return 1; +} + + +u8 set_gtai_isdn(u8 * gtai, u8 * isdn) +{ + u8 temp_buf[32]; + u8 ii; + u8 len; + + isdn_ntoa(temp_buf, isdn); + ii = temp_buf[0]; + memcpy(gtai, temp_buf + 2, ii - 1); + if((temp_buf[ii] & 0x0f0) == 0x0f0) + len = ii * 2 - 3; + else + len = ii * 2 - 2; + return len; +} + +void xapp_set_sccpadd(u8 ssn, u8 * gtt_num, struct SCCP_ADDRESS *sccp_add) +{ + sccp_add->DPC = 0; // set SCCP address + sccp_add->NetID = 4; + sccp_add->SSN = ssn; + sccp_add->RI = 0; + sccp_add->GTI = 0x04; + sccp_add->TT = 0; + sccp_add->NAI = 4; + sccp_add->NP = 1; // MSISDN + sccp_add->len = set_gtai_isdn(sccp_add->GTAI, gtt_num); +} + +u8 get_mapp_open(struct MapComSrv_struct *com_ptr, u8 ssn) +{ + u8 data_flow[1024]; + + if(!map_get_open(data_flow, ssn)) + return 0; + if(!map_com_ftos(com_ptr, data_flow)) + return 0; + printf("-->>: Recv OpenInd !\r\n"); + return 1; +} + +u8 send_mapp_comdata(struct MapComSrv_struct * com_ptr, u8 DelimiterFlag) +{ + u8 data_flow[1024]; + + map_com_stof(com_ptr, data_flow, DelimiterFlag); + return map_send_comdata(data_flow); +} + +u8 recv_mapp_comdata(struct MapComSrv_struct * com_ptr, u32 did) +{ + u8 data_flow[1024]; + + if(!map_get_comdata(data_flow, did)) + return 0; + if(!map_com_ftos(com_ptr, data_flow)) + return 0; + return 1; +} + +int send_mapp_oprdata(struct MapOprData_struct *opr_ptr, u8 DelimiterFlag) +{ + u8 data_flow[1024]; + + map_opr_stof(opr_ptr, data_flow, DelimiterFlag); + return map_send_oprdata(data_flow); +} + +int recv_mapp_oprdata(struct MapOprData_struct *opr_ptr, u32 did) +{ + u8 data_flow[1024]; + + if(!map_get_oprdata(data_flow, did)) + return 0; + if(!map_opr_ftos(opr_ptr, data_flow)) + return 0; + return 1; +} + +int send_mapp_open_req(WORD dialog_id) +{ + struct MapComSrv_struct map_com; + + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_REQUEST; + map_com.port_id = 0; + map_com.dialogue_id = test_xapp.did; + map_com.dlg_list.open_arg.acn_data.acn = 0; + map_com.dlg_list.open_arg.acn_data.acn_ver = 1; + memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR)); + memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR)); + map_com.dlg_list.open_arg.param_flag = 0x0b; + send_mapp_comdata(&map_com, 1); + printf("<<--: Send OpenReq !\r\n"); + return 1; +} + +int send_mapp_open_conf() +{ + struct MapComSrv_struct map_com; + struct MapOpen_Res *open_res; + + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_RESPONSE; + map_com.port_id = 0; + map_com.dialogue_id = test_xapp.did; + map_com.dlg_list.open_arg.acn_data.acn = 0; + map_com.dlg_list.open_arg.acn_data.acn_ver = 1; + memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR)); + memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR)); + open_res = (MapOpen_Res *) & map_com.dlg_list.open_res; + open_res->result = OpenResultAccept; + open_res->param_flag = 0x08; + if(send_mapp_comdata(&map_com, 1)) + { + printf("<<--: Send OpenConf !\r\n"); + return 1; + } + return 0; +} + +int send_mapp_close(WORD dialog_id) +{ + + struct MapComSrv_struct map_com; + + map_com.message_type = MAP_CLOSE; + map_com.message_flag = MAP_REQUEST; + map_com.port_id = 0; + map_com.dialogue_id = test_xapp.did; + map_com.dlg_list.open_arg.acn_data.acn_ver = 1; + memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR)); + memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR)); + map_com.dlg_list.close_arg.release_method = NormalRelease; + map_com.dlg_list.close_arg.param_flag = 0x01; + send_mapp_comdata(&map_com, 1); + printf("<<--: Send Close !\r\n"); + return 1; +} + +u8 get_capp_open(struct MapComSrv_struct * com_ptr, u8 ssn) +{ + u8 data_flow[1024]; + + if(!cap_get_open(data_flow, ssn)) + return 0; + if(!cap_com_ftos(com_ptr, data_flow)) + return 0; + printf("-->>: Recv OpenInd !\r\n"); + return 1; +} + +u8 send_capp_comdata(struct MapComSrv_struct * com_ptr, u8 DelimiterFlag) +{ + u8 data_flow[1024]; + + cap_com_stof(com_ptr, data_flow, DelimiterFlag); + return cap_send_comdata(data_flow); +} + +u8 recv_capp_comdata(struct MapComSrv_struct * com_ptr, u32 did) +{ + u8 data_flow[1024]; + + if(!cap_get_comdata(data_flow, did)) + return 0; + if(!cap_com_ftos(com_ptr, data_flow)) + return 0; + return 1; +} + +int send_capp_oprdata(struct MapOprData_struct *opr_ptr, u8 DelimiterFlag) +{ + u8 data_flow[1024]; + + cap_opr_stof(opr_ptr, data_flow, DelimiterFlag); + return cap_send_oprdata(data_flow); +} + +int recv_capp_oprdata(struct MapOprData_struct *opr_ptr, u32 did) +{ + u8 data_flow[1024]; + + if(!cap_get_oprdata(data_flow, did)) + return 0; + if(!cap_opr_ftos(opr_ptr, data_flow)) + return 0; + return 1; +} + +/* + u8 send_capp_oprdata(CAP_Message *pcapmsg , u8 len) + { + pcapmsg->msgOperaCode = test_xapp.operation_type; + pcapmsg->msgServiceCode = 0x8a; + pcapmsg->msgOperaType = MAP_REQUEST; + pcapmsg->msgContent[0] = test_xapp.invoke_id; + pcapmsg->msgContent[1] = 1; //pointer to paramter + pcapmsg->msgContent[2] = 1; //Tag of parameter + pcapmsg->msgContent[3] = 0; //length1 + pcapmsg->msgContent[4] = len; //length2 + pcapmsg->msgContent[5 + len] = 0x10; //delimiter + pcapmsg->msgContent[6 + len] = 0; + pcapmsg->msgContent[7 + len] = 0; + + pcapmsg->msgLength[0] = 0; + pcapmsg->msgLength[1] = 17 + len; + if(!cap_send_oprdata((char *)pcapmsg)) + { + return 0; + } + return 1; + } + + u8 recv_capp_oprdata(CAP_Message *capmsg , u32 did) + { + return cap_get_oprdata((unsigned char *)capmsg, did); + } + */ +int send_capp_open_req(unsigned char acn, unsigned char acn_v, unsigned short dlgid) +{ + struct MapComSrv_struct map_com; + + map_com.message_type = CAP_O_OPEN; + map_com.message_flag = CAP_REQUEST; + map_com.port_id = 0; + map_com.dialogue_id = test_xapp.did; + map_com.dlg_list.open_arg.acn_data.acn = acn; + map_com.dlg_list.open_arg.acn_data.acn_ver = 1; + memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR)); + memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR)); + map_com.dlg_list.open_arg.param_flag = 0x0b; + send_capp_comdata(&map_com, 1); + printf("<<--: Send OpenReq !\r\n"); + return 1; +} + +void send_capp_open_conf(unsigned char acn, unsigned char acn_v, unsigned short dlgid) +{ + CAP_Message capmsg; + + memcpy(&capmsg, &CAP_Com_OpenResponse, 18); + capmsg.dialogue_id[0] = dlgid >> 8; + capmsg.dialogue_id[1] = dlgid; + capmsg.msgContent[4] = acn; + capmsg.msgContent[5] = acn_v; + cap_send_comdata((unsigned char *)&capmsg); +} + +void send_capp_close(unsigned short dlgid) +{ + CAP_Message capmsg; + + memcpy(&capmsg, &CAP_Com_End, 14); + capmsg.dialogue_id[0] = dlgid >> 8; + capmsg.dialogue_id[1] = dlgid; + cap_send_comdata((unsigned char *)&capmsg); +} + +int build_xapp_msg() +{ + if(test_xapp.xapp_type) + { + int len; + struct CapArg *cap_opr; + struct MapOprData_struct *data_ptr; + u8 buf[1024]; + + cap_opr = &test_xapp.xapp.capp.cap_opr; + data_ptr = &test_xapp.xapp.capp.data_ptr; + + data_ptr->port_id = cap_opr->port_id; + data_ptr->dialogue_id = cap_opr->dialogue_id; + data_ptr->invoke_id = cap_opr->invoke_id; + data_ptr->message_type = cap_opr->ocode; + data_ptr->message_flag = cap_opr->message_flag; + data_ptr->param_flag = 0x1f; + + len = encode_capmsg(*cap_opr, buf, MAX_MAPPOPR_LEN); + if(len == 0 || len > MAX_MAPPOPR_LEN) + return 0; + data_ptr->param_len = len; + + memcpy(data_ptr->param, buf, len); + data_ptr->param_flag |= 0x20; + return len; + } + else + { + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + int len; + u8 buf[1024]; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + data_ptr->port_id = srv_ptr->port_id; + data_ptr->dialogue_id = srv_ptr->dialogue_id; + data_ptr->invoke_id = srv_ptr->invoke_id; + data_ptr->message_type = srv_ptr->message_type; + data_ptr->message_flag = srv_ptr->message_flag; + //data_ptr->linked_id =1; + data_ptr->param_flag = 0x1f; + + len = build_mapparam(srv_ptr, buf); + if(len == 0 || len > MAX_MAPPOPR_LEN) + return 0; + data_ptr->param_len = len; + + memcpy(data_ptr->param, buf, len); + data_ptr->param_flag |= 0x20; + return len; + } + return 0; +} + +int extract_xapp_msg() +{ + if(test_xapp.xapp_type) + { + int len; + struct CapArg *cap_opr; + struct MapOprData_struct *data_ptr; + + data_ptr = &test_xapp.xapp.capp.data_ptr; + cap_opr = &test_xapp.xapp.capp.cap_opr; + + cap_opr->port_id = data_ptr->port_id; + cap_opr->dialogue_id = data_ptr->dialogue_id; + cap_opr->invoke_id = data_ptr->invoke_id; + cap_opr->ocode = data_ptr->message_type; + cap_opr->message_flag = data_ptr->message_flag; + + decode_capmsg(data_ptr->param, data_ptr->param_len, cap_opr->ocode, cap_opr->message_flag, cap_opr); + return len; + } + else + { + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->port_id = data_ptr->port_id; + srv_ptr->dialogue_id = data_ptr->dialogue_id; + srv_ptr->invoke_id = data_ptr->invoke_id; + srv_ptr->message_type = data_ptr->message_type; + srv_ptr->message_flag = data_ptr->message_flag; + if(!(data_ptr->param_flag & 0x20)) // has not parameter + return RER; + extract_mapparam(srv_ptr, data_ptr->message_type, data_ptr->message_flag, data_ptr->param_len, data_ptr->param); + return ROK; + } + return RER; +} + + +void extract_sri() +{ + struct MapOprSrv_struct opr_ptr; + u8 opr_code = SndRoutInfo; + u8 opr_flag = MAP_CONFIRM; + u32 pre_param_len= 21; + u8 *pre_param; + u8 buf[256],temp_buf[256]; + u8 str[256]="A313890864009200000083F10407916857951230F7"; + + Str2Bcd( buf ,str ,pre_param_len ); + + + Bcd2Str_Space(temp_buf, str,pre_param_len); + printf("\r\nextract code :[%d] len :[%ld]\r\n%s\r\n",opr_code,pre_param_len,str); + + pre_param = (u8*)&buf; + opr_ptr.version =3; + extract_mapparam( &opr_ptr, opr_code , opr_flag , pre_param_len , pre_param ); + +} diff --git a/plat/xapp/ut/xapp_test/xapp_coding_test.h b/plat/xapp/ut/xapp_test/xapp_coding_test.h new file mode 100644 index 0000000..687bc56 --- /dev/null +++ b/plat/xapp/ut/xapp_test/xapp_coding_test.h @@ -0,0 +1,105 @@ +/* XAPP coding test function head file */ +/* created by Liu Wei 2006-01-13 */ +/* Version 1.0 */ +/* ------------------------------------- */ + +#include "xapp_main.h" + +#ifndef _XAPP_CODING_TEST_ + +#define _XAPP_CODING_TEST_ + +struct mapp_struct +{ + struct MapOprSrv_struct map_opr; + struct MapOprData_struct data_ptr; + //struct MapOprData_struct data_ptr_bak; + struct MapComSrv_struct com_ptr; +}; + +typedef struct _CAP_Message +{ + unsigned char msgLength[2]; /* unsigned char0 is the higher part */ + unsigned char msgServiceCode; /* fixed as 0xAF */ + unsigned char port_id[3]; /* unsigned char 0 is the higher part,unsigned char 1 is the lower part ,and unsigned char 2 is reserved */ + unsigned char dialogue_id[3]; + unsigned char msgOperaCode; /* message type code ,e.g , InitialDP = 0x00 */ + unsigned char msgOperaType; /* 1/2/3/4 = request, indicate, response, confirm */ + unsigned char msgContent[CAP_CONTENT_LEN]; + /* if the message if cap operation ,then the first unsigned char of msgContent is invoke id */ +} +CAP_Message, *PCAP_Message; + +struct capp_struct +{ + struct CapArg cap_opr; + struct MapOprData_struct data_ptr; + struct MapComSrv_struct com_ptr; + //CAP_Message capmsg; +}; + +struct test_xapp_struct +{ + int sock; + u8 fsm_state; + u8 did; + u8 invoke_id; + u8 xapp_type; + u8 ms_mode; + u8 test_result; + u8 operation_type; + u8 local_ssn; + u8 peer_ssn; + u8 peer_state; + u32 wait_time; + struct SCCP_ADDRESS local_add; + struct SCCP_ADDRESS peer_add; + union + { + struct mapp_struct mapp; + struct capp_struct capp; + } + xapp; +} +test_xapp; + +enum XAPP_TEST_OP test_cmd; +int bcd_hton(BYTE * netbcd, const BYTE * hostbcd, BYTE max_octet); +int bcd_ntoh(BYTE * hostbcd, const BYTE * netbcd, BYTE max_octet); +void isdn_aton(u8 *normal_isdn,u8 *anti_isdn); +void imsi_aton(u8 *normal_imsi,u8 *anti_imsi); +void imsi_ntos(u8 *str_imsi,u8 *normal_imsi); +void imsi_ston(u8 *normal_imsi,u8 *str_imsi); +void isdn_ntos(u8 *str_isdn,u8 *normal_isdn); +void imsi_ntoa(u8 *anti_imsi,u8 *normal_imsi); + +void isdn_ntoa(u8 * anti_isdn, u8 * normal_isdn); +u8 isdn_ston(u8 *normal_isdn,u8 *str_isdn); + +void xapp_set_sccpadd(u8 ssn, u8 * gtt_num, struct SCCP_ADDRESS *sccp_add); + +int build_xapp_msg(); +int extract_xapp_msg(); + +u8 get_mapp_open(struct MapComSrv_struct *com_ptr, u8 ssn); +u8 send_mapp_comdata(struct MapComSrv_struct *com_ptr, u8 DelimiterFlag); +u8 recv_mapp_comdata(struct MapComSrv_struct *com_ptr, u32 did); +int send_mapp_oprdata(struct MapOprData_struct *opr_ptr, u8 DelimiterFlag); +int recv_mapp_oprdata(struct MapOprData_struct *opr_ptr, u32 did); + +int send_mapp_open_req(WORD dialog_id); +int send_mapp_open_conf(); +int send_mapp_close(WORD dialog_id); + +u8 get_capp_open(struct MapComSrv_struct *com_ptr, u8 ssn); +u8 send_capp_comdata(struct MapComSrv_struct *com_ptr, u8 DelimiterFlag); +u8 recv_capp_comdata(struct MapComSrv_struct *com_ptr, u32 did); +int send_capp_oprdata(struct MapOprData_struct *opr_ptr, u8 DelimiterFlag); +int recv_capp_oprdata(struct MapOprData_struct *opr_ptr, u32 did); +int send_capp_open_req(unsigned char acn, unsigned char acn_v, unsigned short dlgid); +void send_capp_open_conf(unsigned char acn, unsigned char acn_v, unsigned short dlgid); +void send_capp_close(unsigned short dlgid); + +void extract_sri(); + +#endif diff --git a/plat/xapp/ut/xapp_test/xapp_main.c b/plat/xapp/ut/xapp_test/xapp_main.c new file mode 100644 index 0000000..6b5ee77 --- /dev/null +++ b/plat/xapp/ut/xapp_test/xapp_main.c @@ -0,0 +1,372 @@ +/* XAPP coding test function c file */ +/* created by Liu Wei 2006-01-13 */ +/* Version 1.0 */ +/* ------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xapp_coding_test.h" +#include "xapp_main.h" + +static int sys_timer10ms = 0; + +static char test_sync_cmd[6][32] = { + "XAPP_TEST", + "XAPP_RSP", + "XAPP_OK", + "XAPP_FAIL", + "XAPP_OK,NEXT", + "XAPP_FAIL,NEXT", +}; + +static char udp_contents = 0; + +#define SYS_IT_INTERVAL_SEC 0 +#define SYS_IT_INTERVAL_USEC (10*1000) +int remote_ip; +int test_port = 6999; +u8 time_count; + +int get_socket(u_int32_t ip, int port) +{ + int sock; + int on = 1; + u_long cmdarg = 1; + struct sockaddr_in sin_addr; + + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = htons(port); + sin_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if(!(sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + perror("Get socket"); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if(bind(sock, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr_in)) != 0) + { + perror("bind"); + return 0; + } + ioctl(sock, FIONBIO, &cmdarg); + return (sock); +} + +int Get_Peer_IP() +{ + char s[16]; + FILE *fp = NULL; + int i = 0; + char c; + + fp = fopen("./conf/sccp_test.conf", "r"); + if(fp != NULL) + { + while((c = fgetc(fp)) != EOF && c != ' ' && c != '\n' && c != '\t') + { + s[i++] = c; + if(i >= 16) + break; + } + s[i] = '\0'; + printf("Remote ip :%s\r\n", s); + remote_ip = inet_addr(s); + i = 0; + while((c = fgetc(fp)) != EOF && c != ' ' && c != '\n' && c != '\t') + { + s[i++] = c; + if(i >= 5) + break; + + } + s[i] = '\0'; + test_xapp.wait_time = strtol(s, NULL, 10); + printf("Waiting start test time :%ld\r\n", test_xapp.wait_time); + return 1; + } + return 0; +} + +void MS_mode_test() +{ + memset(&test_xapp, 0, sizeof(struct test_xapp_struct)); + //test_cmd=0; + //test_xapp.ms_mode = 0; + if(Get_Peer_IP()) + { + test_xapp.sock = get_socket(remote_ip, test_port); + } + else + { + printf("Get Peer IP Fail!\r\n"); + } +} + +void next_case() +{ + test_cmd++; + + test_xapp.test_result = 0; + test_xapp.peer_state = 0; + printf("\r\n ------------------------>> Next Case %d<<------------------ \r\n",(int )test_cmd); + if(test_cmd == XAPP_TEST_LAST_IDLE) + { + printf("\r\n\r\nTest over !\r\n\r\n"); + test_cmd = 0; + test_xapp.test_result = 7; + } +} + +void MS_test_timer() +{ + char msg[256]; + struct sockaddr_in sin_addr; + int addr_len; + u8 isdn[ISDN_LEN]; + u8 i; + char str[32]; + + sin_addr.sin_port = htons(test_port); + sin_addr.sin_addr.s_addr = remote_ip; + addr_len = sizeof(struct sockaddr_in); + udp_contents = 0; + memset(msg, 0, 256); + recvfrom(test_xapp.sock, (char *)msg, 256, 0, (struct sockaddr *)&sin_addr, &addr_len); + if(msg[0]) + { + //printf("Recv Test sycn msg :%s \r\n",msg); + for(i = 0; i <= 6; i++) + { + sprintf(str, "%s", test_sync_cmd[i]); + if(i >= 2) + sprintf(str, "%s:%d", test_sync_cmd[i], test_cmd); + if(strcmp(msg, str) == 0) + { + udp_contents = i + 1; + break; + } + } + + } + if(test_xapp.ms_mode == 0) + { + if(udp_contents == 0) + { + strcpy(msg, "XAPP_TEST"); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + } + if(udp_contents == 2) + { + test_xapp.local_ssn = 7; + test_xapp.peer_ssn = 6; + imap_reg_ssn(test_xapp.local_ssn); + AsciiToBcd(isdn, "918675557122001F", 16); + xapp_set_sccpadd(test_xapp.local_ssn, isdn, &test_xapp.local_add); + AsciiToBcd(isdn, "918675557122002F", 16); + xapp_set_sccpadd(test_xapp.peer_ssn, isdn, &test_xapp.peer_add); + printf(" XAPP Test Slave Started :%s\r\n", msg); + test_xapp.ms_mode = 2; + return; + } + else if(udp_contents == 1) + { + test_xapp.local_ssn = 6; + test_xapp.peer_ssn = 7; + imap_reg_ssn(test_xapp.local_ssn); + AsciiToBcd(isdn, "918675557122002F", 16); + xapp_set_sccpadd(test_xapp.local_ssn, isdn, &test_xapp.local_add); + AsciiToBcd(isdn, "918675557122001F", 16); + xapp_set_sccpadd(test_xapp.peer_ssn, isdn, &test_xapp.peer_add); + printf(" XAPP Test Master Started :%s\r\n", msg); + strcpy(msg, "XAPP_RSP"); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + test_xapp.ms_mode = 1; + return; + } + + } + if(test_xapp.ms_mode) + { + switch (test_xapp.test_result) + { + case 0: + + if(udp_contents == 4) + { + sprintf(msg, "XAPP_FAIL:%d,Next", test_cmd); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + printf("[Test]:Fail!\r\n\r\n"); + next_case(); + return; + } + else if(udp_contents == 3) + { + printf("Peer Test OK !\r\n"); + test_xapp.peer_state = 1; + } + break; + case 1: //OK + printf("Local Test OK !\r\n"); + if(test_xapp.peer_state == 1) + { + sprintf(msg, "XAPP_OK,NEXT:%d", test_cmd); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + printf("[Test]: OK!\r\n\r\n"); + next_case(); + return; + } + sprintf(msg, "XAPP_OK:%d", test_cmd); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + printf("Send sycn msg : %s\r\n ",msg); + test_xapp.test_result = 3; + break; + case 2: + printf("Local Test Fail !\r\n"); + if(test_xapp.peer_state == 1) + { + sprintf(msg, "XAPP_FAIL,NEXT:%d", test_cmd); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + printf("[Test]:Fail!\r\n\r\n"); + next_case(); + return; + } + sprintf(msg, "XAPP_FAIL:%d", test_cmd); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + printf("Send sycn msg : %s\r\n ",msg); + test_xapp.test_result = 4; + break; + case 3: + case 4: + if( msg[0] ) + printf("udp recv pos 3:%s\r\n", msg); + if(udp_contents == 5 || udp_contents == 6) + { + (test_xapp.test_result == 3) ? printf("Peer Test OK !\r\n") : printf("Peer Test Fail !\r\n"); + (test_xapp.test_result == 3) ? printf("[Test]: OK!\r\n\r\n") : printf("[Test]: Fail!\r\n\r\n"); + next_case(); + return; + } + else if(udp_contents == 3) + { + sprintf(msg, "XAPP_OK,NEXT:%d", test_cmd); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + printf("Peer Test OK !\r\n"); + printf("[Test]: OK!\r\n\r\n"); + next_case(); + return; + } + else if(udp_contents == 4) + { + sprintf(msg, "XAPP_FAIL,NEXT:%d", test_cmd); + sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr)); + printf("Peer Test Fail !\r\n"); + printf("[Test]:Fail!\r\n\r\n"); + next_case(); + return; + } + break; + default: + break; + + } + + } +} + + + + +void moduleInit() +{ + //ioperm(0x27A,3,1); + MS_mode_test(); //master and slaver mode + debug_init(); + //#ifdef NEW_PLATFORM + iptrMainInit(); + /*#else + iptrans_init(); + #endif */ + mtp_shm_init(); + snmp_init(4957); + sccp_init(); + tcap_init(1024); + printf("MAP OP data size : %d\r\n,MAP OP Str size : %d\r\n",sizeof(MapOprData_struct),sizeof(MapOprSrv_struct)); + //printf("send para res size : %d \r\nProvid_SSInfo_struct : %d \r\nOdbData_struct :%d \r\n" ,sizeof(MapSP_Res), + //sizeof(Provid_SSInfo_struct),sizeof(struct OdbData_struct)); + printf("Sub_data_struct :%d ExtSsInfo_struct:%d \r\n",sizeof(Sub_data_struct),sizeof(ExtSsInfo_struct)); + printf("MapISD_Arg :%d \r\n",sizeof(MapISD_Arg)); + xap_init(1204); + extract_sri(); + printf("\r\nWating Peer test message ... \r\n"); +} + +void sysTimer_IRQ() +{ + sys_timer10ms = 1; +} + +static void SigactionSystem() +{ + struct sigaction action; + + action.sa_handler = sysTimer_IRQ; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + if(sigaction(SIGALRM, &action, NULL) < 0) + { + printf("sigactin sigalarm failed\n"); + } +} + +void SetFSMTimer() +{ + struct itimerval *ptv, tv; + + ptv = (struct itimerval *)&tv; + ptv->it_interval.tv_sec = 0; + ptv->it_interval.tv_usec = 10 * 1000; + ptv->it_value = ptv->it_interval; + setitimer(ITIMER_REAL, ptv, NULL); +} + +void moduleProc() +{ + iptrans_timer(); + snmp_timer(); + heartbeat_timer(); + mtp3_proc(); + sccp_timer(); + debug_rt(); + tcap_fsm(); + xap_fsm(); + Test_func(); + MS_test_timer(); +} + +int main() +{ + moduleInit(); + SigactionSystem(); + SetFSMTimer(); + + sys_timer10ms = 1; + while(1) + { + if(sys_timer10ms) + { + sys_timer10ms = 0; + moduleProc(); + } + if(sys_timer10ms == 0) + usleep(1); + } + return 1; +} diff --git a/plat/xapp/ut/xapp_test/xapp_main.h b/plat/xapp/ut/xapp_test/xapp_main.h new file mode 100644 index 0000000..a9701f7 --- /dev/null +++ b/plat/xapp/ut/xapp_test/xapp_main.h @@ -0,0 +1,32 @@ +/* XAPP coding test function head file */ +/* created by Liu Wei 2006-01-13 */ +/* Version 1.0 */ +/* ------------------------------------- */ + +#ifndef _XAPP_MAIN_ + +#define _XAPP_MAIN_ + +#include "../../public/asn1.h" +#include "../../public/includes.h" +#include "../../iptrans/iptrans.h" +#include "../../mtp3/mtp3.h" +#include "../../snmp/snmp.h" +#include "../../sccp/sccp.h" +#include "../../tcap/tcap_public.h" +#include "../../tcap/tcap_proc.h" +#include "../../xapp/mapp/map_const.h" +#include "../../xapp/mapp/map_code.h" +#include "../../xapp/mapp/map_acn.h" +#include "../../xapp/mapp/map_struct.h" +#include "../../xapp/mapp/map_public.h" +#include "../../xapp/capp/cap_public.h" +#include "../../xapp/ixap.h" +#include "../../debug/debug.h" +#include "../../snmp/snmp.h" +#include "../../xapp/capp/cap_msg.h" +#include "../../xapp/xap_provider.h" +#include "../../xapp/conv_prefix.h" +#include "xapp_op_test.h" + +#endif diff --git a/plat/xapp/ut/xapp_test/xapp_op_test.c b/plat/xapp/ut/xapp_test/xapp_op_test.c new file mode 100644 index 0000000..b00b774 --- /dev/null +++ b/plat/xapp/ut/xapp_test/xapp_op_test.c @@ -0,0 +1,2067 @@ +/* XAPP coding test function c file */ +/* created by Liu Wei 2006-01-13 */ +/* Version 1.0 */ +/* ------------------------------------- */ + +#include "xapp_main.h" +#include "xapp_coding_test.h" +extern int xapp_test_state; + +u32 time_count2 = 0, time_count3 ,time_count4=0; + +void test_pass() +{ + if( time_count4++ >200 ) + { + time_count4 =0; + test_xapp.fsm_state = 0; + test_xapp.test_result = 1; + if( !test_xapp.xapp_type ) + send_mapp_close(test_xapp.did); + else + send_capp_close(test_xapp.did); + } +} + +void test_fail() +{ + if( time_count4++ >200 ) + { + test_xapp.fsm_state = 0; + test_xapp.test_result = 2; + if( !test_xapp.xapp_type ) + send_mapp_close(test_xapp.did); + else + send_capp_close(test_xapp.did); + } +} + +void MAPP_Test_SendPara_Proc() +{ + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapSP_Arg *sp_arg; + struct MapSP_Res *sp_res; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + u8 bcd_buf_h[ISDN_LEN * 2]; + + test_xapp.xapp_type = 0; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + sp_arg = &srv_ptr->msg_list.sp_arg; + sp_arg->param_flag = 0x03; + sp_arg->ReqPara_num = 2; + sp_arg->ReqPara[0] = 1; + sp_arg->ReqPara[1] = 2; + sp_arg->sub_id.choice_flag = 1; + AsciiToBcd(bcd_buf_h, "46002215712701", IMSI_LEN * 2); + memcpy(sp_arg->sub_id.id_choice.imsi, bcd_buf_h, IMSI_LEN); + + send_mapp_open_req(did); + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send SendparaArg !\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did) && recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) // wait response + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != SendParam) + { + printf("-->>: Recv Sendpara Res decode err!\r\n"); + test_fail(); + + return; + } + printf("-->>:Recv Sendpara Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != SendParam) + { + printf("-->>: Recv Sendpara Arg decode err!\r\n"); + test_fail(); + + return; + } + printf("-->>: Recv Sendpara Arg !\r\n"); + test_xapp.fsm_state++; + test_xapp.invoke_id = test_xapp.xapp.mapp.data_ptr.invoke_id; + test_xapp.operation_type = test_xapp.xapp.mapp.data_ptr.message_type; + } + break; + case 2: + if(map_check_sendopr(test_xapp.did)) + { + struct Sub_data_struct *sub_data; + + test_xapp.xapp_type = 0; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->invoke_id = test_xapp.invoke_id; + srv_ptr->message_flag = MAP_RESPONSE; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + sp_res = &srv_ptr->msg_list.sp_res; + + sp_res->param_flag = 0x0f; + sp_res->sendparamlist_num = 2; + sp_res->sendparalist[0].choice_flag = 1; + memcpy(sp_res->sendparalist[0].SP_Res_Choice.imsi, "460022157127015", IMSI_LEN); + sp_res->sendparalist[1].choice_flag = 4; + + sub_data = &sp_res->sendparalist[1].SP_Res_Choice.sub_data; + sub_data->param_flag = 0xFF; + memcpy(sub_data->msisdn, "8675557127015", ISDN_LEN); + sub_data->category = 1; + sub_data->sub_status = 0; + sub_data->bearer_data= 1234; + sub_data->tele_data=12; + sub_data->zc_list.list_len = 2; + strcpy(sub_data->zc_list.zone_code[0], "HI"); + strcpy(sub_data->zc_list.zone_code[1], "OK"); + sub_data->odb_data.param_flag = 0x03; + sub_data->odb_data.odb_general = 0x1234; + sub_data->odb_data.odb_hplmn = 0xFEDC; + //sub_data->ss_info_num = 4; if 4 the map total length 192, mtp3 not support(<256) + //sub_data->ss_info_num = 2; + + sub_data->ss_info.param_flag = 1; + + sub_data->ss_info.call_info.param_flag = 0x03; + sub_data->ss_info.call_info.ss_code[0] = 4; + sub_data->ss_info.call_info.ss_code[1] = 4; + sub_data->ss_info.call_info.ss_status[0] = 2; + sub_data->ss_info.call_info.ss_status[1] = 4; + sub_data->ss_info.call_info.bs_code[0].bearer_code = 1; + sub_data->ss_info.call_info.bs_code[0].tele_code = 2; + sub_data->ss_info.call_info.bs_code[1].bearer_code = 3; + sub_data->ss_info.call_info.bs_code[1].tele_code = 4; + + /* + sub_data->ss_info[1].choice_flag = 4; + sub_data->ss_info[1].choice.cug_info.param_flag = 0x03; + sub_data->ss_info[1].choice.cug_info.feat_list.list_len = 1; + sub_data->ss_info[1].choice.cug_info.feat_list.cug_feat[0].param_flag = 0x07; + sub_data->ss_info[1].choice.cug_info.feat_list.cug_feat[0].bs.choice_flag = 1; + sub_data->ss_info[1].choice.cug_info.feat_list.cug_feat[0].bs.choice.bear_service = 1; + sub_data->ss_info[1].choice.cug_info.feat_list.cug_feat[0].cug_indicator = 1234; + sub_data->ss_info[1].choice.cug_info.feat_list.cug_feat[0].cug_restric = 12; + sub_data->ss_info[1].choice.cug_info.subs_list.list_len = 1; + sub_data->ss_info[1].choice.cug_info.subs_list.cug_subs[0].param_flag = 0x0f; + sub_data->ss_info[1].choice.cug_info.subs_list.cug_subs[0].bs.choice_flag = 1; + sub_data->ss_info[1].choice.cug_info.subs_list.cug_subs[0].bs.choice.bear_service = 1; + sub_data->ss_info[1].choice.cug_info.subs_list.cug_subs[0].cug_index = 1111; + memcpy(sub_data->ss_info[1].choice.cug_info.subs_list.cug_subs[0].cug_lock, "1234", 4); + sub_data->ss_info[1].choice.cug_info.subs_list.cug_subs[0].cug_opt = 0; + */ + /* + sub_data->ss_info.fwd_info.param_flag = 0x01; + sub_data->ss_info.fwd_info.ss_code[0] = 1; + sub_data->ss_info.fwd_info.fwd_feat[0].param_flag = 0x3F; + sub_data->ss_info.fwd_info.fwd_feat[0].bs_code.param_flag = 1; + sub_data->ss_info.fwd_info.fwd_feat[0].bs_code.tele_code = 1; + sub_data->ss_info.fwd_info.fwd_feat[0].ss_status = 1; + memcpy(sub_data->ss_info.fwd_info.fwd_feat[0].fwdto_num+1, "8675557127016", ISDN_LEN); + sub_data->ss_info.fwd_info.fwd_feat[0].fwdto_num[0] = ISDN_LEN; + sub_data->ss_info.fwd_info.fwd_feat[0].norc_time = 1; + sub_data->ss_info.fwd_info.fwd_feat[0].fwd_option = 2; + + + sub_data->ss_info.ss_data.param_flag = 0x01; + sub_data->ss_info.ss_data.ss_code[0] = 1; + sub_data->ss_info.ss_data.ss_status[0] = 1; + sub_data->ss_info.ss_data.bs_code[0].param_flag = 3; + sub_data->ss_info.ss_data.bs_code[0].tele_code = 2; + sub_data->ss_info.ss_data.bs_code[0].bearer_code = 2; + sub_data->ss_info.ss_data.subs_opt[0].choice_flag = 1; + sub_data->ss_info.ss_data.subs_opt[0].choice.clires_opt = 2; + */ + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send SendparaRes !\r\n"); + test_xapp.fsm_state++; + } + break; + case 3: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } +} + +void MAPP_Test_NotSubPresent_Proc() +{ + + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapNP_Arg *np_arg; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + u8 bcd_buf_h[ISDN_LEN * 2]; + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + np_arg = &srv_ptr->msg_list.np_arg; + np_arg->param_flag = 0x01; + AsciiToBcd(bcd_buf_h, "460022157127012", IMSI_LEN * 2); + memcpy(np_arg->imsi, bcd_buf_h, IMSI_LEN); + np_arg->imsi[IMSI_LEN - 1] = np_arg->imsi[IMSI_LEN - 1] | 0xf0; + + send_mapp_open_req(did); + build_xapp_msg(); + printf("<<--: Send NotSubPresent ,not need to response !\r\n"); + send_mapp_oprdata(data_ptr, 1); + test_xapp.fsm_state++; + } + break; + case 1: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != NoteSubPrnt) + { + printf("-->>: Recv NotSubPresent decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv NotSubPresent ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } +} + +void MAPP_Test_ProcessUSSD_Proc() +{ + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapPUSSD_Arg *ussd_arg; + struct MapPUSSD_Res *ussd_res; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + ussd_arg = &srv_ptr->msg_list.pussd_arg; + ussd_arg->ussd_len = 3; + memcpy(ussd_arg->ussd_data, "123", 3); + ussd_arg->param_flag = 1; + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send ProcessUSSD Arg!\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did) && recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) // wait response + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != ProcUnstrctSSData) + { + printf("-->>: Recv ProcessUSSD Res decode err!\r\n"); + return; + } + printf("-->>: Recv ProcessUSSD Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != ProcUnstrctSSData) + { + printf("-->>: Recv ProcessUSSD arg decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv ProcessUSSD arg !\r\n"); + test_xapp.invoke_id = test_xapp.xapp.mapp.data_ptr.invoke_id; + test_xapp.operation_type = test_xapp.xapp.mapp.data_ptr.message_type; + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendopr(test_xapp.did)) + { + test_xapp.xapp_type = 0; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->invoke_id = test_xapp.invoke_id; + srv_ptr->message_flag = MAP_RESPONSE; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + ussd_res = &srv_ptr->msg_list.pussd_res; + + ussd_res->ussd_len = 3; + memcpy(ussd_res->ussd_data, "123", 3); + ussd_res->param_flag = 1; + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send ProcessUSSD Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 3: + recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did); + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } +} + +void MAPP_Test_BeginSubActivity() +{ + + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapBSA_Arg *bsa_arg; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + u8 bcd_buf_h[ISDN_LEN * 2]; + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + bsa_arg = &srv_ptr->msg_list.bsa_arg; + bsa_arg->param_flag = 0x03; + AsciiToBcd(bcd_buf_h, "46002215712701", IMSI_LEN * 2); + memcpy(bsa_arg->imsi, bcd_buf_h, IMSI_LEN); + bsa_arg->orgenty_num_len = 9; + memcpy(bsa_arg->orgenty_num, "123456789", 9); + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send BegineSubActivity ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != BeginSubAct) + { + printf("-->>: Recv BegineSubActivity decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv BegineSubActivity ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + + } +} + +void MAPP_Test_RegisterSS() +{ + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapRSS_Arg *regss_arg; + struct MapRSS_Res *regss_res; + struct MapComSrv_struct map_com; + /* + u8 isdn1[9] = {0x96, 0x64, 0x00, 0x22, + 0x51, 0x17 ,0x72, 0x10, 0xF5}; + u8 isdn2[9] = {0x91, 0x68, 0x57, 0x55, + 0x17, 0x22, 0x00, 0xF1}; + */ + char dst_ref[54], local_ref[54]; + u8 imsi[9] , isdn[9]; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + regss_arg = &srv_ptr->msg_list.rss_arg; + + regss_arg->param_flag = 0x1F; + regss_arg->ss_code = 0x28; + regss_arg->bs_code.param_flag = 0x01 ; + regss_arg->bs_code.tele_code = 0x0a ; + regss_arg->fwdto_num[0] = ISDN_LEN; + memcpy( regss_arg->fwdto_num+1 , "12345678", 8 ); + regss_arg->norc_time = 30 ; + regss_arg->default_prio = 20 ; + + + + map_com.message_type = MAP_OPEN; + map_com.message_flag = MAP_REQUEST; + map_com.port_id = 0; + map_com.dialogue_id = test_xapp.did; + map_com.dlg_list.open_arg.acn_data.acn = 18; + map_com.dlg_list.open_arg.acn_data.acn_ver = 1; + memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR)); + memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR)); + map_com.dlg_list.open_arg.peerref_len = IMSI_LEN+1; + map_com.dlg_list.open_arg.localref_len = ISDN_LEN; + strcpy( local_ref , "8675557127001"); + isdn_ston( isdn , local_ref); + map_com.dlg_list.open_arg.local_reference[0] = 0x91; + isdn_ntoa( (u8 *)&map_com.dlg_list.open_arg.local_reference+1 , isdn); + strcpy( dst_ref , "460022157127001"); + imsi_ston( imsi , dst_ref); + map_com.dlg_list.open_arg.peer_reference[0] = 0x96; + imsi_ntoa( (u8 *)&map_com.dlg_list.open_arg.peer_reference+1 , imsi); + map_com.dlg_list.open_arg.param_flag = 0x1F; + send_mapp_comdata(&map_com, 1); + printf("<<--: Send OpenReq !\r\n"); + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send Register SS Arg!\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did) && recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) // wait response + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != RegSS) + { + printf("-->>: Recv Register SS Res decode err!\r\n"); + return; + } + printf("-->>: Recv Register SS Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + struct MapOpen_Arg *open_ptr; + + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + open_ptr = (MapOpen_Arg *) &test_xapp.xapp.mapp.com_ptr.dlg_list.open_arg; + if( (open_ptr->param_flag & 0x14) == 0x14) + { + char dst_ref[54], local_ref[54]; + u8 imsi[9] , isdn[9]; + isdn_aton( isdn , open_ptr->local_reference+1); + isdn_ntos( local_ref , isdn ); + imsi_aton( imsi , open_ptr->peer_reference+1); + imsi_ntos( dst_ref , imsi ); + printf("dst ref: %s local_ref :%s\n",dst_ref, local_ref); + + } + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != RegSS) + { + printf("-->>: Recv Register SS arg decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv Register SS arg!\r\n"); + test_xapp.invoke_id = test_xapp.xapp.mapp.data_ptr.invoke_id; + test_xapp.operation_type = test_xapp.xapp.mapp.data_ptr.message_type; + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendopr(test_xapp.did)) + { + test_xapp.xapp_type = 0; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->invoke_id = test_xapp.invoke_id; + srv_ptr->message_flag = MAP_RESPONSE; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + regss_res = &srv_ptr->msg_list.rss_res; + regss_res->param_flag = 0x01; + regss_res->ss_info.choice_flag = 0x01; + regss_res->ss_info.choice.fwd_info.param_flag = 0x01; + regss_res->ss_info.choice.fwd_info.ss_code = 1; + regss_res->ss_info.choice.fwd_info.fwd_feat.param_flag = 0x3F; + regss_res->ss_info.choice.fwd_info.fwd_feat.bs_code.param_flag = 1; + regss_res->ss_info.choice.fwd_info.fwd_feat.bs_code.tele_code = 1; + regss_res->ss_info.choice.fwd_info.fwd_feat.ss_status = 1; + memcpy(regss_res->ss_info.choice.fwd_info.fwd_feat.fwdto_num+1, "8675557127016", ISDN_LEN); + regss_res->ss_info.choice.fwd_info.fwd_feat.fwdto_num[0] = ISDN_LEN; + regss_res->ss_info.choice.fwd_info.fwd_feat.norc_time = 1; + regss_res->ss_info.choice.fwd_info.fwd_feat.fwd_option = 2; + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send Register SS res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 3: + recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did); + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } +} + +void MAPP_Test_PeformHandOver() +{ + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapHO_Arg *ho_arg; + struct MapHO_Res *ho_res; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + ho_arg = &srv_ptr->msg_list.ho_arg; + ho_arg->param_flag = 0x3F; + memcpy(ho_arg->tgt_cellID, "1234567", 7); + memcpy(ho_arg->srv_cellID, "7654321", 7); + memcpy(ho_arg->chl_type, "0123456789", 7); + memcpy(ho_arg->class_mark, "12", 2); + ho_arg->ho_priority = 1; + memcpy(ho_arg->kc, "12345678", 8); + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send PerformHandOver Arg!\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did) && recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) // wait response + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != PerformHo) + { + printf("-->>: Recv PerformHandOver Res decode err!\r\n"); + return; + } + printf("-->>: Recv PerformHandOver Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != PerformHo) + { + printf("-->>: Recv PerformHandOver arg decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv PerformHandOver arg!\r\n"); + test_xapp.invoke_id = test_xapp.xapp.mapp.data_ptr.invoke_id; + test_xapp.operation_type = test_xapp.xapp.mapp.data_ptr.message_type; + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendopr(test_xapp.did)) + { + test_xapp.xapp_type = 0; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->invoke_id = test_xapp.invoke_id; + srv_ptr->message_flag = MAP_RESPONSE; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + ho_res = &srv_ptr->msg_list.ho_res; + ho_res->ho_num_len = 9; + memcpy(ho_res->ho_num, "123456789", 9); + ho_res->access_singal_info.protocol_id = 2; + ho_res->access_singal_info.singal_info_len = 3; + memcpy(ho_res->access_singal_info.signal_info, "123", 3); + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send PerformHandOver res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 3: + recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did); + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } +} + + + +void MAPP_Test_CancelLoc_Proc(u8 ver) +{ + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapCL_Arg *cl_arg; + struct MapCL_Res *cl_res; + + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + test_xapp.xapp_type = 0; + + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + srv_ptr->version = 3; + + cl_arg = &srv_ptr->msg_list.cl_arg; + cl_arg->param_flag = 0x03; + cl_arg->id.choice_flag = 2; + memcpy( cl_arg->id.choice.imsi_withlmsi.imsi ,"1234", IMSI_LEN); + memcpy( cl_arg->id.choice.imsi_withlmsi.lmsi , "1234",LMSI_LEN); + cl_arg->type = 1; + + send_mapp_open_req(did); + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send CancelLocation !\r\n"); + test_xapp.fsm_state++; + if( ver == 1) + { + test_xapp.fsm_state = 2; + printf(" Cancellocation V1 ,need not to response !\r\n"); + } + } + break; + case 1: + if(recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did) && recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) // wait response + { + u8 isok = extract_xapp_msg(); + if( isok != ROK || test_xapp.xapp.mapp.data_ptr.message_type != CancelLoc) + { + printf("-->>: Recv CancelLocation Res decode err!\r\n"); + test_fail(); + return; + } + printf("-->>:Recv CancelLocation Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + u8 isok = extract_xapp_msg(); + if( isok != ROK || test_xapp.xapp.mapp.data_ptr.message_type != CancelLoc) + { + printf("-->>: Recv Cancellocation Arg decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv Cancellocation Arg !\r\n"); + test_xapp.fsm_state++; + test_xapp.invoke_id = test_xapp.xapp.mapp.data_ptr.invoke_id; + test_xapp.operation_type = test_xapp.xapp.mapp.data_ptr.message_type; + if( test_xapp.xapp.mapp.map_opr.version == 1) + { + test_xapp.fsm_state = 3; + printf("Cancellocation V1 ,need not to response !\r\n"); + } + } + break; + case 2: + if(map_check_sendopr(test_xapp.did)) + { + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->invoke_id = test_xapp.invoke_id; + srv_ptr->message_flag = MAP_RESPONSE; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + //srv_ptr->version = 3; + + cl_res = &srv_ptr->msg_list.cl_res; + + cl_res->param_flag = 0x00; + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send SendparaRes !\r\n"); + test_xapp.fsm_state++; + } + break; + case 3: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } +} + + + + +void MAPP_Test_PerformSubsequenthandover() +{ + + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapPFSHO_Arg *ho_arg; + struct MapPFSHO_Res *ho_res; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + ho_arg = &srv_ptr->msg_list.pfsho_arg; + ho_arg->param_flag = 0x0f; + + + memcpy( ho_arg->target_id , "1234567",GCID_LEN); + memcpy( ho_arg->service_id , "1234567",GCID_LEN); + ho_arg->msc_num[0]= ISDN_LEN; + memcpy( ho_arg->msc_num+1 , "01234567" ,ISDN_LEN); + memcpy( ho_arg->classmark_info ,"12" ,2 ); + + + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send Preformsubsequent handover Arg!\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did) && recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) // wait response + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != PerformSubsHo) + { + printf("-->>: Recv Preformsubsequent handover Res decode err!\r\n"); + test_fail(); + + return; + } + printf("-->>:Recv Preformsubsequent handover Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != PerformSubsHo) + { + printf("-->>: Recv Preformsubsequent handover Arg decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv Preformsubsequent handover Arg\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendopr(test_xapp.did)) + { + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->invoke_id = test_xapp.invoke_id; + srv_ptr->message_flag = MAP_RESPONSE; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + //srv_ptr->version = 3; + + ho_res = &srv_ptr->msg_list.pfsho_res; + + ho_res->param_flag = 1; + ho_res->access_sig_info.param_flag = 3; + ho_res->access_sig_info.prt_id =1; + ho_res->access_sig_info.siginfo.siginfo_len =2 ; + memcpy( ho_res->access_sig_info.siginfo.signal_info , "12",2); + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send Preformsubsequent handover Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 3: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + + } +} + + +void MAPP_Test_noteinernalhandover() +{ + + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapNIHO_Arg *ho_arg; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + ho_arg = &srv_ptr->msg_list.niho_arg; + ho_arg->param_flag = 0x07; + ho_arg->ho_type =1; + memcpy(ho_arg->target_id , "1234567" , GCID_LEN); + ho_arg->channel_id.param_flag = 3; + ho_arg->channel_id.prt_id =2; + ho_arg->channel_id.siginfo.siginfo_len =2; + memcpy( ho_arg->channel_id.siginfo.signal_info , "12" ,2 ); + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send noteinernalhandover ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != NoteInterHo) + { + printf("-->>: Recv noteinernalhandover decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv noteinernalhandover ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + + } +} + + +void MAPP_Test_tracesubscriberactivity() +{ + + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapTSA_Arg *tsa_arg; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + u8 bcd_buf_h[ISDN_LEN * 2]; + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + tsa_arg = &srv_ptr->msg_list.tsa_arg; + tsa_arg->param_flag = 0x1f; + AsciiToBcd(bcd_buf_h, "46002215712701", IMSI_LEN * 2); + memcpy(tsa_arg->imsi, bcd_buf_h, IMSI_LEN); + memcpy( tsa_arg->trace_ref , "12",2); + tsa_arg->trace_type = 1; + tsa_arg->omc_id_len =2; + memcpy( tsa_arg->omc_id ,"12", 2 ); + memcpy( tsa_arg->call_ref , "123" ,3 ); + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send tracesubscriberactivity ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != TraceSubAct) + { + printf("-->>: Recv tracesubscriberactivityy decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv tracesubscriberactivity ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + + } +} + +void MAPP_Test_FowardSM() +{ + + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapFSM_Arg *fsm_arg; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + fsm_arg = &srv_ptr->msg_list.fsm_arg; + fsm_arg->param_flag = 0x0f; + fsm_arg->more_msgtosend =1; + fsm_arg->sm_rp_da_choice = 5; + fsm_arg->sm_rp_da.noms_rp_da =1; + + fsm_arg->sm_rp_oa_choice =1; + fsm_arg->sm_rp_oa.msisdn[0 ] = ISDN_LEN; + fsm_arg->sm_rp_oa.msisdn[0] =ISDN_LEN; + memcpy(fsm_arg->sm_rp_oa.msisdn+1 , "12345678" , ISDN_LEN ); + + fsm_arg->sm_rp_ui_len =2; + memcpy(fsm_arg->sm_rp_ui , "12",2); + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send FowardSM ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != FwdSM) + { + printf("-->>: Recv FowardSM decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv FowardSM ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + + } +} + +void MAPP_Test_SendRoutinginfoforSM() +{ + + struct MapOprData_struct *data_ptr; + struct MapOprSrv_struct *srv_ptr; + struct MapRIFSMV1_Arg *ssm_arg; + struct MapRIFSMV1_Res *ssm_res; + + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = map_get_dialogueid(test_xapp.local_ssn); + if(did && map_check_sendopr(did) && map_check_sendcom(did)) + { + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + test_xapp.did = did; + srv_ptr->dialogue_id = test_xapp.did; + srv_ptr->invoke_id = map_get_invokeid(test_xapp.did); + srv_ptr->message_flag = MAP_REQUEST; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->version = 1; + srv_ptr->port_id = 0; + srv_ptr->version = 1; + + ssm_arg = &srv_ptr->msg_list.rifsm_v1_arg; + ssm_arg->param_flag = 0x0f; + ssm_arg->msisdn[0] = ISDN_LEN; + memcpy(ssm_arg->msisdn+1,"12345678", ISDN_LEN); + ssm_arg->sc_add[0]= ISDN_LEN; + memcpy(ssm_arg->sc_add+1,"12345678",ISDN_LEN); + ssm_arg->sm_rp_pri =1; + ssm_arg->tele_service =1; + + send_mapp_open_req(did); + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send sendrounting info sm arg !\r\n"); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_comdata(&test_xapp.xapp.mapp.com_ptr, test_xapp.did) && recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) // wait response + { + u8 isok = extract_xapp_msg(); + if( isok != ROK || test_xapp.xapp.mapp.data_ptr.message_type != SndRoutInfoForSM) + { + printf("-->>: Recv sendrounting info sm decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv sendrounting info sm arg !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_mapp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_mapp_open_conf(); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_mapp_oprdata(&test_xapp.xapp.mapp.data_ptr, test_xapp.did)) + { + if( extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != SndRoutInfoForSM) + { + printf("-->>: Recv sendrounting info sm decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv sendrounting info sm arg !\r\n"); + test_xapp.fsm_state++; + } + break; + case 2: + if(map_check_sendopr(test_xapp.did)) + { + u8 bcd_buf_h[ISDN_LEN * 2]; + + test_xapp.xapp_type = 0; + data_ptr = &test_xapp.xapp.mapp.data_ptr; + srv_ptr = &test_xapp.xapp.mapp.map_opr; + + srv_ptr->invoke_id = test_xapp.invoke_id; + srv_ptr->message_flag = MAP_RESPONSE; + srv_ptr->message_type = test_xapp.operation_type; + srv_ptr->port_id = 0; + //srv_ptr->version = 3; + + ssm_res = &srv_ptr->msg_list.rifsm_v1_res; + ssm_res->param_flag = 0x03; + AsciiToBcd(bcd_buf_h, "46002215712701", IMSI_LEN * 2); + memcpy(ssm_res->imsi, bcd_buf_h, IMSI_LEN); + ssm_res->loc_info.param_flag = 0x02; + memcpy(ssm_res->loc_info.imsi, bcd_buf_h, IMSI_LEN); + ssm_res->loc_info.choice_flag = 1; + ssm_res->loc_info.choice.roaming_num[0] = 8; + memcpy( ssm_res->loc_info.choice.roaming_num+1 , "87654321", 9 ); + + build_xapp_msg(); + send_mapp_oprdata(data_ptr, 1); + printf("<<--: Send sendrounting info sm Res !\r\n"); + test_xapp.fsm_state++; + } + break; + case 3: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + + } +} + + + + +void CAPP_Test_InitialDP() +{ + struct CapInitialDP *init_dp; + struct MapOprData_struct *data_ptr; + struct CapArg *cap_opr; + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = cap_get_dialogueid(test_xapp.local_ssn); + if(did && cap_check_sendopr(did) && cap_check_sendcom(did)) + { + int len; + + //pcapmsg = &test_xapp.xapp.capp.capmsg; + cap_opr = &test_xapp.xapp.capp.cap_opr; + data_ptr = &test_xapp.xapp.capp.data_ptr; + + test_xapp.xapp_type = 1; + test_xapp.did = did; + cap_opr->dialogue_id = test_xapp.did; + cap_opr->invoke_id = test_xapp.invoke_id = map_get_invokeid(did); + cap_opr->message_flag = MAP_REQUEST; + cap_opr->ocode = test_xapp.operation_type; + cap_opr->version = 0; + init_dp = &cap_opr->msg_list.initialDPArg; + + init_dp->serviceKey = 1; + init_dp->optional_flag = 0x0007; + init_dp->calledPartyNumber[0] = 4; + memcpy(&init_dp->calledPartyNumber[1], "1234", 4); + init_dp->callingPartyNumber[0] = 4; + memcpy(&init_dp->callingPartyNumber[1], "1234", 4); + init_dp->callingPartysCategory = 2; + send_capp_open_req(50, 1, did); + + len = build_xapp_msg(); + printf("<<--: Send InitialDP ,not need to response !\r\n"); + send_capp_oprdata(data_ptr, 1); + //send_capp_oprdata(pcapmsg,len); + test_xapp.fsm_state++; + /* + init_dp->serviceKey = 1; + init_dp->optional_flag = 0x947D; + memcpy( init_dp->calledPartyNumber , "46002215712701",IMSI_LEN*2); + //memcpy( init_dp->callingPartyNumber , "46002215712701",IMSI_LEN*2); + init_dp->callingPartysCategory = 2; + //memcpy( init_dp->iPSSPCapabilities ,"123",3); + memcpy( init_dp->locationNumber , "46002215712701" , IMSI_LEN*2); + memcpy( init_dp->originalCalledPartyID , "123456" , 6); + memcpy( init_dp->highLayerCompatibility , "123" , 3); + //memcpy( init_dp->additionalCallingPartyNumber , "46002215712701" , IMSI_LEN*2); + memcpy( init_dp->redirectingPartyID , "123" , 3); + //memcpy( init_dp->redirectionInformation , "123456" , 6); + memcpy( init_dp->iMSI , "46002215712701" , IMSI_LEN*2); + //init_dp->subscriberState_ch = 'a'; + init_dp->ext_basicServiceCode_ch = 'b'; + //memcpy( init_dp->callReferenceNumber , "46002215712701" , IMSI_LEN*2); + //CapBearerCapability bearerCapability; + //CapEventTypeBCSM eventTypeBCSM; + //CapSubscriberState subscriberState; + //CapLocationInformation locationInformation; + //CapExt_BasicServiceCode ext_basicServiceCode; + send_capp_open_req( test_xapp.operation_type , 1 , did ); + build_xapp_msg(); + printf("<<--: Send InitialDP ,not need to response !\r\n"); + send_capp_oprdata((u8 *)&pcapmsg->msgContent[5]); + test_xapp.fsm_state++; + */ + } + break; + case 1: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_capp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_capp_open_conf(test_xapp.operation_type, 1, did); + test_xapp.fsm_state++; + } + if((time_count3++ % 100) == 13) + { + printf("Timer expired!\r\n"); + test_fail(); + return; + } + break; + case 1: + if(recv_capp_oprdata(&test_xapp.xapp.capp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != CAP_OC_InitialDP) + { + printf("-->>: Recv InitialDP decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv InitialDP ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + if((time_count3++ % 100) == 13) + { + printf("Timer expired!\r\n"); + test_fail(); + return; + } + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + if((time_count3++ % 100) == 13) + { + printf("Timer expired!\r\n"); + test_fail(); + return; + } + break; + default: + break; + } + } +} + +void CAPP_Test_ActivityTest() //NULL +{ + +} + +void CAPP_Test_Connect() +{ + /* + struct CapConnect_v1 *connect; + struct MapOprData_struct *data_ptr; + struct CapArg *cap_opr; + int did; + + test_xapp.test_result = 0; + if(test_xapp.ms_mode == 1) // master + { + switch (test_xapp.fsm_state) + { + case 0: + did = cap_get_dialogueid(test_xapp.local_ssn); + if(did && cap_check_sendopr(did) && cap_check_sendcom(did)) + { + int len; + + cap_opr = &test_xapp.xapp.capp.cap_opr; + data_ptr = &test_xapp.xapp.capp.data_ptr; + + test_xapp.xapp_type = 1; + test_xapp.did = did; + cap_opr->dialogue_id = test_xapp.did; + cap_opr->invoke_id = test_xapp.invoke_id = map_get_invokeid(did); + cap_opr->message_flag = MAP_REQUEST; + cap_opr->ocode = test_xapp.operation_type; + cap_opr->version = 0; + + connect = &cap_opr->msg_list.connectArg_v1; + + connect->destinationRoutingAddress[0] = 4; + memcpy(&connect->destinationRoutingAddress[1], "1234", 4); + connect->optional_flag = 0xC3; + connect->originalCalledPartyID[0] = 4; + memcpy(&connect->originalCalledPartyID[1], "1234", 4); + connect->genericNumbers_v1_len = 1; + connect->genericNumber_v1[0][0] = 4; + memcpy(&connect->genericNumber_v1[0][1], "1234", 4); + connect->suppressionOfAnnouncement = 1; + connect->oCSIApplicable = 0; + + send_capp_open_req(50, 1, did); + + len = build_xapp_msg(); + printf("<<--: Send Connect ,not need to response !\r\n"); + send_capp_oprdata(data_ptr, 1); + test_xapp.fsm_state++; + + } + break; + case 1: + if(map_check_sendcom(test_xapp.did) && (time_count3++ % 10) == 3) + { + test_pass(); + } + break; + default: + break; + } + } + else if(test_xapp.ms_mode == 2) // slaver + { + switch (test_xapp.fsm_state) + { + case 0: + if(get_capp_open(&test_xapp.xapp.mapp.com_ptr, test_xapp.local_ssn)) + { + test_xapp.did = test_xapp.xapp.mapp.com_ptr.dialogue_id; + send_capp_open_conf(test_xapp.operation_type, 1, did); + test_xapp.fsm_state++; + } + break; + case 1: + if(recv_capp_oprdata(&test_xapp.xapp.capp.data_ptr, test_xapp.did)) + { + if(extract_xapp_msg() != ROK || test_xapp.xapp.mapp.data_ptr.message_type != CAP_OC_Connect) + { + printf("-->>: Recv Connect decode err!\r\n"); + test_fail(); + return; + } + printf("-->>: Recv Connect ,not need to response !\r\n"); + test_xapp.fsm_state++; + } + case 2: + if(map_check_sendcom(test_xapp.did)) + { + test_pass(); + } + break; + default: + break; + } + } + + */ +} + +void CAPP_Test_Continue() //NULL +{ + +} + +void CAPP_Test_EventReportBCSM() //==V2 +{ + +} + +void CAPP_Test_ReleaseCall() //==V2 +{ + +} + +void CAPP_Test_RequestReportBCSMEvent() //==V2 +{ + +} + +void Test_fsm() +{ + if(test_xapp.operation_type || (!test_xapp.operation_type && test_cmd == CAPP_TEST_INITDP)) + { + switch (test_xapp.operation_type) + { + + /*-------------->>>>>>>>>>>>> MAP V1 Test <<<<<<<<<<<<<<<<<<<<<-------------*/ + case SendParam: // send parameters + MAPP_Test_SendPara_Proc(); + break; + case NoteSubPrnt: // not subscriber present + MAPP_Test_NotSubPresent_Proc(); + break; + case ProcUnstrctSSData: // process unstructure SS data + MAPP_Test_ProcessUSSD_Proc(); + break; + case BeginSubAct: // beging subscriber activity + MAPP_Test_BeginSubActivity(); + break; + case PerformHo: // perform handover + MAPP_Test_PeformHandOver(); + break; + case RegSS: + MAPP_Test_RegisterSS(); + break; + case PerformSubsHo: + MAPP_Test_PerformSubsequenthandover(); + break; + case NoteInterHo: + MAPP_Test_noteinernalhandover(); + break; + case TraceSubAct: + MAPP_Test_tracesubscriberactivity(); + break; + case FwdSM: + MAPP_Test_FowardSM(); + break; + case SndRoutInfoForSM: + MAPP_Test_SendRoutinginfoforSM(); + break; + case CancelLoc: + if( test_cmd == MAPP_TEST_CANCELLOCv3 ) + MAPP_Test_CancelLoc_Proc(3); + else + MAPP_Test_CancelLoc_Proc(1); + break; + case CAP_OC_InitialDP: + CAPP_Test_InitialDP(); + break; + case CAP_OC_ActivityTest: + CAPP_Test_ActivityTest(); + break; + case CAP_OC_Connect: + CAPP_Test_Connect(); + break; + case CAP_OC_Continue: + CAPP_Test_Continue(); + break; + case CAP_OC_EventReportBCSM: + CAPP_Test_EventReportBCSM(); + break; + case CAP_OC_ReleaseCall: + CAPP_Test_ReleaseCall(); + break; + case CAP_OC_RequestReportBCSMEvent: + CAPP_Test_RequestReportBCSMEvent(); + break; + + /*-------------->>>>>>>>>>>>> MAP V1 Test <<<<<<<<<<<<<<<<<<<<<-------------*/ + default: + break; + } + } + +} + +void Test_func() +{ + if(test_xapp.ms_mode > 0 && !test_xapp.test_result && test_xapp.test_result != 7) + { + switch (test_cmd) + { + + case 0: + //printf("time_count2 :%d",time_count2); + if(test_xapp.ms_mode == 2) + { + printf("\r\n\r\nStart xapp Test ......\r\n\r\n"); + //test_cmd = MAPP_TEST_SENDPARA; + test_cmd = MAPP_TEST_REGISTERSS; + break; + } + else if((time_count2++) == test_xapp.wait_time) + { + printf("\r\n\r\nStart xapp Test ......\r\n\r\n"); + //test_cmd = MAPP_TEST_SENDPARA; + test_cmd = MAPP_TEST_REGISTERSS; + } + break; + case MAPP_TEST_SENDPARA: + //test_xapp.operation_type = NoteSubPrnt; + test_xapp.operation_type = SendParam; + break; + case MAPP_TEST_NOTSUBPRE: + test_xapp.operation_type = NoteSubPrnt; + break; + case MAPP_TEST_PROCUSSD: + test_xapp.operation_type = ProcUnstrctSSData; + break; + case MAPP_TEST_BEGINACT: + test_xapp.operation_type = BeginSubAct; + break; + case MAPP_TEST_HANDOVER: + test_xapp.operation_type = PerformHo; + break; + case MAPP_TEST_PERFORMSUBSEQUENTHANDOVER: + test_xapp.operation_type = PerformSubsHo; + break; + case MAPP_TEST_NOTEINERNALHANDOVER: + test_xapp.operation_type = NoteInterHo; + break; + case MAPP_TEST_REGISTERSS: + test_xapp.operation_type = RegSS; + break; + case MAPP_TEST_TRACESUBSCRIBERACTIVITY: + test_xapp.operation_type = TraceSubAct; + break; + case MAPP_TEST_FOWARDSM: + test_xapp.operation_type = FwdSM; + break; + case MAPP_TEST_SENDROUTINGINFOFORSM: + test_xapp.operation_type = SndRoutInfoForSM; + break; + case MAPP_TEST_CANCELLOC: + case MAPP_TEST_CANCELLOCv3: + test_xapp.operation_type = CancelLoc; + break; + case CAPP_TEST_INITDP: + test_xapp.operation_type = CAP_OC_InitialDP; + break; + + //case CAPP_TEST_ACTTEST: + // test_xapp.operation_type = CAP_OC_ActivityTest ; + // break; + case CAPP_TEST_CONNECT: + test_xapp.operation_type = CAP_OC_Connect; + break; + //case CAPP_TEST_CONTINUE: + // test_xapp.operation_type = CAP_OC_Continue; + // break; + //case CAPP_TEST_REPORTBCSM: + // test_xapp.operation_type = CAP_OC_EventReportBCSM; + // break; + //case CAPP_TEST_CALLREL: + // test_xapp.operation_type = CAP_OC_ReleaseCall; + // break; + case CAPP_TEST_REQREPORTBCSM: + test_xapp.operation_type = CAP_OC_RequestReportBCSMEvent; + break; + case XAPP_TEST_LAST_IDLE: + break; + default: + break; + } + Test_fsm(); + } + +} diff --git a/plat/xapp/ut/xapp_test/xapp_op_test.h b/plat/xapp/ut/xapp_test/xapp_op_test.h new file mode 100644 index 0000000..9098f20 --- /dev/null +++ b/plat/xapp/ut/xapp_test/xapp_op_test.h @@ -0,0 +1,39 @@ +/* XAPP coding test function head file */ +/* created by Liu Wei 2006-01-13 */ +/* Version 1.0 */ +/* ------------------------------------- */ + +#ifndef _XAPP_OP_TEST_ + +#define _XAPP_OP_TEST_ + +enum XAPP_TEST_OP +{ + MAPP_TEST_SENDPARA =1, + MAPP_TEST_NOTSUBPRE, + MAPP_TEST_PROCUSSD, + MAPP_TEST_BEGINACT, + MAPP_TEST_REGISTERSS , + MAPP_TEST_HANDOVER, + MAPP_TEST_PERFORMSUBSEQUENTHANDOVER, + MAPP_TEST_NOTEINERNALHANDOVER, + MAPP_TEST_TRACESUBSCRIBERACTIVITY, + MAPP_TEST_FOWARDSM, + MAPP_TEST_SENDROUTINGINFOFORSM, + MAPP_TEST_CANCELLOC, + MAPP_TEST_CANCELLOCv3, + CAPP_TEST_INITDP, + //CAPP_TEST_ACTTEST, + CAPP_TEST_CONNECT, + //CAPP_TEST_CONTINUE, + //CAPP_TEST_REPORTBCSM, + //CAPP_TEST_CALLREL, + CAPP_TEST_REQREPORTBCSM, + XAPP_TEST_LAST_IDLE, + + //Please add here , add behind the XAPP_TEST_LAST_IDLE + +}; + +void Test_func(); +#endif